aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/rt2x00/013-rt2x00-Work-around-a-firmware-bug-with-shared-keys.patch
diff options
context:
space:
mode:
authorDaniel Golle <daniel@makrotopia.org>2019-02-13 19:47:18 +0100
committerDaniel Golle <daniel@makrotopia.org>2019-02-19 09:05:34 +0100
commitd4c999bb891725b71ae38416cc6d5cfa99938ae4 (patch)
tree092236b7f1a2b7c2de42af33619b290c3ea088ec /package/kernel/mac80211/patches/rt2x00/013-rt2x00-Work-around-a-firmware-bug-with-shared-keys.patch
parent331963717bf4781ead1ff03b56de2802b9e05164 (diff)
downloadupstream-d4c999bb891725b71ae38416cc6d5cfa99938ae4.tar.gz
upstream-d4c999bb891725b71ae38416cc6d5cfa99938ae4.tar.bz2
upstream-d4c999bb891725b71ae38416cc6d5cfa99938ae4.zip
mac80211: rt2x00: backport accepted and pending patches from upstream
backport from wireless-drivers-next, replacing some existing patches in our tree (marked with '=' are those which were already present): f483039cf51a rt2x00: use simple_read_from_buffer() =5c656c71b1bf rt2800: move usb specific txdone/txstatus routines to rt2800lib =0b0d556e0ebb rt2800mmio: use txdone/txstatus routines from lib =5022efb50f62 rt2x00: do not check for txstatus timeout every time on tasklet =adf26a356f13 rt2x00: use different txstatus timeouts when flushing =0240564430c0 rt2800: flush and txstatus rework for rt2800mmio 6eba8fd22352 rt2x00: rt2400pci: mark expected switch fall-through 10bb92217747 rt2x00: rt2500pci: mark expected switch fall-through 916e6bbcfcff rt2x00: rt2800lib: mark expected switch fall-throughs 641dd8068ecb rt2x00: rt61pci: mark expected switch fall-through 750afb08ca71 cross-tree: phase out dma_zalloc_coherent() =c2e28ef7711f rt2x00: reduce tx power to nominal level on RT6352 a4296994eb80 rt2x00: Work around a firmware bug with shared keys 2587791d5758 rt2x00: no need to check return value of debugfs_create functions pending on linux-wireless: rt2x00: remove unneeded check rt2x00: remove confusing AGC register rt2800: enable TX_PIN_CFG_LNA_PE_ bits per band rt2800: enable TX_PIN_CFG_RFRX_EN only for MT7620 rt2800: comment and simplify AGC init for RT6352 rt2x00: do not print error when queue is full rt2800: partially restore old mmio txstatus behaviour rt2800: new flush implementation for SoC devices rt2800: move txstatus pending routine rt2800mmio: fetch tx status changes rt2800mmio: use timer and work for handling tx statuses timeouts rt2x00: remove last_nostatus_check rt2x00: remove not used entry field rt2x00mmio: remove legacy comment While at it also rename some existing patches now that there are separate folders with patches for each driver to make things a bit nicer to handle. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Diffstat (limited to 'package/kernel/mac80211/patches/rt2x00/013-rt2x00-Work-around-a-firmware-bug-with-shared-keys.patch')
-rw-r--r--package/kernel/mac80211/patches/rt2x00/013-rt2x00-Work-around-a-firmware-bug-with-shared-keys.patch143
1 files changed, 143 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/rt2x00/013-rt2x00-Work-around-a-firmware-bug-with-shared-keys.patch b/package/kernel/mac80211/patches/rt2x00/013-rt2x00-Work-around-a-firmware-bug-with-shared-keys.patch
new file mode 100644
index 0000000000..dc884c17d2
--- /dev/null
+++ b/package/kernel/mac80211/patches/rt2x00/013-rt2x00-Work-around-a-firmware-bug-with-shared-keys.patch
@@ -0,0 +1,143 @@
+From a4296994eb8061ee3455721a296c387c639bf635 Mon Sep 17 00:00:00 2001
+From: Bernd Edlinger <bernd.edlinger@hotmail.de>
+Date: Tue, 15 Jan 2019 14:01:29 +0000
+Subject: [PATCH 13/28] rt2x00: Work around a firmware bug with shared keys
+
+Apparently the rt2x61 firmware fails temporarily to decode
+broadcast packets if the shared keys are not assigned
+in the "correct" sequence. At the same time unicast
+packets work fine, since they are encrypted with the
+pairwise key.
+
+At least with WPA2 CCMP mode the shared keys are
+set in the following sequence: keyidx=1, 2, 1, 2.
+After a while only keyidx 2 gets decrypted, and
+keyidx 1 is ignored, probably because there is never
+a keyidx 3.
+
+Symptoms are arping -b works for 10 minutes, since
+keyidx=2 is used for broadcast, and then it stops
+working for 10 minutes, because keyidx=1 is used.
+That failure mode repeats forever.
+
+Note, the firmware does not even know which keyidx
+corresponds to which hw_key_idx so the firmware is
+trying to be smarter than the driver, which is bound
+to fail.
+
+As workaround the function rt61pci_config_shared_key
+requests software decryption of the shared keys,
+by returning EOPNOTSUPP. However, pairwise keys are
+still handled by hardware which works just fine.
+
+Signed-off-by: Bernd Edlinger <bernd.edlinger@hotmail.de>
+Acked-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/ralink/rt2x00/rt61pci.c | 93 +-------------------
+ 1 file changed, 4 insertions(+), 89 deletions(-)
+
+--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c
+@@ -321,97 +321,12 @@ static int rt61pci_config_shared_key(str
+ struct rt2x00lib_crypto *crypto,
+ struct ieee80211_key_conf *key)
+ {
+- struct hw_key_entry key_entry;
+- struct rt2x00_field32 field;
+- u32 mask;
+- u32 reg;
+-
+- if (crypto->cmd == SET_KEY) {
+- /*
+- * rt2x00lib can't determine the correct free
+- * key_idx for shared keys. We have 1 register
+- * with key valid bits. The goal is simple, read
+- * the register, if that is full we have no slots
+- * left.
+- * Note that each BSS is allowed to have up to 4
+- * shared keys, so put a mask over the allowed
+- * entries.
+- */
+- mask = (0xf << crypto->bssidx);
+-
+- reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR0);
+- reg &= mask;
+-
+- if (reg && reg == mask)
+- return -ENOSPC;
+-
+- key->hw_key_idx += reg ? ffz(reg) : 0;
+-
+- /*
+- * Upload key to hardware
+- */
+- memcpy(key_entry.key, crypto->key,
+- sizeof(key_entry.key));
+- memcpy(key_entry.tx_mic, crypto->tx_mic,
+- sizeof(key_entry.tx_mic));
+- memcpy(key_entry.rx_mic, crypto->rx_mic,
+- sizeof(key_entry.rx_mic));
+-
+- reg = SHARED_KEY_ENTRY(key->hw_key_idx);
+- rt2x00mmio_register_multiwrite(rt2x00dev, reg,
+- &key_entry, sizeof(key_entry));
+-
+- /*
+- * The cipher types are stored over 2 registers.
+- * bssidx 0 and 1 keys are stored in SEC_CSR1 and
+- * bssidx 1 and 2 keys are stored in SEC_CSR5.
+- * Using the correct defines correctly will cause overhead,
+- * so just calculate the correct offset.
+- */
+- if (key->hw_key_idx < 8) {
+- field.bit_offset = (3 * key->hw_key_idx);
+- field.bit_mask = 0x7 << field.bit_offset;
+-
+- reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR1);
+- rt2x00_set_field32(&reg, field, crypto->cipher);
+- rt2x00mmio_register_write(rt2x00dev, SEC_CSR1, reg);
+- } else {
+- field.bit_offset = (3 * (key->hw_key_idx - 8));
+- field.bit_mask = 0x7 << field.bit_offset;
+-
+- reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR5);
+- rt2x00_set_field32(&reg, field, crypto->cipher);
+- rt2x00mmio_register_write(rt2x00dev, SEC_CSR5, reg);
+- }
+-
+- /*
+- * The driver does not support the IV/EIV generation
+- * in hardware. However it doesn't support the IV/EIV
+- * inside the ieee80211 frame either, but requires it
+- * to be provided separately for the descriptor.
+- * rt2x00lib will cut the IV/EIV data out of all frames
+- * given to us by mac80211, but we must tell mac80211
+- * to generate the IV/EIV data.
+- */
+- key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+- }
+-
+ /*
+- * SEC_CSR0 contains only single-bit fields to indicate
+- * a particular key is valid. Because using the FIELD32()
+- * defines directly will cause a lot of overhead, we use
+- * a calculation to determine the correct bit directly.
++ * Let the software handle the shared keys,
++ * since the hardware decryption does not work reliably,
++ * because the firmware does not know the key's keyidx.
+ */
+- mask = 1 << key->hw_key_idx;
+-
+- reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR0);
+- if (crypto->cmd == SET_KEY)
+- reg |= mask;
+- else if (crypto->cmd == DISABLE_KEY)
+- reg &= ~mask;
+- rt2x00mmio_register_write(rt2x00dev, SEC_CSR0, reg);
+-
+- return 0;
++ return -EOPNOTSUPP;
+ }
+
+ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev,