Changeset 11995


Ignore:
Timestamp:
2008-07-29T20:22:38+02:00 (10 years ago)
Author:
juhosg
Message:

[ar71xx] ethernet driver updates

  • new mii bus code, mac0 and mac1 can use the mac0's miii bus from now on
  • swap eth0 & eth1 on RB433/450
Location:
trunk/target/linux/ar71xx
Files:
2 added
2 deleted
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/ar71xx/files/arch/mips/ar71xx/mach-generic.c

    r11894 r11995  
    5050                                ARRAY_SIZE(ar71xx_generic_spi_info)); 
    5151 
    52         ar71xx_add_device_eth(0, PHY_INTERFACE_MODE_MII, 0x001f0000); 
    53         ar71xx_add_device_eth(1, PHY_INTERFACE_MODE_RMII, 0xffffffff); 
     52        ar71xx_add_device_mdio(0xffe0ffff); 
     53        ar71xx_add_device_eth(0, PHY_INTERFACE_MODE_MII, 0x000f0000); 
     54        ar71xx_add_device_eth(1, PHY_INTERFACE_MODE_RMII, 0x00100000); 
    5455 
    5556        ar71xx_add_device_usb(); 
  • trunk/target/linux/ar71xx/files/arch/mips/ar71xx/mach-rb-4xx.c

    r11894 r11995  
    154154        rb4xx_add_device_spi(); 
    155155 
     156        ar71xx_add_device_mdio(0xfffffffe); 
    156157        ar71xx_add_device_eth(0, PHY_INTERFACE_MODE_MII, 0x00000001); 
    157158 
     
    168169        rb433_add_device_spi(); 
    169170 
    170         ar71xx_add_device_eth(0, PHY_INTERFACE_MODE_MII, 0x00000001); 
    171         ar71xx_add_device_eth(1, PHY_INTERFACE_MODE_RMII, 0xffffffff); 
     171        ar71xx_add_device_mdio(0xffffffec); 
     172        ar71xx_add_device_eth(1, PHY_INTERFACE_MODE_RMII, 0x00000010); 
     173        ar71xx_add_device_eth(0, PHY_INTERFACE_MODE_MII, 0x00000003); 
    172174 
    173175        platform_device_register(&rb4xx_leds_gpio_device); 
     
    183185        rb4xx_add_device_spi(); 
    184186 
    185         ar71xx_add_device_eth(0, PHY_INTERFACE_MODE_MII, 0x00000001); 
    186         ar71xx_add_device_eth(1, PHY_INTERFACE_MODE_RMII, 0xffffffff); 
     187        ar71xx_add_device_mdio(0xffffffe0); 
     188        ar71xx_add_device_eth(1, PHY_INTERFACE_MODE_RMII, 0x00000010); 
     189        ar71xx_add_device_eth(0, PHY_INTERFACE_MODE_MII, 0x0000000f); 
    187190 
    188191        platform_device_register(&rb4xx_leds_gpio_device); 
  • trunk/target/linux/ar71xx/files/arch/mips/ar71xx/mach-wp543.c

    r11894 r11995  
    4949        ar71xx_add_device_spi(NULL, wp543_spi_info, ARRAY_SIZE(wp543_spi_info)); 
    5050 
     51        ar71xx_add_device_mdio(0xfffffffe); 
    5152        ar71xx_add_device_eth(0, PHY_INTERFACE_MODE_MII, 0x00000001); 
    5253 
  • trunk/target/linux/ar71xx/files/arch/mips/ar71xx/platform.c

    r11910 r11995  
    144144#endif /* CONFIG_AR71XX_EARLY_SERIAL */ 
    145145 
     146static struct resource ar71xx_mdio_resources[] = { 
     147        { 
     148                .name   = "mdio_base", 
     149                .flags  = IORESOURCE_MEM, 
     150                .start  = AR71XX_GE0_BASE + 0x20, 
     151                .end    = AR71XX_GE0_BASE + 0x38 - 1, 
     152        } 
     153}; 
     154 
     155static struct ag71xx_mdio_platform_data ar71xx_mdio_data = { 
     156        .phy_mask       = 0xffffffff, 
     157}; 
     158 
     159static struct platform_device ar71xx_mdio_device = { 
     160        .name           = "ag71xx-mdio", 
     161        .id             = -1, 
     162        .resource       = ar71xx_mdio_resources, 
     163        .num_resources  = ARRAY_SIZE(ar71xx_mdio_resources), 
     164        .dev = { 
     165                .platform_data = &ar71xx_mdio_data, 
     166        }, 
     167}; 
     168 
     169void __init ar71xx_add_device_mdio(u32 phy_mask) 
     170{ 
     171        ar71xx_mdio_data.phy_mask = phy_mask; 
     172        platform_device_register(&ar71xx_mdio_device); 
     173} 
     174 
    146175static struct resource ar71xx_eth0_resources[] = { 
    147176        { 
     
    149178                .flags  = IORESOURCE_MEM, 
    150179                .start  = AR71XX_GE0_BASE, 
    151                 .end    = AR71XX_GE0_BASE + AR71XX_GE0_SIZE - 1, 
     180                .end    = AR71XX_GE0_BASE + 0x20 - 1, 
     181        }, { 
     182                .name   = "mac_base2", 
     183                .flags  = IORESOURCE_MEM, 
     184                .start  = AR71XX_GE0_BASE + 0x38, 
     185                .end    = AR71XX_GE0_BASE + 0x200 - 1, 
    152186        }, { 
    153187                .name   = "mii_ctrl", 
     
    183217                .flags  = IORESOURCE_MEM, 
    184218                .start  = AR71XX_GE1_BASE, 
    185                 .end    = AR71XX_GE1_BASE + AR71XX_GE1_SIZE - 1, 
     219                .end    = AR71XX_GE1_BASE + 0x20 - 1, 
     220        }, { 
     221                .name   = "mac_base2", 
     222                .flags  = IORESOURCE_MEM, 
     223                .start  = AR71XX_GE1_BASE + 0x38, 
     224                .end    = AR71XX_GE1_BASE + 0x200 - 1, 
    186225        }, { 
    187226                .name   = "mii_ctrl", 
     
    212251}; 
    213252 
     253static int ar71xx_eth_instance __initdata; 
    214254void __init ar71xx_add_device_eth(unsigned int id, phy_interface_t phy_if_mode, 
    215255                                u32 phy_mask) 
     
    236276                } 
    237277                memcpy(ar71xx_eth0_data.mac_addr, ar71xx_mac_base, ETH_ALEN); 
     278                ar71xx_eth0_data.mac_addr[5] += ar71xx_eth_instance; 
    238279                ar71xx_eth0_data.phy_if_mode = phy_if_mode; 
    239280                ar71xx_eth0_data.phy_mask = phy_mask; 
     
    252293                } 
    253294                memcpy(ar71xx_eth1_data.mac_addr, ar71xx_mac_base, ETH_ALEN); 
    254                 ar71xx_eth1_data.mac_addr[5] += id; 
     295                ar71xx_eth1_data.mac_addr[5] += ar71xx_eth_instance; 
    255296                ar71xx_eth1_data.phy_if_mode = phy_if_mode; 
    256297                ar71xx_eth1_data.phy_mask = phy_mask; 
     
    262303        } 
    263304 
    264         if (pdev) 
     305        if (pdev) { 
    265306                platform_device_register(pdev); 
     307                ar71xx_eth_instance++; 
     308        } 
    266309} 
    267310 
  • trunk/target/linux/ar71xx/files/drivers/net/ag71xx/Makefile

    r11894 r11995  
    55obj-$(CONFIG_AG71XX)    += ag71xx.o 
    66 
    7 ag71xx-objs     := ag71xx_main.o ag71xx_mii.o ag71xx_ethtool.o 
     7ag71xx-objs     := ag71xx_main.o ag71xx_ethtool.o ag71xx_phy.o ag71xx_mdio.o 
  • trunk/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h

    r11910 r11995  
    1616 
    1717#include <linux/kernel.h> 
     18#include <linux/version.h> 
    1819#include <linux/module.h> 
    1920#include <linux/init.h> 
     
    3738 
    3839#define AG71XX_DRV_NAME         "ag71xx" 
    39 #define AG71XX_DRV_VERSION      "0.3.10" 
     40#define AG71XX_DRV_VERSION      "0.4.0" 
    4041 
    4142#define AG71XX_NAPI_TX          1 
     
    6869#define AG71XX_RX_RING_SIZE     128 
    6970 
    70 #undef DEBUG 
    71 #ifdef DEBUG 
     71#undef AG71XX_DEBUG 
     72#ifdef AG71XX_DEBUG 
    7273#define DBG(fmt, args...)       printk(KERN_DEBUG fmt, ## args) 
    7374#else 
     
    105106}; 
    106107 
     108struct ag71xx_mdio { 
     109        struct mii_bus  mii_bus; 
     110        int             mii_irq[PHY_MAX_ADDR]; 
     111        void __iomem    *mdio_base; 
     112}; 
     113 
    107114struct ag71xx { 
    108115        void __iomem            *mac_base; 
     116        void __iomem            *mac_base2; 
    109117        void __iomem            *mii_ctrl; 
    110118 
     
    117125        struct ag71xx_ring      tx_ring; 
    118126 
     127        struct mii_bus          *mii_bus; 
    119128        struct phy_device       *phy_dev; 
    120         struct mii_bus          mii_bus; 
    121129 
    122130        unsigned int            link; 
     
    127135extern struct ethtool_ops ag71xx_ethtool_ops; 
    128136 
    129 extern int ag71xx_mdio_init(struct ag71xx *ag, int id); 
    130 extern void ag71xx_mdio_cleanup(struct ag71xx *ag); 
    131 extern int ag71xx_mii_peek(struct ag71xx *ag); 
    132 extern void ag71xx_mii_ctrl_set_if(struct ag71xx *ag, unsigned int mii_if); 
    133 extern void ag71xx_mii_ctrl_set_speed(struct ag71xx *ag, unsigned int speed); 
    134 extern void ag71xx_link_update(struct ag71xx *ag); 
     137extern struct ag71xx_mdio *ag71xx_mdio_bus; 
     138extern int ag71xx_mdio_driver_init(void) __init; 
     139extern void ag71xx_mdio_driver_exit(void); 
     140 
     141extern int ag71xx_phy_connect(struct ag71xx *ag); 
     142extern void ag71xx_phy_disconnect(struct ag71xx *ag); 
     143extern void ag71xx_phy_start(struct ag71xx *ag); 
     144extern void ag71xx_phy_stop(struct ag71xx *ag); 
    135145 
    136146static inline struct ag71xx_platform_data *ag71xx_get_pdata(struct ag71xx *ag) 
    137147{ 
    138148        return ag->pdev->dev.platform_data; 
    139 } 
    140  
    141 static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value) 
    142 { 
    143         __raw_writel(value, ag->mac_base + reg); 
    144 } 
    145  
    146 static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg) 
    147 { 
    148         return __raw_readl(ag->mac_base + reg); 
    149 } 
    150  
    151 static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask) 
    152 { 
    153         void __iomem *r = ag->mac_base + reg; 
    154  
    155         __raw_writel(__raw_readl(r) | mask, r); 
    156 } 
    157  
    158 static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask) 
    159 { 
    160         void __iomem *r = ag->mac_base + reg; 
    161  
    162         __raw_writel(__raw_readl(r) & ~mask, r); 
    163149} 
    164150 
     
    243229#define MII_CFG_CLK_DIV_20      6 
    244230#define MII_CFG_CLK_DIV_28      7 
     231#define MII_CFG_RESET           BIT(31) 
    245232 
    246233#define MII_CMD_WRITE           0x0 
     
    264251#define FIFO_CFG5_BYTE_PER_CLK  BIT(19) 
    265252 
    266 #define MII_CTRL_SPEED_S        4 
    267 #define MII_CTRL_SPEED_M        3 
     253#define MII_CTRL_IF_MASK        3 
     254#define MII_CTRL_SPEED_SHIFT    4 
     255#define MII_CTRL_SPEED_MASK     3 
    268256#define MII_CTRL_SPEED_10       0 
    269257#define MII_CTRL_SPEED_100      1 
    270258#define MII_CTRL_SPEED_1000     2 
    271259 
     260static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value) 
     261{ 
     262        switch (reg) { 
     263        case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL: 
     264                __raw_writel(value, ag->mac_base + reg); 
     265                break; 
     266        case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS: 
     267                reg -= AG71XX_REG_MAC_IFCTL; 
     268                __raw_writel(value, ag->mac_base2 + reg); 
     269                break; 
     270        default: 
     271                BUG(); 
     272        } 
     273} 
     274 
     275static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg) 
     276{ 
     277        u32 ret; 
     278 
     279        switch (reg) { 
     280        case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL: 
     281                ret = __raw_readl(ag->mac_base + reg); 
     282                break; 
     283        case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS: 
     284                reg -= AG71XX_REG_MAC_IFCTL; 
     285                ret = __raw_readl(ag->mac_base2 + reg); 
     286                break; 
     287        } 
     288 
     289        return ret; 
     290} 
     291 
     292static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask) 
     293{ 
     294        void __iomem *r; 
     295 
     296        switch (reg) { 
     297        case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL: 
     298                r = ag->mac_base + reg; 
     299                __raw_writel(__raw_readl(r) | mask, r); 
     300                break; 
     301        case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS: 
     302                r = ag->mac_base2 + reg - AG71XX_REG_MAC_IFCTL; 
     303                __raw_writel(__raw_readl(r) | mask, r); 
     304                break; 
     305        default: 
     306                BUG(); 
     307        } 
     308} 
     309 
     310static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask) 
     311{ 
     312        void __iomem *r; 
     313 
     314        switch (reg) { 
     315        case AG71XX_REG_MAC_CFG1 ... AG71XX_REG_MAC_MFL: 
     316                r = ag->mac_base + reg; 
     317                __raw_writel(__raw_readl(r) & ~mask, r); 
     318                break; 
     319        case AG71XX_REG_MAC_IFCTL ... AG71XX_REG_INT_STATUS: 
     320                r = ag->mac_base2 + reg - AG71XX_REG_MAC_IFCTL; 
     321                __raw_writel(__raw_readl(r) & ~mask, r); 
     322                break; 
     323        default: 
     324                BUG(); 
     325        } 
     326} 
     327 
    272328static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints) 
    273329{ 
     
    280336} 
    281337 
     338static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value) 
     339{ 
     340        __raw_writel(value, ag->mii_ctrl); 
     341} 
     342 
     343static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag) 
     344{ 
     345        return __raw_readl(ag->mii_ctrl); 
     346} 
     347 
     348static void inline ag71xx_mii_ctrl_set_if(struct ag71xx *ag, 
     349                                          unsigned int mii_if) 
     350{ 
     351        u32 t; 
     352 
     353        t = ag71xx_mii_ctrl_rr(ag); 
     354        t &= ~(MII_CTRL_IF_MASK); 
     355        t |= (mii_if & MII_CTRL_IF_MASK); 
     356        ag71xx_mii_ctrl_wr(ag, t); 
     357} 
     358 
     359static void inline ag71xx_mii_ctrl_set_speed(struct ag71xx *ag, 
     360                                             unsigned int speed) 
     361{ 
     362        u32 t; 
     363 
     364        t = ag71xx_mii_ctrl_rr(ag); 
     365        t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT); 
     366        t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT; 
     367        ag71xx_mii_ctrl_wr(ag, t); 
     368} 
     369 
    282370#endif /* _AG71XX_H */ 
  • trunk/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_main.c

    r11910 r11995  
    2323                ag71xx_rr(ag, AG71XX_REG_MAC_HDX), 
    2424                ag71xx_rr(ag, AG71XX_REG_MAC_MFL)); 
    25         DBG("%s: mii_cfg=%08x, mii_cmd=%08x, mii_addr=%08x\n", 
    26                 ag->dev->name, 
    27                 ag71xx_rr(ag, AG71XX_REG_MII_CFG), 
    28                 ag71xx_rr(ag, AG71XX_REG_MII_CMD), 
    29                 ag71xx_rr(ag, AG71XX_REG_MII_ADDR)); 
    30         DBG("%s: mii_ctrl=%08x, mii_status=%08x, mii_ind=%08x\n", 
    31                 ag->dev->name, 
    32                 ag71xx_rr(ag, AG71XX_REG_MII_CTRL), 
    33                 ag71xx_rr(ag, AG71XX_REG_MII_STATUS), 
    34                 ag71xx_rr(ag, AG71XX_REG_MII_IND)); 
    3525        DBG("%s: mac_ifctl=%08x, mac_addr1=%08x, mac_addr2=%08x\n", 
    3626                ag->dev->name, 
     
    287277        ag71xx_mii_ctrl_set_if(ag, pdata->mii_if); 
    288278 
    289         ag71xx_wr(ag, AG71XX_REG_MII_CFG, MII_CFG_CLK_DIV_28); 
    290  
    291279        ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000); 
    292280        ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff); 
     
    326314 
    327315        netif_carrier_off(dev); 
    328         if (ag->phy_dev) { 
    329                 phy_start(ag->phy_dev); 
    330         } else { 
    331                 ag->duplex = DUPLEX_FULL; 
    332                 ag->speed = SPEED_100; 
    333                 ag->link = 1; 
    334                 ag71xx_link_update(ag); 
    335         } 
     316        ag71xx_phy_start(ag); 
    336317 
    337318        ag71xx_wr(ag, AG71XX_REG_TX_DESC, ag->tx_ring.descs_dma); 
     
    363344 
    364345        netif_carrier_off(dev); 
    365         if (ag->phy_dev) { 
    366                 phy_stop(ag->phy_dev); 
    367         } else { 
    368                 ag->duplex = -1; 
    369                 ag->link = 0; 
    370                 ag->speed = 0; 
    371                 ag71xx_link_update(ag); 
    372         } 
     346        ag71xx_phy_stop(ag); 
    373347 
    374348        napi_disable(&ag->napi); 
     
    718692        ag->pdev = pdev; 
    719693        ag->dev = dev; 
     694        ag->mii_bus = &ag71xx_mdio_bus->mii_bus; 
    720695        spin_lock_init(&ag->lock); 
    721696 
     
    734709        } 
    735710 
     711        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mac_base2"); 
     712        if (!res) { 
     713                dev_err(&pdev->dev, "no mac_base2 resource found\n"); 
     714                err = -ENXIO; 
     715                goto err_unmap_base1; 
     716        } 
     717 
     718        ag->mac_base2 = ioremap_nocache(res->start, res->end - res->start + 1); 
     719        if (!ag->mac_base) { 
     720                dev_err(&pdev->dev, "unable to ioremap mac_base2\n"); 
     721                err = -ENOMEM; 
     722                goto err_unmap_base1; 
     723        } 
     724 
    736725        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mii_ctrl"); 
    737726        if (!res) { 
    738727                dev_err(&pdev->dev, "no mii_ctrl resource found\n"); 
    739728                err = -ENXIO; 
    740                 goto err_unmap_base; 
     729                goto err_unmap_base2; 
    741730        } 
    742731 
     
    745734                dev_err(&pdev->dev, "unable to ioremap mii_ctrl\n"); 
    746735                err = -ENOMEM; 
    747                 goto err_unmap_base; 
     736                goto err_unmap_base2; 
    748737        } 
    749738 
     
    791780        ag71xx_dump_regs(ag); 
    792781 
    793         err = ag71xx_mdio_init(ag, pdev->id); 
     782        /* Reset the mdio bus explicitly */ 
     783        if (ag->mii_bus) { 
     784                mutex_lock(&ag->mii_bus->mdio_lock); 
     785                ag->mii_bus->reset(ag->mii_bus); 
     786                mutex_unlock(&ag->mii_bus->mdio_lock); 
     787        } 
     788 
     789        err = ag71xx_phy_connect(ag); 
    794790        if (err) 
    795791                goto err_unregister_netdev; 
     
    805801err_unmap_mii_ctrl: 
    806802        iounmap(ag->mii_ctrl); 
    807 err_unmap_base: 
     803err_unmap_base2: 
     804        iounmap(ag->mac_base2); 
     805err_unmap_base1: 
    808806        iounmap(ag->mac_base); 
    809807err_free_dev: 
     
    821819                struct ag71xx *ag = netdev_priv(dev); 
    822820 
    823                 if (ag->phy_dev) 
    824                         phy_disconnect(ag->phy_dev); 
    825                 ag71xx_mdio_cleanup(ag); 
     821                ag71xx_phy_disconnect(ag); 
    826822                unregister_netdev(dev); 
    827823                free_irq(dev->irq, dev); 
    828824                iounmap(ag->mii_ctrl); 
     825                iounmap(ag->mac_base2); 
    829826                iounmap(ag->mac_base); 
    830827                kfree(dev); 
     
    845842static int __init ag71xx_module_init(void) 
    846843{ 
    847         return platform_driver_register(&ag71xx_driver); 
     844        int ret; 
     845 
     846        ret = ag71xx_mdio_driver_init(); 
     847        if (ret) 
     848                goto err_out; 
     849 
     850        ret = platform_driver_register(&ag71xx_driver); 
     851        if (ret) 
     852                goto err_mdio_exit; 
     853 
     854        return 0; 
     855 
     856err_mdio_exit: 
     857        ag71xx_mdio_driver_exit(); 
     858err_out: 
     859        return ret; 
    848860} 
    849861 
  • trunk/target/linux/ar71xx/files/include/asm-mips/mach-ar71xx/platform.h

    r11910 r11995  
    2727}; 
    2828 
     29struct ag71xx_mdio_platform_data { 
     30        u32             phy_mask; 
     31}; 
     32 
    2933struct ar71xx_spi_platform_data { 
    3034        unsigned        bus_num; 
     
    4448                                u32 phy_mask) __init; 
    4549 
     50extern void ar71xx_add_device_mdio(u32 phy_mask) __init; 
     51 
    4652#endif /* __ASM_MACH_AR71XX_PLATFORM_H */ 
Note: See TracChangeset for help on using the changeset viewer.