Changeset 26778


Ignore:
Timestamp:
2011-04-28T23:27:37+02:00 (7 years ago)
Author:
nbd
Message:

ar8316: automatically detect whether port4 is used as PHY or as a switch port

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/generic/files/drivers/net/phy/ar8216.c

    r26776 r26778  
    4545        struct mutex reg_mutex; 
    4646        int chip; 
     47        bool initialized; 
     48        bool port4_phy; 
    4749 
    4850        /* all fields below are cleared on reset */ 
     
    512514static int 
    513515ar8316_hw_init(struct ar8216_priv *priv) { 
    514         static int initialized; 
    515516        int i; 
    516         u32 val; 
     517        u32 val, newval; 
    517518        struct mii_bus *bus; 
    518519 
    519         if (initialized) 
    520                 return 0; 
    521  
    522520        val = priv->read(priv, 0x8); 
    523521 
    524522        if (priv->phy->interface == PHY_INTERFACE_MODE_RGMII) { 
    525                 /* value taken from Ubiquiti RouterStation Pro */ 
    526                 if (val == 0x81461bea) { 
    527                         /* switch already intialized by bootloader */ 
    528                         initialized = true; 
    529                         return 0; 
    530                 } 
    531                 priv->write(priv, 0x8, 0x81461bea); 
     523                if (priv->port4_phy) { 
     524                        /* value taken from Ubiquiti RouterStation Pro */ 
     525                        newval = 0x81461bea; 
     526                        printk(KERN_INFO "ar8316: Using port 4 as PHY\n"); 
     527                } else { 
     528                        newval = 0x01261be2; 
     529                        printk(KERN_INFO "ar8316: Using port 4 as switch port\n"); 
     530                } 
    532531        } else if (priv->phy->interface == PHY_INTERFACE_MODE_GMII) { 
    533532                /* value taken from AVM Fritz!Box 7390 sources */ 
    534                 if (val == 0x010e5b71) { 
    535                         /* switch already initialized by bootloader */ 
    536                         initialized = true; 
    537                         return 0; 
    538                 } 
    539                 priv->write(priv, 0x8, 0x010e5b71); 
     533                newval = 0x010e5b71; 
    540534        } else { 
    541535                /* no known value for phy interface */ 
     
    545539        } 
    546540 
     541        if (val == newval) 
     542                goto out; 
     543 
     544        priv->write(priv, 0x8, newval); 
     545 
    547546        /* standard atheros magic */ 
    548547        priv->write(priv, 0x38, 0xc000050e); 
     
    551550        bus = priv->phy->bus; 
    552551        for (i = 0; i < 5; i++) { 
    553                 if ((i == 4) && 
    554                         priv->phy->interface == PHY_INTERFACE_MODE_RGMII) { 
     552                if ((i == 4) && priv->port4_phy && 
     553                    priv->phy->interface == PHY_INTERFACE_MODE_RGMII) { 
    555554                        /* work around for phy4 rgmii mode */ 
    556555                        bus->write(bus, i, MII_ATH_DBG_ADDR, 0x12); 
     
    572571                msleep(1000); 
    573572        } 
    574         initialized = true; 
     573 
     574out: 
     575        priv->initialized = true; 
    575576        return 0; 
    576577} 
     
    657658ar8216_config_init(struct phy_device *pdev) 
    658659{ 
    659         struct ar8216_priv *priv; 
     660        struct ar8216_priv *priv = pdev->priv; 
    660661        struct net_device *dev = pdev->attached_dev; 
    661662        struct switch_dev *swdev; 
    662663        int ret; 
    663664 
    664         priv = kzalloc(sizeof(struct ar8216_priv), GFP_KERNEL); 
    665         if (priv == NULL) 
    666                 return -ENOMEM; 
     665        if (!priv) { 
     666                priv = kzalloc(sizeof(struct ar8216_priv), GFP_KERNEL); 
     667                if (priv == NULL) 
     668                        return -ENOMEM; 
     669        } 
    667670 
    668671        priv->phy = pdev; 
    669672 
    670673        priv->chip = ar8216_id_chip(priv); 
    671  
    672         if (pdev->addr == 0) 
    673                 printk(KERN_INFO "%s: AR%d switch driver attached.\n", 
    674                         pdev->attached_dev->name, priv->chip); 
    675  
    676674 
    677675        if (pdev->addr != 0) { 
     
    679677                        pdev->supported |= SUPPORTED_1000baseT_Full; 
    680678                        pdev->advertising |= ADVERTISED_1000baseT_Full; 
    681                 } 
     679 
     680                        /* check if we're attaching to the switch twice */ 
     681                        pdev = pdev->bus->phy_map[0]; 
     682                        if (!pdev) { 
     683                                kfree(priv); 
     684                                return 0; 
     685                        } 
     686 
     687                        /* switch device has not been initialized, reuse priv */ 
     688                        if (!pdev->priv) { 
     689                                priv->port4_phy = true; 
     690                                pdev->priv = priv; 
     691                                return 0; 
     692                        } 
     693 
     694                        kfree(priv); 
     695 
     696                        /* switch device has been initialized, reinit */ 
     697                        priv = pdev->priv; 
     698                        priv->dev.ports = (AR8216_NUM_PORTS - 1); 
     699                        priv->initialized = false; 
     700                        priv->port4_phy = true; 
     701                        ar8316_hw_init(priv); 
     702                        return 0; 
     703                } 
     704 
    682705                kfree(priv); 
    683706                return 0; 
    684707        } 
     708 
     709        printk(KERN_INFO "%s: AR%d switch driver attached.\n", 
     710                pdev->attached_dev->name, priv->chip); 
    685711 
    686712        pdev->supported = priv->chip == AR8316 ? 
     
    697723        swdev->cpu_port = AR8216_PORT_CPU; 
    698724        swdev->ops = &ar8216_ops; 
     725        swdev->ports = AR8216_NUM_PORTS; 
    699726 
    700727        if (priv->chip == AR8316) { 
    701728                swdev->name = "Atheros AR8316"; 
    702729                swdev->vlans = AR8X16_MAX_VLANS; 
    703                 /* port 5 connected to the other mac, therefore unusable */ 
    704                 swdev->ports = (AR8216_NUM_PORTS - 1); 
     730 
     731                if (priv->port4_phy) { 
     732                        /* port 5 connected to the other mac, therefore unusable */ 
     733                        swdev->ports = (AR8216_NUM_PORTS - 1); 
     734                } 
    705735        } else { 
    706736                swdev->name = "Atheros AR8216"; 
    707737                swdev->vlans = AR8216_NUM_VLANS; 
    708                 swdev->ports = AR8216_NUM_PORTS; 
    709738        } 
    710739 
Note: See TracChangeset for help on using the changeset viewer.