aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKalle Valo <kvalo@codeaurora.org>2018-03-27 03:06:18 -0400
committerKalle Valo <kvalo@codeaurora.org>2018-03-27 03:06:18 -0400
commitabd5f00844ec7fa507064ee4a22b3605c64c7d31 (patch)
treebdfab7c73070807f2667cfd14d16e75ca988f83f
parent996bfed118748c128ad4b6c05c09fd2f5fdfa1b4 (diff)
parent6767b302e1c961f0775abaa068495aa137331191 (diff)
Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
ath.git patches for 4.17. Major changes: wil6210 * support multiple virtual interfaces
-rw-r--r--drivers/net/wireless/ath/ath10k/core.c3
-rw-r--r--drivers/net/wireless/ath/ath10k/core.h67
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.c154
-rw-r--r--drivers/net/wireless/ath/ath10k/debug.h41
-rw-r--r--drivers/net/wireless/ath/ath10k/debugfs_sta.c286
-rw-r--r--drivers/net/wireless/ath/ath10k/htt_rx.c71
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c38
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c2
-rw-r--r--drivers/net/wireless/ath/ath10k/trace.h12
-rw-r--r--drivers/net/wireless/ath/ath10k/txrx.c12
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-ops.h56
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi-tlv.c22
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.c310
-rw-r--r--drivers/net/wireless/ath/ath10k/wmi.h66
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/common-init.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/common-spectral.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c4
-rw-r--r--drivers/net/wireless/ath/dfs_pattern_detector.c2
-rw-r--r--drivers/net/wireless/ath/wcn36xx/dxe.c56
-rw-r--r--drivers/net/wireless/ath/wcn36xx/dxe.h218
-rw-r--r--drivers/net/wireless/ath/wcn36xx/main.c12
-rw-r--r--drivers/net/wireless/ath/wcn36xx/smd.c20
-rw-r--r--drivers/net/wireless/ath/wcn36xx/wcn36xx.h2
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c741
-rw-r--r--drivers/net/wireless/ath/wil6210/debug.c9
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c117
-rw-r--r--drivers/net/wireless/ath/wil6210/ethtool.c4
-rw-r--r--drivers/net/wireless/ath/wil6210/fw.h38
-rw-r--r--drivers/net/wireless/ath/wil6210/fw_inc.c52
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c8
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c333
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c382
-rw-r--r--drivers/net/wireless/ath/wil6210/p2p.c175
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c57
-rw-r--r--drivers/net/wireless/ath/wil6210/pm.c132
-rw-r--r--drivers/net/wireless/ath/wil6210/pmc.c8
-rw-r--r--drivers/net/wireless/ath/wil6210/rx_reorder.c45
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c177
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.h22
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h217
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c460
43 files changed, 3446 insertions, 1015 deletions
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index f3ec13b80b20..830b7fe466f3 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc. 2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
4 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 * 5 *
5 * Permission to use, copy, modify, and/or distribute this software for any 6 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
@@ -2439,7 +2440,7 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
2439 2440
2440 ret = ath10k_hif_power_up(ar); 2441 ret = ath10k_hif_power_up(ar);
2441 if (ret) { 2442 if (ret) {
2442 ath10k_err(ar, "could not start pci hif (%d)\n", ret); 2443 ath10k_err(ar, "could not power on hif bus (%d)\n", ret);
2443 return ret; 2444 return ret;
2444 } 2445 }
2445 2446
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index fe6b30356d3b..73712c830be7 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc. 2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
4 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 * 5 *
5 * Permission to use, copy, modify, and/or distribute this software for any 6 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
@@ -324,6 +325,27 @@ struct ath10k_tpc_stats {
324 struct ath10k_tpc_table tpc_table[WMI_TPC_FLAG]; 325 struct ath10k_tpc_table tpc_table[WMI_TPC_FLAG];
325}; 326};
326 327
328struct ath10k_tpc_table_final {
329 u32 pream_idx[WMI_TPC_FINAL_RATE_MAX];
330 u8 rate_code[WMI_TPC_FINAL_RATE_MAX];
331 char tpc_value[WMI_TPC_FINAL_RATE_MAX][WMI_TPC_TX_N_CHAIN * WMI_TPC_BUF_SIZE];
332};
333
334struct ath10k_tpc_stats_final {
335 u32 reg_domain;
336 u32 chan_freq;
337 u32 phy_mode;
338 u32 twice_antenna_reduction;
339 u32 twice_max_rd_power;
340 s32 twice_antenna_gain;
341 u32 power_limit;
342 u32 num_tx_chain;
343 u32 ctl;
344 u32 rate_max;
345 u8 flag[WMI_TPC_FLAG];
346 struct ath10k_tpc_table_final tpc_table_final[WMI_TPC_FLAG];
347};
348
327struct ath10k_dfs_stats { 349struct ath10k_dfs_stats {
328 u32 phy_errors; 350 u32 phy_errors;
329 u32 pulses_total; 351 u32 pulses_total;
@@ -354,6 +376,45 @@ struct ath10k_txq {
354 unsigned long num_push_allowed; 376 unsigned long num_push_allowed;
355}; 377};
356 378
379enum ath10k_pkt_rx_err {
380 ATH10K_PKT_RX_ERR_FCS,
381 ATH10K_PKT_RX_ERR_TKIP,
382 ATH10K_PKT_RX_ERR_CRYPT,
383 ATH10K_PKT_RX_ERR_PEER_IDX_INVAL,
384 ATH10K_PKT_RX_ERR_MAX,
385};
386
387enum ath10k_ampdu_subfrm_num {
388 ATH10K_AMPDU_SUBFRM_NUM_10,
389 ATH10K_AMPDU_SUBFRM_NUM_20,
390 ATH10K_AMPDU_SUBFRM_NUM_30,
391 ATH10K_AMPDU_SUBFRM_NUM_40,
392 ATH10K_AMPDU_SUBFRM_NUM_50,
393 ATH10K_AMPDU_SUBFRM_NUM_60,
394 ATH10K_AMPDU_SUBFRM_NUM_MORE,
395 ATH10K_AMPDU_SUBFRM_NUM_MAX,
396};
397
398enum ath10k_amsdu_subfrm_num {
399 ATH10K_AMSDU_SUBFRM_NUM_1,
400 ATH10K_AMSDU_SUBFRM_NUM_2,
401 ATH10K_AMSDU_SUBFRM_NUM_3,
402 ATH10K_AMSDU_SUBFRM_NUM_4,
403 ATH10K_AMSDU_SUBFRM_NUM_MORE,
404 ATH10K_AMSDU_SUBFRM_NUM_MAX,
405};
406
407struct ath10k_sta_tid_stats {
408 unsigned long int rx_pkt_from_fw;
409 unsigned long int rx_pkt_unchained;
410 unsigned long int rx_pkt_drop_chained;
411 unsigned long int rx_pkt_drop_filter;
412 unsigned long int rx_pkt_err[ATH10K_PKT_RX_ERR_MAX];
413 unsigned long int rx_pkt_queued_for_mac;
414 unsigned long int rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_MAX];
415 unsigned long int rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_MAX];
416};
417
357struct ath10k_sta { 418struct ath10k_sta {
358 struct ath10k_vif *arvif; 419 struct ath10k_vif *arvif;
359 420
@@ -371,6 +432,9 @@ struct ath10k_sta {
371#ifdef CONFIG_MAC80211_DEBUGFS 432#ifdef CONFIG_MAC80211_DEBUGFS
372 /* protected by conf_mutex */ 433 /* protected by conf_mutex */
373 bool aggr_mode; 434 bool aggr_mode;
435
436 /* Protected with ar->data_lock */
437 struct ath10k_sta_tid_stats tid_stats[IEEE80211_NUM_TIDS + 1];
374#endif 438#endif
375}; 439};
376 440
@@ -487,6 +551,7 @@ struct ath10k_debug {
487 551
488 /* used for tpc-dump storage, protected by data-lock */ 552 /* used for tpc-dump storage, protected by data-lock */
489 struct ath10k_tpc_stats *tpc_stats; 553 struct ath10k_tpc_stats *tpc_stats;
554 struct ath10k_tpc_stats_final *tpc_stats_final;
490 555
491 struct completion tpc_complete; 556 struct completion tpc_complete;
492 557
@@ -1019,6 +1084,8 @@ struct ath10k {
1019 1084
1020 void *ce_priv; 1085 void *ce_priv;
1021 1086
1087 u32 sta_tid_stats_mask;
1088
1022 /* must be last */ 1089 /* must be last */
1023 u8 drv_priv[0] __aligned(sizeof(void *)); 1090 u8 drv_priv[0] __aligned(sizeof(void *));
1024}; 1091};
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index 554cd7856cb6..bac832ce1873 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -1480,6 +1480,19 @@ void ath10k_debug_tpc_stats_process(struct ath10k *ar,
1480 spin_unlock_bh(&ar->data_lock); 1480 spin_unlock_bh(&ar->data_lock);
1481} 1481}
1482 1482
1483void
1484ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
1485 struct ath10k_tpc_stats_final *tpc_stats)
1486{
1487 spin_lock_bh(&ar->data_lock);
1488
1489 kfree(ar->debug.tpc_stats_final);
1490 ar->debug.tpc_stats_final = tpc_stats;
1491 complete(&ar->debug.tpc_complete);
1492
1493 spin_unlock_bh(&ar->data_lock);
1494}
1495
1483static void ath10k_tpc_stats_print(struct ath10k_tpc_stats *tpc_stats, 1496static void ath10k_tpc_stats_print(struct ath10k_tpc_stats *tpc_stats,
1484 unsigned int j, char *buf, size_t *len) 1497 unsigned int j, char *buf, size_t *len)
1485{ 1498{
@@ -2143,6 +2156,137 @@ static const struct file_operations fops_fw_checksums = {
2143 .llseek = default_llseek, 2156 .llseek = default_llseek,
2144}; 2157};
2145 2158
2159static ssize_t ath10k_sta_tid_stats_mask_read(struct file *file,
2160 char __user *user_buf,
2161 size_t count, loff_t *ppos)
2162{
2163 struct ath10k *ar = file->private_data;
2164 char buf[32];
2165 size_t len;
2166
2167 len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->sta_tid_stats_mask);
2168 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2169}
2170
2171static ssize_t ath10k_sta_tid_stats_mask_write(struct file *file,
2172 const char __user *user_buf,
2173 size_t count, loff_t *ppos)
2174{
2175 struct ath10k *ar = file->private_data;
2176 char buf[32];
2177 ssize_t len;
2178 u32 mask;
2179
2180 len = min(count, sizeof(buf) - 1);
2181 if (copy_from_user(buf, user_buf, len))
2182 return -EFAULT;
2183
2184 buf[len] = '\0';
2185 if (kstrtoint(buf, 0, &mask))
2186 return -EINVAL;
2187
2188 ar->sta_tid_stats_mask = mask;
2189
2190 return len;
2191}
2192
2193static const struct file_operations fops_sta_tid_stats_mask = {
2194 .read = ath10k_sta_tid_stats_mask_read,
2195 .write = ath10k_sta_tid_stats_mask_write,
2196 .open = simple_open,
2197 .owner = THIS_MODULE,
2198 .llseek = default_llseek,
2199};
2200
2201static int ath10k_debug_tpc_stats_final_request(struct ath10k *ar)
2202{
2203 int ret;
2204 unsigned long time_left;
2205
2206 lockdep_assert_held(&ar->conf_mutex);
2207
2208 reinit_completion(&ar->debug.tpc_complete);
2209
2210 ret = ath10k_wmi_pdev_get_tpc_table_cmdid(ar, WMI_TPC_CONFIG_PARAM);
2211 if (ret) {
2212 ath10k_warn(ar, "failed to request tpc table cmdid: %d\n", ret);
2213 return ret;
2214 }
2215
2216 time_left = wait_for_completion_timeout(&ar->debug.tpc_complete,
2217 1 * HZ);
2218 if (time_left == 0)
2219 return -ETIMEDOUT;
2220
2221 return 0;
2222}
2223
2224static int ath10k_tpc_stats_final_open(struct inode *inode, struct file *file)
2225{
2226 struct ath10k *ar = inode->i_private;
2227 void *buf;
2228 int ret;
2229
2230 mutex_lock(&ar->conf_mutex);
2231
2232 if (ar->state != ATH10K_STATE_ON) {
2233 ret = -ENETDOWN;
2234 goto err_unlock;
2235 }
2236
2237 buf = vmalloc(ATH10K_TPC_CONFIG_BUF_SIZE);
2238 if (!buf) {
2239 ret = -ENOMEM;
2240 goto err_unlock;
2241 }
2242
2243 ret = ath10k_debug_tpc_stats_final_request(ar);
2244 if (ret) {
2245 ath10k_warn(ar, "failed to request tpc stats final: %d\n",
2246 ret);
2247 goto err_free;
2248 }
2249
2250 ath10k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf);
2251 file->private_data = buf;
2252
2253 mutex_unlock(&ar->conf_mutex);
2254 return 0;
2255
2256err_free:
2257 vfree(buf);
2258
2259err_unlock:
2260 mutex_unlock(&ar->conf_mutex);
2261 return ret;
2262}
2263
2264static int ath10k_tpc_stats_final_release(struct inode *inode,
2265 struct file *file)
2266{
2267 vfree(file->private_data);
2268
2269 return 0;
2270}
2271
2272static ssize_t ath10k_tpc_stats_final_read(struct file *file,
2273 char __user *user_buf,
2274 size_t count, loff_t *ppos)
2275{
2276 const char *buf = file->private_data;
2277 unsigned int len = strlen(buf);
2278
2279 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
2280}
2281
2282static const struct file_operations fops_tpc_stats_final = {
2283 .open = ath10k_tpc_stats_final_open,
2284 .release = ath10k_tpc_stats_final_release,
2285 .read = ath10k_tpc_stats_final_read,
2286 .owner = THIS_MODULE,
2287 .llseek = default_llseek,
2288};
2289
2146int ath10k_debug_create(struct ath10k *ar) 2290int ath10k_debug_create(struct ath10k *ar)
2147{ 2291{
2148 ar->debug.cal_data = vzalloc(ATH10K_DEBUG_CAL_DATA_LEN); 2292 ar->debug.cal_data = vzalloc(ATH10K_DEBUG_CAL_DATA_LEN);
@@ -2258,6 +2402,16 @@ int ath10k_debug_register(struct ath10k *ar)
2258 debugfs_create_file("fw_checksums", 0400, ar->debug.debugfs_phy, ar, 2402 debugfs_create_file("fw_checksums", 0400, ar->debug.debugfs_phy, ar,
2259 &fops_fw_checksums); 2403 &fops_fw_checksums);
2260 2404
2405 if (IS_ENABLED(CONFIG_MAC80211_DEBUGFS))
2406 debugfs_create_file("sta_tid_stats_mask", 0600,
2407 ar->debug.debugfs_phy,
2408 ar, &fops_sta_tid_stats_mask);
2409
2410 if (test_bit(WMI_SERVICE_TPC_STATS_FINAL, ar->wmi.svc_map))
2411 debugfs_create_file("tpc_stats_final", 0400,
2412 ar->debug.debugfs_phy, ar,
2413 &fops_tpc_stats_final);
2414
2261 return 0; 2415 return 0;
2262} 2416}
2263 2417
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h
index e54308889e59..0afca5c106b6 100644
--- a/drivers/net/wireless/ath/ath10k/debug.h
+++ b/drivers/net/wireless/ath/ath10k/debug.h
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc. 2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
4 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 * 5 *
5 * Permission to use, copy, modify, and/or distribute this software for any 6 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
@@ -101,6 +102,9 @@ void ath10k_debug_unregister(struct ath10k *ar);
101void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb); 102void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb);
102void ath10k_debug_tpc_stats_process(struct ath10k *ar, 103void ath10k_debug_tpc_stats_process(struct ath10k *ar,
103 struct ath10k_tpc_stats *tpc_stats); 104 struct ath10k_tpc_stats *tpc_stats);
105void
106ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
107 struct ath10k_tpc_stats_final *tpc_stats);
104void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len); 108void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len);
105 109
106#define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++) 110#define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++)
@@ -164,6 +168,13 @@ static inline void ath10k_debug_tpc_stats_process(struct ath10k *ar,
164 kfree(tpc_stats); 168 kfree(tpc_stats);
165} 169}
166 170
171static inline void
172ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
173 struct ath10k_tpc_stats_final *tpc_stats)
174{
175 kfree(tpc_stats);
176}
177
167static inline void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, 178static inline void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer,
168 int len) 179 int len)
169{ 180{
@@ -191,12 +202,42 @@ void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
191 struct ieee80211_sta *sta, struct dentry *dir); 202 struct ieee80211_sta *sta, struct dentry *dir);
192void ath10k_sta_update_rx_duration(struct ath10k *ar, 203void ath10k_sta_update_rx_duration(struct ath10k *ar,
193 struct ath10k_fw_stats *stats); 204 struct ath10k_fw_stats *stats);
205void ath10k_sta_update_rx_tid_stats(struct ath10k *ar, u8 *first_hdr,
206 unsigned long int num_msdus,
207 enum ath10k_pkt_rx_err err,
208 unsigned long int unchain_cnt,
209 unsigned long int drop_cnt,
210 unsigned long int drop_cnt_filter,
211 unsigned long int queued_msdus);
212void ath10k_sta_update_rx_tid_stats_ampdu(struct ath10k *ar,
213 u16 peer_id, u8 tid,
214 struct htt_rx_indication_mpdu_range *ranges,
215 int num_ranges);
194#else 216#else
195static inline 217static inline
196void ath10k_sta_update_rx_duration(struct ath10k *ar, 218void ath10k_sta_update_rx_duration(struct ath10k *ar,
197 struct ath10k_fw_stats *stats) 219 struct ath10k_fw_stats *stats)
198{ 220{
199} 221}
222
223static inline
224void ath10k_sta_update_rx_tid_stats(struct ath10k *ar, u8 *first_hdr,
225 unsigned long int num_msdus,
226 enum ath10k_pkt_rx_err err,
227 unsigned long int unchain_cnt,
228 unsigned long int drop_cnt,
229 unsigned long int drop_cnt_filter,
230 unsigned long int queued_msdus)
231{
232}
233
234static inline
235void ath10k_sta_update_rx_tid_stats_ampdu(struct ath10k *ar,
236 u16 peer_id, u8 tid,
237 struct htt_rx_indication_mpdu_range *ranges,
238 int num_ranges)
239{
240}
200#endif /* CONFIG_MAC80211_DEBUGFS */ 241#endif /* CONFIG_MAC80211_DEBUGFS */
201 242
202#ifdef CONFIG_ATH10K_DEBUG 243#ifdef CONFIG_ATH10K_DEBUG
diff --git a/drivers/net/wireless/ath/ath10k/debugfs_sta.c b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
index b260b09dd4d3..8f688f136c22 100644
--- a/drivers/net/wireless/ath/ath10k/debugfs_sta.c
+++ b/drivers/net/wireless/ath/ath10k/debugfs_sta.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2014-2017 Qualcomm Atheros, Inc. 2 * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
3 * 4 *
4 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -16,8 +17,125 @@
16 17
17#include "core.h" 18#include "core.h"
18#include "wmi-ops.h" 19#include "wmi-ops.h"
20#include "txrx.h"
19#include "debug.h" 21#include "debug.h"
20 22
23static void ath10k_rx_stats_update_amsdu_subfrm(struct ath10k *ar,
24 struct ath10k_sta_tid_stats *stats,
25 u32 msdu_count)
26{
27 if (msdu_count == 1)
28 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_1]++;
29 else if (msdu_count == 2)
30 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_2]++;
31 else if (msdu_count == 3)
32 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_3]++;
33 else if (msdu_count == 4)
34 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_4]++;
35 else if (msdu_count > 4)
36 stats->rx_pkt_amsdu[ATH10K_AMSDU_SUBFRM_NUM_MORE]++;
37}
38
39static void ath10k_rx_stats_update_ampdu_subfrm(struct ath10k *ar,
40 struct ath10k_sta_tid_stats *stats,
41 u32 mpdu_count)
42{
43 if (mpdu_count <= 10)
44 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_10]++;
45 else if (mpdu_count <= 20)
46 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_20]++;
47 else if (mpdu_count <= 30)
48 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_30]++;
49 else if (mpdu_count <= 40)
50 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_40]++;
51 else if (mpdu_count <= 50)
52 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_50]++;
53 else if (mpdu_count <= 60)
54 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_60]++;
55 else if (mpdu_count > 60)
56 stats->rx_pkt_ampdu[ATH10K_AMPDU_SUBFRM_NUM_MORE]++;
57}
58
59void ath10k_sta_update_rx_tid_stats_ampdu(struct ath10k *ar, u16 peer_id, u8 tid,
60 struct htt_rx_indication_mpdu_range *ranges,
61 int num_ranges)
62{
63 struct ath10k_sta *arsta;
64 struct ath10k_peer *peer;
65 int i;
66
67 if (tid > IEEE80211_NUM_TIDS || !(ar->sta_tid_stats_mask & BIT(tid)))
68 return;
69
70 rcu_read_lock();
71 spin_lock_bh(&ar->data_lock);
72
73 peer = ath10k_peer_find_by_id(ar, peer_id);
74 if (!peer)
75 goto out;
76
77 arsta = (struct ath10k_sta *)peer->sta->drv_priv;
78
79 for (i = 0; i < num_ranges; i++)
80 ath10k_rx_stats_update_ampdu_subfrm(ar,
81 &arsta->tid_stats[tid],
82 ranges[i].mpdu_count);
83
84out:
85 spin_unlock_bh(&ar->data_lock);
86 rcu_read_unlock();
87}
88
89void ath10k_sta_update_rx_tid_stats(struct ath10k *ar, u8 *first_hdr,
90 unsigned long int num_msdus,
91 enum ath10k_pkt_rx_err err,
92 unsigned long int unchain_cnt,
93 unsigned long int drop_cnt,
94 unsigned long int drop_cnt_filter,
95 unsigned long int queued_msdus)
96{
97 struct ieee80211_sta *sta;
98 struct ath10k_sta *arsta;
99 struct ieee80211_hdr *hdr;
100 struct ath10k_sta_tid_stats *stats;
101 u8 tid = IEEE80211_NUM_TIDS;
102 bool non_data_frm = false;
103
104 hdr = (struct ieee80211_hdr *)first_hdr;
105 if (!ieee80211_is_data(hdr->frame_control))
106 non_data_frm = true;
107
108 if (ieee80211_is_data_qos(hdr->frame_control))
109 tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
110
111 if (!(ar->sta_tid_stats_mask & BIT(tid)) || non_data_frm)
112 return;
113
114 rcu_read_lock();
115
116 sta = ieee80211_find_sta_by_ifaddr(ar->hw, hdr->addr2, NULL);
117 if (!sta)
118 goto exit;
119
120 arsta = (struct ath10k_sta *)sta->drv_priv;
121
122 spin_lock_bh(&ar->data_lock);
123 stats = &arsta->tid_stats[tid];
124 stats->rx_pkt_from_fw += num_msdus;
125 stats->rx_pkt_unchained += unchain_cnt;
126 stats->rx_pkt_drop_chained += drop_cnt;
127 stats->rx_pkt_drop_filter += drop_cnt_filter;
128 if (err != ATH10K_PKT_RX_ERR_MAX)
129 stats->rx_pkt_err[err] += queued_msdus;
130 stats->rx_pkt_queued_for_mac += queued_msdus;
131 ath10k_rx_stats_update_amsdu_subfrm(ar, &arsta->tid_stats[tid],
132 num_msdus);
133 spin_unlock_bh(&ar->data_lock);
134
135exit:
136 rcu_read_unlock();
137}
138
21static void ath10k_sta_update_extd_stats_rx_duration(struct ath10k *ar, 139static void ath10k_sta_update_extd_stats_rx_duration(struct ath10k *ar,
22 struct ath10k_fw_stats *stats) 140 struct ath10k_fw_stats *stats)
23{ 141{
@@ -342,6 +460,172 @@ static const struct file_operations fops_peer_debug_trigger = {
342 .llseek = default_llseek, 460 .llseek = default_llseek,
343}; 461};
344 462
463static char *get_err_str(enum ath10k_pkt_rx_err i)
464{
465 switch (i) {
466 case ATH10K_PKT_RX_ERR_FCS:
467 return "fcs_err";
468 case ATH10K_PKT_RX_ERR_TKIP:
469 return "tkip_err";
470 case ATH10K_PKT_RX_ERR_CRYPT:
471 return "crypt_err";
472 case ATH10K_PKT_RX_ERR_PEER_IDX_INVAL:
473 return "peer_idx_inval";
474 case ATH10K_PKT_RX_ERR_MAX:
475 return "unknown";
476 }
477
478 return "unknown";
479}
480
481static char *get_num_ampdu_subfrm_str(enum ath10k_ampdu_subfrm_num i)
482{
483 switch (i) {
484 case ATH10K_AMPDU_SUBFRM_NUM_10:
485 return "upto 10";
486 case ATH10K_AMPDU_SUBFRM_NUM_20:
487 return "11-20";
488 case ATH10K_AMPDU_SUBFRM_NUM_30:
489 return "21-30";
490 case ATH10K_AMPDU_SUBFRM_NUM_40:
491 return "31-40";
492 case ATH10K_AMPDU_SUBFRM_NUM_50:
493 return "41-50";
494 case ATH10K_AMPDU_SUBFRM_NUM_60:
495 return "51-60";
496 case ATH10K_AMPDU_SUBFRM_NUM_MORE:
497 return ">60";
498 case ATH10K_AMPDU_SUBFRM_NUM_MAX:
499 return "0";
500 }
501
502 return "0";
503}
504
505static char *get_num_amsdu_subfrm_str(enum ath10k_amsdu_subfrm_num i)
506{
507 switch (i) {
508 case ATH10K_AMSDU_SUBFRM_NUM_1:
509 return "1";
510 case ATH10K_AMSDU_SUBFRM_NUM_2:
511 return "2";
512 case ATH10K_AMSDU_SUBFRM_NUM_3:
513 return "3";
514 case ATH10K_AMSDU_SUBFRM_NUM_4:
515 return "4";
516 case ATH10K_AMSDU_SUBFRM_NUM_MORE:
517 return ">4";
518 case ATH10K_AMSDU_SUBFRM_NUM_MAX:
519 return "0";
520 }
521
522 return "0";
523}
524
525#define PRINT_TID_STATS(_field, _tabs) \
526 do { \
527 int k = 0; \
528 for (j = 0; j <= IEEE80211_NUM_TIDS; j++) { \
529 if (ar->sta_tid_stats_mask & BIT(j)) { \
530 len += scnprintf(buf + len, buf_len - len, \
531 "[%02d] %-10lu ", \
532 j, stats[j]._field); \
533 k++; \
534 if (k % 8 == 0) { \
535 len += scnprintf(buf + len, \
536 buf_len - len, "\n"); \
537 len += scnprintf(buf + len, \
538 buf_len - len, \
539 _tabs); \
540 } \
541 } \
542 } \
543 len += scnprintf(buf + len, buf_len - len, "\n"); \
544 } while (0)
545
546static ssize_t ath10k_dbg_sta_read_tid_stats(struct file *file,
547 char __user *user_buf,
548 size_t count, loff_t *ppos)
549{
550 struct ieee80211_sta *sta = file->private_data;
551 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
552 struct ath10k *ar = arsta->arvif->ar;
553 struct ath10k_sta_tid_stats *stats = arsta->tid_stats;
554 size_t len = 0, buf_len = 1048 * IEEE80211_NUM_TIDS;
555 char *buf;
556 int i, j;
557 ssize_t ret;
558
559 buf = kzalloc(buf_len, GFP_KERNEL);
560 if (!buf)
561 return -ENOMEM;
562
563 mutex_lock(&ar->conf_mutex);
564
565 spin_lock_bh(&ar->data_lock);
566
567 len += scnprintf(buf + len, buf_len - len,
568 "\n\t\tDriver Rx pkt stats per tid, ([tid] count)\n");
569 len += scnprintf(buf + len, buf_len - len,
570 "\t\t------------------------------------------\n");
571 len += scnprintf(buf + len, buf_len - len, "MSDUs from FW\t\t\t");
572 PRINT_TID_STATS(rx_pkt_from_fw, "\t\t\t\t");
573
574 len += scnprintf(buf + len, buf_len - len, "MSDUs unchained\t\t\t");
575 PRINT_TID_STATS(rx_pkt_unchained, "\t\t\t\t");
576
577 len += scnprintf(buf + len, buf_len - len,
578 "MSDUs locally dropped:chained\t");
579 PRINT_TID_STATS(rx_pkt_drop_chained, "\t\t\t\t");
580
581 len += scnprintf(buf + len, buf_len - len,
582 "MSDUs locally dropped:filtered\t");
583 PRINT_TID_STATS(rx_pkt_drop_filter, "\t\t\t\t");
584
585 len += scnprintf(buf + len, buf_len - len,
586 "MSDUs queued for mac80211\t");
587 PRINT_TID_STATS(rx_pkt_queued_for_mac, "\t\t\t\t");
588
589 for (i = 0; i < ATH10K_PKT_RX_ERR_MAX; i++) {
590 len += scnprintf(buf + len, buf_len - len,
591 "MSDUs with error:%s\t", get_err_str(i));
592 PRINT_TID_STATS(rx_pkt_err[i], "\t\t\t\t");
593 }
594
595 len += scnprintf(buf + len, buf_len - len, "\n");
596 for (i = 0; i < ATH10K_AMPDU_SUBFRM_NUM_MAX; i++) {
597 len += scnprintf(buf + len, buf_len - len,
598 "A-MPDU num subframes %s\t",
599 get_num_ampdu_subfrm_str(i));
600 PRINT_TID_STATS(rx_pkt_ampdu[i], "\t\t\t\t");
601 }
602
603 len += scnprintf(buf + len, buf_len - len, "\n");
604 for (i = 0; i < ATH10K_AMSDU_SUBFRM_NUM_MAX; i++) {
605 len += scnprintf(buf + len, buf_len - len,
606 "A-MSDU num subframes %s\t\t",
607 get_num_amsdu_subfrm_str(i));
608 PRINT_TID_STATS(rx_pkt_amsdu[i], "\t\t\t\t");
609 }
610
611 spin_unlock_bh(&ar->data_lock);
612
613 ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
614
615 kfree(buf);
616
617 mutex_unlock(&ar->conf_mutex);
618
619 return ret;
620}
621
622static const struct file_operations fops_tid_stats_dump = {
623 .open = simple_open,
624 .read = ath10k_dbg_sta_read_tid_stats,
625 .owner = THIS_MODULE,
626 .llseek = default_llseek,
627};
628
345void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 629void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
346 struct ieee80211_sta *sta, struct dentry *dir) 630 struct ieee80211_sta *sta, struct dentry *dir)
347{ 631{
@@ -351,4 +635,6 @@ void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
351 debugfs_create_file("delba", 0200, dir, sta, &fops_delba); 635 debugfs_create_file("delba", 0200, dir, sta, &fops_delba);
352 debugfs_create_file("peer_debug_trigger", 0600, dir, sta, 636 debugfs_create_file("peer_debug_trigger", 0600, dir, sta,
353 &fops_peer_debug_trigger); 637 &fops_peer_debug_trigger);
638 debugfs_create_file("dump_tid_stats", 0400, dir, sta,
639 &fops_tid_stats_dump);
354} 640}
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 6d96f9560950..64996aba1485 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc. 2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
4 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 * 5 *
5 * Permission to use, copy, modify, and/or distribute this software for any 6 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
@@ -1502,7 +1503,9 @@ static void ath10k_htt_rx_h_csum_offload(struct sk_buff *msdu)
1502static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, 1503static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
1503 struct sk_buff_head *amsdu, 1504 struct sk_buff_head *amsdu,
1504 struct ieee80211_rx_status *status, 1505 struct ieee80211_rx_status *status,
1505 bool fill_crypt_header) 1506 bool fill_crypt_header,
1507 u8 *rx_hdr,
1508 enum ath10k_pkt_rx_err *err)
1506{ 1509{
1507 struct sk_buff *first; 1510 struct sk_buff *first;
1508 struct sk_buff *last; 1511 struct sk_buff *last;
@@ -1538,6 +1541,9 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
1538 hdr = (void *)rxd->rx_hdr_status; 1541 hdr = (void *)rxd->rx_hdr_status;
1539 memcpy(first_hdr, hdr, RX_HTT_HDR_STATUS_LEN); 1542 memcpy(first_hdr, hdr, RX_HTT_HDR_STATUS_LEN);
1540 1543
1544 if (rx_hdr)
1545 memcpy(rx_hdr, hdr, RX_HTT_HDR_STATUS_LEN);
1546
1541 /* Each A-MSDU subframe will use the original header as the base and be 1547 /* Each A-MSDU subframe will use the original header as the base and be
1542 * reported as a separate MSDU so strip the A-MSDU bit from QoS Ctl. 1548 * reported as a separate MSDU so strip the A-MSDU bit from QoS Ctl.
1543 */ 1549 */
@@ -1581,6 +1587,17 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
1581 if (has_tkip_err) 1587 if (has_tkip_err)
1582 status->flag |= RX_FLAG_MMIC_ERROR; 1588 status->flag |= RX_FLAG_MMIC_ERROR;
1583 1589
1590 if (err) {
1591 if (has_fcs_err)
1592 *err = ATH10K_PKT_RX_ERR_FCS;
1593 else if (has_tkip_err)
1594 *err = ATH10K_PKT_RX_ERR_TKIP;
1595 else if (has_crypto_err)
1596 *err = ATH10K_PKT_RX_ERR_CRYPT;
1597 else if (has_peer_idx_invalid)
1598 *err = ATH10K_PKT_RX_ERR_PEER_IDX_INVAL;
1599 }
1600
1584 /* Firmware reports all necessary management frames via WMI already. 1601 /* Firmware reports all necessary management frames via WMI already.
1585 * They are not reported to monitor interfaces at all so pass the ones 1602 * They are not reported to monitor interfaces at all so pass the ones
1586 * coming via HTT to monitor interfaces instead. This simplifies 1603 * coming via HTT to monitor interfaces instead. This simplifies
@@ -1651,11 +1668,13 @@ static void ath10k_htt_rx_h_enqueue(struct ath10k *ar,
1651 } 1668 }
1652} 1669}
1653 1670
1654static int ath10k_unchain_msdu(struct sk_buff_head *amsdu) 1671static int ath10k_unchain_msdu(struct sk_buff_head *amsdu,
1672 unsigned long int *unchain_cnt)
1655{ 1673{
1656 struct sk_buff *skb, *first; 1674 struct sk_buff *skb, *first;
1657 int space; 1675 int space;
1658 int total_len = 0; 1676 int total_len = 0;
1677 int amsdu_len = skb_queue_len(amsdu);
1659 1678
1660 /* TODO: Might could optimize this by using 1679 /* TODO: Might could optimize this by using
1661 * skb_try_coalesce or similar method to 1680 * skb_try_coalesce or similar method to
@@ -1691,11 +1710,16 @@ static int ath10k_unchain_msdu(struct sk_buff_head *amsdu)
1691 } 1710 }
1692 1711
1693 __skb_queue_head(amsdu, first); 1712 __skb_queue_head(amsdu, first);
1713
1714 *unchain_cnt += amsdu_len - 1;
1715
1694 return 0; 1716 return 0;
1695} 1717}
1696 1718
1697static void ath10k_htt_rx_h_unchain(struct ath10k *ar, 1719static void ath10k_htt_rx_h_unchain(struct ath10k *ar,
1698 struct sk_buff_head *amsdu) 1720 struct sk_buff_head *amsdu,
1721 unsigned long int *drop_cnt,
1722 unsigned long int *unchain_cnt)
1699{ 1723{
1700 struct sk_buff *first; 1724 struct sk_buff *first;
1701 struct htt_rx_desc *rxd; 1725 struct htt_rx_desc *rxd;
@@ -1713,11 +1737,12 @@ static void ath10k_htt_rx_h_unchain(struct ath10k *ar,
1713 */ 1737 */
1714 if (decap != RX_MSDU_DECAP_RAW || 1738 if (decap != RX_MSDU_DECAP_RAW ||
1715 skb_queue_len(amsdu) != 1 + rxd->frag_info.ring2_more_count) { 1739 skb_queue_len(amsdu) != 1 + rxd->frag_info.ring2_more_count) {
1740 *drop_cnt += skb_queue_len(amsdu);
1716 __skb_queue_purge(amsdu); 1741 __skb_queue_purge(amsdu);
1717 return; 1742 return;
1718 } 1743 }
1719 1744
1720 ath10k_unchain_msdu(amsdu); 1745 ath10k_unchain_msdu(amsdu, unchain_cnt);
1721} 1746}
1722 1747
1723static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, 1748static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar,
@@ -1743,7 +1768,8 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar,
1743 1768
1744static void ath10k_htt_rx_h_filter(struct ath10k *ar, 1769static void ath10k_htt_rx_h_filter(struct ath10k *ar,
1745 struct sk_buff_head *amsdu, 1770 struct sk_buff_head *amsdu,
1746 struct ieee80211_rx_status *rx_status) 1771 struct ieee80211_rx_status *rx_status,
1772 unsigned long int *drop_cnt)
1747{ 1773{
1748 if (skb_queue_empty(amsdu)) 1774 if (skb_queue_empty(amsdu))
1749 return; 1775 return;
@@ -1751,6 +1777,9 @@ static void ath10k_htt_rx_h_filter(struct ath10k *ar,
1751 if (ath10k_htt_rx_amsdu_allowed(ar, amsdu, rx_status)) 1777 if (ath10k_htt_rx_amsdu_allowed(ar, amsdu, rx_status))
1752 return; 1778 return;
1753 1779
1780 if (drop_cnt)
1781 *drop_cnt += skb_queue_len(amsdu);
1782
1754 __skb_queue_purge(amsdu); 1783 __skb_queue_purge(amsdu);
1755} 1784}
1756 1785
@@ -1760,6 +1789,12 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt)
1760 struct ieee80211_rx_status *rx_status = &htt->rx_status; 1789 struct ieee80211_rx_status *rx_status = &htt->rx_status;
1761 struct sk_buff_head amsdu; 1790 struct sk_buff_head amsdu;
1762 int ret; 1791 int ret;
1792 unsigned long int drop_cnt = 0;
1793 unsigned long int unchain_cnt = 0;
1794 unsigned long int drop_cnt_filter = 0;
1795 unsigned long int msdus_to_queue, num_msdus;
1796 enum ath10k_pkt_rx_err err = ATH10K_PKT_RX_ERR_MAX;
1797 u8 first_hdr[RX_HTT_HDR_STATUS_LEN];
1763 1798
1764 __skb_queue_head_init(&amsdu); 1799 __skb_queue_head_init(&amsdu);
1765 1800
@@ -1781,16 +1816,23 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt)
1781 return ret; 1816 return ret;
1782 } 1817 }
1783 1818
1819 num_msdus = skb_queue_len(&amsdu);
1820
1784 ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff); 1821 ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff);
1785 1822
1786 /* only for ret = 1 indicates chained msdus */ 1823 /* only for ret = 1 indicates chained msdus */
1787 if (ret > 0) 1824 if (ret > 0)
1788 ath10k_htt_rx_h_unchain(ar, &amsdu); 1825 ath10k_htt_rx_h_unchain(ar, &amsdu, &drop_cnt, &unchain_cnt);
1789 1826
1790 ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); 1827 ath10k_htt_rx_h_filter(ar, &amsdu, rx_status, &drop_cnt_filter);
1791 ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true); 1828 ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status, true, first_hdr, &err);
1829 msdus_to_queue = skb_queue_len(&amsdu);
1792 ath10k_htt_rx_h_enqueue(ar, &amsdu, rx_status); 1830 ath10k_htt_rx_h_enqueue(ar, &amsdu, rx_status);
1793 1831
1832 ath10k_sta_update_rx_tid_stats(ar, first_hdr, num_msdus, err,
1833 unchain_cnt, drop_cnt, drop_cnt_filter,
1834 msdus_to_queue);
1835
1794 return 0; 1836 return 0;
1795} 1837}
1796 1838
@@ -1801,9 +1843,14 @@ static void ath10k_htt_rx_proc_rx_ind(struct ath10k_htt *htt,
1801 struct htt_rx_indication_mpdu_range *mpdu_ranges; 1843 struct htt_rx_indication_mpdu_range *mpdu_ranges;
1802 int num_mpdu_ranges; 1844 int num_mpdu_ranges;
1803 int i, mpdu_count = 0; 1845 int i, mpdu_count = 0;
1846 u16 peer_id;
1847 u8 tid;
1804 1848
1805 num_mpdu_ranges = MS(__le32_to_cpu(rx->hdr.info1), 1849 num_mpdu_ranges = MS(__le32_to_cpu(rx->hdr.info1),
1806 HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES); 1850 HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES);
1851 peer_id = __le16_to_cpu(rx->hdr.peer_id);
1852 tid = MS(rx->hdr.info0, HTT_RX_INDICATION_INFO0_EXT_TID);
1853
1807 mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx); 1854 mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx);
1808 1855
1809 ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ", 1856 ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ",
@@ -1815,6 +1862,9 @@ static void ath10k_htt_rx_proc_rx_ind(struct ath10k_htt *htt,
1815 mpdu_count += mpdu_ranges[i].mpdu_count; 1862 mpdu_count += mpdu_ranges[i].mpdu_count;
1816 1863
1817 atomic_add(mpdu_count, &htt->num_mpdus_ready); 1864 atomic_add(mpdu_count, &htt->num_mpdus_ready);
1865
1866 ath10k_sta_update_rx_tid_stats_ampdu(ar, peer_id, tid, mpdu_ranges,
1867 num_mpdu_ranges);
1818} 1868}
1819 1869
1820static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar, 1870static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar,
@@ -2124,8 +2174,9 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
2124 * should still give an idea about rx rate to the user. 2174 * should still give an idea about rx rate to the user.
2125 */ 2175 */
2126 ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id); 2176 ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id);
2127 ath10k_htt_rx_h_filter(ar, &amsdu, status); 2177 ath10k_htt_rx_h_filter(ar, &amsdu, status, NULL);
2128 ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false); 2178 ath10k_htt_rx_h_mpdu(ar, &amsdu, status, false, NULL,
2179 NULL);
2129 ath10k_htt_rx_h_enqueue(ar, &amsdu, status); 2180 ath10k_htt_rx_h_enqueue(ar, &amsdu, status);
2130 break; 2181 break;
2131 case -EAGAIN: 2182 case -EAGAIN:
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index ebb3f1b046f3..02674ee04435 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc. 2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
4 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 * 5 *
5 * Permission to use, copy, modify, and/or distribute this software for any 6 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
@@ -3808,6 +3809,7 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3808{ 3809{
3809 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work); 3810 struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work);
3810 struct sk_buff *skb; 3811 struct sk_buff *skb;
3812 dma_addr_t paddr;
3811 int ret; 3813 int ret;
3812 3814
3813 for (;;) { 3815 for (;;) {
@@ -3815,11 +3817,27 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
3815 if (!skb) 3817 if (!skb)
3816 break; 3818 break;
3817 3819
3818 ret = ath10k_wmi_mgmt_tx(ar, skb); 3820 if (test_bit(ATH10K_FW_FEATURE_MGMT_TX_BY_REF,
3819 if (ret) { 3821 ar->running_fw->fw_file.fw_features)) {
3820 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n", 3822 paddr = dma_map_single(ar->dev, skb->data,
3821 ret); 3823 skb->len, DMA_TO_DEVICE);
3822 ieee80211_free_txskb(ar->hw, skb); 3824 if (!paddr)
3825 continue;
3826 ret = ath10k_wmi_mgmt_tx_send(ar, skb, paddr);
3827 if (ret) {
3828 ath10k_warn(ar, "failed to transmit management frame by ref via WMI: %d\n",
3829 ret);
3830 dma_unmap_single(ar->dev, paddr, skb->len,
3831 DMA_FROM_DEVICE);
3832 ieee80211_free_txskb(ar->hw, skb);
3833 }
3834 } else {
3835 ret = ath10k_wmi_mgmt_tx(ar, skb);
3836 if (ret) {
3837 ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
3838 ret);
3839 ieee80211_free_txskb(ar->hw, skb);
3840 }
3823 } 3841 }
3824 } 3842 }
3825} 3843}
@@ -7085,10 +7103,20 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
7085{ 7103{
7086 struct ath10k *ar = hw->priv; 7104 struct ath10k *ar = hw->priv;
7087 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; 7105 struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
7106 struct ath10k_vif *arvif = (void *)vif->drv_priv;
7107 struct ath10k_peer *peer;
7088 u32 bw, smps; 7108 u32 bw, smps;
7089 7109
7090 spin_lock_bh(&ar->data_lock); 7110 spin_lock_bh(&ar->data_lock);
7091 7111
7112 peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
7113 if (!peer) {
7114 spin_unlock_bh(&ar->data_lock);
7115 ath10k_warn(ar, "mac sta rc update failed to find peer %pM on vdev %i\n",
7116 sta->addr, arvif->vdev_id);
7117 return;
7118 }
7119
7092 ath10k_dbg(ar, ATH10K_DBG_MAC, 7120 ath10k_dbg(ar, ATH10K_DBG_MAC,
7093 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n", 7121 "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
7094 sta->addr, changed, sta->bandwidth, sta->rx_nss, 7122 sta->addr, changed, sta->bandwidth, sta->rx_nss,
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 1b266cd0c2ec..808f3d67ba90 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -2221,7 +2221,7 @@ static int ath10k_pci_get_num_banks(struct ath10k *ar)
2221 } 2221 }
2222 break; 2222 break;
2223 case QCA9377_1_0_DEVICE_ID: 2223 case QCA9377_1_0_DEVICE_ID:
2224 return 4; 2224 return 9;
2225 } 2225 }
2226 2226
2227 ath10k_warn(ar, "unknown number of banks, assuming 1\n"); 2227 ath10k_warn(ar, "unknown number of banks, assuming 1\n");
diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h
index e40edced1d82..7d2fac342150 100644
--- a/drivers/net/wireless/ath/ath10k/trace.h
+++ b/drivers/net/wireless/ath/ath10k/trace.h
@@ -152,10 +152,9 @@ TRACE_EVENT(ath10k_log_dbg_dump,
152); 152);
153 153
154TRACE_EVENT(ath10k_wmi_cmd, 154TRACE_EVENT(ath10k_wmi_cmd,
155 TP_PROTO(struct ath10k *ar, int id, const void *buf, size_t buf_len, 155 TP_PROTO(struct ath10k *ar, int id, const void *buf, size_t buf_len),
156 int ret),
157 156
158 TP_ARGS(ar, id, buf, buf_len, ret), 157 TP_ARGS(ar, id, buf, buf_len),
159 158
160 TP_STRUCT__entry( 159 TP_STRUCT__entry(
161 __string(device, dev_name(ar->dev)) 160 __string(device, dev_name(ar->dev))
@@ -163,7 +162,6 @@ TRACE_EVENT(ath10k_wmi_cmd,
163 __field(unsigned int, id) 162 __field(unsigned int, id)
164 __field(size_t, buf_len) 163 __field(size_t, buf_len)
165 __dynamic_array(u8, buf, buf_len) 164 __dynamic_array(u8, buf, buf_len)
166 __field(int, ret)
167 ), 165 ),
168 166
169 TP_fast_assign( 167 TP_fast_assign(
@@ -171,17 +169,15 @@ TRACE_EVENT(ath10k_wmi_cmd,
171 __assign_str(driver, dev_driver_string(ar->dev)); 169 __assign_str(driver, dev_driver_string(ar->dev));
172 __entry->id = id; 170 __entry->id = id;
173 __entry->buf_len = buf_len; 171 __entry->buf_len = buf_len;
174 __entry->ret = ret;
175 memcpy(__get_dynamic_array(buf), buf, buf_len); 172 memcpy(__get_dynamic_array(buf), buf, buf_len);
176 ), 173 ),
177 174
178 TP_printk( 175 TP_printk(
179 "%s %s id %d len %zu ret %d", 176 "%s %s id %d len %zu",
180 __get_str(driver), 177 __get_str(driver),
181 __get_str(device), 178 __get_str(device),
182 __entry->id, 179 __entry->id,
183 __entry->buf_len, 180 __entry->buf_len
184 __entry->ret
185 ) 181 )
186); 182);
187 183
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
index 5b3b021526ab..70e23bbf7171 100644
--- a/drivers/net/wireless/ath/ath10k/txrx.c
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
@@ -102,11 +102,6 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
102 memset(&info->status, 0, sizeof(info->status)); 102 memset(&info->status, 0, sizeof(info->status));
103 trace_ath10k_txrx_tx_unref(ar, tx_done->msdu_id); 103 trace_ath10k_txrx_tx_unref(ar, tx_done->msdu_id);
104 104
105 if (tx_done->status == HTT_TX_COMPL_STATE_DISCARD) {
106 ieee80211_free_txskb(htt->ar->hw, msdu);
107 return 0;
108 }
109
110 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) 105 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
111 info->flags |= IEEE80211_TX_STAT_ACK; 106 info->flags |= IEEE80211_TX_STAT_ACK;
112 107
@@ -117,6 +112,13 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
117 (info->flags & IEEE80211_TX_CTL_NO_ACK)) 112 (info->flags & IEEE80211_TX_CTL_NO_ACK))
118 info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED; 113 info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
119 114
115 if (tx_done->status == HTT_TX_COMPL_STATE_DISCARD) {
116 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
117 info->flags &= ~IEEE80211_TX_STAT_NOACK_TRANSMITTED;
118 else
119 info->flags &= ~IEEE80211_TX_STAT_ACK;
120 }
121
120 ieee80211_tx_status(htt->ar->hw, msdu); 122 ieee80211_tx_status(htt->ar->hw, msdu);
121 /* we do not own the msdu anymore */ 123 /* we do not own the msdu anymore */
122 124
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
index 14093cfdc505..c35e45340b4f 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc. 2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
4 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 * 5 *
5 * Permission to use, copy, modify, and/or distribute this software for any 6 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
@@ -125,6 +126,9 @@ struct wmi_ops {
125 enum wmi_force_fw_hang_type type, 126 enum wmi_force_fw_hang_type type,
126 u32 delay_ms); 127 u32 delay_ms);
127 struct sk_buff *(*gen_mgmt_tx)(struct ath10k *ar, struct sk_buff *skb); 128 struct sk_buff *(*gen_mgmt_tx)(struct ath10k *ar, struct sk_buff *skb);
129 struct sk_buff *(*gen_mgmt_tx_send)(struct ath10k *ar,
130 struct sk_buff *skb,
131 dma_addr_t paddr);
128 struct sk_buff *(*gen_dbglog_cfg)(struct ath10k *ar, u64 module_enable, 132 struct sk_buff *(*gen_dbglog_cfg)(struct ath10k *ar, u64 module_enable,
129 u32 log_level); 133 u32 log_level);
130 struct sk_buff *(*gen_pktlog_enable)(struct ath10k *ar, u32 filter); 134 struct sk_buff *(*gen_pktlog_enable)(struct ath10k *ar, u32 filter);
@@ -197,6 +201,9 @@ struct wmi_ops {
197 (struct ath10k *ar, 201 (struct ath10k *ar,
198 enum wmi_bss_survey_req_type type); 202 enum wmi_bss_survey_req_type type);
199 struct sk_buff *(*gen_echo)(struct ath10k *ar, u32 value); 203 struct sk_buff *(*gen_echo)(struct ath10k *ar, u32 value);
204 struct sk_buff *(*gen_pdev_get_tpc_table_cmdid)(struct ath10k *ar,
205 u32 param);
206
200}; 207};
201 208
202int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); 209int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -372,12 +379,33 @@ ath10k_wmi_get_txbf_conf_scheme(struct ath10k *ar)
372} 379}
373 380
374static inline int 381static inline int
382ath10k_wmi_mgmt_tx_send(struct ath10k *ar, struct sk_buff *msdu,
383 dma_addr_t paddr)
384{
385 struct sk_buff *skb;
386 int ret;
387
388 if (!ar->wmi.ops->gen_mgmt_tx_send)
389 return -EOPNOTSUPP;
390
391 skb = ar->wmi.ops->gen_mgmt_tx_send(ar, msdu, paddr);
392 if (IS_ERR(skb))
393 return PTR_ERR(skb);
394
395 ret = ath10k_wmi_cmd_send(ar, skb,
396 ar->wmi.cmd->mgmt_tx_send_cmdid);
397 if (ret)
398 return ret;
399
400 return 0;
401}
402
403static inline int
375ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) 404ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
376{ 405{
377 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu); 406 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
378 struct sk_buff *skb; 407 struct sk_buff *skb;
379 int ret; 408 int ret;
380 u32 mgmt_tx_cmdid;
381 409
382 if (!ar->wmi.ops->gen_mgmt_tx) 410 if (!ar->wmi.ops->gen_mgmt_tx)
383 return -EOPNOTSUPP; 411 return -EOPNOTSUPP;
@@ -386,13 +414,8 @@ ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
386 if (IS_ERR(skb)) 414 if (IS_ERR(skb))
387 return PTR_ERR(skb); 415 return PTR_ERR(skb);
388 416
389 if (test_bit(ATH10K_FW_FEATURE_MGMT_TX_BY_REF, 417 ret = ath10k_wmi_cmd_send(ar, skb,
390 ar->running_fw->fw_file.fw_features)) 418 ar->wmi.cmd->mgmt_tx_cmdid);
391 mgmt_tx_cmdid = ar->wmi.cmd->mgmt_tx_send_cmdid;
392 else
393 mgmt_tx_cmdid = ar->wmi.cmd->mgmt_tx_cmdid;
394
395 ret = ath10k_wmi_cmd_send(ar, skb, mgmt_tx_cmdid);
396 if (ret) 419 if (ret)
397 return ret; 420 return ret;
398 421
@@ -1425,4 +1448,21 @@ ath10k_wmi_echo(struct ath10k *ar, u32 value)
1425 return ath10k_wmi_cmd_send(ar, skb, wmi->cmd->echo_cmdid); 1448 return ath10k_wmi_cmd_send(ar, skb, wmi->cmd->echo_cmdid);
1426} 1449}
1427 1450
1451static inline int
1452ath10k_wmi_pdev_get_tpc_table_cmdid(struct ath10k *ar, u32 param)
1453{
1454 struct sk_buff *skb;
1455
1456 if (!ar->wmi.ops->gen_pdev_get_tpc_table_cmdid)
1457 return -EOPNOTSUPP;
1458
1459 skb = ar->wmi.ops->gen_pdev_get_tpc_table_cmdid(ar, param);
1460
1461 if (IS_ERR(skb))
1462 return PTR_ERR(skb);
1463
1464 return ath10k_wmi_cmd_send(ar, skb,
1465 ar->wmi.cmd->pdev_get_tpc_table_cmdid);
1466}
1467
1428#endif 1468#endif
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
index ae77a007ae07..523af3f8bb62 100644
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc. 2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
4 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 * 5 *
5 * Permission to use, copy, modify, and/or distribute this software for any 6 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
@@ -2484,19 +2485,19 @@ ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, u32 stats_mask)
2484} 2485}
2485 2486
2486static struct sk_buff * 2487static struct sk_buff *
2487ath10k_wmi_tlv_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) 2488ath10k_wmi_tlv_op_gen_mgmt_tx_send(struct ath10k *ar, struct sk_buff *msdu,
2489 dma_addr_t paddr)
2488{ 2490{
2489 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu); 2491 struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
2490 struct wmi_tlv_mgmt_tx_cmd *cmd; 2492 struct wmi_tlv_mgmt_tx_cmd *cmd;
2491 struct wmi_tlv *tlv;
2492 struct ieee80211_hdr *hdr; 2493 struct ieee80211_hdr *hdr;
2494 struct ath10k_vif *arvif;
2495 u32 buf_len = msdu->len;
2496 struct wmi_tlv *tlv;
2493 struct sk_buff *skb; 2497 struct sk_buff *skb;
2498 u32 vdev_id;
2494 void *ptr; 2499 void *ptr;
2495 int len; 2500 int len;
2496 u32 buf_len = msdu->len;
2497 struct ath10k_vif *arvif;
2498 dma_addr_t mgmt_frame_dma;
2499 u32 vdev_id;
2500 2501
2501 if (!cb->vif) 2502 if (!cb->vif)
2502 return ERR_PTR(-EINVAL); 2503 return ERR_PTR(-EINVAL);
@@ -2537,12 +2538,7 @@ ath10k_wmi_tlv_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
2537 cmd->chanfreq = 0; 2538 cmd->chanfreq = 0;
2538 cmd->buf_len = __cpu_to_le32(buf_len); 2539 cmd->buf_len = __cpu_to_le32(buf_len);
2539 cmd->frame_len = __cpu_to_le32(msdu->len); 2540 cmd->frame_len = __cpu_to_le32(msdu->len);
2540 mgmt_frame_dma = dma_map_single(arvif->ar->dev, msdu->data, 2541 cmd->paddr = __cpu_to_le64(paddr);
2541 msdu->len, DMA_TO_DEVICE);
2542 if (!mgmt_frame_dma)
2543 return ERR_PTR(-ENOMEM);
2544
2545 cmd->paddr = __cpu_to_le64(mgmt_frame_dma);
2546 2542
2547 ptr += sizeof(*tlv); 2543 ptr += sizeof(*tlv);
2548 ptr += sizeof(*cmd); 2544 ptr += sizeof(*cmd);
@@ -3701,7 +3697,7 @@ static const struct wmi_ops wmi_tlv_ops = {
3701 .gen_request_stats = ath10k_wmi_tlv_op_gen_request_stats, 3697 .gen_request_stats = ath10k_wmi_tlv_op_gen_request_stats,
3702 .gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang, 3698 .gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang,
3703 /* .gen_mgmt_tx = not implemented; HTT is used */ 3699 /* .gen_mgmt_tx = not implemented; HTT is used */
3704 .gen_mgmt_tx = ath10k_wmi_tlv_op_gen_mgmt_tx, 3700 .gen_mgmt_tx_send = ath10k_wmi_tlv_op_gen_mgmt_tx_send,
3705 .gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg, 3701 .gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg,
3706 .gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable, 3702 .gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable,
3707 .gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable, 3703 .gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable,
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 58dc2189ba49..9649bb752bbd 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc. 2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
4 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 * 5 *
5 * Permission to use, copy, modify, and/or distribute this software for any 6 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
@@ -196,6 +197,7 @@ static struct wmi_cmd_map wmi_cmd_map = {
196 .mu_cal_start_cmdid = WMI_CMD_UNSUPPORTED, 197 .mu_cal_start_cmdid = WMI_CMD_UNSUPPORTED,
197 .set_cca_params_cmdid = WMI_CMD_UNSUPPORTED, 198 .set_cca_params_cmdid = WMI_CMD_UNSUPPORTED,
198 .pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED, 199 .pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED,
200 .pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
199}; 201};
200 202
201/* 10.X WMI cmd track */ 203/* 10.X WMI cmd track */
@@ -362,6 +364,7 @@ static struct wmi_cmd_map wmi_10x_cmd_map = {
362 .mu_cal_start_cmdid = WMI_CMD_UNSUPPORTED, 364 .mu_cal_start_cmdid = WMI_CMD_UNSUPPORTED,
363 .set_cca_params_cmdid = WMI_CMD_UNSUPPORTED, 365 .set_cca_params_cmdid = WMI_CMD_UNSUPPORTED,
364 .pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED, 366 .pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED,
367 .pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
365}; 368};
366 369
367/* 10.2.4 WMI cmd track */ 370/* 10.2.4 WMI cmd track */
@@ -528,6 +531,7 @@ static struct wmi_cmd_map wmi_10_2_4_cmd_map = {
528 .set_cca_params_cmdid = WMI_CMD_UNSUPPORTED, 531 .set_cca_params_cmdid = WMI_CMD_UNSUPPORTED,
529 .pdev_bss_chan_info_request_cmdid = 532 .pdev_bss_chan_info_request_cmdid =
530 WMI_10_2_PDEV_BSS_CHAN_INFO_REQUEST_CMDID, 533 WMI_10_2_PDEV_BSS_CHAN_INFO_REQUEST_CMDID,
534 .pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
531}; 535};
532 536
533/* 10.4 WMI cmd track */ 537/* 10.4 WMI cmd track */
@@ -1480,6 +1484,7 @@ static struct wmi_cmd_map wmi_10_2_cmd_map = {
1480 .pdev_get_ani_cck_config_cmdid = WMI_CMD_UNSUPPORTED, 1484 .pdev_get_ani_cck_config_cmdid = WMI_CMD_UNSUPPORTED,
1481 .pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED, 1485 .pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED,
1482 .pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED, 1486 .pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED,
1487 .pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
1483}; 1488};
1484 1489
1485static struct wmi_pdev_param_map wmi_10_4_pdev_param_map = { 1490static struct wmi_pdev_param_map wmi_10_4_pdev_param_map = {
@@ -1742,8 +1747,8 @@ int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb,
1742 cmd_hdr->cmd_id = __cpu_to_le32(cmd); 1747 cmd_hdr->cmd_id = __cpu_to_le32(cmd);
1743 1748
1744 memset(skb_cb, 0, sizeof(*skb_cb)); 1749 memset(skb_cb, 0, sizeof(*skb_cb));
1750 trace_ath10k_wmi_cmd(ar, cmd_id, skb->data, skb->len);
1745 ret = ath10k_htc_send(&ar->htc, ar->wmi.eid, skb); 1751 ret = ath10k_htc_send(&ar->htc, ar->wmi.eid, skb);
1746 trace_ath10k_wmi_cmd(ar, cmd_id, skb->data, skb->len, ret);
1747 1752
1748 if (ret) 1753 if (ret)
1749 goto err_pull; 1754 goto err_pull;
@@ -4313,19 +4318,11 @@ static void ath10k_tpc_config_disp_tables(struct ath10k *ar,
4313 } 4318 }
4314} 4319}
4315 4320
4316void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb) 4321void ath10k_wmi_tpc_config_get_rate_code(u8 *rate_code, u16 *pream_table,
4322 u32 num_tx_chain)
4317{ 4323{
4318 u32 i, j, pream_idx, num_tx_chain; 4324 u32 i, j, pream_idx;
4319 u8 rate_code[WMI_TPC_RATE_MAX], rate_idx; 4325 u8 rate_idx;
4320 u16 pream_table[WMI_TPC_PREAM_TABLE_MAX];
4321 struct wmi_pdev_tpc_config_event *ev;
4322 struct ath10k_tpc_stats *tpc_stats;
4323
4324 ev = (struct wmi_pdev_tpc_config_event *)skb->data;
4325
4326 tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC);
4327 if (!tpc_stats)
4328 return;
4329 4326
4330 /* Create the rate code table based on the chains supported */ 4327 /* Create the rate code table based on the chains supported */
4331 rate_idx = 0; 4328 rate_idx = 0;
@@ -4349,8 +4346,6 @@ void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb)
4349 pream_table[pream_idx] = rate_idx; 4346 pream_table[pream_idx] = rate_idx;
4350 pream_idx++; 4347 pream_idx++;
4351 4348
4352 num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
4353
4354 /* Fill HT20 rate code */ 4349 /* Fill HT20 rate code */
4355 for (i = 0; i < num_tx_chain; i++) { 4350 for (i = 0; i < num_tx_chain; i++) {
4356 for (j = 0; j < 8; j++) { 4351 for (j = 0; j < 8; j++) {
@@ -4374,7 +4369,7 @@ void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb)
4374 pream_idx++; 4369 pream_idx++;
4375 4370
4376 /* Fill VHT20 rate code */ 4371 /* Fill VHT20 rate code */
4377 for (i = 0; i < __le32_to_cpu(ev->num_tx_chain); i++) { 4372 for (i = 0; i < num_tx_chain; i++) {
4378 for (j = 0; j < 10; j++) { 4373 for (j = 0; j < 10; j++) {
4379 rate_code[rate_idx] = 4374 rate_code[rate_idx] =
4380 ATH10K_HW_RATECODE(j, i, WMI_RATE_PREAMBLE_VHT); 4375 ATH10K_HW_RATECODE(j, i, WMI_RATE_PREAMBLE_VHT);
@@ -4418,6 +4413,26 @@ void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb)
4418 ATH10K_HW_RATECODE(0, 0, WMI_RATE_PREAMBLE_OFDM); 4413 ATH10K_HW_RATECODE(0, 0, WMI_RATE_PREAMBLE_OFDM);
4419 4414
4420 pream_table[pream_idx] = ATH10K_TPC_PREAM_TABLE_END; 4415 pream_table[pream_idx] = ATH10K_TPC_PREAM_TABLE_END;
4416}
4417
4418void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb)
4419{
4420 u32 num_tx_chain;
4421 u8 rate_code[WMI_TPC_RATE_MAX];
4422 u16 pream_table[WMI_TPC_PREAM_TABLE_MAX];
4423 struct wmi_pdev_tpc_config_event *ev;
4424 struct ath10k_tpc_stats *tpc_stats;
4425
4426 ev = (struct wmi_pdev_tpc_config_event *)skb->data;
4427
4428 tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC);
4429 if (!tpc_stats)
4430 return;
4431
4432 num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
4433
4434 ath10k_wmi_tpc_config_get_rate_code(rate_code, pream_table,
4435 num_tx_chain);
4421 4436
4422 tpc_stats->chan_freq = __le32_to_cpu(ev->chan_freq); 4437 tpc_stats->chan_freq = __le32_to_cpu(ev->chan_freq);
4423 tpc_stats->phy_mode = __le32_to_cpu(ev->phy_mode); 4438 tpc_stats->phy_mode = __le32_to_cpu(ev->phy_mode);
@@ -4457,6 +4472,246 @@ void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb)
4457 __le32_to_cpu(ev->rate_max)); 4472 __le32_to_cpu(ev->rate_max));
4458} 4473}
4459 4474
4475static u8
4476ath10k_wmi_tpc_final_get_rate(struct ath10k *ar,
4477 struct wmi_pdev_tpc_final_table_event *ev,
4478 u32 rate_idx, u32 num_chains,
4479 u32 rate_code, u8 type, u32 pream_idx)
4480{
4481 u8 tpc, num_streams, preamble, ch, stm_idx;
4482 s8 pow_agcdd, pow_agstbc, pow_agtxbf;
4483 int pream;
4484
4485 num_streams = ATH10K_HW_NSS(rate_code);
4486 preamble = ATH10K_HW_PREAMBLE(rate_code);
4487 ch = num_chains - 1;
4488 stm_idx = num_streams - 1;
4489 pream = -1;
4490
4491 if (__le32_to_cpu(ev->chan_freq) <= 2483) {
4492 switch (pream_idx) {
4493 case WMI_TPC_PREAM_2GHZ_CCK:
4494 pream = 0;
4495 break;
4496 case WMI_TPC_PREAM_2GHZ_OFDM:
4497 pream = 1;
4498 break;
4499 case WMI_TPC_PREAM_2GHZ_HT20:
4500 case WMI_TPC_PREAM_2GHZ_VHT20:
4501 pream = 2;
4502 break;
4503 case WMI_TPC_PREAM_2GHZ_HT40:
4504 case WMI_TPC_PREAM_2GHZ_VHT40:
4505 pream = 3;
4506 break;
4507 case WMI_TPC_PREAM_2GHZ_VHT80:
4508 pream = 4;
4509 break;
4510 default:
4511 pream = -1;
4512 break;
4513 }
4514 }
4515
4516 if (__le32_to_cpu(ev->chan_freq) >= 5180) {
4517 switch (pream_idx) {
4518 case WMI_TPC_PREAM_5GHZ_OFDM:
4519 pream = 0;
4520 break;
4521 case WMI_TPC_PREAM_5GHZ_HT20:
4522 case WMI_TPC_PREAM_5GHZ_VHT20:
4523 pream = 1;
4524 break;
4525 case WMI_TPC_PREAM_5GHZ_HT40:
4526 case WMI_TPC_PREAM_5GHZ_VHT40:
4527 pream = 2;
4528 break;
4529 case WMI_TPC_PREAM_5GHZ_VHT80:
4530 pream = 3;
4531 break;
4532 case WMI_TPC_PREAM_5GHZ_HTCUP:
4533 pream = 4;
4534 break;
4535 default:
4536 pream = -1;
4537 break;
4538 }
4539 }
4540
4541 if (pream == 4)
4542 tpc = min_t(u8, ev->rates_array[rate_idx],
4543 ev->max_reg_allow_pow[ch]);
4544 else
4545 tpc = min_t(u8, min_t(u8, ev->rates_array[rate_idx],
4546 ev->max_reg_allow_pow[ch]),
4547 ev->ctl_power_table[0][pream][stm_idx]);
4548
4549 if (__le32_to_cpu(ev->num_tx_chain) <= 1)
4550 goto out;
4551
4552 if (preamble == WMI_RATE_PREAMBLE_CCK)
4553 goto out;
4554
4555 if (num_chains <= num_streams)
4556 goto out;
4557
4558 switch (type) {
4559 case WMI_TPC_TABLE_TYPE_STBC:
4560 pow_agstbc = ev->max_reg_allow_pow_agstbc[ch - 1][stm_idx];
4561 if (pream == 4)
4562 tpc = min_t(u8, tpc, pow_agstbc);
4563 else
4564 tpc = min_t(u8, min_t(u8, tpc, pow_agstbc),
4565 ev->ctl_power_table[0][pream][stm_idx]);
4566 break;
4567 case WMI_TPC_TABLE_TYPE_TXBF:
4568 pow_agtxbf = ev->max_reg_allow_pow_agtxbf[ch - 1][stm_idx];
4569 if (pream == 4)
4570 tpc = min_t(u8, tpc, pow_agtxbf);
4571 else
4572 tpc = min_t(u8, min_t(u8, tpc, pow_agtxbf),
4573 ev->ctl_power_table[1][pream][stm_idx]);
4574 break;
4575 case WMI_TPC_TABLE_TYPE_CDD:
4576 pow_agcdd = ev->max_reg_allow_pow_agcdd[ch - 1][stm_idx];
4577 if (pream == 4)
4578 tpc = min_t(u8, tpc, pow_agcdd);
4579 else
4580 tpc = min_t(u8, min_t(u8, tpc, pow_agcdd),
4581 ev->ctl_power_table[0][pream][stm_idx]);
4582 break;
4583 default:
4584 ath10k_warn(ar, "unknown wmi tpc final table type: %d\n", type);
4585 tpc = 0;
4586 break;
4587 }
4588
4589out:
4590 return tpc;
4591}
4592
4593static void
4594ath10k_wmi_tpc_stats_final_disp_tables(struct ath10k *ar,
4595 struct wmi_pdev_tpc_final_table_event *ev,
4596 struct ath10k_tpc_stats_final *tpc_stats,
4597 u8 *rate_code, u16 *pream_table, u8 type)
4598{
4599 u32 i, j, pream_idx, flags;
4600 u8 tpc[WMI_TPC_TX_N_CHAIN];
4601 char tpc_value[WMI_TPC_TX_N_CHAIN * WMI_TPC_BUF_SIZE];
4602 char buff[WMI_TPC_BUF_SIZE];
4603
4604 flags = __le32_to_cpu(ev->flags);
4605
4606 switch (type) {
4607 case WMI_TPC_TABLE_TYPE_CDD:
4608 if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_CDD)) {
4609 ath10k_dbg(ar, ATH10K_DBG_WMI, "CDD not supported\n");
4610 tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
4611 return;
4612 }
4613 break;
4614 case WMI_TPC_TABLE_TYPE_STBC:
4615 if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_STBC)) {
4616 ath10k_dbg(ar, ATH10K_DBG_WMI, "STBC not supported\n");
4617 tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
4618 return;
4619 }
4620 break;
4621 case WMI_TPC_TABLE_TYPE_TXBF:
4622 if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_TXBF)) {
4623 ath10k_dbg(ar, ATH10K_DBG_WMI, "TXBF not supported\n");
4624 tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
4625 return;
4626 }
4627 break;
4628 default:
4629 ath10k_dbg(ar, ATH10K_DBG_WMI,
4630 "invalid table type in wmi tpc event: %d\n", type);
4631 return;
4632 }
4633
4634 pream_idx = 0;
4635 for (i = 0; i < __le32_to_cpu(ev->rate_max); i++) {
4636 memset(tpc_value, 0, sizeof(tpc_value));
4637 memset(buff, 0, sizeof(buff));
4638 if (i == pream_table[pream_idx])
4639 pream_idx++;
4640
4641 for (j = 0; j < WMI_TPC_TX_N_CHAIN; j++) {
4642 if (j >= __le32_to_cpu(ev->num_tx_chain))
4643 break;
4644
4645 tpc[j] = ath10k_wmi_tpc_final_get_rate(ar, ev, i, j + 1,
4646 rate_code[i],
4647 type, pream_idx);
4648 snprintf(buff, sizeof(buff), "%8d ", tpc[j]);
4649 strncat(tpc_value, buff, strlen(buff));
4650 }
4651 tpc_stats->tpc_table_final[type].pream_idx[i] = pream_idx;
4652 tpc_stats->tpc_table_final[type].rate_code[i] = rate_code[i];
4653 memcpy(tpc_stats->tpc_table_final[type].tpc_value[i],
4654 tpc_value, sizeof(tpc_value));
4655 }
4656}
4657
4658void ath10k_wmi_event_tpc_final_table(struct ath10k *ar, struct sk_buff *skb)
4659{
4660 u32 num_tx_chain;
4661 u8 rate_code[WMI_TPC_FINAL_RATE_MAX];
4662 u16 pream_table[WMI_TPC_PREAM_TABLE_MAX];
4663 struct wmi_pdev_tpc_final_table_event *ev;
4664 struct ath10k_tpc_stats_final *tpc_stats;
4665
4666 ev = (struct wmi_pdev_tpc_final_table_event *)skb->data;
4667
4668 tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC);
4669 if (!tpc_stats)
4670 return;
4671
4672 num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
4673
4674 ath10k_wmi_tpc_config_get_rate_code(rate_code, pream_table,
4675 num_tx_chain);
4676
4677 tpc_stats->chan_freq = __le32_to_cpu(ev->chan_freq);
4678 tpc_stats->phy_mode = __le32_to_cpu(ev->phy_mode);
4679 tpc_stats->ctl = __le32_to_cpu(ev->ctl);
4680 tpc_stats->reg_domain = __le32_to_cpu(ev->reg_domain);
4681 tpc_stats->twice_antenna_gain = a_sle32_to_cpu(ev->twice_antenna_gain);
4682 tpc_stats->twice_antenna_reduction =
4683 __le32_to_cpu(ev->twice_antenna_reduction);
4684 tpc_stats->power_limit = __le32_to_cpu(ev->power_limit);
4685 tpc_stats->twice_max_rd_power = __le32_to_cpu(ev->twice_max_rd_power);
4686 tpc_stats->num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
4687 tpc_stats->rate_max = __le32_to_cpu(ev->rate_max);
4688
4689 ath10k_wmi_tpc_stats_final_disp_tables(ar, ev, tpc_stats,
4690 rate_code, pream_table,
4691 WMI_TPC_TABLE_TYPE_CDD);
4692 ath10k_wmi_tpc_stats_final_disp_tables(ar, ev, tpc_stats,
4693 rate_code, pream_table,
4694 WMI_TPC_TABLE_TYPE_STBC);
4695 ath10k_wmi_tpc_stats_final_disp_tables(ar, ev, tpc_stats,
4696 rate_code, pream_table,
4697 WMI_TPC_TABLE_TYPE_TXBF);
4698
4699 ath10k_debug_tpc_stats_final_process(ar, tpc_stats);
4700
4701 ath10k_dbg(ar, ATH10K_DBG_WMI,
4702 "wmi event tpc final table channel %d mode %d ctl %d regd %d gain %d %d limit %d max_power %d tx_chanins %d rates %d\n",
4703 __le32_to_cpu(ev->chan_freq),
4704 __le32_to_cpu(ev->phy_mode),
4705 __le32_to_cpu(ev->ctl),
4706 __le32_to_cpu(ev->reg_domain),
4707 a_sle32_to_cpu(ev->twice_antenna_gain),
4708 __le32_to_cpu(ev->twice_antenna_reduction),
4709 __le32_to_cpu(ev->power_limit),
4710 __le32_to_cpu(ev->twice_max_rd_power) / 2,
4711 __le32_to_cpu(ev->num_tx_chain),
4712 __le32_to_cpu(ev->rate_max));
4713}
4714
4460static void 4715static void
4461ath10k_wmi_handle_tdls_peer_event(struct ath10k *ar, struct sk_buff *skb) 4716ath10k_wmi_handle_tdls_peer_event(struct ath10k *ar, struct sk_buff *skb)
4462{ 4717{
@@ -5549,6 +5804,9 @@ static void ath10k_wmi_10_4_op_rx(struct ath10k *ar, struct sk_buff *skb)
5549 case WMI_10_4_TDLS_PEER_EVENTID: 5804 case WMI_10_4_TDLS_PEER_EVENTID:
5550 ath10k_wmi_handle_tdls_peer_event(ar, skb); 5805 ath10k_wmi_handle_tdls_peer_event(ar, skb);
5551 break; 5806 break;
5807 case WMI_10_4_PDEV_TPC_TABLE_EVENTID:
5808 ath10k_wmi_event_tpc_final_table(ar, skb);
5809 break;
5552 default: 5810 default:
5553 ath10k_warn(ar, "Unknown eventid: %d\n", id); 5811 ath10k_warn(ar, "Unknown eventid: %d\n", id);
5554 break; 5812 break;
@@ -7990,6 +8248,24 @@ static u32 ath10k_wmi_prepare_peer_qos(u8 uapsd_queues, u8 sp)
7990} 8248}
7991 8249
7992static struct sk_buff * 8250static struct sk_buff *
8251ath10k_wmi_10_4_op_gen_pdev_get_tpc_table_cmdid(struct ath10k *ar, u32 param)
8252{
8253 struct wmi_pdev_get_tpc_table_cmd *cmd;
8254 struct sk_buff *skb;
8255
8256 skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
8257 if (!skb)
8258 return ERR_PTR(-ENOMEM);
8259
8260 cmd = (struct wmi_pdev_get_tpc_table_cmd *)skb->data;
8261 cmd->param = __cpu_to_le32(param);
8262
8263 ath10k_dbg(ar, ATH10K_DBG_WMI,
8264 "wmi pdev get tpc table param:%d\n", param);
8265 return skb;
8266}
8267
8268static struct sk_buff *
7993ath10k_wmi_10_4_gen_tdls_peer_update(struct ath10k *ar, 8269ath10k_wmi_10_4_gen_tdls_peer_update(struct ath10k *ar,
7994 const struct wmi_tdls_peer_update_cmd_arg *arg, 8270 const struct wmi_tdls_peer_update_cmd_arg *arg,
7995 const struct wmi_tdls_peer_capab_arg *cap, 8271 const struct wmi_tdls_peer_capab_arg *cap,
@@ -8430,6 +8706,8 @@ static const struct wmi_ops wmi_10_4_ops = {
8430 .ext_resource_config = ath10k_wmi_10_4_ext_resource_config, 8706 .ext_resource_config = ath10k_wmi_10_4_ext_resource_config,
8431 .gen_update_fw_tdls_state = ath10k_wmi_10_4_gen_update_fw_tdls_state, 8707 .gen_update_fw_tdls_state = ath10k_wmi_10_4_gen_update_fw_tdls_state,
8432 .gen_tdls_peer_update = ath10k_wmi_10_4_gen_tdls_peer_update, 8708 .gen_tdls_peer_update = ath10k_wmi_10_4_gen_tdls_peer_update,
8709 .gen_pdev_get_tpc_table_cmdid =
8710 ath10k_wmi_10_4_op_gen_pdev_get_tpc_table_cmdid,
8433 8711
8434 /* shared with 10.2 */ 8712 /* shared with 10.2 */
8435 .pull_echo_ev = ath10k_wmi_op_pull_echo_ev, 8713 .pull_echo_ev = ath10k_wmi_op_pull_echo_ev,
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index c7b30ed9015d..c8fc45d8090e 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2005-2011 Atheros Communications Inc. 2 * Copyright (c) 2005-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 3 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
4 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 * 5 *
5 * Permission to use, copy, modify, and/or distribute this software for any 6 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
@@ -197,6 +198,9 @@ enum wmi_service {
197 WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, 198 WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
198 WMI_SERVICE_MGMT_TX_WMI, 199 WMI_SERVICE_MGMT_TX_WMI,
199 WMI_SERVICE_TDLS_WIDER_BANDWIDTH, 200 WMI_SERVICE_TDLS_WIDER_BANDWIDTH,
201 WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
202 WMI_SERVICE_HOST_DFS_CHECK_SUPPORT,
203 WMI_SERVICE_TPC_STATS_FINAL,
200 204
201 /* keep last */ 205 /* keep last */
202 WMI_SERVICE_MAX, 206 WMI_SERVICE_MAX,
@@ -339,6 +343,9 @@ enum wmi_10_4_service {
339 WMI_10_4_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE, 343 WMI_10_4_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
340 WMI_10_4_SERVICE_TDLS_EXPLICIT_MODE_ONLY, 344 WMI_10_4_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
341 WMI_10_4_SERVICE_TDLS_WIDER_BANDWIDTH, 345 WMI_10_4_SERVICE_TDLS_WIDER_BANDWIDTH,
346 WMI_10_4_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
347 WMI_10_4_SERVICE_HOST_DFS_CHECK_SUPPORT,
348 WMI_10_4_SERVICE_TPC_STATS_FINAL,
342}; 349};
343 350
344static inline char *wmi_service_name(int service_id) 351static inline char *wmi_service_name(int service_id)
@@ -448,6 +455,9 @@ static inline char *wmi_service_name(int service_id)
448 SVCSTR(WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE); 455 SVCSTR(WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE);
449 SVCSTR(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY); 456 SVCSTR(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY);
450 SVCSTR(WMI_SERVICE_TDLS_WIDER_BANDWIDTH); 457 SVCSTR(WMI_SERVICE_TDLS_WIDER_BANDWIDTH);
458 SVCSTR(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS);
459 SVCSTR(WMI_SERVICE_HOST_DFS_CHECK_SUPPORT);
460 SVCSTR(WMI_SERVICE_TPC_STATS_FINAL);
451 default: 461 default:
452 return NULL; 462 return NULL;
453 } 463 }
@@ -746,6 +756,12 @@ static inline void wmi_10_4_svc_map(const __le32 *in, unsigned long *out,
746 WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, len); 756 WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, len);
747 SVCMAP(WMI_10_4_SERVICE_TDLS_WIDER_BANDWIDTH, 757 SVCMAP(WMI_10_4_SERVICE_TDLS_WIDER_BANDWIDTH,
748 WMI_SERVICE_TDLS_WIDER_BANDWIDTH, len); 758 WMI_SERVICE_TDLS_WIDER_BANDWIDTH, len);
759 SVCMAP(WMI_10_4_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
760 WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, len);
761 SVCMAP(WMI_10_4_SERVICE_HOST_DFS_CHECK_SUPPORT,
762 WMI_SERVICE_HOST_DFS_CHECK_SUPPORT, len);
763 SVCMAP(WMI_10_4_SERVICE_TPC_STATS_FINAL,
764 WMI_SERVICE_TPC_STATS_FINAL, len);
749} 765}
750 766
751#undef SVCMAP 767#undef SVCMAP
@@ -3993,10 +4009,12 @@ struct wmi_pdev_get_tpc_config_cmd {
3993 4009
3994#define WMI_TPC_CONFIG_PARAM 1 4010#define WMI_TPC_CONFIG_PARAM 1
3995#define WMI_TPC_RATE_MAX 160 4011#define WMI_TPC_RATE_MAX 160
4012#define WMI_TPC_FINAL_RATE_MAX 240
3996#define WMI_TPC_TX_N_CHAIN 4 4013#define WMI_TPC_TX_N_CHAIN 4
3997#define WMI_TPC_PREAM_TABLE_MAX 10 4014#define WMI_TPC_PREAM_TABLE_MAX 10
3998#define WMI_TPC_FLAG 3 4015#define WMI_TPC_FLAG 3
3999#define WMI_TPC_BUF_SIZE 10 4016#define WMI_TPC_BUF_SIZE 10
4017#define WMI_TPC_BEAMFORMING 2
4000 4018
4001enum wmi_tpc_table_type { 4019enum wmi_tpc_table_type {
4002 WMI_TPC_TABLE_TYPE_CDD = 0, 4020 WMI_TPC_TABLE_TYPE_CDD = 0,
@@ -4039,6 +4057,51 @@ enum wmi_tp_scale {
4039 WMI_TP_SCALE_SIZE = 5, /* max num of enum */ 4057 WMI_TP_SCALE_SIZE = 5, /* max num of enum */
4040}; 4058};
4041 4059
4060struct wmi_pdev_tpc_final_table_event {
4061 __le32 reg_domain;
4062 __le32 chan_freq;
4063 __le32 phy_mode;
4064 __le32 twice_antenna_reduction;
4065 __le32 twice_max_rd_power;
4066 a_sle32 twice_antenna_gain;
4067 __le32 power_limit;
4068 __le32 rate_max;
4069 __le32 num_tx_chain;
4070 __le32 ctl;
4071 __le32 flags;
4072 s8 max_reg_allow_pow[WMI_TPC_TX_N_CHAIN];
4073 s8 max_reg_allow_pow_agcdd[WMI_TPC_TX_N_CHAIN][WMI_TPC_TX_N_CHAIN];
4074 s8 max_reg_allow_pow_agstbc[WMI_TPC_TX_N_CHAIN][WMI_TPC_TX_N_CHAIN];
4075 s8 max_reg_allow_pow_agtxbf[WMI_TPC_TX_N_CHAIN][WMI_TPC_TX_N_CHAIN];
4076 u8 rates_array[WMI_TPC_FINAL_RATE_MAX];
4077 u8 ctl_power_table[WMI_TPC_BEAMFORMING][WMI_TPC_TX_N_CHAIN]
4078 [WMI_TPC_TX_N_CHAIN];
4079} __packed;
4080
4081struct wmi_pdev_get_tpc_table_cmd {
4082 __le32 param;
4083} __packed;
4084
4085enum wmi_tpc_pream_2ghz {
4086 WMI_TPC_PREAM_2GHZ_CCK = 0,
4087 WMI_TPC_PREAM_2GHZ_OFDM,
4088 WMI_TPC_PREAM_2GHZ_HT20,
4089 WMI_TPC_PREAM_2GHZ_HT40,
4090 WMI_TPC_PREAM_2GHZ_VHT20,
4091 WMI_TPC_PREAM_2GHZ_VHT40,
4092 WMI_TPC_PREAM_2GHZ_VHT80,
4093};
4094
4095enum wmi_tpc_pream_5ghz {
4096 WMI_TPC_PREAM_5GHZ_OFDM = 1,
4097 WMI_TPC_PREAM_5GHZ_HT20,
4098 WMI_TPC_PREAM_5GHZ_HT40,
4099 WMI_TPC_PREAM_5GHZ_VHT20,
4100 WMI_TPC_PREAM_5GHZ_VHT40,
4101 WMI_TPC_PREAM_5GHZ_VHT80,
4102 WMI_TPC_PREAM_5GHZ_HTCUP,
4103};
4104
4042struct wmi_pdev_chanlist_update_event { 4105struct wmi_pdev_chanlist_update_event {
4043 /* number of channels */ 4106 /* number of channels */
4044 __le32 num_chan; 4107 __le32 num_chan;
@@ -6979,5 +7042,8 @@ void ath10k_wmi_10_4_op_fw_stats_fill(struct ath10k *ar,
6979int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar, 7042int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar,
6980 enum wmi_vdev_subtype subtype); 7043 enum wmi_vdev_subtype subtype);
6981int ath10k_wmi_barrier(struct ath10k *ar); 7044int ath10k_wmi_barrier(struct ath10k *ar);
7045void ath10k_wmi_tpc_config_get_rate_code(u8 *rate_code, u16 *pream_table,
7046 u32 num_tx_chain);
7047void ath10k_wmi_event_tpc_final_table(struct ath10k *ar, struct sk_buff *skb);
6982 7048
6983#endif /* _WMI_H_ */ 7049#endif /* _WMI_H_ */
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index beda11ce34a7..147947f632f7 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -327,8 +327,6 @@ ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
327 327
328 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); 328 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
329 329
330 tq = &ah->ah_txq[queue];
331
332 /* Skip if queue inactive or if we are on AR5210 330 /* Skip if queue inactive or if we are on AR5210
333 * that doesn't have QCU/DCU */ 331 * that doesn't have QCU/DCU */
334 if ((ah->ah_version == AR5K_AR5210) || 332 if ((ah->ah_version == AR5K_AR5210) ||
diff --git a/drivers/net/wireless/ath/ath9k/common-init.c b/drivers/net/wireless/ath/ath9k/common-init.c
index 8b4f7fdabf58..82de0fadbc95 100644
--- a/drivers/net/wireless/ath/ath9k/common-init.c
+++ b/drivers/net/wireless/ath/ath9k/common-init.c
@@ -88,7 +88,7 @@ static const struct ieee80211_channel ath9k_5ghz_chantable[] = {
88 CHAN5G(5825, 37), /* Channel 165 */ 88 CHAN5G(5825, 37), /* Channel 165 */
89}; 89};
90 90
91/* Atheros hardware rate code addition for short premble */ 91/* Atheros hardware rate code addition for short preamble */
92#define SHPCHECK(__hw_rate, __flags) \ 92#define SHPCHECK(__hw_rate, __flags) \
93 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0) 93 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
94 94
diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.c b/drivers/net/wireless/ath/ath9k/common-spectral.c
index 5e77fe1f5b0d..a41bcbda1d9e 100644
--- a/drivers/net/wireless/ath/ath9k/common-spectral.c
+++ b/drivers/net/wireless/ath/ath9k/common-spectral.c
@@ -479,14 +479,16 @@ ath_cmn_is_fft_buf_full(struct ath_spec_scan_priv *spec_priv)
479{ 479{
480 int i = 0; 480 int i = 0;
481 int ret = 0; 481 int ret = 0;
482 struct rchan_buf *buf;
482 struct rchan *rc = spec_priv->rfs_chan_spec_scan; 483 struct rchan *rc = spec_priv->rfs_chan_spec_scan;
483 484
484 for_each_online_cpu(i) 485 for_each_possible_cpu(i) {
485 ret += relay_buf_full(*per_cpu_ptr(rc->buf, i)); 486 if ((buf = *per_cpu_ptr(rc->buf, i))) {
486 487 ret += relay_buf_full(buf);
487 i = num_online_cpus(); 488 }
489 }
488 490
489 if (ret == i) 491 if (ret)
490 return 1; 492 return 1;
491 else 493 else
492 return 0; 494 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index cd0f023ccf77..6b37036b2d36 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -184,7 +184,8 @@ u16 ath9k_hw_computetxtime(struct ath_hw *ah,
184 break; 184 break;
185 case WLAN_RC_PHY_OFDM: 185 case WLAN_RC_PHY_OFDM:
186 if (ah->curchan && IS_CHAN_QUARTER_RATE(ah->curchan)) { 186 if (ah->curchan && IS_CHAN_QUARTER_RATE(ah->curchan)) {
187 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000; 187 bitsPerSymbol =
188 ((kbps >> 2) * OFDM_SYMBOL_TIME_QUARTER) / 1000;
188 numBits = OFDM_PLCP_BITS + (frameLen << 3); 189 numBits = OFDM_PLCP_BITS + (frameLen << 3);
189 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol); 190 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
190 txTime = OFDM_SIFS_TIME_QUARTER 191 txTime = OFDM_SIFS_TIME_QUARTER
@@ -192,7 +193,8 @@ u16 ath9k_hw_computetxtime(struct ath_hw *ah,
192 + (numSymbols * OFDM_SYMBOL_TIME_QUARTER); 193 + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
193 } else if (ah->curchan && 194 } else if (ah->curchan &&
194 IS_CHAN_HALF_RATE(ah->curchan)) { 195 IS_CHAN_HALF_RATE(ah->curchan)) {
195 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000; 196 bitsPerSymbol =
197 ((kbps >> 1) * OFDM_SYMBOL_TIME_HALF) / 1000;
196 numBits = OFDM_PLCP_BITS + (frameLen << 3); 198 numBits = OFDM_PLCP_BITS + (frameLen << 3);
197 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol); 199 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
198 txTime = OFDM_SIFS_TIME_HALF + 200 txTime = OFDM_SIFS_TIME_HALF +
@@ -1036,7 +1038,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
1036 int acktimeout, ctstimeout, ack_offset = 0; 1038 int acktimeout, ctstimeout, ack_offset = 0;
1037 int slottime; 1039 int slottime;
1038 int sifstime; 1040 int sifstime;
1039 int rx_lat = 0, tx_lat = 0, eifs = 0; 1041 int rx_lat = 0, tx_lat = 0, eifs = 0, ack_shift = 0;
1040 u32 reg; 1042 u32 reg;
1041 1043
1042 ath_dbg(ath9k_hw_common(ah), RESET, "ah->misc_mode 0x%x\n", 1044 ath_dbg(ath9k_hw_common(ah), RESET, "ah->misc_mode 0x%x\n",
@@ -1068,6 +1070,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
1068 1070
1069 sifstime = 32; 1071 sifstime = 32;
1070 ack_offset = 16; 1072 ack_offset = 16;
1073 ack_shift = 3;
1071 slottime = 13; 1074 slottime = 13;
1072 } else if (IS_CHAN_QUARTER_RATE(chan)) { 1075 } else if (IS_CHAN_QUARTER_RATE(chan)) {
1073 eifs = 340; 1076 eifs = 340;
@@ -1078,6 +1081,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
1078 1081
1079 sifstime = 64; 1082 sifstime = 64;
1080 ack_offset = 32; 1083 ack_offset = 32;
1084 ack_shift = 1;
1081 slottime = 21; 1085 slottime = 21;
1082 } else { 1086 } else {
1083 if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) { 1087 if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) {
@@ -1134,6 +1138,10 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
1134 SM(tx_lat, AR_USEC_TX_LAT), 1138 SM(tx_lat, AR_USEC_TX_LAT),
1135 AR_USEC_TX_LAT | AR_USEC_RX_LAT | AR_USEC_USEC); 1139 AR_USEC_TX_LAT | AR_USEC_RX_LAT | AR_USEC_USEC);
1136 1140
1141 if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))
1142 REG_RMW(ah, AR_TXSIFS,
1143 sifstime | SM(ack_shift, AR_TXSIFS_ACK_SHIFT),
1144 (AR_TXSIFS_TIME | AR_TXSIFS_ACK_SHIFT));
1137} 1145}
1138EXPORT_SYMBOL(ath9k_hw_init_global_settings); 1146EXPORT_SYMBOL(ath9k_hw_init_global_settings);
1139 1147
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 396bf05c6bf6..d8b041f48ca8 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2892,6 +2892,8 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
2892 struct ath_txq *txq; 2892 struct ath_txq *txq;
2893 int tidno; 2893 int tidno;
2894 2894
2895 rcu_read_lock();
2896
2895 for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { 2897 for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
2896 tid = ath_node_to_tid(an, tidno); 2898 tid = ath_node_to_tid(an, tidno);
2897 txq = tid->txq; 2899 txq = tid->txq;
@@ -2909,6 +2911,8 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
2909 if (!an->sta) 2911 if (!an->sta)
2910 break; /* just one multicast ath_atx_tid */ 2912 break; /* just one multicast ath_atx_tid */
2911 } 2913 }
2914
2915 rcu_read_unlock();
2912} 2916}
2913 2917
2914#ifdef CONFIG_ATH9K_TX99 2918#ifdef CONFIG_ATH9K_TX99
diff --git a/drivers/net/wireless/ath/dfs_pattern_detector.c b/drivers/net/wireless/ath/dfs_pattern_detector.c
index 4100ffd42a43..448b83eea810 100644
--- a/drivers/net/wireless/ath/dfs_pattern_detector.c
+++ b/drivers/net/wireless/ath/dfs_pattern_detector.c
@@ -115,7 +115,7 @@ static const struct radar_detector_specs jp_radar_ref_types[] = {
115 JP_PATTERN(4, 0, 5, 150, 230, 1, 23, 50, false), 115 JP_PATTERN(4, 0, 5, 150, 230, 1, 23, 50, false),
116 JP_PATTERN(5, 6, 10, 200, 500, 1, 16, 50, false), 116 JP_PATTERN(5, 6, 10, 200, 500, 1, 16, 50, false),
117 JP_PATTERN(6, 11, 20, 200, 500, 1, 12, 50, false), 117 JP_PATTERN(6, 11, 20, 200, 500, 1, 12, 50, false),
118 JP_PATTERN(7, 50, 100, 1000, 2000, 1, 3, 50, false), 118 JP_PATTERN(7, 50, 100, 1000, 2000, 1, 3, 50, true),
119 JP_PATTERN(5, 0, 1, 333, 333, 1, 9, 50, false), 119 JP_PATTERN(5, 0, 1, 333, 333, 1, 9, 50, false),
120}; 120};
121 121
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c
index a3f1f7d042a4..7d5ecaf02288 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -376,7 +376,7 @@ static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch)
376 spin_lock_irqsave(&ch->lock, flags); 376 spin_lock_irqsave(&ch->lock, flags);
377 ctl = ch->tail_blk_ctl; 377 ctl = ch->tail_blk_ctl;
378 do { 378 do {
379 if (ctl->desc->ctrl & WCN36XX_DXE_CTRL_VALID_MASK) 379 if (ctl->desc->ctrl & WCN36xx_DXE_CTRL_VLD)
380 break; 380 break;
381 if (ctl->skb) { 381 if (ctl->skb) {
382 dma_unmap_single(wcn->dev, ctl->desc->src_addr_l, 382 dma_unmap_single(wcn->dev, ctl->desc->src_addr_l,
@@ -397,7 +397,7 @@ static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch)
397 } 397 }
398 ctl = ctl->next; 398 ctl = ctl->next;
399 } while (ctl != ch->head_blk_ctl && 399 } while (ctl != ch->head_blk_ctl &&
400 !(ctl->desc->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)); 400 !(ctl->desc->ctrl & WCN36xx_DXE_CTRL_VLD));
401 401
402 ch->tail_blk_ctl = ctl; 402 ch->tail_blk_ctl = ctl;
403 spin_unlock_irqrestore(&ch->lock, flags); 403 spin_unlock_irqrestore(&ch->lock, flags);
@@ -415,14 +415,31 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
415 WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_H, 415 WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_H,
416 &int_reason); 416 &int_reason);
417 417
418 /* TODO: Check int_reason */
419
420 wcn36xx_dxe_write_register(wcn, 418 wcn36xx_dxe_write_register(wcn,
421 WCN36XX_DXE_0_INT_CLR, 419 WCN36XX_DXE_0_INT_CLR,
422 WCN36XX_INT_MASK_CHAN_TX_H); 420 WCN36XX_INT_MASK_CHAN_TX_H);
423 421
424 wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_ED_CLR, 422 if (int_reason & WCN36XX_CH_STAT_INT_ERR_MASK ) {
425 WCN36XX_INT_MASK_CHAN_TX_H); 423 wcn36xx_dxe_write_register(wcn,
424 WCN36XX_DXE_0_INT_ERR_CLR,
425 WCN36XX_INT_MASK_CHAN_TX_H);
426
427 wcn36xx_err("DXE IRQ reported error: 0x%x in high TX channel\n",
428 int_src);
429 }
430
431 if (int_reason & WCN36XX_CH_STAT_INT_DONE_MASK) {
432 wcn36xx_dxe_write_register(wcn,
433 WCN36XX_DXE_0_INT_DONE_CLR,
434 WCN36XX_INT_MASK_CHAN_TX_H);
435 }
436
437 if (int_reason & WCN36XX_CH_STAT_INT_ED_MASK) {
438 wcn36xx_dxe_write_register(wcn,
439 WCN36XX_DXE_0_INT_ED_CLR,
440 WCN36XX_INT_MASK_CHAN_TX_H);
441 }
442
426 wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready high\n"); 443 wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready high\n");
427 reap_tx_dxes(wcn, &wcn->dxe_tx_h_ch); 444 reap_tx_dxes(wcn, &wcn->dxe_tx_h_ch);
428 } 445 }
@@ -431,14 +448,33 @@ static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev)
431 wcn36xx_dxe_read_register(wcn, 448 wcn36xx_dxe_read_register(wcn,
432 WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_L, 449 WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_L,
433 &int_reason); 450 &int_reason);
434 /* TODO: Check int_reason */
435 451
436 wcn36xx_dxe_write_register(wcn, 452 wcn36xx_dxe_write_register(wcn,
437 WCN36XX_DXE_0_INT_CLR, 453 WCN36XX_DXE_0_INT_CLR,
438 WCN36XX_INT_MASK_CHAN_TX_L); 454 WCN36XX_INT_MASK_CHAN_TX_L);
439 455
440 wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_ED_CLR, 456
441 WCN36XX_INT_MASK_CHAN_TX_L); 457 if (int_reason & WCN36XX_CH_STAT_INT_ERR_MASK ) {
458 wcn36xx_dxe_write_register(wcn,
459 WCN36XX_DXE_0_INT_ERR_CLR,
460 WCN36XX_INT_MASK_CHAN_TX_L);
461
462 wcn36xx_err("DXE IRQ reported error: 0x%x in low TX channel\n",
463 int_src);
464 }
465
466 if (int_reason & WCN36XX_CH_STAT_INT_DONE_MASK) {
467 wcn36xx_dxe_write_register(wcn,
468 WCN36XX_DXE_0_INT_DONE_CLR,
469 WCN36XX_INT_MASK_CHAN_TX_L);
470 }
471
472 if (int_reason & WCN36XX_CH_STAT_INT_ED_MASK) {
473 wcn36xx_dxe_write_register(wcn,
474 WCN36XX_DXE_0_INT_ED_CLR,
475 WCN36XX_INT_MASK_CHAN_TX_L);
476 }
477
442 wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready low\n"); 478 wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready low\n");
443 reap_tx_dxes(wcn, &wcn->dxe_tx_l_ch); 479 reap_tx_dxes(wcn, &wcn->dxe_tx_l_ch);
444 } 480 }
@@ -503,7 +539,7 @@ static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn,
503 int_mask = WCN36XX_DXE_INT_CH3_MASK; 539 int_mask = WCN36XX_DXE_INT_CH3_MASK;
504 } 540 }
505 541
506 while (!(dxe->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)) { 542 while (!(dxe->ctrl & WCN36xx_DXE_CTRL_VLD)) {
507 skb = ctl->skb; 543 skb = ctl->skb;
508 dma_addr = dxe->dst_addr_l; 544 dma_addr = dxe->dst_addr_l;
509 ret = wcn36xx_dxe_fill_skb(wcn->dev, ctl); 545 ret = wcn36xx_dxe_fill_skb(wcn->dev, ctl);
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.h b/drivers/net/wireless/ath/wcn36xx/dxe.h
index c012e807753b..2bc376c5391b 100644
--- a/drivers/net/wireless/ath/wcn36xx/dxe.h
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.h
@@ -33,15 +33,106 @@ H2H_TEST_RX_TX = DMA2
33#define WCN36XX_CCU_DXE_INT_SELECT_RIVA 0x310 33#define WCN36XX_CCU_DXE_INT_SELECT_RIVA 0x310
34#define WCN36XX_CCU_DXE_INT_SELECT_PRONTO 0x10dc 34#define WCN36XX_CCU_DXE_INT_SELECT_PRONTO 0x10dc
35 35
36/* TODO This must calculated properly but not hardcoded */ 36/* Descriptor valid */
37#define WCN36XX_DXE_CTRL_TX_L 0x328a44 37#define WCN36xx_DXE_CTRL_VLD BIT(0)
38#define WCN36XX_DXE_CTRL_TX_H 0x32ce44 38/* End of packet */
39#define WCN36XX_DXE_CTRL_RX_L 0x12ad2f 39#define WCN36xx_DXE_CTRL_EOP BIT(3)
40#define WCN36XX_DXE_CTRL_RX_H 0x12d12f 40/* BD handling bit */
41#define WCN36XX_DXE_CTRL_TX_H_BD 0x30ce45 41#define WCN36xx_DXE_CTRL_BDH BIT(4)
42#define WCN36XX_DXE_CTRL_TX_H_SKB 0x32ce4d 42/* Source is a queue */
43#define WCN36XX_DXE_CTRL_TX_L_BD 0x308a45 43#define WCN36xx_DXE_CTRL_SIQ BIT(5)
44#define WCN36XX_DXE_CTRL_TX_L_SKB 0x328a4d 44/* Destination is a queue */
45#define WCN36xx_DXE_CTRL_DIQ BIT(6)
46/* Pointer address is a queue */
47#define WCN36xx_DXE_CTRL_PIQ BIT(7)
48/* Release PDU when done */
49#define WCN36xx_DXE_CTRL_PDU_REL BIT(8)
50/* STOP channel processing */
51#define WCN36xx_DXE_CTRL_STOP BIT(16)
52/* INT on descriptor done */
53#define WCN36xx_DXE_CTRL_INT BIT(17)
54/* Endian byte swap enable */
55#define WCN36xx_DXE_CTRL_SWAP BIT(20)
56/* Master endianness */
57#define WCN36xx_DXE_CTRL_ENDIANNESS BIT(21)
58
59/* Transfer type */
60#define WCN36xx_DXE_CTRL_XTYPE_SHIFT 1
61#define WCN36xx_DXE_CTRL_XTYPE_MASK GENMASK(2, WCN36xx_DXE_CTRL_XTYPE_SHIFT)
62#define WCN36xx_DXE_CTRL_XTYPE_SET(x) ((x) << WCN36xx_DXE_CTRL_XTYPE_SHIFT)
63
64/* BMU Threshold select */
65#define WCN36xx_DXE_CTRL_BTHLD_SEL_SHIFT 9
66#define WCN36xx_DXE_CTRL_BTHLD_SEL_MASK GENMASK(12, WCN36xx_DXE_CTRL_BTHLD_SEL_SHIFT)
67#define WCN36xx_DXE_CTRL_BTHLD_SEL_SET(x) ((x) << WCN36xx_DXE_CTRL_BTHLD_SEL_SHIFT)
68
69/* Priority */
70#define WCN36xx_DXE_CTRL_PRIO_SHIFT 13
71#define WCN36xx_DXE_CTRL_PRIO_MASK GENMASK(15, WCN36xx_DXE_CTRL_PRIO_SHIFT)
72#define WCN36xx_DXE_CTRL_PRIO_SET(x) ((x) << WCN36xx_DXE_CTRL_PRIO_SHIFT)
73
74/* BD Template index */
75#define WCN36xx_DXE_CTRL_BDT_IDX_SHIFT 18
76#define WCN36xx_DXE_CTRL_BDT_IDX_MASK GENMASK(19, WCN36xx_DXE_CTRL_BDT_IDX_SHIFT)
77#define WCN36xx_DXE_CTRL_BDT_IDX_SET(x) ((x) << WCN36xx_DXE_CTRL_BDT_IDX_SHIFT)
78
79/* Transfer types: */
80/* Host to host */
81#define WCN36xx_DXE_XTYPE_H2H (0)
82/* Host to BMU */
83#define WCN36xx_DXE_XTYPE_H2B (2)
84/* BMU to host */
85#define WCN36xx_DXE_XTYPE_B2H (3)
86
87#define WCN36XX_DXE_CTRL_TX_L (WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
88 WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(5) | \
89 WCN36xx_DXE_CTRL_PRIO_SET(4) | WCN36xx_DXE_CTRL_INT | \
90 WCN36xx_DXE_CTRL_SWAP | WCN36xx_DXE_CTRL_ENDIANNESS)
91
92#define WCN36XX_DXE_CTRL_TX_H (WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
93 WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(7) | \
94 WCN36xx_DXE_CTRL_PRIO_SET(6) | WCN36xx_DXE_CTRL_INT | \
95 WCN36xx_DXE_CTRL_SWAP | WCN36xx_DXE_CTRL_ENDIANNESS)
96
97#define WCN36XX_DXE_CTRL_RX_L (WCN36xx_DXE_CTRL_VLD | \
98 WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \
99 WCN36xx_DXE_CTRL_EOP | WCN36xx_DXE_CTRL_SIQ | \
100 WCN36xx_DXE_CTRL_PDU_REL | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(6) | \
101 WCN36xx_DXE_CTRL_PRIO_SET(5) | WCN36xx_DXE_CTRL_INT | \
102 WCN36xx_DXE_CTRL_SWAP)
103
104#define WCN36XX_DXE_CTRL_RX_H (WCN36xx_DXE_CTRL_VLD | \
105 WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \
106 WCN36xx_DXE_CTRL_EOP | WCN36xx_DXE_CTRL_SIQ | \
107 WCN36xx_DXE_CTRL_PDU_REL | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(8) | \
108 WCN36xx_DXE_CTRL_PRIO_SET(6) | WCN36xx_DXE_CTRL_INT | \
109 WCN36xx_DXE_CTRL_SWAP)
110
111#define WCN36XX_DXE_CTRL_TX_H_BD (WCN36xx_DXE_CTRL_VLD | \
112 WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
113 WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(7) | \
114 WCN36xx_DXE_CTRL_PRIO_SET(6) | WCN36xx_DXE_CTRL_SWAP | \
115 WCN36xx_DXE_CTRL_ENDIANNESS)
116
117#define WCN36XX_DXE_CTRL_TX_H_SKB (WCN36xx_DXE_CTRL_VLD | \
118 WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
119 WCN36xx_DXE_CTRL_EOP | WCN36xx_DXE_CTRL_DIQ | \
120 WCN36xx_DXE_CTRL_BTHLD_SEL_SET(7) | WCN36xx_DXE_CTRL_PRIO_SET(6) | \
121 WCN36xx_DXE_CTRL_INT | WCN36xx_DXE_CTRL_SWAP | \
122 WCN36xx_DXE_CTRL_ENDIANNESS)
123
124#define WCN36XX_DXE_CTRL_TX_L_BD (WCN36xx_DXE_CTRL_VLD | \
125 WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
126 WCN36xx_DXE_CTRL_DIQ | WCN36xx_DXE_CTRL_BTHLD_SEL_SET(5) | \
127 WCN36xx_DXE_CTRL_PRIO_SET(4) | WCN36xx_DXE_CTRL_SWAP | \
128 WCN36xx_DXE_CTRL_ENDIANNESS)
129
130#define WCN36XX_DXE_CTRL_TX_L_SKB (WCN36xx_DXE_CTRL_VLD | \
131 WCN36xx_DXE_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
132 WCN36xx_DXE_CTRL_EOP | WCN36xx_DXE_CTRL_DIQ | \
133 WCN36xx_DXE_CTRL_BTHLD_SEL_SET(5) | WCN36xx_DXE_CTRL_PRIO_SET(4) | \
134 WCN36xx_DXE_CTRL_INT | WCN36xx_DXE_CTRL_SWAP | \
135 WCN36xx_DXE_CTRL_ENDIANNESS)
45 136
46/* TODO This must calculated properly but not hardcoded */ 137/* TODO This must calculated properly but not hardcoded */
47#define WCN36XX_DXE_WQ_TX_L 0x17 138#define WCN36XX_DXE_WQ_TX_L 0x17
@@ -49,15 +140,106 @@ H2H_TEST_RX_TX = DMA2
49#define WCN36XX_DXE_WQ_RX_L 0xB 140#define WCN36XX_DXE_WQ_RX_L 0xB
50#define WCN36XX_DXE_WQ_RX_H 0x4 141#define WCN36XX_DXE_WQ_RX_H 0x4
51 142
52/* DXE descriptor control filed */ 143/* Channel enable or restart */
53#define WCN36XX_DXE_CTRL_VALID_MASK (0x00000001) 144#define WCN36xx_DXE_CH_CTRL_EN BIT(0)
145/* End of packet bit */
146#define WCN36xx_DXE_CH_CTRL_EOP BIT(3)
147/* BD Handling bit */
148#define WCN36xx_DXE_CH_CTRL_BDH BIT(4)
149/* Source is queue */
150#define WCN36xx_DXE_CH_CTRL_SIQ BIT(5)
151/* Destination is queue */
152#define WCN36xx_DXE_CH_CTRL_DIQ BIT(6)
153/* Pointer descriptor is queue */
154#define WCN36xx_DXE_CH_CTRL_PIQ BIT(7)
155/* Relase PDU when done */
156#define WCN36xx_DXE_CH_CTRL_PDU_REL BIT(8)
157/* Stop channel processing */
158#define WCN36xx_DXE_CH_CTRL_STOP BIT(16)
159/* Enable external descriptor interrupt */
160#define WCN36xx_DXE_CH_CTRL_INE_ED BIT(17)
161/* Enable channel interrupt on errors */
162#define WCN36xx_DXE_CH_CTRL_INE_ERR BIT(18)
163/* Enable Channel interrupt when done */
164#define WCN36xx_DXE_CH_CTRL_INE_DONE BIT(19)
165/* External descriptor enable */
166#define WCN36xx_DXE_CH_CTRL_EDEN BIT(20)
167/* Wait for valid bit */
168#define WCN36xx_DXE_CH_CTRL_EDVEN BIT(21)
169/* Endianness is little endian*/
170#define WCN36xx_DXE_CH_CTRL_ENDIANNESS BIT(26)
171/* Abort transfer */
172#define WCN36xx_DXE_CH_CTRL_ABORT BIT(27)
173/* Long descriptor format */
174#define WCN36xx_DXE_CH_CTRL_DFMT BIT(28)
175/* Endian byte swap enable */
176#define WCN36xx_DXE_CH_CTRL_SWAP BIT(31)
177
178/* Transfer type */
179#define WCN36xx_DXE_CH_CTRL_XTYPE_SHIFT 1
180#define WCN36xx_DXE_CH_CTRL_XTYPE_MASK GENMASK(2, WCN36xx_DXE_CH_CTRL_XTYPE_SHIFT)
181#define WCN36xx_DXE_CH_CTRL_XTYPE_SET(x) ((x) << WCN36xx_DXE_CH_CTRL_XTYPE_SHIFT)
182
183/* Channel BMU Threshold select */
184#define WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SHIFT 9
185#define WCN36xx_DXE_CH_CTRL_BTHLD_SEL_MASK GENMASK(12, WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SHIFT)
186#define WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(x) ((x) << WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SHIFT)
187
188/* Channel Priority */
189#define WCN36xx_DXE_CH_CTRL_PRIO_SHIFT 13
190#define WCN36xx_DXE_CH_CTRL_PRIO_MASK GENMASK(15, WCN36xx_DXE_CH_CTRL_PRIO_SHIFT)
191#define WCN36xx_DXE_CH_CTRL_PRIO_SET(x) ((x) << WCN36xx_DXE_CH_CTRL_PRIO_SHIFT)
192
193/* Counter select */
194#define WCN36xx_DXE_CH_CTRL_SEL_SHIFT 22
195#define WCN36xx_DXE_CH_CTRL_SEL_MASK GENMASK(25, WCN36xx_DXE_CH_CTRL_SEL_SHIFT)
196#define WCN36xx_DXE_CH_CTRL_SEL_SET(x) ((x) << WCN36xx_DXE_CH_CTRL_SEL_SHIFT)
197
198/* Channel BD template index */
199#define WCN36xx_DXE_CH_CTRL_BDT_IDX_SHIFT 29
200#define WCN36xx_DXE_CH_CTRL_BDT_IDX_MASK GENMASK(30, WCN36xx_DXE_CH_CTRL_BDT_IDX_SHIFT)
201#define WCN36xx_DXE_CH_CTRL_BDT_IDX_SET(x) ((x) << WCN36xx_DXE_CH_CTRL_BDT_IDX_SHIFT)
54 202
55/* TODO This must calculated properly but not hardcoded */
56/* DXE default control register values */ 203/* DXE default control register values */
57#define WCN36XX_DXE_CH_DEFAULT_CTL_RX_L 0x847EAD2F 204#define WCN36XX_DXE_CH_DEFAULT_CTL_RX_L (WCN36xx_DXE_CH_CTRL_EN | \
58#define WCN36XX_DXE_CH_DEFAULT_CTL_RX_H 0x84FED12F 205 WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \
59#define WCN36XX_DXE_CH_DEFAULT_CTL_TX_H 0x853ECF4D 206 WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_SIQ | \
60#define WCN36XX_DXE_CH_DEFAULT_CTL_TX_L 0x843e8b4d 207 WCN36xx_DXE_CH_CTRL_PDU_REL | WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(6) | \
208 WCN36xx_DXE_CH_CTRL_PRIO_SET(5) | WCN36xx_DXE_CH_CTRL_INE_ED | \
209 WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \
210 WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \
211 WCN36xx_DXE_CH_CTRL_SEL_SET(1) | WCN36xx_DXE_CH_CTRL_ENDIANNESS | \
212 WCN36xx_DXE_CH_CTRL_SWAP)
213
214#define WCN36XX_DXE_CH_DEFAULT_CTL_RX_H (WCN36xx_DXE_CH_CTRL_EN | \
215 WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_B2H) | \
216 WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_SIQ | \
217 WCN36xx_DXE_CH_CTRL_PDU_REL | WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(8) | \
218 WCN36xx_DXE_CH_CTRL_PRIO_SET(6) | WCN36xx_DXE_CH_CTRL_INE_ED | \
219 WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \
220 WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \
221 WCN36xx_DXE_CH_CTRL_SEL_SET(3) | WCN36xx_DXE_CH_CTRL_ENDIANNESS | \
222 WCN36xx_DXE_CH_CTRL_SWAP)
223
224#define WCN36XX_DXE_CH_DEFAULT_CTL_TX_H (WCN36xx_DXE_CH_CTRL_EN | \
225 WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
226 WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_DIQ | \
227 WCN36xx_DXE_CH_CTRL_PDU_REL | WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(7) | \
228 WCN36xx_DXE_CH_CTRL_PRIO_SET(6) | WCN36xx_DXE_CH_CTRL_INE_ED | \
229 WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \
230 WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \
231 WCN36xx_DXE_CH_CTRL_SEL_SET(4) | WCN36xx_DXE_CH_CTRL_ENDIANNESS | \
232 WCN36xx_DXE_CH_CTRL_SWAP)
233
234#define WCN36XX_DXE_CH_DEFAULT_CTL_TX_L (WCN36xx_DXE_CH_CTRL_EN | \
235 WCN36xx_DXE_CH_CTRL_XTYPE_SET(WCN36xx_DXE_XTYPE_H2B) | \
236 WCN36xx_DXE_CH_CTRL_EOP | WCN36xx_DXE_CH_CTRL_DIQ | \
237 WCN36xx_DXE_CH_CTRL_PDU_REL | WCN36xx_DXE_CH_CTRL_BTHLD_SEL_SET(5) | \
238 WCN36xx_DXE_CH_CTRL_PRIO_SET(4) | WCN36xx_DXE_CH_CTRL_INE_ED | \
239 WCN36xx_DXE_CH_CTRL_INE_ERR | WCN36xx_DXE_CH_CTRL_INE_DONE | \
240 WCN36xx_DXE_CH_CTRL_EDEN | WCN36xx_DXE_CH_CTRL_EDVEN | \
241 WCN36xx_DXE_CH_CTRL_SEL_SET(0) | WCN36xx_DXE_CH_CTRL_ENDIANNESS | \
242 WCN36xx_DXE_CH_CTRL_SWAP)
61 243
62/* Common DXE registers */ 244/* Common DXE registers */
63#define WCN36XX_DXE_MEM_CSR (WCN36XX_DXE_MEM_REG + 0x00) 245#define WCN36XX_DXE_MEM_CSR (WCN36XX_DXE_MEM_REG + 0x00)
@@ -80,6 +262,10 @@ H2H_TEST_RX_TX = DMA2
80#define WCN36XX_DXE_0_INT_DONE_CLR (WCN36XX_DXE_MEM_REG + 0x38) 262#define WCN36XX_DXE_0_INT_DONE_CLR (WCN36XX_DXE_MEM_REG + 0x38)
81#define WCN36XX_DXE_0_INT_ERR_CLR (WCN36XX_DXE_MEM_REG + 0x3C) 263#define WCN36XX_DXE_0_INT_ERR_CLR (WCN36XX_DXE_MEM_REG + 0x3C)
82 264
265#define WCN36XX_CH_STAT_INT_DONE_MASK 0x00008000
266#define WCN36XX_CH_STAT_INT_ERR_MASK 0x00004000
267#define WCN36XX_CH_STAT_INT_ED_MASK 0x00002000
268
83#define WCN36XX_DXE_0_CH0_STATUS (WCN36XX_DXE_MEM_REG + 0x404) 269#define WCN36XX_DXE_0_CH0_STATUS (WCN36XX_DXE_MEM_REG + 0x404)
84#define WCN36XX_DXE_0_CH1_STATUS (WCN36XX_DXE_MEM_REG + 0x444) 270#define WCN36XX_DXE_0_CH1_STATUS (WCN36XX_DXE_MEM_REG + 0x444)
85#define WCN36XX_DXE_0_CH2_STATUS (WCN36XX_DXE_MEM_REG + 0x484) 271#define WCN36XX_DXE_0_CH2_STATUS (WCN36XX_DXE_MEM_REG + 0x484)
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index ab5be6d2c691..621e72b6ec99 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -261,7 +261,7 @@ static void wcn36xx_feat_caps_info(struct wcn36xx *wcn)
261 261
262 for (i = 0; i < MAX_FEATURE_SUPPORTED; i++) { 262 for (i = 0; i < MAX_FEATURE_SUPPORTED; i++) {
263 if (get_feat_caps(wcn->fw_feat_caps, i)) 263 if (get_feat_caps(wcn->fw_feat_caps, i))
264 wcn36xx_info("FW Cap %s\n", wcn36xx_get_cap_name(i)); 264 wcn36xx_dbg(WCN36XX_DBG_MAC, "FW Cap %s\n", wcn36xx_get_cap_name(i));
265 } 265 }
266} 266}
267 267
@@ -666,16 +666,13 @@ static void wcn36xx_cancel_hw_scan(struct ieee80211_hw *hw,
666{ 666{
667 struct wcn36xx *wcn = hw->priv; 667 struct wcn36xx *wcn = hw->priv;
668 668
669 if (!wcn36xx_smd_stop_hw_scan(wcn)) {
670 struct cfg80211_scan_info scan_info = { .aborted = true };
671
672 ieee80211_scan_completed(wcn->hw, &scan_info);
673 }
674
675 mutex_lock(&wcn->scan_lock); 669 mutex_lock(&wcn->scan_lock);
676 wcn->scan_aborted = true; 670 wcn->scan_aborted = true;
677 mutex_unlock(&wcn->scan_lock); 671 mutex_unlock(&wcn->scan_lock);
678 672
673 /* ieee80211_scan_completed will be called on FW scan indication */
674 wcn36xx_smd_stop_hw_scan(wcn);
675
679 cancel_work_sync(&wcn->scan_work); 676 cancel_work_sync(&wcn->scan_work);
680} 677}
681 678
@@ -1283,6 +1280,7 @@ static int wcn36xx_probe(struct platform_device *pdev)
1283 wcn = hw->priv; 1280 wcn = hw->priv;
1284 wcn->hw = hw; 1281 wcn->hw = hw;
1285 wcn->dev = &pdev->dev; 1282 wcn->dev = &pdev->dev;
1283 wcn->first_boot = true;
1286 mutex_init(&wcn->conf_mutex); 1284 mutex_init(&wcn->conf_mutex);
1287 mutex_init(&wcn->hal_mutex); 1285 mutex_init(&wcn->hal_mutex);
1288 mutex_init(&wcn->scan_lock); 1286 mutex_init(&wcn->scan_lock);
diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c
index 2a4871ca9c72..def6b23b777f 100644
--- a/drivers/net/wireless/ath/wcn36xx/smd.c
+++ b/drivers/net/wireless/ath/wcn36xx/smd.c
@@ -409,15 +409,17 @@ static int wcn36xx_smd_start_rsp(struct wcn36xx *wcn, void *buf, size_t len)
409 wcn->fw_minor = rsp->start_rsp_params.version.minor; 409 wcn->fw_minor = rsp->start_rsp_params.version.minor;
410 wcn->fw_major = rsp->start_rsp_params.version.major; 410 wcn->fw_major = rsp->start_rsp_params.version.major;
411 411
412 wcn36xx_info("firmware WLAN version '%s' and CRM version '%s'\n", 412 if (wcn->first_boot) {
413 wcn->wlan_version, wcn->crm_version); 413 wcn->first_boot = false;
414 414 wcn36xx_info("firmware WLAN version '%s' and CRM version '%s'\n",
415 wcn36xx_info("firmware API %u.%u.%u.%u, %u stations, %u bssids\n", 415 wcn->wlan_version, wcn->crm_version);
416 wcn->fw_major, wcn->fw_minor,
417 wcn->fw_version, wcn->fw_revision,
418 rsp->start_rsp_params.stations,
419 rsp->start_rsp_params.bssids);
420 416
417 wcn36xx_info("firmware API %u.%u.%u.%u, %u stations, %u bssids\n",
418 wcn->fw_major, wcn->fw_minor,
419 wcn->fw_version, wcn->fw_revision,
420 rsp->start_rsp_params.stations,
421 rsp->start_rsp_params.bssids);
422 }
421 return 0; 423 return 0;
422} 424}
423 425
@@ -2138,6 +2140,8 @@ static int wcn36xx_smd_hw_scan_ind(struct wcn36xx *wcn, void *buf, size_t len)
2138 case WCN36XX_HAL_SCAN_IND_COMPLETED: 2140 case WCN36XX_HAL_SCAN_IND_COMPLETED:
2139 mutex_lock(&wcn->scan_lock); 2141 mutex_lock(&wcn->scan_lock);
2140 wcn->scan_req = NULL; 2142 wcn->scan_req = NULL;
2143 if (wcn->scan_aborted)
2144 scan_info.aborted = true;
2141 mutex_unlock(&wcn->scan_lock); 2145 mutex_unlock(&wcn->scan_lock);
2142 ieee80211_scan_completed(wcn->hw, &scan_info); 2146 ieee80211_scan_completed(wcn->hw, &scan_info);
2143 break; 2147 break;
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index 81017e6703b4..5854adf43f3a 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -192,6 +192,8 @@ struct wcn36xx {
192 u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1]; 192 u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1];
193 u8 wlan_version[WCN36XX_HAL_VERSION_LENGTH + 1]; 193 u8 wlan_version[WCN36XX_HAL_VERSION_LENGTH + 1];
194 194
195 bool first_boot;
196
195 /* IRQs */ 197 /* IRQs */
196 int tx_irq; 198 int tx_irq;
197 int rx_irq; 199 int rx_irq;
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index b799a5384abb..cdbb393863f3 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
3 * 4 *
4 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -17,8 +18,10 @@
17#include <linux/etherdevice.h> 18#include <linux/etherdevice.h>
18#include <linux/moduleparam.h> 19#include <linux/moduleparam.h>
19#include <net/netlink.h> 20#include <net/netlink.h>
21#include <net/cfg80211.h>
20#include "wil6210.h" 22#include "wil6210.h"
21#include "wmi.h" 23#include "wmi.h"
24#include "fw.h"
22 25
23#define WIL_MAX_ROC_DURATION_MS 5000 26#define WIL_MAX_ROC_DURATION_MS 5000
24 27
@@ -258,9 +261,10 @@ int wil_iftype_nl2wmi(enum nl80211_iftype type)
258 return -EOPNOTSUPP; 261 return -EOPNOTSUPP;
259} 262}
260 263
261int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid, 264int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
262 struct station_info *sinfo) 265 struct station_info *sinfo)
263{ 266{
267 struct wil6210_priv *wil = vif_to_wil(vif);
264 struct wmi_notify_req_cmd cmd = { 268 struct wmi_notify_req_cmd cmd = {
265 .cid = cid, 269 .cid = cid,
266 .interval_usec = 0, 270 .interval_usec = 0,
@@ -272,17 +276,17 @@ int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid,
272 struct wil_net_stats *stats = &wil->sta[cid].stats; 276 struct wil_net_stats *stats = &wil->sta[cid].stats;
273 int rc; 277 int rc;
274 278
275 rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd), 279 rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, vif->mid, &cmd, sizeof(cmd),
276 WMI_NOTIFY_REQ_DONE_EVENTID, &reply, sizeof(reply), 20); 280 WMI_NOTIFY_REQ_DONE_EVENTID, &reply, sizeof(reply), 20);
277 if (rc) 281 if (rc)
278 return rc; 282 return rc;
279 283
280 wil_dbg_wmi(wil, "Link status for CID %d: {\n" 284 wil_dbg_wmi(wil, "Link status for CID %d MID %d: {\n"
281 " MCS %d TSF 0x%016llx\n" 285 " MCS %d TSF 0x%016llx\n"
282 " BF status 0x%08x RSSI %d SQI %d%%\n" 286 " BF status 0x%08x RSSI %d SQI %d%%\n"
283 " Tx Tpt %d goodput %d Rx goodput %d\n" 287 " Tx Tpt %d goodput %d Rx goodput %d\n"
284 " Sectors(rx:tx) my %d:%d peer %d:%d\n""}\n", 288 " Sectors(rx:tx) my %d:%d peer %d:%d\n""}\n",
285 cid, le16_to_cpu(reply.evt.bf_mcs), 289 cid, vif->mid, le16_to_cpu(reply.evt.bf_mcs),
286 le64_to_cpu(reply.evt.tsf), reply.evt.status, 290 le64_to_cpu(reply.evt.tsf), reply.evt.status,
287 reply.evt.rssi, 291 reply.evt.rssi,
288 reply.evt.sqi, 292 reply.evt.sqi,
@@ -315,7 +319,7 @@ int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid,
315 sinfo->tx_packets = stats->tx_packets; 319 sinfo->tx_packets = stats->tx_packets;
316 sinfo->tx_failed = stats->tx_errors; 320 sinfo->tx_failed = stats->tx_errors;
317 321
318 if (test_bit(wil_status_fwconnected, wil->status)) { 322 if (test_bit(wil_vif_fwconnected, vif->status)) {
319 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); 323 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
320 if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING, 324 if (test_bit(WMI_FW_CAPABILITY_RSSI_REPORTING,
321 wil->fw_capabilities)) 325 wil->fw_capabilities))
@@ -331,30 +335,34 @@ static int wil_cfg80211_get_station(struct wiphy *wiphy,
331 struct net_device *ndev, 335 struct net_device *ndev,
332 const u8 *mac, struct station_info *sinfo) 336 const u8 *mac, struct station_info *sinfo)
333{ 337{
338 struct wil6210_vif *vif = ndev_to_vif(ndev);
334 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 339 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
335 int rc; 340 int rc;
336 341
337 int cid = wil_find_cid(wil, mac); 342 int cid = wil_find_cid(wil, vif->mid, mac);
338 343
339 wil_dbg_misc(wil, "get_station: %pM CID %d\n", mac, cid); 344 wil_dbg_misc(wil, "get_station: %pM CID %d MID %d\n", mac, cid,
345 vif->mid);
340 if (cid < 0) 346 if (cid < 0)
341 return cid; 347 return cid;
342 348
343 rc = wil_cid_fill_sinfo(wil, cid, sinfo); 349 rc = wil_cid_fill_sinfo(vif, cid, sinfo);
344 350
345 return rc; 351 return rc;
346} 352}
347 353
348/* 354/*
349 * Find @idx-th active STA for station dump. 355 * Find @idx-th active STA for specific MID for station dump.
350 */ 356 */
351static int wil_find_cid_by_idx(struct wil6210_priv *wil, int idx) 357static int wil_find_cid_by_idx(struct wil6210_priv *wil, u8 mid, int idx)
352{ 358{
353 int i; 359 int i;
354 360
355 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { 361 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
356 if (wil->sta[i].status == wil_sta_unused) 362 if (wil->sta[i].status == wil_sta_unused)
357 continue; 363 continue;
364 if (wil->sta[i].mid != mid)
365 continue;
358 if (idx == 0) 366 if (idx == 0)
359 return i; 367 return i;
360 idx--; 368 idx--;
@@ -367,17 +375,19 @@ static int wil_cfg80211_dump_station(struct wiphy *wiphy,
367 struct net_device *dev, int idx, 375 struct net_device *dev, int idx,
368 u8 *mac, struct station_info *sinfo) 376 u8 *mac, struct station_info *sinfo)
369{ 377{
378 struct wil6210_vif *vif = ndev_to_vif(dev);
370 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 379 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
371 int rc; 380 int rc;
372 int cid = wil_find_cid_by_idx(wil, idx); 381 int cid = wil_find_cid_by_idx(wil, vif->mid, idx);
373 382
374 if (cid < 0) 383 if (cid < 0)
375 return -ENOENT; 384 return -ENOENT;
376 385
377 ether_addr_copy(mac, wil->sta[cid].addr); 386 ether_addr_copy(mac, wil->sta[cid].addr);
378 wil_dbg_misc(wil, "dump_station: %pM CID %d\n", mac, cid); 387 wil_dbg_misc(wil, "dump_station: %pM CID %d MID %d\n", mac, cid,
388 vif->mid);
379 389
380 rc = wil_cid_fill_sinfo(wil, cid, sinfo); 390 rc = wil_cid_fill_sinfo(vif, cid, sinfo);
381 391
382 return rc; 392 return rc;
383} 393}
@@ -388,7 +398,7 @@ static int wil_cfg80211_start_p2p_device(struct wiphy *wiphy,
388 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 398 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
389 399
390 wil_dbg_misc(wil, "start_p2p_device: entered\n"); 400 wil_dbg_misc(wil, "start_p2p_device: entered\n");
391 wil->p2p.p2p_dev_started = 1; 401 wil->p2p_dev_started = 1;
392 return 0; 402 return 0;
393} 403}
394 404
@@ -396,20 +406,66 @@ static void wil_cfg80211_stop_p2p_device(struct wiphy *wiphy,
396 struct wireless_dev *wdev) 406 struct wireless_dev *wdev)
397{ 407{
398 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 408 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
399 struct wil_p2p_info *p2p = &wil->p2p;
400 409
401 if (!p2p->p2p_dev_started) 410 if (!wil->p2p_dev_started)
402 return; 411 return;
403 412
404 wil_dbg_misc(wil, "stop_p2p_device: entered\n"); 413 wil_dbg_misc(wil, "stop_p2p_device: entered\n");
405 mutex_lock(&wil->mutex); 414 mutex_lock(&wil->mutex);
406 mutex_lock(&wil->p2p_wdev_mutex); 415 mutex_lock(&wil->vif_mutex);
407 wil_p2p_stop_radio_operations(wil); 416 wil_p2p_stop_radio_operations(wil);
408 p2p->p2p_dev_started = 0; 417 wil->p2p_dev_started = 0;
409 mutex_unlock(&wil->p2p_wdev_mutex); 418 mutex_unlock(&wil->vif_mutex);
410 mutex_unlock(&wil->mutex); 419 mutex_unlock(&wil->mutex);
411} 420}
412 421
422static int wil_cfg80211_validate_add_iface(struct wil6210_priv *wil,
423 enum nl80211_iftype new_type)
424{
425 int i;
426 struct wireless_dev *wdev;
427 struct iface_combination_params params = {
428 .num_different_channels = 1,
429 };
430
431 for (i = 0; i < wil->max_vifs; i++) {
432 if (wil->vifs[i]) {
433 wdev = vif_to_wdev(wil->vifs[i]);
434 params.iftype_num[wdev->iftype]++;
435 }
436 }
437 params.iftype_num[new_type]++;
438 return cfg80211_check_combinations(wil->wiphy, &params);
439}
440
441static int wil_cfg80211_validate_change_iface(struct wil6210_priv *wil,
442 struct wil6210_vif *vif,
443 enum nl80211_iftype new_type)
444{
445 int i, ret = 0;
446 struct wireless_dev *wdev;
447 struct iface_combination_params params = {
448 .num_different_channels = 1,
449 };
450 bool check_combos = false;
451
452 for (i = 0; i < wil->max_vifs; i++) {
453 struct wil6210_vif *vif_pos = wil->vifs[i];
454
455 if (vif_pos && vif != vif_pos) {
456 wdev = vif_to_wdev(vif_pos);
457 params.iftype_num[wdev->iftype]++;
458 check_combos = true;
459 }
460 }
461
462 if (check_combos) {
463 params.iftype_num[new_type]++;
464 ret = cfg80211_check_combinations(wil->wiphy, &params);
465 }
466 return ret;
467}
468
413static struct wireless_dev * 469static struct wireless_dev *
414wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name, 470wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name,
415 unsigned char name_assign_type, 471 unsigned char name_assign_type,
@@ -417,51 +473,137 @@ wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name,
417 struct vif_params *params) 473 struct vif_params *params)
418{ 474{
419 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 475 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
420 struct net_device *ndev = wil_to_ndev(wil); 476 struct net_device *ndev_main = wil->main_ndev, *ndev;
421 struct wireless_dev *p2p_wdev; 477 struct wil6210_vif *vif;
478 struct wireless_dev *p2p_wdev, *wdev;
479 int rc;
422 480
423 wil_dbg_misc(wil, "add_iface\n"); 481 wil_dbg_misc(wil, "add_iface, type %d\n", type);
424 482
425 if (type != NL80211_IFTYPE_P2P_DEVICE) { 483 /* P2P device is not a real virtual interface, it is a management-only
426 wil_err(wil, "unsupported iftype %d\n", type); 484 * interface that shares the main interface.
427 return ERR_PTR(-EINVAL); 485 * Skip concurrency checks here.
486 */
487 if (type == NL80211_IFTYPE_P2P_DEVICE) {
488 if (wil->p2p_wdev) {
489 wil_err(wil, "P2P_DEVICE interface already created\n");
490 return ERR_PTR(-EINVAL);
491 }
492
493 p2p_wdev = kzalloc(sizeof(*p2p_wdev), GFP_KERNEL);
494 if (!p2p_wdev)
495 return ERR_PTR(-ENOMEM);
496
497 p2p_wdev->iftype = type;
498 p2p_wdev->wiphy = wiphy;
499 /* use our primary ethernet address */
500 ether_addr_copy(p2p_wdev->address, ndev_main->perm_addr);
501
502 wil->p2p_wdev = p2p_wdev;
503
504 return p2p_wdev;
428 } 505 }
429 506
430 if (wil->p2p_wdev) { 507 if (!wil->wiphy->n_iface_combinations) {
431 wil_err(wil, "P2P_DEVICE interface already created\n"); 508 wil_err(wil, "virtual interfaces not supported\n");
432 return ERR_PTR(-EINVAL); 509 return ERR_PTR(-EINVAL);
433 } 510 }
434 511
435 p2p_wdev = kzalloc(sizeof(*p2p_wdev), GFP_KERNEL); 512 rc = wil_cfg80211_validate_add_iface(wil, type);
436 if (!p2p_wdev) 513 if (rc) {
437 return ERR_PTR(-ENOMEM); 514 wil_err(wil, "iface validation failed, err=%d\n", rc);
515 return ERR_PTR(rc);
516 }
438 517
439 p2p_wdev->iftype = type; 518 vif = wil_vif_alloc(wil, name, name_assign_type, type);
440 p2p_wdev->wiphy = wiphy; 519 if (IS_ERR(vif))
441 /* use our primary ethernet address */ 520 return ERR_CAST(vif);
442 ether_addr_copy(p2p_wdev->address, ndev->perm_addr); 521
522 ndev = vif_to_ndev(vif);
523 ether_addr_copy(ndev->perm_addr, ndev_main->perm_addr);
524 if (is_valid_ether_addr(params->macaddr)) {
525 ether_addr_copy(ndev->dev_addr, params->macaddr);
526 } else {
527 ether_addr_copy(ndev->dev_addr, ndev_main->perm_addr);
528 ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << vif->mid)) |
529 0x2; /* locally administered */
530 }
531 wdev = vif_to_wdev(vif);
532 ether_addr_copy(wdev->address, ndev->dev_addr);
443 533
444 wil->p2p_wdev = p2p_wdev; 534 rc = wil_vif_add(wil, vif);
535 if (rc)
536 goto out;
445 537
446 return p2p_wdev; 538 wil_info(wil, "added VIF, mid %d iftype %d MAC %pM\n",
539 vif->mid, type, wdev->address);
540 return wdev;
541out:
542 wil_vif_free(vif);
543 return ERR_PTR(rc);
544}
545
546int wil_vif_prepare_stop(struct wil6210_vif *vif)
547{
548 struct wil6210_priv *wil = vif_to_wil(vif);
549 struct wireless_dev *wdev = vif_to_wdev(vif);
550 struct net_device *ndev;
551 int rc;
552
553 if (wdev->iftype != NL80211_IFTYPE_AP)
554 return 0;
555
556 ndev = vif_to_ndev(vif);
557 if (netif_carrier_ok(ndev)) {
558 rc = wmi_pcp_stop(vif);
559 if (rc) {
560 wil_info(wil, "failed to stop AP, status %d\n",
561 rc);
562 /* continue */
563 }
564 wil_bcast_fini(vif);
565 netif_carrier_off(ndev);
566 }
567
568 return 0;
447} 569}
448 570
449static int wil_cfg80211_del_iface(struct wiphy *wiphy, 571static int wil_cfg80211_del_iface(struct wiphy *wiphy,
450 struct wireless_dev *wdev) 572 struct wireless_dev *wdev)
451{ 573{
452 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 574 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
575 struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
576 int rc;
453 577
454 wil_dbg_misc(wil, "del_iface\n"); 578 wil_dbg_misc(wil, "del_iface\n");
455 579
456 if (wdev != wil->p2p_wdev) { 580 if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) {
457 wil_err(wil, "delete of incorrect interface 0x%p\n", wdev); 581 if (wdev != wil->p2p_wdev) {
582 wil_err(wil, "delete of incorrect interface 0x%p\n",
583 wdev);
584 return -EINVAL;
585 }
586
587 wil_cfg80211_stop_p2p_device(wiphy, wdev);
588 wil_p2p_wdev_free(wil);
589 return 0;
590 }
591
592 if (vif->mid == 0) {
593 wil_err(wil, "cannot remove the main interface\n");
458 return -EINVAL; 594 return -EINVAL;
459 } 595 }
460 596
461 wil_cfg80211_stop_p2p_device(wiphy, wdev); 597 rc = wil_vif_prepare_stop(vif);
462 wil_p2p_wdev_free(wil); 598 if (rc)
599 goto out;
600
601 wil_info(wil, "deleted VIF, mid %d iftype %d MAC %pM\n",
602 vif->mid, wdev->iftype, wdev->address);
463 603
464 return 0; 604 wil_vif_remove(wil, vif->mid);
605out:
606 return rc;
465} 607}
466 608
467static int wil_cfg80211_change_iface(struct wiphy *wiphy, 609static int wil_cfg80211_change_iface(struct wiphy *wiphy,
@@ -470,12 +612,26 @@ static int wil_cfg80211_change_iface(struct wiphy *wiphy,
470 struct vif_params *params) 612 struct vif_params *params)
471{ 613{
472 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 614 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
473 struct wireless_dev *wdev = wil_to_wdev(wil); 615 struct wil6210_vif *vif = ndev_to_vif(ndev);
616 struct wireless_dev *wdev = vif_to_wdev(vif);
474 int rc; 617 int rc;
618 bool fw_reset = false;
475 619
476 wil_dbg_misc(wil, "change_iface: type=%d\n", type); 620 wil_dbg_misc(wil, "change_iface: type=%d\n", type);
477 621
478 if (netif_running(wil_to_ndev(wil)) && !wil_is_recovery_blocked(wil)) { 622 if (wiphy->n_iface_combinations) {
623 rc = wil_cfg80211_validate_change_iface(wil, vif, type);
624 if (rc) {
625 wil_err(wil, "iface validation failed, err=%d\n", rc);
626 return rc;
627 }
628 }
629
630 /* do not reset FW when there are active VIFs,
631 * because it can cause significant disruption
632 */
633 if (!wil_has_other_active_ifaces(wil, ndev, true, false) &&
634 netif_running(ndev) && !wil_is_recovery_blocked(wil)) {
479 wil_dbg_misc(wil, "interface is up. resetting...\n"); 635 wil_dbg_misc(wil, "interface is up. resetting...\n");
480 mutex_lock(&wil->mutex); 636 mutex_lock(&wil->mutex);
481 __wil_down(wil); 637 __wil_down(wil);
@@ -484,6 +640,7 @@ static int wil_cfg80211_change_iface(struct wiphy *wiphy,
484 640
485 if (rc) 641 if (rc)
486 return rc; 642 return rc;
643 fw_reset = true;
487 } 644 }
488 645
489 switch (type) { 646 switch (type) {
@@ -500,8 +657,18 @@ static int wil_cfg80211_change_iface(struct wiphy *wiphy,
500 return -EOPNOTSUPP; 657 return -EOPNOTSUPP;
501 } 658 }
502 659
503 wdev->iftype = type; 660 if (vif->mid != 0 && wil_has_active_ifaces(wil, true, false)) {
661 if (!fw_reset)
662 wil_vif_prepare_stop(vif);
663 rc = wmi_port_delete(wil, vif->mid);
664 if (rc)
665 return rc;
666 rc = wmi_port_allocate(wil, vif->mid, ndev->dev_addr, type);
667 if (rc)
668 return rc;
669 }
504 670
671 wdev->iftype = type;
505 return 0; 672 return 0;
506} 673}
507 674
@@ -510,6 +677,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
510{ 677{
511 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 678 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
512 struct wireless_dev *wdev = request->wdev; 679 struct wireless_dev *wdev = request->wdev;
680 struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
513 struct { 681 struct {
514 struct wmi_start_scan_cmd cmd; 682 struct wmi_start_scan_cmd cmd;
515 u16 chnl[4]; 683 u16 chnl[4];
@@ -537,35 +705,38 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
537 705
538 mutex_lock(&wil->mutex); 706 mutex_lock(&wil->mutex);
539 707
540 mutex_lock(&wil->p2p_wdev_mutex); 708 mutex_lock(&wil->vif_mutex);
541 if (wil->scan_request || wil->p2p.discovery_started) { 709 if (vif->scan_request || vif->p2p.discovery_started) {
542 wil_err(wil, "Already scanning\n"); 710 wil_err(wil, "Already scanning\n");
543 mutex_unlock(&wil->p2p_wdev_mutex); 711 mutex_unlock(&wil->vif_mutex);
544 rc = -EAGAIN; 712 rc = -EAGAIN;
545 goto out; 713 goto out;
546 } 714 }
547 mutex_unlock(&wil->p2p_wdev_mutex); 715 mutex_unlock(&wil->vif_mutex);
548 716
549 if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) { 717 if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) {
550 if (!wil->p2p.p2p_dev_started) { 718 if (!wil->p2p_dev_started) {
551 wil_err(wil, "P2P search requested on stopped P2P device\n"); 719 wil_err(wil, "P2P search requested on stopped P2P device\n");
552 rc = -EIO; 720 rc = -EIO;
553 goto out; 721 goto out;
554 } 722 }
555 /* social scan on P2P_DEVICE is handled as p2p search */ 723 /* social scan on P2P_DEVICE is handled as p2p search */
556 if (wil_p2p_is_social_scan(request)) { 724 if (wil_p2p_is_social_scan(request)) {
557 wil->scan_request = request; 725 vif->scan_request = request;
558 wil->radio_wdev = wdev; 726 if (vif->mid == 0)
559 rc = wil_p2p_search(wil, request); 727 wil->radio_wdev = wdev;
728 rc = wil_p2p_search(vif, request);
560 if (rc) { 729 if (rc) {
561 wil->radio_wdev = wil_to_wdev(wil); 730 if (vif->mid == 0)
562 wil->scan_request = NULL; 731 wil->radio_wdev =
732 wil->main_ndev->ieee80211_ptr;
733 vif->scan_request = NULL;
563 } 734 }
564 goto out; 735 goto out;
565 } 736 }
566 } 737 }
567 738
568 (void)wil_p2p_stop_discovery(wil); 739 (void)wil_p2p_stop_discovery(vif);
569 740
570 wil_dbg_misc(wil, "Start scan_request 0x%p\n", request); 741 wil_dbg_misc(wil, "Start scan_request 0x%p\n", request);
571 wil_dbg_misc(wil, "SSID count: %d", request->n_ssids); 742 wil_dbg_misc(wil, "SSID count: %d", request->n_ssids);
@@ -578,18 +749,18 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
578 } 749 }
579 750
580 if (request->n_ssids) 751 if (request->n_ssids)
581 rc = wmi_set_ssid(wil, request->ssids[0].ssid_len, 752 rc = wmi_set_ssid(vif, request->ssids[0].ssid_len,
582 request->ssids[0].ssid); 753 request->ssids[0].ssid);
583 else 754 else
584 rc = wmi_set_ssid(wil, 0, NULL); 755 rc = wmi_set_ssid(vif, 0, NULL);
585 756
586 if (rc) { 757 if (rc) {
587 wil_err(wil, "set SSID for scan request failed: %d\n", rc); 758 wil_err(wil, "set SSID for scan request failed: %d\n", rc);
588 goto out; 759 goto out;
589 } 760 }
590 761
591 wil->scan_request = request; 762 vif->scan_request = request;
592 mod_timer(&wil->scan_timer, jiffies + WIL6210_SCAN_TO); 763 mod_timer(&vif->scan_timer, jiffies + WIL6210_SCAN_TO);
593 764
594 memset(&cmd, 0, sizeof(cmd)); 765 memset(&cmd, 0, sizeof(cmd));
595 cmd.cmd.scan_type = WMI_ACTIVE_SCAN; 766 cmd.cmd.scan_type = WMI_ACTIVE_SCAN;
@@ -616,7 +787,8 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
616 else 787 else
617 wil_dbg_misc(wil, "Scan has no IE's\n"); 788 wil_dbg_misc(wil, "Scan has no IE's\n");
618 789
619 rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len, request->ie); 790 rc = wmi_set_ie(vif, WMI_FRAME_PROBE_REQ,
791 request->ie_len, request->ie);
620 if (rc) 792 if (rc)
621 goto out_restore; 793 goto out_restore;
622 794
@@ -625,15 +797,18 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
625 wil_dbg_misc(wil, "active scan with discovery_mode=1\n"); 797 wil_dbg_misc(wil, "active scan with discovery_mode=1\n");
626 } 798 }
627 799
628 wil->radio_wdev = wdev; 800 if (vif->mid == 0)
629 rc = wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) + 801 wil->radio_wdev = wdev;
630 cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0])); 802 rc = wmi_send(wil, WMI_START_SCAN_CMDID, vif->mid,
803 &cmd, sizeof(cmd.cmd) +
804 cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0]));
631 805
632out_restore: 806out_restore:
633 if (rc) { 807 if (rc) {
634 del_timer_sync(&wil->scan_timer); 808 del_timer_sync(&vif->scan_timer);
635 wil->radio_wdev = wil_to_wdev(wil); 809 if (vif->mid == 0)
636 wil->scan_request = NULL; 810 wil->radio_wdev = wil->main_ndev->ieee80211_ptr;
811 vif->scan_request = NULL;
637 } 812 }
638out: 813out:
639 mutex_unlock(&wil->mutex); 814 mutex_unlock(&wil->mutex);
@@ -644,27 +819,28 @@ static void wil_cfg80211_abort_scan(struct wiphy *wiphy,
644 struct wireless_dev *wdev) 819 struct wireless_dev *wdev)
645{ 820{
646 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 821 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
822 struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
647 823
648 wil_dbg_misc(wil, "wdev=0x%p iftype=%d\n", wdev, wdev->iftype); 824 wil_dbg_misc(wil, "wdev=0x%p iftype=%d\n", wdev, wdev->iftype);
649 825
650 mutex_lock(&wil->mutex); 826 mutex_lock(&wil->mutex);
651 mutex_lock(&wil->p2p_wdev_mutex); 827 mutex_lock(&wil->vif_mutex);
652 828
653 if (!wil->scan_request) 829 if (!vif->scan_request)
654 goto out; 830 goto out;
655 831
656 if (wdev != wil->scan_request->wdev) { 832 if (wdev != vif->scan_request->wdev) {
657 wil_dbg_misc(wil, "abort scan was called on the wrong iface\n"); 833 wil_dbg_misc(wil, "abort scan was called on the wrong iface\n");
658 goto out; 834 goto out;
659 } 835 }
660 836
661 if (wil->radio_wdev == wil->p2p_wdev) 837 if (wdev == wil->p2p_wdev && wil->radio_wdev == wil->p2p_wdev)
662 wil_p2p_stop_radio_operations(wil); 838 wil_p2p_stop_radio_operations(wil);
663 else 839 else
664 wil_abort_scan(wil, true); 840 wil_abort_scan(vif, true);
665 841
666out: 842out:
667 mutex_unlock(&wil->p2p_wdev_mutex); 843 mutex_unlock(&wil->vif_mutex);
668 mutex_unlock(&wil->mutex); 844 mutex_unlock(&wil->mutex);
669} 845}
670 846
@@ -715,6 +891,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
715 struct cfg80211_connect_params *sme) 891 struct cfg80211_connect_params *sme)
716{ 892{
717 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 893 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
894 struct wil6210_vif *vif = ndev_to_vif(ndev);
718 struct cfg80211_bss *bss; 895 struct cfg80211_bss *bss;
719 struct wmi_connect_cmd conn; 896 struct wmi_connect_cmd conn;
720 const u8 *ssid_eid; 897 const u8 *ssid_eid;
@@ -723,11 +900,11 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
723 int rc = 0; 900 int rc = 0;
724 enum ieee80211_bss_type bss_type = IEEE80211_BSS_TYPE_ESS; 901 enum ieee80211_bss_type bss_type = IEEE80211_BSS_TYPE_ESS;
725 902
726 wil_dbg_misc(wil, "connect\n"); 903 wil_dbg_misc(wil, "connect, mid=%d\n", vif->mid);
727 wil_print_connect_params(wil, sme); 904 wil_print_connect_params(wil, sme);
728 905
729 if (test_bit(wil_status_fwconnecting, wil->status) || 906 if (test_bit(wil_vif_fwconnecting, vif->status) ||
730 test_bit(wil_status_fwconnected, wil->status)) 907 test_bit(wil_vif_fwconnected, vif->status))
731 return -EALREADY; 908 return -EALREADY;
732 909
733 if (sme->ie_len > WMI_MAX_IE_LEN) { 910 if (sme->ie_len > WMI_MAX_IE_LEN) {
@@ -758,18 +935,18 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
758 rc = -ENOENT; 935 rc = -ENOENT;
759 goto out; 936 goto out;
760 } 937 }
761 wil->privacy = sme->privacy; 938 vif->privacy = sme->privacy;
762 wil->pbss = sme->pbss; 939 vif->pbss = sme->pbss;
763 940
764 if (wil->privacy) { 941 if (vif->privacy) {
765 /* For secure assoc, remove old keys */ 942 /* For secure assoc, remove old keys */
766 rc = wmi_del_cipher_key(wil, 0, bss->bssid, 943 rc = wmi_del_cipher_key(vif, 0, bss->bssid,
767 WMI_KEY_USE_PAIRWISE); 944 WMI_KEY_USE_PAIRWISE);
768 if (rc) { 945 if (rc) {
769 wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(PTK) failed\n"); 946 wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(PTK) failed\n");
770 goto out; 947 goto out;
771 } 948 }
772 rc = wmi_del_cipher_key(wil, 0, bss->bssid, 949 rc = wmi_del_cipher_key(vif, 0, bss->bssid,
773 WMI_KEY_USE_RX_GROUP); 950 WMI_KEY_USE_RX_GROUP);
774 if (rc) { 951 if (rc) {
775 wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(GTK) failed\n"); 952 wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD(GTK) failed\n");
@@ -781,7 +958,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
781 * elements. Send it also in case it's empty, to erase previously set 958 * elements. Send it also in case it's empty, to erase previously set
782 * ies in FW. 959 * ies in FW.
783 */ 960 */
784 rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie); 961 rc = wmi_set_ie(vif, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie);
785 if (rc) 962 if (rc)
786 goto out; 963 goto out;
787 964
@@ -799,7 +976,7 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
799 bss->capability); 976 bss->capability);
800 goto out; 977 goto out;
801 } 978 }
802 if (wil->privacy) { 979 if (vif->privacy) {
803 if (rsn_eid) { /* regular secure connection */ 980 if (rsn_eid) { /* regular secure connection */
804 conn.dot11_auth_mode = WMI_AUTH11_SHARED; 981 conn.dot11_auth_mode = WMI_AUTH11_SHARED;
805 conn.auth_mode = WMI_AUTH_WPA2_PSK; 982 conn.auth_mode = WMI_AUTH_WPA2_PSK;
@@ -831,18 +1008,19 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
831 ether_addr_copy(conn.bssid, bss->bssid); 1008 ether_addr_copy(conn.bssid, bss->bssid);
832 ether_addr_copy(conn.dst_mac, bss->bssid); 1009 ether_addr_copy(conn.dst_mac, bss->bssid);
833 1010
834 set_bit(wil_status_fwconnecting, wil->status); 1011 set_bit(wil_vif_fwconnecting, vif->status);
835 1012
836 rc = wmi_send(wil, WMI_CONNECT_CMDID, &conn, sizeof(conn)); 1013 rc = wmi_send(wil, WMI_CONNECT_CMDID, vif->mid, &conn, sizeof(conn));
837 if (rc == 0) { 1014 if (rc == 0) {
838 netif_carrier_on(ndev); 1015 netif_carrier_on(ndev);
839 wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS); 1016 if (!wil_has_other_active_ifaces(wil, ndev, false, true))
840 wil->bss = bss; 1017 wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);
1018 vif->bss = bss;
841 /* Connect can take lots of time */ 1019 /* Connect can take lots of time */
842 mod_timer(&wil->connect_timer, 1020 mod_timer(&vif->connect_timer,
843 jiffies + msecs_to_jiffies(5000)); 1021 jiffies + msecs_to_jiffies(5000));
844 } else { 1022 } else {
845 clear_bit(wil_status_fwconnecting, wil->status); 1023 clear_bit(wil_vif_fwconnecting, vif->status);
846 } 1024 }
847 1025
848 out: 1026 out:
@@ -857,17 +1035,19 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
857{ 1035{
858 int rc; 1036 int rc;
859 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1037 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1038 struct wil6210_vif *vif = ndev_to_vif(ndev);
860 1039
861 wil_dbg_misc(wil, "disconnect: reason=%d\n", reason_code); 1040 wil_dbg_misc(wil, "disconnect: reason=%d, mid=%d\n",
1041 reason_code, vif->mid);
862 1042
863 if (!(test_bit(wil_status_fwconnecting, wil->status) || 1043 if (!(test_bit(wil_vif_fwconnecting, vif->status) ||
864 test_bit(wil_status_fwconnected, wil->status))) { 1044 test_bit(wil_vif_fwconnected, vif->status))) {
865 wil_err(wil, "Disconnect was called while disconnected\n"); 1045 wil_err(wil, "Disconnect was called while disconnected\n");
866 return 0; 1046 return 0;
867 } 1047 }
868 1048
869 wil->locally_generated_disc = true; 1049 vif->locally_generated_disc = true;
870 rc = wmi_call(wil, WMI_DISCONNECT_CMDID, NULL, 0, 1050 rc = wmi_call(wil, WMI_DISCONNECT_CMDID, vif->mid, NULL, 0,
871 WMI_DISCONNECT_EVENTID, NULL, 0, 1051 WMI_DISCONNECT_EVENTID, NULL, 0,
872 WIL6210_DISCONNECT_TO_MS); 1052 WIL6210_DISCONNECT_TO_MS);
873 if (rc) 1053 if (rc)
@@ -903,6 +1083,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
903 const u8 *buf = params->buf; 1083 const u8 *buf = params->buf;
904 size_t len = params->len, total; 1084 size_t len = params->len, total;
905 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1085 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1086 struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
906 int rc; 1087 int rc;
907 bool tx_status = false; 1088 bool tx_status = false;
908 struct ieee80211_mgmt *mgmt_frame = (void *)buf; 1089 struct ieee80211_mgmt *mgmt_frame = (void *)buf;
@@ -919,7 +1100,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
919 * different from currently "listened" channel and fail if it is. 1100 * different from currently "listened" channel and fail if it is.
920 */ 1101 */
921 1102
922 wil_dbg_misc(wil, "mgmt_tx\n"); 1103 wil_dbg_misc(wil, "mgmt_tx mid %d\n", vif->mid);
923 wil_hex_dump_misc("mgmt tx frame ", DUMP_PREFIX_OFFSET, 16, 1, buf, 1104 wil_hex_dump_misc("mgmt tx frame ", DUMP_PREFIX_OFFSET, 16, 1, buf,
924 len, true); 1105 len, true);
925 1106
@@ -940,7 +1121,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
940 cmd->len = cpu_to_le16(len); 1121 cmd->len = cpu_to_le16(len);
941 memcpy(cmd->payload, buf, len); 1122 memcpy(cmd->payload, buf, len);
942 1123
943 rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, total, 1124 rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, vif->mid, cmd, total,
944 WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000); 1125 WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000);
945 if (rc == 0) 1126 if (rc == 0)
946 tx_status = !evt.evt.status; 1127 tx_status = !evt.evt.status;
@@ -962,10 +1143,10 @@ static int wil_cfg80211_set_channel(struct wiphy *wiphy,
962 return 0; 1143 return 0;
963} 1144}
964 1145
965static enum wmi_key_usage wil_detect_key_usage(struct wil6210_priv *wil, 1146static enum wmi_key_usage wil_detect_key_usage(struct wireless_dev *wdev,
966 bool pairwise) 1147 bool pairwise)
967{ 1148{
968 struct wireless_dev *wdev = wil_to_wdev(wil); 1149 struct wil6210_priv *wil = wdev_to_wil(wdev);
969 enum wmi_key_usage rc; 1150 enum wmi_key_usage rc;
970 1151
971 if (pairwise) { 1152 if (pairwise) {
@@ -993,7 +1174,7 @@ static enum wmi_key_usage wil_detect_key_usage(struct wil6210_priv *wil,
993} 1174}
994 1175
995static struct wil_sta_info * 1176static struct wil_sta_info *
996wil_find_sta_by_key_usage(struct wil6210_priv *wil, 1177wil_find_sta_by_key_usage(struct wil6210_priv *wil, u8 mid,
997 enum wmi_key_usage key_usage, const u8 *mac_addr) 1178 enum wmi_key_usage key_usage, const u8 *mac_addr)
998{ 1179{
999 int cid = -EINVAL; 1180 int cid = -EINVAL;
@@ -1003,9 +1184,9 @@ wil_find_sta_by_key_usage(struct wil6210_priv *wil,
1003 1184
1004 /* supplicant provides Rx group key in STA mode with NULL MAC address */ 1185 /* supplicant provides Rx group key in STA mode with NULL MAC address */
1005 if (mac_addr) 1186 if (mac_addr)
1006 cid = wil_find_cid(wil, mac_addr); 1187 cid = wil_find_cid(wil, mid, mac_addr);
1007 else if (key_usage == WMI_KEY_USE_RX_GROUP) 1188 else if (key_usage == WMI_KEY_USE_RX_GROUP)
1008 cid = wil_find_cid_by_idx(wil, 0); 1189 cid = wil_find_cid_by_idx(wil, mid, 0);
1009 if (cid < 0) { 1190 if (cid < 0) {
1010 wil_err(wil, "No CID for %pM %s\n", mac_addr, 1191 wil_err(wil, "No CID for %pM %s\n", mac_addr,
1011 key_usage_str[key_usage]); 1192 key_usage_str[key_usage]);
@@ -1082,9 +1263,12 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy,
1082 struct key_params *params) 1263 struct key_params *params)
1083{ 1264{
1084 int rc; 1265 int rc;
1266 struct wil6210_vif *vif = ndev_to_vif(ndev);
1085 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1267 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1086 enum wmi_key_usage key_usage = wil_detect_key_usage(wil, pairwise); 1268 struct wireless_dev *wdev = vif_to_wdev(vif);
1087 struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, key_usage, 1269 enum wmi_key_usage key_usage = wil_detect_key_usage(wdev, pairwise);
1270 struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, vif->mid,
1271 key_usage,
1088 mac_addr); 1272 mac_addr);
1089 1273
1090 if (!params) { 1274 if (!params) {
@@ -1114,7 +1298,7 @@ static int wil_cfg80211_add_key(struct wiphy *wiphy,
1114 return -EINVAL; 1298 return -EINVAL;
1115 } 1299 }
1116 1300
1117 rc = wmi_add_cipher_key(wil, key_index, mac_addr, params->key_len, 1301 rc = wmi_add_cipher_key(vif, key_index, mac_addr, params->key_len,
1118 params->key, key_usage); 1302 params->key, key_usage);
1119 if (!rc) 1303 if (!rc)
1120 wil_set_crypto_rx(key_index, key_usage, cs, params); 1304 wil_set_crypto_rx(key_index, key_usage, cs, params);
@@ -1127,9 +1311,12 @@ static int wil_cfg80211_del_key(struct wiphy *wiphy,
1127 u8 key_index, bool pairwise, 1311 u8 key_index, bool pairwise,
1128 const u8 *mac_addr) 1312 const u8 *mac_addr)
1129{ 1313{
1314 struct wil6210_vif *vif = ndev_to_vif(ndev);
1130 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1315 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1131 enum wmi_key_usage key_usage = wil_detect_key_usage(wil, pairwise); 1316 struct wireless_dev *wdev = vif_to_wdev(vif);
1132 struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, key_usage, 1317 enum wmi_key_usage key_usage = wil_detect_key_usage(wdev, pairwise);
1318 struct wil_sta_info *cs = wil_find_sta_by_key_usage(wil, vif->mid,
1319 key_usage,
1133 mac_addr); 1320 mac_addr);
1134 1321
1135 wil_dbg_misc(wil, "del_key: %pM %s[%d]\n", mac_addr, 1322 wil_dbg_misc(wil, "del_key: %pM %s[%d]\n", mac_addr,
@@ -1142,7 +1329,7 @@ static int wil_cfg80211_del_key(struct wiphy *wiphy,
1142 if (!IS_ERR_OR_NULL(cs)) 1329 if (!IS_ERR_OR_NULL(cs))
1143 wil_del_rx_key(key_index, key_usage, cs); 1330 wil_del_rx_key(key_index, key_usage, cs);
1144 1331
1145 return wmi_del_cipher_key(wil, key_index, mac_addr, key_usage); 1332 return wmi_del_cipher_key(vif, key_index, mac_addr, key_usage);
1146} 1333}
1147 1334
1148/* Need to be present or wiphy_new() will WARN */ 1335/* Need to be present or wiphy_new() will WARN */
@@ -1179,10 +1366,11 @@ static int wil_cancel_remain_on_channel(struct wiphy *wiphy,
1179 u64 cookie) 1366 u64 cookie)
1180{ 1367{
1181 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1368 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1369 struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
1182 1370
1183 wil_dbg_misc(wil, "cancel_remain_on_channel\n"); 1371 wil_dbg_misc(wil, "cancel_remain_on_channel\n");
1184 1372
1185 return wil_p2p_cancel_listen(wil, cookie); 1373 return wil_p2p_cancel_listen(vif, cookie);
1186} 1374}
1187 1375
1188/** 1376/**
@@ -1275,11 +1463,10 @@ static void wil_print_bcon_data(struct cfg80211_beacon_data *b)
1275} 1463}
1276 1464
1277/* internal functions for device reset and starting AP */ 1465/* internal functions for device reset and starting AP */
1278static int _wil_cfg80211_set_ies(struct wiphy *wiphy, 1466static int _wil_cfg80211_set_ies(struct wil6210_vif *vif,
1279 struct cfg80211_beacon_data *bcon) 1467 struct cfg80211_beacon_data *bcon)
1280{ 1468{
1281 int rc; 1469 int rc;
1282 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1283 u16 len = 0, proberesp_len = 0; 1470 u16 len = 0, proberesp_len = 0;
1284 u8 *ies = NULL, *proberesp = NULL; 1471 u8 *ies = NULL, *proberesp = NULL;
1285 1472
@@ -1300,20 +1487,21 @@ static int _wil_cfg80211_set_ies(struct wiphy *wiphy,
1300 if (rc) 1487 if (rc)
1301 goto out; 1488 goto out;
1302 1489
1303 rc = wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, len, ies); 1490 rc = wmi_set_ie(vif, WMI_FRAME_PROBE_RESP, len, ies);
1304 if (rc) 1491 if (rc)
1305 goto out; 1492 goto out;
1306 1493
1307 if (bcon->assocresp_ies) 1494 if (bcon->assocresp_ies)
1308 rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, 1495 rc = wmi_set_ie(vif, WMI_FRAME_ASSOC_RESP,
1309 bcon->assocresp_ies_len, bcon->assocresp_ies); 1496 bcon->assocresp_ies_len, bcon->assocresp_ies);
1310 else 1497 else
1311 rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, len, ies); 1498 rc = wmi_set_ie(vif, WMI_FRAME_ASSOC_RESP, len, ies);
1312#if 0 /* to use beacon IE's, remove this #if 0 */ 1499#if 0 /* to use beacon IE's, remove this #if 0 */
1313 if (rc) 1500 if (rc)
1314 goto out; 1501 goto out;
1315 1502
1316 rc = wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->tail_len, bcon->tail); 1503 rc = wmi_set_ie(vif, WMI_FRAME_BEACON,
1504 bcon->tail_len, bcon->tail);
1317#endif 1505#endif
1318out: 1506out:
1319 kfree(ies); 1507 kfree(ies);
@@ -1328,6 +1516,7 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
1328 u8 hidden_ssid, u32 pbss) 1516 u8 hidden_ssid, u32 pbss)
1329{ 1517{
1330 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1518 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1519 struct wil6210_vif *vif = ndev_to_vif(ndev);
1331 int rc; 1520 int rc;
1332 struct wireless_dev *wdev = ndev->ieee80211_ptr; 1521 struct wireless_dev *wdev = ndev->ieee80211_ptr;
1333 u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype); 1522 u8 wmi_nettype = wil_iftype_nl2wmi(wdev->iftype);
@@ -1336,7 +1525,7 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
1336 if (pbss) 1525 if (pbss)
1337 wmi_nettype = WMI_NETTYPE_P2P; 1526 wmi_nettype = WMI_NETTYPE_P2P;
1338 1527
1339 wil_dbg_misc(wil, "start_ap: is_go=%d\n", is_go); 1528 wil_dbg_misc(wil, "start_ap: mid=%d, is_go=%d\n", vif->mid, is_go);
1340 if (is_go && !pbss) { 1529 if (is_go && !pbss) {
1341 wil_err(wil, "P2P GO must be in PBSS\n"); 1530 wil_err(wil, "P2P GO must be in PBSS\n");
1342 return -ENOTSUPP; 1531 return -ENOTSUPP;
@@ -1346,42 +1535,46 @@ static int _wil_cfg80211_start_ap(struct wiphy *wiphy,
1346 1535
1347 mutex_lock(&wil->mutex); 1536 mutex_lock(&wil->mutex);
1348 1537
1349 __wil_down(wil); 1538 if (!wil_has_other_active_ifaces(wil, ndev, true, false)) {
1350 rc = __wil_up(wil); 1539 __wil_down(wil);
1351 if (rc) 1540 rc = __wil_up(wil);
1352 goto out; 1541 if (rc)
1542 goto out;
1543 }
1353 1544
1354 rc = wmi_set_ssid(wil, ssid_len, ssid); 1545 rc = wmi_set_ssid(vif, ssid_len, ssid);
1355 if (rc) 1546 if (rc)
1356 goto out; 1547 goto out;
1357 1548
1358 rc = _wil_cfg80211_set_ies(wiphy, bcon); 1549 rc = _wil_cfg80211_set_ies(vif, bcon);
1359 if (rc) 1550 if (rc)
1360 goto out; 1551 goto out;
1361 1552
1362 wil->privacy = privacy; 1553 vif->privacy = privacy;
1363 wil->channel = chan; 1554 vif->channel = chan;
1364 wil->hidden_ssid = hidden_ssid; 1555 vif->hidden_ssid = hidden_ssid;
1365 wil->pbss = pbss; 1556 vif->pbss = pbss;
1366 1557
1367 netif_carrier_on(ndev); 1558 netif_carrier_on(ndev);
1368 wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS); 1559 if (!wil_has_other_active_ifaces(wil, ndev, false, true))
1560 wil6210_bus_request(wil, WIL_MAX_BUS_REQUEST_KBPS);
1369 1561
1370 rc = wmi_pcp_start(wil, bi, wmi_nettype, chan, hidden_ssid, is_go); 1562 rc = wmi_pcp_start(vif, bi, wmi_nettype, chan, hidden_ssid, is_go);
1371 if (rc) 1563 if (rc)
1372 goto err_pcp_start; 1564 goto err_pcp_start;
1373 1565
1374 rc = wil_bcast_init(wil); 1566 rc = wil_bcast_init(vif);
1375 if (rc) 1567 if (rc)
1376 goto err_bcast; 1568 goto err_bcast;
1377 1569
1378 goto out; /* success */ 1570 goto out; /* success */
1379 1571
1380err_bcast: 1572err_bcast:
1381 wmi_pcp_stop(wil); 1573 wmi_pcp_stop(vif);
1382err_pcp_start: 1574err_pcp_start:
1383 netif_carrier_off(ndev); 1575 netif_carrier_off(ndev);
1384 wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS); 1576 if (!wil_has_other_active_ifaces(wil, ndev, false, true))
1577 wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
1385out: 1578out:
1386 mutex_unlock(&wil->mutex); 1579 mutex_unlock(&wil->mutex);
1387 return rc; 1580 return rc;
@@ -1392,10 +1585,11 @@ static int wil_cfg80211_change_beacon(struct wiphy *wiphy,
1392 struct cfg80211_beacon_data *bcon) 1585 struct cfg80211_beacon_data *bcon)
1393{ 1586{
1394 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1587 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1588 struct wil6210_vif *vif = ndev_to_vif(ndev);
1395 int rc; 1589 int rc;
1396 u32 privacy = 0; 1590 u32 privacy = 0;
1397 1591
1398 wil_dbg_misc(wil, "change_beacon\n"); 1592 wil_dbg_misc(wil, "change_beacon, mid=%d\n", vif->mid);
1399 wil_print_bcon_data(bcon); 1593 wil_print_bcon_data(bcon);
1400 1594
1401 if (bcon->tail && 1595 if (bcon->tail &&
@@ -1404,20 +1598,20 @@ static int wil_cfg80211_change_beacon(struct wiphy *wiphy,
1404 privacy = 1; 1598 privacy = 1;
1405 1599
1406 /* in case privacy has changed, need to restart the AP */ 1600 /* in case privacy has changed, need to restart the AP */
1407 if (wil->privacy != privacy) { 1601 if (vif->privacy != privacy) {
1408 struct wireless_dev *wdev = ndev->ieee80211_ptr; 1602 struct wireless_dev *wdev = ndev->ieee80211_ptr;
1409 1603
1410 wil_dbg_misc(wil, "privacy changed %d=>%d. Restarting AP\n", 1604 wil_dbg_misc(wil, "privacy changed %d=>%d. Restarting AP\n",
1411 wil->privacy, privacy); 1605 vif->privacy, privacy);
1412 1606
1413 rc = _wil_cfg80211_start_ap(wiphy, ndev, wdev->ssid, 1607 rc = _wil_cfg80211_start_ap(wiphy, ndev, wdev->ssid,
1414 wdev->ssid_len, privacy, 1608 wdev->ssid_len, privacy,
1415 wdev->beacon_interval, 1609 wdev->beacon_interval,
1416 wil->channel, bcon, 1610 vif->channel, bcon,
1417 wil->hidden_ssid, 1611 vif->hidden_ssid,
1418 wil->pbss); 1612 vif->pbss);
1419 } else { 1613 } else {
1420 rc = _wil_cfg80211_set_ies(wiphy, bcon); 1614 rc = _wil_cfg80211_set_ies(vif, bcon);
1421 } 1615 }
1422 1616
1423 return rc; 1617 return rc;
@@ -1484,20 +1678,27 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
1484 struct net_device *ndev) 1678 struct net_device *ndev)
1485{ 1679{
1486 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1680 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1681 struct wil6210_vif *vif = ndev_to_vif(ndev);
1682 bool last;
1487 1683
1488 wil_dbg_misc(wil, "stop_ap\n"); 1684 wil_dbg_misc(wil, "stop_ap, mid=%d\n", vif->mid);
1489 1685
1490 netif_carrier_off(ndev); 1686 netif_carrier_off(ndev);
1491 wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS); 1687 last = !wil_has_other_active_ifaces(wil, ndev, false, true);
1492 wil_set_recovery_state(wil, fw_recovery_idle); 1688 if (last) {
1493 1689 wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
1494 set_bit(wil_status_resetting, wil->status); 1690 wil_set_recovery_state(wil, fw_recovery_idle);
1691 set_bit(wil_status_resetting, wil->status);
1692 }
1495 1693
1496 mutex_lock(&wil->mutex); 1694 mutex_lock(&wil->mutex);
1497 1695
1498 wmi_pcp_stop(wil); 1696 wmi_pcp_stop(vif);
1499 1697
1500 __wil_down(wil); 1698 if (last)
1699 __wil_down(wil);
1700 else
1701 wil_bcast_fini(vif);
1501 1702
1502 mutex_unlock(&wil->mutex); 1703 mutex_unlock(&wil->mutex);
1503 1704
@@ -1509,9 +1710,11 @@ static int wil_cfg80211_add_station(struct wiphy *wiphy,
1509 const u8 *mac, 1710 const u8 *mac,
1510 struct station_parameters *params) 1711 struct station_parameters *params)
1511{ 1712{
1713 struct wil6210_vif *vif = ndev_to_vif(dev);
1512 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1714 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1513 1715
1514 wil_dbg_misc(wil, "add station %pM aid %d\n", mac, params->aid); 1716 wil_dbg_misc(wil, "add station %pM aid %d mid %d\n",
1717 mac, params->aid, vif->mid);
1515 1718
1516 if (!disable_ap_sme) { 1719 if (!disable_ap_sme) {
1517 wil_err(wil, "not supported with AP SME enabled\n"); 1720 wil_err(wil, "not supported with AP SME enabled\n");
@@ -1523,20 +1726,21 @@ static int wil_cfg80211_add_station(struct wiphy *wiphy,
1523 return -EINVAL; 1726 return -EINVAL;
1524 } 1727 }
1525 1728
1526 return wmi_new_sta(wil, mac, params->aid); 1729 return wmi_new_sta(vif, mac, params->aid);
1527} 1730}
1528 1731
1529static int wil_cfg80211_del_station(struct wiphy *wiphy, 1732static int wil_cfg80211_del_station(struct wiphy *wiphy,
1530 struct net_device *dev, 1733 struct net_device *dev,
1531 struct station_del_parameters *params) 1734 struct station_del_parameters *params)
1532{ 1735{
1736 struct wil6210_vif *vif = ndev_to_vif(dev);
1533 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1737 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1534 1738
1535 wil_dbg_misc(wil, "del_station: %pM, reason=%d\n", params->mac, 1739 wil_dbg_misc(wil, "del_station: %pM, reason=%d mid=%d\n",
1536 params->reason_code); 1740 params->mac, params->reason_code, vif->mid);
1537 1741
1538 mutex_lock(&wil->mutex); 1742 mutex_lock(&wil->mutex);
1539 wil6210_disconnect(wil, params->mac, params->reason_code, false); 1743 wil6210_disconnect(vif, params->mac, params->reason_code, false);
1540 mutex_unlock(&wil->mutex); 1744 mutex_unlock(&wil->mutex);
1541 1745
1542 return 0; 1746 return 0;
@@ -1547,13 +1751,15 @@ static int wil_cfg80211_change_station(struct wiphy *wiphy,
1547 const u8 *mac, 1751 const u8 *mac,
1548 struct station_parameters *params) 1752 struct station_parameters *params)
1549{ 1753{
1754 struct wil6210_vif *vif = ndev_to_vif(dev);
1550 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1755 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1551 int authorize; 1756 int authorize;
1552 int cid, i; 1757 int cid, i;
1553 struct vring_tx_data *txdata = NULL; 1758 struct vring_tx_data *txdata = NULL;
1554 1759
1555 wil_dbg_misc(wil, "change station %pM mask 0x%x set 0x%x\n", mac, 1760 wil_dbg_misc(wil, "change station %pM mask 0x%x set 0x%x mid %d\n",
1556 params->sta_flags_mask, params->sta_flags_set); 1761 mac, params->sta_flags_mask, params->sta_flags_set,
1762 vif->mid);
1557 1763
1558 if (!disable_ap_sme) { 1764 if (!disable_ap_sme) {
1559 wil_dbg_misc(wil, "not supported with AP SME enabled\n"); 1765 wil_dbg_misc(wil, "not supported with AP SME enabled\n");
@@ -1563,7 +1769,7 @@ static int wil_cfg80211_change_station(struct wiphy *wiphy,
1563 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED))) 1769 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
1564 return 0; 1770 return 0;
1565 1771
1566 cid = wil_find_cid(wil, mac); 1772 cid = wil_find_cid(wil, vif->mid, mac);
1567 if (cid < 0) { 1773 if (cid < 0) {
1568 wil_err(wil, "station not found\n"); 1774 wil_err(wil, "station not found\n");
1569 return -ENOLINK; 1775 return -ENOLINK;
@@ -1590,9 +1796,10 @@ static int wil_cfg80211_change_station(struct wiphy *wiphy,
1590 1796
1591/* probe_client handling */ 1797/* probe_client handling */
1592static void wil_probe_client_handle(struct wil6210_priv *wil, 1798static void wil_probe_client_handle(struct wil6210_priv *wil,
1799 struct wil6210_vif *vif,
1593 struct wil_probe_client_req *req) 1800 struct wil_probe_client_req *req)
1594{ 1801{
1595 struct net_device *ndev = wil_to_ndev(wil); 1802 struct net_device *ndev = vif_to_ndev(vif);
1596 struct wil_sta_info *sta = &wil->sta[req->cid]; 1803 struct wil_sta_info *sta = &wil->sta[req->cid];
1597 /* assume STA is alive if it is still connected, 1804 /* assume STA is alive if it is still connected,
1598 * else FW will disconnect it 1805 * else FW will disconnect it
@@ -1603,51 +1810,53 @@ static void wil_probe_client_handle(struct wil6210_priv *wil,
1603 0, false, GFP_KERNEL); 1810 0, false, GFP_KERNEL);
1604} 1811}
1605 1812
1606static struct list_head *next_probe_client(struct wil6210_priv *wil) 1813static struct list_head *next_probe_client(struct wil6210_vif *vif)
1607{ 1814{
1608 struct list_head *ret = NULL; 1815 struct list_head *ret = NULL;
1609 1816
1610 mutex_lock(&wil->probe_client_mutex); 1817 mutex_lock(&vif->probe_client_mutex);
1611 1818
1612 if (!list_empty(&wil->probe_client_pending)) { 1819 if (!list_empty(&vif->probe_client_pending)) {
1613 ret = wil->probe_client_pending.next; 1820 ret = vif->probe_client_pending.next;
1614 list_del(ret); 1821 list_del(ret);
1615 } 1822 }
1616 1823
1617 mutex_unlock(&wil->probe_client_mutex); 1824 mutex_unlock(&vif->probe_client_mutex);
1618 1825
1619 return ret; 1826 return ret;
1620} 1827}
1621 1828
1622void wil_probe_client_worker(struct work_struct *work) 1829void wil_probe_client_worker(struct work_struct *work)
1623{ 1830{
1624 struct wil6210_priv *wil = container_of(work, struct wil6210_priv, 1831 struct wil6210_vif *vif = container_of(work, struct wil6210_vif,
1625 probe_client_worker); 1832 probe_client_worker);
1833 struct wil6210_priv *wil = vif_to_wil(vif);
1626 struct wil_probe_client_req *req; 1834 struct wil_probe_client_req *req;
1627 struct list_head *lh; 1835 struct list_head *lh;
1628 1836
1629 while ((lh = next_probe_client(wil)) != NULL) { 1837 while ((lh = next_probe_client(vif)) != NULL) {
1630 req = list_entry(lh, struct wil_probe_client_req, list); 1838 req = list_entry(lh, struct wil_probe_client_req, list);
1631 1839
1632 wil_probe_client_handle(wil, req); 1840 wil_probe_client_handle(wil, vif, req);
1633 kfree(req); 1841 kfree(req);
1634 } 1842 }
1635} 1843}
1636 1844
1637void wil_probe_client_flush(struct wil6210_priv *wil) 1845void wil_probe_client_flush(struct wil6210_vif *vif)
1638{ 1846{
1639 struct wil_probe_client_req *req, *t; 1847 struct wil_probe_client_req *req, *t;
1848 struct wil6210_priv *wil = vif_to_wil(vif);
1640 1849
1641 wil_dbg_misc(wil, "probe_client_flush\n"); 1850 wil_dbg_misc(wil, "probe_client_flush\n");
1642 1851
1643 mutex_lock(&wil->probe_client_mutex); 1852 mutex_lock(&vif->probe_client_mutex);
1644 1853
1645 list_for_each_entry_safe(req, t, &wil->probe_client_pending, list) { 1854 list_for_each_entry_safe(req, t, &vif->probe_client_pending, list) {
1646 list_del(&req->list); 1855 list_del(&req->list);
1647 kfree(req); 1856 kfree(req);
1648 } 1857 }
1649 1858
1650 mutex_unlock(&wil->probe_client_mutex); 1859 mutex_unlock(&vif->probe_client_mutex);
1651} 1860}
1652 1861
1653static int wil_cfg80211_probe_client(struct wiphy *wiphy, 1862static int wil_cfg80211_probe_client(struct wiphy *wiphy,
@@ -1655,10 +1864,12 @@ static int wil_cfg80211_probe_client(struct wiphy *wiphy,
1655 const u8 *peer, u64 *cookie) 1864 const u8 *peer, u64 *cookie)
1656{ 1865{
1657 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1866 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1867 struct wil6210_vif *vif = ndev_to_vif(dev);
1658 struct wil_probe_client_req *req; 1868 struct wil_probe_client_req *req;
1659 int cid = wil_find_cid(wil, peer); 1869 int cid = wil_find_cid(wil, vif->mid, peer);
1660 1870
1661 wil_dbg_misc(wil, "probe_client: %pM => CID %d\n", peer, cid); 1871 wil_dbg_misc(wil, "probe_client: %pM => CID %d MID %d\n",
1872 peer, cid, vif->mid);
1662 1873
1663 if (cid < 0) 1874 if (cid < 0)
1664 return -ENOLINK; 1875 return -ENOLINK;
@@ -1670,12 +1881,12 @@ static int wil_cfg80211_probe_client(struct wiphy *wiphy,
1670 req->cid = cid; 1881 req->cid = cid;
1671 req->cookie = cid; 1882 req->cookie = cid;
1672 1883
1673 mutex_lock(&wil->probe_client_mutex); 1884 mutex_lock(&vif->probe_client_mutex);
1674 list_add_tail(&req->list, &wil->probe_client_pending); 1885 list_add_tail(&req->list, &vif->probe_client_pending);
1675 mutex_unlock(&wil->probe_client_mutex); 1886 mutex_unlock(&vif->probe_client_mutex);
1676 1887
1677 *cookie = req->cookie; 1888 *cookie = req->cookie;
1678 queue_work(wil->wq_service, &wil->probe_client_worker); 1889 queue_work(wil->wq_service, &vif->probe_client_worker);
1679 return 0; 1890 return 0;
1680} 1891}
1681 1892
@@ -1684,11 +1895,12 @@ static int wil_cfg80211_change_bss(struct wiphy *wiphy,
1684 struct bss_parameters *params) 1895 struct bss_parameters *params)
1685{ 1896{
1686 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1897 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1898 struct wil6210_vif *vif = ndev_to_vif(dev);
1687 1899
1688 if (params->ap_isolate >= 0) { 1900 if (params->ap_isolate >= 0) {
1689 wil_dbg_misc(wil, "change_bss: ap_isolate %d => %d\n", 1901 wil_dbg_misc(wil, "change_bss: ap_isolate MID %d, %d => %d\n",
1690 wil->ap_isolate, params->ap_isolate); 1902 vif->mid, vif->ap_isolate, params->ap_isolate);
1691 wil->ap_isolate = params->ap_isolate; 1903 vif->ap_isolate = params->ap_isolate;
1692 } 1904 }
1693 1905
1694 return 0; 1906 return 0;
@@ -1732,10 +1944,10 @@ static int wil_cfg80211_suspend(struct wiphy *wiphy,
1732 wil_dbg_pm(wil, "suspending\n"); 1944 wil_dbg_pm(wil, "suspending\n");
1733 1945
1734 mutex_lock(&wil->mutex); 1946 mutex_lock(&wil->mutex);
1735 mutex_lock(&wil->p2p_wdev_mutex); 1947 mutex_lock(&wil->vif_mutex);
1736 wil_p2p_stop_radio_operations(wil); 1948 wil_p2p_stop_radio_operations(wil);
1737 wil_abort_scan(wil, true); 1949 wil_abort_scan_all_vifs(wil, true);
1738 mutex_unlock(&wil->p2p_wdev_mutex); 1950 mutex_unlock(&wil->vif_mutex);
1739 mutex_unlock(&wil->mutex); 1951 mutex_unlock(&wil->mutex);
1740 1952
1741out: 1953out:
@@ -1757,8 +1969,12 @@ wil_cfg80211_sched_scan_start(struct wiphy *wiphy,
1757 struct cfg80211_sched_scan_request *request) 1969 struct cfg80211_sched_scan_request *request)
1758{ 1970{
1759 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 1971 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
1972 struct wil6210_vif *vif = ndev_to_vif(dev);
1760 int i, rc; 1973 int i, rc;
1761 1974
1975 if (vif->mid != 0)
1976 return -EOPNOTSUPP;
1977
1762 wil_dbg_misc(wil, 1978 wil_dbg_misc(wil,
1763 "sched scan start: n_ssids %d, ie_len %zu, flags 0x%x\n", 1979 "sched scan start: n_ssids %d, ie_len %zu, flags 0x%x\n",
1764 request->n_ssids, request->ie_len, request->flags); 1980 request->n_ssids, request->ie_len, request->flags);
@@ -1792,7 +2008,8 @@ wil_cfg80211_sched_scan_start(struct wiphy *wiphy,
1792 i, sp->interval, sp->iterations); 2008 i, sp->interval, sp->iterations);
1793 } 2009 }
1794 2010
1795 rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len, request->ie); 2011 rc = wmi_set_ie(vif, WMI_FRAME_PROBE_REQ,
2012 request->ie_len, request->ie);
1796 if (rc) 2013 if (rc)
1797 return rc; 2014 return rc;
1798 return wmi_start_sched_scan(wil, request); 2015 return wmi_start_sched_scan(wil, request);
@@ -1803,8 +2020,12 @@ wil_cfg80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev,
1803 u64 reqid) 2020 u64 reqid)
1804{ 2021{
1805 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 2022 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
2023 struct wil6210_vif *vif = ndev_to_vif(dev);
1806 int rc; 2024 int rc;
1807 2025
2026 if (vif->mid != 0)
2027 return -EOPNOTSUPP;
2028
1808 rc = wmi_stop_sched_scan(wil); 2029 rc = wmi_stop_sched_scan(wil);
1809 /* device would return error if it thinks PNO is already stopped. 2030 /* device would return error if it thinks PNO is already stopped.
1810 * ignore the return code so user space and driver gets back in-sync 2031 * ignore the return code so user space and driver gets back in-sync
@@ -1893,57 +2114,132 @@ static void wil_wiphy_init(struct wiphy *wiphy)
1893#endif 2114#endif
1894} 2115}
1895 2116
1896struct wireless_dev *wil_cfg80211_init(struct device *dev) 2117int wil_cfg80211_iface_combinations_from_fw(
2118 struct wil6210_priv *wil, const struct wil_fw_record_concurrency *conc)
1897{ 2119{
1898 int rc = 0; 2120 struct wiphy *wiphy = wil_to_wiphy(wil);
1899 struct wireless_dev *wdev; 2121 u32 total_limits = 0;
2122 u16 n_combos;
2123 const struct wil_fw_concurrency_combo *combo;
2124 const struct wil_fw_concurrency_limit *limit;
2125 struct ieee80211_iface_combination *iface_combinations;
2126 struct ieee80211_iface_limit *iface_limit;
2127 int i, j;
2128
2129 if (wiphy->iface_combinations) {
2130 wil_dbg_misc(wil, "iface_combinations already set, skipping\n");
2131 return 0;
2132 }
1900 2133
1901 dev_dbg(dev, "%s()\n", __func__); 2134 combo = conc->combos;
2135 n_combos = le16_to_cpu(conc->n_combos);
2136 for (i = 0; i < n_combos; i++) {
2137 total_limits += combo->n_limits;
2138 limit = combo->limits + combo->n_limits;
2139 combo = (struct wil_fw_concurrency_combo *)limit;
2140 }
1902 2141
1903 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); 2142 iface_combinations =
1904 if (!wdev) 2143 kzalloc(n_combos * sizeof(struct ieee80211_iface_combination) +
1905 return ERR_PTR(-ENOMEM); 2144 total_limits * sizeof(struct ieee80211_iface_limit),
2145 GFP_KERNEL);
2146 if (!iface_combinations)
2147 return -ENOMEM;
2148 iface_limit = (struct ieee80211_iface_limit *)(iface_combinations +
2149 n_combos);
2150 combo = conc->combos;
2151 for (i = 0; i < n_combos; i++) {
2152 iface_combinations[i].max_interfaces = combo->max_interfaces;
2153 iface_combinations[i].num_different_channels =
2154 combo->n_diff_channels;
2155 iface_combinations[i].beacon_int_infra_match =
2156 combo->same_bi;
2157 iface_combinations[i].n_limits = combo->n_limits;
2158 wil_dbg_misc(wil,
2159 "iface_combination %d: max_if %d, num_ch %d, bi_match %d\n",
2160 i, iface_combinations[i].max_interfaces,
2161 iface_combinations[i].num_different_channels,
2162 iface_combinations[i].beacon_int_infra_match);
2163 limit = combo->limits;
2164 for (j = 0; j < combo->n_limits; j++) {
2165 iface_limit[j].max = le16_to_cpu(limit[j].max);
2166 iface_limit[j].types = le16_to_cpu(limit[j].types);
2167 wil_dbg_misc(wil,
2168 "limit %d: max %d types 0x%x\n", j,
2169 iface_limit[j].max, iface_limit[j].types);
2170 }
2171 iface_combinations[i].limits = iface_limit;
2172 iface_limit += combo->n_limits;
2173 limit += combo->n_limits;
2174 combo = (struct wil_fw_concurrency_combo *)limit;
2175 }
1906 2176
1907 wdev->wiphy = wiphy_new(&wil_cfg80211_ops, 2177 wil_dbg_misc(wil, "multiple VIFs supported, n_mids %d\n", conc->n_mids);
1908 sizeof(struct wil6210_priv)); 2178 wil->max_vifs = conc->n_mids + 1; /* including main interface */
1909 if (!wdev->wiphy) { 2179 if (wil->max_vifs > WIL_MAX_VIFS) {
1910 rc = -ENOMEM; 2180 wil_info(wil, "limited number of VIFs supported(%d, FW %d)\n",
1911 goto out; 2181 WIL_MAX_VIFS, wil->max_vifs);
2182 wil->max_vifs = WIL_MAX_VIFS;
1912 } 2183 }
2184 wiphy->n_iface_combinations = n_combos;
2185 wiphy->iface_combinations = iface_combinations;
2186 return 0;
2187}
1913 2188
1914 set_wiphy_dev(wdev->wiphy, dev); 2189struct wil6210_priv *wil_cfg80211_init(struct device *dev)
1915 wil_wiphy_init(wdev->wiphy); 2190{
2191 struct wiphy *wiphy;
2192 struct wil6210_priv *wil;
2193 struct ieee80211_channel *ch;
1916 2194
1917 return wdev; 2195 dev_dbg(dev, "%s()\n", __func__);
1918 2196
1919out: 2197 /* Note: the wireless_dev structure is no longer allocated here.
1920 kfree(wdev); 2198 * Instead, it is allocated as part of the net_device structure
2199 * for main interface and each VIF.
2200 */
2201 wiphy = wiphy_new(&wil_cfg80211_ops, sizeof(struct wil6210_priv));
2202 if (!wiphy)
2203 return ERR_PTR(-ENOMEM);
1921 2204
1922 return ERR_PTR(rc); 2205 set_wiphy_dev(wiphy, dev);
2206 wil_wiphy_init(wiphy);
2207
2208 wil = wiphy_to_wil(wiphy);
2209 wil->wiphy = wiphy;
2210
2211 /* default monitor channel */
2212 ch = wiphy->bands[NL80211_BAND_60GHZ]->channels;
2213 cfg80211_chandef_create(&wil->monitor_chandef, ch, NL80211_CHAN_NO_HT);
2214
2215 return wil;
1923} 2216}
1924 2217
1925void wil_wdev_free(struct wil6210_priv *wil) 2218void wil_cfg80211_deinit(struct wil6210_priv *wil)
1926{ 2219{
1927 struct wireless_dev *wdev = wil_to_wdev(wil); 2220 struct wiphy *wiphy = wil_to_wiphy(wil);
1928 2221
1929 dev_dbg(wil_to_dev(wil), "%s()\n", __func__); 2222 dev_dbg(wil_to_dev(wil), "%s()\n", __func__);
1930 2223
1931 if (!wdev) 2224 if (!wiphy)
1932 return; 2225 return;
1933 2226
1934 wiphy_free(wdev->wiphy); 2227 kfree(wiphy->iface_combinations);
1935 kfree(wdev); 2228 wiphy->iface_combinations = NULL;
2229
2230 wiphy_free(wiphy);
2231 /* do not access wil6210_priv after returning from here */
1936} 2232}
1937 2233
1938void wil_p2p_wdev_free(struct wil6210_priv *wil) 2234void wil_p2p_wdev_free(struct wil6210_priv *wil)
1939{ 2235{
1940 struct wireless_dev *p2p_wdev; 2236 struct wireless_dev *p2p_wdev;
1941 2237
1942 mutex_lock(&wil->p2p_wdev_mutex); 2238 mutex_lock(&wil->vif_mutex);
1943 p2p_wdev = wil->p2p_wdev; 2239 p2p_wdev = wil->p2p_wdev;
1944 wil->p2p_wdev = NULL; 2240 wil->p2p_wdev = NULL;
1945 wil->radio_wdev = wil_to_wdev(wil); 2241 wil->radio_wdev = wil->main_ndev->ieee80211_ptr;
1946 mutex_unlock(&wil->p2p_wdev_mutex); 2242 mutex_unlock(&wil->vif_mutex);
1947 if (p2p_wdev) { 2243 if (p2p_wdev) {
1948 cfg80211_unregister_wdev(p2p_wdev); 2244 cfg80211_unregister_wdev(p2p_wdev);
1949 kfree(p2p_wdev); 2245 kfree(p2p_wdev);
@@ -1971,6 +2267,7 @@ static int wil_rf_sector_get_cfg(struct wiphy *wiphy,
1971 const void *data, int data_len) 2267 const void *data, int data_len)
1972{ 2268{
1973 struct wil6210_priv *wil = wdev_to_wil(wdev); 2269 struct wil6210_priv *wil = wdev_to_wil(wdev);
2270 struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
1974 int rc; 2271 int rc;
1975 struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1]; 2272 struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
1976 u16 sector_index; 2273 u16 sector_index;
@@ -2027,8 +2324,8 @@ static int wil_rf_sector_get_cfg(struct wiphy *wiphy,
2027 cmd.sector_type = sector_type; 2324 cmd.sector_type = sector_type;
2028 cmd.rf_modules_vec = rf_modules_vec & 0xFF; 2325 cmd.rf_modules_vec = rf_modules_vec & 0xFF;
2029 memset(&reply, 0, sizeof(reply)); 2326 memset(&reply, 0, sizeof(reply));
2030 rc = wmi_call(wil, WMI_GET_RF_SECTOR_PARAMS_CMDID, &cmd, sizeof(cmd), 2327 rc = wmi_call(wil, WMI_GET_RF_SECTOR_PARAMS_CMDID, vif->mid,
2031 WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID, 2328 &cmd, sizeof(cmd), WMI_GET_RF_SECTOR_PARAMS_DONE_EVENTID,
2032 &reply, sizeof(reply), 2329 &reply, sizeof(reply),
2033 500); 2330 500);
2034 if (rc) 2331 if (rc)
@@ -2090,6 +2387,7 @@ static int wil_rf_sector_set_cfg(struct wiphy *wiphy,
2090 const void *data, int data_len) 2387 const void *data, int data_len)
2091{ 2388{
2092 struct wil6210_priv *wil = wdev_to_wil(wdev); 2389 struct wil6210_priv *wil = wdev_to_wil(wdev);
2390 struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
2093 int rc, tmp; 2391 int rc, tmp;
2094 struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1]; 2392 struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
2095 struct nlattr *tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_MAX + 1]; 2393 struct nlattr *tb2[QCA_ATTR_DMG_RF_SECTOR_CFG_MAX + 1];
@@ -2184,8 +2482,8 @@ static int wil_rf_sector_set_cfg(struct wiphy *wiphy,
2184 2482
2185 cmd.rf_modules_vec = rf_modules_vec & 0xFF; 2483 cmd.rf_modules_vec = rf_modules_vec & 0xFF;
2186 memset(&reply, 0, sizeof(reply)); 2484 memset(&reply, 0, sizeof(reply));
2187 rc = wmi_call(wil, WMI_SET_RF_SECTOR_PARAMS_CMDID, &cmd, sizeof(cmd), 2485 rc = wmi_call(wil, WMI_SET_RF_SECTOR_PARAMS_CMDID, vif->mid,
2188 WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID, 2486 &cmd, sizeof(cmd), WMI_SET_RF_SECTOR_PARAMS_DONE_EVENTID,
2189 &reply, sizeof(reply), 2487 &reply, sizeof(reply),
2190 500); 2488 500);
2191 if (rc) 2489 if (rc)
@@ -2198,6 +2496,7 @@ static int wil_rf_sector_get_selected(struct wiphy *wiphy,
2198 const void *data, int data_len) 2496 const void *data, int data_len)
2199{ 2497{
2200 struct wil6210_priv *wil = wdev_to_wil(wdev); 2498 struct wil6210_priv *wil = wdev_to_wil(wdev);
2499 struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
2201 int rc; 2500 int rc;
2202 struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1]; 2501 struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
2203 u8 sector_type, mac_addr[ETH_ALEN]; 2502 u8 sector_type, mac_addr[ETH_ALEN];
@@ -2231,13 +2530,13 @@ static int wil_rf_sector_get_selected(struct wiphy *wiphy,
2231 2530
2232 if (tb[QCA_ATTR_MAC_ADDR]) { 2531 if (tb[QCA_ATTR_MAC_ADDR]) {
2233 ether_addr_copy(mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR])); 2532 ether_addr_copy(mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR]));
2234 cid = wil_find_cid(wil, mac_addr); 2533 cid = wil_find_cid(wil, vif->mid, mac_addr);
2235 if (cid < 0) { 2534 if (cid < 0) {
2236 wil_err(wil, "invalid MAC address %pM\n", mac_addr); 2535 wil_err(wil, "invalid MAC address %pM\n", mac_addr);
2237 return -ENOENT; 2536 return -ENOENT;
2238 } 2537 }
2239 } else { 2538 } else {
2240 if (test_bit(wil_status_fwconnected, wil->status)) { 2539 if (test_bit(wil_vif_fwconnected, vif->status)) {
2241 wil_err(wil, "must specify MAC address when connected\n"); 2540 wil_err(wil, "must specify MAC address when connected\n");
2242 return -EINVAL; 2541 return -EINVAL;
2243 } 2542 }
@@ -2247,7 +2546,7 @@ static int wil_rf_sector_get_selected(struct wiphy *wiphy,
2247 cmd.cid = (u8)cid; 2546 cmd.cid = (u8)cid;
2248 cmd.sector_type = sector_type; 2547 cmd.sector_type = sector_type;
2249 memset(&reply, 0, sizeof(reply)); 2548 memset(&reply, 0, sizeof(reply));
2250 rc = wmi_call(wil, WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID, 2549 rc = wmi_call(wil, WMI_GET_SELECTED_RF_SECTOR_INDEX_CMDID, vif->mid,
2251 &cmd, sizeof(cmd), 2550 &cmd, sizeof(cmd),
2252 WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID, 2551 WMI_GET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID,
2253 &reply, sizeof(reply), 2552 &reply, sizeof(reply),
@@ -2280,7 +2579,7 @@ nla_put_failure:
2280} 2579}
2281 2580
2282static int wil_rf_sector_wmi_set_selected(struct wil6210_priv *wil, 2581static int wil_rf_sector_wmi_set_selected(struct wil6210_priv *wil,
2283 u16 sector_index, 2582 u8 mid, u16 sector_index,
2284 u8 sector_type, u8 cid) 2583 u8 sector_type, u8 cid)
2285{ 2584{
2286 struct wmi_set_selected_rf_sector_index_cmd cmd; 2585 struct wmi_set_selected_rf_sector_index_cmd cmd;
@@ -2295,7 +2594,7 @@ static int wil_rf_sector_wmi_set_selected(struct wil6210_priv *wil,
2295 cmd.sector_type = sector_type; 2594 cmd.sector_type = sector_type;
2296 cmd.cid = (u8)cid; 2595 cmd.cid = (u8)cid;
2297 memset(&reply, 0, sizeof(reply)); 2596 memset(&reply, 0, sizeof(reply));
2298 rc = wmi_call(wil, WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID, 2597 rc = wmi_call(wil, WMI_SET_SELECTED_RF_SECTOR_INDEX_CMDID, mid,
2299 &cmd, sizeof(cmd), 2598 &cmd, sizeof(cmd),
2300 WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID, 2599 WMI_SET_SELECTED_RF_SECTOR_INDEX_DONE_EVENTID,
2301 &reply, sizeof(reply), 2600 &reply, sizeof(reply),
@@ -2310,6 +2609,7 @@ static int wil_rf_sector_set_selected(struct wiphy *wiphy,
2310 const void *data, int data_len) 2609 const void *data, int data_len)
2311{ 2610{
2312 struct wil6210_priv *wil = wdev_to_wil(wdev); 2611 struct wil6210_priv *wil = wdev_to_wil(wdev);
2612 struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
2313 int rc; 2613 int rc;
2314 struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1]; 2614 struct nlattr *tb[QCA_ATTR_DMG_RF_SECTOR_MAX + 1];
2315 u16 sector_index; 2615 u16 sector_index;
@@ -2349,7 +2649,7 @@ static int wil_rf_sector_set_selected(struct wiphy *wiphy,
2349 if (tb[QCA_ATTR_MAC_ADDR]) { 2649 if (tb[QCA_ATTR_MAC_ADDR]) {
2350 ether_addr_copy(mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR])); 2650 ether_addr_copy(mac_addr, nla_data(tb[QCA_ATTR_MAC_ADDR]));
2351 if (!is_broadcast_ether_addr(mac_addr)) { 2651 if (!is_broadcast_ether_addr(mac_addr)) {
2352 cid = wil_find_cid(wil, mac_addr); 2652 cid = wil_find_cid(wil, vif->mid, mac_addr);
2353 if (cid < 0) { 2653 if (cid < 0) {
2354 wil_err(wil, "invalid MAC address %pM\n", 2654 wil_err(wil, "invalid MAC address %pM\n",
2355 mac_addr); 2655 mac_addr);
@@ -2363,7 +2663,7 @@ static int wil_rf_sector_set_selected(struct wiphy *wiphy,
2363 cid = -1; 2663 cid = -1;
2364 } 2664 }
2365 } else { 2665 } else {
2366 if (test_bit(wil_status_fwconnected, wil->status)) { 2666 if (test_bit(wil_vif_fwconnected, vif->status)) {
2367 wil_err(wil, "must specify MAC address when connected\n"); 2667 wil_err(wil, "must specify MAC address when connected\n");
2368 return -EINVAL; 2668 return -EINVAL;
2369 } 2669 }
@@ -2371,17 +2671,20 @@ static int wil_rf_sector_set_selected(struct wiphy *wiphy,
2371 } 2671 }
2372 2672
2373 if (cid >= 0) { 2673 if (cid >= 0) {
2374 rc = wil_rf_sector_wmi_set_selected(wil, sector_index, 2674 rc = wil_rf_sector_wmi_set_selected(wil, vif->mid, sector_index,
2375 sector_type, cid); 2675 sector_type, cid);
2376 } else { 2676 } else {
2377 /* unlock all cids */ 2677 /* unlock all cids */
2378 rc = wil_rf_sector_wmi_set_selected( 2678 rc = wil_rf_sector_wmi_set_selected(
2379 wil, WMI_INVALID_RF_SECTOR_INDEX, sector_type, 2679 wil, vif->mid, WMI_INVALID_RF_SECTOR_INDEX,
2380 WIL_CID_ALL); 2680 sector_type, WIL_CID_ALL);
2381 if (rc == -EINVAL) { 2681 if (rc == -EINVAL) {
2382 for (i = 0; i < WIL6210_MAX_CID; i++) { 2682 for (i = 0; i < WIL6210_MAX_CID; i++) {
2683 if (wil->sta[i].mid != vif->mid)
2684 continue;
2383 rc = wil_rf_sector_wmi_set_selected( 2685 rc = wil_rf_sector_wmi_set_selected(
2384 wil, WMI_INVALID_RF_SECTOR_INDEX, 2686 wil, vif->mid,
2687 WMI_INVALID_RF_SECTOR_INDEX,
2385 sector_type, i); 2688 sector_type, i);
2386 /* the FW will silently ignore and return 2689 /* the FW will silently ignore and return
2387 * success for unused cid, so abort the loop 2690 * success for unused cid, so abort the loop
diff --git a/drivers/net/wireless/ath/wil6210/debug.c b/drivers/net/wireless/ath/wil6210/debug.c
index 217a4591bde4..a9befb971cc4 100644
--- a/drivers/net/wireless/ath/wil6210/debug.c
+++ b/drivers/net/wireless/ath/wil6210/debug.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2013,2016 Qualcomm Atheros, Inc. 2 * Copyright (c) 2013,2016 Qualcomm Atheros, Inc.
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
3 * 4 *
4 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -25,7 +26,7 @@ void __wil_err(struct wil6210_priv *wil, const char *fmt, ...)
25 va_start(args, fmt); 26 va_start(args, fmt);
26 vaf.fmt = fmt; 27 vaf.fmt = fmt;
27 vaf.va = &args; 28 vaf.va = &args;
28 netdev_err(wil_to_ndev(wil), "%pV", &vaf); 29 netdev_err(wil->main_ndev, "%pV", &vaf);
29 trace_wil6210_log_err(&vaf); 30 trace_wil6210_log_err(&vaf);
30 va_end(args); 31 va_end(args);
31} 32}
@@ -41,7 +42,7 @@ void __wil_err_ratelimited(struct wil6210_priv *wil, const char *fmt, ...)
41 va_start(args, fmt); 42 va_start(args, fmt);
42 vaf.fmt = fmt; 43 vaf.fmt = fmt;
43 vaf.va = &args; 44 vaf.va = &args;
44 netdev_err(wil_to_ndev(wil), "%pV", &vaf); 45 netdev_err(wil->main_ndev, "%pV", &vaf);
45 trace_wil6210_log_err(&vaf); 46 trace_wil6210_log_err(&vaf);
46 va_end(args); 47 va_end(args);
47} 48}
@@ -57,7 +58,7 @@ void wil_dbg_ratelimited(const struct wil6210_priv *wil, const char *fmt, ...)
57 va_start(args, fmt); 58 va_start(args, fmt);
58 vaf.fmt = fmt; 59 vaf.fmt = fmt;
59 vaf.va = &args; 60 vaf.va = &args;
60 netdev_dbg(wil_to_ndev(wil), "%pV", &vaf); 61 netdev_dbg(wil->main_ndev, "%pV", &vaf);
61 trace_wil6210_log_dbg(&vaf); 62 trace_wil6210_log_dbg(&vaf);
62 va_end(args); 63 va_end(args);
63} 64}
@@ -70,7 +71,7 @@ void __wil_info(struct wil6210_priv *wil, const char *fmt, ...)
70 va_start(args, fmt); 71 va_start(args, fmt);
71 vaf.fmt = fmt; 72 vaf.fmt = fmt;
72 vaf.va = &args; 73 vaf.va = &args;
73 netdev_info(wil_to_ndev(wil), "%pV", &vaf); 74 netdev_info(wil->main_ndev, "%pV", &vaf);
74 trace_wil6210_log_info(&vaf); 75 trace_wil6210_log_info(&vaf);
75 va_end(args); 76 va_end(args);
76} 77}
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 4a4888246e8c..8c90b3111f0b 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
3 * 4 *
4 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -621,7 +622,7 @@ static ssize_t wil_write_file_reset(struct file *file, const char __user *buf,
621 size_t len, loff_t *ppos) 622 size_t len, loff_t *ppos)
622{ 623{
623 struct wil6210_priv *wil = file->private_data; 624 struct wil6210_priv *wil = file->private_data;
624 struct net_device *ndev = wil_to_ndev(wil); 625 struct net_device *ndev = wil->main_ndev;
625 626
626 /** 627 /**
627 * BUG: 628 * BUG:
@@ -716,27 +717,44 @@ static ssize_t wil_write_back(struct file *file, const char __user *buf,
716 if (rc < 2) 717 if (rc < 2)
717 return -EINVAL; 718 return -EINVAL;
718 719
719 if (0 == strcmp(cmd, "add")) { 720 if ((strcmp(cmd, "add") == 0) ||
720 if (rc < 3) { 721 (strcmp(cmd, "del_tx") == 0)) {
721 wil_err(wil, "BACK: add require at least 2 params\n"); 722 struct vring_tx_data *txdata;
723
724 if (p1 < 0 || p1 >= WIL6210_MAX_TX_RINGS) {
725 wil_err(wil, "BACK: invalid ring id %d\n", p1);
722 return -EINVAL; 726 return -EINVAL;
723 } 727 }
724 if (rc < 4) 728 txdata = &wil->vring_tx_data[p1];
725 p3 = 0; 729 if (strcmp(cmd, "add") == 0) {
726 wmi_addba(wil, p1, p2, p3); 730 if (rc < 3) {
727 } else if (0 == strcmp(cmd, "del_tx")) { 731 wil_err(wil, "BACK: add require at least 2 params\n");
728 if (rc < 3) 732 return -EINVAL;
729 p2 = WLAN_REASON_QSTA_LEAVE_QBSS; 733 }
730 wmi_delba_tx(wil, p1, p2); 734 if (rc < 4)
731 } else if (0 == strcmp(cmd, "del_rx")) { 735 p3 = 0;
736 wmi_addba(wil, txdata->mid, p1, p2, p3);
737 } else {
738 if (rc < 3)
739 p2 = WLAN_REASON_QSTA_LEAVE_QBSS;
740 wmi_delba_tx(wil, txdata->mid, p1, p2);
741 }
742 } else if (strcmp(cmd, "del_rx") == 0) {
743 struct wil_sta_info *sta;
744
732 if (rc < 3) { 745 if (rc < 3) {
733 wil_err(wil, 746 wil_err(wil,
734 "BACK: del_rx require at least 2 params\n"); 747 "BACK: del_rx require at least 2 params\n");
735 return -EINVAL; 748 return -EINVAL;
736 } 749 }
750 if (p1 < 0 || p1 >= WIL6210_MAX_CID) {
751 wil_err(wil, "BACK: invalid CID %d\n", p1);
752 return -EINVAL;
753 }
737 if (rc < 4) 754 if (rc < 4)
738 p3 = WLAN_REASON_QSTA_LEAVE_QBSS; 755 p3 = WLAN_REASON_QSTA_LEAVE_QBSS;
739 wmi_delba_rx(wil, mk_cidxtid(p1, p2), p3); 756 sta = &wil->sta[p1];
757 wmi_delba_rx(wil, sta->mid, mk_cidxtid(p1, p2), p3);
740 } else { 758 } else {
741 wil_err(wil, "BACK: Unrecognized command \"%s\"\n", cmd); 759 wil_err(wil, "BACK: Unrecognized command \"%s\"\n", cmd);
742 return -EINVAL; 760 return -EINVAL;
@@ -855,7 +873,7 @@ static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf,
855{ 873{
856 struct wil6210_priv *wil = file->private_data; 874 struct wil6210_priv *wil = file->private_data;
857 struct wiphy *wiphy = wil_to_wiphy(wil); 875 struct wiphy *wiphy = wil_to_wiphy(wil);
858 struct wireless_dev *wdev = wil_to_wdev(wil); 876 struct wireless_dev *wdev = wil->main_ndev->ieee80211_ptr;
859 struct cfg80211_mgmt_tx_params params; 877 struct cfg80211_mgmt_tx_params params;
860 int rc; 878 int rc;
861 void *frame; 879 void *frame;
@@ -890,6 +908,7 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,
890 size_t len, loff_t *ppos) 908 size_t len, loff_t *ppos)
891{ 909{
892 struct wil6210_priv *wil = file->private_data; 910 struct wil6210_priv *wil = file->private_data;
911 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
893 struct wmi_cmd_hdr *wmi; 912 struct wmi_cmd_hdr *wmi;
894 void *cmd; 913 void *cmd;
895 int cmdlen = len - sizeof(struct wmi_cmd_hdr); 914 int cmdlen = len - sizeof(struct wmi_cmd_hdr);
@@ -912,7 +931,7 @@ static ssize_t wil_write_file_wmi(struct file *file, const char __user *buf,
912 cmd = (cmdlen > 0) ? &wmi[1] : NULL; 931 cmd = (cmdlen > 0) ? &wmi[1] : NULL;
913 cmdid = le16_to_cpu(wmi->command_id); 932 cmdid = le16_to_cpu(wmi->command_id);
914 933
915 rc1 = wmi_send(wil, cmdid, cmd, cmdlen); 934 rc1 = wmi_send(wil, cmdid, vif->mid, cmd, cmdlen);
916 kfree(wmi); 935 kfree(wmi);
917 936
918 wil_info(wil, "0x%04x[%d] -> %d\n", cmdid, cmdlen, rc1); 937 wil_info(wil, "0x%04x[%d] -> %d\n", cmdid, cmdlen, rc1);
@@ -1050,6 +1069,7 @@ static int wil_bf_debugfs_show(struct seq_file *s, void *data)
1050 int rc; 1069 int rc;
1051 int i; 1070 int i;
1052 struct wil6210_priv *wil = s->private; 1071 struct wil6210_priv *wil = s->private;
1072 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
1053 struct wmi_notify_req_cmd cmd = { 1073 struct wmi_notify_req_cmd cmd = {
1054 .interval_usec = 0, 1074 .interval_usec = 0,
1055 }; 1075 };
@@ -1062,7 +1082,8 @@ static int wil_bf_debugfs_show(struct seq_file *s, void *data)
1062 u32 status; 1082 u32 status;
1063 1083
1064 cmd.cid = i; 1084 cmd.cid = i;
1065 rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd), 1085 rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, vif->mid,
1086 &cmd, sizeof(cmd),
1066 WMI_NOTIFY_REQ_DONE_EVENTID, &reply, 1087 WMI_NOTIFY_REQ_DONE_EVENTID, &reply,
1067 sizeof(reply), 20); 1088 sizeof(reply), 20);
1068 /* if reply is all-0, ignore this CID */ 1089 /* if reply is all-0, ignore this CID */
@@ -1155,7 +1176,7 @@ static const struct file_operations fops_temp = {
1155static int wil_freq_debugfs_show(struct seq_file *s, void *data) 1176static int wil_freq_debugfs_show(struct seq_file *s, void *data)
1156{ 1177{
1157 struct wil6210_priv *wil = s->private; 1178 struct wil6210_priv *wil = s->private;
1158 struct wireless_dev *wdev = wil_to_wdev(wil); 1179 struct wireless_dev *wdev = wil->main_ndev->ieee80211_ptr;
1159 u16 freq = wdev->chandef.chan ? wdev->chandef.chan->center_freq : 0; 1180 u16 freq = wdev->chandef.chan ? wdev->chandef.chan->center_freq : 0;
1160 1181
1161 seq_printf(s, "Freq = %d\n", freq); 1182 seq_printf(s, "Freq = %d\n", freq);
@@ -1185,6 +1206,8 @@ static int wil_link_debugfs_show(struct seq_file *s, void *data)
1185 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { 1206 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
1186 struct wil_sta_info *p = &wil->sta[i]; 1207 struct wil_sta_info *p = &wil->sta[i];
1187 char *status = "unknown"; 1208 char *status = "unknown";
1209 struct wil6210_vif *vif;
1210 u8 mid;
1188 1211
1189 switch (p->status) { 1212 switch (p->status) {
1190 case wil_sta_unused: 1213 case wil_sta_unused:
@@ -1197,16 +1220,24 @@ static int wil_link_debugfs_show(struct seq_file *s, void *data)
1197 status = "connected"; 1220 status = "connected";
1198 break; 1221 break;
1199 } 1222 }
1200 seq_printf(s, "[%d] %pM %s\n", i, p->addr, status); 1223 mid = (p->status != wil_sta_unused) ? p->mid : U8_MAX;
1224 seq_printf(s, "[%d][MID %d] %pM %s\n",
1225 i, mid, p->addr, status);
1201 1226
1202 if (p->status == wil_sta_connected) { 1227 if (p->status != wil_sta_connected)
1203 rc = wil_cid_fill_sinfo(wil, i, &sinfo); 1228 continue;
1229
1230 vif = (mid < wil->max_vifs) ? wil->vifs[mid] : NULL;
1231 if (vif) {
1232 rc = wil_cid_fill_sinfo(vif, i, &sinfo);
1204 if (rc) 1233 if (rc)
1205 return rc; 1234 return rc;
1206 1235
1207 seq_printf(s, " Tx_mcs = %d\n", sinfo.txrate.mcs); 1236 seq_printf(s, " Tx_mcs = %d\n", sinfo.txrate.mcs);
1208 seq_printf(s, " Rx_mcs = %d\n", sinfo.rxrate.mcs); 1237 seq_printf(s, " Rx_mcs = %d\n", sinfo.rxrate.mcs);
1209 seq_printf(s, " SQ = %d\n", sinfo.signal); 1238 seq_printf(s, " SQ = %d\n", sinfo.signal);
1239 } else {
1240 seq_puts(s, " INVALID MID\n");
1210 } 1241 }
1211 } 1242 }
1212 1243
@@ -1229,7 +1260,7 @@ static const struct file_operations fops_link = {
1229static int wil_info_debugfs_show(struct seq_file *s, void *data) 1260static int wil_info_debugfs_show(struct seq_file *s, void *data)
1230{ 1261{
1231 struct wil6210_priv *wil = s->private; 1262 struct wil6210_priv *wil = s->private;
1232 struct net_device *ndev = wil_to_ndev(wil); 1263 struct net_device *ndev = wil->main_ndev;
1233 int is_ac = power_supply_is_system_supplied(); 1264 int is_ac = power_supply_is_system_supplied();
1234 int rx = atomic_xchg(&wil->isr_count_rx, 0); 1265 int rx = atomic_xchg(&wil->isr_count_rx, 0);
1235 int tx = atomic_xchg(&wil->isr_count_tx, 0); 1266 int tx = atomic_xchg(&wil->isr_count_tx, 0);
@@ -1398,6 +1429,7 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
1398 struct wil_sta_info *p = &wil->sta[i]; 1429 struct wil_sta_info *p = &wil->sta[i];
1399 char *status = "unknown"; 1430 char *status = "unknown";
1400 u8 aid = 0; 1431 u8 aid = 0;
1432 u8 mid;
1401 1433
1402 switch (p->status) { 1434 switch (p->status) {
1403 case wil_sta_unused: 1435 case wil_sta_unused:
@@ -1411,7 +1443,9 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
1411 aid = p->aid; 1443 aid = p->aid;
1412 break; 1444 break;
1413 } 1445 }
1414 seq_printf(s, "[%d] %pM %s AID %d\n", i, p->addr, status, aid); 1446 mid = (p->status != wil_sta_unused) ? p->mid : U8_MAX;
1447 seq_printf(s, "[%d] %pM %s MID %d AID %d\n", i, p->addr, status,
1448 mid, aid);
1415 1449
1416 if (p->status == wil_sta_connected) { 1450 if (p->status == wil_sta_connected) {
1417 spin_lock_bh(&p->tid_rx_lock); 1451 spin_lock_bh(&p->tid_rx_lock);
@@ -1461,6 +1495,42 @@ static const struct file_operations fops_sta = {
1461 .llseek = seq_lseek, 1495 .llseek = seq_lseek,
1462}; 1496};
1463 1497
1498static int wil_mids_debugfs_show(struct seq_file *s, void *data)
1499{
1500 struct wil6210_priv *wil = s->private;
1501 struct wil6210_vif *vif;
1502 struct net_device *ndev;
1503 int i;
1504
1505 mutex_lock(&wil->vif_mutex);
1506 for (i = 0; i < wil->max_vifs; i++) {
1507 vif = wil->vifs[i];
1508
1509 if (vif) {
1510 ndev = vif_to_ndev(vif);
1511 seq_printf(s, "[%d] %pM %s\n", i, ndev->dev_addr,
1512 ndev->name);
1513 } else {
1514 seq_printf(s, "[%d] unused\n", i);
1515 }
1516 }
1517 mutex_unlock(&wil->vif_mutex);
1518
1519 return 0;
1520}
1521
1522static int wil_mids_seq_open(struct inode *inode, struct file *file)
1523{
1524 return single_open(file, wil_mids_debugfs_show, inode->i_private);
1525}
1526
1527static const struct file_operations fops_mids = {
1528 .open = wil_mids_seq_open,
1529 .release = single_release,
1530 .read = seq_read,
1531 .llseek = seq_lseek,
1532};
1533
1464static ssize_t wil_read_file_led_cfg(struct file *file, char __user *user_buf, 1534static ssize_t wil_read_file_led_cfg(struct file *file, char __user *user_buf,
1465 size_t count, loff_t *ppos) 1535 size_t count, loff_t *ppos)
1466{ 1536{
@@ -1715,6 +1785,7 @@ static const struct {
1715 {"mbox", 0444, &fops_mbox}, 1785 {"mbox", 0444, &fops_mbox},
1716 {"vrings", 0444, &fops_vring}, 1786 {"vrings", 0444, &fops_vring},
1717 {"stations", 0444, &fops_sta}, 1787 {"stations", 0444, &fops_sta},
1788 {"mids", 0444, &fops_mids},
1718 {"desc", 0444, &fops_txdesc}, 1789 {"desc", 0444, &fops_txdesc},
1719 {"bf", 0444, &fops_bf}, 1790 {"bf", 0444, &fops_bf},
1720 {"mem_val", 0644, &fops_memread}, 1791 {"mem_val", 0644, &fops_memread},
@@ -1773,11 +1844,9 @@ static void wil6210_debugfs_init_isr(struct wil6210_priv *wil,
1773 1844
1774/* fields in struct wil6210_priv */ 1845/* fields in struct wil6210_priv */
1775static const struct dbg_off dbg_wil_off[] = { 1846static const struct dbg_off dbg_wil_off[] = {
1776 WIL_FIELD(privacy, 0444, doff_u32),
1777 WIL_FIELD(status[0], 0644, doff_ulong), 1847 WIL_FIELD(status[0], 0644, doff_ulong),
1778 WIL_FIELD(hw_version, 0444, doff_x32), 1848 WIL_FIELD(hw_version, 0444, doff_x32),
1779 WIL_FIELD(recovery_count, 0444, doff_u32), 1849 WIL_FIELD(recovery_count, 0444, doff_u32),
1780 WIL_FIELD(ap_isolate, 0444, doff_u32),
1781 WIL_FIELD(discovery_mode, 0644, doff_u8), 1850 WIL_FIELD(discovery_mode, 0644, doff_u8),
1782 WIL_FIELD(chip_revision, 0444, doff_u8), 1851 WIL_FIELD(chip_revision, 0444, doff_u8),
1783 WIL_FIELD(abft_len, 0644, doff_u8), 1852 WIL_FIELD(abft_len, 0644, doff_u8),
diff --git a/drivers/net/wireless/ath/wil6210/ethtool.c b/drivers/net/wireless/ath/wil6210/ethtool.c
index 66200f616a37..e7ff41e623d2 100644
--- a/drivers/net/wireless/ath/wil6210/ethtool.c
+++ b/drivers/net/wireless/ath/wil6210/ethtool.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2014,2017 Qualcomm Atheros, Inc. 2 * Copyright (c) 2014,2017 Qualcomm Atheros, Inc.
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
3 * 4 *
4 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -74,12 +75,13 @@ static int wil_ethtoolops_set_coalesce(struct net_device *ndev,
74 struct ethtool_coalesce *cp) 75 struct ethtool_coalesce *cp)
75{ 76{
76 struct wil6210_priv *wil = ndev_to_wil(ndev); 77 struct wil6210_priv *wil = ndev_to_wil(ndev);
78 struct wireless_dev *wdev = ndev->ieee80211_ptr;
77 int ret; 79 int ret;
78 80
79 wil_dbg_misc(wil, "ethtoolops_set_coalesce: rx %d usec, tx %d usec\n", 81 wil_dbg_misc(wil, "ethtoolops_set_coalesce: rx %d usec, tx %d usec\n",
80 cp->rx_coalesce_usecs, cp->tx_coalesce_usecs); 82 cp->rx_coalesce_usecs, cp->tx_coalesce_usecs);
81 83
82 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { 84 if (wdev->iftype == NL80211_IFTYPE_MONITOR) {
83 wil_dbg_misc(wil, "No IRQ coalescing in monitor mode\n"); 85 wil_dbg_misc(wil, "No IRQ coalescing in monitor mode\n");
84 return -EINVAL; 86 return -EINVAL;
85 } 87 }
diff --git a/drivers/net/wireless/ath/wil6210/fw.h b/drivers/net/wireless/ath/wil6210/fw.h
index 2c7b24f61587..3e7a28045cab 100644
--- a/drivers/net/wireless/ath/wil6210/fw.h
+++ b/drivers/net/wireless/ath/wil6210/fw.h
@@ -14,6 +14,8 @@
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */ 16 */
17#ifndef __WIL_FW_H__
18#define __WIL_FW_H__
17 19
18#define WIL_FW_SIGNATURE (0x36323130) /* '0126' */ 20#define WIL_FW_SIGNATURE (0x36323130) /* '0126' */
19#define WIL_FW_FMT_VERSION (1) /* format version driver supports */ 21#define WIL_FW_FMT_VERSION (1) /* format version driver supports */
@@ -71,7 +73,39 @@ struct wil_fw_record_capabilities { /* type == wil_fw_type_comment */
71 struct wil_fw_record_comment_hdr hdr; 73 struct wil_fw_record_comment_hdr hdr;
72 /* capabilities (variable size), see enum wmi_fw_capability */ 74 /* capabilities (variable size), see enum wmi_fw_capability */
73 u8 capabilities[0]; 75 u8 capabilities[0];
74}; 76} __packed;
77
78/* FW VIF concurrency encoded inside a comment record
79 * Format is similar to wiphy->iface_combinations
80 */
81#define WIL_FW_CONCURRENCY_MAGIC (0xfedccdef)
82#define WIL_FW_CONCURRENCY_REC_VER 1
83struct wil_fw_concurrency_limit {
84 __le16 max; /* maximum number of interfaces of these types */
85 __le16 types; /* interface types (bit mask of enum nl80211_iftype) */
86} __packed;
87
88struct wil_fw_concurrency_combo {
89 u8 n_limits; /* number of wil_fw_concurrency_limit entries */
90 u8 max_interfaces; /* max number of concurrent interfaces allowed */
91 u8 n_diff_channels; /* total number of different channels allowed */
92 u8 same_bi; /* for APs, 1 if all APs must have same BI */
93 /* keep last - concurrency limits, variable size by n_limits */
94 struct wil_fw_concurrency_limit limits[0];
95} __packed;
96
97struct wil_fw_record_concurrency { /* type == wil_fw_type_comment */
98 /* identifies concurrency record */
99 __le32 magic;
100 /* structure version, currently always 1 */
101 u8 version;
102 /* maximum number of supported MIDs _in addition_ to MID 0 */
103 u8 n_mids;
104 /* number of concurrency combinations that follow */
105 __le16 n_combos;
106 /* keep last - combinations, variable size by n_combos */
107 struct wil_fw_concurrency_combo combos[0];
108} __packed;
75 109
76/* brd file info encoded inside a comment record */ 110/* brd file info encoded inside a comment record */
77#define WIL_BRD_FILE_MAGIC (0xabcddcbb) 111#define WIL_BRD_FILE_MAGIC (0xabcddcbb)
@@ -175,3 +209,5 @@ struct wil_fw_record_gateway_data4 { /* type == wil_fw_type_gateway_data4 */
175 __le32 command; 209 __le32 command;
176 struct wil_fw_data_gw4 data[0]; /* total size [data_size], see above */ 210 struct wil_fw_data_gw4 data[0]; /* total size [data_size], see above */
177} __packed; 211} __packed;
212
213#endif /* __WIL_FW_H__ */
diff --git a/drivers/net/wireless/ath/wil6210/fw_inc.c b/drivers/net/wireless/ath/wil6210/fw_inc.c
index 914c0106e94b..718161b829c2 100644
--- a/drivers/net/wireless/ath/wil6210/fw_inc.c
+++ b/drivers/net/wireless/ath/wil6210/fw_inc.c
@@ -136,8 +136,8 @@ fw_handle_capabilities(struct wil6210_priv *wil, const void *data,
136 size_t capa_size; 136 size_t capa_size;
137 137
138 if (size < sizeof(*rec)) { 138 if (size < sizeof(*rec)) {
139 wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, 139 wil_err_fw(wil, "capabilities record too short: %zu\n", size);
140 data, size, true); 140 /* let the FW load anyway */
141 return 0; 141 return 0;
142 } 142 }
143 143
@@ -158,8 +158,7 @@ fw_handle_brd_file(struct wil6210_priv *wil, const void *data,
158 const struct wil_fw_record_brd_file *rec = data; 158 const struct wil_fw_record_brd_file *rec = data;
159 159
160 if (size < sizeof(*rec)) { 160 if (size < sizeof(*rec)) {
161 wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, 161 wil_err_fw(wil, "brd_file record too short: %zu\n", size);
162 data, size, true);
163 return 0; 162 return 0;
164 } 163 }
165 164
@@ -173,6 +172,44 @@ fw_handle_brd_file(struct wil6210_priv *wil, const void *data,
173} 172}
174 173
175static int 174static int
175fw_handle_concurrency(struct wil6210_priv *wil, const void *data,
176 size_t size)
177{
178 const struct wil_fw_record_concurrency *rec = data;
179 const struct wil_fw_concurrency_combo *combo;
180 const struct wil_fw_concurrency_limit *limit;
181 size_t remain, lsize;
182 int i, n_combos;
183
184 if (size < sizeof(*rec)) {
185 wil_err_fw(wil, "concurrency record too short: %zu\n", size);
186 /* continue, let the FW load anyway */
187 return 0;
188 }
189
190 n_combos = le16_to_cpu(rec->n_combos);
191 remain = size - offsetof(struct wil_fw_record_concurrency, combos);
192 combo = rec->combos;
193 for (i = 0; i < n_combos; i++) {
194 if (remain < sizeof(*combo))
195 goto out_short;
196 remain -= sizeof(*combo);
197 limit = combo->limits;
198 lsize = combo->n_limits * sizeof(*limit);
199 if (remain < lsize)
200 goto out_short;
201 remain -= lsize;
202 limit += combo->n_limits;
203 combo = (struct wil_fw_concurrency_combo *)limit;
204 }
205
206 return wil_cfg80211_iface_combinations_from_fw(wil, rec);
207out_short:
208 wil_err_fw(wil, "concurrency record truncated\n");
209 return 0;
210}
211
212static int
176fw_handle_comment(struct wil6210_priv *wil, const void *data, 213fw_handle_comment(struct wil6210_priv *wil, const void *data,
177 size_t size) 214 size_t size)
178{ 215{
@@ -194,6 +231,13 @@ fw_handle_comment(struct wil6210_priv *wil, const void *data,
194 wil_dbg_fw(wil, "magic is WIL_BRD_FILE_MAGIC\n"); 231 wil_dbg_fw(wil, "magic is WIL_BRD_FILE_MAGIC\n");
195 rc = fw_handle_brd_file(wil, data, size); 232 rc = fw_handle_brd_file(wil, data, size);
196 break; 233 break;
234 case WIL_FW_CONCURRENCY_MAGIC:
235 wil_dbg_fw(wil, "magic is WIL_FW_CONCURRENCY_MAGIC\n");
236 rc = fw_handle_concurrency(wil, data, size);
237 break;
238 default:
239 wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1,
240 data, size, true);
197 } 241 }
198 242
199 return rc; 243 return rc;
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index 1835187ea075..84e9840c1752 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -127,7 +127,7 @@ void wil6210_unmask_irq_tx(struct wil6210_priv *wil)
127 127
128void wil6210_unmask_irq_rx(struct wil6210_priv *wil) 128void wil6210_unmask_irq_rx(struct wil6210_priv *wil)
129{ 129{
130 bool unmask_rx_htrsh = test_bit(wil_status_fwconnected, wil->status); 130 bool unmask_rx_htrsh = atomic_read(&wil->connected_vifs) > 0;
131 131
132 wil_w(wil, RGF_DMA_EP_RX_ICR + offsetof(struct RGF_ICR, IMC), 132 wil_w(wil, RGF_DMA_EP_RX_ICR + offsetof(struct RGF_ICR, IMC),
133 unmask_rx_htrsh ? WIL6210_IMC_RX : WIL6210_IMC_RX_NO_RX_HTRSH); 133 unmask_rx_htrsh ? WIL6210_IMC_RX : WIL6210_IMC_RX_NO_RX_HTRSH);
@@ -188,12 +188,14 @@ void wil_unmask_irq(struct wil6210_priv *wil)
188 188
189void wil_configure_interrupt_moderation(struct wil6210_priv *wil) 189void wil_configure_interrupt_moderation(struct wil6210_priv *wil)
190{ 190{
191 struct wireless_dev *wdev = wil->main_ndev->ieee80211_ptr;
192
191 wil_dbg_irq(wil, "configure_interrupt_moderation\n"); 193 wil_dbg_irq(wil, "configure_interrupt_moderation\n");
192 194
193 /* disable interrupt moderation for monitor 195 /* disable interrupt moderation for monitor
194 * to get better timestamp precision 196 * to get better timestamp precision
195 */ 197 */
196 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) 198 if (wdev->iftype == NL80211_IFTYPE_MONITOR)
197 return; 199 return;
198 200
199 /* Disable and clear tx counter before (re)configuration */ 201 /* Disable and clear tx counter before (re)configuration */
@@ -340,7 +342,7 @@ static irqreturn_t wil6210_irq_tx(int irq, void *cookie)
340 342
341static void wil_notify_fw_error(struct wil6210_priv *wil) 343static void wil_notify_fw_error(struct wil6210_priv *wil)
342{ 344{
343 struct device *dev = &wil_to_ndev(wil)->dev; 345 struct device *dev = &wil->main_ndev->dev;
344 char *envp[3] = { 346 char *envp[3] = {
345 [0] = "SOURCE=wil6210", 347 [0] = "SOURCE=wil6210",
346 [1] = "EVENT=FW_ERROR", 348 [1] = "EVENT=FW_ERROR",
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index 0c61a6c13991..a4b413e8d55a 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -160,24 +160,34 @@ void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
160 } 160 }
161} 161}
162 162
163static void wil_disconnect_cid(struct wil6210_priv *wil, int cid, 163static void wil_disconnect_cid(struct wil6210_vif *vif, int cid,
164 u16 reason_code, bool from_event) 164 u16 reason_code, bool from_event)
165__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) 165__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
166{ 166{
167 uint i; 167 uint i;
168 struct net_device *ndev = wil_to_ndev(wil); 168 struct wil6210_priv *wil = vif_to_wil(vif);
169 struct wireless_dev *wdev = wil->wdev; 169 struct net_device *ndev = vif_to_ndev(vif);
170 struct wireless_dev *wdev = vif_to_wdev(vif);
170 struct wil_sta_info *sta = &wil->sta[cid]; 171 struct wil_sta_info *sta = &wil->sta[cid];
171 172
172 might_sleep(); 173 might_sleep();
173 wil_dbg_misc(wil, "disconnect_cid: CID %d, status %d\n", 174 wil_dbg_misc(wil, "disconnect_cid: CID %d, MID %d, status %d\n",
174 cid, sta->status); 175 cid, sta->mid, sta->status);
175 /* inform upper/lower layers */ 176 /* inform upper/lower layers */
176 if (sta->status != wil_sta_unused) { 177 if (sta->status != wil_sta_unused) {
178 if (vif->mid != sta->mid) {
179 wil_err(wil, "STA MID mismatch with VIF MID(%d)\n",
180 vif->mid);
181 /* let FW override sta->mid but be more strict with
182 * user space requests
183 */
184 if (!from_event)
185 return;
186 }
177 if (!from_event) { 187 if (!from_event) {
178 bool del_sta = (wdev->iftype == NL80211_IFTYPE_AP) ? 188 bool del_sta = (wdev->iftype == NL80211_IFTYPE_AP) ?
179 disable_ap_sme : false; 189 disable_ap_sme : false;
180 wmi_disconnect_sta(wil, sta->addr, reason_code, 190 wmi_disconnect_sta(vif, sta->addr, reason_code,
181 true, del_sta); 191 true, del_sta);
182 } 192 }
183 193
@@ -191,6 +201,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
191 break; 201 break;
192 } 202 }
193 sta->status = wil_sta_unused; 203 sta->status = wil_sta_unused;
204 sta->mid = U8_MAX;
194 } 205 }
195 /* reorder buffers */ 206 /* reorder buffers */
196 for (i = 0; i < WIL_STA_TID_NUM; i++) { 207 for (i = 0; i < WIL_STA_TID_NUM; i++) {
@@ -216,28 +227,33 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
216 memset(&sta->stats, 0, sizeof(sta->stats)); 227 memset(&sta->stats, 0, sizeof(sta->stats));
217} 228}
218 229
219static bool wil_is_connected(struct wil6210_priv *wil) 230static bool wil_vif_is_connected(struct wil6210_priv *wil, u8 mid)
220{ 231{
221 int i; 232 int i;
222 233
223 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { 234 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
224 if (wil->sta[i].status == wil_sta_connected) 235 if (wil->sta[i].mid == mid &&
236 wil->sta[i].status == wil_sta_connected)
225 return true; 237 return true;
226 } 238 }
227 239
228 return false; 240 return false;
229} 241}
230 242
231static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, 243static void _wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
232 u16 reason_code, bool from_event) 244 u16 reason_code, bool from_event)
233{ 245{
246 struct wil6210_priv *wil = vif_to_wil(vif);
234 int cid = -ENOENT; 247 int cid = -ENOENT;
235 struct net_device *ndev = wil_to_ndev(wil); 248 struct net_device *ndev;
236 struct wireless_dev *wdev = wil->wdev; 249 struct wireless_dev *wdev;
237 250
238 if (unlikely(!ndev)) 251 if (unlikely(!vif))
239 return; 252 return;
240 253
254 ndev = vif_to_ndev(vif);
255 wdev = vif_to_wdev(vif);
256
241 might_sleep(); 257 might_sleep();
242 wil_info(wil, "bssid=%pM, reason=%d, ev%s\n", bssid, 258 wil_info(wil, "bssid=%pM, reason=%d, ev%s\n", bssid,
243 reason_code, from_event ? "+" : "-"); 259 reason_code, from_event ? "+" : "-");
@@ -254,48 +270,51 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
254 */ 270 */
255 if (bssid && !is_broadcast_ether_addr(bssid) && 271 if (bssid && !is_broadcast_ether_addr(bssid) &&
256 !ether_addr_equal_unaligned(ndev->dev_addr, bssid)) { 272 !ether_addr_equal_unaligned(ndev->dev_addr, bssid)) {
257 cid = wil_find_cid(wil, bssid); 273 cid = wil_find_cid(wil, vif->mid, bssid);
258 wil_dbg_misc(wil, "Disconnect %pM, CID=%d, reason=%d\n", 274 wil_dbg_misc(wil, "Disconnect %pM, CID=%d, reason=%d\n",
259 bssid, cid, reason_code); 275 bssid, cid, reason_code);
260 if (cid >= 0) /* disconnect 1 peer */ 276 if (cid >= 0) /* disconnect 1 peer */
261 wil_disconnect_cid(wil, cid, reason_code, from_event); 277 wil_disconnect_cid(vif, cid, reason_code, from_event);
262 } else { /* all */ 278 } else { /* all */
263 wil_dbg_misc(wil, "Disconnect all\n"); 279 wil_dbg_misc(wil, "Disconnect all\n");
264 for (cid = 0; cid < WIL6210_MAX_CID; cid++) 280 for (cid = 0; cid < WIL6210_MAX_CID; cid++)
265 wil_disconnect_cid(wil, cid, reason_code, from_event); 281 wil_disconnect_cid(vif, cid, reason_code, from_event);
266 } 282 }
267 283
268 /* link state */ 284 /* link state */
269 switch (wdev->iftype) { 285 switch (wdev->iftype) {
270 case NL80211_IFTYPE_STATION: 286 case NL80211_IFTYPE_STATION:
271 case NL80211_IFTYPE_P2P_CLIENT: 287 case NL80211_IFTYPE_P2P_CLIENT:
272 wil_bcast_fini(wil); 288 wil_bcast_fini(vif);
273 wil_update_net_queues_bh(wil, NULL, true); 289 wil_update_net_queues_bh(wil, vif, NULL, true);
274 netif_carrier_off(ndev); 290 netif_carrier_off(ndev);
275 wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS); 291 if (!wil_has_other_active_ifaces(wil, ndev, false, true))
292 wil6210_bus_request(wil, WIL_DEFAULT_BUS_REQUEST_KBPS);
276 293
277 if (test_bit(wil_status_fwconnected, wil->status)) { 294 if (test_and_clear_bit(wil_vif_fwconnected, vif->status)) {
278 clear_bit(wil_status_fwconnected, wil->status); 295 atomic_dec(&wil->connected_vifs);
279 cfg80211_disconnected(ndev, reason_code, 296 cfg80211_disconnected(ndev, reason_code,
280 NULL, 0, 297 NULL, 0,
281 wil->locally_generated_disc, 298 vif->locally_generated_disc,
282 GFP_KERNEL); 299 GFP_KERNEL);
283 wil->locally_generated_disc = false; 300 vif->locally_generated_disc = false;
284 } else if (test_bit(wil_status_fwconnecting, wil->status)) { 301 } else if (test_bit(wil_vif_fwconnecting, vif->status)) {
285 cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0, 302 cfg80211_connect_result(ndev, bssid, NULL, 0, NULL, 0,
286 WLAN_STATUS_UNSPECIFIED_FAILURE, 303 WLAN_STATUS_UNSPECIFIED_FAILURE,
287 GFP_KERNEL); 304 GFP_KERNEL);
288 wil->bss = NULL; 305 vif->bss = NULL;
289 } 306 }
290 clear_bit(wil_status_fwconnecting, wil->status); 307 clear_bit(wil_vif_fwconnecting, vif->status);
291 break; 308 break;
292 case NL80211_IFTYPE_AP: 309 case NL80211_IFTYPE_AP:
293 case NL80211_IFTYPE_P2P_GO: 310 case NL80211_IFTYPE_P2P_GO:
294 if (!wil_is_connected(wil)) { 311 if (!wil_vif_is_connected(wil, vif->mid)) {
295 wil_update_net_queues_bh(wil, NULL, true); 312 wil_update_net_queues_bh(wil, vif, NULL, true);
296 clear_bit(wil_status_fwconnected, wil->status); 313 if (test_and_clear_bit(wil_vif_fwconnected,
314 vif->status))
315 atomic_dec(&wil->connected_vifs);
297 } else { 316 } else {
298 wil_update_net_queues_bh(wil, NULL, false); 317 wil_update_net_queues_bh(wil, vif, NULL, false);
299 } 318 }
300 break; 319 break;
301 default: 320 default:
@@ -303,26 +322,27 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
303 } 322 }
304} 323}
305 324
306static void wil_disconnect_worker(struct work_struct *work) 325void wil_disconnect_worker(struct work_struct *work)
307{ 326{
308 struct wil6210_priv *wil = container_of(work, 327 struct wil6210_vif *vif = container_of(work,
309 struct wil6210_priv, disconnect_worker); 328 struct wil6210_vif, disconnect_worker);
310 struct net_device *ndev = wil_to_ndev(wil); 329 struct wil6210_priv *wil = vif_to_wil(vif);
330 struct net_device *ndev = vif_to_ndev(vif);
311 int rc; 331 int rc;
312 struct { 332 struct {
313 struct wmi_cmd_hdr wmi; 333 struct wmi_cmd_hdr wmi;
314 struct wmi_disconnect_event evt; 334 struct wmi_disconnect_event evt;
315 } __packed reply; 335 } __packed reply;
316 336
317 if (test_bit(wil_status_fwconnected, wil->status)) 337 if (test_bit(wil_vif_fwconnected, vif->status))
318 /* connect succeeded after all */ 338 /* connect succeeded after all */
319 return; 339 return;
320 340
321 if (!test_bit(wil_status_fwconnecting, wil->status)) 341 if (!test_bit(wil_vif_fwconnecting, vif->status))
322 /* already disconnected */ 342 /* already disconnected */
323 return; 343 return;
324 344
325 rc = wmi_call(wil, WMI_DISCONNECT_CMDID, NULL, 0, 345 rc = wmi_call(wil, WMI_DISCONNECT_CMDID, vif->mid, NULL, 0,
326 WMI_DISCONNECT_EVENTID, &reply, sizeof(reply), 346 WMI_DISCONNECT_EVENTID, &reply, sizeof(reply),
327 WIL6210_DISCONNECT_TO_MS); 347 WIL6210_DISCONNECT_TO_MS);
328 if (rc) { 348 if (rc) {
@@ -330,35 +350,11 @@ static void wil_disconnect_worker(struct work_struct *work)
330 return; 350 return;
331 } 351 }
332 352
333 wil_update_net_queues_bh(wil, NULL, true); 353 wil_update_net_queues_bh(wil, vif, NULL, true);
334 netif_carrier_off(ndev); 354 netif_carrier_off(ndev);
335 cfg80211_connect_result(ndev, NULL, NULL, 0, NULL, 0, 355 cfg80211_connect_result(ndev, NULL, NULL, 0, NULL, 0,
336 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL); 356 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL);
337 clear_bit(wil_status_fwconnecting, wil->status); 357 clear_bit(wil_vif_fwconnecting, vif->status);
338}
339
340static void wil_connect_timer_fn(struct timer_list *t)
341{
342 struct wil6210_priv *wil = from_timer(wil, t, connect_timer);
343 bool q;
344
345 wil_err(wil, "Connect timeout detected, disconnect station\n");
346
347 /* reschedule to thread context - disconnect won't
348 * run from atomic context.
349 * queue on wmi_wq to prevent race with connect event.
350 */
351 q = queue_work(wil->wmi_wq, &wil->disconnect_worker);
352 wil_dbg_wmi(wil, "queue_work of disconnect_worker -> %d\n", q);
353}
354
355static void wil_scan_timer_fn(struct timer_list *t)
356{
357 struct wil6210_priv *wil = from_timer(wil, t, scan_timer);
358
359 clear_bit(wil_status_fwready, wil->status);
360 wil_err(wil, "Scan timeout detected, start fw error recovery\n");
361 wil_fw_error_recovery(wil);
362} 358}
363 359
364static int wil_wait_for_recovery(struct wil6210_priv *wil) 360static int wil_wait_for_recovery(struct wil6210_priv *wil)
@@ -394,12 +390,12 @@ static void wil_fw_error_worker(struct work_struct *work)
394{ 390{
395 struct wil6210_priv *wil = container_of(work, struct wil6210_priv, 391 struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
396 fw_error_worker); 392 fw_error_worker);
397 struct wireless_dev *wdev = wil->wdev; 393 struct net_device *ndev = wil->main_ndev;
398 struct net_device *ndev = wil_to_ndev(wil); 394 struct wireless_dev *wdev = ndev->ieee80211_ptr;
399 395
400 wil_dbg_misc(wil, "fw error worker\n"); 396 wil_dbg_misc(wil, "fw error worker\n");
401 397
402 if (!(ndev->flags & IFF_UP)) { 398 if (!ndev || !(ndev->flags & IFF_UP)) {
403 wil_info(wil, "No recovery - interface is down\n"); 399 wil_info(wil, "No recovery - interface is down\n");
404 return; 400 return;
405 } 401 }
@@ -429,6 +425,10 @@ static void wil_fw_error_worker(struct work_struct *work)
429 return; 425 return;
430 426
431 mutex_lock(&wil->mutex); 427 mutex_lock(&wil->mutex);
428 /* Needs adaptation for multiple VIFs
429 * need to go over all VIFs and consider the appropriate
430 * recovery.
431 */
432 switch (wdev->iftype) { 432 switch (wdev->iftype) {
433 case NL80211_IFTYPE_STATION: 433 case NL80211_IFTYPE_STATION:
434 case NL80211_IFTYPE_P2P_CLIENT: 434 case NL80211_IFTYPE_P2P_CLIENT:
@@ -461,8 +461,9 @@ static int wil_find_free_vring(struct wil6210_priv *wil)
461 return -EINVAL; 461 return -EINVAL;
462} 462}
463 463
464int wil_tx_init(struct wil6210_priv *wil, int cid) 464int wil_tx_init(struct wil6210_vif *vif, int cid)
465{ 465{
466 struct wil6210_priv *wil = vif_to_wil(vif);
466 int rc = -EINVAL, ringid; 467 int rc = -EINVAL, ringid;
467 468
468 if (cid < 0) { 469 if (cid < 0) {
@@ -475,21 +476,22 @@ int wil_tx_init(struct wil6210_priv *wil, int cid)
475 goto out; 476 goto out;
476 } 477 }
477 478
478 wil_dbg_wmi(wil, "Configure for connection CID %d vring %d\n", 479 wil_dbg_wmi(wil, "Configure for connection CID %d MID %d vring %d\n",
479 cid, ringid); 480 cid, vif->mid, ringid);
480 481
481 rc = wil_vring_init_tx(wil, ringid, 1 << tx_ring_order, cid, 0); 482 rc = wil_vring_init_tx(vif, ringid, 1 << tx_ring_order, cid, 0);
482 if (rc) 483 if (rc)
483 wil_err(wil, "wil_vring_init_tx for CID %d vring %d failed\n", 484 wil_err(wil, "init TX for CID %d MID %d vring %d failed\n",
484 cid, ringid); 485 cid, vif->mid, ringid);
485 486
486out: 487out:
487 return rc; 488 return rc;
488} 489}
489 490
490int wil_bcast_init(struct wil6210_priv *wil) 491int wil_bcast_init(struct wil6210_vif *vif)
491{ 492{
492 int ri = wil->bcast_vring, rc; 493 struct wil6210_priv *wil = vif_to_wil(vif);
494 int ri = vif->bcast_vring, rc;
493 495
494 if ((ri >= 0) && wil->vring_tx[ri].va) 496 if ((ri >= 0) && wil->vring_tx[ri].va)
495 return 0; 497 return 0;
@@ -498,25 +500,38 @@ int wil_bcast_init(struct wil6210_priv *wil)
498 if (ri < 0) 500 if (ri < 0)
499 return ri; 501 return ri;
500 502
501 wil->bcast_vring = ri; 503 vif->bcast_vring = ri;
502 rc = wil_vring_init_bcast(wil, ri, 1 << bcast_ring_order); 504 rc = wil_vring_init_bcast(vif, ri, 1 << bcast_ring_order);
503 if (rc) 505 if (rc)
504 wil->bcast_vring = -1; 506 vif->bcast_vring = -1;
505 507
506 return rc; 508 return rc;
507} 509}
508 510
509void wil_bcast_fini(struct wil6210_priv *wil) 511void wil_bcast_fini(struct wil6210_vif *vif)
510{ 512{
511 int ri = wil->bcast_vring; 513 struct wil6210_priv *wil = vif_to_wil(vif);
514 int ri = vif->bcast_vring;
512 515
513 if (ri < 0) 516 if (ri < 0)
514 return; 517 return;
515 518
516 wil->bcast_vring = -1; 519 vif->bcast_vring = -1;
517 wil_vring_fini_tx(wil, ri); 520 wil_vring_fini_tx(wil, ri);
518} 521}
519 522
523void wil_bcast_fini_all(struct wil6210_priv *wil)
524{
525 int i;
526 struct wil6210_vif *vif;
527
528 for (i = 0; i < wil->max_vifs; i++) {
529 vif = wil->vifs[i];
530 if (vif)
531 wil_bcast_fini(vif);
532 }
533}
534
520int wil_priv_init(struct wil6210_priv *wil) 535int wil_priv_init(struct wil6210_priv *wil)
521{ 536{
522 uint i; 537 uint i;
@@ -524,38 +539,29 @@ int wil_priv_init(struct wil6210_priv *wil)
524 wil_dbg_misc(wil, "priv_init\n"); 539 wil_dbg_misc(wil, "priv_init\n");
525 540
526 memset(wil->sta, 0, sizeof(wil->sta)); 541 memset(wil->sta, 0, sizeof(wil->sta));
527 for (i = 0; i < WIL6210_MAX_CID; i++) 542 for (i = 0; i < WIL6210_MAX_CID; i++) {
528 spin_lock_init(&wil->sta[i].tid_rx_lock); 543 spin_lock_init(&wil->sta[i].tid_rx_lock);
544 wil->sta[i].mid = U8_MAX;
545 }
529 546
530 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) 547 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++)
531 spin_lock_init(&wil->vring_tx_data[i].lock); 548 spin_lock_init(&wil->vring_tx_data[i].lock);
532 549
533 mutex_init(&wil->mutex); 550 mutex_init(&wil->mutex);
551 mutex_init(&wil->vif_mutex);
534 mutex_init(&wil->wmi_mutex); 552 mutex_init(&wil->wmi_mutex);
535 mutex_init(&wil->probe_client_mutex);
536 mutex_init(&wil->p2p_wdev_mutex);
537 mutex_init(&wil->halp.lock); 553 mutex_init(&wil->halp.lock);
538 554
539 init_completion(&wil->wmi_ready); 555 init_completion(&wil->wmi_ready);
540 init_completion(&wil->wmi_call); 556 init_completion(&wil->wmi_call);
541 init_completion(&wil->halp.comp); 557 init_completion(&wil->halp.comp);
542 558
543 wil->bcast_vring = -1;
544 timer_setup(&wil->connect_timer, wil_connect_timer_fn, 0);
545 timer_setup(&wil->scan_timer, wil_scan_timer_fn, 0);
546 timer_setup(&wil->p2p.discovery_timer, wil_p2p_discovery_timer_fn, 0);
547
548 INIT_WORK(&wil->disconnect_worker, wil_disconnect_worker);
549 INIT_WORK(&wil->wmi_event_worker, wmi_event_worker); 559 INIT_WORK(&wil->wmi_event_worker, wmi_event_worker);
550 INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker); 560 INIT_WORK(&wil->fw_error_worker, wil_fw_error_worker);
551 INIT_WORK(&wil->probe_client_worker, wil_probe_client_worker);
552 INIT_WORK(&wil->p2p.delayed_listen_work, wil_p2p_delayed_listen_work);
553 561
554 INIT_LIST_HEAD(&wil->pending_wmi_ev); 562 INIT_LIST_HEAD(&wil->pending_wmi_ev);
555 INIT_LIST_HEAD(&wil->probe_client_pending);
556 spin_lock_init(&wil->wmi_ev_lock); 563 spin_lock_init(&wil->wmi_ev_lock);
557 spin_lock_init(&wil->net_queue_lock); 564 spin_lock_init(&wil->net_queue_lock);
558 wil->net_queue_stopped = 1;
559 init_waitqueue_head(&wil->wq); 565 init_waitqueue_head(&wil->wq);
560 566
561 wil->wmi_wq = create_singlethread_workqueue(WIL_NAME "_wmi"); 567 wil->wmi_wq = create_singlethread_workqueue(WIL_NAME "_wmi");
@@ -582,6 +588,9 @@ int wil_priv_init(struct wil6210_priv *wil)
582 memset(&wil->suspend_stats, 0, sizeof(wil->suspend_stats)); 588 memset(&wil->suspend_stats, 0, sizeof(wil->suspend_stats));
583 wil->vring_idle_trsh = 16; 589 wil->vring_idle_trsh = 16;
584 590
591 wil->reply_mid = U8_MAX;
592 wil->max_vifs = 1;
593
585 return 0; 594 return 0;
586 595
587out_wmi_wq: 596out_wmi_wq:
@@ -600,7 +609,7 @@ void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps)
600 609
601/** 610/**
602 * wil6210_disconnect - disconnect one connection 611 * wil6210_disconnect - disconnect one connection
603 * @wil: driver context 612 * @vif: virtual interface context
604 * @bssid: peer to disconnect, NULL to disconnect all 613 * @bssid: peer to disconnect, NULL to disconnect all
605 * @reason_code: Reason code for the Disassociation frame 614 * @reason_code: Reason code for the Disassociation frame
606 * @from_event: whether is invoked from FW event handler 615 * @from_event: whether is invoked from FW event handler
@@ -608,13 +617,15 @@ void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps)
608 * Disconnect and release associated resources. If invoked not from the 617 * Disconnect and release associated resources. If invoked not from the
609 * FW event handler, issue WMI command(s) to trigger MAC disconnect. 618 * FW event handler, issue WMI command(s) to trigger MAC disconnect.
610 */ 619 */
611void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, 620void wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
612 u16 reason_code, bool from_event) 621 u16 reason_code, bool from_event)
613{ 622{
623 struct wil6210_priv *wil = vif_to_wil(vif);
624
614 wil_dbg_misc(wil, "disconnect\n"); 625 wil_dbg_misc(wil, "disconnect\n");
615 626
616 del_timer_sync(&wil->connect_timer); 627 del_timer_sync(&vif->connect_timer);
617 _wil6210_disconnect(wil, bssid, reason_code, from_event); 628 _wil6210_disconnect(vif, bssid, reason_code, from_event);
618} 629}
619 630
620void wil_priv_deinit(struct wil6210_priv *wil) 631void wil_priv_deinit(struct wil6210_priv *wil)
@@ -622,18 +633,8 @@ void wil_priv_deinit(struct wil6210_priv *wil)
622 wil_dbg_misc(wil, "priv_deinit\n"); 633 wil_dbg_misc(wil, "priv_deinit\n");
623 634
624 wil_set_recovery_state(wil, fw_recovery_idle); 635 wil_set_recovery_state(wil, fw_recovery_idle);
625 del_timer_sync(&wil->scan_timer);
626 del_timer_sync(&wil->p2p.discovery_timer);
627 cancel_work_sync(&wil->disconnect_worker);
628 cancel_work_sync(&wil->fw_error_worker); 636 cancel_work_sync(&wil->fw_error_worker);
629 cancel_work_sync(&wil->p2p.discovery_expired_work);
630 cancel_work_sync(&wil->p2p.delayed_listen_work);
631 mutex_lock(&wil->mutex);
632 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
633 mutex_unlock(&wil->mutex);
634 wmi_event_flush(wil); 637 wmi_event_flush(wil);
635 wil_probe_client_flush(wil);
636 cancel_work_sync(&wil->probe_client_worker);
637 destroy_workqueue(wil->wq_service); 638 destroy_workqueue(wil->wq_service);
638 destroy_workqueue(wil->wmi_wq); 639 destroy_workqueue(wil->wmi_wq);
639} 640}
@@ -715,7 +716,7 @@ static void wil_bl_prepare_halt(struct wil6210_priv *wil)
715 offsetof(struct bl_dedicated_registers_v0, 716 offsetof(struct bl_dedicated_registers_v0,
716 boot_loader_struct_version)); 717 boot_loader_struct_version));
717 if (!tmp) { 718 if (!tmp) {
718 wil_dbg_misc(wil, "old BL, skipping halt preperation\n"); 719 wil_dbg_misc(wil, "old BL, skipping halt preparation\n");
719 return; 720 return;
720 } 721 }
721 722
@@ -943,7 +944,7 @@ void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r)
943 944
944static int wil_get_bl_info(struct wil6210_priv *wil) 945static int wil_get_bl_info(struct wil6210_priv *wil)
945{ 946{
946 struct net_device *ndev = wil_to_ndev(wil); 947 struct net_device *ndev = wil->main_ndev;
947 struct wiphy *wiphy = wil_to_wiphy(wil); 948 struct wiphy *wiphy = wil_to_wiphy(wil);
948 union { 949 union {
949 struct bl_dedicated_registers_v0 bl0; 950 struct bl_dedicated_registers_v0 bl0;
@@ -1035,7 +1036,7 @@ static void wil_bl_crash_info(struct wil6210_priv *wil, bool is_err)
1035 1036
1036static int wil_get_otp_info(struct wil6210_priv *wil) 1037static int wil_get_otp_info(struct wil6210_priv *wil)
1037{ 1038{
1038 struct net_device *ndev = wil_to_ndev(wil); 1039 struct net_device *ndev = wil->main_ndev;
1039 struct wiphy *wiphy = wil_to_wiphy(wil); 1040 struct wiphy *wiphy = wil_to_wiphy(wil);
1040 u8 mac[8]; 1041 u8 mac[8];
1041 1042
@@ -1069,31 +1070,46 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil)
1069 return 0; 1070 return 0;
1070} 1071}
1071 1072
1072void wil_abort_scan(struct wil6210_priv *wil, bool sync) 1073void wil_abort_scan(struct wil6210_vif *vif, bool sync)
1073{ 1074{
1075 struct wil6210_priv *wil = vif_to_wil(vif);
1074 int rc; 1076 int rc;
1075 struct cfg80211_scan_info info = { 1077 struct cfg80211_scan_info info = {
1076 .aborted = true, 1078 .aborted = true,
1077 }; 1079 };
1078 1080
1079 lockdep_assert_held(&wil->p2p_wdev_mutex); 1081 lockdep_assert_held(&wil->vif_mutex);
1080 1082
1081 if (!wil->scan_request) 1083 if (!vif->scan_request)
1082 return; 1084 return;
1083 1085
1084 wil_dbg_misc(wil, "Abort scan_request 0x%p\n", wil->scan_request); 1086 wil_dbg_misc(wil, "Abort scan_request 0x%p\n", vif->scan_request);
1085 del_timer_sync(&wil->scan_timer); 1087 del_timer_sync(&vif->scan_timer);
1086 mutex_unlock(&wil->p2p_wdev_mutex); 1088 mutex_unlock(&wil->vif_mutex);
1087 rc = wmi_abort_scan(wil); 1089 rc = wmi_abort_scan(vif);
1088 if (!rc && sync) 1090 if (!rc && sync)
1089 wait_event_interruptible_timeout(wil->wq, !wil->scan_request, 1091 wait_event_interruptible_timeout(wil->wq, !vif->scan_request,
1090 msecs_to_jiffies( 1092 msecs_to_jiffies(
1091 WAIT_FOR_SCAN_ABORT_MS)); 1093 WAIT_FOR_SCAN_ABORT_MS));
1092 1094
1093 mutex_lock(&wil->p2p_wdev_mutex); 1095 mutex_lock(&wil->vif_mutex);
1094 if (wil->scan_request) { 1096 if (vif->scan_request) {
1095 cfg80211_scan_done(wil->scan_request, &info); 1097 cfg80211_scan_done(vif->scan_request, &info);
1096 wil->scan_request = NULL; 1098 vif->scan_request = NULL;
1099 }
1100}
1101
1102void wil_abort_scan_all_vifs(struct wil6210_priv *wil, bool sync)
1103{
1104 int i;
1105
1106 lockdep_assert_held(&wil->vif_mutex);
1107
1108 for (i = 0; i < wil->max_vifs; i++) {
1109 struct wil6210_vif *vif = wil->vifs[i];
1110
1111 if (vif)
1112 wil_abort_scan(vif, sync);
1097 } 1113 }
1098} 1114}
1099 1115
@@ -1138,6 +1154,34 @@ static void wil_pre_fw_config(struct wil6210_priv *wil)
1138 } 1154 }
1139} 1155}
1140 1156
1157static int wil_restore_vifs(struct wil6210_priv *wil)
1158{
1159 struct wil6210_vif *vif;
1160 struct net_device *ndev;
1161 struct wireless_dev *wdev;
1162 int i, rc;
1163
1164 for (i = 0; i < wil->max_vifs; i++) {
1165 vif = wil->vifs[i];
1166 if (!vif)
1167 continue;
1168 vif->ap_isolate = 0;
1169 if (vif->mid) {
1170 ndev = vif_to_ndev(vif);
1171 wdev = vif_to_wdev(vif);
1172 rc = wmi_port_allocate(wil, vif->mid, ndev->dev_addr,
1173 wdev->iftype);
1174 if (rc) {
1175 wil_err(wil, "fail to restore VIF %d type %d, rc %d\n",
1176 i, wdev->iftype, rc);
1177 return rc;
1178 }
1179 }
1180 }
1181
1182 return 0;
1183}
1184
1141/* 1185/*
1142 * We reset all the structures, and we reset the UMAC. 1186 * We reset all the structures, and we reset the UMAC.
1143 * After calling this routine, you're expected to reload 1187 * After calling this routine, you're expected to reload
@@ -1145,9 +1189,10 @@ static void wil_pre_fw_config(struct wil6210_priv *wil)
1145 */ 1189 */
1146int wil_reset(struct wil6210_priv *wil, bool load_fw) 1190int wil_reset(struct wil6210_priv *wil, bool load_fw)
1147{ 1191{
1148 int rc; 1192 int rc, i;
1149 unsigned long status_flags = BIT(wil_status_resetting); 1193 unsigned long status_flags = BIT(wil_status_resetting);
1150 int no_flash; 1194 int no_flash;
1195 struct wil6210_vif *vif;
1151 1196
1152 wil_dbg_misc(wil, "reset\n"); 1197 wil_dbg_misc(wil, "reset\n");
1153 1198
@@ -1158,7 +1203,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
1158 static const u8 mac[ETH_ALEN] = { 1203 static const u8 mac[ETH_ALEN] = {
1159 0x00, 0xde, 0xad, 0x12, 0x34, 0x56, 1204 0x00, 0xde, 0xad, 0x12, 0x34, 0x56,
1160 }; 1205 };
1161 struct net_device *ndev = wil_to_ndev(wil); 1206 struct net_device *ndev = wil->main_ndev;
1162 1207
1163 ether_addr_copy(ndev->perm_addr, mac); 1208 ether_addr_copy(ndev->perm_addr, mac);
1164 ether_addr_copy(ndev->dev_addr, ndev->perm_addr); 1209 ether_addr_copy(ndev->dev_addr, ndev->perm_addr);
@@ -1196,17 +1241,23 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
1196 goto out; 1241 goto out;
1197 } 1242 }
1198 1243
1199 cancel_work_sync(&wil->disconnect_worker); 1244 mutex_lock(&wil->vif_mutex);
1200 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false); 1245 wil_abort_scan_all_vifs(wil, false);
1201 wil_bcast_fini(wil); 1246 mutex_unlock(&wil->vif_mutex);
1247
1248 for (i = 0; i < wil->max_vifs; i++) {
1249 vif = wil->vifs[i];
1250 if (vif) {
1251 cancel_work_sync(&vif->disconnect_worker);
1252 wil6210_disconnect(vif, NULL,
1253 WLAN_REASON_DEAUTH_LEAVING, false);
1254 }
1255 }
1256 wil_bcast_fini_all(wil);
1202 1257
1203 /* Disable device led before reset*/ 1258 /* Disable device led before reset*/
1204 wmi_led_cfg(wil, false); 1259 wmi_led_cfg(wil, false);
1205 1260
1206 mutex_lock(&wil->p2p_wdev_mutex);
1207 wil_abort_scan(wil, false);
1208 mutex_unlock(&wil->p2p_wdev_mutex);
1209
1210 /* prevent NAPI from being scheduled and prevent wmi commands */ 1261 /* prevent NAPI from being scheduled and prevent wmi commands */
1211 mutex_lock(&wil->wmi_mutex); 1262 mutex_lock(&wil->wmi_mutex);
1212 if (test_bit(wil_status_suspending, wil->status)) 1263 if (test_bit(wil_status_suspending, wil->status))
@@ -1276,7 +1327,6 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
1276 } 1327 }
1277 1328
1278 /* init after reset */ 1329 /* init after reset */
1279 wil->ap_isolate = 0;
1280 reinit_completion(&wil->wmi_ready); 1330 reinit_completion(&wil->wmi_ready);
1281 reinit_completion(&wil->wmi_call); 1331 reinit_completion(&wil->wmi_call);
1282 reinit_completion(&wil->halp.comp); 1332 reinit_completion(&wil->halp.comp);
@@ -1299,6 +1349,12 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
1299 return rc; 1349 return rc;
1300 } 1350 }
1301 1351
1352 rc = wil_restore_vifs(wil);
1353 if (rc) {
1354 wil_err(wil, "failed to restore vifs, rc %d\n", rc);
1355 return rc;
1356 }
1357
1302 wil_collect_fw_info(wil); 1358 wil_collect_fw_info(wil);
1303 1359
1304 if (wil->ps_profile != WMI_PS_PROFILE_TYPE_DEFAULT) 1360 if (wil->ps_profile != WMI_PS_PROFILE_TYPE_DEFAULT)
@@ -1337,8 +1393,8 @@ void wil_fw_error_recovery(struct wil6210_priv *wil)
1337 1393
1338int __wil_up(struct wil6210_priv *wil) 1394int __wil_up(struct wil6210_priv *wil)
1339{ 1395{
1340 struct net_device *ndev = wil_to_ndev(wil); 1396 struct net_device *ndev = wil->main_ndev;
1341 struct wireless_dev *wdev = wil->wdev; 1397 struct wireless_dev *wdev = ndev->ieee80211_ptr;
1342 int rc; 1398 int rc;
1343 1399
1344 WARN_ON(!mutex_is_locked(&wil->mutex)); 1400 WARN_ON(!mutex_is_locked(&wil->mutex));
@@ -1420,10 +1476,10 @@ int __wil_down(struct wil6210_priv *wil)
1420 } 1476 }
1421 wil_enable_irq(wil); 1477 wil_enable_irq(wil);
1422 1478
1423 mutex_lock(&wil->p2p_wdev_mutex); 1479 mutex_lock(&wil->vif_mutex);
1424 wil_p2p_stop_radio_operations(wil); 1480 wil_p2p_stop_radio_operations(wil);
1425 wil_abort_scan(wil, false); 1481 wil_abort_scan_all_vifs(wil, false);
1426 mutex_unlock(&wil->p2p_wdev_mutex); 1482 mutex_unlock(&wil->vif_mutex);
1427 1483
1428 return wil_reset(wil, false); 1484 return wil_reset(wil, false);
1429} 1485}
@@ -1442,13 +1498,14 @@ int wil_down(struct wil6210_priv *wil)
1442 return rc; 1498 return rc;
1443} 1499}
1444 1500
1445int wil_find_cid(struct wil6210_priv *wil, const u8 *mac) 1501int wil_find_cid(struct wil6210_priv *wil, u8 mid, const u8 *mac)
1446{ 1502{
1447 int i; 1503 int i;
1448 int rc = -ENOENT; 1504 int rc = -ENOENT;
1449 1505
1450 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { 1506 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
1451 if ((wil->sta[i].status != wil_sta_unused) && 1507 if (wil->sta[i].mid == mid &&
1508 wil->sta[i].status != wil_sta_unused &&
1452 ether_addr_equal(wil->sta[i].addr, mac)) { 1509 ether_addr_equal(wil->sta[i].addr, mac)) {
1453 rc = i; 1510 rc = i;
1454 break; 1511 break;
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 7ba4e0af8f57..05e9408e7ea3 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
3 * 4 *
4 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -15,13 +16,41 @@
15 */ 16 */
16 17
17#include <linux/etherdevice.h> 18#include <linux/etherdevice.h>
19#include <linux/rtnetlink.h>
18#include "wil6210.h" 20#include "wil6210.h"
19#include "txrx.h" 21#include "txrx.h"
20 22
23bool wil_has_other_active_ifaces(struct wil6210_priv *wil,
24 struct net_device *ndev, bool up, bool ok)
25{
26 int i;
27 struct wil6210_vif *vif;
28 struct net_device *ndev_i;
29
30 for (i = 0; i < wil->max_vifs; i++) {
31 vif = wil->vifs[i];
32 if (vif) {
33 ndev_i = vif_to_ndev(vif);
34 if (ndev_i != ndev)
35 if ((up && (ndev_i->flags & IFF_UP)) ||
36 (ok && netif_carrier_ok(ndev_i)))
37 return true;
38 }
39 }
40
41 return false;
42}
43
44bool wil_has_active_ifaces(struct wil6210_priv *wil, bool up, bool ok)
45{
46 /* use NULL ndev argument to check all interfaces */
47 return wil_has_other_active_ifaces(wil, NULL, up, ok);
48}
49
21static int wil_open(struct net_device *ndev) 50static int wil_open(struct net_device *ndev)
22{ 51{
23 struct wil6210_priv *wil = ndev_to_wil(ndev); 52 struct wil6210_priv *wil = ndev_to_wil(ndev);
24 int rc; 53 int rc = 0;
25 54
26 wil_dbg_misc(wil, "open\n"); 55 wil_dbg_misc(wil, "open\n");
27 56
@@ -31,13 +60,16 @@ static int wil_open(struct net_device *ndev)
31 return -EINVAL; 60 return -EINVAL;
32 } 61 }
33 62
34 rc = wil_pm_runtime_get(wil); 63 if (!wil_has_other_active_ifaces(wil, ndev, true, false)) {
35 if (rc < 0) 64 wil_dbg_misc(wil, "open, first iface\n");
36 return rc; 65 rc = wil_pm_runtime_get(wil);
66 if (rc < 0)
67 return rc;
37 68
38 rc = wil_up(wil); 69 rc = wil_up(wil);
39 if (rc) 70 if (rc)
40 wil_pm_runtime_put(wil); 71 wil_pm_runtime_put(wil);
72 }
41 73
42 return rc; 74 return rc;
43} 75}
@@ -45,13 +77,16 @@ static int wil_open(struct net_device *ndev)
45static int wil_stop(struct net_device *ndev) 77static int wil_stop(struct net_device *ndev)
46{ 78{
47 struct wil6210_priv *wil = ndev_to_wil(ndev); 79 struct wil6210_priv *wil = ndev_to_wil(ndev);
48 int rc; 80 int rc = 0;
49 81
50 wil_dbg_misc(wil, "stop\n"); 82 wil_dbg_misc(wil, "stop\n");
51 83
52 rc = wil_down(wil); 84 if (!wil_has_other_active_ifaces(wil, ndev, true, false)) {
53 if (!rc) 85 wil_dbg_misc(wil, "stop, last iface\n");
54 wil_pm_runtime_put(wil); 86 rc = wil_down(wil);
87 if (!rc)
88 wil_pm_runtime_put(wil);
89 }
55 90
56 return rc; 91 return rc;
57} 92}
@@ -96,11 +131,19 @@ static int wil6210_netdev_poll_tx(struct napi_struct *napi, int budget)
96 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { 131 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
97 struct vring *vring = &wil->vring_tx[i]; 132 struct vring *vring = &wil->vring_tx[i];
98 struct vring_tx_data *txdata = &wil->vring_tx_data[i]; 133 struct vring_tx_data *txdata = &wil->vring_tx_data[i];
134 struct wil6210_vif *vif;
99 135
100 if (!vring->va || !txdata->enabled) 136 if (!vring->va || !txdata->enabled ||
137 txdata->mid >= wil->max_vifs)
101 continue; 138 continue;
102 139
103 tx_done += wil_tx_complete(wil, i); 140 vif = wil->vifs[txdata->mid];
141 if (unlikely(!vif)) {
142 wil_dbg_txrx(wil, "Invalid MID %d\n", txdata->mid);
143 continue;
144 }
145
146 tx_done += wil_tx_complete(vif, i);
104 } 147 }
105 148
106 if (tx_done < budget) { 149 if (tx_done < budget) {
@@ -121,44 +164,137 @@ static void wil_dev_setup(struct net_device *dev)
121 dev->tx_queue_len = WIL_TX_Q_LEN_DEFAULT; 164 dev->tx_queue_len = WIL_TX_Q_LEN_DEFAULT;
122} 165}
123 166
124void *wil_if_alloc(struct device *dev) 167static void wil_vif_deinit(struct wil6210_vif *vif)
125{ 168{
126 struct net_device *ndev; 169 del_timer_sync(&vif->scan_timer);
127 struct wireless_dev *wdev; 170 del_timer_sync(&vif->p2p.discovery_timer);
128 struct wil6210_priv *wil; 171 cancel_work_sync(&vif->disconnect_worker);
129 struct ieee80211_channel *ch; 172 cancel_work_sync(&vif->p2p.discovery_expired_work);
130 int rc = 0; 173 cancel_work_sync(&vif->p2p.delayed_listen_work);
174 wil_probe_client_flush(vif);
175 cancel_work_sync(&vif->probe_client_worker);
176}
131 177
132 wdev = wil_cfg80211_init(dev); 178void wil_vif_free(struct wil6210_vif *vif)
133 if (IS_ERR(wdev)) { 179{
134 dev_err(dev, "wil_cfg80211_init failed\n"); 180 struct net_device *ndev = vif_to_ndev(vif);
135 return wdev;
136 }
137 181
138 wil = wdev_to_wil(wdev); 182 wil_vif_deinit(vif);
139 wil->wdev = wdev; 183 free_netdev(ndev);
140 wil->radio_wdev = wdev; 184}
141 185
142 wil_dbg_misc(wil, "if_alloc\n"); 186static void wil_ndev_destructor(struct net_device *ndev)
187{
188 struct wil6210_vif *vif = ndev_to_vif(ndev);
143 189
144 rc = wil_priv_init(wil); 190 wil_vif_deinit(vif);
145 if (rc) { 191}
146 dev_err(dev, "wil_priv_init failed\n"); 192
147 goto out_wdev; 193static void wil_connect_timer_fn(struct timer_list *t)
194{
195 struct wil6210_vif *vif = from_timer(vif, t, connect_timer);
196 struct wil6210_priv *wil = vif_to_wil(vif);
197 bool q;
198
199 wil_err(wil, "Connect timeout detected, disconnect station\n");
200
201 /* reschedule to thread context - disconnect won't
202 * run from atomic context.
203 * queue on wmi_wq to prevent race with connect event.
204 */
205 q = queue_work(wil->wmi_wq, &vif->disconnect_worker);
206 wil_dbg_wmi(wil, "queue_work of disconnect_worker -> %d\n", q);
207}
208
209static void wil_scan_timer_fn(struct timer_list *t)
210{
211 struct wil6210_vif *vif = from_timer(vif, t, scan_timer);
212 struct wil6210_priv *wil = vif_to_wil(vif);
213
214 clear_bit(wil_status_fwready, wil->status);
215 wil_err(wil, "Scan timeout detected, start fw error recovery\n");
216 wil_fw_error_recovery(wil);
217}
218
219static void wil_p2p_discovery_timer_fn(struct timer_list *t)
220{
221 struct wil6210_vif *vif = from_timer(vif, t, p2p.discovery_timer);
222 struct wil6210_priv *wil = vif_to_wil(vif);
223
224 wil_dbg_misc(wil, "p2p_discovery_timer_fn\n");
225
226 schedule_work(&vif->p2p.discovery_expired_work);
227}
228
229static void wil_vif_init(struct wil6210_vif *vif)
230{
231 vif->bcast_vring = -1;
232
233 mutex_init(&vif->probe_client_mutex);
234
235 timer_setup(&vif->connect_timer, wil_connect_timer_fn, 0);
236 timer_setup(&vif->scan_timer, wil_scan_timer_fn, 0);
237 timer_setup(&vif->p2p.discovery_timer, wil_p2p_discovery_timer_fn, 0);
238
239 INIT_WORK(&vif->probe_client_worker, wil_probe_client_worker);
240 INIT_WORK(&vif->disconnect_worker, wil_disconnect_worker);
241 INIT_WORK(&vif->p2p.delayed_listen_work, wil_p2p_delayed_listen_work);
242
243 INIT_LIST_HEAD(&vif->probe_client_pending);
244
245 vif->net_queue_stopped = 1;
246}
247
248static u8 wil_vif_find_free_mid(struct wil6210_priv *wil)
249{
250 u8 i;
251
252 for (i = 0; i < wil->max_vifs; i++) {
253 if (!wil->vifs[i])
254 return i;
148 } 255 }
149 256
150 wdev->iftype = NL80211_IFTYPE_STATION; /* TODO */ 257 return U8_MAX;
151 /* default monitor channel */ 258}
152 ch = wdev->wiphy->bands[NL80211_BAND_60GHZ]->channels; 259
153 cfg80211_chandef_create(&wil->monitor_chandef, ch, NL80211_CHAN_NO_HT); 260struct wil6210_vif *
261wil_vif_alloc(struct wil6210_priv *wil, const char *name,
262 unsigned char name_assign_type, enum nl80211_iftype iftype)
263{
264 struct net_device *ndev;
265 struct wireless_dev *wdev;
266 struct wil6210_vif *vif;
267 u8 mid;
268
269 mid = wil_vif_find_free_mid(wil);
270 if (mid == U8_MAX) {
271 wil_err(wil, "no available virtual interface\n");
272 return ERR_PTR(-EINVAL);
273 }
154 274
155 ndev = alloc_netdev(0, "wlan%d", NET_NAME_UNKNOWN, wil_dev_setup); 275 ndev = alloc_netdev(sizeof(*vif), name, name_assign_type,
276 wil_dev_setup);
156 if (!ndev) { 277 if (!ndev) {
157 dev_err(dev, "alloc_netdev_mqs failed\n"); 278 dev_err(wil_to_dev(wil), "alloc_netdev failed\n");
158 rc = -ENOMEM; 279 return ERR_PTR(-ENOMEM);
159 goto out_priv; 280 }
281 if (mid == 0) {
282 wil->main_ndev = ndev;
283 } else {
284 ndev->priv_destructor = wil_ndev_destructor;
285 ndev->needs_free_netdev = true;
160 } 286 }
161 287
288 vif = ndev_to_vif(ndev);
289 vif->ndev = ndev;
290 vif->wil = wil;
291 vif->mid = mid;
292 wil_vif_init(vif);
293
294 wdev = &vif->wdev;
295 wdev->wiphy = wil->wiphy;
296 wdev->iftype = iftype;
297
162 ndev->netdev_ops = &wil_netdev_ops; 298 ndev->netdev_ops = &wil_netdev_ops;
163 wil_set_ethtoolops(ndev); 299 wil_set_ethtoolops(ndev);
164 ndev->ieee80211_ptr = wdev; 300 ndev->ieee80211_ptr = wdev;
@@ -170,21 +306,53 @@ void *wil_if_alloc(struct device *dev)
170 ndev->features |= ndev->hw_features; 306 ndev->features |= ndev->hw_features;
171 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); 307 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
172 wdev->netdev = ndev; 308 wdev->netdev = ndev;
309 return vif;
310}
311
312void *wil_if_alloc(struct device *dev)
313{
314 struct wil6210_priv *wil;
315 struct wil6210_vif *vif;
316 int rc = 0;
317
318 wil = wil_cfg80211_init(dev);
319 if (IS_ERR(wil)) {
320 dev_err(dev, "wil_cfg80211_init failed\n");
321 return wil;
322 }
323
324 rc = wil_priv_init(wil);
325 if (rc) {
326 dev_err(dev, "wil_priv_init failed\n");
327 goto out_cfg;
328 }
329
330 wil_dbg_misc(wil, "if_alloc\n");
331
332 vif = wil_vif_alloc(wil, "wlan%d", NET_NAME_UNKNOWN,
333 NL80211_IFTYPE_STATION);
334 if (IS_ERR(vif)) {
335 dev_err(dev, "wil_vif_alloc failed\n");
336 rc = -ENOMEM;
337 goto out_priv;
338 }
339
340 wil->radio_wdev = vif_to_wdev(vif);
173 341
174 return wil; 342 return wil;
175 343
176 out_priv: 344out_priv:
177 wil_priv_deinit(wil); 345 wil_priv_deinit(wil);
178 346
179 out_wdev: 347out_cfg:
180 wil_wdev_free(wil); 348 wil_cfg80211_deinit(wil);
181 349
182 return ERR_PTR(rc); 350 return ERR_PTR(rc);
183} 351}
184 352
185void wil_if_free(struct wil6210_priv *wil) 353void wil_if_free(struct wil6210_priv *wil)
186{ 354{
187 struct net_device *ndev = wil_to_ndev(wil); 355 struct net_device *ndev = wil->main_ndev;
188 356
189 wil_dbg_misc(wil, "if_free\n"); 357 wil_dbg_misc(wil, "if_free\n");
190 358
@@ -193,17 +361,50 @@ void wil_if_free(struct wil6210_priv *wil)
193 361
194 wil_priv_deinit(wil); 362 wil_priv_deinit(wil);
195 363
196 wil_to_ndev(wil) = NULL; 364 wil->main_ndev = NULL;
365 wil_ndev_destructor(ndev);
197 free_netdev(ndev); 366 free_netdev(ndev);
198 367
199 wil_wdev_free(wil); 368 wil_cfg80211_deinit(wil);
369}
370
371int wil_vif_add(struct wil6210_priv *wil, struct wil6210_vif *vif)
372{
373 struct net_device *ndev = vif_to_ndev(vif);
374 struct wireless_dev *wdev = vif_to_wdev(vif);
375 bool any_active = wil_has_active_ifaces(wil, true, false);
376 int rc;
377
378 ASSERT_RTNL();
379
380 if (wil->vifs[vif->mid]) {
381 dev_err(&ndev->dev, "VIF with mid %d already in use\n",
382 vif->mid);
383 return -EEXIST;
384 }
385 if (any_active && vif->mid != 0) {
386 rc = wmi_port_allocate(wil, vif->mid, ndev->dev_addr,
387 wdev->iftype);
388 if (rc)
389 return rc;
390 }
391 rc = register_netdevice(ndev);
392 if (rc < 0) {
393 dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc);
394 if (any_active && vif->mid != 0)
395 wmi_port_delete(wil, vif->mid);
396 return rc;
397 }
398
399 wil->vifs[vif->mid] = vif;
400 return 0;
200} 401}
201 402
202int wil_if_add(struct wil6210_priv *wil) 403int wil_if_add(struct wil6210_priv *wil)
203{ 404{
204 struct wireless_dev *wdev = wil_to_wdev(wil); 405 struct wiphy *wiphy = wil->wiphy;
205 struct wiphy *wiphy = wdev->wiphy; 406 struct net_device *ndev = wil->main_ndev;
206 struct net_device *ndev = wil_to_ndev(wil); 407 struct wil6210_vif *vif = ndev_to_vif(ndev);
207 int rc; 408 int rc;
208 409
209 wil_dbg_misc(wil, "entered"); 410 wil_dbg_misc(wil, "entered");
@@ -216,33 +417,94 @@ int wil_if_add(struct wil6210_priv *wil)
216 return rc; 417 return rc;
217 } 418 }
218 419
219 netif_napi_add(ndev, &wil->napi_rx, wil6210_netdev_poll_rx, 420 init_dummy_netdev(&wil->napi_ndev);
421 netif_napi_add(&wil->napi_ndev, &wil->napi_rx, wil6210_netdev_poll_rx,
220 WIL6210_NAPI_BUDGET); 422 WIL6210_NAPI_BUDGET);
221 netif_tx_napi_add(ndev, &wil->napi_tx, wil6210_netdev_poll_tx, 423 netif_tx_napi_add(&wil->napi_ndev,
424 &wil->napi_tx, wil6210_netdev_poll_tx,
222 WIL6210_NAPI_BUDGET); 425 WIL6210_NAPI_BUDGET);
223 426
224 wil_update_net_queues_bh(wil, NULL, true); 427 wil_update_net_queues_bh(wil, vif, NULL, true);
225 428
226 rc = register_netdev(ndev); 429 rtnl_lock();
227 if (rc < 0) { 430 rc = wil_vif_add(wil, vif);
228 dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc); 431 rtnl_unlock();
432 if (rc < 0)
229 goto out_wiphy; 433 goto out_wiphy;
230 }
231 434
232 return 0; 435 return 0;
233 436
234out_wiphy: 437out_wiphy:
235 wiphy_unregister(wdev->wiphy); 438 wiphy_unregister(wiphy);
236 return rc; 439 return rc;
237} 440}
238 441
442void wil_vif_remove(struct wil6210_priv *wil, u8 mid)
443{
444 struct wil6210_vif *vif;
445 struct net_device *ndev;
446 bool any_active = wil_has_active_ifaces(wil, true, false);
447
448 ASSERT_RTNL();
449 if (mid >= wil->max_vifs) {
450 wil_err(wil, "invalid MID: %d\n", mid);
451 return;
452 }
453
454 vif = wil->vifs[mid];
455 if (!vif) {
456 wil_err(wil, "MID %d not registered\n", mid);
457 return;
458 }
459
460 ndev = vif_to_ndev(vif);
461 /* during unregister_netdevice cfg80211_leave may perform operations
462 * such as stop AP, disconnect, so we only clear the VIF afterwards
463 */
464 unregister_netdevice(ndev);
465
466 mutex_lock(&wil->mutex);
467 wil6210_disconnect(vif, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
468 mutex_unlock(&wil->mutex);
469
470 if (any_active && vif->mid != 0)
471 wmi_port_delete(wil, vif->mid);
472
473 /* make sure no one is accessing the VIF before removing */
474 mutex_lock(&wil->vif_mutex);
475 wil->vifs[mid] = NULL;
476 /* ensure NAPI code will see the NULL VIF */
477 wmb();
478 if (test_bit(wil_status_napi_en, wil->status)) {
479 napi_synchronize(&wil->napi_rx);
480 napi_synchronize(&wil->napi_tx);
481 }
482 mutex_unlock(&wil->vif_mutex);
483
484 flush_work(&wil->wmi_event_worker);
485 del_timer_sync(&vif->connect_timer);
486 cancel_work_sync(&vif->disconnect_worker);
487 wil_probe_client_flush(vif);
488 cancel_work_sync(&vif->probe_client_worker);
489 /* for VIFs, ndev will be freed by destructor after RTNL is unlocked.
490 * the main interface will be freed in wil_if_free, we need to keep it
491 * a bit longer so logging macros will work.
492 */
493}
494
239void wil_if_remove(struct wil6210_priv *wil) 495void wil_if_remove(struct wil6210_priv *wil)
240{ 496{
241 struct net_device *ndev = wil_to_ndev(wil); 497 struct net_device *ndev = wil->main_ndev;
242 struct wireless_dev *wdev = wil_to_wdev(wil); 498 struct wireless_dev *wdev = ndev->ieee80211_ptr;
243 499
244 wil_dbg_misc(wil, "if_remove\n"); 500 wil_dbg_misc(wil, "if_remove\n");
245 501
246 unregister_netdev(ndev); 502 rtnl_lock();
503 wil_vif_remove(wil, 0);
504 rtnl_unlock();
505
506 netif_napi_del(&wil->napi_tx);
507 netif_napi_del(&wil->napi_rx);
508
247 wiphy_unregister(wdev->wiphy); 509 wiphy_unregister(wdev->wiphy);
248} 510}
diff --git a/drivers/net/wireless/ath/wil6210/p2p.c b/drivers/net/wireless/ath/wil6210/p2p.c
index 7dbee2c3e482..db087ea58ddf 100644
--- a/drivers/net/wireless/ath/wil6210/p2p.c
+++ b/drivers/net/wireless/ath/wil6210/p2p.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2014-2017 Qualcomm Atheros, Inc. 2 * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
3 * 4 *
4 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -22,27 +23,28 @@
22#define P2P_SEARCH_DURATION_MS 500 23#define P2P_SEARCH_DURATION_MS 500
23#define P2P_DEFAULT_BI 100 24#define P2P_DEFAULT_BI 100
24 25
25static int wil_p2p_start_listen(struct wil6210_priv *wil) 26static int wil_p2p_start_listen(struct wil6210_vif *vif)
26{ 27{
27 struct wil_p2p_info *p2p = &wil->p2p; 28 struct wil6210_priv *wil = vif_to_wil(vif);
29 struct wil_p2p_info *p2p = &vif->p2p;
28 u8 channel = p2p->listen_chan.hw_value; 30 u8 channel = p2p->listen_chan.hw_value;
29 int rc; 31 int rc;
30 32
31 lockdep_assert_held(&wil->mutex); 33 lockdep_assert_held(&wil->mutex);
32 34
33 rc = wmi_p2p_cfg(wil, channel, P2P_DEFAULT_BI); 35 rc = wmi_p2p_cfg(vif, channel, P2P_DEFAULT_BI);
34 if (rc) { 36 if (rc) {
35 wil_err(wil, "wmi_p2p_cfg failed\n"); 37 wil_err(wil, "wmi_p2p_cfg failed\n");
36 goto out; 38 goto out;
37 } 39 }
38 40
39 rc = wmi_set_ssid(wil, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID); 41 rc = wmi_set_ssid(vif, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID);
40 if (rc) { 42 if (rc) {
41 wil_err(wil, "wmi_set_ssid failed\n"); 43 wil_err(wil, "wmi_set_ssid failed\n");
42 goto out_stop; 44 goto out_stop;
43 } 45 }
44 46
45 rc = wmi_start_listen(wil); 47 rc = wmi_start_listen(vif);
46 if (rc) { 48 if (rc) {
47 wil_err(wil, "wmi_start_listen failed\n"); 49 wil_err(wil, "wmi_start_listen failed\n");
48 goto out_stop; 50 goto out_stop;
@@ -53,7 +55,7 @@ static int wil_p2p_start_listen(struct wil6210_priv *wil)
53 jiffies + msecs_to_jiffies(p2p->listen_duration)); 55 jiffies + msecs_to_jiffies(p2p->listen_duration));
54out_stop: 56out_stop:
55 if (rc) 57 if (rc)
56 wmi_stop_discovery(wil); 58 wmi_stop_discovery(vif);
57 59
58out: 60out:
59 return rc; 61 return rc;
@@ -65,20 +67,12 @@ bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request)
65 (request->channels[0]->hw_value == P2P_DMG_SOCIAL_CHANNEL); 67 (request->channels[0]->hw_value == P2P_DMG_SOCIAL_CHANNEL);
66} 68}
67 69
68void wil_p2p_discovery_timer_fn(struct timer_list *t) 70int wil_p2p_search(struct wil6210_vif *vif,
69{
70 struct wil6210_priv *wil = from_timer(wil, t, p2p.discovery_timer);
71
72 wil_dbg_misc(wil, "p2p_discovery_timer_fn\n");
73
74 schedule_work(&wil->p2p.discovery_expired_work);
75}
76
77int wil_p2p_search(struct wil6210_priv *wil,
78 struct cfg80211_scan_request *request) 71 struct cfg80211_scan_request *request)
79{ 72{
73 struct wil6210_priv *wil = vif_to_wil(vif);
80 int rc; 74 int rc;
81 struct wil_p2p_info *p2p = &wil->p2p; 75 struct wil_p2p_info *p2p = &vif->p2p;
82 76
83 wil_dbg_misc(wil, "p2p_search: channel %d\n", P2P_DMG_SOCIAL_CHANNEL); 77 wil_dbg_misc(wil, "p2p_search: channel %d\n", P2P_DMG_SOCIAL_CHANNEL);
84 78
@@ -90,20 +84,20 @@ int wil_p2p_search(struct wil6210_priv *wil,
90 goto out; 84 goto out;
91 } 85 }
92 86
93 rc = wmi_p2p_cfg(wil, P2P_DMG_SOCIAL_CHANNEL, P2P_DEFAULT_BI); 87 rc = wmi_p2p_cfg(vif, P2P_DMG_SOCIAL_CHANNEL, P2P_DEFAULT_BI);
94 if (rc) { 88 if (rc) {
95 wil_err(wil, "wmi_p2p_cfg failed\n"); 89 wil_err(wil, "wmi_p2p_cfg failed\n");
96 goto out; 90 goto out;
97 } 91 }
98 92
99 rc = wmi_set_ssid(wil, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID); 93 rc = wmi_set_ssid(vif, strlen(P2P_WILDCARD_SSID), P2P_WILDCARD_SSID);
100 if (rc) { 94 if (rc) {
101 wil_err(wil, "wmi_set_ssid failed\n"); 95 wil_err(wil, "wmi_set_ssid failed\n");
102 goto out_stop; 96 goto out_stop;
103 } 97 }
104 98
105 /* Set application IE to probe request and probe response */ 99 /* Set application IE to probe request and probe response */
106 rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, 100 rc = wmi_set_ie(vif, WMI_FRAME_PROBE_REQ,
107 request->ie_len, request->ie); 101 request->ie_len, request->ie);
108 if (rc) { 102 if (rc) {
109 wil_err(wil, "wmi_set_ie(WMI_FRAME_PROBE_REQ) failed\n"); 103 wil_err(wil, "wmi_set_ie(WMI_FRAME_PROBE_REQ) failed\n");
@@ -113,14 +107,14 @@ int wil_p2p_search(struct wil6210_priv *wil,
113 /* supplicant doesn't provide Probe Response IEs. As a workaround - 107 /* supplicant doesn't provide Probe Response IEs. As a workaround -
114 * re-use Probe Request IEs 108 * re-use Probe Request IEs
115 */ 109 */
116 rc = wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, 110 rc = wmi_set_ie(vif, WMI_FRAME_PROBE_RESP,
117 request->ie_len, request->ie); 111 request->ie_len, request->ie);
118 if (rc) { 112 if (rc) {
119 wil_err(wil, "wmi_set_ie(WMI_FRAME_PROBE_RESP) failed\n"); 113 wil_err(wil, "wmi_set_ie(WMI_FRAME_PROBE_RESP) failed\n");
120 goto out_stop; 114 goto out_stop;
121 } 115 }
122 116
123 rc = wmi_start_search(wil); 117 rc = wmi_start_search(vif);
124 if (rc) { 118 if (rc) {
125 wil_err(wil, "wmi_start_search failed\n"); 119 wil_err(wil, "wmi_start_search failed\n");
126 goto out_stop; 120 goto out_stop;
@@ -133,7 +127,7 @@ int wil_p2p_search(struct wil6210_priv *wil,
133 127
134out_stop: 128out_stop:
135 if (rc) 129 if (rc)
136 wmi_stop_discovery(wil); 130 wmi_stop_discovery(vif);
137 131
138out: 132out:
139 return rc; 133 return rc;
@@ -143,7 +137,8 @@ int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev,
143 unsigned int duration, struct ieee80211_channel *chan, 137 unsigned int duration, struct ieee80211_channel *chan,
144 u64 *cookie) 138 u64 *cookie)
145{ 139{
146 struct wil_p2p_info *p2p = &wil->p2p; 140 struct wil6210_vif *vif = wdev_to_vif(wil, wdev);
141 struct wil_p2p_info *p2p = &vif->p2p;
147 int rc; 142 int rc;
148 143
149 if (!chan) 144 if (!chan)
@@ -163,23 +158,24 @@ int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev,
163 *cookie = ++p2p->cookie; 158 *cookie = ++p2p->cookie;
164 p2p->listen_duration = duration; 159 p2p->listen_duration = duration;
165 160
166 mutex_lock(&wil->p2p_wdev_mutex); 161 mutex_lock(&wil->vif_mutex);
167 if (wil->scan_request) { 162 if (vif->scan_request) {
168 wil_dbg_misc(wil, "Delaying p2p listen until scan done\n"); 163 wil_dbg_misc(wil, "Delaying p2p listen until scan done\n");
169 p2p->pending_listen_wdev = wdev; 164 p2p->pending_listen_wdev = wdev;
170 p2p->discovery_started = 1; 165 p2p->discovery_started = 1;
171 rc = 0; 166 rc = 0;
172 mutex_unlock(&wil->p2p_wdev_mutex); 167 mutex_unlock(&wil->vif_mutex);
173 goto out; 168 goto out;
174 } 169 }
175 mutex_unlock(&wil->p2p_wdev_mutex); 170 mutex_unlock(&wil->vif_mutex);
176 171
177 rc = wil_p2p_start_listen(wil); 172 rc = wil_p2p_start_listen(vif);
178 if (rc) 173 if (rc)
179 goto out; 174 goto out;
180 175
181 p2p->discovery_started = 1; 176 p2p->discovery_started = 1;
182 wil->radio_wdev = wdev; 177 if (vif->mid == 0)
178 wil->radio_wdev = wdev;
183 179
184 cfg80211_ready_on_channel(wdev, *cookie, chan, duration, 180 cfg80211_ready_on_channel(wdev, *cookie, chan, duration,
185 GFP_KERNEL); 181 GFP_KERNEL);
@@ -189,9 +185,9 @@ out:
189 return rc; 185 return rc;
190} 186}
191 187
192u8 wil_p2p_stop_discovery(struct wil6210_priv *wil) 188u8 wil_p2p_stop_discovery(struct wil6210_vif *vif)
193{ 189{
194 struct wil_p2p_info *p2p = &wil->p2p; 190 struct wil_p2p_info *p2p = &vif->p2p;
195 u8 started = p2p->discovery_started; 191 u8 started = p2p->discovery_started;
196 192
197 if (p2p->discovery_started) { 193 if (p2p->discovery_started) {
@@ -200,7 +196,7 @@ u8 wil_p2p_stop_discovery(struct wil6210_priv *wil)
200 p2p->pending_listen_wdev = NULL; 196 p2p->pending_listen_wdev = NULL;
201 } else { 197 } else {
202 del_timer_sync(&p2p->discovery_timer); 198 del_timer_sync(&p2p->discovery_timer);
203 wmi_stop_discovery(wil); 199 wmi_stop_discovery(vif);
204 } 200 }
205 p2p->discovery_started = 0; 201 p2p->discovery_started = 0;
206 } 202 }
@@ -208,9 +204,10 @@ u8 wil_p2p_stop_discovery(struct wil6210_priv *wil)
208 return started; 204 return started;
209} 205}
210 206
211int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie) 207int wil_p2p_cancel_listen(struct wil6210_vif *vif, u64 cookie)
212{ 208{
213 struct wil_p2p_info *p2p = &wil->p2p; 209 struct wil6210_priv *wil = vif_to_wil(vif);
210 struct wil_p2p_info *p2p = &vif->p2p;
214 u8 started; 211 u8 started;
215 212
216 mutex_lock(&wil->mutex); 213 mutex_lock(&wil->mutex);
@@ -222,7 +219,7 @@ int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie)
222 return -ENOENT; 219 return -ENOENT;
223 } 220 }
224 221
225 started = wil_p2p_stop_discovery(wil); 222 started = wil_p2p_stop_discovery(vif);
226 223
227 mutex_unlock(&wil->mutex); 224 mutex_unlock(&wil->mutex);
228 225
@@ -231,13 +228,14 @@ int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie)
231 return -ENOENT; 228 return -ENOENT;
232 } 229 }
233 230
234 mutex_lock(&wil->p2p_wdev_mutex); 231 mutex_lock(&wil->vif_mutex);
235 cfg80211_remain_on_channel_expired(wil->radio_wdev, 232 cfg80211_remain_on_channel_expired(vif_to_radio_wdev(wil, vif),
236 p2p->cookie, 233 p2p->cookie,
237 &p2p->listen_chan, 234 &p2p->listen_chan,
238 GFP_KERNEL); 235 GFP_KERNEL);
239 wil->radio_wdev = wil->wdev; 236 if (vif->mid == 0)
240 mutex_unlock(&wil->p2p_wdev_mutex); 237 wil->radio_wdev = wil->main_ndev->ieee80211_ptr;
238 mutex_unlock(&wil->vif_mutex);
241 return 0; 239 return 0;
242} 240}
243 241
@@ -245,40 +243,43 @@ void wil_p2p_listen_expired(struct work_struct *work)
245{ 243{
246 struct wil_p2p_info *p2p = container_of(work, 244 struct wil_p2p_info *p2p = container_of(work,
247 struct wil_p2p_info, discovery_expired_work); 245 struct wil_p2p_info, discovery_expired_work);
248 struct wil6210_priv *wil = container_of(p2p, 246 struct wil6210_vif *vif = container_of(p2p,
249 struct wil6210_priv, p2p); 247 struct wil6210_vif, p2p);
248 struct wil6210_priv *wil = vif_to_wil(vif);
250 u8 started; 249 u8 started;
251 250
252 wil_dbg_misc(wil, "p2p_listen_expired\n"); 251 wil_dbg_misc(wil, "p2p_listen_expired\n");
253 252
254 mutex_lock(&wil->mutex); 253 mutex_lock(&wil->mutex);
255 started = wil_p2p_stop_discovery(wil); 254 started = wil_p2p_stop_discovery(vif);
256 mutex_unlock(&wil->mutex); 255 mutex_unlock(&wil->mutex);
257 256
258 if (started) { 257 if (!started)
259 mutex_lock(&wil->p2p_wdev_mutex); 258 return;
260 cfg80211_remain_on_channel_expired(wil->radio_wdev,
261 p2p->cookie,
262 &p2p->listen_chan,
263 GFP_KERNEL);
264 wil->radio_wdev = wil->wdev;
265 mutex_unlock(&wil->p2p_wdev_mutex);
266 }
267 259
260 mutex_lock(&wil->vif_mutex);
261 cfg80211_remain_on_channel_expired(vif_to_radio_wdev(wil, vif),
262 p2p->cookie,
263 &p2p->listen_chan,
264 GFP_KERNEL);
265 if (vif->mid == 0)
266 wil->radio_wdev = wil->main_ndev->ieee80211_ptr;
267 mutex_unlock(&wil->vif_mutex);
268} 268}
269 269
270void wil_p2p_search_expired(struct work_struct *work) 270void wil_p2p_search_expired(struct work_struct *work)
271{ 271{
272 struct wil_p2p_info *p2p = container_of(work, 272 struct wil_p2p_info *p2p = container_of(work,
273 struct wil_p2p_info, discovery_expired_work); 273 struct wil_p2p_info, discovery_expired_work);
274 struct wil6210_priv *wil = container_of(p2p, 274 struct wil6210_vif *vif = container_of(p2p,
275 struct wil6210_priv, p2p); 275 struct wil6210_vif, p2p);
276 struct wil6210_priv *wil = vif_to_wil(vif);
276 u8 started; 277 u8 started;
277 278
278 wil_dbg_misc(wil, "p2p_search_expired\n"); 279 wil_dbg_misc(wil, "p2p_search_expired\n");
279 280
280 mutex_lock(&wil->mutex); 281 mutex_lock(&wil->mutex);
281 started = wil_p2p_stop_discovery(wil); 282 started = wil_p2p_stop_discovery(vif);
282 mutex_unlock(&wil->mutex); 283 mutex_unlock(&wil->mutex);
283 284
284 if (started) { 285 if (started) {
@@ -286,13 +287,15 @@ void wil_p2p_search_expired(struct work_struct *work)
286 .aborted = false, 287 .aborted = false,
287 }; 288 };
288 289
289 mutex_lock(&wil->p2p_wdev_mutex); 290 mutex_lock(&wil->vif_mutex);
290 if (wil->scan_request) { 291 if (vif->scan_request) {
291 cfg80211_scan_done(wil->scan_request, &info); 292 cfg80211_scan_done(vif->scan_request, &info);
292 wil->scan_request = NULL; 293 vif->scan_request = NULL;
293 wil->radio_wdev = wil->wdev; 294 if (vif->mid == 0)
295 wil->radio_wdev =
296 wil->main_ndev->ieee80211_ptr;
294 } 297 }
295 mutex_unlock(&wil->p2p_wdev_mutex); 298 mutex_unlock(&wil->vif_mutex);
296 } 299 }
297} 300}
298 301
@@ -300,8 +303,9 @@ void wil_p2p_delayed_listen_work(struct work_struct *work)
300{ 303{
301 struct wil_p2p_info *p2p = container_of(work, 304 struct wil_p2p_info *p2p = container_of(work,
302 struct wil_p2p_info, delayed_listen_work); 305 struct wil_p2p_info, delayed_listen_work);
303 struct wil6210_priv *wil = container_of(p2p, 306 struct wil6210_vif *vif = container_of(p2p,
304 struct wil6210_priv, p2p); 307 struct wil6210_vif, p2p);
308 struct wil6210_priv *wil = vif_to_wil(vif);
305 int rc; 309 int rc;
306 310
307 mutex_lock(&wil->mutex); 311 mutex_lock(&wil->mutex);
@@ -310,31 +314,33 @@ void wil_p2p_delayed_listen_work(struct work_struct *work)
310 if (!p2p->discovery_started || !p2p->pending_listen_wdev) 314 if (!p2p->discovery_started || !p2p->pending_listen_wdev)
311 goto out; 315 goto out;
312 316
313 mutex_lock(&wil->p2p_wdev_mutex); 317 mutex_lock(&wil->vif_mutex);
314 if (wil->scan_request) { 318 if (vif->scan_request) {
315 /* another scan started, wait again... */ 319 /* another scan started, wait again... */
316 mutex_unlock(&wil->p2p_wdev_mutex); 320 mutex_unlock(&wil->vif_mutex);
317 goto out; 321 goto out;
318 } 322 }
319 mutex_unlock(&wil->p2p_wdev_mutex); 323 mutex_unlock(&wil->vif_mutex);
320 324
321 rc = wil_p2p_start_listen(wil); 325 rc = wil_p2p_start_listen(vif);
322 326
323 mutex_lock(&wil->p2p_wdev_mutex); 327 mutex_lock(&wil->vif_mutex);
324 if (rc) { 328 if (rc) {
325 cfg80211_remain_on_channel_expired(p2p->pending_listen_wdev, 329 cfg80211_remain_on_channel_expired(p2p->pending_listen_wdev,
326 p2p->cookie, 330 p2p->cookie,
327 &p2p->listen_chan, 331 &p2p->listen_chan,
328 GFP_KERNEL); 332 GFP_KERNEL);
329 wil->radio_wdev = wil->wdev; 333 if (vif->mid == 0)
334 wil->radio_wdev = wil->main_ndev->ieee80211_ptr;
330 } else { 335 } else {
331 cfg80211_ready_on_channel(p2p->pending_listen_wdev, p2p->cookie, 336 cfg80211_ready_on_channel(p2p->pending_listen_wdev, p2p->cookie,
332 &p2p->listen_chan, 337 &p2p->listen_chan,
333 p2p->listen_duration, GFP_KERNEL); 338 p2p->listen_duration, GFP_KERNEL);
334 wil->radio_wdev = p2p->pending_listen_wdev; 339 if (vif->mid == 0)
340 wil->radio_wdev = p2p->pending_listen_wdev;
335 } 341 }
336 p2p->pending_listen_wdev = NULL; 342 p2p->pending_listen_wdev = NULL;
337 mutex_unlock(&wil->p2p_wdev_mutex); 343 mutex_unlock(&wil->vif_mutex);
338 344
339out: 345out:
340 mutex_unlock(&wil->mutex); 346 mutex_unlock(&wil->mutex);
@@ -342,34 +348,35 @@ out:
342 348
343void wil_p2p_stop_radio_operations(struct wil6210_priv *wil) 349void wil_p2p_stop_radio_operations(struct wil6210_priv *wil)
344{ 350{
345 struct wil_p2p_info *p2p = &wil->p2p; 351 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
352 struct wil_p2p_info *p2p = &vif->p2p;
346 struct cfg80211_scan_info info = { 353 struct cfg80211_scan_info info = {
347 .aborted = true, 354 .aborted = true,
348 }; 355 };
349 356
350 lockdep_assert_held(&wil->mutex); 357 lockdep_assert_held(&wil->mutex);
351 lockdep_assert_held(&wil->p2p_wdev_mutex); 358 lockdep_assert_held(&wil->vif_mutex);
352 359
353 if (wil->radio_wdev != wil->p2p_wdev) 360 if (wil->radio_wdev != wil->p2p_wdev)
354 goto out; 361 goto out;
355 362
356 if (!p2p->discovery_started) { 363 if (!p2p->discovery_started) {
357 /* Regular scan on the p2p device */ 364 /* Regular scan on the p2p device */
358 if (wil->scan_request && 365 if (vif->scan_request &&
359 wil->scan_request->wdev == wil->p2p_wdev) 366 vif->scan_request->wdev == wil->p2p_wdev)
360 wil_abort_scan(wil, true); 367 wil_abort_scan(vif, true);
361 goto out; 368 goto out;
362 } 369 }
363 370
364 /* Search or listen on p2p device */ 371 /* Search or listen on p2p device */
365 mutex_unlock(&wil->p2p_wdev_mutex); 372 mutex_unlock(&wil->vif_mutex);
366 wil_p2p_stop_discovery(wil); 373 wil_p2p_stop_discovery(vif);
367 mutex_lock(&wil->p2p_wdev_mutex); 374 mutex_lock(&wil->vif_mutex);
368 375
369 if (wil->scan_request) { 376 if (vif->scan_request) {
370 /* search */ 377 /* search */
371 cfg80211_scan_done(wil->scan_request, &info); 378 cfg80211_scan_done(vif->scan_request, &info);
372 wil->scan_request = NULL; 379 vif->scan_request = NULL;
373 } else { 380 } else {
374 /* listen */ 381 /* listen */
375 cfg80211_remain_on_channel_expired(wil->radio_wdev, 382 cfg80211_remain_on_channel_expired(wil->radio_wdev,
@@ -379,5 +386,5 @@ void wil_p2p_stop_radio_operations(struct wil6210_priv *wil)
379 } 386 }
380 387
381out: 388out:
382 wil->radio_wdev = wil->wdev; 389 wil->radio_wdev = wil->main_ndev->ieee80211_ptr;
383} 390}
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 809092a49192..19cbc6add637 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -137,6 +137,20 @@ void wil_enable_irq(struct wil6210_priv *wil)
137 enable_irq(wil->pdev->irq); 137 enable_irq(wil->pdev->irq);
138} 138}
139 139
140static void wil_remove_all_additional_vifs(struct wil6210_priv *wil)
141{
142 struct wil6210_vif *vif;
143 int i;
144
145 for (i = 1; i < wil->max_vifs; i++) {
146 vif = wil->vifs[i];
147 if (vif) {
148 wil_vif_prepare_stop(vif);
149 wil_vif_remove(wil, vif->mid);
150 }
151 }
152}
153
140/* Bus ops */ 154/* Bus ops */
141static int wil_if_pcie_enable(struct wil6210_priv *wil) 155static int wil_if_pcie_enable(struct wil6210_priv *wil)
142{ 156{
@@ -148,10 +162,8 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
148 */ 162 */
149 int msi_only = pdev->msi_enabled; 163 int msi_only = pdev->msi_enabled;
150 bool _use_msi = use_msi; 164 bool _use_msi = use_msi;
151 bool wmi_only = test_bit(WMI_FW_CAPABILITY_WMI_ONLY,
152 wil->fw_capabilities);
153 165
154 wil_dbg_misc(wil, "if_pcie_enable, wmi_only %d\n", wmi_only); 166 wil_dbg_misc(wil, "if_pcie_enable\n");
155 167
156 pci_set_master(pdev); 168 pci_set_master(pdev);
157 169
@@ -172,11 +184,9 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
172 if (rc) 184 if (rc)
173 goto stop_master; 185 goto stop_master;
174 186
175 /* need reset here to obtain MAC or in case of WMI-only FW, full reset 187 /* need reset here to obtain MAC */
176 * and fw loading takes place
177 */
178 mutex_lock(&wil->mutex); 188 mutex_lock(&wil->mutex);
179 rc = wil_reset(wil, wmi_only); 189 rc = wil_reset(wil, false);
180 mutex_unlock(&wil->mutex); 190 mutex_unlock(&wil->mutex);
181 if (rc) 191 if (rc)
182 goto release_irq; 192 goto release_irq;
@@ -356,6 +366,18 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
356 goto bus_disable; 366 goto bus_disable;
357 } 367 }
358 368
369 /* in case of WMI-only FW, perform full reset and FW loading */
370 if (test_bit(WMI_FW_CAPABILITY_WMI_ONLY, wil->fw_capabilities)) {
371 wil_dbg_misc(wil, "Loading WMI only FW\n");
372 mutex_lock(&wil->mutex);
373 rc = wil_reset(wil, true);
374 mutex_unlock(&wil->mutex);
375 if (rc) {
376 wil_err(wil, "failed to load WMI only FW\n");
377 goto if_remove;
378 }
379 }
380
359 if (IS_ENABLED(CONFIG_PM)) 381 if (IS_ENABLED(CONFIG_PM))
360 wil->pm_notify.notifier_call = wil6210_pm_notify; 382 wil->pm_notify.notifier_call = wil6210_pm_notify;
361 383
@@ -372,6 +394,8 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
372 394
373 return 0; 395 return 0;
374 396
397if_remove:
398 wil_if_remove(wil);
375bus_disable: 399bus_disable:
376 wil_if_pcie_disable(wil); 400 wil_if_pcie_disable(wil);
377err_iounmap: 401err_iounmap:
@@ -402,6 +426,7 @@ static void wil_pcie_remove(struct pci_dev *pdev)
402 wil6210_debugfs_remove(wil); 426 wil6210_debugfs_remove(wil);
403 rtnl_lock(); 427 rtnl_lock();
404 wil_p2p_wdev_free(wil); 428 wil_p2p_wdev_free(wil);
429 wil_remove_all_additional_vifs(wil);
405 rtnl_unlock(); 430 rtnl_unlock();
406 wil_if_remove(wil); 431 wil_if_remove(wil);
407 wil_if_pcie_disable(wil); 432 wil_if_pcie_disable(wil);
@@ -425,12 +450,15 @@ static int wil6210_suspend(struct device *dev, bool is_runtime)
425 int rc = 0; 450 int rc = 0;
426 struct pci_dev *pdev = to_pci_dev(dev); 451 struct pci_dev *pdev = to_pci_dev(dev);
427 struct wil6210_priv *wil = pci_get_drvdata(pdev); 452 struct wil6210_priv *wil = pci_get_drvdata(pdev);
428 struct net_device *ndev = wil_to_ndev(wil); 453 bool keep_radio_on, active_ifaces;
429 bool keep_radio_on = ndev->flags & IFF_UP &&
430 wil->keep_radio_on_during_sleep;
431 454
432 wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system"); 455 wil_dbg_pm(wil, "suspend: %s\n", is_runtime ? "runtime" : "system");
433 456
457 mutex_lock(&wil->vif_mutex);
458 active_ifaces = wil_has_active_ifaces(wil, true, false);
459 mutex_unlock(&wil->vif_mutex);
460 keep_radio_on = active_ifaces && wil->keep_radio_on_during_sleep;
461
434 rc = wil_can_suspend(wil, is_runtime); 462 rc = wil_can_suspend(wil, is_runtime);
435 if (rc) 463 if (rc)
436 goto out; 464 goto out;
@@ -457,12 +485,15 @@ static int wil6210_resume(struct device *dev, bool is_runtime)
457 int rc = 0; 485 int rc = 0;
458 struct pci_dev *pdev = to_pci_dev(dev); 486 struct pci_dev *pdev = to_pci_dev(dev);
459 struct wil6210_priv *wil = pci_get_drvdata(pdev); 487 struct wil6210_priv *wil = pci_get_drvdata(pdev);
460 struct net_device *ndev = wil_to_ndev(wil); 488 bool keep_radio_on, active_ifaces;
461 bool keep_radio_on = ndev->flags & IFF_UP &&
462 wil->keep_radio_on_during_sleep;
463 489
464 wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system"); 490 wil_dbg_pm(wil, "resume: %s\n", is_runtime ? "runtime" : "system");
465 491
492 mutex_lock(&wil->vif_mutex);
493 active_ifaces = wil_has_active_ifaces(wil, true, false);
494 mutex_unlock(&wil->vif_mutex);
495 keep_radio_on = active_ifaces && wil->keep_radio_on_during_sleep;
496
466 /* In case radio stays on, platform device will control 497 /* In case radio stays on, platform device will control
467 * PCIe master 498 * PCIe master
468 */ 499 */
diff --git a/drivers/net/wireless/ath/wil6210/pm.c b/drivers/net/wireless/ath/wil6210/pm.c
index 0a96518a566f..ba81fb3ac96f 100644
--- a/drivers/net/wireless/ath/wil6210/pm.c
+++ b/drivers/net/wireless/ath/wil6210/pm.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2014,2017 Qualcomm Atheros, Inc. 2 * Copyright (c) 2014,2017 Qualcomm Atheros, Inc.
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
3 * 4 *
4 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -20,13 +21,72 @@
20 21
21#define WIL6210_AUTOSUSPEND_DELAY_MS (1000) 22#define WIL6210_AUTOSUSPEND_DELAY_MS (1000)
22 23
24static void wil_pm_wake_connected_net_queues(struct wil6210_priv *wil)
25{
26 int i;
27
28 mutex_lock(&wil->vif_mutex);
29 for (i = 0; i < wil->max_vifs; i++) {
30 struct wil6210_vif *vif = wil->vifs[i];
31
32 if (vif && test_bit(wil_vif_fwconnected, vif->status))
33 wil_update_net_queues_bh(wil, vif, NULL, false);
34 }
35 mutex_unlock(&wil->vif_mutex);
36}
37
38static void wil_pm_stop_all_net_queues(struct wil6210_priv *wil)
39{
40 int i;
41
42 mutex_lock(&wil->vif_mutex);
43 for (i = 0; i < wil->max_vifs; i++) {
44 struct wil6210_vif *vif = wil->vifs[i];
45
46 if (vif)
47 wil_update_net_queues_bh(wil, vif, NULL, true);
48 }
49 mutex_unlock(&wil->vif_mutex);
50}
51
52static bool
53wil_can_suspend_vif(struct wil6210_priv *wil, struct wil6210_vif *vif,
54 bool is_runtime)
55{
56 struct wireless_dev *wdev = vif_to_wdev(vif);
57
58 switch (wdev->iftype) {
59 case NL80211_IFTYPE_MONITOR:
60 wil_dbg_pm(wil, "Sniffer\n");
61 return false;
62
63 /* for STA-like interface, don't runtime suspend */
64 case NL80211_IFTYPE_STATION:
65 case NL80211_IFTYPE_P2P_CLIENT:
66 if (test_bit(wil_vif_fwconnecting, vif->status)) {
67 wil_dbg_pm(wil, "Delay suspend when connecting\n");
68 return false;
69 }
70 if (is_runtime) {
71 wil_dbg_pm(wil, "STA-like interface\n");
72 return false;
73 }
74 break;
75 /* AP-like interface - can't suspend */
76 default:
77 wil_dbg_pm(wil, "AP-like interface\n");
78 return false;
79 }
80
81 return true;
82}
83
23int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime) 84int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime)
24{ 85{
25 int rc = 0; 86 int rc = 0, i;
26 struct wireless_dev *wdev = wil->wdev;
27 struct net_device *ndev = wil_to_ndev(wil);
28 bool wmi_only = test_bit(WMI_FW_CAPABILITY_WMI_ONLY, 87 bool wmi_only = test_bit(WMI_FW_CAPABILITY_WMI_ONLY,
29 wil->fw_capabilities); 88 wil->fw_capabilities);
89 bool active_ifaces;
30 90
31 wil_dbg_pm(wil, "can_suspend: %s\n", is_runtime ? "runtime" : "system"); 91 wil_dbg_pm(wil, "can_suspend: %s\n", is_runtime ? "runtime" : "system");
32 92
@@ -40,7 +100,12 @@ int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime)
40 rc = -EBUSY; 100 rc = -EBUSY;
41 goto out; 101 goto out;
42 } 102 }
43 if (!(ndev->flags & IFF_UP)) { 103
104 mutex_lock(&wil->vif_mutex);
105 active_ifaces = wil_has_active_ifaces(wil, true, false);
106 mutex_unlock(&wil->vif_mutex);
107
108 if (!active_ifaces) {
44 /* can always sleep when down */ 109 /* can always sleep when down */
45 wil_dbg_pm(wil, "Interface is down\n"); 110 wil_dbg_pm(wil, "Interface is down\n");
46 goto out; 111 goto out;
@@ -57,32 +122,19 @@ int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime)
57 } 122 }
58 123
59 /* interface is running */ 124 /* interface is running */
60 switch (wdev->iftype) { 125 mutex_lock(&wil->vif_mutex);
61 case NL80211_IFTYPE_MONITOR: 126 for (i = 0; i < wil->max_vifs; i++) {
62 wil_dbg_pm(wil, "Sniffer\n"); 127 struct wil6210_vif *vif = wil->vifs[i];
63 rc = -EBUSY; 128
64 goto out; 129 if (!vif)
65 /* for STA-like interface, don't runtime suspend */ 130 continue;
66 case NL80211_IFTYPE_STATION: 131 if (!wil_can_suspend_vif(wil, vif, is_runtime)) {
67 case NL80211_IFTYPE_P2P_CLIENT:
68 if (test_bit(wil_status_fwconnecting, wil->status)) {
69 wil_dbg_pm(wil, "Delay suspend when connecting\n");
70 rc = -EBUSY;
71 goto out;
72 }
73 /* Runtime pm not supported in case the interface is up */
74 if (is_runtime) {
75 wil_dbg_pm(wil, "STA-like interface\n");
76 rc = -EBUSY; 132 rc = -EBUSY;
133 mutex_unlock(&wil->vif_mutex);
77 goto out; 134 goto out;
78 } 135 }
79 break;
80 /* AP-like interface - can't suspend */
81 default:
82 wil_dbg_pm(wil, "AP-like interface\n");
83 rc = -EBUSY;
84 break;
85 } 136 }
137 mutex_unlock(&wil->vif_mutex);
86 138
87out: 139out:
88 wil_dbg_pm(wil, "can_suspend: %s => %s (%d)\n", 140 wil_dbg_pm(wil, "can_suspend: %s => %s (%d)\n",
@@ -127,8 +179,7 @@ static int wil_resume_keep_radio_on(struct wil6210_priv *wil)
127 } 179 }
128 180
129 /* Wake all queues */ 181 /* Wake all queues */
130 if (test_bit(wil_status_fwconnected, wil->status)) 182 wil_pm_wake_connected_net_queues(wil);
131 wil_update_net_queues_bh(wil, NULL, false);
132 183
133out: 184out:
134 if (rc) 185 if (rc)
@@ -152,7 +203,7 @@ static int wil_suspend_keep_radio_on(struct wil6210_priv *wil)
152 wil->suspend_stats.rejected_by_host++; 203 wil->suspend_stats.rejected_by_host++;
153 return -EBUSY; 204 return -EBUSY;
154 } 205 }
155 wil_update_net_queues_bh(wil, NULL, true); 206 wil_pm_stop_all_net_queues(wil);
156 207
157 if (!wil_is_tx_idle(wil)) { 208 if (!wil_is_tx_idle(wil)) {
158 wil_dbg_pm(wil, "Pending TX data, reject suspend\n"); 209 wil_dbg_pm(wil, "Pending TX data, reject suspend\n");
@@ -243,22 +294,20 @@ resume_after_fail:
243 /* if resume succeeded, reject the suspend */ 294 /* if resume succeeded, reject the suspend */
244 if (!rc) { 295 if (!rc) {
245 rc = -EBUSY; 296 rc = -EBUSY;
246 if (test_bit(wil_status_fwconnected, wil->status)) 297 wil_pm_wake_connected_net_queues(wil);
247 wil_update_net_queues_bh(wil, NULL, false);
248 } 298 }
249 return rc; 299 return rc;
250 300
251reject_suspend: 301reject_suspend:
252 clear_bit(wil_status_suspending, wil->status); 302 clear_bit(wil_status_suspending, wil->status);
253 if (test_bit(wil_status_fwconnected, wil->status)) 303 wil_pm_wake_connected_net_queues(wil);
254 wil_update_net_queues_bh(wil, NULL, false);
255 return -EBUSY; 304 return -EBUSY;
256} 305}
257 306
258static int wil_suspend_radio_off(struct wil6210_priv *wil) 307static int wil_suspend_radio_off(struct wil6210_priv *wil)
259{ 308{
260 int rc = 0; 309 int rc = 0;
261 struct net_device *ndev = wil_to_ndev(wil); 310 bool active_ifaces;
262 311
263 wil_dbg_pm(wil, "suspend radio off\n"); 312 wil_dbg_pm(wil, "suspend radio off\n");
264 313
@@ -272,7 +321,11 @@ static int wil_suspend_radio_off(struct wil6210_priv *wil)
272 } 321 }
273 322
274 /* if netif up, hardware is alive, shut it down */ 323 /* if netif up, hardware is alive, shut it down */
275 if (ndev->flags & IFF_UP) { 324 mutex_lock(&wil->vif_mutex);
325 active_ifaces = wil_has_active_ifaces(wil, true, false);
326 mutex_unlock(&wil->vif_mutex);
327
328 if (active_ifaces) {
276 rc = wil_down(wil); 329 rc = wil_down(wil);
277 if (rc) { 330 if (rc) {
278 wil_err(wil, "wil_down : %d\n", rc); 331 wil_err(wil, "wil_down : %d\n", rc);
@@ -306,16 +359,19 @@ out:
306static int wil_resume_radio_off(struct wil6210_priv *wil) 359static int wil_resume_radio_off(struct wil6210_priv *wil)
307{ 360{
308 int rc = 0; 361 int rc = 0;
309 struct net_device *ndev = wil_to_ndev(wil); 362 bool active_ifaces;
310 363
311 wil_dbg_pm(wil, "Enabling PCIe IRQ\n"); 364 wil_dbg_pm(wil, "Enabling PCIe IRQ\n");
312 wil_enable_irq(wil); 365 wil_enable_irq(wil);
313 /* if netif up, bring hardware up 366 /* if any netif up, bring hardware up
314 * During open(), IFF_UP set after actual device method 367 * During open(), IFF_UP set after actual device method
315 * invocation. This prevent recursive call to wil_up() 368 * invocation. This prevent recursive call to wil_up()
316 * wil_status_suspended will be cleared in wil_reset 369 * wil_status_suspended will be cleared in wil_reset
317 */ 370 */
318 if (ndev->flags & IFF_UP) 371 mutex_lock(&wil->vif_mutex);
372 active_ifaces = wil_has_active_ifaces(wil, true, false);
373 mutex_unlock(&wil->vif_mutex);
374 if (active_ifaces)
319 rc = wil_up(wil); 375 rc = wil_up(wil);
320 else 376 else
321 clear_bit(wil_status_suspended, wil->status); 377 clear_bit(wil_status_suspended, wil->status);
diff --git a/drivers/net/wireless/ath/wil6210/pmc.c b/drivers/net/wireless/ath/wil6210/pmc.c
index 4ea27b0bd278..c49f7988369e 100644
--- a/drivers/net/wireless/ath/wil6210/pmc.c
+++ b/drivers/net/wireless/ath/wil6210/pmc.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2012-2015,2017 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2015,2017 Qualcomm Atheros, Inc.
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
3 * 4 *
4 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -53,6 +54,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
53 u32 i; 54 u32 i;
54 struct pmc_ctx *pmc = &wil->pmc; 55 struct pmc_ctx *pmc = &wil->pmc;
55 struct device *dev = wil_to_dev(wil); 56 struct device *dev = wil_to_dev(wil);
57 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
56 struct wmi_pmc_cmd pmc_cmd = {0}; 58 struct wmi_pmc_cmd pmc_cmd = {0};
57 int last_cmd_err = -ENOMEM; 59 int last_cmd_err = -ENOMEM;
58 60
@@ -186,6 +188,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil,
186 wil_dbg_misc(wil, "pmc_alloc: send WMI_PMC_CMD with ALLOCATE op\n"); 188 wil_dbg_misc(wil, "pmc_alloc: send WMI_PMC_CMD with ALLOCATE op\n");
187 pmc->last_cmd_status = wmi_send(wil, 189 pmc->last_cmd_status = wmi_send(wil,
188 WMI_PMC_CMDID, 190 WMI_PMC_CMDID,
191 vif->mid,
189 &pmc_cmd, 192 &pmc_cmd,
190 sizeof(pmc_cmd)); 193 sizeof(pmc_cmd));
191 if (pmc->last_cmd_status) { 194 if (pmc->last_cmd_status) {
@@ -236,6 +239,7 @@ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd)
236{ 239{
237 struct pmc_ctx *pmc = &wil->pmc; 240 struct pmc_ctx *pmc = &wil->pmc;
238 struct device *dev = wil_to_dev(wil); 241 struct device *dev = wil_to_dev(wil);
242 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
239 struct wmi_pmc_cmd pmc_cmd = {0}; 243 struct wmi_pmc_cmd pmc_cmd = {0};
240 244
241 mutex_lock(&pmc->lock); 245 mutex_lock(&pmc->lock);
@@ -254,8 +258,8 @@ void wil_pmc_free(struct wil6210_priv *wil, int send_pmc_cmd)
254 wil_dbg_misc(wil, "send WMI_PMC_CMD with RELEASE op\n"); 258 wil_dbg_misc(wil, "send WMI_PMC_CMD with RELEASE op\n");
255 pmc_cmd.op = WMI_PMC_RELEASE; 259 pmc_cmd.op = WMI_PMC_RELEASE;
256 pmc->last_cmd_status = 260 pmc->last_cmd_status =
257 wmi_send(wil, WMI_PMC_CMDID, &pmc_cmd, 261 wmi_send(wil, WMI_PMC_CMDID, vif->mid,
258 sizeof(pmc_cmd)); 262 &pmc_cmd, sizeof(pmc_cmd));
259 if (pmc->last_cmd_status) { 263 if (pmc->last_cmd_status) {
260 wil_err(wil, 264 wil_err(wil,
261 "WMI_PMC_CMD with RELEASE op failed, status %d", 265 "WMI_PMC_CMD with RELEASE op failed, status %d",
diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c
index a43cffcf1bbf..14dcb0698dee 100644
--- a/drivers/net/wireless/ath/wil6210/rx_reorder.c
+++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2014-2017 Qualcomm Atheros, Inc. 2 * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
3 * 4 *
4 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -40,11 +41,10 @@ static inline int reorder_index(struct wil_tid_ampdu_rx *r, u16 seq)
40 return seq_sub(seq, r->ssn) % r->buf_size; 41 return seq_sub(seq, r->ssn) % r->buf_size;
41} 42}
42 43
43static void wil_release_reorder_frame(struct wil6210_priv *wil, 44static void wil_release_reorder_frame(struct net_device *ndev,
44 struct wil_tid_ampdu_rx *r, 45 struct wil_tid_ampdu_rx *r,
45 int index) 46 int index)
46{ 47{
47 struct net_device *ndev = wil_to_ndev(wil);
48 struct sk_buff *skb = r->reorder_buf[index]; 48 struct sk_buff *skb = r->reorder_buf[index];
49 49
50 if (!skb) 50 if (!skb)
@@ -59,7 +59,7 @@ no_frame:
59 r->head_seq_num = seq_inc(r->head_seq_num); 59 r->head_seq_num = seq_inc(r->head_seq_num);
60} 60}
61 61
62static void wil_release_reorder_frames(struct wil6210_priv *wil, 62static void wil_release_reorder_frames(struct net_device *ndev,
63 struct wil_tid_ampdu_rx *r, 63 struct wil_tid_ampdu_rx *r,
64 u16 hseq) 64 u16 hseq)
65{ 65{
@@ -73,18 +73,18 @@ static void wil_release_reorder_frames(struct wil6210_priv *wil,
73 */ 73 */
74 while (seq_less(r->head_seq_num, hseq) && r->stored_mpdu_num) { 74 while (seq_less(r->head_seq_num, hseq) && r->stored_mpdu_num) {
75 index = reorder_index(r, r->head_seq_num); 75 index = reorder_index(r, r->head_seq_num);
76 wil_release_reorder_frame(wil, r, index); 76 wil_release_reorder_frame(ndev, r, index);
77 } 77 }
78 r->head_seq_num = hseq; 78 r->head_seq_num = hseq;
79} 79}
80 80
81static void wil_reorder_release(struct wil6210_priv *wil, 81static void wil_reorder_release(struct net_device *ndev,
82 struct wil_tid_ampdu_rx *r) 82 struct wil_tid_ampdu_rx *r)
83{ 83{
84 int index = reorder_index(r, r->head_seq_num); 84 int index = reorder_index(r, r->head_seq_num);
85 85
86 while (r->reorder_buf[index]) { 86 while (r->reorder_buf[index]) {
87 wil_release_reorder_frame(wil, r, index); 87 wil_release_reorder_frame(ndev, r, index);
88 index = reorder_index(r, r->head_seq_num); 88 index = reorder_index(r, r->head_seq_num);
89 } 89 }
90} 90}
@@ -93,7 +93,8 @@ static void wil_reorder_release(struct wil6210_priv *wil,
93void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb) 93void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
94__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) 94__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
95{ 95{
96 struct net_device *ndev = wil_to_ndev(wil); 96 struct wil6210_vif *vif;
97 struct net_device *ndev;
97 struct vring_rx_desc *d = wil_skb_rxdesc(skb); 98 struct vring_rx_desc *d = wil_skb_rxdesc(skb);
98 int tid = wil_rxdesc_tid(d); 99 int tid = wil_rxdesc_tid(d);
99 int cid = wil_rxdesc_cid(d); 100 int cid = wil_rxdesc_cid(d);
@@ -108,6 +109,14 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
108 wil_dbg_txrx(wil, "MID %d CID %d TID %d Seq 0x%03x mcast %01x\n", 109 wil_dbg_txrx(wil, "MID %d CID %d TID %d Seq 0x%03x mcast %01x\n",
109 mid, cid, tid, seq, mcast); 110 mid, cid, tid, seq, mcast);
110 111
112 vif = wil->vifs[mid];
113 if (unlikely(!vif)) {
114 wil_dbg_txrx(wil, "invalid VIF, mid %d\n", mid);
115 dev_kfree_skb(skb);
116 return;
117 }
118 ndev = vif_to_ndev(vif);
119
111 if (unlikely(mcast)) { 120 if (unlikely(mcast)) {
112 wil_netif_rx_any(skb, ndev); 121 wil_netif_rx_any(skb, ndev);
113 return; 122 return;
@@ -168,7 +177,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
168 if (!seq_less(seq, r->head_seq_num + r->buf_size)) { 177 if (!seq_less(seq, r->head_seq_num + r->buf_size)) {
169 hseq = seq_inc(seq_sub(seq, r->buf_size)); 178 hseq = seq_inc(seq_sub(seq, r->buf_size));
170 /* release stored frames up to new head to stack */ 179 /* release stored frames up to new head to stack */
171 wil_release_reorder_frames(wil, r, hseq); 180 wil_release_reorder_frames(ndev, r, hseq);
172 } 181 }
173 182
174 /* Now the new frame is always in the range of the reordering buffer */ 183 /* Now the new frame is always in the range of the reordering buffer */
@@ -199,16 +208,18 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
199 r->reorder_buf[index] = skb; 208 r->reorder_buf[index] = skb;
200 r->reorder_time[index] = jiffies; 209 r->reorder_time[index] = jiffies;
201 r->stored_mpdu_num++; 210 r->stored_mpdu_num++;
202 wil_reorder_release(wil, r); 211 wil_reorder_release(ndev, r);
203 212
204out: 213out:
205 spin_unlock(&sta->tid_rx_lock); 214 spin_unlock(&sta->tid_rx_lock);
206} 215}
207 216
208/* process BAR frame, called in NAPI context */ 217/* process BAR frame, called in NAPI context */
209void wil_rx_bar(struct wil6210_priv *wil, u8 cid, u8 tid, u16 seq) 218void wil_rx_bar(struct wil6210_priv *wil, struct wil6210_vif *vif,
219 u8 cid, u8 tid, u16 seq)
210{ 220{
211 struct wil_sta_info *sta = &wil->sta[cid]; 221 struct wil_sta_info *sta = &wil->sta[cid];
222 struct net_device *ndev = vif_to_ndev(vif);
212 struct wil_tid_ampdu_rx *r; 223 struct wil_tid_ampdu_rx *r;
213 224
214 spin_lock(&sta->tid_rx_lock); 225 spin_lock(&sta->tid_rx_lock);
@@ -223,9 +234,9 @@ void wil_rx_bar(struct wil6210_priv *wil, u8 cid, u8 tid, u16 seq)
223 seq, r->head_seq_num); 234 seq, r->head_seq_num);
224 goto out; 235 goto out;
225 } 236 }
226 wil_dbg_txrx(wil, "BAR: CID %d TID %d Seq 0x%03x head 0x%03x\n", 237 wil_dbg_txrx(wil, "BAR: CID %d MID %d TID %d Seq 0x%03x head 0x%03x\n",
227 cid, tid, seq, r->head_seq_num); 238 cid, vif->mid, tid, seq, r->head_seq_num);
228 wil_release_reorder_frames(wil, r, seq); 239 wil_release_reorder_frames(ndev, r, seq);
229 240
230out: 241out:
231 spin_unlock(&sta->tid_rx_lock); 242 spin_unlock(&sta->tid_rx_lock);
@@ -292,8 +303,8 @@ static u16 wil_agg_size(struct wil6210_priv *wil, u16 req_agg_wsize)
292} 303}
293 304
294/* Block Ack - Rx side (recipient) */ 305/* Block Ack - Rx side (recipient) */
295int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid, 306int wil_addba_rx_request(struct wil6210_priv *wil, u8 mid,
296 u8 dialog_token, __le16 ba_param_set, 307 u8 cidxtid, u8 dialog_token, __le16 ba_param_set,
297 __le16 ba_timeout, __le16 ba_seq_ctrl) 308 __le16 ba_timeout, __le16 ba_seq_ctrl)
298__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) 309__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
299{ 310{
@@ -354,7 +365,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
354 } 365 }
355 } 366 }
356 367
357 rc = wmi_addba_rx_resp(wil, cid, tid, dialog_token, status, 368 rc = wmi_addba_rx_resp(wil, mid, cid, tid, dialog_token, status,
358 agg_amsdu, agg_wsize, agg_timeout); 369 agg_amsdu, agg_wsize, agg_timeout);
359 if (rc || (status != WLAN_STATUS_SUCCESS)) { 370 if (rc || (status != WLAN_STATUS_SUCCESS)) {
360 wil_err(wil, "do not apply ba, rc(%d), status(%d)\n", rc, 371 wil_err(wil, "do not apply ba, rc(%d), status(%d)\n", rc,
@@ -393,7 +404,7 @@ int wil_addba_tx_request(struct wil6210_priv *wil, u8 ringid, u16 wsize)
393 goto out; 404 goto out;
394 } 405 }
395 txdata->addba_in_progress = true; 406 txdata->addba_in_progress = true;
396 rc = wmi_addba(wil, ringid, agg_wsize, agg_timeout); 407 rc = wmi_addba(wil, txdata->mid, ringid, agg_wsize, agg_timeout);
397 if (rc) { 408 if (rc) {
398 wil_err(wil, "wmi_addba failed, rc (%d)", rc); 409 wil_err(wil, "wmi_addba failed, rc (%d)", rc);
399 txdata->addba_in_progress = false; 410 txdata->addba_in_progress = false;
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 16b8a4e5201f..b60b9fcaaebd 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
3 * 4 *
4 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -474,7 +475,8 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
474 struct vring *vring) 475 struct vring *vring)
475{ 476{
476 struct device *dev = wil_to_dev(wil); 477 struct device *dev = wil_to_dev(wil);
477 struct net_device *ndev = wil_to_ndev(wil); 478 struct wil6210_vif *vif;
479 struct net_device *ndev;
478 volatile struct vring_rx_desc *_d; 480 volatile struct vring_rx_desc *_d;
479 struct vring_rx_desc *d; 481 struct vring_rx_desc *d;
480 struct sk_buff *skb; 482 struct sk_buff *skb;
@@ -483,7 +485,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
483 unsigned int sz = wil->rx_buf_len + ETH_HLEN + snaplen; 485 unsigned int sz = wil->rx_buf_len + ETH_HLEN + snaplen;
484 u16 dmalen; 486 u16 dmalen;
485 u8 ftype; 487 u8 ftype;
486 int cid; 488 int cid, mid;
487 int i; 489 int i;
488 struct wil_net_stats *stats; 490 struct wil_net_stats *stats;
489 491
@@ -520,6 +522,16 @@ again:
520 (const void *)d, sizeof(*d), false); 522 (const void *)d, sizeof(*d), false);
521 523
522 cid = wil_rxdesc_cid(d); 524 cid = wil_rxdesc_cid(d);
525 mid = wil_rxdesc_mid(d);
526 vif = wil->vifs[mid];
527
528 if (unlikely(!vif)) {
529 wil_dbg_txrx(wil, "skipped RX descriptor with invalid mid %d",
530 mid);
531 kfree_skb(skb);
532 goto again;
533 }
534 ndev = vif_to_ndev(vif);
523 stats = &wil->sta[cid].stats; 535 stats = &wil->sta[cid].stats;
524 536
525 if (unlikely(dmalen > sz)) { 537 if (unlikely(dmalen > sz)) {
@@ -553,7 +565,6 @@ again:
553 ftype = wil_rxdesc_ftype(d) << 2; 565 ftype = wil_rxdesc_ftype(d) << 2;
554 if (unlikely(ftype != IEEE80211_FTYPE_DATA)) { 566 if (unlikely(ftype != IEEE80211_FTYPE_DATA)) {
555 u8 fc1 = wil_rxdesc_fc1(d); 567 u8 fc1 = wil_rxdesc_fc1(d);
556 int mid = wil_rxdesc_mid(d);
557 int tid = wil_rxdesc_tid(d); 568 int tid = wil_rxdesc_tid(d);
558 u16 seq = wil_rxdesc_seq(d); 569 u16 seq = wil_rxdesc_seq(d);
559 570
@@ -565,7 +576,7 @@ again:
565 wil_dbg_txrx(wil, 576 wil_dbg_txrx(wil,
566 "BAR: MID %d CID %d TID %d Seq 0x%03x\n", 577 "BAR: MID %d CID %d TID %d Seq 0x%03x\n",
567 mid, cid, tid, seq); 578 mid, cid, tid, seq);
568 wil_rx_bar(wil, cid, tid, seq); 579 wil_rx_bar(wil, vif, cid, tid, seq);
569 } else { 580 } else {
570 /* print again all info. One can enable only this 581 /* print again all info. One can enable only this
571 * without overhead for printing every Rx frame 582 * without overhead for printing every Rx frame
@@ -621,10 +632,15 @@ again:
621/** 632/**
622 * allocate and fill up to @count buffers in rx ring 633 * allocate and fill up to @count buffers in rx ring
623 * buffers posted at @swtail 634 * buffers posted at @swtail
635 * Note: we have a single RX queue for servicing all VIFs, but we
636 * allocate skbs with headroom according to main interface only. This
637 * means it will not work with monitor interface together with other VIFs.
638 * Currently we only support monitor interface on its own without other VIFs,
639 * and we will need to fix this code once we add support.
624 */ 640 */
625static int wil_rx_refill(struct wil6210_priv *wil, int count) 641static int wil_rx_refill(struct wil6210_priv *wil, int count)
626{ 642{
627 struct net_device *ndev = wil_to_ndev(wil); 643 struct net_device *ndev = wil->main_ndev;
628 struct vring *v = &wil->vring_rx; 644 struct vring *v = &wil->vring_rx;
629 u32 next_tail; 645 u32 next_tail;
630 int rc = 0; 646 int rc = 0;
@@ -713,8 +729,9 @@ static int wil_rx_crypto_check(struct wil6210_priv *wil, struct sk_buff *skb)
713void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) 729void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
714{ 730{
715 gro_result_t rc = GRO_NORMAL; 731 gro_result_t rc = GRO_NORMAL;
732 struct wil6210_vif *vif = ndev_to_vif(ndev);
716 struct wil6210_priv *wil = ndev_to_wil(ndev); 733 struct wil6210_priv *wil = ndev_to_wil(ndev);
717 struct wireless_dev *wdev = wil_to_wdev(wil); 734 struct wireless_dev *wdev = vif_to_wdev(vif);
718 unsigned int len = skb->len; 735 unsigned int len = skb->len;
719 struct vring_rx_desc *d = wil_skb_rxdesc(skb); 736 struct vring_rx_desc *d = wil_skb_rxdesc(skb);
720 int cid = wil_rxdesc_cid(d); /* always 0..7, no need to check */ 737 int cid = wil_rxdesc_cid(d); /* always 0..7, no need to check */
@@ -751,14 +768,15 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
751 goto stats; 768 goto stats;
752 } 769 }
753 770
754 if (wdev->iftype == NL80211_IFTYPE_AP && !wil->ap_isolate) { 771 if (wdev->iftype == NL80211_IFTYPE_AP && !vif->ap_isolate) {
755 if (mcast) { 772 if (mcast) {
756 /* send multicast frames both to higher layers in 773 /* send multicast frames both to higher layers in
757 * local net stack and back to the wireless medium 774 * local net stack and back to the wireless medium
758 */ 775 */
759 xmit_skb = skb_copy(skb, GFP_ATOMIC); 776 xmit_skb = skb_copy(skb, GFP_ATOMIC);
760 } else { 777 } else {
761 int xmit_cid = wil_find_cid(wil, eth->h_dest); 778 int xmit_cid = wil_find_cid(wil, vif->mid,
779 eth->h_dest);
762 780
763 if (xmit_cid >= 0) { 781 if (xmit_cid >= 0) {
764 /* The destination station is associated to 782 /* The destination station is associated to
@@ -786,8 +804,8 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
786 } 804 }
787 805
788 if (skb) { /* deliver to local stack */ 806 if (skb) { /* deliver to local stack */
789
790 skb->protocol = eth_type_trans(skb, ndev); 807 skb->protocol = eth_type_trans(skb, ndev);
808 skb->dev = ndev;
791 rc = napi_gro_receive(&wil->napi_rx, skb); 809 rc = napi_gro_receive(&wil->napi_rx, skb);
792 wil_dbg_txrx(wil, "Rx complete %d bytes => %s\n", 810 wil_dbg_txrx(wil, "Rx complete %d bytes => %s\n",
793 len, gro_res_str[rc]); 811 len, gro_res_str[rc]);
@@ -815,7 +833,8 @@ stats:
815 */ 833 */
816void wil_rx_handle(struct wil6210_priv *wil, int *quota) 834void wil_rx_handle(struct wil6210_priv *wil, int *quota)
817{ 835{
818 struct net_device *ndev = wil_to_ndev(wil); 836 struct net_device *ndev = wil->main_ndev;
837 struct wireless_dev *wdev = ndev->ieee80211_ptr;
819 struct vring *v = &wil->vring_rx; 838 struct vring *v = &wil->vring_rx;
820 struct sk_buff *skb; 839 struct sk_buff *skb;
821 840
@@ -827,7 +846,8 @@ void wil_rx_handle(struct wil6210_priv *wil, int *quota)
827 while ((*quota > 0) && (NULL != (skb = wil_vring_reap_rx(wil, v)))) { 846 while ((*quota > 0) && (NULL != (skb = wil_vring_reap_rx(wil, v)))) {
828 (*quota)--; 847 (*quota)--;
829 848
830 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR) { 849 /* monitor is currently supported on main interface only */
850 if (wdev->iftype == NL80211_IFTYPE_MONITOR) {
831 skb->dev = ndev; 851 skb->dev = ndev;
832 skb_reset_mac_header(skb); 852 skb_reset_mac_header(skb);
833 skb->ip_summed = CHECKSUM_UNNECESSARY; 853 skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -911,12 +931,14 @@ static inline void wil_tx_data_init(struct vring_tx_data *txdata)
911 txdata->agg_timeout = 0; 931 txdata->agg_timeout = 0;
912 txdata->agg_amsdu = 0; 932 txdata->agg_amsdu = 0;
913 txdata->addba_in_progress = false; 933 txdata->addba_in_progress = false;
934 txdata->mid = U8_MAX;
914 spin_unlock_bh(&txdata->lock); 935 spin_unlock_bh(&txdata->lock);
915} 936}
916 937
917int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, 938int wil_vring_init_tx(struct wil6210_vif *vif, int id, int size,
918 int cid, int tid) 939 int cid, int tid)
919{ 940{
941 struct wil6210_priv *wil = vif_to_wil(vif);
920 int rc; 942 int rc;
921 struct wmi_vring_cfg_cmd cmd = { 943 struct wmi_vring_cfg_cmd cmd = {
922 .action = cpu_to_le32(WMI_VRING_CMD_ADD), 944 .action = cpu_to_le32(WMI_VRING_CMD_ADD),
@@ -966,9 +988,9 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
966 988
967 cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); 989 cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa);
968 990
969 if (!wil->privacy) 991 if (!vif->privacy)
970 txdata->dot1x_open = true; 992 txdata->dot1x_open = true;
971 rc = wmi_call(wil, WMI_VRING_CFG_CMDID, &cmd, sizeof(cmd), 993 rc = wmi_call(wil, WMI_VRING_CFG_CMDID, vif->mid, &cmd, sizeof(cmd),
972 WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100); 994 WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100);
973 if (rc) 995 if (rc)
974 goto out_free; 996 goto out_free;
@@ -982,6 +1004,7 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
982 1004
983 spin_lock_bh(&txdata->lock); 1005 spin_lock_bh(&txdata->lock);
984 vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr); 1006 vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr);
1007 txdata->mid = vif->mid;
985 txdata->enabled = 1; 1008 txdata->enabled = 1;
986 spin_unlock_bh(&txdata->lock); 1009 spin_unlock_bh(&txdata->lock);
987 1010
@@ -1003,8 +1026,9 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
1003 return rc; 1026 return rc;
1004} 1027}
1005 1028
1006int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size) 1029int wil_vring_init_bcast(struct wil6210_vif *vif, int id, int size)
1007{ 1030{
1031 struct wil6210_priv *wil = vif_to_wil(vif);
1008 int rc; 1032 int rc;
1009 struct wmi_bcast_vring_cfg_cmd cmd = { 1033 struct wmi_bcast_vring_cfg_cmd cmd = {
1010 .action = cpu_to_le32(WMI_VRING_CMD_ADD), 1034 .action = cpu_to_le32(WMI_VRING_CMD_ADD),
@@ -1046,9 +1070,10 @@ int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size)
1046 1070
1047 cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa); 1071 cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa);
1048 1072
1049 if (!wil->privacy) 1073 if (!vif->privacy)
1050 txdata->dot1x_open = true; 1074 txdata->dot1x_open = true;
1051 rc = wmi_call(wil, WMI_BCAST_VRING_CFG_CMDID, &cmd, sizeof(cmd), 1075 rc = wmi_call(wil, WMI_BCAST_VRING_CFG_CMDID, vif->mid,
1076 &cmd, sizeof(cmd),
1052 WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100); 1077 WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100);
1053 if (rc) 1078 if (rc)
1054 goto out_free; 1079 goto out_free;
@@ -1062,6 +1087,7 @@ int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size)
1062 1087
1063 spin_lock_bh(&txdata->lock); 1088 spin_lock_bh(&txdata->lock);
1064 vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr); 1089 vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr);
1090 txdata->mid = vif->mid;
1065 txdata->enabled = 1; 1091 txdata->enabled = 1;
1066 spin_unlock_bh(&txdata->lock); 1092 spin_unlock_bh(&txdata->lock);
1067 1093
@@ -1091,6 +1117,7 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
1091 1117
1092 spin_lock_bh(&txdata->lock); 1118 spin_lock_bh(&txdata->lock);
1093 txdata->dot1x_open = false; 1119 txdata->dot1x_open = false;
1120 txdata->mid = U8_MAX;
1094 txdata->enabled = 0; /* no Tx can be in progress or start anew */ 1121 txdata->enabled = 0; /* no Tx can be in progress or start anew */
1095 spin_unlock_bh(&txdata->lock); 1122 spin_unlock_bh(&txdata->lock);
1096 /* napi_synchronize waits for completion of the current NAPI but will 1123 /* napi_synchronize waits for completion of the current NAPI but will
@@ -1108,11 +1135,12 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
1108} 1135}
1109 1136
1110static struct vring *wil_find_tx_ucast(struct wil6210_priv *wil, 1137static struct vring *wil_find_tx_ucast(struct wil6210_priv *wil,
1138 struct wil6210_vif *vif,
1111 struct sk_buff *skb) 1139 struct sk_buff *skb)
1112{ 1140{
1113 int i; 1141 int i;
1114 struct ethhdr *eth = (void *)skb->data; 1142 struct ethhdr *eth = (void *)skb->data;
1115 int cid = wil_find_cid(wil, eth->h_dest); 1143 int cid = wil_find_cid(wil, vif->mid, eth->h_dest);
1116 1144
1117 if (cid < 0) 1145 if (cid < 0)
1118 return NULL; 1146 return NULL;
@@ -1142,10 +1170,11 @@ static struct vring *wil_find_tx_ucast(struct wil6210_priv *wil,
1142 return NULL; 1170 return NULL;
1143} 1171}
1144 1172
1145static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, 1173static int wil_tx_vring(struct wil6210_priv *wil, struct wil6210_vif *vif,
1146 struct sk_buff *skb); 1174 struct vring *vring, struct sk_buff *skb);
1147 1175
1148static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil, 1176static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil,
1177 struct wil6210_vif *vif,
1149 struct sk_buff *skb) 1178 struct sk_buff *skb)
1150{ 1179{
1151 struct vring *v; 1180 struct vring *v;
@@ -1160,7 +1189,7 @@ static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil,
1160 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { 1189 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
1161 v = &wil->vring_tx[i]; 1190 v = &wil->vring_tx[i];
1162 txdata = &wil->vring_tx_data[i]; 1191 txdata = &wil->vring_tx_data[i];
1163 if (!v->va || !txdata->enabled) 1192 if (!v->va || !txdata->enabled || txdata->mid != vif->mid)
1164 continue; 1193 continue;
1165 1194
1166 cid = wil->vring2cid_tid[i][0]; 1195 cid = wil->vring2cid_tid[i][0];
@@ -1193,11 +1222,12 @@ static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil,
1193 * - for PBSS 1222 * - for PBSS
1194 */ 1223 */
1195static struct vring *wil_find_tx_bcast_1(struct wil6210_priv *wil, 1224static struct vring *wil_find_tx_bcast_1(struct wil6210_priv *wil,
1225 struct wil6210_vif *vif,
1196 struct sk_buff *skb) 1226 struct sk_buff *skb)
1197{ 1227{
1198 struct vring *v; 1228 struct vring *v;
1199 struct vring_tx_data *txdata; 1229 struct vring_tx_data *txdata;
1200 int i = wil->bcast_vring; 1230 int i = vif->bcast_vring;
1201 1231
1202 if (i < 0) 1232 if (i < 0)
1203 return NULL; 1233 return NULL;
@@ -1222,6 +1252,7 @@ static void wil_set_da_for_vring(struct wil6210_priv *wil,
1222} 1252}
1223 1253
1224static struct vring *wil_find_tx_bcast_2(struct wil6210_priv *wil, 1254static struct vring *wil_find_tx_bcast_2(struct wil6210_priv *wil,
1255 struct wil6210_vif *vif,
1225 struct sk_buff *skb) 1256 struct sk_buff *skb)
1226{ 1257{
1227 struct vring *v, *v2; 1258 struct vring *v, *v2;
@@ -1230,13 +1261,13 @@ static struct vring *wil_find_tx_bcast_2(struct wil6210_priv *wil,
1230 u8 cid; 1261 u8 cid;
1231 struct ethhdr *eth = (void *)skb->data; 1262 struct ethhdr *eth = (void *)skb->data;
1232 char *src = eth->h_source; 1263 char *src = eth->h_source;
1233 struct vring_tx_data *txdata; 1264 struct vring_tx_data *txdata, *txdata2;
1234 1265
1235 /* find 1-st vring eligible for data */ 1266 /* find 1-st vring eligible for data */
1236 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { 1267 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
1237 v = &wil->vring_tx[i]; 1268 v = &wil->vring_tx[i];
1238 txdata = &wil->vring_tx_data[i]; 1269 txdata = &wil->vring_tx_data[i];
1239 if (!v->va || !txdata->enabled) 1270 if (!v->va || !txdata->enabled || txdata->mid != vif->mid)
1240 continue; 1271 continue;
1241 1272
1242 cid = wil->vring2cid_tid[i][0]; 1273 cid = wil->vring2cid_tid[i][0];
@@ -1264,7 +1295,8 @@ found:
1264 /* find other active vrings and duplicate skb for each */ 1295 /* find other active vrings and duplicate skb for each */
1265 for (i++; i < WIL6210_MAX_TX_RINGS; i++) { 1296 for (i++; i < WIL6210_MAX_TX_RINGS; i++) {
1266 v2 = &wil->vring_tx[i]; 1297 v2 = &wil->vring_tx[i];
1267 if (!v2->va) 1298 txdata2 = &wil->vring_tx_data[i];
1299 if (!v2->va || txdata2->mid != vif->mid)
1268 continue; 1300 continue;
1269 cid = wil->vring2cid_tid[i][0]; 1301 cid = wil->vring2cid_tid[i][0];
1270 if (cid >= WIL6210_MAX_CID) /* skip BCAST */ 1302 if (cid >= WIL6210_MAX_CID) /* skip BCAST */
@@ -1280,7 +1312,7 @@ found:
1280 if (skb2) { 1312 if (skb2) {
1281 wil_dbg_txrx(wil, "BCAST DUP -> ring %d\n", i); 1313 wil_dbg_txrx(wil, "BCAST DUP -> ring %d\n", i);
1282 wil_set_da_for_vring(wil, skb2, i); 1314 wil_set_da_for_vring(wil, skb2, i);
1283 wil_tx_vring(wil, v2, skb2); 1315 wil_tx_vring(wil, vif, v2, skb2);
1284 } else { 1316 } else {
1285 wil_err(wil, "skb_copy failed\n"); 1317 wil_err(wil, "skb_copy failed\n");
1286 } 1318 }
@@ -1417,8 +1449,8 @@ static inline void wil_set_tx_desc_last_tso(volatile struct vring_tx_desc *d)
1417 DMA_CFG_DESC_TX_0_SEGMENT_BUF_DETAILS_POS; 1449 DMA_CFG_DESC_TX_0_SEGMENT_BUF_DETAILS_POS;
1418} 1450}
1419 1451
1420static int __wil_tx_vring_tso(struct wil6210_priv *wil, struct vring *vring, 1452static int __wil_tx_vring_tso(struct wil6210_priv *wil, struct wil6210_vif *vif,
1421 struct sk_buff *skb) 1453 struct vring *vring, struct sk_buff *skb)
1422{ 1454{
1423 struct device *dev = wil_to_dev(wil); 1455 struct device *dev = wil_to_dev(wil);
1424 1456
@@ -1710,8 +1742,8 @@ err_exit:
1710 return rc; 1742 return rc;
1711} 1743}
1712 1744
1713static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, 1745static int __wil_tx_vring(struct wil6210_priv *wil, struct wil6210_vif *vif,
1714 struct sk_buff *skb) 1746 struct vring *vring, struct sk_buff *skb)
1715{ 1747{
1716 struct device *dev = wil_to_dev(wil); 1748 struct device *dev = wil_to_dev(wil);
1717 struct vring_tx_desc dd, *d = &dd; 1749 struct vring_tx_desc dd, *d = &dd;
@@ -1725,7 +1757,7 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
1725 uint i = swhead; 1757 uint i = swhead;
1726 dma_addr_t pa; 1758 dma_addr_t pa;
1727 int used; 1759 int used;
1728 bool mcast = (vring_index == wil->bcast_vring); 1760 bool mcast = (vring_index == vif->bcast_vring);
1729 uint len = skb_headlen(skb); 1761 uint len = skb_headlen(skb);
1730 1762
1731 wil_dbg_txrx(wil, "tx_vring: %d bytes to vring %d\n", skb->len, 1763 wil_dbg_txrx(wil, "tx_vring: %d bytes to vring %d\n", skb->len,
@@ -1860,8 +1892,8 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
1860 return -EINVAL; 1892 return -EINVAL;
1861} 1893}
1862 1894
1863static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, 1895static int wil_tx_vring(struct wil6210_priv *wil, struct wil6210_vif *vif,
1864 struct sk_buff *skb) 1896 struct vring *vring, struct sk_buff *skb)
1865{ 1897{
1866 int vring_index = vring - wil->vring_tx; 1898 int vring_index = vring - wil->vring_tx;
1867 struct vring_tx_data *txdata = &wil->vring_tx_data[vring_index]; 1899 struct vring_tx_data *txdata = &wil->vring_tx_data[vring_index];
@@ -1879,7 +1911,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
1879 } 1911 }
1880 1912
1881 rc = (skb_is_gso(skb) ? __wil_tx_vring_tso : __wil_tx_vring) 1913 rc = (skb_is_gso(skb) ? __wil_tx_vring_tso : __wil_tx_vring)
1882 (wil, vring, skb); 1914 (wil, vif, vring, skb);
1883 1915
1884 spin_unlock(&txdata->lock); 1916 spin_unlock(&txdata->lock);
1885 1917
@@ -1888,6 +1920,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
1888 1920
1889/** 1921/**
1890 * Check status of tx vrings and stop/wake net queues if needed 1922 * Check status of tx vrings and stop/wake net queues if needed
1923 * It will start/stop net queues of a specific VIF net_device.
1891 * 1924 *
1892 * This function does one of two checks: 1925 * This function does one of two checks:
1893 * In case check_stop is true, will check if net queues need to be stopped. If 1926 * In case check_stop is true, will check if net queues need to be stopped. If
@@ -1903,28 +1936,32 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
1903 * availability and modified vring has high descriptor availability. 1936 * availability and modified vring has high descriptor availability.
1904 */ 1937 */
1905static inline void __wil_update_net_queues(struct wil6210_priv *wil, 1938static inline void __wil_update_net_queues(struct wil6210_priv *wil,
1939 struct wil6210_vif *vif,
1906 struct vring *vring, 1940 struct vring *vring,
1907 bool check_stop) 1941 bool check_stop)
1908{ 1942{
1909 int i; 1943 int i;
1910 1944
1945 if (unlikely(!vif))
1946 return;
1947
1911 if (vring) 1948 if (vring)
1912 wil_dbg_txrx(wil, "vring %d, check_stop=%d, stopped=%d", 1949 wil_dbg_txrx(wil, "vring %d, mid %d, check_stop=%d, stopped=%d",
1913 (int)(vring - wil->vring_tx), check_stop, 1950 (int)(vring - wil->vring_tx), vif->mid, check_stop,
1914 wil->net_queue_stopped); 1951 vif->net_queue_stopped);
1915 else 1952 else
1916 wil_dbg_txrx(wil, "check_stop=%d, stopped=%d", 1953 wil_dbg_txrx(wil, "check_stop=%d, mid=%d, stopped=%d",
1917 check_stop, wil->net_queue_stopped); 1954 check_stop, vif->mid, vif->net_queue_stopped);
1918 1955
1919 if (check_stop == wil->net_queue_stopped) 1956 if (check_stop == vif->net_queue_stopped)
1920 /* net queues already in desired state */ 1957 /* net queues already in desired state */
1921 return; 1958 return;
1922 1959
1923 if (check_stop) { 1960 if (check_stop) {
1924 if (!vring || unlikely(wil_vring_avail_low(vring))) { 1961 if (!vring || unlikely(wil_vring_avail_low(vring))) {
1925 /* not enough room in the vring */ 1962 /* not enough room in the vring */
1926 netif_tx_stop_all_queues(wil_to_ndev(wil)); 1963 netif_tx_stop_all_queues(vif_to_ndev(vif));
1927 wil->net_queue_stopped = true; 1964 vif->net_queue_stopped = true;
1928 wil_dbg_txrx(wil, "netif_tx_stop called\n"); 1965 wil_dbg_txrx(wil, "netif_tx_stop called\n");
1929 } 1966 }
1930 return; 1967 return;
@@ -1940,7 +1977,8 @@ static inline void __wil_update_net_queues(struct wil6210_priv *wil,
1940 struct vring *cur_vring = &wil->vring_tx[i]; 1977 struct vring *cur_vring = &wil->vring_tx[i];
1941 struct vring_tx_data *txdata = &wil->vring_tx_data[i]; 1978 struct vring_tx_data *txdata = &wil->vring_tx_data[i];
1942 1979
1943 if (!cur_vring->va || !txdata->enabled || cur_vring == vring) 1980 if (txdata->mid != vif->mid || !cur_vring->va ||
1981 !txdata->enabled || cur_vring == vring)
1944 continue; 1982 continue;
1945 1983
1946 if (wil_vring_avail_low(cur_vring)) { 1984 if (wil_vring_avail_low(cur_vring)) {
@@ -1953,30 +1991,31 @@ static inline void __wil_update_net_queues(struct wil6210_priv *wil,
1953 if (!vring || wil_vring_avail_high(vring)) { 1991 if (!vring || wil_vring_avail_high(vring)) {
1954 /* enough room in the vring */ 1992 /* enough room in the vring */
1955 wil_dbg_txrx(wil, "calling netif_tx_wake\n"); 1993 wil_dbg_txrx(wil, "calling netif_tx_wake\n");
1956 netif_tx_wake_all_queues(wil_to_ndev(wil)); 1994 netif_tx_wake_all_queues(vif_to_ndev(vif));
1957 wil->net_queue_stopped = false; 1995 vif->net_queue_stopped = false;
1958 } 1996 }
1959} 1997}
1960 1998
1961void wil_update_net_queues(struct wil6210_priv *wil, struct vring *vring, 1999void wil_update_net_queues(struct wil6210_priv *wil, struct wil6210_vif *vif,
1962 bool check_stop) 2000 struct vring *vring, bool check_stop)
1963{ 2001{
1964 spin_lock(&wil->net_queue_lock); 2002 spin_lock(&wil->net_queue_lock);
1965 __wil_update_net_queues(wil, vring, check_stop); 2003 __wil_update_net_queues(wil, vif, vring, check_stop);
1966 spin_unlock(&wil->net_queue_lock); 2004 spin_unlock(&wil->net_queue_lock);
1967} 2005}
1968 2006
1969void wil_update_net_queues_bh(struct wil6210_priv *wil, struct vring *vring, 2007void wil_update_net_queues_bh(struct wil6210_priv *wil, struct wil6210_vif *vif,
1970 bool check_stop) 2008 struct vring *vring, bool check_stop)
1971{ 2009{
1972 spin_lock_bh(&wil->net_queue_lock); 2010 spin_lock_bh(&wil->net_queue_lock);
1973 __wil_update_net_queues(wil, vring, check_stop); 2011 __wil_update_net_queues(wil, vif, vring, check_stop);
1974 spin_unlock_bh(&wil->net_queue_lock); 2012 spin_unlock_bh(&wil->net_queue_lock);
1975} 2013}
1976 2014
1977netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) 2015netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1978{ 2016{
1979 struct wil6210_priv *wil = ndev_to_wil(ndev); 2017 struct wil6210_vif *vif = ndev_to_vif(ndev);
2018 struct wil6210_priv *wil = vif_to_wil(vif);
1980 struct ethhdr *eth = (void *)skb->data; 2019 struct ethhdr *eth = (void *)skb->data;
1981 bool bcast = is_multicast_ether_addr(eth->h_dest); 2020 bool bcast = is_multicast_ether_addr(eth->h_dest);
1982 struct vring *vring; 2021 struct vring *vring;
@@ -1991,49 +2030,50 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1991 } 2030 }
1992 goto drop; 2031 goto drop;
1993 } 2032 }
1994 if (unlikely(!test_bit(wil_status_fwconnected, wil->status))) { 2033 if (unlikely(!test_bit(wil_vif_fwconnected, vif->status))) {
1995 wil_dbg_ratelimited(wil, "FW not connected, packet dropped\n"); 2034 wil_dbg_ratelimited(wil,
2035 "VIF not connected, packet dropped\n");
1996 goto drop; 2036 goto drop;
1997 } 2037 }
1998 if (unlikely(wil->wdev->iftype == NL80211_IFTYPE_MONITOR)) { 2038 if (unlikely(vif->wdev.iftype == NL80211_IFTYPE_MONITOR)) {
1999 wil_err(wil, "Xmit in monitor mode not supported\n"); 2039 wil_err(wil, "Xmit in monitor mode not supported\n");
2000 goto drop; 2040 goto drop;
2001 } 2041 }
2002 pr_once_fw = false; 2042 pr_once_fw = false;
2003 2043
2004 /* find vring */ 2044 /* find vring */
2005 if (wil->wdev->iftype == NL80211_IFTYPE_STATION && !wil->pbss) { 2045 if (vif->wdev.iftype == NL80211_IFTYPE_STATION && !vif->pbss) {
2006 /* in STA mode (ESS), all to same VRING (to AP) */ 2046 /* in STA mode (ESS), all to same VRING (to AP) */
2007 vring = wil_find_tx_vring_sta(wil, skb); 2047 vring = wil_find_tx_vring_sta(wil, vif, skb);
2008 } else if (bcast) { 2048 } else if (bcast) {
2009 if (wil->pbss) 2049 if (vif->pbss)
2010 /* in pbss, no bcast VRING - duplicate skb in 2050 /* in pbss, no bcast VRING - duplicate skb in
2011 * all stations VRINGs 2051 * all stations VRINGs
2012 */ 2052 */
2013 vring = wil_find_tx_bcast_2(wil, skb); 2053 vring = wil_find_tx_bcast_2(wil, vif, skb);
2014 else if (wil->wdev->iftype == NL80211_IFTYPE_AP) 2054 else if (vif->wdev.iftype == NL80211_IFTYPE_AP)
2015 /* AP has a dedicated bcast VRING */ 2055 /* AP has a dedicated bcast VRING */
2016 vring = wil_find_tx_bcast_1(wil, skb); 2056 vring = wil_find_tx_bcast_1(wil, vif, skb);
2017 else 2057 else
2018 /* unexpected combination, fallback to duplicating 2058 /* unexpected combination, fallback to duplicating
2019 * the skb in all stations VRINGs 2059 * the skb in all stations VRINGs
2020 */ 2060 */
2021 vring = wil_find_tx_bcast_2(wil, skb); 2061 vring = wil_find_tx_bcast_2(wil, vif, skb);
2022 } else { 2062 } else {
2023 /* unicast, find specific VRING by dest. address */ 2063 /* unicast, find specific VRING by dest. address */
2024 vring = wil_find_tx_ucast(wil, skb); 2064 vring = wil_find_tx_ucast(wil, vif, skb);
2025 } 2065 }
2026 if (unlikely(!vring)) { 2066 if (unlikely(!vring)) {
2027 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest); 2067 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest);
2028 goto drop; 2068 goto drop;
2029 } 2069 }
2030 /* set up vring entry */ 2070 /* set up vring entry */
2031 rc = wil_tx_vring(wil, vring, skb); 2071 rc = wil_tx_vring(wil, vif, vring, skb);
2032 2072
2033 switch (rc) { 2073 switch (rc) {
2034 case 0: 2074 case 0:
2035 /* shall we stop net queues? */ 2075 /* shall we stop net queues? */
2036 wil_update_net_queues_bh(wil, vring, true); 2076 wil_update_net_queues_bh(wil, vif, vring, true);
2037 /* statistics will be updated on the tx_complete */ 2077 /* statistics will be updated on the tx_complete */
2038 dev_kfree_skb_any(skb); 2078 dev_kfree_skb_any(skb);
2039 return NETDEV_TX_OK; 2079 return NETDEV_TX_OK;
@@ -2072,9 +2112,10 @@ static inline void wil_consume_skb(struct sk_buff *skb, bool acked)
2072 * 2112 *
2073 * Safe to call from IRQ 2113 * Safe to call from IRQ
2074 */ 2114 */
2075int wil_tx_complete(struct wil6210_priv *wil, int ringid) 2115int wil_tx_complete(struct wil6210_vif *vif, int ringid)
2076{ 2116{
2077 struct net_device *ndev = wil_to_ndev(wil); 2117 struct wil6210_priv *wil = vif_to_wil(vif);
2118 struct net_device *ndev = vif_to_ndev(vif);
2078 struct device *dev = wil_to_dev(wil); 2119 struct device *dev = wil_to_dev(wil);
2079 struct vring *vring = &wil->vring_tx[ringid]; 2120 struct vring *vring = &wil->vring_tx[ringid];
2080 struct vring_tx_data *txdata = &wil->vring_tx_data[ringid]; 2121 struct vring_tx_data *txdata = &wil->vring_tx_data[ringid];
@@ -2184,7 +2225,7 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
2184 2225
2185 /* shall we wake net queues? */ 2226 /* shall we wake net queues? */
2186 if (done) 2227 if (done)
2187 wil_update_net_queues(wil, vring, false); 2228 wil_update_net_queues(wil, vif, vring, false);
2188 2229
2189 return done; 2230 return done;
2190} 2231}
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
index fcdffaa8251b..5f07717acc2c 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/drivers/net/wireless/ath/wil6210/txrx.h
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2012-2016 Qualcomm Atheros, Inc. 2 * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
3 * 4 *
4 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
@@ -63,7 +64,9 @@ static inline void wil_desc_addr_set(struct vring_dma_addr *addr,
63 * [dword 1] 64 * [dword 1]
64 * bit 0.. 3 : pkt_mode:4 65 * bit 0.. 3 : pkt_mode:4
65 * bit 4 : pkt_mode_en:1 66 * bit 4 : pkt_mode_en:1
66 * bit 5..14 : reserved0:10 67 * bit 5 : mac_id_en:1
68 * bit 6..7 : mac_id:2
69 * bit 8..14 : reserved0:7
67 * bit 15 : ack_policy_en:1 70 * bit 15 : ack_policy_en:1
68 * bit 16..19 : dst_index:4 71 * bit 16..19 : dst_index:4
69 * bit 20 : dst_index_en:1 72 * bit 20 : dst_index_en:1
@@ -132,6 +135,14 @@ struct vring_tx_mac {
132#define MAC_CFG_DESC_TX_1_PKT_MODE_EN_LEN 1 135#define MAC_CFG_DESC_TX_1_PKT_MODE_EN_LEN 1
133#define MAC_CFG_DESC_TX_1_PKT_MODE_EN_MSK 0x10 136#define MAC_CFG_DESC_TX_1_PKT_MODE_EN_MSK 0x10
134 137
138#define MAC_CFG_DESC_TX_1_MAC_ID_EN_POS 5
139#define MAC_CFG_DESC_TX_1_MAC_ID_EN_LEN 1
140#define MAC_CFG_DESC_TX_1_MAC_ID_EN_MSK 0x20
141
142#define MAC_CFG_DESC_TX_1_MAC_ID_POS 6
143#define MAC_CFG_DESC_TX_1_MAC_ID_LEN 2
144#define MAC_CFG_DESC_TX_1_MAC_ID_MSK 0xc0
145
135#define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_POS 15 146#define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_POS 15
136#define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_LEN 1 147#define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_LEN 1
137#define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_MSK 0x8000 148#define MAC_CFG_DESC_TX_1_ACK_POLICY_EN_MSK 0x8000
@@ -304,7 +315,7 @@ enum {
304 * bit 0.. 3 : tid:4 The QoS (b3-0) TID Field 315 * bit 0.. 3 : tid:4 The QoS (b3-0) TID Field
305 * bit 4.. 6 : cid:3 The Source index that was found during parsing the TA. 316 * bit 4.. 6 : cid:3 The Source index that was found during parsing the TA.
306 * This field is used to define the source of the packet 317 * This field is used to define the source of the packet
307 * bit 7 : reserved:1 318 * bit 7 : MAC_id_valid:1, 1 if MAC virtual number is valid.
308 * bit 8.. 9 : mid:2 The MAC virtual number 319 * bit 8.. 9 : mid:2 The MAC virtual number
309 * bit 10..11 : frame_type:2 : The FC (b3-2) - MPDU Type 320 * bit 10..11 : frame_type:2 : The FC (b3-2) - MPDU Type
310 * (management, data, control and extension) 321 * (management, data, control and extension)
@@ -395,6 +406,7 @@ struct vring_rx_mac {
395#define RX_DMA_D0_CMD_DMA_EOP BIT(8) 406#define RX_DMA_D0_CMD_DMA_EOP BIT(8)
396#define RX_DMA_D0_CMD_DMA_RT BIT(9) /* always 1 */ 407#define RX_DMA_D0_CMD_DMA_RT BIT(9) /* always 1 */
397#define RX_DMA_D0_CMD_DMA_IT BIT(10) /* interrupt */ 408#define RX_DMA_D0_CMD_DMA_IT BIT(10) /* interrupt */
409#define RX_MAC_D0_MAC_ID_VALID BIT(7)
398 410
399/* Error field */ 411/* Error field */
400#define RX_DMA_ERROR_FCS BIT(0) 412#define RX_DMA_ERROR_FCS BIT(0)
@@ -451,7 +463,8 @@ static inline int wil_rxdesc_cid(struct vring_rx_desc *d)
451 463
452static inline int wil_rxdesc_mid(struct vring_rx_desc *d) 464static inline int wil_rxdesc_mid(struct vring_rx_desc *d)
453{ 465{
454 return WIL_GET_BITS(d->mac.d0, 8, 9); 466 return (d->mac.d0 & RX_MAC_D0_MAC_ID_VALID) ?
467 WIL_GET_BITS(d->mac.d0, 8, 9) : 0;
455} 468}
456 469
457static inline int wil_rxdesc_ftype(struct vring_rx_desc *d) 470static inline int wil_rxdesc_ftype(struct vring_rx_desc *d)
@@ -517,7 +530,8 @@ static inline struct vring_rx_desc *wil_skb_rxdesc(struct sk_buff *skb)
517 530
518void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev); 531void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev);
519void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb); 532void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb);
520void wil_rx_bar(struct wil6210_priv *wil, u8 cid, u8 tid, u16 seq); 533void wil_rx_bar(struct wil6210_priv *wil, struct wil6210_vif *vif,
534 u8 cid, u8 tid, u16 seq);
521struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil, 535struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
522 int size, u16 ssn); 536 int size, u16 ssn);
523void wil_tid_ampdu_rx_free(struct wil6210_priv *wil, 537void wil_tid_ampdu_rx_free(struct wil6210_priv *wil,
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 0df2aada6659..f9c5155025bc 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -26,6 +26,7 @@
26#include <linux/types.h> 26#include <linux/types.h>
27#include "wmi.h" 27#include "wmi.h"
28#include "wil_platform.h" 28#include "wil_platform.h"
29#include "fw.h"
29 30
30extern bool no_fw_recovery; 31extern bool no_fw_recovery;
31extern unsigned int mtu_max; 32extern unsigned int mtu_max;
@@ -49,6 +50,11 @@ extern bool disable_ap_sme;
49#define WIL_DEFAULT_BUS_REQUEST_KBPS 128000 /* ~1Gbps */ 50#define WIL_DEFAULT_BUS_REQUEST_KBPS 128000 /* ~1Gbps */
50#define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */ 51#define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */
51 52
53/* maximum number of virtual interfaces the driver supports
54 * (including the main interface)
55 */
56#define WIL_MAX_VIFS 4
57
52/** 58/**
53 * extract bits [@b0:@b1] (inclusive) from the value @x 59 * extract bits [@b0:@b1] (inclusive) from the value @x
54 * it should be @b0 <= @b1, or result is incorrect 60 * it should be @b0 <= @b1, or result is incorrect
@@ -463,13 +469,12 @@ struct vring_tx_data {
463 u16 agg_timeout; 469 u16 agg_timeout;
464 u8 agg_amsdu; 470 u8 agg_amsdu;
465 bool addba_in_progress; /* if set, agg_xxx is for request in progress */ 471 bool addba_in_progress; /* if set, agg_xxx is for request in progress */
472 u8 mid;
466 spinlock_t lock; 473 spinlock_t lock;
467}; 474};
468 475
469enum { /* for wil6210_priv.status */ 476enum { /* for wil6210_priv.status */
470 wil_status_fwready = 0, /* FW operational */ 477 wil_status_fwready = 0, /* FW operational */
471 wil_status_fwconnecting,
472 wil_status_fwconnected,
473 wil_status_dontscan, 478 wil_status_dontscan,
474 wil_status_mbox_ready, /* MBOX structures ready */ 479 wil_status_mbox_ready, /* MBOX structures ready */
475 wil_status_irqen, /* interrupts enabled - for debug */ 480 wil_status_irqen, /* interrupts enabled - for debug */
@@ -541,7 +546,6 @@ struct wil_tid_crypto_rx {
541struct wil_p2p_info { 546struct wil_p2p_info {
542 struct ieee80211_channel listen_chan; 547 struct ieee80211_channel listen_chan;
543 u8 discovery_started; 548 u8 discovery_started;
544 u8 p2p_dev_started;
545 u64 cookie; 549 u64 cookie;
546 struct wireless_dev *pending_listen_wdev; 550 struct wireless_dev *pending_listen_wdev;
547 unsigned int listen_duration; 551 unsigned int listen_duration;
@@ -584,6 +588,7 @@ struct wil_net_stats {
584 */ 588 */
585struct wil_sta_info { 589struct wil_sta_info {
586 u8 addr[ETH_ALEN]; 590 u8 addr[ETH_ALEN];
591 u8 mid;
587 enum wil_sta_status status; 592 enum wil_sta_status status;
588 struct wil_net_stats stats; 593 struct wil_net_stats stats;
589 /* Rx BACK */ 594 /* Rx BACK */
@@ -669,10 +674,44 @@ extern struct blink_on_off_time led_blink_time[WIL_LED_TIME_LAST];
669extern u8 led_id; 674extern u8 led_id;
670extern u8 led_polarity; 675extern u8 led_polarity;
671 676
677enum wil6210_vif_status {
678 wil_vif_fwconnecting,
679 wil_vif_fwconnected,
680 wil_vif_status_last /* keep last */
681};
682
683struct wil6210_vif {
684 struct wireless_dev wdev;
685 struct net_device *ndev;
686 struct wil6210_priv *wil;
687 u8 mid;
688 DECLARE_BITMAP(status, wil_vif_status_last);
689 u32 privacy; /* secure connection? */
690 u16 channel; /* relevant in AP mode */
691 u8 hidden_ssid; /* relevant in AP mode */
692 u32 ap_isolate; /* no intra-BSS communication */
693 bool pbss;
694 int bcast_vring;
695 struct cfg80211_bss *bss; /* connected bss, relevant in STA mode */
696 int locally_generated_disc; /* relevant in STA mode */
697 struct timer_list connect_timer;
698 struct work_struct disconnect_worker;
699 /* scan */
700 struct cfg80211_scan_request *scan_request;
701 struct timer_list scan_timer; /* detect scan timeout */
702 struct wil_p2p_info p2p;
703 /* keep alive */
704 struct list_head probe_client_pending;
705 struct mutex probe_client_mutex; /* protect @probe_client_pending */
706 struct work_struct probe_client_worker;
707 int net_queue_stopped; /* netif_tx_stop_all_queues invoked */
708};
709
672struct wil6210_priv { 710struct wil6210_priv {
673 struct pci_dev *pdev; 711 struct pci_dev *pdev;
674 u32 bar_size; 712 u32 bar_size;
675 struct wireless_dev *wdev; 713 struct wiphy *wiphy;
714 struct net_device *main_ndev;
676 void __iomem *csr; 715 void __iomem *csr;
677 DECLARE_BITMAP(status, wil_status_last); 716 DECLARE_BITMAP(status, wil_status_last);
678 u8 fw_version[ETHTOOL_FWVERS_LEN]; 717 u8 fw_version[ETHTOOL_FWVERS_LEN];
@@ -686,21 +725,18 @@ struct wil6210_priv {
686 DECLARE_BITMAP(hw_capa, hw_capa_last); 725 DECLARE_BITMAP(hw_capa, hw_capa_last);
687 DECLARE_BITMAP(fw_capabilities, WMI_FW_CAPABILITY_MAX); 726 DECLARE_BITMAP(fw_capabilities, WMI_FW_CAPABILITY_MAX);
688 DECLARE_BITMAP(platform_capa, WIL_PLATFORM_CAPA_MAX); 727 DECLARE_BITMAP(platform_capa, WIL_PLATFORM_CAPA_MAX);
689 u8 n_mids; /* number of additional MIDs as reported by FW */
690 u32 recovery_count; /* num of FW recovery attempts in a short time */ 728 u32 recovery_count; /* num of FW recovery attempts in a short time */
691 u32 recovery_state; /* FW recovery state machine */ 729 u32 recovery_state; /* FW recovery state machine */
692 unsigned long last_fw_recovery; /* jiffies of last fw recovery */ 730 unsigned long last_fw_recovery; /* jiffies of last fw recovery */
693 wait_queue_head_t wq; /* for all wait_event() use */ 731 wait_queue_head_t wq; /* for all wait_event() use */
732 u8 max_vifs; /* maximum number of interfaces, including main */
733 struct wil6210_vif *vifs[WIL_MAX_VIFS];
734 struct mutex vif_mutex; /* protects access to VIF entries */
735 atomic_t connected_vifs;
694 /* profile */ 736 /* profile */
695 struct cfg80211_chan_def monitor_chandef; 737 struct cfg80211_chan_def monitor_chandef;
696 u32 monitor_flags; 738 u32 monitor_flags;
697 u32 privacy; /* secure connection? */
698 u8 hidden_ssid; /* relevant in AP mode */
699 u16 channel; /* relevant in AP mode */
700 int sinfo_gen; 739 int sinfo_gen;
701 u32 ap_isolate; /* no intra-BSS communication */
702 struct cfg80211_bss *bss; /* connected bss, relevant in STA mode */
703 int locally_generated_disc; /* relevant in STA mode */
704 /* interrupt moderation */ 740 /* interrupt moderation */
705 u32 tx_max_burst_duration; 741 u32 tx_max_burst_duration;
706 u32 tx_interframe_timeout; 742 u32 tx_interframe_timeout;
@@ -715,15 +751,13 @@ struct wil6210_priv {
715 struct completion wmi_call; 751 struct completion wmi_call;
716 u16 wmi_seq; 752 u16 wmi_seq;
717 u16 reply_id; /**< wait for this WMI event */ 753 u16 reply_id; /**< wait for this WMI event */
754 u8 reply_mid;
718 void *reply_buf; 755 void *reply_buf;
719 u16 reply_size; 756 u16 reply_size;
720 struct workqueue_struct *wmi_wq; /* for deferred calls */ 757 struct workqueue_struct *wmi_wq; /* for deferred calls */
721 struct work_struct wmi_event_worker; 758 struct work_struct wmi_event_worker;
722 struct workqueue_struct *wq_service; 759 struct workqueue_struct *wq_service;
723 struct work_struct disconnect_worker;
724 struct work_struct fw_error_worker; /* for FW error recovery */ 760 struct work_struct fw_error_worker; /* for FW error recovery */
725 struct timer_list connect_timer;
726 struct timer_list scan_timer; /* detect scan timeout */
727 struct list_head pending_wmi_ev; 761 struct list_head pending_wmi_ev;
728 /* 762 /*
729 * protect pending_wmi_ev 763 * protect pending_wmi_ev
@@ -732,13 +766,10 @@ struct wil6210_priv {
732 */ 766 */
733 spinlock_t wmi_ev_lock; 767 spinlock_t wmi_ev_lock;
734 spinlock_t net_queue_lock; /* guarding stop/wake netif queue */ 768 spinlock_t net_queue_lock; /* guarding stop/wake netif queue */
735 int net_queue_stopped; /* netif_tx_stop_all_queues invoked */
736 struct napi_struct napi_rx; 769 struct napi_struct napi_rx;
737 struct napi_struct napi_tx; 770 struct napi_struct napi_tx;
738 /* keep alive */ 771 struct net_device napi_ndev; /* dummy net_device serving all VIFs */
739 struct list_head probe_client_pending; 772
740 struct mutex probe_client_mutex; /* protect @probe_client_pending */
741 struct work_struct probe_client_worker;
742 /* DMA related */ 773 /* DMA related */
743 struct vring vring_rx; 774 struct vring vring_rx;
744 unsigned int rx_buf_len; 775 unsigned int rx_buf_len;
@@ -746,11 +777,8 @@ struct wil6210_priv {
746 struct vring_tx_data vring_tx_data[WIL6210_MAX_TX_RINGS]; 777 struct vring_tx_data vring_tx_data[WIL6210_MAX_TX_RINGS];
747 u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */ 778 u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */
748 struct wil_sta_info sta[WIL6210_MAX_CID]; 779 struct wil_sta_info sta[WIL6210_MAX_CID];
749 int bcast_vring;
750 u32 vring_idle_trsh; /* HW fetches up to 16 descriptors at once */ 780 u32 vring_idle_trsh; /* HW fetches up to 16 descriptors at once */
751 u32 dma_addr_size; /* indicates dma addr size */ 781 u32 dma_addr_size; /* indicates dma addr size */
752 /* scan */
753 struct cfg80211_scan_request *scan_request;
754 782
755 struct mutex mutex; /* for wil6210_priv access in wil_{up|down} */ 783 struct mutex mutex; /* for wil6210_priv access in wil_{up|down} */
756 /* statistics */ 784 /* statistics */
@@ -770,13 +798,10 @@ struct wil6210_priv {
770 798
771 struct pmc_ctx pmc; 799 struct pmc_ctx pmc;
772 800
773 bool pbss; 801 u8 p2p_dev_started;
774
775 struct wil_p2p_info p2p;
776 802
777 /* P2P_DEVICE vif */ 803 /* P2P_DEVICE vif */
778 struct wireless_dev *p2p_wdev; 804 struct wireless_dev *p2p_wdev;
779 struct mutex p2p_wdev_mutex; /* protect @p2p_wdev and @scan_request */
780 struct wireless_dev *radio_wdev; 805 struct wireless_dev *radio_wdev;
781 806
782 /* High Access Latency Policy voting */ 807 /* High Access Latency Policy voting */
@@ -798,13 +823,35 @@ struct wil6210_priv {
798 u32 iccm_base; 823 u32 iccm_base;
799}; 824};
800 825
801#define wil_to_wiphy(i) (i->wdev->wiphy) 826#define wil_to_wiphy(i) (i->wiphy)
802#define wil_to_dev(i) (wiphy_dev(wil_to_wiphy(i))) 827#define wil_to_dev(i) (wiphy_dev(wil_to_wiphy(i)))
803#define wiphy_to_wil(w) (struct wil6210_priv *)(wiphy_priv(w)) 828#define wiphy_to_wil(w) (struct wil6210_priv *)(wiphy_priv(w))
804#define wil_to_wdev(i) (i->wdev)
805#define wdev_to_wil(w) (struct wil6210_priv *)(wdev_priv(w)) 829#define wdev_to_wil(w) (struct wil6210_priv *)(wdev_priv(w))
806#define wil_to_ndev(i) (wil_to_wdev(i)->netdev)
807#define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr)) 830#define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr))
831#define ndev_to_vif(n) (struct wil6210_vif *)(netdev_priv(n))
832#define vif_to_wil(v) (v->wil)
833#define vif_to_ndev(v) (v->ndev)
834#define vif_to_wdev(v) (&v->wdev)
835
836static inline struct wil6210_vif *wdev_to_vif(struct wil6210_priv *wil,
837 struct wireless_dev *wdev)
838{
839 /* main interface is shared with P2P device */
840 if (wdev == wil->p2p_wdev)
841 return ndev_to_vif(wil->main_ndev);
842 else
843 return container_of(wdev, struct wil6210_vif, wdev);
844}
845
846static inline struct wireless_dev *
847vif_to_radio_wdev(struct wil6210_priv *wil, struct wil6210_vif *vif)
848{
849 /* main interface is shared with P2P device */
850 if (vif->mid)
851 return vif_to_wdev(vif);
852 else
853 return wil->radio_wdev;
854}
808 855
809__printf(2, 3) 856__printf(2, 3)
810void wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...); 857void wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...);
@@ -817,7 +864,7 @@ void __wil_info(struct wil6210_priv *wil, const char *fmt, ...);
817__printf(2, 3) 864__printf(2, 3)
818void wil_dbg_ratelimited(const struct wil6210_priv *wil, const char *fmt, ...); 865void wil_dbg_ratelimited(const struct wil6210_priv *wil, const char *fmt, ...);
819#define wil_dbg(wil, fmt, arg...) do { \ 866#define wil_dbg(wil, fmt, arg...) do { \
820 netdev_dbg(wil_to_ndev(wil), fmt, ##arg); \ 867 netdev_dbg(wil->main_ndev, fmt, ##arg); \
821 wil_dbg_trace(wil, fmt, ##arg); \ 868 wil_dbg_trace(wil, fmt, ##arg); \
822} while (0) 869} while (0)
823 870
@@ -900,9 +947,18 @@ void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src,
900void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src, 947void wil_memcpy_toio_32(volatile void __iomem *dst, const void *src,
901 size_t count); 948 size_t count);
902 949
950struct wil6210_vif *
951wil_vif_alloc(struct wil6210_priv *wil, const char *name,
952 unsigned char name_assign_type, enum nl80211_iftype iftype);
953void wil_vif_free(struct wil6210_vif *vif);
903void *wil_if_alloc(struct device *dev); 954void *wil_if_alloc(struct device *dev);
955bool wil_has_other_active_ifaces(struct wil6210_priv *wil,
956 struct net_device *ndev, bool up, bool ok);
957bool wil_has_active_ifaces(struct wil6210_priv *wil, bool up, bool ok);
904void wil_if_free(struct wil6210_priv *wil); 958void wil_if_free(struct wil6210_priv *wil);
959int wil_vif_add(struct wil6210_priv *wil, struct wil6210_vif *vif);
905int wil_if_add(struct wil6210_priv *wil); 960int wil_if_add(struct wil6210_priv *wil);
961void wil_vif_remove(struct wil6210_priv *wil, u8 mid);
906void wil_if_remove(struct wil6210_priv *wil); 962void wil_if_remove(struct wil6210_priv *wil);
907int wil_priv_init(struct wil6210_priv *wil); 963int wil_priv_init(struct wil6210_priv *wil);
908void wil_priv_deinit(struct wil6210_priv *wil); 964void wil_priv_deinit(struct wil6210_priv *wil);
@@ -918,7 +974,7 @@ int wil_down(struct wil6210_priv *wil);
918int __wil_down(struct wil6210_priv *wil); 974int __wil_down(struct wil6210_priv *wil);
919void wil_refresh_fw_capabilities(struct wil6210_priv *wil); 975void wil_refresh_fw_capabilities(struct wil6210_priv *wil);
920void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r); 976void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r);
921int wil_find_cid(struct wil6210_priv *wil, const u8 *mac); 977int wil_find_cid(struct wil6210_priv *wil, u8 mid, const u8 *mac);
922void wil_set_ethtoolops(struct net_device *ndev); 978void wil_set_ethtoolops(struct net_device *ndev);
923 979
924struct fw_map *wil_find_fw_mapping(const char *section); 980struct fw_map *wil_find_fw_mapping(const char *section);
@@ -927,40 +983,45 @@ void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr);
927void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr); 983void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr);
928int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr, 984int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr,
929 struct wil6210_mbox_hdr *hdr); 985 struct wil6210_mbox_hdr *hdr);
930int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len); 986int wmi_send(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len);
931void wmi_recv_cmd(struct wil6210_priv *wil); 987void wmi_recv_cmd(struct wil6210_priv *wil);
932int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, 988int wmi_call(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len,
933 u16 reply_id, void *reply, u8 reply_size, int to_msec); 989 u16 reply_id, void *reply, u8 reply_size, int to_msec);
934void wmi_event_worker(struct work_struct *work); 990void wmi_event_worker(struct work_struct *work);
935void wmi_event_flush(struct wil6210_priv *wil); 991void wmi_event_flush(struct wil6210_priv *wil);
936int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid); 992int wmi_set_ssid(struct wil6210_vif *vif, u8 ssid_len, const void *ssid);
937int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid); 993int wmi_get_ssid(struct wil6210_vif *vif, u8 *ssid_len, void *ssid);
938int wmi_set_channel(struct wil6210_priv *wil, int channel); 994int wmi_set_channel(struct wil6210_priv *wil, int channel);
939int wmi_get_channel(struct wil6210_priv *wil, int *channel); 995int wmi_get_channel(struct wil6210_priv *wil, int *channel);
940int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index, 996int wmi_del_cipher_key(struct wil6210_vif *vif, u8 key_index,
941 const void *mac_addr, int key_usage); 997 const void *mac_addr, int key_usage);
942int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index, 998int wmi_add_cipher_key(struct wil6210_vif *vif, u8 key_index,
943 const void *mac_addr, int key_len, const void *key, 999 const void *mac_addr, int key_len, const void *key,
944 int key_usage); 1000 int key_usage);
945int wmi_echo(struct wil6210_priv *wil); 1001int wmi_echo(struct wil6210_priv *wil);
946int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie); 1002int wmi_set_ie(struct wil6210_vif *vif, u8 type, u16 ie_len, const void *ie);
947int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring); 1003int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring);
948int wmi_rxon(struct wil6210_priv *wil, bool on); 1004int wmi_rxon(struct wil6210_priv *wil, bool on);
949int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r); 1005int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r);
950int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, 1006int wmi_disconnect_sta(struct wil6210_vif *vif, const u8 *mac,
951 u16 reason, bool full_disconnect, bool del_sta); 1007 u16 reason, bool full_disconnect, bool del_sta);
952int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout); 1008int wmi_addba(struct wil6210_priv *wil, u8 mid,
953int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason); 1009 u8 ringid, u8 size, u16 timeout);
954int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason); 1010int wmi_delba_tx(struct wil6210_priv *wil, u8 mid, u8 ringid, u16 reason);
955int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token, 1011int wmi_delba_rx(struct wil6210_priv *wil, u8 mid, u8 cidxtid, u16 reason);
1012int wmi_addba_rx_resp(struct wil6210_priv *wil,
1013 u8 mid, u8 cid, u8 tid, u8 token,
956 u16 status, bool amsdu, u16 agg_wsize, u16 timeout); 1014 u16 status, bool amsdu, u16 agg_wsize, u16 timeout);
957int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil, 1015int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil,
958 enum wmi_ps_profile_type ps_profile); 1016 enum wmi_ps_profile_type ps_profile);
959int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short); 1017int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short);
960int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short); 1018int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short);
961int wmi_new_sta(struct wil6210_priv *wil, const u8 *mac, u8 aid); 1019int wmi_new_sta(struct wil6210_vif *vif, const u8 *mac, u8 aid);
962int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid, 1020int wmi_port_allocate(struct wil6210_priv *wil, u8 mid,
963 u8 dialog_token, __le16 ba_param_set, 1021 const u8 *mac, enum nl80211_iftype iftype);
1022int wmi_port_delete(struct wil6210_priv *wil, u8 mid);
1023int wil_addba_rx_request(struct wil6210_priv *wil, u8 mid,
1024 u8 cidxtid, u8 dialog_token, __le16 ba_param_set,
964 __le16 ba_timeout, __le16 ba_seq_ctrl); 1025 __le16 ba_timeout, __le16 ba_seq_ctrl);
965int wil_addba_tx_request(struct wil6210_priv *wil, u8 ringid, u16 wsize); 1026int wil_addba_tx_request(struct wil6210_priv *wil, u8 ringid, u16 wsize);
966 1027
@@ -976,28 +1037,31 @@ void wil6210_mask_halp(struct wil6210_priv *wil);
976 1037
977/* P2P */ 1038/* P2P */
978bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request); 1039bool wil_p2p_is_social_scan(struct cfg80211_scan_request *request);
979void wil_p2p_discovery_timer_fn(struct timer_list *t); 1040int wil_p2p_search(struct wil6210_vif *vif,
980int wil_p2p_search(struct wil6210_priv *wil,
981 struct cfg80211_scan_request *request); 1041 struct cfg80211_scan_request *request);
982int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev, 1042int wil_p2p_listen(struct wil6210_priv *wil, struct wireless_dev *wdev,
983 unsigned int duration, struct ieee80211_channel *chan, 1043 unsigned int duration, struct ieee80211_channel *chan,
984 u64 *cookie); 1044 u64 *cookie);
985u8 wil_p2p_stop_discovery(struct wil6210_priv *wil); 1045u8 wil_p2p_stop_discovery(struct wil6210_vif *vif);
986int wil_p2p_cancel_listen(struct wil6210_priv *wil, u64 cookie); 1046int wil_p2p_cancel_listen(struct wil6210_vif *vif, u64 cookie);
987void wil_p2p_listen_expired(struct work_struct *work); 1047void wil_p2p_listen_expired(struct work_struct *work);
988void wil_p2p_search_expired(struct work_struct *work); 1048void wil_p2p_search_expired(struct work_struct *work);
989void wil_p2p_stop_radio_operations(struct wil6210_priv *wil); 1049void wil_p2p_stop_radio_operations(struct wil6210_priv *wil);
990void wil_p2p_delayed_listen_work(struct work_struct *work); 1050void wil_p2p_delayed_listen_work(struct work_struct *work);
991 1051
992/* WMI for P2P */ 1052/* WMI for P2P */
993int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi); 1053int wmi_p2p_cfg(struct wil6210_vif *vif, int channel, int bi);
994int wmi_start_listen(struct wil6210_priv *wil); 1054int wmi_start_listen(struct wil6210_vif *vif);
995int wmi_start_search(struct wil6210_priv *wil); 1055int wmi_start_search(struct wil6210_vif *vif);
996int wmi_stop_discovery(struct wil6210_priv *wil); 1056int wmi_stop_discovery(struct wil6210_vif *vif);
997 1057
998int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 1058int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
999 struct cfg80211_mgmt_tx_params *params, 1059 struct cfg80211_mgmt_tx_params *params,
1000 u64 *cookie); 1060 u64 *cookie);
1061int wil_cfg80211_iface_combinations_from_fw(
1062 struct wil6210_priv *wil,
1063 const struct wil_fw_record_concurrency *conc);
1064int wil_vif_prepare_stop(struct wil6210_vif *vif);
1001 1065
1002#if defined(CONFIG_WIL6210_DEBUGFS) 1066#if defined(CONFIG_WIL6210_DEBUGFS)
1003int wil6210_debugfs_init(struct wil6210_priv *wil); 1067int wil6210_debugfs_init(struct wil6210_priv *wil);
@@ -1007,44 +1071,47 @@ static inline int wil6210_debugfs_init(struct wil6210_priv *wil) { return 0; }
1007static inline void wil6210_debugfs_remove(struct wil6210_priv *wil) {} 1071static inline void wil6210_debugfs_remove(struct wil6210_priv *wil) {}
1008#endif 1072#endif
1009 1073
1010int wil_cid_fill_sinfo(struct wil6210_priv *wil, int cid, 1074int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
1011 struct station_info *sinfo); 1075 struct station_info *sinfo);
1012 1076
1013struct wireless_dev *wil_cfg80211_init(struct device *dev); 1077struct wil6210_priv *wil_cfg80211_init(struct device *dev);
1014void wil_wdev_free(struct wil6210_priv *wil); 1078void wil_cfg80211_deinit(struct wil6210_priv *wil);
1015void wil_p2p_wdev_free(struct wil6210_priv *wil); 1079void wil_p2p_wdev_free(struct wil6210_priv *wil);
1016 1080
1017int wmi_set_mac_address(struct wil6210_priv *wil, void *addr); 1081int wmi_set_mac_address(struct wil6210_priv *wil, void *addr);
1018int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, 1082int wmi_pcp_start(struct wil6210_vif *vif, int bi, u8 wmi_nettype, u8 chan,
1019 u8 chan, u8 hidden_ssid, u8 is_go); 1083 u8 hidden_ssid, u8 is_go);
1020int wmi_pcp_stop(struct wil6210_priv *wil); 1084int wmi_pcp_stop(struct wil6210_vif *vif);
1021int wmi_led_cfg(struct wil6210_priv *wil, bool enable); 1085int wmi_led_cfg(struct wil6210_priv *wil, bool enable);
1022int wmi_abort_scan(struct wil6210_priv *wil); 1086int wmi_abort_scan(struct wil6210_vif *vif);
1023void wil_abort_scan(struct wil6210_priv *wil, bool sync); 1087void wil_abort_scan(struct wil6210_vif *vif, bool sync);
1088void wil_abort_scan_all_vifs(struct wil6210_priv *wil, bool sync);
1024void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps); 1089void wil6210_bus_request(struct wil6210_priv *wil, u32 kbps);
1025void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid, 1090void wil6210_disconnect(struct wil6210_vif *vif, const u8 *bssid,
1026 u16 reason_code, bool from_event); 1091 u16 reason_code, bool from_event);
1027void wil_probe_client_flush(struct wil6210_priv *wil); 1092void wil_probe_client_flush(struct wil6210_vif *vif);
1028void wil_probe_client_worker(struct work_struct *work); 1093void wil_probe_client_worker(struct work_struct *work);
1094void wil_disconnect_worker(struct work_struct *work);
1029 1095
1030int wil_rx_init(struct wil6210_priv *wil, u16 size); 1096int wil_rx_init(struct wil6210_priv *wil, u16 size);
1031void wil_rx_fini(struct wil6210_priv *wil); 1097void wil_rx_fini(struct wil6210_priv *wil);
1032 1098
1033/* TX API */ 1099/* TX API */
1034int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, 1100int wil_vring_init_tx(struct wil6210_vif *vif, int id, int size,
1035 int cid, int tid); 1101 int cid, int tid);
1036void wil_vring_fini_tx(struct wil6210_priv *wil, int id); 1102void wil_vring_fini_tx(struct wil6210_priv *wil, int id);
1037int wil_tx_init(struct wil6210_priv *wil, int cid); 1103int wil_tx_init(struct wil6210_vif *vif, int cid);
1038int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size); 1104int wil_vring_init_bcast(struct wil6210_vif *vif, int id, int size);
1039int wil_bcast_init(struct wil6210_priv *wil); 1105int wil_bcast_init(struct wil6210_vif *vif);
1040void wil_bcast_fini(struct wil6210_priv *wil); 1106void wil_bcast_fini(struct wil6210_vif *vif);
1041 1107void wil_bcast_fini_all(struct wil6210_priv *wil);
1042void wil_update_net_queues(struct wil6210_priv *wil, struct vring *vring, 1108
1043 bool should_stop); 1109void wil_update_net_queues(struct wil6210_priv *wil, struct wil6210_vif *vif,
1044void wil_update_net_queues_bh(struct wil6210_priv *wil, struct vring *vring, 1110 struct vring *vring, bool should_stop);
1045 bool check_stop); 1111void wil_update_net_queues_bh(struct wil6210_priv *wil, struct wil6210_vif *vif,
1112 struct vring *vring, bool check_stop);
1046netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev); 1113netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev);
1047int wil_tx_complete(struct wil6210_priv *wil, int ringid); 1114int wil_tx_complete(struct wil6210_vif *vif, int ringid);
1048void wil6210_unmask_irq_tx(struct wil6210_priv *wil); 1115void wil6210_unmask_irq_tx(struct wil6210_priv *wil);
1049 1116
1050/* RX API */ 1117/* RX API */
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index b31e2514f8c2..a3dda9a97c1f 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -341,6 +341,10 @@ static const char *cmdid2name(u16 cmdid)
341 return "WMI_GET_PCP_CHANNEL_CMD"; 341 return "WMI_GET_PCP_CHANNEL_CMD";
342 case WMI_P2P_CFG_CMDID: 342 case WMI_P2P_CFG_CMDID:
343 return "WMI_P2P_CFG_CMD"; 343 return "WMI_P2P_CFG_CMD";
344 case WMI_PORT_ALLOCATE_CMDID:
345 return "WMI_PORT_ALLOCATE_CMD";
346 case WMI_PORT_DELETE_CMDID:
347 return "WMI_PORT_DELETE_CMD";
344 case WMI_START_LISTEN_CMDID: 348 case WMI_START_LISTEN_CMDID:
345 return "WMI_START_LISTEN_CMD"; 349 return "WMI_START_LISTEN_CMD";
346 case WMI_START_SEARCH_CMDID: 350 case WMI_START_SEARCH_CMDID:
@@ -479,6 +483,10 @@ static const char *eventid2name(u16 eventid)
479 return "WMI_GET_PCP_CHANNEL_EVENT"; 483 return "WMI_GET_PCP_CHANNEL_EVENT";
480 case WMI_P2P_CFG_DONE_EVENTID: 484 case WMI_P2P_CFG_DONE_EVENTID:
481 return "WMI_P2P_CFG_DONE_EVENT"; 485 return "WMI_P2P_CFG_DONE_EVENT";
486 case WMI_PORT_ALLOCATED_EVENTID:
487 return "WMI_PORT_ALLOCATED_EVENT";
488 case WMI_PORT_DELETED_EVENTID:
489 return "WMI_PORT_DELETED_EVENT";
482 case WMI_LISTEN_STARTED_EVENTID: 490 case WMI_LISTEN_STARTED_EVENTID:
483 return "WMI_LISTEN_STARTED_EVENT"; 491 return "WMI_LISTEN_STARTED_EVENT";
484 case WMI_SEARCH_STARTED_EVENTID: 492 case WMI_SEARCH_STARTED_EVENTID:
@@ -516,7 +524,8 @@ static const char *eventid2name(u16 eventid)
516 } 524 }
517} 525}
518 526
519static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) 527static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, u8 mid,
528 void *buf, u16 len)
520{ 529{
521 struct { 530 struct {
522 struct wil6210_mbox_hdr hdr; 531 struct wil6210_mbox_hdr hdr;
@@ -528,7 +537,7 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
528 .len = cpu_to_le16(sizeof(cmd.wmi) + len), 537 .len = cpu_to_le16(sizeof(cmd.wmi) + len),
529 }, 538 },
530 .wmi = { 539 .wmi = {
531 .mid = 0, 540 .mid = mid,
532 .command_id = cpu_to_le16(cmdid), 541 .command_id = cpu_to_le16(cmdid),
533 }, 542 },
534 }; 543 };
@@ -612,8 +621,8 @@ static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
612 } 621 }
613 cmd.hdr.seq = cpu_to_le16(++wil->wmi_seq); 622 cmd.hdr.seq = cpu_to_le16(++wil->wmi_seq);
614 /* set command */ 623 /* set command */
615 wil_dbg_wmi(wil, "sending %s (0x%04x) [%d]\n", 624 wil_dbg_wmi(wil, "sending %s (0x%04x) [%d] mid %d\n",
616 cmdid2name(cmdid), cmdid, len); 625 cmdid2name(cmdid), cmdid, len, mid);
617 wil_hex_dump_wmi("Cmd ", DUMP_PREFIX_OFFSET, 16, 1, &cmd, 626 wil_hex_dump_wmi("Cmd ", DUMP_PREFIX_OFFSET, 16, 1, &cmd,
618 sizeof(cmd), true); 627 sizeof(cmd), true);
619 wil_hex_dump_wmi("cmd ", DUMP_PREFIX_OFFSET, 16, 1, buf, 628 wil_hex_dump_wmi("cmd ", DUMP_PREFIX_OFFSET, 16, 1, buf,
@@ -637,31 +646,34 @@ out:
637 return rc; 646 return rc;
638} 647}
639 648
640int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len) 649int wmi_send(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len)
641{ 650{
642 int rc; 651 int rc;
643 652
644 mutex_lock(&wil->wmi_mutex); 653 mutex_lock(&wil->wmi_mutex);
645 rc = __wmi_send(wil, cmdid, buf, len); 654 rc = __wmi_send(wil, cmdid, mid, buf, len);
646 mutex_unlock(&wil->wmi_mutex); 655 mutex_unlock(&wil->wmi_mutex);
647 656
648 return rc; 657 return rc;
649} 658}
650 659
651/*=== Event handlers ===*/ 660/*=== Event handlers ===*/
652static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len) 661static void wmi_evt_ready(struct wil6210_vif *vif, int id, void *d, int len)
653{ 662{
654 struct wireless_dev *wdev = wil->wdev; 663 struct wil6210_priv *wil = vif_to_wil(vif);
664 struct wiphy *wiphy = wil_to_wiphy(wil);
655 struct wmi_ready_event *evt = d; 665 struct wmi_ready_event *evt = d;
656 666
657 wil->n_mids = evt->numof_additional_mids;
658
659 wil_info(wil, "FW ver. %s(SW %d); MAC %pM; %d MID's\n", 667 wil_info(wil, "FW ver. %s(SW %d); MAC %pM; %d MID's\n",
660 wil->fw_version, le32_to_cpu(evt->sw_version), 668 wil->fw_version, le32_to_cpu(evt->sw_version),
661 evt->mac, wil->n_mids); 669 evt->mac, evt->numof_additional_mids);
670 if (evt->numof_additional_mids + 1 < wil->max_vifs) {
671 wil_err(wil, "FW does not support enough MIDs (need %d)",
672 wil->max_vifs - 1);
673 return; /* FW load will fail after timeout */
674 }
662 /* ignore MAC address, we already have it from the boot loader */ 675 /* ignore MAC address, we already have it from the boot loader */
663 strlcpy(wdev->wiphy->fw_version, wil->fw_version, 676 strlcpy(wiphy->fw_version, wil->fw_version, sizeof(wiphy->fw_version));
664 sizeof(wdev->wiphy->fw_version));
665 677
666 if (len > offsetof(struct wmi_ready_event, rfc_read_calib_result)) { 678 if (len > offsetof(struct wmi_ready_event, rfc_read_calib_result)) {
667 wil_dbg_wmi(wil, "rfc calibration result %d\n", 679 wil_dbg_wmi(wil, "rfc calibration result %d\n",
@@ -674,8 +686,9 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
674 complete(&wil->wmi_ready); 686 complete(&wil->wmi_ready);
675} 687}
676 688
677static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len) 689static void wmi_evt_rx_mgmt(struct wil6210_vif *vif, int id, void *d, int len)
678{ 690{
691 struct wil6210_priv *wil = vif_to_wil(vif);
679 struct wmi_rx_mgmt_packet_event *data = d; 692 struct wmi_rx_mgmt_packet_event *data = d;
680 struct wiphy *wiphy = wil_to_wiphy(wil); 693 struct wiphy *wiphy = wil_to_wiphy(wil);
681 struct ieee80211_mgmt *rx_mgmt_frame = 694 struct ieee80211_mgmt *rx_mgmt_frame =
@@ -753,14 +766,14 @@ static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
753 wil_err(wil, "cfg80211_inform_bss_frame() failed\n"); 766 wil_err(wil, "cfg80211_inform_bss_frame() failed\n");
754 } 767 }
755 } else { 768 } else {
756 mutex_lock(&wil->p2p_wdev_mutex); 769 mutex_lock(&wil->vif_mutex);
757 cfg80211_rx_mgmt(wil->radio_wdev, freq, signal, 770 cfg80211_rx_mgmt(vif_to_radio_wdev(wil, vif), freq, signal,
758 (void *)rx_mgmt_frame, d_len, 0); 771 (void *)rx_mgmt_frame, d_len, 0);
759 mutex_unlock(&wil->p2p_wdev_mutex); 772 mutex_unlock(&wil->vif_mutex);
760 } 773 }
761} 774}
762 775
763static void wmi_evt_tx_mgmt(struct wil6210_priv *wil, int id, void *d, int len) 776static void wmi_evt_tx_mgmt(struct wil6210_vif *vif, int id, void *d, int len)
764{ 777{
765 struct wmi_tx_mgmt_packet_event *data = d; 778 struct wmi_tx_mgmt_packet_event *data = d;
766 struct ieee80211_mgmt *mgmt_frame = 779 struct ieee80211_mgmt *mgmt_frame =
@@ -771,11 +784,13 @@ static void wmi_evt_tx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
771 flen, true); 784 flen, true);
772} 785}
773 786
774static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id, 787static void wmi_evt_scan_complete(struct wil6210_vif *vif, int id,
775 void *d, int len) 788 void *d, int len)
776{ 789{
777 mutex_lock(&wil->p2p_wdev_mutex); 790 struct wil6210_priv *wil = vif_to_wil(vif);
778 if (wil->scan_request) { 791
792 mutex_lock(&wil->vif_mutex);
793 if (vif->scan_request) {
779 struct wmi_scan_complete_event *data = d; 794 struct wmi_scan_complete_event *data = d;
780 int status = le32_to_cpu(data->status); 795 int status = le32_to_cpu(data->status);
781 struct cfg80211_scan_info info = { 796 struct cfg80211_scan_info info = {
@@ -785,26 +800,28 @@ static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id,
785 800
786 wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", status); 801 wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", status);
787 wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n", 802 wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n",
788 wil->scan_request, info.aborted); 803 vif->scan_request, info.aborted);
789 del_timer_sync(&wil->scan_timer); 804 del_timer_sync(&vif->scan_timer);
790 cfg80211_scan_done(wil->scan_request, &info); 805 cfg80211_scan_done(vif->scan_request, &info);
791 wil->radio_wdev = wil->wdev; 806 if (vif->mid == 0)
792 wil->scan_request = NULL; 807 wil->radio_wdev = wil->main_ndev->ieee80211_ptr;
808 vif->scan_request = NULL;
793 wake_up_interruptible(&wil->wq); 809 wake_up_interruptible(&wil->wq);
794 if (wil->p2p.pending_listen_wdev) { 810 if (vif->p2p.pending_listen_wdev) {
795 wil_dbg_misc(wil, "Scheduling delayed listen\n"); 811 wil_dbg_misc(wil, "Scheduling delayed listen\n");
796 schedule_work(&wil->p2p.delayed_listen_work); 812 schedule_work(&vif->p2p.delayed_listen_work);
797 } 813 }
798 } else { 814 } else {
799 wil_err(wil, "SCAN_COMPLETE while not scanning\n"); 815 wil_err(wil, "SCAN_COMPLETE while not scanning\n");
800 } 816 }
801 mutex_unlock(&wil->p2p_wdev_mutex); 817 mutex_unlock(&wil->vif_mutex);
802} 818}
803 819
804static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len) 820static void wmi_evt_connect(struct wil6210_vif *vif, int id, void *d, int len)
805{ 821{
806 struct net_device *ndev = wil_to_ndev(wil); 822 struct wil6210_priv *wil = vif_to_wil(vif);
807 struct wireless_dev *wdev = wil->wdev; 823 struct net_device *ndev = vif_to_ndev(vif);
824 struct wireless_dev *wdev = vif_to_wdev(vif);
808 struct wmi_connect_event *evt = d; 825 struct wmi_connect_event *evt = d;
809 int ch; /* channel number */ 826 int ch; /* channel number */
810 struct station_info sinfo; 827 struct station_info sinfo;
@@ -869,12 +886,12 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
869 886
870 if ((wdev->iftype == NL80211_IFTYPE_STATION) || 887 if ((wdev->iftype == NL80211_IFTYPE_STATION) ||
871 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) { 888 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
872 if (!test_bit(wil_status_fwconnecting, wil->status)) { 889 if (!test_bit(wil_vif_fwconnecting, vif->status)) {
873 wil_err(wil, "Not in connecting state\n"); 890 wil_err(wil, "Not in connecting state\n");
874 mutex_unlock(&wil->mutex); 891 mutex_unlock(&wil->mutex);
875 return; 892 return;
876 } 893 }
877 del_timer_sync(&wil->connect_timer); 894 del_timer_sync(&vif->connect_timer);
878 } else if ((wdev->iftype == NL80211_IFTYPE_AP) || 895 } else if ((wdev->iftype == NL80211_IFTYPE_AP) ||
879 (wdev->iftype == NL80211_IFTYPE_P2P_GO)) { 896 (wdev->iftype == NL80211_IFTYPE_P2P_GO)) {
880 if (wil->sta[evt->cid].status != wil_sta_unused) { 897 if (wil->sta[evt->cid].status != wil_sta_unused) {
@@ -886,13 +903,14 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
886 } 903 }
887 904
888 ether_addr_copy(wil->sta[evt->cid].addr, evt->bssid); 905 ether_addr_copy(wil->sta[evt->cid].addr, evt->bssid);
906 wil->sta[evt->cid].mid = vif->mid;
889 wil->sta[evt->cid].status = wil_sta_conn_pending; 907 wil->sta[evt->cid].status = wil_sta_conn_pending;
890 908
891 rc = wil_tx_init(wil, evt->cid); 909 rc = wil_tx_init(vif, evt->cid);
892 if (rc) { 910 if (rc) {
893 wil_err(wil, "config tx vring failed for CID %d, rc (%d)\n", 911 wil_err(wil, "config tx vring failed for CID %d, rc (%d)\n",
894 evt->cid, rc); 912 evt->cid, rc);
895 wmi_disconnect_sta(wil, wil->sta[evt->cid].addr, 913 wmi_disconnect_sta(vif, wil->sta[evt->cid].addr,
896 WLAN_REASON_UNSPECIFIED, false, false); 914 WLAN_REASON_UNSPECIFIED, false, false);
897 } else { 915 } else {
898 wil_info(wil, "successful connection to CID %d\n", evt->cid); 916 wil_info(wil, "successful connection to CID %d\n", evt->cid);
@@ -912,14 +930,14 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
912 } else { 930 } else {
913 struct wiphy *wiphy = wil_to_wiphy(wil); 931 struct wiphy *wiphy = wil_to_wiphy(wil);
914 932
915 cfg80211_ref_bss(wiphy, wil->bss); 933 cfg80211_ref_bss(wiphy, vif->bss);
916 cfg80211_connect_bss(ndev, evt->bssid, wil->bss, 934 cfg80211_connect_bss(ndev, evt->bssid, vif->bss,
917 assoc_req_ie, assoc_req_ielen, 935 assoc_req_ie, assoc_req_ielen,
918 assoc_resp_ie, assoc_resp_ielen, 936 assoc_resp_ie, assoc_resp_ielen,
919 WLAN_STATUS_SUCCESS, GFP_KERNEL, 937 WLAN_STATUS_SUCCESS, GFP_KERNEL,
920 NL80211_TIMEOUT_UNSPECIFIED); 938 NL80211_TIMEOUT_UNSPECIFIED);
921 } 939 }
922 wil->bss = NULL; 940 vif->bss = NULL;
923 } else if ((wdev->iftype == NL80211_IFTYPE_AP) || 941 } else if ((wdev->iftype == NL80211_IFTYPE_AP) ||
924 (wdev->iftype == NL80211_IFTYPE_P2P_GO)) { 942 (wdev->iftype == NL80211_IFTYPE_P2P_GO)) {
925 if (rc) { 943 if (rc) {
@@ -947,19 +965,23 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
947 965
948 wil->sta[evt->cid].status = wil_sta_connected; 966 wil->sta[evt->cid].status = wil_sta_connected;
949 wil->sta[evt->cid].aid = evt->aid; 967 wil->sta[evt->cid].aid = evt->aid;
950 set_bit(wil_status_fwconnected, wil->status); 968 if (!test_and_set_bit(wil_vif_fwconnected, vif->status))
951 wil_update_net_queues_bh(wil, NULL, false); 969 atomic_inc(&wil->connected_vifs);
970 wil_update_net_queues_bh(wil, vif, NULL, false);
952 971
953out: 972out:
954 if (rc) 973 if (rc) {
955 wil->sta[evt->cid].status = wil_sta_unused; 974 wil->sta[evt->cid].status = wil_sta_unused;
956 clear_bit(wil_status_fwconnecting, wil->status); 975 wil->sta[evt->cid].mid = U8_MAX;
976 }
977 clear_bit(wil_vif_fwconnecting, vif->status);
957 mutex_unlock(&wil->mutex); 978 mutex_unlock(&wil->mutex);
958} 979}
959 980
960static void wmi_evt_disconnect(struct wil6210_priv *wil, int id, 981static void wmi_evt_disconnect(struct wil6210_vif *vif, int id,
961 void *d, int len) 982 void *d, int len)
962{ 983{
984 struct wil6210_priv *wil = vif_to_wil(vif);
963 struct wmi_disconnect_event *evt = d; 985 struct wmi_disconnect_event *evt = d;
964 u16 reason_code = le16_to_cpu(evt->protocol_reason_status); 986 u16 reason_code = le16_to_cpu(evt->protocol_reason_status);
965 987
@@ -976,7 +998,7 @@ static void wmi_evt_disconnect(struct wil6210_priv *wil, int id,
976 } 998 }
977 999
978 mutex_lock(&wil->mutex); 1000 mutex_lock(&wil->mutex);
979 wil6210_disconnect(wil, evt->bssid, reason_code, true); 1001 wil6210_disconnect(vif, evt->bssid, reason_code, true);
980 mutex_unlock(&wil->mutex); 1002 mutex_unlock(&wil->mutex);
981} 1003}
982 1004
@@ -984,10 +1006,10 @@ static void wmi_evt_disconnect(struct wil6210_priv *wil, int id,
984 * Firmware reports EAPOL frame using WME event. 1006 * Firmware reports EAPOL frame using WME event.
985 * Reconstruct Ethernet frame and deliver it via normal Rx 1007 * Reconstruct Ethernet frame and deliver it via normal Rx
986 */ 1008 */
987static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id, 1009static void wmi_evt_eapol_rx(struct wil6210_vif *vif, int id, void *d, int len)
988 void *d, int len)
989{ 1010{
990 struct net_device *ndev = wil_to_ndev(wil); 1011 struct wil6210_priv *wil = vif_to_wil(vif);
1012 struct net_device *ndev = vif_to_ndev(vif);
991 struct wmi_eapol_rx_event *evt = d; 1013 struct wmi_eapol_rx_event *evt = d;
992 u16 eapol_len = le16_to_cpu(evt->eapol_len); 1014 u16 eapol_len = le16_to_cpu(evt->eapol_len);
993 int sz = eapol_len + ETH_HLEN; 1015 int sz = eapol_len + ETH_HLEN;
@@ -996,10 +1018,10 @@ static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id,
996 int cid; 1018 int cid;
997 struct wil_net_stats *stats = NULL; 1019 struct wil_net_stats *stats = NULL;
998 1020
999 wil_dbg_wmi(wil, "EAPOL len %d from %pM\n", eapol_len, 1021 wil_dbg_wmi(wil, "EAPOL len %d from %pM MID %d\n", eapol_len,
1000 evt->src_mac); 1022 evt->src_mac, vif->mid);
1001 1023
1002 cid = wil_find_cid(wil, evt->src_mac); 1024 cid = wil_find_cid(wil, vif->mid, evt->src_mac);
1003 if (cid >= 0) 1025 if (cid >= 0)
1004 stats = &wil->sta[cid].stats; 1026 stats = &wil->sta[cid].stats;
1005 1027
@@ -1034,13 +1056,14 @@ static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id,
1034 } 1056 }
1035} 1057}
1036 1058
1037static void wmi_evt_vring_en(struct wil6210_priv *wil, int id, void *d, int len) 1059static void wmi_evt_vring_en(struct wil6210_vif *vif, int id, void *d, int len)
1038{ 1060{
1061 struct wil6210_priv *wil = vif_to_wil(vif);
1039 struct wmi_vring_en_event *evt = d; 1062 struct wmi_vring_en_event *evt = d;
1040 u8 vri = evt->vring_index; 1063 u8 vri = evt->vring_index;
1041 struct wireless_dev *wdev = wil_to_wdev(wil); 1064 struct wireless_dev *wdev = vif_to_wdev(vif);
1042 1065
1043 wil_dbg_wmi(wil, "Enable vring %d\n", vri); 1066 wil_dbg_wmi(wil, "Enable vring %d MID %d\n", vri, vif->mid);
1044 1067
1045 if (vri >= ARRAY_SIZE(wil->vring_tx)) { 1068 if (vri >= ARRAY_SIZE(wil->vring_tx)) {
1046 wil_err(wil, "Enable for invalid vring %d\n", vri); 1069 wil_err(wil, "Enable for invalid vring %d\n", vri);
@@ -1052,15 +1075,16 @@ static void wmi_evt_vring_en(struct wil6210_priv *wil, int id, void *d, int len)
1052 * wil_cfg80211_change_station() 1075 * wil_cfg80211_change_station()
1053 */ 1076 */
1054 wil->vring_tx_data[vri].dot1x_open = true; 1077 wil->vring_tx_data[vri].dot1x_open = true;
1055 if (vri == wil->bcast_vring) /* no BA for bcast */ 1078 if (vri == vif->bcast_vring) /* no BA for bcast */
1056 return; 1079 return;
1057 if (agg_wsize >= 0) 1080 if (agg_wsize >= 0)
1058 wil_addba_tx_request(wil, vri, agg_wsize); 1081 wil_addba_tx_request(wil, vri, agg_wsize);
1059} 1082}
1060 1083
1061static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d, 1084static void wmi_evt_ba_status(struct wil6210_vif *vif, int id,
1062 int len) 1085 void *d, int len)
1063{ 1086{
1087 struct wil6210_priv *wil = vif_to_wil(vif);
1064 struct wmi_ba_status_event *evt = d; 1088 struct wmi_ba_status_event *evt = d;
1065 struct vring_tx_data *txdata; 1089 struct vring_tx_data *txdata;
1066 1090
@@ -1089,19 +1113,21 @@ static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d,
1089 txdata->addba_in_progress = false; 1113 txdata->addba_in_progress = false;
1090} 1114}
1091 1115
1092static void wmi_evt_addba_rx_req(struct wil6210_priv *wil, int id, void *d, 1116static void wmi_evt_addba_rx_req(struct wil6210_vif *vif, int id,
1093 int len) 1117 void *d, int len)
1094{ 1118{
1119 struct wil6210_priv *wil = vif_to_wil(vif);
1095 struct wmi_rcp_addba_req_event *evt = d; 1120 struct wmi_rcp_addba_req_event *evt = d;
1096 1121
1097 wil_addba_rx_request(wil, evt->cidxtid, evt->dialog_token, 1122 wil_addba_rx_request(wil, vif->mid, evt->cidxtid, evt->dialog_token,
1098 evt->ba_param_set, evt->ba_timeout, 1123 evt->ba_param_set, evt->ba_timeout,
1099 evt->ba_seq_ctrl); 1124 evt->ba_seq_ctrl);
1100} 1125}
1101 1126
1102static void wmi_evt_delba(struct wil6210_priv *wil, int id, void *d, int len) 1127static void wmi_evt_delba(struct wil6210_vif *vif, int id, void *d, int len)
1103__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) 1128__acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
1104{ 1129{
1130 struct wil6210_priv *wil = vif_to_wil(vif);
1105 struct wmi_delba_event *evt = d; 1131 struct wmi_delba_event *evt = d;
1106 u8 cid, tid; 1132 u8 cid, tid;
1107 u16 reason = __le16_to_cpu(evt->reason); 1133 u16 reason = __le16_to_cpu(evt->reason);
@@ -1110,8 +1136,8 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
1110 1136
1111 might_sleep(); 1137 might_sleep();
1112 parse_cidxtid(evt->cidxtid, &cid, &tid); 1138 parse_cidxtid(evt->cidxtid, &cid, &tid);
1113 wil_dbg_wmi(wil, "DELBA CID %d TID %d from %s reason %d\n", 1139 wil_dbg_wmi(wil, "DELBA MID %d CID %d TID %d from %s reason %d\n",
1114 cid, tid, 1140 vif->mid, cid, tid,
1115 evt->from_initiator ? "originator" : "recipient", 1141 evt->from_initiator ? "originator" : "recipient",
1116 reason); 1142 reason);
1117 if (!evt->from_initiator) { 1143 if (!evt->from_initiator) {
@@ -1148,8 +1174,9 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
1148} 1174}
1149 1175
1150static void 1176static void
1151wmi_evt_sched_scan_result(struct wil6210_priv *wil, int id, void *d, int len) 1177wmi_evt_sched_scan_result(struct wil6210_vif *vif, int id, void *d, int len)
1152{ 1178{
1179 struct wil6210_priv *wil = vif_to_wil(vif);
1153 struct wmi_sched_scan_result_event *data = d; 1180 struct wmi_sched_scan_result_event *data = d;
1154 struct wiphy *wiphy = wil_to_wiphy(wil); 1181 struct wiphy *wiphy = wil_to_wiphy(wil);
1155 struct ieee80211_mgmt *rx_mgmt_frame = 1182 struct ieee80211_mgmt *rx_mgmt_frame =
@@ -1220,15 +1247,17 @@ wmi_evt_sched_scan_result(struct wil6210_priv *wil, int id, void *d, int len)
1220 * Some events are ignored for purpose; and need not be interpreted as 1247 * Some events are ignored for purpose; and need not be interpreted as
1221 * "unhandled events" 1248 * "unhandled events"
1222 */ 1249 */
1223static void wmi_evt_ignore(struct wil6210_priv *wil, int id, void *d, int len) 1250static void wmi_evt_ignore(struct wil6210_vif *vif, int id, void *d, int len)
1224{ 1251{
1252 struct wil6210_priv *wil = vif_to_wil(vif);
1253
1225 wil_dbg_wmi(wil, "Ignore event 0x%04x len %d\n", id, len); 1254 wil_dbg_wmi(wil, "Ignore event 0x%04x len %d\n", id, len);
1226} 1255}
1227 1256
1228static const struct { 1257static const struct {
1229 int eventid; 1258 int eventid;
1230 void (*handler)(struct wil6210_priv *wil, int eventid, 1259 void (*handler)(struct wil6210_vif *vif,
1231 void *data, int data_len); 1260 int eventid, void *data, int data_len);
1232} wmi_evt_handlers[] = { 1261} wmi_evt_handlers[] = {
1233 {WMI_READY_EVENTID, wmi_evt_ready}, 1262 {WMI_READY_EVENTID, wmi_evt_ready},
1234 {WMI_FW_READY_EVENTID, wmi_evt_ignore}, 1263 {WMI_FW_READY_EVENTID, wmi_evt_ignore},
@@ -1325,6 +1354,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
1325 (len >= sizeof(struct wmi_cmd_hdr))) { 1354 (len >= sizeof(struct wmi_cmd_hdr))) {
1326 struct wmi_cmd_hdr *wmi = &evt->event.wmi; 1355 struct wmi_cmd_hdr *wmi = &evt->event.wmi;
1327 u16 id = le16_to_cpu(wmi->command_id); 1356 u16 id = le16_to_cpu(wmi->command_id);
1357 u8 mid = wmi->mid;
1328 u32 tstamp = le32_to_cpu(wmi->fw_timestamp); 1358 u32 tstamp = le32_to_cpu(wmi->fw_timestamp);
1329 if (test_bit(wil_status_resuming, wil->status)) { 1359 if (test_bit(wil_status_resuming, wil->status)) {
1330 if (id == WMI_TRAFFIC_RESUME_EVENTID) 1360 if (id == WMI_TRAFFIC_RESUME_EVENTID)
@@ -1336,7 +1366,8 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
1336 id); 1366 id);
1337 } 1367 }
1338 spin_lock_irqsave(&wil->wmi_ev_lock, flags); 1368 spin_lock_irqsave(&wil->wmi_ev_lock, flags);
1339 if (wil->reply_id && wil->reply_id == id) { 1369 if (wil->reply_id && wil->reply_id == id &&
1370 wil->reply_mid == mid) {
1340 if (wil->reply_buf) { 1371 if (wil->reply_buf) {
1341 memcpy(wil->reply_buf, wmi, 1372 memcpy(wil->reply_buf, wmi,
1342 min(len, wil->reply_size)); 1373 min(len, wil->reply_size));
@@ -1384,7 +1415,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
1384 n - num_immed_reply, num_immed_reply); 1415 n - num_immed_reply, num_immed_reply);
1385} 1416}
1386 1417
1387int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, 1418int wmi_call(struct wil6210_priv *wil, u16 cmdid, u8 mid, void *buf, u16 len,
1388 u16 reply_id, void *reply, u8 reply_size, int to_msec) 1419 u16 reply_id, void *reply, u8 reply_size, int to_msec)
1389{ 1420{
1390 int rc; 1421 int rc;
@@ -1394,12 +1425,13 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
1394 1425
1395 spin_lock(&wil->wmi_ev_lock); 1426 spin_lock(&wil->wmi_ev_lock);
1396 wil->reply_id = reply_id; 1427 wil->reply_id = reply_id;
1428 wil->reply_mid = mid;
1397 wil->reply_buf = reply; 1429 wil->reply_buf = reply;
1398 wil->reply_size = reply_size; 1430 wil->reply_size = reply_size;
1399 reinit_completion(&wil->wmi_call); 1431 reinit_completion(&wil->wmi_call);
1400 spin_unlock(&wil->wmi_ev_lock); 1432 spin_unlock(&wil->wmi_ev_lock);
1401 1433
1402 rc = __wmi_send(wil, cmdid, buf, len); 1434 rc = __wmi_send(wil, cmdid, mid, buf, len);
1403 if (rc) 1435 if (rc)
1404 goto out; 1436 goto out;
1405 1437
@@ -1419,6 +1451,7 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
1419out: 1451out:
1420 spin_lock(&wil->wmi_ev_lock); 1452 spin_lock(&wil->wmi_ev_lock);
1421 wil->reply_id = 0; 1453 wil->reply_id = 0;
1454 wil->reply_mid = U8_MAX;
1422 wil->reply_buf = NULL; 1455 wil->reply_buf = NULL;
1423 wil->reply_size = 0; 1456 wil->reply_size = 0;
1424 spin_unlock(&wil->wmi_ev_lock); 1457 spin_unlock(&wil->wmi_ev_lock);
@@ -1430,27 +1463,31 @@ out:
1430 1463
1431int wmi_echo(struct wil6210_priv *wil) 1464int wmi_echo(struct wil6210_priv *wil)
1432{ 1465{
1466 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
1433 struct wmi_echo_cmd cmd = { 1467 struct wmi_echo_cmd cmd = {
1434 .value = cpu_to_le32(0x12345678), 1468 .value = cpu_to_le32(0x12345678),
1435 }; 1469 };
1436 1470
1437 return wmi_call(wil, WMI_ECHO_CMDID, &cmd, sizeof(cmd), 1471 return wmi_call(wil, WMI_ECHO_CMDID, vif->mid, &cmd, sizeof(cmd),
1438 WMI_ECHO_RSP_EVENTID, NULL, 0, 50); 1472 WMI_ECHO_RSP_EVENTID, NULL, 0, 50);
1439} 1473}
1440 1474
1441int wmi_set_mac_address(struct wil6210_priv *wil, void *addr) 1475int wmi_set_mac_address(struct wil6210_priv *wil, void *addr)
1442{ 1476{
1477 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
1443 struct wmi_set_mac_address_cmd cmd; 1478 struct wmi_set_mac_address_cmd cmd;
1444 1479
1445 ether_addr_copy(cmd.mac, addr); 1480 ether_addr_copy(cmd.mac, addr);
1446 1481
1447 wil_dbg_wmi(wil, "Set MAC %pM\n", addr); 1482 wil_dbg_wmi(wil, "Set MAC %pM\n", addr);
1448 1483
1449 return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd)); 1484 return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, vif->mid,
1485 &cmd, sizeof(cmd));
1450} 1486}
1451 1487
1452int wmi_led_cfg(struct wil6210_priv *wil, bool enable) 1488int wmi_led_cfg(struct wil6210_priv *wil, bool enable)
1453{ 1489{
1490 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
1454 int rc = 0; 1491 int rc = 0;
1455 struct wmi_led_cfg_cmd cmd = { 1492 struct wmi_led_cfg_cmd cmd = {
1456 .led_mode = enable, 1493 .led_mode = enable,
@@ -1487,7 +1524,7 @@ int wmi_led_cfg(struct wil6210_priv *wil, bool enable)
1487 "%s led %d\n", 1524 "%s led %d\n",
1488 enable ? "enabling" : "disabling", led_id); 1525 enable ? "enabling" : "disabling", led_id);
1489 1526
1490 rc = wmi_call(wil, WMI_LED_CFG_CMDID, &cmd, sizeof(cmd), 1527 rc = wmi_call(wil, WMI_LED_CFG_CMDID, vif->mid, &cmd, sizeof(cmd),
1491 WMI_LED_CFG_DONE_EVENTID, &reply, sizeof(reply), 1528 WMI_LED_CFG_DONE_EVENTID, &reply, sizeof(reply),
1492 100); 1529 100);
1493 if (rc) 1530 if (rc)
@@ -1503,9 +1540,10 @@ out:
1503 return rc; 1540 return rc;
1504} 1541}
1505 1542
1506int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, 1543int wmi_pcp_start(struct wil6210_vif *vif,
1507 u8 chan, u8 hidden_ssid, u8 is_go) 1544 int bi, u8 wmi_nettype, u8 chan, u8 hidden_ssid, u8 is_go)
1508{ 1545{
1546 struct wil6210_priv *wil = vif_to_wil(vif);
1509 int rc; 1547 int rc;
1510 1548
1511 struct wmi_pcp_start_cmd cmd = { 1549 struct wmi_pcp_start_cmd cmd = {
@@ -1524,7 +1562,7 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype,
1524 struct wmi_pcp_started_event evt; 1562 struct wmi_pcp_started_event evt;
1525 } __packed reply; 1563 } __packed reply;
1526 1564
1527 if (!wil->privacy) 1565 if (!vif->privacy)
1528 cmd.disable_sec = 1; 1566 cmd.disable_sec = 1;
1529 1567
1530 if ((cmd.pcp_max_assoc_sta > WIL6210_MAX_CID) || 1568 if ((cmd.pcp_max_assoc_sta > WIL6210_MAX_CID) ||
@@ -1546,7 +1584,7 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype,
1546 * Processing time may be huge, in case of secure AP it takes about 1584 * Processing time may be huge, in case of secure AP it takes about
1547 * 3500ms for FW to start AP 1585 * 3500ms for FW to start AP
1548 */ 1586 */
1549 rc = wmi_call(wil, WMI_PCP_START_CMDID, &cmd, sizeof(cmd), 1587 rc = wmi_call(wil, WMI_PCP_START_CMDID, vif->mid, &cmd, sizeof(cmd),
1550 WMI_PCP_STARTED_EVENTID, &reply, sizeof(reply), 5000); 1588 WMI_PCP_STARTED_EVENTID, &reply, sizeof(reply), 5000);
1551 if (rc) 1589 if (rc)
1552 return rc; 1590 return rc;
@@ -1561,20 +1599,22 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype,
1561 return rc; 1599 return rc;
1562} 1600}
1563 1601
1564int wmi_pcp_stop(struct wil6210_priv *wil) 1602int wmi_pcp_stop(struct wil6210_vif *vif)
1565{ 1603{
1604 struct wil6210_priv *wil = vif_to_wil(vif);
1566 int rc; 1605 int rc;
1567 1606
1568 rc = wmi_led_cfg(wil, false); 1607 rc = wmi_led_cfg(wil, false);
1569 if (rc) 1608 if (rc)
1570 return rc; 1609 return rc;
1571 1610
1572 return wmi_call(wil, WMI_PCP_STOP_CMDID, NULL, 0, 1611 return wmi_call(wil, WMI_PCP_STOP_CMDID, vif->mid, NULL, 0,
1573 WMI_PCP_STOPPED_EVENTID, NULL, 0, 20); 1612 WMI_PCP_STOPPED_EVENTID, NULL, 0, 20);
1574} 1613}
1575 1614
1576int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid) 1615int wmi_set_ssid(struct wil6210_vif *vif, u8 ssid_len, const void *ssid)
1577{ 1616{
1617 struct wil6210_priv *wil = vif_to_wil(vif);
1578 struct wmi_set_ssid_cmd cmd = { 1618 struct wmi_set_ssid_cmd cmd = {
1579 .ssid_len = cpu_to_le32(ssid_len), 1619 .ssid_len = cpu_to_le32(ssid_len),
1580 }; 1620 };
@@ -1584,11 +1624,12 @@ int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid)
1584 1624
1585 memcpy(cmd.ssid, ssid, ssid_len); 1625 memcpy(cmd.ssid, ssid, ssid_len);
1586 1626
1587 return wmi_send(wil, WMI_SET_SSID_CMDID, &cmd, sizeof(cmd)); 1627 return wmi_send(wil, WMI_SET_SSID_CMDID, vif->mid, &cmd, sizeof(cmd));
1588} 1628}
1589 1629
1590int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid) 1630int wmi_get_ssid(struct wil6210_vif *vif, u8 *ssid_len, void *ssid)
1591{ 1631{
1632 struct wil6210_priv *wil = vif_to_wil(vif);
1592 int rc; 1633 int rc;
1593 struct { 1634 struct {
1594 struct wmi_cmd_hdr wmi; 1635 struct wmi_cmd_hdr wmi;
@@ -1596,8 +1637,8 @@ int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid)
1596 } __packed reply; 1637 } __packed reply;
1597 int len; /* reply.cmd.ssid_len in CPU order */ 1638 int len; /* reply.cmd.ssid_len in CPU order */
1598 1639
1599 rc = wmi_call(wil, WMI_GET_SSID_CMDID, NULL, 0, WMI_GET_SSID_EVENTID, 1640 rc = wmi_call(wil, WMI_GET_SSID_CMDID, vif->mid, NULL, 0,
1600 &reply, sizeof(reply), 20); 1641 WMI_GET_SSID_EVENTID, &reply, sizeof(reply), 20);
1601 if (rc) 1642 if (rc)
1602 return rc; 1643 return rc;
1603 1644
@@ -1613,22 +1654,25 @@ int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid)
1613 1654
1614int wmi_set_channel(struct wil6210_priv *wil, int channel) 1655int wmi_set_channel(struct wil6210_priv *wil, int channel)
1615{ 1656{
1657 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
1616 struct wmi_set_pcp_channel_cmd cmd = { 1658 struct wmi_set_pcp_channel_cmd cmd = {
1617 .channel = channel - 1, 1659 .channel = channel - 1,
1618 }; 1660 };
1619 1661
1620 return wmi_send(wil, WMI_SET_PCP_CHANNEL_CMDID, &cmd, sizeof(cmd)); 1662 return wmi_send(wil, WMI_SET_PCP_CHANNEL_CMDID, vif->mid,
1663 &cmd, sizeof(cmd));
1621} 1664}
1622 1665
1623int wmi_get_channel(struct wil6210_priv *wil, int *channel) 1666int wmi_get_channel(struct wil6210_priv *wil, int *channel)
1624{ 1667{
1668 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
1625 int rc; 1669 int rc;
1626 struct { 1670 struct {
1627 struct wmi_cmd_hdr wmi; 1671 struct wmi_cmd_hdr wmi;
1628 struct wmi_set_pcp_channel_cmd cmd; 1672 struct wmi_set_pcp_channel_cmd cmd;
1629 } __packed reply; 1673 } __packed reply;
1630 1674
1631 rc = wmi_call(wil, WMI_GET_PCP_CHANNEL_CMDID, NULL, 0, 1675 rc = wmi_call(wil, WMI_GET_PCP_CHANNEL_CMDID, vif->mid, NULL, 0,
1632 WMI_GET_PCP_CHANNEL_EVENTID, &reply, sizeof(reply), 20); 1676 WMI_GET_PCP_CHANNEL_EVENTID, &reply, sizeof(reply), 20);
1633 if (rc) 1677 if (rc)
1634 return rc; 1678 return rc;
@@ -1641,8 +1685,9 @@ int wmi_get_channel(struct wil6210_priv *wil, int *channel)
1641 return 0; 1685 return 0;
1642} 1686}
1643 1687
1644int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi) 1688int wmi_p2p_cfg(struct wil6210_vif *vif, int channel, int bi)
1645{ 1689{
1690 struct wil6210_priv *wil = vif_to_wil(vif);
1646 int rc; 1691 int rc;
1647 struct wmi_p2p_cfg_cmd cmd = { 1692 struct wmi_p2p_cfg_cmd cmd = {
1648 .discovery_mode = WMI_DISCOVERY_MODE_PEER2PEER, 1693 .discovery_mode = WMI_DISCOVERY_MODE_PEER2PEER,
@@ -1656,7 +1701,7 @@ int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi)
1656 1701
1657 wil_dbg_wmi(wil, "sending WMI_P2P_CFG_CMDID\n"); 1702 wil_dbg_wmi(wil, "sending WMI_P2P_CFG_CMDID\n");
1658 1703
1659 rc = wmi_call(wil, WMI_P2P_CFG_CMDID, &cmd, sizeof(cmd), 1704 rc = wmi_call(wil, WMI_P2P_CFG_CMDID, vif->mid, &cmd, sizeof(cmd),
1660 WMI_P2P_CFG_DONE_EVENTID, &reply, sizeof(reply), 300); 1705 WMI_P2P_CFG_DONE_EVENTID, &reply, sizeof(reply), 300);
1661 if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) { 1706 if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) {
1662 wil_err(wil, "P2P_CFG failed. status %d\n", reply.evt.status); 1707 wil_err(wil, "P2P_CFG failed. status %d\n", reply.evt.status);
@@ -1666,8 +1711,9 @@ int wmi_p2p_cfg(struct wil6210_priv *wil, int channel, int bi)
1666 return rc; 1711 return rc;
1667} 1712}
1668 1713
1669int wmi_start_listen(struct wil6210_priv *wil) 1714int wmi_start_listen(struct wil6210_vif *vif)
1670{ 1715{
1716 struct wil6210_priv *wil = vif_to_wil(vif);
1671 int rc; 1717 int rc;
1672 struct { 1718 struct {
1673 struct wmi_cmd_hdr wmi; 1719 struct wmi_cmd_hdr wmi;
@@ -1676,7 +1722,7 @@ int wmi_start_listen(struct wil6210_priv *wil)
1676 1722
1677 wil_dbg_wmi(wil, "sending WMI_START_LISTEN_CMDID\n"); 1723 wil_dbg_wmi(wil, "sending WMI_START_LISTEN_CMDID\n");
1678 1724
1679 rc = wmi_call(wil, WMI_START_LISTEN_CMDID, NULL, 0, 1725 rc = wmi_call(wil, WMI_START_LISTEN_CMDID, vif->mid, NULL, 0,
1680 WMI_LISTEN_STARTED_EVENTID, &reply, sizeof(reply), 300); 1726 WMI_LISTEN_STARTED_EVENTID, &reply, sizeof(reply), 300);
1681 if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) { 1727 if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) {
1682 wil_err(wil, "device failed to start listen. status %d\n", 1728 wil_err(wil, "device failed to start listen. status %d\n",
@@ -1687,8 +1733,9 @@ int wmi_start_listen(struct wil6210_priv *wil)
1687 return rc; 1733 return rc;
1688} 1734}
1689 1735
1690int wmi_start_search(struct wil6210_priv *wil) 1736int wmi_start_search(struct wil6210_vif *vif)
1691{ 1737{
1738 struct wil6210_priv *wil = vif_to_wil(vif);
1692 int rc; 1739 int rc;
1693 struct { 1740 struct {
1694 struct wmi_cmd_hdr wmi; 1741 struct wmi_cmd_hdr wmi;
@@ -1697,7 +1744,7 @@ int wmi_start_search(struct wil6210_priv *wil)
1697 1744
1698 wil_dbg_wmi(wil, "sending WMI_START_SEARCH_CMDID\n"); 1745 wil_dbg_wmi(wil, "sending WMI_START_SEARCH_CMDID\n");
1699 1746
1700 rc = wmi_call(wil, WMI_START_SEARCH_CMDID, NULL, 0, 1747 rc = wmi_call(wil, WMI_START_SEARCH_CMDID, vif->mid, NULL, 0,
1701 WMI_SEARCH_STARTED_EVENTID, &reply, sizeof(reply), 300); 1748 WMI_SEARCH_STARTED_EVENTID, &reply, sizeof(reply), 300);
1702 if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) { 1749 if (!rc && reply.evt.status != WMI_FW_STATUS_SUCCESS) {
1703 wil_err(wil, "device failed to start search. status %d\n", 1750 wil_err(wil, "device failed to start search. status %d\n",
@@ -1708,13 +1755,14 @@ int wmi_start_search(struct wil6210_priv *wil)
1708 return rc; 1755 return rc;
1709} 1756}
1710 1757
1711int wmi_stop_discovery(struct wil6210_priv *wil) 1758int wmi_stop_discovery(struct wil6210_vif *vif)
1712{ 1759{
1760 struct wil6210_priv *wil = vif_to_wil(vif);
1713 int rc; 1761 int rc;
1714 1762
1715 wil_dbg_wmi(wil, "sending WMI_DISCOVERY_STOP_CMDID\n"); 1763 wil_dbg_wmi(wil, "sending WMI_DISCOVERY_STOP_CMDID\n");
1716 1764
1717 rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, NULL, 0, 1765 rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, vif->mid, NULL, 0,
1718 WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 100); 1766 WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 100);
1719 1767
1720 if (rc) 1768 if (rc)
@@ -1723,9 +1771,10 @@ int wmi_stop_discovery(struct wil6210_priv *wil)
1723 return rc; 1771 return rc;
1724} 1772}
1725 1773
1726int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index, 1774int wmi_del_cipher_key(struct wil6210_vif *vif, u8 key_index,
1727 const void *mac_addr, int key_usage) 1775 const void *mac_addr, int key_usage)
1728{ 1776{
1777 struct wil6210_priv *wil = vif_to_wil(vif);
1729 struct wmi_delete_cipher_key_cmd cmd = { 1778 struct wmi_delete_cipher_key_cmd cmd = {
1730 .key_index = key_index, 1779 .key_index = key_index,
1731 }; 1780 };
@@ -1733,13 +1782,15 @@ int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index,
1733 if (mac_addr) 1782 if (mac_addr)
1734 memcpy(cmd.mac, mac_addr, WMI_MAC_LEN); 1783 memcpy(cmd.mac, mac_addr, WMI_MAC_LEN);
1735 1784
1736 return wmi_send(wil, WMI_DELETE_CIPHER_KEY_CMDID, &cmd, sizeof(cmd)); 1785 return wmi_send(wil, WMI_DELETE_CIPHER_KEY_CMDID, vif->mid,
1786 &cmd, sizeof(cmd));
1737} 1787}
1738 1788
1739int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index, 1789int wmi_add_cipher_key(struct wil6210_vif *vif, u8 key_index,
1740 const void *mac_addr, int key_len, const void *key, 1790 const void *mac_addr, int key_len, const void *key,
1741 int key_usage) 1791 int key_usage)
1742{ 1792{
1793 struct wil6210_priv *wil = vif_to_wil(vif);
1743 struct wmi_add_cipher_key_cmd cmd = { 1794 struct wmi_add_cipher_key_cmd cmd = {
1744 .key_index = key_index, 1795 .key_index = key_index,
1745 .key_usage = key_usage, 1796 .key_usage = key_usage,
@@ -1753,11 +1804,13 @@ int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index,
1753 if (mac_addr) 1804 if (mac_addr)
1754 memcpy(cmd.mac, mac_addr, WMI_MAC_LEN); 1805 memcpy(cmd.mac, mac_addr, WMI_MAC_LEN);
1755 1806
1756 return wmi_send(wil, WMI_ADD_CIPHER_KEY_CMDID, &cmd, sizeof(cmd)); 1807 return wmi_send(wil, WMI_ADD_CIPHER_KEY_CMDID, vif->mid,
1808 &cmd, sizeof(cmd));
1757} 1809}
1758 1810
1759int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie) 1811int wmi_set_ie(struct wil6210_vif *vif, u8 type, u16 ie_len, const void *ie)
1760{ 1812{
1813 struct wil6210_priv *wil = vif_to_wil(vif);
1761 static const char *const names[] = { 1814 static const char *const names[] = {
1762 [WMI_FRAME_BEACON] = "BEACON", 1815 [WMI_FRAME_BEACON] = "BEACON",
1763 [WMI_FRAME_PROBE_REQ] = "PROBE_REQ", 1816 [WMI_FRAME_PROBE_REQ] = "PROBE_REQ",
@@ -1786,7 +1839,7 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie)
1786 /* BUG: FW API define ieLen as u8. Will fix FW */ 1839 /* BUG: FW API define ieLen as u8. Will fix FW */
1787 cmd->ie_len = cpu_to_le16(ie_len); 1840 cmd->ie_len = cpu_to_le16(ie_len);
1788 memcpy(cmd->ie_info, ie, ie_len); 1841 memcpy(cmd->ie_info, ie, ie_len);
1789 rc = wmi_send(wil, WMI_SET_APPIE_CMDID, cmd, len); 1842 rc = wmi_send(wil, WMI_SET_APPIE_CMDID, vif->mid, cmd, len);
1790 kfree(cmd); 1843 kfree(cmd);
1791out: 1844out:
1792 if (rc) { 1845 if (rc) {
@@ -1808,6 +1861,7 @@ out:
1808 */ 1861 */
1809int wmi_rxon(struct wil6210_priv *wil, bool on) 1862int wmi_rxon(struct wil6210_priv *wil, bool on)
1810{ 1863{
1864 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
1811 int rc; 1865 int rc;
1812 struct { 1866 struct {
1813 struct wmi_cmd_hdr wmi; 1867 struct wmi_cmd_hdr wmi;
@@ -1817,13 +1871,13 @@ int wmi_rxon(struct wil6210_priv *wil, bool on)
1817 wil_info(wil, "(%s)\n", on ? "on" : "off"); 1871 wil_info(wil, "(%s)\n", on ? "on" : "off");
1818 1872
1819 if (on) { 1873 if (on) {
1820 rc = wmi_call(wil, WMI_START_LISTEN_CMDID, NULL, 0, 1874 rc = wmi_call(wil, WMI_START_LISTEN_CMDID, vif->mid, NULL, 0,
1821 WMI_LISTEN_STARTED_EVENTID, 1875 WMI_LISTEN_STARTED_EVENTID,
1822 &reply, sizeof(reply), 100); 1876 &reply, sizeof(reply), 100);
1823 if ((rc == 0) && (reply.evt.status != WMI_FW_STATUS_SUCCESS)) 1877 if ((rc == 0) && (reply.evt.status != WMI_FW_STATUS_SUCCESS))
1824 rc = -EINVAL; 1878 rc = -EINVAL;
1825 } else { 1879 } else {
1826 rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, NULL, 0, 1880 rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, vif->mid, NULL, 0,
1827 WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 20); 1881 WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 20);
1828 } 1882 }
1829 1883
@@ -1832,8 +1886,9 @@ int wmi_rxon(struct wil6210_priv *wil, bool on)
1832 1886
1833int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring) 1887int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
1834{ 1888{
1835 struct wireless_dev *wdev = wil->wdev; 1889 struct net_device *ndev = wil->main_ndev;
1836 struct net_device *ndev = wil_to_ndev(wil); 1890 struct wireless_dev *wdev = ndev->ieee80211_ptr;
1891 struct wil6210_vif *vif = ndev_to_vif(ndev);
1837 struct wmi_cfg_rx_chain_cmd cmd = { 1892 struct wmi_cfg_rx_chain_cmd cmd = {
1838 .action = WMI_RX_CHAIN_ADD, 1893 .action = WMI_RX_CHAIN_ADD,
1839 .rx_sw_ring = { 1894 .rx_sw_ring = {
@@ -1877,7 +1932,7 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
1877 L2_802_3_OFFLOAD_CTRL_SNAP_KEEP_MSK; 1932 L2_802_3_OFFLOAD_CTRL_SNAP_KEEP_MSK;
1878 1933
1879 /* typical time for secure PCP is 840ms */ 1934 /* typical time for secure PCP is 840ms */
1880 rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd), 1935 rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, vif->mid, &cmd, sizeof(cmd),
1881 WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000); 1936 WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000);
1882 if (rc) 1937 if (rc)
1883 return rc; 1938 return rc;
@@ -1895,6 +1950,7 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
1895 1950
1896int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf) 1951int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf)
1897{ 1952{
1953 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
1898 int rc; 1954 int rc;
1899 struct wmi_temp_sense_cmd cmd = { 1955 struct wmi_temp_sense_cmd cmd = {
1900 .measure_baseband_en = cpu_to_le32(!!t_bb), 1956 .measure_baseband_en = cpu_to_le32(!!t_bb),
@@ -1906,7 +1962,7 @@ int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf)
1906 struct wmi_temp_sense_done_event evt; 1962 struct wmi_temp_sense_done_event evt;
1907 } __packed reply; 1963 } __packed reply;
1908 1964
1909 rc = wmi_call(wil, WMI_TEMP_SENSE_CMDID, &cmd, sizeof(cmd), 1965 rc = wmi_call(wil, WMI_TEMP_SENSE_CMDID, vif->mid, &cmd, sizeof(cmd),
1910 WMI_TEMP_SENSE_DONE_EVENTID, &reply, sizeof(reply), 100); 1966 WMI_TEMP_SENSE_DONE_EVENTID, &reply, sizeof(reply), 100);
1911 if (rc) 1967 if (rc)
1912 return rc; 1968 return rc;
@@ -1919,9 +1975,10 @@ int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf)
1919 return 0; 1975 return 0;
1920} 1976}
1921 1977
1922int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, 1978int wmi_disconnect_sta(struct wil6210_vif *vif, const u8 *mac,
1923 u16 reason, bool full_disconnect, bool del_sta) 1979 u16 reason, bool full_disconnect, bool del_sta)
1924{ 1980{
1981 struct wil6210_priv *wil = vif_to_wil(vif);
1925 int rc; 1982 int rc;
1926 u16 reason_code; 1983 u16 reason_code;
1927 struct wmi_disconnect_sta_cmd disc_sta_cmd = { 1984 struct wmi_disconnect_sta_cmd disc_sta_cmd = {
@@ -1937,16 +1994,17 @@ int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac,
1937 1994
1938 wil_dbg_wmi(wil, "disconnect_sta: (%pM, reason %d)\n", mac, reason); 1995 wil_dbg_wmi(wil, "disconnect_sta: (%pM, reason %d)\n", mac, reason);
1939 1996
1940 wil->locally_generated_disc = true; 1997 vif->locally_generated_disc = true;
1941 if (del_sta) { 1998 if (del_sta) {
1942 ether_addr_copy(del_sta_cmd.dst_mac, mac); 1999 ether_addr_copy(del_sta_cmd.dst_mac, mac);
1943 rc = wmi_call(wil, WMI_DEL_STA_CMDID, &del_sta_cmd, 2000 rc = wmi_call(wil, WMI_DEL_STA_CMDID, vif->mid, &del_sta_cmd,
1944 sizeof(del_sta_cmd), WMI_DISCONNECT_EVENTID, 2001 sizeof(del_sta_cmd), WMI_DISCONNECT_EVENTID,
1945 &reply, sizeof(reply), 1000); 2002 &reply, sizeof(reply), 1000);
1946 } else { 2003 } else {
1947 ether_addr_copy(disc_sta_cmd.dst_mac, mac); 2004 ether_addr_copy(disc_sta_cmd.dst_mac, mac);
1948 rc = wmi_call(wil, WMI_DISCONNECT_STA_CMDID, &disc_sta_cmd, 2005 rc = wmi_call(wil, WMI_DISCONNECT_STA_CMDID, vif->mid,
1949 sizeof(disc_sta_cmd), WMI_DISCONNECT_EVENTID, 2006 &disc_sta_cmd, sizeof(disc_sta_cmd),
2007 WMI_DISCONNECT_EVENTID,
1950 &reply, sizeof(reply), 1000); 2008 &reply, sizeof(reply), 1000);
1951 } 2009 }
1952 /* failure to disconnect in reasonable time treated as FW error */ 2010 /* failure to disconnect in reasonable time treated as FW error */
@@ -1967,12 +2025,13 @@ int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac,
1967 reply.evt.disconnect_reason); 2025 reply.evt.disconnect_reason);
1968 2026
1969 wil->sinfo_gen++; 2027 wil->sinfo_gen++;
1970 wil6210_disconnect(wil, reply.evt.bssid, reason_code, true); 2028 wil6210_disconnect(vif, reply.evt.bssid, reason_code, true);
1971 } 2029 }
1972 return 0; 2030 return 0;
1973} 2031}
1974 2032
1975int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout) 2033int wmi_addba(struct wil6210_priv *wil, u8 mid,
2034 u8 ringid, u8 size, u16 timeout)
1976{ 2035{
1977 struct wmi_vring_ba_en_cmd cmd = { 2036 struct wmi_vring_ba_en_cmd cmd = {
1978 .ringid = ringid, 2037 .ringid = ringid,
@@ -1984,10 +2043,10 @@ int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout)
1984 wil_dbg_wmi(wil, "addba: (ring %d size %d timeout %d)\n", ringid, size, 2043 wil_dbg_wmi(wil, "addba: (ring %d size %d timeout %d)\n", ringid, size,
1985 timeout); 2044 timeout);
1986 2045
1987 return wmi_send(wil, WMI_VRING_BA_EN_CMDID, &cmd, sizeof(cmd)); 2046 return wmi_send(wil, WMI_VRING_BA_EN_CMDID, mid, &cmd, sizeof(cmd));
1988} 2047}
1989 2048
1990int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason) 2049int wmi_delba_tx(struct wil6210_priv *wil, u8 mid, u8 ringid, u16 reason)
1991{ 2050{
1992 struct wmi_vring_ba_dis_cmd cmd = { 2051 struct wmi_vring_ba_dis_cmd cmd = {
1993 .ringid = ringid, 2052 .ringid = ringid,
@@ -1996,10 +2055,10 @@ int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason)
1996 2055
1997 wil_dbg_wmi(wil, "delba_tx: (ring %d reason %d)\n", ringid, reason); 2056 wil_dbg_wmi(wil, "delba_tx: (ring %d reason %d)\n", ringid, reason);
1998 2057
1999 return wmi_send(wil, WMI_VRING_BA_DIS_CMDID, &cmd, sizeof(cmd)); 2058 return wmi_send(wil, WMI_VRING_BA_DIS_CMDID, mid, &cmd, sizeof(cmd));
2000} 2059}
2001 2060
2002int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason) 2061int wmi_delba_rx(struct wil6210_priv *wil, u8 mid, u8 cidxtid, u16 reason)
2003{ 2062{
2004 struct wmi_rcp_delba_cmd cmd = { 2063 struct wmi_rcp_delba_cmd cmd = {
2005 .cidxtid = cidxtid, 2064 .cidxtid = cidxtid,
@@ -2009,10 +2068,11 @@ int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason)
2009 wil_dbg_wmi(wil, "delba_rx: (CID %d TID %d reason %d)\n", cidxtid & 0xf, 2068 wil_dbg_wmi(wil, "delba_rx: (CID %d TID %d reason %d)\n", cidxtid & 0xf,
2010 (cidxtid >> 4) & 0xf, reason); 2069 (cidxtid >> 4) & 0xf, reason);
2011 2070
2012 return wmi_send(wil, WMI_RCP_DELBA_CMDID, &cmd, sizeof(cmd)); 2071 return wmi_send(wil, WMI_RCP_DELBA_CMDID, mid, &cmd, sizeof(cmd));
2013} 2072}
2014 2073
2015int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token, 2074int wmi_addba_rx_resp(struct wil6210_priv *wil,
2075 u8 mid, u8 cid, u8 tid, u8 token,
2016 u16 status, bool amsdu, u16 agg_wsize, u16 timeout) 2076 u16 status, bool amsdu, u16 agg_wsize, u16 timeout)
2017{ 2077{
2018 int rc; 2078 int rc;
@@ -2035,10 +2095,11 @@ int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token,
2035 } __packed reply; 2095 } __packed reply;
2036 2096
2037 wil_dbg_wmi(wil, 2097 wil_dbg_wmi(wil,
2038 "ADDBA response for CID %d TID %d size %d timeout %d status %d AMSDU%s\n", 2098 "ADDBA response for MID %d CID %d TID %d size %d timeout %d status %d AMSDU%s\n",
2039 cid, tid, agg_wsize, timeout, status, amsdu ? "+" : "-"); 2099 mid, cid, tid, agg_wsize,
2100 timeout, status, amsdu ? "+" : "-");
2040 2101
2041 rc = wmi_call(wil, WMI_RCP_ADDBA_RESP_CMDID, &cmd, sizeof(cmd), 2102 rc = wmi_call(wil, WMI_RCP_ADDBA_RESP_CMDID, mid, &cmd, sizeof(cmd),
2042 WMI_RCP_ADDBA_RESP_SENT_EVENTID, &reply, sizeof(reply), 2103 WMI_RCP_ADDBA_RESP_SENT_EVENTID, &reply, sizeof(reply),
2043 100); 2104 100);
2044 if (rc) 2105 if (rc)
@@ -2056,6 +2117,7 @@ int wmi_addba_rx_resp(struct wil6210_priv *wil, u8 cid, u8 tid, u8 token,
2056int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil, 2117int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil,
2057 enum wmi_ps_profile_type ps_profile) 2118 enum wmi_ps_profile_type ps_profile)
2058{ 2119{
2120 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
2059 int rc; 2121 int rc;
2060 struct wmi_ps_dev_profile_cfg_cmd cmd = { 2122 struct wmi_ps_dev_profile_cfg_cmd cmd = {
2061 .ps_profile = ps_profile, 2123 .ps_profile = ps_profile,
@@ -2070,7 +2132,8 @@ int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil,
2070 2132
2071 reply.evt.status = cpu_to_le32(WMI_PS_CFG_CMD_STATUS_ERROR); 2133 reply.evt.status = cpu_to_le32(WMI_PS_CFG_CMD_STATUS_ERROR);
2072 2134
2073 rc = wmi_call(wil, WMI_PS_DEV_PROFILE_CFG_CMDID, &cmd, sizeof(cmd), 2135 rc = wmi_call(wil, WMI_PS_DEV_PROFILE_CFG_CMDID, vif->mid,
2136 &cmd, sizeof(cmd),
2074 WMI_PS_DEV_PROFILE_CFG_EVENTID, &reply, sizeof(reply), 2137 WMI_PS_DEV_PROFILE_CFG_EVENTID, &reply, sizeof(reply),
2075 100); 2138 100);
2076 if (rc) 2139 if (rc)
@@ -2089,6 +2152,7 @@ int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil,
2089 2152
2090int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short) 2153int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short)
2091{ 2154{
2155 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
2092 int rc; 2156 int rc;
2093 struct wmi_set_mgmt_retry_limit_cmd cmd = { 2157 struct wmi_set_mgmt_retry_limit_cmd cmd = {
2094 .mgmt_retry_limit = retry_short, 2158 .mgmt_retry_limit = retry_short,
@@ -2105,7 +2169,8 @@ int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short)
2105 2169
2106 reply.evt.status = WMI_FW_STATUS_FAILURE; 2170 reply.evt.status = WMI_FW_STATUS_FAILURE;
2107 2171
2108 rc = wmi_call(wil, WMI_SET_MGMT_RETRY_LIMIT_CMDID, &cmd, sizeof(cmd), 2172 rc = wmi_call(wil, WMI_SET_MGMT_RETRY_LIMIT_CMDID, vif->mid,
2173 &cmd, sizeof(cmd),
2109 WMI_SET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply), 2174 WMI_SET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply),
2110 100); 2175 100);
2111 if (rc) 2176 if (rc)
@@ -2122,6 +2187,7 @@ int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short)
2122 2187
2123int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short) 2188int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short)
2124{ 2189{
2190 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
2125 int rc; 2191 int rc;
2126 struct { 2192 struct {
2127 struct wmi_cmd_hdr wmi; 2193 struct wmi_cmd_hdr wmi;
@@ -2134,7 +2200,7 @@ int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short)
2134 return -ENOTSUPP; 2200 return -ENOTSUPP;
2135 2201
2136 reply.evt.mgmt_retry_limit = 0; 2202 reply.evt.mgmt_retry_limit = 0;
2137 rc = wmi_call(wil, WMI_GET_MGMT_RETRY_LIMIT_CMDID, NULL, 0, 2203 rc = wmi_call(wil, WMI_GET_MGMT_RETRY_LIMIT_CMDID, vif->mid, NULL, 0,
2138 WMI_GET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply), 2204 WMI_GET_MGMT_RETRY_LIMIT_EVENTID, &reply, sizeof(reply),
2139 100); 2205 100);
2140 if (rc) 2206 if (rc)
@@ -2146,21 +2212,23 @@ int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short)
2146 return 0; 2212 return 0;
2147} 2213}
2148 2214
2149int wmi_abort_scan(struct wil6210_priv *wil) 2215int wmi_abort_scan(struct wil6210_vif *vif)
2150{ 2216{
2217 struct wil6210_priv *wil = vif_to_wil(vif);
2151 int rc; 2218 int rc;
2152 2219
2153 wil_dbg_wmi(wil, "sending WMI_ABORT_SCAN_CMDID\n"); 2220 wil_dbg_wmi(wil, "sending WMI_ABORT_SCAN_CMDID\n");
2154 2221
2155 rc = wmi_send(wil, WMI_ABORT_SCAN_CMDID, NULL, 0); 2222 rc = wmi_send(wil, WMI_ABORT_SCAN_CMDID, vif->mid, NULL, 0);
2156 if (rc) 2223 if (rc)
2157 wil_err(wil, "Failed to abort scan (%d)\n", rc); 2224 wil_err(wil, "Failed to abort scan (%d)\n", rc);
2158 2225
2159 return rc; 2226 return rc;
2160} 2227}
2161 2228
2162int wmi_new_sta(struct wil6210_priv *wil, const u8 *mac, u8 aid) 2229int wmi_new_sta(struct wil6210_vif *vif, const u8 *mac, u8 aid)
2163{ 2230{
2231 struct wil6210_priv *wil = vif_to_wil(vif);
2164 int rc; 2232 int rc;
2165 struct wmi_new_sta_cmd cmd = { 2233 struct wmi_new_sta_cmd cmd = {
2166 .aid = aid, 2234 .aid = aid,
@@ -2170,7 +2238,7 @@ int wmi_new_sta(struct wil6210_priv *wil, const u8 *mac, u8 aid)
2170 2238
2171 ether_addr_copy(cmd.dst_mac, mac); 2239 ether_addr_copy(cmd.dst_mac, mac);
2172 2240
2173 rc = wmi_send(wil, WMI_NEW_STA_CMDID, &cmd, sizeof(cmd)); 2241 rc = wmi_send(wil, WMI_NEW_STA_CMDID, vif->mid, &cmd, sizeof(cmd));
2174 if (rc) 2242 if (rc)
2175 wil_err(wil, "Failed to send new sta (%d)\n", rc); 2243 wil_err(wil, "Failed to send new sta (%d)\n", rc);
2176 2244
@@ -2206,6 +2274,7 @@ static const char *suspend_status2name(u8 status)
2206 2274
2207int wmi_suspend(struct wil6210_priv *wil) 2275int wmi_suspend(struct wil6210_priv *wil)
2208{ 2276{
2277 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
2209 int rc; 2278 int rc;
2210 struct wmi_traffic_suspend_cmd cmd = { 2279 struct wmi_traffic_suspend_cmd cmd = {
2211 .wakeup_trigger = wil->wakeup_trigger, 2280 .wakeup_trigger = wil->wakeup_trigger,
@@ -2221,7 +2290,8 @@ int wmi_suspend(struct wil6210_priv *wil)
2221 2290
2222 reply.evt.status = WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE; 2291 reply.evt.status = WMI_TRAFFIC_SUSPEND_REJECTED_LINK_NOT_IDLE;
2223 2292
2224 rc = wmi_call(wil, WMI_TRAFFIC_SUSPEND_CMDID, &cmd, sizeof(cmd), 2293 rc = wmi_call(wil, WMI_TRAFFIC_SUSPEND_CMDID, vif->mid,
2294 &cmd, sizeof(cmd),
2225 WMI_TRAFFIC_SUSPEND_EVENTID, &reply, sizeof(reply), 2295 WMI_TRAFFIC_SUSPEND_EVENTID, &reply, sizeof(reply),
2226 suspend_to); 2296 suspend_to);
2227 if (rc) { 2297 if (rc) {
@@ -2289,6 +2359,7 @@ static void resume_triggers2string(u32 triggers, char *string, int str_size)
2289 2359
2290int wmi_resume(struct wil6210_priv *wil) 2360int wmi_resume(struct wil6210_priv *wil)
2291{ 2361{
2362 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
2292 int rc; 2363 int rc;
2293 char string[100]; 2364 char string[100];
2294 struct { 2365 struct {
@@ -2299,7 +2370,7 @@ int wmi_resume(struct wil6210_priv *wil)
2299 reply.evt.status = WMI_TRAFFIC_RESUME_FAILED; 2370 reply.evt.status = WMI_TRAFFIC_RESUME_FAILED;
2300 reply.evt.resume_triggers = WMI_RESUME_TRIGGER_UNKNOWN; 2371 reply.evt.resume_triggers = WMI_RESUME_TRIGGER_UNKNOWN;
2301 2372
2302 rc = wmi_call(wil, WMI_TRAFFIC_RESUME_CMDID, NULL, 0, 2373 rc = wmi_call(wil, WMI_TRAFFIC_RESUME_CMDID, vif->mid, NULL, 0,
2303 WMI_TRAFFIC_RESUME_EVENTID, &reply, sizeof(reply), 2374 WMI_TRAFFIC_RESUME_EVENTID, &reply, sizeof(reply),
2304 WIL_WAIT_FOR_SUSPEND_RESUME_COMP); 2375 WIL_WAIT_FOR_SUSPEND_RESUME_COMP);
2305 if (rc) 2376 if (rc)
@@ -2313,14 +2384,100 @@ int wmi_resume(struct wil6210_priv *wil)
2313 return reply.evt.status; 2384 return reply.evt.status;
2314} 2385}
2315 2386
2316static bool wmi_evt_call_handler(struct wil6210_priv *wil, int id, 2387int wmi_port_allocate(struct wil6210_priv *wil, u8 mid,
2388 const u8 *mac, enum nl80211_iftype iftype)
2389{
2390 int rc;
2391 struct wmi_port_allocate_cmd cmd = {
2392 .mid = mid,
2393 };
2394 struct {
2395 struct wmi_cmd_hdr wmi;
2396 struct wmi_port_allocated_event evt;
2397 } __packed reply;
2398
2399 wil_dbg_misc(wil, "port allocate, mid %d iftype %d, mac %pM\n",
2400 mid, iftype, mac);
2401
2402 ether_addr_copy(cmd.mac, mac);
2403 switch (iftype) {
2404 case NL80211_IFTYPE_STATION:
2405 cmd.port_role = WMI_PORT_STA;
2406 break;
2407 case NL80211_IFTYPE_AP:
2408 cmd.port_role = WMI_PORT_AP;
2409 break;
2410 case NL80211_IFTYPE_P2P_CLIENT:
2411 cmd.port_role = WMI_PORT_P2P_CLIENT;
2412 break;
2413 case NL80211_IFTYPE_P2P_GO:
2414 cmd.port_role = WMI_PORT_P2P_GO;
2415 break;
2416 /* what about monitor??? */
2417 default:
2418 wil_err(wil, "unsupported iftype: %d\n", iftype);
2419 return -EINVAL;
2420 }
2421
2422 reply.evt.status = WMI_FW_STATUS_FAILURE;
2423
2424 rc = wmi_call(wil, WMI_PORT_ALLOCATE_CMDID, mid,
2425 &cmd, sizeof(cmd),
2426 WMI_PORT_ALLOCATED_EVENTID, &reply,
2427 sizeof(reply), 300);
2428 if (rc) {
2429 wil_err(wil, "failed to allocate port, status %d\n", rc);
2430 return rc;
2431 }
2432 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) {
2433 wil_err(wil, "WMI_PORT_ALLOCATE returned status %d\n",
2434 reply.evt.status);
2435 return -EINVAL;
2436 }
2437
2438 return 0;
2439}
2440
2441int wmi_port_delete(struct wil6210_priv *wil, u8 mid)
2442{
2443 int rc;
2444 struct wmi_port_delete_cmd cmd = {
2445 .mid = mid,
2446 };
2447 struct {
2448 struct wmi_cmd_hdr wmi;
2449 struct wmi_port_deleted_event evt;
2450 } __packed reply;
2451
2452 wil_dbg_misc(wil, "port delete, mid %d\n", mid);
2453
2454 reply.evt.status = WMI_FW_STATUS_FAILURE;
2455
2456 rc = wmi_call(wil, WMI_PORT_DELETE_CMDID, mid,
2457 &cmd, sizeof(cmd),
2458 WMI_PORT_DELETED_EVENTID, &reply,
2459 sizeof(reply), 2000);
2460 if (rc) {
2461 wil_err(wil, "failed to delete port, status %d\n", rc);
2462 return rc;
2463 }
2464 if (reply.evt.status != WMI_FW_STATUS_SUCCESS) {
2465 wil_err(wil, "WMI_PORT_DELETE returned status %d\n",
2466 reply.evt.status);
2467 return -EINVAL;
2468 }
2469
2470 return 0;
2471}
2472
2473static bool wmi_evt_call_handler(struct wil6210_vif *vif, int id,
2317 void *d, int len) 2474 void *d, int len)
2318{ 2475{
2319 uint i; 2476 uint i;
2320 2477
2321 for (i = 0; i < ARRAY_SIZE(wmi_evt_handlers); i++) { 2478 for (i = 0; i < ARRAY_SIZE(wmi_evt_handlers); i++) {
2322 if (wmi_evt_handlers[i].eventid == id) { 2479 if (wmi_evt_handlers[i].eventid == id) {
2323 wmi_evt_handlers[i].handler(wil, id, d, len); 2480 wmi_evt_handlers[i].handler(vif, id, d, len);
2324 return true; 2481 return true;
2325 } 2482 }
2326 } 2483 }
@@ -2332,19 +2489,39 @@ static void wmi_event_handle(struct wil6210_priv *wil,
2332 struct wil6210_mbox_hdr *hdr) 2489 struct wil6210_mbox_hdr *hdr)
2333{ 2490{
2334 u16 len = le16_to_cpu(hdr->len); 2491 u16 len = le16_to_cpu(hdr->len);
2492 struct wil6210_vif *vif;
2335 2493
2336 if ((hdr->type == WIL_MBOX_HDR_TYPE_WMI) && 2494 if ((hdr->type == WIL_MBOX_HDR_TYPE_WMI) &&
2337 (len >= sizeof(struct wmi_cmd_hdr))) { 2495 (len >= sizeof(struct wmi_cmd_hdr))) {
2338 struct wmi_cmd_hdr *wmi = (void *)(&hdr[1]); 2496 struct wmi_cmd_hdr *wmi = (void *)(&hdr[1]);
2339 void *evt_data = (void *)(&wmi[1]); 2497 void *evt_data = (void *)(&wmi[1]);
2340 u16 id = le16_to_cpu(wmi->command_id); 2498 u16 id = le16_to_cpu(wmi->command_id);
2499 u8 mid = wmi->mid;
2500
2501 wil_dbg_wmi(wil, "Handle %s (0x%04x) (reply_id 0x%04x,%d)\n",
2502 eventid2name(id), id, wil->reply_id,
2503 wil->reply_mid);
2504
2505 if (mid == MID_BROADCAST)
2506 mid = 0;
2507 if (mid >= wil->max_vifs) {
2508 wil_dbg_wmi(wil, "invalid mid %d, event skipped\n",
2509 mid);
2510 return;
2511 }
2512 vif = wil->vifs[mid];
2513 if (!vif) {
2514 wil_dbg_wmi(wil, "event for empty VIF(%d), skipped\n",
2515 mid);
2516 return;
2517 }
2341 2518
2342 wil_dbg_wmi(wil, "Handle %s (0x%04x) (reply_id 0x%04x)\n",
2343 eventid2name(id), id, wil->reply_id);
2344 /* check if someone waits for this event */ 2519 /* check if someone waits for this event */
2345 if (wil->reply_id && wil->reply_id == id) { 2520 if (wil->reply_id && wil->reply_id == id &&
2521 wil->reply_mid == mid) {
2346 WARN_ON(wil->reply_buf); 2522 WARN_ON(wil->reply_buf);
2347 wmi_evt_call_handler(wil, id, evt_data, 2523
2524 wmi_evt_call_handler(vif, id, evt_data,
2348 len - sizeof(*wmi)); 2525 len - sizeof(*wmi));
2349 wil_dbg_wmi(wil, "event_handle: Complete WMI 0x%04x\n", 2526 wil_dbg_wmi(wil, "event_handle: Complete WMI 0x%04x\n",
2350 id); 2527 id);
@@ -2353,7 +2530,7 @@ static void wmi_event_handle(struct wil6210_priv *wil,
2353 } 2530 }
2354 /* unsolicited event */ 2531 /* unsolicited event */
2355 /* search for handler */ 2532 /* search for handler */
2356 if (!wmi_evt_call_handler(wil, id, evt_data, 2533 if (!wmi_evt_call_handler(vif, id, evt_data,
2357 len - sizeof(*wmi))) { 2534 len - sizeof(*wmi))) {
2358 wil_info(wil, "Unhandled event 0x%04x\n", id); 2535 wil_info(wil, "Unhandled event 0x%04x\n", id);
2359 } 2536 }
@@ -2523,6 +2700,7 @@ wmi_sched_scan_set_plans(struct wil6210_priv *wil,
2523int wmi_start_sched_scan(struct wil6210_priv *wil, 2700int wmi_start_sched_scan(struct wil6210_priv *wil,
2524 struct cfg80211_sched_scan_request *request) 2701 struct cfg80211_sched_scan_request *request)
2525{ 2702{
2703 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
2526 int rc; 2704 int rc;
2527 struct wmi_start_sched_scan_cmd cmd = { 2705 struct wmi_start_sched_scan_cmd cmd = {
2528 .min_rssi_threshold = S8_MIN, 2706 .min_rssi_threshold = S8_MIN,
@@ -2549,7 +2727,8 @@ int wmi_start_sched_scan(struct wil6210_priv *wil,
2549 2727
2550 reply.evt.result = WMI_PNO_REJECT; 2728 reply.evt.result = WMI_PNO_REJECT;
2551 2729
2552 rc = wmi_call(wil, WMI_START_SCHED_SCAN_CMDID, &cmd, sizeof(cmd), 2730 rc = wmi_call(wil, WMI_START_SCHED_SCAN_CMDID, vif->mid,
2731 &cmd, sizeof(cmd),
2553 WMI_START_SCHED_SCAN_EVENTID, &reply, sizeof(reply), 2732 WMI_START_SCHED_SCAN_EVENTID, &reply, sizeof(reply),
2554 WIL_WMI_CALL_GENERAL_TO_MS); 2733 WIL_WMI_CALL_GENERAL_TO_MS);
2555 if (rc) 2734 if (rc)
@@ -2566,6 +2745,7 @@ int wmi_start_sched_scan(struct wil6210_priv *wil,
2566 2745
2567int wmi_stop_sched_scan(struct wil6210_priv *wil) 2746int wmi_stop_sched_scan(struct wil6210_priv *wil)
2568{ 2747{
2748 struct wil6210_vif *vif = ndev_to_vif(wil->main_ndev);
2569 int rc; 2749 int rc;
2570 struct { 2750 struct {
2571 struct wmi_cmd_hdr wmi; 2751 struct wmi_cmd_hdr wmi;
@@ -2577,7 +2757,7 @@ int wmi_stop_sched_scan(struct wil6210_priv *wil)
2577 2757
2578 reply.evt.result = WMI_PNO_REJECT; 2758 reply.evt.result = WMI_PNO_REJECT;
2579 2759
2580 rc = wmi_call(wil, WMI_STOP_SCHED_SCAN_CMDID, NULL, 0, 2760 rc = wmi_call(wil, WMI_STOP_SCHED_SCAN_CMDID, vif->mid, NULL, 0,
2581 WMI_STOP_SCHED_SCAN_EVENTID, &reply, sizeof(reply), 2761 WMI_STOP_SCHED_SCAN_EVENTID, &reply, sizeof(reply),
2582 WIL_WMI_CALL_GENERAL_TO_MS); 2762 WIL_WMI_CALL_GENERAL_TO_MS);
2583 if (rc) 2763 if (rc)