Linux wireless drivers development
 help / color / mirror / Atom feed
* RE: [PATCH wireless-next v3 08/15] wifi: cfg80211: extend PMSR FTM response for proximity ranging
From: Stern, Avraham @ 2026-03-12 21:13 UTC (permalink / raw)
  To: Peddolla Harshavardhan Reddy, johannes@sipsolutions.net
  Cc: linux-wireless@vger.kernel.org, kavita.kavita@oss.qualcomm.com
In-Reply-To: <20260305160712.1263829-9-peddolla.reddy@oss.qualcomm.com>



> From: Peddolla Harshavardhan Reddy <peddolla.reddy@oss.qualcomm.com> 
> Sent: Thursday, March 5, 2026 6:07 PM
> To: johannes@sipsolutions.net
> Cc: linux-wireless@vger.kernel.org; kavita.kavita@oss.qualcomm.com
> Subject: [PATCH wireless-next v3 08/15] wifi: cfg80211: extend PMSR FTM response for proximity ranging

+ * @max_time_between_measurements: the negotiated maximum interval (in units of
+ *	10 ms) by which the ISTA must complete the next measurement cycle.
+ * @min_time_between_measurements: the negotiated minimum interval (in units of
+ *	100 us) between two consecutive range measurements initiated by the
+ *	ISTA.

These are not useful when processing the result

+ * @availability_window: negotiated availability window time used in this
+ *	session in units of milliseconds (u32).

This one too.

> @@ -4295,8 +4329,19 @@ struct cfg80211_pmsr_ftm_result {
> +	u32 tx_ltf_repetition_count;
> +	u32 rx_ltf_repetition_count;
> +	u32 num_tx_spatial_streams;
> +	u32 num_rx_spatial_streams;

u8 should be enough for all these.

---------------------------------------------------------------------
A member of the Intel Corporation group of companies

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


^ permalink raw reply

* RE: [PATCH wireless-next v3 07/15] wifi: cfg80211: add continuous ranging and PD request support
From: Stern, Avraham @ 2026-03-12 21:11 UTC (permalink / raw)
  To: Peddolla Harshavardhan Reddy, johannes@sipsolutions.net
  Cc: linux-wireless@vger.kernel.org, kavita.kavita@oss.qualcomm.com
In-Reply-To: <20260305160712.1263829-8-peddolla.reddy@oss.qualcomm.com>



> From: Peddolla Harshavardhan Reddy <peddolla.reddy@oss.qualcomm.com>
> Sent: Thursday, March 5, 2026 6:07 PM
> To: johannes@sipsolutions.net
> Cc: linux-wireless@vger.kernel.org; kavita.kavita@oss.qualcomm.com
> Subject: [PATCH wireless-next v3 07/15] wifi: cfg80211: add continuous ranging and PD request support

> Proximity detection (PD) applications require sustained measurement sessions without repeated FTM negotiation overhead. Currently, each ranging session requires separate negotiation.

There are already NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD, NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION and NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST, which are practically the same as nominal_time, availability_window and measurements_per_aw, respectively. These are used for pd_request with EDCA.
Maybe these can be reused for pd_request with NTB as well (with clarifying the usage in their description?)


> + * @min_time_between_measurements: minimum time between two consecutive range
> + *	measurements in units of 100 micro seconds, applicable for
> + *	non trigger based ranging. Only valid if @non_trigger_based is set.
> + * @max_time_between_measurements: maximum time between two consecutive range
> + *	measurements in units of 10 milli seconds, to avoid FTM negotiation
> + *	applicable for non trigger based ranging. Only valid
> + *	if @non_trigger_based is set.

The user doesn't need to control these. Only the periodicity parameters below.

> + * @availability_window: duration of the availability window (AW) in units of
> + *	1 millisecond (0-255 ms). Only valid if @non_trigger_based is set.
> + * @nominal_time: Nominal duration between adjacent availability windows
> + *	in units of milli seconds. Only valid if @non_trigger_based is set.
> + * @measurements_per_aw: number of measurement attempts per availability window
> + *	with a maximum value of 4. Only valid if @non_trigger_based is set.

All these should be valid only if repeated periodic measurements are requested. But there is no indication for that...
Need to add number_of_measurements (similar to NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP) to indicate how many repetitions are requested.

> +	u32 availability_window;

u8 will keep the 255 limit.

> +	u32 measurements_per_aw;

u8 is enough for a maximum of 4.
 
> +	   pd_request:1;
>  	struct cfg80211_pmsr_ftm_request_peer ftm;  };

Should be part of the ftm data. Not really needed. The device only cares if multi repetitions are requested.
 

> +	if (!out->ftm.trigger_based && !out->ftm.non_trigger_based &&
> +	    capa->ftm.max_ftms_per_burst &&
> +	    (out->ftm.ftms_per_burst > capa->ftm.max_ftms_per_burst ||
> +	     out->ftm.ftms_per_burst == 0)) {
> +		NL_SET_ERR_MSG_ATTR(info->extack,
> +				    tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST],
> +				    "FTM: FTMs per burst must be set lower than the device limit but non-zero");
> +		return -EINVAL;

If ftms_per_burst is not applicable for trigger_based and non_trigger_based, they must not be set together, not ignored.


