mac80211: rt2x00: backport accepted and pending patches from upstream
[oweals/openwrt.git] / package / kernel / mac80211 / patches / rt2x00 / 013-rt2x00-Work-around-a-firmware-bug-with-shared-keys.patch
1 From a4296994eb8061ee3455721a296c387c639bf635 Mon Sep 17 00:00:00 2001
2 From: Bernd Edlinger <bernd.edlinger@hotmail.de>
3 Date: Tue, 15 Jan 2019 14:01:29 +0000
4 Subject: [PATCH 13/28] rt2x00: Work around a firmware bug with shared keys
5
6 Apparently the rt2x61 firmware fails temporarily to decode
7 broadcast packets if the shared keys are not assigned
8 in the "correct" sequence. At the same time unicast
9 packets work fine, since they are encrypted with the
10 pairwise key.
11
12 At least with WPA2 CCMP mode the shared keys are
13 set in the following sequence: keyidx=1, 2, 1, 2.
14 After a while only keyidx 2 gets decrypted, and
15 keyidx 1 is ignored, probably because there is never
16 a keyidx 3.
17
18 Symptoms are arping -b works for 10 minutes, since
19 keyidx=2 is used for broadcast, and then it stops
20 working for 10 minutes, because keyidx=1 is used.
21 That failure mode repeats forever.
22
23 Note, the firmware does not even know which keyidx
24 corresponds to which hw_key_idx so the firmware is
25 trying to be smarter than the driver, which is bound
26 to fail.
27
28 As workaround the function rt61pci_config_shared_key
29 requests software decryption of the shared keys,
30 by returning EOPNOTSUPP. However, pairwise keys are
31 still handled by hardware which works just fine.
32
33 Signed-off-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
34 Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
35 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
36 ---
37  drivers/net/wireless/ralink/rt2x00/rt61pci.c | 93 +-------------------
38  1 file changed, 4 insertions(+), 89 deletions(-)
39
40 --- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c
41 +++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
42 @@ -321,97 +321,12 @@ static int rt61pci_config_shared_key(str
43                                      struct rt2x00lib_crypto *crypto,
44                                      struct ieee80211_key_conf *key)
45  {
46 -       struct hw_key_entry key_entry;
47 -       struct rt2x00_field32 field;
48 -       u32 mask;
49 -       u32 reg;
50 -
51 -       if (crypto->cmd == SET_KEY) {
52 -               /*
53 -                * rt2x00lib can't determine the correct free
54 -                * key_idx for shared keys. We have 1 register
55 -                * with key valid bits. The goal is simple, read
56 -                * the register, if that is full we have no slots
57 -                * left.
58 -                * Note that each BSS is allowed to have up to 4
59 -                * shared keys, so put a mask over the allowed
60 -                * entries.
61 -                */
62 -               mask = (0xf << crypto->bssidx);
63 -
64 -               reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR0);
65 -               reg &= mask;
66 -
67 -               if (reg && reg == mask)
68 -                       return -ENOSPC;
69 -
70 -               key->hw_key_idx += reg ? ffz(reg) : 0;
71 -
72 -               /*
73 -                * Upload key to hardware
74 -                */
75 -               memcpy(key_entry.key, crypto->key,
76 -                      sizeof(key_entry.key));
77 -               memcpy(key_entry.tx_mic, crypto->tx_mic,
78 -                      sizeof(key_entry.tx_mic));
79 -               memcpy(key_entry.rx_mic, crypto->rx_mic,
80 -                      sizeof(key_entry.rx_mic));
81 -
82 -               reg = SHARED_KEY_ENTRY(key->hw_key_idx);
83 -               rt2x00mmio_register_multiwrite(rt2x00dev, reg,
84 -                                              &key_entry, sizeof(key_entry));
85 -
86 -               /*
87 -                * The cipher types are stored over 2 registers.
88 -                * bssidx 0 and 1 keys are stored in SEC_CSR1 and
89 -                * bssidx 1 and 2 keys are stored in SEC_CSR5.
90 -                * Using the correct defines correctly will cause overhead,
91 -                * so just calculate the correct offset.
92 -                */
93 -               if (key->hw_key_idx < 8) {
94 -                       field.bit_offset = (3 * key->hw_key_idx);
95 -                       field.bit_mask = 0x7 << field.bit_offset;
96 -
97 -                       reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR1);
98 -                       rt2x00_set_field32(&reg, field, crypto->cipher);
99 -                       rt2x00mmio_register_write(rt2x00dev, SEC_CSR1, reg);
100 -               } else {
101 -                       field.bit_offset = (3 * (key->hw_key_idx - 8));
102 -                       field.bit_mask = 0x7 << field.bit_offset;
103 -
104 -                       reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR5);
105 -                       rt2x00_set_field32(&reg, field, crypto->cipher);
106 -                       rt2x00mmio_register_write(rt2x00dev, SEC_CSR5, reg);
107 -               }
108 -
109 -               /*
110 -                * The driver does not support the IV/EIV generation
111 -                * in hardware. However it doesn't support the IV/EIV
112 -                * inside the ieee80211 frame either, but requires it
113 -                * to be provided separately for the descriptor.
114 -                * rt2x00lib will cut the IV/EIV data out of all frames
115 -                * given to us by mac80211, but we must tell mac80211
116 -                * to generate the IV/EIV data.
117 -                */
118 -               key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
119 -       }
120 -
121         /*
122 -        * SEC_CSR0 contains only single-bit fields to indicate
123 -        * a particular key is valid. Because using the FIELD32()
124 -        * defines directly will cause a lot of overhead, we use
125 -        * a calculation to determine the correct bit directly.
126 +        * Let the software handle the shared keys,
127 +        * since the hardware decryption does not work reliably,
128 +        * because the firmware does not know the key's keyidx.
129          */
130 -       mask = 1 << key->hw_key_idx;
131 -
132 -       reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR0);
133 -       if (crypto->cmd == SET_KEY)
134 -               reg |= mask;
135 -       else if (crypto->cmd == DISABLE_KEY)
136 -               reg &= ~mask;
137 -       rt2x00mmio_register_write(rt2x00dev, SEC_CSR0, reg);
138 -
139 -       return 0;
140 +       return -EOPNOTSUPP;
141  }
142  
143  static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev,