aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorYaniv Rosner <yanivr@broadcom.com>2012-11-26 22:46:30 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-28 10:59:21 -0500
commit55386fe88349706ae570522180d89892883af2b5 (patch)
tree289f3c615e80d50fd824c81aa1c83cde479800ac /drivers/net
parent4e7b4997886e1dcbb0024308fb474c5994e8af2b (diff)
bnx2x: Change MDIO clock settings
When drivers works on top of an old bootcode, it is theoretically subjected to MDC/MDIO failures since the MDIO clock is set in the beginning of each sequence, rather than per CL45 command. On rare cases an old bootcodes may change that in the middle, so to address that, the MDIO clock is set for each CL45 access. In addition, setting the MDIO clock is now done per EMAC base, and not per port number, since a specific port can potentially use both EMACs for different PHY accesses. Signed-off-by: Yaniv Rosner <yanivr@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h1
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c77
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h3
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c5
4 files changed, 66 insertions, 20 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
index 525a9bc30cb..a1a3ff43f66 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
@@ -1246,6 +1246,7 @@ struct drv_func_mb {
1246 #define DRV_MSG_CODE_VRFY_AFEX_SUPPORTED 0xa2000000 1246 #define DRV_MSG_CODE_VRFY_AFEX_SUPPORTED 0xa2000000
1247 #define REQ_BC_VER_4_VRFY_AFEX_SUPPORTED 0x00070002 1247 #define REQ_BC_VER_4_VRFY_AFEX_SUPPORTED 0x00070002
1248 #define REQ_BC_VER_4_SFP_TX_DISABLE_SUPPORTED 0x00070014 1248 #define REQ_BC_VER_4_SFP_TX_DISABLE_SUPPORTED 0x00070014
1249 #define REQ_BC_VER_4_MT_SUPPORTED 0x00070201
1249 #define REQ_BC_VER_4_PFC_STATS_SUPPORTED 0x00070201 1250 #define REQ_BC_VER_4_PFC_STATS_SUPPORTED 0x00070201
1250 #define REQ_BC_VER_4_FCOE_FEATURES 0x00070209 1251 #define REQ_BC_VER_4_FCOE_FEATURES 0x00070209
1251 1252
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index eb44b230676..e054921d45d 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -1441,30 +1441,47 @@ void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
1441/******************************************************************/ 1441/******************************************************************/
1442/* MAC/PBF section */ 1442/* MAC/PBF section */
1443/******************************************************************/ 1443/******************************************************************/
1444static void bnx2x_set_mdio_clk(struct bnx2x *bp, u32 chip_id, u8 port) 1444static void bnx2x_set_mdio_clk(struct bnx2x *bp, u32 chip_id,
1445 u32 emac_base)
1445{ 1446{
1446 u32 mode, emac_base; 1447 u32 new_mode, cur_mode;
1448 u32 clc_cnt;
1447 /* Set clause 45 mode, slow down the MDIO clock to 2.5MHz 1449 /* Set clause 45 mode, slow down the MDIO clock to 2.5MHz
1448 * (a value of 49==0x31) and make sure that the AUTO poll is off 1450 * (a value of 49==0x31) and make sure that the AUTO poll is off
1449 */ 1451 */
1452 cur_mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
1450 1453
1451 if (CHIP_IS_E2(bp))
1452 emac_base = GRCBASE_EMAC0;
1453 else
1454 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1455 mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
1456 mode &= ~(EMAC_MDIO_MODE_AUTO_POLL |
1457 EMAC_MDIO_MODE_CLOCK_CNT);
1458 if (USES_WARPCORE(bp)) 1454 if (USES_WARPCORE(bp))
1459 mode |= (74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT); 1455 clc_cnt = 74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
1460 else 1456 else
1461 mode |= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT); 1457 clc_cnt = 49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
1462 1458
1463 mode |= (EMAC_MDIO_MODE_CLAUSE_45); 1459 if (((cur_mode & EMAC_MDIO_MODE_CLOCK_CNT) == clc_cnt) &&
1464 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, mode); 1460 (cur_mode & (EMAC_MDIO_MODE_CLAUSE_45)))
1461 return;
1462
1463 new_mode = cur_mode &
1464 ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
1465 new_mode |= clc_cnt;
1466 new_mode |= (EMAC_MDIO_MODE_CLAUSE_45);
1465 1467
1468 DP(NETIF_MSG_LINK, "Changing emac_mode from 0x%x to 0x%x\n",
1469 cur_mode, new_mode);
1470 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, new_mode);
1466 udelay(40); 1471 udelay(40);
1467} 1472}
1473
1474static void bnx2x_set_mdio_emac_per_phy(struct bnx2x *bp,
1475 struct link_params *params)
1476{
1477 u8 phy_index;
1478 /* Set mdio clock per phy */
1479 for (phy_index = INT_PHY; phy_index < params->num_phys;
1480 phy_index++)
1481 bnx2x_set_mdio_clk(bp, params->chip_id,
1482 params->phy[phy_index].mdio_ctrl);
1483}
1484
1468static u8 bnx2x_is_4_port_mode(struct bnx2x *bp) 1485static u8 bnx2x_is_4_port_mode(struct bnx2x *bp)
1469{ 1486{
1470 u32 port4mode_ovwr_val; 1487 u32 port4mode_ovwr_val;
@@ -1509,7 +1526,8 @@ static void bnx2x_emac_init(struct link_params *params,
1509 } 1526 }
1510 timeout--; 1527 timeout--;
1511 } while (val & EMAC_MODE_RESET); 1528 } while (val & EMAC_MODE_RESET);
1512 bnx2x_set_mdio_clk(bp, params->chip_id, port); 1529
1530 bnx2x_set_mdio_emac_per_phy(bp, params);
1513 /* Set mac address */ 1531 /* Set mac address */
1514 val = ((params->mac_addr[0] << 8) | 1532 val = ((params->mac_addr[0] << 8) |
1515 params->mac_addr[1]); 1533 params->mac_addr[1]);
@@ -2683,6 +2701,13 @@ static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
2683 u32 val; 2701 u32 val;
2684 u16 i; 2702 u16 i;
2685 int rc = 0; 2703 int rc = 0;
2704 u32 chip_id;
2705 if (phy->flags & FLAGS_MDC_MDIO_WA_G) {
2706 chip_id = (REG_RD(bp, MISC_REG_CHIP_NUM) << 16) |
2707 ((REG_RD(bp, MISC_REG_CHIP_REV) & 0xf) << 12);
2708 bnx2x_set_mdio_clk(bp, chip_id, phy->mdio_ctrl);
2709 }
2710
2686 if (phy->flags & FLAGS_MDC_MDIO_WA_B0) 2711 if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
2687 bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS, 2712 bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2688 EMAC_MDIO_STATUS_10MB); 2713 EMAC_MDIO_STATUS_10MB);
@@ -2751,6 +2776,13 @@ static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
2751 u32 tmp; 2776 u32 tmp;
2752 u8 i; 2777 u8 i;
2753 int rc = 0; 2778 int rc = 0;
2779 u32 chip_id;
2780 if (phy->flags & FLAGS_MDC_MDIO_WA_G) {
2781 chip_id = (REG_RD(bp, MISC_REG_CHIP_NUM) << 16) |
2782 ((REG_RD(bp, MISC_REG_CHIP_REV) & 0xf) << 12);
2783 bnx2x_set_mdio_clk(bp, chip_id, phy->mdio_ctrl);
2784 }
2785
2754 if (phy->flags & FLAGS_MDC_MDIO_WA_B0) 2786 if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
2755 bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS, 2787 bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2756 EMAC_MDIO_STATUS_10MB); 2788 EMAC_MDIO_STATUS_10MB);
@@ -4508,7 +4540,7 @@ static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy,
4508 struct bnx2x *bp = params->bp; 4540 struct bnx2x *bp = params->bp;
4509 u16 val16, lane; 4541 u16 val16, lane;
4510 bnx2x_sfp_e3_set_transmitter(params, phy, 0); 4542 bnx2x_sfp_e3_set_transmitter(params, phy, 0);
4511 bnx2x_set_mdio_clk(bp, params->chip_id, params->port); 4543 bnx2x_set_mdio_emac_per_phy(bp, params);
4512 bnx2x_set_aer_mmd(params, phy); 4544 bnx2x_set_aer_mmd(params, phy);
4513 /* Global register */ 4545 /* Global register */
4514 bnx2x_warpcore_reset_lane(bp, phy, 1); 4546 bnx2x_warpcore_reset_lane(bp, phy, 1);
@@ -8600,7 +8632,7 @@ void bnx2x_handle_module_detect_int(struct link_params *params)
8600 8632
8601 /* Call the handling function in case module is detected */ 8633 /* Call the handling function in case module is detected */
8602 if (gpio_val == 0) { 8634 if (gpio_val == 0) {
8603 bnx2x_set_mdio_clk(bp, params->chip_id, params->port); 8635 bnx2x_set_mdio_emac_per_phy(bp, params);
8604 bnx2x_set_aer_mmd(params, phy); 8636 bnx2x_set_aer_mmd(params, phy);
8605 8637
8606 bnx2x_power_sfp_module(params, phy, 1); 8638 bnx2x_power_sfp_module(params, phy, 1);
@@ -12100,6 +12132,10 @@ int bnx2x_phy_probe(struct link_params *params)
12100 FEATURE_CONFIG_DISABLE_REMOTE_FAULT_DET) 12132 FEATURE_CONFIG_DISABLE_REMOTE_FAULT_DET)
12101 phy->flags &= ~FLAGS_TX_ERROR_CHECK; 12133 phy->flags &= ~FLAGS_TX_ERROR_CHECK;
12102 12134
12135 if (!(params->feature_config_flags &
12136 FEATURE_CONFIG_MT_SUPPORT))
12137 phy->flags |= FLAGS_MDC_MDIO_WA_G;
12138
12103 sync_offset = params->shmem_base + 12139 sync_offset = params->shmem_base +
12104 offsetof(struct shmem_region, 12140 offsetof(struct shmem_region,
12105 dev_info.port_hw_config[params->port].media_type); 12141 dev_info.port_hw_config[params->port].media_type);
@@ -12542,7 +12578,7 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
12542 * Hold it as vars low 12578 * Hold it as vars low
12543 */ 12579 */
12544 /* Clear link led */ 12580 /* Clear link led */
12545 bnx2x_set_mdio_clk(bp, params->chip_id, port); 12581 bnx2x_set_mdio_emac_per_phy(bp, params);
12546 bnx2x_set_led(params, vars, LED_MODE_OFF, 0); 12582 bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
12547 12583
12548 if (reset_ext_phy) { 12584 if (reset_ext_phy) {
@@ -13019,12 +13055,12 @@ int bnx2x_pre_init_phy(struct bnx2x *bp,
13019{ 13055{
13020 int rc = 0; 13056 int rc = 0;
13021 struct bnx2x_phy phy; 13057 struct bnx2x_phy phy;
13022 bnx2x_set_mdio_clk(bp, chip_id, PORT_0);
13023 if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, shmem2_base, 13058 if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, shmem2_base,
13024 PORT_0, &phy)) { 13059 PORT_0, &phy)) {
13025 DP(NETIF_MSG_LINK, "populate_phy failed\n"); 13060 DP(NETIF_MSG_LINK, "populate_phy failed\n");
13026 return -EINVAL; 13061 return -EINVAL;
13027 } 13062 }
13063 bnx2x_set_mdio_clk(bp, chip_id, phy.mdio_ctrl);
13028 switch (phy.type) { 13064 switch (phy.type) {
13029 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833: 13065 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
13030 rc = bnx2x_84833_pre_init_phy(bp, &phy); 13066 rc = bnx2x_84833_pre_init_phy(bp, &phy);
@@ -13095,8 +13131,9 @@ int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
13095 u32 phy_ver, val; 13131 u32 phy_ver, val;
13096 u8 phy_index = 0; 13132 u8 phy_index = 0;
13097 u32 ext_phy_type, ext_phy_config; 13133 u32 ext_phy_type, ext_phy_config;
13098 bnx2x_set_mdio_clk(bp, chip_id, PORT_0); 13134
13099 bnx2x_set_mdio_clk(bp, chip_id, PORT_1); 13135 bnx2x_set_mdio_clk(bp, chip_id, GRCBASE_EMAC0);
13136 bnx2x_set_mdio_clk(bp, chip_id, GRCBASE_EMAC1);
13100 DP(NETIF_MSG_LINK, "Begin common phy init\n"); 13137 DP(NETIF_MSG_LINK, "Begin common phy init\n");
13101 if (CHIP_IS_E3(bp)) { 13138 if (CHIP_IS_E3(bp)) {
13102 /* Enable EPIO */ 13139 /* Enable EPIO */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
index 33940fbe52c..24246b9a0c5 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
@@ -156,6 +156,7 @@ struct bnx2x_phy {
156#define FLAGS_MDC_MDIO_WA_B0 (1<<10) 156#define FLAGS_MDC_MDIO_WA_B0 (1<<10)
157#define FLAGS_TX_ERROR_CHECK (1<<12) 157#define FLAGS_TX_ERROR_CHECK (1<<12)
158#define FLAGS_EEE (1<<13) 158#define FLAGS_EEE (1<<13)
159#define FLAGS_MDC_MDIO_WA_G (1<<15)
159 160
160 /* preemphasis values for the rx side */ 161 /* preemphasis values for the rx side */
161 u16 rx_preemphasis[4]; 162 u16 rx_preemphasis[4];
@@ -267,6 +268,8 @@ struct link_params {
267#define FEATURE_CONFIG_AUTOGREEEN_ENABLED (1<<9) 268#define FEATURE_CONFIG_AUTOGREEEN_ENABLED (1<<9)
268#define FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED (1<<10) 269#define FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED (1<<10)
269#define FEATURE_CONFIG_DISABLE_REMOTE_FAULT_DET (1<<11) 270#define FEATURE_CONFIG_DISABLE_REMOTE_FAULT_DET (1<<11)
271#define FEATURE_CONFIG_MT_SUPPORT (1<<13)
272
270 /* Will be populated during common init */ 273 /* Will be populated during common init */
271 struct bnx2x_phy phy[MAX_PHYS]; 274 struct bnx2x_phy phy[MAX_PHYS];
272 275
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 4f33170a18d..79e4b724556 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -9921,6 +9921,11 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp)
9921 bp->link_params.feature_config_flags |= 9921 bp->link_params.feature_config_flags |=
9922 (val >= REQ_BC_VER_4_SFP_TX_DISABLE_SUPPORTED) ? 9922 (val >= REQ_BC_VER_4_SFP_TX_DISABLE_SUPPORTED) ?
9923 FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED : 0; 9923 FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED : 0;
9924
9925 bp->link_params.feature_config_flags |=
9926 (val >= REQ_BC_VER_4_MT_SUPPORTED) ?
9927 FEATURE_CONFIG_MT_SUPPORT : 0;
9928
9924 bp->flags |= (val >= REQ_BC_VER_4_PFC_STATS_SUPPORTED) ? 9929 bp->flags |= (val >= REQ_BC_VER_4_PFC_STATS_SUPPORTED) ?
9925 BC_SUPPORTS_PFC_STATS : 0; 9930 BC_SUPPORTS_PFC_STATS : 0;
9926 9931