aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r--drivers/net/bnx2.c124
1 files changed, 89 insertions, 35 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 65df1de447e4..d83512d3e02f 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -6145,6 +6145,10 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs)
6145 REG_WR(bp, BNX2_PCI_MSIX_TBL_OFF_BIR, BNX2_PCI_GRC_WINDOW2_BASE); 6145 REG_WR(bp, BNX2_PCI_MSIX_TBL_OFF_BIR, BNX2_PCI_GRC_WINDOW2_BASE);
6146 REG_WR(bp, BNX2_PCI_MSIX_PBA_OFF_BIT, BNX2_PCI_GRC_WINDOW3_BASE); 6146 REG_WR(bp, BNX2_PCI_MSIX_PBA_OFF_BIT, BNX2_PCI_GRC_WINDOW3_BASE);
6147 6147
6148 /* Need to flush the previous three writes to ensure MSI-X
6149 * is setup properly */
6150 REG_RD(bp, BNX2_PCI_MSIX_CONTROL);
6151
6148 for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) { 6152 for (i = 0; i < BNX2_MAX_MSIX_VEC; i++) {
6149 msix_ent[i].entry = i; 6153 msix_ent[i].entry = i;
6150 msix_ent[i].vector = 0; 6154 msix_ent[i].vector = 0;
@@ -6227,6 +6231,8 @@ bnx2_open(struct net_device *dev)
6227 6231
6228 atomic_set(&bp->intr_sem, 0); 6232 atomic_set(&bp->intr_sem, 0);
6229 6233
6234 memset(bp->temp_stats_blk, 0, sizeof(struct statistics_block));
6235
6230 bnx2_enable_int(bp); 6236 bnx2_enable_int(bp);
6231 6237
6232 if (bp->flags & BNX2_FLAG_USING_MSI) { 6238 if (bp->flags & BNX2_FLAG_USING_MSI) {
@@ -6538,92 +6544,121 @@ bnx2_close(struct net_device *dev)
6538 return 0; 6544 return 0;
6539} 6545}
6540 6546
6541#define GET_NET_STATS64(ctr) \ 6547static void
6548bnx2_save_stats(struct bnx2 *bp)
6549{
6550 u32 *hw_stats = (u32 *) bp->stats_blk;
6551 u32 *temp_stats = (u32 *) bp->temp_stats_blk;
6552 int i;
6553
6554 /* The 1st 10 counters are 64-bit counters */
6555 for (i = 0; i < 20; i += 2) {
6556 u32 hi;
6557 u64 lo;
6558
6559 hi = *(temp_stats + i) + *(hw_stats + i);
6560 lo = *(temp_stats + i + 1) + *(hw_stats + i + 1);
6561 if (lo > 0xffffffff)
6562 hi++;
6563 *(temp_stats + i) = hi;
6564 *(temp_stats + i + 1) = lo & 0xffffffff;
6565 }
6566
6567 for ( ; i < sizeof(struct statistics_block) / 4; i++)
6568 *(temp_stats + i) = *(temp_stats + i) + *(hw_stats + i);
6569}
6570
6571#define GET_64BIT_NET_STATS64(ctr) \
6542 (unsigned long) ((unsigned long) (ctr##_hi) << 32) + \ 6572 (unsigned long) ((unsigned long) (ctr##_hi) << 32) + \
6543 (unsigned long) (ctr##_lo) 6573 (unsigned long) (ctr##_lo)
6544 6574
6545#define GET_NET_STATS32(ctr) \ 6575#define GET_64BIT_NET_STATS32(ctr) \
6546 (ctr##_lo) 6576 (ctr##_lo)
6547 6577
6548#if (BITS_PER_LONG == 64) 6578#if (BITS_PER_LONG == 64)
6549#define GET_NET_STATS GET_NET_STATS64 6579#define GET_64BIT_NET_STATS(ctr) \
6580 GET_64BIT_NET_STATS64(bp->stats_blk->ctr) + \
6581 GET_64BIT_NET_STATS64(bp->temp_stats_blk->ctr)
6550#else 6582#else
6551#define GET_NET_STATS GET_NET_STATS32 6583#define GET_64BIT_NET_STATS(ctr) \
6584 GET_64BIT_NET_STATS32(bp->stats_blk->ctr) + \
6585 GET_64BIT_NET_STATS32(bp->temp_stats_blk->ctr)
6552#endif 6586#endif
6553 6587
6588#define GET_32BIT_NET_STATS(ctr) \
6589 (unsigned long) (bp->stats_blk->ctr + \
6590 bp->temp_stats_blk->ctr)
6591
6554static struct net_device_stats * 6592static struct net_device_stats *
6555bnx2_get_stats(struct net_device *dev) 6593bnx2_get_stats(struct net_device *dev)
6556{ 6594{
6557 struct bnx2 *bp = netdev_priv(dev); 6595 struct bnx2 *bp = netdev_priv(dev);
6558 struct statistics_block *stats_blk = bp->stats_blk;
6559 struct net_device_stats *net_stats = &dev->stats; 6596 struct net_device_stats *net_stats = &dev->stats;
6560 6597
6561 if (bp->stats_blk == NULL) { 6598 if (bp->stats_blk == NULL) {
6562 return net_stats; 6599 return net_stats;
6563 } 6600 }
6564 net_stats->rx_packets = 6601 net_stats->rx_packets =
6565 GET_NET_STATS(stats_blk->stat_IfHCInUcastPkts) + 6602 GET_64BIT_NET_STATS(stat_IfHCInUcastPkts) +
6566 GET_NET_STATS(stats_blk->stat_IfHCInMulticastPkts) + 6603 GET_64BIT_NET_STATS(stat_IfHCInMulticastPkts) +
6567 GET_NET_STATS(stats_blk->stat_IfHCInBroadcastPkts); 6604 GET_64BIT_NET_STATS(stat_IfHCInBroadcastPkts);
6568 6605
6569 net_stats->tx_packets = 6606 net_stats->tx_packets =
6570 GET_NET_STATS(stats_blk->stat_IfHCOutUcastPkts) + 6607 GET_64BIT_NET_STATS(stat_IfHCOutUcastPkts) +
6571 GET_NET_STATS(stats_blk->stat_IfHCOutMulticastPkts) + 6608 GET_64BIT_NET_STATS(stat_IfHCOutMulticastPkts) +
6572 GET_NET_STATS(stats_blk->stat_IfHCOutBroadcastPkts); 6609 GET_64BIT_NET_STATS(stat_IfHCOutBroadcastPkts);
6573 6610
6574 net_stats->rx_bytes = 6611 net_stats->rx_bytes =
6575 GET_NET_STATS(stats_blk->stat_IfHCInOctets); 6612 GET_64BIT_NET_STATS(stat_IfHCInOctets);
6576 6613
6577 net_stats->tx_bytes = 6614 net_stats->tx_bytes =
6578 GET_NET_STATS(stats_blk->stat_IfHCOutOctets); 6615 GET_64BIT_NET_STATS(stat_IfHCOutOctets);
6579 6616
6580 net_stats->multicast = 6617 net_stats->multicast =
6581 GET_NET_STATS(stats_blk->stat_IfHCOutMulticastPkts); 6618 GET_64BIT_NET_STATS(stat_IfHCOutMulticastPkts);
6582 6619
6583 net_stats->collisions = 6620 net_stats->collisions =
6584 (unsigned long) stats_blk->stat_EtherStatsCollisions; 6621 GET_32BIT_NET_STATS(stat_EtherStatsCollisions);
6585 6622
6586 net_stats->rx_length_errors = 6623 net_stats->rx_length_errors =
6587 (unsigned long) (stats_blk->stat_EtherStatsUndersizePkts + 6624 GET_32BIT_NET_STATS(stat_EtherStatsUndersizePkts) +
6588 stats_blk->stat_EtherStatsOverrsizePkts); 6625 GET_32BIT_NET_STATS(stat_EtherStatsOverrsizePkts);
6589 6626
6590 net_stats->rx_over_errors = 6627 net_stats->rx_over_errors =
6591 (unsigned long) (stats_blk->stat_IfInFTQDiscards + 6628 GET_32BIT_NET_STATS(stat_IfInFTQDiscards) +
6592 stats_blk->stat_IfInMBUFDiscards); 6629 GET_32BIT_NET_STATS(stat_IfInMBUFDiscards);
6593 6630
6594 net_stats->rx_frame_errors = 6631 net_stats->rx_frame_errors =
6595 (unsigned long) stats_blk->stat_Dot3StatsAlignmentErrors; 6632 GET_32BIT_NET_STATS(stat_Dot3StatsAlignmentErrors);
6596 6633
6597 net_stats->rx_crc_errors = 6634 net_stats->rx_crc_errors =
6598 (unsigned long) stats_blk->stat_Dot3StatsFCSErrors; 6635 GET_32BIT_NET_STATS(stat_Dot3StatsFCSErrors);
6599 6636
6600 net_stats->rx_errors = net_stats->rx_length_errors + 6637 net_stats->rx_errors = net_stats->rx_length_errors +
6601 net_stats->rx_over_errors + net_stats->rx_frame_errors + 6638 net_stats->rx_over_errors + net_stats->rx_frame_errors +
6602 net_stats->rx_crc_errors; 6639 net_stats->rx_crc_errors;
6603 6640
6604 net_stats->tx_aborted_errors = 6641 net_stats->tx_aborted_errors =
6605 (unsigned long) (stats_blk->stat_Dot3StatsExcessiveCollisions + 6642 GET_32BIT_NET_STATS(stat_Dot3StatsExcessiveCollisions) +
6606 stats_blk->stat_Dot3StatsLateCollisions); 6643 GET_32BIT_NET_STATS(stat_Dot3StatsLateCollisions);
6607 6644
6608 if ((CHIP_NUM(bp) == CHIP_NUM_5706) || 6645 if ((CHIP_NUM(bp) == CHIP_NUM_5706) ||
6609 (CHIP_ID(bp) == CHIP_ID_5708_A0)) 6646 (CHIP_ID(bp) == CHIP_ID_5708_A0))
6610 net_stats->tx_carrier_errors = 0; 6647 net_stats->tx_carrier_errors = 0;
6611 else { 6648 else {
6612 net_stats->tx_carrier_errors = 6649 net_stats->tx_carrier_errors =
6613 (unsigned long) 6650 GET_32BIT_NET_STATS(stat_Dot3StatsCarrierSenseErrors);
6614 stats_blk->stat_Dot3StatsCarrierSenseErrors;
6615 } 6651 }
6616 6652
6617 net_stats->tx_errors = 6653 net_stats->tx_errors =
6618 (unsigned long) 6654 GET_32BIT_NET_STATS(stat_emac_tx_stat_dot3statsinternalmactransmiterrors) +
6619 stats_blk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors
6620 +
6621 net_stats->tx_aborted_errors + 6655 net_stats->tx_aborted_errors +
6622 net_stats->tx_carrier_errors; 6656 net_stats->tx_carrier_errors;
6623 6657
6624 net_stats->rx_missed_errors = 6658 net_stats->rx_missed_errors =
6625 (unsigned long) (stats_blk->stat_IfInFTQDiscards + 6659 GET_32BIT_NET_STATS(stat_IfInFTQDiscards) +
6626 stats_blk->stat_IfInMBUFDiscards + stats_blk->stat_FwRxDrop); 6660 GET_32BIT_NET_STATS(stat_IfInMBUFDiscards) +
6661 GET_32BIT_NET_STATS(stat_FwRxDrop);
6627 6662
6628 return net_stats; 6663 return net_stats;
6629} 6664}
@@ -7083,6 +7118,9 @@ static int
7083bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx) 7118bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
7084{ 7119{
7085 if (netif_running(bp->dev)) { 7120 if (netif_running(bp->dev)) {
7121 /* Reset will erase chipset stats; save them */
7122 bnx2_save_stats(bp);
7123
7086 bnx2_netif_stop(bp); 7124 bnx2_netif_stop(bp);
7087 bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); 7125 bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
7088 bnx2_free_skbs(bp); 7126 bnx2_free_skbs(bp);
@@ -7427,6 +7465,7 @@ bnx2_get_ethtool_stats(struct net_device *dev,
7427 struct bnx2 *bp = netdev_priv(dev); 7465 struct bnx2 *bp = netdev_priv(dev);
7428 int i; 7466 int i;
7429 u32 *hw_stats = (u32 *) bp->stats_blk; 7467 u32 *hw_stats = (u32 *) bp->stats_blk;
7468 u32 *temp_stats = (u32 *) bp->temp_stats_blk;
7430 u8 *stats_len_arr = NULL; 7469 u8 *stats_len_arr = NULL;
7431 7470
7432 if (hw_stats == NULL) { 7471 if (hw_stats == NULL) {
@@ -7443,21 +7482,26 @@ bnx2_get_ethtool_stats(struct net_device *dev,
7443 stats_len_arr = bnx2_5708_stats_len_arr; 7482 stats_len_arr = bnx2_5708_stats_len_arr;
7444 7483
7445 for (i = 0; i < BNX2_NUM_STATS; i++) { 7484 for (i = 0; i < BNX2_NUM_STATS; i++) {
7485 unsigned long offset;
7486
7446 if (stats_len_arr[i] == 0) { 7487 if (stats_len_arr[i] == 0) {
7447 /* skip this counter */ 7488 /* skip this counter */
7448 buf[i] = 0; 7489 buf[i] = 0;
7449 continue; 7490 continue;
7450 } 7491 }
7492
7493 offset = bnx2_stats_offset_arr[i];
7451 if (stats_len_arr[i] == 4) { 7494 if (stats_len_arr[i] == 4) {
7452 /* 4-byte counter */ 7495 /* 4-byte counter */
7453 buf[i] = (u64) 7496 buf[i] = (u64) *(hw_stats + offset) +
7454 *(hw_stats + bnx2_stats_offset_arr[i]); 7497 *(temp_stats + offset);
7455 continue; 7498 continue;
7456 } 7499 }
7457 /* 8-byte counter */ 7500 /* 8-byte counter */
7458 buf[i] = (((u64) *(hw_stats + 7501 buf[i] = (((u64) *(hw_stats + offset)) << 32) +
7459 bnx2_stats_offset_arr[i])) << 32) + 7502 *(hw_stats + offset + 1) +
7460 *(hw_stats + bnx2_stats_offset_arr[i] + 1); 7503 (((u64) *(temp_stats + offset)) << 32) +
7504 *(temp_stats + offset + 1);
7461 } 7505 }
7462} 7506}
7463 7507
@@ -7825,6 +7869,14 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
7825 bp->flags = 0; 7869 bp->flags = 0;
7826 bp->phy_flags = 0; 7870 bp->phy_flags = 0;
7827 7871
7872 bp->temp_stats_blk =
7873 kzalloc(sizeof(struct statistics_block), GFP_KERNEL);
7874
7875 if (bp->temp_stats_blk == NULL) {
7876 rc = -ENOMEM;
7877 goto err_out;
7878 }
7879
7828 /* enable device (incl. PCI PM wakeup), and bus-mastering */ 7880 /* enable device (incl. PCI PM wakeup), and bus-mastering */
7829 rc = pci_enable_device(pdev); 7881 rc = pci_enable_device(pdev);
7830 if (rc) { 7882 if (rc) {
@@ -8346,6 +8398,8 @@ bnx2_remove_one(struct pci_dev *pdev)
8346 if (bp->regview) 8398 if (bp->regview)
8347 iounmap(bp->regview); 8399 iounmap(bp->regview);
8348 8400
8401 kfree(bp->temp_stats_blk);
8402
8349 free_netdev(dev); 8403 free_netdev(dev);
8350 pci_release_regions(pdev); 8404 pci_release_regions(pdev);
8351 pci_disable_device(pdev); 8405 pci_disable_device(pdev);