diff --git a/target_if/direct_buf_rx/inc/target_if_direct_buf_rx_api.h b/target_if/direct_buf_rx/inc/target_if_direct_buf_rx_api.h index 14ccf7ce3e..5cf0220f69 100644 --- a/target_if/direct_buf_rx/inc/target_if_direct_buf_rx_api.h +++ b/target_if/direct_buf_rx/inc/target_if_direct_buf_rx_api.h @@ -88,8 +88,10 @@ struct wlan_lmac_if_tx_ops; * @paddr: physical address of buffer corresponding to vaddr * @meta_data_valid: Indicates that metadata is valid * @cv_meta_data_valid: Indicates that CV upload metadata is valid + * @cqi_meta_data_valid: Indicates that CQI upload metadata is valid * @meta_data: Meta data * @cv_meta_data: TxBF CV Meta data + * @cqi_meta_data: TxBF CQI Meta data */ struct direct_buf_rx_data { size_t dbr_len; @@ -98,9 +100,11 @@ struct direct_buf_rx_data { qdf_dma_addr_t paddr; bool meta_data_valid; bool cv_meta_data_valid; + bool cqi_meta_data_valid; union { struct direct_buf_rx_metadata meta_data; struct direct_buf_rx_cv_metadata cv_meta_data; + struct direct_buf_rx_cqi_metadata cqi_meta_data; }; }; #endif diff --git a/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.c b/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.c index 0f0209d1b2..0069fb75b6 100644 --- a/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.c +++ b/target_if/direct_buf_rx/src/target_if_direct_buf_rx_main.c @@ -2194,6 +2194,15 @@ static int target_if_direct_buf_rx_rsp_event_handler(ol_scn_t scn, wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); return QDF_STATUS_E_FAILURE; } + if (dbr_rsp.num_cqi_meta_data_entry > dbr_rsp.num_buf_release_entry) { + direct_buf_rx_err("More than expected number of cqi metadata"); + direct_buf_rx_err("meta_data_entry:%d cqi_meta_data_entry:%d buf_release_entry:%d", + dbr_rsp.num_meta_data_entry, + dbr_rsp.num_cqi_meta_data_entry, + dbr_rsp.num_buf_release_entry); + wlan_objmgr_pdev_release_ref(pdev, dbr_mod_id); + return QDF_STATUS_E_FAILURE; + } QDF_ASSERT(!(dbr_rsp.num_cv_meta_data_entry && dbr_rsp.num_meta_data_entry)); for (i = 0; i < dbr_rsp.num_buf_release_entry; i++) { @@ -2232,6 +2241,14 @@ static int target_if_direct_buf_rx_rsp_event_handler(ol_scn_t scn, dbr_data.cv_meta_data_valid = true; } + dbr_data.cqi_meta_data_valid = false; + if (i < dbr_rsp.num_cqi_meta_data_entry) { + if (wmi_extract_dbr_buf_cqi_metadata( + wmi_handle, data_buf, i, + &dbr_data.cqi_meta_data) == QDF_STATUS_SUCCESS) + dbr_data.cqi_meta_data_valid = true; + } + target_if_dbr_add_ring_debug_entry(pdev, dbr_rsp.mod_id, DBR_RING_DEBUG_EVENT_RX, srng_id); diff --git a/wmi/inc/wmi_unified_dbr_api.h b/wmi/inc/wmi_unified_dbr_api.h index 39e8ff05e1..e194a9643c 100644 --- a/wmi/inc/wmi_unified_dbr_api.h +++ b/wmi/inc/wmi_unified_dbr_api.h @@ -93,4 +93,19 @@ QDF_STATUS wmi_extract_dbr_buf_cv_metadata( wmi_unified_t wmi_handle, uint8_t *evt_buf, uint8_t idx, struct direct_buf_rx_cv_metadata *param); + +/** + * wmi_extract_dbr_buf_cqi_metadata: Extract direct buffer TxBF cqi metadata + * + * @wmi_handle: WMI handle + * @evt_buf: Event buffer + * @idx: Index of the module for which capability is received + * @param: Pointer to direct buffer cqi metadata + * + * Return: QDF status of operation + */ +QDF_STATUS wmi_extract_dbr_buf_cqi_metadata( + wmi_unified_t wmi_handle, + uint8_t *evt_buf, uint8_t idx, + struct direct_buf_rx_cqi_metadata *param); #endif /* _WMI_UNIFIED_DBR_API_H_ */ diff --git a/wmi/inc/wmi_unified_dbr_param.h b/wmi/inc/wmi_unified_dbr_param.h index be6aa1c579..937625fb9a 100644 --- a/wmi/inc/wmi_unified_dbr_param.h +++ b/wmi/inc/wmi_unified_dbr_param.h @@ -81,6 +81,7 @@ * @num_buf_release_entry: Number of buffers released through event * @num_meta_data_entry: Number of meta data released * @num_cv_meta_data_entry: Number of cv meta data released + * @num_cqi_meta_data_entry: Number of cqi meta data released * @dbr_entries: Pointer to direct buffer rx entry struct */ struct direct_buf_rx_rsp { @@ -89,6 +90,7 @@ struct direct_buf_rx_rsp { uint32_t num_buf_release_entry; uint32_t num_meta_data_entry; uint32_t num_cv_meta_data_entry; + uint32_t num_cqi_meta_data_entry; struct direct_buf_rx_entry *dbr_entries; }; @@ -164,6 +166,53 @@ struct direct_buf_rx_cv_metadata { uint32_t fb_params; }; +/* + * In CQI data buffer, each user CQI data will be stored + * in a fixed offset of 64 locations from each other, + * and each location corresponds to 64-bit length. + */ +#define CQI_USER_DATA_LENGTH (64 * 8) +#define CQI_USER_DATA_OFFSET(idx) ((idx) * CQI_USER_DATA_LENGTH) +#define MAX_NUM_CQI_USERS 3 +/* + * struct direct_buf_rx_cqi_per_user_info: Per user CQI data + * + * @asnr_len: Average SNR length + * @asnr_offset: Average SNR offset + * @fb_params: Feedback params, [1:0] Nc + * @peer_mac: Peer macaddr + */ +struct direct_buf_rx_cqi_per_user_info { + uint16_t asnr_len; + uint16_t asnr_offset; + uint32_t fb_params; + struct qdf_mac_addr peer_mac; +}; + +/** + * struct direct_buf_rx_cqi_metadata: direct buffer metadata for CQI upload + * + * @num_users: Number of user info in a metadta buffer + * @is_valid: Set cqi metadata is valid, + * false if sw_peer_id is invalid or FCS error + * @fb_type: Feedback type, 0 for SU 1 for MU 2 for CQI + * @fb_params: Feedback params + * [0] is_valid0 + * [1] is_valid1 + * [2] is_valid2 + * [4:3] Nc0 + * [5:4] Nc1 + * [6:5] Nc2 + * @user_info: Per user CQI info + */ +struct direct_buf_rx_cqi_metadata { + uint8_t num_users; + uint32_t is_valid; + uint32_t fb_type; + uint32_t fb_params; + struct direct_buf_rx_cqi_per_user_info user_info[MAX_NUM_CQI_USERS]; +}; + /** * struct direct_buf_rx_entry: direct buffer rx release entry structure * diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 5ddc4a8d71..35ac27d0da 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -2339,6 +2339,11 @@ QDF_STATUS (*extract_dbr_buf_cv_metadata)( wmi_unified_t wmi_handle, uint8_t *evt_buf, uint8_t idx, struct direct_buf_rx_cv_metadata *param); + +QDF_STATUS (*extract_dbr_buf_cqi_metadata)( + wmi_unified_t wmi_handle, + uint8_t *evt_buf, uint8_t idx, + struct direct_buf_rx_cqi_metadata *param); #endif QDF_STATUS (*extract_pdev_utf_event)(wmi_unified_t wmi_hdl, diff --git a/wmi/src/wmi_unified_dbr_api.c b/wmi/src/wmi_unified_dbr_api.c index a402339a6b..00bdd12952 100644 --- a/wmi/src/wmi_unified_dbr_api.c +++ b/wmi/src/wmi_unified_dbr_api.c @@ -80,3 +80,16 @@ QDF_STATUS wmi_extract_dbr_buf_cv_metadata( return QDF_STATUS_E_FAILURE; } + +QDF_STATUS wmi_extract_dbr_buf_cqi_metadata( + wmi_unified_t wmi_handle, + uint8_t *evt_buf, uint8_t idx, + struct direct_buf_rx_cqi_metadata *param) +{ + if (wmi_handle->ops->extract_dbr_buf_cqi_metadata) + return wmi_handle->ops->extract_dbr_buf_cqi_metadata( + wmi_handle, + evt_buf, idx, param); + + return QDF_STATUS_E_FAILURE; +} diff --git a/wmi/src/wmi_unified_dbr_tlv.c b/wmi/src/wmi_unified_dbr_tlv.c index 1ba03ea212..e4d2385975 100644 --- a/wmi/src/wmi_unified_dbr_tlv.c +++ b/wmi/src/wmi_unified_dbr_tlv.c @@ -141,12 +141,15 @@ static QDF_STATUS extract_dbr_buf_release_fixed_tlv(wmi_unified_t wmi_handle, if (((!param_buf->num_meta_data) || param_buf->num_meta_data < ev->num_meta_data_entry) && ((!param_buf->num_cv_meta_data) || - param_buf->num_cv_meta_data < ev->num_meta_data_entry)) { + param_buf->num_cv_meta_data < ev->num_meta_data_entry) && + ((!param_buf->num_cqi_meta_data) || + param_buf->num_cqi_meta_data < ev->num_meta_data_entry)) { wmi_err(" actual num of meta data entries less than provided entries"); return QDF_STATUS_E_INVAL; } param->num_meta_data_entry = param_buf->num_meta_data; param->num_cv_meta_data_entry = param_buf->num_cv_meta_data; + param->num_cqi_meta_data_entry = param_buf->num_cqi_meta_data; wmi_debug("pdev id %d mod id %d num buf release entry %d", param->pdev_id, param->mod_id, param->num_buf_release_entry); @@ -242,6 +245,54 @@ static QDF_STATUS extract_dbr_buf_cv_metadata_tlv( return QDF_STATUS_SUCCESS; } +static QDF_STATUS extract_dbr_buf_cqi_metadata_tlv( + wmi_unified_t wmi_handle, uint8_t *event, + uint8_t idx, struct direct_buf_rx_cqi_metadata *param) +{ + WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *param_buf; + wmi_dma_buf_release_cqi_upload_meta_data *ev; + uint16_t asnr_len, asnr_offset; + uint8_t num_users = 0; + uint8_t i; + + param_buf = (WMI_PDEV_DMA_RING_BUF_RELEASE_EVENTID_param_tlvs *)event; + if (!param_buf) + return QDF_STATUS_E_INVAL; + + ev = ¶m_buf->cqi_meta_data[idx]; + + if (!ev) { + wmi_err("CQI metadata is NULL"); + return QDF_STATUS_E_FAILURE; + } + + param->fb_params = ev->fb_params_cqi; + asnr_len = + WMI_DMA_BUF_RELEASE_CV_UPLOAD_GET_ASNR_LENGTH(ev->asnr_params); + asnr_offset = + WMI_DMA_BUF_RELEASE_CV_UPLOAD_GET_ASNR_OFFSET(ev->asnr_params); + for (i = 0; i < MAX_NUM_CQI_USERS_IN_STANDALONE_SND; i++) { + if (WMI_DMA_BUF_RELEASE_CQI_UPLOAD_GET_FB_PARAMS_IS_VALID( + param->fb_params, i)) { + WMI_DMA_BUF_RELEASE_CQI_UPLOAD_SET_FB_PARAMS_IS_VALID( + param->is_valid, 1, i); + param->user_info[i].asnr_len = asnr_len; + param->user_info[i].asnr_offset = + asnr_offset + CQI_USER_DATA_OFFSET(i); + param->user_info[i].fb_params = + WMI_DMA_BUF_RELEASE_CQI_UPLOAD_GET_FB_PARAMS_NC( + param->fb_params, i); + + WMI_MAC_ADDR_TO_CHAR_ARRAY(&ev->peer_mac_address[i], + ¶m->user_info[i].peer_mac.bytes[0]); + num_users++; + } + } + param->num_users = num_users; + + return QDF_STATUS_SUCCESS; +} + void wmi_dbr_attach_tlv(wmi_unified_t wmi_handle) { struct wmi_ops *ops = wmi_handle->ops; @@ -250,6 +301,7 @@ void wmi_dbr_attach_tlv(wmi_unified_t wmi_handle) ops->extract_dbr_buf_release_entry = extract_dbr_buf_release_entry_tlv; ops->extract_dbr_buf_metadata = extract_dbr_buf_metadata_tlv; ops->extract_dbr_buf_cv_metadata = extract_dbr_buf_cv_metadata_tlv; + ops->extract_dbr_buf_cqi_metadata = extract_dbr_buf_cqi_metadata_tlv; ops->extract_dbr_buf_release_fixed = extract_dbr_buf_release_fixed_tlv; ops->extract_scaling_params_service_ready_ext = extract_scaling_params_service_ready_ext_tlv;