1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /**
8 * @brief File containing API definitions for the
9 * FMAC IF Layer of the Wi-Fi driver.
10 */
11
12 #include "host_rpu_umac_if.h"
13 #include "radio_test/fmac_api.h"
14 #include "radio_test/hal_api.h"
15 #include "radio_test/fmac_structs.h"
16 #include "common/fmac_util.h"
17 #include "radio_test/fmac_cmd.h"
18 #include "radio_test/fmac_event.h"
19 #include "util.h"
20
21 #define RADIO_CMD_STATUS_TIMEOUT 5000
22
23
nrf_wifi_rt_fmac_fw_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,struct nrf_wifi_board_params * board_params,unsigned char * country_code)24 static enum nrf_wifi_status nrf_wifi_rt_fmac_fw_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
25 struct nrf_wifi_phy_rf_params *rf_params,
26 bool rf_params_valid,
27 #ifdef NRF_WIFI_LOW_POWER
28 int sleep_type,
29 #endif /* NRF_WIFI_LOW_POWER */
30 unsigned int phy_calib,
31 enum op_band op_band,
32 bool beamforming,
33 struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl,
34 struct nrf_wifi_board_params *board_params,
35 unsigned char *country_code)
36 {
37 unsigned long start_time_us = 0;
38 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
39
40 if (!fmac_dev_ctx) {
41 nrf_wifi_osal_log_err("%s: Invalid device context",
42 __func__);
43 goto out;
44 }
45
46 status = umac_cmd_rt_init(fmac_dev_ctx,
47 rf_params,
48 rf_params_valid,
49 #ifdef NRF_WIFI_LOW_POWER
50 sleep_type,
51 #endif /* NRF_WIFI_LOWPOWER */
52 phy_calib,
53 op_band,
54 beamforming,
55 tx_pwr_ctrl,
56 board_params,
57 country_code);
58
59 if (status != NRF_WIFI_STATUS_SUCCESS) {
60 nrf_wifi_osal_log_err("%s: UMAC init failed",
61 __func__);
62 goto out;
63 }
64 start_time_us = nrf_wifi_osal_time_get_curr_us();
65 while (!fmac_dev_ctx->fw_init_done) {
66 nrf_wifi_osal_sleep_ms(1);
67 #define MAX_INIT_WAIT (5 * 1000 * 1000)
68 if (nrf_wifi_osal_time_elapsed_us(start_time_us) >= MAX_INIT_WAIT) {
69 break;
70 }
71 }
72
73 if (!fmac_dev_ctx->fw_init_done) {
74 nrf_wifi_osal_log_err("%s: UMAC init timed out",
75 __func__);
76 status = NRF_WIFI_STATUS_FAIL;
77 goto out;
78 }
79
80 status = NRF_WIFI_STATUS_SUCCESS;
81
82 out:
83 return status;
84 }
85
nrf_wifi_rt_fmac_fw_deinit(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)86 static void nrf_wifi_rt_fmac_fw_deinit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
87 {
88 }
89
nrf_wifi_rt_fmac_dev_add(struct nrf_wifi_fmac_priv * fpriv,void * os_dev_ctx)90 struct nrf_wifi_fmac_dev_ctx *nrf_wifi_rt_fmac_dev_add(struct nrf_wifi_fmac_priv *fpriv,
91 void *os_dev_ctx)
92 {
93 struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
94 struct nrf_wifi_rt_fmac_dev_ctx *rt_fmac_dev_ctx = NULL;
95
96
97 if (!fpriv || !os_dev_ctx) {
98 return NULL;
99 }
100
101 if (fpriv->op_mode != NRF_WIFI_OP_MODE_RT) {
102 nrf_wifi_osal_log_err("%s: Invalid op mode",
103 __func__);
104 goto out;
105 }
106
107 fmac_dev_ctx = nrf_wifi_osal_mem_zalloc(sizeof(*fmac_dev_ctx) + sizeof(*rt_fmac_dev_ctx));
108
109 if (!fmac_dev_ctx) {
110 nrf_wifi_osal_log_err("%s: Unable to allocate fmac_dev_ctx",
111 __func__);
112 goto out;
113 }
114
115 fmac_dev_ctx->fpriv = fpriv;
116 fmac_dev_ctx->os_dev_ctx = os_dev_ctx;
117
118 fmac_dev_ctx->hal_dev_ctx = nrf_wifi_rt_hal_dev_add(fpriv->hpriv,
119 fmac_dev_ctx);
120
121 if (!fmac_dev_ctx->hal_dev_ctx) {
122 nrf_wifi_osal_log_err("%s: nrf_wifi_rt_hal_dev_add failed",
123 __func__);
124
125 nrf_wifi_osal_mem_free(fmac_dev_ctx);
126 fmac_dev_ctx = NULL;
127 goto out;
128 }
129
130 fmac_dev_ctx->op_mode = NRF_WIFI_OP_MODE_RT;
131
132 out:
133 return fmac_dev_ctx;
134 }
135
136
nrf_wifi_rt_fmac_dev_init(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,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_tx_pwr_ceil_params * tx_pwr_ceil_params,struct nrf_wifi_board_params * board_params,unsigned char * country_code)137 enum nrf_wifi_status nrf_wifi_rt_fmac_dev_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
138 #ifdef NRF_WIFI_LOW_POWER
139 int sleep_type,
140 #endif /* NRF_WIFI_LOW_POWER */
141 unsigned int phy_calib,
142 enum op_band op_band,
143 bool beamforming,
144 struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl_params,
145 struct nrf_wifi_tx_pwr_ceil_params *tx_pwr_ceil_params,
146 struct nrf_wifi_board_params *board_params,
147 unsigned char *country_code)
148 {
149 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
150 struct nrf_wifi_fmac_otp_info otp_info;
151 struct nrf_wifi_phy_rf_params phy_rf_params;
152
153 if (!fmac_dev_ctx) {
154 nrf_wifi_osal_log_err("%s: Invalid device context",
155 __func__);
156 goto out;
157 }
158
159 if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_RT) {
160 nrf_wifi_osal_log_err("%s: Invalid op mode",
161 __func__);
162 goto out;
163 }
164
165 status = nrf_wifi_hal_dev_init(fmac_dev_ctx->hal_dev_ctx);
166
167 if (status != NRF_WIFI_STATUS_SUCCESS) {
168 nrf_wifi_osal_log_err("%s: nrf_wifi_hal_dev_init failed",
169 __func__);
170 goto out;
171 }
172
173 fmac_dev_ctx->tx_pwr_ceil_params = nrf_wifi_osal_mem_alloc(sizeof(*tx_pwr_ceil_params));
174 nrf_wifi_osal_mem_cpy(fmac_dev_ctx->tx_pwr_ceil_params,
175 tx_pwr_ceil_params,
176 sizeof(*tx_pwr_ceil_params));
177
178 nrf_wifi_osal_mem_set(&otp_info,
179 0xFF,
180 sizeof(otp_info));
181
182 status = nrf_wifi_hal_otp_info_get(fmac_dev_ctx->hal_dev_ctx,
183 &otp_info.info,
184 &otp_info.flags);
185
186 if (status != NRF_WIFI_STATUS_SUCCESS) {
187 nrf_wifi_osal_log_err("%s: Fetching of RPU OTP information failed",
188 __func__);
189 goto out;
190 }
191
192 status = nrf_wifi_rt_fmac_rf_params_get(fmac_dev_ctx,
193 &phy_rf_params);
194
195 if (status != NRF_WIFI_STATUS_SUCCESS) {
196 nrf_wifi_osal_log_err("%s: RF parameters get failed",
197 __func__);
198 goto out;
199 }
200
201 status = nrf_wifi_rt_fmac_fw_init(fmac_dev_ctx,
202 &phy_rf_params,
203 true,
204 #ifdef NRF_WIFI_LOW_POWER
205 sleep_type,
206 #endif /* NRF_WIFI_LOW_POWER */
207 phy_calib,
208 op_band,
209 beamforming,
210 tx_pwr_ctrl_params,
211 board_params,
212 country_code);
213
214 if (status == NRF_WIFI_STATUS_FAIL) {
215 nrf_wifi_osal_log_err("%s: nrf_wifi_sys_fmac_fw_init failed",
216 __func__);
217 goto out;
218 }
219 out:
220 return status;
221 }
222
nrf_wifi_rt_fmac_dev_deinit(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)223 void nrf_wifi_rt_fmac_dev_deinit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
224 {
225 if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_RT) {
226 nrf_wifi_osal_log_err("%s: Invalid op mode",
227 __func__);
228 return;
229 }
230
231 nrf_wifi_osal_mem_free(fmac_dev_ctx->tx_pwr_ceil_params);
232 nrf_wifi_rt_fmac_fw_deinit(fmac_dev_ctx);
233 }
234
nrf_wifi_rt_fmac_init(void)235 struct nrf_wifi_fmac_priv *nrf_wifi_rt_fmac_init(void)
236 {
237 struct nrf_wifi_fmac_priv *fpriv = NULL;
238 struct nrf_wifi_hal_cfg_params hal_cfg_params;
239
240 fpriv = nrf_wifi_osal_mem_zalloc(sizeof(*fpriv));
241
242 if (!fpriv) {
243 nrf_wifi_osal_log_err("%s: Unable to allocate fpriv",
244 __func__);
245 goto out;
246 }
247
248 nrf_wifi_osal_mem_set(&hal_cfg_params,
249 0,
250 sizeof(hal_cfg_params));
251
252
253 hal_cfg_params.max_cmd_size = MAX_NRF_WIFI_UMAC_CMD_SIZE;
254 hal_cfg_params.max_event_size = MAX_EVENT_POOL_LEN;
255
256 fpriv->hpriv = nrf_wifi_hal_init(&hal_cfg_params,
257 &nrf_wifi_rt_fmac_event_callback,
258 NULL);
259
260 if (!fpriv->hpriv) {
261 nrf_wifi_osal_log_err("%s: Unable to do HAL init",
262 __func__);
263 nrf_wifi_osal_mem_free(fpriv);
264 fpriv = NULL;
265 goto out;
266 }
267
268 fpriv->op_mode = NRF_WIFI_OP_MODE_RT;
269 out:
270 return fpriv;
271 }
272
273
wait_for_radio_cmd_status(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned int timeout)274 static enum nrf_wifi_status wait_for_radio_cmd_status(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
275 unsigned int timeout)
276 {
277 unsigned int count = 0;
278 enum nrf_wifi_cmd_status radio_cmd_status;
279 struct nrf_wifi_rt_fmac_dev_ctx *rt_dev_ctx = NULL;
280
281 rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
282 do {
283 nrf_wifi_osal_sleep_ms(1);
284 count++;
285 } while ((!rt_dev_ctx->radio_cmd_done) &&
286 (count < timeout));
287
288 if (count == timeout) {
289 nrf_wifi_osal_log_err("%s: Timed out (%d secs)",
290 __func__,
291 timeout / 1000);
292 goto out;
293 }
294
295 radio_cmd_status = rt_dev_ctx->radio_cmd_status;
296
297 if (radio_cmd_status != NRF_WIFI_UMAC_CMD_SUCCESS) {
298 nrf_wifi_osal_log_err("%s: Radio test command failed with status %d",
299 __func__,
300 radio_cmd_status);
301 goto out;
302 }
303 return NRF_WIFI_STATUS_SUCCESS;
304
305 out:
306 return NRF_WIFI_STATUS_FAIL;
307 }
308
nrf_wifi_rt_fmac_radio_test_init(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct rpu_conf_params * params)309 enum nrf_wifi_status nrf_wifi_rt_fmac_radio_test_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
310 struct rpu_conf_params *params)
311 {
312 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
313 struct nrf_wifi_radio_test_init_info init_params;
314 struct nrf_wifi_rt_fmac_dev_ctx *rt_dev_ctx = NULL;
315
316 if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_RT) {
317 nrf_wifi_osal_log_err("%s: Invalid op mode",
318 __func__);
319 goto out;
320 }
321
322 rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
323
324 nrf_wifi_osal_mem_set(&init_params,
325 0,
326 sizeof(init_params));
327
328 nrf_wifi_osal_mem_cpy(init_params.rf_params,
329 params->rf_params,
330 NRF_WIFI_RF_PARAMS_SIZE);
331
332 nrf_wifi_osal_mem_cpy(&init_params.chan,
333 ¶ms->chan,
334 sizeof(init_params.chan));
335
336 init_params.phy_threshold = params->phy_threshold;
337 init_params.phy_calib = params->phy_calib;
338
339 rt_dev_ctx->radio_cmd_done = false;
340 status = umac_cmd_rt_prog_init(fmac_dev_ctx,
341 &init_params);
342
343 if (status != NRF_WIFI_STATUS_SUCCESS) {
344 nrf_wifi_osal_log_err("%s: Unable to init radio test",
345 __func__);
346 goto out;
347 }
348
349 status = wait_for_radio_cmd_status(fmac_dev_ctx,
350 RADIO_CMD_STATUS_TIMEOUT);
351 if (status != NRF_WIFI_STATUS_SUCCESS) {
352 goto out;
353 }
354
355 out:
356 return status;
357 }
358
359
nrf_wifi_rt_fmac_prog_tx(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct rpu_conf_params * params)360 enum nrf_wifi_status nrf_wifi_rt_fmac_prog_tx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
361 struct rpu_conf_params *params)
362 {
363 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
364 struct nrf_wifi_rt_fmac_dev_ctx *rt_dev_ctx = NULL;
365
366 if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_RT) {
367 nrf_wifi_osal_log_err("%s: Invalid op mode",
368 __func__);
369 goto out;
370 }
371
372 rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
373
374 rt_dev_ctx->radio_cmd_done = false;
375 status = umac_cmd_rt_prog_tx(fmac_dev_ctx,
376 params);
377
378 if (status != NRF_WIFI_STATUS_SUCCESS) {
379 nrf_wifi_osal_log_err("%s: Unable to program radio test TX",
380 __func__);
381 goto out;
382 }
383
384 status = wait_for_radio_cmd_status(fmac_dev_ctx,
385 RADIO_CMD_STATUS_TIMEOUT);
386 if (status != NRF_WIFI_STATUS_SUCCESS) {
387 goto out;
388 }
389 out:
390 return status;
391 }
392
393
nrf_wifi_rt_fmac_prog_rx(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct rpu_conf_params * params)394 enum nrf_wifi_status nrf_wifi_rt_fmac_prog_rx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
395 struct rpu_conf_params *params)
396 {
397 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
398 struct rpu_conf_rx_radio_test_params rx_params;
399 struct nrf_wifi_rt_fmac_dev_ctx *rt_dev_ctx = NULL;
400
401 if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_RT) {
402 nrf_wifi_osal_log_err("%s: Invalid op mode",
403 __func__);
404 goto out;
405 }
406
407 rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
408
409 nrf_wifi_osal_mem_set(&rx_params,
410 0,
411 sizeof(rx_params));
412
413 rx_params.nss = params->nss;
414
415 nrf_wifi_osal_mem_cpy(rx_params.rf_params,
416 params->rf_params,
417 NRF_WIFI_RF_PARAMS_SIZE);
418
419 nrf_wifi_osal_mem_cpy(&rx_params.chan,
420 ¶ms->chan,
421 sizeof(rx_params.chan));
422
423 rx_params.phy_threshold = params->phy_threshold;
424 rx_params.phy_calib = params->phy_calib;
425 rx_params.rx = params->rx;
426
427 rt_dev_ctx->radio_cmd_done = false;
428 status = umac_cmd_rt_prog_rx(fmac_dev_ctx,
429 &rx_params);
430
431 if (status != NRF_WIFI_STATUS_SUCCESS) {
432 nrf_wifi_osal_log_err("%s: Unable to program radio test RX",
433 __func__);
434 goto out;
435 }
436
437 status = wait_for_radio_cmd_status(fmac_dev_ctx,
438 RADIO_CMD_STATUS_TIMEOUT);
439 if (status != NRF_WIFI_STATUS_SUCCESS) {
440 goto out;
441 }
442 out:
443 return status;
444 }
445
446
nrf_wifi_rt_fmac_rf_test_rx_cap(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,enum nrf_wifi_rf_test rf_test_type,void * cap_data,unsigned short int num_samples,unsigned short int capture_timeout,unsigned char lna_gain,unsigned char bb_gain,unsigned char * capture_status)447 enum nrf_wifi_status nrf_wifi_rt_fmac_rf_test_rx_cap(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
448 enum nrf_wifi_rf_test rf_test_type,
449 void *cap_data,
450 unsigned short int num_samples,
451 unsigned short int capture_timeout ,
452 unsigned char lna_gain,
453 unsigned char bb_gain,
454 unsigned char *capture_status)
455 {
456 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
457 struct nrf_wifi_rf_test_capture_params rf_test_cap_params;
458 struct nrf_wifi_rt_fmac_dev_ctx *rt_dev_ctx = NULL;
459 unsigned int count = 0;
460
461 if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_RT) {
462 nrf_wifi_osal_log_err("%s: Invalid op mode",
463 __func__);
464 goto out;
465 }
466
467 rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
468
469 nrf_wifi_osal_mem_set(&rf_test_cap_params,
470 0,
471 sizeof(rf_test_cap_params));
472
473 rf_test_cap_params.test = rf_test_type;
474 rf_test_cap_params.cap_len = num_samples;
475 rf_test_cap_params.cap_time = capture_timeout;
476 rf_test_cap_params.lna_gain = lna_gain;
477 rf_test_cap_params.bb_gain = bb_gain;
478
479 rt_dev_ctx->rf_test_type = rf_test_type;
480 rt_dev_ctx->rf_test_cap_data = cap_data;
481 rt_dev_ctx->rf_test_cap_sz = (num_samples * 3);
482 rt_dev_ctx->capture_status = 0;
483
484 status = umac_cmd_rt_prog_rf_test(fmac_dev_ctx,
485 &rf_test_cap_params,
486 sizeof(rf_test_cap_params));
487
488 if (status != NRF_WIFI_STATUS_SUCCESS) {
489 nrf_wifi_osal_log_err("%s: umac_cmd_rt_prog_rf_test_cap failed",
490 __func__);
491
492 goto out;
493 }
494
495 do {
496 nrf_wifi_osal_sleep_ms(100);
497 count++;
498 } while ((rt_dev_ctx->rf_test_type != NRF_WIFI_RF_TEST_MAX) &&
499 (count < (RX_CAPTURE_TIMEOUT_CONST * capture_timeout)));
500
501 if (count == (RX_CAPTURE_TIMEOUT_CONST * capture_timeout)) {
502 nrf_wifi_osal_log_err("%s: Timed out",
503 __func__);
504 rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_MAX;
505 rt_dev_ctx->rf_test_cap_data = NULL;
506 status = NRF_WIFI_STATUS_FAIL;
507 goto out;
508 }
509 *capture_status = rt_dev_ctx->capture_status;
510
511 out:
512 return status;
513 }
514
515
nrf_wifi_rt_fmac_rf_test_tx_tone(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned char enable,signed char tone_freq,signed char tx_power)516 enum nrf_wifi_status nrf_wifi_rt_fmac_rf_test_tx_tone(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
517 unsigned char enable,
518 signed char tone_freq,
519 signed char tx_power)
520 {
521 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
522 struct nrf_wifi_rf_test_tx_params rf_test_tx_params;
523 struct nrf_wifi_rt_fmac_dev_ctx *rt_dev_ctx = NULL;
524 unsigned int count = 0;
525
526 if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_RT) {
527 nrf_wifi_osal_log_err("%s: Invalid op mode",
528 __func__);
529 goto out;
530 }
531
532 rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
533
534 nrf_wifi_osal_mem_set(&rf_test_tx_params,
535 0,
536 sizeof(rf_test_tx_params));
537
538 rf_test_tx_params.test = NRF_WIFI_RF_TEST_TX_TONE;
539 rf_test_tx_params.tone_freq = tone_freq;
540 rf_test_tx_params.tx_pow = tx_power;
541 rf_test_tx_params.enabled = enable;
542
543 rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_TX_TONE;
544 rt_dev_ctx->rf_test_cap_data = NULL;
545 rt_dev_ctx->rf_test_cap_sz = 0;
546
547 status = umac_cmd_rt_prog_rf_test(fmac_dev_ctx,
548 &rf_test_tx_params,
549 sizeof(rf_test_tx_params));
550
551 if (status != NRF_WIFI_STATUS_SUCCESS) {
552 nrf_wifi_osal_log_err("%s: umac_cmd_rt_prog_rf_test_tx_tone failed",
553 __func__);
554
555 goto out;
556 }
557
558 do {
559 nrf_wifi_osal_sleep_ms(100);
560 count++;
561 } while ((rt_dev_ctx->rf_test_type != NRF_WIFI_RF_TEST_MAX) &&
562 (count < NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT));
563
564 if (count == NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT) {
565 nrf_wifi_osal_log_err("%s: Timed out",
566 __func__);
567 rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_MAX;
568 rt_dev_ctx->rf_test_cap_data = NULL;
569 status = NRF_WIFI_STATUS_FAIL;
570 goto out;
571 }
572
573 out:
574 return status;
575 }
576
577
nrf_wifi_rt_fmac_rf_test_dpd(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned char enable)578 enum nrf_wifi_status nrf_wifi_rt_fmac_rf_test_dpd(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
579 unsigned char enable)
580 {
581 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
582 struct nrf_wifi_rf_test_dpd_params rf_test_dpd_params;
583 struct nrf_wifi_rt_fmac_dev_ctx *rt_dev_ctx = NULL;
584 unsigned int count = 0;
585
586 if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_RT) {
587 nrf_wifi_osal_log_err("%s: Invalid op mode",
588 __func__);
589 goto out;
590 }
591
592 rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
593
594 nrf_wifi_osal_mem_set(&rf_test_dpd_params,
595 0,
596 sizeof(rf_test_dpd_params));
597
598 rf_test_dpd_params.test = NRF_WIFI_RF_TEST_DPD;
599 rf_test_dpd_params.enabled = enable;
600
601 rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_DPD;
602 rt_dev_ctx->rf_test_cap_data = NULL;
603 rt_dev_ctx->rf_test_cap_sz = 0;
604
605 status = umac_cmd_rt_prog_rf_test(fmac_dev_ctx,
606 &rf_test_dpd_params,
607 sizeof(rf_test_dpd_params));
608
609 if (status != NRF_WIFI_STATUS_SUCCESS) {
610 nrf_wifi_osal_log_err("%s: umac_cmd_rt_prog_rf_test_dpd failed",
611 __func__);
612
613 goto out;
614 }
615
616 do {
617 nrf_wifi_osal_sleep_ms(100);
618 count++;
619 } while ((rt_dev_ctx->rf_test_type != NRF_WIFI_RF_TEST_MAX) &&
620 (count < NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT));
621
622 if (count == NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT) {
623 nrf_wifi_osal_log_err("%s: Timed out",
624 __func__);
625 rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_MAX;
626 rt_dev_ctx->rf_test_cap_data = NULL;
627 status = NRF_WIFI_STATUS_FAIL;
628 goto out;
629 }
630
631 out:
632 return status;
633 }
634
635
nrf_wifi_rt_fmac_rf_get_temp(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)636 enum nrf_wifi_status nrf_wifi_rt_fmac_rf_get_temp(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
637 {
638 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
639 struct nrf_wifi_temperature_params rf_test_get_temperature;
640 struct nrf_wifi_rt_fmac_dev_ctx *rt_dev_ctx = NULL;
641 unsigned int count = 0;
642
643 if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_RT) {
644 nrf_wifi_osal_log_err("%s: Invalid op mode",
645 __func__);
646 goto out;
647 }
648
649 rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
650
651 nrf_wifi_osal_mem_set(&rf_test_get_temperature,
652 0,
653 sizeof(rf_test_get_temperature));
654
655 rf_test_get_temperature.test = NRF_WIFI_RF_TEST_GET_TEMPERATURE;
656
657 rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_GET_TEMPERATURE;
658 rt_dev_ctx->rf_test_cap_data = NULL;
659 rt_dev_ctx->rf_test_cap_sz = 0;
660
661 status = umac_cmd_rt_prog_rf_test(fmac_dev_ctx,
662 &rf_test_get_temperature,
663 sizeof(rf_test_get_temperature));
664
665 if (status != NRF_WIFI_STATUS_SUCCESS) {
666 nrf_wifi_osal_log_err("%s: umac_cmd_rt_prog_rf_get_temperature failed",
667 __func__);
668
669 goto out;
670 }
671
672 do {
673 nrf_wifi_osal_sleep_ms(100);
674 count++;
675 } while ((rt_dev_ctx->rf_test_type != NRF_WIFI_RF_TEST_MAX) &&
676 (count < NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT));
677
678 if (count == NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT) {
679 nrf_wifi_osal_log_err("%s: Timed out",
680 __func__);
681 rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_MAX;
682 rt_dev_ctx->rf_test_cap_data = NULL;
683 status = NRF_WIFI_STATUS_FAIL;
684 goto out;
685 }
686
687 out:
688 return status;
689 }
690
nrf_wifi_rt_fmac_rf_get_rf_rssi(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)691 enum nrf_wifi_status nrf_wifi_rt_fmac_rf_get_rf_rssi(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
692 {
693 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
694 struct nrf_wifi_rf_get_rf_rssi rf_get_rf_rssi_params;
695 struct nrf_wifi_rt_fmac_dev_ctx *rt_dev_ctx = NULL;
696 unsigned int count = 0;
697
698 if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_RT) {
699 nrf_wifi_osal_log_err("%s: Invalid op mode",
700 __func__);
701 goto out;
702 }
703
704 rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
705
706 nrf_wifi_osal_mem_set(&rf_get_rf_rssi_params,
707 0,
708 sizeof(rf_get_rf_rssi_params));
709
710 rf_get_rf_rssi_params.test = NRF_WIFI_RF_TEST_RF_RSSI;
711 rf_get_rf_rssi_params.lna_gain = 3;
712 rf_get_rf_rssi_params.bb_gain = 10;
713
714 rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_RF_RSSI;
715 rt_dev_ctx->rf_test_cap_data = NULL;
716 rt_dev_ctx->rf_test_cap_sz = 0;
717
718 status = umac_cmd_rt_prog_rf_test(fmac_dev_ctx,
719 &rf_get_rf_rssi_params,
720 sizeof(rf_get_rf_rssi_params));
721
722 if (status != NRF_WIFI_STATUS_SUCCESS) {
723 nrf_wifi_osal_log_err("%s: umac_cmd_rt_prog_rf_get_rf_rssi failed",
724 __func__);
725
726 goto out;
727 }
728
729 do {
730 nrf_wifi_osal_sleep_ms(100);
731 count++;
732 } while ((rt_dev_ctx->rf_test_type != NRF_WIFI_RF_TEST_MAX) &&
733 (count < NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT));
734
735 if (count == NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT) {
736 nrf_wifi_osal_log_err("%s: Timed out",
737 __func__);
738 rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_MAX;
739 rt_dev_ctx->rf_test_cap_data = NULL;
740 status = NRF_WIFI_STATUS_FAIL;
741 goto out;
742 }
743
744 out:
745 return status;
746 }
747
748
nrf_wifi_rt_fmac_set_xo_val(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned char value)749 enum nrf_wifi_status nrf_wifi_rt_fmac_set_xo_val(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
750 unsigned char value)
751 {
752 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
753 struct nrf_wifi_rf_test_xo_calib nrf_wifi_rf_test_xo_calib_params;
754 struct nrf_wifi_rt_fmac_dev_ctx *rt_dev_ctx = NULL;
755 unsigned int count = 0;
756
757 if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_RT) {
758 nrf_wifi_osal_log_err("%s: Invalid op mode",
759 __func__);
760 goto out;
761 }
762
763 rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
764
765 nrf_wifi_osal_mem_set(&nrf_wifi_rf_test_xo_calib_params,
766 0,
767 sizeof(nrf_wifi_rf_test_xo_calib_params));
768
769 nrf_wifi_rf_test_xo_calib_params.test = NRF_WIFI_RF_TEST_XO_CALIB;
770 nrf_wifi_rf_test_xo_calib_params.xo_val = value;
771
772
773 rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_XO_CALIB;
774 rt_dev_ctx->rf_test_cap_data = NULL;
775 rt_dev_ctx->rf_test_cap_sz = 0;
776
777 status = umac_cmd_rt_prog_rf_test(fmac_dev_ctx,
778 &nrf_wifi_rf_test_xo_calib_params,
779 sizeof(nrf_wifi_rf_test_xo_calib_params));
780
781 if (status != NRF_WIFI_STATUS_SUCCESS) {
782 nrf_wifi_osal_log_err("%s: umac_cmd_rt_prog_set_xo_val failed",
783 __func__);
784
785 goto out;
786 }
787
788 do {
789 nrf_wifi_osal_sleep_ms(100);
790 count++;
791 } while ((rt_dev_ctx->rf_test_type != NRF_WIFI_RF_TEST_MAX) &&
792 (count < NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT));
793
794 if (count == NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT) {
795 nrf_wifi_osal_log_err("%s: Timed out",
796 __func__);
797 rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_MAX;
798 rt_dev_ctx->rf_test_cap_data = NULL;
799 status = NRF_WIFI_STATUS_FAIL;
800 goto out;
801 }
802
803 out:
804 return status;
805 }
806
807
nrf_wifi_rt_fmac_rf_test_compute_xo(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx)808 enum nrf_wifi_status nrf_wifi_rt_fmac_rf_test_compute_xo(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx)
809 {
810 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
811 struct nrf_wifi_rf_get_xo_value rf_get_xo_value_params;
812 struct nrf_wifi_rt_fmac_dev_ctx *rt_dev_ctx = NULL;
813 unsigned int count = 0;
814
815 if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_RT) {
816 nrf_wifi_osal_log_err("%s: Invalid op mode",
817 __func__);
818 goto out;
819 }
820
821 rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
822
823 nrf_wifi_osal_mem_set(&rf_get_xo_value_params,
824 0,
825 sizeof(rf_get_xo_value_params));
826
827 rf_get_xo_value_params.test = NRF_WIFI_RF_TEST_XO_TUNE;
828
829 rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_XO_TUNE;
830 rt_dev_ctx->rf_test_cap_data = NULL;
831 rt_dev_ctx->rf_test_cap_sz = 0;
832
833 status = umac_cmd_rt_prog_rf_test(fmac_dev_ctx,
834 &rf_get_xo_value_params,
835 sizeof(rf_get_xo_value_params));
836
837 if (status != NRF_WIFI_STATUS_SUCCESS) {
838 nrf_wifi_osal_log_err("%s: umac_cmd_rt_prog_rf_get_xo_value failed",
839 __func__);
840
841 goto out;
842 }
843
844 do {
845 nrf_wifi_osal_sleep_ms(100);
846 count++;
847 } while ((rt_dev_ctx->rf_test_type != NRF_WIFI_RF_TEST_MAX) &&
848 (count < NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT));
849
850 if (count == NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT) {
851 nrf_wifi_osal_log_err("%s: Timed out",
852 __func__);
853 rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_MAX;
854 rt_dev_ctx->rf_test_cap_data = NULL;
855 status = NRF_WIFI_STATUS_FAIL;
856 goto out;
857 }
858
859 out:
860 return status;
861 }
862
nrf_wifi_rt_fmac_stats_get(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,enum rpu_op_mode op_mode,struct rpu_rt_op_stats * stats)863 enum nrf_wifi_status nrf_wifi_rt_fmac_stats_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
864 enum rpu_op_mode op_mode,
865 struct rpu_rt_op_stats *stats)
866 {
867 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
868 unsigned char count = 0;
869
870 if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_RT) {
871 nrf_wifi_osal_log_err("%s: Invalid op mode",
872 __func__);
873 goto out;
874 }
875
876 if (fmac_dev_ctx->stats_req == true) {
877 nrf_wifi_osal_log_err("%s: Stats request already pending",
878 __func__);
879 goto out;
880 }
881
882 fmac_dev_ctx->stats_req = true;
883 fmac_dev_ctx->fw_stats = &stats->fw;
884
885 status = umac_cmd_rt_prog_stats_get(fmac_dev_ctx,
886 op_mode);
887
888 if (status != NRF_WIFI_STATUS_SUCCESS) {
889 goto out;
890 }
891
892 do {
893 nrf_wifi_osal_sleep_ms(1);
894 count++;
895 } while ((fmac_dev_ctx->stats_req == true) &&
896 (count < NRF_WIFI_FMAC_STATS_RECV_TIMEOUT));
897
898 if (count == NRF_WIFI_FMAC_STATS_RECV_TIMEOUT) {
899 nrf_wifi_osal_log_err("%s: Timed out",
900 __func__);
901 goto out;
902 }
903
904 status = NRF_WIFI_STATUS_SUCCESS;
905 out:
906 return status;
907 }
908
nrf_wifi_rt_fmac_phy_rf_params_init(struct nrf_wifi_phy_rf_params * prf,unsigned int package_info,unsigned char * str)909 static int nrf_wifi_rt_fmac_phy_rf_params_init(struct nrf_wifi_phy_rf_params *prf,
910 unsigned int package_info,
911 unsigned char *str)
912 {
913 int ret = -1;
914 unsigned int rf_param_offset = BAND_2G_LW_ED_BKF_DSSS_OFST - NRF_WIFI_RF_PARAMS_CONF_SIZE;
915 /* Initilaize reserved bytes */
916 nrf_wifi_osal_mem_set(prf,
917 0x0,
918 sizeof(prf));
919 /* Initialize PD adjust values for MCS7. Currently these 4 bytes are not being used */
920 prf->pd_adjust_val.pd_adjt_lb_chan = PD_ADJUST_VAL;
921 prf->pd_adjust_val.pd_adjt_hb_low_chan = PD_ADJUST_VAL;
922 prf->pd_adjust_val.pd_adjt_hb_mid_chan = PD_ADJUST_VAL;
923 prf->pd_adjust_val.pd_adjt_hb_high_chan = PD_ADJUST_VAL;
924
925 /* RX Gain offsets */
926 prf->rx_gain_offset.rx_gain_lb_chan = CTRL_PWR_OPTIMIZATIONS;
927 prf->rx_gain_offset.rx_gain_hb_low_chan = RX_GAIN_OFFSET_HB_LOW_CHAN;
928 prf->rx_gain_offset.rx_gain_hb_mid_chan = RX_GAIN_OFFSET_HB_MID_CHAN;
929 prf->rx_gain_offset.rx_gain_hb_high_chan = RX_GAIN_OFFSET_HB_HIGH_CHAN;
930
931 if (package_info == CSP_PACKAGE_INFO) {
932 prf->xo_offset.xo_freq_offset = CSP_XO_VAL;
933
934 /* Configure systematic offset value */
935 prf->syst_tx_pwr_offset.syst_off_lb_chan = CSP_SYSTEM_OFFSET_LB;
936 prf->syst_tx_pwr_offset.syst_off_hb_low_chan = CSP_SYSTEM_OFFSET_HB_CHAN_LOW;
937 prf->syst_tx_pwr_offset.syst_off_hb_mid_chan = CSP_SYSTEM_OFFSET_HB_CHAN_MID;
938 prf->syst_tx_pwr_offset.syst_off_hb_high_chan = CSP_SYSTEM_OFFSET_HB_CHAN_HIGH;
939
940 /* TX power ceiling */
941 prf->max_pwr_ceil.max_dsss_pwr = CSP_MAX_TX_PWR_DSSS;
942 prf->max_pwr_ceil.max_lb_mcs7_pwr = CSP_MAX_TX_PWR_LB_MCS7;
943 prf->max_pwr_ceil.max_lb_mcs0_pwr = CSP_MAX_TX_PWR_LB_MCS0;
944 prf->max_pwr_ceil.max_hb_low_chan_mcs7_pwr = CSP_MAX_TX_PWR_HB_LOW_CHAN_MCS7;
945 prf->max_pwr_ceil.max_hb_mid_chan_mcs7_pwr = CSP_MAX_TX_PWR_HB_MID_CHAN_MCS7;
946 prf->max_pwr_ceil.max_hb_high_chan_mcs7_pwr = CSP_MAX_TX_PWR_HB_HIGH_CHAN_MCS7;
947 prf->max_pwr_ceil.max_hb_low_chan_mcs0_pwr = CSP_MAX_TX_PWR_HB_LOW_CHAN_MCS0;
948 prf->max_pwr_ceil.max_hb_mid_chan_mcs0_pwr = CSP_MAX_TX_PWR_HB_MID_CHAN_MCS0;
949 prf->max_pwr_ceil.max_hb_high_chan_mcs0_pwr = CSP_MAX_TX_PWR_HB_HIGH_CHAN_MCS0;
950 } else {
951 /** If nothing is written to OTP field corresponding to package info byte
952 * or if the package info field is corrupted then the default package
953 * package is QFN.
954 */
955
956 /* Initialize XO */
957 prf->xo_offset.xo_freq_offset = QFN_XO_VAL;
958
959 /* Configure systematic offset value */
960 prf->syst_tx_pwr_offset.syst_off_lb_chan = QFN_SYSTEM_OFFSET_LB;
961 prf->syst_tx_pwr_offset.syst_off_hb_low_chan = QFN_SYSTEM_OFFSET_HB_CHAN_LOW;
962 prf->syst_tx_pwr_offset.syst_off_hb_mid_chan = QFN_SYSTEM_OFFSET_HB_CHAN_MID;
963 prf->syst_tx_pwr_offset.syst_off_hb_high_chan = QFN_SYSTEM_OFFSET_HB_CHAN_HIGH;
964
965 /* TX power ceiling */
966 prf->max_pwr_ceil.max_dsss_pwr = QFN_MAX_TX_PWR_DSSS;
967 prf->max_pwr_ceil.max_lb_mcs7_pwr = QFN_MAX_TX_PWR_LB_MCS7;
968 prf->max_pwr_ceil.max_lb_mcs0_pwr = QFN_MAX_TX_PWR_LB_MCS0;
969 prf->max_pwr_ceil.max_hb_low_chan_mcs7_pwr = QFN_MAX_TX_PWR_HB_LOW_CHAN_MCS7;
970 prf->max_pwr_ceil.max_hb_mid_chan_mcs7_pwr = QFN_MAX_TX_PWR_HB_MID_CHAN_MCS7;
971 prf->max_pwr_ceil.max_hb_high_chan_mcs7_pwr = QFN_MAX_TX_PWR_HB_HIGH_CHAN_MCS7;
972 prf->max_pwr_ceil.max_hb_low_chan_mcs0_pwr = QFN_MAX_TX_PWR_HB_LOW_CHAN_MCS0;
973 prf->max_pwr_ceil.max_hb_mid_chan_mcs0_pwr = QFN_MAX_TX_PWR_HB_MID_CHAN_MCS0;
974 prf->max_pwr_ceil.max_hb_high_chan_mcs0_pwr = QFN_MAX_TX_PWR_HB_HIGH_CHAN_MCS0;
975 }
976
977 ret = nrf_wifi_utils_hex_str_to_val((unsigned char *)&prf->phy_params,
978 sizeof(prf->phy_params),
979 str);
980
981 prf->phy_params[rf_param_offset] = NRF70_BAND_2G_LOWER_EDGE_BACKOFF_DSSS;
982 prf->phy_params[rf_param_offset + 1] = NRF70_BAND_2G_LOWER_EDGE_BACKOFF_HT;
983 prf->phy_params[rf_param_offset + 2] = NRF70_BAND_2G_LOWER_EDGE_BACKOFF_HE;
984 prf->phy_params[rf_param_offset + 3] = NRF70_BAND_2G_UPPER_EDGE_BACKOFF_DSSS;
985 prf->phy_params[rf_param_offset + 4] = NRF70_BAND_2G_UPPER_EDGE_BACKOFF_HT;
986 prf->phy_params[rf_param_offset + 5] = NRF70_BAND_2G_UPPER_EDGE_BACKOFF_HE;
987 prf->phy_params[rf_param_offset + 6] = NRF70_BAND_UNII_1_LOWER_EDGE_BACKOFF_HT;
988 prf->phy_params[rf_param_offset + 7] = NRF70_BAND_UNII_1_LOWER_EDGE_BACKOFF_HE;
989 prf->phy_params[rf_param_offset + 8] = NRF70_BAND_UNII_1_UPPER_EDGE_BACKOFF_HT;
990 prf->phy_params[rf_param_offset + 9] = NRF70_BAND_UNII_1_UPPER_EDGE_BACKOFF_HE;
991 prf->phy_params[rf_param_offset + 10] = NRF70_BAND_UNII_2A_LOWER_EDGE_BACKOFF_HT;
992 prf->phy_params[rf_param_offset + 11] = NRF70_BAND_UNII_2A_LOWER_EDGE_BACKOFF_HE;
993 prf->phy_params[rf_param_offset + 12] = NRF70_BAND_UNII_2A_UPPER_EDGE_BACKOFF_HT;
994 prf->phy_params[rf_param_offset + 13] = NRF70_BAND_UNII_2A_UPPER_EDGE_BACKOFF_HE;
995 prf->phy_params[rf_param_offset + 14] = NRF70_BAND_UNII_2C_LOWER_EDGE_BACKOFF_HT;
996 prf->phy_params[rf_param_offset + 15] = NRF70_BAND_UNII_2C_LOWER_EDGE_BACKOFF_HE;
997 prf->phy_params[rf_param_offset + 16] = NRF70_BAND_UNII_2C_UPPER_EDGE_BACKOFF_HT;
998 prf->phy_params[rf_param_offset + 17] = NRF70_BAND_UNII_2C_UPPER_EDGE_BACKOFF_HE;
999 prf->phy_params[rf_param_offset + 18] = NRF70_BAND_UNII_3_LOWER_EDGE_BACKOFF_HT;
1000 prf->phy_params[rf_param_offset + 19] = NRF70_BAND_UNII_3_LOWER_EDGE_BACKOFF_HE;
1001 prf->phy_params[rf_param_offset + 20] = NRF70_BAND_UNII_3_UPPER_EDGE_BACKOFF_HT;
1002 prf->phy_params[rf_param_offset + 21] = NRF70_BAND_UNII_3_UPPER_EDGE_BACKOFF_HE;
1003 prf->phy_params[rf_param_offset + 22] = NRF70_BAND_UNII_4_LOWER_EDGE_BACKOFF_HT;
1004 prf->phy_params[rf_param_offset + 23] = NRF70_BAND_UNII_4_LOWER_EDGE_BACKOFF_HE;
1005 prf->phy_params[rf_param_offset + 24] = NRF70_BAND_UNII_4_UPPER_EDGE_BACKOFF_HT;
1006 prf->phy_params[rf_param_offset + 25] = NRF70_BAND_UNII_4_UPPER_EDGE_BACKOFF_HE;
1007 prf->phy_params[rf_param_offset + 26] = NRF70_ANT_GAIN_2G;
1008 prf->phy_params[rf_param_offset + 27] = NRF70_ANT_GAIN_5G_BAND1;
1009 prf->phy_params[rf_param_offset + 28] = NRF70_ANT_GAIN_5G_BAND2;
1010 prf->phy_params[rf_param_offset + 29] = NRF70_ANT_GAIN_5G_BAND3;
1011 prf->phy_params[rf_param_offset + 30] = NRF70_PCB_LOSS_2G;
1012 prf->phy_params[rf_param_offset + 31] = NRF70_PCB_LOSS_5G_BAND1;
1013 prf->phy_params[rf_param_offset + 32] = NRF70_PCB_LOSS_5G_BAND2;
1014 prf->phy_params[rf_param_offset + 33] = NRF70_PCB_LOSS_5G_BAND3;
1015
1016 return(ret);
1017 }
1018
1019
nrf_wifi_rt_fmac_rf_params_get(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct nrf_wifi_phy_rf_params * phy_rf_params)1020 enum nrf_wifi_status nrf_wifi_rt_fmac_rf_params_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
1021 struct nrf_wifi_phy_rf_params *phy_rf_params)
1022 {
1023 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
1024 struct nrf_wifi_fmac_otp_info otp_info;
1025 unsigned int ft_prog_ver;
1026 int ret = -1;
1027 /* If package_info is not written to OTP then the default value will be 0xFF. */
1028 unsigned int package_info = 0xFFFFFFFF;
1029 struct nrf_wifi_tx_pwr_ceil_params *tx_pwr_ceil_params;
1030 unsigned char backoff_2g_dsss = 0, backoff_2g_ofdm = 0;
1031 unsigned char backoff_5g_lowband = 0, backoff_5g_midband = 0, backoff_5g_highband = 0;
1032
1033 if (!fmac_dev_ctx || !phy_rf_params) {
1034 nrf_wifi_osal_log_err("%s: Invalid parameters",
1035 __func__);
1036 goto out;
1037 }
1038
1039 if (!fmac_dev_ctx->op_mode == NRF_WIFI_OP_MODE_RT) {
1040 nrf_wifi_osal_log_err("%s: Invalid op mode",
1041 __func__);
1042 goto out;
1043 }
1044
1045 tx_pwr_ceil_params = fmac_dev_ctx->tx_pwr_ceil_params;
1046
1047 nrf_wifi_osal_mem_set(&otp_info,
1048 0xFF,
1049 sizeof(otp_info));
1050
1051 status = nrf_wifi_hal_otp_info_get(fmac_dev_ctx->hal_dev_ctx,
1052 &otp_info.info,
1053 &otp_info.flags);
1054
1055 if (status != NRF_WIFI_STATUS_SUCCESS) {
1056 nrf_wifi_osal_log_err("%s: Fetching of RPU OTP information failed",
1057 __func__);
1058 goto out;
1059 }
1060
1061 status = nrf_wifi_hal_otp_ft_prog_ver_get(fmac_dev_ctx->hal_dev_ctx,
1062 &ft_prog_ver);
1063 if (status != NRF_WIFI_STATUS_SUCCESS) {
1064 nrf_wifi_osal_log_err("%s: Fetching of FT program version failed",
1065 __func__);
1066 goto out;
1067 }
1068
1069 status = nrf_wifi_hal_otp_pack_info_get(fmac_dev_ctx->hal_dev_ctx,
1070 &package_info);
1071 if (status != NRF_WIFI_STATUS_SUCCESS) {
1072 nrf_wifi_osal_log_err("%s: Fetching of Package info failed",
1073 __func__);
1074 goto out;
1075 }
1076
1077 ret = nrf_wifi_rt_fmac_phy_rf_params_init(phy_rf_params,
1078 package_info,
1079 NRF_WIFI_RT_DEF_RF_PARAMS);
1080
1081 if (ret == -1) {
1082 nrf_wifi_osal_log_err("%s: Initialization of RF params with default values failed",
1083 __func__);
1084 status = NRF_WIFI_STATUS_FAIL;
1085 goto out;
1086 }
1087 if (!(otp_info.flags & (~CALIB_XO_FLAG_MASK))) {
1088 nrf_wifi_osal_mem_cpy(&phy_rf_params->xo_offset.xo_freq_offset,
1089 (char *)otp_info.info.calib + OTP_OFF_CALIB_XO,
1090 OTP_SZ_CALIB_XO);
1091
1092 }
1093
1094 ft_prog_ver = (ft_prog_ver & FT_PROG_VER_MASK) >> 16;
1095
1096 if (ft_prog_ver == FT_PROG_VER1) {
1097 backoff_2g_dsss = FT_PROG_VER1_2G_DSSS_TXCEIL_BKOFF;
1098 backoff_2g_ofdm = FT_PROG_VER1_2G_OFDM_TXCEIL_BKOFF;
1099 backoff_5g_lowband = FT_PROG_VER1_5G_LOW_OFDM_TXCEIL_BKOFF;
1100 backoff_5g_midband = FT_PROG_VER1_5G_MID_OFDM_TXCEIL_BKOFF;
1101 backoff_5g_highband = FT_PROG_VER1_5G_HIGH_OFDM_TXCEIL_BKOFF;
1102 } else if (ft_prog_ver == FT_PROG_VER2) {
1103 backoff_2g_dsss = FT_PROG_VER2_2G_DSSS_TXCEIL_BKOFF;
1104 backoff_2g_ofdm = FT_PROG_VER2_2G_OFDM_TXCEIL_BKOFF;
1105 backoff_5g_lowband = FT_PROG_VER2_5G_LOW_OFDM_TXCEIL_BKOFF;
1106 backoff_5g_midband = FT_PROG_VER2_5G_MID_OFDM_TXCEIL_BKOFF;
1107 backoff_5g_highband = FT_PROG_VER2_5G_HIGH_OFDM_TXCEIL_BKOFF;
1108 } else if (ft_prog_ver == FT_PROG_VER3) {
1109 backoff_2g_dsss = FT_PROG_VER3_2G_DSSS_TXCEIL_BKOFF;
1110 backoff_2g_ofdm = FT_PROG_VER3_2G_OFDM_TXCEIL_BKOFF;
1111 backoff_5g_lowband = FT_PROG_VER3_5G_LOW_OFDM_TXCEIL_BKOFF;
1112 backoff_5g_midband = FT_PROG_VER3_5G_MID_OFDM_TXCEIL_BKOFF;
1113 backoff_5g_highband = FT_PROG_VER3_5G_HIGH_OFDM_TXCEIL_BKOFF;
1114 }
1115 phy_rf_params->max_pwr_ceil.max_dsss_pwr =
1116 MIN(tx_pwr_ceil_params->max_pwr_2g_dsss, phy_rf_params->max_pwr_ceil.max_dsss_pwr)
1117 - backoff_2g_dsss;
1118 phy_rf_params->max_pwr_ceil.max_lb_mcs7_pwr =
1119 MIN(tx_pwr_ceil_params->max_pwr_2g_mcs7, phy_rf_params->max_pwr_ceil.max_lb_mcs7_pwr)
1120 - backoff_2g_ofdm;
1121 phy_rf_params->max_pwr_ceil.max_lb_mcs0_pwr =
1122 MIN(tx_pwr_ceil_params->max_pwr_2g_mcs0, phy_rf_params->max_pwr_ceil.max_lb_mcs0_pwr)
1123 - backoff_2g_ofdm;
1124 #ifndef NRF70_2_4G_ONLY
1125 phy_rf_params->max_pwr_ceil.max_hb_low_chan_mcs7_pwr =
1126 MIN(tx_pwr_ceil_params->max_pwr_5g_low_mcs7,
1127 phy_rf_params->max_pwr_ceil.max_hb_low_chan_mcs7_pwr) - backoff_5g_lowband;
1128 phy_rf_params->max_pwr_ceil.max_hb_mid_chan_mcs7_pwr =
1129 MIN(tx_pwr_ceil_params->max_pwr_5g_mid_mcs7,
1130 phy_rf_params->max_pwr_ceil.max_hb_mid_chan_mcs7_pwr) - backoff_5g_midband;
1131 phy_rf_params->max_pwr_ceil.max_hb_high_chan_mcs7_pwr =
1132 MIN(tx_pwr_ceil_params->max_pwr_5g_high_mcs7,
1133 phy_rf_params->max_pwr_ceil.max_hb_high_chan_mcs7_pwr) - backoff_5g_highband;
1134 phy_rf_params->max_pwr_ceil.max_hb_low_chan_mcs0_pwr =
1135 MIN(tx_pwr_ceil_params->max_pwr_5g_low_mcs0,
1136 phy_rf_params->max_pwr_ceil.max_hb_low_chan_mcs0_pwr) - backoff_5g_lowband;
1137 phy_rf_params->max_pwr_ceil.max_hb_mid_chan_mcs0_pwr =
1138 MIN(tx_pwr_ceil_params->max_pwr_5g_mid_mcs0,
1139 phy_rf_params->max_pwr_ceil.max_hb_mid_chan_mcs0_pwr) - backoff_5g_midband;
1140 phy_rf_params->max_pwr_ceil.max_hb_high_chan_mcs0_pwr =
1141 MIN(tx_pwr_ceil_params->max_pwr_5g_high_mcs0,
1142 phy_rf_params->max_pwr_ceil.max_hb_high_chan_mcs0_pwr) - backoff_5g_highband;
1143 #endif /* NRF70_2_4G_ONLY */
1144
1145 status = NRF_WIFI_STATUS_SUCCESS;
1146 out:
1147 return status;
1148 }