ar71xx: sync ethernet driver changes with trunk to fix MDIO issues on ar7240
authornbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Fri, 15 Apr 2011 00:05:44 +0000 (00:05 +0000)
committernbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Fri, 15 Apr 2011 00:05:44 +0000 (00:05 +0000)
git-svn-id: svn://svn.openwrt.org/openwrt/branches/backfire@26672 3c298f89-4303-0410-b956-a3cf2f4a3e73

target/linux/ar71xx/files/arch/mips/ar71xx/mach-dir-600-a1.c
target/linux/ar71xx/files/arch/mips/ar71xx/mach-rb750.c
target/linux/ar71xx/files/arch/mips/ar71xx/mach-tl-wr741nd.c
target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h
target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ar7240.c
target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_debugfs.c
target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c
target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_mdio.c
target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_phy.c

index fad417a..b835bc8 100644 (file)
@@ -136,6 +136,7 @@ static void __init dir_600_a1_setup(void)
        ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
        ar71xx_eth0_data.speed = SPEED_100;
        ar71xx_eth0_data.duplex = DUPLEX_FULL;
+       ar71xx_eth0_data.phy_mask = BIT(4);
 
        /* LAN ports */
        ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
index 41a184e..b5b4c6c 100644 (file)
@@ -121,6 +121,7 @@ static void __init rb750_setup(void)
        ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
        ar71xx_eth0_data.speed = SPEED_100;
        ar71xx_eth0_data.duplex = DUPLEX_FULL;
+       ar71xx_eth0_data.phy_mask = BIT(4);
 
        /* LAN ports */
        ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
index 4d6308e..c5365fe 100644 (file)
@@ -114,6 +114,7 @@ static void __init tl_wr741nd_setup(void)
        ar71xx_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
        ar71xx_eth0_data.speed = SPEED_100;
        ar71xx_eth0_data.duplex = DUPLEX_FULL;
+       ar71xx_eth0_data.phy_mask = BIT(4);
 
        /* LAN ports */
        ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
index be14e7e..bb4cb5b 100644 (file)
@@ -89,7 +89,7 @@ struct ag71xx_desc {
 
 struct ag71xx_buf {
        struct sk_buff          *skb;
-       struct ag71xx_desc      *desc;
+       struct ag71xx_desc      *desc;
        dma_addr_t              dma_addr;
        u32                     pad;
 };
@@ -162,7 +162,7 @@ struct ag71xx {
 
        unsigned int            link;
        unsigned int            speed;
-       int                     duplex;
+       int                     duplex;
 
        struct work_struct      restart_work;
        struct timer_list       oom_timer;
@@ -190,12 +190,12 @@ static inline struct ag71xx_platform_data *ag71xx_get_pdata(struct ag71xx *ag)
 
 static inline int ag71xx_desc_empty(struct ag71xx_desc *desc)
 {
-       return ((desc->ctrl & DESC_EMPTY) != 0);
+       return (desc->ctrl & DESC_EMPTY) != 0;
 }
 
 static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc)
 {
-       return (desc->ctrl & DESC_PKTLEN_M);
+       return desc->ctrl & DESC_PKTLEN_M;
 }
 
 /* Register offsets */
@@ -432,7 +432,7 @@ static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag)
        return __raw_readl(ag->mii_ctrl);
 }
 
-static void inline ag71xx_mii_ctrl_set_if(struct ag71xx *ag,
+static inline void ag71xx_mii_ctrl_set_if(struct ag71xx *ag,
                                          unsigned int mii_if)
 {
        u32 t;
@@ -443,7 +443,7 @@ static void inline ag71xx_mii_ctrl_set_if(struct ag71xx *ag,
        ag71xx_mii_ctrl_wr(ag, t);
 }
 
-static void inline ag71xx_mii_ctrl_set_speed(struct ag71xx *ag,
+static inline void ag71xx_mii_ctrl_set_speed(struct ag71xx *ag,
                                             unsigned int speed)
 {
        u32 t;
@@ -503,4 +503,12 @@ void ag71xx_ar7240_stop(struct ag71xx *ag);
 int ag71xx_ar7240_init(struct ag71xx *ag);
 void ag71xx_ar7240_cleanup(struct ag71xx *ag);
 
+int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg);
+void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val);
+
+u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr,
+                     unsigned reg_addr);
+int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr,
+                      unsigned reg_addr, u16 reg_val);
+
 #endif /* _AG71XX_H */
index e299e68..3ce2f0a 100644 (file)
 
 struct ar7240sw {
        struct mii_bus  *mii_bus;
-       struct mutex    reg_mutex;
        struct switch_dev swdev;
        bool vlan;
        u16 vlan_id[AR7240_MAX_VLANS];
@@ -210,117 +209,115 @@ struct ar7240sw_hw_stat {
        int reg;
 };
 
+static DEFINE_MUTEX(reg_mutex);
 
 static inline void ar7240sw_init(struct ar7240sw *as, struct mii_bus *mii)
 {
        as->mii_bus = mii;
-       mutex_init(&as->reg_mutex);
 }
 
 static inline u16 mk_phy_addr(u32 reg)
 {
-       return (0x17 & ((reg >> 4) | 0x10));
+       return 0x17 & ((reg >> 4) | 0x10);
 }
 
 static inline u16 mk_phy_reg(u32 reg)
 {
-       return ((reg << 1) & 0x1e);
+       return (reg << 1) & 0x1e;
 }
 
 static inline u16 mk_high_addr(u32 reg)
 {
-       return ((reg >> 7) & 0x1ff);
+       return (reg >> 7) & 0x1ff;
 }
 
-static u32 __ar7240sw_reg_read(struct ar7240sw *as, u32 reg)
+static u32 __ar7240sw_reg_read(struct mii_bus *mii, u32 reg)
 {
-       struct mii_bus *mii = as->mii_bus;
        u16 phy_addr;
        u16 phy_reg;
        u32 hi, lo;
 
        reg = (reg & 0xfffffffc) >> 2;
 
-       mdiobus_write(mii, 0x1f, 0x10, mk_high_addr(reg));
+       ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg));
 
        phy_addr = mk_phy_addr(reg);
        phy_reg = mk_phy_reg(reg);
 
-       lo = (u32) mdiobus_read(mii, phy_addr, phy_reg);
-       hi = (u32) mdiobus_read(mii, phy_addr, phy_reg + 1);
+       lo = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg);
+       hi = (u32) ag71xx_mdio_mii_read(mii->priv, phy_addr, phy_reg + 1);
 
-       return ((hi << 16) | lo);
+       return (hi << 16) | lo;
 }
 
-static void __ar7240sw_reg_write(struct ar7240sw *as, u32 reg, u32 val)
+static void __ar7240sw_reg_write(struct mii_bus *mii, u32 reg, u32 val)
 {
-       struct mii_bus *mii = as->mii_bus;
        u16 phy_addr;
        u16 phy_reg;
 
        reg = (reg & 0xfffffffc) >> 2;
 
-       mdiobus_write(mii, 0x1f, 0x10, mk_high_addr(reg));
+       ag71xx_mdio_mii_write(mii->priv, 0x1f, 0x10, mk_high_addr(reg));
 
        phy_addr = mk_phy_addr(reg);
        phy_reg = mk_phy_reg(reg);
 
-       mdiobus_write(mii, phy_addr, phy_reg + 1, (val >> 16));
-       mdiobus_write(mii, phy_addr, phy_reg, (val & 0xffff));
+       ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg + 1, (val >> 16));
+       ag71xx_mdio_mii_write(mii->priv, phy_addr, phy_reg, (val & 0xffff));
 }
 
-static u32 ar7240sw_reg_read(struct ar7240sw *as, u32 reg_addr)
+static u32 ar7240sw_reg_read(struct mii_bus *mii, u32 reg_addr)
 {
        u32 ret;
 
-       mutex_lock(&as->reg_mutex);
-       ret = __ar7240sw_reg_read(as, reg_addr);
-       mutex_unlock(&as->reg_mutex);
+       mutex_lock(&reg_mutex);
+       ret = __ar7240sw_reg_read(mii, reg_addr);
+       mutex_unlock(&reg_mutex);
 
        return ret;
 }
 
-static void ar7240sw_reg_write(struct ar7240sw *as, u32 reg_addr, u32 reg_val)
+static void ar7240sw_reg_write(struct mii_bus *mii, u32 reg_addr, u32 reg_val)
 {
-       mutex_lock(&as->reg_mutex);
-       __ar7240sw_reg_write(as, reg_addr, reg_val);
-       mutex_unlock(&as->reg_mutex);
+       mutex_lock(&reg_mutex);
+       __ar7240sw_reg_write(mii, reg_addr, reg_val);
+       mutex_unlock(&reg_mutex);
 }
 
-static u32 ar7240sw_reg_rmw(struct ar7240sw *as, u32 reg, u32 mask, u32 val)
+static u32 ar7240sw_reg_rmw(struct mii_bus *mii, u32 reg, u32 mask, u32 val)
 {
        u32 t;
 
-       mutex_lock(&as->reg_mutex);
-       t = __ar7240sw_reg_read(as, reg);
+       mutex_lock(&reg_mutex);
+       t = __ar7240sw_reg_read(mii, reg);
        t &= ~mask;
        t |= val;
-       __ar7240sw_reg_write(as, reg, t);
-       mutex_unlock(&as->reg_mutex);
+       __ar7240sw_reg_write(mii, reg, t);
+       mutex_unlock(&reg_mutex);
 
        return t;
 }
 
-static void ar7240sw_reg_set(struct ar7240sw *as, u32 reg, u32 val)
+static void ar7240sw_reg_set(struct mii_bus *mii, u32 reg, u32 val)
 {
        u32 t;
 
-       mutex_lock(&as->reg_mutex);
-       t = __ar7240sw_reg_read(as, reg);
+       mutex_lock(&reg_mutex);
+       t = __ar7240sw_reg_read(mii, reg);
        t |= val;
-       __ar7240sw_reg_write(as, reg, t);
-       mutex_unlock(&as->reg_mutex);
+       __ar7240sw_reg_write(mii, reg, t);
+       mutex_unlock(&reg_mutex);
 }
 
-static int ar7240sw_reg_wait(struct ar7240sw *as, u32 reg, u32 mask, u32 val,
-                            unsigned timeout)
+static int __ar7240sw_reg_wait(struct mii_bus *mii, u32 reg, u32 mask, u32 val,
+                              unsigned timeout)
 {
        int i;
 
        for (i = 0; i < timeout; i++) {
                u32 t;
 
-               t = ar7240sw_reg_read(as, reg);
+               t = __ar7240sw_reg_read(mii, reg);
                if ((t & mask) == val)
                        return 0;
 
@@ -330,33 +327,45 @@ static int ar7240sw_reg_wait(struct ar7240sw *as, u32 reg, u32 mask, u32 val,
        return -ETIMEDOUT;
 }
 
-static u16 ar7240sw_phy_read(struct ar7240sw *as, unsigned phy_addr,
-                            unsigned reg_addr)
+static int ar7240sw_reg_wait(struct mii_bus *mii, u32 reg, u32 mask, u32 val,
+                            unsigned timeout)
 {
-       u32 t;
+       int ret;
+
+       mutex_lock(&reg_mutex);
+       ret = __ar7240sw_reg_wait(mii, reg, mask, val, timeout);
+       mutex_unlock(&reg_mutex);
+       return ret;
+}
+
+u16 ar7240sw_phy_read(struct mii_bus *mii, unsigned phy_addr,
+                     unsigned reg_addr)
+{
+       u32 t, val = 0xffff;
        int err;
 
        if (phy_addr >= AR7240_NUM_PHYS)
                return 0xffff;
 
+       mutex_lock(&reg_mutex);
        t = (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) |
            (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) |
            AR7240_MDIO_CTRL_MASTER_EN |
            AR7240_MDIO_CTRL_BUSY |
            AR7240_MDIO_CTRL_CMD_READ;
 
-       ar7240sw_reg_write(as, AR7240_REG_MDIO_CTRL, t);
-       err = ar7240sw_reg_wait(as, AR7240_REG_MDIO_CTRL,
-                               AR7240_MDIO_CTRL_BUSY, 0, 5);
-       if (err)
-               return 0xffff;
+       __ar7240sw_reg_write(mii, AR7240_REG_MDIO_CTRL, t);
+       err = __ar7240sw_reg_wait(mii, AR7240_REG_MDIO_CTRL,
+                                 AR7240_MDIO_CTRL_BUSY, 0, 5);
+       if (!err)
+               val = __ar7240sw_reg_read(mii, AR7240_REG_MDIO_CTRL);
+       mutex_unlock(&reg_mutex);
 
-       t = ar7240sw_reg_read(as, AR7240_REG_MDIO_CTRL);
-       return (t & AR7240_MDIO_CTRL_DATA_M);
+       return val & AR7240_MDIO_CTRL_DATA_M;
 }
 
-static int ar7240sw_phy_write(struct ar7240sw *as, unsigned phy_addr,
-                             unsigned reg_addr, u16 reg_val)
+int ar7240sw_phy_write(struct mii_bus *mii, unsigned phy_addr,
+                      unsigned reg_addr, u16 reg_val)
 {
        u32 t;
        int ret;
@@ -364,6 +373,7 @@ static int ar7240sw_phy_write(struct ar7240sw *as, unsigned phy_addr,
        if (phy_addr >= AR7240_NUM_PHYS)
                return -EINVAL;
 
+       mutex_lock(&reg_mutex);
        t = (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) |
            (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) |
            AR7240_MDIO_CTRL_MASTER_EN |
@@ -371,34 +381,38 @@ static int ar7240sw_phy_write(struct ar7240sw *as, unsigned phy_addr,
            AR7240_MDIO_CTRL_CMD_WRITE |
            reg_val;
 
-       ar7240sw_reg_write(as, AR7240_REG_MDIO_CTRL, t);
-       ret = ar7240sw_reg_wait(as, AR7240_REG_MDIO_CTRL,
-                               AR7240_MDIO_CTRL_BUSY, 0, 5);
+       __ar7240sw_reg_write(mii, AR7240_REG_MDIO_CTRL, t);
+       ret = __ar7240sw_reg_wait(mii, AR7240_REG_MDIO_CTRL,
+                                 AR7240_MDIO_CTRL_BUSY, 0, 5);
+       mutex_unlock(&reg_mutex);
+
        return ret;
 }
 
 static int ar7240sw_capture_stats(struct ar7240sw *as)
 {
+       struct mii_bus *mii = as->mii_bus;
        int ret;
 
        /* Capture the hardware statistics for all ports */
-       ar7240sw_reg_write(as, AR7240_REG_MIB_FUNCTION0,
+       ar7240sw_reg_write(mii, AR7240_REG_MIB_FUNCTION0,
                           (AR7240_MIB_FUNC_CAPTURE << AR7240_MIB_FUNC_S));
 
        /* Wait for the capturing to complete. */
-       ret = ar7240sw_reg_wait(as, AR7240_REG_MIB_FUNCTION0,
+       ret = ar7240sw_reg_wait(mii, AR7240_REG_MIB_FUNCTION0,
                                AR7240_MIB_BUSY, 0, 10);
        return ret;
 }
 
 static void ar7240sw_disable_port(struct ar7240sw *as, unsigned port)
 {
-       ar7240sw_reg_write(as, AR7240_REG_PORT_CTRL(port),
+       ar7240sw_reg_write(as->mii_bus, AR7240_REG_PORT_CTRL(port),
                           AR7240_PORT_CTRL_STATE_DISABLED);
 }
 
 static int ar7240sw_reset(struct ar7240sw *as)
 {
+       struct mii_bus *mii = as->mii_bus;
        int ret;
        int i;
 
@@ -410,41 +424,44 @@ static int ar7240sw_reset(struct ar7240sw *as)
        msleep(2);
 
        /* Reset the switch. */
-       ar7240sw_reg_write(as, AR7240_REG_MASK_CTRL,
+       ar7240sw_reg_write(mii, AR7240_REG_MASK_CTRL,
                           AR7240_MASK_CTRL_SOFT_RESET);
 
-       ret = ar7240sw_reg_wait(as, AR7240_REG_MASK_CTRL,
-                               AR7240_MASK_CTRL_SOFT_RESET, 0, 1000);
+       ret = ar7240sw_reg_wait(mii, AR7240_REG_MASK_CTRL,
+                               AR7240_MASK_CTRL_SOFT_RESET, 0, 1000);
        return ret;
 }
 
 static void ar7240sw_setup(struct ar7240sw *as)
 {
+       struct mii_bus *mii = as->mii_bus;
+
        /* Enable CPU port, and disable mirror port */
-       ar7240sw_reg_write(as, AR7240_REG_CPU_PORT,
+       ar7240sw_reg_write(mii, AR7240_REG_CPU_PORT,
                           AR7240_CPU_PORT_EN |
                           (15 << AR7240_MIRROR_PORT_S));
 
        /* Setup TAG priority mapping */
-       ar7240sw_reg_write(as, AR7240_REG_TAG_PRIORITY, 0xfa50);
+       ar7240sw_reg_write(mii, AR7240_REG_TAG_PRIORITY, 0xfa50);
 
        /* Enable ARP frame acknowledge */
-       ar7240sw_reg_set(as, AR7240_REG_AT_CTRL, AR7240_AT_CTRL_ARP_EN);
+       ar7240sw_reg_set(mii, AR7240_REG_AT_CTRL, AR7240_AT_CTRL_ARP_EN);
 
        /* Enable Broadcast frames transmitted to the CPU */
-       ar7240sw_reg_set(as, AR7240_REG_FLOOD_MASK,
+       ar7240sw_reg_set(mii, AR7240_REG_FLOOD_MASK,
                         AR7240_FLOOD_MASK_BROAD_TO_CPU);
 
        /* setup MTU */
-       ar7240sw_reg_rmw(as, AR7240_REG_GLOBAL_CTRL, AR7240_GLOBAL_CTRL_MTU_M,
+       ar7240sw_reg_rmw(mii, AR7240_REG_GLOBAL_CTRL, AR7240_GLOBAL_CTRL_MTU_M,
                         1536);
 
        /* setup Service TAG */
-       ar7240sw_reg_rmw(as, AR7240_REG_SERVICE_TAG, AR7240_SERVICE_TAG_M, 0);
+       ar7240sw_reg_rmw(mii, AR7240_REG_SERVICE_TAG, AR7240_SERVICE_TAG_M, 0);
 }
 
 static void ar7240sw_setup_port(struct ar7240sw *as, unsigned port, u8 portmask)
 {
+       struct mii_bus *mii = as->mii_bus;
        u32 ctrl;
        u32 dest_ports;
        u32 vlan;
@@ -453,7 +470,7 @@ static void ar7240sw_setup_port(struct ar7240sw *as, unsigned port, u8 portmask)
                AR7240_PORT_CTRL_SINGLE_VLAN;
 
        if (port == AR7240_PORT_CPU) {
-               ar7240sw_reg_write(as, AR7240_REG_PORT_STATUS(port),
+               ar7240sw_reg_write(mii, AR7240_REG_PORT_STATUS(port),
                                   AR7240_PORT_STATUS_SPEED_1000 |
                                   AR7240_PORT_STATUS_TXFLOW |
                                   AR7240_PORT_STATUS_RXFLOW |
@@ -461,7 +478,7 @@ static void ar7240sw_setup_port(struct ar7240sw *as, unsigned port, u8 portmask)
                                   AR7240_PORT_STATUS_RXMAC |
                                   AR7240_PORT_STATUS_DUPLEX);
        } else {
-               ar7240sw_reg_write(as, AR7240_REG_PORT_STATUS(port),
+               ar7240sw_reg_write(mii, AR7240_REG_PORT_STATUS(port),
                                   AR7240_PORT_STATUS_LINK_AUTO);
        }
 
@@ -499,26 +516,27 @@ static void ar7240sw_setup_port(struct ar7240sw *as, unsigned port, u8 portmask)
        /* set default VID and and destination ports for this VLAN */
        vlan |= (portmask << AR7240_PORT_VLAN_DEST_PORTS_S);
 
-       ar7240sw_reg_write(as, AR7240_REG_PORT_CTRL(port), ctrl);
-       ar7240sw_reg_write(as, AR7240_REG_PORT_VLAN(port), vlan);
+       ar7240sw_reg_write(mii, AR7240_REG_PORT_CTRL(port), ctrl);
+       ar7240sw_reg_write(mii, AR7240_REG_PORT_VLAN(port), vlan);
 }
 
 static int ar7240_set_addr(struct ar7240sw *as, u8 *addr)
 {
+       struct mii_bus *mii = as->mii_bus;
        u32 t;
 
        t = (addr[4] << 8) | addr[5];
-       ar7240sw_reg_write(as, AR7240_REG_MAC_ADDR0, t);
+       ar7240sw_reg_write(mii, AR7240_REG_MAC_ADDR0, t);
 
        t = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3];
-       ar7240sw_reg_write(as, AR7240_REG_MAC_ADDR1, t);
+       ar7240sw_reg_write(mii, AR7240_REG_MAC_ADDR1, t);
 
        return 0;
 }
 
 static int
 ar7240_set_vid(struct switch_dev *dev, const struct switch_attr *attr,
-                struct switch_val *val)
+               struct switch_val *val)
 {
        struct ar7240sw *as = sw_to_ar7240(dev);
        as->vlan_id[val->port_vlan] = val->value.i;
@@ -527,7 +545,7 @@ ar7240_set_vid(struct switch_dev *dev, const struct switch_attr *attr,
 
 static int
 ar7240_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
-                struct switch_val *val)
+               struct switch_val *val)
 {
        struct ar7240sw *as = sw_to_ar7240(dev);
        val->value.i = as->vlan_id[val->port_vlan];
@@ -613,7 +631,7 @@ ar7240_set_ports(struct switch_dev *dev, struct switch_val *val)
 
 static int
 ar7240_set_vlan(struct switch_dev *dev, const struct switch_attr *attr,
-                struct switch_val *val)
+               struct switch_val *val)
 {
        struct ar7240sw *as = sw_to_ar7240(dev);
        as->vlan = !!val->value.i;
@@ -622,7 +640,7 @@ ar7240_set_vlan(struct switch_dev *dev, const struct switch_attr *attr,
 
 static int
 ar7240_get_vlan(struct switch_dev *dev, const struct switch_attr *attr,
-                struct switch_val *val)
+               struct switch_val *val)
 {
        struct ar7240sw *as = sw_to_ar7240(dev);
        val->value.i = as->vlan;
@@ -633,16 +651,18 @@ ar7240_get_vlan(struct switch_dev *dev, const struct switch_attr *attr,
 static void
 ar7240_vtu_op(struct ar7240sw *as, u32 op, u32 val)
 {
-       if (ar7240sw_reg_wait(as, AR7240_REG_VTU, AR7240_VTU_ACTIVE, 0, 5))
+       struct mii_bus *mii = as->mii_bus;
+
+       if (ar7240sw_reg_wait(mii, AR7240_REG_VTU, AR7240_VTU_ACTIVE, 0, 5))
                return;
 
        if ((op & AR7240_VTU_OP) == AR7240_VTU_OP_LOAD) {
                val &= AR7240_VTUDATA_MEMBER;
                val |= AR7240_VTUDATA_VALID;
-               ar7240sw_reg_write(as, AR7240_REG_VTU_DATA, val);
+               ar7240sw_reg_write(mii, AR7240_REG_VTU_DATA, val);
        }
        op |= AR7240_VTU_ACTIVE;
-       ar7240sw_reg_write(as, AR7240_REG_VTU, op);
+       ar7240sw_reg_write(mii, AR7240_REG_VTU, op);
 }
 
 static int
@@ -766,16 +786,17 @@ static struct ar7240sw *ar7240_probe(struct ag71xx *ag)
 
        ar7240sw_init(as, mii);
 
-       ctrl = ar7240sw_reg_read(as, AR7240_REG_MASK_CTRL);
+       ctrl = ar7240sw_reg_read(mii, AR7240_REG_MASK_CTRL);
 
        ver = (ctrl >> AR7240_MASK_CTRL_VERSION_S) & AR7240_MASK_CTRL_VERSION_M;
        if (ver != 1) {
-               pr_err("%s: unsupported chip, ctrl=%08x\n", ag->dev->name, ctrl);
+               pr_err("%s: unsupported chip, ctrl=%08x\n",
+                       ag->dev->name, ctrl);
                return NULL;
        }
 
-       phy_id1 = ar7240sw_phy_read(as, 0, MII_PHYSID1);
-       phy_id2 = ar7240sw_phy_read(as, 0, MII_PHYSID2);
+       phy_id1 = ar7240sw_phy_read(mii, 0, MII_PHYSID1);
+       phy_id2 = ar7240sw_phy_read(mii, 0, MII_PHYSID2);
        if (phy_id1 != AR7240_PHY_ID1 || phy_id2 != AR7240_PHY_ID2) {
                pr_err("%s: unknown phy id '%04x:%04x'\n",
                       ag->dev->name, phy_id1, phy_id2);
@@ -790,11 +811,11 @@ static struct ar7240sw *ar7240_probe(struct ag71xx *ag)
        swdev->ops = &ar7240_ops;
 
        if (register_switch(&as->swdev, ag->dev) < 0) {
-           kfree(as);
-           return NULL;
+               kfree(as);
+               return NULL;
        }
 
-       printk("%s: Found an AR7240 built-in switch\n", ag->dev->name);
+       pr_info("%s: Found an AR7240 built-in switch\n", ag->dev->name);
 
        /* initialize defaults */
        for (i = 0; i < AR7240_MAX_VLANS; i++)
@@ -824,7 +845,7 @@ void ag71xx_ar7240_stop(struct ag71xx *ag)
 {
 }
 
-int __init ag71xx_ar7240_init(struct ag71xx *ag)
+int __devinit ag71xx_ar7240_init(struct ag71xx *ag)
 {
        struct ar7240sw *as;
 
@@ -838,7 +859,7 @@ int __init ag71xx_ar7240_init(struct ag71xx *ag)
        return 0;
 }
 
-void __exit ag71xx_ar7240_cleanup(struct ag71xx *ag)
+void __devexit ag71xx_ar7240_cleanup(struct ag71xx *ag)
 {
        struct ar7240sw *as = ag->phy_priv;
 
index c37265e..8111cad 100644 (file)
@@ -44,8 +44,8 @@ void ag71xx_debugfs_update_int_stats(struct ag71xx *ag, u32 status)
 static ssize_t read_file_int_stats(struct file *file, char __user *user_buf,
                                   size_t count, loff_t *ppos)
 {
-#define PR_INT_STAT(_label, _field)                                    \
-       len += snprintf(buf + len, sizeof(buf) - len,                   \
+#define PR_INT_STAT(_label, _field)                                    \
+       len += snprintf(buf + len, sizeof(buf) - len,                   \
                "%20s: %10lu\n", _label, ag->debug.int_stats._field);
 
        struct ag71xx *ag = file->private_data;
@@ -173,7 +173,7 @@ int ag71xx_debugfs_init(struct ag71xx *ag)
 
        return 0;
 
- err:
+err:
        ag71xx_debugfs_exit(ag);
        return -ENOMEM;
 }
index fc838f4..eae443e 100644 (file)
 #include "ag71xx.h"
 
 #define AG71XX_DEFAULT_MSG_ENABLE      \
-       ( NETIF_MSG_DRV                 \
+       (NETIF_MSG_DRV                  \
        | NETIF_MSG_PROBE               \
        | NETIF_MSG_LINK                \
        | NETIF_MSG_TIMER               \
        | NETIF_MSG_IFDOWN              \
        | NETIF_MSG_IFUP                \
        | NETIF_MSG_RX_ERR              \
-       | NETIF_MSG_TX_ERR )
+       | NETIF_MSG_TX_ERR)
 
 static int ag71xx_msg_level = -1;
 
@@ -119,14 +119,15 @@ static int ag71xx_ring_alloc(struct ag71xx_ring *ring, unsigned int size)
        }
 
        for (i = 0; i < size; i++) {
-               ring->buf[i].desc = (struct ag71xx_desc *)&ring->descs_cpu[i * ring->desc_size];
+               int idx = i * ring->desc_size;
+               ring->buf[i].desc = (struct ag71xx_desc *)&ring->descs_cpu[idx];
                DBG("ag71xx: ring %p, desc %d at %p\n",
                        ring, i, ring->buf[i].desc);
        }
 
        return 0;
 
- err:
+err:
        return err;
 }
 
@@ -573,16 +574,12 @@ static void ag71xx_hw_stop(struct ag71xx *ag)
 static int ag71xx_open(struct net_device *dev)
 {
        struct ag71xx *ag = netdev_priv(dev);
-       struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
        int ret;
 
        ret = ag71xx_rings_init(ag);
        if (ret)
                goto err;
 
-       if (pdata->is_ar724x)
-               ag71xx_hw_init(ag);
-
        napi_enable(&ag->napi);
 
        netif_carrier_off(dev);
@@ -599,7 +596,7 @@ static int ag71xx_open(struct net_device *dev)
 
        return 0;
 
- err:
+err:
        ag71xx_rings_cleanup(ag);
        return ret;
 }
@@ -676,7 +673,7 @@ static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb,
 
        return NETDEV_TX_OK;
 
- err_drop:
+err_drop:
        dev->stats.tx_dropped++;
 
        dev_kfree_skb(skb);
@@ -685,7 +682,6 @@ static netdev_tx_t ag71xx_hard_start_xmit(struct sk_buff *skb,
 
 static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *) &ifr->ifr_data;
        struct ag71xx *ag = netdev_priv(dev);
        int ret;
 
@@ -717,7 +713,7 @@ static int ag71xx_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                if (ag->phy_dev == NULL)
                        break;
 
-               return phy_mii_ioctl(ag->phy_dev, data, cmd);
+               return phy_mii_ioctl(ag->phy_dev, ifr, cmd);
 
        default:
                break;
@@ -747,8 +743,13 @@ static void ag71xx_tx_timeout(struct net_device *dev)
 static void ag71xx_restart_work_func(struct work_struct *work)
 {
        struct ag71xx *ag = container_of(work, struct ag71xx, restart_work);
+       struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
 
        ag71xx_stop(ag->dev);
+
+       if (pdata->is_ar724x)
+               ag71xx_hw_init(ag);
+
        ag71xx_open(ag->dev);
 }
 
@@ -909,12 +910,12 @@ static int ag71xx_poll(struct napi_struct *napi, int limit)
                return rx_done;
        }
 
- more:
+more:
        DBG("%s: stay in polling mode, rx=%d, tx=%d, limit=%d\n",
                        dev->name, rx_done, tx_done, limit);
        return rx_done;
 
- oom:
+oom:
        if (netif_msg_rx_err(ag))
                printk(KERN_DEBUG "%s: out of memory\n", dev->name);
 
@@ -991,7 +992,7 @@ static const struct net_device_ops ag71xx_netdev_ops = {
 #endif
 };
 
-static int __init ag71xx_probe(struct platform_device *pdev)
+static int __devinit ag71xx_probe(struct platform_device *pdev)
 {
        struct net_device *dev;
        struct resource *res;
@@ -1058,7 +1059,7 @@ static int __init ag71xx_probe(struct platform_device *pdev)
 
        dev->irq = platform_get_irq(pdev, 0);
        err = request_irq(dev->irq, ag71xx_interrupt,
-                         IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
+                         IRQF_DISABLED,
                          dev->name, dev);
        if (err) {
                dev_err(&pdev->dev, "unable to request IRQ %d\n", dev->irq);
@@ -1106,24 +1107,24 @@ static int __init ag71xx_probe(struct platform_device *pdev)
 
        return 0;
 
- err_phy_disconnect:
+err_phy_disconnect:
        ag71xx_phy_disconnect(ag);
- err_unregister_netdev:
+err_unregister_netdev:
        unregister_netdev(dev);
- err_free_irq:
+err_free_irq:
        free_irq(dev->irq, dev);
- err_unmap_mii_ctrl:
+err_unmap_mii_ctrl:
        iounmap(ag->mii_ctrl);
- err_unmap_base:
+err_unmap_base:
        iounmap(ag->mac_base);
- err_free_dev:
+err_free_dev:
        kfree(dev);
- err_out:
+err_out:
        platform_set_drvdata(pdev, NULL);
        return err;
 }
 
-static int __exit ag71xx_remove(struct platform_device *pdev)
+static int __devexit ag71xx_remove(struct platform_device *pdev)
 {
        struct net_device *dev = platform_get_drvdata(pdev);
 
@@ -1169,11 +1170,11 @@ static int __init ag71xx_module_init(void)
 
        return 0;
 
- err_mdio_exit:
+err_mdio_exit:
        ag71xx_mdio_driver_exit();
- err_debugfs_exit:
+err_debugfs_exit:
        ag71xx_debugfs_root_exit();
- err_out:
+err_out:
        return ret;
 }
 
index 3984840..b2460d7 100644 (file)
@@ -47,7 +47,7 @@ static void ag71xx_mdio_dump_regs(struct ag71xx_mdio *am)
                ag71xx_mdio_rr(am, AG71XX_REG_MII_IND));
 }
 
-static int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg)
+int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg)
 {
        int ret;
        int i;
@@ -73,12 +73,11 @@ static int ag71xx_mdio_mii_read(struct ag71xx_mdio *am, int addr, int reg)
 
        DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, ret);
 
- out:
+out:
        return ret;
 }
 
-static void ag71xx_mdio_mii_write(struct ag71xx_mdio *am,
-                                 int addr, int reg, u16 val)
+void ag71xx_mdio_mii_write(struct ag71xx_mdio *am, int addr, int reg, u16 val)
 {
        int i;
 
@@ -122,18 +121,24 @@ static int ag71xx_mdio_read(struct mii_bus *bus, int addr, int reg)
 {
        struct ag71xx_mdio *am = bus->priv;
 
-       return ag71xx_mdio_mii_read(am, addr, reg);
+       if (am->pdata->is_ar7240)
+               return ar7240sw_phy_read(bus, addr, reg);
+       else
+               return ag71xx_mdio_mii_read(am, addr, reg);
 }
 
 static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val)
 {
        struct ag71xx_mdio *am = bus->priv;
 
-       ag71xx_mdio_mii_write(am, addr, reg, val);
+       if (am->pdata->is_ar7240)
+               ar7240sw_phy_write(bus, addr, reg, val);
+       else
+               ag71xx_mdio_mii_write(am, addr, reg, val);
        return 0;
 }
 
-static int __init ag71xx_mdio_probe(struct platform_device *pdev)
+static int __devinit ag71xx_mdio_probe(struct platform_device *pdev)
 {
        struct ag71xx_mdio_platform_data *pdata;
        struct ag71xx_mdio *am;
@@ -199,17 +204,17 @@ static int __init ag71xx_mdio_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, am);
        return 0;
 
- err_free_bus:
+err_free_bus:
        mdiobus_free(am->mii_bus);
- err_iounmap:
+err_iounmap:
        iounmap(am->mdio_base);
- err_free_mdio:
+err_free_mdio:
        kfree(am);
- err_out:
+err_out:
        return err;
 }
 
-static int __exit ag71xx_mdio_remove(struct platform_device *pdev)
+static int __devexit ag71xx_mdio_remove(struct platform_device *pdev)
 {
        struct ag71xx_mdio *am = platform_get_drvdata(pdev);
 
@@ -232,7 +237,7 @@ static struct platform_driver ag71xx_mdio_driver = {
        }
 };
 
-int ag71xx_mdio_driver_init(void)
+int __init ag71xx_mdio_driver_init(void)
 {
        return platform_driver_register(&ag71xx_mdio_driver);
 }
index eada693..d70aaf0 100644 (file)
@@ -190,7 +190,7 @@ static struct mii_bus *dev_to_mii_bus(struct device *dev)
        return NULL;
 }
 
-int ag71xx_phy_connect(struct ag71xx *ag)
+int __devinit ag71xx_phy_connect(struct ag71xx *ag)
 {
        struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);
 
@@ -217,7 +217,7 @@ int ag71xx_phy_connect(struct ag71xx *ag)
        return ag71xx_phy_connect_fixed(ag);
 }
 
-void ag71xx_phy_disconnect(struct ag71xx *ag)
+void __devexit ag71xx_phy_disconnect(struct ag71xx *ag)
 {
        struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);