summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/aes_cmac.c60
-rw-r--r--net/mac80211/aes_cmac.h7
-rw-r--r--net/mac80211/aes_gmac.c22
-rw-r--r--net/mac80211/aes_gmac.h1
-rw-r--r--net/mac80211/chan.c15
-rw-r--r--net/mac80211/mlme.c5
-rw-r--r--net/mac80211/rx.c6
-rw-r--r--net/mac80211/tx.c6
-rw-r--r--net/mac80211/wpa.c148
-rw-r--r--net/mac80211/wpa.h10
-rw-r--r--net/wireless/core.c5
-rw-r--r--net/wireless/core.h1
-rw-r--r--net/wireless/mlme.c19
-rw-r--r--net/wireless/nl80211.c3
-rw-r--r--net/wireless/sysfs.c2
-rw-r--r--net/wireless/util.c23
16 files changed, 127 insertions, 206 deletions
diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c
index 48c04f89de20..0827965455dc 100644
--- a/net/mac80211/aes_cmac.c
+++ b/net/mac80211/aes_cmac.c
@@ -16,56 +16,48 @@
#include "key.h"
#include "aes_cmac.h"
-#define CMAC_TLEN 8 /* CMAC TLen = 64 bits (8 octets) */
-#define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */
#define AAD_LEN 20
-static const u8 zero[CMAC_TLEN_256];
+static const u8 zero[IEEE80211_CMAC_256_MIC_LEN];
-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad,
- const u8 *data, size_t data_len, u8 *mic)
+int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad,
+ const u8 *data, size_t data_len, u8 *mic,
+ unsigned int mic_len)
{
+ int err;
SHASH_DESC_ON_STACK(desc, tfm);
u8 out[AES_BLOCK_SIZE];
const __le16 *fc;
desc->tfm = tfm;
- crypto_shash_init(desc);
- crypto_shash_update(desc, aad, AAD_LEN);
+ err = crypto_shash_init(desc);
+ if (err)
+ return err;
+ err = crypto_shash_update(desc, aad, AAD_LEN);
+ if (err)
+ return err;
fc = (const __le16 *)aad;
if (ieee80211_is_beacon(*fc)) {
/* mask Timestamp field to zero */
- crypto_shash_update(desc, zero, 8);
- crypto_shash_update(desc, data + 8, data_len - 8 - CMAC_TLEN);
+ err = crypto_shash_update(desc, zero, 8);
+ if (err)
+ return err;
+ err = crypto_shash_update(desc, data + 8,
+ data_len - 8 - mic_len);
+ if (err)
+ return err;
} else {
- crypto_shash_update(desc, data, data_len - CMAC_TLEN);
+ err = crypto_shash_update(desc, data, data_len - mic_len);
+ if (err)
+ return err;
}
- crypto_shash_finup(desc, zero, CMAC_TLEN, out);
+ err = crypto_shash_finup(desc, zero, mic_len, out);
+ if (err)
+ return err;
+ memcpy(mic, out, mic_len);
- memcpy(mic, out, CMAC_TLEN);
-}
-
-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad,
- const u8 *data, size_t data_len, u8 *mic)
-{
- SHASH_DESC_ON_STACK(desc, tfm);
- const __le16 *fc;
-
- desc->tfm = tfm;
-
- crypto_shash_init(desc);
- crypto_shash_update(desc, aad, AAD_LEN);
- fc = (const __le16 *)aad;
- if (ieee80211_is_beacon(*fc)) {
- /* mask Timestamp field to zero */
- crypto_shash_update(desc, zero, 8);
- crypto_shash_update(desc, data + 8,
- data_len - 8 - CMAC_TLEN_256);
- } else {
- crypto_shash_update(desc, data, data_len - CMAC_TLEN_256);
- }
- crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic);
+ return 0;
}
struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[],
diff --git a/net/mac80211/aes_cmac.h b/net/mac80211/aes_cmac.h
index 76817446fb83..5f971a8298cb 100644
--- a/net/mac80211/aes_cmac.h
+++ b/net/mac80211/aes_cmac.h
@@ -11,10 +11,9 @@
struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[],
size_t key_len);
-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad,
- const u8 *data, size_t data_len, u8 *mic);
-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad,
- const u8 *data, size_t data_len, u8 *mic);
+int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad,
+ const u8 *data, size_t data_len, u8 *mic,
+ unsigned int mic_len);
void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm);
#endif /* AES_CMAC_H */
diff --git a/net/mac80211/aes_gmac.c b/net/mac80211/aes_gmac.c
index 512cab073f2e..811a83d8d525 100644
--- a/net/mac80211/aes_gmac.c
+++ b/net/mac80211/aes_gmac.c
@@ -24,15 +24,16 @@ int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
const __le16 *fc;
int ret;
- if (data_len < GMAC_MIC_LEN)
+ if (data_len < IEEE80211_GMAC_MIC_LEN)
return -EINVAL;
- aead_req = kzalloc(reqsize + GMAC_MIC_LEN + GMAC_AAD_LEN, GFP_ATOMIC);
+ aead_req = kzalloc(reqsize + IEEE80211_GMAC_MIC_LEN + GMAC_AAD_LEN,
+ GFP_ATOMIC);
if (!aead_req)
return -ENOMEM;
zero = (u8 *)aead_req + reqsize;
- __aad = zero + GMAC_MIC_LEN;
+ __aad = zero + IEEE80211_GMAC_MIC_LEN;
memcpy(__aad, aad, GMAC_AAD_LEN);
fc = (const __le16 *)aad;
@@ -41,15 +42,16 @@ int ieee80211_aes_gmac(struct crypto_aead *tfm, const u8 *aad, u8 *nonce,
sg_init_table(sg, 5);
sg_set_buf(&sg[0], __aad, GMAC_AAD_LEN);
sg_set_buf(&sg[1], zero, 8);
- sg_set_buf(&sg[2], data + 8, data_len - 8 - GMAC_MIC_LEN);
- sg_set_buf(&sg[3], zero, GMAC_MIC_LEN);
- sg_set_buf(&sg[4], mic, GMAC_MIC_LEN);
+ sg_set_buf(&sg[2], data + 8,
+ data_len - 8 - IEEE80211_GMAC_MIC_LEN);
+ sg_set_buf(&sg[3], zero, IEEE80211_GMAC_MIC_LEN);
+ sg_set_buf(&sg[4], mic, IEEE80211_GMAC_MIC_LEN);
} else {
sg_init_table(sg, 4);
sg_set_buf(&sg[0], __aad, GMAC_AAD_LEN);
- sg_set_buf(&sg[1], data, data_len - GMAC_MIC_LEN);
- sg_set_buf(&sg[2], zero, GMAC_MIC_LEN);
- sg_set_buf(&sg[3], mic, GMAC_MIC_LEN);
+ sg_set_buf(&sg[1], data, data_len - IEEE80211_GMAC_MIC_LEN);
+ sg_set_buf(&sg[2], zero, IEEE80211_GMAC_MIC_LEN);
+ sg_set_buf(&sg[3], mic, IEEE80211_GMAC_MIC_LEN);
}
memcpy(iv, nonce, GMAC_NONCE_LEN);
@@ -78,7 +80,7 @@ struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
err = crypto_aead_setkey(tfm, key, key_len);
if (!err)
- err = crypto_aead_setauthsize(tfm, GMAC_MIC_LEN);
+ err = crypto_aead_setauthsize(tfm, IEEE80211_GMAC_MIC_LEN);
if (!err)
return tfm;
diff --git a/net/mac80211/aes_gmac.h b/net/mac80211/aes_gmac.h
index c739356bae2a..206136b60bca 100644
--- a/net/mac80211/aes_gmac.h
+++ b/net/mac80211/aes_gmac.h
@@ -9,7 +9,6 @@
#include <linux/crypto.h>
#define GMAC_AAD_LEN 20
-#define GMAC_MIC_LEN 16
#define GMAC_NONCE_LEN 12
struct crypto_aead *ieee80211_aes_gmac_key_setup(const u8 key[],
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 6aa305839f53..d0bfb1216401 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -654,8 +654,19 @@ static void _ieee80211_change_chanctx(struct ieee80211_local *local,
};
u32 changed = 0;
- /* expected to handle only 20/40/80/160/320 channel widths */
+ /* 5/10 MHz not handled here */
switch (chandef->width) {
+ case NL80211_CHAN_WIDTH_1:
+ case NL80211_CHAN_WIDTH_2:
+ case NL80211_CHAN_WIDTH_4:
+ case NL80211_CHAN_WIDTH_8:
+ case NL80211_CHAN_WIDTH_16:
+ /*
+ * mac80211 currently only supports sharing identical
+ * chanctx's for S1G interfaces.
+ */
+ WARN_ON(!ieee80211_chanreq_identical(&ctx_req, chanreq));
+ return;
case NL80211_CHAN_WIDTH_20_NOHT:
case NL80211_CHAN_WIDTH_20:
case NL80211_CHAN_WIDTH_40:
@@ -1715,7 +1726,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
n_reserved = 0;
n_ready = 0;
- for_each_chanctx_user_assigned(local, ctx, &iter) {
+ for_each_chanctx_user_assigned(local, ctx->replace_ctx, &iter) {
n_assigned++;
if (iter.link->reserved_chanctx) {
n_reserved++;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c705d3f45aff..e56ad4b9330f 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -6108,9 +6108,10 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
ret = ieee80211_link_use_channel(link, &chanreq,
IEEE80211_CHANCTX_SHARED);
- /* don't downgrade for 5 and 10 MHz channels, though. */
+ /* don't downgrade for 5/10/S1G MHz channels, though. */
if (chanreq.oper.width == NL80211_CHAN_WIDTH_5 ||
- chanreq.oper.width == NL80211_CHAN_WIDTH_10)
+ chanreq.oper.width == NL80211_CHAN_WIDTH_10 ||
+ cfg80211_chandef_is_s1g(&chanreq.oper))
return ret;
while (ret && chanreq.oper.width != NL80211_CHAN_WIDTH_20_NOHT) {
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index cc26c279984d..6a1899512d07 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2215,10 +2215,12 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
rx, IEEE80211_CCMP_256_MIC_LEN);
break;
case WLAN_CIPHER_SUITE_AES_CMAC:
- result = ieee80211_crypto_aes_cmac_decrypt(rx);
+ result = ieee80211_crypto_aes_cmac_decrypt(
+ rx, IEEE80211_CMAC_128_MIC_LEN);
break;
case WLAN_CIPHER_SUITE_BIP_CMAC_256:
- result = ieee80211_crypto_aes_cmac_256_decrypt(rx);
+ result = ieee80211_crypto_aes_cmac_decrypt(
+ rx, IEEE80211_CMAC_256_MIC_LEN);
break;
case WLAN_CIPHER_SUITE_BIP_GMAC_128:
case WLAN_CIPHER_SUITE_BIP_GMAC_256:
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e7b141c55f7a..9d8b0a25f73c 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1062,9 +1062,11 @@ ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx)
return ieee80211_crypto_ccmp_encrypt(
tx, IEEE80211_CCMP_256_MIC_LEN);
case WLAN_CIPHER_SUITE_AES_CMAC:
- return ieee80211_crypto_aes_cmac_encrypt(tx);
+ return ieee80211_crypto_aes_cmac_encrypt(
+ tx, IEEE80211_CMAC_128_MIC_LEN);
case WLAN_CIPHER_SUITE_BIP_CMAC_256:
- return ieee80211_crypto_aes_cmac_256_encrypt(tx);
+ return ieee80211_crypto_aes_cmac_encrypt(
+ tx, IEEE80211_CMAC_256_MIC_LEN);
case WLAN_CIPHER_SUITE_BIP_GMAC_128:
case WLAN_CIPHER_SUITE_BIP_GMAC_256:
return ieee80211_crypto_aes_gmac_encrypt(tx);
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 40d5d9e48479..4a858112e4ef 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -828,12 +828,14 @@ static inline void bip_ipn_swap(u8 *d, const u8 *s)
ieee80211_tx_result
-ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx)
+ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx,
+ unsigned int mic_len)
{
struct sk_buff *skb;
struct ieee80211_tx_info *info;
struct ieee80211_key *key = tx->key;
- struct ieee80211_mmie *mmie;
+ struct ieee80211_mmie_var *mmie;
+ size_t mmie_len;
u8 aad[20];
u64 pn64;
@@ -848,60 +850,14 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx)
!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIE))
return TX_CONTINUE;
- if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
- return TX_DROP;
-
- mmie = skb_put(skb, sizeof(*mmie));
- mmie->element_id = WLAN_EID_MMIE;
- mmie->length = sizeof(*mmie) - 2;
- mmie->key_id = cpu_to_le16(key->conf.keyidx);
-
- /* PN = PN + 1 */
- pn64 = atomic64_inc_return(&key->conf.tx_pn);
-
- bip_ipn_set64(mmie->sequence_number, pn64);
-
- if (info->control.hw_key)
- return TX_CONTINUE;
-
- bip_aad(skb, aad);
-
- /*
- * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64)
- */
- ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
- skb->data + 24, skb->len - 24, mmie->mic);
-
- return TX_CONTINUE;
-}
-
-ieee80211_tx_result
-ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx)
-{
- struct sk_buff *skb;
- struct ieee80211_tx_info *info;
- struct ieee80211_key *key = tx->key;
- struct ieee80211_mmie_16 *mmie;
- u8 aad[20];
- u64 pn64;
-
- if (WARN_ON(skb_queue_len(&tx->skbs) != 1))
- return TX_DROP;
-
- skb = skb_peek(&tx->skbs);
-
- info = IEEE80211_SKB_CB(skb);
-
- if (info->control.hw_key &&
- !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIE))
- return TX_CONTINUE;
+ mmie_len = sizeof(*mmie) + mic_len;
- if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie)))
+ if (WARN_ON(skb_tailroom(skb) < mmie_len))
return TX_DROP;
- mmie = skb_put(skb, sizeof(*mmie));
+ mmie = skb_put(skb, mmie_len);
mmie->element_id = WLAN_EID_MMIE;
- mmie->length = sizeof(*mmie) - 2;
+ mmie->length = mmie_len - 2;
mmie->key_id = cpu_to_le16(key->conf.keyidx);
/* PN = PN + 1 */
@@ -914,86 +870,40 @@ ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx)
bip_aad(skb, aad);
- /* MIC = AES-256-CMAC(IGTK, AAD || Management Frame Body || MMIE, 128)
- */
- ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad,
- skb->data + 24, skb->len - 24, mmie->mic);
+ if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
+ skb->data + 24, skb->len - 24,
+ mmie->mic, mic_len))
+ return TX_DROP;
return TX_CONTINUE;
}
ieee80211_rx_result
-ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx)
+ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx,
+ unsigned int mic_len)
{
struct sk_buff *skb = rx->skb;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_key *key = rx->key;
- struct ieee80211_mmie *mmie;
- u8 aad[20], mic[8], ipn[6];
+ struct ieee80211_mmie_var *mmie;
+ size_t mmie_len;
+ u8 aad[20], mic[IEEE80211_CMAC_256_MIC_LEN], ipn[6];
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
if (!ieee80211_is_mgmt(hdr->frame_control))
return RX_CONTINUE;
- /* management frames are already linear */
-
- if (skb->len < 24 + sizeof(*mmie))
- return RX_DROP_U_SHORT_CMAC;
-
- mmie = (struct ieee80211_mmie *)
- (skb->data + skb->len - sizeof(*mmie));
- if (mmie->element_id != WLAN_EID_MMIE ||
- mmie->length != sizeof(*mmie) - 2)
- return RX_DROP_U_BAD_MMIE; /* Invalid MMIE */
-
- bip_ipn_swap(ipn, mmie->sequence_number);
-
- if (memcmp(ipn, key->u.aes_cmac.rx_pn, 6) <= 0) {
- key->u.aes_cmac.replays++;
- return RX_DROP_U_REPLAY;
- }
-
- if (!(status->flag & RX_FLAG_DECRYPTED)) {
- /* hardware didn't decrypt/verify MIC */
- bip_aad(skb, aad);
- ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
- skb->data + 24, skb->len - 24, mic);
- if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
- key->u.aes_cmac.icverrors++;
- return RX_DROP_U_MIC_FAIL;
- }
- }
-
- memcpy(key->u.aes_cmac.rx_pn, ipn, 6);
-
- /* Remove MMIE */
- skb_trim(skb, skb->len - sizeof(*mmie));
-
- return RX_CONTINUE;
-}
-
-ieee80211_rx_result
-ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)
-{
- struct sk_buff *skb = rx->skb;
- struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
- struct ieee80211_key *key = rx->key;
- struct ieee80211_mmie_16 *mmie;
- u8 aad[20], mic[16], ipn[6];
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-
- if (!ieee80211_is_mgmt(hdr->frame_control))
- return RX_CONTINUE;
+ mmie_len = sizeof(*mmie) + mic_len;
/* management frames are already linear */
- if (skb->len < 24 + sizeof(*mmie))
- return RX_DROP_U_SHORT_CMAC256;
+ if (skb->len < 24 + mmie_len)
+ return mic_len == IEEE80211_CMAC_128_MIC_LEN ?
+ RX_DROP_U_SHORT_CMAC : RX_DROP_U_SHORT_CMAC256;
- mmie = (struct ieee80211_mmie_16 *)
- (skb->data + skb->len - sizeof(*mmie));
+ mmie = (struct ieee80211_mmie_var *)(skb->data + skb->len - mmie_len);
if (mmie->element_id != WLAN_EID_MMIE ||
- mmie->length != sizeof(*mmie) - 2)
+ mmie->length != mmie_len - 2)
return RX_DROP_U_BAD_MMIE; /* Invalid MMIE */
bip_ipn_swap(ipn, mmie->sequence_number);
@@ -1006,9 +916,11 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)
if (!(status->flag & RX_FLAG_DECRYPTED)) {
/* hardware didn't decrypt/verify MIC */
bip_aad(skb, aad);
- ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad,
- skb->data + 24, skb->len - 24, mic);
- if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) {
+ if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad,
+ skb->data + 24, skb->len - 24,
+ mic, mic_len))
+ return RX_DROP_U_DECRYPT_FAIL;
+ if (crypto_memneq(mic, mmie->mic, mic_len)) {
key->u.aes_cmac.icverrors++;
return RX_DROP_U_MIC_FAIL;
}
@@ -1017,7 +929,7 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx)
memcpy(key->u.aes_cmac.rx_pn, ipn, 6);
/* Remove MMIE */
- skb_trim(skb, skb->len - sizeof(*mmie));
+ skb_trim(skb, skb->len - mmie_len);
return RX_CONTINUE;
}
@@ -1113,7 +1025,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx)
memcpy(nonce, hdr->addr2, ETH_ALEN);
memcpy(nonce + ETH_ALEN, ipn, 6);
- mic = kmalloc(GMAC_MIC_LEN, GFP_ATOMIC);
+ mic = kmalloc(IEEE80211_GMAC_MIC_LEN, GFP_ATOMIC);
if (!mic)
return RX_DROP_U_OOM;
if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce,
diff --git a/net/mac80211/wpa.h b/net/mac80211/wpa.h
index a9a81abb5479..6e8846dfe710 100644
--- a/net/mac80211/wpa.h
+++ b/net/mac80211/wpa.h
@@ -29,13 +29,11 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx,
unsigned int mic_len);
ieee80211_tx_result
-ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx);
-ieee80211_tx_result
-ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx);
-ieee80211_rx_result
-ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx);
+ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx,
+ unsigned int mic_len);
ieee80211_rx_result
-ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx);
+ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx,
+ unsigned int mic_len);
ieee80211_tx_result
ieee80211_crypto_aes_gmac_encrypt(struct ieee80211_tx_data *tx);
ieee80211_rx_result
diff --git a/net/wireless/core.c b/net/wireless/core.c
index aa78dbaaf093..9a420d627d3c 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -431,7 +431,7 @@ static void cfg80211_wiphy_work(struct work_struct *work)
if (wk) {
list_del_init(&wk->entry);
if (!list_empty(&rdev->wiphy_work_list))
- queue_work(system_unbound_wq, work);
+ queue_work(system_dfl_wq, work);
spin_unlock_irq(&rdev->wiphy_work_lock);
trace_wiphy_work_run(&rdev->wiphy, wk);
@@ -1380,6 +1380,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev,
cfg80211_pmsr_wdev_down(wdev);
+ cfg80211_stop_radar_detection(wdev);
cfg80211_stop_background_radar_detection(wdev);
switch (wdev->iftype) {
@@ -1713,7 +1714,7 @@ void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work)
list_add_tail(&work->entry, &rdev->wiphy_work_list);
spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags);
- queue_work(system_unbound_wq, &rdev->wiphy_work);
+ queue_work(system_dfl_wq, &rdev->wiphy_work);
}
EXPORT_SYMBOL_GPL(wiphy_work_queue);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 82f343663e8f..63dcf315dba7 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -489,6 +489,7 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde
struct wireless_dev *wdev,
struct cfg80211_chan_def *chandef);
+void cfg80211_stop_radar_detection(struct wireless_dev *wdev);
void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev);
void cfg80211_background_cac_done_wk(struct work_struct *work);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 46394eb2086f..3fc175f9f868 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -1295,6 +1295,25 @@ cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rde
return 0;
}
+void cfg80211_stop_radar_detection(struct wireless_dev *wdev)
+{
+ struct wiphy *wiphy = wdev->wiphy;
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
+ int link_id;
+
+ for_each_valid_link(wdev, link_id) {
+ struct cfg80211_chan_def chandef;
+
+ if (!wdev->links[link_id].cac_started)
+ continue;
+
+ chandef = *wdev_chandef(wdev, link_id);
+ rdev_end_cac(rdev, wdev->netdev, link_id);
+ nl80211_radar_notify(rdev, &chandef, NL80211_RADAR_CAC_ABORTED,
+ wdev->netdev, GFP_KERNEL);
+ }
+}
+
void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev)
{
struct wiphy *wiphy = wdev->wiphy;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 29c92bc8291b..c961cd42a832 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4178,6 +4178,9 @@ int nl80211_send_chandef(struct sk_buff *msg, const struct cfg80211_chan_def *ch
if (chandef->punctured &&
nla_put_u32(msg, NL80211_ATTR_PUNCT_BITMAP, chandef->punctured))
return -ENOBUFS;
+ if (chandef->s1g_primary_2mhz &&
+ nla_put_flag(msg, NL80211_ATTR_S1G_PRIMARY_2MHZ))
+ return -ENOBUFS;
return 0;
}
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 62f26618f674..8d142856e385 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -137,7 +137,7 @@ static int wiphy_resume(struct device *dev)
if (rdev->wiphy.registered && rdev->ops->resume)
ret = rdev_resume(rdev);
rdev->suspended = false;
- queue_work(system_unbound_wq, &rdev->wiphy_work);
+ queue_work(system_dfl_wq, &rdev->wiphy_work);
wiphy_unlock(&rdev->wiphy);
if (ret)
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 97f40c6d1e9d..27e8a2f52f04 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1203,28 +1203,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
dev->ieee80211_ptr->use_4addr = false;
rdev_set_qos_map(rdev, dev, NULL);
- switch (otype) {
- case NL80211_IFTYPE_AP:
- case NL80211_IFTYPE_P2P_GO:
- cfg80211_stop_ap(rdev, dev, -1, true);
- break;
- case NL80211_IFTYPE_ADHOC:
- cfg80211_leave_ibss(rdev, dev, false);
- break;
- case NL80211_IFTYPE_STATION:
- case NL80211_IFTYPE_P2P_CLIENT:
- cfg80211_disconnect(rdev, dev,
- WLAN_REASON_DEAUTH_LEAVING, true);
- break;
- case NL80211_IFTYPE_MESH_POINT:
- /* mesh should be handled? */
- break;
- case NL80211_IFTYPE_OCB:
- cfg80211_leave_ocb(rdev, dev);
- break;
- default:
- break;
- }
+ cfg80211_leave(rdev, dev->ieee80211_ptr);
cfg80211_process_rdev_events(rdev);
cfg80211_mlme_purge_registrations(dev->ieee80211_ptr);