* [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, ®);
+ rt2x00_set_field32(®, BCN_OFFSET2_BCN8,
+ rt2800_get_beacon_offset(rt2x00dev, 8));
+ rt2x00_set_field32(®, BCN_OFFSET2_BCN9,
+ rt2800_get_beacon_offset(rt2x00dev, 9));
+ rt2x00_set_field32(®, BCN_OFFSET2_BCN10,
+ rt2800_get_beacon_offset(rt2x00dev, 10));
+ rt2x00_set_field32(®, BCN_OFFSET2_BCN11,
+ rt2800_get_beacon_offset(rt2x00dev, 11));
+ rt2800_register_write(rt2x00dev, BCN_OFFSET2, reg);
+
+ rt2800_register_read(rt2x00dev, BCN_OFFSET3, ®);
+ rt2x00_set_field32(®, BCN_OFFSET3_BCN12,
+ rt2800_get_beacon_offset(rt2x00dev, 12));
+ rt2x00_set_field32(®, BCN_OFFSET3_BCN13,
+ rt2800_get_beacon_offset(rt2x00dev, 13));
+ rt2x00_set_field32(®, BCN_OFFSET3_BCN14,
+ rt2800_get_beacon_offset(rt2x00dev, 14));
+ rt2x00_set_field32(®, 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, ®);
+ rt2x00_set_field32(®, 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(®, H2M_MAILBOX_CSR_CMD_TOKEN, token);
rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG0, arg0);
rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG1, arg1);
+ rt2800_shared_mem_lock(rt2x00dev);
rt2800_register_write_lock(rt2x00dev, H2M_MAILBOX_CSR, reg);
reg = 0;
rt2x00_set_field32(®, 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, ®);
+ 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, ®);
rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX, (bssidx & 0x7));
rt2x00_set_field32(®, 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, ®);
rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_KEYTAB,
@@ -1315,6 +1336,7 @@ static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(®, 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, ®);
rt2x00_set_field32(®, 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(®, 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, ®);
+ 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(®, 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, ®);
rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
+ rt2800_shared_mem_unlock(rt2x00dev);
reg = 0;
rt2x00_set_field32(®, 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, ®);
5044 rt2x00_set_field32(®, TX_LINK_CFG_REMOTE_MFB_LIFETIME, 32);
5045 rt2x00_set_field32(®, TX_LINK_CFG_MFB_ENABLE, 0);
5046 rt2x00_set_field32(®, TX_LINK_CFG_REMOTE_UMFS_ENABLE, 0);
5047 rt2x00_set_field32(®, TX_LINK_CFG_TX_MRQ_EN, 0);
5048 rt2x00_set_field32(®, TX_LINK_CFG_TX_RDG_EN, 0);
5049 rt2x00_set_field32(®, TX_LINK_CFG_TX_CF_ACK_EN, 1);
5050 rt2x00_set_field32(®, TX_LINK_CFG_REMOTE_MFB, 0);
5051 rt2x00_set_field32(®, TX_LINK_CFG_REMOTE_MFS, 0);
5052 rt2800_register_write(rt2x00dev, TX_LINK_CFG, reg);
5053
5054 rt2800_register_read(rt2x00dev, TX_TIMEOUT_CFG, ®);
5055 rt2x00_set_field32(®, TX_TIMEOUT_CFG_MPDU_LIFETIME, 9);
5056 rt2x00_set_field32(®, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT, 32);
5057 rt2x00_set_field32(®, 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, ®);
5061 rt2x00_set_field32(®, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
5062 if (rt2x00_rt(rt2x00dev, RT3883)) {
5063 drv_data->max_psdu = 3;
5064 rt2x00_set_field32(®, 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(®, MAX_LEN_CFG_MAX_PSDU, 2);
5070 } else {
5071 drv_data->max_psdu = 1;
5072 rt2x00_set_field32(®, MAX_LEN_CFG_MAX_PSDU, 1);
5073 }
5074 rt2x00_set_field32(®, MAX_LEN_CFG_MIN_PSDU, 10);
5075 rt2x00_set_field32(®, MAX_LEN_CFG_MIN_MPDU, 10);
5076 rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg);
5077
5078 rt2800_register_read(rt2x00dev, LED_CFG, ®);
5079 rt2x00_set_field32(®, LED_CFG_ON_PERIOD, 70);
5080 rt2x00_set_field32(®, LED_CFG_OFF_PERIOD, 30);
5081 rt2x00_set_field32(®, LED_CFG_SLOW_BLINK_PERIOD, 3);
5082 rt2x00_set_field32(®, LED_CFG_R_LED_MODE, 3);
5083 rt2x00_set_field32(®, LED_CFG_G_LED_MODE, 3);
5084 rt2x00_set_field32(®, LED_CFG_Y_LED_MODE, 3);
5085 rt2x00_set_field32(®, 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, ®);
5091 rt2x00_set_field32(®, TX_RTY_CFG_SHORT_RTY_LIMIT, 15);
5092 rt2x00_set_field32(®, TX_RTY_CFG_LONG_RTY_LIMIT, 31);
5093 rt2x00_set_field32(®, TX_RTY_CFG_LONG_RTY_THRE, 2000);
5094 rt2x00_set_field32(®, TX_RTY_CFG_NON_AGG_RTY_MODE, 0);
5095 rt2x00_set_field32(®, TX_RTY_CFG_AGG_RTY_MODE, 0);
5096 rt2x00_set_field32(®, 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, ®);
5100 rt2x00_set_field32(®, AUTO_RSP_CFG_AUTORESPONDER, 1);
5101 rt2x00_set_field32(®, AUTO_RSP_CFG_BAC_ACK_POLICY, 1);
5102 rt2x00_set_field32(®, AUTO_RSP_CFG_CTS_40_MMODE, 1);
5103 rt2x00_set_field32(®, AUTO_RSP_CFG_CTS_40_MREF, 0);
5104 rt2x00_set_field32(®, AUTO_RSP_CFG_AR_PREAMBLE, 0);
5105 rt2x00_set_field32(®, AUTO_RSP_CFG_DUAL_CTS_EN, 0);
5106 rt2x00_set_field32(®, 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, ®);
5110 rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_RATE, 3);
5111 rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_CTRL, 0);
5112 rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_NAV_SHORT, 1);
5113 rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1);
5114 rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
5115 rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1);
5116 rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_MM40, 0);
5117 rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_GF20, 1);
5118 rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_GF40, 0);
5119 rt2x00_set_field32(®, 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, ®);
5123 rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_RATE, 3);
5124 rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, 0);
5125 rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_NAV_SHORT, 1);
5126 rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1);
5127 rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
5128 rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1);
5129 rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_MM40, 0);
5130 rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_GF20, 1);
5131 rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_GF40, 0);
5132 rt2x00_set_field32(®, 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, ®);
5136 rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_RATE, 0x4004);
5137 rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_CTRL, 1);
5138 rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_NAV_SHORT, 1);
5139 rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_CCK, 0);
5140 rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
5141 rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
5142 rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
5143 rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
5144 rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
5145 rt2x00_set_field32(®, 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, ®);
5149 rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, 0x4084);
5150 rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, 1);
5151 rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_NAV_SHORT, 1);
5152 rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 0);
5153 rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
5154 rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
5155 rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
5156 rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
5157 rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
5158 rt2x00_set_field32(®, 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, ®);
5162 rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_RATE, 0x4004);
5163 rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_CTRL, 1);
5164 rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_NAV_SHORT, 1);
5165 rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_CCK, 0);
5166 rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
5167 rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
5168 rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
5169 rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
5170 rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
5171 rt2x00_set_field32(®, 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, ®);
5175 rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_RATE, 0x4084);
5176 rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_CTRL, 1);
5177 rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_NAV_SHORT, 1);
5178 rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_CCK, 0);
5179 rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
5180 rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
5181 rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
5182 rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
5183 rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
5184 rt2x00_set_field32(®, 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, ®);
5191 rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
5192 rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
5193 rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
5194 rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
5195 rt2x00_set_field32(®, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 3);
5196 rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 0);
5197 rt2x00_set_field32(®, WPDMA_GLO_CFG_BIG_ENDIAN, 0);
5198 rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_HDR_SCATTER, 0);
5199 rt2x00_set_field32(®, 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, ®);
5208 rt2x00_set_field32(®, TXOP_CTRL_CFG_TIMEOUT_TRUN_EN, 1);
5209 rt2x00_set_field32(®, TXOP_CTRL_CFG_AC_TRUN_EN, 1);
5210 rt2x00_set_field32(®, TXOP_CTRL_CFG_TXRATEGRP_TRUN_EN, 1);
5211 rt2x00_set_field32(®, TXOP_CTRL_CFG_USER_MODE_TRUN_EN, 1);
5212 rt2x00_set_field32(®, TXOP_CTRL_CFG_MIMO_PS_TRUN_EN, 1);
5213 rt2x00_set_field32(®, TXOP_CTRL_CFG_RESERVED_TRUN_EN, 1);
5214 rt2x00_set_field32(®, TXOP_CTRL_CFG_LSIG_TXOP_EN, 0);
5215 rt2x00_set_field32(®, TXOP_CTRL_CFG_EXT_CCA_EN, 0);
5216 rt2x00_set_field32(®, TXOP_CTRL_CFG_EXT_CCA_DLY, 88);
5217 rt2x00_set_field32(®, 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, ®);
---
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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox