2019-11-16 11:21:22

by Markus Theil

[permalink] [raw]
Subject: [PATCH 0/4] mt76: channel switch support for USB devices

This patch series adds channel switch support for mt76 usb interfaces.
When testing, I noticed that between 5 or 7 consecutive beacons had the
identical channel switch count set. After some debugging I found out,
that beacon copying over usb took far too long (up to 700ms for one call
of mt76x02u_pre_tbtt_work).

Therefore the first three patches speed up beacon copying and the last
patch enables channel switch support also for usb interfaces.

Markus Theil (4):
mt76: mt76x02: ommit beacon slot clearing
mt76: mt76x02: split beaconing
mt76: speed up usb bulk copy
mt76: mt76x02: add channel switch support for usb interfaces

drivers/net/wireless/mediatek/mt76/mt76.h | 2 +-
.../wireless/mediatek/mt76/mt76x02_beacon.c | 62 +++++++------------
.../net/wireless/mediatek/mt76/mt76x02_mac.h | 2 +
.../net/wireless/mediatek/mt76/mt76x02_mmio.c | 4 ++
.../wireless/mediatek/mt76/mt76x02_usb_core.c | 11 ++++
.../net/wireless/mediatek/mt76/mt76x02_util.c | 2 +-
.../wireless/mediatek/mt76/mt76x2/usb_main.c | 5 ++
drivers/net/wireless/mediatek/mt76/usb.c | 22 +++++--
8 files changed, 63 insertions(+), 47 deletions(-)

--
2.24.0


2019-11-16 11:22:46

by Markus Theil

[permalink] [raw]
Subject: [PATCH 1/4] mt76: mt76x02: ommit beacon slot clearing

mt76 hw does not send beacons from beacon slots, if the corresponding
bitmask is set accordingly. Therefore we can ommit clearing the beacon
memory. Clearing uses many usb calls, if usb drivers are used. These
calls unnecessarily slow down the beacon tasklet. Thanks to Stanislaw
Gruzska for pointing this out.

Signed-off-by: Markus Theil <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c | 10 ----------
1 file changed, 10 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
index 4209209ac940..54fe449f01c9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
@@ -56,10 +56,6 @@ __mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 bcn_idx,
ret = mt76x02_write_beacon(dev, beacon_addr, skb);
if (!ret)
dev->beacon_data_mask |= BIT(bcn_idx);
- } else {
- dev->beacon_data_mask &= ~BIT(bcn_idx);
- for (i = 0; i < beacon_len; i += 4)
- mt76_wr(dev, beacon_addr + i, 0);
}

mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xff00 | ~dev->beacon_data_mask);
@@ -241,17 +237,11 @@ EXPORT_SYMBOL_GPL(mt76x02_enqueue_buffered_bc);

void mt76x02_init_beacon_config(struct mt76x02_dev *dev)
{
- int i;
-
mt76_clear(dev, MT_BEACON_TIME_CFG, (MT_BEACON_TIME_CFG_TIMER_EN |
MT_BEACON_TIME_CFG_TBTT_EN |
MT_BEACON_TIME_CFG_BEACON_TX));
mt76_set(dev, MT_BEACON_TIME_CFG, MT_BEACON_TIME_CFG_SYNC_MODE);
mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xffff);
-
- for (i = 0; i < 8; i++)
- mt76x02_mac_set_beacon(dev, i, NULL);
-
mt76x02_set_beacon_offsets(dev);
}
EXPORT_SYMBOL_GPL(mt76x02_init_beacon_config);
--
2.24.0

2019-11-16 11:23:11

by Markus Theil

[permalink] [raw]
Subject: [PATCH 3/4] mt76: speed up usb bulk copy

Use larger batches for usb copy to speed this operation up. Otherwise it
would be too slow for copying new beacons or broadcast frames over usb.

Signed-off-by: Markus Theil <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 2 +-
.../wireless/mediatek/mt76/mt76x02_beacon.c | 1 -
drivers/net/wireless/mediatek/mt76/usb.c | 22 ++++++++++++++-----
3 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 8aec7ccf2d79..7a6f5d097a3d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -383,7 +383,7 @@ enum mt76u_out_ep {
struct mt76_usb {
struct mutex usb_ctrl_mtx;
union {
- u8 data[32];
+ u8 data[128];
__le32 reg_val;
};

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
index 47207b790bf9..8b2f7a0d58b5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
@@ -86,7 +86,6 @@ int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
dev->beacons[vif_idx] = skb;
__mt76x02_mac_set_beacon(dev, vif_idx, skb);

-
return 0;
}
EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon);
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 20c6fe510e9d..6183105166ec 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -149,18 +149,28 @@ static void mt76u_copy(struct mt76_dev *dev, u32 offset,
const void *data, int len)
{
struct mt76_usb *usb = &dev->usb;
- const u32 *val = data;
- int i, ret;
+ const u8 *val = data;
+ int ret;
+ const int batch_size_max = sizeof(usb->data);
+ int current_batch_size;
+ int i = 0;

mutex_lock(&usb->usb_ctrl_mtx);
- for (i = 0; i < DIV_ROUND_UP(len, 4); i++) {
- put_unaligned(val[i], (u32 *)usb->data);
+ while (i < len) {
+ if(len - i > batch_size_max) {
+ current_batch_size = batch_size_max;
+ } else {
+ current_batch_size = len - i;
+ }
+ memcpy(usb->data, val + i, current_batch_size);
ret = __mt76u_vendor_request(dev, MT_VEND_MULTI_WRITE,
USB_DIR_OUT | USB_TYPE_VENDOR,
- 0, offset + i * 4, usb->data,
- sizeof(u32));
+ 0, offset + i, usb->data,
+ current_batch_size);
if (ret < 0)
break;
+
+ i += current_batch_size;
}
mutex_unlock(&usb->usb_ctrl_mtx);
}
--
2.24.0

2019-11-16 11:23:16

by Markus Theil

[permalink] [raw]
Subject: [PATCH 4/4] mt76: mt76x02: add channel switch support for usb interfaces

This patch enables channel switch support on mt76 usb interfaces.

Signed-off-by: Markus Theil <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c | 7 +++++++
drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c | 5 +++++
3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index aedab4cc8d40..32e6c37aa80d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -179,6 +179,12 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)

mt76x02_resync_beacon_timer(dev);

+ mt76_csa_check(&dev->mt76);
+ if (dev->mt76.csa_complete) {
+ mt76_csa_finish(&dev->mt76);
+ goto out;
+ }
+
mt76x02_mac_set_beacon_prepare(dev);

ieee80211_iterate_active_interfaces(mt76_hw(dev),
@@ -195,6 +201,7 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)

mt76x02_mac_set_beacon_finish(dev);

+out:
mt76x02u_restart_pre_tbtt_timer(dev);
}

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 414b22399d93..3f95e5b24e1d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -174,7 +174,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->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;

/* init led callbacks */
if (IS_ENABLED(CONFIG_MT76_LEDS)) {
@@ -184,6 +183,7 @@ void mt76x02_init_device(struct mt76x02_dev *dev)
}
}

+ wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);

hw->sta_data_size = sizeof(struct mt76x02_sta);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
index eb73cb856c81..2f2c39a6a9e6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
@@ -100,6 +100,10 @@ mt76x2u_config(struct ieee80211_hw *hw, u32 changed)
return err;
}

+void mt76x2u_channel_switch_beacon(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct cfg80211_chan_def *chandef) {}
+
const struct ieee80211_ops mt76x2u_ops = {
.tx = mt76x02_tx,
.start = mt76x2u_start,
@@ -121,4 +125,5 @@ const struct ieee80211_ops mt76x2u_ops = {
.get_survey = mt76_get_survey,
.set_tim = mt76_set_tim,
.release_buffered_frames = mt76_release_buffered_frames,
+ .channel_switch_beacon = mt76x2u_channel_switch_beacon,
};
--
2.24.0

2019-11-16 11:23:17

by Markus Theil

[permalink] [raw]
Subject: [PATCH 2/4] mt76: mt76x02: split beaconing

Sending beacons to the hardware always happens in batches. In order to
speed up beacon processing on usb devices, this patch splits out common
code an calls it only once (mt76x02_mac_set_beacon_prepare,
mt76x02_mac_set_beacon_finish). Making this split breaks beacon
enabling/disabling per vif. This is fixed by adding a call to set the
bypass mask, if beaconing should be disabled for a vif. Otherwise the
beacon is send after the next beacon interval.

The code is also adapted for the mmio part of the driver, but should not
have any performance implication there.

Signed-off-by: Markus Theil <[email protected]>
---
.../wireless/mediatek/mt76/mt76x02_beacon.c | 53 +++++++++----------
.../net/wireless/mediatek/mt76/mt76x02_mac.h | 2 +
.../net/wireless/mediatek/mt76/mt76x02_mmio.c | 4 ++
.../wireless/mediatek/mt76/mt76x02_usb_core.c | 4 ++
4 files changed, 34 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
index 54fe449f01c9..47207b790bf9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
@@ -47,10 +47,6 @@ __mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 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;
-
- /* Prevent corrupt transmissions during update */
- mt76_set(dev, MT_BCN_BYPASS_MASK, BIT(bcn_idx));

if (skb) {
ret = mt76x02_write_beacon(dev, beacon_addr, skb);
@@ -58,41 +54,39 @@ __mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 bcn_idx,
dev->beacon_data_mask |= BIT(bcn_idx);
}

- mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xff00 | ~dev->beacon_data_mask);
-
return ret;
}

-int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
- struct sk_buff *skb)
-{
- bool force_update = false;
- int bcn_idx = 0;
- int i;
+void mt76x02_mac_set_beacon_prepare(struct mt76x02_dev *dev) {
+ /* Prevent corrupt transmissions during update */
+ mt76_set(dev, MT_BCN_BYPASS_MASK, 0xffff);
+}
+EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon_prepare);

- for (i = 0; i < ARRAY_SIZE(dev->beacons); i++) {
- if (vif_idx == i) {
- force_update = !!dev->beacons[i] ^ !!skb;
- dev_kfree_skb(dev->beacons[i]);
- dev->beacons[i] = skb;
- __mt76x02_mac_set_beacon(dev, bcn_idx, skb);
- } else if (force_update && dev->beacons[i]) {
- __mt76x02_mac_set_beacon(dev, bcn_idx,
- dev->beacons[i]);
- }
+void mt76x02_mac_set_beacon_finish(struct mt76x02_dev *dev) {
+ int i;
+ int bcn_idx = 0;
+ int nbeacons = hweight8(dev->mt76.beacon_mask);

+ for(i = 0; i < nbeacons; ++i) {
bcn_idx += !!dev->beacons[i];
}

- for (i = bcn_idx; i < ARRAY_SIZE(dev->beacons); i++) {
- if (!(dev->beacon_data_mask & BIT(i)))
- break;
-
- __mt76x02_mac_set_beacon(dev, i, NULL);
- }
-
mt76_rmw_field(dev, MT_MAC_BSSID_DW1, MT_MAC_BSSID_DW1_MBEACON_N,
bcn_idx - 1);
+
+ mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xff00 | ~dev->beacon_data_mask);
+}
+EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon_finish);
+
+int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
+ struct sk_buff *skb)
+{
+ dev_kfree_skb(dev->beacons[vif_idx]);
+ dev->beacons[vif_idx] = skb;
+ __mt76x02_mac_set_beacon(dev, vif_idx, skb);
+
+
return 0;
}
EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon);
@@ -113,6 +107,7 @@ void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
} else {
dev->mt76.beacon_mask &= ~BIT(mvif->idx);
mt76x02_mac_set_beacon(dev, mvif->idx, NULL);
+ mt76_set(dev, MT_BCN_BYPASS_MASK, BIT(mvif->idx));
}

if (!!old_mask == !!dev->mt76.beacon_mask)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
index efa4ef945e35..4e717640eef6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
@@ -197,6 +197,8 @@ int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
struct sk_buff *skb);
void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
struct ieee80211_vif *vif, bool enable);
+void mt76x02_mac_set_beacon_prepare(struct mt76x02_dev *dev);
+void mt76x02_mac_set_beacon_finish(struct mt76x02_dev *dev);

void mt76x02_edcca_init(struct mt76x02_dev *dev);
#endif
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index dc773070481d..b8b4c6a67d39 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -24,10 +24,14 @@ static void mt76x02_pre_tbtt_tasklet(unsigned long arg)

mt76x02_resync_beacon_timer(dev);

+ mt76x02_mac_set_beacon_prepare(dev);
+
ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
IEEE80211_IFACE_ITER_RESUME_ALL,
mt76x02_update_beacon_iter, dev);

+ mt76x02_mac_set_beacon_finish(dev);
+
mt76_csa_check(&dev->mt76);

if (dev->mt76.csa_complete)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index 78dfc1e7f27b..aedab4cc8d40 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -179,6 +179,8 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)

mt76x02_resync_beacon_timer(dev);

+ mt76x02_mac_set_beacon_prepare(dev);
+
ieee80211_iterate_active_interfaces(mt76_hw(dev),
IEEE80211_IFACE_ITER_RESUME_ALL,
mt76x02_update_beacon_iter, dev);
@@ -191,6 +193,8 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
mt76x02_mac_set_beacon(dev, i, skb);
}

+ mt76x02_mac_set_beacon_finish(dev);
+
mt76x02u_restart_pre_tbtt_timer(dev);
}

--
2.24.0

2019-11-16 11:44:14

by Lorenzo Bianconi

[permalink] [raw]
Subject: Re: [PATCH 3/4] mt76: speed up usb bulk copy

> Use larger batches for usb copy to speed this operation up. Otherwise it
> would be too slow for copying new beacons or broadcast frames over usb.
>
> Signed-off-by: Markus Theil <[email protected]>
> ---

Hi Markus,

> drivers/net/wireless/mediatek/mt76/mt76.h | 2 +-
> .../wireless/mediatek/mt76/mt76x02_beacon.c | 1 -
> drivers/net/wireless/mediatek/mt76/usb.c | 22 ++++++++++++++-----
> 3 files changed, 17 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
> index 8aec7ccf2d79..7a6f5d097a3d 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> @@ -383,7 +383,7 @@ enum mt76u_out_ep {
> struct mt76_usb {
> struct mutex usb_ctrl_mtx;
> union {
> - u8 data[32];
> + u8 data[128];
> __le32 reg_val;
> };
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> index 47207b790bf9..8b2f7a0d58b5 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> @@ -86,7 +86,6 @@ int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
> dev->beacons[vif_idx] = skb;
> __mt76x02_mac_set_beacon(dev, vif_idx, skb);
>
> -
> return 0;
> }
> EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon);
> diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
> index 20c6fe510e9d..6183105166ec 100644
> --- a/drivers/net/wireless/mediatek/mt76/usb.c
> +++ b/drivers/net/wireless/mediatek/mt76/usb.c
> @@ -149,18 +149,28 @@ static void mt76u_copy(struct mt76_dev *dev, u32 offset,
> const void *data, int len)
> {
> struct mt76_usb *usb = &dev->usb;
> - const u32 *val = data;
> - int i, ret;
> + const u8 *val = data;
> + int ret;
> + const int batch_size_max = sizeof(usb->data);
> + int current_batch_size;
> + int i = 0;
>
> mutex_lock(&usb->usb_ctrl_mtx);
> - for (i = 0; i < DIV_ROUND_UP(len, 4); i++) {
> - put_unaligned(val[i], (u32 *)usb->data);
> + while (i < len) {
> + if(len - i > batch_size_max) {
> + current_batch_size = batch_size_max;
> + } else {
> + current_batch_size = len - i;
> + }

current_batch_size = min(sizeof(usb->data), len - i);

> + memcpy(usb->data, val + i, current_batch_size);
> ret = __mt76u_vendor_request(dev, MT_VEND_MULTI_WRITE,
> USB_DIR_OUT | USB_TYPE_VENDOR,
> - 0, offset + i * 4, usb->data,
> - sizeof(u32));
> + 0, offset + i, usb->data,
> + current_batch_size);

@Stanislaw: I vaguely remember you reported some issues if the burst size
is greater than 4B (but I can be wrong)

> if (ret < 0)
> break;
> +
> + i += current_batch_size;
> }
> mutex_unlock(&usb->usb_ctrl_mtx);
> }
> --
> 2.24.0
>


Attachments:
(No filename) (2.91 kB)
signature.asc (235.00 B)
Download all attachments

2019-11-16 11:44:57

by Markus Theil

[permalink] [raw]
Subject: Re: [PATCH 1/4] mt76: mt76x02: ommit beacon slot clearing

On 11/16/19 12:17 PM, Markus Theil wrote:
> mt76 hw does not send beacons from beacon slots, if the corresponding
> bitmask is set accordingly. Therefore we can ommit clearing the beacon
> memory. Clearing uses many usb calls, if usb drivers are used. These
> calls unnecessarily slow down the beacon tasklet. Thanks to Stanislaw
> Gruzska for pointing this out.
>
> Signed-off-by: Markus Theil <[email protected]>
> ---
> drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c | 10 ----------
> 1 file changed, 10 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> index 4209209ac940..54fe449f01c9 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> @@ -56,10 +56,6 @@ __mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 bcn_idx,
> ret = mt76x02_write_beacon(dev, beacon_addr, skb);
> if (!ret)
> dev->beacon_data_mask |= BIT(bcn_idx);
> - } else {
> - dev->beacon_data_mask &= ~BIT(bcn_idx);

I've noticed, that I have to keep the line above, in order to correctly
track the beacon_data_mask.
I'll correct it in the next version.

> - for (i = 0; i < beacon_len; i += 4)
> - mt76_wr(dev, beacon_addr + i, 0);
> }
>
> mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xff00 | ~dev->beacon_data_mask);
> @@ -241,17 +237,11 @@ EXPORT_SYMBOL_GPL(mt76x02_enqueue_buffered_bc);
>
> void mt76x02_init_beacon_config(struct mt76x02_dev *dev)
> {
> - int i;
> -
> mt76_clear(dev, MT_BEACON_TIME_CFG, (MT_BEACON_TIME_CFG_TIMER_EN |
> MT_BEACON_TIME_CFG_TBTT_EN |
> MT_BEACON_TIME_CFG_BEACON_TX));
> mt76_set(dev, MT_BEACON_TIME_CFG, MT_BEACON_TIME_CFG_SYNC_MODE);
> mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xffff);
> -
> - for (i = 0; i < 8; i++)
> - mt76x02_mac_set_beacon(dev, i, NULL);
> -
> mt76x02_set_beacon_offsets(dev);
> }
> EXPORT_SYMBOL_GPL(mt76x02_init_beacon_config);

--
Markus Theil

Technische Universität Ilmenau, Fachgebiet Telematik/Rechnernetze
Postfach 100565
98684 Ilmenau, Germany

Phone: +49 3677 69-4582
Email: markus[dot]theil[at]tu-ilmenau[dot]de
Web: http://www.tu-ilmenau.de/telematik

2019-11-16 11:45:55

by Lorenzo Bianconi

[permalink] [raw]
Subject: Re: [PATCH 4/4] mt76: mt76x02: add channel switch support for usb interfaces

> This patch enables channel switch support on mt76 usb interfaces.
>

Hi Markus,

I was thinking about it, but since usb does not support DFS what is the purpose
of CSA in this case?

Regards,
Lorenzo

> Signed-off-by: Markus Theil <[email protected]>
> ---
> drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c | 7 +++++++
> drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 2 +-
> drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c | 5 +++++
> 3 files changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
> index aedab4cc8d40..32e6c37aa80d 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
> @@ -179,6 +179,12 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
>
> mt76x02_resync_beacon_timer(dev);
>
> + mt76_csa_check(&dev->mt76);
> + if (dev->mt76.csa_complete) {
> + mt76_csa_finish(&dev->mt76);
> + goto out;
> + }
> +
> mt76x02_mac_set_beacon_prepare(dev);
>
> ieee80211_iterate_active_interfaces(mt76_hw(dev),
> @@ -195,6 +201,7 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
>
> mt76x02_mac_set_beacon_finish(dev);
>
> +out:
> mt76x02u_restart_pre_tbtt_timer(dev);
> }
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> index 414b22399d93..3f95e5b24e1d 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> @@ -174,7 +174,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->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
>
> /* init led callbacks */
> if (IS_ENABLED(CONFIG_MT76_LEDS)) {
> @@ -184,6 +183,7 @@ void mt76x02_init_device(struct mt76x02_dev *dev)
> }
> }
>
> + wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
> wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
>
> hw->sta_data_size = sizeof(struct mt76x02_sta);
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
> index eb73cb856c81..2f2c39a6a9e6 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
> @@ -100,6 +100,10 @@ mt76x2u_config(struct ieee80211_hw *hw, u32 changed)
> return err;
> }
>
> +void mt76x2u_channel_switch_beacon(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif,
> + struct cfg80211_chan_def *chandef) {}
> +
> const struct ieee80211_ops mt76x2u_ops = {
> .tx = mt76x02_tx,
> .start = mt76x2u_start,
> @@ -121,4 +125,5 @@ const struct ieee80211_ops mt76x2u_ops = {
> .get_survey = mt76_get_survey,
> .set_tim = mt76_set_tim,
> .release_buffered_frames = mt76_release_buffered_frames,
> + .channel_switch_beacon = mt76x2u_channel_switch_beacon,
> };
> --
> 2.24.0
>


Attachments:
(No filename) (3.18 kB)
signature.asc (235.00 B)
Download all attachments

2019-11-16 12:14:15

by Markus Theil

[permalink] [raw]
Subject: Re: [PATCH 4/4] mt76: mt76x02: add channel switch support for usb interfaces

On 11/16/19 12:45 PM, Lorenzo Bianconi wrote:
>> This patch enables channel switch support on mt76 usb interfaces.
>>
> Hi Markus,
>
> I was thinking about it, but since usb does not support DFS what is the purpose
> of CSA in this case?
>
> Regards,
> Lorenzo

Hi Lorenzo,

for research purposes I'm currently trying out some dynamic channel
allocation strategies with multiple indoor APs. I use a dedicated
interface to perform surveys and monitoring the environment. These
survey results are then correlated between different with traffic
patterns to find out interferers. Afterwards I let the AP interfaces
change their channel to a less congested one if necessary and notice the
STAs via CSAs.

I use mt76 based USB devices for my tests as they are quite versatile
and useful for debugging with a notebook (I can just attach multiple
ones). Therefore I thought, having the possibility to dynamically switch
channels on this devices would maybe useful to other researchers and
submitted my patches.

Regards,
Markus

>> Signed-off-by: Markus Theil <[email protected]>
>> ---
>> drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c | 7 +++++++
>> drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 2 +-
>> drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c | 5 +++++
>> 3 files changed, 13 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
>> index aedab4cc8d40..32e6c37aa80d 100644
>> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
>> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
>> @@ -179,6 +179,12 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
>>
>> mt76x02_resync_beacon_timer(dev);
>>
>> + mt76_csa_check(&dev->mt76);
>> + if (dev->mt76.csa_complete) {
>> + mt76_csa_finish(&dev->mt76);
>> + goto out;
>> + }
>> +
>> mt76x02_mac_set_beacon_prepare(dev);
>>
>> ieee80211_iterate_active_interfaces(mt76_hw(dev),
>> @@ -195,6 +201,7 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
>>
>> mt76x02_mac_set_beacon_finish(dev);
>>
>> +out:
>> mt76x02u_restart_pre_tbtt_timer(dev);
>> }
>>
>> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
>> index 414b22399d93..3f95e5b24e1d 100644
>> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
>> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
>> @@ -174,7 +174,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->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
>>
>> /* init led callbacks */
>> if (IS_ENABLED(CONFIG_MT76_LEDS)) {
>> @@ -184,6 +183,7 @@ void mt76x02_init_device(struct mt76x02_dev *dev)
>> }
>> }
>>
>> + wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
>> wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
>>
>> hw->sta_data_size = sizeof(struct mt76x02_sta);
>> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
>> index eb73cb856c81..2f2c39a6a9e6 100644
>> --- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
>> +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
>> @@ -100,6 +100,10 @@ mt76x2u_config(struct ieee80211_hw *hw, u32 changed)
>> return err;
>> }
>>
>> +void mt76x2u_channel_switch_beacon(struct ieee80211_hw *hw,
>> + struct ieee80211_vif *vif,
>> + struct cfg80211_chan_def *chandef) {}
>> +
>> const struct ieee80211_ops mt76x2u_ops = {
>> .tx = mt76x02_tx,
>> .start = mt76x2u_start,
>> @@ -121,4 +125,5 @@ const struct ieee80211_ops mt76x2u_ops = {
>> .get_survey = mt76_get_survey,
>> .set_tim = mt76_set_tim,
>> .release_buffered_frames = mt76_release_buffered_frames,
>> + .channel_switch_beacon = mt76x2u_channel_switch_beacon,
>> };
>> --
>> 2.24.0
>>
--
Markus Theil

Technische Universit?t Ilmenau, Fachgebiet Telematik/Rechnernetze
Postfach 100565
98684 Ilmenau, Germany

Phone: +49 3677 69-4582
Email: markus[dot]theil[at]tu-ilmenau[dot]de
Web: http://www.tu-ilmenau.de/telematik


2019-11-16 12:44:44

by Lorenzo Bianconi

[permalink] [raw]
Subject: Re: [PATCH 4/4] mt76: mt76x02: add channel switch support for usb interfaces

> On 11/16/19 12:45 PM, Lorenzo Bianconi wrote:
> >> This patch enables channel switch support on mt76 usb interfaces.
> >>
> > Hi Markus,
> >
> > I was thinking about it, but since usb does not support DFS what is the purpose
> > of CSA in this case?
> >
> > Regards,
> > Lorenzo
>
> Hi Lorenzo,
>
> for research purposes I'm currently trying out some dynamic channel
> allocation strategies with multiple indoor APs. I use a dedicated
> interface to perform surveys and monitoring the environment. These
> survey results are then correlated between different with traffic
> patterns to find out interferers. Afterwards I let the AP interfaces
> change their channel to a less congested one if necessary and notice the
> STAs via CSAs.
>
> I use mt76 based USB devices for my tests as they are quite versatile
> and useful for debugging with a notebook (I can just attach multiple
> ones). Therefore I thought, having the possibility to dynamically switch
> channels on this devices would maybe useful to other researchers and
> submitted my patches.
>
> Regards,
> Markus

ack, sounds good to me.

Regards,
Lorenzo

>
> >> Signed-off-by: Markus Theil <[email protected]>
> >> ---
> >> drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c | 7 +++++++
> >> drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 2 +-
> >> drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c | 5 +++++
> >> 3 files changed, 13 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
> >> index aedab4cc8d40..32e6c37aa80d 100644
> >> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
> >> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
> >> @@ -179,6 +179,12 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
> >>
> >> mt76x02_resync_beacon_timer(dev);
> >>
> >> + mt76_csa_check(&dev->mt76);
> >> + if (dev->mt76.csa_complete) {
> >> + mt76_csa_finish(&dev->mt76);
> >> + goto out;
> >> + }
> >> +
> >> mt76x02_mac_set_beacon_prepare(dev);
> >>
> >> ieee80211_iterate_active_interfaces(mt76_hw(dev),
> >> @@ -195,6 +201,7 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
> >>
> >> mt76x02_mac_set_beacon_finish(dev);
> >>
> >> +out:
> >> mt76x02u_restart_pre_tbtt_timer(dev);
> >> }
> >>
> >> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> >> index 414b22399d93..3f95e5b24e1d 100644
> >> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> >> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
> >> @@ -174,7 +174,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->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
> >>
> >> /* init led callbacks */
> >> if (IS_ENABLED(CONFIG_MT76_LEDS)) {
> >> @@ -184,6 +183,7 @@ void mt76x02_init_device(struct mt76x02_dev *dev)
> >> }
> >> }
> >>
> >> + wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
> >> wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
> >>
> >> hw->sta_data_size = sizeof(struct mt76x02_sta);
> >> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
> >> index eb73cb856c81..2f2c39a6a9e6 100644
> >> --- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
> >> +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
> >> @@ -100,6 +100,10 @@ mt76x2u_config(struct ieee80211_hw *hw, u32 changed)
> >> return err;
> >> }
> >>
> >> +void mt76x2u_channel_switch_beacon(struct ieee80211_hw *hw,
> >> + struct ieee80211_vif *vif,
> >> + struct cfg80211_chan_def *chandef) {}
> >> +
> >> const struct ieee80211_ops mt76x2u_ops = {
> >> .tx = mt76x02_tx,
> >> .start = mt76x2u_start,
> >> @@ -121,4 +125,5 @@ const struct ieee80211_ops mt76x2u_ops = {
> >> .get_survey = mt76_get_survey,
> >> .set_tim = mt76_set_tim,
> >> .release_buffered_frames = mt76_release_buffered_frames,
> >> + .channel_switch_beacon = mt76x2u_channel_switch_beacon,
> >> };
> >> --
> >> 2.24.0
> >>
> --
> Markus Theil
>
> Technische Universit?t Ilmenau, Fachgebiet Telematik/Rechnernetze
> Postfach 100565
> 98684 Ilmenau, Germany
>
> Phone: +49 3677 69-4582
> Email: markus[dot]theil[at]tu-ilmenau[dot]de
> Web: http://www.tu-ilmenau.de/telematik
>
>


Attachments:
(No filename) (4.59 kB)
signature.asc (235.00 B)
Download all attachments

2019-11-16 12:53:19

by Lorenzo Bianconi

[permalink] [raw]
Subject: Re: [PATCH 2/4] mt76: mt76x02: split beaconing

> Sending beacons to the hardware always happens in batches. In order to
> speed up beacon processing on usb devices, this patch splits out common
> code an calls it only once (mt76x02_mac_set_beacon_prepare,
> mt76x02_mac_set_beacon_finish). Making this split breaks beacon
> enabling/disabling per vif. This is fixed by adding a call to set the
> bypass mask, if beaconing should be disabled for a vif. Otherwise the
> beacon is send after the next beacon interval.
>
> The code is also adapted for the mmio part of the driver, but should not
> have any performance implication there.
>
> Signed-off-by: Markus Theil <[email protected]>
> ---
> .../wireless/mediatek/mt76/mt76x02_beacon.c | 53 +++++++++----------
> .../net/wireless/mediatek/mt76/mt76x02_mac.h | 2 +
> .../net/wireless/mediatek/mt76/mt76x02_mmio.c | 4 ++
> .../wireless/mediatek/mt76/mt76x02_usb_core.c | 4 ++
> 4 files changed, 34 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> index 54fe449f01c9..47207b790bf9 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> @@ -47,10 +47,6 @@ __mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 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;
> -
> - /* Prevent corrupt transmissions during update */
> - mt76_set(dev, MT_BCN_BYPASS_MASK, BIT(bcn_idx));
>
> if (skb) {
> ret = mt76x02_write_beacon(dev, beacon_addr, skb);
> @@ -58,41 +54,39 @@ __mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 bcn_idx,
> dev->beacon_data_mask |= BIT(bcn_idx);
> }
>
> - mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xff00 | ~dev->beacon_data_mask);
> -
> return ret;
> }
>
> -int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
> - struct sk_buff *skb)
> -{
> - bool force_update = false;
> - int bcn_idx = 0;
> - int i;
> +void mt76x02_mac_set_beacon_prepare(struct mt76x02_dev *dev) {
> + /* Prevent corrupt transmissions during update */
> + mt76_set(dev, MT_BCN_BYPASS_MASK, 0xffff);

Do we really need it? I guess just call mt76_set(dev, MT_BCN_BYPASS_MASK, 0xffff)
directly

> +}
> +EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon_prepare);
>
> - for (i = 0; i < ARRAY_SIZE(dev->beacons); i++) {
> - if (vif_idx == i) {
> - force_update = !!dev->beacons[i] ^ !!skb;
> - dev_kfree_skb(dev->beacons[i]);
> - dev->beacons[i] = skb;
> - __mt76x02_mac_set_beacon(dev, bcn_idx, skb);
> - } else if (force_update && dev->beacons[i]) {
> - __mt76x02_mac_set_beacon(dev, bcn_idx,
> - dev->beacons[i]);
> - }
> +void mt76x02_mac_set_beacon_finish(struct mt76x02_dev *dev) {
> + int i;
> + int bcn_idx = 0;
> + int nbeacons = hweight8(dev->mt76.beacon_mask);
>
> + for(i = 0; i < nbeacons; ++i) {

for (i = 0; i < hweight8(dev->mt76.beacon_mask); i++)
bcn_idx += !!dev->beacons[i];

> bcn_idx += !!dev->beacons[i];
> }
>
> - for (i = bcn_idx; i < ARRAY_SIZE(dev->beacons); i++) {
> - if (!(dev->beacon_data_mask & BIT(i)))
> - break;
> -
> - __mt76x02_mac_set_beacon(dev, i, NULL);
> - }
> -
> mt76_rmw_field(dev, MT_MAC_BSSID_DW1, MT_MAC_BSSID_DW1_MBEACON_N,
> bcn_idx - 1);
> +
> + mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xff00 | ~dev->beacon_data_mask);
> +}
> +EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon_finish);
> +
> +int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
> + struct sk_buff *skb)
> +{
> + dev_kfree_skb(dev->beacons[vif_idx]);
> + dev->beacons[vif_idx] = skb;
> + __mt76x02_mac_set_beacon(dev, vif_idx, skb);
> +
> +
> return 0;
> }
> EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon);
> @@ -113,6 +107,7 @@ void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
> } else {
> dev->mt76.beacon_mask &= ~BIT(mvif->idx);
> mt76x02_mac_set_beacon(dev, mvif->idx, NULL);
> + mt76_set(dev, MT_BCN_BYPASS_MASK, BIT(mvif->idx));
> }
>
> if (!!old_mask == !!dev->mt76.beacon_mask)
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
> index efa4ef945e35..4e717640eef6 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
> @@ -197,6 +197,8 @@ int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
> struct sk_buff *skb);
> void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
> struct ieee80211_vif *vif, bool enable);
> +void mt76x02_mac_set_beacon_prepare(struct mt76x02_dev *dev);
> +void mt76x02_mac_set_beacon_finish(struct mt76x02_dev *dev);
>
> void mt76x02_edcca_init(struct mt76x02_dev *dev);
> #endif
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
> index dc773070481d..b8b4c6a67d39 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
> @@ -24,10 +24,14 @@ static void mt76x02_pre_tbtt_tasklet(unsigned long arg)
>
> mt76x02_resync_beacon_timer(dev);
>
> + mt76x02_mac_set_beacon_prepare(dev);
> +
> ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
> IEEE80211_IFACE_ITER_RESUME_ALL,
> mt76x02_update_beacon_iter, dev);
>
> + mt76x02_mac_set_beacon_finish(dev);
> +
> mt76_csa_check(&dev->mt76);
>
> if (dev->mt76.csa_complete)
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
> index 78dfc1e7f27b..aedab4cc8d40 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
> @@ -179,6 +179,8 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
>
> mt76x02_resync_beacon_timer(dev);
>
> + mt76x02_mac_set_beacon_prepare(dev);
> +
> ieee80211_iterate_active_interfaces(mt76_hw(dev),
> IEEE80211_IFACE_ITER_RESUME_ALL,
> mt76x02_update_beacon_iter, dev);
> @@ -191,6 +193,8 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
> mt76x02_mac_set_beacon(dev, i, skb);
> }
>
> + mt76x02_mac_set_beacon_finish(dev);
> +
> mt76x02u_restart_pre_tbtt_timer(dev);
> }
>
> --
> 2.24.0
>


Attachments:
(No filename) (6.35 kB)
signature.asc (235.00 B)
Download all attachments

2019-11-17 03:45:10

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 4/4] mt76: mt76x02: add channel switch support for usb interfaces

Hi Markus,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on wireless-drivers-next/master]
[cannot apply to v5.4-rc7 next-20191115]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url: https://github.com/0day-ci/linux/commits/Markus-Theil/mt76-channel-switch-support-for-USB-devices/20191116-192204
base: https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master
reproduce:
# apt-get install sparse
# sparse version: v0.6.1-32-g233d4e1-dirty
make ARCH=x86_64 allmodconfig
make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <[email protected]>


sparse warnings: (new ones prefixed by >>)

>> drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c:103:6: sparse: sparse: symbol 'mt76x2u_channel_switch_beacon' was not declared. Should it be static?

Please review and possibly fold the followup patch.

---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/hyperkitty/list/[email protected] Intel Corporation

2019-11-17 03:46:30

by kernel test robot

[permalink] [raw]
Subject: [RFC PATCH] mt76: mt76x02: mt76x2u_channel_switch_beacon() can be static


Fixes: 919c09d543ec ("mt76: mt76x02: add channel switch support for usb interfaces")
Signed-off-by: kbuild test robot <[email protected]>
---
usb_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
index 2f2c39a6a9e6c..ee88ec1f488b0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
@@ -100,7 +100,7 @@ mt76x2u_config(struct ieee80211_hw *hw, u32 changed)
return err;
}

-void mt76x2u_channel_switch_beacon(struct ieee80211_hw *hw,
+static void mt76x2u_channel_switch_beacon(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_chan_def *chandef) {}

2019-11-19 11:02:17

by Stanislaw Gruszka

[permalink] [raw]
Subject: Re: [PATCH 3/4] mt76: speed up usb bulk copy

On Sat, Nov 16, 2019 at 01:43:12PM +0200, Lorenzo Bianconi wrote:
> > + memcpy(usb->data, val + i, current_batch_size);
> > ret = __mt76u_vendor_request(dev, MT_VEND_MULTI_WRITE,
> > USB_DIR_OUT | USB_TYPE_VENDOR,
> > - 0, offset + i * 4, usb->data,
> > - sizeof(u32));
> > + 0, offset + i, usb->data,
> > + current_batch_size);
>
> @Stanislaw: I vaguely remember you reported some issues if the burst size
> is greater than 4B (but I can be wrong)

It didn't work as usb vendor requests which were not multiple of 4
were not transferred to the device on some usb host. But this is
properly handled by the latest version of this patch set.

Stanislaw