Merge branch '10GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates 2015-12-03

This series contains updates to ixgbe and ixgbevf only.

Mark cleans up ixgbe_init_phy_ops_x550em, since this was designed to
initialize function pointers only and moves the KR PHY reset to the
ixgbe_setup_internal_phy_t_x550em which was designed to detect which
mode the PHY operates in and set it up.  Added the new thermal alarm
type support used with newer X550EM_x devices.  Fixed both ixgbe and
ixgbevf to use a private work queue to avoid hangs, which would
possibly occur when creating and destroying many VFS repeatedly.
Updated ixgbe PTP implementation to accommodate X550EM_x devices,
which handle clocking differently.  Fixed specification violations
in the datasheet, which was reported by Dan Streetman.  Fixed ixgbe
to check for and handle IPv6 extended headers so that Tx checksum
offload can be done, which was reported by Tom Herbert.  Fixed ixgbe
link issue for some systems with X540 or X550 by only inhibiting the
turning PHY power off when manageability is present.

Alex Duyck refactors the MAC address configuration code, which in
turns fixes an issue where once 63 entries had been used, you could no
longer add additional filters.  Updated ixgbe to use __dev_uc_sync
which also resolved an issue in which you could not remove an FDB
address without having to reset the port.  Updated the ixgbe driver
to make use of all the free RAR entries for FDB use if needed.

v2: updated patch 13 to "Alex Duyck Approved" version, in the original
    submission, I had grabbed a previous version of the patch and did not
    catch it was superseded by a later version
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2015-12-03 11:43:32 -05:00
commit 68e14a48fe
12 changed files with 889 additions and 360 deletions

View File

@ -139,6 +139,7 @@ enum ixgbe_tx_flags {
#define IXGBE_X540_VF_DEVICE_ID 0x1515 #define IXGBE_X540_VF_DEVICE_ID 0x1515
struct vf_data_storage { struct vf_data_storage {
struct pci_dev *vfdev;
unsigned char vf_mac_addresses[ETH_ALEN]; unsigned char vf_mac_addresses[ETH_ALEN];
u16 vf_mc_hashes[IXGBE_MAX_VF_MC_ENTRIES]; u16 vf_mc_hashes[IXGBE_MAX_VF_MC_ENTRIES];
u16 num_vf_mc_hashes; u16 num_vf_mc_hashes;
@ -224,6 +225,8 @@ struct ixgbe_rx_queue_stats {
u64 csum_err; u64 csum_err;
}; };
#define IXGBE_TS_HDR_LEN 8
enum ixgbe_ring_state_t { enum ixgbe_ring_state_t {
__IXGBE_TX_FDIR_INIT_DONE, __IXGBE_TX_FDIR_INIT_DONE,
__IXGBE_TX_XPS_INIT_DONE, __IXGBE_TX_XPS_INIT_DONE,
@ -282,6 +285,8 @@ struct ixgbe_ring {
u16 next_to_use; u16 next_to_use;
u16 next_to_clean; u16 next_to_clean;
unsigned long last_rx_timestamp;
union { union {
u16 next_to_alloc; u16 next_to_alloc;
struct { struct {
@ -587,9 +592,10 @@ static inline u16 ixgbe_desc_unused(struct ixgbe_ring *ring)
struct ixgbe_mac_addr { struct ixgbe_mac_addr {
u8 addr[ETH_ALEN]; u8 addr[ETH_ALEN];
u16 queue; u16 pool;
u16 state; /* bitmask */ u16 state; /* bitmask */
}; };
#define IXGBE_MAC_STATE_DEFAULT 0x1 #define IXGBE_MAC_STATE_DEFAULT 0x1
#define IXGBE_MAC_STATE_MODIFIED 0x2 #define IXGBE_MAC_STATE_MODIFIED 0x2
#define IXGBE_MAC_STATE_IN_USE 0x4 #define IXGBE_MAC_STATE_IN_USE 0x4
@ -639,6 +645,8 @@ struct ixgbe_adapter {
#define IXGBE_FLAG_SRIOV_CAPABLE (u32)(1 << 22) #define IXGBE_FLAG_SRIOV_CAPABLE (u32)(1 << 22)
#define IXGBE_FLAG_SRIOV_ENABLED (u32)(1 << 23) #define IXGBE_FLAG_SRIOV_ENABLED (u32)(1 << 23)
#define IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE BIT(24) #define IXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE BIT(24)
#define IXGBE_FLAG_RX_HWTSTAMP_ENABLED BIT(25)
#define IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER BIT(26)
u32 flags2; u32 flags2;
#define IXGBE_FLAG2_RSC_CAPABLE (u32)(1 << 0) #define IXGBE_FLAG2_RSC_CAPABLE (u32)(1 << 0)
@ -755,9 +763,12 @@ struct ixgbe_adapter {
unsigned long last_rx_ptp_check; unsigned long last_rx_ptp_check;
unsigned long last_rx_timestamp; unsigned long last_rx_timestamp;
spinlock_t tmreg_lock; spinlock_t tmreg_lock;
struct cyclecounter cc; struct cyclecounter hw_cc;
struct timecounter tc; struct timecounter hw_tc;
u32 base_incval; u32 base_incval;
u32 tx_hwtstamp_timeouts;
u32 rx_hwtstamp_cleared;
void (*ptp_setup_sdp)(struct ixgbe_adapter *);
/* SR-IOV */ /* SR-IOV */
DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS); DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS);
@ -883,9 +894,9 @@ int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id,
void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter); void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter);
#endif #endif
int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter, int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter,
u8 *addr, u16 queue); const u8 *addr, u16 queue);
int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter, int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter,
u8 *addr, u16 queue); const u8 *addr, u16 queue);
void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter);
netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, struct ixgbe_adapter *, netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, struct ixgbe_adapter *,
struct ixgbe_ring *); struct ixgbe_ring *);
@ -968,12 +979,33 @@ void ixgbe_ptp_suspend(struct ixgbe_adapter *adapter);
void ixgbe_ptp_stop(struct ixgbe_adapter *adapter); void ixgbe_ptp_stop(struct ixgbe_adapter *adapter);
void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter); void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter);
void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter); void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter);
void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb); void ixgbe_ptp_rx_pktstamp(struct ixgbe_q_vector *, struct sk_buff *);
void ixgbe_ptp_rx_rgtstamp(struct ixgbe_q_vector *, struct sk_buff *skb);
static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring,
union ixgbe_adv_rx_desc *rx_desc,
struct sk_buff *skb)
{
if (unlikely(ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_TSIP))) {
ixgbe_ptp_rx_pktstamp(rx_ring->q_vector, skb);
return;
}
if (unlikely(!ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS)))
return;
ixgbe_ptp_rx_rgtstamp(rx_ring->q_vector, skb);
/* Update the last_rx_timestamp timer in order to enable watchdog check
* for error case of latched timestamp on a dropped packet.
*/
rx_ring->last_rx_timestamp = jiffies;
}
int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter);
void ixgbe_ptp_reset(struct ixgbe_adapter *adapter); void ixgbe_ptp_reset(struct ixgbe_adapter *adapter);
void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter, u32 eicr); void ixgbe_ptp_check_pps_event(struct ixgbe_adapter *adapter);
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
void ixgbe_sriov_reinit(struct ixgbe_adapter *adapter); void ixgbe_sriov_reinit(struct ixgbe_adapter *adapter);
#endif #endif

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2014 Intel Corporation. Copyright(c) 1999 - 2015 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
@ -765,13 +765,14 @@ mac_reset_top:
ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL) | IXGBE_CTRL_RST; ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL) | IXGBE_CTRL_RST;
IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
IXGBE_WRITE_FLUSH(hw); IXGBE_WRITE_FLUSH(hw);
usleep_range(1000, 1200);
/* Poll for reset bit to self-clear indicating reset is complete */ /* Poll for reset bit to self-clear indicating reset is complete */
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
udelay(1);
ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
if (!(ctrl & IXGBE_CTRL_RST)) if (!(ctrl & IXGBE_CTRL_RST))
break; break;
udelay(1);
} }
if (ctrl & IXGBE_CTRL_RST) { if (ctrl & IXGBE_CTRL_RST) {
status = IXGBE_ERR_RESET_FAILED; status = IXGBE_ERR_RESET_FAILED;

View File

@ -990,13 +990,14 @@ mac_reset_top:
ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
IXGBE_WRITE_FLUSH(hw); IXGBE_WRITE_FLUSH(hw);
usleep_range(1000, 1200);
/* Poll for reset bit to self-clear indicating reset is complete */ /* Poll for reset bit to self-clear indicating reset is complete */
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
udelay(1);
ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
if (!(ctrl & IXGBE_CTRL_RST_MASK)) if (!(ctrl & IXGBE_CTRL_RST_MASK))
break; break;
udelay(1);
} }
if (ctrl & IXGBE_CTRL_RST_MASK) { if (ctrl & IXGBE_CTRL_RST_MASK) {

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2014 Intel Corporation. Copyright(c) 1999 - 2015 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
@ -2454,6 +2454,17 @@ static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
/* Always set this bit to ensure any future transactions are blocked */ /* Always set this bit to ensure any future transactions are blocked */
IXGBE_WRITE_REG(hw, IXGBE_CTRL, IXGBE_CTRL_GIO_DIS); IXGBE_WRITE_REG(hw, IXGBE_CTRL, IXGBE_CTRL_GIO_DIS);
/* Poll for bit to read as set */
for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
if (IXGBE_READ_REG(hw, IXGBE_CTRL) & IXGBE_CTRL_GIO_DIS)
break;
usleep_range(100, 120);
}
if (i >= IXGBE_PCI_MASTER_DISABLE_TIMEOUT) {
hw_dbg(hw, "GIO disable did not set - requesting resets\n");
goto gio_disable_fail;
}
/* Exit if master requests are blocked */ /* Exit if master requests are blocked */
if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO) || if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO) ||
ixgbe_removed(hw->hw_addr)) ixgbe_removed(hw->hw_addr))
@ -2475,6 +2486,7 @@ static s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
* again to clear out any effects they may have had on our device. * again to clear out any effects they may have had on our device.
*/ */
hw_dbg(hw, "GIO Master Disable bit didn't clear - requesting resets\n"); hw_dbg(hw, "GIO Master Disable bit didn't clear - requesting resets\n");
gio_disable_fail:
hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
if (hw->mac.type >= ixgbe_mac_X550) if (hw->mac.type >= ixgbe_mac_X550)

View File

@ -172,6 +172,8 @@ MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION); MODULE_VERSION(DRV_VERSION);
static struct workqueue_struct *ixgbe_wq;
static bool ixgbe_check_cfg_remove(struct ixgbe_hw *hw, struct pci_dev *pdev); static bool ixgbe_check_cfg_remove(struct ixgbe_hw *hw, struct pci_dev *pdev);
static int ixgbe_read_pci_cfg_word_parent(struct ixgbe_adapter *adapter, static int ixgbe_read_pci_cfg_word_parent(struct ixgbe_adapter *adapter,
@ -313,7 +315,7 @@ static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter)
if (!test_bit(__IXGBE_DOWN, &adapter->state) && if (!test_bit(__IXGBE_DOWN, &adapter->state) &&
!test_bit(__IXGBE_REMOVING, &adapter->state) && !test_bit(__IXGBE_REMOVING, &adapter->state) &&
!test_and_set_bit(__IXGBE_SERVICE_SCHED, &adapter->state)) !test_and_set_bit(__IXGBE_SERVICE_SCHED, &adapter->state))
schedule_work(&adapter->service_task); queue_work(ixgbe_wq, &adapter->service_task);
} }
static void ixgbe_remove_adapter(struct ixgbe_hw *hw) static void ixgbe_remove_adapter(struct ixgbe_hw *hw)
@ -1632,6 +1634,7 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct net_device *dev = rx_ring->netdev; struct net_device *dev = rx_ring->netdev;
u32 flags = rx_ring->q_vector->adapter->flags;
ixgbe_update_rsc_stats(rx_ring, skb); ixgbe_update_rsc_stats(rx_ring, skb);
@ -1639,8 +1642,8 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,
ixgbe_rx_checksum(rx_ring, rx_desc, skb); ixgbe_rx_checksum(rx_ring, rx_desc, skb);
if (unlikely(ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS))) if (unlikely(flags & IXGBE_FLAG_RX_HWTSTAMP_ENABLED))
ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector->adapter, skb); ixgbe_ptp_rx_hwtstamp(rx_ring, rx_desc, skb);
if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) && if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) {
@ -2738,7 +2741,7 @@ static irqreturn_t ixgbe_msix_other(int irq, void *data)
ixgbe_check_fan_failure(adapter, eicr); ixgbe_check_fan_failure(adapter, eicr);
if (unlikely(eicr & IXGBE_EICR_TIMESYNC)) if (unlikely(eicr & IXGBE_EICR_TIMESYNC))
ixgbe_ptp_check_pps_event(adapter, eicr); ixgbe_ptp_check_pps_event(adapter);
/* re-enable the original interrupt state, no lsc, no queues */ /* re-enable the original interrupt state, no lsc, no queues */
if (!test_bit(__IXGBE_DOWN, &adapter->state)) if (!test_bit(__IXGBE_DOWN, &adapter->state))
@ -2945,7 +2948,7 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
ixgbe_check_fan_failure(adapter, eicr); ixgbe_check_fan_failure(adapter, eicr);
if (unlikely(eicr & IXGBE_EICR_TIMESYNC)) if (unlikely(eicr & IXGBE_EICR_TIMESYNC))
ixgbe_ptp_check_pps_event(adapter, eicr); ixgbe_ptp_check_pps_event(adapter);
/* would disable interrupts here but EIAM disabled it */ /* would disable interrupts here but EIAM disabled it */
napi_schedule_irqoff(&q_vector->napi); napi_schedule_irqoff(&q_vector->napi);
@ -4029,124 +4032,156 @@ static int ixgbe_write_mc_addr_list(struct net_device *netdev)
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter) void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0];
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
int i; int i;
for (i = 0; i < hw->mac.num_rar_entries; i++) {
if (adapter->mac_table[i].state & IXGBE_MAC_STATE_IN_USE) for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) {
hw->mac.ops.set_rar(hw, i, adapter->mac_table[i].addr, mac_table->state &= ~IXGBE_MAC_STATE_MODIFIED;
adapter->mac_table[i].queue,
if (mac_table->state & IXGBE_MAC_STATE_IN_USE)
hw->mac.ops.set_rar(hw, i,
mac_table->addr,
mac_table->pool,
IXGBE_RAH_AV); IXGBE_RAH_AV);
else else
hw->mac.ops.clear_rar(hw, i); hw->mac.ops.clear_rar(hw, i);
adapter->mac_table[i].state &= ~(IXGBE_MAC_STATE_MODIFIED);
} }
} }
#endif
#endif
static void ixgbe_sync_mac_table(struct ixgbe_adapter *adapter) static void ixgbe_sync_mac_table(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0];
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
int i; int i;
for (i = 0; i < hw->mac.num_rar_entries; i++) {
if (adapter->mac_table[i].state & IXGBE_MAC_STATE_MODIFIED) { for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) {
if (adapter->mac_table[i].state & if (!(mac_table->state & IXGBE_MAC_STATE_MODIFIED))
IXGBE_MAC_STATE_IN_USE) continue;
mac_table->state &= ~IXGBE_MAC_STATE_MODIFIED;
if (mac_table->state & IXGBE_MAC_STATE_IN_USE)
hw->mac.ops.set_rar(hw, i, hw->mac.ops.set_rar(hw, i,
adapter->mac_table[i].addr, mac_table->addr,
adapter->mac_table[i].queue, mac_table->pool,
IXGBE_RAH_AV); IXGBE_RAH_AV);
else else
hw->mac.ops.clear_rar(hw, i); hw->mac.ops.clear_rar(hw, i);
adapter->mac_table[i].state &=
~(IXGBE_MAC_STATE_MODIFIED);
}
} }
} }
static void ixgbe_flush_sw_mac_table(struct ixgbe_adapter *adapter) static void ixgbe_flush_sw_mac_table(struct ixgbe_adapter *adapter)
{ {
int i; struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0];
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
int i;
for (i = 0; i < hw->mac.num_rar_entries; i++) { for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) {
adapter->mac_table[i].state |= IXGBE_MAC_STATE_MODIFIED; mac_table->state |= IXGBE_MAC_STATE_MODIFIED;
adapter->mac_table[i].state &= ~IXGBE_MAC_STATE_IN_USE; mac_table->state &= ~IXGBE_MAC_STATE_IN_USE;
eth_zero_addr(adapter->mac_table[i].addr);
adapter->mac_table[i].queue = 0;
} }
ixgbe_sync_mac_table(adapter); ixgbe_sync_mac_table(adapter);
} }
static int ixgbe_available_rars(struct ixgbe_adapter *adapter) static int ixgbe_available_rars(struct ixgbe_adapter *adapter, u16 pool)
{ {
struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0];
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
int i, count = 0; int i, count = 0;
for (i = 0; i < hw->mac.num_rar_entries; i++) { for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) {
if (adapter->mac_table[i].state == 0) /* do not count default RAR as available */
if (mac_table->state & IXGBE_MAC_STATE_DEFAULT)
continue;
/* only count unused and addresses that belong to us */
if (mac_table->state & IXGBE_MAC_STATE_IN_USE) {
if (mac_table->pool != pool)
continue;
}
count++; count++;
} }
return count; return count;
} }
/* this function destroys the first RAR entry */ /* this function destroys the first RAR entry */
static void ixgbe_mac_set_default_filter(struct ixgbe_adapter *adapter, static void ixgbe_mac_set_default_filter(struct ixgbe_adapter *adapter)
u8 *addr)
{ {
struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0];
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
memcpy(&adapter->mac_table[0].addr, addr, ETH_ALEN); memcpy(&mac_table->addr, hw->mac.addr, ETH_ALEN);
adapter->mac_table[0].queue = VMDQ_P(0); mac_table->pool = VMDQ_P(0);
adapter->mac_table[0].state = (IXGBE_MAC_STATE_DEFAULT |
IXGBE_MAC_STATE_IN_USE); mac_table->state = IXGBE_MAC_STATE_DEFAULT | IXGBE_MAC_STATE_IN_USE;
hw->mac.ops.set_rar(hw, 0, adapter->mac_table[0].addr,
adapter->mac_table[0].queue, hw->mac.ops.set_rar(hw, 0, mac_table->addr, mac_table->pool,
IXGBE_RAH_AV); IXGBE_RAH_AV);
} }
int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter, u8 *addr, u16 queue) int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter,
const u8 *addr, u16 pool)
{ {
struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0];
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
int i; int i;
if (is_zero_ether_addr(addr)) if (is_zero_ether_addr(addr))
return -EINVAL; return -EINVAL;
for (i = 0; i < hw->mac.num_rar_entries; i++) { for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) {
if (adapter->mac_table[i].state & IXGBE_MAC_STATE_IN_USE) if (mac_table->state & IXGBE_MAC_STATE_IN_USE)
continue; continue;
adapter->mac_table[i].state |= (IXGBE_MAC_STATE_MODIFIED |
IXGBE_MAC_STATE_IN_USE); ether_addr_copy(mac_table->addr, addr);
ether_addr_copy(adapter->mac_table[i].addr, addr); mac_table->pool = pool;
adapter->mac_table[i].queue = queue;
mac_table->state |= IXGBE_MAC_STATE_MODIFIED |
IXGBE_MAC_STATE_IN_USE;
ixgbe_sync_mac_table(adapter); ixgbe_sync_mac_table(adapter);
return i; return i;
} }
return -ENOMEM; return -ENOMEM;
} }
int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter, u8 *addr, u16 queue) int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter,
const u8 *addr, u16 pool)
{ {
/* search table for addr, if found, set to 0 and sync */ struct ixgbe_mac_addr *mac_table = &adapter->mac_table[0];
int i;
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
int i;
if (is_zero_ether_addr(addr)) if (is_zero_ether_addr(addr))
return -EINVAL; return -EINVAL;
for (i = 0; i < hw->mac.num_rar_entries; i++) { /* search table for addr, if found clear IN_USE flag and sync */
if (ether_addr_equal(addr, adapter->mac_table[i].addr) && for (i = 0; i < hw->mac.num_rar_entries; i++, mac_table++) {
adapter->mac_table[i].queue == queue) { /* we can only delete an entry if it is in use */
adapter->mac_table[i].state |= IXGBE_MAC_STATE_MODIFIED; if (!(mac_table->state & IXGBE_MAC_STATE_IN_USE))
adapter->mac_table[i].state &= ~IXGBE_MAC_STATE_IN_USE; continue;
eth_zero_addr(adapter->mac_table[i].addr); /* we only care about entries that belong to the given pool */
adapter->mac_table[i].queue = 0; if (mac_table->pool != pool)
continue;
/* we only care about a specific MAC address */
if (!ether_addr_equal(addr, mac_table->addr))
continue;
mac_table->state |= IXGBE_MAC_STATE_MODIFIED;
mac_table->state &= ~IXGBE_MAC_STATE_IN_USE;
ixgbe_sync_mac_table(adapter); ixgbe_sync_mac_table(adapter);
return 0; return 0;
} }
}
return -ENOMEM; return -ENOMEM;
} }
/** /**
@ -4164,7 +4199,7 @@ static int ixgbe_write_uc_addr_list(struct net_device *netdev, int vfn)
int count = 0; int count = 0;
/* return ENOMEM indicating insufficient memory for addresses */ /* return ENOMEM indicating insufficient memory for addresses */
if (netdev_uc_count(netdev) > ixgbe_available_rars(adapter)) if (netdev_uc_count(netdev) > ixgbe_available_rars(adapter, vfn))
return -ENOMEM; return -ENOMEM;
if (!netdev_uc_empty(netdev)) { if (!netdev_uc_empty(netdev)) {
@ -4178,6 +4213,25 @@ static int ixgbe_write_uc_addr_list(struct net_device *netdev, int vfn)
return count; return count;
} }
static int ixgbe_uc_sync(struct net_device *netdev, const unsigned char *addr)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
int ret;
ret = ixgbe_add_mac_filter(adapter, addr, VMDQ_P(0));
return min_t(int, ret, 0);
}
static int ixgbe_uc_unsync(struct net_device *netdev, const unsigned char *addr)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
ixgbe_del_mac_filter(adapter, addr, VMDQ_P(0));
return 0;
}
/** /**
* ixgbe_set_rx_mode - Unicast, Multicast and Promiscuous mode set * ixgbe_set_rx_mode - Unicast, Multicast and Promiscuous mode set
* @netdev: network interface device structure * @netdev: network interface device structure
@ -4233,8 +4287,7 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
* sufficient space to store all the addresses then enable * sufficient space to store all the addresses then enable
* unicast promiscuous mode * unicast promiscuous mode
*/ */
count = ixgbe_write_uc_addr_list(netdev, VMDQ_P(0)); if (__dev_uc_sync(netdev, ixgbe_uc_sync, ixgbe_uc_unsync)) {
if (count < 0) {
fctrl |= IXGBE_FCTRL_UPE; fctrl |= IXGBE_FCTRL_UPE;
vmolr |= IXGBE_VMOLR_ROPE; vmolr |= IXGBE_VMOLR_ROPE;
} }
@ -5037,7 +5090,6 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
int err; int err;
u8 old_addr[ETH_ALEN];
if (ixgbe_removed(hw->hw_addr)) if (ixgbe_removed(hw->hw_addr))
return; return;
@ -5073,10 +5125,13 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
} }
clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state); clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
/* do not flush user set addresses */
memcpy(old_addr, &adapter->mac_table[0].addr, netdev->addr_len); /* flush entries out of MAC table */
ixgbe_flush_sw_mac_table(adapter); ixgbe_flush_sw_mac_table(adapter);
ixgbe_mac_set_default_filter(adapter, old_addr); __dev_uc_unsync(netdev, NULL);
/* do not flush user set addresses */
ixgbe_mac_set_default_filter(adapter);
/* update SAN MAC vmdq pool selection */ /* update SAN MAC vmdq pool selection */
if (hw->mac.san_mac_rar_index) if (hw->mac.san_mac_rar_index)
@ -6611,10 +6666,8 @@ static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
struct pci_dev *vfdev; unsigned int vf;
u32 gpc; u32 gpc;
int pos;
unsigned short vf_id;
if (!(netif_carrier_ok(adapter->netdev))) if (!(netif_carrier_ok(adapter->netdev)))
return; return;
@ -6631,27 +6684,18 @@ static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter)
if (!pdev) if (!pdev)
return; return;
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
if (!pos)
return;
/* get the device ID for the VF */
pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, &vf_id);
/* check status reg for all VFs owned by this PF */ /* check status reg for all VFs owned by this PF */
vfdev = pci_get_device(pdev->vendor, vf_id, NULL); for (vf = 0; vf < adapter->num_vfs; ++vf) {
while (vfdev) { struct pci_dev *vfdev = adapter->vfinfo[vf].vfdev;
if (vfdev->is_virtfn && (vfdev->physfn == pdev)) {
u16 status_reg; u16 status_reg;
if (!vfdev)
continue;
pci_read_config_word(vfdev, PCI_STATUS, &status_reg); pci_read_config_word(vfdev, PCI_STATUS, &status_reg);
if (status_reg & PCI_STATUS_REC_MASTER_ABORT) if (status_reg != IXGBE_FAILED_READ_CFG_WORD &&
/* issue VFLR */ status_reg & PCI_STATUS_REC_MASTER_ABORT)
ixgbe_issue_vf_flr(adapter, vfdev); ixgbe_issue_vf_flr(adapter, vfdev);
} }
vfdev = pci_get_device(pdev->vendor, vf_id, vfdev);
}
} }
static void ixgbe_spoof_check(struct ixgbe_adapter *adapter) static void ixgbe_spoof_check(struct ixgbe_adapter *adapter)
@ -7019,6 +7063,7 @@ static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
struct tcphdr *tcphdr; struct tcphdr *tcphdr;
u8 *raw; u8 *raw;
} transport_hdr; } transport_hdr;
__be16 frag_off;
if (skb->encapsulation) { if (skb->encapsulation) {
network_hdr.raw = skb_inner_network_header(skb); network_hdr.raw = skb_inner_network_header(skb);
@ -7042,13 +7087,17 @@ static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
case 6: case 6:
vlan_macip_lens |= transport_hdr.raw - network_hdr.raw; vlan_macip_lens |= transport_hdr.raw - network_hdr.raw;
l4_hdr = network_hdr.ipv6->nexthdr; l4_hdr = network_hdr.ipv6->nexthdr;
if (likely((transport_hdr.raw - network_hdr.raw) ==
sizeof(struct ipv6hdr)))
break;
ipv6_skip_exthdr(skb, network_hdr.raw - skb->data +
sizeof(struct ipv6hdr),
&l4_hdr, &frag_off);
if (unlikely(frag_off))
l4_hdr = NEXTHDR_FRAGMENT;
break; break;
default: default:
if (unlikely(net_ratelimit())) { break;
dev_warn(tx_ring->dev,
"partial checksum but version=%d\n",
network_hdr.ipv4->version);
}
} }
switch (l4_hdr) { switch (l4_hdr) {
@ -7069,16 +7118,18 @@ static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
default: default:
if (unlikely(net_ratelimit())) { if (unlikely(net_ratelimit())) {
dev_warn(tx_ring->dev, dev_warn(tx_ring->dev,
"partial checksum but l4 proto=%x!\n", "partial checksum, version=%d, l4 proto=%x\n",
l4_hdr); network_hdr.ipv4->version, l4_hdr);
} }
break; skb_checksum_help(skb);
goto no_csum;
} }
/* update TX checksum flag */ /* update TX checksum flag */
first->tx_flags |= IXGBE_TX_FLAGS_CSUM; first->tx_flags |= IXGBE_TX_FLAGS_CSUM;
} }
no_csum:
/* vlan_macip_lens: MACLEN, VLAN tag */ /* vlan_macip_lens: MACLEN, VLAN tag */
vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK; vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;
@ -7654,17 +7705,16 @@ static int ixgbe_set_mac(struct net_device *netdev, void *p)
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
struct sockaddr *addr = p; struct sockaddr *addr = p;
int ret;
if (!is_valid_ether_addr(addr->sa_data)) if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
ixgbe_del_mac_filter(adapter, hw->mac.addr, VMDQ_P(0));
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len); memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
ret = ixgbe_add_mac_filter(adapter, hw->mac.addr, VMDQ_P(0)); ixgbe_mac_set_default_filter(adapter);
return ret > 0 ? 0 : ret;
return 0;
} }
static int static int
@ -8147,7 +8197,10 @@ static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
{ {
/* guarantee we can provide a unique filter for the unicast address */ /* guarantee we can provide a unique filter for the unicast address */
if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr)) { if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr)) {
if (IXGBE_MAX_PF_MACVLANS <= netdev_uc_count(dev)) struct ixgbe_adapter *adapter = netdev_priv(dev);
u16 pool = VMDQ_P(0);
if (netdev_uc_count(dev) >= ixgbe_available_rars(adapter, pool))
return -ENOMEM; return -ENOMEM;
} }
@ -8865,7 +8918,7 @@ skip_sriov:
goto err_sw_init; goto err_sw_init;
} }
ixgbe_mac_set_default_filter(adapter, hw->mac.perm_addr); ixgbe_mac_set_default_filter(adapter);
setup_timer(&adapter->service_timer, &ixgbe_service_timer, setup_timer(&adapter->service_timer, &ixgbe_service_timer,
(unsigned long) adapter); (unsigned long) adapter);
@ -9320,6 +9373,12 @@ static int __init ixgbe_init_module(void)
pr_info("%s - version %s\n", ixgbe_driver_string, ixgbe_driver_version); pr_info("%s - version %s\n", ixgbe_driver_string, ixgbe_driver_version);
pr_info("%s\n", ixgbe_copyright); pr_info("%s\n", ixgbe_copyright);
ixgbe_wq = create_singlethread_workqueue(ixgbe_driver_name);
if (!ixgbe_wq) {
pr_err("%s: Failed to create workqueue\n", ixgbe_driver_name);
return -ENOMEM;
}
ixgbe_dbg_init(); ixgbe_dbg_init();
ret = pci_register_driver(&ixgbe_driver); ret = pci_register_driver(&ixgbe_driver);
@ -9351,6 +9410,10 @@ static void __exit ixgbe_exit_module(void)
pci_unregister_driver(&ixgbe_driver); pci_unregister_driver(&ixgbe_driver);
ixgbe_dbg_exit(); ixgbe_dbg_exit();
if (ixgbe_wq) {
destroy_workqueue(ixgbe_wq);
ixgbe_wq = NULL;
}
} }
#ifdef CONFIG_IXGBE_DCA #ifdef CONFIG_IXGBE_DCA

