[RAMEN9610-20413][9610] wlbt: SCSC Driver version 10.6.1.0
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / drivers / net / wireless / scsc / cfg80211_ops.c
1 /***************************************************************************
2 *
3 * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
4 *
5 ****************************************************************************/
6
7 #include <linux/version.h>
8 #include <net/cfg80211.h>
9 #include <linux/etherdevice.h>
10 #include "dev.h"
11 #include "cfg80211_ops.h"
12 #include "debug.h"
13 #include "mgt.h"
14 #include "mlme.h"
15 #include "netif.h"
16 #include "unifiio.h"
17 #include "mib.h"
18
19 #ifdef CONFIG_ANDROID
20 #include "scsc_wifilogger_rings.h"
21 #endif
22 #include "nl80211_vendor.h"
23
24 #define SLSI_MAX_CHAN_2G_BAND 14
25
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");
29
30 static bool slsi_is_mhs_active(struct slsi_dev *sdev)
31 {
32 struct net_device *mhs_dev = sdev->netdev_ap;
33 struct netdev_vif *ndev_vif;
34 bool ret;
35
36 if (mhs_dev) {
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);
41 return ret;
42 }
43
44 return 0;
45 }
46
47 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
48 struct wireless_dev *slsi_add_virtual_intf(struct wiphy *wiphy,
49 const char *name,
50 unsigned char name_assign_type,
51 enum nl80211_iftype type,
52 struct vif_params *params)
53 {
54 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
55 struct wireless_dev *slsi_add_virtual_intf(struct wiphy *wiphy,
56 const char *name,
57 unsigned char name_assign_type,
58 enum nl80211_iftype type,
59 u32 *flags,
60 struct vif_params *params)
61 {
62 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
63 struct wireless_dev *slsi_add_virtual_intf(struct wiphy *wiphy,
64 const char *name,
65 enum nl80211_iftype type,
66 u32 *flags,
67 struct vif_params *params)
68 {
69 #else
70 struct net_device *slsi_add_ virtual_intf(struct wiphy *wiphy,
71 char *name,
72 enum nl80211_iftype type,
73 u32 *flags,
74 struct vif_params *params)
75 {
76 #endif
77
78 struct net_device *dev = NULL;
79 struct netdev_vif *ndev_vif = NULL;
80 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
81
82 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 11, 0))
83 SLSI_UNUSED_PARAMETER(flags);
84 #endif
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);
89 }
90 dev = slsi_dynamic_interface_create(wiphy, name, type, params);
91 if (!dev)
92 goto exit_with_error;
93 ndev_vif = netdev_priv(dev);
94
95 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
96 return &ndev_vif->wdev;
97 #else
98 return dev;
99 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) */
100
101 exit_with_error:
102 return ERR_PTR(-ENODEV);
103 }
104
105 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
106 int slsi_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
107 {
108 struct net_device *dev = wdev->netdev;
109
110 #else
111 int slsi_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
112 {
113 #endif
114 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
115
116 if (WARN_ON(!dev))
117 return -EINVAL;
118
119 SLSI_NET_DBG1(dev, SLSI_CFG80211, "Dev name:%s\n", dev->name);
120
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);
129
130 return 0;
131 }
132
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)
138 {
139 #else
140 int slsi_change_virtual_intf(struct wiphy *wiphy,
141 struct net_device *dev,
142 enum nl80211_iftype type,
143 u32 *flags,
144 struct vif_params *params)
145 {
146 #endif
147
148 struct netdev_vif *ndev_vif = netdev_priv(dev);
149 int r = 0;
150
151 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 11, 0))
152 SLSI_UNUSED_PARAMETER(flags);
153 #endif
154
155 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
156
157 SLSI_NET_DBG1(dev, SLSI_CFG80211, "type:%u, iftype:%d\n", type, ndev_vif->iftype);
158
159 if (WARN_ON(ndev_vif->activated)) {
160 r = -EINVAL;
161 goto exit;
162 }
163
164 switch (type) {
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:
173 #endif
174 ndev_vif->iftype = type;
175 dev->ieee80211_ptr->iftype = type;
176 if (params)
177 dev->ieee80211_ptr->use_4addr = params->use_4addr;
178 break;
179 default:
180 r = -EINVAL;
181 break;
182 }
183
184 exit:
185 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
186 return r;
187 }
188
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)
192 {
193 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
194 struct netdev_vif *ndev_vif = netdev_priv(dev);
195 struct slsi_peer *peer = NULL;
196 int r = 0;
197 u16 key_type = FAPI_KEYTYPE_GROUP;
198
199 if (WARN_ON(pairwise && !mac_addr))
200 return -EINVAL;
201
202 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
203
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,
206 ndev_vif->vif_type);
207
208 if (!ndev_vif->activated) {
209 SLSI_NET_DBG1(dev, SLSI_CFG80211, "vif not active\n");
210 goto exit;
211 }
212
213 if (params->cipher == WLAN_CIPHER_SUITE_PMK) {
214 r = slsi_mlme_set_pmk(sdev, dev, params->key, params->key_len);
215 goto exit;
216 }
217
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);
221 if (peer)
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);
226 if (peer)
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;
231 else {
232 r = -EINVAL;
233 goto exit;
234 }
235
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 };
241
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);
248 } else {
249 SLSI_NET_ERR(dev, "Error adding WEP key\n");
250 }
251 goto exit;
252 }
253
254 if (pairwise) {
255 key_type = FAPI_KEYTYPE_PAIRWISE;
256 if (WARN_ON(!peer)) {
257 r = -EINVAL;
258 goto exit;
259 }
260 } else if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
261 key_type = FAPI_KEYTYPE_IGTK;
262 }
263
264 if (WARN(!mac_addr, "mac_addr not defined\n")) {
265 r = -EINVAL;
266 goto exit;
267 }
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);
270 if (r) {
271 SLSI_NET_ERR(dev, "error in adding key (key_type: %d)\n", key_type);
272 goto exit;
273 }
274 }
275
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);
281 }
282
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) {
287 if (peer)
288 peer->pairwise_key_set = true;
289 }
290
291 if (peer) {
292 if (ndev_vif->vif_type == FAPI_VIFTYPE_STATION) {
293 if (pairwise) {
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);
298 }
299 }
300
301 if (ndev_vif->sta.gratuitous_arp_needed) {
302 ndev_vif->sta.gratuitous_arp_needed = false;
303 slsi_send_gratuitous_arp(sdev, dev);
304 }
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;
311 }
312 }
313
314 exit:
315 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
316 return r;
317 }
318
319 int slsi_del_key(struct wiphy *wiphy, struct net_device *dev,
320 u8 key_index, bool pairwise, const u8 *mac_addr)
321 {
322 SLSI_UNUSED_PARAMETER(wiphy);
323 SLSI_UNUSED_PARAMETER(key_index);
324 SLSI_UNUSED_PARAMETER(pairwise);
325 SLSI_UNUSED_PARAMETER(mac_addr);
326
327 if (slsi_is_test_mode_enabled()) {
328 SLSI_NET_INFO(dev, "Skip sending signal, WlanLite FW does not support MLME_DELETEKEYS.request\n");
329 return -EOPNOTSUPP;
330 }
331
332 return 0;
333 }
334
335 int slsi_get_key(struct wiphy *wiphy, struct net_device *dev,
336 u8 key_index, bool pairwise, const u8 *mac_addr,
337 void *cookie,
338 void (*callback)(void *cookie, struct key_params *))
339 {
340 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
341 struct netdev_vif *ndev_vif = netdev_priv(dev);
342 struct key_params params;
343
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 };
346 int r = 0;
347
348 SLSI_UNUSED_PARAMETER(mac_addr);
349
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");
352 return -EOPNOTSUPP;
353 }
354
355 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
356
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);
359
360 if (!ndev_vif->activated) {
361 SLSI_NET_ERR(dev, "vif not active\n");
362 r = -EINVAL;
363 goto exit;
364 }
365
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);
369 r = -EINVAL;
370 goto exit;
371 }
372 if (pairwise) {
373 SLSI_NET_ERR(dev, "Invalid key type\n");
374 r = -EINVAL;
375 goto exit;
376 }
377
378 memset(&params, 0, sizeof(params));
379 /* Update params with sequence number, key field would be updated NULL */
380 params.key = NULL;
381 params.key_len = 0;
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, &params.seq_len);
385
386 if (!r) {
387 params.seq = key_seq;
388 callback(cookie, &params);
389 }
390 }
391 #undef SLSI_MAX_KEY_SIZE
392 exit:
393 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
394 return r;
395 }
396
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)
398 {
399 const u8 *ie;
400 const u8 *next_ie;
401 size_t dest_ie_len = 0;
402
403 if (!dest_ie || !(strip_p2p || strip_wsc))
404 return dest_ie_len;
405
406 for (ie = src_ie; (ie - src_ie) < src_ie_len; ie = next_ie) {
407 next_ie = ie + ie[1] + 2;
408
409 if (ie[0] == WLAN_EID_VENDOR_SPECIFIC && ie[1] > 4) {
410 int i;
411 unsigned int oui = 0;
412
413 for (i = 0; i < 4; i++)
414 oui = (oui << 8) | ie[5 - i];
415
416 if (strip_wsc && (oui == SLSI_WPS_OUI_PATTERN))
417 continue;
418 if (strip_p2p && (oui == SLSI_P2P_OUI_PATTERN))
419 continue;
420 }
421
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;
425 }
426 }
427
428 return dest_ie_len;
429 }
430
431 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
432 int slsi_scan(struct wiphy *wiphy,
433 struct cfg80211_scan_request *request)
434 {
435 struct net_device *dev = request->wdev->netdev;
436
437 #else
438 int slsi_scan(struct wiphy *wiphy, struct net_device *dev,
439 struct cfg80211_scan_request *request)
440 {
441 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) */
442
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;
446 int r = 0;
447 u8 *scan_ie;
448 size_t scan_ie_len;
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};
456 #endif
457
458 if (WARN_ON(!request->wdev))
459 return -EINVAL;
460 if (WARN_ON(!dev))
461 return -EINVAL;
462
463 if (slsi_is_test_mode_enabled()) {
464 SLSI_NET_WARN(dev, "not supported in WlanLite mode\n");
465 return -EOPNOTSUPP;
466 }
467
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");
471 return -EBUSY;
472 }
473
474 SLSI_MUTEX_LOCK(ndev_vif->scan_mutex);
475
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");
478 r = -EBUSY;
479 goto exit;
480 }
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)) {
484 int ret = 0;
485
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);
488
489 if (!ret) {
490 ret = slsi_send_forward_beacon_abort_vendor_event(sdev,
491 SLSI_FORWARD_BEACON_ABORT_REASON_SCANNING);
492 }
493 }
494 #endif
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);
497
498 for (i = 0; i < request->n_channels; i++)
499 channels[i] = request->channels[i];
500 chan_count = request->n_channels;
501
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;
506 }
507 ndev_vif->unsync.slsi_p2p_continuous_fullscan = false;
508 }
509
510 /* Update scan timing for P2P social channels scan.*/
511 if ((request->ie) &&
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
517 */
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;
523 }
524 }
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;
532 } else {
533 int count = 0, chann = 0;
534
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];
541 count++;
542 }
543 }
544 chan_count = count;
545 }
546 }
547 }
548
549 if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif) && (request->ie)) {
550 const u8 *ie;
551
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);
554 if (r)
555 goto exit;
556
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
560 */
561
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)
565 strip_wsc = true;
566
567 ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P, request->ie, request->ie_len);
568 if (ie)
569 strip_p2p = true;
570 }
571
572 if (strip_wsc || strip_p2p) {
573 scan_ie = kmalloc(request->ie_len, GFP_KERNEL);
574 if (!scan_ie) {
575 SLSI_NET_INFO(dev, "Out of memory for scan IEs\n");
576 r = -ENOMEM;
577 goto exit;
578 }
579 scan_ie_len = slsi_strip_wsc_p2p_ie(request->ie, request->ie_len, scan_ie, strip_wsc, strip_p2p);
580 } else {
581 scan_ie = (u8 *)request->ie;
582 scan_ie_len = request->ie_len;
583 }
584
585 /* Flush out any outstanding single scan timeout work */
586 cancel_delayed_work(&ndev_vif->scan_timeout_work);
587
588 ndev_vif->scan[SLSI_SCAN_HW_ID].is_blocking_scan = false;
589 slsi_purge_scan_results(ndev_vif, SLSI_SCAN_HW_ID);
590
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);
597 if (!r)
598 sdev->scan_addr_set = 1;
599 } else {
600 SLSI_NET_INFO(dev, "Mac Randomization is not enabled in Firmware\n");
601 sdev->scan_addr_set = 0;
602 }
603 } else
604 #endif
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;
609 }
610 #endif
611
612 r = slsi_mlme_add_scan(sdev,
613 dev,
614 scan_type,
615 FAPI_REPORTMODE_REAL_TIME,
616 request->n_ssids,
617 request->ssids,
618 chan_count,
619 channels,
620 NULL,
621 scan_ie,
622 scan_ie_len,
623 ndev_vif->scan[SLSI_SCAN_HW_ID].is_blocking_scan);
624
625 if (r != 0) {
626 if (r > 0) {
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);
630 #else
631 cfg80211_scan_done(request, false);
632 #endif
633 r = 0;
634 } else {
635 SLSI_NET_DBG2(dev, SLSI_CFG80211, "add_scan error: %d\n", r);
636 r = -EIO;
637 }
638 } else {
639 ndev_vif->scan[SLSI_SCAN_HW_ID].scan_req = request;
640
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
643 */
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;
647 else
648 ndev_vif->scan[SLSI_SCAN_HW_ID].requeue_timeout_work = true;
649
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;
659 else {
660 ndev_vif->probe_req_ie_len = scan_ie_len;
661 memcpy(ndev_vif->probe_req_ies, scan_ie, scan_ie_len);
662 }
663 }
664 }
665 if (strip_p2p || strip_wsc)
666 kfree(scan_ie);
667
668 exit:
669 SLSI_MUTEX_UNLOCK(ndev_vif->scan_mutex);
670 return r;
671 }
672
673 int slsi_sched_scan_start(struct wiphy *wiphy,
674 struct net_device *dev,
675 struct cfg80211_sched_scan_request *request)
676 {
677 struct netdev_vif *ndev_vif = netdev_priv(dev);
678 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
679 int r;
680 u8 *scan_ie;
681 size_t scan_ie_len;
682 bool strip_wsc = false;
683 bool strip_p2p = false;
684
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");
687 return -EOPNOTSUPP;
688 }
689
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.
692 */
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);
695 return -EINVAL;
696 }
697
698 /* Unlikely to get a schedule scan while Group formation is in progress.
699 * In case it is requested, it will be rejected.
700 */
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");
703 return -EBUSY;
704 }
705
706 SLSI_MUTEX_LOCK(ndev_vif->scan_mutex);
707
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);
710
711 if (ndev_vif->scan[SLSI_SCAN_HW_ID].sched_req) {
712 r = -EBUSY;
713 goto exit;
714 }
715
716 if (request->ie) {
717 const u8 *ie;
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
721 */
722
723 ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, WLAN_OUI_TYPE_MICROSOFT_WPS, request->ie, request->ie_len);
724 if (ie)
725 strip_wsc = true;
726
727 ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P, request->ie, request->ie_len);
728 if (ie)
729 strip_p2p = true;
730 }
731
732 if (strip_wsc || strip_p2p) {
733 scan_ie = kmalloc(request->ie_len, GFP_KERNEL);
734 if (!scan_ie) {
735 SLSI_NET_INFO(dev, "Out of memory for scan IEs\n");
736 r = -ENOMEM;
737 goto exit;
738 }
739 scan_ie_len = slsi_strip_wsc_p2p_ie(request->ie, request->ie_len, scan_ie, strip_wsc, strip_p2p);
740 } else {
741 scan_ie = (u8 *)request->ie;
742 scan_ie_len = request->ie_len;
743 }
744
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);
747
748 if (strip_p2p || strip_wsc)
749 kfree(scan_ie);
750
751 if (r != 0) {
752 if (r > 0) {
753 SLSI_NET_DBG2(dev, SLSI_CFG80211, "Nothing to be done\n");
754 cfg80211_sched_scan_stopped(wiphy, request->reqid);
755 r = 0;
756 } else {
757 SLSI_NET_DBG2(dev, SLSI_CFG80211, "add_scan error: %d\n", r);
758 r = -EIO;
759 }
760 } else {
761 ndev_vif->scan[SLSI_SCAN_SCHED_ID].sched_req = request;
762 }
763
764 exit:
765 SLSI_MUTEX_UNLOCK(ndev_vif->scan_mutex);
766 return r;
767 }
768
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)
771 {
772 #else
773 int slsi_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev)
774 {
775 #endif
776 struct netdev_vif *ndev_vif = netdev_priv(dev);
777 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
778 int r = 0;
779
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");
785 goto exit;
786 }
787
788 r = slsi_mlme_del_scan(sdev, dev, (ndev_vif->ifnum << 8 | SLSI_SCAN_SCHED_ID), false);
789
790 ndev_vif->scan[SLSI_SCAN_SCHED_ID].sched_req = NULL;
791
792 exit:
793 SLSI_MUTEX_UNLOCK(ndev_vif->scan_mutex);
794 return r;
795 }
796
797 static void slsi_abort_hw_scan(struct slsi_dev *sdev, struct net_device *dev)
798 {
799 struct netdev_vif *ndev_vif = netdev_priv(dev);
800
801 SLSI_MUTEX_LOCK(ndev_vif->scan_mutex);
802
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);
806
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);
810 }
811 SLSI_MUTEX_UNLOCK(ndev_vif->scan_mutex);
812 }
813
814 int slsi_connect(struct wiphy *wiphy, struct net_device *dev,
815 struct cfg80211_connect_params *sme)
816 {
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 };
821 int r = 0;
822 u16 capability = WLAN_CAPABILITY_ESS;
823 struct slsi_peer *peer;
824 u16 prev_vif_type;
825 u32 action_frame_bmap;
826 struct net_device *p2p_dev;
827 const u8 *bssid;
828 struct ieee80211_channel *channel;
829 const u8 *connected_ssid = NULL;
830 u8 peer_address[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
831 u16 center_freq = 0;
832
833 if (slsi_is_test_mode_enabled()) {
834 SLSI_NET_INFO(dev, "Skip sending signal, WlanLite FW does not support MLME_CONNECT.request\n");
835 return -EOPNOTSUPP;
836 }
837 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
838 capability = sme->privacy ? IEEE80211_PRIVACY_ON : IEEE80211_PRIVACY_OFF;
839 #else
840 if (sme->privacy)
841 capability |= WLAN_CAPABILITY_PRIVACY;
842 #endif
843
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);
848 return -EINVAL;
849 }
850
851 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
852
853 if (ndev_vif->sta.sta_bss)
854 SLSI_ETHER_COPY(peer_address, ndev_vif->sta.sta_bss->bssid);
855
856 center_freq = sme->channel ? sme->channel->center_freq : 0;
857
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);
861
862 #ifdef CONFIG_SCSC_WIFILOGGER
863 SCSC_WLOG_PKTFATE_NEW_ASSOC();
864 if (sme->bssid) {
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), &center_freq);
869 // ?? WIFI_TAG_VENDOR_SPECIFIC, sizeof(RSSE), RSSE);
870 }
871 #endif
872
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;
878 }
879
880 if (WARN_ON(!sme->ssid))
881 goto exit_with_error;
882
883 if (WARN_ON(sme->ssid_len > IEEE80211_MAX_SSID_LEN))
884 goto exit_with_error;
885
886 if (sme->bssid) {
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);
889 if (p2p_dev) {
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;
895 }
896 }
897 }
898 }
899 }
900
901 if ((ndev_vif->vif_type == FAPI_VIFTYPE_STATION) && (ndev_vif->sta.vif_status == SLSI_VIF_STATUS_CONNECTED)) {
902 /*reassociation*/
903 peer = slsi_get_peer_from_qs(sdev, dev, SLSI_STA_PEER_QUEUESET);
904 if (WARN_ON(!peer))
905 goto exit_with_error;
906
907 if (!sme->bssid) {
908 SLSI_NET_ERR(dev, "Require bssid in reassoc but received null\n");
909 goto exit_with_error;
910 }
911 if (!memcmp(peer->address, sme->bssid, ETH_ALEN)) { /*same bssid*/
912 r = slsi_mlme_reassociate(sdev, dev);
913 if (r) {
914 SLSI_NET_ERR(dev, "Failed to reassociate : %d\n", r);
915 } else {
916 ndev_vif->sta.vif_status = SLSI_VIF_STATUS_CONNECTING;
917 slsi_ps_port_control(sdev, dev, peer, SLSI_STA_CONN_STATE_DISCONNECTED);
918 }
919 goto exit;
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);
922
923 if (!connected_ssid) {
924 SLSI_NET_ERR(dev, "Require ssid in roam but received null\n");
925 goto exit_with_error;
926 }
927
928 if (!memcmp(&connected_ssid[2], sme->ssid, connected_ssid[1])) { /*same ssid*/
929 if (!sme->channel) {
930 SLSI_NET_ERR(dev, "Roaming has been rejected, as sme->channel is null\n");
931 goto exit_with_error;
932 }
933 r = slsi_mlme_roam(sdev, dev, sme->bssid, sme->channel->center_freq);
934 if (r) {
935 SLSI_NET_ERR(dev, "Failed to roam : %d\n", r);
936 goto exit_with_error;
937 }
938 goto exit;
939 } else {
940 SLSI_NET_ERR(dev, "Connected but received connect to new ESS, without disconnect");
941 goto exit_with_error;
942 }
943 }
944 }
945 /* Sta started case */
946
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;
952 }
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;
957 }
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;
962 }
963 prev_vif_type = ndev_vif->vif_type;
964
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;
975 #endif
976 break;
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);
980 if (p2p_dev)
981 SLSI_ETHER_COPY(device_address, p2p_dev->dev_addr);
982 action_frame_bmap = SLSI_ACTION_FRAME_PUBLIC;
983 break;
984 default:
985 SLSI_NET_ERR(dev, "Invalid Device Type: %d\n", ndev_vif->iftype);
986 goto exit_with_error;
987 }
988
989 /* Initial Roaming checks done - assign vif type */
990 ndev_vif->vif_type = FAPI_VIFTYPE_STATION;
991
992 channel = sme->channel;
993 bssid = sme->bssid;
994 ndev_vif->sta.sta_bss = cfg80211_get_bss(wiphy,
995 sme->channel,
996 sme->bssid,
997 sme->ssid,
998 sme->ssid_len,
999 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
1000 IEEE80211_BSS_TYPE_ANY,
1001 #else
1002 capability,
1003 #endif
1004 capability);
1005 if (!ndev_vif->sta.sta_bss) {
1006 struct cfg80211_ssid ssid;
1007
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);
1012 if (r) {
1013 SLSI_NET_ERR(dev, "slsi_mlme_connect_scan failed\n");
1014 goto exit;
1015 }
1016 ndev_vif->sta.sta_bss = cfg80211_get_bss(wiphy,
1017 sme->channel,
1018 sme->bssid,
1019 sme->ssid,
1020 sme->ssid_len,
1021 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
1022 IEEE80211_BSS_TYPE_ANY,
1023 #else
1024 capability,
1025 #endif
1026 capability);
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;
1031 r = -ENOENT;
1032 goto exit;
1033 }
1034 channel = ndev_vif->sta.sta_bss->channel;
1035 bssid = ndev_vif->sta.sta_bss->bssid;
1036 } else {
1037 channel = ndev_vif->sta.sta_bss->channel;
1038 bssid = ndev_vif->sta.sta_bss->bssid;
1039 }
1040
1041 ndev_vif->channel_type = NL80211_CHAN_NO_HT;
1042 ndev_vif->chan = channel;
1043
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");
1046 goto exit_with_bss;
1047 }
1048 if (slsi_vif_activated(sdev, dev) != 0) {
1049 SLSI_NET_ERR(dev, "slsi_vif_activated failed\n");
1050 goto exit_with_vif;
1051 }
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);
1054 goto exit_with_vif;
1055 }
1056
1057 r = slsi_set_boost(sdev, dev);
1058 if (r != 0)
1059 SLSI_NET_ERR(dev, "Rssi Boost set failed: %d\n", r);
1060
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
1063 */
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
1069 */
1070 else
1071 /* Retain stored Probe Req at vif deletion until WPA2 connection to allow Probe req */
1072 ndev_vif->delete_probe_req_ies = false;
1073 } else {
1074 ndev_vif->delete_probe_req_ies = true; /* Delete stored Probe Req at vif deletion for STA */
1075 }
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);
1078 }
1079
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.
1084 */
1085 netif_carrier_on(dev);
1086 ndev_vif->sta.vif_status = SLSI_VIF_STATUS_CONNECTING;
1087
1088 #ifdef CONFIG_SCSC_WLAN_SAE_CONFIG
1089 if (sme->auth_type == NL80211_AUTHTYPE_SAE && (sme->flags & CONNECT_REQ_EXTERNAL_AUTH_SUPPORT)) {
1090 const u8 *rsn;
1091
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);
1095 if (rsn) {
1096 int pos;
1097
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]));
1100 }
1101
1102 SLSI_NET_DBG1(dev, SLSI_CFG80211, "RSN IE: : %1d\n", ndev_vif->sta.crypto.akm_suites[0]);
1103 } else {
1104 ndev_vif->sta.crypto.wpa_versions = 0;
1105 }
1106 #endif
1107 r = slsi_mlme_connect(sdev, dev, sme, channel, bssid);
1108 if (r != 0) {
1109 ndev_vif->sta.is_wps = false;
1110 SLSI_NET_ERR(dev, "connect failed: %d\n", r);
1111 netif_carrier_off(dev);
1112 goto exit_with_vif;
1113 }
1114
1115 peer = slsi_peer_add(sdev, dev, (u8 *)bssid, SLSI_STA_PEER_QUEUESET + 1);
1116 ndev_vif->sta.resp_id = 0;
1117
1118 if (!peer)
1119 goto exit_with_error;
1120
1121 goto exit;
1122
1123 exit_with_vif:
1124 slsi_mlme_del_vif(sdev, dev);
1125 slsi_vif_deactivated(sdev, dev);
1126 exit_with_bss:
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;
1130 }
1131 exit_with_error:
1132 r = -EINVAL;
1133 exit:
1134 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1135 SLSI_MUTEX_UNLOCK(sdev->start_stop_mutex);
1136 return r;
1137 }
1138
1139 int slsi_disconnect(struct wiphy *wiphy, struct net_device *dev,
1140 u16 reason_code)
1141 {
1142 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1143 struct netdev_vif *ndev_vif = netdev_priv(dev);
1144 struct slsi_peer *peer;
1145 int r = 0;
1146
1147 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1148
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);
1151
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.
1155 */
1156 if (!ndev_vif->activated) {
1157 r = 0;
1158 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
1159 cfg80211_disconnected(dev, reason_code, NULL, 0, false, GFP_KERNEL);
1160 #else
1161 cfg80211_disconnected(dev, reason_code, NULL, 0, GFP_KERNEL);
1162 #endif
1163 SLSI_NET_INFO(dev, "Vif is already Deactivated\n");
1164 goto exit;
1165 }
1166
1167 peer = ndev_vif->peer_sta_record[SLSI_STA_PEER_QUEUESET];
1168
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);
1173 #endif
1174
1175 switch (ndev_vif->vif_type) {
1176 case FAPI_VIFTYPE_STATION:
1177 {
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.
1182 */
1183 ndev_vif->sta.vif_status = SLSI_VIF_STATUS_DISCONNECTING;
1184
1185 netif_carrier_off(dev);
1186 if (peer->valid)
1187 slsi_ps_port_control(sdev, dev, peer, SLSI_STA_CONN_STATE_DISCONNECTED);
1188
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)
1194 */
1195
1196 r = slsi_mlme_disconnect(sdev, dev, peer->address, reason_code, true);
1197 if (r != 0)
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);
1201
1202 break;
1203 }
1204 default:
1205 SLSI_NET_WARN(dev, "Invalid - vif type:%d, device type:%d)\n", ndev_vif->vif_type, ndev_vif->iftype);
1206 r = -EINVAL;
1207 break;
1208 }
1209
1210 exit:
1211 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1212 return r;
1213 }
1214
1215 int slsi_set_default_key(struct wiphy *wiphy, struct net_device *dev,
1216 u8 key_index, bool unicast, bool multicast)
1217 {
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 */
1224 return 0;
1225 }
1226
1227 int slsi_config_default_mgmt_key(struct wiphy *wiphy,
1228 struct net_device *dev,
1229 u8 key_index)
1230 {
1231 SLSI_UNUSED_PARAMETER(wiphy);
1232 SLSI_UNUSED_PARAMETER(key_index);
1233 SLSI_UNUSED_PARAMETER(dev);
1234
1235 return 0;
1236 }
1237
1238 int slsi_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1239 {
1240 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1241 int r = 0;
1242
1243 SLSI_DBG1(sdev, SLSI_CFG80211, "slsi_set_wiphy_parms Frag Threshold = %d, RTS Threshold = %d",
1244 wiphy->frag_threshold, wiphy->rts_threshold);
1245
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);
1248 if (r != 0) {
1249 SLSI_ERR(sdev, "Setting FRAG_THRESHOLD failed\n");
1250 return r;
1251 }
1252 }
1253
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);
1256 if (r != 0) {
1257 SLSI_ERR(sdev, "Setting RTS_THRESHOLD failed\n");
1258 return r;
1259 }
1260 }
1261
1262 return r;
1263 }
1264
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)
1268 #else
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)) */
1272 {
1273 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1274 int r = 0;
1275
1276 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1277 SLSI_UNUSED_PARAMETER(wdev);
1278 SLSI_UNUSED_PARAMETER(type);
1279 #endif
1280 SLSI_UNUSED_PARAMETER(mbm);
1281 SLSI_UNUSED_PARAMETER(sdev);
1282
1283 r = -EOPNOTSUPP;
1284
1285 return r;
1286 }
1287
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)
1290 #else
1291 int slsi_get_tx_power(struct wiphy *wiphy, int *dbm)
1292 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) */
1293 {
1294 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1295 int r = 0;
1296
1297 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1298 SLSI_UNUSED_PARAMETER(wdev);
1299 #endif
1300 SLSI_UNUSED_PARAMETER(dbm);
1301 SLSI_UNUSED_PARAMETER(sdev);
1302
1303 r = -EOPNOTSUPP;
1304
1305 return r;
1306 }
1307
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,
1313 const u8 *mac)
1314 #else
1315 int slsi_del_station(struct wiphy *wiphy, struct net_device *dev,
1316 u8 *mac)
1317 #endif
1318 {
1319 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1320 struct netdev_vif *ndev_vif = netdev_priv(dev);
1321 struct slsi_peer *peer;
1322 int r = 0;
1323
1324 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
1325 const u8 *mac = del_params->mac;
1326 #endif
1327
1328 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1329
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);
1332
1333 /* Function is called by cfg80211 before the VIF is added */
1334 if (!ndev_vif->activated)
1335 goto exit;
1336
1337 if (FAPI_VIFTYPE_AP != ndev_vif->vif_type) {
1338 r = -EINVAL;
1339 goto exit;
1340 }
1341 /* MAC with NULL value will come in case of flushing VLANS . Ignore this.*/
1342 if (!mac) {
1343 goto exit;
1344 } else if (is_broadcast_ether_addr(mac)) {
1345 int i = 0;
1346
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);
1351 }
1352 ++i;
1353 }
1354
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
1358 */
1359
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);
1363
1364 netif_carrier_off(dev);
1365
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);
1370
1371 if (ndev_vif->ap.p2p_gc_keys_set) {
1372 slsi_wakeunlock(&sdev->wlan_wl);
1373 ndev_vif->ap.p2p_gc_keys_set = false;
1374 }
1375 } else {
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");
1380 goto exit;
1381 }
1382 if (peer->is_wps) {
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");
1385 goto exit;
1386 }
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);
1389 if (r != 0)
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);
1393 }
1394 }
1395
1396 exit:
1397 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1398 return r;
1399 }
1400
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)
1404 #else
1405 int slsi_get_station(struct wiphy *wiphy, struct net_device *dev,
1406 u8 *mac, struct station_info *sinfo)
1407 #endif
1408 {
1409 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1410 struct netdev_vif *ndev_vif = netdev_priv(dev);
1411 struct slsi_peer *peer;
1412 int r = 0;
1413
1414 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1415
1416 if (!ndev_vif->activated) {
1417 r = -EINVAL;
1418 goto exit;
1419 }
1420
1421 peer = slsi_get_peer_from_mac(sdev, dev, mac);
1422 if (!peer) {
1423 SLSI_NET_DBG1(dev, SLSI_CFG80211, "%pM : Not Found\n", mac);
1424 r = -EINVAL;
1425 goto exit;
1426 }
1427
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);
1432 if (r) {
1433 SLSI_NET_DBG1(dev, SLSI_CFG80211, "failed to read Station Info Error:%d\n", r);
1434 goto exit;
1435 }
1436 }
1437
1438 *sinfo = peer->sinfo;
1439 sinfo->generation = ndev_vif->cfg80211_sinfo_generation;
1440
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",
1443 mac,
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);
1450 #else
1451 SLSI_NET_DBG1(dev, SLSI_CFG80211, "%pM, tx:%d, txbytes:%d, rx:%d, rxbytes:%d tx_fail:%d tx_retry:%d\n",
1452 mac,
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);
1459 #endif
1460
1461 exit:
1462 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1463 return r;
1464 }
1465
1466 int slsi_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1467 bool enabled, int timeout)
1468 {
1469 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1470 struct netdev_vif *ndev_vif = netdev_priv(dev);
1471 int r = -EINVAL;
1472 u16 pwr_mode = enabled ? FAPI_POWERMANAGEMENTMODE_POWER_SAVE : FAPI_POWERMANAGEMENTMODE_ACTIVE_MODE;
1473
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");
1477 return -EOPNOTSUPP;
1478 }
1479
1480 if (slsi_is_rf_test_mode_enabled()) {
1481 SLSI_NET_INFO(dev, "Skip sending signal, RF test does not support.\n");
1482 return -EOPNOTSUPP;
1483 }
1484
1485 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1486
1487 SLSI_NET_DBG3(dev, SLSI_CFG80211, "enabled:%d, vif_type:%d, vif_index:%d\n", enabled, ndev_vif->vif_type,
1488 ndev_vif->ifnum);
1489
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);
1493 } else {
1494 r = 0;
1495 }
1496
1497 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1498 return r;
1499 }
1500
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)
1503 #else
1504 int slsi_tdls_oper(struct wiphy *wiphy, struct net_device *dev, u8 *peer, enum nl80211_tdls_operation oper)
1505 #endif
1506 {
1507 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1508 struct netdev_vif *ndev_vif = netdev_priv(dev);
1509 int r = 0;
1510
1511 SLSI_NET_DBG3(dev, SLSI_CFG80211, "oper:%d, vif_type:%d, vif_index:%d\n", oper, ndev_vif->vif_type,
1512 ndev_vif->ifnum);
1513
1514 if (!(wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS))
1515 return -ENOTSUPP;
1516
1517 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1518
1519 if ((!ndev_vif->activated) || SLSI_IS_VIF_INDEX_P2P_GROUP(sdev, ndev_vif) ||
1520 (ndev_vif->sta.vif_status != SLSI_VIF_STATUS_CONNECTED)) {
1521 r = -ENOTSUPP;
1522 goto exit;
1523 }
1524
1525 switch (oper) {
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);
1529 break;
1530 case NL80211_TDLS_SETUP:
1531 r = slsi_mlme_tdls_action(sdev, dev, peer, FAPI_TDLSACTION_SETUP, 0, 0);
1532 break;
1533 case NL80211_TDLS_TEARDOWN:
1534 r = slsi_mlme_tdls_action(sdev, dev, peer, FAPI_TDLSACTION_TEARDOWN, 0, 0);
1535 break;
1536 default:
1537 r = -EOPNOTSUPP;
1538 goto exit;
1539 }
1540 exit:
1541 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1542 return r;
1543 }
1544
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)
1547 {
1548 struct netdev_vif *ndev_vif = netdev_priv(dev);
1549 struct slsi_peer *peer;
1550 int r = 0;
1551
1552 /* Cleaning up is inherently taken care by driver */
1553 if (!qos_map)
1554 return r;
1555
1556 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1557
1558 if (!ndev_vif->activated) {
1559 r = -EINVAL;
1560 goto exit;
1561 }
1562
1563 if (ndev_vif->vif_type != FAPI_VIFTYPE_STATION) {
1564 r = -EINVAL;
1565 goto exit;
1566 }
1567
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) {
1571 r = -EINVAL;
1572 goto exit;
1573 }
1574
1575 memcpy(&peer->qos_map, qos_map, sizeof(struct cfg80211_qos_map));
1576 peer->qos_map_set = true;
1577
1578 exit:
1579 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1580 return r;
1581 }
1582
1583 #ifdef CONFIG_SCSC_WLAN_DEBUG
1584 int slsi_set_monitor_channel(struct wiphy *wiphy, struct cfg80211_chan_def *chandef)
1585 {
1586 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1587 struct net_device *dev;
1588 struct netdev_vif *ndev_vif;
1589
1590 SLSI_DBG1(sdev, SLSI_CFG80211, "channel (freq:%u)\n", chandef->chan->center_freq);
1591
1592 rcu_read_lock();
1593 dev = slsi_get_netdev_rcu(sdev, SLSI_NET_INDEX_WLAN);
1594 if (!dev) {
1595 SLSI_ERR(sdev, "netdev No longer exists\n");
1596 rcu_read_unlock();
1597 return -EINVAL;
1598 }
1599 ndev_vif = netdev_priv(dev);
1600 rcu_read_unlock();
1601
1602 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1603
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);
1607 return -EINVAL;
1608 }
1609 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1610 return 0;
1611 }
1612 #endif
1613 #endif
1614 int slsi_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow)
1615 {
1616 SLSI_UNUSED_PARAMETER(wow);
1617
1618 return 0;
1619 }
1620
1621 int slsi_resume(struct wiphy *wiphy)
1622 {
1623 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1624
1625 /* Scheduling the IO thread */
1626 /* (void)slsi_hip_run_bh(sdev); */
1627 SLSI_UNUSED_PARAMETER(sdev);
1628
1629 return 0;
1630 }
1631
1632 int slsi_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
1633 struct cfg80211_pmksa *pmksa)
1634 {
1635 SLSI_UNUSED_PARAMETER(wiphy);
1636 SLSI_UNUSED_PARAMETER(dev);
1637 SLSI_UNUSED_PARAMETER(pmksa);
1638 return 0;
1639 }
1640
1641 int slsi_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
1642 struct cfg80211_pmksa *pmksa)
1643 {
1644 SLSI_UNUSED_PARAMETER(wiphy);
1645 SLSI_UNUSED_PARAMETER(dev);
1646 SLSI_UNUSED_PARAMETER(pmksa);
1647 return 0;
1648 }
1649
1650 int slsi_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
1651 {
1652 SLSI_UNUSED_PARAMETER(wiphy);
1653 SLSI_UNUSED_PARAMETER(dev);
1654 return 0;
1655 }
1656
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,
1662 u64 *cookie)
1663 {
1664 struct net_device *dev = wdev->netdev;
1665
1666 #else
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,
1672 u64 *cookie)
1673 {
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);
1677 int r = 0;
1678
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;
1683 }
1684
1685 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1686
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;
1693 }
1694
1695 if (SLSI_IS_P2P_GROUP_STATE(sdev)) {
1696 slsi_assign_cookie_id(cookie, &ndev_vif->unsync.roc_cookie);
1697
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);
1701 #else
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);
1704 #endif
1705 goto exit;
1706 }
1707
1708 /* Unsync vif will be required, cancel any pending work of its deletion */
1709 cancel_delayed_work(&ndev_vif->unsync.del_vif_work);
1710
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.
1714 */
1715 cancel_delayed_work(&ndev_vif->unsync.roc_expiry_work);
1716
1717 if (delayed_work_pending(&ndev_vif->unsync.unset_channel_expiry_work))
1718 cancel_delayed_work(&ndev_vif->unsync.unset_channel_expiry_work);
1719
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.
1722 */
1723 if ((sdev->p2p_state == P2P_ACTION_FRAME_TX_RX) || (sdev->p2p_state == P2P_LISTENING)) {
1724 goto exit_with_roc;
1725 }
1726
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;
1735
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");
1738 goto exit_with_vif;
1739 }
1740 ndev_vif->unsync.ies_changed = false;
1741 }
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");
1746 goto exit_with_vif;
1747 } else {
1748 ndev_vif->chan = chan;
1749 ndev_vif->driver_channel = chan->hw_value;
1750 }
1751 }
1752 } else {
1753 SLSI_NET_ERR(dev, "Driver in incorrect P2P state (%s)", slsi_p2p_state_text(sdev->p2p_state));
1754 goto exit_with_error;
1755 }
1756
1757 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 9))
1758 ndev_vif->channel_type = channel_type;
1759 #endif
1760
1761 SLSI_P2P_STATE_CHANGE(sdev, P2P_LISTENING);
1762
1763 exit_with_roc:
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
1768 */
1769 queue_delayed_work(sdev->device_wq, &ndev_vif->unsync.roc_expiry_work,
1770 msecs_to_jiffies(duration - SLSI_P2P_ROC_EXTRA_MSEC));
1771
1772 slsi_assign_cookie_id(cookie, &ndev_vif->unsync.roc_cookie);
1773 SLSI_NET_DBG2(dev, SLSI_CFG80211, "Cookie = 0x%llx\n", *cookie);
1774
1775 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1776 cfg80211_ready_on_channel(wdev, *cookie, chan, duration, GFP_KERNEL);
1777 #else
1778 cfg80211_ready_on_channel(dev, *cookie, chan, channel_type, duration, GFP_KERNEL);
1779 #endif
1780
1781 goto exit;
1782
1783 exit_with_vif:
1784 slsi_p2p_vif_deactivate(sdev, dev, true);
1785 exit_with_error:
1786 r = -EINVAL;
1787 exit:
1788 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1789 SLSI_MUTEX_UNLOCK(sdev->start_stop_mutex);
1790 return r;
1791 }
1792
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,
1796 u64 cookie)
1797 {
1798 struct net_device *dev = wdev->netdev;
1799
1800 #else
1801 int slsi_cancel_remain_on_channel(struct wiphy *wiphy,
1802 struct net_device *dev,
1803 u64 cookie)
1804 {
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);
1808 int r = 0;
1809
1810 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1811
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);
1816
1817 if (!SLSI_IS_VIF_INDEX_P2P(ndev_vif)) {
1818 SLSI_NET_ERR(dev, "Invalid vif type\n");
1819 r = -EINVAL;
1820 goto exit;
1821 }
1822
1823 if (!((sdev->p2p_state == P2P_LISTENING) || (sdev->p2p_state == P2P_ACTION_FRAME_TX_RX))) {
1824 goto exit;
1825 }
1826
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;
1831 }
1832
1833 cancel_delayed_work(&ndev_vif->unsync.roc_expiry_work);
1834
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);
1837 #else
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);
1840 #endif
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));
1846 }
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);
1850
1851 exit:
1852 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1853 return r;
1854 }
1855
1856 int slsi_change_bss(struct wiphy *wiphy, struct net_device *dev,
1857 struct bss_parameters *params)
1858 {
1859 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1860 int r = 0;
1861
1862 SLSI_UNUSED_PARAMETER(params);
1863 SLSI_UNUSED_PARAMETER(sdev);
1864
1865 return r;
1866 }
1867
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)
1872 {
1873 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1874 struct netdev_vif *ndev_vif = netdev_priv(dev);
1875 int r = 0;
1876
1877 SLSI_UNUSED_PARAMETER(sdev);
1878 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1879
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)) {
1883 r = -EINVAL;
1884 goto exit;
1885 }
1886
1887 ndev_vif->channel_type = channel_type;
1888 ndev_vif->chan = chan;
1889
1890 exit:
1891 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1892 return r;
1893 }
1894 #endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(3, 5, 0)) */
1895
1896 static void slsi_ap_start_obss_scan(struct slsi_dev *sdev, struct net_device *dev, struct netdev_vif *ndev_vif)
1897 {
1898 struct cfg80211_ssid ssids;
1899 struct ieee80211_channel *channel;
1900 int n_ssids = 1, n_channels = 1, i;
1901
1902 SLSI_NET_DBG1(dev, SLSI_CFG80211, "channel %u\n", ndev_vif->chan->hw_value);
1903
1904 SLSI_MUTEX_LOCK(ndev_vif->scan_mutex);
1905
1906 ssids.ssid_len = 0;
1907 for (i = 0; i < IEEE80211_MAX_SSID_LEN; i++)
1908 ssids.ssid[i] = 0x00; /* Broadcast SSID */
1909
1910 channel = ieee80211_get_channel(sdev->wiphy, ndev_vif->chan->center_freq);
1911
1912 ndev_vif->scan[SLSI_SCAN_HW_ID].is_blocking_scan = true;
1913 (void)slsi_mlme_add_scan(sdev,
1914 dev,
1915 FAPI_SCANTYPE_OBSS_SCAN,
1916 FAPI_REPORTMODE_REAL_TIME,
1917 n_ssids,
1918 &ssids,
1919 n_channels,
1920 &channel,
1921 NULL,
1922 NULL, /* No IEs */
1923 0,
1924 ndev_vif->scan[SLSI_SCAN_HW_ID].is_blocking_scan /* Wait for scan_done_ind */);
1925
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);
1929 }
1930
1931 static int slsi_ap_start_validate(struct net_device *dev, struct slsi_dev *sdev, struct cfg80211_ap_settings *settings)
1932 {
1933 struct netdev_vif *ndev_vif = netdev_priv(dev);
1934
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;
1938 }
1939
1940 if (!settings->ssid_len || !settings->ssid) {
1941 SLSI_NET_ERR(dev, "SSID not provided\n");
1942 goto exit_with_error;
1943 }
1944
1945 if (!settings->beacon.head_len || !settings->beacon.head) {
1946 SLSI_NET_ERR(dev, "Beacon not provided\n");
1947 goto exit_with_error;
1948 }
1949
1950 if (!settings->beacon_interval) {
1951 SLSI_NET_ERR(dev, "Beacon Interval not provided\n");
1952 goto exit_with_error;
1953 }
1954
1955 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1956 ndev_vif->chandef = &settings->chandef;
1957 ndev_vif->chan = ndev_vif->chandef->chan;
1958 #endif
1959 if (WARN_ON(!ndev_vif->chan))
1960 goto exit_with_error;
1961
1962 if (WARN_ON(ndev_vif->activated))
1963 goto exit_with_error;
1964
1965 if (WARN_ON((ndev_vif->iftype != NL80211_IFTYPE_AP) && (ndev_vif->iftype != NL80211_IFTYPE_P2P_GO)))
1966 goto exit_with_error;
1967
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;
1973 }
1974 #else
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;
1979 }
1980 #endif
1981
1982 return 0;
1983
1984 exit_with_error:
1985 return -EINVAL;
1986 }
1987
1988 static int slsi_get_max_bw_mhz(struct slsi_dev *sdev, u16 prim_chan_cf)
1989 {
1990 int i;
1991 struct ieee80211_regdomain *regd = sdev->device_config.domain_info.regdomain;
1992
1993 if (!regd) {
1994 SLSI_WARN(sdev, "NO regdomain info\n");
1995 return 0;
1996 }
1997
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;
2002 }
2003
2004 SLSI_WARN(sdev, "Freq(%d) not found in regdomain\n", prim_chan_cf);
2005 return 0;
2006 }
2007
2008 void slsi_store_settings_for_recovery(struct cfg80211_ap_settings *settings, struct netdev_vif *ndev_vif)
2009 {
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);
2019
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);
2026
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));
2032 }
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));
2036 }
2037
2038 }
2039
2040 int slsi_start_ap(struct wiphy *wiphy, struct net_device *dev,
2041 struct cfg80211_ap_settings *settings)
2042 {
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 };
2047 int r = 0;
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;
2055 const u8 *ie;
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;
2060 #endif
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;
2068 int i;
2069 u32 chan_flags;
2070 u16 center_freq;
2071
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);
2075 r = -EINVAL;
2076 goto exit_with_start_stop_mutex;
2077 }
2078
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);
2082 if (wlan_dev)
2083 slsi_abort_hw_scan(sdev, wlan_dev);
2084
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)) {
2091 if (ndev_sta_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);
2102 r = -EINVAL;
2103 goto exit_with_vif_mutex;
2104 }
2105 }
2106 SLSI_MUTEX_UNLOCK(ndev_sta_vif->vif_mutex);
2107 }
2108 }
2109 #endif
2110
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);*/
2114
2115 /* Reg domain changes */
2116 country_ie = cfg80211_find_ie(WLAN_EID_COUNTRY, settings->beacon.tail, settings->beacon.tail_len);
2117 if (country_ie) {
2118 country_ie += 2;
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) {
2122 r = -EINVAL;
2123 goto exit_with_vif_mutex;
2124 }
2125 }
2126 }
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);
2130 if (!channel) {
2131 SLSI_ERR(sdev, "Invalid frequency %d used to start AP. Channel not found\n",
2132 settings->chandef.chan->center_freq);
2133 r = -EINVAL;
2134 goto exit_with_vif_mutex;
2135 }
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
2142 #else
2143 IEEE80211_CHAN_NO_IR
2144 #endif
2145 );
2146
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",
2153 center_freq,
2154 wiphy->bands[NL80211_BAND_5GHZ]->channels[i].flags);
2155 indoor_channel = 1;
2156 break;
2157 }
2158 }
2159 if (indoor_channel == 0) {
2160 SLSI_ERR(sdev, "No valid channel found to start the AP");
2161 r = -EINVAL;
2162 goto exit_with_vif_mutex;
2163 }
2164 }
2165 }
2166 }
2167
2168 r = slsi_ap_start_validate(dev, sdev, settings);
2169 if (r != 0)
2170 goto exit_with_vif_mutex;
2171
2172 if (ndev_vif->iftype == NL80211_IFTYPE_P2P_GO) {
2173 struct net_device *p2p_dev;
2174
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");
2182 r = -EINVAL;
2183 goto exit_with_vif_mutex;
2184 }
2185 }
2186
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;
2197
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,
2208 NL80211_BAND_5GHZ);
2209 else if ((oper_chan >= 100) && (oper_chan <= 112))
2210 ndev_vif->chandef->center_freq1 = ieee80211_channel_to_frequency(106,
2211 NL80211_BAND_5GHZ);
2212 else if ((oper_chan >= 116) && (oper_chan <= 128))
2213 ndev_vif->chandef->center_freq1 = ieee80211_channel_to_frequency(122,
2214 NL80211_BAND_5GHZ);
2215 else if ((oper_chan >= 132) && (oper_chan <= 144))
2216 ndev_vif->chandef->center_freq1 = ieee80211_channel_to_frequency(138,
2217 NL80211_BAND_5GHZ);
2218 }
2219 #endif
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 };
2230 #endif
2231 u8 ch;
2232
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;
2238 break;
2239 }
2240
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;
2246 break;
2247 }
2248 }
2249 #endif
2250 }
2251 #endif
2252
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) {
2256 #else
2257 if (slsi_check_channelization(sdev, ndev_vif->chandef, 0) != 0) {
2258 #endif
2259 #else
2260 if (slsi_check_channelization(sdev, ndev_vif->channel_type) != 0) {
2261 #endif
2262 r = -EINVAL;
2263 goto exit_with_vif_mutex;
2264 }
2265
2266 if (ndev_vif->iftype == NL80211_IFTYPE_AP) {
2267 /* Legacy AP */
2268 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
2269 if (ndev_vif->chandef->width == NL80211_CHAN_WIDTH_20)
2270 #else
2271 if (ndev_vif->channel_type == NL80211_CHAN_HT20)
2272 #endif
2273 slsi_ap_start_obss_scan(sdev, dev, ndev_vif);
2274 }
2275
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);
2283
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);
2288 }
2289 } else if (cfg80211_chandef_valid(ndev_vif->chandef)) {
2290 u8 *ht_operation_ie;
2291 u8 sec_chan_offset = 0;
2292 u8 ch;
2293 u8 bw_40_minus_channels[] = { 40, 48, 153, 161, 5, 6, 7, 8, 9, 10, 11 };
2294
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");
2299 r = -EINVAL;
2300 goto exit_with_vif_mutex;
2301 }
2302
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;
2307 break;
2308 }
2309
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;
2314
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.
2317 */
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);
2325
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);
2330 }
2331 }
2332 #endif
2333
2334 if (indoor_channel == 1
2335 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
2336 || (wifi_sharing_channel_switched == 1)
2337 #endif
2338 ) {
2339 slsi_modify_ies_on_channel_switch(dev, settings, ds_params_ie, ht_operation_ie, mgmt, beacon_ie_head_len);
2340 }
2341 ndev_vif->vif_type = FAPI_VIFTYPE_AP;
2342
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");
2345 r = -EINVAL;
2346 goto exit_with_vif_mutex;
2347 }
2348
2349 if (slsi_vif_activated(sdev, dev) != 0) {
2350 SLSI_NET_ERR(dev, "slsi_vif_activated failed\n");
2351 goto exit_with_vif;
2352 }
2353
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
2356 */
2357 wpa_ie_pos = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, WLAN_OUI_TYPE_MICROSOFT_WPA, settings->beacon.tail, settings->beacon.tail_len);
2358 if (wpa_ie_pos) {
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);
2362 }
2363
2364 wmm_ie_pos = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, WLAN_OUI_TYPE_MICROSOFT_WMM, settings->beacon.tail, settings->beacon.tail_len);
2365 if (wmm_ie_pos) {
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);
2369 }
2370
2371 slsi_clear_cached_ies(&ndev_vif->ap.add_info_ies, &ndev_vif->ap.add_info_ies_len);
2372
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.
2377 */
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);
2383 }
2384
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);
2390 }
2391
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);
2397 }
2398
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;
2402
2403 r = slsi_mlme_register_action_frame(sdev, dev, af_bmap_active, af_bmap_suspended);
2404 if (r != 0) {
2405 SLSI_NET_ERR(dev, "slsi_mlme_register_action_frame failed: resultcode = %d\n", r);
2406 goto exit_with_vif;
2407 }
2408 }
2409
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;
2415 } else {
2416 ie = cfg80211_find_ie(WLAN_EID_SUPP_RATES, settings->beacon.tail, settings->beacon.tail_len);
2417 if (ie)
2418 ndev_vif->ap.mode = slsi_get_supported_mode(ie);
2419 }
2420
2421 r = slsi_mlme_start(sdev, dev, dev->dev_addr, settings, wpa_ie_pos, wmm_ie_pos, append_vht_ies);
2422
2423 if ((indoor_channel == 1)
2424 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
2425 || (wifi_sharing_channel_switched == 1)
2426 #endif
2427 #ifdef CONFIG_SCSC_WLAN_ACS_ENABLE
2428 || (sdev->acs_channel_switched == true)
2429 #endif
2430 )
2431 cfg80211_ch_switch_notify(dev, &settings->chandef);
2432
2433 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
2434 if (r == 0)
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;
2439 #endif
2440 if (r != 0) {
2441 SLSI_NET_ERR(dev, "Start ap failed: resultcode = %d frequency = %d\n", r,
2442 settings->chandef.chan->center_freq);
2443 goto exit_with_vif;
2444 } else if (ndev_vif->iftype == NL80211_IFTYPE_P2P_GO) {
2445 SLSI_P2P_STATE_CHANGE(sdev, P2P_GROUP_FORMED_GO);
2446 }
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*/);
2451 }
2452 #endif
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);
2456
2457 netif_carrier_on(dev);
2458
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);
2462
2463 r = slsi_read_disconnect_ind_timeout(sdev, SLSI_PSID_UNIFI_DISCONNECT_TIMEOUT);
2464 if (r != 0)
2465 sdev->device_config.ap_disconnect_ind_timeout = *sdev->sig_wait_cfm_timeout;
2466
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;
2469 exit_with_vif:
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);
2473 r = -EINVAL;
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);
2478
2479 #ifdef CONFIG_SCSC_WLAN_SILENT_RECOVERY
2480 slsi_store_settings_for_recovery(settings, ndev_vif);
2481 #endif
2482 return r;
2483 }
2484
2485 int slsi_change_beacon(struct wiphy *wiphy, struct net_device *dev,
2486 struct cfg80211_beacon_data *info)
2487 {
2488 SLSI_UNUSED_PARAMETER(info);
2489
2490 return -EOPNOTSUPP;
2491 }
2492
2493 int slsi_stop_ap(struct wiphy *wiphy, struct net_device *dev)
2494 {
2495 slsi_reset_throughput_stats(dev);
2496
2497 return 0;
2498 }
2499
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)
2504 {
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);
2509 int r = 0;
2510 u32 host_tag = slsi_tx_mgmt_host_tag(sdev);
2511 u16 freq = 0;
2512 u32 dwell_time = SLSI_FORCE_SCHD_ACT_FRAME_MSEC;
2513 u16 data_unit_desc = FAPI_DATAUNITDESCRIPTOR_IEEE802_11_FRAME;
2514
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);
2517 return -EINVAL;
2518 }
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);
2527
2528 if (!((ndev_vif->iftype == NL80211_IFTYPE_P2P_GO) || (ndev_vif->iftype == NL80211_IFTYPE_P2P_CLIENT)))
2529 goto exit_with_error;
2530
2531 if (chan->hw_value != ndev_vif->chan->hw_value) {
2532 freq = SLSI_FREQ_HOST_TO_FW(chan->center_freq);
2533 dwell_time = wait;
2534 }
2535
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);
2539
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);
2541 if (r)
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;
2546
2547 exit_with_error:
2548 r = -EINVAL;
2549 exit_with_lock:
2550 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
2551 return r;
2552 }
2553
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)
2559 {
2560 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
2561 int ret = 0;
2562
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);
2566 u8 exp_peer_frame;
2567 u32 dwell_time = 0;
2568
2569 SLSI_NET_DBG2(dev, SLSI_CFG80211, "Action frame (%s), unsync_vif_active (%d)\n", slsi_p2p_pa_subtype_text(subtype), ndev_vif->activated);
2570
2571 if (subtype == SLSI_P2P_PA_INVALID) {
2572 SLSI_NET_ERR(dev, "Invalid Action frame subtype\n");
2573 goto exit_with_error;
2574 }
2575
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;
2580
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);
2586
2587 if (slsi_mlme_set_channel(sdev, dev, chan, SLSI_FW_CHANNEL_DURATION_UNSPECIFIED, 0, 0) != 0)
2588 goto exit_with_vif;
2589 else {
2590 ndev_vif->chan = chan;
2591 ndev_vif->driver_channel = chan->hw_value;
2592 }
2593 }
2594
2595 /* Check if peer frame response is expected */
2596 exp_peer_frame = slsi_p2p_get_exp_peer_frame_subtype(subtype);
2597
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;
2602 } else {
2603 SLSI_NET_DBG1(dev, SLSI_CFG80211, "Peer response expected with action frame (%s)\n",
2604 slsi_p2p_pa_subtype_text(exp_peer_frame));
2605
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);
2608
2609 /* Change Force Schedule Duration as peer response is expected */
2610 if (wait)
2611 dwell_time = wait;
2612 else
2613 dwell_time = SLSI_FORCE_SCHD_ACT_FRAME_MSEC;
2614 }
2615 }
2616
2617 slsi_assign_cookie_id(cookie, &ndev_vif->mgmt_tx_cookie);
2618
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)
2621 goto exit_with_vif;
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;
2629
2630 SLSI_NET_DBG1(dev, SLSI_CFG80211, "Store mgmt frame tx data for cookie = 0x%llx\n", *cookie);
2631
2632 ret = slsi_set_mgmt_tx_data(ndev_vif, *cookie, host_tag, buf, len);
2633 if (ret != 0)
2634 goto exit_with_vif;
2635 ndev_vif->mgmt_tx_data.exp_frame = exp_peer_frame;
2636
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
2642 */
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;
2647 if (n_wait) {
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);
2650 }
2651 } else {
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.
2654 */
2655 WARN_ON(sdev->p2p_state != P2P_ACTION_FRAME_TX_RX);
2656
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);
2661 #else
2662 cfg80211_mgmt_tx_status(dev, *cookie, buf, len, true, GFP_KERNEL);
2663 #endif
2664 }
2665 }
2666 goto exit;
2667 }
2668
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;
2672
2673 exit_with_vif:
2674 if (sdev->p2p_state != P2P_LISTENING)
2675 slsi_p2p_vif_deactivate(sdev, dev, true);
2676 exit_with_error:
2677 ret = -EINVAL;
2678 exit:
2679 return ret;
2680 }
2681
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,
2685 u64 cookie)
2686 {
2687 struct net_device *dev = wdev->netdev;
2688
2689 #else
2690 int slsi_mgmt_tx_cancel_wait(struct wiphy *wiphy,
2691 struct net_device *dev,
2692 u64 cookie)
2693 {
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);
2697
2698 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
2699
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);
2705
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);
2710
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;
2713
2714 if (delayed_work_pending(&ndev_vif->unsync.roc_expiry_work)) {
2715 SLSI_P2P_STATE_CHANGE(sdev, P2P_LISTENING);
2716 } else {
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);
2719 }
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));
2727 }
2728
2729 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
2730 return 0;
2731 }
2732
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)
2737 {
2738 struct net_device *dev = wdev->netdev;
2739
2740 #else
2741 void slsi_mgmt_frame_register(struct wiphy *wiphy,
2742 struct net_device *dev,
2743 u16 frame_type, bool reg)
2744 {
2745 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) */
2746 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
2747
2748 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
2749 SLSI_UNUSED_PARAMETER(frame_type);
2750 SLSI_UNUSED_PARAMETER(reg);
2751 #endif
2752
2753 if (WARN_ON(!dev))
2754 return;
2755
2756 SLSI_UNUSED_PARAMETER(sdev);
2757 }
2758
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)
2762 {
2763 u32 host_tag = slsi_tx_mgmt_host_tag(sdev);
2764 struct netdev_vif *ndev_vif = netdev_priv(dev);
2765 int r = 0;
2766 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
2767
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);
2772 if (r)
2773 return r;
2774
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);
2776 if (r)
2777 goto exit_with_vif;
2778
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));
2781 } else {
2782 /* vif is active*/
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);
2787 if (r)
2788 return r;
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);
2794 if (r)
2795 goto exit_with_vif;
2796 else {
2797 ndev_vif->driver_channel = chan->hw_value;
2798 }
2799 }
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);
2802 if (r)
2803 goto exit_with_vif;
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);
2809 if (r)
2810 return r;
2811 } else {
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);
2814 if (r)
2815 return r;
2816 }
2817 }
2818
2819 slsi_assign_cookie_id(cookie, &ndev_vif->mgmt_tx_cookie);
2820 slsi_set_mgmt_tx_data(ndev_vif, *cookie, host_tag, buf, len);
2821 return r;
2822
2823 exit_with_vif:
2824 slsi_wlan_unsync_vif_deactivate(sdev, dev, true);
2825 return r;
2826 }
2827
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,
2831 u64 *cookie)
2832 {
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)
2837 {
2838 struct net_device *dev = wdev->netdev;
2839
2840 #else
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)
2847 {
2848 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) */
2849
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.
2855 */
2856
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;
2866 #endif
2867
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;
2871 int r = 0;
2872
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);
2878 r = -EINVAL;
2879 goto exit;
2880 }
2881
2882 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
2883
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);
2888 } else {
2889 SLSI_NET_DBG2(dev, SLSI_CFG80211, "Received Auth Frame");
2890 }
2891
2892 if (!(ieee80211_is_mgmt(mgmt->frame_control))) {
2893 SLSI_NET_ERR(dev, "Drop Tx frame: Not a Management frame\n");
2894 r = -EINVAL;
2895 goto exit;
2896 }
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);
2899 goto exit;
2900 }
2901
2902 /*P2P*/
2903
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);
2911 #else
2912 cfg80211_mgmt_tx_status(dev, *cookie, buf, len, true, GFP_KERNEL);
2913 #endif
2914 }
2915 goto exit;
2916 }
2917
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);
2924 else
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);
2930
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);
2932 if (r) {
2933 SLSI_NET_ERR(dev, "Failed to send action frame, r = %d\n", r);
2934 goto exit;
2935 }
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);
2938 }
2939 exit:
2940 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
2941 SLSI_MUTEX_UNLOCK(sdev->start_stop_mutex);
2942 return r;
2943 }
2944
2945 /* cw = (2^n -1). But WMM IE needs value n. */
2946 u8 slsi_get_ecw(int cw)
2947 {
2948 int ecw = 0;
2949
2950 cw = cw + 1;
2951 do {
2952 cw = cw >> 1;
2953 ecw++;
2954 } while (cw);
2955 return ecw - 1;
2956 }
2957
2958 int slsi_set_txq_params(struct wiphy *wiphy, struct net_device *ndev,
2959 struct ieee80211_txq_params *params)
2960 {
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;
2964 int r = 0;
2965
2966 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2967 int ac = params->ac;
2968 #else
2969 int ac = params->queue;
2970 #endif
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.
2975 */
2976 u8 ac_index_map[4] = { AC_VO, AC_VI, AC_BE, AC_BK };
2977 int ac_remapped = ac_index_map[ac];
2978
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);
2983
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);
2988 if (ac == 3) {
2989 wmm_ie->eid = SLSI_WLAN_EID_VENDOR_SPECIFIC;
2990 wmm_ie->len = 24;
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));
3000 if (r)
3001 SLSI_NET_ERR(ndev, "Error sending TX Queue Parameters for AP error = %d", r);
3002 }
3003 }
3004 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
3005 return r;
3006 }
3007
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)
3011 {
3012 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
3013 struct netdev_vif *ndev_vif = netdev_priv(dev);
3014 int r;
3015
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);
3019 return r;
3020 }
3021 #endif
3022
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)
3025 {
3026 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
3027 struct netdev_vif *ndev_vif = netdev_priv(dev);
3028 int r = 0;
3029
3030 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
3031
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);
3034
3035 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
3036 return r;
3037 }
3038
3039 int slsi_set_mac_acl(struct wiphy *wiphy, struct net_device *dev,
3040 const struct cfg80211_acl_data *params)
3041 {
3042 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
3043 struct netdev_vif *ndev_vif = netdev_priv(dev);
3044 int r = 0;
3045
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");
3048 return -EOPNOTSUPP;
3049 }
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);
3053 r = -EINVAL;
3054 goto exit;
3055 }
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);
3058 if (r != 0)
3059 SLSI_NET_ERR(dev, "mlme_set_acl_req returned with CFM failure\n");
3060 exit:
3061 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
3062 return r;
3063 }
3064 #endif
3065
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,
3070
3071 .scan = slsi_scan,
3072 .connect = slsi_connect,
3073 .disconnect = slsi_disconnect,
3074
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,
3080
3081 .set_wiphy_params = slsi_set_wiphy_params,
3082
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,
3088
3089 .suspend = slsi_suspend,
3090 .resume = slsi_resume,
3091
3092 .set_pmksa = slsi_set_pmksa,
3093 .del_pmksa = slsi_del_pmksa,
3094 .flush_pmksa = slsi_flush_pmksa,
3095
3096 .remain_on_channel = slsi_remain_on_channel,
3097 .cancel_remain_on_channel = slsi_cancel_remain_on_channel,
3098
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)) */
3103
3104 .start_ap = slsi_start_ap,
3105 .change_beacon = slsi_change_beacon,
3106 .stop_ap = slsi_stop_ap,
3107
3108 .sched_scan_start = slsi_sched_scan_start,
3109 .sched_scan_stop = slsi_sched_scan_stop,
3110
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,
3117 #endif
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,
3121 #endif
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,
3126 #endif
3127 .set_qos_map = slsi_set_qos_map
3128 #endif
3129 };
3130
3131 #define RATE_LEGACY(_rate, _hw_value, _flags) { \
3132 .bitrate = (_rate), \
3133 .hw_value = (_hw_value), \
3134 .flags = (_flags), \
3135 }
3136
3137 #define CHAN2G(_freq, _idx) { \
3138 .band = NL80211_BAND_2GHZ, \
3139 .center_freq = (_freq), \
3140 .hw_value = (_idx), \
3141 .max_power = 17, \
3142 }
3143
3144 #define CHAN5G(_freq, _idx) { \
3145 .band = NL80211_BAND_5GHZ, \
3146 .center_freq = (_freq), \
3147 .hw_value = (_idx), \
3148 .max_power = 17, \
3149 }
3150
3151 static struct ieee80211_channel slsi_2ghz_channels[] = {
3152 CHAN2G(2412, 1),
3153 CHAN2G(2417, 2),
3154 CHAN2G(2422, 3),
3155 CHAN2G(2427, 4),
3156 CHAN2G(2432, 5),
3157 CHAN2G(2437, 6),
3158 CHAN2G(2442, 7),
3159 CHAN2G(2447, 8),
3160 CHAN2G(2452, 9),
3161 CHAN2G(2457, 10),
3162 CHAN2G(2462, 11),
3163 CHAN2G(2467, 12),
3164 CHAN2G(2472, 13),
3165 CHAN2G(2484, 14),
3166 };
3167
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),
3181 };
3182
3183 static struct ieee80211_channel slsi_5ghz_channels[] = {
3184 /* _We_ call this UNII 1 */
3185 CHAN5G(5180, 36),
3186 CHAN5G(5200, 40),
3187 CHAN5G(5220, 44),
3188 CHAN5G(5240, 48),
3189 /* UNII 2 */
3190 CHAN5G(5260, 52),
3191 CHAN5G(5280, 56),
3192 CHAN5G(5300, 60),
3193 CHAN5G(5320, 64),
3194 /* "Middle band" */
3195 CHAN5G(5500, 100),
3196 CHAN5G(5520, 104),
3197 CHAN5G(5540, 108),
3198 CHAN5G(5560, 112),
3199 CHAN5G(5580, 116),
3200 CHAN5G(5600, 120),
3201 CHAN5G(5620, 124),
3202 CHAN5G(5640, 128),
3203 CHAN5G(5660, 132),
3204 CHAN5G(5680, 136),
3205 CHAN5G(5700, 140),
3206 CHAN5G(5720, 144),
3207 /* UNII 3 */
3208 CHAN5G(5745, 149),
3209 CHAN5G(5765, 153),
3210 CHAN5G(5785, 157),
3211 CHAN5G(5805, 161),
3212 CHAN5G(5825, 165),
3213 };
3214
3215 /* note fw_rate_idx_to_host_11a_idx[] below must change if this table changes */
3216
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),
3226 };
3227
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,
3238 .mcs = {
3239 .rx_mask = { 0xff, 0, },
3240 .rx_highest = cpu_to_le16(0),
3241 .tx_params = 0,
3242 },
3243 };
3244
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),
3253 .vht_mcs = {
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),
3258 },
3259 };
3260 #endif
3261
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),
3268 };
3269
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),
3276 };
3277
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
3291 };
3292
3293 static const struct ieee80211_txrx_stypes
3294 ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
3295 [NL80211_IFTYPE_AP] = {
3296 .tx = 0xffff,
3297 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3298 BIT(IEEE80211_STYPE_AUTH >> 4)
3299 },
3300 [NL80211_IFTYPE_STATION] = {
3301 .tx = 0xffff,
3302 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3303 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
3304 BIT(IEEE80211_STYPE_AUTH >> 4)
3305 },
3306 [NL80211_IFTYPE_P2P_GO] = {
3307 .tx = 0xffff,
3308 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3309 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3310 },
3311 [NL80211_IFTYPE_P2P_CLIENT] = {
3312 .tx = 0xffff,
3313 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
3314 },
3315 };
3316
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 */
3321 {
3322 .max = CONFIG_SCSC_WLAN_MAX_INTERFACES,
3323 .types = BIT(NL80211_IFTYPE_STATION),
3324 },
3325 #else
3326 /* AP mode: # AP <= 1 on channel = 1 */
3327 {
3328 .max = 1,
3329 .types = BIT(NL80211_IFTYPE_AP),
3330 },
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.
3334 */
3335 {
3336 .max = CONFIG_SCSC_WLAN_MAX_INTERFACES,
3337 .types = BIT(NL80211_IFTYPE_STATION),
3338 },
3339 {
3340 .max = 1,
3341 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO),
3342 },
3343 /* ADHOC mode: #ADHOC <= 1 on channel = 1 */
3344 {
3345 .max = 1,
3346 .types = BIT(NL80211_IFTYPE_ADHOC),
3347 },
3348 #endif
3349 };
3350
3351 static struct ieee80211_regdomain slsi_regdomain = {
3352 .reg_rules = {
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),
3373 }
3374 };
3375
3376 static struct ieee80211_iface_combination iface_comb[] = {
3377 {
3378 .limits = iface_limits,
3379 .n_limits = ARRAY_SIZE(iface_limits),
3380 .num_different_channels = 2,
3381 .max_interfaces = CONFIG_SCSC_WLAN_MAX_INTERFACES,
3382 },
3383 };
3384
3385 #ifdef CONFIG_PM
3386 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3387 static struct cfg80211_wowlan slsi_wowlan_config = {
3388 .any = true,
3389 };
3390 #endif
3391 #endif
3392
3393 struct slsi_dev *slsi_cfg80211_new(struct device *dev)
3394 {
3395 struct wiphy *wiphy;
3396 struct slsi_dev *sdev = NULL;
3397
3398 SLSI_DBG1_NODEV(SLSI_CFG80211, "wiphy_new()\n");
3399 wiphy = wiphy_new(&slsi_ops, sizeof(struct slsi_dev));
3400 if (!wiphy) {
3401 SLSI_ERR_NODEV("wiphy_new() failed");
3402 return NULL;
3403 }
3404
3405 sdev = (struct slsi_dev *)wiphy->priv;
3406
3407 sdev->wiphy = wiphy;
3408
3409 set_wiphy_dev(wiphy, dev);
3410
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;
3415
3416 /* wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
3417 *
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
3423 */
3424
3425 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
3426 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
3427 WIPHY_FLAG_AP_UAPSD;
3428
3429 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
3430 wiphy->max_acl_mac_addrs = SLSI_AP_PEER_CONNECTIONS_MAX;
3431 #endif
3432
3433 wiphy->privid = sdev;
3434
3435 wiphy->interface_modes =
3436 #ifdef CONFIG_SCSC_WLAN_STA_ONLY
3437 BIT(NL80211_IFTYPE_STATION);
3438 #else
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) |
3445 #endif
3446 BIT(NL80211_IFTYPE_ADHOC);
3447 #endif
3448 slsi_band_2ghz.ht_cap = slsi_ht_cap;
3449 slsi_band_5ghz.ht_cap = slsi_ht_cap;
3450
3451 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
3452 slsi_band_5ghz.vht_cap = slsi_vht_cap;
3453 #endif
3454 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3455
3456 wiphy->bands[NL80211_BAND_2GHZ] = &slsi_band_2ghz;
3457 wiphy->bands[NL80211_BAND_5GHZ] = &slsi_band_5ghz;
3458
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;
3463
3464 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
3465 wiphy->max_remain_on_channel_duration = 5000; /* 5000 msec */
3466
3467 wiphy->cipher_suites = slsi_cipher_suites;
3468 wiphy->n_cipher_suites = ARRAY_SIZE(slsi_cipher_suites);
3469
3470 wiphy->mgmt_stypes = ieee80211_default_mgmt_stypes;
3471
3472 /* Driver interface combinations */
3473 wiphy->n_iface_combinations = ARRAY_SIZE(iface_comb);
3474 wiphy->iface_combinations = iface_comb;
3475
3476 /* Basic scan parameters */
3477 wiphy->max_scan_ssids = 10;
3478 wiphy->max_scan_ie_len = 2048;
3479
3480 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 11, 0))
3481 /* Scheduled scanning support */
3482 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
3483 #endif
3484
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);
3489 #endif
3490
3491 /* Match the maximum number of SSIDs that could be requested from wpa_supplicant */
3492 wiphy->max_sched_scan_ssids = 16;
3493
3494 /* To get a list of SSIDs rather than just the wildcard SSID need to support match sets */
3495 wiphy->max_match_sets = 16;
3496
3497 wiphy->max_sched_scan_ie_len = 2048;
3498
3499 #ifdef CONFIG_PM
3500 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3501 wiphy->wowlan = NULL;
3502 wiphy->wowlan_config = &slsi_wowlan_config;
3503 #endif
3504 #endif
3505
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);
3510 #endif
3511 #ifndef CONFIG_SCSC_WLAN_STA_ONLY
3512 /* P2P flags */
3513 wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX;
3514
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;
3520
3521 /* TDLS support */
3522 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
3523 #endif
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;
3529 #endif
3530 #endif
3531 #ifdef CONFIG_SCSC_WLAN_SAE_CONFIG
3532 wiphy->features |= NL80211_FEATURE_SAE;
3533 #endif
3534 return sdev;
3535 }
3536
3537 int slsi_cfg80211_register(struct slsi_dev *sdev)
3538 {
3539 SLSI_DBG1(sdev, SLSI_CFG80211, "wiphy_register()\n");
3540 return wiphy_register(sdev->wiphy);
3541 }
3542
3543 void slsi_cfg80211_unregister(struct slsi_dev *sdev)
3544 {
3545 #ifdef CONFIG_PM
3546 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3547 sdev->wiphy->wowlan = NULL;
3548 sdev->wiphy->wowlan_config = NULL;
3549 #endif
3550 #endif
3551 SLSI_DBG1(sdev, SLSI_CFG80211, "wiphy_unregister()\n");
3552 wiphy_unregister(sdev->wiphy);
3553 }
3554
3555 void slsi_cfg80211_free(struct slsi_dev *sdev)
3556 {
3557 SLSI_DBG1(sdev, SLSI_CFG80211, "wiphy_free()\n");
3558 wiphy_free(sdev->wiphy);
3559 }
3560
3561 void slsi_cfg80211_update_wiphy(struct slsi_dev *sdev)
3562 {
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;
3567 } else {
3568 sdev->wiphy->bands[NL80211_BAND_5GHZ] = NULL;
3569 sdev->device_config.band_5G = NULL;
3570 }
3571
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;
3578 } else {
3579 slsi_ht_cap.ht_supported = false;
3580 }
3581 slsi_band_2ghz.ht_cap = slsi_ht_cap;
3582 slsi_band_5ghz.ht_cap = slsi_ht_cap;
3583
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);
3589 } else {
3590 slsi_vht_cap.vht_supported = false;
3591 }
3592 slsi_band_5ghz.vht_cap = slsi_vht_cap;
3593 #endif
3594
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);
3602 #endif
3603 }