1 /****************************************************************************
3 * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
5 ****************************************************************************/
6 #include <linux/types.h>
15 #include "scsc_wifilogger_rings.h"
17 #include "nl80211_vendor.h"
20 #define SUPPORTED_OLD_VERSION 0
22 static int sap_mlme_version_supported(u16 version
);
23 static int sap_mlme_rx_handler(struct slsi_dev
*sdev
, struct sk_buff
*skb
);
25 static int sap_mlme_notifier(struct slsi_dev
*sdev
, unsigned long event
);
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
,
35 static int sap_mlme_notifier(struct slsi_dev
*sdev
, unsigned long event
)
38 #ifdef CONFIG_SLSI_WLAN_STA_FWD_BEACON
39 struct net_device
*dev
;
41 #ifdef CONFIG_SCSC_WLAN_SILENT_RECOVERY
42 bool vif_type_ap
= false;
45 struct netdev_vif
*ndev_vif
;
47 SLSI_INFO_NODEV("Notifier event received: %lu\n", event
);
48 if (event
>= SCSC_MAX_NOTIFIER
)
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
);
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
) {
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
;
80 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
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;
88 SLSI_MUTEX_UNLOCK(sdev
->netdev_add_remove_mutex
);
89 SLSI_INFO_NODEV("Force cleaned all VIFs\n");
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
);
100 case SCSC_WIFI_SUSPEND
:
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
);
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;
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");
118 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
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
);
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
);
133 SLSI_INFO_NODEV("Unknown event code %lu\n", event
);
140 static int sap_mlme_version_supported(u16 version
)
142 unsigned int major
= SAP_MAJOR(version
);
143 unsigned int minor
= SAP_MINOR(version
);
146 SLSI_INFO_NODEV("Reported version: %d.%d\n", major
, minor
);
148 for (i
= 0; i
< SAP_MAX_VER
; i
++)
149 if (SAP_MAJOR(sap_mlme
.sap_versions
[i
]) == major
)
152 SLSI_ERR_NODEV("Version %d.%d Not supported\n", major
, minor
);
157 static int slsi_rx_netdev_mlme(struct slsi_dev
*sdev
, struct net_device
*dev
, struct sk_buff
*skb
)
159 u16 id
= fapi_get_u16(skb
, id
);
161 /* The skb is consumed by the functions called.
165 slsi_rx_scan_ind(sdev
, dev
, skb
);
167 case MLME_SCAN_DONE_IND
:
168 slsi_rx_scan_done_ind(sdev
, dev
, skb
);
170 case MLME_CONNECT_IND
:
171 slsi_rx_connect_ind(sdev
, dev
, skb
);
173 case MLME_CONNECTED_IND
:
174 slsi_rx_connected_ind(sdev
, dev
, skb
);
176 case MLME_RECEIVED_FRAME_IND
:
177 slsi_rx_received_frame_ind(sdev
, dev
, skb
);
179 case MLME_DISCONNECT_IND
:
180 slsi_rx_disconnect_ind(sdev
, dev
, skb
);
182 case MLME_DISCONNECTED_IND
:
183 slsi_rx_disconnected_ind(sdev
, dev
, skb
);
185 case MLME_PROCEDURE_STARTED_IND
:
186 slsi_rx_procedure_started_ind(sdev
, dev
, skb
);
188 case MLME_FRAME_TRANSMISSION_IND
:
189 slsi_rx_frame_transmission_ind(sdev
, dev
, skb
);
191 case MA_BLOCKACK_IND
:
192 slsi_rx_blockack_ind(sdev
, dev
, skb
);
194 case MLME_ROAMED_IND
:
195 slsi_rx_roamed_ind(sdev
, dev
, skb
);
198 slsi_rx_roam_ind(sdev
, dev
, skb
);
200 case MLME_MIC_FAILURE_IND
:
201 slsi_rx_mic_failure_ind(sdev
, dev
, skb
);
203 case MLME_REASSOCIATE_IND
:
204 slsi_rx_reassoc_ind(sdev
, dev
, skb
);
206 case MLME_TDLS_PEER_IND
:
207 slsi_tdls_peer_ind(sdev
, dev
, skb
);
209 case MLME_LISTEN_END_IND
:
210 slsi_rx_listen_end_ind(dev
, skb
);
212 case MLME_CHANNEL_SWITCHED_IND
:
213 slsi_rx_channel_switched_ind(sdev
, dev
, skb
);
215 case MLME_AC_PRIORITY_UPDATE_IND
:
216 SLSI_DBG1(sdev
, SLSI_MLME
, "Unexpected MLME_AC_PRIORITY_UPDATE_IND\n");
219 #ifdef CONFIG_SCSC_WLAN_GSCAN_ENABLE
220 case MLME_RSSI_REPORT_IND
:
221 slsi_rx_rssi_report_ind(sdev
, dev
, skb
);
224 slsi_rx_range_ind(sdev
, dev
, skb
);
226 case MLME_RANGE_DONE_IND
:
227 slsi_rx_range_done_ind(sdev
, dev
, skb
);
229 case MLME_EVENT_LOG_IND
:
230 slsi_rx_event_log_indication(sdev
, dev
, skb
);
233 #ifdef CONFIG_SCSC_WIFI_NAN_ENABLE
234 case MLME_NAN_EVENT_IND
:
235 slsi_nan_event(sdev
, dev
, skb
);
237 case MLME_NAN_FOLLOWUP_IND
:
238 slsi_nan_followup_ind(sdev
, dev
, skb
);
240 case MLME_NAN_SERVICE_IND
:
241 slsi_nan_service_ind(sdev
, dev
, skb
);
243 case MLME_NDP_REQUEST_IND
:
244 slsi_nan_ndp_setup_ind(sdev
, dev
, skb
, true);
246 case MLME_NDP_REQUESTED_IND
:
247 slsi_nan_ndp_requested_ind(sdev
, dev
, skb
);
249 case MLME_NDP_RESPONSE_IND
:
250 slsi_nan_ndp_setup_ind(sdev
, dev
, skb
, false);
252 case MLME_NDP_TERMINATE_IND
:
253 slsi_nan_ndp_termination_ind(sdev
, dev
, skb
, false);
255 case MLME_NDP_TERMINATED_IND
:
256 slsi_nan_ndp_termination_ind(sdev
, dev
, skb
, true);
259 #ifdef CONFIG_SCSC_WLAN_SAE_CONFIG
260 case MLME_SYNCHRONISED_IND
:
261 slsi_rx_synchronised_ind(sdev
, dev
, skb
);
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
);
271 SLSI_NET_ERR(dev
, "Unhandled Ind: 0x%.4x\n", id
);
277 void slsi_rx_netdev_mlme_work(struct work_struct
*work
)
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
);
287 slsi_wakelock(&sdev
->wlan_wl
);
289 slsi_debug_frame(sdev
, dev
, skb
, "RX");
290 slsi_rx_netdev_mlme(sdev
, dev
, skb
);
291 skb
= slsi_skb_work_dequeue(w
);
293 slsi_wakeunlock(&sdev
->wlan_wl
);
296 int slsi_rx_enqueue_netdev_mlme(struct slsi_dev
*sdev
, struct sk_buff
*skb
, u16 vif
)
298 struct net_device
*dev
;
299 struct netdev_vif
*ndev_vif
;
302 dev
= slsi_get_netdev_rcu(sdev
, vif
);
305 /* Calling function should free the skb */
309 ndev_vif
= netdev_priv(dev
);
311 if (unlikely(ndev_vif
->is_fw_test
)) {
317 slsi_skb_work_enqueue(&ndev_vif
->rx_mlme
, skb
);
322 static int slsi_rx_action_enqueue_netdev_mlme(struct slsi_dev
*sdev
, struct sk_buff
*skb
, u16 vif
)
324 struct net_device
*dev
;
325 struct netdev_vif
*ndev_vif
;
328 dev
= slsi_get_netdev_rcu(sdev
, vif
);
334 ndev_vif
= netdev_priv(dev
);
336 if (unlikely(ndev_vif
->is_fw_test
)) {
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
);
348 if (WARN_ON(!p2pdev
)) {
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
356 ndev_vif
= netdev_priv(p2pdev
);
358 if (unlikely(ndev_vif
->is_fw_test
)) {
367 slsi_skb_work_enqueue(&ndev_vif
->rx_mlme
, skb
);
373 static int sap_mlme_rx_handler(struct slsi_dev
*sdev
, struct sk_buff
*skb
)
376 u16 vif
= fapi_get_vif(skb
);
378 if (slsi_rx_blocking_signals(sdev
, skb
) == 0)
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
));
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
);
393 return slsi_rx_enqueue_netdev_mlme(sdev
, skb
, (scan_id
>> 8));
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
);
402 return slsi_rx_enqueue_netdev_mlme(sdev
, skb
, (scan_id
>> 8));
403 case MLME_RECEIVED_FRAME_IND
:
405 SLSI_WARN(sdev
, "Received MLME_RECEIVED_FRAME_IND on VIF 0\n");
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
);
422 case MLME_RANGE_DONE_IND
:
424 return slsi_rx_enqueue_netdev_mlme(sdev
, skb
, SLSI_NET_INDEX_WLAN
);
426 return slsi_rx_enqueue_netdev_mlme(sdev
, skb
, vif
);
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
);
432 case MLME_ROAMED_IND
:
434 SLSI_WARN(sdev
, "Received MLME_ROAMED_IND on VIF 0, return error\n");
437 struct net_device
*dev
;
438 struct netdev_vif
*ndev_vif
;
441 dev
= slsi_get_netdev_rcu(sdev
, vif
);
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. */
454 return slsi_rx_enqueue_netdev_mlme(sdev
, skb
, vif
);
458 SLSI_WARN(sdev
, "Received signal 0x%04x on VIF 0, return error\n", fapi_get_sigid(skb
));
461 return slsi_rx_enqueue_netdev_mlme(sdev
, skb
, vif
);
465 if (WARN_ON(fapi_is_req(skb
)))
468 if (slsi_is_test_mode_enabled()) {
479 int sap_mlme_init(void)
481 SLSI_INFO_NODEV("Registering SAP\n");
482 slsi_hip_sap_register(&sap_mlme
);
486 int sap_mlme_deinit(void)
488 SLSI_INFO_NODEV("Unregistering SAP\n");
489 slsi_hip_sap_unregister(&sap_mlme
);