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