Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH v2 06/14] rt2x00: rt2800lib: init additional beacon offset registers
From: Daniel Golle @ 2017-01-16  3:03 UTC (permalink / raw)
  To: linux-wireless
  Cc: Johannes Berg, Stanislaw Gruszka, roman, michel.stempin,
	c.mignanti, evaxige, Kalle Valo, Felix Fietkau, John Crispin,
	Gabor Juhos
In-Reply-To: <874m114lwq.fsf@codeaurora.org>

From: Gabor Juhos <juhosg@openwrt.org>

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/wireless/ralink/rt2x00/rt2800.h    | 14 ++++++++++++++
 drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 24 ++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h
index a81852cfb4f9..02ed0d512734 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
@@ -629,6 +629,20 @@
  */
 #define PBF_DBG				0x043c
 
+/* BCN_OFFSET2 */
+#define BCN_OFFSET2			0x0444
+#define BCN_OFFSET2_BCN8		FIELD32(0x000000ff)
+#define BCN_OFFSET2_BCN9		FIELD32(0x0000ff00)
+#define BCN_OFFSET2_BCN10		FIELD32(0x00ff0000)
+#define BCN_OFFSET2_BCN11		FIELD32(0xff000000)
+
+/* BCN_OFFSET3 */
+#define BCN_OFFSET3			0x0448
+#define BCN_OFFSET3_BCN12		FIELD32(0x000000ff)
+#define BCN_OFFSET3_BCN13		FIELD32(0x0000ff00)
+#define BCN_OFFSET3_BCN14		FIELD32(0x00ff0000)
+#define BCN_OFFSET3_BCN15		FIELD32(0xff000000)
+
 /*
  * RF registers
  */
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 0893d9147af9..5058494d6c27 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -4665,6 +4665,30 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
 	if (ret)
 		return ret;
 
+	if (drv_data->hw_beacon_count == 16) {
+		rt2800_register_read(rt2x00dev, BCN_OFFSET2, &reg);
+		rt2x00_set_field32(&reg, BCN_OFFSET2_BCN8,
+				   rt2800_get_beacon_offset(rt2x00dev, 8));
+		rt2x00_set_field32(&reg, BCN_OFFSET2_BCN9,
+				   rt2800_get_beacon_offset(rt2x00dev, 9));
+		rt2x00_set_field32(&reg, BCN_OFFSET2_BCN10,
+				   rt2800_get_beacon_offset(rt2x00dev, 10));
+		rt2x00_set_field32(&reg, BCN_OFFSET2_BCN11,
+				   rt2800_get_beacon_offset(rt2x00dev, 11));
+		rt2800_register_write(rt2x00dev, BCN_OFFSET2, reg);
+
+		rt2800_register_read(rt2x00dev, BCN_OFFSET3, &reg);
+		rt2x00_set_field32(&reg, BCN_OFFSET3_BCN12,
+				   rt2800_get_beacon_offset(rt2x00dev, 12));
+		rt2x00_set_field32(&reg, BCN_OFFSET3_BCN13,
+				   rt2800_get_beacon_offset(rt2x00dev, 13));
+		rt2x00_set_field32(&reg, BCN_OFFSET3_BCN14,
+				   rt2800_get_beacon_offset(rt2x00dev, 14));
+		rt2x00_set_field32(&reg, BCN_OFFSET3_BCN15,
+				   rt2800_get_beacon_offset(rt2x00dev, 15));
+		rt2800_register_write(rt2x00dev, BCN_OFFSET3, reg);
+	}
+
 	rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
 	rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
 
-- 
2.11.0

^ permalink raw reply related

* [PATCH v2 07/14] rt2x00: rt2800lib: fix max supported beacon count for RT3593
From: Daniel Golle @ 2017-01-16  3:03 UTC (permalink / raw)
  To: linux-wireless
  Cc: Johannes Berg, Stanislaw Gruszka, roman, michel.stempin,
	c.mignanti, evaxige, Kalle Valo, Felix Fietkau, John Crispin,
	Gabor Juhos
In-Reply-To: <874m114lwq.fsf@codeaurora.org>

From: Gabor Juhos <juhosg@openwrt.org>

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 5058494d6c27..ff653f0d43d2 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -7899,7 +7899,10 @@ int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
 	if (rt2x00_rt(rt2x00dev, RT3593))
 		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
 
-	drv_data->hw_beacon_count = 8;
+	if (rt2x00_rt(rt2x00dev, RT3593))
+		drv_data->hw_beacon_count = 16;
+	else
+		drv_data->hw_beacon_count = 8;
 
 	/*
 	 * Allocate eeprom data.
-- 
2.11.0

^ permalink raw reply related

* [PATCH v2 05/14] rt2x00: rt2800lib: add hw_beacon_count field to struct rt2800_drv_data
From: Daniel Golle @ 2017-01-16  3:02 UTC (permalink / raw)
  To: linux-wireless
  Cc: Johannes Berg, Stanislaw Gruszka, roman, michel.stempin,
	c.mignanti, evaxige, Kalle Valo, Felix Fietkau, John Crispin,
	Gabor Juhos
In-Reply-To: <874m114lwq.fsf@codeaurora.org>

From: Gabor Juhos <juhosg@openwrt.org>

Some chipsets can handle more than 8 beacons at once.
Add a new field to the rt2800_drv_data structure which
will hold the number of supported beacons of the given
chipset.

Update the rt2x00_init_registers function to get the
beacon count from the new field instead of using a
hardcoded value.

In order to keep the current behaviour, initialize the
new field with the actually used value.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 4 +++-
 drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index dcacfa54b3d6..0893d9147af9 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -5025,7 +5025,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Clear all beacons
 	 */
-	for (i = 0; i < 8; i++)
+	for (i = 0; i < drv_data->hw_beacon_count; i++)
 		rt2800_clear_beacon_register(rt2x00dev, i);
 
 	if (rt2x00_is_usb(rt2x00dev)) {
@@ -7875,6 +7875,8 @@ int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
 	if (rt2x00_rt(rt2x00dev, RT3593))
 		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
 
+	drv_data->hw_beacon_count = 8;
+
 	/*
 	 * Allocate eeprom data.
 	 */
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
index ccfa8cf1f5ac..ab49e6feeeb9 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
@@ -37,6 +37,7 @@ struct rt2800_drv_data {
 	u8 max_psdu;
 	unsigned int tbtt_tick;
 	unsigned int ampdu_factor_cnt[4];
+	unsigned int hw_beacon_count;
 	DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
 
 	unsigned long rt2800_flags;
-- 
2.11.0

^ permalink raw reply related

* [PATCH v2 04/14] rt2x00: rt2800lib: fix beacon generation on RT3593
From: Daniel Golle @ 2017-01-16  3:01 UTC (permalink / raw)
  To: linux-wireless
  Cc: Johannes Berg, Stanislaw Gruszka, roman, michel.stempin,
	c.mignanti, evaxige, Kalle Valo, Felix Fietkau, John Crispin,
	Gabor Juhos
In-Reply-To: <874m114lwq.fsf@codeaurora.org>

From: Gabor Juhos <juhosg@openwrt.org>

On the RT3593 chipset, the beacon registers are located
in the high 8KB part of the shared memory.

The high part of the shared memory is only accessible
if it is explicitly selected. Add a helper function
in order to be able to control the SHR_MSEL bit in
the PBF_SYS_CTRL register. Also add a few more helper
functions and use those to select the correct part of
the shared memory before and after accessing the beacon
registers.

The base addresses of the beacon registers are also
different from the actually used values, so fix the
'rt2800_hw_beacon_base' function to return the correct
values.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/wireless/ralink/rt2x00/rt2800.h    |  3 ++
 drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 44 ++++++++++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h
index 2371896c1e99..a81852cfb4f9 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
@@ -574,6 +574,7 @@
 #define PBF_SYS_CTRL			0x0400
 #define PBF_SYS_CTRL_READY		FIELD32(0x00000080)
 #define PBF_SYS_CTRL_HOST_RAM_WRITE	FIELD32(0x00010000)
+#define PBF_SYS_CTRL_SHR_MSEL		FIELD32(0x00080000)
 
 /*
  * HOST-MCU shared memory
@@ -2026,6 +2027,8 @@ struct mac_iveiv_entry {
 	  (((__index) < 6) ? (HW_BEACON_BASE4 + ((__index - 4) * 0x0200)) : \
 	  (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))))
 
+#define HW_BEACON_BASE_HIGH(__index)	(0x4000 + (__index) * 512)
+
 #define BEACON_BASE_TO_OFFSET(_base)	(((_base) - 0x4000) / 64)
 
 /*
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 0fd67026f806..dcacfa54b3d6 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -82,6 +82,39 @@ static inline bool rt2800_is_305x_soc(struct rt2x00_dev *rt2x00dev)
 	return false;
 }
 
+static inline void rt2800_shared_mem_select(struct rt2x00_dev *rt2x00dev,
+					    bool high)
+{
+	u32 reg;
+
+	if (WARN_ON_ONCE(!rt2800_has_high_shared_mem(rt2x00dev)))
+		return;
+
+	rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+	rt2x00_set_field32(&reg, PBF_SYS_CTRL_SHR_MSEL, high);
+	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg);
+}
+
+static inline bool rt2800_beacon_uses_high_mem(struct rt2x00_dev *rt2x00dev)
+{
+	if (rt2x00_rt(rt2x00dev, RT3593))
+		return true;
+
+	return false;
+}
+
+static inline void rt2800_select_beacon_mem(struct rt2x00_dev *rt2x00dev)
+{
+	if (rt2800_beacon_uses_high_mem(rt2x00dev))
+		rt2800_shared_mem_select(rt2x00dev, true);
+}
+
+static inline void rt2800_deselect_beacon_mem(struct rt2x00_dev *rt2x00dev)
+{
+	if (rt2800_beacon_uses_high_mem(rt2x00dev))
+		rt2800_shared_mem_select(rt2x00dev, false);
+}
+
 static void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev,
 			     const unsigned int word, const u8 value)
 {
@@ -948,6 +981,9 @@ EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
 static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
 					  unsigned int index)
 {
+	if (rt2x00_rt(rt2x00dev, RT3593))
+		return HW_BEACON_BASE_HIGH(index);
+
 	return HW_BEACON_BASE(index);
 }
 
@@ -1046,8 +1082,12 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
 	beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx);
 
 	rt2800_shared_mem_lock(rt2x00dev);
+
+	rt2800_select_beacon_mem(rt2x00dev);
 	rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
 				   entry->skb->len + padding_len);
+	rt2800_deselect_beacon_mem(rt2x00dev);
+
 	rt2800_shared_mem_unlock(rt2x00dev);
 	__set_bit(ENTRY_BCN_ENABLED, &entry->flags);
 
@@ -1080,6 +1120,8 @@ static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev,
 
 	rt2800_shared_mem_lock(rt2x00dev);
 
+	rt2800_select_beacon_mem(rt2x00dev);
+
 	/*
 	 * For the Beacon base registers we only need to clear
 	 * the whole TXWI which (when set to 0) will invalidate
@@ -1088,6 +1130,8 @@ static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev,
 	for (i = 0; i < txwi_desc_size; i += sizeof(__le32))
 		rt2800_register_write(rt2x00dev, beacon_base + i, 0);
 
+	rt2800_deselect_beacon_mem(rt2x00dev);
+
 	rt2800_shared_mem_unlock(rt2x00dev);
 }
 
-- 
2.11.0

^ permalink raw reply related

* [PATCH v2 03/14] rt2x00: rt2800: serialize shared memory access
From: Daniel Golle @ 2017-01-16  2:58 UTC (permalink / raw)
  To: linux-wireless
  Cc: Johannes Berg, Stanislaw Gruszka, roman, michel.stempin,
	c.mignanti, evaxige, Kalle Valo, Felix Fietkau, John Crispin,
	Gabor Juhos
In-Reply-To: <874m114lwq.fsf@codeaurora.org>

From: Gabor Juhos <juhosg@openwrt.org>

The shared memory of the rt2800 devices is accessible
through the register offset range between 0x4000 and
0x8000. The size of this range is 16KB only and on
devices which have more than 16KB of shared memory either
the low or the high part of the memory is accessible at a
time.

Serialize all accesses to the shared memory by a mutex,
in order to avoid concurrent use of that.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/wireless/ralink/rt2x00/rt2800lib.c  | 55 ++++++++++++++++++++++++-
 drivers/net/wireless/ralink/rt2x00/rt2800lib.h  | 35 ++++++++++++++++
 drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 26 ++++++++++++
 drivers/net/wireless/ralink/rt2x00/rt2800mmio.h |  4 ++
 drivers/net/wireless/ralink/rt2x00/rt2800pci.c  | 14 +++++++
 drivers/net/wireless/ralink/rt2x00/rt2800soc.c  |  3 ++
 drivers/net/wireless/ralink/rt2x00/rt2800usb.c  | 31 ++++++++++++++
 7 files changed, 167 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 5045af1b0dc9..0fd67026f806 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -451,11 +451,13 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
 		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_CMD_TOKEN, token);
 		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG0, arg0);
 		rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG1, arg1);
+		rt2800_shared_mem_lock(rt2x00dev);
 		rt2800_register_write_lock(rt2x00dev, H2M_MAILBOX_CSR, reg);
 
 		reg = 0;
 		rt2x00_set_field32(&reg, HOST_CMD_CSR_HOST_COMMAND, command);
 		rt2800_register_write_lock(rt2x00dev, HOST_CMD_CSR, reg);
+		rt2800_shared_mem_unlock(rt2x00dev);
 	}
 
 	mutex_unlock(&rt2x00dev->csr_mutex);
@@ -674,7 +676,9 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
 	 * Wait for device to stabilize.
 	 */
 	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+		rt2800_shared_mem_lock(rt2x00dev);
 		rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+		rt2800_shared_mem_unlock(rt2x00dev);
 		if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY))
 			break;
 		msleep(1);
@@ -694,10 +698,16 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
 	/*
 	 * Initialize firmware.
 	 */
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
 	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+	rt2800_shared_mem_unlock(rt2x00dev);
+
 	if (rt2x00_is_usb(rt2x00dev)) {
+		rt2800_shared_mem_lock(rt2x00dev);
 		rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
+		rt2800_shared_mem_unlock(rt2x00dev);
+
 		rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
 	}
 	msleep(1);
@@ -1035,8 +1045,10 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
 
 	beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx);
 
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
 				   entry->skb->len + padding_len);
+	rt2800_shared_mem_unlock(rt2x00dev);
 	__set_bit(ENTRY_BCN_ENABLED, &entry->flags);
 
 	/*
@@ -1066,6 +1078,8 @@ static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev,
 
 	beacon_base = rt2800_hw_beacon_base(rt2x00dev, index);
 
+	rt2800_shared_mem_lock(rt2x00dev);
+
 	/*
 	 * For the Beacon base registers we only need to clear
 	 * the whole TXWI which (when set to 0) will invalidate
@@ -1073,6 +1087,8 @@ static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev,
 	 */
 	for (i = 0; i < txwi_desc_size; i += sizeof(__le32))
 		rt2800_register_write(rt2x00dev, beacon_base + i, 0);
+
+	rt2800_shared_mem_unlock(rt2x00dev);
 }
 
 void rt2800_clear_beacon(struct queue_entry *entry)
@@ -1261,7 +1277,9 @@ static void rt2800_delete_wcid_attr(struct rt2x00_dev *rt2x00dev, int wcid)
 {
 	u32 offset;
 	offset = MAC_WCID_ATTR_ENTRY(wcid);
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_write(rt2x00dev, offset, 0);
+	rt2800_shared_mem_unlock(rt2x00dev);
 }
 
 static void rt2800_config_wcid_attr_bssidx(struct rt2x00_dev *rt2x00dev,
@@ -1274,11 +1292,13 @@ static void rt2800_config_wcid_attr_bssidx(struct rt2x00_dev *rt2x00dev,
 	 * The BSS Idx numbers is split in a main value of 3 bits,
 	 * and a extended field for adding one additional bit to the value.
 	 */
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_read(rt2x00dev, offset, &reg);
 	rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX, (bssidx & 0x7));
 	rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX_EXT,
 			   (bssidx & 0x8) >> 3);
 	rt2800_register_write(rt2x00dev, offset, reg);
+	rt2800_shared_mem_unlock(rt2x00dev);
 }
 
 static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev,
@@ -1291,6 +1311,7 @@ static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev,
 
 	offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx);
 
+	rt2800_shared_mem_lock(rt2x00dev);
 	if (crypto->cmd == SET_KEY) {
 		rt2800_register_read(rt2x00dev, offset, &reg);
 		rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
@@ -1315,6 +1336,7 @@ static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev,
 		rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, 0);
 		rt2800_register_write(rt2x00dev, offset, reg);
 	}
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
 
@@ -1324,8 +1346,11 @@ static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev,
 	    (crypto->cipher == CIPHER_AES))
 		iveiv_entry.iv[3] |= 0x20;
 	iveiv_entry.iv[3] |= key->keyidx << 6;
+
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_multiwrite(rt2x00dev, offset,
 				      &iveiv_entry, sizeof(iveiv_entry));
+	rt2800_shared_mem_unlock(rt2x00dev);
 }
 
 int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
@@ -1348,8 +1373,11 @@ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
 		       sizeof(key_entry.rx_mic));
 
 		offset = SHARED_KEY_ENTRY(key->hw_key_idx);
+
+		rt2800_shared_mem_lock(rt2x00dev);
 		rt2800_register_multiwrite(rt2x00dev, offset,
 					      &key_entry, sizeof(key_entry));
+		rt2800_shared_mem_unlock(rt2x00dev);
 	}
 
 	/*
@@ -1364,10 +1392,12 @@ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
 
 	offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8);
 
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_read(rt2x00dev, offset, &reg);
 	rt2x00_set_field32(&reg, field,
 			   (crypto->cmd == SET_KEY) * crypto->cipher);
 	rt2800_register_write(rt2x00dev, offset, reg);
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	/*
 	 * Update WCID information
@@ -1405,8 +1435,11 @@ int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
 		       sizeof(key_entry.rx_mic));
 
 		offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
+
+		rt2800_shared_mem_lock(rt2x00dev);
 		rt2800_register_multiwrite(rt2x00dev, offset,
 					      &key_entry, sizeof(key_entry));
+		rt2800_shared_mem_unlock(rt2x00dev);
 	}
 
 	/*
@@ -4930,14 +4963,19 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * ASIC will keep garbage value after boot, clear encryption keys.
 	 */
+	rt2800_shared_mem_lock(rt2x00dev);
 	for (i = 0; i < 4; i++)
 		rt2800_register_write(rt2x00dev,
 					 SHARED_KEY_MODE_ENTRY(i), 0);
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	for (i = 0; i < 256; i++) {
 		rt2800_config_wcid(rt2x00dev, NULL, i);
 		rt2800_delete_wcid_attr(rt2x00dev, i);
+
+		rt2800_shared_mem_lock(rt2x00dev);
 		rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
+		rt2800_shared_mem_unlock(rt2x00dev);
 	}
 
 	/*
@@ -5063,8 +5101,10 @@ static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
 	 * BBP was enabled after firmware was loaded,
 	 * but we need to reactivate it now.
 	 */
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
 	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+	rt2800_shared_mem_unlock(rt2x00dev);
 	msleep(1);
 
 	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
@@ -6760,11 +6800,19 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Send signal during boot time to initialize firmware.
 	 */
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
 	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
-	if (rt2x00_is_usb(rt2x00dev))
+	rt2800_shared_mem_unlock(rt2x00dev);
+
+	if (rt2x00_is_usb(rt2x00dev)) {
+		rt2800_shared_mem_lock(rt2x00dev);
 		rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
+		rt2800_shared_mem_unlock(rt2x00dev);
+	}
+
 	rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
+
 	msleep(1);
 
 	/*
@@ -7774,6 +7822,8 @@ int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
 	int retval;
 	u32 reg;
 
+	rt2800_shared_mem_init_lock(rt2x00dev);
+
 	retval = rt2800_probe_rt(rt2x00dev);
 	if (retval)
 		return retval;
@@ -7857,8 +7907,11 @@ void rt2800_get_key_seq(struct ieee80211_hw *hw,
 		return;
 
 	offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
+
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_multiread(rt2x00dev, offset,
 				      &iveiv_entry, sizeof(iveiv_entry));
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	memcpy(&seq->tkip.iv16, &iveiv_entry.iv[0], 2);
 	memcpy(&seq->tkip.iv32, &iveiv_entry.iv[4], 4);
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
index 4ee424dfe23f..ccfa8cf1f5ac 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
@@ -40,6 +40,14 @@ struct rt2800_drv_data {
 	DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
 
 	unsigned long rt2800_flags;
+
+	/* locks to serialize shared memory access */
+	union {
+		/* a spinlock is used for MMIO devices */
+		spinlock_t spin;
+		/* a mutex is used for PCI devices */
+		struct mutex mutex;
+	} shmem_lock;
 };
 
 struct rt2800_ops {
@@ -70,6 +78,10 @@ struct rt2800_ops {
 				  const u8 *data, const size_t len);
 	int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
 	__le32 *(*drv_get_txwi)(struct queue_entry *entry);
+
+	void (*shmem_init_lock)(struct rt2x00_dev *rt2x00dev);
+	void (*shmem_lock)(struct rt2x00_dev *rt2x00dev);
+	void (*shmem_unlock)(struct rt2x00_dev *rt2x00dev);
 };
 
 static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev)
@@ -79,6 +91,29 @@ static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev)
 	return test_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
 }
 
+static inline void rt2800_shared_mem_init_lock(struct rt2x00_dev *rt2x00dev)
+{
+	const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
+
+	rt2800ops->shmem_init_lock(rt2x00dev);
+}
+
+static inline void rt2800_shared_mem_lock(struct rt2x00_dev *rt2x00dev)
+{
+	const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
+
+	if (rt2800_has_high_shared_mem(rt2x00dev))
+		rt2800ops->shmem_lock(rt2x00dev);
+}
+
+static inline void rt2800_shared_mem_unlock(struct rt2x00_dev *rt2x00dev)
+{
+	const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
+
+	if (rt2800_has_high_shared_mem(rt2x00dev))
+		rt2800ops->shmem_unlock(rt2x00dev);
+}
+
 static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev,
 					const unsigned int offset,
 					u32 *value)
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
index de4790b41be7..5f1936aa8fa7 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c
@@ -820,8 +820,10 @@ int rt2800mmio_init_registers(struct rt2x00_dev *rt2x00dev)
 	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
 	rt2x00mmio_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
 
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
 	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	if (rt2x00_is_pcie(rt2x00dev) &&
 	    (rt2x00_rt(rt2x00dev, RT3090) ||
@@ -865,6 +867,30 @@ int rt2800mmio_enable_radio(struct rt2x00_dev *rt2x00dev)
 }
 EXPORT_SYMBOL_GPL(rt2800mmio_enable_radio);
 
+void rt2800mmio_shmem_init_lock(struct rt2x00_dev *rt2x00dev)
+{
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+
+	spin_lock_init(&drv_data->shmem_lock.spin);
+}
+EXPORT_SYMBOL_GPL(rt2800mmio_shmem_init_lock);
+
+void rt2800mmio_shmem_lock(struct rt2x00_dev *rt2x00dev)
+{
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+
+	spin_lock_bh(&drv_data->shmem_lock.spin);
+}
+EXPORT_SYMBOL_GPL(rt2800mmio_shmem_lock);
+
+void rt2800mmio_shmem_unlock(struct rt2x00_dev *rt2x00dev)
+{
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+
+	spin_unlock_bh(&drv_data->shmem_lock.spin);
+}
+EXPORT_SYMBOL_GPL(rt2800mmio_shmem_unlock);
+
 MODULE_AUTHOR(DRV_PROJECT);
 MODULE_VERSION(DRV_VERSION);
 MODULE_DESCRIPTION("rt2800 MMIO library");
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h
index b63312ce3f27..352b409dcff2 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h
@@ -160,4 +160,8 @@ int rt2800mmio_init_registers(struct rt2x00_dev *rt2x00dev);
 /* Device state switch handlers. */
 int rt2800mmio_enable_radio(struct rt2x00_dev *rt2x00dev);
 
+void rt2800mmio_shmem_init_lock(struct rt2x00_dev *rt2x00dev);
+void rt2800mmio_shmem_lock(struct rt2x00_dev *rt2x00dev);
+void rt2800mmio_shmem_unlock(struct rt2x00_dev *rt2x00dev);
+
 #endif /* RT2800MMIO_H */
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
index 0af22573a2eb..beb1199acccb 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c
@@ -69,7 +69,9 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
 		return;
 
 	for (i = 0; i < 200; i++) {
+		rt2800_shared_mem_lock(rt2x00dev);
 		rt2x00mmio_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg);
+		rt2800_shared_mem_unlock(rt2x00dev);
 
 		if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) ||
 		    (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) ||
@@ -83,8 +85,10 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
 	if (i == 200)
 		rt2x00_err(rt2x00dev, "MCU request failed, no response from hardware\n");
 
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+	rt2800_shared_mem_unlock(rt2x00dev);
 }
 
 static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom)
@@ -184,6 +188,8 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev,
 	 */
 	reg = 0;
 	rt2x00_set_field32(&reg, PBF_SYS_CTRL_HOST_RAM_WRITE, 1);
+
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, reg);
 
 	/*
@@ -197,6 +203,7 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev,
 
 	rt2x00mmio_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	return 0;
 }
@@ -213,8 +220,10 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
 		return retval;
 
 	/* After resume MCU_BOOT_SIGNAL will trash these. */
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_RADIO_OFF, 0xff, 0x02);
 	rt2800pci_mcu_status(rt2x00dev, TOKEN_RADIO_OFF);
@@ -233,10 +242,12 @@ static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
 				   0, 0x02);
 		rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP);
 	} else if (state == STATE_SLEEP) {
+		rt2800_shared_mem_lock(rt2x00dev);
 		rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS,
 					  0xffffffff);
 		rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID,
 					  0xffffffff);
+		rt2800_shared_mem_unlock(rt2x00dev);
 		rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_SLEEP,
 				   0xff, 0x01);
 	}
@@ -337,6 +348,9 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = {
 	.drv_write_firmware	= rt2800pci_write_firmware,
 	.drv_init_registers	= rt2800mmio_init_registers,
 	.drv_get_txwi		= rt2800mmio_get_txwi,
+	.shmem_init_lock	= rt2800mmio_shmem_init_lock,
+	.shmem_lock		= rt2800mmio_shmem_lock,
+	.shmem_unlock		= rt2800mmio_shmem_unlock,
 };
 
 static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
index a985a5a7945e..871d9d331046 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c
@@ -176,6 +176,9 @@ static const struct rt2800_ops rt2800soc_rt2800_ops = {
 	.drv_write_firmware	= rt2800soc_write_firmware,
 	.drv_init_registers	= rt2800mmio_init_registers,
 	.drv_get_txwi		= rt2800mmio_get_txwi,
+	.shmem_init_lock	= rt2800mmio_shmem_init_lock,
+	.shmem_lock		= rt2800mmio_shmem_lock,
+	.shmem_unlock		= rt2800mmio_shmem_unlock,
 };
 
 static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = {
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
index f38c44061b5b..f8d905c63ac8 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
@@ -51,6 +51,27 @@ static bool rt2800usb_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev)
 	return modparam_nohwcrypt;
 }
 
+static void rt2800usb_shmem_init_lock(struct rt2x00_dev *rt2x00dev)
+{
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+
+	mutex_init(&drv_data->shmem_lock.mutex);
+}
+
+static void rt2800usb_shmem_lock(struct rt2x00_dev *rt2x00dev)
+{
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+
+	mutex_lock(&drv_data->shmem_lock.mutex);
+}
+
+static void rt2800usb_shmem_unlock(struct rt2x00_dev *rt2x00dev)
+{
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+
+	mutex_unlock(&drv_data->shmem_lock.mutex);
+}
+
 /*
  * Queue handlers.
  */
@@ -299,8 +320,10 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
 					      data + offset, length);
 	}
 
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
 	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	/*
 	 * Send firmware request to device to load firmware,
@@ -315,7 +338,10 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
 	}
 
 	msleep(10);
+
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	return 0;
 }
@@ -333,8 +359,10 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
 	if (rt2800_wait_csr_ready(rt2x00dev))
 		return -EBUSY;
 
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
 	rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	reg = 0;
 	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
@@ -860,6 +888,9 @@ static const struct rt2800_ops rt2800usb_rt2800_ops = {
 	.drv_write_firmware	= rt2800usb_write_firmware,
 	.drv_init_registers	= rt2800usb_init_registers,
 	.drv_get_txwi		= rt2800usb_get_txwi,
+	.shmem_init_lock	= rt2800usb_shmem_init_lock,
+	.shmem_lock		= rt2800usb_shmem_lock,
+	.shmem_unlock		= rt2800usb_shmem_unlock,
 };
 
 static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
-- 
2.11.0

^ permalink raw reply related

* [PATCH v2 02/14] rt2x00: rt2800lib: introduce RT2800_HAS_HIGH_SHARED_MEM flag
From: Daniel Golle @ 2017-01-16  2:55 UTC (permalink / raw)
  To: linux-wireless
  Cc: Johannes Berg, Stanislaw Gruszka, roman, michel.stempin,
	c.mignanti, evaxige, Kalle Valo, Felix Fietkau, John Crispin,
	Gabor Juhos
In-Reply-To: <874m114lwq.fsf@codeaurora.org>

From: Gabor Juhos <juhosg@openwrt.org>

Some chipsets have more than 16KB of shared memory.
Introduce a new rt2800 specific flag to indicate that
and add a helper function which helps to check the
presence of the new flag.

Also enable the new flag for the RT3593 chipset which
has 24KB of shared memory. The flag can also be used
for other chipsets, but none of those has been tested
yet.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/wireless/ralink/rt2x00/rt2800lib.c |  4 ++++
 drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 13 +++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
index 5436cdb07937..5045af1b0dc9 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c
@@ -7770,6 +7770,7 @@ static int rt2800_probe_rt(struct rt2x00_dev *rt2x00dev)
 
 int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
 {
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
 	int retval;
 	u32 reg;
 
@@ -7777,6 +7778,9 @@ int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
 	if (retval)
 		return retval;
 
+	if (rt2x00_rt(rt2x00dev, RT3593))
+		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
+
 	/*
 	 * Allocate eeprom data.
 	 */
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
index 256928f0ea6a..4ee424dfe23f 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
@@ -22,6 +22,10 @@
 
 #include "rt2800.h"
 
+enum rt2800_flag {
+	RT2800_HAS_HIGH_SHARED_MEM,
+};
+
 /* RT2800 driver data structure */
 struct rt2800_drv_data {
 	u8 calibration_bw20;
@@ -34,6 +38,8 @@ struct rt2800_drv_data {
 	unsigned int tbtt_tick;
 	unsigned int ampdu_factor_cnt[4];
 	DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
+
+	unsigned long rt2800_flags;
 };
 
 struct rt2800_ops {
@@ -66,6 +72,13 @@ struct rt2800_ops {
 	__le32 *(*drv_get_txwi)(struct queue_entry *entry);
 };
 
+static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev)
+{
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+
+	return test_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
+}
+
 static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev,
 					const unsigned int offset,
 					u32 *value)
-- 
2.11.0

^ permalink raw reply related

* [PATCH v2 01/14] rt2x00: rt2800lib: move rt2800_drv_data declaration into rt2800lib.h
From: Daniel Golle @ 2017-01-16  2:55 UTC (permalink / raw)
  To: linux-wireless
  Cc: Johannes Berg, Stanislaw Gruszka, roman, michel.stempin,
	c.mignanti, evaxige, Kalle Valo, Felix Fietkau, John Crispin,
	Gabor Juhos
In-Reply-To: <874m114lwq.fsf@codeaurora.org>

From: Gabor Juhos <juhosg@openwrt.org>

The rt2800_drv_data structure contains driver specific
information. Move the declaration into the rt2800lib.h
header which is a more logical place for it. Also fix
the comment style to avoid checkpatch warning.

The patch contains no functional changes, it is in
preparation for the next patch.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/wireless/ralink/rt2x00/rt2800.h    | 16 ----------------
 drivers/net/wireless/ralink/rt2x00/rt2800lib.h | 16 ++++++++++++++++
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h
index ec622a08a486..2371896c1e99 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h
@@ -2969,20 +2969,4 @@ enum rt2800_eeprom_word {
 #define WCID_END	222
 #define STA_IDS_SIZE	(WCID_END - WCID_START + 2)
 
-/*
- * RT2800 driver data structure
- */
-struct rt2800_drv_data {
-	u8 calibration_bw20;
-	u8 calibration_bw40;
-	u8 bbp25;
-	u8 bbp26;
-	u8 txmixer_gain_24g;
-	u8 txmixer_gain_5g;
-	u8 max_psdu;
-	unsigned int tbtt_tick;
-	unsigned int ampdu_factor_cnt[4];
-	DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
-};
-
 #endif /* RT2800_H */
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
index 0a8b4df665fe..256928f0ea6a 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h
@@ -20,6 +20,22 @@
 #ifndef RT2800LIB_H
 #define RT2800LIB_H
 
+#include "rt2800.h"
+
+/* RT2800 driver data structure */
+struct rt2800_drv_data {
+	u8 calibration_bw20;
+	u8 calibration_bw40;
+	u8 bbp25;
+	u8 bbp26;
+	u8 txmixer_gain_24g;
+	u8 txmixer_gain_5g;
+	u8 max_psdu;
+	unsigned int tbtt_tick;
+	unsigned int ampdu_factor_cnt[4];
+	DECLARE_BITMAP(sta_ids, STA_IDS_SIZE);
+};
+
 struct rt2800_ops {
 	void (*register_read)(struct rt2x00_dev *rt2x00dev,
 			      const unsigned int offset, u32 *value);
-- 
2.11.0

^ permalink raw reply related

* [PATCH v2 00/14] rt2x00 patches from OpenWrt.org
From: Daniel Golle @ 2017-01-16  2:53 UTC (permalink / raw)
  To: linux-wireless
  Cc: Johannes Berg, Stanislaw Gruszka, roman, michel.stempin,
	c.mignanti, evaxige, Kalle Valo, Felix Fietkau, John Crispin,
	Gabor Juhos
In-Reply-To: <874m114lwq.fsf@codeaurora.org>

As requested the original series was devided so that everything except
for Rt3883 can go first. What's left are a couple of fixes and as well
as added support for some Rt3352 boards as well as the Rt5350 WiSoC.

Claudio Mignanti (1):
  rt2x00: rt2x00pci: set PCI MWI only if supported

Daniel Golle (2):
  rt2x00: rt2800lib: support for for RT3352 with external PA
  rt2x00: rt2800lib: add support for RT3352 with 20MHz crystal

Felix Fietkau (1):
  rt2x00: rt2800lib: fix rf id for RT3352

Gabor Juhos (8):
  rt2x00: rt2800lib: move rt2800_drv_data declaration into rt2800lib.h
  rt2x00: rt2800lib: introduce RT2800_HAS_HIGH_SHARED_MEM flag
  rt2x00: rt2800: serialize shared memory access
  rt2x00: rt2800lib: fix beacon generation on RT3593
  rt2x00: rt2800lib: add hw_beacon_count field to struct rt2800_drv_data
  rt2x00: rt2800lib: init additional beacon offset registers
  rt2x00: rt2800lib: fix max supported beacon count for RT3593
  rt2x00: rt2800mmio: add a workaround for spurious TX_FIFO_STATUS
    interrupts

Michel Stempin (1):
  rt2x00: add support for RT5350 WiSoC

Serge Vasilugin (1):
  rt2x00: rt2800lib: correctly set HT20/HT40 filter

 drivers/net/wireless/ralink/rt2x00/rt2800.h     |  60 +++-
 drivers/net/wireless/ralink/rt2x00/rt2800lib.c  | 406 ++++++++++++++++++++++--
 drivers/net/wireless/ralink/rt2x00/rt2800lib.h  |  65 ++++
 drivers/net/wireless/ralink/rt2x00/rt2800mmio.c |  98 +++++-
 drivers/net/wireless/ralink/rt2x00/rt2800mmio.h |   4 +
 drivers/net/wireless/ralink/rt2x00/rt2800pci.c  |  14 +
 drivers/net/wireless/ralink/rt2x00/rt2800soc.c  |   3 +
 drivers/net/wireless/ralink/rt2x00/rt2800usb.c  |  31 ++
 drivers/net/wireless/ralink/rt2x00/rt2x00.h     |  10 +
 drivers/net/wireless/ralink/rt2x00/rt2x00pci.c  |   2 +
 10 files changed, 640 insertions(+), 53 deletions(-)

-- 
2.11.0

^ permalink raw reply

* Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip
From: Shawn Lin @ 2017-01-16  2:35 UTC (permalink / raw)
  To: Matt Ranostay
  Cc: shawn.lin, linux-wireless, Linux Kernel, linux-mmc, devicetree,
	Tony Lindgren, Ulf Hansson
In-Reply-To: <CAJ_EiSQtPUwv9K7CbM5e_wnre6=qR=+hgtq-oVFub2phijvXgA@mail.gmail.com>

On 2017/1/16 5:41, Matt Ranostay wrote:
> On Thu, Jan 12, 2017 at 11:16 PM, Shawn Lin <shawn.lin@rock-chips.com> wrote:
>> On 2017/1/13 13:29, Matt Ranostay wrote:
>>>
>>> Allow power sequencing for the Marvell SD8787 Wifi/BT chip.
>>> This can be abstracted to other chipsets if needed in the future.
>>>
>>> Cc: Tony Lindgren <tony@atomide.com>
>>> Cc: Ulf Hansson <ulf.hansson@linaro.org>
>>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>>> ---
>>>  drivers/mmc/core/Kconfig         |  10 ++++
>>>  drivers/mmc/core/Makefile        |   1 +
>>>  drivers/mmc/core/pwrseq_sd8787.c | 117
>>> +++++++++++++++++++++++++++++++++++++++
>>>  3 files changed, 128 insertions(+)
>>>  create mode 100644 drivers/mmc/core/pwrseq_sd8787.c
>>>
>>> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
>>> index cdfa8520a4b1..fc1ecdaaa9ca 100644
>>> --- a/drivers/mmc/core/Kconfig
>>> +++ b/drivers/mmc/core/Kconfig
>>> @@ -12,6 +12,16 @@ config PWRSEQ_EMMC
>>>           This driver can also be built as a module. If so, the module
>>>           will be called pwrseq_emmc.
>>>
>>> +config PWRSEQ_SD8787
>>> +       tristate "HW reset support for SD8787 BT + Wifi module"
>>> +       depends on OF && (MWIFIEX || BT_MRVL_SDIO)
>>> +       help
>>> +         This selects hardware reset support for the SD8787 BT + Wifi
>>> +         module. By default this option is set to n.
>>> +
>>> +         This driver can also be built as a module. If so, the module
>>> +         will be called pwrseq_sd8787.
>>> +
>>
>>
>> I don't like this way, as we have a chance to list lots
>> configure options here. wifi A,B,C,D...Z, all of them need a
>> new section here if needed?
>>
>> Instead, could you just extent pwrseq_simple.c and add you
>> .compatible = "mmc-pwrseq-sd8787", "mmc-pwrseq-simple"?
>
> You mean all the chipset pwrseqs linked into the pwrseq-simple module?

What I mean was if you just extent the pwrseq-simple a bit, you could
just add your chipset pwrseqs linked into the pwrseq-simple. But if you
need a different *pattern* of pwrseqs, you should need a new name, for
instance, pwrseq-sdio.c etc... But please don't use the name of
sd8787? So if I use a wifi named ABC but using the same pwrseq pattenr,
should I include your "mmc-pwrseq- sd8787" for that or I need a new
mmc-pwrseq-ABC.c?

>
> Ulf your thoughts on this?
>
>>
>>
>>
>>>  config PWRSEQ_SIMPLE
>>>         tristate "Simple HW reset support for MMC"
>>>         default y
>>> diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
>>> index b2a257dc644f..0f81464fa824 100644
>>> --- a/drivers/mmc/core/Makefile
>>> +++ b/drivers/mmc/core/Makefile
>>> @@ -10,6 +10,7 @@ mmc_core-y                    := core.o bus.o host.o \
>>>                                    quirks.o slot-gpio.o
>>>  mmc_core-$(CONFIG_OF)          += pwrseq.o
>>>  obj-$(CONFIG_PWRSEQ_SIMPLE)    += pwrseq_simple.o
>>> +obj-$(CONFIG_PWRSEQ_SD8787)    += pwrseq_sd8787.o
>>>  obj-$(CONFIG_PWRSEQ_EMMC)      += pwrseq_emmc.o
>>>  mmc_core-$(CONFIG_DEBUG_FS)    += debugfs.o
>>>  obj-$(CONFIG_MMC_BLOCK)                += mmc_block.o
>>> diff --git a/drivers/mmc/core/pwrseq_sd8787.c
>>> b/drivers/mmc/core/pwrseq_sd8787.c
>>> new file mode 100644
>>> index 000000000000..f4080fe6439e
>>> --- /dev/null
>>> +++ b/drivers/mmc/core/pwrseq_sd8787.c
>>> @@ -0,0 +1,117 @@
>>> +/*
>>> + * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT + Wifi
>>> chip
>>> + *
>>> + * Copyright (C) 2016 Matt Ranostay <matt@ranostay.consulting>
>>> + *
>>> + * Based on the original work pwrseq_simple.c
>>> + *  Copyright (C) 2014 Linaro Ltd
>>> + *  Author: Ulf Hansson <ulf.hansson@linaro.org>
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License as published by
>>> + * the Free Software Foundation; either version 2 of the License, or
>>> + * (at your option) any later version.
>>> + *
>>> + * This program is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>>> + * GNU General Public License for more details.
>>> + *
>>> + */
>>> +
>>> +#include <linux/delay.h>
>>> +#include <linux/init.h>
>>> +#include <linux/kernel.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/module.h>
>>> +#include <linux/slab.h>
>>> +#include <linux/device.h>
>>> +#include <linux/err.h>
>>> +#include <linux/gpio/consumer.h>
>>> +
>>> +#include <linux/mmc/host.h>
>>> +
>>> +#include "pwrseq.h"
>>> +
>>> +struct mmc_pwrseq_sd8787 {
>>> +       struct mmc_pwrseq pwrseq;
>>> +       struct gpio_desc *reset_gpio;
>>> +       struct gpio_desc *pwrdn_gpio;
>>> +};
>>> +
>>> +#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787,
>>> pwrseq)
>>> +
>>> +static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
>>> +{
>>> +       struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
>>> +
>>> +       gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
>>> +
>>> +       msleep(300);
>>> +       gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
>>> +}
>>> +
>>> +static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host)
>>> +{
>>> +       struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
>>> +
>>> +       gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0);
>>> +       gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
>>> +}
>>> +
>>> +static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
>>> +       .pre_power_on = mmc_pwrseq_sd8787_pre_power_on,
>>> +       .power_off = mmc_pwrseq_sd8787_power_off,
>>> +};
>>> +
>>> +static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
>>> +       { .compatible = "mmc-pwrseq-sd8787",},
>>> +       {/* sentinel */},
>>> +};
>>> +MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
>>> +
>>> +static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
>>> +{
>>> +       struct mmc_pwrseq_sd8787 *pwrseq;
>>> +       struct device *dev = &pdev->dev;
>>> +
>>> +       pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
>>> +       if (!pwrseq)
>>> +               return -ENOMEM;
>>> +
>>> +       pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "pwrdn", GPIOD_OUT_LOW);
>>> +       if (IS_ERR(pwrseq->pwrdn_gpio))
>>> +               return PTR_ERR(pwrseq->pwrdn_gpio);
>>> +
>>> +       pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
>>> +       if (IS_ERR(pwrseq->reset_gpio))
>>> +               return PTR_ERR(pwrseq->reset_gpio);
>>> +
>>> +       pwrseq->pwrseq.dev = dev;
>>> +       pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops;
>>> +       pwrseq->pwrseq.owner = THIS_MODULE;
>>> +       platform_set_drvdata(pdev, pwrseq);
>>> +
>>> +       return mmc_pwrseq_register(&pwrseq->pwrseq);
>>> +}
>>> +
>>> +static int mmc_pwrseq_sd8787_remove(struct platform_device *pdev)
>>> +{
>>> +       struct mmc_pwrseq_sd8787 *pwrseq = platform_get_drvdata(pdev);
>>> +
>>> +       mmc_pwrseq_unregister(&pwrseq->pwrseq);
>>> +
>>> +       return 0;
>>> +}
>>> +
>>> +static struct platform_driver mmc_pwrseq_sd8787_driver = {
>>> +       .probe = mmc_pwrseq_sd8787_probe,
>>> +       .remove = mmc_pwrseq_sd8787_remove,
>>> +       .driver = {
>>> +               .name = "pwrseq_sd8787",
>>> +               .of_match_table = mmc_pwrseq_sd8787_of_match,
>>> +       },
>>> +};
>>> +
>>> +module_platform_driver(mmc_pwrseq_sd8787_driver);
>>> +MODULE_LICENSE("GPL v2");
>>>
>>
>>
>> --
>> Best Regards
>> Shawn Lin
>>
>
>
>


-- 
Best Regards
Shawn Lin

^ permalink raw reply

* Re: [PATCH v2 2/3] mwifiex: pcie: don't loop/retry interrupt status checks
From: Dmitry Torokhov @ 2017-01-16  0:54 UTC (permalink / raw)
  To: Brian Norris
  Cc: Amitkumar Karwar, Nishant Sarmukadam, linux-kernel, Kalle Valo,
	linux-wireless, Cathy Luo
In-Reply-To: <20170113233538.36196-2-briannorris@chromium.org>

On Fri, Jan 13, 2017 at 03:35:37PM -0800, Brian Norris wrote:
> The following sequence occurs when using IEEE power-save on 8997:
> (a) driver sees SLEEP event
> (b) driver issues SLEEP CONFIRM
> (c) driver recevies CMD interrupt; within the interrupt processing loop,
>     we do (d) and (e):
> (d) wait for FW sleep cookie (and often time out; it takes a while), FW
>     is putting card into low power mode
> (e) re-check PCIE_HOST_INT_STATUS register; quit loop with 0 value
> 
> But at (e), no one actually signaled an interrupt (i.e., we didn't check
> adapter->int_status). And what's more, because the card is going to
> sleep, this register read appears to take a very long time in some cases
> -- 3 milliseconds in my case!
> 
> Now, I propose that (e) is completely unnecessary. If there were any
> additional interrupts signaled after the start of this loop, then the
> interrupt handler would have set adapter->int_status to non-zero and
> queued more work for the main loop -- and we'd catch it on the next
> iteration of the main loop.
> 
> So this patch drops all the looping/re-reading of PCIE_HOST_INT_STATUS,
> which avoids the problematic (and slow) register read in step (e).
> 
> Incidentally, this is a very similar issue to the one fixed in commit
> ec815dd2a5f1 ("mwifiex: prevent register accesses after host is
> sleeping"), except that the register read is just very slow instead of
> fatal in this case.
> 
> Tested on 8997 in both MSI and (though not technically supported at the
> moment) MSI-X mode.

Well, that kills interrupt mitigation and with PCIE that might be
somewhat important (SDIO is too slow to be important I think) and might
cost you throughput.

OTOH maybe Marvell should convert PICE to NAPI to make this more
obvious and probably more correct.

> 
> Signed-off-by: Brian Norris <briannorris@chromium.org>
> ---
> v2:
>  * new in v2, replacing an attempt to mess with step (d) above
> ---
>  drivers/net/wireless/marvell/mwifiex/pcie.c | 102 +++++++++-------------------
>  1 file changed, 32 insertions(+), 70 deletions(-)
> 
> diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
> index 3f4cda2d3b61..194e0e04c3b1 100644
> --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
> +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
> @@ -2332,79 +2332,41 @@ static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter)
>  			}
>  		}
>  	}
> -	while (pcie_ireg & HOST_INTR_MASK) {
> -		if (pcie_ireg & HOST_INTR_DNLD_DONE) {
> -			pcie_ireg &= ~HOST_INTR_DNLD_DONE;
> -			mwifiex_dbg(adapter, INTR,
> -				    "info: TX DNLD Done\n");
> -			ret = mwifiex_pcie_send_data_complete(adapter);
> -			if (ret)
> -				return ret;
> -		}
> -		if (pcie_ireg & HOST_INTR_UPLD_RDY) {
> -			pcie_ireg &= ~HOST_INTR_UPLD_RDY;
> -			mwifiex_dbg(adapter, INTR,
> -				    "info: Rx DATA\n");
> -			ret = mwifiex_pcie_process_recv_data(adapter);
> -			if (ret)
> -				return ret;
> -		}
> -		if (pcie_ireg & HOST_INTR_EVENT_RDY) {
> -			pcie_ireg &= ~HOST_INTR_EVENT_RDY;
> -			mwifiex_dbg(adapter, INTR,
> -				    "info: Rx EVENT\n");
> -			ret = mwifiex_pcie_process_event_ready(adapter);
> -			if (ret)
> -				return ret;
> -		}
> -
> -		if (pcie_ireg & HOST_INTR_CMD_DONE) {
> -			pcie_ireg &= ~HOST_INTR_CMD_DONE;
> -			if (adapter->cmd_sent) {
> -				mwifiex_dbg(adapter, INTR,
> -					    "info: CMD sent Interrupt\n");
> -				adapter->cmd_sent = false;
> -			}
> -			/* Handle command response */
> -			ret = mwifiex_pcie_process_cmd_complete(adapter);
> -			if (ret)
> -				return ret;
> -			if (adapter->hs_activated)
> -				return ret;
> -		}
> -
> -		if (card->msi_enable) {
> -			spin_lock_irqsave(&adapter->int_lock, flags);
> -			adapter->int_status = 0;
> -			spin_unlock_irqrestore(&adapter->int_lock, flags);
> -		}
> -
> -		if (mwifiex_pcie_ok_to_access_hw(adapter)) {
> -			if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
> -					     &pcie_ireg)) {
> -				mwifiex_dbg(adapter, ERROR,
> -					    "Read register failed\n");
> -				return -1;
> -			}
>  
> -			if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
> -				if (mwifiex_write_reg(adapter,
> -						      PCIE_HOST_INT_STATUS,
> -						      ~pcie_ireg)) {
> -					mwifiex_dbg(adapter, ERROR,
> -						    "Write register failed\n");
> -					return -1;
> -				}
> -			}
> -
> -		}
> -		if (!card->msi_enable) {
> -			spin_lock_irqsave(&adapter->int_lock, flags);
> -			pcie_ireg |= adapter->int_status;
> -			adapter->int_status = 0;
> -			spin_unlock_irqrestore(&adapter->int_lock, flags);
> +	if (pcie_ireg & HOST_INTR_DNLD_DONE) {
> +		pcie_ireg &= ~HOST_INTR_DNLD_DONE;
> +		mwifiex_dbg(adapter, INTR, "info: TX DNLD Done\n");
> +		ret = mwifiex_pcie_send_data_complete(adapter);
> +		if (ret)
> +			return ret;
> +	}
> +	if (pcie_ireg & HOST_INTR_UPLD_RDY) {
> +		pcie_ireg &= ~HOST_INTR_UPLD_RDY;
> +		mwifiex_dbg(adapter, INTR, "info: Rx DATA\n");
> +		ret = mwifiex_pcie_process_recv_data(adapter);
> +		if (ret)
> +			return ret;
> +	}
> +	if (pcie_ireg & HOST_INTR_EVENT_RDY) {
> +		pcie_ireg &= ~HOST_INTR_EVENT_RDY;
> +		mwifiex_dbg(adapter, INTR, "info: Rx EVENT\n");
> +		ret = mwifiex_pcie_process_event_ready(adapter);
> +		if (ret)
> +			return ret;
> +	}
> +	if (pcie_ireg & HOST_INTR_CMD_DONE) {
> +		pcie_ireg &= ~HOST_INTR_CMD_DONE;
> +		if (adapter->cmd_sent) {
> +			mwifiex_dbg(adapter, INTR,
> +				    "info: CMD sent Interrupt\n");
> +			adapter->cmd_sent = false;
>  		}
> +		/* Handle command response */
> +		ret = mwifiex_pcie_process_cmd_complete(adapter);
> +		if (ret)
> +			return ret;
>  	}
> +
>  	mwifiex_dbg(adapter, INTR,
>  		    "info: cmd_sent=%d data_sent=%d\n",
>  		    adapter->cmd_sent, adapter->data_sent);
> -- 
> 2.11.0.483.g087da7b7c-goog
> 

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v3 2/2] mmc: pwrseq: add support for Marvell SD8787 chip
From: Matt Ranostay @ 2017-01-15 21:41 UTC (permalink / raw)
  To: Shawn Lin
  Cc: linux-wireless, Linux Kernel, linux-mmc, devicetree,
	Tony Lindgren, Ulf Hansson
In-Reply-To: <cd669d08-0db4-57e4-478b-2b200ccef6f1@rock-chips.com>

On Thu, Jan 12, 2017 at 11:16 PM, Shawn Lin <shawn.lin@rock-chips.com> wrote:
> On 2017/1/13 13:29, Matt Ranostay wrote:
>>
>> Allow power sequencing for the Marvell SD8787 Wifi/BT chip.
>> This can be abstracted to other chipsets if needed in the future.
>>
>> Cc: Tony Lindgren <tony@atomide.com>
>> Cc: Ulf Hansson <ulf.hansson@linaro.org>
>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>> ---
>>  drivers/mmc/core/Kconfig         |  10 ++++
>>  drivers/mmc/core/Makefile        |   1 +
>>  drivers/mmc/core/pwrseq_sd8787.c | 117
>> +++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 128 insertions(+)
>>  create mode 100644 drivers/mmc/core/pwrseq_sd8787.c
>>
>> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
>> index cdfa8520a4b1..fc1ecdaaa9ca 100644
>> --- a/drivers/mmc/core/Kconfig
>> +++ b/drivers/mmc/core/Kconfig
>> @@ -12,6 +12,16 @@ config PWRSEQ_EMMC
>>           This driver can also be built as a module. If so, the module
>>           will be called pwrseq_emmc.
>>
>> +config PWRSEQ_SD8787
>> +       tristate "HW reset support for SD8787 BT + Wifi module"
>> +       depends on OF && (MWIFIEX || BT_MRVL_SDIO)
>> +       help
>> +         This selects hardware reset support for the SD8787 BT + Wifi
>> +         module. By default this option is set to n.
>> +
>> +         This driver can also be built as a module. If so, the module
>> +         will be called pwrseq_sd8787.
>> +
>
>
> I don't like this way, as we have a chance to list lots
> configure options here. wifi A,B,C,D...Z, all of them need a
> new section here if needed?
>
> Instead, could you just extent pwrseq_simple.c and add you
> .compatible = "mmc-pwrseq-sd8787", "mmc-pwrseq-simple"?

You mean all the chipset pwrseqs linked into the pwrseq-simple module?

Ulf your thoughts on this?

>
>
>
>>  config PWRSEQ_SIMPLE
>>         tristate "Simple HW reset support for MMC"
>>         default y
>> diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
>> index b2a257dc644f..0f81464fa824 100644
>> --- a/drivers/mmc/core/Makefile
>> +++ b/drivers/mmc/core/Makefile
>> @@ -10,6 +10,7 @@ mmc_core-y                    := core.o bus.o host.o \
>>                                    quirks.o slot-gpio.o
>>  mmc_core-$(CONFIG_OF)          += pwrseq.o
>>  obj-$(CONFIG_PWRSEQ_SIMPLE)    += pwrseq_simple.o
>> +obj-$(CONFIG_PWRSEQ_SD8787)    += pwrseq_sd8787.o
>>  obj-$(CONFIG_PWRSEQ_EMMC)      += pwrseq_emmc.o
>>  mmc_core-$(CONFIG_DEBUG_FS)    += debugfs.o
>>  obj-$(CONFIG_MMC_BLOCK)                += mmc_block.o
>> diff --git a/drivers/mmc/core/pwrseq_sd8787.c
>> b/drivers/mmc/core/pwrseq_sd8787.c
>> new file mode 100644
>> index 000000000000..f4080fe6439e
>> --- /dev/null
>> +++ b/drivers/mmc/core/pwrseq_sd8787.c
>> @@ -0,0 +1,117 @@
>> +/*
>> + * pwrseq_sd8787.c - power sequence support for Marvell SD8787 BT + Wifi
>> chip
>> + *
>> + * Copyright (C) 2016 Matt Ranostay <matt@ranostay.consulting>
>> + *
>> + * Based on the original work pwrseq_simple.c
>> + *  Copyright (C) 2014 Linaro Ltd
>> + *  Author: Ulf Hansson <ulf.hansson@linaro.org>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + */
>> +
>> +#include <linux/delay.h>
>> +#include <linux/init.h>
>> +#include <linux/kernel.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/module.h>
>> +#include <linux/slab.h>
>> +#include <linux/device.h>
>> +#include <linux/err.h>
>> +#include <linux/gpio/consumer.h>
>> +
>> +#include <linux/mmc/host.h>
>> +
>> +#include "pwrseq.h"
>> +
>> +struct mmc_pwrseq_sd8787 {
>> +       struct mmc_pwrseq pwrseq;
>> +       struct gpio_desc *reset_gpio;
>> +       struct gpio_desc *pwrdn_gpio;
>> +};
>> +
>> +#define to_pwrseq_sd8787(p) container_of(p, struct mmc_pwrseq_sd8787,
>> pwrseq)
>> +
>> +static void mmc_pwrseq_sd8787_pre_power_on(struct mmc_host *host)
>> +{
>> +       struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
>> +
>> +       gpiod_set_value_cansleep(pwrseq->reset_gpio, 1);
>> +
>> +       msleep(300);
>> +       gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 1);
>> +}
>> +
>> +static void mmc_pwrseq_sd8787_power_off(struct mmc_host *host)
>> +{
>> +       struct mmc_pwrseq_sd8787 *pwrseq = to_pwrseq_sd8787(host->pwrseq);
>> +
>> +       gpiod_set_value_cansleep(pwrseq->pwrdn_gpio, 0);
>> +       gpiod_set_value_cansleep(pwrseq->reset_gpio, 0);
>> +}
>> +
>> +static const struct mmc_pwrseq_ops mmc_pwrseq_sd8787_ops = {
>> +       .pre_power_on = mmc_pwrseq_sd8787_pre_power_on,
>> +       .power_off = mmc_pwrseq_sd8787_power_off,
>> +};
>> +
>> +static const struct of_device_id mmc_pwrseq_sd8787_of_match[] = {
>> +       { .compatible = "mmc-pwrseq-sd8787",},
>> +       {/* sentinel */},
>> +};
>> +MODULE_DEVICE_TABLE(of, mmc_pwrseq_sd8787_of_match);
>> +
>> +static int mmc_pwrseq_sd8787_probe(struct platform_device *pdev)
>> +{
>> +       struct mmc_pwrseq_sd8787 *pwrseq;
>> +       struct device *dev = &pdev->dev;
>> +
>> +       pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
>> +       if (!pwrseq)
>> +               return -ENOMEM;
>> +
>> +       pwrseq->pwrdn_gpio = devm_gpiod_get(dev, "pwrdn", GPIOD_OUT_LOW);
>> +       if (IS_ERR(pwrseq->pwrdn_gpio))
>> +               return PTR_ERR(pwrseq->pwrdn_gpio);
>> +
>> +       pwrseq->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
>> +       if (IS_ERR(pwrseq->reset_gpio))
>> +               return PTR_ERR(pwrseq->reset_gpio);
>> +
>> +       pwrseq->pwrseq.dev = dev;
>> +       pwrseq->pwrseq.ops = &mmc_pwrseq_sd8787_ops;
>> +       pwrseq->pwrseq.owner = THIS_MODULE;
>> +       platform_set_drvdata(pdev, pwrseq);
>> +
>> +       return mmc_pwrseq_register(&pwrseq->pwrseq);
>> +}
>> +
>> +static int mmc_pwrseq_sd8787_remove(struct platform_device *pdev)
>> +{
>> +       struct mmc_pwrseq_sd8787 *pwrseq = platform_get_drvdata(pdev);
>> +
>> +       mmc_pwrseq_unregister(&pwrseq->pwrseq);
>> +
>> +       return 0;
>> +}
>> +
>> +static struct platform_driver mmc_pwrseq_sd8787_driver = {
>> +       .probe = mmc_pwrseq_sd8787_probe,
>> +       .remove = mmc_pwrseq_sd8787_remove,
>> +       .driver = {
>> +               .name = "pwrseq_sd8787",
>> +               .of_match_table = mmc_pwrseq_sd8787_of_match,
>> +       },
>> +};
>> +
>> +module_platform_driver(mmc_pwrseq_sd8787_driver);
>> +MODULE_LICENSE("GPL v2");
>>
>
>
> --
> Best Regards
> Shawn Lin
>

^ permalink raw reply

* Re: [PATCH 14/40] rt2x00: rt2800lib: add MAC register initialization for RT3883
From: kbuild test robot @ 2017-01-15  6:49 UTC (permalink / raw)
  To: Daniel Golle
  Cc: kbuild-all, linux-wireless, Johannes Berg, Stanislaw Gruszka,
	roman, michel.stempin, c.mignanti, evaxige, Kalle Valo,
	Felix Fietkau, John Crispin, Gabor Juhos
In-Reply-To: <20170113212510.GA3447@makrotopia.org>

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

Hi Gabor,

[auto build test ERROR on wireless-drivers-next/master]
[also build test ERROR on next-20170113]
[cannot apply to v4.10-rc3]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Daniel-Golle/rt2x00-patches-form-OpenWrt-org/20170115-102250
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next.git master
config: x86_64-allyesdebian (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

Note: the linux-review/Daniel-Golle/rt2x00-patches-form-OpenWrt-org/20170115-102250 HEAD 849367246e2b54e086e272ee2bd32b9983bc30fb builds fine.
      It only hurts bisectibility.

All errors (new ones prefixed by >>):

   drivers/net/wireless/ralink/rt2x00/rt2800lib.c: In function 'rt2800_config_channel_rf3853':
   drivers/net/wireless/ralink/rt2x00/rt2800lib.c:2734:2: error: implicit declaration of function 'rt2800_adjust_freq_offset' [-Werror=implicit-function-declaration]
     rt2800_adjust_freq_offset(rt2x00dev);
     ^~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/net/wireless/ralink/rt2x00/rt2800lib.c: In function 'rt2800_init_registers':
>> drivers/net/wireless/ralink/rt2x00/rt2800lib.c:5027:36: error: 'TX_TXBF_CFG_0' undeclared (first use in this function)
      rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21);
                                       ^~~~~~~~~~~~~
   drivers/net/wireless/ralink/rt2x00/rt2800lib.c:5027:36: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/net/wireless/ralink/rt2x00/rt2800lib.c:5028:36: error: 'TX_TXBF_CFG_3' undeclared (first use in this function)
      rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40);
                                       ^~~~~~~~~~~~~
>> drivers/net/wireless/ralink/rt2x00/rt2800lib.c:5224:36: error: 'TX_FBK_CFG_3S_0' undeclared (first use in this function)
      rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_0, 0x12111008);
                                       ^~~~~~~~~~~~~~~
>> drivers/net/wireless/ralink/rt2x00/rt2800lib.c:5225:36: error: 'TX_FBK_CFG_3S_1' undeclared (first use in this function)
      rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_1, 0x16151413);
                                       ^~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +/TX_TXBF_CFG_0 +5027 drivers/net/wireless/ralink/rt2x00/rt2800lib.c

  5021						      0x00000000);
  5022			}
  5023		} else if (rt2x00_rt(rt2x00dev, RT3883)) {
  5024			rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402);
  5025			rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
  5026			rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00040000);
