Skip to content

Commit f8912ca

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 275a8dd commit f8912ca

File tree

6 files changed

+444
-4
lines changed

6 files changed

+444
-4
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ target_compile_definitions(
5959
$<$<BOOL:${CONFIG_NRF70_SR_COEX_SLEEP_CTRL_GPIO_CTRL}>:NRF70_SR_COEX_SLEEP_CTRL_GPIO_CTRL>
6060
$<$<BOOL:${CONFIG_NRF71_ON_IPC}>:NRF71_ON_IPC>
6161
$<$<BOOL:${CONFIG_NRF71_RX_BUFF}>:NRF71_RX_BUFF>
62+
$<$<BOOL:${CONFIG_NRF71_SOFT_HPQM}>:NRF71_SOFT_HPQM>
6263
NRF_WIFI_MAX_PS_POLL_FAIL_CNT=${CONFIG_NRF_WIFI_MAX_PS_POLL_FAIL_CNT}
6364
NRF70_RX_NUM_BUFS=${CONFIG_NRF70_RX_NUM_BUFS}
6465
NRF70_MAX_TX_TOKENS=${CONFIG_NRF70_MAX_TX_TOKENS}

fw_if/umac_if/inc/fw/host_rpu_common_if.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,32 @@ 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_GDRAM_START_ADDR 0x20084548
145+
#define NRF_WIFI_HOST_RPU_TX_CMD_START_ADDR 0x200800b8
146+
#define NRF_WIFI_HOST_RPU_CMD_BUFFERS 4
147+
#define NRF_WIFI_HOST_RPU_EVENT_BUFFERS 7
148+
#define NRF_WIFI_HOST_RPU_TX_DESC 12
149+
150+
struct soft_hpqm_info {
151+
volatile unsigned int host_cmd_free_index;
152+
volatile unsigned int rpu_cmd_busy_index;
153+
volatile unsigned int host_event_busy_index;
154+
volatile unsigned int rpu_event_free_index;
155+
volatile unsigned int host_tx_cmd_busy_index;
156+
volatile unsigned int rpu_tx_cmd_busy_index;
157+
volatile unsigned int host_tx_done_busy_index;
158+
volatile unsigned int rpu_tx_done_busy_index;
159+
volatile unsigned int cmd_free_buffs[NRF_WIFI_HOST_RPU_CMD_BUFFERS];
160+
volatile unsigned int cmd_busy_buffs[NRF_WIFI_HOST_RPU_CMD_BUFFERS];
161+
volatile unsigned int event_free_buffs[NRF_WIFI_HOST_RPU_EVENT_BUFFERS];
162+
volatile unsigned int event_busy_buffs[NRF_WIFI_HOST_RPU_EVENT_BUFFERS];
163+
volatile unsigned int tx_cmd_buffs[NRF_WIFI_HOST_RPU_TX_DESC];
164+
volatile unsigned int tx_done_buffs[NRF_WIFI_HOST_RPU_TX_DESC];
165+
} __NRF_WIFI_PKD;
166+
#endif /* NRF71_SOFT_HPQM */
141167
/**
142168
* @}
143169
*/

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: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,12 @@ 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+
#else
218221
/* Address which has information about the TX command base */
219222
#define RPU_MEM_TX_CMD_BASE 0xB00000B8
220-
223+
#endif /* NRF71_SOFT_HPQM */
221224
/* Address which has OTP location containing the factory test program version */
222225
#define RPU_MEM_OTP_FT_PROG_VERSION 0xB0004FD8
223226
/* Address which has the OTP flags */

hw_if/hal/src/common/hal_api_common.c

Lines changed: 239 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,47 @@ 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 current_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+
&current_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 address failed, val (0x%X)\n",
239+
__func__,
240+
(unsigned int)addr,
241+
current_index);
242+
return true;
243+
}
244+
245+
addr = (unsigned long)&hal_dev_ctx->rpu_info.soft_hpq->cmd_free_buffs[current_index];
246+
status = hal_rpu_mem_read(hal_dev_ctx,
247+
&val,
248+
(unsigned int)addr,
249+
sizeof(unsigned int));
250+
251+
if (status != NRF_WIFI_STATUS_SUCCESS) {
252+
nrf_wifi_osal_log_err("%s: Read from dequeue address %x failed, val (0x%X)\n",
253+
__func__,
254+
(unsigned int)addr,
255+
val);
256+
return true;
257+
}
258+
if (val) {
259+
return false;
260+
}
261+
return true;
262+
}
263+
#else
223264
static bool hal_rpu_hpq_is_empty(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
224265
struct host_rpu_hpq *hpq)
225266
{
@@ -243,12 +284,27 @@ static bool hal_rpu_hpq_is_empty(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
243284

244285
return true;
245286
}
287+
#endif /* NRF71_SOFT_HPQM */
246288

247289

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

254310
if (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL) {
@@ -268,11 +324,11 @@ static enum nrf_wifi_status hal_rpu_ready(struct nrf_wifi_hal_dev_ctx *hal_dev_c
268324
if (is_empty == true) {
269325
return NRF_WIFI_STATUS_FAIL;
270326
}
327+
#endif /* NRF71_SOFT_HPQM */
271328

272329
return NRF_WIFI_STATUS_SUCCESS;
273330
}
274331

275-
276332
static enum nrf_wifi_status hal_rpu_ready_wait(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
277333
enum NRF_WIFI_HAL_MSG_TYPE msg_type)
278334
{
@@ -315,13 +371,119 @@ static enum nrf_wifi_status hal_rpu_msg_trigger(struct nrf_wifi_hal_dev_ctx *hal
315371
return status;
316372
}
317373

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

327489
if (queue_id >= MAX_NUM_OF_RX_QUEUES) {
@@ -355,6 +517,7 @@ enum nrf_wifi_status hal_rpu_msg_post(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
355517
__func__);
356518
goto out;
357519
}
520+
#endif /* NRF71_SOFT_HPQM */
358521

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

381612
if (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL) {
@@ -398,6 +629,7 @@ static enum nrf_wifi_status hal_rpu_msg_get_addr(struct nrf_wifi_hal_dev_ctx *ha
398629
*msg_addr = 0;
399630
goto out;
400631
}
632+
#endif /*NRF71_SOFT_HPQM */
401633
out:
402634
return status;
403635
}
@@ -748,13 +980,18 @@ enum nrf_wifi_status nrf_wifi_hal_dev_init(struct nrf_wifi_hal_dev_ctx *hal_dev_
748980
}
749981

750982
#ifndef NRF71_ON_IPC
983+
#ifdef NRF71_SOFT_HPQM
984+
hal_dev_ctx->rpu_info.soft_hpq = (struct soft_hpqm_info *)NRF_WIFI_HOST_RPU_GDRAM_START_ADDR;
985+
986+
#else
751987
/* Read the HPQM info for all the queues provided by the RPU
752988
* (like command, event, RX buf queues etc)
753989
*/
754990
status = hal_rpu_mem_read(hal_dev_ctx,
755991
&hal_dev_ctx->rpu_info.hpqm_info,
756992
RPU_MEM_HPQ_INFO,
757993
sizeof(hal_dev_ctx->rpu_info.hpqm_info));
994+
#endif /* NRF71_SOFT_HPQM */
758995

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

0 commit comments

Comments
 (0)