Skip to content

Commit cecafe3

Browse files
committed
Add support for host RX buffers pass to UMAC (nRF71)
In nRF70, the host programmed RX buffers directly to the RPU through hardware queues. With nRF71, hardware queues are not accessible from the host side. This update adds a command handling to allow the host to pass RX buffers to UMAC firmware, which then programs them to the RPU. Signed-off-by: Ajay Parida <[email protected]>
1 parent 52286f1 commit cecafe3

File tree

10 files changed

+234
-2
lines changed

10 files changed

+234
-2
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ target_compile_definitions(
6060
$<$<BOOL:${CONFIG_NRF71_ON_IPC}>:NRF71_ON_IPC>
6161
$<$<BOOL:${CONFIG_NRF_WIFI_DYNAMIC_BANDWIDTH_SIGNALLING}>:NRF_WIFI_DYNAMIC_BANDWIDTH_SIGNALLING>
6262
$<$<BOOL:${CONFIG_NRF_WIFI_DYNAMIC_ED}>:NRF_WIFI_DYNAMIC_ED>
63+
$<$<BOOL:${CONFIG_NRF71_RX_BUFF}>:NRF71_RX_BUFF>
6364
NRF_WIFI_MAX_PS_POLL_FAIL_CNT=${CONFIG_NRF_WIFI_MAX_PS_POLL_FAIL_CNT}
6465
NRF70_RX_NUM_BUFS=${CONFIG_NRF70_RX_NUM_BUFS}
6566
NRF70_MAX_TX_TOKENS=${CONFIG_NRF70_MAX_TX_TOKENS}

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ ccflags-y += -DNRF_WIFI_RPU_RECOVERY_PS_ACTIVE_TIMEOUT_MS=50000
9797
ccflags-y += -DNRF_WIFI_DISPLAY_SCAN_BSS_LIMIT=150
9898
ccflags-y += -DNRF_WIFI_RPU_MIN_TIME_TO_ENTER_SLEEP_MS=1000
9999
ccflags-y += -DWIFI_NRF70_LOG_LEVEL=1
100+
#ccflags-y += -DNRF71_RX_BUFF
100101

101102
# Source files
102103
SRCS = os_if/src/osal.c \

fw_if/umac_if/inc/fw/host_rpu_sys_if.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
#define MAX_TX_AGG_SIZE 16
4141
#define MAX_RX_BUFS_PER_EVNT 64
42+
#define MAX_RX_BUFS_PER_CMD 32
4243
#define MAX_MGMT_BUFS 16
4344

4445
/*#define ETH_ADDR_LEN 6*/

fw_if/umac_if/inc/fw/host_rpu_umac_if.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ enum nrf_wifi_umac_commands {
150150
NRF_WIFI_UMAC_CMD_CONFIG_QUIET_PERIOD,
151151
/** Command to specify power save exit strategy */
152152
NRF_WIFI_UMAC_CMD_PS_EXIT_STRATEGY,
153+
/** Send host RX Buffers */
154+
NRF_WIFI_UMAC_CMD_CONFIG_RX_BUF,
153155
};
154156

155157
/**
@@ -3548,4 +3550,19 @@ struct nrf_wifi_cmd_ps_exit_strategy {
35483550
unsigned char ps_exit_strategy;
35493551
} __NRF_WIFI_PKD;
35503552

3553+
struct nrf_wifi_rx_buf {
3554+
unsigned int skb_pointer;
3555+
unsigned short skb_desc_no;
3556+
} __NRF_WIFI_PKD;
3557+
3558+
/**
3559+
* @brief This structure represents the command used to configure rx buffers.
3560+
*
3561+
*/
3562+
struct nrf_wifi_cmd_rx_buf_info {
3563+
struct nrf_wifi_umac_hdr umac_hdr;
3564+
unsigned int rx_buf_num;
3565+
struct nrf_wifi_rx_buf info[0];
3566+
} __NRF_WIFI_PKD;
3567+
35513568
#endif /* __HOST_RPU_UMAC_IF_H */

fw_if/umac_if/inc/system/fmac_api.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1175,6 +1175,21 @@ enum nrf_wifi_status nrf_wifi_sys_fmac_stats_get(struct nrf_wifi_fmac_dev_ctx *f
11751175
enum rpu_op_mode op_mode,
11761176
struct rpu_sys_op_stats *stats);
11771177

1178+
#ifdef NRF71_RX_BUFF
1179+
/**
1180+
* @brief Configure Rx buffer to firmware.
1181+
* @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device.
1182+
* @param nrf_wifi_rx_buf RX buffer info.
1183+
* @param num_buffs Number of buffers.
1184+
*
1185+
* This function is used to send host Rx buffers to UMAC module
1186+
*
1187+
* @return Command execution status
1188+
*/
1189+
enum nrf_wifi_status nrf_wifi_sys_fmac_prog_rx_buf_info(void *fmac_dev_ctx,
1190+
struct nrf_wifi_rx_buf *rx_buf,
1191+
unsigned int num_buffs);
1192+
#endif /* NRF71_RX_BUFF*/
11781193
/**
11791194
* @}
11801195
*/

fw_if/umac_if/inc/system/fmac_rx.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,8 @@ enum nrf_wifi_status nrf_wifi_fmac_rx_event_process(struct nrf_wifi_fmac_dev_ctx
3737
struct nrf_wifi_rx_buff *config);
3838

3939
void nrf_wifi_fmac_rx_tasklet(void *data);
40-
40+
#ifdef NRF71_RX_BUFF
41+
unsigned long nrf_wifi_fmac_get_rx_buf_map_addr(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
42+
unsigned int desc_id);
43+
#endif /* NRF71_RX_BUFF */
4144
#endif /* __FMAC_RX_H__ */

fw_if/umac_if/src/system/fmac_api.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3346,6 +3346,89 @@ enum nrf_wifi_status nrf_wifi_sys_fmac_set_ps_exit_strategy(void *dev_ctx,
33463346

33473347
return status;
33483348
}
3349+
3350+
#ifdef NRF71_RX_BUFF
3351+
enum nrf_wifi_status nrf_wifi_sys_fmac_prog_rx_buf_info(void *dev_ctx,
3352+
struct nrf_wifi_rx_buf *rx_buf,
3353+
unsigned int rx_buf_nums)
3354+
{
3355+
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
3356+
struct nrf_wifi_cmd_rx_buf_info *rx_buf_cmd = NULL;
3357+
struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL;
3358+
struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL;
3359+
struct nrf_wifi_rx_buf *rx_buf_iter = NULL;
3360+
int i = 0, remained_buf_cnt = 0, counter = 0, rx_buff_prog_cnt = 0;
3361+
3362+
fmac_dev_ctx = dev_ctx;
3363+
def_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
3364+
3365+
if (rx_buf_nums > MAX_RX_BUFS_PER_CMD) {
3366+
rx_buff_prog_cnt = MAX_RX_BUFS_PER_CMD;
3367+
remained_buf_cnt = rx_buf_nums % MAX_RX_BUFS_PER_CMD;
3368+
counter = rx_buf_nums / MAX_RX_BUFS_PER_CMD;
3369+
} else {
3370+
rx_buff_prog_cnt = rx_buf_nums;
3371+
counter = 1;
3372+
}
3373+
3374+
rx_buf_iter = rx_buf;
3375+
3376+
for (i = 0; i < counter; i++) {
3377+
rx_buf_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*rx_buf_cmd) +
3378+
rx_buff_prog_cnt *
3379+
sizeof(struct nrf_wifi_rx_buf));
3380+
if (!rx_buf_cmd) {
3381+
nrf_wifi_osal_log_err("%s: Unable to allocate memory\n",
3382+
__func__);
3383+
goto out;
3384+
}
3385+
3386+
rx_buf_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_CONFIG_RX_BUF;
3387+
nrf_wifi_osal_mem_cpy(&rx_buf_cmd->info,
3388+
rx_buf,
3389+
rx_buff_prog_cnt * sizeof(struct nrf_wifi_rx_buf));
3390+
3391+
rx_buf_cmd->rx_buf_num = rx_buff_prog_cnt;
3392+
3393+
status = umac_cmd_cfg(fmac_dev_ctx,
3394+
rx_buf_cmd,
3395+
sizeof(*rx_buf_cmd) +
3396+
rx_buff_prog_cnt *
3397+
sizeof(struct nrf_wifi_rx_buf));
3398+
if (rx_buf_cmd) {
3399+
nrf_wifi_osal_mem_free(rx_buf_cmd);
3400+
}
3401+
}
3402+
if (remained_buf_cnt > 0) {
3403+
rx_buf_cmd = nrf_wifi_osal_mem_zalloc(sizeof(*rx_buf_cmd) +
3404+
remained_buf_cnt *
3405+
sizeof(struct nrf_wifi_rx_buf));
3406+
if (!rx_buf_cmd) {
3407+
nrf_wifi_osal_log_err("%s: Unable to allocate memory\n",
3408+
__func__);
3409+
goto out;
3410+
}
3411+
3412+
rx_buf_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_CONFIG_RX_BUF;
3413+
nrf_wifi_osal_mem_cpy(&rx_buf_cmd->info,
3414+
rx_buf + (MAX_RX_BUFS_PER_CMD),
3415+
remained_buf_cnt * sizeof(struct nrf_wifi_rx_buf));
3416+
3417+
rx_buf_cmd->rx_buf_num = remained_buf_cnt;
3418+
3419+
status = umac_cmd_cfg(fmac_dev_ctx,
3420+
rx_buf_cmd,
3421+
sizeof(*rx_buf_cmd) +
3422+
remained_buf_cnt *
3423+
sizeof(struct nrf_wifi_rx_buf));
3424+
if (rx_buf_cmd) {
3425+
nrf_wifi_osal_mem_free(rx_buf_cmd);
3426+
}
3427+
}
3428+
out:
3429+
return status;
3430+
}
3431+
#endif /* NRF71_RX_BUFF */
33493432
#endif /* NRF70_STA_MODE */
33503433

