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