1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /**
8  * @brief Header containing command specific declarations for the
9  * offloaded raw TX mode in the FMAC IF Layer of the Wi-Fi driver.
10  */
11 
12 #include "offload_raw_tx/fmac_cmd.h"
13 #include "common/hal_api_common.h"
14 
umac_cmd_off_raw_tx_init(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct nrf_wifi_phy_rf_params * rf_params,bool rf_params_valid,int sleep_type,unsigned int phy_calib,enum op_band op_band,bool beamforming,struct nrf_wifi_tx_pwr_ctrl_params * tx_pwr_ctrl_params,struct nrf_wifi_board_params * board_params,unsigned char * country_code)15 enum nrf_wifi_status umac_cmd_off_raw_tx_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
16 					      struct nrf_wifi_phy_rf_params *rf_params,
17 					      bool rf_params_valid,
18 #ifdef NRF_WIFI_LOW_POWER
19 					      int sleep_type,
20 #endif /* NRF_WIFI_LOW_POWER */
21 					      unsigned int phy_calib,
22 					      enum op_band op_band,
23 					      bool beamforming,
24 					      struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl_params,
25 					      struct nrf_wifi_board_params *board_params,
26 					      unsigned char *country_code)
27 {
28 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
29 	struct host_rpu_msg *umac_cmd = NULL;
30 	struct nrf_wifi_cmd_sys_init *umac_cmd_data = NULL;
31 	unsigned int len = 0;
32 
33 	len = sizeof(*umac_cmd_data);
34 
35 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
36 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
37 				  len);
38 
39 	if (!umac_cmd) {
40 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
41 				      __func__);
42 		goto out;
43 	}
44 
45 	umac_cmd_data = (struct nrf_wifi_cmd_sys_init *)(umac_cmd->msg);
46 
47 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_INIT;
48 	umac_cmd_data->sys_head.len = len;
49 
50 
51 	umac_cmd_data->sys_params.rf_params_valid = rf_params_valid;
52 
53 	if (rf_params_valid) {
54 		nrf_wifi_osal_mem_cpy(umac_cmd_data->sys_params.rf_params,
55 				      rf_params,
56 				      NRF_WIFI_RF_PARAMS_SIZE);
57 	}
58 
59 
60 	umac_cmd_data->sys_params.phy_calib = phy_calib;
61 	umac_cmd_data->sys_params.hw_bringup_time = HW_DELAY;
62 	umac_cmd_data->sys_params.sw_bringup_time = SW_DELAY;
63 	umac_cmd_data->sys_params.bcn_time_out = BCN_TIMEOUT;
64 	umac_cmd_data->sys_params.calib_sleep_clk = CALIB_SLEEP_CLOCK_ENABLE;
65 #ifdef NRF_WIFI_LOW_POWER
66 	umac_cmd_data->sys_params.sleep_enable = sleep_type;
67 #endif /* NRF_WIFI_LOW_POWER */
68 #ifdef NRF70_TCP_IP_CHECKSUM_OFFLOAD
69 	umac_cmd_data->tcp_ip_checksum_offload = 1;
70 #endif /* NRF70_TCP_IP_CHECKSUM_OFFLOAD */
71 	umac_cmd_data->discon_timeout = NRF_WIFI_AP_DEAD_DETECT_TIMEOUT;
72 #ifdef NRF_WIFI_RPU_RECOVERY
73 	umac_cmd_data->watchdog_timer_val =
74 		(NRF_WIFI_RPU_RECOVERY_PS_ACTIVE_TIMEOUT_MS) / 1000;
75 #else
76 	/* Disable watchdog */
77 	umac_cmd_data->watchdog_timer_val = 0xFFFFFF;
78 #endif /* NRF_WIFI_RPU_RECOVERY */
79 
80 	nrf_wifi_osal_log_dbg("RPU LPM type: %s",
81 		umac_cmd_data->sys_params.sleep_enable == 2 ? "HW" :
82 		umac_cmd_data->sys_params.sleep_enable == 1 ? "SW" : "DISABLED");
83 
84 #ifdef NRF_WIFI_MGMT_BUFF_OFFLOAD
85 	umac_cmd_data->mgmt_buff_offload =  1;
86 	nrf_wifi_osal_log_info("Management buffer offload enabled\n");
87 #endif /* NRF_WIFI_MGMT_BUFF_OFFLOAD */
88 #ifdef NRF_WIFI_FEAT_KEEPALIVE
89 	umac_cmd_data->keep_alive_enable = KEEP_ALIVE_ENABLED;
90 	umac_cmd_data->keep_alive_period = NRF_WIFI_KEEPALIVE_PERIOD_S;
91 	nrf_wifi_osal_log_dbg("Keepalive enabled with period %d\n",
92 				   umac_cmd_data->keepalive_period);
93 #endif /* NRF_WIFI_FEAT_KEEPALIVE */
94 
95 	umac_cmd_data->op_band = op_band;
96 
97 	nrf_wifi_osal_mem_cpy(&umac_cmd_data->sys_params.rf_params[PCB_LOSS_BYTE_2G_OFST],
98 			      &board_params->pcb_loss_2g,
99 			      NUM_PCB_LOSS_OFFSET);
100 
101 	nrf_wifi_osal_mem_cpy(&umac_cmd_data->sys_params.rf_params[ANT_GAIN_2G_OFST],
102 			      &tx_pwr_ctrl_params->ant_gain_2g,
103 			      NUM_ANT_GAIN);
104 
105 	nrf_wifi_osal_mem_cpy(&umac_cmd_data->sys_params.rf_params[BAND_2G_LW_ED_BKF_DSSS_OFST],
106 			      &tx_pwr_ctrl_params->band_edge_2g_lo_dss,
107 			      NUM_EDGE_BACKOFF);
108 
109 	nrf_wifi_osal_mem_cpy(umac_cmd_data->country_code,
110 			      country_code,
111 			      NRF_WIFI_COUNTRY_CODE_LEN);
112 
113 #ifdef NRF70_RPU_EXTEND_TWT_SP
114 	 umac_cmd_data->feature_flags |= TWT_EXTEND_SP_EDCA;
115 #endif
116 #ifdef CONFIG_WIFI_NRF70_SCAN_DISABLE_DFS_CHANNELS
117 	umac_cmd_data->feature_flags |= DISABLE_DFS_CHANNELS;
118 #endif /* NRF70_SCAN_DISABLE_DFS_CHANNELS */
119 
120 	if (!beamforming) {
121 		umac_cmd_data->disable_beamforming = 1;
122 	}
123 
124 #if defined(NRF_WIFI_PS_INT_PS)
125 	umac_cmd_data->ps_exit_strategy = INT_PS;
126 #else
127 	umac_cmd_data->ps_exit_strategy = EVERY_TIM;
128 #endif  /* NRF_WIFI_PS_INT_PS */
129 
130 	umac_cmd_data->display_scan_bss_limit = NRF_WIFI_DISPLAY_SCAN_BSS_LIMIT;
131 
132 #ifdef NRF_WIFI_COEX_DISABLE_PRIORITY_WINDOW_FOR_SCAN
133 	umac_cmd_data->coex_disable_ptiwin_for_wifi_scan = 1;
134 #else
135 	umac_cmd_data->coex_disable_ptiwin_for_wifi_scan = 0;
136 #endif /* NRF_WIFI_COEX_DISABLE_PRIORITY_WINDOW_FOR_SCAN */
137 
138 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
139 					    umac_cmd,
140 					    (sizeof(*umac_cmd) + len));
141 
142 out:
143 	return status;
144 }
145 
umac_cmd_off_raw_tx_prog_stats_get(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)146 enum nrf_wifi_status umac_cmd_off_raw_tx_prog_stats_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
147 {
148 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
149 	struct host_rpu_msg *umac_cmd = NULL;
150 	struct nrf_wifi_cmd_get_stats *umac_cmd_data = NULL;
151 	int len = 0;
152 
153 	len = sizeof(*umac_cmd_data);
154 
155 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
156 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
157 				  len);
158 
159 	if (!umac_cmd) {
160 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
161 				      __func__);
162 		goto out;
163 	}
164 
165 	umac_cmd_data = (struct nrf_wifi_cmd_get_stats *)(umac_cmd->msg);
166 
167 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_GET_STATS;
168 	umac_cmd_data->sys_head.len = len;
169 	umac_cmd_data->stats_type = RPU_STATS_TYPE_OFFLOADED_RAW_TX;
170 
171 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
172 					    umac_cmd,
173 					    (sizeof(*umac_cmd) + len));
174 
175 out:
176 	return status;
177 }
178 
179 
umac_cmd_off_raw_tx_conf(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct nrf_wifi_offload_ctrl_params * off_ctrl_params,struct nrf_wifi_offload_tx_ctrl * offload_tx_params)180 enum nrf_wifi_status umac_cmd_off_raw_tx_conf(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
181 					      struct nrf_wifi_offload_ctrl_params *off_ctrl_params,
182 					      struct nrf_wifi_offload_tx_ctrl *offload_tx_params)
183 {
184 	struct host_rpu_msg *umac_cmd = NULL;
185 	struct nrf_wifi_cmd_offload_raw_tx_params *umac_cmd_data = NULL;
186 	int len = 0;
187 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
188 
189 	if (!fmac_dev_ctx->fw_init_done) {
190 		nrf_wifi_osal_log_err("%s: UMAC buff config not yet done",__func__);
191 		goto out;
192 	}
193 
194 	if (!off_ctrl_params) {
195 		nrf_wifi_osal_log_err("%s: offloaded raw tx control params is NULL", __func__);
196 		goto out;
197 	}
198 
199 	if (!offload_tx_params) {
200 		nrf_wifi_osal_log_err("%s: offload raw tx params is NULL", __func__);
201 		goto out;
202 	}
203 
204 	len = sizeof(*umac_cmd_data);
205 
206 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
207 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
208 				  len);
209 
210 	if (!umac_cmd) {
211 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed", __func__);
212 		goto out;
213 	}
214 
215 	umac_cmd_data = (struct nrf_wifi_cmd_offload_raw_tx_params *)(umac_cmd->msg);
216 
217 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_OFFLOAD_RAW_TX_PARAMS;
218 	umac_cmd_data->sys_head.len = len;
219 
220 	nrf_wifi_osal_mem_cpy(&umac_cmd_data->ctrl_info,
221 			      off_ctrl_params,
222 			      sizeof(*off_ctrl_params));
223 
224 	nrf_wifi_osal_mem_cpy(&umac_cmd_data->tx_params,
225 			      offload_tx_params,
226 			      sizeof(*offload_tx_params));
227 
228 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
229 					    umac_cmd,
230 					    (sizeof(*umac_cmd) + len));
231 out:
232 	return status;
233 }
234 
umac_cmd_off_raw_tx_ctrl(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned char ctrl_type)235 enum nrf_wifi_status umac_cmd_off_raw_tx_ctrl(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
236 					      unsigned char ctrl_type)
237 {
238 	struct host_rpu_msg *umac_cmd = NULL;
239 	struct nrf_wifi_cmd_offload_raw_tx_ctrl *umac_cmd_data = NULL;
240 	int len = 0;
241 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
242 
243 	if (!fmac_dev_ctx->fw_init_done) {
244 		nrf_wifi_osal_log_err("%s: UMAC buff config not yet done", __func__);
245 		goto out;
246 	}
247 
248 	len = sizeof(*umac_cmd_data);
249 
250 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
251 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
252 				  len);
253 
254 	if (!umac_cmd) {
255 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed", __func__);
256 		goto out;
257 	}
258 
259 	umac_cmd_data = (struct nrf_wifi_cmd_offload_raw_tx_ctrl *)(umac_cmd->msg);
260 
261 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_OFFLOAD_RAW_TX_CTRL;
262 	umac_cmd_data->sys_head.len = len;
263 	umac_cmd_data->ctrl_type = ctrl_type;
264 
265 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
266 					    umac_cmd,
267 					    (sizeof(*umac_cmd) + len));
268 out:
269 	return status;
270 }