> 5027			rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21);
> 5028			rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40);
  5029		} else if (rt2x00_rt(rt2x00dev, RT5390) ||
  5030			   rt2x00_rt(rt2x00dev, RT5392)) {
  5031			rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
  5032			rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
  5033			rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
  5034		} else if (rt2x00_rt(rt2x00dev, RT5592)) {
  5035			rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
  5036			rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
  5037			rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
  5038		} else {
  5039			rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
  5040			rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
  5041		}
  5042	
  5043		rt2800_register_read(rt2x00dev, TX_LINK_CFG, &reg);
  5044		rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFB_LIFETIME, 32);
  5045		rt2x00_set_field32(&reg, TX_LINK_CFG_MFB_ENABLE, 0);
  5046		rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_UMFS_ENABLE, 0);
  5047		rt2x00_set_field32(&reg, TX_LINK_CFG_TX_MRQ_EN, 0);
  5048		rt2x00_set_field32(&reg, TX_LINK_CFG_TX_RDG_EN, 0);
  5049		rt2x00_set_field32(&reg, TX_LINK_CFG_TX_CF_ACK_EN, 1);
  5050		rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFB, 0);
  5051		rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFS, 0);
  5052		rt2800_register_write(rt2x00dev, TX_LINK_CFG, reg);
  5053	
  5054		rt2800_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
  5055		rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_MPDU_LIFETIME, 9);
  5056		rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT, 32);
  5057		rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_TX_OP_TIMEOUT, 10);
  5058		rt2800_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
  5059	
  5060		rt2800_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
  5061		rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
  5062		if (rt2x00_rt(rt2x00dev, RT3883)) {
  5063			drv_data->max_psdu = 3;
  5064			rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 3);
  5065		} else if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) ||
  5066		    rt2x00_rt(rt2x00dev, RT2883) ||
  5067		    rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E)) {
  5068			drv_data->max_psdu = 2;
  5069			rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
  5070		} else {
  5071			drv_data->max_psdu = 1;
  5072			rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
  5073		}
  5074		rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_PSDU, 10);
  5075		rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_MPDU, 10);
  5076		rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg);
  5077	
  5078		rt2800_register_read(rt2x00dev, LED_CFG, &reg);
  5079		rt2x00_set_field32(&reg, LED_CFG_ON_PERIOD, 70);
  5080		rt2x00_set_field32(&reg, LED_CFG_OFF_PERIOD, 30);
  5081		rt2x00_set_field32(&reg, LED_CFG_SLOW_BLINK_PERIOD, 3);
  5082		rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE, 3);
  5083		rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, 3);
  5084		rt2x00_set_field32(&reg, LED_CFG_Y_LED_MODE, 3);
  5085		rt2x00_set_field32(&reg, LED_CFG_LED_POLAR, 1);
  5086		rt2800_register_write(rt2x00dev, LED_CFG, reg);
  5087	
  5088		rt2800_register_write(rt2x00dev, PBF_MAX_PCNT, 0x1f3fbf9f);
  5089	
  5090		rt2800_register_read(rt2x00dev, TX_RTY_CFG, &reg);
  5091		rt2x00_set_field32(&reg, TX_RTY_CFG_SHORT_RTY_LIMIT, 15);
  5092		rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_LIMIT, 31);
  5093		rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_THRE, 2000);
  5094		rt2x00_set_field32(&reg, TX_RTY_CFG_NON_AGG_RTY_MODE, 0);
  5095		rt2x00_set_field32(&reg, TX_RTY_CFG_AGG_RTY_MODE, 0);
  5096		rt2x00_set_field32(&reg, TX_RTY_CFG_TX_AUTO_FB_ENABLE, 1);
  5097		rt2800_register_write(rt2x00dev, TX_RTY_CFG, reg);
  5098	
  5099		rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
  5100		rt2x00_set_field32(&reg, AUTO_RSP_CFG_AUTORESPONDER, 1);
  5101		rt2x00_set_field32(&reg, AUTO_RSP_CFG_BAC_ACK_POLICY, 1);
  5102		rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MMODE, 1);
  5103		rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MREF, 0);
  5104		rt2x00_set_field32(&reg, AUTO_RSP_CFG_AR_PREAMBLE, 0);
  5105		rt2x00_set_field32(&reg, AUTO_RSP_CFG_DUAL_CTS_EN, 0);
  5106		rt2x00_set_field32(&reg, AUTO_RSP_CFG_ACK_CTS_PSM_BIT, 0);
  5107		rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
  5108	
  5109		rt2800_register_read(rt2x00dev, CCK_PROT_CFG, &reg);
  5110		rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_RATE, 3);
  5111		rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_CTRL, 0);
  5112		rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_NAV_SHORT, 1);
  5113		rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1);
  5114		rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
  5115		rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1);
  5116		rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM40, 0);
  5117		rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF20, 1);
  5118		rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF40, 0);
  5119		rt2x00_set_field32(&reg, CCK_PROT_CFG_RTS_TH_EN, 1);
  5120		rt2800_register_write(rt2x00dev, CCK_PROT_CFG, reg);
  5121	
  5122		rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
  5123		rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_RATE, 3);
  5124		rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL, 0);
  5125		rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_NAV_SHORT, 1);
  5126		rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1);
  5127		rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
  5128		rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1);
  5129		rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM40, 0);
  5130		rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF20, 1);
  5131		rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF40, 0);
  5132		rt2x00_set_field32(&reg, OFDM_PROT_CFG_RTS_TH_EN, 1);
  5133		rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
  5134	
  5135		rt2800_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
  5136		rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_RATE, 0x4004);
  5137		rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_CTRL, 1);
  5138		rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_NAV_SHORT, 1);
  5139		rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_CCK, 0);
  5140		rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
  5141		rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
  5142		rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
  5143		rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
  5144		rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
  5145		rt2x00_set_field32(&reg, MM20_PROT_CFG_RTS_TH_EN, 0);
  5146		rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg);
  5147	
  5148		rt2800_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
  5149		rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_RATE, 0x4084);
  5150		rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 1);
  5151		rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_NAV_SHORT, 1);
  5152		rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 0);
  5153		rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
  5154		rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
  5155		rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
  5156		rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
  5157		rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
  5158		rt2x00_set_field32(&reg, MM40_PROT_CFG_RTS_TH_EN, 0);
  5159		rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg);
  5160	
  5161		rt2800_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
  5162		rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_RATE, 0x4004);
  5163		rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_CTRL, 1);
  5164		rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_NAV_SHORT, 1);
  5165		rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_CCK, 0);
  5166		rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
  5167		rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
  5168		rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
  5169		rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
  5170		rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
  5171		rt2x00_set_field32(&reg, GF20_PROT_CFG_RTS_TH_EN, 0);
  5172		rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg);
  5173	
  5174		rt2800_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
  5175		rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_RATE, 0x4084);
  5176		rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_CTRL, 1);
  5177		rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_NAV_SHORT, 1);
  5178		rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_CCK, 0);
  5179		rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
  5180		rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
  5181		rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
  5182		rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
  5183		rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
  5184		rt2x00_set_field32(&reg, GF40_PROT_CFG_RTS_TH_EN, 0);
  5185		rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg);
  5186	
  5187		if (rt2x00_is_usb(rt2x00dev)) {
  5188			rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
  5189	
  5190			rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
  5191			rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
  5192			rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
  5193			rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
  5194			rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
  5195			rt2x00_set_field32(&reg, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 3);
  5196			rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 0);
  5197			rt2x00_set_field32(&reg, WPDMA_GLO_CFG_BIG_ENDIAN, 0);
  5198			rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_HDR_SCATTER, 0);
  5199			rt2x00_set_field32(&reg, WPDMA_GLO_CFG_HDR_SEG_LEN, 0);
  5200			rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
  5201		}
  5202	
  5203		/*
  5204		 * The legacy driver also sets TXOP_CTRL_CFG_RESERVED_TRUN_EN to 1
  5205		 * although it is reserved.
  5206		 */
  5207		rt2800_register_read(rt2x00dev, TXOP_CTRL_CFG, &reg);
  5208		rt2x00_set_field32(&reg, TXOP_CTRL_CFG_TIMEOUT_TRUN_EN, 1);
  5209		rt2x00_set_field32(&reg, TXOP_CTRL_CFG_AC_TRUN_EN, 1);
  5210		rt2x00_set_field32(&reg, TXOP_CTRL_CFG_TXRATEGRP_TRUN_EN, 1);
  5211		rt2x00_set_field32(&reg, TXOP_CTRL_CFG_USER_MODE_TRUN_EN, 1);
  5212		rt2x00_set_field32(&reg, TXOP_CTRL_CFG_MIMO_PS_TRUN_EN, 1);
  5213		rt2x00_set_field32(&reg, TXOP_CTRL_CFG_RESERVED_TRUN_EN, 1);
  5214		rt2x00_set_field32(&reg, TXOP_CTRL_CFG_LSIG_TXOP_EN, 0);
  5215		rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CCA_EN, 0);
  5216		rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CCA_DLY, 88);
  5217		rt2x00_set_field32(&reg, TXOP_CTRL_CFG_EXT_CWMIN, 0);
  5218		rt2800_register_write(rt2x00dev, TXOP_CTRL_CFG, reg);
  5219	
  5220		reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002;
  5221		rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg);
  5222	
  5223		if (rt2x00_rt(rt2x00dev, RT3883)) {
> 5224			rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_0, 0x12111008);
> 5225			rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_1, 0x16151413);
  5226		}
  5227	
  5228		rt2800_register_read(rt2x00dev, TX_RTS_CFG, &reg);

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 38065 bytes --]

^ permalink raw reply

* support for Ampak AP6255 (bcm43455c0 with SDIO device ID 0xa9bf)
From: Martin Blumenstingl @ 2017-01-14 23:18 UTC (permalink / raw)
  To: brcm80211-dev-list.pdl; +Cc: arend.vanspriel, hante.meuleman, linux-wireless

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

Hello,

I recently got a "Khadas VIM Pro" (see [0] for more information)
The "Pro" version comes with an AP6255 wifi chipset.
Looking at the vendor firmware this seems to be a bcm43455 device: [1]

To my surprise brcmfmac from a mainline 4.10-rc3 kernel did not pick
this device up.
So I started investigating:
$ grep "" /sys/class/mmc_host/mmc2/mmc2\:0001/mmc2\:0001\:*/{class,device,vendor}
/sys/class/mmc_host/mmc2/mmc2:0001/mmc2:0001:1/class:0x00
/sys/class/mmc_host/mmc2/mmc2:0001/mmc2:0001:2/class:0x00
/sys/class/mmc_host/mmc2/mmc2:0001/mmc2:0001:3/class:0x02
/sys/class/mmc_host/mmc2/mmc2:0001/mmc2:0001:1/device:0xa9bf
/sys/class/mmc_host/mmc2/mmc2:0001/mmc2:0001:2/device:0xa9bf
/sys/class/mmc_host/mmc2/mmc2:0001/mmc2:0001:3/device:0xa9bf
/sys/class/mmc_host/mmc2/mmc2:0001/mmc2:0001:1/vendor:0x02d0
/sys/class/mmc_host/mmc2/mmc2:0001/mmc2:0001:2/vendor:0x02d0
/sys/class/mmc_host/mmc2/mmc2:0001/mmc2:0001:3/vendor:0x02d0

I then went ahead and added the device ID to
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c (sample
patch attached)
as a result of that the device is now being detected.
it boots fine with the firmware found in linux-firmware: [2] (plus the
nvram.txt from the vendor repo [1] renamed to brcmfmac43455-sdio.txt)

$ cat /sys/kernel/debug/brcmfmac/mmc2\:0001\:1/revinfo
vendorid: 0x14e4
deviceid: 0x43ab
radiorev: 0.88.3.11
chipnum: 17221 (4345)
chiprev: 6
chippkg: 2
corerev: 54
boardid: 0x06e4
boardvendor: 0x14e4
boardrev: P304
driverrev: 7.45.18
ucoderev: 0
bus: 0
phytype: 11
phyrev: 20
anarev: 0
nvramrev: 00079ac5

downloading a random 100MB file from the internet using curl confirms this.
There are no hangs, connection drops, other devices are also working fine.

the problem I'm facing is very simply (but unfortunately a very common
development problem): naming things (the SDIO_DEVICE_ID_BROADCOM_TODO
constant)!
there's already a definition for SDIO_DEVICE_ID_BROADCOM_4345 with
value 0x4345, does that mean 0xa9bf should be
SDIO_DEVICE_ID_BROADCOM_43455?


Regards,
Martin


[0] http://khadas.com/vim/
[1] https://github.com/khadas/android_hardware_amlogic_wifi/tree/b6709758755568e4a0ff6e80993be0fc64c77fb9/bcm_ampak/config/6255
[2] https://git.kernel.org/cgit/linux/kernel/git/firmware/linux-firmware.git/commit/brcm/brcmfmac43455-sdio.bin?id=b9a38d041d38ac6cf47274e9933f8083e12fc601

[-- Attachment #2: brmcfmac-sdio-0xa9bf.patch --]
[-- Type: text/x-patch, Size: 638 bytes --]

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
index 72139b579b18..7206bb1f9908 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -1106,6 +1106,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345),
 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
 	BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4356),
