diff --git a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h index a0db221c71..275fde4ff4 100644 --- a/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h +++ b/umac/cmn_services/cmn_defs/inc/wlan_cmn_ieee80211.h @@ -3424,8 +3424,7 @@ struct wlan_eht_cap_info_network_endian { } qdf_packed; /** - * struct wlan_edca_pifs_param_ie: struct for QCN_ATTRIB_EDCA_PIFS_PARAM - * @edca_param_type: edca param type + * struct edca_param: struct for edca_param * @acvo_aifsn: ac vo aifsn * @acvo_acm: ac vo acm * @acvo_aci: ac vo aci @@ -3433,27 +3432,40 @@ struct wlan_eht_cap_info_network_endian { * @acvo_cwmin: ac vo cwmin * @acvo_cwmax: ac vo cwmax * @acvo_txoplimit: ac vo txoplimit + */ +struct edca_param { + uint8_t acvo_aifsn:4; + uint8_t acvo_acm:1; + uint8_t acvo_aci:2; + uint8_t unused:1; + uint8_t acvo_cwmin:4; + uint8_t acvo_cwmax:4; + uint16_t acvo_txoplimit; +}; + +/** + * struct pifs_param: struct for pifs_param * @sap_pifs_offset: sap pifs offset * @leb_pifs_offset: left earbud offset * @reb_pifs_offset: right earbud offset */ +struct pifs_param { + uint8_t sap_pifs_offset; + uint8_t leb_pifs_offset; + uint8_t reb_pifs_offset; +}; + +/** + * struct wlan_edca_pifs_param_ie: struct for QCN_ATTRIB_EDCA_PIFS_PARAM + * @edca_param_type: edca param type + * @eparam: structure for edca_param + * @pparam: structure for pifs_param + */ struct wlan_edca_pifs_param_ie { uint8_t edca_param_type; union { - struct { - uint8_t acvo_aifsn:4; - uint8_t acvo_acm:1; - uint8_t acvo_aci:2; - uint8_t unused:1; - uint8_t acvo_cwmin:4; - uint8_t acvo_cwmax:4; - uint16_t acvo_txoplimit; - } qdf_packed edca_param; /* edca_param_type = 0 */ - struct { - uint8_t sap_pifs_offset; - uint8_t leb_pifs_offset; - uint8_t reb_pifs_offset; - } qdf_packed pifs_params; /* edca_param_type = 1 */ + struct edca_param eparam; /* edca_param_type = 0 */ + struct pifs_param pparam; /* edca_param_type = 1 */ } qdf_packed edca_pifs_param; } qdf_packed; diff --git a/umac/cmn_services/inc/wlan_cmn.h b/umac/cmn_services/inc/wlan_cmn.h index 025173c6c2..5a7d7f7e3b 100644 --- a/umac/cmn_services/inc/wlan_cmn.h +++ b/umac/cmn_services/inc/wlan_cmn.h @@ -715,4 +715,14 @@ struct wlan_ssid { #define PSOC_HOST_EHT_MCS_NSS_MAP_5G_SIZE 4 #endif +/** + * enum host_edca_param_type - Host edca param type + * @HOST_EDCA_PARAM_TYPE_AGGRESSIVE: Aggressive type + * @HOST_EDCA_PARAM_TYPE_PIFS: Pifs type + */ +enum host_edca_param_type { + HOST_EDCA_PARAM_TYPE_AGGRESSIVE = 0, + HOST_EDCA_PARAM_TYPE_PIFS = 1, +}; + #endif /* _WLAN_OBJMGR_CMN_H_*/ diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index c8058498e1..f7b48b8373 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -5001,4 +5001,18 @@ QDF_STATUS wmi_extract_health_mon_event( void *ev, struct wmi_health_mon_params *param); #endif /* HEALTH_MON_SUPPORT */ + +/** + * wmi_unified__update_edca_pifs_param() - update EDCA/PIFS params + * @wmi_handle: wmi handle + * @edca_pifs_param: pointer to edca_pifs_vparam struct + * + * This function updates EDCA/PIFS parameters to the target + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS +wmi_unified_update_edca_pifs_param( + wmi_unified_t wmi_handle, + struct edca_pifs_vparam *edca_pifs_param); #endif /* _WMI_UNIFIED_API_H_ */ diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index 2c88d3c2cf..5c75dfb408 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -9484,4 +9484,13 @@ struct wmi_health_mon_params { }; #endif /* HEALTH_MON_SUPPORT */ +/** + * struct edca_pifs_vparam - edca/pifs param for ll sap + * @vdev_id: vdev id + * @param - pointer to wlan_edca_pifs_param_ie struct + */ +struct edca_pifs_vparam { + uint8_t vdev_id; + struct wlan_edca_pifs_param_ie param; +}; #endif /* _WMI_UNIFIED_PARAM_H_ */ diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 6df8bdd00a..10ff6f7c62 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -3187,6 +3187,10 @@ QDF_STATUS void *evt_buf, struct wmi_health_mon_params *param); #endif /* HEALTH_MON_SUPPORT */ + +QDF_STATUS (*send_update_edca_pifs_param_cmd)( + wmi_unified_t wmi_handle, + struct edca_pifs_vparam *edca_pifs_param); }; /* Forward declaration for psoc*/ diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index d6f617604f..b154b1b5b7 100644 --- a/wmi/src/wmi_unified_api.c +++ b/wmi/src/wmi_unified_api.c @@ -4046,3 +4046,15 @@ QDF_STATUS wmi_feature_set_cmd_send(wmi_unified_t wmi_handle, return QDF_STATUS_E_FAILURE; } #endif + +QDF_STATUS +wmi_unified_update_edca_pifs_param( + wmi_unified_t wmi_handle, + struct edca_pifs_vparam *edca_pifs_param) +{ + if (wmi_handle->ops->send_update_edca_pifs_param_cmd) + return wmi_handle->ops->send_update_edca_pifs_param_cmd( + wmi_handle, edca_pifs_param); + + return QDF_STATUS_E_FAILURE; +} diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 43ba4c56f0..2e1d0f66c9 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -5292,6 +5292,150 @@ fail: return QDF_STATUS_E_FAILURE; } +static WMI_EDCA_PARAM_TYPE +wmi_convert_edca_pifs_param_type(enum host_edca_param_type type) +{ + switch (type) { + case HOST_EDCA_PARAM_TYPE_AGGRESSIVE: + return WMI_EDCA_PARAM_TYPE_AGGRESSIVE; + case HOST_EDCA_PARAM_TYPE_PIFS: + return WMI_EDCA_PARAM_TYPE_PIFS; + default: + return WMI_EDCA_PARAM_TYPE_AGGRESSIVE; + } +} + +/** + * send_update_edca_pifs_param_cmd_tlv() - update EDCA params + * @wmi_handle: wmi handle + * @edca_pifs: edca/pifs parameters + * + * This function updates EDCA/PIFS parameters to the target + * + * Return: QDF Status + */ + +static QDF_STATUS +send_update_edca_pifs_param_cmd_tlv(wmi_unified_t wmi_handle, + struct edca_pifs_vparam *edca_pifs) +{ + uint8_t *buf_ptr; + wmi_buf_t buf = NULL; + wmi_vdev_set_twt_edca_params_cmd_fixed_param *cmd; + wmi_wmm_params *wmm_params; + wmi_pifs_params *pifs_params; + uint16_t len; + + if (!edca_pifs) { + wmi_debug("edca_pifs is NULL"); + return QDF_STATUS_E_FAILURE; + } + + len = sizeof(wmi_vdev_set_twt_edca_params_cmd_fixed_param); + if (edca_pifs->param.edca_param_type == + HOST_EDCA_PARAM_TYPE_AGGRESSIVE) { + len += WMI_TLV_HDR_SIZE; + len += sizeof(wmi_wmm_params); + } else { + len += WMI_TLV_HDR_SIZE; + } + if (edca_pifs->param.edca_param_type == + HOST_EDCA_PARAM_TYPE_PIFS) { + len += WMI_TLV_HDR_SIZE; + len += sizeof(wmi_pifs_params); + } else { + len += WMI_TLV_HDR_SIZE; + } + + buf = wmi_buf_alloc(wmi_handle, len); + + if (!buf) + return QDF_STATUS_E_NOMEM; + + cmd = (wmi_vdev_set_twt_edca_params_cmd_fixed_param *)wmi_buf_data(buf); + buf_ptr = (uint8_t *)cmd; + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_vdev_set_twt_edca_params_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN + (wmi_vdev_set_twt_edca_params_cmd_fixed_param)); + + cmd->vdev_id = edca_pifs->vdev_id; + cmd->type = wmi_convert_edca_pifs_param_type( + edca_pifs->param.edca_param_type); + buf_ptr += sizeof(wmi_vdev_set_twt_edca_params_cmd_fixed_param); + + if (cmd->type == WMI_EDCA_PARAM_TYPE_AGGRESSIVE) { + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + sizeof(*wmm_params)); + buf_ptr += WMI_TLV_HDR_SIZE; + wmm_params = (wmi_wmm_params *)buf_ptr; + WMITLV_SET_HDR(&wmm_params->tlv_header, + WMITLV_TAG_STRUC_wmi_wmm_params, + WMITLV_GET_STRUCT_TLVLEN(wmi_wmm_params)); + + wmm_params->cwmin = + edca_pifs->param.edca_pifs_param.eparam.acvo_cwmin; + wmm_params->cwmax = + edca_pifs->param.edca_pifs_param.eparam.acvo_cwmax; + wmm_params->aifs = + edca_pifs->param.edca_pifs_param.eparam.acvo_aifsn; + wmm_params->txoplimit = + edca_pifs->param.edca_pifs_param.eparam.acvo_txoplimit; + wmm_params->acm = + edca_pifs->param.edca_pifs_param.eparam.acvo_acm; + wmm_params->no_ack = 0; + wmi_debug("vdev_id %d type %d cwmin %d cwmax %d aifsn %d txoplimit %d acm %d no_ack %d", + cmd->vdev_id, cmd->type, wmm_params->cwmin, + wmm_params->cwmax, wmm_params->aifs, + wmm_params->txoplimit, wmm_params->acm, + wmm_params->no_ack); + buf_ptr += sizeof(*wmm_params); + } else { + /* set zero TLV's for wmm_params */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf_ptr += WMI_TLV_HDR_SIZE; + } + if (cmd->type == WMI_EDCA_PARAM_TYPE_PIFS) { + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + sizeof(*pifs_params)); + buf_ptr += WMI_TLV_HDR_SIZE; + pifs_params = (wmi_pifs_params *)buf_ptr; + WMITLV_SET_HDR(&pifs_params->tlv_header, + WMITLV_TAG_STRUC_wmi_pifs_params, + WMITLV_GET_STRUCT_TLVLEN(wmi_pifs_params)); + + pifs_params->sap_pifs_offset = + edca_pifs->param.edca_pifs_param.pparam.sap_pifs_offset; + pifs_params->leb_pifs_offset = + edca_pifs->param.edca_pifs_param.pparam.leb_pifs_offset; + pifs_params->reb_pifs_offset = + edca_pifs->param.edca_pifs_param.pparam.reb_pifs_offset; + wmi_debug("vdev_id %d type %d sap_offset %d leb_offset %d reb_offset %d", + cmd->vdev_id, cmd->type, pifs_params->sap_pifs_offset, + pifs_params->leb_pifs_offset, + pifs_params->reb_pifs_offset); + } else { + /* set zero TLV's for pifs_params */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf_ptr += WMI_TLV_HDR_SIZE; + } + + wmi_mtrace(WMI_VDEV_SET_TWT_EDCA_PARAMS_CMDID, cmd->vdev_id, 0); + if (wmi_unified_cmd_send(wmi_handle, buf, len, + WMI_VDEV_SET_TWT_EDCA_PARAMS_CMDID)) + goto fail; + + return QDF_STATUS_SUCCESS; + +fail: + wmi_buf_free(buf); + wmi_err("Failed to set EDCA/PIFS Parameters"); + return QDF_STATUS_E_FAILURE; +} + /** * send_probe_rsp_tmpl_send_cmd_tlv() - send probe response template to fw * @wmi_handle: wmi handle @@ -20132,6 +20276,8 @@ struct wmi_ops tlv_ops = { #endif /* HEALTH_MON_SUPPORT */ .send_multiple_vdev_param_cmd = send_multiple_vdev_param_cmd_tlv, .set_mac_addr_rx_filter = send_set_mac_addr_rx_filter_cmd_tlv, + .send_update_edca_pifs_param_cmd = + send_update_edca_pifs_param_cmd_tlv, }; #ifdef WLAN_FEATURE_11BE_MLO