Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [PATCH v3] ath9k: add loader for AR92XX (and older) pci(e)
From: Christian Lamparter @ 2019-06-29  8:44 UTC (permalink / raw)
  To: Kalle Valo, martin.blumenstingl, chrisrblake93, jonas.gorski
  Cc: linux-wireless, QCA ath9k Development, Julian Calaby, dev, juhosg,
	john, hauke, jow
In-Reply-To: <87tvcasxpg.fsf@purkki.adurom.net>

Hello,

(Sorry for the delay. I only have time for dealing with this
on the weekends. Thanks!)

On Thursday, June 27, 2019 8:13:47 PM CEST Kalle Valo wrote:
> Christian Lamparter <chunkeey@gmail.com> writes:
> > Atheros cards with a AR92XX generation (and older) chip usually
> > store their pci(e) initialization vectors on an external eeprom chip.
> > However these chips technically don't need the eeprom chip attached,
> > the AR9280 Datasheet in section "6.1.2 DEVICE_ID" describes that
> > "... if the EEPROM content is not valid, a value of 0xFF1C returns
> > when read from the register". So, they will show up on the system's
> > pci bus. However in that state, ath9k can't load, since it relies
> > on having the correct pci-id, otherwise it doesn't know what chip it
> > actually is. This happens on many embedded devices like routers
> > and accesspoint since they want to keep the BOM low and store the
> > pci(e) initialization vectors together with the calibration data
> > on the system's FLASH, which is out of reach of the ath9k chip.
> >
> > Furthermore, Some devices (like the Cisco Meraki Z1 Cloud Managed
> > Teleworker Gateway) need to be able to initialize the PCIe wifi device.
> > Normally, this should be done as a pci quirk during the early stages of
> > booting linux. However, this isn't possible for devices which have the
> > init code for the Atheros chip stored on NAND in an UBI volume.
> > Hence, this module can be used to initialize the chip when the
> > user-space is ready to extract the init code.
> >
> > Martin Blumenstingl prodived the following fixes:
> > owl-loader: add support for OWL emulation PCI devices
> > owl-loader: don't re-scan the bus when ath9k_pci_fixup failed
> > owl-loader: use dev_* instead of pr_* logging functions
> > owl-loader: auto-generate the eeprom filename as fallback
> > owl-loader: add a debug message when swapping the eeprom data
> > owl-loader: add missing newlines in log messages
> >
> > Reviewed-by: Julian Calaby <julian.calaby@gmail.com>
> > Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
> > Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
> 
> [...]
> 
> > --- /dev/null
> > +++ b/drivers/net/wireless/ath/ath9k/ath9k_pci_owl_loader.c
> > @@ -0,0 +1,215 @@
> > +// SPDX-License-Identifier: GPL-2.0
> 
> [...]
> 
> > +MODULE_LICENSE("GPL v2");
> 
> ath9k has ISC license, is there a specific reason why you chose GPLv2
> here instead of ISC? I don't like mixing licenses within a driver,
> that's why I'm asking.

About that: The commit message hints The owl-loader was written because
Chris Blake needed it for the Cisco Meraki Z1 (Atheros based SoC) because
the existing methods in the OpenWrt project were designed to work with
straight-from-SPI-NOR. OpenWrt already had multiple different versions for
each platform (ar71xx = Atheros SoCs, lantiq, brcm63xx) of the
pci-ath9k-fixup.c which are all licensed under GPLv2 and they predated
owl-loader initiative by about 8 years.

https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob;f=target/linux/ar71xx/files/arch/mips/ath79/pci-ath9k-fixup.c
(lantiq's version has been since replaced by the owl-loader)
https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob;f=target/linux/brcm63xx/patches-4.14/416-BCM63XX-add-a-fixup-for-ath9k-devices.patch

(ar71xx has been deprecated and will be dropped in favor of the upstream
DeviceTree ath79 which relies on the owl-loader exclusivly)

So this is were the license comes from: Existing code looks similar.
And while the owl-loader was written from scratch as it needed:
 - to get the via firmware_request to make it as universal as possible
 - be able to support all platforms (no fixed pci(e) addresses)
 - separate driver as a module (and not a pci fixup)
I went for the safer "GPLv2" as it is the standard OpenWrt License:
https://git.openwrt.org/?p=openwrt/openwrt.git;a=blob;f=LICENSE

That said: I have no problem relicensing my code under the ISC, if it
helps with the upstreaming process. I've added Chris, Martin and
Mathias as they both were consultants, as well as the previous
authors of three targets to "let them know".

Best Regards,
Christian

(Yeah, I think this might take a while longer. So please don't delete
it just yet.)



^ permalink raw reply

* Re: [PATCH] rt2x00: fix rx queue hang
From: Stanislaw Gruszka @ 2019-06-29  8:50 UTC (permalink / raw)
  To: Soeren Moch
  Cc: Helmut Schaa, Kalle Valo, David S. Miller, linux-wireless, netdev,
	linux-kernel, stable
In-Reply-To: <8d7da251-8218-ff4b-2cf3-8ed69c97275e@web.de>

Hello

On Wed, Jun 26, 2019 at 03:28:00PM +0200, Soeren Moch wrote:
> Hi Stanislaw,
> 
> the good news is: your patch below also solves the issue for me. But
> removing the ENTRY_DATA_STATUS_PENDING check in
> rt2x00usb_kick_rx_entry() alone does not help, while removing this check
> in rt2x00usb_work_rxdone() alone does the trick.
> 
> So the real race seems to be that the flags set in the completion
> handler are not yet visible on the cpu core running the workqueue. And
> because the worker is not rescheduled when aborted, the entry can just
> wait forever.
> Do you think this could make sense?

Yes.

> > I'm somewhat reluctant to change the order, because TX processing
> > might relay on it (we first mark we wait for TX status and
> > then mark entry is no longer owned by hardware).
> OK, maybe it's just good luck that changing the order solves the rx
> problem. Or can memory barriers associated with the spinlock in
> rt2x00lib_dmadone() be responsible for that?
> (I'm testing on a armv7 system, Cortex-A9 quadcore.)

I'm not sure, rt2x00queue_index_inc() also disable/enable interrupts,
so maybe that make race not reproducible. 

> While looking at it, why we double-clear ENTRY_OWNER_DEVICE_DATA in
> rt2x00usb_interrupt_rxdone() directly and in rt2x00lib_dmadone() again,

rt2x00lib_dmadone() is called also on other palaces (error paths)
when we have to clear flags.

> while not doing the same for tx? 

If I remember correctly we have some races on rx (not happened on tx)
that was solved by using test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA).

> Would it make more sense to possibly
> set ENTRY_DATA_IO_FAILED before clearing ENTRY_OWNER_DEVICE_DATA in
> rt2x00usb_interrupt_rxdone() as for tx?

I don't think so, ENTRY_DATA_IO_FAILED should be only set on error
case.

> >  However on RX
> > side ENTRY_DATA_STATUS_PENDING bit make no sense as we do not
> > wait for status. We should remove ENTRY_DATA_STATUS_PENDING on
> > RX side and perhaps this also will solve issue you observe.
> I agree that removing the unnecessary checks is a good idea in any case.
> > Could you please check below patch, if it fixes the problem as well?
> At least I could not trigger the problem within transferring 10GB of
> data. But maybe the probability for triggering this bug is just lower
> because ENTRY_OWNER_DEVICE_DATA is cleared some time before
> ENTRY_DATA_STATUS_PENDING is set?

Not sure. Anyway, could you post patch removing not needed checks
with proper description/changelog ?

Stanislaw

^ permalink raw reply

* [PATCH 0/6] add hw dfs pattern detector support to mt7615 driver
From: Lorenzo Bianconi @ 2019-06-29 10:36 UTC (permalink / raw)
  To: nbd; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo, yf.luo

Introduce radar pattern detection support to mt7615 driver.
Add Channel Switch Announcement support updating beacon template with
CSA IE received from mac80211.
Please note I have tested this series just through the radar pattern test
knob added to debugfs and not through I real radar signal generator.

Lorenzo Bianconi (6):
  mt76: mt7615: introduce mt7615_regd_notifier
  mt76: mt7615: add hw dfs pattern detector support
  mt76: mt7615: do not perform txcalibration before cac is complited
  mt76: mt7615: unlock dfs bands
  mt76: mt7615: add csa support
  mt76: mt7615: add radar pattern test knob to debugfs

 .../wireless/mediatek/mt76/mt7615/Makefile    |   3 +-
 .../wireless/mediatek/mt76/mt7615/debugfs.c   |  38 +++++
 .../net/wireless/mediatek/mt76/mt7615/dma.c   |   2 +-
 .../net/wireless/mediatek/mt76/mt7615/init.c  |  44 ++++--
 .../net/wireless/mediatek/mt76/mt7615/mac.c   |  88 +++++++++++
 .../net/wireless/mediatek/mt76/mt7615/main.c  |  19 +++
 .../net/wireless/mediatek/mt76/mt7615/mcu.c   | 147 ++++++++++++++++--
 .../net/wireless/mediatek/mt76/mt7615/mcu.h   |  24 +++
 .../wireless/mediatek/mt76/mt7615/mt7615.h    |  55 +++++++
 9 files changed, 392 insertions(+), 28 deletions(-)
 create mode 100644 drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c

-- 
2.21.0


^ permalink raw reply

* [PATCH 1/6] mt76: mt7615: introduce mt7615_regd_notifier
From: Lorenzo Bianconi @ 2019-06-29 10:36 UTC (permalink / raw)
  To: nbd; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo, yf.luo
In-Reply-To: <cover.1561804422.git.lorenzo@kernel.org>

Introduce mt7615_regd_notifier callback. This is a preliminary patch to
add radar detection support to mt7615 driver

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt7615/init.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
index 859de2454ec6..edce96ce79a4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
@@ -208,6 +208,16 @@ mt7615_init_txpower(struct mt7615_dev *dev,
 	}
 }
 
+static void
+mt7615_regd_notifier(struct wiphy *wiphy,
+		     struct regulatory_request *request)
+{
+	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+	struct mt7615_dev *dev = hw->priv;
+
+	dev->mt76.region = request->dfs_region;
+}
+
 int mt7615_register_device(struct mt7615_dev *dev)
 {
 	struct ieee80211_hw *hw = mt76_hw(dev);
@@ -230,6 +240,7 @@ int mt7615_register_device(struct mt7615_dev *dev)
 
 	wiphy->iface_combinations = if_comb;
 	wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
+	wiphy->reg_notifier = mt7615_regd_notifier;
 
 	ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
 	ieee80211_hw_set(hw, TX_STATUS_NO_AMPDU_LEN);
-- 
2.21.0


^ permalink raw reply related

* [PATCH 2/6] mt76: mt7615: add hw dfs pattern detector support
From: Lorenzo Bianconi @ 2019-06-29 10:36 UTC (permalink / raw)
  To: nbd; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo, yf.luo
In-Reply-To: <cover.1561804422.git.lorenzo@kernel.org>

Add hw radar detection support to mt7615 driver in order to
unlock dfs channels on 5GHz band

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 .../net/wireless/mediatek/mt76/mt7615/dma.c   |  2 +-
 .../net/wireless/mediatek/mt76/mt7615/init.c  | 17 ++++
 .../net/wireless/mediatek/mt76/mt7615/mac.c   | 88 +++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt7615/main.c  |  6 ++
 .../net/wireless/mediatek/mt76/mt7615/mcu.c   | 65 ++++++++++++++
 .../net/wireless/mediatek/mt76/mt7615/mcu.h   | 22 +++++
 .../wireless/mediatek/mt76/mt7615/mt7615.h    | 46 ++++++++++
 7 files changed, 245 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
index 6a70273d4a69..3fe24d92d4fa 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c
@@ -76,7 +76,7 @@ void mt7615_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
 		mt7615_mac_tx_free(dev, skb);
 		break;
 	case PKT_TYPE_RX_EVENT:
-		mt76_mcu_rx_event(&dev->mt76, skb);
+		mt7615_mcu_rx_event(dev, skb);
 		break;
 	case PKT_TYPE_NORMAL:
 		if (!mt7615_mac_fill_rx(dev, skb)) {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
index edce96ce79a4..5dc4cced5789 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
@@ -163,6 +163,8 @@ static int mt7615_init_debugfs(struct mt7615_dev *dev)
 	if (!dir)
 		return -ENOMEM;
 
+	debugfs_create_u32("dfs_hw_pattern", 0400, dir, &dev->hw_pattern);
+
 	return 0;
 }
 
@@ -214,8 +216,22 @@ mt7615_regd_notifier(struct wiphy *wiphy,
 {
 	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
 	struct mt7615_dev *dev = hw->priv;
+	struct cfg80211_chan_def *chandef = &dev->mt76.chandef;
+
+	if (request->dfs_region == dev->mt76.region)
+		return;
 
 	dev->mt76.region = request->dfs_region;
+
+	if (!(chandef->chan->flags & IEEE80211_CHAN_RADAR))
+		return;
+
+	mt7615_dfs_stop_radar_detector(dev);
+	if (request->dfs_region == NL80211_DFS_UNSET)
+		mt7615_mcu_rdd_cmd(dev, RDD_CAC_END, MT_HW_RDD0,
+				   MT_RX_SEL0, 0);
+	else
+		mt7615_dfs_start_radar_detector(dev);
 }
 
 int mt7615_register_device(struct mt7615_dev *dev)
@@ -254,6 +270,7 @@ int mt7615_register_device(struct mt7615_dev *dev)
 			IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
 	dev->mt76.chainmask = 0x404;
 	dev->mt76.antenna_mask = 0xf;
+	dev->dfs_state = -1;
 
 	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
 #ifdef CONFIG_MAC80211_MESH
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
index 1eb0e9c9970c..08cc3f46b011 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
@@ -746,3 +746,91 @@ void mt7615_mac_work(struct work_struct *work)
 	ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
 				     MT7615_WATCHDOG_TIME);
 }
+
+int mt7615_dfs_stop_radar_detector(struct mt7615_dev *dev)
+{
+	struct cfg80211_chan_def *chandef = &dev->mt76.chandef;
+	int err;
+
+	err = mt7615_mcu_rdd_cmd(dev, RDD_STOP, MT_HW_RDD0,
+				 MT_RX_SEL0, 0);
+	if (err < 0)
+		return err;
+
+	if (chandef->width == NL80211_CHAN_WIDTH_160 ||
+	    chandef->width == NL80211_CHAN_WIDTH_80P80)
+		err = mt7615_mcu_rdd_cmd(dev, RDD_STOP, MT_HW_RDD1,
+					 MT_RX_SEL0, 0);
+	return err;
+}
+
+static int mt7615_dfs_start_rdd(struct mt7615_dev *dev, int chain)
+{
+	int err;
+
+	err = mt7615_mcu_rdd_cmd(dev, RDD_START, chain, MT_RX_SEL0, 0);
+	if (err < 0)
+		return err;
+
+	return mt7615_mcu_rdd_cmd(dev, RDD_DET_MODE, chain,
+				  MT_RX_SEL0, 1);
+}
+
+int mt7615_dfs_start_radar_detector(struct mt7615_dev *dev)
+{
+	struct cfg80211_chan_def *chandef = &dev->mt76.chandef;
+	int err;
+
+	/* start CAC */
+	err = mt7615_mcu_rdd_cmd(dev, RDD_CAC_START, MT_HW_RDD0,
+				 MT_RX_SEL0, 0);
+	if (err < 0)
+		return err;
+
+	/* TODO: DBDC support */
+
+	err = mt7615_dfs_start_rdd(dev, MT_HW_RDD0);
+	if (err < 0)
+		return err;
+
+	if (chandef->width == NL80211_CHAN_WIDTH_160 ||
+	    chandef->width == NL80211_CHAN_WIDTH_80P80) {
+		err = mt7615_dfs_start_rdd(dev, MT_HW_RDD1);
+		if (err < 0)
+			return err;
+	}
+
+	return 0;
+}
+
+int mt7615_dfs_init_radar_detector(struct mt7615_dev *dev)
+{
+	struct cfg80211_chan_def *chandef = &dev->mt76.chandef;
+	int err;
+
+	if (dev->mt76.region == NL80211_DFS_UNSET)
+		return 0;
+
+	if (test_bit(MT76_SCANNING, &dev->mt76.state))
+		return 0;
+
+	if (dev->dfs_state == chandef->chan->dfs_state)
+		return 0;
+
+	dev->dfs_state = chandef->chan->dfs_state;
+
+	if (chandef->chan->flags & IEEE80211_CHAN_RADAR) {
+		if (chandef->chan->dfs_state != NL80211_DFS_AVAILABLE)
+			return mt7615_dfs_start_radar_detector(dev);
+		else
+			return mt7615_mcu_rdd_cmd(dev, RDD_CAC_END, MT_HW_RDD0,
+						  MT_RX_SEL0, 0);
+	} else {
+		err = mt7615_mcu_rdd_cmd(dev, RDD_NORMAL_START,
+					 MT_HW_RDD0, MT_RX_SEL0, 0);
+		if (err < 0)
+			return err;
+
+		return mt7615_dfs_stop_radar_detector(dev);
+	}
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
index b4d6af812c54..cf9be4944cf7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
@@ -137,12 +137,18 @@ static int mt7615_set_channel(struct mt7615_dev *dev)
 	cancel_delayed_work_sync(&dev->mt76.mac_work);
 	set_bit(MT76_RESET, &dev->mt76.state);
 
+	mt7615_dfs_check_channel(dev);
+
 	mt76_set_channel(&dev->mt76);
 
 	ret = mt7615_mcu_set_channel(dev);
 	if (ret)
 		return ret;
 
+	ret = mt7615_dfs_init_radar_detector(dev);
+	if (ret < 0)
+		return ret;
+
 	clear_bit(MT76_RESET, &dev->mt76.state);
 
 	mt76_txq_schedule_all(&dev->mt76);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
index 282b46c6d33d..c3fefccf3d5b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
@@ -159,6 +159,50 @@ mt7615_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
 	return ret;
 }
 
+static void
+mt7615_mcu_rx_ext_event(struct mt7615_dev *dev, struct sk_buff *skb)
+{
+	struct mt7615_mcu_rxd *rxd = (struct mt7615_mcu_rxd *)skb->data;
+
+	switch (rxd->ext_eid) {
+	case MCU_EXT_EVENT_RDD_REPORT:
+		ieee80211_radar_detected(dev->mt76.hw);
+		dev->hw_pattern++;
+		break;
+	default:
+		break;
+	}
+}
+
+static void
+mt7615_mcu_rx_unsolicited_event(struct mt7615_dev *dev, struct sk_buff *skb)
+{
+	struct mt7615_mcu_rxd *rxd = (struct mt7615_mcu_rxd *)skb->data;
+
+	switch (rxd->eid) {
+	case MCU_EVENT_EXT:
+		mt7615_mcu_rx_ext_event(dev, skb);
+		break;
+	default:
+		break;
+	}
+	dev_kfree_skb(skb);
+}
+
+void mt7615_mcu_rx_event(struct mt7615_dev *dev, struct sk_buff *skb)
+{
+	struct mt7615_mcu_rxd *rxd = (struct mt7615_mcu_rxd *)skb->data;
+
+	if (rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT ||
+	    rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST ||
+	    rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP ||
+	    rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC ||
+	    !rxd->seq)
+		mt7615_mcu_rx_unsolicited_event(dev, skb);
+	else
+		mt76_mcu_rx_event(&dev->mt76, skb);
+}
+
 static int mt7615_mcu_init_download(struct mt7615_dev *dev, u32 addr,
 				    u32 len, u32 mode)
 {
@@ -1213,6 +1257,27 @@ int mt7615_mcu_set_tx_power(struct mt7615_dev *dev)
 	return ret;
 }
 
+int mt7615_mcu_rdd_cmd(struct mt7615_dev *dev,
+		       enum mt7615_rdd_cmd cmd, u8 index,
+		       u8 rx_sel, u8 val)
+{
+	struct {
+		u8 ctrl;
+		u8 rdd_idx;
+		u8 rdd_rx_sel;
+		u8 val;
+		u8 rsv[4];
+	} req = {
+		.ctrl = cmd,
+		.rdd_idx = index,
+		.rdd_rx_sel = rx_sel,
+		.val = val,
+	};
+
+	return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_RDD_CTRL,
+				   &req, sizeof(req), true);
+}
+
 int mt7615_mcu_set_channel(struct mt7615_dev *dev)
 {
 	struct cfg80211_chan_def *chdef = &dev->mt76.chandef;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h
index f8b51ad25220..5fe492189f56 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h
@@ -23,6 +23,27 @@ struct mt7615_mcu_txd {
 	u32 reserved[5];
 } __packed __aligned(4);
 
+/* event table */
+enum {
+	MCU_EVENT_TARGET_ADDRESS_LEN = 0x01,
+	MCU_EVENT_FW_START = 0x01,
+	MCU_EVENT_GENERIC = 0x01,
+	MCU_EVENT_ACCESS_REG = 0x02,
+	MCU_EVENT_MT_PATCH_SEM = 0x04,
+	MCU_EVENT_CH_PRIVILEGE = 0x18,
+	MCU_EVENT_EXT = 0xed,
+	MCU_EVENT_RESTART_DL = 0xef,
+};
+
+/* ext event table */
+enum {
+	MCU_EXT_EVENT_PS_SYNC = 0x5,
+	MCU_EXT_EVENT_FW_LOG_2_HOST = 0x13,
+	MCU_EXT_EVENT_THERMAL_PROTECT = 0x22,
+	MCU_EXT_EVENT_ASSERT_DUMP = 0x23,
+	MCU_EXT_EVENT_RDD_REPORT = 0x3a,
+};
+
 struct mt7615_mcu_rxd {
 	__le32 rxd[4];
 
@@ -77,6 +98,7 @@ enum {
 	MCU_EXT_CMD_EDCA_UPDATE = 0x27,
 	MCU_EXT_CMD_DEV_INFO_UPDATE = 0x2A,
 	MCU_EXT_CMD_WTBL_UPDATE = 0x32,
+	MCU_EXT_CMD_SET_RDD_CTRL = 0x3a,
 	MCU_EXT_CMD_PROTECT_CTRL = 0x3e,
 	MCU_EXT_CMD_MAC_INIT_CTRL = 0x46,
 	MCU_EXT_CMD_BCN_OFFLOAD = 0x49,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
index f02ffcffe637..d113fa30115e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
@@ -68,6 +68,9 @@ struct mt7615_dev {
 	u32 vif_mask;
 	u32 omac_mask;
 
+	u32 hw_pattern;
+	int dfs_state;
+
 	spinlock_t token_lock;
 	struct idr token;
 };
@@ -97,6 +100,30 @@ enum {
 	EXT_BSSID_END
 };
 
+enum {
+	MT_HW_RDD0,
+	MT_HW_RDD1,
+};
+
+enum {
+	MT_RX_SEL0,
+	MT_RX_SEL1,
+};
+
+enum mt7615_rdd_cmd {
+	RDD_STOP,
+	RDD_START,
+	RDD_DET_MODE,
+	RDD_DET_STOP,
+	RDD_CAC_START,
+	RDD_CAC_END,
+	RDD_NORMAL_START,
+	RDD_DISABLE_DFS_CAL,
+	RDD_PULSE_DBG,
+	RDD_READ_PULSE,
+	RDD_RESUME_BF,
+};
+
 extern const struct ieee80211_ops mt7615_ops;
 extern struct pci_driver mt7615_pci_driver;
 
@@ -144,6 +171,23 @@ int mt7615_mcu_set_rx_ba(struct mt7615_dev *dev,
 			 bool add);
 int mt7615_mcu_set_ht_cap(struct mt7615_dev *dev, struct ieee80211_vif *vif,
 			  struct ieee80211_sta *sta);
+void mt7615_mcu_rx_event(struct mt7615_dev *dev, struct sk_buff *skb);
+int mt7615_mcu_rdd_cmd(struct mt7615_dev *dev,
+		       enum mt7615_rdd_cmd cmd, u8 index,
+		       u8 rx_sel, u8 val);
+int mt7615_dfs_start_radar_detector(struct mt7615_dev *dev);
+int mt7615_dfs_stop_radar_detector(struct mt7615_dev *dev);
+
+static inline void mt7615_dfs_check_channel(struct mt7615_dev *dev)
+{
+	enum nl80211_chan_width width = dev->mt76.chandef.width;
+	u32 freq = dev->mt76.chandef.chan->center_freq;
+	struct ieee80211_hw *hw = mt76_hw(dev);
+
+	if (hw->conf.chandef.chan->center_freq != freq ||
+	    hw->conf.chandef.width != width)
+		dev->dfs_state = -1;
+}
 
 static inline void mt7615_irq_enable(struct mt7615_dev *dev, u32 mask)
 {
@@ -193,5 +237,7 @@ void mt7615_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
 void mt7615_mac_work(struct work_struct *work);
 void mt7615_txp_skb_unmap(struct mt76_dev *dev,
 			  struct mt76_txwi_cache *txwi);
+int mt76_dfs_start_rdd(struct mt7615_dev *dev, bool force);
+int mt7615_dfs_init_radar_detector(struct mt7615_dev *dev);
 
 #endif
-- 
2.21.0


^ permalink raw reply related

* [PATCH 3/6] mt76: mt7615: do not perform txcalibration before cac is complited
From: Lorenzo Bianconi @ 2019-06-29 10:36 UTC (permalink / raw)
  To: nbd; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo, yf.luo
In-Reply-To: <cover.1561804422.git.lorenzo@kernel.org>

Delay channel calibration after Channel Availability Check. Add some
code cleanup to mt7615_mcu_set_channel

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 .../net/wireless/mediatek/mt76/mt7615/mcu.c   | 25 +++++++++++--------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
index c3fefccf3d5b..397ae4f95db8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
@@ -1280,7 +1280,8 @@ int mt7615_mcu_rdd_cmd(struct mt7615_dev *dev,
 
 int mt7615_mcu_set_channel(struct mt7615_dev *dev)
 {
-	struct cfg80211_chan_def *chdef = &dev->mt76.chandef;
+	struct cfg80211_chan_def *chandef = &dev->mt76.chandef;
+	int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2;
 	struct {
 		u8 control_chan;
 		u8 center_chan;
@@ -1299,17 +1300,20 @@ int mt7615_mcu_set_channel(struct mt7615_dev *dev)
 		u8 rsv1[3];
 		u8 txpower_sku[53];
 		u8 rsv2[3];
-	} req = {0};
+	} req = {
+		.control_chan = chandef->chan->hw_value,
+		.center_chan = ieee80211_frequency_to_channel(freq1),
+		.tx_streams = (dev->mt76.chainmask >> 8) & 0xf,
+		.rx_streams_mask = dev->mt76.antenna_mask,
+		.center_chan2 = ieee80211_frequency_to_channel(freq2),
+	};
 	int ret;
 
-	req.control_chan = chdef->chan->hw_value;
-	req.center_chan = ieee80211_frequency_to_channel(chdef->center_freq1);
-	req.tx_streams = (dev->mt76.chainmask >> 8) & 0xf;
-	req.rx_streams_mask = dev->mt76.antenna_mask;
-	req.switch_reason = CH_SWITCH_NORMAL;
-	req.band_idx = 0;
-	req.center_chan2 = ieee80211_frequency_to_channel(chdef->center_freq2);
-	req.txpower_drop = 0;
+	if ((chandef->chan->flags & IEEE80211_CHAN_RADAR) &&
+	    chandef->chan->dfs_state != NL80211_DFS_AVAILABLE)
+		req.switch_reason = CH_SWITCH_DFS;
+	else
+		req.switch_reason = CH_SWITCH_NORMAL;
 
 	switch (dev->mt76.chandef.width) {
 	case NL80211_CHAN_WIDTH_40:
@@ -1334,6 +1338,7 @@ int mt7615_mcu_set_channel(struct mt7615_dev *dev)
 	case NL80211_CHAN_WIDTH_20:
 	default:
 		req.bw = CMD_CBW_20MHZ;
+		break;
 	}
 	memset(req.txpower_sku, 0x3f, 49);
 
-- 
2.21.0


^ permalink raw reply related

* [PATCH 4/6] mt76: mt7615: unlock dfs bands
From: Lorenzo Bianconi @ 2019-06-29 10:36 UTC (permalink / raw)
  To: nbd; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo, yf.luo
In-Reply-To: <cover.1561804422.git.lorenzo@kernel.org>

Unlock dfs channels since now mt7615 driver supports radar detection

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt7615/init.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
index 5dc4cced5789..6d336d82cafe 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
@@ -152,6 +152,12 @@ static const struct ieee80211_iface_combination if_comb[] = {
 		.max_interfaces = 4,
 		.num_different_channels = 1,
 		.beacon_int_infra_match = true,
+		.radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
+				       BIT(NL80211_CHAN_WIDTH_20) |
+				       BIT(NL80211_CHAN_WIDTH_40) |
+				       BIT(NL80211_CHAN_WIDTH_80) |
+				       BIT(NL80211_CHAN_WIDTH_160) |
+				       BIT(NL80211_CHAN_WIDTH_80P80),
 	}
 };
 
-- 
2.21.0


^ permalink raw reply related

* [PATCH 5/6] mt76: mt7615: add csa support
From: Lorenzo Bianconi @ 2019-06-29 10:36 UTC (permalink / raw)
  To: nbd; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo, yf.luo
In-Reply-To: <cover.1561804422.git.lorenzo@kernel.org>

Add Channel Switch Announcement support to mt7615 driver updating beacon
template with CSA IE received from mac80211

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 .../net/wireless/mediatek/mt76/mt7615/init.c  |  1 +
 .../net/wireless/mediatek/mt76/mt7615/main.c  | 13 ++++++++++
 .../net/wireless/mediatek/mt76/mt7615/mcu.c   | 26 +++++++++++++++----
 .../net/wireless/mediatek/mt76/mt7615/mcu.h   |  1 +
 4 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
index 6d336d82cafe..dbeffe5866aa 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
@@ -263,6 +263,7 @@ int mt7615_register_device(struct mt7615_dev *dev)
 	wiphy->iface_combinations = if_comb;
 	wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
 	wiphy->reg_notifier = mt7615_regd_notifier;
+	wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
 
 	ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER);
 	ieee80211_hw_set(hw, TX_STATUS_NO_AMPDU_LEN);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
index cf9be4944cf7..1ee6dda579a8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
@@ -305,6 +305,18 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
 	mutex_unlock(&dev->mt76.mutex);
 }
 
+static void
+mt7615_channel_switch_beacon(struct ieee80211_hw *hw,
+			     struct ieee80211_vif *vif,
+			     struct cfg80211_chan_def *chandef)
+{
+	struct mt7615_dev *dev = hw->priv;
+
+	mutex_lock(&dev->mt76.mutex);
+	mt7615_mcu_set_bcn(dev, vif, true);
+	mutex_unlock(&dev->mt76.mutex);
+}
+
 int mt7615_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
 		   struct ieee80211_sta *sta)
 {
@@ -496,4 +508,5 @@ const struct ieee80211_ops mt7615_ops = {
 	.sw_scan_complete = mt7615_sw_scan_complete,
 	.release_buffered_frames = mt76_release_buffered_frames,
 	.get_txpower = mt76_get_txpower,
+	.channel_switch_beacon = mt7615_channel_switch_beacon,
 };
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
index 397ae4f95db8..951849e4dd09 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
@@ -159,6 +159,13 @@ mt7615_mcu_msg_send(struct mt76_dev *mdev, int cmd, const void *data,
 	return ret;
 }
 
+static void
+mt7615_mcu_csa_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
+{
+	if (vif->csa_active)
+		ieee80211_csa_finish(vif);
+}
+
 static void
 mt7615_mcu_rx_ext_event(struct mt7615_dev *dev, struct sk_buff *skb)
 {
@@ -169,6 +176,11 @@ mt7615_mcu_rx_ext_event(struct mt7615_dev *dev, struct sk_buff *skb)
 		ieee80211_radar_detected(dev->mt76.hw);
 		dev->hw_pattern++;
 		break;
+	case MCU_EXT_EVENT_CSA_NOTIFY:
+		ieee80211_iterate_active_interfaces_atomic(dev->mt76.hw,
+				IEEE80211_IFACE_ITER_RESUME_ALL,
+				mt7615_mcu_csa_finish, dev);
+		break;
 	default:
 		break;
 	}
@@ -1143,6 +1155,7 @@ int mt7615_mcu_set_bcn(struct mt7615_dev *dev, struct ieee80211_vif *vif,
 {
 	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
 	struct mt76_wcid *wcid = &dev->mt76.global_wcid;
+	struct ieee80211_mutable_offsets offs;
 	struct req {
 		u8 omac_idx;
 		u8 enable;
@@ -1163,13 +1176,10 @@ int mt7615_mcu_set_bcn(struct mt7615_dev *dev, struct ieee80211_vif *vif,
 		.enable = en,
 		.wlan_idx = wcid->idx,
 		.band_idx = mvif->band_idx,
-		/* pky_type: 0 for bcn, 1 for tim */
-		.pkt_type = 0,
 	};
 	struct sk_buff *skb;
-	u16 tim_off;
 
-	skb = ieee80211_beacon_get_tim(mt76_hw(dev), vif, &tim_off, NULL);
+	skb = ieee80211_beacon_get_template(mt76_hw(dev), vif, &offs);
 	if (!skb)
 		return -EINVAL;
 
@@ -1183,8 +1193,14 @@ int mt7615_mcu_set_bcn(struct mt7615_dev *dev, struct ieee80211_vif *vif,
 			      0, NULL);
 	memcpy(req.pkt + MT_TXD_SIZE, skb->data, skb->len);
 	req.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
-	req.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + tim_off);
+	req.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + offs.tim_offset);
+	if (offs.csa_counter_offs[0]) {
+		u16 csa_offs;
 
+		csa_offs = MT_TXD_SIZE + offs.csa_counter_offs[0] - 4;
+		req.csa_ie_pos = cpu_to_le16(csa_offs);
+		req.csa_cnt = skb->data[offs.csa_counter_offs[0]];
+	}
 	dev_kfree_skb(skb);
 
 	return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_BCN_OFFLOAD,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h
index 5fe492189f56..73ce9fe8bfed 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h
@@ -42,6 +42,7 @@ enum {
 	MCU_EXT_EVENT_THERMAL_PROTECT = 0x22,
 	MCU_EXT_EVENT_ASSERT_DUMP = 0x23,
 	MCU_EXT_EVENT_RDD_REPORT = 0x3a,
+	MCU_EXT_EVENT_CSA_NOTIFY = 0x4f,
 };
 
 struct mt7615_mcu_rxd {
-- 
2.21.0


^ permalink raw reply related

* [PATCH 6/6] mt76: mt7615: add radar pattern test knob to debugfs
From: Lorenzo Bianconi @ 2019-06-29 10:36 UTC (permalink / raw)
  To: nbd; +Cc: lorenzo.bianconi, linux-wireless, ryder.lee, royluo, yf.luo
In-Reply-To: <cover.1561804422.git.lorenzo@kernel.org>

Introduce mt7615_mcu_rdd_send_pattern routine to trigger a radar pattern
detection. Moreover move debugfs related routines in a dedicated source
file.

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 .../wireless/mediatek/mt76/mt7615/Makefile    |  3 +-
 .../wireless/mediatek/mt76/mt7615/debugfs.c   | 38 +++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt7615/init.c  | 13 -------
 .../net/wireless/mediatek/mt76/mt7615/mcu.c   | 31 +++++++++++++++
 .../net/wireless/mediatek/mt76/mt7615/mcu.h   |  1 +
 .../wireless/mediatek/mt76/mt7615/mt7615.h    |  9 +++++
 6 files changed, 81 insertions(+), 14 deletions(-)
 create mode 100644 drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/Makefile b/drivers/net/wireless/mediatek/mt76/mt7615/Makefile
index 6397552f6ee3..5aaac69849d6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/Makefile
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/Makefile
@@ -2,4 +2,5 @@
 
 obj-$(CONFIG_MT7615E) += mt7615e.o
 
-mt7615e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o
+mt7615e-y := pci.o init.o dma.o eeprom.o main.o mcu.o mac.o \
+	     debugfs.o
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
new file mode 100644
index 000000000000..ed605fcc99f9
--- /dev/null
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: ISC */
+
+#include "mt7615.h"
+
+static int
+mt7615_radar_pattern_set(void *data, u64 val)
+{
+	struct mt7615_dev *dev = data;
+
+	return mt7615_mcu_rdd_send_pattern(dev);
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_radar_pattern, NULL,
+			 mt7615_radar_pattern_set, "%lld\n");
+
+int mt7615_init_debugfs(struct mt7615_dev *dev)
+{
+	struct dentry *dir;
+
+	dir = mt76_register_debugfs(&dev->mt76);
+	if (!dir)
+		return -ENOMEM;
+
+	debugfs_create_u32("dfs_hw_pattern", 0400, dir, &dev->hw_pattern);
+	/* test pattern knobs */
+	debugfs_create_u8("pattern_len", 0600, dir,
+			  &dev->radar_pattern.n_pulses);
+	debugfs_create_u32("pulse_period", 0600, dir,
+			   &dev->radar_pattern.period);
+	debugfs_create_u16("pulse_width", 0600, dir,
+			   &dev->radar_pattern.width);
+	debugfs_create_u16("pulse_power", 0600, dir,
+			   &dev->radar_pattern.power);
+	debugfs_create_file("radar_trigger", 0200, dir, dev,
+			    &fops_radar_pattern);
+
+	return 0;
+}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
index dbeffe5866aa..3d814e9a31ef 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
@@ -161,19 +161,6 @@ static const struct ieee80211_iface_combination if_comb[] = {
 	}
 };
 
-static int mt7615_init_debugfs(struct mt7615_dev *dev)
-{
-	struct dentry *dir;
-
-	dir = mt76_register_debugfs(&dev->mt76);
-	if (!dir)
-		return -ENOMEM;
-
-	debugfs_create_u32("dfs_hw_pattern", 0400, dir, &dev->hw_pattern);
-
-	return 0;
-}
-
 static void
 mt7615_init_txpower(struct mt7615_dev *dev,
 		    struct ieee80211_supported_band *sband)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
index 951849e4dd09..06d146198e33 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
@@ -1294,6 +1294,37 @@ int mt7615_mcu_rdd_cmd(struct mt7615_dev *dev,
 				   &req, sizeof(req), true);
 }
 
+int mt7615_mcu_rdd_send_pattern(struct mt7615_dev *dev)
+{
+	struct {
+		u8 pulse_num;
+		u8 rsv[3];
+		struct {
+			u32 start_time;
+			u16 width;
+			s16 power;
+		} pattern[32];
+	} req = {
+		.pulse_num = dev->radar_pattern.n_pulses,
+	};
+	u32 start_time = ktime_to_ms(ktime_get_boottime());
+	int i;
+
+	if (dev->radar_pattern.n_pulses > ARRAY_SIZE(req.pattern))
+		return -EINVAL;
+
+	/* TODO: add some noise here */
+	for (i = 0; i < dev->radar_pattern.n_pulses; i++) {
+		req.pattern[i].width = dev->radar_pattern.width;
+		req.pattern[i].power = dev->radar_pattern.power;
+		req.pattern[i].start_time = start_time +
+					    i * dev->radar_pattern.period;
+	}
+
+	return __mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_RDD_PATTERN,
+				   &req, sizeof(req), false);
+}
+
 int mt7615_mcu_set_channel(struct mt7615_dev *dev)
 {
 	struct cfg80211_chan_def *chandef = &dev->mt76.chandef;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h
index 73ce9fe8bfed..17d22bfb1722 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.h
@@ -104,6 +104,7 @@ enum {
 	MCU_EXT_CMD_MAC_INIT_CTRL = 0x46,
 	MCU_EXT_CMD_BCN_OFFLOAD = 0x49,
 	MCU_EXT_CMD_SET_RX_PATH = 0x4e,
+	MCU_EXT_CMD_SET_RDD_PATTERN = 0x7d,
 };
 
 enum {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
index d113fa30115e..3713db874ef4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
@@ -68,6 +68,12 @@ struct mt7615_dev {
 	u32 vif_mask;
 	u32 omac_mask;
 
+	struct {
+		u8 n_pulses;
+		u32 period;
+		u16 width;
+		s16 power;
+	} radar_pattern;
 	u32 hw_pattern;
 	int dfs_state;
 
@@ -177,6 +183,7 @@ int mt7615_mcu_rdd_cmd(struct mt7615_dev *dev,
 		       u8 rx_sel, u8 val);
 int mt7615_dfs_start_radar_detector(struct mt7615_dev *dev);
 int mt7615_dfs_stop_radar_detector(struct mt7615_dev *dev);
+int mt7615_mcu_rdd_send_pattern(struct mt7615_dev *dev);
 
 static inline void mt7615_dfs_check_channel(struct mt7615_dev *dev)
 {
@@ -240,4 +247,6 @@ void mt7615_txp_skb_unmap(struct mt76_dev *dev,
 int mt76_dfs_start_rdd(struct mt7615_dev *dev, bool force);
 int mt7615_dfs_init_radar_detector(struct mt7615_dev *dev);
 
+int mt7615_init_debugfs(struct mt7615_dev *dev);
+
 #endif
-- 
2.21.0


^ permalink raw reply related

* Re: [PATCH 0/6] add hw dfs pattern detector support to mt7615 driver
From: Lorenzo Bianconi @ 2019-06-29 10:48 UTC (permalink / raw)
  To: Felix Fietkau
  Cc: linux-wireless, Ryder Lee, Roy Luo, YF Luo, Lorenzo Bianconi
In-Reply-To: <cover.1561804422.git.lorenzo@kernel.org>

>
> Introduce radar pattern detection support to mt7615 driver.
> Add Channel Switch Announcement support updating beacon template with
> CSA IE received from mac80211.
> Please note I have tested this series just through the radar pattern test
> knob added to debugfs and not through I real radar signal generator.
>

Changes since RFC:
- added Channel Switch Announcement support

> Lorenzo Bianconi (6):
>   mt76: mt7615: introduce mt7615_regd_notifier
>   mt76: mt7615: add hw dfs pattern detector support
>   mt76: mt7615: do not perform txcalibration before cac is complited
>   mt76: mt7615: unlock dfs bands
>   mt76: mt7615: add csa support
>   mt76: mt7615: add radar pattern test knob to debugfs
>
>  .../wireless/mediatek/mt76/mt7615/Makefile    |   3 +-
>  .../wireless/mediatek/mt76/mt7615/debugfs.c   |  38 +++++
>  .../net/wireless/mediatek/mt76/mt7615/dma.c   |   2 +-
>  .../net/wireless/mediatek/mt76/mt7615/init.c  |  44 ++++--
>  .../net/wireless/mediatek/mt76/mt7615/mac.c   |  88 +++++++++++
>  .../net/wireless/mediatek/mt76/mt7615/main.c  |  19 +++
>  .../net/wireless/mediatek/mt76/mt7615/mcu.c   | 147 ++++++++++++++++--
>  .../net/wireless/mediatek/mt76/mt7615/mcu.h   |  24 +++
>  .../wireless/mediatek/mt76/mt7615/mt7615.h    |  55 +++++++
>  9 files changed, 392 insertions(+), 28 deletions(-)
>  create mode 100644 drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
>
> --
> 2.21.0
>

^ permalink raw reply

* Re: [PATCH 0/6] add hw dfs pattern detector support to mt7615 driver
From: Ryder Lee @ 2019-06-29 15:20 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Felix Fietkau, linux-wireless, Roy Luo, YF Luo, Lorenzo Bianconi
In-Reply-To: <CAJ0CqmUqv+uWcDkPnDAmjM2j=9fUZ0F4on4SH5LoQ4zPGmPuNw@mail.gmail.com>

On Sat, 2019-06-29 at 12:48 +0200, Lorenzo Bianconi wrote:
> >
> > Introduce radar pattern detection support to mt7615 driver.
> > Add Channel Switch Announcement support updating beacon template with
> > CSA IE received from mac80211.
> > Please note I have tested this series just through the radar pattern test
> > knob added to debugfs and not through I real radar signal generator.
> >
> 
> Changes since RFC:
> - added Channel Switch Announcement support
> 
> > Lorenzo Bianconi (6):
> >   mt76: mt7615: introduce mt7615_regd_notifier
> >   mt76: mt7615: add hw dfs pattern detector support
> >   mt76: mt7615: do not perform txcalibration before cac is complited
> >   mt76: mt7615: unlock dfs bands
> >   mt76: mt7615: add csa support
> >   mt76: mt7615: add radar pattern test knob to debugfs
> >
> >  .../wireless/mediatek/mt76/mt7615/Makefile    |   3 +-
> >  .../wireless/mediatek/mt76/mt7615/debugfs.c   |  38 +++++
> >  .../net/wireless/mediatek/mt76/mt7615/dma.c   |   2 +-
> >  .../net/wireless/mediatek/mt76/mt7615/init.c  |  44 ++++--
> >  .../net/wireless/mediatek/mt76/mt7615/mac.c   |  88 +++++++++++
> >  .../net/wireless/mediatek/mt76/mt7615/main.c  |  19 +++
> >  .../net/wireless/mediatek/mt76/mt7615/mcu.c   | 147 ++++++++++++++++--
> >  .../net/wireless/mediatek/mt76/mt7615/mcu.h   |  24 +++
> >  .../wireless/mediatek/mt76/mt7615/mt7615.h    |  55 +++++++
> >  9 files changed, 392 insertions(+), 28 deletions(-)
> >  create mode 100644 drivers/net/wireless/mediatek/mt76/mt7615/debugfs.c
> >
> > --
> > 2.21.0


Acked-by: Ryder Lee <ryder.lee@mediatek.com> for the series.
> >



^ permalink raw reply

* [PATCH 3/4] mac80211: AMPDU handling for rekeys with Extended Key ID
From: Alexander Wetzel @ 2019-06-29 19:50 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Alexander Wetzel
In-Reply-To: <20190629195015.19680-1-alexander@wetzel-home.de>

Extended Key ID allows A-MPDU sessions while rekeying as long as each
A-MPDU aggregates only MPDUs with one keyid together.

Drivers able to segregate MPDUs accordingly can tell mac80211 to not
stop A-MPDU sessions when rekeying by setting the new flag
IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT.

Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de>
---
 include/net/mac80211.h |  5 +++++
 net/mac80211/debugfs.c |  1 +
 net/mac80211/key.c     | 14 ++++++++------
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 544dad54b11f..1d6bb67ecb47 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2268,6 +2268,10 @@ struct ieee80211_txq {
  * @IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID: Hardware supports multi BSSID
  *	only for HE APs. Applies if @IEEE80211_HW_SUPPORTS_MULTI_BSSID is set.
  *
+ * @IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT: The card and driver is only
+ *	aggregating MPDUs with the same keyid, allowing mac80211 to keep Tx
+ *	A-MPDU sessions active while rekeying with Extended Key ID.
+ *
  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
  */
 enum ieee80211_hw_flags {
@@ -2319,6 +2323,7 @@ enum ieee80211_hw_flags {
 	IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN,
 	IEEE80211_HW_SUPPORTS_MULTI_BSSID,
 	IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID,
+	IEEE80211_HW_AMPDU_KEYBORDER_SUPPORT,
 
 	/* keep last, obviously */
 	NUM_IEEE80211_HW_FLAGS
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 47435f57e086..568b3b276931 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -271,6 +271,7 @@ static const char *hw_flag_names[] = {
 	FLAG(TX_STATUS_NO_AMPDU_LEN),
 	FLAG(SUPPORTS_MULTI_BSSID),
 	FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
+	FLAG(AMPDU_KEYBORDER_SUPPORT),
 #undef FLAG
 };
 
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 92c3affb0eb0..7dfee848abac 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -270,7 +270,8 @@ int ieee80211_set_tx_key(struct ieee80211_key *key)
 
 	sta->ptk_idx = key->conf.keyidx;
 
-	clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
+	if (!ieee80211_hw_check(&local->hw, AMPDU_KEYBORDER_SUPPORT))
+		clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
 	ieee80211_check_fast_xmit(sta);
 
 	return 0;
@@ -288,15 +289,16 @@ static void ieee80211_pairwise_rekey(struct ieee80211_key *old,
 	if (new->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX) {
 		/* Extended Key ID key install, initial one or rekey */
 
-		if (sta->ptk_idx != INVALID_PTK_KEYIDX) {
+		if (sta->ptk_idx != INVALID_PTK_KEYIDX &&
+		    !ieee80211_hw_check(&local->hw, AMPDU_KEYBORDER_SUPPORT)) {
 			/* Aggregation Sessions with Extended Key ID must not
 			 * mix MPDUs with different keyIDs within one A-MPDU.
 			 * Tear down running Tx aggregation sessions and block
 			 * new Rx/Tx aggregation requests during rekey to
-			 * ensure there are no A-MPDUs for the driver to
-			 * aggregate. (Blocking Tx only would be sufficient but
-			 * WLAN_STA_BLOCK_BA gets the job done for the few ms
-			 * we need it.)
+			 * ensure there are no A-MPDUs when the driver is not
+			 * supporting A-MPDU key borders. (Blocking Tx only
+			 * would be sufficient but WLAN_STA_BLOCK_BA gets the
+			 * job done for the few ms we need it.)
 			 */
 			set_sta_flag(sta, WLAN_STA_BLOCK_BA);
 			mutex_lock(&sta->ampdu_mlme.mtx);
-- 
2.22.0


^ permalink raw reply related

* [PATCH 4/4] iwlwifi: Enable Extended Key ID for mvm and dvm
From: Alexander Wetzel @ 2019-06-29 19:50 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Alexander Wetzel, Luca Coelho
In-Reply-To: <20190629195015.19680-1-alexander@wetzel-home.de>

All iwlwifi cards are able to handle multiple keyids per STA and are
therefore fully compatible with the Extended Key ID implementation
provided by mac80211.

Allow Extended Key ID to be used for all mvm and dvm cards.

Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de>
---

This is basically the v2 patch of https://patchwork.kernel.org/patch/10931879/
which Luca still has in his review queue. It just uses the new proposed
simplified Extended Key ID API from this patch series instead.

Merging (parts) of this series will of course break the older patch
still queued to Luca, so this may need some coordination.

 drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c | 1 +
 drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
index 6c170636110a..ac88c19f4f18 100644
--- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c
@@ -200,6 +200,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
 	iwl_leds_init(priv);
 
 	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
+	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_EXT_KEY_ID);
 
 	ret = ieee80211_register_hw(priv->hw);
 	if (ret) {
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index fdbabca0280e..c752fe6970e3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -599,6 +599,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
 
 	hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
 	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
+	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_EXT_KEY_ID);
 	hw->wiphy->features |= NL80211_FEATURE_HT_IBSS;
 
 	hw->wiphy->regulatory_flags |= REGULATORY_ENABLE_RELAX_NO_IR;
-- 
2.22.0


^ permalink raw reply related

* [PATCH 2/4] mac80211: Simplify Extended Key ID API
From: Alexander Wetzel @ 2019-06-29 19:50 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Alexander Wetzel
In-Reply-To: <20190629195015.19680-1-alexander@wetzel-home.de>

1) Drop IEEE80211_HW_EXT_KEY_ID_NATIVE and let drivers directly set
   the NL80211_EXT_FEATURE_EXT_KEY_ID flag.

2) Drop IEEE80211_HW_NO_AMPDU_KEYBORDER_SUPPORT and simply assume all
   drivers are unable to handle A-MPDU key borders.

The new Extended Key ID API now requires all mac80211 drivers to set
NL80211_EXT_FEATURE_EXT_KEY_ID when they implement set_key() and can
handle Extended Key ID. For drivers not providing set_key() mac80211
itself enables Extended Key ID support, using the internal SW crypto
services.

Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de>
---
Deciding to not merge the COMPAT Extended Key ID support also
invalidated the reasoning to have IEEE80211_HW_EXT_KEY_ID_NATIVE in the
first place. We can simple drop the flag and ask drivers to directly
set NL80211_EXT_FEATURE_EXT_KEY_ID with the current code.

IEEE80211_HW_NO_AMPDU_KEYBORDER_SUPPORT was intended to tell mac80211
that the driver is not checking the keyid when aggregating frames and is
only compatible with the IEEE 802.11 - 2016 standard when there are no
aggregation sessions running during rekey. But reverting the logic makes
more sense, the only driver able to set it for the foreseeable future is
hwsim. And for hwsim it's irrelevant if we stop A-MPDU or not, the
driver is never really aggregating frames.

Now it probably makes sense to not yet implement AMPDU_KEYBORDER_SUPPORT
and wait to see if we really have a need for that. So this patch stops
A-MPDU sessions every time when we rekey with Extended Key ID and is not
providing a API to the driver to prevent that.

But the next patch in the series is implementing the feature, allowing
you to merge it and have the API available today or simply skip it.

 include/net/mac80211.h |  8 --------
 net/mac80211/debugfs.c |  2 --
 net/mac80211/key.c     | 18 ++++++++----------
 net/mac80211/main.c    | 18 ++++++------------
 4 files changed, 14 insertions(+), 32 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index d26da013f7c0..544dad54b11f 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2268,12 +2268,6 @@ struct ieee80211_txq {
  * @IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID: Hardware supports multi BSSID
  *	only for HE APs. Applies if @IEEE80211_HW_SUPPORTS_MULTI_BSSID is set.
  *
- * @IEEE80211_HW_EXT_KEY_ID_NATIVE: Driver and hardware are supporting Extended
- *	Key ID and can handle two unicast keys per station for Rx and Tx.
- *
- * @IEEE80211_HW_NO_AMPDU_KEYBORDER_SUPPORT: The card/driver can't handle
- *	active Tx A-MPDU sessions with Extended Key IDs during rekey.
- *
  * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
  */
 enum ieee80211_hw_flags {
@@ -2325,8 +2319,6 @@ enum ieee80211_hw_flags {
 	IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN,
 	IEEE80211_HW_SUPPORTS_MULTI_BSSID,
 	IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID,
-	IEEE80211_HW_EXT_KEY_ID_NATIVE,
-	IEEE80211_HW_NO_AMPDU_KEYBORDER_SUPPORT,
 
 	/* keep last, obviously */
 	NUM_IEEE80211_HW_FLAGS
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 2e7f75938c51..47435f57e086 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -271,8 +271,6 @@ static const char *hw_flag_names[] = {
 	FLAG(TX_STATUS_NO_AMPDU_LEN),
 	FLAG(SUPPORTS_MULTI_BSSID),
 	FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
-	FLAG(EXT_KEY_ID_NATIVE),
-	FLAG(NO_AMPDU_KEYBORDER_SUPPORT),
 #undef FLAG
 };
 
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index dd60f6428049..92c3affb0eb0 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -270,8 +270,7 @@ int ieee80211_set_tx_key(struct ieee80211_key *key)
 
 	sta->ptk_idx = key->conf.keyidx;
 
-	if (ieee80211_hw_check(&local->hw, NO_AMPDU_KEYBORDER_SUPPORT))
-		clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
+	clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
 	ieee80211_check_fast_xmit(sta);
 
 	return 0;
@@ -289,16 +288,15 @@ static void ieee80211_pairwise_rekey(struct ieee80211_key *old,
 	if (new->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX) {
 		/* Extended Key ID key install, initial one or rekey */
 
-		if (sta->ptk_idx != INVALID_PTK_KEYIDX &&
-		    ieee80211_hw_check(&local->hw,
-				       NO_AMPDU_KEYBORDER_SUPPORT)) {
+		if (sta->ptk_idx != INVALID_PTK_KEYIDX) {
 			/* Aggregation Sessions with Extended Key ID must not
 			 * mix MPDUs with different keyIDs within one A-MPDU.
-			 * Tear down any running Tx aggregation and all new
-			 * Rx/Tx aggregation request during rekey if the driver
-			 * asks us to do so. (Blocking Tx only would be
-			 * sufficient but WLAN_STA_BLOCK_BA gets the job done
-			 * for the few ms we need it.)
+			 * Tear down running Tx aggregation sessions and block
+			 * new Rx/Tx aggregation requests during rekey to
+			 * ensure there are no A-MPDUs for the driver to
+			 * aggregate. (Blocking Tx only would be sufficient but
+			 * WLAN_STA_BLOCK_BA gets the job done for the few ms
+			 * we need it.)
 			 */
 			set_sta_flag(sta, WLAN_STA_BLOCK_BA);
 			mutex_lock(&sta->ampdu_mlme.mtx);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 85e416248753..3b8eb5d2ec7e 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1048,21 +1048,15 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 		}
 	}
 
-	/* Enable Extended Key IDs when driver allowed it, or when it
-	 * supports neither HW crypto nor A-MPDUs
+	/* Mac80211 and therefore all drivers using SW crypto only
+	 * are able to handle PTK rekeys and Extended Key ID.
 	 */
-	if ((!local->ops->set_key &&
-	     !ieee80211_hw_check(hw, AMPDU_AGGREGATION)) ||
-	    ieee80211_hw_check(&local->hw, EXT_KEY_ID_NATIVE))
-		wiphy_ext_feature_set(local->hw.wiphy,
-				      NL80211_EXT_FEATURE_EXT_KEY_ID);
-
-	/* Mac80211 and therefore all cards only using SW crypto are able to
-	 * handle PTK rekeys correctly
-	 */
-	if (!local->ops->set_key)
+	if (!local->ops->set_key) {
 		wiphy_ext_feature_set(local->hw.wiphy,
 				      NL80211_EXT_FEATURE_CAN_REPLACE_PTK0);
+		wiphy_ext_feature_set(local->hw.wiphy,
+				      NL80211_EXT_FEATURE_EXT_KEY_ID);
+	}
 
 	/*
 	 * Calculate scan IE length -- we need this to alloc
-- 
2.22.0


^ permalink raw reply related

* [PATCH 1/4] mac80211_hwsim: Extended Key ID API update
From: Alexander Wetzel @ 2019-06-29 19:50 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, Alexander Wetzel

Prepare hwsim Extended Key ID support for a mac80211 API change.

The mac80211 flag IEEE80211_HW_EXT_KEY_ID_NATIVE is being replaced by
NL80211_EXT_FEATURE_EXT_KEY_ID which only must be set by drivers when
they support HW crypto.

This reverts commit cfe7007a9b4cea9c4a0f7d4192c776c62f31869e.

Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de>
---
 drivers/net/wireless/mac80211_hwsim.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index d396a33bbc9c..26cbb5b5d7cd 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2805,12 +2805,6 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
 	ieee80211_hw_set(hw, SIGNAL_DBM);
 	ieee80211_hw_set(hw, SUPPORTS_PS);
 	ieee80211_hw_set(hw, TDLS_WIDER_BW);
-
-	/* We only have SW crypto and only implement the A-MPDU API
-	 * (but don't really build A-MPDUs) so can have extended key
-	 * support
-	 */
-	ieee80211_hw_set(hw, EXT_KEY_ID_NATIVE);
 	if (rctbl)
 		ieee80211_hw_set(hw, SUPPORTS_RC_TABLE);
 	ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID);
-- 
2.22.0


^ permalink raw reply related

* Re: [PATCH 4/6] mt76: mt7615: unlock dfs bands
From: Kalle Valo @ 2019-06-30  9:28 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: nbd, lorenzo.bianconi, linux-wireless, ryder.lee, royluo, yf.luo
In-Reply-To: <33184e0b78983fe7c79fa70c5fbb21042aafa4f5.1561804422.git.lorenzo@kernel.org>

Lorenzo Bianconi <lorenzo@kernel.org> writes:

> Unlock dfs channels since now mt7615 driver supports radar detection
>
> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> ---
>  drivers/net/wireless/mediatek/mt76/mt7615/init.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
> index 5dc4cced5789..6d336d82cafe 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
> @@ -152,6 +152,12 @@ static const struct ieee80211_iface_combination if_comb[] = {
>  		.max_interfaces = 4,
>  		.num_different_channels = 1,
>  		.beacon_int_infra_match = true,
> +		.radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
> +				       BIT(NL80211_CHAN_WIDTH_20) |
> +				       BIT(NL80211_CHAN_WIDTH_40) |
> +				       BIT(NL80211_CHAN_WIDTH_80) |
> +				       BIT(NL80211_CHAN_WIDTH_160) |
> +				       BIT(NL80211_CHAN_WIDTH_80P80),

Isn't it questionable to enable these without any testing on real
hardware? Getting DFS to work correctly is hard so I'm very suspicious
about this.

-- 
Kalle Valo

^ permalink raw reply

* Re: pull request: mt76 2019-06-27
From: Kalle Valo @ 2019-06-30  9:30 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-wireless
In-Reply-To: <a0e08791-e4e0-6772-751c-be05a4d25d8c@nbd.name>

Felix Fietkau <nbd@nbd.name> writes:

> Hi Kalle,
>
> here's my first pull request for 5.3
>
> - Felix
>
> The following changes since commit e5db0ad7563c38b7b329504836c9a64ae025a47a:
>
>   airo: switch to skcipher interface (2019-06-25 08:12:20 +0300)
>
> are available in the Git repository at:
>
>   https://github.com/nbd168/wireless tags/mt76-for-kvalo-2019-06-27
>
> for you to fetch changes up to 676fabd1d2f089f9fb8bece3476c2ab5584b4a1a:
>
>   mt76: mt7603: fix sparse warnings: warning: incorrect type in assignment (different base types) (2019-06-27 12:59:07 +0200)
>
> ----------------------------------------------------------------
> mt76 patches for 5.3
>
> * use NAPI polling for tx cleanup on mt7603/mt7615
> * various fixes for mt7615
> * unify some code between mt7603 and mt7615
> * fix locking issues on mt76x02
> * add support for toggling edcca on mt7603
> * fix reading target tx power with ext PA on mt7603/mt7615
> * fix initalizing channel maximum power
> * fix rate control / tx status reporting issues on mt76x02/mt7603
> * add support for eeprom calibration data from mtd on mt7615
> * support configuring tx power on mt7615
> * fix external PA support on mt76x0
> * per-chain signal reporting on mt7615
> * rx/tx buffer fixes for USB devices
>
> ----------------------------------------------------------------

Pulled, thanks.

-- 
Kalle Valo

^ permalink raw reply

* Re: [PATCH 4/6] mt76: mt7615: unlock dfs bands
From: Lorenzo Bianconi @ 2019-06-30 11:25 UTC (permalink / raw)
  To: Kalle Valo
  Cc: Lorenzo Bianconi, Felix Fietkau, linux-wireless, Ryder Lee,
	Roy Luo, YF Luo
In-Reply-To: <87muhzs9qv.fsf@purkki.adurom.net>

>
> Lorenzo Bianconi <lorenzo@kernel.org> writes:
>
> > Unlock dfs channels since now mt7615 driver supports radar detection
> >
> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > ---
> >  drivers/net/wireless/mediatek/mt76/mt7615/init.c | 6 ++++++
> >  1 file changed, 6 insertions(+)
> >
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
> > index 5dc4cced5789..6d336d82cafe 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
> > @@ -152,6 +152,12 @@ static const struct ieee80211_iface_combination if_comb[] = {
> >               .max_interfaces = 4,
> >               .num_different_channels = 1,
> >               .beacon_int_infra_match = true,
> > +             .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
> > +                                    BIT(NL80211_CHAN_WIDTH_20) |
> > +                                    BIT(NL80211_CHAN_WIDTH_40) |
> > +                                    BIT(NL80211_CHAN_WIDTH_80) |
> > +                                    BIT(NL80211_CHAN_WIDTH_160) |
> > +                                    BIT(NL80211_CHAN_WIDTH_80P80),
>
> Isn't it questionable to enable these without any testing on real
> hardware? Getting DFS to work correctly is hard so I'm very suspicious
> about this.
>
> --
> Kalle Valo

Hi Kalle,

unfortunately at the moment I am not able to run any tests with a real
signal generator so I just ported the code from vendor sdk.
I am pretty confident it works since the radar pattern detection is
done in fw/hw so I guess it has been already tested in the vendor sdk
but we can postpone this patch and apply just the rest of the series
until we have some test results.

@Ryder: do you have the possibility to carry out some real tests?

Regards,
Lorenzo

^ permalink raw reply

* Re: [RESEND] brcmfmac support for BCM4359 sdio on arm64 ??
From: Christian Hewitt @ 2019-06-30 17:06 UTC (permalink / raw)
  To: Arend Van Spriel
  Cc: linux-wireless, brcm80211-dev-list.pdl, brcm80211-dev-list,
	Wright.Feng, Neil Armstrong, Christoph Muellner
In-Reply-To: <db1e6182-d8fe-a68a-e769-b6460c68fab0@broadcom.com>


> On 24 Jun 2019, at 8:04 pm, Arend Van Spriel <arend.vanspriel@broadcom.com> wrote:
> 
> Hi Christian,
> 
> Here it is. Hopefully unmangled this time.

Hi Arend.

The extra logging patch is un-mangled and applies fine, but I bumped to 5.2-rc4 recently (and now 5.2-rc7) and hit a major problem.

If I add the BCM4359 device ID’s with the following commit I see a brcmfmac splat and the system fails to boot.

commit: https://github.com/chewitt/linux/commit/f07161815699a48e636600a0b835d7ff64715383
splat: https://imgur.com/a/28wu5kh
defconfig: https://github.com/chewitt/LibreELEC.tv/blob/amlogic-master/projects/Amlogic/linux/linux.aarch64.conf

Adding the extra logging changes you suggested is not the issue, it’s adding the device ID’s.

I was previously using 5.1-rc1 and 5.1.9 kernels and didn’t see any issues adding the ID’s.

Any ideas?

Christian

^ permalink raw reply

* linux-next: Fixes tag needs some work in the wireless-drivers-next tree
From: Stephen Rothwell @ 2019-06-30 21:44 UTC (permalink / raw)
  To: Kalle Valo, Wireless
  Cc: Linux Next Mailing List, Linux Kernel Mailing List,
	Lorenzo Bianconi, Felix Fietkau, Ryder Lee

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

Hi all,

In commit

  d923cf6bc38a ("mt76: mt7615: fix sparse warnings: warning: cast from restricted __le16")

Fixes tag

  Fixes: 3ca0a6f6e9df ("mt7615: mcu: use standard signature for mt7615_mcu_msg_send")

has these problem(s):

  - Target SHA1 does not exist

Did you mean

Fixes: 516c3e380533 ("mt7615: mcu: use standard signature for mt7615_mcu_msg_send")

In commit

  eda96044de27 ("mt76: mt7615: fix sparse warnings: incorrect type in assignment (different base types)")

Fixes tag

  Fixes: 7339fbc0caa5 ("mt7615: mcu: do not use function pointers whenever possible")

has these problem(s):

  - Target SHA1 does not exist

Did you mean

Fixes: 1ca8089a55ee ("mt7615: mcu: do not use function pointers whenever possible")

In commit

  1a09d9e0e5f0 ("mt76: mt7615: fix incorrect settings in mesh mode")

Fixes tag

  Fixes: f072c7ba2150 ("mt76: mt7615: enable support for mesh")

has these problem(s):

  - Target SHA1 does not exist

Did you mean

Fixes: f4ec7fdf7f83 ("mt76: mt7615: enable support for mesh")

-- 
Cheers,
Stephen Rothwell

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Fwd: rtl8723au: WiFi scanning stops working shortly after driver loads?
From: Daniel Lenski @ 2019-06-30 21:56 UTC (permalink / raw)
  To: linux-wireless; +Cc: Jes Sorensen
In-Reply-To: <CAOw_LSHsioZ2TP1FeZT3L6gHeeV72e2aKW0bGkAzcJRgVzE43Q@mail.gmail.com>

Hi,
I recently started to use an older laptop with RTL8723AU
WiFi/Bluetooth again for the first time in a couple years.

I've noticed a strange behavior of this device/driver (rtl8xxxu with
4.4.0 kernel): the ability to do a WiFi scan *while associated with an
access point* somehow disappears ~30 seconds after the driver is
loaded.

That is, right after loading the module and connecting to a WiFi
network, I can successfully do `iwlist wlan0 scan`; but after a short
period of time, the scan stops returning any results other than for
the AP that I'm already connected to. Disconnecting from the AP
"resets" this behavior, but once I reconnect to a network, my ability
to scan disappears again shortly thereafter.

Steps to reproduce:

    # rmmod rtl8xxxu
    # modprobe rtl8xxxu debug=99
    # while true; do sudo iwlist wlan0 scan | grep ESSID | wc -l ; sleep 2; done
    13
    13
    13
    13
    1     # only my current AP
    1
    ...

Is this a known issue with the hardware, or with the driver? Any
advice on how to debug it? I've looked through the debug messages, and
found nothing that seems to indicate a state change around the time
that the scan stops working.

Thanks,
Dan

ps: I'm using the "standard" rtl8723aufw_B_NoBT.bin firmware
(https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/rtlwifi/rtl8723aufw_B_NoBT.bin)
and have loaded *only* the WiFi driver, *not* the Bluetooth driver.

[ 3110.201258] usb 1-1.4: Vendor: Realtek
[ 3110.201267] usb 1-1.4: Product: 802.11n WLAN Adapter
[ 3110.201274] usb 1-1.4: RTL8723AU rev B (TSMC) 1T1R, TX queues 2,
WiFi=1, BT=1, GPS=0, HI PA=0
[ 3110.201279] usb 1-1.4: RTL8723AU MAC: 20:16:d8:ce:5e:29
[ 3110.201284] usb 1-1.4: rtl8xxxu: Loading firmware
rtlwifi/rtl8723aufw_B_NoBT.bin
[ 3110.201355] usb 1-1.4: Firmware revision 31.0 (signature 0x2302)

^ permalink raw reply

* Re: [PATCH] rtl8xxxu: Fix wifi low signal strength issue of RTL8723BU
From: Chris Chiu @ 2019-07-01  5:09 UTC (permalink / raw)
  To: Jes Sorensen, Kalle Valo, David Miller
  Cc: linux-wireless, netdev, Linux Kernel, Linux Upstreaming Team
In-Reply-To: <20190627095247.8792-1-chiu@endlessm.com>

On Thu, Jun 27, 2019 at 5:52 PM Chris Chiu <chiu@endlessm.com> wrote:
>
> The WiFi tx power of RTL8723BU is extremely low after booting. So
> the WiFi scan gives very limited AP list and it always fails to
> connect to the selected AP. This module only supports 1x1 antenna
> and the antenna is switched to bluetooth due to some incorrect
> register settings.
>
> This commit hand over the antenna control to PTA, the wifi signal
> will be back to normal and the bluetooth scan can also work at the
> same time. However, the btcoexist still needs to be handled under
> different circumstances. If there's a BT connection established,
> the wifi still fails to connect until disconneting the BT.
>
> Signed-off-by: Chris Chiu <chiu@endlessm.com>
> ---
>  drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c | 9 ++++++---
>  drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c  | 3 ++-
>  2 files changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
> index 3adb1d3d47ac..6c3c70d93ac1 100644
> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
> @@ -1525,7 +1525,7 @@ static void rtl8723b_enable_rf(struct rtl8xxxu_priv *priv)
>         /*
>          * WLAN action by PTA
>          */
> -       rtl8xxxu_write8(priv, REG_WLAN_ACT_CONTROL_8723B, 0x04);
> +       rtl8xxxu_write8(priv, REG_WLAN_ACT_CONTROL_8723B, 0x0c);
>
>         /*
>          * BT select S0/S1 controlled by WiFi
> @@ -1568,9 +1568,12 @@ static void rtl8723b_enable_rf(struct rtl8xxxu_priv *priv)
>         rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.ant_sel_rsv));
>
>         /*
> -        * 0x280, 0x00, 0x200, 0x80 - not clear
> +        * Different settings per different antenna position.
> +        * Antenna switch to BT: 0x280, 0x00 (inverse)
> +        * Antenna switch to WiFi: 0x0, 0x280 (inverse)
> +        * Antenna controlled by PTA: 0x200, 0x80 (inverse)
>          */
> -       rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x00);
> +       rtl8xxxu_write32(priv, REG_S0S1_PATH_SWITCH, 0x80);
>
>         /*
>          * Software control, antenna at WiFi side
> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> index 8136e268b4e6..87b2179a769e 100644
> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> @@ -3891,12 +3891,13 @@ static int rtl8xxxu_init_device(struct ieee80211_hw *hw)
>
>         /* Check if MAC is already powered on */
>         val8 = rtl8xxxu_read8(priv, REG_CR);
> +       val16 = rtl8xxxu_read16(priv, REG_SYS_CLKR);
>
>         /*
>          * Fix 92DU-VC S3 hang with the reason is that secondary mac is not
>          * initialized. First MAC returns 0xea, second MAC returns 0x00
>          */
> -       if (val8 == 0xea)
> +       if (val8 == 0xea || !(val16 & BIT(11)))
>                 macpower = false;
>         else
>                 macpower = true;
> --
> 2.11.0
>

Gentle ping. Cheers.

Chris

^ permalink raw reply

* Re: [RFC PATCH v5] rtl8xxxu: Improve TX performance of RTL8723BU on rtl8xxxu driver
From: Chris Chiu @ 2019-07-01  5:09 UTC (permalink / raw)
  To: Jes Sorensen, Kalle Valo, David Miller
  Cc: linux-wireless, netdev, Linux Kernel, Linux Upstreaming Team
In-Reply-To: <20190617065600.40405-1-chiu@endlessm.com>

On Mon, Jun 17, 2019 at 2:56 PM Chris Chiu <chiu@endlessm.com> wrote:
>
> We have 3 laptops which connect the wifi by the same RTL8723BU.
> The PCI VID/PID of the wifi chip is 10EC:B720 which is supported.
> They have the same problem with the in-kernel rtl8xxxu driver, the
> iperf (as a client to an ethernet-connected server) gets ~1Mbps.
> Nevertheless, the signal strength is reported as around -40dBm,
> which is quite good. From the wireshark capture, the tx rate for each
> data and qos data packet is only 1Mbps. Compare to the Realtek driver
> at https://github.com/lwfinger/rtl8723bu, the same iperf test gets
> ~12Mbps or better. The signal strength is reported similarly around
> -40dBm. That's why we want to improve.
>
> After reading the source code of the rtl8xxxu driver and Realtek's, the
> major difference is that Realtek's driver has a watchdog which will keep
> monitoring the signal quality and updating the rate mask just like the
> rtl8xxxu_gen2_update_rate_mask() does if signal quality changes.
> And this kind of watchdog also exists in rtlwifi driver of some specific
> chips, ex rtl8192ee, rtl8188ee, rtl8723ae, rtl8821ae...etc. They have
> the same member function named dm_watchdog and will invoke the
> corresponding dm_refresh_rate_adaptive_mask to adjust the tx rate
> mask.
>
> With this commit, the tx rate of each data and qos data packet will
> be 39Mbps (MCS4) with the 0xF00000 as the tx rate mask. The 20th bit
> to 23th bit means MCS4 to MCS7. It means that the firmware still picks
> the lowest rate from the rate mask and explains why the tx rate of
> data and qos data is always lowest 1Mbps because the default rate mask
> passed is always 0xFFFFFFF ranges from the basic CCK rate, OFDM rate,
> and MCS rate. However, with Realtek's driver, the tx rate observed from
> wireshark under the same condition is almost 65Mbps or 72Mbps.
>
> I believe the firmware of RTL8723BU may need fix. And I think we
> can still bring in the dm_watchdog as rtlwifi to improve from the
> driver side. Please leave precious comments for my commits and
> suggest what I can do better. Or suggest if there's any better idea
> to fix this. Thanks.
>
> Signed-off-by: Chris Chiu <chiu@endlessm.com>
> ---
>
>
> Notes:
>   v2:
>    - Fix errors and warnings complained by checkpatch.pl
>    - Replace data structure rate_adaptive by 2 member variables
>    - Make rtl8xxxu_wireless_mode non-static
>    - Runs refresh_rate_mask() only in station mode
>   v3:
>    - Remove ugly rtl8xxxu_watchdog data structure
>    - Make sure only one vif exists
>   v4:
>    - Move cancel_delayed_work from rtl8xxxu_disconnect to rtl8xxxu_stop
>    - Clear priv->vif in rtl8xxxu_remove_interface
>    - Add rateid as the function argument of update_rate_mask
>    - Rephrase the comment for priv->vif more explicit.
>   v5:
>    - Make refresh_rate_mask() generic for all sub-drivers.
>    - Add definitions for SNR related to help determine rssi_level
>
>
>  .../net/wireless/realtek/rtl8xxxu/rtl8xxxu.h  |  55 ++++-
>  .../wireless/realtek/rtl8xxxu/rtl8xxxu_core.c | 226 +++++++++++++++++-
>  2 files changed, 274 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> index 8828baf26e7b..1498a8c94d5f 100644
> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
> @@ -1195,6 +1195,48 @@ struct rtl8723bu_c2h {
>
>  struct rtl8xxxu_fileops;
>
> +/*mlme related.*/
> +enum wireless_mode {
> +       WIRELESS_MODE_UNKNOWN = 0,
> +       /* Sub-Element */
> +       WIRELESS_MODE_B = BIT(0),
> +       WIRELESS_MODE_G = BIT(1),
> +       WIRELESS_MODE_A = BIT(2),
> +       WIRELESS_MODE_N_24G = BIT(3),
> +       WIRELESS_MODE_N_5G = BIT(4),
> +       WIRELESS_AUTO = BIT(5),
> +       WIRELESS_MODE_AC = BIT(6),
> +       WIRELESS_MODE_MAX = 0x7F,
> +};
> +
> +/* from rtlwifi/wifi.h */
> +enum ratr_table_mode_new {
> +       RATEID_IDX_BGN_40M_2SS = 0,
> +       RATEID_IDX_BGN_40M_1SS = 1,
> +       RATEID_IDX_BGN_20M_2SS_BN = 2,
> +       RATEID_IDX_BGN_20M_1SS_BN = 3,
> +       RATEID_IDX_GN_N2SS = 4,
> +       RATEID_IDX_GN_N1SS = 5,
> +       RATEID_IDX_BG = 6,
> +       RATEID_IDX_G = 7,
> +       RATEID_IDX_B = 8,
> +       RATEID_IDX_VHT_2SS = 9,
> +       RATEID_IDX_VHT_1SS = 10,
> +       RATEID_IDX_MIX1 = 11,
> +       RATEID_IDX_MIX2 = 12,
> +       RATEID_IDX_VHT_3SS = 13,
> +       RATEID_IDX_BGN_3SS = 14,
> +};
> +
> +#define RTL8XXXU_RATR_STA_INIT 0
> +#define RTL8XXXU_RATR_STA_HIGH 1
> +#define RTL8XXXU_RATR_STA_MID  2
> +#define RTL8XXXU_RATR_STA_LOW  3
> +
> +#define RTL8XXXU_NOISE_FLOOR_MIN       -95
> +#define RTL8XXXU_SNR_THRESH_HIGH       50
> +#define RTL8XXXU_SNR_THRESH_LOW        20
> +
>  struct rtl8xxxu_priv {
>         struct ieee80211_hw *hw;
>         struct usb_device *udev;
> @@ -1299,6 +1341,13 @@ struct rtl8xxxu_priv {
>         u8 pi_enabled:1;
>         u8 no_pape:1;
>         u8 int_buf[USB_INTR_CONTENT_LENGTH];
> +       u8 rssi_level;
> +       /*
> +        * Only one virtual interface permitted because only STA mode
> +        * is supported and no iface_combinations are providec.
> +        */
> +       struct ieee80211_vif *vif;
> +       struct delayed_work ra_watchdog;
>  };
>
>  struct rtl8xxxu_rx_urb {
> @@ -1334,7 +1383,7 @@ struct rtl8xxxu_fileops {
>         void (*set_tx_power) (struct rtl8xxxu_priv *priv, int channel,
>                               bool ht40);
>         void (*update_rate_mask) (struct rtl8xxxu_priv *priv,
> -                                 u32 ramask, int sgi);
> +                                 u32 ramask, u8 rateid, int sgi);
>         void (*report_connect) (struct rtl8xxxu_priv *priv,
>                                 u8 macid, bool connect);
>         void (*fill_txdesc) (struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
> @@ -1419,9 +1468,9 @@ void rtl8xxxu_gen2_config_channel(struct ieee80211_hw *hw);
>  void rtl8xxxu_gen1_usb_quirks(struct rtl8xxxu_priv *priv);
>  void rtl8xxxu_gen2_usb_quirks(struct rtl8xxxu_priv *priv);
>  void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv,
> -                              u32 ramask, int sgi);
> +                              u32 ramask, u8 rateid, int sgi);
>  void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv,
> -                                   u32 ramask, int sgi);
> +                                   u32 ramask, u8 rateid, int sgi);
>  void rtl8xxxu_gen1_report_connect(struct rtl8xxxu_priv *priv,
>                                   u8 macid, bool connect);
>  void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
> diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> index 039e5ca9d2e4..474dea2291a9 100644
> --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
> @@ -4311,7 +4311,8 @@ static void rtl8xxxu_sw_scan_complete(struct ieee80211_hw *hw,
>         rtl8xxxu_write8(priv, REG_BEACON_CTRL, val8);
>  }
>
> -void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv, u32 ramask, int sgi)
> +void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv,
> +                              u32 ramask, u8 rateid, int sgi)
>  {
>         struct h2c_cmd h2c;
>
> @@ -4331,7 +4332,7 @@ void rtl8xxxu_update_rate_mask(struct rtl8xxxu_priv *priv, u32 ramask, int sgi)
>  }
>
>  void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv,
> -                                   u32 ramask, int sgi)
> +                                   u32 ramask, u8 rateid, int sgi)
>  {
>         struct h2c_cmd h2c;
>         u8 bw = 0;
> @@ -4345,7 +4346,7 @@ void rtl8xxxu_gen2_update_rate_mask(struct rtl8xxxu_priv *priv,
>         h2c.b_macid_cfg.ramask3 = (ramask >> 24) & 0xff;
>
>         h2c.ramask.arg = 0x80;
> -       h2c.b_macid_cfg.data1 = 0;
> +       h2c.b_macid_cfg.data1 = rateid;
>         if (sgi)
>                 h2c.b_macid_cfg.data1 |= BIT(7);
>
> @@ -4485,6 +4486,40 @@ static void rtl8xxxu_set_basic_rates(struct rtl8xxxu_priv *priv, u32 rate_cfg)
>         rtl8xxxu_write8(priv, REG_INIRTS_RATE_SEL, rate_idx);
>  }
>
> +static u16
> +rtl8xxxu_wireless_mode(struct ieee80211_hw *hw, struct ieee80211_sta *sta)
> +{
> +       u16 network_type = WIRELESS_MODE_UNKNOWN;
> +       u32 rate_mask;
> +
> +       rate_mask = (sta->supp_rates[0] & 0xfff) |
> +                   (sta->ht_cap.mcs.rx_mask[0] << 12) |
> +                   (sta->ht_cap.mcs.rx_mask[0] << 20);
> +
> +       if (hw->conf.chandef.chan->band == NL80211_BAND_5GHZ) {
> +               if (sta->vht_cap.vht_supported)
> +                       network_type = WIRELESS_MODE_AC;
> +               else if (sta->ht_cap.ht_supported)
> +                       network_type = WIRELESS_MODE_N_5G;
> +
> +               network_type |= WIRELESS_MODE_A;
> +       } else {
> +               if (sta->vht_cap.vht_supported)
> +                       network_type = WIRELESS_MODE_AC;
> +               else if (sta->ht_cap.ht_supported)
> +                       network_type = WIRELESS_MODE_N_24G;
> +
> +               if (sta->supp_rates[0] <= 0xf)
> +                       network_type |= WIRELESS_MODE_B;
> +               else if (sta->supp_rates[0] & 0xf)
> +                       network_type |= (WIRELESS_MODE_B | WIRELESS_MODE_G);
> +               else
> +                       network_type |= WIRELESS_MODE_G;
> +       }
> +
> +       return network_type;
> +}
> +
>  static void
>  rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
>                           struct ieee80211_bss_conf *bss_conf, u32 changed)
> @@ -4527,7 +4562,10 @@ rtl8xxxu_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
>                                 sgi = 1;
>                         rcu_read_unlock();
>
> -                       priv->fops->update_rate_mask(priv, ramask, sgi);
> +                       priv->vif = vif;
> +                       priv->rssi_level = RTL8XXXU_RATR_STA_INIT;
> +
> +                       priv->fops->update_rate_mask(priv, ramask, 0, sgi);
>
>                         rtl8xxxu_write8(priv, REG_BCN_MAX_ERR, 0xff);
>
> @@ -5471,6 +5509,10 @@ static int rtl8xxxu_add_interface(struct ieee80211_hw *hw,
>
>         switch (vif->type) {
>         case NL80211_IFTYPE_STATION:
> +               if (!priv->vif)
> +                       priv->vif = vif;
> +               else
> +                       return -EOPNOTSUPP;
>                 rtl8xxxu_stop_tx_beacon(priv);
>
>                 val8 = rtl8xxxu_read8(priv, REG_BEACON_CTRL);
> @@ -5494,6 +5536,9 @@ static void rtl8xxxu_remove_interface(struct ieee80211_hw *hw,
>         struct rtl8xxxu_priv *priv = hw->priv;
>
>         dev_dbg(&priv->udev->dev, "%s\n", __func__);
> +
> +       if (priv->vif)
> +               priv->vif = NULL;
>  }
>
>  static int rtl8xxxu_config(struct ieee80211_hw *hw, u32 changed)
> @@ -5779,6 +5824,174 @@ rtl8xxxu_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
>         return 0;
>  }
>
> +static u8 rtl8xxxu_signal_to_snr(int signal)
> +{
> +       if (signal < RTL8XXXU_NOISE_FLOOR_MIN)
> +               signal = RTL8XXXU_NOISE_FLOOR_MIN;
> +       return (u8)(signal - RTL8XXXU_NOISE_FLOOR_MIN);
> +}
> +
> +static void rtl8xxxu_refresh_rate_mask(struct rtl8xxxu_priv *priv,
> +                                      int signal, struct ieee80211_sta *sta)
> +{
> +       struct ieee80211_hw *hw = priv->hw;
> +       u16 wireless_mode;
> +       u8 rssi_level, ratr_idx;
> +       u8 txbw_40mhz;
> +       u8 snr, snr_thresh_high, snr_thresh_low;
> +       u8 go_up_gap = 5;
> +
> +       rssi_level = priv->rssi_level;
> +       snr = rtl8xxxu_signal_to_snr(signal);
> +       snr_thresh_high = RTL8XXXU_SNR_THRESH_HIGH;
> +       snr_thresh_low = RTL8XXXU_SNR_THRESH_LOW;
> +       txbw_40mhz = (hw->conf.chandef.width == NL80211_CHAN_WIDTH_40) ? 1 : 0;
> +
> +       switch (rssi_level) {
> +       case RTL8XXXU_RATR_STA_MID:
> +               snr_thresh_high += go_up_gap;
> +               break;
> +       case RTL8XXXU_RATR_STA_LOW:
> +               snr_thresh_high += go_up_gap;
> +               snr_thresh_low += go_up_gap;
> +               break;
> +       default:
> +               break;
> +       }
> +
> +       if (snr > snr_thresh_high)
> +               rssi_level = RTL8XXXU_RATR_STA_HIGH;
> +       else if (snr > snr_thresh_low)
> +               rssi_level = RTL8XXXU_RATR_STA_MID;
> +       else
> +               rssi_level = RTL8XXXU_RATR_STA_LOW;
> +
> +       if (rssi_level != priv->rssi_level) {
> +               int sgi = 0;
> +               u32 rate_bitmap = 0;
> +
> +               rcu_read_lock();
> +               rate_bitmap = (sta->supp_rates[0] & 0xfff) |
> +                               (sta->ht_cap.mcs.rx_mask[0] << 12) |
> +                               (sta->ht_cap.mcs.rx_mask[1] << 20);
> +               if (sta->ht_cap.cap &
> +                   (IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20))
> +                       sgi = 1;
> +               rcu_read_unlock();
> +
> +               wireless_mode = rtl8xxxu_wireless_mode(hw, sta);
> +               switch (wireless_mode) {
> +               case WIRELESS_MODE_B:
> +                       ratr_idx = RATEID_IDX_B;
> +                       if (rate_bitmap & 0x0000000c)
> +                               rate_bitmap &= 0x0000000d;
> +                       else
> +                               rate_bitmap &= 0x0000000f;
> +                       break;
> +               case WIRELESS_MODE_A:
> +               case WIRELESS_MODE_G:
> +                       ratr_idx = RATEID_IDX_G;
> +                       if (rssi_level == RTL8XXXU_RATR_STA_HIGH)
> +                               rate_bitmap &= 0x00000f00;
> +                       else
> +                               rate_bitmap &= 0x00000ff0;
> +                       break;
> +               case (WIRELESS_MODE_B | WIRELESS_MODE_G):
> +                       ratr_idx = RATEID_IDX_BG;
> +                       if (rssi_level == RTL8XXXU_RATR_STA_HIGH)
> +                               rate_bitmap &= 0x00000f00;
> +                       else if (rssi_level == RTL8XXXU_RATR_STA_MID)
> +                               rate_bitmap &= 0x00000ff0;
> +                       else
> +                               rate_bitmap &= 0x00000ff5;
> +                       break;
> +               case WIRELESS_MODE_N_24G:
> +               case WIRELESS_MODE_N_5G:
> +               case (WIRELESS_MODE_G | WIRELESS_MODE_N_24G):
> +               case (WIRELESS_MODE_A | WIRELESS_MODE_N_5G):
> +                       if (priv->tx_paths == 2 && priv->rx_paths == 2)
> +                               ratr_idx = RATEID_IDX_GN_N2SS;
> +                       else
> +                               ratr_idx = RATEID_IDX_GN_N1SS;
> +               case (WIRELESS_MODE_B | WIRELESS_MODE_G | WIRELESS_MODE_N_24G):
> +               case (WIRELESS_MODE_B | WIRELESS_MODE_N_24G):
> +                       if (txbw_40mhz) {
> +                               if (priv->tx_paths == 2 && priv->rx_paths == 2)
> +                                       ratr_idx = RATEID_IDX_BGN_40M_2SS;
> +                               else
> +                                       ratr_idx = RATEID_IDX_BGN_40M_1SS;
> +                       } else {
> +                               if (priv->tx_paths == 2 && priv->rx_paths == 2)
> +                                       ratr_idx = RATEID_IDX_BGN_20M_2SS_BN;
> +                               else
> +                                       ratr_idx = RATEID_IDX_BGN_20M_1SS_BN;
> +                       }
> +
> +                       if (priv->tx_paths == 2 && priv->rx_paths == 2) {
> +                               if (rssi_level == RTL8XXXU_RATR_STA_HIGH) {
> +                                       rate_bitmap &= 0x0f8f0000;
> +                               } else if (rssi_level == RTL8XXXU_RATR_STA_MID) {
> +                                       rate_bitmap &= 0x0f8ff000;
> +                               } else {
> +                                       if (txbw_40mhz)
> +                                               rate_bitmap &= 0x0f8ff015;
> +                                       else
> +                                               rate_bitmap &= 0x0f8ff005;
> +                               }
> +                       } else {
> +                               if (rssi_level == RTL8XXXU_RATR_STA_HIGH) {
> +                                       rate_bitmap &= 0x000f0000;
> +                               } else if (rssi_level == RTL8XXXU_RATR_STA_MID) {
> +                                       rate_bitmap &= 0x000ff000;
> +                               } else {
> +                                       if (txbw_40mhz)
> +                                               rate_bitmap &= 0x000ff015;
> +                                       else
> +                                               rate_bitmap &= 0x000ff005;
> +                               }
> +                       }
> +                       break;
> +               default:
> +                       ratr_idx = RATEID_IDX_BGN_40M_2SS;
> +                       rate_bitmap &= 0x0fffffff;
> +                       break;
> +               }
> +
> +               priv->rssi_level = rssi_level;
> +               priv->fops->update_rate_mask(priv, rate_bitmap, ratr_idx, sgi);
> +       }
> +}
> +
> +static void rtl8xxxu_watchdog_callback(struct work_struct *work)
> +{
> +       struct ieee80211_vif *vif;
> +       struct rtl8xxxu_priv *priv;
> +
> +       priv = container_of(work, struct rtl8xxxu_priv, ra_watchdog.work);
> +       vif = priv->vif;
> +
> +       if (vif && vif->type == NL80211_IFTYPE_STATION) {
> +               int signal;
> +               struct ieee80211_sta *sta;
> +
> +               rcu_read_lock();
> +               sta = ieee80211_find_sta(vif, vif->bss_conf.bssid);
> +               if (!sta) {
> +                       struct device *dev = &priv->udev->dev;
> +
> +                       dev_info(dev, "%s: no sta found\n", __func__);
> +                       rcu_read_unlock();
> +                       return;
> +               }
> +               rcu_read_unlock();
> +
> +               signal = ieee80211_ave_rssi(vif);
> +               rtl8xxxu_refresh_rate_mask(priv, signal, sta);
> +       }
> +
> +       schedule_delayed_work(&priv->ra_watchdog, 2 * HZ);
> +}
> +
>  static int rtl8xxxu_start(struct ieee80211_hw *hw)
>  {
>         struct rtl8xxxu_priv *priv = hw->priv;
> @@ -5835,6 +6048,8 @@ static int rtl8xxxu_start(struct ieee80211_hw *hw)
>
>                 ret = rtl8xxxu_submit_rx_urb(priv, rx_urb);
>         }
> +
> +       schedule_delayed_work(&priv->ra_watchdog, 2 * HZ);
>  exit:
>         /*
>          * Accept all data and mgmt frames
> @@ -5886,6 +6101,8 @@ static void rtl8xxxu_stop(struct ieee80211_hw *hw)
>         if (priv->usb_interrupts)
>                 rtl8xxxu_write32(priv, REG_USB_HIMR, 0);
>
> +       cancel_delayed_work_sync(&priv->ra_watchdog);
> +
>         rtl8xxxu_free_rx_resources(priv);
>         rtl8xxxu_free_tx_resources(priv);
>  }
> @@ -6058,6 +6275,7 @@ static int rtl8xxxu_probe(struct usb_interface *interface,
>         INIT_LIST_HEAD(&priv->rx_urb_pending_list);
>         spin_lock_init(&priv->rx_urb_lock);
>         INIT_WORK(&priv->rx_urb_wq, rtl8xxxu_rx_urb_work);
> +       INIT_DELAYED_WORK(&priv->ra_watchdog, rtl8xxxu_watchdog_callback);
>
>         usb_set_intfdata(interface, hw);
>
> --
> 2.21.0
>

Gentle ping. Cheers.

Chris

^ permalink raw reply

* Re: [RFC PATCH v5] rtl8xxxu: Improve TX performance of RTL8723BU on rtl8xxxu driver
From: Daniel Drake @ 2019-07-01  7:57 UTC (permalink / raw)
  To: Chris Chiu
  Cc: Jes Sorensen, Kalle Valo, David Miller, linux-wireless, netdev,
	Linux Kernel, Linux Upstreaming Team
In-Reply-To: <20190617065600.40405-1-chiu@endlessm.com>

On Mon, Jun 17, 2019 at 2:56 PM Chris Chiu <chiu@endlessm.com> wrote:
> With this commit, the tx rate of each data and qos data packet will
> be 39Mbps (MCS4) with the 0xF00000 as the tx rate mask. The 20th bit
> to 23th bit means MCS4 to MCS7. It means that the firmware still picks
> the lowest rate from the rate mask and explains why the tx rate of
> data and qos data is always lowest 1Mbps because the default rate mask
> passed is always 0xFFFFFFF ranges from the basic CCK rate, OFDM rate,
> and MCS rate. However, with Realtek's driver, the tx rate observed from
> wireshark under the same condition is almost 65Mbps or 72Mbps
suggestion: add:
, indicating that rtl8xxxu could still be further improved.

Then remove this paragraph, I think we're in agreement of the approach here:
> I believe the firmware of RTL8723BU may need fix. And I think we
> can still bring in the dm_watchdog as rtlwifi to improve from the
> driver side. Please leave precious comments for my commits and
> suggest what I can do better. Or suggest if there's any better idea
> to fix this. Thanks.

> Signed-off-by: Chris Chiu <chiu@endlessm.com>
Reviewed-by: Daniel Drake <drake@endlessm.com>

> +        * is supported and no iface_combinations are providec.

typo: provided

^ permalink raw reply

* Re: [PATCH 4/6] mt76: mt7615: unlock dfs bands
From: Kalle Valo @ 2019-07-01  7:59 UTC (permalink / raw)
  To: Lorenzo Bianconi
  Cc: Lorenzo Bianconi, Felix Fietkau, linux-wireless, Ryder Lee,
	Roy Luo, YF Luo
In-Reply-To: <CAJ0CqmU6TLhFa4ZJxWHBzvpx+5g5E4-WkSPECx47F9d3T=5YjQ@mail.gmail.com>

Lorenzo Bianconi <lorenzo.bianconi@redhat.com> writes:

>>
>> Lorenzo Bianconi <lorenzo@kernel.org> writes:
>>
>> > Unlock dfs channels since now mt7615 driver supports radar detection
>> >
>> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
>> > ---
>> >  drivers/net/wireless/mediatek/mt76/mt7615/init.c | 6 ++++++
>> >  1 file changed, 6 insertions(+)
>> >
>> > diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/init.c b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
>> > index 5dc4cced5789..6d336d82cafe 100644
>> > --- a/drivers/net/wireless/mediatek/mt76/mt7615/init.c
>> > +++ b/drivers/net/wireless/mediatek/mt76/mt7615/init.c
>> > @@ -152,6 +152,12 @@ static const struct ieee80211_iface_combination if_comb[] = {
>> >               .max_interfaces = 4,
>> >               .num_different_channels = 1,
>> >               .beacon_int_infra_match = true,
>> > +             .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
>> > +                                    BIT(NL80211_CHAN_WIDTH_20) |
>> > +                                    BIT(NL80211_CHAN_WIDTH_40) |
>> > +                                    BIT(NL80211_CHAN_WIDTH_80) |
>> > +                                    BIT(NL80211_CHAN_WIDTH_160) |
>> > +                                    BIT(NL80211_CHAN_WIDTH_80P80),
>>
>> Isn't it questionable to enable these without any testing on real
>> hardware? Getting DFS to work correctly is hard so I'm very suspicious
>> about this.
>>
>> --
>> Kalle Valo
>
> Hi Kalle,
>
> unfortunately at the moment I am not able to run any tests with a real
> signal generator so I just ported the code from vendor sdk.
> I am pretty confident it works since the radar pattern detection is
> done in fw/hw so I guess it has been already tested in the vendor sdk

DFS is really tricky to get it working right, so I'm not easily
convinced :)

> but we can postpone this patch and apply just the rest of the series
> until we have some test results.

Yeah, I think it would be best to drop this patch so that DFS is not
enabled by default and apply this patch only after positive test
results.

-- 
Kalle Valo

^ permalink raw reply


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