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

Commit 35f2d7d0 authored by Matt Carlson's avatar Matt Carlson Committed by David S. Miller
Browse files

tg3: Create tg3_poll_msix() for non-zero MSIX vecs



This patch gives all non-zero MSIX vectors their own NAPI handler.  This
will make NAPI handling for those vectors slightly more efficient.

Signed-off-by: default avatarMatt Carlson <mcarlson@broadcom.com>
Reviewed-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cbf9ca6c
Loading
Loading
Loading
Loading
+60 −8
Original line number Diff line number Diff line
@@ -4706,15 +4706,14 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
	return received;
}

static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
static void tg3_poll_link(struct tg3 *tp)
{
	struct tg3 *tp = tnapi->tp;
	struct tg3_hw_status *sblk = tnapi->hw_status;

	/* handle link change and other phy events */
	if (!(tp->tg3_flags &
	      (TG3_FLAG_USE_LINKCHG_REG |
	       TG3_FLAG_POLL_SERDES))) {
		struct tg3_hw_status *sblk = tp->napi[0].hw_status;

		if (sblk->status & SD_STATUS_LINK_CHG) {
			sblk->status = SD_STATUS_UPDATED |
				       (sblk->status & ~SD_STATUS_LINK_CHG);
@@ -4731,6 +4730,11 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
			spin_unlock(&tp->lock);
		}
	}
}

static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
{
	struct tg3 *tp = tnapi->tp;

	/* run TX completion thread */
	if (tnapi->hw_status->idx[0].tx_consumer != tnapi->tx_cons) {
@@ -4749,6 +4753,50 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
	return work_done;
}

static int tg3_poll_msix(struct napi_struct *napi, int budget)
{
	struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi);
	struct tg3 *tp = tnapi->tp;
	int work_done = 0;
	struct tg3_hw_status *sblk = tnapi->hw_status;

	while (1) {
		work_done = tg3_poll_work(tnapi, work_done, budget);

		if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
			goto tx_recovery;

		if (unlikely(work_done >= budget))
			break;

		/* tp->last_tag is used in tg3_restart_ints() below
		 * to tell the hw how much work has been processed,
		 * so we must read it before checking for more work.
		 */
		tnapi->last_tag = sblk->status_tag;
		tnapi->last_irq_tag = tnapi->last_tag;
		rmb();

		/* check for RX/TX work to do */
		if (sblk->idx[0].tx_consumer == tnapi->tx_cons &&
		    *(tnapi->rx_rcb_prod_idx) == tnapi->rx_rcb_ptr) {
			napi_complete(napi);
			/* Reenable interrupts. */
			tw32_mailbox(tnapi->int_mbox, tnapi->last_tag << 24);
			mmiowb();
			break;
		}
	}

	return work_done;

tx_recovery:
	/* work_done is guaranteed to be less than budget. */
	napi_complete(napi);
	schedule_work(&tp->reset_task);
	return work_done;
}

static int tg3_poll(struct napi_struct *napi, int budget)
{
	struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi);
@@ -4757,6 +4805,8 @@ static int tg3_poll(struct napi_struct *napi, int budget)
	struct tg3_hw_status *sblk = tnapi->hw_status;

	while (1) {
		tg3_poll_link(tp);

		work_done = tg3_poll_work(tnapi, work_done, budget);

		if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
@@ -14057,10 +14107,13 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
		tnapi->consmbox = rcvmbx;
		tnapi->prodmbox = sndmbx;

		if (i)
		if (i) {
			tnapi->coal_now = HOSTCC_MODE_COAL_VEC1_NOW << (i - 1);
		else
			netif_napi_add(dev, &tnapi->napi, tg3_poll_msix, 64);
		} else {
			tnapi->coal_now = HOSTCC_MODE_NOW;
			netif_napi_add(dev, &tnapi->napi, tg3_poll, 64);
		}

		if (!(tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX))
			break;
@@ -14083,7 +14136,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
			sndmbx += 0xc;
	}

	netif_napi_add(dev, &tp->napi[0].napi, tg3_poll, 64);
	dev->ethtool_ops = &tg3_ethtool_ops;
	dev->watchdog_timeo = TG3_TX_TIMEOUT;
	dev->irq = pdev->irq;