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