diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/niu.c | 371 | ||||
| -rw-r--r-- | drivers/net/niu.h | 12 | ||||
| -rw-r--r-- | drivers/net/tg3.c | 2 |
3 files changed, 344 insertions, 41 deletions
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index 7565c2d7f30e..4009c4ce96b4 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c | |||
| @@ -33,8 +33,8 @@ | |||
| 33 | 33 | ||
| 34 | #define DRV_MODULE_NAME "niu" | 34 | #define DRV_MODULE_NAME "niu" |
| 35 | #define PFX DRV_MODULE_NAME ": " | 35 | #define PFX DRV_MODULE_NAME ": " |
| 36 | #define DRV_MODULE_VERSION "0.7" | 36 | #define DRV_MODULE_VERSION "0.8" |
| 37 | #define DRV_MODULE_RELDATE "February 18, 2008" | 37 | #define DRV_MODULE_RELDATE "April 24, 2008" |
| 38 | 38 | ||
| 39 | static char version[] __devinitdata = | 39 | static char version[] __devinitdata = |
| 40 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 40 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; |
| @@ -673,11 +673,16 @@ static int serdes_init_10g(struct niu *np) | |||
| 673 | } | 673 | } |
| 674 | 674 | ||
| 675 | if ((sig & mask) != val) { | 675 | if ((sig & mask) != val) { |
| 676 | if (np->flags & NIU_FLAGS_HOTPLUG_PHY) { | ||
| 677 | np->flags &= ~NIU_FLAGS_HOTPLUG_PHY_PRESENT; | ||
| 678 | return 0; | ||
| 679 | } | ||
| 676 | dev_err(np->device, PFX "Port %u signal bits [%08x] are not " | 680 | dev_err(np->device, PFX "Port %u signal bits [%08x] are not " |
| 677 | "[%08x]\n", np->port, (int) (sig & mask), (int) val); | 681 | "[%08x]\n", np->port, (int) (sig & mask), (int) val); |
| 678 | return -ENODEV; | 682 | return -ENODEV; |
| 679 | } | 683 | } |
| 680 | 684 | if (np->flags & NIU_FLAGS_HOTPLUG_PHY) | |
| 685 | np->flags |= NIU_FLAGS_HOTPLUG_PHY_PRESENT; | ||
| 681 | return 0; | 686 | return 0; |
| 682 | } | 687 | } |
| 683 | 688 | ||
| @@ -998,6 +1003,28 @@ static int bcm8704_user_dev3_readback(struct niu *np, int reg) | |||
| 998 | return 0; | 1003 | return 0; |
| 999 | } | 1004 | } |
| 1000 | 1005 | ||
| 1006 | static int bcm8706_init_user_dev3(struct niu *np) | ||
| 1007 | { | ||
| 1008 | int err; | ||
| 1009 | |||
| 1010 | |||
| 1011 | err = mdio_read(np, np->phy_addr, BCM8704_USER_DEV3_ADDR, | ||
| 1012 | BCM8704_USER_OPT_DIGITAL_CTRL); | ||
| 1013 | if (err < 0) | ||
| 1014 | return err; | ||
| 1015 | err &= ~USER_ODIG_CTRL_GPIOS; | ||
| 1016 | err |= (0x3 << USER_ODIG_CTRL_GPIOS_SHIFT); | ||
| 1017 | err |= USER_ODIG_CTRL_RESV2; | ||
| 1018 | err = mdio_write(np, np->phy_addr, BCM8704_USER_DEV3_ADDR, | ||
| 1019 | BCM8704_USER_OPT_DIGITAL_CTRL, err); | ||
| 1020 | if (err) | ||
| 1021 | return err; | ||
| 1022 | |||
| 1023 | mdelay(1000); | ||
| 1024 | |||
| 1025 | return 0; | ||
| 1026 | } | ||
| 1027 | |||
| 1001 | static int bcm8704_init_user_dev3(struct niu *np) | 1028 | static int bcm8704_init_user_dev3(struct niu *np) |
| 1002 | { | 1029 | { |
| 1003 | int err; | 1030 | int err; |
| @@ -1127,33 +1154,11 @@ static int xcvr_init_10g_mrvl88x2011(struct niu *np) | |||
| 1127 | MRVL88X2011_10G_PMD_TX_DIS, MRVL88X2011_ENA_PMDTX); | 1154 | MRVL88X2011_10G_PMD_TX_DIS, MRVL88X2011_ENA_PMDTX); |
| 1128 | } | 1155 | } |
| 1129 | 1156 | ||
| 1130 | static int xcvr_init_10g_bcm8704(struct niu *np) | 1157 | |
| 1158 | static int xcvr_diag_bcm870x(struct niu *np) | ||
| 1131 | { | 1159 | { |
| 1132 | struct niu_link_config *lp = &np->link_config; | ||
| 1133 | u16 analog_stat0, tx_alarm_status; | 1160 | u16 analog_stat0, tx_alarm_status; |
| 1134 | int err; | 1161 | int err = 0; |
| 1135 | |||
| 1136 | err = bcm8704_reset(np); | ||
| 1137 | if (err) | ||
| 1138 | return err; | ||
| 1139 | |||
| 1140 | err = bcm8704_init_user_dev3(np); | ||
| 1141 | if (err) | ||
| 1142 | return err; | ||
| 1143 | |||
| 1144 | err = mdio_read(np, np->phy_addr, BCM8704_PCS_DEV_ADDR, | ||
| 1145 | MII_BMCR); | ||
| 1146 | if (err < 0) | ||
| 1147 | return err; | ||
| 1148 | err &= ~BMCR_LOOPBACK; | ||
| 1149 | |||
| 1150 | if (lp->loopback_mode == LOOPBACK_MAC) | ||
| 1151 | err |= BMCR_LOOPBACK; | ||
| 1152 | |||
| 1153 | err = mdio_write(np, np->phy_addr, BCM8704_PCS_DEV_ADDR, | ||
| 1154 | MII_BMCR, err); | ||
| 1155 | if (err) | ||
| 1156 | return err; | ||
| 1157 | 1162 | ||
| 1158 | #if 1 | 1163 | #if 1 |
| 1159 | err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR, | 1164 | err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR, |
| @@ -1211,6 +1216,89 @@ static int xcvr_init_10g_bcm8704(struct niu *np) | |||
| 1211 | return 0; | 1216 | return 0; |
| 1212 | } | 1217 | } |
| 1213 | 1218 | ||
| 1219 | static int xcvr_10g_set_lb_bcm870x(struct niu *np) | ||
| 1220 | { | ||
| 1221 | struct niu_link_config *lp = &np->link_config; | ||
| 1222 | int err; | ||
| 1223 | |||
| 1224 | err = mdio_read(np, np->phy_addr, BCM8704_PCS_DEV_ADDR, | ||
| 1225 | MII_BMCR); | ||
| 1226 | if (err < 0) | ||
| 1227 | return err; | ||
| 1228 | |||
| 1229 | err &= ~BMCR_LOOPBACK; | ||
| 1230 | |||
| 1231 | if (lp->loopback_mode == LOOPBACK_MAC) | ||
| 1232 | err |= BMCR_LOOPBACK; | ||
| 1233 | |||
| 1234 | err = mdio_write(np, np->phy_addr, BCM8704_PCS_DEV_ADDR, | ||
| 1235 | MII_BMCR, err); | ||
| 1236 | if (err) | ||
| 1237 | return err; | ||
| 1238 | |||
| 1239 | return 0; | ||
| 1240 | } | ||
| 1241 | |||
| 1242 | static int xcvr_init_10g_bcm8706(struct niu *np) | ||
| 1243 | { | ||
| 1244 | int err = 0; | ||
| 1245 | u64 val; | ||
| 1246 | |||
| 1247 | if ((np->flags & NIU_FLAGS_HOTPLUG_PHY) && | ||
| 1248 | (np->flags & NIU_FLAGS_HOTPLUG_PHY_PRESENT) == 0) | ||
| 1249 | return err; | ||
| 1250 | |||
| 1251 | val = nr64_mac(XMAC_CONFIG); | ||
| 1252 | val &= ~XMAC_CONFIG_LED_POLARITY; | ||
| 1253 | val |= XMAC_CONFIG_FORCE_LED_ON; | ||
| 1254 | nw64_mac(XMAC_CONFIG, val); | ||
| 1255 | |||
| 1256 | val = nr64(MIF_CONFIG); | ||
| 1257 | val |= MIF_CONFIG_INDIRECT_MODE; | ||
| 1258 | nw64(MIF_CONFIG, val); | ||
| 1259 | |||
| 1260 | err = bcm8704_reset(np); | ||
| 1261 | if (err) | ||
| 1262 | return err; | ||
| 1263 | |||
| 1264 | err = xcvr_10g_set_lb_bcm870x(np); | ||
| 1265 | if (err) | ||
| 1266 | return err; | ||
| 1267 | |||
| 1268 | err = bcm8706_init_user_dev3(np); | ||
| 1269 | if (err) | ||
| 1270 | return err; | ||
| 1271 | |||
| 1272 | err = xcvr_diag_bcm870x(np); | ||
| 1273 | if (err) | ||
| 1274 | return err; | ||
| 1275 | |||
| 1276 | return 0; | ||
| 1277 | } | ||
| 1278 | |||
| 1279 | static int xcvr_init_10g_bcm8704(struct niu *np) | ||
| 1280 | { | ||
| 1281 | int err; | ||
| 1282 | |||
| 1283 | err = bcm8704_reset(np); | ||
| 1284 | if (err) | ||
| 1285 | return err; | ||
| 1286 | |||
| 1287 | err = bcm8704_init_user_dev3(np); | ||
| 1288 | if (err) | ||
| 1289 | return err; | ||
| 1290 | |||
| 1291 | err = xcvr_10g_set_lb_bcm870x(np); | ||
| 1292 | if (err) | ||
| 1293 | return err; | ||
| 1294 | |||
| 1295 | err = xcvr_diag_bcm870x(np); | ||
| 1296 | if (err) | ||
| 1297 | return err; | ||
| 1298 | |||
| 1299 | return 0; | ||
| 1300 | } | ||
| 1301 | |||
| 1214 | static int xcvr_init_10g(struct niu *np) | 1302 | static int xcvr_init_10g(struct niu *np) |
| 1215 | { | 1303 | { |
| 1216 | int phy_id, err; | 1304 | int phy_id, err; |
| @@ -1548,6 +1636,59 @@ out: | |||
| 1548 | return err; | 1636 | return err; |
| 1549 | } | 1637 | } |
| 1550 | 1638 | ||
| 1639 | static int link_status_10g_bcm8706(struct niu *np, int *link_up_p) | ||
| 1640 | { | ||
| 1641 | int err, link_up; | ||
| 1642 | link_up = 0; | ||
| 1643 | |||
| 1644 | err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR, | ||
| 1645 | BCM8704_PMD_RCV_SIGDET); | ||
| 1646 | if (err < 0) | ||
| 1647 | goto out; | ||
| 1648 | if (!(err & PMD_RCV_SIGDET_GLOBAL)) { | ||
| 1649 | err = 0; | ||
| 1650 | goto out; | ||
| 1651 | } | ||
| 1652 | |||
| 1653 | err = mdio_read(np, np->phy_addr, BCM8704_PCS_DEV_ADDR, | ||
| 1654 | BCM8704_PCS_10G_R_STATUS); | ||
| 1655 | if (err < 0) | ||
| 1656 | goto out; | ||
| 1657 | |||
| 1658 | if (!(err & PCS_10G_R_STATUS_BLK_LOCK)) { | ||
| 1659 | err = 0; | ||
| 1660 | goto out; | ||
| 1661 | } | ||
| 1662 | |||
| 1663 | err = mdio_read(np, np->phy_addr, BCM8704_PHYXS_DEV_ADDR, | ||
| 1664 | BCM8704_PHYXS_XGXS_LANE_STAT); | ||
| 1665 | if (err < 0) | ||
| 1666 | goto out; | ||
| 1667 | if (err != (PHYXS_XGXS_LANE_STAT_ALINGED | | ||
| 1668 | PHYXS_XGXS_LANE_STAT_MAGIC | | ||
| 1669 | PHYXS_XGXS_LANE_STAT_PATTEST | | ||
| 1670 | PHYXS_XGXS_LANE_STAT_LANE3 | | ||
| 1671 | PHYXS_XGXS_LANE_STAT_LANE2 | | ||
| 1672 | PHYXS_XGXS_LANE_STAT_LANE1 | | ||
| 1673 | PHYXS_XGXS_LANE_STAT_LANE0)) { | ||
| 1674 | err = 0; | ||
| 1675 | np->link_config.active_speed = SPEED_INVALID; | ||
| 1676 | np->link_config.active_duplex = DUPLEX_INVALID; | ||
| 1677 | goto out; | ||
| 1678 | } | ||
| 1679 | |||
| 1680 | link_up = 1; | ||
| 1681 | np->link_config.active_speed = SPEED_10000; | ||
| 1682 | np->link_config.active_duplex = DUPLEX_FULL; | ||
| 1683 | err = 0; | ||
| 1684 | |||
| 1685 | out: | ||
| 1686 | *link_up_p = link_up; | ||
| 1687 | if (np->flags & NIU_FLAGS_HOTPLUG_PHY) | ||
| 1688 | err = 0; | ||
| 1689 | return err; | ||
| 1690 | } | ||
| 1691 | |||
| 1551 | static int link_status_10g_bcom(struct niu *np, int *link_up_p) | 1692 | static int link_status_10g_bcom(struct niu *np, int *link_up_p) |
| 1552 | { | 1693 | { |
| 1553 | int err, link_up; | 1694 | int err, link_up; |
| @@ -1627,6 +1768,82 @@ static int link_status_10g(struct niu *np, int *link_up_p) | |||
| 1627 | return err; | 1768 | return err; |
| 1628 | } | 1769 | } |
| 1629 | 1770 | ||
| 1771 | static int niu_10g_phy_present(struct niu *np) | ||
| 1772 | { | ||
| 1773 | u64 sig, mask, val; | ||
| 1774 | |||
| 1775 | sig = nr64(ESR_INT_SIGNALS); | ||
| 1776 | switch (np->port) { | ||
| 1777 | case 0: | ||
| 1778 | mask = ESR_INT_SIGNALS_P0_BITS; | ||
| 1779 | val = (ESR_INT_SRDY0_P0 | | ||
| 1780 | ESR_INT_DET0_P0 | | ||
| 1781 | ESR_INT_XSRDY_P0 | | ||
| 1782 | ESR_INT_XDP_P0_CH3 | | ||
| 1783 | ESR_INT_XDP_P0_CH2 | | ||
| 1784 | ESR_INT_XDP_P0_CH1 | | ||
| 1785 | ESR_INT_XDP_P0_CH0); | ||
| 1786 | break; | ||
| 1787 | |||
| 1788 | case 1: | ||
| 1789 | mask = ESR_INT_SIGNALS_P1_BITS; | ||
| 1790 | val = (ESR_INT_SRDY0_P1 | | ||
| 1791 | ESR_INT_DET0_P1 | | ||
| 1792 | ESR_INT_XSRDY_P1 | | ||
| 1793 | ESR_INT_XDP_P1_CH3 | | ||
| 1794 | ESR_INT_XDP_P1_CH2 | | ||
| 1795 | ESR_INT_XDP_P1_CH1 | | ||
| 1796 | ESR_INT_XDP_P1_CH0); | ||
| 1797 | break; | ||
| 1798 | |||
| 1799 | default: | ||
| 1800 | return 0; | ||
| 1801 | } | ||
| 1802 | |||
| 1803 | if ((sig & mask) != val) | ||
| 1804 | return 0; | ||
| 1805 | return 1; | ||
| 1806 | } | ||
| 1807 | |||
| 1808 | static int link_status_10g_hotplug(struct niu *np, int *link_up_p) | ||
| 1809 | { | ||
| 1810 | unsigned long flags; | ||
| 1811 | int err = 0; | ||
| 1812 | int phy_present; | ||
| 1813 | int phy_present_prev; | ||
| 1814 | |||
| 1815 | spin_lock_irqsave(&np->lock, flags); | ||
| 1816 | |||
| 1817 | if (np->link_config.loopback_mode == LOOPBACK_DISABLED) { | ||
| 1818 | phy_present_prev = (np->flags & NIU_FLAGS_HOTPLUG_PHY_PRESENT) ? | ||
| 1819 | 1 : 0; | ||
| 1820 | phy_present = niu_10g_phy_present(np); | ||
| 1821 | if (phy_present != phy_present_prev) { | ||
| 1822 | /* state change */ | ||
| 1823 | if (phy_present) { | ||
| 1824 | np->flags |= NIU_FLAGS_HOTPLUG_PHY_PRESENT; | ||
| 1825 | if (np->phy_ops->xcvr_init) | ||
| 1826 | err = np->phy_ops->xcvr_init(np); | ||
| 1827 | if (err) { | ||
| 1828 | /* debounce */ | ||
| 1829 | np->flags &= ~NIU_FLAGS_HOTPLUG_PHY_PRESENT; | ||
| 1830 | } | ||
| 1831 | } else { | ||
| 1832 | np->flags &= ~NIU_FLAGS_HOTPLUG_PHY_PRESENT; | ||
| 1833 | *link_up_p = 0; | ||
| 1834 | niuwarn(LINK, "%s: Hotplug PHY Removed\n", | ||
| 1835 | np->dev->name); | ||
| 1836 | } | ||
| 1837 | } | ||
| 1838 | if (np->flags & NIU_FLAGS_HOTPLUG_PHY_PRESENT) | ||
| 1839 | err = link_status_10g_bcm8706(np, link_up_p); | ||
| 1840 | } | ||
| 1841 | |||
| 1842 | spin_unlock_irqrestore(&np->lock, flags); | ||
| 1843 | |||
| 1844 | return err; | ||
| 1845 | } | ||
| 1846 | |||
| 1630 | static int link_status_1g(struct niu *np, int *link_up_p) | 1847 | static int link_status_1g(struct niu *np, int *link_up_p) |
| 1631 | { | 1848 | { |
| 1632 | struct niu_link_config *lp = &np->link_config; | 1849 | struct niu_link_config *lp = &np->link_config; |
| @@ -1761,6 +1978,12 @@ static const struct niu_phy_ops phy_ops_10g_fiber = { | |||
| 1761 | .link_status = link_status_10g, | 1978 | .link_status = link_status_10g, |
| 1762 | }; | 1979 | }; |
| 1763 | 1980 | ||
| 1981 | static const struct niu_phy_ops phy_ops_10g_fiber_hotplug = { | ||
| 1982 | .serdes_init = serdes_init_10g, | ||
| 1983 | .xcvr_init = xcvr_init_10g_bcm8706, | ||
| 1984 | .link_status = link_status_10g_hotplug, | ||
| 1985 | }; | ||
| 1986 | |||
| 1764 | static const struct niu_phy_ops phy_ops_10g_copper = { | 1987 | static const struct niu_phy_ops phy_ops_10g_copper = { |
| 1765 | .serdes_init = serdes_init_10g, | 1988 | .serdes_init = serdes_init_10g, |
| 1766 | .link_status = link_status_10g, /* XXX */ | 1989 | .link_status = link_status_10g, /* XXX */ |
| @@ -1792,6 +2015,11 @@ static const struct niu_phy_template phy_template_10g_fiber = { | |||
| 1792 | .phy_addr_base = 8, | 2015 | .phy_addr_base = 8, |
| 1793 | }; | 2016 | }; |
| 1794 | 2017 | ||
| 2018 | static const struct niu_phy_template phy_template_10g_fiber_hotplug = { | ||
| 2019 | .ops = &phy_ops_10g_fiber_hotplug, | ||
| 2020 | .phy_addr_base = 8, | ||
| 2021 | }; | ||
| 2022 | |||
| 1795 | static const struct niu_phy_template phy_template_10g_copper = { | 2023 | static const struct niu_phy_template phy_template_10g_copper = { |
| 1796 | .ops = &phy_ops_10g_copper, | 2024 | .ops = &phy_ops_10g_copper, |
| 1797 | .phy_addr_base = 10, | 2025 | .phy_addr_base = 10, |
| @@ -1996,6 +2224,13 @@ static int niu_determine_phy_disposition(struct niu *np) | |||
| 1996 | plat_type == PLAT_TYPE_VF_P1) | 2224 | plat_type == PLAT_TYPE_VF_P1) |
| 1997 | phy_addr_off = 8; | 2225 | phy_addr_off = 8; |
| 1998 | phy_addr_off += np->port; | 2226 | phy_addr_off += np->port; |
| 2227 | if (np->flags & NIU_FLAGS_HOTPLUG_PHY) { | ||
| 2228 | tp = &phy_template_10g_fiber_hotplug; | ||
| 2229 | if (np->port == 0) | ||
| 2230 | phy_addr_off = 8; | ||
| 2231 | if (np->port == 1) | ||
| 2232 | phy_addr_off = 12; | ||
| 2233 | } | ||
| 1999 | break; | 2234 | break; |
| 2000 | 2235 | ||
| 2001 | case NIU_FLAGS_10G | NIU_FLAGS_XCVR_SERDES: | 2236 | case NIU_FLAGS_10G | NIU_FLAGS_XCVR_SERDES: |
| @@ -6773,6 +7008,37 @@ static int __devinit niu_phy_type_prop_decode(struct niu *np, | |||
| 6773 | return 0; | 7008 | return 0; |
| 6774 | } | 7009 | } |
| 6775 | 7010 | ||
| 7011 | /* niu board models have a trailing dash version incremented | ||
| 7012 | * with HW rev change. Need to ingnore the dash version while | ||
| 7013 | * checking for match | ||
| 7014 | * | ||
| 7015 | * for example, for the 10G card the current vpd.board_model | ||
| 7016 | * is 501-5283-04, of which -04 is the dash version and have | ||
| 7017 | * to be ignored | ||
| 7018 | */ | ||
| 7019 | static int niu_board_model_match(struct niu *np, const char *model) | ||
| 7020 | { | ||
| 7021 | return !strncmp(np->vpd.board_model, model, strlen(model)); | ||
| 7022 | } | ||
| 7023 | |||
| 7024 | static int niu_pci_vpd_get_nports(struct niu *np) | ||
| 7025 | { | ||
| 7026 | int ports = 0; | ||
| 7027 | |||
| 7028 | if ((niu_board_model_match(np, NIU_QGC_LP_BM_STR)) || | ||
| 7029 | (niu_board_model_match(np, NIU_QGC_PEM_BM_STR)) || | ||
| 7030 | (niu_board_model_match(np, NIU_ALONSO_BM_STR))) { | ||
| 7031 | ports = 4; | ||
| 7032 | } else if ((niu_board_model_match(np, NIU_2XGF_LP_BM_STR)) || | ||
| 7033 | (niu_board_model_match(np, NIU_2XGF_PEM_BM_STR)) || | ||
| 7034 | (niu_board_model_match(np, NIU_FOXXY_BM_STR)) || | ||
| 7035 | (niu_board_model_match(np, NIU_2XGF_MRVL_BM_STR))) { | ||
| 7036 | ports = 2; | ||
| 7037 | } | ||
| 7038 | |||
| 7039 | return ports; | ||
| 7040 | } | ||
| 7041 | |||
| 6776 | static void __devinit niu_pci_vpd_validate(struct niu *np) | 7042 | static void __devinit niu_pci_vpd_validate(struct niu *np) |
| 6777 | { | 7043 | { |
| 6778 | struct net_device *dev = np->dev; | 7044 | struct net_device *dev = np->dev; |
| @@ -6799,6 +7065,9 @@ static void __devinit niu_pci_vpd_validate(struct niu *np) | |||
| 6799 | } | 7065 | } |
| 6800 | if (np->flags & NIU_FLAGS_10G) | 7066 | if (np->flags & NIU_FLAGS_10G) |
| 6801 | np->mac_xcvr = MAC_XCVR_XPCS; | 7067 | np->mac_xcvr = MAC_XCVR_XPCS; |
| 7068 | } else if (niu_board_model_match(np, NIU_FOXXY_BM_STR)) { | ||
| 7069 | np->flags |= (NIU_FLAGS_10G | NIU_FLAGS_FIBER | | ||
| 7070 | NIU_FLAGS_HOTPLUG_PHY); | ||
| 6802 | } else if (niu_phy_type_prop_decode(np, np->vpd.phy_type)) { | 7071 | } else if (niu_phy_type_prop_decode(np, np->vpd.phy_type)) { |
| 6803 | dev_err(np->device, PFX "Illegal phy string [%s].\n", | 7072 | dev_err(np->device, PFX "Illegal phy string [%s].\n", |
| 6804 | np->vpd.phy_type); | 7073 | np->vpd.phy_type); |
| @@ -6987,11 +7256,17 @@ static int __devinit niu_get_and_validate_port(struct niu *np) | |||
| 6987 | if (parent->plat_type == PLAT_TYPE_NIU) { | 7256 | if (parent->plat_type == PLAT_TYPE_NIU) { |
| 6988 | parent->num_ports = 2; | 7257 | parent->num_ports = 2; |
| 6989 | } else { | 7258 | } else { |
| 6990 | parent->num_ports = nr64(ESPC_NUM_PORTS_MACS) & | 7259 | parent->num_ports = niu_pci_vpd_get_nports(np); |
| 6991 | ESPC_NUM_PORTS_MACS_VAL; | 7260 | if (!parent->num_ports) { |
| 6992 | 7261 | /* Fall back to SPROM as last resort. | |
| 6993 | if (!parent->num_ports) | 7262 | * This will fail on most cards. |
| 6994 | parent->num_ports = 4; | 7263 | */ |
| 7264 | parent->num_ports = nr64(ESPC_NUM_PORTS_MACS) & | ||
| 7265 | ESPC_NUM_PORTS_MACS_VAL; | ||
| 7266 | |||
| 7267 | if (!parent->num_ports) | ||
| 7268 | return -ENODEV; | ||
| 7269 | } | ||
| 6995 | } | 7270 | } |
| 6996 | } | 7271 | } |
| 6997 | 7272 | ||
| @@ -7015,7 +7290,8 @@ static int __devinit phy_record(struct niu_parent *parent, | |||
| 7015 | return 0; | 7290 | return 0; |
| 7016 | if (type == PHY_TYPE_PMA_PMD || type == PHY_TYPE_PCS) { | 7291 | if (type == PHY_TYPE_PMA_PMD || type == PHY_TYPE_PCS) { |
| 7017 | if (((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704) && | 7292 | if (((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704) && |
| 7018 | ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_MRVL88X2011)) | 7293 | ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_MRVL88X2011) && |
| 7294 | ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8706)) | ||
| 7019 | return 0; | 7295 | return 0; |
| 7020 | } else { | 7296 | } else { |
| 7021 | if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM5464R) | 7297 | if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM5464R) |
| @@ -7262,7 +7538,6 @@ static int __devinit walk_phys(struct niu *np, struct niu_parent *parent) | |||
| 7262 | u32 val; | 7538 | u32 val; |
| 7263 | int err; | 7539 | int err; |
| 7264 | 7540 | ||
| 7265 | |||
| 7266 | if (!strcmp(np->vpd.model, "SUNW,CP3220") || | 7541 | if (!strcmp(np->vpd.model, "SUNW,CP3220") || |
| 7267 | !strcmp(np->vpd.model, "SUNW,CP3260")) { | 7542 | !strcmp(np->vpd.model, "SUNW,CP3260")) { |
| 7268 | num_10g = 0; | 7543 | num_10g = 0; |
| @@ -7273,6 +7548,12 @@ static int __devinit walk_phys(struct niu *np, struct niu_parent *parent) | |||
| 7273 | phy_encode(PORT_TYPE_1G, 1) | | 7548 | phy_encode(PORT_TYPE_1G, 1) | |
| 7274 | phy_encode(PORT_TYPE_1G, 2) | | 7549 | phy_encode(PORT_TYPE_1G, 2) | |
| 7275 | phy_encode(PORT_TYPE_1G, 3)); | 7550 | phy_encode(PORT_TYPE_1G, 3)); |
| 7551 | } else if (niu_board_model_match(np, NIU_FOXXY_BM_STR)) { | ||
| 7552 | num_10g = 2; | ||
| 7553 | num_1g = 0; | ||
| 7554 | parent->num_ports = 2; | ||
| 7555 | val = (phy_encode(PORT_TYPE_10G, 0) | | ||
| 7556 | phy_encode(PORT_TYPE_10G, 1)); | ||
| 7276 | } else { | 7557 | } else { |
| 7277 | err = fill_phy_probe_info(np, parent, info); | 7558 | err = fill_phy_probe_info(np, parent, info); |
| 7278 | if (err) | 7559 | if (err) |
| @@ -7733,15 +8014,16 @@ static int __devinit niu_get_invariants(struct niu *np) | |||
| 7733 | 8014 | ||
| 7734 | have_props = !err; | 8015 | have_props = !err; |
| 7735 | 8016 | ||
| 7736 | err = niu_get_and_validate_port(np); | ||
| 7737 | if (err) | ||
| 7738 | return err; | ||
| 7739 | |||
| 7740 | err = niu_init_mac_ipp_pcs_base(np); | 8017 | err = niu_init_mac_ipp_pcs_base(np); |
| 7741 | if (err) | 8018 | if (err) |
| 7742 | return err; | 8019 | return err; |
| 7743 | 8020 | ||
| 7744 | if (!have_props) { | 8021 | if (have_props) { |
| 8022 | err = niu_get_and_validate_port(np); | ||
| 8023 | if (err) | ||
| 8024 | return err; | ||
| 8025 | |||
| 8026 | } else { | ||
| 7745 | if (np->parent->plat_type == PLAT_TYPE_NIU) | 8027 | if (np->parent->plat_type == PLAT_TYPE_NIU) |
| 7746 | return -EINVAL; | 8028 | return -EINVAL; |
| 7747 | 8029 | ||
| @@ -7753,10 +8035,17 @@ static int __devinit niu_get_invariants(struct niu *np) | |||
| 7753 | niu_pci_vpd_fetch(np, offset); | 8035 | niu_pci_vpd_fetch(np, offset); |
| 7754 | nw64(ESPC_PIO_EN, 0); | 8036 | nw64(ESPC_PIO_EN, 0); |
| 7755 | 8037 | ||
| 7756 | if (np->flags & NIU_FLAGS_VPD_VALID) | 8038 | if (np->flags & NIU_FLAGS_VPD_VALID) { |
| 7757 | niu_pci_vpd_validate(np); | 8039 | niu_pci_vpd_validate(np); |
| 8040 | err = niu_get_and_validate_port(np); | ||
| 8041 | if (err) | ||
| 8042 | return err; | ||
| 8043 | } | ||
| 7758 | 8044 | ||
| 7759 | if (!(np->flags & NIU_FLAGS_VPD_VALID)) { | 8045 | if (!(np->flags & NIU_FLAGS_VPD_VALID)) { |
| 8046 | err = niu_get_and_validate_port(np); | ||
| 8047 | if (err) | ||
| 8048 | return err; | ||
| 7760 | err = niu_pci_probe_sprom(np); | 8049 | err = niu_pci_probe_sprom(np); |
| 7761 | if (err) | 8050 | if (err) |
| 7762 | return err; | 8051 | return err; |
diff --git a/drivers/net/niu.h b/drivers/net/niu.h index 336aed08b275..97ffbe137bcb 100644 --- a/drivers/net/niu.h +++ b/drivers/net/niu.h | |||
| @@ -2537,6 +2537,7 @@ struct fcram_hash_ipv6 { | |||
| 2537 | 2537 | ||
| 2538 | #define NIU_PHY_ID_MASK 0xfffff0f0 | 2538 | #define NIU_PHY_ID_MASK 0xfffff0f0 |
| 2539 | #define NIU_PHY_ID_BCM8704 0x00206030 | 2539 | #define NIU_PHY_ID_BCM8704 0x00206030 |
| 2540 | #define NIU_PHY_ID_BCM8706 0x00206035 | ||
| 2540 | #define NIU_PHY_ID_BCM5464R 0x002060b0 | 2541 | #define NIU_PHY_ID_BCM5464R 0x002060b0 |
| 2541 | #define NIU_PHY_ID_MRVL88X2011 0x01410020 | 2542 | #define NIU_PHY_ID_MRVL88X2011 0x01410020 |
| 2542 | 2543 | ||
| @@ -2937,6 +2938,15 @@ struct rx_ring_info { | |||
| 2937 | 2938 | ||
| 2938 | #define NIU_MAX_MTU 9216 | 2939 | #define NIU_MAX_MTU 9216 |
| 2939 | 2940 | ||
| 2941 | /* VPD strings */ | ||
| 2942 | #define NIU_QGC_LP_BM_STR "501-7606" | ||
| 2943 | #define NIU_2XGF_LP_BM_STR "501-7283" | ||
| 2944 | #define NIU_QGC_PEM_BM_STR "501-7765" | ||
| 2945 | #define NIU_2XGF_PEM_BM_STR "501-7626" | ||
| 2946 | #define NIU_ALONSO_BM_STR "373-0202" | ||
| 2947 | #define NIU_FOXXY_BM_STR "501-7961" | ||
| 2948 | #define NIU_2XGF_MRVL_BM_STR "SK-6E82" | ||
| 2949 | |||
| 2940 | #define NIU_VPD_MIN_MAJOR 3 | 2950 | #define NIU_VPD_MIN_MAJOR 3 |
| 2941 | #define NIU_VPD_MIN_MINOR 4 | 2951 | #define NIU_VPD_MIN_MINOR 4 |
| 2942 | 2952 | ||
| @@ -3199,6 +3209,8 @@ struct niu { | |||
| 3199 | struct niu_parent *parent; | 3209 | struct niu_parent *parent; |
| 3200 | 3210 | ||
| 3201 | u32 flags; | 3211 | u32 flags; |
| 3212 | #define NIU_FLAGS_HOTPLUG_PHY_PRESENT 0x02000000 /* Removebale PHY detected*/ | ||
| 3213 | #define NIU_FLAGS_HOTPLUG_PHY 0x01000000 /* Removebale PHY */ | ||
| 3202 | #define NIU_FLAGS_VPD_VALID 0x00800000 /* VPD has valid version */ | 3214 | #define NIU_FLAGS_VPD_VALID 0x00800000 /* VPD has valid version */ |
| 3203 | #define NIU_FLAGS_MSIX 0x00400000 /* MSI-X in use */ | 3215 | #define NIU_FLAGS_MSIX 0x00400000 /* MSI-X in use */ |
| 3204 | #define NIU_FLAGS_MCAST 0x00200000 /* multicast filter enabled */ | 3216 | #define NIU_FLAGS_MCAST 0x00200000 /* multicast filter enabled */ |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index bc4c62b8e81a..e3f74c9f78bd 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
| @@ -4017,6 +4017,8 @@ static int tg3_halt(struct tg3 *, int, int); | |||
| 4017 | * Invoked with tp->lock held. | 4017 | * Invoked with tp->lock held. |
| 4018 | */ | 4018 | */ |
| 4019 | static int tg3_restart_hw(struct tg3 *tp, int reset_phy) | 4019 | static int tg3_restart_hw(struct tg3 *tp, int reset_phy) |
| 4020 | __releases(tp->lock) | ||
| 4021 | __acquires(tp->lock) | ||
| 4020 | { | 4022 | { |
| 4021 | int err; | 4023 | int err; |
| 4022 | 4024 | ||
