Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nrf_wifi: Wait for regulatory change #1215

Merged
merged 1 commit into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions nrf_wifi/fw_if/umac_if/inc/default/fmac_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,9 @@ struct nrf_wifi_fmac_callbk_fns {
void *frm,
struct raw_rx_pkt_header *);
#endif
void (*reg_change_callbk_fn)(void *os_vif_ctx,
struct nrf_wifi_event_regulatory_change *reg_change,
unsigned int event_len);
};

#if defined(CONFIG_NRF700X_STA_MODE) || defined(__DOXYGEN__)
Expand Down
1 change: 1 addition & 0 deletions nrf_wifi/fw_if/umac_if/inc/fmac_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#ifdef CONFIG_NRF700X_RADIO_TEST
#define NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT 50 /* 5s */
#endif /* CONFIG_NRF_WIFI_LOW_POWER */
#define NRF_WIFI_FMAC_REG_SET_TIMEOUT_MS 2000 /* 2s */

struct host_rpu_msg *umac_cmd_alloc(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
int type,
Expand Down
4 changes: 4 additions & 0 deletions nrf_wifi/fw_if/umac_if/inc/fmac_structs_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ struct nrf_wifi_fmac_dev_ctx {
unsigned int reg_chan_count;
/** Regulatory channel attributes */
struct nrf_wifi_get_reg_chn_info *reg_chan_info;
/** Regulatory set status */
int reg_set_status;
/** Regulatory change event */
struct nrf_wifi_event_regulatory_change *reg_change;
/** Data pointer to mode specific parameters */
char priv[];
};
Expand Down
13 changes: 13 additions & 0 deletions nrf_wifi/fw_if/umac_if/inc/fw/host_rpu_umac_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -3470,6 +3470,19 @@ struct nrf_wifi_cmd_req_set_reg {
unsigned char nrf_wifi_alpha2[NRF_WIFI_COUNTRY_CODE_LEN];
} __NRF_WIFI_PKD;

/**
* @brief This structure represents the event that is generated when the regulatory domain
* is modified or updated. It contains the new regulatory domain information.
*
*/
struct nrf_wifi_event_regulatory_change {
struct nrf_wifi_umac_hdr umac_hdr;
unsigned short nrf_wifi_flags;
signed int intr;
signed char regulatory_type;
unsigned char nrf_wifi_alpha2[2];
} __NRF_WIFI_PKD;

/**
* @brief This structure represents the status code for a command. It is used to indicate
* the outcome or result of executing a specific command. The status code provides valuable
Expand Down
10 changes: 9 additions & 1 deletion nrf_wifi/fw_if/umac_if/src/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,15 @@ static enum nrf_wifi_status umac_event_ctrl_process(struct nrf_wifi_fmac_dev_ctx
umac_hdr->cmd_evnt);
break;
case NRF_WIFI_UMAC_EVENT_REG_CHANGE:
/* TODO: Inform the user space about the regulatory change */
if (callbk_fns->reg_change_callbk_fn)
callbk_fns->reg_change_callbk_fn(vif_ctx->os_vif_ctx,
event_data,
event_len);
else
nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv,
"%s: No callback registered for event %d",
__func__,
umac_hdr->cmd_evnt);
break;
#endif /* CONFIG_NRF700X_STA_MODE */
default:
Expand Down
100 changes: 100 additions & 0 deletions nrf_wifi/fw_if/umac_if/src/fmac_api_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,12 @@ enum nrf_wifi_status nrf_wifi_fmac_set_reg(struct nrf_wifi_fmac_dev_ctx *fmac_de
{
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
struct nrf_wifi_cmd_req_set_reg *set_reg_cmd = NULL;
unsigned int count = 0, max_count = NRF_WIFI_FMAC_REG_SET_TIMEOUT_MS / 20;
enum nrf_wifi_reg_initiator exp_initiator = NRF_WIFI_REGDOM_SET_BY_USER;
enum nrf_wifi_reg_type exp_reg_type = NRF_WIFI_REGDOM_TYPE_COUNTRY;
char exp_alpha2[NRF_WIFI_COUNTRY_CODE_LEN] = {0};
struct nrf_wifi_fmac_reg_info cur_reg_info = {0};
struct nrf_wifi_event_regulatory_change *reg_change = NULL;

if (!fmac_dev_ctx || !reg_info) {
nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv,
Expand All @@ -755,6 +761,28 @@ enum nrf_wifi_status nrf_wifi_fmac_set_reg(struct nrf_wifi_fmac_dev_ctx *fmac_de
goto out;
}

/* No change event from UMAC for same regd */
status = nrf_wifi_fmac_get_reg(fmac_dev_ctx, &cur_reg_info);
if (status != NRF_WIFI_STATUS_SUCCESS) {
nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv,
"%s: Failed to get current regulatory information",
__func__);
goto out;
}

if (nrf_wifi_osal_mem_cmp(fmac_dev_ctx->fpriv->opriv,
cur_reg_info.alpha2,
reg_info->alpha2,
NRF_WIFI_COUNTRY_CODE_LEN) == 0) {
nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv,
"%s: Regulatory domain already set to %c%c",
__func__,
reg_info->alpha2[0],
reg_info->alpha2[1]);
status = NRF_WIFI_STATUS_SUCCESS;
goto out;
}

set_reg_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv,
sizeof(*set_reg_cmd));

Expand All @@ -773,6 +801,13 @@ enum nrf_wifi_status nrf_wifi_fmac_set_reg(struct nrf_wifi_fmac_dev_ctx *fmac_de
reg_info->alpha2,
NRF_WIFI_COUNTRY_CODE_LEN);

exp_alpha2[0] = reg_info->alpha2[0];
exp_alpha2[1] = reg_info->alpha2[1];

if (reg_info->alpha2[0] == '0' && reg_info->alpha2[1] == '0') {
exp_reg_type = NRF_WIFI_REGDOM_TYPE_WORLD;
}

set_reg_cmd->valid_fields = NRF_WIFI_CMD_REQ_SET_REG_ALPHA2_VALID;

/* New feature in rev B patch */
Expand All @@ -783,12 +818,77 @@ enum nrf_wifi_status nrf_wifi_fmac_set_reg(struct nrf_wifi_fmac_dev_ctx *fmac_de
status = umac_cmd_cfg(fmac_dev_ctx,
set_reg_cmd,
sizeof(*set_reg_cmd));
if (status != NRF_WIFI_STATUS_SUCCESS) {
nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv,
"%s: Failed to set regulatory information",
__func__);
goto out;
}

fmac_dev_ctx->reg_set_status = false;
while (!fmac_dev_ctx->reg_set_status && count++ <= max_count) {
nrf_wifi_osal_sleep_ms(fmac_dev_ctx->fpriv->opriv,
100);
}

if (!fmac_dev_ctx->reg_set_status) {
nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv,
"%s: Failed to set regulatory information",
__func__);
status = NRF_WIFI_STATUS_FAIL;
goto out;
}

reg_change = fmac_dev_ctx->reg_change;

if (reg_change->intr != exp_initiator) {
nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv,
"%s: Regulatory domain change not initiated by user: exp: %d, got: %d",
__func__,
exp_initiator,
reg_change->intr);
status = NRF_WIFI_STATUS_FAIL;
goto out;
}

if (reg_change->regulatory_type != exp_reg_type) {
nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv,
"%s: Regulatory domain change not to expected type: exp: %d, got: %d",
__func__,
exp_reg_type,
reg_change->regulatory_type);
status = NRF_WIFI_STATUS_FAIL;
goto out;
}

if ((reg_change->regulatory_type == NRF_WIFI_REGDOM_TYPE_COUNTRY) &&
nrf_wifi_osal_mem_cmp(fmac_dev_ctx->fpriv->opriv,
reg_change->nrf_wifi_alpha2,
exp_alpha2,
NRF_WIFI_COUNTRY_CODE_LEN) != 0) {
nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv,
"%s: Regulatory domain change not to expected alpha2: exp: %c%c, got: %c%c",
__func__,
exp_alpha2[0],
exp_alpha2[1],
reg_change->nrf_wifi_alpha2[0],
reg_change->nrf_wifi_alpha2[1]);
status = NRF_WIFI_STATUS_FAIL;
goto out;
}

out:
if (set_reg_cmd) {
nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv,
set_reg_cmd);
}

if (reg_change) {
nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv,
reg_change);
fmac_dev_ctx->reg_change = NULL;
}

return status;
}

Expand Down
Loading