1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /**
8  * @brief File containing RX data path specific function definitions for the
9  * FMAC IF Layer of the Wi-Fi driver.
10  */
11 
12 #include "system/hal_api.h"
13 #include "system/fmac_rx.h"
14 #include "common/fmac_util.h"
15 #include "system/fmac_promisc.h"
16 
17 static enum nrf_wifi_status
nrf_wifi_fmac_map_desc_to_pool(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned int desc_id,struct nrf_wifi_fmac_rx_pool_map_info * pool_info)18 nrf_wifi_fmac_map_desc_to_pool(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
19 			       unsigned int desc_id,
20 			       struct nrf_wifi_fmac_rx_pool_map_info *pool_info)
21 {
22 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
23 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
24 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
25 	unsigned int pool_id = 0;
26 
27 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
28 	sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
29 
30 	for (pool_id = 0; pool_id < MAX_NUM_OF_RX_QUEUES; pool_id++) {
31 		if ((desc_id >= sys_fpriv->rx_desc[pool_id]) &&
32 		    (desc_id < (sys_fpriv->rx_desc[pool_id] +
33 				sys_fpriv->rx_buf_pools[pool_id].num_bufs))) {
34 			pool_info->pool_id = pool_id;
35 			pool_info->buf_id = (desc_id - sys_fpriv->rx_desc[pool_id]);
36 			status = NRF_WIFI_STATUS_SUCCESS;
37 			goto out;
38 		}
39 	}
40 out:
41 	return status;
42 }
43 
44 #ifdef NRF70_STA_MODE
nrf_wifi_get_skip_header_bytes(unsigned short eth_type)45 int nrf_wifi_get_skip_header_bytes(unsigned short eth_type)
46 {
47 	/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
48 	unsigned char llc_header[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
49 	/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
50 	static unsigned char aarp_ipx_header[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
51 	int skip_header_bytes = 0;
52 
53 	skip_header_bytes = sizeof(eth_type);
54 
55 	if (eth_type == NRF_WIFI_FMAC_ETH_P_AARP ||
56 	    eth_type == NRF_WIFI_FMAC_ETH_P_IPX) {
57 		skip_header_bytes += sizeof(aarp_ipx_header);
58 	} else if (eth_type >= NRF_WIFI_FMAC_ETH_P_802_3_MIN) {
59 		skip_header_bytes += sizeof(llc_header);
60 	}
61 
62 	return skip_header_bytes;
63 }
64 
nrf_wifi_convert_amsdu_to_eth(void * nwb)65 static void nrf_wifi_convert_amsdu_to_eth(void *nwb)
66 {
67 	struct nrf_wifi_fmac_eth_hdr *ehdr = NULL;
68 	struct nrf_wifi_fmac_amsdu_hdr amsdu_hdr;
69 	unsigned int len = 0;
70 	unsigned short eth_type = 0;
71 	void *nwb_data = NULL;
72 	unsigned char amsdu_hdr_len = 0;
73 
74 	amsdu_hdr_len = sizeof(struct nrf_wifi_fmac_amsdu_hdr);
75 
76 	nrf_wifi_osal_mem_cpy(&amsdu_hdr,
77 			      nrf_wifi_osal_nbuf_data_get(nwb),
78 			      amsdu_hdr_len);
79 
80 	nwb_data = (unsigned char *)nrf_wifi_osal_nbuf_data_get(nwb) + amsdu_hdr_len;
81 
82 	eth_type = nrf_wifi_util_rx_get_eth_type(nwb_data);
83 
84 	nrf_wifi_osal_nbuf_data_pull(nwb,
85 				     (amsdu_hdr_len +
86 				      nrf_wifi_get_skip_header_bytes(eth_type)));
87 
88 	len = nrf_wifi_osal_nbuf_data_size(nwb);
89 
90 	ehdr = (struct nrf_wifi_fmac_eth_hdr *)
91 		nrf_wifi_osal_nbuf_data_push(nwb,
92 					     sizeof(struct nrf_wifi_fmac_eth_hdr));
93 
94 	nrf_wifi_osal_mem_cpy(ehdr->src,
95 			      amsdu_hdr.src,
96 			      NRF_WIFI_FMAC_ETH_ADDR_LEN);
97 
98 	nrf_wifi_osal_mem_cpy(ehdr->dst,
99 			      amsdu_hdr.dst,
100 			      NRF_WIFI_FMAC_ETH_ADDR_LEN);
101 
102 	if (eth_type >= NRF_WIFI_FMAC_ETH_P_802_3_MIN) {
103 		ehdr->proto = ((eth_type >> 8) | (eth_type << 8));
104 	} else {
105 		ehdr->proto = len;
106 	}
107 }
108 
nrf_wifi_convert_to_eth(void * nwb,struct nrf_wifi_fmac_ieee80211_hdr * hdr,unsigned short eth_type)109 static void nrf_wifi_convert_to_eth(void *nwb,
110 				    struct nrf_wifi_fmac_ieee80211_hdr *hdr,
111 				    unsigned short eth_type)
112 {
113 
114 	struct nrf_wifi_fmac_eth_hdr *ehdr = NULL;
115 	unsigned int len = 0;
116 
117 	len = nrf_wifi_osal_nbuf_data_size(nwb);
118 
119 	ehdr = (struct nrf_wifi_fmac_eth_hdr *)
120 		nrf_wifi_osal_nbuf_data_push(nwb,
121 					     sizeof(struct nrf_wifi_fmac_eth_hdr));
122 
123 	switch (hdr->fc & (NRF_WIFI_FCTL_TODS | NRF_WIFI_FCTL_FROMDS)) {
124 	case (NRF_WIFI_FCTL_TODS | NRF_WIFI_FCTL_FROMDS):
125 		nrf_wifi_osal_mem_cpy(ehdr->src,
126 				      hdr->addr_4,
127 				      NRF_WIFI_FMAC_ETH_ADDR_LEN);
128 
129 		nrf_wifi_osal_mem_cpy(ehdr->dst,
130 				      hdr->addr_1,
131 				      NRF_WIFI_FMAC_ETH_ADDR_LEN);
132 		break;
133 	case (NRF_WIFI_FCTL_FROMDS):
134 		nrf_wifi_osal_mem_cpy(ehdr->src,
135 				      hdr->addr_3,
136 				      NRF_WIFI_FMAC_ETH_ADDR_LEN);
137 		nrf_wifi_osal_mem_cpy(ehdr->dst,
138 				      hdr->addr_1,
139 				      NRF_WIFI_FMAC_ETH_ADDR_LEN);
140 		break;
141 	case (NRF_WIFI_FCTL_TODS):
142 		nrf_wifi_osal_mem_cpy(ehdr->src,
143 				      hdr->addr_2,
144 				      NRF_WIFI_FMAC_ETH_ADDR_LEN);
145 		nrf_wifi_osal_mem_cpy(ehdr->dst,
146 				      hdr->addr_3,
147 				      NRF_WIFI_FMAC_ETH_ADDR_LEN);
148 		break;
149 	default:
150 		/* Both FROM and TO DS bit is zero*/
151 		nrf_wifi_osal_mem_cpy(ehdr->src,
152 				      hdr->addr_2,
153 				      NRF_WIFI_FMAC_ETH_ADDR_LEN);
154 		nrf_wifi_osal_mem_cpy(ehdr->dst,
155 				      hdr->addr_1,
156 				      NRF_WIFI_FMAC_ETH_ADDR_LEN);
157 
158 	}
159 
160 	if (eth_type >= NRF_WIFI_FMAC_ETH_P_802_3_MIN) {
161 		ehdr->proto = ((eth_type >> 8) | (eth_type << 8));
162 	} else {
163 		ehdr->proto = len;
164 	}
165 }
166 #endif /* NRF70_STA_MODE */
167 
nrf_wifi_fmac_rx_cmd_send(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,enum nrf_wifi_fmac_rx_cmd_type cmd_type,unsigned int desc_id)168 enum nrf_wifi_status nrf_wifi_fmac_rx_cmd_send(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
169 					       enum nrf_wifi_fmac_rx_cmd_type cmd_type,
170 					       unsigned int desc_id)
171 {
172 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
173 	struct nrf_wifi_fmac_buf_map_info *rx_buf_info = NULL;
174 	struct host_rpu_rx_buf_info rx_cmd;
175 	struct nrf_wifi_fmac_rx_pool_map_info pool_info;
176 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
177 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
178 	unsigned long nwb = 0;
179 	unsigned long nwb_data = 0;
180 	unsigned long phy_addr = 0;
181 	unsigned int buf_len = 0;
182 
183 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
184 	sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
185 
186 	status = nrf_wifi_fmac_map_desc_to_pool(fmac_dev_ctx,
187 						desc_id,
188 						&pool_info);
189 
190 	if (status != NRF_WIFI_STATUS_SUCCESS) {
191 		nrf_wifi_osal_log_err("%s: nrf_wifi_fmac_map_desc_to_pool failed",
192 				      __func__);
193 		goto out;
194 	}
195 
196 	rx_buf_info = &sys_dev_ctx->rx_buf_info[desc_id];
197 
198 	buf_len = sys_fpriv->rx_buf_pools[pool_info.pool_id].buf_sz + RX_BUF_HEADROOM;
199 
200 	if (cmd_type == NRF_WIFI_FMAC_RX_CMD_TYPE_INIT) {
201 		if (rx_buf_info->mapped) {
202 			nrf_wifi_osal_log_err("%s: RX init called for mapped RX buffer(%d)",
203 					      __func__,
204 					      desc_id);
205 			status = NRF_WIFI_STATUS_FAIL;
206 			goto out;
207 		}
208 
209 		nwb = (unsigned long)nrf_wifi_osal_nbuf_alloc(buf_len);
210 
211 		if (!nwb) {
212 			nrf_wifi_osal_log_err("%s: No space for allocating RX buffer",
213 					      __func__);
214 			status = NRF_WIFI_STATUS_FAIL;
215 			goto out;
216 		}
217 
218 		nwb_data = (unsigned long)nrf_wifi_osal_nbuf_data_get((void *)nwb);
219 
220 		*(unsigned int *)(nwb_data) = desc_id;
221 
222 		phy_addr = nrf_wifi_sys_hal_buf_map_rx(fmac_dev_ctx->hal_dev_ctx,
223 						       nwb_data,
224 						       buf_len,
225 						       pool_info.pool_id,
226 						       pool_info.buf_id);
227 
228 		if (!phy_addr) {
229 			nrf_wifi_osal_log_err("%s: nrf_wifi_sys_hal_buf_map_rx failed",
230 					      __func__);
231 			status = NRF_WIFI_STATUS_FAIL;
232 			goto out;
233 		}
234 
235 		rx_buf_info->nwb = nwb;
236 		rx_buf_info->mapped = true;
237 
238 		nrf_wifi_osal_mem_set(&rx_cmd,
239 				      0x0,
240 				      sizeof(rx_cmd));
241 
242 		rx_cmd.addr = (unsigned int)phy_addr;
243 
244 		status = nrf_wifi_sys_hal_data_cmd_send(fmac_dev_ctx->hal_dev_ctx,
245 							NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_RX,
246 							&rx_cmd,
247 							sizeof(rx_cmd),
248 							desc_id,
249 							pool_info.pool_id);
250 	} else if (cmd_type == NRF_WIFI_FMAC_RX_CMD_TYPE_DEINIT) {
251 		/* TODO: Need to initialize a command and send it to LMAC
252 		 * when LMAC is capable of handling deinit command
253 		 */
254 		if (!rx_buf_info->mapped) {
255 			nrf_wifi_osal_log_err("%s: RX deinit called for unmapped RX buffer(%d)",
256 					      __func__,
257 					      desc_id);
258 			status = NRF_WIFI_STATUS_FAIL;
259 			goto out;
260 		}
261 
262 		nwb_data = nrf_wifi_sys_hal_buf_unmap_rx(fmac_dev_ctx->hal_dev_ctx,
263 							 0,
264 							 pool_info.pool_id,
265 							 pool_info.buf_id);
266 
267 		if (!nwb_data) {
268 			nrf_wifi_osal_log_err("%s: nrf_wifi_sys_hal_buf_unmap_rx failed",
269 					      __func__);
270 			goto out;
271 		}
272 
273 		nrf_wifi_osal_nbuf_free((void *)rx_buf_info->nwb);
274 		rx_buf_info->nwb = 0;
275 		rx_buf_info->mapped = false;
276 		status = NRF_WIFI_STATUS_SUCCESS;
277 	} else {
278 		nrf_wifi_osal_log_err("%s: Unknown cmd_type (%d)",
279 				      __func__,
280 				      cmd_type);
281 		goto out;
282 	}
283 out:
284 	return status;
285 }
286 
287 
288 #ifdef NRF70_RX_WQ_ENABLED
nrf_wifi_fmac_rx_tasklet(void * data)289 void nrf_wifi_fmac_rx_tasklet(void *data)
290 {
291 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = (struct nrf_wifi_fmac_dev_ctx *)data;
292 	struct nrf_wifi_rx_buff *config = NULL;
293 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
294 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
295 	enum NRF_WIFI_HAL_STATUS hal_status;
296 
297 	nrf_wifi_sys_hal_lock_rx(fmac_dev_ctx->hal_dev_ctx);
298 	hal_status = nrf_wifi_hal_status_unlocked(fmac_dev_ctx->hal_dev_ctx);
299 	if (hal_status != NRF_WIFI_HAL_STATUS_ENABLED) {
300 		goto out;
301 	}
302 
303 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
304 
305 	config = (struct nrf_wifi_rx_buff *)nrf_wifi_utils_q_dequeue(
306 		sys_dev_ctx->rx_tasklet_event_q);
307 
308 	if (!config) {
309 		nrf_wifi_osal_log_err("%s: No RX config available",
310 				      __func__);
311 		goto out;
312 	}
313 
314 	status = nrf_wifi_fmac_rx_event_process(fmac_dev_ctx,
315 						config);
316 
317 	if (status != NRF_WIFI_STATUS_SUCCESS) {
318 		nrf_wifi_osal_log_err("%s: nrf_wifi_fmac_rx_event_process failed",
319 				      __func__);
320 		goto out;
321 	}
322 out:
323 	nrf_wifi_osal_mem_free(config);
324 	nrf_wifi_sys_hal_unlock_rx(fmac_dev_ctx->hal_dev_ctx);
325 }
326 #endif /* NRF70_RX_WQ_ENABLED */
327 
nrf_wifi_fmac_rx_event_process(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct nrf_wifi_rx_buff * config)328 enum nrf_wifi_status nrf_wifi_fmac_rx_event_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
329 						    struct nrf_wifi_rx_buff *config)
330 {
331 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
332 	struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
333 	struct nrf_wifi_fmac_buf_map_info *rx_buf_info = NULL;
334 	struct nrf_wifi_fmac_rx_pool_map_info pool_info;
335 #if defined(NRF70_RAW_DATA_RX) || defined(NRF70_PROMISC_DATA_RX)
336 	struct raw_rx_pkt_header raw_rx_hdr;
337 #if defined(NRF70_PROMISC_DATA_RX)
338 	unsigned short frame_control;
339 #endif
340 #endif /* NRF70_RAW_DATA_RX || NRF70_PROMISC_DATA_RX */
341 	void *nwb = NULL;
342 	void *nwb_data = NULL;
343 	unsigned int num_pkts = 0;
344 	unsigned int desc_id = 0;
345 	unsigned int i = 0;
346 	unsigned int pkt_len = 0;
347 #ifdef NRF70_STA_MODE
348 	struct nrf_wifi_fmac_ieee80211_hdr hdr;
349 	unsigned short eth_type = 0;
350 	unsigned int size = 0;
351 #endif /* NRF70_STA_MODE */
352 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
353 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
354 
355 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
356 	sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
357 
358 	vif_ctx = sys_dev_ctx->vif_ctx[config->wdev_id];
359 
360 #ifdef NRF70_STA_MODE
361 	if (config->rx_pkt_type != NRF_WIFI_RAW_RX_PKT) {
362 		sys_fpriv->callbk_fns.process_rssi_from_rx(vif_ctx->os_vif_ctx,
363 							  config->signal);
364 	}
365 #endif /* NRF70_STA_MODE */
366 	num_pkts = config->rx_pkt_cnt;
367 
368 	for (i = 0; i < num_pkts; i++) {
369 		desc_id = config->rx_buff_info[i].descriptor_id;
370 		pkt_len = config->rx_buff_info[i].rx_pkt_len;
371 
372 		if (desc_id >= sys_fpriv->num_rx_bufs) {
373 			nrf_wifi_osal_log_err("%s: Invalid desc_id %d",
374 					      __func__,
375 					      desc_id);
376 			status = NRF_WIFI_STATUS_FAIL;
377 			continue;
378 		}
379 
380 		status = nrf_wifi_fmac_map_desc_to_pool(fmac_dev_ctx,
381 							desc_id,
382 							&pool_info);
383 
384 		if (status != NRF_WIFI_STATUS_SUCCESS) {
385 			nrf_wifi_osal_log_err("%s: nrf_wifi_fmac_map_desc_to_pool failed",
386 					      __func__);
387 			status = NRF_WIFI_STATUS_FAIL;
388 			continue;
389 		}
390 
391 		nwb_data = (void *)nrf_wifi_sys_hal_buf_unmap_rx(fmac_dev_ctx->hal_dev_ctx,
392 								 pkt_len,
393 								 pool_info.pool_id,
394 								 pool_info.buf_id);
395 
396 		if (!nwb_data) {
397 			nrf_wifi_osal_log_err("%s: nrf_wifi_sys_hal_buf_unmap_rx failed",
398 					      __func__);
399 			status = NRF_WIFI_STATUS_FAIL;
400 			continue;
401 		}
402 
403 		rx_buf_info = &sys_dev_ctx->rx_buf_info[desc_id];
404 		nwb = (void *)rx_buf_info->nwb;
405 
406 		nrf_wifi_osal_nbuf_data_put(nwb,
407 					    pkt_len + RX_BUF_HEADROOM);
408 		nrf_wifi_osal_nbuf_data_pull(nwb,
409 					     RX_BUF_HEADROOM);
410 		nwb_data = nrf_wifi_osal_nbuf_data_get(nwb);
411 
412 		rx_buf_info->nwb = 0;
413 		rx_buf_info->mapped = false;
414 
415 #ifdef NRF70_PROMISC_DATA_RX
416 		nrf_wifi_osal_mem_cpy(&frame_control,
417 				      nwb_data,
418 				      sizeof(unsigned short));
419 #endif
420 
421 		if (config->rx_pkt_type == NRF_WIFI_RX_PKT_DATA) {
422 #ifdef NRF70_PROMISC_DATA_RX
423 			if (vif_ctx->promisc_mode) {
424 				raw_rx_hdr.frequency = config->frequency;
425 				raw_rx_hdr.signal = config->signal;
426 				raw_rx_hdr.rate_flags = config->rate_flags;
427 				raw_rx_hdr.rate = config->rate;
428 				if (nrf_wifi_util_check_filt_setting(vif_ctx, &frame_control)) {
429 					sys_fpriv->callbk_fns.sniffer_callbk_fn(vif_ctx->os_vif_ctx,
430 									       nwb,
431 									       &raw_rx_hdr,
432 									       false);
433 				}
434 			}
435 #endif
436 #ifdef NRF70_STA_MODE
437 			switch (config->rx_buff_info[i].pkt_type) {
438 			case PKT_TYPE_MPDU:
439 				nrf_wifi_osal_mem_cpy(&hdr,
440 						      nwb_data,
441 						      sizeof(struct nrf_wifi_fmac_ieee80211_hdr));
442 
443 				eth_type = nrf_wifi_util_rx_get_eth_type(((char *)nwb_data +
444 								 config->mac_header_len));
445 
446 				size = config->mac_header_len +
447 					nrf_wifi_get_skip_header_bytes(eth_type);
448 
449 				/* Remove hdr len and llc header/length */
450 				nrf_wifi_osal_nbuf_data_pull(nwb,
451 							     size);
452 
453 				nrf_wifi_convert_to_eth(nwb,
454 							&hdr,
455 							eth_type);
456 				break;
457 			case PKT_TYPE_MSDU_WITH_MAC:
458 				nrf_wifi_osal_nbuf_data_pull(nwb,
459 							     config->mac_header_len);
460 
461 				nrf_wifi_convert_amsdu_to_eth(nwb);
462 				break;
463 			case PKT_TYPE_MSDU:
464 				nrf_wifi_convert_amsdu_to_eth(nwb);
465 				break;
466 			default:
467 				nrf_wifi_osal_log_err("%s: Invalid pkt_type=%d",
468 						      __func__,
469 						      (config->rx_buff_info[i].pkt_type));
470 				status = NRF_WIFI_STATUS_FAIL;
471 				continue;
472 			}
473 			sys_fpriv->callbk_fns.rx_frm_callbk_fn(vif_ctx->os_vif_ctx,
474 									 nwb);
475 #endif /* NRF70_STA_MODE */
476 		} else if (config->rx_pkt_type == NRF_WIFI_RX_PKT_BCN_PRB_RSP) {
477 #ifdef WIFI_MGMT_RAW_SCAN_RESULTS
478 			sys_fpriv->callbk_fns.rx_bcn_prb_resp_callbk_fn(
479 							vif_ctx->os_vif_ctx,
480 							nwb,
481 							config->frequency,
482 							config->signal);
483 #endif /* WIFI_MGMT_RAW_SCAN_RESULTS */
484 			nrf_wifi_osal_nbuf_free(nwb);
485 #ifdef NRF_WIFI_MGMT_BUFF_OFFLOAD
486 			continue;
487 #endif /* NRF_WIFI_MGMT_BUFF_OFFLOAD */
488 		}
489 #if defined(NRF70_RAW_DATA_RX) || defined(NRF70_PROMISC_DATA_RX)
490 		else if (config->rx_pkt_type == NRF_WIFI_RAW_RX_PKT) {
491 			raw_rx_hdr.frequency = config->frequency;
492 			raw_rx_hdr.signal = config->signal;
493 			raw_rx_hdr.rate_flags = config->rate_flags;
494 			raw_rx_hdr.rate = config->rate;
495 #if defined(NRF70_PROMISC_DATA_RX)
496 			if (nrf_wifi_util_check_filt_setting(vif_ctx, &frame_control))
497 #endif
498 			{
499 				sys_fpriv->callbk_fns.sniffer_callbk_fn(vif_ctx->os_vif_ctx,
500 								       nwb,
501 								       &raw_rx_hdr,
502 								       true);
503 			}
504 #if defined(NRF70_PROMISC_DATA_RX)
505 			/**
506 			 * In the case of Monitor mode, the sniffer callback function
507 			 * will free the packet. For promiscuous mode, if the packet
508 			 * is not meant to be sent up the stack, the packet needs
509 			 * to be freed here.
510 			 */
511 			else {
512 				nrf_wifi_osal_nbuf_free(nwb);
513 			}
514 #endif
515 		}
516 #endif /* NRF70_RAW_DATA_RX || NRF70_PROMISC_DATA_RX */
517 		else {
518 			nrf_wifi_osal_log_err("%s: Invalid frame type received %d",
519 					      __func__,
520 					      config->rx_pkt_type);
521 			status = NRF_WIFI_STATUS_FAIL;
522 			nrf_wifi_osal_nbuf_free(nwb);
523 			continue;
524 		}
525 
526 		status = nrf_wifi_fmac_rx_cmd_send(fmac_dev_ctx,
527 						   NRF_WIFI_FMAC_RX_CMD_TYPE_INIT,
528 						   desc_id);
529 
530 		if (status != NRF_WIFI_STATUS_SUCCESS) {
531 			nrf_wifi_osal_log_err("%s: nrf_wifi_fmac_rx_cmd_send failed",
532 					      __func__);
533 			continue;
534 		}
535 	}
536 
537 	/* A single failure returns failure for the entire event */
538 	return status;
539 }
540