aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/tg3.c29
-rw-r--r--drivers/net/tg3.h1
2 files changed, 20 insertions, 10 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index a46c26764ba7..c140e1bf6e02 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -642,7 +642,6 @@ static void tg3_disable_ints(struct tg3 *tp)
642static void tg3_enable_ints(struct tg3 *tp) 642static void tg3_enable_ints(struct tg3 *tp)
643{ 643{
644 int i; 644 int i;
645 u32 coal_now = 0;
646 645
647 tp->irq_sync = 0; 646 tp->irq_sync = 0;
648 wmb(); 647 wmb();
@@ -650,13 +649,14 @@ static void tg3_enable_ints(struct tg3 *tp)
650 tw32(TG3PCI_MISC_HOST_CTRL, 649 tw32(TG3PCI_MISC_HOST_CTRL,
651 (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); 650 (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
652 651
652 tp->coal_now = tp->coalesce_mode | HOSTCC_MODE_ENABLE;
653 for (i = 0; i < tp->irq_cnt; i++) { 653 for (i = 0; i < tp->irq_cnt; i++) {
654 struct tg3_napi *tnapi = &tp->napi[i]; 654 struct tg3_napi *tnapi = &tp->napi[i];
655 tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24); 655 tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
656 if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI) 656 if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
657 tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24); 657 tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
658 658
659 coal_now |= tnapi->coal_now; 659 tp->coal_now |= tnapi->coal_now;
660 } 660 }
661 661
662 /* Force an initial interrupt */ 662 /* Force an initial interrupt */
@@ -664,8 +664,9 @@ static void tg3_enable_ints(struct tg3 *tp)
664 (tp->napi[0].hw_status->status & SD_STATUS_UPDATED)) 664 (tp->napi[0].hw_status->status & SD_STATUS_UPDATED))
665 tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); 665 tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
666 else 666 else
667 tw32(HOSTCC_MODE, tp->coalesce_mode | 667 tw32(HOSTCC_MODE, tp->coal_now);
668 HOSTCC_MODE_ENABLE | coal_now); 668
669 tp->coal_now &= ~(tp->napi[0].coal_now | tp->napi[1].coal_now);
669} 670}
670 671
671static inline unsigned int tg3_has_work(struct tg3_napi *tnapi) 672static inline unsigned int tg3_has_work(struct tg3_napi *tnapi)
@@ -4794,12 +4795,12 @@ static void tg3_poll_link(struct tg3 *tp)
4794 } 4795 }
4795} 4796}
4796 4797
4797static void tg3_rx_prodring_xfer(struct tg3 *tp, 4798static int tg3_rx_prodring_xfer(struct tg3 *tp,
4798 struct tg3_rx_prodring_set *dpr, 4799 struct tg3_rx_prodring_set *dpr,
4799 struct tg3_rx_prodring_set *spr) 4800 struct tg3_rx_prodring_set *spr)
4800{ 4801{
4801 u32 si, di, cpycnt, src_prod_idx; 4802 u32 si, di, cpycnt, src_prod_idx;
4802 int i; 4803 int i, err = 0;
4803 4804
4804 while (1) { 4805 while (1) {
4805 src_prod_idx = spr->rx_std_prod_idx; 4806 src_prod_idx = spr->rx_std_prod_idx;
@@ -4825,6 +4826,7 @@ static void tg3_rx_prodring_xfer(struct tg3 *tp,
4825 for (i = di; i < di + cpycnt; i++) { 4826 for (i = di; i < di + cpycnt; i++) {
4826 if (dpr->rx_std_buffers[i].skb) { 4827 if (dpr->rx_std_buffers[i].skb) {
4827 cpycnt = i - di; 4828 cpycnt = i - di;
4829 err = -ENOSPC;
4828 break; 4830 break;
4829 } 4831 }
4830 } 4832 }
@@ -4881,6 +4883,7 @@ static void tg3_rx_prodring_xfer(struct tg3 *tp,
4881 for (i = di; i < di + cpycnt; i++) { 4883 for (i = di; i < di + cpycnt; i++) {
4882 if (dpr->rx_jmb_buffers[i].skb) { 4884 if (dpr->rx_jmb_buffers[i].skb) {
4883 cpycnt = i - di; 4885 cpycnt = i - di;
4886 err = -ENOSPC;
4884 break; 4887 break;
4885 } 4888 }
4886 } 4889 }
@@ -4911,6 +4914,8 @@ static void tg3_rx_prodring_xfer(struct tg3 *tp,
4911 dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) % 4914 dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) %
4912 TG3_RX_JUMBO_RING_SIZE; 4915 TG3_RX_JUMBO_RING_SIZE;
4913 } 4916 }
4917
4918 return err;
4914} 4919}
4915 4920
4916static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget) 4921static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
@@ -4933,12 +4938,13 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
4933 4938
4934 if ((tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) && tnapi == &tp->napi[1]) { 4939 if ((tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) && tnapi == &tp->napi[1]) {
4935 struct tg3_rx_prodring_set *dpr = &tp->prodring[0]; 4940 struct tg3_rx_prodring_set *dpr = &tp->prodring[0];
4936 int i; 4941 int i, err = 0;
4937 u32 std_prod_idx = dpr->rx_std_prod_idx; 4942 u32 std_prod_idx = dpr->rx_std_prod_idx;
4938 u32 jmb_prod_idx = dpr->rx_jmb_prod_idx; 4943 u32 jmb_prod_idx = dpr->rx_jmb_prod_idx;
4939 4944
4940 for (i = 1; i < tp->irq_cnt; i++) 4945 for (i = 1; i < tp->irq_cnt; i++)
4941 tg3_rx_prodring_xfer(tp, dpr, tp->napi[i].prodring); 4946 err |= tg3_rx_prodring_xfer(tp, dpr,
4947 tp->napi[i].prodring);
4942 4948
4943 wmb(); 4949 wmb();
4944 4950
@@ -4951,6 +4957,9 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
4951 dpr->rx_jmb_prod_idx); 4957 dpr->rx_jmb_prod_idx);
4952 4958
4953 mmiowb(); 4959 mmiowb();
4960
4961 if (err)
4962 tw32_f(HOSTCC_MODE, tp->coal_now);
4954 } 4963 }
4955 4964
4956 return work_done; 4965 return work_done;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 88a87bb618c0..cc8bf7d6823a 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -2699,6 +2699,7 @@ struct tg3 {
2699 struct net_device *dev; 2699 struct net_device *dev;
2700 struct pci_dev *pdev; 2700 struct pci_dev *pdev;
2701 2701
2702 u32 coal_now;
2702 u32 msg_enable; 2703 u32 msg_enable;
2703 2704
2704 /* begin "tx thread" cacheline section */ 2705 /* begin "tx thread" cacheline section */