* [PATCH 19/21] wil6210: add support for ucode tracing
From: Maya Erez @ 2019-02-22 14:21 UTC (permalink / raw)
To: Kalle Valo; +Cc: Ahmad Masri, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1550845279-16103-1-git-send-email-merez@codeaurora.org>
From: Ahmad Masri <amasri@codeaurora.org>
The driver needs to expose RGF_USER_USAGE_2 register that contains
the offset of the ucode logging table.
Signed-off-by: Ahmad Masri <amasri@codeaurora.org>
Signed-off-by: Maya Erez <merez@codeaurora.org>
---
drivers/net/wireless/ath/wil6210/debugfs.c | 1 +
drivers/net/wireless/ath/wil6210/wil6210.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 817762f..78320ec 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -2392,6 +2392,7 @@ static void wil6210_debugfs_init_isr(struct wil6210_priv *wil,
{"RGF_MAC_MTRL_COUNTER_0", 0444, HOSTADDR(RGF_MAC_MTRL_COUNTER_0),
doff_io32},
{"RGF_USER_USAGE_1", 0444, HOSTADDR(RGF_USER_USAGE_1), doff_io32},
+ {"RGF_USER_USAGE_2", 0444, HOSTADDR(RGF_USER_USAGE_2), doff_io32},
{},
};
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 9d7e02e..f508d52 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -185,6 +185,7 @@ struct RGF_ICR {
/* registers - FW addresses */
#define RGF_USER_USAGE_1 (0x880004)
+#define RGF_USER_USAGE_2 (0x880008)
#define RGF_USER_USAGE_6 (0x880018)
#define BIT_USER_OOB_MODE BIT(31)
#define BIT_USER_OOB_R2_MODE BIT(30)
--
1.9.1
^ permalink raw reply related
* [PATCH 17/21] wil6210: fix return code of wmi_mgmt_tx and wmi_mgmt_tx_ext
From: Maya Erez @ 2019-02-22 14:21 UTC (permalink / raw)
To: Kalle Valo; +Cc: Lior David, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1550845279-16103-1-git-send-email-merez@codeaurora.org>
From: Lior David <liord@codeaurora.org>
The functions that send management TX frame have 3 possible
results: success and other side acknowledged receive (ACK=1),
success and other side did not acknowledge receive(ACK=0) and
failure to send the frame. The current implementation
incorrectly reports the ACK=0 case as failure.
Signed-off-by: Lior David <liord@codeaurora.org>
Signed-off-by: Maya Erez <merez@codeaurora.org>
---
drivers/net/wireless/ath/wil6210/cfg80211.c | 5 +++++
drivers/net/wireless/ath/wil6210/wmi.c | 11 ++++++-----
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index e8d65dd..218296e 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -1274,7 +1274,12 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
params->wait);
out:
+ /* when the sent packet was not acked by receiver(ACK=0), rc will
+ * be -EAGAIN. In this case this function needs to return success,
+ * the ACK=0 will be reflected in tx_status.
+ */
tx_status = (rc == 0);
+ rc = (rc == -EAGAIN) ? 0 : rc;
cfg80211_mgmt_tx_status(wdev, cookie ? *cookie : 0, buf, len,
tx_status, GFP_KERNEL);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index c5bcb8d..d89cd41 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -3511,8 +3511,9 @@ int wmi_mgmt_tx(struct wil6210_vif *vif, const u8 *buf, size_t len)
rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, vif->mid, cmd, total,
WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000);
if (!rc && evt.evt.status != WMI_FW_STATUS_SUCCESS) {
- wil_err(wil, "mgmt_tx failed with status %d\n", evt.evt.status);
- rc = -EINVAL;
+ wil_dbg_wmi(wil, "mgmt_tx failed with status %d\n",
+ evt.evt.status);
+ rc = -EAGAIN;
}
kfree(cmd);
@@ -3564,9 +3565,9 @@ int wmi_mgmt_tx_ext(struct wil6210_vif *vif, const u8 *buf, size_t len,
rc = wmi_call(wil, WMI_SW_TX_REQ_EXT_CMDID, vif->mid, cmd, total,
WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000);
if (!rc && evt.evt.status != WMI_FW_STATUS_SUCCESS) {
- wil_err(wil, "mgmt_tx_ext failed with status %d\n",
- evt.evt.status);
- rc = -EINVAL;
+ wil_dbg_wmi(wil, "mgmt_tx_ext failed with status %d\n",
+ evt.evt.status);
+ rc = -EAGAIN;
}
kfree(cmd);
--
1.9.1
^ permalink raw reply related
* [PATCH 15/21] wil6210: free edma_rx_swtail upon reset
From: Maya Erez @ 2019-02-22 14:21 UTC (permalink / raw)
To: Kalle Valo; +Cc: Dedy Lansky, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1550845279-16103-1-git-send-email-merez@codeaurora.org>
From: Dedy Lansky <dlansky@codeaurora.org>
edma_rx_swtail dma memory free is missing.
Add this part of Rx desc ring free.
Signed-off-by: Dedy Lansky <dlansky@codeaurora.org>
Signed-off-by: Maya Erez <merez@codeaurora.org>
---
drivers/net/wireless/ath/wil6210/txrx_edma.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c
index c387738..48098ae 100644
--- a/drivers/net/wireless/ath/wil6210/txrx_edma.c
+++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c
@@ -428,6 +428,9 @@ static void wil_ring_free_edma(struct wil6210_priv *wil, struct wil_ring *ring)
&ring->pa, ring->ctx);
wil_move_all_rx_buff_to_free_list(wil, ring);
+ dma_free_coherent(dev, sizeof(*ring->edma_rx_swtail.va),
+ ring->edma_rx_swtail.va,
+ ring->edma_rx_swtail.pa);
goto out;
}
--
1.9.1
^ permalink raw reply related
* [PATCH 11/21] wil6210: do not set BIT_USER_SUPPORT_T_POWER_ON_0 in Talyn-MB
From: Maya Erez @ 2019-02-22 14:21 UTC (permalink / raw)
To: Kalle Valo; +Cc: Maya Erez, linux-wireless, wil6210
In-Reply-To: <1550845279-16103-1-git-send-email-merez@codeaurora.org>
In Sparrow, FW might sleep long time due to T_Power_On calculation
in slow clock, so T_Power_On was set to zero to shorten the L1SS
wake-up time.
In Talyn-MB the L1SS wake-up procedure is handled by the PMU (HW),
hence T_Power_On calculation is accurate and should not be forced
to zero.
Signed-off-by: Maya Erez <merez@codeaurora.org>
---
drivers/net/wireless/ath/wil6210/main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 6df19a2..f2432ad 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -1603,7 +1603,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
if (wil->hw_version == HW_VER_UNKNOWN)
return -ENODEV;
- if (test_bit(WIL_PLATFORM_CAPA_T_PWR_ON_0, wil->platform_capa)) {
+ if (test_bit(WIL_PLATFORM_CAPA_T_PWR_ON_0, wil->platform_capa) &&
+ wil->hw_version < HW_VER_TALYN_MB) {
wil_dbg_misc(wil, "Notify FW to set T_POWER_ON=0\n");
wil_s(wil, RGF_USER_USAGE_8, BIT_USER_SUPPORT_T_POWER_ON_0);
}
--
1.9.1
^ permalink raw reply related
* [PATCH 12/21] wil6210: update WIL_MCS_MAX to 15
From: Maya Erez @ 2019-02-22 14:21 UTC (permalink / raw)
To: Kalle Valo; +Cc: Maya Erez, linux-wireless, wil6210
In-Reply-To: <1550845279-16103-1-git-send-email-merez@codeaurora.org>
Update max MCS to 15, which is supported by Talyn-MB.
This will allow collecting statistics on number of RX packets
in higher MCS.
Signed-off-by: Maya Erez <merez@codeaurora.org>
---
drivers/net/wireless/ath/wil6210/wil6210.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index c417632..1b81f3f 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -569,7 +569,7 @@ struct wil_status_ring {
};
#define WIL_STA_TID_NUM (16)
-#define WIL_MCS_MAX (12) /* Maximum MCS supported */
+#define WIL_MCS_MAX (15) /* Maximum MCS supported */
struct wil_net_stats {
unsigned long rx_packets;
--
1.9.1
^ permalink raw reply related
* [PATCH 08/21] wil6210: align to latest auto generated wmi.h
From: Maya Erez @ 2019-02-22 14:21 UTC (permalink / raw)
To: Kalle Valo; +Cc: Alexei Avshalom Lazar, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1550845279-16103-1-git-send-email-merez@codeaurora.org>
From: Alexei Avshalom Lazar <ailizaro@codeaurora.org>
Align to latest version of the auto generated wmi file
describing the interface with FW.
Signed-off-by: Alexei Avshalom Lazar <ailizaro@codeaurora.org>
Signed-off-by: Maya Erez <merez@codeaurora.org>
---
drivers/net/wireless/ath/wil6210/wmi.c | 7 +++
drivers/net/wireless/ath/wil6210/wmi.h | 91 ++++++++++++++++++++++++++++++++--
2 files changed, 94 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index bda4a97..c737a79e 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -2957,6 +2957,10 @@ static const char *suspend_status2name(u8 status)
switch (status) {
case WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE:
return "LINK_NOT_IDLE";
+ case WMI_TRAFFIC_SUSPEND_REJECTED_DISCONNECT:
+ return "DISCONNECT";
+ case WMI_TRAFFIC_SUSPEND_REJECTED_OTHER:
+ return "OTHER";
default:
return "Untracked status";
}
@@ -3046,6 +3050,9 @@ static void resume_triggers2string(u32 triggers, char *string, int str_size)
if (triggers & WMI_RESUME_TRIGGER_WMI_EVT)
strlcat(string, " WMI_EVT", str_size);
+
+ if (triggers & WMI_RESUME_TRIGGER_DISCONNECT)
+ strlcat(string, " DISCONNECT", str_size);
}
int wmi_resume(struct wil6210_priv *wil)
diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h
index b668758..da46fc8 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.h
+++ b/drivers/net/wireless/ath/wil6210/wmi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2006-2012 Wilocity
*
@@ -104,6 +104,7 @@ enum wmi_fw_capability {
WMI_FW_CAPABILITY_RAW_MODE = 24,
WMI_FW_CAPABILITY_TX_REQ_EXT = 25,
WMI_FW_CAPABILITY_CHANNEL_4 = 26,
+ WMI_FW_CAPABILITY_IPA = 27,
WMI_FW_CAPABILITY_MAX,
};
@@ -294,6 +295,7 @@ enum wmi_command_id {
WMI_SET_AP_SLOT_SIZE_CMDID = 0xA0F,
WMI_SET_VRING_PRIORITY_WEIGHT_CMDID = 0xA10,
WMI_SET_VRING_PRIORITY_CMDID = 0xA11,
+ WMI_RBUFCAP_CFG_CMDID = 0xA12,
WMI_SET_MAC_ADDRESS_CMDID = 0xF003,
WMI_ABORT_SCAN_CMDID = 0xF007,
WMI_SET_PROMISCUOUS_MODE_CMDID = 0xF041,
@@ -979,10 +981,22 @@ enum wmi_rx_msg_type {
WMI_RX_MSG_TYPE_EXTENDED = 0x01,
};
+enum wmi_ring_add_irq_mode {
+ /* Backwards compatibility
+ * for DESC ring - interrupt disabled
+ * for STATUS ring - interrupt enabled
+ */
+ WMI_RING_ADD_IRQ_MODE_BWC = 0x00,
+ WMI_RING_ADD_IRQ_MODE_DISABLE = 0x01,
+ WMI_RING_ADD_IRQ_MODE_ENABLE = 0x02,
+};
+
struct wmi_tx_status_ring_add_cmd {
struct wmi_edma_ring_cfg ring_cfg;
u8 irq_index;
- u8 reserved[3];
+ /* wmi_ring_add_irq_mode */
+ u8 irq_mode;
+ u8 reserved[2];
} __packed;
struct wmi_rx_status_ring_add_cmd {
@@ -1016,7 +1030,10 @@ struct wmi_tx_desc_ring_add_cmd {
u8 mac_ctrl;
u8 to_resolution;
u8 agg_max_wsize;
- u8 reserved[3];
+ u8 irq_index;
+ /* wmi_ring_add_irq_mode */
+ u8 irq_mode;
+ u8 reserved;
struct wmi_vring_cfg_schd schd_params;
} __packed;
@@ -1982,6 +1999,7 @@ enum wmi_event_id {
WMI_BEAMFORMING_MGMT_DONE_EVENTID = 0x1836,
WMI_BF_TXSS_MGMT_DONE_EVENTID = 0x1837,
WMI_BF_RXSS_MGMT_DONE_EVENTID = 0x1839,
+ WMI_BF_TRIG_EVENTID = 0x183A,
WMI_RS_MGMT_DONE_EVENTID = 0x1852,
WMI_RF_MGMT_STATUS_EVENTID = 0x1853,
WMI_BF_SM_MGMT_DONE_EVENTID = 0x1838,
@@ -2082,6 +2100,7 @@ enum wmi_event_id {
WMI_SET_AP_SLOT_SIZE_EVENTID = 0x1A0F,
WMI_SET_VRING_PRIORITY_WEIGHT_EVENTID = 0x1A10,
WMI_SET_VRING_PRIORITY_EVENTID = 0x1A11,
+ WMI_RBUFCAP_CFG_EVENTID = 0x1A12,
WMI_SET_CHANNEL_EVENTID = 0x9000,
WMI_ASSOC_REQ_EVENTID = 0x9001,
WMI_EAPOL_RX_EVENTID = 0x9002,
@@ -2267,7 +2286,9 @@ struct wmi_notify_req_done_event {
__le32 status;
__le64 tsf;
s8 rssi;
- u8 reserved0[3];
+ /* enum wmi_edmg_tx_mode */
+ u8 tx_mode;
+ u8 reserved0[2];
__le32 tx_tpt;
__le32 tx_goodput;
__le32 rx_goodput;
@@ -2316,6 +2337,7 @@ enum wmi_disconnect_reason {
WMI_DIS_REASON_PROFILE_MISMATCH = 0x0C,
WMI_DIS_REASON_CONNECTION_EVICTED = 0x0D,
WMI_DIS_REASON_IBSS_MERGE = 0x0E,
+ WMI_DIS_REASON_HIGH_TEMPERATURE = 0x0F,
};
/* WMI_DISCONNECT_EVENTID */
@@ -3168,6 +3190,30 @@ struct wmi_brp_set_ant_limit_event {
u8 reserved[3];
} __packed;
+enum wmi_bf_type {
+ WMI_BF_TYPE_SLS = 0x00,
+ WMI_BF_TYPE_BRP_RX = 0x01,
+};
+
+/* WMI_BF_TRIG_CMDID */
+struct wmi_bf_trig_cmd {
+ /* enum wmi_bf_type - type of requested beamforming */
+ u8 bf_type;
+ /* used only for WMI_BF_TYPE_BRP_RX */
+ u8 cid;
+ /* used only for WMI_BF_TYPE_SLS */
+ u8 dst_mac[WMI_MAC_LEN];
+ u8 reserved[4];
+} __packed;
+
+/* WMI_BF_TRIG_EVENTID */
+struct wmi_bf_trig_event {
+ /* enum wmi_fw_status */
+ u8 status;
+ u8 cid;
+ u8 reserved[2];
+} __packed;
+
/* broadcast connection ID */
#define WMI_LINK_MAINTAIN_CFG_CID_BROADCAST (0xFFFFFFFF)
@@ -3263,6 +3309,8 @@ struct wmi_link_maintain_cfg_read_done_event {
enum wmi_traffic_suspend_status {
WMI_TRAFFIC_SUSPEND_APPROVED = 0x0,
WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE = 0x1,
+ WMI_TRAFFIC_SUSPEND_REJECTED_DISCONNECT = 0x2,
+ WMI_TRAFFIC_SUSPEND_REJECTED_OTHER = 0x3,
};
/* WMI_TRAFFIC_SUSPEND_EVENTID */
@@ -3282,6 +3330,7 @@ enum wmi_resume_trigger {
WMI_RESUME_TRIGGER_UCAST_RX = 0x2,
WMI_RESUME_TRIGGER_BCAST_RX = 0x4,
WMI_RESUME_TRIGGER_WMI_EVT = 0x8,
+ WMI_RESUME_TRIGGER_DISCONNECT = 0x10,
};
/* WMI_TRAFFIC_RESUME_EVENTID */
@@ -4057,4 +4106,38 @@ struct wmi_set_vring_priority_event {
u8 reserved[3];
} __packed;
+/* WMI_RADAR_PCI_CTRL_BLOCK struct */
+struct wmi_radar_pci_ctrl_block {
+ /* last fw tail address index */
+ __le32 fw_tail_index;
+ /* last SW head address index known to FW */
+ __le32 sw_head_index;
+ __le32 last_wr_pulse_tsf_low;
+ __le32 last_wr_pulse_count;
+ __le32 last_wr_in_bytes;
+ __le32 last_wr_pulse_id;
+ __le32 last_wr_burst_id;
+ /* When pre overflow detected, advance sw head in unit of pulses */
+ __le32 sw_head_inc;
+ __le32 reserved[8];
+} __packed;
+
+/* WMI_RBUFCAP_CFG_CMD */
+struct wmi_rbufcap_cfg_cmd {
+ u8 enable;
+ u8 reserved;
+ /* RBUFCAP indicates rx space unavailable when number of rx
+ * descriptors drops below this threshold. Set 0 to use system
+ * default
+ */
+ __le16 rx_desc_threshold;
+} __packed;
+
+/* WMI_RBUFCAP_CFG_EVENTID */
+struct wmi_rbufcap_cfg_event {
+ /* enum wmi_fw_status */
+ u8 status;
+ u8 reserved[3];
+} __packed;
+
#endif /* __WILOCITY_WMI_H__ */
--
1.9.1
^ permalink raw reply related
* [PATCH 09/21] wil6210: prevent device memory access while in reset or suspend
From: Maya Erez @ 2019-02-22 14:21 UTC (permalink / raw)
To: Kalle Valo; +Cc: Ahmad Masri, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1550845279-16103-1-git-send-email-merez@codeaurora.org>
From: Ahmad Masri <amasri@codeaurora.org>
Accessing some of the memory of the device while the device is
resetting or suspending may cause unexpected error as the HW is still
not in a stable state. Prevent this access to guarantee successful
read/write memory operations.
Signed-off-by: Ahmad Masri <amasri@codeaurora.org>
Signed-off-by: Maya Erez <merez@codeaurora.org>
---
drivers/net/wireless/ath/wil6210/debugfs.c | 25 +++++++++++---
drivers/net/wireless/ath/wil6210/main.c | 41 +++++++++++++++++------
drivers/net/wireless/ath/wil6210/pm.c | 29 ++++++++++------
drivers/net/wireless/ath/wil6210/wil6210.h | 5 ++-
drivers/net/wireless/ath/wil6210/wil_crash_dump.c | 18 ++++------
5 files changed, 80 insertions(+), 38 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 7ad4e53..27cb182 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -258,6 +258,11 @@ static void wil_print_mbox_ring(struct seq_file *s, const char *prefix,
wil_halp_vote(wil);
+ if (wil_mem_access_lock(wil)) {
+ wil_halp_unvote(wil);
+ return;
+ }
+
wil_memcpy_fromio_32(&r, off, sizeof(r));
wil_mbox_ring_le2cpus(&r);
/*
@@ -323,6 +328,7 @@ static void wil_print_mbox_ring(struct seq_file *s, const char *prefix,
}
out:
seq_puts(s, "}\n");
+ wil_mem_access_unlock(wil);
wil_halp_unvote(wil);
}
@@ -601,6 +607,12 @@ static int memread_show(struct seq_file *s, void *data)
if (ret < 0)
return ret;
+ ret = wil_mem_access_lock(wil);
+ if (ret) {
+ wil_pm_runtime_put(wil);
+ return ret;
+ }
+
a = wmi_buffer(wil, cpu_to_le32(mem_addr));
if (a)
@@ -608,6 +620,7 @@ static int memread_show(struct seq_file *s, void *data)
else
seq_printf(s, "[0x%08x] = INVALID\n", mem_addr);
+ wil_mem_access_unlock(wil);
wil_pm_runtime_put(wil);
return 0;
@@ -626,10 +639,6 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
size_t unaligned_bytes, aligned_count, ret;
int rc;
- if (test_bit(wil_status_suspending, wil_blob->wil->status) ||
- test_bit(wil_status_suspended, wil_blob->wil->status))
- return 0;
-
if (pos < 0)
return -EINVAL;
@@ -656,11 +665,19 @@ static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
return rc;
}
+ rc = wil_mem_access_lock(wil);
+ if (rc) {
+ kfree(buf);
+ wil_pm_runtime_put(wil);
+ return rc;
+ }
+
wil_memcpy_fromio_32(buf, (const void __iomem *)
wil_blob->blob.data + aligned_pos, aligned_count);
ret = copy_to_user(user_buf, buf + unaligned_bytes, count);
+ wil_mem_access_unlock(wil);
wil_pm_runtime_put(wil);
kfree(buf);
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 277abfd..6df19a2 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -184,6 +184,28 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
}
}
+/* Device memory access is prohibited while reset or suspend.
+ * wil_mem_access_lock protects accessing device memory in these cases
+ */
+int wil_mem_access_lock(struct wil6210_priv *wil)
+{
+ if (!down_read_trylock(&wil->mem_lock))
+ return -EBUSY;
+
+ if (test_bit(wil_status_suspending, wil->status) ||
+ test_bit(wil_status_suspended, wil->status)) {
+ up_read(&wil->mem_lock);
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+void wil_mem_access_unlock(struct wil6210_priv *wil)
+{
+ up_read(&wil->mem_lock);
+}
+
static void wil_ring_fini_tx(struct wil6210_priv *wil, int id)
{
struct wil_ring *ring = &wil->ring_tx[id];
@@ -703,6 +725,7 @@ int wil_priv_init(struct wil6210_priv *wil)
spin_lock_init(&wil->wmi_ev_lock);
spin_lock_init(&wil->net_queue_lock);
init_waitqueue_head(&wil->wq);
+ init_rwsem(&wil->mem_lock);
wil->wmi_wq = create_singlethread_workqueue(WIL_NAME "_wmi");
if (!wil->wmi_wq)
@@ -1599,15 +1622,6 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
}
set_bit(wil_status_resetting, wil->status);
- if (test_bit(wil_status_collecting_dumps, wil->status)) {
- /* Device collects crash dump, cancel the reset.
- * following crash dump collection, reset would take place.
- */
- wil_dbg_misc(wil, "reject reset while collecting crash dump\n");
- rc = -EBUSY;
- goto out;
- }
-
mutex_lock(&wil->vif_mutex);
wil_abort_scan_all_vifs(wil, false);
mutex_unlock(&wil->vif_mutex);
@@ -1782,7 +1796,9 @@ int __wil_up(struct wil6210_priv *wil)
WARN_ON(!mutex_is_locked(&wil->mutex));
+ down_write(&wil->mem_lock);
rc = wil_reset(wil, true);
+ up_write(&wil->mem_lock);
if (rc)
return rc;
@@ -1854,6 +1870,7 @@ int wil_up(struct wil6210_priv *wil)
int __wil_down(struct wil6210_priv *wil)
{
+ int rc;
WARN_ON(!mutex_is_locked(&wil->mutex));
set_bit(wil_status_resetting, wil->status);
@@ -1873,7 +1890,11 @@ int __wil_down(struct wil6210_priv *wil)
wil_abort_scan_all_vifs(wil, false);
mutex_unlock(&wil->vif_mutex);
- return wil_reset(wil, false);
+ down_write(&wil->mem_lock);
+ rc = wil_reset(wil, false);
+ up_write(&wil->mem_lock);
+
+ return rc;
}
int wil_down(struct wil6210_priv *wil)
diff --git a/drivers/net/wireless/ath/wil6210/pm.c b/drivers/net/wireless/ath/wil6210/pm.c
index 75fe932..f307522 100644
--- a/drivers/net/wireless/ath/wil6210/pm.c
+++ b/drivers/net/wireless/ath/wil6210/pm.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2014,2017 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -195,14 +195,18 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv *wil)
wil_dbg_pm(wil, "suspend keep radio on\n");
/* Prevent handling of new tx and wmi commands */
- set_bit(wil_status_suspending, wil->status);
- if (test_bit(wil_status_collecting_dumps, wil->status)) {
- /* Device collects crash dump, cancel the suspend */
- wil_dbg_pm(wil, "reject suspend while collecting crash dump\n");
- clear_bit(wil_status_suspending, wil->status);
+ rc = down_write_trylock(&wil->mem_lock);
+ if (!rc) {
+ wil_err(wil,
+ "device is busy. down_write_trylock failed, returned (0x%x)\n",
+ rc);
wil->suspend_stats.rejected_by_host++;
return -EBUSY;
}
+
+ set_bit(wil_status_suspending, wil->status);
+ up_write(&wil->mem_lock);
+
wil_pm_stop_all_net_queues(wil);
if (!wil_is_tx_idle(wil)) {
@@ -310,15 +314,18 @@ static int wil_suspend_radio_off(struct wil6210_priv *wil)
wil_dbg_pm(wil, "suspend radio off\n");
- set_bit(wil_status_suspending, wil->status);
- if (test_bit(wil_status_collecting_dumps, wil->status)) {
- /* Device collects crash dump, cancel the suspend */
- wil_dbg_pm(wil, "reject suspend while collecting crash dump\n");
- clear_bit(wil_status_suspending, wil->status);
+ rc = down_write_trylock(&wil->mem_lock);
+ if (!rc) {
+ wil_err(wil,
+ "device is busy. down_write_trylock failed, returned (0x%x)\n",
+ rc);
wil->suspend_stats.rejected_by_host++;
return -EBUSY;
}
+ set_bit(wil_status_suspending, wil->status);
+ up_write(&wil->mem_lock);
+
/* if netif up, hardware is alive, shut it down */
mutex_lock(&wil->vif_mutex);
active_ifaces = wil_has_active_ifaces(wil, true, false);
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index e1b1039b..c417632 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -660,7 +660,6 @@ enum { /* for wil6210_priv.status */
wil_status_suspending, /* suspend in progress */
wil_status_suspended, /* suspend completed, device is suspended */
wil_status_resuming, /* resume in progress */
- wil_status_collecting_dumps, /* crashdump collection in progress */
wil_status_last /* keep last */
};
@@ -992,6 +991,8 @@ struct wil6210_priv {
struct wil_txrx_ops txrx_ops;
struct mutex mutex; /* for wil6210_priv access in wil_{up|down} */
+ /* for synchronizing device memory access while reset or suspend */
+ struct rw_semaphore mem_lock;
/* statistics */
atomic_t isr_count_rx, isr_count_tx;
/* debugfs */
@@ -1176,6 +1177,8 @@ void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src,
size_t count);
void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
size_t count);
+int wil_mem_access_lock(struct wil6210_priv *wil);
+void wil_mem_access_unlock(struct wil6210_priv *wil);
struct wil6210_vif *
wil_vif_alloc(struct wil6210_priv *wil, const char *name,
diff --git a/drivers/net/wireless/ath/wil6210/wil_crash_dump.c b/drivers/net/wireless/ath/wil6210/wil_crash_dump.c
index dc33a0b..772cb00 100644
--- a/drivers/net/wireless/ath/wil6210/wil_crash_dump.c
+++ b/drivers/net/wireless/ath/wil6210/wil_crash_dump.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2015,2017 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -57,7 +57,7 @@ static int wil_fw_get_crash_dump_bounds(struct wil6210_priv *wil,
int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size)
{
- int i;
+ int i, rc;
const struct fw_map *map;
void *data;
u32 host_min, dump_size, offset, len;
@@ -73,14 +73,9 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size)
return -EINVAL;
}
- set_bit(wil_status_collecting_dumps, wil->status);
- if (test_bit(wil_status_suspending, wil->status) ||
- test_bit(wil_status_suspended, wil->status) ||
- test_bit(wil_status_resetting, wil->status)) {
- wil_err(wil, "cannot collect fw dump during suspend/reset\n");
- clear_bit(wil_status_collecting_dumps, wil->status);
- return -EINVAL;
- }
+ rc = wil_mem_access_lock(wil);
+ if (rc)
+ return rc;
/* copy to crash dump area */
for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) {
@@ -100,8 +95,7 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size)
wil_memcpy_fromio_32((void * __force)(dest + offset),
(const void __iomem * __force)data, len);
}
-
- clear_bit(wil_status_collecting_dumps, wil->status);
+ wil_mem_access_unlock(wil);
return 0;
}
--
1.9.1
^ permalink raw reply related
* [PATCH 03/21] wil6210: support up to 20 stations in AP mode
From: Maya Erez @ 2019-02-22 14:21 UTC (permalink / raw)
To: Kalle Valo; +Cc: Ahmad Masri, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1550845279-16103-1-git-send-email-merez@codeaurora.org>
From: Ahmad Masri <amasri@codeaurora.org>
New FW added support for upto 20 clients in AP mode. Change the driver
to support this as well. FW reports it's max supported associations in
WMI_READY_EVENT. Some WMI commands/events use cidxtid field which is
limited to 16 cids. Use new cid/tid fields instead.
For Rx packets cid from rx descriptor is limited to 3 bits (0..7),
to find the real cid, compare transmitter address with the stored
stations mac address in the driver sta array.
EDMA FW still supports 8 stations. Extending the support to 20
stations will come later.
Signed-off-by: Ahmad Masri <amasri@codeaurora.org>
Signed-off-by: Maya Erez <merez@codeaurora.org>
---
drivers/net/wireless/ath/wil6210/cfg80211.c | 6 +-
drivers/net/wireless/ath/wil6210/debugfs.c | 20 ++--
drivers/net/wireless/ath/wil6210/main.c | 10 +-
drivers/net/wireless/ath/wil6210/rx_reorder.c | 10 +-
drivers/net/wireless/ath/wil6210/trace.h | 3 +-
drivers/net/wireless/ath/wil6210/txrx.c | 127 +++++++++++++++++++++-----
drivers/net/wireless/ath/wil6210/txrx.h | 26 ++++++
drivers/net/wireless/ath/wil6210/txrx_edma.c | 8 +-
drivers/net/wireless/ath/wil6210/wil6210.h | 12 ++-
drivers/net/wireless/ath/wil6210/wmi.c | 79 ++++++++++++----
10 files changed, 226 insertions(+), 75 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 9b2f9f5..9a9d55b 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -395,7 +395,7 @@ static int wil_find_cid_by_idx(struct wil6210_priv *wil, u8 mid, int idx)
{
int i;
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
+ for (i = 0; i < max_assoc_sta; i++) {
if (wil->sta[i].status == wil_sta_unused)
continue;
if (wil->sta[i].mid != mid)
@@ -3007,7 +3007,7 @@ static int wil_rf_sector_set_selected(struct wiphy *wiphy,
wil, vif->mid, WMI_INVALID_RF_SECTOR_INDEX,
sector_type, WIL_CID_ALL);
if (rc == -EINVAL) {
- for (i = 0; i < WIL6210_MAX_CID; i++) {
+ for (i = 0; i < max_assoc_sta; i++) {
if (wil->sta[i].mid != vif->mid)
continue;
rc = wil_rf_sector_wmi_set_selected(
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index acbf2f0..7ad4e53 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -162,7 +162,7 @@ static int ring_show(struct seq_file *s, void *data)
snprintf(name, sizeof(name), "tx_%2d", i);
- if (cid < WIL6210_MAX_CID)
+ if (cid < max_assoc_sta)
seq_printf(s,
"\n%pM CID %d TID %d 1x%s BACK([%u] %u TU A%s) [%3d|%3d] idle %s\n",
wil->sta[cid].addr, cid, tid,
@@ -792,14 +792,14 @@ static ssize_t wil_write_back(struct file *file, const char __user *buf,
"BACK: del_rx require at least 2 params\n");
return -EINVAL;
}
- if (p1 < 0 || p1 >= WIL6210_MAX_CID) {
+ if (p1 < 0 || p1 >= max_assoc_sta) {
wil_err(wil, "BACK: invalid CID %d\n", p1);
return -EINVAL;
}
if (rc < 4)
p3 = WLAN_REASON_QSTA_LEAVE_QBSS;
sta = &wil->sta[p1];
- wmi_delba_rx(wil, sta->mid, mk_cidxtid(p1, p2), p3);
+ wmi_delba_rx(wil, sta->mid, p1, p2, p3);
} else {
wil_err(wil, "BACK: Unrecognized command \"%s\"\n", cmd);
return -EINVAL;
@@ -1243,7 +1243,7 @@ static int bf_show(struct seq_file *s, void *data)
memset(&reply, 0, sizeof(reply));
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
+ for (i = 0; i < max_assoc_sta; i++) {
u32 status;
cmd.cid = i;
@@ -1340,7 +1340,7 @@ static int link_show(struct seq_file *s, void *data)
if (!sinfo)
return -ENOMEM;
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
+ for (i = 0; i < max_assoc_sta; i++) {
struct wil_sta_info *p = &wil->sta[i];
char *status = "unknown";
struct wil6210_vif *vif;
@@ -1542,7 +1542,7 @@ static int sta_show(struct seq_file *s, void *data)
struct wil6210_priv *wil = s->private;
int i, tid, mcs;
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
+ for (i = 0; i < max_assoc_sta; i++) {
struct wil_sta_info *p = &wil->sta[i];
char *status = "unknown";
u8 aid = 0;
@@ -1651,7 +1651,7 @@ static int wil_tx_latency_debugfs_show(struct seq_file *s, void *data)
struct wil6210_priv *wil = s->private;
int i, bin;
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
+ for (i = 0; i < max_assoc_sta; i++) {
struct wil_sta_info *p = &wil->sta[i];
char *status = "unknown";
u8 aid = 0;
@@ -1740,7 +1740,7 @@ static ssize_t wil_tx_latency_write(struct file *file, const char __user *buf,
size_t sz = sizeof(u64) * WIL_NUM_LATENCY_BINS;
wil->tx_latency_res = val;
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
+ for (i = 0; i < max_assoc_sta; i++) {
struct wil_sta_info *sta = &wil->sta[i];
kfree(sta->tx_latency_bins);
@@ -1825,7 +1825,7 @@ static void wil_link_stats_debugfs_show_vif(struct wil6210_vif *vif,
}
seq_printf(s, "TSF %lld\n", vif->fw_stats_tsf);
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
+ for (i = 0; i < max_assoc_sta; i++) {
if (wil->sta[i].status == wil_sta_unused)
continue;
if (wil->sta[i].mid != vif->mid)
@@ -2440,7 +2440,7 @@ void wil6210_debugfs_remove(struct wil6210_priv *wil)
wil->debug = NULL;
kfree(wil->dbg_data.data_arr);
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++)
+ for (i = 0; i < max_assoc_sta; i++)
kfree(wil->sta[i].tx_latency_bins);
/* free pmc memory without sending command to fw, as it will
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 5b7de00..10de16a 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -219,7 +219,7 @@ static bool wil_vif_is_connected(struct wil6210_priv *wil, u8 mid)
{
int i;
- for (i = 0; i < WIL6210_MAX_CID; i++) {
+ for (i = 0; i < max_assoc_sta; i++) {
if (wil->sta[i].mid == mid &&
wil->sta[i].status == wil_sta_connected)
return true;
@@ -322,7 +322,7 @@ static void _wil6210_disconnect_complete(struct wil6210_vif *vif,
wil_disconnect_cid_complete(vif, cid, reason_code);
} else { /* all */
wil_dbg_misc(wil, "Disconnect complete all\n");
- for (cid = 0; cid < WIL6210_MAX_CID; cid++)
+ for (cid = 0; cid < max_assoc_sta; cid++)
wil_disconnect_cid_complete(vif, cid, reason_code);
}
@@ -434,7 +434,7 @@ static void _wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
wil_disconnect_cid(vif, cid, reason_code);
} else { /* all */
wil_dbg_misc(wil, "Disconnect all\n");
- for (cid = 0; cid < WIL6210_MAX_CID; cid++)
+ for (cid = 0; cid < max_assoc_sta; cid++)
wil_disconnect_cid(vif, cid, reason_code);
}
@@ -1895,7 +1895,7 @@ int wil_find_cid(struct wil6210_priv *wil, u8 mid, const u8 *mac)
int i;
int rc = -ENOENT;
- for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
+ for (i = 0; i < max_assoc_sta; i++) {
if (wil->sta[i].mid == mid &&
wil->sta[i].status != wil_sta_unused &&
ether_addr_equal(wil->sta[i].addr, mac)) {
diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c
index 983bd00..32b14fc 100644
--- a/drivers/net/wireless/ath/wil6210/rx_reorder.c
+++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -307,8 +307,8 @@ static u16 wil_agg_size(struct wil6210_priv *wil, u16 req_agg_wsize)
}
/* Block Ack - Rx side (recipient) */
-int wil_addba_rx_request(struct wil6210_priv *wil, u8 mid,
- u8 cidxtid, u8 dialog_token, __le16 ba_param_set,
+int wil_addba_rx_request(struct wil6210_priv *wil, u8 mid, u8 cid, u8 tid,
+ u8 dialog_token, __le16 ba_param_set,
__le16 ba_timeout, __le16 ba_seq_ctrl)
__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
{
@@ -316,7 +316,6 @@ int wil_addba_rx_request(struct wil6210_priv *wil, u8 mid,
u16 agg_timeout = le16_to_cpu(ba_timeout);
u16 seq_ctrl = le16_to_cpu(ba_seq_ctrl);
struct wil_sta_info *sta;
- u8 cid, tid;
u16 agg_wsize = 0;
/* bit 0: A-MSDU supported
* bit 1: policy (should be 0 for us)
@@ -335,10 +334,9 @@ int wil_addba_rx_request(struct wil6210_priv *wil, u8 mid,
int rc = 0;
might_sleep();
- parse_cidxtid(cidxtid, &cid, &tid);
/* sanity checks */
- if (cid >= WIL6210_MAX_CID) {
+ if (cid >= max_assoc_sta) {
wil_err(wil, "BACK: invalid CID %d\n", cid);
rc = -EINVAL;
goto out;
diff --git a/drivers/net/wireless/ath/wil6210/trace.h b/drivers/net/wireless/ath/wil6210/trace.h
index 853abc3..36ebfcf 100644
--- a/drivers/net/wireless/ath/wil6210/trace.h
+++ b/drivers/net/wireless/ath/wil6210/trace.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2013-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -181,7 +182,7 @@
__entry->seq = wil_rxdesc_seq(d);
__entry->mcs = wil_rxdesc_mcs(d);
),
- TP_printk("index %d len %d mid %d cid %d tid %d mcs %d seq 0x%03x"
+ TP_printk("index %d len %d mid %d cid (%%8) %d tid %d mcs %d seq 0x%03x"
" type 0x%1x subtype 0x%1x", __entry->index, __entry->len,
__entry->mid, __entry->cid, __entry->tid, __entry->mcs,
__entry->seq, __entry->type, __entry->subtype)
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index de259dc..5aa1427 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -372,6 +372,78 @@ static bool wil_is_rx_idle(struct wil6210_priv *wil)
return true;
}
+static int wil_rx_get_cid_by_skb(struct wil6210_priv *wil, struct sk_buff *skb)
+{
+ struct vring_rx_desc *d = wil_skb_rxdesc(skb);
+ int mid = wil_rxdesc_mid(d);
+ struct wil6210_vif *vif = wil->vifs[mid];
+ /* cid from DMA descriptor is limited to 3 bits.
+ * In case of cid>=8, the value would be cid modulo 8 and we need to
+ * find real cid by locating the transmitter (ta) inside sta array
+ */
+ int cid = wil_rxdesc_cid(d);
+ unsigned int snaplen = wil_rx_snaplen();
+ struct ethhdr *eth;
+ struct ieee80211_hdr_3addr *hdr;
+ int i;
+ unsigned char *ta;
+ u8 ftype;
+
+ /* in monitor mode there are no connections */
+ if (vif->wdev.iftype == NL80211_IFTYPE_MONITOR)
+ return cid;
+
+ ftype = wil_rxdesc_ftype(d) << 2;
+ if (likely(ftype == IEEE80211_FTYPE_DATA)) {
+ if (unlikely(skb->len < ETH_HLEN + snaplen)) {
+ wil_err_ratelimited(wil,
+ "Short data frame, len = %d\n",
+ skb->len);
+ return -ENOENT;
+ }
+ eth = (void *)skb->data;
+ ta = eth->h_source;
+ } else {
+ if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
+ wil_err_ratelimited(wil, "Short frame, len = %d\n",
+ skb->len);
+ return -ENOENT;
+ }
+ hdr = (void *)skb->data;
+ ta = hdr->addr2;
+ }
+
+ if (max_assoc_sta <= WIL6210_RX_DESC_MAX_CID)
+ return cid;
+
+ /* assuming no concurrency between AP interfaces and STA interfaces.
+ * multista is used only in P2P_GO or AP mode. In other modes return
+ * cid from the rx descriptor
+ */
+ if (vif->wdev.iftype != NL80211_IFTYPE_P2P_GO &&
+ vif->wdev.iftype != NL80211_IFTYPE_AP)
+ return cid;
+
+ /* For Rx packets cid from rx descriptor is limited to 3 bits (0..7),
+ * to find the real cid, compare transmitter address with the stored
+ * stations mac address in the driver sta array
+ */
+ for (i = cid; i < max_assoc_sta; i += WIL6210_RX_DESC_MAX_CID) {
+ if (wil->sta[i].status != wil_sta_unused &&
+ ether_addr_equal(wil->sta[i].addr, ta)) {
+ cid = i;
+ break;
+ }
+ }
+ if (i >= max_assoc_sta) {
+ wil_err_ratelimited(wil, "Could not find cid for frame with transmit addr = %pM, iftype = %d, frametype = %d, len = %d\n",
+ ta, vif->wdev.iftype, ftype, skb->len);
+ cid = -ENOENT;
+ }
+
+ return cid;
+}
+
/**
* reap 1 frame from @swhead
*
@@ -397,7 +469,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
int i;
struct wil_net_stats *stats;
- BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb));
+ BUILD_BUG_ON(sizeof(struct skb_rx_info) > sizeof(skb->cb));
again:
if (unlikely(wil_ring_is_empty(vring)))
@@ -429,7 +501,6 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
wil_hex_dump_txrx("RxD ", DUMP_PREFIX_NONE, 32, 4,
(const void *)d, sizeof(*d), false);
- cid = wil_rxdesc_cid(d);
mid = wil_rxdesc_mid(d);
vif = wil->vifs[mid];
@@ -440,11 +511,9 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
goto again;
}
ndev = vif_to_ndev(vif);
- stats = &wil->sta[cid].stats;
-
if (unlikely(dmalen > sz)) {
- wil_err(wil, "Rx size too large: %d bytes!\n", dmalen);
- stats->rx_large_frame++;
+ wil_err_ratelimited(wil, "Rx size too large: %d bytes!\n",
+ dmalen);
kfree_skb(skb);
goto again;
}
@@ -455,6 +524,14 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1,
skb->data, skb_headlen(skb), false);
+ cid = wil_rx_get_cid_by_skb(wil, skb);
+ if (cid == -ENOENT) {
+ kfree_skb(skb);
+ goto again;
+ }
+ wil_skb_set_cid(skb, (u8)cid);
+ stats = &wil->sta[cid].stats;
+
stats->last_mcs_rx = wil_rxdesc_mcs(d);
if (stats->last_mcs_rx < ARRAY_SIZE(stats->rx_per_mcs))
stats->rx_per_mcs[stats->last_mcs_rx]++;
@@ -501,13 +578,6 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
goto again;
}
- if (unlikely(skb->len < ETH_HLEN + snaplen)) {
- wil_err(wil, "Short frame, len = %d\n", skb->len);
- stats->rx_short_frame++;
- kfree_skb(skb);
- goto again;
- }
-
/* L4 IDENT is on when HW calculated checksum, check status
* and in case of error drop the packet
* higher stack layers will handle retransmission (if required)
@@ -604,7 +674,7 @@ int reverse_memcmp(const void *cs, const void *ct, size_t count)
static int wil_rx_crypto_check(struct wil6210_priv *wil, struct sk_buff *skb)
{
struct vring_rx_desc *d = wil_skb_rxdesc(skb);
- int cid = wil_rxdesc_cid(d);
+ int cid = wil_skb_get_cid(skb);
int tid = wil_rxdesc_tid(d);
int key_id = wil_rxdesc_key_id(d);
int mc = wil_rxdesc_mcast(d);
@@ -652,7 +722,7 @@ static void wil_get_netif_rx_params(struct sk_buff *skb, int *cid,
{
struct vring_rx_desc *d = wil_skb_rxdesc(skb);
- *cid = wil_rxdesc_cid(d); /* always 0..7, no need to check */
+ *cid = wil_skb_get_cid(skb);
*security = wil_rxdesc_security(d);
}
@@ -916,7 +986,6 @@ static int wil_vring_init_tx(struct wil6210_vif *vif, int id, int size,
.ring_size = cpu_to_le16(size),
},
.ringid = id,
- .cidxtid = mk_cidxtid(cid, tid),
.encap_trans_type = WMI_VRING_ENC_TYPE_802_3,
.mac_ctrl = 0,
.to_resolution = 0,
@@ -936,6 +1005,14 @@ static int wil_vring_init_tx(struct wil6210_vif *vif, int id, int size,
struct wil_ring *vring = &wil->ring_tx[id];
struct wil_ring_tx_data *txdata = &wil->ring_tx_data[id];
+ if (cid >= WIL6210_RX_DESC_MAX_CID) {
+ cmd.vring_cfg.cidxtid = CIDXTID_EXTENDED_CID_TID;
+ cmd.vring_cfg.cid = cid;
+ cmd.vring_cfg.tid = tid;
+ } else {
+ cmd.vring_cfg.cidxtid = mk_cidxtid(cid, tid);
+ }
+
wil_dbg_misc(wil, "vring_init_tx: max_mpdu_size %d\n",
cmd.vring_cfg.tx_sw_ring.max_mpdu_size);
lockdep_assert_held(&wil->mutex);
@@ -988,7 +1065,7 @@ static int wil_vring_init_tx(struct wil6210_vif *vif, int id, int size,
txdata->enabled = 0;
spin_unlock_bh(&txdata->lock);
wil_vring_free(wil, vring);
- wil->ring2cid_tid[id][0] = WIL6210_MAX_CID;
+ wil->ring2cid_tid[id][0] = max_assoc_sta;
wil->ring2cid_tid[id][1] = 0;
out:
@@ -1073,7 +1150,7 @@ static int wil_tx_vring_modify(struct wil6210_vif *vif, int ring_id, int cid,
txdata->dot1x_open = false;
txdata->enabled = 0;
spin_unlock_bh(&txdata->lock);
- wil->ring2cid_tid[ring_id][0] = WIL6210_MAX_CID;
+ wil->ring2cid_tid[ring_id][0] = max_assoc_sta;
wil->ring2cid_tid[ring_id][1] = 0;
return rc;
}
@@ -1120,7 +1197,7 @@ int wil_vring_init_bcast(struct wil6210_vif *vif, int id, int size)
if (rc)
goto out;
- wil->ring2cid_tid[id][0] = WIL6210_MAX_CID; /* CID */
+ wil->ring2cid_tid[id][0] = max_assoc_sta; /* CID */
wil->ring2cid_tid[id][1] = 0; /* TID */
cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa);
@@ -1167,7 +1244,7 @@ static struct wil_ring *wil_find_tx_ucast(struct wil6210_priv *wil,
int cid = wil_find_cid(wil, vif->mid, eth->h_dest);
int min_ring_id = wil_get_min_tx_ring_id(wil);
- if (cid < 0)
+ if (cid < 0 || cid >= max_assoc_sta)
return NULL;
/* TODO: fix for multiple TID */
@@ -1219,7 +1296,7 @@ static struct wil_ring *wil_find_tx_ring_sta(struct wil6210_priv *wil,
continue;
cid = wil->ring2cid_tid[i][0];
- if (cid >= WIL6210_MAX_CID) /* skip BCAST */
+ if (cid >= max_assoc_sta) /* skip BCAST */
continue;
if (!wil->ring_tx_data[i].dot1x_open &&
@@ -1298,7 +1375,7 @@ static struct wil_ring *wil_find_tx_bcast_2(struct wil6210_priv *wil,
continue;
cid = wil->ring2cid_tid[i][0];
- if (cid >= WIL6210_MAX_CID) /* skip BCAST */
+ if (cid >= max_assoc_sta) /* skip BCAST */
continue;
if (!wil->ring_tx_data[i].dot1x_open &&
skb->protocol != cpu_to_be16(ETH_P_PAE))
@@ -1326,7 +1403,7 @@ static struct wil_ring *wil_find_tx_bcast_2(struct wil6210_priv *wil,
if (!v2->va || txdata2->mid != vif->mid)
continue;
cid = wil->ring2cid_tid[i][0];
- if (cid >= WIL6210_MAX_CID) /* skip BCAST */
+ if (cid >= max_assoc_sta) /* skip BCAST */
continue;
if (!wil->ring_tx_data[i].dot1x_open &&
skb->protocol != cpu_to_be16(ETH_P_PAE))
@@ -2179,7 +2256,7 @@ int wil_tx_complete(struct wil6210_vif *vif, int ringid)
used_before_complete = wil_ring_used_tx(vring);
- if (cid < WIL6210_MAX_CID)
+ if (cid < max_assoc_sta)
stats = &wil->sta[cid].stats;
while (!wil_ring_is_empty(vring)) {
@@ -2288,7 +2365,7 @@ static void wil_get_reorder_params(struct wil6210_priv *wil,
struct vring_rx_desc *d = wil_skb_rxdesc(skb);
*tid = wil_rxdesc_tid(d);
- *cid = wil_rxdesc_cid(d);
+ *cid = wil_skb_get_cid(skb);
*mid = wil_rxdesc_mid(d);
*seq = wil_rxdesc_seq(d);
*mcast = wil_rxdesc_mcast(d);
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
index bc81444..1aec04d 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/drivers/net/wireless/ath/wil6210/txrx.h
@@ -458,6 +458,18 @@ struct vring_rx_desc {
union wil_rx_desc rx;
} __packed;
+struct packet_rx_info {
+ u8 cid;
+};
+
+/* this struct will be stored in the skb cb buffer
+ * max length of the struct is limited to 48 bytes
+ */
+struct skb_rx_info {
+ struct vring_rx_desc rx_desc;
+ struct packet_rx_info rx_info;
+};
+
static inline int wil_rxdesc_tid(struct vring_rx_desc *d)
{
return WIL_GET_BITS(d->mac.d0, 0, 3);
@@ -605,6 +617,20 @@ static inline bool wil_val_in_range(int val, int min, int max)
return val >= min && val < max;
}
+static inline u8 wil_skb_get_cid(struct sk_buff *skb)
+{
+ struct skb_rx_info *skb_rx_info = (void *)skb->cb;
+
+ return skb_rx_info->rx_info.cid;
+}
+
+static inline void wil_skb_set_cid(struct sk_buff *skb, u8 cid)
+{
+ struct skb_rx_info *skb_rx_info = (void *)skb->cb;
+
+ skb_rx_info->rx_info.cid = cid;
+}
+
void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev);
void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb);
void wil_rx_bar(struct wil6210_priv *wil, struct wil6210_vif *vif,
diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c
index 3380aae..c09cd69 100644
--- a/drivers/net/wireless/ath/wil6210/txrx_edma.c
+++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -727,7 +727,7 @@ static int wil_ring_init_tx_edma(struct wil6210_vif *vif, int ring_id,
txdata->enabled = 0;
spin_unlock_bh(&txdata->lock);
wil_ring_free_edma(wil, ring);
- wil->ring2cid_tid[ring_id][0] = WIL6210_MAX_CID;
+ wil->ring2cid_tid[ring_id][0] = max_assoc_sta;
wil->ring2cid_tid[ring_id][1] = 0;
out:
@@ -932,7 +932,7 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil,
eop = wil_rx_status_get_eop(msg);
cid = wil_rx_status_get_cid(msg);
- if (unlikely(!wil_val_in_range(cid, 0, WIL6210_MAX_CID))) {
+ if (unlikely(!wil_val_in_range(cid, 0, max_assoc_sta))) {
wil_err(wil, "Corrupt cid=%d, sring->swhead=%d\n",
cid, sring->swhead);
rxdata->skipping = true;
@@ -1187,7 +1187,7 @@ int wil_tx_sring_handler(struct wil6210_priv *wil,
ndev = vif_to_ndev(vif);
cid = wil->ring2cid_tid[ring_id][0];
- if (cid < WIL6210_MAX_CID)
+ if (cid < max_assoc_sta)
stats = &wil->sta[cid].stats;
wil_dbg_txrx(wil,
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index ba833ac..85dca1b 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -39,6 +39,7 @@
extern bool disable_ap_sme;
extern bool ftm_mode;
extern bool drop_if_ring_full;
+extern uint max_assoc_sta;
struct wil6210_priv;
struct wil6210_vif;
@@ -90,7 +91,8 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
#define WIL_RING_SIZE_ORDER_MIN (5)
#define WIL_RING_SIZE_ORDER_MAX (15)
#define WIL6210_MAX_TX_RINGS (24) /* HW limit */
-#define WIL6210_MAX_CID (8) /* HW limit */
+#define WIL6210_MAX_CID (20) /* max number of stations */
+#define WIL6210_RX_DESC_MAX_CID (8) /* HW limit */
#define WIL6210_NAPI_BUDGET (16) /* arbitrary */
#define WIL_MAX_AMPDU_SIZE (64 * 1024) /* FW/HW limit */
#define WIL_MAX_AGG_WSIZE (32) /* FW/HW limit */
@@ -458,7 +460,7 @@ static inline void parse_cidxtid(u8 cidxtid, u8 *cid, u8 *tid)
*/
static inline bool wil_cid_valid(u8 cid)
{
- return cid < WIL6210_MAX_CID;
+ return (cid >= 0 && cid < max_assoc_sta);
}
struct wil6210_mbox_ring {
@@ -1236,7 +1238,7 @@ int wmi_disconnect_sta(struct wil6210_vif *vif, const u8 *mac, u16 reason,
int wmi_addba(struct wil6210_priv *wil, u8 mid,
u8 ringid, u8 size, u16 timeout);
int wmi_delba_tx(struct wil6210_priv *wil, u8 mid, u8 ringid, u16 reason);
-int wmi_delba_rx(struct wil6210_priv *wil, u8 mid, u8 cidxtid, u16 reason);
+int wmi_delba_rx(struct wil6210_priv *wil, u8 mid, u8 cid, u8 tid, u16 reason);
int wmi_addba_rx_resp(struct wil6210_priv *wil,
u8 mid, u8 cid, u8 tid, u8 token,
u16 status, bool amsdu, u16 agg_wsize, u16 timeout);
@@ -1249,8 +1251,8 @@ int wmi_port_allocate(struct wil6210_priv *wil, u8 mid,
const u8 *mac, enum nl80211_iftype iftype);
int wmi_port_delete(struct wil6210_priv *wil, u8 mid);
int wmi_link_stats_cfg(struct wil6210_vif *vif, u32 type, u8 cid, u32 interval);
-int wil_addba_rx_request(struct wil6210_priv *wil, u8 mid,
- u8 cidxtid, u8 dialog_token, __le16 ba_param_set,
+int wil_addba_rx_request(struct wil6210_priv *wil, u8 mid, u8 cid, u8 tid,
+ u8 dialog_token, __le16 ba_param_set,
__le16 ba_timeout, __le16 ba_seq_ctrl);
int wil_addba_tx_request(struct wil6210_priv *wil, u8 ringid, u16 wsize);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index b1ba519..bda4a97 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -24,8 +24,9 @@
#include "wmi.h"
#include "trace.h"
-static uint max_assoc_sta = WIL6210_MAX_CID;
-module_param(max_assoc_sta, uint, 0644);
+/* set the default max assoc sta to max supported by driver */
+uint max_assoc_sta = WIL6210_MAX_CID;
+module_param(max_assoc_sta, uint, 0444);
MODULE_PARM_DESC(max_assoc_sta, " Max number of stations associated to the AP");
int agg_wsize; /* = 0; */
@@ -770,6 +771,7 @@ static void wmi_evt_ready(struct wil6210_vif *vif, int id, void *d, int len)
struct wil6210_priv *wil = vif_to_wil(vif);
struct wiphy *wiphy = wil_to_wiphy(wil);
struct wmi_ready_event *evt = d;
+ u8 fw_max_assoc_sta;
wil_info(wil, "FW ver. %s(SW %d); MAC %pM; %d MID's\n",
wil->fw_version, le32_to_cpu(evt->sw_version),
@@ -787,6 +789,25 @@ static void wmi_evt_ready(struct wil6210_vif *vif, int id, void *d, int len)
evt->rfc_read_calib_result);
wil->fw_calib_result = evt->rfc_read_calib_result;
}
+
+ fw_max_assoc_sta = WIL6210_RX_DESC_MAX_CID;
+ if (len > offsetof(struct wmi_ready_event, max_assoc_sta) &&
+ evt->max_assoc_sta > 0) {
+ fw_max_assoc_sta = evt->max_assoc_sta;
+ wil_dbg_wmi(wil, "fw reported max assoc sta %d\n",
+ fw_max_assoc_sta);
+
+ if (fw_max_assoc_sta > WIL6210_MAX_CID) {
+ wil_dbg_wmi(wil,
+ "fw max assoc sta %d exceeds max driver supported %d\n",
+ fw_max_assoc_sta, WIL6210_MAX_CID);
+ fw_max_assoc_sta = WIL6210_MAX_CID;
+ }
+ }
+
+ max_assoc_sta = min_t(uint, max_assoc_sta, fw_max_assoc_sta);
+ wil_dbg_wmi(wil, "setting max assoc sta to %d\n", max_assoc_sta);
+
wil_set_recovery_state(wil, fw_recovery_idle);
set_bit(wil_status_fwready, wil->status);
/* let the reset sequence continue */
@@ -952,7 +973,7 @@ static void wmi_evt_connect(struct wil6210_vif *vif, int id, void *d, int len)
evt->assoc_req_len, evt->assoc_resp_len);
return;
}
- if (evt->cid >= WIL6210_MAX_CID) {
+ if (evt->cid >= max_assoc_sta) {
wil_err(wil, "Connect CID invalid : %d\n", evt->cid);
return;
}
@@ -1271,9 +1292,16 @@ static void wmi_evt_addba_rx_req(struct wil6210_vif *vif, int id,
void *d, int len)
{
struct wil6210_priv *wil = vif_to_wil(vif);
+ u8 cid, tid;
struct wmi_rcp_addba_req_event *evt = d;
- wil_addba_rx_request(wil, vif->mid, evt->cidxtid, evt->dialog_token,
+ if (evt->cidxtid != CIDXTID_EXTENDED_CID_TID) {
+ parse_cidxtid(evt->cidxtid, &cid, &tid);
+ } else {
+ cid = evt->cid;
+ tid = evt->tid;
+ }
+ wil_addba_rx_request(wil, vif->mid, cid, tid, evt->dialog_token,
evt->ba_param_set, evt->ba_timeout,
evt->ba_seq_ctrl);
}
@@ -1289,7 +1317,13 @@ static void wmi_evt_delba(struct wil6210_vif *vif, int id, void *d, int len)
struct wil_tid_ampdu_rx *r;
might_sleep();
- parse_cidxtid(evt->cidxtid, &cid, &tid);
+
+ if (evt->cidxtid != CIDXTID_EXTENDED_CID_TID) {
+ parse_cidxtid(evt->cidxtid, &cid, &tid);
+ } else {
+ cid = evt->cid;
+ tid = evt->tid;
+ }
wil_dbg_wmi(wil, "DELBA MID %d CID %d TID %d from %s reason %d\n",
vif->mid, cid, tid,
evt->from_initiator ? "originator" : "recipient",
@@ -1404,7 +1438,7 @@ static void wil_link_stats_store_basic(struct wil6210_vif *vif,
u8 cid = basic->cid;
struct wil_sta_info *sta;
- if (cid < 0 || cid >= WIL6210_MAX_CID) {
+ if (cid < 0 || cid >= max_assoc_sta) {
wil_err(wil, "invalid cid %d\n", cid);
return;
}
@@ -1554,7 +1588,7 @@ static int wil_find_cid_ringid_sta(struct wil6210_priv *wil,
continue;
lcid = wil->ring2cid_tid[i][0];
- if (lcid >= WIL6210_MAX_CID) /* skip BCAST */
+ if (lcid >= max_assoc_sta) /* skip BCAST */
continue;
wil_dbg_wmi(wil, "find sta -> ringid %d cid %d\n", i, lcid);
@@ -2120,10 +2154,9 @@ int wmi_pcp_start(struct wil6210_vif *vif,
if ((cmd.pcp_max_assoc_sta > WIL6210_MAX_CID) ||
(cmd.pcp_max_assoc_sta <= 0)) {
- wil_info(wil,
- "Requested connection limit %u, valid values are 1 - %d. Setting to %d\n",
- max_assoc_sta, WIL6210_MAX_CID, WIL6210_MAX_CID);
- cmd.pcp_max_assoc_sta = WIL6210_MAX_CID;
+ wil_err(wil, "unexpected max_assoc_sta %d\n",
+ cmd.pcp_max_assoc_sta);
+ return -EOPNOTSUPP;
}
if (disable_ap_sme &&
@@ -2651,15 +2684,22 @@ int wmi_delba_tx(struct wil6210_priv *wil, u8 mid, u8 ringid, u16 reason)
return wmi_send(wil, WMI_RING_BA_DIS_CMDID, mid, &cmd, sizeof(cmd));
}
-int wmi_delba_rx(struct wil6210_priv *wil, u8 mid, u8 cidxtid, u16 reason)
+int wmi_delba_rx(struct wil6210_priv *wil, u8 mid, u8 cid, u8 tid, u16 reason)
{
struct wmi_rcp_delba_cmd cmd = {
- .cidxtid = cidxtid,
.reason = cpu_to_le16(reason),
};
- wil_dbg_wmi(wil, "delba_rx: (CID %d TID %d reason %d)\n", cidxtid & 0xf,
- (cidxtid >> 4) & 0xf, reason);
+ if (cid >= WIL6210_RX_DESC_MAX_CID) {
+ cmd.cidxtid = CIDXTID_EXTENDED_CID_TID;
+ cmd.cid = cid;
+ cmd.tid = tid;
+ } else {
+ cmd.cidxtid = mk_cidxtid(cid, tid);
+ }
+
+ wil_dbg_wmi(wil, "delba_rx: (CID %d TID %d reason %d)\n", cid,
+ tid, reason);
return wmi_send(wil, WMI_RCP_DELBA_CMDID, mid, &cmd, sizeof(cmd));
}
@@ -2670,7 +2710,6 @@ int wmi_addba_rx_resp(struct wil6210_priv *wil,
{
int rc;
struct wmi_rcp_addba_resp_cmd cmd = {
- .cidxtid = mk_cidxtid(cid, tid),
.dialog_token = token,
.status_code = cpu_to_le16(status),
/* bit 0: A-MSDU supported
@@ -2689,6 +2728,14 @@ int wmi_addba_rx_resp(struct wil6210_priv *wil,
.evt = {.status = cpu_to_le16(WMI_FW_STATUS_FAILURE)},
};
+ if (cid >= WIL6210_RX_DESC_MAX_CID) {
+ cmd.cidxtid = CIDXTID_EXTENDED_CID_TID;
+ cmd.cid = cid;
+ cmd.tid = tid;
+ } else {
+ cmd.cidxtid = mk_cidxtid(cid, tid);
+ }
+
wil_dbg_wmi(wil,
"ADDBA response for MID %d CID %d TID %d size %d timeout %d status %d AMSDU%s\n",
mid, cid, tid, agg_wsize,
--
1.9.1
^ permalink raw reply related
* [PATCH 06/21] wil6210: ignore HALP ICR if already handled
From: Maya Erez @ 2019-02-22 14:21 UTC (permalink / raw)
To: Kalle Valo; +Cc: Maya Erez, linux-wireless, wil6210
In-Reply-To: <1550845279-16103-1-git-send-email-merez@codeaurora.org>
HALP ICR is set as long as the FW should stay awake.
To prevent its multiple handling the driver masks this IRQ bit.
However, if there is a different MISC ICR before the driver clears
this bit, there is a risk of race condition between HALP mask and
unmask. This race leads to HALP timeout, in case it is mistakenly
masked.
Add an atomic flag to indicate if HALP ICR should be handled.
Signed-off-by: Maya Erez <merez@codeaurora.org>
---
drivers/net/wireless/ath/wil6210/interrupt.c | 12 ++++++++----
drivers/net/wireless/ath/wil6210/main.c | 3 +++
drivers/net/wireless/ath/wil6210/wil6210.h | 1 +
3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index 5d287a8..3f5bd17 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -575,10 +575,14 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
}
if (isr & BIT_DMA_EP_MISC_ICR_HALP) {
- wil_dbg_irq(wil, "irq_misc: HALP IRQ invoked\n");
- wil6210_mask_halp(wil);
isr &= ~BIT_DMA_EP_MISC_ICR_HALP;
- complete(&wil->halp.comp);
+ if (wil->halp.handle_icr) {
+ /* no need to handle HALP ICRs until next vote */
+ wil->halp.handle_icr = false;
+ wil_dbg_irq(wil, "irq_misc: HALP IRQ invoked\n");
+ wil6210_mask_halp(wil);
+ complete(&wil->halp.comp);
+ }
}
wil->isr_misc = isr;
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 10de16a..277abfd 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -1919,11 +1919,14 @@ void wil_halp_vote(struct wil6210_priv *wil)
if (++wil->halp.ref_cnt == 1) {
reinit_completion(&wil->halp.comp);
+ /* mark to IRQ context to handle HALP ICR */
+ wil->halp.handle_icr = true;
wil6210_set_halp(wil);
rc = wait_for_completion_timeout(&wil->halp.comp, to_jiffies);
if (!rc) {
wil_err(wil, "HALP vote timed out\n");
/* Mask HALP as done in case the interrupt is raised */
+ wil->halp.handle_icr = false;
wil6210_mask_halp(wil);
} else {
wil_dbg_irq(wil,
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 85dca1b..e1b1039b 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -794,6 +794,7 @@ struct wil_halp {
struct mutex lock; /* protect halp ref_cnt */
unsigned int ref_cnt;
struct completion comp;
+ u8 handle_icr;
};
struct wil_blob_wrapper {
--
1.9.1
^ permalink raw reply related
* [PATCH 04/21] wil6210: accessing 802.3 addresses via utility functions
From: Maya Erez @ 2019-02-22 14:21 UTC (permalink / raw)
To: Kalle Valo; +Cc: Ahmad Masri, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1550845279-16103-1-git-send-email-merez@codeaurora.org>
From: Ahmad Masri <amasri@codeaurora.org>
Rearrange the code by having functions to access 802.3 header
members, source and destination addresses.
Signed-off-by: Ahmad Masri <amasri@codeaurora.org>
Signed-off-by: Maya Erez <merez@codeaurora.org>
---
drivers/net/wireless/ath/wil6210/txrx.c | 36 ++++++++++++++++-----------------
drivers/net/wireless/ath/wil6210/txrx.h | 18 +++++++++++++++--
2 files changed, 33 insertions(+), 21 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 5aa1427..4ccfd14 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -383,7 +383,6 @@ static int wil_rx_get_cid_by_skb(struct wil6210_priv *wil, struct sk_buff *skb)
*/
int cid = wil_rxdesc_cid(d);
unsigned int snaplen = wil_rx_snaplen();
- struct ethhdr *eth;
struct ieee80211_hdr_3addr *hdr;
int i;
unsigned char *ta;
@@ -401,8 +400,7 @@ static int wil_rx_get_cid_by_skb(struct wil6210_priv *wil, struct sk_buff *skb)
skb->len);
return -ENOENT;
}
- eth = (void *)skb->data;
- ta = eth->h_source;
+ ta = wil_skb_get_sa(skb);
} else {
if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
wil_err_ratelimited(wil, "Short frame, len = %d\n",
@@ -739,11 +737,11 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
unsigned int len = skb->len;
int cid;
int security;
- struct ethhdr *eth = (void *)skb->data;
+ u8 *sa, *da = wil_skb_get_da(skb);
/* here looking for DA, not A1, thus Rxdesc's 'mcast' indication
* is not suitable, need to look at data
*/
- int mcast = is_multicast_ether_addr(eth->h_dest);
+ int mcast = is_multicast_ether_addr(da);
struct wil_net_stats *stats;
struct sk_buff *xmit_skb = NULL;
static const char * const gro_res_str[] = {
@@ -774,7 +772,8 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
}
if (wdev->iftype == NL80211_IFTYPE_STATION) {
- if (mcast && ether_addr_equal(eth->h_source, ndev->dev_addr)) {
+ sa = wil_skb_get_sa(skb);
+ if (mcast && ether_addr_equal(sa, ndev->dev_addr)) {
/* mcast packet looped back to us */
rc = GRO_DROP;
dev_kfree_skb(skb);
@@ -787,8 +786,7 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
*/
xmit_skb = skb_copy(skb, GFP_ATOMIC);
} else {
- int xmit_cid = wil_find_cid(wil, vif->mid,
- eth->h_dest);
+ int xmit_cid = wil_find_cid(wil, vif->mid, da);
if (xmit_cid >= 0) {
/* The destination station is associated to
@@ -1239,11 +1237,12 @@ static struct wil_ring *wil_find_tx_ucast(struct wil6210_priv *wil,
struct wil6210_vif *vif,
struct sk_buff *skb)
{
- int i;
- struct ethhdr *eth = (void *)skb->data;
- int cid = wil_find_cid(wil, vif->mid, eth->h_dest);
+ int i, cid;
+ const u8 *da = wil_skb_get_da(skb);
int min_ring_id = wil_get_min_tx_ring_id(wil);
+ cid = wil_find_cid(wil, vif->mid, da);
+
if (cid < 0 || cid >= max_assoc_sta)
return NULL;
@@ -1257,7 +1256,7 @@ static struct wil_ring *wil_find_tx_ucast(struct wil6210_priv *wil,
struct wil_ring_tx_data *txdata = &wil->ring_tx_data[i];
wil_dbg_txrx(wil, "find_tx_ucast: (%pM) -> [%d]\n",
- eth->h_dest, i);
+ da, i);
if (v->va && txdata->enabled) {
return v;
} else {
@@ -1348,10 +1347,10 @@ static struct wil_ring *wil_find_tx_bcast_1(struct wil6210_priv *wil,
static void wil_set_da_for_vring(struct wil6210_priv *wil,
struct sk_buff *skb, int vring_index)
{
- struct ethhdr *eth = (void *)skb->data;
+ u8 *da = wil_skb_get_da(skb);
int cid = wil->ring2cid_tid[vring_index][0];
- ether_addr_copy(eth->h_dest, wil->sta[cid].addr);
+ ether_addr_copy(da, wil->sta[cid].addr);
}
static struct wil_ring *wil_find_tx_bcast_2(struct wil6210_priv *wil,
@@ -1362,8 +1361,7 @@ static struct wil_ring *wil_find_tx_bcast_2(struct wil6210_priv *wil,
struct sk_buff *skb2;
int i;
u8 cid;
- struct ethhdr *eth = (void *)skb->data;
- char *src = eth->h_source;
+ const u8 *src = wil_skb_get_sa(skb);
struct wil_ring_tx_data *txdata, *txdata2;
int min_ring_id = wil_get_min_tx_ring_id(wil);
@@ -2121,8 +2119,8 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
{
struct wil6210_vif *vif = ndev_to_vif(ndev);
struct wil6210_priv *wil = vif_to_wil(vif);
- struct ethhdr *eth = (void *)skb->data;
- bool bcast = is_multicast_ether_addr(eth->h_dest);
+ const u8 *da = wil_skb_get_da(skb);
+ bool bcast = is_multicast_ether_addr(da);
struct wil_ring *ring;
static bool pr_once_fw;
int rc;
@@ -2169,7 +2167,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
ring = wil_find_tx_ucast(wil, vif, skb);
}
if (unlikely(!ring)) {
- wil_dbg_txrx(wil, "No Tx RING found for %pM\n", eth->h_dest);
+ wil_dbg_txrx(wil, "No Tx RING found for %pM\n", da);
goto drop;
}
/* set up vring entry */
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
index 1aec04d..c0da134 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/drivers/net/wireless/ath/wil6210/txrx.h
@@ -567,11 +567,25 @@ static inline int wil_ring_is_full(struct wil_ring *ring)
return wil_ring_next_tail(ring) == ring->swhead;
}
-static inline bool wil_need_txstat(struct sk_buff *skb)
+static inline u8 *wil_skb_get_da(struct sk_buff *skb)
+{
+ struct ethhdr *eth = (void *)skb->data;
+
+ return eth->h_dest;
+}
+
+static inline u8 *wil_skb_get_sa(struct sk_buff *skb)
{
struct ethhdr *eth = (void *)skb->data;
- return is_unicast_ether_addr(eth->h_dest) && skb->sk &&
+ return eth->h_source;
+}
+
+static inline bool wil_need_txstat(struct sk_buff *skb)
+{
+ const u8 *da = wil_skb_get_da(skb);
+
+ return is_unicast_ether_addr(da) && skb->sk &&
(skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS);
}
--
1.9.1
^ permalink raw reply related
* [PATCH 05/21] wil6210: fix invalid sta statistics update
From: Maya Erez @ 2019-02-22 14:21 UTC (permalink / raw)
To: Kalle Valo; +Cc: Dedy Lansky, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1550845279-16103-1-git-send-email-merez@codeaurora.org>
From: Dedy Lansky <dlansky@codeaurora.org>
Upon status ring handling, in case there are both unicast and
multicast (cid == max) status messages to handle, wrong sta statistics
might get updated.
Fix this by setting stats to NULL upon invalid cid
(e.g. == max_assoc_sta).
Signed-off-by: Dedy Lansky <dlansky@codeaurora.org>
Signed-off-by: Maya Erez <merez@codeaurora.org>
---
drivers/net/wireless/ath/wil6210/txrx_edma.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c
index c09cd69..c387738 100644
--- a/drivers/net/wireless/ath/wil6210/txrx_edma.c
+++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c
@@ -1137,7 +1137,7 @@ int wil_tx_sring_handler(struct wil6210_priv *wil,
/* Total number of completed descriptors in all descriptor rings */
int desc_cnt = 0;
int cid;
- struct wil_net_stats *stats = NULL;
+ struct wil_net_stats *stats;
struct wil_tx_enhanced_desc *_d;
unsigned int ring_id;
unsigned int num_descs;
@@ -1187,8 +1187,7 @@ int wil_tx_sring_handler(struct wil6210_priv *wil,
ndev = vif_to_ndev(vif);
cid = wil->ring2cid_tid[ring_id][0];
- if (cid < max_assoc_sta)
- stats = &wil->sta[cid].stats;
+ stats = (cid < max_assoc_sta ? &wil->sta[cid].stats : NULL);
wil_dbg_txrx(wil,
"tx_status: completed desc_ring (%d), num_descs (%d)\n",
--
1.9.1
^ permalink raw reply related
* [PATCH 02/21] wil6210: add option to drop Tx packets when Tx ring is full
From: Maya Erez @ 2019-02-22 14:21 UTC (permalink / raw)
To: Kalle Valo; +Cc: Dedy Lansky, linux-wireless, wil6210, Maya Erez
In-Reply-To: <1550845279-16103-1-git-send-email-merez@codeaurora.org>
From: Dedy Lansky <dlansky@codeaurora.org>
In AP mode with multiple clients, driver stops net queue
(netif_tx_stop_queue) upon first ring (serving specific client)
becoming full. This can have negative effect on transmission to
other clients which may still have room in their corresponding rings.
Implement new policy in which stop/wake net queue are not used. In
case there is no room in the ring for a transmitted packet, drop the
packet.
New policy can be helpful to debug performance issues, to guarantee
maximum utilization of net queues.
New policy is disabled by default and can be enabled by debugfs:
echo 1 > drop_if_ring_full
Signed-off-by: Dedy Lansky <dlansky@codeaurora.org>
Signed-off-by: Maya Erez <merez@codeaurora.org>
---
drivers/net/wireless/ath/wil6210/debugfs.c | 3 ++-
drivers/net/wireless/ath/wil6210/txrx.c | 9 +++++++++
drivers/net/wireless/ath/wil6210/wil6210.h | 3 ++-
3 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 835c902..acbf2f0 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -2386,6 +2386,7 @@ static void wil6210_debugfs_init_isr(struct wil6210_priv *wil,
{"led_polarity", 0644, (ulong)&led_polarity, doff_u8},
{"status_index", 0644, (ulong)&dbg_status_msg_index, doff_u32},
{"sring_index", 0644, (ulong)&dbg_sring_index, doff_u32},
+ {"drop_if_ring_full", 0644, (ulong)&drop_if_ring_full, doff_u8},
{},
};
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 4d286fb..de259dc 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -38,6 +38,9 @@
module_param(rx_large_buf, bool, 0444);
MODULE_PARM_DESC(rx_large_buf, " allocate 8KB RX buffers, default - no");
+/* Drop Tx packets in case Tx ring is full */
+bool drop_if_ring_full;
+
static inline uint wil_rx_snaplen(void)
{
return rx_align_2 ? 6 : 0;
@@ -1974,6 +1977,10 @@ static inline void __wil_update_net_queues(struct wil6210_priv *wil,
wil_dbg_txrx(wil, "check_stop=%d, mid=%d, stopped=%d",
check_stop, vif->mid, vif->net_queue_stopped);
+ if (ring && drop_if_ring_full)
+ /* no need to stop/wake net queues */
+ return;
+
if (check_stop == vif->net_queue_stopped)
/* net queues already in desired state */
return;
@@ -2099,6 +2106,8 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
case -ENOMEM:
+ if (drop_if_ring_full)
+ goto drop;
return NETDEV_TX_BUSY;
default:
break; /* goto drop; */
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 0f3be3ff..ba833ac 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -38,6 +38,7 @@
extern bool debug_fw;
extern bool disable_ap_sme;
extern bool ftm_mode;
+extern bool drop_if_ring_full;
struct wil6210_priv;
struct wil6210_vif;
--
1.9.1
^ permalink raw reply related
* [PATCH 01/21] wil6210: remove rtap_include_phy_info module param
From: Maya Erez @ 2019-02-22 14:20 UTC (permalink / raw)
To: Kalle Valo; +Cc: Maya Erez, linux-wireless, wil6210
In-Reply-To: <1550845279-16103-1-git-send-email-merez@codeaurora.org>
Due to a HW issue in PHY info collection rtap_include_phy_info is not
in use, hence can be removed.
Signed-off-by: Maya Erez <merez@codeaurora.org>
---
drivers/net/wireless/ath/wil6210/txrx.c | 88 ++++++---------------------------
drivers/net/wireless/ath/wil6210/txrx.h | 7 +--
drivers/net/wireless/ath/wil6210/wmi.c | 4 +-
3 files changed, 18 insertions(+), 81 deletions(-)
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 3e1c831..4d286fb 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -30,11 +30,6 @@
#include "trace.h"
#include "txrx_edma.h"
-static bool rtap_include_phy_info;
-module_param(rtap_include_phy_info, bool, 0444);
-MODULE_PARM_DESC(rtap_include_phy_info,
- " Include PHY info in the radiotap header, default - no");
-
bool rx_align_2;
module_param(rx_align_2, bool, 0444);
MODULE_PARM_DESC(rx_align_2, " align Rx buffers on 4*n+2, default - no");
@@ -332,87 +327,34 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
u8 mcs_flags;
u8 mcs_index;
} __packed;
- struct wil6210_rtap_vendor {
- struct wil6210_rtap rtap;
- /* vendor */
- u8 vendor_oui[3] __aligned(2);
- u8 vendor_ns;
- __le16 vendor_skip;
- u8 vendor_data[0];
- } __packed;
struct vring_rx_desc *d = wil_skb_rxdesc(skb);
- struct wil6210_rtap_vendor *rtap_vendor;
+ struct wil6210_rtap *rtap;
int rtap_len = sizeof(struct wil6210_rtap);
- int phy_length = 0; /* phy info header size, bytes */
- static char phy_data[128];
struct ieee80211_channel *ch = wil->monitor_chandef.chan;
- if (rtap_include_phy_info) {
- rtap_len = sizeof(*rtap_vendor) + sizeof(*d);
- /* calculate additional length */
- if (d->dma.status & RX_DMA_STATUS_PHY_INFO) {
- /**
- * PHY info starts from 8-byte boundary
- * there are 8-byte lines, last line may be partially
- * written (HW bug), thus FW configures for last line
- * to be excessive. Driver skips this last line.
- */
- int len = min_t(int, 8 + sizeof(phy_data),
- wil_rxdesc_phy_length(d));
-
- if (len > 8) {
- void *p = skb_tail_pointer(skb);
- void *pa = PTR_ALIGN(p, 8);
-
- if (skb_tailroom(skb) >= len + (pa - p)) {
- phy_length = len - 8;
- memcpy(phy_data, pa, phy_length);
- }
- }
- }
- rtap_len += phy_length;
- }
-
if (skb_headroom(skb) < rtap_len &&
pskb_expand_head(skb, rtap_len, 0, GFP_ATOMIC)) {
wil_err(wil, "Unable to expand headroom to %d\n", rtap_len);
return;
}
- rtap_vendor = skb_push(skb, rtap_len);
- memset(rtap_vendor, 0, rtap_len);
+ rtap = skb_push(skb, rtap_len);
+ memset(rtap, 0, rtap_len);
- rtap_vendor->rtap.rthdr.it_version = PKTHDR_RADIOTAP_VERSION;
- rtap_vendor->rtap.rthdr.it_len = cpu_to_le16(rtap_len);
- rtap_vendor->rtap.rthdr.it_present = cpu_to_le32(
- (1 << IEEE80211_RADIOTAP_FLAGS) |
+ rtap->rthdr.it_version = PKTHDR_RADIOTAP_VERSION;
+ rtap->rthdr.it_len = cpu_to_le16(rtap_len);
+ rtap->rthdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
(1 << IEEE80211_RADIOTAP_CHANNEL) |
(1 << IEEE80211_RADIOTAP_MCS));
if (d->dma.status & RX_DMA_STATUS_ERROR)
- rtap_vendor->rtap.flags |= IEEE80211_RADIOTAP_F_BADFCS;
-
- rtap_vendor->rtap.chnl_freq = cpu_to_le16(ch ? ch->center_freq : 58320);
- rtap_vendor->rtap.chnl_flags = cpu_to_le16(0);
-
- rtap_vendor->rtap.mcs_present = IEEE80211_RADIOTAP_MCS_HAVE_MCS;
- rtap_vendor->rtap.mcs_flags = 0;
- rtap_vendor->rtap.mcs_index = wil_rxdesc_mcs(d);
-
- if (rtap_include_phy_info) {
- rtap_vendor->rtap.rthdr.it_present |= cpu_to_le32(1 <<
- IEEE80211_RADIOTAP_VENDOR_NAMESPACE);
- /* OUI for Wilocity 04:ce:14 */
- rtap_vendor->vendor_oui[0] = 0x04;
- rtap_vendor->vendor_oui[1] = 0xce;
- rtap_vendor->vendor_oui[2] = 0x14;
- rtap_vendor->vendor_ns = 1;
- /* Rx descriptor + PHY data */
- rtap_vendor->vendor_skip = cpu_to_le16(sizeof(*d) +
- phy_length);
- memcpy(rtap_vendor->vendor_data, (void *)d, sizeof(*d));
- memcpy(rtap_vendor->vendor_data + sizeof(*d), phy_data,
- phy_length);
- }
+ rtap->flags |= IEEE80211_RADIOTAP_F_BADFCS;
+
+ rtap->chnl_freq = cpu_to_le16(ch ? ch->center_freq : 58320);
+ rtap->chnl_flags = cpu_to_le16(0);
+
+ rtap->mcs_present = IEEE80211_RADIOTAP_MCS_HAVE_MCS;
+ rtap->mcs_flags = 0;
+ rtap->mcs_index = wil_rxdesc_mcs(d);
}
static bool wil_is_rx_idle(struct wil6210_priv *wil)
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
index 9d83be4..bc81444 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/drivers/net/wireless/ath/wil6210/txrx.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -530,11 +530,6 @@ static inline int wil_rxdesc_mcast(struct vring_rx_desc *d)
return WIL_GET_BITS(d->mac.d1, 13, 14);
}
-static inline int wil_rxdesc_phy_length(struct vring_rx_desc *d)
-{
- return WIL_GET_BITS(d->dma.d0, 16, 29);
-}
-
static inline struct vring_rx_desc *wil_skb_rxdesc(struct sk_buff *skb)
{
return (void *)skb->cb;
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 345f059..b1ba519 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -2516,7 +2516,7 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct wil_ring *vring)
if (ch)
cmd.sniffer_cfg.channel = ch->hw_value - 1;
cmd.sniffer_cfg.phy_info_mode =
- cpu_to_le32(ndev->type == ARPHRD_IEEE80211_RADIOTAP);
+ cpu_to_le32(WMI_SNIFFER_PHY_INFO_DISABLED);
cmd.sniffer_cfg.phy_support =
cpu_to_le32((wil->monitor_flags & MONITOR_FLAG_CONTROL)
? WMI_SNIFFER_CP : WMI_SNIFFER_BOTH_PHYS);
--
1.9.1
^ permalink raw reply related
* [PATCH 00/21] wil6210 patches
From: Maya Erez @ 2019-02-22 14:20 UTC (permalink / raw)
To: Kalle Valo; +Cc: Maya Erez, linux-wireless, wil6210
The following set of patches include:
- support up to 20 stations in AP mode
- add support for ucode tracing
- various wil6210 fixes
Ahmad Masri (6):
wil6210: support up to 20 stations in AP mode
wil6210: accessing 802.3 addresses via utility functions
wil6210: prevent device memory access while in reset or suspend
wil6210: check mid is valid
wil6210: fix report of rx packet checksum in edma mode
wil6210: add support for ucode tracing
Alexei Avshalom Lazar (2):
wil6210: check null pointer in _wil_cfg80211_merge_extra_ies
wil6210: align to latest auto generated wmi.h
Dedy Lansky (4):
wil6210: add option to drop Tx packets when Tx ring is full
wil6210: fix invalid sta statistics update
wil6210: use OEM MAC address from OTP
wil6210: free edma_rx_swtail upon reset
Lior David (1):
wil6210: fix return code of wmi_mgmt_tx and wmi_mgmt_tx_ext
Maya Erez (8):
wil6210: remove rtap_include_phy_info module param
wil6210: ignore HALP ICR if already handled
wil6210: increase PCP stop command timeout
wil6210: do not set BIT_USER_SUPPORT_T_POWER_ON_0 in Talyn-MB
wil6210: update WIL_MCS_MAX to 15
wil6210: prevent access to RGF_CAF_ICR in Talyn
wil6210: reset buff id in status message after completion
wil6210: print error in FW and board files load failures
drivers/net/wireless/ath/wil6210/cfg80211.c | 31 ++-
drivers/net/wireless/ath/wil6210/debugfs.c | 61 ++++--
drivers/net/wireless/ath/wil6210/fw_inc.c | 6 +-
drivers/net/wireless/ath/wil6210/interrupt.c | 12 +-
drivers/net/wireless/ath/wil6210/main.c | 91 +++++---
drivers/net/wireless/ath/wil6210/netdev.c | 10 +-
drivers/net/wireless/ath/wil6210/pcie_bus.c | 4 +-
drivers/net/wireless/ath/wil6210/pm.c | 35 +--
drivers/net/wireless/ath/wil6210/rx_reorder.c | 10 +-
drivers/net/wireless/ath/wil6210/trace.h | 3 +-
drivers/net/wireless/ath/wil6210/txrx.c | 254 ++++++++++++----------
drivers/net/wireless/ath/wil6210/txrx.h | 51 ++++-
drivers/net/wireless/ath/wil6210/txrx_edma.c | 85 ++++----
drivers/net/wireless/ath/wil6210/txrx_edma.h | 47 +++-
drivers/net/wireless/ath/wil6210/wil6210.h | 27 ++-
drivers/net/wireless/ath/wil6210/wil_crash_dump.c | 18 +-
drivers/net/wireless/ath/wil6210/wmi.c | 107 ++++++---
drivers/net/wireless/ath/wil6210/wmi.h | 91 +++++++-
18 files changed, 641 insertions(+), 302 deletions(-)
--
1.9.1
^ permalink raw reply
* Re: [PATCH] mac80211: Change default tx_sk_pacing_shift to 7
From: Toke Høiland-Jørgensen @ 2019-02-22 13:40 UTC (permalink / raw)
To: Johannes Berg
Cc: linux-wireless, Ben Greear, Grant Grundler, Kalle Valo, wgong,
ath10k, wgong, Kan Yan
In-Reply-To: <a5151441bdfe02cb11043aa0786185b8ee3c3ee9.camel@sipsolutions.net>
Johannes Berg <johannes@sipsolutions.net> writes:
> On Fri, 2019-02-22 at 14:06 +0100, Toke Høiland-Jørgensen wrote:
>> Johannes Berg <johannes@sipsolutions.net> writes:
>>
>> > Toke Høiland-Jørgensen wrote:
>> >
>> > > When we did the original tests for the optimal value of sk_pacing_shift, we
>> > > came up with 6 ms of buffering as the default. Sadly, 6 is not a power of
>> > > two, so when picking the shift value I erred on the size of less buffering
>> > > and picked 4 ms instead of 8. This was probably wrong; those 2 ms of extra
>> > > buffering makes a larger difference than I thought.
>> > >
>> > > So, change the default pacing shift to 7, which corresponds to 8 ms of
>> > > buffering. The point of diminishing returns really kicks in after 8 ms, and
>> > > so having this as a default should cut down on the need for extensive
>> > > per-device testing and overrides needed in the drivers.
>> > >
>> > > Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
>> >
>> > Patch applied to wireless.git, thanks.
>> >
>> > a41f56b9a17a (HEAD -> mac80211) mac80211: Change default
>> > tx_sk_pacing_shift to 7
>
> This mess came from Kalle's tool btw, so I can't really use it yet :-)
>
>> Cool, thanks! What's the easiest way to backport this? I figure it's
>> easier to just update sk_pacing_shift_update() in tx.c for 4.19 (which
>> predates the addition of the driver override hook); shall I just send a
>> separate patch to stable for that? Or do we need to backport the driver
>> override hook as well?
>
> Just update the value, no need to backport the hook.
And send it directly to stable, or does it need to go through you?
-Toke
^ permalink raw reply
* pull-request: mac80211-next 2019-02-22
From: Johannes Berg @ 2019-02-22 13:25 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-wireless
Hi Dave,
Here's the promised update with the big multi-BSSID changes,
which are related to HE (802.11ax) for which we also have some
updates.
Note that I took the liberty of including Herbert's rhashtable
API removal, I merged net-next for that and verified that the
API he removed is also not used in anything new, but if you
apply/applied any patches after I pulled you should probably
double check that again.
Please pull and let me know if there's any problem.
Thanks,
johannes
The following changes since commit 7a25c6c0aac85bbc50d3ce49cd08888adb14508b:
rocker: Add missing break for PRE_BRIDGE_FLAGS (2019-02-21 21:29:23 -0800)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git tags/mac80211-next-for-davem-2019-02-22
for you to fetch changes up to 6c4128f658571b2dc7e01058ad09a8e947bc0159:
rhashtable: Remove obsolete rhashtable_walk_init function (2019-02-22 13:49:00 +0100)
----------------------------------------------------------------
This time we have, of note:
* the massive patch series for multi-BSSID support, I ended up
applying that through a side branch to record some details
* CSA improvements
* HE (802.11ax) updates to Draft 3.3
* strongly typed element iteration/etc. to make such code more
readable - this came up in particular in multi-BSSID
* rhashtable conversion patches from Herbert
Along, as usual, with various fixes and improvements.
----------------------------------------------------------------
Cody Schuffelen (1):
virt_wifi: Remove REGULATORY_WIPHY_SELF_MANAGED
Herbert Xu (2):
mac80211: Use rhashtable_lookup_get_insert_fast instead of racy code
rhashtable: Remove obsolete rhashtable_walk_init function
Johannes Berg (13):
cfg80211: add and use strongly typed element iteration macros
cfg80211: use for_each_element() for multi-bssid parsing
mac80211: use element iteration macro in parsing
cfg80211: add various struct element finding helpers
nl80211: use for_each_element() in validate_ie_attr()
cfg80211: add missing kernel-doc for multi-BSSID fields
Merge branch 'cfg80211-mac80211-multi-bssid' into mac80211-next
ieee80211: fix for_each_element_extid()
cfg80211: restore regulatory without calling userspace
cfg80211: fix and clean up cfg80211_gen_new_bssid()
radiotap: add 0-length PSDU "not captured" type
cfg80211: allow sending vendor events unicast
Merge remote-tracking branch 'net-next/master' into mac80211-next
Jouni Malinen (4):
mac80211_hwsim: Support boottime in scan results
mac80211_hwsim: Declare support for Multi-BSSID
cfg80211: Use const more consistently in for_each_element macros
cfg80211: Report Association Request frame IEs in association events
Liad Kaufman (2):
mac80211: fix position of vendor_data read
mac80211: update HE IEs to D3.3
Mao Wenan (1):
cfg80211: pmsr: use eth_broadcast_addr() to assign broadcast address
Peng Xu (1):
cfg80211: Parsing of Multiple BSSID information in scanning
Sara Sharon (16):
mac80211: pass bssids to elements parsing function
mac80211: move the bss update from elements to an helper
cfg80211: Properly track transmitting and non-transmitting BSS
cfg80211: Move Multiple BSS info to struct cfg80211_bss to be visible
cfg80211: parse multi-bssid only if HW supports it
cfg80211: make BSSID generation function inline
cfg80211: save multi-bssid properties
mac80211: support multi-bssid
mac80211: indicate support for multiple BSSID
cfg80211: fix the IE inheritance of extension IEs
cfg80211: fix memory leak of new_ie
mac80211: support max channel switch time element
mac80211: abort CSA if beacon does not include CSA IEs
mac80211: notify driver on subsequent CSA beacons
mac80211: allow CSA to self with immediate quiet
mac80211: ignore quiet mode in probe
drivers/net/wireless/intel/iwlwifi/fw/api/mac.h | 26 +-
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c | 58 +-
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 40 ++
drivers/net/wireless/mac80211_hwsim.c | 7 +-
drivers/net/wireless/virt_wifi.c | 1 -
include/linux/ieee80211.h | 115 +++-
include/linux/rhashtable.h | 8 -
include/net/cfg80211.h | 233 +++++++-
include/net/ieee80211_radiotap.h | 3 +-
include/net/mac80211.h | 40 +-
lib/rhashtable.c | 2 +-
lib/test_rhashtable.c | 9 +-
net/ipv6/ila/ila_xlat.c | 15 +-
net/mac80211/debugfs.c | 4 +-
net/mac80211/debugfs_sta.c | 35 +-
net/mac80211/driver-ops.h | 31 +-
net/mac80211/ibss.c | 8 +-
net/mac80211/ieee80211_i.h | 28 +-
net/mac80211/main.c | 13 +-
net/mac80211/mesh.c | 10 +-
net/mac80211/mesh_hwmp.c | 3 +-
net/mac80211/mesh_pathtbl.c | 24 +-
net/mac80211/mesh_plink.c | 4 +-
net/mac80211/mlme.c | 269 +++++++---
net/mac80211/rx.c | 21 +-
net/mac80211/scan.c | 160 +++---
net/mac80211/spectmgmt.c | 6 +
net/mac80211/tdls.c | 6 +-
net/mac80211/trace.h | 46 +-
net/mac80211/util.c | 137 ++++-
net/netlink/af_netlink.c | 10 +-
net/wireless/core.h | 13 +-
net/wireless/mlme.c | 8 +-
net/wireless/nl80211.c | 82 +--
net/wireless/nl80211.h | 3 +-
net/wireless/pmsr.c | 2 +-
net/wireless/reg.c | 73 ++-
net/wireless/reg.h | 2 +
net/wireless/scan.c | 595 ++++++++++++++++++---
net/wireless/util.c | 6 +-
40 files changed, 1713 insertions(+), 443 deletions(-)
^ permalink raw reply
* pull-request: mac80211 2019-02-22
From: Johannes Berg @ 2019-02-22 13:10 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-wireless
Hi Dave,
So ... I thought there weren't going to be any more patches
when I asked you to apply that mac80211 one, but now a few
days later I still ended up with three that are current and
possibly even stable material.
Please pull and let me know if there's any problem.
Thanks,
johannes
The following changes since commit 6321aa197547da397753757bd84c6ce64b3e3d89:
phonet: fix building with clang (2019-02-21 16:23:56 -0800)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git tags/mac80211-for-davem-2019-02-22
for you to fetch changes up to 51d0af222f6fa43134c6187ab4f374630f6e0d96:
mac80211: allocate tailroom for forwarded mesh packets (2019-02-22 14:00:40 +0100)
----------------------------------------------------------------
Three more fixes:
* mac80211 mesh code wasn't allocating SKB tailroom properly
in some cases
* tx_sk_pacing_shift should be 7 for better performance
* mac80211_hwsim wasn't propagating genlmsg_reply() errors
----------------------------------------------------------------
Felix Fietkau (1):
mac80211: allocate tailroom for forwarded mesh packets
Li RongQing (1):
mac80211_hwsim: propagate genlmsg_reply return code
Toke Høiland-Jørgensen (1):
mac80211: Change default tx_sk_pacing_shift to 7
drivers/net/wireless/mac80211_hwsim.c | 2 +-
net/mac80211/main.c | 4 ++--
net/mac80211/rx.c | 7 ++++++-
3 files changed, 9 insertions(+), 4 deletions(-)
^ permalink raw reply
* Re: [PATCH] mac80211: Change default tx_sk_pacing_shift to 7
From: Johannes Berg @ 2019-02-22 13:07 UTC (permalink / raw)
To: Toke Høiland-Jørgensen
Cc: linux-wireless, Ben Greear, Grant Grundler, Kalle Valo, wgong,
ath10k, wgong, Kan Yan
In-Reply-To: <87lg28vup0.fsf@toke.dk>
On Fri, 2019-02-22 at 14:06 +0100, Toke Høiland-Jørgensen wrote:
> Johannes Berg <johannes@sipsolutions.net> writes:
>
> > Toke Høiland-Jørgensen wrote:
> >
> > > When we did the original tests for the optimal value of sk_pacing_shift, we
> > > came up with 6 ms of buffering as the default. Sadly, 6 is not a power of
> > > two, so when picking the shift value I erred on the size of less buffering
> > > and picked 4 ms instead of 8. This was probably wrong; those 2 ms of extra
> > > buffering makes a larger difference than I thought.
> > >
> > > So, change the default pacing shift to 7, which corresponds to 8 ms of
> > > buffering. The point of diminishing returns really kicks in after 8 ms, and
> > > so having this as a default should cut down on the need for extensive
> > > per-device testing and overrides needed in the drivers.
> > >
> > > Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
> >
> > Patch applied to wireless.git, thanks.
> >
> > a41f56b9a17a (HEAD -> mac80211) mac80211: Change default
> > tx_sk_pacing_shift to 7
This mess came from Kalle's tool btw, so I can't really use it yet :-)
> Cool, thanks! What's the easiest way to backport this? I figure it's
> easier to just update sk_pacing_shift_update() in tx.c for 4.19 (which
> predates the addition of the driver override hook); shall I just send a
> separate patch to stable for that? Or do we need to backport the driver
> override hook as well?
Just update the value, no need to backport the hook.
johannes
^ permalink raw reply
* Re: [PATCH] mac80211: Change default tx_sk_pacing_shift to 7
From: Toke Høiland-Jørgensen @ 2019-02-22 13:06 UTC (permalink / raw)
To: Johannes Berg
Cc: linux-wireless, Ben Greear, Grant Grundler, Kalle Valo, wgong,
ath10k, wgong, Kan Yan
In-Reply-To: <E1gx9x3-0002j0-1J@sipsolutions.net>
Johannes Berg <johannes@sipsolutions.net> writes:
> Toke Høiland-Jørgensen wrote:
>
>> When we did the original tests for the optimal value of sk_pacing_shift, we
>> came up with 6 ms of buffering as the default. Sadly, 6 is not a power of
>> two, so when picking the shift value I erred on the size of less buffering
>> and picked 4 ms instead of 8. This was probably wrong; those 2 ms of extra
>> buffering makes a larger difference than I thought.
>>
>> So, change the default pacing shift to 7, which corresponds to 8 ms of
>> buffering. The point of diminishing returns really kicks in after 8 ms, and
>> so having this as a default should cut down on the need for extensive
>> per-device testing and overrides needed in the drivers.
>>
>> Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
>
> Patch applied to wireless.git, thanks.
>
> a41f56b9a17a (HEAD -> mac80211) mac80211: Change default
> tx_sk_pacing_shift to 7
Cool, thanks! What's the easiest way to backport this? I figure it's
easier to just update sk_pacing_shift_update() in tx.c for 4.19 (which
predates the addition of the driver override hook); shall I just send a
separate patch to stable for that? Or do we need to backport the driver
override hook as well?
-Toke
^ permalink raw reply
* Re: [PATCH] cfg80211: reg: Fix use-after-free in call_crda
From: Johannes Berg @ 2019-02-22 13:00 UTC (permalink / raw)
To: Yue Haibing, davem; +Cc: linux-kernel, netdev, linux-wireless
In-Reply-To: <20190222094233.21556-1-yuehaibing@huawei.com>
Hi,
> In function reg_query_database, query_regdb_file call
> request_firmware_nowait to do request_firmware asynchronously,
> which need the caller hold the reference of dev, otherwise it will
> do put_device freeing '®_pdev->dev'. After that, call_crda access
> the dev will trigger use-after-free bug.
So ... OK, but how does that then only fix the firmware file loading,
rather than CRDA calling?
> This patch fix this by holding a reference of dev in regulatory_init
> after platform_device_register_simple registered successly, which
> releasing in platform_device_unregister.
This doesn't make sense? You just add a new reference and don't release
it? If there was a bug then just loading & unloading would trigger an
underflow now?
platform_device_register_full() (to which _simple is a wrapper) will
evidently return the pdev with a reference held, because it does
platform_device_put() in the error path?
johannes
^ permalink raw reply
* Re: [PATCH v2] cfg80211: Include the PMK and PMKID in NL80211_CMD_EXTERNAL_AUTH
From: Johannes Berg @ 2019-02-22 12:41 UTC (permalink / raw)
To: Luca Coelho; +Cc: linux-wireless, Andrei Otcheretianski, Luca Coelho
In-Reply-To: <20190206080234.15750-1-luca@coelho.fi>
> +++ b/net/wireless/nl80211.c
> @@ -13098,6 +13098,12 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
> if (!info->attrs[NL80211_ATTR_STATUS_CODE])
> return -EINVAL;
>
> + if ((info->attrs[NL80211_ATTR_PMK] &&
> + !info->attrs[NL80211_ATTR_PMKID]) ||
> + (info->attrs[NL80211_ATTR_PMKID] &&
> + !info->attrs[NL80211_ATTR_PMK]))
> + return -EINVAL;
This constitutes a netlink API change, so no, can't be right? PMKID was
perfectly reasonable to pass by itself before.
johannes
^ permalink raw reply
* Re: [PATCH] mac80211: Change default tx_sk_pacing_shift to 7
From: Johannes Berg @ 2019-02-22 12:29 UTC (permalink / raw)
To: Toke Høiland-Jørgensen
Cc: linux-wireless, Ben Greear, Grant Grundler, Kalle Valo, wgong,
ath10k, wgong, Kan Yan, Toke Høiland-Jørgensen
In-Reply-To: <20190221172936.21816-1-toke@redhat.com>
Toke Høiland-Jørgensen wrote:
> When we did the original tests for the optimal value of sk_pacing_shift, we
> came up with 6 ms of buffering as the default. Sadly, 6 is not a power of
> two, so when picking the shift value I erred on the size of less buffering
> and picked 4 ms instead of 8. This was probably wrong; those 2 ms of extra
> buffering makes a larger difference than I thought.
>
> So, change the default pacing shift to 7, which corresponds to 8 ms of
> buffering. The point of diminishing returns really kicks in after 8 ms, and
> so having this as a default should cut down on the need for extensive
> per-device testing and overrides needed in the drivers.
>
> Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
Patch applied to wireless.git, thanks.
a41f56b9a17a (HEAD -> mac80211) mac80211: Change default tx_sk_pacing_shift to 7
--
https://patchwork.kernel.org/patch/10824427/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: [PATCH] mac80211_hwsim::: propagate genlmsg_reply return code
From: Johannes Berg @ 2019-02-22 12:26 UTC (permalink / raw)
To: Li RongQing; +Cc: kvalo, linux-wireless
In-Reply-To: <1550553160-18324-1-git-send-email-lirongqing@baidu.com>
Li RongQing <lirongqing@baidu.com> wrote:
> genlmsg_reply can fail, so propagate its return code
>
> Signed-off-by: Li RongQing <lirongqing@baidu.com>
Patch applied to wireless.git, thanks.
b97c9cb91d51 (HEAD -> mac80211) mac80211_hwsim::: propagate genlmsg_reply return code
--
https://patchwork.kernel.org/patch/10819185/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* [PATCH] mac80211: allocate tailroom for forwarded mesh packets
From: Felix Fietkau @ 2019-02-22 12:21 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, stable
Forwarded packets enter the tx path through ieee80211_add_pending_skb,
which skips the ieee80211_skb_resize call.
Fixes WARN_ON in ccmp_encrypt_skb and resulting packet loss.
Cc: stable@vger.kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
net/mac80211/rx.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 45aad3d3108c..d78c106ef314 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2644,6 +2644,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
struct ieee80211_sub_if_data *sdata = rx->sdata;
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
u16 ac, q, hdrlen;
+ int tailroom = 0;
hdr = (struct ieee80211_hdr *) skb->data;
hdrlen = ieee80211_hdrlen(hdr->frame_control);
@@ -2730,8 +2731,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
if (!ifmsh->mshcfg.dot11MeshForwarding)
goto out;
+ if (sdata->crypto_tx_tailroom_needed_cnt)
+ tailroom = IEEE80211_ENCRYPT_TAILROOM;
+
fwd_skb = skb_copy_expand(skb, local->tx_headroom +
- sdata->encrypt_headroom, 0, GFP_ATOMIC);
+ sdata->encrypt_headroom,
+ tailroom, GFP_ATOMIC);
if (!fwd_skb)
goto out;
--
2.17.0
^ permalink raw reply related
* Re: [PATCH v3 2/3] mt76usb: use synchronous msg for mcu command responses
From: Lorenzo Bianconi @ 2019-02-22 12:00 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Felix Fietkau, linux-wireless
In-Reply-To: <20190222115446.GA5720@redhat.com>
> On Fri, Feb 22, 2019 at 10:53:19AM +0100, Lorenzo Bianconi wrote:
> > > Use usb_bulk_msg for reading MCU command responses. This simplify code
> > > a lot.
> > >
> > > Together with 97a3005759c ("mt76usb: allow mt76u_bulk_msg be used
> > > for reads") it also fix possible problems with rx data buffers
> > > not being aligned and contained within single page. After doing
> > > page_frag_alloc(1024) consecutive page_frag_alloc(PAGE_SIZE) will
> > > alloc PAGE_SIZE buffer at PAGE_SIZE - 1024 offset.
> > >
> > > Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> > > ---
> > > drivers/net/wireless/mediatek/mt76/mt76.h | 3 +-
> > > drivers/net/wireless/mediatek/mt76/mt76x0/usb.c | 11 --------
> > > .../net/wireless/mediatek/mt76/mt76x02_usb_mcu.c | 32 +++++++---------------
> > > drivers/net/wireless/mediatek/mt76/mt76x2/usb.c | 11 --------
> > > drivers/net/wireless/mediatek/mt76/usb.c | 1 -
> > > drivers/net/wireless/mediatek/mt76/usb_mcu.c | 31 +++------------------
> > > 6 files changed, 15 insertions(+), 74 deletions(-)
> > >
> > > diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
> > > index 6092646014c4..c9b5eb9b0582 100644
> > > --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> > > +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> > > @@ -384,8 +384,7 @@ struct mt76_usb {
> > >
> > > struct mt76u_mcu {
> > > struct mutex mutex;
> > > - struct completion cmpl;
> >
> > Hi Stanislaw,
> >
> > I was reviewing this approach and I guess it is a little bit racey since now we
> > are not sure that when the device is removed or suspended the pending mcu commands
> > are terminated and we do not have any api to stop usb transactions.
> > Are we sure when we access mt76x02_dev/mt76_dev structure it has not been
> > already removed?
> > Maybe we need to maintain the completion in mt76u_mcu and use it to wait the mcu
> > commands are terminated.
>
> I don't think so. On suspend we do mt76xxu_mac_stop() which access registers
> using mcu commands, all should be synchronized by mcu->mutex . All other
> process that could use mcu command should be already stopped. Actually suspend
> can be simplified.
ack, I missed mcu->mutex. Thx.
Regards,
Lorenzo
>
> Device remove should be properly handled by -ENODEV error returned by
> usb_bulk_msg.
>
> Stanislaw
^ 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