Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 844290e5 authored by PJ Waskiewicz's avatar PJ Waskiewicz Committed by Jeff Garzik
Browse files

igb: add NAPI Rx queue support



Update the NAPI implementation to use the new napi_struct infrstructure.
This removes the need of multiple net_device structs to implement a
multiqueue NAPI.

Signed-off-by: default avatarPJ Waskiewicz <peter.p.waskiewicz.jr.@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent 662d7205
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -150,6 +150,7 @@ struct igb_ring {
	u16 itr_register;
	u16 cpu;

	int queue_index;
	unsigned int total_bytes;
	unsigned int total_packets;

@@ -265,6 +266,7 @@ struct igb_adapter {
	int msg_enable;
	struct msix_entry *msix_entries;
	u32 eims_enable_mask;
	u32 eims_other;

	/* to not mess up cache alignment, always add to the bottom */
	unsigned long state;
+59 −89
Original line number Diff line number Diff line
@@ -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
	} 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);
	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);

	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);

	/* 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,14 +3026,8 @@ 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);

	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;
@@ -3049,11 +3035,10 @@ static irqreturn_t igb_msix_other(int irq, void *data)
	/* 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 @@ static int igb_clean_rx_ring_msix(struct napi_struct *napi, int budget)
			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;
	}