aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEilon Greenstein <eilong@broadcom.com>2009-02-12 03:36:55 -0500
committerDavid S. Miller <davem@davemloft.net>2009-02-16 02:31:24 -0500
commit589abe3a0f594a7707a15674ca9e80370c972832 (patch)
treea7930047ca7f5340b9053948fcba98128de4d588
parent4acac6a53a3c9dfc604a9a8647f16b0242080e93 (diff)
bnx2x: Supporting BCM8726 PHY
Also adding the ability to recognize the optic module and disable it if it is not authorized for safety reasons - since this feature might upset some users which are willing to take the risk, it is optional and can be disabled by setting an nvram bit (or a trivial driver patch to set this bit). This dual port PHY requires special handling if the ports are swapped. Signed-off-by: Yaniv Rosner <yanivr@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/bnx2x_hsi.h13
-rw-r--r--drivers/net/bnx2x_link.c776
-rw-r--r--drivers/net/bnx2x_link.h14
-rw-r--r--drivers/net/bnx2x_main.c90
-rw-r--r--drivers/net/bnx2x_reg.h22
5 files changed, 851 insertions, 64 deletions
diff --git a/drivers/net/bnx2x_hsi.h b/drivers/net/bnx2x_hsi.h
index 85e4df68b5d8..7b9acb3667ef 100644
--- a/drivers/net/bnx2x_hsi.h
+++ b/drivers/net/bnx2x_hsi.h
@@ -245,7 +245,7 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
245#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073 0x00000300 245#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073 0x00000300
246#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705 0x00000400 246#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705 0x00000400
247#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706 0x00000500 247#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706 0x00000500
248#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8276 0x00000600 248#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726 0x00000600
249#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481 0x00000700 249#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481 0x00000700
250#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101 0x00000800 250#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101 0x00000800
251#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00 251#define PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE 0x0000fd00
@@ -299,6 +299,12 @@ struct shared_feat_cfg { /* NVRAM Offset */
299 299
300 u32 config; /* 0x450 */ 300 u32 config; /* 0x450 */
301#define SHARED_FEATURE_BMC_ECHO_MODE_EN 0x00000001 301#define SHARED_FEATURE_BMC_ECHO_MODE_EN 0x00000001
302
303 /* Use the values from options 47 and 48 instead of the HW default
304 values */
305#define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_DISABLED 0x00000000
306#define SHARED_FEAT_CFG_OVERRIDE_PREEMPHASIS_CFG_ENABLED 0x00000002
307
302#define SHARED_FEATURE_MF_MODE_DISABLED 0x00000100 308#define SHARED_FEATURE_MF_MODE_DISABLED 0x00000100
303 309
304}; 310};
@@ -352,6 +358,11 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */
352#define PORT_FEATURE_MBA_ENABLED 0x02000000 358#define PORT_FEATURE_MBA_ENABLED 0x02000000
353#define PORT_FEATURE_MFW_ENABLED 0x04000000 359#define PORT_FEATURE_MFW_ENABLED 0x04000000
354 360
361 /* Check the optic vendor via i2c before allowing it to be used by
362 SW */
363#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLED 0x00000000
364#define PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_ENABLED 0x08000000
365
355 u32 wol_config; 366 u32 wol_config;
356 /* Default is used when driver sets to "auto" mode */ 367 /* Default is used when driver sets to "auto" mode */
357#define PORT_FEATURE_WOL_DEFAULT_MASK 0x00000003 368#define PORT_FEATURE_WOL_DEFAULT_MASK 0x00000003
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c
index aea26b4dc453..55f50c7093e0 100644
--- a/drivers/net/bnx2x_link.c
+++ b/drivers/net/bnx2x_link.c
@@ -139,6 +139,26 @@
139#define PHY_SGMII_FLAG 0x2 139#define PHY_SGMII_FLAG 0x2
140#define PHY_SERDES_FLAG 0x4 140#define PHY_SERDES_FLAG 0x4
141 141
142/* */
143#define SFP_EEPROM_CON_TYPE_ADDR 0x2
144 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
145 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
146
147#define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
148 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
149 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
150#define SFP_EEPROM_VENDOR_NAME_ADDR 0x14
151#define SFP_EEPROM_VENDOR_NAME_SIZE 16
152#define SFP_EEPROM_OPTIONS_ADDR 0x40
153 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
154#define SFP_EEPROM_OPTIONS_SIZE 2
155
156#define SFP_MODULE_TYPE_UNKNOWN 0x0
157#define SFP_MODULE_TYPE_LC 0x1
158#define SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE 0x2
159#define SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE 0x3
160
161#define SFP_LIMITING_MODE_VALUE 0x0044
142/**********************************************************/ 162/**********************************************************/
143/* INTERFACE */ 163/* INTERFACE */
144/**********************************************************/ 164/**********************************************************/
@@ -749,12 +769,17 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
749 return 0; 769 return 0;
750} 770}
751 771
752static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port) 772static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
753{ 773{
754 u32 emac_base; 774 u32 emac_base;
755 switch (ext_phy_type) { 775 switch (ext_phy_type) {
756 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: 776 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
757 emac_base = GRCBASE_EMAC0; 777 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
778 /* All MDC/MDIO is directed through single EMAC */
779 if (REG_RD(bp, NIG_REG_PORT_SWAP))
780 emac_base = GRCBASE_EMAC0;
781 else
782 emac_base = GRCBASE_EMAC1;
758 break; 783 break;
759 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 784 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
760 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1; 785 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
@@ -772,11 +797,12 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
772{ 797{
773 u32 tmp, saved_mode; 798 u32 tmp, saved_mode;
774 u8 i, rc = 0; 799 u8 i, rc = 0;
775 u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port); 800 u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
776 801
777 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz 802 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
778 * (a value of 49==0x31) and make sure that the AUTO poll is off 803 * (a value of 49==0x31) and make sure that the AUTO poll is off
779 */ 804 */
805
780 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); 806 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
781 tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL | 807 tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
782 EMAC_MDIO_MODE_CLOCK_CNT); 808 EMAC_MDIO_MODE_CLOCK_CNT);
@@ -841,10 +867,11 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
841 u16 i; 867 u16 i;
842 u8 rc = 0; 868 u8 rc = 0;
843 869
844 u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port); 870 u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port);
845 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz 871 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
846 * (a value of 49==0x31) and make sure that the AUTO poll is off 872 * (a value of 49==0x31) and make sure that the AUTO poll is off
847 */ 873 */
874
848 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); 875 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
849 val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL | 876 val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
850 EMAC_MDIO_MODE_CLOCK_CNT)); 877 EMAC_MDIO_MODE_CLOCK_CNT));
@@ -1726,7 +1753,9 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
1726 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) == 1753 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1727 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) || 1754 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1728 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == 1755 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1729 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) { 1756 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
1757 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1758 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) {
1730 vars->autoneg = AUTO_NEG_ENABLED; 1759 vars->autoneg = AUTO_NEG_ENABLED;
1731 1760
1732 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { 1761 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
@@ -1902,6 +1931,25 @@ static void bnx2x_ext_phy_reset(struct link_params *params,
1902 MDIO_PMA_DEVAD, 1931 MDIO_PMA_DEVAD,
1903 MDIO_PMA_REG_CTRL, 0xa040); 1932 MDIO_PMA_REG_CTRL, 0xa040);
1904 break; 1933 break;
1934 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
1935
1936 /* Restore normal power mode*/
1937 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1938 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1939 params->port);
1940
1941 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1942 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1943 params->port);
1944
1945 bnx2x_cl45_write(bp, params->port,
1946 ext_phy_type,
1947 ext_phy_addr,
1948 MDIO_PMA_DEVAD,
1949 MDIO_PMA_REG_CTRL,
1950 1<<15);
1951
1952 break;
1905 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: 1953 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1906 /* Unset Low Power Mode and SW reset */ 1954 /* Unset Low Power Mode and SW reset */
1907 /* Restore normal power mode*/ 1955 /* Restore normal power mode*/
@@ -2198,6 +2246,484 @@ static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2198 2246
2199} 2247}
2200 2248
2249static void bnx2x_bcm8726_external_rom_boot(struct link_params *params)
2250{
2251 struct bnx2x *bp = params->bp;
2252 u8 port = params->port;
2253 u8 ext_phy_addr = ((params->ext_phy_config &
2254 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2255 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2256 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2257
2258 /* Need to wait 100ms after reset */
2259 msleep(100);
2260
2261 /* Set serial boot control for external load */
2262 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2263 MDIO_PMA_DEVAD,
2264 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2265
2266 /* Micro controller re-boot */
2267 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2268 MDIO_PMA_DEVAD,
2269 MDIO_PMA_REG_GEN_CTRL,
2270 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2271
2272 /* Set soft reset */
2273 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2274 MDIO_PMA_DEVAD,
2275 MDIO_PMA_REG_GEN_CTRL,
2276 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2277
2278 /* Clear soft reset.
2279 Will automatically reset micro-controller re-boot */
2280 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2281 MDIO_PMA_DEVAD,
2282 MDIO_PMA_REG_GEN_CTRL,
2283 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2284
2285 /* wait for 100ms for microcode load */
2286 msleep(100);
2287
2288 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
2289 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2290 MDIO_PMA_DEVAD,
2291 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2292
2293 msleep(200);
2294}
2295
2296static void bnx2x_bcm8726_set_transmitter(struct bnx2x *bp, u8 port,
2297 u8 ext_phy_addr, u8 tx_en)
2298{
2299 u16 val;
2300 DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
2301 tx_en, port);
2302 /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
2303 bnx2x_cl45_read(bp, port,
2304 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2305 ext_phy_addr,
2306 MDIO_PMA_DEVAD,
2307 MDIO_PMA_REG_PHY_IDENTIFIER,
2308 &val);
2309
2310 if (tx_en)
2311 val &= ~(1<<15);
2312 else
2313 val |= (1<<15);
2314
2315 bnx2x_cl45_write(bp, port,
2316 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2317 ext_phy_addr,
2318 MDIO_PMA_DEVAD,
2319 MDIO_PMA_REG_PHY_IDENTIFIER,
2320 val);
2321}
2322
2323
2324static u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr,
2325 u8 byte_cnt, u8 *o_buf) {
2326 struct bnx2x *bp = params->bp;
2327 u16 val, i;
2328 u8 port = params->port;
2329 u8 ext_phy_addr = ((params->ext_phy_config &
2330 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2331 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2332 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2333 if (byte_cnt > 16) {
2334 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2335 " is limited to 0xf\n");
2336 return -EINVAL;
2337 }
2338 /* Set the read command byte count */
2339 bnx2x_cl45_write(bp, port,
2340 ext_phy_type,
2341 ext_phy_addr,
2342 MDIO_PMA_DEVAD,
2343 MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT,
2344 (byte_cnt | 0xa000));
2345
2346 /* Set the read command address */
2347 bnx2x_cl45_write(bp, port,
2348 ext_phy_type,
2349 ext_phy_addr,
2350 MDIO_PMA_DEVAD,
2351 MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR,
2352 addr);
2353
2354 /* Activate read command */
2355 bnx2x_cl45_write(bp, port,
2356 ext_phy_type,
2357 ext_phy_addr,
2358 MDIO_PMA_DEVAD,
2359 MDIO_PMA_REG_8726_TWO_WIRE_CTRL,
2360 0x2c0f);
2361
2362 /* Wait up to 500us for command complete status */
2363 for (i = 0; i < 100; i++) {
2364 bnx2x_cl45_read(bp, port,
2365 ext_phy_type,
2366 ext_phy_addr,
2367 MDIO_PMA_DEVAD,
2368 MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2369 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2370 MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE)
2371 break;
2372 udelay(5);
2373 }
2374
2375 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) !=
2376 MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE) {
2377 DP(NETIF_MSG_LINK,
2378 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2379 (val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK));
2380 return -EINVAL;
2381 }
2382
2383 /* Read the buffer */
2384 for (i = 0; i < byte_cnt; i++) {
2385 bnx2x_cl45_read(bp, port,
2386 ext_phy_type,
2387 ext_phy_addr,
2388 MDIO_PMA_DEVAD,
2389 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2390 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
2391 }
2392
2393 for (i = 0; i < 100; i++) {
2394 bnx2x_cl45_read(bp, port,
2395 ext_phy_type,
2396 ext_phy_addr,
2397 MDIO_PMA_DEVAD,
2398 MDIO_PMA_REG_8726_TWO_WIRE_CTRL, &val);
2399 if ((val & MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK) ==
2400 MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE)
2401 return 0;;
2402 msleep(1);
2403 }
2404 return -EINVAL;
2405}
2406
2407
2408static u8 bnx2x_get_sfp_module_type(struct link_params *params,
2409 u8 *module_type)
2410{
2411 struct bnx2x *bp = params->bp;
2412 u8 val;
2413 *module_type = SFP_MODULE_TYPE_UNKNOWN;
2414
2415 /* First check for copper cable */
2416 if (bnx2x_read_sfp_module_eeprom(params,
2417 SFP_EEPROM_CON_TYPE_ADDR,
2418 1,
2419 &val) != 0) {
2420 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM");
2421 return -EINVAL;
2422 }
2423
2424 switch (val) {
2425 case SFP_EEPROM_CON_TYPE_VAL_COPPER:
2426 {
2427 u8 copper_module_type;
2428 /* Check if its active cable( includes SFP+ module)
2429 of passive cable*/
2430 if (bnx2x_read_sfp_module_eeprom(params,
2431 SFP_EEPROM_FC_TX_TECH_ADDR,
2432 1,
2433 &copper_module_type) !=
2434 0) {
2435 DP(NETIF_MSG_LINK,
2436 "Failed to read copper-cable-type"
2437 " from SFP+ EEPROM\n");
2438 return -EINVAL;
2439 }
2440
2441 if (copper_module_type &
2442 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
2443 DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
2444 *module_type = SFP_MODULE_TYPE_ACTIVE_COPPER_CABLE;
2445 } else if (copper_module_type &
2446 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
2447 DP(NETIF_MSG_LINK, "Passive Copper"
2448 " cable detected\n");
2449 *module_type =
2450 SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE;
2451 } else {
2452 DP(NETIF_MSG_LINK, "Unknown copper-cable-"
2453 "type 0x%x !!!\n", copper_module_type);
2454 return -EINVAL;
2455 }
2456 break;
2457 }
2458 case SFP_EEPROM_CON_TYPE_VAL_LC:
2459 DP(NETIF_MSG_LINK, "Optic module detected\n");
2460 *module_type = SFP_MODULE_TYPE_LC;
2461 break;
2462
2463 default:
2464 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
2465 val);
2466 return -EINVAL;
2467 }
2468 return 0;
2469}
2470
2471
2472/* This function read the relevant field from the module ( SFP+ ),
2473 and verify it is compliant with this board */
2474static u8 bnx2x_verify_sfp_module(struct link_params *params,
2475 u8 module_type)
2476{
2477 struct bnx2x *bp = params->bp;
2478 u8 *str_p, *tmp_buf;
2479 u16 i;
2480
2481#define COMPLIANCE_STR_CNT 6
2482 u8 *compliance_str[] = {"Broadcom", "JDSU", "Molex Inc", "PICOLIGHT",
2483 "FINISAR CORP. ", "Amphenol"};
2484 u8 buf[SFP_EEPROM_VENDOR_NAME_SIZE];
2485 /* Passive Copper cables are allowed to participate,
2486 since the module is hardwired to the copper cable */
2487
2488 if (!(params->feature_config_flags &
2489 FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2490 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
2491 return 0;
2492 }
2493
2494 if (module_type != SFP_MODULE_TYPE_LC) {
2495 DP(NETIF_MSG_LINK, "No need to verify copper cable\n");
2496 return 0;
2497 }
2498
2499 /* In case of non copper cable or Active copper cable,
2500 verify that the SFP+ module is compliant with this board*/
2501 if (bnx2x_read_sfp_module_eeprom(params,
2502 SFP_EEPROM_VENDOR_NAME_ADDR,
2503 SFP_EEPROM_VENDOR_NAME_SIZE,
2504 buf) != 0) {
2505 DP(NETIF_MSG_LINK, "Failed to read Vendor-Name from"
2506 " module EEPROM\n");
2507 return -EINVAL;
2508 }
2509 for (i = 0; i < COMPLIANCE_STR_CNT; i++) {
2510 str_p = compliance_str[i];
2511 tmp_buf = buf;
2512 while (*str_p) {
2513 if ((u8)(*tmp_buf) != (u8)(*str_p))
2514 break;
2515 str_p++;
2516 tmp_buf++;
2517 }
2518
2519 if (!(*str_p)) {
2520 DP(NETIF_MSG_LINK, "SFP+ Module verified, "
2521 "index=%x\n", i);
2522 return 0;
2523 }
2524 }
2525 DP(NETIF_MSG_LINK, "Incompliant SFP+ module. Disable module !!!\n");
2526 return -EINVAL;
2527}
2528
2529
2530static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params,
2531 u8 module_type)
2532{
2533 struct bnx2x *bp = params->bp;
2534 u8 port = params->port;
2535 u8 options[SFP_EEPROM_OPTIONS_SIZE];
2536 u8 limiting_mode;
2537 u8 ext_phy_addr = ((params->ext_phy_config &
2538 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2539 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2540
2541 if (bnx2x_read_sfp_module_eeprom(params,
2542 SFP_EEPROM_OPTIONS_ADDR,
2543 SFP_EEPROM_OPTIONS_SIZE,
2544 options) != 0) {
2545 DP(NETIF_MSG_LINK, "Failed to read Option field from"
2546 " module EEPROM\n");
2547 return -EINVAL;
2548 }
2549 limiting_mode = !(options[0] &
2550 SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK);
2551 if (limiting_mode &&
2552 (module_type != SFP_MODULE_TYPE_PASSIVE_COPPER_CABLE)) {
2553 DP(NETIF_MSG_LINK,
2554 "Module options = 0x%x.Setting LIMITING MODE\n",
2555 options[0]);
2556 bnx2x_cl45_write(bp, port,
2557 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2558 ext_phy_addr,
2559 MDIO_PMA_DEVAD,
2560 MDIO_PMA_REG_ROM_VER2,
2561 SFP_LIMITING_MODE_VALUE);
2562 } else { /* LRM mode ( default )*/
2563 u16 cur_limiting_mode;
2564 DP(NETIF_MSG_LINK, "Module options = 0x%x.Setting LRM MODE\n",
2565 options[0]);
2566
2567 bnx2x_cl45_read(bp, port,
2568 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2569 ext_phy_addr,
2570 MDIO_PMA_DEVAD,
2571 MDIO_PMA_REG_ROM_VER2,
2572 &cur_limiting_mode);
2573
2574 /* Changing to LRM mode takes quite few seconds.
2575 So do it only if current mode is limiting
2576 ( default is LRM )*/
2577 if (cur_limiting_mode != SFP_LIMITING_MODE_VALUE)
2578 return 0;
2579
2580 bnx2x_cl45_write(bp, port,
2581 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2582 ext_phy_addr,
2583 MDIO_PMA_DEVAD,
2584 MDIO_PMA_REG_LRM_MODE,
2585 0);
2586 bnx2x_cl45_write(bp, port,
2587 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2588 ext_phy_addr,
2589 MDIO_PMA_DEVAD,
2590 MDIO_PMA_REG_ROM_VER2,
2591 0x128);
2592 bnx2x_cl45_write(bp, port,
2593 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2594 ext_phy_addr,
2595 MDIO_PMA_DEVAD,
2596 MDIO_PMA_REG_MISC_CTRL0,
2597 0x4008);
2598 bnx2x_cl45_write(bp, port,
2599 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
2600 ext_phy_addr,
2601 MDIO_PMA_DEVAD,
2602 MDIO_PMA_REG_LRM_MODE,
2603 0xaaaa);
2604 }
2605 return 0;
2606}
2607
2608static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
2609{
2610 u8 val;
2611 struct bnx2x *bp = params->bp;
2612 u16 timeout;
2613 /* Initialization time after hot-plug may take up to 300ms for some
2614 phys type ( e.g. JDSU ) */
2615 for (timeout = 0; timeout < 60; timeout++) {
2616 if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val)
2617 == 0) {
2618 DP(NETIF_MSG_LINK, "SFP+ module initialization "
2619 "took %d ms\n", timeout * 5);
2620 return 0;
2621 }
2622 msleep(5);
2623 }
2624 return -EINVAL;
2625}
2626
2627static u8 bnx2x_sfp_module_detection(struct link_params *params)
2628{
2629 struct bnx2x *bp = params->bp;
2630 u8 module_type;
2631 u8 ext_phy_addr = ((params->ext_phy_config &
2632 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2633 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2634 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2635
2636 if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
2637 DP(NETIF_MSG_LINK, "Module detection is not required "
2638 "for this phy\n");
2639 return 0;
2640 }
2641
2642 DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
2643 params->port);
2644
2645 if (bnx2x_get_sfp_module_type(params,
2646 &module_type) != 0) {
2647 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
2648 if (!(params->feature_config_flags &
2649 FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED)) {
2650 /* In case module detection is disabled, it trys to
2651 link up. The issue that can happen here is LRM /
2652 LIMITING mode which set according to the module-type*/
2653 DP(NETIF_MSG_LINK, "Unable to read module-type."
2654 "Probably due to Bit Stretching."
2655 " Proceeding...\n");
2656 } else {
2657 return -EINVAL;
2658 }
2659 } else if (bnx2x_verify_sfp_module(params, module_type) !=
2660 0) {
2661 /* check SFP+ module compatibility */
2662 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
2663 /* Turn on fault module-detected led */
2664 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2665 MISC_REGISTERS_GPIO_HIGH,
2666 params->port);
2667 return -EINVAL;
2668 }
2669
2670 /* Turn off fault module-detected led */
2671 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2672 MISC_REGISTERS_GPIO_LOW,
2673 params->port);
2674
2675 /* Check and set limiting mode / LRM mode */
2676 if (bnx2x_bcm8726_set_limiting_mode(params, module_type)
2677 != 0) {
2678 DP(NETIF_MSG_LINK, "Setting limiting mode failed!!\n");
2679 return -EINVAL;
2680 }
2681
2682 /* Enable transmit for this module */
2683 bnx2x_bcm8726_set_transmitter(bp, params->port,
2684 ext_phy_addr, 1);
2685 return 0;
2686}
2687
2688void bnx2x_handle_module_detect_int(struct link_params *params)
2689{
2690 struct bnx2x *bp = params->bp;
2691 u32 gpio_val;
2692 u8 port = params->port;
2693 /* Set valid module led off */
2694 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2695 MISC_REGISTERS_GPIO_HIGH,
2696 params->port);
2697
2698 /* Get current gpio val refelecting module plugged in / out*/
2699 gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
2700
2701 /* Call the handling function in case module is detected */
2702 if (gpio_val == 0) {
2703
2704 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2705 MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
2706 port);
2707
2708 if (bnx2x_wait_for_sfp_module_initialized(params)
2709 == 0)
2710 bnx2x_sfp_module_detection(params);
2711 else
2712 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
2713 } else {
2714 u8 ext_phy_addr = ((params->ext_phy_config &
2715 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2716 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2717 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
2718 MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
2719 port);
2720 /* Module was plugged out. */
2721 /* Disable transmit for this module */
2722 bnx2x_bcm8726_set_transmitter(bp, params->port,
2723 ext_phy_addr, 0);
2724 }
2725}
2726
2201static void bnx2x_bcm807x_force_10G(struct link_params *params) 2727static void bnx2x_bcm807x_force_10G(struct link_params *params)
2202{ 2728{
2203 struct bnx2x *bp = params->bp; 2729 struct bnx2x *bp = params->bp;
@@ -2580,7 +3106,68 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2580 } 3106 }
2581 3107
2582 break; 3108 break;
3109 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3110 DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3111 bnx2x_bcm8726_external_rom_boot(params);
3112
3113 /* Need to call module detected on initialization since
3114 the module detection triggered by actual module
3115 insertion might occur before driver is loaded, and when
3116 driver is loaded, it reset all registers, including the
3117 transmitter */
3118 bnx2x_sfp_module_detection(params);
3119 if (params->req_line_speed == SPEED_1000) {
3120 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3121 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3122 ext_phy_addr, MDIO_PMA_DEVAD,
3123 MDIO_PMA_REG_CTRL, 0x40);
3124 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3125 ext_phy_addr, MDIO_PMA_DEVAD,
3126 MDIO_PMA_REG_10G_CTRL2, 0xD);
3127 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3128 ext_phy_addr, MDIO_PMA_DEVAD,
3129 MDIO_PMA_REG_LASI_CTRL, 0x5);
3130 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3131 ext_phy_addr, MDIO_PMA_DEVAD,
3132 MDIO_PMA_REG_RX_ALARM_CTRL,
3133 0x400);
3134 } else if ((params->req_line_speed ==
3135 SPEED_AUTO_NEG) &&
3136 ((params->speed_cap_mask &
3137 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3138 DP(NETIF_MSG_LINK, "Setting 1G clause37 \n");
3139 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3140 ext_phy_addr, MDIO_AN_DEVAD,
3141 MDIO_AN_REG_ADV, 0x20);
3142 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3143 ext_phy_addr, MDIO_AN_DEVAD,
3144 MDIO_AN_REG_CL37_CL73, 0x040c);
3145 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3146 ext_phy_addr, MDIO_AN_DEVAD,
3147 MDIO_AN_REG_CL37_FC_LD, 0x0020);
3148 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3149 ext_phy_addr, MDIO_AN_DEVAD,
3150 MDIO_AN_REG_CL37_AN, 0x1000);
3151 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3152 ext_phy_addr, MDIO_AN_DEVAD,
3153 MDIO_AN_REG_CTRL, 0x1200);
3154
3155 /* Enable RX-ALARM control to receive
3156 interrupt for 1G speed change */
3157 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3158 ext_phy_addr, MDIO_PMA_DEVAD,
3159 MDIO_PMA_REG_LASI_CTRL, 0x4);
3160 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3161 ext_phy_addr, MDIO_PMA_DEVAD,
3162 MDIO_PMA_REG_RX_ALARM_CTRL,
3163 0x400);
2583 3164
3165 } else { /* Default 10G. Set only LASI control */
3166 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3167 ext_phy_addr, MDIO_PMA_DEVAD,
3168 MDIO_PMA_REG_LASI_CTRL, 1);
3169 }
3170 break;
2584 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: 3171 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2585 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 3172 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2586 { 3173 {
@@ -2910,38 +3497,43 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2910 break; 3497 break;
2911 3498
2912 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: 3499 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2913 DP(NETIF_MSG_LINK, "XGXS 8706\n"); 3500 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3501 DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
3502 /* Clear RX Alarm*/
2914 bnx2x_cl45_read(bp, params->port, ext_phy_type, 3503 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2915 ext_phy_addr, 3504 ext_phy_addr,
2916 MDIO_PMA_DEVAD, 3505 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
2917 MDIO_PMA_REG_LASI_STATUS, &val1); 3506 &val2);
2918 DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1); 3507 /* clear LASI indication*/
2919
2920 bnx2x_cl45_read(bp, params->port, ext_phy_type, 3508 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2921 ext_phy_addr, 3509 ext_phy_addr,
2922 MDIO_PMA_DEVAD, 3510 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
2923 MDIO_PMA_REG_LASI_STATUS, &val1); 3511 &val1);
2924 DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1); 3512 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3513 ext_phy_addr,
3514 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
3515 &val2);
3516 DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
3517 "0x%x\n", val1, val2);
2925 3518
2926 bnx2x_cl45_read(bp, params->port, ext_phy_type, 3519 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2927 ext_phy_addr, 3520 ext_phy_addr,
2928 MDIO_PMA_DEVAD, 3521 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
2929 MDIO_PMA_REG_RX_SD, &rx_sd); 3522 &rx_sd);
2930 bnx2x_cl45_read(bp, params->port, ext_phy_type, 3523 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2931 ext_phy_addr, 3524 ext_phy_addr,
2932 MDIO_PCS_DEVAD, 3525 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
2933 MDIO_PCS_REG_STATUS, &pcs_status); 3526 &pcs_status);
2934
2935 bnx2x_cl45_read(bp, params->port, ext_phy_type, 3527 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2936 ext_phy_addr, 3528 ext_phy_addr,
2937 MDIO_AN_DEVAD, 3529 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
2938 MDIO_AN_REG_LINK_STATUS, &val2); 3530 &val2);
2939 bnx2x_cl45_read(bp, params->port, ext_phy_type, 3531 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2940 ext_phy_addr, 3532 ext_phy_addr,
2941 MDIO_AN_DEVAD, 3533 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
2942 MDIO_AN_REG_LINK_STATUS, &val2); 3534 &val2);
2943 3535
2944 DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x" 3536 DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
2945 " pcs_status 0x%x 1Gbps link_status 0x%x\n", 3537 " pcs_status 0x%x 1Gbps link_status 0x%x\n",
2946 rx_sd, pcs_status, val2); 3538 rx_sd, pcs_status, val2);
2947 /* link is up if both bit 0 of pmd_rx_sd and 3539 /* link is up if both bit 0 of pmd_rx_sd and
@@ -2951,19 +3543,31 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2951 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) || 3543 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
2952 (val2 & (1<<1))); 3544 (val2 & (1<<1)));
2953 if (ext_phy_link_up) { 3545 if (ext_phy_link_up) {
3546 if (ext_phy_type ==
3547 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
3548 /* If transmitter is disabled,
3549 ignore false link up indication */
3550 bnx2x_cl45_read(bp, params->port,
3551 ext_phy_type,
3552 ext_phy_addr,
3553 MDIO_PMA_DEVAD,
3554 MDIO_PMA_REG_PHY_IDENTIFIER,
3555 &val1);
3556 if (val1 & (1<<15)) {
3557 DP(NETIF_MSG_LINK, "Tx is "
3558 "disabled\n");
3559 ext_phy_link_up = 0;
3560 break;
3561 }
3562 }
3563
2954 if (val2 & (1<<1)) 3564 if (val2 & (1<<1))
2955 vars->line_speed = SPEED_1000; 3565 vars->line_speed = SPEED_1000;
2956 else 3566 else
2957 vars->line_speed = SPEED_10000; 3567 vars->line_speed = SPEED_10000;
2958 } 3568 }
2959 3569
2960 /* clear LASI indication*/
2961 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2962 ext_phy_addr,
2963 MDIO_PMA_DEVAD,
2964 MDIO_PMA_REG_RX_ALARM, &val2);
2965 break; 3570 break;
2966
2967 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: 3571 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2968 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 3572 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2969 { 3573 {
@@ -3523,7 +4127,7 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3523 } 4127 }
3524 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: 4128 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3525 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: 4129 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3526 4130 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3527 bnx2x_cl45_read(bp, params->port, ext_phy_type, 4131 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3528 ext_phy_addr, 4132 ext_phy_addr,
3529 MDIO_PMA_DEVAD, 4133 MDIO_PMA_DEVAD,
@@ -3636,6 +4240,14 @@ static void bnx2x_ext_phy_loopback(struct link_params *params)
3636 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: 4240 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3637 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n"); 4241 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
3638 break; 4242 break;
4243 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4244 DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
4245 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4246 ext_phy_addr,
4247 MDIO_PMA_DEVAD,
4248 MDIO_PMA_REG_CTRL,
4249 0x0001);
4250 break;
3639 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: 4251 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3640 /* SFX7101_XGXS_TEST1 */ 4252 /* SFX7101_XGXS_TEST1 */
3641 bnx2x_cl45_write(bp, params->port, ext_phy_type, 4253 bnx2x_cl45_write(bp, params->port, ext_phy_type,
@@ -3910,7 +4522,8 @@ static u8 bnx2x_link_initialize(struct link_params *params,
3910 (params->loopback_mode == LOOPBACK_EXT_PHY)); 4522 (params->loopback_mode == LOOPBACK_EXT_PHY));
3911 4523
3912 if (non_ext_phy || 4524 if (non_ext_phy ||
3913 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705)) { 4525 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
4526 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)) {
3914 if (params->req_line_speed == SPEED_AUTO_NEG) 4527 if (params->req_line_speed == SPEED_AUTO_NEG)
3915 bnx2x_set_parallel_detection(params, vars->phy_flags); 4528 bnx2x_set_parallel_detection(params, vars->phy_flags);
3916 bnx2x_init_internal_phy(params, vars); 4529 bnx2x_init_internal_phy(params, vars);
@@ -4112,7 +4725,23 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
4112 return 0; 4725 return 0;
4113} 4726}
4114 4727
4115u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars) 4728static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
4729{
4730 DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
4731
4732 /* Set serial boot control for external load */
4733 bnx2x_cl45_write(bp, port,
4734 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
4735 MDIO_PMA_DEVAD,
4736 MDIO_PMA_REG_GEN_CTRL, 0x0001);
4737
4738 /* Disable Transmitter */
4739 bnx2x_bcm8726_set_transmitter(bp, port, ext_phy_addr, 0);
4740
4741}
4742
4743u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
4744 u8 reset_ext_phy)
4116{ 4745{
4117 4746
4118 struct bnx2x *bp = params->bp; 4747 struct bnx2x *bp = params->bp;
@@ -4150,28 +4779,37 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
4150 */ 4779 */
4151 /* clear link led */ 4780 /* clear link led */
4152 bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id); 4781 bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4153 if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) { 4782 if (reset_ext_phy) {
4154 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) && 4783 switch (ext_phy_type) {
4155 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) { 4784 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4785 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4786 break;
4787 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4788 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4789 "low power mode\n",
4790 port);
4791 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4792 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4793 port);
4794 break;
4795 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4796 {
4797 u8 ext_phy_addr = ((params->ext_phy_config &
4798 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4799 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4800 /* Set soft reset */
4801 bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
4802 break;
4803 }
4804 default:
4156 /* HW reset */ 4805 /* HW reset */
4157
4158 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 4806 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4159 MISC_REGISTERS_GPIO_OUTPUT_LOW, 4807 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4160 port); 4808 port);
4161
4162 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 4809 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4163 MISC_REGISTERS_GPIO_OUTPUT_LOW, 4810 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4164 port); 4811 port);
4165
4166 DP(NETIF_MSG_LINK, "reset external PHY\n"); 4812 DP(NETIF_MSG_LINK, "reset external PHY\n");
4167 } else if (ext_phy_type ==
4168 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4169 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4170 "low power mode\n",
4171 port);
4172 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4173 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4174 port);
4175 } 4813 }
4176 } 4814 }
4177 /* reset the SerDes/XGXS */ 4815 /* reset the SerDes/XGXS */
@@ -4337,6 +4975,7 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4337 4975
4338 if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) && 4976 if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4339 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) && 4977 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
4978 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
4340 (ext_phy_link_up && !vars->phy_link_up)) 4979 (ext_phy_link_up && !vars->phy_link_up))
4341 bnx2x_init_internal_phy(params, vars); 4980 bnx2x_init_internal_phy(params, vars);
4342 4981
@@ -4469,6 +5108,45 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4469 5108
4470} 5109}
4471 5110
5111
5112static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
5113{
5114 u8 ext_phy_addr;
5115 u32 val;
5116 s8 port;
5117 /* Use port1 because of the static port-swap */
5118 /* Enable the module detection interrupt */
5119 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
5120 val |= ((1<<MISC_REGISTERS_GPIO_3)|
5121 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
5122 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
5123
5124 bnx2x_hw_reset(bp, 1);
5125 msleep(5);
5126 for (port = 0; port < PORT_MAX; port++) {
5127 /* Extract the ext phy address for the port */
5128 u32 ext_phy_config = REG_RD(bp, shmem_base +
5129 offsetof(struct shmem_region,
5130 dev_info.port_hw_config[port].external_phy_config));
5131
5132 ext_phy_addr =
5133 ((ext_phy_config &
5134 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
5135 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
5136 DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
5137 ext_phy_addr);
5138
5139 bnx2x_8726_reset_phy(bp, port, ext_phy_addr);
5140
5141 /* Set fault module detected LED on */
5142 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
5143 MISC_REGISTERS_GPIO_HIGH,
5144 port);
5145 }
5146
5147 return 0;
5148}
5149
4472u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base) 5150u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4473{ 5151{
4474 u8 rc = 0; 5152 u8 rc = 0;
@@ -4488,6 +5166,12 @@ u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4488 rc = bnx2x_8073_common_init_phy(bp, shmem_base); 5166 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
4489 break; 5167 break;
4490 } 5168 }
5169 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5170 /* GPIO1 affects both ports, so there's need to pull
5171 it for single port alone */
5172 rc = bnx2x_8726_common_init_phy(bp, shmem_base);
5173
5174 break;
4491 default: 5175 default:
4492 DP(NETIF_MSG_LINK, 5176 DP(NETIF_MSG_LINK,
4493 "bnx2x_common_init_phy: ext_phy 0x%x not required\n", 5177 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
diff --git a/drivers/net/bnx2x_link.h b/drivers/net/bnx2x_link.h
index 47cb585f4278..1318683f6e51 100644
--- a/drivers/net/bnx2x_link.h
+++ b/drivers/net/bnx2x_link.h
@@ -89,6 +89,9 @@ struct link_params {
89 89
90 /* phy_addr populated by the CLC */ 90 /* phy_addr populated by the CLC */
91 u8 phy_addr; 91 u8 phy_addr;
92 u32 feature_config_flags;
93#define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0)
94#define FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED (2<<0)
92 /* Device pointer passed to all callback functions */ 95 /* Device pointer passed to all callback functions */
93 struct bnx2x *bp; 96 struct bnx2x *bp;
94}; 97};
@@ -125,8 +128,11 @@ struct link_vars {
125/* Initialize the phy */ 128/* Initialize the phy */
126u8 bnx2x_phy_init(struct link_params *input, struct link_vars *output); 129u8 bnx2x_phy_init(struct link_params *input, struct link_vars *output);
127 130
128/* Reset the link. Should be called when driver or interface goes down */ 131/* Reset the link. Should be called when driver or interface goes down
129u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars); 132 Before calling phy firmware upgrade, the reset_ext_phy should be set
133 to 0 */
134u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
135 u8 reset_ext_phy);
130 136
131/* bnx2x_link_update should be called upon link interrupt */ 137/* bnx2x_link_update should be called upon link interrupt */
132u8 bnx2x_link_update(struct link_params *input, struct link_vars *output); 138u8 bnx2x_link_update(struct link_params *input, struct link_vars *output);
@@ -163,6 +169,10 @@ u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, u32 led_idx, u32 value);
163 169
164u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config, 170u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
165 u8 driver_loaded, char data[], u32 size); 171 u8 driver_loaded, char data[], u32 size);
172/* bnx2x_handle_module_detect_int should be called upon module detection
173 interrupt */
174void bnx2x_handle_module_detect_int(struct link_params *params);
175
166/* Get the actual link status. In case it returns 0, link is up, 176/* Get the actual link status. In case it returns 0, link is up,
167 otherwise link is down*/ 177 otherwise link is down*/
168u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars); 178u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars);
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 95f8e58e73b4..5acbd98778b8 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -2112,7 +2112,7 @@ static void bnx2x__link_reset(struct bnx2x *bp)
2112{ 2112{
2113 if (!BP_NOMCP(bp)) { 2113 if (!BP_NOMCP(bp)) {
2114 bnx2x_acquire_phy_lock(bp); 2114 bnx2x_acquire_phy_lock(bp);
2115 bnx2x_link_reset(&bp->link_params, &bp->link_vars); 2115 bnx2x_link_reset(&bp->link_params, &bp->link_vars, 1);
2116 bnx2x_release_phy_lock(bp); 2116 bnx2x_release_phy_lock(bp);
2117 } else 2117 } else
2118 BNX2X_ERR("Bootcode is missing -not resetting link\n"); 2118 BNX2X_ERR("Bootcode is missing -not resetting link\n");
@@ -2613,6 +2613,13 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn)
2613 } 2613 }
2614 } 2614 }
2615 2615
2616 if (attn & (AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 |
2617 AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1)) {
2618 bnx2x_acquire_phy_lock(bp);
2619 bnx2x_handle_module_detect_int(&bp->link_params);
2620 bnx2x_release_phy_lock(bp);
2621 }
2622
2616 if (attn & HW_INTERRUT_ASSERT_SET_0) { 2623 if (attn & HW_INTERRUT_ASSERT_SET_0) {
2617 2624
2618 val = REG_RD(bp, reg_offset); 2625 val = REG_RD(bp, reg_offset);
@@ -5905,6 +5912,37 @@ static int bnx2x_init_port(struct bnx2x *bp)
5905 /* Port DMAE comes here */ 5912 /* Port DMAE comes here */
5906 5913
5907 switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { 5914 switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
5915 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5916 {
5917 u32 swap_val, swap_override, aeu_gpio_mask, offset;
5918
5919 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
5920 MISC_REGISTERS_GPIO_INPUT_HI_Z, port);
5921
5922 /* The GPIO should be swapped if the swap register is
5923 set and active */
5924 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
5925 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
5926
5927 /* Select function upon port-swap configuration */
5928 if (port == 0) {
5929 offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
5930 aeu_gpio_mask = (swap_val && swap_override) ?
5931 AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 :
5932 AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0;
5933 } else {
5934 offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
5935 aeu_gpio_mask = (swap_val && swap_override) ?
5936 AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 :
5937 AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1;
5938 }
5939 val = REG_RD(bp, offset);
5940 /* add GPIO3 to group */
5941 val |= aeu_gpio_mask;
5942 REG_WR(bp, offset, val);
5943 }
5944 break;
5945
5908 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: 5946 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
5909 /* add SPIO 5 to group 0 */ 5947 /* add SPIO 5 to group 0 */
5910 val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); 5948 val = REG_RD(bp, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
@@ -7623,48 +7661,60 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp,
7623 SUPPORTED_Asym_Pause); 7661 SUPPORTED_Asym_Pause);
7624 break; 7662 break;
7625 7663
7626 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: 7664 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
7627 BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n", 7665 BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n",
7628 ext_phy_type); 7666 ext_phy_type);
7629 7667
7630 bp->port.supported |= (SUPPORTED_10000baseT_Full | 7668 bp->port.supported |= (SUPPORTED_10000baseT_Full |
7669 SUPPORTED_1000baseT_Full |
7631 SUPPORTED_FIBRE | 7670 SUPPORTED_FIBRE |
7671 SUPPORTED_Autoneg |
7632 SUPPORTED_Pause | 7672 SUPPORTED_Pause |
7633 SUPPORTED_Asym_Pause); 7673 SUPPORTED_Asym_Pause);
7634 break; 7674 break;
7635 7675
7636 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: 7676 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
7637 BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n", 7677 BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n",
7638 ext_phy_type); 7678 ext_phy_type);
7639 7679
7640 bp->port.supported |= (SUPPORTED_10000baseT_Full | 7680 bp->port.supported |= (SUPPORTED_10000baseT_Full |
7681 SUPPORTED_2500baseX_Full |
7641 SUPPORTED_1000baseT_Full | 7682 SUPPORTED_1000baseT_Full |
7642 SUPPORTED_FIBRE | 7683 SUPPORTED_FIBRE |
7684 SUPPORTED_Autoneg |
7685 SUPPORTED_Pause |
7686 SUPPORTED_Asym_Pause);
7687 break;
7688
7689 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
7690 BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n",
7691 ext_phy_type);
7692
7693 bp->port.supported |= (SUPPORTED_10000baseT_Full |
7694 SUPPORTED_FIBRE |
7643 SUPPORTED_Pause | 7695 SUPPORTED_Pause |
7644 SUPPORTED_Asym_Pause); 7696 SUPPORTED_Asym_Pause);
7645 break; 7697 break;
7646 7698
7647 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: 7699 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
7648 BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n", 7700 BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n",
7649 ext_phy_type); 7701 ext_phy_type);
7650 7702
7651 bp->port.supported |= (SUPPORTED_10000baseT_Full | 7703 bp->port.supported |= (SUPPORTED_10000baseT_Full |
7652 SUPPORTED_1000baseT_Full | 7704 SUPPORTED_1000baseT_Full |
7653 SUPPORTED_FIBRE | 7705 SUPPORTED_FIBRE |
7654 SUPPORTED_Autoneg |
7655 SUPPORTED_Pause | 7706 SUPPORTED_Pause |
7656 SUPPORTED_Asym_Pause); 7707 SUPPORTED_Asym_Pause);
7657 break; 7708 break;
7658 7709
7659 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 7710 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7660 BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n", 7711 BNX2X_DEV_INFO("ext_phy_type 0x%x (8726)\n",
7661 ext_phy_type); 7712 ext_phy_type);
7662 7713
7663 bp->port.supported |= (SUPPORTED_10000baseT_Full | 7714 bp->port.supported |= (SUPPORTED_10000baseT_Full |
7664 SUPPORTED_2500baseX_Full |
7665 SUPPORTED_1000baseT_Full | 7715 SUPPORTED_1000baseT_Full |
7666 SUPPORTED_FIBRE |
7667 SUPPORTED_Autoneg | 7716 SUPPORTED_Autoneg |
7717 SUPPORTED_FIBRE |
7668 SUPPORTED_Pause | 7718 SUPPORTED_Pause |
7669 SUPPORTED_Asym_Pause); 7719 SUPPORTED_Asym_Pause);
7670 break; 7720 break;
@@ -7905,6 +7955,7 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
7905{ 7955{
7906 int port = BP_PORT(bp); 7956 int port = BP_PORT(bp);
7907 u32 val, val2; 7957 u32 val, val2;
7958 u32 config;
7908 7959
7909 bp->link_params.bp = bp; 7960 bp->link_params.bp = bp;
7910 bp->link_params.port = port; 7961 bp->link_params.port = port;
@@ -7923,6 +7974,14 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
7923 bp->port.link_config = 7974 bp->port.link_config =
7924 SHMEM_RD(bp, dev_info.port_feature_config[port].link_config); 7975 SHMEM_RD(bp, dev_info.port_feature_config[port].link_config);
7925 7976
7977 config = SHMEM_RD(bp, dev_info.port_feature_config[port].config);
7978 if (config & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_ENABLED)
7979 bp->link_params.feature_config_flags |=
7980 FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED;
7981 else
7982 bp->link_params.feature_config_flags &=
7983 ~FEATURE_CONFIG_MODULE_ENFORCMENT_ENABLED;
7984
7926 BNX2X_DEV_INFO("serdes_config 0x%08x lane_config 0x%08x\n" 7985 BNX2X_DEV_INFO("serdes_config 0x%08x lane_config 0x%08x\n"
7927 KERN_INFO " ext_phy_config 0x%08x speed_cap_mask 0x%08x" 7986 KERN_INFO " ext_phy_config 0x%08x speed_cap_mask 0x%08x"
7928 " link_config 0x%08x\n", 7987 " link_config 0x%08x\n",
@@ -8121,10 +8180,11 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
8121 8180
8122 switch (ext_phy_type) { 8181 switch (ext_phy_type) {
8123 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: 8182 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
8124 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
8125 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
8126 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: 8183 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
8127 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 8184 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
8185 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
8186 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
8187 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
8128 cmd->port = PORT_FIBRE; 8188 cmd->port = PORT_FIBRE;
8129 break; 8189 break;
8130 8190
@@ -8807,7 +8867,7 @@ static int bnx2x_set_eeprom(struct net_device *dev,
8807 if ((bp->state == BNX2X_STATE_OPEN) || 8867 if ((bp->state == BNX2X_STATE_OPEN) ||
8808 (bp->state == BNX2X_STATE_DISABLED)) { 8868 (bp->state == BNX2X_STATE_DISABLED)) {
8809 rc |= bnx2x_link_reset(&bp->link_params, 8869 rc |= bnx2x_link_reset(&bp->link_params,
8810 &bp->link_vars); 8870 &bp->link_vars, 1);
8811 rc |= bnx2x_phy_init(&bp->link_params, 8871 rc |= bnx2x_phy_init(&bp->link_params,
8812 &bp->link_vars); 8872 &bp->link_vars);
8813 } 8873 }
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h
index 6fc1d0df9789..520bf695864e 100644
--- a/drivers/net/bnx2x_reg.h
+++ b/drivers/net/bnx2x_reg.h
@@ -5800,9 +5800,25 @@ Theotherbitsarereservedandshouldbezero*/
5800#define MDIO_PMA_REG_ROM_VER2 0xca1a 5800#define MDIO_PMA_REG_ROM_VER2 0xca1a
5801#define MDIO_PMA_REG_EDC_FFE_MAIN 0xca1b 5801#define MDIO_PMA_REG_EDC_FFE_MAIN 0xca1b
5802#define MDIO_PMA_REG_PLL_BANDWIDTH 0xca1d 5802#define MDIO_PMA_REG_PLL_BANDWIDTH 0xca1d
5803#define MDIO_PMA_REG_MISC_CTRL0 0xca23
5804#define MDIO_PMA_REG_LRM_MODE 0xca3f
5803#define MDIO_PMA_REG_CDR_BANDWIDTH 0xca46 5805#define MDIO_PMA_REG_CDR_BANDWIDTH 0xca46
5804#define MDIO_PMA_REG_MISC_CTRL1 0xca85 5806#define MDIO_PMA_REG_MISC_CTRL1 0xca85
5805 5807
5808#define MDIO_PMA_REG_8726_TWO_WIRE_CTRL 0x8000
5809#define MDIO_PMA_REG_8726_TWO_WIRE_CTRL_STATUS_MASK 0x000c
5810#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IDLE 0x0000
5811#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_COMPLETE 0x0004
5812#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_IN_PROGRESS 0x0008
5813#define MDIO_PMA_REG_8726_TWO_WIRE_STATUS_FAILED 0x000c
5814#define MDIO_PMA_REG_8726_TWO_WIRE_BYTE_CNT 0x8002
5815#define MDIO_PMA_REG_8726_TWO_WIRE_MEM_ADDR 0x8003
5816#define MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF 0xc820
5817#define MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK 0xff
5818#define MDIO_PMA_REG_8726_TX_CTRL1 0xca01
5819#define MDIO_PMA_REG_8726_TX_CTRL2 0xca05
5820
5821
5806#define MDIO_PMA_REG_7101_RESET 0xc000 5822#define MDIO_PMA_REG_7101_RESET 0xc000
5807#define MDIO_PMA_REG_7107_LED_CNTL 0xc007 5823#define MDIO_PMA_REG_7107_LED_CNTL 0xc007
5808#define MDIO_PMA_REG_7101_VER1 0xc026 5824#define MDIO_PMA_REG_7101_VER1 0xc026
@@ -5832,6 +5848,12 @@ Theotherbitsarereservedandshouldbezero*/
5832#define MDIO_XS_PLL_SEQUENCER 0x8000 5848#define MDIO_XS_PLL_SEQUENCER 0x8000
5833#define MDIO_XS_SFX7101_XGXS_TEST1 0xc00a 5849#define MDIO_XS_SFX7101_XGXS_TEST1 0xc00a
5834 5850
5851#define MDIO_XS_8706_REG_BANK_RX0 0x80bc
5852#define MDIO_XS_8706_REG_BANK_RX1 0x80cc
5853#define MDIO_XS_8706_REG_BANK_RX2 0x80dc
5854#define MDIO_XS_8706_REG_BANK_RX3 0x80ec
5855#define MDIO_XS_8706_REG_BANK_RXA 0x80fc
5856
5835#define MDIO_AN_DEVAD 0x7 5857#define MDIO_AN_DEVAD 0x7
5836/*ieee*/ 5858/*ieee*/
5837#define MDIO_AN_REG_CTRL 0x0000 5859#define MDIO_AN_REG_CTRL 0x0000