Commit faa72684 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau

mt76: mt7615: run key configuration in mt7615_set_key for usb/sdio devices

Since rate configuration is run holding dev mutex, we can run key
configuration in mt7615_set_key for usb/sdio devices avoiding to
schedule the workqueue
Tested-by: default avatarTested-by: YN Chen <yn.chen@mediatek.com>
Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 930e0ead
...@@ -1030,32 +1030,32 @@ void mt7615_mac_set_rates(struct mt7615_phy *phy, struct mt7615_sta *sta, ...@@ -1030,32 +1030,32 @@ void mt7615_mac_set_rates(struct mt7615_phy *phy, struct mt7615_sta *sta,
} }
EXPORT_SYMBOL_GPL(mt7615_mac_set_rates); EXPORT_SYMBOL_GPL(mt7615_mac_set_rates);
int mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, static int
struct mt76_wcid *wcid, mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
u8 *key, u8 keylen, struct ieee80211_key_conf *key,
enum mt7615_cipher_type cipher, enum mt7615_cipher_type cipher,
enum set_key_cmd cmd) enum set_key_cmd cmd)
{ {
u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx) + 30 * 4; u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx) + 30 * 4;
u8 data[32] = {}; u8 data[32] = {};
if (keylen > sizeof(data)) if (key->keylen > sizeof(data))
return -EINVAL; return -EINVAL;
mt76_rr_copy(dev, addr, data, sizeof(data)); mt76_rr_copy(dev, addr, data, sizeof(data));
if (cmd == SET_KEY) { if (cmd == SET_KEY) {
if (cipher == MT_CIPHER_TKIP) { if (cipher == MT_CIPHER_TKIP) {
/* Rx/Tx MIC keys are swapped */ /* Rx/Tx MIC keys are swapped */
memcpy(data, key, 16); memcpy(data, key->key, 16);
memcpy(data + 16, key + 24, 8); memcpy(data + 16, key->key + 24, 8);
memcpy(data + 24, key + 16, 8); memcpy(data + 24, key->key + 16, 8);
} else { } else {
if (cipher != MT_CIPHER_BIP_CMAC_128 && wcid->cipher) if (cipher != MT_CIPHER_BIP_CMAC_128 && wcid->cipher)
memmove(data + 16, data, 16); memmove(data + 16, data, 16);
if (cipher != MT_CIPHER_BIP_CMAC_128 || !wcid->cipher) if (cipher != MT_CIPHER_BIP_CMAC_128 || !wcid->cipher)
memcpy(data, key, keylen); memcpy(data, key->key, key->keylen);
else if (cipher == MT_CIPHER_BIP_CMAC_128) else if (cipher == MT_CIPHER_BIP_CMAC_128)
memcpy(data + 16, key, 16); memcpy(data + 16, key->key, 16);
} }
} else { } else {
if (wcid->cipher & ~BIT(cipher)) { if (wcid->cipher & ~BIT(cipher)) {
...@@ -1070,12 +1070,11 @@ int mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, ...@@ -1070,12 +1070,11 @@ int mt7615_mac_wtbl_update_key(struct mt7615_dev *dev,
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(mt7615_mac_wtbl_update_key);
int mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev, static int
struct mt76_wcid *wcid, mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev, struct mt76_wcid *wcid,
enum mt7615_cipher_type cipher, enum mt7615_cipher_type cipher,
int keyidx, enum set_key_cmd cmd) int keyidx, enum set_key_cmd cmd)
{ {
u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx), w0, w1; u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx), w0, w1;
...@@ -1107,12 +1106,11 @@ int mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev, ...@@ -1107,12 +1106,11 @@ int mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev,
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(mt7615_mac_wtbl_update_pk);
void mt7615_mac_wtbl_update_cipher(struct mt7615_dev *dev, static void
struct mt76_wcid *wcid, mt7615_mac_wtbl_update_cipher(struct mt7615_dev *dev, struct mt76_wcid *wcid,
enum mt7615_cipher_type cipher, enum mt7615_cipher_type cipher,
enum set_key_cmd cmd) enum set_key_cmd cmd)
{ {
u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx); u32 addr = mt7615_mac_wtbl_addr(dev, wcid->idx);
...@@ -1130,12 +1128,11 @@ void mt7615_mac_wtbl_update_cipher(struct mt7615_dev *dev, ...@@ -1130,12 +1128,11 @@ void mt7615_mac_wtbl_update_cipher(struct mt7615_dev *dev,
mt76_clear(dev, addr + 2 * 4, MT_WTBL_W2_KEY_TYPE); mt76_clear(dev, addr + 2 * 4, MT_WTBL_W2_KEY_TYPE);
} }
} }
EXPORT_SYMBOL_GPL(mt7615_mac_wtbl_update_cipher);
int mt7615_mac_wtbl_set_key(struct mt7615_dev *dev, int __mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
struct mt76_wcid *wcid, struct mt76_wcid *wcid,
struct ieee80211_key_conf *key, struct ieee80211_key_conf *key,
enum set_key_cmd cmd) enum set_key_cmd cmd)
{ {
enum mt7615_cipher_type cipher; enum mt7615_cipher_type cipher;
int err; int err;
...@@ -1144,25 +1141,32 @@ int mt7615_mac_wtbl_set_key(struct mt7615_dev *dev, ...@@ -1144,25 +1141,32 @@ int mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
if (cipher == MT_CIPHER_NONE) if (cipher == MT_CIPHER_NONE)
return -EOPNOTSUPP; return -EOPNOTSUPP;
spin_lock_bh(&dev->mt76.lock);
mt7615_mac_wtbl_update_cipher(dev, wcid, cipher, cmd); mt7615_mac_wtbl_update_cipher(dev, wcid, cipher, cmd);
err = mt7615_mac_wtbl_update_key(dev, wcid, key->key, key->keylen, err = mt7615_mac_wtbl_update_key(dev, wcid, key, cipher, cmd);
cipher, cmd);
if (err < 0) if (err < 0)
goto out; return err;
err = mt7615_mac_wtbl_update_pk(dev, wcid, cipher, key->keyidx, err = mt7615_mac_wtbl_update_pk(dev, wcid, cipher, key->keyidx, cmd);
cmd);
if (err < 0) if (err < 0)
goto out; return err;
if (cmd == SET_KEY) if (cmd == SET_KEY)
wcid->cipher |= BIT(cipher); wcid->cipher |= BIT(cipher);
else else
wcid->cipher &= ~BIT(cipher); wcid->cipher &= ~BIT(cipher);
out: return 0;
}
int mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
struct mt76_wcid *wcid,
struct ieee80211_key_conf *key,
enum set_key_cmd cmd)
{
int err;
spin_lock_bh(&dev->mt76.lock);
err = __mt7615_mac_wtbl_set_key(dev, wcid, key, cmd);
spin_unlock_bh(&dev->mt76.lock); spin_unlock_bh(&dev->mt76.lock);
return err; return err;
......
...@@ -320,39 +320,6 @@ int mt7615_set_channel(struct mt7615_phy *phy) ...@@ -320,39 +320,6 @@ int mt7615_set_channel(struct mt7615_phy *phy)
return ret; return ret;
} }
static int
mt7615_queue_key_update(struct mt7615_dev *dev, enum set_key_cmd cmd,
struct mt7615_sta *msta,
struct ieee80211_key_conf *key)
{
struct mt7615_wtbl_desc *wd;
wd = kzalloc(sizeof(*wd), GFP_KERNEL);
if (!wd)
return -ENOMEM;
wd->type = MT7615_WTBL_KEY_DESC;
wd->sta = msta;
wd->key.key = kmemdup(key->key, key->keylen, GFP_KERNEL);
if (!wd->key.key) {
kfree(wd);
return -ENOMEM;
}
wd->key.cipher = key->cipher;
wd->key.keyidx = key->keyidx;
wd->key.keylen = key->keylen;
wd->key.cmd = cmd;
spin_lock_bh(&dev->mt76.lock);
list_add_tail(&wd->node, &dev->wd_head);
spin_unlock_bh(&dev->mt76.lock);
queue_work(dev->mt76.wq, &dev->wtbl_work);
return 0;
}
static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_vif *vif, struct ieee80211_sta *sta, struct ieee80211_vif *vif, struct ieee80211_sta *sta,
struct ieee80211_key_conf *key) struct ieee80211_key_conf *key)
...@@ -406,7 +373,7 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ...@@ -406,7 +373,7 @@ static int mt7615_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (mt76_is_mmio(&dev->mt76)) if (mt76_is_mmio(&dev->mt76))
err = mt7615_mac_wtbl_set_key(dev, wcid, key, cmd); err = mt7615_mac_wtbl_set_key(dev, wcid, key, cmd);
else else
err = mt7615_queue_key_update(dev, cmd, msta, key); err = __mt7615_mac_wtbl_set_key(dev, wcid, key, cmd);
mt7615_mutex_release(dev); mt7615_mutex_release(dev);
......
...@@ -108,15 +108,6 @@ struct mt7615_rate_desc { ...@@ -108,15 +108,6 @@ struct mt7615_rate_desc {
enum mt7615_wtbl_desc_type { enum mt7615_wtbl_desc_type {
MT7615_WTBL_RATE_DESC, MT7615_WTBL_RATE_DESC,
MT7615_WTBL_KEY_DESC
};
struct mt7615_key_desc {
enum set_key_cmd cmd;
u32 cipher;
s8 keyidx;
u8 keylen;
u8 *key;
}; };
struct mt7615_wtbl_desc { struct mt7615_wtbl_desc {
...@@ -127,7 +118,6 @@ struct mt7615_wtbl_desc { ...@@ -127,7 +118,6 @@ struct mt7615_wtbl_desc {
union { union {
struct mt7615_rate_desc rate; struct mt7615_rate_desc rate;
struct mt7615_key_desc key;
}; };
}; };
...@@ -571,22 +561,13 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi, ...@@ -571,22 +561,13 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
struct ieee80211_sta *sta, int pid, struct ieee80211_sta *sta, int pid,
struct ieee80211_key_conf *key, bool beacon); struct ieee80211_key_conf *key, bool beacon);
void mt7615_mac_set_timing(struct mt7615_phy *phy); void mt7615_mac_set_timing(struct mt7615_phy *phy);
int __mt7615_mac_wtbl_set_key(struct mt7615_dev *dev,
struct mt76_wcid *wcid,
struct ieee80211_key_conf *key,
enum set_key_cmd cmd);
int mt7615_mac_wtbl_set_key(struct mt7615_dev *dev, struct mt76_wcid *wcid, int mt7615_mac_wtbl_set_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
struct ieee80211_key_conf *key, struct ieee80211_key_conf *key,
enum set_key_cmd cmd); enum set_key_cmd cmd);
int mt7615_mac_wtbl_update_pk(struct mt7615_dev *dev,
struct mt76_wcid *wcid,
enum mt7615_cipher_type cipher,
int keyidx, enum set_key_cmd cmd);
void mt7615_mac_wtbl_update_cipher(struct mt7615_dev *dev,
struct mt76_wcid *wcid,
enum mt7615_cipher_type cipher,
enum set_key_cmd cmd);
int mt7615_mac_wtbl_update_key(struct mt7615_dev *dev,
struct mt76_wcid *wcid,
u8 *key, u8 keylen,
enum mt7615_cipher_type cipher,
enum set_key_cmd cmd);
void mt7615_mac_reset_work(struct work_struct *work); void mt7615_mac_reset_work(struct work_struct *work);
u32 mt7615_mac_get_sta_tid_sn(struct mt7615_dev *dev, int wcid, u8 tid); u32 mt7615_mac_get_sta_tid_sn(struct mt7615_dev *dev, int wcid, u8 tid);
......
...@@ -132,52 +132,6 @@ mt7663_usb_sdio_set_rates(struct mt7615_dev *dev, ...@@ -132,52 +132,6 @@ mt7663_usb_sdio_set_rates(struct mt7615_dev *dev,
return 0; return 0;
} }
static int
mt7663_usb_sdio_set_key(struct mt7615_dev *dev,
struct mt7615_wtbl_desc *wd)
{
struct mt7615_key_desc *key = &wd->key;
struct mt7615_sta *sta = wd->sta;
enum mt7615_cipher_type cipher;
struct mt76_wcid *wcid;
int err;
lockdep_assert_held(&dev->mt76.mutex);
if (!sta) {
err = -EINVAL;
goto out;
}
cipher = mt7615_mac_get_cipher(key->cipher);
if (cipher == MT_CIPHER_NONE) {
err = -EOPNOTSUPP;
goto out;
}
wcid = &wd->sta->wcid;
mt7615_mac_wtbl_update_cipher(dev, wcid, cipher, key->cmd);
err = mt7615_mac_wtbl_update_key(dev, wcid, key->key, key->keylen,
cipher, key->cmd);
if (err < 0)
goto out;
err = mt7615_mac_wtbl_update_pk(dev, wcid, cipher, key->keyidx,
key->cmd);
if (err < 0)
goto out;
if (key->cmd == SET_KEY)
wcid->cipher |= BIT(cipher);
else
wcid->cipher &= ~BIT(cipher);
out:
kfree(key->key);
return err;
}
void mt7663_usb_sdio_wtbl_work(struct work_struct *work) void mt7663_usb_sdio_wtbl_work(struct work_struct *work)
{ {
struct mt7615_wtbl_desc *wd, *wd_next; struct mt7615_wtbl_desc *wd, *wd_next;
...@@ -201,9 +155,6 @@ void mt7663_usb_sdio_wtbl_work(struct work_struct *work) ...@@ -201,9 +155,6 @@ void mt7663_usb_sdio_wtbl_work(struct work_struct *work)
case MT7615_WTBL_RATE_DESC: case MT7615_WTBL_RATE_DESC:
mt7663_usb_sdio_set_rates(dev, wd); mt7663_usb_sdio_set_rates(dev, wd);
break; break;
case MT7615_WTBL_KEY_DESC:
mt7663_usb_sdio_set_key(dev, wd);
break;
} }
mt7615_mutex_release(dev); mt7615_mutex_release(dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment