--- 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