* [PATCH v3 03/12] wil6210: refresh FW capabilities during interface up
From: Maya Erez @ 2017-11-14 13:25 UTC (permalink / raw)
To: Kalle Valo; +Cc: Lior David, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1510665944-30198-1-git-send-email-qca_merez@qca.qualcomm.com>
From: Lior David <qca_liord@qca.qualcomm.com>
FW capabilities are currently retrieved only during module
initialization, but userspace can replace the firmware while
interface is down, so refresh the FW capabilities when
interface is up (after FW is loaded) to ensure driver
functionality matches the loaded FW.
Signed-off-by: Lior David <qca_liord@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
drivers/net/wireless/ath/wil6210/fw_inc.c | 21 ++++++++-------------
drivers/net/wireless/ath/wil6210/main.c | 25 +++++++++++++++++++++++--
drivers/net/wireless/ath/wil6210/pcie_bus.c | 13 +------------
drivers/net/wireless/ath/wil6210/wil6210.h | 1 +
4 files changed, 33 insertions(+), 27 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/fw_inc.c b/drivers/net/wireless/ath/wil6210/fw_inc.c
index e01acac..7a33792 100644
--- a/drivers/net/wireless/ath/wil6210/fw_inc.c
+++ b/drivers/net/wireless/ath/wil6210/fw_inc.c
@@ -124,24 +124,19 @@ static int fw_ignore_section(struct wil6210_priv *wil, const void *data,
return 0;
}
-static int fw_handle_comment(struct wil6210_priv *wil, const void *data,
- size_t size)
-{
- wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, data, size, true);
-
- return 0;
-}
-
static int
-fw_handle_capabilities(struct wil6210_priv *wil, const void *data,
- size_t size)
+fw_handle_comment(struct wil6210_priv *wil, const void *data,
+ size_t size)
{
const struct wil_fw_record_capabilities *rec = data;
size_t capa_size;
if (size < sizeof(*rec) ||
- le32_to_cpu(rec->magic) != WIL_FW_CAPABILITIES_MAGIC)
+ le32_to_cpu(rec->magic) != WIL_FW_CAPABILITIES_MAGIC) {
+ wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1,
+ data, size, true);
return 0;
+ }
capa_size = size - offsetof(struct wil_fw_record_capabilities,
capabilities);
@@ -422,7 +417,7 @@ static int fw_handle_gateway_data4(struct wil6210_priv *wil, const void *data,
int (*parse_handler)(struct wil6210_priv *wil, const void *data,
size_t size);
} wil_fw_handlers[] = {
- {wil_fw_type_comment, fw_handle_comment, fw_handle_capabilities},
+ {wil_fw_type_comment, fw_handle_comment, fw_handle_comment},
{wil_fw_type_data, fw_handle_data, fw_ignore_section},
{wil_fw_type_fill, fw_handle_fill, fw_ignore_section},
/* wil_fw_type_action */
@@ -517,7 +512,7 @@ int wil_request_firmware(struct wil6210_priv *wil, const char *name,
rc = request_firmware(&fw, name, wil_to_dev(wil));
if (rc) {
- wil_err_fw(wil, "Failed to load firmware %s\n", name);
+ wil_err_fw(wil, "Failed to load firmware %s rc %d\n", name, rc);
return rc;
}
wil_dbg_fw(wil, "Loading <%s>, %zu bytes\n", name, fw->size);
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 885924a..e92fd35 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -760,6 +760,8 @@ static void wil_collect_fw_info(struct wil6210_priv *wil)
u8 retry_short;
int rc;
+ wil_refresh_fw_capabilities(wil);
+
rc = wmi_get_mgmt_retry(wil, &retry_short);
if (!rc) {
wiphy->retry_short = retry_short;
@@ -767,6 +769,25 @@ static void wil_collect_fw_info(struct wil6210_priv *wil)
}
}
+void wil_refresh_fw_capabilities(struct wil6210_priv *wil)
+{
+ struct wiphy *wiphy = wil_to_wiphy(wil);
+
+ wil->keep_radio_on_during_sleep =
+ wil->platform_ops.keep_radio_on_during_sleep &&
+ wil->platform_ops.keep_radio_on_during_sleep(
+ wil->platform_handle) &&
+ test_bit(WMI_FW_CAPABILITY_D3_SUSPEND, wil->fw_capabilities);
+
+ wil_info(wil, "keep_radio_on_during_sleep (%d)\n",
+ wil->keep_radio_on_during_sleep);
+
+ if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING, wil->fw_capabilities))
+ wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+ else
+ wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
+}
+
void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r)
{
le32_to_cpus(&r->base);
@@ -1071,11 +1092,11 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
return rc;
}
+ wil_collect_fw_info(wil);
+
if (wil->ps_profile != WMI_PS_PROFILE_TYPE_DEFAULT)
wil_ps_update(wil, wil->ps_profile);
- wil_collect_fw_info(wil);
-
if (wil->platform_ops.notify) {
rc = wil->platform_ops.notify(wil->platform_handle,
WIL_PLATFORM_EVT_FW_RDY);
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index f281220..fdab8a5 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -83,9 +83,7 @@ void wil_set_capabilities(struct wil6210_priv *wil)
/* extract FW capabilities from file without loading the FW */
wil_request_firmware(wil, wil->wil_fw_name, false);
-
- if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING, wil->fw_capabilities))
- wil_to_wiphy(wil)->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+ wil_refresh_fw_capabilities(wil);
}
void wil_disable_irq(struct wil6210_priv *wil)
@@ -295,15 +293,6 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
wil_set_capabilities(wil);
wil6210_clear_irq(wil);
- wil->keep_radio_on_during_sleep =
- wil->platform_ops.keep_radio_on_during_sleep &&
- wil->platform_ops.keep_radio_on_during_sleep(
- wil->platform_handle) &&
- test_bit(WMI_FW_CAPABILITY_D3_SUSPEND, wil->fw_capabilities);
-
- wil_info(wil, "keep_radio_on_during_sleep (%d)\n",
- wil->keep_radio_on_during_sleep);
-
/* FW should raise IRQ when ready */
rc = wil_if_pcie_enable(wil);
if (rc) {
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 533cbb3..8e9919b 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -870,6 +870,7 @@ int wil_ps_update(struct wil6210_priv *wil,
int __wil_up(struct wil6210_priv *wil);
int wil_down(struct wil6210_priv *wil);
int __wil_down(struct wil6210_priv *wil);
+void wil_refresh_fw_capabilities(struct wil6210_priv *wil);
void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r);
int wil_find_cid(struct wil6210_priv *wil, const u8 *mac);
void wil_set_ethtoolops(struct net_device *ndev);
--
1.9.1
^ permalink raw reply related
* [PATCH v3 04/12] wil6210: abort properly in cfg suspend
From: Maya Erez @ 2017-11-14 13:25 UTC (permalink / raw)
To: Kalle Valo; +Cc: Hamad Kadmany, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1510665944-30198-1-git-send-email-qca_merez@qca.qualcomm.com>
From: Hamad Kadmany <qca_hkadmany@qca.qualcomm.com>
On-going operations were not aborted properly
and required locks were not taken.
Signed-off-by: Hamad Kadmany <qca_hkadmany@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
drivers/net/wireless/ath/wil6210/cfg80211.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 85d5c04..c3d3c0c 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -1727,9 +1727,12 @@ static int wil_cfg80211_suspend(struct wiphy *wiphy,
wil_dbg_pm(wil, "suspending\n");
- wil_p2p_stop_discovery(wil);
-
+ mutex_lock(&wil->mutex);
+ mutex_lock(&wil->p2p_wdev_mutex);
+ wil_p2p_stop_radio_operations(wil);
wil_abort_scan(wil, true);
+ mutex_unlock(&wil->p2p_wdev_mutex);
+ mutex_unlock(&wil->mutex);
out:
return rc;
--
1.9.1
^ permalink raw reply related
* [PATCH v3 05/12] wil6210: fix length check in __wmi_send
From: Maya Erez @ 2017-11-14 13:25 UTC (permalink / raw)
To: Kalle Valo; +Cc: Lior David, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1510665944-30198-1-git-send-email-qca_merez@qca.qualcomm.com>
From: Lior David <qca_liord@qca.qualcomm.com>
The current length check:
sizeof(cmd) + len > r->entry_size
will allow very large values of len (> U16_MAX - sizeof(cmd))
and can cause a buffer overflow. Fix the check to cover this case.
In addition, ensure the mailbox entry_size is not too small,
since this can also bypass the above check.
Signed-off-by: Lior David <qca_liord@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
drivers/net/wireless/ath/wil6210/interrupt.c | 22 +++++++++++++++++++++-
drivers/net/wireless/ath/wil6210/wmi.c | 2 +-
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index 59def4f..5cf3417 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -358,6 +358,25 @@ static void wil_cache_mbox_regs(struct wil6210_priv *wil)
wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
}
+static bool wil_validate_mbox_regs(struct wil6210_priv *wil)
+{
+ size_t min_size = sizeof(struct wil6210_mbox_hdr) +
+ sizeof(struct wmi_cmd_hdr);
+
+ if (wil->mbox_ctl.rx.entry_size < min_size) {
+ wil_err(wil, "rx mbox entry too small (%d)\n",
+ wil->mbox_ctl.rx.entry_size);
+ return false;
+ }
+ if (wil->mbox_ctl.tx.entry_size < min_size) {
+ wil_err(wil, "tx mbox entry too small (%d)\n",
+ wil->mbox_ctl.tx.entry_size);
+ return false;
+ }
+
+ return true;
+}
+
static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
{
struct wil6210_priv *wil = cookie;
@@ -393,7 +412,8 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
if (isr & ISR_MISC_FW_READY) {
wil_dbg_irq(wil, "IRQ: FW ready\n");
wil_cache_mbox_regs(wil);
- set_bit(wil_status_mbox_ready, wil->status);
+ if (wil_validate_mbox_regs(wil))
+ set_bit(wil_status_mbox_ready, wil->status);
/**
* Actual FW ready indicated by the
* WMI_FW_READY_EVENTID
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 8a780f2..dbdf71d 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -448,7 +448,7 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
uint retry;
int rc = 0;
- if (sizeof(cmd) + len > r->entry_size) {
+ if (len > r->entry_size - sizeof(cmd)) {
wil_err(wil, "WMI size too large: %d bytes, max is %d\n",
(int)(sizeof(cmd) + len), r->entry_size);
return -ERANGE;
--
1.9.1
^ permalink raw reply related
* [PATCH v3 06/12] wil6210: add block size checks during FW load
From: Maya Erez @ 2017-11-14 13:25 UTC (permalink / raw)
To: Kalle Valo; +Cc: Lior David, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1510665944-30198-1-git-send-email-qca_merez@qca.qualcomm.com>
From: Lior David <qca_liord@qca.qualcomm.com>
When loading FW from file add block size checks to ensure a
corrupted FW file will not cause the driver to write outside
the device memory.
Signed-off-by: Lior David <qca_liord@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
drivers/net/wireless/ath/wil6210/fw_inc.c | 58 +++++++++++++++++++-----------
drivers/net/wireless/ath/wil6210/wil6210.h | 1 +
drivers/net/wireless/ath/wil6210/wmi.c | 11 +++++-
3 files changed, 49 insertions(+), 21 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/fw_inc.c b/drivers/net/wireless/ath/wil6210/fw_inc.c
index 7a33792..77d1902 100644
--- a/drivers/net/wireless/ath/wil6210/fw_inc.c
+++ b/drivers/net/wireless/ath/wil6210/fw_inc.c
@@ -26,14 +26,17 @@
prefix_type, rowsize, \
groupsize, buf, len, ascii)
-#define FW_ADDR_CHECK(ioaddr, val, msg) do { \
- ioaddr = wmi_buffer(wil, val); \
- if (!ioaddr) { \
- wil_err_fw(wil, "bad " msg ": 0x%08x\n", \
- le32_to_cpu(val)); \
- return -EINVAL; \
- } \
- } while (0)
+static bool wil_fw_addr_check(struct wil6210_priv *wil,
+ void __iomem **ioaddr, __le32 val,
+ u32 size, const char *msg)
+{
+ *ioaddr = wmi_buffer_block(wil, val, size);
+ if (!(*ioaddr)) {
+ wil_err_fw(wil, "bad %s: 0x%08x\n", msg, le32_to_cpu(val));
+ return false;
+ }
+ return true;
+}
/**
* wil_fw_verify - verify firmware file validity
@@ -160,7 +163,8 @@ static int fw_handle_data(struct wil6210_priv *wil, const void *data,
return -EINVAL;
}
- FW_ADDR_CHECK(dst, d->addr, "address");
+ if (!wil_fw_addr_check(wil, &dst, d->addr, s, "address"))
+ return -EINVAL;
wil_dbg_fw(wil, "write [0x%08x] <== %zu bytes\n", le32_to_cpu(d->addr),
s);
wil_memcpy_toio_32(dst, d->data, s);
@@ -192,7 +196,8 @@ static int fw_handle_fill(struct wil6210_priv *wil, const void *data,
return -EINVAL;
}
- FW_ADDR_CHECK(dst, d->addr, "address");
+ if (!wil_fw_addr_check(wil, &dst, d->addr, s, "address"))
+ return -EINVAL;
v = le32_to_cpu(d->value);
wil_dbg_fw(wil, "fill [0x%08x] <== 0x%08x, %zu bytes\n",
@@ -248,7 +253,8 @@ static int fw_handle_direct_write(struct wil6210_priv *wil, const void *data,
u32 v = le32_to_cpu(block[i].value);
u32 x, y;
- FW_ADDR_CHECK(dst, block[i].addr, "address");
+ if (!wil_fw_addr_check(wil, &dst, block[i].addr, 0, "address"))
+ return -EINVAL;
x = readl(dst);
y = (x & m) | (v & ~m);
@@ -314,10 +320,15 @@ static int fw_handle_gateway_data(struct wil6210_priv *wil, const void *data,
wil_dbg_fw(wil, "gw write record [%3d] blocks, cmd 0x%08x\n",
n, gw_cmd);
- FW_ADDR_CHECK(gwa_addr, d->gateway_addr_addr, "gateway_addr_addr");
- FW_ADDR_CHECK(gwa_val, d->gateway_value_addr, "gateway_value_addr");
- FW_ADDR_CHECK(gwa_cmd, d->gateway_cmd_addr, "gateway_cmd_addr");
- FW_ADDR_CHECK(gwa_ctl, d->gateway_ctrl_address, "gateway_ctrl_address");
+ if (!wil_fw_addr_check(wil, &gwa_addr, d->gateway_addr_addr, 0,
+ "gateway_addr_addr") ||
+ !wil_fw_addr_check(wil, &gwa_val, d->gateway_value_addr, 0,
+ "gateway_value_addr") ||
+ !wil_fw_addr_check(wil, &gwa_cmd, d->gateway_cmd_addr, 0,
+ "gateway_cmd_addr") ||
+ !wil_fw_addr_check(wil, &gwa_ctl, d->gateway_ctrl_address, 0,
+ "gateway_ctrl_address"))
+ return -EINVAL;
wil_dbg_fw(wil, "gw addresses: addr 0x%08x val 0x%08x"
" cmd 0x%08x ctl 0x%08x\n",
@@ -373,12 +384,19 @@ static int fw_handle_gateway_data4(struct wil6210_priv *wil, const void *data,
wil_dbg_fw(wil, "gw4 write record [%3d] blocks, cmd 0x%08x\n",
n, gw_cmd);
- FW_ADDR_CHECK(gwa_addr, d->gateway_addr_addr, "gateway_addr_addr");
+ if (!wil_fw_addr_check(wil, &gwa_addr, d->gateway_addr_addr, 0,
+ "gateway_addr_addr"))
+ return -EINVAL;
for (k = 0; k < ARRAY_SIZE(block->value); k++)
- FW_ADDR_CHECK(gwa_val[k], d->gateway_value_addr[k],
- "gateway_value_addr");
- FW_ADDR_CHECK(gwa_cmd, d->gateway_cmd_addr, "gateway_cmd_addr");
- FW_ADDR_CHECK(gwa_ctl, d->gateway_ctrl_address, "gateway_ctrl_address");
+ if (!wil_fw_addr_check(wil, &gwa_val[k],
+ d->gateway_value_addr[k],
+ 0, "gateway_value_addr"))
+ return -EINVAL;
+ if (!wil_fw_addr_check(wil, &gwa_cmd, d->gateway_cmd_addr, 0,
+ "gateway_cmd_addr") ||
+ !wil_fw_addr_check(wil, &gwa_ctl, d->gateway_ctrl_address, 0,
+ "gateway_ctrl_address"))
+ return -EINVAL;
wil_dbg_fw(wil, "gw4 addresses: addr 0x%08x cmd 0x%08x ctl 0x%08x\n",
le32_to_cpu(d->gateway_addr_addr),
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 8e9919b..48802ae 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -875,6 +875,7 @@ int wil_ps_update(struct wil6210_priv *wil,
int wil_find_cid(struct wil6210_priv *wil, const u8 *mac);
void wil_set_ethtoolops(struct net_device *ndev);
+void __iomem *wmi_buffer_block(struct wil6210_priv *wil, __le32 ptr, u32 size);
void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr);
void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr);
int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr,
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index dbdf71d..16aa624 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -140,13 +140,15 @@ static u32 wmi_addr_remap(u32 x)
/**
* Check address validity for WMI buffer; remap if needed
* @ptr - internal (linker) fw/ucode address
+ * @size - if non zero, validate the block does not
+ * exceed the device memory (bar)
*
* Valid buffer should be DWORD aligned
*
* return address for accessing buffer from the host;
* if buffer is not valid, return NULL.
*/
-void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_)
+void __iomem *wmi_buffer_block(struct wil6210_priv *wil, __le32 ptr_, u32 size)
{
u32 off;
u32 ptr = le32_to_cpu(ptr_);
@@ -161,10 +163,17 @@ void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_)
off = HOSTADDR(ptr);
if (off > wil->bar_size - 4)
return NULL;
+ if (size && ((off + size > wil->bar_size) || (off + size < off)))
+ return NULL;
return wil->csr + off;
}
+void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_)
+{
+ return wmi_buffer_block(wil, ptr_, 0);
+}
+
/**
* Check address validity
*/
--
1.9.1
^ permalink raw reply related
* [PATCH v3 07/12] wil6210: missing length check in wmi_set_ie
From: Maya Erez @ 2017-11-14 13:25 UTC (permalink / raw)
To: Kalle Valo; +Cc: Lior David, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1510665944-30198-1-git-send-email-qca_merez@qca.qualcomm.com>
From: Lior David <qca_liord@qca.qualcomm.com>
Add a length check in wmi_set_ie to detect unsigned integer
overflow.
Signed-off-by: Lior David <qca_liord@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
drivers/net/wireless/ath/wil6210/wmi.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 16aa624..dd25f63 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -1616,8 +1616,14 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie)
};
int rc;
u16 len = sizeof(struct wmi_set_appie_cmd) + ie_len;
- struct wmi_set_appie_cmd *cmd = kzalloc(len, GFP_KERNEL);
+ struct wmi_set_appie_cmd *cmd;
+ if (len < ie_len) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ cmd = kzalloc(len, GFP_KERNEL);
if (!cmd) {
rc = -ENOMEM;
goto out;
--
1.9.1
^ permalink raw reply related
* [PATCH v3 08/12] wil6210: missing length check in wil_cfg80211_mgmt_tx
From: Maya Erez @ 2017-11-14 13:25 UTC (permalink / raw)
To: Kalle Valo; +Cc: Lior David, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1510665944-30198-1-git-send-email-qca_merez@qca.qualcomm.com>
From: Lior David <qca_liord@qca.qualcomm.com>
Add a length check in wil_cfg80211_mgmt_tx to detect unsigned integer
overflow.
Signed-off-by: Lior David <qca_liord@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
drivers/net/wireless/ath/wil6210/cfg80211.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index c3d3c0c..771a534 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -901,7 +901,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
u64 *cookie)
{
const u8 *buf = params->buf;
- size_t len = params->len;
+ size_t len = params->len, total;
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
int rc;
bool tx_status = false;
@@ -926,7 +926,11 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
if (len < sizeof(struct ieee80211_hdr_3addr))
return -EINVAL;
- cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL);
+ total = sizeof(*cmd) + len;
+ if (total < len)
+ return -EINVAL;
+
+ cmd = kmalloc(total, GFP_KERNEL);
if (!cmd) {
rc = -ENOMEM;
goto out;
@@ -936,7 +940,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
cmd->len = cpu_to_le16(len);
memcpy(cmd->payload, buf, len);
- rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, sizeof(*cmd) + len,
+ rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, total,
WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000);
if (rc == 0)
tx_status = !evt.evt.status;
--
1.9.1
^ permalink raw reply related
* [PATCH v3 09/12] wil6210: get suspend reject reason and resume triggers from FW
From: Maya Erez @ 2017-11-14 13:25 UTC (permalink / raw)
To: Kalle Valo; +Cc: Lazar Alexei, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1510665944-30198-1-git-send-email-qca_merez@qca.qualcomm.com>
From: Lazar Alexei <qca_ailizaro@qca.qualcomm.com>
Upon receiving suspend reject, print reject reason.
Upon receiving resume event, print resume triggers.
Signed-off-by: Lazar Alexei <qca_ailizaro@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
drivers/net/wireless/ath/wil6210/wmi.c | 46 +++++++++++++++++++++++++++++++---
drivers/net/wireless/ath/wil6210/wmi.h | 17 ++++++++++---
2 files changed, 57 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index dd25f63..8ace618 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -2043,6 +2043,16 @@ void wmi_event_flush(struct wil6210_priv *wil)
spin_unlock_irqrestore(&wil->wmi_ev_lock, flags);
}
+static const char *suspend_status2name(u8 status)
+{
+ switch (status) {
+ case WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE:
+ return "LINK_NOT_IDLE";
+ default:
+ return "Untracked status";
+ }
+}
+
int wmi_suspend(struct wil6210_priv *wil)
{
int rc;
@@ -2058,7 +2068,7 @@ int wmi_suspend(struct wil6210_priv *wil)
wil->suspend_resp_rcvd = false;
wil->suspend_resp_comp = false;
- reply.evt.status = WMI_TRAFFIC_SUSPEND_REJECTED;
+ reply.evt.status = WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE;
rc = wmi_call(wil, WMI_TRAFFIC_SUSPEND_CMDID, &cmd, sizeof(cmd),
WMI_TRAFFIC_SUSPEND_EVENTID, &reply, sizeof(reply),
@@ -2090,8 +2100,9 @@ int wmi_suspend(struct wil6210_priv *wil)
}
wil_dbg_wmi(wil, "suspend_response_completed rcvd\n");
- if (reply.evt.status == WMI_TRAFFIC_SUSPEND_REJECTED) {
- wil_dbg_pm(wil, "device rejected the suspend\n");
+ if (reply.evt.status != WMI_TRAFFIC_SUSPEND_APPROVED) {
+ wil_dbg_pm(wil, "device rejected the suspend, %s\n",
+ suspend_status2name(reply.evt.status));
wil->suspend_stats.rejected_by_device++;
}
rc = reply.evt.status;
@@ -2103,21 +2114,50 @@ int wmi_suspend(struct wil6210_priv *wil)
return rc;
}
+static void resume_triggers2string(u32 triggers, char *string, int str_size)
+{
+ string[0] = '\0';
+
+ if (!triggers) {
+ strlcat(string, " UNKNOWN", str_size);
+ return;
+ }
+
+ if (triggers & WMI_RESUME_TRIGGER_HOST)
+ strlcat(string, " HOST", str_size);
+
+ if (triggers & WMI_RESUME_TRIGGER_UCAST_RX)
+ strlcat(string, " UCAST_RX", str_size);
+
+ if (triggers & WMI_RESUME_TRIGGER_BCAST_RX)
+ strlcat(string, " BCAST_RX", str_size);
+
+ if (triggers & WMI_RESUME_TRIGGER_WMI_EVT)
+ strlcat(string, " WMI_EVT", str_size);
+}
+
int wmi_resume(struct wil6210_priv *wil)
{
int rc;
+ char string[100];
struct {
struct wmi_cmd_hdr wmi;
struct wmi_traffic_resume_event evt;
} __packed reply;
reply.evt.status = WMI_TRAFFIC_RESUME_FAILED;
+ reply.evt.resume_triggers = WMI_RESUME_TRIGGER_UNKNOWN;
rc = wmi_call(wil, WMI_TRAFFIC_RESUME_CMDID, NULL, 0,
WMI_TRAFFIC_RESUME_EVENTID, &reply, sizeof(reply),
WIL_WAIT_FOR_SUSPEND_RESUME_COMP);
if (rc)
return rc;
+ resume_triggers2string(le32_to_cpu(reply.evt.resume_triggers), string,
+ sizeof(string));
+ wil_dbg_pm(wil, "device resume %s, resume triggers:%s (0x%x)\n",
+ reply.evt.status ? "failed" : "passed", string,
+ le32_to_cpu(reply.evt.resume_triggers));
return reply.evt.status;
}
diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h
index 5263ee7..d9e220a 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.h
+++ b/drivers/net/wireless/ath/wil6210/wmi.h
@@ -2267,8 +2267,8 @@ struct wmi_link_maintain_cfg_read_done_event {
} __packed;
enum wmi_traffic_suspend_status {
- WMI_TRAFFIC_SUSPEND_APPROVED = 0x0,
- WMI_TRAFFIC_SUSPEND_REJECTED = 0x1,
+ WMI_TRAFFIC_SUSPEND_APPROVED = 0x0,
+ WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE = 0x1,
};
/* WMI_TRAFFIC_SUSPEND_EVENTID */
@@ -2282,10 +2282,21 @@ enum wmi_traffic_resume_status {
WMI_TRAFFIC_RESUME_FAILED = 0x1,
};
+enum wmi_resume_trigger {
+ WMI_RESUME_TRIGGER_UNKNOWN = 0x0,
+ WMI_RESUME_TRIGGER_HOST = 0x1,
+ WMI_RESUME_TRIGGER_UCAST_RX = 0x2,
+ WMI_RESUME_TRIGGER_BCAST_RX = 0x4,
+ WMI_RESUME_TRIGGER_WMI_EVT = 0x8,
+};
+
/* WMI_TRAFFIC_RESUME_EVENTID */
struct wmi_traffic_resume_event {
- /* enum wmi_traffic_resume_status_e */
+ /* enum wmi_traffic_resume_status */
u8 status;
+ u8 reserved[3];
+ /* enum wmi_resume_trigger bitmap */
+ __le32 resume_triggers;
} __packed;
/* Power Save command completion status codes */
--
1.9.1
^ permalink raw reply related
* [PATCH v3 10/12] wil6210: fix PCIe bus mastering in case of interface down
From: Maya Erez @ 2017-11-14 13:25 UTC (permalink / raw)
To: Kalle Valo; +Cc: Lazar Alexei, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1510665944-30198-1-git-send-email-qca_merez@qca.qualcomm.com>
From: Lazar Alexei <qca_ailizaro@qca.qualcomm.com>
In case of interface down, radio is turned off but PCIe mastering is
not cleared.
This can cause unexpected PCIe access to the shutdown device.
Fix this by clearing PCIe mastering also in case interface is down
Signed-off-by: Lazar Alexei <qca_ailizaro@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
drivers/net/wireless/ath/wil6210/pcie_bus.c | 24 +++++++++++++++---------
drivers/net/wireless/ath/wil6210/pm.c | 10 ++--------
drivers/net/wireless/ath/wil6210/wil6210.h | 4 ++--
3 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index fdab8a5..0592c73 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -379,6 +379,9 @@ static int wil6210_suspend(struct device *dev, bool is_runtime)
int rc = 0;
struct pci_dev *pdev = to_pci_dev(dev);
struct wil6210_priv *wil = pci_get_drvdata(pdev);
+ struct net_device *ndev = wil_to_ndev(wil);
+ bool keep_radio_on = ndev->flags & IFF_UP &&
+ wil->keep_radio_on_during_sleep;
wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system");
@@ -386,14 +389,14 @@ static int wil6210_suspend(struct device *dev, bool is_runtime)
if (rc)
goto out;
- rc = wil_suspend(wil, is_runtime);
+ rc = wil_suspend(wil, is_runtime, keep_radio_on);
if (!rc) {
wil->suspend_stats.successful_suspends++;
- /* If platform device supports keep_radio_on_during_sleep
- * it will control PCIe master
+ /* In case radio stays on, platform device will control
+ * PCIe master
*/
- if (!wil->keep_radio_on_during_sleep)
+ if (!keep_radio_on)
/* disable bus mastering */
pci_clear_master(pdev);
}
@@ -406,20 +409,23 @@ static int wil6210_resume(struct device *dev, bool is_runtime)
int rc = 0;
struct pci_dev *pdev = to_pci_dev(dev);
struct wil6210_priv *wil = pci_get_drvdata(pdev);
+ struct net_device *ndev = wil_to_ndev(wil);
+ bool keep_radio_on = ndev->flags & IFF_UP &&
+ wil->keep_radio_on_during_sleep;
wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system");
- /* If platform device supports keep_radio_on_during_sleep it will
- * control PCIe master
+ /* In case radio stays on, platform device will control
+ * PCIe master
*/
- if (!wil->keep_radio_on_during_sleep)
+ if (!keep_radio_on)
/* allow master */
pci_set_master(pdev);
- rc = wil_resume(wil, is_runtime);
+ rc = wil_resume(wil, is_runtime, keep_radio_on);
if (rc) {
wil_err(wil, "device failed to resume (%d)\n", rc);
wil->suspend_stats.failed_resumes++;
- if (!wil->keep_radio_on_during_sleep)
+ if (!keep_radio_on)
pci_clear_master(pdev);
} else {
wil->suspend_stats.successful_resumes++;
diff --git a/drivers/net/wireless/ath/wil6210/pm.c b/drivers/net/wireless/ath/wil6210/pm.c
index 43699ac..6fd5420 100644
--- a/drivers/net/wireless/ath/wil6210/pm.c
+++ b/drivers/net/wireless/ath/wil6210/pm.c
@@ -304,12 +304,9 @@ static int wil_resume_radio_off(struct wil6210_priv *wil)
return rc;
}
-int wil_suspend(struct wil6210_priv *wil, bool is_runtime)
+int wil_suspend(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on)
{
int rc = 0;
- struct net_device *ndev = wil_to_ndev(wil);
- bool keep_radio_on = ndev->flags & IFF_UP &&
- wil->keep_radio_on_during_sleep;
wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system");
@@ -332,12 +329,9 @@ int wil_suspend(struct wil6210_priv *wil, bool is_runtime)
return rc;
}
-int wil_resume(struct wil6210_priv *wil, bool is_runtime)
+int wil_resume(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on)
{
int rc = 0;
- struct net_device *ndev = wil_to_ndev(wil);
- bool keep_radio_on = ndev->flags & IFF_UP &&
- wil->keep_radio_on_during_sleep;
unsigned long long suspend_time_usec = 0;
wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system");
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 48802ae..7e017b1 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -1016,8 +1016,8 @@ int wil_request_firmware(struct wil6210_priv *wil, const char *name,
void wil_pm_runtime_put(struct wil6210_priv *wil);
int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime);
-int wil_suspend(struct wil6210_priv *wil, bool is_runtime);
-int wil_resume(struct wil6210_priv *wil, bool is_runtime);
+int wil_suspend(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on);
+int wil_resume(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on);
bool wil_is_wmi_idle(struct wil6210_priv *wil);
int wmi_resume(struct wil6210_priv *wil);
int wmi_suspend(struct wil6210_priv *wil);
--
1.9.1
^ permalink raw reply related
* [PATCH v3 11/12] wil6210: remove suspend time statistics
From: Maya Erez @ 2017-11-14 13:25 UTC (permalink / raw)
To: Kalle Valo; +Cc: Lazar Alexei, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1510665944-30198-1-git-send-email-qca_merez@qca.qualcomm.com>
From: Lazar Alexei <qca_ailizaro@qca.qualcomm.com>
Currently suspend time statistics are showed through debugfs.
Remove time statistics in suspend state since the timing may
not be accurate in that state.
Signed-off-by: Lazar Alexei <qca_ailizaro@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
drivers/net/wireless/ath/wil6210/debugfs.c | 17 ++---------------
drivers/net/wireless/ath/wil6210/main.c | 1 -
drivers/net/wireless/ath/wil6210/pm.c | 20 ++------------------
drivers/net/wireless/ath/wil6210/wil6210.h | 5 -----
4 files changed, 4 insertions(+), 39 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 06b9c56..edaab0f 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -1632,8 +1632,6 @@ static ssize_t wil_write_suspend_stats(struct file *file,
struct wil6210_priv *wil = file->private_data;
memset(&wil->suspend_stats, 0, sizeof(wil->suspend_stats));
- wil->suspend_stats.min_suspend_time = ULONG_MAX;
- wil->suspend_stats.collection_start = ktime_get();
return len;
}
@@ -1645,27 +1643,18 @@ static ssize_t wil_read_suspend_stats(struct file *file,
struct wil6210_priv *wil = file->private_data;
static char text[400];
int n;
- unsigned long long stats_collection_time =
- ktime_to_us(ktime_sub(ktime_get(),
- wil->suspend_stats.collection_start));
n = snprintf(text, sizeof(text),
"Suspend statistics:\n"
"successful suspends:%ld failed suspends:%ld\n"
"successful resumes:%ld failed resumes:%ld\n"
- "rejected by host:%ld rejected by device:%ld\n"
- "total suspend time:%lld min suspend time:%lld\n"
- "max suspend time:%lld stats collection time: %lld\n",
+ "rejected by host:%ld rejected by device:%ld\n",
wil->suspend_stats.successful_suspends,
wil->suspend_stats.failed_suspends,
wil->suspend_stats.successful_resumes,
wil->suspend_stats.failed_resumes,
wil->suspend_stats.rejected_by_host,
- wil->suspend_stats.rejected_by_device,
- wil->suspend_stats.total_suspend_time,
- wil->suspend_stats.min_suspend_time,
- wil->suspend_stats.max_suspend_time,
- stats_collection_time);
+ wil->suspend_stats.rejected_by_device);
n = min_t(int, n, sizeof(text));
@@ -1836,8 +1825,6 @@ int wil6210_debugfs_init(struct wil6210_priv *wil)
wil6210_debugfs_create_ITR_CNT(wil, dbg);
- wil->suspend_stats.collection_start = ktime_get();
-
return 0;
}
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index e92fd35..1b53cd3 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -579,7 +579,6 @@ int wil_priv_init(struct wil6210_priv *wil)
wil->wakeup_trigger = WMI_WAKEUP_TRIGGER_UCAST |
WMI_WAKEUP_TRIGGER_BCAST;
memset(&wil->suspend_stats, 0, sizeof(wil->suspend_stats));
- wil->suspend_stats.min_suspend_time = ULONG_MAX;
wil->vring_idle_trsh = 16;
return 0;
diff --git a/drivers/net/wireless/ath/wil6210/pm.c b/drivers/net/wireless/ath/wil6210/pm.c
index 6fd5420..9fba237 100644
--- a/drivers/net/wireless/ath/wil6210/pm.c
+++ b/drivers/net/wireless/ath/wil6210/pm.c
@@ -323,16 +323,12 @@ int wil_suspend(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on)
wil_dbg_pm(wil, "suspend: %s => %d\n",
is_runtime ? "runtime" : "system", rc);
- if (!rc)
- wil->suspend_stats.suspend_start_time = ktime_get();
-
return rc;
}
int wil_resume(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on)
{
int rc = 0;
- unsigned long long suspend_time_usec = 0;
wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system");
@@ -350,21 +346,9 @@ int wil_resume(struct wil6210_priv *wil, bool is_runtime, bool keep_radio_on)
else
rc = wil_resume_radio_off(wil);
- if (rc)
- goto out;
-
- suspend_time_usec =
- ktime_to_us(ktime_sub(ktime_get(),
- wil->suspend_stats.suspend_start_time));
- wil->suspend_stats.total_suspend_time += suspend_time_usec;
- if (suspend_time_usec < wil->suspend_stats.min_suspend_time)
- wil->suspend_stats.min_suspend_time = suspend_time_usec;
- if (suspend_time_usec > wil->suspend_stats.max_suspend_time)
- wil->suspend_stats.max_suspend_time = suspend_time_usec;
-
out:
- wil_dbg_pm(wil, "resume: %s => %d, suspend time %lld usec\n",
- is_runtime ? "runtime" : "system", rc, suspend_time_usec);
+ wil_dbg_pm(wil, "resume: %s => %d\n", is_runtime ? "runtime" : "system",
+ rc);
return rc;
}
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 7e017b1..ea04117 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -89,11 +89,6 @@ struct wil_suspend_stats {
unsigned long failed_resumes;
unsigned long rejected_by_device;
unsigned long rejected_by_host;
- unsigned long long total_suspend_time;
- unsigned long long min_suspend_time;
- unsigned long long max_suspend_time;
- ktime_t collection_start;
- ktime_t suspend_start_time;
};
/* Calculate MAC buffer size for the firmware. It includes all overhead,
--
1.9.1
^ permalink raw reply related
* [PATCH v3 12/12] wil6210: update statistics for suspend
From: Maya Erez @ 2017-11-14 13:25 UTC (permalink / raw)
To: Kalle Valo; +Cc: Lazar Alexei, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1510665944-30198-1-git-send-email-qca_merez@qca.qualcomm.com>
From: Lazar Alexei <qca_ailizaro@qca.qualcomm.com>
Currently the statistics show how many successful/failed
suspend/resume operations the system had.
Update the statistics by splitting each successful/failed
suspend/resume operations to radio on/off.
Signed-off-by: Lazar Alexei <qca_ailizaro@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
---
drivers/net/wireless/ath/wil6210/debugfs.c | 47 ++++++++++++++++++++---------
drivers/net/wireless/ath/wil6210/pcie_bus.c | 20 ++++++++----
drivers/net/wireless/ath/wil6210/pm.c | 8 +++--
drivers/net/wireless/ath/wil6210/wil6210.h | 11 +++++--
4 files changed, 59 insertions(+), 27 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index edaab0f..4475937 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -1641,24 +1641,41 @@ static ssize_t wil_read_suspend_stats(struct file *file,
size_t count, loff_t *ppos)
{
struct wil6210_priv *wil = file->private_data;
- static char text[400];
- int n;
+ char *text;
+ int n, ret, text_size = 500;
+
+ text = kmalloc(text_size, GFP_KERNEL);
+ if (!text)
+ return -ENOMEM;
- n = snprintf(text, sizeof(text),
- "Suspend statistics:\n"
+ n = snprintf(text, text_size,
+ "Radio on suspend statistics:\n"
"successful suspends:%ld failed suspends:%ld\n"
"successful resumes:%ld failed resumes:%ld\n"
- "rejected by host:%ld rejected by device:%ld\n",
- wil->suspend_stats.successful_suspends,
- wil->suspend_stats.failed_suspends,
- wil->suspend_stats.successful_resumes,
- wil->suspend_stats.failed_resumes,
- wil->suspend_stats.rejected_by_host,
- wil->suspend_stats.rejected_by_device);
-
- n = min_t(int, n, sizeof(text));
-
- return simple_read_from_buffer(user_buf, count, ppos, text, n);
+ "rejected by device:%ld\n"
+ "Radio off suspend statistics:\n"
+ "successful suspends:%ld failed suspends:%ld\n"
+ "successful resumes:%ld failed resumes:%ld\n"
+ "General statistics:\n"
+ "rejected by host:%ld\n",
+ wil->suspend_stats.r_on.successful_suspends,
+ wil->suspend_stats.r_on.failed_suspends,
+ wil->suspend_stats.r_on.successful_resumes,
+ wil->suspend_stats.r_on.failed_resumes,
+ wil->suspend_stats.rejected_by_device,
+ wil->suspend_stats.r_off.successful_suspends,
+ wil->suspend_stats.r_off.failed_suspends,
+ wil->suspend_stats.r_off.successful_resumes,
+ wil->suspend_stats.r_off.failed_resumes,
+ wil->suspend_stats.rejected_by_host);
+
+ n = min_t(int, n, text_size);
+
+ ret = simple_read_from_buffer(user_buf, count, ppos, text, n);
+
+ kfree(text);
+
+ return ret;
}
static const struct file_operations fops_suspend_stats = {
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 0592c73..42a5480 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -391,14 +391,16 @@ static int wil6210_suspend(struct device *dev, bool is_runtime)
rc = wil_suspend(wil, is_runtime, keep_radio_on);
if (!rc) {
- wil->suspend_stats.successful_suspends++;
-
/* In case radio stays on, platform device will control
* PCIe master
*/
- if (!keep_radio_on)
+ if (!keep_radio_on) {
/* disable bus mastering */
pci_clear_master(pdev);
+ wil->suspend_stats.r_off.successful_suspends++;
+ } else {
+ wil->suspend_stats.r_on.successful_suspends++;
+ }
}
out:
return rc;
@@ -424,11 +426,17 @@ static int wil6210_resume(struct device *dev, bool is_runtime)
rc = wil_resume(wil, is_runtime, keep_radio_on);
if (rc) {
wil_err(wil, "device failed to resume (%d)\n", rc);
- wil->suspend_stats.failed_resumes++;
- if (!keep_radio_on)
+ if (!keep_radio_on) {
pci_clear_master(pdev);
+ wil->suspend_stats.r_off.failed_resumes++;
+ } else {
+ wil->suspend_stats.r_on.failed_resumes++;
+ }
} else {
- wil->suspend_stats.successful_resumes++;
+ if (keep_radio_on)
+ wil->suspend_stats.r_on.successful_resumes++;
+ else
+ wil->suspend_stats.r_off.successful_resumes++;
}
return rc;
diff --git a/drivers/net/wireless/ath/wil6210/pm.c b/drivers/net/wireless/ath/wil6210/pm.c
index 9fba237..056b180 100644
--- a/drivers/net/wireless/ath/wil6210/pm.c
+++ b/drivers/net/wireless/ath/wil6210/pm.c
@@ -183,7 +183,7 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv *wil)
break;
wil_err(wil,
"TO waiting for idle RX, suspend failed\n");
- wil->suspend_stats.failed_suspends++;
+ wil->suspend_stats.r_on.failed_suspends++;
goto resume_after_fail;
}
wil_dbg_ratelimited(wil, "rx vring is not empty -> NAPI\n");
@@ -199,7 +199,7 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv *wil)
*/
if (!wil_is_wmi_idle(wil)) {
wil_err(wil, "suspend failed due to pending WMI events\n");
- wil->suspend_stats.failed_suspends++;
+ wil->suspend_stats.r_on.failed_suspends++;
goto resume_after_fail;
}
@@ -213,7 +213,7 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv *wil)
if (rc) {
wil_err(wil, "platform device failed to suspend (%d)\n",
rc);
- wil->suspend_stats.failed_suspends++;
+ wil->suspend_stats.r_on.failed_suspends++;
wil_c(wil, RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD);
wil_unmask_irq(wil);
goto resume_after_fail;
@@ -260,6 +260,7 @@ static int wil_suspend_radio_off(struct wil6210_priv *wil)
rc = wil_down(wil);
if (rc) {
wil_err(wil, "wil_down : %d\n", rc);
+ wil->suspend_stats.r_off.failed_suspends++;
goto out;
}
}
@@ -272,6 +273,7 @@ static int wil_suspend_radio_off(struct wil6210_priv *wil)
rc = wil->platform_ops.suspend(wil->platform_handle, false);
if (rc) {
wil_enable_irq(wil);
+ wil->suspend_stats.r_off.failed_suspends++;
goto out;
}
}
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index ea04117..cf27d97 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -82,12 +82,17 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
*/
#define WIL_MAX_MPDU_OVERHEAD (62)
-struct wil_suspend_stats {
+struct wil_suspend_count_stats {
unsigned long successful_suspends;
- unsigned long failed_suspends;
unsigned long successful_resumes;
+ unsigned long failed_suspends;
unsigned long failed_resumes;
- unsigned long rejected_by_device;
+};
+
+struct wil_suspend_stats {
+ struct wil_suspend_count_stats r_off;
+ struct wil_suspend_count_stats r_on;
+ unsigned long rejected_by_device; /* only radio on */
unsigned long rejected_by_host;
};
--
1.9.1
^ permalink raw reply related
* mwifiex: how to restrict txpower per channel and regulatory region?
From: Porto Rio @ 2017-11-14 14:04 UTC (permalink / raw)
To: linux-wireless
Hi All
For (worldwide) regulatory compliance / WiFi certification I need to restrict/limit the txpower dependent on channels and regulatory region code. At the moment I can restrict it generally via e.g. "iw dev mlan0 set txpower fixed 800". Furthermore I can specify the allowed channels/frequencies with wireless-regdb and crda. Is there some similar way to limit the txpower?
I am using mwifiex (of LTS kernel 4.4 at the moment) on the ARM platform with Marvell chip 88W8897.
There is some Marvell-specific way (specify txpwrlimit_cfg.conf, convert it to txpower_XX.bin file and put this into /lib/firmware/mrvl dir) which seems to work only with the reference driver published in Marvell's Extranet but not with the (open source) mwifiex driver which I want to use. Is this right?
I was asking myself if there is some (more general) Linux way to accomplish this with the open source driver(s), although the txpower limits are dependent on specific hardware parameters (cable loss, antenna gain).
Thanks and best regards,
Matthias
^ permalink raw reply
* RE: [RFC] cfg80211: Implement Multiple BSSID capability in scanning
From: Peng Xu @ 2017-11-14 14:20 UTC (permalink / raw)
To: Johannes Berg, Jouni Malinen; +Cc: linux-wireless@vger.kernel.org, Sara Sharon
In-Reply-To: <1510664296.2030.22.camel@sipsolutions.net>
PiANCj4gPiArCQkJaWYgKHRtcF9vbGRbMF0gPT0gV0xBTl9FSURfVkVORE9SX1NQRUNJRklDKSB7
DQo+ID4gKwkJCQlpZiAoIW1lbWNtcCh0bXBfb2xkICsgMiwgdG1wICsgMiwgNSkpIHsNCj4gPiAr
CQkJCQkvKiBzYW1lIHZlbmRvciBpZSwgY29weSBmcm9tIG5ldyBpZQ0KPiAqLw0KPiA+ICsJCQkJ
CW1lbWNweShwb3MsIHRtcCwgdG1wWzFdICsgMik7DQo+ID4gKwkJCQkJcG9zICs9IHRtcFsxXSAr
IDI7DQo+ID4gKwkJCQl9IGVsc2Ugew0KPiA+ICsJCQkJCW1lbWNweShwb3MsIHRtcF9vbGQsIHRt
cF9vbGRbMV0gKw0KPiAyKTsNCj4gPiArCQkJCQlwb3MgKz0gdG1wX29sZFsxXSArIDI7DQo+IA0K
PiBUaGlzIHNlZW1zIHJlYWxseSBzdHJhbmdlLiBXaGF0J3MgNT8gU2hvdWxkIGl0IGJlIDQsIHNv
IHlvdSBoYXZlDQo+IE9VSStzdWJlbGVtZW50IElEPw0KPiANCg0KSXQgaXMgT1VJICsgdHlwZSAr
IHN1YlR5ZS4NCg0KDQpUaGFua3MsDQpQZW5nIA0K
^ permalink raw reply
* Re: [RFC] cfg80211: Implement Multiple BSSID capability in scanning
From: Johannes Berg @ 2017-11-14 14:23 UTC (permalink / raw)
To: Peng Xu, Jouni Malinen; +Cc: linux-wireless@vger.kernel.org, Sara Sharon
In-Reply-To: <4927d2288442486788cd5b4d0492537a@NASANEXM01F.na.qualcomm.com>
On Tue, 2017-11-14 at 14:20 +0000, Peng Xu wrote:
> >
> > > + if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) {
> > > + if (!memcmp(tmp_old + 2, tmp + 2, 5)) {
> > > + /* same vendor ie, copy from new ie
> >
> > */
> > > + memcpy(pos, tmp, tmp[1] + 2);
> > > + pos += tmp[1] + 2;
> > > + } else {
> > > + memcpy(pos, tmp_old, tmp_old[1] +
> >
> > 2);
> > > + pos += tmp_old[1] + 2;
> >
> > This seems really strange. What's 5? Should it be 4, so you have
> > OUI+subelement ID?
> >
>
> It is OUI + type + subTye.
Ah, right, type/subtype.
Still, this is problematic, because there's nothing that says that the
vendor IE must have OUI + type + subtype, the spec only says OUI +
vendor specific data.
This may be right for the WFA/Microsoft OUI, but not necessary anything
else?
johannes
^ permalink raw reply
* RE: [RFC] cfg80211: Implement Multiple BSSID capability in scanning
From: Peng Xu @ 2017-11-14 14:29 UTC (permalink / raw)
To: Johannes Berg, Jouni Malinen; +Cc: linux-wireless@vger.kernel.org, Sara Sharon
In-Reply-To: <1510669408.2030.23.camel@sipsolutions.net>
PiA+DQo+ID4gSXQgaXMgT1VJICsgdHlwZSArIHN1YlR5ZS4NCj4gDQo+IEFoLCByaWdodCwgdHlw
ZS9zdWJ0eXBlLg0KPiANCj4gU3RpbGwsIHRoaXMgaXMgcHJvYmxlbWF0aWMsIGJlY2F1c2UgdGhl
cmUncyBub3RoaW5nIHRoYXQgc2F5cyB0aGF0IHRoZSB2ZW5kb3IgSUUNCj4gbXVzdCBoYXZlIE9V
SSArIHR5cGUgKyBzdWJ0eXBlLCB0aGUgc3BlYyBvbmx5IHNheXMgT1VJICsgdmVuZG9yIHNwZWNp
ZmljDQo+IGRhdGEuDQo+IA0KPiBUaGlzIG1heSBiZSByaWdodCBmb3IgdGhlIFdGQS9NaWNyb3Nv
ZnQgT1VJLCBidXQgbm90IG5lY2Vzc2FyeSBhbnl0aGluZw0KPiBlbHNlPw0KPiANCg0KUmlnaHQs
IEkgb25seSBjb25zaWRlcmVkIHRoZSBtb3N0IGNvbW1vbiBjYXNlcyBzaW5jZSBJIGRpZCBub3Qg
ZmluZCBhIGdlbmVyaWMgd2F5IHRvIGNvbXBhcmUgdHdvIHZlbmRvciBlbGVtZW50cy4gQW55IHN1
Z2dlc3Rpb24/DQoNClRoYW5rcywNClBlbmcNCg==
^ permalink raw reply
* Re: [RFC] cfg80211: Implement Multiple BSSID capability in scanning
From: Johannes Berg @ 2017-11-14 14:33 UTC (permalink / raw)
To: Peng Xu, Jouni Malinen; +Cc: linux-wireless@vger.kernel.org, Sara Sharon
In-Reply-To: <929d1fdb74524aeaab4959f84a82c732@NASANEXM01F.na.qualcomm.com>
> >
> > This may be right for the WFA/Microsoft OUI, but not necessary anything
> > else?
> >
>
> Right, I only considered the most common cases since I did not find a
> generic way to compare two vendor elements. Any suggestion?
Right, not really.
I'm not even sure why this is necessary anyway though, do we really
think vendors will expect to be able to put vendor IEs inside the
subelements and override the ones outside?
Is there even any point for the WFA ones? It seems WMM really ought to
be the same for all anyway, for example.
johannes
^ permalink raw reply
* RE: [RFC] cfg80211: Implement Multiple BSSID capability in scanning
From: Peng Xu @ 2017-11-14 14:39 UTC (permalink / raw)
To: Johannes Berg, Jouni Malinen; +Cc: linux-wireless@vger.kernel.org, Sara Sharon
In-Reply-To: <1510669995.2030.26.camel@sipsolutions.net>
PiANCj4gUmlnaHQsIG5vdCByZWFsbHkuDQo+IA0KPiBJJ20gbm90IGV2ZW4gc3VyZSB3aHkgdGhp
cyBpcyBuZWNlc3NhcnkgYW55d2F5IHRob3VnaCwgZG8gd2UgcmVhbGx5IHRoaW5rDQo+IHZlbmRv
cnMgd2lsbCBleHBlY3QgdG8gYmUgYWJsZSB0byBwdXQgdmVuZG9yIElFcyBpbnNpZGUgdGhlIHN1
YmVsZW1lbnRzIGFuZA0KPiBvdmVycmlkZSB0aGUgb25lcyBvdXRzaWRlPw0KPiANCj4gSXMgdGhl
cmUgZXZlbiBhbnkgcG9pbnQgZm9yIHRoZSBXRkEgb25lcz8gSXQgc2VlbXMgV01NIHJlYWxseSBv
dWdodCB0byBiZQ0KPiB0aGUgc2FtZSBmb3IgYWxsIGFueXdheSwgZm9yIGV4YW1wbGUuDQo+IA0K
DQpJIGRvbid0IGhhdmUgYW55IHVzZSBjYXNlIGZvciBzdWNoIHNjZW5hcmlvLiBJZiB2ZW5kb3Ig
ZWxlbWVudHMgYXJlIHVubGlrZWx5IHRvDQpiZSBwcmVzZW50IGluIHN1YmVsZW1lbnQsIHRoaXMg
bG9naWMgY2FuIGJlIHJlbW92ZWQuDQoNClRoYW5rcywNClBlbmcNCg==
^ permalink raw reply
* [PATCH] mac80211: fix the update of path metric for RANN frame
From: Chun-Yeow Yeoh @ 2017-11-14 15:20 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Chun-Yeow Yeoh
The previous path metric update from RANN frame has not considered
the own link metric toward the transmitting mesh STA. Fix this.
Reported-by: Michael65535
Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@gmail.com>
---
net/mac80211/mesh_hwmp.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index c1d1b86..35ad398 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -797,7 +797,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
struct mesh_path *mpath;
u8 ttl, flags, hopcount;
const u8 *orig_addr;
- u32 orig_sn, metric, metric_txsta, interval;
+ u32 orig_sn, new_metric, orig_metric, last_hop_metric, interval;
bool root_is_gate;
ttl = rann->rann_ttl;
@@ -808,7 +808,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
interval = le32_to_cpu(rann->rann_interval);
hopcount = rann->rann_hopcount;
hopcount++;
- metric = le32_to_cpu(rann->rann_metric);
+ orig_metric = le32_to_cpu(rann->rann_metric);
/* Ignore our own RANNs */
if (ether_addr_equal(orig_addr, sdata->vif.addr))
@@ -825,7 +825,10 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
return;
}
- metric_txsta = airtime_link_metric_get(local, sta);
+ last_hop_metric = airtime_link_metric_get(local, sta);
+ new_metric = orig_metric + last_hop_metric;
+ if (new_metric < orig_metric)
+ new_metric = MAX_METRIC;
mpath = mesh_path_lookup(sdata, orig_addr);
if (!mpath) {
@@ -838,7 +841,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
}
if (!(SN_LT(mpath->sn, orig_sn)) &&
- !(mpath->sn == orig_sn && metric < mpath->rann_metric)) {
+ !(mpath->sn == orig_sn && new_metric < mpath->rann_metric)) {
rcu_read_unlock();
return;
}
@@ -856,7 +859,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
}
mpath->sn = orig_sn;
- mpath->rann_metric = metric + metric_txsta;
+ mpath->rann_metric = new_metric;
mpath->is_root = true;
/* Recording RANNs sender address to send individually
* addressed PREQs destined for root mesh STA */
@@ -876,7 +879,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
orig_sn, 0, NULL, 0, broadcast_addr,
hopcount, ttl, interval,
- metric + metric_txsta, 0, sdata);
+ new_metric, 0, sdata);
}
rcu_read_unlock();
--
2.3.0
^ permalink raw reply related
* Re: [RFC] cfg80211: Implement Multiple BSSID capability in scanning
From: Jouni Malinen @ 2017-11-14 16:31 UTC (permalink / raw)
To: Peng Xu; +Cc: Johannes Berg, linux-wireless@vger.kernel.org, Sara Sharon
In-Reply-To: <e540b35f76a447cab35f7267c09ee8f5@NASANEXM01F.na.qualcomm.com>
On Tue, Nov 14, 2017 at 02:39:31PM +0000, Peng Xu wrote:
> > I'm not even sure why this is necessary anyway though, do we really thi=
nk
> > vendors will expect to be able to put vendor IEs inside the subelements=
and
> > override the ones outside?
> >=20
> > Is there even any point for the WFA ones? It seems WMM really ought to =
be
> > the same for all anyway, for example.
>=20
> I don't have any use case for such scenario. If vendor elements are unlik=
ely to
> be present in subelement, this logic can be removed.
As far as WMM element is concerned, I'd note that IEEE 802.11 standard
does not list EDCA Parameter Set element as one of the items that has to
be same for all the BSSs in a multiple BSSID set and as such, I'd
consider it to be allowed behavior for an AP to advertise different WMM
parameters for different nontransmitted BSSIDs.
As far as other vendor specific elements are concerned, there could
certainly be use cases for using different values for WPA element,
Hotspot 2.0 element, MBO/OCE element.
--=20
Jouni Malinen PGP id EFC895FA=
^ permalink raw reply
* [PATCH] rtlwifi: rtl818x: remove redundant check for cck_power > 15
From: Colin King @ 2017-11-14 17:01 UTC (permalink / raw)
To: Hin-Tak Leung, Larry Finger, Kalle Valo, linux-wireless, netdev
Cc: kernel-janitors, linux-kernel
From: Colin Ian King <colin.king@canonical.com>
cck_poweri cannot be greated than 15 as is derived from the bottom 4 bits
from riv->channels[channel - 1].hw_value & 0xf. Hence the check for it
being greater than 15 is redundant and can be removed.
Detected by CoverityScan, CID#744303 ("Logically dead code")
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c
index e6668ffb77e6..ff0971f1e2c8 100644
--- a/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c
+++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8225.c
@@ -688,10 +688,7 @@ static void rtl8225z2_b_rf_set_tx_power(struct ieee80211_hw *dev, int channel)
cck_power = priv->channels[channel - 1].hw_value & 0xF;
ofdm_power = priv->channels[channel - 1].hw_value >> 4;
- if (cck_power > 15)
- cck_power = (priv->hw_rev == RTL8187BvB) ? 15 : 22;
- else
- cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7;
+ cck_power += (priv->hw_rev == RTL8187BvB) ? 0 : 7;
cck_power += priv->txpwr_base & 0xF;
cck_power = min(cck_power, (u8)35);
--
2.14.1
^ permalink raw reply related
* [PATCH] ath10k: Fix invalid STS_CAP_OFFSET_MASK.
From: greearb @ 2017-11-14 17:16 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless, Ben Greear
From: Ben Greear <greearb@candelatech.com>
The 10.4 firmware defines this as a 3-bit field, as does the
mac80211 stack. The 4th bit is defined as CONF_IMPLICIT_BF
at least in the firmware header I have seen. This patch
fixes the ath10k wmi header to match the firmware.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
drivers/net/wireless/ath/ath10k/wmi.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index ff15c37..9522f22 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -5195,7 +5195,8 @@ enum wmi_10_4_vdev_param {
#define WMI_VDEV_PARAM_TXBF_MU_TX_BFER BIT(3)
#define WMI_TXBF_STS_CAP_OFFSET_LSB 4
-#define WMI_TXBF_STS_CAP_OFFSET_MASK 0xf0
+#define WMI_TXBF_STS_CAP_OFFSET_MASK 0x70
+#define WMI_TXBF_CONF_IMPLICIT_BF BIT(7)
#define WMI_BF_SOUND_DIM_OFFSET_LSB 8
#define WMI_BF_SOUND_DIM_OFFSET_MASK 0xf00
--
2.4.11
^ permalink raw reply related
* RE: [RFC] cfg80211: Implement Multiple BSSID capability in scanning
From: Peng Xu @ 2017-11-14 17:38 UTC (permalink / raw)
To: Jouni Malinen; +Cc: Johannes Berg, linux-wireless@vger.kernel.org, Sara Sharon
In-Reply-To: <20171114163127.GA24453@jouni.qca.qualcomm.com>
> On Tue, Nov 14, 2017 at 02:39:31PM +0000, Peng Xu wrote:
> > > I'm not even sure why this is necessary anyway though, do we really
> > > think vendors will expect to be able to put vendor IEs inside the
> > > subelements and override the ones outside?
> > >
> > > Is there even any point for the WFA ones? It seems WMM really ought
> > > to be the same for all anyway, for example.
> >
> > I don't have any use case for such scenario. If vendor elements are
> > unlikely to be present in subelement, this logic can be removed.
>=20
> As far as WMM element is concerned, I'd note that IEEE 802.11 standard do=
es
> not list EDCA Parameter Set element as one of the items that has to be sa=
me
> for all the BSSs in a multiple BSSID set and as such, I'd consider it to =
be
> allowed behavior for an AP to advertise different WMM parameters for
> different nontransmitted BSSIDs.
>=20
> As far as other vendor specific elements are concerned, there could certa=
inly
> be use cases for using different values for WPA element, Hotspot 2.0
> element, MBO/OCE element.
>=20
Hi Jouni,
As you pointed out the use cases for having vendor elements in MBSSID subel=
ements, what is
your suggestion to identify and process the vendor elements?=20
Thanks,
Peng
^ permalink raw reply
* Re: [PATCH] mac80211: fix the update of path metric for RANN frame
From: Thomas Pedersen @ 2017-11-14 17:50 UTC (permalink / raw)
To: Chun-Yeow Yeoh; +Cc: Johannes Berg, linux-wireless
In-Reply-To: <1510672805-32594-1-git-send-email-yeohchunyeow@gmail.com>
Thanks Chun-Yeow, this is a good change.
On Tue, Nov 14, 2017 at 7:20 AM, Chun-Yeow Yeoh <yeohchunyeow@gmail.com> wrote:
> The previous path metric update from RANN frame has not considered
> the own link metric toward the transmitting mesh STA. Fix this.
>
> Reported-by: Michael65535
> Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@gmail.com>
> ---
> net/mac80211/mesh_hwmp.c | 15 +++++++++------
> 1 file changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
> index c1d1b86..35ad398 100644
> --- a/net/mac80211/mesh_hwmp.c
> +++ b/net/mac80211/mesh_hwmp.c
> @@ -797,7 +797,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
> struct mesh_path *mpath;
> u8 ttl, flags, hopcount;
> const u8 *orig_addr;
> - u32 orig_sn, metric, metric_txsta, interval;
> + u32 orig_sn, new_metric, orig_metric, last_hop_metric, interval;
> bool root_is_gate;
>
> ttl = rann->rann_ttl;
> @@ -808,7 +808,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
> interval = le32_to_cpu(rann->rann_interval);
> hopcount = rann->rann_hopcount;
> hopcount++;
> - metric = le32_to_cpu(rann->rann_metric);
> + orig_metric = le32_to_cpu(rann->rann_metric);
>
> /* Ignore our own RANNs */
> if (ether_addr_equal(orig_addr, sdata->vif.addr))
> @@ -825,7 +825,10 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
> return;
> }
>
> - metric_txsta = airtime_link_metric_get(local, sta);
> + last_hop_metric = airtime_link_metric_get(local, sta);
> + new_metric = orig_metric + last_hop_metric;
> + if (new_metric < orig_metric)
> + new_metric = MAX_METRIC;
>
> mpath = mesh_path_lookup(sdata, orig_addr);
> if (!mpath) {
> @@ -838,7 +841,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
> }
>
> if (!(SN_LT(mpath->sn, orig_sn)) &&
> - !(mpath->sn == orig_sn && metric < mpath->rann_metric)) {
> + !(mpath->sn == orig_sn && new_metric < mpath->rann_metric)) {
> rcu_read_unlock();
> return;
> }
> @@ -856,7 +859,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
> }
>
> mpath->sn = orig_sn;
> - mpath->rann_metric = metric + metric_txsta;
> + mpath->rann_metric = new_metric;
> mpath->is_root = true;
> /* Recording RANNs sender address to send individually
> * addressed PREQs destined for root mesh STA */
> @@ -876,7 +879,7 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata,
> mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr,
> orig_sn, 0, NULL, 0, broadcast_addr,
> hopcount, ttl, interval,
> - metric + metric_txsta, 0, sdata);
> + new_metric, 0, sdata);
> }
>
> rcu_read_unlock();
> --
> 2.3.0
>
--
thomas
^ permalink raw reply
* Re: [PATCH] ath10k: Fix invalid STS_CAP_OFFSET_MASK.
From: Sebastian Gottschall @ 2017-11-14 18:29 UTC (permalink / raw)
To: greearb, ath10k; +Cc: linux-wireless
In-Reply-To: <1510679819-24115-1-git-send-email-greearb@candelatech.com>
Am 14.11.2017 um 18:16 schrieb greearb@candelatech.com:
> From: Ben Greear <greearb@candelatech.com>
>
> The 10.4 firmware defines this as a 3-bit field, as does the
> mac80211 stack. The 4th bit is defined as CONF_IMPLICIT_BF
> at least in the firmware header I have seen. This patch
> fixes the ath10k wmi header to match the firmware.
>
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---
> drivers/net/wireless/ath/ath10k/wmi.h | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
> index ff15c37..9522f22 100644
> --- a/drivers/net/wireless/ath/ath10k/wmi.h
> +++ b/drivers/net/wireless/ath/ath10k/wmi.h
> @@ -5195,7 +5195,8 @@ enum wmi_10_4_vdev_param {
> #define WMI_VDEV_PARAM_TXBF_MU_TX_BFER BIT(3)
>
> #define WMI_TXBF_STS_CAP_OFFSET_LSB 4
> -#define WMI_TXBF_STS_CAP_OFFSET_MASK 0xf0
> +#define WMI_TXBF_STS_CAP_OFFSET_MASK 0x70
> +#define WMI_TXBF_CONF_IMPLICIT_BF BIT(7)
> #define WMI_BF_SOUND_DIM_OFFSET_LSB 8
> #define WMI_BF_SOUND_DIM_OFFSET_MASK 0xf00
i can validate this. good finding
>
--
Mit freundlichen Grüssen / Regards
Sebastian Gottschall / CTO
NewMedia-NET GmbH - DD-WRT
Firmensitz: Stubenwaldallee 21a, 64625 Bensheim
Registergericht: Amtsgericht Darmstadt, HRB 25473
Geschäftsführer: Peter Steinhäuser, Christian Scheele
http://www.dd-wrt.com
email: s.gottschall@dd-wrt.com
Tel.: +496251-582650 / Fax: +496251-5826565
^ permalink raw reply
* iwlwifi 8265 firmware crash vith v34 on linux 4.14
From: Thomas Backlund @ 2017-11-14 19:49 UTC (permalink / raw)
To: linux-wireless; +Cc: luciano.coelho
Running a Lenovo Yoga 720 with kernel 4.14, I pulled the:
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/linux-firmware.git
tags/iwlwifi-fw-2017-11-03
to try the new fw version 34 on my:
3f:00.0 Network controller [0280]: Intel Corporation Wireless 8265 /
8275 [8086:24fd] (rev 78)
And got this firmware crash and no wifi working:
(for reference firmware version 31.560484.0 from same git pull works)
[ 11.423208] iwlwifi 0000:3f:00.0: Error sending SCAN_REQ_UMAC: time
out after 2000ms.
[ 11.423211] iwlwifi 0000:3f:00.0: Current CMD queue read_ptr 39
write_ptr 40
[ 11.423362] iwlwifi 0000:3f:00.0: Start IWL Error Log Dump:
[ 11.423363] iwlwifi 0000:3f:00.0: Status: 0x00000100, count: 6
[ 11.423364] iwlwifi 0000:3f:00.0: Loaded firmware version: 34.0.1
[ 11.423365] iwlwifi 0000:3f:00.0: 0x00000084 | NMI_INTERRUPT_UNKNOWN
[ 11.423366] iwlwifi 0000:3f:00.0: 0x00A002F1 | trm_hw_status0
[ 11.423366] iwlwifi 0000:3f:00.0: 0x00000000 | trm_hw_status1
[ 11.423367] iwlwifi 0000:3f:00.0: 0x00023FDC | branchlink2
[ 11.423368] iwlwifi 0000:3f:00.0: 0x0003915A | interruptlink1
[ 11.423369] iwlwifi 0000:3f:00.0: 0x0003915A | interruptlink2
[ 11.423369] iwlwifi 0000:3f:00.0: 0x00000000 | data1
[ 11.423370] iwlwifi 0000:3f:00.0: 0x00000080 | data2
[ 11.423371] iwlwifi 0000:3f:00.0: 0x07830000 | data3
[ 11.423372] iwlwifi 0000:3f:00.0: 0x00201DA1 | beacon time
[ 11.423372] iwlwifi 0000:3f:00.0: 0x001FE25D | tsf low
[ 11.423373] iwlwifi 0000:3f:00.0: 0x00000000 | tsf hi
[ 11.423374] iwlwifi 0000:3f:00.0: 0x00000000 | time gp1
[ 11.423375] iwlwifi 0000:3f:00.0: 0x001FE25F | time gp2
[ 11.423375] iwlwifi 0000:3f:00.0: 0x00000001 | uCode revision type
[ 11.423376] iwlwifi 0000:3f:00.0: 0x00000022 | uCode version major
[ 11.423377] iwlwifi 0000:3f:00.0: 0x00000000 | uCode version minor
[ 11.423378] iwlwifi 0000:3f:00.0: 0x00000230 | hw version
[ 11.423378] iwlwifi 0000:3f:00.0: 0x00489000 | board version
[ 11.423379] iwlwifi 0000:3f:00.0: 0x00260128 | hcmd
[ 11.423380] iwlwifi 0000:3f:00.0: 0x00122080 | isr0
[ 11.423381] iwlwifi 0000:3f:00.0: 0x00800000 | isr1
[ 11.423381] iwlwifi 0000:3f:00.0: 0x08001802 | isr2
[ 11.423382] iwlwifi 0000:3f:00.0: 0x004000C0 | isr3
[ 11.423383] iwlwifi 0000:3f:00.0: 0x00000000 | isr4
[ 11.423383] iwlwifi 0000:3f:00.0: 0x00260128 | last cmd Id
[ 11.423384] iwlwifi 0000:3f:00.0: 0x00000000 | wait_event
[ 11.423385] iwlwifi 0000:3f:00.0: 0x0000DFF7 | l2p_control
[ 11.423386] iwlwifi 0000:3f:00.0: 0x00000820 | l2p_duration
[ 11.423386] iwlwifi 0000:3f:00.0: 0x00000000 | l2p_mhvalid
[ 11.423387] iwlwifi 0000:3f:00.0: 0x00000000 | l2p_addr_match
[ 11.423388] iwlwifi 0000:3f:00.0: 0x0000000D | lmpm_pmg_sel
[ 11.423389] iwlwifi 0000:3f:00.0: 0x30101345 | timestamp
[ 11.423389] iwlwifi 0000:3f:00.0: 0x00342030 | flow_handler
[ 11.423455] iwlwifi 0000:3f:00.0: 0x00000000 | ADVANCED_SYSASSERT
[ 11.423456] iwlwifi 0000:3f:00.0: 0x00000000 | umac branchlink1
[ 11.423457] iwlwifi 0000:3f:00.0: 0x00000000 | umac branchlink2
[ 11.423457] iwlwifi 0000:3f:00.0: 0x00000000 | umac interruptlink1
[ 11.423458] iwlwifi 0000:3f:00.0: 0x00000000 | umac interruptlink2
[ 11.423459] iwlwifi 0000:3f:00.0: 0x00000000 | umac data1
[ 11.423460] iwlwifi 0000:3f:00.0: 0x00000000 | umac data2
[ 11.423460] iwlwifi 0000:3f:00.0: 0x00000000 | umac data3
[ 11.423461] iwlwifi 0000:3f:00.0: 0x00000000 | umac major
[ 11.423462] iwlwifi 0000:3f:00.0: 0x00000000 | umac minor
[ 11.423462] iwlwifi 0000:3f:00.0: 0x00000000 | frame pointer
[ 11.423463] iwlwifi 0000:3f:00.0: 0x00000000 | stack pointer
[ 11.423464] iwlwifi 0000:3f:00.0: 0x00000000 | last host cmd
[ 11.423465] iwlwifi 0000:3f:00.0: 0x00000000 | isr status reg
[ 11.423469] ieee80211 phy0: Hardware restart was requested
[ 11.423472] iwlwifi 0000:3f:00.0: Scan failed! ret -110
[ 11.423481] iwlwifi 0000:3f:00.0: Microcode SW error detected.
Restarting 0x2000000.
[ 15.007405] iwlwifi 0000:3f:00.0: Error sending SCAN_REQ_UMAC: time
out after 2000ms.
[ 15.007407] iwlwifi 0000:3f:00.0: Current CMD queue read_ptr 42
write_ptr 43
[ 15.007507] iwlwifi 0000:3f:00.0: Microcode SW error detected.
Restarting 0x2000000.
[ 15.007559] iwlwifi 0000:3f:00.0: Start IWL Error Log Dump:
[ 15.007560] iwlwifi 0000:3f:00.0: Status: 0x00000100, count: 6
[ 15.007561] iwlwifi 0000:3f:00.0: Loaded firmware version: 34.0.1
[ 15.007562] iwlwifi 0000:3f:00.0: 0x00000084 | NMI_INTERRUPT_UNKNOWN
[ 15.007563] iwlwifi 0000:3f:00.0: 0x000002F0 | trm_hw_status0
[ 15.007564] iwlwifi 0000:3f:00.0: 0x00000000 | trm_hw_status1
[ 15.007564] iwlwifi 0000:3f:00.0: 0x00023FDC | branchlink2
[ 15.007565] iwlwifi 0000:3f:00.0: 0x0003915A | interruptlink1
[ 15.007566] iwlwifi 0000:3f:00.0: 0x0003915A | interruptlink2
[ 15.007567] iwlwifi 0000:3f:00.0: 0x00000000 | data1
[ 15.007567] iwlwifi 0000:3f:00.0: 0x00000080 | data2
[ 15.007568] iwlwifi 0000:3f:00.0: 0x07830000 | data3
[ 15.007569] iwlwifi 0000:3f:00.0: 0x00194F47 | beacon time
[ 15.007570] iwlwifi 0000:3f:00.0: 0x002C9934 | tsf low
[ 15.007570] iwlwifi 0000:3f:00.0: 0x00000000 | tsf hi
[ 15.007571] iwlwifi 0000:3f:00.0: 0x00000000 | time gp1
[ 15.007572] iwlwifi 0000:3f:00.0: 0x002C9935 | time gp2
[ 15.007573] iwlwifi 0000:3f:00.0: 0x00000001 | uCode revision type
[ 15.007573] iwlwifi 0000:3f:00.0: 0x00000022 | uCode version major
[ 15.007574] iwlwifi 0000:3f:00.0: 0x00000000 | uCode version minor
[ 15.007575] iwlwifi 0000:3f:00.0: 0x00000230 | hw version
[ 15.007576] iwlwifi 0000:3f:00.0: 0x00489000 | board version
[ 15.007576] iwlwifi 0000:3f:00.0: 0x0029012C | hcmd
[ 15.007577] iwlwifi 0000:3f:00.0: 0x00022080 | isr0
[ 15.007578] iwlwifi 0000:3f:00.0: 0x00800000 | isr1
[ 15.007579] iwlwifi 0000:3f:00.0: 0x08001802 | isr2
[ 15.007579] iwlwifi 0000:3f:00.0: 0x00400080 | isr3
[ 15.007580] iwlwifi 0000:3f:00.0: 0x00000000 | isr4
[ 15.007581] iwlwifi 0000:3f:00.0: 0x0029012C | last cmd Id
[ 15.007582] iwlwifi 0000:3f:00.0: 0x00000000 | wait_event
[ 15.007582] iwlwifi 0000:3f:00.0: 0x0000DFF7 | l2p_control
[ 15.007583] iwlwifi 0000:3f:00.0: 0x00000020 | l2p_duration
[ 15.007584] iwlwifi 0000:3f:00.0: 0x00000000 | l2p_mhvalid
[ 15.007584] iwlwifi 0000:3f:00.0: 0x00000000 | l2p_addr_match
[ 15.007585] iwlwifi 0000:3f:00.0: 0x0000008F | lmpm_pmg_sel
[ 15.007586] iwlwifi 0000:3f:00.0: 0x30101345 | timestamp
[ 15.007587] iwlwifi 0000:3f:00.0: 0x00342030 | flow_handler
[ 15.007653] iwlwifi 0000:3f:00.0: 0x00000000 | ADVANCED_SYSASSERT
[ 15.007654] iwlwifi 0000:3f:00.0: 0x00000000 | umac branchlink1
[ 15.007655] iwlwifi 0000:3f:00.0: 0x00000000 | umac branchlink2
[ 15.007656] iwlwifi 0000:3f:00.0: 0x00000000 | umac interruptlink1
[ 15.007656] iwlwifi 0000:3f:00.0: 0x00000000 | umac interruptlink2
[ 15.007657] iwlwifi 0000:3f:00.0: 0x00000000 | umac data1
[ 15.007658] iwlwifi 0000:3f:00.0: 0x00000000 | umac data2
[ 15.007659] iwlwifi 0000:3f:00.0: 0x00000000 | umac data3
[ 15.007659] iwlwifi 0000:3f:00.0: 0x00000000 | umac major
[ 15.007660] iwlwifi 0000:3f:00.0: 0x00000000 | umac minor
[ 15.007661] iwlwifi 0000:3f:00.0: 0x00000000 | frame pointer
[ 15.007662] iwlwifi 0000:3f:00.0: 0x00000000 | stack pointer
[ 15.007662] iwlwifi 0000:3f:00.0: 0x00000000 | last host cmd
[ 15.007663] iwlwifi 0000:3f:00.0: 0x00000000 | isr status reg
[ 15.007668] ieee80211 phy0: Hardware restart was requested
[ 15.007671] iwlwifi 0000:3f:00.0: Scan failed! ret -110
Any other info you need / want ?
^ permalink raw reply
* Re: iwlwifi 8265 firmware crash vith v34 on linux 4.14
From: Luciano Coelho @ 2017-11-14 20:04 UTC (permalink / raw)
To: Thomas Backlund, linux-wireless
In-Reply-To: <b533ecc1-c4ce-b0fc-b7fb-b7beceb1f1cf@mageia.org>
Hi Thomas,
On Tue, 2017-11-14 at 21:49 +0200, Thomas Backlund wrote:
> Running a Lenovo Yoga 720 with kernel 4.14, I pulled the:
> git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/linux-
> firmware.git
> tags/iwlwifi-fw-2017-11-03
>
> to try the new fw version 34 on my:
> 3f:00.0 Network controller [0280]: Intel Corporation Wireless 8265 /
> 8275 [8086:24fd] (rev 78)
>
> And got this firmware crash and no wifi working:
> (for reference firmware version 31.560484.0 from same git pull works)
>
>
> [ 11.423208] iwlwifi 0000:3f:00.0: Error sending SCAN_REQ_UMAC:
> time out after 2000ms.
Yes, this was a screw up on my side regarding the FW API. We have a
bugzilla and a patch to fix it already (on my comment #6):
https://bugzilla.kernel.org/show_bug.cgi?id=197591#c6
I'll try to get this into the first stable release for 4.14.
Sorry for the trouble and thanks for reporting!
--
Cheers,
Luca.
^ 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