diff options
Diffstat (limited to 'drivers/net/bnx2x_link.c')
| -rw-r--r-- | drivers/net/bnx2x_link.c | 576 |
1 files changed, 418 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; |
