Changeset 20722


Ignore:
Timestamp:
2010-04-06T01:03:16+02:00 (7 years ago)
Author:
jow
Message:

[PATCH 1/2] Add support for the ar8316 switch.
This patch enhances the ar8216 driver with ar8316 support and fixes some minor
issues with the ar8216 driver itself. It should not break anything, but isn't
tested on ar8216 devices.

[PATCH 2/2] ar71xx: Add the ar8316 driver to rs pro/rb-450g.
Add the ar8216 driver to the ar71xx target, and add network
configurations for the RouterStation Pro and the RouterBoard RB-450G.

Location:
trunk/target/linux
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/ar71xx/base-files/etc/defconfig/routerstation-pro/network

    r18103 r20722  
    1515        option ifname   eth0 
    1616        option proto    dhcp 
     17 
     18config switch 
     19        option name     eth1 
     20        option reset    1 
     21        option enable_vlan 1 
     22 
     23config switch_vlan 
     24        option device   eth1 
     25        option vlan     1 
     26        option ports    "0 1 2 3 4" 
  • trunk/target/linux/ar71xx/config-2.6.32

    r20495 r20722  
    4545CONFIG_AR71XX_NVRAM=y 
    4646CONFIG_AR71XX_WDT=y 
     47CONFIG_AR8216_PHY=y 
    4748# CONFIG_ARCH_HAS_ILOG2_U32 is not set 
    4849# CONFIG_ARCH_HAS_ILOG2_U64 is not set 
  • trunk/target/linux/ar71xx/config-2.6.33

    r20495 r20722  
    4545CONFIG_AR71XX_NVRAM=y 
    4646CONFIG_AR71XX_WDT=y 
     47CONFIG_AR8216_PHY=y 
    4748# CONFIG_ARCH_HAS_ILOG2_U32 is not set 
    4849# CONFIG_ARCH_HAS_ILOG2_U64 is not set 
  • trunk/target/linux/ar71xx/config-2.6.34

    r20495 r20722  
    4444CONFIG_AR71XX_NVRAM=y 
    4545CONFIG_AR71XX_WDT=y 
     46CONFIG_AR8216_PHY=y 
    4647# CONFIG_ARCH_HAS_ILOG2_U32 is not set 
    4748# CONFIG_ARCH_HAS_ILOG2_U64 is not set 
  • trunk/target/linux/ar71xx/files/arch/mips/ar71xx/mach-rb4xx.c

    r20359 r20722  
    240240 
    241241        ar71xx_eth0_data.phy_if_mode = (gige) ? PHY_INTERFACE_MODE_RGMII : PHY_INTERFACE_MODE_MII; 
     242        ar71xx_eth0_data.phy_mask = (gige) ? (1 << 0) : 0; 
    242243        ar71xx_eth0_data.speed = (gige) ? SPEED_1000 : SPEED_100; 
    243244        ar71xx_eth0_data.duplex = DUPLEX_FULL; 
  • trunk/target/linux/ar71xx/files/arch/mips/ar71xx/mach-ubnt.c

    r20358 r20722  
    178178 
    179179        ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; 
     180        ar71xx_eth1_data.phy_mask = UBNT_RSPRO_LAN_PHYMASK; 
    180181        ar71xx_eth1_data.speed = SPEED_1000; 
    181182        ar71xx_eth1_data.duplex = DUPLEX_FULL; 
  • trunk/target/linux/generic-2.6/files/drivers/net/phy/ar8216.c

    r20083 r20722  
    3232#include "ar8216.h" 
    3333 
     34/* size of the vlan table */ 
     35#define AR8X16_MAX_VLANS        128 
    3436 
    3537struct ar8216_priv { 
     
    4042        const struct net_device_ops *ndo_old; 
    4143        struct net_device_ops ndo; 
     44        struct mutex reg_mutex; 
     45        int chip; 
    4246 
    4347        /* all fields below are cleared on reset */ 
    4448        bool vlan; 
    45         u16 vlan_id[AR8216_NUM_VLANS]; 
    46         u8 vlan_table[AR8216_NUM_VLANS]; 
     49        u16 vlan_id[AR8X16_MAX_VLANS]; 
     50        u8 vlan_table[AR8X16_MAX_VLANS]; 
    4751        u8 vlan_tagged; 
    4852        u16 pvid[AR8216_NUM_PORTS]; 
     
    111115} 
    112116 
     117static inline int 
     118ar8216_id_chip(struct ar8216_priv *priv) 
     119{ 
     120        u32 val; 
     121        u16 id; 
     122        val = ar8216_mii_read(priv, AR8216_REG_CTRL); 
     123        id = val & (AR8216_CTRL_REVISION | AR8216_CTRL_VERSION); 
     124        switch (id) { 
     125        case 0x0101: 
     126                return AR8216; 
     127        case 0x1001: 
     128                return AR8316; 
     129        default: 
     130                printk(KERN_ERR 
     131                        "ar8216: Unknown Atheros device [ver=%d, rev=%d, phy_id=%04x%04x]\n", 
     132                        (int)(val >> AR8216_CTRL_VERSION_S), 
     133                        (int)(val & AR8216_CTRL_REVISION), 
     134                        priv->phy->bus->read(priv->phy->bus, priv->phy->addr, 2), 
     135                        priv->phy->bus->read(priv->phy->bus, priv->phy->addr, 3)); 
     136 
     137                return UNKNOWN; 
     138        } 
     139} 
     140 
    113141static int 
    114142ar8216_set_vlan(struct switch_dev *dev, const struct switch_attr *attr, 
     
    137165        /* make sure no invalid PVIDs get set */ 
    138166 
    139         if (vlan >= AR8216_NUM_VLANS) 
     167        if (vlan >= dev->vlans) 
    140168                return -EINVAL; 
    141169 
     
    337365                        /* make sure that an untagged port does not 
    338366                         * appear in other vlans */ 
    339                         for (j = 0; j < AR8216_NUM_VLANS; j++) { 
     367                        for (j = 0; j < AR8X16_MAX_VLANS; j++) { 
    340368                                if (j == val->port_vlan) 
    341369                                        continue; 
     
    384412        int i, j; 
    385413 
     414        mutex_lock(&priv->reg_mutex); 
    386415        /* flush all vlan translation unit entries */ 
    387416        ar8216_vtu_op(priv, AR8216_VTU_OP_FLUSH, 0); 
     
    391420                /* calculate the port destination masks and load vlans 
    392421                 * into the vlan translation unit */ 
    393                 for (j = 0; j < AR8216_NUM_VLANS; j++) { 
     422                for (j = 0; j < AR8X16_MAX_VLANS; j++) { 
    394423                        u8 vp = priv->vlan_table[j]; 
    395424 
     
    447476                        AR8216_PORT_CTRL_HEADER | AR8216_PORT_CTRL_LEARN_LOCK, 
    448477                        AR8216_PORT_CTRL_LEARN | 
    449                           (priv->vlan && i == AR8216_PORT_CPU ? 
     478                          (priv->vlan && i == AR8216_PORT_CPU && (priv->chip == AR8216) ? 
    450479                           AR8216_PORT_CTRL_HEADER : 0) | 
    451480                          (egress << AR8216_PORT_CTRL_VLAN_MODE_S) | 
     
    459488                          (pvid << AR8216_PORT_VLAN_DEFAULT_ID_S)); 
    460489        } 
    461  
     490        mutex_unlock(&priv->reg_mutex); 
     491        return 0; 
     492} 
     493 
     494static int 
     495ar8316_hw_init(struct ar8216_priv *priv) { 
     496        static int initialized; 
     497        int i; 
     498        u32 val; 
     499        struct mii_bus *bus; 
     500 
     501        if (initialized) 
     502                return 0; 
     503 
     504        val = priv->read(priv, 0x8); 
     505 
     506        if (priv->phy->interface == PHY_INTERFACE_MODE_RGMII) { 
     507                /* value taken from Ubiquiti RouterStation Pro */ 
     508                if (val == 0x81461bea) { 
     509                        /* switch already intialized by bootloader */ 
     510                        initialized = true; 
     511                        return 0; 
     512                } 
     513                priv->write(priv, 0x8, 0x81461bea); 
     514        } else if (priv->phy->interface == PHY_INTERFACE_MODE_GMII) { 
     515                /* value taken from AVM Fritz!Box 7390 sources */ 
     516                if (val == 0x010e5b71) { 
     517                        /* switch already initialized by bootloader */ 
     518                        initialized = true; 
     519                        return 0; 
     520                } 
     521                priv->write(priv, 0x8, 0x010e5b71); 
     522        } else { 
     523                /* no known value for phy interface */ 
     524                printk(KERN_ERR "ar8316: unsupported mii mode: %d.\n", 
     525                        priv->phy->interface); 
     526                return -EINVAL; 
     527        } 
     528 
     529        /* standard atheros magic */ 
     530        priv->write(priv, 0x38, 0xc000050e); 
     531 
     532        /* Initialize the ports */ 
     533        bus = priv->phy->bus; 
     534        for (i = 0; i < 5; i++) { 
     535                if ((i == 4) && 
     536                        priv->phy->interface == PHY_INTERFACE_MODE_RGMII) { 
     537                        /* work around for phy4 rgmii mode */ 
     538                        bus->write(bus, i, MII_ATH_DBG_ADDR, 0x12); 
     539                        bus->write(bus, i, MII_ATH_DBG_DATA, 0x480c); 
     540                        /* rx delay */ 
     541                        bus->write(bus, i, MII_ATH_DBG_ADDR, 0x0); 
     542                        bus->write(bus, i, MII_ATH_DBG_DATA, 0x824e); 
     543                        /* tx delay */ 
     544                        bus->write(bus, i, MII_ATH_DBG_ADDR, 0x5); 
     545                        bus->write(bus, i, MII_ATH_DBG_DATA, 0x3d47); 
     546                        msleep(1000); 
     547                } 
     548 
     549                /* initialize the port itself */ 
     550                bus->write(bus, i, MII_ADVERTISE, 
     551                        ADVERTISE_ALL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); 
     552                bus->write(bus, i, MII_CTRL1000, ADVERTISE_1000FULL); 
     553                bus->write(bus, i, MII_BMCR, BMCR_RESET | BMCR_ANENABLE); 
     554                msleep(1000); 
     555        } 
     556        initialized = true; 
    462557        return 0; 
    463558} 
     
    469564        int i; 
    470565 
     566        mutex_lock(&priv->reg_mutex); 
    471567        memset(&priv->vlan, 0, sizeof(struct ar8216_priv) - 
    472568                offsetof(struct ar8216_priv, vlan)); 
    473         for (i = 0; i < AR8216_NUM_VLANS; i++) { 
     569        for (i = 0; i < AR8X16_MAX_VLANS; i++) { 
    474570                priv->vlan_id[i] = i; 
    475571        } 
     
    486582                        priv->write(priv, AR8216_REG_PORT_STATUS(i), 
    487583                                AR8216_PORT_STATUS_LINK_UP | 
    488                                 AR8216_PORT_SPEED_100M | 
     584                                ((priv->chip == AR8316) ? 
     585                                        AR8216_PORT_SPEED_1000M : AR8216_PORT_SPEED_100M) | 
    489586                                AR8216_PORT_STATUS_TXMAC | 
    490587                                AR8216_PORT_STATUS_RXMAC | 
     588                                ((priv->chip == AR8316) ? AR8216_PORT_STATUS_RXFLOW : 0) | 
     589                                ((priv->chip == AR8316) ? AR8216_PORT_STATUS_TXFLOW : 0) | 
    491590                                AR8216_PORT_STATUS_DUPLEX); 
    492591                } else { 
     
    498597        priv->write(priv, 0x38, 0xc000050e); 
    499598 
    500         ar8216_rmw(priv, AR8216_REG_GLOBAL_CTRL, 
    501                 AR8216_GCTRL_MTU, 1518 + 8 + 2); 
    502  
     599        if (priv->chip == AR8216) { 
     600                ar8216_rmw(priv, AR8216_REG_GLOBAL_CTRL, 
     601                        AR8216_GCTRL_MTU, 1518 + 8 + 2); 
     602        } else if (priv->chip == AR8316) { 
     603                /* enable jumbo frames */ 
     604                ar8216_rmw(priv, AR8216_REG_GLOBAL_CTRL, 
     605                        AR8316_GCTRL_MTU, 9018 + 8 + 2); 
     606        } 
     607 
     608        if (priv->chip == AR8316) { 
     609                /* enable cpu port to receive multicast and broadcast frames */ 
     610                priv->write(priv, AR8216_REG_FLOOD_MASK, 0x003f003f); 
     611        } 
     612        mutex_unlock(&priv->reg_mutex); 
    503613        return ar8216_hw_apply(dev); 
    504614} 
     
    511621        int ret; 
    512622 
    513         printk("%s: AR8216 PHY driver attached.\n", pdev->attached_dev->name); 
    514         pdev->supported = ADVERTISED_100baseT_Full; 
    515         pdev->advertising = ADVERTISED_100baseT_Full; 
    516  
    517623        priv = kzalloc(sizeof(struct ar8216_priv), GFP_KERNEL); 
    518624        if (priv == NULL) 
     
    520626 
    521627        priv->phy = pdev; 
     628 
     629        priv->chip = ar8216_id_chip(priv); 
     630 
     631        printk(KERN_INFO "%s: AR%d PHY driver attached.\n", 
     632                pdev->attached_dev->name, priv->chip); 
     633 
     634        if (pdev->addr != 0) { 
     635                if (priv->chip == AR8316) { 
     636                        pdev->supported |= SUPPORTED_1000baseT_Full; 
     637                        pdev->advertising |= ADVERTISED_1000baseT_Full; 
     638                } 
     639                kfree(priv); 
     640                return 0; 
     641        } 
     642 
     643        pdev->supported = priv->chip == AR8316 ? 
     644                SUPPORTED_1000baseT_Full : SUPPORTED_100baseT_Full; 
     645        pdev->advertising = pdev->supported; 
     646 
     647        mutex_init(&priv->reg_mutex); 
    522648        priv->read = ar8216_mii_read; 
    523649        priv->write = ar8216_mii_write; 
    524650        memcpy(&priv->dev, &athdev, sizeof(struct switch_dev)); 
    525651        pdev->priv = priv; 
     652 
     653        if (priv->chip == AR8316) { 
     654                priv->dev.name = "Atheros AR8316"; 
     655                priv->dev.vlans = AR8X16_MAX_VLANS; 
     656                /* port 5 connected to the other mac, therefore unusable */ 
     657                priv->dev.ports = (AR8216_NUM_PORTS - 1); 
     658        } 
     659 
    526660        if ((ret = register_switch(&priv->dev, pdev->attached_dev)) < 0) { 
    527661                kfree(priv); 
     
    529663        } 
    530664 
     665        if (priv->chip == AR8316) { 
     666                ret = ar8316_hw_init(priv); 
     667                if (ret) { 
     668                        kfree(priv); 
     669                        goto done; 
     670                } 
     671        } 
     672 
    531673        ret = ar8216_reset_switch(&priv->dev); 
    532         if (ret) 
     674        if (ret) { 
     675                kfree(priv); 
    533676                goto done; 
     677        } 
    534678 
    535679        dev->phy_ptr = priv; 
    536         pdev->pkt_align = 2; 
    537         pdev->netif_receive_skb = ar8216_netif_receive_skb; 
    538         pdev->netif_rx = ar8216_netif_rx; 
    539  
    540         priv->ndo_old = dev->netdev_ops; 
    541         memcpy(&priv->ndo, priv->ndo_old, sizeof(struct net_device_ops)); 
    542         priv->ndo.ndo_start_xmit = ar8216_mangle_tx; 
    543         dev->netdev_ops = &priv->ndo; 
     680 
     681        /* VID fixup only needed on ar8216 */ 
     682        if (pdev->addr == 0 && priv->chip == AR8216) { 
     683                pdev->pkt_align = 2; 
     684                pdev->netif_receive_skb = ar8216_netif_receive_skb; 
     685                pdev->netif_rx = ar8216_netif_rx; 
     686                priv->ndo_old = dev->netdev_ops; 
     687                memcpy(&priv->ndo, priv->ndo_old, sizeof(struct net_device_ops)); 
     688                priv->ndo.ndo_start_xmit = ar8216_mangle_tx; 
     689                dev->netdev_ops = &priv->ndo; 
     690        } 
    544691 
    545692done: 
     
    551698{ 
    552699        struct ar8216_priv *priv = phydev->priv; 
    553  
    554         phydev->speed = SPEED_100; 
     700        int ret; 
     701        if (phydev->addr != 0) { 
     702                return genphy_read_status(phydev); 
     703        } 
     704 
     705        phydev->speed = priv->chip == AR8316 ? SPEED_1000 : SPEED_100; 
    555706        phydev->duplex = DUPLEX_FULL; 
    556707        phydev->link = 1; 
    557708 
    558709        /* flush the address translation unit */ 
    559         if (ar8216_wait_bit(priv, AR8216_REG_ATU, AR8216_ATU_ACTIVE, 0)) 
    560                 return -ETIMEDOUT; 
    561  
    562         priv->write(priv, AR8216_REG_ATU, AR8216_ATU_OP_FLUSH); 
     710        mutex_lock(&priv->reg_mutex); 
     711        ret = ar8216_wait_bit(priv, AR8216_REG_ATU, AR8216_ATU_ACTIVE, 0); 
     712 
     713        if (!ret) 
     714                priv->write(priv, AR8216_REG_ATU, AR8216_ATU_OP_FLUSH); 
     715        else 
     716                ret = -ETIMEDOUT; 
     717        mutex_unlock(&priv->reg_mutex); 
    563718 
    564719        phydev->state = PHY_RUNNING; 
     
    566721        phydev->adjust_link(phydev->attached_dev); 
    567722 
    568         return 0; 
     723        return ret; 
    569724} 
    570725 
     
    572727ar8216_config_aneg(struct phy_device *phydev) 
    573728{ 
    574         return 0; 
     729        if (phydev->addr == 0) 
     730                return 0; 
     731 
     732        return genphy_config_aneg(phydev); 
    575733} 
    576734 
     
    580738        struct ar8216_priv priv; 
    581739 
    582         u8 id, rev; 
    583         u32 val; 
    584  
    585740        priv.phy = pdev; 
    586         val = ar8216_mii_read(&priv, AR8216_REG_CTRL); 
    587         rev = val & AR8216_CTRL_REVISION; 
    588         id = (val & AR8216_CTRL_VERSION) >> AR8216_CTRL_VERSION_S; 
    589         if ((id != 1) || (rev != 1)) 
     741        if (ar8216_id_chip(&priv) == UNKNOWN) { 
    590742                return -ENODEV; 
    591  
     743        } 
    592744        return 0; 
    593745} 
     
    604756        if (priv->ndo_old && dev) 
    605757                dev->netdev_ops = priv->ndo_old; 
    606         unregister_switch(&priv->dev); 
     758        if (pdev->addr == 0) 
     759                unregister_switch(&priv->dev); 
    607760        kfree(priv); 
    608761} 
     
    635788 
    636789static struct phy_driver ar8216_driver = { 
    637         .name           = "Atheros AR8216", 
     790        .phy_id         = 0x004d0000, 
     791        .name           = "Atheros AR8216/AR8316", 
     792        .phy_id_mask    = 0xffff0000, 
    638793        .features       = PHY_BASIC_FEATURES, 
    639794        .probe          = ar8216_probe, 
  • trunk/target/linux/generic-2.6/files/drivers/net/phy/ar8216.h

    r20110 r20722  
    2323#define AR8216_NUM_PORTS        6 
    2424#define AR8216_NUM_VLANS        16 
     25#define AR8316_NUM_VLANS        4096 
     26 
     27/* Atheros specific MII registers */ 
     28#define MII_ATH_DBG_ADDR                0x1d 
     29#define MII_ATH_DBG_DATA                0x1e 
    2530 
    2631#define AR8216_REG_CTRL                 0x0000 
     
    3136#define   AR8216_CTRL_RESET             BIT(31) 
    3237 
     38#define AR8216_REG_FLOOD_MASK           0x002C 
     39#define   AR8216_FM_UNI_DEST_PORTS      BITS(0, 6) 
     40#define   AR8216_FM_MULTI_DEST_PORTS    BITS(16, 6) 
     41 
    3342#define AR8216_REG_GLOBAL_CTRL          0x0030 
    3443#define   AR8216_GCTRL_MTU              BITS(0, 11) 
     44#define   AR8316_GCTRL_MTU              BITS(0, 14) 
    3545 
    3646#define AR8216_REG_VTU                  0x0040 
     
    7585#define   AR8216_ATU_ADDR1              BITS(16, 8) 
    7686#define   AR8216_ATU_ADDR0              BITS(24, 8) 
     87 
     88#define AR8216_REG_ATU_CTRL             0x005C 
     89#define   AR8216_ATU_CTRL_AGE_EN        BIT(17) 
     90#define   AR8216_ATU_CTRL_AGE_TIME      BITS(0, 16) 
     91#define   AR8216_ATU_CTRL_AGE_TIME_S    0 
    7792 
    7893#define AR8216_PORT_OFFSET(_i)          (0x0100 * (_i + 1)) 
     
    163178}; 
    164179 
     180/* device */ 
     181enum { 
     182  UNKNOWN = 0, 
     183  AR8216 = 8216, 
     184  AR8316 = 8316 
     185}; 
     186 
    165187#endif 
Note: See TracChangeset for help on using the changeset viewer.