* [PATCH ath-next v6] wifi: ath12k: avoid dynamic alloc when parsing wmi tb
From: Nicolas Escande @ 2026-04-03 14:28 UTC (permalink / raw)
To: ath12k; +Cc: linux-wireless
On each WMI message received from the hardware, we alloc a temporary array
of WMI_TAG_MAX entries of type void *. This array is then populated with
pointers of parsed structs depending on the WMI type, and then freed. This
alloc can fail when memory pressure in the system is high enough.
Given the fact that it is scheduled in softirq with the system_bh_wq, we
should not be able to parse more than one WMI message per CPU at any time.
So instead lets move to a per cpu allocated array, that is reused across
calls. This memory is allocated as needed and refcounted to exist only
as long as one struct ath12k_base lives.
ath12k_wmi_tlv_parse_alloc() and ath12k_wmi_tlv_parse() are merged
together as it no longer allocs mem but returns the existing per-cpu one.
Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00218-QCAHKSWPL_SILICONZ-1
Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
---
changes from v4:
- moved to a single instance, refcounted per cpu memory alloc
changes from v3:
- simplified ath12k_core_init() with a single statement
- move perpcu.h include directly to wmi.c
changes from v2:
- removed now superfluous return in ath12k_wmi_event_teardown_complete()
- moved ath12k_wmi_tb declaration to wmi.c & added two functions to
alloc / free it
- removed useless error message on memory allocation failure
changes from v1:
- rebased on ath-next 27401c9b1432
- changed wording according to Jeff's comment
- moved alloc/cleanup to new module_init/exit functions in the
ath12k module as per Baochen's comment
changes from RFC:
- rebased on ath-next 8e0ab5b9adb7
- converted missing call sites ath12k_wmi_obss_color_collision_event()
& ath12k_wmi_pdev_temperature_event()
- changed alloc order & cleanup path in ath12k_core_alloc() as it seems
it confused people
- used sizeof(*tb) in ath12k_wmi_tlv_parse()
---
drivers/net/wireless/ath/ath12k/core.c | 6 +
drivers/net/wireless/ath/ath12k/wmi.c | 214 +++++++++----------------
drivers/net/wireless/ath/ath12k/wmi.h | 3 +
3 files changed, 84 insertions(+), 139 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index c31c47fb5a73..6f0f4bfbf699 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -2256,6 +2256,7 @@ void ath12k_core_deinit(struct ath12k_base *ab)
void ath12k_core_free(struct ath12k_base *ab)
{
timer_delete_sync(&ab->rx_replenish_retry);
+ ath12k_wmi_free();
destroy_workqueue(ab->workqueue_aux);
destroy_workqueue(ab->workqueue);
kfree(ab);
@@ -2280,6 +2281,9 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size,
if (!ab->workqueue_aux)
goto err_free_wq;
+ if (ath12k_wmi_alloc() < 0)
+ goto err_free_wq_aux;
+
mutex_init(&ab->core_lock);
spin_lock_init(&ab->base_lock);
init_completion(&ab->reset_complete);
@@ -2314,6 +2318,8 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size,
return ab;
+err_free_wq_aux:
+ destroy_workqueue(ab->workqueue_aux);
err_free_wq:
destroy_workqueue(ab->workqueue);
err_sc_free:
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index 65a05a9520ff..2641a76e9543 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -15,6 +15,8 @@
#include <linux/time.h>
#include <linux/of.h>
#include <linux/cleanup.h>
+#include <linux/percpu.h>
+#include <linux/refcount.h>
#include "core.h"
#include "debugfs.h"
#include "debug.h"
@@ -134,6 +136,10 @@ struct wmi_pdev_set_obss_bitmap_arg {
const char *label;
};
+static DEFINE_MUTEX(ath12k_wmi_mutex);
+static refcount_t ath12k_wmi_refcount = REFCOUNT_INIT(0);
+static void __percpu *ath12k_wmi_tb = NULL;
+
static const struct ath12k_wmi_tlv_policy ath12k_wmi_tlv_policies[] = {
[WMI_TAG_ARRAY_BYTE] = { .min_len = 0 },
[WMI_TAG_ARRAY_UINT32] = { .min_len = 0 },
@@ -289,29 +295,19 @@ static int ath12k_wmi_tlv_iter_parse(struct ath12k_base *ab, u16 tag, u16 len,
return 0;
}
-static int ath12k_wmi_tlv_parse(struct ath12k_base *ar, const void **tb,
- const void *ptr, size_t len)
-{
- return ath12k_wmi_tlv_iter(ar, ptr, len, ath12k_wmi_tlv_iter_parse,
- (void *)tb);
-}
-
static const void **
-ath12k_wmi_tlv_parse_alloc(struct ath12k_base *ab,
- struct sk_buff *skb, gfp_t gfp)
+ath12k_wmi_tlv_parse(struct ath12k_base *ab, struct sk_buff *skb)
{
const void **tb;
int ret;
- tb = kzalloc_objs(*tb, WMI_TAG_MAX, gfp);
- if (!tb)
- return ERR_PTR(-ENOMEM);
+ tb = this_cpu_ptr(ath12k_wmi_tb);
+ memset(tb, 0, WMI_TAG_MAX * sizeof(*tb));
- ret = ath12k_wmi_tlv_parse(ab, tb, skb->data, skb->len);
- if (ret) {
- kfree(tb);
+ ret = ath12k_wmi_tlv_iter(ab, skb->data, skb->len,
+ ath12k_wmi_tlv_iter_parse, (void *)tb);
+ if (ret)
return ERR_PTR(ret);
- }
return tb;
}
@@ -3911,9 +3907,10 @@ ath12k_wmi_obss_color_collision_event(struct ath12k_base *ab, struct sk_buff *sk
const struct wmi_obss_color_collision_event *ev;
struct ath12k_link_vif *arvif;
u32 vdev_id, evt_type;
+ const void **tb;
u64 bitmap;
- const void **tb __free(kfree) = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ath12k_warn(ab, "failed to parse OBSS color collision tlv %ld\n",
PTR_ERR(tb));
@@ -5714,7 +5711,7 @@ static int ath12k_pull_vdev_start_resp_tlv(struct ath12k_base *ab, struct sk_buf
const struct wmi_vdev_start_resp_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -5724,13 +5721,11 @@ static int ath12k_pull_vdev_start_resp_tlv(struct ath12k_base *ab, struct sk_buf
ev = tb[WMI_TAG_VDEV_START_RESPONSE_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch vdev start resp ev");
- kfree(tb);
return -EPROTO;
}
*vdev_rsp = *ev;
- kfree(tb);
return 0;
}
@@ -5809,7 +5804,7 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
ath12k_dbg(ab, ATH12K_DBG_WMI, "processing regulatory ext channel list\n");
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -5819,7 +5814,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
ev = tb[WMI_TAG_REG_CHAN_LIST_CC_EXT_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch reg chan list ext update ev\n");
- kfree(tb);
return -EPROTO;
}
@@ -5849,7 +5843,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
if (num_2g_reg_rules > MAX_REG_RULES || num_5g_reg_rules > MAX_REG_RULES) {
ath12k_warn(ab, "Num reg rules for 2G/5G exceeds max limit (num_2g_reg_rules: %d num_5g_reg_rules: %d max_rules: %d)\n",
num_2g_reg_rules, num_5g_reg_rules, MAX_REG_RULES);
- kfree(tb);
return -EINVAL;
}
@@ -5859,7 +5852,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
if (num_6g_reg_rules_ap[i] > MAX_6GHZ_REG_RULES) {
ath12k_warn(ab, "Num 6G reg rules for AP mode(%d) exceeds max limit (num_6g_reg_rules_ap: %d, max_rules: %d)\n",
i, num_6g_reg_rules_ap[i], MAX_6GHZ_REG_RULES);
- kfree(tb);
return -EINVAL;
}
@@ -5884,14 +5876,12 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
num_6g_reg_rules_cl[WMI_REG_VLP_AP][i] > MAX_6GHZ_REG_RULES) {
ath12k_warn(ab, "Num 6g client reg rules exceeds max limit, for client(type: %d)\n",
i);
- kfree(tb);
return -EINVAL;
}
}
if (!total_reg_rules) {
ath12k_warn(ab, "No reg rules available\n");
- kfree(tb);
return -EINVAL;
}
@@ -5993,7 +5983,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
ext_wmi_reg_rule);
if (!reg_info->reg_rules_2g_ptr) {
- kfree(tb);
ath12k_warn(ab, "Unable to Allocate memory for 2g rules\n");
return -ENOMEM;
}
@@ -6027,7 +6016,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
ext_wmi_reg_rule);
if (!reg_info->reg_rules_5g_ptr) {
- kfree(tb);
ath12k_warn(ab, "Unable to Allocate memory for 5g rules\n");
return -ENOMEM;
}
@@ -6046,7 +6034,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
ext_wmi_reg_rule);
if (!reg_info->reg_rules_6g_ap_ptr[i]) {
- kfree(tb);
ath12k_warn(ab, "Unable to Allocate memory for 6g ap rules\n");
return -ENOMEM;
}
@@ -6061,7 +6048,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
ext_wmi_reg_rule);
if (!reg_info->reg_rules_6g_client_ptr[j][i]) {
- kfree(tb);
ath12k_warn(ab, "Unable to Allocate memory for 6g client rules\n");
return -ENOMEM;
}
@@ -6096,7 +6082,6 @@ static int ath12k_pull_reg_chan_list_ext_update_ev(struct ath12k_base *ab,
ath12k_dbg(ab, ATH12K_DBG_WMI, "processed regulatory ext channel list\n");
- kfree(tb);
return 0;
}
@@ -6107,7 +6092,7 @@ static int ath12k_pull_peer_del_resp_ev(struct ath12k_base *ab, struct sk_buff *
const struct wmi_peer_delete_resp_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -6117,7 +6102,6 @@ static int ath12k_pull_peer_del_resp_ev(struct ath12k_base *ab, struct sk_buff *
ev = tb[WMI_TAG_PEER_DELETE_RESP_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch peer delete resp ev");
- kfree(tb);
return -EPROTO;
}
@@ -6127,7 +6111,6 @@ static int ath12k_pull_peer_del_resp_ev(struct ath12k_base *ab, struct sk_buff *
ether_addr_copy(peer_del_resp->peer_macaddr.addr,
ev->peer_macaddr.addr);
- kfree(tb);
return 0;
}
@@ -6139,7 +6122,7 @@ static int ath12k_pull_vdev_del_resp_ev(struct ath12k_base *ab,
const struct wmi_vdev_delete_resp_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -6149,13 +6132,11 @@ static int ath12k_pull_vdev_del_resp_ev(struct ath12k_base *ab,
ev = tb[WMI_TAG_VDEV_DELETE_RESP_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch vdev delete resp ev");
- kfree(tb);
return -EPROTO;
}
*vdev_id = le32_to_cpu(ev->vdev_id);
- kfree(tb);
return 0;
}
@@ -6167,7 +6148,7 @@ static int ath12k_pull_bcn_tx_status_ev(struct ath12k_base *ab,
const struct wmi_bcn_tx_status_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -6177,14 +6158,12 @@ static int ath12k_pull_bcn_tx_status_ev(struct ath12k_base *ab,
ev = tb[WMI_TAG_OFFLOAD_BCN_TX_STATUS_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch bcn tx status ev");
- kfree(tb);
return -EPROTO;
}
*vdev_id = le32_to_cpu(ev->vdev_id);
*tx_status = le32_to_cpu(ev->tx_status);
- kfree(tb);
return 0;
}
@@ -6195,7 +6174,7 @@ static int ath12k_pull_vdev_stopped_param_tlv(struct ath12k_base *ab, struct sk_
const struct wmi_vdev_stopped_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -6205,13 +6184,11 @@ static int ath12k_pull_vdev_stopped_param_tlv(struct ath12k_base *ab, struct sk_
ev = tb[WMI_TAG_VDEV_STOPPED_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch vdev stop ev");
- kfree(tb);
return -EPROTO;
}
*vdev_id = le32_to_cpu(ev->vdev_id);
- kfree(tb);
return 0;
}
@@ -6350,7 +6327,7 @@ static int ath12k_pull_mgmt_tx_compl_param_tlv(struct ath12k_base *ab,
const struct wmi_mgmt_tx_compl_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -6360,7 +6337,6 @@ static int ath12k_pull_mgmt_tx_compl_param_tlv(struct ath12k_base *ab,
ev = tb[WMI_TAG_MGMT_TX_COMPL_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch mgmt tx compl ev");
- kfree(tb);
return -EPROTO;
}
@@ -6370,7 +6346,6 @@ static int ath12k_pull_mgmt_tx_compl_param_tlv(struct ath12k_base *ab,
param->ppdu_id = ev->ppdu_id;
param->ack_rssi = ev->ack_rssi;
- kfree(tb);
return 0;
}
@@ -6533,7 +6508,7 @@ static int ath12k_pull_scan_ev(struct ath12k_base *ab, struct sk_buff *skb,
const struct wmi_scan_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -6543,7 +6518,6 @@ static int ath12k_pull_scan_ev(struct ath12k_base *ab, struct sk_buff *skb,
ev = tb[WMI_TAG_SCAN_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch scan ev");
- kfree(tb);
return -EPROTO;
}
@@ -6555,7 +6529,6 @@ static int ath12k_pull_scan_ev(struct ath12k_base *ab, struct sk_buff *skb,
scan_evt_param->vdev_id = ev->vdev_id;
scan_evt_param->tsf_timestamp = ev->tsf_timestamp;
- kfree(tb);
return 0;
}
@@ -6566,7 +6539,7 @@ static int ath12k_pull_peer_sta_kickout_ev(struct ath12k_base *ab, struct sk_buf
const struct wmi_peer_sta_kickout_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -6576,7 +6549,6 @@ static int ath12k_pull_peer_sta_kickout_ev(struct ath12k_base *ab, struct sk_buf
ev = tb[WMI_TAG_PEER_STA_KICKOUT_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch peer sta kickout ev");
- kfree(tb);
return -EPROTO;
}
@@ -6584,7 +6556,6 @@ static int ath12k_pull_peer_sta_kickout_ev(struct ath12k_base *ab, struct sk_buf
arg->reason = le32_to_cpu(ev->reason);
arg->rssi = le32_to_cpu(ev->rssi);
- kfree(tb);
return 0;
}
@@ -6595,7 +6566,7 @@ static int ath12k_pull_roam_ev(struct ath12k_base *ab, struct sk_buff *skb,
const struct wmi_roam_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -6605,7 +6576,6 @@ static int ath12k_pull_roam_ev(struct ath12k_base *ab, struct sk_buff *skb,
ev = tb[WMI_TAG_ROAM_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch roam ev");
- kfree(tb);
return -EPROTO;
}
@@ -6613,7 +6583,6 @@ static int ath12k_pull_roam_ev(struct ath12k_base *ab, struct sk_buff *skb,
roam_ev->reason = ev->reason;
roam_ev->rssi = ev->rssi;
- kfree(tb);
return 0;
}
@@ -6647,7 +6616,7 @@ static int ath12k_pull_chan_info_ev(struct ath12k_base *ab, struct sk_buff *skb,
const struct wmi_chan_info_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -6657,7 +6626,6 @@ static int ath12k_pull_chan_info_ev(struct ath12k_base *ab, struct sk_buff *skb,
ev = tb[WMI_TAG_CHAN_INFO_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch chan info ev");
- kfree(tb);
return -EPROTO;
}
@@ -6674,7 +6642,6 @@ static int ath12k_pull_chan_info_ev(struct ath12k_base *ab, struct sk_buff *skb,
ch_info_ev->mac_clk_mhz = ev->mac_clk_mhz;
ch_info_ev->vdev_id = ev->vdev_id;
- kfree(tb);
return 0;
}
@@ -6686,7 +6653,7 @@ ath12k_pull_pdev_bss_chan_info_ev(struct ath12k_base *ab, struct sk_buff *skb,
const struct wmi_pdev_bss_chan_info_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -6696,7 +6663,6 @@ ath12k_pull_pdev_bss_chan_info_ev(struct ath12k_base *ab, struct sk_buff *skb,
ev = tb[WMI_TAG_PDEV_BSS_CHAN_INFO_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch pdev bss chan info ev");
- kfree(tb);
return -EPROTO;
}
@@ -6714,7 +6680,6 @@ ath12k_pull_pdev_bss_chan_info_ev(struct ath12k_base *ab, struct sk_buff *skb,
bss_ch_info_ev->rx_bss_cycle_count_low = ev->rx_bss_cycle_count_low;
bss_ch_info_ev->rx_bss_cycle_count_high = ev->rx_bss_cycle_count_high;
- kfree(tb);
return 0;
}
@@ -6726,7 +6691,7 @@ ath12k_pull_vdev_install_key_compl_ev(struct ath12k_base *ab, struct sk_buff *sk
const struct wmi_vdev_install_key_compl_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -6736,7 +6701,6 @@ ath12k_pull_vdev_install_key_compl_ev(struct ath12k_base *ab, struct sk_buff *sk
ev = tb[WMI_TAG_VDEV_INSTALL_KEY_COMPLETE_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch vdev install key compl ev");
- kfree(tb);
return -EPROTO;
}
@@ -6746,7 +6710,6 @@ ath12k_pull_vdev_install_key_compl_ev(struct ath12k_base *ab, struct sk_buff *sk
arg->key_flags = le32_to_cpu(ev->key_flags);
arg->status = le32_to_cpu(ev->status);
- kfree(tb);
return 0;
}
@@ -6757,7 +6720,7 @@ static int ath12k_pull_peer_assoc_conf_ev(struct ath12k_base *ab, struct sk_buff
const struct wmi_peer_assoc_conf_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -6767,14 +6730,12 @@ static int ath12k_pull_peer_assoc_conf_ev(struct ath12k_base *ab, struct sk_buff
ev = tb[WMI_TAG_PEER_ASSOC_CONF_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch peer assoc conf ev");
- kfree(tb);
return -EPROTO;
}
peer_assoc_conf->vdev_id = le32_to_cpu(ev->vdev_id);
peer_assoc_conf->macaddr = ev->peer_macaddr.addr;
- kfree(tb);
return 0;
}
@@ -6792,7 +6753,7 @@ static int ath12k_reg_11d_new_cc_event(struct ath12k_base *ab, struct sk_buff *s
const void **tb;
int ret, i;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -6801,7 +6762,6 @@ static int ath12k_reg_11d_new_cc_event(struct ath12k_base *ab, struct sk_buff *s
ev = tb[WMI_TAG_11D_NEW_COUNTRY_EVENT];
if (!ev) {
- kfree(tb);
ath12k_warn(ab, "failed to fetch 11d new cc ev");
return -EPROTO;
}
@@ -6814,8 +6774,6 @@ static int ath12k_reg_11d_new_cc_event(struct ath12k_base *ab, struct sk_buff *s
ab->new_alpha2[0],
ab->new_alpha2[1]);
- kfree(tb);
-
for (i = 0; i < ab->num_radios; i++) {
pdev = &ab->pdevs[i];
ar = pdev->ar;
@@ -8557,7 +8515,7 @@ static void ath12k_pdev_ctl_failsafe_check_event(struct ath12k_base *ab,
const struct wmi_pdev_ctl_failsafe_chk_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -8567,7 +8525,6 @@ static void ath12k_pdev_ctl_failsafe_check_event(struct ath12k_base *ab,
ev = tb[WMI_TAG_PDEV_CTL_FAILSAFE_CHECK_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch pdev ctl failsafe check ev");
- kfree(tb);
return;
}
@@ -8581,8 +8538,6 @@ static void ath12k_pdev_ctl_failsafe_check_event(struct ath12k_base *ab,
if (ev->ctl_failsafe_status != 0)
ath12k_warn(ab, "pdev ctl failsafe failure status %d",
ev->ctl_failsafe_status);
-
- kfree(tb);
}
static void
@@ -8654,7 +8609,7 @@ ath12k_wmi_pdev_csa_switch_count_status_event(struct ath12k_base *ab,
const u32 *vdev_ids;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -8666,7 +8621,6 @@ ath12k_wmi_pdev_csa_switch_count_status_event(struct ath12k_base *ab,
if (!ev || !vdev_ids) {
ath12k_warn(ab, "failed to fetch pdev csa switch count ev");
- kfree(tb);
return;
}
@@ -8676,8 +8630,6 @@ ath12k_wmi_pdev_csa_switch_count_status_event(struct ath12k_base *ab,
ev->num_vdevs);
ath12k_wmi_process_csa_switch_count_event(ab, ev, vdev_ids);
-
- kfree(tb);
}
static void
@@ -8689,7 +8641,7 @@ ath12k_wmi_pdev_dfs_radar_detected_event(struct ath12k_base *ab, struct sk_buff
struct ath12k *ar;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -8700,7 +8652,6 @@ ath12k_wmi_pdev_dfs_radar_detected_event(struct ath12k_base *ab, struct sk_buff
if (!ev) {
ath12k_warn(ab, "failed to fetch pdev dfs radar detected ev");
- kfree(tb);
return;
}
@@ -8739,8 +8690,6 @@ ath12k_wmi_pdev_dfs_radar_detected_event(struct ath12k_base *ab, struct sk_buff
exit:
rcu_read_unlock();
-
- kfree(tb);
}
static void ath12k_tm_wmi_event_segmented(struct ath12k_base *ab, u32 cmd_id,
@@ -8751,7 +8700,7 @@ static void ath12k_tm_wmi_event_segmented(struct ath12k_base *ab, u32 cmd_id,
int ret;
u16 length;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
@@ -8762,14 +8711,11 @@ static void ath12k_tm_wmi_event_segmented(struct ath12k_base *ab, u32 cmd_id,
ev = tb[WMI_TAG_ARRAY_BYTE];
if (!ev) {
ath12k_warn(ab, "failed to fetch ftm msg\n");
- kfree(tb);
return;
}
length = skb->len - TLV_HDR_SIZE;
ath12k_tm_process_event(ab, cmd_id, ev, length);
- kfree(tb);
- tb = NULL;
}
static void
@@ -8782,7 +8728,7 @@ ath12k_wmi_pdev_temperature_event(struct ath12k_base *ab,
int temp;
u32 pdev_id;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ath12k_warn(ab, "failed to parse tlv: %ld\n", PTR_ERR(tb));
return;
@@ -8791,15 +8737,12 @@ ath12k_wmi_pdev_temperature_event(struct ath12k_base *ab,
ev = tb[WMI_TAG_PDEV_TEMPERATURE_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch pdev temp ev\n");
- kfree(tb);
return;
}
temp = a_sle32_to_cpu(ev->temp);
pdev_id = le32_to_cpu(ev->pdev_id);
- kfree(tb);
-
ath12k_dbg(ab, ATH12K_DBG_WMI,
"pdev temperature ev temp %d pdev_id %u\n",
temp, pdev_id);
@@ -8826,7 +8769,7 @@ static void ath12k_fils_discovery_event(struct ath12k_base *ab,
const struct wmi_fils_discovery_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab,
@@ -8838,15 +8781,12 @@ static void ath12k_fils_discovery_event(struct ath12k_base *ab,
ev = tb[WMI_TAG_HOST_SWFDA_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch FILS discovery event\n");
- kfree(tb);
return;
}
ath12k_warn(ab,
"FILS discovery frame expected from host for vdev_id: %u, transmission scheduled at %u, next TBTT: %u\n",
ev->vdev_id, ev->fils_tt, ev->tbtt);
-
- kfree(tb);
}
static void ath12k_probe_resp_tx_status_event(struct ath12k_base *ab,
@@ -8856,7 +8796,7 @@ static void ath12k_probe_resp_tx_status_event(struct ath12k_base *ab,
const struct wmi_probe_resp_tx_status_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab,
@@ -8869,7 +8809,6 @@ static void ath12k_probe_resp_tx_status_event(struct ath12k_base *ab,
if (!ev) {
ath12k_warn(ab,
"failed to fetch probe response transmission status event");
- kfree(tb);
return;
}
@@ -8877,8 +8816,6 @@ static void ath12k_probe_resp_tx_status_event(struct ath12k_base *ab,
ath12k_warn(ab,
"Probe response transmission failed for vdev_id %u, status %u\n",
ev->vdev_id, ev->tx_status);
-
- kfree(tb);
}
static int ath12k_wmi_p2p_noa_event(struct ath12k_base *ab,
@@ -8890,7 +8827,7 @@ static int ath12k_wmi_p2p_noa_event(struct ath12k_base *ab,
struct ath12k *ar;
int ret, vdev_id;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse P2P NoA TLV: %d\n", ret);
@@ -8900,10 +8837,8 @@ static int ath12k_wmi_p2p_noa_event(struct ath12k_base *ab,
ev = tb[WMI_TAG_P2P_NOA_EVENT];
noa = tb[WMI_TAG_P2P_NOA_INFO];
- if (!ev || !noa) {
- ret = -EPROTO;
- goto out;
- }
+ if (!ev || !noa)
+ return -EPROTO;
vdev_id = __le32_to_cpu(ev->vdev_id);
@@ -8926,8 +8861,6 @@ static int ath12k_wmi_p2p_noa_event(struct ath12k_base *ab,
unlock:
rcu_read_unlock();
-out:
- kfree(tb);
return ret;
}
@@ -8938,7 +8871,7 @@ static void ath12k_rfkill_state_change_event(struct ath12k_base *ab,
const void **tb;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -8946,10 +8879,8 @@ static void ath12k_rfkill_state_change_event(struct ath12k_base *ab,
}
ev = tb[WMI_TAG_RFKILL_EVENT];
- if (!ev) {
- kfree(tb);
+ if (!ev)
return;
- }
ath12k_dbg(ab, ATH12K_DBG_MAC,
"wmi tlv rfkill state change gpio %d type %d radio_state %d\n",
@@ -8962,7 +8893,6 @@ static void ath12k_rfkill_state_change_event(struct ath12k_base *ab,
spin_unlock_bh(&ab->base_lock);
queue_work(ab->workqueue, &ab->rfkill_work);
- kfree(tb);
}
static void
@@ -8978,7 +8908,7 @@ static void ath12k_wmi_twt_enable_event(struct ath12k_base *ab,
const struct wmi_twt_enable_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse wmi twt enable status event tlv: %d\n",
@@ -8989,15 +8919,12 @@ static void ath12k_wmi_twt_enable_event(struct ath12k_base *ab,
ev = tb[WMI_TAG_TWT_ENABLE_COMPLETE_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch twt enable wmi event\n");
- goto exit;
+ return;
}
ath12k_dbg(ab, ATH12K_DBG_MAC, "wmi twt enable event pdev id %u status %u\n",
le32_to_cpu(ev->pdev_id),
le32_to_cpu(ev->status));
-
-exit:
- kfree(tb);
}
static void ath12k_wmi_twt_disable_event(struct ath12k_base *ab,
@@ -9007,7 +8934,7 @@ static void ath12k_wmi_twt_disable_event(struct ath12k_base *ab,
const struct wmi_twt_disable_event *ev;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse wmi twt disable status event tlv: %d\n",
@@ -9018,15 +8945,12 @@ static void ath12k_wmi_twt_disable_event(struct ath12k_base *ab,
ev = tb[WMI_TAG_TWT_DISABLE_COMPLETE_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch twt disable wmi event\n");
- goto exit;
+ return;
}
ath12k_dbg(ab, ATH12K_DBG_MAC, "wmi twt disable event pdev id %d status %u\n",
le32_to_cpu(ev->pdev_id),
le32_to_cpu(ev->status));
-
-exit:
- kfree(tb);
}
static int ath12k_wmi_wow_wakeup_host_parse(struct ath12k_base *ab,
@@ -9099,7 +9023,7 @@ static void ath12k_wmi_gtk_offload_status_event(struct ath12k_base *ab,
const void **tb;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse tlv: %d\n", ret);
@@ -9109,7 +9033,6 @@ static void ath12k_wmi_gtk_offload_status_event(struct ath12k_base *ab,
ev = tb[WMI_TAG_GTK_OFFLOAD_STATUS_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch gtk offload status ev");
- kfree(tb);
return;
}
@@ -9119,7 +9042,6 @@ static void ath12k_wmi_gtk_offload_status_event(struct ath12k_base *ab,
rcu_read_unlock();
ath12k_warn(ab, "failed to get arvif for vdev_id:%d\n",
le32_to_cpu(ev->vdev_id));
- kfree(tb);
return;
}
@@ -9135,8 +9057,6 @@ static void ath12k_wmi_gtk_offload_status_event(struct ath12k_base *ab,
(void *)&replay_ctr_be, GFP_ATOMIC);
rcu_read_unlock();
-
- kfree(tb);
}
static void ath12k_wmi_event_mlo_setup_complete(struct ath12k_base *ab,
@@ -9148,7 +9068,7 @@ static void ath12k_wmi_event_mlo_setup_complete(struct ath12k_base *ab,
const void **tb;
int ret, i;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse mlo setup complete event tlv: %d\n",
@@ -9159,7 +9079,6 @@ static void ath12k_wmi_event_mlo_setup_complete(struct ath12k_base *ab,
ev = tb[WMI_TAG_MLO_SETUP_COMPLETE_EVENT];
if (!ev) {
ath12k_warn(ab, "failed to fetch mlo setup complete event\n");
- kfree(tb);
return;
}
@@ -9178,14 +9097,11 @@ static void ath12k_wmi_event_mlo_setup_complete(struct ath12k_base *ab,
if (!ar) {
ath12k_warn(ab, "invalid pdev_id %d status %u in setup complete event\n",
ev->pdev_id, ev->status);
- goto out;
+ return;
}
ar->mlo_setup_status = le32_to_cpu(ev->status);
complete(&ar->mlo_setup_done);
-
-out:
- kfree(tb);
}
static void ath12k_wmi_event_teardown_complete(struct ath12k_base *ab,
@@ -9195,7 +9111,7 @@ static void ath12k_wmi_event_teardown_complete(struct ath12k_base *ab,
const void **tb;
int ret;
- tb = ath12k_wmi_tlv_parse_alloc(ab, skb, GFP_ATOMIC);
+ tb = ath12k_wmi_tlv_parse(ab, skb);
if (IS_ERR(tb)) {
ret = PTR_ERR(tb);
ath12k_warn(ab, "failed to parse teardown complete event tlv: %d\n", ret);
@@ -9203,13 +9119,8 @@ static void ath12k_wmi_event_teardown_complete(struct ath12k_base *ab,
}
ev = tb[WMI_TAG_MLO_TEARDOWN_COMPLETE];
- if (!ev) {
+ if (!ev)
ath12k_warn(ab, "failed to fetch teardown complete event\n");
- kfree(tb);
- return;
- }
-
- kfree(tb);
}
#ifdef CONFIG_ATH12K_DEBUGFS
@@ -11239,3 +11150,28 @@ int ath12k_wmi_send_mlo_link_set_active_cmd(struct ath12k_base *ab,
dev_kfree_skb(skb);
return ret;
}
+
+int ath12k_wmi_alloc(void)
+{
+ guard(mutex)(&ath12k_wmi_mutex);
+
+ if (!ath12k_wmi_tb) {
+ ath12k_wmi_tb = __alloc_percpu(WMI_TAG_MAX * sizeof(void *),
+ __alignof__(void *));
+ if (!ath12k_wmi_tb)
+ return -ENOMEM;
+ }
+
+ refcount_inc(&ath12k_wmi_refcount);
+ return 0;
+}
+
+void ath12k_wmi_free(void)
+{
+ guard(mutex)(&ath12k_wmi_mutex);
+
+ if (refcount_dec_and_test(&ath12k_wmi_refcount)) {
+ free_percpu(ath12k_wmi_tb);
+ ath12k_wmi_tb = NULL;
+ }
+}
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index 5ba9b7d3a888..4a34b2ca99ea 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -6576,4 +6576,7 @@ int ath12k_wmi_send_vdev_set_tpc_power(struct ath12k *ar,
struct ath12k_reg_tpc_power_info *param);
int ath12k_wmi_send_mlo_link_set_active_cmd(struct ath12k_base *ab,
struct wmi_mlo_link_set_active_arg *param);
+int ath12k_wmi_alloc(void);
+void ath12k_wmi_free(void);
+
#endif
--
2.53.0
^ permalink raw reply related
* [PATCH] rtlwifi: rtl8821ae: Remove dead code in rtl8821ae_update_hal_rate_table()
From: Chelsy Ratnawat @ 2026-04-03 16:54 UTC (permalink / raw)
To: pkshih; +Cc: johannes.berg, bhelgaas, linux-wireless, Chelsy Ratnawat
The variable 'mimo_ps' is initialized to IEEE80211_SMPS_OFF and never
modified throughout the function. This makes the condition checking for
IEEE80211_SMPS_STATIC always evaluate to false, rendering the entire
if-branch unreachable dead code.
The error was reported by Coverity Scan.
Signed-off-by: Chelsy Ratnawat <chelsyratnawat2001@gmail.com>
---
.../wireless/realtek/rtlwifi/rtl8821ae/hw.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
index 3a4a33476205..81d36041a79b 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
@@ -3257,7 +3257,6 @@ static void rtl8821ae_update_hal_rate_table(struct ieee80211_hw *hw,
u32 ratr_value;
u8 ratr_index = 0;
u8 b_nmode = mac->ht_enable;
- u8 mimo_ps = IEEE80211_SMPS_OFF;
u16 shortgi_rate;
u32 tmp_ratr_value;
u8 curtxbw_40mhz = mac->bw_40;
@@ -3288,19 +3287,15 @@ static void rtl8821ae_update_hal_rate_table(struct ieee80211_hw *hw,
case WIRELESS_MODE_N_24G:
case WIRELESS_MODE_N_5G:
b_nmode = 1;
- if (mimo_ps == IEEE80211_SMPS_STATIC) {
- ratr_value &= 0x0007F005;
- } else {
- u32 ratr_mask;
+ u32 ratr_mask;
- if (get_rf_type(rtlphy) == RF_1T2R ||
- get_rf_type(rtlphy) == RF_1T1R)
- ratr_mask = 0x000ff005;
- else
- ratr_mask = 0x0f0ff005;
+ if (get_rf_type(rtlphy) == RF_1T2R ||
+ get_rf_type(rtlphy) == RF_1T1R)
+ ratr_mask = 0x000ff005;
+ else
+ ratr_mask = 0x0f0ff005;
- ratr_value &= ratr_mask;
- }
+ ratr_value &= ratr_mask;
break;
default:
if (rtlphy->rf_type == RF_1T2R)
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v2 4/7] arm64: dts: qcom: milos: Split up uart11 pinctrl
From: Dmitry Baryshkov @ 2026-04-03 19:32 UTC (permalink / raw)
To: Luca Weiss
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Alexander Koskovich, Liam Girdwood, Mark Brown,
Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
Balakrishna Godavarthi, Rocky Liao, Johannes Berg, Jeff Johnson,
~postmarketos/upstreaming, phone-devel, linux-arm-msm,
linux-kernel, devicetree, linux-bluetooth, linux-wireless, ath11k
In-Reply-To: <20260403-milos-fp6-bt-wifi-v2-4-393322b27c5f@fairphone.com>
On Fri, Apr 03, 2026 at 03:52:50PM +0200, Luca Weiss wrote:
> In order to set the pinctrl for the individual CTS, RTS, TX and RX pins,
> split up the pinctrl configuration into 4 nodes so that boards can set
> some properties separately.
>
> Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
> ---
> arch/arm64/boot/dts/qcom/milos.dtsi | 28 ++++++++++++++++++----------
> 1 file changed, 18 insertions(+), 10 deletions(-)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH v2 5/7] arm64: dts: qcom: milos: Add WCN6755 WiFi node
From: Dmitry Baryshkov @ 2026-04-03 19:33 UTC (permalink / raw)
To: Luca Weiss
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Alexander Koskovich, Liam Girdwood, Mark Brown,
Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
Balakrishna Godavarthi, Rocky Liao, Johannes Berg, Jeff Johnson,
~postmarketos/upstreaming, phone-devel, linux-arm-msm,
linux-kernel, devicetree, linux-bluetooth, linux-wireless, ath11k
In-Reply-To: <20260403-milos-fp6-bt-wifi-v2-5-393322b27c5f@fairphone.com>
On Fri, Apr 03, 2026 at 03:52:51PM +0200, Luca Weiss wrote:
> Add a node for the WCN6755 WiFi found with the Milos SoC.
>
> Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
> ---
> arch/arm64/boot/dts/qcom/milos.dtsi | 46 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 46 insertions(+)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply
* [PATCH] wifi: brcmsmac: phy_lcn: Remove dead code in wlc_lcnphy_radio_2064_channel_tune_4313()
From: Chelsy Ratnawat @ 2026-04-03 19:33 UTC (permalink / raw)
To: arend.vanspriel
Cc: linux-wireless, brcm80211, brcm80211-dev-list.pdl,
Chelsy Ratnawat
The variable rfpll_doubler is initialized to 0 and then unconditionally
set to 1 on the very next line, making the subsequent check for
!rfpll_doubler always evaluate to false. This results in logically
dead code that has never been executed.
Remove the unused variable, the unreachable conditional branch, and
simplify the fpfd calculation to directly use the PLL doubler values.
Signed-off-by: Chelsy Ratnawat <chelsyratnawat2001@gmail.com>
---
.../broadcom/brcm80211/brcmsmac/phy/phy_lcn.c | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c
index 8cec5ad79fda..d65a68045ca8 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -1607,7 +1607,6 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
{
uint i;
const struct chan_info_2064_lcnphy *ci;
- u8 rfpll_doubler = 0;
u8 pll_pwrup, pll_pwrup_ovr;
s32 qFcal;
u8 d15, d16, f16, e44, e45;
@@ -1618,18 +1617,12 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
u16 g30, d28;
ci = &chan_info_2064_lcnphy[0];
- rfpll_doubler = 1;
mod_radio_reg(pi, RADIO_2064_REG09D, 0x4, 0x1 << 2);
write_radio_reg(pi, RADIO_2064_REG09E, 0xf);
- if (!rfpll_doubler) {
- loop_bw = PLL_2064_LOOP_BW;
- d30 = PLL_2064_D30;
- } else {
- loop_bw = PLL_2064_LOOP_BW_DOUBLER;
- d30 = PLL_2064_D30_DOUBLER;
- }
+ loop_bw = PLL_2064_LOOP_BW_DOUBLER;
+ d30 = PLL_2064_D30_DOUBLER;
if (CHSPEC_IS2G(pi->radio_chanspec)) {
for (i = 0; i < ARRAY_SIZE(chan_info_2064_lcnphy); i++)
@@ -1669,7 +1662,7 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
e44 = 0;
e45 = 0;
- fpfd = rfpll_doubler ? (pi->xtalfreq << 1) : (pi->xtalfreq);
+ fpfd = pi->xtalfreq << 1;
if (pi->xtalfreq > 26000000)
e44 = 1;
if (pi->xtalfreq > 52000000)
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v2 6/7] arm64: dts: qcom: milos-fairphone-fp6: Enable Bluetooth
From: Dmitry Baryshkov @ 2026-04-03 19:33 UTC (permalink / raw)
To: Luca Weiss
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Alexander Koskovich, Liam Girdwood, Mark Brown,
Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
Balakrishna Godavarthi, Rocky Liao, Johannes Berg, Jeff Johnson,
~postmarketos/upstreaming, phone-devel, linux-arm-msm,
linux-kernel, devicetree, linux-bluetooth, linux-wireless, ath11k
In-Reply-To: <20260403-milos-fp6-bt-wifi-v2-6-393322b27c5f@fairphone.com>
On Fri, Apr 03, 2026 at 03:52:52PM +0200, Luca Weiss wrote:
> Add the nodes to describe the WCN6755 chip with its PMU and Bluetooth
> parts.
>
> Thanks to Alexander Koskovich for helping with the bringup, adding
> 'clocks' to the PMU node to make Bluetooth work.
>
> Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
> ---
> arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts | 174 +++++++++++++++++++++++
> 1 file changed, 174 insertions(+)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH v2 7/7] arm64: dts: qcom: milos-fairphone-fp6: Enable WiFi
From: Dmitry Baryshkov @ 2026-04-03 19:35 UTC (permalink / raw)
To: Luca Weiss
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Alexander Koskovich, Liam Girdwood, Mark Brown,
Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
Balakrishna Godavarthi, Rocky Liao, Johannes Berg, Jeff Johnson,
~postmarketos/upstreaming, phone-devel, linux-arm-msm,
linux-kernel, devicetree, linux-bluetooth, linux-wireless, ath11k
In-Reply-To: <20260403-milos-fp6-bt-wifi-v2-7-393322b27c5f@fairphone.com>
On Fri, Apr 03, 2026 at 03:52:53PM +0200, Luca Weiss wrote:
> Configure and enable the WiFi node, and add the required pinctrl to
> provide the sleep clock from the PMK8550 (PMK7635) to WCN6755.
>
> Thanks to Alexander Koskovich for helping with the bringup, adding
> the missing pinctrl to make the WPSS stop crashing.
>
> Link: https://lore.kernel.org/linux-arm-msm/DBF7OWAWQ94M.FSCP4DPF8ZJY@fairphone.com/
> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
> Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
> ---
> arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts | 19 ++++++++++++++++++-
> 1 file changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts b/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts
> index db72418b7195..d8ac495ca7c8 100644
> --- a/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts
> +++ b/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts
> @@ -242,7 +242,7 @@ wcn6750-pmu {
>
> clocks = <&rpmhcc RPMH_RF_CLK1>;
>
> - pinctrl-0 = <&bluetooth_enable_default>;
> + pinctrl-0 = <&bluetooth_enable_default>, <&pmk8550_sleep_clk_default>;
> pinctrl-names = "default";
>
> regulators {
> @@ -766,6 +766,17 @@ &pmiv0104_eusb2_repeater {
> qcom,tune-usb2-preem = /bits/ 8 <0x6>;
> };
>
> +&pmk8550_gpios {
> + pmk8550_sleep_clk_default: sleep-clk-default-state {
> + pins = "gpio5";
> + function = "func1";
> + input-disable;
> + output-enable;
Hmm, if it's a sleep_clk, should it not be handled via the power
sequencer?
> + bias-disable;
> + power-source = <0>;
> + };
> +};
> +
> &pmr735b_gpios {
> s1j_enable_default: s1j-enable-default-state {
> pins = "gpio1";
> @@ -1049,3 +1060,9 @@ &usb_1_hsphy {
>
> status = "okay";
> };
> +
> +&wifi {
> + qcom,calibration-variant = "Fairphone_Gen_6";
> +
> + status = "okay";
> +};
>
> --
> 2.53.0
>
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [BUG] wifi: rtw88: Hard system freeze on RTL8821CE when power_save is enabled (LPS/ASPM conflict)
From: LB F @ 2026-04-03 21:47 UTC (permalink / raw)
To: Ping-Ke Shih
Cc: Bitterblue Smith, linux-wireless@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <5fb2f699626b483b8a0a537960b274f0@realtek.com>
Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
> If we can't find the reason for these weird frames, maybe the best
> way to filter them out is to check RTW_RX_DESC_W0_DRV_INFO_SIZE.
Hi Bitterblue, Ping-Ke,
I have a new crash to report that shows a different failure mode
from the garbage RX data, with some characteristics I haven't
seen before.
=== NEW INCIDENT: 2026-04-03 ===
The system froze approximately 1 second after Wi-Fi association
on a fresh cold boot (not resume from hibernation). Hard power-off
was required.
Timeline:
17:16:16 Cold boot (PM: Image not found — no hibernation image)
17:16:38 wlan0 associated with AP (6c:68:a4:1c:97:5b)
17:16:39 First "pci bus timeout" + mac80211 WARNING
17:16:39-17:17:00 System frozen, hard reset required
Kernel: 6.19.10-1-cachyos (PREEMPT full, Clang/LLVM)
Patches applied: DMI quirk (ASPM+LPS disabled), rate validation v2,
Bitterblue's diagnostic hex dump in query_phy_status.
=== THREE DIFFERENCES FROM PREVIOUS CRASHES ===
1) Zero "unused phy status page" events.
Every previous incident had a burst of these messages before
or during the crash. This time there were none at all. The
corrupted data appears to have gone straight to mac80211 without
triggering query_phy_status — likely because PHYST=0 in the
corrupted descriptors, so the diagnostic hex dump never fired.
2) Cold boot, 1 second after initial association.
All previous crashes occurred after minutes to hours of uptime
or shortly after hibernation resume. This one happened on a
fresh boot before any power-state transition. ASPM and LPS Deep
were already disabled by the DMI quirk.
3) Hang mechanism: infinite "pci bus timeout" loop.
Not the NULL dereference (Bug 221286) and not the ASPM deadlock
(Bug 221195). The loop produced 547 "pci bus timeout" messages
and 41 mac80211 WARNINGs over 21 seconds.
=== HANG MECHANISM (my reading of the code, please correct if wrong) ===
The crash appears to follow this sequence in rtw_pci_rx_napi():
while (count--) {
rtw_pci_dma_check(rtwdev, ring, cur_rp); // [A]
...
rtw_rx_query_rx_desc(rtwdev, rx_desc, ...); // [B]
...
ieee80211_rx_napi(rtwdev->hw, NULL, new, napi); // [C]
}
At [A], rtw_pci_dma_check() detects an RX tag mismatch and prints
the warning, but returns void and the loop continues. At [B], since
PHYST=0, query_phy_status is not called. At [C], the garbage frame
reaches ieee80211_rx_list(), triggering WARNING at rx.c:896.
The RBP values across the 41 WARNING traces form a monotonically
increasing sequence from 0x55 to 0x1FF, which looks like cur_rp
cycling through the ring. Once exhausted, rtw_pci_get_hw_rx_ring_nr()
reads more entries from hardware (which is in a bad state), and the
loop restarts. The NAPI poll never returns.
The execution context migrated from irq/58-rtw_pci (PID 635,
170 traces) to ksoftirqd/1 (PID 26, 216 traces) as the softirq
was deferred, but the loop continued in both.
=== FIRST WARNING (full trace) ===
WARNING: net/mac80211/rx.c:896 at ieee80211_rx_list+0x1033/0x1040
[mac80211], CPU#1: irq/58-rtw_pci/635
RAX: 0000000000020100 RBX: 0000000000000000 RCX: 0000000000000004
RDX: 0000000000000000 RSI: ffff8e56c7bb2f18 RDI: 0000000000000000
RBP: 0000000000000055 R08: 0000000000000004 R09: 0000000000000000
Call Trace:
<IRQ>
ieee80211_rx_napi+0x51/0xe0 [mac80211]
rtw_pci_rx_napi+0x2fd/0x400 [rtw_pci]
rtw_pci_napi_poll+0x79/0x1d0 [rtw_pci]
net_rx_action+0x195/0x290
handle_softirqs+0x12d/0x1c0
do_softirq+0x56/0x70
</IRQ>
<TASK>
__local_bh_enable_ip.cold+0xc/0x11
rtw_pci_interrupt_threadfn+0x270/0x360 [rtw_pci]
irq_thread_fn+0x24/0x50
irq_thread+0xbc/0x160
kthread+0x205/0x280
</TASK>
=== NAIVE HARDENING IDEA (please ignore if this is wrong) ===
I am not a kernel developer and I may be misreading the code, but
I wondered if making rtw_pci_dma_check() return a value and
skipping the frame on tag mismatch might prevent the infinite loop,
independently of the DRV_INFO_SIZE filter. Something along these
lines:
--- a/drivers/net/wireless/realtek/rtw88/pci.c
+++ b/drivers/net/wireless/realtek/rtw88/pci.c
-static void rtw_pci_dma_check(struct rtw_dev *rtwdev,
+static bool rtw_pci_dma_check(struct rtw_dev *rtwdev,
struct rtw_pci_rx_ring *rx_ring,
u32 idx)
{
- if (total_pkt_size != rtwpci->rx_tag)
+ if (total_pkt_size != rtwpci->rx_tag) {
rtw_warn(rtwdev, "pci bus timeout, check dma status\n");
+ return false;
+ }
rtwpci->rx_tag = (rtwpci->rx_tag + 1) % RX_TAG_MAX;
+ return true;
}
while (count--) {
- rtw_pci_dma_check(rtwdev, ring, cur_rp);
+ if (!rtw_pci_dma_check(rtwdev, ring, cur_rp))
+ goto next_rp;
I am sure there are considerations I am missing. Please treat this
only as a description of what I observed, not as a proposed patch.
=== SUMMARY ===
The garbage RX data from this chip now appears to cause at least
three distinct failure modes:
1) Bug 221195: ASPM/LPS deadlock (fixed by DMI quirk)
2) Bug 221286: NULL dereference via C2H_ADAPTIVITY misinterpretation
3) This incident: infinite loop triggered by DMA tag mismatch
I wanted to report this new failure mode in case it is useful for
your work on the DRV_INFO_SIZE filter. I can provide the full dmesg
from this crash (7828 lines) if it would be helpful — just let me
know.
Best regards,
Oleksandr Havrylov
^ permalink raw reply
* [PATCH ath-next] wifi: ath11k: cancel SSR work items during PCI shutdown
From: Wei Zhang @ 2026-04-04 4:30 UTC (permalink / raw)
To: jeff.johnson; +Cc: ath11k, linux-wireless, linux-kernel, Wei Zhang
A reboot can crash the kernel if it overlaps with WLAN firmware crash
recovery (SSR). The crash is a NULL pointer dereference in the MHI teardown
path while freeing DMA-backed MHI contexts.
Simplified trace:
dma_free_attrs
mhi_deinit_dev_ctxt [mhi]
ath11k_pci_power_down [ath11k_pci]
ath11k_pci_shutdown [ath11k_pci]
device_shutdown
kernel_restart
On the host side, SSR is driven by the MHI RDDM callback, which queues
reset_work to perform device recovery. reset_work power-cycles the device
by calling ath11k_hif_power_down() followed by ath11k_hif_power_up(). The
power-down phase deinitializes MHI and frees DMA resources.
Shutdown/reboot runs fully asynchronously with this RDDM-driven SSR
recovery flow. As a result, the shutdown path
(ath11k_pci_shutdown() -> ath11k_pci_power_down()) can race with the SSR
recovery sequence.
Fix this by canceling SSR-related work items during PCI shutdown, marking
the device as unregistering, and serializing the RDDM callback path that
checks and queues reset_work. This ensures that no new SSR recovery work
can be queued once teardown has started, and that any in-flight recovery
work is fully synchronized before device power-down, preventing MHI
teardown and DMA resource freeing from running more than once.
Note: This issue only affects PCI/MHI-based devices. AHB-based ath11k
devices do not queue reset_work in normal SSR flows.
Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-04866.5-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1
Fixes: 13da397f884d ("ath11k: add support for device recovery for QCA6390/WCN6855")
Fixes: 5edbb148bc57 ("wifi: ath11k: Add firmware coredump collection support")
Signed-off-by: Wei Zhang <wei.zhang@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath11k/mhi.c | 4 +++-
drivers/net/wireless/ath/ath11k/pci.c | 8 ++++++++
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c
index f994233df2bb..a6c9ff112c68 100644
--- a/drivers/net/wireless/ath/ath11k/mhi.c
+++ b/drivers/net/wireless/ath/ath11k/mhi.c
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BSD-3-Clause-Clear
/*
* Copyright (c) 2020 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/msi.h>
@@ -282,8 +282,10 @@ static void ath11k_mhi_op_status_cb(struct mhi_controller *mhi_cntrl,
break;
}
+ spin_lock_bh(&ab->base_lock);
if (!(test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)))
queue_work(ab->workqueue_aux, &ab->reset_work);
+ spin_unlock_bh(&ab->base_lock);
break;
default:
diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c
index 7114eca8810d..35bb9e7a63a2 100644
--- a/drivers/net/wireless/ath/ath11k/pci.c
+++ b/drivers/net/wireless/ath/ath11k/pci.c
@@ -1210,6 +1210,14 @@ static void ath11k_pci_shutdown(struct pci_dev *pdev)
struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
ath11k_pci_set_irq_affinity_hint(ab_pci, NULL);
+
+ spin_lock_bh(&ab->base_lock);
+ set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags);
+ spin_unlock_bh(&ab->base_lock);
+
+ cancel_work_sync(&ab->reset_work);
+ cancel_work_sync(&ab->dump_work);
+
ath11k_pci_power_down(ab, false);
}
base-commit: 15551ababf6d4e857f2101366a0c3eaa86dd822c
--
2.34.1
^ permalink raw reply related
* Re: [PATCH ath-next v4 0/6] wifi: ath12k: Enable IPQ5424 AHB WiFi device
From: Krzysztof Kozlowski @ 2026-04-04 5:23 UTC (permalink / raw)
To: Baochen Qiang, Raj Kumar Bhagat, Johannes Berg, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jeff Johnson
Cc: linux-wireless, devicetree, linux-kernel, ath12k,
Saravanakumar Duraisamy, Sowmiya Sree Elavalagan
In-Reply-To: <5a606f7d-6665-4b0c-bbbe-32538b2315b6@oss.qualcomm.com>
On 03/04/2026 11:13, Baochen Qiang wrote:
>>
>> .../bindings/net/wireless/qcom,ipq5332-wifi.yaml | 1 +
>> drivers/net/wireless/ath/ath12k/ahb.c | 36 +++++----
>> drivers/net/wireless/ath/ath12k/ahb.h | 1 +
>> drivers/net/wireless/ath/ath12k/ce.h | 13 ++-
>> drivers/net/wireless/ath/ath12k/core.h | 1 +
>> drivers/net/wireless/ath/ath12k/wifi7/ahb.c | 8 ++
>> drivers/net/wireless/ath/ath12k/wifi7/hal.c | 7 ++
>> drivers/net/wireless/ath/ath12k/wifi7/hal.h | 3 +
>> .../net/wireless/ath/ath12k/wifi7/hal_qcn9274.c | 88 ++++++++++++++++++++
>> .../net/wireless/ath/ath12k/wifi7/hal_qcn9274.h | 1 +
>> drivers/net/wireless/ath/ath12k/wifi7/hw.c | 93 +++++++++++++++++++++-
>> 11 files changed, 231 insertions(+), 21 deletions(-)
>> ---
>> base-commit: 15551ababf6d4e857f2101366a0c3eaa86dd822c
>> change-id: 20260331-ath12k-ipq5424-cddb63a46a97
>>
>
> only nit in patch 2/6, so for patches 2-6/6:
>
> Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
It does not work like this. Replying to cover letter causes that all
patches will get it. Provide detailed review and response to each email
in such case.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH ath-next v6] wifi: ath12k: avoid dynamic alloc when parsing wmi tb
From: Rameshkumar Sundaram @ 2026-04-04 9:48 UTC (permalink / raw)
To: Nicolas Escande, ath12k; +Cc: linux-wireless
In-Reply-To: <20260403142841.1105780-1-nico.escande@gmail.com>
On 4/3/2026 7:58 PM, Nicolas Escande wrote:
> On each WMI message received from the hardware, we alloc a temporary array
> of WMI_TAG_MAX entries of type void *. This array is then populated with
> pointers of parsed structs depending on the WMI type, and then freed. This
> alloc can fail when memory pressure in the system is high enough.
>
> Given the fact that it is scheduled in softirq with the system_bh_wq, we
> should not be able to parse more than one WMI message per CPU at any time.
>
> So instead lets move to a per cpu allocated array, that is reused across
> calls. This memory is allocated as needed and refcounted to exist only
> as long as one struct ath12k_base lives.
>
> ath12k_wmi_tlv_parse_alloc() and ath12k_wmi_tlv_parse() are merged
> together as it no longer allocs mem but returns the existing per-cpu one.
>
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00218-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
> ---
> changes from v4:
> - moved to a single instance, refcounted per cpu memory alloc
>
> changes from v3:
> - simplified ath12k_core_init() with a single statement
> - move perpcu.h include directly to wmi.c
>
> changes from v2:
> - removed now superfluous return in ath12k_wmi_event_teardown_complete()
> - moved ath12k_wmi_tb declaration to wmi.c & added two functions to
> alloc / free it
> - removed useless error message on memory allocation failure
>
> changes from v1:
> - rebased on ath-next 27401c9b1432
> - changed wording according to Jeff's comment
> - moved alloc/cleanup to new module_init/exit functions in the
> ath12k module as per Baochen's comment
>
> changes from RFC:
> - rebased on ath-next 8e0ab5b9adb7
> - converted missing call sites ath12k_wmi_obss_color_collision_event()
> & ath12k_wmi_pdev_temperature_event()
> - changed alloc order & cleanup path in ath12k_core_alloc() as it seems
> it confused people
> - used sizeof(*tb) in ath12k_wmi_tlv_parse()
> ---
> drivers/net/wireless/ath/ath12k/core.c | 6 +
> drivers/net/wireless/ath/ath12k/wmi.c | 214 +++++++++----------------
> drivers/net/wireless/ath/ath12k/wmi.h | 3 +
> 3 files changed, 84 insertions(+), 139 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
> index c31c47fb5a73..6f0f4bfbf699 100644
> --- a/drivers/net/wireless/ath/ath12k/core.c
> +++ b/drivers/net/wireless/ath/ath12k/core.c
> @@ -2256,6 +2256,7 @@ void ath12k_core_deinit(struct ath12k_base *ab)
> void ath12k_core_free(struct ath12k_base *ab)
> {
> timer_delete_sync(&ab->rx_replenish_retry);
> + ath12k_wmi_free();
> destroy_workqueue(ab->workqueue_aux);
> destroy_workqueue(ab->workqueue);
> kfree(ab);
> @@ -2280,6 +2281,9 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size,
> if (!ab->workqueue_aux)
> goto err_free_wq;
>
> + if (ath12k_wmi_alloc() < 0)
> + goto err_free_wq_aux;
> +
> mutex_init(&ab->core_lock);
> spin_lock_init(&ab->base_lock);
> init_completion(&ab->reset_complete);
> @@ -2314,6 +2318,8 @@ struct ath12k_base *ath12k_core_alloc(struct device *dev, size_t priv_size,
>
> return ab;
>
> +err_free_wq_aux:
> + destroy_workqueue(ab->workqueue_aux);
> err_free_wq:
> destroy_workqueue(ab->workqueue);
> err_sc_free:
> diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
> index 65a05a9520ff..2641a76e9543 100644
> --- a/drivers/net/wireless/ath/ath12k/wmi.c
> +++ b/drivers/net/wireless/ath/ath12k/wmi.c
> @@ -15,6 +15,8 @@
> #include <linux/time.h>
> #include <linux/of.h>
> #include <linux/cleanup.h>
> +#include <linux/percpu.h>
> +#include <linux/refcount.h>
> #include "core.h"
> #include "debugfs.h"
> #include "debug.h"
> @@ -134,6 +136,10 @@ struct wmi_pdev_set_obss_bitmap_arg {
> const char *label;
> };
>
> +static DEFINE_MUTEX(ath12k_wmi_mutex);
> +static refcount_t ath12k_wmi_refcount = REFCOUNT_INIT(0);
> +static void __percpu *ath12k_wmi_tb = NULL;
Checkpatch complains:
drivers/net/wireless/ath/ath12k/wmi.c:141: do not initialise statics to NULL
> +
> static const struct ath12k_wmi_tlv_policy ath12k_wmi_tlv_policies[] = {
> [WMI_TAG_ARRAY_BYTE] = { .min_len = 0 },
> [WMI_TAG_ARRAY_UINT32] = { .min_len = 0 },
> @@ -289,29 +295,19 @@ static int ath12k_wmi_tlv_iter_parse(struct ath12k_base *ab, u16 tag, u16 len,
> return 0;
> }
>
{...}
> #ifdef CONFIG_ATH12K_DEBUGFS
> @@ -11239,3 +11150,28 @@ int ath12k_wmi_send_mlo_link_set_active_cmd(struct ath12k_base *ab,
> dev_kfree_skb(skb);
> return ret;
> }
> +
> +int ath12k_wmi_alloc(void)
> +{
> + guard(mutex)(&ath12k_wmi_mutex);
> +
> + if (!ath12k_wmi_tb) {
> + ath12k_wmi_tb = __alloc_percpu(WMI_TAG_MAX * sizeof(void *),
> + __alignof__(void *));
> + if (!ath12k_wmi_tb)
> + return -ENOMEM;
> + }
> +
> + refcount_inc(&ath12k_wmi_refcount);
With ath12k_wmi_refcount initialized to zero, this will trigger addition
on 0 - use-after-free warning in refcount.
We may have to do refcount_set(&ath12k_wmi_refcount, 1); on tb alloc.
> + return 0;
> +}
> +
> +void ath12k_wmi_free(void)
> +{
> + guard(mutex)(&ath12k_wmi_mutex);
> +
> + if (refcount_dec_and_test(&ath12k_wmi_refcount)) {
> + free_percpu(ath12k_wmi_tb);
> + ath12k_wmi_tb = NULL;
> + }
> +}
> diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
> index 5ba9b7d3a888..4a34b2ca99ea 100644
> --- a/drivers/net/wireless/ath/ath12k/wmi.h
> +++ b/drivers/net/wireless/ath/ath12k/wmi.h
> @@ -6576,4 +6576,7 @@ int ath12k_wmi_send_vdev_set_tpc_power(struct ath12k *ar,
> struct ath12k_reg_tpc_power_info *param);
> int ath12k_wmi_send_mlo_link_set_active_cmd(struct ath12k_base *ab,
> struct wmi_mlo_link_set_active_arg *param);
> +int ath12k_wmi_alloc(void);
> +void ath12k_wmi_free(void);
> +
> #endif
--
Ramesh
^ permalink raw reply
* Re: [BUG] wifi: rtw88: Hard system freeze on RTL8821CE when power_save is enabled (LPS/ASPM conflict)
From: LB F @ 2026-04-04 10:44 UTC (permalink / raw)
To: Ping-Ke Shih
Cc: Bitterblue Smith, linux-wireless@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <CALdGYqThUD1DSAcsshC0y4Lm=uG=EDvBccMqkL=qr2+Jajp4tg@mail.gmail.com>
Hi Bitterblue, Ping-Ke,
I need to correct an error in my previous message. I wrote that
Ping-Ke's rate validation v2 patch (DESC_RATE_MAX clamp in
rtw_rx_query_rx_desc) was applied during the crash — it was not.
When I checked the source with `git diff`, rx.c turned out to be
completely unmodified. I sincerely apologize for the confusion.
At the time of the April 3rd crash, only two patches were active:
- Ping-Ke's DMI quirk (ASPM + LPS Deep disabled)
- Bitterblue's diagnostic hex dump in query_phy_status
The rate validation patch has now been re-applied and verified
in the running system.
That said, I believe this particular crash was not caused by the
missing rate validation. The mac80211 WARNING in the crash fires
at rx.c:896 (ieee80211_rx_list+0x1033), not at rx.c:5491 (the
VHT NSS=0 check that rate validation addresses). The system hang
itself was caused by the DMA tag mismatch loop in
rtw_pci_dma_check(), which is independent of rate handling.
Again, I am very sorry for the inaccuracy. I will be more careful
verifying applied patches before reporting in the future.
Best regards,
Oleksandr Havrylov
^ permalink raw reply
* Re: [PATCH v2 1/7] regulator: dt-bindings: qcom,qca6390-pmu: Document WCN6755 PMU
From: Krzysztof Kozlowski @ 2026-04-04 10:57 UTC (permalink / raw)
To: Luca Weiss
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Alexander Koskovich, Liam Girdwood, Mark Brown,
Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
Balakrishna Godavarthi, Rocky Liao, Johannes Berg, Jeff Johnson,
~postmarketos/upstreaming, phone-devel, linux-arm-msm,
linux-kernel, devicetree, linux-bluetooth, linux-wireless, ath11k
In-Reply-To: <20260403-milos-fp6-bt-wifi-v2-1-393322b27c5f@fairphone.com>
On Fri, Apr 03, 2026 at 03:52:47PM +0200, Luca Weiss wrote:
> Document the WCN6755 PMU using a fallback to WCN6750 since the two chips
> seem to be completely pin and software compatible. In fact the original
> downstream kernel just pretends the WCN6755 is a WCN6750.
>
> Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
> ---
> .../devicetree/bindings/regulator/qcom,qca6390-pmu.yaml | 16 +++++++++++-----
> 1 file changed, 11 insertions(+), 5 deletions(-)
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v2 2/7] dt-bindings: bluetooth: qcom,wcn6750-bt: Document WCN6755 Bluetooth
From: Krzysztof Kozlowski @ 2026-04-04 10:58 UTC (permalink / raw)
To: Luca Weiss
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Alexander Koskovich, Liam Girdwood, Mark Brown,
Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
Balakrishna Godavarthi, Rocky Liao, Johannes Berg, Jeff Johnson,
~postmarketos/upstreaming, phone-devel, linux-arm-msm,
linux-kernel, devicetree, linux-bluetooth, linux-wireless, ath11k
In-Reply-To: <20260403-milos-fp6-bt-wifi-v2-2-393322b27c5f@fairphone.com>
On Fri, Apr 03, 2026 at 03:52:48PM +0200, Luca Weiss wrote:
> Document the WCN6755 Bluetooth using a fallback to WCN6750 since the two
> chips seem to be completely pin and software compatible. In fact the
> original downstream kernel just pretends the WCN6755 is a WCN6750.
>
> Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
> ---
> .../devicetree/bindings/net/bluetooth/qcom,wcn6750-bt.yaml | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v2 3/7] dt-bindings: net: wireless: ath11k: Document WCN6755 WiFi
From: Krzysztof Kozlowski @ 2026-04-04 11:03 UTC (permalink / raw)
To: Luca Weiss
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Alexander Koskovich, Liam Girdwood, Mark Brown,
Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
Balakrishna Godavarthi, Rocky Liao, Johannes Berg, Jeff Johnson,
~postmarketos/upstreaming, phone-devel, linux-arm-msm,
linux-kernel, devicetree, linux-bluetooth, linux-wireless, ath11k
In-Reply-To: <20260403-milos-fp6-bt-wifi-v2-3-393322b27c5f@fairphone.com>
On Fri, Apr 03, 2026 at 03:52:49PM +0200, Luca Weiss wrote:
> Document the WCN6755 WiFi using a fallback to WCN6750 since the two
> chips seem to be completely pin and software compatible. In fact the
> original downstream kernel just pretends the WCN6755 is a WCN6750.
>
> Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
> ---
> .../devicetree/bindings/net/wireless/qcom,ath11k.yaml | 16 +++++++++++-----
> 1 file changed, 11 insertions(+), 5 deletions(-)
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH rtw-next 01/12] wifi: rtw89: usb: Disable MLO for now
From: Bitterblue Smith @ 2026-04-04 14:07 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless@vger.kernel.org
In-Reply-To: <dbd41cc160504b8daeb93b7967101c7f@realtek.com>
On 30/03/2026 05:59, Ping-Ke Shih wrote:
> Bitterblue Smith <rtl8821cerfe2@gmail.com> wrote:
>> It's not yet clear how the TX queue/channel selection is supposed to
>> work for RTL8922AU with MLO, and I can't test MLO anyway.
>
> Currently, rtw89 work in MLSR mode by default, which means it works like
> legacy mode, so it's probably fine to enable MLO.
>
Someone tested MLO now (5 GHz + 6 GHz) so I will drop this patch from v2.
> The debugfs can switch eMLSR mode, but it doesn't work very well for now.
>
>>
>> Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
>> ---
>> drivers/net/wireless/realtek/rtw89/usb.c | 4 ++++
>> 1 file changed, 4 insertions(+)
>>
>> diff --git a/drivers/net/wireless/realtek/rtw89/usb.c
>> b/drivers/net/wireless/realtek/rtw89/usb.c
>> index 581b8c05f930..7a46ace34c25 100644
>> --- a/drivers/net/wireless/realtek/rtw89/usb.c
>> +++ b/drivers/net/wireless/realtek/rtw89/usb.c
>> @@ -1029,6 +1029,10 @@ int rtw89_usb_probe(struct usb_interface *intf,
>> return -ENOMEM;
>> }
>>
>> + rtw89_debug(rtwdev, RTW89_DBG_CHAN,
>> + "%s: disable MLO for now\n", __func__);
>> + rtwdev->support_mlo = false;
>> +
>> rtwusb = rtw89_usb_priv(rtwdev);
>> rtwusb->rtwdev = rtwdev;
>> rtwusb->info = info->bus.usb;
>> --
>> 2.53.0
>
^ permalink raw reply
* [PATCH wireless-next 0/6] Consolidate Michael MIC code into mac80211
From: Eric Biggers @ 2026-04-05 5:27 UTC (permalink / raw)
To: Johannes Berg, linux-wireless
Cc: linux-crypto, linux-kernel, Herbert Xu, Eric Biggers
Michael MIC is an inherently weak algorithm that is specific to WPA
TKIP, which itself was an interim security solution to replace the
broken WEP standard.
Currently, the primary implementation of Michael MIC in the kernel is
the one in the mac80211 module. But there's also a duplicate
implementation in crypto/michael_mic.c which is exposed via the
crypto_shash API. It's used only by a few wireless drivers.
Seeing as Michael MIC is specific to WPA TKIP and should never be used
elsewhere, this series migrates those few drivers to the mac80211
implementation of Michael MIC, then removes the crypto implementation of
Michael MIC. This consolidates duplicate code and prevents other kernel
subsystems from accidentally using this insecure algorithm.
This series is targeting wireless-next.
Eric Biggers (6):
wifi: mac80211: Export michael_mic()
wifi: ath11k: Use michael_mic() from mac80211
wifi: ath12k: Use michael_mic() from mac80211
wifi: ipw2x00: Depend on MAC80211
wifi: ipw2x00: Use michael_mic() from mac80211
crypto: Remove michael_mic from crypto_shash API
arch/arm/configs/omap2plus_defconfig | 1 -
arch/arm/configs/spitz_defconfig | 1 -
arch/arm64/configs/defconfig | 1 -
arch/m68k/configs/amiga_defconfig | 1 -
arch/m68k/configs/apollo_defconfig | 1 -
arch/m68k/configs/atari_defconfig | 1 -
arch/m68k/configs/bvme6000_defconfig | 1 -
arch/m68k/configs/hp300_defconfig | 1 -
arch/m68k/configs/mac_defconfig | 1 -
arch/m68k/configs/multi_defconfig | 1 -
arch/m68k/configs/mvme147_defconfig | 1 -
arch/m68k/configs/mvme16x_defconfig | 1 -
arch/m68k/configs/q40_defconfig | 1 -
arch/m68k/configs/sun3_defconfig | 1 -
arch/m68k/configs/sun3x_defconfig | 1 -
arch/mips/configs/bigsur_defconfig | 1 -
arch/mips/configs/decstation_64_defconfig | 1 -
arch/mips/configs/decstation_defconfig | 1 -
arch/mips/configs/decstation_r4k_defconfig | 1 -
arch/mips/configs/gpr_defconfig | 1 -
arch/mips/configs/ip32_defconfig | 1 -
arch/mips/configs/lemote2f_defconfig | 1 -
arch/mips/configs/malta_qemu_32r6_defconfig | 1 -
arch/mips/configs/maltaaprp_defconfig | 1 -
arch/mips/configs/maltasmvp_defconfig | 1 -
arch/mips/configs/maltasmvp_eva_defconfig | 1 -
arch/mips/configs/maltaup_defconfig | 1 -
arch/mips/configs/mtx1_defconfig | 1 -
arch/mips/configs/rm200_defconfig | 1 -
arch/mips/configs/sb1250_swarm_defconfig | 1 -
arch/parisc/configs/generic-32bit_defconfig | 1 -
arch/parisc/configs/generic-64bit_defconfig | 1 -
arch/powerpc/configs/g5_defconfig | 1 -
arch/powerpc/configs/linkstation_defconfig | 1 -
arch/powerpc/configs/mvme5100_defconfig | 1 -
arch/powerpc/configs/powernv_defconfig | 1 -
arch/powerpc/configs/ppc64_defconfig | 1 -
arch/powerpc/configs/ppc64e_defconfig | 1 -
arch/powerpc/configs/ppc6xx_defconfig | 1 -
arch/powerpc/configs/ps3_defconfig | 1 -
arch/s390/configs/debug_defconfig | 1 -
arch/s390/configs/defconfig | 1 -
arch/sh/configs/sh2007_defconfig | 1 -
arch/sh/configs/titan_defconfig | 1 -
arch/sh/configs/ul2_defconfig | 1 -
arch/sparc/configs/sparc32_defconfig | 1 -
arch/sparc/configs/sparc64_defconfig | 1 -
crypto/Kconfig | 12 --
crypto/Makefile | 1 -
crypto/michael_mic.c | 176 ------------------
crypto/tcrypt.c | 4 -
crypto/testmgr.c | 6 -
crypto/testmgr.h | 50 -----
drivers/net/wireless/ath/ath11k/Kconfig | 1 -
drivers/net/wireless/ath/ath11k/dp.c | 2 -
drivers/net/wireless/ath/ath11k/dp_rx.c | 60 +-----
drivers/net/wireless/ath/ath11k/peer.h | 1 -
drivers/net/wireless/ath/ath12k/Kconfig | 1 -
drivers/net/wireless/ath/ath12k/dp.c | 2 -
drivers/net/wireless/ath/ath12k/dp_peer.h | 1 -
drivers/net/wireless/ath/ath12k/dp_rx.c | 55 +-----
drivers/net/wireless/ath/ath12k/dp_rx.h | 4 -
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 7 +-
drivers/net/wireless/intel/ipw2x00/Kconfig | 7 +-
.../intel/ipw2x00/libipw_crypto_tkip.c | 120 +-----------
include/linux/ieee80211.h | 5 +
net/mac80211/michael.c | 5 +-
net/mac80211/michael.h | 22 ---
net/mac80211/wpa.c | 1 -
69 files changed, 32 insertions(+), 558 deletions(-)
delete mode 100644 crypto/michael_mic.c
delete mode 100644 net/mac80211/michael.h
base-commit: dbd94b9831bc52a1efb7ff3de841ffc3457428ce
--
2.53.0
^ permalink raw reply
* [PATCH wireless-next 1/6] wifi: mac80211: Export michael_mic()
From: Eric Biggers @ 2026-04-05 5:27 UTC (permalink / raw)
To: Johannes Berg, linux-wireless
Cc: linux-crypto, linux-kernel, Herbert Xu, Eric Biggers
In-Reply-To: <20260405052734.130368-1-ebiggers@kernel.org>
Export the michael_mic() function so that it can be reused by the
ath11k, ath12k, and ipw2x00 drivers. Currently they have their own
local implementations of it based on crypto_shash, which is redundant
and inefficient.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
include/linux/ieee80211.h | 5 +++++
net/mac80211/michael.c | 5 ++++-
net/mac80211/michael.h | 22 ----------------------
net/mac80211/wpa.c | 1 -
4 files changed, 9 insertions(+), 24 deletions(-)
delete mode 100644 net/mac80211/michael.h
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index b5d649db123fe..da6fcdc742e7c 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1919,10 +1919,15 @@ enum ieee80211_radio_measurement_actioncode {
#define FILS_ERP_MAX_RRK_LEN 64
#define PMK_MAX_LEN 64
#define SAE_PASSWORD_MAX_LEN 128
+#define MICHAEL_MIC_LEN 8
+
+void michael_mic(const u8 *key, struct ieee80211_hdr *hdr,
+ const u8 *data, size_t data_len, u8 *mic);
+
/* Public action codes (IEEE Std 802.11-2016, 9.6.8.1, Table 9-307) */
enum ieee80211_pub_actioncode {
WLAN_PUB_ACTION_20_40_BSS_COEX = 0,
WLAN_PUB_ACTION_DSE_ENABLEMENT = 1,
WLAN_PUB_ACTION_DSE_DEENABLEMENT = 2,
diff --git a/net/mac80211/michael.c b/net/mac80211/michael.c
index 8a1afc93e7499..50cdb67f0503d 100644
--- a/net/mac80211/michael.c
+++ b/net/mac80211/michael.c
@@ -6,11 +6,13 @@
#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/ieee80211.h>
#include <linux/unaligned.h>
-#include "michael.h"
+struct michael_mic_ctx {
+ u32 l, r;
+};
static void michael_block(struct michael_mic_ctx *mctx, u32 val)
{
mctx->l ^= val;
mctx->r ^= rol32(mctx->l, 17);
@@ -79,5 +81,6 @@ void michael_mic(const u8 *key, struct ieee80211_hdr *hdr,
michael_block(&mctx, 0);
put_unaligned_le32(mctx.l, mic);
put_unaligned_le32(mctx.r, mic + 4);
}
+EXPORT_SYMBOL_GPL(michael_mic);
diff --git a/net/mac80211/michael.h b/net/mac80211/michael.h
deleted file mode 100644
index a7fdb8e84615a..0000000000000
--- a/net/mac80211/michael.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Michael MIC implementation - optimized for TKIP MIC operations
- * Copyright 2002-2003, Instant802 Networks, Inc.
- */
-
-#ifndef MICHAEL_H
-#define MICHAEL_H
-
-#include <linux/types.h>
-#include <linux/ieee80211.h>
-
-#define MICHAEL_MIC_LEN 8
-
-struct michael_mic_ctx {
- u32 l, r;
-};
-
-void michael_mic(const u8 *key, struct ieee80211_hdr *hdr,
- const u8 *data, size_t data_len, u8 *mic);
-
-#endif /* MICHAEL_H */
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 64a57475ce506..724ec831a8857 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -16,11 +16,10 @@
#include <net/mac80211.h>
#include <crypto/aes.h>
#include <crypto/utils.h>
#include "ieee80211_i.h"
-#include "michael.h"
#include "tkip.h"
#include "aes_ccm.h"
#include "aes_cmac.h"
#include "aes_gmac.h"
#include "aes_gcm.h"
--
2.53.0
^ permalink raw reply related
* [PATCH wireless-next 2/6] wifi: ath11k: Use michael_mic() from mac80211
From: Eric Biggers @ 2026-04-05 5:27 UTC (permalink / raw)
To: Johannes Berg, linux-wireless
Cc: linux-crypto, linux-kernel, Herbert Xu, Eric Biggers
In-Reply-To: <20260405052734.130368-1-ebiggers@kernel.org>
Just use the michael_mic() function from mac80211 instead of a local
implementation of it on top of the crypto_shash API.
Preserve the check for fips_enabled which was present implicitly in the
crypto_shash-based code.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
drivers/net/wireless/ath/ath11k/Kconfig | 1 -
drivers/net/wireless/ath/ath11k/dp.c | 2 -
drivers/net/wireless/ath/ath11k/dp_rx.c | 60 +++----------------------
drivers/net/wireless/ath/ath11k/peer.h | 1 -
4 files changed, 7 insertions(+), 57 deletions(-)
diff --git a/drivers/net/wireless/ath/ath11k/Kconfig b/drivers/net/wireless/ath/ath11k/Kconfig
index 47dfd39caa89a..385513cfdc30e 100644
--- a/drivers/net/wireless/ath/ath11k/Kconfig
+++ b/drivers/net/wireless/ath/ath11k/Kconfig
@@ -1,10 +1,9 @@
# SPDX-License-Identifier: BSD-3-Clause-Clear
config ATH11K
tristate "Qualcomm Technologies 802.11ax chipset support"
depends on MAC80211 && HAS_DMA
- select CRYPTO_MICHAEL_MIC
select ATH_COMMON
select QCOM_QMI_HELPERS
help
This module adds support for Qualcomm Technologies 802.11ax family of
chipsets.
diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c
index c940de285276d..bbb86f1651419 100644
--- a/drivers/net/wireless/ath/ath11k/dp.c
+++ b/drivers/net/wireless/ath/ath11k/dp.c
@@ -3,11 +3,10 @@
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
-#include <crypto/hash.h>
#include <linux/export.h>
#include "core.h"
#include "dp_tx.h"
#include "hal_tx.h"
#include "hif.h"
@@ -37,11 +36,10 @@ void ath11k_dp_peer_cleanup(struct ath11k *ar, int vdev_id, const u8 *addr)
return;
}
ath11k_peer_rx_tid_cleanup(ar, peer);
peer->dp_setup_done = false;
- crypto_free_shash(peer->tfm_mmic);
spin_unlock_bh(&ab->base_lock);
}
int ath11k_dp_peer_setup(struct ath11k *ar, int vdev_id, const u8 *addr)
{
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
index 49d959b2e1480..00df93e41fa80 100644
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -2,14 +2,14 @@
/*
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
*/
+#include <linux/fips.h>
#include <linux/ieee80211.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
-#include <crypto/hash.h>
#include "core.h"
#include "debug.h"
#include "debugfs_htt_stats.h"
#include "debugfs_sta.h"
#include "hal_desc.h"
@@ -3181,96 +3181,50 @@ static void ath11k_dp_rx_frag_timer(struct timer_list *timer)
}
int ath11k_peer_rx_frag_setup(struct ath11k *ar, const u8 *peer_mac, int vdev_id)
{
struct ath11k_base *ab = ar->ab;
- struct crypto_shash *tfm;
struct ath11k_peer *peer;
struct dp_rx_tid *rx_tid;
int i;
- tfm = crypto_alloc_shash("michael_mic", 0, 0);
- if (IS_ERR(tfm)) {
- ath11k_warn(ab, "failed to allocate michael_mic shash: %ld\n",
- PTR_ERR(tfm));
- return PTR_ERR(tfm);
+ if (fips_enabled) {
+ ath11k_warn(ab, "Michael MIC is not FIPS-allowed");
+ return -ENOENT;
}
spin_lock_bh(&ab->base_lock);
peer = ath11k_peer_find(ab, vdev_id, peer_mac);
if (!peer) {
ath11k_warn(ab, "failed to find the peer to set up fragment info\n");
spin_unlock_bh(&ab->base_lock);
- crypto_free_shash(tfm);
return -ENOENT;
}
for (i = 0; i <= IEEE80211_NUM_TIDS; i++) {
rx_tid = &peer->rx_tid[i];
rx_tid->ab = ab;
timer_setup(&rx_tid->frag_timer, ath11k_dp_rx_frag_timer, 0);
skb_queue_head_init(&rx_tid->rx_frags);
}
- peer->tfm_mmic = tfm;
peer->dp_setup_done = true;
spin_unlock_bh(&ab->base_lock);
return 0;
}
-static int ath11k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key,
- struct ieee80211_hdr *hdr, u8 *data,
- size_t data_len, u8 *mic)
-{
- SHASH_DESC_ON_STACK(desc, tfm);
- u8 mic_hdr[16] = {};
- u8 tid = 0;
- int ret;
-
- if (!tfm)
- return -EINVAL;
-
- desc->tfm = tfm;
-
- ret = crypto_shash_setkey(tfm, key, 8);
- if (ret)
- goto out;
-
- ret = crypto_shash_init(desc);
- if (ret)
- goto out;
-
- /* TKIP MIC header */
- memcpy(mic_hdr, ieee80211_get_DA(hdr), ETH_ALEN);
- memcpy(mic_hdr + ETH_ALEN, ieee80211_get_SA(hdr), ETH_ALEN);
- if (ieee80211_is_data_qos(hdr->frame_control))
- tid = ieee80211_get_tid(hdr);
- mic_hdr[12] = tid;
-
- ret = crypto_shash_update(desc, mic_hdr, 16);
- if (ret)
- goto out;
- ret = crypto_shash_update(desc, data, data_len);
- if (ret)
- goto out;
- ret = crypto_shash_final(desc, mic);
-out:
- shash_desc_zero(desc);
- return ret;
-}
-
static int ath11k_dp_rx_h_verify_tkip_mic(struct ath11k *ar, struct ath11k_peer *peer,
struct sk_buff *msdu)
{
struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data;
struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu);
struct ieee80211_key_conf *key_conf;
struct ieee80211_hdr *hdr;
u8 mic[IEEE80211_CCMP_MIC_LEN];
- int head_len, tail_len, ret;
+ int head_len, tail_len;
size_t data_len;
u32 hdr_len, hal_rx_desc_sz = ar->ab->hw_params.hal_desc_sz;
u8 *key, *data;
u8 key_idx;
@@ -3292,12 +3246,12 @@ static int ath11k_dp_rx_h_verify_tkip_mic(struct ath11k *ar, struct ath11k_peer
data = msdu->data + head_len;
data_len = msdu->len - head_len - tail_len;
key = &key_conf->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
- ret = ath11k_dp_rx_h_michael_mic(peer->tfm_mmic, key, hdr, data, data_len, mic);
- if (ret || memcmp(mic, data + data_len, IEEE80211_CCMP_MIC_LEN))
+ michael_mic(key, hdr, data, data_len, mic);
+ if (memcmp(mic, data + data_len, IEEE80211_CCMP_MIC_LEN))
goto mic_fail;
return 0;
mic_fail:
diff --git a/drivers/net/wireless/ath/ath11k/peer.h b/drivers/net/wireless/ath/ath11k/peer.h
index 3ad2f3355b14f..f5ef1a27f8f25 100644
--- a/drivers/net/wireless/ath/ath11k/peer.h
+++ b/drivers/net/wireless/ath/ath11k/peer.h
@@ -27,11 +27,10 @@ struct ath11k_peer {
struct rhash_head rhash_addr;
/* Info used in MMIC verification of
* RX fragments
*/
- struct crypto_shash *tfm_mmic;
u8 mcast_keyidx;
u8 ucast_keyidx;
u16 sec_type;
u16 sec_type_grp;
bool is_authorized;
--
2.53.0
^ permalink raw reply related
* [PATCH wireless-next 3/6] wifi: ath12k: Use michael_mic() from mac80211
From: Eric Biggers @ 2026-04-05 5:27 UTC (permalink / raw)
To: Johannes Berg, linux-wireless
Cc: linux-crypto, linux-kernel, Herbert Xu, Eric Biggers
In-Reply-To: <20260405052734.130368-1-ebiggers@kernel.org>
Just use the michael_mic() function from mac80211 instead of a local
implementation of it on top of the crypto_shash API.
Preserve the check for fips_enabled which was present implicitly in the
crypto_shash-based code.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
drivers/net/wireless/ath/ath12k/Kconfig | 1 -
drivers/net/wireless/ath/ath12k/dp.c | 2 -
drivers/net/wireless/ath/ath12k/dp_peer.h | 1 -
drivers/net/wireless/ath/ath12k/dp_rx.c | 55 ++-----------------
drivers/net/wireless/ath/ath12k/dp_rx.h | 4 --
drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c | 7 +--
6 files changed, 8 insertions(+), 62 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/Kconfig b/drivers/net/wireless/ath/ath12k/Kconfig
index 1ea1af1b8f6c5..d39c075758bda 100644
--- a/drivers/net/wireless/ath/ath12k/Kconfig
+++ b/drivers/net/wireless/ath/ath12k/Kconfig
@@ -1,10 +1,9 @@
# SPDX-License-Identifier: BSD-3-Clause-Clear
config ATH12K
tristate "Qualcomm Technologies Wi-Fi 7 support (ath12k)"
depends on MAC80211 && HAS_DMA && PCI
- select CRYPTO_MICHAEL_MIC
select QCOM_QMI_HELPERS
select MHI_BUS
select QRTR
select QRTR_MHI
select PCI_PWRCTRL_PWRSEQ if HAVE_PWRCTRL
diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
index 1c82d927d27b2..90802ed1aa59f 100644
--- a/drivers/net/wireless/ath/ath12k/dp.c
+++ b/drivers/net/wireless/ath/ath12k/dp.c
@@ -2,11 +2,10 @@
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
-#include <crypto/hash.h>
#include "core.h"
#include "dp_tx.h"
#include "hif.h"
#include "hal.h"
#include "debug.h"
@@ -39,11 +38,10 @@ void ath12k_dp_peer_cleanup(struct ath12k *ar, int vdev_id, const u8 *addr)
spin_unlock_bh(&dp->dp_lock);
return;
}
ath12k_dp_rx_peer_tid_cleanup(ar, peer);
- crypto_free_shash(peer->dp_peer->tfm_mmic);
peer->dp_peer->dp_setup_done = false;
spin_unlock_bh(&dp->dp_lock);
}
int ath12k_dp_peer_setup(struct ath12k *ar, int vdev_id, const u8 *addr)
diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.h b/drivers/net/wireless/ath/ath12k/dp_peer.h
index 20294ff095131..113b8040010fa 100644
--- a/drivers/net/wireless/ath/ath12k/dp_peer.h
+++ b/drivers/net/wireless/ath/ath12k/dp_peer.h
@@ -137,11 +137,10 @@ struct ath12k_dp_peer {
u16 sec_type_grp;
u16 sec_type;
/* Info used in MMIC verification of * RX fragments */
- struct crypto_shash *tfm_mmic;
struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1];
struct ath12k_dp_link_peer __rcu *link_peers[ATH12K_NUM_MAX_LINKS];
struct ath12k_reoq_buf reoq_bufs[IEEE80211_NUM_TIDS + 1];
struct ath12k_dp_rx_tid rx_tid[IEEE80211_NUM_TIDS + 1];
};
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c
index f0b4f607b8452..1272fd6c69860 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -2,14 +2,14 @@
/*
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
+#include <linux/fips.h>
#include <linux/ieee80211.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
-#include <crypto/hash.h>
#include "core.h"
#include "debug.h"
#include "hw.h"
#include "dp_rx.h"
#include "dp_tx.h"
@@ -1429,92 +1429,47 @@ static void ath12k_dp_rx_frag_timer(struct timer_list *timer)
}
int ath12k_dp_rx_peer_frag_setup(struct ath12k *ar, const u8 *peer_mac, int vdev_id)
{
struct ath12k_base *ab = ar->ab;
- struct crypto_shash *tfm;
struct ath12k_dp_link_peer *peer;
struct ath12k_dp_rx_tid *rx_tid;
int i;
struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
- tfm = crypto_alloc_shash("michael_mic", 0, 0);
- if (IS_ERR(tfm))
- return PTR_ERR(tfm);
+ if (fips_enabled) {
+ ath12k_warn(ab, "Michael MIC is not FIPS-allowed");
+ return -ENOENT;
+ }
spin_lock_bh(&dp->dp_lock);
peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, peer_mac);
if (!peer || !peer->dp_peer) {
spin_unlock_bh(&dp->dp_lock);
- crypto_free_shash(tfm);
ath12k_warn(ab, "failed to find the peer to set up fragment info\n");
return -ENOENT;
}
if (!peer->primary_link) {
spin_unlock_bh(&dp->dp_lock);
- crypto_free_shash(tfm);
return 0;
}
for (i = 0; i <= IEEE80211_NUM_TIDS; i++) {
rx_tid = &peer->dp_peer->rx_tid[i];
rx_tid->dp = dp;
timer_setup(&rx_tid->frag_timer, ath12k_dp_rx_frag_timer, 0);
skb_queue_head_init(&rx_tid->rx_frags);
}
- peer->dp_peer->tfm_mmic = tfm;
peer->dp_peer->dp_setup_done = true;
spin_unlock_bh(&dp->dp_lock);
return 0;
}
-int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key,
- struct ieee80211_hdr *hdr, u8 *data,
- size_t data_len, u8 *mic)
-{
- SHASH_DESC_ON_STACK(desc, tfm);
- u8 mic_hdr[16] = {};
- u8 tid = 0;
- int ret;
-
- if (!tfm)
- return -EINVAL;
-
- desc->tfm = tfm;
-
- ret = crypto_shash_setkey(tfm, key, 8);
- if (ret)
- goto out;
-
- ret = crypto_shash_init(desc);
- if (ret)
- goto out;
-
- /* TKIP MIC header */
- memcpy(mic_hdr, ieee80211_get_DA(hdr), ETH_ALEN);
- memcpy(mic_hdr + ETH_ALEN, ieee80211_get_SA(hdr), ETH_ALEN);
- if (ieee80211_is_data_qos(hdr->frame_control))
- tid = ieee80211_get_tid(hdr);
- mic_hdr[12] = tid;
-
- ret = crypto_shash_update(desc, mic_hdr, 16);
- if (ret)
- goto out;
- ret = crypto_shash_update(desc, data, data_len);
- if (ret)
- goto out;
- ret = crypto_shash_final(desc, mic);
-out:
- shash_desc_zero(desc);
- return ret;
-}
-EXPORT_SYMBOL(ath12k_dp_rx_h_michael_mic);
-
void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu,
enum hal_encrypt_type enctype, u32 flags)
{
struct ath12k_dp *dp = dp_pdev->dp;
struct ieee80211_hdr *hdr;
diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.h b/drivers/net/wireless/ath/ath12k/dp_rx.h
index bd62af0c80d46..55a31e669b3b0 100644
--- a/drivers/net/wireless/ath/ath12k/dp_rx.h
+++ b/drivers/net/wireless/ath/ath12k/dp_rx.h
@@ -4,11 +4,10 @@
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#ifndef ATH12K_DP_RX_H
#define ATH12K_DP_RX_H
-#include <crypto/hash.h>
#include "core.h"
#include "debug.h"
#define DP_MAX_NWIFI_HDR_LEN 30
@@ -202,13 +201,10 @@ u64 ath12k_dp_rx_h_get_pn(struct ath12k_dp *dp, struct sk_buff *skb);
void ath12k_dp_rx_h_sort_frags(struct ath12k_hal *hal,
struct sk_buff_head *frag_list,
struct sk_buff *cur_frag);
void ath12k_dp_rx_h_undecap_frag(struct ath12k_pdev_dp *dp_pdev, struct sk_buff *msdu,
enum hal_encrypt_type enctype, u32 flags);
-int ath12k_dp_rx_h_michael_mic(struct crypto_shash *tfm, u8 *key,
- struct ieee80211_hdr *hdr, u8 *data,
- size_t data_len, u8 *mic);
int ath12k_dp_rx_ampdu_start(struct ath12k *ar,
struct ieee80211_ampdu_params *params,
u8 link_id);
int ath12k_dp_rx_ampdu_stop(struct ath12k *ar,
struct ieee80211_ampdu_params *params,
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
index e6a934d74e85d..945680b3ebdfc 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c
@@ -981,11 +981,11 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev,
struct hal_rx_desc *rx_desc = (struct hal_rx_desc *)msdu->data;
struct ieee80211_rx_status *rxs = IEEE80211_SKB_RXCB(msdu);
struct ieee80211_key_conf *key_conf;
struct ieee80211_hdr *hdr;
u8 mic[IEEE80211_CCMP_MIC_LEN];
- int head_len, tail_len, ret;
+ int head_len, tail_len;
size_t data_len;
u32 hdr_len, hal_rx_desc_sz = hal->hal_desc_sz;
u8 *key, *data;
u8 key_idx;
@@ -1009,13 +1009,12 @@ static int ath12k_wifi7_dp_rx_h_verify_tkip_mic(struct ath12k_pdev_dp *dp_pdev,
data = msdu->data + head_len;
data_len = msdu->len - head_len - tail_len;
key = &key_conf->key[NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY];
- ret = ath12k_dp_rx_h_michael_mic(peer->tfm_mmic, key, hdr, data,
- data_len, mic);
- if (ret || memcmp(mic, data + data_len, IEEE80211_CCMP_MIC_LEN))
+ michael_mic(key, hdr, data, data_len, mic);
+ if (memcmp(mic, data + data_len, IEEE80211_CCMP_MIC_LEN))
goto mic_fail;
return 0;
mic_fail:
--
2.53.0
^ permalink raw reply related
* [PATCH wireless-next 4/6] wifi: ipw2x00: Depend on MAC80211
From: Eric Biggers @ 2026-04-05 5:27 UTC (permalink / raw)
To: Johannes Berg, linux-wireless
Cc: linux-crypto, linux-kernel, Herbert Xu, Eric Biggers
In-Reply-To: <20260405052734.130368-1-ebiggers@kernel.org>
While the ipw2100 and ipw2200 hardware is "Full MAC" in the sense that
it handles management frames (like association and scanning), it doesn't
implement various cryptographic protocols, such as the Michael MIC
algorithm used in the (deprecated) TKIP.
Currently ipw2x00 accesses Michael MIC via the crypto_shash API. Yet,
the mac80211 module already has its own Michael MIC implementation.
ipw2x00 is the only code in the kernel tree that needs a Michael MIC
implementation that doesn't already depend on CONFIG_MAC80211.
Just add the dependency on MAC80211 so that we'll be able to consolidate
the Michael MIC code in mac80211 and remove it from crypto_shash.
Alternatives considered:
- Move michael_mic() from mac80211 to cfg80211. Probably not worth it
just for ipw2x00.
- Move michael_mic() to its own independent module. Again, probably
not worth it just for ipw2x00.
- Copy michael_mic() into ipw2x00. It seems better to avoid the
duplicate copy.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
drivers/net/wireless/intel/ipw2x00/Kconfig | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/intel/ipw2x00/Kconfig b/drivers/net/wireless/intel/ipw2x00/Kconfig
index b92df91adb3a4..13d69f94c889a 100644
--- a/drivers/net/wireless/intel/ipw2x00/Kconfig
+++ b/drivers/net/wireless/intel/ipw2x00/Kconfig
@@ -3,11 +3,11 @@
# Intel Centrino wireless drivers
#
config IPW2100
tristate "Intel PRO/Wireless 2100 Network Connection"
- depends on PCI && CFG80211
+ depends on PCI && MAC80211
select WIRELESS_EXT
select WEXT_PRIV
select FW_LOADER
select LIBIPW
help
@@ -62,11 +62,11 @@ config IPW2100_DEBUG
If you are not trying to debug or develop the IPW2100 driver, you
most likely want to say N here.
config IPW2200
tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
- depends on PCI && CFG80211
+ depends on PCI && MAC80211
select WIRELESS_EXT
select WEXT_PRIV
select FW_LOADER
select LIBIPW
help
@@ -149,11 +149,11 @@ config IPW2200_DEBUG
If you are not sure, say N here.
config LIBIPW
tristate
- depends on PCI && CFG80211
+ depends on PCI && MAC80211
select WIRELESS_EXT
select CRYPTO
select CRYPTO_MICHAEL_MIC
select CRYPTO_LIB_ARC4
select CRC32
--
2.53.0
^ permalink raw reply related
* [PATCH wireless-next 5/6] wifi: ipw2x00: Use michael_mic() from mac80211
From: Eric Biggers @ 2026-04-05 5:27 UTC (permalink / raw)
To: Johannes Berg, linux-wireless
Cc: linux-crypto, linux-kernel, Herbert Xu, Eric Biggers
In-Reply-To: <20260405052734.130368-1-ebiggers@kernel.org>
Just use the michael_mic() function from mac80211 instead of a local
implementation of it on top of the crypto_shash API.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
drivers/net/wireless/intel/ipw2x00/Kconfig | 1 -
.../intel/ipw2x00/libipw_crypto_tkip.c | 120 +-----------------
2 files changed, 5 insertions(+), 116 deletions(-)
diff --git a/drivers/net/wireless/intel/ipw2x00/Kconfig b/drivers/net/wireless/intel/ipw2x00/Kconfig
index 13d69f94c889a..20d1392e1d61c 100644
--- a/drivers/net/wireless/intel/ipw2x00/Kconfig
+++ b/drivers/net/wireless/intel/ipw2x00/Kconfig
@@ -152,11 +152,10 @@ config IPW2200_DEBUG
config LIBIPW
tristate
depends on PCI && MAC80211
select WIRELESS_EXT
select CRYPTO
- select CRYPTO_MICHAEL_MIC
select CRYPTO_LIB_ARC4
select CRC32
help
This option enables the hardware independent IEEE 802.11
networking stack. This component is deprecated in favor of the
diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_crypto_tkip.c b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_tkip.c
index c6b0de8d91aea..24bb28ab7a49b 100644
--- a/drivers/net/wireless/intel/ipw2x00/libipw_crypto_tkip.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_tkip.c
@@ -23,12 +23,10 @@
#include <asm/string.h>
#include <linux/wireless.h>
#include <linux/ieee80211.h>
#include <net/iw_handler.h>
#include <crypto/arc4.h>
-#include <crypto/hash.h>
-#include <linux/crypto.h>
#include <linux/crc32.h>
#include "libipw.h"
#define TKIP_HDR_LEN 8
@@ -55,15 +53,10 @@ struct libipw_tkip_data {
int key_idx;
struct arc4_ctx rx_ctx_arc4;
struct arc4_ctx tx_ctx_arc4;
- struct crypto_shash *rx_tfm_michael;
- struct crypto_shash *tx_tfm_michael;
-
- /* scratch buffers for virt_to_page() (crypto API) */
- u8 rx_hdr[16], tx_hdr[16];
unsigned long flags;
};
static unsigned long libipw_tkip_set_flags(unsigned long flags, void *priv)
@@ -87,45 +80,18 @@ static void *libipw_tkip_init(int key_idx)
if (fips_enabled)
return NULL;
priv = kzalloc_obj(*priv, GFP_ATOMIC);
if (priv == NULL)
- goto fail;
+ return priv;
priv->key_idx = key_idx;
-
- priv->tx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0);
- if (IS_ERR(priv->tx_tfm_michael)) {
- priv->tx_tfm_michael = NULL;
- goto fail;
- }
-
- priv->rx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0);
- if (IS_ERR(priv->rx_tfm_michael)) {
- priv->rx_tfm_michael = NULL;
- goto fail;
- }
-
return priv;
-
- fail:
- if (priv) {
- crypto_free_shash(priv->tx_tfm_michael);
- crypto_free_shash(priv->rx_tfm_michael);
- kfree(priv);
- }
-
- return NULL;
}
static void libipw_tkip_deinit(void *priv)
{
- struct libipw_tkip_data *_priv = priv;
- if (_priv) {
- crypto_free_shash(_priv->tx_tfm_michael);
- crypto_free_shash(_priv->rx_tfm_michael);
- }
kfree_sensitive(priv);
}
static inline u16 RotR1(u16 val)
{
@@ -462,77 +428,10 @@ static int libipw_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
skb_trim(skb, skb->len - 4);
return keyidx;
}
-static int michael_mic(struct crypto_shash *tfm_michael, u8 *key, u8 *hdr,
- u8 *data, size_t data_len, u8 *mic)
-{
- SHASH_DESC_ON_STACK(desc, tfm_michael);
- int err;
-
- if (tfm_michael == NULL) {
- pr_warn("%s(): tfm_michael == NULL\n", __func__);
- return -1;
- }
-
- desc->tfm = tfm_michael;
-
- if (crypto_shash_setkey(tfm_michael, key, 8))
- return -1;
-
- err = crypto_shash_init(desc);
- if (err)
- goto out;
- err = crypto_shash_update(desc, hdr, 16);
- if (err)
- goto out;
- err = crypto_shash_update(desc, data, data_len);
- if (err)
- goto out;
- err = crypto_shash_final(desc, mic);
-
-out:
- shash_desc_zero(desc);
- return err;
-}
-
-static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr)
-{
- struct ieee80211_hdr *hdr11;
-
- hdr11 = (struct ieee80211_hdr *)skb->data;
-
- switch (le16_to_cpu(hdr11->frame_control) &
- (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
- case IEEE80211_FCTL_TODS:
- memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
- break;
- case IEEE80211_FCTL_FROMDS:
- memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
- break;
- case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
- memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
- break;
- default:
- memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
- break;
- }
-
- if (ieee80211_is_data_qos(hdr11->frame_control)) {
- hdr[12] = le16_to_cpu(*((__le16 *)ieee80211_get_qos_ctl(hdr11)))
- & IEEE80211_QOS_CTL_TID_MASK;
- } else
- hdr[12] = 0; /* priority */
-
- hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
-}
-
static int libipw_michael_mic_add(struct sk_buff *skb, int hdr_len,
void *priv)
{
struct libipw_tkip_data *tkey = priv;
u8 *pos;
@@ -542,16 +441,13 @@ static int libipw_michael_mic_add(struct sk_buff *skb, int hdr_len,
"(tailroom=%d hdr_len=%d skb->len=%d)\n",
skb_tailroom(skb), hdr_len, skb->len);
return -1;
}
- michael_mic_hdr(skb, tkey->tx_hdr);
pos = skb_put(skb, 8);
- if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
- skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
- return -1;
-
+ michael_mic(&tkey->key[16], (struct ieee80211_hdr *)skb->data,
+ skb->data + hdr_len, skb->len - 8 - hdr_len, pos);
return 0;
}
static void libipw_michael_mic_failure(struct net_device *dev,
struct ieee80211_hdr *hdr,
@@ -581,14 +477,12 @@ static int libipw_michael_mic_verify(struct sk_buff *skb, int keyidx,
u8 mic[8];
if (!tkey->key_set)
return -1;
- michael_mic_hdr(skb, tkey->rx_hdr);
- if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
- skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
- return -1;
+ michael_mic(&tkey->key[24], (struct ieee80211_hdr *)skb->data,
+ skb->data + hdr_len, skb->len - 8 - hdr_len, mic);
if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
struct ieee80211_hdr *hdr;
hdr = (struct ieee80211_hdr *)skb->data;
printk(KERN_DEBUG "%s: Michael MIC verification failed for "
"MSDU from %pM keyidx=%d\n",
@@ -612,21 +506,17 @@ static int libipw_michael_mic_verify(struct sk_buff *skb, int keyidx,
static int libipw_tkip_set_key(void *key, int len, u8 * seq, void *priv)
{
struct libipw_tkip_data *tkey = priv;
int keyidx;
- struct crypto_shash *tfm = tkey->tx_tfm_michael;
struct arc4_ctx *tfm2 = &tkey->tx_ctx_arc4;
- struct crypto_shash *tfm3 = tkey->rx_tfm_michael;
struct arc4_ctx *tfm4 = &tkey->rx_ctx_arc4;
keyidx = tkey->key_idx;
memset(tkey, 0, sizeof(*tkey));
tkey->key_idx = keyidx;
- tkey->tx_tfm_michael = tfm;
tkey->tx_ctx_arc4 = *tfm2;
- tkey->rx_tfm_michael = tfm3;
tkey->rx_ctx_arc4 = *tfm4;
if (len == TKIP_KEY_LEN) {
memcpy(tkey->key, key, TKIP_KEY_LEN);
tkey->key_set = 1;
tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
--
2.53.0
^ permalink raw reply related
* [PATCH wireless-next 6/6] crypto: Remove michael_mic from crypto_shash API
From: Eric Biggers @ 2026-04-05 5:27 UTC (permalink / raw)
To: Johannes Berg, linux-wireless
Cc: linux-crypto, linux-kernel, Herbert Xu, Eric Biggers
In-Reply-To: <20260405052734.130368-1-ebiggers@kernel.org>
Remove the "michael_mic" crypto_shash algorithm, since it's no longer
used. Its only users were wireless drivers, which have now been
converted to use the michael_mic() function instead.
It makes sense that no other users ever appeared: Michael MIC is an
insecure algorithm that is specific to WPA TKIP, which itself was an
interim security solution to replace the broken WEP standard.
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
arch/arm/configs/omap2plus_defconfig | 1 -
arch/arm/configs/spitz_defconfig | 1 -
arch/arm64/configs/defconfig | 1 -
arch/m68k/configs/amiga_defconfig | 1 -
arch/m68k/configs/apollo_defconfig | 1 -
arch/m68k/configs/atari_defconfig | 1 -
arch/m68k/configs/bvme6000_defconfig | 1 -
arch/m68k/configs/hp300_defconfig | 1 -
arch/m68k/configs/mac_defconfig | 1 -
arch/m68k/configs/multi_defconfig | 1 -
arch/m68k/configs/mvme147_defconfig | 1 -
arch/m68k/configs/mvme16x_defconfig | 1 -
arch/m68k/configs/q40_defconfig | 1 -
arch/m68k/configs/sun3_defconfig | 1 -
arch/m68k/configs/sun3x_defconfig | 1 -
arch/mips/configs/bigsur_defconfig | 1 -
arch/mips/configs/decstation_64_defconfig | 1 -
arch/mips/configs/decstation_defconfig | 1 -
arch/mips/configs/decstation_r4k_defconfig | 1 -
arch/mips/configs/gpr_defconfig | 1 -
arch/mips/configs/ip32_defconfig | 1 -
arch/mips/configs/lemote2f_defconfig | 1 -
arch/mips/configs/malta_qemu_32r6_defconfig | 1 -
arch/mips/configs/maltaaprp_defconfig | 1 -
arch/mips/configs/maltasmvp_defconfig | 1 -
arch/mips/configs/maltasmvp_eva_defconfig | 1 -
arch/mips/configs/maltaup_defconfig | 1 -
arch/mips/configs/mtx1_defconfig | 1 -
arch/mips/configs/rm200_defconfig | 1 -
arch/mips/configs/sb1250_swarm_defconfig | 1 -
arch/parisc/configs/generic-32bit_defconfig | 1 -
arch/parisc/configs/generic-64bit_defconfig | 1 -
arch/powerpc/configs/g5_defconfig | 1 -
arch/powerpc/configs/linkstation_defconfig | 1 -
arch/powerpc/configs/mvme5100_defconfig | 1 -
arch/powerpc/configs/powernv_defconfig | 1 -
arch/powerpc/configs/ppc64_defconfig | 1 -
arch/powerpc/configs/ppc64e_defconfig | 1 -
arch/powerpc/configs/ppc6xx_defconfig | 1 -
arch/powerpc/configs/ps3_defconfig | 1 -
arch/s390/configs/debug_defconfig | 1 -
arch/s390/configs/defconfig | 1 -
arch/sh/configs/sh2007_defconfig | 1 -
arch/sh/configs/titan_defconfig | 1 -
arch/sh/configs/ul2_defconfig | 1 -
arch/sparc/configs/sparc32_defconfig | 1 -
arch/sparc/configs/sparc64_defconfig | 1 -
crypto/Kconfig | 12 --
crypto/Makefile | 1 -
crypto/michael_mic.c | 176 --------------------
crypto/tcrypt.c | 4 -
crypto/testmgr.c | 6 -
crypto/testmgr.h | 50 ------
53 files changed, 296 deletions(-)
delete mode 100644 crypto/michael_mic.c
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index 0464f6552169b..ae2883d3ff0ea 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -702,11 +702,10 @@ CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_ROOT_NFS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_SECURITY=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
CONFIG_CRYPTO_GHASH_ARM_CE=m
CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_AES_ARM_BS=m
CONFIG_CRYPTO_DEV_OMAP=m
CONFIG_CRYPTO_DEV_OMAP_SHAM=m
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index c130af6d44d48..f116a01c3f5f1 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -228,11 +228,10 @@ CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_FONTS=y
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index b67d5b1fc45b0..a2a5884f0ac82 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1912,11 +1912,10 @@ CONFIG_NLS_ISO8859_1=y
CONFIG_SECURITY=y
CONFIG_CRYPTO_USER=y
CONFIG_CRYPTO_CHACHA20=m
CONFIG_CRYPTO_BENCHMARK=m
CONFIG_CRYPTO_ECHAINIV=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA3=m
CONFIG_CRYPTO_USER_API_RNG=m
CONFIG_CRYPTO_GHASH_ARM64_CE=y
CONFIG_CRYPTO_SM3_ARM64_CE=m
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
diff --git a/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig
index 31d16cba9879f..c4230232634a3 100644
--- a/arch/m68k/configs/amiga_defconfig
+++ b/arch/m68k/configs/amiga_defconfig
@@ -576,11 +576,10 @@ CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SM3_GENERIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig
index c0c419ec9a9e9..740edd4f3ca14 100644
--- a/arch/m68k/configs/apollo_defconfig
+++ b/arch/m68k/configs/apollo_defconfig
@@ -533,11 +533,10 @@ CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SM3_GENERIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig
index 2b7547ecc4c41..1773533ead702 100644
--- a/arch/m68k/configs/atari_defconfig
+++ b/arch/m68k/configs/atari_defconfig
@@ -553,11 +553,10 @@ CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SM3_GENERIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig
index 0b63787cff0da..6aaf126a646ea 100644
--- a/arch/m68k/configs/bvme6000_defconfig
+++ b/arch/m68k/configs/bvme6000_defconfig
@@ -525,11 +525,10 @@ CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SM3_GENERIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig
index 308836b60bba4..9a2076458de8f 100644
--- a/arch/m68k/configs/hp300_defconfig
+++ b/arch/m68k/configs/hp300_defconfig
@@ -535,11 +535,10 @@ CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SM3_GENERIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig
index 97e108c0d24f2..76bac1bedf1c6 100644
--- a/arch/m68k/configs/mac_defconfig
+++ b/arch/m68k/configs/mac_defconfig
@@ -552,11 +552,10 @@ CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SM3_GENERIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
diff --git a/arch/m68k/configs/multi_defconfig b/arch/m68k/configs/multi_defconfig
index 7e9f83af9af46..9d3b9b9d0c15e 100644
--- a/arch/m68k/configs/multi_defconfig
+++ b/arch/m68k/configs/multi_defconfig
@@ -639,11 +639,10 @@ CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SM3_GENERIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig
index 2fe33271d2494..e705aff2fa200 100644
--- a/arch/m68k/configs/mvme147_defconfig
+++ b/arch/m68k/configs/mvme147_defconfig
@@ -525,11 +525,10 @@ CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SM3_GENERIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig
index 4308daaa7f74c..286f7c949fcb2 100644
--- a/arch/m68k/configs/mvme16x_defconfig
+++ b/arch/m68k/configs/mvme16x_defconfig
@@ -526,11 +526,10 @@ CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SM3_GENERIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig
index 36eb29ec54eeb..3cedc6a76bc9f 100644
--- a/arch/m68k/configs/q40_defconfig
+++ b/arch/m68k/configs/q40_defconfig
@@ -542,11 +542,10 @@ CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SM3_GENERIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig
index 524a89fa69531..91c6060f42922 100644
--- a/arch/m68k/configs/sun3_defconfig
+++ b/arch/m68k/configs/sun3_defconfig
@@ -523,11 +523,10 @@ CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SM3_GENERIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig
index f4fbc65c52d9a..8bb0ac877f652 100644
--- a/arch/m68k/configs/sun3x_defconfig
+++ b/arch/m68k/configs/sun3x_defconfig
@@ -523,11 +523,10 @@ CONFIG_CRYPTO_HCTR2=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_SM3_GENERIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index 349e9e0b4f547..3b64e151e187f 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -220,11 +220,10 @@ CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m
diff --git a/arch/mips/configs/decstation_64_defconfig b/arch/mips/configs/decstation_64_defconfig
index dad98c5752928..7c43352fac6bd 100644
--- a/arch/mips/configs/decstation_64_defconfig
+++ b/arch/mips/configs/decstation_64_defconfig
@@ -178,11 +178,10 @@ CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_CMAC=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_CRC32=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_ARC4=m
diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig
index 4e1b51a4ad900..aee10274f0488 100644
--- a/arch/mips/configs/decstation_defconfig
+++ b/arch/mips/configs/decstation_defconfig
@@ -173,11 +173,10 @@ CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_CMAC=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_CRC32=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_ARC4=m
diff --git a/arch/mips/configs/decstation_r4k_defconfig b/arch/mips/configs/decstation_r4k_defconfig
index 4e550dffc23df..a1698049aa7a7 100644
--- a/arch/mips/configs/decstation_r4k_defconfig
+++ b/arch/mips/configs/decstation_r4k_defconfig
@@ -173,11 +173,10 @@ CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_CMAC=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_CRC32=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_ARC4=m
diff --git a/arch/mips/configs/gpr_defconfig b/arch/mips/configs/gpr_defconfig
index 437ef6dc0b4c2..fdd28a89e3369 100644
--- a/arch/mips/configs/gpr_defconfig
+++ b/arch/mips/configs/gpr_defconfig
@@ -273,11 +273,10 @@ CONFIG_NLS_CODEPAGE_850=y
CONFIG_NLS_ISO8859_1=y
CONFIG_CRYPTO_AUTHENC=m
CONFIG_CRYPTO_BENCHMARK=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST5=m
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig
index 7568838eb08b2..68558d0d3f52c 100644
--- a/arch/mips/configs/ip32_defconfig
+++ b/arch/mips/configs/ip32_defconfig
@@ -157,11 +157,10 @@ CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_LRW=y
CONFIG_CRYPTO_PCBC=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_WP512=y
CONFIG_CRYPTO_ANUBIS=y
diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig
index 8d3f20ed19b56..eb3565a3f292c 100644
--- a/arch/mips/configs/lemote2f_defconfig
+++ b/arch/mips/configs/lemote2f_defconfig
@@ -306,11 +306,10 @@ CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_DEFLATE=m
diff --git a/arch/mips/configs/malta_qemu_32r6_defconfig b/arch/mips/configs/malta_qemu_32r6_defconfig
index accb471a1d93f..46a69e8984c5a 100644
--- a/arch/mips/configs/malta_qemu_32r6_defconfig
+++ b/arch/mips/configs/malta_qemu_32r6_defconfig
@@ -165,11 +165,10 @@ CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_ISO8859_1=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
diff --git a/arch/mips/configs/maltaaprp_defconfig b/arch/mips/configs/maltaaprp_defconfig
index 6bda67c5f68f8..74a0e5f6a8860 100644
--- a/arch/mips/configs/maltaaprp_defconfig
+++ b/arch/mips/configs/maltaaprp_defconfig
@@ -166,11 +166,10 @@ CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_ISO8859_1=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
diff --git a/arch/mips/configs/maltasmvp_defconfig b/arch/mips/configs/maltasmvp_defconfig
index e4082537f80fb..873bfc59623b8 100644
--- a/arch/mips/configs/maltasmvp_defconfig
+++ b/arch/mips/configs/maltasmvp_defconfig
@@ -167,11 +167,10 @@ CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_ISO8859_1=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
diff --git a/arch/mips/configs/maltasmvp_eva_defconfig b/arch/mips/configs/maltasmvp_eva_defconfig
index 58f5af45fa983..c9230b2c4ea8d 100644
--- a/arch/mips/configs/maltasmvp_eva_defconfig
+++ b/arch/mips/configs/maltasmvp_eva_defconfig
@@ -169,11 +169,10 @@ CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_ISO8859_1=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
diff --git a/arch/mips/configs/maltaup_defconfig b/arch/mips/configs/maltaup_defconfig
index 9bfef7de0d1cf..79fd3ccab3393 100644
--- a/arch/mips/configs/maltaup_defconfig
+++ b/arch/mips/configs/maltaup_defconfig
@@ -165,11 +165,10 @@ CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
CONFIG_NLS_CODEPAGE_437=m
CONFIG_NLS_ISO8859_1=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig
index 77050ae3945fc..930c0178cc670 100644
--- a/arch/mips/configs/mtx1_defconfig
+++ b/arch/mips/configs/mtx1_defconfig
@@ -661,11 +661,10 @@ CONFIG_NLS_KOI8_U=m
CONFIG_NLS_UTF8=m
CONFIG_CRYPTO_BENCHMARK=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_KHAZAD=m
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index b507dc4dddd48..b1e67ff0c4f08 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -380,11 +380,10 @@ CONFIG_NLS_KOI8_U=m
CONFIG_NLS_UTF8=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAMELLIA=m
CONFIG_CRYPTO_CAST6=m
diff --git a/arch/mips/configs/sb1250_swarm_defconfig b/arch/mips/configs/sb1250_swarm_defconfig
index ae2afff00e01a..4a25b8d3e5078 100644
--- a/arch/mips/configs/sb1250_swarm_defconfig
+++ b/arch/mips/configs/sb1250_swarm_defconfig
@@ -83,11 +83,10 @@ CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAMELLIA=m
CONFIG_CRYPTO_CAST5=m
diff --git a/arch/parisc/configs/generic-32bit_defconfig b/arch/parisc/configs/generic-32bit_defconfig
index 5444ce6405f3a..a2cb2a7a02db8 100644
--- a/arch/parisc/configs/generic-32bit_defconfig
+++ b/arch/parisc/configs/generic-32bit_defconfig
@@ -257,11 +257,10 @@ CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_DEFLATE=y
CONFIG_FONTS=y
CONFIG_PRINTK_TIME=y
diff --git a/arch/parisc/configs/generic-64bit_defconfig b/arch/parisc/configs/generic-64bit_defconfig
index ce91f9d1fdbfb..4dd6cf6a2cb9b 100644
--- a/arch/parisc/configs/generic-64bit_defconfig
+++ b/arch/parisc/configs/generic-64bit_defconfig
@@ -285,11 +285,10 @@ CONFIG_NLS_UTF8=m
CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_DEFLATE=m
# CONFIG_CRYPTO_HW is not set
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_KERNEL=y
CONFIG_STRIP_ASM_SYMS=y
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig
index 428f17b455132..466f196ee8b29 100644
--- a/arch/powerpc/configs/g5_defconfig
+++ b/arch/powerpc/configs/g5_defconfig
@@ -236,11 +236,10 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_BOOTX_TEXT=y
CONFIG_CRYPTO_BENCHMARK=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST5=m
diff --git a/arch/powerpc/configs/linkstation_defconfig b/arch/powerpc/configs/linkstation_defconfig
index b564f9e33a0df..31f84d08b6efe 100644
--- a/arch/powerpc/configs/linkstation_defconfig
+++ b/arch/powerpc/configs/linkstation_defconfig
@@ -127,11 +127,10 @@ CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_UTF8=m
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_DEFLATE=m
diff --git a/arch/powerpc/configs/mvme5100_defconfig b/arch/powerpc/configs/mvme5100_defconfig
index fa2b3b9c59452..c82754c14e15e 100644
--- a/arch/powerpc/configs/mvme5100_defconfig
+++ b/arch/powerpc/configs/mvme5100_defconfig
@@ -113,11 +113,10 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=20
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA1=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TWOFISH=m
diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig
index 9ac746cfb4be3..675462b783200 100644
--- a/arch/powerpc/configs/powernv_defconfig
+++ b/arch/powerpc/configs/powernv_defconfig
@@ -317,11 +317,10 @@ CONFIG_FTR_FIXUP_SELFTEST=y
CONFIG_MSI_BITMAP_SELFTEST=y
CONFIG_XMON=y
CONFIG_CRYPTO_BENCHMARK=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST6=m
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 2b0720f2753bc..e3e1cad668d9a 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -380,11 +380,10 @@ CONFIG_CRYPTO_BENCHMARK=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_LZO=m
CONFIG_CRYPTO_AES_GCM_P10=m
CONFIG_CRYPTO_DEV_NX=y
diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig
index 90247b2a0ab0c..e877598fe3562 100644
--- a/arch/powerpc/configs/ppc64e_defconfig
+++ b/arch/powerpc/configs/ppc64e_defconfig
@@ -223,11 +223,10 @@ CONFIG_XMON=y
CONFIG_CRYPTO_BENCHMARK=m
CONFIG_CRYPTO_CCM=m
CONFIG_CRYPTO_GCM=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST6=m
diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig
index 3c08f46f3d41f..27d4350e8fdbe 100644
--- a/arch/powerpc/configs/ppc6xx_defconfig
+++ b/arch/powerpc/configs/ppc6xx_defconfig
@@ -1075,11 +1075,10 @@ CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig
index 0b48d2b776c44..7cfae0b7b2f35 100644
--- a/arch/powerpc/configs/ps3_defconfig
+++ b/arch/powerpc/configs/ps3_defconfig
@@ -144,11 +144,10 @@ CONFIG_ROOT_NFS=y
CONFIG_CIFS=m
CONFIG_NLS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_LZO=m
CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_MEMORY_INIT=y
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
index 98fd0a2f51c6a..b74f96eec4658 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -792,11 +792,10 @@ CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_SEQIV=y
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA3=m
CONFIG_CRYPTO_SM3_GENERIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig
index 0f4cedcab3cef..0c831481e43fd 100644
--- a/arch/s390/configs/defconfig
+++ b/arch/s390/configs/defconfig
@@ -776,11 +776,10 @@ CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_AEGIS128=m
CONFIG_CRYPTO_GCM=y
CONFIG_CRYPTO_SEQIV=y
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_RMD160=m
CONFIG_CRYPTO_SHA3=m
CONFIG_CRYPTO_SM3_GENERIC=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_XCBC=m
diff --git a/arch/sh/configs/sh2007_defconfig b/arch/sh/configs/sh2007_defconfig
index e32d2ce72699f..5d90804994857 100644
--- a/arch/sh/configs/sh2007_defconfig
+++ b/arch/sh/configs/sh2007_defconfig
@@ -168,11 +168,10 @@ CONFIG_CRYPTO_LRW=y
CONFIG_CRYPTO_PCBC=y
CONFIG_CRYPTO_XTS=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_SHA512=y
CONFIG_CRYPTO_TGR192=y
CONFIG_CRYPTO_WP512=y
diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig
index 896e980d04e14..00863ecb228e8 100644
--- a/arch/sh/configs/titan_defconfig
+++ b/arch/sh/configs/titan_defconfig
@@ -244,11 +244,10 @@ CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MICHAEL_MIC=y
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_AES=y
diff --git a/arch/sh/configs/ul2_defconfig b/arch/sh/configs/ul2_defconfig
index 0d1c858754dbb..00a37944b043c 100644
--- a/arch/sh/configs/ul2_defconfig
+++ b/arch/sh/configs/ul2_defconfig
@@ -77,6 +77,5 @@ CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_932=y
CONFIG_NLS_ISO8859_1=y
# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_CRYPTO_MICHAEL_MIC=y
diff --git a/arch/sparc/configs/sparc32_defconfig b/arch/sparc/configs/sparc32_defconfig
index e021ecfb5a771..48d834acafb4a 100644
--- a/arch/sparc/configs/sparc32_defconfig
+++ b/arch/sparc/configs/sparc32_defconfig
@@ -80,11 +80,10 @@ CONFIG_KGDB=y
CONFIG_KGDB_TESTS=y
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_BLOWFISH=m
diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig
index 9f3f41246ae6d..632081a262bae 100644
--- a/arch/sparc/configs/sparc64_defconfig
+++ b/arch/sparc/configs/sparc64_defconfig
@@ -208,11 +208,10 @@ CONFIG_CRYPTO_BENCHMARK=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_XTS=m
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_AES=m
diff --git a/crypto/Kconfig b/crypto/Kconfig
index b4bb85e8e2261..769aef52a7851 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -914,22 +914,10 @@ config CRYPTO_MD5
select CRYPTO_HASH
select CRYPTO_LIB_MD5
help
MD5 message digest algorithm (RFC1321), including HMAC support.
-config CRYPTO_MICHAEL_MIC
- tristate "Michael MIC"
- select CRYPTO_HASH
- help
- Michael MIC (Message Integrity Code) (IEEE 802.11i)
-
- Defined by the IEEE 802.11i TKIP (Temporal Key Integrity Protocol),
- known as WPA (Wif-Fi Protected Access).
-
- This algorithm is required for TKIP, but it should not be used for
- other purposes because of the weakness of the algorithm.
-
config CRYPTO_RMD160
tristate "RIPEMD-160"
select CRYPTO_HASH
help
RIPEMD-160 hash function (ISO/IEC 10118-3)
diff --git a/crypto/Makefile b/crypto/Makefile
index 04e269117589a..aa35ba03222f7 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -148,11 +148,10 @@ obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o
obj-$(CONFIG_CRYPTO_SEED) += seed.o
obj-$(CONFIG_CRYPTO_ARIA) += aria_generic.o
obj-$(CONFIG_CRYPTO_CHACHA20) += chacha.o
CFLAGS_chacha.o += -DARCH=$(ARCH)
obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
-obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
obj-$(CONFIG_CRYPTO_CRC32C) += crc32c-cryptoapi.o
crc32c-cryptoapi-y := crc32c.o
obj-$(CONFIG_CRYPTO_CRC32) += crc32-cryptoapi.o
crc32-cryptoapi-y := crc32.o
obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
diff --git a/crypto/michael_mic.c b/crypto/michael_mic.c
deleted file mode 100644
index 69ad35f524d7b..0000000000000
--- a/crypto/michael_mic.c
+++ /dev/null
@@ -1,176 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Cryptographic API
- *
- * Michael MIC (IEEE 802.11i/TKIP) keyed digest
- *
- * Copyright (c) 2004 Jouni Malinen <j@w1.fi>
- */
-#include <crypto/internal/hash.h>
-#include <linux/unaligned.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/types.h>
-
-
-struct michael_mic_ctx {
- u32 l, r;
-};
-
-struct michael_mic_desc_ctx {
- __le32 pending;
- size_t pending_len;
-
- u32 l, r;
-};
-
-static inline u32 xswap(u32 val)
-{
- return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
-}
-
-
-#define michael_block(l, r) \
-do { \
- r ^= rol32(l, 17); \
- l += r; \
- r ^= xswap(l); \
- l += r; \
- r ^= rol32(l, 3); \
- l += r; \
- r ^= ror32(l, 2); \
- l += r; \
-} while (0)
-
-
-static int michael_init(struct shash_desc *desc)
-{
- struct michael_mic_desc_ctx *mctx = shash_desc_ctx(desc);
- struct michael_mic_ctx *ctx = crypto_shash_ctx(desc->tfm);
- mctx->pending_len = 0;
- mctx->l = ctx->l;
- mctx->r = ctx->r;
-
- return 0;
-}
-
-
-static int michael_update(struct shash_desc *desc, const u8 *data,
- unsigned int len)
-{
- struct michael_mic_desc_ctx *mctx = shash_desc_ctx(desc);
-
- if (mctx->pending_len) {
- int flen = 4 - mctx->pending_len;
- if (flen > len)
- flen = len;
- memcpy((u8 *)&mctx->pending + mctx->pending_len, data, flen);
- mctx->pending_len += flen;
- data += flen;
- len -= flen;
-
- if (mctx->pending_len < 4)
- return 0;
-
- mctx->l ^= le32_to_cpu(mctx->pending);
- michael_block(mctx->l, mctx->r);
- mctx->pending_len = 0;
- }
-
- while (len >= 4) {
- mctx->l ^= get_unaligned_le32(data);
- michael_block(mctx->l, mctx->r);
- data += 4;
- len -= 4;
- }
-
- if (len > 0) {
- mctx->pending_len = len;
- memcpy(&mctx->pending, data, len);
- }
-
- return 0;
-}
-
-
-static int michael_final(struct shash_desc *desc, u8 *out)
-{
- struct michael_mic_desc_ctx *mctx = shash_desc_ctx(desc);
- u8 *data = (u8 *)&mctx->pending;
-
- /* Last block and padding (0x5a, 4..7 x 0) */
- switch (mctx->pending_len) {
- case 0:
- mctx->l ^= 0x5a;
- break;
- case 1:
- mctx->l ^= data[0] | 0x5a00;
- break;
- case 2:
- mctx->l ^= data[0] | (data[1] << 8) | 0x5a0000;
- break;
- case 3:
- mctx->l ^= data[0] | (data[1] << 8) | (data[2] << 16) |
- 0x5a000000;
- break;
- }
- michael_block(mctx->l, mctx->r);
- /* l ^= 0; */
- michael_block(mctx->l, mctx->r);
-
- put_unaligned_le32(mctx->l, out);
- put_unaligned_le32(mctx->r, out + 4);
-
- return 0;
-}
-
-
-static int michael_setkey(struct crypto_shash *tfm, const u8 *key,
- unsigned int keylen)
-{
- struct michael_mic_ctx *mctx = crypto_shash_ctx(tfm);
-
- if (keylen != 8)
- return -EINVAL;
-
- mctx->l = get_unaligned_le32(key);
- mctx->r = get_unaligned_le32(key + 4);
- return 0;
-}
-
-static struct shash_alg alg = {
- .digestsize = 8,
- .setkey = michael_setkey,
- .init = michael_init,
- .update = michael_update,
- .final = michael_final,
- .descsize = sizeof(struct michael_mic_desc_ctx),
- .base = {
- .cra_name = "michael_mic",
- .cra_driver_name = "michael_mic-generic",
- .cra_blocksize = 8,
- .cra_ctxsize = sizeof(struct michael_mic_ctx),
- .cra_module = THIS_MODULE,
- }
-};
-
-static int __init michael_mic_init(void)
-{
- return crypto_register_shash(&alg);
-}
-
-
-static void __exit michael_mic_exit(void)
-{
- crypto_unregister_shash(&alg);
-}
-
-
-module_init(michael_mic_init);
-module_exit(michael_mic_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("Michael MIC");
-MODULE_AUTHOR("Jouni Malinen <j@w1.fi>");
-MODULE_ALIAS_CRYPTO("michael_mic");
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index aded375461374..24f0ccc767961 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -1555,14 +1555,10 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
case 16:
ret = min(ret, tcrypt_test("ecb(arc4)"));
break;
- case 17:
- ret = min(ret, tcrypt_test("michael_mic"));
- break;
-
case 18:
ret = min(ret, tcrypt_test("crc32c"));
break;
case 19:
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 4985411dedaec..d5c38683bf46f 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -5195,16 +5195,10 @@ static const struct alg_test_desc alg_test_descs[] = {
.generic_driver = "md5-lib",
.test = alg_test_hash,
.suite = {
.hash = __VECS(md5_tv_template)
}
- }, {
- .alg = "michael_mic",
- .test = alg_test_hash,
- .suite = {
- .hash = __VECS(michael_mic_tv_template)
- }
}, {
.alg = "p1363(ecdsa-nist-p192)",
.test = alg_test_null,
}, {
.alg = "p1363(ecdsa-nist-p256)",
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 1c69c11c0cdb4..11911bff5f793 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -32806,60 +32806,10 @@ static const struct comp_testvec lzorle_decomp_tv_template[] = {
.output = "Join us now and share the software "
"Join us now and share the software ",
},
};
-/*
- * Michael MIC test vectors from IEEE 802.11i
- */
-#define MICHAEL_MIC_TEST_VECTORS 6
-
-static const struct hash_testvec michael_mic_tv_template[] = {
- {
- .key = "\x00\x00\x00\x00\x00\x00\x00\x00",
- .ksize = 8,
- .plaintext = zeroed_string,
- .psize = 0,
- .digest = "\x82\x92\x5c\x1c\xa1\xd1\x30\xb8",
- },
- {
- .key = "\x82\x92\x5c\x1c\xa1\xd1\x30\xb8",
- .ksize = 8,
- .plaintext = "M",
- .psize = 1,
- .digest = "\x43\x47\x21\xca\x40\x63\x9b\x3f",
- },
- {
- .key = "\x43\x47\x21\xca\x40\x63\x9b\x3f",
- .ksize = 8,
- .plaintext = "Mi",
- .psize = 2,
- .digest = "\xe8\xf9\xbe\xca\xe9\x7e\x5d\x29",
- },
- {
- .key = "\xe8\xf9\xbe\xca\xe9\x7e\x5d\x29",
- .ksize = 8,
- .plaintext = "Mic",
- .psize = 3,
- .digest = "\x90\x03\x8f\xc6\xcf\x13\xc1\xdb",
- },
- {
- .key = "\x90\x03\x8f\xc6\xcf\x13\xc1\xdb",
- .ksize = 8,
- .plaintext = "Mich",
- .psize = 4,
- .digest = "\xd5\x5e\x10\x05\x10\x12\x89\x86",
- },
- {
- .key = "\xd5\x5e\x10\x05\x10\x12\x89\x86",
- .ksize = 8,
- .plaintext = "Michael",
- .psize = 7,
- .digest = "\x0a\x94\x2b\x12\x4e\xca\xa5\x46",
- }
-};
-
/*
* CRC32 test vectors
*/
static const struct hash_testvec crc32_tv_template[] = {
{
--
2.53.0
^ permalink raw reply related
* [PATCH 3/3] wifi: iwlwifi: mld: skip TX when firmware is dead
From: Cole Leavitt @ 2026-04-05 5:41 UTC (permalink / raw)
To: linux-wireless; +Cc: greearb, miriam.rachel.korenblit, johannes, cole
In-Reply-To: <20260405054145.1064152-1-cole@unwrap.rs>
When firmware encounters an error, STATUS_FW_ERROR is set but the
mac80211 TX path continues pulling frames from TXQs. Each frame
fails at iwl_trans_tx() which checks STATUS_FW_ERROR and returns
-EIO, but iwl_mld_tx_from_txq() keeps looping over every queued
frame. This burns CPU in a tight loop on dead firmware and can
cause soft lockups during firmware error recovery.
Add a STATUS_FW_ERROR check at the top of iwl_mld_tx_from_txq()
to stop pulling frames from mac80211 TXQs when firmware is dead.
Also guard iwl_mld_mac80211_tx() which bypasses the TXQ path
entirely and would otherwise continue feeding frames to dead
firmware.
Once STATUS_FW_ERROR is cleared during firmware restart, TX
resumes naturally with no explicit wake needed.
Fixes: d1e879ec600f ("wifi: iwlwifi: add iwlmld sub-driver")
Signed-off-by: Cole Leavitt <cole@unwrap.rs>
---
drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 4 ++++
drivers/net/wireless/intel/iwlwifi/mld/tx.c | 3 +++
2 files changed, 7 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index 71a9a72c9ac0..0df3be3089c3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -519,6 +519,10 @@ iwl_mld_mac80211_tx(struct ieee80211_hw *hw,
u32 link_id = u32_get_bits(info->control.flags,
IEEE80211_TX_CTRL_MLO_LINK);
+ if (unlikely(test_bit(STATUS_FW_ERROR, &mld->trans->status))) {
+ ieee80211_free_txskb(hw, skb);
+ return;
+ }
/* In AP mode, mgmt frames are sent on the bcast station,
* so the FW can't translate the MLD addr to the link addr. Do it here
*/
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tx.c b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
index 8af58aabcd68..33bd2e336166 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/tx.c
@@ -962,6 +962,9 @@ void iwl_mld_tx_from_txq(struct iwl_mld *mld, struct ieee80211_txq *txq)
struct sk_buff *skb = NULL;
u8 zero_addr[ETH_ALEN] = {};
+ if (unlikely(test_bit(STATUS_FW_ERROR, &mld->trans->status)))
+ return;
+
/*
* No need for threads to be pending here, they can leave the first
* taker all the work.
--
2.52.0
^ permalink raw reply related
* [PATCH v2 0/3] wifi: iwlwifi: mld: fix UAF and soft lockup on firmware error
From: Cole Leavitt @ 2026-04-05 5:41 UTC (permalink / raw)
To: linux-wireless; +Cc: greearb, miriam.rachel.korenblit, johannes, cole
Three fixes for the iwlmld sub-driver addressing use-after-free,
TSO segmentation explosion, and soft lockups during firmware error
recovery on Intel BE200 (WiFi7).
1/3 closes the NAPI race window where stale RX data from dying
firmware reaches the TX completion handlers, causing corrupt SSN
values to trigger skb use-after-free in iwl_trans_reclaim().
Ben Greear confirmed the WARN_ONCE fires on his test systems.
2/3 fixes the TSO segmentation explosion when AMSDU is disabled
for a TID. The TLC notification sets max_tid_amsdu_len to the
sentinel value 1, which slips past the existing zero check and
produces num_subframes=0, causing skb_gso_segment() to create
32000+ tiny segments. Revised per Miriam Korenblit's feedback to
check for the sentinel value directly and add a WARN_ON_ONCE
guard after the division as defense-in-depth.
3/3 adds STATUS_FW_ERROR checks in the TX pull path to stop
feeding frames to dead firmware. Revised per Johannes Berg's
feedback to use status bit checks instead of stop_queues/wake_queues,
which doesn't interact well with TXQ-based APIs.
Changes since v1:
- 1/3: Added Tested-by from Ben Greear
- 2/3: Check max_tid_amsdu_len == 1 (sentinel) instead of
guarding !num_subframes after division; added WARN_ON_ONCE
defense-in-depth (Suggested-by: Miriam Korenblit)
- 3/3: Replaced ieee80211_stop_queues()/wake_queues() with
STATUS_FW_ERROR checks in TX pull path (per Johannes Berg)
Cole Leavitt (3):
wifi: iwlwifi: prevent NAPI processing after firmware error
wifi: iwlwifi: mld: fix TSO segmentation explosion when AMSDU is
disabled
wifi: iwlwifi: mld: skip TX when firmware is dead
.../net/wireless/intel/iwlwifi/mld/mac80211.c | 4 +
drivers/net/wireless/intel/iwlwifi/mld/tx.c | 210 +++++------
.../wireless/intel/iwlwifi/pcie/gen1_2/rx.c | 337 +++++++++---------
3 files changed, 284 insertions(+), 267 deletions(-)
base-commit: 3aae9383f42f687221c011d7ee87529398e826b3
--
2.52.0
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox