Loading drivers/net/bnx2.c +79 −22 Original line number Diff line number Diff line Loading @@ -1331,6 +1331,38 @@ bnx2_set_mac_loopback(struct bnx2 *bp) return 0; } static int bnx2_test_link(struct bnx2 *); static int bnx2_set_phy_loopback(struct bnx2 *bp) { u32 mac_mode; int rc, i; spin_lock_bh(&bp->phy_lock); rc = bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED1000); spin_unlock_bh(&bp->phy_lock); if (rc) return rc; for (i = 0; i < 10; i++) { if (bnx2_test_link(bp) == 0) break; udelay(10); } mac_mode = REG_RD(bp, BNX2_EMAC_MODE); mac_mode &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX | BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK | BNX2_EMAC_MODE_25G); mac_mode |= BNX2_EMAC_MODE_PORT_GMII; REG_WR(bp, BNX2_EMAC_MODE, mac_mode); bp->link_up = 1; return 0; } static int bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent) { Loading Loading @@ -3907,26 +3939,33 @@ bnx2_test_memory(struct bnx2 *bp) return ret; } #define BNX2_MAC_LOOPBACK 0 #define BNX2_PHY_LOOPBACK 1 static int bnx2_test_loopback(struct bnx2 *bp) bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) { unsigned int pkt_size, num_pkts, i; struct sk_buff *skb, *rx_skb; unsigned char *packet; u16 rx_start_idx, rx_idx, send_idx; u32 send_bseq, val; u16 rx_start_idx, rx_idx; u32 val; dma_addr_t map; struct tx_bd *txbd; struct sw_bd *rx_buf; struct l2_fhdr *rx_hdr; int ret = -ENODEV; if (!netif_running(bp->dev)) return -ENODEV; if (loopback_mode == BNX2_MAC_LOOPBACK) { bp->loopback = MAC_LOOPBACK; bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_DIAG); bnx2_set_mac_loopback(bp); } else if (loopback_mode == BNX2_PHY_LOOPBACK) { bp->loopback = 0; bnx2_set_phy_loopback(bp); } else return -EINVAL; pkt_size = 1514; skb = dev_alloc_skb(pkt_size); Loading @@ -3948,11 +3987,9 @@ bnx2_test_loopback(struct bnx2 *bp) udelay(5); rx_start_idx = bp->status_blk->status_rx_quick_consumer_index0; send_idx = 0; send_bseq = 0; num_pkts = 0; txbd = &bp->tx_desc_ring[send_idx]; txbd = &bp->tx_desc_ring[TX_RING_IDX(bp->tx_prod)]; txbd->tx_bd_haddr_hi = (u64) map >> 32; txbd->tx_bd_haddr_lo = (u64) map & 0xffffffff; Loading @@ -3960,13 +3997,11 @@ bnx2_test_loopback(struct bnx2 *bp) txbd->tx_bd_vlan_tag_flags = TX_BD_FLAGS_START | TX_BD_FLAGS_END; num_pkts++; send_idx = NEXT_TX_BD(send_idx); send_bseq += pkt_size; REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, send_idx); REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, send_bseq); bp->tx_prod = NEXT_TX_BD(bp->tx_prod); bp->tx_prod_bseq += pkt_size; REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, bp->tx_prod); REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq); udelay(100); Loading @@ -3979,7 +4014,7 @@ bnx2_test_loopback(struct bnx2 *bp) pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE); dev_kfree_skb_irq(skb); if (bp->status_blk->status_tx_quick_consumer_index0 != send_idx) { if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_prod) { goto loopback_test_done; } Loading Loading @@ -4025,6 +4060,30 @@ bnx2_test_loopback(struct bnx2 *bp) return ret; } #define BNX2_MAC_LOOPBACK_FAILED 1 #define BNX2_PHY_LOOPBACK_FAILED 2 #define BNX2_LOOPBACK_FAILED (BNX2_MAC_LOOPBACK_FAILED | \ BNX2_PHY_LOOPBACK_FAILED) static int bnx2_test_loopback(struct bnx2 *bp) { int rc = 0; if (!netif_running(bp->dev)) return BNX2_LOOPBACK_FAILED; bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET); spin_lock_bh(&bp->phy_lock); bnx2_init_phy(bp); spin_unlock_bh(&bp->phy_lock); if (bnx2_run_loopback(bp, BNX2_MAC_LOOPBACK)) rc |= BNX2_MAC_LOOPBACK_FAILED; if (bnx2_run_loopback(bp, BNX2_PHY_LOOPBACK)) rc |= BNX2_PHY_LOOPBACK_FAILED; return rc; } #define NVRAM_SIZE 0x200 #define CRC32_RESIDUAL 0xdebb20e3 Loading Loading @@ -5169,10 +5228,8 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf) buf[1] = 1; etest->flags |= ETH_TEST_FL_FAILED; } if (bnx2_test_loopback(bp) != 0) { buf[2] = 1; if ((buf[2] = bnx2_test_loopback(bp)) != 0) etest->flags |= ETH_TEST_FL_FAILED; } if (!netif_running(bp->dev)) { bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); Loading Loading
drivers/net/bnx2.c +79 −22 Original line number Diff line number Diff line Loading @@ -1331,6 +1331,38 @@ bnx2_set_mac_loopback(struct bnx2 *bp) return 0; } static int bnx2_test_link(struct bnx2 *); static int bnx2_set_phy_loopback(struct bnx2 *bp) { u32 mac_mode; int rc, i; spin_lock_bh(&bp->phy_lock); rc = bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED1000); spin_unlock_bh(&bp->phy_lock); if (rc) return rc; for (i = 0; i < 10; i++) { if (bnx2_test_link(bp) == 0) break; udelay(10); } mac_mode = REG_RD(bp, BNX2_EMAC_MODE); mac_mode &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX | BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK | BNX2_EMAC_MODE_25G); mac_mode |= BNX2_EMAC_MODE_PORT_GMII; REG_WR(bp, BNX2_EMAC_MODE, mac_mode); bp->link_up = 1; return 0; } static int bnx2_fw_sync(struct bnx2 *bp, u32 msg_data, int silent) { Loading Loading @@ -3907,26 +3939,33 @@ bnx2_test_memory(struct bnx2 *bp) return ret; } #define BNX2_MAC_LOOPBACK 0 #define BNX2_PHY_LOOPBACK 1 static int bnx2_test_loopback(struct bnx2 *bp) bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) { unsigned int pkt_size, num_pkts, i; struct sk_buff *skb, *rx_skb; unsigned char *packet; u16 rx_start_idx, rx_idx, send_idx; u32 send_bseq, val; u16 rx_start_idx, rx_idx; u32 val; dma_addr_t map; struct tx_bd *txbd; struct sw_bd *rx_buf; struct l2_fhdr *rx_hdr; int ret = -ENODEV; if (!netif_running(bp->dev)) return -ENODEV; if (loopback_mode == BNX2_MAC_LOOPBACK) { bp->loopback = MAC_LOOPBACK; bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_DIAG); bnx2_set_mac_loopback(bp); } else if (loopback_mode == BNX2_PHY_LOOPBACK) { bp->loopback = 0; bnx2_set_phy_loopback(bp); } else return -EINVAL; pkt_size = 1514; skb = dev_alloc_skb(pkt_size); Loading @@ -3948,11 +3987,9 @@ bnx2_test_loopback(struct bnx2 *bp) udelay(5); rx_start_idx = bp->status_blk->status_rx_quick_consumer_index0; send_idx = 0; send_bseq = 0; num_pkts = 0; txbd = &bp->tx_desc_ring[send_idx]; txbd = &bp->tx_desc_ring[TX_RING_IDX(bp->tx_prod)]; txbd->tx_bd_haddr_hi = (u64) map >> 32; txbd->tx_bd_haddr_lo = (u64) map & 0xffffffff; Loading @@ -3960,13 +3997,11 @@ bnx2_test_loopback(struct bnx2 *bp) txbd->tx_bd_vlan_tag_flags = TX_BD_FLAGS_START | TX_BD_FLAGS_END; num_pkts++; send_idx = NEXT_TX_BD(send_idx); send_bseq += pkt_size; REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, send_idx); REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, send_bseq); bp->tx_prod = NEXT_TX_BD(bp->tx_prod); bp->tx_prod_bseq += pkt_size; REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, bp->tx_prod); REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq); udelay(100); Loading @@ -3979,7 +4014,7 @@ bnx2_test_loopback(struct bnx2 *bp) pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE); dev_kfree_skb_irq(skb); if (bp->status_blk->status_tx_quick_consumer_index0 != send_idx) { if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_prod) { goto loopback_test_done; } Loading Loading @@ -4025,6 +4060,30 @@ bnx2_test_loopback(struct bnx2 *bp) return ret; } #define BNX2_MAC_LOOPBACK_FAILED 1 #define BNX2_PHY_LOOPBACK_FAILED 2 #define BNX2_LOOPBACK_FAILED (BNX2_MAC_LOOPBACK_FAILED | \ BNX2_PHY_LOOPBACK_FAILED) static int bnx2_test_loopback(struct bnx2 *bp) { int rc = 0; if (!netif_running(bp->dev)) return BNX2_LOOPBACK_FAILED; bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET); spin_lock_bh(&bp->phy_lock); bnx2_init_phy(bp); spin_unlock_bh(&bp->phy_lock); if (bnx2_run_loopback(bp, BNX2_MAC_LOOPBACK)) rc |= BNX2_MAC_LOOPBACK_FAILED; if (bnx2_run_loopback(bp, BNX2_PHY_LOOPBACK)) rc |= BNX2_PHY_LOOPBACK_FAILED; return rc; } #define NVRAM_SIZE 0x200 #define CRC32_RESIDUAL 0xdebb20e3 Loading Loading @@ -5169,10 +5228,8 @@ bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf) buf[1] = 1; etest->flags |= ETH_TEST_FL_FAILED; } if (bnx2_test_loopback(bp) != 0) { buf[2] = 1; if ((buf[2] = bnx2_test_loopback(bp)) != 0) etest->flags |= ETH_TEST_FL_FAILED; } if (!netif_running(bp->dev)) { bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); Loading