> +	if (out->pd_request && out->ftm.non_trigger_based && !out->ftm.rsta &&
> +	    out->ftm.measurements_per_aw == 0) {
> +		NL_SET_ERR_MSG_ATTR(info->extack,
> +				    ftmreq,
> +				    "FTM: Invalid parameters:measurements per avail window is zero for NTB PD request");
> +		return -EINVAL;

measurement_per_aw is required for rsta as well.



---------------------------------------------------------------------
A member of the Intel Corporation group of companies

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


^ permalink raw reply

* RE: [PATCH wireless-next v3 06/15] wifi: cfg80211: add proximity detection capabilities to PMSR
From: Stern, Avraham @ 2026-03-12 21:08 UTC (permalink / raw)
  To: Peddolla Harshavardhan Reddy, johannes@sipsolutions.net
  Cc: linux-wireless@vger.kernel.org, kavita.kavita@oss.qualcomm.com
In-Reply-To: <20260305160712.1263829-7-peddolla.reddy@oss.qualcomm.com>



> From: Peddolla Harshavardhan Reddy <peddolla.reddy@oss.qualcomm.com> 
> Sent: Thursday, March 5, 2026 6:07 PM
> To: johannes@sipsolutions.net
> Cc: linux-wireless@vger.kernel.org; kavita.kavita@oss.qualcomm.com
> Subject: [PATCH wireless-next v3 06/15] wifi: cfg80211: add proximity detection capabilities to PMSR

> + * @pd_support: supports peer-to-peer ranging as mentioned in the specification
> + *	"PR Implementation Consideration Draft 1.9 rev 1" where PD stands for
> + *	proximity detection
> + * @pd_concurrent_ista_rsta_support: As the peer measurement request can be a
> + *	multi-peer request this will indicate if the device can act
> + *	simultaneously as initiator and a responder. Only valid if @pd_support
> + *	is set.
> * @ftm: FTM measurement data

These should be part of the FTM data.
pd_concurrent_ista_rsta_support is only valid if ftm.support_rsta is set.

> + * @ftm.max_no_of_tx_antennas: maximum number of transmit antennas supported for
> + *	ranging
> + * @ftm.max_no_of_rx_antennas: maximum number of receive antennas supported for
> + *	ranging

Supported for EDCA based ranging

> + * @ftm.min_allowed_ranging_interval_edca: Minimum EDCA ranging
> + *	interval supported by the device in milli seconds. (0 means unknown)
> + * @ftm.min_allowed_ranging_interval_ntb: Minimum NTB ranging
> + *	interval supported by the device in milli seconds. (0 means unknown)

These are not advertised anywhere, and time between measurements is not part of the measurement request from the user.
So why this capability is needed?

>  * @ftm.support_rsta: supports operating as RSTA in PMSR FTM request
> + * @ftm.support_edca_responder: supports operating as FTM responder in PMSR FTM
> + *	request for EDCA-based ranging

So support rsta means supports RSTA for NTB only now? Do we also need support TB RSTA?
 
	struct {
 		u32 preambles;
> +		u32 max_no_of_tx_antennas;
> +		u32 max_no_of_rx_antennas;

u8 should be enough

  * @NUM_NL80211_PMSR_ATTR: internal
>   * @NL80211_PMSR_ATTR_MAX: highest attribute number @@ -7841,6 +7850,8 @@ enum nl80211_peer_measurement_attrs {
> 	NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR,
>  	NL80211_PMSR_ATTR_TYPE_CAPA,
>  	NL80211_PMSR_ATTR_PEERS,
> +	NL80211_PMSR_ATTR_PD_SUPPORT,
> +	NL80211_PMSR_ATTR_PD_CONCURRENT_ISTA_RSTA_SUPPORT,
 
These should be under nl80211_peer_measurement_ftm_capa

> -	if (out->ftm.rsta && !capa->ftm.support_rsta) {
> +	if (out->ftm.rsta && !capa->ftm.support_rsta &&
> +	    !capa->ftm.support_edca_responder) {
>  		NL_SET_ERR_MSG_ATTR(info->extack,
>  				    tb[NL80211_PMSR_FTM_REQ_ATTR_RSTA],
> 				    "FTM: RSTA not supported by device");

capa->ftm.support_edca_responder is only needed if out->ftm.non_trigger_based is not set

---------------------------------------------------------------------
A member of the Intel Corporation group of companies

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


^ permalink raw reply

* RE: [PATCH wireless-next v3 04/15] wifi: cfg80211/mac80211: Add NL80211_IFTYPE_PD for PD PASN and PMSR operations
From: Stern, Avraham @ 2026-03-12 21:06 UTC (permalink / raw)
  To: Peddolla Harshavardhan Reddy, johannes@sipsolutions.net
  Cc: linux-wireless@vger.kernel.org, kavita.kavita@oss.qualcomm.com
In-Reply-To: <20260305160712.1263829-5-peddolla.reddy@oss.qualcomm.com>


> From: Peddolla Harshavardhan Reddy <peddolla.reddy@oss.qualcomm.com> > Sent: Thursday, March 5, 2026 6:07 PM
> To: johannes@sipsolutions.net
> Cc: linux-wireless@vger.kernel.org; kavita.kavita@oss.qualcomm.com
> Subject: [PATCH wireless-next v3 04/15] wifi: cfg80211/mac80211: Add NL80211_IFTYPE_PD for PD PASN and PMSR operations

> Add a new wdev-only interface type NL80211_IFTYPE_PD to support Proximity Detection (PD) operations such as PASN, key install and peer measurement operations. This interface type operates without a netdev, similar to P2P_DEVICE and NAN interfaces.

What about PD discovery?

> The PD interface provides isolated functionality for PD PASN and PMSR without affecting existing network operations.

So PMSR will be allowed on station interface (for sta to AP measurements, when possibly associated and have security context already), and on the new interface type for non-AP ranging?

> @@ -1935,6 +1938,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
>  		break;
>  	case NL80211_IFTYPE_AP_VLAN:
>  	case NL80211_IFTYPE_P2P_DEVICE:
> +	case NL80211_IFTYPE_PD:
>  		sdata->vif.bss_conf.bssid = sdata->vif.addr;
>  		break;
 
bss_conf is irrelevant for PD interface 

> @@ -898,6 +898,7 @@ int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
>  		need_offchan = true;
>  		break;
>  	case NL80211_IFTYPE_NAN:
> +	case NL80211_IFTYPE_PD:
>  		break;

PD interface doesn't have a channel context, so set need_offchan = true?

> @@ -4621,6 +4621,7 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
>  			(ieee80211_is_public_action(hdr, skb->len) ||
>  			 (ieee80211_is_auth(hdr->frame_control) &&
>  			  ether_addr_equal(sdata->vif.addr, hdr->addr1)));
> +	case NL80211_IFTYPE_PD:
> 	default:
> 		break;
 
At least check addr1, and accept only auth frames (PASN) and if used for discovery, also public action.

> @@ -13954,6 +13962,11 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
>  		      WIPHY_NAN_FLAGS_USERSPACE_DE))
> 			return -EOPNOTSUPP;
> 		break;
> +	case NL80211_IFTYPE_PD:
> +		if (!wiphy_ext_feature_isset(wdev->wiphy,
> +					     NL80211_EXT_FEATURE_SECURE_RTT))
> +			return -EOPNOTSUPP;
> +		break;

So not used for PD discovery, why?

---------------------------------------------------------------------
A member of the Intel Corporation group of companies

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


^ permalink raw reply

* [RFC PATCH] wifi: rtl8xxxu: handle rate control for 8188e a per mac_id
From: Georg Müller @ 2026-03-12 20:58 UTC (permalink / raw)
  To: Jes.Sorensen, rtl8821cerfe2
  Cc: linux-wireless, linux-kernel, Georg Müller
In-Reply-To: <d622184a-36b2-4df6-bea2-7f5c6ba9b22a@gmail.com>

convert member ra_info to an array with one entry per mac id. This
allows having different rate control settings per connected station
in ap mode.

The max_macid_num is conservative. The old driver used 32 [1], some
other sources said 64 [2]. I have not enough adapters to test any of the
higher values. Given the usage of this chipset in nano dongles, I think
the 16 might be high enough.


I am a bit unsure about the handling in of priv->vifs in
rtl8188e_handle_ra_tx_report2():

The comment says "We only use macid 0" with the remark of not handling
AP mode, but priv->vifs has only two entries (no the number of mac_ids),
so I don't know the relation between them.


[1] https://github.com/lwfinger/rtl8188eu/blob/f5d1c8df2e2d8b217ea0113bf2cf3e37df8cb716/include/sta_info.h#L28
[2] https://lore.kernel.org/linux-wireless/27e83382-4c84-1841-c428-d1e5143ea20c@gmail.com/

Signed-off-by: Georg Müller <georgmueller@gmx.net>
---
 drivers/net/wireless/realtek/rtl8xxxu/8188e.c    | 12 ++++++------
 drivers/net/wireless/realtek/rtl8xxxu/core.c     | 11 +++++++----
 drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h |  3 ++-
 3 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtl8xxxu/8188e.c b/drivers/net/wireless/realtek/rtl8xxxu/8188e.c
index 766a7a7c7d28..ca044979ba79 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/8188e.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/8188e.c
@@ -1468,9 +1468,8 @@ static void rtl8188e_reset_ra_counter(struct rtl8xxxu_ra_info *ra)
 	ra->nsc_down = (n_threshold_high[rate_id] + n_threshold_low[rate_id]) >> 1;
 }
 
-static void rtl8188e_rate_decision(struct rtl8xxxu_ra_info *ra)
+static void rtl8188e_rate_decision(struct rtl8xxxu_priv *priv, struct rtl8xxxu_ra_info *ra)
 {
-	struct rtl8xxxu_priv *priv = container_of(ra, struct rtl8xxxu_priv, ra_info);
 	const u8 *retry_penalty_idx_0;
 	const u8 *retry_penalty_idx_1;
 	const u8 *retry_penalty_up_idx;
@@ -1669,7 +1668,7 @@ void rtl8188e_handle_ra_tx_report2(struct rtl8xxxu_priv *priv, struct sk_buff *s
 	u32 *_rx_desc = (u32 *)(skb->data - sizeof(struct rtl8xxxu_rxdesc16));
 	struct rtl8xxxu_rxdesc16 *rx_desc = (struct rtl8xxxu_rxdesc16 *)_rx_desc;
 	struct device *dev = &priv->udev->dev;
-	struct rtl8xxxu_ra_info *ra = &priv->ra_info;
+	struct rtl8xxxu_ra_info *ra;
 	u32 tx_rpt_len = rx_desc->pktlen & 0x3ff;
 	u32 items = tx_rpt_len / TX_RPT2_ITEM_SIZE;
 	u64 macid_valid = ((u64)_rx_desc[5] << 32) | _rx_desc[4];
@@ -1688,6 +1687,7 @@ void rtl8188e_handle_ra_tx_report2(struct rtl8xxxu_priv *priv, struct sk_buff *s
 
 	for (macid = 0; macid < items; macid++) {
 		valid = false;
+		 ra = &priv->ra_info[macid];
 
 		if (macid < 64)
 			valid = macid_valid & BIT(macid);
@@ -1704,7 +1704,7 @@ void rtl8188e_handle_ra_tx_report2(struct rtl8xxxu_priv *priv, struct sk_buff *s
 
 			if (ra->total > 0) {
 				if (ra->ra_stage < 5)
-					rtl8188e_rate_decision(ra);
+					rtl8188e_rate_decision(priv, ra);
 				else if (ra->ra_stage == 5)
 					rtl8188e_power_training_try_state(ra);
 				else /* ra->ra_stage == 6 */
@@ -1781,7 +1781,7 @@ rtl8188e_update_rate_mask(struct rtl8xxxu_priv *priv,
 			  u32 ramask, u8 rateid, int sgi, int txbw_40mhz,
 			  u8 macid)
 {
-	struct rtl8xxxu_ra_info *ra = &priv->ra_info;
+	struct rtl8xxxu_ra_info *ra = &priv->ra_info[macid];
 
 	ra->rate_id = rateid;
 	ra->rate_mask = ramask;
@@ -1792,7 +1792,7 @@ rtl8188e_update_rate_mask(struct rtl8xxxu_priv *priv,
 
 static void rtl8188e_ra_set_rssi(struct rtl8xxxu_priv *priv, u8 macid, u8 rssi)
 {
-	priv->ra_info.rssi_sta_ra = rssi;
+	priv->ra_info[macid].rssi_sta_ra = rssi;
 }
 
 void rtl8188e_ra_info_init_all(struct rtl8xxxu_ra_info *ra)
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/core.c b/drivers/net/wireless/realtek/rtl8xxxu/core.c
index 794187d28caa..570b1d58e475 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/core.c
+++ b/drivers/net/wireless/realtek/rtl8xxxu/core.c
@@ -3921,6 +3921,7 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
 	struct device *dev = &priv->udev->dev;
 	struct rtl8xxxu_fileops *fops = priv->fops;
 	bool macpower;
+	u16 mac_id;
 	int ret;
 	u8 val8;
 	u16 val16;
@@ -4393,9 +4394,11 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
 		priv->cfo_tracking.crystal_cap = priv->default_crystal_cap;
 	}
 
-	if (priv->rtl_chip == RTL8188E)
-		rtl8188e_ra_info_init_all(&priv->ra_info);
-
+	if (priv->rtl_chip == RTL8188E)	{
+		for (mac_id = 0; mac_id < ARRAY_SIZE(priv->ra_info); mac_id++) {
+			rtl8188e_ra_info_init_all(&priv->ra_info[mac_id]);
+		}
+	}
 	set_bit(RTL8XXXU_BC_MC_MACID, priv->mac_id_map);
 	set_bit(RTL8XXXU_BC_MC_MACID1, priv->mac_id_map);
 
@@ -5338,7 +5341,7 @@ rtl8xxxu_fill_txdesc_v3(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
 {
 	struct rtl8xxxu_priv *priv = hw->priv;
 	struct device *dev = &priv->udev->dev;
-	struct rtl8xxxu_ra_info *ra = &priv->ra_info;
+	struct rtl8xxxu_ra_info *ra = &priv->ra_info[macid];
 	u8 *qc = ieee80211_get_qos_ctl(hdr);
 	u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
 	u32 rate = 0;
diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
index 9fb2583ffffc..6a415b9c3bd9 100644
--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
@@ -76,6 +76,7 @@
 #define RTL_FW_PAGE_SIZE		4096
 #define RTL8XXXU_FIRMWARE_POLL_MAX	1000
 
+#define RTL8188E_MAX_MAC_ID_NUM		16
 #define RTL8723A_CHANNEL_GROUPS		3
 #define RTL8723A_MAX_RF_PATHS		2
 #define RTL8723B_CHANNEL_GROUPS		6
@@ -1916,7 +1917,7 @@ struct rtl8xxxu_priv {
 	struct rtl8xxxu_btcoex bt_coex;
 	struct rtl8xxxu_ra_report ra_report;
 	struct rtl8xxxu_cfo_tracking cfo_tracking;
-	struct rtl8xxxu_ra_info ra_info;
+	struct rtl8xxxu_ra_info ra_info[RTL8188E_MAX_MAC_ID_NUM];
 
 	bool led_registered;
 	char led_name[32];
-- 
2.53.0


^ permalink raw reply related

* RE: [PATCH wireless-next v3 02/15] wifi: cfg80211: cancel pmsr_free_wk in cfg80211_pmsr_wdev_down
From: Stern, Avraham @ 2026-03-12 21:04 UTC (permalink / raw)
  To: Peddolla Harshavardhan Reddy, johannes@sipsolutions.net
  Cc: linux-wireless@vger.kernel.org, kavita.kavita@oss.qualcomm.com
In-Reply-To: <20260305160712.1263829-3-peddolla.reddy@oss.qualcomm.com>



> From: Peddolla Harshavardhan Reddy <peddolla.reddy@oss.qualcomm.com> 
> Sent: Thursday, March 5, 2026 6:07 PM
> To: johannes@sipsolutions.net
> Cc: linux-wireless@vger.kernel.org; kavita.kavita@oss.qualcomm.com
> Subject: [PATCH wireless-next v3 02/15] wifi: cfg80211: cancel pmsr_free_wk in cfg80211_pmsr_wdev_down

> When the nl80211 socket that originated a PMSR request is closed, cfg80211_release_pmsr() sets the request's nl_portid to zero and schedules pmsr_free_wk to process the abort asynchronously. If the interface is concurrently torn down before that work runs, cfg80211_pmsr_wdev_down() calls
> cfg80211_pmsr_process_abort() directly. However, the already- scheduled pmsr_free_wk work item remains pending and may run after the interface has been removed from the driver. This could cause the driver's abort_pmsr callback to operate on a torn-down interface, leading to undefined behavior and potential crashes.

pmsr_free_wk work is cancelled on NETDEV_GOING_DOWN, so this makes sure wdev is still valid when it runs.
Why isn't it sufficient?


---------------------------------------------------------------------
A member of the Intel Corporation group of companies

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


^ permalink raw reply

* RE: [PATCH wireless-next v3 01/15] wifi: cfg80211: Allow RSTA role without LMR request
From: Stern, Avraham @ 2026-03-12 21:03 UTC (permalink / raw)
  To: Peddolla Harshavardhan Reddy, johannes@sipsolutions.net
  Cc: linux-wireless@vger.kernel.org, kavita.kavita@oss.qualcomm.com
In-Reply-To: <20260305160712.1263829-2-peddolla.reddy@oss.qualcomm.com>



Hi Peddolla

> From: Peddolla Harshavardhan Reddy <peddolla.reddy@oss.qualcomm.com>
> Sent: Thursday, March 5, 2026 6:07 PM
> To: johannes@sipsolutions.net
> Cc: linux-wireless@vger.kernel.org; kavita.kavita@oss.qualcomm.com
> Subject: [PATCH wireless-next v3 01/15] wifi: cfg80211: Allow RSTA 
> role without LMR request

> Currently when enabling RSTA role in PMSR FTM requests,
> pmsr_parse_ftm() mandates LMR feedback to be requested. This

I2R LMR is mandatory when the RSTA is not continuously available on-channel:
I2R LMR is required for ISTA to request AW changes (NNW bit) and to terminate the session.

> prevents valid use cases where devices need to operate as RSTA without 
> waking the host for measurement reports.

Devices can decide not to wake the host although I2R LMR was used over the air.
But with current API, cfg80211_pmsr_report() is expected to be called in response.
So maybe need a different flag to indicate no response?

Avi

---------------------------------------------------------------------
A member of the Intel Corporation group of companies

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.


^ permalink raw reply

* Re: [PATCH 48/61] mtd: Prefer IS_ERR_OR_NULL over manual NULL check
From: Richard Weinberger @ 2026-03-12 19:33 UTC (permalink / raw)
  To: Philipp Hahn
  Cc: amd-gfx, apparmor, bpf, ceph-devel, cocci, dm-devel,
	DRI mailing list, gfs2, intel-gfx, intel-wired-lan, iommu, kvm,
	linux-arm-kernel, linux-block, linux-bluetooth, linux-btrfs,
	linux-cifs, linux-clk, linux-erofs, linux-ext4, linux-fsdevel,
	linux-gpio, linux-hyperv, linux-input, linux-kernel, linux-leds,
	linux-media, linux-mips, linux-mm, linux-modules, linux-mtd,
	linux-nfs, linux-omap, linux-phy, linux-pm, linux-rockchip,
	linux-s390, linux-scsi, linux-sctp, LSM, linux-sh, linux-sound,
	linux-stm32, linux-trace-kernel, linux-usb, linux-wireless,
	netdev, ntfs3, samba-technical, sched-ext, target-devel,
	tipc-discussion, v9fs, Miquel Raynal, Vignesh Raghavendra
In-Reply-To: <20260310-b4-is_err_or_null-v1-48-bd63b656022d@avm.de>

----- Ursprüngliche Mail -----
> Von: "Philipp Hahn" <phahn-oss@avm.de>
> -	if (gpiomtd->nwp && !IS_ERR(gpiomtd->nwp))
> +	if (!IS_ERR_OR_NULL(gpiomtd->nwp))

No, please don't.

This makes reading the code not easier.

Thanks,
//richard

^ permalink raw reply

* Re: [PATCH wireless-next v8 2/3] wifi: cfg80211: add initial UHR support
From: Johannes Berg @ 2026-03-12 19:32 UTC (permalink / raw)
  To: Harshitha Prem, linux-wireless
  Cc: Karthikeyan Kathirvel, vasanthakumar.thiagarajan,
	Lorenzo Bianconi, ath12k, Jeff Johnson, Ping-Ke Shih,
	Manish Dharanenthiran, Jouni Malinen, Benjamin Berg
In-Reply-To: <c676b2cd73463fa88f459f0416c60b03f20dd027.camel@sipsolutions.net>


> > Because of this, an event-driven approach was considered.

So - starting this again from scratch. Benjamin and I spent some time
discussing this today too, and hashed out a (mostly?) workable solution
that should address most of the issues. I'll try to summarise that
below.

As will become obvious - and that's why I quoted only the line _you_
wrote before - this means we (including myself :)) need to stop being
afraid of hostapd doing (soft?) real-time [1] tasks...

[1] I'm using that word in the (formal) sense of having a deadline, not
of having to be particularly fast.


Let's assume the following constraints:

- preparing a beacon template as a real-time task can be done by
hostapd, given enough heads-up time
- no periodic events in a steady state when the AP is operating
normally
- TSF drift between links is correctly handled (maintaining <=30us
offset at any time)

We evidently already make these assumptions:

- if beacon intervals are not the same, the TBTT offset in RNR is
filled in by firmware (I see no way around this)
- either firmware fills in TSF offset, or it's just zero, and not
really accounting for slight drifts (but that's probably OK since it
never adds up given the <=30us requirement)

And also let's introduce some new operations to driver/firmware:

- the firmware can drop a frame that it's not able to transmit before
a given (as frame metadata) TSF value on the link, and indicate to
the driver that this is the reason the frame was dropped
- the firmware can create events at/after beacon TBTT (or beacon
transmission), this can be controlled by the driver; these events
contain the next TBTT's timestamp value
- the TSF offsets between links can be known to the driver, if they can
change (I suspect CSA could do that?) this can somehow be noticed by
or given to the driver

With that, it seems we can redesign this whole thing to be event-driven
and (mostly?) race-free.

In steady state, basically nothing would change from what hostapd is
doing today. It simply configures beacon templates, occasionally updates
them if elements need to change, and sends probe responses,
(re)association responses etc. as usual.

During any sort of update (CSA, color change, EHT updates, UHR updates)
things operate a bit differently:

1) hostapd enables TBTT / beacon transmit events, these events would be
generated by firmware and passed up, for each link, containing also the
TBTT timestamp of the _next_ beacon to be transmitted

2) hostapd waits for the TBTT event for the link that it wants to do the
update on, ignoring events for other links

3) starting from that TBTT event, on each TBTT event hostapd generates a
new beacon template for the link the event was for, and configures it to
the driver/firmware. Since that's a future beacon, it has to predict the
content of that beacon using
- the TBTT of the first beacon carrying the update announcement
- the TSF offsets between the links
- the beacon intervals of all the links
(a bit more on this later)

4) After applying the updates (a bit more on this later) and noticing
that the announcements are finished, hostapd waits for one more TBTT
event for each link and configures the beacons back to steady state,
after which it turns off the events.

If, at any time during this, hostapd needs to send a probe response,
(re)association response, EPP Capa/Operation response (or others?) which
holds information about the updates with the current counter values,
hostapd will create the frame per the current counters that it
maintains, and will transmit this frame with a TSF cut-off value
indicating that it must be transmitted before the next TBTT (over all
links), or dropped.
If this frame ends up being dropped by firmware because it didn't get
out before the indicated TSF, hostapd gets a specific notification for
this and then simply re-generates it and sends it again. This could
possibly repeat if TBTTs are close together on multiple links, but I
think it's not worth optimising for this case, though it could be done
by deferring the response slightly based on timers, or at the expense of
a more complex API ("defer until X and don't send after Y" vs. "don't
send after Y"), neither seems really worthwhile.


I said I'd give more information for (3) and (4) above, so:

For (3), also consider that it already has to effectively be able to do
this for the templates thing we discussed, it has to predict what each
link is going to look like in the future. I think this isn't too much of
an issue, but care must be taken especially if beacon intervals differ.

For (4), I think the way how the updates are done may depend on what the
update is. If, for example, it's DBE increasing the bandwidth, then
could just do the update _before_ the 0 beacon is transmitted, and if
it's decreasing bandwidth could do it _after_ the 0 beacon is
transmitted. Some of these may potentially require management by the
kernel or even driver/firmware (how do you switch NPCA parameters at the
exact right point if not in FW?), and perhaps (especially for CSA?)
there will be some considerations regarding multiple interfaces.
I mostly think this question is orthogonal, since armed with a TBTT
hostapd could also request that this update be done at a given TBTT.


We haven't really been able to poke significant holes into this, but
maybe that doesn't mean much. Couple of thoughts on that:

 * For each link, hostapd has roughly the whole beacon interval to build
   the next beacon's template, which seems reasonable.
 * There's a really weird corner case where an assoc response is
   attempted to transmit just before a beacon, doesn't get an ACK, but a
   retransmission isn't possible until after the beacon and it's dropped
   due to the TSF cut-off. Doesn't seem worth worrying about.
 * If the TBTTs for two links are at the same time, and the events to
   userspace for them are not coming "updated link first", then the
   beacon transmitted at the same time on the unchanged link may not yet
   be announcing the update, depending on the event order, given that
   hostapd waited for the affected link's first TBTT event. This doesn't
   really seem like a problem, but I think could be addressed by
   updating all the links on the first event immediately or so, or
   (Benjamin prefers this I think) adding the first beacon's TBTT to the
   response to the event enable command, I just worry that would cause
   other races that would need to be addressed.

That's it for now :) Let me know what you think.

johannes

^ permalink raw reply

* Re: [PATCH 1/2] mt76: connac: fix txpower_cur not updated in mt76_connac_mcu_set_rate_txpower()
From: bryam vargas @ 2026-03-12 18:22 UTC (permalink / raw)
  To: Sean Wang
  Cc: linux-wireless, nbd, lorenzo,
	moderated list:ARM/Mediatek SoC support
In-Reply-To: <CANAPQzj24sTgnuXMo3wqVDhA==UQ6JQLESk0AernQUUmZvTi2w@mail.gmail.com>

Subject: Bug: mt7921u unrecoverable chip hang requiring system reboot
(USB device disappears from bus)

Hi,

I'm filing a bug report for a recurring failure mode on the MT7921U USB
WiFi adapter where the chip becomes completely unresponsive and
eventually disappears from the USB bus, requiring a full system reboot
to recover.

This follows up on Sean Wang's suggestion to document the failure before
proposing driver-level recovery mechanisms.


== Hardware ==

  System:    Minisforum NAB9 (Intel i9-12900H)
  Adapter:   MediaTek MT7921AU USB (VID 35bc, PID 0107)
  Kernel:    6.18.x (Ubuntu 24.04)
  Location:  Bogotá, Colombia (2400m altitude)
  Uptime:    Continuous operation as home server (6-12 daily users)


== Symptoms ==

The MT7921U periodically enters a state where:

1. nmcli device show / iw dev wlan0 info time out
2. WiFi scan requests hang indefinitely
3. The interface exists in ip link but is non-functional
4. All software recovery attempts fail (driver reload, USB
   unbind/rebind, USB controller reset, uhubctl power cycle)
5. The device eventually disappears from lsusb entirely
6. Only a full system reboot restores the adapter


== Structured Event Log ==

I run an automated monitoring script (net-rescue.sh) that checks chip
responsiveness every 10 minutes and logs events with timestamps and
system uptime. Here is the complete chip-events.log from January
through March 2026:

Recoverable events (soft USB reset succeeds):
  2026-01-11 20:29 HANG -> RECOVERED (soft_usb_reset) [8s]
  2026-01-11 20:34 HANG -> RECOVERED (soft_usb_reset) [7s]
  2026-01-11 20:45 HANG -> RECOVERED (soft_usb_reset) [8s]
  2026-01-11 20:55 HANG -> RECOVERED (soft_usb_reset) [7s]
  2026-01-14 09:34 HANG -> RECOVERED (soft_usb_reset) [373s]
  2026-01-16 13:37 HANG -> RECOVERED (soft_usb_reset) [313s]
  2026-01-17 15:21 HANG -> RECOVERED (soft_usb_reset) [129s]
  2026-02-28 13:49 HANG -> RECOVERED (soft_usb_reset) [99s]

Unrecoverable events (all escalation levels fail):
  2026-01-13 17:16 HANG -> FAILED (all_recovery_attempts_failed)
  2026-01-26 14:10 HANG -> FAILED (all_recovery_attempts_failed)
  2026-02-09 14:33 HANG -> FAILED (all_recovery_attempts_failed)
  2026-02-11 11:07 HANG -> FAILED -> 14x DISAPPEARED over 3+ hours
  2026-02-22 09:45 HANG -> FAILED -> 35x DISAPPEARED over 6+ hours

The DISAPPEARED entries mean the device is no longer visible on the
USB bus at all. The monitoring script runs every ~10 minutes, so each
DISAPPEARED entry is a separate detection cycle confirming the device
remains absent.

The Feb 11 and Feb 22 incidents are the most telling: after the initial
hang and failed recovery, the chip vanished from the bus entirely and
stayed gone for hours until the daily 2:00 AM scheduled reboot
restored it.


== Recovery Escalation (all fail in unrecoverable case) ==

  Level 1: USB deauthorize/reauthorize via sysfs
  Level 2: modprobe -r mt7921u / modprobe mt7921u
  Level 3: USB unbind/rebind via /sys/bus/usb/drivers/usb/
  Level 4: uhubctl power cycle (physical power cut to USB port)
  Level 5: xhci_pci / ehci_pci module reload

When the chip enters the unrecoverable state, mt792xu_wfsys_reset()
cannot succeed because the chip does not respond to USB vendor
requests. Even cutting physical power to the USB port via uhubctl
and restoring it does not bring the device back. Only a full system
reboot (which resets the xHCI controller at BIOS level) recovers it.


== Pattern Analysis ==

From the event log:
  - 10 HANG events over ~2 months of continuous operation
  - 8 recovered via soft USB reset (80% success rate)
  - 5 required system reboot (escalation completely failed)
  - 2 incidents with extended DISAPPEARED state (3-6 hours)

The Jan 11 cluster (4 HANGs in 30 minutes) suggests a transient
condition that resolves with soft resets. The Feb 11 and Feb 22
incidents represent a different, more severe failure where the
chip enters a state that no software recovery can address.


== Pending Data ==

I can provide the following on request or when the next event occurs:
  - Full dmesg around HANG/DISAPPEARED transitions
  - lsusb -t (USB topology) and lsusb -v -d 0e8d:7961
  - usbmon traces during the failure
  - journalctl entries from net-rescue.service

The static USB data (topology, device descriptor) I can provide
immediately. The dynamic data (dmesg during failure) requires waiting
for the next natural occurrence, as the system has been stable since
the last incident.


== Related Reports ==

  https://github.com/openwrt/mt76/issues/838
  https://github.com/morrownr/USB-WiFi/issues/410
  https://github.com/raspberrypi/linux/issues/5193

All describe the same symptom: mt7921u interface becomes a zombie
(UP but unable to TX/RX), requiring physical USB unplug or system
reboot.


== Note on Environment ==

This system operates at 2400m altitude where atmospheric neutron
flux is elevated compared to sea level. I initially attributed these
events to cosmic radiation-induced SEFI (Single Event Functional
Interrupt), but as Sean correctly pointed out, the failure mode needs
to be understood before attributing a cause. The structured event log
is provided as evidence of the failure pattern regardless of root
cause.

This is a home server under active development running multiple
services (ERP, Minecraft, Tailscale, DNS/DHCP, containers). When the
chip enters the unrecoverable state and I'm not physically near the
hardware, the system can remain without WiFi connectivity for days
until I can manually reboot it.

Best regards,
Bryam Vargas

^ permalink raw reply

* Re: [syzbot ci] Re: iwlwifi + mac80211 stability
From: Johannes Berg @ 2026-03-12 17:44 UTC (permalink / raw)
  To: Ben Greear, syzbot ci, linux-wireless; +Cc: syzbot, syzkaller-bugs
In-Reply-To: <1e6b8cbb-0f89-6b9b-b2cf-d21ca80dd7a2@candelatech.com>

On Thu, 2026-03-12 at 08:25 -0700, Ben Greear wrote:
> Which would be triggered by this from patch 0004, I guess.   The phyd
> pointer appears to be an error code -13 instead of clean NULL, so I guess I
> need to add checks for where that is created as well.

No ...

> --- a/net/mac80211/debugfs.c
> +++ b/net/mac80211/debugfs.c
> @@ -680,6 +680,12 @@ void debugfs_hw_add(struct ieee80211_local *local)
>   		return;
> 
>   	local->debugfs.keys = debugfs_create_dir("keys", phyd);
> +	if (IS_ERR(local->debugfs.keys)) {
> +		pr_err("Failed to create local keys debugfs dir, rv: %ld phyd: 0x%px\n",
> +		       (long)(local->debugfs.keys), phyd);
> +		local->debugfs.keys = NULL;
> +		return;
> +	}

That's just never going to get applied anyway, so what you _really_ need
to do is stop sending this crap.

johannes

^ permalink raw reply

* Re: [PATCH v2 1/2] mt76: mt7921: add mt7921-specific get_txpower callback
From: Lucid Duck @ 2026-03-12 17:38 UTC (permalink / raw)
  To: bryam vargas
  Cc: Sean Wang, Felix Fietkau, Lorenzo Bianconi, linux-wireless,
	linux-mediatek
In-Reply-To: <CANAPQzgD312EPSbvaQTE6U+wn85L65+xZHms7DP509ApxWvSZA@mail.gmail.com>

Hi Bryam, Sean,

I tested this on my MT7921AU USB adapter (Alfa AWUS036AXML, Fedora,
kernel 6.18.16, ISED/Canada). The callback itself is clean and with
one fix it gives correct values on all three bands, stable across a
full gauntlet. Nice work.


chanctx channel source (affects all mt7921 phy->chandef readers)
-----------------------------------------------------------------

This one bit me during testing and is worth flagging because it
affects more than just the callback. mt7921 uses the chanctx model,
and mt7921_add_chanctx() stores the context in dev->new_ctx without
updating phy->chandef. So phy->chandef.chan stays stuck on whatever
channel the firmware scanned at probe time -- channel 229 (6 GHz) on
my system. I confirmed via debugfs: "Tx power table (channel 229)"
while actually connected to 2.4 GHz ch6.

Because the callback reads phy->chandef.chan->max_power, it returns
12 dBm on every band. mt76_get_power_bound() has the same issue
internally since it also reads phy->chandef.chan.

The fix that worked for me: read the channel from the VIF chanctx
(falling back to phy->chandef.chan when unassociated) and inline the
SAR + delta math to avoid get_power_bound:

    rcu_read_lock();
    ctx = rcu_dereference(vif->bss_conf.chanctx_conf);
    chan = ctx ? ctx->def.chan : phy->chandef.chan;
    rcu_read_unlock();

    if (!chan)
        return mt76_get_txpower(hw, vif, link_id, dbm);

    n_chains = hweight16(phy->chainmask);
    delta = mt76_tx_power_path_delta(n_chains);
    tx_power = mt76_get_sar_power(phy, chan, chan->max_power * 2);
    tx_power -= delta;
    tx_power = mt76_get_rate_power_limits(phy, chan, &limits, tx_power);
    *dbm = DIV_ROUND_UP(tx_power + delta, 2);


A note on Sean's rate power loop direction
-------------------------------------------

Sean's feedback on both our patches points toward deriving the
reported value from mt76_connac_mcu_rate_txpower_band() -- the loop
that computes per-rate power limits before sending SKU tables to
firmware. That would sidestep the chanctx issue entirely since
txpower_cur gets written at configuration time rather than computed
at query time.

Looking at the code, mt7915 already does this (mt7915/mcu.c:3396):

    tx_power = mt76_get_rate_power_limits(...);
    mphy->txpower_cur = tx_power;

The connac equivalent calls mt76_get_rate_power_limits() in the same
loop but discards the return value. If that were fixed to match
mt7915, the existing mt76_get_txpower() would report correctly
without a per-driver callback.

That approach would also cover user txpower limits for free --
`iw dev set txpower fixed 1500` currently succeeds but the callback
reports the regulatory ceiling because it starts from chan->max_power.
The rate power loop already reads 2 * phy->hw->conf.power_level
(mt76_connac_mcu.c:2162), so user limits would be reflected
automatically.

Either way, happy to help test whatever direction v3 takes.


Test results (chanctx fix applied)
------------------------------------

Alfa AWUS036AXML (MT7921AU, USB, 2x2 MIMO)
Kernel 6.18.16-200.fc43.x86_64, ISED/Canada

    Per-band (10 runs each):
      2.4 GHz ch6:   30.00 dBm  (ISED: 30)   10/10 PASS
      5 GHz ch100:   26.00 dBm  (ISED: 26)   10/10 PASS
      6 GHz ch5:     12.00 dBm  (ISED: 12)   10/10 PASS

    Band switching:           18/18 correct
    Rapid cycling (20/band):  60/60 PASS
    Regdomain (CA/US/CA):     9/9 PASS (5 GHz: 26->24->26)
    60-min soak (5 GHz):      61/61 PASS, zero drift
    USB torture (module reload, monitor cycling, assoc interrupt):
                              20/20 PASS
    Kernel errors:            zero across all phases

Tested-by: Lucid Duck <lucid_duck@justthetip.ca>

^ permalink raw reply

* Re: [PATCH] wifi: rtl8xxxu: Enable AP mode for RTL8188EU
From: Bitterblue Smith @ 2026-03-12 17:06 UTC (permalink / raw)
  To: Georg Müller, Jes.Sorensen; +Cc: linux-wireless, linux-kernel
In-Reply-To: <98711825-cbf3-46ad-a26c-9f1d284480ac@gmx.net>

On 12/03/2026 18:08, Georg Müller wrote:
> 
> Am 12.03.26 um 16:58 schrieb Bitterblue Smith:
>> On 12/03/2026 16:21, Georg Müller wrote:
>>> Allow devices with this driver to be used as a wireless access point.
>>>
>>> I successfully tested this with a TP-Link TP-Link TL-WN725N adapter.
>>>
>>> Experiments two years ago failed, but some other improvements to the
>>> driver seemed to have resolved theses issues.
>>>
>>
>> The rate control code still doesn't handle more than one station.
>> It's not going to work right.
>>
>> It shouldn't be too complicated. The ra_info member of rtl8xxxu_priv
>> needs to become an array.
> 
> Ok, I have only tested it with one client in my setup.
> 
> So the ra_info array needs to of size max_macid_num?
> Dynamically allocated or hard-coded in struct rtl8xxxu_priv (8188e seems
> to be the only user of struct rtl8xxxu_ra_info)?
> 

Yes. :)

Also, if I remember correctly, there was a member of rtl8xxxu_ra_info
that needs to be moved to rtl8xxxu_priv, because it's a global thing,
not per macid.

> Best regards,
> Georg
> 


^ permalink raw reply

* [PATCH wireless-next v2 26/28] wifi: mac80211: Ensure link work-items are only initialized once.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>

From: Ben Greear <greearb@candelatech.com>

Re-initialization could cause corruption in work queues in case
links were not properly stopped for some reason.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 net/mac80211/ieee80211_i.h |  1 +
 net/mac80211/link.c        | 28 ++++++++++++++++++++--------
 2 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index d71e0c6d2165..ac4e10f16cd9 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1079,6 +1079,7 @@ struct ieee80211_link_data {
 
 
 	bool operating_11g_mode;
+	bool already_initialized; /* has ieee80211_link_init been called? */
 
 	struct {
 		struct wiphy_work finalize_work;
diff --git a/net/mac80211/link.c b/net/mac80211/link.c
index 03bfca27d205..6125e79f67c9 100644
--- a/net/mac80211/link.c
+++ b/net/mac80211/link.c
@@ -110,14 +110,25 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
 	link->user_power_level = sdata->local->user_power_level;
 	link_conf->txpower = INT_MIN;
 
-	wiphy_work_init(&link->csa.finalize_work,
-			ieee80211_csa_finalize_work);
-	wiphy_work_init(&link->color_change_finalize_work,
-			ieee80211_color_change_finalize_work);
-	wiphy_delayed_work_init(&link->color_collision_detect_work,
-				ieee80211_color_collision_detection_work);
-	wiphy_hrtimer_work_init(&link->dfs_cac_timer_work,
-				ieee80211_dfs_cac_timer_work);
+	if (link->already_initialized) {
+		wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
+					  &link->color_collision_detect_work);
+		wiphy_work_cancel(link->sdata->local->hw.wiphy,
+				  &link->color_change_finalize_work);
+		wiphy_work_cancel(link->sdata->local->hw.wiphy,
+				  &link->csa.finalize_work);
+		wiphy_hrtimer_work_cancel(link->sdata->local->hw.wiphy,
+					  &link->dfs_cac_timer_work);
+	} else {
+		wiphy_work_init(&link->csa.finalize_work,
+				ieee80211_csa_finalize_work);
+		wiphy_work_init(&link->color_change_finalize_work,
+				ieee80211_color_change_finalize_work);
+		wiphy_delayed_work_init(&link->color_collision_detect_work,
+					ieee80211_color_collision_detection_work);
+		wiphy_hrtimer_work_init(&link->dfs_cac_timer_work,
+					ieee80211_dfs_cac_timer_work);
+	}
 
 	if (!deflink) {
 		switch (sdata->vif.type) {
@@ -138,6 +149,7 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
 		ieee80211_link_debugfs_add(link);
 	}
 
+	link->already_initialized = true;
 	rcu_assign_pointer(sdata->vif.link_conf[link_id], link_conf);
 	rcu_assign_pointer(sdata->link[link_id], link);
 }
-- 
2.42.0


^ permalink raw reply related

* [PATCH wireless-next v2 28/28] wifi: mac80211: Decrease WARN spam.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>

From: Ben Greear <greearb@candelatech.com>

Comment one of them out, and make another WARN_ONCE.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 net/mac80211/link.c | 1 -
 net/mac80211/util.c | 3 ++-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/link.c b/net/mac80211/link.c
index 6125e79f67c9..e3a825ea3a04 100644
--- a/net/mac80211/link.c
+++ b/net/mac80211/link.c
@@ -544,7 +544,6 @@ static int _ieee80211_set_active_links(struct ieee80211_sub_if_data *sdata,
 		ret = drv_change_sta_links(local, sdata, &sta->sta,
 					   old_active | active_links,
 					   active_links);
-		WARN_ON_ONCE(ret);
 
 		/*
 		 * Do it again, just in case - the driver might very
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index ec11ee6b8752..df156f8b5211 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1879,7 +1879,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
 		if (suspended)
 			WARN(1, "Hardware became unavailable upon resume. This could be a software issue prior to suspend or a hardware issue.\n");
 		else
-			WARN(1, "Hardware became unavailable during restart.\n");
+			WARN_ONCE(1, "Hardware became unavailable during restart: %d\n", res);
+
 		ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
 						IEEE80211_QUEUE_STOP_REASON_SUSPEND,
 						false);
-- 
2.42.0


^ permalink raw reply related

* [PATCH wireless-next v2 25/28] wifi: iwlwifi: mld: Fix bad return address in tx code.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>

From: Ben Greear <greearb@candelatech.com>

iwl_mld_txq_from_mac80211 was returning the offset into
txq without checking if txq was NULL.  In case txq is
NULL, this would return a small, but non NULL pointer.

The safety check in calling code would then treat it
as non-null and attempt to dereference.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 drivers/net/wireless/intel/iwlwifi/mld/tx.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/tx.h b/drivers/net/wireless/intel/iwlwifi/mld/tx.h
index 520f15f9d33c..8b0da098c25f 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/tx.h
+++ b/drivers/net/wireless/intel/iwlwifi/mld/tx.h
@@ -45,6 +45,8 @@ static inline void iwl_mld_init_txq(struct iwl_mld_txq *mld_txq)
 static inline struct iwl_mld_txq *
 iwl_mld_txq_from_mac80211(struct ieee80211_txq *txq)
 {
+	if (!txq)
+		return NULL;
 	return (void *)txq->drv_priv;
 }
 
-- 
2.42.0


^ permalink raw reply related

* [PATCH wireless-next v2 22/28] wifi: mac80211: Add force-cleanup call to driver.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>

From: Ben Greear <greearb@candelatech.com>

When hardware is determined by mac80211 to be in non-recoverable
state, then SDATA_IN_DRIVER flag is removed, and mac80211 will no
longer do any 'graceful' teardown of the objects in the driver.

This was causing use-after-free crashes in the iwlwifi driver
since it's logic to do internal cleanup is not quite right for
some reason.

Add an explicit callback to the driver to tell it to clean up
whatever it needs to clean up in case mac80211 considers it
dead.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 include/net/mac80211.h    | 7 +++++++
 net/mac80211/driver-ops.h | 8 ++++++++
 net/mac80211/util.c       | 5 +++++
 3 files changed, 20 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 9cc482191ab9..d963f213863b 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3934,6 +3934,12 @@ struct ieee80211_prep_tx_info {
  *	you should ensure to cancel it on this callback.
  *	Must be implemented and can sleep.
  *
+ * @force_cleanup: Called after mac80211 determines the
+ *      driver/firmware/hardware has failed and cannot
+ *      be restarted.  SDATA_IN_DRIVER is false at this point,
+ *      so normal cleanup will not happen.  This force_cleanup
+ *      operation lets the driver do any needed houskeeping.
+ *
  * @suspend: Suspend the device; mac80211 itself will quiesce before and
  *	stop transmitting and doing any other configuration, and then
  *	ask the device to suspend. This is only invoked when WoWLAN is
@@ -4569,6 +4575,7 @@ struct ieee80211_ops {
 		   struct sk_buff *skb);
 	int (*start)(struct ieee80211_hw *hw);
 	void (*stop)(struct ieee80211_hw *hw, bool suspend);
+	void (*force_cleanup)(struct ieee80211_hw *hw);
 #ifdef CONFIG_PM
 	int (*suspend)(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan);
 	int (*resume)(struct ieee80211_hw *hw);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index e2283d7dcd1e..3bd3d078ce9b 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -300,6 +300,14 @@ static inline void drv_cancel_hw_scan(struct ieee80211_local *local,
 	trace_drv_return_void(local);
 }
 
+static inline void
+drv_force_cleanup(struct ieee80211_local *local)
+{
+	lockdep_assert_wiphy(local->hw.wiphy);
+	if (local->ops->force_cleanup)
+		local->ops->force_cleanup(&local->hw);
+}
+
 static inline int
 drv_sched_scan_start(struct ieee80211_local *local,
 		     struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 55054de62508..ec11ee6b8752 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1692,6 +1692,11 @@ static void ieee80211_handle_reconfig_failure(struct ieee80211_local *local)
 	 */
 	list_for_each_entry(ctx, &local->chanctx_list, list)
 		ctx->driver_present = false;
+
+	/* Tell driver to purge any remaining configuration it may have
+	 * lingering around.
+	 */
+	drv_force_cleanup(local);
 }
 
 static void ieee80211_assign_chanctx(struct ieee80211_local *local,
-- 
2.42.0


^ permalink raw reply related

* [PATCH wireless-next v2 27/28] wifi: iwlwifi: mld: Convert to WARN_ONCE in link removal path.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>

From: Ben Greear <greearb@candelatech.com>

While the comment indicates this should not happen, it does at least
when firmware is being problematic.  Change to WARN_ON_ONCE to
decrease log spam.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 drivers/net/wireless/intel/iwlwifi/mld/sta.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/sta.h b/drivers/net/wireless/intel/iwlwifi/mld/sta.h
index 1897b121aae2..44c54e6d68e6 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/sta.h
+++ b/drivers/net/wireless/intel/iwlwifi/mld/sta.h
@@ -170,7 +170,7 @@ iwl_mld_cleanup_sta(void *data, struct ieee80211_sta *sta)
 			continue;
 
 		/* Should not happen as link removal should always succeed */
-		WARN_ON(1);
+		WARN_ON_ONCE(1);
 		RCU_INIT_POINTER(mld_sta->link[link_id], NULL);
 		RCU_INIT_POINTER(mld_sta->mld->fw_id_to_link_sta[mld_link_sta->fw_id],
 				 NULL);
-- 
2.42.0


^ permalink raw reply related

* [PATCH wireless-next v2 24/28] wifi: iwlwifi: mld: Fix NPE in flush logic.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>

From: Ben Greear <greearb@candelatech.com>

It appears that sometimes the sta can be NULL, so check for
that and return early.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 drivers/net/wireless/intel/iwlwifi/mld/sta.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/sta.c b/drivers/net/wireless/intel/iwlwifi/mld/sta.c
index 288fc4b7604e..06e064466e3b 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/sta.c
@@ -779,6 +779,9 @@ void iwl_mld_flush_sta_txqs(struct iwl_mld *mld, struct ieee80211_sta *sta)
 
 void iwl_mld_wait_sta_txqs_empty(struct iwl_mld *mld, struct ieee80211_sta *sta)
 {
+	if (!sta)
+		return;
+
 	/* Avoid a warning in iwl_trans_wait_txq_empty if are anyway on the way
 	 * to a restart.
 	 */
-- 
2.42.0


^ permalink raw reply related

* [PATCH wireless-next v2 19/28] wifi: iwlwifi: mld: Improve error message in rx path.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>

From: Ben Greear <greearb@candelatech.com>

Print return code that is causing the failure path.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 drivers/net/wireless/intel/iwlwifi/mld/rx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/rx.c b/drivers/net/wireless/intel/iwlwifi/mld/rx.c
index 214dcfde2fb4..f5c20a3aa869 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/rx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/rx.c
@@ -2204,8 +2204,8 @@ void iwl_mld_sync_rx_queues(struct iwl_mld *mld,
 	ret = wait_event_timeout(mld->rxq_sync.waitq,
 				 READ_ONCE(mld->rxq_sync.state) == 0,
 				 SYNC_RX_QUEUE_TIMEOUT);
-	WARN_ONCE(!ret, "RXQ sync failed: state=0x%lx, cookie=%d\n",
-		  mld->rxq_sync.state, mld->rxq_sync.cookie);
+	WARN_ONCE(!ret, "RXQ sync failed: state=0x%lx, cookie=%d, ret: %d\n",
+		  mld->rxq_sync.state, mld->rxq_sync.cookie, ret);
 
 out:
 	mld->rxq_sync.state = 0;
-- 
2.42.0


^ permalink raw reply related

* [PATCH wireless-next v2 23/28] wifi: iwlwifi: mld: Support force-cleanup op
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>

From: Ben Greear <greearb@candelatech.com>

This lets mac80211 force the driver to clean up any lingering
configuration, fixing use-after-free in case of unrecoverable
hardware failure.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index 43bc73764dcd..31a3818f32bc 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -560,6 +560,18 @@ iwl_mld_restart_cleanup(struct iwl_mld *mld)
 	iwl_mld_ftm_restart_cleanup(mld);
 }
 
+/* mac80211 thinks our driver/firmware/hardware has crashed
+ * and cannot be recovered.  Force clean any existing configuration
+ * (stas, etc), as mac80211 will not attempt further cleanup.
+ */
+static void iwl_mld_mac80211_force_cleanup(struct ieee80211_hw *hw)
+{
+	struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw);
+
+	IWL_ERR(mld, "mac80211-force-cleanup called, calling mld_restart_cleanup.\n");
+	iwl_mld_restart_cleanup(mld);
+}
+
 static
 int iwl_mld_mac80211_start(struct ieee80211_hw *hw)
 {
@@ -2717,6 +2729,7 @@ const struct ieee80211_ops iwl_mld_hw_ops = {
 	.config = iwl_mld_mac80211_config,
 	.get_antenna = iwl_mld_get_antenna,
 	.set_antenna = iwl_mld_set_antenna,
+	.force_cleanup = iwl_mld_mac80211_force_cleanup,
 	.add_interface = iwl_mld_mac80211_add_interface,
 	.remove_interface = iwl_mld_mac80211_remove_interface,
 	.conf_tx = iwl_mld_mac80211_conf_tx,
-- 
2.42.0


^ permalink raw reply related

* [PATCH wireless-next v2 21/28] wifi: iwlwifi: mld: Protect from null mld_sta
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>

From: Ben Greear <greearb@candelatech.com>

Torture tests were crashing here, protect against a null
mld_sta.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index 1557aa2a4866..43bc73764dcd 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -1911,6 +1911,7 @@ static void iwl_mld_mac80211_flush(struct ieee80211_hw *hw,
 	iwl_mld_add_txq_list(mld);
 
 	for (int i = 0; i < mld->fw->ucode_capa.num_stations; i++) {
+		struct iwl_mld_sta *mld_sta;
 		struct ieee80211_link_sta *link_sta =
 			wiphy_dereference(mld->wiphy,
 					  mld->fw_id_to_link_sta[i]);
@@ -1919,7 +1920,8 @@ static void iwl_mld_mac80211_flush(struct ieee80211_hw *hw,
 			continue;
 
 		/* Check that the sta belongs to the given vif */
-		if (vif && vif != iwl_mld_sta_from_mac80211(link_sta->sta)->vif)
+		mld_sta = iwl_mld_sta_from_mac80211(link_sta->sta);
+		if (vif && (!mld_sta || vif != mld_sta->vif))
 			continue;
 
 		if (drop)
-- 
2.42.0


^ permalink raw reply related

* [PATCH wireless-next v2 20/28] wifi: iwlwifi: mld: Improve logging message.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>

From: Ben Greear <greearb@candelatech.com>

Indicate that the problem is being fixed.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
index 0c53d6bd9651..1557aa2a4866 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c
@@ -647,7 +647,7 @@ void iwl_mld_mac80211_stop(struct ieee80211_hw *hw, bool suspend)
 	 */
 	for (int i = 0; i < ARRAY_SIZE(mld->scan.uid_status); i++)
 		if (WARN_ONCE(mld->scan.uid_status[i],
-			      "UMAC scan UID %d status was not cleaned (0x%x 0x%x)\n",
+			      "mac80211-stop: UMAC scan UID %d status was not cleaned (0x%x 0x%x), forcing to 0\n",
 			      i, mld->scan.uid_status[i], mld->scan.status))
 			mld->scan.uid_status[i] = 0;
 }
-- 
2.42.0


^ permalink raw reply related

* [PATCH wireless-next v2 13/28] wifi: iwlwifi: mld: Remove warning about BAID.
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>

From: Ben Greear <greearb@candelatech.com>

It seems to be expected behaviour, and is seen fairly often
in testing in adverse conditions, so make it a one-line log
message instead of WARN splat.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 drivers/net/wireless/intel/iwlwifi/mld/agg.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mld/agg.c b/drivers/net/wireless/intel/iwlwifi/mld/agg.c
index a757077b0a7a..23d55374ef8a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/agg.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/agg.c
@@ -216,10 +216,16 @@ iwl_mld_reorder(struct iwl_mld *mld, struct napi_struct *napi,
 	if (baid == IWL_RX_REORDER_DATA_INVALID_BAID)
 		return IWL_MLD_PASS_SKB;
 
-	/* no sta yet */
-	if (WARN_ONCE(!sta,
-		      "Got valid BAID without a valid station assigned\n"))
+	/* no sta yet.  This happens fairly often, don't WARN_ON about it. */
+	if (!sta) {
+		static bool done_once;
+
+		if (!done_once) {
+			IWL_ERR(mld, "Got valid BAID without a valid station assigned, will not log again.\n");
+			done_once = true;
+		}
 		return IWL_MLD_PASS_SKB;
+	}
 
 	mld_sta = iwl_mld_sta_from_mac80211(sta);
 
-- 
2.42.0


^ permalink raw reply related

* [PATCH wireless-next v2 09/28] wifi: mac80211: Use warn-on-once in drv_remove_chanctxt
From: greearb @ 2026-03-12 17:00 UTC (permalink / raw)
  To: linux-wireless; +Cc: Ben Greear
In-Reply-To: <20260312170026.285494-1-greearb@candelatech.com>

From: Ben Greear <greearb@candelatech.com>

But still log it to dmesg.

Signed-off-by: Ben Greear <greearb@candelatech.com>
---
 net/mac80211/driver-ops.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 51bf3c7822a7..e2283d7dcd1e 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1035,8 +1035,10 @@ static inline void drv_remove_chanctx(struct ieee80211_local *local,
 	might_sleep();
 	lockdep_assert_wiphy(local->hw.wiphy);
 
-	if (WARN_ON(!ctx->driver_present))
+	if (WARN_ON_ONCE(!ctx->driver_present)) {
+		pr_err("drv-remove-chanctx, NOT driver_present, not sending request to driver.");
 		return;
+	}
 
 	trace_drv_remove_chanctx(local, ctx);
 	if (local->ops->remove_chanctx)
-- 
2.42.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox