@@ -4706,18 +4706,17 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
47064706 return received ;
47074707}
47084708
4709- static int tg3_poll_work (struct tg3_napi * tnapi , int work_done , int budget )
4709+ static void tg3_poll_link (struct tg3 * tp )
47104710{
4711- struct tg3 * tp = tnapi -> tp ;
4712- struct tg3_hw_status * sblk = tnapi -> hw_status ;
4713-
47144711 /* handle link change and other phy events */
47154712 if (!(tp -> tg3_flags &
47164713 (TG3_FLAG_USE_LINKCHG_REG |
47174714 TG3_FLAG_POLL_SERDES ))) {
4715+ struct tg3_hw_status * sblk = tp -> napi [0 ].hw_status ;
4716+
47184717 if (sblk -> status & SD_STATUS_LINK_CHG ) {
47194718 sblk -> status = SD_STATUS_UPDATED |
4720- (sblk -> status & ~SD_STATUS_LINK_CHG );
4719+ (sblk -> status & ~SD_STATUS_LINK_CHG );
47214720 spin_lock (& tp -> lock );
47224721 if (tp -> tg3_flags3 & TG3_FLG3_USE_PHYLIB ) {
47234722 tw32_f (MAC_STATUS ,
@@ -4731,6 +4730,11 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
47314730 spin_unlock (& tp -> lock );
47324731 }
47334732 }
4733+ }
4734+
4735+ static int tg3_poll_work (struct tg3_napi * tnapi , int work_done , int budget )
4736+ {
4737+ struct tg3 * tp = tnapi -> tp ;
47344738
47354739 /* run TX completion thread */
47364740 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)
47494753 return work_done ;
47504754}
47514755
4756+ static int tg3_poll_msix (struct napi_struct * napi , int budget )
4757+ {
4758+ struct tg3_napi * tnapi = container_of (napi , struct tg3_napi , napi );
4759+ struct tg3 * tp = tnapi -> tp ;
4760+ int work_done = 0 ;
4761+ struct tg3_hw_status * sblk = tnapi -> hw_status ;
4762+
4763+ while (1 ) {
4764+ work_done = tg3_poll_work (tnapi , work_done , budget );
4765+
4766+ if (unlikely (tp -> tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING ))
4767+ goto tx_recovery ;
4768+
4769+ if (unlikely (work_done >= budget ))
4770+ break ;
4771+
4772+ /* tp->last_tag is used in tg3_restart_ints() below
4773+ * to tell the hw how much work has been processed,
4774+ * so we must read it before checking for more work.
4775+ */
4776+ tnapi -> last_tag = sblk -> status_tag ;
4777+ tnapi -> last_irq_tag = tnapi -> last_tag ;
4778+ rmb ();
4779+
4780+ /* check for RX/TX work to do */
4781+ if (sblk -> idx [0 ].tx_consumer == tnapi -> tx_cons &&
4782+ * (tnapi -> rx_rcb_prod_idx ) == tnapi -> rx_rcb_ptr ) {
4783+ napi_complete (napi );
4784+ /* Reenable interrupts. */
4785+ tw32_mailbox (tnapi -> int_mbox , tnapi -> last_tag << 24 );
4786+ mmiowb ();
4787+ break ;
4788+ }
4789+ }
4790+
4791+ return work_done ;
4792+
4793+ tx_recovery :
4794+ /* work_done is guaranteed to be less than budget. */
4795+ napi_complete (napi );
4796+ schedule_work (& tp -> reset_task );
4797+ return work_done ;
4798+ }
4799+
47524800static int tg3_poll (struct napi_struct * napi , int budget )
47534801{
47544802 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)
47574805 struct tg3_hw_status * sblk = tnapi -> hw_status ;
47584806
47594807 while (1 ) {
4808+ tg3_poll_link (tp );
4809+
47604810 work_done = tg3_poll_work (tnapi , work_done , budget );
47614811
47624812 if (unlikely (tp -> tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING ))
@@ -14057,10 +14107,13 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
1405714107 tnapi -> consmbox = rcvmbx ;
1405814108 tnapi -> prodmbox = sndmbx ;
1405914109
14060- if (i )
14110+ if (i ) {
1406114111 tnapi -> coal_now = HOSTCC_MODE_COAL_VEC1_NOW << (i - 1 );
14062- else
14112+ netif_napi_add (dev , & tnapi -> napi , tg3_poll_msix , 64 );
14113+ } else {
1406314114 tnapi -> coal_now = HOSTCC_MODE_NOW ;
14115+ netif_napi_add (dev , & tnapi -> napi , tg3_poll , 64 );
14116+ }
1406414117
1406514118 if (!(tp -> tg3_flags & TG3_FLAG_SUPPORT_MSIX ))
1406614119 break ;
@@ -14083,7 +14136,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
1408314136 sndmbx += 0xc ;
1408414137 }
1408514138
14086- netif_napi_add (dev , & tp -> napi [0 ].napi , tg3_poll , 64 );
1408714139 dev -> ethtool_ops = & tg3_ethtool_ops ;
1408814140 dev -> watchdog_timeo = TG3_TX_TIMEOUT ;
1408914141 dev -> irq = pdev -> irq ;
0 commit comments