From: Jeff Chen Add support for the firmware TRPC configuration command used to retrieve and update TX power limit data. Assisted-by: LLM Signed-off-by: Jeff Chen --- drivers/net/wireless/nxp/nxpwifi/cfg.h | 11 ++++ drivers/net/wireless/nxp/nxpwifi/fw.h | 8 +++ drivers/net/wireless/nxp/nxpwifi/main.h | 2 + drivers/net/wireless/nxp/nxpwifi/sta_cfg.c | 8 +++ drivers/net/wireless/nxp/nxpwifi/sta_cmd.c | 67 ++++++++++++++++++++++ 5 files changed, 96 insertions(+) diff --git a/drivers/net/wireless/nxp/nxpwifi/cfg.h b/drivers/net/wireless/nxp/nxpwifi/cfg.h index 8627a3372978..4c0558ed483e 100644 --- a/drivers/net/wireless/nxp/nxpwifi/cfg.h +++ b/drivers/net/wireless/nxp/nxpwifi/cfg.h @@ -755,6 +755,17 @@ struct nxpwifi_ds_coalesce_cfg { struct nxpwifi_coalesce_rule rule[NXPWIFI_COALESCE_MAX_RULES]; }; +/* Host-side helper for the channel TRPC command. */ +struct nxpwifi_ds_chan_trpc_cfg { + u32 len; + u16 action; + u16 subband; + u8 tlvbuffer[]; +}; + +/* Upper bound on the TRPC TLV table exchanged with the firmware. */ +#define NXPWIFI_MAX_TRPC_BUF (4 * 1024) + struct nxpwifi_11ax_he_cap_cfg { u16 id; u16 len; diff --git a/drivers/net/wireless/nxp/nxpwifi/fw.h b/drivers/net/wireless/nxp/nxpwifi/fw.h index 188110b020cf..0de5d2fc9242 100644 --- a/drivers/net/wireless/nxp/nxpwifi/fw.h +++ b/drivers/net/wireless/nxp/nxpwifi/fw.h @@ -386,6 +386,7 @@ enum NXPWIFI_802_11_PRIVACY_FILTER { #define HOST_CMD_CAU_REG_ACCESS 0x00ed #define HOST_CMD_SET_BSS_MODE 0x00f7 #define HOST_CMD_PCIE_DESC_DETAILS 0x00fa +#define HOST_CMD_CHAN_TRPC_CONFIG 0x00fb #define HOST_CMD_802_11_NET_MONITOR 0x0102 #define HOST_CMD_802_11_SCAN_EXT 0x0107 #define HOST_CMD_COALESCE_CFG 0x010a @@ -2373,6 +2374,12 @@ struct host_cmd_twt_cfg { u8 val[]; } __packed; +struct host_cmd_chan_trpc_cfg { + __le16 action; + __le16 subband; + u8 tlvbuffer[]; +} __packed; + struct host_cmd_ds_command { __le16 command; __le16 size; @@ -2447,6 +2454,7 @@ struct host_cmd_ds_command { struct host_cmd_11ax_cmd ax_cmd; struct host_cmd_ds_802_11_net_monitor net_mon; struct host_cmd_twt_cfg twt_cfg; + struct host_cmd_chan_trpc_cfg ch_trpc_cfg; } params; } __packed; diff --git a/drivers/net/wireless/nxp/nxpwifi/main.h b/drivers/net/wireless/nxp/nxpwifi/main.h index b25a6a4f2936..9ae017bdc6ca 100644 --- a/drivers/net/wireless/nxp/nxpwifi/main.h +++ b/drivers/net/wireless/nxp/nxpwifi/main.h @@ -1415,6 +1415,8 @@ int nxpwifi_get_wakeup_reason(struct nxpwifi_private *priv, u16 action, struct nxpwifi_ds_wakeup_reason *wakeup_reason); int nxpwifi_get_chan_info(struct nxpwifi_private *priv, struct nxpwifi_channel_band *channel_band); +int nxpwifi_chan_trpc_cfg(struct nxpwifi_private *priv, int cmd_type, + struct nxpwifi_ds_chan_trpc_cfg *ch_trpc); void nxpwifi_coex_ampdu_rxwinsize(struct nxpwifi_adapter *adapter); void nxpwifi_11n_delba(struct nxpwifi_private *priv, int tid); int nxpwifi_send_domain_info_cmd_fw(struct wiphy *wiphy, enum nl80211_band band); diff --git a/drivers/net/wireless/nxp/nxpwifi/sta_cfg.c b/drivers/net/wireless/nxp/nxpwifi/sta_cfg.c index 56cf63fbf7fe..650de6156912 100644 --- a/drivers/net/wireless/nxp/nxpwifi/sta_cfg.c +++ b/drivers/net/wireless/nxp/nxpwifi/sta_cfg.c @@ -1175,3 +1175,11 @@ int nxpwifi_get_chan_info(struct nxpwifi_private *priv, HOST_ACT_GEN_GET, 0, channel_band, NXPWIFI_SYNC_CMD); } + +int nxpwifi_chan_trpc_cfg(struct nxpwifi_private *priv, int cmd_type, + struct nxpwifi_ds_chan_trpc_cfg *ch_trpc) +{ + return nxpwifi_send_cmd(priv, HOST_CMD_CHAN_TRPC_CONFIG, + ch_trpc->action, 0, ch_trpc, + cmd_type == NXPWIFI_SYNC_CMD); +} diff --git a/drivers/net/wireless/nxp/nxpwifi/sta_cmd.c b/drivers/net/wireless/nxp/nxpwifi/sta_cmd.c index 9bfa4aebc3e5..8ac5008e0081 100644 --- a/drivers/net/wireless/nxp/nxpwifi/sta_cmd.c +++ b/drivers/net/wireless/nxp/nxpwifi/sta_cmd.c @@ -3033,6 +3033,70 @@ nxpwifi_ret_sta_twt_cfg(struct nxpwifi_private *priv, return nxpwifi_ret_twt_cfg(priv, resp, data_buf); } +static int nxpwifi_cmd_chan_trpc_cfg(struct nxpwifi_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_no, void *data_buf, u16 cmd_action, + u32 cmd_type) +{ + struct host_cmd_chan_trpc_cfg *chan_trpc_cfg = &cmd->params.ch_trpc_cfg; + struct nxpwifi_ds_chan_trpc_cfg *usr_chan_trpc_cfg = + (struct nxpwifi_ds_chan_trpc_cfg *)data_buf; + u32 hdr_len = sizeof(chan_trpc_cfg->action) + + sizeof(chan_trpc_cfg->subband); + + /* usr_chan_trpc_cfg->len covers action, subband, and TRPC data. + * Reject lengths outside the supported command payload range. + */ + if (usr_chan_trpc_cfg->len < hdr_len || + usr_chan_trpc_cfg->len > hdr_len + NXPWIFI_MAX_TRPC_BUF) + return -EINVAL; + + cmd->command = cpu_to_le16(cmd_no); + cmd->size = cpu_to_le16(S_DS_GEN + usr_chan_trpc_cfg->len); + + memcpy(chan_trpc_cfg, &usr_chan_trpc_cfg->action, + usr_chan_trpc_cfg->len); + + return 0; +} + +static int nxpwifi_ret_chan_trpc_cfg(struct nxpwifi_private *priv, + struct host_cmd_ds_command *resp, + u16 cmdresp_no, void *data_buf) +{ + struct host_cmd_chan_trpc_cfg *chan_trpc_cfg = + &resp->params.ch_trpc_cfg; + struct nxpwifi_ds_chan_trpc_cfg *usr_chan_trpc_cfg = + (struct nxpwifi_ds_chan_trpc_cfg *)data_buf; + + if (chan_trpc_cfg->action == HOST_ACT_GEN_GET) { + u16 resp_size = le16_to_cpu(resp->size); + u16 resp_len; + + if (resp_size < S_DS_GEN) + return -EIO; + + resp_len = resp_size - S_DS_GEN; + /* The firmware response contains action, subband, and TRPC + * data. Validate that the payload length is within bounds. + */ + if (resp_len < sizeof(chan_trpc_cfg->action) + + sizeof(chan_trpc_cfg->subband) || + resp_len > sizeof(chan_trpc_cfg->action) + + sizeof(chan_trpc_cfg->subband) + + NXPWIFI_MAX_TRPC_BUF) { + nxpwifi_dbg(priv->adapter, ERROR, + "chan_trpc bad resp len: %u\n", resp_len); + return -EIO; + } + + usr_chan_trpc_cfg->len = resp_len; + memcpy(&usr_chan_trpc_cfg->action, chan_trpc_cfg, resp_len); + } + + return 0; +} + static const struct nxpwifi_cmd_entry cmd_table_sta[] = { {.cmd_no = HOST_CMD_GET_HW_SPEC, .prepare_cmd = nxpwifi_cmd_sta_get_hw_spec, @@ -3217,6 +3281,9 @@ static const struct nxpwifi_cmd_entry cmd_table_sta[] = { {.cmd_no = HOST_CMD_TWT_CFG, .prepare_cmd = nxpwifi_cmd_sta_twt_cfg, .cmd_resp = nxpwifi_ret_sta_twt_cfg}, + {.cmd_no = HOST_CMD_CHAN_TRPC_CONFIG, + .prepare_cmd = nxpwifi_cmd_chan_trpc_cfg, + .cmd_resp = nxpwifi_ret_chan_trpc_cfg}, }; /* -- 2.34.1