diff options
author | Yaniv Rosner <yanivr@broadcom.com> | 2011-05-31 17:27:06 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-06-01 16:10:56 -0400 |
commit | c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39ba (patch) | |
tree | 6004092cce67ac60b919c5c4ec324d83c8f3d8ba | |
parent | fcf5b650832996bd857bb8f0b0b42097218f7fb8 (diff) |
bnx2x: Add TX fault check for fiber PHYs
In case TX fault is detected on Fiber PHYs, declare the link as down until TX fault is gone.
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>
-rw-r--r-- | drivers/net/bnx2x/bnx2x_link.c | 72 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_link.h | 3 | ||||
-rw-r--r-- | drivers/net/bnx2x/bnx2x_reg.h | 1 |
3 files changed, 72 insertions, 4 deletions
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 7705e79945ec..87c5d9ff8163 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c | |||
@@ -3495,6 +3495,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
3495 | phy_vars[phy_index].duplex = DUPLEX_FULL; | 3495 | phy_vars[phy_index].duplex = DUPLEX_FULL; |
3496 | phy_vars[phy_index].phy_link_up = 0; | 3496 | phy_vars[phy_index].phy_link_up = 0; |
3497 | phy_vars[phy_index].link_up = 0; | 3497 | phy_vars[phy_index].link_up = 0; |
3498 | phy_vars[phy_index].fault_detected = 0; | ||
3498 | } | 3499 | } |
3499 | 3500 | ||
3500 | DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", | 3501 | DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", |
@@ -3707,7 +3708,8 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) | |||
3707 | */ | 3708 | */ |
3708 | vars->link_up = (vars->phy_link_up && | 3709 | vars->link_up = (vars->phy_link_up && |
3709 | (ext_phy_link_up || | 3710 | (ext_phy_link_up || |
3710 | SINGLE_MEDIA_DIRECT(params))); | 3711 | SINGLE_MEDIA_DIRECT(params)) && |
3712 | (phy_vars[active_external_phy].fault_detected == 0)); | ||
3711 | 3713 | ||
3712 | if (vars->link_up) | 3714 | if (vars->link_up) |
3713 | rc = bnx2x_update_link_up(params, vars, link_10g); | 3715 | rc = bnx2x_update_link_up(params, vars, link_10g); |
@@ -5205,6 +5207,29 @@ void bnx2x_handle_module_detect_int(struct link_params *params) | |||
5205 | } | 5207 | } |
5206 | 5208 | ||
5207 | /******************************************************************/ | 5209 | /******************************************************************/ |
5210 | /* Used by 8706 and 8727 */ | ||
5211 | /******************************************************************/ | ||
5212 | static void bnx2x_sfp_mask_fault(struct bnx2x *bp, | ||
5213 | struct bnx2x_phy *phy, | ||
5214 | u16 alarm_status_offset, | ||
5215 | u16 alarm_ctrl_offset) | ||
5216 | { | ||
5217 | u16 alarm_status, val; | ||
5218 | bnx2x_cl45_read(bp, phy, | ||
5219 | MDIO_PMA_DEVAD, alarm_status_offset, | ||
5220 | &alarm_status); | ||
5221 | bnx2x_cl45_read(bp, phy, | ||
5222 | MDIO_PMA_DEVAD, alarm_status_offset, | ||
5223 | &alarm_status); | ||
5224 | /* Mask or enable the fault event. */ | ||
5225 | bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, &val); | ||
5226 | if (alarm_status & (1<<0)) | ||
5227 | val &= ~(1<<0); | ||
5228 | else | ||
5229 | val |= (1<<0); | ||
5230 | bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, val); | ||
5231 | } | ||
5232 | /******************************************************************/ | ||
5208 | /* common BCM8706/BCM8726 PHY SECTION */ | 5233 | /* common BCM8706/BCM8726 PHY SECTION */ |
5209 | /******************************************************************/ | 5234 | /******************************************************************/ |
5210 | static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, | 5235 | static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, |
@@ -5218,6 +5243,10 @@ static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, | |||
5218 | /* Clear RX Alarm*/ | 5243 | /* Clear RX Alarm*/ |
5219 | bnx2x_cl45_read(bp, phy, | 5244 | bnx2x_cl45_read(bp, phy, |
5220 | MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2); | 5245 | MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2); |
5246 | |||
5247 | bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_REG_TX_ALARM, | ||
5248 | MDIO_PMA_REG_TX_ALARM_CTRL); | ||
5249 | |||
5221 | /* clear LASI indication*/ | 5250 | /* clear LASI indication*/ |
5222 | bnx2x_cl45_read(bp, phy, | 5251 | bnx2x_cl45_read(bp, phy, |
5223 | MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); | 5252 | MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); |
@@ -5249,6 +5278,17 @@ static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, | |||
5249 | bnx2x_ext_phy_resolve_fc(phy, params, vars); | 5278 | bnx2x_ext_phy_resolve_fc(phy, params, vars); |
5250 | vars->duplex = DUPLEX_FULL; | 5279 | vars->duplex = DUPLEX_FULL; |
5251 | } | 5280 | } |
5281 | |||
5282 | /* Capture 10G link fault. Read twice to clear stale value. */ | ||
5283 | if (vars->line_speed == SPEED_10000) { | ||
5284 | bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, | ||
5285 | MDIO_PMA_REG_TX_ALARM, &val1); | ||
5286 | bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, | ||
5287 | MDIO_PMA_REG_TX_ALARM, &val1); | ||
5288 | if (val1 & (1<<0)) | ||
5289 | vars->fault_detected = 1; | ||
5290 | } | ||
5291 | |||
5252 | return link_up; | 5292 | return link_up; |
5253 | } | 5293 | } |
5254 | 5294 | ||
@@ -5304,7 +5344,11 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, | |||
5304 | MDIO_PMA_DEVAD, | 5344 | MDIO_PMA_DEVAD, |
5305 | MDIO_PMA_REG_DIGITAL_CTRL, 0x400); | 5345 | MDIO_PMA_REG_DIGITAL_CTRL, 0x400); |
5306 | bnx2x_cl45_write(bp, phy, | 5346 | bnx2x_cl45_write(bp, phy, |
5307 | MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1); | 5347 | MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_ALARM_CTRL, |
5348 | 0); | ||
5349 | /* Arm LASI for link and Tx fault. */ | ||
5350 | bnx2x_cl45_write(bp, phy, | ||
5351 | MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 3); | ||
5308 | } else { | 5352 | } else { |
5309 | /* Force 1Gbps using autoneg with 1G advertisement */ | 5353 | /* Force 1Gbps using autoneg with 1G advertisement */ |
5310 | 5354 | ||
@@ -5637,14 +5681,17 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy, | |||
5637 | 5681 | ||
5638 | bnx2x_wait_reset_complete(bp, phy, params); | 5682 | bnx2x_wait_reset_complete(bp, phy, params); |
5639 | rx_alarm_ctrl_val = (1<<2) | (1<<5) ; | 5683 | rx_alarm_ctrl_val = (1<<2) | (1<<5) ; |
5640 | lasi_ctrl_val = 0x0004; | 5684 | /* Should be 0x6 to enable XS on Tx side. */ |
5685 | lasi_ctrl_val = 0x0006; | ||
5641 | 5686 | ||
5642 | DP(NETIF_MSG_LINK, "Initializing BCM8727\n"); | 5687 | DP(NETIF_MSG_LINK, "Initializing BCM8727\n"); |
5643 | /* enable LASI */ | 5688 | /* enable LASI */ |
5644 | bnx2x_cl45_write(bp, phy, | 5689 | bnx2x_cl45_write(bp, phy, |
5645 | MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, | 5690 | MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, |
5646 | rx_alarm_ctrl_val); | 5691 | rx_alarm_ctrl_val); |
5647 | 5692 | bnx2x_cl45_write(bp, phy, | |
5693 | MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_ALARM_CTRL, | ||
5694 | 0); | ||
5648 | bnx2x_cl45_write(bp, phy, | 5695 | bnx2x_cl45_write(bp, phy, |
5649 | MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val); | 5696 | MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val); |
5650 | 5697 | ||
@@ -5899,6 +5946,9 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, | |||
5899 | vars->line_speed = 0; | 5946 | vars->line_speed = 0; |
5900 | DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status); | 5947 | DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status); |
5901 | 5948 | ||
5949 | bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_REG_TX_ALARM, | ||
5950 | MDIO_PMA_REG_TX_ALARM_CTRL); | ||
5951 | |||
5902 | bnx2x_cl45_read(bp, phy, | 5952 | bnx2x_cl45_read(bp, phy, |
5903 | MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); | 5953 | MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); |
5904 | 5954 | ||
@@ -5991,6 +6041,20 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, | |||
5991 | DP(NETIF_MSG_LINK, "port %x: External link is down\n", | 6041 | DP(NETIF_MSG_LINK, "port %x: External link is down\n", |
5992 | params->port); | 6042 | params->port); |
5993 | } | 6043 | } |
6044 | |||
6045 | /* Capture 10G link fault. */ | ||
6046 | if (vars->line_speed == SPEED_10000) { | ||
6047 | bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, | ||
6048 | MDIO_PMA_REG_TX_ALARM, &val1); | ||
6049 | |||
6050 | bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, | ||
6051 | MDIO_PMA_REG_TX_ALARM, &val1); | ||
6052 | |||
6053 | if (val1 & (1<<0)) { | ||
6054 | vars->fault_detected = 1; | ||
6055 | } | ||
6056 | } | ||
6057 | |||
5994 | if (link_up) { | 6058 | if (link_up) { |
5995 | bnx2x_ext_phy_resolve_fc(phy, params, vars); | 6059 | bnx2x_ext_phy_resolve_fc(phy, params, vars); |
5996 | vars->duplex = DUPLEX_FULL; | 6060 | vars->duplex = DUPLEX_FULL; |
diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 418bef472e08..4d5509bf87aa 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h | |||
@@ -276,6 +276,9 @@ struct link_vars { | |||
276 | 276 | ||
277 | /* The same definitions as the shmem parameter */ | 277 | /* The same definitions as the shmem parameter */ |
278 | u32 link_status; | 278 | u32 link_status; |
279 | u8 fault_detected; | ||
280 | u8 rsrv1; | ||
281 | u16 rsrv2; | ||
279 | }; | 282 | }; |
280 | 283 | ||
281 | /***********************************************************/ | 284 | /***********************************************************/ |
diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 86bba25d2d3f..7260d09cf25f 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h | |||
@@ -6037,6 +6037,7 @@ Theotherbitsarereservedandshouldbezero*/ | |||
6037 | #define MDIO_PMA_REG_BCM_CTRL 0x0096 | 6037 | #define MDIO_PMA_REG_BCM_CTRL 0x0096 |
6038 | #define MDIO_PMA_REG_FEC_CTRL 0x00ab | 6038 | #define MDIO_PMA_REG_FEC_CTRL 0x00ab |
6039 | #define MDIO_PMA_REG_RX_ALARM_CTRL 0x9000 | 6039 | #define MDIO_PMA_REG_RX_ALARM_CTRL 0x9000 |
6040 | #define MDIO_PMA_REG_TX_ALARM_CTRL 0x9001 | ||
6040 | #define MDIO_PMA_REG_LASI_CTRL 0x9002 | 6041 | #define MDIO_PMA_REG_LASI_CTRL 0x9002 |
6041 | #define MDIO_PMA_REG_RX_ALARM 0x9003 | 6042 | #define MDIO_PMA_REG_RX_ALARM 0x9003 |
6042 | #define MDIO_PMA_REG_TX_ALARM 0x9004 | 6043 | #define MDIO_PMA_REG_TX_ALARM 0x9004 |