1 /***************************************************************************
3 * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
5 ****************************************************************************/
7 #include <linux/version.h>
8 #include <net/cfg80211.h>
9 #include <linux/etherdevice.h>
11 #include "cfg80211_ops.h"
20 #include "scsc_wifilogger_rings.h"
22 #include "nl80211_vendor.h"
24 #define SLSI_MAX_CHAN_2G_BAND 14
26 static uint keep_alive_period
= SLSI_P2PGO_KEEP_ALIVE_PERIOD_SEC
;
27 module_param(keep_alive_period
, uint
, S_IRUGO
| S_IWUSR
);
28 MODULE_PARM_DESC(keep_alive_period
, "default is 10 seconds");
30 static bool slsi_is_mhs_active(struct slsi_dev
*sdev
)
32 struct net_device
*mhs_dev
= sdev
->netdev_ap
;
33 struct netdev_vif
*ndev_vif
;
37 ndev_vif
= netdev_priv(mhs_dev
);
38 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
39 ret
= ndev_vif
->is_available
;
40 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
47 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
48 struct wireless_dev
*slsi_add_virtual_intf(struct wiphy
*wiphy
,
50 unsigned char name_assign_type
,
51 enum nl80211_iftype type
,
52 struct vif_params
*params
)
54 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
55 struct wireless_dev
*slsi_add_virtual_intf(struct wiphy
*wiphy
,
57 unsigned char name_assign_type
,
58 enum nl80211_iftype type
,
60 struct vif_params
*params
)
62 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
63 struct wireless_dev
*slsi_add_virtual_intf(struct wiphy
*wiphy
,
65 enum nl80211_iftype type
,
67 struct vif_params
*params
)
70 struct net_device
*slsi_add_
virtual_intf(struct wiphy
*wiphy
,
72 enum nl80211_iftype type
,
74 struct vif_params
*params
)
78 struct net_device
*dev
= NULL
;
79 struct netdev_vif
*ndev_vif
= NULL
;
80 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
82 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 11, 0))
83 SLSI_UNUSED_PARAMETER(flags
);
85 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "Intf name:%s, type:%d, macaddr:%pM\n", name
, type
, params
->macaddr
);
86 if (slsi_is_mhs_active(sdev
)) {
87 SLSI_ERR(sdev
, "MHS is active. cannot add new interface\n");
88 return ERR_PTR(-EOPNOTSUPP
);
90 dev
= slsi_dynamic_interface_create(wiphy
, name
, type
, params
);
93 ndev_vif
= netdev_priv(dev
);
95 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
96 return &ndev_vif
->wdev
;
99 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) */
102 return ERR_PTR(-ENODEV
);
105 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
106 int slsi_del_virtual_intf(struct wiphy
*wiphy
, struct wireless_dev
*wdev
)
108 struct net_device
*dev
= wdev
->netdev
;
111 int slsi_del_virtual_intf(struct wiphy
*wiphy
, struct net_device
*dev
)
114 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
119 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "Dev name:%s\n", dev
->name
);
121 slsi_stop_net_dev(sdev
, dev
);
122 slsi_netif_remove_rtlnl_locked(sdev
, dev
);
123 SLSI_MUTEX_LOCK(sdev
->netdev_add_remove_mutex
);
124 if (dev
== sdev
->netdev_ap
)
125 rcu_assign_pointer(sdev
->netdev_ap
, NULL
);
126 if (!sdev
->netdev
[SLSI_NET_INDEX_P2PX_SWLAN
])
127 rcu_assign_pointer(sdev
->netdev
[SLSI_NET_INDEX_P2PX_SWLAN
], sdev
->netdev_ap
);
128 SLSI_MUTEX_UNLOCK(sdev
->netdev_add_remove_mutex
);
133 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
134 int slsi_change_virtual_intf(struct wiphy
*wiphy
,
135 struct net_device
*dev
,
136 enum nl80211_iftype type
,
137 struct vif_params
*params
)
140 int slsi_change_virtual_intf(struct wiphy
*wiphy
,
141 struct net_device
*dev
,
142 enum nl80211_iftype type
,
144 struct vif_params
*params
)
148 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
151 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 11, 0))
152 SLSI_UNUSED_PARAMETER(flags
);
155 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
157 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "type:%u, iftype:%d\n", type
, ndev_vif
->iftype
);
159 if (WARN_ON(ndev_vif
->activated
)) {
165 case NL80211_IFTYPE_UNSPECIFIED
:
166 case NL80211_IFTYPE_ADHOC
:
167 case NL80211_IFTYPE_STATION
:
168 case NL80211_IFTYPE_AP
:
169 case NL80211_IFTYPE_P2P_CLIENT
:
170 case NL80211_IFTYPE_P2P_GO
:
171 #ifdef CONFIG_SCSC_WLAN_DEBUG
172 case NL80211_IFTYPE_MONITOR
:
174 ndev_vif
->iftype
= type
;
175 dev
->ieee80211_ptr
->iftype
= type
;
177 dev
->ieee80211_ptr
->use_4addr
= params
->use_4addr
;
185 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
189 int slsi_add_key(struct wiphy
*wiphy
, struct net_device
*dev
,
190 u8 key_index
, bool pairwise
, const u8
*mac_addr
,
191 struct key_params
*params
)
193 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
194 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
195 struct slsi_peer
*peer
= NULL
;
197 u16 key_type
= FAPI_KEYTYPE_GROUP
;
199 if (WARN_ON(pairwise
&& !mac_addr
))
202 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
204 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "(key_index:%d, pairwise:%d, address:%pM, cipher:0x%.8X, key_len:%d,"
205 "vif_type:%d)\n", key_index
, pairwise
, mac_addr
, params
->cipher
, params
->key_len
,
208 if (!ndev_vif
->activated
) {
209 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "vif not active\n");
213 if (params
->cipher
== WLAN_CIPHER_SUITE_PMK
) {
214 r
= slsi_mlme_set_pmk(sdev
, dev
, params
->key
, params
->key_len
);
218 if (mac_addr
&& pairwise
) {
219 /* All Pairwise Keys will have a peer record. */
220 peer
= slsi_get_peer_from_mac(sdev
, dev
, mac_addr
);
222 mac_addr
= peer
->address
;
223 } else if (ndev_vif
->vif_type
== FAPI_VIFTYPE_STATION
) {
224 /* Sta Group Key will use the peer address */
225 peer
= slsi_get_peer_from_qs(sdev
, dev
, SLSI_STA_PEER_QUEUESET
);
227 mac_addr
= peer
->address
;
228 } else if (ndev_vif
->vif_type
== FAPI_VIFTYPE_AP
&& !pairwise
)
229 /* AP Group Key will use the Interface address */
230 mac_addr
= dev
->dev_addr
;
236 /*Treat WEP key as pairwise key*/
237 if ((ndev_vif
->vif_type
== FAPI_VIFTYPE_STATION
) &&
238 ((params
->cipher
== WLAN_CIPHER_SUITE_WEP40
) ||
239 (params
->cipher
== WLAN_CIPHER_SUITE_WEP104
)) && peer
) {
240 u8 bc_mac_addr
[ETH_ALEN
] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
242 SLSI_NET_DBG3(dev
, SLSI_CFG80211
, "WEP Key: store key\n");
243 r
= slsi_mlme_set_key(sdev
, dev
, key_index
, FAPI_KEYTYPE_WEP
, bc_mac_addr
, params
);
244 if (r
== FAPI_RESULTCODE_SUCCESS
) {
245 /* if static ip is set before connection, after setting keys enable powersave. */
246 if (ndev_vif
->ipaddress
)
247 slsi_mlme_powermgt(sdev
, dev
, ndev_vif
->set_power_mode
);
249 SLSI_NET_ERR(dev
, "Error adding WEP key\n");
255 key_type
= FAPI_KEYTYPE_PAIRWISE
;
256 if (WARN_ON(!peer
)) {
260 } else if (params
->cipher
== WLAN_CIPHER_SUITE_AES_CMAC
) {
261 key_type
= FAPI_KEYTYPE_IGTK
;
264 if (WARN(!mac_addr
, "mac_addr not defined\n")) {
268 if (!((ndev_vif
->vif_type
== FAPI_VIFTYPE_AP
) && (key_index
== 4))) {
269 r
= slsi_mlme_set_key(sdev
, dev
, key_index
, key_type
, mac_addr
, params
);
271 SLSI_NET_ERR(dev
, "error in adding key (key_type: %d)\n", key_type
);
276 if (ndev_vif
->vif_type
== FAPI_VIFTYPE_STATION
) {
277 ndev_vif
->sta
.eap_hosttag
= 0xFFFF;
278 /* if static IP is set before connection, after setting keys enable powersave. */
279 if (ndev_vif
->ipaddress
)
280 slsi_mlme_powermgt(sdev
, dev
, ndev_vif
->set_power_mode
);
283 if (key_type
== FAPI_KEYTYPE_GROUP
) {
284 ndev_vif
->sta
.group_key_set
= true;
285 ndev_vif
->ap
.cipher
= params
->cipher
;
286 } else if (key_type
== FAPI_KEYTYPE_PAIRWISE
) {
288 peer
->pairwise_key_set
= true;
292 if (ndev_vif
->vif_type
== FAPI_VIFTYPE_STATION
) {
294 if (params
->cipher
== WLAN_CIPHER_SUITE_SMS4
) { /*WAPI */
295 slsi_mlme_connect_resp(sdev
, dev
);
296 slsi_set_packet_filters(sdev
, dev
);
297 slsi_ps_port_control(sdev
, dev
, peer
, SLSI_STA_CONN_STATE_CONNECTED
);
301 if (ndev_vif
->sta
.gratuitous_arp_needed
) {
302 ndev_vif
->sta
.gratuitous_arp_needed
= false;
303 slsi_send_gratuitous_arp(sdev
, dev
);
305 } else if (ndev_vif
->vif_type
== FAPI_VIFTYPE_AP
&& pairwise
) {
306 slsi_mlme_connected_resp(sdev
, dev
, peer
->aid
);
307 slsi_ps_port_control(sdev
, dev
, peer
, SLSI_STA_CONN_STATE_CONNECTED
);
308 peer
->connected_state
= SLSI_STA_CONN_STATE_CONNECTED
;
309 if (ndev_vif
->iftype
== NL80211_IFTYPE_P2P_GO
)
310 ndev_vif
->ap
.p2p_gc_keys_set
= true;
315 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
319 int slsi_del_key(struct wiphy
*wiphy
, struct net_device
*dev
,
320 u8 key_index
, bool pairwise
, const u8
*mac_addr
)
322 SLSI_UNUSED_PARAMETER(wiphy
);
323 SLSI_UNUSED_PARAMETER(key_index
);
324 SLSI_UNUSED_PARAMETER(pairwise
);
325 SLSI_UNUSED_PARAMETER(mac_addr
);
327 if (slsi_is_test_mode_enabled()) {
328 SLSI_NET_INFO(dev
, "Skip sending signal, WlanLite FW does not support MLME_DELETEKEYS.request\n");
335 int slsi_get_key(struct wiphy
*wiphy
, struct net_device
*dev
,
336 u8 key_index
, bool pairwise
, const u8
*mac_addr
,
338 void (*callback
)(void *cookie
, struct key_params
*))
340 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
341 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
342 struct key_params params
;
344 #define SLSI_MAX_KEY_SIZE 8 /*used only for AP case, so WAPI not considered*/
345 u8 key_seq
[SLSI_MAX_KEY_SIZE
] = { 0 };
348 SLSI_UNUSED_PARAMETER(mac_addr
);
350 if (slsi_is_test_mode_enabled()) {
351 SLSI_NET_INFO(dev
, "Skip sending signal, WlanLite FW does not support MLME_GET_KEY_SEQUENCE.request\n");
355 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
357 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "(key_index:%d, pairwise:%d, mac_addr:%pM, vif_type:%d)\n", key_index
,
358 pairwise
, mac_addr
, ndev_vif
->vif_type
);
360 if (!ndev_vif
->activated
) {
361 SLSI_NET_ERR(dev
, "vif not active\n");
366 /* The get_key call is expected only for AP vif with Group Key type */
367 if (FAPI_VIFTYPE_AP
!= ndev_vif
->vif_type
) {
368 SLSI_NET_ERR(dev
, "Invalid vif type: %d\n", ndev_vif
->vif_type
);
373 SLSI_NET_ERR(dev
, "Invalid key type\n");
378 memset(¶ms
, 0, sizeof(params
));
379 /* Update params with sequence number, key field would be updated NULL */
382 params
.cipher
= ndev_vif
->ap
.cipher
;
383 if (!((ndev_vif
->vif_type
== FAPI_VIFTYPE_AP
) && (key_index
== 4))) {
384 r
= slsi_mlme_get_key(sdev
, dev
, key_index
, FAPI_KEYTYPE_GROUP
, key_seq
, ¶ms
.seq_len
);
387 params
.seq
= key_seq
;
388 callback(cookie
, ¶ms
);
391 #undef SLSI_MAX_KEY_SIZE
393 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
397 static size_t slsi_strip_wsc_p2p_ie(const u8
*src_ie
, size_t src_ie_len
, u8
*dest_ie
, bool strip_wsc
, bool strip_p2p
)
401 size_t dest_ie_len
= 0;
403 if (!dest_ie
|| !(strip_p2p
|| strip_wsc
))
406 for (ie
= src_ie
; (ie
- src_ie
) < src_ie_len
; ie
= next_ie
) {
407 next_ie
= ie
+ ie
[1] + 2;
409 if (ie
[0] == WLAN_EID_VENDOR_SPECIFIC
&& ie
[1] > 4) {
411 unsigned int oui
= 0;
413 for (i
= 0; i
< 4; i
++)
414 oui
= (oui
<< 8) | ie
[5 - i
];
416 if (strip_wsc
&& (oui
== SLSI_WPS_OUI_PATTERN
))
418 if (strip_p2p
&& (oui
== SLSI_P2P_OUI_PATTERN
))
422 if (next_ie
- src_ie
<= src_ie_len
) {
423 memcpy(dest_ie
+ dest_ie_len
, ie
, ie
[1] + 2);
424 dest_ie_len
+= ie
[1] + 2;
431 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
432 int slsi_scan(struct wiphy
*wiphy
,
433 struct cfg80211_scan_request
*request
)
435 struct net_device
*dev
= request
->wdev
->netdev
;
438 int slsi_scan(struct wiphy
*wiphy
, struct net_device
*dev
,
439 struct cfg80211_scan_request
*request
)
441 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) */
443 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
444 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
445 u16 scan_type
= FAPI_SCANTYPE_FULL_SCAN
;
449 bool strip_wsc
= false;
450 bool strip_p2p
= false;
451 struct ieee80211_channel
*channels
[64];
452 int i
, chan_count
= 0;
453 struct cfg80211_scan_info info
= {.aborted
= false};
454 #ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION
455 u8 mac_addr_mask
[ETH_ALEN
] = {0xFF};
458 if (WARN_ON(!request
->wdev
))
463 if (slsi_is_test_mode_enabled()) {
464 SLSI_NET_WARN(dev
, "not supported in WlanLite mode\n");
468 /* Reject scan request if Group Formation is in progress */
469 if (sdev
->p2p_state
== P2P_ACTION_FRAME_TX_RX
) {
470 SLSI_NET_INFO(dev
, "Scan received in P2P Action Frame Tx/Rx state - Reject\n");
474 SLSI_MUTEX_LOCK(ndev_vif
->scan_mutex
);
476 if (ndev_vif
->scan
[SLSI_SCAN_HW_ID
].scan_req
) {
477 SLSI_NET_INFO(dev
, "Rejecting scan request as last scan is still running\n");
481 #ifdef CONFIG_SLSI_WLAN_STA_FWD_BEACON
482 if (ndev_vif
->is_wips_running
&& (ndev_vif
->vif_type
== FAPI_VIFTYPE_STATION
) &&
483 (ndev_vif
->sta
.vif_status
== SLSI_VIF_STATUS_CONNECTED
)) {
486 SLSI_NET_DBG3(dev
, SLSI_CFG80211
, "Scan invokes DRIVER_BCN_ABORT\n");
487 ret
= slsi_mlme_set_forward_beacon(sdev
, dev
, FAPI_ACTION_STOP
);
490 ret
= slsi_send_forward_beacon_abort_vendor_event(sdev
,
491 SLSI_FORWARD_BEACON_ABORT_REASON_SCANNING
);
495 SLSI_NET_DBG3(dev
, SLSI_CFG80211
, "channels:%d, ssids:%d, ie_len:%d, vif_index:%d\n", request
->n_channels
,
496 request
->n_ssids
, (int)request
->ie_len
, ndev_vif
->ifnum
);
498 for (i
= 0; i
< request
->n_channels
; i
++)
499 channels
[i
] = request
->channels
[i
];
500 chan_count
= request
->n_channels
;
502 if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif
)) {
503 if (sdev
->initial_scan
) {
504 sdev
->initial_scan
= false;
505 scan_type
= FAPI_SCANTYPE_INITIAL_SCAN
;
507 ndev_vif
->unsync
.slsi_p2p_continuous_fullscan
= false;
510 /* Update scan timing for P2P social channels scan.*/
512 cfg80211_find_vendor_ie(WLAN_OUI_WFA
, WLAN_OUI_TYPE_WFA_P2P
, request
->ie
, request
->ie_len
) &&
513 request
->ssids
&& SLSI_IS_P2P_SSID(request
->ssids
[0].ssid
, request
->ssids
[0].ssid_len
)) {
514 /* In supplicant during joining procedure the P2P GO scan
515 * with GO's operating channel comes on P2P device. Hence added the
516 * check for n_channels as 1
518 if (!ndev_vif
->drv_in_p2p_procedure
) {
519 if (delayed_work_pending(&ndev_vif
->unsync
.unset_channel_expiry_work
)) {
520 cancel_delayed_work(&ndev_vif
->unsync
.unset_channel_expiry_work
);
521 slsi_mlme_unset_channel_req(sdev
, dev
);
522 ndev_vif
->driver_channel
= 0;
525 if (request
->n_channels
== SLSI_P2P_SOCIAL_CHAN_COUNT
|| request
->n_channels
== 1) {
526 scan_type
= FAPI_SCANTYPE_P2P_SCAN_SOCIAL
;
527 ndev_vif
->unsync
.slsi_p2p_continuous_fullscan
= false;
528 } else if (request
->n_channels
> SLSI_P2P_SOCIAL_CHAN_COUNT
) {
529 if (!ndev_vif
->unsync
.slsi_p2p_continuous_fullscan
) {
530 scan_type
= FAPI_SCANTYPE_P2P_SCAN_FULL
;
531 ndev_vif
->unsync
.slsi_p2p_continuous_fullscan
= true;
533 int count
= 0, chann
= 0;
535 scan_type
= FAPI_SCANTYPE_P2P_SCAN_SOCIAL
;
536 ndev_vif
->unsync
.slsi_p2p_continuous_fullscan
= false;
537 for (i
= 0; i
< request
->n_channels
; i
++) {
538 chann
= channels
[i
]->hw_value
& 0xFF;
539 if (chann
== 1 || chann
== 6 || chann
== 11) {
540 channels
[count
] = request
->channels
[i
];
549 if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif
) && (request
->ie
)) {
552 /* check HS2 related bits in extended capabilties (interworking, WNM,QoS Map, BSS transition) and set in MIB*/
553 r
= slsi_mlme_set_hs2_ext_cap(sdev
, dev
, request
->ie
, request
->ie_len
);
557 /* Supplicant adds wsc and p2p in Station scan at the end of scan request ie.
558 * for non-wps case remove both wps and p2p IEs
559 * for wps case remove only p2p IE
562 ie
= cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT
, WLAN_OUI_TYPE_MICROSOFT_WPS
, request
->ie
, request
->ie_len
);
563 if (ie
&& ie
[1] > SLSI_WPS_REQUEST_TYPE_POS
&&
564 ie
[SLSI_WPS_REQUEST_TYPE_POS
] == SLSI_WPS_REQUEST_TYPE_ENROLEE_INFO_ONLY
)
567 ie
= cfg80211_find_vendor_ie(WLAN_OUI_WFA
, WLAN_OUI_TYPE_WFA_P2P
, request
->ie
, request
->ie_len
);
572 if (strip_wsc
|| strip_p2p
) {
573 scan_ie
= kmalloc(request
->ie_len
, GFP_KERNEL
);
575 SLSI_NET_INFO(dev
, "Out of memory for scan IEs\n");
579 scan_ie_len
= slsi_strip_wsc_p2p_ie(request
->ie
, request
->ie_len
, scan_ie
, strip_wsc
, strip_p2p
);
581 scan_ie
= (u8
*)request
->ie
;
582 scan_ie_len
= request
->ie_len
;
585 /* Flush out any outstanding single scan timeout work */
586 cancel_delayed_work(&ndev_vif
->scan_timeout_work
);
588 ndev_vif
->scan
[SLSI_SCAN_HW_ID
].is_blocking_scan
= false;
589 slsi_purge_scan_results(ndev_vif
, SLSI_SCAN_HW_ID
);
591 #ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION
592 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
593 if (request
->flags
& NL80211_SCAN_FLAG_RANDOM_ADDR
) {
594 if (sdev
->fw_mac_randomization_enabled
) {
595 memcpy(sdev
->scan_mac_addr
, request
->mac_addr
, ETH_ALEN
);
596 r
= slsi_set_mac_randomisation_mask(sdev
, request
->mac_addr_mask
);
598 sdev
->scan_addr_set
= 1;
600 SLSI_NET_INFO(dev
, "Mac Randomization is not enabled in Firmware\n");
601 sdev
->scan_addr_set
= 0;
605 if (sdev
->scan_addr_set
) {
606 memset(mac_addr_mask
, 0xFF, ETH_ALEN
);
607 r
= slsi_set_mac_randomisation_mask(sdev
, mac_addr_mask
);
608 sdev
->scan_addr_set
= 0;
612 r
= slsi_mlme_add_scan(sdev
,
615 FAPI_REPORTMODE_REAL_TIME
,
623 ndev_vif
->scan
[SLSI_SCAN_HW_ID
].is_blocking_scan
);
627 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "Nothing to be done\n");
628 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0))
629 cfg80211_scan_done(request
, &info
);
631 cfg80211_scan_done(request
, false);
635 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "add_scan error: %d\n", r
);
639 ndev_vif
->scan
[SLSI_SCAN_HW_ID
].scan_req
= request
;
641 /* if delayed work is already scheduled, queue delayed work fails. So set
642 * requeue_timeout_work flag to enqueue delayed work in the timeout handler
644 if (queue_delayed_work(sdev
->device_wq
, &ndev_vif
->scan_timeout_work
,
645 msecs_to_jiffies(SLSI_FW_SCAN_DONE_TIMEOUT_MSEC
)))
646 ndev_vif
->scan
[SLSI_SCAN_HW_ID
].requeue_timeout_work
= false;
648 ndev_vif
->scan
[SLSI_SCAN_HW_ID
].requeue_timeout_work
= true;
650 /* Update State only for scan in Device role */
651 if (SLSI_IS_VIF_INDEX_P2P(ndev_vif
) && (!SLSI_IS_P2P_GROUP_STATE(sdev
))) {
652 if (scan_type
== FAPI_SCANTYPE_P2P_SCAN_SOCIAL
)
653 SLSI_P2P_STATE_CHANGE(sdev
, P2P_SCANNING
);
654 } else if (!SLSI_IS_VIF_INDEX_P2P(ndev_vif
) && scan_ie_len
) {
655 kfree(ndev_vif
->probe_req_ies
);
656 ndev_vif
->probe_req_ies
= kmalloc(request
->ie_len
, GFP_KERNEL
);
657 if (!ndev_vif
->probe_req_ies
) /* Don't fail, continue as it would still work */
658 ndev_vif
->probe_req_ie_len
= 0;
660 ndev_vif
->probe_req_ie_len
= scan_ie_len
;
661 memcpy(ndev_vif
->probe_req_ies
, scan_ie
, scan_ie_len
);
665 if (strip_p2p
|| strip_wsc
)
669 SLSI_MUTEX_UNLOCK(ndev_vif
->scan_mutex
);
673 int slsi_sched_scan_start(struct wiphy
*wiphy
,
674 struct net_device
*dev
,
675 struct cfg80211_sched_scan_request
*request
)
677 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
678 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
682 bool strip_wsc
= false;
683 bool strip_p2p
= false;
685 if (slsi_is_test_mode_enabled()) {
686 SLSI_NET_INFO(dev
, "Skip sending signal, WlanLite FW does not support MLME_ADD_SCAN.request\n");
690 /* Allow sched_scan only on wlan0. For P2PCLI interface, sched_scan might get requested following a
691 * wlan0 scan and its results being shared to sibling interfaces. Reject sched_scan for other interfaces.
693 if (!SLSI_IS_VIF_INDEX_WLAN(ndev_vif
)) {
694 SLSI_NET_INFO(dev
, "Scheduled scan req received on vif %d - Reject\n", ndev_vif
->ifnum
);
698 /* Unlikely to get a schedule scan while Group formation is in progress.
699 * In case it is requested, it will be rejected.
701 if (sdev
->p2p_state
== P2P_ACTION_FRAME_TX_RX
) {
702 SLSI_NET_INFO(dev
, "Scheduled scan req received in P2P Action Frame Tx/Rx state - Reject\n");
706 SLSI_MUTEX_LOCK(ndev_vif
->scan_mutex
);
708 SLSI_NET_DBG3(dev
, SLSI_CFG80211
, "channels:%d, ssids:%d, ie_len:%d, vif_index:%d\n", request
->n_channels
,
709 request
->n_ssids
, (int)request
->ie_len
, ndev_vif
->ifnum
);
711 if (ndev_vif
->scan
[SLSI_SCAN_HW_ID
].sched_req
) {
718 /* Supplicant adds wsc and p2p in Station scan at the end of scan request ie.
719 * Remove both wps and p2p IEs.
720 * Scheduled scan is not used for wsc, So no need to check for wsc request type
723 ie
= cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT
, WLAN_OUI_TYPE_MICROSOFT_WPS
, request
->ie
, request
->ie_len
);
727 ie
= cfg80211_find_vendor_ie(WLAN_OUI_WFA
, WLAN_OUI_TYPE_WFA_P2P
, request
->ie
, request
->ie_len
);
732 if (strip_wsc
|| strip_p2p
) {
733 scan_ie
= kmalloc(request
->ie_len
, GFP_KERNEL
);
735 SLSI_NET_INFO(dev
, "Out of memory for scan IEs\n");
739 scan_ie_len
= slsi_strip_wsc_p2p_ie(request
->ie
, request
->ie_len
, scan_ie
, strip_wsc
, strip_p2p
);
741 scan_ie
= (u8
*)request
->ie
;
742 scan_ie_len
= request
->ie_len
;
745 slsi_purge_scan_results(ndev_vif
, SLSI_SCAN_SCHED_ID
);
746 r
= slsi_mlme_add_sched_scan(sdev
, dev
, request
, scan_ie
, scan_ie_len
);
748 if (strip_p2p
|| strip_wsc
)
753 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "Nothing to be done\n");
754 cfg80211_sched_scan_stopped(wiphy
, request
->reqid
);
757 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "add_scan error: %d\n", r
);
761 ndev_vif
->scan
[SLSI_SCAN_SCHED_ID
].sched_req
= request
;
765 SLSI_MUTEX_UNLOCK(ndev_vif
->scan_mutex
);
769 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
770 int slsi_sched_scan_stop(struct wiphy
*wiphy
, struct net_device
*dev
, u64 reqid
)
773 int slsi_sched_scan_stop(struct wiphy
*wiphy
, struct net_device
*dev
)
776 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
777 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
780 SLSI_UNUSED_PARAMETER(reqid
);
781 SLSI_MUTEX_LOCK(ndev_vif
->scan_mutex
);
782 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "vif_index:%d", ndev_vif
->ifnum
);
783 if (!ndev_vif
->scan
[SLSI_SCAN_SCHED_ID
].sched_req
) {
784 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "No sched scan req\n");
788 r
= slsi_mlme_del_scan(sdev
, dev
, (ndev_vif
->ifnum
<< 8 | SLSI_SCAN_SCHED_ID
), false);
790 ndev_vif
->scan
[SLSI_SCAN_SCHED_ID
].sched_req
= NULL
;
793 SLSI_MUTEX_UNLOCK(ndev_vif
->scan_mutex
);
797 static void slsi_abort_hw_scan(struct slsi_dev
*sdev
, struct net_device
*dev
)
799 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
801 SLSI_MUTEX_LOCK(ndev_vif
->scan_mutex
);
803 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "Abort on-going scan, vif_index:%d,"
804 "ndev_vif->scan[SLSI_SCAN_HW_ID].scan_req:%p\n", ndev_vif
->ifnum
,
805 ndev_vif
->scan
[SLSI_SCAN_HW_ID
].scan_req
);
807 if (ndev_vif
->scan
[SLSI_SCAN_HW_ID
].scan_req
) {
808 (void)slsi_mlme_del_scan(sdev
, dev
, ndev_vif
->ifnum
<< 8 | SLSI_SCAN_HW_ID
, false);
809 slsi_scan_complete(sdev
, dev
, SLSI_SCAN_HW_ID
, false);
811 SLSI_MUTEX_UNLOCK(ndev_vif
->scan_mutex
);
814 int slsi_connect(struct wiphy
*wiphy
, struct net_device
*dev
,
815 struct cfg80211_connect_params
*sme
)
817 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
818 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
819 struct netdev_vif
*ndev_p2p_vif
;
820 u8 device_address
[ETH_ALEN
] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
822 u16 capability
= WLAN_CAPABILITY_ESS
;
823 struct slsi_peer
*peer
;
825 u32 action_frame_bmap
;
826 struct net_device
*p2p_dev
;
828 struct ieee80211_channel
*channel
;
829 const u8
*connected_ssid
= NULL
;
830 u8 peer_address
[ETH_ALEN
] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
833 if (slsi_is_test_mode_enabled()) {
834 SLSI_NET_INFO(dev
, "Skip sending signal, WlanLite FW does not support MLME_CONNECT.request\n");
837 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
838 capability
= sme
->privacy
? IEEE80211_PRIVACY_ON
: IEEE80211_PRIVACY_OFF
;
841 capability
|= WLAN_CAPABILITY_PRIVACY
;
844 SLSI_MUTEX_LOCK(sdev
->start_stop_mutex
);
845 if (sdev
->device_state
!= SLSI_DEVICE_STATE_STARTED
) {
846 SLSI_WARN(sdev
, "device not started yet (device_state:%d)\n", sdev
->device_state
);
847 SLSI_MUTEX_UNLOCK(sdev
->start_stop_mutex
);
851 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
853 if (ndev_vif
->sta
.sta_bss
)
854 SLSI_ETHER_COPY(peer_address
, ndev_vif
->sta
.sta_bss
->bssid
);
856 center_freq
= sme
->channel
? sme
->channel
->center_freq
: 0;
858 SLSI_NET_INFO(dev
, "%.*s Freq=%d vifStatus=%d CurrBssid:%pM NewBssid:%pM Qinfo:%d ieLen:%d\n",
859 (int)sme
->ssid_len
, sme
->ssid
, center_freq
, ndev_vif
->sta
.vif_status
,
860 peer_address
, sme
->bssid
, sdev
->device_config
.qos_info
, (int)sme
->ie_len
);
862 #ifdef CONFIG_SCSC_WIFILOGGER
863 SCSC_WLOG_PKTFATE_NEW_ASSOC();
865 SCSC_WLOG_DRIVER_EVENT(WLOG_NORMAL
, WIFI_EVENT_ASSOCIATION_REQUESTED
, 3,
866 WIFI_TAG_BSSID
, ETH_ALEN
, sme
->bssid
,
867 WIFI_TAG_SSID
, sme
->ssid_len
, sme
->ssid
,
868 WIFI_TAG_CHANNEL
, sizeof(u16
), ¢er_freq
);
869 // ?? WIFI_TAG_VENDOR_SPECIFIC, sizeof(RSSE), RSSE);
873 if (SLSI_IS_HS2_UNSYNC_VIF(ndev_vif
)) {
874 slsi_wlan_unsync_vif_deactivate(sdev
, dev
, true);
875 } else if (SLSI_IS_VIF_INDEX_P2P(ndev_vif
)) {
876 SLSI_NET_ERR(dev
, "Connect requested on incorrect vif\n");
877 goto exit_with_error
;
880 if (WARN_ON(!sme
->ssid
))
881 goto exit_with_error
;
883 if (WARN_ON(sme
->ssid_len
> IEEE80211_MAX_SSID_LEN
))
884 goto exit_with_error
;
887 if ((SLSI_IS_VIF_INDEX_WLAN(ndev_vif
)) && (sdev
->p2p_state
== P2P_GROUP_FORMED_CLI
)) {
888 p2p_dev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_P2PX_SWLAN
);
890 ndev_p2p_vif
= netdev_priv(p2p_dev
);
891 if (ndev_p2p_vif
->sta
.sta_bss
) {
892 if (SLSI_ETHER_EQUAL(ndev_p2p_vif
->sta
.sta_bss
->bssid
, sme
->bssid
)) {
893 SLSI_NET_ERR(dev
, "Connect Request Rejected\n");
894 goto exit_with_error
;
901 if ((ndev_vif
->vif_type
== FAPI_VIFTYPE_STATION
) && (ndev_vif
->sta
.vif_status
== SLSI_VIF_STATUS_CONNECTED
)) {
903 peer
= slsi_get_peer_from_qs(sdev
, dev
, SLSI_STA_PEER_QUEUESET
);
905 goto exit_with_error
;
908 SLSI_NET_ERR(dev
, "Require bssid in reassoc but received null\n");
909 goto exit_with_error
;
911 if (!memcmp(peer
->address
, sme
->bssid
, ETH_ALEN
)) { /*same bssid*/
912 r
= slsi_mlme_reassociate(sdev
, dev
);
914 SLSI_NET_ERR(dev
, "Failed to reassociate : %d\n", r
);
916 ndev_vif
->sta
.vif_status
= SLSI_VIF_STATUS_CONNECTING
;
917 slsi_ps_port_control(sdev
, dev
, peer
, SLSI_STA_CONN_STATE_DISCONNECTED
);
920 } else { /*different bssid*/
921 connected_ssid
= cfg80211_find_ie(WLAN_EID_SSID
, ndev_vif
->sta
.sta_bss
->ies
->data
, ndev_vif
->sta
.sta_bss
->ies
->len
);
923 if (!connected_ssid
) {
924 SLSI_NET_ERR(dev
, "Require ssid in roam but received null\n");
925 goto exit_with_error
;
928 if (!memcmp(&connected_ssid
[2], sme
->ssid
, connected_ssid
[1])) { /*same ssid*/
930 SLSI_NET_ERR(dev
, "Roaming has been rejected, as sme->channel is null\n");
931 goto exit_with_error
;
933 r
= slsi_mlme_roam(sdev
, dev
, sme
->bssid
, sme
->channel
->center_freq
);
935 SLSI_NET_ERR(dev
, "Failed to roam : %d\n", r
);
936 goto exit_with_error
;
940 SLSI_NET_ERR(dev
, "Connected but received connect to new ESS, without disconnect");
941 goto exit_with_error
;
945 /* Sta started case */
947 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
948 if (SLSI_IS_VIF_INDEX_MHS(sdev
, ndev_vif
))
949 if (ndev_vif
->iftype
== NL80211_IFTYPE_P2P_CLIENT
) {
950 SLSI_NET_ERR(dev
, "Iftype: %d\n", ndev_vif
->iftype
);
951 goto exit_with_error
;
953 #endif /*wifi sharing*/
954 if (WARN_ON(ndev_vif
->activated
)) {
955 SLSI_NET_ERR(dev
, "Vif is activated: %d\n", ndev_vif
->activated
);
956 goto exit_with_error
;
958 if (ndev_vif
->vif_type
== FAPI_VIFTYPE_STATION
&&
959 ndev_vif
->sta
.vif_status
!= SLSI_VIF_STATUS_UNSPECIFIED
) {
960 SLSI_NET_ERR(dev
, "VIF status: %d\n", ndev_vif
->sta
.vif_status
);
961 goto exit_with_error
;
963 prev_vif_type
= ndev_vif
->vif_type
;
965 prev_vif_type
= ndev_vif
->vif_type
;
966 switch (ndev_vif
->iftype
) {
967 case NL80211_IFTYPE_UNSPECIFIED
:
968 case NL80211_IFTYPE_STATION
:
969 ndev_vif
->iftype
= NL80211_IFTYPE_STATION
;
970 dev
->ieee80211_ptr
->iftype
= NL80211_IFTYPE_STATION
;
971 action_frame_bmap
= SLSI_STA_ACTION_FRAME_BITMAP
;
972 #ifdef CONFIG_SCSC_WLAN_WES_NCHO
973 if (sdev
->device_config
.wes_mode
)
974 action_frame_bmap
|= SLSI_ACTION_FRAME_VENDOR_SPEC
;
977 case NL80211_IFTYPE_P2P_CLIENT
:
978 slsi_p2p_group_start_remove_unsync_vif(sdev
);
979 p2p_dev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_P2P
);
981 SLSI_ETHER_COPY(device_address
, p2p_dev
->dev_addr
);
982 action_frame_bmap
= SLSI_ACTION_FRAME_PUBLIC
;
985 SLSI_NET_ERR(dev
, "Invalid Device Type: %d\n", ndev_vif
->iftype
);
986 goto exit_with_error
;
989 /* Initial Roaming checks done - assign vif type */
990 ndev_vif
->vif_type
= FAPI_VIFTYPE_STATION
;
992 channel
= sme
->channel
;
994 ndev_vif
->sta
.sta_bss
= cfg80211_get_bss(wiphy
,
999 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
1000 IEEE80211_BSS_TYPE_ANY
,
1005 if (!ndev_vif
->sta
.sta_bss
) {
1006 struct cfg80211_ssid ssid
;
1008 SLSI_NET_DBG3(dev
, SLSI_CFG80211
, "BSS info is not available - Perform scan\n");
1009 ssid
.ssid_len
= sme
->ssid_len
;
1010 memcpy(ssid
.ssid
, sme
->ssid
, ssid
.ssid_len
);
1011 r
= slsi_mlme_connect_scan(sdev
, dev
, 1, &ssid
, sme
->channel
);
1013 SLSI_NET_ERR(dev
, "slsi_mlme_connect_scan failed\n");
1016 ndev_vif
->sta
.sta_bss
= cfg80211_get_bss(wiphy
,
1021 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
1022 IEEE80211_BSS_TYPE_ANY
,
1027 if (!ndev_vif
->sta
.sta_bss
) {
1028 SLSI_NET_ERR(dev
, "cfg80211_get_bss(%.*s, %pM) Not found\n", (int)sme
->ssid_len
, sme
->ssid
, sme
->bssid
);
1029 /*Set previous status in case of failure */
1030 ndev_vif
->vif_type
= prev_vif_type
;
1034 channel
= ndev_vif
->sta
.sta_bss
->channel
;
1035 bssid
= ndev_vif
->sta
.sta_bss
->bssid
;
1037 channel
= ndev_vif
->sta
.sta_bss
->channel
;
1038 bssid
= ndev_vif
->sta
.sta_bss
->bssid
;
1041 ndev_vif
->channel_type
= NL80211_CHAN_NO_HT
;
1042 ndev_vif
->chan
= channel
;
1044 if (slsi_mlme_add_vif(sdev
, dev
, dev
->dev_addr
, device_address
) != 0) {
1045 SLSI_NET_ERR(dev
, "slsi_mlme_add_vif failed\n");
1048 if (slsi_vif_activated(sdev
, dev
) != 0) {
1049 SLSI_NET_ERR(dev
, "slsi_vif_activated failed\n");
1052 if (slsi_mlme_register_action_frame(sdev
, dev
, action_frame_bmap
, action_frame_bmap
) != 0) {
1053 SLSI_NET_ERR(dev
, "Action frame registration failed for bitmap value %d\n", action_frame_bmap
);
1057 r
= slsi_set_boost(sdev
, dev
);
1059 SLSI_NET_ERR(dev
, "Rssi Boost set failed: %d\n", r
);
1061 /* add_info_elements with Probe Req IEs. Proceed even if confirm fails for add_info as it would
1062 * still work if the fw pre-join scan does not include the vendor IEs
1064 if (ndev_vif
->probe_req_ies
) {
1065 if (ndev_vif
->iftype
== NL80211_IFTYPE_P2P_CLIENT
) {
1066 if (sme
->crypto
.wpa_versions
== 2)
1067 ndev_vif
->delete_probe_req_ies
= true; /* Stored Probe Req can be deleted at vif
1068 * deletion after WPA2 association
1071 /* Retain stored Probe Req at vif deletion until WPA2 connection to allow Probe req */
1072 ndev_vif
->delete_probe_req_ies
= false;
1074 ndev_vif
->delete_probe_req_ies
= true; /* Delete stored Probe Req at vif deletion for STA */
1076 (void)slsi_mlme_add_info_elements(sdev
, dev
, FAPI_PURPOSE_PROBE_REQUEST
, ndev_vif
->probe_req_ies
,
1077 ndev_vif
->probe_req_ie_len
);
1080 /* Sometimes netif stack takes more time to initialize and any packet
1081 * sent to stack would be dropped. This behavior is random in nature,
1082 * so start the netif stack before sending out the connect req, it shall
1083 * give enough time to netstack to initialize.
1085 netif_carrier_on(dev
);
1086 ndev_vif
->sta
.vif_status
= SLSI_VIF_STATUS_CONNECTING
;
1088 #ifdef CONFIG_SCSC_WLAN_SAE_CONFIG
1089 if (sme
->auth_type
== NL80211_AUTHTYPE_SAE
&& (sme
->flags
& CONNECT_REQ_EXTERNAL_AUTH_SUPPORT
)) {
1092 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "N AKM Suites: : %1d\n", sme
->crypto
.n_akm_suites
);
1093 ndev_vif
->sta
.crypto
.wpa_versions
= 3;
1094 rsn
= cfg80211_find_ie(WLAN_EID_RSN
, sme
->ie
, sme
->ie_len
);
1098 pos
= 7 + 2 + (rsn
[8] * 4) + 2;
1099 ndev_vif
->sta
.crypto
.akm_suites
[0] = ((rsn
[pos
+ 4] << 24) | (rsn
[pos
+ 3] << 16) | (rsn
[pos
+ 2] << 8) | (rsn
[pos
+ 1]));
1102 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "RSN IE: : %1d\n", ndev_vif
->sta
.crypto
.akm_suites
[0]);
1104 ndev_vif
->sta
.crypto
.wpa_versions
= 0;
1107 r
= slsi_mlme_connect(sdev
, dev
, sme
, channel
, bssid
);
1109 ndev_vif
->sta
.is_wps
= false;
1110 SLSI_NET_ERR(dev
, "connect failed: %d\n", r
);
1111 netif_carrier_off(dev
);
1115 peer
= slsi_peer_add(sdev
, dev
, (u8
*)bssid
, SLSI_STA_PEER_QUEUESET
+ 1);
1116 ndev_vif
->sta
.resp_id
= 0;
1119 goto exit_with_error
;
1124 slsi_mlme_del_vif(sdev
, dev
);
1125 slsi_vif_deactivated(sdev
, dev
);
1127 if (ndev_vif
->sta
.sta_bss
) {
1128 slsi_cfg80211_put_bss(wiphy
, ndev_vif
->sta
.sta_bss
);
1129 ndev_vif
->sta
.sta_bss
= NULL
;
1134 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1135 SLSI_MUTEX_UNLOCK(sdev
->start_stop_mutex
);
1139 int slsi_disconnect(struct wiphy
*wiphy
, struct net_device
*dev
,
1142 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1143 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1144 struct slsi_peer
*peer
;
1147 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1149 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "reason: %d, vif_index = %d, vif_type = %d\n", reason_code
,
1150 ndev_vif
->ifnum
, ndev_vif
->vif_type
);
1152 /* Assuming that the time it takes the firmware to disconnect is not significant
1153 * as this function holds the locks until the MLME-DISCONNECT-IND comes back.
1154 * Unless the MLME-DISCONNECT-CFM fails.
1156 if (!ndev_vif
->activated
) {
1158 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
1159 cfg80211_disconnected(dev
, reason_code
, NULL
, 0, false, GFP_KERNEL
);
1161 cfg80211_disconnected(dev
, reason_code
, NULL
, 0, GFP_KERNEL
);
1163 SLSI_NET_INFO(dev
, "Vif is already Deactivated\n");
1167 peer
= ndev_vif
->peer_sta_record
[SLSI_STA_PEER_QUEUESET
];
1169 #ifdef CONFIG_SCSC_WIFILOGGER
1170 SCSC_WLOG_DRIVER_EVENT(WLOG_NORMAL
, WIFI_EVENT_DISASSOCIATION_REQUESTED
, 2,
1171 WIFI_TAG_BSSID
, ETH_ALEN
, peer
->address
,
1172 WIFI_TAG_REASON_CODE
, sizeof(u16
), &reason_code
);
1175 switch (ndev_vif
->vif_type
) {
1176 case FAPI_VIFTYPE_STATION
:
1178 slsi_reset_throughput_stats(dev
);
1179 /* Disconnecting spans several host firmware interactions so track the status
1180 * so that the Host can ignore connect related signaling eg. MLME-CONNECT-IND
1181 * now that it has triggered a disconnect.
1183 ndev_vif
->sta
.vif_status
= SLSI_VIF_STATUS_DISCONNECTING
;
1185 netif_carrier_off(dev
);
1187 slsi_ps_port_control(sdev
, dev
, peer
, SLSI_STA_CONN_STATE_DISCONNECTED
);
1189 /* MLME-DISCONNECT_CFM only means that the firmware has accepted the request it has not yet
1190 * disconnected. Completion of the disconnect is indicated by MLME-DISCONNECT-IND, so have
1191 * to wait for that before deleting the VIF. Also any new activities eg. connect can not yet
1192 * be started on the VIF until the disconnection is completed. So the MLME function also handles
1193 * waiting for the MLME-DISCONNECT-IND (if the CFM is successful)
1196 r
= slsi_mlme_disconnect(sdev
, dev
, peer
->address
, reason_code
, true);
1198 SLSI_NET_ERR(dev
, "Disconnection returned with failure\n");
1199 /* Even if we fail to disconnect cleanly, tidy up. */
1200 r
= slsi_handle_disconnect(sdev
, dev
, peer
->address
, 0, NULL
, 0);
1205 SLSI_NET_WARN(dev
, "Invalid - vif type:%d, device type:%d)\n", ndev_vif
->vif_type
, ndev_vif
->iftype
);
1211 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1215 int slsi_set_default_key(struct wiphy
*wiphy
, struct net_device
*dev
,
1216 u8 key_index
, bool unicast
, bool multicast
)
1218 SLSI_UNUSED_PARAMETER(wiphy
);
1219 SLSI_UNUSED_PARAMETER(dev
);
1220 SLSI_UNUSED_PARAMETER(key_index
);
1221 SLSI_UNUSED_PARAMETER(unicast
);
1222 SLSI_UNUSED_PARAMETER(multicast
);
1223 /* Key is set in add_key. Nothing to do here */
1227 int slsi_config_default_mgmt_key(struct wiphy
*wiphy
,
1228 struct net_device
*dev
,
1231 SLSI_UNUSED_PARAMETER(wiphy
);
1232 SLSI_UNUSED_PARAMETER(key_index
);
1233 SLSI_UNUSED_PARAMETER(dev
);
1238 int slsi_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
1240 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1243 SLSI_DBG1(sdev
, SLSI_CFG80211
, "slsi_set_wiphy_parms Frag Threshold = %d, RTS Threshold = %d",
1244 wiphy
->frag_threshold
, wiphy
->rts_threshold
);
1246 if ((changed
& WIPHY_PARAM_FRAG_THRESHOLD
) && (wiphy
->frag_threshold
!= -1)) {
1247 r
= slsi_set_uint_mib(sdev
, NULL
, SLSI_PSID_DOT11_FRAGMENTATION_THRESHOLD
, wiphy
->frag_threshold
);
1249 SLSI_ERR(sdev
, "Setting FRAG_THRESHOLD failed\n");
1254 if ((changed
& WIPHY_PARAM_RTS_THRESHOLD
) && (wiphy
->rts_threshold
!= -1)) {
1255 r
= slsi_set_uint_mib(sdev
, NULL
, SLSI_PSID_DOT11_RTS_THRESHOLD
, wiphy
->rts_threshold
);
1257 SLSI_ERR(sdev
, "Setting RTS_THRESHOLD failed\n");
1265 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1266 int slsi_set_tx_power(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
1267 enum nl80211_tx_power_setting type
, int mbm
)
1269 int slsi_set_tx_power(struct wiphy
*wiphy
,
1270 enum nl80211_tx_power_setting type
, int mbm
)
1271 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) */
1273 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1276 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1277 SLSI_UNUSED_PARAMETER(wdev
);
1278 SLSI_UNUSED_PARAMETER(type
);
1280 SLSI_UNUSED_PARAMETER(mbm
);
1281 SLSI_UNUSED_PARAMETER(sdev
);
1288 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1289 int slsi_get_tx_power(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, int *dbm
)
1291 int slsi_get_tx_power(struct wiphy
*wiphy
, int *dbm
)
1292 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) */
1294 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1297 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1298 SLSI_UNUSED_PARAMETER(wdev
);
1300 SLSI_UNUSED_PARAMETER(dbm
);
1301 SLSI_UNUSED_PARAMETER(sdev
);
1308 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
1309 int slsi_del_station(struct wiphy
*wiphy
, struct net_device
*dev
,
1310 struct station_del_parameters
*del_params
)
1311 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
1312 int slsi_del_station(struct wiphy
*wiphy
, struct net_device
*dev
,
1315 int slsi_del_station(struct wiphy
*wiphy
, struct net_device
*dev
,
1319 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1320 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1321 struct slsi_peer
*peer
;
1324 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
1325 const u8
*mac
= del_params
->mac
;
1328 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1330 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "%pM, vifType:%d, vifIndex:%d vifActivated:%d ap.p2p_gc_keys_set = %d\n",
1331 mac
, ndev_vif
->vif_type
, ndev_vif
->ifnum
, ndev_vif
->activated
, ndev_vif
->ap
.p2p_gc_keys_set
);
1333 /* Function is called by cfg80211 before the VIF is added */
1334 if (!ndev_vif
->activated
)
1337 if (FAPI_VIFTYPE_AP
!= ndev_vif
->vif_type
) {
1341 /* MAC with NULL value will come in case of flushing VLANS . Ignore this.*/
1344 } else if (is_broadcast_ether_addr(mac
)) {
1347 while (i
< SLSI_PEER_INDEX_MAX
) {
1348 peer
= ndev_vif
->peer_sta_record
[i
];
1349 if (peer
&& peer
->valid
) {
1350 slsi_ps_port_control(sdev
, dev
, peer
, SLSI_STA_CONN_STATE_DISCONNECTED
);
1355 /* Note AP :: mlme_disconnect_request with broadcast mac address is
1356 * not required. Other third party devices don't support this. Conclusively,
1357 * BIP support is not present with AP
1360 /* Free WPA and WMM IEs if present */
1361 slsi_clear_cached_ies(&ndev_vif
->ap
.cache_wpa_ie
, &ndev_vif
->ap
.wpa_ie_len
);
1362 slsi_clear_cached_ies(&ndev_vif
->ap
.cache_wmm_ie
, &ndev_vif
->ap
.wmm_ie_len
);
1364 netif_carrier_off(dev
);
1366 /* All STA related packets and info should already have been flushed */
1367 slsi_mlme_del_vif(sdev
, dev
);
1368 slsi_vif_deactivated(sdev
, dev
);
1369 ndev_vif
->ipaddress
= cpu_to_be32(0);
1371 if (ndev_vif
->ap
.p2p_gc_keys_set
) {
1372 slsi_wakeunlock(&sdev
->wlan_wl
);
1373 ndev_vif
->ap
.p2p_gc_keys_set
= false;
1376 peer
= slsi_get_peer_from_mac(sdev
, dev
, mac
);
1377 if (peer
) { /* To handle race condition when disconnect_req is sent before procedure_strted_ind and before mlme-connected_ind*/
1378 if (peer
->connected_state
== SLSI_STA_CONN_STATE_CONNECTING
) {
1379 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "SLSI_STA_CONN_STATE_CONNECTING : mlme-disconnect-req dropped at driver\n");
1383 /* To inter-op with Intel STA in P2P cert need to discard the deauth after successful WPS handshake as a P2P GO */
1384 SLSI_NET_INFO(dev
, "DISCONNECT after WPS : mlme-disconnect-req dropped at driver\n");
1387 slsi_ps_port_control(sdev
, dev
, peer
, SLSI_STA_CONN_STATE_DISCONNECTED
);
1388 r
= slsi_mlme_disconnect(sdev
, dev
, peer
->address
, WLAN_REASON_DEAUTH_LEAVING
, true);
1390 SLSI_NET_ERR(dev
, "Disconnection returned with failure\n");
1391 /* Even if we fail to disconnect cleanly, tidy up. */
1392 r
= slsi_handle_disconnect(sdev
, dev
, peer
->address
, WLAN_REASON_DEAUTH_LEAVING
, NULL
, 0);
1397 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1401 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
1402 int slsi_get_station(struct wiphy
*wiphy
, struct net_device
*dev
,
1403 const u8
*mac
, struct station_info
*sinfo
)
1405 int slsi_get_station(struct wiphy
*wiphy
, struct net_device
*dev
,
1406 u8
*mac
, struct station_info
*sinfo
)
1409 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1410 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1411 struct slsi_peer
*peer
;
1414 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1416 if (!ndev_vif
->activated
) {
1421 peer
= slsi_get_peer_from_mac(sdev
, dev
, mac
);
1423 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "%pM : Not Found\n", mac
);
1428 if (((ndev_vif
->iftype
== NL80211_IFTYPE_STATION
&& !(ndev_vif
->sta
.roam_in_progress
)) ||
1429 ndev_vif
->iftype
== NL80211_IFTYPE_P2P_CLIENT
)) {
1430 /*Read MIB and fill into the peer.sinfo*/
1431 r
= slsi_mlme_get_sinfo_mib(sdev
, dev
, peer
);
1433 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "failed to read Station Info Error:%d\n", r
);
1438 *sinfo
= peer
->sinfo
;
1439 sinfo
->generation
= ndev_vif
->cfg80211_sinfo_generation
;
1441 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1442 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "%pM, tx:%d, txbytes:%llu, rx:%d, rxbytes:%llu tx_fail:%d tx_retry:%d\n",
1444 peer
->sinfo
.tx_packets
,
1445 peer
->sinfo
.tx_bytes
,
1446 peer
->sinfo
.rx_packets
,
1447 peer
->sinfo
.rx_bytes
,
1448 peer
->sinfo
.tx_failed
,
1449 peer
->sinfo
.tx_retries
);
1451 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "%pM, tx:%d, txbytes:%d, rx:%d, rxbytes:%d tx_fail:%d tx_retry:%d\n",
1453 peer
->sinfo
.tx_packets
,
1454 peer
->sinfo
.tx_bytes
,
1455 peer
->sinfo
.rx_packets
,
1456 peer
->sinfo
.rx_bytes
,
1457 peer
->sinfo
.tx_failed
,
1458 peer
->sinfo
.tx_retries
);
1462 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1466 int slsi_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*dev
,
1467 bool enabled
, int timeout
)
1469 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1470 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1472 u16 pwr_mode
= enabled
? FAPI_POWERMANAGEMENTMODE_POWER_SAVE
: FAPI_POWERMANAGEMENTMODE_ACTIVE_MODE
;
1474 SLSI_UNUSED_PARAMETER(timeout
);
1475 if (slsi_is_test_mode_enabled()) {
1476 SLSI_NET_INFO(dev
, "Skip sending signal, WlanLite FW does not support MLME_POWERMGT.request\n");
1480 if (slsi_is_rf_test_mode_enabled()) {
1481 SLSI_NET_INFO(dev
, "Skip sending signal, RF test does not support.\n");
1485 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1487 SLSI_NET_DBG3(dev
, SLSI_CFG80211
, "enabled:%d, vif_type:%d, vif_index:%d\n", enabled
, ndev_vif
->vif_type
,
1490 if ((ndev_vif
->activated
) && (ndev_vif
->vif_type
== FAPI_VIFTYPE_STATION
)) {
1491 ndev_vif
->set_power_mode
= pwr_mode
;
1492 r
= slsi_mlme_powermgt(sdev
, dev
, pwr_mode
);
1497 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1501 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 18))
1502 int slsi_tdls_oper(struct wiphy
*wiphy
, struct net_device
*dev
, const u8
*peer
, enum nl80211_tdls_operation oper
)
1504 int slsi_tdls_oper(struct wiphy
*wiphy
, struct net_device
*dev
, u8
*peer
, enum nl80211_tdls_operation oper
)
1507 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1508 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1511 SLSI_NET_DBG3(dev
, SLSI_CFG80211
, "oper:%d, vif_type:%d, vif_index:%d\n", oper
, ndev_vif
->vif_type
,
1514 if (!(wiphy
->flags
& WIPHY_FLAG_SUPPORTS_TDLS
))
1517 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1519 if ((!ndev_vif
->activated
) || SLSI_IS_VIF_INDEX_P2P_GROUP(sdev
, ndev_vif
) ||
1520 (ndev_vif
->sta
.vif_status
!= SLSI_VIF_STATUS_CONNECTED
)) {
1526 case NL80211_TDLS_DISCOVERY_REQ
:
1527 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "NL80211_TDLS_DISCOVERY_REQ\n");
1528 r
= slsi_mlme_tdls_action(sdev
, dev
, peer
, FAPI_TDLSACTION_DISCOVERY
, 0, 0);
1530 case NL80211_TDLS_SETUP
:
1531 r
= slsi_mlme_tdls_action(sdev
, dev
, peer
, FAPI_TDLSACTION_SETUP
, 0, 0);
1533 case NL80211_TDLS_TEARDOWN
:
1534 r
= slsi_mlme_tdls_action(sdev
, dev
, peer
, FAPI_TDLSACTION_TEARDOWN
, 0, 0);
1541 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1545 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
1546 int slsi_set_qos_map(struct wiphy
*wiphy
, struct net_device
*dev
, struct cfg80211_qos_map
*qos_map
)
1548 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1549 struct slsi_peer
*peer
;
1552 /* Cleaning up is inherently taken care by driver */
1556 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1558 if (!ndev_vif
->activated
) {
1563 if (ndev_vif
->vif_type
!= FAPI_VIFTYPE_STATION
) {
1568 SLSI_NET_DBG3(dev
, SLSI_CFG80211
, "Set QoS Map\n");
1569 peer
= ndev_vif
->peer_sta_record
[SLSI_STA_PEER_QUEUESET
];
1570 if (!peer
|| !peer
->valid
) {
1575 memcpy(&peer
->qos_map
, qos_map
, sizeof(struct cfg80211_qos_map
));
1576 peer
->qos_map_set
= true;
1579 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1583 #ifdef CONFIG_SCSC_WLAN_DEBUG
1584 int slsi_set_monitor_channel(struct wiphy
*wiphy
, struct cfg80211_chan_def
*chandef
)
1586 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1587 struct net_device
*dev
;
1588 struct netdev_vif
*ndev_vif
;
1590 SLSI_DBG1(sdev
, SLSI_CFG80211
, "channel (freq:%u)\n", chandef
->chan
->center_freq
);
1593 dev
= slsi_get_netdev_rcu(sdev
, SLSI_NET_INDEX_WLAN
);
1595 SLSI_ERR(sdev
, "netdev No longer exists\n");
1599 ndev_vif
= netdev_priv(dev
);
1602 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1604 if (slsi_test_sap_configure_monitor_mode(sdev
, dev
, chandef
) != 0) {
1605 SLSI_ERR(sdev
, "set Monitor channel failed\n");
1606 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1609 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1614 int slsi_suspend(struct wiphy
*wiphy
, struct cfg80211_wowlan
*wow
)
1616 SLSI_UNUSED_PARAMETER(wow
);
1621 int slsi_resume(struct wiphy
*wiphy
)
1623 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1625 /* Scheduling the IO thread */
1626 /* (void)slsi_hip_run_bh(sdev); */
1627 SLSI_UNUSED_PARAMETER(sdev
);
1632 int slsi_set_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
1633 struct cfg80211_pmksa
*pmksa
)
1635 SLSI_UNUSED_PARAMETER(wiphy
);
1636 SLSI_UNUSED_PARAMETER(dev
);
1637 SLSI_UNUSED_PARAMETER(pmksa
);
1641 int slsi_del_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
,
1642 struct cfg80211_pmksa
*pmksa
)
1644 SLSI_UNUSED_PARAMETER(wiphy
);
1645 SLSI_UNUSED_PARAMETER(dev
);
1646 SLSI_UNUSED_PARAMETER(pmksa
);
1650 int slsi_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*dev
)
1652 SLSI_UNUSED_PARAMETER(wiphy
);
1653 SLSI_UNUSED_PARAMETER(dev
);
1657 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1658 int slsi_remain_on_channel(struct wiphy
*wiphy
,
1659 struct wireless_dev
*wdev
,
1660 struct ieee80211_channel
*chan
,
1661 unsigned int duration
,
1664 struct net_device
*dev
= wdev
->netdev
;
1667 int slsi_remain_on_channel(struct wiphy
*wiphy
,
1668 struct net_device
*dev
,
1669 struct ieee80211_channel
*chan
,
1670 enum nl80211_channel_type channel_type
,
1671 unsigned int duration
,
1674 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) */
1675 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1676 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1679 SLSI_MUTEX_LOCK(sdev
->start_stop_mutex
);
1680 if (sdev
->device_state
!= SLSI_DEVICE_STATE_STARTED
) {
1681 SLSI_WARN(sdev
, "device not started yet (device_state:%d)\n", sdev
->device_state
);
1682 goto exit_with_error
;
1685 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1687 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "channel freq = %d, duration = %d, vif_type = %d, vif_index = %d,"
1688 "sdev->p2p_state = %s\n", chan
->center_freq
, duration
, ndev_vif
->vif_type
, ndev_vif
->ifnum
,
1689 slsi_p2p_state_text(sdev
->p2p_state
));
1690 if (!SLSI_IS_VIF_INDEX_P2P(ndev_vif
)) {
1691 SLSI_NET_ERR(dev
, "Invalid vif type\n");
1692 goto exit_with_error
;
1695 if (SLSI_IS_P2P_GROUP_STATE(sdev
)) {
1696 slsi_assign_cookie_id(cookie
, &ndev_vif
->unsync
.roc_cookie
);
1698 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1699 cfg80211_ready_on_channel(wdev
, *cookie
, chan
, duration
, GFP_KERNEL
);
1700 cfg80211_remain_on_channel_expired(wdev
, *cookie
, chan
, GFP_KERNEL
);
1702 cfg80211_ready_on_channel(dev
, *cookie
, chan
, channel_type
, duration
, GFP_KERNEL
);
1703 cfg80211_remain_on_channel_expired(dev
, *cookie
, chan
, channel_type
, GFP_KERNEL
);
1708 /* Unsync vif will be required, cancel any pending work of its deletion */
1709 cancel_delayed_work(&ndev_vif
->unsync
.del_vif_work
);
1711 /* Ideally, there should not be any ROC work pending. However, supplicant can send back to back ROC in a race scenario as below.
1712 * If action frame is received while P2P social scan, the response frame tx is delayed till scan completes. After scan completion,
1713 * frame tx is done and ROC is started. Upon frame tx status, supplicant sends another ROC without cancelling the previous one.
1715 cancel_delayed_work(&ndev_vif
->unsync
.roc_expiry_work
);
1717 if (delayed_work_pending(&ndev_vif
->unsync
.unset_channel_expiry_work
))
1718 cancel_delayed_work(&ndev_vif
->unsync
.unset_channel_expiry_work
);
1720 /* If action frame tx is in progress and ROC comes, then it would mean action frame tx was done in ROC and
1721 * frame tx ind is awaited, don't change state. Also allow back to back ROC in case it comes.
1723 if ((sdev
->p2p_state
== P2P_ACTION_FRAME_TX_RX
) || (sdev
->p2p_state
== P2P_LISTENING
)) {
1727 /* Unsync vif activation: Possible P2P state at this point is P2P_IDLE_NO_VIF or P2P_IDLE_VIF_ACTIVE */
1728 if (sdev
->p2p_state
== P2P_IDLE_NO_VIF
) {
1729 if (slsi_p2p_vif_activate(sdev
, dev
, chan
, duration
, true) != 0)
1730 goto exit_with_error
;
1731 } else if (sdev
->p2p_state
== P2P_IDLE_VIF_ACTIVE
) {
1732 /* Configure Probe Response IEs in firmware if they have changed */
1733 if (ndev_vif
->unsync
.ies_changed
) {
1734 u16 purpose
= FAPI_PURPOSE_PROBE_RESPONSE
;
1736 if (slsi_mlme_add_info_elements(sdev
, dev
, purpose
, ndev_vif
->unsync
.probe_rsp_ies
, ndev_vif
->unsync
.probe_rsp_ies_len
) != 0) {
1737 SLSI_NET_ERR(dev
, "Probe Rsp IEs setting failed\n");
1740 ndev_vif
->unsync
.ies_changed
= false;
1742 /* Channel Setting - Don't set if already on same channel */
1743 if (ndev_vif
->driver_channel
!= chan
->hw_value
) {
1744 if (slsi_mlme_set_channel(sdev
, dev
, chan
, SLSI_FW_CHANNEL_DURATION_UNSPECIFIED
, 0, 0) != 0) {
1745 SLSI_NET_ERR(dev
, "Channel setting failed\n");
1748 ndev_vif
->chan
= chan
;
1749 ndev_vif
->driver_channel
= chan
->hw_value
;
1753 SLSI_NET_ERR(dev
, "Driver in incorrect P2P state (%s)", slsi_p2p_state_text(sdev
->p2p_state
));
1754 goto exit_with_error
;
1757 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 9))
1758 ndev_vif
->channel_type
= channel_type
;
1761 SLSI_P2P_STATE_CHANGE(sdev
, P2P_LISTENING
);
1764 /* Cancel remain on channel is sent to the supplicant 10ms before the duration
1765 *This is to avoid the race condition of supplicant sending cancel remain on channel and
1766 *drv sending cancel_remain on channel because of roc expiry.
1767 *This race condition causes delay to the next p2p search
1769 queue_delayed_work(sdev
->device_wq
, &ndev_vif
->unsync
.roc_expiry_work
,
1770 msecs_to_jiffies(duration
- SLSI_P2P_ROC_EXTRA_MSEC
));
1772 slsi_assign_cookie_id(cookie
, &ndev_vif
->unsync
.roc_cookie
);
1773 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "Cookie = 0x%llx\n", *cookie
);
1775 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1776 cfg80211_ready_on_channel(wdev
, *cookie
, chan
, duration
, GFP_KERNEL
);
1778 cfg80211_ready_on_channel(dev
, *cookie
, chan
, channel_type
, duration
, GFP_KERNEL
);
1784 slsi_p2p_vif_deactivate(sdev
, dev
, true);
1788 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1789 SLSI_MUTEX_UNLOCK(sdev
->start_stop_mutex
);
1793 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1794 int slsi_cancel_remain_on_channel(struct wiphy
*wiphy
,
1795 struct wireless_dev
*wdev
,
1798 struct net_device
*dev
= wdev
->netdev
;
1801 int slsi_cancel_remain_on_channel(struct wiphy
*wiphy
,
1802 struct net_device
*dev
,
1805 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) */
1806 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1807 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1810 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1812 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "Cookie = 0x%llx, vif_type = %d, vif_index = %d, sdev->p2p_state = %s,"
1813 "ndev_vif->ap.p2p_gc_keys_set = %d, ndev_vif->unsync.roc_cookie = 0x%llx\n", cookie
,
1814 ndev_vif
->vif_type
, ndev_vif
->ifnum
, slsi_p2p_state_text(sdev
->p2p_state
),
1815 ndev_vif
->ap
.p2p_gc_keys_set
, ndev_vif
->unsync
.roc_cookie
);
1817 if (!SLSI_IS_VIF_INDEX_P2P(ndev_vif
)) {
1818 SLSI_NET_ERR(dev
, "Invalid vif type\n");
1823 if (!((sdev
->p2p_state
== P2P_LISTENING
) || (sdev
->p2p_state
== P2P_ACTION_FRAME_TX_RX
))) {
1827 if (sdev
->p2p_state
== P2P_ACTION_FRAME_TX_RX
&& ndev_vif
->mgmt_tx_data
.exp_frame
!= SLSI_P2P_PA_INVALID
) {
1828 /* Reset the expected action frame as procedure got completed */
1829 SLSI_INFO(sdev
, "Action frame (%s) was not received\n", slsi_p2p_pa_subtype_text(ndev_vif
->mgmt_tx_data
.exp_frame
));
1830 ndev_vif
->mgmt_tx_data
.exp_frame
= SLSI_P2P_PA_INVALID
;
1833 cancel_delayed_work(&ndev_vif
->unsync
.roc_expiry_work
);
1835 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1836 cfg80211_remain_on_channel_expired(&ndev_vif
->wdev
, ndev_vif
->unsync
.roc_cookie
, ndev_vif
->chan
, GFP_KERNEL
);
1838 cfg80211_remain_on_channel_expired(ndev_vif
->wdev
.netdev
, ndev_vif
->unsync
.roc_cookie
,
1839 ndev_vif
->chan
, ndev_vif
->channel_type
, GFP_KERNEL
);
1841 if (!ndev_vif
->drv_in_p2p_procedure
) {
1842 if (delayed_work_pending(&ndev_vif
->unsync
.unset_channel_expiry_work
))
1843 cancel_delayed_work(&ndev_vif
->unsync
.unset_channel_expiry_work
);
1844 queue_delayed_work(sdev
->device_wq
, &ndev_vif
->unsync
.unset_channel_expiry_work
,
1845 msecs_to_jiffies(SLSI_P2P_UNSET_CHANNEL_EXTRA_MSEC
));
1847 /* Queue work to delete unsync vif */
1848 slsi_p2p_queue_unsync_vif_del_work(ndev_vif
, SLSI_P2P_UNSYNC_VIF_EXTRA_MSEC
);
1849 SLSI_P2P_STATE_CHANGE(sdev
, P2P_IDLE_VIF_ACTIVE
);
1852 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1856 int slsi_change_bss(struct wiphy
*wiphy
, struct net_device
*dev
,
1857 struct bss_parameters
*params
)
1859 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1862 SLSI_UNUSED_PARAMETER(params
);
1863 SLSI_UNUSED_PARAMETER(sdev
);
1868 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 5, 0))
1869 int slsi_set_channel(struct wiphy
*wiphy
, struct net_device
*dev
,
1870 struct ieee80211_channel
*chan
,
1871 enum nl80211_channel_type channel_type
)
1873 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1874 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1877 SLSI_UNUSED_PARAMETER(sdev
);
1878 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1880 SLSI_NET_DBG3(dev
, SLSI_CFG80211
, "channel_type:%u, freq:%u, vif_index:%d, vif_type:%d\n", channel_type
,
1881 chan
->center_freq
, ndev_vif
->ifnum
, ndev_vif
->vif_type
);
1882 if (WARN_ON(ndev_vif
->activated
)) {
1887 ndev_vif
->channel_type
= channel_type
;
1888 ndev_vif
->chan
= chan
;
1891 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1894 #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 5, 0)) */
1896 static void slsi_ap_start_obss_scan(struct slsi_dev
*sdev
, struct net_device
*dev
, struct netdev_vif
*ndev_vif
)
1898 struct cfg80211_ssid ssids
;
1899 struct ieee80211_channel
*channel
;
1900 int n_ssids
= 1, n_channels
= 1, i
;
1902 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "channel %u\n", ndev_vif
->chan
->hw_value
);
1904 SLSI_MUTEX_LOCK(ndev_vif
->scan_mutex
);
1907 for (i
= 0; i
< IEEE80211_MAX_SSID_LEN
; i
++)
1908 ssids
.ssid
[i
] = 0x00; /* Broadcast SSID */
1910 channel
= ieee80211_get_channel(sdev
->wiphy
, ndev_vif
->chan
->center_freq
);
1912 ndev_vif
->scan
[SLSI_SCAN_HW_ID
].is_blocking_scan
= true;
1913 (void)slsi_mlme_add_scan(sdev
,
1915 FAPI_SCANTYPE_OBSS_SCAN
,
1916 FAPI_REPORTMODE_REAL_TIME
,
1924 ndev_vif
->scan
[SLSI_SCAN_HW_ID
].is_blocking_scan
/* Wait for scan_done_ind */);
1926 slsi_ap_obss_scan_done_ind(dev
, ndev_vif
);
1927 ndev_vif
->scan
[SLSI_SCAN_HW_ID
].is_blocking_scan
= false;
1928 SLSI_MUTEX_UNLOCK(ndev_vif
->scan_mutex
);
1931 static int slsi_ap_start_validate(struct net_device
*dev
, struct slsi_dev
*sdev
, struct cfg80211_ap_settings
*settings
)
1933 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1935 if (SLSI_IS_VIF_INDEX_P2P(ndev_vif
)) {
1936 SLSI_NET_ERR(dev
, "AP start requested on incorrect vif\n");
1937 goto exit_with_error
;
1940 if (!settings
->ssid_len
|| !settings
->ssid
) {
1941 SLSI_NET_ERR(dev
, "SSID not provided\n");
1942 goto exit_with_error
;
1945 if (!settings
->beacon
.head_len
|| !settings
->beacon
.head
) {
1946 SLSI_NET_ERR(dev
, "Beacon not provided\n");
1947 goto exit_with_error
;
1950 if (!settings
->beacon_interval
) {
1951 SLSI_NET_ERR(dev
, "Beacon Interval not provided\n");
1952 goto exit_with_error
;
1955 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1956 ndev_vif
->chandef
= &settings
->chandef
;
1957 ndev_vif
->chan
= ndev_vif
->chandef
->chan
;
1959 if (WARN_ON(!ndev_vif
->chan
))
1960 goto exit_with_error
;
1962 if (WARN_ON(ndev_vif
->activated
))
1963 goto exit_with_error
;
1965 if (WARN_ON((ndev_vif
->iftype
!= NL80211_IFTYPE_AP
) && (ndev_vif
->iftype
!= NL80211_IFTYPE_P2P_GO
)))
1966 goto exit_with_error
;
1968 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1969 if ((ndev_vif
->chan
->hw_value
<= 14) && (!sdev
->fw_SoftAp_2g_40mhz_enabled
) &&
1970 (ndev_vif
->chandef
->width
== NL80211_CHAN_WIDTH_40
)) {
1971 SLSI_NET_ERR(dev
, "Configuration error: 40 MHz on 2.4 GHz is not supported. Channel_no: %d Channel_width: %d\n", ndev_vif
->chan
->hw_value
, slsi_get_chann_info(sdev
, ndev_vif
->chandef
));
1972 goto exit_with_error
;
1975 if ((ndev_vif
->chan
->hw_value
<= 14) && (!sdev
->fw_SoftAp_2g_40mhz_enabled
) &&
1976 (ndev_vif
->channel_type
> NL80211_CHAN_HT20
)) {
1977 SLSI_NET_ERR(dev
, "Configuration error: 40 MHz on 2.4 GHz is not supported. Channel_no: %d Channel_width: %d\n", ndev_vif
->chan
->hw_value
, slsi_get_chann_info(sdev
, ndev_vif
->channel_type
));
1978 goto exit_with_error
;
1988 static int slsi_get_max_bw_mhz(struct slsi_dev
*sdev
, u16 prim_chan_cf
)
1991 struct ieee80211_regdomain
*regd
= sdev
->device_config
.domain_info
.regdomain
;
1994 SLSI_WARN(sdev
, "NO regdomain info\n");
1998 for (i
= 0; i
< regd
->n_reg_rules
; i
++) {
1999 if ((regd
->reg_rules
[i
].freq_range
.start_freq_khz
/ 1000 <= prim_chan_cf
- 10) &&
2000 (regd
->reg_rules
[i
].freq_range
.end_freq_khz
/ 1000 >= prim_chan_cf
+ 10))
2001 return regd
->reg_rules
[i
].freq_range
.max_bandwidth_khz
/ 1000;
2004 SLSI_WARN(sdev
, "Freq(%d) not found in regdomain\n", prim_chan_cf
);
2008 void slsi_store_settings_for_recovery(struct cfg80211_ap_settings
*settings
, struct netdev_vif
*ndev_vif
)
2010 ndev_vif
->backup_settings
= *settings
;
2011 ndev_vif
->backup_settings
.chandef
.chan
= kmalloc(sizeof(struct ieee80211_channel
), GFP_KERNEL
);
2012 memcpy(ndev_vif
->backup_settings
.chandef
.chan
, settings
->chandef
.chan
, sizeof(struct ieee80211_channel
));
2013 ndev_vif
->backup_settings
.beacon
.head
= kmalloc(settings
->beacon
.head_len
, GFP_KERNEL
);
2014 memcpy((u8
*)ndev_vif
->backup_settings
.beacon
.head
, settings
->beacon
.head
, settings
->beacon
.head_len
);
2015 ndev_vif
->backup_settings
.beacon
.tail
= kmalloc(settings
->beacon
.tail_len
, GFP_KERNEL
);
2016 memcpy((u8
*)ndev_vif
->backup_settings
.beacon
.tail
, settings
->beacon
.tail
, settings
->beacon
.tail_len
);
2017 ndev_vif
->backup_settings
.beacon
.beacon_ies
= kmalloc(settings
->beacon
.beacon_ies_len
, GFP_KERNEL
);
2018 memcpy((u8
*)ndev_vif
->backup_settings
.beacon
.beacon_ies
, settings
->beacon
.beacon_ies
, settings
->beacon
.beacon_ies_len
);
2020 ndev_vif
->backup_settings
.beacon
.proberesp_ies
= kmalloc(settings
->beacon
.proberesp_ies_len
, GFP_KERNEL
);
2021 memcpy((u8
*)ndev_vif
->backup_settings
.beacon
.proberesp_ies
, settings
->beacon
.proberesp_ies
,settings
->beacon
.proberesp_ies_len
);
2022 ndev_vif
->backup_settings
.beacon
.assocresp_ies
= kmalloc(settings
->beacon
.assocresp_ies_len
, GFP_KERNEL
);
2023 memcpy((u8
*)ndev_vif
->backup_settings
.beacon
.assocresp_ies
, settings
->beacon
.assocresp_ies
, settings
->beacon
.assocresp_ies_len
);
2024 ndev_vif
->backup_settings
.beacon
.probe_resp
= kmalloc(settings
->beacon
.probe_resp_len
, GFP_KERNEL
);
2025 memcpy((u8
*)ndev_vif
->backup_settings
.beacon
.probe_resp
, settings
->beacon
.probe_resp
, settings
->beacon
.probe_resp_len
);
2027 ndev_vif
->backup_settings
.ssid
= kmalloc(settings
->ssid_len
, GFP_KERNEL
);
2028 memcpy((u8
*)ndev_vif
->backup_settings
.ssid
, settings
->ssid
, settings
->ssid_len
);
2029 if (settings
->ht_cap
) {
2030 ndev_vif
->backup_settings
.ht_cap
= kmalloc(sizeof(struct ieee80211_ht_cap
), GFP_KERNEL
);
2031 memcpy((u8
*)ndev_vif
->backup_settings
.ht_cap
, settings
->ht_cap
, sizeof(struct ieee80211_ht_cap
));
2033 if (settings
->vht_cap
) {
2034 ndev_vif
->backup_settings
.vht_cap
= kmalloc(sizeof(struct ieee80211_vht_cap
), GFP_KERNEL
);
2035 memcpy((u8
*)ndev_vif
->backup_settings
.vht_cap
, settings
->vht_cap
, sizeof(struct ieee80211_vht_cap
));
2040 int slsi_start_ap(struct wiphy
*wiphy
, struct net_device
*dev
,
2041 struct cfg80211_ap_settings
*settings
)
2043 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2044 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
2045 struct net_device
*wlan_dev
;
2046 u8 device_address
[ETH_ALEN
] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2048 const u8
*wpa_ie_pos
= NULL
;
2049 size_t wpa_ie_len
= 0;
2050 const u8
*wmm_ie_pos
= NULL
;
2051 size_t wmm_ie_len
= 0;
2052 const u8
*country_ie
= NULL
;
2053 char alpha2
[SLSI_COUNTRY_CODE_LEN
];
2054 bool append_vht_ies
= false;
2056 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
2057 int wifi_sharing_channel_switched
= 0;
2058 struct netdev_vif
*ndev_sta_vif
;
2059 int invalid_channel
= 0;
2061 int skip_indoor_check_for_wifi_sharing
= 0;
2062 u8
*ds_params_ie
= NULL
;
2063 struct ieee80211_mgmt
*mgmt
;
2064 u16 beacon_ie_head_len
;
2065 u8
*ht_operation_ie
= NULL
;
2066 struct ieee80211_channel
*channel
= NULL
;
2067 int indoor_channel
= 0;
2072 SLSI_MUTEX_LOCK(sdev
->start_stop_mutex
);
2073 if (sdev
->device_state
!= SLSI_DEVICE_STATE_STARTED
) {
2074 SLSI_WARN(sdev
, "device not started yet (device_state:%d)\n", sdev
->device_state
);
2076 goto exit_with_start_stop_mutex
;
2079 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
2080 /* Abort any ongoing wlan scan. */
2081 wlan_dev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_WLAN
);
2083 slsi_abort_hw_scan(sdev
, wlan_dev
);
2085 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "AP frequency received: %d\n", settings
->chandef
.chan
->center_freq
);
2086 mgmt
= (struct ieee80211_mgmt
*)settings
->beacon
.head
;
2087 beacon_ie_head_len
= settings
->beacon
.head_len
- ((u8
*)mgmt
->u
.beacon
.variable
- (u8
*)mgmt
);
2088 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
2089 ndev_sta_vif
= netdev_priv(wlan_dev
);
2090 if (SLSI_IS_VIF_INDEX_MHS(sdev
, ndev_vif
)) {
2092 SLSI_MUTEX_LOCK(ndev_sta_vif
->vif_mutex
);
2093 if ((ndev_sta_vif
->activated
) && (ndev_sta_vif
->vif_type
== FAPI_VIFTYPE_STATION
) &&
2094 (ndev_sta_vif
->sta
.vif_status
== SLSI_VIF_STATUS_CONNECTING
||
2095 ndev_sta_vif
->sta
.vif_status
== SLSI_VIF_STATUS_CONNECTED
)) {
2096 invalid_channel
= slsi_select_wifi_sharing_ap_channel(wiphy
, dev
, settings
, sdev
,
2097 &wifi_sharing_channel_switched
);
2098 skip_indoor_check_for_wifi_sharing
= 1;
2099 if (invalid_channel
) {
2100 SLSI_NET_ERR(dev
, "Rejecting AP start req at host (invalid channel)\n");
2101 SLSI_MUTEX_UNLOCK(ndev_sta_vif
->vif_mutex
);
2103 goto exit_with_vif_mutex
;
2106 SLSI_MUTEX_UNLOCK(ndev_sta_vif
->vif_mutex
);
2111 memset(&ndev_vif
->ap
, 0, sizeof(ndev_vif
->ap
));
2112 /* Initialise all allocated peer structures to remove old data. */
2113 /*slsi_netif_init_all_peers(sdev, dev);*/
2115 /* Reg domain changes */
2116 country_ie
= cfg80211_find_ie(WLAN_EID_COUNTRY
, settings
->beacon
.tail
, settings
->beacon
.tail_len
);
2119 memcpy(alpha2
, country_ie
, SLSI_COUNTRY_CODE_LEN
);
2120 if (memcmp(sdev
->device_config
.domain_info
.regdomain
->alpha2
, alpha2
, SLSI_COUNTRY_CODE_LEN
- 1) != 0) {
2121 if (slsi_set_country_update_regd(sdev
, alpha2
, SLSI_COUNTRY_CODE_LEN
) != 0) {
2123 goto exit_with_vif_mutex
;
2127 if (!skip_indoor_check_for_wifi_sharing
&& sdev
->band_5g_supported
&&
2128 ((settings
->chandef
.chan
->center_freq
/ 1000) == 5)) {
2129 channel
= ieee80211_get_channel(sdev
->wiphy
, settings
->chandef
.chan
->center_freq
);
2131 SLSI_ERR(sdev
, "Invalid frequency %d used to start AP. Channel not found\n",
2132 settings
->chandef
.chan
->center_freq
);
2134 goto exit_with_vif_mutex
;
2136 if (ndev_vif
->iftype
!= NL80211_IFTYPE_P2P_GO
) {
2137 if ((channel
->flags
) & (IEEE80211_CHAN_INDOOR_ONLY
)) {
2138 chan_flags
= (IEEE80211_CHAN_INDOOR_ONLY
| IEEE80211_CHAN_RADAR
|
2139 IEEE80211_CHAN_DISABLED
|
2140 #if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 10, 13)
2141 IEEE80211_CHAN_PASSIVE_SCAN
2143 IEEE80211_CHAN_NO_IR
2147 for (i
= 0; i
< wiphy
->bands
[NL80211_BAND_5GHZ
]->n_channels
; i
++) {
2148 if (!(wiphy
->bands
[NL80211_BAND_5GHZ
]->channels
[i
].flags
& chan_flags
)) {
2149 center_freq
= wiphy
->bands
[NL80211_BAND_5GHZ
]->channels
[i
].center_freq
;
2150 settings
->chandef
.chan
= ieee80211_get_channel(wiphy
, center_freq
);
2151 settings
->chandef
.center_freq1
= center_freq
;
2152 SLSI_DBG1(sdev
, SLSI_CFG80211
, "ap valid frequency:%d,chan_flags:%x\n",
2154 wiphy
->bands
[NL80211_BAND_5GHZ
]->channels
[i
].flags
);
2159 if (indoor_channel
== 0) {
2160 SLSI_ERR(sdev
, "No valid channel found to start the AP");
2162 goto exit_with_vif_mutex
;
2168 r
= slsi_ap_start_validate(dev
, sdev
, settings
);
2170 goto exit_with_vif_mutex
;
2172 if (ndev_vif
->iftype
== NL80211_IFTYPE_P2P_GO
) {
2173 struct net_device
*p2p_dev
;
2175 slsi_p2p_group_start_remove_unsync_vif(sdev
);
2176 p2p_dev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_P2P
);
2177 SLSI_ETHER_COPY(device_address
, p2p_dev
->dev_addr
);
2178 if (keep_alive_period
!= SLSI_P2PGO_KEEP_ALIVE_PERIOD_SEC
)
2179 if (slsi_set_uint_mib(sdev
, NULL
, SLSI_PSID_UNIFI_MLMEGO_KEEP_ALIVE_TIMEOUT
,
2180 keep_alive_period
) != 0) {
2181 SLSI_NET_ERR(dev
, "P2PGO Keep Alive MIB set failed");
2183 goto exit_with_vif_mutex
;
2187 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
2188 SLSI_NET_DBG1(dev
, SLSI_MLME
, "Channel: %d, Maximum bandwidth: %d\n", ndev_vif
->chandef
->chan
->hw_value
,
2189 slsi_get_max_bw_mhz(sdev
, ndev_vif
->chandef
->chan
->center_freq
));
2190 /* 11ac configuration (5GHz and VHT) */
2191 if ((ndev_vif
->chandef
->chan
->hw_value
>= 36) && (ndev_vif
->chandef
->chan
->hw_value
< 165) &&
2192 (sdev
->fw_vht_enabled
) && sdev
->allow_switch_80_mhz
&&
2193 (slsi_get_max_bw_mhz(sdev
, ndev_vif
->chandef
->chan
->center_freq
) >= 80)) {
2194 u16 oper_chan
= ndev_vif
->chandef
->chan
->hw_value
;
2195 append_vht_ies
= true;
2196 ndev_vif
->chandef
->width
= NL80211_CHAN_WIDTH_80
;
2198 SLSI_NET_DBG1(dev
, SLSI_MLME
, "5 GHz- Include VHT\n");
2199 if ((oper_chan
>= 36) && (oper_chan
<= 48))
2200 ndev_vif
->chandef
->center_freq1
= ieee80211_channel_to_frequency(42, NL80211_BAND_5GHZ
);
2201 else if ((oper_chan
>= 149) && (oper_chan
<= 161))
2202 ndev_vif
->chandef
->center_freq1
= ieee80211_channel_to_frequency(155, NL80211_BAND_5GHZ
);
2203 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
2204 /* In wifi sharing case, AP can start on STA channel even though it is DFS channel*/
2205 if (wifi_sharing_channel_switched
== 1) {
2206 if ((oper_chan
>= 52) && (oper_chan
<= 64))
2207 ndev_vif
->chandef
->center_freq1
= ieee80211_channel_to_frequency(58,
2209 else if ((oper_chan
>= 100) && (oper_chan
<= 112))
2210 ndev_vif
->chandef
->center_freq1
= ieee80211_channel_to_frequency(106,
2212 else if ((oper_chan
>= 116) && (oper_chan
<= 128))
2213 ndev_vif
->chandef
->center_freq1
= ieee80211_channel_to_frequency(122,
2215 else if ((oper_chan
>= 132) && (oper_chan
<= 144))
2216 ndev_vif
->chandef
->center_freq1
= ieee80211_channel_to_frequency(138,
2220 } else if (sdev
->fw_ht_enabled
&& sdev
->allow_switch_40_mhz
&&
2221 slsi_get_max_bw_mhz(sdev
, ndev_vif
->chandef
->chan
->center_freq
) >= 40 &&
2222 ((ndev_vif
->chandef
->chan
->hw_value
< 165 && ndev_vif
->chandef
->chan
->hw_value
>= 36) ||
2223 (ndev_vif
->chandef
->chan
->hw_value
< 12 && sdev
->fw_SoftAp_2g_40mhz_enabled
&&
2224 ndev_vif
->iftype
== NL80211_IFTYPE_P2P_GO
))) {
2225 /* HT40 configuration (5GHz/2GHz and HT) */
2226 u16 oper_chan
= ndev_vif
->chandef
->chan
->hw_value
;
2227 u8 bw_40_minus_channels
[] = { 40, 48, 153, 161, 5, 6, 7, 8, 9, 10, 11 };
2228 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
2229 u8 bw_40_minus_dfs_channels
[] = { 144, 136, 128, 120, 112, 104, 64, 56 };
2233 ndev_vif
->chandef
->width
= NL80211_CHAN_WIDTH_40
;
2234 ndev_vif
->chandef
->center_freq1
= ndev_vif
->chandef
->chan
->center_freq
+ 10;
2235 for (ch
= 0; ch
< ARRAY_SIZE(bw_40_minus_channels
); ch
++)
2236 if (oper_chan
== bw_40_minus_channels
[ch
]) {
2237 ndev_vif
->chandef
->center_freq1
= ndev_vif
->chandef
->chan
->center_freq
- 10;
2241 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
2242 if (wifi_sharing_channel_switched
== 1) {
2243 for (ch
= 0; ch
< ARRAY_SIZE(bw_40_minus_dfs_channels
); ch
++)
2244 if (oper_chan
== bw_40_minus_dfs_channels
[ch
]) {
2245 ndev_vif
->chandef
->center_freq1
= ndev_vif
->chandef
->chan
->center_freq
- 10;
2253 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
2254 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
2255 if (slsi_check_channelization(sdev
, ndev_vif
->chandef
, wifi_sharing_channel_switched
) != 0) {
2257 if (slsi_check_channelization(sdev
, ndev_vif
->chandef
, 0) != 0) {
2260 if (slsi_check_channelization(sdev
, ndev_vif
->channel_type
) != 0) {
2263 goto exit_with_vif_mutex
;
2266 if (ndev_vif
->iftype
== NL80211_IFTYPE_AP
) {
2268 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
2269 if (ndev_vif
->chandef
->width
== NL80211_CHAN_WIDTH_20
)
2271 if (ndev_vif
->channel_type
== NL80211_CHAN_HT20
)
2273 slsi_ap_start_obss_scan(sdev
, dev
, ndev_vif
);
2276 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
2277 if (ndev_vif
->chandef
->width
<= NL80211_CHAN_WIDTH_20
) {
2278 /* Enable LDPC, SGI20 and SGI40 for both SoftAP & P2PGO if firmware supports */
2279 if (cfg80211_find_ie(WLAN_EID_HT_CAPABILITY
, settings
->beacon
.tail
, settings
->beacon
.tail_len
)) {
2280 u8 enforce_ht_cap1
= sdev
->fw_ht_cap
[0] & (IEEE80211_HT_CAP_LDPC_CODING
|
2281 IEEE80211_HT_CAP_SGI_20
);
2282 u8 enforce_ht_cap2
= sdev
->fw_ht_cap
[1] & (IEEE80211_HT_CAP_RX_STBC
>> 8);
2284 slsi_modify_ies(dev
, WLAN_EID_HT_CAPABILITY
, (u8
*)settings
->beacon
.tail
,
2285 settings
->beacon
.tail_len
, 2, enforce_ht_cap1
);
2286 slsi_modify_ies(dev
, WLAN_EID_HT_CAPABILITY
, (u8
*)settings
->beacon
.tail
,
2287 settings
->beacon
.tail_len
, 3, enforce_ht_cap2
);
2289 } else if (cfg80211_chandef_valid(ndev_vif
->chandef
)) {
2290 u8
*ht_operation_ie
;
2291 u8 sec_chan_offset
= 0;
2293 u8 bw_40_minus_channels
[] = { 40, 48, 153, 161, 5, 6, 7, 8, 9, 10, 11 };
2295 ht_operation_ie
= (u8
*)cfg80211_find_ie(WLAN_EID_HT_OPERATION
, settings
->beacon
.tail
,
2296 settings
->beacon
.tail_len
);
2297 if (!ht_operation_ie
) {
2298 SLSI_NET_ERR(dev
, "HT Operation IE is not passed by wpa_supplicant");
2300 goto exit_with_vif_mutex
;
2303 sec_chan_offset
= IEEE80211_HT_PARAM_CHA_SEC_ABOVE
;
2304 for (ch
= 0; ch
< ARRAY_SIZE(bw_40_minus_channels
); ch
++)
2305 if (bw_40_minus_channels
[ch
] == ndev_vif
->chandef
->chan
->hw_value
) {
2306 sec_chan_offset
= IEEE80211_HT_PARAM_CHA_SEC_BELOW
;
2310 /* Change HT Information IE subset 1 */
2311 ht_operation_ie
+= 3;
2312 *(ht_operation_ie
) |= sec_chan_offset
;
2313 *(ht_operation_ie
) |= IEEE80211_HT_PARAM_CHAN_WIDTH_ANY
;
2315 /* For 80MHz, Enable HT Capabilities : Support 40MHz Channel Width, SGI20 and SGI40
2316 * for AP (both softAp as well as P2P GO), if firmware supports.
2318 if (cfg80211_find_ie(WLAN_EID_HT_CAPABILITY
, settings
->beacon
.tail
,
2319 settings
->beacon
.tail_len
)) {
2320 u8 enforce_ht_cap1
= sdev
->fw_ht_cap
[0] & (IEEE80211_HT_CAP_SUP_WIDTH_20_40
|
2321 IEEE80211_HT_CAP_SGI_20
|
2322 IEEE80211_HT_CAP_SGI_40
|
2323 IEEE80211_HT_CAP_LDPC_CODING
);
2324 u8 enforce_ht_cap2
= sdev
->fw_ht_cap
[1] & (IEEE80211_HT_CAP_RX_STBC
>> 8);
2326 slsi_modify_ies(dev
, WLAN_EID_HT_CAPABILITY
, (u8
*)settings
->beacon
.tail
,
2327 settings
->beacon
.tail_len
, 2, enforce_ht_cap1
);
2328 slsi_modify_ies(dev
, WLAN_EID_HT_CAPABILITY
, (u8
*)settings
->beacon
.tail
,
2329 settings
->beacon
.tail_len
, 3, enforce_ht_cap2
);
2334 if (indoor_channel
== 1
2335 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
2336 || (wifi_sharing_channel_switched
== 1)
2339 slsi_modify_ies_on_channel_switch(dev
, settings
, ds_params_ie
, ht_operation_ie
, mgmt
, beacon_ie_head_len
);
2341 ndev_vif
->vif_type
= FAPI_VIFTYPE_AP
;
2343 if (slsi_mlme_add_vif(sdev
, dev
, dev
->dev_addr
, device_address
) != 0) {
2344 SLSI_NET_ERR(dev
, "slsi_mlme_add_vif failed\n");
2346 goto exit_with_vif_mutex
;
2349 if (slsi_vif_activated(sdev
, dev
) != 0) {
2350 SLSI_NET_ERR(dev
, "slsi_vif_activated failed\n");
2354 /* Extract the WMM and WPA IEs from settings->beacon.tail - This is sent in add_info_elements and shouldn't be included in start_req
2355 * Cache IEs to be used in later add_info_elements_req. The IEs would be freed during AP stop
2357 wpa_ie_pos
= cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT
, WLAN_OUI_TYPE_MICROSOFT_WPA
, settings
->beacon
.tail
, settings
->beacon
.tail_len
);
2359 wpa_ie_len
= (size_t)(*(wpa_ie_pos
+ 1) + 2); /* For 0xdd (1) and Tag Length (1) */
2360 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "WPA IE found: Length = %zu\n", wpa_ie_len
);
2361 SLSI_EC_GOTO(slsi_cache_ies(wpa_ie_pos
, wpa_ie_len
, &ndev_vif
->ap
.cache_wpa_ie
, &ndev_vif
->ap
.wpa_ie_len
), r
, exit_with_vif
);
2364 wmm_ie_pos
= cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT
, WLAN_OUI_TYPE_MICROSOFT_WMM
, settings
->beacon
.tail
, settings
->beacon
.tail_len
);
2366 wmm_ie_len
= (size_t)(*(wmm_ie_pos
+ 1) + 2);
2367 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "WMM IE found: Length = %zu\n", wmm_ie_len
);
2368 SLSI_EC_GOTO(slsi_cache_ies(wmm_ie_pos
, wmm_ie_len
, &ndev_vif
->ap
.cache_wmm_ie
, &ndev_vif
->ap
.wmm_ie_len
), r
, exit_with_vif
);
2371 slsi_clear_cached_ies(&ndev_vif
->ap
.add_info_ies
, &ndev_vif
->ap
.add_info_ies_len
);
2373 /* Set Vendor specific IEs (WPA, WMM, WPS, P2P) for Beacon, Probe Response and Association Response
2374 * The Beacon and Assoc Rsp IEs can include Extended Capability (WLAN_EID_EXT_CAPAB) IE when supported.
2375 * Some other IEs (like internetworking, etc) can also come if supported.
2376 * The add_info should include only vendor specific IEs and other IEs should be removed if supported in future.
2378 if ((wmm_ie_pos
) || (wpa_ie_pos
) || (settings
->beacon
.beacon_ies_len
> 0 && settings
->beacon
.beacon_ies
)) {
2379 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "Add info elements for beacon\n");
2380 SLSI_EC_GOTO(slsi_ap_prepare_add_info_ies(ndev_vif
, settings
->beacon
.beacon_ies
, settings
->beacon
.beacon_ies_len
), r
, exit_with_vif
);
2381 SLSI_EC_GOTO(slsi_mlme_add_info_elements(sdev
, dev
, FAPI_PURPOSE_BEACON
, ndev_vif
->ap
.add_info_ies
, ndev_vif
->ap
.add_info_ies_len
), r
, exit_with_vif
);
2382 slsi_clear_cached_ies(&ndev_vif
->ap
.add_info_ies
, &ndev_vif
->ap
.add_info_ies_len
);
2385 if ((wmm_ie_pos
) || (wpa_ie_pos
) || (settings
->beacon
.proberesp_ies_len
> 0 && settings
->beacon
.proberesp_ies
)) {
2386 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "Add info elements for probe response\n");
2387 SLSI_EC_GOTO(slsi_ap_prepare_add_info_ies(ndev_vif
, settings
->beacon
.proberesp_ies
, settings
->beacon
.proberesp_ies_len
), r
, exit_with_vif
);
2388 SLSI_EC_GOTO(slsi_mlme_add_info_elements(sdev
, dev
, FAPI_PURPOSE_PROBE_RESPONSE
, ndev_vif
->ap
.add_info_ies
, ndev_vif
->ap
.add_info_ies_len
), r
, exit_with_vif
);
2389 slsi_clear_cached_ies(&ndev_vif
->ap
.add_info_ies
, &ndev_vif
->ap
.add_info_ies_len
);
2392 if ((wmm_ie_pos
) || (wpa_ie_pos
) || (settings
->beacon
.assocresp_ies_len
> 0 && settings
->beacon
.assocresp_ies
)) {
2393 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "Add info elements for assoc response\n");
2394 SLSI_EC_GOTO(slsi_ap_prepare_add_info_ies(ndev_vif
, settings
->beacon
.assocresp_ies
, settings
->beacon
.assocresp_ies_len
), r
, exit_with_vif
);
2395 SLSI_EC_GOTO(slsi_mlme_add_info_elements(sdev
, dev
, FAPI_PURPOSE_ASSOCIATION_RESPONSE
, ndev_vif
->ap
.add_info_ies
, ndev_vif
->ap
.add_info_ies_len
), r
, exit_with_vif
);
2396 slsi_clear_cached_ies(&ndev_vif
->ap
.add_info_ies
, &ndev_vif
->ap
.add_info_ies_len
);
2399 if (ndev_vif
->iftype
== NL80211_IFTYPE_P2P_GO
) {
2400 u32 af_bmap_active
= SLSI_ACTION_FRAME_PUBLIC
;
2401 u32 af_bmap_suspended
= SLSI_ACTION_FRAME_PUBLIC
;
2403 r
= slsi_mlme_register_action_frame(sdev
, dev
, af_bmap_active
, af_bmap_suspended
);
2405 SLSI_NET_ERR(dev
, "slsi_mlme_register_action_frame failed: resultcode = %d\n", r
);
2410 if (append_vht_ies
) {
2411 ndev_vif
->ap
.mode
= SLSI_80211_MODE_11AC
;
2412 } else if (cfg80211_find_ie(WLAN_EID_HT_CAPABILITY
, settings
->beacon
.tail
, settings
->beacon
.tail_len
) &&
2413 cfg80211_find_ie(WLAN_EID_HT_OPERATION
, settings
->beacon
.tail
, settings
->beacon
.tail_len
)) {
2414 ndev_vif
->ap
.mode
= SLSI_80211_MODE_11N
;
2416 ie
= cfg80211_find_ie(WLAN_EID_SUPP_RATES
, settings
->beacon
.tail
, settings
->beacon
.tail_len
);
2418 ndev_vif
->ap
.mode
= slsi_get_supported_mode(ie
);
2421 r
= slsi_mlme_start(sdev
, dev
, dev
->dev_addr
, settings
, wpa_ie_pos
, wmm_ie_pos
, append_vht_ies
);
2423 if ((indoor_channel
== 1)
2424 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
2425 || (wifi_sharing_channel_switched
== 1)
2427 #ifdef CONFIG_SCSC_WLAN_ACS_ENABLE
2428 || (sdev
->acs_channel_switched
== true)
2431 cfg80211_ch_switch_notify(dev
, &settings
->chandef
);
2433 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
2435 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "Soft Ap started on frequency: %d\n",
2436 settings
->chandef
.chan
->center_freq
);
2437 if (SLSI_IS_VIF_INDEX_MHS(sdev
, ndev_vif
))
2438 ndev_vif
->chan
= settings
->chandef
.chan
;
2441 SLSI_NET_ERR(dev
, "Start ap failed: resultcode = %d frequency = %d\n", r
,
2442 settings
->chandef
.chan
->center_freq
);
2444 } else if (ndev_vif
->iftype
== NL80211_IFTYPE_P2P_GO
) {
2445 SLSI_P2P_STATE_CHANGE(sdev
, P2P_GROUP_FORMED_GO
);
2447 #ifdef CONFIG_SCSC_WLAN_SET_NUM_ANTENNAS
2448 if (ndev_vif
->iftype
== NL80211_IFTYPE_AP
) {
2449 /* Don't care results. */
2450 slsi_set_num_antennas(dev
, 1 /*SISO*/);
2453 ndev_vif
->ap
.beacon_interval
= settings
->beacon_interval
;
2454 ndev_vif
->ap
.ssid_len
= settings
->ssid_len
;
2455 memcpy(ndev_vif
->ap
.ssid
, settings
->ssid
, settings
->ssid_len
);
2457 netif_carrier_on(dev
);
2459 if (ndev_vif
->ipaddress
!= cpu_to_be32(0))
2460 /* Static IP is assigned already */
2461 slsi_ip_address_changed(sdev
, dev
, ndev_vif
->ipaddress
);
2463 r
= slsi_read_disconnect_ind_timeout(sdev
, SLSI_PSID_UNIFI_DISCONNECT_TIMEOUT
);
2465 sdev
->device_config
.ap_disconnect_ind_timeout
= *sdev
->sig_wait_cfm_timeout
;
2467 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "slsi_read_disconnect_ind_timeout: timeout = %d", sdev
->device_config
.ap_disconnect_ind_timeout
);
2468 goto exit_with_vif_mutex
;
2470 slsi_clear_cached_ies(&ndev_vif
->ap
.add_info_ies
, &ndev_vif
->ap
.add_info_ies_len
);
2471 slsi_mlme_del_vif(sdev
, dev
);
2472 slsi_vif_deactivated(sdev
, dev
);
2474 exit_with_vif_mutex
:
2475 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2476 exit_with_start_stop_mutex
:
2477 SLSI_MUTEX_UNLOCK(sdev
->start_stop_mutex
);
2479 #ifdef CONFIG_SCSC_WLAN_SILENT_RECOVERY
2480 slsi_store_settings_for_recovery(settings
, ndev_vif
);
2485 int slsi_change_beacon(struct wiphy
*wiphy
, struct net_device
*dev
,
2486 struct cfg80211_beacon_data
*info
)
2488 SLSI_UNUSED_PARAMETER(info
);
2493 int slsi_stop_ap(struct wiphy
*wiphy
, struct net_device
*dev
)
2495 slsi_reset_throughput_stats(dev
);
2500 static int slsi_p2p_group_mgmt_tx(const struct ieee80211_mgmt
*mgmt
, struct wiphy
*wiphy
,
2501 struct net_device
*dev
, struct ieee80211_channel
*chan
,
2502 unsigned int wait
, const u8
*buf
, size_t len
,
2503 bool dont_wait_for_ack
, u64
*cookie
)
2505 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2506 struct netdev_vif
*ndev_vif
;
2507 struct net_device
*netdev
;
2508 int subtype
= slsi_p2p_get_public_action_subtype(mgmt
);
2510 u32 host_tag
= slsi_tx_mgmt_host_tag(sdev
);
2512 u32 dwell_time
= SLSI_FORCE_SCHD_ACT_FRAME_MSEC
;
2513 u16 data_unit_desc
= FAPI_DATAUNITDESCRIPTOR_IEEE802_11_FRAME
;
2515 if (sdev
->p2p_group_exp_frame
!= SLSI_P2P_PA_INVALID
) {
2516 SLSI_NET_ERR(dev
, "sdev->p2p_group_exp_frame : %d\n", sdev
->p2p_group_exp_frame
);
2519 netdev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_P2PX_SWLAN
);
2520 ndev_vif
= netdev_priv(netdev
);
2521 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
2522 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "Sending Action frame (%s) on p2p group vif (%d), vif_index = %d,"
2523 "vif_type = %d, chan->hw_value = %d, ndev_vif->chan->hw_value = %d, wait = %d,"
2524 "sdev->p2p_group_exp_frame = %d\n", slsi_p2p_pa_subtype_text(subtype
), ndev_vif
->activated
,
2525 ndev_vif
->ifnum
, ndev_vif
->vif_type
, chan
->hw_value
, ndev_vif
->chan
->hw_value
, wait
,
2526 ndev_vif
->chan
->hw_value
);
2528 if (!((ndev_vif
->iftype
== NL80211_IFTYPE_P2P_GO
) || (ndev_vif
->iftype
== NL80211_IFTYPE_P2P_CLIENT
)))
2529 goto exit_with_error
;
2531 if (chan
->hw_value
!= ndev_vif
->chan
->hw_value
) {
2532 freq
= SLSI_FREQ_HOST_TO_FW(chan
->center_freq
);
2536 /* Incase of GO dont wait for resp/cfm packets for go-negotiation.*/
2537 if (subtype
!= SLSI_P2P_PA_GO_NEG_RSP
)
2538 sdev
->p2p_group_exp_frame
= slsi_p2p_get_exp_peer_frame_subtype(subtype
);
2540 r
= slsi_mlme_send_frame_mgmt(sdev
, netdev
, buf
, len
, data_unit_desc
, FAPI_MESSAGETYPE_IEEE80211_ACTION
, host_tag
, freq
, dwell_time
* 1000, 0);
2542 goto exit_with_lock
;
2543 slsi_assign_cookie_id(cookie
, &ndev_vif
->mgmt_tx_cookie
);
2544 r
= slsi_set_mgmt_tx_data(ndev_vif
, *cookie
, host_tag
, buf
, len
); /* If error then it is returned in exit */
2545 goto exit_with_lock
;
2550 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2554 /* Handle mgmt_tx callback for P2P modes */
2555 static int slsi_p2p_mgmt_tx(const struct ieee80211_mgmt
*mgmt
, struct wiphy
*wiphy
,
2556 struct net_device
*dev
, struct netdev_vif
*ndev_vif
,
2557 struct ieee80211_channel
*chan
, unsigned int wait
,
2558 const u8
*buf
, size_t len
, bool dont_wait_for_ack
, u64
*cookie
)
2560 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2563 if (ieee80211_is_action(mgmt
->frame_control
)) {
2564 u16 host_tag
= slsi_tx_mgmt_host_tag(sdev
);
2565 int subtype
= slsi_p2p_get_public_action_subtype(mgmt
);
2569 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "Action frame (%s), unsync_vif_active (%d)\n", slsi_p2p_pa_subtype_text(subtype
), ndev_vif
->activated
);
2571 if (subtype
== SLSI_P2P_PA_INVALID
) {
2572 SLSI_NET_ERR(dev
, "Invalid Action frame subtype\n");
2573 goto exit_with_error
;
2576 /* Check if unsync vif is available */
2577 if (sdev
->p2p_state
== P2P_IDLE_NO_VIF
)
2578 if (slsi_p2p_vif_activate(sdev
, dev
, chan
, wait
, false) != 0)
2579 goto exit_with_error
;
2581 /* Clear Probe Response IEs if vif was already present with a different channel */
2582 if (ndev_vif
->driver_channel
!= chan
->hw_value
) {
2583 if (slsi_mlme_add_info_elements(sdev
, dev
, FAPI_PURPOSE_PROBE_RESPONSE
, NULL
, 0) != 0)
2584 SLSI_NET_ERR(dev
, "Clearing Probe Response IEs failed for unsync vif\n");
2585 slsi_unsync_vif_set_probe_rsp_ie(ndev_vif
, NULL
, 0);
2587 if (slsi_mlme_set_channel(sdev
, dev
, chan
, SLSI_FW_CHANNEL_DURATION_UNSPECIFIED
, 0, 0) != 0)
2590 ndev_vif
->chan
= chan
;
2591 ndev_vif
->driver_channel
= chan
->hw_value
;
2595 /* Check if peer frame response is expected */
2596 exp_peer_frame
= slsi_p2p_get_exp_peer_frame_subtype(subtype
);
2598 if (exp_peer_frame
!= SLSI_P2P_PA_INVALID
) {
2599 if ((subtype
== SLSI_P2P_PA_GO_NEG_RSP
) && (slsi_p2p_get_go_neg_rsp_status(dev
, mgmt
) != SLSI_P2P_STATUS_CODE_SUCCESS
)) {
2600 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "GO_NEG_RSP Tx, peer response not expected\n");
2601 exp_peer_frame
= SLSI_P2P_PA_INVALID
;
2603 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "Peer response expected with action frame (%s)\n",
2604 slsi_p2p_pa_subtype_text(exp_peer_frame
));
2606 if (ndev_vif
->mgmt_tx_data
.exp_frame
!= SLSI_P2P_PA_INVALID
)
2607 (void)slsi_set_mgmt_tx_data(ndev_vif
, 0, 0, NULL
, 0);
2609 /* Change Force Schedule Duration as peer response is expected */
2613 dwell_time
= SLSI_FORCE_SCHD_ACT_FRAME_MSEC
;
2617 slsi_assign_cookie_id(cookie
, &ndev_vif
->mgmt_tx_cookie
);
2619 /* Send the action frame, transmission status indication would be received later */
2620 if (slsi_mlme_send_frame_mgmt(sdev
, dev
, buf
, len
, FAPI_DATAUNITDESCRIPTOR_IEEE802_11_FRAME
, FAPI_MESSAGETYPE_IEEE80211_ACTION
, host_tag
, 0, dwell_time
* 1000, 0) != 0)
2622 if (subtype
== SLSI_P2P_PA_GO_NEG_CFM
)
2623 ndev_vif
->drv_in_p2p_procedure
= false;
2624 else if ((subtype
== SLSI_P2P_PA_GO_NEG_REQ
) || (subtype
== SLSI_P2P_PA_PROV_DISC_REQ
))
2625 ndev_vif
->drv_in_p2p_procedure
= true;
2626 /* If multiple frames are requested for tx, only the info of first frame would be stored */
2627 if (ndev_vif
->mgmt_tx_data
.host_tag
== 0) {
2628 unsigned int n_wait
= 0;
2630 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "Store mgmt frame tx data for cookie = 0x%llx\n", *cookie
);
2632 ret
= slsi_set_mgmt_tx_data(ndev_vif
, *cookie
, host_tag
, buf
, len
);
2635 ndev_vif
->mgmt_tx_data
.exp_frame
= exp_peer_frame
;
2637 SLSI_P2P_STATE_CHANGE(sdev
, P2P_ACTION_FRAME_TX_RX
);
2638 if ((exp_peer_frame
== SLSI_P2P_PA_GO_NEG_RSP
) || (exp_peer_frame
== SLSI_P2P_PA_GO_NEG_CFM
))
2639 /* Retain vif for larger duration that wpa_supplicant asks to wait,
2640 * during GO-Negotiation to allow peer to retry GO neg in bad radio condition.
2641 * Some of phones retry GO-Negotiation after 2 seconds
2643 n_wait
= SLSI_P2P_NEG_PROC_UNSYNC_VIF_RETAIN_DURATION
;
2644 else if (exp_peer_frame
!= SLSI_P2P_PA_INVALID
)
2645 /* If a peer response is expected queue work to retain vif till wait time else the work will be handled in mgmt_tx_cancel_wait */
2646 n_wait
= wait
+ SLSI_P2P_MGMT_TX_EXTRA_MSEC
;
2648 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "retain unsync vif for duration (%d) msec\n", n_wait
);
2649 slsi_p2p_queue_unsync_vif_del_work(ndev_vif
, n_wait
);
2652 /* Already a frame Tx is in progress, send immediate tx_status as success. Sending immediate tx status should be ok
2653 * as supplicant is in another procedure and so these frames would be mostly only response frames.
2655 WARN_ON(sdev
->p2p_state
!= P2P_ACTION_FRAME_TX_RX
);
2657 if (!dont_wait_for_ack
) {
2658 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "Send immediate tx_status (cookie = 0x%llx)\n", *cookie
);
2659 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2660 cfg80211_mgmt_tx_status(&ndev_vif
->wdev
, *cookie
, buf
, len
, true, GFP_KERNEL
);
2662 cfg80211_mgmt_tx_status(dev
, *cookie
, buf
, len
, true, GFP_KERNEL
);
2669 /* Else send failure for unexpected management frame */
2670 SLSI_NET_ERR(dev
, "Drop Tx frame: Unexpected Management frame\n");
2671 goto exit_with_error
;
2674 if (sdev
->p2p_state
!= P2P_LISTENING
)
2675 slsi_p2p_vif_deactivate(sdev
, dev
, true);
2682 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2683 int slsi_mgmt_tx_cancel_wait(struct wiphy
*wiphy
,
2684 struct wireless_dev
*wdev
,
2687 struct net_device
*dev
= wdev
->netdev
;
2690 int slsi_mgmt_tx_cancel_wait(struct wiphy
*wiphy
,
2691 struct net_device
*dev
,
2694 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) */
2695 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
2696 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2698 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
2700 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "iface_num = %d, cookie = 0x%llx, vif_index = %d, vif_type = %d,"
2701 "sdev->p2p_state = %d, ndev_vif->mgmt_tx_data.cookie = 0x%llx, sdev->p2p_group_exp_frame = %d,"
2702 "sdev->wlan_unsync_vif_state = %d\n", ndev_vif
->ifnum
, cookie
,
2703 ndev_vif
->vif_type
, sdev
->p2p_state
, ndev_vif
->mgmt_tx_data
.cookie
,
2704 sdev
->p2p_group_exp_frame
, sdev
->wlan_unsync_vif_state
);
2706 /* If device was in frame tx_rx state, clear mgmt tx data and change state */
2707 if ((sdev
->p2p_state
== P2P_ACTION_FRAME_TX_RX
) && (ndev_vif
->mgmt_tx_data
.cookie
== cookie
)) {
2708 if (ndev_vif
->mgmt_tx_data
.exp_frame
!= SLSI_P2P_PA_INVALID
)
2709 (void)slsi_mlme_reset_dwell_time(sdev
, dev
);
2711 (void)slsi_set_mgmt_tx_data(ndev_vif
, 0, 0, NULL
, 0);
2712 ndev_vif
->mgmt_tx_data
.exp_frame
= SLSI_P2P_PA_INVALID
;
2714 if (delayed_work_pending(&ndev_vif
->unsync
.roc_expiry_work
)) {
2715 SLSI_P2P_STATE_CHANGE(sdev
, P2P_LISTENING
);
2717 slsi_p2p_queue_unsync_vif_del_work(ndev_vif
, SLSI_P2P_UNSYNC_VIF_EXTRA_MSEC
);
2718 SLSI_P2P_STATE_CHANGE(ndev_vif
->sdev
, P2P_IDLE_VIF_ACTIVE
);
2720 } else if ((SLSI_IS_P2P_GROUP_STATE(sdev
)) && (sdev
->p2p_group_exp_frame
!= SLSI_P2P_PA_INVALID
)) {
2721 /* acquire mutex lock if it is not group net dev */
2722 slsi_clear_offchannel_data(sdev
, (!SLSI_IS_VIF_INDEX_P2P_GROUP(sdev
, ndev_vif
)) ? true : false);
2723 } else if ((sdev
->wlan_unsync_vif_state
== WLAN_UNSYNC_VIF_TX
) && (ndev_vif
->mgmt_tx_data
.cookie
== cookie
)) {
2724 sdev
->wlan_unsync_vif_state
= WLAN_UNSYNC_VIF_ACTIVE
;
2725 cancel_delayed_work(&ndev_vif
->unsync
.hs2_del_vif_work
);
2726 queue_delayed_work(sdev
->device_wq
, &ndev_vif
->unsync
.hs2_del_vif_work
, msecs_to_jiffies(SLSI_HS2_UNSYNC_VIF_EXTRA_MSEC
));
2729 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2733 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
2734 void slsi_mgmt_frame_register(struct wiphy
*wiphy
,
2735 struct wireless_dev
*wdev
,
2736 u16 frame_type
, bool reg
)
2738 struct net_device
*dev
= wdev
->netdev
;
2741 void slsi_mgmt_frame_register(struct wiphy
*wiphy
,
2742 struct net_device
*dev
,
2743 u16 frame_type
, bool reg
)
2745 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) */
2746 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2748 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
2749 SLSI_UNUSED_PARAMETER(frame_type
);
2750 SLSI_UNUSED_PARAMETER(reg
);
2756 SLSI_UNUSED_PARAMETER(sdev
);
2759 static int slsi_wlan_mgmt_tx(struct slsi_dev
*sdev
, struct net_device
*dev
,
2760 struct ieee80211_channel
*chan
, unsigned int wait
,
2761 const u8
*buf
, size_t len
, bool dont_wait_for_ack
, u64
*cookie
)
2763 u32 host_tag
= slsi_tx_mgmt_host_tag(sdev
);
2764 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
2766 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
2768 if (!ieee80211_is_auth(mgmt
->frame_control
))
2769 slsi_wlan_dump_public_action_subtype(sdev
, mgmt
, true);
2770 if (!ndev_vif
->activated
) {
2771 r
= slsi_wlan_unsync_vif_activate(sdev
, dev
, chan
, wait
);
2775 r
= slsi_mlme_send_frame_mgmt(sdev
, dev
, buf
, len
, FAPI_DATAUNITDESCRIPTOR_IEEE802_11_FRAME
, FAPI_MESSAGETYPE_IEEE80211_ACTION
, host_tag
, 0, wait
* 1000, 0);
2779 sdev
->wlan_unsync_vif_state
= WLAN_UNSYNC_VIF_TX
;
2780 queue_delayed_work(sdev
->device_wq
, &ndev_vif
->unsync
.hs2_del_vif_work
, msecs_to_jiffies(wait
));
2783 if (ieee80211_is_auth(mgmt
->frame_control
)) {
2784 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "Transmit on the current frequency\n");
2785 r
= slsi_mlme_send_frame_mgmt(sdev
, dev
, buf
, len
, FAPI_DATAUNITDESCRIPTOR_IEEE802_11_FRAME
,
2786 FAPI_MESSAGETYPE_IEEE80211_MGMT
, host_tag
, 0, wait
* 1000, 0);
2789 } else if (ndev_vif
->vif_type
== FAPI_VIFTYPE_UNSYNCHRONISED
) {
2790 cancel_delayed_work(&ndev_vif
->unsync
.hs2_del_vif_work
);
2791 /*even if we fail to cancel the delayed work, we shall go ahead and send action frames*/
2792 if (ndev_vif
->driver_channel
!= chan
->hw_value
) {
2793 r
= slsi_mlme_set_channel(sdev
, dev
, chan
, SLSI_FW_CHANNEL_DURATION_UNSPECIFIED
, 0, 0);
2797 ndev_vif
->driver_channel
= chan
->hw_value
;
2800 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "HS2 vif is active ,send GAS (ANQP) request on channel freq = %d\n", chan
->center_freq
);
2801 r
= slsi_mlme_send_frame_mgmt(sdev
, dev
, buf
, len
, FAPI_DATAUNITDESCRIPTOR_IEEE802_11_FRAME
, FAPI_MESSAGETYPE_IEEE80211_ACTION
, host_tag
, 0, wait
* 1000, 0);
2804 sdev
->wlan_unsync_vif_state
= WLAN_UNSYNC_VIF_TX
;
2805 queue_delayed_work(sdev
->device_wq
, &ndev_vif
->unsync
.hs2_del_vif_work
, msecs_to_jiffies(wait
));
2806 } else if (ndev_vif
->chan
->hw_value
== chan
->hw_value
) {
2807 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "STA VIF is active on same channel, send GAS (ANQP) request on channel freq %d\n", chan
->center_freq
);
2808 r
= slsi_mlme_send_frame_mgmt(sdev
, dev
, buf
, len
, FAPI_DATAUNITDESCRIPTOR_IEEE802_11_FRAME
, FAPI_MESSAGETYPE_IEEE80211_ACTION
, host_tag
, 0, wait
* 1000, 0);
2812 SLSI_NET_DBG1(dev
, SLSI_CFG80211
, "STA VIF is active on a different channel, send GAS (ANQP) request on channel freq %d\n", chan
->center_freq
);
2813 r
= slsi_mlme_send_frame_mgmt(sdev
, dev
, buf
, len
, FAPI_DATAUNITDESCRIPTOR_IEEE802_11_FRAME
, FAPI_MESSAGETYPE_IEEE80211_ACTION
, host_tag
, SLSI_FREQ_HOST_TO_FW(chan
->center_freq
), wait
* 1000, 0);
2819 slsi_assign_cookie_id(cookie
, &ndev_vif
->mgmt_tx_cookie
);
2820 slsi_set_mgmt_tx_data(ndev_vif
, *cookie
, host_tag
, buf
, len
);
2824 slsi_wlan_unsync_vif_deactivate(sdev
, dev
, true);
2828 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
2829 int slsi_mgmt_tx(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
2830 struct cfg80211_mgmt_tx_params
*params
,
2833 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2834 int slsi_mgmt_tx(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
2835 struct ieee80211_channel
*chan
, bool offchan
,
2836 unsigned int wait
, const u8
*buf
, size_t len
, bool no_cck
, bool dont_wait_for_ack
, u64
*cookie
)
2838 struct net_device
*dev
= wdev
->netdev
;
2841 int slsi_mgmt_tx(struct wiphy
*wiphy
, struct net_device
*dev
,
2842 struct ieee80211_channel
*chan
, bool offchan
,
2843 enum nl80211_channel_type channel_type
,
2844 bool channel_type_valid
, unsigned int wait
,
2845 const u8
*buf
, size_t len
, bool no_cck
,
2846 bool dont_wait_for_ack
, u64
*cookie
)
2848 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) */
2850 /* Note to explore for AP ::All public action frames which come to host should be handled properly
2851 * Additionally, if PMF is negotiated over the link, the host shall not issue "mlme-send-frame.request"
2852 * primitive for action frames before the pairwise keys have been installed in F/W. Presently, for
2853 * SoftAP with PMF support, there is no scenario in which slsi_mlme_send_frame will be called for
2854 * action frames for VIF TYPE = AP.
2857 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
2858 struct net_device
*dev
= wdev
->netdev
;
2859 struct ieee80211_channel
*chan
= params
->chan
;
2860 bool offchan
= params
->offchan
;
2861 unsigned int wait
= params
->wait
;
2862 const u8
*buf
= params
->buf
;
2863 size_t len
= params
->len
;
2864 bool no_cck
= params
->no_cck
;
2865 bool dont_wait_for_ack
= params
->dont_wait_for_ack
;
2868 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2869 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
2870 const struct ieee80211_mgmt
*mgmt
= (const struct ieee80211_mgmt
*)buf
;
2873 SLSI_UNUSED_PARAMETER(offchan
);
2874 SLSI_UNUSED_PARAMETER(no_cck
);
2875 SLSI_MUTEX_LOCK(sdev
->start_stop_mutex
);
2876 if (sdev
->device_state
!= SLSI_DEVICE_STATE_STARTED
) {
2877 SLSI_WARN(sdev
, "device not started yet (device_state:%d)\n", sdev
->device_state
);
2882 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
2884 if (!(ieee80211_is_auth(mgmt
->frame_control
))) {
2885 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "Mgmt Frame Tx: iface_num = %d, channel = %d, wait = %d, noAck = %d,"
2886 "offchannel = %d, mgmt->frame_control = %d, vif_type = %d\n", ndev_vif
->ifnum
, chan
->hw_value
,
2887 wait
, dont_wait_for_ack
, offchan
, mgmt
->frame_control
, ndev_vif
->vif_type
);
2889 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "Received Auth Frame");
2892 if (!(ieee80211_is_mgmt(mgmt
->frame_control
))) {
2893 SLSI_NET_ERR(dev
, "Drop Tx frame: Not a Management frame\n");
2897 if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif
) || (ndev_vif
->iftype
== NL80211_IFTYPE_AP
&& (ieee80211_is_auth(mgmt
->frame_control
)))) {
2898 r
= slsi_wlan_mgmt_tx(SDEV_FROM_WIPHY(wiphy
), dev
, chan
, wait
, buf
, len
, dont_wait_for_ack
, cookie
);
2904 /* Drop Probe Responses which can come in P2P Device and P2P Group role */
2905 if (ieee80211_is_probe_resp(mgmt
->frame_control
)) {
2906 /* Ideally supplicant doesn't expect Tx status for Probe Rsp. Send tx status just in case it requests ack */
2907 if (!dont_wait_for_ack
) {
2908 slsi_assign_cookie_id(cookie
, &ndev_vif
->mgmt_tx_cookie
);
2909 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2910 cfg80211_mgmt_tx_status(wdev
, *cookie
, buf
, len
, true, GFP_KERNEL
);
2912 cfg80211_mgmt_tx_status(dev
, *cookie
, buf
, len
, true, GFP_KERNEL
);
2918 if (SLSI_IS_VIF_INDEX_P2P(ndev_vif
)) {
2919 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2920 /* Check whether STA scan is running or not. If yes, then abort the STA scan */
2921 slsi_abort_sta_scan(sdev
);
2922 if (SLSI_IS_P2P_GROUP_STATE(sdev
))
2923 r
= slsi_p2p_group_mgmt_tx(mgmt
, wiphy
, dev
, chan
, wait
, buf
, len
, dont_wait_for_ack
, cookie
);
2925 r
= slsi_p2p_mgmt_tx(mgmt
, wiphy
, dev
, ndev_vif
, chan
, wait
, buf
, len
, dont_wait_for_ack
, cookie
);
2926 } else if (SLSI_IS_VIF_INDEX_P2P_GROUP(sdev
, ndev_vif
))
2927 if (chan
->hw_value
== ndev_vif
->chan
->hw_value
) {
2928 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2929 u16 host_tag
= slsi_tx_mgmt_host_tag(sdev
);
2931 r
= slsi_mlme_send_frame_mgmt(sdev
, dev
, buf
, len
, FAPI_DATAUNITDESCRIPTOR_IEEE802_11_FRAME
, FAPI_MESSAGETYPE_IEEE80211_ACTION
, host_tag
, 0, 0, 0);
2933 SLSI_NET_ERR(dev
, "Failed to send action frame, r = %d\n", r
);
2936 slsi_assign_cookie_id(cookie
, &ndev_vif
->mgmt_tx_cookie
);
2937 r
= slsi_set_mgmt_tx_data(ndev_vif
, *cookie
, host_tag
, buf
, len
);
2940 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2941 SLSI_MUTEX_UNLOCK(sdev
->start_stop_mutex
);
2945 /* cw = (2^n -1). But WMM IE needs value n. */
2946 u8
slsi_get_ecw(int cw
)
2958 int slsi_set_txq_params(struct wiphy
*wiphy
, struct net_device
*ndev
,
2959 struct ieee80211_txq_params
*params
)
2961 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2962 struct netdev_vif
*ndev_vif
= netdev_priv(ndev
);
2963 struct slsi_wmm_parameter_element
*wmm_ie
= &ndev_vif
->ap
.wmm_ie
;
2966 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2967 int ac
= params
->ac
;
2969 int ac
= params
->queue
;
2971 /* Index remapping for AC from nl80211_ac enum to slsi_ac_index_wmm enum (index to be used in the IE).
2972 * Kernel version less than 3.5.0 doesn't support nl80211_ac enum hence not using the nl80211_ac enum.
2973 * Eg. NL80211_AC_VO (index value 0) would be remapped to AC_VO (index value 3).
2974 * Don't change the order of array elements.
2976 u8 ac_index_map
[4] = { AC_VO
, AC_VI
, AC_BE
, AC_BK
};
2977 int ac_remapped
= ac_index_map
[ac
];
2979 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
2980 SLSI_NET_DBG2(ndev
, SLSI_CFG80211
, " ac= %x, ac_remapped = %d aifs = %d, cmin=%x cmax = %x, txop = %x,"
2981 "vif_index = %d vif_type = %d", ac
, ac_remapped
, params
->aifs
, params
->cwmin
, params
->cwmax
,
2982 params
->txop
, ndev_vif
->ifnum
, ndev_vif
->vif_type
);
2984 if (ndev_vif
->activated
) {
2985 wmm_ie
->ac
[ac_remapped
].aci_aifsn
= (ac_remapped
<< 5) | (params
->aifs
& 0x0f);
2986 wmm_ie
->ac
[ac_remapped
].ecw
= ((slsi_get_ecw(params
->cwmax
)) << 4) | ((slsi_get_ecw(params
->cwmin
)) & 0x0f);
2987 wmm_ie
->ac
[ac_remapped
].txop_limit
= cpu_to_le16(params
->txop
);
2989 wmm_ie
->eid
= SLSI_WLAN_EID_VENDOR_SPECIFIC
;
2991 wmm_ie
->oui
[0] = 0x00;
2992 wmm_ie
->oui
[1] = 0x50;
2993 wmm_ie
->oui
[2] = 0xf2;
2994 wmm_ie
->oui_type
= WLAN_OUI_TYPE_MICROSOFT_WMM
;
2995 wmm_ie
->oui_subtype
= 1;
2996 wmm_ie
->version
= 1;
2997 wmm_ie
->qos_info
= 0;
2998 wmm_ie
->reserved
= 0;
2999 r
= slsi_mlme_add_info_elements(sdev
, ndev
, FAPI_PURPOSE_LOCAL
, (const u8
*)wmm_ie
, sizeof(struct slsi_wmm_parameter_element
));
3001 SLSI_NET_ERR(ndev
, "Error sending TX Queue Parameters for AP error = %d", r
);
3004 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
3008 #ifdef CONFIG_SCSC_WLAN_SAE_CONFIG
3009 int slsi_synchronised_response(struct wiphy
*wiphy
, struct net_device
*dev
,
3010 struct cfg80211_external_auth_params
*params
)
3012 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
3013 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
3016 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
3017 r
= slsi_mlme_synchronised_response(sdev
, dev
, params
);
3018 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
3023 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
3024 static int slsi_update_ft_ies(struct wiphy
*wiphy
, struct net_device
*dev
, struct cfg80211_update_ft_ies_params
*ftie
)
3026 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
3027 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
3030 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
3032 if (ndev_vif
->vif_type
== FAPI_VIFTYPE_STATION
)
3033 r
= slsi_mlme_add_info_elements(sdev
, dev
, FAPI_PURPOSE_ASSOCIATION_REQUEST
, ftie
->ie
, ftie
->ie_len
);
3035 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
3039 int slsi_set_mac_acl(struct wiphy
*wiphy
, struct net_device
*dev
,
3040 const struct cfg80211_acl_data
*params
)
3042 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
3043 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
3046 if (slsi_is_test_mode_enabled()) {
3047 SLSI_NET_INFO(dev
, "Skip sending signal, WlanLite FW does not support MLME_SET_ACL.request\n");
3050 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
3051 if (FAPI_VIFTYPE_AP
!= ndev_vif
->vif_type
) {
3052 SLSI_NET_ERR(dev
, "Invalid vif type: %d\n", ndev_vif
->vif_type
);
3056 SLSI_NET_DBG2(dev
, SLSI_CFG80211
, "ACL:: Policy: %d Number of stations: %d\n", params
->acl_policy
, params
->n_acl_entries
);
3057 r
= slsi_mlme_set_acl(sdev
, dev
, ndev_vif
->ifnum
, params
);
3059 SLSI_NET_ERR(dev
, "mlme_set_acl_req returned with CFM failure\n");
3061 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
3066 static struct cfg80211_ops slsi_ops
= {
3067 .add_virtual_intf
= slsi_add_virtual_intf
,
3068 .del_virtual_intf
= slsi_del_virtual_intf
,
3069 .change_virtual_intf
= slsi_change_virtual_intf
,
3072 .connect
= slsi_connect
,
3073 .disconnect
= slsi_disconnect
,
3075 .add_key
= slsi_add_key
,
3076 .del_key
= slsi_del_key
,
3077 .get_key
= slsi_get_key
,
3078 .set_default_key
= slsi_set_default_key
,
3079 .set_default_mgmt_key
= slsi_config_default_mgmt_key
,
3081 .set_wiphy_params
= slsi_set_wiphy_params
,
3083 .del_station
= slsi_del_station
,
3084 .get_station
= slsi_get_station
,
3085 .set_tx_power
= slsi_set_tx_power
,
3086 .get_tx_power
= slsi_get_tx_power
,
3087 .set_power_mgmt
= slsi_set_power_mgmt
,
3089 .suspend
= slsi_suspend
,
3090 .resume
= slsi_resume
,
3092 .set_pmksa
= slsi_set_pmksa
,
3093 .del_pmksa
= slsi_del_pmksa
,
3094 .flush_pmksa
= slsi_flush_pmksa
,
3096 .remain_on_channel
= slsi_remain_on_channel
,
3097 .cancel_remain_on_channel
= slsi_cancel_remain_on_channel
,
3099 .change_bss
= slsi_change_bss
,
3100 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 5, 0))
3101 .set_channel
= slsi_set_channel
,
3102 #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 5, 0)) */
3104 .start_ap
= slsi_start_ap
,
3105 .change_beacon
= slsi_change_beacon
,
3106 .stop_ap
= slsi_stop_ap
,
3108 .sched_scan_start
= slsi_sched_scan_start
,
3109 .sched_scan_stop
= slsi_sched_scan_stop
,
3111 .mgmt_frame_register
= slsi_mgmt_frame_register
,
3112 .mgmt_tx
= slsi_mgmt_tx
,
3113 .mgmt_tx_cancel_wait
= slsi_mgmt_tx_cancel_wait
,
3114 .set_txq_params
= slsi_set_txq_params
,
3115 #ifdef CONFIG_SCSC_WLAN_SAE_CONFIG
3116 .external_auth
= slsi_synchronised_response
,
3118 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
3119 .set_mac_acl
= slsi_set_mac_acl
,
3120 .update_ft_ies
= slsi_update_ft_ies
,
3122 .tdls_oper
= slsi_tdls_oper
,
3123 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
3124 #ifdef CONFIG_SCSC_WLAN_DEBUG
3125 .set_monitor_channel
= slsi_set_monitor_channel
,
3127 .set_qos_map
= slsi_set_qos_map
3131 #define RATE_LEGACY(_rate, _hw_value, _flags) { \
3132 .bitrate = (_rate), \
3133 .hw_value = (_hw_value), \
3134 .flags = (_flags), \
3137 #define CHAN2G(_freq, _idx) { \
3138 .band = NL80211_BAND_2GHZ, \
3139 .center_freq = (_freq), \
3140 .hw_value = (_idx), \
3144 #define CHAN5G(_freq, _idx) { \
3145 .band = NL80211_BAND_5GHZ, \
3146 .center_freq = (_freq), \
3147 .hw_value = (_idx), \
3151 static struct ieee80211_channel slsi_2ghz_channels
[] = {
3168 static struct ieee80211_rate slsi_11g_rates
[] = {
3169 RATE_LEGACY(10, 1, 0),
3170 RATE_LEGACY(20, 2, IEEE80211_RATE_SHORT_PREAMBLE
),
3171 RATE_LEGACY(55, 3, IEEE80211_RATE_SHORT_PREAMBLE
),
3172 RATE_LEGACY(110, 6, IEEE80211_RATE_SHORT_PREAMBLE
),
3173 RATE_LEGACY(60, 4, 0),
3174 RATE_LEGACY(90, 5, 0),
3175 RATE_LEGACY(120, 7, 0),
3176 RATE_LEGACY(180, 8, 0),
3177 RATE_LEGACY(240, 9, 0),
3178 RATE_LEGACY(360, 10, 0),
3179 RATE_LEGACY(480, 11, 0),
3180 RATE_LEGACY(540, 12, 0),
3183 static struct ieee80211_channel slsi_5ghz_channels
[] = {
3184 /* _We_ call this UNII 1 */
3215 /* note fw_rate_idx_to_host_11a_idx[] below must change if this table changes */
3217 static struct ieee80211_rate wifi_11a_rates
[] = {
3218 RATE_LEGACY(60, 4, 0),
3219 RATE_LEGACY(90, 5, 0),
3220 RATE_LEGACY(120, 7, 0),
3221 RATE_LEGACY(180, 8, 0),
3222 RATE_LEGACY(240, 9, 0),
3223 RATE_LEGACY(360, 10, 0),
3224 RATE_LEGACY(480, 11, 0),
3225 RATE_LEGACY(540, 12, 0),
3228 static struct ieee80211_sta_ht_cap slsi_ht_cap
= {
3229 .ht_supported
= true,
3230 .cap
= IEEE80211_HT_CAP_SUP_WIDTH_20_40
|
3231 IEEE80211_HT_CAP_LDPC_CODING
|
3232 IEEE80211_HT_CAP_RX_STBC
|
3233 IEEE80211_HT_CAP_GRN_FLD
|
3234 IEEE80211_HT_CAP_SGI_20
|
3235 IEEE80211_HT_CAP_SGI_40
,
3236 .ampdu_factor
= IEEE80211_HT_MAX_AMPDU_64K
,
3237 .ampdu_density
= IEEE80211_HT_MPDU_DENSITY_4
,
3239 .rx_mask
= { 0xff, 0, },
3240 .rx_highest
= cpu_to_le16(0),
3245 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
3246 struct ieee80211_sta_vht_cap slsi_vht_cap
= {
3247 .vht_supported
= true,
3248 .cap
= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991
|
3249 IEEE80211_VHT_CAP_SHORT_GI_80
|
3250 IEEE80211_VHT_CAP_RXSTBC_1
|
3251 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE
|
3252 (5 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT
),
3254 .rx_mcs_map
= cpu_to_le16(0xfffe),
3255 .rx_highest
= cpu_to_le16(0),
3256 .tx_mcs_map
= cpu_to_le16(0xfffe),
3257 .tx_highest
= cpu_to_le16(0),
3262 struct ieee80211_supported_band slsi_band_2ghz
= {
3263 .channels
= slsi_2ghz_channels
,
3264 .band
= NL80211_BAND_2GHZ
,
3265 .n_channels
= ARRAY_SIZE(slsi_2ghz_channels
),
3266 .bitrates
= slsi_11g_rates
,
3267 .n_bitrates
= ARRAY_SIZE(slsi_11g_rates
),
3270 struct ieee80211_supported_band slsi_band_5ghz
= {
3271 .channels
= slsi_5ghz_channels
,
3272 .band
= NL80211_BAND_5GHZ
,
3273 .n_channels
= ARRAY_SIZE(slsi_5ghz_channels
),
3274 .bitrates
= wifi_11a_rates
,
3275 .n_bitrates
= ARRAY_SIZE(wifi_11a_rates
),
3278 static const u32 slsi_cipher_suites
[] = {
3279 WLAN_CIPHER_SUITE_WEP40
,
3280 WLAN_CIPHER_SUITE_WEP104
,
3281 WLAN_CIPHER_SUITE_TKIP
,
3282 WLAN_CIPHER_SUITE_CCMP
,
3283 WLAN_CIPHER_SUITE_AES_CMAC
,
3284 WLAN_CIPHER_SUITE_SMS4
,
3285 WLAN_CIPHER_SUITE_PMK
,
3286 WLAN_CIPHER_SUITE_GCMP
,
3287 WLAN_CIPHER_SUITE_GCMP_256
,
3288 WLAN_CIPHER_SUITE_CCMP_256
,
3289 WLAN_CIPHER_SUITE_BIP_GMAC_128
,
3290 WLAN_CIPHER_SUITE_BIP_GMAC_256
3293 static const struct ieee80211_txrx_stypes
3294 ieee80211_default_mgmt_stypes
[NUM_NL80211_IFTYPES
] = {
3295 [NL80211_IFTYPE_AP
] = {
3297 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
3298 BIT(IEEE80211_STYPE_AUTH
>> 4)
3300 [NL80211_IFTYPE_STATION
] = {
3302 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
3303 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4) |
3304 BIT(IEEE80211_STYPE_AUTH
>> 4)
3306 [NL80211_IFTYPE_P2P_GO
] = {
3308 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
3309 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
3311 [NL80211_IFTYPE_P2P_CLIENT
] = {
3313 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4)
3317 /* Interface combinations supported by driver */
3318 static struct ieee80211_iface_limit iface_limits
[] = {
3319 #ifdef CONFIG_SCSC_WLAN_STA_ONLY
3320 /* Basic STA-only */
3322 .max
= CONFIG_SCSC_WLAN_MAX_INTERFACES
,
3323 .types
= BIT(NL80211_IFTYPE_STATION
),
3326 /* AP mode: # AP <= 1 on channel = 1 */
3329 .types
= BIT(NL80211_IFTYPE_AP
),
3331 /* STA and P2P mode: #STA <= 1, #{P2P-client,P2P-GO} <= 1 on two channels */
3332 /* For P2P, the device mode and group mode is first started as STATION and then changed.
3333 * Similarly it is changed to STATION on group removal. Hence set maximum interfaces for STATION.
3336 .max
= CONFIG_SCSC_WLAN_MAX_INTERFACES
,
3337 .types
= BIT(NL80211_IFTYPE_STATION
),
3341 .types
= BIT(NL80211_IFTYPE_P2P_CLIENT
) | BIT(NL80211_IFTYPE_P2P_GO
),
3343 /* ADHOC mode: #ADHOC <= 1 on channel = 1 */
3346 .types
= BIT(NL80211_IFTYPE_ADHOC
),
3351 static struct ieee80211_regdomain slsi_regdomain
= {
3353 REG_RULE(0, 0, 0, 0, 0, 0),
3354 REG_RULE(0, 0, 0, 0, 0, 0),
3355 REG_RULE(0, 0, 0, 0, 0, 0),
3356 REG_RULE(0, 0, 0, 0, 0, 0),
3357 REG_RULE(0, 0, 0, 0, 0, 0),
3358 REG_RULE(0, 0, 0, 0, 0, 0),
3359 REG_RULE(0, 0, 0, 0, 0, 0),
3360 REG_RULE(0, 0, 0, 0, 0, 0),
3361 REG_RULE(0, 0, 0, 0, 0, 0),
3362 REG_RULE(0, 0, 0, 0, 0, 0),
3363 REG_RULE(0, 0, 0, 0, 0, 0),
3364 REG_RULE(0, 0, 0, 0, 0, 0),
3365 REG_RULE(0, 0, 0, 0, 0, 0),
3366 REG_RULE(0, 0, 0, 0, 0, 0),
3367 REG_RULE(0, 0, 0, 0, 0, 0),
3368 REG_RULE(0, 0, 0, 0, 0, 0),
3369 REG_RULE(0, 0, 0, 0, 0, 0),
3370 REG_RULE(0, 0, 0, 0, 0, 0),
3371 REG_RULE(0, 0, 0, 0, 0, 0),
3372 REG_RULE(0, 0, 0, 0, 0, 0),
3376 static struct ieee80211_iface_combination iface_comb
[] = {
3378 .limits
= iface_limits
,
3379 .n_limits
= ARRAY_SIZE(iface_limits
),
3380 .num_different_channels
= 2,
3381 .max_interfaces
= CONFIG_SCSC_WLAN_MAX_INTERFACES
,
3386 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3387 static struct cfg80211_wowlan slsi_wowlan_config
= {
3393 struct slsi_dev
*slsi_cfg80211_new(struct device
*dev
)
3395 struct wiphy
*wiphy
;
3396 struct slsi_dev
*sdev
= NULL
;
3398 SLSI_DBG1_NODEV(SLSI_CFG80211
, "wiphy_new()\n");
3399 wiphy
= wiphy_new(&slsi_ops
, sizeof(struct slsi_dev
));
3401 SLSI_ERR_NODEV("wiphy_new() failed");
3405 sdev
= (struct slsi_dev
*)wiphy
->priv
;
3407 sdev
->wiphy
= wiphy
;
3409 set_wiphy_dev(wiphy
, dev
);
3411 /* Allow changing of the netns, if NOT set then no changes are allowed */
3412 wiphy
->flags
|= WIPHY_FLAG_NETNS_OK
;
3413 wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
;
3414 wiphy
->flags
|= WIPHY_FLAG_CONTROL_PORT_PROTOCOL
;
3416 /* wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
3418 * Whilst the firmware does support roaming the driver MUST NOT advertise it
3419 * as the supplicant will NOT send the BSSID and frequency information in the
3420 * connect cfg80211 op.
3421 * If the driver advertises FW_ROAM then the supplicant expects it to perform
3422 * any scans required to find an appropriate AP and will only pass the SSID
3425 wiphy
->flags
|= WIPHY_FLAG_HAVE_AP_SME
|
3426 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
|
3427 WIPHY_FLAG_AP_UAPSD
;
3429 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
3430 wiphy
->max_acl_mac_addrs
= SLSI_AP_PEER_CONNECTIONS_MAX
;
3433 wiphy
->privid
= sdev
;
3435 wiphy
->interface_modes
=
3436 #ifdef CONFIG_SCSC_WLAN_STA_ONLY
3437 BIT(NL80211_IFTYPE_STATION
);
3439 BIT(NL80211_IFTYPE_P2P_GO
) |
3440 BIT(NL80211_IFTYPE_P2P_CLIENT
) |
3441 BIT(NL80211_IFTYPE_STATION
) |
3442 BIT(NL80211_IFTYPE_AP
) |
3443 #ifdef CONFIG_SCSC_WLAN_DEBUG
3444 BIT(NL80211_IFTYPE_MONITOR
) |
3446 BIT(NL80211_IFTYPE_ADHOC
);
3448 slsi_band_2ghz
.ht_cap
= slsi_ht_cap
;
3449 slsi_band_5ghz
.ht_cap
= slsi_ht_cap
;
3451 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
3452 slsi_band_5ghz
.vht_cap
= slsi_vht_cap
;
3454 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
3456 wiphy
->bands
[NL80211_BAND_2GHZ
] = &slsi_band_2ghz
;
3457 wiphy
->bands
[NL80211_BAND_5GHZ
] = &slsi_band_5ghz
;
3459 memset(&sdev
->device_config
, 0, sizeof(struct slsi_dev_config
));
3460 sdev
->device_config
.band_5G
= &slsi_band_5ghz
;
3461 sdev
->device_config
.band_2G
= &slsi_band_2ghz
;
3462 sdev
->device_config
.domain_info
.regdomain
= &slsi_regdomain
;
3464 wiphy
->flags
|= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
;
3465 wiphy
->max_remain_on_channel_duration
= 5000; /* 5000 msec */
3467 wiphy
->cipher_suites
= slsi_cipher_suites
;
3468 wiphy
->n_cipher_suites
= ARRAY_SIZE(slsi_cipher_suites
);
3470 wiphy
->mgmt_stypes
= ieee80211_default_mgmt_stypes
;
3472 /* Driver interface combinations */
3473 wiphy
->n_iface_combinations
= ARRAY_SIZE(iface_comb
);
3474 wiphy
->iface_combinations
= iface_comb
;
3476 /* Basic scan parameters */
3477 wiphy
->max_scan_ssids
= 10;
3478 wiphy
->max_scan_ie_len
= 2048;
3480 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 11, 0))
3481 /* Scheduled scanning support */
3482 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
3485 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
3486 /* Parameters for Scheduled Scanning Support */
3487 wiphy
->max_sched_scan_reqs
= 1;
3488 wiphy_ext_feature_set(wiphy
, NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI
);
3491 /* Match the maximum number of SSIDs that could be requested from wpa_supplicant */
3492 wiphy
->max_sched_scan_ssids
= 16;
3494 /* To get a list of SSIDs rather than just the wildcard SSID need to support match sets */
3495 wiphy
->max_match_sets
= 16;
3497 wiphy
->max_sched_scan_ie_len
= 2048;
3500 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3501 wiphy
->wowlan
= NULL
;
3502 wiphy
->wowlan_config
= &slsi_wowlan_config
;
3506 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
3507 wiphy
->regulatory_flags
|= (REGULATORY_STRICT_REG
|
3508 REGULATORY_CUSTOM_REG
|
3509 REGULATORY_DISABLE_BEACON_HINTS
);
3511 #ifndef CONFIG_SCSC_WLAN_STA_ONLY
3513 wiphy
->flags
|= WIPHY_FLAG_OFFCHAN_TX
;
3515 /* Enable Probe response offloading w.r.t WPS and P2P */
3516 wiphy
->probe_resp_offload
|=
3517 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS
|
3518 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2
|
3519 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P
;
3522 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_TDLS
;
3524 /* Mac Randomization */
3525 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
3526 #ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION
3527 wiphy
->features
|= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR
;
3528 wiphy
->features
|= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR
;
3531 #ifdef CONFIG_SCSC_WLAN_SAE_CONFIG
3532 wiphy
->features
|= NL80211_FEATURE_SAE
;
3537 int slsi_cfg80211_register(struct slsi_dev
*sdev
)
3539 SLSI_DBG1(sdev
, SLSI_CFG80211
, "wiphy_register()\n");
3540 return wiphy_register(sdev
->wiphy
);
3543 void slsi_cfg80211_unregister(struct slsi_dev
*sdev
)
3546 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3547 sdev
->wiphy
->wowlan
= NULL
;
3548 sdev
->wiphy
->wowlan_config
= NULL
;
3551 SLSI_DBG1(sdev
, SLSI_CFG80211
, "wiphy_unregister()\n");
3552 wiphy_unregister(sdev
->wiphy
);
3555 void slsi_cfg80211_free(struct slsi_dev
*sdev
)
3557 SLSI_DBG1(sdev
, SLSI_CFG80211
, "wiphy_free()\n");
3558 wiphy_free(sdev
->wiphy
);
3561 void slsi_cfg80211_update_wiphy(struct slsi_dev
*sdev
)
3563 /* update supported Bands */
3564 if (sdev
->band_5g_supported
) {
3565 sdev
->wiphy
->bands
[NL80211_BAND_5GHZ
] = &slsi_band_5ghz
;
3566 sdev
->device_config
.band_5G
= &slsi_band_5ghz
;
3568 sdev
->wiphy
->bands
[NL80211_BAND_5GHZ
] = NULL
;
3569 sdev
->device_config
.band_5G
= NULL
;
3572 /* update HT features */
3573 if (sdev
->fw_ht_enabled
) {
3574 slsi_ht_cap
.ht_supported
= true;
3575 slsi_ht_cap
.cap
= le16_to_cpu(*(u16
*)sdev
->fw_ht_cap
);
3576 slsi_ht_cap
.ampdu_density
= (sdev
->fw_ht_cap
[2] & IEEE80211_HT_AMPDU_PARM_DENSITY
) >> IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT
;
3577 slsi_ht_cap
.ampdu_factor
= sdev
->fw_ht_cap
[2] & IEEE80211_HT_AMPDU_PARM_FACTOR
;
3579 slsi_ht_cap
.ht_supported
= false;
3581 slsi_band_2ghz
.ht_cap
= slsi_ht_cap
;
3582 slsi_band_5ghz
.ht_cap
= slsi_ht_cap
;
3584 /* update VHT features */
3585 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
3586 if (sdev
->fw_vht_enabled
) {
3587 slsi_vht_cap
.vht_supported
= true;
3588 slsi_vht_cap
.cap
= le32_to_cpu(*(u32
*)sdev
->fw_vht_cap
);
3590 slsi_vht_cap
.vht_supported
= false;
3592 slsi_band_5ghz
.vht_cap
= slsi_vht_cap
;
3595 SLSI_INFO(sdev
, "BANDS SUPPORTED -> 2.4:'%c' 5:'%c'\n", sdev
->wiphy
->bands
[NL80211_BAND_2GHZ
] ? 'Y' : 'N',
3596 sdev
->wiphy
->bands
[NL80211_BAND_5GHZ
] ? 'Y' : 'N');
3597 SLSI_INFO(sdev
, "HT/VHT SUPPORTED -> HT:'%c' VHT:'%c'\n", sdev
->fw_ht_enabled
? 'Y' : 'N',
3598 sdev
->fw_vht_enabled
? 'Y' : 'N');
3599 SLSI_INFO(sdev
, "HT -> cap:0x%04x ampdu_density:%d ampdu_factor:%d\n", slsi_ht_cap
.cap
, slsi_ht_cap
.ampdu_density
, slsi_ht_cap
.ampdu_factor
);
3600 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
3601 SLSI_INFO(sdev
, "VHT -> cap:0x%08x\n", slsi_vht_cap
.cap
);