public inbox for linux-wireless@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH wireless v2] wifi: mt76: mt7996: replace direct WTBL access with MCU for station statistics
@ 2026-04-07  5:38 Joshua Klinesmith
  2026-04-07 14:56 ` kernel test robot
  2026-04-07 14:56 ` kernel test robot
  0 siblings, 2 replies; 3+ messages in thread
From: Joshua Klinesmith @ 2026-04-07  5:38 UTC (permalink / raw)
  To: linux-wireless
  Cc: nbd, lorenzo, ryder.lee, shayne.chen, sean.wang,
	Joshua Klinesmith

Direct MMIO access to WTBL entries for airtime and RSSI statistics in
mt7996_mac_sta_poll() races with firmware, causing warnings at
mt7996_mac_wtbl_lmac_addr, MCU message timeouts, and firmware
communication breakdown. The function was called from
mt7996_mac_tx_free() on every TX-Free-Done event, compounding the
issue with heavy CPU overhead.

Replace the direct WTBL polling with firmware MCU queries:
- Airtime: UNI_ALL_STA_TXRX_AIR_TIME via the existing all_sta_info
  MCU command, with a new handler in mt7996_mcu_rx_all_sta_info_event()
- RSSI: UNI_PER_STA_RSSI via new mt7996_mcu_get_per_sta_info() using
  MCU_WM_UNI_CMD(PER_STA_INFO)

Both queries run from mt7996_mac_work() every 5th tick under dev mutex,
matching the pattern already used for TX rate, admission stats, and
MSDU count reporting.

Remove mt7996_mac_sta_poll() and its airtime_ac tracking array entirely.

The per-sta-info response handler validates the firmware-returned entry
count against what was requested and against the skb payload length
before walking the response array, and uses bounds-checked
mt76_wcid_ptr() for WLAN ID lookup. RSSI polling is batched in groups
of PER_STA_INFO_MAX_NUM to cover the full WTBL capacity.

Vendor driver analysis (mt_wifi.ko from Xiaomi AX3000T MT7981 firmware)
confirms the RCPI-to-RSSI conversion formula (rcpi - 220) / 2 and that
the vendor never performs direct WTBL reads for statistics.

Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Link: https://github.com/openwrt/openwrt/issues/21177
Signed-off-by: Joshua Klinesmith <joshuaklinesmith@gmail.com>
---
 .../wireless/mediatek/mt76/mt76_connac_mcu.h  |   7 +
 .../net/wireless/mediatek/mt76/mt7996/mac.c   | 117 +--------------
 .../net/wireless/mediatek/mt76/mt7996/mcu.c   | 135 ++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt7996/mcu.h   |  25 ++++
 .../wireless/mediatek/mt76/mt7996/mt7996.h    |   2 +-
 5 files changed, 170 insertions(+), 116 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
index 8d59cf43f0e2..14d3ee7defa1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
@@ -1392,6 +1392,13 @@ enum {
 	UNI_OFFLOAD_OFFLOAD_BMC_RPY_DETECT,
 };
 
+#define PER_STA_INFO_MAX_NUM	90
+
+enum UNI_PER_STA_INFO_TAG {
+	UNI_PER_STA_RSSI,
+	UNI_PER_STA_MAX_NUM
+};
+
 enum UNI_ALL_STA_INFO_TAG {
 	UNI_ALL_STA_TXRX_RATE,
 	UNI_ALL_STA_TX_STAT,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index d4f3ee943b47..3d9648fb6773 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -111,119 +111,6 @@ u32 mt7996_mac_wtbl_lmac_addr(struct mt7996_dev *dev, u16 wcid, u8 dw)
 	return MT_WTBL_LMAC_OFFS(wcid, dw);
 }
 
-static void mt7996_mac_sta_poll(struct mt7996_dev *dev)
-{
-	static const u8 ac_to_tid[] = {
-		[IEEE80211_AC_BE] = 0,
-		[IEEE80211_AC_BK] = 1,
-		[IEEE80211_AC_VI] = 4,
-		[IEEE80211_AC_VO] = 6
-	};
-	struct mt7996_sta_link *msta_link;
-	struct mt76_vif_link *mlink;
-	struct ieee80211_sta *sta;
-	struct mt7996_sta *msta;
-	u32 tx_time[IEEE80211_NUM_ACS], rx_time[IEEE80211_NUM_ACS];
-	LIST_HEAD(sta_poll_list);
-	struct mt76_wcid *wcid;
-	int i;
-
-	spin_lock_bh(&dev->mt76.sta_poll_lock);
-	list_splice_init(&dev->mt76.sta_poll_list, &sta_poll_list);
-	spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
-	rcu_read_lock();
-
-	while (true) {
-		bool clear = false;
-		u32 addr, val;
-		u16 idx;
-		s8 rssi[4];
-
-		spin_lock_bh(&dev->mt76.sta_poll_lock);
-		if (list_empty(&sta_poll_list)) {
-			spin_unlock_bh(&dev->mt76.sta_poll_lock);
-			break;
-		}
-		msta_link = list_first_entry(&sta_poll_list,
-					     struct mt7996_sta_link,
-					     wcid.poll_list);
-		msta = msta_link->sta;
-		wcid = &msta_link->wcid;
-		list_del_init(&wcid->poll_list);
-		spin_unlock_bh(&dev->mt76.sta_poll_lock);
-
-		idx = wcid->idx;
-
-		/* refresh peer's airtime reporting */
-		addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 20);
-
-		for (i = 0; i < IEEE80211_NUM_ACS; i++) {
-			u32 tx_last = msta_link->airtime_ac[i];
-			u32 rx_last = msta_link->airtime_ac[i + 4];
-
-			msta_link->airtime_ac[i] = mt76_rr(dev, addr);
-			msta_link->airtime_ac[i + 4] = mt76_rr(dev, addr + 4);
-
-			tx_time[i] = msta_link->airtime_ac[i] - tx_last;
-			rx_time[i] = msta_link->airtime_ac[i + 4] - rx_last;
-
-			if ((tx_last | rx_last) & BIT(30))
-				clear = true;
-
-			addr += 8;
-		}
-
-		if (clear) {
-			mt7996_mac_wtbl_update(dev, idx,
-					       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
-			memset(msta_link->airtime_ac, 0,
-			       sizeof(msta_link->airtime_ac));
-		}
-
-		if (!wcid->sta)
-			continue;
-
-		sta = container_of((void *)msta, struct ieee80211_sta,
-				   drv_priv);
-		for (i = 0; i < IEEE80211_NUM_ACS; i++) {
-			u8 q = mt76_connac_lmac_mapping(i);
-			u32 tx_cur = tx_time[q];
-			u32 rx_cur = rx_time[q];
-			u8 tid = ac_to_tid[i];
-
-			if (!tx_cur && !rx_cur)
-				continue;
-
-			ieee80211_sta_register_airtime(sta, tid, tx_cur, rx_cur);
-		}
-
-		/* get signal strength of resp frames (CTS/BA/ACK) */
-		addr = mt7996_mac_wtbl_lmac_addr(dev, idx, 34);
-		val = mt76_rr(dev, addr);
-
-		rssi[0] = to_rssi(GENMASK(7, 0), val);
-		rssi[1] = to_rssi(GENMASK(15, 8), val);
-		rssi[2] = to_rssi(GENMASK(23, 16), val);
-		rssi[3] = to_rssi(GENMASK(31, 14), val);
-
-		mlink = rcu_dereference(msta->vif->mt76.link[wcid->link_id]);
-		if (mlink) {
-			struct mt76_phy *mphy = mt76_vif_link_phy(mlink);
-
-			if (mphy)
-				msta_link->ack_signal =
-					mt76_rx_signal(mphy->antenna_mask,
-						       rssi);
-		}
-
-		ewma_avg_signal_add(&msta_link->avg_ack_signal,
-				    -msta_link->ack_signal);
-	}
-
-	rcu_read_unlock();
-}
-
 /* The HW does not translate the mac header to 802.3 for mesh point */
 static int mt7996_reverse_frag0_hdr_trans(struct sk_buff *skb, u16 hdr_gap)
 {
@@ -1424,8 +1311,6 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)
 		}
 	}
 
-	mt7996_mac_sta_poll(dev);
-
 	if (wake)
 		mt76_set_tx_blocked(&dev->mt76, false);
 
@@ -2947,6 +2832,8 @@ void mt7996_mac_work(struct work_struct *work)
 		mt7996_mac_update_stats(phy);
 
 		mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_RATE);
+		mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_AIR_TIME);
+		mt7996_mcu_get_per_sta_info(phy, UNI_PER_STA_RSSI);
 		if (mtk_wed_device_active(&phy->dev->mt76.mmio.wed)) {
 			mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_ADM_STAT);
 			mt7996_mcu_get_all_sta_info(phy, UNI_ALL_STA_TXRX_MSDU_COUNT);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
index c0c042de477b..bf95e1d9299d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -616,6 +616,35 @@ mt7996_mcu_rx_all_sta_info_event(struct mt7996_dev *dev, struct sk_buff *skb)
 			wcid->stats.rx_packets +=
 				le32_to_cpu(res->msdu_cnt[i].rx_msdu_cnt);
 			break;
+		case UNI_ALL_STA_TXRX_AIR_TIME: {
+			static const u8 ac_to_tid[] = {
+				[IEEE80211_AC_BE] = 0,
+				[IEEE80211_AC_BK] = 1,
+				[IEEE80211_AC_VI] = 4,
+				[IEEE80211_AC_VO] = 6
+			};
+			struct ieee80211_sta *sta;
+
+			wlan_idx = le16_to_cpu(res->airtime[i].wlan_idx);
+			wcid = mt76_wcid_ptr(dev, wlan_idx);
+			sta = wcid_to_sta(wcid);
+			if (!sta)
+				break;
+
+			for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+				u8 lmac_ac = mt76_connac_lmac_mapping(ac);
+				u32 tx_cur = le32_to_cpu(res->airtime[i].tx[lmac_ac]);
+				u32 rx_cur = le32_to_cpu(res->airtime[i].rx[lmac_ac]);
+
+				if (!tx_cur && !rx_cur)
+					continue;
+
+				ieee80211_sta_register_airtime(sta,
+							      ac_to_tid[ac],
+							      tx_cur, rx_cur);
+			}
+			break;
+		}
 		default:
 			break;
 		}
@@ -4755,6 +4784,112 @@ int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag)
 				 &req, sizeof(req), false);
 }
 
+int mt7996_mcu_get_per_sta_info(struct mt7996_phy *phy, u16 tag)
+{
+	struct mt7996_dev *dev = phy->dev;
+	struct mt7996_mcu_per_sta_info_event *res;
+	struct mt76_wcid *wcid;
+	struct sk_buff *skb;
+	int i, ret, sta_num, resp_sta_num;
+	int wcid_idx = 0;
+	struct {
+		u8 _rsv1;
+		u8 unsolicit;
+		u8 _rsv2[2];
+
+		__le16 tag;
+		__le16 len;
+		__le16 sta_num;
+		u8 _rsv3[2];
+		__le16 wlan_idx[PER_STA_INFO_MAX_NUM];
+	} __packed req = {
+		.tag = cpu_to_le16(tag),
+		.len = cpu_to_le16(sizeof(req) - 4),
+	};
+
+	while (wcid_idx < mt7996_wtbl_size(dev)) {
+		sta_num = 0;
+
+		rcu_read_lock();
+		for (i = wcid_idx;
+		     i < mt7996_wtbl_size(dev) && sta_num < PER_STA_INFO_MAX_NUM;
+		     i++) {
+			wcid = rcu_dereference(dev->mt76.wcid[i]);
+			if (!wcid || !wcid->sta)
+				continue;
+			req.wlan_idx[sta_num++] = cpu_to_le16(i);
+		}
+		rcu_read_unlock();
+		wcid_idx = i;
+
+		if (!sta_num)
+			continue;
+
+		req.sta_num = cpu_to_le16(sta_num);
+
+		ret = mt76_mcu_send_and_get_msg(&dev->mt76,
+						MCU_WM_UNI_CMD(PER_STA_INFO),
+						&req, sizeof(req), true, &skb);
+		if (ret)
+			return ret;
+
+		res = (struct mt7996_mcu_per_sta_info_event *)skb->data;
+
+		resp_sta_num = le16_to_cpu(res->sta_num);
+		if (resp_sta_num > sta_num ||
+		    skb->len < struct_size(res, rssi, resp_sta_num)) {
+			dev_kfree_skb(skb);
+			return -EINVAL;
+		}
+
+		rcu_read_lock();
+		for (i = 0; i < resp_sta_num; i++) {
+			struct mt7996_sta_link *msta_link;
+			struct mt76_vif_link *mvif;
+			struct mt76_vif_link *mlink;
+			struct mt76_phy *mphy;
+			u16 wlan_idx;
+			s8 rssi[4];
+
+			switch (tag) {
+			case UNI_PER_STA_RSSI:
+				wlan_idx = le16_to_cpu(res->rssi[i].wlan_idx);
+				wcid = mt76_wcid_ptr(dev, wlan_idx);
+				if (!wcid || !wcid->sta)
+					break;
+
+				msta_link = container_of(wcid,
+							 struct mt7996_sta_link,
+							 wcid);
+
+				rssi[0] = (res->rssi[i].rcpi[0] - 220) / 2;
+				rssi[1] = (res->rssi[i].rcpi[1] - 220) / 2;
+				rssi[2] = (res->rssi[i].rcpi[2] - 220) / 2;
+				rssi[3] = (res->rssi[i].rcpi[3] - 220) / 2;
+
+				mvif = &msta_link->sta->vif->mt76;
+				mlink = rcu_dereference(mvif->link[wcid->link_id]);
+				if (mlink) {
+					mphy = mt76_vif_link_phy(mlink);
+					if (mphy)
+						msta_link->ack_signal =
+							mt76_rx_signal(mphy->antenna_mask,
+								       rssi);
+				}
+
+				ewma_avg_signal_add(&msta_link->avg_ack_signal,
+						    -msta_link->ack_signal);
+				break;
+			}
+		}
+		rcu_read_unlock();
+
+		dev_kfree_skb(skb);
+	}
+
+	return 0;
+}
+
 int mt7996_mcu_wed_rro_reset_sessions(struct mt7996_dev *dev, u16 id)
 {
 	struct {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
index e0b83ac9f5e2..b5bad9a76c49 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
@@ -220,6 +220,31 @@ struct mt7996_mcu_all_sta_info_event {
 			__le32 tx_msdu_cnt;
 			__le32 rx_msdu_cnt;
 		} __packed, msdu_cnt);
+
+		DECLARE_FLEX_ARRAY(struct {
+			__le16 wlan_idx;
+			u8 rsv[2];
+			__le32 tx[IEEE80211_NUM_ACS];
+			__le32 rx[IEEE80211_NUM_ACS];
+		} __packed, airtime);
+	} __packed;
+} __packed;
+
+struct mt7996_mcu_per_sta_info_event {
+	u8 rsv[4];
+	__le16 tag;
+	__le16 len;
+	u8 more;
+	u8 rsv2;
+	__le16 sta_num;
+	u8 rsv3[4];
+
+	union {
+		DECLARE_FLEX_ARRAY(struct {
+			__le16 wlan_idx;
+			u8 rsv[2];
+			u8 rcpi[4];
+		} __packed, rssi);
 	} __packed;
 } __packed;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
index 7a884311800e..b523e971f78c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h
@@ -222,7 +222,6 @@ struct mt7996_sta_link {
 	struct mt7996_sta *sta;
 
 	struct list_head rc_list;
-	u32 airtime_ac[8];
 
 	int ack_signal;
 	struct ewma_avg_signal avg_ack_signal;
@@ -741,6 +740,7 @@ int mt7996_mcu_trigger_assert(struct mt7996_dev *dev);
 void mt7996_mcu_rx_event(struct mt7996_dev *dev, struct sk_buff *skb);
 void mt7996_mcu_exit(struct mt7996_dev *dev);
 int mt7996_mcu_get_all_sta_info(struct mt7996_phy *phy, u16 tag);
+int mt7996_mcu_get_per_sta_info(struct mt7996_phy *phy, u16 tag);
 int mt7996_mcu_wed_rro_reset_sessions(struct mt7996_dev *dev, u16 id);
 int mt7996_mcu_set_sniffer_mode(struct mt7996_phy *phy, bool enabled);
 
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH wireless v2] wifi: mt76: mt7996: replace direct WTBL access with MCU for station statistics
  2026-04-07  5:38 [PATCH wireless v2] wifi: mt76: mt7996: replace direct WTBL access with MCU for station statistics Joshua Klinesmith
@ 2026-04-07 14:56 ` kernel test robot
  2026-04-07 14:56 ` kernel test robot
  1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2026-04-07 14:56 UTC (permalink / raw)
  To: Joshua Klinesmith, linux-wireless
  Cc: llvm, oe-kbuild-all, nbd, lorenzo, ryder.lee, shayne.chen,
	sean.wang, Joshua Klinesmith

Hi Joshua,

kernel test robot noticed the following build errors:

[auto build test ERROR on wireless/main]
[also build test ERROR on linus/master v7.0-rc7 next-20260406]
[cannot apply to wireless-next/main]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Joshua-Klinesmith/wifi-mt76-mt7996-replace-direct-WTBL-access-with-MCU-for-station-statistics/20260407-151612
base:   https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git main
patch link:    https://lore.kernel.org/r/20260407053855.75828-1-joshuaklinesmith%40gmail.com
patch subject: [PATCH wireless v2] wifi: mt76: mt7996: replace direct WTBL access with MCU for station statistics
config: loongarch-allmodconfig (https://download.01.org/0day-ci/archive/20260407/202604072218.tGCSoRNR-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260407/202604072218.tGCSoRNR-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202604072218.tGCSoRNR-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4870:10: error: incompatible pointer types assigning to 'struct mt76_vif_link *' from 'struct mt76_vif_data *' [-Werror,-Wincompatible-pointer-types]
    4870 |                                 mvif = &msta_link->sta->vif->mt76;
         |                                      ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   include/linux/rcupdate.h:752:50: note: expanded from macro 'rcu_dereference'
     752 | #define rcu_dereference(p) rcu_dereference_check(p, 0)
         |                                                  ^
   include/linux/rcupdate.h:662:27: note: expanded from macro 'rcu_dereference_check'
     662 |         __rcu_dereference_check((p), __UNIQUE_ID(rcu), \
         |                                  ^
   include/linux/rcupdate.h:514:10: note: expanded from macro '__rcu_dereference_check'
     514 |         typeof(*p) *local = (typeof(*p) *__force)READ_ONCE(p); \
         |                 ^
>> drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   include/linux/rcupdate.h:752:50: note: expanded from macro 'rcu_dereference'
     752 | #define rcu_dereference(p) rcu_dereference_check(p, 0)
         |                                                  ^
   include/linux/rcupdate.h:662:27: note: expanded from macro 'rcu_dereference_check'
     662 |         __rcu_dereference_check((p), __UNIQUE_ID(rcu), \
         |                                  ^
   include/linux/rcupdate.h:514:31: note: expanded from macro '__rcu_dereference_check'
     514 |         typeof(*p) *local = (typeof(*p) *__force)READ_ONCE(p); \
         |                                      ^
>> drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   include/linux/rcupdate.h:752:50: note: expanded from macro 'rcu_dereference'
     752 | #define rcu_dereference(p) rcu_dereference_check(p, 0)
         |                                                  ^
   include/linux/rcupdate.h:662:27: note: expanded from macro 'rcu_dereference_check'
     662 |         __rcu_dereference_check((p), __UNIQUE_ID(rcu), \
         |                                  ^
   include/linux/rcupdate.h:514:53: note: expanded from macro '__rcu_dereference_check'
     514 |         typeof(*p) *local = (typeof(*p) *__force)READ_ONCE(p); \
         |                                                            ^
   note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:706:22: note: expanded from macro 'compiletime_assert'
     706 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
         |                             ^~~~~~~~~
   include/linux/compiler_types.h:694:23: note: expanded from macro '_compiletime_assert'
     694 |         __compiletime_assert(condition, msg, prefix, suffix)
         |                              ^~~~~~~~~
   include/linux/compiler_types.h:686:9: note: expanded from macro '__compiletime_assert'
     686 |                 if (!(condition))                                       \
         |                       ^~~~~~~~~
>> drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   include/linux/rcupdate.h:752:50: note: expanded from macro 'rcu_dereference'
     752 | #define rcu_dereference(p) rcu_dereference_check(p, 0)
         |                                                  ^
   include/linux/rcupdate.h:662:27: note: expanded from macro 'rcu_dereference_check'
     662 |         __rcu_dereference_check((p), __UNIQUE_ID(rcu), \
         |                                  ^
   include/linux/rcupdate.h:514:53: note: expanded from macro '__rcu_dereference_check'
     514 |         typeof(*p) *local = (typeof(*p) *__force)READ_ONCE(p); \
         |                                                            ^
   note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:706:22: note: expanded from macro 'compiletime_assert'
     706 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
         |                             ^~~~~~~~~
   include/linux/compiler_types.h:694:23: note: expanded from macro '_compiletime_assert'
     694 |         __compiletime_assert(condition, msg, prefix, suffix)
         |                              ^~~~~~~~~
   include/linux/compiler_types.h:686:9: note: expanded from macro '__compiletime_assert'
     686 |                 if (!(condition))                                       \
         |                       ^~~~~~~~~
>> drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   include/linux/rcupdate.h:752:50: note: expanded from macro 'rcu_dereference'
     752 | #define rcu_dereference(p) rcu_dereference_check(p, 0)
         |                                                  ^
   include/linux/rcupdate.h:662:27: note: expanded from macro 'rcu_dereference_check'
     662 |         __rcu_dereference_check((p), __UNIQUE_ID(rcu), \
         |                                  ^
   include/linux/rcupdate.h:514:53: note: expanded from macro '__rcu_dereference_check'
     514 |         typeof(*p) *local = (typeof(*p) *__force)READ_ONCE(p); \
         |                                                            ^
   note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:706:22: note: expanded from macro 'compiletime_assert'
     706 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
         |                             ^~~~~~~~~
   include/linux/compiler_types.h:694:23: note: expanded from macro '_compiletime_assert'
     694 |         __compiletime_assert(condition, msg, prefix, suffix)
         |                              ^~~~~~~~~
   include/linux/compiler_types.h:686:9: note: expanded from macro '__compiletime_assert'
     686 |                 if (!(condition))                                       \
         |                       ^~~~~~~~~
>> drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   include/linux/rcupdate.h:752:50: note: expanded from macro 'rcu_dereference'
     752 | #define rcu_dereference(p) rcu_dereference_check(p, 0)
         |                                                  ^
   include/linux/rcupdate.h:662:27: note: expanded from macro 'rcu_dereference_check'
     662 |         __rcu_dereference_check((p), __UNIQUE_ID(rcu), \
         |                                  ^
   include/linux/rcupdate.h:514:53: note: expanded from macro '__rcu_dereference_check'
     514 |         typeof(*p) *local = (typeof(*p) *__force)READ_ONCE(p); \
         |                                                            ^
   note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:706:22: note: expanded from macro 'compiletime_assert'
     706 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
         |                             ^~~~~~~~~
   include/linux/compiler_types.h:694:23: note: expanded from macro '_compiletime_assert'
     694 |         __compiletime_assert(condition, msg, prefix, suffix)
         |                              ^~~~~~~~~
   include/linux/compiler_types.h:686:9: note: expanded from macro '__compiletime_assert'
     686 |                 if (!(condition))                                       \
         |                       ^~~~~~~~~
>> drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   include/linux/rcupdate.h:752:50: note: expanded from macro 'rcu_dereference'
     752 | #define rcu_dereference(p) rcu_dereference_check(p, 0)
         |                                                  ^
   include/linux/rcupdate.h:662:27: note: expanded from macro 'rcu_dereference_check'
     662 |         __rcu_dereference_check((p), __UNIQUE_ID(rcu), \
         |                                  ^
   include/linux/rcupdate.h:514:53: note: expanded from macro '__rcu_dereference_check'
     514 |         typeof(*p) *local = (typeof(*p) *__force)READ_ONCE(p); \
         |                                                            ^
   note: (skipping 2 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
   include/linux/compiler_types.h:706:22: note: expanded from macro 'compiletime_assert'
     706 |         _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
         |                             ^~~~~~~~~
   include/linux/compiler_types.h:694:23: note: expanded from macro '_compiletime_assert'
     694 |         __compiletime_assert(condition, msg, prefix, suffix)
         |                              ^~~~~~~~~
   include/linux/compiler_types.h:686:9: note: expanded from macro '__compiletime_assert'
     686 |                 if (!(condition))                                       \
         |                       ^~~~~~~~~
>> drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   include/linux/rcupdate.h:752:50: note: expanded from macro 'rcu_dereference'
     752 | #define rcu_dereference(p) rcu_dereference_check(p, 0)
         |                                                  ^
   include/linux/rcupdate.h:662:27: note: expanded from macro 'rcu_dereference_check'
     662 |         __rcu_dereference_check((p), __UNIQUE_ID(rcu), \
         |                                  ^
   include/linux/rcupdate.h:514:53: note: expanded from macro '__rcu_dereference_check'
     514 |         typeof(*p) *local = (typeof(*p) *__force)READ_ONCE(p); \
         |                                                            ^
   include/asm-generic/rwonce.h:50:14: note: expanded from macro 'READ_ONCE'
      50 |         __READ_ONCE(x);                                                 \
         |                     ^
   include/asm-generic/rwonce.h:44:65: note: expanded from macro '__READ_ONCE'
      44 | #define __READ_ONCE(x)  (*(const volatile __unqual_scalar_typeof(x) *)&(x))
         |                                                                  ^
   include/linux/compiler_types.h:642:53: note: expanded from macro '__unqual_scalar_typeof'
     642 | #define __unqual_scalar_typeof(x) __typeof_unqual__(x)
         |                                                     ^
>> drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   include/linux/rcupdate.h:752:50: note: expanded from macro 'rcu_dereference'
     752 | #define rcu_dereference(p) rcu_dereference_check(p, 0)
         |                                                  ^
   include/linux/rcupdate.h:662:27: note: expanded from macro 'rcu_dereference_check'
     662 |         __rcu_dereference_check((p), __UNIQUE_ID(rcu), \
         |                                  ^
   include/linux/rcupdate.h:514:53: note: expanded from macro '__rcu_dereference_check'
     514 |         typeof(*p) *local = (typeof(*p) *__force)READ_ONCE(p); \
         |                                                            ^
   include/asm-generic/rwonce.h:50:14: note: expanded from macro 'READ_ONCE'
      50 |         __READ_ONCE(x);                                                 \
         |                     ^
   include/asm-generic/rwonce.h:44:72: note: expanded from macro '__READ_ONCE'
      44 | #define __READ_ONCE(x)  (*(const volatile __unqual_scalar_typeof(x) *)&(x))
         |                                                                         ^
>> drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   include/linux/rcupdate.h:752:50: note: expanded from macro 'rcu_dereference'
     752 | #define rcu_dereference(p) rcu_dereference_check(p, 0)
         |                                                  ^
   include/linux/rcupdate.h:662:27: note: expanded from macro 'rcu_dereference_check'
     662 |         __rcu_dereference_check((p), __UNIQUE_ID(rcu), \
         |                                  ^
   include/linux/rcupdate.h:517:12: note: expanded from macro '__rcu_dereference_check'
     517 |         ((typeof(*p) __force __kernel *)(local)); \
         |                   ^
>> drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:11: error: assigning to 'struct mt76_vif_link *' from incompatible type 'void'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                       ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   12 errors generated.


vim +4870 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c

  4786	
  4787	int mt7996_mcu_get_per_sta_info(struct mt7996_phy *phy, u16 tag)
  4788	{
  4789		struct mt7996_dev *dev = phy->dev;
  4790		struct mt7996_mcu_per_sta_info_event *res;
  4791		struct mt76_wcid *wcid;
  4792		struct sk_buff *skb;
  4793		int i, ret, sta_num, resp_sta_num;
  4794		int wcid_idx = 0;
  4795		struct {
  4796			u8 _rsv1;
  4797			u8 unsolicit;
  4798			u8 _rsv2[2];
  4799	
  4800			__le16 tag;
  4801			__le16 len;
  4802			__le16 sta_num;
  4803			u8 _rsv3[2];
  4804			__le16 wlan_idx[PER_STA_INFO_MAX_NUM];
  4805		} __packed req = {
  4806			.tag = cpu_to_le16(tag),
  4807			.len = cpu_to_le16(sizeof(req) - 4),
  4808		};
  4809	
  4810		while (wcid_idx < mt7996_wtbl_size(dev)) {
  4811			sta_num = 0;
  4812	
  4813			rcu_read_lock();
  4814			for (i = wcid_idx;
  4815			     i < mt7996_wtbl_size(dev) && sta_num < PER_STA_INFO_MAX_NUM;
  4816			     i++) {
  4817				wcid = rcu_dereference(dev->mt76.wcid[i]);
  4818				if (!wcid || !wcid->sta)
  4819					continue;
  4820				req.wlan_idx[sta_num++] = cpu_to_le16(i);
  4821			}
  4822			rcu_read_unlock();
  4823			wcid_idx = i;
  4824	
  4825			if (!sta_num)
  4826				continue;
  4827	
  4828			req.sta_num = cpu_to_le16(sta_num);
  4829	
  4830			ret = mt76_mcu_send_and_get_msg(&dev->mt76,
  4831							MCU_WM_UNI_CMD(PER_STA_INFO),
  4832							&req, sizeof(req), true, &skb);
  4833			if (ret)
  4834				return ret;
  4835	
  4836			res = (struct mt7996_mcu_per_sta_info_event *)skb->data;
  4837	
  4838			resp_sta_num = le16_to_cpu(res->sta_num);
  4839			if (resp_sta_num > sta_num ||
  4840			    skb->len < struct_size(res, rssi, resp_sta_num)) {
  4841				dev_kfree_skb(skb);
  4842				return -EINVAL;
  4843			}
  4844	
  4845			rcu_read_lock();
  4846			for (i = 0; i < resp_sta_num; i++) {
  4847				struct mt7996_sta_link *msta_link;
  4848				struct mt76_vif_link *mvif;
  4849				struct mt76_vif_link *mlink;
  4850				struct mt76_phy *mphy;
  4851				u16 wlan_idx;
  4852				s8 rssi[4];
  4853	
  4854				switch (tag) {
  4855				case UNI_PER_STA_RSSI:
  4856					wlan_idx = le16_to_cpu(res->rssi[i].wlan_idx);
  4857					wcid = mt76_wcid_ptr(dev, wlan_idx);
  4858					if (!wcid || !wcid->sta)
  4859						break;
  4860	
  4861					msta_link = container_of(wcid,
  4862								 struct mt7996_sta_link,
  4863								 wcid);
  4864	
  4865					rssi[0] = (res->rssi[i].rcpi[0] - 220) / 2;
  4866					rssi[1] = (res->rssi[i].rcpi[1] - 220) / 2;
  4867					rssi[2] = (res->rssi[i].rcpi[2] - 220) / 2;
  4868					rssi[3] = (res->rssi[i].rcpi[3] - 220) / 2;
  4869	
> 4870					mvif = &msta_link->sta->vif->mt76;
> 4871					mlink = rcu_dereference(mvif->link[wcid->link_id]);
  4872					if (mlink) {
  4873						mphy = mt76_vif_link_phy(mlink);
  4874						if (mphy)
  4875							msta_link->ack_signal =
  4876								mt76_rx_signal(mphy->antenna_mask,
  4877									       rssi);
  4878					}
  4879	
  4880					ewma_avg_signal_add(&msta_link->avg_ack_signal,
  4881							    -msta_link->ack_signal);
  4882					break;
  4883				}
  4884			}
  4885			rcu_read_unlock();
  4886	
  4887			dev_kfree_skb(skb);
  4888		}
  4889	
  4890		return 0;
  4891	}
  4892	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH wireless v2] wifi: mt76: mt7996: replace direct WTBL access with MCU for station statistics
  2026-04-07  5:38 [PATCH wireless v2] wifi: mt76: mt7996: replace direct WTBL access with MCU for station statistics Joshua Klinesmith
  2026-04-07 14:56 ` kernel test robot
@ 2026-04-07 14:56 ` kernel test robot
  1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2026-04-07 14:56 UTC (permalink / raw)
  To: Joshua Klinesmith, linux-wireless
  Cc: llvm, oe-kbuild-all, nbd, lorenzo, ryder.lee, shayne.chen,
	sean.wang, Joshua Klinesmith

Hi Joshua,

kernel test robot noticed the following build errors:

[auto build test ERROR on wireless/main]
[also build test ERROR on linus/master v7.0-rc7 next-20260406]
[cannot apply to wireless-next/main]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Joshua-Klinesmith/wifi-mt76-mt7996-replace-direct-WTBL-access-with-MCU-for-station-statistics/20260407-151612
base:   https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git main
patch link:    https://lore.kernel.org/r/20260407053855.75828-1-joshuaklinesmith%40gmail.com
patch subject: [PATCH wireless v2] wifi: mt76: mt7996: replace direct WTBL access with MCU for station statistics
config: riscv-allmodconfig (https://download.01.org/0day-ci/archive/20260407/202604072310.QZ9n9tFj-lkp@intel.com/config)
compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project c80443cd37b2e2788cba67ffa180a6331e5f0791)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260407/202604072310.QZ9n9tFj-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202604072310.QZ9n9tFj-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4870:10: error: incompatible pointer types assigning to 'struct mt76_vif_link *' from 'struct mt76_vif_data *' [-Wincompatible-pointer-types]
    4870 |                                 mvif = &msta_link->sta->vif->mt76;
         |                                      ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   drivers/net/wireless/mediatek/mt76/mt7996/mcu.c:4871:35: error: no member named 'link' in 'struct mt76_vif_link'
    4871 |                                 mlink = rcu_dereference(mvif->link[wcid->link_id]);
         |                                                         ~~~~  ^
   11 errors generated.


vim +4870 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c

  4786	
  4787	int mt7996_mcu_get_per_sta_info(struct mt7996_phy *phy, u16 tag)
  4788	{
  4789		struct mt7996_dev *dev = phy->dev;
  4790		struct mt7996_mcu_per_sta_info_event *res;
  4791		struct mt76_wcid *wcid;
  4792		struct sk_buff *skb;
  4793		int i, ret, sta_num, resp_sta_num;
  4794		int wcid_idx = 0;
  4795		struct {
  4796			u8 _rsv1;
  4797			u8 unsolicit;
  4798			u8 _rsv2[2];
  4799	
  4800			__le16 tag;
  4801			__le16 len;
  4802			__le16 sta_num;
  4803			u8 _rsv3[2];
  4804			__le16 wlan_idx[PER_STA_INFO_MAX_NUM];
  4805		} __packed req = {
  4806			.tag = cpu_to_le16(tag),
  4807			.len = cpu_to_le16(sizeof(req) - 4),
  4808		};
  4809	
  4810		while (wcid_idx < mt7996_wtbl_size(dev)) {
  4811			sta_num = 0;
  4812	
  4813			rcu_read_lock();
  4814			for (i = wcid_idx;
  4815			     i < mt7996_wtbl_size(dev) && sta_num < PER_STA_INFO_MAX_NUM;
  4816			     i++) {
  4817				wcid = rcu_dereference(dev->mt76.wcid[i]);
  4818				if (!wcid || !wcid->sta)
  4819					continue;
  4820				req.wlan_idx[sta_num++] = cpu_to_le16(i);
  4821			}
  4822			rcu_read_unlock();
  4823			wcid_idx = i;
  4824	
  4825			if (!sta_num)
  4826				continue;
  4827	
  4828			req.sta_num = cpu_to_le16(sta_num);
  4829	
  4830			ret = mt76_mcu_send_and_get_msg(&dev->mt76,
  4831							MCU_WM_UNI_CMD(PER_STA_INFO),
  4832							&req, sizeof(req), true, &skb);
  4833			if (ret)
  4834				return ret;
  4835	
  4836			res = (struct mt7996_mcu_per_sta_info_event *)skb->data;
  4837	
  4838			resp_sta_num = le16_to_cpu(res->sta_num);
  4839			if (resp_sta_num > sta_num ||
  4840			    skb->len < struct_size(res, rssi, resp_sta_num)) {
  4841				dev_kfree_skb(skb);
  4842				return -EINVAL;
  4843			}
  4844	
  4845			rcu_read_lock();
  4846			for (i = 0; i < resp_sta_num; i++) {
  4847				struct mt7996_sta_link *msta_link;
  4848				struct mt76_vif_link *mvif;
  4849				struct mt76_vif_link *mlink;
  4850				struct mt76_phy *mphy;
  4851				u16 wlan_idx;
  4852				s8 rssi[4];
  4853	
  4854				switch (tag) {
  4855				case UNI_PER_STA_RSSI:
  4856					wlan_idx = le16_to_cpu(res->rssi[i].wlan_idx);
  4857					wcid = mt76_wcid_ptr(dev, wlan_idx);
  4858					if (!wcid || !wcid->sta)
  4859						break;
  4860	
  4861					msta_link = container_of(wcid,
  4862								 struct mt7996_sta_link,
  4863								 wcid);
  4864	
  4865					rssi[0] = (res->rssi[i].rcpi[0] - 220) / 2;
  4866					rssi[1] = (res->rssi[i].rcpi[1] - 220) / 2;
  4867					rssi[2] = (res->rssi[i].rcpi[2] - 220) / 2;
  4868					rssi[3] = (res->rssi[i].rcpi[3] - 220) / 2;
  4869	
> 4870					mvif = &msta_link->sta->vif->mt76;
  4871					mlink = rcu_dereference(mvif->link[wcid->link_id]);
  4872					if (mlink) {
  4873						mphy = mt76_vif_link_phy(mlink);
  4874						if (mphy)
  4875							msta_link->ack_signal =
  4876								mt76_rx_signal(mphy->antenna_mask,
  4877									       rssi);
  4878					}
  4879	
  4880					ewma_avg_signal_add(&msta_link->avg_ack_signal,
  4881							    -msta_link->ack_signal);
  4882					break;
  4883				}
  4884			}
  4885			rcu_read_unlock();
  4886	
  4887			dev_kfree_skb(skb);
  4888		}
  4889	
  4890		return 0;
  4891	}
  4892	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-04-07 14:57 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-07  5:38 [PATCH wireless v2] wifi: mt76: mt7996: replace direct WTBL access with MCU for station statistics Joshua Klinesmith
2026-04-07 14:56 ` kernel test robot
2026-04-07 14:56 ` kernel test robot

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