3bbe9ea9cb5418e310fcca16b987725dab2e8925
[openwrt.git] / target / linux / generic / patches-3.18 / 077-05-bgmac-leave-interrupts-disabled-as-long-as-there-is-.patch
1 From: Felix Fietkau <nbd@openwrt.org>
2 Date: Sun, 12 Apr 2015 10:08:04 +0200
3 Subject: [PATCH] bgmac: leave interrupts disabled as long as there is work
4  to do
5
6 Always poll rx and tx during NAPI poll instead of relying on the status
7 of the first interrupt. This prevents bgmac_poll from leaving unfinished
8 work around until the next IRQ.
9 In my tests this makes bridging/routing throughput under heavy load more
10 stable and ensures that no new IRQs arrive as long as bgmac_poll uses up
11 the entire budget.
12
13 Signed-off-by: Felix Fietkau <nbd@openwrt.org>
14 ---
15
16 --- a/drivers/net/ethernet/broadcom/bgmac.c
17 +++ b/drivers/net/ethernet/broadcom/bgmac.c
18 @@ -1109,8 +1109,6 @@ static void bgmac_chip_reset(struct bgma
19         bgmac_phy_init(bgmac);
20  
21         netdev_reset_queue(bgmac->net_dev);
22 -
23 -       bgmac->int_status = 0;
24  }
25  
26  static void bgmac_chip_intrs_on(struct bgmac *bgmac)
27 @@ -1225,14 +1223,13 @@ static irqreturn_t bgmac_interrupt(int i
28         if (!int_status)
29                 return IRQ_NONE;
30  
31 -       /* Ack */
32 -       bgmac_write(bgmac, BGMAC_INT_STATUS, int_status);
33 +       int_status &= ~(BGMAC_IS_TX0 | BGMAC_IS_RX);
34 +       if (int_status)
35 +               bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", int_status);
36  
37         /* Disable new interrupts until handling existing ones */
38         bgmac_chip_intrs_off(bgmac);
39  
40 -       bgmac->int_status = int_status;
41 -
42         napi_schedule(&bgmac->napi);
43  
44         return IRQ_HANDLED;
45 @@ -1241,25 +1238,17 @@ static irqreturn_t bgmac_interrupt(int i
46  static int bgmac_poll(struct napi_struct *napi, int weight)
47  {
48         struct bgmac *bgmac = container_of(napi, struct bgmac, napi);
49 -       struct bgmac_dma_ring *ring;
50         int handled = 0;
51  
52 -       if (bgmac->int_status & BGMAC_IS_TX0) {
53 -               ring = &bgmac->tx_ring[0];
54 -               bgmac_dma_tx_free(bgmac, ring);
55 -               bgmac->int_status &= ~BGMAC_IS_TX0;
56 -       }
57 +       /* Ack */
58 +       bgmac_write(bgmac, BGMAC_INT_STATUS, ~0);
59  
60 -       if (bgmac->int_status & BGMAC_IS_RX) {
61 -               ring = &bgmac->rx_ring[0];
62 -               handled += bgmac_dma_rx_read(bgmac, ring, weight);
63 -               bgmac->int_status &= ~BGMAC_IS_RX;
64 -       }
65 +       bgmac_dma_tx_free(bgmac, &bgmac->tx_ring[0]);
66 +       handled += bgmac_dma_rx_read(bgmac, &bgmac->rx_ring[0], weight);
67  
68 -       if (bgmac->int_status) {
69 -               bgmac_err(bgmac, "Unknown IRQs: 0x%08X\n", bgmac->int_status);
70 -               bgmac->int_status = 0;
71 -       }
72 +       /* Poll again if more events arrived in the meantime */
73 +       if (bgmac_read(bgmac, BGMAC_INT_STATUS) & (BGMAC_IS_TX0 | BGMAC_IS_RX))
74 +               return handled;
75  
76         if (handled < weight) {
77                 napi_complete(napi);
78 --- a/drivers/net/ethernet/broadcom/bgmac.h
79 +++ b/drivers/net/ethernet/broadcom/bgmac.h
80 @@ -452,7 +452,6 @@ struct bgmac {
81  
82         /* Int */
83         u32 int_mask;
84 -       u32 int_status;
85  
86         /* Current MAC state */
87         int mac_speed;