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>
		
			
				
	
	
		
			144 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			144 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| 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(®, 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(®, 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,
 |