* Re: pull-request: wireless-drivers 2019-03-19
From: David Miller @ 2019-03-19 19:47 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, netdev, linux-kernel
In-Reply-To: <87pnqm4pmf.fsf@kamboji.qca.qualcomm.com>
From: Kalle Valo <kvalo@codeaurora.org>
Date: Tue, 19 Mar 2019 21:43:04 +0200
> here are some fixes to net tree for 5.1. Please let me know if there are
> any problems.
Pulled, thanks Kalle.
^ permalink raw reply
* pull-request: wireless-drivers 2019-03-19
From: Kalle Valo @ 2019-03-19 19:43 UTC (permalink / raw)
To: David Miller; +Cc: linux-wireless, netdev, linux-kernel
Hi Dave,
here are some fixes to net tree for 5.1. Please let me know if there are
any problems.
Kalle
The following changes since commit 4177c5d94264b57f426ef5c45a788808d1a1e536:
net/sched: act_tunnel_key: Fix double free dst_cache (2019-03-05 12:57:28 -0800)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers.git tags/wireless-drivers-for-davem-2019-03-19
for you to fetch changes up to 7dfc45e6282a7662279d168cc1219929456f8750:
mt76x02: do not enable RTS/CTS by default (2019-03-19 17:37:25 +0200)
----------------------------------------------------------------
wireless-drivers fixes for 5.1
First set of fixes for 5.1. Lots of fixes for mt76 this time.
iwlwifi
* fix warning with do_div()
mt7601u
* avoid using hardware which is supported by mt76
mt76
* more fixes for hweight8() usage
* fix hardware restart for mt76x2
* fix writing txwi on USB devices
* fix (and disable by default) ED/CCA support on 76x2
* fix powersave issues on 7603
* fix return value check for ioremap on 7603
* fix duplicate USB device IDs
----------------------------------------------------------------
Arnd Bergmann (1):
iwlwifi: fix 64-bit division
Felix Fietkau (16):
mt76: rewrite dma descriptor base and ring size on queue reset
mt76: mt76x02: when setting a key, use PN from mac80211
mt76: mt76x2: implement full device restart on watchdog reset
mt76: mt76x02: only update the base mac address if necessary
mt76: mt76x02: reduce false positives in ED/CCA tx blocking
mt76: mt7603: fix tx status HT rate validation
mt76: mt76x2: fix external LNA gain settings
mt76: mt76x2: fix 2.4 GHz channel gain settings
mt76: mt7603: clear ps filtering mode before releasing buffered frames
mt76: mt7603: fix up hardware queue index for PS filtered packets
mt76: mt7603: notify mac80211 about buffered frames in ps queue
mt76: mt7603: clear the service period on releasing PS filtered packets
mt76: when releasing PS frames, end the service period if no frame was found
mt76: mt76x02: disable ED/CCA by default
mt76: mt7603: set moredata flag when queueing ps-filtered packets
mt76: mt7603: use the correct hweight8() function
Kalle Valo (1):
Merge tag 'mt76-for-kvalo-2019-03-07' of https://github.com/nbd168/wireless
Lorenzo Bianconi (3):
mt76: introduce q->stopped parameter
mt76x2u: remove duplicated entry in mt76x2u_device_table
mt76: fix schedule while atomic in mt76x02_reset_state
Stanislaw Gruszka (4):
mt76x02: fix hdr pointer in write txwi for USB
mt7601u: check chip version on probe
mt76x02u: check chip version on probe
mt76x02: do not enable RTS/CTS by default
Wei Yongjun (1):
mt76: fix return value check in mt76_wmac_probe()
.../net/wireless/intel/iwlwifi/mvm/ftm-initiator.c | 4 +-
drivers/net/wireless/mediatek/mt76/dma.c | 7 +-
drivers/net/wireless/mediatek/mt76/mac80211.c | 18 +++--
drivers/net/wireless/mediatek/mt76/mt76.h | 4 ++
drivers/net/wireless/mediatek/mt76/mt7603/beacon.c | 3 +-
drivers/net/wireless/mediatek/mt76/mt7603/dma.c | 17 ++++-
drivers/net/wireless/mediatek/mt76/mt7603/init.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt7603/mac.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt7603/main.c | 16 +++++
drivers/net/wireless/mediatek/mt76/mt7603/mcu.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt7603/soc.c | 4 +-
.../net/wireless/mediatek/mt76/mt76x0/initvals.h | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x0/usb.c | 10 ++-
drivers/net/wireless/mediatek/mt76/mt76x02.h | 11 +++
.../net/wireless/mediatek/mt76/mt76x02_debugfs.c | 27 +++++++
drivers/net/wireless/mediatek/mt76/mt76x02_dfs.c | 3 +-
drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 67 ++++++++++++++++--
drivers/net/wireless/mediatek/mt76/mt76x02_mac.h | 2 +
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c | 82 +++++++++++++++++++---
drivers/net/wireless/mediatek/mt76/mt76x02_phy.c | 2 +
.../net/wireless/mediatek/mt76/mt76x02_usb_core.c | 3 +-
drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 14 ++--
drivers/net/wireless/mediatek/mt76/mt76x2/init.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x2/mt76x2.h | 1 +
.../net/wireless/mediatek/mt76/mt76x2/pci_init.c | 2 +-
.../net/wireless/mediatek/mt76/mt76x2/pci_mcu.c | 21 ++++++
drivers/net/wireless/mediatek/mt76/mt76x2/phy.c | 30 +++++---
drivers/net/wireless/mediatek/mt76/mt76x2/usb.c | 7 +-
.../net/wireless/mediatek/mt76/mt76x2/usb_mac.c | 1 -
drivers/net/wireless/mediatek/mt76/tx.c | 11 ++-
drivers/net/wireless/mediatek/mt76/usb.c | 6 +-
drivers/net/wireless/mediatek/mt7601u/usb.c | 4 ++
32 files changed, 329 insertions(+), 58 deletions(-)
--
Kalle Valo
^ permalink raw reply
* [PATCH] net:mwl8k:move spin_lock_bh to spin_lock in tasklet
From: Jeff Xie @ 2019-03-19 16:24 UTC (permalink / raw)
To: buytenh, kvalo; +Cc: davem, chongguiguzi, linux-wireless, netdev, linux-kernel
It is unnecessary to call spin_lock_bh in a tasklet.
Signed-off-by: Jeff Xie <chongguiguzi@gmail.com>
---
drivers/net/wireless/marvell/mwl8k.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/marvell/mwl8k.c b/drivers/net/wireless/marvell/mwl8k.c
index 8e4e9b6..21a86cc 100644
--- a/drivers/net/wireless/marvell/mwl8k.c
+++ b/drivers/net/wireless/marvell/mwl8k.c
@@ -4631,7 +4631,7 @@ static void mwl8k_tx_poll(unsigned long data)
limit = 32;
- spin_lock_bh(&priv->tx_lock);
+ spin_lock(&priv->tx_lock);
for (i = 0; i < mwl8k_tx_queues(priv); i++)
limit -= mwl8k_txq_reclaim(hw, i, limit, 0);
@@ -4641,7 +4641,7 @@ static void mwl8k_tx_poll(unsigned long data)
priv->tx_wait = NULL;
}
- spin_unlock_bh(&priv->tx_lock);
+ spin_unlock(&priv->tx_lock);
if (limit) {
writel(~MWL8K_A2H_INT_TX_DONE,
--
2.7.4
^ permalink raw reply related
* Re: [RFC] mt76: usb: reduce locking in mt76u_tx_tasklet
From: Lorenzo Bianconi @ 2019-03-19 16:23 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Lorenzo Bianconi, nbd, linux-wireless
In-Reply-To: <20190319160426.GA15616@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 2457 bytes --]
> On Tue, Mar 19, 2019 at 01:58:13PM +0100, Lorenzo Bianconi wrote:
> > > On Mon, Mar 18, 2019 at 12:09:32PM +0100, Lorenzo Bianconi wrote:
> > > > Similar to pci counterpart, reduce locking in mt76u_tx_tasklet since
> > > > q->head is managed just in mt76u_tx_tasklet and q->queued is updated
> > > > holding q->lock
> > > >
> > > > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > > > ---
> > > > drivers/net/wireless/mediatek/mt76/usb.c | 18 +++++++++++-------
> > > > 1 file changed, 11 insertions(+), 7 deletions(-)
> > > >
> > > > diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
> > > > index ac03acdae279..8cd70c32d77a 100644
> > > > --- a/drivers/net/wireless/mediatek/mt76/usb.c
> > > > +++ b/drivers/net/wireless/mediatek/mt76/usb.c
> > > > @@ -634,29 +634,33 @@ static void mt76u_tx_tasklet(unsigned long data)
> > > > int i;
> > > >
> > > > for (i = 0; i < IEEE80211_NUM_ACS; i++) {
> > > > + u32 n_queued = 0, n_sw_queued = 0;
> > > > +
> > > > sq = &dev->q_tx[i];
> > > > q = sq->q;
> > > >
> > > > - spin_lock_bh(&q->lock);
> > > > - while (true) {
> > > > + while (q->queued > n_queued) {
> > > > buf = &q->entry[q->head].ubuf;
> > > > - if (!buf->done || !q->queued)
> > > > + if (!buf->done)
> > > > break;
> > >
> > > I'm still thinking if this is safe or not. Is somewhat tricky to
> > > read variable outside the lock because in such case there is no time
> > > guarantee when variable written on one CPU gets updated value on
> > > different CPU. And for USB is not only q->queued but also buf->done.
> >
> > Hi Stanislaw,
> >
> > I was wondering if this is safe as well, but q->queued is updated holding q->lock
> > and I guess it will ensure to not overlap tx and status code path.
>
> Overlap will not happen, at worst what can happen is q->queued will be
> smaller on tx_tasklet than on tx_queue_skb.
Yes, that is the point :)
>
> > Regarding buf->done, it is already updated without holding the lock in mt76u_complete_tx
>
> That's actually a bug, but it's not important, if tx_tasklet will not
> see updated buf->done <- true value by mt76u_complete_tx on different
> cpu, it will not complete skb. It will be done on next tx_tasklet iteration.
> Worse thing would be opposite situation.
Can this really occur? (since queued is update holding the lock)
>
> Stanislaw
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [RFC] mt76: usb: reduce locking in mt76u_tx_tasklet
From: Stanislaw Gruszka @ 2019-03-19 16:04 UTC (permalink / raw)
To: Lorenzo Bianconi; +Cc: Lorenzo Bianconi, nbd, linux-wireless
In-Reply-To: <20190319125812.GA21821@localhost.localdomain>
On Tue, Mar 19, 2019 at 01:58:13PM +0100, Lorenzo Bianconi wrote:
> > On Mon, Mar 18, 2019 at 12:09:32PM +0100, Lorenzo Bianconi wrote:
> > > Similar to pci counterpart, reduce locking in mt76u_tx_tasklet since
> > > q->head is managed just in mt76u_tx_tasklet and q->queued is updated
> > > holding q->lock
> > >
> > > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > > ---
> > > drivers/net/wireless/mediatek/mt76/usb.c | 18 +++++++++++-------
> > > 1 file changed, 11 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
> > > index ac03acdae279..8cd70c32d77a 100644
> > > --- a/drivers/net/wireless/mediatek/mt76/usb.c
> > > +++ b/drivers/net/wireless/mediatek/mt76/usb.c
> > > @@ -634,29 +634,33 @@ static void mt76u_tx_tasklet(unsigned long data)
> > > int i;
> > >
> > > for (i = 0; i < IEEE80211_NUM_ACS; i++) {
> > > + u32 n_queued = 0, n_sw_queued = 0;
> > > +
> > > sq = &dev->q_tx[i];
> > > q = sq->q;
> > >
> > > - spin_lock_bh(&q->lock);
> > > - while (true) {
> > > + while (q->queued > n_queued) {
> > > buf = &q->entry[q->head].ubuf;
> > > - if (!buf->done || !q->queued)
> > > + if (!buf->done)
> > > break;
> >
> > I'm still thinking if this is safe or not. Is somewhat tricky to
> > read variable outside the lock because in such case there is no time
> > guarantee when variable written on one CPU gets updated value on
> > different CPU. And for USB is not only q->queued but also buf->done.
>
> Hi Stanislaw,
>
> I was wondering if this is safe as well, but q->queued is updated holding q->lock
> and I guess it will ensure to not overlap tx and status code path.
Overlap will not happen, at worst what can happen is q->queued will be
smaller on tx_tasklet than on tx_queue_skb.
> Regarding buf->done, it is already updated without holding the lock in mt76u_complete_tx
That's actually a bug, but it's not important, if tx_tasklet will not
see updated buf->done <- true value by mt76u_complete_tx on different
cpu, it will not complete skb. It will be done on next tx_tasklet iteration.
Worse thing would be opposite situation.
Stanislaw
^ permalink raw reply
* Re: [PATCH 5.1] mt76x02: do not enable RTS/CTS by default
From: Kalle Valo @ 2019-03-19 15:38 UTC (permalink / raw)
To: Stanislaw Gruszka
Cc: linux-wireless, Felix Fietkau, Lorenzo Bianconi,
Stanislaw Gruszka
In-Reply-To: <1552393927-26634-1-git-send-email-sgruszka@redhat.com>
Stanislaw Gruszka <sgruszka@redhat.com> wrote:
> My commit 26a7b5473191 ("mt76x02: set protection according to ht
> operation element") enabled by default RTS/CTS protection for OFDM
> and CCK traffic, because MT_TX_RTS_CFG_THRESH is configured to non
> 0xffff by initvals and .set_rts_threshold callback is not called by
> mac80211 on initialization, only on user request or during
> ieee80211_reconfig() (suspend/resuem or restart_hw).
>
> Enabling RTS/CTS cause some problems when sending probe request
> frames by hcxdumptool penetration tool, but I expect it can cause
> other issues on different scenarios.
>
> Restore previous setting of RTS/CTS being disabled by default for
> OFDM/CCK by changing MT_TX_RTS_CFG_THRESH initvals to 0xffff.
>
> Fixes: 26a7b5473191 ("mt76x02: set protection according to ht operation element")
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Patch applied to wireless-drivers.git, thanks.
7dfc45e6282a mt76x02: do not enable RTS/CTS by default
--
https://patchwork.kernel.org/patch/10849179/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: [PATCH v2] mt76: fix schedule while atomic in mt76x02_reset_state
From: Kalle Valo @ 2019-03-19 15:37 UTC (permalink / raw)
To: Lorenzo Bianconi; +Cc: nbd, linux-wireless
In-Reply-To: <f5d501960f82e62806e4a4566e0b50795b2103db.1552309862.git.lorenzo@kernel.org>
Lorenzo Bianconi <lorenzo@kernel.org> wrote:
> Fix following schedule while atomic in mt76x02_reset_state
> since synchronize_rcu is run inside a RCU section
>
> [44036.944222] mt76x2e 0000:06:00.0: MCU message 31 (seq 3) timed out
> [44036.944281] BUG: sleeping function called from invalid context at kernel/rcu/tree_exp.h:818
> [44036.944284] in_atomic(): 1, irqs_disabled(): 0, pid: 28066, name: kworker/u4:1
> [44036.944287] INFO: lockdep is turned off.
> [44036.944292] CPU: 1 PID: 28066 Comm: kworker/u4:1 Tainted: G W 5.0.0-rc7-wdn-t1+ #7
> [44036.944294] Hardware name: Dell Inc. Studio XPS 1340/0K183D, BIOS A11 09/08/2009
> [44036.944305] Workqueue: phy1 mt76x02_wdt_work [mt76x02_lib]
> [44036.944308] Call Trace:
> [44036.944317] dump_stack+0x67/0x90
> [44036.944322] ___might_sleep.cold.88+0x9f/0xaf
> [44036.944327] rcu_blocking_is_gp+0x13/0x50
> [44036.944330] synchronize_rcu+0x17/0x80
> [44036.944337] mt76_sta_state+0x138/0x1d0 [mt76]
> [44036.944349] mt76x02_wdt_work+0x1c9/0x610 [mt76x02_lib]
> [44036.944355] process_one_work+0x2a5/0x620
> [44036.944361] worker_thread+0x35/0x3e0
> [44036.944368] kthread+0x11c/0x140
> [44036.944376] ret_from_fork+0x3a/0x50
> [44036.944384] BUG: scheduling while atomic: kworker/u4:1/28066/0x00000002
> [44036.944387] INFO: lockdep is turned off.
> [44036.944389] Modules linked in: cmac ctr ccm af_packet snd_hda_codec_hdmi
>
> Introduce __mt76_sta_remove in order to run sta_remove without holding dev->mutex.
> Move __mt76_sta_remove outside of RCU section in mt76x02_reset_state
>
> Fixes: e4ebb8b403d1 ("mt76: mt76x2: implement full device restart on watchdog reset")
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Patch applied to wireless-drivers.git, thanks.
13f61dfc5235 mt76: fix schedule while atomic in mt76x02_reset_state
--
https://patchwork.kernel.org/patch/10847437/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: [PATCH] mt76: mt7603: use the correct hweight8() function
From: Kalle Valo @ 2019-03-19 15:36 UTC (permalink / raw)
To: Felix Fietkau; +Cc: linux-wireless
In-Reply-To: <20190311130953.61869-1-nbd@nbd.name>
Felix Fietkau <nbd@nbd.name> wrote:
> __sw_hweight8() is only defined if CONFIG_GENERIC_HWEIGHT is enabled.
> The function that works on all architectures is hweight8().
>
> Signed-off-by: Felix Fietkau <nbd@nbd.name>
Patch applied to wireless-drivers.git, thanks.
f2a00a821aac mt76: mt7603: use the correct hweight8() function
--
https://patchwork.kernel.org/patch/10847433/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: [PATCH v2] mt76x02u: check chip version on probe
From: Kalle Valo @ 2019-03-19 15:35 UTC (permalink / raw)
To: Stanislaw Gruszka
Cc: linux-wireless, Felix Fietkau, Lorenzo Bianconi,
Xose Vazquez Perez, Stanislaw Gruszka
In-Reply-To: <1551961341-28975-1-git-send-email-sgruszka@redhat.com>
Stanislaw Gruszka <sgruszka@redhat.com> wrote:
> Since some USB device IDs are duplicated between mt76x0u, mt7601u
> and mt76x2u device, check chip version on probe and return error if
> not match the driver.
>
> Don't think this is serious issue, probe most likely will fail at
> some other point for wrong device, but we do not have to configure
> it if we know is not our device.
>
> Reported-by: Xose Vazquez Perez <xose.vazquez@gmail.com>
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Patch applied to wireless-drivers.git, thanks.
40b941611bd4 mt76x02u: check chip version on probe
--
https://patchwork.kernel.org/patch/10842759/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: [PATCH v2] mt7601u: check chip version on probe
From: Kalle Valo @ 2019-03-19 15:33 UTC (permalink / raw)
To: Stanislaw Gruszka
Cc: linux-wireless, Jakub Kicinski, Xose Vazquez Perez,
Stanislaw Gruszka
In-Reply-To: <1551961327-28912-1-git-send-email-sgruszka@redhat.com>
Stanislaw Gruszka <sgruszka@redhat.com> wrote:
> Since some USB device IDs are duplicated between mt7601u and mt76x0u
> devices, check chip version on probe and return error if not match
> 0x7601.
>
> Don't think this is serious issue, probe most likely will fail at
> some other point for wrong device, but we do not have to configure
> it if we know is not mt7601u device.
>
> Reported-by: Xose Vazquez Perez <xose.vazquez@gmail.com>
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> Acked-by: Jakub Kicinski <kubakici@wp.pl>
Patch applied to wireless-drivers.git, thanks.
c0316470683a mt7601u: check chip version on probe
--
https://patchwork.kernel.org/patch/10842757/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* [PATCH] rtl8723ae: Make rtl8723e_dm_refresh_rate_adaptive_mask static
From: Yue Haibing @ 2019-03-19 15:19 UTC (permalink / raw)
To: davem, pkshih, kvalo; +Cc: linux-kernel, netdev, linux-wireless, YueHaibing
From: YueHaibing <yuehaibing@huawei.com>
Fix sparse warning:
drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c:666:6:
warning: symbol 'rtl8723e_dm_refresh_rate_adaptive_mask' was not declared. Should it be static?
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c
index 514891e..d8260c7 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/dm.c
@@ -663,7 +663,7 @@ void rtl8723e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
}
-void rtl8723e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
+static void rtl8723e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
--
2.7.4
^ permalink raw reply related
* Re: [PATCH RFC v2] mac80211: debugfs option to force TX status frames
From: Julius Niedworok @ 2019-03-19 15:07 UTC (permalink / raw)
To: Jeremy Sowden
Cc: Kalle Valo, ga58taw, linux-wireless, david, nc, Johannes Berg,
David S. Miller, netdev, linux-kernel
In-Reply-To: <20190311145240.akms2pz2hxsalmaz@azazel.net>
> On 11.03.2019 15:52, Jeremy Sowden wrote:
>
> It's the value that matters, not the type. It will only be too big for
> the buffer if the result of casting local->force_tx_status to int is
> less than -9 or greeater than 99.
>
> scnprintf(buf, size(buf), "%lld\n", (long long)local->force_tx_status)
>
> would also be fine if the value were in range. Note also that scnprintf
> will not overrun the buffer: it will truncate the string.
Thanks for the clarification :)
> As it happens, arguments to variadic functions are subject to the
> "default argument promotions," so if local->force_tx_status is in fact a
> bool (I can't find the definition), it would be promoted to int and the
> cast is superfluous.
Yes - the cast is superfluous. We still think it might be useful to keep it
there to make the point that the value will be casted. However, if you
prefer to omit the cast, we are happy to take it out.
Thank you,
Julius and Charlie
^ permalink raw reply
* [PATCH] net:rtlwifi:move spin_lock_bh to spin_lock in tasklet
From: Jeff Xie @ 2019-03-19 14:31 UTC (permalink / raw)
To: pkshih, kvalo; +Cc: davem, linux-wireless, netdev, linux-kernel, chongguiguzi
It is unnecessary to call spin_lock_bh in a tasklet.
Signed-off-by: Jeff Xie <chongguiguzi@gmail.com>
---
drivers/net/wireless/realtek/rtlwifi/pci.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
index 48ca521..4055e0a 100644
--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
@@ -499,16 +499,16 @@ static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw)
memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
- spin_lock_bh(&rtlpriv->locks.waitq_lock);
+ spin_lock(&rtlpriv->locks.waitq_lock);
if (!skb_queue_empty(&mac->skb_waitq[tid]) &&
(ring->entries - skb_queue_len(&ring->queue) >
rtlhal->max_earlymode_num)) {
skb = skb_dequeue(&mac->skb_waitq[tid]);
} else {
- spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+ spin_unlock(&rtlpriv->locks.waitq_lock);
break;
}
- spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+ spin_unlock(&rtlpriv->locks.waitq_lock);
/* Some macaddr can't do early mode. like
* multicast/broadcast/no_qos data
--
2.7.4
^ permalink raw reply related
* Re: [RFC] mt76: usb: reduce locking in mt76u_tx_tasklet
From: Lorenzo Bianconi @ 2019-03-19 12:58 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Lorenzo Bianconi, nbd, linux-wireless
In-Reply-To: <20190319110708.GA5360@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 1748 bytes --]
> On Mon, Mar 18, 2019 at 12:09:32PM +0100, Lorenzo Bianconi wrote:
> > Similar to pci counterpart, reduce locking in mt76u_tx_tasklet since
> > q->head is managed just in mt76u_tx_tasklet and q->queued is updated
> > holding q->lock
> >
> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > ---
> > drivers/net/wireless/mediatek/mt76/usb.c | 18 +++++++++++-------
> > 1 file changed, 11 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
> > index ac03acdae279..8cd70c32d77a 100644
> > --- a/drivers/net/wireless/mediatek/mt76/usb.c
> > +++ b/drivers/net/wireless/mediatek/mt76/usb.c
> > @@ -634,29 +634,33 @@ static void mt76u_tx_tasklet(unsigned long data)
> > int i;
> >
> > for (i = 0; i < IEEE80211_NUM_ACS; i++) {
> > + u32 n_queued = 0, n_sw_queued = 0;
> > +
> > sq = &dev->q_tx[i];
> > q = sq->q;
> >
> > - spin_lock_bh(&q->lock);
> > - while (true) {
> > + while (q->queued > n_queued) {
> > buf = &q->entry[q->head].ubuf;
> > - if (!buf->done || !q->queued)
> > + if (!buf->done)
> > break;
>
> I'm still thinking if this is safe or not. Is somewhat tricky to
> read variable outside the lock because in such case there is no time
> guarantee when variable written on one CPU gets updated value on
> different CPU. And for USB is not only q->queued but also buf->done.
Hi Stanislaw,
I was wondering if this is safe as well, but q->queued is updated holding q->lock
and I guess it will ensure to not overlap tx and status code path.
Regarding buf->done, it is already updated without holding the lock in mt76u_complete_tx
Regards,
Lorenzo
>
> Stanislaw
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [RFC] mt76: usb: reduce locking in mt76u_tx_tasklet
From: Stanislaw Gruszka @ 2019-03-19 11:07 UTC (permalink / raw)
To: Lorenzo Bianconi; +Cc: nbd, linux-wireless, lorenzo.bianconi
In-Reply-To: <1ee5ce7818f9d45c9713ce99e810cb84f50dcf03.1552907276.git.lorenzo@kernel.org>
On Mon, Mar 18, 2019 at 12:09:32PM +0100, Lorenzo Bianconi wrote:
> Similar to pci counterpart, reduce locking in mt76u_tx_tasklet since
> q->head is managed just in mt76u_tx_tasklet and q->queued is updated
> holding q->lock
>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
> drivers/net/wireless/mediatek/mt76/usb.c | 18 +++++++++++-------
> 1 file changed, 11 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
> index ac03acdae279..8cd70c32d77a 100644
> --- a/drivers/net/wireless/mediatek/mt76/usb.c
> +++ b/drivers/net/wireless/mediatek/mt76/usb.c
> @@ -634,29 +634,33 @@ static void mt76u_tx_tasklet(unsigned long data)
> int i;
>
> for (i = 0; i < IEEE80211_NUM_ACS; i++) {
> + u32 n_queued = 0, n_sw_queued = 0;
> +
> sq = &dev->q_tx[i];
> q = sq->q;
>
> - spin_lock_bh(&q->lock);
> - while (true) {
> + while (q->queued > n_queued) {
> buf = &q->entry[q->head].ubuf;
> - if (!buf->done || !q->queued)
> + if (!buf->done)
> break;
I'm still thinking if this is safe or not. Is somewhat tricky to
read variable outside the lock because in such case there is no time
guarantee when variable written on one CPU gets updated value on
different CPU. And for USB is not only q->queued but also buf->done.
Stanislaw
^ permalink raw reply
* [PATCH v2] mac80211: un-schedule TXQs on powersave start
From: Felix Fietkau @ 2019-03-19 11:00 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, Toke Høiland-Jørgensen
Once a station enters powersave, its queues should not be returned by
ieee80211_next_txq() anymore. They will be re-scheduled again after the
station has woken up again
Fixes: 1866760096bf4 ("mac80211: Add TXQ scheduling API")
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
net/mac80211/rx.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 295535b75184..60aac91e35d0 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1568,7 +1568,15 @@ static void sta_ps_start(struct sta_info *sta)
return;
for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) {
- if (txq_has_queue(sta->sta.txq[tid]))
+ struct ieee80211_txq *txq = sta->sta.txq[tid];
+ struct txq_info *txqi = to_txq_info(txq);
+
+ spin_lock(&local->active_txq_lock[txq->ac]);
+ if (!list_empty(&txqi->schedule_order))
+ list_del_init(&txqi->schedule_order);
+ spin_unlock(&local->active_txq_lock[txq->ac]);
+
+ if (txq_has_queue(txq))
set_bit(tid, &sta->txq_buffered_tids);
else
clear_bit(tid, &sta->txq_buffered_tids);
--
2.17.0
^ permalink raw reply related
* [PATCH] mac80211: un-schedule TXQs on powersave start
From: Felix Fietkau @ 2019-03-19 10:49 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, Toke Høiland-Jørgensen
Once a station enters powersave, its queues should not be returned by
ieee80211_next_txq() anymore. They will be re-scheduled again after the
station has woken up again
Fixes: 1866760096bf4 ("mac80211: Add TXQ scheduling API")
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
net/mac80211/rx.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 295535b75184..7a7738942034 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1568,7 +1568,15 @@ static void sta_ps_start(struct sta_info *sta)
return;
for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) {
- if (txq_has_queue(sta->sta.txq[tid]))
+ struct ieee80211_txq *txq = sta->sta.txq[tid];
+ struct txq_info *txqi = to_txq_info(txq);
+
+ spin_lock_bh(&local->active_txq_lock[txq->ac]);
+ if (!list_empty(&txqi->schedule_order))
+ list_del_init(&txqi->schedule_order);
+ spin_unlock_bh(&local->active_txq_lock[txq->ac]);
+
+ if (txq_has_queue(txq))
set_bit(tid, &sta->txq_buffered_tids);
else
clear_bit(tid, &sta->txq_buffered_tids);
--
2.17.0
^ permalink raw reply related
* [PATCH v2 12/12] mt76x02: enable AP mode for USB
From: Stanislaw Gruszka @ 2019-03-19 10:37 UTC (permalink / raw)
To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552991867-5087-1-git-send-email-sgruszka@redhat.com>
Enable AP mode. For now without multi-vif support, this will require
more testing and investigation.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index ed6463c9166e..284dae65cdf1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -142,6 +142,7 @@ void mt76x02_init_device(struct mt76x02_dev *dev)
wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_AP) |
#ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
@@ -158,7 +159,6 @@ void mt76x02_init_device(struct mt76x02_dev *dev)
wiphy->reg_notifier = mt76x02_regd_notifier;
wiphy->iface_combinations = mt76x02_if_comb;
wiphy->n_iface_combinations = ARRAY_SIZE(mt76x02_if_comb);
- wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
/* init led callbacks */
--
1.9.3
^ permalink raw reply related
* [PATCH v2 11/12] mt76: unify set_tim
From: Stanislaw Gruszka @ 2019-03-19 10:37 UTC (permalink / raw)
To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552991867-5087-1-git-send-email-sgruszka@redhat.com>
All mt76 drivers (now also USB drivers) require empty .set_tim
callback. Add it to common mt76 module and use on all drivers.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/mediatek/mt76/mac80211.c | 7 +++++++
drivers/net/wireless/mediatek/mt76/mt76.h | 2 ++
drivers/net/wireless/mediatek/mt76/mt7603/main.c | 8 +-------
drivers/net/wireless/mediatek/mt76/mt76x0/pci.c | 9 +--------
drivers/net/wireless/mediatek/mt76/mt76x0/usb.c | 1 +
drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c | 8 +-------
drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c | 1 +
7 files changed, 14 insertions(+), 22 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 47eecb4d4d01..851caabbecda 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -785,3 +785,10 @@ void mt76_csa_check(struct mt76_dev *dev)
__mt76_csa_check, dev);
}
EXPORT_SYMBOL_GPL(mt76_csa_check);
+
+int
+mt76_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
+{
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mt76_set_tim);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index edff44f32c8e..c163ba68647e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -732,6 +732,8 @@ int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
void mt76_csa_check(struct mt76_dev *dev);
void mt76_csa_finish(struct mt76_dev *dev);
+int mt76_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set);
+
/* internal */
void mt76_tx_free(struct mt76_dev *dev);
struct mt76_txwi_cache *mt76_get_txwi(struct mt76_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
index 7849528db134..a03729824c4d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
@@ -664,12 +664,6 @@ static void mt7603_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *cont
mt76_tx(&dev->mt76, control->sta, wcid, skb);
}
-static int
-mt7603_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
-{
- return 0;
-}
-
const struct ieee80211_ops mt7603_ops = {
.tx = mt7603_tx,
.start = mt7603_start,
@@ -691,7 +685,7 @@ static void mt7603_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *cont
.sta_rate_tbl_update = mt7603_sta_rate_tbl_update,
.release_buffered_frames = mt7603_release_buffered_frames,
.set_coverage_class = mt7603_set_coverage_class,
- .set_tim = mt7603_set_tim,
+ .set_tim = mt76_set_tim,
.get_survey = mt76_get_survey,
};
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index e35165416cf0..a7ff7e32b9b3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -74,13 +74,6 @@ static void mt76x0e_stop(struct ieee80211_hw *hw)
{
}
-static int
-mt76x0e_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
- bool set)
-{
- return 0;
-}
-
static const struct ieee80211_ops mt76x0e_ops = {
.tx = mt76x02_tx,
.start = mt76x0e_start,
@@ -101,7 +94,7 @@ static void mt76x0e_stop(struct ieee80211_hw *hw)
.get_survey = mt76_get_survey,
.get_txpower = mt76_get_txpower,
.flush = mt76x0e_flush,
- .set_tim = mt76x0e_set_tim,
+ .set_tim = mt76_set_tim,
.release_buffered_frames = mt76_release_buffered_frames,
.set_coverage_class = mt76x02_set_coverage_class,
.set_rts_threshold = mt76x02_set_rts_threshold,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index b9b8a1dafbc9..cf97bbd89485 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -152,6 +152,7 @@ static void mt76x0u_stop(struct ieee80211_hw *hw)
.set_rts_threshold = mt76x02_set_rts_threshold,
.wake_tx_queue = mt76_wake_tx_queue,
.get_txpower = mt76_get_txpower,
+ .set_tim = mt76_set_tim,
.release_buffered_frames = mt76_release_buffered_frames,
};
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
index 878ce92405ed..16dc8e2451b5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
@@ -135,12 +135,6 @@
{
}
-static int
-mt76x2_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
-{
- return 0;
-}
-
static int mt76x2_set_antenna(struct ieee80211_hw *hw, u32 tx_ant,
u32 rx_ant)
{
@@ -197,7 +191,7 @@ static int mt76x2_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant,
.release_buffered_frames = mt76_release_buffered_frames,
.set_coverage_class = mt76x02_set_coverage_class,
.get_survey = mt76_get_survey,
- .set_tim = mt76x2_set_tim,
+ .set_tim = mt76_set_tim,
.set_antenna = mt76x2_set_antenna,
.get_antenna = mt76x2_get_antenna,
.set_rts_threshold = mt76x02_set_rts_threshold,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
index 46c6b3764f5a..eb414fb75fb1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
@@ -129,5 +129,6 @@ static void mt76x2u_stop(struct ieee80211_hw *hw)
.sw_scan_complete = mt76x02_sw_scan_complete,
.sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
.get_txpower = mt76_get_txpower,
+ .set_tim = mt76_set_tim,
.release_buffered_frames = mt76_release_buffered_frames,
};
--
1.9.3
^ permalink raw reply related
* [PATCH v2 10/12] mt76x02u: add mt76_release_buffered_frames
From: Stanislaw Gruszka @ 2019-03-19 10:37 UTC (permalink / raw)
To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552991867-5087-1-git-send-email-sgruszka@redhat.com>
Create software MT_TXQ_PSD queue for USB and map it to MT_TXQ_VO
since we do not have USB endpoint for PSD. This should make
mt76_release_buffered_frames() work by sending released frames
via MT_TXQ_VO.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/mediatek/mt76/mt76x0/usb.c | 1 +
drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c | 1 +
drivers/net/wireless/mediatek/mt76/usb.c | 7 ++++++-
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index 0348a1b38d2d..b9b8a1dafbc9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -152,6 +152,7 @@ static void mt76x0u_stop(struct ieee80211_hw *hw)
.set_rts_threshold = mt76x02_set_rts_threshold,
.wake_tx_queue = mt76_wake_tx_queue,
.get_txpower = mt76_get_txpower,
+ .release_buffered_frames = mt76_release_buffered_frames,
};
static int mt76x0u_init_hardware(struct mt76x02_dev *dev)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
index 1e6856856536..46c6b3764f5a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
@@ -129,4 +129,5 @@ static void mt76x2u_stop(struct ieee80211_hw *hw)
.sw_scan_complete = mt76x02_sw_scan_complete,
.sta_rate_tbl_update = mt76x02_sta_rate_tbl_update,
.get_txpower = mt76_get_txpower,
+ .release_buffered_frames = mt76_release_buffered_frames,
};
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 27896a435d6c..7b62bd63d395 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -792,9 +792,14 @@ static int mt76u_alloc_tx(struct mt76_dev *dev)
struct mt76_queue *q;
int i, j;
- for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+ for (i = 0; i <= MT_TXQ_PSD; i++) {
INIT_LIST_HEAD(&dev->q_tx[i].swq);
+ if (i >= IEEE80211_NUM_ACS) {
+ dev->q_tx[i].q = dev->q_tx[0].q;
+ continue;
+ }
+
q = devm_kzalloc(dev->dev, sizeof(*q), GFP_KERNEL);
if (!q)
return -ENOMEM;
--
1.9.3
^ permalink raw reply related
* [PATCH v2 09/12] mt76x02: make beacon slots bigger for USB
From: Stanislaw Gruszka @ 2019-03-19 10:37 UTC (permalink / raw)
To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552991867-5087-1-git-send-email-sgruszka@redhat.com>
Since we sent PS buffered frames via beacon memory we need to make
beacon slots bigger. That imply we will also need to decrease number
of slots as beacon SRAM memory is limited to 8kB.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/mediatek/mt76/mt76x02.h | 3 +-
.../net/wireless/mediatek/mt76/mt76x02_beacon.c | 34 ++++------------------
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c | 2 ++
.../net/wireless/mediatek/mt76/mt76x02_usb_core.c | 20 ++++++++-----
4 files changed, 22 insertions(+), 37 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 93f9436ab809..d665137d256c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -69,6 +69,8 @@ struct mt76x02_calibration {
};
struct mt76x02_beacon_ops {
+ unsigned int nslots;
+ unsigned int slot_size;
void (*pre_tbtt_enable) (struct mt76x02_dev *, bool);
void (*beacon_enable) (struct mt76x02_dev *, bool);
};
@@ -194,7 +196,6 @@ void mt76x02_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *info, u32 changed);
-extern const u16 mt76x02_beacon_offsets[16];
struct beacon_bc_data {
struct mt76x02_dev *dev;
struct sk_buff_head q;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
index c0be90988f82..0c232d02f189 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
@@ -18,36 +18,14 @@
#include "mt76x02.h"
-const u16 mt76x02_beacon_offsets[16] = {
- /* 1024 byte per beacon */
- 0xc000,
- 0xc400,
- 0xc800,
- 0xcc00,
- 0xd000,
- 0xd400,
- 0xd800,
- 0xdc00,
- /* BSS idx 8-15 not used for beacons */
- 0xc000,
- 0xc000,
- 0xc000,
- 0xc000,
- 0xc000,
- 0xc000,
- 0xc000,
- 0xc000,
-};
-EXPORT_SYMBOL_GPL(mt76x02_beacon_offsets);
-
static void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev)
{
- u16 val, base = MT_BEACON_BASE;
u32 regs[4] = {};
+ u16 val;
int i;
- for (i = 0; i < 16; i++) {
- val = mt76x02_beacon_offsets[i] - base;
+ for (i = 0; i < dev->beacon_ops->nslots; i++) {
+ val = i * dev->beacon_ops->slot_size;
regs[i / 4] |= (val / 64) << (8 * (i % 4));
}
@@ -58,7 +36,7 @@ static void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev)
static int
mt76x02_write_beacon(struct mt76x02_dev *dev, int offset, struct sk_buff *skb)
{
- int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
+ int beacon_len = dev->beacon_ops->slot_size;
struct mt76x02_txwi txwi;
if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x02_txwi)))
@@ -77,8 +55,8 @@ static void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev)
__mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 bcn_idx,
struct sk_buff *skb)
{
- int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
- int beacon_addr = mt76x02_beacon_offsets[bcn_idx];
+ int beacon_len = dev->beacon_ops->slot_size;
+ int beacon_addr = MT_BEACON_BASE + (beacon_len * bcn_idx);
int ret = 0;
int i;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index eea8e4718600..79c1126f4ba4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -85,6 +85,8 @@ static void mt76x02e_beacon_enable(struct mt76x02_dev *dev, bool en)
void mt76x02e_init_beacon_config(struct mt76x02_dev *dev)
{
static const struct mt76x02_beacon_ops beacon_ops = {
+ .nslots = 8,
+ .slot_size = 1024,
.pre_tbtt_enable = mt76x02e_pre_tbtt_enable,
.beacon_enable = mt76x02e_beacon_enable,
};
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index 89249621bcec..c403218533da 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -107,6 +107,13 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
/* Trigger pre-TBTT event 8 ms before TBTT */
#define PRE_TBTT_USEC 8000
+
+/* Beacon SRAM memory is limited to 8kB. We need to send PS buffered frames
+ * (which can be 1500 bytes big) via beacon memory. That make limit of number
+ * of slots to 5. TODO: dynamically calculate offsets in beacon SRAM.
+ */
+#define N_BCN_SLOTS 5
+
static void mt76x02u_start_pre_tbtt_timer(struct mt76x02_dev *dev)
{
u64 time;
@@ -164,7 +171,6 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
{
struct mt76x02_dev *dev =
container_of(work, struct mt76x02_dev, pre_tbtt_work);
- int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
struct beacon_bc_data data = {};
struct sk_buff *skb;
int i, nbeacons;
@@ -179,14 +185,10 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
mt76x02_update_beacon_iter, dev);
nbeacons = hweight8(dev->beacon_mask);
- mt76x02_enqueue_buffered_bc(dev, &data, 8 - nbeacons);
+ mt76x02_enqueue_buffered_bc(dev, &data, N_BCN_SLOTS - nbeacons);
- for (i = nbeacons; i < 8; i++) {
+ for (i = nbeacons; i < N_BCN_SLOTS; i++) {
skb = __skb_dequeue(&data.q);
- if (skb && skb->len >= beacon_len) {
- dev_kfree_skb(skb);
- skb = NULL;
- }
mt76x02_mac_set_beacon(dev, i, skb);
}
@@ -224,7 +226,7 @@ static void mt76x02u_beacon_enable(struct mt76x02_dev *dev, bool en)
/* Timer is already stopped, only clean up
* PS buffered frames if any.
*/
- for (i = 0; i < 8; i++)
+ for (i = 0; i < N_BCN_SLOTS; i++)
mt76x02_mac_set_beacon(dev, i, NULL);
}
}
@@ -232,6 +234,8 @@ static void mt76x02u_beacon_enable(struct mt76x02_dev *dev, bool en)
void mt76x02u_init_beacon_config(struct mt76x02_dev *dev)
{
static const struct mt76x02_beacon_ops beacon_ops = {
+ .nslots = N_BCN_SLOTS,
+ .slot_size = (8192 / N_BCN_SLOTS) & ~63,
.pre_tbtt_enable = mt76x02u_pre_tbtt_enable,
.beacon_enable = mt76x02u_beacon_enable,
};
--
1.9.3
^ permalink raw reply related
* [PATCH v2 08/12] mt76x02u: implement pre TBTT work for USB
From: Stanislaw Gruszka @ 2019-03-19 10:37 UTC (permalink / raw)
To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552991867-5087-1-git-send-email-sgruszka@redhat.com>
Program beacons data and PS buffered frames on TBTT work for USB.
We do not have MT_TXQ_PSD queue available via USB endpoints. The way
we can send PS broadcast frames in timely manner before PS stations go
sleep again is program them in beacon data area. Hardware do not modify
those frames since TXWI is properly configured. mt76x02_mac_set_beacon()
already handle this and free no longer used frames.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
.../net/wireless/mediatek/mt76/mt76x02_beacon.c | 2 ++
.../net/wireless/mediatek/mt76/mt76x02_usb_core.c | 36 ++++++++++++++++++++--
2 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
index d77088b7659e..c0be90988f82 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
@@ -38,6 +38,7 @@
0xc000,
0xc000,
};
+EXPORT_SYMBOL_GPL(mt76x02_beacon_offsets);
static void mt76x02_set_beacon_offsets(struct mt76x02_dev *dev)
{
@@ -134,6 +135,7 @@ int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
bcn_idx - 1);
return 0;
}
+EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon);
static void
__mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev, u8 vif_idx,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index 82b78cc5b362..89249621bcec 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -164,9 +164,32 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
{
struct mt76x02_dev *dev =
container_of(work, struct mt76x02_dev, pre_tbtt_work);
+ int beacon_len = mt76x02_beacon_offsets[1] - mt76x02_beacon_offsets[0];
+ struct beacon_bc_data data = {};
+ struct sk_buff *skb;
+ int i, nbeacons;
if (!dev->beacon_mask)
return;
+
+ mt76x02_resync_beacon_timer(dev);
+
+ ieee80211_iterate_active_interfaces(mt76_hw(dev),
+ IEEE80211_IFACE_ITER_RESUME_ALL,
+ mt76x02_update_beacon_iter, dev);
+
+ nbeacons = hweight8(dev->beacon_mask);
+ mt76x02_enqueue_buffered_bc(dev, &data, 8 - nbeacons);
+
+ for (i = nbeacons; i < 8; i++) {
+ skb = __skb_dequeue(&data.q);
+ if (skb && skb->len >= beacon_len) {
+ dev_kfree_skb(skb);
+ skb = NULL;
+ }
+ mt76x02_mac_set_beacon(dev, i, skb);
+ }
+
mt76x02u_restart_pre_tbtt_timer(dev);
}
@@ -190,13 +213,20 @@ static void mt76x02u_pre_tbtt_enable(struct mt76x02_dev *dev, bool en)
static void mt76x02u_beacon_enable(struct mt76x02_dev *dev, bool en)
{
+ int i;
+
if (WARN_ON_ONCE(!dev->beacon_int))
return;
- if (en)
+ if (en) {
mt76x02u_start_pre_tbtt_timer(dev);
-
- /* Nothing to do on disable as timer is already stopped */
+ } else {
+ /* Timer is already stopped, only clean up
+ * PS buffered frames if any.
+ */
+ for (i = 0; i < 8; i++)
+ mt76x02_mac_set_beacon(dev, i, NULL);
+ }
}
void mt76x02u_init_beacon_config(struct mt76x02_dev *dev)
--
1.9.3
^ permalink raw reply related
* [PATCH v2 07/12] mt76x02: disable HW encryption for group frames
From: Stanislaw Gruszka @ 2019-03-19 10:37 UTC (permalink / raw)
To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552991867-5087-1-git-send-email-sgruszka@redhat.com>
This is required to sent multicast/broadcast frames in USB AP
mode just after beacon.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 168c62a90361..ed6463c9166e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -424,6 +424,16 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
return -EOPNOTSUPP;
+ /*
+ * In USB AP mode, broadcast/multicast frames are setup in beacon
+ * data registers and sent via HW beacons engine, they require to
+ * be already encrypted.
+ */
+ if (mt76_is_usb(dev) &&
+ vif->type == NL80211_IFTYPE_AP &&
+ !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+ return -EOPNOTSUPP;
+
msta = sta ? (struct mt76x02_sta *) sta->drv_priv : NULL;
wcid = msta ? &msta->wcid : &mvif->group_wcid;
--
1.9.3
^ permalink raw reply related
* [PATCH v2 06/12] mt76x02u: add sta_ps
From: Stanislaw Gruszka @ 2019-03-19 10:37 UTC (permalink / raw)
To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552991867-5087-1-git-send-email-sgruszka@redhat.com>
Add sta_ps callback but dont set WCID drop sicne registers for USB
can not be accessed from tasklet context.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/mediatek/mt76/mt76x0/usb.c | 1 +
drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 3 ++-
drivers/net/wireless/mediatek/mt76/mt76x2/usb.c | 1 +
3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index 7f3113b91498..0348a1b38d2d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -222,6 +222,7 @@ static int mt76x0u_probe(struct usb_interface *usb_intf,
.tx_complete_skb = mt76x02u_tx_complete_skb,
.tx_status_data = mt76x02_tx_status_data,
.rx_skb = mt76x02_queue_rx_skb,
+ .sta_ps = mt76x02_sta_ps,
.sta_add = mt76x02_sta_add,
.sta_remove = mt76x02_sta_remove,
};
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 1026939d6b63..168c62a90361 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -615,7 +615,8 @@ void mt76x02_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta,
int idx = msta->wcid.idx;
mt76_stop_tx_queues(&dev->mt76, sta, true);
- mt76x02_mac_wcid_set_drop(dev, idx, ps);
+ if (mt76_is_mmio(dev))
+ mt76x02_mac_wcid_set_drop(dev, idx, ps);
}
EXPORT_SYMBOL_GPL(mt76x02_sta_ps);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
index 7a5d539873ca..1f0b1bebed79 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
@@ -40,6 +40,7 @@ static int mt76x2u_probe(struct usb_interface *intf,
.tx_complete_skb = mt76x02u_tx_complete_skb,
.tx_status_data = mt76x02_tx_status_data,
.rx_skb = mt76x02_queue_rx_skb,
+ .sta_ps = mt76x02_sta_ps,
.sta_add = mt76x02_sta_add,
.sta_remove = mt76x02_sta_remove,
};
--
1.9.3
^ permalink raw reply related
* [PATCH v2 05/12] mt76x02: generalize some mmio beaconing functions
From: Stanislaw Gruszka @ 2019-03-19 10:37 UTC (permalink / raw)
To: linux-wireless; +Cc: Felix Fietkau, Lorenzo Bianconi, Stanislaw Gruszka
In-Reply-To: <1552991867-5087-1-git-send-email-sgruszka@redhat.com>
Move some TBTT mmio functions to mt76x02_beacon.c and create new ones
in order to be reused by USB pre-TBTT.
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
drivers/net/wireless/mediatek/mt76/mt76x02.h | 11 +++
.../net/wireless/mediatek/mt76/mt76x02_beacon.c | 102 +++++++++++++++++++++
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c | 91 +-----------------
3 files changed, 115 insertions(+), 89 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 0bfc3a9839d0..93f9436ab809 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -195,8 +195,19 @@ void mt76x02_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *info, u32 changed);
extern const u16 mt76x02_beacon_offsets[16];
+struct beacon_bc_data {
+ struct mt76x02_dev *dev;
+ struct sk_buff_head q;
+ struct sk_buff *tail[8];
+};
void mt76x02_init_beacon_config(struct mt76x02_dev *dev);
void mt76x02e_init_beacon_config(struct mt76x02_dev *dev);
+void mt76x02_resync_beacon_timer(struct mt76x02_dev *dev);
+void mt76x02_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif);
+void mt76x02_enqueue_buffered_bc(struct mt76x02_dev *dev,
+ struct beacon_bc_data *data,
+ int max_nframes);
+
void mt76x02_mac_start(struct mt76x02_dev *dev);
void mt76x02_init_debugfs(struct mt76x02_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
index e980becb6683..d77088b7659e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
@@ -184,6 +184,108 @@ void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
dev->beacon_ops->pre_tbtt_enable(dev, true);
}
+void
+mt76x02_resync_beacon_timer(struct mt76x02_dev *dev)
+{
+ u32 timer_val = dev->beacon_int << 4;
+
+ dev->tbtt_count++;
+
+ /*
+ * Beacon timer drifts by 1us every tick, the timer is configured
+ * in 1/16 TU (64us) units.
+ */
+ if (dev->tbtt_count < 63)
+ return;
+
+ /*
+ * The updated beacon interval takes effect after two TBTT, because
+ * at this point the original interval has already been loaded into
+ * the next TBTT_TIMER value
+ */
+ if (dev->tbtt_count == 63)
+ timer_val -= 1;
+
+ mt76_rmw_field(dev, MT_BEACON_TIME_CFG,
+ MT_BEACON_TIME_CFG_INTVAL, timer_val);
+
+ if (dev->tbtt_count >= 64) {
+ dev->tbtt_count = 0;
+ return;
+ }
+}
+EXPORT_SYMBOL_GPL(mt76x02_resync_beacon_timer);
+
+void
+mt76x02_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
+{
+ struct mt76x02_dev *dev = (struct mt76x02_dev *)priv;
+ struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
+ struct sk_buff *skb = NULL;
+
+ if (!(dev->beacon_mask & BIT(mvif->idx)))
+ return;
+
+ skb = ieee80211_beacon_get(mt76_hw(dev), vif);
+ if (!skb)
+ return;
+
+ mt76x02_mac_set_beacon(dev, mvif->idx, skb);
+}
+EXPORT_SYMBOL_GPL(mt76x02_update_beacon_iter);
+
+static void
+mt76x02_add_buffered_bc(void *priv, u8 *mac, struct ieee80211_vif *vif)
+{
+ struct beacon_bc_data *data = priv;
+ struct mt76x02_dev *dev = data->dev;
+ struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
+ struct ieee80211_tx_info *info;
+ struct sk_buff *skb;
+
+ if (!(dev->beacon_mask & BIT(mvif->idx)))
+ return;
+
+ skb = ieee80211_get_buffered_bc(mt76_hw(dev), vif);
+ if (!skb)
+ return;
+
+ info = IEEE80211_SKB_CB(skb);
+ info->control.vif = vif;
+ info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
+ mt76_skb_set_moredata(skb, true);
+ __skb_queue_tail(&data->q, skb);
+ data->tail[mvif->idx] = skb;
+}
+
+void
+mt76x02_enqueue_buffered_bc(struct mt76x02_dev *dev, struct beacon_bc_data *data,
+ int max_nframes)
+{
+ int i, nframes;
+
+ data->dev = dev;
+ __skb_queue_head_init(&data->q);
+
+ do {
+ nframes = skb_queue_len(&data->q);
+ ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
+ IEEE80211_IFACE_ITER_RESUME_ALL,
+ mt76x02_add_buffered_bc, data);
+ } while (nframes != skb_queue_len(&data->q) &&
+ skb_queue_len(&data->q) < max_nframes);
+
+ if (!skb_queue_len(&data->q))
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(data->tail); i++) {
+ if (!data->tail[i])
+ continue;
+ mt76_skb_set_moredata(data->tail[i], false);
+ }
+}
+EXPORT_SYMBOL_GPL(mt76x02_enqueue_buffered_bc);
+
void mt76x02_init_beacon_config(struct mt76x02_dev *dev)
{
int i;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 2be3ca0c67be..eea8e4718600 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -22,97 +22,16 @@
#include "mt76x02_mcu.h"
#include "mt76x02_trace.h"
-struct beacon_bc_data {
- struct mt76x02_dev *dev;
- struct sk_buff_head q;
- struct sk_buff *tail[8];
-};
-
-static void
-mt76x02_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
-{
- struct mt76x02_dev *dev = (struct mt76x02_dev *)priv;
- struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
- struct sk_buff *skb = NULL;
-
- if (!(dev->beacon_mask & BIT(mvif->idx)))
- return;
-
- skb = ieee80211_beacon_get(mt76_hw(dev), vif);
- if (!skb)
- return;
-
- mt76x02_mac_set_beacon(dev, mvif->idx, skb);
-}
-
-static void
-mt76x02_add_buffered_bc(void *priv, u8 *mac, struct ieee80211_vif *vif)
-{
- struct beacon_bc_data *data = priv;
- struct mt76x02_dev *dev = data->dev;
- struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;
- struct ieee80211_tx_info *info;
- struct sk_buff *skb;
-
- if (!(dev->beacon_mask & BIT(mvif->idx)))
- return;
-
- skb = ieee80211_get_buffered_bc(mt76_hw(dev), vif);
- if (!skb)
- return;
-
- info = IEEE80211_SKB_CB(skb);
- info->control.vif = vif;
- info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
- mt76_skb_set_moredata(skb, true);
- __skb_queue_tail(&data->q, skb);
- data->tail[mvif->idx] = skb;
-}
-
-static void
-mt76x02_resync_beacon_timer(struct mt76x02_dev *dev)
-{
- u32 timer_val = dev->beacon_int << 4;
-
- dev->tbtt_count++;
-
- /*
- * Beacon timer drifts by 1us every tick, the timer is configured
- * in 1/16 TU (64us) units.
- */
- if (dev->tbtt_count < 63)
- return;
-
- /*
- * The updated beacon interval takes effect after two TBTT, because
- * at this point the original interval has already been loaded into
- * the next TBTT_TIMER value
- */
- if (dev->tbtt_count == 63)
- timer_val -= 1;
-
- mt76_rmw_field(dev, MT_BEACON_TIME_CFG,
- MT_BEACON_TIME_CFG_INTVAL, timer_val);
-
- if (dev->tbtt_count >= 64) {
- dev->tbtt_count = 0;
- return;
- }
-}
-
static void mt76x02_pre_tbtt_tasklet(unsigned long arg)
{
struct mt76x02_dev *dev = (struct mt76x02_dev *)arg;
struct mt76_queue *q = dev->mt76.q_tx[MT_TXQ_PSD].q;
struct beacon_bc_data data = {};
struct sk_buff *skb;
- int i, nframes;
+ int i;
mt76x02_resync_beacon_timer(dev);
- data.dev = dev;
- __skb_queue_head_init(&data.q);
-
ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
IEEE80211_IFACE_ITER_RESUME_ALL,
mt76x02_update_beacon_iter, dev);
@@ -122,13 +41,7 @@ static void mt76x02_pre_tbtt_tasklet(unsigned long arg)
if (dev->mt76.csa_complete)
return;
- do {
- nframes = skb_queue_len(&data.q);
- ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
- IEEE80211_IFACE_ITER_RESUME_ALL,
- mt76x02_add_buffered_bc, &data);
- } while (nframes != skb_queue_len(&data.q) &&
- skb_queue_len(&data.q) < 8);
+ mt76x02_enqueue_buffered_bc(dev, &data, 8);
if (!skb_queue_len(&data.q))
return;
--
1.9.3
^ 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