]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
tg3: Add MDIO bus address assignments
authorMatt Carlson <mcarlson@broadcom.com>
Tue, 1 Sep 2009 13:21:36 +0000 (13:21 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 2 Sep 2009 07:44:09 +0000 (00:44 -0700)
The 5717 is a dual port chip that has a shared MDIO bus design.  While
it is impossible for one function to interface with the wrong phy, that
function still needs to know which MDIO bus address to use when
interfacing with its own phy.  This patch adds code to determine which
MDIO bus address to use.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Benjamin Li <benli@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/tg3.c
drivers/net/tg3.h

index 2de1ab6278d51ea8481fde70080dc7d08a1ef8d8..9ff97cc7e916cf599061e12c95ea65574291bd56 100644 (file)
@@ -782,7 +782,7 @@ static int tg3_readphy(struct tg3 *tp, int reg, u32 *val)
 
        *val = 0x0;
 
-       frame_val  = ((PHY_ADDR << MI_COM_PHY_ADDR_SHIFT) &
+       frame_val  = ((tp->phy_addr << MI_COM_PHY_ADDR_SHIFT) &
                      MI_COM_PHY_ADDR_MASK);
        frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
                      MI_COM_REG_ADDR_MASK);
@@ -833,7 +833,7 @@ static int tg3_writephy(struct tg3 *tp, int reg, u32 val)
                udelay(80);
        }
 
-       frame_val  = ((PHY_ADDR << MI_COM_PHY_ADDR_SHIFT) &
+       frame_val  = ((tp->phy_addr << MI_COM_PHY_ADDR_SHIFT) &
                      MI_COM_PHY_ADDR_MASK);
        frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
                      MI_COM_REG_ADDR_MASK);
@@ -1021,6 +1021,21 @@ static void tg3_mdio_start(struct tg3 *tp)
        tw32_f(MAC_MI_MODE, tp->mi_mode);
        udelay(80);
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+               u32 funcnum, is_serdes;
+
+               funcnum = tr32(TG3_CPMU_STATUS) & TG3_CPMU_STATUS_PCIE_FUNC;
+               if (funcnum)
+                       tp->phy_addr = 2;
+               else
+                       tp->phy_addr = 1;
+
+               is_serdes = tr32(SG_DIG_STATUS) & SG_DIG_IS_SERDES;
+               if (is_serdes)
+                       tp->phy_addr += 7;
+       } else
+               tp->phy_addr = PHY_ADDR;
+
        if ((tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) &&
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
                tg3_mdio_config_5785(tp);
@@ -9266,7 +9281,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                cmd->speed = tp->link_config.active_speed;
                cmd->duplex = tp->link_config.active_duplex;
        }
-       cmd->phy_address = PHY_ADDR;
+       cmd->phy_address = tp->phy_addr;
        cmd->transceiver = XCVR_INTERNAL;
        cmd->autoneg = tp->link_config.autoneg;
        cmd->maxtxpkt = 0;
@@ -10570,7 +10585,7 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
        switch(cmd) {
        case SIOCGMIIPHY:
-               data->phy_id = PHY_ADDR;
+               data->phy_id = tp->phy_addr;
 
                /* fallthru */
        case SIOCGMIIREG: {
index ea57a3a4372c425ee17af2fc2bc9b565f4908090..82b45d8797b4eb6b2e6b8ad5ba6f08ed2a23709c 100644 (file)
 #define  SG_DIG_PARTNER_FULL_DUPLEX     0x00020000 /* If !MRADV_CRC16_SELECT */
 #define  SG_DIG_PARTNER_NEXT_PAGE       0x00010000 /* If !MRADV_CRC16_SELECT */
 #define  SG_DIG_AUTONEG_STATE_MASK      0x00000ff0
+#define  SG_DIG_IS_SERDES               0x00000100
 #define  SG_DIG_COMMA_DETECTOR          0x00000008
 #define  SG_DIG_MAC_ACK_STATUS          0x00000004
 #define  SG_DIG_AUTONEG_COMPLETE        0x00000002
@@ -2805,6 +2806,8 @@ struct tg3 {
        struct mii_bus                  *mdio_bus;
        int                             mdio_irq[PHY_MAX_ADDR];
 
+       u8                              phy_addr;
+
        /* PHY info */
        u32                             phy_id;
 #define PHY_ID_MASK                    0xfffffff0