treewide: replace nbd@openwrt.org with nbd@nbd.name
[openwrt/staging/mkresin.git] / target / linux / generic / patches-3.18 / 077-05-bgmac-leave-interrupts-disabled-as-long-as-there-is-.patch
1 From: Felix Fietkau <nbd@nbd.name>
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@nbd.name>
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;