+	BRCMF_SDIO_DEVICE(0xa9bf),
 	{ /* end: all zeroes */ }
 };
 MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);


^ permalink raw reply related

* Re: [PATCH v2 2/2] mmc: pwrseq: add support for Marvell SD8787 chip
From: kbuild test robot @ 2017-01-14 21:37 UTC (permalink / raw)
  To: Matt Ranostay
  Cc: kbuild-all, linux-wireless, linux-kernel, linux-mmc, devicetree,
	tony, Matt Ranostay, Ulf Hansson
In-Reply-To: <20170113052218.10534-3-matt@ranostay.consulting>

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

Hi Matt,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.10-rc3 next-20170113]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Matt-Ranostay/mmc-pwrseq-add-support-for-Marvell-SD8787-chip/20170115-030459
config: i386-allmodconfig (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

All errors (new ones prefixed by >>):

>> make[4]: *** No rule to make target 'drivers/mmc/core/pwrseq_sd8787.c', needed by 'drivers/mmc/core/pwrseq_sd8787.o'.
   make[4]: Target '__build' not remade because of errors.

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 57927 bytes --]

^ permalink raw reply

* Re: [PATCH] ath10k: Search SMBIOS for OEM board file extension
From: kbuild test robot @ 2017-01-14 18:09 UTC (permalink / raw)
  To: Waldemar Rymarkiewicz
  Cc: kbuild-all, kvalo, ath10k, bartosz.markowski, rwchang, alanliu,
	linux-wireless, Waldemar Rymarkiewicz
In-Reply-To: <20170113111022.5570-1-ext.waldemar.rymarkiewicz@tieto.com>

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

Hi Waldemar,

[auto build test WARNING on ath6kl/ath-next]
[also build test WARNING on v4.10-rc3 next-20170113]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Waldemar-Rymarkiewicz/ath10k-Search-SMBIOS-for-OEM-board-file-extension/20170115-005232
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git ath-next
config: xtensa-allmodconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 4.9.0
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=xtensa 

All warnings (new ones prefixed by >>):

   drivers/net/wireless/ath/ath10k/core.c: In function 'ath10k_core_check_bdfext':
>> drivers/net/wireless/ath/ath10k/core.c:754:2: warning: ignoring return value of 'strscpy', declared with attribute warn_unused_result [-Wunused-result]
     strscpy(ar->id.bdf_ext, bdf_ext + strlen(magic),
     ^

vim +/strscpy +754 drivers/net/wireless/ath/ath10k/core.c

   738	
   739		if (memcmp(bdf_ext, magic, strlen(magic)) != 0) {
   740			ath10k_dbg(ar, ATH10K_DBG_BOOT,
   741				   "bdf variant magic does not match.\n");
   742			return;
   743		}
   744	
   745		for (i = 0; i < strlen(bdf_ext); i++) {
   746			if (!isascii(bdf_ext[i]) || !isprint(bdf_ext[i])) {
   747				ath10k_dbg(ar, ATH10K_DBG_BOOT,
   748					   "bdf variant name contains non ascii chars.\n");
   749				return;
   750			}
   751		}
   752	
   753		/* Copy extension name without magic suffix */
 > 754		strscpy(ar->id.bdf_ext, bdf_ext + strlen(magic),
   755			sizeof(ar->id.bdf_ext));
   756	
   757		ath10k_dbg(ar, ATH10K_DBG_BOOT,
   758			   "found and validated bdf variant smbios_type 0x%x bdf %s\n",
   759			   ATH10K_SMBIOS_BDF_EXT_TYPE, bdf_ext);
   760	}
   761	
   762	static int ath10k_core_check_smbios(struct ath10k *ar)

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 48158 bytes --]

^ permalink raw reply

* Re: pull-request: mac80211-next 2017-01-13
From: David Miller @ 2017-01-14 17:04 UTC (permalink / raw)
  To: johannes; +Cc: netdev, linux-wireless
In-Reply-To: <20170113102933.8246-1-johannes@sipsolutions.net>

From: Johannes Berg <johannes@sipsolutions.net>
Date: Fri, 13 Jan 2017 11:29:32 +0100

> This is my first pull request for net-next, and it seems a bit
> bigger than the past few releases. Detailed information below,
> as usual.
> 
> Please pull and let me know if there's any problem.

Pulled, thanks Johannes.

^ permalink raw reply

* Re: [PATCH 04/40] rt2x00: rt2800lib: fix beacon generation on RT3593
From: Kalle Valo @ 2017-01-14 17:00 UTC (permalink / raw)
  To: Daniel Golle
  Cc: linux-wireless, Johannes Berg, Stanislaw Gruszka, roman,
	michel.stempin, c.mignanti, evaxige, Felix Fietkau, John Crispin,
	Gabor Juhos
In-Reply-To: <20170113212027.GA3372@makrotopia.org>

Daniel Golle <daniel@makrotopia.org> writes:

> From: Gabor Juhos <juhosg@openwrt.org>
>
> On the RT3593 chipset, the beacon registers are located
> in the high 8KB part of the shared memory.
>
> The high part of the shared memory is only accessible
> if it is explicitly selected. Add a helper function
> in order to be able to control the SHR_MSEL bit in
> the PBF_SYS_CTRL register. Also add a few more helper
> functions and use those to select the correct part of
> the shared memory before and after accessing the beacon
> registers.
>
> The base addresses of the beacon registers are also
> different from the actually used values, so fix the
> 'rt2800_hw_beacon_base' function to return the correct
> values.
>
> Signed-off-by: Gabor Juhos <juhosg@openwrt.org>

Daniel, as you are submitting these patches you should add your
Signed-off-by after the author's line. Documentation/SubmittingPatches
contains more info about that and what Signed-off-by means. And also
take a look at how Luca does it:

http://www.spinics.net/lists/linux-wireless/msg158064.html

-- 
Kalle Valo

^ permalink raw reply

* Re: [RFC] [PULL REQUEST] rt2x00 patches from OpenWrt.org
From: Kalle Valo @ 2017-01-14 16:48 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: Daniel Golle, linux-wireless, lede-dev, openwrt-devel, john, nbd,
	roman, evaxige, c.mignanti, michel.stempin, vasilugin,
	Helmut Schaa
In-Reply-To: <20170113141554.GA8018@redhat.com>

Stanislaw Gruszka <sgruszka@redhat.com> writes:

> Hi
>
> On Fri, Jan 13, 2017 at 04:50:32AM +0100, Daniel Golle wrote:
>> Please review and comment, so we can get those patches merged!
>
> As already pointed by Kalle posting patches to mailing list is better
> way for review. Posing patches is easy with git-format-patch and
> git-send-email. Ideally patch series should not be long, let say no more
> than 30 patches - I suggest to split this into two series: second one
> for RT3853 support and first one for other patches.

Even 30 patches in a set is quite a lot. I think the pain point is
somewhere about 10-12 patches, anything longer than that and most people
lost interest looking at the patches in detail.

-- 
Kalle Valo

^ permalink raw reply

* Re: linux driver bcm4311 failure
From: Arend Van Spriel @ 2017-01-14 11:53 UTC (permalink / raw)
  To: message, brcm80211-dev-list.pdl, arch-general, linux-wireless
In-Reply-To: <851aa49795494ec407c4783f8579437e@openmailbox.org>

On 14-1-2017 11:15, message wrote:
> On 2017-01-02 20:04, Arend van Spriel wrote:
>> On 02-01-17 15:33, message wrote:
>>> On 2016-12-30 19:46, message wrote:
>>>> On 2016-09-17 08:11, message wrote:
>>>>> On 2016-09-09 07:57, Arend Van Spriel wrote:
>>>>>>
>>>>>> The device is claimed by b43-pci-bridge so I would suggest:
>>>>>>
>>>>>> blacklist b43-pci-bridge
>>>>>>
>>>
>>> The wifi card indicator now appears to start after computer switch on
>>> (twice in a row now!)
>>>
>>> Neither networkmanager or wicd are accepting the password.
>>>
>>> Even:
>>>
>>> wicd-cli --wireless -c [wifihotspotname]
>>> done!
>>>
>>> is false and internet access not found.
>>>
>>> wpa_supplicant continues to report 'conn_failed' error.
>>>
>>> Connection to same network is successful using debian on chromebook
>>> (crouton)
>>
>> I am confused by all your messages. In the previous one you did a
>> 'modprobe b43'. So what driver do you intend to use here. b43 is not a
>> driver maintained by broadcom. You should ask for help on the b43
>> mailing list [1] if you want to use that driver.
>>
>> Regards,
>> Arend
>>
>> [1] http://lists.infradead.org/mailman/listinfo/b43-dev
> 
> After system upgrade, wifi card fails to be recognised.
> 
> For the benefit of other users: save your time and avoid broadcom
> products; they are terrible.

Why sending these types of messages hiding in anonymity without
responding to any of the questions in my email responses. Again what
driver are you using. If it is b43 you want you should not blacklist
b43-pci-bridge. Whether or not b43 supports your device can be found
here [2]. Supposedly it is. If not you might try your luck at the b43
mailing list I gave you in earlier email.

Regards,
Arend

[2] https://wireless.wiki.kernel.org/en/users/drivers/b43#list_of_hardware

^ permalink raw reply

* Re: Searching new home for ath[59]k-devel mailing lists
From: Michael Renzmann @ 2017-01-14  6:48 UTC (permalink / raw)
  To: Kalle Valo; +Cc: linux-wireless, ath5k-devel, ath9k-devel
In-Reply-To: <87y3yfi78t.fsf@purkki.adurom.net>

Hi Kalle.

Thanks for your response.

Kalle Valo wrote:
> So feel free to close both of the lists and thanks for the heads up.

Ok. I will send a shutdown notice to both lists during the next few days,
then unsubscribe all subscribers, and close the lists for new
subscriptions. I intend to keep the mailing list archives online, for
reference purpose.

> Are you planning to update the MAINTAINERS file or should I?

It would be great if you could take care of that.

Someone should also update the "Mailing list" section of [1] accordingly.
I guess one needs to have a valid user account for that to do, and I don't
have one atm.

[1] https://wireless.wiki.kernel.org/en/users/Drivers/ath9k

Bye, Mike

^ permalink raw reply

* [PATCH] mwifiex: don't complain about 'unknown event id: 0x63'
From: Brian Norris @ 2017-01-14  2:16 UTC (permalink / raw)
  To: Amitkumar Karwar, Nishant Sarmukadam
  Cc: linux-kernel, Kalle Valo, linux-wireless, Cathy Luo, Brian Norris

Marvell folks tell me this is a debugging event that the driver doesn't
need to handle, but on 8997 w/ firmware 16.68.1.p97, I see several of
these sorts of messages at (for instance) boot time:

[   13.825848] mwifiex_pcie 0000:01:00.0: event: unknown event id: 0x63
[   14.838561] mwifiex_pcie 0000:01:00.0: event: unknown event id: 0x63
[   14.850397] mwifiex_pcie 0000:01:00.0: event: unknown event id: 0x63
[   32.529923] mwifiex_pcie 0000:01:00.0: event: unknown event id: 0x63

Let's handle this "event" with a much lower verbosity.

Signed-off-by: Brian Norris <briannorris@chromium.org>
---
 drivers/net/wireless/marvell/mwifiex/fw.h        | 1 +
 drivers/net/wireless/marvell/mwifiex/sta_event.c | 4 ++++
 2 files changed, 5 insertions(+)

diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h
index 55db158fd156..cb6a1a81d44e 100644
--- a/drivers/net/wireless/marvell/mwifiex/fw.h
+++ b/drivers/net/wireless/marvell/mwifiex/fw.h
@@ -550,6 +550,7 @@ enum mwifiex_channel_flags {
 #define EVENT_TX_DATA_PAUSE             0x00000055
 #define EVENT_EXT_SCAN_REPORT           0x00000058
 #define EVENT_RXBA_SYNC                 0x00000059
+#define EVENT_UNKNOWN_DEBUG             0x00000063
 #define EVENT_BG_SCAN_STOPPED           0x00000065
 #define EVENT_REMAIN_ON_CHAN_EXPIRED    0x0000005f
 #define EVENT_MULTI_CHAN_INFO           0x0000006a
diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
index 9df0c4dc06ed..96503d3d053f 100644
--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
+++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
@@ -1009,6 +1009,10 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
 					    adapter->event_skb->len -
 					    sizeof(eventcause));
 		break;
+	/* Debugging event; not used, but let's not print an ERROR for it. */
+	case EVENT_UNKNOWN_DEBUG:
+		mwifiex_dbg(adapter, EVENT, "event: debug\n");
+		break;
 	default:
 		mwifiex_dbg(adapter, ERROR, "event: unknown event id: %#x\n",
 			    eventcause);
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related