View File

@ -2393,6 +2393,9 @@ s32 ixgbe_set_copper_phy_power(struct ixgbe_hw *hw, bool on)
if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
return 0; return 0;
if (!on && ixgbe_mng_present(hw))
return 0;
status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL, status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL,
IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
&reg); &reg);

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2014 Intel Corporation. Copyright(c) 1999 - 2015 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
@ -130,6 +130,38 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
return -ENOMEM; return -ENOMEM;
} }
/**
* ixgbe_get_vfs - Find and take references to all vf devices
* @adapter: Pointer to adapter struct
*/
static void ixgbe_get_vfs(struct ixgbe_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
u16 vendor = pdev->vendor;
struct pci_dev *vfdev;
int vf = 0;
u16 vf_id;
int pos;
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
if (!pos)
return;
pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, &vf_id);
vfdev = pci_get_device(vendor, vf_id, NULL);
for (; vfdev; vfdev = pci_get_device(vendor, vf_id, vfdev)) {
if (!vfdev->is_virtfn)
continue;
if (vfdev->physfn != pdev)
continue;
if (vf >= adapter->num_vfs)
continue;
pci_dev_get(vfdev);
adapter->vfinfo[vf].vfdev = vfdev;
++vf;
}
}
/* Note this function is called when the user wants to enable SR-IOV /* Note this function is called when the user wants to enable SR-IOV
* VFs using the now deprecated module parameter * VFs using the now deprecated module parameter
*/ */
@ -170,8 +202,10 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
} }
} }
if (!__ixgbe_enable_sriov(adapter)) if (!__ixgbe_enable_sriov(adapter)) {
ixgbe_get_vfs(adapter);
return; return;
}
/* If we have gotten to this point then there is no memory available /* If we have gotten to this point then there is no memory available
* to manage the VF devices - print message and bail. * to manage the VF devices - print message and bail.
@ -184,6 +218,7 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
#endif /* #ifdef CONFIG_PCI_IOV */ #endif /* #ifdef CONFIG_PCI_IOV */
int ixgbe_disable_sriov(struct ixgbe_adapter *adapter) int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
{ {
unsigned int num_vfs = adapter->num_vfs, vf;
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
u32 gpie; u32 gpie;
u32 vmdctl; u32 vmdctl;
@ -192,6 +227,16 @@ int ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
/* set num VFs to 0 to prevent access to vfinfo */ /* set num VFs to 0 to prevent access to vfinfo */
adapter->num_vfs = 0; adapter->num_vfs = 0;
/* put the reference to all of the vf devices */
for (vf = 0; vf < num_vfs; ++vf) {
struct pci_dev *vfdev = adapter->vfinfo[vf].vfdev;
if (!vfdev)
continue;
adapter->vfinfo[vf].vfdev = NULL;
pci_dev_put(vfdev);
}
/* free VF control structures */ /* free VF control structures */
kfree(adapter->vfinfo); kfree(adapter->vfinfo);
adapter->vfinfo = NULL; adapter->vfinfo = NULL;
@ -289,6 +334,7 @@ static int ixgbe_pci_sriov_enable(struct pci_dev *dev, int num_vfs)
e_dev_warn("Failed to enable PCI sriov: %d\n", err); e_dev_warn("Failed to enable PCI sriov: %d\n", err);
return err; return err;
} }
ixgbe_get_vfs(adapter);
ixgbe_sriov_reinit(adapter); ixgbe_sriov_reinit(adapter);
return num_vfs; return num_vfs;

