Merge "qcacmn: Perform cleanup of send_init_cmd"

This commit is contained in:
Linux Build Service Account 2017-11-08 21:21:48 -08:00 • committed by Gerrit - the friendly Code Review server
commit 92794de618
25 changed files with 777 additions and 364 deletions

View file

@ -157,10 +157,10 @@ static inline void cdp_peer_teardown
}
static inline void
cdp_peer_delete(ol_txrx_soc_handle soc, void *peer)
cdp_peer_delete(ol_txrx_soc_handle soc, void *peer, uint32_t bitmap)
{
if (soc->ops->cmn_drv_ops->txrx_peer_delete)
return soc->ops->cmn_drv_ops->txrx_peer_delete(peer);
return soc->ops->cmn_drv_ops->txrx_peer_delete(peer, bitmap);
return;
}

View file

@ -991,6 +991,8 @@ struct cdp_pdev_stats {
uint32_t map_err;
/* x86 failures */
uint32_t x86_fail;
/* low threshold interrupts */
uint32_t low_thresh_intrs;
} replenish;
/* Rx Raw Packets */

View file

@ -36,6 +36,12 @@
#include <linux/ipa.h>
#endif
/**
* bitmap values to indicate special handling of peer_delete
*/
#define CDP_PEER_DELETE_NO_SPECIAL 0
#define CDP_PEER_DO_NOT_START_UNMAP_TIMER 1
/******************************************************************************
*
* Control Interface (A Interface)
@ -75,7 +81,7 @@ struct cdp_cmn_ops {
void (*txrx_peer_teardown)
(struct cdp_vdev *vdev_hdl, void *peer_hdl);
void (*txrx_peer_delete)(void *peer);
void (*txrx_peer_delete)(void *peer, uint32_t bitmap);
int (*txrx_set_monitor_mode)(struct cdp_vdev *vdev,
uint8_t smart_monitor);

View file

@ -29,6 +29,9 @@
#include "dp_tx.h"
#include "dp_ipa.h"
/* Hard coded config parameters until dp_ops_cfg.cfg_attach implemented */
#define CFG_IPA_UC_TX_BUF_SIZE_DEFAULT (2048)
/**
* dp_tx_ipa_uc_detach - Free autonomy TX resources
* @soc: data path instance
@ -41,16 +44,37 @@
static void dp_tx_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
{
int idx;
uint32_t ring_base_align = 8;
/*
* Uncomment when dp_ops_cfg.cfg_attach is implemented
* unsigned int uc_tx_buf_sz =
* dp_cfg_ipa_uc_tx_buf_size(pdev->osif_pdev);
*/
unsigned int uc_tx_buf_sz = CFG_IPA_UC_TX_BUF_SIZE_DEFAULT;
unsigned int alloc_size = uc_tx_buf_sz + ring_base_align - 1;
for (idx = 0; idx < soc->ipa_uc_tx_rsc.alloc_tx_buf_cnt; idx++) {
if (soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr[idx]) {
qdf_mem_free(soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr[idx]);
soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr[idx] = NULL;
if (soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr_unaligned[idx]) {
qdf_mem_free_consistent(
soc->osdev, soc->osdev->dev,
alloc_size,
soc->ipa_uc_tx_rsc.
tx_buf_pool_vaddr_unaligned[idx],
soc->ipa_uc_tx_rsc.
tx_buf_pool_paddr_unaligned[idx],
0);
soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr_unaligned[idx] =
(void *)NULL;
soc->ipa_uc_tx_rsc.tx_buf_pool_paddr_unaligned[idx] =
(qdf_dma_addr_t)NULL;
}
}
qdf_mem_free(soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr);
soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr = NULL;
qdf_mem_free(soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr_unaligned);
soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr_unaligned = NULL;
qdf_mem_free(soc->ipa_uc_tx_rsc.tx_buf_pool_paddr_unaligned);
soc->ipa_uc_tx_rsc.tx_buf_pool_paddr_unaligned = NULL;
}
/**
@ -78,9 +102,6 @@ int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev)
return QDF_STATUS_SUCCESS; /* success */
}
/* Hard coded config parameters until dp_ops_cfg.cfg_attach implemented */
#define CFG_IPA_UC_TX_BUF_SIZE_DEFAULT (2048)
/**
* dp_tx_ipa_uc_attach - Allocate autonomy TX resources
* @soc: data path instance
@ -118,15 +139,28 @@ static int dp_tx_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev)
hal_get_srng_params(soc->hal_soc, (void *)wbm_srng, &srng_params);
num_entries = srng_params.num_entries;
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
"requested %d buffers to be posted to wbm ring",
num_entries);
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
"%s: requested %d buffers to be posted to wbm ring",
__func__, num_entries);
soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr = qdf_mem_malloc(num_entries *
sizeof(*soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr));
if (!soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr) {
soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr_unaligned =
qdf_mem_malloc(num_entries *
sizeof(*soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr_unaligned));
if (!soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr_unaligned) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
"%s: IPA WBM Ring mem_info alloc fail", __func__);
"%s: IPA WBM Ring Tx buf pool vaddr alloc fail",
__func__);
return -ENOMEM;
}
soc->ipa_uc_tx_rsc.tx_buf_pool_paddr_unaligned =
qdf_mem_malloc(num_entries *
sizeof(*soc->ipa_uc_tx_rsc.tx_buf_pool_paddr_unaligned));
if (!soc->ipa_uc_tx_rsc.tx_buf_pool_paddr_unaligned) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
"%s: IPA WBM Ring Tx buf pool paddr alloc fail",
__func__);
qdf_mem_free(soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr_unaligned);
return -ENOMEM;
}
@ -148,12 +182,13 @@ static int dp_tx_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev)
ring_entry = hal_srng_dst_get_next_hp(soc->hal_soc,
(void *)wbm_srng);
if (!ring_entry) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
"Failed to get WBM ring entry\n");
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
"%s: Failed to get WBM ring entry\n",
__func__);
qdf_mem_free_consistent(soc->osdev, soc->osdev->dev,
alloc_size, buffer_vaddr_unaligned,
buffer_paddr_unaligned, 0);
goto fail;
break;
}
buffer_vaddr = (void *)qdf_align((unsigned long)
@ -167,24 +202,32 @@ static int dp_tx_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev)
HAL_WBM_PADDR_LO_SET(ring_entry, paddr_lo);
HAL_WBM_PADDR_HI_SET(ring_entry, paddr_hi);
soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr[tx_buffer_count] =
buffer_vaddr;
soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr_unaligned[tx_buffer_count]
= buffer_vaddr_unaligned;
soc->ipa_uc_tx_rsc.tx_buf_pool_paddr_unaligned[tx_buffer_count]
= buffer_paddr_unaligned;
}
hal_srng_access_end(soc->hal_soc, wbm_srng);
soc->ipa_uc_tx_rsc.alloc_tx_buf_cnt = tx_buffer_count;
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
"IPA WDI TX buffer: %d allocated\n",
tx_buffer_count);
if (tx_buffer_count) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
"%s: IPA WDI TX buffer: %d allocated\n",
__func__, tx_buffer_count);
} else {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
"%s: No IPA WDI TX buffer allocated\n",
__func__);
qdf_mem_free(soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr_unaligned);
soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr_unaligned = NULL;
qdf_mem_free(soc->ipa_uc_tx_rsc.tx_buf_pool_paddr_unaligned);
soc->ipa_uc_tx_rsc.tx_buf_pool_paddr_unaligned = NULL;
retval = -ENOMEM;
}
return retval;
fail:
hal_srng_access_end(soc->hal_soc, wbm_srng);
qdf_mem_free(soc->ipa_uc_tx_rsc.tx_buf_pool_vaddr);
return retval;
}
/**
@ -211,7 +254,8 @@ int dp_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev)
error = dp_tx_ipa_uc_attach(soc, pdev);
if (error) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
"DP IPA UC TX attach fail code %d\n", error);
"%s: DP IPA UC TX attach fail code %d\n",
__func__, error);
return error;
}
@ -219,7 +263,8 @@ int dp_ipa_uc_attach(struct dp_soc *soc, struct dp_pdev *pdev)
error = dp_rx_ipa_uc_attach(soc, pdev);
if (error) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
"DP IPA UC RX attach fail code %d\n", error);
"%s: DP IPA UC RX attach fail code %d\n",
__func__, error);
dp_tx_ipa_uc_detach(soc, pdev);
return error;
}
@ -471,7 +516,7 @@ qdf_nbuf_t dp_tx_send_ipa_data_frame(struct cdp_vdev *vdev, qdf_nbuf_t skb)
ret = dp_tx_send((struct dp_vdev_t *)vdev, skb);
if (ret) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"Failed to tx");
"%s: Failed to tx", __func__);
return ret;
}
@ -643,23 +688,25 @@ QDF_STATUS dp_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb,
ret = ipa_wdi3_conn_pipes(&pipe_in, &pipe_out);
if (ret) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"ipa_wdi3_conn_pipes: IPA pipe setup failed: ret=%d",
ret);
"%s: ipa_wdi3_conn_pipes: IPA pipe setup failed: ret=%d",
__func__, ret);
return QDF_STATUS_E_FAILURE;
}
/* IPA uC Doorbell registers */
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"Tx DB PA=0x%x, Rx DB PA=0x%x",
(unsigned int)pipe_out.tx_uc_db_pa,
(unsigned int)pipe_out.rx_uc_db_pa);
"%s: Tx DB PA=0x%x, Rx DB PA=0x%x",
__func__,
(unsigned int)pipe_out.tx_uc_db_pa,
(unsigned int)pipe_out.rx_uc_db_pa);
ipa_res->tx_comp_doorbell_paddr = pipe_out.tx_uc_db_pa;
ipa_res->tx_comp_doorbell_vaddr = pipe_out.tx_uc_db_va;
ipa_res->rx_ready_doorbell_paddr = pipe_out.rx_uc_db_pa;
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"Tx: %s=%pK, %s=%d, %s=%pK, %s=%pK, %s=%d, %s=%pK, %s=%d, %s=%pK",
"%s: Tx: %s=%pK, %s=%d, %s=%pK, %s=%pK, %s=%d, %s=%pK, %s=%d, %s=%pK",
__func__,
"transfer_ring_base_pa",
(void *)pipe_in.tx.transfer_ring_base_pa,
"transfer_ring_size",
@ -678,7 +725,8 @@ QDF_STATUS dp_ipa_setup(struct cdp_pdev *ppdev, void *ipa_i2w_cb,
(void *)ipa_res->tx_comp_doorbell_paddr);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"Rx: %s=%pK, %s=%d, %s=%pK, %s=%pK, %s=%d, %s=%pK, %s=%d, %s=%pK",
"%s: Rx: %s=%pK, %s=%d, %s=%pK, %s=%pK, %s=%d, %s=%pK, %s=%d, %s=%pK",
__func__,
"transfer_ring_base_pa",
(void *)pipe_in.rx.transfer_ring_base_pa,
"transfer_ring_size",
@ -713,8 +761,8 @@ QDF_STATUS dp_ipa_cleanup(uint32_t tx_pipe_handle, uint32_t rx_pipe_handle)
ret = ipa_wdi3_disconn_pipes();
if (ret) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"ipa_wdi3_disconn_pipes: IPA pipe cleanup failed: ret=%d",
ret);
"%s: ipa_wdi3_disconn_pipes: IPA pipe cleanup failed: ret=%d",
__func__, ret);
return QDF_STATUS_E_FAILURE;
}
@ -743,8 +791,8 @@ QDF_STATUS dp_ipa_setup_iface(char *ifname, uint8_t *mac_addr,
int ret = -EINVAL;
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
"Add Partial hdr: %s, %pM",
ifname, mac_addr);
"%s: Add Partial hdr: %s, %pM",
__func__, ifname, mac_addr);
qdf_mem_zero(&hdr_info, sizeof(struct ipa_wdi3_hdr_info));
qdf_ether_addr_copy(uc_tx_hdr.eth.h_source, mac_addr);
@ -773,8 +821,8 @@ QDF_STATUS dp_ipa_setup_iface(char *ifname, uint8_t *mac_addr,
ret = ipa_wdi3_reg_intf(&in);
if (ret) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"ipa_wdi3_reg_intf: register IPA interface falied: ret=%d",
ret);
"%s: ipa_wdi3_reg_intf: register IPA interface falied: ret=%d",
__func__, ret);
return QDF_STATUS_E_FAILURE;
}
@ -795,8 +843,8 @@ QDF_STATUS dp_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled)
ret = ipa_wdi3_dereg_intf(ifname);
if (ret) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"ipa_wdi3_dereg_intf: IPA pipe deregistration failed: ret=%d",
ret);
"%s: ipa_wdi3_dereg_intf: IPA pipe deregistration failed: ret=%d",
__func__, ret);
return QDF_STATUS_E_FAILURE;
}
@ -816,8 +864,8 @@ QDF_STATUS dp_ipa_enable_pipes(struct cdp_pdev *ppdev)
result = ipa_wdi3_enable_pipes();
if (result) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"%s: Enable WDI PIPE fail, code %d",
__func__, result);
"%s: Enable WDI PIPE fail, code %d",
__func__, result);
return QDF_STATUS_E_FAILURE;
}
@ -837,8 +885,8 @@ QDF_STATUS dp_ipa_disable_pipes(struct cdp_pdev *ppdev)
result = ipa_wdi3_disable_pipes();
if (result) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"%s: Disable WDI PIPE fail, code %d",
__func__, result);
"%s: Disable WDI PIPE fail, code %d",
__func__, result);
return QDF_STATUS_E_FAILURE;
}
@ -863,8 +911,8 @@ QDF_STATUS dp_ipa_set_perf_level(int client, uint32_t max_supported_bw_mbps)
result = ipa_wdi3_set_perf_profile(&profile);
if (result) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"%s: ipa_wdi3_set_perf_profile fail, code %d",
__func__, result);
"%s: ipa_wdi3_set_perf_profile fail, code %d",
__func__, result);
return QDF_STATUS_E_FAILURE;
}

View file

@ -339,8 +339,11 @@ static int dp_srng_calculate_msi_group(struct dp_soc *soc,
grp_mask = &soc->wlan_cfg_ctx->int_rxdma2host_ring_mask[0];
break;
case RXDMA_MONITOR_BUF:
case RXDMA_BUF:
grp_mask = &soc->wlan_cfg_ctx->int_host2rxdma_ring_mask[0];
break;
case RXDMA_MONITOR_BUF:
/* TODO: support low_thresh interrupt */
return -QDF_STATUS_E_NOENT;
break;
@ -490,6 +493,7 @@ static int dp_srng_setup(struct dp_soc *soc, struct dp_srng *srng,
num_entries = (num_entries > max_entries) ? max_entries : num_entries;
srng->hal_srng = NULL;
srng->alloc_size = (num_entries * entry_size) + ring_base_align - 1;
srng->num_entries = num_entries;
srng->base_vaddr_unaligned = qdf_mem_alloc_consistent(
soc->osdev, soc->osdev->dev, srng->alloc_size,
&(srng->base_paddr_unaligned));
@ -608,6 +612,7 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
uint8_t rx_wbm_rel_mask = int_ctx->rx_wbm_rel_ring_mask;
uint8_t reo_status_mask = int_ctx->reo_status_ring_mask;
uint32_t remaining_quota = dp_budget;
struct dp_pdev *pdev = NULL;
/* Process Tx completion interrupts first to return back buffers */
while (tx_mask) {
@ -689,11 +694,14 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
/* Process LMAC interrupts */
for (ring = 0 ; ring < MAX_PDEV_CNT; ring++) {
if (soc->pdev_list[ring] == NULL)
pdev = soc->pdev_list[ring];
if (pdev == NULL)
continue;
if (int_ctx->rx_mon_ring_mask & (1 << ring)) {
work_done = dp_mon_process(soc, ring, remaining_quota);
budget -= work_done;
if (budget <= 0)
goto budget_done;
remaining_quota = budget;
}
@ -701,6 +709,22 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
work_done = dp_rxdma_err_process(soc, ring,
remaining_quota);
budget -= work_done;
if (budget <= 0)
goto budget_done;
remaining_quota = budget;
}
if (int_ctx->host2rxdma_ring_mask & (1 << ring)) {
union dp_rx_desc_list_elem_t *desc_list = NULL;
union dp_rx_desc_list_elem_t *tail = NULL;
struct dp_srng *rx_refill_buf_ring =
&pdev->rx_refill_buf_ring;
DP_STATS_INC(pdev, replenish.low_thresh_intrs, 1);
dp_rx_buffers_replenish(soc, ring,
rx_refill_buf_ring,
&soc->rx_desc_buf[ring], 0,
&desc_list, &tail, HAL_RX_BUF_RBM_SW3_BM);
}
}
@ -758,6 +782,7 @@ static QDF_STATUS dp_soc_interrupt_attach_poll(void *txrx_soc)
soc->intr_ctx[i].rx_wbm_rel_ring_mask = 0x1;
soc->intr_ctx[i].reo_status_ring_mask = 0x1;
soc->intr_ctx[i].rxdma2host_ring_mask = 0x1;
soc->intr_ctx[i].host2rxdma_ring_mask = 0x1;
soc->intr_ctx[i].soc = soc;
soc->intr_ctx[i].lro_ctx = qdf_lro_init();
}
@ -825,6 +850,8 @@ static void dp_soc_interrupt_map_calculate_integrated(struct dp_soc *soc,
soc->wlan_cfg_ctx, intr_ctx_num);
int rxdma2host_ring_mask = wlan_cfg_get_rxdma2host_ring_mask(
soc->wlan_cfg_ctx, intr_ctx_num);
int host2rxdma_ring_mask = wlan_cfg_get_host2rxdma_ring_mask(
soc->wlan_cfg_ctx, intr_ctx_num);
for (j = 0; j < HIF_MAX_GRP_IRQ; j++) {
@ -844,6 +871,12 @@ static void dp_soc_interrupt_map_calculate_integrated(struct dp_soc *soc,
wlan_cfg_get_hw_mac_idx(soc->wlan_cfg_ctx, j);
}
if (host2rxdma_ring_mask & (1 << j)) {
irq_id_map[num_irq++] =
host2rxdma_host_buf_ring_mac1 -
wlan_cfg_get_hw_mac_idx(soc->wlan_cfg_ctx, j);
}
if (rx_mon_mask & (1 << j)) {
irq_id_map[num_irq++] =
ppdu_end_interrupts_mac1 -
@ -953,6 +986,9 @@ static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc)
wlan_cfg_get_reo_status_ring_mask(soc->wlan_cfg_ctx, i);
int rxdma2host_ring_mask =
wlan_cfg_get_rxdma2host_ring_mask(soc->wlan_cfg_ctx, i);
int host2rxdma_ring_mask =
wlan_cfg_get_host2rxdma_ring_mask(soc->wlan_cfg_ctx, i);
soc->intr_ctx[i].dp_intr_id = i;
soc->intr_ctx[i].tx_ring_mask = tx_mask;
@ -960,6 +996,7 @@ static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc)
soc->intr_ctx[i].rx_mon_ring_mask = rx_mon_mask;
soc->intr_ctx[i].rx_err_ring_mask = rx_err_ring_mask;
soc->intr_ctx[i].rxdma2host_ring_mask = rxdma2host_ring_mask;
soc->intr_ctx[i].host2rxdma_ring_mask = host2rxdma_ring_mask;
soc->intr_ctx[i].rx_wbm_rel_ring_mask = rx_wbm_rel_ring_mask;
soc->intr_ctx[i].reo_status_ring_mask = reo_status_ring_mask;
@ -1015,6 +1052,7 @@ static void dp_soc_interrupt_detach(void *txrx_soc)
soc->intr_ctx[i].rx_wbm_rel_ring_mask = 0;
soc->intr_ctx[i].reo_status_ring_mask = 0;
soc->intr_ctx[i].rxdma2host_ring_mask = 0;
soc->intr_ctx[i].host2rxdma_ring_mask = 0;
qdf_lro_deinit(soc->intr_ctx[i].lro_ctx);
}
@ -1344,7 +1382,7 @@ static void dp_hw_link_desc_pool_cleanup(struct dp_soc *soc)
#define REO_CMD_RING_SIZE 32
#define REO_STATUS_RING_SIZE 32
#define RXDMA_BUF_RING_SIZE 1024
#define RXDMA_REFILL_RING_SIZE 2048
#define RXDMA_REFILL_RING_SIZE 4096
#define RXDMA_MONITOR_BUF_RING_SIZE 4096
#define RXDMA_MONITOR_DST_RING_SIZE 2048
#define RXDMA_MONITOR_STATUS_RING_SIZE 1024
@ -1489,6 +1527,7 @@ static uint8_t dp_soc_ring_if_nss_offloaded(struct dp_soc *soc, enum hal_ring_ty
switch (ring_type) {
case WBM2SW_RELEASE:
case REO_DST:
case RXDMA_BUF:
status = ((nss_config) & (1 << ring_num));
break;
default:
@ -1530,7 +1569,7 @@ static void dp_soc_reset_intr_mask(struct dp_soc *soc)
group_number = dp_srng_find_ring_in_mask(j, grp_mask);
if (group_number < 0) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
FL("ring not part of an group; ring_type: %d,ring_num %d"),
FL("ring not part of any group; ring_type: %d,ring_num %d"),
WBM2SW_RELEASE, j);
return;
}
@ -1565,7 +1604,7 @@ static void dp_soc_reset_intr_mask(struct dp_soc *soc)
group_number = dp_srng_find_ring_in_mask(j, grp_mask);
if (group_number < 0) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
FL("ring not part of an group; ring_type: %d,ring_num %d"),
FL("ring not part of any group; ring_type: %d,ring_num %d"),
REO_DST, j);
return;
}
@ -1579,6 +1618,40 @@ static void dp_soc_reset_intr_mask(struct dp_soc *soc)
*/
wlan_cfg_set_rx_ring_mask(soc->wlan_cfg_ctx, group_number, mask);
}
/*
* group mask for Rx buffer refill ring
*/
grp_mask = &soc->wlan_cfg_ctx->int_host2rxdma_ring_mask[0];
/* loop and reset the mask for only offloaded ring */
for (j = 0; j < MAX_PDEV_CNT; j++) {
if (!dp_soc_ring_if_nss_offloaded(soc, RXDMA_BUF, j)) {
continue;
}
/*
* Group number corresponding to rx offloaded ring.
*/
group_number = dp_srng_find_ring_in_mask(j, grp_mask);
if (group_number < 0) {
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
FL("ring not part of any group; ring_type: %d,ring_num %d"),
REO_DST, j);
return;
}
/* set the interrupt mask for offloaded ring */
mask = wlan_cfg_get_host2rxdma_ring_mask(soc->wlan_cfg_ctx,
group_number);
mask &= (~(1 << j));
/*
* set the interrupt mask to zero for rx offloaded radio.
*/
wlan_cfg_set_host2rxdma_ring_mask(soc->wlan_cfg_ctx,
group_number, mask);
}
}
#ifdef IPA_OFFLOAD
@ -3217,10 +3290,11 @@ void dp_peer_unref_delete(void *peer_handle)
/*
* dp_peer_detach_wifi3() – Detach txrx peer
* @peer_handle: Datapath peer handle
* @peer_handle: Datapath peer handle
* @bitmap: bitmap indicating special handling of request.
*
*/
static void dp_peer_delete_wifi3(void *peer_handle)
static void dp_peer_delete_wifi3(void *peer_handle, uint32_t bitmap)
{
struct dp_peer *peer = (struct dp_peer *)peer_handle;
@ -3856,6 +3930,8 @@ dp_print_pdev_rx_stats(struct dp_pdev *pdev)
pdev->stats.replenish.pkts.bytes);
DP_PRINT_STATS(" Buffers Added To Freelist = %d",
pdev->stats.buf_freelist);
DP_PRINT_STATS(" Low threshold intr = %d",
pdev->stats.replenish.low_thresh_intrs);
DP_PRINT_STATS("Dropped:");
DP_PRINT_STATS(" msdu_not_done = %d",
pdev->stats.dropped.msdu_not_done);

View file

@ -107,6 +107,29 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"requested %d buffers for replenish", num_req_buffers);
hal_srng_access_start(dp_soc->hal_soc, rxdma_srng);
num_entries_avail = hal_srng_src_num_avail(dp_soc->hal_soc,
rxdma_srng,
sync_hw_ptr);
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"no of availble entries in rxdma ring: %d",
num_entries_avail);
if (!(*desc_list) && (num_entries_avail >
((dp_rxdma_srng->num_entries * 3) / 4))) {
num_req_buffers = num_entries_avail;
} else if (num_entries_avail < num_req_buffers) {
num_desc_to_free = num_req_buffers - num_entries_avail;
num_req_buffers = num_entries_avail;
}
if (qdf_unlikely(!num_req_buffers)) {
num_desc_to_free = num_req_buffers;
hal_srng_access_end(dp_soc->hal_soc, rxdma_srng);
goto free_descs;
}
/*
* if desc_list is NULL, allocate the descs from freelist
*/
@ -122,6 +145,7 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
"no free rx_descs in freelist");
DP_STATS_INC(dp_pdev, err.desc_alloc_fail,
num_req_buffers);
hal_srng_access_end(dp_soc->hal_soc, rxdma_srng);
return QDF_STATUS_E_NOMEM;
}
@ -130,19 +154,6 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
num_req_buffers = num_alloc_desc;
}
hal_srng_access_start(dp_soc->hal_soc, rxdma_srng);
num_entries_avail = hal_srng_src_num_avail(dp_soc->hal_soc,
rxdma_srng,
sync_hw_ptr);
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"no of availble entries in rxdma ring: %d",
num_entries_avail);
if (num_entries_avail < num_req_buffers) {
num_desc_to_free = num_req_buffers - num_entries_avail;
num_req_buffers = num_entries_avail;
}
count = 0;
@ -208,10 +219,11 @@ QDF_STATUS dp_rx_buffers_replenish(struct dp_soc *dp_soc, uint32_t mac_id,
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"%d rx desc added back to free list", num_desc_to_free);
DP_STATS_INC(dp_pdev, buf_freelist, num_desc_to_free);
DP_STATS_INC_PKT(dp_pdev, replenish.pkts, num_req_buffers,
(RX_BUFFER_SIZE * num_req_buffers));
free_descs:
DP_STATS_INC(dp_pdev, buf_freelist, num_desc_to_free);
/*
* add any available free desc back to the free list
*/
@ -957,9 +969,8 @@ dp_rx_process(struct dp_intr *int_ctx, void *hal_ring, uint32_t quota)
* them in per vdev queue.
* Process the received pkts in a different per vdev loop.
*/
while (qdf_likely((ring_desc =
hal_srng_dst_get_next(hal_soc, hal_ring))
&& quota)) {
while (qdf_likely(quota && (ring_desc =
hal_srng_dst_get_next(hal_soc, hal_ring)))) {
error = HAL_RX_ERROR_STATUS_GET(ring_desc);
ring_id = hal_srng_ring_id_get(hal_ring);
@ -1450,7 +1461,7 @@ dp_rx_pdev_attach(struct dp_pdev *pdev)
/* For Rx buffers, WBM release ring is SW RING 3,for all pdev's */
dp_rxdma_srng = &pdev->rx_refill_buf_ring;
dp_rx_buffers_replenish(soc, pdev_id, dp_rxdma_srng, rx_desc_pool,
rxdma_entries, &desc_list, &tail, HAL_RX_BUF_RBM_SW3_BM);
0, &desc_list, &tail, HAL_RX_BUF_RBM_SW3_BM);
return QDF_STATUS_SUCCESS;
}

