aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x/bnx2x_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_main.c')
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c354
1 files changed, 240 insertions, 114 deletions
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index 30618c7ed4ed..f0a788467fb1 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -1227,26 +1227,66 @@ static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode)
1227 return 0; 1227 return 0;
1228} 1228}
1229 1229
1230int bnx2x_get_link_cfg_idx(struct bnx2x *bp)
1231{
1232 u32 sel_phy_idx = 0;
1233 if (bp->link_vars.link_up) {
1234 sel_phy_idx = EXT_PHY1;
1235 /* In case link is SERDES, check if the EXT_PHY2 is the one */
1236 if ((bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) &&
1237 (bp->link_params.phy[EXT_PHY2].supported & SUPPORTED_FIBRE))
1238 sel_phy_idx = EXT_PHY2;
1239 } else {
1240
1241 switch (bnx2x_phy_selection(&bp->link_params)) {
1242 case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
1243 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
1244 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
1245 sel_phy_idx = EXT_PHY1;
1246 break;
1247 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
1248 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
1249 sel_phy_idx = EXT_PHY2;
1250 break;
1251 }
1252 }
1253 /*
1254 * The selected actived PHY is always after swapping (in case PHY
1255 * swapping is enabled). So when swapping is enabled, we need to reverse
1256 * the configuration
1257 */
1258
1259 if (bp->link_params.multi_phy_config &
1260 PORT_HW_CFG_PHY_SWAPPED_ENABLED) {
1261 if (sel_phy_idx == EXT_PHY1)
1262 sel_phy_idx = EXT_PHY2;
1263 else if (sel_phy_idx == EXT_PHY2)
1264 sel_phy_idx = EXT_PHY1;
1265 }
1266 return LINK_CONFIG_IDX(sel_phy_idx);
1267}
1268
1230void bnx2x_calc_fc_adv(struct bnx2x *bp) 1269void bnx2x_calc_fc_adv(struct bnx2x *bp)
1231{ 1270{
1271 u8 cfg_idx = bnx2x_get_link_cfg_idx(bp);
1232 switch (bp->link_vars.ieee_fc & 1272 switch (bp->link_vars.ieee_fc &
1233 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) { 1273 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) {
1234 case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE: 1274 case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE:
1235 bp->port.advertising &= ~(ADVERTISED_Asym_Pause | 1275 bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause |
1236 ADVERTISED_Pause); 1276 ADVERTISED_Pause);
1237 break; 1277 break;
1238 1278
1239 case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH: 1279 case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH:
1240 bp->port.advertising |= (ADVERTISED_Asym_Pause | 1280 bp->port.advertising[cfg_idx] |= (ADVERTISED_Asym_Pause |
1241 ADVERTISED_Pause); 1281 ADVERTISED_Pause);
1242 break; 1282 break;
1243 1283
1244 case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC: 1284 case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC:
1245 bp->port.advertising |= ADVERTISED_Asym_Pause; 1285 bp->port.advertising[cfg_idx] |= ADVERTISED_Asym_Pause;
1246 break; 1286 break;
1247 1287
1248 default: 1288 default:
1249 bp->port.advertising &= ~(ADVERTISED_Asym_Pause | 1289 bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause |
1250 ADVERTISED_Pause); 1290 ADVERTISED_Pause);
1251 break; 1291 break;
1252 } 1292 }
@@ -1257,7 +1297,8 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
1257{ 1297{
1258 if (!BP_NOMCP(bp)) { 1298 if (!BP_NOMCP(bp)) {
1259 u8 rc; 1299 u8 rc;
1260 1300 int cfx_idx = bnx2x_get_link_cfg_idx(bp);
1301 u16 req_line_speed = bp->link_params.req_line_speed[cfx_idx];
1261 /* Initialize link parameters structure variables */ 1302 /* Initialize link parameters structure variables */
1262 /* It is recommended to turn off RX FC for jumbo frames 1303 /* It is recommended to turn off RX FC for jumbo frames
1263 for better performance */ 1304 for better performance */
@@ -1268,8 +1309,10 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
1268 1309
1269 bnx2x_acquire_phy_lock(bp); 1310 bnx2x_acquire_phy_lock(bp);
1270 1311
1271 if (load_mode == LOAD_DIAG) 1312 if (load_mode == LOAD_DIAG) {
1272 bp->link_params.loopback_mode = LOOPBACK_XGXS; 1313 bp->link_params.loopback_mode = LOOPBACK_XGXS;
1314 bp->link_params.req_line_speed[cfx_idx] = SPEED_10000;
1315 }
1273 1316
1274 rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars); 1317 rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars);
1275 1318
@@ -1281,7 +1324,7 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode)
1281 bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); 1324 bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP);
1282 bnx2x_link_report(bp); 1325 bnx2x_link_report(bp);
1283 } 1326 }
1284 1327 bp->link_params.req_line_speed[cfx_idx] = req_line_speed;
1285 return rc; 1328 return rc;
1286 } 1329 }
1287 BNX2X_ERR("Bootcode is missing - can not initialize link\n"); 1330 BNX2X_ERR("Bootcode is missing - can not initialize link\n");
@@ -1311,13 +1354,14 @@ static void bnx2x__link_reset(struct bnx2x *bp)
1311 BNX2X_ERR("Bootcode is missing - can not reset link\n"); 1354 BNX2X_ERR("Bootcode is missing - can not reset link\n");
1312} 1355}
1313 1356
1314u8 bnx2x_link_test(struct bnx2x *bp) 1357u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes)
1315{ 1358{
1316 u8 rc = 0; 1359 u8 rc = 0;
1317 1360
1318 if (!BP_NOMCP(bp)) { 1361 if (!BP_NOMCP(bp)) {
1319 bnx2x_acquire_phy_lock(bp); 1362 bnx2x_acquire_phy_lock(bp);
1320 rc = bnx2x_test_link(&bp->link_params, &bp->link_vars); 1363 rc = bnx2x_test_link(&bp->link_params, &bp->link_vars,
1364 is_serdes);
1321 bnx2x_release_phy_lock(bp); 1365 bnx2x_release_phy_lock(bp);
1322 } else 1366 } else
1323 BNX2X_ERR("Bootcode is missing - can not test link\n"); 1367 BNX2X_ERR("Bootcode is missing - can not test link\n");
@@ -1586,7 +1630,7 @@ static void bnx2x_pmf_update(struct bnx2x *bp)
1586 */ 1630 */
1587 1631
1588/* send the MCP a request, block until there is a reply */ 1632/* send the MCP a request, block until there is a reply */
1589u32 bnx2x_fw_command(struct bnx2x *bp, u32 command) 1633u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param)
1590{ 1634{
1591 int func = BP_FUNC(bp); 1635 int func = BP_FUNC(bp);
1592 u32 seq = ++bp->fw_seq; 1636 u32 seq = ++bp->fw_seq;
@@ -1595,6 +1639,7 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command)
1595 u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10; 1639 u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10;
1596 1640
1597 mutex_lock(&bp->fw_mb_mutex); 1641 mutex_lock(&bp->fw_mb_mutex);
1642 SHMEM_WR(bp, func_mb[func].drv_mb_param, param);
1598 SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq)); 1643 SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq));
1599 DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq)); 1644 DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq));
1600 1645
@@ -1716,9 +1761,9 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event)
1716 1761
1717 /* Report results to MCP */ 1762 /* Report results to MCP */
1718 if (dcc_event) 1763 if (dcc_event)
1719 bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE); 1764 bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE, 0);
1720 else 1765 else
1721 bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK); 1766 bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK, 0);
1722} 1767}
1723 1768
1724/* must be called under the spq lock */ 1769/* must be called under the spq lock */
@@ -3848,6 +3893,7 @@ static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp)
3848 bnx2x_fan_failure_det_req( 3893 bnx2x_fan_failure_det_req(
3849 bp, 3894 bp,
3850 bp->common.shmem_base, 3895 bp->common.shmem_base,
3896 bp->common.shmem2_base,
3851 port); 3897 port);
3852 } 3898 }
3853 3899
@@ -4116,7 +4162,8 @@ static int bnx2x_init_common(struct bnx2x *bp)
4116 } 4162 }
4117 4163
4118 bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, 4164 bp->port.need_hw_lock = bnx2x_hw_lock_required(bp,
4119 bp->common.shmem_base); 4165 bp->common.shmem_base,
4166 bp->common.shmem2_base);
4120 4167
4121 bnx2x_setup_fan_failure_detection(bp); 4168 bnx2x_setup_fan_failure_detection(bp);
4122 4169
@@ -4129,7 +4176,8 @@ static int bnx2x_init_common(struct bnx2x *bp)
4129 4176
4130 if (!BP_NOMCP(bp)) { 4177 if (!BP_NOMCP(bp)) {
4131 bnx2x_acquire_phy_lock(bp); 4178 bnx2x_acquire_phy_lock(bp);
4132 bnx2x_common_init_phy(bp, bp->common.shmem_base); 4179 bnx2x_common_init_phy(bp, bp->common.shmem_base,
4180 bp->common.shmem2_base);
4133 bnx2x_release_phy_lock(bp); 4181 bnx2x_release_phy_lock(bp);
4134 } else 4182 } else
4135 BNX2X_ERR("Bootcode is missing - can not initialize link\n"); 4183 BNX2X_ERR("Bootcode is missing - can not initialize link\n");
@@ -4265,10 +4313,10 @@ static int bnx2x_init_port(struct bnx2x *bp)
4265 bnx2x_init_block(bp, MCP_BLOCK, init_stage); 4313 bnx2x_init_block(bp, MCP_BLOCK, init_stage);
4266 bnx2x_init_block(bp, DMAE_BLOCK, init_stage); 4314 bnx2x_init_block(bp, DMAE_BLOCK, init_stage);
4267 bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, 4315 bp->port.need_hw_lock = bnx2x_hw_lock_required(bp,
4268 bp->common.shmem_base); 4316 bp->common.shmem_base,
4269 4317 bp->common.shmem2_base);
4270 if (bnx2x_fan_failure_det_req(bp, bp->common.shmem_base, 4318 if (bnx2x_fan_failure_det_req(bp, bp->common.shmem_base,
4271 port)) { 4319 bp->common.shmem2_base, port)) {
4272 u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : 4320 u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 :
4273 MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); 4321 MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0);
4274 val = REG_RD(bp, reg_addr); 4322 val = REG_RD(bp, reg_addr);
@@ -5226,7 +5274,7 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode)
5226 5274
5227unload_error: 5275unload_error:
5228 if (!BP_NOMCP(bp)) 5276 if (!BP_NOMCP(bp))
5229 reset_code = bnx2x_fw_command(bp, reset_code); 5277 reset_code = bnx2x_fw_command(bp, reset_code, 0);
5230 else { 5278 else {
5231 DP(NETIF_MSG_IFDOWN, "NO MCP - load counts %d, %d, %d\n", 5279 DP(NETIF_MSG_IFDOWN, "NO MCP - load counts %d, %d, %d\n",
5232 load_count[0], load_count[1], load_count[2]); 5280 load_count[0], load_count[1], load_count[2]);
@@ -5251,7 +5299,7 @@ unload_error:
5251 5299
5252 /* Report UNLOAD_DONE to MCP */ 5300 /* Report UNLOAD_DONE to MCP */
5253 if (!BP_NOMCP(bp)) 5301 if (!BP_NOMCP(bp))
5254 bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); 5302 bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0);
5255 5303
5256} 5304}
5257 5305
@@ -5816,13 +5864,14 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
5816 bp->fw_seq = 5864 bp->fw_seq =
5817 (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & 5865 (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) &
5818 DRV_MSG_SEQ_NUMBER_MASK); 5866 DRV_MSG_SEQ_NUMBER_MASK);
5819 reset_code = bnx2x_fw_command(bp, reset_code); 5867 reset_code = bnx2x_fw_command(bp, reset_code, 0);
5820 5868
5821 /* if UNDI is loaded on the other port */ 5869 /* if UNDI is loaded on the other port */
5822 if (reset_code != FW_MSG_CODE_DRV_UNLOAD_COMMON) { 5870 if (reset_code != FW_MSG_CODE_DRV_UNLOAD_COMMON) {
5823 5871
5824 /* send "DONE" for previous unload */ 5872 /* send "DONE" for previous unload */
5825 bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); 5873 bnx2x_fw_command(bp,
5874 DRV_MSG_CODE_UNLOAD_DONE, 0);
5826 5875
5827 /* unload UNDI on port 1 */ 5876 /* unload UNDI on port 1 */
5828 bp->func = 1; 5877 bp->func = 1;
@@ -5831,7 +5880,7 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
5831 DRV_MSG_SEQ_NUMBER_MASK); 5880 DRV_MSG_SEQ_NUMBER_MASK);
5832 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; 5881 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;
5833 5882
5834 bnx2x_fw_command(bp, reset_code); 5883 bnx2x_fw_command(bp, reset_code, 0);
5835 } 5884 }
5836 5885
5837 /* now it's safe to release the lock */ 5886 /* now it's safe to release the lock */
@@ -5873,7 +5922,7 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp)
5873 REG_WR(bp, NIG_REG_STRAP_OVERRIDE, swap_en); 5922 REG_WR(bp, NIG_REG_STRAP_OVERRIDE, swap_en);
5874 5923
5875 /* send unload done to the MCP */ 5924 /* send unload done to the MCP */
5876 bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); 5925 bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0);
5877 5926
5878 /* restore our func and fw_seq */ 5927 /* restore our func and fw_seq */
5879 bp->func = func; 5928 bp->func = func;
@@ -5921,6 +5970,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
5921 bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); 5970 bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
5922 bp->common.shmem2_base = REG_RD(bp, MISC_REG_GENERIC_CR_0); 5971 bp->common.shmem2_base = REG_RD(bp, MISC_REG_GENERIC_CR_0);
5923 bp->link_params.shmem_base = bp->common.shmem_base; 5972 bp->link_params.shmem_base = bp->common.shmem_base;
5973 bp->link_params.shmem2_base = bp->common.shmem2_base;
5924 BNX2X_DEV_INFO("shmem offset 0x%x shmem2 offset 0x%x\n", 5974 BNX2X_DEV_INFO("shmem offset 0x%x shmem2 offset 0x%x\n",
5925 bp->common.shmem_base, bp->common.shmem2_base); 5975 bp->common.shmem_base, bp->common.shmem2_base);
5926 5976
@@ -5963,8 +6013,11 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
5963 "please upgrade BC\n", BNX2X_BC_VER, val); 6013 "please upgrade BC\n", BNX2X_BC_VER, val);
5964 } 6014 }
5965 bp->link_params.feature_config_flags |= 6015 bp->link_params.feature_config_flags |=
5966 (val >= REQ_BC_VER_4_VRFY_OPT_MDL) ? 6016 (val >= REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL) ?
5967 FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0; 6017 FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0;
6018 bp->link_params.feature_config_flags |=
6019 (val >= REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL) ?
6020 FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY : 0;
5968 6021
5969 if (BP_E1HVN(bp) == 0) { 6022 if (BP_E1HVN(bp) == 0) {
5970 pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc); 6023 pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc);
@@ -5988,22 +6041,44 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
5988static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, 6041static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp,
5989 u32 switch_cfg) 6042 u32 switch_cfg)
5990{ 6043{
5991 int port = BP_PORT(bp); 6044 int cfg_size = 0, idx, port = BP_PORT(bp);
5992 bp->port.supported = 0; 6045
6046 /* Aggregation of supported attributes of all external phys */
6047 bp->port.supported[0] = 0;
6048 bp->port.supported[1] = 0;
5993 switch (bp->link_params.num_phys) { 6049 switch (bp->link_params.num_phys) {
5994 case 1: 6050 case 1:
5995 bp->port.supported = bp->link_params.phy[INT_PHY].supported; 6051 bp->port.supported[0] = bp->link_params.phy[INT_PHY].supported;
5996 break; 6052 cfg_size = 1;
6053 break;
5997 case 2: 6054 case 2:
5998 bp->port.supported = bp->link_params.phy[EXT_PHY1].supported; 6055 bp->port.supported[0] = bp->link_params.phy[EXT_PHY1].supported;
5999 break; 6056 cfg_size = 1;
6057 break;
6058 case 3:
6059 if (bp->link_params.multi_phy_config &
6060 PORT_HW_CFG_PHY_SWAPPED_ENABLED) {
6061 bp->port.supported[1] =
6062 bp->link_params.phy[EXT_PHY1].supported;
6063 bp->port.supported[0] =
6064 bp->link_params.phy[EXT_PHY2].supported;
6065 } else {
6066 bp->port.supported[0] =
6067 bp->link_params.phy[EXT_PHY1].supported;
6068 bp->port.supported[1] =
6069 bp->link_params.phy[EXT_PHY2].supported;
6070 }
6071 cfg_size = 2;
6072 break;
6000 } 6073 }
6001 6074
6002 if (!(bp->port.supported)) { 6075 if (!(bp->port.supported[0] || bp->port.supported[1])) {
6003 BNX2X_ERR("NVRAM config error. BAD phy config." 6076 BNX2X_ERR("NVRAM config error. BAD phy config."
6004 "PHY1 config 0x%x\n", 6077 "PHY1 config 0x%x, PHY2 config 0x%x\n",
6005 SHMEM_RD(bp, 6078 SHMEM_RD(bp,
6006 dev_info.port_hw_config[port].external_phy_config)); 6079 dev_info.port_hw_config[port].external_phy_config),
6080 SHMEM_RD(bp,
6081 dev_info.port_hw_config[port].external_phy_config2));
6007 return; 6082 return;
6008 } 6083 }
6009 6084
@@ -6023,147 +6098,183 @@ static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp,
6023 6098
6024 default: 6099 default:
6025 BNX2X_ERR("BAD switch_cfg link_config 0x%x\n", 6100 BNX2X_ERR("BAD switch_cfg link_config 0x%x\n",
6026 bp->port.link_config); 6101 bp->port.link_config[0]);
6027 return; 6102 return;
6028 } 6103 }
6029 /* mask what we support according to speed_cap_mask */ 6104 /* mask what we support according to speed_cap_mask per configuration */
6030 if (!(bp->link_params.speed_cap_mask & 6105 for (idx = 0; idx < cfg_size; idx++) {
6106 if (!(bp->link_params.speed_cap_mask[idx] &
6031 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) 6107 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF))
6032 bp->port.supported &= ~SUPPORTED_10baseT_Half; 6108 bp->port.supported[idx] &= ~SUPPORTED_10baseT_Half;
6033 6109
6034 if (!(bp->link_params.speed_cap_mask & 6110 if (!(bp->link_params.speed_cap_mask[idx] &
6035 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL)) 6111 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL))
6036 bp->port.supported &= ~SUPPORTED_10baseT_Full; 6112 bp->port.supported[idx] &= ~SUPPORTED_10baseT_Full;
6037 6113
6038 if (!(bp->link_params.speed_cap_mask & 6114 if (!(bp->link_params.speed_cap_mask[idx] &
6039 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) 6115 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF))
6040 bp->port.supported &= ~SUPPORTED_100baseT_Half; 6116 bp->port.supported[idx] &= ~SUPPORTED_100baseT_Half;
6041 6117
6042 if (!(bp->link_params.speed_cap_mask & 6118 if (!(bp->link_params.speed_cap_mask[idx] &
6043 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL)) 6119 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL))
6044 bp->port.supported &= ~SUPPORTED_100baseT_Full; 6120 bp->port.supported[idx] &= ~SUPPORTED_100baseT_Full;
6045 6121
6046 if (!(bp->link_params.speed_cap_mask & 6122 if (!(bp->link_params.speed_cap_mask[idx] &
6047 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) 6123 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))
6048 bp->port.supported &= ~(SUPPORTED_1000baseT_Half | 6124 bp->port.supported[idx] &= ~(SUPPORTED_1000baseT_Half |
6049 SUPPORTED_1000baseT_Full); 6125 SUPPORTED_1000baseT_Full);
6050 6126
6051 if (!(bp->link_params.speed_cap_mask & 6127 if (!(bp->link_params.speed_cap_mask[idx] &
6052 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) 6128 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
6053 bp->port.supported &= ~SUPPORTED_2500baseX_Full; 6129 bp->port.supported[idx] &= ~SUPPORTED_2500baseX_Full;
6054 6130
6055 if (!(bp->link_params.speed_cap_mask & 6131 if (!(bp->link_params.speed_cap_mask[idx] &
6056 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) 6132 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G))
6057 bp->port.supported &= ~SUPPORTED_10000baseT_Full; 6133 bp->port.supported[idx] &= ~SUPPORTED_10000baseT_Full;
6134
6135 }
6058 6136
6059 BNX2X_DEV_INFO("supported 0x%x\n", bp->port.supported); 6137 BNX2X_DEV_INFO("supported 0x%x 0x%x\n", bp->port.supported[0],
6138 bp->port.supported[1]);
6060} 6139}
6061 6140
6062static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) 6141static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp)
6063{ 6142{
6064 bp->link_params.req_duplex = DUPLEX_FULL; 6143 u32 link_config, idx, cfg_size = 0;
6065 6144 bp->port.advertising[0] = 0;
6066 switch (bp->port.link_config & PORT_FEATURE_LINK_SPEED_MASK) { 6145 bp->port.advertising[1] = 0;
6146 switch (bp->link_params.num_phys) {
6147 case 1:
6148 case 2:
6149 cfg_size = 1;
6150 break;
6151 case 3:
6152 cfg_size = 2;
6153 break;
6154 }
6155 for (idx = 0; idx < cfg_size; idx++) {
6156 bp->link_params.req_duplex[idx] = DUPLEX_FULL;
6157 link_config = bp->port.link_config[idx];
6158 switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) {
6067 case PORT_FEATURE_LINK_SPEED_AUTO: 6159 case PORT_FEATURE_LINK_SPEED_AUTO:
6068 if (bp->port.supported & SUPPORTED_Autoneg) { 6160 if (bp->port.supported[idx] & SUPPORTED_Autoneg) {
6069 bp->link_params.req_line_speed = SPEED_AUTO_NEG; 6161 bp->link_params.req_line_speed[idx] =
6070 bp->port.advertising = bp->port.supported; 6162 SPEED_AUTO_NEG;
6163 bp->port.advertising[idx] |=
6164 bp->port.supported[idx];
6071 } else { 6165 } else {
6072 /* force 10G, no AN */ 6166 /* force 10G, no AN */
6073 bp->link_params.req_line_speed = SPEED_10000; 6167 bp->link_params.req_line_speed[idx] =
6074 bp->port.advertising = (ADVERTISED_10000baseT_Full | 6168 SPEED_10000;
6169 bp->port.advertising[idx] |=
6170 (ADVERTISED_10000baseT_Full |
6075 ADVERTISED_FIBRE); 6171 ADVERTISED_FIBRE);
6172 continue;
6076 } 6173 }
6077 break; 6174 break;
6078 6175
6079 case PORT_FEATURE_LINK_SPEED_10M_FULL: 6176 case PORT_FEATURE_LINK_SPEED_10M_FULL:
6080 if (bp->port.supported & SUPPORTED_10baseT_Full) { 6177 if (bp->port.supported[idx] & SUPPORTED_10baseT_Full) {
6081 bp->link_params.req_line_speed = SPEED_10; 6178 bp->link_params.req_line_speed[idx] =
6082 bp->port.advertising = (ADVERTISED_10baseT_Full | 6179 SPEED_10;
6180 bp->port.advertising[idx] |=
6181 (ADVERTISED_10baseT_Full |
6083 ADVERTISED_TP); 6182 ADVERTISED_TP);
6084 } else { 6183 } else {
6085 BNX2X_ERROR("NVRAM config error. " 6184 BNX2X_ERROR("NVRAM config error. "
6086 "Invalid link_config 0x%x" 6185 "Invalid link_config 0x%x"
6087 " speed_cap_mask 0x%x\n", 6186 " speed_cap_mask 0x%x\n",
6088 bp->port.link_config, 6187 link_config,
6089 bp->link_params.speed_cap_mask); 6188 bp->link_params.speed_cap_mask[idx]);
6090 return; 6189 return;
6091 } 6190 }
6092 break; 6191 break;
6093 6192
6094 case PORT_FEATURE_LINK_SPEED_10M_HALF: 6193 case PORT_FEATURE_LINK_SPEED_10M_HALF:
6095 if (bp->port.supported & SUPPORTED_10baseT_Half) { 6194 if (bp->port.supported[idx] & SUPPORTED_10baseT_Half) {
6096 bp->link_params.req_line_speed = SPEED_10; 6195 bp->link_params.req_line_speed[idx] =
6097 bp->link_params.req_duplex = DUPLEX_HALF; 6196 SPEED_10;
6098 bp->port.advertising = (ADVERTISED_10baseT_Half | 6197 bp->link_params.req_duplex[idx] =
6198 DUPLEX_HALF;
6199 bp->port.advertising[idx] |=
6200 (ADVERTISED_10baseT_Half |
6099 ADVERTISED_TP); 6201 ADVERTISED_TP);
6100 } else { 6202 } else {
6101 BNX2X_ERROR("NVRAM config error. " 6203 BNX2X_ERROR("NVRAM config error. "
6102 "Invalid link_config 0x%x" 6204 "Invalid link_config 0x%x"
6103 " speed_cap_mask 0x%x\n", 6205 " speed_cap_mask 0x%x\n",
6104 bp->port.link_config, 6206 link_config,
6105 bp->link_params.speed_cap_mask); 6207 bp->link_params.speed_cap_mask[idx]);
6106 return; 6208 return;
6107 } 6209 }
6108 break; 6210 break;
6109 6211
6110 case PORT_FEATURE_LINK_SPEED_100M_FULL: 6212 case PORT_FEATURE_LINK_SPEED_100M_FULL:
6111 if (bp->port.supported & SUPPORTED_100baseT_Full) { 6213 if (bp->port.supported[idx] & SUPPORTED_100baseT_Full) {
6112 bp->link_params.req_line_speed = SPEED_100; 6214 bp->link_params.req_line_speed[idx] =
6113 bp->port.advertising = (ADVERTISED_100baseT_Full | 6215 SPEED_100;
6216 bp->port.advertising[idx] |=
6217 (ADVERTISED_100baseT_Full |
6114 ADVERTISED_TP); 6218 ADVERTISED_TP);
6115 } else { 6219 } else {
6116 BNX2X_ERROR("NVRAM config error. " 6220 BNX2X_ERROR("NVRAM config error. "
6117 "Invalid link_config 0x%x" 6221 "Invalid link_config 0x%x"
6118 " speed_cap_mask 0x%x\n", 6222 " speed_cap_mask 0x%x\n",
6119 bp->port.link_config, 6223 link_config,
6120 bp->link_params.speed_cap_mask); 6224 bp->link_params.speed_cap_mask[idx]);
6121 return; 6225 return;
6122 } 6226 }
6123 break; 6227 break;
6124 6228
6125 case PORT_FEATURE_LINK_SPEED_100M_HALF: 6229 case PORT_FEATURE_LINK_SPEED_100M_HALF:
6126 if (bp->port.supported & SUPPORTED_100baseT_Half) { 6230 if (bp->port.supported[idx] & SUPPORTED_100baseT_Half) {
6127 bp->link_params.req_line_speed = SPEED_100; 6231 bp->link_params.req_line_speed[idx] = SPEED_100;
6128 bp->link_params.req_duplex = DUPLEX_HALF; 6232 bp->link_params.req_duplex[idx] = DUPLEX_HALF;
6129 bp->port.advertising = (ADVERTISED_100baseT_Half | 6233 bp->port.advertising[idx] |=
6234 (ADVERTISED_100baseT_Half |
6130 ADVERTISED_TP); 6235 ADVERTISED_TP);
6131 } else { 6236 } else {
6132 BNX2X_ERROR("NVRAM config error. " 6237 BNX2X_ERROR("NVRAM config error. "
6133 "Invalid link_config 0x%x" 6238 "Invalid link_config 0x%x"
6134 " speed_cap_mask 0x%x\n", 6239 " speed_cap_mask 0x%x\n",
6135 bp->port.link_config, 6240 link_config,
6136 bp->link_params.speed_cap_mask); 6241 bp->link_params.speed_cap_mask[idx]);
6137 return; 6242 return;
6138 } 6243 }
6139 break; 6244 break;
6140 6245
6141 case PORT_FEATURE_LINK_SPEED_1G: 6246 case PORT_FEATURE_LINK_SPEED_1G:
6142 if (bp->port.supported & SUPPORTED_1000baseT_Full) { 6247 if (bp->port.supported[idx] &
6143 bp->link_params.req_line_speed = SPEED_1000; 6248 SUPPORTED_1000baseT_Full) {
6144 bp->port.advertising = (ADVERTISED_1000baseT_Full | 6249 bp->link_params.req_line_speed[idx] =
6250 SPEED_1000;
6251 bp->port.advertising[idx] |=
6252 (ADVERTISED_1000baseT_Full |
6145 ADVERTISED_TP); 6253 ADVERTISED_TP);
6146 } else { 6254 } else {
6147 BNX2X_ERROR("NVRAM config error. " 6255 BNX2X_ERROR("NVRAM config error. "
6148 "Invalid link_config 0x%x" 6256 "Invalid link_config 0x%x"
6149 " speed_cap_mask 0x%x\n", 6257 " speed_cap_mask 0x%x\n",
6150 bp->port.link_config, 6258 link_config,
6151 bp->link_params.speed_cap_mask); 6259 bp->link_params.speed_cap_mask[idx]);
6152 return; 6260 return;
6153 } 6261 }
6154 break; 6262 break;
6155 6263
6156 case PORT_FEATURE_LINK_SPEED_2_5G: 6264 case PORT_FEATURE_LINK_SPEED_2_5G:
6157 if (bp->port.supported & SUPPORTED_2500baseX_Full) { 6265 if (bp->port.supported[idx] &
6158 bp->link_params.req_line_speed = SPEED_2500; 6266 SUPPORTED_2500baseX_Full) {
6159 bp->port.advertising = (ADVERTISED_2500baseX_Full | 6267 bp->link_params.req_line_speed[idx] =
6268 SPEED_2500;
6269 bp->port.advertising[idx] |=
6270 (ADVERTISED_2500baseX_Full |
6160 ADVERTISED_TP); 6271 ADVERTISED_TP);
6161 } else { 6272 } else {
6162 BNX2X_ERROR("NVRAM config error. " 6273 BNX2X_ERROR("NVRAM config error. "
6163 "Invalid link_config 0x%x" 6274 "Invalid link_config 0x%x"
6164 " speed_cap_mask 0x%x\n", 6275 " speed_cap_mask 0x%x\n",
6165 bp->port.link_config, 6276 link_config,
6166 bp->link_params.speed_cap_mask); 6277 bp->link_params.speed_cap_mask[idx]);
6167 return; 6278 return;
6168 } 6279 }
6169 break; 6280 break;
@@ -6171,16 +6282,19 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp)
6171 case PORT_FEATURE_LINK_SPEED_10G_CX4: 6282 case PORT_FEATURE_LINK_SPEED_10G_CX4:
6172 case PORT_FEATURE_LINK_SPEED_10G_KX4: 6283 case PORT_FEATURE_LINK_SPEED_10G_KX4:
6173 case PORT_FEATURE_LINK_SPEED_10G_KR: 6284 case PORT_FEATURE_LINK_SPEED_10G_KR:
6174 if (bp->port.supported & SUPPORTED_10000baseT_Full) { 6285 if (bp->port.supported[idx] &
6175 bp->link_params.req_line_speed = SPEED_10000; 6286 SUPPORTED_10000baseT_Full) {
6176 bp->port.advertising = (ADVERTISED_10000baseT_Full | 6287 bp->link_params.req_line_speed[idx] =
6288 SPEED_10000;
6289 bp->port.advertising[idx] |=
6290 (ADVERTISED_10000baseT_Full |
6177 ADVERTISED_FIBRE); 6291 ADVERTISED_FIBRE);
6178 } else { 6292 } else {
6179 BNX2X_ERROR("NVRAM config error. " 6293 BNX2X_ERROR("NVRAM config error. "
6180 "Invalid link_config 0x%x" 6294 "Invalid link_config 0x%x"
6181 " speed_cap_mask 0x%x\n", 6295 " speed_cap_mask 0x%x\n",
6182 bp->port.link_config, 6296 link_config,
6183 bp->link_params.speed_cap_mask); 6297 bp->link_params.speed_cap_mask[idx]);
6184 return; 6298 return;
6185 } 6299 }
6186 break; 6300 break;
@@ -6188,23 +6302,28 @@ static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp)
6188 default: 6302 default:
6189 BNX2X_ERROR("NVRAM config error. " 6303 BNX2X_ERROR("NVRAM config error. "
6190 "BAD link speed link_config 0x%x\n", 6304 "BAD link speed link_config 0x%x\n",
6191 bp->port.link_config); 6305 link_config);
6192 bp->link_params.req_line_speed = SPEED_AUTO_NEG; 6306 bp->link_params.req_line_speed[idx] = SPEED_AUTO_NEG;
6193 bp->port.advertising = bp->port.supported; 6307 bp->port.advertising[idx] = bp->port.supported[idx];
6194 break; 6308 break;
6195 } 6309 }
6196 6310
6197 bp->link_params.req_flow_ctrl = (bp->port.link_config & 6311 bp->link_params.req_flow_ctrl[idx] = (link_config &
6198 PORT_FEATURE_FLOW_CONTROL_MASK); 6312 PORT_FEATURE_FLOW_CONTROL_MASK);
6199 if ((bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) && 6313 if ((bp->link_params.req_flow_ctrl[idx] ==
6200 !(bp->port.supported & SUPPORTED_Autoneg)) 6314 BNX2X_FLOW_CTRL_AUTO) &&
6201 bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_NONE; 6315 !(bp->port.supported[idx] & SUPPORTED_Autoneg)) {
6316 bp->link_params.req_flow_ctrl[idx] =
6317 BNX2X_FLOW_CTRL_NONE;
6318 }
6202 6319
6203 BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl 0x%x" 6320 BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl"
6204 " advertising 0x%x\n", 6321 " 0x%x advertising 0x%x\n",
6205 bp->link_params.req_line_speed, 6322 bp->link_params.req_line_speed[idx],
6206 bp->link_params.req_duplex, 6323 bp->link_params.req_duplex[idx],
6207 bp->link_params.req_flow_ctrl, bp->port.advertising); 6324 bp->link_params.req_flow_ctrl[idx],
6325 bp->port.advertising[idx]);
6326 }
6208} 6327}
6209 6328
6210static void __devinit bnx2x_set_mac_buf(u8 *mac_buf, u32 mac_lo, u16 mac_hi) 6329static void __devinit bnx2x_set_mac_buf(u8 *mac_buf, u32 mac_lo, u16 mac_hi)
@@ -6228,14 +6347,20 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
6228 bp->link_params.lane_config = 6347 bp->link_params.lane_config =
6229 SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config); 6348 SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config);
6230 6349
6231 bp->link_params.speed_cap_mask = 6350 bp->link_params.speed_cap_mask[0] =
6232 SHMEM_RD(bp, 6351 SHMEM_RD(bp,
6233 dev_info.port_hw_config[port].speed_capability_mask); 6352 dev_info.port_hw_config[port].speed_capability_mask);
6234 6353 bp->link_params.speed_cap_mask[1] =
6235 bp->port.link_config = 6354 SHMEM_RD(bp,
6355 dev_info.port_hw_config[port].speed_capability_mask2);
6356 bp->port.link_config[0] =
6236 SHMEM_RD(bp, dev_info.port_feature_config[port].link_config); 6357 SHMEM_RD(bp, dev_info.port_feature_config[port].link_config);
6237 6358
6359 bp->port.link_config[1] =
6360 SHMEM_RD(bp, dev_info.port_feature_config[port].link_config2);
6238 6361
6362 bp->link_params.multi_phy_config =
6363 SHMEM_RD(bp, dev_info.port_hw_config[port].multi_phy_config);
6239 /* If the device is capable of WoL, set the default state according 6364 /* If the device is capable of WoL, set the default state according
6240 * to the HW 6365 * to the HW
6241 */ 6366 */
@@ -6244,11 +6369,12 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp)
6244 (config & PORT_FEATURE_WOL_ENABLED)); 6369 (config & PORT_FEATURE_WOL_ENABLED));
6245 6370
6246 BNX2X_DEV_INFO("lane_config 0x%08x" 6371 BNX2X_DEV_INFO("lane_config 0x%08x"
6247 " speed_cap_mask 0x%08x link_config 0x%08x\n", 6372 "speed_cap_mask0 0x%08x link_config0 0x%08x\n",
6248 bp->link_params.lane_config, 6373 bp->link_params.lane_config,
6249 bp->link_params.speed_cap_mask, bp->port.link_config); 6374 bp->link_params.speed_cap_mask[0],
6375 bp->port.link_config[0]);
6250 6376
6251 bp->link_params.switch_cfg |= (bp->port.link_config & 6377 bp->link_params.switch_cfg = (bp->port.link_config[0] &
6252 PORT_FEATURE_CONNECTED_SWITCH_MASK); 6378 PORT_FEATURE_CONNECTED_SWITCH_MASK);
6253 bnx2x_phy_probe(&bp->link_params); 6379 bnx2x_phy_probe(&bp->link_params);
6254 bnx2x_link_settings_supported(bp, bp->link_params.switch_cfg); 6380 bnx2x_link_settings_supported(bp, bp->link_params.switch_cfg);