1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /**
8  * @brief File containing event specific definitions in the
9  * Offloaded raw TX modefor the FMAC IF Layer of the Wi-Fi driver.
10  */
11 
12 #include "queue.h"
13 #include "host_rpu_umac_if.h"
14 #include "common/hal_mem.h"
15 #include "offload_raw_tx/fmac_structs.h"
16 #include "common/fmac_util.h"
umac_event_off_raw_tx_stats_process(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,void * event)17 static enum nrf_wifi_status umac_event_off_raw_tx_stats_process(
18 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
19 	void *event)
20 {
21 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
22 	struct nrf_wifi_off_raw_tx_umac_event_stats *stats = NULL;
23 
24 	if (!event) {
25 		nrf_wifi_osal_log_err("%s: Invalid parameters",
26 				      __func__);
27 		goto out;
28 	}
29 
30 	if (!fmac_dev_ctx->stats_req) {
31 		nrf_wifi_osal_log_err("%s: Stats recd when req was not sent!",
32 				      __func__);
33 		goto out;
34 	}
35 
36 	stats = ((struct nrf_wifi_off_raw_tx_umac_event_stats *)event);
37 
38 	nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fw_stats,
39 			      &stats->fw,
40 			      sizeof(*fmac_dev_ctx->fw_stats));
41 
42 	fmac_dev_ctx->stats_req = false;
43 
44 	status = NRF_WIFI_STATUS_SUCCESS;
45 
46 out:
47 	return status;
48 }
49 
50 
51 
52 
umac_event_off_raw_tx_proc_events(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct host_rpu_msg * rpu_msg)53 static enum nrf_wifi_status umac_event_off_raw_tx_proc_events(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
54 							      struct host_rpu_msg *rpu_msg)
55 {
56 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
57 	unsigned char *sys_head = NULL;
58 	struct nrf_wifi_off_raw_tx_fmac_dev_ctx *dev_ctx_off_raw_tx;
59 	struct nrf_wifi_umac_event_err_status *umac_status;
60 
61 	if (!fmac_dev_ctx || !rpu_msg) {
62 		return status;
63 	}
64 
65 	dev_ctx_off_raw_tx = wifi_dev_priv(fmac_dev_ctx);
66 	sys_head = (unsigned char *)rpu_msg->msg;
67 
68 	switch (((struct nrf_wifi_sys_head *)sys_head)->cmd_event) {
69 	case NRF_WIFI_EVENT_STATS:
70 		status = umac_event_off_raw_tx_stats_process(fmac_dev_ctx,
71 							     sys_head);
72 		break;
73 	case NRF_WIFI_EVENT_INIT_DONE:
74 		fmac_dev_ctx->fw_init_done = 1;
75 		status = NRF_WIFI_STATUS_SUCCESS;
76 		break;
77 	case NRF_WIFI_EVENT_DEINIT_DONE:
78 		fmac_dev_ctx->fw_deinit_done = 1;
79 		status = NRF_WIFI_STATUS_SUCCESS;
80 		break;
81 	case NRF_WIFI_EVENT_OFFLOADED_RAWTX_STATUS:
82 		umac_status = ((struct nrf_wifi_umac_event_err_status *)sys_head);
83 		dev_ctx_off_raw_tx->off_raw_tx_cmd_status = umac_status->status;
84 		dev_ctx_off_raw_tx->off_raw_tx_cmd_done = false;
85 		status = NRF_WIFI_STATUS_SUCCESS;
86 		break;
87 	default:
88 		nrf_wifi_osal_log_err("%s: Unknown event recd: %d",
89 				      __func__,
90 				      ((struct nrf_wifi_sys_head *)sys_head)->cmd_event);
91 		break;
92 	}
93 	return status;
94 }
95 
96 
umac_event_ctrl_process(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,void * event_data,unsigned int event_len)97 static enum nrf_wifi_status umac_event_ctrl_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
98 						    void *event_data,
99 						    unsigned int event_len)
100 {
101 	enum nrf_wifi_status status = NRF_WIFI_STATUS_SUCCESS;
102 	struct nrf_wifi_umac_hdr *umac_hdr = NULL;
103 	struct nrf_wifi_off_raw_tx_fmac_dev_ctx *dev_ctx_off_raw_tx = NULL;
104 	struct nrf_wifi_reg *get_reg_event = NULL;
105 	unsigned char if_id = 0;
106 	unsigned int event_num = 0;
107 
108 	if (!fmac_dev_ctx || !event_data) {
109 		nrf_wifi_osal_log_err("%s: Invalid parameters",
110 				      __func__);
111 		goto out;
112 	}
113 
114 	dev_ctx_off_raw_tx = wifi_dev_priv(fmac_dev_ctx);
115 
116 	umac_hdr = event_data;
117 	if_id = umac_hdr->ids.wdev_id;
118 	event_num = umac_hdr->cmd_evnt;
119 
120 	if (if_id >= MAX_NUM_VIFS) {
121 		nrf_wifi_osal_log_err("%s: Invalid wdev_id recd from UMAC %d",
122 				      __func__,
123 				      if_id);
124 
125 		goto out;
126 	}
127 
128 #ifdef NRF_WIFI_CMD_EVENT_LOG
129 	nrf_wifi_osal_log_info("%s: Event %d received from UMAC\n",
130 			      __func__,
131 			      event_num);
132 #else
133 	nrf_wifi_osal_log_dbg("%s: Event %d received from UMAC",
134 			      __func__,
135 			      event_num);
136 #endif /* NRF_WIFI_CMD_EVENT_LOG */
137 
138 	switch (umac_hdr->cmd_evnt) {
139 	case NRF_WIFI_UMAC_EVENT_GET_REG:
140 		get_reg_event = (struct nrf_wifi_reg *)event_data;
141 
142 		nrf_wifi_osal_mem_cpy(&dev_ctx_off_raw_tx->country_code,
143 				      &get_reg_event->nrf_wifi_alpha2,
144 				      sizeof(get_reg_event->nrf_wifi_alpha2));
145 		fmac_dev_ctx->alpha2_valid = true;
146 		break;
147 	default:
148 		nrf_wifi_osal_log_dbg("%s: No callback registered for event %d",
149 				      __func__,
150 				      umac_hdr->cmd_evnt);
151 		break;
152 	}
153 
154 	nrf_wifi_osal_log_dbg("%s: Event %d processed",
155 			      __func__,
156 			      event_num);
157 
158 out:
159 	return status;
160 }
161 
162 
nrf_wifi_off_raw_tx_fmac_event_callback(void * mac_dev_ctx,void * rpu_event_data,unsigned int rpu_event_len)163 enum nrf_wifi_status nrf_wifi_off_raw_tx_fmac_event_callback(void *mac_dev_ctx,
164 							     void *rpu_event_data,
165 							     unsigned int rpu_event_len)
166 {
167 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
168 	struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
169 	struct host_rpu_msg *rpu_msg = NULL;
170 	struct nrf_wifi_umac_hdr *umac_hdr = NULL;
171 	unsigned int umac_msg_len = 0;
172 	int umac_msg_type = NRF_WIFI_UMAC_EVENT_UNSPECIFIED;
173 
174 	fmac_dev_ctx = (struct nrf_wifi_fmac_dev_ctx *)mac_dev_ctx;
175 
176 	rpu_msg = (struct host_rpu_msg *)rpu_event_data;
177 	umac_hdr = (struct nrf_wifi_umac_hdr *)rpu_msg->msg;
178 	umac_msg_len = rpu_msg->hdr.len;
179 	umac_msg_type = umac_hdr->cmd_evnt;
180 
181 #ifdef NRF_WIFI_CMD_EVENT_LOG
182 	nrf_wifi_osal_log_info("%s: Event type %d recd\n",
183 			      __func__,
184 			      rpu_msg->type);
185 #else
186 	nrf_wifi_osal_log_dbg("%s: Event type %d recd",
187 			      __func__,
188 			      rpu_msg->type);
189 #endif /* NRF_WIFI_CMD_EVENT_LOG */
190 
191 	switch (rpu_msg->type) {
192 	case NRF_WIFI_HOST_RPU_MSG_TYPE_UMAC:
193 		status = umac_event_ctrl_process(fmac_dev_ctx,
194 						 rpu_msg->msg,
195 						 rpu_msg->hdr.len);
196 
197 		if (status != NRF_WIFI_STATUS_SUCCESS) {
198 			nrf_wifi_osal_log_err("%s: umac_event_ctrl_process failed",
199 					      __func__);
200 			goto out;
201 		}
202 		break;
203 	case NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM:
204 		status = umac_event_off_raw_tx_proc_events(fmac_dev_ctx,
205 							   rpu_msg);
206 		break;
207 	default:
208 		goto out;
209 	}
210 
211 out:
212 	return status;
213 }