summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2500usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2500usb.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 002db646ae0..44205526013 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -347,6 +347,7 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,
{
u32 mask;
u16 reg;
+ enum cipher curr_cipher;
if (crypto->cmd == SET_KEY) {
/*
@@ -357,6 +358,7 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,
mask = TXRX_CSR0_KEY_ID.bit_mask;
rt2500usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
+ curr_cipher = rt2x00_get_field16(reg, TXRX_CSR0_ALGORITHM);
reg &= mask;
if (reg && reg == mask)
@@ -365,6 +367,14 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,
reg = rt2x00_get_field16(reg, TXRX_CSR0_KEY_ID);
key->hw_key_idx += reg ? ffz(reg) : 0;
+ /*
+ * Hardware requires that all keys use the same cipher
+ * (e.g. TKIP-only, AES-only, but not TKIP+AES).
+ * If this is not the first key, compare the cipher with the
+ * first one and fall back to SW crypto if not the same.
+ */
+ if (key->hw_key_idx > 0 && crypto->cipher != curr_cipher)
+ return -EOPNOTSUPP;
rt2500usb_register_multiwrite(rt2x00dev, reg,
crypto->key, sizeof(crypto->key));
@@ -1769,7 +1779,6 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
.link_stats = rt2500usb_link_stats,
.reset_tuner = rt2500usb_reset_tuner,
.write_tx_desc = rt2500usb_write_tx_desc,
- .write_tx_data = rt2x00usb_write_tx_data,
.write_beacon = rt2500usb_write_beacon,
.get_tx_data_len = rt2500usb_get_tx_data_len,
.kick_tx_queue = rt2x00usb_kick_tx_queue,