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