diff options
-rw-r--r-- | drivers/net/bnx2x_link.c | 576 | ||||
-rw-r--r-- | drivers/net/bnx2x_link.h | 3 | ||||
-rw-r--r-- | drivers/net/bnx2x_main.c | 7 |
3 files changed, 428 insertions, 158 deletions
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index c9cffa6d47b6..693efce7cda5 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c | |||
@@ -2121,42 +2121,45 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params) | |||
2121 | 2121 | ||
2122 | } | 2122 | } |
2123 | 2123 | ||
2124 | static void bnx2x_bcm8073_external_rom_boot(struct link_params *params) | 2124 | static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port, |
2125 | u8 ext_phy_addr) | ||
2125 | { | 2126 | { |
2126 | struct bnx2x *bp = params->bp; | 2127 | u16 fw_ver1, fw_ver2; |
2127 | u8 port = params->port; | 2128 | /* Boot port from external ROM */ |
2128 | u8 ext_phy_addr = ((params->ext_phy_config & | ||
2129 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | ||
2130 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | ||
2131 | u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); | ||
2132 | u16 fw_ver1, fw_ver2, val; | ||
2133 | /* Need to wait 100ms after reset */ | ||
2134 | msleep(100); | ||
2135 | /* Boot port from external ROM */ | ||
2136 | /* EDC grst */ | 2129 | /* EDC grst */ |
2137 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2130 | bnx2x_cl45_write(bp, port, |
2131 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
2132 | ext_phy_addr, | ||
2138 | MDIO_PMA_DEVAD, | 2133 | MDIO_PMA_DEVAD, |
2139 | MDIO_PMA_REG_GEN_CTRL, | 2134 | MDIO_PMA_REG_GEN_CTRL, |
2140 | 0x0001); | 2135 | 0x0001); |
2141 | 2136 | ||
2142 | /* ucode reboot and rst */ | 2137 | /* ucode reboot and rst */ |
2143 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2138 | bnx2x_cl45_write(bp, port, |
2139 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
2140 | ext_phy_addr, | ||
2144 | MDIO_PMA_DEVAD, | 2141 | MDIO_PMA_DEVAD, |
2145 | MDIO_PMA_REG_GEN_CTRL, | 2142 | MDIO_PMA_REG_GEN_CTRL, |
2146 | 0x008c); | 2143 | 0x008c); |
2147 | 2144 | ||
2148 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2145 | bnx2x_cl45_write(bp, port, |
2146 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
2147 | ext_phy_addr, | ||
2149 | MDIO_PMA_DEVAD, | 2148 | MDIO_PMA_DEVAD, |
2150 | MDIO_PMA_REG_MISC_CTRL1, 0x0001); | 2149 | MDIO_PMA_REG_MISC_CTRL1, 0x0001); |
2151 | 2150 | ||
2152 | /* Reset internal microprocessor */ | 2151 | /* Reset internal microprocessor */ |
2153 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2152 | bnx2x_cl45_write(bp, port, |
2153 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
2154 | ext_phy_addr, | ||
2154 | MDIO_PMA_DEVAD, | 2155 | MDIO_PMA_DEVAD, |
2155 | MDIO_PMA_REG_GEN_CTRL, | 2156 | MDIO_PMA_REG_GEN_CTRL, |
2156 | MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); | 2157 | MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); |
2157 | 2158 | ||
2158 | /* Release srst bit */ | 2159 | /* Release srst bit */ |
2159 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2160 | bnx2x_cl45_write(bp, port, |
2161 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
2162 | ext_phy_addr, | ||
2160 | MDIO_PMA_DEVAD, | 2163 | MDIO_PMA_DEVAD, |
2161 | MDIO_PMA_REG_GEN_CTRL, | 2164 | MDIO_PMA_REG_GEN_CTRL, |
2162 | MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); | 2165 | MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); |
@@ -2165,35 +2168,52 @@ static void bnx2x_bcm8073_external_rom_boot(struct link_params *params) | |||
2165 | msleep(100); | 2168 | msleep(100); |
2166 | 2169 | ||
2167 | /* Clear ser_boot_ctl bit */ | 2170 | /* Clear ser_boot_ctl bit */ |
2168 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2171 | bnx2x_cl45_write(bp, port, |
2172 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
2173 | ext_phy_addr, | ||
2169 | MDIO_PMA_DEVAD, | 2174 | MDIO_PMA_DEVAD, |
2170 | MDIO_PMA_REG_MISC_CTRL1, 0x0000); | 2175 | MDIO_PMA_REG_MISC_CTRL1, 0x0000); |
2171 | 2176 | ||
2172 | bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, | 2177 | bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, |
2173 | MDIO_PMA_DEVAD, | 2178 | ext_phy_addr, |
2174 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); | 2179 | MDIO_PMA_DEVAD, |
2175 | bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, | 2180 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); |
2176 | MDIO_PMA_DEVAD, | 2181 | bnx2x_cl45_read(bp, port, |
2177 | MDIO_PMA_REG_ROM_VER2, &fw_ver2); | 2182 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, |
2183 | ext_phy_addr, | ||
2184 | MDIO_PMA_DEVAD, | ||
2185 | MDIO_PMA_REG_ROM_VER2, &fw_ver2); | ||
2178 | DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2); | 2186 | DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2); |
2179 | 2187 | ||
2180 | /* Only set bit 10 = 1 (Tx power down) */ | 2188 | } |
2181 | bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, | ||
2182 | MDIO_PMA_DEVAD, | ||
2183 | MDIO_PMA_REG_TX_POWER_DOWN, &val); | ||
2184 | 2189 | ||
2190 | static void bnx2x_bcm807x_force_10G(struct link_params *params) | ||
2191 | { | ||
2192 | struct bnx2x *bp = params->bp; | ||
2193 | u8 port = params->port; | ||
2194 | u8 ext_phy_addr = ((params->ext_phy_config & | ||
2195 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | ||
2196 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | ||
2197 | u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); | ||
2198 | |||
2199 | /* Force KR or KX */ | ||
2185 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2200 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, |
2186 | MDIO_PMA_DEVAD, | 2201 | MDIO_PMA_DEVAD, |
2187 | MDIO_PMA_REG_TX_POWER_DOWN, (val | 1<<10)); | 2202 | MDIO_PMA_REG_CTRL, |
2188 | 2203 | 0x2040); | |
2189 | msleep(600); | ||
2190 | /* Release bit 10 (Release Tx power down) */ | ||
2191 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2204 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, |
2192 | MDIO_PMA_DEVAD, | 2205 | MDIO_PMA_DEVAD, |
2193 | MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10)))); | 2206 | MDIO_PMA_REG_10G_CTRL2, |
2194 | 2207 | 0x000b); | |
2208 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | ||
2209 | MDIO_PMA_DEVAD, | ||
2210 | MDIO_PMA_REG_BCM_CTRL, | ||
2211 | 0x0000); | ||
2212 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | ||
2213 | MDIO_AN_DEVAD, | ||
2214 | MDIO_AN_REG_CTRL, | ||
2215 | 0x0000); | ||
2195 | } | 2216 | } |
2196 | |||
2197 | static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params) | 2217 | static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params) |
2198 | { | 2218 | { |
2199 | struct bnx2x *bp = params->bp; | 2219 | struct bnx2x *bp = params->bp; |
@@ -2259,32 +2279,51 @@ static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params) | |||
2259 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2279 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, |
2260 | MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); | 2280 | MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); |
2261 | } | 2281 | } |
2262 | static void bnx2x_bcm807x_force_10G(struct link_params *params) | 2282 | |
2283 | static void bnx2x_8073_set_pause_cl37(struct link_params *params, | ||
2284 | struct link_vars *vars) | ||
2263 | { | 2285 | { |
2286 | |||
2264 | struct bnx2x *bp = params->bp; | 2287 | struct bnx2x *bp = params->bp; |
2265 | u8 port = params->port; | 2288 | u16 cl37_val; |
2266 | u8 ext_phy_addr = ((params->ext_phy_config & | 2289 | u8 ext_phy_addr = ((params->ext_phy_config & |
2267 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | 2290 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> |
2268 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | 2291 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); |
2269 | u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); | 2292 | u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); |
2270 | 2293 | ||
2271 | /* Force KR or KX */ | 2294 | bnx2x_cl45_read(bp, params->port, |
2272 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2295 | ext_phy_type, |
2273 | MDIO_PMA_DEVAD, | 2296 | ext_phy_addr, |
2274 | MDIO_PMA_REG_CTRL, | 2297 | MDIO_AN_DEVAD, |
2275 | 0x2040); | 2298 | MDIO_AN_REG_CL37_FC_LD, &cl37_val); |
2276 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2299 | |
2277 | MDIO_PMA_DEVAD, | 2300 | cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; |
2278 | MDIO_PMA_REG_10G_CTRL2, | 2301 | /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ |
2279 | 0x000b); | 2302 | |
2280 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2303 | if ((vars->ieee_fc & |
2281 | MDIO_PMA_DEVAD, | 2304 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) == |
2282 | MDIO_PMA_REG_BCM_CTRL, | 2305 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) { |
2283 | 0x0000); | 2306 | cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC; |
2284 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2307 | } |
2308 | if ((vars->ieee_fc & | ||
2309 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == | ||
2310 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { | ||
2311 | cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; | ||
2312 | } | ||
2313 | if ((vars->ieee_fc & | ||
2314 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == | ||
2315 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) { | ||
2316 | cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; | ||
2317 | } | ||
2318 | DP(NETIF_MSG_LINK, | ||
2319 | "Ext phy AN advertize cl37 0x%x\n", cl37_val); | ||
2320 | |||
2321 | bnx2x_cl45_write(bp, params->port, | ||
2322 | ext_phy_type, | ||
2323 | ext_phy_addr, | ||
2285 | MDIO_AN_DEVAD, | 2324 | MDIO_AN_DEVAD, |
2286 | MDIO_AN_REG_CTRL, | 2325 | MDIO_AN_REG_CL37_FC_LD, cl37_val); |
2287 | 0x0000); | 2326 | msleep(500); |
2288 | } | 2327 | } |
2289 | 2328 | ||
2290 | static void bnx2x_ext_phy_set_pause(struct link_params *params, | 2329 | static void bnx2x_ext_phy_set_pause(struct link_params *params, |
@@ -2542,54 +2581,43 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
2542 | rx_alarm_ctrl_val = 0x400; | 2581 | rx_alarm_ctrl_val = 0x400; |
2543 | lasi_ctrl_val = 0x0004; | 2582 | lasi_ctrl_val = 0x0004; |
2544 | } else { | 2583 | } else { |
2545 | /* In 8073, port1 is directed through emac0 and | ||
2546 | * port0 is directed through emac1 | ||
2547 | */ | ||
2548 | rx_alarm_ctrl_val = (1<<2); | 2584 | rx_alarm_ctrl_val = (1<<2); |
2549 | /*lasi_ctrl_val = 0x0005;*/ | ||
2550 | lasi_ctrl_val = 0x0004; | 2585 | lasi_ctrl_val = 0x0004; |
2551 | } | 2586 | } |
2552 | 2587 | ||
2553 | /* Wait for soft reset to get cleared upto 1 sec */ | 2588 | /* enable LASI */ |
2554 | for (cnt = 0; cnt < 1000; cnt++) { | 2589 | bnx2x_cl45_write(bp, params->port, |
2555 | bnx2x_cl45_read(bp, params->port, | 2590 | ext_phy_type, |
2556 | ext_phy_type, | 2591 | ext_phy_addr, |
2557 | ext_phy_addr, | 2592 | MDIO_PMA_DEVAD, |
2558 | MDIO_PMA_DEVAD, | 2593 | MDIO_PMA_REG_RX_ALARM_CTRL, |
2559 | MDIO_PMA_REG_CTRL, | 2594 | rx_alarm_ctrl_val); |
2560 | &ctrl); | 2595 | |
2561 | if (!(ctrl & (1<<15))) | 2596 | bnx2x_cl45_write(bp, params->port, |
2562 | break; | 2597 | ext_phy_type, |
2563 | msleep(1); | 2598 | ext_phy_addr, |
2564 | } | 2599 | MDIO_PMA_DEVAD, |
2565 | DP(NETIF_MSG_LINK, | 2600 | MDIO_PMA_REG_LASI_CTRL, |
2566 | "807x control reg 0x%x (after %d ms)\n", | 2601 | lasi_ctrl_val); |
2567 | ctrl, cnt); | 2602 | |
2603 | bnx2x_8073_set_pause_cl37(params, vars); | ||
2568 | 2604 | ||
2569 | if (ext_phy_type == | 2605 | if (ext_phy_type == |
2570 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){ | 2606 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){ |
2571 | bnx2x_bcm8072_external_rom_boot(params); | 2607 | bnx2x_bcm8072_external_rom_boot(params); |
2572 | } else { | 2608 | } else { |
2573 | bnx2x_bcm8073_external_rom_boot(params); | 2609 | |
2574 | /* In case of 8073 with long xaui lines, | 2610 | /* In case of 8073 with long xaui lines, |
2575 | don't set the 8073 xaui low power*/ | 2611 | don't set the 8073 xaui low power*/ |
2576 | bnx2x_bcm8073_set_xaui_low_power_mode(params); | 2612 | bnx2x_bcm8073_set_xaui_low_power_mode(params); |
2577 | } | 2613 | } |
2578 | 2614 | ||
2579 | /* enable LASI */ | 2615 | bnx2x_cl45_read(bp, params->port, |
2580 | bnx2x_cl45_write(bp, params->port, | 2616 | ext_phy_type, |
2581 | ext_phy_type, | 2617 | ext_phy_addr, |
2582 | ext_phy_addr, | 2618 | MDIO_PMA_DEVAD, |
2583 | MDIO_PMA_DEVAD, | 2619 | 0xca13, |
2584 | MDIO_PMA_REG_RX_ALARM_CTRL, | 2620 | &tmp1); |
2585 | rx_alarm_ctrl_val); | ||
2586 | |||
2587 | bnx2x_cl45_write(bp, params->port, | ||
2588 | ext_phy_type, | ||
2589 | ext_phy_addr, | ||
2590 | MDIO_PMA_DEVAD, | ||
2591 | MDIO_PMA_REG_LASI_CTRL, | ||
2592 | lasi_ctrl_val); | ||
2593 | 2621 | ||
2594 | bnx2x_cl45_read(bp, params->port, | 2622 | bnx2x_cl45_read(bp, params->port, |
2595 | ext_phy_type, | 2623 | ext_phy_type, |
@@ -2603,12 +2631,21 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
2603 | /* If this is forced speed, set to KR or KX | 2631 | /* If this is forced speed, set to KR or KX |
2604 | * (all other are not supported) | 2632 | * (all other are not supported) |
2605 | */ | 2633 | */ |
2606 | if (!(params->req_line_speed == SPEED_AUTO_NEG)) { | 2634 | if (params->loopback_mode == LOOPBACK_EXT) { |
2607 | if (params->req_line_speed == SPEED_10000) { | 2635 | bnx2x_bcm807x_force_10G(params); |
2608 | bnx2x_bcm807x_force_10G(params); | 2636 | DP(NETIF_MSG_LINK, |
2609 | DP(NETIF_MSG_LINK, | 2637 | "Forced speed 10G on 807X\n"); |
2610 | "Forced speed 10G on 807X\n"); | 2638 | break; |
2611 | break; | 2639 | } else { |
2640 | bnx2x_cl45_write(bp, params->port, | ||
2641 | ext_phy_type, ext_phy_addr, | ||
2642 | MDIO_PMA_DEVAD, | ||
2643 | MDIO_PMA_REG_BCM_CTRL, | ||
2644 | 0x0002); | ||
2645 | } | ||
2646 | if (params->req_line_speed != SPEED_AUTO_NEG) { | ||
2647 | if (params->req_line_speed == SPEED_10000) { | ||
2648 | val = (1<<7); | ||
2612 | } else if (params->req_line_speed == | 2649 | } else if (params->req_line_speed == |
2613 | SPEED_2500) { | 2650 | SPEED_2500) { |
2614 | val = (1<<5); | 2651 | val = (1<<5); |
@@ -2623,11 +2660,14 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
2623 | PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) | 2660 | PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) |
2624 | val |= (1<<7); | 2661 | val |= (1<<7); |
2625 | 2662 | ||
2663 | /* Note that 2.5G works only when | ||
2664 | used with 1G advertisment */ | ||
2626 | if (params->speed_cap_mask & | 2665 | if (params->speed_cap_mask & |
2627 | PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) | 2666 | (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G | |
2667 | PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) | ||
2628 | val |= (1<<5); | 2668 | val |= (1<<5); |
2629 | DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val); | 2669 | DP(NETIF_MSG_LINK, |
2630 | /*val = ((1<<5)|(1<<7));*/ | 2670 | "807x autoneg val = 0x%x\n", val); |
2631 | } | 2671 | } |
2632 | 2672 | ||
2633 | bnx2x_cl45_write(bp, params->port, | 2673 | bnx2x_cl45_write(bp, params->port, |
@@ -2638,20 +2678,19 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
2638 | 2678 | ||
2639 | if (ext_phy_type == | 2679 | if (ext_phy_type == |
2640 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { | 2680 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { |
2641 | /* Disable 2.5Ghz */ | 2681 | |
2642 | bnx2x_cl45_read(bp, params->port, | 2682 | bnx2x_cl45_read(bp, params->port, |
2643 | ext_phy_type, | 2683 | ext_phy_type, |
2644 | ext_phy_addr, | 2684 | ext_phy_addr, |
2645 | MDIO_AN_DEVAD, | 2685 | MDIO_AN_DEVAD, |
2646 | 0x8329, &tmp1); | 2686 | 0x8329, &tmp1); |
2647 | /* SUPPORT_SPEED_CAPABILITY | 2687 | |
2648 | (Due to the nature of the link order, its not | 2688 | if (((params->speed_cap_mask & |
2649 | possible to enable 2.5G within the autoneg | 2689 | PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) && |
2650 | capabilities) | 2690 | (params->req_line_speed == |
2651 | if (params->speed_cap_mask & | 2691 | SPEED_AUTO_NEG)) || |
2652 | PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) | 2692 | (params->req_line_speed == |
2653 | */ | 2693 | SPEED_2500)) { |
2654 | if (params->req_line_speed == SPEED_2500) { | ||
2655 | u16 phy_ver; | 2694 | u16 phy_ver; |
2656 | /* Allow 2.5G for A1 and above */ | 2695 | /* Allow 2.5G for A1 and above */ |
2657 | bnx2x_cl45_read(bp, params->port, | 2696 | bnx2x_cl45_read(bp, params->port, |
@@ -2659,49 +2698,53 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
2659 | ext_phy_addr, | 2698 | ext_phy_addr, |
2660 | MDIO_PMA_DEVAD, | 2699 | MDIO_PMA_DEVAD, |
2661 | 0xc801, &phy_ver); | 2700 | 0xc801, &phy_ver); |
2662 | 2701 | DP(NETIF_MSG_LINK, "Add 2.5G\n"); | |
2663 | if (phy_ver > 0) | 2702 | if (phy_ver > 0) |
2664 | tmp1 |= 1; | 2703 | tmp1 |= 1; |
2665 | else | 2704 | else |
2666 | tmp1 &= 0xfffe; | 2705 | tmp1 &= 0xfffe; |
2667 | } | 2706 | } else { |
2668 | else | 2707 | DP(NETIF_MSG_LINK, "Disable 2.5G\n"); |
2669 | tmp1 &= 0xfffe; | 2708 | tmp1 &= 0xfffe; |
2709 | } | ||
2670 | 2710 | ||
2671 | bnx2x_cl45_write(bp, params->port, | 2711 | bnx2x_cl45_write(bp, params->port, |
2672 | ext_phy_type, | 2712 | ext_phy_type, |
2673 | ext_phy_addr, | 2713 | ext_phy_addr, |
2674 | MDIO_AN_DEVAD, | 2714 | MDIO_AN_DEVAD, |
2675 | 0x8329, tmp1); | 2715 | 0x8329, tmp1); |
2676 | } | 2716 | } |
2677 | /* Add support for CL37 (passive mode) I */ | 2717 | |
2678 | bnx2x_cl45_write(bp, params->port, | 2718 | /* Add support for CL37 (passive mode) II */ |
2719 | |||
2720 | bnx2x_cl45_read(bp, params->port, | ||
2679 | ext_phy_type, | 2721 | ext_phy_type, |
2680 | ext_phy_addr, | 2722 | ext_phy_addr, |
2681 | MDIO_AN_DEVAD, | 2723 | MDIO_AN_DEVAD, |
2682 | MDIO_AN_REG_CL37_FC_LD, 0x040c); | 2724 | MDIO_AN_REG_CL37_FC_LD, |
2683 | /* Add support for CL37 (passive mode) II */ | 2725 | &tmp1); |
2726 | |||
2684 | bnx2x_cl45_write(bp, params->port, | 2727 | bnx2x_cl45_write(bp, params->port, |
2685 | ext_phy_type, | 2728 | ext_phy_type, |
2686 | ext_phy_addr, | 2729 | ext_phy_addr, |
2687 | MDIO_AN_DEVAD, | 2730 | MDIO_AN_DEVAD, |
2688 | MDIO_AN_REG_CL37_FC_LD, 0x20); | 2731 | MDIO_AN_REG_CL37_FC_LD, (tmp1 | |
2732 | ((params->req_duplex == DUPLEX_FULL) ? | ||
2733 | 0x20 : 0x40))); | ||
2734 | |||
2689 | /* Add support for CL37 (passive mode) III */ | 2735 | /* Add support for CL37 (passive mode) III */ |
2690 | bnx2x_cl45_write(bp, params->port, | 2736 | bnx2x_cl45_write(bp, params->port, |
2691 | ext_phy_type, | 2737 | ext_phy_type, |
2692 | ext_phy_addr, | 2738 | ext_phy_addr, |
2693 | MDIO_AN_DEVAD, | 2739 | MDIO_AN_DEVAD, |
2694 | MDIO_AN_REG_CL37_AN, 0x1000); | 2740 | MDIO_AN_REG_CL37_AN, 0x1000); |
2695 | /* Restart autoneg */ | ||
2696 | msleep(500); | ||
2697 | 2741 | ||
2698 | if (ext_phy_type == | 2742 | if (ext_phy_type == |
2699 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { | 2743 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { |
2700 | 2744 | /* The SNR will improve about 2db by changing | |
2701 | /* The SNR will improve about 2db by changing the | ||
2702 | BW and FEE main tap. Rest commands are executed | 2745 | BW and FEE main tap. Rest commands are executed |
2703 | after link is up*/ | 2746 | after link is up*/ |
2704 | /* Change FFE main cursor to 5 in EDC register */ | 2747 | /*Change FFE main cursor to 5 in EDC register*/ |
2705 | if (bnx2x_8073_is_snr_needed(params)) | 2748 | if (bnx2x_8073_is_snr_needed(params)) |
2706 | bnx2x_cl45_write(bp, params->port, | 2749 | bnx2x_cl45_write(bp, params->port, |
2707 | ext_phy_type, | 2750 | ext_phy_type, |
@@ -2710,25 +2753,28 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
2710 | MDIO_PMA_REG_EDC_FFE_MAIN, | 2753 | MDIO_PMA_REG_EDC_FFE_MAIN, |
2711 | 0xFB0C); | 2754 | 0xFB0C); |
2712 | 2755 | ||
2713 | /* Enable FEC (Forware Error Correction) | 2756 | /* Enable FEC (Forware Error Correction) |
2714 | Request in the AN */ | 2757 | Request in the AN */ |
2715 | bnx2x_cl45_read(bp, params->port, | 2758 | bnx2x_cl45_read(bp, params->port, |
2716 | ext_phy_type, | 2759 | ext_phy_type, |
2717 | ext_phy_addr, | 2760 | ext_phy_addr, |
2718 | MDIO_AN_DEVAD, | 2761 | MDIO_AN_DEVAD, |
2719 | MDIO_AN_REG_ADV2, &tmp1); | 2762 | MDIO_AN_REG_ADV2, &tmp1); |
2720 | 2763 | ||
2721 | tmp1 |= (1<<15); | 2764 | tmp1 |= (1<<15); |
2765 | |||
2766 | bnx2x_cl45_write(bp, params->port, | ||
2767 | ext_phy_type, | ||
2768 | ext_phy_addr, | ||
2769 | MDIO_AN_DEVAD, | ||
2770 | MDIO_AN_REG_ADV2, tmp1); | ||
2722 | 2771 | ||
2723 | bnx2x_cl45_write(bp, params->port, | ||
2724 | ext_phy_type, | ||
2725 | ext_phy_addr, | ||
2726 | MDIO_AN_DEVAD, | ||
2727 | MDIO_AN_REG_ADV2, tmp1); | ||
2728 | } | 2772 | } |
2729 | 2773 | ||
2730 | bnx2x_ext_phy_set_pause(params, vars); | 2774 | bnx2x_ext_phy_set_pause(params, vars); |
2731 | 2775 | ||
2776 | /* Restart autoneg */ | ||
2777 | msleep(500); | ||
2732 | bnx2x_cl45_write(bp, params->port, | 2778 | bnx2x_cl45_write(bp, params->port, |
2733 | ext_phy_type, | 2779 | ext_phy_type, |
2734 | ext_phy_addr, | 2780 | ext_phy_addr, |
@@ -2910,6 +2956,8 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
2910 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: | 2956 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: |
2911 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: | 2957 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: |
2912 | { | 2958 | { |
2959 | u16 link_status = 0; | ||
2960 | u16 an1000_status = 0; | ||
2913 | if (ext_phy_type == | 2961 | if (ext_phy_type == |
2914 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) { | 2962 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) { |
2915 | bnx2x_cl45_read(bp, params->port, | 2963 | bnx2x_cl45_read(bp, params->port, |
@@ -2936,14 +2984,9 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
2936 | MDIO_PMA_DEVAD, | 2984 | MDIO_PMA_DEVAD, |
2937 | MDIO_PMA_REG_LASI_STATUS, &val1); | 2985 | MDIO_PMA_REG_LASI_STATUS, &val1); |
2938 | 2986 | ||
2939 | bnx2x_cl45_read(bp, params->port, | ||
2940 | ext_phy_type, | ||
2941 | ext_phy_addr, | ||
2942 | MDIO_PMA_DEVAD, | ||
2943 | MDIO_PMA_REG_LASI_STATUS, &val2); | ||
2944 | DP(NETIF_MSG_LINK, | 2987 | DP(NETIF_MSG_LINK, |
2945 | "8703 LASI status 0x%x->0x%x\n", | 2988 | "8703 LASI status 0x%x\n", |
2946 | val1, val2); | 2989 | val1); |
2947 | } | 2990 | } |
2948 | 2991 | ||
2949 | /* clear the interrupt LASI status register */ | 2992 | /* clear the interrupt LASI status register */ |
@@ -2959,20 +3002,23 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
2959 | MDIO_PCS_REG_STATUS, &val1); | 3002 | MDIO_PCS_REG_STATUS, &val1); |
2960 | DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", | 3003 | DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", |
2961 | val2, val1); | 3004 | val2, val1); |
2962 | /* Check the LASI */ | 3005 | /* Clear MSG-OUT */ |
2963 | bnx2x_cl45_read(bp, params->port, | 3006 | bnx2x_cl45_read(bp, params->port, |
2964 | ext_phy_type, | 3007 | ext_phy_type, |
2965 | ext_phy_addr, | 3008 | ext_phy_addr, |
2966 | MDIO_PMA_DEVAD, | 3009 | MDIO_PMA_DEVAD, |
2967 | MDIO_PMA_REG_RX_ALARM, &val2); | 3010 | 0xca13, |
3011 | &val1); | ||
3012 | |||
3013 | /* Check the LASI */ | ||
2968 | bnx2x_cl45_read(bp, params->port, | 3014 | bnx2x_cl45_read(bp, params->port, |
2969 | ext_phy_type, | 3015 | ext_phy_type, |
2970 | ext_phy_addr, | 3016 | ext_phy_addr, |
2971 | MDIO_PMA_DEVAD, | 3017 | MDIO_PMA_DEVAD, |
2972 | MDIO_PMA_REG_RX_ALARM, | 3018 | MDIO_PMA_REG_RX_ALARM, &val2); |
2973 | &val1); | 3019 | |
2974 | DP(NETIF_MSG_LINK, "KR 0x9003 0x%x->0x%x\n", | 3020 | DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2); |
2975 | val2, val1); | 3021 | |
2976 | /* Check the link status */ | 3022 | /* Check the link status */ |
2977 | bnx2x_cl45_read(bp, params->port, | 3023 | bnx2x_cl45_read(bp, params->port, |
2978 | ext_phy_type, | 3024 | ext_phy_type, |
@@ -2995,29 +3041,29 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
2995 | DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1); | 3041 | DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1); |
2996 | if (ext_phy_type == | 3042 | if (ext_phy_type == |
2997 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { | 3043 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { |
2998 | u16 an1000_status = 0; | 3044 | |
2999 | if (ext_phy_link_up && | 3045 | if (ext_phy_link_up && |
3000 | ( | 3046 | ((params->req_line_speed != |
3001 | (params->req_line_speed != SPEED_10000) | 3047 | SPEED_10000))) { |
3002 | )) { | ||
3003 | if (bnx2x_bcm8073_xaui_wa(params) | 3048 | if (bnx2x_bcm8073_xaui_wa(params) |
3004 | != 0) { | 3049 | != 0) { |
3005 | ext_phy_link_up = 0; | 3050 | ext_phy_link_up = 0; |
3006 | break; | 3051 | break; |
3007 | } | 3052 | } |
3008 | bnx2x_cl45_read(bp, params->port, | 3053 | } |
3054 | bnx2x_cl45_read(bp, params->port, | ||
3009 | ext_phy_type, | 3055 | ext_phy_type, |
3010 | ext_phy_addr, | 3056 | ext_phy_addr, |
3011 | MDIO_XS_DEVAD, | 3057 | MDIO_AN_DEVAD, |
3012 | 0x8304, | 3058 | 0x8304, |
3013 | &an1000_status); | 3059 | &an1000_status); |
3014 | bnx2x_cl45_read(bp, params->port, | 3060 | bnx2x_cl45_read(bp, params->port, |
3015 | ext_phy_type, | 3061 | ext_phy_type, |
3016 | ext_phy_addr, | 3062 | ext_phy_addr, |
3017 | MDIO_XS_DEVAD, | 3063 | MDIO_AN_DEVAD, |
3018 | 0x8304, | 3064 | 0x8304, |
3019 | &an1000_status); | 3065 | &an1000_status); |
3020 | } | 3066 | |
3021 | /* Check the link status on 1.1.2 */ | 3067 | /* Check the link status on 1.1.2 */ |
3022 | bnx2x_cl45_read(bp, params->port, | 3068 | bnx2x_cl45_read(bp, params->port, |
3023 | ext_phy_type, | 3069 | ext_phy_type, |
@@ -3033,8 +3079,8 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
3033 | "an_link_status=0x%x\n", | 3079 | "an_link_status=0x%x\n", |
3034 | val2, val1, an1000_status); | 3080 | val2, val1, an1000_status); |
3035 | 3081 | ||
3036 | ext_phy_link_up = (((val1 & 4) == 4) || | 3082 | ext_phy_link_up = (((val1 & 4) == 4) || |
3037 | (an1000_status & (1<<1))); | 3083 | (an1000_status & (1<<1))); |
3038 | if (ext_phy_link_up && | 3084 | if (ext_phy_link_up && |
3039 | bnx2x_8073_is_snr_needed(params)) { | 3085 | bnx2x_8073_is_snr_needed(params)) { |
3040 | /* The SNR will improve about 2dbby | 3086 | /* The SNR will improve about 2dbby |
@@ -3058,8 +3104,74 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
3058 | MDIO_PMA_REG_CDR_BANDWIDTH, | 3104 | MDIO_PMA_REG_CDR_BANDWIDTH, |
3059 | 0x0333); | 3105 | 0x0333); |
3060 | 3106 | ||
3107 | |||
3108 | } | ||
3109 | bnx2x_cl45_read(bp, params->port, | ||
3110 | ext_phy_type, | ||
3111 | ext_phy_addr, | ||
3112 | MDIO_PMA_DEVAD, | ||
3113 | 0xc820, | ||
3114 | &link_status); | ||
3115 | |||
3116 | /* Bits 0..2 --> speed detected, | ||
3117 | bits 13..15--> link is down */ | ||
3118 | if ((link_status & (1<<2)) && | ||
3119 | (!(link_status & (1<<15)))) { | ||
3120 | ext_phy_link_up = 1; | ||
3121 | vars->line_speed = SPEED_10000; | ||
3122 | DP(NETIF_MSG_LINK, | ||
3123 | "port %x: External link" | ||
3124 | " up in 10G\n", params->port); | ||
3125 | } else if ((link_status & (1<<1)) && | ||
3126 | (!(link_status & (1<<14)))) { | ||
3127 | ext_phy_link_up = 1; | ||
3128 | vars->line_speed = SPEED_2500; | ||
3129 | DP(NETIF_MSG_LINK, | ||
3130 | "port %x: External link" | ||
3131 | " up in 2.5G\n", params->port); | ||
3132 | } else if ((link_status & (1<<0)) && | ||
3133 | (!(link_status & (1<<13)))) { | ||
3134 | ext_phy_link_up = 1; | ||
3135 | vars->line_speed = SPEED_1000; | ||
3136 | DP(NETIF_MSG_LINK, | ||
3137 | "port %x: External link" | ||
3138 | " up in 1G\n", params->port); | ||
3139 | } else { | ||
3140 | ext_phy_link_up = 0; | ||
3141 | DP(NETIF_MSG_LINK, | ||
3142 | "port %x: External link" | ||
3143 | " is down\n", params->port); | ||
3144 | } | ||
3145 | } else { | ||
3146 | /* See if 1G link is up for the 8072 */ | ||
3147 | bnx2x_cl45_read(bp, params->port, | ||
3148 | ext_phy_type, | ||
3149 | ext_phy_addr, | ||
3150 | MDIO_AN_DEVAD, | ||
3151 | 0x8304, | ||
3152 | &an1000_status); | ||
3153 | bnx2x_cl45_read(bp, params->port, | ||
3154 | ext_phy_type, | ||
3155 | ext_phy_addr, | ||
3156 | MDIO_AN_DEVAD, | ||
3157 | 0x8304, | ||
3158 | &an1000_status); | ||
3159 | if (an1000_status & (1<<1)) { | ||
3160 | ext_phy_link_up = 1; | ||
3161 | vars->line_speed = SPEED_1000; | ||
3162 | DP(NETIF_MSG_LINK, | ||
3163 | "port %x: External link" | ||
3164 | " up in 1G\n", params->port); | ||
3165 | } else if (ext_phy_link_up) { | ||
3166 | ext_phy_link_up = 1; | ||
3167 | vars->line_speed = SPEED_10000; | ||
3168 | DP(NETIF_MSG_LINK, | ||
3169 | "port %x: External link" | ||
3170 | " up in 10G\n", params->port); | ||
3061 | } | 3171 | } |
3062 | } | 3172 | } |
3173 | |||
3174 | |||
3063 | break; | 3175 | break; |
3064 | } | 3176 | } |
3065 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: | 3177 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: |
@@ -4203,6 +4315,154 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
4203 | return rc; | 4315 | return rc; |
4204 | } | 4316 | } |
4205 | 4317 | ||
4318 | static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) | ||
4319 | { | ||
4320 | u8 ext_phy_addr[PORT_MAX]; | ||
4321 | u16 val; | ||
4322 | s8 port; | ||
4323 | |||
4324 | /* PART1 - Reset both phys */ | ||
4325 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { | ||
4326 | /* Extract the ext phy address for the port */ | ||
4327 | u32 ext_phy_config = REG_RD(bp, shmem_base + | ||
4328 | offsetof(struct shmem_region, | ||
4329 | dev_info.port_hw_config[port].external_phy_config)); | ||
4330 | |||
4331 | /* disable attentions */ | ||
4332 | bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, | ||
4333 | (NIG_MASK_XGXS0_LINK_STATUS | | ||
4334 | NIG_MASK_XGXS0_LINK10G | | ||
4335 | NIG_MASK_SERDES0_LINK_STATUS | | ||
4336 | NIG_MASK_MI_INT)); | ||
4337 | |||
4338 | ext_phy_addr[port] = | ||
4339 | ((ext_phy_config & | ||
4340 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | ||
4341 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | ||
4342 | |||
4343 | /* Need to take the phy out of low power mode in order | ||
4344 | to write to access its registers */ | ||
4345 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, | ||
4346 | MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); | ||
4347 | |||
4348 | /* Reset the phy */ | ||
4349 | bnx2x_cl45_write(bp, port, | ||
4350 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
4351 | ext_phy_addr[port], | ||
4352 | MDIO_PMA_DEVAD, | ||
4353 | MDIO_PMA_REG_CTRL, | ||
4354 | 1<<15); | ||
4355 | } | ||
4356 | |||
4357 | /* Add delay of 150ms after reset */ | ||
4358 | msleep(150); | ||
4359 | |||
4360 | /* PART2 - Download firmware to both phys */ | ||
4361 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { | ||
4362 | u16 fw_ver1; | ||
4363 | |||
4364 | bnx2x_bcm8073_external_rom_boot(bp, port, | ||
4365 | ext_phy_addr[port]); | ||
4366 | |||
4367 | bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
4368 | ext_phy_addr[port], | ||
4369 | MDIO_PMA_DEVAD, | ||
4370 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); | ||
4371 | if (fw_ver1 == 0) { | ||
4372 | DP(NETIF_MSG_LINK, | ||
4373 | "bnx2x_8073_common_init_phy port %x " | ||
4374 | "fw Download failed\n", port); | ||
4375 | return -EINVAL; | ||
4376 | } | ||
4377 | |||
4378 | /* Only set bit 10 = 1 (Tx power down) */ | ||
4379 | bnx2x_cl45_read(bp, port, | ||
4380 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
4381 | ext_phy_addr[port], | ||
4382 | MDIO_PMA_DEVAD, | ||
4383 | MDIO_PMA_REG_TX_POWER_DOWN, &val); | ||
4384 | |||
4385 | /* Phase1 of TX_POWER_DOWN reset */ | ||
4386 | bnx2x_cl45_write(bp, port, | ||
4387 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
4388 | ext_phy_addr[port], | ||
4389 | MDIO_PMA_DEVAD, | ||
4390 | MDIO_PMA_REG_TX_POWER_DOWN, | ||
4391 | (val | 1<<10)); | ||
4392 | } | ||
4393 | |||
4394 | /* Toggle Transmitter: Power down and then up with 600ms | ||
4395 | delay between */ | ||
4396 | msleep(600); | ||
4397 | |||
4398 | /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */ | ||
4399 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { | ||
4400 | /* Phase2 of POWER_DOWN_RESET*/ | ||
4401 | /* Release bit 10 (Release Tx power down) */ | ||
4402 | bnx2x_cl45_read(bp, port, | ||
4403 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
4404 | ext_phy_addr[port], | ||
4405 | MDIO_PMA_DEVAD, | ||
4406 | MDIO_PMA_REG_TX_POWER_DOWN, &val); | ||
4407 | |||
4408 | bnx2x_cl45_write(bp, port, | ||
4409 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
4410 | ext_phy_addr[port], | ||
4411 | MDIO_PMA_DEVAD, | ||
4412 | MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10)))); | ||
4413 | msleep(15); | ||
4414 | |||
4415 | /* Read modify write the SPI-ROM version select register */ | ||
4416 | bnx2x_cl45_read(bp, port, | ||
4417 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
4418 | ext_phy_addr[port], | ||
4419 | MDIO_PMA_DEVAD, | ||
4420 | MDIO_PMA_REG_EDC_FFE_MAIN, &val); | ||
4421 | bnx2x_cl45_write(bp, port, | ||
4422 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
4423 | ext_phy_addr[port], | ||
4424 | MDIO_PMA_DEVAD, | ||
4425 | MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12))); | ||
4426 | |||
4427 | /* set GPIO2 back to LOW */ | ||
4428 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, | ||
4429 | MISC_REGISTERS_GPIO_OUTPUT_LOW, port); | ||
4430 | } | ||
4431 | return 0; | ||
4432 | |||
4433 | } | ||
4434 | |||
4435 | u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base) | ||
4436 | { | ||
4437 | u8 rc = 0; | ||
4438 | u32 ext_phy_type; | ||
4439 | |||
4440 | DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n"); | ||
4441 | |||
4442 | /* Read the ext_phy_type for arbitrary port(0) */ | ||
4443 | ext_phy_type = XGXS_EXT_PHY_TYPE( | ||
4444 | REG_RD(bp, shmem_base + | ||
4445 | offsetof(struct shmem_region, | ||
4446 | dev_info.port_hw_config[0].external_phy_config))); | ||
4447 | |||
4448 | switch (ext_phy_type) { | ||
4449 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: | ||
4450 | { | ||
4451 | rc = bnx2x_8073_common_init_phy(bp, shmem_base); | ||
4452 | break; | ||
4453 | } | ||
4454 | default: | ||
4455 | DP(NETIF_MSG_LINK, | ||
4456 | "bnx2x_common_init_phy: ext_phy 0x%x not required\n", | ||
4457 | ext_phy_type); | ||
4458 | break; | ||
4459 | } | ||
4460 | |||
4461 | return rc; | ||
4462 | } | ||
4463 | |||
4464 | |||
4465 | |||
4206 | static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr) | 4466 | static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr) |
4207 | { | 4467 | { |
4208 | u16 val, cnt; | 4468 | u16 val, cnt; |
diff --git a/drivers/net/bnx2x_link.h b/drivers/net/bnx2x_link.h index b222552b868d..80c945ca3a51 100644 --- a/drivers/net/bnx2x_link.h +++ b/drivers/net/bnx2x_link.h | |||
@@ -55,6 +55,7 @@ struct link_params { | |||
55 | #define LOOPBACK_BMAC 2 | 55 | #define LOOPBACK_BMAC 2 |
56 | #define LOOPBACK_XGXS_10 3 | 56 | #define LOOPBACK_XGXS_10 3 |
57 | #define LOOPBACK_EXT_PHY 4 | 57 | #define LOOPBACK_EXT_PHY 4 |
58 | #define LOOPBACK_EXT 5 | ||
58 | 59 | ||
59 | u16 req_duplex; | 60 | u16 req_duplex; |
60 | u16 req_flow_ctrl; | 61 | u16 req_flow_ctrl; |
@@ -166,5 +167,7 @@ u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config, | |||
166 | otherwise link is down*/ | 167 | otherwise link is down*/ |
167 | u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars); | 168 | u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars); |
168 | 169 | ||
170 | /* One-time initialization for external phy after power up */ | ||
171 | u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base); | ||
169 | 172 | ||
170 | #endif /* BNX2X_LINK_H */ | 173 | #endif /* BNX2X_LINK_H */ |
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 85ea799a0539..594b08aac93b 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c | |||
@@ -5377,6 +5377,13 @@ static int bnx2x_init_common(struct bnx2x *bp) | |||
5377 | ((u32 *)&tmp)[1]); | 5377 | ((u32 *)&tmp)[1]); |
5378 | } | 5378 | } |
5379 | 5379 | ||
5380 | if (!BP_NOMCP(bp)) { | ||
5381 | bnx2x_acquire_phy_lock(bp); | ||
5382 | bnx2x_common_init_phy(bp, bp->common.shmem_base); | ||
5383 | bnx2x_release_phy_lock(bp); | ||
5384 | } else | ||
5385 | BNX2X_ERR("Bootcode is missing - can not initialize link\n"); | ||
5386 | |||
5380 | return 0; | 5387 | return 0; |
5381 | } | 5388 | } |
5382 | 5389 | ||