|
@@ -227,12 +227,11 @@ static int igb_alloc_queues(struct igb_adapter *adapter)
|
|
|
for (i = 0; i < adapter->num_rx_queues; i++) {
|
|
|
struct igb_ring *ring = &(adapter->rx_ring[i]);
|
|
|
ring->adapter = adapter;
|
|
|
+ ring->queue_index = i;
|
|
|
ring->itr_register = E1000_ITR;
|
|
|
|
|
|
- if (!ring->napi.poll)
|
|
|
- netif_napi_add(adapter->netdev, &ring->napi, igb_clean,
|
|
|
- adapter->napi.weight /
|
|
|
- adapter->num_rx_queues);
|
|
|
+ /* set a default napi handler for each rx_ring */
|
|
|
+ netif_napi_add(adapter->netdev, &ring->napi, igb_clean, 64);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
@@ -300,9 +299,6 @@ static void igb_configure_msix(struct igb_adapter *adapter)
|
|
|
array_wr32(E1000_MSIXBM(0), vector++,
|
|
|
E1000_EIMS_OTHER);
|
|
|
|
|
|
- /* disable IAM for ICR interrupt bits */
|
|
|
- wr32(E1000_IAM, 0);
|
|
|
-
|
|
|
tmp = rd32(E1000_CTRL_EXT);
|
|
|
/* enable MSI-X PBA support*/
|
|
|
tmp |= E1000_CTRL_EXT_PBA_CLR;
|
|
@@ -313,6 +309,7 @@ static void igb_configure_msix(struct igb_adapter *adapter)
|
|
|
|
|
|
wr32(E1000_CTRL_EXT, tmp);
|
|
|
adapter->eims_enable_mask |= E1000_EIMS_OTHER;
|
|
|
+ adapter->eims_other = E1000_EIMS_OTHER;
|
|
|
|
|
|
wrfl();
|
|
|
}
|
|
@@ -355,6 +352,9 @@ static int igb_request_msix(struct igb_adapter *adapter)
|
|
|
goto out;
|
|
|
ring->itr_register = E1000_EITR(0) + (vector << 2);
|
|
|
ring->itr_val = adapter->itr;
|
|
|
+ /* overwrite the poll routine for MSIX, we've already done
|
|
|
+ * netif_napi_add */
|
|
|
+ ring->napi.poll = &igb_clean_rx_ring_msix;
|
|
|
vector++;
|
|
|
}
|
|
|
|
|
@@ -363,9 +363,6 @@ static int igb_request_msix(struct igb_adapter *adapter)
|
|
|
if (err)
|
|
|
goto out;
|
|
|
|
|
|
- adapter->napi.poll = igb_clean_rx_ring_msix;
|
|
|
- for (i = 0; i < adapter->num_rx_queues; i++)
|
|
|
- adapter->rx_ring[i].napi.poll = adapter->napi.poll;
|
|
|
igb_configure_msix(adapter);
|
|
|
return 0;
|
|
|
out:
|
|
@@ -434,12 +431,8 @@ static int igb_request_irq(struct igb_adapter *adapter)
|
|
|
|
|
|
if (adapter->msix_entries) {
|
|
|
err = igb_request_msix(adapter);
|
|
|
- if (!err) {
|
|
|
- /* enable IAM, auto-mask,
|
|
|
- * DO NOT USE EIAM or IAM in legacy mode */
|
|
|
- wr32(E1000_IAM, IMS_ENABLE_MASK);
|
|
|
+ if (!err)
|
|
|
goto request_done;
|
|
|
- }
|
|
|
/* fall back to MSI */
|
|
|
igb_reset_interrupt_capability(adapter);
|
|
|
if (!pci_enable_msi(adapter->pdev))
|
|
@@ -448,7 +441,11 @@ static int igb_request_irq(struct igb_adapter *adapter)
|
|
|
igb_free_all_rx_resources(adapter);
|
|
|
adapter->num_rx_queues = 1;
|
|
|
igb_alloc_queues(adapter);
|
|
|
+ } else {
|
|
|
+ wr32(E1000_MSIXBM(0), (E1000_EICR_RX_QUEUE0 |
|
|
|
+ E1000_EIMS_OTHER));
|
|
|
}
|
|
|
+
|
|
|
if (adapter->msi_enabled) {
|
|
|
err = request_irq(adapter->pdev->irq, &igb_intr_msi, 0,
|
|
|
netdev->name, netdev);
|
|
@@ -500,9 +497,12 @@ static void igb_irq_disable(struct igb_adapter *adapter)
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
|
|
if (adapter->msix_entries) {
|
|
|
+ wr32(E1000_EIAM, 0);
|
|
|
wr32(E1000_EIMC, ~0);
|
|
|
wr32(E1000_EIAC, 0);
|
|
|
}
|
|
|
+
|
|
|
+ wr32(E1000_IAM, 0);
|
|
|
wr32(E1000_IMC, ~0);
|
|
|
wrfl();
|
|
|
synchronize_irq(adapter->pdev->irq);
|
|
@@ -517,13 +517,14 @@ static void igb_irq_enable(struct igb_adapter *adapter)
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
|
|
if (adapter->msix_entries) {
|
|
|
- wr32(E1000_EIMS,
|
|
|
- adapter->eims_enable_mask);
|
|
|
- wr32(E1000_EIAC,
|
|
|
- adapter->eims_enable_mask);
|
|
|
+ wr32(E1000_EIAC, adapter->eims_enable_mask);
|
|
|
+ wr32(E1000_EIAM, adapter->eims_enable_mask);
|
|
|
+ wr32(E1000_EIMS, adapter->eims_enable_mask);
|
|
|
wr32(E1000_IMS, E1000_IMS_LSC);
|
|
|
- } else
|
|
|
- wr32(E1000_IMS, IMS_ENABLE_MASK);
|
|
|
+ } else {
|
|
|
+ wr32(E1000_IMS, IMS_ENABLE_MASK);
|
|
|
+ wr32(E1000_IAM, IMS_ENABLE_MASK);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void igb_update_mng_vlan(struct igb_adapter *adapter)
|
|
@@ -661,13 +662,10 @@ int igb_up(struct igb_adapter *adapter)
|
|
|
|
|
|
clear_bit(__IGB_DOWN, &adapter->state);
|
|
|
|
|
|
- napi_enable(&adapter->napi);
|
|
|
-
|
|
|
- if (adapter->msix_entries) {
|
|
|
- for (i = 0; i < adapter->num_rx_queues; i++)
|
|
|
- napi_enable(&adapter->rx_ring[i].napi);
|
|
|
+ for (i = 0; i < adapter->num_rx_queues; i++)
|
|
|
+ napi_enable(&adapter->rx_ring[i].napi);
|
|
|
+ if (adapter->msix_entries)
|
|
|
igb_configure_msix(adapter);
|
|
|
- }
|
|
|
|
|
|
/* Clear any pending interrupts. */
|
|
|
rd32(E1000_ICR);
|
|
@@ -704,11 +702,9 @@ void igb_down(struct igb_adapter *adapter)
|
|
|
wrfl();
|
|
|
msleep(10);
|
|
|
|
|
|
- napi_disable(&adapter->napi);
|
|
|
+ for (i = 0; i < adapter->num_rx_queues; i++)
|
|
|
+ napi_disable(&adapter->rx_ring[i].napi);
|
|
|
|
|
|
- if (adapter->msix_entries)
|
|
|
- for (i = 0; i < adapter->num_rx_queues; i++)
|
|
|
- napi_disable(&adapter->rx_ring[i].napi);
|
|
|
igb_irq_disable(adapter);
|
|
|
|
|
|
del_timer_sync(&adapter->watchdog_timer);
|
|
@@ -933,7 +929,6 @@ static int __devinit igb_probe(struct pci_dev *pdev,
|
|
|
igb_set_ethtool_ops(netdev);
|
|
|
netdev->tx_timeout = &igb_tx_timeout;
|
|
|
netdev->watchdog_timeo = 5 * HZ;
|
|
|
- netif_napi_add(netdev, &adapter->napi, igb_clean, 64);
|
|
|
netdev->vlan_rx_register = igb_vlan_rx_register;
|
|
|
netdev->vlan_rx_add_vid = igb_vlan_rx_add_vid;
|
|
|
netdev->vlan_rx_kill_vid = igb_vlan_rx_kill_vid;
|
|
@@ -1298,15 +1293,14 @@ static int igb_open(struct net_device *netdev)
|
|
|
/* From here on the code is the same as igb_up() */
|
|
|
clear_bit(__IGB_DOWN, &adapter->state);
|
|
|
|
|
|
- napi_enable(&adapter->napi);
|
|
|
- if (adapter->msix_entries)
|
|
|
- for (i = 0; i < adapter->num_rx_queues; i++)
|
|
|
- napi_enable(&adapter->rx_ring[i].napi);
|
|
|
-
|
|
|
- igb_irq_enable(adapter);
|
|
|
+ for (i = 0; i < adapter->num_rx_queues; i++)
|
|
|
+ napi_enable(&adapter->rx_ring[i].napi);
|
|
|
|
|
|
/* Clear any pending interrupts. */
|
|
|
rd32(E1000_ICR);
|
|
|
+
|
|
|
+ igb_irq_enable(adapter);
|
|
|
+
|
|
|
/* Fire a link status change interrupt to start the watchdog. */
|
|
|
wr32(E1000_ICS, E1000_ICS_LSC);
|
|
|
|
|
@@ -1534,8 +1528,6 @@ int igb_setup_rx_resources(struct igb_adapter *adapter,
|
|
|
rx_ring->pending_skb = NULL;
|
|
|
|
|
|
rx_ring->adapter = adapter;
|
|
|
- /* FIXME: do we want to setup ring->napi->poll here? */
|
|
|
- rx_ring->napi.poll = adapter->napi.poll;
|
|
|
|
|
|
return 0;
|
|
|
|
|
@@ -3034,26 +3026,19 @@ static irqreturn_t igb_msix_other(int irq, void *data)
|
|
|
struct net_device *netdev = data;
|
|
|
struct igb_adapter *adapter = netdev_priv(netdev);
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
- u32 eicr;
|
|
|
- /* disable interrupts from the "other" bit, avoid re-entry */
|
|
|
- wr32(E1000_EIMC, E1000_EIMS_OTHER);
|
|
|
-
|
|
|
- eicr = rd32(E1000_EICR);
|
|
|
+ u32 icr = rd32(E1000_ICR);
|
|
|
|
|
|
- if (eicr & E1000_EIMS_OTHER) {
|
|
|
- u32 icr = rd32(E1000_ICR);
|
|
|
- /* reading ICR causes bit 31 of EICR to be cleared */
|
|
|
- if (!(icr & E1000_ICR_LSC))
|
|
|
- goto no_link_interrupt;
|
|
|
- hw->mac.get_link_status = 1;
|
|
|
- /* guard against interrupt when we're going down */
|
|
|
- if (!test_bit(__IGB_DOWN, &adapter->state))
|
|
|
- mod_timer(&adapter->watchdog_timer, jiffies + 1);
|
|
|
- }
|
|
|
+ /* reading ICR causes bit 31 of EICR to be cleared */
|
|
|
+ if (!(icr & E1000_ICR_LSC))
|
|
|
+ goto no_link_interrupt;
|
|
|
+ hw->mac.get_link_status = 1;
|
|
|
+ /* guard against interrupt when we're going down */
|
|
|
+ if (!test_bit(__IGB_DOWN, &adapter->state))
|
|
|
+ mod_timer(&adapter->watchdog_timer, jiffies + 1);
|
|
|
|
|
|
no_link_interrupt:
|
|
|
wr32(E1000_IMS, E1000_IMS_LSC);
|
|
|
- wr32(E1000_EIMS, E1000_EIMS_OTHER);
|
|
|
+ wr32(E1000_EIMS, adapter->eims_other);
|
|
|
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
@@ -3084,21 +3069,19 @@ static irqreturn_t igb_msix_rx(int irq, void *data)
|
|
|
struct igb_adapter *adapter = rx_ring->adapter;
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
|
|
|
- if (!rx_ring->itr_val)
|
|
|
- wr32(E1000_EIMC, rx_ring->eims_value);
|
|
|
+ /* Write the ITR value calculated at the end of the
|
|
|
+ * previous interrupt.
|
|
|
+ */
|
|
|
|
|
|
- if (netif_rx_schedule_prep(adapter->netdev, &rx_ring->napi)) {
|
|
|
- rx_ring->total_bytes = 0;
|
|
|
- rx_ring->total_packets = 0;
|
|
|
- rx_ring->no_itr_adjust = 0;
|
|
|
- __netif_rx_schedule(adapter->netdev, &rx_ring->napi);
|
|
|
- } else {
|
|
|
- if (!rx_ring->no_itr_adjust) {
|
|
|
- igb_lower_rx_eitr(adapter, rx_ring);
|
|
|
- rx_ring->no_itr_adjust = 1;
|
|
|
- }
|
|
|
+ if (adapter->set_itr) {
|
|
|
+ wr32(rx_ring->itr_register,
|
|
|
+ 1000000000 / (rx_ring->itr_val * 256));
|
|
|
+ adapter->set_itr = 0;
|
|
|
}
|
|
|
|
|
|
+ if (netif_rx_schedule_prep(adapter->netdev, &rx_ring->napi))
|
|
|
+ __netif_rx_schedule(adapter->netdev, &rx_ring->napi);
|
|
|
+
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
|
|
|
@@ -3112,7 +3095,6 @@ static irqreturn_t igb_intr_msi(int irq, void *data)
|
|
|
{
|
|
|
struct net_device *netdev = data;
|
|
|
struct igb_adapter *adapter = netdev_priv(netdev);
|
|
|
- struct napi_struct *napi = &adapter->napi;
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
/* read ICR disables interrupts using IAM */
|
|
|
u32 icr = rd32(E1000_ICR);
|
|
@@ -3121,25 +3103,17 @@ static irqreturn_t igb_intr_msi(int irq, void *data)
|
|
|
* previous interrupt.
|
|
|
*/
|
|
|
if (adapter->set_itr) {
|
|
|
- wr32(E1000_ITR,
|
|
|
- 1000000000 / (adapter->itr * 256));
|
|
|
+ wr32(E1000_ITR, 1000000000 / (adapter->itr * 256));
|
|
|
adapter->set_itr = 0;
|
|
|
}
|
|
|
|
|
|
- /* read ICR disables interrupts using IAM */
|
|
|
if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
|
|
|
hw->mac.get_link_status = 1;
|
|
|
if (!test_bit(__IGB_DOWN, &adapter->state))
|
|
|
mod_timer(&adapter->watchdog_timer, jiffies + 1);
|
|
|
}
|
|
|
|
|
|
- if (netif_rx_schedule_prep(netdev, napi)) {
|
|
|
- adapter->tx_ring->total_bytes = 0;
|
|
|
- adapter->tx_ring->total_packets = 0;
|
|
|
- adapter->rx_ring->total_bytes = 0;
|
|
|
- adapter->rx_ring->total_packets = 0;
|
|
|
- __netif_rx_schedule(netdev, napi);
|
|
|
- }
|
|
|
+ netif_rx_schedule(netdev, &adapter->rx_ring[0].napi);
|
|
|
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
@@ -3153,7 +3127,6 @@ static irqreturn_t igb_intr(int irq, void *data)
|
|
|
{
|
|
|
struct net_device *netdev = data;
|
|
|
struct igb_adapter *adapter = netdev_priv(netdev);
|
|
|
- struct napi_struct *napi = &adapter->napi;
|
|
|
struct e1000_hw *hw = &adapter->hw;
|
|
|
/* Interrupt Auto-Mask...upon reading ICR, interrupts are masked. No
|
|
|
* need for the IMC write */
|
|
@@ -3166,8 +3139,7 @@ static irqreturn_t igb_intr(int irq, void *data)
|
|
|
* previous interrupt.
|
|
|
*/
|
|
|
if (adapter->set_itr) {
|
|
|
- wr32(E1000_ITR,
|
|
|
- 1000000000 / (adapter->itr * 256));
|
|
|
+ wr32(E1000_ITR, 1000000000 / (adapter->itr * 256));
|
|
|
adapter->set_itr = 0;
|
|
|
}
|
|
|
|
|
@@ -3185,13 +3157,7 @@ static irqreturn_t igb_intr(int irq, void *data)
|
|
|
mod_timer(&adapter->watchdog_timer, jiffies + 1);
|
|
|
}
|
|
|
|
|
|
- if (netif_rx_schedule_prep(netdev, napi)) {
|
|
|
- adapter->tx_ring->total_bytes = 0;
|
|
|
- adapter->rx_ring->total_bytes = 0;
|
|
|
- adapter->tx_ring->total_packets = 0;
|
|
|
- adapter->rx_ring->total_packets = 0;
|
|
|
- __netif_rx_schedule(netdev, napi);
|
|
|
- }
|
|
|
+ netif_rx_schedule(netdev, &adapter->rx_ring[0].napi);
|
|
|
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
@@ -3274,6 +3240,10 @@ quit_polling:
|
|
|
else if (mean_size > IGB_DYN_ITR_LENGTH_HIGH)
|
|
|
igb_lower_rx_eitr(adapter, rx_ring);
|
|
|
}
|
|
|
+
|
|
|
+ if (!test_bit(__IGB_DOWN, &adapter->state))
|
|
|
+ wr32(E1000_EIMS, rx_ring->eims_value);
|
|
|
+
|
|
|
return 0;
|
|
|
}
|
|
|
|