2 * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com>
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.
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.
17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19 #include <linux/module.h>
20 #include <linux/firmware.h>
21 #include <linux/platform_device.h>
23 #include <linux/of_address.h>
24 #include <linux/rpmsg.h>
25 #include <linux/soc/qcom/smem_state.h>
26 #include <linux/soc/qcom/wcnss_ctrl.h>
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");
36 #define CHAN2G(_freq, _idx) { \
37 .band = NL80211_BAND_2GHZ, \
38 .center_freq = (_freq), \
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), \
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 */
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
),
98 #define RATE(_bitrate, _hw_rate, _flags) { \
99 .bitrate = (_bitrate), \
101 .hw_value = (_hw_rate), \
102 .hw_value_short = (_hw_rate) \
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)
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)
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
),
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
,
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
,
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
),
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
,
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
,
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
187 static inline u8
get_sta_index(struct ieee80211_vif
*vif
,
188 struct wcn36xx_sta
*sta_priv
)
190 return NL80211_IFTYPE_STATION
== vif
->type
?
191 sta_priv
->bss_sta_index
:
195 static void wcn36xx_feat_caps_info(struct wcn36xx
*wcn
)
199 for (i
= 0; i
< MAX_FEATURE_SUPPORTED
; i
++) {
200 if (wcn36xx_firmware_get_feat_caps(wcn
->fw_feat_caps
, i
)) {
201 wcn36xx_dbg(WCN36XX_DBG_MAC
, "FW Cap %s\n",
202 wcn36xx_firmware_get_cap_name(i
));
207 static int wcn36xx_start(struct ieee80211_hw
*hw
)
209 struct wcn36xx
*wcn
= hw
->priv
;
212 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac start\n");
214 /* SMD initialization */
215 ret
= wcn36xx_smd_open(wcn
);
217 wcn36xx_err("Failed to open smd channel: %d\n", ret
);
221 /* Allocate memory pools for Mgmt BD headers and Data BD headers */
222 ret
= wcn36xx_dxe_allocate_mem_pools(wcn
);
224 wcn36xx_err("Failed to alloc DXE mempool: %d\n", ret
);
228 ret
= wcn36xx_dxe_alloc_ctl_blks(wcn
);
230 wcn36xx_err("Failed to alloc DXE ctl blocks: %d\n", ret
);
231 goto out_free_dxe_pool
;
234 ret
= wcn36xx_smd_load_nv(wcn
);
236 wcn36xx_err("Failed to push NV to chip\n");
237 goto out_free_dxe_ctl
;
240 ret
= wcn36xx_smd_start(wcn
);
242 wcn36xx_err("Failed to start chip\n");
243 goto out_free_dxe_ctl
;
246 if (!wcn36xx_is_fw_version(wcn
, 1, 2, 2, 24)) {
247 ret
= wcn36xx_smd_feature_caps_exchange(wcn
);
249 wcn36xx_warn("Exchange feature caps failed\n");
251 wcn36xx_feat_caps_info(wcn
);
254 /* DMA channel initialization */
255 ret
= wcn36xx_dxe_init(wcn
);
257 wcn36xx_err("DXE init failed\n");
261 wcn36xx_debugfs_init(wcn
);
263 INIT_LIST_HEAD(&wcn
->vif_list
);
264 spin_lock_init(&wcn
->dxe_lock
);
265 spin_lock_init(&wcn
->survey_lock
);
270 wcn36xx_smd_stop(wcn
);
272 wcn36xx_dxe_free_ctl_blks(wcn
);
274 wcn36xx_dxe_free_mem_pools(wcn
);
276 wcn36xx_smd_close(wcn
);
281 static void wcn36xx_stop(struct ieee80211_hw
*hw
, bool suspend
)
283 struct wcn36xx
*wcn
= hw
->priv
;
285 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac stop\n");
287 mutex_lock(&wcn
->scan_lock
);
289 struct cfg80211_scan_info scan_info
= {
293 ieee80211_scan_completed(wcn
->hw
, &scan_info
);
295 wcn
->scan_req
= NULL
;
296 mutex_unlock(&wcn
->scan_lock
);
298 wcn36xx_debugfs_exit(wcn
);
299 wcn36xx_smd_stop(wcn
);
300 wcn36xx_dxe_deinit(wcn
);
301 wcn36xx_smd_close(wcn
);
303 wcn36xx_dxe_free_mem_pools(wcn
);
304 wcn36xx_dxe_free_ctl_blks(wcn
);
307 static void wcn36xx_change_ps(struct wcn36xx
*wcn
, bool enable
)
309 struct ieee80211_vif
*vif
= NULL
;
310 struct wcn36xx_vif
*tmp
;
312 list_for_each_entry(tmp
, &wcn
->vif_list
, list
) {
313 vif
= wcn36xx_priv_to_vif(tmp
);
314 if (enable
&& !wcn
->sw_scan
) {
315 if (vif
->cfg
.ps
) /* ps allowed ? */
316 wcn36xx_pmc_enter_bmps_state(wcn
, vif
);
318 wcn36xx_pmc_exit_bmps_state(wcn
, vif
);
323 static void wcn36xx_change_opchannel(struct wcn36xx
*wcn
, int ch
)
325 struct ieee80211_vif
*vif
= NULL
;
326 struct wcn36xx_vif
*tmp
;
327 struct ieee80211_supported_band
*band
;
328 struct ieee80211_channel
*channel
= NULL
;
332 for (i
= 0; i
< ARRAY_SIZE(wcn
->hw
->wiphy
->bands
); i
++) {
333 band
= wcn
->hw
->wiphy
->bands
[i
];
336 for (j
= 0; j
< band
->n_channels
; j
++) {
337 if (HW_VALUE_CHANNEL(band
->channels
[j
].hw_value
) == ch
) {
338 channel
= &band
->channels
[j
];
347 wcn36xx_err("Cannot tune to channel %d\n", ch
);
351 spin_lock_irqsave(&wcn
->survey_lock
, flags
);
353 wcn
->channel
= channel
;
354 spin_unlock_irqrestore(&wcn
->survey_lock
, flags
);
356 list_for_each_entry(tmp
, &wcn
->vif_list
, list
) {
357 vif
= wcn36xx_priv_to_vif(tmp
);
358 wcn36xx_smd_switch_channel(wcn
, vif
, ch
);
364 static int wcn36xx_config(struct ieee80211_hw
*hw
, u32 changed
)
366 struct wcn36xx
*wcn
= hw
->priv
;
369 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac config changed 0x%08x\n", changed
);
371 mutex_lock(&wcn
->conf_mutex
);
373 if (changed
& IEEE80211_CONF_CHANGE_CHANNEL
) {
374 int ch
= WCN36XX_HW_CHANNEL(wcn
);
375 wcn36xx_dbg(WCN36XX_DBG_MAC
, "wcn36xx_config channel switch=%d\n",
378 if (wcn
->sw_scan_opchannel
== ch
&& wcn
->sw_scan_channel
) {
379 /* If channel is the initial operating channel, we may
380 * want to receive/transmit regular data packets, then
381 * simply stop the scan session and exit PS mode.
383 if (wcn
->sw_scan_channel
)
384 wcn36xx_smd_end_scan(wcn
, wcn
->sw_scan_channel
);
385 if (wcn
->sw_scan_init
) {
386 wcn36xx_smd_finish_scan(wcn
, HAL_SYS_MODE_SCAN
,
389 } else if (wcn
->sw_scan
) {
390 /* A scan is ongoing, do not change the operating
391 * channel, but start a scan session on the channel.
393 if (wcn
->sw_scan_channel
)
394 wcn36xx_smd_end_scan(wcn
, wcn
->sw_scan_channel
);
395 if (!wcn
->sw_scan_init
) {
396 /* This can fail if we are unable to notify the
399 ret
= wcn36xx_smd_init_scan(wcn
,
403 mutex_unlock(&wcn
->conf_mutex
);
407 wcn36xx_smd_start_scan(wcn
, ch
);
409 wcn36xx_change_opchannel(wcn
, ch
);
413 if (changed
& IEEE80211_CONF_CHANGE_PS
)
414 wcn36xx_change_ps(wcn
, hw
->conf
.flags
& IEEE80211_CONF_PS
);
416 if (changed
& IEEE80211_CONF_CHANGE_IDLE
) {
417 if (hw
->conf
.flags
& IEEE80211_CONF_IDLE
)
418 wcn36xx_smd_enter_imps(wcn
);
420 wcn36xx_smd_exit_imps(wcn
);
423 mutex_unlock(&wcn
->conf_mutex
);
428 static void wcn36xx_configure_filter(struct ieee80211_hw
*hw
,
429 unsigned int changed
,
430 unsigned int *total
, u64 multicast
)
432 struct wcn36xx_hal_rcv_flt_mc_addr_list_type
*fp
;
433 struct wcn36xx
*wcn
= hw
->priv
;
434 struct wcn36xx_vif
*tmp
;
435 struct ieee80211_vif
*vif
= NULL
;
437 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac configure filter\n");
439 mutex_lock(&wcn
->conf_mutex
);
441 *total
&= FIF_ALLMULTI
;
443 fp
= (void *)(unsigned long)multicast
;
444 list_for_each_entry(tmp
, &wcn
->vif_list
, list
) {
445 vif
= wcn36xx_priv_to_vif(tmp
);
447 /* FW handles MC filtering only when connected as STA */
448 if (*total
& FIF_ALLMULTI
)
449 wcn36xx_smd_set_mc_list(wcn
, vif
, NULL
);
450 else if (NL80211_IFTYPE_STATION
== vif
->type
&& tmp
->sta_assoc
)
451 wcn36xx_smd_set_mc_list(wcn
, vif
, fp
);
454 mutex_unlock(&wcn
->conf_mutex
);
458 static u64
wcn36xx_prepare_multicast(struct ieee80211_hw
*hw
,
459 struct netdev_hw_addr_list
*mc_list
)
461 struct wcn36xx_hal_rcv_flt_mc_addr_list_type
*fp
;
462 struct netdev_hw_addr
*ha
;
464 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac prepare multicast list\n");
465 fp
= kzalloc(sizeof(*fp
), GFP_ATOMIC
);
467 wcn36xx_err("Out of memory setting filters.\n");
471 fp
->mc_addr_count
= 0;
472 /* update multicast filtering parameters */
473 if (netdev_hw_addr_list_count(mc_list
) <=
474 WCN36XX_HAL_MAX_NUM_MULTICAST_ADDRESS
) {
475 netdev_hw_addr_list_for_each(ha
, mc_list
) {
476 memcpy(fp
->mc_addr
[fp
->mc_addr_count
],
482 return (u64
)(unsigned long)fp
;
485 static void wcn36xx_tx(struct ieee80211_hw
*hw
,
486 struct ieee80211_tx_control
*control
,
489 struct wcn36xx
*wcn
= hw
->priv
;
490 struct wcn36xx_sta
*sta_priv
= NULL
;
493 sta_priv
= wcn36xx_sta_to_priv(control
->sta
);
495 if (wcn36xx_start_tx(wcn
, sta_priv
, skb
))
496 ieee80211_free_txskb(wcn
->hw
, skb
);
499 static int wcn36xx_set_key(struct ieee80211_hw
*hw
, enum set_key_cmd cmd
,
500 struct ieee80211_vif
*vif
,
501 struct ieee80211_sta
*sta
,
502 struct ieee80211_key_conf
*key_conf
)
504 struct wcn36xx
*wcn
= hw
->priv
;
505 struct wcn36xx_vif
*vif_priv
= wcn36xx_vif_to_priv(vif
);
506 struct wcn36xx_sta
*sta_priv
= sta
? wcn36xx_sta_to_priv(sta
) : NULL
;
508 u8 key
[WLAN_MAX_KEY_LEN
];
510 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac80211 set key\n");
511 wcn36xx_dbg(WCN36XX_DBG_MAC
, "Key: cmd=0x%x algo:0x%x, id:%d, len:%d flags 0x%x\n",
512 cmd
, key_conf
->cipher
, key_conf
->keyidx
,
513 key_conf
->keylen
, key_conf
->flags
);
514 wcn36xx_dbg_dump(WCN36XX_DBG_MAC
, "KEY: ",
518 mutex_lock(&wcn
->conf_mutex
);
520 switch (key_conf
->cipher
) {
521 case WLAN_CIPHER_SUITE_WEP40
:
522 vif_priv
->encrypt_type
= WCN36XX_HAL_ED_WEP40
;
524 case WLAN_CIPHER_SUITE_WEP104
:
525 vif_priv
->encrypt_type
= WCN36XX_HAL_ED_WEP104
;
527 case WLAN_CIPHER_SUITE_CCMP
:
528 vif_priv
->encrypt_type
= WCN36XX_HAL_ED_CCMP
;
530 case WLAN_CIPHER_SUITE_TKIP
:
531 vif_priv
->encrypt_type
= WCN36XX_HAL_ED_TKIP
;
534 wcn36xx_err("Unsupported key type 0x%x\n",
542 if (WCN36XX_HAL_ED_TKIP
== vif_priv
->encrypt_type
) {
544 * Supplicant is sending key in the wrong order:
545 * Temporal Key (16 b) - TX MIC (8 b) - RX MIC (8 b)
546 * but HW expects it to be in the order as described in
547 * IEEE 802.11 spec (see chapter 11.7) like this:
548 * Temporal Key (16 b) - RX MIC (8 b) - TX MIC (8 b)
550 memcpy(key
, key_conf
->key
, 16);
551 memcpy(key
+ 16, key_conf
->key
+ 24, 8);
552 memcpy(key
+ 24, key_conf
->key
+ 16, 8);
554 memcpy(key
, key_conf
->key
, key_conf
->keylen
);
557 if (IEEE80211_KEY_FLAG_PAIRWISE
& key_conf
->flags
) {
558 sta_priv
->is_data_encrypted
= true;
559 /* Reconfigure bss with encrypt_type */
560 if (NL80211_IFTYPE_STATION
== vif
->type
) {
561 wcn36xx_smd_config_bss(wcn
,
566 wcn36xx_smd_config_sta(wcn
, vif
, sta
);
569 wcn36xx_smd_set_stakey(wcn
,
570 vif_priv
->encrypt_type
,
574 get_sta_index(vif
, sta_priv
));
576 wcn36xx_smd_set_bsskey(wcn
,
577 vif_priv
->encrypt_type
,
583 if ((WLAN_CIPHER_SUITE_WEP40
== key_conf
->cipher
) ||
584 (WLAN_CIPHER_SUITE_WEP104
== key_conf
->cipher
)) {
585 list_for_each_entry(sta_priv
,
586 &vif_priv
->sta_list
, list
) {
587 sta_priv
->is_data_encrypted
= true;
588 wcn36xx_smd_set_stakey(wcn
,
589 vif_priv
->encrypt_type
,
593 get_sta_index(vif
, sta_priv
));
599 if (!(IEEE80211_KEY_FLAG_PAIRWISE
& key_conf
->flags
)) {
600 if (vif_priv
->bss_index
!= WCN36XX_HAL_BSS_INVALID_IDX
)
601 wcn36xx_smd_remove_bsskey(wcn
,
602 vif_priv
->encrypt_type
,
606 vif_priv
->encrypt_type
= WCN36XX_HAL_ED_NONE
;
608 sta_priv
->is_data_encrypted
= false;
609 /* do not remove key if disassociated */
611 wcn36xx_smd_remove_stakey(wcn
,
612 vif_priv
->encrypt_type
,
614 get_sta_index(vif
, sta_priv
));
618 wcn36xx_err("Unsupported key cmd 0x%x\n", cmd
);
624 mutex_unlock(&wcn
->conf_mutex
);
629 static int wcn36xx_hw_scan(struct ieee80211_hw
*hw
,
630 struct ieee80211_vif
*vif
,
631 struct ieee80211_scan_request
*hw_req
)
633 struct wcn36xx
*wcn
= hw
->priv
;
635 if (!wcn36xx_firmware_get_feat_caps(wcn
->fw_feat_caps
, SCAN_OFFLOAD
)) {
636 /* fallback to mac80211 software scan */
640 /* Firmware scan offload is limited to 48 channels, fallback to
641 * software driven scanning otherwise.
643 if (hw_req
->req
.n_channels
> 48) {
644 wcn36xx_warn("Offload scan aborted, n_channels=%u",
645 hw_req
->req
.n_channels
);
649 mutex_lock(&wcn
->scan_lock
);
651 mutex_unlock(&wcn
->scan_lock
);
655 wcn
->scan_aborted
= false;
656 wcn
->scan_req
= &hw_req
->req
;
658 mutex_unlock(&wcn
->scan_lock
);
660 wcn36xx_smd_update_channel_list(wcn
, &hw_req
->req
);
661 return wcn36xx_smd_start_hw_scan(wcn
, vif
, &hw_req
->req
);
664 static void wcn36xx_cancel_hw_scan(struct ieee80211_hw
*hw
,
665 struct ieee80211_vif
*vif
)
667 struct wcn36xx
*wcn
= hw
->priv
;
669 mutex_lock(&wcn
->scan_lock
);
670 wcn
->scan_aborted
= true;
671 mutex_unlock(&wcn
->scan_lock
);
673 if (wcn36xx_firmware_get_feat_caps(wcn
->fw_feat_caps
, SCAN_OFFLOAD
)) {
674 /* ieee80211_scan_completed will be called on FW scan
676 wcn36xx_smd_stop_hw_scan(wcn
);
680 static void wcn36xx_sw_scan_start(struct ieee80211_hw
*hw
,
681 struct ieee80211_vif
*vif
,
684 struct wcn36xx
*wcn
= hw
->priv
;
685 struct wcn36xx_vif
*vif_priv
= wcn36xx_vif_to_priv(vif
);
687 wcn36xx_dbg(WCN36XX_DBG_MAC
, "sw_scan_start");
690 wcn
->sw_scan_vif
= vif
;
691 wcn
->sw_scan_channel
= 0;
692 if (vif_priv
->sta_assoc
)
693 wcn
->sw_scan_opchannel
= WCN36XX_HW_CHANNEL(wcn
);
695 wcn
->sw_scan_opchannel
= 0;
698 static void wcn36xx_sw_scan_complete(struct ieee80211_hw
*hw
,
699 struct ieee80211_vif
*vif
)
701 struct wcn36xx
*wcn
= hw
->priv
;
703 wcn36xx_dbg(WCN36XX_DBG_MAC
, "sw_scan_complete");
705 /* ensure that any scan session is finished */
706 if (wcn
->sw_scan_channel
)
707 wcn36xx_smd_end_scan(wcn
, wcn
->sw_scan_channel
);
708 if (wcn
->sw_scan_init
) {
709 wcn36xx_smd_finish_scan(wcn
, HAL_SYS_MODE_SCAN
,
712 wcn
->sw_scan
= false;
713 wcn
->sw_scan_opchannel
= 0;
716 static void wcn36xx_update_allowed_rates(struct ieee80211_sta
*sta
,
717 enum nl80211_band band
)
721 struct wcn36xx_sta
*sta_priv
= wcn36xx_sta_to_priv(sta
);
722 u32 rates
= sta
->deflink
.supp_rates
[band
];
724 memset(&sta_priv
->supported_rates
, 0,
725 sizeof(sta_priv
->supported_rates
));
726 sta_priv
->supported_rates
.op_rate_mode
= STA_11n
;
728 size
= ARRAY_SIZE(sta_priv
->supported_rates
.dsss_rates
);
729 rates_table
= sta_priv
->supported_rates
.dsss_rates
;
730 if (band
== NL80211_BAND_2GHZ
) {
731 for (i
= 0; i
< size
; i
++) {
733 rates_table
[i
] = wcn_2ghz_rates
[i
].hw_value
;
739 size
= ARRAY_SIZE(sta_priv
->supported_rates
.ofdm_rates
);
740 rates_table
= sta_priv
->supported_rates
.ofdm_rates
;
741 for (i
= 0; i
< size
; i
++) {
743 rates_table
[i
] = wcn_5ghz_rates
[i
].hw_value
;
748 if (sta
->deflink
.ht_cap
.ht_supported
) {
749 BUILD_BUG_ON(sizeof(sta
->deflink
.ht_cap
.mcs
.rx_mask
) >
750 sizeof(sta_priv
->supported_rates
.supported_mcs_set
));
751 memcpy(sta_priv
->supported_rates
.supported_mcs_set
,
752 sta
->deflink
.ht_cap
.mcs
.rx_mask
,
753 sizeof(sta
->deflink
.ht_cap
.mcs
.rx_mask
));
756 if (sta
->deflink
.vht_cap
.vht_supported
) {
757 sta_priv
->supported_rates
.op_rate_mode
= STA_11ac
;
758 sta_priv
->supported_rates
.vht_rx_mcs_map
=
759 le16_to_cpu(sta
->deflink
.vht_cap
.vht_mcs
.rx_mcs_map
);
760 sta_priv
->supported_rates
.vht_tx_mcs_map
=
761 le16_to_cpu(sta
->deflink
.vht_cap
.vht_mcs
.tx_mcs_map
);
765 void wcn36xx_set_default_rates(struct wcn36xx_hal_supported_rates
*rates
)
767 u16 ofdm_rates
[WCN36XX_HAL_NUM_OFDM_RATES
] = {
770 HW_RATE_INDEX_12MBPS
,
771 HW_RATE_INDEX_18MBPS
,
772 HW_RATE_INDEX_24MBPS
,
773 HW_RATE_INDEX_36MBPS
,
774 HW_RATE_INDEX_48MBPS
,
777 u16 dsss_rates
[WCN36XX_HAL_NUM_DSSS_RATES
] = {
780 HW_RATE_INDEX_5_5MBPS
,
784 rates
->op_rate_mode
= STA_11n
;
785 memcpy(rates
->dsss_rates
, dsss_rates
,
786 sizeof(*dsss_rates
) * WCN36XX_HAL_NUM_DSSS_RATES
);
787 memcpy(rates
->ofdm_rates
, ofdm_rates
,
788 sizeof(*ofdm_rates
) * WCN36XX_HAL_NUM_OFDM_RATES
);
789 rates
->supported_mcs_set
[0] = 0xFF;
792 void wcn36xx_set_default_rates_v1(struct wcn36xx_hal_supported_rates_v1
*rates
)
794 rates
->op_rate_mode
= STA_11ac
;
795 rates
->vht_rx_mcs_map
= IEEE80211_VHT_MCS_SUPPORT_0_9
;
796 rates
->vht_tx_mcs_map
= IEEE80211_VHT_MCS_SUPPORT_0_9
;
799 static void wcn36xx_bss_info_changed(struct ieee80211_hw
*hw
,
800 struct ieee80211_vif
*vif
,
801 struct ieee80211_bss_conf
*bss_conf
,
804 struct wcn36xx
*wcn
= hw
->priv
;
805 struct sk_buff
*skb
= NULL
;
806 u16 tim_off
, tim_len
;
807 enum wcn36xx_hal_link_state link_state
;
808 struct wcn36xx_vif
*vif_priv
= wcn36xx_vif_to_priv(vif
);
810 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac bss info changed vif %p changed 0x%llx\n",
813 mutex_lock(&wcn
->conf_mutex
);
815 if (changed
& BSS_CHANGED_BEACON_INFO
) {
816 wcn36xx_dbg(WCN36XX_DBG_MAC
,
817 "mac bss changed dtim period %d\n",
818 bss_conf
->dtim_period
);
820 vif_priv
->dtim_period
= bss_conf
->dtim_period
;
823 if (changed
& BSS_CHANGED_BSSID
) {
824 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac bss changed_bssid %pM\n",
827 if (!is_zero_ether_addr(bss_conf
->bssid
)) {
828 vif_priv
->is_joining
= true;
829 vif_priv
->bss_index
= WCN36XX_HAL_BSS_INVALID_IDX
;
830 wcn36xx_smd_set_link_st(wcn
, bss_conf
->bssid
, vif
->addr
,
831 WCN36XX_HAL_LINK_PREASSOC_STATE
);
832 wcn36xx_smd_join(wcn
, bss_conf
->bssid
,
833 vif
->addr
, WCN36XX_HW_CHANNEL(wcn
));
834 wcn36xx_smd_config_bss(wcn
, vif
, NULL
,
835 bss_conf
->bssid
, false);
837 vif_priv
->is_joining
= false;
838 wcn36xx_smd_delete_bss(wcn
, vif
);
839 wcn36xx_smd_set_link_st(wcn
, bss_conf
->bssid
, vif
->addr
,
840 WCN36XX_HAL_LINK_IDLE_STATE
);
841 vif_priv
->encrypt_type
= WCN36XX_HAL_ED_NONE
;
845 if (changed
& BSS_CHANGED_SSID
) {
846 wcn36xx_dbg(WCN36XX_DBG_MAC
,
847 "mac bss changed ssid\n");
848 wcn36xx_dbg_dump(WCN36XX_DBG_MAC
, "ssid ",
849 vif
->cfg
.ssid
, vif
->cfg
.ssid_len
);
851 vif_priv
->ssid
.length
= vif
->cfg
.ssid_len
;
852 memcpy(&vif_priv
->ssid
.ssid
,
857 if (changed
& BSS_CHANGED_ASSOC
) {
858 vif_priv
->is_joining
= false;
859 if (vif
->cfg
.assoc
) {
860 struct ieee80211_sta
*sta
;
861 struct wcn36xx_sta
*sta_priv
;
863 wcn36xx_dbg(WCN36XX_DBG_MAC
,
864 "mac assoc bss %pM vif %pM AID=%d\n",
869 vif_priv
->sta_assoc
= true;
872 * Holding conf_mutex ensures mutal exclusion with
873 * wcn36xx_sta_remove() and as such ensures that sta
874 * won't be freed while we're operating on it. As such
875 * we do not need to hold the rcu_read_lock().
877 sta
= ieee80211_find_sta(vif
, bss_conf
->bssid
);
879 wcn36xx_err("sta %pM is not found\n",
883 sta_priv
= wcn36xx_sta_to_priv(sta
);
885 wcn36xx_update_allowed_rates(sta
, WCN36XX_BAND(wcn
));
887 wcn36xx_smd_set_link_st(wcn
, bss_conf
->bssid
,
889 WCN36XX_HAL_LINK_POSTASSOC_STATE
);
890 wcn36xx_smd_config_bss(wcn
, vif
, sta
,
893 sta_priv
->aid
= vif
->cfg
.aid
;
895 * config_sta must be called from because this is the
896 * place where AID is available.
898 wcn36xx_smd_config_sta(wcn
, vif
, sta
);
899 if (vif
->type
== NL80211_IFTYPE_STATION
)
900 wcn36xx_smd_add_beacon_filter(wcn
, vif
);
901 wcn36xx_enable_keep_alive_null_packet(wcn
, vif
);
903 wcn36xx_dbg(WCN36XX_DBG_MAC
,
904 "disassociated bss %pM vif %pM AID=%d\n",
908 vif_priv
->sta_assoc
= false;
909 wcn36xx_smd_set_link_st(wcn
,
912 WCN36XX_HAL_LINK_IDLE_STATE
);
916 if (changed
& BSS_CHANGED_AP_PROBE_RESP
) {
917 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac bss changed ap probe resp\n");
918 skb
= ieee80211_proberesp_get(hw
, vif
);
920 wcn36xx_err("failed to alloc probereq skb\n");
924 wcn36xx_smd_update_proberesp_tmpl(wcn
, vif
, skb
);
928 if (changed
& BSS_CHANGED_BEACON_ENABLED
||
929 changed
& BSS_CHANGED_BEACON
) {
930 wcn36xx_dbg(WCN36XX_DBG_MAC
,
931 "mac bss changed beacon enabled %d\n",
932 bss_conf
->enable_beacon
);
934 if (bss_conf
->enable_beacon
) {
935 vif_priv
->dtim_period
= bss_conf
->dtim_period
;
936 vif_priv
->bss_index
= WCN36XX_HAL_BSS_INVALID_IDX
;
937 wcn36xx_smd_config_bss(wcn
, vif
, NULL
,
939 skb
= ieee80211_beacon_get_tim(hw
, vif
, &tim_off
,
942 wcn36xx_err("failed to alloc beacon skb\n");
945 wcn36xx_smd_send_beacon(wcn
, vif
, skb
, tim_off
, 0);
948 if (vif
->type
== NL80211_IFTYPE_ADHOC
||
949 vif
->type
== NL80211_IFTYPE_MESH_POINT
)
950 link_state
= WCN36XX_HAL_LINK_IBSS_STATE
;
952 link_state
= WCN36XX_HAL_LINK_AP_STATE
;
954 wcn36xx_smd_set_link_st(wcn
, vif
->addr
, vif
->addr
,
957 wcn36xx_smd_delete_bss(wcn
, vif
);
958 wcn36xx_smd_set_link_st(wcn
, vif
->addr
, vif
->addr
,
959 WCN36XX_HAL_LINK_IDLE_STATE
);
964 mutex_unlock(&wcn
->conf_mutex
);
967 /* this is required when using IEEE80211_HW_HAS_RATE_CONTROL */
968 static int wcn36xx_set_rts_threshold(struct ieee80211_hw
*hw
, u32 value
)
970 struct wcn36xx
*wcn
= hw
->priv
;
971 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac set RTS threshold %d\n", value
);
973 mutex_lock(&wcn
->conf_mutex
);
974 wcn36xx_smd_update_cfg(wcn
, WCN36XX_HAL_CFG_RTS_THRESHOLD
, value
);
975 mutex_unlock(&wcn
->conf_mutex
);
980 static void wcn36xx_remove_interface(struct ieee80211_hw
*hw
,
981 struct ieee80211_vif
*vif
)
983 struct wcn36xx
*wcn
= hw
->priv
;
984 struct wcn36xx_vif
*vif_priv
= wcn36xx_vif_to_priv(vif
);
985 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac remove interface vif %p\n", vif
);
987 mutex_lock(&wcn
->conf_mutex
);
989 list_del(&vif_priv
->list
);
990 wcn36xx_smd_delete_sta_self(wcn
, vif
->addr
);
992 mutex_unlock(&wcn
->conf_mutex
);
995 static int wcn36xx_add_interface(struct ieee80211_hw
*hw
,
996 struct ieee80211_vif
*vif
)
998 struct wcn36xx
*wcn
= hw
->priv
;
999 struct wcn36xx_vif
*vif_priv
= wcn36xx_vif_to_priv(vif
);
1001 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac add interface vif %p type %d\n",
1004 if (!(NL80211_IFTYPE_STATION
== vif
->type
||
1005 NL80211_IFTYPE_AP
== vif
->type
||
1006 NL80211_IFTYPE_ADHOC
== vif
->type
||
1007 NL80211_IFTYPE_MESH_POINT
== vif
->type
)) {
1008 wcn36xx_warn("Unsupported interface type requested: %d\n",
1013 mutex_lock(&wcn
->conf_mutex
);
1015 vif_priv
->bss_index
= WCN36XX_HAL_BSS_INVALID_IDX
;
1016 INIT_LIST_HEAD(&vif_priv
->sta_list
);
1017 list_add(&vif_priv
->list
, &wcn
->vif_list
);
1018 wcn36xx_smd_add_sta_self(wcn
, vif
);
1020 mutex_unlock(&wcn
->conf_mutex
);
1025 static int wcn36xx_sta_add(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
1026 struct ieee80211_sta
*sta
)
1028 struct wcn36xx
*wcn
= hw
->priv
;
1029 struct wcn36xx_vif
*vif_priv
= wcn36xx_vif_to_priv(vif
);
1030 struct wcn36xx_sta
*sta_priv
= wcn36xx_sta_to_priv(sta
);
1031 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac sta add vif %p sta %pM\n",
1034 mutex_lock(&wcn
->conf_mutex
);
1036 spin_lock_init(&sta_priv
->ampdu_lock
);
1037 sta_priv
->vif
= vif_priv
;
1038 list_add(&sta_priv
->list
, &vif_priv
->sta_list
);
1041 * For STA mode HW will be configured on BSS_CHANGED_ASSOC because
1042 * at this stage AID is not available yet.
1044 if (NL80211_IFTYPE_STATION
!= vif
->type
) {
1045 wcn36xx_update_allowed_rates(sta
, WCN36XX_BAND(wcn
));
1046 sta_priv
->aid
= sta
->aid
;
1047 wcn36xx_smd_config_sta(wcn
, vif
, sta
);
1050 mutex_unlock(&wcn
->conf_mutex
);
1055 static int wcn36xx_sta_remove(struct ieee80211_hw
*hw
,
1056 struct ieee80211_vif
*vif
,
1057 struct ieee80211_sta
*sta
)
1059 struct wcn36xx
*wcn
= hw
->priv
;
1060 struct wcn36xx_sta
*sta_priv
= wcn36xx_sta_to_priv(sta
);
1062 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac sta remove vif %p sta %pM index %d\n",
1063 vif
, sta
->addr
, sta_priv
->sta_index
);
1065 mutex_lock(&wcn
->conf_mutex
);
1067 list_del(&sta_priv
->list
);
1068 wcn36xx_smd_delete_sta(wcn
, sta_priv
->sta_index
);
1069 sta_priv
->vif
= NULL
;
1071 mutex_unlock(&wcn
->conf_mutex
);
1078 static struct ieee80211_vif
*wcn36xx_get_first_assoc_vif(struct wcn36xx
*wcn
)
1080 struct wcn36xx_vif
*vif_priv
= NULL
;
1081 struct ieee80211_vif
*vif
= NULL
;
1083 list_for_each_entry(vif_priv
, &wcn
->vif_list
, list
) {
1084 if (vif_priv
->sta_assoc
) {
1085 vif
= wcn36xx_priv_to_vif(vif_priv
);
1092 static int wcn36xx_suspend(struct ieee80211_hw
*hw
, struct cfg80211_wowlan
*wow
)
1094 struct wcn36xx
*wcn
= hw
->priv
;
1095 struct ieee80211_vif
*vif
= NULL
;
1098 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac suspend\n");
1100 mutex_lock(&wcn
->conf_mutex
);
1102 vif
= wcn36xx_get_first_assoc_vif(wcn
);
1104 ret
= wcn36xx_smd_arp_offload(wcn
, vif
, true);
1107 ret
= wcn36xx_smd_ipv6_ns_offload(wcn
, vif
, true);
1110 ret
= wcn36xx_smd_gtk_offload(wcn
, vif
, true);
1113 ret
= wcn36xx_smd_set_power_params(wcn
, true);
1116 ret
= wcn36xx_smd_wlan_host_suspend_ind(wcn
);
1119 /* Disable IRQ, we don't want to handle any packet before mac80211 is
1120 * resumed and ready to receive packets.
1122 disable_irq(wcn
->tx_irq
);
1123 disable_irq(wcn
->rx_irq
);
1126 mutex_unlock(&wcn
->conf_mutex
);
1130 static int wcn36xx_resume(struct ieee80211_hw
*hw
)
1132 struct wcn36xx
*wcn
= hw
->priv
;
1133 struct ieee80211_vif
*vif
= NULL
;
1135 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac resume\n");
1137 mutex_lock(&wcn
->conf_mutex
);
1138 vif
= wcn36xx_get_first_assoc_vif(wcn
);
1140 wcn36xx_smd_host_resume(wcn
);
1141 wcn36xx_smd_set_power_params(wcn
, false);
1142 wcn36xx_smd_gtk_offload_get_info(wcn
, vif
);
1143 wcn36xx_smd_gtk_offload(wcn
, vif
, false);
1144 wcn36xx_smd_ipv6_ns_offload(wcn
, vif
, false);
1145 wcn36xx_smd_arp_offload(wcn
, vif
, false);
1148 enable_irq(wcn
->tx_irq
);
1149 enable_irq(wcn
->rx_irq
);
1151 mutex_unlock(&wcn
->conf_mutex
);
1156 static void wcn36xx_set_rekey_data(struct ieee80211_hw
*hw
,
1157 struct ieee80211_vif
*vif
,
1158 struct cfg80211_gtk_rekey_data
*data
)
1160 struct wcn36xx
*wcn
= hw
->priv
;
1161 struct wcn36xx_vif
*vif_priv
= wcn36xx_vif_to_priv(vif
);
1163 mutex_lock(&wcn
->conf_mutex
);
1165 memcpy(vif_priv
->rekey_data
.kek
, data
->kek
, NL80211_KEK_LEN
);
1166 memcpy(vif_priv
->rekey_data
.kck
, data
->kck
, NL80211_KCK_LEN
);
1167 vif_priv
->rekey_data
.replay_ctr
=
1168 cpu_to_le64(be64_to_cpup((__be64
*)data
->replay_ctr
));
1169 vif_priv
->rekey_data
.valid
= true;
1171 mutex_unlock(&wcn
->conf_mutex
);
1176 static int wcn36xx_ampdu_action(struct ieee80211_hw
*hw
,
1177 struct ieee80211_vif
*vif
,
1178 struct ieee80211_ampdu_params
*params
)
1180 struct wcn36xx
*wcn
= hw
->priv
;
1181 struct wcn36xx_sta
*sta_priv
= wcn36xx_sta_to_priv(params
->sta
);
1182 struct ieee80211_sta
*sta
= params
->sta
;
1183 enum ieee80211_ampdu_mlme_action action
= params
->action
;
1184 u16 tid
= params
->tid
;
1185 u16
*ssn
= ¶ms
->ssn
;
1189 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac ampdu action action %d tid %d\n",
1192 mutex_lock(&wcn
->conf_mutex
);
1195 case IEEE80211_AMPDU_RX_START
:
1196 sta_priv
->tid
= tid
;
1197 session
= wcn36xx_smd_add_ba_session(wcn
, sta
, tid
, ssn
, 0,
1198 get_sta_index(vif
, sta_priv
));
1203 wcn36xx_smd_add_ba(wcn
, session
);
1205 case IEEE80211_AMPDU_RX_STOP
:
1206 wcn36xx_smd_del_ba(wcn
, tid
, 0, get_sta_index(vif
, sta_priv
));
1208 case IEEE80211_AMPDU_TX_START
:
1209 spin_lock_bh(&sta_priv
->ampdu_lock
);
1210 sta_priv
->ampdu_state
[tid
] = WCN36XX_AMPDU_START
;
1211 spin_unlock_bh(&sta_priv
->ampdu_lock
);
1213 /* Replace the mac80211 ssn with the firmware one */
1214 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac ampdu ssn = %u\n", *ssn
);
1215 wcn36xx_smd_trigger_ba(wcn
, get_sta_index(vif
, sta_priv
), tid
, ssn
);
1216 wcn36xx_dbg(WCN36XX_DBG_MAC
, "mac ampdu fw-ssn = %u\n", *ssn
);
1218 /* Start BA session */
1219 session
= wcn36xx_smd_add_ba_session(wcn
, sta
, tid
, ssn
, 1,
1220 get_sta_index(vif
, sta_priv
));
1225 ret
= IEEE80211_AMPDU_TX_START_IMMEDIATE
;
1227 case IEEE80211_AMPDU_TX_OPERATIONAL
:
1228 spin_lock_bh(&sta_priv
->ampdu_lock
);
1229 sta_priv
->ampdu_state
[tid
] = WCN36XX_AMPDU_OPERATIONAL
;
1230 spin_unlock_bh(&sta_priv
->ampdu_lock
);
1233 case IEEE80211_AMPDU_TX_STOP_FLUSH
:
1234 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT
:
1235 case IEEE80211_AMPDU_TX_STOP_CONT
:
1236 spin_lock_bh(&sta_priv
->ampdu_lock
);
1237 sta_priv
->ampdu_state
[tid
] = WCN36XX_AMPDU_NONE
;
1238 spin_unlock_bh(&sta_priv
->ampdu_lock
);
1240 wcn36xx_smd_del_ba(wcn
, tid
, 1, get_sta_index(vif
, sta_priv
));
1241 ieee80211_stop_tx_ba_cb_irqsafe(vif
, sta
->addr
, tid
);
1244 wcn36xx_err("Unknown AMPDU action\n");
1248 mutex_unlock(&wcn
->conf_mutex
);
1253 #if IS_ENABLED(CONFIG_IPV6)
1254 static void wcn36xx_ipv6_addr_change(struct ieee80211_hw
*hw
,
1255 struct ieee80211_vif
*vif
,
1256 struct inet6_dev
*idev
)
1258 struct wcn36xx_vif
*vif_priv
= wcn36xx_vif_to_priv(vif
);
1259 struct inet6_ifaddr
*ifa
;
1262 memset(vif_priv
->tentative_addrs
, 0, sizeof(vif_priv
->tentative_addrs
));
1264 read_lock_bh(&idev
->lock
);
1265 list_for_each_entry(ifa
, &idev
->addr_list
, if_list
) {
1266 vif_priv
->target_ipv6_addrs
[idx
] = ifa
->addr
;
1267 if (ifa
->flags
& IFA_F_TENTATIVE
)
1268 __set_bit(idx
, vif_priv
->tentative_addrs
);
1270 if (idx
>= WCN36XX_HAL_IPV6_OFFLOAD_ADDR_MAX
)
1272 wcn36xx_dbg(WCN36XX_DBG_MAC
, "%pI6 %s\n", &ifa
->addr
,
1273 (ifa
->flags
& IFA_F_TENTATIVE
) ? "tentative" : NULL
);
1275 read_unlock_bh(&idev
->lock
);
1277 vif_priv
->num_target_ipv6_addrs
= idx
;
1281 static void wcn36xx_flush(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
1282 u32 queues
, bool drop
)
1284 struct wcn36xx
*wcn
= hw
->priv
;
1286 if (wcn36xx_dxe_tx_flush(wcn
)) {
1287 wcn36xx_err("Failed to flush hardware tx queues\n");
1291 static int wcn36xx_get_survey(struct ieee80211_hw
*hw
, int idx
,
1292 struct survey_info
*survey
)
1294 struct wcn36xx
*wcn
= hw
->priv
;
1295 struct ieee80211_supported_band
*sband
;
1296 struct wcn36xx_chan_survey
*chan_survey
;
1298 unsigned long flags
;
1300 sband
= wcn
->hw
->wiphy
->bands
[NL80211_BAND_2GHZ
];
1302 if (band_idx
>= sband
->n_channels
) {
1303 band_idx
-= sband
->n_channels
;
1304 sband
= wcn
->hw
->wiphy
->bands
[NL80211_BAND_5GHZ
];
1307 if (!sband
|| band_idx
>= sband
->n_channels
)
1310 spin_lock_irqsave(&wcn
->survey_lock
, flags
);
1312 chan_survey
= &wcn
->chan_survey
[idx
];
1313 survey
->channel
= &sband
->channels
[band_idx
];
1314 survey
->noise
= chan_survey
->rssi
- chan_survey
->snr
;
1317 if (chan_survey
->rssi
> -100 && chan_survey
->rssi
< 0)
1318 survey
->filled
|= SURVEY_INFO_NOISE_DBM
;
1320 if (survey
->channel
== wcn
->channel
)
1321 survey
->filled
|= SURVEY_INFO_IN_USE
;
1323 spin_unlock_irqrestore(&wcn
->survey_lock
, flags
);
1325 wcn36xx_dbg(WCN36XX_DBG_MAC
,
1326 "ch %d rssi %d snr %d noise %d filled %x freq %d\n",
1327 HW_VALUE_CHANNEL(survey
->channel
->hw_value
),
1328 chan_survey
->rssi
, chan_survey
->snr
, survey
->noise
,
1329 survey
->filled
, survey
->channel
->center_freq
);
1334 static void wcn36xx_sta_statistics(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
1335 struct ieee80211_sta
*sta
, struct station_info
*sinfo
)
1337 struct wcn36xx
*wcn
;
1342 sta_index
= get_sta_index(vif
, wcn36xx_sta_to_priv(sta
));
1343 status
= wcn36xx_smd_get_stats(wcn
, sta_index
, HAL_GLOBAL_CLASS_A_STATS_INFO
, sinfo
);
1346 wcn36xx_err("wcn36xx_smd_get_stats failed\n");
1349 static const struct ieee80211_ops wcn36xx_ops
= {
1350 .add_chanctx
= ieee80211_emulate_add_chanctx
,
1351 .remove_chanctx
= ieee80211_emulate_remove_chanctx
,
1352 .change_chanctx
= ieee80211_emulate_change_chanctx
,
1353 .switch_vif_chanctx
= ieee80211_emulate_switch_vif_chanctx
,
1354 .start
= wcn36xx_start
,
1355 .stop
= wcn36xx_stop
,
1356 .add_interface
= wcn36xx_add_interface
,
1357 .remove_interface
= wcn36xx_remove_interface
,
1359 .suspend
= wcn36xx_suspend
,
1360 .resume
= wcn36xx_resume
,
1361 .set_rekey_data
= wcn36xx_set_rekey_data
,
1363 .config
= wcn36xx_config
,
1364 .prepare_multicast
= wcn36xx_prepare_multicast
,
1365 .configure_filter
= wcn36xx_configure_filter
,
1367 .wake_tx_queue
= ieee80211_handle_wake_tx_queue
,
1368 .set_key
= wcn36xx_set_key
,
1369 .hw_scan
= wcn36xx_hw_scan
,
1370 .cancel_hw_scan
= wcn36xx_cancel_hw_scan
,
1371 .sw_scan_start
= wcn36xx_sw_scan_start
,
1372 .sw_scan_complete
= wcn36xx_sw_scan_complete
,
1373 .bss_info_changed
= wcn36xx_bss_info_changed
,
1374 .set_rts_threshold
= wcn36xx_set_rts_threshold
,
1375 .sta_add
= wcn36xx_sta_add
,
1376 .sta_remove
= wcn36xx_sta_remove
,
1377 .sta_statistics
= wcn36xx_sta_statistics
,
1378 .ampdu_action
= wcn36xx_ampdu_action
,
1379 #if IS_ENABLED(CONFIG_IPV6)
1380 .ipv6_addr_change
= wcn36xx_ipv6_addr_change
,
1382 .flush
= wcn36xx_flush
,
1383 .get_survey
= wcn36xx_get_survey
,
1385 CFG80211_TESTMODE_CMD(wcn36xx_tm_cmd
)
1389 wcn36xx_set_ieee80211_vht_caps(struct ieee80211_sta_vht_cap
*vht_cap
)
1391 vht_cap
->vht_supported
= true;
1393 vht_cap
->cap
= (IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895
|
1394 IEEE80211_VHT_CAP_SHORT_GI_80
|
1395 IEEE80211_VHT_CAP_RXSTBC_1
|
1396 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE
|
1397 IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE
|
1398 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT
|
1399 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT
);
1401 vht_cap
->vht_mcs
.rx_mcs_map
=
1402 cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9
|
1403 IEEE80211_VHT_MCS_NOT_SUPPORTED
<< 2 |
1404 IEEE80211_VHT_MCS_NOT_SUPPORTED
<< 4 |
1405 IEEE80211_VHT_MCS_NOT_SUPPORTED
<< 6 |
1406 IEEE80211_VHT_MCS_NOT_SUPPORTED
<< 8 |
1407 IEEE80211_VHT_MCS_NOT_SUPPORTED
<< 10 |
1408 IEEE80211_VHT_MCS_NOT_SUPPORTED
<< 12 |
1409 IEEE80211_VHT_MCS_NOT_SUPPORTED
<< 14);
1411 vht_cap
->vht_mcs
.rx_highest
= cpu_to_le16(433);
1412 vht_cap
->vht_mcs
.tx_highest
= vht_cap
->vht_mcs
.rx_highest
;
1414 vht_cap
->vht_mcs
.tx_mcs_map
= vht_cap
->vht_mcs
.rx_mcs_map
;
1417 static int wcn36xx_init_ieee80211(struct wcn36xx
*wcn
)
1419 static const u32 cipher_suites
[] = {
1420 WLAN_CIPHER_SUITE_WEP40
,
1421 WLAN_CIPHER_SUITE_WEP104
,
1422 WLAN_CIPHER_SUITE_TKIP
,
1423 WLAN_CIPHER_SUITE_CCMP
,
1426 ieee80211_hw_set(wcn
->hw
, TIMING_BEACON_ONLY
);
1427 ieee80211_hw_set(wcn
->hw
, AMPDU_AGGREGATION
);
1428 ieee80211_hw_set(wcn
->hw
, SUPPORTS_PS
);
1429 ieee80211_hw_set(wcn
->hw
, SIGNAL_DBM
);
1430 ieee80211_hw_set(wcn
->hw
, HAS_RATE_CONTROL
);
1431 ieee80211_hw_set(wcn
->hw
, SINGLE_SCAN_ON_ALL_BANDS
);
1432 ieee80211_hw_set(wcn
->hw
, REPORTS_TX_ACK_STATUS
);
1434 wcn
->hw
->wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
1435 BIT(NL80211_IFTYPE_AP
) |
1436 BIT(NL80211_IFTYPE_ADHOC
) |
1437 BIT(NL80211_IFTYPE_MESH_POINT
);
1439 wcn
->hw
->wiphy
->bands
[NL80211_BAND_2GHZ
] = &wcn_band_2ghz
;
1440 if (wcn
->rf_id
!= RF_IRIS_WCN3620
)
1441 wcn
->hw
->wiphy
->bands
[NL80211_BAND_5GHZ
] = &wcn_band_5ghz
;
1443 if (wcn
->rf_id
== RF_IRIS_WCN3680
)
1444 wcn36xx_set_ieee80211_vht_caps(&wcn_band_5ghz
.vht_cap
);
1446 wcn
->hw
->wiphy
->max_scan_ssids
= WCN36XX_MAX_SCAN_SSIDS
;
1447 wcn
->hw
->wiphy
->max_scan_ie_len
= WCN36XX_MAX_SCAN_IE_LEN
;
1449 wcn
->hw
->wiphy
->cipher_suites
= cipher_suites
;
1450 wcn
->hw
->wiphy
->n_cipher_suites
= ARRAY_SIZE(cipher_suites
);
1453 wcn
->hw
->wiphy
->wowlan
= &wowlan_support
;
1456 wcn
->hw
->max_listen_interval
= 200;
1458 wcn
->hw
->queues
= 4;
1460 SET_IEEE80211_DEV(wcn
->hw
, wcn
->dev
);
1462 wcn
->hw
->sta_data_size
= sizeof(struct wcn36xx_sta
);
1463 wcn
->hw
->vif_data_size
= sizeof(struct wcn36xx_vif
);
1465 wiphy_ext_feature_set(wcn
->hw
->wiphy
,
1466 NL80211_EXT_FEATURE_CQM_RSSI_LIST
);
1471 static int wcn36xx_platform_get_resources(struct wcn36xx
*wcn
,
1472 struct platform_device
*pdev
)
1474 struct device_node
*mmio_node
;
1475 struct device_node
*iris_node
;
1480 ret
= platform_get_irq_byname(pdev
, "tx");
1486 ret
= platform_get_irq_byname(pdev
, "rx");
1491 /* Acquire SMSM tx enable handle */
1492 wcn
->tx_enable_state
= qcom_smem_state_get(&pdev
->dev
,
1493 "tx-enable", &wcn
->tx_enable_state_bit
);
1494 if (IS_ERR(wcn
->tx_enable_state
)) {
1495 wcn36xx_err("failed to get tx-enable state\n");
1496 return PTR_ERR(wcn
->tx_enable_state
);
1499 /* Acquire SMSM tx rings empty handle */
1500 wcn
->tx_rings_empty_state
= qcom_smem_state_get(&pdev
->dev
,
1501 "tx-rings-empty", &wcn
->tx_rings_empty_state_bit
);
1502 if (IS_ERR(wcn
->tx_rings_empty_state
)) {
1503 wcn36xx_err("failed to get tx-rings-empty state\n");
1504 return PTR_ERR(wcn
->tx_rings_empty_state
);
1507 mmio_node
= of_parse_phandle(pdev
->dev
.parent
->of_node
, "qcom,mmio", 0);
1509 wcn36xx_err("failed to acquire qcom,mmio reference\n");
1513 wcn
->is_pronto
= !!of_device_is_compatible(mmio_node
, "qcom,pronto");
1514 wcn
->is_pronto_v3
= !!of_device_is_compatible(mmio_node
, "qcom,pronto-v3-pil");
1516 /* Map the CCU memory */
1517 index
= of_property_match_string(mmio_node
, "reg-names", "ccu");
1518 wcn
->ccu_base
= of_iomap(mmio_node
, index
);
1519 if (!wcn
->ccu_base
) {
1520 wcn36xx_err("failed to map ccu memory\n");
1525 /* Map the DXE memory */
1526 index
= of_property_match_string(mmio_node
, "reg-names", "dxe");
1527 wcn
->dxe_base
= of_iomap(mmio_node
, index
);
1528 if (!wcn
->dxe_base
) {
1529 wcn36xx_err("failed to map dxe memory\n");
1534 /* External RF module */
1535 iris_node
= of_get_child_by_name(mmio_node
, "iris");
1537 if (of_device_is_compatible(iris_node
, "qcom,wcn3620"))
1538 wcn
->rf_id
= RF_IRIS_WCN3620
;
1539 if (of_device_is_compatible(iris_node
, "qcom,wcn3660") ||
1540 of_device_is_compatible(iris_node
, "qcom,wcn3660b"))
1541 wcn
->rf_id
= RF_IRIS_WCN3660
;
1542 if (of_device_is_compatible(iris_node
, "qcom,wcn3680"))
1543 wcn
->rf_id
= RF_IRIS_WCN3680
;
1544 of_node_put(iris_node
);
1547 of_node_put(mmio_node
);
1551 iounmap(wcn
->ccu_base
);
1553 of_node_put(mmio_node
);
1557 static int wcn36xx_probe(struct platform_device
*pdev
)
1559 struct ieee80211_hw
*hw
;
1560 struct wcn36xx
*wcn
;
1566 wcn36xx_dbg(WCN36XX_DBG_MAC
, "platform probe\n");
1568 wcnss
= dev_get_drvdata(pdev
->dev
.parent
);
1570 hw
= ieee80211_alloc_hw(sizeof(struct wcn36xx
), &wcn36xx_ops
);
1572 wcn36xx_err("failed to alloc hw\n");
1576 platform_set_drvdata(pdev
, hw
);
1579 wcn
->dev
= &pdev
->dev
;
1580 wcn
->first_boot
= true;
1581 mutex_init(&wcn
->conf_mutex
);
1582 mutex_init(&wcn
->hal_mutex
);
1583 mutex_init(&wcn
->scan_lock
);
1584 __skb_queue_head_init(&wcn
->amsdu
);
1586 wcn
->hal_buf
= devm_kmalloc(wcn
->dev
, WCN36XX_HAL_BUF_SIZE
, GFP_KERNEL
);
1587 if (!wcn
->hal_buf
) {
1592 n_channels
= wcn_band_2ghz
.n_channels
+ wcn_band_5ghz
.n_channels
;
1593 wcn
->chan_survey
= devm_kmalloc(wcn
->dev
, n_channels
, GFP_KERNEL
);
1594 if (!wcn
->chan_survey
) {
1599 ret
= dma_set_mask_and_coherent(wcn
->dev
, DMA_BIT_MASK(32));
1601 wcn36xx_err("failed to set DMA mask: %d\n", ret
);
1605 wcn
->nv_file
= WLAN_NV_FILE
;
1606 ret
= of_property_read_string(wcn
->dev
->parent
->of_node
, "firmware-name", &wcn
->nv_file
);
1607 if (ret
< 0 && ret
!= -EINVAL
) {
1608 wcn36xx_err("failed to read \"firmware-name\" property: %d\n", ret
);
1612 wcn
->smd_channel
= qcom_wcnss_open_channel(wcnss
, "WLAN_CTRL", wcn36xx_smd_rsp_process
, hw
);
1613 if (IS_ERR(wcn
->smd_channel
)) {
1614 wcn36xx_err("failed to open WLAN_CTRL channel\n");
1615 ret
= PTR_ERR(wcn
->smd_channel
);
1619 addr
= of_get_property(pdev
->dev
.of_node
, "local-mac-address", &ret
);
1620 if (addr
&& ret
!= ETH_ALEN
) {
1621 wcn36xx_err("invalid local-mac-address\n");
1623 goto out_destroy_ept
;
1625 wcn36xx_info("mac address: %pM\n", addr
);
1626 SET_IEEE80211_PERM_ADDR(wcn
->hw
, addr
);
1629 ret
= wcn36xx_platform_get_resources(wcn
, pdev
);
1631 goto out_destroy_ept
;
1633 wcn36xx_init_ieee80211(wcn
);
1634 ret
= ieee80211_register_hw(wcn
->hw
);
1641 iounmap(wcn
->ccu_base
);
1642 iounmap(wcn
->dxe_base
);
1644 rpmsg_destroy_ept(wcn
->smd_channel
);
1646 ieee80211_free_hw(hw
);
1651 static void wcn36xx_remove(struct platform_device
*pdev
)
1653 struct ieee80211_hw
*hw
= platform_get_drvdata(pdev
);
1654 struct wcn36xx
*wcn
= hw
->priv
;
1655 wcn36xx_dbg(WCN36XX_DBG_MAC
, "platform remove\n");
1657 release_firmware(wcn
->nv
);
1659 ieee80211_unregister_hw(hw
);
1661 qcom_smem_state_put(wcn
->tx_enable_state
);
1662 qcom_smem_state_put(wcn
->tx_rings_empty_state
);
1664 rpmsg_destroy_ept(wcn
->smd_channel
);
1666 iounmap(wcn
->dxe_base
);
1667 iounmap(wcn
->ccu_base
);
1669 __skb_queue_purge(&wcn
->amsdu
);
1671 mutex_destroy(&wcn
->hal_mutex
);
1672 ieee80211_free_hw(hw
);
1675 static const struct of_device_id wcn36xx_of_match
[] = {
1676 { .compatible
= "qcom,wcnss-wlan" },
1679 MODULE_DEVICE_TABLE(of
, wcn36xx_of_match
);
1681 static struct platform_driver wcn36xx_driver
= {
1682 .probe
= wcn36xx_probe
,
1683 .remove
= wcn36xx_remove
,
1686 .of_match_table
= wcn36xx_of_match
,
1690 module_platform_driver(wcn36xx_driver
);
1692 MODULE_DESCRIPTION("Qualcomm Atheros WCN3660/3680 wireless driver");
1693 MODULE_LICENSE("Dual BSD/GPL");
1694 MODULE_AUTHOR("Eugene Krasnikov k.eugene.e@gmail.com");
1695 MODULE_FIRMWARE(WLAN_NV_FILE
);