mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-15 01:01:56 -04:00
Merge "qcacmn: Add implementation for WMI_OEM_DMA_RING_CFG_REQ_CMDID"
This commit is contained in:
commit
e66556a21e
18 changed files with 622 additions and 95 deletions
|
|
@ -157,6 +157,9 @@ enum hal_ring_type {
|
|||
RXDMA_MONITOR_STATUS,
|
||||
RXDMA_MONITOR_DST,
|
||||
RXDMA_MONITOR_DESC,
|
||||
#ifdef WLAN_FEATURE_CIF_CFR
|
||||
WIFI_POS_SRC,
|
||||
#endif
|
||||
MAX_RING_TYPES
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -147,7 +147,10 @@ enum hal_srng_ring_id {
|
|||
HAL_SRNG_WMAC1_RXDMA2SW0 = 133,
|
||||
HAL_SRNG_WMAC1_RXDMA2SW1 = 134,
|
||||
HAL_SRNG_WMAC1_SW2RXDMA1_DESC = 135,
|
||||
/* 136-142 unused */
|
||||
#ifdef WLAN_FEATURE_CIF_CFR
|
||||
HAL_SRNG_WIFI_POS_SRC_DMA_RING = 136,
|
||||
#endif
|
||||
/* 137-142 unused */
|
||||
HAL_SRNG_LMAC1_ID_END = 143
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -497,6 +497,20 @@ static struct hal_hw_srng_config hw_srng_table[] = {
|
|||
.reg_start = {},
|
||||
.reg_size = {},
|
||||
},
|
||||
#ifdef WLAN_FEATURE_CIF_CFR
|
||||
{ /* WIFI_POS_SRC */
|
||||
.start_ring_id = HAL_SRNG_WIFI_POS_SRC_DMA_RING,
|
||||
.max_rings = 1,
|
||||
.entry_size = sizeof(wmi_oem_dma_buf_release_entry) >> 2,
|
||||
.lmac_ring = TRUE,
|
||||
.ring_dir = HAL_SRNG_SRC_RING,
|
||||
/* reg_start is not set because LMAC rings are not accessed
|
||||
* from host
|
||||
*/
|
||||
.reg_start = {},
|
||||
.reg_size = {},
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -757,6 +757,9 @@ QDF_STATUS pmo_core_psoc_bus_runtime_suspend(struct wlan_objmgr_psoc *psoc,
|
|||
goto dec_psoc_ref;
|
||||
}
|
||||
|
||||
wow_params.interface_pause = PMO_WOW_INTERFACE_PAUSE_ENABLE;
|
||||
wow_params.resume_trigger = PMO_WOW_RESUME_TRIGGER_GPIO;
|
||||
|
||||
if (hif_pre_runtime_suspend(hif_ctx))
|
||||
goto runtime_failure;
|
||||
|
||||
|
|
|
|||
|
|
@ -605,8 +605,8 @@ static inline size_t __qdf_nbuf_len(struct sk_buff *skb)
|
|||
* @dst: Buffer to piggyback into
|
||||
* @src: Buffer to put
|
||||
*
|
||||
* Link tow nbufs the new buf is piggybacked into the older one. The older
|
||||
* (src) skb is released.
|
||||
* Concat two nbufs, the new buf(src) is piggybacked into the older one.
|
||||
* It is callers responsibility to free the src skb.
|
||||
*
|
||||
* Return: QDF_STATUS (status of the call) if failed the src skb
|
||||
* is released
|
||||
|
|
@ -628,11 +628,9 @@ __qdf_nbuf_cat(struct sk_buff *dst, struct sk_buff *src)
|
|||
if (error)
|
||||
return __qdf_to_status(error);
|
||||
}
|
||||
|
||||
memcpy(skb_tail_pointer(dst), src->data, src->len);
|
||||
|
||||
skb_put(dst, src->len);
|
||||
dev_kfree_skb_any(src);
|
||||
|
||||
return __qdf_to_status(error);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,6 +124,13 @@ static inline void target_if_wifi_pos_register_rx_ops(
|
|||
QDF_STATUS target_if_wifi_pos_init_cir_cfr_rings(struct wlan_objmgr_psoc *psoc,
|
||||
void *hal_soc, uint8_t num_mac,
|
||||
void *buf);
|
||||
/**
|
||||
* target_if_wifi_pos_deinit_dma_rings: frees up DMA rings
|
||||
* @psoc: pointer to psoc
|
||||
*
|
||||
* Return: status of operation
|
||||
*/
|
||||
QDF_STATUS target_if_wifi_pos_deinit_dma_rings(struct wlan_objmgr_psoc *psoc);
|
||||
#else
|
||||
static inline QDF_STATUS target_if_wifi_pos_init_cir_cfr_rings(
|
||||
struct wlan_objmgr_psoc *psoc, void *hal_soc,
|
||||
|
|
@ -131,6 +138,12 @@ static inline QDF_STATUS target_if_wifi_pos_init_cir_cfr_rings(
|
|||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline QDF_STATUS target_if_wifi_pos_deinit_dma_rings(
|
||||
struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _WIFI_POS_TGT_IF_H_ */
|
||||
|
|
|
|||
|
|
@ -38,56 +38,185 @@
|
|||
#include "target_if.h"
|
||||
#ifdef WLAN_FEATURE_CIF_CFR
|
||||
#include "hal_api.h"
|
||||
|
||||
#define RING_BASE_ALIGN 8
|
||||
|
||||
static void *target_if_wifi_pos_vaddr_lookup(
|
||||
struct wifi_pos_psoc_priv_obj *priv,
|
||||
void *paddr, uint8_t ring_num, uint32_t cookie)
|
||||
{
|
||||
if (priv->dma_buf_pool[ring_num][cookie].paddr == paddr) {
|
||||
return priv->dma_buf_pool[ring_num][cookie].vaddr +
|
||||
priv->dma_buf_pool[ring_num][cookie].offset;
|
||||
} else {
|
||||
target_if_err("incorrect paddr found on cookie slot");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static QDF_STATUS target_if_wifi_pos_replenish_ring(
|
||||
struct wifi_pos_psoc_priv_obj *priv, uint8_t ring_idx,
|
||||
void *alinged_vaddr, uint32_t cookie)
|
||||
{
|
||||
uint64_t *ring_entry;
|
||||
uint32_t dw_lo, dw_hi = 0, map_status;
|
||||
void *hal_soc = priv->hal_soc;
|
||||
void *srng = priv->dma_cfg[ring_idx].srng;
|
||||
void *paddr;
|
||||
|
||||
if (!alinged_vaddr) {
|
||||
target_if_debug("NULL alinged_vaddr provided");
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
map_status = qdf_mem_map_nbytes_single(NULL, alinged_vaddr,
|
||||
QDF_DMA_FROM_DEVICE,
|
||||
priv->dma_cap[ring_idx].min_buf_size,
|
||||
(qdf_dma_addr_t *)&paddr);
|
||||
if (map_status) {
|
||||
target_if_err("mem map failed status: %d", map_status);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
QDF_ASSERT(!((uint64_t)paddr % priv->dma_cap[ring_idx].min_buf_align));
|
||||
priv->dma_buf_pool[ring_idx][cookie].paddr = paddr;
|
||||
|
||||
hal_srng_access_start(hal_soc, srng);
|
||||
ring_entry = hal_srng_src_get_next(hal_soc, srng);
|
||||
dw_lo = (uint64_t)paddr & 0xFFFFFFFF;
|
||||
WMI_OEM_DMA_DATA_ADDR_HI_SET(dw_hi, (uint64_t)paddr >> 32);
|
||||
WMI_OEM_DMA_DATA_ADDR_HI_HOST_DATA_SET(dw_hi, cookie);
|
||||
*ring_entry = (uint64_t)dw_hi << 32 | dw_lo;
|
||||
hal_srng_access_end(hal_soc, srng);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS target_if_wifi_pos_get_indirect_data(
|
||||
struct wifi_pos_psoc_priv_obj *priv_obj,
|
||||
wmi_oem_indirect_data *indirect,
|
||||
struct oem_data_rsp *rsp, uint32_t *cookie)
|
||||
{
|
||||
void *paddr = NULL;
|
||||
uint32_t addr_hi;
|
||||
uint8_t ring_idx = 0, num_rings;
|
||||
|
||||
if (!indirect) {
|
||||
target_if_debug("no indirect data. regular event received");
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ring_idx = indirect->pdev_id - 1;
|
||||
num_rings = priv_obj->num_rings;
|
||||
if (ring_idx >= num_rings) {
|
||||
target_if_err("incorrect pdev_id: %d", indirect->pdev_id);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
addr_hi = (uint64_t)WMI_OEM_DMA_DATA_ADDR_HI_GET(
|
||||
indirect->addr_hi);
|
||||
paddr = (void *)((uint64_t)addr_hi << 32 | indirect->addr_lo);
|
||||
*cookie = WMI_OEM_DMA_DATA_ADDR_HI_HOST_DATA_GET(
|
||||
indirect->addr_hi);
|
||||
rsp->vaddr = target_if_wifi_pos_vaddr_lookup(priv_obj,
|
||||
paddr, ring_idx, *cookie);
|
||||
rsp->dma_len = indirect->len;
|
||||
qdf_mem_unmap_nbytes_single(NULL, (qdf_dma_addr_t)paddr,
|
||||
QDF_DMA_FROM_DEVICE,
|
||||
priv_obj->dma_cap[ring_idx].min_buf_size);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#else
|
||||
static QDF_STATUS target_if_wifi_pos_replenish_ring(
|
||||
struct wifi_pos_psoc_priv_obj *priv, uint8_t ring_idx,
|
||||
void *vaddr, uint32_t cookie)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS target_if_wifi_pos_get_indirect_data(
|
||||
struct wifi_pos_psoc_priv_obj *priv_obj,
|
||||
wmi_oem_indirect_data *indirect,
|
||||
struct oem_data_rsp *rsp, uint32_t *cookie)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* wifi_pos_oem_rsp_ev_handler: handler registered with WMI_OEM_RESPONSE_EVENTID
|
||||
* target_if_wifi_pos_oem_rsp_ev_handler: handler registered with
|
||||
* WMI_OEM_RESPONSE_EVENTID
|
||||
* @scn: scn handle
|
||||
* @data_buf: event buffer
|
||||
* @data_len: event buffer length
|
||||
*
|
||||
* Return: status of operation
|
||||
*/
|
||||
static int wifi_pos_oem_rsp_ev_handler(ol_scn_t scn,
|
||||
static int target_if_wifi_pos_oem_rsp_ev_handler(ol_scn_t scn,
|
||||
uint8_t *data_buf,
|
||||
uint32_t data_len)
|
||||
{
|
||||
int ret;
|
||||
uint8_t ring_idx = 0;
|
||||
QDF_STATUS status;
|
||||
uint32_t cookie = 0;
|
||||
wmi_oem_indirect_data *indirect;
|
||||
struct oem_data_rsp oem_rsp = {0};
|
||||
struct wifi_pos_psoc_priv_obj *wifi_pos_psoc;
|
||||
struct wifi_pos_psoc_priv_obj *priv_obj;
|
||||
struct wlan_objmgr_psoc *psoc = wifi_pos_get_psoc();
|
||||
struct wlan_lmac_if_wifi_pos_rx_ops *wifi_pos_rx_ops = NULL;
|
||||
WMI_OEM_RESPONSE_EVENTID_param_tlvs *param_buf =
|
||||
(WMI_OEM_RESPONSE_EVENTID_param_tlvs *)data_buf;
|
||||
|
||||
if (!psoc) {
|
||||
wifi_pos_err("psoc is null");
|
||||
target_if_err("psoc is null");
|
||||
return QDF_STATUS_NOT_INITIALIZED;
|
||||
}
|
||||
wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(psoc);
|
||||
if (!wifi_pos_psoc) {
|
||||
wifi_pos_err("wifi_pos_psoc is null");
|
||||
return QDF_STATUS_NOT_INITIALIZED;
|
||||
}
|
||||
qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock);
|
||||
|
||||
wlan_objmgr_psoc_get_ref(psoc, WLAN_WIFI_POS_ID);
|
||||
|
||||
wifi_pos_rx_ops = target_if_wifi_pos_get_rxops(psoc);
|
||||
/* this will be implemented later */
|
||||
if (!wifi_pos_rx_ops || !wifi_pos_rx_ops->oem_rsp_event_rx) {
|
||||
wifi_pos_err("lmac callbacks not registered");
|
||||
ret = QDF_STATUS_NOT_INITIALIZED;
|
||||
goto release_psoc_ref;
|
||||
priv_obj = wifi_pos_get_psoc_priv_obj(psoc);
|
||||
if (!priv_obj) {
|
||||
target_if_err("priv_obj is null");
|
||||
wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_ID);
|
||||
return QDF_STATUS_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
oem_rsp.rsp_len = param_buf->num_data;
|
||||
oem_rsp.data = param_buf->data;
|
||||
wifi_pos_rx_ops = target_if_wifi_pos_get_rxops(psoc);
|
||||
if (!wifi_pos_rx_ops || !wifi_pos_rx_ops->oem_rsp_event_rx) {
|
||||
wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_ID);
|
||||
target_if_err("lmac callbacks not registered");
|
||||
return QDF_STATUS_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
oem_rsp.rsp_len_1 = param_buf->num_data;
|
||||
oem_rsp.data_1 = param_buf->data;
|
||||
|
||||
if (param_buf->num_data2) {
|
||||
oem_rsp.rsp_len_2 = param_buf->num_data2;
|
||||
oem_rsp.data_2 = param_buf->data2;
|
||||
}
|
||||
|
||||
indirect = (wmi_oem_indirect_data *)param_buf->indirect_data;
|
||||
status = target_if_wifi_pos_get_indirect_data(priv_obj, indirect,
|
||||
&oem_rsp, &cookie);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
target_if_err("get indirect data failed status: %d", status);
|
||||
wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_ID);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
ret = wifi_pos_rx_ops->oem_rsp_event_rx(psoc, &oem_rsp);
|
||||
if (indirect)
|
||||
ring_idx = indirect->pdev_id - 1;
|
||||
status = target_if_wifi_pos_replenish_ring(priv_obj, ring_idx,
|
||||
oem_rsp.vaddr, cookie);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
target_if_err("replenish failed status: %d", status);
|
||||
ret = QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
release_psoc_ref:
|
||||
wlan_objmgr_psoc_release_ref(psoc, WLAN_WIFI_POS_ID);
|
||||
qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -151,15 +280,15 @@ static QDF_STATUS wifi_pos_oem_data_req(struct wlan_objmgr_psoc *psoc,
|
|||
QDF_STATUS status;
|
||||
void *wmi_hdl = GET_WMI_HDL_FROM_PSOC(psoc);
|
||||
|
||||
wifi_pos_debug("Send oem data req to target");
|
||||
target_if_debug("Send oem data req to target");
|
||||
|
||||
if (!req || !req->data) {
|
||||
wifi_pos_err("oem_data_req is null");
|
||||
target_if_err("oem_data_req is null");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (!wmi_hdl) {
|
||||
wifi_pos_err(FL("WMA closed, can't send oem data req cmd"));
|
||||
target_if_err("WMA closed, can't send oem data req cmd");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
|
|
@ -167,7 +296,7 @@ static QDF_STATUS wifi_pos_oem_data_req(struct wlan_objmgr_psoc *psoc,
|
|||
req->data);
|
||||
|
||||
if (!QDF_IS_STATUS_SUCCESS(status))
|
||||
wifi_pos_err("wmi cmd send failed");
|
||||
target_if_err("wmi cmd send failed");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
@ -190,7 +319,7 @@ inline struct wlan_lmac_if_wifi_pos_tx_ops *target_if_wifi_pos_get_txops(
|
|||
struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
if (!psoc) {
|
||||
wifi_pos_err("passed psoc is NULL");
|
||||
target_if_err("passed psoc is NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -201,7 +330,7 @@ inline struct wlan_lmac_if_wifi_pos_rx_ops *target_if_wifi_pos_get_rxops(
|
|||
struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
if (!psoc) {
|
||||
wifi_pos_err("passed psoc is NULL");
|
||||
target_if_err("passed psoc is NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -213,43 +342,43 @@ QDF_STATUS target_if_wifi_pos_register_events(struct wlan_objmgr_psoc *psoc)
|
|||
int ret;
|
||||
|
||||
if (!psoc || !psoc->tgt_if_handle) {
|
||||
wifi_pos_err("psoc or psoc->tgt_if_handle is null");
|
||||
target_if_err("psoc or psoc->tgt_if_handle is null");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
ret = wmi_unified_register_event_handler(psoc->tgt_if_handle,
|
||||
WMI_OEM_RESPONSE_EVENTID,
|
||||
wifi_pos_oem_rsp_ev_handler,
|
||||
WMI_RX_UMAC_CTX);
|
||||
target_if_wifi_pos_oem_rsp_ev_handler,
|
||||
WMI_RX_WORK_CTX);
|
||||
if (ret) {
|
||||
wifi_pos_err("register_event_handler failed: err %d", ret);
|
||||
target_if_err("register_event_handler failed: err %d", ret);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
ret = wmi_unified_register_event_handler(psoc->tgt_if_handle,
|
||||
wmi_oem_cap_event_id,
|
||||
wifi_pos_oem_cap_ev_handler,
|
||||
WMI_RX_UMAC_CTX);
|
||||
WMI_RX_WORK_CTX);
|
||||
if (ret) {
|
||||
wifi_pos_err("register_event_handler failed: err %d", ret);
|
||||
target_if_err("register_event_handler failed: err %d", ret);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
ret = wmi_unified_register_event_handler(psoc->tgt_if_handle,
|
||||
wmi_oem_meas_report_event_id,
|
||||
wifi_pos_oem_meas_rpt_ev_handler,
|
||||
WMI_RX_UMAC_CTX);
|
||||
WMI_RX_WORK_CTX);
|
||||
if (ret) {
|
||||
wifi_pos_err("register_event_handler failed: err %d", ret);
|
||||
target_if_err("register_event_handler failed: err %d", ret);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
ret = wmi_unified_register_event_handler(psoc->tgt_if_handle,
|
||||
wmi_oem_report_event_id,
|
||||
wifi_pos_oem_err_rpt_ev_handler,
|
||||
WMI_RX_UMAC_CTX);
|
||||
WMI_RX_WORK_CTX);
|
||||
if (ret) {
|
||||
wifi_pos_err("register_event_handler failed: err %d", ret);
|
||||
target_if_err("register_event_handler failed: err %d", ret);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
|
|
@ -259,7 +388,7 @@ QDF_STATUS target_if_wifi_pos_register_events(struct wlan_objmgr_psoc *psoc)
|
|||
QDF_STATUS target_if_wifi_pos_deregister_events(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
if (!psoc || !psoc->tgt_if_handle) {
|
||||
wifi_pos_err("psoc or psoc->tgt_if_handle is null");
|
||||
target_if_err("psoc or psoc->tgt_if_handle is null");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
|
|
@ -276,15 +405,216 @@ QDF_STATUS target_if_wifi_pos_deregister_events(struct wlan_objmgr_psoc *psoc)
|
|||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_CIF_CFR
|
||||
static QDF_STATUS target_if_wifi_pos_init_srngs(struct wlan_objmgr_psoc *psoc,
|
||||
void *hal_soc, struct wifi_pos_psoc_priv_obj *priv_obj)
|
||||
static QDF_STATUS target_if_wifi_pos_fill_ring(uint8_t ring_idx,
|
||||
struct hal_srng *srng,
|
||||
struct wifi_pos_psoc_priv_obj *priv)
|
||||
{
|
||||
uint32_t i;
|
||||
void *buf, *buf_aligned;
|
||||
|
||||
for (i = 0; i < priv->dma_cfg[ring_idx].num_ptr; i++) {
|
||||
buf = qdf_mem_malloc(priv->dma_cap[ring_idx].min_buf_size +
|
||||
priv->dma_cap[ring_idx].min_buf_align - 1);
|
||||
if (!buf) {
|
||||
target_if_err("malloc failed");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
priv->dma_buf_pool[ring_idx][i].vaddr = buf;
|
||||
buf_aligned = (void *)qdf_roundup((uint64_t)buf,
|
||||
priv->dma_cap[ring_idx].min_buf_align);
|
||||
priv->dma_buf_pool[ring_idx][i].offset = buf_aligned - buf;
|
||||
priv->dma_buf_pool[ring_idx][i].cookie = i;
|
||||
target_if_wifi_pos_replenish_ring(priv, ring_idx,
|
||||
buf_aligned, i);
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS target_if_wifi_pos_empty_ring(uint8_t ring_idx,
|
||||
struct wifi_pos_psoc_priv_obj *priv)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < priv->dma_cfg[ring_idx].num_ptr; i++) {
|
||||
qdf_mem_unmap_nbytes_single(NULL,
|
||||
(qdf_dma_addr_t)priv->dma_buf_pool[ring_idx][i].vaddr,
|
||||
QDF_DMA_FROM_DEVICE,
|
||||
priv->dma_cap[ring_idx].min_buf_size);
|
||||
qdf_mem_free(priv->dma_buf_pool[ring_idx][i].vaddr);
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS target_if_wifi_pos_init_ring(uint8_t ring_idx,
|
||||
struct wifi_pos_psoc_priv_obj *priv)
|
||||
{
|
||||
void *srng;
|
||||
uint32_t num_entries;
|
||||
qdf_dma_addr_t paddr;
|
||||
uint32_t ring_alloc_size;
|
||||
void *hal_soc = priv->hal_soc;
|
||||
struct hal_srng_params ring_params = {0};
|
||||
uint32_t max_entries = hal_srng_max_entries(hal_soc, WIFI_POS_SRC);
|
||||
uint32_t entry_size = hal_srng_get_entrysize(hal_soc, WIFI_POS_SRC);
|
||||
|
||||
num_entries = priv->dma_cap[ring_idx].min_num_ptr > max_entries ?
|
||||
max_entries : priv->dma_cap[ring_idx].min_num_ptr;
|
||||
priv->dma_cfg[ring_idx].num_ptr = num_entries;
|
||||
priv->dma_buf_pool[ring_idx] = qdf_mem_malloc(num_entries *
|
||||
sizeof(struct wifi_pos_dma_buf_info));
|
||||
if (!priv->dma_buf_pool[ring_idx]) {
|
||||
target_if_err("malloc failed");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
ring_alloc_size = (num_entries * entry_size) + RING_BASE_ALIGN - 1;
|
||||
priv->dma_cfg[ring_idx].ring_alloc_size = ring_alloc_size;
|
||||
priv->dma_cfg[ring_idx].base_vaddr_unaligned =
|
||||
qdf_mem_alloc_consistent(NULL, NULL, ring_alloc_size, &paddr);
|
||||
priv->dma_cfg[ring_idx].base_paddr_unaligned = (void *)paddr;
|
||||
if (!priv->dma_cfg[ring_idx].base_vaddr_unaligned) {
|
||||
target_if_err("malloc failed");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
priv->dma_cfg[ring_idx].base_vaddr_aligned = (void *)qdf_roundup(
|
||||
(uint64_t)priv->dma_cfg[ring_idx].base_vaddr_unaligned,
|
||||
RING_BASE_ALIGN);
|
||||
ring_params.ring_base_vaddr =
|
||||
priv->dma_cfg[ring_idx].base_vaddr_aligned;
|
||||
priv->dma_cfg[ring_idx].base_paddr_aligned = (void *)qdf_roundup(
|
||||
(uint64_t)priv->dma_cfg[ring_idx].base_paddr_unaligned,
|
||||
RING_BASE_ALIGN);
|
||||
ring_params.ring_base_paddr =
|
||||
(qdf_dma_addr_t)priv->dma_cfg[ring_idx].base_paddr_aligned;
|
||||
ring_params.num_entries = num_entries;
|
||||
srng = hal_srng_setup(hal_soc, WIFI_POS_SRC, 0,
|
||||
priv->dma_cap[ring_idx].pdev_id, &ring_params);
|
||||
if (!srng) {
|
||||
target_if_err("srng setup failed");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
priv->dma_cfg[ring_idx].srng = srng;
|
||||
priv->dma_cfg[ring_idx].tail_idx_addr =
|
||||
(void *)hal_srng_get_tp_addr(hal_soc, srng);
|
||||
priv->dma_cfg[ring_idx].head_idx_addr =
|
||||
(void *)hal_srng_get_tp_addr(hal_soc, srng);
|
||||
|
||||
return target_if_wifi_pos_fill_ring(ring_idx, srng, priv);
|
||||
}
|
||||
|
||||
static QDF_STATUS target_if_wifi_pos_deinit_ring(uint8_t ring_idx,
|
||||
struct wifi_pos_psoc_priv_obj *priv)
|
||||
{
|
||||
target_if_wifi_pos_empty_ring(ring_idx, priv);
|
||||
priv->dma_buf_pool[ring_idx] = NULL;
|
||||
hal_srng_cleanup(priv->hal_soc, priv->dma_cfg[ring_idx].srng);
|
||||
qdf_mem_free_consistent(NULL, NULL,
|
||||
priv->dma_cfg[ring_idx].ring_alloc_size,
|
||||
priv->dma_cfg[ring_idx].base_vaddr_unaligned,
|
||||
(qdf_dma_addr_t)priv->dma_cfg[ring_idx].base_paddr_unaligned,
|
||||
0);
|
||||
qdf_mem_free(priv->dma_buf_pool[ring_idx]);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS target_if_wifi_pos_init_srngs(
|
||||
struct wifi_pos_psoc_priv_obj *priv)
|
||||
{
|
||||
uint8_t i;
|
||||
QDF_STATUS status;
|
||||
|
||||
/* allocate memory for num_rings pointers */
|
||||
priv->dma_cfg = qdf_mem_malloc(priv->num_rings *
|
||||
sizeof(struct wifi_pos_dma_rings_cap));
|
||||
if (!priv->dma_cfg) {
|
||||
target_if_err("malloc failed");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
priv->dma_buf_pool = qdf_mem_malloc(priv->num_rings *
|
||||
sizeof(struct wifi_pos_dma_buf_info *));
|
||||
if (!priv->dma_buf_pool) {
|
||||
target_if_err("malloc failed");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < priv->num_rings; i++) {
|
||||
status = target_if_wifi_pos_init_ring(i, priv);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
target_if_err("init for ring[%d] failed", i);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS target_if_wifi_pos_deinit_srngs(
|
||||
struct wifi_pos_psoc_priv_obj *priv)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < priv->num_rings; i++)
|
||||
target_if_wifi_pos_deinit_ring(i, priv);
|
||||
|
||||
qdf_mem_free(priv->dma_buf_pool);
|
||||
priv->dma_buf_pool = NULL;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS target_if_wifi_pos_cfg_fw(struct wlan_objmgr_psoc *psoc,
|
||||
struct wifi_pos_psoc_priv_obj *priv_obj)
|
||||
struct wifi_pos_psoc_priv_obj *priv)
|
||||
{
|
||||
uint8_t i;
|
||||
QDF_STATUS status;
|
||||
void *wmi_hdl = GET_WMI_HDL_FROM_PSOC(psoc);
|
||||
wmi_oem_dma_ring_cfg_req_fixed_param cfg = {0};
|
||||
|
||||
if (!wmi_hdl) {
|
||||
target_if_err("WMA closed, can't send oem data req cmd");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
target_if_debug("Sending oem dma ring cfg to target");
|
||||
|
||||
for (i = 0; i < priv->num_rings; i++) {
|
||||
cfg.pdev_id = priv->dma_cfg[i].pdev_id;
|
||||
cfg.base_addr_lo = (uint64_t)priv->dma_cfg[i].base_paddr_aligned
|
||||
& 0xFFFFFFFF;
|
||||
cfg.base_addr_hi = (uint64_t)priv->dma_cfg[i].base_paddr_aligned
|
||||
& 0xFFFFFFFF00000000;
|
||||
cfg.head_idx_addr_lo = (uint64_t)priv->dma_cfg[i].head_idx_addr
|
||||
& 0xFFFFFFFF;
|
||||
cfg.head_idx_addr_hi = (uint64_t)priv->dma_cfg[i].head_idx_addr
|
||||
& 0xFFFFFFFF00000000;
|
||||
cfg.tail_idx_addr_lo = (uint64_t)priv->dma_cfg[i].tail_idx_addr
|
||||
& 0xFFFFFFFF;
|
||||
cfg.tail_idx_addr_hi = (uint64_t)priv->dma_cfg[i].tail_idx_addr
|
||||
& 0xFFFFFFFF00000000;
|
||||
cfg.num_ptr = priv->dma_cfg[i].num_ptr;
|
||||
status = wmi_unified_oem_dma_ring_cfg(wmi_hdl, &cfg);
|
||||
if (!QDF_IS_STATUS_SUCCESS(status)) {
|
||||
target_if_err("wmi cmd send failed");
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS target_if_wifi_pos_deinit_dma_rings(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
struct wifi_pos_psoc_priv_obj *priv = wifi_pos_get_psoc_priv_obj(psoc);
|
||||
|
||||
target_if_wifi_pos_deinit_srngs(priv);
|
||||
qdf_mem_free(priv->dma_cap);
|
||||
priv->dma_cap = NULL;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -293,37 +623,50 @@ QDF_STATUS target_if_wifi_pos_init_cir_cfr_rings(struct wlan_objmgr_psoc *psoc,
|
|||
void *buf)
|
||||
{
|
||||
uint8_t i;
|
||||
struct wifi_pos_psoc_priv_obj *priv_obj =
|
||||
wifi_pos_get_psoc_priv_obj(psoc);
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
WMI_OEM_DMA_RING_CAPABILITIES *dma_cap = buf;
|
||||
struct wifi_pos_psoc_priv_obj *priv = wifi_pos_get_psoc_priv_obj(psoc);
|
||||
|
||||
if (!priv_obj) {
|
||||
if (!priv) {
|
||||
target_if_err("unable to get wifi_pos psoc obj");
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
priv_obj->hal_soc = hal_soc;
|
||||
priv_obj->num_rings = num_mac;
|
||||
priv_obj->dma_cap = qdf_mem_malloc(priv_obj->num_rings *
|
||||
priv->hal_soc = hal_soc;
|
||||
priv->num_rings = num_mac;
|
||||
priv->dma_cap = qdf_mem_malloc(priv->num_rings *
|
||||
sizeof(struct wifi_pos_dma_rings_cap));
|
||||
if (!priv_obj->dma_cap) {
|
||||
if (!priv->dma_cap) {
|
||||
target_if_err("unable to get wifi_pos psoc obj");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_mac; i++) {
|
||||
priv_obj->dma_cap[i].pdev_id = dma_cap[i].pdev_id;
|
||||
priv_obj->dma_cap[i].min_num_ptr = dma_cap[i].min_num_ptr;
|
||||
priv_obj->dma_cap[i].min_buf_size = dma_cap[i].min_buf_size;
|
||||
priv_obj->dma_cap[i].min_buf_align = dma_cap[i].min_buf_align;
|
||||
priv->dma_cap[i].pdev_id = dma_cap[i].pdev_id;
|
||||
priv->dma_cap[i].min_num_ptr = dma_cap[i].min_num_ptr;
|
||||
priv->dma_cap[i].min_buf_size = dma_cap[i].min_buf_size;
|
||||
priv->dma_cap[i].min_buf_align = dma_cap[i].min_buf_align;
|
||||
}
|
||||
|
||||
/* initialize DMA rings now */
|
||||
target_if_wifi_pos_init_srngs(psoc, hal_soc, priv_obj);
|
||||
status = target_if_wifi_pos_init_srngs(priv);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
target_if_err("dma init failed: %d", status);
|
||||
goto dma_init_failed;
|
||||
}
|
||||
|
||||
/* send cfg req cmd to firmware */
|
||||
target_if_wifi_pos_cfg_fw(psoc, priv_obj);
|
||||
status = target_if_wifi_pos_cfg_fw(psoc, priv);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
target_if_err("configure to FW failed: %d", status);
|
||||
goto dma_init_failed;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
dma_init_failed:
|
||||
target_if_wifi_pos_deinit_dma_rings(psoc);
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -200,15 +200,12 @@ enum block_ack_actioncode {
|
|||
/**
|
||||
* enum pub_actioncode - public action frames
|
||||
* @PUB_ACTION_2040_BSS_COEXISTENCE: public 20-40 bss coex action frame
|
||||
* @PUB_ACTION_P2P_SUBTYPE_PRESENCE_RSP: public p2p subtype presence
|
||||
* response action frame
|
||||
* @PUB_ACTION_EXT_CHANNEL_SWITCH_ID: public ext channel switch id action frame
|
||||
* @PUB_ACTION_VENDOR_SPECIFIC: vendor specific public action frame
|
||||
* @PUB_ACTION_TDLS_DISCRESP: tdls discovery response public action frame
|
||||
*/
|
||||
enum pub_actioncode {
|
||||
PUB_ACTION_2040_BSS_COEXISTENCE = 0,
|
||||
PUB_ACTION_P2P_SUBTYPE_PRESENCE_RSP = 2,
|
||||
PUB_ACTION_EXT_CHANNEL_SWITCH_ID = 4,
|
||||
PUB_ACTION_VENDOR_SPECIFIC = 9,
|
||||
PUB_ACTION_TDLS_DISCRESP = 14,
|
||||
|
|
@ -434,7 +431,7 @@ struct action_frm_hdr {
|
|||
* @MGMT_ACTION_BA_ADDBA_RESPONSE: ADDBA response action frame
|
||||
* @MGMT_ACTION_BA_DELBA: DELBA action frame
|
||||
* @MGMT_ACTION_2040_BSS_COEXISTENCE: 20-40 bss coex action frame
|
||||
* @MGMT_ACTION_P2P_SUBTYPE_PRESENCE_RSP: p2p subtype presence rsp action frame
|
||||
* @MGMT_ACTION_CATEGORY_VENDOR_SPECIFIC: category vendor spcific action frame
|
||||
* @MGMT_ACTION_EXT_CHANNEL_SWITCH_ID: ext channel switch id action frame
|
||||
* @MGMT_ACTION_VENDOR_SPECIFIC: vendor specific action frame
|
||||
* @MGMT_ACTION_TDLS_DISCRESP: TDLS discovery response frame
|
||||
|
|
@ -529,7 +526,7 @@ enum mgmt_frame_type {
|
|||
MGMT_ACTION_BA_ADDBA_RESPONSE,
|
||||
MGMT_ACTION_BA_DELBA,
|
||||
MGMT_ACTION_2040_BSS_COEXISTENCE,
|
||||
MGMT_ACTION_P2P_SUBTYPE_PRESENCE_RSP,
|
||||
MGMT_ACTION_CATEGORY_VENDOR_SPECIFIC,
|
||||
MGMT_ACTION_EXT_CHANNEL_SWITCH_ID,
|
||||
MGMT_ACTION_VENDOR_SPECIFIC,
|
||||
MGMT_ACTION_TDLS_DISCRESP,
|
||||
|
|
|
|||
|
|
@ -187,9 +187,6 @@ mgmt_get_public_action_subtype(uint8_t action_code)
|
|||
case PUB_ACTION_2040_BSS_COEXISTENCE:
|
||||
frm_type = MGMT_ACTION_2040_BSS_COEXISTENCE;
|
||||
break;
|
||||
case PUB_ACTION_P2P_SUBTYPE_PRESENCE_RSP:
|
||||
frm_type = MGMT_ACTION_P2P_SUBTYPE_PRESENCE_RSP;
|
||||
break;
|
||||
case PUB_ACTION_EXT_CHANNEL_SWITCH_ID:
|
||||
frm_type = MGMT_ACTION_EXT_CHANNEL_SWITCH_ID;
|
||||
break;
|
||||
|
|
@ -681,6 +678,9 @@ mgmt_txrx_get_action_frm_subtype(uint8_t *mpdu_data_ptr)
|
|||
case ACTION_CATEGORY_VHT:
|
||||
frm_type = mgmt_get_vht_action_subtype(action_hdr->action_code);
|
||||
break;
|
||||
case ACTION_CATEGORY_VENDOR_SPECIFIC:
|
||||
frm_type = MGMT_ACTION_CATEGORY_VENDOR_SPECIFIC;
|
||||
break;
|
||||
default:
|
||||
frm_type = MGMT_FRM_UNSPECIFIED;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -535,6 +535,8 @@ static char *p2p_get_frame_type_str(struct p2p_frame_info *frame_info)
|
|||
return "Invalid P2P command";
|
||||
}
|
||||
|
||||
if (frame_info->action_type == P2P_ACTION_PRESENCE_REQ)
|
||||
return "P2P action presence request";
|
||||
if (frame_info->action_type == P2P_ACTION_PRESENCE_RSP)
|
||||
return "P2P action presence response";
|
||||
|
||||
|
|
@ -651,6 +653,9 @@ static QDF_STATUS p2p_get_frame_info(uint8_t *data_buf, uint32_t length,
|
|||
buf = data_buf +
|
||||
P2P_ACTION_FRAME_TYPE_OFFSET;
|
||||
action_type = buf[0];
|
||||
if (action_type == P2P_ACTION_PRESENCE_REQ)
|
||||
frame_info->action_type =
|
||||
P2P_ACTION_PRESENCE_REQ;
|
||||
if (action_type == P2P_ACTION_PRESENCE_RSP)
|
||||
frame_info->action_type =
|
||||
P2P_ACTION_PRESENCE_RSP;
|
||||
|
|
@ -1631,6 +1636,10 @@ QDF_STATUS p2p_process_rx_mgmt(
|
|||
}
|
||||
}
|
||||
|
||||
if (rx_mgmt->frm_type == MGMT_ACTION_CATEGORY_VENDOR_SPECIFIC)
|
||||
p2p_get_frame_info(rx_mgmt->buf, rx_mgmt->frame_len,
|
||||
&frame_info);
|
||||
|
||||
start_param = p2p_soc_obj->start_param;
|
||||
if (start_param->rx_cb)
|
||||
start_param->rx_cb(start_param->rx_cb_data, rx_mgmt);
|
||||
|
|
|
|||
|
|
@ -121,10 +121,12 @@ enum p2p_public_action_type {
|
|||
|
||||
/**
|
||||
* enum p2p_action_type - p2p action frame type
|
||||
* @P2P_ACTION_PRESENCE_REQ: presence request frame
|
||||
* @P2P_ACTION_PRESENCE_RSP: presence response frame
|
||||
* @P2P_ACTION_NOT_SUPPORT: not support action frame type
|
||||
*/
|
||||
enum p2p_action_type {
|
||||
P2P_ACTION_PRESENCE_REQ = 1,
|
||||
P2P_ACTION_PRESENCE_RSP = 2,
|
||||
P2P_ACTION_NOT_SUPPORT,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -545,20 +545,22 @@ static QDF_STATUS p2p_process_scan_complete_evt(
|
|||
QDF_STATUS p2p_mgmt_rx_action_ops(struct wlan_objmgr_psoc *psoc,
|
||||
bool isregister)
|
||||
{
|
||||
struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info;
|
||||
struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info[2];
|
||||
QDF_STATUS status;
|
||||
|
||||
p2p_debug("psoc:%p, is register rx:%d", psoc, isregister);
|
||||
|
||||
frm_cb_info.frm_type = MGMT_ACTION_VENDOR_SPECIFIC;
|
||||
frm_cb_info.mgmt_rx_cb = tgt_p2p_mgmt_frame_rx_cb;
|
||||
frm_cb_info[0].frm_type = MGMT_ACTION_VENDOR_SPECIFIC;
|
||||
frm_cb_info[0].mgmt_rx_cb = tgt_p2p_mgmt_frame_rx_cb;
|
||||
frm_cb_info[1].frm_type = MGMT_ACTION_CATEGORY_VENDOR_SPECIFIC;
|
||||
frm_cb_info[1].mgmt_rx_cb = tgt_p2p_mgmt_frame_rx_cb;
|
||||
|
||||
if (isregister)
|
||||
status = wlan_mgmt_txrx_register_rx_cb(psoc,
|
||||
WLAN_UMAC_COMP_P2P, &frm_cb_info, 1);
|
||||
WLAN_UMAC_COMP_P2P, frm_cb_info, 2);
|
||||
else
|
||||
status = wlan_mgmt_txrx_deregister_rx_cb(psoc,
|
||||
WLAN_UMAC_COMP_P2P, &frm_cb_info, 1);
|
||||
WLAN_UMAC_COMP_P2P, frm_cb_info, 2);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -447,6 +447,8 @@ QDF_STATUS wifi_pos_psoc_obj_destroyed_notification(
|
|||
return QDF_STATUS_E_FAULT;
|
||||
}
|
||||
|
||||
target_if_wifi_pos_deinit_dma_rings(psoc);
|
||||
|
||||
status = wlan_objmgr_psoc_component_obj_detach(psoc,
|
||||
WLAN_UMAC_COMP_WIFI_POS,
|
||||
wifi_pos_obj);
|
||||
|
|
@ -463,20 +465,52 @@ QDF_STATUS wifi_pos_psoc_obj_destroyed_notification(
|
|||
int wifi_pos_oem_rsp_handler(struct wlan_objmgr_psoc *psoc,
|
||||
struct oem_data_rsp *oem_rsp)
|
||||
{
|
||||
struct wifi_pos_psoc_priv_obj *wifi_pos_obj =
|
||||
uint32_t len;
|
||||
uint8_t *data;
|
||||
uint32_t app_pid;
|
||||
struct wifi_pos_psoc_priv_obj *priv =
|
||||
wifi_pos_get_psoc_priv_obj(psoc);
|
||||
/* handle oem event here */
|
||||
if (oem_rsp->rsp_len > OEM_DATA_RSP_SIZE) {
|
||||
void (*wifi_pos_send_rsp)(uint32_t, uint32_t, uint32_t, uint8_t *);
|
||||
|
||||
if (!priv) {
|
||||
wifi_pos_err("private object is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
qdf_spin_lock_bh(&priv->wifi_pos_lock);
|
||||
app_pid = priv->app_pid;
|
||||
wifi_pos_send_rsp = priv->wifi_pos_send_rsp;
|
||||
qdf_spin_unlock_bh(&priv->wifi_pos_lock);
|
||||
|
||||
len = oem_rsp->rsp_len_1 + oem_rsp->rsp_len_2 + oem_rsp->dma_len;
|
||||
if (oem_rsp->rsp_len_1 > OEM_DATA_RSP_SIZE ||
|
||||
oem_rsp->rsp_len_2 > OEM_DATA_RSP_SIZE) {
|
||||
wifi_pos_err("invalid length of Oem Data response");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
wifi_pos_debug("sending oem data rsp, len: %d to pid: %d",
|
||||
oem_rsp->rsp_len, wifi_pos_obj->app_pid);
|
||||
wifi_pos_obj->wifi_pos_send_rsp(wifi_pos_obj->app_pid,
|
||||
ANI_MSG_OEM_DATA_RSP,
|
||||
oem_rsp->rsp_len,
|
||||
oem_rsp->data);
|
||||
wifi_pos_debug("oem data rsp, len: %d to pid: %d", len, app_pid);
|
||||
|
||||
if (oem_rsp->rsp_len_2 + oem_rsp->dma_len) {
|
||||
/* stitch togther the msg data_1 + CIR/CFR + data_2 */
|
||||
data = qdf_mem_malloc(len);
|
||||
if (!data) {
|
||||
wifi_pos_err("malloc failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
qdf_mem_copy(data, oem_rsp->data_1, oem_rsp->rsp_len_1);
|
||||
qdf_mem_copy(&data[oem_rsp->rsp_len_1],
|
||||
oem_rsp->vaddr, oem_rsp->dma_len);
|
||||
qdf_mem_copy(&data[oem_rsp->rsp_len_1 + oem_rsp->dma_len],
|
||||
oem_rsp->data_2, oem_rsp->rsp_len_2);
|
||||
|
||||
wifi_pos_send_rsp(app_pid, ANI_MSG_OEM_DATA_RSP, len, data);
|
||||
qdf_mem_free(data);
|
||||
} else {
|
||||
wifi_pos_send_rsp(app_pid, ANI_MSG_OEM_DATA_RSP,
|
||||
oem_rsp->rsp_len_1, oem_rsp->data_1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,13 +106,21 @@ struct oem_data_req {
|
|||
|
||||
/**
|
||||
* struct oem_data_rsp - response from firmware to data request sent earlier
|
||||
* @data_len: len of data
|
||||
* @data: buffer containing data
|
||||
* @rsp_len_1: len of data_1
|
||||
* @data_1: first part of payload
|
||||
* @rsp_len_2: len of data_2
|
||||
* @data_2: second part of payload
|
||||
* @dma_len: len of DMAed data
|
||||
* @vaddr: virtual address of DMA data start
|
||||
*
|
||||
*/
|
||||
struct oem_data_rsp {
|
||||
uint32_t rsp_len;
|
||||
uint8_t *data;
|
||||
uint32_t rsp_len_1;
|
||||
uint8_t *data_1;
|
||||
uint32_t rsp_len_2;
|
||||
uint8_t *data_2;
|
||||
uint32_t dma_len;
|
||||
void *vaddr;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -196,26 +204,44 @@ struct wifi_pos_dma_rings_cap {
|
|||
uint32_t min_buf_align;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wifi_pos_dma_buf_info - buffer info struct containing phy to virtual
|
||||
* mapping.
|
||||
* @cookie: this identifies location of DMA buffer in pool array
|
||||
* @paddr: aligned physical address as exchanged with firmware
|
||||
* @vaddr: virtual address - unaligned. this helps in freeing later
|
||||
* @offset: offset of aligned address from unaligned
|
||||
*/
|
||||
struct wifi_pos_dma_buf_info {
|
||||
uint32_t cookie;
|
||||
void *paddr;
|
||||
void *vaddr;
|
||||
uint8_t offset;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wifi_pos_dma_rings_cfg - DMA ring parameters to be programmed to FW.
|
||||
* @pdev_id: pdev_id of ring
|
||||
* @base_addr_lo: Base address of ring, bits 31:0
|
||||
* @base_addr_hi: Base address of ring, bits 63:32
|
||||
* @head_idx_addr_lo: Address of head index register, bits 31:0
|
||||
* @head_idx_addr_hi: Address of head index register, bits 63:32
|
||||
* @tail_idx_addr_lo: Address of tail index register, bits 31:0
|
||||
* @tail_idx_addr_hi: Address of tail index register, bits 63:32
|
||||
* @num_ptr: Number of pointers in the ring
|
||||
* @num_ptr: depth of ring
|
||||
* @base_paddr_unaligned: base physical addr unaligned
|
||||
* @base_vaddr_unaligned: base virtual addr unaligned
|
||||
* @base_paddr_aligned: base physical addr aligned
|
||||
* @base_vaddr_aligned: base virtual addr unaligned
|
||||
* @head_idx_addr: head index addr
|
||||
* @tail_idx_addr: tail index addr
|
||||
* @srng: hal srng
|
||||
*/
|
||||
struct wifi_pos_dma_rings_cfg {
|
||||
uint32_t pdev_id;
|
||||
uint32_t base_addr_lo;
|
||||
uint32_t base_addr_hi;
|
||||
uint32_t head_idx_addr_lo;
|
||||
uint32_t head_idx_addr_hi;
|
||||
uint32_t tail_idx_addr_lo;
|
||||
uint32_t tail_idx_addr_hi;
|
||||
uint32_t num_ptr;
|
||||
uint32_t ring_alloc_size;
|
||||
void *base_paddr_unaligned;
|
||||
void *base_vaddr_unaligned;
|
||||
void *base_paddr_aligned;
|
||||
void *base_vaddr_aligned;
|
||||
void *head_idx_addr;
|
||||
void *tail_idx_addr;
|
||||
void *srng;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -234,9 +260,11 @@ struct wifi_pos_dma_rings_cfg {
|
|||
* @allowed_dwell_time_max: allowed dwell time max, populated from HDD
|
||||
* @current_dwell_time_min: current dwell time min, populated from HDD
|
||||
* @current_dwell_time_max: current dwell time max, populated from HDD
|
||||
* @hal_soc: hal_soc
|
||||
* @num_rings: DMA ring cap requested by firmware
|
||||
* @dma_cap: dma cap as read from service ready ext event
|
||||
* @dma_cfg: DMA ring cfg to be programmed to firmware
|
||||
* @dma_buf_pool: DMA buffer pools maintained at host: this will be 2-D array
|
||||
* where with num_rows = number of rings num_elements in each row = ring depth
|
||||
* @wifi_pos_lock: lock to access wifi pos priv object
|
||||
* @wifi_pos_req_handler: function pointer to handle TLV or non-TLV
|
||||
|
|
@ -269,9 +297,11 @@ struct wifi_pos_psoc_priv_obj {
|
|||
uint16_t current_dwell_time_min;
|
||||
uint16_t current_dwell_time_max;
|
||||
|
||||
void *hal_soc;
|
||||
uint8_t num_rings;
|
||||
struct wifi_pos_dma_rings_cap *dma_cap;
|
||||
struct wifi_pos_dma_rings_cfg *dma_cfg;
|
||||
struct wifi_pos_dma_buf_info **dma_buf_pool;
|
||||
|
||||
qdf_spinlock_t wifi_pos_lock;
|
||||
QDF_STATUS (*wifi_pos_req_handler)(struct wlan_objmgr_psoc *psoc,
|
||||
|
|
|
|||
|
|
@ -719,6 +719,19 @@ QDF_STATUS wmi_unified_nat_keepalive_en_cmd(void *wmi_hdl, uint8_t vdev_id);
|
|||
|
||||
QDF_STATUS wmi_unified_csa_offload_enable(void *wmi_hdl, uint8_t vdev_id);
|
||||
|
||||
#ifdef WLAN_FEATURE_CIF_CFR
|
||||
/**
|
||||
* wmi_unified_oem_dma_ring_cfg() - configure OEM DMA rings
|
||||
* @wmi_handle: wmi handle
|
||||
* @data_len: len of dma cfg req
|
||||
* @data: dma cfg req
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
|
||||
*/
|
||||
QDF_STATUS wmi_unified_oem_dma_ring_cfg(void *wmi_hdl,
|
||||
wmi_oem_dma_ring_cfg_req_fixed_param *cfg);
|
||||
#endif
|
||||
|
||||
QDF_STATUS wmi_unified_start_oem_data_cmd(void *wmi_hdl,
|
||||
uint32_t data_len,
|
||||
uint8_t *data);
|
||||
|
|
|
|||
|
|
@ -593,6 +593,11 @@ QDF_STATUS (*send_fw_profiling_cmd)(wmi_unified_t wmi_handle,
|
|||
|
||||
QDF_STATUS (*send_nat_keepalive_en_cmd)(wmi_unified_t wmi_handle, uint8_t vdev_id);
|
||||
|
||||
#ifdef WLAN_FEATURE_CIF_CFR
|
||||
QDF_STATUS (*send_oem_dma_cfg_cmd)(wmi_unified_t wmi_handle,
|
||||
wmi_oem_dma_ring_cfg_req_fixed_param *cfg);
|
||||
#endif
|
||||
|
||||
QDF_STATUS (*send_start_oem_data_cmd)(wmi_unified_t wmi_handle,
|
||||
uint32_t data_len,
|
||||
uint8_t *data);
|
||||
|
|
|
|||
|
|
@ -2258,6 +2258,20 @@ QDF_STATUS wmi_unified_csa_offload_enable(void *wmi_hdl, uint8_t vdev_id)
|
|||
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_CIF_CFR
|
||||
QDF_STATUS wmi_unified_oem_dma_ring_cfg(void *wmi_hdl,
|
||||
wmi_oem_dma_ring_cfg_req_fixed_param *cfg)
|
||||
{
|
||||
wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
|
||||
|
||||
if (wmi_handle->ops->send_start_oem_data_cmd)
|
||||
return wmi_handle->ops->send_oem_dma_cfg_cmd(wmi_handle, cfg);
|
||||
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* wmi_unified_start_oem_data_cmd() - start OEM data request to target
|
||||
* @wmi_handle: wmi handle
|
||||
|
|
|
|||
|
|
@ -7915,6 +7915,47 @@ static QDF_STATUS send_csa_offload_enable_cmd_tlv(wmi_unified_t wmi_handle,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_CIF_CFR
|
||||
/**
|
||||
* send_oem_dma_cfg_cmd_tlv() - configure OEM DMA rings
|
||||
* @wmi_handle: wmi handle
|
||||
* @data_len: len of dma cfg req
|
||||
* @data: dma cfg req
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
|
||||
*/
|
||||
static QDF_STATUS send_oem_dma_cfg_cmd_tlv(wmi_unified_t wmi_handle,
|
||||
wmi_oem_dma_ring_cfg_req_fixed_param *cfg)
|
||||
{
|
||||
wmi_buf_t buf;
|
||||
uint8_t *cmd;
|
||||
QDF_STATUS ret;
|
||||
|
||||
WMITLV_SET_HDR(cfg,
|
||||
WMITLV_TAG_STRUC_wmi_oem_dma_ring_cfg_req_fixed_param,
|
||||
(sizeof(*cfg) - WMI_TLV_HDR_SIZE));
|
||||
|
||||
buf = wmi_buf_alloc(wmi_handle, sizeof(*cfg));
|
||||
if (!buf) {
|
||||
WMI_LOGE(FL("wmi_buf_alloc failed"));
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
cmd = (uint8_t *) wmi_buf_data(buf);
|
||||
qdf_mem_copy(cmd, cfg, sizeof(*cfg));
|
||||
WMI_LOGI(FL("Sending OEM Data Request to target, data len %lu"),
|
||||
sizeof(*cfg));
|
||||
ret = wmi_unified_cmd_send(wmi_handle, buf, sizeof(*cfg),
|
||||
WMI_OEM_DMA_RING_CFG_REQ_CMDID);
|
||||
if (QDF_IS_STATUS_ERROR(ret)) {
|
||||
WMI_LOGE(FL(":wmi cmd send failed"));
|
||||
wmi_buf_free(buf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* send_start_oem_data_cmd_tlv() - start OEM data request to target
|
||||
* @wmi_handle: wmi handle
|
||||
|
|
@ -17739,6 +17780,9 @@ struct wmi_ops tlv_ops = {
|
|||
.send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv,
|
||||
.send_nat_keepalive_en_cmd = send_nat_keepalive_en_cmd_tlv,
|
||||
.send_start_oem_data_cmd = send_start_oem_data_cmd_tlv,
|
||||
#ifdef WLAN_FEATURE_CIF_CFR
|
||||
.send_oem_dma_cfg_cmd = send_oem_dma_cfg_cmd_tlv,
|
||||
#endif
|
||||
.send_dfs_phyerr_filter_offload_en_cmd =
|
||||
send_dfs_phyerr_filter_offload_en_cmd_tlv,
|
||||
.send_wow_delete_pattern_cmd = send_wow_delete_pattern_cmd_tlv,
|
||||
|
|
|
|||
Loading…
Reference in a new issue