[9610] wlbt: SCSC Driver version 10.9.1.0
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / drivers / net / wireless / scsc / sap_mlme.c
1 /****************************************************************************
2 *
3 * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
4 *
5 ****************************************************************************/
6 #include <linux/types.h>
7 #include "debug.h"
8 #include "dev.h"
9 #include "sap.h"
10 #include "sap_mlme.h"
11 #include "hip.h"
12 #include "mgt.h"
13
14 #ifdef CONFIG_ANDROID
15 #include "scsc_wifilogger_rings.h"
16 #endif
17 #include "nl80211_vendor.h"
18 #include "mlme.h"
19
20 #define SUPPORTED_OLD_VERSION 0
21
22 static int sap_mlme_version_supported(u16 version);
23 static int sap_mlme_rx_handler(struct slsi_dev *sdev, struct sk_buff *skb);
24
25 static int sap_mlme_notifier(struct slsi_dev *sdev, unsigned long event);
26
27 static struct sap_api sap_mlme = {
28 .sap_class = SAP_MLME,
29 .sap_version_supported = sap_mlme_version_supported,
30 .sap_handler = sap_mlme_rx_handler,
31 .sap_versions = { FAPI_CONTROL_SAP_VERSION, SUPPORTED_OLD_VERSION },
32 .sap_notifier = sap_mlme_notifier,
33 };
34
35 static int sap_mlme_notifier(struct slsi_dev *sdev, unsigned long event)
36 {
37 int i;
38 #ifdef CONFIG_SLSI_WLAN_STA_FWD_BEACON
39 struct net_device *dev;
40 #endif
41 #ifdef CONFIG_SCSC_WLAN_SILENT_RECOVERY
42 bool vif_type_ap = false;
43 int level;
44 #endif
45 struct netdev_vif *ndev_vif;
46
47 SLSI_INFO_NODEV("Notifier event received: %lu\n", event);
48 if (event >= SCSC_MAX_NOTIFIER)
49 return -EIO;
50
51 switch (event) {
52 case SCSC_WIFI_STOP:
53 /* Stop sending signals down*/
54 sdev->mlme_blocked = true;
55 /* cleanup all the VIFs and scan data */
56 SLSI_MUTEX_LOCK(sdev->netdev_add_remove_mutex);
57 #ifdef CONFIG_SCSC_WLAN_SILENT_RECOVERY
58 level = atomic_read(&sdev->cm_if.reset_level);
59 SLSI_INFO_NODEV("MLME BLOCKED system error level:%d\n", level);
60 #endif
61 complete_all(&sdev->sig_wait.completion);
62 /*WLAN system down actions*/
63 for (i = 1; i <= CONFIG_SCSC_WLAN_MAX_INTERFACES; i++)
64 if (sdev->netdev[i]) {
65 ndev_vif = netdev_priv(sdev->netdev[i]);
66 complete_all(&ndev_vif->sig_wait.completion);
67 slsi_scan_cleanup(sdev, sdev->netdev[i]);
68 #ifdef CONFIG_SCSC_WLAN_SILENT_RECOVERY
69 /* For level8 use the older panic flow */
70 if (level < SLSI_WIFI_CM_IF_SYSTEM_ERROR_PANIC && ndev_vif->vif_type == FAPI_VIFTYPE_AP) {
71 vif_type_ap = true;
72 }
73 #endif
74 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
75 slsi_vif_cleanup(sdev, sdev->netdev[i], 0);
76 #ifdef CONFIG_SCSC_WLAN_SILENT_RECOVERY
77 if (level < SLSI_WIFI_CM_IF_SYSTEM_ERROR_PANIC && vif_type_ap)
78 ndev_vif->vif_type = FAPI_VIFTYPE_AP;
79 #endif
80 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
81 }
82 #ifdef CONFIG_SCSC_WLAN_SILENT_RECOVERY
83 if (level < SLSI_WIFI_CM_IF_SYSTEM_ERROR_PANIC)
84 sdev->device_state = SLSI_DEVICE_STATE_STOPPING;
85 if (sdev->netdev_up_count == 0)
86 sdev->mlme_blocked = false;
87 #endif
88 SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex);
89 SLSI_INFO_NODEV("Force cleaned all VIFs\n");
90 break;
91
92 case SCSC_WIFI_FAILURE_RESET:
93 #ifdef CONFIG_SCSC_WLAN_SILENT_RECOVERY
94 level = atomic_read(&sdev->cm_if.reset_level);
95 if (level < SLSI_WIFI_CM_IF_SYSTEM_ERROR_PANIC)
96 queue_work(sdev->device_wq, &sdev->recovery_work_on_stop);
97 #endif
98 break;
99
100 case SCSC_WIFI_SUSPEND:
101 break;
102
103 case SCSC_WIFI_RESUME:
104 #ifdef CONFIG_SLSI_WLAN_STA_FWD_BEACON
105 dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_WLAN);
106 ndev_vif = netdev_priv(dev);
107 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
108
109 if ((ndev_vif->is_wips_running) && (ndev_vif->activated) &&
110 (ndev_vif->vif_type == FAPI_VIFTYPE_STATION) &&
111 (ndev_vif->sta.vif_status == SLSI_VIF_STATUS_CONNECTED)) {
112 ndev_vif->is_wips_running = false;
113
114 slsi_send_forward_beacon_abort_vendor_event(sdev, SLSI_FORWARD_BEACON_ABORT_REASON_SUSPENDED);
115 SLSI_INFO_NODEV("FORWARD_BEACON: SUSPEND_RESUMED!! send abort event\n");
116 }
117
118 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
119 #endif
120 break;
121 #ifdef CONFIG_SCSC_WLAN_SILENT_RECOVERY
122 case SCSC_WIFI_SUBSYSTEM_RESET:
123 /*wlan system down actions*/
124 queue_work(sdev->device_wq, &sdev->recovery_work);
125 break;
126 case SCSC_WIFI_CHIP_READY:
127 level = atomic_read(&sdev->cm_if.reset_level);
128 if (level < SLSI_WIFI_CM_IF_SYSTEM_ERROR_PANIC && sdev->netdev_up_count != 0)
129 queue_work(sdev->device_wq, &sdev->recovery_work_on_start);
130 break;
131 #endif
132 default:
133 SLSI_INFO_NODEV("Unknown event code %lu\n", event);
134 break;
135 }
136
137 return 0;
138 }
139
140 static int sap_mlme_version_supported(u16 version)
141 {
142 unsigned int major = SAP_MAJOR(version);
143 unsigned int minor = SAP_MINOR(version);
144 u8 i = 0;
145
146 SLSI_INFO_NODEV("Reported version: %d.%d\n", major, minor);
147
148 for (i = 0; i < SAP_MAX_VER; i++)
149 if (SAP_MAJOR(sap_mlme.sap_versions[i]) == major)
150 return 0;
151
152 SLSI_ERR_NODEV("Version %d.%d Not supported\n", major, minor);
153
154 return -EINVAL;
155 }
156
157 static int slsi_rx_netdev_mlme(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
158 {
159 u16 id = fapi_get_u16(skb, id);
160
161 /* The skb is consumed by the functions called.
162 */
163 switch (id) {
164 case MLME_SCAN_IND:
165 slsi_rx_scan_ind(sdev, dev, skb);
166 break;
167 case MLME_SCAN_DONE_IND:
168 slsi_rx_scan_done_ind(sdev, dev, skb);
169 break;
170 case MLME_CONNECT_IND:
171 slsi_rx_connect_ind(sdev, dev, skb);
172 break;
173 case MLME_CONNECTED_IND:
174 slsi_rx_connected_ind(sdev, dev, skb);
175 break;
176 case MLME_RECEIVED_FRAME_IND:
177 slsi_rx_received_frame_ind(sdev, dev, skb);
178 break;
179 case MLME_DISCONNECT_IND:
180 slsi_rx_disconnect_ind(sdev, dev, skb);
181 break;
182 case MLME_DISCONNECTED_IND:
183 slsi_rx_disconnected_ind(sdev, dev, skb);
184 break;
185 case MLME_PROCEDURE_STARTED_IND:
186 slsi_rx_procedure_started_ind(sdev, dev, skb);
187 break;
188 case MLME_FRAME_TRANSMISSION_IND:
189 slsi_rx_frame_transmission_ind(sdev, dev, skb);
190 break;
191 case MA_BLOCKACK_IND:
192 slsi_rx_blockack_ind(sdev, dev, skb);
193 break;
194 case MLME_ROAMED_IND:
195 slsi_rx_roamed_ind(sdev, dev, skb);
196 break;
197 case MLME_ROAM_IND:
198 slsi_rx_roam_ind(sdev, dev, skb);
199 break;
200 case MLME_MIC_FAILURE_IND:
201 slsi_rx_mic_failure_ind(sdev, dev, skb);
202 break;
203 case MLME_REASSOCIATE_IND:
204 slsi_rx_reassoc_ind(sdev, dev, skb);
205 break;
206 case MLME_TDLS_PEER_IND:
207 slsi_tdls_peer_ind(sdev, dev, skb);
208 break;
209 case MLME_LISTEN_END_IND:
210 slsi_rx_listen_end_ind(dev, skb);
211 break;
212 case MLME_CHANNEL_SWITCHED_IND:
213 slsi_rx_channel_switched_ind(sdev, dev, skb);
214 break;
215 case MLME_AC_PRIORITY_UPDATE_IND:
216 SLSI_DBG1(sdev, SLSI_MLME, "Unexpected MLME_AC_PRIORITY_UPDATE_IND\n");
217 slsi_kfree_skb(skb);
218 break;
219 #ifdef CONFIG_SCSC_WLAN_GSCAN_ENABLE
220 case MLME_RSSI_REPORT_IND:
221 slsi_rx_rssi_report_ind(sdev, dev, skb);
222 break;
223 case MLME_RANGE_IND:
224 slsi_rx_range_ind(sdev, dev, skb);
225 break;
226 case MLME_RANGE_DONE_IND:
227 slsi_rx_range_done_ind(sdev, dev, skb);
228 break;
229 case MLME_EVENT_LOG_IND:
230 slsi_rx_event_log_indication(sdev, dev, skb);
231 break;
232 #endif
233 #ifdef CONFIG_SCSC_WIFI_NAN_ENABLE
234 case MLME_NAN_EVENT_IND:
235 slsi_nan_event(sdev, dev, skb);
236 break;
237 case MLME_NAN_FOLLOWUP_IND:
238 slsi_nan_followup_ind(sdev, dev, skb);
239 break;
240 case MLME_NAN_SERVICE_IND:
241 slsi_nan_service_ind(sdev, dev, skb);
242 break;
243 case MLME_NDP_REQUEST_IND:
244 slsi_nan_ndp_setup_ind(sdev, dev, skb, true);
245 break;
246 case MLME_NDP_REQUESTED_IND:
247 slsi_nan_ndp_requested_ind(sdev, dev, skb);
248 break;
249 case MLME_NDP_RESPONSE_IND:
250 slsi_nan_ndp_setup_ind(sdev, dev, skb, false);
251 break;
252 case MLME_NDP_TERMINATE_IND:
253 slsi_nan_ndp_termination_ind(sdev, dev, skb, false);
254 break;
255 case MLME_NDP_TERMINATED_IND:
256 slsi_nan_ndp_termination_ind(sdev, dev, skb, true);
257 break;
258 #endif
259 #ifdef CONFIG_SCSC_WLAN_SAE_CONFIG
260 case MLME_SYNCHRONISED_IND:
261 slsi_rx_synchronised_ind(sdev, dev, skb);
262 break;
263 #endif
264 #ifdef CONFIG_SLSI_WLAN_STA_FWD_BEACON
265 case MLME_BEACON_REPORTING_EVENT_IND:
266 slsi_rx_beacon_reporting_event_ind(sdev, dev, skb);
267 break;
268 #endif
269 default:
270 slsi_kfree_skb(skb);
271 SLSI_NET_ERR(dev, "Unhandled Ind: 0x%.4x\n", id);
272 break;
273 }
274 return 0;
275 }
276
277 void slsi_rx_netdev_mlme_work(struct work_struct *work)
278 {
279 struct slsi_skb_work *w = container_of(work, struct slsi_skb_work, work);
280 struct slsi_dev *sdev = w->sdev;
281 struct net_device *dev = w->dev;
282 struct sk_buff *skb = slsi_skb_work_dequeue(w);
283
284 if (WARN_ON(!dev))
285 return;
286
287 slsi_wakelock(&sdev->wlan_wl);
288 while (skb) {
289 slsi_debug_frame(sdev, dev, skb, "RX");
290 slsi_rx_netdev_mlme(sdev, dev, skb);
291 skb = slsi_skb_work_dequeue(w);
292 }
293 slsi_wakeunlock(&sdev->wlan_wl);
294 }
295
296 int slsi_rx_enqueue_netdev_mlme(struct slsi_dev *sdev, struct sk_buff *skb, u16 vif)
297 {
298 struct net_device *dev;
299 struct netdev_vif *ndev_vif;
300
301 rcu_read_lock();
302 dev = slsi_get_netdev_rcu(sdev, vif);
303 if (WARN_ON(!dev)) {
304 rcu_read_unlock();
305 /* Calling function should free the skb */
306 return -ENODEV;
307 }
308
309 ndev_vif = netdev_priv(dev);
310
311 if (unlikely(ndev_vif->is_fw_test)) {
312 slsi_kfree_skb(skb);
313 rcu_read_unlock();
314 return 0;
315 }
316
317 slsi_skb_work_enqueue(&ndev_vif->rx_mlme, skb);
318 rcu_read_unlock();
319 return 0;
320 }
321
322 static int slsi_rx_action_enqueue_netdev_mlme(struct slsi_dev *sdev, struct sk_buff *skb, u16 vif)
323 {
324 struct net_device *dev;
325 struct netdev_vif *ndev_vif;
326
327 rcu_read_lock();
328 dev = slsi_get_netdev_rcu(sdev, vif);
329 if (WARN_ON(!dev)) {
330 rcu_read_unlock();
331 return -ENODEV;
332 }
333
334 ndev_vif = netdev_priv(dev);
335
336 if (unlikely(ndev_vif->is_fw_test)) {
337 rcu_read_unlock();
338 return 0;
339 }
340
341 if (ndev_vif->iftype == NL80211_IFTYPE_P2P_GO || ndev_vif->iftype == NL80211_IFTYPE_P2P_CLIENT) {
342 struct ieee80211_mgmt *mgmt = fapi_get_mgmt(skb);
343 /* Check the DA of received action frame with the GO interface address */
344 if (memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) != 0) {
345 /* If not equal, compare DA of received action frame with the P2P DEV address*/
346 struct net_device *p2pdev = slsi_get_netdev_rcu(sdev, SLSI_NET_INDEX_P2P);
347
348 if (WARN_ON(!p2pdev)) {
349 rcu_read_unlock();
350 return -ENODEV;
351 }
352 if (memcmp(mgmt->da, p2pdev->dev_addr, ETH_ALEN) == 0) {
353 /* If destination address is equal to P2P DEV ADDR, then action frame is received on
354 * GO interface. Hence indicate action frames on P2P DEV
355 */
356 ndev_vif = netdev_priv(p2pdev);
357
358 if (unlikely(ndev_vif->is_fw_test)) {
359 slsi_kfree_skb(skb);
360 rcu_read_unlock();
361 return 0;
362 }
363 }
364 }
365 }
366
367 slsi_skb_work_enqueue(&ndev_vif->rx_mlme, skb);
368
369 rcu_read_unlock();
370 return 0;
371 }
372
373 static int sap_mlme_rx_handler(struct slsi_dev *sdev, struct sk_buff *skb)
374 {
375 u16 scan_id;
376 u16 vif = fapi_get_vif(skb);
377
378 if (slsi_rx_blocking_signals(sdev, skb) == 0)
379 return 0;
380
381 if (fapi_is_ind(skb)) {
382 #ifdef CONFIG_SCSC_WIFILOGGER
383 SCSC_WLOG_PKTFATE_LOG_RX_CTRL_FRAME(fapi_get_data(skb), fapi_get_datalen(skb));
384 #endif
385
386 switch (fapi_get_sigid(skb)) {
387 case MLME_SCAN_DONE_IND:
388 scan_id = fapi_get_u16(skb, u.mlme_scan_done_ind.scan_id);
389 #ifdef CONFIG_SCSC_WLAN_GSCAN_ENABLE
390 if (slsi_is_gscan_id(scan_id))
391 return slsi_rx_enqueue_netdev_mlme(sdev, skb, SLSI_NET_INDEX_WLAN);
392 #endif
393 return slsi_rx_enqueue_netdev_mlme(sdev, skb, (scan_id >> 8));
394 case MLME_SCAN_IND:
395 if (vif)
396 return slsi_rx_enqueue_netdev_mlme(sdev, skb, vif);
397 scan_id = fapi_get_u16(skb, u.mlme_scan_ind.scan_id);
398 #ifdef CONFIG_SCSC_WLAN_GSCAN_ENABLE
399 if (slsi_is_gscan_id(scan_id))
400 return slsi_rx_enqueue_netdev_mlme(sdev, skb, SLSI_NET_INDEX_WLAN);
401 #endif
402 return slsi_rx_enqueue_netdev_mlme(sdev, skb, (scan_id >> 8));
403 case MLME_RECEIVED_FRAME_IND:
404 if (vif == 0) {
405 SLSI_WARN(sdev, "Received MLME_RECEIVED_FRAME_IND on VIF 0\n");
406 goto err;
407 }
408 return slsi_rx_action_enqueue_netdev_mlme(sdev, skb, vif);
409 #ifdef CONFIG_SCSC_WLAN_GSCAN_ENABLE
410 #ifdef CONFIG_SCSC_WIFI_NAN_ENABLE
411 case MLME_NAN_EVENT_IND:
412 case MLME_NAN_FOLLOWUP_IND:
413 case MLME_NAN_SERVICE_IND:
414 case MLME_NDP_REQUEST_IND:
415 case MLME_NDP_REQUESTED_IND:
416 case MLME_NDP_RESPONSE_IND:
417 case MLME_NDP_TERMINATE_IND:
418 case MLME_NDP_TERMINATED_IND:
419 return slsi_rx_enqueue_netdev_mlme(sdev, skb, vif);
420 #endif
421 case MLME_RANGE_IND:
422 case MLME_RANGE_DONE_IND:
423 if (vif == 0)
424 return slsi_rx_enqueue_netdev_mlme(sdev, skb, SLSI_NET_INDEX_WLAN);
425 else
426 return slsi_rx_enqueue_netdev_mlme(sdev, skb, vif);
427 #endif
428 #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING
429 case MLME_EVENT_LOG_IND:
430 return slsi_rx_enqueue_netdev_mlme(sdev, skb, SLSI_NET_INDEX_WLAN);
431 #endif
432 case MLME_ROAMED_IND:
433 if (vif == 0) {
434 SLSI_WARN(sdev, "Received MLME_ROAMED_IND on VIF 0, return error\n");
435 goto err;
436 } else {
437 struct net_device *dev;
438 struct netdev_vif *ndev_vif;
439
440 rcu_read_lock();
441 dev = slsi_get_netdev_rcu(sdev, vif);
442 if (WARN_ON(!dev)) {
443 rcu_read_unlock();
444 return -ENODEV;
445 }
446 ndev_vif = netdev_priv(dev);
447 if (atomic_read(&ndev_vif->sta.drop_roamed_ind)) {
448 /* If roam cfm is not received for the req, ignore this roamed indication. */
449 slsi_kfree_skb(skb);
450 rcu_read_unlock();
451 return 0;
452 }
453 rcu_read_unlock();
454 return slsi_rx_enqueue_netdev_mlme(sdev, skb, vif);
455 }
456 default:
457 if (vif == 0) {
458 SLSI_WARN(sdev, "Received signal 0x%04x on VIF 0, return error\n", fapi_get_sigid(skb));
459 goto err;
460 } else {
461 return slsi_rx_enqueue_netdev_mlme(sdev, skb, vif);
462 }
463 }
464 }
465 if (WARN_ON(fapi_is_req(skb)))
466 goto err;
467
468 if (slsi_is_test_mode_enabled()) {
469 slsi_kfree_skb(skb);
470 return 0;
471 }
472
473 WARN_ON(1);
474
475 err:
476 return -EINVAL;
477 }
478
479 int sap_mlme_init(void)
480 {
481 SLSI_INFO_NODEV("Registering SAP\n");
482 slsi_hip_sap_register(&sap_mlme);
483 return 0;
484 }
485
486 int sap_mlme_deinit(void)
487 {
488 SLSI_INFO_NODEV("Unregistering SAP\n");
489 slsi_hip_sap_unregister(&sap_mlme);
490 return 0;
491 }