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  * system mode in the FMAC IF Layer of the Wi-Fi driver.
10  */
11 
12 #include "system/fmac_structs.h"
13 #include "system/fmac_cmd.h"
14 #include "common/fmac_util.h"
15 #include "common/hal_api_common.h"
16 
umac_cmd_sys_init(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct nrf_wifi_phy_rf_params * rf_params,bool rf_params_valid,struct nrf_wifi_data_config_params * config,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)17 enum nrf_wifi_status umac_cmd_sys_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
18 				       struct nrf_wifi_phy_rf_params *rf_params,
19 				       bool rf_params_valid,
20 				       struct nrf_wifi_data_config_params *config,
21 #ifdef NRF_WIFI_LOW_POWER
22 				       int sleep_type,
23 #endif /* NRF_WIFI_LOW_POWER */
24 				       unsigned int phy_calib,
25 				       enum op_band op_band,
26 				       bool beamforming,
27 				       struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl_params,
28 				       struct nrf_wifi_board_params *board_params,
29 				       unsigned char *country_code)
30 {
31 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
32 	struct host_rpu_msg *umac_cmd = NULL;
33 	struct nrf_wifi_cmd_sys_init *umac_cmd_data = NULL;
34 	unsigned int len = 0;
35 	struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
36 
37 	sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
38 
39 	len = sizeof(*umac_cmd_data);
40 
41 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
42 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
43 				  len);
44 
45 	if (!umac_cmd) {
46 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
47 				      __func__);
48 		goto out;
49 	}
50 
51 	umac_cmd_data = (struct nrf_wifi_cmd_sys_init *)(umac_cmd->msg);
52 
53 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_INIT;
54 	umac_cmd_data->sys_head.len = len;
55 
56 
57 	umac_cmd_data->sys_params.rf_params_valid = rf_params_valid;
58 
59 	if (rf_params_valid) {
60 		nrf_wifi_osal_mem_cpy(umac_cmd_data->sys_params.rf_params,
61 				      rf_params,
62 				      NRF_WIFI_RF_PARAMS_SIZE);
63 	}
64 
65 
66 	umac_cmd_data->sys_params.phy_calib = phy_calib;
67 	umac_cmd_data->sys_params.hw_bringup_time = HW_DELAY;
68 	umac_cmd_data->sys_params.sw_bringup_time = SW_DELAY;
69 	umac_cmd_data->sys_params.bcn_time_out = BCN_TIMEOUT;
70 	umac_cmd_data->sys_params.calib_sleep_clk = CALIB_SLEEP_CLOCK_ENABLE;
71 #ifdef NRF_WIFI_LOW_POWER
72 	umac_cmd_data->sys_params.sleep_enable = sleep_type;
73 #endif /* NRF_WIFI_LOW_POWER */
74 #ifdef NRF70_TCP_IP_CHECKSUM_OFFLOAD
75 	umac_cmd_data->tcp_ip_checksum_offload = 1;
76 #endif /* NRF70_TCP_IP_CHECKSUM_OFFLOAD */
77 	umac_cmd_data->discon_timeout = NRF_WIFI_AP_DEAD_DETECT_TIMEOUT;
78 #ifdef NRF_WIFI_RPU_RECOVERY
79 	umac_cmd_data->watchdog_timer_val =
80 		(NRF_WIFI_RPU_RECOVERY_PS_ACTIVE_TIMEOUT_MS) / 1000;
81 #else
82 	/* Disable watchdog */
83 	umac_cmd_data->watchdog_timer_val = 0xFFFFFF;
84 #endif /* NRF_WIFI_RPU_RECOVERY */
85 
86 	nrf_wifi_osal_log_dbg("RPU LPM type: %s",
87 		umac_cmd_data->sys_params.sleep_enable == 2 ? "HW" :
88 		umac_cmd_data->sys_params.sleep_enable == 1 ? "SW" : "DISABLED");
89 
90 #ifdef NRF_WIFI_MGMT_BUFF_OFFLOAD
91 	umac_cmd_data->mgmt_buff_offload =  1;
92 	nrf_wifi_osal_log_info("Management buffer offload enabled\n");
93 #endif /* NRF_WIFI_MGMT_BUFF_OFFLOAD */
94 #ifdef NRF_WIFI_FEAT_KEEPALIVE
95 	umac_cmd_data->keep_alive_enable = KEEP_ALIVE_ENABLED;
96 	umac_cmd_data->keep_alive_period = NRF_WIFI_KEEPALIVE_PERIOD_S;
97 	nrf_wifi_osal_log_dbg("Keepalive enabled with period %d\n",
98 				   umac_cmd_data->keepalive_period);
99 #endif /* NRF_WIFI_FEAT_KEEPALIVE */
100 
101 	nrf_wifi_osal_mem_cpy(umac_cmd_data->rx_buf_pools,
102 			      sys_fpriv->rx_buf_pools,
103 			      sizeof(umac_cmd_data->rx_buf_pools));
104 
105 	nrf_wifi_osal_mem_cpy(&umac_cmd_data->data_config_params,
106 			      config,
107 			      sizeof(umac_cmd_data->data_config_params));
108 
109 	umac_cmd_data->temp_vbat_config_params.temp_based_calib_en = NRF_WIFI_TEMP_CALIB_ENABLE;
110 	umac_cmd_data->temp_vbat_config_params.temp_calib_bitmap = NRF_WIFI_DEF_PHY_TEMP_CALIB;
111 	umac_cmd_data->temp_vbat_config_params.vbat_calibp_bitmap = NRF_WIFI_DEF_PHY_VBAT_CALIB;
112 	umac_cmd_data->temp_vbat_config_params.temp_vbat_mon_period = NRF_WIFI_TEMP_CALIB_PERIOD;
113 	umac_cmd_data->temp_vbat_config_params.vth_low = NRF_WIFI_VBAT_LOW;
114 	umac_cmd_data->temp_vbat_config_params.vth_hi = NRF_WIFI_VBAT_HIGH;
115 	umac_cmd_data->temp_vbat_config_params.temp_threshold = NRF_WIFI_TEMP_CALIB_THRESHOLD;
116 	umac_cmd_data->temp_vbat_config_params.vth_very_low = NRF_WIFI_VBAT_VERYLOW;
117 
118 	umac_cmd_data->op_band = op_band;
119 
120 	nrf_wifi_osal_mem_cpy(&umac_cmd_data->sys_params.rf_params[PCB_LOSS_BYTE_2G_OFST],
121 			      &board_params->pcb_loss_2g,
122 			      NUM_PCB_LOSS_OFFSET);
123 
124 	nrf_wifi_osal_mem_cpy(&umac_cmd_data->sys_params.rf_params[ANT_GAIN_2G_OFST],
125 			      &tx_pwr_ctrl_params->ant_gain_2g,
126 			      NUM_ANT_GAIN);
127 
128 	nrf_wifi_osal_mem_cpy(&umac_cmd_data->sys_params.rf_params[BAND_2G_LW_ED_BKF_DSSS_OFST],
129 			      &tx_pwr_ctrl_params->band_edge_2g_lo_dss,
130 			      NUM_EDGE_BACKOFF);
131 
132 	nrf_wifi_osal_mem_cpy(umac_cmd_data->country_code,
133 			      country_code,
134 			      NRF_WIFI_COUNTRY_CODE_LEN);
135 
136 #ifdef NRF70_RPU_EXTEND_TWT_SP
137 	 umac_cmd_data->feature_flags |= TWT_EXTEND_SP_EDCA;
138 #endif
139 #ifdef CONFIG_WIFI_NRF70_SCAN_DISABLE_DFS_CHANNELS
140 	umac_cmd_data->feature_flags |= DISABLE_DFS_CHANNELS;
141 #endif /* NRF70_SCAN_DISABLE_DFS_CHANNELS */
142 
143 	if (!beamforming) {
144 		umac_cmd_data->disable_beamforming = 1;
145 	}
146 
147 #if defined(NRF_WIFI_PS_INT_PS)
148 	umac_cmd_data->ps_exit_strategy = INT_PS;
149 #else
150 	umac_cmd_data->ps_exit_strategy = EVERY_TIM;
151 #endif  /* NRF_WIFI_PS_INT_PS */
152 
153 	umac_cmd_data->display_scan_bss_limit = NRF_WIFI_DISPLAY_SCAN_BSS_LIMIT;
154 
155 #ifdef NRF_WIFI_COEX_DISABLE_PRIORITY_WINDOW_FOR_SCAN
156 	umac_cmd_data->coex_disable_ptiwin_for_wifi_scan = 1;
157 #else
158 	umac_cmd_data->coex_disable_ptiwin_for_wifi_scan = 0;
159 #endif /* NRF_WIFI_COEX_DISABLE_PRIORITY_WINDOW_FOR_SCAN */
160 
161 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
162 					    umac_cmd,
163 					    (sizeof(*umac_cmd) + len));
164 
165 out:
166 	return status;
167 }
168 
umac_cmd_sys_prog_stats_get(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)169 enum nrf_wifi_status umac_cmd_sys_prog_stats_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
170 {
171 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
172 	struct host_rpu_msg *umac_cmd = NULL;
173 	struct nrf_wifi_cmd_get_stats *umac_cmd_data = NULL;
174 	int len = 0;
175 
176 	len = sizeof(*umac_cmd_data);
177 
178 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
179 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
180 				  len);
181 
182 	if (!umac_cmd) {
183 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
184 				      __func__);
185 		goto out;
186 	}
187 
188 	umac_cmd_data = (struct nrf_wifi_cmd_get_stats *)(umac_cmd->msg);
189 
190 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_GET_STATS;
191 	umac_cmd_data->sys_head.len = len;
192 	umac_cmd_data->stats_type = RPU_STATS_TYPE_ALL;
193 
194 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
195 					    umac_cmd,
196 					    (sizeof(*umac_cmd) + len));
197 
198 out:
199 	return status;
200 }
201 
202 
umac_cmd_sys_he_ltf_gi(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned char he_ltf,unsigned char he_gi,unsigned char enabled)203 enum nrf_wifi_status umac_cmd_sys_he_ltf_gi(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
204 					    unsigned char he_ltf,
205 					    unsigned char he_gi,
206 					    unsigned char enabled)
207 {
208 	struct host_rpu_msg *umac_cmd = NULL;
209 	struct nrf_wifi_cmd_he_gi_ltf_config *umac_cmd_data = NULL;
210 	int len = 0;
211 	enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
212 
213 	len = sizeof(*umac_cmd_data);
214 
215 	umac_cmd = umac_cmd_alloc(fmac_dev_ctx,
216 				  NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM,
217 				  len);
218 
219 	if (!umac_cmd) {
220 		nrf_wifi_osal_log_err("%s: umac_cmd_alloc failed",
221 				      __func__);
222 		goto out;
223 	}
224 
225 	umac_cmd_data = (struct nrf_wifi_cmd_he_gi_ltf_config *)(umac_cmd->msg);
226 
227 	umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_HE_GI_LTF_CONFIG;
228 	umac_cmd_data->sys_head.len = len;
229 
230 	if (enabled) {
231 		nrf_wifi_osal_mem_cpy(&umac_cmd_data->he_ltf,
232 				      &he_ltf,
233 				      sizeof(he_ltf));
234 		nrf_wifi_osal_mem_cpy(&umac_cmd_data->he_gi_type,
235 				      &he_gi,
236 				      sizeof(he_gi));
237 	}
238 
239 	nrf_wifi_osal_mem_cpy(&umac_cmd_data->enable,
240 			      &enabled,
241 			      sizeof(enabled));
242 
243 	status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx,
244 					    umac_cmd,
245 					    (sizeof(*umac_cmd) + len));
246 out:
247 	return status;
248 }