1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @brief File containing netowrk stack interface specific definitions for the
9  * Zephyr OS layer of the Wi-Fi driver.
10  */
11 
12 #include <stdlib.h>
13 
14 #ifdef CONFIG_WIFI_RANDOM_MAC_ADDRESS
15 #include <zephyr/random/random.h>
16 #endif
17 
18 #include <zephyr/logging/log.h>
19 LOG_MODULE_DECLARE(wifi_nrf, CONFIG_WIFI_NRF70_LOG_LEVEL);
20 
21 #include <zephyr/sys/reboot.h>
22 
23 #include "net_private.h"
24 
25 #include "util.h"
26 #include "common/fmac_util.h"
27 #include "shim.h"
28 #include "fmac_main.h"
29 #include "wpa_supp_if.h"
30 #include "net_if.h"
31 
32 extern char *net_sprint_ll_addr_buf(const uint8_t *ll, uint8_t ll_len,
33 				    char *buf, int buflen);
34 
35 #ifdef CONFIG_NRF70_STA_MODE
36 static struct net_if_mcast_monitor mcast_monitor;
37 #endif /* CONFIG_NRF70_STA_MODE */
38 
nrf_wifi_set_iface_event_handler(void * os_vif_ctx,struct nrf_wifi_umac_event_set_interface * event,unsigned int event_len)39 void nrf_wifi_set_iface_event_handler(void *os_vif_ctx,
40 						struct nrf_wifi_umac_event_set_interface *event,
41 						unsigned int event_len)
42 {
43 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
44 
45 	if (!os_vif_ctx) {
46 		LOG_ERR("%s: Invalid parameters",
47 			__func__);
48 		goto out;
49 	}
50 
51 	if (!event) {
52 		LOG_ERR("%s: event is NULL",
53 			__func__);
54 		goto out;
55 	}
56 
57 	(void)event_len;
58 
59 	vif_ctx_zep = os_vif_ctx;
60 
61 	vif_ctx_zep->set_if_event_received = true;
62 	vif_ctx_zep->set_if_status = event->return_value;
63 
64 out:
65 	return;
66 }
67 
68 #ifdef CONFIG_NRF_WIFI_RPU_RECOVERY
nrf_wifi_rpu_recovery_work_handler(struct k_work * work)69 static void nrf_wifi_rpu_recovery_work_handler(struct k_work *work)
70 {
71 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = CONTAINER_OF(work,
72 								struct nrf_wifi_vif_ctx_zep,
73 								nrf_wifi_rpu_recovery_work);
74 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
75 	int ret;
76 	bool recovery_fail = false;
77 
78 	if (!vif_ctx_zep) {
79 		LOG_ERR("%s: vif_ctx_zep is NULL", __func__);
80 		return;
81 	}
82 
83 	if (!vif_ctx_zep->zep_net_if_ctx) {
84 		LOG_ERR("%s: zep_net_if_ctx is NULL", __func__);
85 		return;
86 	}
87 
88 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
89 	if (!rpu_ctx_zep || !rpu_ctx_zep->rpu_ctx) {
90 		LOG_ERR("%s: rpu_ctx_zep is NULL", __func__);
91 		return;
92 	}
93 
94 	if (rpu_ctx_zep->rpu_recovery_in_progress) {
95 #ifdef CONFIG_NRF_WIFI_RPU_RECOVERY_DEBUG
96 		LOG_ERR("%s: RPU recovery already in progress", __func__);
97 #else
98 		LOG_DBG("%s: RPU recovery already in progress", __func__);
99 #endif
100 		return;
101 	}
102 
103 	if (rpu_ctx_zep->last_rpu_recovery_time_ms &&
104 		((k_uptime_get() - rpu_ctx_zep->last_rpu_recovery_time_ms) <
105 	    CONFIG_NRF_WIFI_RPU_RECOVERY_QUIET_PERIOD_MS)) {
106 #ifdef CONFIG_NRF_WIFI_RPU_RECOVERY_DEBUG
107 		LOG_ERR("%s: In quiet period (last_rpu_recovery_time_ms=%ld), ignoring",
108 			__func__, rpu_ctx_zep->last_rpu_recovery_time_ms);
109 #else
110 		LOG_DBG("%s: In quiet period (last_rpu_recovery_time_ms=%ld), ignoring",
111 			__func__, rpu_ctx_zep->last_rpu_recovery_time_ms);
112 #endif
113 		return;
114 	}
115 
116 #ifdef CONFIG_NRF_WIFI_RPU_RECOVERY_DEBUG
117 	LOG_ERR("%s: Starting RPU recovery", __func__);
118 #else
119 	LOG_DBG("%s: Starting RPU recovery", __func__);
120 #endif
121 	k_mutex_lock(&rpu_ctx_zep->rpu_lock, K_FOREVER);
122 #if CONFIG_NRF_WIFI_RPU_RECOVERY_MAX_RETRIES > 0
123 	if (!rpu_ctx_zep->last_rpu_recovery_time_ms ||
124 		(k_uptime_get() - rpu_ctx_zep->last_rpu_recovery_time_ms) <
125 	    CONFIG_NRF_WIFI_RPU_RECOVERY_RETRY_WINDOW_S * MSEC_PER_SEC) {
126 		if (rpu_ctx_zep->rpu_recovery_retries >=
127 		    CONFIG_NRF_WIFI_RPU_RECOVERY_MAX_RETRIES) {
128 			LOG_ERR("%s: Maximum recovery retries reached, rebooting system",
129 				__func__);
130 			sys_reboot(SYS_REBOOT_COLD);
131 		}
132 		rpu_ctx_zep->rpu_recovery_retries++;
133 	} else {
134 		rpu_ctx_zep->rpu_recovery_retries = 0;
135 	}
136 #endif
137 	rpu_ctx_zep->rpu_recovery_in_progress = true;
138 #ifdef CONFIG_NRF_WIFI_RPU_RECOVERY_DEBUG
139 	LOG_ERR("%s: Bringing the interface down", __func__);
140 #else
141 	LOG_DBG("%s: Bringing the interface down", __func__);
142 #endif
143 	/* This indirectly does a cold-boot of RPU */
144 	ret = net_if_down(vif_ctx_zep->zep_net_if_ctx);
145 	if (ret) {
146 		rpu_ctx_zep->rpu_recovery_failure++;
147 		recovery_fail = true;
148 		LOG_ERR("%s: net_if_down failed: %d", __func__, ret);
149 		/* Continue with the recovery */
150 	}
151 	k_msleep(CONFIG_NRF_WIFI_RPU_RECOVERY_PROPAGATION_DELAY_MS);
152 #ifdef CONFIG_NRF_WIFI_RPU_RECOVERY_DEBUG
153 	LOG_ERR("%s: Bringing the interface up", __func__);
154 #else
155 	LOG_DBG("%s: Bringing the interface up", __func__);
156 #endif
157 	ret = net_if_up(vif_ctx_zep->zep_net_if_ctx);
158 	if (ret) {
159 		LOG_ERR("%s: net_if_up failed: %d", __func__, ret);
160 	}
161 	rpu_ctx_zep->rpu_recovery_in_progress = false;
162 	rpu_ctx_zep->last_rpu_recovery_time_ms = k_uptime_get();
163 	if (!recovery_fail) {
164 		rpu_ctx_zep->rpu_recovery_success++;
165 	}
166 	k_mutex_unlock(&rpu_ctx_zep->rpu_lock);
167 #ifdef CONFIG_NRF_WIFI_RPU_RECOVERY_DEBUG
168 	LOG_ERR("%s: RPU recovery done", __func__);
169 #else
170 	LOG_DBG("%s: RPU recovery done", __func__);
171 #endif
172 }
173 
nrf_wifi_rpu_recovery_cb(void * vif_ctx_handle,void * event_data,unsigned int event_len)174 void nrf_wifi_rpu_recovery_cb(void *vif_ctx_handle,
175 		void *event_data,
176 		unsigned int event_len)
177 {
178 	struct nrf_wifi_fmac_vif_ctx *vif_ctx = vif_ctx_handle;
179 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
180 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
181 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
182 
183 	if (!vif_ctx) {
184 		LOG_ERR("%s: vif_ctx is NULL",
185 			__func__);
186 		goto out;
187 	}
188 
189 	fmac_dev_ctx = vif_ctx->fmac_dev_ctx;
190 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
191 	if (!sys_dev_ctx) {
192 		LOG_ERR("%s: sys_dev_ctx is NULL",
193 			__func__);
194 		goto out;
195 	}
196 
197 	vif_ctx_zep = vif_ctx->os_vif_ctx;
198 	(void)event_data;
199 
200 	k_work_submit(&vif_ctx_zep->nrf_wifi_rpu_recovery_work);
201 out:
202 	return;
203 }
204 #endif /* CONFIG_NRF_WIFI_RPU_RECOVERY */
205 
206 #ifdef CONFIG_NRF70_DATA_TX
nrf_wifi_net_iface_work_handler(struct k_work * work)207 static void nrf_wifi_net_iface_work_handler(struct k_work *work)
208 {
209 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = CONTAINER_OF(work,
210 								struct nrf_wifi_vif_ctx_zep,
211 								nrf_wifi_net_iface_work);
212 
213 	if (!vif_ctx_zep) {
214 		LOG_ERR("%s: vif_ctx_zep is NULL", __func__);
215 		return;
216 	}
217 
218 	if (!vif_ctx_zep->zep_net_if_ctx) {
219 		LOG_ERR("%s: zep_net_if_ctx is NULL", __func__);
220 		return;
221 	}
222 
223 	if (vif_ctx_zep->if_carr_state == NRF_WIFI_FMAC_IF_CARR_STATE_ON) {
224 		net_if_dormant_off(vif_ctx_zep->zep_net_if_ctx);
225 	} else if (vif_ctx_zep->if_carr_state == NRF_WIFI_FMAC_IF_CARR_STATE_OFF) {
226 		net_if_dormant_on(vif_ctx_zep->zep_net_if_ctx);
227 	}
228 }
229 
230 #if defined(CONFIG_NRF70_RAW_DATA_RX) || defined(CONFIG_NRF70_PROMISC_DATA_RX)
nrf_wifi_if_sniffer_rx_frm(void * os_vif_ctx,void * frm,struct raw_rx_pkt_header * raw_rx_hdr,bool pkt_free)231 void nrf_wifi_if_sniffer_rx_frm(void *os_vif_ctx, void *frm,
232 				struct raw_rx_pkt_header *raw_rx_hdr,
233 				bool pkt_free)
234 {
235 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = os_vif_ctx;
236 	struct net_if *iface = vif_ctx_zep->zep_net_if_ctx;
237 	struct net_pkt *pkt;
238 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
239 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = rpu_ctx_zep->rpu_ctx;
240 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
241 	int ret;
242 
243 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
244 
245 	pkt = net_raw_pkt_from_nbuf(iface, frm, sizeof(struct raw_rx_pkt_header),
246 				    raw_rx_hdr,
247 				    pkt_free);
248 	if (!pkt) {
249 		LOG_DBG("Failed to allocate net_pkt");
250 		return;
251 	}
252 
253 	net_capture_pkt(iface, pkt);
254 
255 	ret = net_recv_data(iface, pkt);
256 	if (ret < 0) {
257 		LOG_DBG("RCV Packet dropped by NET stack: %d", ret);
258 		net_pkt_unref(pkt);
259 	}
260 }
261 #endif /* CONFIG_NRF70_RAW_DATA_RX || CONFIG_NRF70_PROMISC_DATA_RX */
262 
nrf_wifi_if_rx_frm(void * os_vif_ctx,void * frm)263 void nrf_wifi_if_rx_frm(void *os_vif_ctx, void *frm)
264 {
265 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = os_vif_ctx;
266 	struct net_if *iface = vif_ctx_zep->zep_net_if_ctx;
267 	struct net_pkt *pkt;
268 	int status;
269 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
270 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = rpu_ctx_zep->rpu_ctx;
271 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
272 	struct rpu_host_stats *host_stats = NULL;
273 
274 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
275 	host_stats = &sys_dev_ctx->host_stats;
276 	host_stats->total_rx_pkts++;
277 
278 	pkt = net_pkt_from_nbuf(iface, frm);
279 	if (!pkt) {
280 		LOG_DBG("Failed to allocate net_pkt");
281 		host_stats->total_rx_drop_pkts++;
282 		return;
283 	}
284 
285 	status = net_recv_data(iface, pkt);
286 
287 	if (status < 0) {
288 		LOG_DBG("RCV Packet dropped by NET stack: %d", status);
289 		host_stats->total_rx_drop_pkts++;
290 		net_pkt_unref(pkt);
291 	}
292 }
293 
nrf_wifi_if_carr_state_chg(void * os_vif_ctx,enum nrf_wifi_fmac_if_carr_state carr_state)294 enum nrf_wifi_status nrf_wifi_if_carr_state_chg(void *os_vif_ctx,
295 						enum nrf_wifi_fmac_if_carr_state carr_state)
296 {
297 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
298 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
299 
300 	if (!os_vif_ctx) {
301 		LOG_ERR("%s: Invalid parameters",
302 			__func__);
303 		goto out;
304 	}
305 
306 	vif_ctx_zep = os_vif_ctx;
307 
308 	vif_ctx_zep->if_carr_state = carr_state;
309 
310 	LOG_DBG("%s: Carrier state: %d", __func__, carr_state);
311 
312 	k_work_submit(&vif_ctx_zep->nrf_wifi_net_iface_work);
313 
314 	status = NRF_WIFI_STATUS_SUCCESS;
315 
316 out:
317 	return status;
318 }
319 
is_eapol(struct net_pkt * pkt)320 static bool is_eapol(struct net_pkt *pkt)
321 {
322 	struct net_eth_hdr *hdr;
323 	uint16_t ethertype;
324 
325 	hdr = NET_ETH_HDR(pkt);
326 	ethertype = ntohs(hdr->type);
327 
328 	return ethertype == NET_ETH_PTYPE_EAPOL;
329 }
330 #endif /* CONFIG_NRF70_DATA_TX */
331 
nrf_wifi_if_caps_get(const struct device * dev)332 enum ethernet_hw_caps nrf_wifi_if_caps_get(const struct device *dev)
333 {
334 	enum ethernet_hw_caps caps = (ETHERNET_LINK_10BASE_T |
335 			ETHERNET_LINK_100BASE_T | ETHERNET_LINK_1000BASE_T);
336 
337 #ifdef CONFIG_NRF70_TCP_IP_CHECKSUM_OFFLOAD
338 	caps |= ETHERNET_HW_TX_CHKSUM_OFFLOAD |
339 		ETHERNET_HW_RX_CHKSUM_OFFLOAD;
340 #endif /* CONFIG_NRF70_TCP_IP_CHECKSUM_OFFLOAD */
341 
342 #ifdef CONFIG_NRF70_RAW_DATA_TX
343 	caps |= ETHERNET_TXINJECTION_MODE;
344 #endif
345 #ifdef CONFIG_NRF70_PROMISC_DATA_RX
346 	caps |= ETHERNET_PROMISC_MODE;
347 #endif
348 	return caps;
349 }
350 
nrf_wifi_if_send(const struct device * dev,struct net_pkt * pkt)351 int nrf_wifi_if_send(const struct device *dev,
352 		     struct net_pkt *pkt)
353 {
354 	int ret = -1;
355 #ifdef CONFIG_NRF70_DATA_TX
356 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
357 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
358 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
359 	struct rpu_host_stats *host_stats = NULL;
360 	void *nbuf = NULL;
361 
362 	if (!dev || !pkt) {
363 		LOG_ERR("%s: vif_ctx_zep is NULL", __func__);
364 		goto out;
365 	}
366 
367 	vif_ctx_zep = dev->data;
368 
369 	if (!vif_ctx_zep) {
370 		LOG_ERR("%s: vif_ctx_zep is NULL", __func__);
371 		goto out;
372 	}
373 
374 	ret = k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
375 	if (ret != 0) {
376 		LOG_ERR("%s: Failed to lock vif_lock", __func__);
377 		goto out;
378 	}
379 
380 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
381 	if (!rpu_ctx_zep || !rpu_ctx_zep->rpu_ctx) {
382 		goto unlock;
383 	}
384 
385 	sys_dev_ctx = wifi_dev_priv(rpu_ctx_zep->rpu_ctx);
386 	host_stats = &sys_dev_ctx->host_stats;
387 	nbuf = net_pkt_to_nbuf(pkt);
388 	if (!nbuf) {
389 		LOG_DBG("Failed to allocate net_pkt");
390 		host_stats->total_tx_drop_pkts++;
391 		goto out;
392 	}
393 
394 #ifdef CONFIG_NRF70_RAW_DATA_TX
395 	if ((*(unsigned int *)pkt->frags->data) == NRF_WIFI_MAGIC_NUM_RAWTX) {
396 		if (vif_ctx_zep->if_carr_state != NRF_WIFI_FMAC_IF_CARR_STATE_ON) {
397 			goto drop;
398 		}
399 
400 		ret = nrf_wifi_fmac_start_rawpkt_xmit(rpu_ctx_zep->rpu_ctx,
401 						      vif_ctx_zep->vif_idx,
402 						      nbuf);
403 	} else {
404 #endif /* CONFIG_NRF70_RAW_DATA_TX */
405 		if ((vif_ctx_zep->if_carr_state != NRF_WIFI_FMAC_IF_CARR_STATE_ON) ||
406 		    (!vif_ctx_zep->authorized && !is_eapol(pkt))) {
407 			goto drop;
408 		}
409 
410 		ret = nrf_wifi_fmac_start_xmit(rpu_ctx_zep->rpu_ctx,
411 					       vif_ctx_zep->vif_idx,
412 					       nbuf);
413 #ifdef CONFIG_NRF70_RAW_DATA_TX
414 	}
415 #endif /* CONFIG_NRF70_RAW_DATA_TX */
416 	goto unlock;
417 drop:
418 	host_stats->total_tx_drop_pkts++;
419 	nrf_wifi_osal_nbuf_free(nbuf);
420 unlock:
421 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
422 #else
423 	ARG_UNUSED(dev);
424 	ARG_UNUSED(pkt);
425 	goto out;
426 #endif /* CONFIG_NRF70_DATA_TX */
427 
428 out:
429 	return ret;
430 }
431 
432 #ifdef CONFIG_NRF70_STA_MODE
ip_maddr_event_handler(struct net_if * iface,const struct net_addr * addr,bool is_joined)433 static void ip_maddr_event_handler(struct net_if *iface,
434 	const struct net_addr *addr, bool is_joined)
435 {
436 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
437 	struct net_eth_addr mac_addr;
438 	struct nrf_wifi_umac_mcast_cfg *mcast_info = NULL;
439 	enum nrf_wifi_status status;
440 	uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")];
441 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
442 	int ret;
443 
444 	vif_ctx_zep = nrf_wifi_get_vif_ctx(iface);
445 	if (!vif_ctx_zep) {
446 		return;
447 	}
448 
449 	ret = k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
450 	if (ret != 0) {
451 		LOG_ERR("%s: Failed to lock vif_lock", __func__);
452 		return;
453 	}
454 
455 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
456 	if (!rpu_ctx_zep || !rpu_ctx_zep->rpu_ctx) {
457 		LOG_DBG("%s: rpu_ctx_zep or rpu_ctx is NULL",
458 			__func__);
459 		goto unlock;
460 	}
461 
462 	mcast_info = nrf_wifi_osal_mem_zalloc(sizeof(*mcast_info));
463 
464 	if (!mcast_info) {
465 		LOG_ERR("%s: Unable to allocate memory of size %d "
466 			"for mcast_info", __func__, sizeof(*mcast_info));
467 		goto unlock;
468 	}
469 
470 	switch (addr->family) {
471 	case AF_INET:
472 		net_eth_ipv4_mcast_to_mac_addr(&addr->in_addr, &mac_addr);
473 		break;
474 	case AF_INET6:
475 		net_eth_ipv6_mcast_to_mac_addr(&addr->in6_addr, &mac_addr);
476 		break;
477 	default:
478 		LOG_ERR("%s: Invalid address family %d", __func__, addr->family);
479 		break;
480 	}
481 
482 	if (is_joined) {
483 		mcast_info->type = MCAST_ADDR_ADD;
484 	} else {
485 		mcast_info->type = MCAST_ADDR_DEL;
486 	}
487 
488 	memcpy(((char *)(mcast_info->mac_addr)),
489 		   &mac_addr,
490 		   NRF_WIFI_ETH_ADDR_LEN);
491 
492 	status = nrf_wifi_sys_fmac_set_mcast_addr(rpu_ctx_zep->rpu_ctx,
493 					      vif_ctx_zep->vif_idx,
494 					      mcast_info);
495 	if (status == NRF_WIFI_STATUS_FAIL) {
496 		LOG_ERR("%s: nrf_wifi_fmac_set_multicast failed	for"
497 			" mac addr=%s",
498 			__func__,
499 			net_sprint_ll_addr_buf(mac_addr.addr,
500 					       WIFI_MAC_ADDR_LEN, mac_string_buf,
501 					       sizeof(mac_string_buf)));
502 	}
503 unlock:
504 	nrf_wifi_osal_mem_free(mcast_info);
505 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
506 }
507 #endif /* CONFIG_NRF70_STA_MODE */
508 
509 #ifdef CONFIG_WIFI_FIXED_MAC_ADDRESS_ENABLED
510 BUILD_ASSERT(sizeof(CONFIG_WIFI_FIXED_MAC_ADDRESS) - 1 == ((WIFI_MAC_ADDR_LEN * 2) + 5),
511 					"Invalid fixed MAC address length");
512 #endif
513 
nrf_wifi_get_mac_addr(struct nrf_wifi_vif_ctx_zep * vif_ctx_zep)514 enum nrf_wifi_status nrf_wifi_get_mac_addr(struct nrf_wifi_vif_ctx_zep *vif_ctx_zep)
515 {
516 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
517 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
518 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
519 	int ret;
520 
521 	if (!vif_ctx_zep) {
522 		LOG_ERR("%s: vif_ctx_zep is NULL",
523 			__func__);
524 		goto out;
525 	}
526 
527 	ret = k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
528 	if (ret != 0) {
529 		LOG_ERR("%s: Failed to lock vif_lock", __func__);
530 		goto out;
531 	}
532 
533 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
534 	if (!rpu_ctx_zep || !rpu_ctx_zep->rpu_ctx) {
535 		LOG_DBG("%s: rpu_ctx_zep or rpu_ctx is NULL",
536 			__func__);
537 		goto unlock;
538 	}
539 
540 	fmac_dev_ctx = rpu_ctx_zep->rpu_ctx;
541 
542 #ifdef CONFIG_WIFI_FIXED_MAC_ADDRESS_ENABLED
543 	char fixed_mac_addr[WIFI_MAC_ADDR_LEN];
544 
545 	ret = net_bytes_from_str(fixed_mac_addr,
546 			WIFI_MAC_ADDR_LEN,
547 			CONFIG_WIFI_FIXED_MAC_ADDRESS);
548 	if (ret < 0) {
549 		LOG_ERR("%s: Failed to parse MAC address: %s",
550 			__func__,
551 			CONFIG_WIFI_FIXED_MAC_ADDRESS);
552 		goto unlock;
553 	}
554 
555 	memcpy(vif_ctx_zep->mac_addr.addr,
556 		fixed_mac_addr,
557 		WIFI_MAC_ADDR_LEN);
558 #elif CONFIG_WIFI_RANDOM_MAC_ADDRESS
559 	char random_mac_addr[WIFI_MAC_ADDR_LEN];
560 
561 	sys_rand_get(random_mac_addr, WIFI_MAC_ADDR_LEN);
562 	random_mac_addr[0] = (random_mac_addr[0] & UNICAST_MASK) | LOCAL_BIT;
563 
564 	memcpy(vif_ctx_zep->mac_addr.addr,
565 		random_mac_addr,
566 		WIFI_MAC_ADDR_LEN);
567 #elif CONFIG_WIFI_OTP_MAC_ADDRESS
568 	status = nrf_wifi_fmac_otp_mac_addr_get(fmac_dev_ctx,
569 				vif_ctx_zep->vif_idx,
570 				vif_ctx_zep->mac_addr.addr);
571 	if (status != NRF_WIFI_STATUS_SUCCESS) {
572 		LOG_ERR("%s: Fetching of MAC address from OTP failed",
573 			__func__);
574 		goto unlock;
575 	}
576 #endif
577 
578 	if (!nrf_wifi_utils_is_mac_addr_valid(vif_ctx_zep->mac_addr.addr)) {
579 		LOG_ERR("%s: Invalid MAC address: %s",
580 			__func__,
581 			net_sprint_ll_addr(vif_ctx_zep->mac_addr.addr,
582 					WIFI_MAC_ADDR_LEN));
583 		status = NRF_WIFI_STATUS_FAIL;
584 		memset(vif_ctx_zep->mac_addr.addr,
585 			0,
586 			WIFI_MAC_ADDR_LEN);
587 		goto unlock;
588 	}
589 	status = NRF_WIFI_STATUS_SUCCESS;
590 unlock:
591 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
592 out:
593 	return status;
594 }
595 
nrf_wifi_if_init_zep(struct net_if * iface)596 void nrf_wifi_if_init_zep(struct net_if *iface)
597 {
598 	const struct device *dev = NULL;
599 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
600 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
601 	struct ethernet_context *eth_ctx = net_if_l2_data(iface);
602 
603 	if (!iface) {
604 		LOG_ERR("%s: Invalid parameters",
605 			__func__);
606 		return;
607 	}
608 
609 	dev = net_if_get_device(iface);
610 
611 	if (!dev) {
612 		LOG_ERR("%s: Invalid dev",
613 			__func__);
614 		return;
615 	}
616 
617 	vif_ctx_zep = dev->data;
618 
619 	if (!vif_ctx_zep) {
620 		LOG_ERR("%s: vif_ctx_zep is NULL",
621 			__func__);
622 		return;
623 	}
624 
625 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
626 
627 	if (!rpu_ctx_zep) {
628 		LOG_ERR("%s: rpu_ctx_zep is NULL",
629 			__func__);
630 		return;
631 	}
632 
633 	vif_ctx_zep->zep_net_if_ctx = iface;
634 	vif_ctx_zep->zep_dev_ctx = dev;
635 
636 	eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI;
637 	ethernet_init(iface);
638 	net_eth_carrier_on(iface);
639 	net_if_dormant_on(iface);
640 
641 #ifdef CONFIG_NRF70_STA_MODE
642 	net_if_mcast_mon_register(&mcast_monitor, iface, ip_maddr_event_handler);
643 #endif /* CONFIG_NRF70_STA_MODE */
644 #ifdef CONFIG_NRF70_DATA_TX
645 	k_work_init(&vif_ctx_zep->nrf_wifi_net_iface_work,
646 		    nrf_wifi_net_iface_work_handler);
647 #endif /* CONFIG_NRF70_DATA_TX */
648 
649 #ifdef CONFIG_NRF_WIFI_RPU_RECOVERY
650 	k_work_init(&vif_ctx_zep->nrf_wifi_rpu_recovery_work,
651 		    nrf_wifi_rpu_recovery_work_handler);
652 #endif /* CONFIG_NRF_WIFI_RPU_RECOVERY */
653 
654 #if !defined(CONFIG_NRF_WIFI_IF_AUTO_START)
655 	net_if_flag_set(iface, NET_IF_NO_AUTO_START);
656 #endif /* CONFIG_NRF_WIFI_IF_AUTO_START */
657 	net_if_flag_set(iface, NET_IF_NO_TX_LOCK);
658 }
659 
660 /* Board-specific Wi-Fi startup code to run before the Wi-Fi device is started */
nrf_wifi_if_zep_start_board(const struct device * dev)661 __weak int nrf_wifi_if_zep_start_board(const struct device *dev)
662 {
663 	ARG_UNUSED(dev);
664 	return 0;
665 }
666 
667 /* Board-specific Wi-Fi shutdown code to run after the Wi-Fi device is stopped */
nrf_wifi_if_zep_stop_board(const struct device * dev)668 __weak int nrf_wifi_if_zep_stop_board(const struct device *dev)
669 {
670 	ARG_UNUSED(dev);
671 	return 0;
672 }
673 
nrf_wifi_if_start_zep(const struct device * dev)674 int nrf_wifi_if_start_zep(const struct device *dev)
675 {
676 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
677 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
678 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
679 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
680 	struct nrf_wifi_umac_chg_vif_state_info vif_info;
681 	struct nrf_wifi_umac_add_vif_info add_vif_info;
682 	char *mac_addr = NULL;
683 	unsigned int mac_addr_len = 0;
684 	int ret = -1;
685 	bool fmac_dev_added = false;
686 
687 	if (!dev) {
688 		LOG_ERR("%s: Invalid parameters",
689 			__func__);
690 		goto out;
691 	}
692 
693 	if (!device_is_ready(dev)) {
694 		LOG_ERR("%s: Device %s is not ready",
695 			__func__, dev->name);
696 		goto out;
697 	}
698 
699 	ret = nrf_wifi_if_zep_start_board(dev);
700 	if (ret) {
701 		LOG_ERR("nrf_wifi_if_zep_start_board failed with error: %d",
702 			ret);
703 		goto out;
704 	}
705 
706 	vif_ctx_zep = dev->data;
707 
708 	if (!vif_ctx_zep) {
709 		LOG_ERR("%s: vif_ctx_zep is NULL",
710 			__func__);
711 		goto out;
712 	}
713 
714 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
715 
716 	if (!rpu_ctx_zep) {
717 		LOG_ERR("%s: rpu_ctx_zep is NULL",
718 			__func__);
719 		goto out;
720 	}
721 
722 	ret = k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
723 	if (ret != 0) {
724 		LOG_ERR("%s: Failed to lock vif_lock", __func__);
725 		goto out;
726 	}
727 
728 	if (!rpu_ctx_zep->rpu_ctx) {
729 		status = nrf_wifi_fmac_dev_add_zep(&rpu_drv_priv_zep);
730 
731 		if (status != NRF_WIFI_STATUS_SUCCESS) {
732 			LOG_ERR("%s: nrf_wifi_fmac_dev_add_zep failed",
733 				__func__);
734 			goto out;
735 		}
736 		fmac_dev_added = true;
737 		LOG_DBG("%s: FMAC device added", __func__);
738 	}
739 
740 	fmac_dev_ctx = rpu_ctx_zep->rpu_ctx;
741 
742 	memset(&add_vif_info,
743 	       0,
744 	       sizeof(add_vif_info));
745 
746 	/* TODO: This should be configurable */
747 	add_vif_info.iftype = NRF_WIFI_IFTYPE_STATION;
748 
749 	memcpy(add_vif_info.ifacename,
750 	       dev->name,
751 	       strlen(dev->name));
752 
753 	vif_ctx_zep->vif_idx = nrf_wifi_sys_fmac_add_vif(fmac_dev_ctx,
754 						     vif_ctx_zep,
755 						     &add_vif_info);
756 	if (vif_ctx_zep->vif_idx >= MAX_NUM_VIFS) {
757 		LOG_ERR("%s: FMAC returned invalid interface index",
758 			__func__);
759 		goto dev_rem;
760 	}
761 
762 	k_mutex_init(&vif_ctx_zep->vif_lock);
763 	rpu_ctx_zep->vif_ctx_zep[vif_ctx_zep->vif_idx].if_type =
764 		add_vif_info.iftype;
765 
766 	/* Check if user has provided a valid MAC address, if not
767 	 * fetch it from OTP.
768 	 */
769 	mac_addr = net_if_get_link_addr(vif_ctx_zep->zep_net_if_ctx)->addr;
770 	mac_addr_len = net_if_get_link_addr(vif_ctx_zep->zep_net_if_ctx)->len;
771 
772 	if (!nrf_wifi_utils_is_mac_addr_valid(mac_addr)) {
773 		status = nrf_wifi_get_mac_addr(vif_ctx_zep);
774 		if (status != NRF_WIFI_STATUS_SUCCESS) {
775 			LOG_ERR("%s: Failed to get MAC address",
776 				__func__);
777 			goto del_vif;
778 		}
779 		net_if_set_link_addr(vif_ctx_zep->zep_net_if_ctx,
780 					vif_ctx_zep->mac_addr.addr,
781 					WIFI_MAC_ADDR_LEN,
782 					NET_LINK_ETHERNET);
783 		mac_addr = vif_ctx_zep->mac_addr.addr;
784 		mac_addr_len = WIFI_MAC_ADDR_LEN;
785 	}
786 
787 	status = nrf_wifi_sys_fmac_set_vif_macaddr(rpu_ctx_zep->rpu_ctx,
788 					       vif_ctx_zep->vif_idx,
789 					       mac_addr);
790 
791 	if (status != NRF_WIFI_STATUS_SUCCESS) {
792 		LOG_ERR("%s: MAC address change failed",
793 			__func__);
794 		goto del_vif;
795 	}
796 
797 	memset(&vif_info,
798 	       0,
799 	       sizeof(vif_info));
800 
801 	vif_info.state = NRF_WIFI_FMAC_IF_OP_STATE_UP;
802 	vif_info.if_index = vif_ctx_zep->vif_idx;
803 
804 	memcpy(vif_ctx_zep->ifname,
805 	       dev->name,
806 	       strlen(dev->name));
807 
808 	status = nrf_wifi_sys_fmac_chg_vif_state(rpu_ctx_zep->rpu_ctx,
809 					     vif_ctx_zep->vif_idx,
810 					     &vif_info);
811 
812 	if (status != NRF_WIFI_STATUS_SUCCESS) {
813 		LOG_ERR("%s: nrf_wifi_sys_fmac_chg_vif_state failed",
814 			__func__);
815 		goto del_vif;
816 	}
817 
818 #ifdef CONFIG_NRF70_STA_MODE
819 	nrf_wifi_wpa_supp_event_mac_chgd(vif_ctx_zep);
820 
821 #ifdef CONFIG_NRF_WIFI_LOW_POWER
822 	status = nrf_wifi_sys_fmac_set_power_save(rpu_ctx_zep->rpu_ctx,
823 					      vif_ctx_zep->vif_idx,
824 					      NRF_WIFI_PS_ENABLED);
825 
826 	if (status != NRF_WIFI_STATUS_SUCCESS) {
827 		LOG_ERR("%s: nrf_wifi_sys_fmac_set_power_save failed",
828 			__func__);
829 		goto dev_rem;
830 	}
831 #endif /* CONFIG_NRF_WIFI_LOW_POWER */
832 #endif /* CONFIG_NRF70_STA_MODE */
833 
834 	vif_ctx_zep->if_op_state = NRF_WIFI_FMAC_IF_OP_STATE_UP;
835 
836 	ret = 0;
837 
838 	goto out;
839 del_vif:
840 	status = nrf_wifi_sys_fmac_del_vif(rpu_ctx_zep->rpu_ctx, vif_ctx_zep->vif_idx);
841 	if (status != NRF_WIFI_STATUS_SUCCESS) {
842 		LOG_ERR("%s: nrf_wifi_sys_fmac_del_vif failed",
843 			__func__);
844 	}
845 dev_rem:
846 	/* Free only if we added above i.e., for 1st VIF */
847 	if (fmac_dev_added) {
848 		nrf_wifi_fmac_dev_rem_zep(&rpu_drv_priv_zep);
849 	}
850 out:
851 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
852 	return ret;
853 }
854 
855 
nrf_wifi_if_stop_zep(const struct device * dev)856 int nrf_wifi_if_stop_zep(const struct device *dev)
857 {
858 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
859 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
860 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
861 	struct nrf_wifi_umac_chg_vif_state_info vif_info;
862 	int ret = -1;
863 
864 	if (!dev) {
865 		LOG_ERR("%s: Invalid parameters",
866 			__func__);
867 		goto out;
868 	}
869 
870 	vif_ctx_zep = dev->data;
871 
872 	if (!vif_ctx_zep) {
873 		LOG_ERR("%s: vif_ctx_zep is NULL",
874 			__func__);
875 		goto out;
876 	}
877 
878 	ret = k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
879 	if (ret != 0) {
880 		LOG_ERR("%s: Failed to lock vif_lock", __func__);
881 		goto unlock;
882 	}
883 
884 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
885 	if (!rpu_ctx_zep || !rpu_ctx_zep->rpu_ctx) {
886 		LOG_ERR("%s: rpu_ctx_zep is NULL",
887 			__func__);
888 		goto unlock;
889 	}
890 
891 #ifdef CONFIG_NRF70_STA_MODE
892 #ifdef CONFIG_NRF_WIFI_LOW_POWER
893 	status = nrf_wifi_sys_fmac_set_power_save(rpu_ctx_zep->rpu_ctx,
894 					      vif_ctx_zep->vif_idx,
895 					      NRF_WIFI_PS_DISABLED);
896 
897 	if (status != NRF_WIFI_STATUS_SUCCESS) {
898 		LOG_ERR("%s: nrf_wifi_sys_fmac_set_power_save failed",
899 			__func__);
900 	}
901 #endif /* CONFIG_NRF_WIFI_LOW_POWER */
902 #endif /* CONFIG_NRF70_STA_MODE */
903 
904 	memset(&vif_info,
905 	       0,
906 	       sizeof(vif_info));
907 
908 	vif_info.state = NRF_WIFI_FMAC_IF_OP_STATE_DOWN;
909 	vif_info.if_index = vif_ctx_zep->vif_idx;
910 
911 	status = nrf_wifi_sys_fmac_chg_vif_state(rpu_ctx_zep->rpu_ctx,
912 					     vif_ctx_zep->vif_idx,
913 					     &vif_info);
914 
915 	if (status != NRF_WIFI_STATUS_SUCCESS) {
916 		LOG_ERR("%s: nrf_wifi_sys_fmac_chg_vif_state failed",
917 			__func__);
918 	}
919 
920 	status = nrf_wifi_sys_fmac_del_vif(rpu_ctx_zep->rpu_ctx,
921 				       vif_ctx_zep->vif_idx);
922 
923 	if (status != NRF_WIFI_STATUS_SUCCESS) {
924 		LOG_ERR("%s: nrf_wifi_sys_fmac_del_vif failed",
925 			__func__);
926 	}
927 
928 	if (nrf_wifi_fmac_get_num_vifs(rpu_ctx_zep->rpu_ctx) == 0) {
929 		nrf_wifi_fmac_dev_rem_zep(&rpu_drv_priv_zep);
930 	}
931 	ret = 0;
932 unlock:
933 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
934 
935 	ret = nrf_wifi_if_zep_stop_board(dev);
936 	if (ret) {
937 		LOG_ERR("nrf_wifi_if_zep_stop_board failed with error: %d",
938 			ret);
939 	}
940 out:
941 	return ret;
942 }
943 
nrf_wifi_if_get_config_zep(const struct device * dev,enum ethernet_config_type type,struct ethernet_config * config)944 int nrf_wifi_if_get_config_zep(const struct device *dev,
945 			       enum ethernet_config_type type,
946 			       struct ethernet_config *config)
947 {
948 	int ret = -1;
949 #ifdef CONFIG_NRF70_RAW_DATA_TX
950 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
951 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
952 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
953 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
954 
955 	if (!dev || !config) {
956 		LOG_ERR("%s: Invalid parameters",
957 			__func__);
958 		goto out;
959 	}
960 
961 	vif_ctx_zep = dev->data;
962 	if (!vif_ctx_zep) {
963 		LOG_ERR("%s: vif_ctx_zep is NULL",
964 			__func__);
965 		goto out;
966 	}
967 
968 	ret = k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
969 	if (ret != 0) {
970 		LOG_ERR("%s: Failed to lock vif_lock", __func__);
971 		goto out;
972 	}
973 
974 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
975 	if (!rpu_ctx_zep || !rpu_ctx_zep->rpu_ctx) {
976 		LOG_DBG("%s: rpu_ctx_zep or rpu_ctx is NULL",
977 			__func__);
978 		goto unlock;
979 	}
980 	fmac_dev_ctx = rpu_ctx_zep->rpu_ctx;
981 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
982 	if (!sys_dev_ctx) {
983 		LOG_ERR("%s: sys_dev_ctx is NULL",
984 			__func__);
985 		goto unlock;
986 	}
987 
988 	memset(config, 0, sizeof(struct ethernet_config));
989 
990 	if (type == ETHERNET_CONFIG_TYPE_TXINJECTION_MODE) {
991 		config->txinjection_mode =
992 			sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->txinjection_mode;
993 	}
994 #ifdef CONFIG_NRF70_TCP_IP_CHECKSUM_OFFLOAD
995 	if (type  == ETHERNET_CONFIG_TYPE_TX_CHECKSUM_SUPPORT ||
996 	    type == ETHERNET_CONFIG_TYPE_RX_CHECKSUM_SUPPORT) {
997 		config->chksum_support = ETHERNET_CHECKSUM_SUPPORT_IPV4_HEADER |
998 					 ETHERNET_CHECKSUM_SUPPORT_IPV4_ICMP |
999 					 ETHERNET_CHECKSUM_SUPPORT_IPV6_HEADER |
1000 					 ETHERNET_CHECKSUM_SUPPORT_IPV6_ICMP |
1001 					 ETHERNET_CHECKSUM_SUPPORT_TCP |
1002 					 ETHERNET_CHECKSUM_SUPPORT_UDP;
1003 	}
1004 #endif
1005 	ret = 0;
1006 unlock:
1007 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
1008 out:
1009 #endif
1010 	return ret;
1011 }
1012 
nrf_wifi_if_set_config_zep(const struct device * dev,enum ethernet_config_type type,const struct ethernet_config * config)1013 int nrf_wifi_if_set_config_zep(const struct device *dev,
1014 			       enum ethernet_config_type type,
1015 			       const struct ethernet_config *config)
1016 {
1017 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1018 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
1019 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
1020 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1021 	int ret = -1;
1022 
1023 	if (!dev) {
1024 		LOG_ERR("%s: Invalid parameters",
1025 			__func__);
1026 		goto out;
1027 	}
1028 
1029 	vif_ctx_zep = dev->data;
1030 	if (!vif_ctx_zep) {
1031 		LOG_ERR("%s: vif_ctx_zep is NULL",
1032 			__func__);
1033 		goto out;
1034 	}
1035 
1036 	ret = k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
1037 	if (ret != 0) {
1038 		LOG_ERR("%s: Failed to lock vif_lock", __func__);
1039 		goto out;
1040 	}
1041 
1042 	/* Commands without FMAC interaction */
1043 	if (type == ETHERNET_CONFIG_TYPE_MAC_ADDRESS) {
1044 		if (!net_eth_is_addr_valid((struct net_eth_addr *)&config->mac_address)) {
1045 			LOG_ERR("%s: Invalid MAC address",
1046 				__func__);
1047 			goto unlock;
1048 		}
1049 		memcpy(vif_ctx_zep->mac_addr.addr,
1050 		       config->mac_address.addr,
1051 		       sizeof(vif_ctx_zep->mac_addr.addr));
1052 
1053 		net_if_set_link_addr(vif_ctx_zep->zep_net_if_ctx,
1054 				     vif_ctx_zep->mac_addr.addr,
1055 				     sizeof(vif_ctx_zep->mac_addr.addr),
1056 				     NET_LINK_ETHERNET);
1057 		ret = 0;
1058 		goto unlock;
1059 	}
1060 
1061 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
1062 	if (!rpu_ctx_zep || !rpu_ctx_zep->rpu_ctx) {
1063 		LOG_DBG("%s: rpu_ctx_zep or rpu_ctx is NULL",
1064 			__func__);
1065 		goto unlock;
1066 	}
1067 
1068 	fmac_dev_ctx = rpu_ctx_zep->rpu_ctx;
1069 	sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
1070 	if (!sys_dev_ctx) {
1071 		LOG_ERR("%s: sys_dev_ctx is NULL",
1072 			__func__);
1073 		goto unlock;
1074 	}
1075 
1076 #ifdef CONFIG_NRF70_RAW_DATA_TX
1077 	if (type == ETHERNET_CONFIG_TYPE_TXINJECTION_MODE) {
1078 		unsigned char mode;
1079 
1080 		if (sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->txinjection_mode ==
1081 		    config->txinjection_mode) {
1082 			LOG_INF("%s: Driver TX injection setting is same as configured setting",
1083 				__func__);
1084 			goto unlock;
1085 		}
1086 		/**
1087 		 * Since UMAC wishes to use the same mode command as previously
1088 		 * used for mode, `OR` the primary mode with TX-Injection mode and
1089 		 * send it to the UMAC. That way UMAC can still maintain code
1090 		 * as is
1091 		 */
1092 		if (config->txinjection_mode) {
1093 			mode = (sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->mode) |
1094 			       (NRF_WIFI_TX_INJECTION_MODE);
1095 		} else {
1096 			mode = (sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->mode) ^
1097 			       (NRF_WIFI_TX_INJECTION_MODE);
1098 		}
1099 
1100 		ret = nrf_wifi_sys_fmac_set_mode(rpu_ctx_zep->rpu_ctx,
1101 						 vif_ctx_zep->vif_idx, mode);
1102 
1103 		if (ret != NRF_WIFI_STATUS_SUCCESS) {
1104 			LOG_ERR("%s: Mode set operation failed", __func__);
1105 			goto unlock;
1106 		}
1107 	}
1108 #endif
1109 #ifdef CONFIG_NRF70_PROMISC_DATA_RX
1110 	else if (type == ETHERNET_CONFIG_TYPE_PROMISC_MODE) {
1111 		unsigned char mode;
1112 
1113 		if (sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->promisc_mode ==
1114 		    config->promisc_mode) {
1115 			LOG_ERR("%s: Driver promisc mode setting is same as configured setting",
1116 				__func__);
1117 			goto out;
1118 		}
1119 
1120 		if (config->promisc_mode) {
1121 			mode = (sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->mode) |
1122 			       (NRF_WIFI_PROMISCUOUS_MODE);
1123 		} else {
1124 			mode = (sys_dev_ctx->vif_ctx[vif_ctx_zep->vif_idx]->mode) ^
1125 			       (NRF_WIFI_PROMISCUOUS_MODE);
1126 		}
1127 
1128 		ret = nrf_wifi_sys_fmac_set_mode(rpu_ctx_zep->rpu_ctx,
1129 						 vif_ctx_zep->vif_idx, mode);
1130 
1131 		if (ret != NRF_WIFI_STATUS_SUCCESS) {
1132 			LOG_ERR("%s: mode set operation failed", __func__);
1133 			goto out;
1134 		}
1135 	}
1136 #endif
1137 	ret = 0;
1138 unlock:
1139 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
1140 out:
1141 	return ret;
1142 }
1143 
1144 #ifdef CONFIG_NET_STATISTICS_ETHERNET
nrf_wifi_eth_stats_get(const struct device * dev)1145 struct net_stats_eth *nrf_wifi_eth_stats_get(const struct device *dev)
1146 {
1147 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1148 
1149 	if (!dev) {
1150 		LOG_ERR("%s Device not found", __func__);
1151 		goto out;
1152 	}
1153 
1154 	vif_ctx_zep = dev->data;
1155 	if (!vif_ctx_zep) {
1156 		LOG_ERR("%s: vif_ctx_zep is NULL", __func__);
1157 		goto out;
1158 	}
1159 
1160 	return &vif_ctx_zep->eth_stats;
1161 out:
1162 	return NULL;
1163 }
1164 #endif /* CONFIG_NET_STATISTICS_ETHERNET */
1165 
1166 #ifdef CONFIG_NET_STATISTICS_WIFI
nrf_wifi_stats_get(const struct device * dev,struct net_stats_wifi * zstats)1167 int nrf_wifi_stats_get(const struct device *dev, struct net_stats_wifi *zstats)
1168 {
1169 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1170 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
1171 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1172 #ifdef CONFIG_NRF70_RAW_DATA_TX
1173 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1174 #endif /* CONFIG_NRF70_RAW_DATA_TX */
1175 	struct rpu_sys_op_stats stats;
1176 	int ret = -1;
1177 
1178 	if (!dev) {
1179 		LOG_ERR("%s Device not found", __func__);
1180 		goto out;
1181 	}
1182 
1183 	if (!zstats) {
1184 		LOG_ERR("%s Stats buffer not allocated", __func__);
1185 		goto out;
1186 	}
1187 
1188 	vif_ctx_zep = dev->data;
1189 	if (!vif_ctx_zep) {
1190 		LOG_ERR("%s: vif_ctx_zep is NULL", __func__);
1191 		goto out;
1192 	}
1193 
1194 	ret = k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
1195 	if (ret != 0) {
1196 		LOG_ERR("%s: Failed to lock vif_lock", __func__);
1197 		goto out;
1198 	}
1199 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
1200 	if (!rpu_ctx_zep || !rpu_ctx_zep->rpu_ctx) {
1201 		LOG_DBG("%s: rpu_ctx_zep or rpu_ctx is NULL",
1202 			__func__);
1203 		goto unlock;
1204 	}
1205 
1206 	memset(&stats, 0, sizeof(struct rpu_sys_op_stats));
1207 	status = nrf_wifi_sys_fmac_stats_get(rpu_ctx_zep->rpu_ctx, 0, &stats);
1208 	if (status != NRF_WIFI_STATUS_SUCCESS) {
1209 		LOG_ERR("%s: nrf_wifi_fmac_stats_get failed", __func__);
1210 		goto unlock;
1211 	}
1212 
1213 	zstats->pkts.tx = stats.host.total_tx_pkts;
1214 	zstats->pkts.rx = stats.host.total_rx_pkts;
1215 	zstats->errors.tx = stats.host.total_tx_drop_pkts;
1216 	zstats->errors.rx = stats.host.total_rx_drop_pkts +
1217 			stats.fw.umac.interface_data_stats.rx_checksum_error_count;
1218 	zstats->bytes.received = stats.fw.umac.interface_data_stats.rx_bytes;
1219 	zstats->bytes.sent = stats.fw.umac.interface_data_stats.tx_bytes;
1220 	zstats->sta_mgmt.beacons_rx = stats.fw.umac.interface_data_stats.rx_beacon_success_count;
1221 	zstats->sta_mgmt.beacons_miss = stats.fw.umac.interface_data_stats.rx_beacon_miss_count;
1222 	zstats->broadcast.rx = stats.fw.umac.interface_data_stats.rx_broadcast_pkt_count;
1223 	zstats->broadcast.tx = stats.fw.umac.interface_data_stats.tx_broadcast_pkt_count;
1224 	zstats->multicast.rx = stats.fw.umac.interface_data_stats.rx_multicast_pkt_count;
1225 	zstats->multicast.tx = stats.fw.umac.interface_data_stats.tx_multicast_pkt_count;
1226 	zstats->unicast.rx   = stats.fw.umac.interface_data_stats.rx_unicast_pkt_count;
1227 	zstats->unicast.tx   = stats.fw.umac.interface_data_stats.tx_unicast_pkt_count;
1228 	zstats->overrun_count = stats.host.total_tx_drop_pkts + stats.host.total_rx_drop_pkts;
1229 
1230 #ifdef CONFIG_NRF70_RAW_DATA_TX
1231 	sys_dev_ctx = wifi_dev_priv(rpu_ctx_zep->rpu_ctx);
1232 	zstats->errors.tx += sys_dev_ctx->raw_pkt_stats.raw_pkt_send_failure;
1233 #endif /* CONFIG_NRF70_RAW_DATA_TX */
1234 	ret = 0;
1235 unlock:
1236 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
1237 out:
1238 	return ret;
1239 }
1240 
nrf_wifi_stats_reset(const struct device * dev)1241 int nrf_wifi_stats_reset(const struct device *dev)
1242 {
1243 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1244 	struct nrf_wifi_ctx_zep *rpu_ctx_zep = NULL;
1245 	struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
1246 	struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
1247 	int ret = -1;
1248 
1249 	if (!dev) {
1250 		LOG_ERR("%s Device not found", __func__);
1251 		goto out;
1252 	}
1253 
1254 	vif_ctx_zep = dev->data;
1255 	if (!vif_ctx_zep) {
1256 		LOG_ERR("%s: vif_ctx_zep is NULL", __func__);
1257 		goto out;
1258 	}
1259 
1260 	ret = k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
1261 	if (ret != 0) {
1262 		LOG_ERR("%s: Failed to lock vif_lock", __func__);
1263 		goto out;
1264 	}
1265 
1266 	rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
1267 	if (!rpu_ctx_zep || !rpu_ctx_zep->rpu_ctx) {
1268 		LOG_DBG("%s: rpu_ctx_zep or rpu_ctx is NULL",
1269 			__func__);
1270 		goto unlock;
1271 	}
1272 
1273 	status = nrf_wifi_fmac_stats_reset(rpu_ctx_zep->rpu_ctx);
1274 	if (status != NRF_WIFI_STATUS_SUCCESS) {
1275 		LOG_ERR("%s: nrf_wifi_fmac_stats_reset failed", __func__);
1276 		goto unlock;
1277 	}
1278 
1279 	sys_dev_ctx = wifi_dev_priv(rpu_ctx_zep->rpu_ctx);
1280 	memset(&sys_dev_ctx->host_stats, 0, sizeof(struct rpu_host_stats));
1281 
1282 	ret = 0;
1283 unlock:
1284 	k_mutex_unlock(&vif_ctx_zep->vif_lock);
1285 out:
1286 	return ret;
1287 }
1288 #endif /* CONFIG_NET_STATISTICS_WIFI */
1289