diff options
-rw-r--r-- | drivers/net/e100.c | 66 | ||||
-rw-r--r-- | drivers/net/e1000/e1000.h | 3 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_ethtool.c | 50 | ||||
-rw-r--r-- | drivers/net/igb/igb_ethtool.c | 37 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_ethtool.c | 11 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 21 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_type.h | 8 |
7 files changed, 100 insertions, 96 deletions
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 29f812d..e336c79 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -593,7 +593,6 @@ struct nic { enum phy phy; struct params params; struct timer_list watchdog; - struct timer_list blink_timer; struct mii_if_info mii; struct work_struct tx_timeout_task; enum loopback loopback; @@ -618,7 +617,6 @@ struct nic { u32 rx_tco_frames; u32 rx_over_length_errors; - u16 leds; u16 eeprom_wc; __le16 eeprom[256]; spinlock_t mdio_lock; @@ -2353,30 +2351,6 @@ err_clean_rx: #define E100_82552_LED_OVERRIDE 0x19 #define E100_82552_LED_ON 0x000F /* LEDTX and LED_RX both on */ #define E100_82552_LED_OFF 0x000A /* LEDTX and LED_RX both off */ -static void e100_blink_led(unsigned long data) -{ - struct nic *nic = (struct nic *)data; - enum led_state { - led_on = 0x01, - led_off = 0x04, - led_on_559 = 0x05, - led_on_557 = 0x07, - }; - u16 led_reg = MII_LED_CONTROL; - - if (nic->phy == phy_82552_v) { - led_reg = E100_82552_LED_OVERRIDE; - - nic->leds = (nic->leds == E100_82552_LED_ON) ? - E100_82552_LED_OFF : E100_82552_LED_ON; - } else { - nic->leds = (nic->leds & led_on) ? led_off : - (nic->mac < mac_82559_D101M) ? led_on_557 : - led_on_559; - } - mdio_write(nic->netdev, nic->mii.phy_id, led_reg, nic->leds); - mod_timer(&nic->blink_timer, jiffies + HZ / 4); -} static int e100_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) { @@ -2600,19 +2574,38 @@ static void e100_diag_test(struct net_device *netdev, msleep_interruptible(4 * 1000); } -static int e100_phys_id(struct net_device *netdev, u32 data) +static int e100_set_phys_id(struct net_device *netdev, + enum ethtool_phys_id_state state) { struct nic *nic = netdev_priv(netdev); + enum led_state { + led_on = 0x01, + led_off = 0x04, + led_on_559 = 0x05, + led_on_557 = 0x07, + }; u16 led_reg = (nic->phy == phy_82552_v) ? E100_82552_LED_OVERRIDE : - MII_LED_CONTROL; + MII_LED_CONTROL; + u16 leds = 0; + + switch (state) { + case ETHTOOL_ID_ACTIVE: + return 2; - if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) - data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ); - mod_timer(&nic->blink_timer, jiffies); - msleep_interruptible(data * 1000); - del_timer_sync(&nic->blink_timer); - mdio_write(netdev, nic->mii.phy_id, led_reg, 0); + case ETHTOOL_ID_ON: + leds = (nic->phy == phy_82552_v) ? E100_82552_LED_ON : + (nic->mac < mac_82559_D101M) ? led_on_557 : led_on_559; + break; + + case ETHTOOL_ID_OFF: + leds = (nic->phy == phy_82552_v) ? E100_82552_LED_OFF : led_off; + break; + + case ETHTOOL_ID_INACTIVE: + break; + } + mdio_write(netdev, nic->mii.phy_id, led_reg, leds); return 0; } @@ -2693,7 +2686,7 @@ static const struct ethtool_ops e100_ethtool_ops = { .set_ringparam = e100_set_ringparam, .self_test = e100_diag_test, .get_strings = e100_get_strings, - .phys_id = e100_phys_id, + .set_phys_id = e100_set_phys_id, .get_ethtool_stats = e100_get_ethtool_stats, .get_sset_count = e100_get_sset_count, }; @@ -2834,9 +2827,6 @@ static int __devinit e100_probe(struct pci_dev *pdev, init_timer(&nic->watchdog); nic->watchdog.function = e100_watchdog; nic->watchdog.data = (unsigned long)nic; - init_timer(&nic->blink_timer); - nic->blink_timer.function = e100_blink_led; - nic->blink_timer.data = (unsigned long)nic; INIT_WORK(&nic->tx_timeout_task, e100_tx_timeout_task); diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index b1b23dd..8676899 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -238,9 +238,6 @@ struct e1000_adapter { struct work_struct reset_task; u8 fc_autoneg; - struct timer_list blink_timer; - unsigned long led_status; - /* TX */ struct e1000_tx_ring *tx_ring; /* One per active queue */ unsigned int restart_queue; diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 4fa727c..ec0fa42 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -1755,46 +1755,28 @@ static int e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) return 0; } -/* toggle LED 4 times per second = 2 "blinks" per second */ -#define E1000_ID_INTERVAL (HZ/4) - -/* bit defines for adapter->led_status */ -#define E1000_LED_ON 0 - -static void e1000_led_blink_callback(unsigned long data) +static int e1000_set_phys_id(struct net_device *netdev, + enum ethtool_phys_id_state state) { - struct e1000_adapter *adapter = (struct e1000_adapter *) data; + struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - if (test_and_change_bit(E1000_LED_ON, &adapter->led_status)) - e1000_led_off(hw); - else - e1000_led_on(hw); - - mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL); -} + switch (state) { + case ETHTOOL_ID_ACTIVE: + e1000_setup_led(hw); + return 2; -static int e1000_phys_id(struct net_device *netdev, u32 data) -{ - struct e1000_adapter *adapter = netdev_priv(netdev); - struct e1000_hw *hw = &adapter->hw; + case ETHTOOL_ID_ON: + e1000_led_on(hw); + break; - if (!data) - data = INT_MAX; + case ETHTOOL_ID_OFF: + e1000_led_off(hw); + break; - if (!adapter->blink_timer.function) { - init_timer(&adapter->blink_timer); - adapter->blink_timer.function = e1000_led_blink_callback; - adapter->blink_timer.data = (unsigned long)adapter; + case ETHTOOL_ID_INACTIVE: + e1000_cleanup_led(hw); } - e1000_setup_led(hw); - mod_timer(&adapter->blink_timer, jiffies); - msleep_interruptible(data * 1000); - del_timer_sync(&adapter->blink_timer); - - e1000_led_off(hw); - clear_bit(E1000_LED_ON, &adapter->led_status); - e1000_cleanup_led(hw); return 0; } @@ -1931,7 +1913,7 @@ static const struct ethtool_ops e1000_ethtool_ops = { .set_tso = e1000_set_tso, .self_test = e1000_diag_test, .get_strings = e1000_get_strings, - .phys_id = e1000_phys_id, + .set_phys_id = e1000_set_phys_id, .get_ethtool_stats = e1000_get_ethtool_stats, .get_sset_count = e1000_get_sset_count, .get_coalesce = e1000_get_coalesce, diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index 6e29634..fdc895e 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -1964,27 +1964,28 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) /* bit defines for adapter->led_status */ #define IGB_LED_ON 0 -static int igb_phys_id(struct net_device *netdev, u32 data) +static int igb_set_phys_id(struct net_device *netdev, + enum ethtool_phys_id_state state) { struct igb_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - unsigned long timeout; - timeout = data * 1000; - - /* - * msleep_interruptable only accepts unsigned int so we are limited - * in how long a duration we can wait - */ - if (!timeout || timeout > UINT_MAX) - timeout = UINT_MAX; - - igb_blink_led(hw); - msleep_interruptible(timeout); - - igb_led_off(hw); - clear_bit(IGB_LED_ON, &adapter->led_status); - igb_cleanup_led(hw); + switch (state) { + case ETHTOOL_ID_ACTIVE: + igb_blink_led(hw); + return 2; + case ETHTOOL_ID_ON: + igb_blink_led(hw); + break; + case ETHTOOL_ID_OFF: + igb_led_off(hw); + break; + case ETHTOOL_ID_INACTIVE: + igb_led_off(hw); + clear_bit(IGB_LED_ON, &adapter->led_status); + igb_cleanup_led(hw); + break; + } return 0; } @@ -2216,7 +2217,7 @@ static const struct ethtool_ops igb_ethtool_ops = { .set_tso = igb_set_tso, .self_test = igb_diag_test, .get_strings = igb_get_strings, - .phys_id = igb_phys_id, + .set_phys_id = igb_set_phys_id, .get_sset_count = igb_get_sset_count, .get_ethtool_stats = igb_get_ethtool_stats, .get_coalesce = igb_get_coalesce, diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index f2efa324..1fdd075 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -102,6 +102,10 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = { {"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)}, {"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)}, {"rx_no_dma_resources", IXGBE_STAT(hw_rx_no_dma_resources)}, + {"os2bmc_rx_by_bmc", IXGBE_STAT(stats.o2bgptc)}, + {"os2bmc_tx_by_bmc", IXGBE_STAT(stats.b2ospc)}, + {"os2bmc_tx_by_host", IXGBE_STAT(stats.o2bspc)}, + {"os2bmc_rx_by_host", IXGBE_STAT(stats.b2ogprc)}, #ifdef IXGBE_FCOE {"fcoe_bad_fccrc", IXGBE_STAT(stats.fccrc)}, {"rx_fcoe_dropped", IXGBE_STAT(stats.fcoerpdc)}, @@ -2253,8 +2257,13 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) need_reset = (data & ETH_FLAG_RXVLAN) != (netdev->features & NETIF_F_HW_VLAN_RX); + if ((data & ETH_FLAG_RXHASH) && + !(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) + return -EOPNOTSUPP; + rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | ETH_FLAG_NTUPLE | - ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN); + ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | + ETH_FLAG_RXHASH); if (rc) return rc; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index eebb192..a3e384b 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1063,8 +1063,14 @@ static int __ixgbe_notify_dca(struct device *dev, void *data) return 0; } - #endif /* CONFIG_IXGBE_DCA */ + +static inline void ixgbe_rx_hash(union ixgbe_adv_rx_desc *rx_desc, + struct sk_buff *skb) +{ + skb->rxhash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss); +} + /** * ixgbe_receive_skb - Send a completed packet up the stack * @adapter: board private structure @@ -1456,6 +1462,8 @@ static void ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, } ixgbe_rx_checksum(adapter, rx_desc, skb); + if (adapter->netdev->features & NETIF_F_RXHASH) + ixgbe_rx_hash(rx_desc, skb); /* probably a little skewed due to removing CRC */ total_rx_bytes += skb->len; @@ -5904,8 +5912,13 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH); hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH); break; - case ixgbe_mac_82599EB: case ixgbe_mac_X540: + /* OS2BMC stats are X540 only*/ + hwstats->o2bgptc += IXGBE_READ_REG(hw, IXGBE_O2BGPTC); + hwstats->o2bspc += IXGBE_READ_REG(hw, IXGBE_O2BSPC); + hwstats->b2ospc += IXGBE_READ_REG(hw, IXGBE_B2OSPC); + hwstats->b2ogprc += IXGBE_READ_REG(hw, IXGBE_B2OGPRC); + case ixgbe_mac_82599EB: hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCL); IXGBE_READ_REG(hw, IXGBE_GORCH); /* to clear */ hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL); @@ -7361,6 +7374,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, netdev->features |= NETIF_F_TSO; netdev->features |= NETIF_F_TSO6; netdev->features |= NETIF_F_GRO; + netdev->features |= NETIF_F_RXHASH; switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: @@ -7441,6 +7455,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, if (err) goto err_sw_init; + if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED)) + netdev->features &= ~NETIF_F_RXHASH; + switch (pdev->device) { case IXGBE_DEV_ID_82599_SFP: /* Only this subdevice supports WOL */ diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index b1d523c..70e6870 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -672,6 +672,10 @@ #define IXGBE_FCOEDWRC 0x0242C /* Number of FCoE DWords Received */ #define IXGBE_FCOEPTC 0x08784 /* Number of FCoE Packets Transmitted */ #define IXGBE_FCOEDWTC 0x08788 /* Number of FCoE DWords Transmitted */ +#define IXGBE_O2BGPTC 0x041C4 +#define IXGBE_O2BSPC 0x087B0 +#define IXGBE_B2OSPC 0x041C0 +#define IXGBE_B2OGPRC 0x02F90 #define IXGBE_PCRC8ECL 0x0E810 #define IXGBE_PCRC8ECH 0x0E811 #define IXGBE_PCRC8ECH_MASK 0x1F @@ -2554,6 +2558,10 @@ struct ixgbe_hw_stats { u64 fcoeptc; u64 fcoedwrc; u64 fcoedwtc; + u64 b2ospc; + u64 b2ogprc; + u64 o2bgptc; + u64 o2bspc; }; /* forward declaration */ |