q_vector->eitr = adapter->rx_eitr_param;
ixgbe_write_eitr(q_vector);
+ /* If Flow Director is enabled, set interrupt affinity */
+ if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) ||
+ (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) {
+ /*
+ * Allocate the affinity_hint cpumask, assign the mask
+ * for this vector, and set our affinity_hint for
+ * this irq.
+ */
+ if (!alloc_cpumask_var(&q_vector->affinity_mask,
+ GFP_KERNEL))
+ return;
+ cpumask_set_cpu(v_idx, q_vector->affinity_mask);
+ irq_set_affinity_hint(adapter->msix_entries[v_idx].vector,
+ q_vector->affinity_mask);
+ }
}
if (adapter->hw.mac.type == ixgbe_mac_82598EB)
* ixgbe_irq_enable - Enable default interrupt generation settings
* @adapter: board private structure
**/
-static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
+static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues,
+ bool flush)
{
u32 mask;
mask |= IXGBE_EIMS_FLOW_DIR;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
- ixgbe_irq_enable_queues(adapter, ~0);
- IXGBE_WRITE_FLUSH(&adapter->hw);
+ if (queues)
+ ixgbe_irq_enable_queues(adapter, ~0);
+ if (flush)
+ IXGBE_WRITE_FLUSH(&adapter->hw);
if (adapter->num_vfs > 32) {
u32 eitrsel = (1 << (adapter->num_vfs - 32)) - 1;
u32 eicr;
/*
- * Workaround for silicon errata. Mask the interrupts
+ * Workaround for silicon errata on 82598. Mask the interrupts
* before the read of EICR.
*/
IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
* therefore no explict interrupt disable is necessary */
eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
if (!eicr) {
- /* shared interrupt alert!
+ /*
+ * shared interrupt alert!
* make sure interrupts are enabled because the read will
- * have disabled interrupts due to EIAM */
- ixgbe_irq_enable(adapter);
+ * have disabled interrupts due to EIAM
+ * finish the workaround of silicon errata on 82598. Unmask
+ * the interrupt that we masked before the EICR read.
+ */
+ if (!test_bit(__IXGBE_DOWN, &adapter->state))
+ ixgbe_irq_enable(adapter, true, true);
return IRQ_NONE; /* Not our interrupt */
}
__napi_schedule(&(q_vector->napi));
}
+ /*
+ * re-enable link(maybe) and non-queue interrupts, no flush.
+ * ixgbe_poll will re-enable the queue interrupts
+ */
+
+ if (!test_bit(__IXGBE_DOWN, &adapter->state))
+ ixgbe_irq_enable(adapter, false, false);
+
return IRQ_HANDLED;
}
vlan_group_set_device(adapter->vlgrp, vid, NULL);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
- ixgbe_irq_enable(adapter);
+ ixgbe_irq_enable(adapter, true, true);
/* remove VID from filter table */
hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, false);
ixgbe_vlan_rx_add_vid(netdev, 0);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
- ixgbe_irq_enable(adapter);
+ ixgbe_irq_enable(adapter, true, true);
}
static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
if (adapter->vlgrp) {
u16 vid;
- for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
+ for (vid = 0; vid < VLAN_N_VID; vid++) {
if (!vlan_group_get_device(adapter->vlgrp, vid))
continue;
ixgbe_vlan_rx_add_vid(adapter->netdev, vid);
if (hw->mac.type == ixgbe_mac_82598EB)
netif_set_gso_max_size(adapter->netdev, 32768);
- ixgbe_dcb_check_config(&adapter->dcb_cfg);
ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_TX_CONFIG);
ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_RX_CONFIG);
/* clear any pending interrupts, may auto mask */
IXGBE_READ_REG(hw, IXGBE_EICR);
- ixgbe_irq_enable(adapter);
+ ixgbe_irq_enable(adapter, true, true);
/*
* If this adapter has a fan, check to see if we had a failure
u32 rxctrl;
u32 txdctl;
int i, j;
+ int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
/* signal that we are down to the interrupt handler */
set_bit(__IXGBE_DOWN, &adapter->state);
ixgbe_napi_disable_all(adapter);
+ /* Cleanup the affinity_hint CPU mask memory and callback */
+ for (i = 0; i < num_q_vectors; i++) {
+ struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
+ /* clear the affinity_mask in the IRQ descriptor */
+ irq_set_affinity_hint(adapter->msix_entries[i]. vector, NULL);
+ /* release the CPU mask memory */
+ free_cpumask_var(q_vector->affinity_mask);
+ }
+
if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
cancel_work_sync(&adapter->fdir_reinit_task);
* fallthrough conditions.
*
**/
-static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
+static int ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
{
/* Start with base case */
adapter->num_rx_queues = 1;
adapter->num_rx_queues_per_pool = 1;
if (ixgbe_set_sriov_queues(adapter))
- return;
+ goto done;
#ifdef IXGBE_FCOE
if (ixgbe_set_fcoe_queues(adapter))
adapter->num_tx_queues = 1;
done:
- /* Notify the stack of the (possibly) reduced Tx Queue count. */
+ /* Notify the stack of the (possibly) reduced queue counts. */
netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues);
+ return netif_set_real_num_rx_queues(adapter->netdev,
+ adapter->num_rx_queues);
}
static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
ixgbe_disable_sriov(adapter);
- ixgbe_set_num_queues(adapter);
+ err = ixgbe_set_num_queues(adapter);
+ if (err)
+ return err;
err = pci_enable_msi(adapter->pdev);
if (!err) {
int err;
/* Number of supported queues */
- ixgbe_set_num_queues(adapter);
+ err = ixgbe_set_num_queues(adapter);
+ if (err)
+ return err;
err = ixgbe_set_interrupt_capability(adapter);
if (err) {
int count = 0;
unsigned int f;
- if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+ if (vlan_tx_tag_present(skb)) {
tx_flags |= vlan_tx_tag_get(skb);
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
tx_flags &= ~IXGBE_TX_FLAGS_VLAN_PRIO_MASK;