View file

@ -126,6 +126,7 @@ uint16_t dp_rx_get_free_desc_list(struct dp_soc *soc, uint32_t pool_id,
return count;
}
}
(*tail)->next = NULL;
qdf_spin_unlock_bh(&soc->rx_desc_mutex[pool_id]);
return count;
}
@ -152,7 +153,7 @@ void dp_rx_add_desc_list_to_free_list(struct dp_soc *soc,
temp_list = rx_desc_pool->freelist;
qdf_print(
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
"temp_list: %pK, *local_desc_list: %pK, *tail: %pK (*tail)->next: %pK\n",
temp_list, *local_desc_list, *tail, (*tail)->next);
rx_desc_pool->freelist = *local_desc_list;

View file

@ -774,9 +774,9 @@ dp_rx_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
goto done;
}
while (qdf_likely((ring_desc =
hal_srng_dst_get_next(hal_soc, hal_ring))
&& quota--)) {
while (qdf_likely(quota-- && (ring_desc =
hal_srng_dst_get_next(hal_soc, hal_ring)))) {
DP_STATS_INC(soc, rx.err_ring_pkts, 1);
error = HAL_RX_ERROR_STATUS_GET(ring_desc);
@ -843,6 +843,7 @@ dp_rx_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
/* Return link descriptor through WBM ring (SW2WBM)*/
dp_rx_link_desc_return(soc, ring_desc,
HAL_BM_ACTION_PUT_IN_IDLE_LIST);
}
done:
@ -913,9 +914,8 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
goto done;
}
while (qdf_likely((ring_desc =
hal_srng_dst_get_next(hal_soc, hal_ring))
&& quota--)) {
while (qdf_likely(quota-- && (ring_desc =
hal_srng_dst_get_next(hal_soc, hal_ring)))) {
/* XXX */
wbm_err_src = HAL_RX_WBM_ERR_SRC_GET(ring_desc);
@ -992,7 +992,7 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
default:
QDF_TRACE(QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_ERROR,
QDF_TRACE_LEVEL_DEBUG,
"REO error %d detected",
reo_error_code);
}
@ -1029,13 +1029,13 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota)
case HAL_RXDMA_ERR_DECRYPT:
QDF_TRACE(QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_ERROR,
QDF_TRACE_LEVEL_DEBUG,
"Packet received with Decrypt error");
break;
default:
QDF_TRACE(QDF_MODULE_ID_DP,
QDF_TRACE_LEVEL_ERROR,
QDF_TRACE_LEVEL_DEBUG,
"RXDMA error %d",
rxdma_error_code);
}
@ -1133,11 +1133,7 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
qdf_assert(rx_msdu_link_desc);
num_msdus = (msdu_cnt > HAL_RX_NUM_MSDU_DESC)?
HAL_RX_NUM_MSDU_DESC:msdu_cnt;
hal_rx_msdu_list_get(rx_msdu_link_desc, &msdu_list, &num_msdus);
msdu_cnt -= num_msdus;
if (msdu_list.sw_cookie[0] != HAL_RX_COOKIE_SPECIAL) {
/* if the msdus belongs to NSS offloaded radio &&
@ -1184,7 +1180,7 @@ dp_rx_err_mpdu_pop(struct dp_soc *soc, uint32_t mac_id,
dp_rx_link_desc_return(soc, p_last_buf_addr_info, bm_action);
p_last_buf_addr_info = p_buf_addr_info;
} while (buf_info.paddr && msdu_cnt);
} while (buf_info.paddr);
DP_STATS_INC(soc, rx.err.rxdma_error[rxdma_error_code], 1);
@ -1248,8 +1244,8 @@ dp_rxdma_err_process(struct dp_soc *soc, uint32_t mac_id, uint32_t quota)
return 0;
}
while (qdf_likely((rxdma_dst_ring_desc =
hal_srng_dst_get_next(hal_soc, err_dst_srng)) && quota--)) {
while (qdf_likely(quota-- && (rxdma_dst_ring_desc =
hal_srng_dst_get_next(hal_soc, err_dst_srng)))) {
rx_bufs_used += dp_rx_err_mpdu_pop(soc, mac_id,
rxdma_dst_ring_desc,

View file

@ -358,6 +358,7 @@ struct dp_srng {
qdf_dma_addr_t base_paddr_unaligned;
uint32_t alloc_size;
int irq;
uint32_t num_entries;
};
struct dp_rx_reorder_array_elem {
@ -427,6 +428,7 @@ struct dp_intr {
uint8_t rx_wbm_rel_ring_mask; /* WBM2SW Rx Release Ring */
uint8_t reo_status_ring_mask; /* REO command response ring */
uint8_t rxdma2host_ring_mask; /* RXDMA to host destination ring */
uint8_t host2rxdma_ring_mask; /* Host to RXDMA buffer ring */
struct dp_soc *soc; /* Reference to SoC structure ,
to get DMA ring handles */
qdf_lro_ctx_t lro_ctx;
@ -797,7 +799,8 @@ struct dp_soc {
qdf_dma_addr_t ipa_wbm_tp_paddr;
/* TX buffers populated into the WBM ring */
void **tx_buf_pool_vaddr;
void **tx_buf_pool_vaddr_unaligned;
qdf_dma_addr_t *tx_buf_pool_paddr_unaligned;
} ipa_uc_tx_rsc;
/* IPA uC datapath offload Wlan Rx resources */

View file

@ -1719,7 +1719,7 @@ static int hif_device_inserted(struct sdio_func *func,
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
("%s: CMD52 to set bus width failed: %d\n",
__func__, ret));
return ret;
goto del_hif_dev;;
}
device->host->ios.bus_width =
MMC_BUS_WIDTH_1;
@ -1740,7 +1740,7 @@ static int hif_device_inserted(struct sdio_func *func,
("%s: CMD52 to bus width failed: %d\n",
__func__,
ret));
return ret;
goto del_hif_dev;
}
device->host->ios.bus_width =
MMC_BUS_WIDTH_4;
@ -1761,7 +1761,7 @@ static int hif_device_inserted(struct sdio_func *func,
("%s: CMD52 to bus width failed: %d\n",
__func__,
ret));
return ret;
goto del_hif_dev;
}
device->host->ios.bus_width =
MMC_BUS_WIDTH_8;
@ -1773,7 +1773,8 @@ static int hif_device_inserted(struct sdio_func *func,
("%s: MMC bus width %d is not supported.\n",
__func__,
mmcbuswidth));
return ret = QDF_STATUS_E_FAILURE;
ret = QDF_STATUS_E_FAILURE;
goto del_hif_dev;
}
AR_DEBUG_PRINTF(ATH_DEBUG_ANY,
("%s: Set MMC bus width to %dBit.\n",
@ -1808,9 +1809,23 @@ static int hif_device_inserted(struct sdio_func *func,
sema_init(&device->sem_async, 0);
ret = hif_enable_func(device, func);
return (ret == QDF_STATUS_SUCCESS || ret == QDF_STATUS_E_PENDING)
? 0 : QDF_STATUS_E_FAILURE;
if ((ret == QDF_STATUS_SUCCESS || ret == QDF_STATUS_E_PENDING))
return 0;
ret = QDF_STATUS_E_FAILURE;
del_hif_dev:
del_hif_device(device);
for (i = 0; i < MAX_HIF_DEVICES; ++i) {
if (hif_devices[i] == device) {
hif_devices[i] = NULL;
break;
}
}
if (i == MAX_HIF_DEVICES) {
AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,
("%s: No hif_devices[] slot for %pK",
__func__, device));
}
return ret;
}
/**

View file

@ -188,61 +188,25 @@ static inline void restore_tx_packet(HTC_TARGET *target, HTC_PACKET *pPacket)
}
static void do_send_completion(HTC_ENDPOINT *pEndpoint,
HTC_PACKET_QUEUE *pQueueToIndicate)
{
do {
if (HTC_QUEUE_EMPTY(pQueueToIndicate)) {
/* nothing to indicate */
break;
}
if (pEndpoint->EpCallBacks.EpTxCompleteMultiple != NULL) {
AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
("HTC calling ep %d, send complete multiple callback (%d pkts)\n",
pEndpoint->Id,
HTC_PACKET_QUEUE_DEPTH
(pQueueToIndicate)));
/* a multiple send complete handler is being used, pass
* the queue to the handler
*/
pEndpoint->EpCallBacks.EpTxCompleteMultiple(
pEndpoint->EpCallBacks.pContext,
pQueueToIndicate);
/* all packets are now owned by the callback, reset
* queue to be safe
*/
INIT_HTC_PACKET_QUEUE(pQueueToIndicate);
} else {
HTC_PACKET *pPacket;
/* using legacy EpTxComplete */
do {
pPacket = htc_packet_dequeue(pQueueToIndicate);
AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
("HTC calling ep %d send complete callback on packet %pK\n",
pEndpoint->Id, pPacket));
pEndpoint->EpCallBacks.EpTxComplete(pEndpoint->
EpCallBacks.
pContext,
pPacket);
} while (!HTC_QUEUE_EMPTY(pQueueToIndicate));
}
} while (false);
}
static void send_packet_completion(HTC_TARGET *target, HTC_PACKET *pPacket)
{
HTC_ENDPOINT *pEndpoint = &target->endpoint[pPacket->Endpoint];
HTC_PACKET_QUEUE container;
HTC_EP_SEND_PKT_COMPLETE EpTxComplete;
restore_tx_packet(target, pPacket);
INIT_HTC_PACKET_QUEUE_AND_ADD(&container, pPacket);
/* do completion */
do_send_completion(pEndpoint, &container);
AR_DEBUG_PRINTF(ATH_DEBUG_SEND,
("HTC calling ep %d send complete callback on packet %pK\n",
pEndpoint->Id, pPacket));
EpTxComplete = pEndpoint->EpCallBacks.EpTxComplete;
if (EpTxComplete != NULL)
EpTxComplete(pEndpoint->EpCallBacks.pContext, pPacket);
else
qdf_nbuf_free(pPacket->pPktContext);
}
void htc_send_complete_check_cleanup(void *context)
@ -1535,20 +1499,15 @@ QDF_STATUS htc_send_pkts_multiple(HTC_HANDLE HTCHandle,
#endif
/* do completion on any packets that couldn't get in */
if (!HTC_QUEUE_EMPTY(pPktQueue)) {
while (!HTC_QUEUE_EMPTY(pPktQueue)) {
pPacket = htc_packet_dequeue(pPktQueue);
HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue, pPacket) {
/* remove the headroom reserved for HTC_FRAME_HDR */
restore_tx_packet(target, pPacket);
if (HTC_STOPPING(target))
pPacket->Status = QDF_STATUS_E_CANCELED;
else
pPacket->Status = QDF_STATUS_E_RESOURCES;
if (HTC_STOPPING(target))
pPacket->Status = QDF_STATUS_E_CANCELED;
else
pPacket->Status = QDF_STATUS_E_RESOURCES;
}
HTC_PACKET_QUEUE_ITERATE_END;
do_send_completion(pEndpoint, pPktQueue);
send_packet_completion(target, pPacket);
}
AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-htc_send_pkts_multiple\n"));

106
qdf/inc/qdf_cpuhp.h Normal file
View file

@ -0,0 +1,106 @@
/*
* Copyright (c) 2017 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
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: qdf_cpuhp (CPU hotplug)
* QCA driver framework (QDF) CPU hotplug APIs
*/
#ifndef __QDF_CPUHP_H
#define __QDF_CPUHP_H
#include "qdf_status.h"
#include "qdf_types.h"
/**
* struct qdf_cpuhp_handler - an opaque hotplug event registration handle
*/
struct qdf_cpuhp_handler;
typedef void (*qdf_cpuhp_callback)(void *context, uint32_t cpu);
#ifdef QCA_CONFIG_SMP
/**
* qdf_cpuhp_init() - Initialize the CPU hotplug event infrastructure
*
* To be called once, globally.
*
* Return: None
*/
QDF_STATUS qdf_cpuhp_init(void);
/**
* qdf_cpuhp_deinit() - De-initialize the CPU hotplug event infrastructure
*
* To be called once, globally.
*
* Return: None
*/
QDF_STATUS qdf_cpuhp_deinit(void);
/**
* qdf_cpuhp_register() - Register for CPU up/down event notifications
* @handler: a double pointer to the event registration handle to allocate
* @context: an opaque context to pass back to event listeners
* @up_callback: the function pointer to invoke for CPU up events
* @down_callback: the function pointer to invoke for CPU down events
*
* "Up" happens just after the CPU is up. Inversely, "down" happens just before
* the CPU goes down.
*
* @handler will point to a valid memory address on success, or NULL on failure.
*
* Return: QDF_STATUS
*/
QDF_STATUS qdf_cpuhp_register(struct qdf_cpuhp_handler **handler,
void *context,
qdf_cpuhp_callback up_callback,
qdf_cpuhp_callback down_callback);
/**
* qdf_cpuhp_unregister() - Un-register for CPU up/down event notifications
* @handler: a double pointer to the event registration handle to de-allocate
*
* @handler point to NULL upon completion
*
* Return: None
*/
void qdf_cpuhp_unregister(struct qdf_cpuhp_handler **handler);
#else
QDF_STATUS qdf_cpuhp_init(void)
{
return QDF_STATUS_SUCCESS;
}
QDF_STATUS qdf_cpuhp_deinit(void)
{
return QDF_STATUS_SUCCESS;
}
QDF_STATUS qdf_cpuhp_register(struct qdf_cpuhp_handler **handler,
void *context,
qdf_cpuhp_callback up_callback,
qdf_cpuhp_callback down_callback)
{
return QDF_STATUS_SUCCESS;
}
void qdf_cpuhp_unregister(struct qdf_cpuhp_handler **handler) {}
#endif /* QCA_CONFIG_SMP */
#endif /* __QDF_CPUHP_H */

View file

@ -0,0 +1,34 @@
/*
* Copyright (c) 2017 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
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: i_qdf_cpuhp.h (CPU hotplug)
* Linux-specific definitions for QDF CPU hotplug API's
*/
#ifndef __I_QDF_CPUHP_H
#define __I_QDF_CPUHP_H
#include "linux/types.h"
typedef void (*__qdf_cpuhp_emit)(uint32_t cpu);
void __qdf_cpuhp_os_init(__qdf_cpuhp_emit on_up, __qdf_cpuhp_emit on_down);
void __qdf_cpuhp_os_deinit(void);
#endif /* __I_QDF_CPUHP_H */

119
qdf/linux/src/qdf_cpuhp.c Normal file
View file

@ -0,0 +1,119 @@
/*
* Copyright (c) 2017 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
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: qdf_cpuhp
* This file provides OS dependent QDF CPU hotplug APIs
*/
#include "i_qdf_cpuhp.h"
#include "qdf_trace.h"
#include "linux/cpu.h"
#include "linux/notifier.h"
#include "linux/version.h"
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0)
#include "linux/cpuhotplug.h"
#endif
static __qdf_cpuhp_emit __qdf_cpuhp_on_up;
static __qdf_cpuhp_emit __qdf_cpuhp_on_down;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
static int qdf_cpuhp_legacy_handler(struct notifier_block *block,
unsigned long state,
void *hcpu)
{
unsigned long cpu = (unsigned long)hcpu;
switch (state) {
case CPU_ONLINE:
__qdf_cpuhp_on_up(cpu);
break;
case CPU_DOWN_PREPARE:
case CPU_DOWN_PREPARE_FROZEN:
__qdf_cpuhp_on_down(cpu);
break;
default:
break;
}
return NOTIFY_OK;
}
static struct notifier_block qdf_cpuhp_notifier_block = {
.notifier_call = qdf_cpuhp_legacy_handler,
};
static inline void qdf_cpuhp_register_callbacks(void)
{
register_hotcpu_notifier(&qdf_cpuhp_notifier_block);
}
static inline void qdf_cpuhp_unregister_callbacks(void)
{
unregister_hotcpu_notifier(&qdf_cpuhp_notifier_block);
}
#else
static enum cpuhp_state registered_hotplug_state;
static int qdf_cpuhp_up_handler(unsigned int cpu)
{
__qdf_cpuhp_on_up(cpu);
return 0;
}
static int qdf_cpuhp_down_handler(unsigned int cpu)
{
__qdf_cpuhp_on_down(cpu);
return 0;
}
static inline void qdf_cpuhp_register_callbacks(void)
{
registered_hotplug_state = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
"wlan/qca-qdf:online",
qdf_cpuhp_up_handler,
qdf_cpuhp_down_handler);
}
static inline void qdf_cpuhp_unregister_callbacks(void)
{
QDF_BUG(registered_hotplug_state);
if (registered_hotplug_state)
cpuhp_remove_state(registered_hotplug_state);
}
#endif /* KERNEL_VERSION(4, 6, 0) */
void __qdf_cpuhp_os_init(__qdf_cpuhp_emit on_up, __qdf_cpuhp_emit on_down)
{
__qdf_cpuhp_on_up = on_up;
__qdf_cpuhp_on_down = on_down;
qdf_cpuhp_register_callbacks();
}
void __qdf_cpuhp_os_deinit(void)
{
qdf_cpuhp_unregister_callbacks();
}

