1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 
8 /**
9  * @brief File containing event specific definitions in the System mode
10  * for the FMAC IF Layer of the Wi-Fi driver.
11  */
12 
13 #include "queue.h"
14 #include "host_rpu_umac_if.h"
15 #include "common/hal_mem.h"
16 #include "system/fmac_rx.h"
17 #include "system/fmac_tx.h"
18 #include "system/fmac_peer.h"
19 #include "system/fmac_ap.h"
20 #include "system/fmac_event.h"
21 #include "common/fmac_util.h"
22 
23 #ifdef NRF70_SYSTEM_WITH_RAW_MODES
24 static enum nrf_wifi_status
nrf_wifi_fmac_if_mode_set_event_proc(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct nrf_wifi_event_raw_config_mode * mode_event)25 nrf_wifi_fmac_if_mode_set_event_proc(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
26 				     struct nrf_wifi_event_raw_config_mode *mode_event)
27 {
28 	enum nrf_wifi_status status = NRF_WIFI_STATUS_SUCCESS;
29 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx;
30 	struct tx_config *config;
31 	struct nrf_wifi_fmac_vif_ctx *vif;
32 	unsigned char if_idx = mode_event->if_index;
33 
34 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
35 	config = &sys_dev_ctx->tx_config;
36 	vif = sys_dev_ctx->vif_ctx[if_idx];
37 
38 	if (!mode_event->status) {
39 		vif->mode = mode_event->op_mode;
40 #ifdef NRF70_RAW_DATA_TX
41 		vif->txinjection_mode = false;
42 #endif /* NRF70_RAW_DATA_TX */
43 #ifdef NRF70_PROMISC_DATA_RX
44 		vif->promisc_mode = false;
45 #endif /* NRF70_PROMISC_DATA_RX */
46 		if ((mode_event->op_mode & NRF_WIFI_STA_MODE)
47 			== NRF_WIFI_STA_MODE) {
48 			mode_event->op_mode ^= NRF_WIFI_STA_MODE;
49 			vif->if_type = NRF_WIFI_IFTYPE_STATION;
50 			config->peers[MAX_PEERS].peer_id = -1;
51 			config->peers[MAX_PEERS].if_idx = -1;
52 
53 #if defined(NRF70_RAW_DATA_TX) && defined (NRF70_PROMISC_DATA_RX)
54 			if ((mode_event->op_mode ^
55 			    (NRF_WIFI_PROMISCUOUS_MODE |
56 			     NRF_WIFI_TX_INJECTION_MODE)) == 0) {
57 				vif->if_type
58 					= NRF_WIFI_STA_PROMISC_TX_INJECTOR;
59 				config->peers[MAX_PEERS].peer_id
60 					= MAX_PEERS;
61 				config->peers[MAX_PEERS].if_idx
62 					= if_idx;
63 				vif->txinjection_mode = true;
64 				vif->promisc_mode = true;
65 			}
66 #endif /* NRF70_RAW_DATA_TX && defined NRF70_PROMISC_DATA_RX */
67 #ifdef NRF70_RAW_DATA_TX
68 			if ((mode_event->op_mode ^
69 			     NRF_WIFI_TX_INJECTION_MODE) == 0) {
70 				config->peers[MAX_PEERS].peer_id
71 					= MAX_PEERS;
72 				config->peers[MAX_PEERS].if_idx
73 					= if_idx;
74 				vif->if_type = NRF_WIFI_STA_TX_INJECTOR;
75 				vif->txinjection_mode = true;
76 			}
77 #endif /* NRF70_RAW_DATA_TX */
78 #ifdef NRF70_PROMISC_DATA_RX
79 			if ((mode_event->op_mode ^
80 			     NRF_WIFI_PROMISCUOUS_MODE) == 0) {
81 				vif->if_type = NRF_WIFI_STA_PROMISC;
82 				vif->promisc_mode = true;
83 			}
84 #endif /* NRF70_PROMISC_DATA_RX */
85 			goto out;
86 		}
87 #ifdef NRF70_RAW_DATA_RX
88 		if ((mode_event->op_mode & NRF_WIFI_MONITOR_MODE)
89 			== NRF_WIFI_MONITOR_MODE) {
90 			mode_event->op_mode ^= NRF_WIFI_MONITOR_MODE;
91 			vif->if_type = NRF_WIFI_IFTYPE_MONITOR;
92 			config->peers[MAX_PEERS].peer_id = -1;
93 			config->peers[MAX_PEERS].if_idx = -1;
94 #ifdef NRF70_RAW_DATA_TX
95 			if ((mode_event->op_mode ^
96 			     NRF_WIFI_TX_INJECTION_MODE) == 0) {
97 				config->peers[MAX_PEERS].peer_id
98 					= MAX_PEERS;
99 				config->peers[MAX_PEERS].if_idx
100 					= if_idx;
101 				vif->if_type = NRF_WIFI_MONITOR_TX_INJECTOR;
102 				vif->txinjection_mode = true;
103 			}
104 #endif
105 			goto out;
106 		}
107 #endif
108 	} else {
109 		nrf_wifi_osal_log_err("%s: Set mode failed!",
110 				      __func__);
111 		status = NRF_WIFI_STATUS_FAIL;
112 	}
113 out:
114 	return status;
115 }
116 #endif /* NRF70_SYSTEM_WITH_RAW_MODES */
117 
118 
119 #ifdef NRF70_DATA_TX
120 static enum nrf_wifi_status
nrf_wifi_fmac_if_carr_state_event_proc(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned char * umac_head,enum nrf_wifi_fmac_if_carr_state carr_state)121 nrf_wifi_fmac_if_carr_state_event_proc(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
122 				       unsigned char *umac_head,
123 				       enum nrf_wifi_fmac_if_carr_state carr_state)
124 {
125 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
126 	struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
127 	unsigned char if_idx = 0;
128 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
129 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
130 
131 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
132 	sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
133 
134 	if (!fmac_dev_ctx || !umac_head) {
135 		nrf_wifi_osal_log_err("%s: Invalid parameters",
136 				      __func__);
137 
138 		goto out;
139 	}
140 
141 	if (!sys_fpriv->callbk_fns.if_carr_state_chg_callbk_fn) {
142 		nrf_wifi_osal_log_dbg("%s: No callback handler registered",
143 				      __func__);
144 
145 		status = NRF_WIFI_STATUS_SUCCESS;
146 		goto out;
147 	}
148 
149 	if_idx = ((struct nrf_wifi_data_carrier_state *)umac_head)->wdev_id;
150 
151 	if (if_idx >= MAX_NUM_VIFS) {
152 		nrf_wifi_osal_log_err("%s: Invalid wdev_id recd from UMAC %d",
153 				      __func__,
154 				      if_idx);
155 		goto out;
156 	}
157 
158 	vif_ctx = sys_dev_ctx->vif_ctx[if_idx];
159 
160 	status = sys_fpriv->callbk_fns.if_carr_state_chg_callbk_fn(vif_ctx->os_vif_ctx,
161 									     carr_state);
162 
163 	if (status != NRF_WIFI_STATUS_SUCCESS) {
164 		nrf_wifi_osal_log_err("%s: IF carrier state change failed for VIF idx = %d",
165 				      __func__,
166 				      if_idx);
167 		goto out;
168 	}
169 out:
170 	return status;
171 }
172 #endif /* NRF70_DATA_TX */
173 
174 
umac_event_sys_stats_process(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,void * event)175 static enum nrf_wifi_status umac_event_sys_stats_process(
176 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
177 	void *event)
178 {
179 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
180 	struct nrf_wifi_sys_umac_event_stats *stats = NULL;
181 
182 	if (!event) {
183 		nrf_wifi_osal_log_err("%s: Invalid parameters",
184 				      __func__);
185 		goto out;
186 	}
187 
188 	if (!fmac_dev_ctx->stats_req) {
189 		nrf_wifi_osal_log_err("%s: Stats recd when req was not sent!",
190 				      __func__);
191 		goto out;
192 	}
193 
194 	stats = ((struct nrf_wifi_sys_umac_event_stats *)event);
195 
196 	nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fw_stats,
197 			      &stats->fw,
198 			      sizeof(*fmac_dev_ctx->fw_stats));
199 
200 	fmac_dev_ctx->stats_req = false;
201 
202 	status = NRF_WIFI_STATUS_SUCCESS;
203 
204 out:
205 	return status;
206 }
207 
208 
umac_event_sys_proc_events(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct host_rpu_msg * rpu_msg)209 static enum nrf_wifi_status umac_event_sys_proc_events(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
210 						       struct host_rpu_msg *rpu_msg)
211 {
212 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
213 	unsigned char *sys_head = NULL;
214 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx;
215 
216 	if (!fmac_dev_ctx || !rpu_msg) {
217 		return status;
218 	}
219 
220 
221 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
222 
223 	sys_head = (unsigned char *)rpu_msg->msg;
224 
225 	switch (((struct nrf_wifi_sys_head *)sys_head)->cmd_event) {
226 	case NRF_WIFI_EVENT_STATS:
227 		status = umac_event_sys_stats_process(fmac_dev_ctx,
228 						      sys_head);
229 		break;
230 	case NRF_WIFI_EVENT_INIT_DONE:
231 		fmac_dev_ctx->fw_init_done = 1;
232 		status = NRF_WIFI_STATUS_SUCCESS;
233 		break;
234 	case NRF_WIFI_EVENT_DEINIT_DONE:
235 		fmac_dev_ctx->fw_deinit_done = 1;
236 		status = NRF_WIFI_STATUS_SUCCESS;
237 		break;
238 #ifdef NRF70_RAW_DATA_TX
239 	case NRF_WIFI_EVENT_RAW_TX_DONE:
240 		status = nrf_wifi_fmac_rawtx_done_event_process(fmac_dev_ctx,
241 						(struct nrf_wifi_event_raw_tx_done *)sys_head);
242 		break;
243 #endif
244 #ifdef NRF70_SYSTEM_WITH_RAW_MODES
245 	case NRF_WIFI_EVENT_MODE_SET_DONE:
246 		status = nrf_wifi_fmac_if_mode_set_event_proc(fmac_dev_ctx,
247 						(struct nrf_wifi_event_raw_config_mode *)sys_head);
248 		break;
249 #endif
250 #if defined(NRF70_RAW_DATA_TX) || defined(NRF70_RAW_DATA_RX)
251 	case NRF_WIFI_EVENT_CHANNEL_SET_DONE:
252 		struct nrf_wifi_event_set_channel *channel_event;
253 
254 		channel_event = (struct nrf_wifi_event_set_channel *)sys_head;
255 		if (!channel_event->status) {
256 			sys_dev_ctx->vif_ctx[channel_event->if_index]->channel =
257 								channel_event->chan_num;
258 		}
259 		status = NRF_WIFI_STATUS_SUCCESS;
260 		break;
261 #endif /* NRF70_RAW_DATA_TX */
262 #if defined(NRF70_RAW_DATA_RX) || defined(NRF70_PROMISC_DATA_RX)
263 	case NRF_WIFI_EVENT_FILTER_SET_DONE:
264 		struct nrf_wifi_event_raw_config_filter *filter_event;
265 
266 		filter_event = (struct nrf_wifi_event_raw_config_filter *)sys_head;
267 		if (!filter_event->status) {
268 			sys_dev_ctx->vif_ctx[filter_event->if_index]->packet_filter =
269 								filter_event->filter;
270 		}
271 		status = NRF_WIFI_STATUS_SUCCESS;
272 		break;
273 #endif /* NRF70_RAW_DATA_RX || NRF70_PROMISC_DATA_RX */
274 	default:
275 		nrf_wifi_osal_log_err("%s: Unknown event recd: %d",
276 				      __func__,
277 				      ((struct nrf_wifi_sys_head *)sys_head)->cmd_event);
278 		break;
279 	}
280 	return status;
281 }
282 
283 
284 static enum nrf_wifi_status
nrf_wifi_fmac_data_event_process(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,void * umac_head)285 nrf_wifi_fmac_data_event_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
286 				 void *umac_head)
287 {
288 	enum nrf_wifi_status status = NRF_WIFI_STATUS_SUCCESS;
289 	int event = -1;
290 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
291 
292 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
293 
294 	if (!fmac_dev_ctx) {
295 		goto out;
296 	}
297 
298 	if (!umac_head) {
299 		nrf_wifi_osal_log_err("%s: Invalid parameters",
300 				      __func__);
301 		goto out;
302 	}
303 
304 	event = ((struct nrf_wifi_umac_head *)umac_head)->cmd;
305 
306 #ifdef NRF_WIFI_CMD_EVENT_LOG
307 	nrf_wifi_osal_log_info("%s: Event %d received from UMAC\n",
308 			      __func__,
309 			      event);
310 #else
311 	nrf_wifi_osal_log_dbg("%s: Event %d received from UMAC",
312 			      __func__,
313 			      event);
314 #endif /* NRF_WIFI_CMD_EVENT_LOG */
315 
316 	switch (event) {
317 	case NRF_WIFI_CMD_RX_BUFF:
318 #ifdef NRF70_RX_DONE_WQ_ENABLED
319 		struct nrf_wifi_rx_buff *config = nrf_wifi_osal_mem_zalloc(
320 			sizeof(struct nrf_wifi_rx_buff));
321 		if (!config) {
322 			nrf_wifi_osal_log_err("%s: Failed to allocate memory (RX)",
323 					      __func__);
324 			status = NRF_WIFI_STATUS_FAIL;
325 			break;
326 		}
327 		nrf_wifi_osal_mem_cpy(config,
328 				      umac_head,
329 				      sizeof(struct nrf_wifi_rx_buff));
330 		status = nrf_wifi_utils_q_enqueue(sys_dev_ctx->rx_config.rx_tasklet_event_q,
331 						  config);
332 		if (status != NRF_WIFI_STATUS_SUCCESS) {
333 			nrf_wifi_osal_log_err("%s: Failed to enqueue RX buffer",
334 					      __func__);
335 			nrf_wifi_osal_mem_free(config);
336 			break;
337 		}
338 		nrf_wifi_osal_tasklet_schedule(sys_dev_ctx->rx_tasklet);
339 #else
340 		status = nrf_wifi_fmac_rx_event_process(fmac_dev_ctx,
341 							umac_head);
342 #endif /* NRF70_RX_DONE_WQ_ENABLED */
343 		break;
344 #ifdef NRF70_DATA_TX
345 	case NRF_WIFI_CMD_TX_BUFF_DONE:
346 #ifdef NRF70_TX_DONE_WQ_ENABLED
347 		struct nrf_wifi_tx_buff_done *config = nrf_wifi_osal_mem_zalloc(
348 					sizeof(struct nrf_wifi_tx_buff_done));
349 		if (!config) {
350 			nrf_wifi_osal_log_err("%s: Failed to allocate memory (TX)",
351 					      __func__);
352 			status = NRF_WIFI_STATUS_FAIL;
353 			break;
354 		}
355 		nrf_wifi_osal_mem_cpy(config,
356 				      umac_head,
357 				      sizeof(struct nrf_wifi_tx_buff_done));
358 		status = nrf_wifi_utils_q_enqueue(sys_dev_ctx->tx_config.tx_done_tasklet_event_q,
359 						  config);
360 		if (status != NRF_WIFI_STATUS_SUCCESS) {
361 			nrf_wifi_osal_log_err("%s: Failed to enqueue TX buffer",
362 					      __func__);
363 			nrf_wifi_osal_mem_free(config);
364 			break;
365 		}
366 		nrf_wifi_osal_tasklet_schedule(sys_dev_ctx->tx_done_tasklet);
367 #else
368 		status = nrf_wifi_fmac_tx_done_event_process(fmac_dev_ctx,
369 								umac_head);
370 #endif /* NRF70_TX_DONE_WQ_ENABLED */
371 		break;
372 	case NRF_WIFI_CMD_CARRIER_ON:
373 		status = nrf_wifi_fmac_if_carr_state_event_proc(fmac_dev_ctx,
374 								umac_head,
375 								NRF_WIFI_FMAC_IF_CARR_STATE_ON);
376 		break;
377 	case NRF_WIFI_CMD_CARRIER_OFF:
378 		status = nrf_wifi_fmac_if_carr_state_event_proc(fmac_dev_ctx,
379 								umac_head,
380 								NRF_WIFI_FMAC_IF_CARR_STATE_OFF);
381 		break;
382 #endif /* NRF70_DATA_TX */
383 #ifdef NRF70_AP_MODE
384 	case NRF_WIFI_CMD_PM_MODE:
385 		status = sap_client_update_pmmode(fmac_dev_ctx,
386 						  umac_head);
387 		break;
388 	case NRF_WIFI_CMD_PS_GET_FRAMES:
389 		status = sap_client_ps_get_frames(fmac_dev_ctx,
390 						  umac_head);
391 		break;
392 #endif /* NRF70_AP_MODE */
393 	default:
394 		break;
395 	}
396 
397 out:
398 	if (status != NRF_WIFI_STATUS_SUCCESS) {
399 		nrf_wifi_osal_log_err("%s: Failed for event = %d",
400 				      __func__,
401 				      event);
402 	}
403 
404 	return status;
405 }
406 
407 
408 static enum nrf_wifi_status
nrf_wifi_fmac_data_events_process(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct host_rpu_msg * rpu_msg)409 nrf_wifi_fmac_data_events_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
410 				  struct host_rpu_msg *rpu_msg)
411 {
412 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
413 	unsigned char *umac_head = NULL;
414 	int host_rpu_length_left = 0;
415 
416 	if (!fmac_dev_ctx || !rpu_msg) {
417 		goto out;
418 	}
419 
420 	umac_head = (unsigned char *)rpu_msg->msg;
421 	host_rpu_length_left = rpu_msg->hdr.len - sizeof(struct host_rpu_msg);
422 
423 	while (host_rpu_length_left > 0) {
424 		status = nrf_wifi_fmac_data_event_process(fmac_dev_ctx,
425 							  umac_head);
426 
427 		if (status != NRF_WIFI_STATUS_SUCCESS) {
428 			nrf_wifi_osal_log_err("%s: umac_process_data_event failed",
429 					      __func__);
430 			goto out;
431 		}
432 
433 		host_rpu_length_left -= ((struct nrf_wifi_umac_head *)umac_head)->len;
434 		umac_head += ((struct nrf_wifi_umac_head *)umac_head)->len;
435 	}
436 out:
437 	return status;
438 }
439 
440 
441 #ifdef NRF70_STA_MODE
umac_event_connect(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,void * event_data)442 static void umac_event_connect(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
443 			       void *event_data)
444 {
445 	unsigned char if_index = 0;
446 	int peer_id = -1;
447 	struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
448 	struct nrf_wifi_umac_event_new_station *event = NULL;
449 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
450 
451 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
452 	event = (struct nrf_wifi_umac_event_new_station *)event_data;
453 
454 	if_index = event->umac_hdr.ids.wdev_id;
455 
456 	vif_ctx = sys_dev_ctx->vif_ctx[if_index];
457 	if (if_index >= MAX_NUM_VIFS) {
458 		nrf_wifi_osal_log_err("%s: Invalid wdev_id recd from UMAC %d",
459 				      __func__,
460 				      if_index);
461 		return;
462 	}
463 
464 	if (event->umac_hdr.cmd_evnt == NRF_WIFI_UMAC_EVENT_NEW_STATION) {
465 		if (vif_ctx->if_type == 2) {
466 			nrf_wifi_osal_mem_cpy(vif_ctx->bssid,
467 					      event->mac_addr,
468 					      NRF_WIFI_ETH_ADDR_LEN);
469 		}
470 		peer_id = nrf_wifi_fmac_peer_get_id(fmac_dev_ctx, event->mac_addr);
471 
472 		if (peer_id == -1) {
473 			peer_id = nrf_wifi_fmac_peer_add(fmac_dev_ctx,
474 							 if_index,
475 							 event->mac_addr,
476 							 event->is_sta_legacy,
477 							 event->wme);
478 
479 			if (peer_id == -1) {
480 				nrf_wifi_osal_log_err("%s:Can't add new station.",
481 						      __func__);
482 				return;
483 			}
484 		}
485 	} else if (event->umac_hdr.cmd_evnt == NRF_WIFI_UMAC_EVENT_DEL_STATION) {
486 		peer_id = nrf_wifi_fmac_peer_get_id(fmac_dev_ctx, event->mac_addr);
487 		if (peer_id != -1) {
488 			nrf_wifi_fmac_peer_remove(fmac_dev_ctx,
489 						  if_index,
490 						  peer_id);
491 		}
492 	}
493 
494 	return;
495 
496 }
497 #endif /* NRF70_STA_MODE */
498 
499 
umac_event_ctrl_process(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,void * event_data,unsigned int event_len)500 static enum nrf_wifi_status umac_event_ctrl_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
501 						    void *event_data,
502 						    unsigned int event_len)
503 {
504 	enum nrf_wifi_status status = NRF_WIFI_STATUS_SUCCESS;
505 	struct nrf_wifi_umac_hdr *umac_hdr = NULL;
506 	struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
507 	struct nrf_wifi_fmac_callbk_fns *callbk_fns = NULL;
508 	struct nrf_wifi_umac_event_vif_state *evnt_vif_state = NULL;
509 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
510 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
511 	bool more_res = false;
512 	unsigned char if_id = 0;
513 	unsigned int event_num = 0;
514 
515 	if (!fmac_dev_ctx || !event_data) {
516 		nrf_wifi_osal_log_err("%s: Invalid parameters",
517 				      __func__);
518 		goto out;
519 	}
520 
521 	sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
522 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
523 
524 	if (!sys_fpriv || !sys_dev_ctx) {
525 		goto out;
526 	}
527 
528 	umac_hdr = event_data;
529 	if_id = umac_hdr->ids.wdev_id;
530 	event_num = umac_hdr->cmd_evnt;
531 
532 	if (if_id >= MAX_NUM_VIFS) {
533 		nrf_wifi_osal_log_err("%s: Invalid wdev_id recd from UMAC %d",
534 				      __func__,
535 				      if_id);
536 
537 		goto out;
538 	}
539 
540 	vif_ctx = sys_dev_ctx->vif_ctx[if_id];
541 	if (!vif_ctx) {
542 		nrf_wifi_osal_log_err("%s: Invalid vif_ctx",
543 				      __func__);
544 		goto out;
545 	}
546 	callbk_fns = &sys_fpriv->callbk_fns;
547 	if (!callbk_fns) {
548 		nrf_wifi_osal_log_err("%s: Invalid callbk_fns",
549 				      __func__);
550 		goto out;
551 	}
552 
553 #ifdef NRF_WIFI_CMD_EVENT_LOG
554 	nrf_wifi_osal_log_info("%s: Event %d received from UMAC\n",
555 			      __func__,
556 			      event_num);
557 #else
558 	nrf_wifi_osal_log_dbg("%s: Event %d received from UMAC",
559 			      __func__,
560 			      event_num);
561 #endif /* NRF_WIFI_CMD_EVENT_LOG */
562 
563 	switch (umac_hdr->cmd_evnt) {
564 	case NRF_WIFI_UMAC_EVENT_GET_REG:
565 		if (callbk_fns->event_get_reg)
566 			callbk_fns->event_get_reg(vif_ctx->os_vif_ctx,
567 						      event_data,
568 						      event_len);
569 		else
570 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
571 					      __func__,
572 					      umac_hdr->cmd_evnt);
573 		break;
574 	case NRF_WIFI_UMAC_EVENT_REG_CHANGE:
575 		if (callbk_fns->reg_change_callbk_fn)
576 			callbk_fns->reg_change_callbk_fn(vif_ctx->os_vif_ctx,
577 							 event_data,
578 							 event_len);
579 		else
580 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
581 					      __func__,
582 					      umac_hdr->cmd_evnt);
583 		break;
584 	case NRF_WIFI_UMAC_EVENT_TRIGGER_SCAN_START:
585 		if (callbk_fns->scan_start_callbk_fn)
586 			callbk_fns->scan_start_callbk_fn(vif_ctx->os_vif_ctx,
587 							 event_data,
588 							 event_len);
589 		else
590 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
591 					      __func__,
592 					      umac_hdr->cmd_evnt);
593 		break;
594 	case NRF_WIFI_UMAC_EVENT_SCAN_DONE:
595 		if (callbk_fns->scan_done_callbk_fn)
596 			callbk_fns->scan_done_callbk_fn(vif_ctx->os_vif_ctx,
597 							event_data,
598 							event_len);
599 		else
600 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
601 					      __func__,
602 					      umac_hdr->cmd_evnt);
603 		break;
604 	case NRF_WIFI_UMAC_EVENT_SCAN_ABORTED:
605 		if (callbk_fns->scan_abort_callbk_fn)
606 			callbk_fns->scan_abort_callbk_fn(vif_ctx->os_vif_ctx,
607 							 event_data,
608 							 event_len);
609 		else
610 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
611 					      __func__,
612 					      umac_hdr->cmd_evnt);
613 		break;
614 	case NRF_WIFI_UMAC_EVENT_SCAN_DISPLAY_RESULT:
615 		if (umac_hdr->seq != 0)
616 			more_res = true;
617 
618 		if (callbk_fns->disp_scan_res_callbk_fn)
619 			callbk_fns->disp_scan_res_callbk_fn(vif_ctx->os_vif_ctx,
620 							    event_data,
621 							    event_len,
622 							    more_res);
623 		else
624 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
625 					      __func__,
626 					      umac_hdr->cmd_evnt);
627 		break;
628 	case NRF_WIFI_UMAC_EVENT_IFFLAGS_STATUS:
629 		evnt_vif_state = (struct nrf_wifi_umac_event_vif_state *)event_data;
630 
631 		if (evnt_vif_state->status < 0) {
632 			nrf_wifi_osal_log_err("%s: Failed to set interface flags: %d",
633 					      __func__,
634 						evnt_vif_state->status);
635 			goto out;
636 		}
637 		vif_ctx->ifflags = true;
638 		break;
639 #ifdef NRF70_STA_MODE
640 	case NRF_WIFI_UMAC_EVENT_TWT_SLEEP:
641 		if (callbk_fns->twt_sleep_callbk_fn)
642 			callbk_fns->twt_sleep_callbk_fn(vif_ctx->os_vif_ctx,
643 							event_data,
644 							event_len);
645 		else
646 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
647 					      __func__,
648 					      umac_hdr->cmd_evnt);
649 		break;
650 	case NRF_WIFI_UMAC_EVENT_SCAN_RESULT:
651 		if (umac_hdr->seq != 0)
652 			more_res = true;
653 
654 		if (callbk_fns->scan_res_callbk_fn)
655 			callbk_fns->scan_res_callbk_fn(vif_ctx->os_vif_ctx,
656 						       event_data,
657 						       event_len,
658 						       more_res);
659 		else
660 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
661 					      __func__,
662 					      umac_hdr->cmd_evnt);
663 		break;
664 	case NRF_WIFI_UMAC_EVENT_AUTHENTICATE:
665 		if (callbk_fns->auth_resp_callbk_fn)
666 			callbk_fns->auth_resp_callbk_fn(vif_ctx->os_vif_ctx,
667 							event_data,
668 							event_len);
669 		else
670 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
671 					      __func__,
672 					      umac_hdr->cmd_evnt);
673 		break;
674 	case NRF_WIFI_UMAC_EVENT_ASSOCIATE:
675 		if (callbk_fns->assoc_resp_callbk_fn)
676 			callbk_fns->assoc_resp_callbk_fn(vif_ctx->os_vif_ctx,
677 							 event_data,
678 							 event_len);
679 		else
680 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
681 					      __func__,
682 					      umac_hdr->cmd_evnt);
683 		break;
684 	case NRF_WIFI_UMAC_EVENT_DEAUTHENTICATE:
685 		if (callbk_fns->deauth_callbk_fn)
686 			callbk_fns->deauth_callbk_fn(vif_ctx->os_vif_ctx,
687 						     event_data,
688 						     event_len);
689 		else
690 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
691 					      __func__,
692 					      umac_hdr->cmd_evnt);
693 		break;
694 	case NRF_WIFI_UMAC_EVENT_DISASSOCIATE:
695 		if (callbk_fns->disassoc_callbk_fn)
696 			callbk_fns->disassoc_callbk_fn(vif_ctx->os_vif_ctx,
697 						       event_data,
698 						       event_len);
699 		else
700 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
701 					      __func__,
702 					      umac_hdr->cmd_evnt);
703 		break;
704 	case NRF_WIFI_UMAC_EVENT_FRAME:
705 		if (callbk_fns->mgmt_rx_callbk_fn)
706 			callbk_fns->mgmt_rx_callbk_fn(vif_ctx->os_vif_ctx,
707 						      event_data,
708 						      event_len);
709 		else
710 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
711 					      __func__,
712 					      umac_hdr->cmd_evnt);
713 		break;
714 	case NRF_WIFI_UMAC_EVENT_GET_TX_POWER:
715 		if (callbk_fns->tx_pwr_get_callbk_fn)
716 			callbk_fns->tx_pwr_get_callbk_fn(vif_ctx->os_vif_ctx,
717 							 event_data,
718 							 event_len);
719 		else
720 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
721 					      __func__,
722 					      umac_hdr->cmd_evnt);
723 		break;
724 	case NRF_WIFI_UMAC_EVENT_GET_CHANNEL:
725 		if (callbk_fns->chnl_get_callbk_fn)
726 			callbk_fns->chnl_get_callbk_fn(vif_ctx->os_vif_ctx,
727 						       event_data,
728 						       event_len);
729 		else
730 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
731 					      __func__,
732 					      umac_hdr->cmd_evnt);
733 		break;
734 	case NRF_WIFI_UMAC_EVENT_GET_STATION:
735 		if (callbk_fns->get_station_callbk_fn)
736 			callbk_fns->get_station_callbk_fn(vif_ctx->os_vif_ctx,
737 						     event_data,
738 						     event_len);
739 		else
740 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
741 					      __func__,
742 					      umac_hdr->cmd_evnt);
743 		break;
744 	case NRF_WIFI_UMAC_EVENT_NEW_INTERFACE:
745 		if (callbk_fns->get_interface_callbk_fn)
746 			callbk_fns->get_interface_callbk_fn(vif_ctx->os_vif_ctx,
747 						     event_data,
748 						     event_len);
749 		else
750 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
751 					      __func__,
752 					      umac_hdr->cmd_evnt);
753 		break;
754 	case NRF_WIFI_UMAC_EVENT_COOKIE_RESP:
755 		if (callbk_fns->cookie_rsp_callbk_fn)
756 			callbk_fns->cookie_rsp_callbk_fn(vif_ctx->os_vif_ctx,
757 							 event_data,
758 							 event_len);
759 		else
760 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
761 					      __func__,
762 					      umac_hdr->cmd_evnt);
763 		break;
764 	case NRF_WIFI_UMAC_EVENT_FRAME_TX_STATUS:
765 		if (callbk_fns->mgmt_tx_status)
766 			callbk_fns->mgmt_tx_status(vif_ctx->os_vif_ctx,
767 							event_data,
768 							event_len);
769 		else
770 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
771 					      __func__,
772 					      umac_hdr->cmd_evnt);
773 		break;
774 	case NRF_WIFI_UMAC_EVENT_UNPROT_DEAUTHENTICATE:
775 	case NRF_WIFI_UMAC_EVENT_UNPROT_DISASSOCIATE:
776 		if (callbk_fns->unprot_mlme_mgmt_rx_callbk_fn)
777 			callbk_fns->unprot_mlme_mgmt_rx_callbk_fn(vif_ctx->os_vif_ctx,
778 								  event_data,
779 								  event_len);
780 		else
781 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
782 					      __func__,
783 					      umac_hdr->cmd_evnt);
784 		break;
785 	case NRF_WIFI_UMAC_EVENT_SET_INTERFACE:
786 		if (callbk_fns->set_if_callbk_fn)
787 			callbk_fns->set_if_callbk_fn(vif_ctx->os_vif_ctx,
788 						     event_data,
789 						     event_len);
790 		else
791 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
792 					      __func__,
793 					      umac_hdr->cmd_evnt);
794 		break;
795 	case NRF_WIFI_UMAC_EVENT_CONFIG_TWT:
796 		if (callbk_fns->twt_config_callbk_fn)
797 			callbk_fns->twt_config_callbk_fn(vif_ctx->os_vif_ctx,
798 							event_data,
799 							event_len);
800 		else
801 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
802 					      __func__,
803 					      umac_hdr->cmd_evnt);
804 		break;
805 	case NRF_WIFI_UMAC_EVENT_TEARDOWN_TWT:
806 		if (callbk_fns->twt_teardown_callbk_fn)
807 			callbk_fns->twt_teardown_callbk_fn(vif_ctx->os_vif_ctx,
808 							   event_data,
809 							   event_len);
810 		else
811 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
812 					      __func__,
813 					      umac_hdr->cmd_evnt);
814 		break;
815 	case NRF_WIFI_UMAC_EVENT_NEW_WIPHY:
816 		if (callbk_fns->event_get_wiphy)
817 			callbk_fns->event_get_wiphy(vif_ctx->os_vif_ctx,
818 						    event_data,
819 						    event_len);
820 		else
821 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
822 					      __func__,
823 					      umac_hdr->cmd_evnt);
824 		break;
825 	case NRF_WIFI_UMAC_EVENT_CMD_STATUS:
826 #if WIFI_NRF70_LOG_LEVEL >= NRF_WIFI_LOG_LEVEL_DBG
827 		struct nrf_wifi_umac_event_cmd_status *cmd_status =
828 			(struct nrf_wifi_umac_event_cmd_status *)event_data;
829 #endif
830 		nrf_wifi_osal_log_dbg("%s: Command %d -> status %d",
831 				      __func__,
832 				      cmd_status->cmd_id,
833 				      cmd_status->cmd_status);
834 		break;
835 	case NRF_WIFI_UMAC_EVENT_BEACON_HINT:
836 	case NRF_WIFI_UMAC_EVENT_CONNECT:
837 	case NRF_WIFI_UMAC_EVENT_DISCONNECT:
838 		/* Nothing to be done */
839 		break;
840 	case NRF_WIFI_UMAC_EVENT_GET_POWER_SAVE_INFO:
841 		if (callbk_fns->event_get_ps_info)
842 			callbk_fns->event_get_ps_info(vif_ctx->os_vif_ctx,
843 						      event_data,
844 						      event_len);
845 		else
846 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
847 					      __func__,
848 					      umac_hdr->cmd_evnt);
849 		break;
850 #ifdef NRF70_STA_MODE
851 	case NRF_WIFI_UMAC_EVENT_NEW_STATION:
852 	case NRF_WIFI_UMAC_EVENT_DEL_STATION:
853 		umac_event_connect(fmac_dev_ctx,
854 				   event_data);
855 		break;
856 #endif /* NRF70_STA_MODE */
857 #ifdef NRF70_P2P_MODE
858 	case NRF_WIFI_UMAC_EVENT_REMAIN_ON_CHANNEL:
859 		if (callbk_fns->roc_callbk_fn)
860 			callbk_fns->roc_callbk_fn(vif_ctx->os_vif_ctx,
861 						  event_data,
862 						  event_len);
863 		else
864 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
865 					      __func__,
866 					      umac_hdr->cmd_evnt);
867 		break;
868 	case NRF_WIFI_UMAC_EVENT_CANCEL_REMAIN_ON_CHANNEL:
869 		if (callbk_fns->roc_cancel_callbk_fn)
870 			callbk_fns->roc_cancel_callbk_fn(vif_ctx->os_vif_ctx,
871 							 event_data,
872 							 event_len);
873 		else
874 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
875 					      __func__,
876 					      umac_hdr->cmd_evnt);
877 		break;
878 #endif /* NRF70_P2P_MODE */
879 	case NRF_WIFI_UMAC_EVENT_GET_CONNECTION_INFO:
880 		if (callbk_fns->get_conn_info_callbk_fn)
881 			callbk_fns->get_conn_info_callbk_fn(vif_ctx->os_vif_ctx,
882 							    event_data,
883 							    event_len);
884 		else
885 			nrf_wifi_osal_log_err("%s: No callback registered for event %d",
886 					      __func__,
887 					      umac_hdr->cmd_evnt);
888 		break;
889 #endif /* NRF70_STA_MODE */
890 	default:
891 		nrf_wifi_osal_log_dbg("%s: No callback registered for event %d",
892 				      __func__,
893 				      umac_hdr->cmd_evnt);
894 		break;
895 	}
896 
897 	nrf_wifi_osal_log_dbg("%s: Event %d processed",
898 			      __func__,
899 			      event_num);
900 
901 out:
902 	return status;
903 }
904 
905 
nrf_wifi_sys_fmac_event_callback(void * mac_dev_ctx,void * rpu_event_data,unsigned int rpu_event_len)906 enum nrf_wifi_status nrf_wifi_sys_fmac_event_callback(void *mac_dev_ctx,
907 						      void *rpu_event_data,
908 						      unsigned int rpu_event_len)
909 {
910 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
911 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
912 	struct host_rpu_msg *rpu_msg = NULL;
913 	struct nrf_wifi_umac_hdr *umac_hdr = NULL;
914 	unsigned int umac_msg_len = 0;
915 	int umac_msg_type = NRF_WIFI_UMAC_EVENT_UNSPECIFIED;
916 
917 	fmac_dev_ctx = (struct nrf_wifi_fmac_dev_ctx *)mac_dev_ctx;
918 
919 	rpu_msg = (struct host_rpu_msg *)rpu_event_data;
920 	umac_hdr = (struct nrf_wifi_umac_hdr *)rpu_msg->msg;
921 	umac_msg_len = rpu_msg->hdr.len;
922 	umac_msg_type = umac_hdr->cmd_evnt;
923 
924 #ifdef NRF_WIFI_CMD_EVENT_LOG
925 	nrf_wifi_osal_log_info("%s: Event type %d recd\n",
926 			      __func__,
927 			      rpu_msg->type);
928 #else
929 	nrf_wifi_osal_log_dbg("%s: Event type %d recd",
930 			      __func__,
931 			      rpu_msg->type);
932 #endif /* NRF_WIFI_CMD_EVENT_LOG */
933 
934 	switch (rpu_msg->type) {
935 	case NRF_WIFI_HOST_RPU_MSG_TYPE_DATA:
936 		status = nrf_wifi_fmac_data_events_process(fmac_dev_ctx,
937 							   rpu_msg);
938 		break;
939 	case NRF_WIFI_HOST_RPU_MSG_TYPE_UMAC:
940 		status = umac_event_ctrl_process(fmac_dev_ctx,
941 						 rpu_msg->msg,
942 						 rpu_msg->hdr.len);
943 
944 		if (status != NRF_WIFI_STATUS_SUCCESS) {
945 			nrf_wifi_osal_log_err("%s: umac_event_ctrl_process failed",
946 					      __func__);
947 			goto out;
948 		}
949 		break;
950 	case NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM:
951 		status = umac_event_sys_proc_events(fmac_dev_ctx,
952 						    rpu_msg);
953 		break;
954 	default:
955 		goto out;
956 	}
957 
958 out:
959 	return status;
960 }
961