1 /*
2 * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com>
3 *
4 * 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 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18
19 #include <linux/module.h>
20 #include <linux/firmware.h>
21 #include <linux/platform_device.h>
22 #include <linux/of_address.h>
23 #include <linux/of_device.h>
24 #include <linux/of_irq.h>
25 #include <linux/rpmsg.h>
26 #include <linux/soc/qcom/smem_state.h>
27 #include <linux/soc/qcom/wcnss_ctrl.h>
28 #include <net/ipv6.h>
29 #include "wcn36xx.h"
30 #include "testmode.h"
31 #include "firmware.h"
32
33 unsigned int wcn36xx_dbg_mask;
34 module_param_named(debug_mask, wcn36xx_dbg_mask, uint, 0644);
35 MODULE_PARM_DESC(debug_mask, "Debugging mask");
36
37 #define CHAN2G(_freq, _idx) { \
38 .band = NL80211_BAND_2GHZ, \
39 .center_freq = (_freq), \
40 .hw_value = (_idx), \
41 .max_power = 25, \
42 }
43
44 #define CHAN5G(_freq, _idx, _phy_val) { \
45 .band = NL80211_BAND_5GHZ, \
46 .center_freq = (_freq), \
47 .hw_value = (_phy_val) << HW_VALUE_PHY_SHIFT | HW_VALUE_CHANNEL(_idx), \
48 .max_power = 25, \
49 }
50
51 /* The wcn firmware expects channel values to matching
52 * their mnemonic values. So use these for .hw_value. */
53 static struct ieee80211_channel wcn_2ghz_channels[] = {
54 CHAN2G(2412, 1), /* Channel 1 */
55 CHAN2G(2417, 2), /* Channel 2 */
56 CHAN2G(2422, 3), /* Channel 3 */
57 CHAN2G(2427, 4), /* Channel 4 */
58 CHAN2G(2432, 5), /* Channel 5 */
59 CHAN2G(2437, 6), /* Channel 6 */
60 CHAN2G(2442, 7), /* Channel 7 */
61 CHAN2G(2447, 8), /* Channel 8 */
62 CHAN2G(2452, 9), /* Channel 9 */
63 CHAN2G(2457, 10), /* Channel 10 */
64 CHAN2G(2462, 11), /* Channel 11 */
65 CHAN2G(2467, 12), /* Channel 12 */
66 CHAN2G(2472, 13), /* Channel 13 */
67 CHAN2G(2484, 14) /* Channel 14 */
68
69 };
70
71 static struct ieee80211_channel wcn_5ghz_channels[] = {
72 CHAN5G(5180, 36, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW),
73 CHAN5G(5200, 40, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW),
74 CHAN5G(5220, 44, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH),
75 CHAN5G(5240, 48, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH),
76 CHAN5G(5260, 52, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW),
77 CHAN5G(5280, 56, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW),
78 CHAN5G(5300, 60, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH),
79 CHAN5G(5320, 64, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH),
80 CHAN5G(5500, 100, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW),
81 CHAN5G(5520, 104, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW),
82 CHAN5G(5540, 108, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH),
83 CHAN5G(5560, 112, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH),
84 CHAN5G(5580, 116, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW),
85 CHAN5G(5600, 120, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW),
86 CHAN5G(5620, 124, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH),
87 CHAN5G(5640, 128, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH),
88 CHAN5G(5660, 132, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW),
89 CHAN5G(5680, 136, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW),
90 CHAN5G(5700, 140, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH),
91 CHAN5G(5720, 144, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH),
92 CHAN5G(5745, 149, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW),
93 CHAN5G(5765, 153, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW),
94 CHAN5G(5785, 157, PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH),
95 CHAN5G(5805, 161, PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH),
96 CHAN5G(5825, 165, 0)
97 };
98
99 #define RATE(_bitrate, _hw_rate, _flags) { \
100 .bitrate = (_bitrate), \
101 .flags = (_flags), \
102 .hw_value = (_hw_rate), \
103 .hw_value_short = (_hw_rate) \
104 }
105
106 static struct ieee80211_rate wcn_2ghz_rates[] = {
107 RATE(10, HW_RATE_INDEX_1MBPS, 0),
108 RATE(20, HW_RATE_INDEX_2MBPS, IEEE80211_RATE_SHORT_PREAMBLE),
109 RATE(55, HW_RATE_INDEX_5_5MBPS, IEEE80211_RATE_SHORT_PREAMBLE),
110 RATE(110, HW_RATE_INDEX_11MBPS, IEEE80211_RATE_SHORT_PREAMBLE),
111 RATE(60, HW_RATE_INDEX_6MBPS, 0),
112 RATE(90, HW_RATE_INDEX_9MBPS, 0),
113 RATE(120, HW_RATE_INDEX_12MBPS, 0),
114 RATE(180, HW_RATE_INDEX_18MBPS, 0),
115 RATE(240, HW_RATE_INDEX_24MBPS, 0),
116 RATE(360, HW_RATE_INDEX_36MBPS, 0),
117 RATE(480, HW_RATE_INDEX_48MBPS, 0),
118 RATE(540, HW_RATE_INDEX_54MBPS, 0)
119 };
120
121 static struct ieee80211_rate wcn_5ghz_rates[] = {
122 RATE(60, HW_RATE_INDEX_6MBPS, 0),
123 RATE(90, HW_RATE_INDEX_9MBPS, 0),
124 RATE(120, HW_RATE_INDEX_12MBPS, 0),
125 RATE(180, HW_RATE_INDEX_18MBPS, 0),
126 RATE(240, HW_RATE_INDEX_24MBPS, 0),
127 RATE(360, HW_RATE_INDEX_36MBPS, 0),
128 RATE(480, HW_RATE_INDEX_48MBPS, 0),
129 RATE(540, HW_RATE_INDEX_54MBPS, 0)
130 };
131
132 static struct ieee80211_supported_band wcn_band_2ghz = {
133 .channels = wcn_2ghz_channels,
134 .n_channels = ARRAY_SIZE(wcn_2ghz_channels),
135 .bitrates = wcn_2ghz_rates,
136 .n_bitrates = ARRAY_SIZE(wcn_2ghz_rates),
137 .ht_cap = {
138 .cap = IEEE80211_HT_CAP_GRN_FLD |
139 IEEE80211_HT_CAP_SGI_20 |
140 IEEE80211_HT_CAP_DSSSCCK40 |
141 IEEE80211_HT_CAP_LSIG_TXOP_PROT |
142 IEEE80211_HT_CAP_SGI_40 |
143 IEEE80211_HT_CAP_SUP_WIDTH_20_40,
144 .ht_supported = true,
145 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
146 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
147 .mcs = {
148 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
149 .rx_highest = cpu_to_le16(72),
150 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
151 }
152 }
153 };
154
155 static struct ieee80211_supported_band wcn_band_5ghz = {
156 .channels = wcn_5ghz_channels,
157 .n_channels = ARRAY_SIZE(wcn_5ghz_channels),
158 .bitrates = wcn_5ghz_rates,
159 .n_bitrates = ARRAY_SIZE(wcn_5ghz_rates),
160 .ht_cap = {
161 .cap = IEEE80211_HT_CAP_GRN_FLD |
162 IEEE80211_HT_CAP_SGI_20 |
163 IEEE80211_HT_CAP_DSSSCCK40 |
164 IEEE80211_HT_CAP_LSIG_TXOP_PROT |
165 IEEE80211_HT_CAP_SGI_40 |
166 IEEE80211_HT_CAP_SUP_WIDTH_20_40,
167 .ht_supported = true,
168 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
169 .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
170 .mcs = {
171 .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
172 .rx_highest = cpu_to_le16(150),
173 .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
174 }
175 }
176 };
177
178 #ifdef CONFIG_PM
179
180 static const struct wiphy_wowlan_support wowlan_support = {
181 .flags = WIPHY_WOWLAN_ANY |
182 WIPHY_WOWLAN_MAGIC_PKT |
183 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY
184 };
185
186 #endif
187
get_sta_index(struct ieee80211_vif * vif,struct wcn36xx_sta * sta_priv)188 static inline u8 get_sta_index(struct ieee80211_vif *vif,
189 struct wcn36xx_sta *sta_priv)
190 {
191 return NL80211_IFTYPE_STATION == vif->type ?
192 sta_priv->bss_sta_index :
193 sta_priv->sta_index;
194 }
195
wcn36xx_feat_caps_info(struct wcn36xx * wcn)196 static void wcn36xx_feat_caps_info(struct wcn36xx *wcn)
197 {
198 int i;
199
200 for (i = 0; i < MAX_FEATURE_SUPPORTED; i++) {
201 if (wcn36xx_firmware_get_feat_caps(wcn->fw_feat_caps, i)) {
202 wcn36xx_dbg(WCN36XX_DBG_MAC, "FW Cap %s\n",
203 wcn36xx_firmware_get_cap_name(i));
204 }
205 }
206 }
207
wcn36xx_start(struct ieee80211_hw * hw)208 static int wcn36xx_start(struct ieee80211_hw *hw)
209 {
210 struct wcn36xx *wcn = hw->priv;
211 int ret;
212
213 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac start\n");
214
215 /* SMD initialization */
216 ret = wcn36xx_smd_open(wcn);
217 if (ret) {
218 wcn36xx_err("Failed to open smd channel: %d\n", ret);
219 goto out_err;
220 }
221
222 /* Allocate memory pools for Mgmt BD headers and Data BD headers */
223 ret = wcn36xx_dxe_allocate_mem_pools(wcn);
224 if (ret) {
225 wcn36xx_err("Failed to alloc DXE mempool: %d\n", ret);
226 goto out_smd_close;
227 }
228
229 ret = wcn36xx_dxe_alloc_ctl_blks(wcn);
230 if (ret) {
231 wcn36xx_err("Failed to alloc DXE ctl blocks: %d\n", ret);
232 goto out_free_dxe_pool;
233 }
234
235 ret = wcn36xx_smd_load_nv(wcn);
236 if (ret) {
237 wcn36xx_err("Failed to push NV to chip\n");
238 goto out_free_dxe_ctl;
239 }
240
241 ret = wcn36xx_smd_start(wcn);
242 if (ret) {
243 wcn36xx_err("Failed to start chip\n");
244 goto out_free_dxe_ctl;
245 }
246
247 if (!wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) {
248 ret = wcn36xx_smd_feature_caps_exchange(wcn);
249 if (ret)
250 wcn36xx_warn("Exchange feature caps failed\n");
251 else
252 wcn36xx_feat_caps_info(wcn);
253 }
254
255 /* DMA channel initialization */
256 ret = wcn36xx_dxe_init(wcn);
257 if (ret) {
258 wcn36xx_err("DXE init failed\n");
259 goto out_smd_stop;
260 }
261
262 wcn36xx_debugfs_init(wcn);
263
264 INIT_LIST_HEAD(&wcn->vif_list);
265 spin_lock_init(&wcn->dxe_lock);
266 spin_lock_init(&wcn->survey_lock);
267
268 return 0;
269
270 out_smd_stop:
271 wcn36xx_smd_stop(wcn);
272 out_free_dxe_ctl:
273 wcn36xx_dxe_free_ctl_blks(wcn);
274 out_free_dxe_pool:
275 wcn36xx_dxe_free_mem_pools(wcn);
276 out_smd_close:
277 wcn36xx_smd_close(wcn);
278 out_err:
279 return ret;
280 }
281
wcn36xx_stop(struct ieee80211_hw * hw)282 static void wcn36xx_stop(struct ieee80211_hw *hw)
283 {
284 struct wcn36xx *wcn = hw->priv;
285
286 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac stop\n");
287
288 mutex_lock(&wcn->scan_lock);
289 if (wcn->scan_req) {
290 struct cfg80211_scan_info scan_info = {
291 .aborted = true,
292 };
293
294 ieee80211_scan_completed(wcn->hw, &scan_info);
295 }
296 wcn->scan_req = NULL;
297 mutex_unlock(&wcn->scan_lock);
298
299 wcn36xx_debugfs_exit(wcn);
300 wcn36xx_smd_stop(wcn);
301 wcn36xx_dxe_deinit(wcn);
302 wcn36xx_smd_close(wcn);
303
304 wcn36xx_dxe_free_mem_pools(wcn);
305 wcn36xx_dxe_free_ctl_blks(wcn);
306 }
307
wcn36xx_change_ps(struct wcn36xx * wcn,bool enable)308 static void wcn36xx_change_ps(struct wcn36xx *wcn, bool enable)
309 {
310 struct ieee80211_vif *vif = NULL;
311 struct wcn36xx_vif *tmp;
312
313 list_for_each_entry(tmp, &wcn->vif_list, list) {
314 vif = wcn36xx_priv_to_vif(tmp);
315 if (enable && !wcn->sw_scan) {
316 if (vif->cfg.ps) /* ps allowed ? */
317 wcn36xx_pmc_enter_bmps_state(wcn, vif);
318 } else {
319 wcn36xx_pmc_exit_bmps_state(wcn, vif);
320 }
321 }
322 }
323
wcn36xx_change_opchannel(struct wcn36xx * wcn,int ch)324 static void wcn36xx_change_opchannel(struct wcn36xx *wcn, int ch)
325 {
326 struct ieee80211_vif *vif = NULL;
327 struct wcn36xx_vif *tmp;
328 struct ieee80211_supported_band *band;
329 struct ieee80211_channel *channel = NULL;
330 unsigned long flags;
331 int i, j;
332
333 for (i = 0; i < ARRAY_SIZE(wcn->hw->wiphy->bands); i++) {
334 band = wcn->hw->wiphy->bands[i];
335 if (!band)
336 break;
337 for (j = 0; j < band->n_channels; j++) {
338 if (HW_VALUE_CHANNEL(band->channels[j].hw_value) == ch) {
339 channel = &band->channels[j];
340 break;
341 }
342 }
343 if (channel)
344 break;
345 }
346
347 if (!channel) {
348 wcn36xx_err("Cannot tune to channel %d\n", ch);
349 return;
350 }
351
352 spin_lock_irqsave(&wcn->survey_lock, flags);
353 wcn->band = band;
354 wcn->channel = channel;
355 spin_unlock_irqrestore(&wcn->survey_lock, flags);
356
357 list_for_each_entry(tmp, &wcn->vif_list, list) {
358 vif = wcn36xx_priv_to_vif(tmp);
359 wcn36xx_smd_switch_channel(wcn, vif, ch);
360 }
361
362 return;
363 }
364
wcn36xx_config(struct ieee80211_hw * hw,u32 changed)365 static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed)
366 {
367 struct wcn36xx *wcn = hw->priv;
368 int ret;
369
370 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac config changed 0x%08x\n", changed);
371
372 mutex_lock(&wcn->conf_mutex);
373
374 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
375 int ch = WCN36XX_HW_CHANNEL(wcn);
376 wcn36xx_dbg(WCN36XX_DBG_MAC, "wcn36xx_config channel switch=%d\n",
377 ch);
378
379 if (wcn->sw_scan_opchannel == ch && wcn->sw_scan_channel) {
380 /* If channel is the initial operating channel, we may
381 * want to receive/transmit regular data packets, then
382 * simply stop the scan session and exit PS mode.
383 */
384 if (wcn->sw_scan_channel)
385 wcn36xx_smd_end_scan(wcn, wcn->sw_scan_channel);
386 if (wcn->sw_scan_init) {
387 wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN,
388 wcn->sw_scan_vif);
389 }
390 } else if (wcn->sw_scan) {
391 /* A scan is ongoing, do not change the operating
392 * channel, but start a scan session on the channel.
393 */
394 if (wcn->sw_scan_channel)
395 wcn36xx_smd_end_scan(wcn, wcn->sw_scan_channel);
396 if (!wcn->sw_scan_init) {
397 /* This can fail if we are unable to notify the
398 * operating channel.
399 */
400 ret = wcn36xx_smd_init_scan(wcn,
401 HAL_SYS_MODE_SCAN,
402 wcn->sw_scan_vif);
403 if (ret) {
404 mutex_unlock(&wcn->conf_mutex);
405 return -EIO;
406 }
407 }
408 wcn36xx_smd_start_scan(wcn, ch);
409 } else {
410 wcn36xx_change_opchannel(wcn, ch);
411 }
412 }
413
414 if (changed & IEEE80211_CONF_CHANGE_PS)
415 wcn36xx_change_ps(wcn, hw->conf.flags & IEEE80211_CONF_PS);
416
417 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
418 if (hw->conf.flags & IEEE80211_CONF_IDLE)
419 wcn36xx_smd_enter_imps(wcn);
420 else
421 wcn36xx_smd_exit_imps(wcn);
422 }
423
424 mutex_unlock(&wcn->conf_mutex);
425
426 return 0;
427 }
428
wcn36xx_configure_filter(struct ieee80211_hw * hw,unsigned int changed,unsigned int * total,u64 multicast)429 static void wcn36xx_configure_filter(struct ieee80211_hw *hw,
430 unsigned int changed,
431 unsigned int *total, u64 multicast)
432 {
433 struct wcn36xx_hal_rcv_flt_mc_addr_list_type *fp;
434 struct wcn36xx *wcn = hw->priv;
435 struct wcn36xx_vif *tmp;
436 struct ieee80211_vif *vif = NULL;
437
438 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac configure filter\n");
439
440 mutex_lock(&wcn->conf_mutex);
441
442 *total &= FIF_ALLMULTI;
443
444 fp = (void *)(unsigned long)multicast;
445 list_for_each_entry(tmp, &wcn->vif_list, list) {
446 vif = wcn36xx_priv_to_vif(tmp);
447
448 /* FW handles MC filtering only when connected as STA */
449 if (*total & FIF_ALLMULTI)
450 wcn36xx_smd_set_mc_list(wcn, vif, NULL);
451 else if (NL80211_IFTYPE_STATION == vif->type && tmp->sta_assoc)
452 wcn36xx_smd_set_mc_list(wcn, vif, fp);
453 }
454
455 mutex_unlock(&wcn->conf_mutex);
456 kfree(fp);
457 }
458
wcn36xx_prepare_multicast(struct ieee80211_hw * hw,struct netdev_hw_addr_list * mc_list)459 static u64 wcn36xx_prepare_multicast(struct ieee80211_hw *hw,
460 struct netdev_hw_addr_list *mc_list)
461 {
462 struct wcn36xx_hal_rcv_flt_mc_addr_list_type *fp;
463 struct netdev_hw_addr *ha;
464
465 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac prepare multicast list\n");
466 fp = kzalloc(sizeof(*fp), GFP_ATOMIC);
467 if (!fp) {
468 wcn36xx_err("Out of memory setting filters.\n");
469 return 0;
470 }
471
472 fp->mc_addr_count = 0;
473 /* update multicast filtering parameters */
474 if (netdev_hw_addr_list_count(mc_list) <=
475 WCN36XX_HAL_MAX_NUM_MULTICAST_ADDRESS) {
476 netdev_hw_addr_list_for_each(ha, mc_list) {
477 memcpy(fp->mc_addr[fp->mc_addr_count],
478 ha->addr, ETH_ALEN);
479 fp->mc_addr_count++;
480 }
481 }
482
483 return (u64)(unsigned long)fp;
484 }
485
wcn36xx_tx(struct ieee80211_hw * hw,struct ieee80211_tx_control * control,struct sk_buff * skb)486 static void wcn36xx_tx(struct ieee80211_hw *hw,
487 struct ieee80211_tx_control *control,
488 struct sk_buff *skb)
489 {
490 struct wcn36xx *wcn = hw->priv;
491 struct wcn36xx_sta *sta_priv = NULL;
492
493 if (control->sta)
494 sta_priv = wcn36xx_sta_to_priv(control->sta);
495
496 if (wcn36xx_start_tx(wcn, sta_priv, skb))
497 ieee80211_free_txskb(wcn->hw, skb);
498 }
499
wcn36xx_set_key(struct ieee80211_hw * hw,enum set_key_cmd cmd,struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct ieee80211_key_conf * key_conf)500 static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
501 struct ieee80211_vif *vif,
502 struct ieee80211_sta *sta,
503 struct ieee80211_key_conf *key_conf)
504 {
505 struct wcn36xx *wcn = hw->priv;
506 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
507 struct wcn36xx_sta *sta_priv = sta ? wcn36xx_sta_to_priv(sta) : NULL;
508 int ret = 0;
509 u8 key[WLAN_MAX_KEY_LEN];
510
511 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac80211 set key\n");
512 wcn36xx_dbg(WCN36XX_DBG_MAC, "Key: cmd=0x%x algo:0x%x, id:%d, len:%d flags 0x%x\n",
513 cmd, key_conf->cipher, key_conf->keyidx,
514 key_conf->keylen, key_conf->flags);
515 wcn36xx_dbg_dump(WCN36XX_DBG_MAC, "KEY: ",
516 key_conf->key,
517 key_conf->keylen);
518
519 mutex_lock(&wcn->conf_mutex);
520
521 switch (key_conf->cipher) {
522 case WLAN_CIPHER_SUITE_WEP40:
523 vif_priv->encrypt_type = WCN36XX_HAL_ED_WEP40;
524 break;
525 case WLAN_CIPHER_SUITE_WEP104:
526 vif_priv->encrypt_type = WCN36XX_HAL_ED_WEP104;
527 break;
528 case WLAN_CIPHER_SUITE_CCMP:
529 vif_priv->encrypt_type = WCN36XX_HAL_ED_CCMP;
530 break;
531 case WLAN_CIPHER_SUITE_TKIP:
532 vif_priv->encrypt_type = WCN36XX_HAL_ED_TKIP;
533 break;
534 default:
535 wcn36xx_err("Unsupported key type 0x%x\n",
536 key_conf->cipher);
537 ret = -EOPNOTSUPP;
538 goto out;
539 }
540
541 switch (cmd) {
542 case SET_KEY:
543 if (WCN36XX_HAL_ED_TKIP == vif_priv->encrypt_type) {
544 /*
545 * Supplicant is sending key in the wrong order:
546 * Temporal Key (16 b) - TX MIC (8 b) - RX MIC (8 b)
547 * but HW expects it to be in the order as described in
548 * IEEE 802.11 spec (see chapter 11.7) like this:
549 * Temporal Key (16 b) - RX MIC (8 b) - TX MIC (8 b)
550 */
551 memcpy(key, key_conf->key, 16);
552 memcpy(key + 16, key_conf->key + 24, 8);
553 memcpy(key + 24, key_conf->key + 16, 8);
554 } else {
555 memcpy(key, key_conf->key, key_conf->keylen);
556 }
557
558 if (IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags) {
559 sta_priv->is_data_encrypted = true;
560 /* Reconfigure bss with encrypt_type */
561 if (NL80211_IFTYPE_STATION == vif->type) {
562 wcn36xx_smd_config_bss(wcn,
563 vif,
564 sta,
565 sta->addr,
566 true);
567 wcn36xx_smd_config_sta(wcn, vif, sta);
568 }
569
570 wcn36xx_smd_set_stakey(wcn,
571 vif_priv->encrypt_type,
572 key_conf->keyidx,
573 key_conf->keylen,
574 key,
575 get_sta_index(vif, sta_priv));
576 } else {
577 wcn36xx_smd_set_bsskey(wcn,
578 vif_priv->encrypt_type,
579 vif_priv->bss_index,
580 key_conf->keyidx,
581 key_conf->keylen,
582 key);
583
584 if ((WLAN_CIPHER_SUITE_WEP40 == key_conf->cipher) ||
585 (WLAN_CIPHER_SUITE_WEP104 == key_conf->cipher)) {
586 list_for_each_entry(sta_priv,
587 &vif_priv->sta_list, list) {
588 sta_priv->is_data_encrypted = true;
589 wcn36xx_smd_set_stakey(wcn,
590 vif_priv->encrypt_type,
591 key_conf->keyidx,
592 key_conf->keylen,
593 key,
594 get_sta_index(vif, sta_priv));
595 }
596 }
597 }
598 break;
599 case DISABLE_KEY:
600 if (!(IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags)) {
601 if (vif_priv->bss_index != WCN36XX_HAL_BSS_INVALID_IDX)
602 wcn36xx_smd_remove_bsskey(wcn,
603 vif_priv->encrypt_type,
604 vif_priv->bss_index,
605 key_conf->keyidx);
606
607 vif_priv->encrypt_type = WCN36XX_HAL_ED_NONE;
608 } else {
609 sta_priv->is_data_encrypted = false;
610 /* do not remove key if disassociated */
611 if (sta_priv->aid)
612 wcn36xx_smd_remove_stakey(wcn,
613 vif_priv->encrypt_type,
614 key_conf->keyidx,
615 get_sta_index(vif, sta_priv));
616 }
617 break;
618 default:
619 wcn36xx_err("Unsupported key cmd 0x%x\n", cmd);
620 ret = -EOPNOTSUPP;
621 goto out;
622 }
623
624 out:
625 mutex_unlock(&wcn->conf_mutex);
626
627 return ret;
628 }
629
wcn36xx_hw_scan(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_scan_request * hw_req)630 static int wcn36xx_hw_scan(struct ieee80211_hw *hw,
631 struct ieee80211_vif *vif,
632 struct ieee80211_scan_request *hw_req)
633 {
634 struct wcn36xx *wcn = hw->priv;
635
636 if (!wcn36xx_firmware_get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) {
637 /* fallback to mac80211 software scan */
638 return 1;
639 }
640
641 /* Firmware scan offload is limited to 48 channels, fallback to
642 * software driven scanning otherwise.
643 */
644 if (hw_req->req.n_channels > 48) {
645 wcn36xx_warn("Offload scan aborted, n_channels=%u",
646 hw_req->req.n_channels);
647 return 1;
648 }
649
650 mutex_lock(&wcn->scan_lock);
651 if (wcn->scan_req) {
652 mutex_unlock(&wcn->scan_lock);
653 return -EBUSY;
654 }
655
656 wcn->scan_aborted = false;
657 wcn->scan_req = &hw_req->req;
658
659 mutex_unlock(&wcn->scan_lock);
660
661 wcn36xx_smd_update_channel_list(wcn, &hw_req->req);
662 return wcn36xx_smd_start_hw_scan(wcn, vif, &hw_req->req);
663 }
664
wcn36xx_cancel_hw_scan(struct ieee80211_hw * hw,struct ieee80211_vif * vif)665 static void wcn36xx_cancel_hw_scan(struct ieee80211_hw *hw,
666 struct ieee80211_vif *vif)
667 {
668 struct wcn36xx *wcn = hw->priv;
669
670 mutex_lock(&wcn->scan_lock);
671 wcn->scan_aborted = true;
672 mutex_unlock(&wcn->scan_lock);
673
674 if (wcn36xx_firmware_get_feat_caps(wcn->fw_feat_caps, SCAN_OFFLOAD)) {
675 /* ieee80211_scan_completed will be called on FW scan
676 * indication */
677 wcn36xx_smd_stop_hw_scan(wcn);
678 }
679 }
680
wcn36xx_sw_scan_start(struct ieee80211_hw * hw,struct ieee80211_vif * vif,const u8 * mac_addr)681 static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw,
682 struct ieee80211_vif *vif,
683 const u8 *mac_addr)
684 {
685 struct wcn36xx *wcn = hw->priv;
686 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
687
688 wcn36xx_dbg(WCN36XX_DBG_MAC, "sw_scan_start");
689
690 wcn->sw_scan = true;
691 wcn->sw_scan_vif = vif;
692 wcn->sw_scan_channel = 0;
693 if (vif_priv->sta_assoc)
694 wcn->sw_scan_opchannel = WCN36XX_HW_CHANNEL(wcn);
695 else
696 wcn->sw_scan_opchannel = 0;
697 }
698
wcn36xx_sw_scan_complete(struct ieee80211_hw * hw,struct ieee80211_vif * vif)699 static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw,
700 struct ieee80211_vif *vif)
701 {
702 struct wcn36xx *wcn = hw->priv;
703
704 wcn36xx_dbg(WCN36XX_DBG_MAC, "sw_scan_complete");
705
706 /* ensure that any scan session is finished */
707 if (wcn->sw_scan_channel)
708 wcn36xx_smd_end_scan(wcn, wcn->sw_scan_channel);
709 if (wcn->sw_scan_init) {
710 wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN,
711 wcn->sw_scan_vif);
712 }
713 wcn->sw_scan = false;
714 wcn->sw_scan_opchannel = 0;
715 }
716
wcn36xx_update_allowed_rates(struct ieee80211_sta * sta,enum nl80211_band band)717 static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta,
718 enum nl80211_band band)
719 {
720 int i, size;
721 u16 *rates_table;
722 struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta);
723 u32 rates = sta->deflink.supp_rates[band];
724
725 memset(&sta_priv->supported_rates, 0,
726 sizeof(sta_priv->supported_rates));
727 sta_priv->supported_rates.op_rate_mode = STA_11n;
728
729 size = ARRAY_SIZE(sta_priv->supported_rates.dsss_rates);
730 rates_table = sta_priv->supported_rates.dsss_rates;
731 if (band == NL80211_BAND_2GHZ) {
732 for (i = 0; i < size; i++) {
733 if (rates & 0x01) {
734 rates_table[i] = wcn_2ghz_rates[i].hw_value;
735 rates = rates >> 1;
736 }
737 }
738 }
739
740 size = ARRAY_SIZE(sta_priv->supported_rates.ofdm_rates);
741 rates_table = sta_priv->supported_rates.ofdm_rates;
742 for (i = 0; i < size; i++) {
743 if (rates & 0x01) {
744 rates_table[i] = wcn_5ghz_rates[i].hw_value;
745 rates = rates >> 1;
746 }
747 }
748
749 if (sta->deflink.ht_cap.ht_supported) {
750 BUILD_BUG_ON(sizeof(sta->deflink.ht_cap.mcs.rx_mask) >
751 sizeof(sta_priv->supported_rates.supported_mcs_set));
752 memcpy(sta_priv->supported_rates.supported_mcs_set,
753 sta->deflink.ht_cap.mcs.rx_mask,
754 sizeof(sta->deflink.ht_cap.mcs.rx_mask));
755 }
756
757 if (sta->deflink.vht_cap.vht_supported) {
758 sta_priv->supported_rates.op_rate_mode = STA_11ac;
759 sta_priv->supported_rates.vht_rx_mcs_map =
760 sta->deflink.vht_cap.vht_mcs.rx_mcs_map;
761 sta_priv->supported_rates.vht_tx_mcs_map =
762 sta->deflink.vht_cap.vht_mcs.tx_mcs_map;
763 }
764 }
765
wcn36xx_set_default_rates(struct wcn36xx_hal_supported_rates * rates)766 void wcn36xx_set_default_rates(struct wcn36xx_hal_supported_rates *rates)
767 {
768 u16 ofdm_rates[WCN36XX_HAL_NUM_OFDM_RATES] = {
769 HW_RATE_INDEX_6MBPS,
770 HW_RATE_INDEX_9MBPS,
771 HW_RATE_INDEX_12MBPS,
772 HW_RATE_INDEX_18MBPS,
773 HW_RATE_INDEX_24MBPS,
774 HW_RATE_INDEX_36MBPS,
775 HW_RATE_INDEX_48MBPS,
776 HW_RATE_INDEX_54MBPS
777 };
778 u16 dsss_rates[WCN36XX_HAL_NUM_DSSS_RATES] = {
779 HW_RATE_INDEX_1MBPS,
780 HW_RATE_INDEX_2MBPS,
781 HW_RATE_INDEX_5_5MBPS,
782 HW_RATE_INDEX_11MBPS
783 };
784
785 rates->op_rate_mode = STA_11n;
786 memcpy(rates->dsss_rates, dsss_rates,
787 sizeof(*dsss_rates) * WCN36XX_HAL_NUM_DSSS_RATES);
788 memcpy(rates->ofdm_rates, ofdm_rates,
789 sizeof(*ofdm_rates) * WCN36XX_HAL_NUM_OFDM_RATES);
790 rates->supported_mcs_set[0] = 0xFF;
791 }
792
wcn36xx_set_default_rates_v1(struct wcn36xx_hal_supported_rates_v1 * rates)793 void wcn36xx_set_default_rates_v1(struct wcn36xx_hal_supported_rates_v1 *rates)
794 {
795 rates->op_rate_mode = STA_11ac;
796 rates->vht_rx_mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9;
797 rates->vht_tx_mcs_map = IEEE80211_VHT_MCS_SUPPORT_0_9;
798 }
799
wcn36xx_bss_info_changed(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_bss_conf * bss_conf,u64 changed)800 static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
801 struct ieee80211_vif *vif,
802 struct ieee80211_bss_conf *bss_conf,
803 u64 changed)
804 {
805 struct wcn36xx *wcn = hw->priv;
806 struct sk_buff *skb = NULL;
807 u16 tim_off, tim_len;
808 enum wcn36xx_hal_link_state link_state;
809 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
810
811 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss info changed vif %p changed 0x%llx\n",
812 vif, changed);
813
814 mutex_lock(&wcn->conf_mutex);
815
816 if (changed & BSS_CHANGED_BEACON_INFO) {
817 wcn36xx_dbg(WCN36XX_DBG_MAC,
818 "mac bss changed dtim period %d\n",
819 bss_conf->dtim_period);
820
821 vif_priv->dtim_period = bss_conf->dtim_period;
822 }
823
824 if (changed & BSS_CHANGED_BSSID) {
825 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss changed_bssid %pM\n",
826 bss_conf->bssid);
827
828 if (!is_zero_ether_addr(bss_conf->bssid)) {
829 vif_priv->is_joining = true;
830 vif_priv->bss_index = WCN36XX_HAL_BSS_INVALID_IDX;
831 wcn36xx_smd_set_link_st(wcn, bss_conf->bssid, vif->addr,
832 WCN36XX_HAL_LINK_PREASSOC_STATE);
833 wcn36xx_smd_join(wcn, bss_conf->bssid,
834 vif->addr, WCN36XX_HW_CHANNEL(wcn));
835 wcn36xx_smd_config_bss(wcn, vif, NULL,
836 bss_conf->bssid, false);
837 } else {
838 vif_priv->is_joining = false;
839 wcn36xx_smd_delete_bss(wcn, vif);
840 wcn36xx_smd_set_link_st(wcn, bss_conf->bssid, vif->addr,
841 WCN36XX_HAL_LINK_IDLE_STATE);
842 vif_priv->encrypt_type = WCN36XX_HAL_ED_NONE;
843 }
844 }
845
846 if (changed & BSS_CHANGED_SSID) {
847 wcn36xx_dbg(WCN36XX_DBG_MAC,
848 "mac bss changed ssid\n");
849 wcn36xx_dbg_dump(WCN36XX_DBG_MAC, "ssid ",
850 vif->cfg.ssid, vif->cfg.ssid_len);
851
852 vif_priv->ssid.length = vif->cfg.ssid_len;
853 memcpy(&vif_priv->ssid.ssid,
854 vif->cfg.ssid,
855 vif->cfg.ssid_len);
856 }
857
858 if (changed & BSS_CHANGED_ASSOC) {
859 vif_priv->is_joining = false;
860 if (vif->cfg.assoc) {
861 struct ieee80211_sta *sta;
862 struct wcn36xx_sta *sta_priv;
863
864 wcn36xx_dbg(WCN36XX_DBG_MAC,
865 "mac assoc bss %pM vif %pM AID=%d\n",
866 bss_conf->bssid,
867 vif->addr,
868 vif->cfg.aid);
869
870 vif_priv->sta_assoc = true;
871
872 /*
873 * Holding conf_mutex ensures mutal exclusion with
874 * wcn36xx_sta_remove() and as such ensures that sta
875 * won't be freed while we're operating on it. As such
876 * we do not need to hold the rcu_read_lock().
877 */
878 sta = ieee80211_find_sta(vif, bss_conf->bssid);
879 if (!sta) {
880 wcn36xx_err("sta %pM is not found\n",
881 bss_conf->bssid);
882 goto out;
883 }
884 sta_priv = wcn36xx_sta_to_priv(sta);
885
886 wcn36xx_update_allowed_rates(sta, WCN36XX_BAND(wcn));
887
888 wcn36xx_smd_set_link_st(wcn, bss_conf->bssid,
889 vif->addr,
890 WCN36XX_HAL_LINK_POSTASSOC_STATE);
891 wcn36xx_smd_config_bss(wcn, vif, sta,
892 bss_conf->bssid,
893 true);
894 sta_priv->aid = vif->cfg.aid;
895 /*
896 * config_sta must be called from because this is the
897 * place where AID is available.
898 */
899 wcn36xx_smd_config_sta(wcn, vif, sta);
900 if (vif->type == NL80211_IFTYPE_STATION)
901 wcn36xx_smd_add_beacon_filter(wcn, vif);
902 wcn36xx_enable_keep_alive_null_packet(wcn, vif);
903 } else {
904 wcn36xx_dbg(WCN36XX_DBG_MAC,
905 "disassociated bss %pM vif %pM AID=%d\n",
906 bss_conf->bssid,
907 vif->addr,
908 vif->cfg.aid);
909 vif_priv->sta_assoc = false;
910 wcn36xx_smd_set_link_st(wcn,
911 bss_conf->bssid,
912 vif->addr,
913 WCN36XX_HAL_LINK_IDLE_STATE);
914 }
915 }
916
917 if (changed & BSS_CHANGED_AP_PROBE_RESP) {
918 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss changed ap probe resp\n");
919 skb = ieee80211_proberesp_get(hw, vif);
920 if (!skb) {
921 wcn36xx_err("failed to alloc probereq skb\n");
922 goto out;
923 }
924
925 wcn36xx_smd_update_proberesp_tmpl(wcn, vif, skb);
926 dev_kfree_skb(skb);
927 }
928
929 if (changed & BSS_CHANGED_BEACON_ENABLED ||
930 changed & BSS_CHANGED_BEACON) {
931 wcn36xx_dbg(WCN36XX_DBG_MAC,
932 "mac bss changed beacon enabled %d\n",
933 bss_conf->enable_beacon);
934
935 if (bss_conf->enable_beacon) {
936 vif_priv->dtim_period = bss_conf->dtim_period;
937 vif_priv->bss_index = WCN36XX_HAL_BSS_INVALID_IDX;
938 wcn36xx_smd_config_bss(wcn, vif, NULL,
939 vif->addr, false);
940 skb = ieee80211_beacon_get_tim(hw, vif, &tim_off,
941 &tim_len, 0);
942 if (!skb) {
943 wcn36xx_err("failed to alloc beacon skb\n");
944 goto out;
945 }
946 wcn36xx_smd_send_beacon(wcn, vif, skb, tim_off, 0);
947 dev_kfree_skb(skb);
948
949 if (vif->type == NL80211_IFTYPE_ADHOC ||
950 vif->type == NL80211_IFTYPE_MESH_POINT)
951 link_state = WCN36XX_HAL_LINK_IBSS_STATE;
952 else
953 link_state = WCN36XX_HAL_LINK_AP_STATE;
954
955 wcn36xx_smd_set_link_st(wcn, vif->addr, vif->addr,
956 link_state);
957 } else {
958 wcn36xx_smd_delete_bss(wcn, vif);
959 wcn36xx_smd_set_link_st(wcn, vif->addr, vif->addr,
960 WCN36XX_HAL_LINK_IDLE_STATE);
961 }
962 }
963 out:
964
965 mutex_unlock(&wcn->conf_mutex);
966 }
967
968 /* this is required when using IEEE80211_HW_HAS_RATE_CONTROL */
wcn36xx_set_rts_threshold(struct ieee80211_hw * hw,u32 value)969 static int wcn36xx_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
970 {
971 struct wcn36xx *wcn = hw->priv;
972 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac set RTS threshold %d\n", value);
973
974 mutex_lock(&wcn->conf_mutex);
975 wcn36xx_smd_update_cfg(wcn, WCN36XX_HAL_CFG_RTS_THRESHOLD, value);
976 mutex_unlock(&wcn->conf_mutex);
977
978 return 0;
979 }
980
wcn36xx_remove_interface(struct ieee80211_hw * hw,struct ieee80211_vif * vif)981 static void wcn36xx_remove_interface(struct ieee80211_hw *hw,
982 struct ieee80211_vif *vif)
983 {
984 struct wcn36xx *wcn = hw->priv;
985 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
986 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac remove interface vif %p\n", vif);
987
988 mutex_lock(&wcn->conf_mutex);
989
990 list_del(&vif_priv->list);
991 wcn36xx_smd_delete_sta_self(wcn, vif->addr);
992
993 mutex_unlock(&wcn->conf_mutex);
994 }
995
wcn36xx_add_interface(struct ieee80211_hw * hw,struct ieee80211_vif * vif)996 static int wcn36xx_add_interface(struct ieee80211_hw *hw,
997 struct ieee80211_vif *vif)
998 {
999 struct wcn36xx *wcn = hw->priv;
1000 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
1001
1002 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac add interface vif %p type %d\n",
1003 vif, vif->type);
1004
1005 if (!(NL80211_IFTYPE_STATION == vif->type ||
1006 NL80211_IFTYPE_AP == vif->type ||
1007 NL80211_IFTYPE_ADHOC == vif->type ||
1008 NL80211_IFTYPE_MESH_POINT == vif->type)) {
1009 wcn36xx_warn("Unsupported interface type requested: %d\n",
1010 vif->type);
1011 return -EOPNOTSUPP;
1012 }
1013
1014 mutex_lock(&wcn->conf_mutex);
1015
1016 vif_priv->bss_index = WCN36XX_HAL_BSS_INVALID_IDX;
1017 INIT_LIST_HEAD(&vif_priv->sta_list);
1018 list_add(&vif_priv->list, &wcn->vif_list);
1019 wcn36xx_smd_add_sta_self(wcn, vif);
1020
1021 mutex_unlock(&wcn->conf_mutex);
1022
1023 return 0;
1024 }
1025
wcn36xx_sta_add(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_sta * sta)1026 static int wcn36xx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1027 struct ieee80211_sta *sta)
1028 {
1029 struct wcn36xx *wcn = hw->priv;
1030 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
1031 struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta);
1032 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta add vif %p sta %pM\n",
1033 vif, sta->addr);
1034
1035 mutex_lock(&wcn->conf_mutex);
1036
1037 spin_lock_init(&sta_priv->ampdu_lock);
1038 sta_priv->vif = vif_priv;
1039 list_add(&sta_priv->list, &vif_priv->sta_list);
1040
1041 /*
1042 * For STA mode HW will be configured on BSS_CHANGED_ASSOC because
1043 * at this stage AID is not available yet.
1044 */
1045 if (NL80211_IFTYPE_STATION != vif->type) {
1046 wcn36xx_update_allowed_rates(sta, WCN36XX_BAND(wcn));
1047 sta_priv->aid = sta->aid;
1048 wcn36xx_smd_config_sta(wcn, vif, sta);
1049 }
1050
1051 mutex_unlock(&wcn->conf_mutex);
1052
1053 return 0;
1054 }
1055
wcn36xx_sta_remove(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_sta * sta)1056 static int wcn36xx_sta_remove(struct ieee80211_hw *hw,
1057 struct ieee80211_vif *vif,
1058 struct ieee80211_sta *sta)
1059 {
1060 struct wcn36xx *wcn = hw->priv;
1061 struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(sta);
1062
1063 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta remove vif %p sta %pM index %d\n",
1064 vif, sta->addr, sta_priv->sta_index);
1065
1066 mutex_lock(&wcn->conf_mutex);
1067
1068 list_del(&sta_priv->list);
1069 wcn36xx_smd_delete_sta(wcn, sta_priv->sta_index);
1070 sta_priv->vif = NULL;
1071
1072 mutex_unlock(&wcn->conf_mutex);
1073
1074 return 0;
1075 }
1076
1077 #ifdef CONFIG_PM
1078
wcn36xx_get_first_assoc_vif(struct wcn36xx * wcn)1079 static struct ieee80211_vif *wcn36xx_get_first_assoc_vif(struct wcn36xx *wcn)
1080 {
1081 struct wcn36xx_vif *vif_priv = NULL;
1082 struct ieee80211_vif *vif = NULL;
1083
1084 list_for_each_entry(vif_priv, &wcn->vif_list, list) {
1085 if (vif_priv->sta_assoc) {
1086 vif = wcn36xx_priv_to_vif(vif_priv);
1087 break;
1088 }
1089 }
1090 return vif;
1091 }
1092
wcn36xx_suspend(struct ieee80211_hw * hw,struct cfg80211_wowlan * wow)1093 static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow)
1094 {
1095 struct wcn36xx *wcn = hw->priv;
1096 struct ieee80211_vif *vif = NULL;
1097 int ret = 0;
1098
1099 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac suspend\n");
1100
1101 mutex_lock(&wcn->conf_mutex);
1102
1103 vif = wcn36xx_get_first_assoc_vif(wcn);
1104 if (vif) {
1105 ret = wcn36xx_smd_arp_offload(wcn, vif, true);
1106 if (ret)
1107 goto out;
1108 ret = wcn36xx_smd_ipv6_ns_offload(wcn, vif, true);
1109 if (ret)
1110 goto out;
1111 ret = wcn36xx_smd_gtk_offload(wcn, vif, true);
1112 if (ret)
1113 goto out;
1114 ret = wcn36xx_smd_set_power_params(wcn, true);
1115 if (ret)
1116 goto out;
1117 ret = wcn36xx_smd_wlan_host_suspend_ind(wcn);
1118 }
1119
1120 /* Disable IRQ, we don't want to handle any packet before mac80211 is
1121 * resumed and ready to receive packets.
1122 */
1123 disable_irq(wcn->tx_irq);
1124 disable_irq(wcn->rx_irq);
1125
1126 out:
1127 mutex_unlock(&wcn->conf_mutex);
1128 return ret;
1129 }
1130
wcn36xx_resume(struct ieee80211_hw * hw)1131 static int wcn36xx_resume(struct ieee80211_hw *hw)
1132 {
1133 struct wcn36xx *wcn = hw->priv;
1134 struct ieee80211_vif *vif = NULL;
1135
1136 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac resume\n");
1137
1138 mutex_lock(&wcn->conf_mutex);
1139 vif = wcn36xx_get_first_assoc_vif(wcn);
1140 if (vif) {
1141 wcn36xx_smd_host_resume(wcn);
1142 wcn36xx_smd_set_power_params(wcn, false);
1143 wcn36xx_smd_gtk_offload_get_info(wcn, vif);
1144 wcn36xx_smd_gtk_offload(wcn, vif, false);
1145 wcn36xx_smd_ipv6_ns_offload(wcn, vif, false);
1146 wcn36xx_smd_arp_offload(wcn, vif, false);
1147 }
1148
1149 enable_irq(wcn->tx_irq);
1150 enable_irq(wcn->rx_irq);
1151
1152 mutex_unlock(&wcn->conf_mutex);
1153
1154 return 0;
1155 }
1156
wcn36xx_set_rekey_data(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct cfg80211_gtk_rekey_data * data)1157 static void wcn36xx_set_rekey_data(struct ieee80211_hw *hw,
1158 struct ieee80211_vif *vif,
1159 struct cfg80211_gtk_rekey_data *data)
1160 {
1161 struct wcn36xx *wcn = hw->priv;
1162 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
1163
1164 mutex_lock(&wcn->conf_mutex);
1165
1166 memcpy(vif_priv->rekey_data.kek, data->kek, NL80211_KEK_LEN);
1167 memcpy(vif_priv->rekey_data.kck, data->kck, NL80211_KCK_LEN);
1168 vif_priv->rekey_data.replay_ctr =
1169 cpu_to_le64(be64_to_cpup((__be64 *)data->replay_ctr));
1170 vif_priv->rekey_data.valid = true;
1171
1172 mutex_unlock(&wcn->conf_mutex);
1173 }
1174
1175 #endif
1176
wcn36xx_ampdu_action(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_ampdu_params * params)1177 static int wcn36xx_ampdu_action(struct ieee80211_hw *hw,
1178 struct ieee80211_vif *vif,
1179 struct ieee80211_ampdu_params *params)
1180 {
1181 struct wcn36xx *wcn = hw->priv;
1182 struct wcn36xx_sta *sta_priv = wcn36xx_sta_to_priv(params->sta);
1183 struct ieee80211_sta *sta = params->sta;
1184 enum ieee80211_ampdu_mlme_action action = params->action;
1185 u16 tid = params->tid;
1186 u16 *ssn = ¶ms->ssn;
1187 int ret = 0;
1188 int session;
1189
1190 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n",
1191 action, tid);
1192
1193 mutex_lock(&wcn->conf_mutex);
1194
1195 switch (action) {
1196 case IEEE80211_AMPDU_RX_START:
1197 sta_priv->tid = tid;
1198 session = wcn36xx_smd_add_ba_session(wcn, sta, tid, ssn, 0,
1199 get_sta_index(vif, sta_priv));
1200 if (session < 0) {
1201 ret = session;
1202 goto out;
1203 }
1204 wcn36xx_smd_add_ba(wcn, session);
1205 break;
1206 case IEEE80211_AMPDU_RX_STOP:
1207 wcn36xx_smd_del_ba(wcn, tid, 0, get_sta_index(vif, sta_priv));
1208 break;
1209 case IEEE80211_AMPDU_TX_START:
1210 spin_lock_bh(&sta_priv->ampdu_lock);
1211 sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_START;
1212 spin_unlock_bh(&sta_priv->ampdu_lock);
1213
1214 /* Replace the mac80211 ssn with the firmware one */
1215 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu ssn = %u\n", *ssn);
1216 wcn36xx_smd_trigger_ba(wcn, get_sta_index(vif, sta_priv), tid, ssn);
1217 wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu fw-ssn = %u\n", *ssn);
1218
1219 /* Start BA session */
1220 session = wcn36xx_smd_add_ba_session(wcn, sta, tid, ssn, 1,
1221 get_sta_index(vif, sta_priv));
1222 if (session < 0) {
1223 ret = session;
1224 goto out;
1225 }
1226 ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
1227 break;
1228 case IEEE80211_AMPDU_TX_OPERATIONAL:
1229 spin_lock_bh(&sta_priv->ampdu_lock);
1230 sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_OPERATIONAL;
1231 spin_unlock_bh(&sta_priv->ampdu_lock);
1232
1233 break;
1234 case IEEE80211_AMPDU_TX_STOP_FLUSH:
1235 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
1236 case IEEE80211_AMPDU_TX_STOP_CONT:
1237 spin_lock_bh(&sta_priv->ampdu_lock);
1238 sta_priv->ampdu_state[tid] = WCN36XX_AMPDU_NONE;
1239 spin_unlock_bh(&sta_priv->ampdu_lock);
1240
1241 wcn36xx_smd_del_ba(wcn, tid, 1, get_sta_index(vif, sta_priv));
1242 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1243 break;
1244 default:
1245 wcn36xx_err("Unknown AMPDU action\n");
1246 }
1247
1248 out:
1249 mutex_unlock(&wcn->conf_mutex);
1250
1251 return ret;
1252 }
1253
1254 #if IS_ENABLED(CONFIG_IPV6)
wcn36xx_ipv6_addr_change(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct inet6_dev * idev)1255 static void wcn36xx_ipv6_addr_change(struct ieee80211_hw *hw,
1256 struct ieee80211_vif *vif,
1257 struct inet6_dev *idev)
1258 {
1259 struct wcn36xx_vif *vif_priv = wcn36xx_vif_to_priv(vif);
1260 struct inet6_ifaddr *ifa;
1261 int idx = 0;
1262
1263 memset(vif_priv->tentative_addrs, 0, sizeof(vif_priv->tentative_addrs));
1264
1265 read_lock_bh(&idev->lock);
1266 list_for_each_entry(ifa, &idev->addr_list, if_list) {
1267 vif_priv->target_ipv6_addrs[idx] = ifa->addr;
1268 if (ifa->flags & IFA_F_TENTATIVE)
1269 __set_bit(idx, vif_priv->tentative_addrs);
1270 idx++;
1271 if (idx >= WCN36XX_HAL_IPV6_OFFLOAD_ADDR_MAX)
1272 break;
1273 wcn36xx_dbg(WCN36XX_DBG_MAC, "%pI6 %s\n", &ifa->addr,
1274 (ifa->flags & IFA_F_TENTATIVE) ? "tentative" : NULL);
1275 }
1276 read_unlock_bh(&idev->lock);
1277
1278 vif_priv->num_target_ipv6_addrs = idx;
1279 }
1280 #endif
1281
wcn36xx_flush(struct ieee80211_hw * hw,struct ieee80211_vif * vif,u32 queues,bool drop)1282 static void wcn36xx_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1283 u32 queues, bool drop)
1284 {
1285 struct wcn36xx *wcn = hw->priv;
1286
1287 if (wcn36xx_dxe_tx_flush(wcn)) {
1288 wcn36xx_err("Failed to flush hardware tx queues\n");
1289 }
1290 }
1291
wcn36xx_get_survey(struct ieee80211_hw * hw,int idx,struct survey_info * survey)1292 static int wcn36xx_get_survey(struct ieee80211_hw *hw, int idx,
1293 struct survey_info *survey)
1294 {
1295 struct wcn36xx *wcn = hw->priv;
1296 struct ieee80211_supported_band *sband;
1297 struct wcn36xx_chan_survey *chan_survey;
1298 int band_idx;
1299 unsigned long flags;
1300
1301 sband = wcn->hw->wiphy->bands[NL80211_BAND_2GHZ];
1302 band_idx = idx;
1303 if (band_idx >= sband->n_channels) {
1304 band_idx -= sband->n_channels;
1305 sband = wcn->hw->wiphy->bands[NL80211_BAND_5GHZ];
1306 }
1307
1308 if (!sband || band_idx >= sband->n_channels)
1309 return -ENOENT;
1310
1311 spin_lock_irqsave(&wcn->survey_lock, flags);
1312
1313 chan_survey = &wcn->chan_survey[idx];
1314 survey->channel = &sband->channels[band_idx];
1315 survey->noise = chan_survey->rssi - chan_survey->snr;
1316 survey->filled = 0;
1317
1318 if (chan_survey->rssi > -100 && chan_survey->rssi < 0)
1319 survey->filled |= SURVEY_INFO_NOISE_DBM;
1320
1321 if (survey->channel == wcn->channel)
1322 survey->filled |= SURVEY_INFO_IN_USE;
1323
1324 spin_unlock_irqrestore(&wcn->survey_lock, flags);
1325
1326 wcn36xx_dbg(WCN36XX_DBG_MAC,
1327 "ch %d rssi %d snr %d noise %d filled %x freq %d\n",
1328 HW_VALUE_CHANNEL(survey->channel->hw_value),
1329 chan_survey->rssi, chan_survey->snr, survey->noise,
1330 survey->filled, survey->channel->center_freq);
1331
1332 return 0;
1333 }
1334
wcn36xx_sta_statistics(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct station_info * sinfo)1335 static void wcn36xx_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1336 struct ieee80211_sta *sta, struct station_info *sinfo)
1337 {
1338 struct wcn36xx *wcn;
1339 u8 sta_index;
1340 int status;
1341
1342 wcn = hw->priv;
1343 sta_index = get_sta_index(vif, wcn36xx_sta_to_priv(sta));
1344 status = wcn36xx_smd_get_stats(wcn, sta_index, HAL_GLOBAL_CLASS_A_STATS_INFO, sinfo);
1345
1346 if (status)
1347 wcn36xx_err("wcn36xx_smd_get_stats failed\n");
1348 }
1349
1350 static const struct ieee80211_ops wcn36xx_ops = {
1351 .start = wcn36xx_start,
1352 .stop = wcn36xx_stop,
1353 .add_interface = wcn36xx_add_interface,
1354 .remove_interface = wcn36xx_remove_interface,
1355 #ifdef CONFIG_PM
1356 .suspend = wcn36xx_suspend,
1357 .resume = wcn36xx_resume,
1358 .set_rekey_data = wcn36xx_set_rekey_data,
1359 #endif
1360 .config = wcn36xx_config,
1361 .prepare_multicast = wcn36xx_prepare_multicast,
1362 .configure_filter = wcn36xx_configure_filter,
1363 .tx = wcn36xx_tx,
1364 .set_key = wcn36xx_set_key,
1365 .hw_scan = wcn36xx_hw_scan,
1366 .cancel_hw_scan = wcn36xx_cancel_hw_scan,
1367 .sw_scan_start = wcn36xx_sw_scan_start,
1368 .sw_scan_complete = wcn36xx_sw_scan_complete,
1369 .bss_info_changed = wcn36xx_bss_info_changed,
1370 .set_rts_threshold = wcn36xx_set_rts_threshold,
1371 .sta_add = wcn36xx_sta_add,
1372 .sta_remove = wcn36xx_sta_remove,
1373 .sta_statistics = wcn36xx_sta_statistics,
1374 .ampdu_action = wcn36xx_ampdu_action,
1375 #if IS_ENABLED(CONFIG_IPV6)
1376 .ipv6_addr_change = wcn36xx_ipv6_addr_change,
1377 #endif
1378 .flush = wcn36xx_flush,
1379 .get_survey = wcn36xx_get_survey,
1380
1381 CFG80211_TESTMODE_CMD(wcn36xx_tm_cmd)
1382 };
1383
1384 static void
wcn36xx_set_ieee80211_vht_caps(struct ieee80211_sta_vht_cap * vht_cap)1385 wcn36xx_set_ieee80211_vht_caps(struct ieee80211_sta_vht_cap *vht_cap)
1386 {
1387 vht_cap->vht_supported = true;
1388
1389 vht_cap->cap = (IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 |
1390 IEEE80211_VHT_CAP_SHORT_GI_80 |
1391 IEEE80211_VHT_CAP_RXSTBC_1 |
1392 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
1393 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
1394 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT |
1395 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
1396
1397 vht_cap->vht_mcs.rx_mcs_map =
1398 cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 |
1399 IEEE80211_VHT_MCS_NOT_SUPPORTED << 2 |
1400 IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
1401 IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
1402 IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
1403 IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
1404 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
1405 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);
1406
1407 vht_cap->vht_mcs.rx_highest = cpu_to_le16(433);
1408 vht_cap->vht_mcs.tx_highest = vht_cap->vht_mcs.rx_highest;
1409
1410 vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
1411 }
1412
wcn36xx_init_ieee80211(struct wcn36xx * wcn)1413 static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
1414 {
1415 static const u32 cipher_suites[] = {
1416 WLAN_CIPHER_SUITE_WEP40,
1417 WLAN_CIPHER_SUITE_WEP104,
1418 WLAN_CIPHER_SUITE_TKIP,
1419 WLAN_CIPHER_SUITE_CCMP,
1420 };
1421
1422 ieee80211_hw_set(wcn->hw, TIMING_BEACON_ONLY);
1423 ieee80211_hw_set(wcn->hw, AMPDU_AGGREGATION);
1424 ieee80211_hw_set(wcn->hw, SUPPORTS_PS);
1425 ieee80211_hw_set(wcn->hw, SIGNAL_DBM);
1426 ieee80211_hw_set(wcn->hw, HAS_RATE_CONTROL);
1427 ieee80211_hw_set(wcn->hw, SINGLE_SCAN_ON_ALL_BANDS);
1428 ieee80211_hw_set(wcn->hw, REPORTS_TX_ACK_STATUS);
1429
1430 wcn->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1431 BIT(NL80211_IFTYPE_AP) |
1432 BIT(NL80211_IFTYPE_ADHOC) |
1433 BIT(NL80211_IFTYPE_MESH_POINT);
1434
1435 wcn->hw->wiphy->bands[NL80211_BAND_2GHZ] = &wcn_band_2ghz;
1436 if (wcn->rf_id != RF_IRIS_WCN3620)
1437 wcn->hw->wiphy->bands[NL80211_BAND_5GHZ] = &wcn_band_5ghz;
1438
1439 if (wcn->rf_id == RF_IRIS_WCN3680)
1440 wcn36xx_set_ieee80211_vht_caps(&wcn_band_5ghz.vht_cap);
1441
1442 wcn->hw->wiphy->max_scan_ssids = WCN36XX_MAX_SCAN_SSIDS;
1443 wcn->hw->wiphy->max_scan_ie_len = WCN36XX_MAX_SCAN_IE_LEN;
1444
1445 wcn->hw->wiphy->cipher_suites = cipher_suites;
1446 wcn->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
1447
1448 #ifdef CONFIG_PM
1449 wcn->hw->wiphy->wowlan = &wowlan_support;
1450 #endif
1451
1452 wcn->hw->max_listen_interval = 200;
1453
1454 wcn->hw->queues = 4;
1455
1456 SET_IEEE80211_DEV(wcn->hw, wcn->dev);
1457
1458 wcn->hw->sta_data_size = sizeof(struct wcn36xx_sta);
1459 wcn->hw->vif_data_size = sizeof(struct wcn36xx_vif);
1460
1461 wiphy_ext_feature_set(wcn->hw->wiphy,
1462 NL80211_EXT_FEATURE_CQM_RSSI_LIST);
1463
1464 return 0;
1465 }
1466
wcn36xx_platform_get_resources(struct wcn36xx * wcn,struct platform_device * pdev)1467 static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
1468 struct platform_device *pdev)
1469 {
1470 struct device_node *mmio_node;
1471 struct device_node *iris_node;
1472 int index;
1473 int ret;
1474
1475 /* Set TX IRQ */
1476 ret = platform_get_irq_byname(pdev, "tx");
1477 if (ret < 0)
1478 return ret;
1479 wcn->tx_irq = ret;
1480
1481 /* Set RX IRQ */
1482 ret = platform_get_irq_byname(pdev, "rx");
1483 if (ret < 0)
1484 return ret;
1485 wcn->rx_irq = ret;
1486
1487 /* Acquire SMSM tx enable handle */
1488 wcn->tx_enable_state = qcom_smem_state_get(&pdev->dev,
1489 "tx-enable", &wcn->tx_enable_state_bit);
1490 if (IS_ERR(wcn->tx_enable_state)) {
1491 wcn36xx_err("failed to get tx-enable state\n");
1492 return PTR_ERR(wcn->tx_enable_state);
1493 }
1494
1495 /* Acquire SMSM tx rings empty handle */
1496 wcn->tx_rings_empty_state = qcom_smem_state_get(&pdev->dev,
1497 "tx-rings-empty", &wcn->tx_rings_empty_state_bit);
1498 if (IS_ERR(wcn->tx_rings_empty_state)) {
1499 wcn36xx_err("failed to get tx-rings-empty state\n");
1500 return PTR_ERR(wcn->tx_rings_empty_state);
1501 }
1502
1503 mmio_node = of_parse_phandle(pdev->dev.parent->of_node, "qcom,mmio", 0);
1504 if (!mmio_node) {
1505 wcn36xx_err("failed to acquire qcom,mmio reference\n");
1506 return -EINVAL;
1507 }
1508
1509 wcn->is_pronto = !!of_device_is_compatible(mmio_node, "qcom,pronto");
1510
1511 /* Map the CCU memory */
1512 index = of_property_match_string(mmio_node, "reg-names", "ccu");
1513 wcn->ccu_base = of_iomap(mmio_node, index);
1514 if (!wcn->ccu_base) {
1515 wcn36xx_err("failed to map ccu memory\n");
1516 ret = -ENOMEM;
1517 goto put_mmio_node;
1518 }
1519
1520 /* Map the DXE memory */
1521 index = of_property_match_string(mmio_node, "reg-names", "dxe");
1522 wcn->dxe_base = of_iomap(mmio_node, index);
1523 if (!wcn->dxe_base) {
1524 wcn36xx_err("failed to map dxe memory\n");
1525 ret = -ENOMEM;
1526 goto unmap_ccu;
1527 }
1528
1529 /* External RF module */
1530 iris_node = of_get_child_by_name(mmio_node, "iris");
1531 if (iris_node) {
1532 if (of_device_is_compatible(iris_node, "qcom,wcn3620"))
1533 wcn->rf_id = RF_IRIS_WCN3620;
1534 if (of_device_is_compatible(iris_node, "qcom,wcn3660") ||
1535 of_device_is_compatible(iris_node, "qcom,wcn3660b"))
1536 wcn->rf_id = RF_IRIS_WCN3660;
1537 if (of_device_is_compatible(iris_node, "qcom,wcn3680"))
1538 wcn->rf_id = RF_IRIS_WCN3680;
1539 of_node_put(iris_node);
1540 }
1541
1542 of_node_put(mmio_node);
1543 return 0;
1544
1545 unmap_ccu:
1546 iounmap(wcn->ccu_base);
1547 put_mmio_node:
1548 of_node_put(mmio_node);
1549 return ret;
1550 }
1551
wcn36xx_probe(struct platform_device * pdev)1552 static int wcn36xx_probe(struct platform_device *pdev)
1553 {
1554 struct ieee80211_hw *hw;
1555 struct wcn36xx *wcn;
1556 void *wcnss;
1557 int ret;
1558 const u8 *addr;
1559 int n_channels;
1560
1561 wcn36xx_dbg(WCN36XX_DBG_MAC, "platform probe\n");
1562
1563 wcnss = dev_get_drvdata(pdev->dev.parent);
1564
1565 hw = ieee80211_alloc_hw(sizeof(struct wcn36xx), &wcn36xx_ops);
1566 if (!hw) {
1567 wcn36xx_err("failed to alloc hw\n");
1568 ret = -ENOMEM;
1569 goto out_err;
1570 }
1571 platform_set_drvdata(pdev, hw);
1572 wcn = hw->priv;
1573 wcn->hw = hw;
1574 wcn->dev = &pdev->dev;
1575 wcn->first_boot = true;
1576 mutex_init(&wcn->conf_mutex);
1577 mutex_init(&wcn->hal_mutex);
1578 mutex_init(&wcn->scan_lock);
1579 __skb_queue_head_init(&wcn->amsdu);
1580
1581 wcn->hal_buf = devm_kmalloc(wcn->dev, WCN36XX_HAL_BUF_SIZE, GFP_KERNEL);
1582 if (!wcn->hal_buf) {
1583 ret = -ENOMEM;
1584 goto out_wq;
1585 }
1586
1587 n_channels = wcn_band_2ghz.n_channels + wcn_band_5ghz.n_channels;
1588 wcn->chan_survey = devm_kmalloc(wcn->dev, n_channels, GFP_KERNEL);
1589 if (!wcn->chan_survey) {
1590 ret = -ENOMEM;
1591 goto out_wq;
1592 }
1593
1594 ret = dma_set_mask_and_coherent(wcn->dev, DMA_BIT_MASK(32));
1595 if (ret < 0) {
1596 wcn36xx_err("failed to set DMA mask: %d\n", ret);
1597 goto out_wq;
1598 }
1599
1600 wcn->nv_file = WLAN_NV_FILE;
1601 ret = of_property_read_string(wcn->dev->parent->of_node, "firmware-name", &wcn->nv_file);
1602 if (ret < 0 && ret != -EINVAL) {
1603 wcn36xx_err("failed to read \"firmware-name\" property: %d\n", ret);
1604 goto out_wq;
1605 }
1606
1607 wcn->smd_channel = qcom_wcnss_open_channel(wcnss, "WLAN_CTRL", wcn36xx_smd_rsp_process, hw);
1608 if (IS_ERR(wcn->smd_channel)) {
1609 wcn36xx_err("failed to open WLAN_CTRL channel\n");
1610 ret = PTR_ERR(wcn->smd_channel);
1611 goto out_wq;
1612 }
1613
1614 addr = of_get_property(pdev->dev.of_node, "local-mac-address", &ret);
1615 if (addr && ret != ETH_ALEN) {
1616 wcn36xx_err("invalid local-mac-address\n");
1617 ret = -EINVAL;
1618 goto out_destroy_ept;
1619 } else if (addr) {
1620 wcn36xx_info("mac address: %pM\n", addr);
1621 SET_IEEE80211_PERM_ADDR(wcn->hw, addr);
1622 }
1623
1624 ret = wcn36xx_platform_get_resources(wcn, pdev);
1625 if (ret)
1626 goto out_destroy_ept;
1627
1628 wcn36xx_init_ieee80211(wcn);
1629 ret = ieee80211_register_hw(wcn->hw);
1630 if (ret)
1631 goto out_unmap;
1632
1633 return 0;
1634
1635 out_unmap:
1636 iounmap(wcn->ccu_base);
1637 iounmap(wcn->dxe_base);
1638 out_destroy_ept:
1639 rpmsg_destroy_ept(wcn->smd_channel);
1640 out_wq:
1641 ieee80211_free_hw(hw);
1642 out_err:
1643 return ret;
1644 }
1645
wcn36xx_remove(struct platform_device * pdev)1646 static int wcn36xx_remove(struct platform_device *pdev)
1647 {
1648 struct ieee80211_hw *hw = platform_get_drvdata(pdev);
1649 struct wcn36xx *wcn = hw->priv;
1650 wcn36xx_dbg(WCN36XX_DBG_MAC, "platform remove\n");
1651
1652 release_firmware(wcn->nv);
1653
1654 ieee80211_unregister_hw(hw);
1655
1656 qcom_smem_state_put(wcn->tx_enable_state);
1657 qcom_smem_state_put(wcn->tx_rings_empty_state);
1658
1659 rpmsg_destroy_ept(wcn->smd_channel);
1660
1661 iounmap(wcn->dxe_base);
1662 iounmap(wcn->ccu_base);
1663
1664 __skb_queue_purge(&wcn->amsdu);
1665
1666 mutex_destroy(&wcn->hal_mutex);
1667 ieee80211_free_hw(hw);
1668
1669 return 0;
1670 }
1671
1672 static const struct of_device_id wcn36xx_of_match[] = {
1673 { .compatible = "qcom,wcnss-wlan" },
1674 {}
1675 };
1676 MODULE_DEVICE_TABLE(of, wcn36xx_of_match);
1677
1678 static struct platform_driver wcn36xx_driver = {
1679 .probe = wcn36xx_probe,
1680 .remove = wcn36xx_remove,
1681 .driver = {
1682 .name = "wcn36xx",
1683 .of_match_table = wcn36xx_of_match,
1684 },
1685 };
1686
1687 module_platform_driver(wcn36xx_driver);
1688
1689 MODULE_LICENSE("Dual BSD/GPL");
1690 MODULE_AUTHOR("Eugene Krasnikov k.eugene.e@gmail.com");
1691 MODULE_FIRMWARE(WLAN_NV_FILE);
1692