33513434
enum nrf_wifi_status nrf_wifi_sys_fmac_stats_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,

fw_if/umac_if/src/system/rx.c

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
#include "system/fmac_rx.h"
1414
#include "common/fmac_util.h"
1515
#include "system/fmac_promisc.h"
16+
#ifdef NRF71_RX_BUFF
17+
#include "system/fmac_api.h"
18+
#endif /* NRF71_RX_BUFF */
1619

1720
static enum nrf_wifi_status
1821
nrf_wifi_fmac_map_desc_to_pool(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
@@ -165,6 +168,47 @@ static void nrf_wifi_convert_to_eth(void *nwb,
165168
}
166169
#endif /* NRF70_STA_MODE */
167170

171+
#ifdef NRF71_RX_BUFF
172+
unsigned long nrf_wifi_fmac_get_rx_buf_map_addr(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
173+
unsigned int desc_id)
174+
{
175+
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
176+
struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
177+
struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
178+
struct nrf_wifi_fmac_buf_map_info *rx_buf_info = NULL;
179+
struct nrf_wifi_fmac_rx_pool_map_info pool_info;
180+
unsigned long phy_addr = 0;
181+
182+
sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
183+
sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
184+
185+
status = nrf_wifi_fmac_map_desc_to_pool(fmac_dev_ctx,
186+
desc_id,
187+
&pool_info);
188+
189+
if (status != NRF_WIFI_STATUS_SUCCESS) {
190+
nrf_wifi_osal_log_err("%s: nrf_wifi_fmac_map_desc_to_pool failed\n",
191+
__func__);
192+
goto out;
193+
}
194+
195+
rx_buf_info = &sys_dev_ctx->rx_buf_info[desc_id];
196+
197+
if (rx_buf_info->mapped) {
198+
phy_addr = nrf_wifi_sys_hal_get_buf_map_rx(fmac_dev_ctx->hal_dev_ctx,
199+
pool_info.pool_id,
200+
pool_info.buf_id);
201+
return phy_addr;
202+
} else {
203+
nrf_wifi_osal_log_err("%s: rx buffer not mapped for desc_id= %d\n",
204+
__func__,
205+
desc_id);
206+
}
207+
out:
208+
return 0;
209+
}
210+
#endif /* NRF71_RX_BUFF */
211+
168212
enum nrf_wifi_status nrf_wifi_fmac_rx_cmd_send(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
169213
enum nrf_wifi_fmac_rx_cmd_type cmd_type,
170214
unsigned int desc_id)
@@ -245,12 +289,14 @@ enum nrf_wifi_status nrf_wifi_fmac_rx_cmd_send(struct nrf_wifi_fmac_dev_ctx *fma
245289
#else
246290
rx_cmd.addr = (unsigned int)nwb_data;
247291
#endif /* NRF71_ON_IPC */
292+
#ifndef NRF71_RX_BUFF
248293
status = nrf_wifi_sys_hal_data_cmd_send(fmac_dev_ctx->hal_dev_ctx,
249294
NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_RX,
250295
&rx_cmd,
251296
sizeof(rx_cmd),
252297
desc_id,
253298
pool_info.pool_id);
299+
#endif /* NRF71_RX_BUFF */
254300
} else if (cmd_type == NRF_WIFI_FMAC_RX_CMD_TYPE_DEINIT) {
255301
#ifndef NRF71_ON_IPC
256302
/* TODO: Need to initialize a command and send it to LMAC
@@ -359,6 +405,10 @@ enum nrf_wifi_status nrf_wifi_fmac_rx_event_process(struct nrf_wifi_fmac_dev_ctx
359405
#endif /* NRF70_STA_MODE */
360406
struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
361407
struct nrf_wifi_sys_fmac_priv *sys_fpriv = NULL;
408+
#ifdef NRF71_RX_BUFF
409+
unsigned int buf_addr = 0;
410+
struct nrf_wifi_rx_buf *rx_buf_ipc = NULL, *rx_buf_info_iter = NULL;
411+
#endif /* NRF71_RX_BUFF */
362412

363413
sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
364414
sys_fpriv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
@@ -373,6 +423,12 @@ enum nrf_wifi_status nrf_wifi_fmac_rx_event_process(struct nrf_wifi_fmac_dev_ctx
373423
#endif /* NRF70_STA_MODE */
374424
num_pkts = config->rx_pkt_cnt;
375425

426+
#ifdef NRF71_RX_BUFF
427+
rx_buf_ipc = nrf_wifi_osal_mem_zalloc(num_pkts *
428+
sizeof(struct nrf_wifi_rx_buf));
429+
rx_buf_info_iter = rx_buf_ipc;
430+
#endif /* NRF71_RX_BUFF */
431+
376432
for (i = 0; i < num_pkts; i++) {
377433
desc_id = config->rx_buff_info[i].descriptor_id;
378434
pkt_len = config->rx_buff_info[i].rx_pkt_len;
@@ -548,8 +604,38 @@ enum nrf_wifi_status nrf_wifi_fmac_rx_event_process(struct nrf_wifi_fmac_dev_ctx
548604
__func__);
549605
continue;
550606
}
607+
#ifdef NRF71_RX_BUFF
608+
buf_addr = (unsigned int) nrf_wifi_fmac_get_rx_buf_map_addr(fmac_dev_ctx,
609+
desc_id);
610+
if (buf_addr) {
611+
rx_buf_info_iter->skb_pointer = buf_addr;
612+
rx_buf_info_iter->skb_desc_no = desc_id;
613+
rx_buf_info_iter++;
614+
} else {
615+
nrf_wifi_osal_log_err("%s: UMAC rx buff not mapped\
616+
for desc_id = %d\n",
617+
__func__,
618+
desc_id);
619+
continue;
620+
}
621+
#endif /* NRF71_RX_BUFF */
551622
}
552-
623+
#ifdef NRF71_RX_BUFF
624+
status = nrf_wifi_sys_fmac_prog_rx_buf_info(fmac_dev_ctx,
625+
rx_buf_ipc,
626+
num_pkts);
627+
if (status != NRF_WIFI_STATUS_SUCCESS) {
628+
nrf_wifi_osal_log_err("%s: UMAC rx buff\
629+
programming failed \n",
630+
__func__);
631+
status = NRF_WIFI_STATUS_FAIL;
632+
} else {
633+
nrf_wifi_osal_log_dbg("%s: UMAC rx buff refill\
634+
programmed for num_buffs= %d \n",
635+
__func__, num_pkts);
636+
nrf_wifi_osal_mem_free(rx_buf_ipc);
637+
}
638+
#endif /* NRF71_RX_BUFF */
553639
/* A single failure returns failure for the entire event */
554640
return status;
555641
}

hw_if/hal/inc/system/hal_api.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,4 +144,9 @@ enum nrf_wifi_status nrf_wifi_hal_coex_config_sleep_ctrl_gpio_ctrl(
144144
unsigned int invert_bt_coex_grant_output);
145145
#endif /* NRF70_SR_COEX_SLEEP_CTRL_GPIO_CTRL */
146146

147+
#ifdef NRF71_RX_BUFF
148+
unsigned long nrf_wifi_sys_hal_get_buf_map_rx(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
149+
unsigned int pool_id,
150+
unsigned int buf_id);
151+
#endif /* NRF71_RX_BUFF */
147152
#endif /* __HAL_API_SYS_H__ */

hw_if/hal/src/system/hal_api.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,26 @@ static void recovery_tasklet_fn(unsigned long data)
9595
&flags);
9696
}
9797

98+
#ifdef NRF71_RX_BUFF
99+
unsigned long nrf_wifi_sys_hal_get_buf_map_rx(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
100+
unsigned int pool_id,
101+
unsigned int buf_id)
102+
{
103+
struct nrf_wifi_hal_buf_map_info *rx_buf_info = NULL;
104+
105+
rx_buf_info = &hal_dev_ctx->rx_buf_info[pool_id][buf_id];
106+
107+
if (rx_buf_info->mapped) {
108+
return rx_buf_info->phy_addr;
109+
} else {
110+
nrf_wifi_osal_log_err("%s: Rx buffer not mapped for pool_id = %d, buf_id=%d\n",
111+
__func__,
112+
pool_id,
113+
buf_id);
114+
}
115+
return 0;
116+
}
117+
#endif /* NRF71_RX_BUFF */
98118

99119
unsigned long nrf_wifi_sys_hal_buf_map_rx(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx,
100120
unsigned long buf,

0 commit comments

Comments
 (0)