aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2006-01-23 19:13:22 -0500
committerDavid S. Miller <davem@davemloft.net>2006-01-23 19:13:22 -0500
commitbc5a0690e917206b423c7b565c997b06675fb572 (patch)
treef741fe9ac8f40971fb14a1bdac95ce146b005d67 /drivers/net/bnx2.c
parent972ec0d4ba67bf0ec7f00cd93fbac47452f80d25 (diff)
[BNX2]: Add PHY loopback test
Enhance the ethtool loopback test with PHY loopback test. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r--drivers/net/bnx2.c101
1 files changed, 79 insertions, 22 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 7be011f37d13..9f71cca81e91 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -1331,6 +1331,38 @@ bnx2_set_mac_loopback(struct bnx2 *bp)
1331 return 0; 1331 return 0;
1332} 1332}
1333 1333
1334static int bnx2_test_link(struct bnx2 *);
1335
1336static int
1337bnx2_set_phy_loopback(struct bnx2 *bp)
1338{
1339 u32 mac_mode;
1340 int rc, i;
1341
1342 spin_lock_bh(&bp->phy_lock);
1343 rc = bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX |
1344 BMCR_SPEED1000);
1345 spin_unlock_bh(&bp->phy_lock);
1346 if (rc)
1347 return rc;
1348
1349 for (i = 0; i < 10; i++) {
1350 if (bnx2_test_link(bp) == 0)
1351 break;
1352 udelay(10);
1353 }
1354
1355 mac_mode = REG_RD(bp, BNX2_EMAC_MODE);
1356 mac_mode &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
1357 BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
1358 BNX2_EMAC_MODE_25G);
1359
1360 mac_mode |= BNX2_EMAC_MODE_PORT_GMII;
1361 REG_WR(bp, BNX2_EMAC_MODE, mac_mode);
1362 bp->link_up = 1;
1363 return 0;
1364}
1365
1334static int 1366static int
1335bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent) 1367bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent)
1336{ 1368{
@@ -3907,26 +3939,33 @@ bnx2_test_memory(struct bnx2 *bp)
3907 return ret; 3939 return ret;
3908} 3940}
3909 3941
3942#define BNX2_MAC_LOOPBACK 0
3943#define BNX2_PHY_LOOPBACK 1
3944
3910static int 3945static int
3911bnx2_test_loopback(struct bnx2 *bp) 3946bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
3912{ 3947{
3913 unsigned int pkt_size, num_pkts, i; 3948 unsigned int pkt_size, num_pkts, i;
3914 struct sk_buff *skb, *rx_skb; 3949 struct sk_buff *skb, *rx_skb;
3915 unsigned char *packet; 3950 unsigned char *packet;
3916 u16 rx_start_idx, rx_idx, send_idx; 3951 u16 rx_start_idx, rx_idx;
3917 u32 send_bseq, val; 3952 u32 val;
3918 dma_addr_t map; 3953 dma_addr_t map;
3919 struct tx_bd *txbd; 3954 struct tx_bd *txbd;
3920 struct sw_bd *rx_buf; 3955 struct sw_bd *rx_buf;
3921 struct l2_fhdr *rx_hdr; 3956 struct l2_fhdr *rx_hdr;
3922 int ret = -ENODEV; 3957 int ret = -ENODEV;
3923 3958
3924 if (!netif_running(bp->dev)) 3959 if (loopback_mode == BNX2_MAC_LOOPBACK) {
3925 return -ENODEV; 3960 bp->loopback = MAC_LOOPBACK;
3926 3961 bnx2_set_mac_loopback(bp);
3927 bp->loopback = MAC_LOOPBACK; 3962 }
3928 bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_DIAG); 3963 else if (loopback_mode == BNX2_PHY_LOOPBACK) {
3929 bnx2_set_mac_loopback(bp); 3964 bp->loopback = 0;
3965 bnx2_set_phy_loopback(bp);
3966 }
3967 else
3968 return -EINVAL;
3930 3969
3931 pkt_size = 1514; 3970 pkt_size = 1514;
3932 skb = dev_alloc_skb(pkt_size); 3971 skb = dev_alloc_skb(pkt_size);
@@ -3948,11 +3987,9 @@ bnx2_test_loopback(struct bnx2 *bp)
3948 udelay(5); 3987 udelay(5);
3949 rx_start_idx = bp->status_blk->status_rx_quick_consumer_index0; 3988 rx_start_idx = bp->status_blk->status_rx_quick_consumer_index0;
3950 3989
3951 send_idx = 0;
3952 send_bseq = 0;
3953 num_pkts = 0; 3990 num_pkts = 0;
3954 3991
3955 txbd = &bp->tx_desc_ring[send_idx]; 3992 txbd = &bp->tx_desc_ring[TX_RING_IDX(bp->tx_prod)];
3956 3993
3957 txbd->tx_bd_haddr_hi = (u64) map >> 32; 3994 txbd->tx_bd_haddr_hi = (u64) map >> 32;
3958 txbd->tx_bd_haddr_lo = (u64) map & 0xffffffff; 3995 txbd->tx_bd_haddr_lo = (u64) map & 0xffffffff;
@@ -3960,13 +3997,11 @@ bnx2_test_loopback(struct bnx2 *bp)
3960 txbd->tx_bd_vlan_tag_flags = TX_BD_FLAGS_START | TX_BD_FLAGS_END; 3997 txbd->tx_bd_vlan_tag_flags = TX_BD_FLAGS_START | TX_BD_FLAGS_END;
3961 3998
3962 num_pkts++; 3999 num_pkts++;
3963 send_idx = NEXT_TX_BD(send_idx); 4000 bp->tx_prod = NEXT_TX_BD(bp->tx_prod);
3964 4001 bp->tx_prod_bseq += pkt_size;
3965 send_bseq += pkt_size;
3966
3967 REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, send_idx);
3968 REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, send_bseq);
3969 4002
4003 REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, bp->tx_prod);
4004 REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq);
3970 4005
3971 udelay(100); 4006 udelay(100);
3972 4007
@@ -3979,7 +4014,7 @@ bnx2_test_loopback(struct bnx2 *bp)
3979 pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE); 4014 pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE);
3980 dev_kfree_skb_irq(skb); 4015 dev_kfree_skb_irq(skb);
3981 4016
3982 if (bp->status_blk->status_tx_quick_consumer_index0 != send_idx) { 4017 if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_prod) {
3983 goto loopback_test_done; 4018 goto loopback_test_done;
3984 } 4019 }
3985 4020
@@ -4025,6 +4060,30 @@ loopback_test_done:
4025 return ret; 4060 return ret;
4026} 4061}
4027 4062
4063#define BNX2_MAC_LOOPBACK_FAILED 1
4064#define BNX2_PHY_LOOPBACK_FAILED 2
4065#define BNX2_LOOPBACK_FAILED (BNX2_MAC_LOOPBACK_FAILED | \
4066 BNX2_PHY_LOOPBACK_FAILED)
4067
4068static int
4069bnx2_test_loopback(struct bnx2 *bp)
4070{
4071 int rc = 0;
4072
4073 if (!netif_running(bp->dev))
4074 return BNX2_LOOPBACK_FAILED;
4075
4076 bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET);
4077 spin_lock_bh(&bp->phy_lock);
4078 bnx2_init_phy(bp);
4079 spin_unlock_bh(&bp->phy_lock);
4080 if (bnx2_run_loopback(bp, BNX2_MAC_LOOPBACK))
4081 rc |= BNX2_MAC_LOOPBACK_FAILED;
4082 if (bnx2_run_loopback(bp, BNX2_PHY_LOOPBACK))
4083 rc |= BNX2_PHY_LOOPBACK_FAILED;
4084 return rc;
4085}
4086
4028#define NVRAM_SIZE 0x200 4087#define NVRAM_SIZE 0x200
4029#define CRC32_RESIDUAL 0xdebb20e3 4088#define CRC32_RESIDUAL 0xdebb20e3
4030 4089
@@ -5169,10 +5228,8 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf)
5169 buf[1] = 1; 5228 buf[1] = 1;
5170 etest->flags |= ETH_TEST_FL_FAILED; 5229 etest->flags |= ETH_TEST_FL_FAILED;
5171 } 5230 }
5172 if (bnx2_test_loopback(bp) != 0) { 5231 if ((buf[2] = bnx2_test_loopback(bp)) != 0)
5173 buf[2] = 1;
5174 etest->flags |= ETH_TEST_FL_FAILED; 5232 etest->flags |= ETH_TEST_FL_FAILED;
5175 }
5176 5233
5177 if (!netif_running(bp->dev)) { 5234 if (!netif_running(bp->dev)) {
5178 bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); 5235 bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);