Commit fd183f6a authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next

Jeff Kirsher says:

--------------------
This series contains updates to ixgbe and ixgbevf.
 ...
Akeem G. Abodunrin (1):
  igb: reset PHY in the link_up process to recover PHY setting after
    power down.

Alexander Duyck (8):
  ixgbe: Drop probe_vf and merge functionality into ixgbe_enable_sriov
  ixgbe: Change how we check for pre-existing and assigned VFs
  ixgbevf: Add lock around mailbox ops to prevent simultaneous access
  ixgbevf: Add support for PCI error handling
  ixgbe: Fix handling of FDIR_HASH flag
  ixgbe: Reduce Rx header size to what is actually used
  ixgbe: Use num_tcs.pg_tcs as upper limit for TC when checking based
    on UP
  ixgbe: Use 1TC DCB instead of disabling DCB for MSI and legacy
    interrupts

Don Skidmore (1):
  ixgbe: add support for new 82599 device

Greg Rose (1):
  ixgbevf: Fix namespace issue with ixgbe_write_eitr

John Fastabend (2):
  ixgbe: fix RAR entry counting for generic and fdb_add()
  ixgbe: remove extra unused queues in DCB + FCoE case
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5dc7c779 76886596
...@@ -1500,11 +1500,12 @@ static void igb_configure(struct igb_adapter *adapter) ...@@ -1500,11 +1500,12 @@ static void igb_configure(struct igb_adapter *adapter)
**/ **/
void igb_power_up_link(struct igb_adapter *adapter) void igb_power_up_link(struct igb_adapter *adapter)
{ {
igb_reset_phy(&adapter->hw);
if (adapter->hw.phy.media_type == e1000_media_type_copper) if (adapter->hw.phy.media_type == e1000_media_type_copper)
igb_power_up_phy_copper(&adapter->hw); igb_power_up_phy_copper(&adapter->hw);
else else
igb_power_up_serdes_link_82575(&adapter->hw); igb_power_up_serdes_link_82575(&adapter->hw);
igb_reset_phy(&adapter->hw);
} }
/** /**
......
...@@ -77,17 +77,18 @@ ...@@ -77,17 +77,18 @@
#define IXGBE_MAX_FCPAUSE 0xFFFF #define IXGBE_MAX_FCPAUSE 0xFFFF
/* Supported Rx Buffer Sizes */ /* Supported Rx Buffer Sizes */
#define IXGBE_RXBUFFER_512 512 /* Used for packet split */ #define IXGBE_RXBUFFER_256 256 /* Used for skb receive header */
#define IXGBE_MAX_RXBUFFER 16384 /* largest size for a single descriptor */ #define IXGBE_MAX_RXBUFFER 16384 /* largest size for a single descriptor */
/* /*
* NOTE: netdev_alloc_skb reserves up to 64 bytes, NET_IP_ALIGN mans we * NOTE: netdev_alloc_skb reserves up to 64 bytes, NET_IP_ALIGN means we
* reserve 2 more, and skb_shared_info adds an additional 384 bytes more, * reserve 64 more, and skb_shared_info adds an additional 320 bytes more,
* this adds up to 512 bytes of extra data meaning the smallest allocation * this adds up to 448 bytes of extra data.
* we could have is 1K. *
* i.e. RXBUFFER_512 --> size-1024 slab * Since netdev_alloc_skb now allocates a page fragment we can use a value
* of 256 and the resultant skb will have a truesize of 960 or less.
*/ */
#define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_512 #define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_256
#define MAXIMUM_ETHERNET_VLAN_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) #define MAXIMUM_ETHERNET_VLAN_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
...@@ -130,7 +131,6 @@ struct vf_data_storage { ...@@ -130,7 +131,6 @@ struct vf_data_storage {
u16 tx_rate; u16 tx_rate;
u16 vlan_count; u16 vlan_count;
u8 spoofchk_enabled; u8 spoofchk_enabled;
struct pci_dev *vfdev;
}; };
struct vf_macvlans { struct vf_macvlans {
......
...@@ -232,18 +232,22 @@ u8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *cfg, int direction, u8 up) ...@@ -232,18 +232,22 @@ u8 ixgbe_dcb_get_tc_from_up(struct ixgbe_dcb_config *cfg, int direction, u8 up)
{ {
struct tc_configuration *tc_config = &cfg->tc_config[0]; struct tc_configuration *tc_config = &cfg->tc_config[0];
u8 prio_mask = 1 << up; u8 prio_mask = 1 << up;
u8 tc; u8 tc = cfg->num_tcs.pg_tcs;
/* If tc is 0 then DCB is likely not enabled or supported */
if (!tc)
goto out;
/* /*
* Test for TCs 7 through 1 and report the first match we find. If * Test from maximum TC to 1 and report the first match we find. If
* we find no match we can assume that the TC is 0 since the TC must * we find no match we can assume that the TC is 0 since the TC must
* be set for all user priorities * be set for all user priorities
*/ */
for (tc = MAX_TRAFFIC_CLASS - 1; tc; tc--) { for (tc--; tc; tc--) {
if (prio_mask & tc_config[tc].path[direction].up_to_tc_bitmap) if (prio_mask & tc_config[tc].path[direction].up_to_tc_bitmap)
break; break;
} }
out:
return tc; return tc;
} }
......
...@@ -370,6 +370,9 @@ static bool ixgbe_set_dcb_sriov_queues(struct ixgbe_adapter *adapter) ...@@ -370,6 +370,9 @@ static bool ixgbe_set_dcb_sriov_queues(struct ixgbe_adapter *adapter)
adapter->ring_feature[RING_F_RSS].indices = 1; adapter->ring_feature[RING_F_RSS].indices = 1;
adapter->ring_feature[RING_F_RSS].mask = IXGBE_RSS_DISABLED_MASK; adapter->ring_feature[RING_F_RSS].mask = IXGBE_RSS_DISABLED_MASK;
/* disable ATR as it is not supported when VMDq is enabled */
adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
adapter->num_rx_pools = vmdq_i; adapter->num_rx_pools = vmdq_i;
adapter->num_rx_queues_per_pool = tcs; adapter->num_rx_queues_per_pool = tcs;
...@@ -450,6 +453,9 @@ static bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter) ...@@ -450,6 +453,9 @@ static bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter)
f->indices = rss_i; f->indices = rss_i;
f->mask = rss_m; f->mask = rss_m;
/* disable ATR as it is not supported when multiple TCs are enabled */
adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
#ifdef IXGBE_FCOE #ifdef IXGBE_FCOE
/* FCoE enabled queues require special configuration indexed /* FCoE enabled queues require special configuration indexed
* by feature specific indices and offset. Here we map FCoE * by feature specific indices and offset. Here we map FCoE
...@@ -606,16 +612,22 @@ static bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter) ...@@ -606,16 +612,22 @@ static bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
f->indices = rss_i; f->indices = rss_i;
f->mask = IXGBE_RSS_16Q_MASK; f->mask = IXGBE_RSS_16Q_MASK;
/* disable ATR by default, it will be configured below */
adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
/* /*
* Use Flow Director in addition to RSS to ensure the best * Use Flow Director in addition to RSS to ensure the best
* distribution of flows across cores, even when an FDIR flow * distribution of flows across cores, even when an FDIR flow
* isn't matched. * isn't matched.
*/ */
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) { if (rss_i > 1 && adapter->atr_sample_rate) {
f = &adapter->ring_feature[RING_F_FDIR]; f = &adapter->ring_feature[RING_F_FDIR];
f->indices = min_t(u16, num_online_cpus(), f->limit); f->indices = min_t(u16, num_online_cpus(), f->limit);
rss_i = max_t(u16, rss_i, f->indices); rss_i = max_t(u16, rss_i, f->indices);
if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE))
adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
} }
#ifdef IXGBE_FCOE #ifdef IXGBE_FCOE
...@@ -1053,18 +1065,27 @@ static void ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter) ...@@ -1053,18 +1065,27 @@ static void ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
return; return;
} }
adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; /* disable DCB if number of TCs exceeds 1 */
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) { if (netdev_get_num_tc(adapter->netdev) > 1) {
e_err(probe, e_err(probe, "num TCs exceeds number of queues - disabling DCB\n");
"ATR is not supported while multiple " netdev_reset_tc(adapter->netdev);
"queues are disabled. Disabling Flow Director\n");
if (adapter->hw.mac.type == ixgbe_mac_82598EB)
adapter->hw.fc.requested_mode = adapter->last_lfc_mode;
adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
adapter->temp_dcb_cfg.pfc_mode_enable = false;
adapter->dcb_cfg.pfc_mode_enable = false;
} }
adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; adapter->dcb_cfg.num_tcs.pg_tcs = 1;
adapter->atr_sample_rate = 0; adapter->dcb_cfg.num_tcs.pfc_tcs = 1;
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
ixgbe_disable_sriov(adapter); /* disable SR-IOV */
ixgbe_disable_sriov(adapter);
/* disable RSS */
adapter->ring_feature[RING_F_RSS].limit = 1; adapter->ring_feature[RING_F_RSS].limit = 1;
ixgbe_set_num_queues(adapter); ixgbe_set_num_queues(adapter);
adapter->num_q_vectors = 1; adapter->num_q_vectors = 1;
......
...@@ -1517,8 +1517,8 @@ static bool ixgbe_cleanup_headers(struct ixgbe_ring *rx_ring, ...@@ -1517,8 +1517,8 @@ static bool ixgbe_cleanup_headers(struct ixgbe_ring *rx_ring,
* 60 bytes if the skb->len is less than 60 for skb_pad. * 60 bytes if the skb->len is less than 60 for skb_pad.
*/ */
pull_len = skb_frag_size(frag); pull_len = skb_frag_size(frag);
if (pull_len > 256) if (pull_len > IXGBE_RX_HDR_SIZE)
pull_len = ixgbe_get_headlen(va, pull_len); pull_len = ixgbe_get_headlen(va, IXGBE_RX_HDR_SIZE);
/* align pull length to size of long to optimize memcpy performance */ /* align pull length to size of long to optimize memcpy performance */
skb_copy_to_linear_data(skb, va, ALIGN(pull_len, sizeof(long))); skb_copy_to_linear_data(skb, va, ALIGN(pull_len, sizeof(long)));
...@@ -2688,8 +2688,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, ...@@ -2688,8 +2688,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
32; /* PTHRESH = 32 */ 32; /* PTHRESH = 32 */
/* reinitialize flowdirector state */ /* reinitialize flowdirector state */
if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) && if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) {
adapter->atr_sample_rate) {
ring->atr_sample_rate = adapter->atr_sample_rate; ring->atr_sample_rate = adapter->atr_sample_rate;
ring->atr_count = 0; ring->atr_count = 0;
set_bit(__IXGBE_TX_FDIR_INIT_DONE, &ring->state); set_bit(__IXGBE_TX_FDIR_INIT_DONE, &ring->state);
...@@ -3442,14 +3441,18 @@ static int ixgbe_write_uc_addr_list(struct net_device *netdev) ...@@ -3442,14 +3441,18 @@ static int ixgbe_write_uc_addr_list(struct net_device *netdev)
{ {
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;
unsigned int rar_entries = IXGBE_MAX_PF_MACVLANS; unsigned int rar_entries = hw->mac.num_rar_entries - 1;
int count = 0; int count = 0;
/* In SR-IOV mode significantly less RAR entries are available */
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
rar_entries = IXGBE_MAX_PF_MACVLANS - 1;
/* return ENOMEM indicating insufficient memory for addresses */ /* return ENOMEM indicating insufficient memory for addresses */
if (netdev_uc_count(netdev) > rar_entries) if (netdev_uc_count(netdev) > rar_entries)
return -ENOMEM; return -ENOMEM;
if (!netdev_uc_empty(netdev) && rar_entries) { if (!netdev_uc_empty(netdev)) {
struct netdev_hw_addr *ha; struct netdev_hw_addr *ha;
/* return error if we do not support writing to RAR table */ /* return error if we do not support writing to RAR table */
if (!hw->mac.ops.set_rar) if (!hw->mac.ops.set_rar)
...@@ -4419,7 +4422,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) ...@@ -4419,7 +4422,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
if (hw->device_id == IXGBE_DEV_ID_82599_T3_LOM) if (hw->device_id == IXGBE_DEV_ID_82599_T3_LOM)
adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE; adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE;
/* Flow Director hash filters enabled */ /* Flow Director hash filters enabled */
adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
adapter->atr_sample_rate = 20; adapter->atr_sample_rate = 20;
adapter->ring_feature[RING_F_FDIR].limit = adapter->ring_feature[RING_F_FDIR].limit =
IXGBE_MAX_FDIR_INDICES; IXGBE_MAX_FDIR_INDICES;
...@@ -4490,6 +4492,12 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) ...@@ -4490,6 +4492,12 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
hw->fc.send_xon = true; hw->fc.send_xon = true;
hw->fc.disable_fc_autoneg = false; hw->fc.disable_fc_autoneg = false;
#ifdef CONFIG_PCI_IOV
/* assign number of SR-IOV VFs */
if (hw->mac.type != ixgbe_mac_82598EB)
adapter->num_vfs = (max_vfs > 63) ? 0 : max_vfs;
#endif
/* enable itr by default in dynamic mode */ /* enable itr by default in dynamic mode */
adapter->rx_itr_setting = 1; adapter->rx_itr_setting = 1;
adapter->tx_itr_setting = 1; adapter->tx_itr_setting = 1;
...@@ -6695,12 +6703,6 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc) ...@@ -6695,12 +6703,6 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
struct ixgbe_adapter *adapter = netdev_priv(dev); struct ixgbe_adapter *adapter = netdev_priv(dev);
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
/* Multiple traffic classes requires multiple queues */
if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) {
e_err(drv, "Enable failed, needs MSI-X\n");
return -EINVAL;
}
/* Hardware supports up to 8 traffic classes */ /* Hardware supports up to 8 traffic classes */
if (tc > adapter->dcb_cfg.num_tcs.pg_tcs || if (tc > adapter->dcb_cfg.num_tcs.pg_tcs ||
(hw->mac.type == ixgbe_mac_82598EB && (hw->mac.type == ixgbe_mac_82598EB &&
...@@ -6720,7 +6722,6 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc) ...@@ -6720,7 +6722,6 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
ixgbe_set_prio_tc_map(adapter); ixgbe_set_prio_tc_map(adapter);
adapter->flags |= IXGBE_FLAG_DCB_ENABLED; adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
if (adapter->hw.mac.type == ixgbe_mac_82598EB) { if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
adapter->last_lfc_mode = adapter->hw.fc.requested_mode; adapter->last_lfc_mode = adapter->hw.fc.requested_mode;
...@@ -6733,7 +6734,6 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc) ...@@ -6733,7 +6734,6 @@ int ixgbe_setup_tc(struct net_device *dev, u8 tc)
adapter->hw.fc.requested_mode = adapter->last_lfc_mode; adapter->hw.fc.requested_mode = adapter->last_lfc_mode;
adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
adapter->temp_dcb_cfg.pfc_mode_enable = false; adapter->temp_dcb_cfg.pfc_mode_enable = false;
adapter->dcb_cfg.pfc_mode_enable = false; adapter->dcb_cfg.pfc_mode_enable = false;
...@@ -6802,20 +6802,40 @@ static int ixgbe_set_features(struct net_device *netdev, ...@@ -6802,20 +6802,40 @@ static int ixgbe_set_features(struct net_device *netdev,
* Check if Flow Director n-tuple support was enabled or disabled. If * Check if Flow Director n-tuple support was enabled or disabled. If
* the state changed, we need to reset. * the state changed, we need to reset.
*/ */
if (!(features & NETIF_F_NTUPLE)) { switch (features & NETIF_F_NTUPLE) {
if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) { case NETIF_F_NTUPLE:
/* turn off Flow Director, set ATR and reset */
if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) &&
!(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
need_reset = true;
}
adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
} else if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) {
/* turn off ATR, enable perfect filters and reset */ /* turn off ATR, enable perfect filters and reset */
if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE))
need_reset = true;
adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE; adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
need_reset = true; break;
default:
/* turn off perfect filters, enable ATR and reset */
if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
need_reset = true;
adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
/* We cannot enable ATR if SR-IOV is enabled */
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
break;
/* We cannot enable ATR if we have 2 or more traffic classes */
if (netdev_get_num_tc(netdev) > 1)
break;
/* We cannot enable ATR if RSS is disabled */
if (adapter->ring_feature[RING_F_RSS].limit <= 1)
break;
/* A sample rate of 0 indicates ATR disabled */
if (!adapter->atr_sample_rate)
break;
adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
break;
} }
if (features & NETIF_F_HW_VLAN_RX) if (features & NETIF_F_HW_VLAN_RX)
...@@ -6839,7 +6859,10 @@ static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, ...@@ -6839,7 +6859,10 @@ static int ixgbe_ndo_fdb_add(struct ndmsg *ndm,
u16 flags) u16 flags)
{ {
struct ixgbe_adapter *adapter = netdev_priv(dev); struct ixgbe_adapter *adapter = netdev_priv(dev);
int err = -EOPNOTSUPP; int err;
if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
return -EOPNOTSUPP;
if (ndm->ndm_state & NUD_PERMANENT) { if (ndm->ndm_state & NUD_PERMANENT) {
pr_info("%s: FDB only supports static addresses\n", pr_info("%s: FDB only supports static addresses\n",
...@@ -6847,13 +6870,17 @@ static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, ...@@ -6847,13 +6870,17 @@ static int ixgbe_ndo_fdb_add(struct ndmsg *ndm,
return -EINVAL; return -EINVAL;
} }
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { if (is_unicast_ether_addr(addr)) {
if (is_unicast_ether_addr(addr)) u32 rar_uc_entries = IXGBE_MAX_PF_MACVLANS;
if (netdev_uc_count(dev) < rar_uc_entries)
err = dev_uc_add_excl(dev, addr); err = dev_uc_add_excl(dev, addr);
else if (is_multicast_ether_addr(addr))
err = dev_mc_add_excl(dev, addr);
else else
err = -EINVAL; err = -ENOMEM;
} else if (is_multicast_ether_addr(addr)) {
err = dev_mc_add_excl(dev, addr);
} else {
err = -EINVAL;
} }
/* Only return duplicate errors if NLM_F_EXCL is set */ /* Only return duplicate errors if NLM_F_EXCL is set */
...@@ -6942,26 +6969,6 @@ static const struct net_device_ops ixgbe_netdev_ops = { ...@@ -6942,26 +6969,6 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_fdb_dump = ixgbe_ndo_fdb_dump, .ndo_fdb_dump = ixgbe_ndo_fdb_dump,
}; };
static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
const struct ixgbe_info *ii)
{
#ifdef CONFIG_PCI_IOV
struct ixgbe_hw *hw = &adapter->hw;
if (hw->mac.type == ixgbe_mac_82598EB)
return;
/* The 82599 supports up to 64 VFs per physical function
* but this implementation limits allocation to 63 so that
* basic networking resources are still available to the
* physical function. If the user requests greater thn
* 63 VFs then it is an error - reset to default of zero.
*/
adapter->num_vfs = (max_vfs > 63) ? 0 : max_vfs;
ixgbe_enable_sriov(adapter, ii);
#endif /* CONFIG_PCI_IOV */
}
/** /**
* ixgbe_wol_supported - Check whether device supports WoL * ixgbe_wol_supported - Check whether device supports WoL
* @hw: hw specific details * @hw: hw specific details
...@@ -6988,6 +6995,7 @@ int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id, ...@@ -6988,6 +6995,7 @@ int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id,
if (hw->bus.func != 0) if (hw->bus.func != 0)
break; break;
case IXGBE_SUBDEV_ID_82599_SFP: case IXGBE_SUBDEV_ID_82599_SFP:
case IXGBE_SUBDEV_ID_82599_RNDC:
is_wol_supported = 1; is_wol_supported = 1;
break; break;
} }
...@@ -7035,6 +7043,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ...@@ -7035,6 +7043,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
int i, err, pci_using_dac; int i, err, pci_using_dac;
u8 part_str[IXGBE_PBANUM_LENGTH]; u8 part_str[IXGBE_PBANUM_LENGTH];
unsigned int indices = num_possible_cpus(); unsigned int indices = num_possible_cpus();
unsigned int dcb_max = 0;
#ifdef IXGBE_FCOE #ifdef IXGBE_FCOE
u16 device_caps; u16 device_caps;
#endif #endif
...@@ -7084,15 +7093,16 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ...@@ -7084,15 +7093,16 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
pci_save_state(pdev); pci_save_state(pdev);
#ifdef CONFIG_IXGBE_DCB #ifdef CONFIG_IXGBE_DCB
indices *= MAX_TRAFFIC_CLASS; if (ii->mac == ixgbe_mac_82598EB)
dcb_max = min_t(unsigned int, indices * MAX_TRAFFIC_CLASS,
IXGBE_MAX_RSS_INDICES);
else
dcb_max = min_t(unsigned int, indices * MAX_TRAFFIC_CLASS,
IXGBE_MAX_FDIR_INDICES);
#endif #endif
if (ii->mac == ixgbe_mac_82598EB) if (ii->mac == ixgbe_mac_82598EB)
#ifdef CONFIG_IXGBE_DCB
indices = min_t(unsigned int, indices, MAX_TRAFFIC_CLASS * 4);
#else
indices = min_t(unsigned int, indices, IXGBE_MAX_RSS_INDICES); indices = min_t(unsigned int, indices, IXGBE_MAX_RSS_INDICES);
#endif
else else
indices = min_t(unsigned int, indices, IXGBE_MAX_FDIR_INDICES); indices = min_t(unsigned int, indices, IXGBE_MAX_FDIR_INDICES);
...@@ -7100,6 +7110,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ...@@ -7100,6 +7110,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
indices += min_t(unsigned int, num_possible_cpus(), indices += min_t(unsigned int, num_possible_cpus(),
IXGBE_MAX_FCOE_INDICES); IXGBE_MAX_FCOE_INDICES);
#endif #endif
indices = max_t(unsigned int, dcb_max, indices);
netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices); netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices);
if (!netdev) { if (!netdev) {
err = -ENOMEM; err = -ENOMEM;
...@@ -7206,8 +7217,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ...@@ -7206,8 +7217,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
goto err_sw_init; goto err_sw_init;
} }
ixgbe_probe_vf(adapter, ii); #ifdef CONFIG_PCI_IOV
ixgbe_enable_sriov(adapter, ii);
#endif
netdev->features = NETIF_F_SG | netdev->features = NETIF_F_SG |
NETIF_F_IP_CSUM | NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM | NETIF_F_IPV6_CSUM |
...@@ -7411,8 +7424,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ...@@ -7411,8 +7424,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
ixgbe_release_hw_control(adapter); ixgbe_release_hw_control(adapter);
ixgbe_clear_interrupt_scheme(adapter); ixgbe_clear_interrupt_scheme(adapter);
err_sw_init: err_sw_init:
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) ixgbe_disable_sriov(adapter);
ixgbe_disable_sriov(adapter);
adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP; adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP;
iounmap(hw->hw_addr); iounmap(hw->hw_addr);
err_ioremap: err_ioremap:
...@@ -7465,13 +7477,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) ...@@ -7465,13 +7477,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
if (netdev->reg_state == NETREG_REGISTERED) if (netdev->reg_state == NETREG_REGISTERED)
unregister_netdev(netdev); unregister_netdev(netdev);
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { ixgbe_disable_sriov(adapter);
if (!(ixgbe_check_vf_assignment(adapter)))
ixgbe_disable_sriov(adapter);
else
e_dev_warn("Unloading driver while VFs are assigned "
"- VFs will not be deallocated\n");
}
ixgbe_clear_interrupt_scheme(adapter); ixgbe_clear_interrupt_scheme(adapter);
......
...@@ -44,50 +44,15 @@ ...@@ -44,50 +44,15 @@
#include "ixgbe_sriov.h" #include "ixgbe_sriov.h"
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
static int ixgbe_find_enabled_vfs(struct ixgbe_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
struct pci_dev *pvfdev;
u16 vf_devfn = 0;
int device_id;
int vfs_found = 0;
switch (adapter->hw.mac.type) {
case ixgbe_mac_82599EB:
device_id = IXGBE_DEV_ID_82599_VF;
break;
case ixgbe_mac_X540:
device_id = IXGBE_DEV_ID_X540_VF;
break;
default:
device_id = 0;
break;
}
vf_devfn = pdev->devfn + 0x80;
pvfdev = pci_get_device(PCI_VENDOR_ID_INTEL, device_id, NULL);
while (pvfdev) {
if (pvfdev->devfn == vf_devfn &&
(pvfdev->bus->number >= pdev->bus->number))
vfs_found++;
vf_devfn += 2;
pvfdev = pci_get_device(PCI_VENDOR_ID_INTEL,
device_id, pvfdev);
}
return vfs_found;
}
void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
const struct ixgbe_info *ii) const struct ixgbe_info *ii)
{ {
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
int err = 0;
int num_vf_macvlans, i; int num_vf_macvlans, i;
struct vf_macvlans *mv_list; struct vf_macvlans *mv_list;
int pre_existing_vfs = 0; int pre_existing_vfs = 0;
pre_existing_vfs = ixgbe_find_enabled_vfs(adapter); pre_existing_vfs = pci_num_vf(adapter->pdev);
if (!pre_existing_vfs && !adapter->num_vfs) if (!pre_existing_vfs && !adapter->num_vfs)
return; return;
...@@ -106,10 +71,21 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, ...@@ -106,10 +71,21 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
"enabled for this device - Please reload all " "enabled for this device - Please reload all "
"VF drivers to avoid spoofed packet errors\n"); "VF drivers to avoid spoofed packet errors\n");
} else { } else {
int err;
/*
* The 82599 supports up to 64 VFs per physical function
* but this implementation limits allocation to 63 so that
* basic networking resources are still available to the
* physical function. If the user requests greater thn
* 63 VFs then it is an error - reset to default of zero.
*/
adapter->num_vfs = min_t(unsigned int, adapter->num_vfs, 63);
err = pci_enable_sriov(adapter->pdev, adapter->num_vfs); err = pci_enable_sriov(adapter->pdev, adapter->num_vfs);
if (err) { if (err) {
e_err(probe, "Failed to enable PCI sriov: %d\n", err); e_err(probe, "Failed to enable PCI sriov: %d\n", err);
goto err_novfs; adapter->num_vfs = 0;
return;
} }
} }
...@@ -193,20 +169,48 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, ...@@ -193,20 +169,48 @@ void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
/* Oh oh */ /* Oh oh */
e_err(probe, "Unable to allocate memory for VF Data Storage - " e_err(probe, "Unable to allocate memory for VF Data Storage - "
"SRIOV disabled\n"); "SRIOV disabled\n");
pci_disable_sriov(adapter->pdev); ixgbe_disable_sriov(adapter);
}
err_novfs: static bool ixgbe_vfs_are_assigned(struct ixgbe_adapter *adapter)
adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED; {
adapter->num_vfs = 0; struct pci_dev *pdev = adapter->pdev;
struct pci_dev *vfdev;
int dev_id;
switch (adapter->hw.mac.type) {
case ixgbe_mac_82599EB:
dev_id = IXGBE_DEV_ID_82599_VF;
break;
case ixgbe_mac_X540:
dev_id = IXGBE_DEV_ID_X540_VF;
break;
default:
return false;
}
/* loop through all the VFs to see if we own any that are assigned */
vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, NULL);
while (vfdev) {
/* if we don't own it we don't care */
if (vfdev->is_virtfn && vfdev->physfn == pdev) {
/* if it is assigned we cannot release it */
if (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)
return true;
}
vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, vfdev);
}
return false;
} }
#endif /* #ifdef CONFIG_PCI_IOV */
#endif /* #ifdef CONFIG_PCI_IOV */
void ixgbe_disable_sriov(struct ixgbe_adapter *adapter) void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
{ {
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
u32 gpie; u32 gpie;
u32 vmdctl; u32 vmdctl;
int i;
/* 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;
...@@ -219,7 +223,20 @@ void ixgbe_disable_sriov(struct ixgbe_adapter *adapter) ...@@ -219,7 +223,20 @@ void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
kfree(adapter->mv_list); kfree(adapter->mv_list);
adapter->mv_list = NULL; adapter->mv_list = NULL;
/* if SR-IOV is already disabled then there is nothing to do */
if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED))
return;
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
/*
* If our VFs are assigned we cannot shut down SR-IOV
* without causing issues, so just leave the hardware
* available but disabled
*/
if (ixgbe_vfs_are_assigned(adapter)) {
e_dev_warn("Unloading driver while VFs are assigned - VFs will not be deallocated\n");
return;
/* disable iov and allow time for transactions to clear */ /* disable iov and allow time for transactions to clear */
pci_disable_sriov(adapter->pdev); pci_disable_sriov(adapter->pdev);
#endif #endif
...@@ -244,12 +261,6 @@ void ixgbe_disable_sriov(struct ixgbe_adapter *adapter) ...@@ -244,12 +261,6 @@ void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
/* take a breather then clean up driver data */ /* take a breather then clean up driver data */
msleep(100); msleep(100);
/* Release reference to VF devices */
for (i = 0; i < adapter->num_vfs; i++) {
if (adapter->vfinfo[i].vfdev)
pci_dev_put(adapter->vfinfo[i].vfdev);
}
adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED; adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED;
} }
...@@ -483,28 +494,11 @@ static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter, ...@@ -483,28 +494,11 @@ static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,
return 0; return 0;
} }
int ixgbe_check_vf_assignment(struct ixgbe_adapter *adapter)
{
#ifdef CONFIG_PCI_IOV
int i;
for (i = 0; i < adapter->num_vfs; i++) {
if (adapter->vfinfo[i].vfdev->dev_flags &
PCI_DEV_FLAGS_ASSIGNED)
return true;
}
#endif
return false;
}
int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
{ {
unsigned char vf_mac_addr[6]; unsigned char vf_mac_addr[6];
struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); struct ixgbe_adapter *adapter = pci_get_drvdata(pdev);
unsigned int vfn = (event_mask & 0x3f); unsigned int vfn = (event_mask & 0x3f);
struct pci_dev *pvfdev;
unsigned int device_id;
u16 thisvf_devfn = (pdev->devfn + 0x80 + (vfn << 1)) |
(pdev->devfn & 1);
bool enable = ((event_mask & 0x10000000U) != 0); bool enable = ((event_mask & 0x10000000U) != 0);
...@@ -517,31 +511,6 @@ int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) ...@@ -517,31 +511,6 @@ int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
* for it later. * for it later.
*/ */
memcpy(adapter->vfinfo[vfn].vf_mac_addresses, vf_mac_addr, 6); memcpy(adapter->vfinfo[vfn].vf_mac_addresses, vf_mac_addr, 6);
switch (adapter->hw.mac.type) {
case ixgbe_mac_82599EB:
device_id = IXGBE_DEV_ID_82599_VF;
break;
case ixgbe_mac_X540:
device_id = IXGBE_DEV_ID_X540_VF;
break;
default:
device_id = 0;
break;
}
pvfdev = pci_get_device(PCI_VENDOR_ID_INTEL, device_id, NULL);
while (pvfdev) {
if (pvfdev->devfn == thisvf_devfn)
break;
pvfdev = pci_get_device(PCI_VENDOR_ID_INTEL,
device_id, pvfdev);
}
if (pvfdev)
adapter->vfinfo[vfn].vfdev = pvfdev;
else
e_err(drv, "Couldn't find pci dev ptr for VF %4.4x\n",
thisvf_devfn);
} }
return 0; return 0;
......
...@@ -42,7 +42,6 @@ int ixgbe_ndo_get_vf_config(struct net_device *netdev, ...@@ -42,7 +42,6 @@ int ixgbe_ndo_get_vf_config(struct net_device *netdev,
int vf, struct ifla_vf_info *ivi); int vf, struct ifla_vf_info *ivi);
void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter); void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter);
void ixgbe_disable_sriov(struct ixgbe_adapter *adapter); void ixgbe_disable_sriov(struct ixgbe_adapter *adapter);
int ixgbe_check_vf_assignment(struct ixgbe_adapter *adapter);
#ifdef CONFIG_PCI_IOV #ifdef CONFIG_PCI_IOV
void ixgbe_enable_sriov(struct ixgbe_adapter *adapter, void ixgbe_enable_sriov(struct ixgbe_adapter *adapter,
const struct ixgbe_info *ii); const struct ixgbe_info *ii);
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#define IXGBE_DEV_ID_82599_BACKPLANE_FCOE 0x152a #define IXGBE_DEV_ID_82599_BACKPLANE_FCOE 0x152a
#define IXGBE_DEV_ID_82599_SFP_FCOE 0x1529 #define IXGBE_DEV_ID_82599_SFP_FCOE 0x1529
#define IXGBE_SUBDEV_ID_82599_SFP 0x11A9 #define IXGBE_SUBDEV_ID_82599_SFP 0x11A9
#define IXGBE_SUBDEV_ID_82599_RNDC 0x1F72
#define IXGBE_SUBDEV_ID_82599_560FLR 0x17D0 #define IXGBE_SUBDEV_ID_82599_560FLR 0x17D0
#define IXGBE_DEV_ID_82599_SFP_EM 0x1507 #define IXGBE_DEV_ID_82599_SFP_EM 0x1507
#define IXGBE_DEV_ID_82599_SFP_SF2 0x154D #define IXGBE_DEV_ID_82599_SFP_SF2 0x154D
......
...@@ -249,6 +249,8 @@ struct ixgbevf_adapter { ...@@ -249,6 +249,8 @@ struct ixgbevf_adapter {
bool link_up; bool link_up;
struct work_struct watchdog_task; struct work_struct watchdog_task;
spinlock_t mbx_lock;
}; };
enum ixbgevf_state_t { enum ixbgevf_state_t {
...@@ -284,7 +286,6 @@ extern void ixgbevf_free_rx_resources(struct ixgbevf_adapter *, ...@@ -284,7 +286,6 @@ extern void ixgbevf_free_rx_resources(struct ixgbevf_adapter *,
extern void ixgbevf_free_tx_resources(struct ixgbevf_adapter *, extern void ixgbevf_free_tx_resources(struct ixgbevf_adapter *,
struct ixgbevf_ring *); struct ixgbevf_ring *);
extern void ixgbevf_update_stats(struct ixgbevf_adapter *adapter); extern void ixgbevf_update_stats(struct ixgbevf_adapter *adapter);
void ixgbevf_write_eitr(struct ixgbevf_q_vector *);
extern int ethtool_ioctl(struct ifreq *ifr); extern int ethtool_ioctl(struct ifreq *ifr);
extern void ixgbe_napi_add_all(struct ixgbevf_adapter *adapter); extern void ixgbe_napi_add_all(struct ixgbevf_adapter *adapter);
......
...@@ -540,6 +540,25 @@ static int ixgbevf_poll(struct napi_struct *napi, int budget) ...@@ -540,6 +540,25 @@ static int ixgbevf_poll(struct napi_struct *napi, int budget)
return 0; return 0;
} }
/**
* ixgbevf_write_eitr - write VTEITR register in hardware specific way
* @q_vector: structure containing interrupt and ring information
*/
static void ixgbevf_write_eitr(struct ixgbevf_q_vector *q_vector)
{
struct ixgbevf_adapter *adapter = q_vector->adapter;
struct ixgbe_hw *hw = &adapter->hw;
int v_idx = q_vector->v_idx;
u32 itr_reg = q_vector->itr & IXGBE_MAX_EITR;
/*
* set the WDIS bit to not clear the timer bits and cause an
* immediate assertion of the interrupt
*/
itr_reg |= IXGBE_EITR_CNT_WDIS;
IXGBE_WRITE_REG(hw, IXGBE_VTEITR(v_idx), itr_reg);
}
/** /**
* ixgbevf_configure_msix - Configure MSI-X hardware * ixgbevf_configure_msix - Configure MSI-X hardware
...@@ -662,30 +681,6 @@ static void ixgbevf_update_itr(struct ixgbevf_q_vector *q_vector, ...@@ -662,30 +681,6 @@ static void ixgbevf_update_itr(struct ixgbevf_q_vector *q_vector,
ring_container->itr = itr_setting; ring_container->itr = itr_setting;
} }
/**
* ixgbevf_write_eitr - write VTEITR register in hardware specific way
* @q_vector: structure containing interrupt and ring information
*
* This function is made to be called by ethtool and by the driver
* when it needs to update VTEITR registers at runtime. Hardware
* specific quirks/differences are taken care of here.
*/
void ixgbevf_write_eitr(struct ixgbevf_q_vector *q_vector)
{
struct ixgbevf_adapter *adapter = q_vector->adapter;
struct ixgbe_hw *hw = &adapter->hw;
int v_idx = q_vector->v_idx;
u32 itr_reg = q_vector->itr & IXGBE_MAX_EITR;
/*
* set the WDIS bit to not clear the timer bits and cause an
* immediate assertion of the interrupt
*/
itr_reg |= IXGBE_EITR_CNT_WDIS;
IXGBE_WRITE_REG(hw, IXGBE_VTEITR(v_idx), itr_reg);
}
static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector) static void ixgbevf_set_itr(struct ixgbevf_q_vector *q_vector)
{ {
u32 new_itr = q_vector->itr; u32 new_itr = q_vector->itr;
...@@ -1120,9 +1115,14 @@ static int ixgbevf_vlan_rx_add_vid(struct net_device *netdev, u16 vid) ...@@ -1120,9 +1115,14 @@ static int ixgbevf_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
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;
spin_lock(&adapter->mbx_lock);
/* add VID to filter table */ /* add VID to filter table */
if (hw->mac.ops.set_vfta) if (hw->mac.ops.set_vfta)
hw->mac.ops.set_vfta(hw, vid, 0, true); hw->mac.ops.set_vfta(hw, vid, 0, true);
spin_unlock(&adapter->mbx_lock);
set_bit(vid, adapter->active_vlans); set_bit(vid, adapter->active_vlans);
return 0; return 0;
...@@ -1133,9 +1133,14 @@ static int ixgbevf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) ...@@ -1133,9 +1133,14 @@ static int ixgbevf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
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;
spin_lock(&adapter->mbx_lock);
/* remove VID from filter table */ /* remove VID from filter table */
if (hw->mac.ops.set_vfta) if (hw->mac.ops.set_vfta)
hw->mac.ops.set_vfta(hw, vid, 0, false); hw->mac.ops.set_vfta(hw, vid, 0, false);
spin_unlock(&adapter->mbx_lock);
clear_bit(vid, adapter->active_vlans); clear_bit(vid, adapter->active_vlans);
return 0; return 0;
...@@ -1190,11 +1195,15 @@ static void ixgbevf_set_rx_mode(struct net_device *netdev) ...@@ -1190,11 +1195,15 @@ static void ixgbevf_set_rx_mode(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;
spin_lock(&adapter->mbx_lock);
/* reprogram multicast list */ /* reprogram multicast list */
if (hw->mac.ops.update_mc_addr_list) if (hw->mac.ops.update_mc_addr_list)
hw->mac.ops.update_mc_addr_list(hw, netdev); hw->mac.ops.update_mc_addr_list(hw, netdev);
ixgbevf_write_uc_addr_list(netdev); ixgbevf_write_uc_addr_list(netdev);
spin_unlock(&adapter->mbx_lock);
} }
static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter) static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter)
...@@ -1339,6 +1348,8 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter) ...@@ -1339,6 +1348,8 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter)
ixgbevf_configure_msix(adapter); ixgbevf_configure_msix(adapter);
spin_lock(&adapter->mbx_lock);
if (hw->mac.ops.set_rar) { if (hw->mac.ops.set_rar) {
if (is_valid_ether_addr(hw->mac.addr)) if (is_valid_ether_addr(hw->mac.addr))
hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0); hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0);
...@@ -1350,6 +1361,8 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter) ...@@ -1350,6 +1361,8 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter)
msg[1] = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; msg[1] = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
hw->mbx.ops.write_posted(hw, msg, 2); hw->mbx.ops.write_posted(hw, msg, 2);
spin_unlock(&adapter->mbx_lock);
clear_bit(__IXGBEVF_DOWN, &adapter->state); clear_bit(__IXGBEVF_DOWN, &adapter->state);
ixgbevf_napi_enable_all(adapter); ixgbevf_napi_enable_all(adapter);
...@@ -1562,11 +1575,15 @@ void ixgbevf_reset(struct ixgbevf_adapter *adapter) ...@@ -1562,11 +1575,15 @@ void ixgbevf_reset(struct ixgbevf_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;
spin_lock(&adapter->mbx_lock);
if (hw->mac.ops.reset_hw(hw)) if (hw->mac.ops.reset_hw(hw))
hw_dbg(hw, "PF still resetting\n"); hw_dbg(hw, "PF still resetting\n");
else else
hw->mac.ops.init_hw(hw); hw->mac.ops.init_hw(hw);
spin_unlock(&adapter->mbx_lock);
if (is_valid_ether_addr(adapter->hw.mac.addr)) { if (is_valid_ether_addr(adapter->hw.mac.addr)) {
memcpy(netdev->dev_addr, adapter->hw.mac.addr, memcpy(netdev->dev_addr, adapter->hw.mac.addr,
netdev->addr_len); netdev->addr_len);
...@@ -1893,6 +1910,9 @@ static int __devinit ixgbevf_sw_init(struct ixgbevf_adapter *adapter) ...@@ -1893,6 +1910,9 @@ static int __devinit ixgbevf_sw_init(struct ixgbevf_adapter *adapter)
adapter->netdev->addr_len); adapter->netdev->addr_len);
} }
/* lock to protect mailbox accesses */
spin_lock_init(&adapter->mbx_lock);
/* Enable dynamic interrupt throttling rates */ /* Enable dynamic interrupt throttling rates */
adapter->rx_itr_setting = 1; adapter->rx_itr_setting = 1;
adapter->tx_itr_setting = 1; adapter->tx_itr_setting = 1;
...@@ -2032,8 +2052,16 @@ static void ixgbevf_watchdog_task(struct work_struct *work) ...@@ -2032,8 +2052,16 @@ static void ixgbevf_watchdog_task(struct work_struct *work)
* no LSC interrupt * no LSC interrupt
*/ */
if (hw->mac.ops.check_link) { if (hw->mac.ops.check_link) {
if ((hw->mac.ops.check_link(hw, &link_speed, s32 need_reset;
&link_up, false)) != 0) {
spin_lock(&adapter->mbx_lock);
need_reset = hw->mac.ops.check_link(hw, &link_speed,
&link_up, false);
spin_unlock(&adapter->mbx_lock);
if (need_reset) {
adapter->link_up = link_up; adapter->link_up = link_up;
adapter->link_speed = link_speed; adapter->link_speed = link_speed;
netif_carrier_off(netdev); netif_carrier_off(netdev);
...@@ -2813,9 +2841,13 @@ static int ixgbevf_set_mac(struct net_device *netdev, void *p) ...@@ -2813,9 +2841,13 @@ static int ixgbevf_set_mac(struct net_device *netdev, void *p)
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);
spin_lock(&adapter->mbx_lock);
if (hw->mac.ops.set_rar) if (hw->mac.ops.set_rar)
hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0); hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0);
spin_unlock(&adapter->mbx_lock);
return 0; return 0;
} }
...@@ -3152,12 +3184,92 @@ static void __devexit ixgbevf_remove(struct pci_dev *pdev) ...@@ -3152,12 +3184,92 @@ static void __devexit ixgbevf_remove(struct pci_dev *pdev)
pci_disable_device(pdev); pci_disable_device(pdev);
} }
/**
* ixgbevf_io_error_detected - called when PCI error is detected
* @pdev: Pointer to PCI device
* @state: The current pci connection state
*
* This function is called after a PCI bus error affecting
* this device has been detected.
*/
static pci_ers_result_t ixgbevf_io_error_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
netif_device_detach(netdev);
if (state == pci_channel_io_perm_failure)
return PCI_ERS_RESULT_DISCONNECT;
if (netif_running(netdev))
ixgbevf_down(adapter);
pci_disable_device(pdev);
/* Request a slot slot reset. */
return PCI_ERS_RESULT_NEED_RESET;
}
/**
* ixgbevf_io_slot_reset - called after the pci bus has been reset.
* @pdev: Pointer to PCI device
*
* Restart the card from scratch, as if from a cold-boot. Implementation
* resembles the first-half of the ixgbevf_resume routine.
*/
static pci_ers_result_t ixgbevf_io_slot_reset(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
if (pci_enable_device_mem(pdev)) {
dev_err(&pdev->dev,
"Cannot re-enable PCI device after reset.\n");
return PCI_ERS_RESULT_DISCONNECT;
}
pci_set_master(pdev);
ixgbevf_reset(adapter);
return PCI_ERS_RESULT_RECOVERED;
}
/**
* ixgbevf_io_resume - called when traffic can start flowing again.
* @pdev: Pointer to PCI device
*
* This callback is called when the error recovery driver tells us that
* its OK to resume normal operation. Implementation resembles the
* second-half of the ixgbevf_resume routine.
*/
static void ixgbevf_io_resume(struct pci_dev *pdev)
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct ixgbevf_adapter *adapter = netdev_priv(netdev);
if (netif_running(netdev))
ixgbevf_up(adapter);
netif_device_attach(netdev);
}
/* PCI Error Recovery (ERS) */
static struct pci_error_handlers ixgbevf_err_handler = {
.error_detected = ixgbevf_io_error_detected,
.slot_reset = ixgbevf_io_slot_reset,
.resume = ixgbevf_io_resume,
};
static struct pci_driver ixgbevf_driver = { static struct pci_driver ixgbevf_driver = {
.name = ixgbevf_driver_name, .name = ixgbevf_driver_name,
.id_table = ixgbevf_pci_tbl, .id_table = ixgbevf_pci_tbl,
.probe = ixgbevf_probe, .probe = ixgbevf_probe,
.remove = __devexit_p(ixgbevf_remove), .remove = __devexit_p(ixgbevf_remove),
.shutdown = ixgbevf_shutdown, .shutdown = ixgbevf_shutdown,
.err_handler = &ixgbevf_err_handler
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment