linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v9 0/6] mt76: channel switch support for USB devices
@ 2019-11-26 21:46 Markus Theil
  2019-11-26 21:46 ` [PATCH v9 1/6] mt76: mt76x02: ommit beacon slot clearing Markus Theil
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Markus Theil @ 2019-11-26 21:46 UTC (permalink / raw)
  To: nbd; +Cc: linux-wireless, lorenzo.bianconi, Stanislaw Gruszka, Markus Theil

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 five patches speed up beacon copying and provide beaconing
fixes. The last patch enables channel switch support also for usb interfaces.

Thanks to Stanislaw, Lorenzo and Felix for their help.

v9:
* use beacon_data_count instead of beacon_data_mask
* add missing txwi copy again
* move csa_check for usb under beacon iteration (send beacons and no ps frames
  in case of finished csa)

v8:
* fix mbss beaconing
* fix adding vifs with idx 8
* fix memory leaks by dropping beacon buffer
* permanently enable 7 additional bss to save another usb call and make
  beacon masking easier
* added beacon_prepare call again, which now also clears beacon_data_mask

v7:
* fix mbss beacon settings (incorrect try)
* fix compilation with latest upstream

v6:
* use min_t in mt76u_copy
* use round_up in mt76u_copy
* use additional copy for mmio beacon set again

v5:
* ommit empty mt76x2u_channel_switch_beacon
* copy txwi into beacon skb

v4:
* use multiple of 4 len for usb copy again

v3:
* fixed checkpatch errors

v2:
* correctly track beacon data mask
* clean-ups
* make channel switch fn static (reported by kbuild test robot)

Markus Theil (6):
  mt76: mt76x02: ommit beacon slot clearing
  mt76: mt76x02: split beaconing
  mt76: mt76x02: add check for invalid vif idx
  mt76: mt76x02: remove a copy call for usb speedup
  mt76: speed up usb bulk copy
  mt76: mt76x02: add channel switch support for usb interfaces

 drivers/net/wireless/mediatek/mt76/mt76.h     |  2 +-
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  3 +-
 .../wireless/mediatek/mt76/mt76x02_beacon.c   | 97 +++++++------------
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  |  2 +
 .../net/wireless/mediatek/mt76/mt76x02_mac.h  |  5 +-
 .../net/wireless/mediatek/mt76/mt76x02_mmio.c |  4 +
 .../wireless/mediatek/mt76/mt76x02_usb_core.c | 22 +++--
 .../net/wireless/mediatek/mt76/mt76x02_util.c |  6 +-
 drivers/net/wireless/mediatek/mt76/usb.c      | 24 +++--
 9 files changed, 85 insertions(+), 80 deletions(-)

-- 
2.24.0


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

* [PATCH v9 1/6] mt76: mt76x02: ommit beacon slot clearing
  2019-11-26 21:46 [PATCH v9 0/6] mt76: channel switch support for USB devices Markus Theil
@ 2019-11-26 21:46 ` Markus Theil
  2019-11-26 21:47 ` [PATCH v9 2/6] mt76: mt76x02: split beaconing Markus Theil
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Markus Theil @ 2019-11-26 21:46 UTC (permalink / raw)
  To: nbd; +Cc: linux-wireless, lorenzo.bianconi, Stanislaw Gruszka, Markus Theil

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 <markus.theil@tu-ilmenau.de>
---
 drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
index 4209209ac940..403866496640 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
@@ -58,8 +58,6 @@ __mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 bcn_idx,
 			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 +239,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


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

* [PATCH v9 2/6] mt76: mt76x02: split beaconing
  2019-11-26 21:46 [PATCH v9 0/6] mt76: channel switch support for USB devices Markus Theil
  2019-11-26 21:46 ` [PATCH v9 1/6] mt76: mt76x02: ommit beacon slot clearing Markus Theil
@ 2019-11-26 21:47 ` Markus Theil
  2019-12-17  9:50   ` Lorenzo Bianconi
  2019-12-18  9:37   ` Lorenzo Bianconi
  2019-11-26 21:47 ` [PATCH v9 3/6] mt76: mt76x02: add check for invalid vif idx Markus Theil
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 14+ messages in thread
From: Markus Theil @ 2019-11-26 21:47 UTC (permalink / raw)
  To: nbd; +Cc: linux-wireless, lorenzo.bianconi, Stanislaw Gruszka, Markus Theil

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).

Beacons are sequentially written into the beacon memory area, by
tracking its usage with the dev->beacon_data_mask. MBSS support
is fixed by reversing the beacon_data_mask when setting it inverted
as the bypass mask.

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

MBSS tests were performed with AVM AC860 USB NIC with temporary support
for 5 BSS'. Different combinations of active vifs were created and
brought up. Afterwards connection and data transfer was tested for the
announced BSS'.

Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
 drivers/net/wireless/mediatek/mt76/mt76x02.h  |  3 +-
 .../wireless/mediatek/mt76/mt76x02_beacon.c   | 69 ++++++-------------
 .../net/wireless/mediatek/mt76/mt76x02_mac.c  |  2 +
 .../net/wireless/mediatek/mt76/mt76x02_mac.h  |  5 +-
 .../net/wireless/mediatek/mt76/mt76x02_mmio.c |  4 ++
 .../wireless/mediatek/mt76/mt76x02_usb_core.c | 14 ++--
 6 files changed, 38 insertions(+), 59 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 0ca0bbfe8769..ee87c5f30e81 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -93,8 +93,7 @@ struct mt76x02_dev {
 
 	const struct mt76x02_beacon_ops *beacon_ops;
 
-	struct sk_buff *beacons[8];
-	u8 beacon_data_mask;
+	u8 beacon_data_count;
 
 	u8 tbtt_count;
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
index 403866496640..1c4bdf88f712 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
@@ -40,62 +40,36 @@ mt76x02_write_beacon(struct mt76x02_dev *dev, int offset, struct sk_buff *skb)
 	return 0;
 }
 
-static int
-__mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 bcn_idx,
-			 struct sk_buff *skb)
+void mt76x02_mac_set_beacon_prepare(struct mt76x02_dev *dev)
 {
-	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);
-		if (!ret)
-			dev->beacon_data_mask |= BIT(bcn_idx);
-	} else {
-		dev->beacon_data_mask &= ~BIT(bcn_idx);
-	}
-
-	mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xff00 | ~dev->beacon_data_mask);
+	mt76_set(dev, MT_BCN_BYPASS_MASK, 0xffff);
+	dev->beacon_data_count = 0;
+}
+EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon_prepare);
 
-	return ret;
+void mt76x02_mac_set_beacon_finish(struct mt76x02_dev *dev)
+{
+	mt76_wr(dev, MT_BCN_BYPASS_MASK,
+		0xff00 | ~(0xff00 >> dev->beacon_data_count));
 }
+EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon_finish);
 
-int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
+int mt76x02_mac_set_beacon(struct mt76x02_dev *dev,
 			   struct sk_buff *skb)
 {
-	bool force_update = false;
-	int bcn_idx = 0;
-	int i;
-
-	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]);
-		}
-
-		bcn_idx += !!dev->beacons[i];
-	}
-
-	for (i = bcn_idx; i < ARRAY_SIZE(dev->beacons); i++) {
-		if (!(dev->beacon_data_mask & BIT(i)))
-			break;
+	int bcn_len = dev->beacon_ops->slot_size;
+	int bcn_addr = MT_BEACON_BASE + (bcn_len * dev->beacon_data_count);
+	int ret = 0;
 
-		__mt76x02_mac_set_beacon(dev, i, NULL);
+	if (skb) {
+		ret = mt76x02_write_beacon(dev, bcn_addr, skb);
+		if (!ret)
+			dev->beacon_data_count++;
 	}
 
-	mt76_rmw_field(dev, MT_MAC_BSSID_DW1, MT_MAC_BSSID_DW1_MBEACON_N,
-		       bcn_idx - 1);
-	return 0;
+	dev_kfree_skb(skb);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon);
 
@@ -114,7 +88,6 @@ void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
 		dev->mt76.beacon_mask |= BIT(mvif->idx);
 	} else {
 		dev->mt76.beacon_mask &= ~BIT(mvif->idx);
-		mt76x02_mac_set_beacon(dev, mvif->idx, NULL);
 	}
 
 	if (!!old_mask == !!dev->mt76.beacon_mask)
@@ -180,7 +153,7 @@ mt76x02_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
 	if (!skb)
 		return;
 
-	mt76x02_mac_set_beacon(dev, mvif->idx, skb);
+	mt76x02_mac_set_beacon(dev, skb);
 }
 EXPORT_SYMBOL_GPL(mt76x02_update_beacon_iter);
 
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 4460548f346a..285ab0f491d0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -741,6 +741,8 @@ void mt76x02_mac_setaddr(struct mt76x02_dev *dev, const u8 *addr)
 		get_unaligned_le16(dev->mt76.macaddr + 4) |
 		FIELD_PREP(MT_MAC_BSSID_DW1_MBSS_MODE, 3) | /* 8 APs + 8 STAs */
 		MT_MAC_BSSID_DW1_MBSS_LOCAL_BIT);
+	/* enable 7 additional beacon slots and control them with bypass mask */
+	mt76_rmw_field(dev, MT_MAC_BSSID_DW1, MT_MAC_BSSID_DW1_MBEACON_N, 7);
 
 	for (i = 0; i < 16; i++)
 		mt76x02_mac_set_bssid(dev, i, null_addr);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
index 7d946aa77182..f67f66f65ee0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
@@ -201,10 +201,11 @@ void mt76x02_mac_work(struct work_struct *work);
 
 void mt76x02_mac_cc_reset(struct mt76x02_dev *dev);
 void mt76x02_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, const u8 *addr);
-int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
-			   struct sk_buff *skb);
+int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, 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 4e2371c926d8..ae35780aaff1 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 d03d3c8e296c..fca861f10563 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -208,6 +208,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);
@@ -217,9 +219,11 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
 
 	for (i = nbeacons; i < N_BCN_SLOTS; i++) {
 		skb = __skb_dequeue(&data.q);
-		mt76x02_mac_set_beacon(dev, i, skb);
+		mt76x02_mac_set_beacon(dev, skb);
 	}
 
+	mt76x02_mac_set_beacon_finish(dev);
+
 	mt76x02u_restart_pre_tbtt_timer(dev);
 }
 
@@ -244,19 +248,15 @@ 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->mt76.beacon_int))
 		return;
 
 	if (en) {
 		mt76x02u_start_pre_tbtt_timer(dev);
 	} else {
-		/* Timer is already stopped, only clean up
-		 * PS buffered frames if any.
+		/* Timer is already stopped,
+		 * nothing else to do here.
 		 */
-		for (i = 0; i < N_BCN_SLOTS; i++)
-			mt76x02_mac_set_beacon(dev, i, NULL);
 	}
 }
 
-- 
2.24.0


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

* [PATCH v9 3/6] mt76: mt76x02: add check for invalid vif idx
  2019-11-26 21:46 [PATCH v9 0/6] mt76: channel switch support for USB devices Markus Theil
  2019-11-26 21:46 ` [PATCH v9 1/6] mt76: mt76x02: ommit beacon slot clearing Markus Theil
  2019-11-26 21:47 ` [PATCH v9 2/6] mt76: mt76x02: split beaconing Markus Theil
@ 2019-11-26 21:47 ` Markus Theil
  2019-11-26 21:47 ` [PATCH v9 4/6] mt76: mt76x02: remove a copy call for usb speedup Markus Theil
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 14+ messages in thread
From: Markus Theil @ 2019-11-26 21:47 UTC (permalink / raw)
  To: nbd; +Cc: linux-wireless, lorenzo.bianconi, Stanislaw Gruszka, Markus Theil

On adding vifs the idx can become 1 + (7 & 7) = 8 for APs.
Check against that, as only AP vif idx 0-7 is possible.

Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
 drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 889566b36a40..6073f8a4a8f6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -325,7 +325,9 @@ mt76x02_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 	if (vif->type == NL80211_IFTYPE_STATION)
 		idx += 8;
 
-	if (dev->vif_mask & BIT(idx))
+	/* vif is already set or idx is 8 for AP/Mesh/... */
+	if (dev->vif_mask & BIT(idx) ||
+	    (vif->type != NL80211_IFTYPE_STATION && idx > 7))
 		return -EBUSY;
 
 	dev->vif_mask |= BIT(idx);
-- 
2.24.0


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

* [PATCH v9 4/6] mt76: mt76x02: remove a copy call for usb speedup
  2019-11-26 21:46 [PATCH v9 0/6] mt76: channel switch support for USB devices Markus Theil
                   ` (2 preceding siblings ...)
  2019-11-26 21:47 ` [PATCH v9 3/6] mt76: mt76x02: add check for invalid vif idx Markus Theil
@ 2019-11-26 21:47 ` Markus Theil
  2019-12-17  9:40   ` Lorenzo Bianconi
  2019-11-26 21:47 ` [PATCH v9 5/6] mt76: speed up usb bulk copy Markus Theil
  2019-11-26 21:47 ` [PATCH v9 6/6] mt76: mt76x02: add channel switch support for usb interfaces Markus Theil
  5 siblings, 1 reply; 14+ messages in thread
From: Markus Theil @ 2019-11-26 21:47 UTC (permalink / raw)
  To: nbd; +Cc: linux-wireless, lorenzo.bianconi, Stanislaw Gruszka, Markus Theil

This patch removes a mt76_wr_copy call from the beacon path to hw.
The skb which is used in this place gets therefore build with txwi
inside its data. For mt76 usb drivers, this saves one synchronuous
copy call over usb, which lets the beacon work complete faster.

In mmio case, there is not enough headroom to put the txwi into the
skb, it is therefore using an additional mt76_wr_copy, which is fast
over mmio. Thanks Stanislaw for pointing this out.

Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
 .../wireless/mediatek/mt76/mt76x02_beacon.c   | 20 +++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
index 1c4bdf88f712..68a4f512319e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
@@ -26,15 +26,27 @@ static int
 mt76x02_write_beacon(struct mt76x02_dev *dev, int offset, struct sk_buff *skb)
 {
 	int beacon_len = dev->beacon_ops->slot_size;
-	struct mt76x02_txwi txwi;
 
 	if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x02_txwi)))
 		return -ENOSPC;
 
-	mt76x02_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len);
+	/* USB devices already reserve enough skb headroom for txwi's. This
+	 * helps to save slow copies over USB.
+	 */
+	if (mt76_is_usb(&dev->mt76)) {
+		struct mt76x02_txwi *txwi;
+
+		mt76_insert_hdr_pad(skb);
+		txwi = (struct mt76x02_txwi *)(skb->data - sizeof(*txwi));
+		mt76x02_mac_write_txwi(dev, txwi, skb, NULL, NULL, skb->len);
+		skb_push(skb, sizeof(*txwi));
+	} else {
+		struct mt76x02_txwi txwi;
 
-	mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
-	offset += sizeof(txwi);
+		mt76x02_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len);
+		mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
+		offset += sizeof(txwi);
+	}
 
 	mt76_wr_copy(dev, offset, skb->data, skb->len);
 	return 0;
-- 
2.24.0


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

* [PATCH v9 5/6] mt76: speed up usb bulk copy
  2019-11-26 21:46 [PATCH v9 0/6] mt76: channel switch support for USB devices Markus Theil
                   ` (3 preceding siblings ...)
  2019-11-26 21:47 ` [PATCH v9 4/6] mt76: mt76x02: remove a copy call for usb speedup Markus Theil
@ 2019-11-26 21:47 ` Markus Theil
  2019-11-26 21:47 ` [PATCH v9 6/6] mt76: mt76x02: add channel switch support for usb interfaces Markus Theil
  5 siblings, 0 replies; 14+ messages in thread
From: Markus Theil @ 2019-11-26 21:47 UTC (permalink / raw)
  To: nbd; +Cc: linux-wireless, lorenzo.bianconi, Stanislaw Gruszka, Markus Theil

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.
Assure, that always a multiple of 4 Bytes is copied, as outlined in
850e8f6fbd "mt76: round up length on mt76_wr_copy" from Felix Fietkau.

Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
 drivers/net/wireless/mediatek/mt76/mt76.h |  2 +-
 drivers/net/wireless/mediatek/mt76/usb.c  | 24 +++++++++++++++++------
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index fb077760347a..1981912de1f9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -382,7 +382,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/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index d6d47081e281..97b263ce3872 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -149,18 +149,30 @@ 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;
+	int current_batch_size;
+	int i = 0;
+
+	/* Assure that always a multiple of 4 bytes are copied,
+	 * otherwise beacons can be corrupted.
+	 * See: "mt76: round up length on mt76_wr_copy"
+	 * Commit 850e8f6fbd5d0003b0
+	 */
+	len = round_up(len, 4);
 
 	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) {
+		current_batch_size = min_t(int, 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);
 		if (ret < 0)
 			break;
+
+		i += current_batch_size;
 	}
 	mutex_unlock(&usb->usb_ctrl_mtx);
 }
-- 
2.24.0


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

* [PATCH v9 6/6] mt76: mt76x02: add channel switch support for usb interfaces
  2019-11-26 21:46 [PATCH v9 0/6] mt76: channel switch support for USB devices Markus Theil
                   ` (4 preceding siblings ...)
  2019-11-26 21:47 ` [PATCH v9 5/6] mt76: speed up usb bulk copy Markus Theil
@ 2019-11-26 21:47 ` Markus Theil
  5 siblings, 0 replies; 14+ messages in thread
From: Markus Theil @ 2019-11-26 21:47 UTC (permalink / raw)
  To: nbd; +Cc: linux-wireless, lorenzo.bianconi, Stanislaw Gruszka, Markus Theil

This patch enables channel switch support on mt76 usb interfaces.

Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
---
 drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c | 8 ++++++++
 drivers/net/wireless/mediatek/mt76/mt76x02_util.c     | 2 +-
 2 files changed, 9 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 fca861f10563..3dc3682d585a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -214,6 +214,13 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
 		IEEE80211_IFACE_ITER_RESUME_ALL,
 		mt76x02_update_beacon_iter, dev);
 
+	mt76_csa_check(&dev->mt76);
+
+	if (dev->mt76.csa_complete) {
+		mt76_csa_finish(&dev->mt76);
+		goto out;
+	}
+
 	nbeacons = hweight8(dev->mt76.beacon_mask);
 	mt76x02_enqueue_buffered_bc(dev, &data, N_BCN_SLOTS - nbeacons);
 
@@ -222,6 +229,7 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
 		mt76x02_mac_set_beacon(dev, skb);
 	}
 
+out:
 	mt76x02_mac_set_beacon_finish(dev);
 
 	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 6073f8a4a8f6..dbda7fb6dab7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -166,7 +166,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)) {
@@ -176,6 +175,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);
-- 
2.24.0


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

* Re: [PATCH v9 4/6] mt76: mt76x02: remove a copy call for usb speedup
  2019-11-26 21:47 ` [PATCH v9 4/6] mt76: mt76x02: remove a copy call for usb speedup Markus Theil
@ 2019-12-17  9:40   ` Lorenzo Bianconi
  2019-12-18 12:11     ` Markus Theil
  0 siblings, 1 reply; 14+ messages in thread
From: Lorenzo Bianconi @ 2019-12-17  9:40 UTC (permalink / raw)
  To: Markus Theil; +Cc: nbd, linux-wireless, lorenzo.bianconi, Stanislaw Gruszka

[-- Attachment #1: Type: text/plain, Size: 2246 bytes --]

> This patch removes a mt76_wr_copy call from the beacon path to hw.
> The skb which is used in this place gets therefore build with txwi
> inside its data. For mt76 usb drivers, this saves one synchronuous
> copy call over usb, which lets the beacon work complete faster.
> 
> In mmio case, there is not enough headroom to put the txwi into the
> skb, it is therefore using an additional mt76_wr_copy, which is fast
> over mmio. Thanks Stanislaw for pointing this out.
> 
> Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
> ---
>  .../wireless/mediatek/mt76/mt76x02_beacon.c   | 20 +++++++++++++++----
>  1 file changed, 16 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> index 1c4bdf88f712..68a4f512319e 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> @@ -26,15 +26,27 @@ static int
>  mt76x02_write_beacon(struct mt76x02_dev *dev, int offset, struct sk_buff *skb)
>  {
>  	int beacon_len = dev->beacon_ops->slot_size;
> -	struct mt76x02_txwi txwi;
>  
>  	if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x02_txwi)))
>  		return -ENOSPC;
>  
> -	mt76x02_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len);
> +	/* USB devices already reserve enough skb headroom for txwi's. This
> +	 * helps to save slow copies over USB.
> +	 */
> +	if (mt76_is_usb(&dev->mt76)) {
> +		struct mt76x02_txwi *txwi;
> +
> +		mt76_insert_hdr_pad(skb);

Do we really need mt76_insert_hdr_pad? I think beacon header should be 4B
aligned.

Regards,
Lorenzo

> +		txwi = (struct mt76x02_txwi *)(skb->data - sizeof(*txwi));
> +		mt76x02_mac_write_txwi(dev, txwi, skb, NULL, NULL, skb->len);
> +		skb_push(skb, sizeof(*txwi));
> +	} else {
> +		struct mt76x02_txwi txwi;
>  
> -	mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
> -	offset += sizeof(txwi);
> +		mt76x02_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len);
> +		mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
> +		offset += sizeof(txwi);
> +	}
>  
>  	mt76_wr_copy(dev, offset, skb->data, skb->len);
>  	return 0;
> -- 
> 2.24.0
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH v9 2/6] mt76: mt76x02: split beaconing
  2019-11-26 21:47 ` [PATCH v9 2/6] mt76: mt76x02: split beaconing Markus Theil
@ 2019-12-17  9:50   ` Lorenzo Bianconi
  2019-12-18  9:37   ` Lorenzo Bianconi
  1 sibling, 0 replies; 14+ messages in thread
From: Lorenzo Bianconi @ 2019-12-17  9:50 UTC (permalink / raw)
  To: Markus Theil; +Cc: nbd, linux-wireless, lorenzo.bianconi, Stanislaw Gruszka

[-- Attachment #1: Type: text/plain, Size: 8833 bytes --]

> 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).
> 

[...]

> Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
> ---
>  drivers/net/wireless/mediatek/mt76/mt76x02.h  |  3 +-
>  .../wireless/mediatek/mt76/mt76x02_beacon.c   | 69 ++++++-------------
>  .../net/wireless/mediatek/mt76/mt76x02_mac.c  |  2 +
>  .../net/wireless/mediatek/mt76/mt76x02_mac.h  |  5 +-
>  .../net/wireless/mediatek/mt76/mt76x02_mmio.c |  4 ++
>  .../wireless/mediatek/mt76/mt76x02_usb_core.c | 14 ++--
>  6 files changed, 38 insertions(+), 59 deletions(-)
> 
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h
> index 0ca0bbfe8769..ee87c5f30e81 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
> @@ -93,8 +93,7 @@ struct mt76x02_dev {
>  
>  	const struct mt76x02_beacon_ops *beacon_ops;
>  
> -	struct sk_buff *beacons[8];
> -	u8 beacon_data_mask;
> +	u8 beacon_data_count;
>  
>  	u8 tbtt_count;
>  
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> index 403866496640..1c4bdf88f712 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> @@ -40,62 +40,36 @@ mt76x02_write_beacon(struct mt76x02_dev *dev, int offset, struct sk_buff *skb)
>  	return 0;
>  }
>  
> -static int
> -__mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 bcn_idx,
> -			 struct sk_buff *skb)
> +void mt76x02_mac_set_beacon_prepare(struct mt76x02_dev *dev)
>  {
> -	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);
> -		if (!ret)
> -			dev->beacon_data_mask |= BIT(bcn_idx);
> -	} else {
> -		dev->beacon_data_mask &= ~BIT(bcn_idx);
> -	}
> -
> -	mt76_wr(dev, MT_BCN_BYPASS_MASK, 0xff00 | ~dev->beacon_data_mask);
> +	mt76_set(dev, MT_BCN_BYPASS_MASK, 0xffff);
> +	dev->beacon_data_count = 0;

I would prefer open-coding here

> +}
> +EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon_prepare);
>  
> -	return ret;
> +void mt76x02_mac_set_beacon_finish(struct mt76x02_dev *dev)
> +{
> +	mt76_wr(dev, MT_BCN_BYPASS_MASK,
> +		0xff00 | ~(0xff00 >> dev->beacon_data_count));
>  }
> +EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon_finish);

Probably better open-coding here since we just run mt76_wr()

>  
> -int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
> +int mt76x02_mac_set_beacon(struct mt76x02_dev *dev,
>  			   struct sk_buff *skb)
>  {
> -	bool force_update = false;
> -	int bcn_idx = 0;
> -	int i;
> -
> -	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]);
> -		}
> -
> -		bcn_idx += !!dev->beacons[i];
> -	}
> -
> -	for (i = bcn_idx; i < ARRAY_SIZE(dev->beacons); i++) {
> -		if (!(dev->beacon_data_mask & BIT(i)))
> -			break;
> +	int bcn_len = dev->beacon_ops->slot_size;
> +	int bcn_addr = MT_BEACON_BASE + (bcn_len * dev->beacon_data_count);
> +	int ret = 0;
>  
> -		__mt76x02_mac_set_beacon(dev, i, NULL);
> +	if (skb) {
> +		ret = mt76x02_write_beacon(dev, bcn_addr, skb);
> +		if (!ret)
> +			dev->beacon_data_count++;
>  	}
>  
> -	mt76_rmw_field(dev, MT_MAC_BSSID_DW1, MT_MAC_BSSID_DW1_MBEACON_N,
> -		       bcn_idx - 1);
> -	return 0;
> +	dev_kfree_skb(skb);
> +	return ret;
>  }
>  EXPORT_SYMBOL_GPL(mt76x02_mac_set_beacon);
>  
> @@ -114,7 +88,6 @@ void mt76x02_mac_set_beacon_enable(struct mt76x02_dev *dev,
>  		dev->mt76.beacon_mask |= BIT(mvif->idx);
>  	} else {
>  		dev->mt76.beacon_mask &= ~BIT(mvif->idx);
> -		mt76x02_mac_set_beacon(dev, mvif->idx, NULL);
>  	}
>  
>  	if (!!old_mask == !!dev->mt76.beacon_mask)
> @@ -180,7 +153,7 @@ mt76x02_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
>  	if (!skb)
>  		return;
>  
> -	mt76x02_mac_set_beacon(dev, mvif->idx, skb);
> +	mt76x02_mac_set_beacon(dev, skb);
>  }
>  EXPORT_SYMBOL_GPL(mt76x02_update_beacon_iter);
>  
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> index 4460548f346a..285ab0f491d0 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
> @@ -741,6 +741,8 @@ void mt76x02_mac_setaddr(struct mt76x02_dev *dev, const u8 *addr)
>  		get_unaligned_le16(dev->mt76.macaddr + 4) |
>  		FIELD_PREP(MT_MAC_BSSID_DW1_MBSS_MODE, 3) | /* 8 APs + 8 STAs */
>  		MT_MAC_BSSID_DW1_MBSS_LOCAL_BIT);
> +	/* enable 7 additional beacon slots and control them with bypass mask */
> +	mt76_rmw_field(dev, MT_MAC_BSSID_DW1, MT_MAC_BSSID_DW1_MBEACON_N, 7);
>  
>  	for (i = 0; i < 16; i++)
>  		mt76x02_mac_set_bssid(dev, i, null_addr);
> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
> index 7d946aa77182..f67f66f65ee0 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
> @@ -201,10 +201,11 @@ void mt76x02_mac_work(struct work_struct *work);
>  
>  void mt76x02_mac_cc_reset(struct mt76x02_dev *dev);
>  void mt76x02_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, const u8 *addr);
> -int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, u8 vif_idx,
> -			   struct sk_buff *skb);
> +int mt76x02_mac_set_beacon(struct mt76x02_dev *dev, 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 4e2371c926d8..ae35780aaff1 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 d03d3c8e296c..fca861f10563 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
> @@ -208,6 +208,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);
> @@ -217,9 +219,11 @@ static void mt76x02u_pre_tbtt_work(struct work_struct *work)
>  
>  	for (i = nbeacons; i < N_BCN_SLOTS; i++) {
>  		skb = __skb_dequeue(&data.q);
> -		mt76x02_mac_set_beacon(dev, i, skb);
> +		mt76x02_mac_set_beacon(dev, skb);
>  	}
>  
> +	mt76x02_mac_set_beacon_finish(dev);
> +
>  	mt76x02u_restart_pre_tbtt_timer(dev);
>  }
>  
> @@ -244,19 +248,15 @@ 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->mt76.beacon_int))
>  		return;
>  
>  	if (en) {
>  		mt76x02u_start_pre_tbtt_timer(dev);
>  	} else {
> -		/* Timer is already stopped, only clean up
> -		 * PS buffered frames if any.
> +		/* Timer is already stopped,
> +		 * nothing else to do here.
>  		 */
> -		for (i = 0; i < N_BCN_SLOTS; i++)
> -			mt76x02_mac_set_beacon(dev, i, NULL);
>  	}
>  }
>  
> -- 
> 2.24.0
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH v9 2/6] mt76: mt76x02: split beaconing
  2019-11-26 21:47 ` [PATCH v9 2/6] mt76: mt76x02: split beaconing Markus Theil
  2019-12-17  9:50   ` Lorenzo Bianconi
@ 2019-12-18  9:37   ` Lorenzo Bianconi
  2019-12-18 12:12     ` Markus Theil
  1 sibling, 1 reply; 14+ messages in thread
From: Lorenzo Bianconi @ 2019-12-18  9:37 UTC (permalink / raw)
  To: Markus Theil; +Cc: nbd, linux-wireless, Stanislaw Gruszka

[-- Attachment #1: Type: text/plain, Size: 707 bytes --]


[...]
>  
> @@ -244,19 +248,15 @@ 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->mt76.beacon_int))
>  		return;
>  
>  	if (en) {
>  		mt76x02u_start_pre_tbtt_timer(dev);
>  	} else {
> -		/* Timer is already stopped, only clean up
> -		 * PS buffered frames if any.
> +		/* Timer is already stopped,
> +		 * nothing else to do here.
>  		 */
> -		for (i = 0; i < N_BCN_SLOTS; i++)
> -			mt76x02_mac_set_beacon(dev, i, NULL);
>  	}

I guess here you can get rid of 'else' branch

Regards,
Lorenzo

>  }
>  
> -- 
> 2.24.0
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH v9 4/6] mt76: mt76x02: remove a copy call for usb speedup
  2019-12-17  9:40   ` Lorenzo Bianconi
@ 2019-12-18 12:11     ` Markus Theil
  2019-12-18 13:17       ` Lorenzo Bianconi
  0 siblings, 1 reply; 14+ messages in thread
From: Markus Theil @ 2019-12-18 12:11 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: nbd, linux-wireless, lorenzo.bianconi, Stanislaw Gruszka

On 12/17/19 10:40 AM, Lorenzo Bianconi wrote:
>> This patch removes a mt76_wr_copy call from the beacon path to hw.
>> The skb which is used in this place gets therefore build with txwi
>> inside its data. For mt76 usb drivers, this saves one synchronuous
>> copy call over usb, which lets the beacon work complete faster.
>>
>> In mmio case, there is not enough headroom to put the txwi into the
>> skb, it is therefore using an additional mt76_wr_copy, which is fast
>> over mmio. Thanks Stanislaw for pointing this out.
>>
>> Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
>> ---
>>  .../wireless/mediatek/mt76/mt76x02_beacon.c   | 20 +++++++++++++++----
>>  1 file changed, 16 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
>> index 1c4bdf88f712..68a4f512319e 100644
>> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
>> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
>> @@ -26,15 +26,27 @@ static int
>>  mt76x02_write_beacon(struct mt76x02_dev *dev, int offset, struct sk_buff *skb)
>>  {
>>  	int beacon_len = dev->beacon_ops->slot_size;
>> -	struct mt76x02_txwi txwi;
>>  
>>  	if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x02_txwi)))
>>  		return -ENOSPC;
>>  
>> -	mt76x02_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len);
>> +	/* USB devices already reserve enough skb headroom for txwi's. This
>> +	 * helps to save slow copies over USB.
>> +	 */
>> +	if (mt76_is_usb(&dev->mt76)) {
>> +		struct mt76x02_txwi *txwi;
>> +
>> +		mt76_insert_hdr_pad(skb);
> Do we really need mt76_insert_hdr_pad? I think beacon header should be 4B
> aligned.
>
> Regards,
> Lorenzo
I can leave it out of course, but I don't  know, if beacons from
mac80211 are always 4B aligned.

Regards,
Markus
>> +		txwi = (struct mt76x02_txwi *)(skb->data - sizeof(*txwi));
>> +		mt76x02_mac_write_txwi(dev, txwi, skb, NULL, NULL, skb->len);
>> +		skb_push(skb, sizeof(*txwi));
>> +	} else {
>> +		struct mt76x02_txwi txwi;
>>  
>> -	mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
>> -	offset += sizeof(txwi);
>> +		mt76x02_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len);
>> +		mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
>> +		offset += sizeof(txwi);
>> +	}
>>  
>>  	mt76_wr_copy(dev, offset, skb->data, skb->len);
>>  	return 0;
>> -- 
>> 2.24.0
>>


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

* Re: [PATCH v9 2/6] mt76: mt76x02: split beaconing
  2019-12-18  9:37   ` Lorenzo Bianconi
@ 2019-12-18 12:12     ` Markus Theil
  0 siblings, 0 replies; 14+ messages in thread
From: Markus Theil @ 2019-12-18 12:12 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: nbd, linux-wireless, Stanislaw Gruszka

On 12/18/19 10:37 AM, Lorenzo Bianconi wrote:
> [...]
>>  
>> @@ -244,19 +248,15 @@ 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->mt76.beacon_int))
>>  		return;
>>  
>>  	if (en) {
>>  		mt76x02u_start_pre_tbtt_timer(dev);
>>  	} else {
>> -		/* Timer is already stopped, only clean up
>> -		 * PS buffered frames if any.
>> +		/* Timer is already stopped,
>> +		 * nothing else to do here.
>>  		 */
>> -		for (i = 0; i < N_BCN_SLOTS; i++)
>> -			mt76x02_mac_set_beacon(dev, i, NULL);
>>  	}
> I guess here you can get rid of 'else' branch
>
> Regards,
> Lorenzo

I changed my patch regarding to your suggestions. I'll wait with sending
another iteration on comments to the
4B alignment of beacons.

Markus

>>  }
>>  
>> -- 
>> 2.24.0
>>

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

* Re: [PATCH v9 4/6] mt76: mt76x02: remove a copy call for usb speedup
  2019-12-18 12:11     ` Markus Theil
@ 2019-12-18 13:17       ` Lorenzo Bianconi
  2019-12-18 14:57         ` Markus Theil
  0 siblings, 1 reply; 14+ messages in thread
From: Lorenzo Bianconi @ 2019-12-18 13:17 UTC (permalink / raw)
  To: Markus Theil; +Cc: Lorenzo Bianconi, nbd, linux-wireless, Stanislaw Gruszka

[-- Attachment #1: Type: text/plain, Size: 2726 bytes --]

> On 12/17/19 10:40 AM, Lorenzo Bianconi wrote:
> >> This patch removes a mt76_wr_copy call from the beacon path to hw.
> >> The skb which is used in this place gets therefore build with txwi
> >> inside its data. For mt76 usb drivers, this saves one synchronuous
> >> copy call over usb, which lets the beacon work complete faster.
> >>
> >> In mmio case, there is not enough headroom to put the txwi into the
> >> skb, it is therefore using an additional mt76_wr_copy, which is fast
> >> over mmio. Thanks Stanislaw for pointing this out.
> >>
> >> Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
> >> ---
> >>  .../wireless/mediatek/mt76/mt76x02_beacon.c   | 20 +++++++++++++++----
> >>  1 file changed, 16 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> >> index 1c4bdf88f712..68a4f512319e 100644
> >> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> >> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
> >> @@ -26,15 +26,27 @@ static int
> >>  mt76x02_write_beacon(struct mt76x02_dev *dev, int offset, struct sk_buff *skb)
> >>  {
> >>  	int beacon_len = dev->beacon_ops->slot_size;
> >> -	struct mt76x02_txwi txwi;
> >>  
> >>  	if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x02_txwi)))
> >>  		return -ENOSPC;
> >>  
> >> -	mt76x02_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len);
> >> +	/* USB devices already reserve enough skb headroom for txwi's. This
> >> +	 * helps to save slow copies over USB.
> >> +	 */
> >> +	if (mt76_is_usb(&dev->mt76)) {
> >> +		struct mt76x02_txwi *txwi;
> >> +
> >> +		mt76_insert_hdr_pad(skb);
> > Do we really need mt76_insert_hdr_pad? I think beacon header should be 4B
> > aligned.

mt76_insert_hdr_pad takes into account just 802.11 header length and it is 24
or 28 for mgmt frames.

Regards,
Lorenzo

> >
> > Regards,
> > Lorenzo
> I can leave it out of course, but I don't  know, if beacons from
> mac80211 are always 4B aligned.
> 
> Regards,
> Markus
> >> +		txwi = (struct mt76x02_txwi *)(skb->data - sizeof(*txwi));
> >> +		mt76x02_mac_write_txwi(dev, txwi, skb, NULL, NULL, skb->len);
> >> +		skb_push(skb, sizeof(*txwi));
> >> +	} else {
> >> +		struct mt76x02_txwi txwi;
> >>  
> >> -	mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
> >> -	offset += sizeof(txwi);
> >> +		mt76x02_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len);
> >> +		mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
> >> +		offset += sizeof(txwi);
> >> +	}
> >>  
> >>  	mt76_wr_copy(dev, offset, skb->data, skb->len);
> >>  	return 0;
> >> -- 
> >> 2.24.0
> >>
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

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

* Re: [PATCH v9 4/6] mt76: mt76x02: remove a copy call for usb speedup
  2019-12-18 13:17       ` Lorenzo Bianconi
@ 2019-12-18 14:57         ` Markus Theil
  0 siblings, 0 replies; 14+ messages in thread
From: Markus Theil @ 2019-12-18 14:57 UTC (permalink / raw)
  To: Lorenzo Bianconi; +Cc: Lorenzo Bianconi, nbd, linux-wireless, Stanislaw Gruszka

On 12/18/19 2:17 PM, Lorenzo Bianconi wrote:
>> On 12/17/19 10:40 AM, Lorenzo Bianconi wrote:
>>>> This patch removes a mt76_wr_copy call from the beacon path to hw.
>>>> The skb which is used in this place gets therefore build with txwi
>>>> inside its data. For mt76 usb drivers, this saves one synchronuous
>>>> copy call over usb, which lets the beacon work complete faster.
>>>>
>>>> In mmio case, there is not enough headroom to put the txwi into the
>>>> skb, it is therefore using an additional mt76_wr_copy, which is fast
>>>> over mmio. Thanks Stanislaw for pointing this out.
>>>>
>>>> Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
>>>> ---
>>>>  .../wireless/mediatek/mt76/mt76x02_beacon.c   | 20 +++++++++++++++----
>>>>  1 file changed, 16 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
>>>> index 1c4bdf88f712..68a4f512319e 100644
>>>> --- a/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
>>>> +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_beacon.c
>>>> @@ -26,15 +26,27 @@ static int
>>>>  mt76x02_write_beacon(struct mt76x02_dev *dev, int offset, struct sk_buff *skb)
>>>>  {
>>>>  	int beacon_len = dev->beacon_ops->slot_size;
>>>> -	struct mt76x02_txwi txwi;
>>>>  
>>>>  	if (WARN_ON_ONCE(beacon_len < skb->len + sizeof(struct mt76x02_txwi)))
>>>>  		return -ENOSPC;
>>>>  
>>>> -	mt76x02_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len);
>>>> +	/* USB devices already reserve enough skb headroom for txwi's. This
>>>> +	 * helps to save slow copies over USB.
>>>> +	 */
>>>> +	if (mt76_is_usb(&dev->mt76)) {
>>>> +		struct mt76x02_txwi *txwi;
>>>> +
>>>> +		mt76_insert_hdr_pad(skb);
>>> Do we really need mt76_insert_hdr_pad? I think beacon header should be 4B
>>> aligned.
> mt76_insert_hdr_pad takes into account just 802.11 header length and it is 24
> or 28 for mgmt frames.
>
> Regards,
> Lorenzo

Ok, thanks. Then I drop the call.

Markus

>>> Regards,
>>> Lorenzo
>> I can leave it out of course, but I don't  know, if beacons from
>> mac80211 are always 4B aligned.
>>
>> Regards,
>> Markus
>>>> +		txwi = (struct mt76x02_txwi *)(skb->data - sizeof(*txwi));
>>>> +		mt76x02_mac_write_txwi(dev, txwi, skb, NULL, NULL, skb->len);
>>>> +		skb_push(skb, sizeof(*txwi));
>>>> +	} else {
>>>> +		struct mt76x02_txwi txwi;
>>>>  
>>>> -	mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
>>>> -	offset += sizeof(txwi);
>>>> +		mt76x02_mac_write_txwi(dev, &txwi, skb, NULL, NULL, skb->len);
>>>> +		mt76_wr_copy(dev, offset, &txwi, sizeof(txwi));
>>>> +		offset += sizeof(txwi);
>>>> +	}
>>>>  
>>>>  	mt76_wr_copy(dev, offset, skb->data, skb->len);
>>>>  	return 0;
>>>> -- 
>>>> 2.24.0
>>>>

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

end of thread, other threads:[~2019-12-18 14:57 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-26 21:46 [PATCH v9 0/6] mt76: channel switch support for USB devices Markus Theil
2019-11-26 21:46 ` [PATCH v9 1/6] mt76: mt76x02: ommit beacon slot clearing Markus Theil
2019-11-26 21:47 ` [PATCH v9 2/6] mt76: mt76x02: split beaconing Markus Theil
2019-12-17  9:50   ` Lorenzo Bianconi
2019-12-18  9:37   ` Lorenzo Bianconi
2019-12-18 12:12     ` Markus Theil
2019-11-26 21:47 ` [PATCH v9 3/6] mt76: mt76x02: add check for invalid vif idx Markus Theil
2019-11-26 21:47 ` [PATCH v9 4/6] mt76: mt76x02: remove a copy call for usb speedup Markus Theil
2019-12-17  9:40   ` Lorenzo Bianconi
2019-12-18 12:11     ` Markus Theil
2019-12-18 13:17       ` Lorenzo Bianconi
2019-12-18 14:57         ` Markus Theil
2019-11-26 21:47 ` [PATCH v9 5/6] mt76: speed up usb bulk copy Markus Theil
2019-11-26 21:47 ` [PATCH v9 6/6] mt76: mt76x02: add channel switch support for usb interfaces Markus Theil

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).