157
qdf/src/qdf_cpuhp.c Normal file
View file

@ -0,0 +1,157 @@
/*
* Copyright (c) 2017 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
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: qdf_cpuhp (CPU hotplug)
* QCA driver framework (QDF) CPU hotplug APIs
*/
#include "qdf_cpuhp.h"
#include "i_qdf_cpuhp.h"
#include "qdf_list.h"
#include "qdf_lock.h"
static qdf_mutex_t qdf_cpuhp_lock;
static qdf_list_t qdf_cpuhp_handlers;
struct qdf_cpuhp_handler {
qdf_list_node_t node;
void *context;
qdf_cpuhp_callback up_callback;
qdf_cpuhp_callback down_callback;
};
static void qdf_cpuhp_on_up(uint32_t cpu)
{
QDF_STATUS status;
qdf_list_node_t *node;
qdf_mutex_acquire(&qdf_cpuhp_lock);
status = qdf_list_peek_front(&qdf_cpuhp_handlers, &node);
while (QDF_IS_STATUS_SUCCESS(status)) {
struct qdf_cpuhp_handler *handler =
qdf_container_of(node, struct qdf_cpuhp_handler, node);
if (handler->up_callback)
handler->up_callback(handler->context, cpu);
status = qdf_list_peek_next(&qdf_cpuhp_handlers, node, &node);
}
qdf_mutex_release(&qdf_cpuhp_lock);
}
static void qdf_cpuhp_on_down(uint32_t cpu)
{
QDF_STATUS status;
qdf_list_node_t *node;
qdf_mutex_acquire(&qdf_cpuhp_lock);
status = qdf_list_peek_front(&qdf_cpuhp_handlers, &node);
while (QDF_IS_STATUS_SUCCESS(status)) {
struct qdf_cpuhp_handler *handler =
qdf_container_of(node, struct qdf_cpuhp_handler, node);
if (handler->down_callback)
handler->down_callback(handler->context, cpu);
status = qdf_list_peek_next(&qdf_cpuhp_handlers, node, &node);
}
qdf_mutex_release(&qdf_cpuhp_lock);
}
QDF_STATUS qdf_cpuhp_init(void)
{
QDF_STATUS status;
status = qdf_mutex_create(&qdf_cpuhp_lock);
if (QDF_IS_STATUS_ERROR(status))
return status;
qdf_list_create(&qdf_cpuhp_handlers, 0);
__qdf_cpuhp_os_init(qdf_cpuhp_on_up, qdf_cpuhp_on_down);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS qdf_cpuhp_deinit(void)
{
__qdf_cpuhp_os_deinit();
qdf_list_destroy(&qdf_cpuhp_handlers);
return qdf_mutex_destroy(&qdf_cpuhp_lock);
}
QDF_STATUS qdf_cpuhp_register(struct qdf_cpuhp_handler **out_handler,
void *context,
qdf_cpuhp_callback up_callback,
qdf_cpuhp_callback down_callback)
{
QDF_STATUS status;
struct qdf_cpuhp_handler *handler;
*out_handler = NULL;
handler = qdf_mem_malloc(sizeof(*handler));
if (!handler)
return QDF_STATUS_E_NOMEM;
handler->context = context;
handler->up_callback = up_callback;
handler->down_callback = down_callback;
status = qdf_mutex_acquire(&qdf_cpuhp_lock);
if (QDF_IS_STATUS_ERROR(status))
goto free_handler;
status = qdf_list_insert_back(&qdf_cpuhp_handlers, &handler->node);
if (QDF_IS_STATUS_ERROR(status))
goto release_lock;
/* this can fail, but there isn't a good way to recover... */
qdf_mutex_release(&qdf_cpuhp_lock);
*out_handler = handler;
return QDF_STATUS_SUCCESS;
release_lock:
qdf_mutex_release(&qdf_cpuhp_lock);
free_handler:
qdf_mem_free(handler);
return status;
}
void qdf_cpuhp_unregister(struct qdf_cpuhp_handler **out_handler)
{
struct qdf_cpuhp_handler *handler = *out_handler;
QDF_BUG(handler);
if (!handler)
return;
qdf_mutex_acquire(&qdf_cpuhp_lock);
qdf_list_remove_node(&qdf_cpuhp_handlers, &handler->node);
qdf_mutex_release(&qdf_cpuhp_lock);
*out_handler = NULL;
}

View file

@ -230,6 +230,7 @@ enum wifi_traffic_ac {
* @WLAN_PEER_NAWDS: NAWDS Peer
* @WLAN_PEER_STA_TEMP: STA Peer Temp (its host only node)
* @WLAN_PEER_IBSS: IBSS Peer
* @WLAN_PEER_NDP: NDP Peer
*/
enum wlan_peer_type {
WLAN_PEER_SELF = 1,
@ -241,6 +242,7 @@ enum wlan_peer_type {
WLAN_PEER_NAWDS = 7,
WLAN_PEER_STA_TEMP = 8,
WLAN_PEER_IBSS = 9,
WLAN_PEER_NDP = 10,
};
/**

View file

@ -360,7 +360,7 @@ QDF_STATUS tgt_dfs_process_emulate_bang_radar_cmd(struct wlan_objmgr_pdev *pdev,
dfs_unit_test);
else
dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
"dfs_tx_ops=%p", dfs_tx_ops);
"dfs_tx_ops=%pK", dfs_tx_ops);
return QDF_STATUS_E_FAILURE;
}

View file

@ -77,7 +77,7 @@
/* Interrupt Mitigation - Timer threshold in us */
#define WLAN_CFG_INT_TIMER_THRESHOLD_TX 1000
#define WLAN_CFG_INT_TIMER_THRESHOLD_RX 500
#define WLAN_CFG_INT_TIMER_THRESHOLD_OTHER 8
#define WLAN_CFG_INT_TIMER_THRESHOLD_OTHER 1000
#define WLAN_CFG_TX_RING_SIZE 512
@ -159,6 +159,11 @@
#define WLAN_CFG_RXDMA2HOST_RING_MASK_2 0x4
#define WLAN_CFG_RXDMA2HOST_RING_MASK_3 0x0
#define WLAN_CFG_HOST2RXDMA_RING_MASK_0 0x1
#define WLAN_CFG_HOST2RXDMA_RING_MASK_1 0x2
#define WLAN_CFG_HOST2RXDMA_RING_MASK_2 0x4
#define WLAN_CFG_HOST2RXDMA_RING_MASK_3 0x0
#define WLAN_CFG_DP_TX_NUM_POOLS 3
/* Change this to a lower value to enforce scattered idle list mode */
#define WLAN_CFG_MAX_ALLOC_SIZE (2 << 20)
@ -254,6 +259,12 @@ static const int rxdma2host_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = {
WLAN_CFG_RXDMA2HOST_RING_MASK_2,
WLAN_CFG_RXDMA2HOST_RING_MASK_3};
static const int host2rxdma_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS] = {
WLAN_CFG_HOST2RXDMA_RING_MASK_0,
WLAN_CFG_HOST2RXDMA_RING_MASK_1,
WLAN_CFG_HOST2RXDMA_RING_MASK_2,
WLAN_CFG_HOST2RXDMA_RING_MASK_3};
/**
* struct wlan_cfg_dp_pdev_ctxt - Configuration parameters for pdev (radio)
* @rx_dma_buf_ring_size - Size of RxDMA buffer ring
@ -322,6 +333,8 @@ struct wlan_cfg_dp_soc_ctxt *wlan_cfg_soc_attach()
reo_status_ring_mask[i];
wlan_cfg_ctx->int_rxdma2host_ring_mask[i] =
rxdma2host_ring_mask[i];
wlan_cfg_ctx->int_host2rxdma_ring_mask[i] =
host2rxdma_ring_mask[i];
}
/* This is default mapping and can be overridden by HW config
@ -404,6 +417,18 @@ int wlan_cfg_get_rxdma2host_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg,
return cfg->int_rxdma2host_ring_mask[context];
}
void wlan_cfg_set_host2rxdma_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg,
int context, int mask)
{
cfg->int_host2rxdma_ring_mask[context] = mask;
}
int wlan_cfg_get_host2rxdma_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg,
int context)
{
return cfg->int_host2rxdma_ring_mask[context];
}
void wlan_cfg_set_hw_macid(struct wlan_cfg_dp_soc_ctxt *cfg, int pdev_idx,
int hw_macid)
{

View file

@ -128,6 +128,7 @@ struct wlan_cfg_dp_soc_ctxt {
int int_rx_wbm_rel_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS];
int int_reo_status_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS];
int int_rxdma2host_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS];
int int_host2rxdma_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS];
int hw_macid[MAX_PDEV_CNT];
int base_hw_macid;
bool lro_enabled;
@ -268,6 +269,27 @@ void wlan_cfg_set_rxdma2host_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg,
int wlan_cfg_get_rxdma2host_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg,
int context);
/**
* wlan_cfg_set_host2rxdma_ring_mask() - Set host2rxdma ring interrupt mask
* for the given interrupt context
* @wlan_cfg_ctx - Configuration Handle
* @context - Numerical ID identifying the Interrupt/NAPI context
*
*/
void wlan_cfg_set_host2rxdma_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg,
int context, int mask);
/**
* wlan_cfg_get_host2rxdma_ring_mask() - Return host2rxdma ring interrupt mask
* mapped to an interrupt context
* @wlan_cfg_ctx - Configuration Handle
* @context - Numerical ID identifying the Interrupt/NAPI context
*
* Return: int_host2rxdma_ring_mask[context]
*/
int wlan_cfg_get_host2rxdma_ring_mask(struct wlan_cfg_dp_soc_ctxt *cfg,
int context);
/**
* wlan_cfg_set_hw_macid() - Set HW MAC Id for the given PDEV index
*

View file

@ -841,15 +841,6 @@ QDF_STATUS wmi_unified_dcc_update_ndl(void *wmi_hdl,
QDF_STATUS wmi_unified_save_fw_version_cmd(void *wmi_hdl,
void *evt_buf);
#ifdef CONFIG_MCL
QDF_STATUS wmi_unified_send_init_cmd(void *wmi_hdl,
wmi_resource_config *res_cfg,
uint8_t num_mem_chunks, struct wmi_host_mem_chunk *mem_chunk,
bool action);
#endif
QDF_STATUS wmi_unified_send_saved_init_cmd(void *wmi_hdl);
QDF_STATUS wmi_unified_set_base_macaddr_indicate_cmd(void *wmi_hdl,
uint8_t *custom_addr);

View file

@ -5664,6 +5664,7 @@ typedef enum {
wmi_vdev_param_set_hemu_mode,
wmi_vdev_param_set_he_ltf,
wmi_vdev_param_set_heop,
wmi_vdev_param_disable_cabq,
wmi_vdev_param_max,
} wmi_conv_vdev_param_id;
@ -5900,6 +5901,8 @@ struct wmi_host_fw_abi_ver {
* @rx_batchmode: RX batch mode
* @tt_support: Thermal throttling support
* @atf_config: ATF config
* @mgmt_comp_evt_bundle_support: bundle support required for mgmt complete evt
* @tx_msdu_new_partition_id_support: new partiition id support for tx msdu
* @iphdr_pad_config: ipheader pad config
* @qwrap_config: Qwrap configuration
* @alloc_frag_desc_for_data_pkt: Frag desc for data
@ -5921,6 +5924,7 @@ struct wmi_host_fw_abi_ver {
* @bpf_instruction_size:
* @max_bssid_rx_filters:
* @use_pdev_id:
* @max_num_dbs_scan_duty_cycle: max dbs can duty cycle value
*/
typedef struct {
uint32_t num_vdevs;
@ -5962,7 +5966,9 @@ typedef struct {
uint32_t VO_Minfree;
uint32_t rx_batchmode;
uint32_t tt_support;
uint32_t atf_config;
uint32_t atf_config:1,
mgmt_comp_evt_bundle_support:1,
tx_msdu_new_partition_id_support:1;
uint32_t iphdr_pad_config;
uint32_t
qwrap_config:16,
@ -5986,6 +5992,7 @@ typedef struct {
uint32_t bpf_instruction_size;
uint32_t max_bssid_rx_filters;
uint32_t use_pdev_id;
uint32_t max_num_dbs_scan_duty_cycle;
} target_resource_config;
/**

View file

@ -680,19 +680,10 @@ QDF_STATUS (*send_process_fw_mem_dump_cmd)(wmi_unified_t wmi_handle,
QDF_STATUS (*send_process_set_ie_info_cmd)(wmi_unified_t wmi_handle,
struct vdev_ie_info_param *ie_info);
#ifdef CONFIG_MCL
QDF_STATUS (*send_init_cmd)(wmi_unified_t wmi_handle,
wmi_resource_config *res_cfg,
uint8_t num_mem_chunks, struct wmi_host_mem_chunk *mem_chunk,
bool action);
#endif
QDF_STATUS (*save_fw_version_cmd)(wmi_unified_t wmi_handle, void *evt_buf);
QDF_STATUS (*check_and_update_fw_version_cmd)(wmi_unified_t wmi_hdl, void *ev);
QDF_STATUS (*send_saved_init_cmd)(wmi_unified_t wmi_handle);
QDF_STATUS (*send_set_base_macaddr_indicate_cmd)(wmi_unified_t wmi_handle,
uint8_t *custom_addr);
@ -1444,7 +1435,6 @@ struct wmi_unified {
int wmi_stop_in_progress;
struct wmi_host_abi_version fw_abi_version;
struct wmi_host_abi_version final_abi_vers;
struct wmi_cmd_init saved_wmi_init_cmd;
uint32_t num_of_diag_events_logs;
uint32_t *events_logs_list;
#ifdef WLAN_OPEN_SOURCE

View file

@ -2755,51 +2755,6 @@ QDF_STATUS wmi_unified_process_set_ie_info_cmd(void *wmi_hdl,
return QDF_STATUS_E_FAILURE;
}
#ifdef CONFIG_MCL
/**
* wmi_unified_send_init_cmd() - wmi init command
* @wmi_handle: pointer to wmi handle
* @res_cfg: resource config
* @num_mem_chunks: no of mem chunck
* @mem_chunk: pointer to mem chunck structure
*
* This function sends IE information to firmware
*
* Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
*
*/
QDF_STATUS wmi_unified_send_init_cmd(void *wmi_hdl,
wmi_resource_config *res_cfg,
uint8_t num_mem_chunks, struct wmi_host_mem_chunk *mem_chunk,
bool action)
{
wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
if (wmi_handle->ops->send_init_cmd)
return wmi_handle->ops->send_init_cmd(wmi_handle,
res_cfg, num_mem_chunks, mem_chunk, action);
return QDF_STATUS_E_FAILURE;
}
#endif
/**
* wmi_unified_send_saved_init_cmd() - wmi init command
* @wmi_handle: pointer to wmi handle
*
* This function sends IE information to firmware
*
* Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
*
*/
QDF_STATUS wmi_unified_send_saved_init_cmd(void *wmi_hdl)
{
wmi_unified_t wmi_handle = (wmi_unified_t) wmi_hdl;
if (wmi_handle->ops->send_saved_init_cmd)
return wmi_handle->ops->send_saved_init_cmd(wmi_handle);
return QDF_STATUS_E_FAILURE;
}
/**
* wmi_unified_save_fw_version_cmd() - save fw version

View file

@ -8987,6 +8987,8 @@ static void populate_vdev_param_non_tlv(uint32_t *vdev_param)
WMI_VDEV_PARAM_DISABLE_DYN_BW_RTS;
vdev_param[wmi_vdev_param_ampdu_subframe_size_per_ac] =
WMI_VDEV_PARAM_AMPDU_SUBFRAME_SIZE_PER_AC;
vdev_param[wmi_vdev_param_disable_cabq] =
WMI_VDEV_PARAM_DISABLE_CABQ;
}
#endif

View file

@ -4940,6 +4940,9 @@ static QDF_STATUS send_setup_install_key_cmd_tlv(wmi_unified_t wmi_handle,
key_data = (A_UINT8 *) (buf_ptr + WMI_TLV_HDR_SIZE);
qdf_mem_copy((void *)key_data,
(const void *)key_params->key_data, key_params->key_len);
if (key_params->key_rsc_counter)
qdf_mem_copy(&cmd->key_rsc_counter, key_params->key_rsc_counter,
sizeof(wmi_key_seq_counter));
cmd->key_len = key_params->key_len;
status = wmi_unified_cmd_send(wmi_handle, buf, len,
@ -12456,9 +12459,17 @@ void wmi_copy_resource_config(wmi_resource_config *resource_cfg,
resource_cfg->bpf_instruction_size = tgt_res_cfg->bpf_instruction_size;
resource_cfg->max_bssid_rx_filters = tgt_res_cfg->max_bssid_rx_filters;
resource_cfg->use_pdev_id = tgt_res_cfg->use_pdev_id;
resource_cfg->max_num_dbs_scan_duty_cycle =
tgt_res_cfg->max_num_dbs_scan_duty_cycle;
WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1,
tgt_res_cfg->atf_config);
if (tgt_res_cfg->atf_config)
WMI_RSRC_CFG_FLAG_ATF_CONFIG_ENABLE_SET(resource_cfg->flag1, 1);
if (tgt_res_cfg->mgmt_comp_evt_bundle_support)
WMI_RSRC_CFG_FLAG_MGMT_COMP_EVT_BUNDLE_SUPPORT_SET(
resource_cfg->flag1, 1);
if (tgt_res_cfg->tx_msdu_new_partition_id_support)
WMI_RSRC_CFG_FLAG_TX_MSDU_ID_NEW_PARTITION_SUPPORT_SET(
resource_cfg->flag1, 1);
}
/* copy_hw_mode_id_in_init_cmd() - Helper routine to copy hw_mode in init cmd
@ -12557,131 +12568,6 @@ static inline void copy_fw_abi_version_tlv(wmi_unified_t wmi_handle,
sizeof(wmi_abi_version));
}
#ifdef CONFIG_MCL
/**
* send_init_cmd_tlv() - wmi init command
* @wmi_handle: pointer to wmi handle
* @res_cfg: resource config
* @num_mem_chunks: no of mem chunck
* @mem_chunk: pointer to mem chunck structure
*
* This function sends IE information to firmware
*
* Return: QDF_STATUS_SUCCESS for success otherwise failure
*
*/
static QDF_STATUS send_init_cmd_tlv(wmi_unified_t wmi_handle,
wmi_resource_config *tgt_res_cfg,
uint8_t num_mem_chunks, struct wmi_host_mem_chunk *mem_chunks,
bool action)
{
wmi_buf_t buf;
wmi_init_cmd_fixed_param *cmd;
uint8_t *buf_ptr;
wmi_resource_config *resource_cfg;
wlan_host_memory_chunk *host_mem_chunks;
uint32_t mem_chunk_len = 0;
uint16_t idx;
int len;
int ret;
len = sizeof(*cmd) + sizeof(wmi_resource_config) + WMI_TLV_HDR_SIZE;
mem_chunk_len = (sizeof(wlan_host_memory_chunk) * MAX_MEM_CHUNKS);
buf = wmi_buf_alloc(wmi_handle, len + mem_chunk_len);
if (!buf) {
WMI_LOGD("%s: wmi_buf_alloc failed\n", __func__);
return QDF_STATUS_E_FAILURE;
}
buf_ptr = (uint8_t *) wmi_buf_data(buf);
cmd = (wmi_init_cmd_fixed_param *) buf_ptr;
resource_cfg = (wmi_resource_config *) (buf_ptr + sizeof(*cmd));
host_mem_chunks = (wlan_host_memory_chunk *)
(buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)
+ WMI_TLV_HDR_SIZE);
WMITLV_SET_HDR(&cmd->tlv_header,
WMITLV_TAG_STRUC_wmi_init_cmd_fixed_param,
WMITLV_GET_STRUCT_TLVLEN(wmi_init_cmd_fixed_param));
qdf_mem_copy(resource_cfg, tgt_res_cfg, sizeof(wmi_resource_config));
WMITLV_SET_HDR(&resource_cfg->tlv_header,
WMITLV_TAG_STRUC_wmi_resource_config,
WMITLV_GET_STRUCT_TLVLEN(wmi_resource_config));
for (idx = 0; idx < num_mem_chunks; ++idx) {
WMITLV_SET_HDR(&(host_mem_chunks[idx].tlv_header),
WMITLV_TAG_STRUC_wlan_host_memory_chunk,
WMITLV_GET_STRUCT_TLVLEN
(wlan_host_memory_chunk));
host_mem_chunks[idx].ptr = mem_chunks[idx].paddr;
host_mem_chunks[idx].size = mem_chunks[idx].len;
host_mem_chunks[idx].req_id = mem_chunks[idx].req_id;
WMI_LOGD("chunk %d len %d requested ,ptr 0x%x ",
idx, host_mem_chunks[idx].size,
host_mem_chunks[idx].ptr);
}
cmd->num_host_mem_chunks = num_mem_chunks;
len += (num_mem_chunks * sizeof(wlan_host_memory_chunk));
WMITLV_SET_HDR((buf_ptr + sizeof(*cmd) + sizeof(wmi_resource_config)),
WMITLV_TAG_ARRAY_STRUC,
(sizeof(wlan_host_memory_chunk) *
num_mem_chunks));
/* Fill fw_abi_vers */
copy_fw_abi_version_tlv(wmi_handle, cmd);
if (action) {
ret = wmi_unified_cmd_send(wmi_handle, buf, len,
WMI_INIT_CMDID);
if (ret) {
WMI_LOGE(FL("Failed to send set WMI INIT command ret = %d"), ret);
wmi_buf_free(buf);
return QDF_STATUS_E_FAILURE;
}
} else {
wmi_handle->saved_wmi_init_cmd.buf = buf;
wmi_handle->saved_wmi_init_cmd.buf_len = len;
}
return QDF_STATUS_SUCCESS;
}
#endif
/**
* send_saved_init_cmd_tlv() - wmi init command
* @wmi_handle: pointer to wmi handle
*
* This function sends IE information to firmware
*
* Return: QDF_STATUS_SUCCESS for success otherwise failure
*
*/
static QDF_STATUS send_saved_init_cmd_tlv(wmi_unified_t wmi_handle)
{
int status;
if (!wmi_handle->saved_wmi_init_cmd.buf ||
!wmi_handle->saved_wmi_init_cmd.buf_len) {
WMI_LOGP("Service ready ext event w/o WMI_SERVICE_EXT_MSG!");
return QDF_STATUS_E_FAILURE;
}
status = wmi_unified_cmd_send(wmi_handle,
wmi_handle->saved_wmi_init_cmd.buf,
wmi_handle->saved_wmi_init_cmd.buf_len,
WMI_INIT_CMDID);
if (status) {
WMI_LOGE(FL("Failed to send set WMI INIT command ret = %d"), status);
wmi_buf_free(wmi_handle->saved_wmi_init_cmd.buf);
return QDF_STATUS_E_FAILURE;
}
wmi_handle->saved_wmi_init_cmd.buf = NULL;
wmi_handle->saved_wmi_init_cmd.buf_len = 0;
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS save_fw_version_cmd_tlv(wmi_unified_t wmi_handle, void *evt_buf)
{
WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf;
@ -16301,6 +16187,10 @@ QDF_STATUS save_ext_service_bitmap_tlv(wmi_unified_t wmi_handle, void *evt_buf,
ev->wmi_service_segment_bitmap,
(WMI_SERVICE_SEGMENT_BM_SIZE32 * sizeof(uint32_t)));
WMI_LOGD("wmi_ext_service_bitmap 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x\n",
soc->wmi_ext_service_bitmap[0], soc->wmi_ext_service_bitmap[1],
soc->wmi_ext_service_bitmap[2], soc->wmi_ext_service_bitmap[3]);
if (bitmap_buf)
qdf_mem_copy(bitmap_buf,
soc->wmi_ext_service_bitmap,
@ -19802,13 +19692,9 @@ struct wmi_ops tlv_ops = {
.send_update_tdls_peer_state_cmd = send_update_tdls_peer_state_cmd_tlv,
.send_process_fw_mem_dump_cmd = send_process_fw_mem_dump_cmd_tlv,
.send_process_set_ie_info_cmd = send_process_set_ie_info_cmd_tlv,
#ifdef CONFIG_MCL
.send_init_cmd = send_init_cmd_tlv,
#endif
.save_fw_version_cmd = save_fw_version_cmd_tlv,
.check_and_update_fw_version =
check_and_update_fw_version_cmd_tlv,
.send_saved_init_cmd = send_saved_init_cmd_tlv,
.send_set_base_macaddr_indicate_cmd =
send_set_base_macaddr_indicate_cmd_tlv,
.send_log_supported_evt_cmd = send_log_supported_evt_cmd_tlv,
@ -20356,7 +20242,7 @@ static void populate_tlv_service(uint32_t *wmi_service)
wmi_service[wmi_service_smart_antenna_hw_support] =
WMI_SERVICE_UNAVAILABLE;
wmi_service[wmi_service_enhanced_proxy_sta] = WMI_SERVICE_UNAVAILABLE;
wmi_service[wmi_service_tt] = WMI_SERVICE_UNAVAILABLE;
wmi_service[wmi_service_tt] = WMI_SERVICE_THERM_THROT;
wmi_service[wmi_service_atf] = WMI_SERVICE_ATF;
wmi_service[wmi_service_peer_caching] = WMI_SERVICE_UNAVAILABLE;
wmi_service[wmi_service_coex_gpio] = WMI_SERVICE_UNAVAILABLE;