aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/netdev.c
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2008-04-23 14:09:00 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-04-25 02:07:11 -0400
commit7c25769f88ff0b186766d6a9f9390a2e9fd4670f (patch)
treec47607674ec0b14ddfc4f022822f49dbb9b4950f /drivers/net/e1000e/netdev.c
parentc9fcbf4774d7a29b73078017af25d100f152a4af (diff)
e1000e: cleanup several stats issues
Several stats registers are completely unused and we just waste pci bus time reading them. We also omit using the high 32 bits of the GORC/ GOTC counters. We can just read clear them and only read the low registers. Mii-tool can also break es2lan if it executes a MII PHY register ioctl while the device is in autonegotiation. Unfortunately it seems that several applications and installations still perform this ioctl call periodically and especially in this crucial startup time. We can fool the ioctl by providing fail safe information that mimics the "down" link state and only perform the dangerous PHY reads once after link comes up to fill in the real values. As long as link stays up the information will not change. Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/e1000e/netdev.c')
-rw-r--r--drivers/net/e1000e/netdev.c155
1 files changed, 94 insertions, 61 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index c8dc47fd132a..9d1143aa6189 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -466,10 +466,10 @@ next_desc:
466 if (cleaned_count) 466 if (cleaned_count)
467 adapter->alloc_rx_buf(adapter, cleaned_count); 467 adapter->alloc_rx_buf(adapter, cleaned_count);
468 468
469 adapter->total_rx_packets += total_rx_packets;
470 adapter->total_rx_bytes += total_rx_bytes; 469 adapter->total_rx_bytes += total_rx_bytes;
471 adapter->net_stats.rx_packets += total_rx_packets; 470 adapter->total_rx_packets += total_rx_packets;
472 adapter->net_stats.rx_bytes += total_rx_bytes; 471 adapter->net_stats.rx_bytes += total_rx_bytes;
472 adapter->net_stats.rx_packets += total_rx_packets;
473 return cleaned; 473 return cleaned;
474} 474}
475 475
@@ -606,8 +606,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
606 } 606 }
607 adapter->total_tx_bytes += total_tx_bytes; 607 adapter->total_tx_bytes += total_tx_bytes;
608 adapter->total_tx_packets += total_tx_packets; 608 adapter->total_tx_packets += total_tx_packets;
609 adapter->net_stats.tx_packets += total_tx_packets;
610 adapter->net_stats.tx_bytes += total_tx_bytes; 609 adapter->net_stats.tx_bytes += total_tx_bytes;
610 adapter->net_stats.tx_packets += total_tx_packets;
611 return cleaned; 611 return cleaned;
612} 612}
613 613
@@ -775,10 +775,10 @@ next_desc:
775 if (cleaned_count) 775 if (cleaned_count)
776 adapter->alloc_rx_buf(adapter, cleaned_count); 776 adapter->alloc_rx_buf(adapter, cleaned_count);
777 777
778 adapter->total_rx_packets += total_rx_packets;
779 adapter->total_rx_bytes += total_rx_bytes; 778 adapter->total_rx_bytes += total_rx_bytes;
780 adapter->net_stats.rx_packets += total_rx_packets; 779 adapter->total_rx_packets += total_rx_packets;
781 adapter->net_stats.rx_bytes += total_rx_bytes; 780 adapter->net_stats.rx_bytes += total_rx_bytes;
781 adapter->net_stats.rx_packets += total_rx_packets;
782 return cleaned; 782 return cleaned;
783} 783}
784 784
@@ -2506,56 +2506,27 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
2506 2506
2507 adapter->stats.crcerrs += er32(CRCERRS); 2507 adapter->stats.crcerrs += er32(CRCERRS);
2508 adapter->stats.gprc += er32(GPRC); 2508 adapter->stats.gprc += er32(GPRC);
2509 adapter->stats.gorcl += er32(GORCL); 2509 adapter->stats.gorc += er32(GORCL);
2510 adapter->stats.gorch += er32(GORCH); 2510 er32(GORCH); /* Clear gorc */
2511 adapter->stats.bprc += er32(BPRC); 2511 adapter->stats.bprc += er32(BPRC);
2512 adapter->stats.mprc += er32(MPRC); 2512 adapter->stats.mprc += er32(MPRC);
2513 adapter->stats.roc += er32(ROC); 2513 adapter->stats.roc += er32(ROC);
2514 2514
2515 if (adapter->flags & FLAG_HAS_STATS_PTC_PRC) {
2516 adapter->stats.prc64 += er32(PRC64);
2517 adapter->stats.prc127 += er32(PRC127);
2518 adapter->stats.prc255 += er32(PRC255);
2519 adapter->stats.prc511 += er32(PRC511);
2520 adapter->stats.prc1023 += er32(PRC1023);
2521 adapter->stats.prc1522 += er32(PRC1522);
2522 adapter->stats.symerrs += er32(SYMERRS);
2523 adapter->stats.sec += er32(SEC);
2524 }
2525
2526 adapter->stats.mpc += er32(MPC); 2515 adapter->stats.mpc += er32(MPC);
2527 adapter->stats.scc += er32(SCC); 2516 adapter->stats.scc += er32(SCC);
2528 adapter->stats.ecol += er32(ECOL); 2517 adapter->stats.ecol += er32(ECOL);
2529 adapter->stats.mcc += er32(MCC); 2518 adapter->stats.mcc += er32(MCC);
2530 adapter->stats.latecol += er32(LATECOL); 2519 adapter->stats.latecol += er32(LATECOL);
2531 adapter->stats.dc += er32(DC); 2520 adapter->stats.dc += er32(DC);
2532 adapter->stats.rlec += er32(RLEC);
2533 adapter->stats.xonrxc += er32(XONRXC); 2521 adapter->stats.xonrxc += er32(XONRXC);
2534 adapter->stats.xontxc += er32(XONTXC); 2522 adapter->stats.xontxc += er32(XONTXC);
2535 adapter->stats.xoffrxc += er32(XOFFRXC); 2523 adapter->stats.xoffrxc += er32(XOFFRXC);
2536 adapter->stats.xofftxc += er32(XOFFTXC); 2524 adapter->stats.xofftxc += er32(XOFFTXC);
2537 adapter->stats.fcruc += er32(FCRUC);
2538 adapter->stats.gptc += er32(GPTC); 2525 adapter->stats.gptc += er32(GPTC);
2539 adapter->stats.gotcl += er32(GOTCL); 2526 adapter->stats.gotc += er32(GOTCL);
2540 adapter->stats.gotch += er32(GOTCH); 2527 er32(GOTCH); /* Clear gotc */
2541 adapter->stats.rnbc += er32(RNBC); 2528 adapter->stats.rnbc += er32(RNBC);
2542 adapter->stats.ruc += er32(RUC); 2529 adapter->stats.ruc += er32(RUC);
2543 adapter->stats.rfc += er32(RFC);
2544 adapter->stats.rjc += er32(RJC);
2545 adapter->stats.torl += er32(TORL);
2546 adapter->stats.torh += er32(TORH);
2547 adapter->stats.totl += er32(TOTL);
2548 adapter->stats.toth += er32(TOTH);
2549 adapter->stats.tpr += er32(TPR);
2550
2551 if (adapter->flags & FLAG_HAS_STATS_PTC_PRC) {
2552 adapter->stats.ptc64 += er32(PTC64);
2553 adapter->stats.ptc127 += er32(PTC127);
2554 adapter->stats.ptc255 += er32(PTC255);
2555 adapter->stats.ptc511 += er32(PTC511);
2556 adapter->stats.ptc1023 += er32(PTC1023);
2557 adapter->stats.ptc1522 += er32(PTC1522);
2558 }
2559 2530
2560 adapter->stats.mptc += er32(MPTC); 2531 adapter->stats.mptc += er32(MPTC);
2561 adapter->stats.bptc += er32(BPTC); 2532 adapter->stats.bptc += er32(BPTC);
@@ -2574,19 +2545,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
2574 adapter->stats.tsctc += er32(TSCTC); 2545 adapter->stats.tsctc += er32(TSCTC);
2575 adapter->stats.tsctfc += er32(TSCTFC); 2546 adapter->stats.tsctfc += er32(TSCTFC);
2576 2547
2577 adapter->stats.iac += er32(IAC);
2578
2579 if (adapter->flags & FLAG_HAS_STATS_ICR_ICT) {
2580 adapter->stats.icrxoc += er32(ICRXOC);
2581 adapter->stats.icrxptc += er32(ICRXPTC);
2582 adapter->stats.icrxatc += er32(ICRXATC);
2583 adapter->stats.ictxptc += er32(ICTXPTC);
2584 adapter->stats.ictxatc += er32(ICTXATC);
2585 adapter->stats.ictxqec += er32(ICTXQEC);
2586 adapter->stats.ictxqmtc += er32(ICTXQMTC);
2587 adapter->stats.icrxdmtc += er32(ICRXDMTC);
2588 }
2589
2590 /* Fill out the OS statistics structure */ 2548 /* Fill out the OS statistics structure */
2591 adapter->net_stats.multicast = adapter->stats.mprc; 2549 adapter->net_stats.multicast = adapter->stats.mprc;
2592 adapter->net_stats.collisions = adapter->stats.colc; 2550 adapter->net_stats.collisions = adapter->stats.colc;
@@ -2633,6 +2591,54 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
2633 spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); 2591 spin_unlock_irqrestore(&adapter->stats_lock, irq_flags);
2634} 2592}
2635 2593
2594/**
2595 * e1000_phy_read_status - Update the PHY register status snapshot
2596 * @adapter: board private structure
2597 **/
2598static void e1000_phy_read_status(struct e1000_adapter *adapter)
2599{
2600 struct e1000_hw *hw = &adapter->hw;
2601 struct e1000_phy_regs *phy = &adapter->phy_regs;
2602 int ret_val;
2603 unsigned long irq_flags;
2604
2605
2606 spin_lock_irqsave(&adapter->stats_lock, irq_flags);
2607
2608 if ((er32(STATUS) & E1000_STATUS_LU) &&
2609 (adapter->hw.phy.media_type == e1000_media_type_copper)) {
2610 ret_val = e1e_rphy(hw, PHY_CONTROL, &phy->bmcr);
2611 ret_val |= e1e_rphy(hw, PHY_STATUS, &phy->bmsr);
2612 ret_val |= e1e_rphy(hw, PHY_AUTONEG_ADV, &phy->advertise);
2613 ret_val |= e1e_rphy(hw, PHY_LP_ABILITY, &phy->lpa);
2614 ret_val |= e1e_rphy(hw, PHY_AUTONEG_EXP, &phy->expansion);
2615 ret_val |= e1e_rphy(hw, PHY_1000T_CTRL, &phy->ctrl1000);
2616 ret_val |= e1e_rphy(hw, PHY_1000T_STATUS, &phy->stat1000);
2617 ret_val |= e1e_rphy(hw, PHY_EXT_STATUS, &phy->estatus);
2618 if (ret_val)
2619 ndev_warn(adapter->netdev,
2620 "Error reading PHY register\n");
2621 } else {
2622 /*
2623 * Do not read PHY registers if link is not up
2624 * Set values to typical power-on defaults
2625 */
2626 phy->bmcr = (BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_FULLDPLX);
2627 phy->bmsr = (BMSR_100FULL | BMSR_100HALF | BMSR_10FULL |
2628 BMSR_10HALF | BMSR_ESTATEN | BMSR_ANEGCAPABLE |
2629 BMSR_ERCAP);
2630 phy->advertise = (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP |
2631 ADVERTISE_ALL | ADVERTISE_CSMA);
2632 phy->lpa = 0;
2633 phy->expansion = EXPANSION_ENABLENPAGE;
2634 phy->ctrl1000 = ADVERTISE_1000FULL;
2635 phy->stat1000 = 0;
2636 phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF);
2637 }
2638
2639 spin_unlock_irqrestore(&adapter->stats_lock, irq_flags);
2640}
2641
2636static void e1000_print_link_info(struct e1000_adapter *adapter) 2642static void e1000_print_link_info(struct e1000_adapter *adapter)
2637{ 2643{
2638 struct e1000_hw *hw = &adapter->hw; 2644 struct e1000_hw *hw = &adapter->hw;
@@ -2745,6 +2751,7 @@ static void e1000_watchdog_task(struct work_struct *work)
2745 if (!netif_carrier_ok(netdev)) { 2751 if (!netif_carrier_ok(netdev)) {
2746 bool txb2b = 1; 2752 bool txb2b = 1;
2747 /* update snapshot of PHY registers on LSC */ 2753 /* update snapshot of PHY registers on LSC */
2754 e1000_phy_read_status(adapter);
2748 mac->ops.get_link_up_info(&adapter->hw, 2755 mac->ops.get_link_up_info(&adapter->hw,
2749 &adapter->link_speed, 2756 &adapter->link_speed,
2750 &adapter->link_duplex); 2757 &adapter->link_duplex);
@@ -2842,10 +2849,10 @@ link_up:
2842 mac->collision_delta = adapter->stats.colc - adapter->colc_old; 2849 mac->collision_delta = adapter->stats.colc - adapter->colc_old;
2843 adapter->colc_old = adapter->stats.colc; 2850 adapter->colc_old = adapter->stats.colc;
2844 2851
2845 adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old; 2852 adapter->gorc = adapter->stats.gorc - adapter->gorc_old;
2846 adapter->gorcl_old = adapter->stats.gorcl; 2853 adapter->gorc_old = adapter->stats.gorc;
2847 adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old; 2854 adapter->gotc = adapter->stats.gotc - adapter->gotc_old;
2848 adapter->gotcl_old = adapter->stats.gotcl; 2855 adapter->gotc_old = adapter->stats.gotc;
2849 2856
2850 e1000e_update_adaptive(&adapter->hw); 2857 e1000e_update_adaptive(&adapter->hw);
2851 2858
@@ -3500,7 +3507,6 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
3500{ 3507{
3501 struct e1000_adapter *adapter = netdev_priv(netdev); 3508 struct e1000_adapter *adapter = netdev_priv(netdev);
3502 struct mii_ioctl_data *data = if_mii(ifr); 3509 struct mii_ioctl_data *data = if_mii(ifr);
3503 unsigned long irq_flags;
3504 3510
3505 if (adapter->hw.phy.media_type != e1000_media_type_copper) 3511 if (adapter->hw.phy.media_type != e1000_media_type_copper)
3506 return -EOPNOTSUPP; 3512 return -EOPNOTSUPP;
@@ -3512,13 +3518,40 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
3512 case SIOCGMIIREG: 3518 case SIOCGMIIREG:
3513 if (!capable(CAP_NET_ADMIN)) 3519 if (!capable(CAP_NET_ADMIN))
3514 return -EPERM; 3520 return -EPERM;
3515 spin_lock_irqsave(&adapter->stats_lock, irq_flags); 3521 switch (data->reg_num & 0x1F) {
3516 if (e1e_rphy(&adapter->hw, data->reg_num & 0x1F, 3522 case MII_BMCR:
3517 &data->val_out)) { 3523 data->val_out = adapter->phy_regs.bmcr;
3518 spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); 3524 break;
3525 case MII_BMSR:
3526 data->val_out = adapter->phy_regs.bmsr;
3527 break;
3528 case MII_PHYSID1:
3529 data->val_out = (adapter->hw.phy.id >> 16);
3530 break;
3531 case MII_PHYSID2:
3532 data->val_out = (adapter->hw.phy.id & 0xFFFF);
3533 break;
3534 case MII_ADVERTISE:
3535 data->val_out = adapter->phy_regs.advertise;
3536 break;
3537 case MII_LPA:
3538 data->val_out = adapter->phy_regs.lpa;
3539 break;
3540 case MII_EXPANSION:
3541 data->val_out = adapter->phy_regs.expansion;
3542 break;
3543 case MII_CTRL1000:
3544 data->val_out = adapter->phy_regs.ctrl1000;
3545 break;
3546 case MII_STAT1000:
3547 data->val_out = adapter->phy_regs.stat1000;
3548 break;
3549 case MII_ESTATUS:
3550 data->val_out = adapter->phy_regs.estatus;
3551 break;
3552 default:
3519 return -EIO; 3553 return -EIO;
3520 } 3554 }
3521 spin_unlock_irqrestore(&adapter->stats_lock, irq_flags);
3522 break; 3555 break;
3523 case SIOCSMIIREG: 3556 case SIOCSMIIREG:
3524 default: 3557 default: