52314a79ae92818163d93d2e39bdbc8ed976a9f0
[librecmc/librecmc.git] /
1 From 91a5340db0526b7263bc8da14b120ea3129b5f28 Mon Sep 17 00:00:00 2001
2 From: Stanislaw Gruszka <sgruszka@redhat.com>
3 Date: Sat, 9 Feb 2019 12:08:31 +0100
4 X-Patchwork-Submitter: Stanislaw Gruszka <sgruszka@redhat.com>
5 X-Patchwork-Id: 10804437
6 X-Patchwork-Delegate: kvalo@adurom.com
7 Subject: [PATCH 21/28] rt2800: partially restore old mmio txstatus behaviour
8
9 Do not disable txstatus interrupt and add quota of processed tx statuses in
10 one tasklet. Quota is needed to allow to fed device with new frames during
11 processing of tx statuses.
12
13 Patch fixes about 15% performance degradation on some scenarios coused by
14 0b0d556e0ebb ("rt2800mmio: use txdone/txstatus routines from lib").
15
16 Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
17 ---
18  .../net/wireless/ralink/rt2x00/rt2800lib.c    |  4 +--
19  .../net/wireless/ralink/rt2x00/rt2800lib.h    |  2 +-
20  .../net/wireless/ralink/rt2x00/rt2800mmio.c   | 30 +++++--------------
21  .../net/wireless/ralink/rt2x00/rt2800usb.c    |  2 +-
22  4 files changed, 12 insertions(+), 26 deletions(-)
23
24 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
25 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
26 @@ -1100,7 +1100,7 @@ void rt2800_txdone_entry(struct queue_en
27  }
28  EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
29  
30 -void rt2800_txdone(struct rt2x00_dev *rt2x00dev)
31 +void rt2800_txdone(struct rt2x00_dev *rt2x00dev, unsigned int quota)
32  {
33         struct data_queue *queue;
34         struct queue_entry *entry;
35 @@ -1108,7 +1108,7 @@ void rt2800_txdone(struct rt2x00_dev *rt
36         u8 qid;
37         bool match;
38  
39 -       while (kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
40 +       while (quota-- > 0 && kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
41                 /*
42                  * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is
43                  * guaranteed to be one of the TX QIDs .
44 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
45 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
46 @@ -195,7 +195,7 @@ void rt2800_process_rxwi(struct queue_en
47  
48  void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi,
49                          bool match);
50 -void rt2800_txdone(struct rt2x00_dev *rt2x00dev);
51 +void rt2800_txdone(struct rt2x00_dev *rt2x00dev, unsigned int quota);
52  void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev);
53  bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev);
54  
55 --- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
56 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
57 @@ -255,20 +255,6 @@ void rt2800mmio_autowake_tasklet(unsigne
58  }
59  EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet);
60  
61 -static void rt2800mmio_txdone(struct rt2x00_dev *rt2x00dev)
62 -{
63 -       bool timeout = false;
64 -
65 -       while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) ||
66 -              (timeout = rt2800_txstatus_timeout(rt2x00dev))) {
67 -
68 -               rt2800_txdone(rt2x00dev);
69 -
70 -               if (timeout)
71 -                       rt2800_txdone_nostatus(rt2x00dev);
72 -       }
73 -}
74 -
75  static bool rt2800mmio_fetch_txstatus(struct rt2x00_dev *rt2x00dev)
76  {
77         u32 status;
78 @@ -305,14 +291,11 @@ void rt2800mmio_txstatus_tasklet(unsigne
79  {
80         struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
81  
82 -       do {
83 -               rt2800mmio_txdone(rt2x00dev);
84 +       rt2800_txdone(rt2x00dev, 16);
85  
86 -       } while (rt2800mmio_fetch_txstatus(rt2x00dev));
87 +       if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo))
88 +               tasklet_schedule(&rt2x00dev->txstatus_tasklet);
89  
90 -       if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
91 -               rt2800mmio_enable_interrupt(rt2x00dev,
92 -                                           INT_SOURCE_CSR_TX_FIFO_STATUS);
93  }
94  EXPORT_SYMBOL_GPL(rt2800mmio_txstatus_tasklet);
95  
96 @@ -339,8 +322,10 @@ irqreturn_t rt2800mmio_interrupt(int irq
97         mask = ~reg;
98  
99         if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) {
100 +               rt2x00_set_field32(&mask, INT_MASK_CSR_TX_FIFO_STATUS, 1);
101                 rt2800mmio_fetch_txstatus(rt2x00dev);
102 -               tasklet_schedule(&rt2x00dev->txstatus_tasklet);
103 +               if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo))
104 +                       tasklet_schedule(&rt2x00dev->txstatus_tasklet);
105         }
106  
107         if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT))
108 @@ -500,7 +485,8 @@ void rt2800mmio_flush_queue(struct data_
109                  */
110                 if (tx_queue) {
111                         tasklet_disable(&rt2x00dev->txstatus_tasklet);
112 -                       rt2800mmio_txdone(rt2x00dev);
113 +                       rt2800_txdone(rt2x00dev, UINT_MAX);
114 +                       rt2800_txdone_nostatus(rt2x00dev);
115                         tasklet_enable(&rt2x00dev->txstatus_tasklet);
116                 }
117  
118 --- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
119 +++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
120 @@ -480,7 +480,7 @@ static void rt2800usb_work_txdone(struct
121         while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) ||
122                rt2800_txstatus_timeout(rt2x00dev)) {
123  
124 -               rt2800_txdone(rt2x00dev);
125 +               rt2800_txdone(rt2x00dev, UINT_MAX);
126  
127                 rt2800_txdone_nostatus(rt2x00dev);
128