diff options
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 95 |
1 files changed, 88 insertions, 7 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 69ded90cd96e..365fcffc3144 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/ethtool.h> | 33 | #include <linux/ethtool.h> |
34 | #include <linux/mii.h> | 34 | #include <linux/mii.h> |
35 | #include <linux/phy.h> | 35 | #include <linux/phy.h> |
36 | #include <linux/brcmphy.h> | ||
36 | #include <linux/if_vlan.h> | 37 | #include <linux/if_vlan.h> |
37 | #include <linux/ip.h> | 38 | #include <linux/ip.h> |
38 | #include <linux/tcp.h> | 39 | #include <linux/tcp.h> |
@@ -869,6 +870,51 @@ static int tg3_mdio_reset(struct mii_bus *bp) | |||
869 | return 0; | 870 | return 0; |
870 | } | 871 | } |
871 | 872 | ||
873 | static void tg3_mdio_config(struct tg3 *tp) | ||
874 | { | ||
875 | u32 val; | ||
876 | |||
877 | if (tp->mdio_bus.phy_map[PHY_ADDR]->interface != | ||
878 | PHY_INTERFACE_MODE_RGMII) | ||
879 | return; | ||
880 | |||
881 | val = tr32(MAC_PHYCFG1) & ~(MAC_PHYCFG1_RGMII_EXT_RX_DEC | | ||
882 | MAC_PHYCFG1_RGMII_SND_STAT_EN); | ||
883 | if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE) { | ||
884 | if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN) | ||
885 | val |= MAC_PHYCFG1_RGMII_EXT_RX_DEC; | ||
886 | if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN) | ||
887 | val |= MAC_PHYCFG1_RGMII_SND_STAT_EN; | ||
888 | } | ||
889 | tw32(MAC_PHYCFG1, val | MAC_PHYCFG1_RGMII_INT | MAC_PHYCFG1_TXC_DRV); | ||
890 | |||
891 | val = tr32(MAC_PHYCFG2) & ~(MAC_PHYCFG2_INBAND_ENABLE); | ||
892 | if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE)) | ||
893 | val |= MAC_PHYCFG2_INBAND_ENABLE; | ||
894 | tw32(MAC_PHYCFG2, val); | ||
895 | |||
896 | val = tr32(MAC_EXT_RGMII_MODE); | ||
897 | val &= ~(MAC_RGMII_MODE_RX_INT_B | | ||
898 | MAC_RGMII_MODE_RX_QUALITY | | ||
899 | MAC_RGMII_MODE_RX_ACTIVITY | | ||
900 | MAC_RGMII_MODE_RX_ENG_DET | | ||
901 | MAC_RGMII_MODE_TX_ENABLE | | ||
902 | MAC_RGMII_MODE_TX_LOWPWR | | ||
903 | MAC_RGMII_MODE_TX_RESET); | ||
904 | if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE) { | ||
905 | if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN) | ||
906 | val |= MAC_RGMII_MODE_RX_INT_B | | ||
907 | MAC_RGMII_MODE_RX_QUALITY | | ||
908 | MAC_RGMII_MODE_RX_ACTIVITY | | ||
909 | MAC_RGMII_MODE_RX_ENG_DET; | ||
910 | if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN) | ||
911 | val |= MAC_RGMII_MODE_TX_ENABLE | | ||
912 | MAC_RGMII_MODE_TX_LOWPWR | | ||
913 | MAC_RGMII_MODE_TX_RESET; | ||
914 | } | ||
915 | tw32(MAC_EXT_RGMII_MODE, val); | ||
916 | } | ||
917 | |||
872 | static void tg3_mdio_start(struct tg3 *tp) | 918 | static void tg3_mdio_start(struct tg3 *tp) |
873 | { | 919 | { |
874 | if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) { | 920 | if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) { |
@@ -880,6 +926,9 @@ static void tg3_mdio_start(struct tg3 *tp) | |||
880 | tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL; | 926 | tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL; |
881 | tw32_f(MAC_MI_MODE, tp->mi_mode); | 927 | tw32_f(MAC_MI_MODE, tp->mi_mode); |
882 | udelay(80); | 928 | udelay(80); |
929 | |||
930 | if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) | ||
931 | tg3_mdio_config(tp); | ||
883 | } | 932 | } |
884 | 933 | ||
885 | static void tg3_mdio_stop(struct tg3 *tp) | 934 | static void tg3_mdio_stop(struct tg3 *tp) |
@@ -895,6 +944,7 @@ static int tg3_mdio_init(struct tg3 *tp) | |||
895 | { | 944 | { |
896 | int i; | 945 | int i; |
897 | u32 reg; | 946 | u32 reg; |
947 | struct phy_device *phydev; | ||
898 | struct mii_bus *mdio_bus = &tp->mdio_bus; | 948 | struct mii_bus *mdio_bus = &tp->mdio_bus; |
899 | 949 | ||
900 | tg3_mdio_start(tp); | 950 | tg3_mdio_start(tp); |
@@ -928,13 +978,34 @@ static int tg3_mdio_init(struct tg3 *tp) | |||
928 | tg3_bmcr_reset(tp); | 978 | tg3_bmcr_reset(tp); |
929 | 979 | ||
930 | i = mdiobus_register(mdio_bus); | 980 | i = mdiobus_register(mdio_bus); |
931 | if (!i) | 981 | if (i) { |
932 | tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED; | ||
933 | else | ||
934 | printk(KERN_WARNING "%s: mdiobus_reg failed (0x%x)\n", | 982 | printk(KERN_WARNING "%s: mdiobus_reg failed (0x%x)\n", |
935 | tp->dev->name, i); | 983 | tp->dev->name, i); |
984 | return i; | ||
985 | } | ||
936 | 986 | ||
937 | return i; | 987 | tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED; |
988 | |||
989 | phydev = tp->mdio_bus.phy_map[PHY_ADDR]; | ||
990 | |||
991 | switch (phydev->phy_id) { | ||
992 | case TG3_PHY_ID_BCM50610: | ||
993 | phydev->interface = PHY_INTERFACE_MODE_RGMII; | ||
994 | if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE) | ||
995 | phydev->dev_flags |= PHY_BRCM_STD_IBND_DISABLE; | ||
996 | if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN) | ||
997 | phydev->dev_flags |= PHY_BRCM_EXT_IBND_RX_ENABLE; | ||
998 | if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN) | ||
999 | phydev->dev_flags |= PHY_BRCM_EXT_IBND_TX_ENABLE; | ||
1000 | break; | ||
1001 | case TG3_PHY_ID_BCMAC131: | ||
1002 | phydev->interface = PHY_INTERFACE_MODE_MII; | ||
1003 | break; | ||
1004 | } | ||
1005 | |||
1006 | tg3_mdio_config(tp); | ||
1007 | |||
1008 | return 0; | ||
938 | } | 1009 | } |
939 | 1010 | ||
940 | static void tg3_mdio_fini(struct tg3 *tp) | 1011 | static void tg3_mdio_fini(struct tg3 *tp) |
@@ -1238,8 +1309,8 @@ static int tg3_phy_init(struct tg3 *tp) | |||
1238 | phydev = tp->mdio_bus.phy_map[PHY_ADDR]; | 1309 | phydev = tp->mdio_bus.phy_map[PHY_ADDR]; |
1239 | 1310 | ||
1240 | /* Attach the MAC to the PHY. */ | 1311 | /* Attach the MAC to the PHY. */ |
1241 | phydev = phy_connect(tp->dev, phydev->dev.bus_id, | 1312 | phydev = phy_connect(tp->dev, phydev->dev.bus_id, tg3_adjust_link, |
1242 | tg3_adjust_link, 0, phydev->interface); | 1313 | phydev->dev_flags, phydev->interface); |
1243 | if (IS_ERR(phydev)) { | 1314 | if (IS_ERR(phydev)) { |
1244 | printk(KERN_ERR "%s: Could not attach to PHY\n", tp->dev->name); | 1315 | printk(KERN_ERR "%s: Could not attach to PHY\n", tp->dev->name); |
1245 | return PTR_ERR(phydev); | 1316 | return PTR_ERR(phydev); |
@@ -11219,7 +11290,7 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) | |||
11219 | tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); | 11290 | tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); |
11220 | if (val == NIC_SRAM_DATA_SIG_MAGIC) { | 11291 | if (val == NIC_SRAM_DATA_SIG_MAGIC) { |
11221 | u32 nic_cfg, led_cfg; | 11292 | u32 nic_cfg, led_cfg; |
11222 | u32 nic_phy_id, ver, cfg2 = 0, eeprom_phy_id; | 11293 | u32 nic_phy_id, ver, cfg2 = 0, cfg4 = 0, eeprom_phy_id; |
11223 | int eeprom_phy_serdes = 0; | 11294 | int eeprom_phy_serdes = 0; |
11224 | 11295 | ||
11225 | tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg); | 11296 | tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg); |
@@ -11233,6 +11304,9 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) | |||
11233 | (ver > 0) && (ver < 0x100)) | 11304 | (ver > 0) && (ver < 0x100)) |
11234 | tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &cfg2); | 11305 | tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &cfg2); |
11235 | 11306 | ||
11307 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) | ||
11308 | tg3_read_mem(tp, NIC_SRAM_DATA_CFG_4, &cfg4); | ||
11309 | |||
11236 | if ((nic_cfg & NIC_SRAM_DATA_CFG_PHY_TYPE_MASK) == | 11310 | if ((nic_cfg & NIC_SRAM_DATA_CFG_PHY_TYPE_MASK) == |
11237 | NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER) | 11311 | NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER) |
11238 | eeprom_phy_serdes = 1; | 11312 | eeprom_phy_serdes = 1; |
@@ -11357,6 +11431,13 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) | |||
11357 | if (cfg3 & NIC_SRAM_ASPM_DEBOUNCE) | 11431 | if (cfg3 & NIC_SRAM_ASPM_DEBOUNCE) |
11358 | tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND; | 11432 | tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND; |
11359 | } | 11433 | } |
11434 | |||
11435 | if (cfg4 & NIC_SRAM_RGMII_STD_IBND_DISABLE) | ||
11436 | tp->tg3_flags3 |= TG3_FLG3_RGMII_STD_IBND_DISABLE; | ||
11437 | if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_RX_EN) | ||
11438 | tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_RX_EN; | ||
11439 | if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_TX_EN) | ||
11440 | tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_TX_EN; | ||
11360 | } | 11441 | } |
11361 | } | 11442 | } |
11362 | 11443 | ||