aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x_link.c
diff options
context:
space:
mode:
authorYaniv Rosner <yanivr@broadcom.com>2008-08-13 18:57:28 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-13 19:05:33 -0400
commit6bbca910e621d82b3ca93a99af9b59eb1ff3cbcd (patch)
tree1332b0eed56b157e442dc518fe8b4a63d6c1860a /drivers/net/bnx2x_link.c
parent17de50b7f71d176375e9d4d67ffce42482e5515f (diff)
bnx2x: 8073 PHY changes
8073 PHY changes The initial support we had for this PHY needs some serious changing. The major change is that this PHY should be initialized only when the first function is loaded and not for each function. The official SPI-ROM of this PHY was released and it requires some changes in the initialization code as well 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>
Diffstat (limited to 'drivers/net/bnx2x_link.c')
-rw-r--r--drivers/net/bnx2x_link.c576
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
2124static void bnx2x_bcm8073_external_rom_boot(struct link_params *params) 2124static 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
2190static 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
2197static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params) 2217static 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}
2262static void bnx2x_bcm807x_force_10G(struct link_params *params) 2282
2283static 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
2290static void bnx2x_ext_phy_set_pause(struct link_params *params, 2329static 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
4318static 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
4435u8 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
4206static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr) 4466static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
4207{ 4467{
4208 u16 val, cnt; 4468 u16 val, cnt;