Skip to content

Commit 36b86fc

Browse files
committed
Add SOFT_HPQM support
SOFT_HPQM is to replace existing hardware based queue used to communicate between host and firmware. Targeted towards nrf71 based system. TX and CTRL commands are used to communicate using software queue. RX buffers are programmed to firmware at initialization are handled by firmware. Signed-off-by: Ajay Parida <[email protected]>
1 parent 969cd5c commit 36b86fc

File tree

6 files changed

+457
-4
lines changed

6 files changed

+457
-4
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ target_compile_definitions(
6161
$<$<BOOL:${CONFIG_NRF_WIFI_DYNAMIC_BANDWIDTH_SIGNALLING}>:NRF_WIFI_DYNAMIC_BANDWIDTH_SIGNALLING>
6262
$<$<BOOL:${CONFIG_NRF_WIFI_DYNAMIC_ED}>:NRF_WIFI_DYNAMIC_ED>
6363
$<$<BOOL:${CONFIG_NRF71_HOST_RX_BUF_CMD}>:NRF71_HOST_RX_BUF_CMD>
64+
$<$<BOOL:${CONFIG_NRF71_SOFT_HPQM}>:NRF71_SOFT_HPQM>
6465
NRF_WIFI_MAX_PS_POLL_FAIL_CNT=${CONFIG_NRF_WIFI_MAX_PS_POLL_FAIL_CNT}
6566
NRF70_RX_NUM_BUFS=${CONFIG_NRF70_RX_NUM_BUFS}
6667
NRF70_MAX_TX_TOKENS=${CONFIG_NRF70_MAX_TX_TOKENS}

fw_if/umac_if/inc/fw/host_rpu_common_if.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,30 @@ struct host_rpu_umac_info {
138138
/** OTP params */
139139
unsigned int calib[9];
140140
} __NRF_WIFI_PKD;
141+
142+
#ifdef NRF71_SOFT_HPQM
143+
144+
#define NRF_WIFI_HOST_RPU_CMD_BUFFERS 4
145+
#define NRF_WIFI_HOST_RPU_EVENT_BUFFERS 7
146+
#define NRF_WIFI_HOST_RPU_TX_DESC 12
147+
148+
struct soft_hpqm_info {
149+
volatile unsigned int host_cmd_free_index;
150+
volatile unsigned int rpu_cmd_busy_index;
151+
volatile unsigned int host_event_busy_index;
152+
volatile unsigned int rpu_event_free_index;
153+
volatile unsigned int host_tx_cmd_busy_index;
154+
volatile unsigned int rpu_tx_cmd_busy_index;
155+
volatile unsigned int host_tx_done_busy_index;
156+
volatile unsigned int rpu_tx_done_busy_index;
157+
volatile unsigned int cmd_free_buffs[NRF_WIFI_HOST_RPU_CMD_BUFFERS];
158+
volatile unsigned int cmd_busy_buffs[NRF_WIFI_HOST_RPU_CMD_BUFFERS];
159+
volatile unsigned int event_free_buffs[NRF_WIFI_HOST_RPU_EVENT_BUFFERS];
160+
volatile unsigned int event_busy_buffs[NRF_WIFI_HOST_RPU_EVENT_BUFFERS];
161+
volatile unsigned int tx_cmd_buffs[NRF_WIFI_HOST_RPU_TX_DESC];
162+
volatile unsigned int tx_done_buffs[NRF_WIFI_HOST_RPU_TX_DESC];
163+
} __NRF_WIFI_PKD;
164+
#endif /* NRF71_SOFT_HPQM */
141165
/**
142166
* @}
143167
*/

hw_if/hal/inc/common/hal_structs_common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ enum NRF_WIFI_HAL_STATUS {
116116
* @brief Structure to hold RPU information.
117117
*/
118118
struct nrf_wifi_hal_info {
119+
#ifdef NRF71_SOFT_HPQM
120+
/** Host RPU soft_hpqm information */
121+
struct soft_hpqm_info *soft_hpq;
122+
#endif /* NRF71_SOFT_HPQM */
119123
/** Host RPU HPQM information */
120124
struct host_rpu_hpqm_info hpqm_info;
121125
/** RX command base */

hw_if/hal/inc/common/rpu_if.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,13 @@ struct rpu_mcu_boot_vectors {
215215

216216
/* Address which has information about the host port queue manager (HPQM) */
217217
#define RPU_MEM_HPQ_INFO 0xB0000024
218+
#ifdef NRF71_SOFT_HPQM
219+
#define RPU_MEM_TX_CMD_BASE 0x200800B8
220+
#define NRF_WIFI_SOFTHPQM_INFO_START_ADDR 0x20084548
221+
#else
218222
/* Address which has information about the TX command base */
219223
#define RPU_MEM_TX_CMD_BASE 0xB00000B8
220-
224+
#endif /* NRF71_SOFT_HPQM */
221225
/* Address which has OTP location containing the factory test program version */
222226
#define RPU_MEM_OTP_FT_PROG_VERSION 0xB0004FD8
223227
/* Address which has the OTP flags */

hw_if/hal/src/common/hal_api_common.c

Lines changed: 250 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,48 @@ enum nrf_wifi_status nrf_wifi_hal_get_rpu_ps_state(
220220
#endif /* NRF_WIFI_LOW_POWER */
221221

222222

223+
#ifdef NRF71_SOFT_HPQM
224+
static bool hal_rpu_soft_hpq_is_empty(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx)
225+
{
226+
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
227+
unsigned int val = 0;
228+
unsigned int cur_index = 0;
229+
unsigned long addr = 0;
230+
231+
addr = (unsigned long)&hal_dev_ctx->rpu_info.soft_hpq->host_cmd_free_index;
232+
status = hal_rpu_mem_read(hal_dev_ctx,
233+
&cur_index,
234+
(unsigned int)addr,
235+
sizeof(unsigned int));
236+
237+
if (status != NRF_WIFI_STATUS_SUCCESS) {
238+
nrf_wifi_osal_log_err("%s: Read from the host_event_busy_index = %x"
239+
" address failed, val (0x%X)\n",
240+
__func__,
241+
(unsigned int)addr,
242+
cur_index);
243+
return true;
244+
}
245+
246+
addr = (unsigned long)&hal_dev_ctx->rpu_info.soft_hpq->cmd_free_buffs[cur_index];
247+
status = hal_rpu_mem_read(hal_dev_ctx,
248+
&val,
249+
(unsigned int)addr,
250+
sizeof(unsigned int));
251+
252+
if (status != NRF_WIFI_STATUS_SUCCESS) {
253+
nrf_wifi_osal_log_err("%s: Read from dequeue address %x failed, val (0x%X)\n",
254+
__func__,
255+
(unsigned int)addr,
256+
val);
257+
return true;
258+
}
259+
if (val) {
260+
return false;
261+
}
262+
return true;
263+
}
264+
#else
223265
static bool hal_rpu_hpq_is_empty(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
224266
struct host_rpu_hpq *hpq)
225267
{
@@ -243,12 +285,27 @@ static bool hal_rpu_hpq_is_empty(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
243285

244286
return true;
245287
}
288+
#endif /* NRF71_SOFT_HPQM */
246289

247290

248291
static enum nrf_wifi_status hal_rpu_ready(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
249292
enum NRF_WIFI_HAL_MSG_TYPE msg_type)
250293
{
251294
bool is_empty = false;
295+
#ifdef NRF71_SOFT_HPQM
296+
if (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL) {
297+
is_empty = hal_rpu_soft_hpq_is_empty(hal_dev_ctx);
298+
if (is_empty == true) {
299+
return NRF_WIFI_STATUS_FAIL;
300+
}
301+
} else {
302+
nrf_wifi_osal_log_err("%s: Invalid msg type %d",
303+
__func__,
304+
msg_type);
305+
306+
return NRF_WIFI_STATUS_FAIL;
307+
}
308+
#else
252309
struct host_rpu_hpq *avl_buf_q = NULL;
253310

254311
if (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL) {
@@ -268,11 +325,11 @@ static enum nrf_wifi_status hal_rpu_ready(struct nrf_wifi_hal_dev_ctx *hal_dev_c
268325
if (is_empty == true) {
269326
return NRF_WIFI_STATUS_FAIL;
270327
}
328+
#endif /* NRF71_SOFT_HPQM */
271329

272330
return NRF_WIFI_STATUS_SUCCESS;
273331
}
274332

275-
276333
static enum nrf_wifi_status hal_rpu_ready_wait(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
277334
enum NRF_WIFI_HAL_MSG_TYPE msg_type)
278335
{
@@ -315,13 +372,124 @@ static enum nrf_wifi_status hal_rpu_msg_trigger(struct nrf_wifi_hal_dev_ctx *hal
315372
return status;
316373
}
317374

318-
319375
enum nrf_wifi_status hal_rpu_msg_post(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
320376
enum NRF_WIFI_HAL_MSG_TYPE msg_type,
321377
unsigned int queue_id,
322378
unsigned int msg_addr)
323379
{
324380
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
381+
#ifdef NRF71_SOFT_HPQM
382+
unsigned int cur_index = 0;
383+
unsigned long addr = 0;
384+
385+
if (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL) {
386+
addr = (unsigned long)&hal_dev_ctx->rpu_info.soft_hpq->host_cmd_free_index;
387+
status = hal_rpu_mem_read(hal_dev_ctx,
388+
&cur_index,
389+
(unsigned int)addr,
390+
sizeof(unsigned int));
391+
392+
if (status != NRF_WIFI_STATUS_SUCCESS) {
393+
nrf_wifi_osal_log_err("%s: Read from the cmd_free_index = %x "
394+
"addr failed, val (0x%X)\n",
395+
__func__,
396+
(unsigned int)addr,
397+
cur_index);
398+
goto out;
399+
}
400+
401+
addr = (unsigned long)&hal_dev_ctx->rpu_info.soft_hpq->cmd_busy_buffs[cur_index];
402+
status = hal_rpu_mem_write(hal_dev_ctx,
403+
(unsigned int)addr,
404+
(void *)(unsigned long)msg_addr,
405+
sizeof(unsigned int));
406+
407+
if (status != NRF_WIFI_STATUS_SUCCESS) {
408+
nrf_wifi_osal_log_err("%s: Writing to cmd_busy_buffs[%d] "
409+
" addr = %x failed msg_addr = %x\n",
410+
__func__,
411+
cur_index,
412+
(unsigned int)addr,
413+
msg_addr);
414+
goto out;
415+
}
416+
417+
cur_index++;
418+
if (cur_index == NRF_WIFI_HOST_RPU_CMD_BUFFERS)
419+
cur_index = 0;
420+
421+
addr = (unsigned long)&hal_dev_ctx->rpu_info.soft_hpq->host_cmd_free_index;
422+
status = hal_rpu_mem_write(hal_dev_ctx,
423+
(unsigned int)addr,
424+
(void *)(unsigned long)cur_index,
425+
sizeof(unsigned int));
426+
427+
if (status != NRF_WIFI_STATUS_SUCCESS) {
428+
nrf_wifi_osal_log_err("%s: Writing to cmd_free_index = %x "
429+
" failed for val =%d\n",
430+
__func__,
431+
(unsigned int)addr,
432+
cur_index);
433+
goto out;
434+
}
435+
} else if (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_TX) {
436+
addr = (unsigned long)&hal_dev_ctx->rpu_info.soft_hpq->host_tx_cmd_busy_index;
437+
status = hal_rpu_mem_read(hal_dev_ctx,
438+
&cur_index,
439+
(unsigned int)addr,
440+
sizeof(unsigned int));
441+
442+
if (status != NRF_WIFI_STATUS_SUCCESS) {
443+
nrf_wifi_osal_log_err("%s: Read from the event_busy_index = %x "
444+
" addr failed, val (0x%X)\n",
445+
__func__,
446+
(unsigned int)addr,
447+
cur_index);
448+
goto out;
449+
}
450+
451+
addr = (unsigned long)&hal_dev_ctx->rpu_info.soft_hpq->tx_cmd_buffs[cur_index];
452+
status = hal_rpu_mem_write(hal_dev_ctx,
453+
(unsigned int)addr,
454+
(void *)(unsigned long)msg_addr,
455+
sizeof(unsigned int));
456+
457+
if (status != NRF_WIFI_STATUS_SUCCESS) {
458+
nrf_wifi_osal_log_err("%s: Writing to tx_cmd_buffs[%d] "
459+
"addr = %x failed val=%x\n",
460+
__func__,
461+
cur_index,
462+
(unsigned int)addr,
463+
msg_addr);
464+
goto out;
465+
}
466+
467+
cur_index++;
468+
if (cur_index == NRF_WIFI_HOST_RPU_TX_DESC)
469+
cur_index = 0;
470+
471+
addr = (unsigned long)&hal_dev_ctx->rpu_info.soft_hpq->host_tx_cmd_busy_index;
472+
status = hal_rpu_mem_write(hal_dev_ctx,
473+
(unsigned int)addr,
474+
(void *)(unsigned long)cur_index,
475+
sizeof(unsigned int));
476+
477+
if (status != NRF_WIFI_STATUS_SUCCESS) {
478+
nrf_wifi_osal_log_err("%s: Writing to cmd_free_index = %x failed for val =%d\n",
479+
__func__,
480+
(unsigned int)addr,
481+
cur_index);
482+
goto out;
483+
}
484+
} else if (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_RX) {
485+
;/* Nothing to do */
486+
} else {
487+
nrf_wifi_osal_log_err("%s: Invalid msg_type (%d)",
488+
__func__,
489+
msg_type);
490+
goto out;
491+
}
492+
#else
325493
struct host_rpu_hpq *busy_queue = NULL;
326494

327495
if (queue_id >= MAX_NUM_OF_RX_QUEUES) {
@@ -355,6 +523,7 @@ enum nrf_wifi_status hal_rpu_msg_post(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
355523
__func__);
356524
goto out;
357525
}
526+
#endif /* NRF71_SOFT_HPQM */
358527

359528
if (msg_type != NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_RX) {
360529
/* Indicate to the RPU that the information has been posted */
@@ -376,6 +545,78 @@ static enum nrf_wifi_status hal_rpu_msg_get_addr(struct nrf_wifi_hal_dev_ctx *ha
376545
unsigned int *msg_addr)
377546
{
378547
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
548+
#ifdef NRF71_SOFT_HPQM
549+
unsigned int val = 0;
550+
unsigned int cur_index = 0;
551+
unsigned long addr = 0;
552+
553+
if (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL) {
554+
addr = (unsigned long)&hal_dev_ctx->rpu_info.soft_hpq->host_cmd_free_index;
555+
status = hal_rpu_mem_read(hal_dev_ctx,
556+
&cur_index,
557+
(unsigned int)addr,
558+
sizeof(unsigned int));
559+
560+
if (status != NRF_WIFI_STATUS_SUCCESS) {
561+
nrf_wifi_osal_log_err("%s: Read from the event_busy_index = %x"
562+
"addr failed, val (0x%X)\n",
563+
__func__,
564+
addr,
565+
cur_index);
566+
goto out;
567+
}
568+
569+
addr = (unsigned long)&hal_dev_ctx->rpu_info.soft_hpq->cmd_free_buffs[cur_index];
570+
status = hal_rpu_mem_read(hal_dev_ctx,
571+
&val,
572+
(unsigned int)addr,
573+
sizeof(unsigned int));
574+
575+
if (status != NRF_WIFI_STATUS_SUCCESS) {
576+
nrf_wifi_osal_log_err("%s: Read from the cmd_free_buffs[%d] = %x"
577+
" addr failed, val (0x%X)\n",
578+
__func__,
579+
cur_index,
580+
addr,
581+
val);
582+
goto out;
583+
}
584+
} else {
585+
nrf_wifi_osal_log_err("%s: Invalid msg type %d\n",
586+
__func__,
587+
msg_type);
588+
return NRF_WIFI_STATUS_FAIL;
589+
}
590+
591+
if (!val) {
592+
nrf_wifi_osal_log_err("%s:No valid content avaialble in the expected index \n",
593+
__func__,
594+
cur_index);
595+
*msg_addr = 0;
596+
status = NRF_WIFI_STATUS_FAIL;
597+
goto out;
598+
} else {
599+
/* Valid address has been read.
600+
* So write back 0 to same index address at cmd_free_buffs.
601+
*/
602+
addr = (unsigned long)&hal_dev_ctx->rpu_info.soft_hpq->cmd_free_buffs[cur_index];
603+
status = hal_rpu_mem_write(hal_dev_ctx,
604+
(unsigned int)addr,
605+
0x0,
606+
sizeof(unsigned int));
607+
608+
if (status != NRF_WIFI_STATUS_SUCCESS) {
609+
nrf_wifi_osal_log_err("%s: Write to address %xfailed, val (0x%X)\n",
610+
__func__,
611+
addr,
612+
0x0);
613+
return true;
614+
}
615+
616+
*msg_addr = val; /* Assign the address read from cmd_free_buffs cur_index */
617+
status = NRF_WIFI_STATUS_SUCCESS;
618+
}
619+
#else
379620
struct host_rpu_hpq *avl_queue = NULL;
380621

381622
if (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL) {
@@ -398,6 +639,7 @@ static enum nrf_wifi_status hal_rpu_msg_get_addr(struct nrf_wifi_hal_dev_ctx *ha
398639
*msg_addr = 0;
399640
goto out;
400641
}
642+
#endif /*NRF71_SOFT_HPQM */
401643
out:
402644
return status;
403645
}
@@ -748,13 +990,19 @@ enum nrf_wifi_status nrf_wifi_hal_dev_init(struct nrf_wifi_hal_dev_ctx *hal_dev_
748990
}
749991

750992
#ifndef NRF71_ON_IPC
993+
#ifdef NRF71_SOFT_HPQM
994+
hal_dev_ctx->rpu_info.soft_hpq =
995+
(struct soft_hpqm_info *)NRF_WIFI_SOFTHPQM_INFO_START_ADDR;
996+
997+
#else
751998
/* Read the HPQM info for all the queues provided by the RPU
752999
* (like command, event, RX buf queues etc)
7531000
*/
7541001
status = hal_rpu_mem_read(hal_dev_ctx,
7551002
&hal_dev_ctx->rpu_info.hpqm_info,
7561003
RPU_MEM_HPQ_INFO,
7571004
sizeof(hal_dev_ctx->rpu_info.hpqm_info));
1005+
#endif /* NRF71_SOFT_HPQM */
7581006

7591007
if (status != NRF_WIFI_STATUS_SUCCESS) {
7601008
nrf_wifi_osal_log_err("%s: Failed to get the HPQ info",

0 commit comments

Comments
 (0)