View File

@ -1020,6 +1020,7 @@ struct ixgbe_thermal_sensor_data {
#define IXGBE_TXSTMPH 0x08C08 /* Tx timestamp value High - RO */ #define IXGBE_TXSTMPH 0x08C08 /* Tx timestamp value High - RO */
#define IXGBE_SYSTIML 0x08C0C /* System time register Low - RO */ #define IXGBE_SYSTIML 0x08C0C /* System time register Low - RO */
#define IXGBE_SYSTIMH 0x08C10 /* System time register High - RO */ #define IXGBE_SYSTIMH 0x08C10 /* System time register High - RO */
#define IXGBE_SYSTIMR 0x08C58 /* System time register Residue - RO */
#define IXGBE_TIMINCA 0x08C14 /* Increment attributes register - RW */ #define IXGBE_TIMINCA 0x08C14 /* Increment attributes register - RW */
#define IXGBE_TIMADJL 0x08C18 /* Time Adjustment Offset register Low - RW */ #define IXGBE_TIMADJL 0x08C18 /* Time Adjustment Offset register Low - RW */
#define IXGBE_TIMADJH 0x08C1C /* Time Adjustment Offset register High - RW */ #define IXGBE_TIMADJH 0x08C1C /* Time Adjustment Offset register High - RW */
@ -1036,6 +1037,7 @@ struct ixgbe_thermal_sensor_data {
#define IXGBE_AUXSTMPH0 0x08C40 /* Auxiliary Time Stamp 0 register High - RO */ #define IXGBE_AUXSTMPH0 0x08C40 /* Auxiliary Time Stamp 0 register High - RO */
#define IXGBE_AUXSTMPL1 0x08C44 /* Auxiliary Time Stamp 1 register Low - RO */ #define IXGBE_AUXSTMPL1 0x08C44 /* Auxiliary Time Stamp 1 register Low - RO */
#define IXGBE_AUXSTMPH1 0x08C48 /* Auxiliary Time Stamp 1 register High - RO */ #define IXGBE_AUXSTMPH1 0x08C48 /* Auxiliary Time Stamp 1 register High - RO */
#define IXGBE_TSIM 0x08C68 /* TimeSync Interrupt Mask Register - RW */
/* Diagnostic Registers */ /* Diagnostic Registers */
#define IXGBE_RDSTATCTL 0x02C20 #define IXGBE_RDSTATCTL 0x02C20
@ -1345,7 +1347,10 @@ struct ixgbe_thermal_sensor_data {
#define IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK 0xFF01 /* int chip-wide mask */ #define IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_MASK 0xFF01 /* int chip-wide mask */
#define IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG 0xFC01 /* int chip-wide mask */ #define IXGBE_MDIO_GLOBAL_INT_CHIP_VEN_FLAG 0xFC01 /* int chip-wide mask */
#define IXGBE_MDIO_GLOBAL_ALARM_1 0xCC00 /* Global alarm 1 */ #define IXGBE_MDIO_GLOBAL_ALARM_1 0xCC00 /* Global alarm 1 */
#define IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT 0x0010 /* device fault */
#define IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL 0x4000 /* high temp failure */ #define IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL 0x4000 /* high temp failure */
#define IXGBE_MDIO_GLOBAL_FAULT_MSG 0xC850 /* global fault msg */
#define IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP 0x8007 /* high temp failure */
#define IXGBE_MDIO_GLOBAL_INT_MASK 0xD400 /* Global int mask */ #define IXGBE_MDIO_GLOBAL_INT_MASK 0xD400 /* Global int mask */
/* autoneg vendor alarm int enable */ /* autoneg vendor alarm int enable */
#define IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN 0x1000 #define IXGBE_MDIO_GLOBAL_AN_VEN_ALM_INT_EN 0x1000
@ -1353,6 +1358,7 @@ struct ixgbe_thermal_sensor_data {
#define IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN 0x1 /* vendor alarm int enable */ #define IXGBE_MDIO_GLOBAL_VEN_ALM_INT_EN 0x1 /* vendor alarm int enable */
#define IXGBE_MDIO_GLOBAL_STD_ALM2_INT 0x200 /* vendor alarm2 int mask */ #define IXGBE_MDIO_GLOBAL_STD_ALM2_INT 0x200 /* vendor alarm2 int mask */
#define IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN 0x4000 /* int high temp enable */ #define IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN 0x4000 /* int high temp enable */
#define IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN 0x0010 /*int dev fault enable */
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Addr Reg */ #define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Addr Reg */
#define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */ #define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */
@ -2209,6 +2215,7 @@ enum {
#define IXGBE_TSAUXC_EN_CLK 0x00000004 #define IXGBE_TSAUXC_EN_CLK 0x00000004
#define IXGBE_TSAUXC_SYNCLK 0x00000008 #define IXGBE_TSAUXC_SYNCLK 0x00000008
#define IXGBE_TSAUXC_SDP0_INT 0x00000040 #define IXGBE_TSAUXC_SDP0_INT 0x00000040
#define IXGBE_TSAUXC_DISABLE_SYSTIME 0x80000000
#define IXGBE_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */ #define IXGBE_TSYNCTXCTL_VALID 0x00000001 /* Tx timestamp valid */
#define IXGBE_TSYNCTXCTL_ENABLED 0x00000010 /* Tx timestamping enabled */ #define IXGBE_TSYNCTXCTL_ENABLED 0x00000010 /* Tx timestamping enabled */
@ -2218,8 +2225,12 @@ enum {
#define IXGBE_TSYNCRXCTL_TYPE_L2_V2 0x00 #define IXGBE_TSYNCRXCTL_TYPE_L2_V2 0x00
#define IXGBE_TSYNCRXCTL_TYPE_L4_V1 0x02 #define IXGBE_TSYNCRXCTL_TYPE_L4_V1 0x02
#define IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2 0x04 #define IXGBE_TSYNCRXCTL_TYPE_L2_L4_V2 0x04
#define IXGBE_TSYNCRXCTL_TYPE_ALL 0x08
#define IXGBE_TSYNCRXCTL_TYPE_EVENT_V2 0x0A #define IXGBE_TSYNCRXCTL_TYPE_EVENT_V2 0x0A
#define IXGBE_TSYNCRXCTL_ENABLED 0x00000010 /* Rx Timestamping enabled */ #define IXGBE_TSYNCRXCTL_ENABLED 0x00000010 /* Rx Timestamping enabled */
#define IXGBE_TSYNCRXCTL_TSIP_UT_EN 0x00800000 /* Rx Timestamp in Packet */
#define IXGBE_TSIM_TXTS 0x00000002
#define IXGBE_RXMTRL_V1_CTRLT_MASK 0x000000FF #define IXGBE_RXMTRL_V1_CTRLT_MASK 0x000000FF
#define IXGBE_RXMTRL_V1_SYNC_MSG 0x00 #define IXGBE_RXMTRL_V1_SYNC_MSG 0x00
@ -2332,6 +2343,7 @@ enum {
#define IXGBE_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */ #define IXGBE_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */
#define IXGBE_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */ #define IXGBE_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */
#define IXGBE_RXD_STAT_LLINT 0x800 /* Pkt caused Low Latency Interrupt */ #define IXGBE_RXD_STAT_LLINT 0x800 /* Pkt caused Low Latency Interrupt */
#define IXGBE_RXD_STAT_TSIP 0x08000 /* Time Stamp in packet buffer */
#define IXGBE_RXD_STAT_TS 0x10000 /* Time Stamp */ #define IXGBE_RXD_STAT_TS 0x10000 /* Time Stamp */
#define IXGBE_RXD_STAT_SECP 0x20000 /* Security Processing */ #define IXGBE_RXD_STAT_SECP 0x20000 /* Security Processing */
#define IXGBE_RXD_STAT_LB 0x40000 /* Loopback Status */ #define IXGBE_RXD_STAT_LB 0x40000 /* Loopback Status */

View File

@ -57,7 +57,6 @@ s32 ixgbe_get_invariants_X540(struct ixgbe_hw *hw)
struct ixgbe_phy_info *phy = &hw->phy; struct ixgbe_phy_info *phy = &hw->phy;
/* set_phy_power was set by default to NULL */ /* set_phy_power was set by default to NULL */
if (!ixgbe_mng_present(hw))
phy->ops.set_phy_power = ixgbe_set_copper_phy_power; phy->ops.set_phy_power = ixgbe_set_copper_phy_power;
mac->mcft_size = IXGBE_X540_MC_TBL_SIZE; mac->mcft_size = IXGBE_X540_MC_TBL_SIZE;
@ -110,13 +109,14 @@ mac_reset_top:
ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
IXGBE_WRITE_FLUSH(hw); IXGBE_WRITE_FLUSH(hw);
usleep_range(1000, 1200);
/* Poll for reset bit to self-clear indicating reset is complete */ /* Poll for reset bit to self-clear indicating reset is complete */
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
udelay(1);
ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
if (!(ctrl & IXGBE_CTRL_RST_MASK)) if (!(ctrl & IXGBE_CTRL_RST_MASK))
break; break;
udelay(1);
} }
if (ctrl & IXGBE_CTRL_RST_MASK) { if (ctrl & IXGBE_CTRL_RST_MASK) {

View File

@ -1444,7 +1444,7 @@ static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
IXGBE_MDIO_GLOBAL_ALARM_1_INT))) IXGBE_MDIO_GLOBAL_ALARM_1_INT)))
return status; return status;
/* High temperature failure alarm triggered */ /* Global alarm triggered */
status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1, status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_ALARM_1,
IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
&reg); &reg);
@ -1458,6 +1458,21 @@ static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc)
ixgbe_set_copper_phy_power(hw, false); ixgbe_set_copper_phy_power(hw, false);
return IXGBE_ERR_OVERTEMP; return IXGBE_ERR_OVERTEMP;
} }
if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) {
/* device fault alarm triggered */
status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_FAULT_MSG,
IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
&reg);
if (status)
return status;
/* if device fault was due to high temp alarm handle and exit */
if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) {
/* power down the PHY in case the PHY FW didn't */
ixgbe_set_copper_phy_power(hw, false);
return IXGBE_ERR_OVERTEMP;
}
}
/* Vendor alarm 2 triggered */ /* Vendor alarm 2 triggered */
status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG, status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_CHIP_STD_INT_FLAG,
@ -1511,14 +1526,15 @@ static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw)
if (status) if (status)
return status; return status;
/* Enables high temperature failure alarm */ /* Enable high temperature failure and global fault alarms */
status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK, status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
&reg); &reg);
if (status) if (status)
return status; return status;
reg |= IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN; reg |= (IXGBE_MDIO_GLOBAL_INT_HI_TEMP_EN |
IXGBE_MDIO_GLOBAL_INT_DEV_FAULT_EN);
status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK, status = hw->phy.ops.write_reg(hw, IXGBE_MDIO_GLOBAL_INT_MASK,
IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
@ -1727,6 +1743,12 @@ static s32 ixgbe_setup_internal_phy_t_x550em(struct ixgbe_hw *hw)
if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper)
return IXGBE_ERR_CONFIG; return IXGBE_ERR_CONFIG;
if (hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE) {
speed = IXGBE_LINK_SPEED_10GB_FULL |
IXGBE_LINK_SPEED_1GB_FULL;
return ixgbe_setup_kr_speed_x550em(hw, speed);
}
/* If link is not up, then there is no setup necessary so return */ /* If link is not up, then there is no setup necessary so return */
status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up); status = ixgbe_ext_phy_t_x550em_get_link(hw, &link_up);
if (status) if (status)
@ -1931,7 +1953,6 @@ static s32 ixgbe_enter_lplu_t_x550em(struct ixgbe_hw *hw)
static s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw) static s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
{ {
struct ixgbe_phy_info *phy = &hw->phy; struct ixgbe_phy_info *phy = &hw->phy;
ixgbe_link_speed speed;
s32 ret_val; s32 ret_val;
hw->mac.ops.set_lan_id(hw); hw->mac.ops.set_lan_id(hw);
@ -1944,10 +1965,6 @@ static s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
* to determine internal PHY mode. * to determine internal PHY mode.
*/ */
phy->nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL); phy->nw_mng_if_sel = IXGBE_READ_REG(hw, IXGBE_NW_MNG_IF_SEL);
if (phy->nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE) {
speed = IXGBE_LINK_SPEED_10GB_FULL |
IXGBE_LINK_SPEED_1GB_FULL;
}
} }
/* Identify the PHY or SFP module */ /* Identify the PHY or SFP module */
@ -1979,14 +1996,8 @@ static s32 ixgbe_init_phy_ops_X550em(struct ixgbe_hw *hw)
/* If internal link mode is XFI, then setup iXFI internal link, /* If internal link mode is XFI, then setup iXFI internal link,
* else setup KR now. * else setup KR now.
*/ */
if (!(phy->nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE)) {
phy->ops.setup_internal_link = phy->ops.setup_internal_link =
ixgbe_setup_internal_phy_t_x550em; ixgbe_setup_internal_phy_t_x550em;
} else {
speed = IXGBE_LINK_SPEED_10GB_FULL |
IXGBE_LINK_SPEED_1GB_FULL;
ret_val = ixgbe_setup_kr_speed_x550em(hw, speed);
}
/* setup SW LPLU only for first revision */ /* setup SW LPLU only for first revision */
if (!(IXGBE_FUSES0_REV1 & IXGBE_READ_REG(hw, if (!(IXGBE_FUSES0_REV1 & IXGBE_READ_REG(hw,
@ -2135,13 +2146,14 @@ mac_reset_top:
ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL);
IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
IXGBE_WRITE_FLUSH(hw); IXGBE_WRITE_FLUSH(hw);
usleep_range(1000, 1200);
/* Poll for reset bit to self-clear meaning reset is complete */ /* Poll for reset bit to self-clear meaning reset is complete */
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
udelay(1);
ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
if (!(ctrl & IXGBE_CTRL_RST_MASK)) if (!(ctrl & IXGBE_CTRL_RST_MASK))
break; break;
udelay(1);
} }
if (ctrl & IXGBE_CTRL_RST_MASK) { if (ctrl & IXGBE_CTRL_RST_MASK) {

View File

@ -59,7 +59,7 @@ static const char ixgbevf_driver_string[] =
#define DRV_VERSION "2.12.1-k" #define DRV_VERSION "2.12.1-k"
const char ixgbevf_driver_version[] = DRV_VERSION; const char ixgbevf_driver_version[] = DRV_VERSION;
static char ixgbevf_copyright[] = static char ixgbevf_copyright[] =
"Copyright (c) 2009 - 2012 Intel Corporation."; "Copyright (c) 2009 - 2015 Intel Corporation.";
static const struct ixgbevf_info *ixgbevf_info_tbl[] = { static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
[board_82599_vf] = &ixgbevf_82599_vf_info, [board_82599_vf] = &ixgbevf_82599_vf_info,
@ -96,12 +96,14 @@ static int debug = -1;
module_param(debug, int, 0); module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
static struct workqueue_struct *ixgbevf_wq;
static void ixgbevf_service_event_schedule(struct ixgbevf_adapter *adapter) static void ixgbevf_service_event_schedule(struct ixgbevf_adapter *adapter)
{ {
if (!test_bit(__IXGBEVF_DOWN, &adapter->state) && if (!test_bit(__IXGBEVF_DOWN, &adapter->state) &&
!test_bit(__IXGBEVF_REMOVING, &adapter->state) && !test_bit(__IXGBEVF_REMOVING, &adapter->state) &&
!test_and_set_bit(__IXGBEVF_SERVICE_SCHED, &adapter->state)) !test_and_set_bit(__IXGBEVF_SERVICE_SCHED, &adapter->state))
schedule_work(&adapter->service_task); queue_work(ixgbevf_wq, &adapter->service_task);
} }
static void ixgbevf_service_event_complete(struct ixgbevf_adapter *adapter) static void ixgbevf_service_event_complete(struct ixgbevf_adapter *adapter)
@ -1332,7 +1334,6 @@ static int ixgbevf_map_rings_to_vectors(struct ixgbevf_adapter *adapter)
int txr_remaining = adapter->num_tx_queues; int txr_remaining = adapter->num_tx_queues;
int i, j; int i, j;
int rqpv, tqpv; int rqpv, tqpv;
int err = 0;
q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
@ -1345,7 +1346,7 @@ static int ixgbevf_map_rings_to_vectors(struct ixgbevf_adapter *adapter)
for (; txr_idx < txr_remaining; v_start++, txr_idx++) for (; txr_idx < txr_remaining; v_start++, txr_idx++)
map_vector_to_txq(adapter, v_start, txr_idx); map_vector_to_txq(adapter, v_start, txr_idx);
goto out; return 0;
} }
/* If we don't have enough vectors for a 1-to-1 /* If we don't have enough vectors for a 1-to-1
@ -1370,8 +1371,7 @@ static int ixgbevf_map_rings_to_vectors(struct ixgbevf_adapter *adapter)
} }
} }
out: return 0;
return err;
} }
/** /**
@ -1469,9 +1469,7 @@ static inline void ixgbevf_reset_q_vectors(struct ixgbevf_adapter *adapter)
**/ **/
static int ixgbevf_request_irq(struct ixgbevf_adapter *adapter) static int ixgbevf_request_irq(struct ixgbevf_adapter *adapter)
{ {
int err = 0; int err = ixgbevf_request_msix_irqs(adapter);
err = ixgbevf_request_msix_irqs(adapter);
if (err) if (err)
hw_dbg(&adapter->hw, "request_irq failed, Error %d\n", err); hw_dbg(&adapter->hw, "request_irq failed, Error %d\n", err);
@ -1830,7 +1828,7 @@ static int ixgbevf_vlan_rx_kill_vid(struct net_device *netdev,
{ {
struct ixgbevf_adapter *adapter = netdev_priv(netdev); struct ixgbevf_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
int err = -EOPNOTSUPP; int err;
spin_lock_bh(&adapter->mbx_lock); spin_lock_bh(&adapter->mbx_lock);
@ -2046,7 +2044,7 @@ static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter)
ixgbe_mbox_api_11, ixgbe_mbox_api_11,
ixgbe_mbox_api_10, ixgbe_mbox_api_10,
ixgbe_mbox_api_unknown }; ixgbe_mbox_api_unknown };
int err = 0, idx = 0; int err, idx = 0;
spin_lock_bh(&adapter->mbx_lock); spin_lock_bh(&adapter->mbx_lock);
@ -2419,7 +2417,7 @@ err_allocation:
static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter) static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
int err = 0; int err;
int vector, v_budget; int vector, v_budget;
/* It's easy to be greedy for MSI-X vectors, but it really /* It's easy to be greedy for MSI-X vectors, but it really
@ -2437,26 +2435,21 @@ static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter)
*/ */
adapter->msix_entries = kcalloc(v_budget, adapter->msix_entries = kcalloc(v_budget,
sizeof(struct msix_entry), GFP_KERNEL); sizeof(struct msix_entry), GFP_KERNEL);
if (!adapter->msix_entries) { if (!adapter->msix_entries)
err = -ENOMEM; return -ENOMEM;
goto out;
}
for (vector = 0; vector < v_budget; vector++) for (vector = 0; vector < v_budget; vector++)
adapter->msix_entries[vector].entry = vector; adapter->msix_entries[vector].entry = vector;
err = ixgbevf_acquire_msix_vectors(adapter, v_budget); err = ixgbevf_acquire_msix_vectors(adapter, v_budget);
if (err) if (err)
goto out; return err;
err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues); err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues);
if (err) if (err)
goto out;
err = netif_set_real_num_rx_queues(netdev, adapter->num_rx_queues);
out:
return err; return err;
return netif_set_real_num_rx_queues(netdev, adapter->num_rx_queues);
} }
/** /**
@ -3351,6 +3344,7 @@ static void ixgbevf_tx_csum(struct ixgbevf_ring *tx_ring,
if (skb->ip_summed == CHECKSUM_PARTIAL) { if (skb->ip_summed == CHECKSUM_PARTIAL) {
u8 l4_hdr = 0; u8 l4_hdr = 0;
__be16 frag_off;
switch (first->protocol) { switch (first->protocol) {
case htons(ETH_P_IP): case htons(ETH_P_IP):
@ -3361,13 +3355,16 @@ static void ixgbevf_tx_csum(struct ixgbevf_ring *tx_ring,
case htons(ETH_P_IPV6): case htons(ETH_P_IPV6):
vlan_macip_lens |= skb_network_header_len(skb); vlan_macip_lens |= skb_network_header_len(skb);
l4_hdr = ipv6_hdr(skb)->nexthdr; l4_hdr = ipv6_hdr(skb)->nexthdr;
if (likely(skb_network_header_len(skb) ==
sizeof(struct ipv6hdr)))
break;
ipv6_skip_exthdr(skb, skb_network_offset(skb) +
sizeof(struct ipv6hdr),
&l4_hdr, &frag_off);
if (unlikely(frag_off))
l4_hdr = NEXTHDR_FRAGMENT;
break; break;
default: default:
if (unlikely(net_ratelimit())) {
dev_warn(tx_ring->dev,
"partial checksum but proto=%x!\n",
first->protocol);
}
break; break;
} }
@ -3389,16 +3386,18 @@ static void ixgbevf_tx_csum(struct ixgbevf_ring *tx_ring,
default: default:
if (unlikely(net_ratelimit())) { if (unlikely(net_ratelimit())) {
dev_warn(tx_ring->dev, dev_warn(tx_ring->dev,
"partial checksum but l4 proto=%x!\n", "partial checksum, l3 proto=%x, l4 proto=%x\n",
l4_hdr); first->protocol, l4_hdr);
} }
break; skb_checksum_help(skb);
goto no_csum;
} }
/* update TX checksum flag */ /* update TX checksum flag */
first->tx_flags |= IXGBE_TX_FLAGS_CSUM; first->tx_flags |= IXGBE_TX_FLAGS_CSUM;
} }
no_csum:
/* vlan_macip_lens: MACLEN, VLAN tag */ /* vlan_macip_lens: MACLEN, VLAN tag */
vlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT; vlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT;
vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK; vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;
@ -4244,15 +4243,17 @@ static struct pci_driver ixgbevf_driver = {
**/ **/
static int __init ixgbevf_init_module(void) static int __init ixgbevf_init_module(void)
{ {
int ret;
pr_info("%s - version %s\n", ixgbevf_driver_string, pr_info("%s - version %s\n", ixgbevf_driver_string,
ixgbevf_driver_version); ixgbevf_driver_version);
pr_info("%s\n", ixgbevf_copyright); pr_info("%s\n", ixgbevf_copyright);
ixgbevf_wq = create_singlethread_workqueue(ixgbevf_driver_name);
if (!ixgbevf_wq) {
pr_err("%s: Failed to create workqueue\n", ixgbevf_driver_name);
return -ENOMEM;
}
ret = pci_register_driver(&ixgbevf_driver); return pci_register_driver(&ixgbevf_driver);
return ret;
} }
module_init(ixgbevf_init_module); module_init(ixgbevf_init_module);
@ -4266,6 +4267,10 @@ module_init(ixgbevf_init_module);
static void __exit ixgbevf_exit_module(void) static void __exit ixgbevf_exit_module(void)
{ {
pci_unregister_driver(&ixgbevf_driver); pci_unregister_driver(&ixgbevf_driver);
if (ixgbevf_wq) {
destroy_workqueue(ixgbevf_wq);
ixgbevf_wq = NULL;
}
} }
#ifdef DEBUG #ifdef DEBUG