aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYaniv Rosner <yanivr@broadcom.com>2011-05-31 17:27:06 -0400
committerDavid S. Miller <davem@davemloft.net>2011-06-01 16:10:56 -0400
commitc688fe2fc0cab3a5d266f7f6fcb21f14e4ac39ba (patch)
tree6004092cce67ac60b919c5c4ec324d83c8f3d8ba
parentfcf5b650832996bd857bb8f0b0b42097218f7fb8 (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.c72
-rw-r--r--drivers/net/bnx2x/bnx2x_link.h3
-rw-r--r--drivers/net/bnx2x/bnx2x_reg.h1
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/******************************************************************/
5212static 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/******************************************************************/
5210static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, 5235static 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