diff options
Diffstat (limited to 'drivers/net/bnx2x_link.c')
-rw-r--r-- | drivers/net/bnx2x_link.c | 1258 |
1 files changed, 805 insertions, 453 deletions
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c index ff2743db10d9..8b92c6ad0759 100644 --- a/drivers/net/bnx2x_link.c +++ b/drivers/net/bnx2x_link.c | |||
@@ -31,17 +31,16 @@ | |||
31 | 31 | ||
32 | /********************************************************/ | 32 | /********************************************************/ |
33 | #define SUPPORT_CL73 0 /* Currently no */ | 33 | #define SUPPORT_CL73 0 /* Currently no */ |
34 | #define ETH_HLEN 14 | 34 | #define ETH_HLEN 14 |
35 | #define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/ | 35 | #define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/ |
36 | #define ETH_MIN_PACKET_SIZE 60 | 36 | #define ETH_MIN_PACKET_SIZE 60 |
37 | #define ETH_MAX_PACKET_SIZE 1500 | 37 | #define ETH_MAX_PACKET_SIZE 1500 |
38 | #define ETH_MAX_JUMBO_PACKET_SIZE 9600 | 38 | #define ETH_MAX_JUMBO_PACKET_SIZE 9600 |
39 | #define MDIO_ACCESS_TIMEOUT 1000 | 39 | #define MDIO_ACCESS_TIMEOUT 1000 |
40 | #define BMAC_CONTROL_RX_ENABLE 2 | 40 | #define BMAC_CONTROL_RX_ENABLE 2 |
41 | #define MAX_MTU_SIZE 5000 | ||
42 | 41 | ||
43 | /***********************************************************/ | 42 | /***********************************************************/ |
44 | /* Shortcut definitions */ | 43 | /* Shortcut definitions */ |
45 | /***********************************************************/ | 44 | /***********************************************************/ |
46 | 45 | ||
47 | #define NIG_STATUS_XGXS0_LINK10G \ | 46 | #define NIG_STATUS_XGXS0_LINK10G \ |
@@ -80,12 +79,12 @@ | |||
80 | 79 | ||
81 | #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37 | 80 | #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37 |
82 | #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73 | 81 | #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73 |
83 | #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM | 82 | #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM |
84 | #define AUTONEG_PARALLEL \ | 83 | #define AUTONEG_PARALLEL \ |
85 | SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION | 84 | SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION |
86 | #define AUTONEG_SGMII_FIBER_AUTODET \ | 85 | #define AUTONEG_SGMII_FIBER_AUTODET \ |
87 | SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT | 86 | SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT |
88 | #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY | 87 | #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY |
89 | 88 | ||
90 | #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \ | 89 | #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \ |
91 | MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE | 90 | MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE |
@@ -202,11 +201,10 @@ static void bnx2x_emac_init(struct link_params *params, | |||
202 | /* init emac - use read-modify-write */ | 201 | /* init emac - use read-modify-write */ |
203 | /* self clear reset */ | 202 | /* self clear reset */ |
204 | val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); | 203 | val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); |
205 | EMAC_WR(EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET)); | 204 | EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET)); |
206 | 205 | ||
207 | timeout = 200; | 206 | timeout = 200; |
208 | do | 207 | do { |
209 | { | ||
210 | val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); | 208 | val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); |
211 | DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val); | 209 | DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val); |
212 | if (!timeout) { | 210 | if (!timeout) { |
@@ -214,18 +212,18 @@ static void bnx2x_emac_init(struct link_params *params, | |||
214 | return; | 212 | return; |
215 | } | 213 | } |
216 | timeout--; | 214 | timeout--; |
217 | }while (val & EMAC_MODE_RESET); | 215 | } while (val & EMAC_MODE_RESET); |
218 | 216 | ||
219 | /* Set mac address */ | 217 | /* Set mac address */ |
220 | val = ((params->mac_addr[0] << 8) | | 218 | val = ((params->mac_addr[0] << 8) | |
221 | params->mac_addr[1]); | 219 | params->mac_addr[1]); |
222 | EMAC_WR(EMAC_REG_EMAC_MAC_MATCH, val); | 220 | EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val); |
223 | 221 | ||
224 | val = ((params->mac_addr[2] << 24) | | 222 | val = ((params->mac_addr[2] << 24) | |
225 | (params->mac_addr[3] << 16) | | 223 | (params->mac_addr[3] << 16) | |
226 | (params->mac_addr[4] << 8) | | 224 | (params->mac_addr[4] << 8) | |
227 | params->mac_addr[5]); | 225 | params->mac_addr[5]); |
228 | EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val); | 226 | EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val); |
229 | } | 227 | } |
230 | 228 | ||
231 | static u8 bnx2x_emac_enable(struct link_params *params, | 229 | static u8 bnx2x_emac_enable(struct link_params *params, |
@@ -286,7 +284,7 @@ static u8 bnx2x_emac_enable(struct link_params *params, | |||
286 | if (CHIP_REV_IS_SLOW(bp)) { | 284 | if (CHIP_REV_IS_SLOW(bp)) { |
287 | /* config GMII mode */ | 285 | /* config GMII mode */ |
288 | val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); | 286 | val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); |
289 | EMAC_WR(EMAC_REG_EMAC_MODE, | 287 | EMAC_WR(bp, EMAC_REG_EMAC_MODE, |
290 | (val | EMAC_MODE_PORT_GMII)); | 288 | (val | EMAC_MODE_PORT_GMII)); |
291 | } else { /* ASIC */ | 289 | } else { /* ASIC */ |
292 | /* pause enable/disable */ | 290 | /* pause enable/disable */ |
@@ -298,17 +296,19 @@ static u8 bnx2x_emac_enable(struct link_params *params, | |||
298 | EMAC_RX_MODE_FLOW_EN); | 296 | EMAC_RX_MODE_FLOW_EN); |
299 | 297 | ||
300 | bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE, | 298 | bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE, |
301 | EMAC_TX_MODE_EXT_PAUSE_EN); | 299 | (EMAC_TX_MODE_EXT_PAUSE_EN | |
300 | EMAC_TX_MODE_FLOW_EN)); | ||
302 | if (vars->flow_ctrl & FLOW_CTRL_TX) | 301 | if (vars->flow_ctrl & FLOW_CTRL_TX) |
303 | bnx2x_bits_en(bp, emac_base + | 302 | bnx2x_bits_en(bp, emac_base + |
304 | EMAC_REG_EMAC_TX_MODE, | 303 | EMAC_REG_EMAC_TX_MODE, |
305 | EMAC_TX_MODE_EXT_PAUSE_EN); | 304 | (EMAC_TX_MODE_EXT_PAUSE_EN | |
305 | EMAC_TX_MODE_FLOW_EN)); | ||
306 | } | 306 | } |
307 | 307 | ||
308 | /* KEEP_VLAN_TAG, promiscuous */ | 308 | /* KEEP_VLAN_TAG, promiscuous */ |
309 | val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE); | 309 | val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE); |
310 | val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS; | 310 | val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS; |
311 | EMAC_WR(EMAC_REG_EMAC_RX_MODE, val); | 311 | EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val); |
312 | 312 | ||
313 | /* Set Loopback */ | 313 | /* Set Loopback */ |
314 | val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); | 314 | val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); |
@@ -316,10 +316,10 @@ static u8 bnx2x_emac_enable(struct link_params *params, | |||
316 | val |= 0x810; | 316 | val |= 0x810; |
317 | else | 317 | else |
318 | val &= ~0x810; | 318 | val &= ~0x810; |
319 | EMAC_WR(EMAC_REG_EMAC_MODE, val); | 319 | EMAC_WR(bp, EMAC_REG_EMAC_MODE, val); |
320 | 320 | ||
321 | /* enable emac for jumbo packets */ | 321 | /* enable emac for jumbo packets */ |
322 | EMAC_WR(EMAC_REG_EMAC_RX_MTU_SIZE, | 322 | EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE, |
323 | (EMAC_RX_MTU_SIZE_JUMBO_ENA | | 323 | (EMAC_RX_MTU_SIZE_JUMBO_ENA | |
324 | (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD))); | 324 | (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD))); |
325 | 325 | ||
@@ -591,9 +591,9 @@ void bnx2x_link_status_update(struct link_params *params, | |||
591 | vars->flow_ctrl &= ~FLOW_CTRL_RX; | 591 | vars->flow_ctrl &= ~FLOW_CTRL_RX; |
592 | 592 | ||
593 | if (vars->phy_flags & PHY_XGXS_FLAG) { | 593 | if (vars->phy_flags & PHY_XGXS_FLAG) { |
594 | if (params->req_line_speed && | 594 | if (vars->line_speed && |
595 | ((params->req_line_speed == SPEED_10) || | 595 | ((vars->line_speed == SPEED_10) || |
596 | (params->req_line_speed == SPEED_100))) { | 596 | (vars->line_speed == SPEED_100))) { |
597 | vars->phy_flags |= PHY_SGMII_FLAG; | 597 | vars->phy_flags |= PHY_SGMII_FLAG; |
598 | } else { | 598 | } else { |
599 | vars->phy_flags &= ~PHY_SGMII_FLAG; | 599 | vars->phy_flags &= ~PHY_SGMII_FLAG; |
@@ -645,7 +645,7 @@ static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port) | |||
645 | u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM : | 645 | u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM : |
646 | NIG_REG_INGRESS_BMAC0_MEM; | 646 | NIG_REG_INGRESS_BMAC0_MEM; |
647 | u32 wb_data[2]; | 647 | u32 wb_data[2]; |
648 | u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4); | 648 | u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4); |
649 | 649 | ||
650 | /* Only if the bmac is out of reset */ | 650 | /* Only if the bmac is out of reset */ |
651 | if (REG_RD(bp, MISC_REG_RESET_REG_2) & | 651 | if (REG_RD(bp, MISC_REG_RESET_REG_2) & |
@@ -670,7 +670,6 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, | |||
670 | u8 port = params->port; | 670 | u8 port = params->port; |
671 | u32 init_crd, crd; | 671 | u32 init_crd, crd; |
672 | u32 count = 1000; | 672 | u32 count = 1000; |
673 | u32 pause = 0; | ||
674 | 673 | ||
675 | /* disable port */ | 674 | /* disable port */ |
676 | REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1); | 675 | REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1); |
@@ -693,33 +692,25 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, | |||
693 | return -EINVAL; | 692 | return -EINVAL; |
694 | } | 693 | } |
695 | 694 | ||
696 | if (flow_ctrl & FLOW_CTRL_RX) | 695 | if (flow_ctrl & FLOW_CTRL_RX || |
697 | pause = 1; | 696 | line_speed == SPEED_10 || |
698 | REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, pause); | 697 | line_speed == SPEED_100 || |
699 | if (pause) { | 698 | line_speed == SPEED_1000 || |
699 | line_speed == SPEED_2500) { | ||
700 | REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1); | ||
700 | /* update threshold */ | 701 | /* update threshold */ |
701 | REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0); | 702 | REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0); |
702 | /* update init credit */ | 703 | /* update init credit */ |
703 | init_crd = 778; /* (800-18-4) */ | 704 | init_crd = 778; /* (800-18-4) */ |
704 | 705 | ||
705 | } else { | 706 | } else { |
706 | u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE + | 707 | u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE + |
707 | ETH_OVREHEAD)/16; | 708 | ETH_OVREHEAD)/16; |
708 | 709 | REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0); | |
709 | /* update threshold */ | 710 | /* update threshold */ |
710 | REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh); | 711 | REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh); |
711 | /* update init credit */ | 712 | /* update init credit */ |
712 | switch (line_speed) { | 713 | switch (line_speed) { |
713 | case SPEED_10: | ||
714 | case SPEED_100: | ||
715 | case SPEED_1000: | ||
716 | init_crd = thresh + 55 - 22; | ||
717 | break; | ||
718 | |||
719 | case SPEED_2500: | ||
720 | init_crd = thresh + 138 - 22; | ||
721 | break; | ||
722 | |||
723 | case SPEED_10000: | 714 | case SPEED_10000: |
724 | init_crd = thresh + 553 - 22; | 715 | init_crd = thresh + 553 - 22; |
725 | break; | 716 | break; |
@@ -764,10 +755,10 @@ static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port) | |||
764 | emac_base = GRCBASE_EMAC0; | 755 | emac_base = GRCBASE_EMAC0; |
765 | break; | 756 | break; |
766 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: | 757 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: |
767 | emac_base = (port) ? GRCBASE_EMAC0: GRCBASE_EMAC1; | 758 | emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1; |
768 | break; | 759 | break; |
769 | default: | 760 | default: |
770 | emac_base = (port) ? GRCBASE_EMAC1: GRCBASE_EMAC0; | 761 | emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; |
771 | break; | 762 | break; |
772 | } | 763 | } |
773 | return emac_base; | 764 | return emac_base; |
@@ -1044,7 +1035,7 @@ static void bnx2x_set_swap_lanes(struct link_params *params) | |||
1044 | } | 1035 | } |
1045 | 1036 | ||
1046 | static void bnx2x_set_parallel_detection(struct link_params *params, | 1037 | static void bnx2x_set_parallel_detection(struct link_params *params, |
1047 | u8 phy_flags) | 1038 | u8 phy_flags) |
1048 | { | 1039 | { |
1049 | struct bnx2x *bp = params->bp; | 1040 | struct bnx2x *bp = params->bp; |
1050 | u16 control2; | 1041 | u16 control2; |
@@ -1114,7 +1105,7 @@ static void bnx2x_set_autoneg(struct link_params *params, | |||
1114 | MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); | 1105 | MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); |
1115 | 1106 | ||
1116 | /* CL37 Autoneg Enabled */ | 1107 | /* CL37 Autoneg Enabled */ |
1117 | if (params->req_line_speed == SPEED_AUTO_NEG) | 1108 | if (vars->line_speed == SPEED_AUTO_NEG) |
1118 | reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN; | 1109 | reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN; |
1119 | else /* CL37 Autoneg Disabled */ | 1110 | else /* CL37 Autoneg Disabled */ |
1120 | reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | | 1111 | reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | |
@@ -1132,7 +1123,7 @@ static void bnx2x_set_autoneg(struct link_params *params, | |||
1132 | MDIO_REG_BANK_SERDES_DIGITAL, | 1123 | MDIO_REG_BANK_SERDES_DIGITAL, |
1133 | MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val); | 1124 | MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val); |
1134 | reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN; | 1125 | reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN; |
1135 | if (params->req_line_speed == SPEED_AUTO_NEG) | 1126 | if (vars->line_speed == SPEED_AUTO_NEG) |
1136 | reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET; | 1127 | reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET; |
1137 | else | 1128 | else |
1138 | reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET; | 1129 | reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET; |
@@ -1148,7 +1139,7 @@ static void bnx2x_set_autoneg(struct link_params *params, | |||
1148 | MDIO_REG_BANK_BAM_NEXT_PAGE, | 1139 | MDIO_REG_BANK_BAM_NEXT_PAGE, |
1149 | MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, | 1140 | MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, |
1150 | ®_val); | 1141 | ®_val); |
1151 | if (params->req_line_speed == SPEED_AUTO_NEG) { | 1142 | if (vars->line_speed == SPEED_AUTO_NEG) { |
1152 | /* Enable BAM aneg Mode and TetonII aneg Mode */ | 1143 | /* Enable BAM aneg Mode and TetonII aneg Mode */ |
1153 | reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE | | 1144 | reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE | |
1154 | MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN); | 1145 | MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN); |
@@ -1164,7 +1155,7 @@ static void bnx2x_set_autoneg(struct link_params *params, | |||
1164 | reg_val); | 1155 | reg_val); |
1165 | 1156 | ||
1166 | /* Enable Clause 73 Aneg */ | 1157 | /* Enable Clause 73 Aneg */ |
1167 | if ((params->req_line_speed == SPEED_AUTO_NEG) && | 1158 | if ((vars->line_speed == SPEED_AUTO_NEG) && |
1168 | (SUPPORT_CL73)) { | 1159 | (SUPPORT_CL73)) { |
1169 | /* Enable BAM Station Manager */ | 1160 | /* Enable BAM Station Manager */ |
1170 | 1161 | ||
@@ -1226,7 +1217,8 @@ static void bnx2x_set_autoneg(struct link_params *params, | |||
1226 | } | 1217 | } |
1227 | 1218 | ||
1228 | /* program SerDes, forced speed */ | 1219 | /* program SerDes, forced speed */ |
1229 | static void bnx2x_program_serdes(struct link_params *params) | 1220 | static void bnx2x_program_serdes(struct link_params *params, |
1221 | struct link_vars *vars) | ||
1230 | { | 1222 | { |
1231 | struct bnx2x *bp = params->bp; | 1223 | struct bnx2x *bp = params->bp; |
1232 | u16 reg_val; | 1224 | u16 reg_val; |
@@ -1248,28 +1240,35 @@ static void bnx2x_program_serdes(struct link_params *params) | |||
1248 | 1240 | ||
1249 | /* program speed | 1241 | /* program speed |
1250 | - needed only if the speed is greater than 1G (2.5G or 10G) */ | 1242 | - needed only if the speed is greater than 1G (2.5G or 10G) */ |
1251 | if (!((params->req_line_speed == SPEED_1000) || | 1243 | CL45_RD_OVER_CL22(bp, params->port, |
1252 | (params->req_line_speed == SPEED_100) || | ||
1253 | (params->req_line_speed == SPEED_10))) { | ||
1254 | CL45_RD_OVER_CL22(bp, params->port, | ||
1255 | params->phy_addr, | 1244 | params->phy_addr, |
1256 | MDIO_REG_BANK_SERDES_DIGITAL, | 1245 | MDIO_REG_BANK_SERDES_DIGITAL, |
1257 | MDIO_SERDES_DIGITAL_MISC1, ®_val); | 1246 | MDIO_SERDES_DIGITAL_MISC1, ®_val); |
1258 | /* clearing the speed value before setting the right speed */ | 1247 | /* clearing the speed value before setting the right speed */ |
1259 | reg_val &= ~MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK; | 1248 | DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val); |
1249 | |||
1250 | reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK | | ||
1251 | MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL); | ||
1252 | |||
1253 | if (!((vars->line_speed == SPEED_1000) || | ||
1254 | (vars->line_speed == SPEED_100) || | ||
1255 | (vars->line_speed == SPEED_10))) { | ||
1256 | |||
1260 | reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M | | 1257 | reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M | |
1261 | MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL); | 1258 | MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL); |
1262 | if (params->req_line_speed == SPEED_10000) | 1259 | if (vars->line_speed == SPEED_10000) |
1263 | reg_val |= | 1260 | reg_val |= |
1264 | MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4; | 1261 | MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4; |
1265 | if (params->req_line_speed == SPEED_13000) | 1262 | if (vars->line_speed == SPEED_13000) |
1266 | reg_val |= | 1263 | reg_val |= |
1267 | MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G; | 1264 | MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G; |
1268 | CL45_WR_OVER_CL22(bp, params->port, | 1265 | } |
1266 | |||
1267 | CL45_WR_OVER_CL22(bp, params->port, | ||
1269 | params->phy_addr, | 1268 | params->phy_addr, |
1270 | MDIO_REG_BANK_SERDES_DIGITAL, | 1269 | MDIO_REG_BANK_SERDES_DIGITAL, |
1271 | MDIO_SERDES_DIGITAL_MISC1, reg_val); | 1270 | MDIO_SERDES_DIGITAL_MISC1, reg_val); |
1272 | } | 1271 | |
1273 | } | 1272 | } |
1274 | 1273 | ||
1275 | static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params) | 1274 | static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params) |
@@ -1295,48 +1294,49 @@ static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params) | |||
1295 | MDIO_OVER_1G_UP3, 0); | 1294 | MDIO_OVER_1G_UP3, 0); |
1296 | } | 1295 | } |
1297 | 1296 | ||
1298 | static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params, | 1297 | static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc) |
1299 | u32 *ieee_fc) | ||
1300 | { | 1298 | { |
1301 | struct bnx2x *bp = params->bp; | 1299 | *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX; |
1302 | /* for AN, we are always publishing full duplex */ | ||
1303 | u16 an_adv = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX; | ||
1304 | |||
1305 | /* resolve pause mode and advertisement | 1300 | /* resolve pause mode and advertisement |
1306 | * Please refer to Table 28B-3 of the 802.3ab-1999 spec */ | 1301 | * Please refer to Table 28B-3 of the 802.3ab-1999 spec */ |
1307 | 1302 | ||
1308 | switch (params->req_flow_ctrl) { | 1303 | switch (params->req_flow_ctrl) { |
1309 | case FLOW_CTRL_AUTO: | 1304 | case FLOW_CTRL_AUTO: |
1310 | if (params->mtu <= MAX_MTU_SIZE) { | 1305 | if (params->req_fc_auto_adv == FLOW_CTRL_BOTH) { |
1311 | an_adv |= | 1306 | *ieee_fc |= |
1312 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; | 1307 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; |
1313 | } else { | 1308 | } else { |
1314 | an_adv |= | 1309 | *ieee_fc |= |
1315 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; | 1310 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; |
1316 | } | 1311 | } |
1317 | break; | 1312 | break; |
1318 | case FLOW_CTRL_TX: | 1313 | case FLOW_CTRL_TX: |
1319 | an_adv |= | 1314 | *ieee_fc |= |
1320 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; | 1315 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; |
1321 | break; | 1316 | break; |
1322 | 1317 | ||
1323 | case FLOW_CTRL_RX: | 1318 | case FLOW_CTRL_RX: |
1324 | case FLOW_CTRL_BOTH: | 1319 | case FLOW_CTRL_BOTH: |
1325 | an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; | 1320 | *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; |
1326 | break; | 1321 | break; |
1327 | 1322 | ||
1328 | case FLOW_CTRL_NONE: | 1323 | case FLOW_CTRL_NONE: |
1329 | default: | 1324 | default: |
1330 | an_adv |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; | 1325 | *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; |
1331 | break; | 1326 | break; |
1332 | } | 1327 | } |
1328 | } | ||
1333 | 1329 | ||
1334 | *ieee_fc = an_adv; | 1330 | static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params, |
1331 | u32 ieee_fc) | ||
1332 | { | ||
1333 | struct bnx2x *bp = params->bp; | ||
1334 | /* for AN, we are always publishing full duplex */ | ||
1335 | 1335 | ||
1336 | CL45_WR_OVER_CL22(bp, params->port, | 1336 | CL45_WR_OVER_CL22(bp, params->port, |
1337 | params->phy_addr, | 1337 | params->phy_addr, |
1338 | MDIO_REG_BANK_COMBO_IEEE0, | 1338 | MDIO_REG_BANK_COMBO_IEEE0, |
1339 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV, an_adv); | 1339 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc); |
1340 | } | 1340 | } |
1341 | 1341 | ||
1342 | static void bnx2x_restart_autoneg(struct link_params *params) | 1342 | static void bnx2x_restart_autoneg(struct link_params *params) |
@@ -1382,7 +1382,8 @@ static void bnx2x_restart_autoneg(struct link_params *params) | |||
1382 | } | 1382 | } |
1383 | } | 1383 | } |
1384 | 1384 | ||
1385 | static void bnx2x_initialize_sgmii_process(struct link_params *params) | 1385 | static void bnx2x_initialize_sgmii_process(struct link_params *params, |
1386 | struct link_vars *vars) | ||
1386 | { | 1387 | { |
1387 | struct bnx2x *bp = params->bp; | 1388 | struct bnx2x *bp = params->bp; |
1388 | u16 control1; | 1389 | u16 control1; |
@@ -1406,7 +1407,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params) | |||
1406 | control1); | 1407 | control1); |
1407 | 1408 | ||
1408 | /* if forced speed */ | 1409 | /* if forced speed */ |
1409 | if (!(params->req_line_speed == SPEED_AUTO_NEG)) { | 1410 | if (!(vars->line_speed == SPEED_AUTO_NEG)) { |
1410 | /* set speed, disable autoneg */ | 1411 | /* set speed, disable autoneg */ |
1411 | u16 mii_control; | 1412 | u16 mii_control; |
1412 | 1413 | ||
@@ -1419,7 +1420,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params) | |||
1419 | MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK| | 1420 | MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK| |
1420 | MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX); | 1421 | MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX); |
1421 | 1422 | ||
1422 | switch (params->req_line_speed) { | 1423 | switch (vars->line_speed) { |
1423 | case SPEED_100: | 1424 | case SPEED_100: |
1424 | mii_control |= | 1425 | mii_control |= |
1425 | MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100; | 1426 | MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100; |
@@ -1433,8 +1434,8 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params) | |||
1433 | break; | 1434 | break; |
1434 | default: | 1435 | default: |
1435 | /* invalid speed for SGMII */ | 1436 | /* invalid speed for SGMII */ |
1436 | DP(NETIF_MSG_LINK, "Invalid req_line_speed 0x%x\n", | 1437 | DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", |
1437 | params->req_line_speed); | 1438 | vars->line_speed); |
1438 | break; | 1439 | break; |
1439 | } | 1440 | } |
1440 | 1441 | ||
@@ -1460,20 +1461,20 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params) | |||
1460 | */ | 1461 | */ |
1461 | 1462 | ||
1462 | static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result) | 1463 | static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result) |
1463 | { | 1464 | { /* LD LP */ |
1464 | switch (pause_result) { /* ASYM P ASYM P */ | 1465 | switch (pause_result) { /* ASYM P ASYM P */ |
1465 | case 0xb: /* 1 0 1 1 */ | 1466 | case 0xb: /* 1 0 1 1 */ |
1466 | vars->flow_ctrl = FLOW_CTRL_TX; | 1467 | vars->flow_ctrl = FLOW_CTRL_TX; |
1467 | break; | 1468 | break; |
1468 | 1469 | ||
1469 | case 0xe: /* 1 1 1 0 */ | 1470 | case 0xe: /* 1 1 1 0 */ |
1470 | vars->flow_ctrl = FLOW_CTRL_RX; | 1471 | vars->flow_ctrl = FLOW_CTRL_RX; |
1471 | break; | 1472 | break; |
1472 | 1473 | ||
1473 | case 0x5: /* 0 1 0 1 */ | 1474 | case 0x5: /* 0 1 0 1 */ |
1474 | case 0x7: /* 0 1 1 1 */ | 1475 | case 0x7: /* 0 1 1 1 */ |
1475 | case 0xd: /* 1 1 0 1 */ | 1476 | case 0xd: /* 1 1 0 1 */ |
1476 | case 0xf: /* 1 1 1 1 */ | 1477 | case 0xf: /* 1 1 1 1 */ |
1477 | vars->flow_ctrl = FLOW_CTRL_BOTH; | 1478 | vars->flow_ctrl = FLOW_CTRL_BOTH; |
1478 | break; | 1479 | break; |
1479 | 1480 | ||
@@ -1531,6 +1532,28 @@ static u8 bnx2x_ext_phy_resove_fc(struct link_params *params, | |||
1531 | DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n", | 1532 | DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n", |
1532 | pause_result); | 1533 | pause_result); |
1533 | bnx2x_pause_resolve(vars, pause_result); | 1534 | bnx2x_pause_resolve(vars, pause_result); |
1535 | if (vars->flow_ctrl == FLOW_CTRL_NONE && | ||
1536 | ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { | ||
1537 | bnx2x_cl45_read(bp, port, | ||
1538 | ext_phy_type, | ||
1539 | ext_phy_addr, | ||
1540 | MDIO_AN_DEVAD, | ||
1541 | MDIO_AN_REG_CL37_FC_LD, &ld_pause); | ||
1542 | |||
1543 | bnx2x_cl45_read(bp, port, | ||
1544 | ext_phy_type, | ||
1545 | ext_phy_addr, | ||
1546 | MDIO_AN_DEVAD, | ||
1547 | MDIO_AN_REG_CL37_FC_LP, &lp_pause); | ||
1548 | pause_result = (ld_pause & | ||
1549 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5; | ||
1550 | pause_result |= (lp_pause & | ||
1551 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7; | ||
1552 | |||
1553 | bnx2x_pause_resolve(vars, pause_result); | ||
1554 | DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n", | ||
1555 | pause_result); | ||
1556 | } | ||
1534 | } | 1557 | } |
1535 | return ret; | 1558 | return ret; |
1536 | } | 1559 | } |
@@ -1541,8 +1564,8 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params, | |||
1541 | u32 gp_status) | 1564 | u32 gp_status) |
1542 | { | 1565 | { |
1543 | struct bnx2x *bp = params->bp; | 1566 | struct bnx2x *bp = params->bp; |
1544 | u16 ld_pause; /* local driver */ | 1567 | u16 ld_pause; /* local driver */ |
1545 | u16 lp_pause; /* link partner */ | 1568 | u16 lp_pause; /* link partner */ |
1546 | u16 pause_result; | 1569 | u16 pause_result; |
1547 | 1570 | ||
1548 | vars->flow_ctrl = FLOW_CTRL_NONE; | 1571 | vars->flow_ctrl = FLOW_CTRL_NONE; |
@@ -1573,13 +1596,10 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params, | |||
1573 | (bnx2x_ext_phy_resove_fc(params, vars))) { | 1596 | (bnx2x_ext_phy_resove_fc(params, vars))) { |
1574 | return; | 1597 | return; |
1575 | } else { | 1598 | } else { |
1576 | vars->flow_ctrl = params->req_flow_ctrl; | 1599 | if (params->req_flow_ctrl == FLOW_CTRL_AUTO) |
1577 | if (vars->flow_ctrl == FLOW_CTRL_AUTO) { | 1600 | vars->flow_ctrl = params->req_fc_auto_adv; |
1578 | if (params->mtu <= MAX_MTU_SIZE) | 1601 | else |
1579 | vars->flow_ctrl = FLOW_CTRL_BOTH; | 1602 | vars->flow_ctrl = params->req_flow_ctrl; |
1580 | else | ||
1581 | vars->flow_ctrl = FLOW_CTRL_TX; | ||
1582 | } | ||
1583 | } | 1603 | } |
1584 | DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl); | 1604 | DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl); |
1585 | } | 1605 | } |
@@ -1590,6 +1610,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params, | |||
1590 | u32 gp_status) | 1610 | u32 gp_status) |
1591 | { | 1611 | { |
1592 | struct bnx2x *bp = params->bp; | 1612 | struct bnx2x *bp = params->bp; |
1613 | |||
1593 | u8 rc = 0; | 1614 | u8 rc = 0; |
1594 | vars->link_status = 0; | 1615 | vars->link_status = 0; |
1595 | 1616 | ||
@@ -1690,7 +1711,11 @@ static u8 bnx2x_link_settings_status(struct link_params *params, | |||
1690 | 1711 | ||
1691 | vars->link_status |= LINK_STATUS_SERDES_LINK; | 1712 | vars->link_status |= LINK_STATUS_SERDES_LINK; |
1692 | 1713 | ||
1693 | if (params->req_line_speed == SPEED_AUTO_NEG) { | 1714 | if ((params->req_line_speed == SPEED_AUTO_NEG) && |
1715 | ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) == | ||
1716 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) || | ||
1717 | (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == | ||
1718 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) { | ||
1694 | vars->autoneg = AUTO_NEG_ENABLED; | 1719 | vars->autoneg = AUTO_NEG_ENABLED; |
1695 | 1720 | ||
1696 | if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { | 1721 | if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { |
@@ -1705,18 +1730,18 @@ static u8 bnx2x_link_settings_status(struct link_params *params, | |||
1705 | 1730 | ||
1706 | } | 1731 | } |
1707 | if (vars->flow_ctrl & FLOW_CTRL_TX) | 1732 | if (vars->flow_ctrl & FLOW_CTRL_TX) |
1708 | vars->link_status |= | 1733 | vars->link_status |= |
1709 | LINK_STATUS_TX_FLOW_CONTROL_ENABLED; | 1734 | LINK_STATUS_TX_FLOW_CONTROL_ENABLED; |
1710 | 1735 | ||
1711 | if (vars->flow_ctrl & FLOW_CTRL_RX) | 1736 | if (vars->flow_ctrl & FLOW_CTRL_RX) |
1712 | vars->link_status |= | 1737 | vars->link_status |= |
1713 | LINK_STATUS_RX_FLOW_CONTROL_ENABLED; | 1738 | LINK_STATUS_RX_FLOW_CONTROL_ENABLED; |
1714 | 1739 | ||
1715 | } else { /* link_down */ | 1740 | } else { /* link_down */ |
1716 | DP(NETIF_MSG_LINK, "phy link down\n"); | 1741 | DP(NETIF_MSG_LINK, "phy link down\n"); |
1717 | 1742 | ||
1718 | vars->phy_link_up = 0; | 1743 | vars->phy_link_up = 0; |
1719 | vars->line_speed = 0; | 1744 | |
1720 | vars->duplex = DUPLEX_FULL; | 1745 | vars->duplex = DUPLEX_FULL; |
1721 | vars->flow_ctrl = FLOW_CTRL_NONE; | 1746 | vars->flow_ctrl = FLOW_CTRL_NONE; |
1722 | vars->autoneg = AUTO_NEG_DISABLED; | 1747 | vars->autoneg = AUTO_NEG_DISABLED; |
@@ -1817,15 +1842,15 @@ static u8 bnx2x_emac_program(struct link_params *params, | |||
1817 | } | 1842 | } |
1818 | 1843 | ||
1819 | /*****************************************************************************/ | 1844 | /*****************************************************************************/ |
1820 | /* External Phy section */ | 1845 | /* External Phy section */ |
1821 | /*****************************************************************************/ | 1846 | /*****************************************************************************/ |
1822 | static void bnx2x_hw_reset(struct bnx2x *bp) | 1847 | static void bnx2x_hw_reset(struct bnx2x *bp, u8 port) |
1823 | { | 1848 | { |
1824 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, | 1849 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, |
1825 | MISC_REGISTERS_GPIO_OUTPUT_LOW); | 1850 | MISC_REGISTERS_GPIO_OUTPUT_LOW, port); |
1826 | msleep(1); | 1851 | msleep(1); |
1827 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, | 1852 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, |
1828 | MISC_REGISTERS_GPIO_OUTPUT_HIGH); | 1853 | MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); |
1829 | } | 1854 | } |
1830 | 1855 | ||
1831 | static void bnx2x_ext_phy_reset(struct link_params *params, | 1856 | static void bnx2x_ext_phy_reset(struct link_params *params, |
@@ -1854,10 +1879,11 @@ static void bnx2x_ext_phy_reset(struct link_params *params, | |||
1854 | 1879 | ||
1855 | /* Restore normal power mode*/ | 1880 | /* Restore normal power mode*/ |
1856 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, | 1881 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, |
1857 | MISC_REGISTERS_GPIO_OUTPUT_HIGH); | 1882 | MISC_REGISTERS_GPIO_OUTPUT_HIGH, |
1883 | params->port); | ||
1858 | 1884 | ||
1859 | /* HW reset */ | 1885 | /* HW reset */ |
1860 | bnx2x_hw_reset(bp); | 1886 | bnx2x_hw_reset(bp, params->port); |
1861 | 1887 | ||
1862 | bnx2x_cl45_write(bp, params->port, | 1888 | bnx2x_cl45_write(bp, params->port, |
1863 | ext_phy_type, | 1889 | ext_phy_type, |
@@ -1869,7 +1895,8 @@ static void bnx2x_ext_phy_reset(struct link_params *params, | |||
1869 | /* Unset Low Power Mode and SW reset */ | 1895 | /* Unset Low Power Mode and SW reset */ |
1870 | /* Restore normal power mode*/ | 1896 | /* Restore normal power mode*/ |
1871 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, | 1897 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, |
1872 | MISC_REGISTERS_GPIO_OUTPUT_HIGH); | 1898 | MISC_REGISTERS_GPIO_OUTPUT_HIGH, |
1899 | params->port); | ||
1873 | 1900 | ||
1874 | DP(NETIF_MSG_LINK, "XGXS 8072\n"); | 1901 | DP(NETIF_MSG_LINK, "XGXS 8072\n"); |
1875 | bnx2x_cl45_write(bp, params->port, | 1902 | bnx2x_cl45_write(bp, params->port, |
@@ -1887,19 +1914,14 @@ static void bnx2x_ext_phy_reset(struct link_params *params, | |||
1887 | 1914 | ||
1888 | /* Restore normal power mode*/ | 1915 | /* Restore normal power mode*/ |
1889 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, | 1916 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, |
1890 | MISC_REGISTERS_GPIO_OUTPUT_HIGH); | 1917 | MISC_REGISTERS_GPIO_OUTPUT_HIGH, |
1918 | params->port); | ||
1891 | 1919 | ||
1892 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, | 1920 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, |
1893 | MISC_REGISTERS_GPIO_OUTPUT_HIGH); | 1921 | MISC_REGISTERS_GPIO_OUTPUT_HIGH, |
1922 | params->port); | ||
1894 | 1923 | ||
1895 | DP(NETIF_MSG_LINK, "XGXS 8073\n"); | 1924 | DP(NETIF_MSG_LINK, "XGXS 8073\n"); |
1896 | bnx2x_cl45_write(bp, | ||
1897 | params->port, | ||
1898 | ext_phy_type, | ||
1899 | ext_phy_addr, | ||
1900 | MDIO_PMA_DEVAD, | ||
1901 | MDIO_PMA_REG_CTRL, | ||
1902 | 1<<15); | ||
1903 | } | 1925 | } |
1904 | break; | 1926 | break; |
1905 | 1927 | ||
@@ -1908,10 +1930,11 @@ static void bnx2x_ext_phy_reset(struct link_params *params, | |||
1908 | 1930 | ||
1909 | /* Restore normal power mode*/ | 1931 | /* Restore normal power mode*/ |
1910 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, | 1932 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, |
1911 | MISC_REGISTERS_GPIO_OUTPUT_HIGH); | 1933 | MISC_REGISTERS_GPIO_OUTPUT_HIGH, |
1934 | params->port); | ||
1912 | 1935 | ||
1913 | /* HW reset */ | 1936 | /* HW reset */ |
1914 | bnx2x_hw_reset(bp); | 1937 | bnx2x_hw_reset(bp, params->port); |
1915 | 1938 | ||
1916 | break; | 1939 | break; |
1917 | 1940 | ||
@@ -1934,7 +1957,7 @@ static void bnx2x_ext_phy_reset(struct link_params *params, | |||
1934 | 1957 | ||
1935 | case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: | 1958 | case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: |
1936 | DP(NETIF_MSG_LINK, "SerDes 5482\n"); | 1959 | DP(NETIF_MSG_LINK, "SerDes 5482\n"); |
1937 | bnx2x_hw_reset(bp); | 1960 | bnx2x_hw_reset(bp, params->port); |
1938 | break; | 1961 | break; |
1939 | 1962 | ||
1940 | default: | 1963 | default: |
@@ -2098,42 +2121,45 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params) | |||
2098 | 2121 | ||
2099 | } | 2122 | } |
2100 | 2123 | ||
2101 | 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) | ||
2102 | { | 2126 | { |
2103 | struct bnx2x *bp = params->bp; | 2127 | u16 fw_ver1, fw_ver2; |
2104 | u8 port = params->port; | 2128 | /* Boot port from external ROM */ |
2105 | u8 ext_phy_addr = ((params->ext_phy_config & | ||
2106 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | ||
2107 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | ||
2108 | u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); | ||
2109 | u16 fw_ver1, fw_ver2, val; | ||
2110 | /* Need to wait 100ms after reset */ | ||
2111 | msleep(100); | ||
2112 | /* Boot port from external ROM */ | ||
2113 | /* EDC grst */ | 2129 | /* EDC grst */ |
2114 | 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, | ||
2115 | MDIO_PMA_DEVAD, | 2133 | MDIO_PMA_DEVAD, |
2116 | MDIO_PMA_REG_GEN_CTRL, | 2134 | MDIO_PMA_REG_GEN_CTRL, |
2117 | 0x0001); | 2135 | 0x0001); |
2118 | 2136 | ||
2119 | /* ucode reboot and rst */ | 2137 | /* ucode reboot and rst */ |
2120 | 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, | ||
2121 | MDIO_PMA_DEVAD, | 2141 | MDIO_PMA_DEVAD, |
2122 | MDIO_PMA_REG_GEN_CTRL, | 2142 | MDIO_PMA_REG_GEN_CTRL, |
2123 | 0x008c); | 2143 | 0x008c); |
2124 | 2144 | ||
2125 | 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, | ||
2126 | MDIO_PMA_DEVAD, | 2148 | MDIO_PMA_DEVAD, |
2127 | MDIO_PMA_REG_MISC_CTRL1, 0x0001); | 2149 | MDIO_PMA_REG_MISC_CTRL1, 0x0001); |
2128 | 2150 | ||
2129 | /* Reset internal microprocessor */ | 2151 | /* Reset internal microprocessor */ |
2130 | 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, | ||
2131 | MDIO_PMA_DEVAD, | 2155 | MDIO_PMA_DEVAD, |
2132 | MDIO_PMA_REG_GEN_CTRL, | 2156 | MDIO_PMA_REG_GEN_CTRL, |
2133 | MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); | 2157 | MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); |
2134 | 2158 | ||
2135 | /* Release srst bit */ | 2159 | /* Release srst bit */ |
2136 | 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, | ||
2137 | MDIO_PMA_DEVAD, | 2163 | MDIO_PMA_DEVAD, |
2138 | MDIO_PMA_REG_GEN_CTRL, | 2164 | MDIO_PMA_REG_GEN_CTRL, |
2139 | MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); | 2165 | MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); |
@@ -2142,35 +2168,52 @@ static void bnx2x_bcm8073_external_rom_boot(struct link_params *params) | |||
2142 | msleep(100); | 2168 | msleep(100); |
2143 | 2169 | ||
2144 | /* Clear ser_boot_ctl bit */ | 2170 | /* Clear ser_boot_ctl bit */ |
2145 | 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, | ||
2146 | MDIO_PMA_DEVAD, | 2174 | MDIO_PMA_DEVAD, |
2147 | MDIO_PMA_REG_MISC_CTRL1, 0x0000); | 2175 | MDIO_PMA_REG_MISC_CTRL1, 0x0000); |
2148 | 2176 | ||
2149 | 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, |
2150 | MDIO_PMA_DEVAD, | 2178 | ext_phy_addr, |
2151 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); | 2179 | MDIO_PMA_DEVAD, |
2152 | bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, | 2180 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); |
2153 | MDIO_PMA_DEVAD, | 2181 | bnx2x_cl45_read(bp, port, |
2154 | 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); | ||
2155 | 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); |
2156 | 2187 | ||
2157 | /* Only set bit 10 = 1 (Tx power down) */ | 2188 | } |
2158 | bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, | ||
2159 | MDIO_PMA_DEVAD, | ||
2160 | MDIO_PMA_REG_TX_POWER_DOWN, &val); | ||
2161 | 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 */ | ||
2162 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2200 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, |
2163 | MDIO_PMA_DEVAD, | 2201 | MDIO_PMA_DEVAD, |
2164 | MDIO_PMA_REG_TX_POWER_DOWN, (val | 1<<10)); | 2202 | MDIO_PMA_REG_CTRL, |
2165 | 2203 | 0x2040); | |
2166 | msleep(600); | ||
2167 | /* Release bit 10 (Release Tx power down) */ | ||
2168 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2204 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, |
2169 | MDIO_PMA_DEVAD, | 2205 | MDIO_PMA_DEVAD, |
2170 | MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10)))); | 2206 | MDIO_PMA_REG_10G_CTRL2, |
2171 | 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); | ||
2172 | } | 2216 | } |
2173 | |||
2174 | 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) |
2175 | { | 2218 | { |
2176 | struct bnx2x *bp = params->bp; | 2219 | struct bnx2x *bp = params->bp; |
@@ -2236,32 +2279,51 @@ static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params) | |||
2236 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2279 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, |
2237 | MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); | 2280 | MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); |
2238 | } | 2281 | } |
2239 | 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) | ||
2240 | { | 2285 | { |
2286 | |||
2241 | struct bnx2x *bp = params->bp; | 2287 | struct bnx2x *bp = params->bp; |
2242 | u8 port = params->port; | 2288 | u16 cl37_val; |
2243 | u8 ext_phy_addr = ((params->ext_phy_config & | 2289 | u8 ext_phy_addr = ((params->ext_phy_config & |
2244 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | 2290 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> |
2245 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | 2291 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); |
2246 | 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); |
2247 | 2293 | ||
2248 | /* Force KR or KX */ | 2294 | bnx2x_cl45_read(bp, params->port, |
2249 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2295 | ext_phy_type, |
2250 | MDIO_PMA_DEVAD, | 2296 | ext_phy_addr, |
2251 | MDIO_PMA_REG_CTRL, | 2297 | MDIO_AN_DEVAD, |
2252 | 0x2040); | 2298 | MDIO_AN_REG_CL37_FC_LD, &cl37_val); |
2253 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2299 | |
2254 | MDIO_PMA_DEVAD, | 2300 | cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; |
2255 | MDIO_PMA_REG_10G_CTRL2, | 2301 | /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ |
2256 | 0x000b); | 2302 | |
2257 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | 2303 | if ((vars->ieee_fc & |
2258 | MDIO_PMA_DEVAD, | 2304 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) == |
2259 | MDIO_PMA_REG_BCM_CTRL, | 2305 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) { |
2260 | 0x0000); | 2306 | cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC; |
2261 | 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, | ||
2262 | MDIO_AN_DEVAD, | 2324 | MDIO_AN_DEVAD, |
2263 | MDIO_AN_REG_CTRL, | 2325 | MDIO_AN_REG_CL37_FC_LD, cl37_val); |
2264 | 0x0000); | 2326 | msleep(500); |
2265 | } | 2327 | } |
2266 | 2328 | ||
2267 | static void bnx2x_ext_phy_set_pause(struct link_params *params, | 2329 | static void bnx2x_ext_phy_set_pause(struct link_params *params, |
@@ -2282,13 +2344,16 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params, | |||
2282 | MDIO_AN_REG_ADV_PAUSE, &val); | 2344 | MDIO_AN_REG_ADV_PAUSE, &val); |
2283 | 2345 | ||
2284 | val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH; | 2346 | val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH; |
2347 | |||
2285 | /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ | 2348 | /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ |
2286 | 2349 | ||
2287 | if (vars->ieee_fc & | 2350 | if ((vars->ieee_fc & |
2351 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == | ||
2288 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { | 2352 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { |
2289 | val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC; | 2353 | val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC; |
2290 | } | 2354 | } |
2291 | if (vars->ieee_fc & | 2355 | if ((vars->ieee_fc & |
2356 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == | ||
2292 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) { | 2357 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) { |
2293 | val |= | 2358 | val |= |
2294 | MDIO_AN_REG_ADV_PAUSE_PAUSE; | 2359 | MDIO_AN_REG_ADV_PAUSE_PAUSE; |
@@ -2302,6 +2367,65 @@ static void bnx2x_ext_phy_set_pause(struct link_params *params, | |||
2302 | MDIO_AN_REG_ADV_PAUSE, val); | 2367 | MDIO_AN_REG_ADV_PAUSE, val); |
2303 | } | 2368 | } |
2304 | 2369 | ||
2370 | |||
2371 | static void bnx2x_init_internal_phy(struct link_params *params, | ||
2372 | struct link_vars *vars) | ||
2373 | { | ||
2374 | struct bnx2x *bp = params->bp; | ||
2375 | u8 port = params->port; | ||
2376 | if (!(vars->phy_flags & PHY_SGMII_FLAG)) { | ||
2377 | u16 bank, rx_eq; | ||
2378 | |||
2379 | rx_eq = ((params->serdes_config & | ||
2380 | PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >> | ||
2381 | PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT); | ||
2382 | |||
2383 | DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq); | ||
2384 | for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL; | ||
2385 | bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) { | ||
2386 | CL45_WR_OVER_CL22(bp, port, | ||
2387 | params->phy_addr, | ||
2388 | bank , | ||
2389 | MDIO_RX0_RX_EQ_BOOST, | ||
2390 | ((rx_eq & | ||
2391 | MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) | | ||
2392 | MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL)); | ||
2393 | } | ||
2394 | |||
2395 | /* forced speed requested? */ | ||
2396 | if (vars->line_speed != SPEED_AUTO_NEG) { | ||
2397 | DP(NETIF_MSG_LINK, "not SGMII, no AN\n"); | ||
2398 | |||
2399 | /* disable autoneg */ | ||
2400 | bnx2x_set_autoneg(params, vars); | ||
2401 | |||
2402 | /* program speed and duplex */ | ||
2403 | bnx2x_program_serdes(params, vars); | ||
2404 | |||
2405 | } else { /* AN_mode */ | ||
2406 | DP(NETIF_MSG_LINK, "not SGMII, AN\n"); | ||
2407 | |||
2408 | /* AN enabled */ | ||
2409 | bnx2x_set_brcm_cl37_advertisment(params); | ||
2410 | |||
2411 | /* program duplex & pause advertisement (for aneg) */ | ||
2412 | bnx2x_set_ieee_aneg_advertisment(params, | ||
2413 | vars->ieee_fc); | ||
2414 | |||
2415 | /* enable autoneg */ | ||
2416 | bnx2x_set_autoneg(params, vars); | ||
2417 | |||
2418 | /* enable and restart AN */ | ||
2419 | bnx2x_restart_autoneg(params); | ||
2420 | } | ||
2421 | |||
2422 | } else { /* SGMII mode */ | ||
2423 | DP(NETIF_MSG_LINK, "SGMII\n"); | ||
2424 | |||
2425 | bnx2x_initialize_sgmii_process(params, vars); | ||
2426 | } | ||
2427 | } | ||
2428 | |||
2305 | static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | 2429 | static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) |
2306 | { | 2430 | { |
2307 | struct bnx2x *bp = params->bp; | 2431 | struct bnx2x *bp = params->bp; |
@@ -2343,7 +2467,6 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
2343 | 2467 | ||
2344 | switch (ext_phy_type) { | 2468 | switch (ext_phy_type) { |
2345 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: | 2469 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: |
2346 | DP(NETIF_MSG_LINK, "XGXS Direct\n"); | ||
2347 | break; | 2470 | break; |
2348 | 2471 | ||
2349 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: | 2472 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: |
@@ -2419,7 +2542,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
2419 | ext_phy_type, | 2542 | ext_phy_type, |
2420 | ext_phy_addr, | 2543 | ext_phy_addr, |
2421 | MDIO_AN_DEVAD, | 2544 | MDIO_AN_DEVAD, |
2422 | MDIO_AN_REG_CL37_FD, | 2545 | MDIO_AN_REG_CL37_FC_LP, |
2423 | 0x0020); | 2546 | 0x0020); |
2424 | /* Enable CL37 AN */ | 2547 | /* Enable CL37 AN */ |
2425 | bnx2x_cl45_write(bp, params->port, | 2548 | bnx2x_cl45_write(bp, params->port, |
@@ -2458,54 +2581,43 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
2458 | rx_alarm_ctrl_val = 0x400; | 2581 | rx_alarm_ctrl_val = 0x400; |
2459 | lasi_ctrl_val = 0x0004; | 2582 | lasi_ctrl_val = 0x0004; |
2460 | } else { | 2583 | } else { |
2461 | /* In 8073, port1 is directed through emac0 and | ||
2462 | * port0 is directed through emac1 | ||
2463 | */ | ||
2464 | rx_alarm_ctrl_val = (1<<2); | 2584 | rx_alarm_ctrl_val = (1<<2); |
2465 | /*lasi_ctrl_val = 0x0005;*/ | ||
2466 | lasi_ctrl_val = 0x0004; | 2585 | lasi_ctrl_val = 0x0004; |
2467 | } | 2586 | } |
2468 | 2587 | ||
2469 | /* Wait for soft reset to get cleared upto 1 sec */ | 2588 | /* enable LASI */ |
2470 | for (cnt = 0; cnt < 1000; cnt++) { | 2589 | bnx2x_cl45_write(bp, params->port, |
2471 | bnx2x_cl45_read(bp, params->port, | 2590 | ext_phy_type, |
2472 | ext_phy_type, | 2591 | ext_phy_addr, |
2473 | ext_phy_addr, | 2592 | MDIO_PMA_DEVAD, |
2474 | MDIO_PMA_DEVAD, | 2593 | MDIO_PMA_REG_RX_ALARM_CTRL, |
2475 | MDIO_PMA_REG_CTRL, | 2594 | rx_alarm_ctrl_val); |
2476 | &ctrl); | 2595 | |
2477 | if (!(ctrl & (1<<15))) | 2596 | bnx2x_cl45_write(bp, params->port, |
2478 | break; | 2597 | ext_phy_type, |
2479 | msleep(1); | 2598 | ext_phy_addr, |
2480 | } | 2599 | MDIO_PMA_DEVAD, |
2481 | DP(NETIF_MSG_LINK, | 2600 | MDIO_PMA_REG_LASI_CTRL, |
2482 | "807x control reg 0x%x (after %d ms)\n", | 2601 | lasi_ctrl_val); |
2483 | ctrl, cnt); | 2602 | |
2603 | bnx2x_8073_set_pause_cl37(params, vars); | ||
2484 | 2604 | ||
2485 | if (ext_phy_type == | 2605 | if (ext_phy_type == |
2486 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){ | 2606 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){ |
2487 | bnx2x_bcm8072_external_rom_boot(params); | 2607 | bnx2x_bcm8072_external_rom_boot(params); |
2488 | } else { | 2608 | } else { |
2489 | bnx2x_bcm8073_external_rom_boot(params); | 2609 | |
2490 | /* In case of 8073 with long xaui lines, | 2610 | /* In case of 8073 with long xaui lines, |
2491 | don't set the 8073 xaui low power*/ | 2611 | don't set the 8073 xaui low power*/ |
2492 | bnx2x_bcm8073_set_xaui_low_power_mode(params); | 2612 | bnx2x_bcm8073_set_xaui_low_power_mode(params); |
2493 | } | 2613 | } |
2494 | 2614 | ||
2495 | /* enable LASI */ | 2615 | bnx2x_cl45_read(bp, params->port, |
2496 | bnx2x_cl45_write(bp, params->port, | 2616 | ext_phy_type, |
2497 | ext_phy_type, | 2617 | ext_phy_addr, |
2498 | ext_phy_addr, | 2618 | MDIO_PMA_DEVAD, |
2499 | MDIO_PMA_DEVAD, | 2619 | 0xca13, |
2500 | MDIO_PMA_REG_RX_ALARM_CTRL, | 2620 | &tmp1); |
2501 | rx_alarm_ctrl_val); | ||
2502 | |||
2503 | bnx2x_cl45_write(bp, params->port, | ||
2504 | ext_phy_type, | ||
2505 | ext_phy_addr, | ||
2506 | MDIO_PMA_DEVAD, | ||
2507 | MDIO_PMA_REG_LASI_CTRL, | ||
2508 | lasi_ctrl_val); | ||
2509 | 2621 | ||
2510 | bnx2x_cl45_read(bp, params->port, | 2622 | bnx2x_cl45_read(bp, params->port, |
2511 | ext_phy_type, | 2623 | ext_phy_type, |
@@ -2519,12 +2631,21 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
2519 | /* If this is forced speed, set to KR or KX | 2631 | /* If this is forced speed, set to KR or KX |
2520 | * (all other are not supported) | 2632 | * (all other are not supported) |
2521 | */ | 2633 | */ |
2522 | if (!(params->req_line_speed == SPEED_AUTO_NEG)) { | 2634 | if (params->loopback_mode == LOOPBACK_EXT) { |
2523 | if (params->req_line_speed == SPEED_10000) { | 2635 | bnx2x_bcm807x_force_10G(params); |
2524 | bnx2x_bcm807x_force_10G(params); | 2636 | DP(NETIF_MSG_LINK, |
2525 | DP(NETIF_MSG_LINK, | 2637 | "Forced speed 10G on 807X\n"); |
2526 | "Forced speed 10G on 807X\n"); | 2638 | break; |
2527 | 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); | ||
2528 | } else if (params->req_line_speed == | 2649 | } else if (params->req_line_speed == |
2529 | SPEED_2500) { | 2650 | SPEED_2500) { |
2530 | val = (1<<5); | 2651 | val = (1<<5); |
@@ -2539,11 +2660,14 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
2539 | PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) | 2660 | PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) |
2540 | val |= (1<<7); | 2661 | val |= (1<<7); |
2541 | 2662 | ||
2663 | /* Note that 2.5G works only when | ||
2664 | used with 1G advertisment */ | ||
2542 | if (params->speed_cap_mask & | 2665 | if (params->speed_cap_mask & |
2543 | PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) | 2666 | (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G | |
2667 | PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) | ||
2544 | val |= (1<<5); | 2668 | val |= (1<<5); |
2545 | DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val); | 2669 | DP(NETIF_MSG_LINK, |
2546 | /*val = ((1<<5)|(1<<7));*/ | 2670 | "807x autoneg val = 0x%x\n", val); |
2547 | } | 2671 | } |
2548 | 2672 | ||
2549 | bnx2x_cl45_write(bp, params->port, | 2673 | bnx2x_cl45_write(bp, params->port, |
@@ -2554,20 +2678,19 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
2554 | 2678 | ||
2555 | if (ext_phy_type == | 2679 | if (ext_phy_type == |
2556 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { | 2680 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { |
2557 | /* Disable 2.5Ghz */ | 2681 | |
2558 | bnx2x_cl45_read(bp, params->port, | 2682 | bnx2x_cl45_read(bp, params->port, |
2559 | ext_phy_type, | 2683 | ext_phy_type, |
2560 | ext_phy_addr, | 2684 | ext_phy_addr, |
2561 | MDIO_AN_DEVAD, | 2685 | MDIO_AN_DEVAD, |
2562 | 0x8329, &tmp1); | 2686 | 0x8329, &tmp1); |
2563 | /* SUPPORT_SPEED_CAPABILITY | 2687 | |
2564 | (Due to the nature of the link order, its not | 2688 | if (((params->speed_cap_mask & |
2565 | possible to enable 2.5G within the autoneg | 2689 | PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) && |
2566 | capabilities) | 2690 | (params->req_line_speed == |
2567 | if (params->speed_cap_mask & | 2691 | SPEED_AUTO_NEG)) || |
2568 | PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) | 2692 | (params->req_line_speed == |
2569 | */ | 2693 | SPEED_2500)) { |
2570 | if (params->req_line_speed == SPEED_2500) { | ||
2571 | u16 phy_ver; | 2694 | u16 phy_ver; |
2572 | /* Allow 2.5G for A1 and above */ | 2695 | /* Allow 2.5G for A1 and above */ |
2573 | bnx2x_cl45_read(bp, params->port, | 2696 | bnx2x_cl45_read(bp, params->port, |
@@ -2575,49 +2698,53 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
2575 | ext_phy_addr, | 2698 | ext_phy_addr, |
2576 | MDIO_PMA_DEVAD, | 2699 | MDIO_PMA_DEVAD, |
2577 | 0xc801, &phy_ver); | 2700 | 0xc801, &phy_ver); |
2578 | 2701 | DP(NETIF_MSG_LINK, "Add 2.5G\n"); | |
2579 | if (phy_ver > 0) | 2702 | if (phy_ver > 0) |
2580 | tmp1 |= 1; | 2703 | tmp1 |= 1; |
2581 | else | 2704 | else |
2582 | tmp1 &= 0xfffe; | 2705 | tmp1 &= 0xfffe; |
2583 | } | 2706 | } else { |
2584 | else | 2707 | DP(NETIF_MSG_LINK, "Disable 2.5G\n"); |
2585 | tmp1 &= 0xfffe; | 2708 | tmp1 &= 0xfffe; |
2709 | } | ||
2586 | 2710 | ||
2587 | bnx2x_cl45_write(bp, params->port, | 2711 | bnx2x_cl45_write(bp, params->port, |
2588 | ext_phy_type, | 2712 | ext_phy_type, |
2589 | ext_phy_addr, | 2713 | ext_phy_addr, |
2590 | MDIO_AN_DEVAD, | 2714 | MDIO_AN_DEVAD, |
2591 | 0x8329, tmp1); | 2715 | 0x8329, tmp1); |
2592 | } | 2716 | } |
2593 | /* Add support for CL37 (passive mode) I */ | 2717 | |
2594 | bnx2x_cl45_write(bp, params->port, | 2718 | /* Add support for CL37 (passive mode) II */ |
2719 | |||
2720 | bnx2x_cl45_read(bp, params->port, | ||
2595 | ext_phy_type, | 2721 | ext_phy_type, |
2596 | ext_phy_addr, | 2722 | ext_phy_addr, |
2597 | MDIO_AN_DEVAD, | 2723 | MDIO_AN_DEVAD, |
2598 | MDIO_AN_REG_CL37_CL73, 0x040c); | 2724 | MDIO_AN_REG_CL37_FC_LD, |
2599 | /* Add support for CL37 (passive mode) II */ | 2725 | &tmp1); |
2726 | |||
2600 | bnx2x_cl45_write(bp, params->port, | 2727 | bnx2x_cl45_write(bp, params->port, |
2601 | ext_phy_type, | 2728 | ext_phy_type, |
2602 | ext_phy_addr, | 2729 | ext_phy_addr, |
2603 | MDIO_AN_DEVAD, | 2730 | MDIO_AN_DEVAD, |
2604 | MDIO_AN_REG_CL37_FD, 0x20); | 2731 | MDIO_AN_REG_CL37_FC_LD, (tmp1 | |
2732 | ((params->req_duplex == DUPLEX_FULL) ? | ||
2733 | 0x20 : 0x40))); | ||
2734 | |||
2605 | /* Add support for CL37 (passive mode) III */ | 2735 | /* Add support for CL37 (passive mode) III */ |
2606 | bnx2x_cl45_write(bp, params->port, | 2736 | bnx2x_cl45_write(bp, params->port, |
2607 | ext_phy_type, | 2737 | ext_phy_type, |
2608 | ext_phy_addr, | 2738 | ext_phy_addr, |
2609 | MDIO_AN_DEVAD, | 2739 | MDIO_AN_DEVAD, |
2610 | MDIO_AN_REG_CL37_AN, 0x1000); | 2740 | MDIO_AN_REG_CL37_AN, 0x1000); |
2611 | /* Restart autoneg */ | ||
2612 | msleep(500); | ||
2613 | 2741 | ||
2614 | if (ext_phy_type == | 2742 | if (ext_phy_type == |
2615 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { | 2743 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { |
2616 | 2744 | /* The SNR will improve about 2db by changing | |
2617 | /* The SNR will improve about 2db by changing the | ||
2618 | BW and FEE main tap. Rest commands are executed | 2745 | BW and FEE main tap. Rest commands are executed |
2619 | after link is up*/ | 2746 | after link is up*/ |
2620 | /* Change FFE main cursor to 5 in EDC register */ | 2747 | /*Change FFE main cursor to 5 in EDC register*/ |
2621 | if (bnx2x_8073_is_snr_needed(params)) | 2748 | if (bnx2x_8073_is_snr_needed(params)) |
2622 | bnx2x_cl45_write(bp, params->port, | 2749 | bnx2x_cl45_write(bp, params->port, |
2623 | ext_phy_type, | 2750 | ext_phy_type, |
@@ -2626,25 +2753,28 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
2626 | MDIO_PMA_REG_EDC_FFE_MAIN, | 2753 | MDIO_PMA_REG_EDC_FFE_MAIN, |
2627 | 0xFB0C); | 2754 | 0xFB0C); |
2628 | 2755 | ||
2629 | /* Enable FEC (Forware Error Correction) | 2756 | /* Enable FEC (Forware Error Correction) |
2630 | Request in the AN */ | 2757 | Request in the AN */ |
2631 | bnx2x_cl45_read(bp, params->port, | 2758 | bnx2x_cl45_read(bp, params->port, |
2632 | ext_phy_type, | 2759 | ext_phy_type, |
2633 | ext_phy_addr, | 2760 | ext_phy_addr, |
2634 | MDIO_AN_DEVAD, | 2761 | MDIO_AN_DEVAD, |
2635 | MDIO_AN_REG_ADV2, &tmp1); | 2762 | MDIO_AN_REG_ADV2, &tmp1); |
2636 | 2763 | ||
2637 | 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); | ||
2638 | 2771 | ||
2639 | bnx2x_cl45_write(bp, params->port, | ||
2640 | ext_phy_type, | ||
2641 | ext_phy_addr, | ||
2642 | MDIO_AN_DEVAD, | ||
2643 | MDIO_AN_REG_ADV2, tmp1); | ||
2644 | } | 2772 | } |
2645 | 2773 | ||
2646 | bnx2x_ext_phy_set_pause(params, vars); | 2774 | bnx2x_ext_phy_set_pause(params, vars); |
2647 | 2775 | ||
2776 | /* Restart autoneg */ | ||
2777 | msleep(500); | ||
2648 | bnx2x_cl45_write(bp, params->port, | 2778 | bnx2x_cl45_write(bp, params->port, |
2649 | ext_phy_type, | 2779 | ext_phy_type, |
2650 | ext_phy_addr, | 2780 | ext_phy_addr, |
@@ -2701,10 +2831,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
2701 | } | 2831 | } |
2702 | 2832 | ||
2703 | } else { /* SerDes */ | 2833 | } else { /* SerDes */ |
2704 | /* ext_phy_addr = ((bp->ext_phy_config & | 2834 | |
2705 | PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) >> | ||
2706 | PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT); | ||
2707 | */ | ||
2708 | ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); | 2835 | ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); |
2709 | switch (ext_phy_type) { | 2836 | switch (ext_phy_type) { |
2710 | case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: | 2837 | case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: |
@@ -2726,7 +2853,7 @@ static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) | |||
2726 | 2853 | ||
2727 | 2854 | ||
2728 | static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | 2855 | static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, |
2729 | struct link_vars *vars) | 2856 | struct link_vars *vars) |
2730 | { | 2857 | { |
2731 | struct bnx2x *bp = params->bp; | 2858 | struct bnx2x *bp = params->bp; |
2732 | u32 ext_phy_type; | 2859 | u32 ext_phy_type; |
@@ -2767,6 +2894,8 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
2767 | MDIO_PMA_REG_RX_SD, &rx_sd); | 2894 | MDIO_PMA_REG_RX_SD, &rx_sd); |
2768 | DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd); | 2895 | DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd); |
2769 | ext_phy_link_up = (rx_sd & 0x1); | 2896 | ext_phy_link_up = (rx_sd & 0x1); |
2897 | if (ext_phy_link_up) | ||
2898 | vars->line_speed = SPEED_10000; | ||
2770 | break; | 2899 | break; |
2771 | 2900 | ||
2772 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: | 2901 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: |
@@ -2810,6 +2939,13 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
2810 | */ | 2939 | */ |
2811 | ext_phy_link_up = ((rx_sd & pcs_status & 0x1) || | 2940 | ext_phy_link_up = ((rx_sd & pcs_status & 0x1) || |
2812 | (val2 & (1<<1))); | 2941 | (val2 & (1<<1))); |
2942 | if (ext_phy_link_up) { | ||
2943 | if (val2 & (1<<1)) | ||
2944 | vars->line_speed = SPEED_1000; | ||
2945 | else | ||
2946 | vars->line_speed = SPEED_10000; | ||
2947 | } | ||
2948 | |||
2813 | /* clear LASI indication*/ | 2949 | /* clear LASI indication*/ |
2814 | bnx2x_cl45_read(bp, params->port, ext_phy_type, | 2950 | bnx2x_cl45_read(bp, params->port, ext_phy_type, |
2815 | ext_phy_addr, | 2951 | ext_phy_addr, |
@@ -2820,6 +2956,8 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
2820 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: | 2956 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: |
2821 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: | 2957 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: |
2822 | { | 2958 | { |
2959 | u16 link_status = 0; | ||
2960 | u16 an1000_status = 0; | ||
2823 | if (ext_phy_type == | 2961 | if (ext_phy_type == |
2824 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) { | 2962 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) { |
2825 | bnx2x_cl45_read(bp, params->port, | 2963 | bnx2x_cl45_read(bp, params->port, |
@@ -2846,14 +2984,9 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
2846 | MDIO_PMA_DEVAD, | 2984 | MDIO_PMA_DEVAD, |
2847 | MDIO_PMA_REG_LASI_STATUS, &val1); | 2985 | MDIO_PMA_REG_LASI_STATUS, &val1); |
2848 | 2986 | ||
2849 | bnx2x_cl45_read(bp, params->port, | ||
2850 | ext_phy_type, | ||
2851 | ext_phy_addr, | ||
2852 | MDIO_PMA_DEVAD, | ||
2853 | MDIO_PMA_REG_LASI_STATUS, &val2); | ||
2854 | DP(NETIF_MSG_LINK, | 2987 | DP(NETIF_MSG_LINK, |
2855 | "8703 LASI status 0x%x->0x%x\n", | 2988 | "8703 LASI status 0x%x\n", |
2856 | val1, val2); | 2989 | val1); |
2857 | } | 2990 | } |
2858 | 2991 | ||
2859 | /* clear the interrupt LASI status register */ | 2992 | /* clear the interrupt LASI status register */ |
@@ -2869,20 +3002,23 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
2869 | MDIO_PCS_REG_STATUS, &val1); | 3002 | MDIO_PCS_REG_STATUS, &val1); |
2870 | 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", |
2871 | val2, val1); | 3004 | val2, val1); |
2872 | /* Check the LASI */ | 3005 | /* Clear MSG-OUT */ |
2873 | bnx2x_cl45_read(bp, params->port, | 3006 | bnx2x_cl45_read(bp, params->port, |
2874 | ext_phy_type, | 3007 | ext_phy_type, |
2875 | ext_phy_addr, | 3008 | ext_phy_addr, |
2876 | MDIO_PMA_DEVAD, | 3009 | MDIO_PMA_DEVAD, |
2877 | MDIO_PMA_REG_RX_ALARM, &val2); | 3010 | 0xca13, |
3011 | &val1); | ||
3012 | |||
3013 | /* Check the LASI */ | ||
2878 | bnx2x_cl45_read(bp, params->port, | 3014 | bnx2x_cl45_read(bp, params->port, |
2879 | ext_phy_type, | 3015 | ext_phy_type, |
2880 | ext_phy_addr, | 3016 | ext_phy_addr, |
2881 | MDIO_PMA_DEVAD, | 3017 | MDIO_PMA_DEVAD, |
2882 | MDIO_PMA_REG_RX_ALARM, | 3018 | MDIO_PMA_REG_RX_ALARM, &val2); |
2883 | &val1); | 3019 | |
2884 | DP(NETIF_MSG_LINK, "KR 0x9003 0x%x->0x%x\n", | 3020 | DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2); |
2885 | val2, val1); | 3021 | |
2886 | /* Check the link status */ | 3022 | /* Check the link status */ |
2887 | bnx2x_cl45_read(bp, params->port, | 3023 | bnx2x_cl45_read(bp, params->port, |
2888 | ext_phy_type, | 3024 | ext_phy_type, |
@@ -2905,29 +3041,29 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
2905 | DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1); | 3041 | DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1); |
2906 | if (ext_phy_type == | 3042 | if (ext_phy_type == |
2907 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { | 3043 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { |
2908 | u16 an1000_status = 0; | 3044 | |
2909 | if (ext_phy_link_up && | 3045 | if (ext_phy_link_up && |
2910 | ( | 3046 | ((params->req_line_speed != |
2911 | (params->req_line_speed != SPEED_10000) | 3047 | SPEED_10000))) { |
2912 | )) { | ||
2913 | if (bnx2x_bcm8073_xaui_wa(params) | 3048 | if (bnx2x_bcm8073_xaui_wa(params) |
2914 | != 0) { | 3049 | != 0) { |
2915 | ext_phy_link_up = 0; | 3050 | ext_phy_link_up = 0; |
2916 | break; | 3051 | break; |
2917 | } | 3052 | } |
2918 | bnx2x_cl45_read(bp, params->port, | 3053 | } |
3054 | bnx2x_cl45_read(bp, params->port, | ||
2919 | ext_phy_type, | 3055 | ext_phy_type, |
2920 | ext_phy_addr, | 3056 | ext_phy_addr, |
2921 | MDIO_XS_DEVAD, | 3057 | MDIO_AN_DEVAD, |
2922 | 0x8304, | 3058 | 0x8304, |
2923 | &an1000_status); | 3059 | &an1000_status); |
2924 | bnx2x_cl45_read(bp, params->port, | 3060 | bnx2x_cl45_read(bp, params->port, |
2925 | ext_phy_type, | 3061 | ext_phy_type, |
2926 | ext_phy_addr, | 3062 | ext_phy_addr, |
2927 | MDIO_XS_DEVAD, | 3063 | MDIO_AN_DEVAD, |
2928 | 0x8304, | 3064 | 0x8304, |
2929 | &an1000_status); | 3065 | &an1000_status); |
2930 | } | 3066 | |
2931 | /* Check the link status on 1.1.2 */ | 3067 | /* Check the link status on 1.1.2 */ |
2932 | bnx2x_cl45_read(bp, params->port, | 3068 | bnx2x_cl45_read(bp, params->port, |
2933 | ext_phy_type, | 3069 | ext_phy_type, |
@@ -2943,8 +3079,8 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
2943 | "an_link_status=0x%x\n", | 3079 | "an_link_status=0x%x\n", |
2944 | val2, val1, an1000_status); | 3080 | val2, val1, an1000_status); |
2945 | 3081 | ||
2946 | ext_phy_link_up = (((val1 & 4) == 4) || | 3082 | ext_phy_link_up = (((val1 & 4) == 4) || |
2947 | (an1000_status & (1<<1))); | 3083 | (an1000_status & (1<<1))); |
2948 | if (ext_phy_link_up && | 3084 | if (ext_phy_link_up && |
2949 | bnx2x_8073_is_snr_needed(params)) { | 3085 | bnx2x_8073_is_snr_needed(params)) { |
2950 | /* The SNR will improve about 2dbby | 3086 | /* The SNR will improve about 2dbby |
@@ -2968,8 +3104,74 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
2968 | MDIO_PMA_REG_CDR_BANDWIDTH, | 3104 | MDIO_PMA_REG_CDR_BANDWIDTH, |
2969 | 0x0333); | 3105 | 0x0333); |
2970 | 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); | ||
2971 | } | 3171 | } |
2972 | } | 3172 | } |
3173 | |||
3174 | |||
2973 | break; | 3175 | break; |
2974 | } | 3176 | } |
2975 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: | 3177 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: |
@@ -3006,6 +3208,7 @@ static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, | |||
3006 | MDIO_AN_DEVAD, | 3208 | MDIO_AN_DEVAD, |
3007 | MDIO_AN_REG_MASTER_STATUS, | 3209 | MDIO_AN_REG_MASTER_STATUS, |
3008 | &val2); | 3210 | &val2); |
3211 | vars->line_speed = SPEED_10000; | ||
3009 | DP(NETIF_MSG_LINK, | 3212 | DP(NETIF_MSG_LINK, |
3010 | "SFX7101 AN status 0x%x->Master=%x\n", | 3213 | "SFX7101 AN status 0x%x->Master=%x\n", |
3011 | val2, | 3214 | val2, |
@@ -3100,7 +3303,7 @@ static void bnx2x_link_int_enable(struct link_params *params) | |||
3100 | * link management | 3303 | * link management |
3101 | */ | 3304 | */ |
3102 | static void bnx2x_link_int_ack(struct link_params *params, | 3305 | static void bnx2x_link_int_ack(struct link_params *params, |
3103 | struct link_vars *vars, u16 is_10g) | 3306 | struct link_vars *vars, u8 is_10g) |
3104 | { | 3307 | { |
3105 | struct bnx2x *bp = params->bp; | 3308 | struct bnx2x *bp = params->bp; |
3106 | u8 port = params->port; | 3309 | u8 port = params->port; |
@@ -3181,7 +3384,8 @@ static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len) | |||
3181 | } | 3384 | } |
3182 | 3385 | ||
3183 | 3386 | ||
3184 | static void bnx2x_turn_on_sf(struct bnx2x *bp, u8 port, u8 ext_phy_addr) | 3387 | static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr, |
3388 | u32 ext_phy_type) | ||
3185 | { | 3389 | { |
3186 | u32 cnt = 0; | 3390 | u32 cnt = 0; |
3187 | u16 ctrl = 0; | 3391 | u16 ctrl = 0; |
@@ -3192,12 +3396,14 @@ static void bnx2x_turn_on_sf(struct bnx2x *bp, u8 port, u8 ext_phy_addr) | |||
3192 | 3396 | ||
3193 | /* take ext phy out of reset */ | 3397 | /* take ext phy out of reset */ |
3194 | bnx2x_set_gpio(bp, | 3398 | bnx2x_set_gpio(bp, |
3195 | MISC_REGISTERS_GPIO_2, | 3399 | MISC_REGISTERS_GPIO_2, |
3196 | MISC_REGISTERS_GPIO_HIGH); | 3400 | MISC_REGISTERS_GPIO_HIGH, |
3401 | port); | ||
3197 | 3402 | ||
3198 | bnx2x_set_gpio(bp, | 3403 | bnx2x_set_gpio(bp, |
3199 | MISC_REGISTERS_GPIO_1, | 3404 | MISC_REGISTERS_GPIO_1, |
3200 | MISC_REGISTERS_GPIO_HIGH); | 3405 | MISC_REGISTERS_GPIO_HIGH, |
3406 | port); | ||
3201 | 3407 | ||
3202 | /* wait for 5ms */ | 3408 | /* wait for 5ms */ |
3203 | msleep(5); | 3409 | msleep(5); |
@@ -3205,7 +3411,7 @@ static void bnx2x_turn_on_sf(struct bnx2x *bp, u8 port, u8 ext_phy_addr) | |||
3205 | for (cnt = 0; cnt < 1000; cnt++) { | 3411 | for (cnt = 0; cnt < 1000; cnt++) { |
3206 | msleep(1); | 3412 | msleep(1); |
3207 | bnx2x_cl45_read(bp, port, | 3413 | bnx2x_cl45_read(bp, port, |
3208 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, | 3414 | ext_phy_type, |
3209 | ext_phy_addr, | 3415 | ext_phy_addr, |
3210 | MDIO_PMA_DEVAD, | 3416 | MDIO_PMA_DEVAD, |
3211 | MDIO_PMA_REG_CTRL, | 3417 | MDIO_PMA_REG_CTRL, |
@@ -3217,13 +3423,17 @@ static void bnx2x_turn_on_sf(struct bnx2x *bp, u8 port, u8 ext_phy_addr) | |||
3217 | } | 3423 | } |
3218 | } | 3424 | } |
3219 | 3425 | ||
3220 | static void bnx2x_turn_off_sf(struct bnx2x *bp) | 3426 | static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port) |
3221 | { | 3427 | { |
3222 | /* put sf to reset */ | 3428 | /* put sf to reset */ |
3223 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, MISC_REGISTERS_GPIO_LOW); | ||
3224 | bnx2x_set_gpio(bp, | 3429 | bnx2x_set_gpio(bp, |
3225 | MISC_REGISTERS_GPIO_2, | 3430 | MISC_REGISTERS_GPIO_1, |
3226 | MISC_REGISTERS_GPIO_LOW); | 3431 | MISC_REGISTERS_GPIO_LOW, |
3432 | port); | ||
3433 | bnx2x_set_gpio(bp, | ||
3434 | MISC_REGISTERS_GPIO_2, | ||
3435 | MISC_REGISTERS_GPIO_LOW, | ||
3436 | port); | ||
3227 | } | 3437 | } |
3228 | 3438 | ||
3229 | u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, | 3439 | u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, |
@@ -3253,7 +3463,8 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, | |||
3253 | 3463 | ||
3254 | /* Take ext phy out of reset */ | 3464 | /* Take ext phy out of reset */ |
3255 | if (!driver_loaded) | 3465 | if (!driver_loaded) |
3256 | bnx2x_turn_on_sf(bp, params->port, ext_phy_addr); | 3466 | bnx2x_turn_on_ef(bp, params->port, ext_phy_addr, |
3467 | ext_phy_type); | ||
3257 | 3468 | ||
3258 | /* wait for 1ms */ | 3469 | /* wait for 1ms */ |
3259 | msleep(1); | 3470 | msleep(1); |
@@ -3276,11 +3487,16 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, | |||
3276 | version[4] = '\0'; | 3487 | version[4] = '\0'; |
3277 | 3488 | ||
3278 | if (!driver_loaded) | 3489 | if (!driver_loaded) |
3279 | bnx2x_turn_off_sf(bp); | 3490 | bnx2x_turn_off_sf(bp, params->port); |
3280 | break; | 3491 | break; |
3281 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: | 3492 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: |
3282 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: | 3493 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: |
3283 | { | 3494 | { |
3495 | /* Take ext phy out of reset */ | ||
3496 | if (!driver_loaded) | ||
3497 | bnx2x_turn_on_ef(bp, params->port, ext_phy_addr, | ||
3498 | ext_phy_type); | ||
3499 | |||
3284 | bnx2x_cl45_read(bp, params->port, ext_phy_type, | 3500 | bnx2x_cl45_read(bp, params->port, ext_phy_type, |
3285 | ext_phy_addr, | 3501 | ext_phy_addr, |
3286 | MDIO_PMA_DEVAD, | 3502 | MDIO_PMA_DEVAD, |
@@ -3333,7 +3549,7 @@ static void bnx2x_set_xgxs_loopback(struct link_params *params, | |||
3333 | struct bnx2x *bp = params->bp; | 3549 | struct bnx2x *bp = params->bp; |
3334 | 3550 | ||
3335 | if (is_10g) { | 3551 | if (is_10g) { |
3336 | u32 md_devad; | 3552 | u32 md_devad; |
3337 | 3553 | ||
3338 | DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n"); | 3554 | DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n"); |
3339 | 3555 | ||
@@ -3553,6 +3769,8 @@ u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed, | |||
3553 | u16 hw_led_mode, u32 chip_id) | 3769 | u16 hw_led_mode, u32 chip_id) |
3554 | { | 3770 | { |
3555 | u8 rc = 0; | 3771 | u8 rc = 0; |
3772 | u32 tmp; | ||
3773 | u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; | ||
3556 | DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode); | 3774 | DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode); |
3557 | DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n", | 3775 | DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n", |
3558 | speed, hw_led_mode); | 3776 | speed, hw_led_mode); |
@@ -3561,6 +3779,9 @@ u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed, | |||
3561 | REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0); | 3779 | REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0); |
3562 | REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, | 3780 | REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, |
3563 | SHARED_HW_CFG_LED_MAC1); | 3781 | SHARED_HW_CFG_LED_MAC1); |
3782 | |||
3783 | tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); | ||
3784 | EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE)); | ||
3564 | break; | 3785 | break; |
3565 | 3786 | ||
3566 | case LED_MODE_OPER: | 3787 | case LED_MODE_OPER: |
@@ -3572,6 +3793,10 @@ u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed, | |||
3572 | LED_BLINK_RATE_VAL); | 3793 | LED_BLINK_RATE_VAL); |
3573 | REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 + | 3794 | REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 + |
3574 | port*4, 1); | 3795 | port*4, 1); |
3796 | tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); | ||
3797 | EMAC_WR(bp, EMAC_REG_EMAC_LED, | ||
3798 | (tmp & (~EMAC_LED_OVERRIDE))); | ||
3799 | |||
3575 | if (!CHIP_IS_E1H(bp) && | 3800 | if (!CHIP_IS_E1H(bp) && |
3576 | ((speed == SPEED_2500) || | 3801 | ((speed == SPEED_2500) || |
3577 | (speed == SPEED_1000) || | 3802 | (speed == SPEED_1000) || |
@@ -3622,7 +3847,8 @@ static u8 bnx2x_link_initialize(struct link_params *params, | |||
3622 | struct bnx2x *bp = params->bp; | 3847 | struct bnx2x *bp = params->bp; |
3623 | u8 port = params->port; | 3848 | u8 port = params->port; |
3624 | u8 rc = 0; | 3849 | u8 rc = 0; |
3625 | 3850 | u8 non_ext_phy; | |
3851 | u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); | ||
3626 | /* Activate the external PHY */ | 3852 | /* Activate the external PHY */ |
3627 | bnx2x_ext_phy_reset(params, vars); | 3853 | bnx2x_ext_phy_reset(params, vars); |
3628 | 3854 | ||
@@ -3644,10 +3870,6 @@ static u8 bnx2x_link_initialize(struct link_params *params, | |||
3644 | bnx2x_set_swap_lanes(params); | 3870 | bnx2x_set_swap_lanes(params); |
3645 | } | 3871 | } |
3646 | 3872 | ||
3647 | /* Set Parallel Detect */ | ||
3648 | if (params->req_line_speed == SPEED_AUTO_NEG) | ||
3649 | bnx2x_set_parallel_detection(params, vars->phy_flags); | ||
3650 | |||
3651 | if (vars->phy_flags & PHY_XGXS_FLAG) { | 3873 | if (vars->phy_flags & PHY_XGXS_FLAG) { |
3652 | if (params->req_line_speed && | 3874 | if (params->req_line_speed && |
3653 | ((params->req_line_speed == SPEED_100) || | 3875 | ((params->req_line_speed == SPEED_100) || |
@@ -3657,68 +3879,33 @@ static u8 bnx2x_link_initialize(struct link_params *params, | |||
3657 | vars->phy_flags &= ~PHY_SGMII_FLAG; | 3879 | vars->phy_flags &= ~PHY_SGMII_FLAG; |
3658 | } | 3880 | } |
3659 | } | 3881 | } |
3882 | /* In case of external phy existance, the line speed would be the | ||
3883 | line speed linked up by the external phy. In case it is direct only, | ||
3884 | then the line_speed during initialization will be equal to the | ||
3885 | req_line_speed*/ | ||
3886 | vars->line_speed = params->req_line_speed; | ||
3660 | 3887 | ||
3661 | if (!(vars->phy_flags & PHY_SGMII_FLAG)) { | 3888 | bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc); |
3662 | u16 bank, rx_eq; | ||
3663 | |||
3664 | rx_eq = ((params->serdes_config & | ||
3665 | PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >> | ||
3666 | PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT); | ||
3667 | 3889 | ||
3668 | DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq); | 3890 | /* init ext phy and enable link state int */ |
3669 | for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL; | 3891 | non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) || |
3670 | bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) { | 3892 | (params->loopback_mode == LOOPBACK_XGXS_10) || |
3671 | CL45_WR_OVER_CL22(bp, port, | 3893 | (params->loopback_mode == LOOPBACK_EXT_PHY)); |
3672 | params->phy_addr, | 3894 | |
3673 | bank , | 3895 | if (non_ext_phy || |
3674 | MDIO_RX0_RX_EQ_BOOST, | 3896 | (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705)) { |
3675 | ((rx_eq & | 3897 | if (params->req_line_speed == SPEED_AUTO_NEG) |
3676 | MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) | | 3898 | bnx2x_set_parallel_detection(params, vars->phy_flags); |
3677 | MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL)); | 3899 | bnx2x_init_internal_phy(params, vars); |
3678 | } | ||
3679 | |||
3680 | /* forced speed requested? */ | ||
3681 | if (params->req_line_speed != SPEED_AUTO_NEG) { | ||
3682 | DP(NETIF_MSG_LINK, "not SGMII, no AN\n"); | ||
3683 | |||
3684 | /* disable autoneg */ | ||
3685 | bnx2x_set_autoneg(params, vars); | ||
3686 | |||
3687 | /* program speed and duplex */ | ||
3688 | bnx2x_program_serdes(params); | ||
3689 | vars->ieee_fc = | ||
3690 | MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE; | ||
3691 | |||
3692 | } else { /* AN_mode */ | ||
3693 | DP(NETIF_MSG_LINK, "not SGMII, AN\n"); | ||
3694 | |||
3695 | /* AN enabled */ | ||
3696 | bnx2x_set_brcm_cl37_advertisment(params); | ||
3697 | |||
3698 | /* program duplex & pause advertisement (for aneg) */ | ||
3699 | bnx2x_set_ieee_aneg_advertisment(params, | ||
3700 | &vars->ieee_fc); | ||
3701 | |||
3702 | /* enable autoneg */ | ||
3703 | bnx2x_set_autoneg(params, vars); | ||
3704 | |||
3705 | /* enable and restart AN */ | ||
3706 | bnx2x_restart_autoneg(params); | ||
3707 | } | ||
3708 | |||
3709 | } else { /* SGMII mode */ | ||
3710 | DP(NETIF_MSG_LINK, "SGMII\n"); | ||
3711 | |||
3712 | bnx2x_initialize_sgmii_process(params); | ||
3713 | } | 3900 | } |
3714 | 3901 | ||
3715 | /* init ext phy and enable link state int */ | 3902 | if (!non_ext_phy) |
3716 | rc |= bnx2x_ext_phy_init(params, vars); | 3903 | rc |= bnx2x_ext_phy_init(params, vars); |
3717 | 3904 | ||
3718 | bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, | 3905 | bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, |
3719 | (NIG_STATUS_XGXS0_LINK10G | | 3906 | (NIG_STATUS_XGXS0_LINK10G | |
3720 | NIG_STATUS_XGXS0_LINK_STATUS | | 3907 | NIG_STATUS_XGXS0_LINK_STATUS | |
3721 | NIG_STATUS_SERDES0_LINK_STATUS)); | 3908 | NIG_STATUS_SERDES0_LINK_STATUS)); |
3722 | 3909 | ||
3723 | return rc; | 3910 | return rc; |
3724 | 3911 | ||
@@ -3730,15 +3917,23 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) | |||
3730 | struct bnx2x *bp = params->bp; | 3917 | struct bnx2x *bp = params->bp; |
3731 | 3918 | ||
3732 | u32 val; | 3919 | u32 val; |
3733 | DP(NETIF_MSG_LINK, "Phy Initialization started\n"); | 3920 | DP(NETIF_MSG_LINK, "Phy Initialization started \n"); |
3734 | DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n", | 3921 | DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n", |
3735 | params->req_line_speed, params->req_flow_ctrl); | 3922 | params->req_line_speed, params->req_flow_ctrl); |
3736 | vars->link_status = 0; | 3923 | vars->link_status = 0; |
3924 | vars->phy_link_up = 0; | ||
3925 | vars->link_up = 0; | ||
3926 | vars->line_speed = 0; | ||
3927 | vars->duplex = DUPLEX_FULL; | ||
3928 | vars->flow_ctrl = FLOW_CTRL_NONE; | ||
3929 | vars->mac_type = MAC_TYPE_NONE; | ||
3930 | |||
3737 | if (params->switch_cfg == SWITCH_CFG_1G) | 3931 | if (params->switch_cfg == SWITCH_CFG_1G) |
3738 | vars->phy_flags = PHY_SERDES_FLAG; | 3932 | vars->phy_flags = PHY_SERDES_FLAG; |
3739 | else | 3933 | else |
3740 | vars->phy_flags = PHY_XGXS_FLAG; | 3934 | vars->phy_flags = PHY_XGXS_FLAG; |
3741 | 3935 | ||
3936 | |||
3742 | /* disable attentions */ | 3937 | /* disable attentions */ |
3743 | bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4, | 3938 | bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4, |
3744 | (NIG_MASK_XGXS0_LINK_STATUS | | 3939 | (NIG_MASK_XGXS0_LINK_STATUS | |
@@ -3894,6 +4089,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) | |||
3894 | } | 4089 | } |
3895 | 4090 | ||
3896 | bnx2x_link_initialize(params, vars); | 4091 | bnx2x_link_initialize(params, vars); |
4092 | msleep(30); | ||
3897 | bnx2x_link_int_enable(params); | 4093 | bnx2x_link_int_enable(params); |
3898 | } | 4094 | } |
3899 | return 0; | 4095 | return 0; |
@@ -3943,39 +4139,22 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars) | |||
3943 | /* HW reset */ | 4139 | /* HW reset */ |
3944 | 4140 | ||
3945 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, | 4141 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, |
3946 | MISC_REGISTERS_GPIO_OUTPUT_LOW); | 4142 | MISC_REGISTERS_GPIO_OUTPUT_LOW, |
4143 | port); | ||
3947 | 4144 | ||
3948 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, | 4145 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, |
3949 | MISC_REGISTERS_GPIO_OUTPUT_LOW); | 4146 | MISC_REGISTERS_GPIO_OUTPUT_LOW, |
4147 | port); | ||
3950 | 4148 | ||
3951 | DP(NETIF_MSG_LINK, "reset external PHY\n"); | 4149 | DP(NETIF_MSG_LINK, "reset external PHY\n"); |
3952 | } else { | 4150 | } else if (ext_phy_type == |
3953 | 4151 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { | |
3954 | u8 ext_phy_addr = ((ext_phy_config & | 4152 | DP(NETIF_MSG_LINK, "Setting 8073 port %d into " |
3955 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | ||
3956 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | ||
3957 | |||
3958 | /* SW reset */ | ||
3959 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | ||
3960 | MDIO_PMA_DEVAD, | ||
3961 | MDIO_PMA_REG_CTRL, | ||
3962 | 1<<15); | ||
3963 | |||
3964 | /* Set Low Power Mode */ | ||
3965 | bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, | ||
3966 | MDIO_PMA_DEVAD, | ||
3967 | MDIO_PMA_REG_CTRL, | ||
3968 | 1<<11); | ||
3969 | |||
3970 | |||
3971 | if (ext_phy_type == | ||
3972 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { | ||
3973 | DP(NETIF_MSG_LINK, "Setting 8073 port %d into" | ||
3974 | "low power mode\n", | 4153 | "low power mode\n", |
3975 | port); | 4154 | port); |
3976 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, | 4155 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, |
3977 | MISC_REGISTERS_GPIO_OUTPUT_LOW); | 4156 | MISC_REGISTERS_GPIO_OUTPUT_LOW, |
3978 | } | 4157 | port); |
3979 | } | 4158 | } |
3980 | } | 4159 | } |
3981 | /* reset the SerDes/XGXS */ | 4160 | /* reset the SerDes/XGXS */ |
@@ -3995,6 +4174,73 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars) | |||
3995 | return 0; | 4174 | return 0; |
3996 | } | 4175 | } |
3997 | 4176 | ||
4177 | static u8 bnx2x_update_link_down(struct link_params *params, | ||
4178 | struct link_vars *vars) | ||
4179 | { | ||
4180 | struct bnx2x *bp = params->bp; | ||
4181 | u8 port = params->port; | ||
4182 | DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port); | ||
4183 | bnx2x_set_led(bp, port, LED_MODE_OFF, | ||
4184 | 0, params->hw_led_mode, | ||
4185 | params->chip_id); | ||
4186 | |||
4187 | /* indicate no mac active */ | ||
4188 | vars->mac_type = MAC_TYPE_NONE; | ||
4189 | |||
4190 | /* update shared memory */ | ||
4191 | vars->link_status = 0; | ||
4192 | vars->line_speed = 0; | ||
4193 | bnx2x_update_mng(params, vars->link_status); | ||
4194 | |||
4195 | /* activate nig drain */ | ||
4196 | REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); | ||
4197 | |||
4198 | /* reset BigMac */ | ||
4199 | bnx2x_bmac_rx_disable(bp, params->port); | ||
4200 | REG_WR(bp, GRCBASE_MISC + | ||
4201 | MISC_REGISTERS_RESET_REG_2_CLEAR, | ||
4202 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); | ||
4203 | return 0; | ||
4204 | } | ||
4205 | |||
4206 | static u8 bnx2x_update_link_up(struct link_params *params, | ||
4207 | struct link_vars *vars, | ||
4208 | u8 link_10g, u32 gp_status) | ||
4209 | { | ||
4210 | struct bnx2x *bp = params->bp; | ||
4211 | u8 port = params->port; | ||
4212 | u8 rc = 0; | ||
4213 | vars->link_status |= LINK_STATUS_LINK_UP; | ||
4214 | if (link_10g) { | ||
4215 | bnx2x_bmac_enable(params, vars, 0); | ||
4216 | bnx2x_set_led(bp, port, LED_MODE_OPER, | ||
4217 | SPEED_10000, params->hw_led_mode, | ||
4218 | params->chip_id); | ||
4219 | |||
4220 | } else { | ||
4221 | bnx2x_emac_enable(params, vars, 0); | ||
4222 | rc = bnx2x_emac_program(params, vars->line_speed, | ||
4223 | vars->duplex); | ||
4224 | |||
4225 | /* AN complete? */ | ||
4226 | if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { | ||
4227 | if (!(vars->phy_flags & | ||
4228 | PHY_SGMII_FLAG)) | ||
4229 | bnx2x_set_sgmii_tx_driver(params); | ||
4230 | } | ||
4231 | } | ||
4232 | |||
4233 | /* PBF - link up */ | ||
4234 | rc |= bnx2x_pbf_update(params, vars->flow_ctrl, | ||
4235 | vars->line_speed); | ||
4236 | |||
4237 | /* disable drain */ | ||
4238 | REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0); | ||
4239 | |||
4240 | /* update shared memory */ | ||
4241 | bnx2x_update_mng(params, vars->link_status); | ||
4242 | return rc; | ||
4243 | } | ||
3998 | /* This function should called upon link interrupt */ | 4244 | /* This function should called upon link interrupt */ |
3999 | /* In case vars->link_up, driver needs to | 4245 | /* In case vars->link_up, driver needs to |
4000 | 1. Update the pbf | 4246 | 1. Update the pbf |
@@ -4012,10 +4258,10 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
4012 | { | 4258 | { |
4013 | struct bnx2x *bp = params->bp; | 4259 | struct bnx2x *bp = params->bp; |
4014 | u8 port = params->port; | 4260 | u8 port = params->port; |
4015 | u16 i; | ||
4016 | u16 gp_status; | 4261 | u16 gp_status; |
4017 | u16 link_10g; | 4262 | u8 link_10g; |
4018 | u8 rc = 0; | 4263 | u8 ext_phy_link_up, rc = 0; |
4264 | u32 ext_phy_type; | ||
4019 | 4265 | ||
4020 | DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", | 4266 | DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", |
4021 | port, | 4267 | port, |
@@ -4031,15 +4277,16 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
4031 | REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), | 4277 | REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), |
4032 | REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); | 4278 | REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); |
4033 | 4279 | ||
4280 | ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); | ||
4034 | 4281 | ||
4035 | /* avoid fast toggling */ | 4282 | /* Check external link change only for non-direct */ |
4036 | for (i = 0; i < 10; i++) { | 4283 | ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars); |
4037 | msleep(10); | 4284 | |
4038 | CL45_RD_OVER_CL22(bp, port, params->phy_addr, | 4285 | /* Read gp_status */ |
4039 | MDIO_REG_BANK_GP_STATUS, | 4286 | CL45_RD_OVER_CL22(bp, port, params->phy_addr, |
4040 | MDIO_GP_STATUS_TOP_AN_STATUS1, | 4287 | MDIO_REG_BANK_GP_STATUS, |
4041 | &gp_status); | 4288 | MDIO_GP_STATUS_TOP_AN_STATUS1, |
4042 | } | 4289 | &gp_status); |
4043 | 4290 | ||
4044 | rc = bnx2x_link_settings_status(params, vars, gp_status); | 4291 | rc = bnx2x_link_settings_status(params, vars, gp_status); |
4045 | if (rc != 0) | 4292 | if (rc != 0) |
@@ -4055,73 +4302,177 @@ u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
4055 | 4302 | ||
4056 | bnx2x_link_int_ack(params, vars, link_10g); | 4303 | bnx2x_link_int_ack(params, vars, link_10g); |
4057 | 4304 | ||
4305 | /* In case external phy link is up, and internal link is down | ||
4306 | ( not initialized yet probably after link initialization, it needs | ||
4307 | to be initialized. | ||
4308 | Note that after link down-up as result of cable plug, | ||
4309 | the xgxs link would probably become up again without the need to | ||
4310 | initialize it*/ | ||
4311 | |||
4312 | if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) && | ||
4313 | (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) && | ||
4314 | (ext_phy_link_up && !vars->phy_link_up)) | ||
4315 | bnx2x_init_internal_phy(params, vars); | ||
4316 | |||
4058 | /* link is up only if both local phy and external phy are up */ | 4317 | /* link is up only if both local phy and external phy are up */ |
4059 | vars->link_up = (vars->phy_link_up && | 4318 | vars->link_up = (ext_phy_link_up && vars->phy_link_up); |
4060 | bnx2x_ext_phy_is_link_up(params, vars)); | ||
4061 | 4319 | ||
4062 | if (!vars->phy_link_up && | 4320 | if (vars->link_up) |
4063 | REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18)) { | 4321 | rc = bnx2x_update_link_up(params, vars, link_10g, gp_status); |
4064 | bnx2x_ext_phy_is_link_up(params, vars); /* Clear interrupt */ | 4322 | else |
4323 | rc = bnx2x_update_link_down(params, vars); | ||
4324 | |||
4325 | return rc; | ||
4326 | } | ||
4327 | |||
4328 | static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) | ||
4329 | { | ||
4330 | u8 ext_phy_addr[PORT_MAX]; | ||
4331 | u16 val; | ||
4332 | s8 port; | ||
4333 | |||
4334 | /* PART1 - Reset both phys */ | ||
4335 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { | ||
4336 | /* Extract the ext phy address for the port */ | ||
4337 | u32 ext_phy_config = REG_RD(bp, shmem_base + | ||
4338 | offsetof(struct shmem_region, | ||
4339 | dev_info.port_hw_config[port].external_phy_config)); | ||
4340 | |||
4341 | /* disable attentions */ | ||
4342 | bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, | ||
4343 | (NIG_MASK_XGXS0_LINK_STATUS | | ||
4344 | NIG_MASK_XGXS0_LINK10G | | ||
4345 | NIG_MASK_SERDES0_LINK_STATUS | | ||
4346 | NIG_MASK_MI_INT)); | ||
4347 | |||
4348 | ext_phy_addr[port] = | ||
4349 | ((ext_phy_config & | ||
4350 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> | ||
4351 | PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT); | ||
4352 | |||
4353 | /* Need to take the phy out of low power mode in order | ||
4354 | to write to access its registers */ | ||
4355 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, | ||
4356 | MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); | ||
4357 | |||
4358 | /* Reset the phy */ | ||
4359 | bnx2x_cl45_write(bp, port, | ||
4360 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
4361 | ext_phy_addr[port], | ||
4362 | MDIO_PMA_DEVAD, | ||
4363 | MDIO_PMA_REG_CTRL, | ||
4364 | 1<<15); | ||
4065 | } | 4365 | } |
4066 | 4366 | ||
4067 | if (vars->link_up) { | 4367 | /* Add delay of 150ms after reset */ |
4068 | vars->link_status |= LINK_STATUS_LINK_UP; | 4368 | msleep(150); |
4069 | if (link_10g) { | ||
4070 | bnx2x_bmac_enable(params, vars, 0); | ||
4071 | bnx2x_set_led(bp, port, LED_MODE_OPER, | ||
4072 | SPEED_10000, params->hw_led_mode, | ||
4073 | params->chip_id); | ||
4074 | 4369 | ||
4075 | } else { | 4370 | /* PART2 - Download firmware to both phys */ |
4076 | bnx2x_emac_enable(params, vars, 0); | 4371 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { |
4077 | rc = bnx2x_emac_program(params, vars->line_speed, | 4372 | u16 fw_ver1; |
4078 | vars->duplex); | ||
4079 | 4373 | ||
4080 | /* AN complete? */ | 4374 | bnx2x_bcm8073_external_rom_boot(bp, port, |
4081 | if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { | 4375 | ext_phy_addr[port]); |
4082 | if (!(vars->phy_flags & | 4376 | |
4083 | PHY_SGMII_FLAG)) | 4377 | bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, |
4084 | bnx2x_set_sgmii_tx_driver(params); | 4378 | ext_phy_addr[port], |
4085 | } | 4379 | MDIO_PMA_DEVAD, |
4380 | MDIO_PMA_REG_ROM_VER1, &fw_ver1); | ||
4381 | if (fw_ver1 == 0) { | ||
4382 | DP(NETIF_MSG_LINK, | ||
4383 | "bnx2x_8073_common_init_phy port %x " | ||
4384 | "fw Download failed\n", port); | ||
4385 | return -EINVAL; | ||
4086 | } | 4386 | } |
4087 | 4387 | ||
4088 | /* PBF - link up */ | 4388 | /* Only set bit 10 = 1 (Tx power down) */ |
4089 | rc |= bnx2x_pbf_update(params, vars->flow_ctrl, | 4389 | bnx2x_cl45_read(bp, port, |
4090 | vars->line_speed); | 4390 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, |
4391 | ext_phy_addr[port], | ||
4392 | MDIO_PMA_DEVAD, | ||
4393 | MDIO_PMA_REG_TX_POWER_DOWN, &val); | ||
4091 | 4394 | ||
4092 | /* disable drain */ | 4395 | /* Phase1 of TX_POWER_DOWN reset */ |
4093 | REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0); | 4396 | bnx2x_cl45_write(bp, port, |
4397 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
4398 | ext_phy_addr[port], | ||
4399 | MDIO_PMA_DEVAD, | ||
4400 | MDIO_PMA_REG_TX_POWER_DOWN, | ||
4401 | (val | 1<<10)); | ||
4402 | } | ||
4094 | 4403 | ||
4095 | /* update shared memory */ | 4404 | /* Toggle Transmitter: Power down and then up with 600ms |
4096 | bnx2x_update_mng(params, vars->link_status); | 4405 | delay between */ |
4406 | msleep(600); | ||
4097 | 4407 | ||
4098 | } else { /* link down */ | 4408 | /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */ |
4099 | DP(NETIF_MSG_LINK, "Port %x: Link is down\n", params->port); | 4409 | for (port = PORT_MAX - 1; port >= PORT_0; port--) { |
4100 | bnx2x_set_led(bp, port, LED_MODE_OFF, | 4410 | /* Phase2 of POWER_DOWN_RESET*/ |
4101 | 0, params->hw_led_mode, | 4411 | /* Release bit 10 (Release Tx power down) */ |
4102 | params->chip_id); | 4412 | bnx2x_cl45_read(bp, port, |
4413 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
4414 | ext_phy_addr[port], | ||
4415 | MDIO_PMA_DEVAD, | ||
4416 | MDIO_PMA_REG_TX_POWER_DOWN, &val); | ||
4103 | 4417 | ||
4104 | /* indicate no mac active */ | 4418 | bnx2x_cl45_write(bp, port, |
4105 | vars->mac_type = MAC_TYPE_NONE; | 4419 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, |
4420 | ext_phy_addr[port], | ||
4421 | MDIO_PMA_DEVAD, | ||
4422 | MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10)))); | ||
4423 | msleep(15); | ||
4106 | 4424 | ||
4107 | /* update shared memory */ | 4425 | /* Read modify write the SPI-ROM version select register */ |
4108 | vars->link_status = 0; | 4426 | bnx2x_cl45_read(bp, port, |
4109 | bnx2x_update_mng(params, vars->link_status); | 4427 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, |
4428 | ext_phy_addr[port], | ||
4429 | MDIO_PMA_DEVAD, | ||
4430 | MDIO_PMA_REG_EDC_FFE_MAIN, &val); | ||
4431 | bnx2x_cl45_write(bp, port, | ||
4432 | PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, | ||
4433 | ext_phy_addr[port], | ||
4434 | MDIO_PMA_DEVAD, | ||
4435 | MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12))); | ||
4110 | 4436 | ||
4111 | /* activate nig drain */ | 4437 | /* set GPIO2 back to LOW */ |
4112 | REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); | 4438 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, |
4439 | MISC_REGISTERS_GPIO_OUTPUT_LOW, port); | ||
4440 | } | ||
4441 | return 0; | ||
4113 | 4442 | ||
4114 | /* reset BigMac */ | 4443 | } |
4115 | bnx2x_bmac_rx_disable(bp, params->port); | ||
4116 | REG_WR(bp, GRCBASE_MISC + | ||
4117 | MISC_REGISTERS_RESET_REG_2_CLEAR, | ||
4118 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); | ||
4119 | 4444 | ||
4445 | u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base) | ||
4446 | { | ||
4447 | u8 rc = 0; | ||
4448 | u32 ext_phy_type; | ||
4449 | |||
4450 | DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n"); | ||
4451 | |||
4452 | /* Read the ext_phy_type for arbitrary port(0) */ | ||
4453 | ext_phy_type = XGXS_EXT_PHY_TYPE( | ||
4454 | REG_RD(bp, shmem_base + | ||
4455 | offsetof(struct shmem_region, | ||
4456 | dev_info.port_hw_config[0].external_phy_config))); | ||
4457 | |||
4458 | switch (ext_phy_type) { | ||
4459 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: | ||
4460 | { | ||
4461 | rc = bnx2x_8073_common_init_phy(bp, shmem_base); | ||
4462 | break; | ||
4463 | } | ||
4464 | default: | ||
4465 | DP(NETIF_MSG_LINK, | ||
4466 | "bnx2x_common_init_phy: ext_phy 0x%x not required\n", | ||
4467 | ext_phy_type); | ||
4468 | break; | ||
4120 | } | 4469 | } |
4121 | 4470 | ||
4122 | return rc; | 4471 | return rc; |
4123 | } | 4472 | } |
4124 | 4473 | ||
4474 | |||
4475 | |||
4125 | static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr) | 4476 | static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr) |
4126 | { | 4477 | { |
4127 | u16 val, cnt; | 4478 | u16 val, cnt; |
@@ -4154,7 +4505,7 @@ static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr) | |||
4154 | } | 4505 | } |
4155 | #define RESERVED_SIZE 256 | 4506 | #define RESERVED_SIZE 256 |
4156 | /* max application is 160K bytes - data at end of RAM */ | 4507 | /* max application is 160K bytes - data at end of RAM */ |
4157 | #define MAX_APP_SIZE 160*1024 - RESERVED_SIZE | 4508 | #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE) |
4158 | 4509 | ||
4159 | /* Header is 14 bytes */ | 4510 | /* Header is 14 bytes */ |
4160 | #define HEADER_SIZE 14 | 4511 | #define HEADER_SIZE 14 |
@@ -4192,12 +4543,12 @@ static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port, | |||
4192 | size = MAX_APP_SIZE+HEADER_SIZE; | 4543 | size = MAX_APP_SIZE+HEADER_SIZE; |
4193 | } | 4544 | } |
4194 | DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]); | 4545 | DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]); |
4195 | DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]); | 4546 | DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]); |
4196 | /* Put the DSP in download mode by setting FLASH_CFG[2] to 1 | 4547 | /* Put the DSP in download mode by setting FLASH_CFG[2] to 1 |
4197 | and issuing a reset.*/ | 4548 | and issuing a reset.*/ |
4198 | 4549 | ||
4199 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, | 4550 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, |
4200 | MISC_REGISTERS_GPIO_HIGH); | 4551 | MISC_REGISTERS_GPIO_HIGH, port); |
4201 | 4552 | ||
4202 | bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr); | 4553 | bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr); |
4203 | 4554 | ||
@@ -4429,7 +4780,8 @@ static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port, | |||
4429 | } | 4780 | } |
4430 | 4781 | ||
4431 | /* DSP Remove Download Mode */ | 4782 | /* DSP Remove Download Mode */ |
4432 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, MISC_REGISTERS_GPIO_LOW); | 4783 | bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, |
4784 | MISC_REGISTERS_GPIO_LOW, port); | ||
4433 | 4785 | ||
4434 | bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr); | 4786 | bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr); |
4435 | 4787 | ||
@@ -4437,7 +4789,7 @@ static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port, | |||
4437 | for (cnt = 0; cnt < 100; cnt++) | 4789 | for (cnt = 0; cnt < 100; cnt++) |
4438 | msleep(5); | 4790 | msleep(5); |
4439 | 4791 | ||
4440 | bnx2x_hw_reset(bp); | 4792 | bnx2x_hw_reset(bp, port); |
4441 | 4793 | ||
4442 | for (cnt = 0; cnt < 100; cnt++) | 4794 | for (cnt = 0; cnt < 100; cnt++) |
4443 | msleep(5); | 4795 | msleep(5); |
@@ -4473,7 +4825,7 @@ static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port, | |||
4473 | MDIO_PMA_REG_7101_VER2, | 4825 | MDIO_PMA_REG_7101_VER2, |
4474 | &image_revision2); | 4826 | &image_revision2); |
4475 | 4827 | ||
4476 | if (data[0x14e] != (image_revision2&0xFF) || | 4828 | if (data[0x14e] != (image_revision2&0xFF) || |
4477 | data[0x14f] != ((image_revision2&0xFF00)>>8) || | 4829 | data[0x14f] != ((image_revision2&0xFF00)>>8) || |
4478 | data[0x150] != (image_revision1&0xFF) || | 4830 | data[0x150] != (image_revision1&0xFF) || |
4479 | data[0x151] != ((image_revision1&0xFF00)>>8)) { | 4831 | data[0x151] != ((image_revision1&0xFF00)>>8)) { |
@@ -4508,11 +4860,11 @@ u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config, | |||
4508 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: | 4860 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: |
4509 | /* Take ext phy out of reset */ | 4861 | /* Take ext phy out of reset */ |
4510 | if (!driver_loaded) | 4862 | if (!driver_loaded) |
4511 | bnx2x_turn_on_sf(bp, port, ext_phy_addr); | 4863 | bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type); |
4512 | rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr, | 4864 | rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr, |
4513 | data, size); | 4865 | data, size); |
4514 | if (!driver_loaded) | 4866 | if (!driver_loaded) |
4515 | bnx2x_turn_off_sf(bp); | 4867 | bnx2x_turn_off_sf(bp, port); |
4516 | break; | 4868 | break; |
4517 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: | 4869 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: |
4518 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: | 4870 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: |