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

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
...@@ -4706,18 +4706,17 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) ...@@ -4706,18 +4706,17 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
return received; 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 */ /* handle link change and other phy events */
if (!(tp->tg3_flags & if (!(tp->tg3_flags &
(TG3_FLAG_USE_LINKCHG_REG | (TG3_FLAG_USE_LINKCHG_REG |
TG3_FLAG_POLL_SERDES))) { TG3_FLAG_POLL_SERDES))) {
struct tg3_hw_status *sblk = tp->napi[0].hw_status;
if (sblk->status & SD_STATUS_LINK_CHG) { if (sblk->status & SD_STATUS_LINK_CHG) {
sblk->status = SD_STATUS_UPDATED | sblk->status = SD_STATUS_UPDATED |
(sblk->status & ~SD_STATUS_LINK_CHG); (sblk->status & ~SD_STATUS_LINK_CHG);
spin_lock(&tp->lock); spin_lock(&tp->lock);
if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) { if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
tw32_f(MAC_STATUS, tw32_f(MAC_STATUS,
...@@ -4731,6 +4730,11 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget) ...@@ -4731,6 +4730,11 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
spin_unlock(&tp->lock); 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 */ /* run TX completion thread */
if (tnapi->hw_status->idx[0].tx_consumer != tnapi->tx_cons) { 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) ...@@ -4749,6 +4753,50 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
return work_done; 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) static int tg3_poll(struct napi_struct *napi, int budget)
{ {
struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi); 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) ...@@ -4757,6 +4805,8 @@ static int tg3_poll(struct napi_struct *napi, int budget)
struct tg3_hw_status *sblk = tnapi->hw_status; struct tg3_hw_status *sblk = tnapi->hw_status;
while (1) { while (1) {
tg3_poll_link(tp);
work_done = tg3_poll_work(tnapi, work_done, budget); work_done = tg3_poll_work(tnapi, work_done, budget);
if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING)) if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
...@@ -14057,10 +14107,13 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, ...@@ -14057,10 +14107,13 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tnapi->consmbox = rcvmbx; tnapi->consmbox = rcvmbx;
tnapi->prodmbox = sndmbx; tnapi->prodmbox = sndmbx;
if (i) if (i) {
tnapi->coal_now = HOSTCC_MODE_COAL_VEC1_NOW << (i - 1); 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; tnapi->coal_now = HOSTCC_MODE_NOW;
netif_napi_add(dev, &tnapi->napi, tg3_poll, 64);
}
if (!(tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX)) if (!(tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX))
break; break;
...@@ -14083,7 +14136,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, ...@@ -14083,7 +14136,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
sndmbx += 0xc; sndmbx += 0xc;
} }
netif_napi_add(dev, &tp->napi[0].napi, tg3_poll, 64);
dev->ethtool_ops = &tg3_ethtool_ops; dev->ethtool_ops = &tg3_ethtool_ops;
dev->watchdog_timeo = TG3_TX_TIMEOUT; dev->watchdog_timeo = TG3_TX_TIMEOUT;
dev->irq = pdev->irq; dev->irq = pdev->irq;
......
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