* [PATCH v2 3/3] mwifiex: pcie: read FROMDEVICE DMA-able memory with READ_ONCE()
From: Brian Norris @ 2017-01-13 23:35 UTC (permalink / raw)
  To: Amitkumar Karwar, Nishant Sarmukadam
  Cc: linux-kernel, Kalle Valo, linux-wireless, Cathy Luo,
	Dmitry Torokhov, Brian Norris
In-Reply-To: <20170113233538.36196-1-briannorris@chromium.org>

In mwifiex_delay_for_sleep_cookie(), we're looping and waiting for the
PCIe endpoint to write a magic value back to memory, to signal that it
has finished going to sleep. We're not letting the compiler know that
this might change underneath our feet though. Let's do that, for good
hygiene.

I'm not aware of this fixing any concrete problems. I also give no
guarantee that this loop is actually correct in any other way, but at
least this looks like an improvement to me.

Signed-off-by: Brian Norris <briannorris@chromium.org>
---
v2: new in v2
---
 drivers/net/wireless/marvell/mwifiex/pcie.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 194e0e04c3b1..c2511f212502 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -440,7 +440,7 @@ static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter,
 
 	for (count = 0; count < max_delay_loop_cnt; count++) {
 		buffer = card->cmdrsp_buf->data - INTF_HEADER_LEN;
-		sleep_cookie = *(u32 *)buffer;
+		sleep_cookie = READ_ONCE(*(u32 *)buffer);
 
 		if (sleep_cookie == MWIFIEX_DEF_SLEEP_COOKIE) {
 			mwifiex_dbg(adapter, INFO,
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related

* [PATCH v2 2/3] mwifiex: pcie: don't loop/retry interrupt status checks
From: Brian Norris @ 2017-01-13 23:35 UTC (permalink / raw)
  To: Amitkumar Karwar, Nishant Sarmukadam
  Cc: linux-kernel, Kalle Valo, linux-wireless, Cathy Luo,
	Dmitry Torokhov, Brian Norris
In-Reply-To: <20170113233538.36196-1-briannorris@chromium.org>

The following sequence occurs when using IEEE power-save on 8997:
(a) driver sees SLEEP event
(b) driver issues SLEEP CONFIRM
(c) driver recevies CMD interrupt; within the interrupt processing loop,
    we do (d) and (e):
(d) wait for FW sleep cookie (and often time out; it takes a while), FW
    is putting card into low power mode
(e) re-check PCIE_HOST_INT_STATUS register; quit loop with 0 value

But at (e), no one actually signaled an interrupt (i.e., we didn't check
adapter->int_status). And what's more, because the card is going to
sleep, this register read appears to take a very long time in some cases
-- 3 milliseconds in my case!

Now, I propose that (e) is completely unnecessary. If there were any
additional interrupts signaled after the start of this loop, then the
interrupt handler would have set adapter->int_status to non-zero and
queued more work for the main loop -- and we'd catch it on the next
iteration of the main loop.

So this patch drops all the looping/re-reading of PCIE_HOST_INT_STATUS,
which avoids the problematic (and slow) register read in step (e).

Incidentally, this is a very similar issue to the one fixed in commit
ec815dd2a5f1 ("mwifiex: prevent register accesses after host is
sleeping"), except that the register read is just very slow instead of
fatal in this case.

Tested on 8997 in both MSI and (though not technically supported at the
moment) MSI-X mode.

Signed-off-by: Brian Norris <briannorris@chromium.org>
---
v2:
 * new in v2, replacing an attempt to mess with step (d) above
---
 drivers/net/wireless/marvell/mwifiex/pcie.c | 102 +++++++++-------------------
 1 file changed, 32 insertions(+), 70 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 3f4cda2d3b61..194e0e04c3b1 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -2332,79 +2332,41 @@ static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter)
 			}
 		}
 	}
-	while (pcie_ireg & HOST_INTR_MASK) {
-		if (pcie_ireg & HOST_INTR_DNLD_DONE) {
-			pcie_ireg &= ~HOST_INTR_DNLD_DONE;
-			mwifiex_dbg(adapter, INTR,
-				    "info: TX DNLD Done\n");
-			ret = mwifiex_pcie_send_data_complete(adapter);
-			if (ret)
-				return ret;
-		}
-		if (pcie_ireg & HOST_INTR_UPLD_RDY) {
-			pcie_ireg &= ~HOST_INTR_UPLD_RDY;
-			mwifiex_dbg(adapter, INTR,
-				    "info: Rx DATA\n");
-			ret = mwifiex_pcie_process_recv_data(adapter);
-			if (ret)
-				return ret;
-		}
-		if (pcie_ireg & HOST_INTR_EVENT_RDY) {
-			pcie_ireg &= ~HOST_INTR_EVENT_RDY;
-			mwifiex_dbg(adapter, INTR,
-				    "info: Rx EVENT\n");
-			ret = mwifiex_pcie_process_event_ready(adapter);
-			if (ret)
-				return ret;
-		}
-
-		if (pcie_ireg & HOST_INTR_CMD_DONE) {
-			pcie_ireg &= ~HOST_INTR_CMD_DONE;
-			if (adapter->cmd_sent) {
-				mwifiex_dbg(adapter, INTR,
-					    "info: CMD sent Interrupt\n");
-				adapter->cmd_sent = false;
-			}
-			/* Handle command response */
-			ret = mwifiex_pcie_process_cmd_complete(adapter);
-			if (ret)
-				return ret;
-			if (adapter->hs_activated)
-				return ret;
-		}
-
-		if (card->msi_enable) {
-			spin_lock_irqsave(&adapter->int_lock, flags);
-			adapter->int_status = 0;
-			spin_unlock_irqrestore(&adapter->int_lock, flags);
-		}
-
-		if (mwifiex_pcie_ok_to_access_hw(adapter)) {
-			if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS,
-					     &pcie_ireg)) {
-				mwifiex_dbg(adapter, ERROR,
-					    "Read register failed\n");
-				return -1;
-			}
 
-			if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) {
-				if (mwifiex_write_reg(adapter,
-						      PCIE_HOST_INT_STATUS,
-						      ~pcie_ireg)) {
-					mwifiex_dbg(adapter, ERROR,
-						    "Write register failed\n");
-					return -1;
-				}
-			}
-
-		}
-		if (!card->msi_enable) {
-			spin_lock_irqsave(&adapter->int_lock, flags);
-			pcie_ireg |= adapter->int_status;
-			adapter->int_status = 0;
-			spin_unlock_irqrestore(&adapter->int_lock, flags);
+	if (pcie_ireg & HOST_INTR_DNLD_DONE) {
+		pcie_ireg &= ~HOST_INTR_DNLD_DONE;
+		mwifiex_dbg(adapter, INTR, "info: TX DNLD Done\n");
+		ret = mwifiex_pcie_send_data_complete(adapter);
+		if (ret)
+			return ret;
+	}
+	if (pcie_ireg & HOST_INTR_UPLD_RDY) {
+		pcie_ireg &= ~HOST_INTR_UPLD_RDY;
+		mwifiex_dbg(adapter, INTR, "info: Rx DATA\n");
+		ret = mwifiex_pcie_process_recv_data(adapter);
+		if (ret)
+			return ret;
+	}
+	if (pcie_ireg & HOST_INTR_EVENT_RDY) {
+		pcie_ireg &= ~HOST_INTR_EVENT_RDY;
+		mwifiex_dbg(adapter, INTR, "info: Rx EVENT\n");
+		ret = mwifiex_pcie_process_event_ready(adapter);
+		if (ret)
+			return ret;
+	}
+	if (pcie_ireg & HOST_INTR_CMD_DONE) {
+		pcie_ireg &= ~HOST_INTR_CMD_DONE;
+		if (adapter->cmd_sent) {
+			mwifiex_dbg(adapter, INTR,
+				    "info: CMD sent Interrupt\n");
+			adapter->cmd_sent = false;
 		}
+		/* Handle command response */
+		ret = mwifiex_pcie_process_cmd_complete(adapter);
+		if (ret)
+			return ret;
 	}
+
 	mwifiex_dbg(adapter, INTR,
 		    "info: cmd_sent=%d data_sent=%d\n",
 		    adapter->cmd_sent, adapter->data_sent);
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related

* [PATCH v2 1/3] mwifiex: pcie: use posted write to wake up firmware
From: Brian Norris @ 2017-01-13 23:35 UTC (permalink / raw)
  To: Amitkumar Karwar, Nishant Sarmukadam
  Cc: linux-kernel, Kalle Valo, linux-wireless, Cathy Luo,
	Dmitry Torokhov, Brian Norris

Depending on system factors (e.g., the PCIe link PM state), the first
read to wake up the Wifi firmware can take a long time. There is no
reason to use a (blocking, non-posted) read at this point, so let's just
use a write instead. Write vs. read doesn't matter functionality-wise --
it's just a dummy operation. But let's make sure to re-write with the
correct "ready" signature, since we check for that in other parts of the
driver.

This has been shown to decrease the time spent blocking in this function
on RK3399.

Signed-off-by: Brian Norris <briannorris@chromium.org>
---
v2:
 * write FIRMWARE_READY_PCIE instead of 0
---
 drivers/net/wireless/marvell/mwifiex/pcie.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 66226c615be0..3f4cda2d3b61 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -458,7 +458,6 @@ static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter,
 /* This function wakes up the card by reading fw_status register. */
 static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
 {
-	u32 fw_status;
 	struct pcie_service_card *card = adapter->card;
 	const struct mwifiex_pcie_card_reg *reg = card->pcie.reg;
 
@@ -468,10 +467,10 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
 	if (reg->sleep_cookie)
 		mwifiex_pcie_dev_wakeup_delay(adapter);
 
-	/* Reading fw_status register will wakeup device */
-	if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status)) {
+	/* Accessing fw_status register will wakeup device */
+	if (mwifiex_write_reg(adapter, reg->fw_status, FIRMWARE_READY_PCIE)) {
 		mwifiex_dbg(adapter, ERROR,
-			    "Reading fw_status register failed\n");
+			    "Writing fw_status register failed\n");
 		return -1;
 	}
 
-- 
2.11.0.483.g087da7b7c-goog

^ permalink raw reply related

* Re: [PATCH 2/2] mwifiex: pcie: don't delay for sleep cookie when not required
From: Brian Norris @ 2017-01-13 22:54 UTC (permalink / raw)
  To: Amitkumar Karwar, Nishant Sarmukadam
  Cc: linux-kernel, Kalle Valo, linux-wireless, Cathy Luo
In-Reply-To: <20170112210232.18554-2-briannorris@chromium.org>

On Thu, Jan 12, 2017 at 01:02:32PM -0800, Brian Norris wrote:
> Wifi modules like 8997 don't support the "sleep cookie", and so most of
> the time, we just time out in the mwifiex_delay_for_sleep_cookie()
> function ("max count reached while accessing sleep cookie"). This is a
> waste of time, and we should skip it for modules without the sleep
> cookie flag.
> 
> Additionally, this delay is sometimes counterproductive. For instance,
> when PCIe ASPM is enabled, this extra delay can leave the link idle for
> long enough to re-enter a low-power state even while we are trying to
> wake the module, compounding an additional delay when it comes time to
> read the next register (e.g., the interrupt status). On some systems,
> this is detrimental to overall system latency.
> 
> Signed-off-by: Brian Norris <briannorris@chromium.org>
> ---
> Tested on Marvell 8997, but would be good to get confirmation from Marvell.

It would still be good to get comment from Marvell here, but elsewhere,
they've told me that this breaks the expected handshake procedure. I'm
still not quite sure how that is true, considering that we time out in
the mwifiex_delay_for_sleep_cookie() all the time anyway (so what's the
point of waiting then?)...

But anyway I think I have discovered a proper root cause [1] that is
causing my latency problems above. I'll post a v2 which replaces the
current patch with something else.

Brian

[1] The short version: re-reading the interrupt status register from the
card after we've sent it to sleep takes a long time. We shouldn't do
that.

>  drivers/net/wireless/marvell/mwifiex/pcie.c | 12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
> index 435ba879ef29..11e0673617c7 100644
> --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
> +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
> @@ -1712,11 +1712,13 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
>  					    "Write register failed\n");
>  				return -1;
>  			}
> -			mwifiex_delay_for_sleep_cookie(adapter,
> -						       MWIFIEX_MAX_DELAY_COUNT);
> -			while (reg->sleep_cookie && (count++ < 10) &&
> -			       mwifiex_pcie_ok_to_access_hw(adapter))
> -				usleep_range(50, 60);
> +			if (reg->sleep_cookie) {
> +				mwifiex_delay_for_sleep_cookie(adapter,
> +							       MWIFIEX_MAX_DELAY_COUNT);
> +				while ((count++ < 10) &&
> +				       mwifiex_pcie_ok_to_access_hw(adapter))
> +					usleep_range(50, 60);
> +			}
>  			mwifiex_pcie_enable_host_int(adapter);
>  			mwifiex_process_sleep_confirm_resp(adapter, skb->data,
>  							   skb->len);
> -- 
> 2.11.0.390.gc69c2f50cf-goog
> 

^ 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