wil6210: support rx key setting for all TIDs
According to the spec the PN should be calculated per TID. In the current implementation, the PN and key_set were set only for TID 0, therefore only traffic for TID 0 was supported. In order to support all TIDs, the key_set and PN should be set for all the TIDs. Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
f1b7764f86
commit
74b6ac586d
|
@ -760,14 +760,11 @@ static enum wmi_key_usage wil_detect_key_usage(struct wil6210_priv *wil,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static struct wil_tid_crypto_rx_single *
|
||||
wil_find_crypto_ctx(struct wil6210_priv *wil, u8 key_index,
|
||||
enum wmi_key_usage key_usage, const u8 *mac_addr)
|
||||
static struct wil_sta_info *
|
||||
wil_find_sta_by_key_usage(struct wil6210_priv *wil,
|
||||
enum wmi_key_usage key_usage, const u8 *mac_addr)
|
||||
{
|
||||
int cid = -EINVAL;
|
||||
int tid = 0;
|
||||
struct wil_sta_info *s;
|
||||
struct wil_tid_crypto_rx *c;
|
||||
|
||||
if (key_usage == WMI_KEY_USE_TX_GROUP)
|
||||
return NULL; /* not needed */
|
||||
|
@ -778,18 +775,72 @@ wil_find_crypto_ctx(struct wil6210_priv *wil, u8 key_index,
|
|||
else if (key_usage == WMI_KEY_USE_RX_GROUP)
|
||||
cid = wil_find_cid_by_idx(wil, 0);
|
||||
if (cid < 0) {
|
||||
wil_err(wil, "No CID for %pM %s[%d]\n", mac_addr,
|
||||
key_usage_str[key_usage], key_index);
|
||||
wil_err(wil, "No CID for %pM %s\n", mac_addr,
|
||||
key_usage_str[key_usage]);
|
||||
return ERR_PTR(cid);
|
||||
}
|
||||
|
||||
s = &wil->sta[cid];
|
||||
if (key_usage == WMI_KEY_USE_PAIRWISE)
|
||||
c = &s->tid_crypto_rx[tid];
|
||||
else
|
||||
c = &s->group_crypto_rx;
|
||||
return &wil->sta[cid];
|
||||
}
|
||||
|
||||
return &c->key_id[key_index];
|
||||
static void wil_set_crypto_rx(u8 key_index, enum wmi_key_usage key_usage,
|
||||
struct wil_sta_info *cs,
|
||||
struct key_params *params)
|
||||
{
|
||||
struct wil_tid_crypto_rx_single *cc;
|
||||
int tid;
|
||||
|
||||
if (!cs)
|
||||
return;
|
||||
|
||||
switch (key_usage) {
|
||||
case WMI_KEY_USE_PAIRWISE:
|
||||
for (tid = 0; tid < WIL_STA_TID_NUM; tid++) {
|
||||
cc = &cs->tid_crypto_rx[tid].key_id[key_index];
|
||||
if (params->seq)
|
||||
memcpy(cc->pn, params->seq,
|
||||
IEEE80211_GCMP_PN_LEN);
|
||||
else
|
||||
memset(cc->pn, 0, IEEE80211_GCMP_PN_LEN);
|
||||
cc->key_set = true;
|
||||
}
|
||||
break;
|
||||
case WMI_KEY_USE_RX_GROUP:
|
||||
cc = &cs->group_crypto_rx.key_id[key_index];
|
||||
if (params->seq)
|
||||
memcpy(cc->pn, params->seq, IEEE80211_GCMP_PN_LEN);
|
||||
else
|
||||
memset(cc->pn, 0, IEEE80211_GCMP_PN_LEN);
|
||||
cc->key_set = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void wil_del_rx_key(u8 key_index, enum wmi_key_usage key_usage,
|
||||
struct wil_sta_info *cs)
|
||||
{
|
||||
struct wil_tid_crypto_rx_single *cc;
|
||||
int tid;
|
||||
|
||||
if (!cs)
|
||||
return;
|
||||
|
||||
switch (key_usage) {
|
||||
case WMI_KEY_USE_PAIRWISE:
|
||||
for (tid = 0; tid < WIL_STA_TID_NUM; tid++) {
|
||||
cc = &cs->tid_crypto_rx[tid].key_id[key_index];
|
||||
cc->key_set = false;
|
||||
}
|
||||
break;
|
||||
case WMI_KEY_USE_RX_GROUP:
|
||||
cc = &cs->group_crypto_rx.key_id[key_index];
|
||||
cc->key_set = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int wil_cfg80211_add_key(struct wiphy *wiphy,
|
||||
|
@ -801,24 +852,26 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy,
|
|||
int rc;
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
enum wmi_key_usage key_usage = wil_detect_key_usage(wil, pairwise);
|
||||
struct wil_tid_crypto_rx_single *cc = wil_find_crypto_ctx(wil,
|
||||
key_index,
|
||||
key_usage,
|
||||
mac_addr);
|
||||
struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, key_usage,
|
||||
mac_addr);
|
||||
|
||||
if (!params) {
|
||||
wil_err(wil, "NULL params\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
wil_dbg_misc(wil, "%s(%pM %s[%d] PN %*phN)\n", __func__,
|
||||
mac_addr, key_usage_str[key_usage], key_index,
|
||||
params->seq_len, params->seq);
|
||||
|
||||
if (IS_ERR(cc)) {
|
||||
if (IS_ERR(cs)) {
|
||||
wil_err(wil, "Not connected, %s(%pM %s[%d] PN %*phN)\n",
|
||||
__func__, mac_addr, key_usage_str[key_usage], key_index,
|
||||
params->seq_len, params->seq);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cc)
|
||||
cc->key_set = false;
|
||||
wil_del_rx_key(key_index, key_usage, cs);
|
||||
|
||||
if (params->seq && params->seq_len != IEEE80211_GCMP_PN_LEN) {
|
||||
wil_err(wil,
|
||||
|
@ -831,13 +884,8 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy,
|
|||
|
||||
rc = wmi_add_cipher_key(wil, key_index, mac_addr, params->key_len,
|
||||
params->key, key_usage);
|
||||
if ((rc == 0) && cc) {
|
||||
if (params->seq)
|
||||
memcpy(cc->pn, params->seq, IEEE80211_GCMP_PN_LEN);
|
||||
else
|
||||
memset(cc->pn, 0, IEEE80211_GCMP_PN_LEN);
|
||||
cc->key_set = true;
|
||||
}
|
||||
if (!rc)
|
||||
wil_set_crypto_rx(key_index, key_usage, cs, params);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -849,20 +897,18 @@ static int wil_cfg80211_del_key(struct wiphy *wiphy,
|
|||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
enum wmi_key_usage key_usage = wil_detect_key_usage(wil, pairwise);
|
||||
struct wil_tid_crypto_rx_single *cc = wil_find_crypto_ctx(wil,
|
||||
key_index,
|
||||
key_usage,
|
||||
mac_addr);
|
||||
struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, key_usage,
|
||||
mac_addr);
|
||||
|
||||
wil_dbg_misc(wil, "%s(%pM %s[%d])\n", __func__, mac_addr,
|
||||
key_usage_str[key_usage], key_index);
|
||||
|
||||
if (IS_ERR(cc))
|
||||
if (IS_ERR(cs))
|
||||
wil_info(wil, "Not connected, %s(%pM %s[%d])\n", __func__,
|
||||
mac_addr, key_usage_str[key_usage], key_index);
|
||||
|
||||
if (!IS_ERR_OR_NULL(cc))
|
||||
cc->key_set = false;
|
||||
if (!IS_ERR_OR_NULL(cs))
|
||||
wil_del_rx_key(key_index, key_usage, cs);
|
||||
|
||||
return wmi_del_cipher_key(wil, key_index, mac_addr, key_usage);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue