* Re: [PATCH net-next v3 03/13] net: introduce ndo_set_rx_mode_async and dev_rx_mode_work
From: Stanislav Fomichev @ 2026-03-24 18:13 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Stanislav Fomichev, netdev, davem, edumazet, pabeni, horms,
corbet, skhan, andrew+netdev, michael.chan, pavan.chebbi,
anthony.l.nguyen, przemyslaw.kitszel, saeedm, tariqt, mbloch,
alexanderduyck, kernel-team, johannes, sd, jianbol, dtatulea,
mohsin.bashr, jacob.e.keller, willemb, skhawaja, bestswngs,
aleksandr.loktionov, kees, linux-doc, linux-kernel,
intel-wired-lan, linux-rdma, linux-wireless, linux-kselftest,
leon
In-Reply-To: <20260323162003.0d155055@kernel.org>
On 03/23, Jakub Kicinski wrote:
> On Thu, 19 Mar 2026 18:24:51 -0700 Stanislav Fomichev wrote:
> > diff --git a/Documentation/networking/netdevices.rst b/Documentation/networking/netdevices.rst
> > index 35704d115312..dc83d78d3b27 100644
> > --- a/Documentation/networking/netdevices.rst
> > +++ b/Documentation/networking/netdevices.rst
> > @@ -289,6 +289,14 @@ struct net_device synchronization rules
> > ndo_set_rx_mode:
> > Synchronization: netif_addr_lock spinlock.
> > Context: BHs disabled
> > + Notes: Deprecated in favor of sleepable ndo_set_rx_mode_async.
> >
> > +ndo_set_rx_mode_async:
> > + Synchronization: rtnl_lock() semaphore. In addition, netdev instance
> > + lock if the driver implements queue management or shaper API.
> > + Context: process (from a work queue)
> > + Notes: Sleepable version of ndo_set_rx_mode. Receives snapshots
>
> It's probably just my weirdness but I find creating adjectives out
> of random nouns by adding "-able" to be in poor taste. "sleepable"
> took root in certain three letter subsystems but I hope it won't
> in netdev.
>
> Please use your words:
>
> Notes: Async version of ndo_set_rx_mode which runs in process
> context. Receives snapshots f the unicast and multicast address lists.
SG, will do!
> > + of the unicast and multicast address lists.
> >
> > ndo_setup_tc:
> > ``TC_SETUP_BLOCK`` and ``TC_SETUP_FT`` are running under NFT locks
> > diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> > index 469b7cdb3237..b05bdd67b807 100644
> > --- a/include/linux/netdevice.h
> > +++ b/include/linux/netdevice.h
> > @@ -1117,6 +1117,16 @@ struct netdev_net_notifier {
> > * This function is called device changes address list filtering.
> > * If driver handles unicast address filtering, it should set
> > * IFF_UNICAST_FLT in its priv_flags.
> > + * Cannot sleep, called with netif_addr_lock_bh held.
> > + * Deprecated in favor of sleepable ndo_set_rx_mode_async.
> > + *
> > + * void (*ndo_set_rx_mode_async)(struct net_device *dev,
> > + * struct netdev_hw_addr_list *uc,
> > + * struct netdev_hw_addr_list *mc);
> > + * Sleepable version of ndo_set_rx_mode. Called from a work queue
> > + * with rtnl_lock and netdev_lock_ops(dev) held. The uc/mc parameters
> > + * are snapshots of the address lists - iterate with
> > + * netdev_hw_addr_list_for_each(ha, uc).
> > *
> > * int (*ndo_set_mac_address)(struct net_device *dev, void *addr);
> > * This function is called when the Media Access Control address
> > @@ -1437,6 +1447,9 @@ struct net_device_ops {
> > void (*ndo_change_rx_flags)(struct net_device *dev,
> > int flags);
> > void (*ndo_set_rx_mode)(struct net_device *dev);
> > + void (*ndo_set_rx_mode_async)(struct net_device *dev,
> > + struct netdev_hw_addr_list *uc,
> > + struct netdev_hw_addr_list *mc);
> > int (*ndo_set_mac_address)(struct net_device *dev,
> > void *addr);
> > int (*ndo_validate_addr)(struct net_device *dev);
> > @@ -1903,6 +1916,7 @@ enum netdev_reg_state {
> > * has been enabled due to the need to listen to
> > * additional unicast addresses in a device that
> > * does not implement ndo_set_rx_mode()
> > + * @rx_mode_work: Work queue entry for ndo_set_rx_mode_async()
> > * @uc: unicast mac addresses
> > * @mc: multicast mac addresses
> > * @dev_addrs: list of device hw addresses
> > @@ -2293,6 +2307,7 @@ struct net_device {
> > unsigned int promiscuity;
> > unsigned int allmulti;
> > bool uc_promisc;
> > + struct work_struct rx_mode_work;
> > #ifdef CONFIG_LOCKDEP
> > unsigned char nested_level;
> > #endif
> > @@ -4661,6 +4676,11 @@ static inline bool netif_device_present(const struct net_device *dev)
> > return test_bit(__LINK_STATE_PRESENT, &dev->state);
> > }
> >
> > +static inline bool netif_up_and_present(const struct net_device *dev)
> > +{
> > + return (dev->flags & IFF_UP) && netif_device_present(dev);
>
> Is this really worth a dedicated helper? What are you trying to express
> here semantically?
I mostly added it to avoid repeating the same present & UP check. Will
undo.
> > +
> > void netif_device_detach(struct net_device *dev);
> >
> > void netif_device_attach(struct net_device *dev);
> > diff --git a/net/core/dev.c b/net/core/dev.c
> > index 200d44883fc1..fedc423306fc 100644
> > --- a/net/core/dev.c
> > +++ b/net/core/dev.c
> > @@ -2381,6 +2381,8 @@ static void netstamp_clear(struct work_struct *work)
> > static DECLARE_WORK(netstamp_work, netstamp_clear);
> > #endif
> >
> > +static struct workqueue_struct *rx_mode_wq;
> > +
> > void net_enable_timestamp(void)
> > {
> > #ifdef CONFIG_JUMP_LABEL
> > @@ -9669,22 +9671,84 @@ int netif_set_allmulti(struct net_device *dev, int inc, bool notify)
> > return 0;
> > }
> >
> > -/*
> > - * Upload unicast and multicast address lists to device and
> > - * configure RX filtering. When the device doesn't support unicast
> > - * filtering it is put in promiscuous mode while unicast addresses
> > - * are present.
> > +static void dev_rx_mode_work(struct work_struct *work)
> > +{
> > + struct net_device *dev = container_of(work, struct net_device,
> > + rx_mode_work);
> > + struct netdev_hw_addr_list uc_snap, mc_snap, uc_ref, mc_ref;
> > + const struct net_device_ops *ops = dev->netdev_ops;
> > + int err;
> > +
> > + __hw_addr_init(&uc_snap);
> > + __hw_addr_init(&mc_snap);
> > + __hw_addr_init(&uc_ref);
> > + __hw_addr_init(&mc_ref);
> > +
> > + rtnl_lock();
> > + netdev_lock_ops(dev);
> > +
> > + if (!netif_up_and_present(dev))
> > + goto out;
> > +
> > + if (ops->ndo_set_rx_mode_async) {
>
> How did we get here if we don't have this op?
> Are you planning to plumb more code thru this work in the future?
> If yes the whole rx_mode handling should be in a dedicated helper
> rather than indenting most of the function.
I do expand this, yes, in the subsequent patches. With promisc
handling (ndo_change_rx_flags) and ndo_set_rx_mode fallback. Let me try
to see if I can add some helper+struct to manage a set of snapshots
to make it a bit more clear.
> > + netif_addr_lock_bh(dev);
> > +
> > + err = __hw_addr_list_snapshot(&uc_snap, &dev->uc,
> > + dev->addr_len);
> > + if (!err)
> > + err = __hw_addr_list_snapshot(&uc_ref, &dev->uc,
> > + dev->addr_len);
> > + if (!err)
> > + err = __hw_addr_list_snapshot(&mc_snap, &dev->mc,
> > + dev->addr_len);
> > + if (!err)
> > + err = __hw_addr_list_snapshot(&mc_ref, &dev->mc,
> > + dev->addr_len);
>
> This doesn't get slow with a few thousands of addresses?
I can add kunit benchmark and attach the output? Although not sure where
to go from that. The alternative to this is allocating an array of entries.
I started with that initially but __hw_addr_sync_dev wants to kfree the
individual entries and I decided not to have a separate helpers to
manage the snapshots.
> > + netif_addr_unlock_bh(dev);
> > +
> > + if (err) {
> > + netdev_WARN(dev, "failed to sync uc/mc addresses\n");
> > + __hw_addr_flush(&uc_snap);
> > + __hw_addr_flush(&uc_ref);
> > + __hw_addr_flush(&mc_snap);
> > + goto out;
> > + }
> > +
> > + ops->ndo_set_rx_mode_async(dev, &uc_snap, &mc_snap);
> > +
> > + netif_addr_lock_bh(dev);
> > + __hw_addr_list_reconcile(&dev->uc, &uc_snap,
> > + &uc_ref, dev->addr_len);
> > + __hw_addr_list_reconcile(&dev->mc, &mc_snap,
> > + &mc_ref, dev->addr_len);
> > + netif_addr_unlock_bh(dev);
> > + }
> > +
> > +out:
> > + netdev_unlock_ops(dev);
> > + rtnl_unlock();
> > +}
> > +
> > +/**
> > + * __dev_set_rx_mode() - upload unicast and multicast address lists to device
> > + * and configure RX filtering.
> > + * @dev: device
> > + *
> > + * When the device doesn't support unicast filtering it is put in promiscuous
> > + * mode while unicast addresses are present.
> > */
> > void __dev_set_rx_mode(struct net_device *dev)
> > {
> > const struct net_device_ops *ops = dev->netdev_ops;
> >
> > /* dev_open will call this function so the list will stay sane. */
> > - if (!(dev->flags&IFF_UP))
> > + if (!netif_up_and_present(dev))
> > return;
> >
> > - if (!netif_device_present(dev))
> > + if (ops->ndo_set_rx_mode_async) {
> > + queue_work(rx_mode_wq, &dev->rx_mode_work);
> > return;
> > + }
> >
> > if (!(dev->priv_flags & IFF_UNICAST_FLT)) {
> > /* Unicast addresses changes may only happen under the rtnl,
> > @@ -11708,6 +11772,16 @@ void netdev_run_todo(void)
> >
> > __rtnl_unlock();
> >
> > + /* Make sure all pending rx_mode work completes before returning.
> > + *
> > + * rx_mode_wq may be NULL during early boot:
> > + * core_initcall(netlink_proto_init) vs subsys_initcall(net_dev_init).
> > + *
> > + * Check current_work() to avoid flushing from the wq.
> > + */
> > + if (rx_mode_wq && !current_work())
> > + flush_workqueue(rx_mode_wq);
>
> Can we give the work a reference on the netdev (at init time) and
> cancel + release it here instead of flushing / waiting?
Not sure why cancel+release, maybe you're thinking about the unregister
path? This is rtnl_unlock -> netdev_run_todo -> __rtnl_unlock + some
extras.
And the flush is here to plumb the addresses to the real devices
before we return to the callers. Mostly because of the following
things we have in the tests:
# TEST: team cleanup mode lacp [FAIL]
# macvlan unicast address not found on a slave
Can you explain a bit more on the suggestion?
> > /* Wait for rcu callbacks to finish before next phase */
> > if (!list_empty(&list))
> > rcu_barrier();
> > @@ -12099,6 +12173,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
> > #endif
> >
> > mutex_init(&dev->lock);
> > + INIT_WORK(&dev->rx_mode_work, dev_rx_mode_work);
> >
> > dev->priv_flags = IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM;
> > setup(dev);
> > @@ -12203,6 +12278,8 @@ void free_netdev(struct net_device *dev)
> >
> > kfree(rcu_dereference_protected(dev->ingress_queue, 1));
> >
> > + cancel_work_sync(&dev->rx_mode_work);
>
> Should never happen so maybe wrap it in a WARN ?
Or maybe just flush_workqueue here as well? To signal the intent that we
are mostly waiting for the wq entry to be unused to be able to kfree it?
^ permalink raw reply
* Re: [PATCH net-next v3 01/13] net: add address list snapshot and reconciliation infrastructure
From: Stanislav Fomichev @ 2026-03-24 18:13 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Stanislav Fomichev, netdev, davem, edumazet, pabeni, horms,
corbet, skhan, andrew+netdev, michael.chan, pavan.chebbi,
anthony.l.nguyen, przemyslaw.kitszel, saeedm, tariqt, mbloch,
alexanderduyck, kernel-team, johannes, sd, jianbol, dtatulea,
mohsin.bashr, jacob.e.keller, willemb, skhawaja, bestswngs,
aleksandr.loktionov, kees, linux-doc, linux-kernel,
intel-wired-lan, linux-rdma, linux-wireless, linux-kselftest,
leon
In-Reply-To: <20260323162053.62a148c2@kernel.org>
On 03/23, Jakub Kicinski wrote:
> On Thu, 19 Mar 2026 18:24:49 -0700 Stanislav Fomichev wrote:
> > +EXPORT_SYMBOL(__hw_addr_list_snapshot);
> > +EXPORT_SYMBOL(__hw_addr_list_reconcile);
>
> Why? For the kunit tests?
Yeah, no good reason, will remove!
^ permalink raw reply
* Re: [PATCH net-next v3 08/13] bnxt: use snapshot in bnxt_cfg_rx_mode
From: Stanislav Fomichev @ 2026-03-24 18:29 UTC (permalink / raw)
To: Michael Chan
Cc: Stanislav Fomichev, netdev, davem, edumazet, kuba, pabeni, horms,
corbet, skhan, andrew+netdev, pavan.chebbi, anthony.l.nguyen,
przemyslaw.kitszel, saeedm, tariqt, mbloch, alexanderduyck,
kernel-team, johannes, sd, jianbol, dtatulea, mohsin.bashr,
jacob.e.keller, willemb, skhawaja, bestswngs, aleksandr.loktionov,
kees, linux-doc, linux-kernel, intel-wired-lan, linux-rdma,
linux-wireless, linux-kselftest, leon
In-Reply-To: <CACKFLi=j7DO_d46jwZnmZ=OfmkoFA3AXUoX4nmF0tQuYt5Y3UQ@mail.gmail.com>
On 03/23, Michael Chan wrote:
> On Thu, Mar 19, 2026 at 6:25 PM Stanislav Fomichev <sdf@fomichev.me> wrote:
> >
> > With the introduction of ndo_set_rx_mode_async (as discussed in [0])
> > we can call bnxt_cfg_rx_mode directly. Convert bnxt_cfg_rx_mode to
> > use uc/mc snapshots and move its call in bnxt_sp_task to the
> > section that resets BNXT_STATE_IN_SP_TASK. Switch to direct call in
> > bnxt_set_rx_mode.
> >
> > 0: https://lore.kernel.org/netdev/CACKFLi=5vj8hPqEUKDd8RTw3au5G+zRgQEqjF+6NZnyoNm90KA@mail.gmail.com/
> >
> > Cc: Michael Chan <michael.chan@broadcom.com>
> > Cc: Pavan Chebbi <pavan.chebbi@broadcom.com>
> > Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
> > ---
> > drivers/net/ethernet/broadcom/bnxt/bnxt.c | 26 ++++++++++++++---------
> > 1 file changed, 16 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> > index 225217b32e4b..12265bd7fda4 100644
> > --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> > +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
> > @@ -11039,7 +11039,8 @@ static int bnxt_setup_nitroa0_vnic(struct bnxt *bp)
> > return rc;
> > }
> >
> > -static int bnxt_cfg_rx_mode(struct bnxt *);
> > +static int bnxt_cfg_rx_mode(struct bnxt *, struct netdev_hw_addr_list *,
> > + struct netdev_hw_addr_list *);
> > static bool bnxt_mc_list_updated(struct bnxt *, u32 *,
> > const struct netdev_hw_addr_list *);
> >
> > @@ -11135,7 +11136,7 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
> > vnic->rx_mask |= mask;
> > }
> >
> > - rc = bnxt_cfg_rx_mode(bp);
> > + rc = bnxt_cfg_rx_mode(bp, &bp->dev->uc, &bp->dev->mc);
> > if (rc)
> > goto err_out;
> >
> > @@ -13610,11 +13611,12 @@ static void bnxt_set_rx_mode(struct net_device *dev,
> > if (mask != vnic->rx_mask || uc_update || mc_update) {
> > vnic->rx_mask = mask;
> >
> > - bnxt_queue_sp_work(bp, BNXT_RX_MASK_SP_EVENT);
> > + bnxt_cfg_rx_mode(bp, uc, mc);
> > }
> > }
> >
> > -static int bnxt_cfg_rx_mode(struct bnxt *bp)
> > +static int bnxt_cfg_rx_mode(struct bnxt *bp, struct netdev_hw_addr_list *uc,
> > + struct netdev_hw_addr_list *mc)
> > {
> > struct net_device *dev = bp->dev;
> > struct bnxt_vnic_info *vnic = &bp->vnic_info[BNXT_VNIC_DEFAULT];
> > @@ -13623,7 +13625,7 @@ static int bnxt_cfg_rx_mode(struct bnxt *bp)
> > bool uc_update;
> >
> > netif_addr_lock_bh(dev);
> > - uc_update = bnxt_uc_list_updated(bp, &dev->uc);
> > + uc_update = bnxt_uc_list_updated(bp, uc);
>
> Will the uc list snapshot change between bnxt_set_rx_mode() and
> bnxt_cfg_rx_mode() with the direct call now? In the original deferred
> update implementation, the uc list can change and that's why we check
> in both functions.
The snapshot is gonna be the same for bnxt_set_rx_mode->bnxt_cfg_rx_mode path.
So you're saying that it's ok to remove the one in bnxt_cfg_rx_mode
because it's called either from bnxt_set_rx_mode (with a new list) or,
explicitly, via the BNXT_RX_MASK_SP_EVENT retry mechanism (where we know
that we need to redo the updates anyway)?
This makes me wonder whether I need to push the retrying mechanism to
the core stack... Right now, if some of the allocations in wq handler
fail, we just give up, maybe I should handle it better. And I can plug
the signal from the driver (make ndo_set_rx_mode_async return int)
in the same retry mechanism.
^ permalink raw reply
* Re: [PATCH v2 05/13] wifi: mt76: mt7925: advertise EHT 320MHz capabilities for 6GHz band
From: Sean Wang @ 2026-03-24 19:24 UTC (permalink / raw)
To: Javier Tia
Cc: Felix Fietkau, Lorenzo Bianconi, Ryder Lee, Shayne Chen,
Sean Wang, Matthias Brugger, AngeloGioacchino Del Regno, Deren Wu,
Ming Yen Hsieh, linux-wireless, linux-kernel, linux-arm-kernel,
linux-mediatek, Marcin FM, Cristian-Florin Radoi,
George Salukvadze, Evgeny Kapusta, Samu Toljamo, Ariel Rosenfeld,
Chapuis Dario, Thibaut François, 张旭涵
In-Reply-To: <20260319-mt7927-wifi-support-v2-v2-5-d627a7fad70d@jetm.me>
Hi,
On Thu, Mar 19, 2026 at 5:26 PM Javier Tia <floss@jetm.me> wrote:
>
> mt7925_init_eht_caps() only populates EHT MCS/NSS maps for BW <= 80
> and BW = 160, but never sets BW = 320. This means iw phy shows no
> 320MHz MCS map entries even though the hardware supports 320MHz
> operation in the 6GHz band.
>
> Add the missing 320MHz capability bits for 6GHz, following the same
> pattern as mt7996:
> - PHY_CAP0: IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ
> - PHY_CAP1: beamformee SS for 320MHz
> - PHY_CAP2: sounding dimensions for 320MHz
> - PHY_CAP6: MCS15 support for 320MHz width
> - PHY_CAP7: non-OFDMA UL MU-MIMO and MU beamformer for 320MHz
> - MCS/NSS: populate bw._320 maps for 6GHz band
>
> Introduce is_320mhz_supported() as a generic capability check using the
> mt7925 family ID. This avoids chip-specific references in common code,
> and automatically extends to new chips once they join the
> is_mt7925() family via chip ID helpers.
>
> Tested-by: Marcin FM <marcin@lgic.pl>
> Tested-by: Cristian-Florin Radoi <radoi.chris@gmail.com>
> Tested-by: George Salukvadze <giosal90@gmail.com>
> Tested-by: Evgeny Kapusta <3193631@gmail.com>
> Tested-by: Samu Toljamo <samu.toljamo@gmail.com>
> Tested-by: Ariel Rosenfeld <ariel.rosenfeld.750@gmail.com>
> Tested-by: Chapuis Dario <chapuisdario4@gmail.com>
> Tested-by: Thibaut François <tibo@humeurlibre.fr>
> Tested-by: 张旭涵 <Loong.0x00@gmail.com>
> Signed-off-by: Javier Tia <floss@jetm.me>
> ---
> drivers/net/wireless/mediatek/mt76/mt76_connac.h | 5 +++++
> drivers/net/wireless/mediatek/mt76/mt7925/main.c | 28 +++++++++++++++++++++++-
> 2 files changed, 32 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
> index 813d61bffc2c..554716e01ee6 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
> @@ -177,6 +177,11 @@ static inline bool is_mt7925(struct mt76_dev *dev)
> return mt76_chip(dev) == 0x7925;
> }
>
> +static inline bool is_320mhz_supported(struct mt76_dev *dev)
> +{
> + return is_mt7925(dev);
I don't think this is correct for mt7925, and it will cause a
regression there. Was this tested on actual mt7925 hardware?
> +}
> +
> static inline bool is_mt7920(struct mt76_dev *dev)
> {
> return mt76_chip(dev) == 0x7920;
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
> index f128a198f81d..cd043ac266fb 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
> @@ -183,6 +183,10 @@ mt7925_init_eht_caps(struct mt792x_phy *phy, enum nl80211_band band,
> IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER |
> IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE;
>
> + if (band == NL80211_BAND_6GHZ && is_320mhz_supported(&phy->dev->mt76))
> + eht_cap_elem->phy_cap_info[0] |=
> + IEEE80211_EHT_PHY_CAP0_320MHZ_IN_6GHZ;
> +
> eht_cap_elem->phy_cap_info[0] |=
> u8_encode_bits(u8_get_bits(sts - 1, BIT(0)),
> IEEE80211_EHT_PHY_CAP0_BEAMFORMEE_SS_80MHZ_MASK);
> @@ -193,10 +197,20 @@ mt7925_init_eht_caps(struct mt792x_phy *phy, enum nl80211_band band,
> u8_encode_bits(sts - 1,
> IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_160MHZ_MASK);
>
> + if (band == NL80211_BAND_6GHZ && is_320mhz_supported(&phy->dev->mt76))
> + eht_cap_elem->phy_cap_info[1] |=
> + u8_encode_bits(sts - 1,
> + IEEE80211_EHT_PHY_CAP1_BEAMFORMEE_SS_320MHZ_MASK);
> +
> eht_cap_elem->phy_cap_info[2] =
> u8_encode_bits(sts - 1, IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_80MHZ_MASK) |
> u8_encode_bits(sts - 1, IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_160MHZ_MASK);
>
> + if (band == NL80211_BAND_6GHZ && is_320mhz_supported(&phy->dev->mt76))
> + eht_cap_elem->phy_cap_info[2] |=
> + u8_encode_bits(sts - 1,
> + IEEE80211_EHT_PHY_CAP2_SOUNDING_DIM_320MHZ_MASK);
> +
> eht_cap_elem->phy_cap_info[3] =
> IEEE80211_EHT_PHY_CAP3_NG_16_SU_FEEDBACK |
> IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK |
> @@ -217,7 +231,8 @@ mt7925_init_eht_caps(struct mt792x_phy *phy, enum nl80211_band band,
> u8_encode_bits(u8_get_bits(0x11, GENMASK(1, 0)),
> IEEE80211_EHT_PHY_CAP5_MAX_NUM_SUPP_EHT_LTF_MASK);
>
> - val = width == NL80211_CHAN_WIDTH_160 ? 0x7 :
> + val = width == NL80211_CHAN_WIDTH_320 ? 0xf :
> + width == NL80211_CHAN_WIDTH_160 ? 0x7 :
> width == NL80211_CHAN_WIDTH_80 ? 0x3 : 0x1;
> eht_cap_elem->phy_cap_info[6] =
> u8_encode_bits(u8_get_bits(0x11, GENMASK(4, 2)),
> @@ -230,6 +245,11 @@ mt7925_init_eht_caps(struct mt792x_phy *phy, enum nl80211_band band,
> IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_80MHZ |
> IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_160MHZ;
>
> + if (band == NL80211_BAND_6GHZ && is_320mhz_supported(&phy->dev->mt76))
> + eht_cap_elem->phy_cap_info[7] |=
> + IEEE80211_EHT_PHY_CAP7_NON_OFDMA_UL_MU_MIMO_320MHZ |
> + IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ;
> +
I don't think this should be copied from mt7996 as-is for mt7927. I'd
suggest dropping the eht_cap_elem->phy_cap_info[7] change and keeping
it conservative for now.
> val = u8_encode_bits(nss, IEEE80211_EHT_MCS_NSS_RX) |
> u8_encode_bits(nss, IEEE80211_EHT_MCS_NSS_TX);
>
> @@ -239,6 +259,12 @@ mt7925_init_eht_caps(struct mt792x_phy *phy, enum nl80211_band band,
> eht_nss->bw._160.rx_tx_mcs9_max_nss = val;
> eht_nss->bw._160.rx_tx_mcs11_max_nss = val;
> eht_nss->bw._160.rx_tx_mcs13_max_nss = val;
> +
> + if (band == NL80211_BAND_6GHZ && is_320mhz_supported(&phy->dev->mt76)) {
> + eht_nss->bw._320.rx_tx_mcs9_max_nss = val;
> + eht_nss->bw._320.rx_tx_mcs11_max_nss = val;
> + eht_nss->bw._320.rx_tx_mcs13_max_nss = val;
> + }
> }
>
> int mt7925_init_mlo_caps(struct mt792x_phy *phy)
>
> --
> 2.53.0
>
>
^ permalink raw reply
* Re: [PATCH v2 0/3] ath10k: Introduce a devicetree quirk to skip host cap QMI requests
From: Dmitry Baryshkov @ 2026-03-24 21:09 UTC (permalink / raw)
To: David Heidelberg
Cc: Jeff Johnson, Johannes Berg, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jeff Johnson, Bjorn Andersson, Konrad Dybcio,
linux-wireless, devicetree, ath10k, linux-kernel, linux-arm-msm,
phone-devel, Amit Pundir
In-Reply-To: <b7gibtoind5srjk6ncybnen3ikdvwnktg4epyzbltg7alipmex@k5zzpbnmzlso>
On Tue, Nov 25, 2025 at 04:42:15PM +0200, Dmitry Baryshkov wrote:
> On Tue, Nov 25, 2025 at 10:29:23AM +0100, David Heidelberg wrote:
> > On 10/11/2025 21:41, Dmitry Baryshkov wrote:
> >
> > [...]
> >
> > > I think this should go to the firmware-N file. SNOC platforms now allow
> > > per-platform firmware description files, so it's possible to describe
> > > quirks for the particular firmware file.
> >
> > Since the approach to put it into the firmware failed due to early
> > initialization, see
> > https://lore.kernel.org/linux-wireless/20251111-xiaomi-beryllium-firmware-v1-0-836b9c51ad86@ixit.cz/
>
> Is it required before we load the firmware? If so, it must be clearly
> explained in the commit messages. In the end, if it happens before
> firmware load, there is little you can do. That was the reason why
> qcom,no-msa-ready-indicator was implemented as a DT property.
David, gracious ping. Could you please describe your findings in the
commit messages and repost? Please explain that there is no other
sensible way to provide this information to the driver since this
happens before we load firmware-N.bin / board-M.bin).
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH net-next v3 03/13] net: introduce ndo_set_rx_mode_async and dev_rx_mode_work
From: Jakub Kicinski @ 2026-03-24 21:21 UTC (permalink / raw)
To: Stanislav Fomichev
Cc: Stanislav Fomichev, netdev, davem, edumazet, pabeni, horms,
corbet, skhan, andrew+netdev, michael.chan, pavan.chebbi,
anthony.l.nguyen, przemyslaw.kitszel, saeedm, tariqt, mbloch,
alexanderduyck, kernel-team, johannes, sd, jianbol, dtatulea,
mohsin.bashr, jacob.e.keller, willemb, skhawaja, bestswngs,
aleksandr.loktionov, kees, linux-doc, linux-kernel,
intel-wired-lan, linux-rdma, linux-wireless, linux-kselftest,
leon
In-Reply-To: <acLUMN1BYkIVyOk8@mini-arch>
On Tue, 24 Mar 2026 11:13:04 -0700 Stanislav Fomichev wrote:
> > > + netif_addr_lock_bh(dev);
> > > +
> > > + err = __hw_addr_list_snapshot(&uc_snap, &dev->uc,
> > > + dev->addr_len);
> > > + if (!err)
> > > + err = __hw_addr_list_snapshot(&uc_ref, &dev->uc,
> > > + dev->addr_len);
> > > + if (!err)
> > > + err = __hw_addr_list_snapshot(&mc_snap, &dev->mc,
> > > + dev->addr_len);
> > > + if (!err)
> > > + err = __hw_addr_list_snapshot(&mc_ref, &dev->mc,
> > > + dev->addr_len);
> >
> > This doesn't get slow with a few thousands of addresses?
>
> I can add kunit benchmark and attach the output? Although not sure where
> to go from that. The alternative to this is allocating an array of entries.
> I started with that initially but __hw_addr_sync_dev wants to kfree the
> individual entries and I decided not to have a separate helpers to
> manage the snapshots.
Let's see what the benchmark says. Hopefully it's fast enough and
we don't have to worry. Is keeping these lists around between the
invocations of the work tricky?
> > Can we give the work a reference on the netdev (at init time) and
> > cancel + release it here instead of flushing / waiting?
>
> Not sure why cancel+release, maybe you're thinking about the unregister
> path? This is rtnl_unlock -> netdev_run_todo -> __rtnl_unlock + some
> extras.
>
> And the flush is here to plumb the addresses to the real devices
> before we return to the callers. Mostly because of the following
> things we have in the tests:
>
> # TEST: team cleanup mode lacp [FAIL]
> # macvlan unicast address not found on a slave
>
> Can you explain a bit more on the suggestion?
Oh, I thought it's here for unregister! Feels like it'd be cleaner to
add the flush in dev_*c_add() and friends? How hard would it be to
identify the callers in atomic context?
> > > /* Wait for rcu callbacks to finish before next phase */
> > > if (!list_empty(&list))
> > > rcu_barrier();
> > > @@ -12099,6 +12173,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
> > > #endif
> > >
> > > mutex_init(&dev->lock);
> > > + INIT_WORK(&dev->rx_mode_work, dev_rx_mode_work);
> > >
> > > dev->priv_flags = IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM;
> > > setup(dev);
> > > @@ -12203,6 +12278,8 @@ void free_netdev(struct net_device *dev)
> > >
> > > kfree(rcu_dereference_protected(dev->ingress_queue, 1));
> > >
> > > + cancel_work_sync(&dev->rx_mode_work);
> >
> > Should never happen so maybe wrap it in a WARN ?
>
> Or maybe just flush_workqueue here as well? To signal the intent that we
> are mostly waiting for the wq entry to be unused to be able to kfree it?
>
^ permalink raw reply
* [PATCH] wifi: virt_wifi: remove SET_NETDEV_DEV to avoid use-after-free
From: Alexander Popov @ 2026-03-24 22:46 UTC (permalink / raw)
To: Andrew Lunn, Jakub Kicinski, David Miller, Eric Dumazet,
Paolo Abeni, Simon Horman, Maxime Chevallier, Michal Kubecek,
Gal Pressman, Kory Maincent, Oleksij Rempel, Ido Schimmel,
Heiner Kallweit, Greg KH, Johannes Berg, James Guan, Kees Cook,
Paul Moses, linux-wireless, netdev, linux-kernel, Alexander Popov
Cc: security, notify
Currently we execute `SET_NETDEV_DEV(dev, &priv->lowerdev->dev)` for
the virt_wifi net devices. However, unregistering a virt_wifi device in
netdev_run_todo() can happen together with the device referenced by
SET_NETDEV_DEV().
It can result in use-after-free during the ethtool operations performed
on a virt_wifi device that is currently being unregistered. Such a net
device can have the `dev.parent` field pointing to the freed memory,
but ethnl_ops_begin() calls `pm_runtime_get_sync(dev->dev.parent)`.
Let's remove SET_NETDEV_DEV for virt_wifi to avoid bugs like this:
==================================================================
BUG: KASAN: slab-use-after-free in __pm_runtime_resume+0xe2/0xf0
Read of size 2 at addr ffff88810cfc46f8 by task pm/606
Call Trace:
<TASK>
dump_stack_lvl+0x4d/0x70
print_report+0x170/0x4f3
? __pfx__raw_spin_lock_irqsave+0x10/0x10
kasan_report+0xda/0x110
? __pm_runtime_resume+0xe2/0xf0
? __pm_runtime_resume+0xe2/0xf0
__pm_runtime_resume+0xe2/0xf0
ethnl_ops_begin+0x49/0x270
ethnl_set_features+0x23c/0xab0
? __pfx_ethnl_set_features+0x10/0x10
? kvm_sched_clock_read+0x11/0x20
? local_clock_noinstr+0xf/0xf0
? local_clock+0x10/0x30
? kasan_save_track+0x25/0x60
? __kasan_kmalloc+0x7f/0x90
? genl_family_rcv_msg_attrs_parse.isra.0+0x150/0x2c0
genl_family_rcv_msg_doit+0x1e7/0x2c0
? __pfx_genl_family_rcv_msg_doit+0x10/0x10
? __pfx_cred_has_capability.isra.0+0x10/0x10
? stack_trace_save+0x8e/0xc0
genl_rcv_msg+0x411/0x660
? __pfx_genl_rcv_msg+0x10/0x10
? __pfx_ethnl_set_features+0x10/0x10
netlink_rcv_skb+0x121/0x380
? __pfx_genl_rcv_msg+0x10/0x10
? __pfx_netlink_rcv_skb+0x10/0x10
? __pfx_down_read+0x10/0x10
genl_rcv+0x23/0x30
netlink_unicast+0x60f/0x830
? __pfx_netlink_unicast+0x10/0x10
? __pfx___alloc_skb+0x10/0x10
netlink_sendmsg+0x6ea/0xbc0
? __pfx_netlink_sendmsg+0x10/0x10
? __futex_queue+0x10b/0x1f0
____sys_sendmsg+0x7a2/0x950
? copy_msghdr_from_user+0x26b/0x430
? __pfx_____sys_sendmsg+0x10/0x10
? __pfx_copy_msghdr_from_user+0x10/0x10
___sys_sendmsg+0xf8/0x180
? __pfx____sys_sendmsg+0x10/0x10
? __pfx_futex_wait+0x10/0x10
? fdget+0x2e4/0x4a0
__sys_sendmsg+0x11f/0x1c0
? __pfx___sys_sendmsg+0x10/0x10
do_syscall_64+0xe2/0x570
? exc_page_fault+0x66/0xb0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
This fix may be combined with another one in the ethtool subsystem:
https://lore.kernel.org/all/20260322075917.254874-1-alex.popov@linux.com/T/#u
Fixes: d43c65b05b848e0b ("ethtool: runtime-resume netdev parent in ethnl_ops_begin")
Cc: stable@vger.kernel.org
Signed-off-by: Alexander Popov <alex.popov@linux.com>
---
drivers/net/wireless/virtual/virt_wifi.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/net/wireless/virtual/virt_wifi.c b/drivers/net/wireless/virtual/virt_wifi.c
index 885dc7243e8d..97bd39d89e98 100644
--- a/drivers/net/wireless/virtual/virt_wifi.c
+++ b/drivers/net/wireless/virtual/virt_wifi.c
@@ -557,7 +557,6 @@ static int virt_wifi_newlink(struct net_device *dev,
eth_hw_addr_inherit(dev, priv->lowerdev);
netif_stacked_transfer_operstate(priv->lowerdev, dev);
- SET_NETDEV_DEV(dev, &priv->lowerdev->dev);
dev->ieee80211_ptr = kzalloc_obj(*dev->ieee80211_ptr);
if (!dev->ieee80211_ptr) {
--
2.53.0
^ permalink raw reply related
* Re: [PATCH net-next v3 03/13] net: introduce ndo_set_rx_mode_async and dev_rx_mode_work
From: Stanislav Fomichev @ 2026-03-24 22:49 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Stanislav Fomichev, netdev, davem, edumazet, pabeni, horms,
corbet, skhan, andrew+netdev, michael.chan, pavan.chebbi,
anthony.l.nguyen, przemyslaw.kitszel, saeedm, tariqt, mbloch,
alexanderduyck, kernel-team, johannes, sd, jianbol, dtatulea,
mohsin.bashr, jacob.e.keller, willemb, skhawaja, bestswngs,
aleksandr.loktionov, kees, linux-doc, linux-kernel,
intel-wired-lan, linux-rdma, linux-wireless, linux-kselftest,
leon
In-Reply-To: <20260324142114.216fcb01@kernel.org>
On 03/24, Jakub Kicinski wrote:
> On Tue, 24 Mar 2026 11:13:04 -0700 Stanislav Fomichev wrote:
> > > > + netif_addr_lock_bh(dev);
> > > > +
> > > > + err = __hw_addr_list_snapshot(&uc_snap, &dev->uc,
> > > > + dev->addr_len);
> > > > + if (!err)
> > > > + err = __hw_addr_list_snapshot(&uc_ref, &dev->uc,
> > > > + dev->addr_len);
> > > > + if (!err)
> > > > + err = __hw_addr_list_snapshot(&mc_snap, &dev->mc,
> > > > + dev->addr_len);
> > > > + if (!err)
> > > > + err = __hw_addr_list_snapshot(&mc_ref, &dev->mc,
> > > > + dev->addr_len);
> > >
> > > This doesn't get slow with a few thousands of addresses?
> >
> > I can add kunit benchmark and attach the output? Although not sure where
> > to go from that. The alternative to this is allocating an array of entries.
> > I started with that initially but __hw_addr_sync_dev wants to kfree the
> > individual entries and I decided not to have a separate helpers to
> > manage the snapshots.
>
> Let's see what the benchmark says. Hopefully it's fast enough and
> we don't have to worry. Is keeping these lists around between the
> invocations of the work tricky?
Yeah, that sounds doable, don't think it's too tricky, just extra
list_head on net_device + change the alloc/free to use it.
And then we keep this cache around until unregister? I will try to add it as
a separate patch to cache these entries to keep it simple for review..
> > > Can we give the work a reference on the netdev (at init time) and
> > > cancel + release it here instead of flushing / waiting?
> >
> > Not sure why cancel+release, maybe you're thinking about the unregister
> > path? This is rtnl_unlock -> netdev_run_todo -> __rtnl_unlock + some
> > extras.
> >
> > And the flush is here to plumb the addresses to the real devices
> > before we return to the callers. Mostly because of the following
> > things we have in the tests:
> >
> > # TEST: team cleanup mode lacp [FAIL]
> > # macvlan unicast address not found on a slave
> >
> > Can you explain a bit more on the suggestion?
>
> Oh, I thought it's here for unregister! Feels like it'd be cleaner to
> add the flush in dev_*c_add() and friends? How hard would it be to
> identify the callers in atomic context?
Not sure we can do it in dev_xc_add because it runs under rtnl :-(
I currently do flush in netdev_run_todo because that's the place that
doesn't hold rtnl. Otherwise flush will get stuck because the work
handler grabs it...
^ permalink raw reply
* Re: [PATCH v2 rtw-next] wifi: rtw88: validate RX rate to prevent out-of-bound
From: LB F @ 2026-03-24 23:55 UTC (permalink / raw)
To: Ping-Ke Shih; +Cc: linux-wireless
In-Reply-To: <20260324011001.5742-1-pkshih@realtek.com>
Ping-Ke Shih <pkshih@realtek.com> wrote:
> The reported RX rate might be unexpected, causing kernel warns:
>
> Rate marked as a VHT rate but data is invalid: MCS: 0, NSS: 0
> WARNING: net/mac80211/rx.c:5491 at ieee80211_rx_list+0x183/0x1020 [mac80211]
>
> As the RX rate can be index of an array under certain conditions, validate
> it to prevent accessing array out-of-bound potentially.
Tested on HP Notebook P3S95EA#ACB (kernel 6.19.9-1-cachyos):
- No WARNING: net/mac80211/rx.c:5491 observed after the v2 patch.
The unexpected `NSS: 0, MCS: 0` VHT rate warnings are successfully
mitigated.
- The system remains fully stable through prolonged idle periods,
high network load, active Bluetooth A2DP usage, and multiple deep
suspend/resume cycles.
- Zero h2c timeouts or firmware lps state errors observed in dmesg.
The v2 patch (with the added `unlikely()` hint) functions flawlessly.
Tested-by: Oleksandr Havrylov <goainwo@gmail.com>
^ permalink raw reply
* Re: [PATCH] wifi: mac80211: fix monitor mode frame capture for real chanctx drivers
From: 傅继晗 @ 2026-03-25 0:15 UTC (permalink / raw)
To: oscar.alfonso.diaz
Cc: 傅继晗, johannes, linux-wireless, linux-kernel,
stable
In-Reply-To: <CA+bbHrW0C9+Pz5TOUgM_oodhfJnoO7P0YiEdp85D08h=hLPF5A@mail.gmail.com>
Hi Oscar,
Thank you for testing the v1 patch and reporting the VM hang -- your
report was critical in identifying the root cause.
Lucid-Duck did extensive debugging and reproduction work on this.
The full discussion is here:
https://github.com/morrownr/USB-WiFi/issues/682#issuecomment-4120751621
Root cause of the crash:
The v1 patch falls back to list_first_entry_or_null(&local->chanctx_list)
when the monitor vif has no chanctx. In your Evil Twin + DoS scenario,
the AP and monitor interfaces created multiple channel contexts. The
fallback blindly grabbed whichever chanctx was first on the list --
which could be the AP's chanctx that the firmware wasn't expecting
monitor traffic on. Injecting frames on a chanctx where
mt7921_mcu_config_sniffer() was never called is the likely trigger
for the hard hang.
The v2 patch adds a list_is_singular() guard: injection only proceeds
when there is exactly one chanctx (unambiguous), and is refused when
multiple chanctxs exist. This covers the common single-channel AP +
monitor case while preventing the dangerous multi-chanctx path that
caused your crash.
Lucid-Duck tested v2 extensively on kernel 6.19.8 with the MT7921AU
(ALFA AWUS036AXML) -- single-channel AP + monitor + injection,
multi-chanctx via P2P-GO, heavy load injection floods (50k fps,
1.8M packets) -- all stable with zero crashes or kernel warnings.
The v2 diff against net/mac80211/tx.c:
chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf);
- if (chanctx_conf)
+ if (chanctx_conf) {
chandef = &chanctx_conf->def;
- else if (local->emulate_chanctx)
+ } else if (local->emulate_chanctx) {
chandef = &local->hw.conf.chandef;
- else
- goto fail_rcu;
+ } else {
+ struct ieee80211_chanctx *ctx;
+
+ ctx = list_first_entry_or_null(&local->chanctx_list,
+ struct ieee80211_chanctx,
+ list);
+ if (ctx && list_is_singular(&local->chanctx_list))
+ chandef = &ctx->conf.def;
+ else
+ goto fail_rcu;
+ }
If you have time, could you re-test with this v2 patch in your
original Evil Twin + DoS setup? That would help confirm the fix
before I send v2 to the list.
Thanks again for your help!
Best regards,
傅继晗
^ permalink raw reply
* Re: [PATCH v3 2/9] dt-bindings: mmc: amlogic: Add compatible for T7 mmc
From: Xianwei Zhao @ 2026-03-25 2:38 UTC (permalink / raw)
To: Ronald Claveau, Neil Armstrong, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Ulf Hansson, Johannes Berg, van Spriel
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
linux-mmc, linux-wireless
In-Reply-To: <20260323-add-emmc-t7-vim4-v3-2-5159d90a984c@aliel.fr>
Hi Ronald,
On 2026/3/23 17:55, Ronald Claveau wrote:
> Add amlogic,t7-mmc compatible string, falling back to amlogic,meson-axg-mmc
> as the T7 MMC controller is compatible with the AXG implementation.
>
> Signed-off-by: Ronald Claveau<linux-kernel-dev@aliel.fr>
> ---
> Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml | 5
> ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git
> a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml
> b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml
> index 57646575a13f8..40dccf9715781 100644
> --- a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml
> +++ b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml
> @@ -19,7 +19,10 @@ allOf:
> properties:
> compatible:
> oneOf:
> - - const: amlogic,meson-axg-mmc
> + - items:
> + - enum:
> + - amlogic,t7-mmc
> + - const: amlogic,meson-axg-mmc
It seems that break API here.
One item should be added here instead of being replaced.
> - items:
> - const: amlogic,meson-gx-mmc
> - const: amlogic,meson-gxbb-mmc
>
> --
> 2.49.0
^ permalink raw reply
* Re: ath12k: desc_va endianness problem
From: Baochen Qiang @ 2026-03-25 2:46 UTC (permalink / raw)
To: Alexander Wilhelm; +Cc: Jeff Johnson, ath12k, linux-wireless, linux-kernel
In-Reply-To: <acEh4vckyl6bq29l@FUE-ALEWI-WINX>
On 3/23/2026 7:20 PM, Alexander Wilhelm wrote:
> On Mon, Mar 23, 2026 at 05:31:03PM +0800, Baochen Qiang wrote:
>>
>>
>> On 3/20/2026 5:52 PM, Alexander Wilhelm wrote:
>>> Hello ath12k developers,
>>>
>>> I have another fix for the big endian platform, but unfortunately the data types
>>> do not match here, so I need your support. The problem is the following: the
>>> structs `hal_reo_dest_ring`, `hal_wbm_completion_ring`, and
>>> `hal_wbm_release_ring_cc_rx` all define the members `buf_va_lo` and `buf_va_hi`
>>> as `__le32`. At first glance this seems correct, because the entire structure
>>> contains only little endian fields. The local variable `desc_va` in each
>>> function (see patch below) is of type `u64`, so it makes sense that I would need
>>> to convert from little endian to CPU endian. Unfortunately, this leads to the
>>> following crashes, in `tx_completion` and `rx_process_wbm`, respectivally:
>>>
>>>
>>> Kernel attempted to read user page (40dcdf) - exploit attempt? (uid: 0)
>>> BUG: Unable to handle kernel data access on read at 0x0040dcdf
>>> Faulting instruction address: 0xe209290c
>>> Oops: Kernel access of bad area, sig: 11 [#1]
>>> BE PAGE_SIZE=4K SMP NR_CPUS=4 CoreNet Generic
>>> Modules linked in: ath12k(O) mac80211(O) cfg80211(O) compat(O) ...
>>> CPU: 1 PID: 10200 Comm: jshn Tainted: G O 6.6.73 #0
>>> Hardware name: CyBoxAP-A e5500 0x80241021 CoreNet Generic
>>> NIP: e209290c LR: e2092854 CTR: c08d3190
>>> REGS: dffe3d40 TRAP: 0300 Tainted: G O (6.6.73)
>>> MSR: 00029002 <CE,EE,ME> CR: 44004804 XER: 00000000
>>> DEAR: 0040dcdf ESR: 00000000
>>> GPR00: e2092854 dffe3e30 c328a500 e2092854 0040dcce 00000008 00070000 cf900000
>>> GPR08: 00000000 cf900004 40000000 c8e52c4c c08d3190 1002801c 0fcf5000 c0ab85f8
>>> GPR16: d0d1f7a0 c12a9080 00000001 df7b7f80 00000003 cf900000 e1bc0000 e1ccb988
>>> GPR24: ffffffff c8ed0000 e1cc0220 00000000 c8ec0000 c8ec0000 c8ec0f50 c8ec0000
>>> NIP [e209290c] ath12k_dp_tx_completion_handler+0x22c/0x720 [ath12k]
>>> LR [e2092854] ath12k_dp_tx_completion_handler+0x174/0x720 [ath12k]
>>> Call Trace:
>>> [dffe3e30] [e2092854] ath12k_dp_tx_completion_handler+0x174/0x720 [ath12k] (unreliable)
>>> [dffe3e80] [e208fe18] ath12k_dp_service_srng+0x58/0x380 [ath12k]
>>> [dffe3ed0] [e20a1490] ath12k_pci_hif_resume+0x520/0x8a0 [ath12k]
>>> [dffe3f00] [c067404c] __napi_poll+0x4c/0x260
>>> [dffe3f30] [c06746f8] net_rx_action+0x188/0x340
>>> [dffe3fa0] [c003a3d8] handle_softirqs+0x128/0x280
>>> [dffe3ff0] [c00045b0] do_softirq_own_stack+0x30/0x50
>>> [d0f2fb70] [00000000] 0x0
>>> [d0f2fb90] [c003a7d0] irq_exit+0x70/0xa0
>>> [d0f2fba0] [c0000c84] ExternalInput+0x144/0x160
>>> --- interrupt: 500 at percpu_counter_add_batch+0x9c/0x150
>>> NIP: c0425e8c LR: c01a5964 CTR: c01764e0
>>> REGS: d0f2fbb0 TRAP: 0500 Tainted: G O (6.6.73)
>>> MSR: 00029002 <CE,EE,ME> CR: 48008802 XER: 20000000
>>>
>>> GPR00: c01a5a00 d0f2fca0 c328a500 c1db7300 dffc0f20 00000000 fffffffc 00021002
>>> GPR08: 1e763000 e1091054 00000007 c12b0530 88002808 1002801c 0fcf5000 c0ab85f8
>>> GPR16: d0d1f7a0 dffc0f20 00000000 000003fe 00000000 f92412bd 00000003 c9525480
>>> GPR24: d0f2fd74 c8a501f8 c12b0530 00029002 00000007 00000000 0000000b c1db7300
>>> NIP [c0425e8c] percpu_counter_add_batch+0x9c/0x150
>>> LR [c01a5964] unmap_page_range+0x484/0x820
>>> --- interrupt: 500
>>> [d0f2fca0] [00000001] 0x1 (unreliable)
>>> [d0f2fcd0] [c01a5a00] unmap_page_range+0x520/0x820
>>> [d0f2fd60] [c01a5d9c] unmap_vmas+0x9c/0xe0
>>> [d0f2fda0] [c01afef4] exit_mmap+0xb4/0x2a0
>>> [d0f2fe40] [c0031610] mmput+0x40/0x140
>>> [d0f2fe60] [c0038df4] do_exit+0x2b4/0x990
>>> [d0f2feb0] [c00396c4] do_group_exit+0x34/0xa0
>>> [d0f2fed0] [c0039748] sys_exit_group+0x18/0x20
>>> [d0f2fee0] [c000dbac] system_call_exception+0xac/0x1f0
>>> [d0f2ff00] [c00110e8] ret_from_syscall+0x0/0x28
>>> --- interrupt: c00 at 0xfded438
>>> NIP: 0fded438 LR: 0ff23958 CTR: 0fd94930
>>> REGS: d0f2ff10 TRAP: 0c00 Tainted: G O (6.6.73)
>>> MSR: 0002f902 <CE,EE,PR,FP,ME> CR: 28002402 XER: 20000000
>>>
>>> GPR00: 000000ea bff93390 b0316520 00000000 113e8af0 113e8af0 00000000 00000000
>>> GPR08: 00000000 00000000 00000000 ffffffff b02ccb04 1002801c 100a0000 bfbc4260
>>> GPR16: 114974b0 00000000 114a4de0 00000000 b02cc900 00000001 00000000 00000001
>>> GPR24: 0ff239a0 00000000 00000001 00000000 b030f52c fffff000 0ff23958 00000000
>>> NIP [0fded438] 0xfded438
>>> LR [0ff23958] 0xff23958
>>> --- interrupt: c00
>>> Code: 512a421e 2e140000 512a463e 40f20008 555b9f3e 39350004 754a4000 7c804c2c 41c20224 7c87442c 2c040000 41c20230 <88a40011> 7fc3f378 83a40008 8a640010
>>> ---[ end trace 0000000000000000 ]---
>>>
>>> Kernel panic - not syncing: Fatal exception
>>> ---[ end Kernel panic - not syncing: Fatal exception ]---
>>>
>>>
>>> user@root:~# Kernel attempted to read user page (c011de) - exploit attempt? (uid: 0)
>>> BUG: Unable to handle kernel data access on read at 0x00c011de
>>> Faulting instruction address: 0xe1e3dc44
>>> Oops: Kernel access of bad area, sig: 11 [#1]
>>> BE PAGE_SIZE=4K SMP NR_CPUS=4 CoreNet Generic
>>> Modules linked in: ...
>>> CPU: 1 PID: 0 Comm: swapper/1 Tainted: G O 6.6.73 #0
>>> Hardware name: CyBoxAP-A e5500 0x80241021 CoreNet Generic
>>> NIP: e1e3dc44 LR: e1e3dc30 CTR: c08d40e0
>>> REGS: dffe3ce0 TRAP: 0300 Tainted: G O (6.6.73)
>>> MSR: 00029002 <CE,EE,ME> CR: 44004402 XER: 00000000
>>> DEAR: 00c011de ESR: 00000000
>>> GPR00: e1e33154 dffe3dd0 c1870000 00000000 cebe0000 00000000 00000000 00c011ce
>>> GPR08: 00000001 00000000 00020000 c30a294c c08d40e0 00000000 00000001 00000000
>>> GPR16: e1ce2668 c9270000 c9269a18 c92664d0 e1ce26dc 00000000 babababa dffe3df4
>>> GPR24: 00000040 00000000 c9266480 dffe3dec dffe3e04 c9260000 00c011ce c9269a18
>>> NIP [e1e3dc44] ath12k_dp_rx_process_wbm_err+0x124/0x600 [ath12k]
>>> LR [e1e3dc30] ath12k_dp_rx_process_wbm_err+0x110/0x600 [ath12k]
>>> Call Trace:
>>> [dffe3dd0] [c0ab8e30] 0xc0ab8e30 (unreliable)
>>> [dffe3e80] [e1e33154] ath12k_dp_service_srng+0x314/0x380 [ath12k]
>>> [dffe3ed0] [e1e44540] ath12k_pci_hif_resume+0x520/0x8a0 [ath12k]
>>> [dffe3f00] [c0674c7c] __napi_poll+0x4c/0x260
>>> [dffe3f30] [c0675328] net_rx_action+0x188/0x340
>>> [dffe3fa0] [c003a3d8] handle_softirqs+0x128/0x280
>>> [dffe3ff0] [c00045b0] do_softirq_own_stack+0x30/0x50
>>> [c18c7e10] [c12b040c] 0xc12b040c
>>> [c18c7e30] [c003a7d0] irq_exit+0x70/0xa0
>>> [c18c7e40] [c0000c84] ExternalInput+0x144/0x160
>>> --- interrupt: 500 at arch_cpu_idle+0x24/0x50
>>> NIP: c00071f4 LR: c00071f4 CTR: c000fe14
>>> REGS: c18c7e50 TRAP: 0500 Tainted: G O (6.6.73)
>>> MSR: 0002b002 <CE,EE,FP,ME> CR: 84000402 XER: 00000000
>>>
>>> GPR00: c08cc978 c18c7f40 c1870000 00000005 00000001 40000000 c328becc c12b0530
>>> GPR08: c12b0530 c000fe14 0098ca91 00154674 24000402 00000000 00000001 00000000
>>> GPR16: 00000000 00000000 c00119a0 dffee5f0 00000001 00000000 ffffffff c1050254
>>> GPR24: c12c0000 c0011970 c0011940 c12d0000 00000004 c12b040c c12b0000 00000001
>>> NIP [c00071f4] arch_cpu_idle+0x24/0x50
>>> LR [c00071f4] arch_cpu_idle+0x24/0x50
>>> --- interrupt: 500
>>> [c18c7f40] [c0a367e0] 0xc0a367e0 (unreliable)
>>> [c18c7f50] [c08cc978] default_idle_call+0x38/0x58
>>> [c18c7f60] [c007b3b0] do_idle+0xf0/0x130
>>> [c18c7f80] [c007b580] cpu_startup_entry+0x30/0x40
>>> [c18c7fa0] [c001325c] start_secondary+0x48c/0x930
>>> [c18c7ff0] [c0002870] __secondary_start+0x90/0xdc
>>> Code: 7fa3eb78 4bfcba59 7c641b79 41c20144 38a10044 7fa3eb78 4bfcdb85 7c651b79 40c2026c 83c10058 2c1e0000 41c202d0 <813e0010> 7c09b000 41c20010 7e84a378
>>> ---[ end trace 0000000000000000 ]---
>>>
>>> Kernel panic - not syncing: Fatal exception
>>> ---[ end Kernel panic - not syncing: Fatal exception ]---
>>>
>>>
>>> My fix, as shown in the patch below, is to remove the conversion. But then the
>>> member variables `buf_va_lo` and `buf_va_hi` must be `u32`, which is obviously
>>> wrong. Alternatively, `desc_va` must be `__le64`, but that is likely also
>>> incorrect, because the address is simply dereferenced, and this clearly requires
>>> CPU endianness. What I also do not fully understand is who actually fills these
>>> addresses and at which stage this happens. I hope you can help clarify this so
>>> that I can provide a correct patch for this issue afterward.
>>>
>>>
>>
>> hmm, i am not sure here, but can you please try
>>
>> diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c
>> index 1c82d927d27b..f142759a217b 100644
>> --- a/drivers/net/wireless/ath/ath12k/dp.c
>> +++ b/drivers/net/wireless/ath/ath12k/dp.c
>> @@ -1246,7 +1246,7 @@ static int ath12k_dp_cc_desc_init(struct ath12k_base *ab)
>>
>> /* Update descriptor VA in SPT */
>> rx_desc_addr = ath12k_dp_cc_get_desc_addr_ptr(dp, ppt_idx, j);
>> - *rx_desc_addr = &rx_descs[j];
>> + *rx_desc_addr = (struct ath12k_rx_desc_info
>> *)cpu_to_le64(&rx_descs[j]);
>> }
>> }
>>
>> @@ -1286,7 +1286,7 @@ static int ath12k_dp_cc_desc_init(struct ath12k_base *ab)
>> /* Update descriptor VA in SPT */
>> tx_desc_addr =
>> ath12k_dp_cc_get_desc_addr_ptr(dp, ppt_idx, j);
>> - *tx_desc_addr = &tx_descs[j];
>> + *tx_desc_addr = (struct ath12k_tx_desc_info
>> *)cpu_to_le64(&tx_descs[j]);
>> }
>> }
>> spin_unlock_bh(&dp->tx_desc_lock[pool_id]);
>>
>
> Hi Baochen,
>
> It actually worked, although the solution isn't entirely clean. Sparse
> consequently complains with:
>
> dp.c:1249:42: warning: cast from restricted __le64
> dp.c:1289:50: warning: cast from restricted __le64
>
> To be honest, I also don't quite understand why the struct pointer has to be in
> little endian at this point. The function `ath12k_dp_cc_get_desc_addr_ptr`
> returns an offset from the `vaddr` inside the `spt_info` struct, stored as a
> `u64`. But dereferencing it suddenly treats it as little endian. Shouldn't
> `vaddr` itself perhaps be a `__le64`?
that piece of memory is for direct access by the target, so yes I think 'vaddr' should be
defined as __le64.
>
>
> Best regards
> Alexander Wilhelm
^ permalink raw reply
* Re: [PATCH v3 1/9] arm64: dts: amlogic: t7: Add eMMC, SD card and SDIO pinctrl nodes
From: Xianwei Zhao @ 2026-03-25 2:48 UTC (permalink / raw)
To: Ronald Claveau, Neil Armstrong, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Ulf Hansson, Johannes Berg, van Spriel
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
linux-mmc, linux-wireless
In-Reply-To: <20260323-add-emmc-t7-vim4-v3-1-5159d90a984c@aliel.fr>
Hi Ronald,
On 2026/3/23 17:55, Ronald Claveau wrote:
> These pinctrl nodes are required by the eMMC, SD card and SDIO drivers
> to configure pin muxing at runtime.
>
> - eMMC: control, 4-bit/8-bit data, data strobe and clock gate pins
> - SD card: data, clock, command and clock gate pins
> - SDIO: data, clock, command and clock gate pins
>
> Signed-off-by: Ronald Claveau<linux-kernel-dev@aliel.fr>
> ---
> arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 98 +++++++++++++++++++++++++++++
> 1 file changed, 98 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> index 6510068bcff92..ac8de8e9b8010 100644
> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> @@ -250,6 +250,104 @@ gpio: bank@4000 {
> #gpio-cells = <2>;
> gpio-ranges = <&periphs_pinctrl 0 0 157>;
> };
> +
> + emmc_ctrl_pins: emmc-ctrl {
> + mux-0 {
> + groups = "emmc_cmd";
> + function = "emmc";
> + bias-pull-up;
> + };
> +
> + mux-1 {
> + groups = "emmc_clk";
> + function = "emmc";
> + bias-disable;
> + };
> + };
> +
> + emmc_data_4b_pins: emmc-data-4b {
> + mux-0 {
> + groups = "emmc_nand_d0",
> + "emmc_nand_d1",
> + "emmc_nand_d2",
> + "emmc_nand_d3";
> + function = "emmc";
> + bias-pull-up;
> + };
> + };
> +
> + emmc_data_8b_pins: emmc-data-8b {
> + mux-0 {
> + groups = "emmc_nand_d0",
> + "emmc_nand_d1",
> + "emmc_nand_d2",
> + "emmc_nand_d3",
> + "emmc_nand_d4",
> + "emmc_nand_d5",
> + "emmc_nand_d6",
> + "emmc_nand_d7";
> + function = "emmc";
> + bias-pull-up;
> + };
> + };
> +
> + emmc_ds_pins: emmc-ds {
> + mux {
> + groups = "emmc_nand_ds";
> + function = "emmc";
> + bias-pull-down;
> + };
> + };
> +
> + emmc_clk_gate_pins: emmc_clk_gate {
Node names should use hyphens ('-') instead of underscores ('_'),
consistent with the following nodes.
> + mux {
> + groups = "GPIOB_8";
> + function = "gpio_periphs";
> + bias-pull-down;
> + };
> + };
> +
> + sdcard_pins: sdcard {
> + mux {
> + groups = "sdcard_d0",
> + "sdcard_d1",
> + "sdcard_d2",
> + "sdcard_d3",
> + "sdcard_clk",
> + "sdcard_cmd";
> + function = "sdcard";
> + bias-pull-up;
> + };
> + };
> +
> + sdcard_clk_gate_pins: sdcard_clk_gate {
> + mux {
> + groups = "GPIOC_4";
> + function = "gpio_periphs";
> + bias-pull-down;
> + };
> + };
> +
> + sdio_pins: sdio {
> + mux-0 {
> + groups = "sdio_d0",
> + "sdio_d1",
> + "sdio_d2",
> + "sdio_d3",
> + "sdio_clk",
> + "sdio_cmd";
> + function = "sdio";
> + bias-pull-up;
> + };
> + };
> +
> + sdio_clk_gate_pins: sdio_clk_gate {
> + mux {
> + groups = "GPIOX_4";
> + function = "gpio_periphs";
> + bias-pull-up;
> + };
> + };
> };
>
> gpio_intc: interrupt-controller@4080 {
^ permalink raw reply
* [PATCH ath-current] wifi: ath10k: fix station lookup failure during disconnect
From: Baochen Qiang @ 2026-03-25 3:05 UTC (permalink / raw)
To: Jeff Johnson; +Cc: linux-wireless, ath10k, pmenzel, Baochen Qiang
Recent commit [1] moved station statistics collection to an earlier stage
of the disconnect flow. With this change in place, ath10k fails to resolve
the station entry when handling a peer stats event triggered during
disconnect, resulting in log messages such as:
wlp58s0: deauthenticating from 74:1a:e0:e7:b4:c8 by local choice (Reason: 3=DEAUTH_LEAVING)
ath10k_pci 0000:3a:00.0: not found station for peer stats
ath10k_pci 0000:3a:00.0: failed to parse stats info tlv: -22
The failure occurs because ath10k relies on ieee80211_find_sta_by_ifaddr()
for station lookup. That function uses local->sta_hash, but by the time
the peer stats request is triggered during disconnect, mac80211 has
already removed the station from that hash table, leading to lookup
failure.
Before commit [1], this issue was not visible because the transition from
IEEE80211_STA_NONE to IEEE80211_STA_NOTEXIST prevented ath10k from sending
a peer stats request at all: ath10k_mac_sta_get_peer_stats_info() would
fail early to find the peer and skip requesting statistics.
Fix this by switching the lookup path to ath10k_peer_find(), which queries
ath10k's internal peer table. At the point where the firmware emits the
peer stats event, the peer entry is still present in the driver's list,
ensuring lookup succeeds.
Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00309-QCARMSWPZ-1
Fixes: a203dbeeca15 ("wifi: mac80211: collect station statistics earlier when disconnect") # [1]
Reported-by: Paul Menzel <pmenzel@molgen.mpg.de>
Closes: https://lore.kernel.org/ath10k/57671b89-ec9f-4e6c-992c-45eb8e75929c@molgen.mpg.de
Signed-off-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath10k/wmi-tlv.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index ec8e91707f84..01f2d1fa9d7d 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -3,7 +3,7 @@
* Copyright (c) 2005-2011 Atheros Communications Inc.
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
- * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include "core.h"
#include "debug.h"
@@ -14,6 +14,7 @@
#include "wmi-tlv.h"
#include "p2p.h"
#include "testmode.h"
+#include "txrx.h"
#include <linux/bitfield.h>
/***************/
@@ -224,8 +225,9 @@ static int ath10k_wmi_tlv_parse_peer_stats_info(struct ath10k *ar, u16 tag, u16
const void *ptr, void *data)
{
const struct wmi_tlv_peer_stats_info *stat = ptr;
- struct ieee80211_sta *sta;
+ u32 vdev_id = *(u32 *)data;
struct ath10k_sta *arsta;
+ struct ath10k_peer *peer;
if (tag != WMI_TLV_TAG_STRUCT_PEER_STATS_INFO)
return -EPROTO;
@@ -241,20 +243,20 @@ static int ath10k_wmi_tlv_parse_peer_stats_info(struct ath10k *ar, u16 tag, u16
__le32_to_cpu(stat->last_tx_rate_code),
__le32_to_cpu(stat->last_tx_bitrate_kbps));
- rcu_read_lock();
- sta = ieee80211_find_sta_by_ifaddr(ar->hw, stat->peer_macaddr.addr, NULL);
- if (!sta) {
- rcu_read_unlock();
- ath10k_warn(ar, "not found station for peer stats\n");
+ guard(spinlock_bh)(&ar->data_lock);
+
+ peer = ath10k_peer_find(ar, vdev_id, stat->peer_macaddr.addr);
+ if (!peer || !peer->sta) {
+ ath10k_warn(ar, "not found %s with vdev id %u mac addr %pM for peer stats\n",
+ peer ? "sta" : "peer", vdev_id, stat->peer_macaddr.addr);
return -EINVAL;
}
- arsta = (struct ath10k_sta *)sta->drv_priv;
+ arsta = (struct ath10k_sta *)peer->sta->drv_priv;
arsta->rx_rate_code = __le32_to_cpu(stat->last_rx_rate_code);
arsta->rx_bitrate_kbps = __le32_to_cpu(stat->last_rx_bitrate_kbps);
arsta->tx_rate_code = __le32_to_cpu(stat->last_tx_rate_code);
arsta->tx_bitrate_kbps = __le32_to_cpu(stat->last_tx_bitrate_kbps);
- rcu_read_unlock();
return 0;
}
@@ -266,6 +268,7 @@ static int ath10k_wmi_tlv_op_pull_peer_stats_info(struct ath10k *ar,
const struct wmi_tlv_peer_stats_info_ev *ev;
const void *data;
u32 num_peer_stats;
+ u32 vdev_id;
int ret;
tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
@@ -284,15 +287,16 @@ static int ath10k_wmi_tlv_op_pull_peer_stats_info(struct ath10k *ar,
}
num_peer_stats = __le32_to_cpu(ev->num_peers);
+ vdev_id = __le32_to_cpu(ev->vdev_id);
ath10k_dbg(ar, ATH10K_DBG_WMI,
"wmi tlv peer stats info update peer vdev id %d peers %i more data %d\n",
- __le32_to_cpu(ev->vdev_id),
+ vdev_id,
num_peer_stats,
__le32_to_cpu(ev->more_data));
ret = ath10k_wmi_tlv_iter(ar, data, ath10k_wmi_tlv_len(data),
- ath10k_wmi_tlv_parse_peer_stats_info, NULL);
+ ath10k_wmi_tlv_parse_peer_stats_info, &vdev_id);
if (ret)
ath10k_warn(ar, "failed to parse stats info tlv: %d\n", ret);
---
base-commit: 4242625f272974dd1947f73b10d884eab3b277cd
change-id: 20260325-ath10k-station-lookup-failure-be4dd6e81100
Best regards,
--
Baochen Qiang <baochen.qiang@oss.qualcomm.com>
^ permalink raw reply related
* Re: [PATCH net-next v3 03/13] net: introduce ndo_set_rx_mode_async and dev_rx_mode_work
From: Jakub Kicinski @ 2026-03-25 3:44 UTC (permalink / raw)
To: Stanislav Fomichev
Cc: Stanislav Fomichev, netdev, davem, edumazet, pabeni, horms,
corbet, skhan, andrew+netdev, michael.chan, pavan.chebbi,
anthony.l.nguyen, przemyslaw.kitszel, saeedm, tariqt, mbloch,
alexanderduyck, kernel-team, johannes, sd, jianbol, dtatulea,
mohsin.bashr, jacob.e.keller, willemb, skhawaja, bestswngs,
aleksandr.loktionov, kees, linux-doc, linux-kernel,
intel-wired-lan, linux-rdma, linux-wireless, linux-kselftest,
leon
In-Reply-To: <acMU93XN02PHmAGi@mini-arch>
On Tue, 24 Mar 2026 15:49:27 -0700 Stanislav Fomichev wrote:
> > > Not sure why cancel+release, maybe you're thinking about the unregister
> > > path? This is rtnl_unlock -> netdev_run_todo -> __rtnl_unlock + some
> > > extras.
> > >
> > > And the flush is here to plumb the addresses to the real devices
> > > before we return to the callers. Mostly because of the following
> > > things we have in the tests:
> > >
> > > # TEST: team cleanup mode lacp [FAIL]
> > > # macvlan unicast address not found on a slave
> > >
> > > Can you explain a bit more on the suggestion?
> >
> > Oh, I thought it's here for unregister! Feels like it'd be cleaner to
> > add the flush in dev_*c_add() and friends? How hard would it be to
> > identify the callers in atomic context?
>
> Not sure we can do it in dev_xc_add because it runs under rtnl :-(
> I currently do flush in netdev_run_todo because that's the place that
> doesn't hold rtnl. Otherwise flush will get stuck because the work
> handler grabs it...
I was thinking of something a'la linkwatch. We can "steal" / "flush"
the pending work inline. I guess linkwatch is a major source of races
over the years...
Does the macvlan + team problem still happens with the current
implementation minus the flush? We are only flushing once so only
pushing the addresses thru one layer of async callbacks.
^ permalink raw reply
* Re: [PATCH 1/4] wifi: mac80211: factor out part of ieee80211_calc_expected_tx_airtime
From: Felix Fietkau @ 2026-03-25 3:58 UTC (permalink / raw)
To: Pablo MARTIN-GOMEZ, linux-wireless; +Cc: johannes
In-Reply-To: <900aa78e-b0ca-43de-adae-4053bde4d328@freebox.fr>
On 23.03.26 17:00, Pablo MARTIN-GOMEZ wrote:
> Hello,
>
> On 23/03/2026 11:19, Felix Fietkau wrote:
>> Create ieee80211_rate_expected_tx_airtime helper function, which returns
>> the expected tx airtime for a given rate and packet length in units of
>> 1024 usec, for more accuracy.
>>
>> Signed-off-by: Felix Fietkau <nbd@nbd.name>
>> ---
>> net/mac80211/airtime.c | 87 ++++++++++++++++++++++----------------
>> net/mac80211/ieee80211_i.h | 5 +++
>> 2 files changed, 56 insertions(+), 36 deletions(-)
>>
>> diff --git a/net/mac80211/airtime.c b/net/mac80211/airtime.c
>> index c61df637232a..0c54cdbd753c 100644
>> --- a/net/mac80211/airtime.c
>> +++ b/net/mac80211/airtime.c
>> @@ -685,7 +685,7 @@ static int ieee80211_fill_rx_status(struct ieee80211_rx_status *stat,
>> if (ieee80211_fill_rate_info(hw, stat, band, ri))
>> return 0;
>>
>> - if (!ieee80211_rate_valid(rate))
>> + if (!rate || !ieee80211_rate_valid(rate))
>> return -1;
>>
>> if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
>> @@ -753,6 +753,53 @@ u32 ieee80211_calc_tx_airtime(struct ieee80211_hw *hw,
>> }
>> EXPORT_SYMBOL_GPL(ieee80211_calc_tx_airtime);
>>
>> +u32 ieee80211_rate_expected_tx_airtime(struct ieee80211_hw *hw,
>> + struct ieee80211_tx_rate *tx_rate,
>> + struct rate_info *ri,
>> + enum nl80211_band band,
>> + bool ampdu, int len)
>> +{
>> + struct ieee80211_rx_status stat;
>> + u32 duration, overhead;
>> + u8 agg_shift;
>> +
>> + if (ieee80211_fill_rx_status(&stat, hw, tx_rate, ri, band, len))
>> + return 0;
>> +
>> + if (stat.encoding == RX_ENC_LEGACY || !ampdu)
>> + return ieee80211_calc_rx_airtime(hw, &stat, len) * 1024;
>> +
>> + duration = ieee80211_get_rate_duration(hw, &stat, &overhead);
>> +
>> + /*
>> + * Assume that HT/VHT transmission on any AC except VO will
>> + * use aggregation. Since we don't have reliable reporting
>> + * of aggregation length, assume an average size based on the
>> + * tx rate.
>> + * This will not be very accurate, but much better than simply
>> + * assuming un-aggregated tx in all cases.
>> + */
>> + if (duration > 400 * 1024) /* <= VHT20 MCS2 1S */
>> + agg_shift = 1;
>> + else if (duration > 250 * 1024) /* <= VHT20 MCS3 1S or MCS1 2S */
>> + agg_shift = 2;
>> + else if (duration > 150 * 1024) /* <= VHT20 MCS5 1S or MCS2 2S */
>> + agg_shift = 3;
>> + else if (duration > 70 * 1024) /* <= VHT20 MCS5 2S */
>> + agg_shift = 4;
>> + else if (stat.encoding != RX_ENC_HE ||
>> + duration > 20 * 1024) /* <= HE40 MCS6 2S */
>> + agg_shift = 5;
>> + else
>> + agg_shift = 6;
>> +
>> + duration *= len;
>> + duration /= AVG_PKT_SIZE;
>> + duration += (overhead * 1024 >> agg_shift);
> I know this patch is just a refactoring, but I think this moved code is
> bugged. If (and it's a big if) I understood correctly the chain of
> macros and the comments, `ieee80211_get_rate_duration` return the
> `duration` in 1024 µs of an average packet (which would imply
> 1f38b8c564b8 is wrong) and the (PHY) `overhead` in µs for a (average)
> packet. So I believe the code should be:
> ```c
> duration = ieee80211_get_rate_duration(hw, &stat, &overhead);
> duration *= 1024; /* now duration is in µs */
> /* the agg_shift calculation has to be fixed */
> duration += (overhead >> agg_shift); /* for one packet, we "assign" a
> fraction of the overhead */
> duration *= len/AVG_PKT_SIZE; /* we multiply by the number of packets */
> duration /= 1024; /* we go back to a duration in 1024 µs*/
>
> return duration;
> ```
The overhead (preamble, signal field, etc.) is a fixed per-frame PHY
cost that doesn't depend on how many data bytes are in the frame. In the
aggregated case, agg_shift amortizes that fixed cost across the
estimated number of subframes in the aggregate. So the correct order is:
scale the data duration to the actual packet size, then add the
amortized overhead once.
This is the same pattern used in ieee80211_calc_rx_airtime:
duration *= len;
duration /= AVG_PKT_SIZE;
duration /= 1024;
return duration + overhead;
Your proposed rewrite would multiply the overhead by len / AVG_PKT_SIZE,
making it proportional to packet size, which is incorrect, because a
512-byte frame and a 1500-byte frame have the same PHY preamble duration.
- Felix
^ permalink raw reply
* [PATCH] wifi: mt76: mt7996: disable UNI_BSS_INFO_PROTECT_INFO for mt7996
From: Ryder Lee @ 2026-03-25 3:59 UTC (permalink / raw)
To: Felix Fietkau; +Cc: linux-mediatek, linux-wireless, Shayne Chen, Ryder Lee
There are known firmware issues with MT7996, so it is temporarily
disabled. MT7992 and MT7990 are working normally.
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
---
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
index 16420375112d..bdc40e94127c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -1281,6 +1281,9 @@ int mt7996_mcu_set_protection(struct mt7996_phy *phy, struct mt7996_vif_link *li
PROT_NONGF_STA = BIT(7),
};
+ if (is_mt7996(&dev->mt76))
+ return 0;
+
skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &link->mt76,
MT7996_BSS_UPDATE_MAX_SIZE);
if (IS_ERR(skb))
--
2.45.2
^ permalink raw reply related
* [PATCH 1/3] wifi: mt76: connac: use a helper to cache txpower_cur
From: Sean Wang @ 2026-03-25 4:33 UTC (permalink / raw)
To: nbd, lorenzo.bianconi; +Cc: linux-wireless, linux-mediatek, Sean Wang
From: Sean Wang <sean.wang@mediatek.com>
The cached txpower value is derived from the bounded channel power after
applying the chainmask path delta.
Use a helper for that conversion so callers do not open-code it.
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
drivers/net/wireless/mediatek/mt76/mt76_connac.h | 2 +-
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c | 9 +++++++++
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 11 ++++++++---
3 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
index 51423c7740bd..d0953e02810b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
@@ -420,7 +420,7 @@ mt76_connac_mutex_release(struct mt76_dev *dev, struct mt76_connac_pm *pm)
void mt76_connac_gen_ppe_thresh(u8 *he_ppet, int nss, enum nl80211_band band);
int mt76_connac_init_tx_queues(struct mt76_phy *phy, int idx, int n_desc,
int ring_base, void *wed, u32 flags);
-
+void mt76_connac_set_txpower_cur(struct mt76_phy *phy, s8 max_power);
void mt76_connac_write_hw_txp(struct mt76_dev *dev,
struct mt76_tx_info *tx_info,
void *txp_ptr, u32 id);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
index 0339e2e7ab60..b2daa6c7d061 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c
@@ -275,6 +275,15 @@ int mt76_connac_init_tx_queues(struct mt76_phy *phy, int idx, int n_desc,
}
EXPORT_SYMBOL_GPL(mt76_connac_init_tx_queues);
+void mt76_connac_set_txpower_cur(struct mt76_phy *phy, s8 max_power)
+{
+ int delta;
+
+ delta = mt76_tx_power_path_delta(hweight16(phy->chainmask));
+ phy->txpower_cur = max_power - delta;
+}
+EXPORT_SYMBOL_GPL(mt76_connac_set_txpower_cur);
+
#define __bitrate_mask_check(_mcs, _mode) \
({ \
u8 i = 0; \
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index 89bd52ea8bf7..897b065a2be6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -2223,14 +2223,19 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
.hw_value = ch_list[idx],
.band = band,
};
- s8 reg_power, sar_power;
+ s8 reg_power, sar_power, max_power;
reg_power = mt76_connac_get_ch_power(phy, &chan,
tx_power);
sar_power = mt76_get_sar_power(phy, &chan, reg_power);
- mt76_get_rate_power_limits(phy, &chan, limits,
- sar_power);
+ max_power = mt76_get_rate_power_limits(phy, &chan, limits,
+ sar_power);
+
+ if (phy->chandef.chan &&
+ phy->chandef.chan->hw_value == ch_list[idx] &&
+ phy->chandef.chan->band == band)
+ mt76_connac_set_txpower_cur(phy, max_power);
tx_power_tlv.last_msg = ch_list[idx] == last_ch;
sku_tlbv.channel = ch_list[idx];
--
2.43.0
^ permalink raw reply related
* [PATCH 2/3] wifi: mt76: connac: factor out rate power limit calculation
From: Sean Wang @ 2026-03-25 4:33 UTC (permalink / raw)
To: nbd, lorenzo.bianconi; +Cc: linux-wireless, linux-mediatek, Sean Wang
In-Reply-To: <20260325043318.13298-1-sean.wang@kernel.org>
From: Sean Wang <sean.wang@mediatek.com>
Factor out the per-channel rate power limit calculation into a shared
helper.
This avoids duplicating the same regulatory, SAR and rate-limit logic in
multiple paths.
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
.../net/wireless/mediatek/mt76/mt76_connac.h | 3 ++
.../wireless/mediatek/mt76/mt76_connac_mcu.c | 28 +++++++++++++------
2 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
index d0953e02810b..1549a97873ee 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
@@ -421,6 +421,9 @@ void mt76_connac_gen_ppe_thresh(u8 *he_ppet, int nss, enum nl80211_band band);
int mt76_connac_init_tx_queues(struct mt76_phy *phy, int idx, int n_desc,
int ring_base, void *wed, u32 flags);
void mt76_connac_set_txpower_cur(struct mt76_phy *phy, s8 max_power);
+s8 mt76_connac_get_rate_power_limit(struct mt76_phy *phy,
+ struct ieee80211_channel *chan,
+ struct mt76_power_limits *limits);
void mt76_connac_write_hw_txp(struct mt76_dev *dev,
struct mt76_tx_info *tx_info,
void *txp_ptr, u32 id);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index 897b065a2be6..1117a22c70ac 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -2223,15 +2223,10 @@ mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
.hw_value = ch_list[idx],
.band = band,
};
- s8 reg_power, sar_power, max_power;
-
- reg_power = mt76_connac_get_ch_power(phy, &chan,
- tx_power);
- sar_power = mt76_get_sar_power(phy, &chan, reg_power);
-
- max_power = mt76_get_rate_power_limits(phy, &chan, limits,
- sar_power);
+ s8 max_power;
+ max_power = mt76_connac_get_rate_power_limit(phy, &chan,
+ limits);
if (phy->chandef.chan &&
phy->chandef.chan->hw_value == ch_list[idx] &&
phy->chandef.chan->band == band)
@@ -2967,6 +2962,23 @@ int mt76_connac_mcu_rdd_cmd(struct mt76_dev *dev, int cmd, u8 index,
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_rdd_cmd);
+s8 mt76_connac_get_rate_power_limit(struct mt76_phy *phy,
+ struct ieee80211_channel *chan,
+ struct mt76_power_limits *limits)
+{
+ s8 reg_power, sar_power;
+ int tx_power;
+
+ tx_power = 2 * phy->hw->conf.power_level;
+ if (!tx_power)
+ tx_power = 127;
+
+ reg_power = mt76_connac_get_ch_power(phy, chan, tx_power);
+ sar_power = mt76_get_sar_power(phy, chan, reg_power);
+ return mt76_get_rate_power_limits(phy, chan, limits, sar_power);
+}
+EXPORT_SYMBOL_GPL(mt76_connac_get_rate_power_limit);
+
static int
mt76_connac_mcu_send_ram_firmware(struct mt76_dev *dev,
const struct mt76_connac2_fw_trailer *hdr,
--
2.43.0
^ permalink raw reply related
* [PATCH 3/3] wifi: mt76: mt792x: report txpower for the requested vif link
From: Sean Wang @ 2026-03-25 4:33 UTC (permalink / raw)
To: nbd, lorenzo.bianconi; +Cc: linux-wireless, linux-mediatek, Sean Wang
In-Reply-To: <20260325043318.13298-1-sean.wang@kernel.org>
From: Sean Wang <sean.wang@mediatek.com>
mt792x currently reports txpower from the generic PHY cached state,
which may not match the requested vif/link context.
Resolve the requested link channel and derive txpower from that channel
instead, with fallback to the current PHY chandef if no valid chanctx is
available.
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
---
.../net/wireless/mediatek/mt76/mt7921/main.c | 2 +-
.../net/wireless/mediatek/mt76/mt7925/main.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt792x.h | 2 +
.../net/wireless/mediatek/mt76/mt792x_core.c | 41 +++++++++++++++++++
4 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
index 3d74fabe7408..2e7cdf8edc12 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
@@ -1552,7 +1552,7 @@ const struct ieee80211_ops mt7921_ops = {
.wake_tx_queue = mt76_wake_tx_queue,
.release_buffered_frames = mt76_release_buffered_frames,
.channel_switch_beacon = mt7921_channel_switch_beacon,
- .get_txpower = mt76_get_txpower,
+ .get_txpower = mt792x_get_txpower,
.get_stats = mt792x_get_stats,
.get_et_sset_count = mt792x_get_et_sset_count,
.get_et_strings = mt792x_get_et_strings,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
index 73d3722739d0..53e1a93c6976 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
@@ -2433,7 +2433,7 @@ const struct ieee80211_ops mt7925_ops = {
.wake_tx_queue = mt76_wake_tx_queue,
.release_buffered_frames = mt76_release_buffered_frames,
.channel_switch_beacon = mt7925_channel_switch_beacon,
- .get_txpower = mt76_get_txpower,
+ .get_txpower = mt792x_get_txpower,
.get_stats = mt792x_get_stats,
.get_et_sset_count = mt792x_get_et_sset_count,
.get_et_strings = mt792x_get_et_strings,
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h
index 4ff93f2cd624..65eba18bc3a1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x.h
+++ b/drivers/net/wireless/mediatek/mt76/mt792x.h
@@ -397,6 +397,8 @@ void mt792x_roc_timer(struct timer_list *timer);
void mt792x_csa_timer(struct timer_list *timer);
void mt792x_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u32 queues, bool drop);
+int mt792x_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ unsigned int link_id, int *dbm);
int mt792x_assign_vif_chanctx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf,
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net/wireless/mediatek/mt76/mt792x_core.c
index 152cfcca2f90..3fd1be7db1f4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c
@@ -329,6 +329,47 @@ void mt792x_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
}
EXPORT_SYMBOL_GPL(mt792x_flush);
+int mt792x_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ unsigned int link_id, int *dbm)
+{
+ struct mt76_power_limits limits = {};
+ struct ieee80211_bss_conf *link_conf;
+ struct ieee80211_channel *chan;
+ struct mt792x_bss_conf *mconf;
+ struct mt792x_vif *mvif;
+ struct mt76_phy *phy;
+ s8 max_power;
+
+ if (!vif)
+ return mt76_get_txpower(hw, vif, link_id, dbm);
+
+ mvif = (struct mt792x_vif *)vif->drv_priv;
+ phy = mvif->phy->mt76;
+
+ mt792x_mutex_acquire(mvif->phy->dev);
+
+ link_conf = mt792x_vif_to_bss_conf(vif, link_id);
+ mconf = link_conf ? mt792x_link_conf_to_mconf(link_conf) : NULL;
+ if (mconf && mconf->mt76.ctx && mconf->mt76.ctx->def.chan)
+ chan = mconf->mt76.ctx->def.chan;
+ else
+ /* Fall back to the current PHY chandef if the requested link
+ * does not have a valid channel context.
+ */
+ chan = phy->chandef.chan;
+
+ mt792x_mutex_release(mvif->phy->dev);
+
+ if (!chan)
+ return -EINVAL;
+
+ max_power = mt76_connac_get_rate_power_limit(phy, chan, &limits);
+ *dbm = DIV_ROUND_UP(max_power, 2);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mt792x_get_txpower);
+
int mt792x_assign_vif_chanctx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf,
--
2.43.0
^ permalink raw reply related
* Re: [PATCH 10/14] drm/msm: Switch to generic PAS TZ APIs
From: Dmitry Baryshkov @ 2026-03-25 4:34 UTC (permalink / raw)
To: Sumit Garg
Cc: linux-arm-msm, devicetree, dri-devel, freedreno, linux-media,
netdev, linux-wireless, ath12k, linux-remoteproc, andersson,
konradybcio, robh, krzk+dt, conor+dt, robin.clark, sean, akhilpo,
lumag, abhinav.kumar, jesszhan0024, marijn.suijten, airlied,
simona, vikash.garodia, dikshita.agarwal, bod, mchehab, elder,
andrew+netdev, davem, edumazet, kuba, pabeni, jjohnson,
mathieu.poirier, trilokkumar.soni, mukesh.ojha, pavan.kondeti,
jorge.ramirez, tonyh, vignesh.viswanathan, srinivas.kandagatla,
amirreza.zarrabi, jens.wiklander, op-tee, apurupa, skare,
Sumit Garg
In-Reply-To: <20260306105027.290375-11-sumit.garg@kernel.org>
On Fri, Mar 06, 2026 at 04:20:23PM +0530, Sumit Garg wrote:
> From: Sumit Garg <sumit.garg@oss.qualcomm.com>
>
> Switch drm/msm client drivers over to generic PAS TZ APIs. Generic PAS
> TZ service allows to support multiple TZ implementation backends like QTEE
> based SCM PAS service, OP-TEE based PAS service and any further future TZ
> backend service.
>
> Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
> ---
> drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 4 ++--
> drivers/gpu/drm/msm/adreno/adreno_gpu.c | 11 ++++++-----
> 2 files changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> index ef9fd6171af7..3283852f9a14 100644
> --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
> @@ -5,7 +5,7 @@
> #include <linux/kernel.h>
> #include <linux/types.h>
> #include <linux/cpumask.h>
> -#include <linux/firmware/qcom/qcom_scm.h>
> +#include <linux/firmware/qcom/qcom_pas.h>
Missing `select QCOM_PAS`.
> #include <linux/pm_opp.h>
> #include <linux/nvmem-consumer.h>
> #include <linux/slab.h>
> @@ -653,7 +653,7 @@ static int a5xx_zap_shader_resume(struct msm_gpu *gpu)
> if (adreno_is_a506(adreno_gpu))
> return 0;
>
> - ret = qcom_scm_set_remote_state(SCM_GPU_ZAP_SHADER_RESUME, GPU_PAS_ID);
> + ret = qcom_pas_set_remote_state(SCM_GPU_ZAP_SHADER_RESUME, GPU_PAS_ID);
> if (ret)
> DRM_ERROR("%s: zap-shader resume failed: %d\n",
> gpu->name, ret);
--
With best wishes
Dmitry
^ permalink raw reply
* [wireless-next:main] BUILD SUCCESS 7109310c5031075ecb9b5da75b1443557c232dcd
From: kernel test robot @ 2026-03-25 7:10 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git main
branch HEAD: 7109310c5031075ecb9b5da75b1443557c232dcd Merge tag 'mt76-next-2026-03-23' of https://github.com/nbd168/wireless
elapsed time: 756m
configs tested: 175
configs skipped: 2
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-15.2.0
alpha allyesconfig gcc-15.2.0
alpha defconfig gcc-15.2.0
arc allmodconfig clang-16
arc allnoconfig gcc-15.2.0
arc allyesconfig clang-23
arc defconfig gcc-15.2.0
arc randconfig-001-20260325 gcc-8.5.0
arc randconfig-002-20260325 gcc-8.5.0
arm allnoconfig gcc-15.2.0
arm allyesconfig clang-16
arm defconfig gcc-15.2.0
arm omap1_defconfig gcc-15.2.0
arm randconfig-001-20260325 gcc-8.5.0
arm randconfig-002-20260325 gcc-8.5.0
arm randconfig-003-20260325 gcc-8.5.0
arm randconfig-004-20260325 gcc-8.5.0
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-15.2.0
arm64 defconfig gcc-15.2.0
arm64 randconfig-001-20260325 clang-23
arm64 randconfig-002-20260325 clang-23
arm64 randconfig-003-20260325 clang-23
arm64 randconfig-004-20260325 clang-23
csky allmodconfig gcc-15.2.0
csky allnoconfig gcc-15.2.0
csky defconfig gcc-15.2.0
csky randconfig-001-20260325 clang-23
csky randconfig-002-20260325 clang-23
hexagon allmodconfig gcc-15.2.0
hexagon allnoconfig gcc-15.2.0
hexagon defconfig gcc-15.2.0
hexagon randconfig-001-20260325 gcc-11.5.0
hexagon randconfig-002-20260325 gcc-11.5.0
i386 allmodconfig clang-20
i386 allnoconfig gcc-15.2.0
i386 allyesconfig clang-20
i386 buildonly-randconfig-001-20260325 gcc-14
i386 buildonly-randconfig-002-20260325 gcc-14
i386 buildonly-randconfig-003-20260325 gcc-14
i386 buildonly-randconfig-004-20260325 gcc-14
i386 buildonly-randconfig-005-20260325 gcc-14
i386 buildonly-randconfig-006-20260325 gcc-14
i386 defconfig gcc-15.2.0
i386 randconfig-001-20260325 clang-20
i386 randconfig-002-20260325 clang-20
i386 randconfig-003-20260325 clang-20
i386 randconfig-004-20260325 clang-20
i386 randconfig-005-20260325 clang-20
i386 randconfig-006-20260325 clang-20
i386 randconfig-007-20260325 clang-20
i386 randconfig-011-20260325 clang-20
i386 randconfig-012-20260325 clang-20
i386 randconfig-013-20260325 clang-20
i386 randconfig-014-20260325 clang-20
i386 randconfig-015-20260325 clang-20
i386 randconfig-016-20260325 clang-20
i386 randconfig-017-20260325 clang-20
loongarch allmodconfig clang-23
loongarch allnoconfig gcc-15.2.0
loongarch defconfig clang-19
loongarch randconfig-001-20260325 gcc-11.5.0
loongarch randconfig-002-20260325 gcc-11.5.0
m68k allmodconfig gcc-15.2.0
m68k allnoconfig gcc-15.2.0
m68k allyesconfig clang-16
m68k defconfig clang-19
microblaze allnoconfig gcc-15.2.0
microblaze allyesconfig gcc-15.2.0
microblaze defconfig clang-19
mips allmodconfig gcc-15.2.0
mips allnoconfig gcc-15.2.0
mips allyesconfig gcc-15.2.0
nios2 allmodconfig clang-23
nios2 allmodconfig gcc-11.5.0
nios2 allnoconfig clang-23
nios2 defconfig clang-19
nios2 randconfig-001-20260325 gcc-11.5.0
nios2 randconfig-002-20260325 gcc-11.5.0
openrisc allmodconfig clang-23
openrisc allmodconfig gcc-15.2.0
openrisc allnoconfig clang-23
openrisc defconfig gcc-15.2.0
parisc allmodconfig gcc-15.2.0
parisc allnoconfig clang-23
parisc allyesconfig clang-19
parisc allyesconfig gcc-15.2.0
parisc defconfig gcc-15.2.0
parisc randconfig-001-20260325 clang-23
parisc randconfig-002-20260325 clang-23
parisc64 defconfig clang-19
powerpc allmodconfig gcc-15.2.0
powerpc allnoconfig clang-23
powerpc randconfig-001-20260325 clang-23
powerpc randconfig-002-20260325 clang-23
powerpc taishan_defconfig clang-17
powerpc64 randconfig-001-20260325 clang-23
powerpc64 randconfig-002-20260325 clang-23
riscv allmodconfig clang-23
riscv allnoconfig clang-23
riscv allyesconfig clang-16
riscv defconfig gcc-15.2.0
riscv randconfig-001-20260325 gcc-8.5.0
riscv randconfig-002-20260325 gcc-8.5.0
s390 allmodconfig clang-18
s390 allmodconfig clang-19
s390 allnoconfig clang-23
s390 allyesconfig gcc-15.2.0
s390 defconfig gcc-15.2.0
s390 randconfig-001-20260325 gcc-8.5.0
s390 randconfig-002-20260325 gcc-8.5.0
sh allmodconfig gcc-15.2.0
sh allnoconfig clang-23
sh allyesconfig clang-19
sh allyesconfig gcc-15.2.0
sh defconfig gcc-14
sh randconfig-001-20260325 gcc-8.5.0
sh randconfig-002-20260325 gcc-8.5.0
sparc allnoconfig clang-23
sparc defconfig gcc-15.2.0
sparc randconfig-001-20260325 gcc-13
sparc randconfig-002-20260325 gcc-13
sparc64 allmodconfig clang-23
sparc64 defconfig gcc-14
sparc64 randconfig-001-20260325 gcc-13
sparc64 randconfig-002-20260325 gcc-13
um allmodconfig clang-19
um allnoconfig clang-23
um allyesconfig gcc-15.2.0
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001-20260325 gcc-13
um randconfig-002-20260325 gcc-13
um x86_64_defconfig gcc-14
x86_64 allmodconfig clang-20
x86_64 allnoconfig clang-23
x86_64 allyesconfig clang-20
x86_64 buildonly-randconfig-001-20260325 gcc-14
x86_64 buildonly-randconfig-002-20260325 gcc-14
x86_64 buildonly-randconfig-003-20260325 gcc-14
x86_64 buildonly-randconfig-004-20260325 gcc-14
x86_64 buildonly-randconfig-005-20260325 gcc-14
x86_64 buildonly-randconfig-006-20260325 gcc-14
x86_64 defconfig gcc-14
x86_64 kexec clang-20
x86_64 randconfig-001-20260325 gcc-12
x86_64 randconfig-002-20260325 gcc-12
x86_64 randconfig-003-20260325 gcc-12
x86_64 randconfig-004-20260325 gcc-12
x86_64 randconfig-005-20260325 gcc-12
x86_64 randconfig-006-20260325 gcc-12
x86_64 randconfig-011-20260325 clang-20
x86_64 randconfig-012-20260325 clang-20
x86_64 randconfig-013-20260325 clang-20
x86_64 randconfig-014-20260325 clang-20
x86_64 randconfig-015-20260325 clang-20
x86_64 randconfig-016-20260325 clang-20
x86_64 randconfig-071-20260325 gcc-14
x86_64 randconfig-072-20260325 gcc-14
x86_64 randconfig-073-20260325 gcc-14
x86_64 randconfig-074-20260325 gcc-14
x86_64 randconfig-075-20260325 gcc-14
x86_64 randconfig-076-20260325 gcc-14
x86_64 rhel-9.4 clang-20
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-func clang-20
x86_64 rhel-9.4-kselftests clang-20
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
x86_64 rhel-9.4-rust clang-20
xtensa allnoconfig clang-23
xtensa allyesconfig clang-23
xtensa allyesconfig gcc-15.2.0
xtensa randconfig-001-20260325 gcc-13
xtensa randconfig-002-20260325 gcc-13
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* [wireless:for-next] BUILD SUCCESS 744fabc338e87b95c4d1ff7c95bc8c0f834c6d99
From: kernel test robot @ 2026-03-25 7:20 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git for-next
branch HEAD: 744fabc338e87b95c4d1ff7c95bc8c0f834c6d99 wifi: iwlwifi: mvm: fix potential out-of-bounds read in iwl_mvm_nd_match_info_handler()
elapsed time: 766m
configs tested: 169
configs skipped: 2
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-15.2.0
alpha allyesconfig gcc-15.2.0
alpha defconfig gcc-15.2.0
arc allmodconfig clang-16
arc allnoconfig gcc-15.2.0
arc allyesconfig clang-23
arc defconfig gcc-15.2.0
arc randconfig-001-20260325 gcc-8.5.0
arc randconfig-002-20260325 gcc-8.5.0
arm allnoconfig gcc-15.2.0
arm allyesconfig clang-16
arm defconfig gcc-15.2.0
arm omap1_defconfig gcc-15.2.0
arm randconfig-001-20260325 gcc-8.5.0
arm randconfig-002-20260325 gcc-8.5.0
arm randconfig-003-20260325 gcc-8.5.0
arm randconfig-004-20260325 gcc-8.5.0
arm64 allmodconfig clang-23
arm64 allnoconfig gcc-15.2.0
arm64 defconfig gcc-15.2.0
arm64 randconfig-001-20260325 clang-23
arm64 randconfig-002-20260325 clang-23
arm64 randconfig-003-20260325 clang-23
arm64 randconfig-004-20260325 clang-23
csky allmodconfig gcc-15.2.0
csky allnoconfig gcc-15.2.0
csky defconfig gcc-15.2.0
csky randconfig-001-20260325 clang-23
csky randconfig-002-20260325 clang-23
hexagon allmodconfig gcc-15.2.0
hexagon allnoconfig gcc-15.2.0
hexagon defconfig gcc-15.2.0
hexagon randconfig-001-20260325 gcc-11.5.0
hexagon randconfig-002-20260325 gcc-11.5.0
i386 allmodconfig clang-20
i386 allnoconfig gcc-15.2.0
i386 allyesconfig clang-20
i386 buildonly-randconfig-001-20260325 gcc-14
i386 buildonly-randconfig-002-20260325 gcc-14
i386 buildonly-randconfig-003-20260325 gcc-14
i386 buildonly-randconfig-004-20260325 gcc-14
i386 buildonly-randconfig-005-20260325 gcc-14
i386 buildonly-randconfig-006-20260325 gcc-14
i386 defconfig gcc-15.2.0
i386 randconfig-001-20260325 clang-20
i386 randconfig-002-20260325 clang-20
i386 randconfig-003-20260325 clang-20
i386 randconfig-004-20260325 clang-20
i386 randconfig-005-20260325 clang-20
i386 randconfig-006-20260325 clang-20
i386 randconfig-007-20260325 clang-20
i386 randconfig-011-20260325 clang-20
i386 randconfig-012-20260325 clang-20
i386 randconfig-013-20260325 clang-20
i386 randconfig-014-20260325 clang-20
i386 randconfig-015-20260325 clang-20
i386 randconfig-016-20260325 clang-20
i386 randconfig-017-20260325 clang-20
loongarch allmodconfig clang-23
loongarch allnoconfig gcc-15.2.0
loongarch defconfig clang-19
loongarch randconfig-001-20260325 gcc-11.5.0
loongarch randconfig-002-20260325 gcc-11.5.0
m68k allmodconfig gcc-15.2.0
m68k allnoconfig gcc-15.2.0
m68k allyesconfig clang-16
m68k defconfig clang-19
microblaze allnoconfig gcc-15.2.0
microblaze allyesconfig gcc-15.2.0
microblaze defconfig clang-19
mips allmodconfig gcc-15.2.0
mips allnoconfig gcc-15.2.0
mips allyesconfig gcc-15.2.0
nios2 allmodconfig clang-23
nios2 allnoconfig clang-23
nios2 defconfig clang-19
nios2 randconfig-001-20260325 gcc-11.5.0
nios2 randconfig-002-20260325 gcc-11.5.0
openrisc allmodconfig clang-23
openrisc allnoconfig clang-23
openrisc defconfig gcc-15.2.0
parisc allmodconfig gcc-15.2.0
parisc allnoconfig clang-23
parisc allyesconfig clang-19
parisc defconfig gcc-15.2.0
parisc randconfig-001-20260325 clang-23
parisc randconfig-002-20260325 clang-23
parisc64 defconfig clang-19
powerpc allmodconfig gcc-15.2.0
powerpc allnoconfig clang-23
powerpc randconfig-001-20260325 clang-23
powerpc randconfig-002-20260325 clang-23
powerpc taishan_defconfig clang-17
powerpc64 randconfig-001-20260325 clang-23
powerpc64 randconfig-002-20260325 clang-23
riscv allmodconfig clang-23
riscv allnoconfig clang-23
riscv allyesconfig clang-16
riscv defconfig gcc-15.2.0
riscv randconfig-001-20260325 gcc-8.5.0
riscv randconfig-002-20260325 gcc-8.5.0
s390 allmodconfig clang-19
s390 allnoconfig clang-23
s390 allyesconfig gcc-15.2.0
s390 defconfig gcc-15.2.0
s390 randconfig-001-20260325 gcc-8.5.0
s390 randconfig-002-20260325 gcc-8.5.0
sh allmodconfig gcc-15.2.0
sh allnoconfig clang-23
sh allyesconfig clang-19
sh defconfig gcc-14
sh randconfig-001-20260325 gcc-8.5.0
sh randconfig-002-20260325 gcc-8.5.0
sparc allnoconfig clang-23
sparc defconfig gcc-15.2.0
sparc randconfig-001-20260325 gcc-13
sparc randconfig-002-20260325 gcc-13
sparc64 allmodconfig clang-23
sparc64 defconfig gcc-14
sparc64 randconfig-001-20260325 gcc-13
sparc64 randconfig-002-20260325 gcc-13
um allmodconfig clang-19
um allnoconfig clang-23
um allyesconfig gcc-15.2.0
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001-20260325 gcc-13
um randconfig-002-20260325 gcc-13
um x86_64_defconfig gcc-14
x86_64 allmodconfig clang-20
x86_64 allnoconfig clang-23
x86_64 allyesconfig clang-20
x86_64 buildonly-randconfig-001-20260325 gcc-14
x86_64 buildonly-randconfig-002-20260325 gcc-14
x86_64 buildonly-randconfig-003-20260325 gcc-14
x86_64 buildonly-randconfig-004-20260325 gcc-14
x86_64 buildonly-randconfig-005-20260325 gcc-14
x86_64 buildonly-randconfig-006-20260325 gcc-14
x86_64 defconfig gcc-14
x86_64 kexec clang-20
x86_64 randconfig-001-20260325 gcc-12
x86_64 randconfig-002-20260325 gcc-12
x86_64 randconfig-003-20260325 gcc-12
x86_64 randconfig-004-20260325 gcc-12
x86_64 randconfig-005-20260325 gcc-12
x86_64 randconfig-006-20260325 gcc-12
x86_64 randconfig-011-20260325 clang-20
x86_64 randconfig-012-20260325 clang-20
x86_64 randconfig-013-20260325 clang-20
x86_64 randconfig-014-20260325 clang-20
x86_64 randconfig-015-20260325 clang-20
x86_64 randconfig-016-20260325 clang-20
x86_64 randconfig-071-20260325 gcc-14
x86_64 randconfig-072-20260325 gcc-14
x86_64 randconfig-073-20260325 gcc-14
x86_64 randconfig-074-20260325 gcc-14
x86_64 randconfig-075-20260325 gcc-14
x86_64 randconfig-076-20260325 gcc-14
x86_64 rhel-9.4 clang-20
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-func clang-20
x86_64 rhel-9.4-kselftests clang-20
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
x86_64 rhel-9.4-rust clang-20
xtensa allnoconfig clang-23
xtensa allyesconfig clang-23
xtensa randconfig-001-20260325 gcc-13
xtensa randconfig-002-20260325 gcc-13
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* [PATCH rtw-next 0/8] wifi: rtw89: MAC and PHY changes for RTL8922D and WoWLAN for MLD magic packet
From: Ping-Ke Shih @ 2026-03-25 7:21 UTC (permalink / raw)
To: linux-wireless; +Cc: timlee, echuang, kevin_yang
First two patches are to support WoWLAN MLD magic packet.
The remaining patches are changes related to RTL8922D, including MAC, PHY,
and PCIE settings.
Chin-Yen Lee (2):
wifi: rtw89: wow: use struct style to fill WOW wakeup control H2C
command
wifi: rtw89: wow: enable MLD address for Magic packet wakeup
Eric Huang (1):
wifi: rtw89: phy: expand PHY page for RTL8922D
Ping-Ke Shih (4):
wifi: rtw89: pci: clear SER ISR when initial and leaving WoWLAN for
WiFi 7 chips
wifi: rtw89: mac: add specific case to dump mac memory for RTL8922D
wifi: rtw89: mac: disable pre-load function for RTL8922DE
wifi: rtw89: phy: load RF parameters relying on ACV for RTL8922D
Zong-Zhe Yang (1):
wifi: rtw89: fw: load TX power elements according to AID
drivers/net/wireless/realtek/rtw89/debug.c | 2 +-
drivers/net/wireless/realtek/rtw89/fw.c | 34 ++++++++----
drivers/net/wireless/realtek/rtw89/fw.h | 57 +++++----------------
drivers/net/wireless/realtek/rtw89/mac.c | 4 +-
drivers/net/wireless/realtek/rtw89/mac.h | 16 +++++-
drivers/net/wireless/realtek/rtw89/pci.h | 3 ++
drivers/net/wireless/realtek/rtw89/pci_be.c | 52 ++++++++++++++++---
drivers/net/wireless/realtek/rtw89/phy.c | 15 +++---
drivers/net/wireless/realtek/rtw89/phy_be.c | 2 +-
drivers/net/wireless/realtek/rtw89/ser.c | 2 +-
10 files changed, 113 insertions(+), 74 deletions(-)
base-commit: eef6d4449e8a540fde792968a26d8aa514af8089
--
2.25.1
^ permalink raw reply
* [PATCH rtw-next 1/8] wifi: rtw89: wow: use struct style to fill WOW wakeup control H2C command
From: Ping-Ke Shih @ 2026-03-25 7:21 UTC (permalink / raw)
To: linux-wireless; +Cc: timlee, echuang, kevin_yang
In-Reply-To: <20260325072130.41751-1-pkshih@realtek.com>
From: Chin-Yen Lee <timlee@realtek.com>
The WOW wakeup control command is used to tell firmware the content
of wakeup feature. Use struct instead of macros to fill the data.
Signed-off-by: Chin-Yen Lee <timlee@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/fw.c | 21 ++++++----
drivers/net/wireless/realtek/rtw89/fw.h | 56 ++++++-------------------
2 files changed, 26 insertions(+), 51 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 45d8c5e70084..701cea9a771e 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -9705,38 +9705,43 @@ int rtw89_fw_h2c_wow_global(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtw
return ret;
}
-#define H2C_WAKEUP_CTRL_LEN 4
int rtw89_fw_h2c_wow_wakeup_ctrl(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
bool enable)
{
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
+ struct rtw89_h2c_wow_wakeup_ctrl *h2c;
struct sk_buff *skb;
+ u32 len = sizeof(*h2c);
u8 macid = rtwvif_link->mac_id;
int ret;
- skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, H2C_WAKEUP_CTRL_LEN);
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
rtw89_err(rtwdev, "failed to alloc skb for wakeup ctrl\n");
return -ENOMEM;
}
- skb_put(skb, H2C_WAKEUP_CTRL_LEN);
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_wow_wakeup_ctrl *)skb->data;
if (rtw_wow->pattern_cnt)
- RTW89_SET_WOW_WAKEUP_CTRL_PATTERN_MATCH_ENABLE(skb->data, enable);
+ h2c->w0 |= le32_encode_bits(enable,
+ RTW89_H2C_WOW_WAKEUP_CTRL_W0_PATTERN_MATCH_ENABLE);
if (test_bit(RTW89_WOW_FLAG_EN_MAGIC_PKT, rtw_wow->flags))
- RTW89_SET_WOW_WAKEUP_CTRL_MAGIC_ENABLE(skb->data, enable);
+ h2c->w0 |= le32_encode_bits(enable,
+ RTW89_H2C_WOW_WAKEUP_CTRL_W0_MAGIC_ENABLE);
if (test_bit(RTW89_WOW_FLAG_EN_DISCONNECT, rtw_wow->flags))
- RTW89_SET_WOW_WAKEUP_CTRL_DEAUTH_ENABLE(skb->data, enable);
+ h2c->w0 |= le32_encode_bits(enable,
+ RTW89_H2C_WOW_WAKEUP_CTRL_W0_DEAUTH_ENABLE);
- RTW89_SET_WOW_WAKEUP_CTRL_MAC_ID(skb->data, macid);
+ h2c->w0 |= le32_encode_bits(macid, RTW89_H2C_WOW_WAKEUP_CTRL_W0_MAC_ID);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_MAC,
H2C_CL_MAC_WOW,
H2C_FUNC_WAKEUP_CTRL, 0, 1,
- H2C_WAKEUP_CTRL_LEN);
+ len);
ret = rtw89_h2c_tx(rtwdev, skb, false);
if (ret) {
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index 57e3b464c0a2..cf86fade84a2 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -2219,50 +2219,20 @@ struct rtw89_h2c_cfg_nlo {
#define RTW89_H2C_NLO_W0_IGNORE_CIPHER BIT(2)
#define RTW89_H2C_NLO_W0_MACID GENMASK(31, 24)
-static inline void RTW89_SET_WOW_WAKEUP_CTRL_PATTERN_MATCH_ENABLE(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, BIT(0));
-}
-
-static inline void RTW89_SET_WOW_WAKEUP_CTRL_MAGIC_ENABLE(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, BIT(1));
-}
-
-static inline void RTW89_SET_WOW_WAKEUP_CTRL_HW_UNICAST_ENABLE(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, BIT(2));
-}
-
-static inline void RTW89_SET_WOW_WAKEUP_CTRL_FW_UNICAST_ENABLE(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, BIT(3));
-}
-
-static inline void RTW89_SET_WOW_WAKEUP_CTRL_DEAUTH_ENABLE(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, BIT(4));
-}
-
-static inline void RTW89_SET_WOW_WAKEUP_CTRL_REKEYP_ENABLE(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, BIT(5));
-}
-
-static inline void RTW89_SET_WOW_WAKEUP_CTRL_EAP_ENABLE(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, BIT(6));
-}
-
-static inline void RTW89_SET_WOW_WAKEUP_CTRL_ALL_DATA_ENABLE(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, BIT(7));
-}
+struct rtw89_h2c_wow_wakeup_ctrl {
+ __le32 w0;
+} __packed;
-static inline void RTW89_SET_WOW_WAKEUP_CTRL_MAC_ID(void *h2c, u32 val)
-{
- le32p_replace_bits((__le32 *)h2c, val, GENMASK(31, 24));
-}
+#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_PATTERN_MATCH_ENABLE BIT(0)
+#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_MAGIC_ENABLE BIT(1)
+#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_HW_UNICAST_ENABLE BIT(2)
+#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_FW_UNICAST_ENABLE BIT(3)
+#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_DEAUTH_ENABLE BIT(4)
+#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_REKEYP_ENABLE BIT(5)
+#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_EAP_ENABLE BIT(6)
+#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_ALL_DATA_ENABLE BIT(7)
+#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_MAC_ID_EXT GENMASK(23, 16)
+#define RTW89_H2C_WOW_WAKEUP_CTRL_W0_MAC_ID GENMASK(31, 24)
struct rtw89_h2c_wow_cam_update {
__le32 w0;
--
2.25.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox