--- linux/drivers/net/au1000_eth.h	2003-06-05 02:00:35.000000000 +0200
+++ patch/drivers/net/au1000_eth.h	2006-10-13 14:36:42.237757250 +0200
@@ -233,3 +233,11 @@
 	struct timer_list timer;
 	spinlock_t lock;       /* Serialise access to device */
 };
+
+struct mii_ioctl_data {
+	u16             phy_id;
+	u16             reg_num;
+	u16             val_in;
+	u16             val_out;
+};
+
--- linux/drivers/net/au1000_eth.c	2004-11-24 12:12:42.000000000 +0100
+++ patch/drivers/net/au1000_eth.c	2006-10-13 14:36:36.649408000 +0200
@@ -83,8 +83,6 @@
 static int au1000_set_config(struct net_device *dev, struct ifmap *map);
 static void set_rx_mode(struct net_device *);
 static struct net_device_stats *au1000_get_stats(struct net_device *);
-static inline void update_tx_stats(struct net_device *, u32, u32);
-static inline void update_rx_stats(struct net_device *, u32);
 static void au1000_timer(unsigned long);
 static int au1000_ioctl(struct net_device *, struct ifreq *, int);
 static int mdio_read(struct net_device *, int, int);
@@ -674,6 +672,7 @@
 	{"Broadcom BCM5201 10/100 BaseT PHY",0x0040,0x6212, &bcm_5201_ops,0},
 	{"Broadcom BCM5221 10/100 BaseT PHY",0x0040,0x61e4, &bcm_5201_ops,0},
 	{"Broadcom BCM5222 10/100 BaseT PHY",0x0040,0x6322, &bcm_5201_ops,1},
+	{"Broadcom BCM5241 10/100 BaseT PHY",0x0143,0xBC31, &bcm_5201_ops,0},
 	{"AMD 79C901 HomePNA PHY",0x0000,0x35c8, &am79c901_ops,0},
 	{"AMD 79C874 10/100 BaseT PHY",0x0022,0x561b, &am79c874_ops,0},
 	{"LSI 80227 10/100 BaseT PHY",0x0016,0xf840, &lsi_80227_ops,0},
@@ -1389,6 +1388,7 @@
 		control |= MAC_FULL_DUPLEX;
 	}
 	aup->mac->control = control;
+	aup->mac->vlan1_tag = 0x8100; /* activate vlan support */
 	au_sync();
 
 	spin_unlock_irqrestore(&aup->lock, flags);
@@ -1539,16 +1539,11 @@
 	}
 }
 
-
-static inline void 
-update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len)
+static void update_tx_stats(struct net_device *dev, u32 status)
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
 	struct net_device_stats *ps = &aup->stats;
 
-	ps->tx_packets++;
-	ps->tx_bytes += pkt_len;
-
 	if (status & TX_FRAME_ABORTED) {
 		if (dev->if_port == IF_PORT_100BASEFX) {
 			if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) {
@@ -1581,7 +1576,7 @@
 	ptxd = aup->tx_dma_ring[aup->tx_tail];
 
 	while (ptxd->buff_stat & TX_T_DONE) {
-		update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff);
+		update_tx_stats(dev, ptxd->status);
 		ptxd->buff_stat &= ~TX_T_DONE;
 		ptxd->len = 0;
 		au_sync();
@@ -1603,6 +1598,7 @@
 static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
+	struct net_device_stats *ps = &aup->stats;
 	volatile tx_dma_t *ptxd;
 	u32 buff_stat;
 	db_dest_t *pDB;
@@ -1622,7 +1618,7 @@
 		return 1;
 	}
 	else if (buff_stat & TX_T_DONE) {
-		update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff);
+		update_tx_stats(dev, ptxd->status);
 		ptxd->len = 0;
 	}
 
@@ -1642,6 +1638,9 @@
 	else
 		ptxd->len = skb->len;
 
+	ps->tx_packets++;
+	ps->tx_bytes += ptxd->len;
+
 	ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE;
 	au_sync();
 	dev_kfree_skb(skb);
@@ -1650,7 +1649,6 @@
 	return 0;
 }
 
-
 static inline void update_rx_stats(struct net_device *dev, u32 status)
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
@@ -1840,21 +1838,36 @@
 
 static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-	//u16 *data = (u16 *)&rq->ifr_data;
+        struct au1000_private *aup = (struct au1000_private *)dev->priv;
+	struct mii_ioctl_data *mii_data = (struct mii_ioctl_data *)&rq->ifr_ifru;
+	u16 val = mii_data->val_in;
+	const u32 enabled = MAC_EN_RESET0 | MAC_EN_RESET1 | 
+		MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE;
+
+	/* Check if net device is running */
+        if (!netif_running(dev)) return -EINVAL;
+	
+	/* Check if ethernet mac is in reset mode */
+	if (*aup->enable & enabled != enabled) return -EINVAL; 
 
-	/* fixme */
 	switch(cmd) { 
-		case SIOCDEVPRIVATE:	/* Get the address of the PHY in use. */
-		//data[0] = PHY_ADDRESS;
-		case SIOCDEVPRIVATE+1:	/* Read the specified MII register. */
-		//data[3] = mdio_read(ioaddr, data[0], data[1]); 
-		return 0;
-		case SIOCDEVPRIVATE+2:	/* Write the specified MII register */
-		//mdio_write(ioaddr, data[0], data[1], data[2]);
-		return 0;
+		case SIOCGMIIPHY:	/* Get the address of the PHY in use. */
+			mii_data->phy_id = aup->phy_addr;
+			break;
+		case SIOCGMIIREG:	/* Read the specified MII register. */
+			mii_data->val_out = mdio_read(dev, mii_data->phy_id, 
+				mii_data->reg_num);
+			break;
+		case SIOCSMIIREG:	/* Write the specified MII register */
+			if (!capable(CAP_NET_ADMIN))
+				return -EPERM;
+			mdio_write(dev,mii_data->phy_id, mii_data->reg_num, 
+				val);
 		default:
 		return -EOPNOTSUPP;
+
 	}
+	return 0;
 }
 
 
--- linux/drivers/net/Config.in	2006-10-13 15:05:33.697966750 +0200
+++ patch/drivers/net/Config.in	2006-10-13 14:36:47.030056750 +0200
@@ -67,9 +67,7 @@
    fi
    if [ "$CONFIG_SOC_AU1X00" = "y" ]; then
       tristate '  MIPS Au1x00 Ethernet support' CONFIG_MIPS_AU1X00_ENET
-      if [ "$CONFIG_MIPS_AU1X00_ENET" = "y" ]; then
-         bool '   Broadcom 5222 Dual Phy Support' CONFIG_BCM5222_DUAL_PHY
-      fi
+      dep_mbool '   Broadcom 5222 Dual Phy Support' CONFIG_BCM5222_DUAL_PHY $CONFIG_MIPS_AU1X00_ENET
    fi
    if [ "$CONFIG_SGI_IP27" = "y" ]; then
       bool '  SGI IOC3 Ethernet' CONFIG_SGI_IOC3_ETH