diff --git a/target_if/init_deinit/inc/init_cmd_api.h b/target_if/init_deinit/inc/init_cmd_api.h index e96d3802c5..a7c9adf1ef 100644 --- a/target_if/init_deinit/inc/init_cmd_api.h +++ b/target_if/init_deinit/inc/init_cmd_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -33,18 +33,6 @@ #define TXBF_CV_POOL2 4 #define HOST_CONTIGUOUS_MEM_CHUNK_REQUIRED 0x8 -/** - * enum wlan_fw_mem_prio - defines FW Memory requirement type - * @FW_MEM_HIGH_PRIORITY: Memory requires contiguous memory allocation - * @FW_MEM_LOW_PRIORITY: Memory can be fragmented - * @FW_PRIORITY_MAX: Invalid type - */ -enum wlan_fw_mem_prio { - FW_MEM_HIGH_PRIORITY = 0, - FW_MEM_LOW_PRIORITY, - FW_PRIORITY_MAX -}; - /** * init_deinit_handle_host_mem_req() - handle host memory request * @psoc: PSOC object diff --git a/target_if/init_deinit/src/init_cmd_api.c b/target_if/init_deinit/src/init_cmd_api.c index 1d73b1be95..04ac9401a2 100644 --- a/target_if/init_deinit/src/init_cmd_api.c +++ b/target_if/init_deinit/src/init_cmd_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -182,98 +181,6 @@ static QDF_STATUS init_deinit_alloc_host_mem(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } -/** - * init_deinit_alloc_num_units() - allocates num units requested by FW. - * @psoc: PSOC object - * @tgt_hdl: Target PSOC info - * @mem_reqs: pointer to mem req - * @num_units: Number - * @i: FW priority - * @idx: Index - * - * API to allocate num units of host memory requested by FW - * - * Return: QDF_STATUS_SUCCESS on successful allocation - * QDF_STATUS_E_FAILURE on failure - */ -static QDF_STATUS init_deinit_alloc_num_units(struct wlan_objmgr_psoc *psoc, - struct target_psoc_info *tgt_hdl, - host_mem_req *mem_reqs, uint16_t fw_prio, - uint16_t idx) -{ - struct tgt_info *info; - uint32_t num_units; - QDF_STATUS status; - - if (!tgt_hdl || !mem_reqs) { - target_if_err("Invalid parameters, tgt_hdl: %pK, mem_reqs: %pK", - tgt_hdl, mem_reqs); - return QDF_STATUS_E_INVAL; - } - - info = (&tgt_hdl->info); - - if (((fw_prio == FW_MEM_HIGH_PRIORITY) && - (mem_reqs[idx].num_unit_info & - HOST_CONTIGUOUS_MEM_CHUNK_REQUIRED)) || - ((fw_prio == FW_MEM_LOW_PRIORITY) && - (!(mem_reqs[idx].num_unit_info & - HOST_CONTIGUOUS_MEM_CHUNK_REQUIRED)))) { - /* First allocate the memory that requires contiguous memory */ - num_units = mem_reqs[idx].num_units; - if (mem_reqs[idx].num_unit_info) { - if (mem_reqs[idx].num_unit_info & - NUM_UNITS_IS_NUM_PEERS) { - /* - * number of units allocated is equal to number - * of peers, 1 extra for self peer on target. - * this needs to be fixed, host and target can - * get out of sync - */ - num_units = info->wlan_res_cfg.num_peers + 1; - } - if (mem_reqs[idx].num_unit_info & - NUM_UNITS_IS_NUM_ACTIVE_PEERS) { - /* - * Requesting allocation of memory using - * num_active_peers in qcache. if qcache is - * disabled in host, then it should allocate - * memory for num_peers instead of - * num_active_peers. - */ - if (info->wlan_res_cfg.num_active_peers) - num_units = - info->wlan_res_cfg.num_active_peers + 1; - else - num_units = - info->wlan_res_cfg.num_peers + 1; - } - } - - target_if_debug("idx %d req %d num_units %d num_unit_info %d unit size %d actual units %d", - idx, mem_reqs[idx].req_id, - mem_reqs[idx].num_units, - mem_reqs[idx].num_unit_info, - mem_reqs[idx].unit_size, num_units); - - status = init_deinit_alloc_host_mem(psoc, tgt_hdl, - mem_reqs[idx].req_id, num_units, - mem_reqs[idx].unit_size, - mem_reqs[idx].num_unit_info); - if (status == QDF_STATUS_E_FAILURE) { - target_if_err( - "psoc:(%pK) num_mem_chunk exceeds supp number", - psoc); - return QDF_STATUS_E_FAILURE; - } else if (status == QDF_STATUS_E_NOMEM) { - target_if_err("soc:(%pK) mem alloc failure", psoc); - return QDF_STATUS_E_NOMEM; - } - } - - return QDF_STATUS_SUCCESS; -} - QDF_STATUS init_deinit_free_num_units(struct wlan_objmgr_psoc *psoc, struct target_psoc_info *tgt_hdl) { @@ -300,12 +207,12 @@ QDF_STATUS init_deinit_free_num_units(struct wlan_objmgr_psoc *psoc, info = (&tgt_hdl->info); for (idx = 0; idx < info->num_mem_chunks; idx++) { qdf_mem_free_consistent( - qdf_dev, qdf_dev->dev, - info->mem_chunks[idx].len, - info->mem_chunks[idx].vaddr, - info->mem_chunks[idx].paddr, - qdf_get_dma_mem_context( - (&(info->mem_chunks[idx])), memctx)); + qdf_dev, qdf_dev->dev, + info->mem_chunks[idx].len, + info->mem_chunks[idx].vaddr, + info->mem_chunks[idx].paddr, + qdf_get_dma_mem_context( + (&info->mem_chunks[idx]), memctx)); info->mem_chunks[idx].vaddr = NULL; info->mem_chunks[idx].paddr = 0; @@ -319,11 +226,11 @@ QDF_STATUS init_deinit_free_num_units(struct wlan_objmgr_psoc *psoc, } QDF_STATUS init_deinit_handle_host_mem_req( - struct wlan_objmgr_psoc *psoc, - struct target_psoc_info *tgt_hdl, uint8_t *event) + struct wlan_objmgr_psoc *psoc, + struct target_psoc_info *tgt_hdl, uint8_t *event) { - uint8_t num_mem_reqs; - host_mem_req *mem_reqs; + uint32_t num_mem_reqs; + host_mem_req mem_reqs; uint32_t i; uint32_t idx; QDF_STATUS status = QDF_STATUS_SUCCESS; @@ -338,21 +245,38 @@ QDF_STATUS init_deinit_handle_host_mem_req( wmi_handle = target_psoc_get_wmi_hdl(tgt_hdl); info = (&tgt_hdl->info); - mem_reqs = wmi_extract_host_mem_req_from_service_ready( - wmi_handle, event, &num_mem_reqs); + num_mem_reqs = wmi_extract_num_mem_reqs_from_service_ready( + wmi_handle, event); if (!num_mem_reqs) return QDF_STATUS_SUCCESS; if (num_mem_reqs > MAX_MEM_CHUNKS) { target_if_err_rl("num_mem_reqs:%u is out of bounds", - num_mem_reqs); + num_mem_reqs); return QDF_STATUS_E_FAILURE; } - for (i = 0; i < FW_PRIORITY_MAX; i++) { + for (i = 0; i < WMI_FW_PRIORITY_MAX; i++) { for (idx = 0; idx < num_mem_reqs; idx++) { - status = init_deinit_alloc_num_units(psoc, tgt_hdl, - mem_reqs, i, idx); + status = wmi_extract_host_mem_req_from_service_ready( + wmi_handle, event, &mem_reqs, + info->wlan_res_cfg.num_active_peers, + info->wlan_res_cfg.num_peers, i, idx); + if (mem_reqs.tgt_num_units) { + status = init_deinit_alloc_host_mem( + psoc, + tgt_hdl, + mem_reqs.req_id, + mem_reqs.tgt_num_units, + mem_reqs.unit_size, + mem_reqs.num_unit_info); + if (status == QDF_STATUS_E_FAILURE) { + target_if_err("num_mem_chunk exceeds supp number"); + } else if (status == QDF_STATUS_E_NOMEM) { + target_if_err("mem alloc failure"); + } + } + if (status != QDF_STATUS_SUCCESS) return status; } diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index 7744b5293e..519a628e9e 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -148,6 +148,18 @@ enum wmi_rx_exec_ctx { WMI_RX_SERIALIZER_CTX = 2 }; +/** + * enum wmi_fw_mem_prio - defines FW Memory requirement type + * @WMI_FW_MEM_HIGH_PRIORITY: Memory requires contiguous memory allocation + * @WMI_FW_MEM_LOW_PRIORITY: Memory can be fragmented + * @WMI_FW_PRIORITY_MAX: Invalid type + */ +enum wmi_fw_mem_prio { + WMI_FW_MEM_HIGH_PRIORITY = 0, + WMI_FW_MEM_LOW_PRIORITY, + WMI_FW_PRIORITY_MAX +}; + /** * struct wmi_unified_attach_params - wmi init parameters * @osdev: NIC device @@ -2251,18 +2263,35 @@ QDF_STATUS wmi_extract_hal_reg_cap(wmi_unified_t wmi_handle, void *evt_buf, struct wlan_psoc_hal_reg_capability *hal_reg_cap); +/** + * wmi_extract_num_mem_reqs_from_service_ready() - Extract number of memory + * entries requested + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * + * Return: Number of entries requested + */ +uint32_t wmi_extract_num_mem_reqs_from_service_ready( + wmi_unified_t wmi_handle, + void *evt_buf); + /** * wmi_extract_host_mem_req_from_service_ready() - Extract host memory * request event * @wmi_handle: wmi handle * @evt_buf: pointer to event buffer - * @num_entries: pointer to hold number of entries requested + * @mem_reqs: pointer to host memory request structure + * @num_active_peers: number of active peers for peer cache + * @num_peers: number of peers + * @fw_prio: FW priority + * @idx: Index for memory request * - * Return: Number of entries requested + * Return: Host memory request parameters requested by target */ -host_mem_req *wmi_extract_host_mem_req_from_service_ready( - wmi_unified_t wmi_handle, - void *evt_buf, uint8_t *num_entries); +QDF_STATUS wmi_extract_host_mem_req_from_service_ready( + wmi_unified_t wmi_handle, void *evt_buf, host_mem_req *mem_reqs, + uint32_t num_active_peers, uint32_t num_peers, + enum wmi_fw_mem_prio fw_prio, uint16_t idx); /** * wmi_ready_extract_init_status() - Extract init status from ready event diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index a2616856de..2456a2b1fd 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -2606,12 +2606,14 @@ struct extscan_bssid_hotlist_set_params { * @unit_size: Size of single unit requested. * @num_unit_info: Memory chunk info * @num_units: number of units requested. + * @tgt_num_units: number of units request by target. */ typedef struct { uint32_t req_id; uint32_t unit_size; uint32_t num_unit_info; uint32_t num_units; + uint32_t tgt_num_units; } host_mem_req; #define WMI_HOST_DSCP_MAP_MAX (64) diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 1d7ca98206..d270c9e48e 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -1262,8 +1262,14 @@ QDF_STATUS (*extract_fw_abi_version)(wmi_unified_t wmi_handle, QDF_STATUS (*extract_hal_reg_cap)(wmi_unified_t wmi_handle, void *evt_buf, struct wlan_psoc_hal_reg_capability *hal_reg_cap); -host_mem_req * (*extract_host_mem_req)(wmi_unified_t wmi_handle, - void *evt_buf, uint8_t *num_entries); +uint32_t (*extract_num_mem_reqs)(wmi_unified_t wmi_handle, + void *evt_buf); + +QDF_STATUS (*extract_host_mem_req)(wmi_unified_t wmi_handle, + void *evt_buf, host_mem_req *mem_reqs, + uint32_t num_active_peers, + uint32_t num_peers, + enum wmi_fw_mem_prio fw_prio, uint16_t idx); QDF_STATUS (*init_cmd_send)(wmi_unified_t wmi_handle, struct wmi_init_cmd_param *param); diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index 1db3046e57..2a75468704 100644 --- a/wmi/src/wmi_unified_api.c +++ b/wmi/src/wmi_unified_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -1636,17 +1636,33 @@ wmi_extract_hal_reg_cap(wmi_unified_t wmi_handle, void *evt_buf, return QDF_STATUS_E_FAILURE; } -host_mem_req -*wmi_extract_host_mem_req_from_service_ready( +uint32_t +wmi_extract_num_mem_reqs_from_service_ready( wmi_unified_t wmi_handle, - void *evt_buf, uint8_t *num_entries) + void *evt_buf) +{ + if (wmi_handle->ops->extract_num_mem_reqs) + return wmi_handle->ops->extract_num_mem_reqs(wmi_handle, + evt_buf); + + return 0; +} + +QDF_STATUS +wmi_extract_host_mem_req_from_service_ready(wmi_unified_t wmi_handle, + void *evt_buf, + host_mem_req *mem_reqs, + uint32_t num_active_peers, + uint32_t num_peers, + enum wmi_fw_mem_prio fw_prio, + uint16_t idx) { if (wmi_handle->ops->extract_host_mem_req) return wmi_handle->ops->extract_host_mem_req(wmi_handle, - evt_buf, num_entries); + evt_buf, mem_reqs, num_active_peers, + num_peers, fw_prio, idx); - *num_entries = 0; - return NULL; + return QDF_STATUS_E_FAILURE; } uint32_t wmi_ready_extract_init_status(wmi_unified_t wmi_handle, void *ev) diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 56a27a73d7..9cf0cedcc6 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -8651,15 +8651,14 @@ static QDF_STATUS extract_hal_reg_cap_tlv(wmi_unified_t wmi_handle, } /** - * extract_host_mem_req_tlv() - Extract host memory request event + * extract_num_mem_reqs_tlv() - Extract number of memory entries requested * @wmi_handle: wmi handle - * @param evt_buf: pointer to event buffer - * @param num_entries: pointer to hold number of entries requested + * @evt_buf: pointer to event buffer * * Return: Number of entries requested */ -static host_mem_req *extract_host_mem_req_tlv(wmi_unified_t wmi_handle, - void *evt_buf, uint8_t *num_entries) +static uint32_t extract_num_mem_reqs_tlv(wmi_unified_t wmi_handle, + void *evt_buf) { WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; wmi_service_ready_event_fixed_param *ev; @@ -8669,18 +8668,97 @@ static host_mem_req *extract_host_mem_req_tlv(wmi_unified_t wmi_handle, ev = (wmi_service_ready_event_fixed_param *) param_buf->fixed_param; if (!ev) { qdf_print("%s: wmi_buf_alloc failed", __func__); - return NULL; + return 0; } if (ev->num_mem_reqs > param_buf->num_mem_reqs) { WMI_LOGE("Invalid num_mem_reqs %d:%d", ev->num_mem_reqs, param_buf->num_mem_reqs); - return NULL; + return 0; } - *num_entries = ev->num_mem_reqs; + return ev->num_mem_reqs; +} - return (host_mem_req *)param_buf->mem_reqs; +/** + * extract_host_mem_req_tlv() - Extract host memory required from + * service ready event + * @wmi_handle: wmi handle + * @evt_buf: pointer to event buffer + * @mem_reqs: pointer to host memory request structure + * @num_active_peers: number of active peers for peer cache + * @num_peers: number of peers + * @fw_prio: FW priority + * @idx: index for memory request + * + * Return: Host memory request parameters requested by target + */ +static QDF_STATUS extract_host_mem_req_tlv(wmi_unified_t wmi_handle, + void *evt_buf, + host_mem_req *mem_reqs, + uint32_t num_active_peers, + uint32_t num_peers, + enum wmi_fw_mem_prio fw_prio, + uint16_t idx) +{ + WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; + + param_buf = (WMI_SERVICE_READY_EVENTID_param_tlvs *)evt_buf; + + mem_reqs->req_id = (uint32_t)param_buf->mem_reqs[idx].req_id; + mem_reqs->unit_size = (uint32_t)param_buf->mem_reqs[idx].unit_size; + mem_reqs->num_unit_info = + (uint32_t)param_buf->mem_reqs[idx].num_unit_info; + mem_reqs->num_units = (uint32_t)param_buf->mem_reqs[idx].num_units; + mem_reqs->tgt_num_units = 0; + + if (((fw_prio == WMI_FW_MEM_HIGH_PRIORITY) && + (mem_reqs->num_unit_info & + REQ_TO_HOST_FOR_CONT_MEMORY)) || + ((fw_prio == WMI_FW_MEM_LOW_PRIORITY) && + (!(mem_reqs->num_unit_info & + REQ_TO_HOST_FOR_CONT_MEMORY)))) { + /* First allocate the memory that requires contiguous memory */ + mem_reqs->tgt_num_units = mem_reqs->num_units; + if (mem_reqs->num_unit_info) { + if (mem_reqs->num_unit_info & + NUM_UNITS_IS_NUM_PEERS) { + /* + * number of units allocated is equal to number + * of peers, 1 extra for self peer on target. + * this needs to be fixed, host and target can + * get out of sync + */ + mem_reqs->tgt_num_units = num_peers + 1; + } + if (mem_reqs->num_unit_info & + NUM_UNITS_IS_NUM_ACTIVE_PEERS) { + /* + * Requesting allocation of memory using + * num_active_peers in qcache. if qcache is + * disabled in host, then it should allocate + * memory for num_peers instead of + * num_active_peers. + */ + if (num_active_peers) + mem_reqs->tgt_num_units = + num_active_peers + 1; + else + mem_reqs->tgt_num_units = + num_peers + 1; + } + } + + WMI_LOGI("idx %d req %d num_units %d num_unit_info %d" + "unit size %d actual units %d", + idx, mem_reqs->req_id, + mem_reqs->num_units, + mem_reqs->num_unit_info, + mem_reqs->unit_size, + mem_reqs->tgt_num_units); + } + + return QDF_STATUS_SUCCESS; } /** @@ -13006,6 +13084,7 @@ struct wmi_ops tlv_ops = { .send_addba_clearresponse_cmd = send_addba_clearresponse_cmd_tlv, .get_target_cap_from_service_ready = extract_service_ready_tlv, .extract_hal_reg_cap = extract_hal_reg_cap_tlv, + .extract_num_mem_reqs = extract_num_mem_reqs_tlv, .extract_host_mem_req = extract_host_mem_req_tlv, .save_service_bitmap = save_service_bitmap_tlv, .save_ext_service_bitmap = save_ext_service_bitmap_tlv,