diff options
author | Eilon Greenstein <eilong@broadcom.com> | 2009-02-12 03:38:08 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-16 02:31:50 -0500 |
commit | b5bf9068ebb1b4012e4c0fef58490f97e6b6a0db (patch) | |
tree | 75c15b5ca4456238cdc6296d34fc7336c0664a64 /drivers/net/bnx2x_main.c | |
parent | 26e029752c8f8671b1de83fe86906fc29f9eda92 (diff) |
bnx2x: Loopback in diag mode
When loading in diag mode, set the device to loopback instead of normal link and
then changing it to loopback mode
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r-- | drivers/net/bnx2x_main.c | 57 |
1 files changed, 33 insertions, 24 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index a14fe7544844..96e23fd7eb4a 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c | |||
@@ -2064,7 +2064,7 @@ static void bnx2x_link_report(struct bnx2x *bp) | |||
2064 | } | 2064 | } |
2065 | } | 2065 | } |
2066 | 2066 | ||
2067 | static u8 bnx2x_initial_phy_init(struct bnx2x *bp) | 2067 | static u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) |
2068 | { | 2068 | { |
2069 | if (!BP_NOMCP(bp)) { | 2069 | if (!BP_NOMCP(bp)) { |
2070 | u8 rc; | 2070 | u8 rc; |
@@ -2080,14 +2080,20 @@ static u8 bnx2x_initial_phy_init(struct bnx2x *bp) | |||
2080 | bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH; | 2080 | bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH; |
2081 | 2081 | ||
2082 | bnx2x_acquire_phy_lock(bp); | 2082 | bnx2x_acquire_phy_lock(bp); |
2083 | |||
2084 | if (load_mode == LOAD_DIAG) | ||
2085 | bp->link_params.loopback_mode = LOOPBACK_XGXS_10; | ||
2086 | |||
2083 | rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars); | 2087 | rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars); |
2088 | |||
2084 | bnx2x_release_phy_lock(bp); | 2089 | bnx2x_release_phy_lock(bp); |
2085 | 2090 | ||
2086 | bnx2x_calc_fc_adv(bp); | 2091 | bnx2x_calc_fc_adv(bp); |
2087 | 2092 | ||
2088 | if (bp->link_vars.link_up) | 2093 | if (CHIP_REV_IS_SLOW(bp) && bp->link_vars.link_up) { |
2094 | bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); | ||
2089 | bnx2x_link_report(bp); | 2095 | bnx2x_link_report(bp); |
2090 | 2096 | } | |
2091 | 2097 | ||
2092 | return rc; | 2098 | return rc; |
2093 | } | 2099 | } |
@@ -6942,7 +6948,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
6942 | bnx2x_set_mac_addr_e1h(bp, 1); | 6948 | bnx2x_set_mac_addr_e1h(bp, 1); |
6943 | 6949 | ||
6944 | if (bp->port.pmf) | 6950 | if (bp->port.pmf) |
6945 | bnx2x_initial_phy_init(bp); | 6951 | bnx2x_initial_phy_init(bp, load_mode); |
6946 | 6952 | ||
6947 | /* Start fast path */ | 6953 | /* Start fast path */ |
6948 | switch (load_mode) { | 6954 | switch (load_mode) { |
@@ -9328,23 +9334,23 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) | |||
9328 | u16 len; | 9334 | u16 len; |
9329 | int rc = -ENODEV; | 9335 | int rc = -ENODEV; |
9330 | 9336 | ||
9331 | if (loopback_mode == BNX2X_MAC_LOOPBACK) { | 9337 | /* check the loopback mode */ |
9338 | switch (loopback_mode) { | ||
9339 | case BNX2X_PHY_LOOPBACK: | ||
9340 | if (bp->link_params.loopback_mode != LOOPBACK_XGXS_10) | ||
9341 | return -EINVAL; | ||
9342 | break; | ||
9343 | case BNX2X_MAC_LOOPBACK: | ||
9332 | bp->link_params.loopback_mode = LOOPBACK_BMAC; | 9344 | bp->link_params.loopback_mode = LOOPBACK_BMAC; |
9333 | bnx2x_phy_init(&bp->link_params, &bp->link_vars); | 9345 | bnx2x_phy_init(&bp->link_params, &bp->link_vars); |
9334 | 9346 | break; | |
9335 | } else if (loopback_mode == BNX2X_PHY_LOOPBACK) { | 9347 | default: |
9336 | u16 cnt = 1000; | ||
9337 | bp->link_params.loopback_mode = LOOPBACK_XGXS_10; | ||
9338 | bnx2x_phy_init(&bp->link_params, &bp->link_vars); | ||
9339 | /* wait until link state is restored */ | ||
9340 | if (link_up) | ||
9341 | while (cnt-- && bnx2x_test_link(&bp->link_params, | ||
9342 | &bp->link_vars)) | ||
9343 | msleep(10); | ||
9344 | } else | ||
9345 | return -EINVAL; | 9348 | return -EINVAL; |
9349 | } | ||
9346 | 9350 | ||
9347 | pkt_size = 1514; | 9351 | /* prepare the loopback packet */ |
9352 | pkt_size = (((bp->dev->mtu < ETH_MAX_PACKET_SIZE) ? | ||
9353 | bp->dev->mtu : ETH_MAX_PACKET_SIZE) + ETH_HLEN); | ||
9348 | skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size); | 9354 | skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size); |
9349 | if (!skb) { | 9355 | if (!skb) { |
9350 | rc = -ENOMEM; | 9356 | rc = -ENOMEM; |
@@ -9356,6 +9362,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) | |||
9356 | for (i = ETH_HLEN; i < pkt_size; i++) | 9362 | for (i = ETH_HLEN; i < pkt_size; i++) |
9357 | packet[i] = (unsigned char) (i & 0xff); | 9363 | packet[i] = (unsigned char) (i & 0xff); |
9358 | 9364 | ||
9365 | /* send the loopback packet */ | ||
9359 | num_pkts = 0; | 9366 | num_pkts = 0; |
9360 | tx_start_idx = le16_to_cpu(*fp->tx_cons_sb); | 9367 | tx_start_idx = le16_to_cpu(*fp->tx_cons_sb); |
9361 | rx_start_idx = le16_to_cpu(*fp->rx_cons_sb); | 9368 | rx_start_idx = le16_to_cpu(*fp->rx_cons_sb); |
@@ -9440,7 +9447,7 @@ test_loopback_exit: | |||
9440 | 9447 | ||
9441 | static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up) | 9448 | static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up) |
9442 | { | 9449 | { |
9443 | int rc = 0; | 9450 | int rc = 0, res; |
9444 | 9451 | ||
9445 | if (!netif_running(bp->dev)) | 9452 | if (!netif_running(bp->dev)) |
9446 | return BNX2X_LOOPBACK_FAILED; | 9453 | return BNX2X_LOOPBACK_FAILED; |
@@ -9448,14 +9455,16 @@ static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up) | |||
9448 | bnx2x_netif_stop(bp, 1); | 9455 | bnx2x_netif_stop(bp, 1); |
9449 | bnx2x_acquire_phy_lock(bp); | 9456 | bnx2x_acquire_phy_lock(bp); |
9450 | 9457 | ||
9451 | if (bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up)) { | 9458 | res = bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up); |
9452 | DP(NETIF_MSG_PROBE, "MAC loopback failed\n"); | 9459 | if (res) { |
9453 | rc |= BNX2X_MAC_LOOPBACK_FAILED; | 9460 | DP(NETIF_MSG_PROBE, " PHY loopback failed (res %d)\n", res); |
9461 | rc |= BNX2X_PHY_LOOPBACK_FAILED; | ||
9454 | } | 9462 | } |
9455 | 9463 | ||
9456 | if (bnx2x_run_loopback(bp, BNX2X_PHY_LOOPBACK, link_up)) { | 9464 | res = bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up); |
9457 | DP(NETIF_MSG_PROBE, "PHY loopback failed\n"); | 9465 | if (res) { |
9458 | rc |= BNX2X_PHY_LOOPBACK_FAILED; | 9466 | DP(NETIF_MSG_PROBE, " MAC loopback failed (res %d)\n", res); |
9467 | rc |= BNX2X_MAC_LOOPBACK_FAILED; | ||
9459 | } | 9468 | } |
9460 | 9469 | ||
9461 | bnx2x_release_phy_lock(bp); | 9470 | bnx2x_release_phy_lock(bp); |