qcacmn: DP changes to create li/be TX files
Move DP TX target specific functionality to dp/wifi3.0/be and dp/wifi3.0/li folders. DP Functionality common to both lithium and beryllium targets stays in dp/wifi3.0. Change-Id: I3497284153e2ea30a9cb1faf05bd41422329b804 CRs-Fixed: 2891038
This commit is contained in:

committed by
Rakesh Pillai

parent
ca2db4bfa8
commit
e135b3e106
@@ -103,6 +103,35 @@ void *dp_soc_init_wifi3(struct cdp_soc_t *soc,
|
||||
}
|
||||
#endif /* QCA_WIFI_QCA8074 */
|
||||
|
||||
static inline int cdp_get_arch_type_from_devid(uint16_t devid)
|
||||
{
|
||||
switch (devid) {
|
||||
case LITHIUM_DP: /*FIXME Add lithium devide IDs */
|
||||
case QCA8074_DEVICE_ID: /* Hawekeye */
|
||||
case QCA8074V2_DEVICE_ID: /* Hawekeye V2*/
|
||||
case QCA5018_DEVICE_ID:
|
||||
case QCA6290_DEVICE_ID:
|
||||
case QCN9000_DEVICE_ID:
|
||||
case QCN6122_DEVICE_ID:
|
||||
case QCA6390_DEVICE_ID:
|
||||
case QCA6490_DEVICE_ID:
|
||||
case QCA6750_DEVICE_ID:
|
||||
case QCA6390_EMULATION_DEVICE_ID:
|
||||
case RUMIM2M_DEVICE_ID_NODE0: /*lithium emulation */
|
||||
case RUMIM2M_DEVICE_ID_NODE1: /*lithium emulation */
|
||||
case RUMIM2M_DEVICE_ID_NODE2: /*lithium emulation */
|
||||
case RUMIM2M_DEVICE_ID_NODE3: /*lithium emulation */
|
||||
case RUMIM2M_DEVICE_ID_NODE4: /*lithium emulation */
|
||||
case RUMIM2M_DEVICE_ID_NODE5: /*lithium emulation */
|
||||
return LITHIUM_DP;
|
||||
case BERYLLIUM_DP:
|
||||
case WCN7850_DEVICE_ID:
|
||||
return BERYLLIUM_DP;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline
|
||||
ol_txrx_soc_handle cdp_soc_attach(u_int16_t devid,
|
||||
struct hif_opaque_softc *hif_handle,
|
||||
|
113
dp/wifi3.0/be/dp_be.c
Normal file
113
dp/wifi3.0/be/dp_be.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
#include "dp_be.h"
|
||||
#include "dp_be_tx.h"
|
||||
#include "dp_be_rx.h"
|
||||
|
||||
qdf_size_t dp_get_context_size_be(enum dp_context_type context_type)
|
||||
{
|
||||
switch (context_type) {
|
||||
case DP_CONTEXT_TYPE_SOC:
|
||||
return sizeof(struct dp_soc_be);
|
||||
case DP_CONTEXT_TYPE_PDEV:
|
||||
return sizeof(struct dp_pdev_be);
|
||||
case DP_CONTEXT_TYPE_VDEV:
|
||||
return sizeof(struct dp_vdev_be);
|
||||
case DP_CONTEXT_TYPE_PEER:
|
||||
return sizeof(struct dp_peer_be);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static QDF_STATUS dp_soc_attach_be(struct dp_soc *soc)
|
||||
{
|
||||
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
|
||||
QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
|
||||
|
||||
soc->wbm_sw0_bm_id = hal_tx_get_wbm_sw0_bm_id();
|
||||
qdf_status = dp_tx_init_bank_profiles(be_soc);
|
||||
|
||||
return qdf_status;
|
||||
}
|
||||
|
||||
static QDF_STATUS dp_soc_detach_be(struct dp_soc *soc)
|
||||
{
|
||||
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
|
||||
|
||||
dp_tx_deinit_bank_profiles(be_soc);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS dp_pdev_attach_be(struct dp_pdev *pdev)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS dp_pdev_detach_be(struct dp_pdev *pdev)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS dp_vdev_attach_be(struct dp_soc *soc, struct dp_vdev *vdev)
|
||||
{
|
||||
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
|
||||
struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
|
||||
|
||||
be_vdev->bank_id = dp_tx_get_bank_profile(be_soc, be_vdev);
|
||||
|
||||
/* Needs to be enabled after bring-up*/
|
||||
be_vdev->vdev_id_check_en = false;
|
||||
|
||||
if (be_vdev->bank_id == DP_BE_INVALID_BANK_ID) {
|
||||
QDF_BUG(0);
|
||||
return QDF_STATUS_E_FAULT;
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS dp_vdev_detach_be(struct dp_soc *soc, struct dp_vdev *vdev)
|
||||
{
|
||||
struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
|
||||
struct dp_vdev_be *be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
|
||||
|
||||
dp_tx_put_bank_profile(be_soc, be_vdev);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
qdf_size_t dp_get_soc_context_size_be(void)
|
||||
{
|
||||
return sizeof(struct dp_soc_be);
|
||||
}
|
||||
|
||||
void dp_initialize_arch_ops_be(struct dp_arch_ops *arch_ops)
|
||||
{
|
||||
arch_ops->tx_hw_enqueue = dp_tx_hw_enqueue_be;
|
||||
arch_ops->txrx_get_context_size = dp_get_context_size_be;
|
||||
arch_ops->dp_rx_process = dp_rx_process_be;
|
||||
|
||||
arch_ops->txrx_soc_attach = dp_soc_attach_be;
|
||||
arch_ops->txrx_soc_detach = dp_soc_detach_be;
|
||||
arch_ops->txrx_pdev_attach = dp_pdev_attach_be;
|
||||
arch_ops->txrx_pdev_detach = dp_pdev_detach_be;
|
||||
arch_ops->txrx_vdev_attach = dp_vdev_attach_be;
|
||||
arch_ops->txrx_vdev_detach = dp_vdev_detach_be;
|
||||
arch_ops->tx_comp_get_params_from_hal_desc =
|
||||
dp_tx_comp_get_params_from_hal_desc_be;
|
||||
}
|
147
dp/wifi3.0/be/dp_be.h
Normal file
147
dp/wifi3.0/be/dp_be.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
#ifndef __DP_BE_H
|
||||
#define __DP_BE_H
|
||||
|
||||
#include <dp_types.h>
|
||||
#include <hal_be_tx.h>
|
||||
|
||||
/**
|
||||
* struct dp_tx_bank_profile - DP wrapper for TCL banks
|
||||
* @is_configured: flag indicating if this bank is configured
|
||||
* @ref_count: ref count indicating number of users of the bank
|
||||
* @bank_config: HAL TX bank configuration
|
||||
*/
|
||||
struct dp_tx_bank_profile {
|
||||
uint8_t is_configured;
|
||||
qdf_atomic_t ref_count;
|
||||
union hal_tx_bank_config bank_config;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dp_soc_be - Extended DP soc for BE targets
|
||||
* @soc: dp soc structure
|
||||
* @num_bank_profiles: num TX bank profiles
|
||||
* @bank_profiles: bank profiles for various TX banks
|
||||
*/
|
||||
struct dp_soc_be {
|
||||
struct dp_soc soc;
|
||||
uint8_t num_bank_profiles;
|
||||
qdf_mutex_t tx_bank_lock;
|
||||
struct dp_tx_bank_profile *bank_profiles;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dp_pdev_be - Extended DP pdev for BE targets
|
||||
* @pdev: dp pdev structure
|
||||
*/
|
||||
struct dp_pdev_be {
|
||||
struct dp_pdev pdev;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dp_vdev_be - Extended DP vdev for BE targets
|
||||
* @vdev: dp vdev structure
|
||||
* @bank_id: bank_id to be used for TX
|
||||
* @vdev_id_check_en: flag if HW vdev_id check is enabled for vdev
|
||||
*/
|
||||
struct dp_vdev_be {
|
||||
struct dp_vdev vdev;
|
||||
int8_t bank_id;
|
||||
uint8_t vdev_id_check_en;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dp_peer_be - Extended DP peer for BE targets
|
||||
* @dp_peer: dp peer structure
|
||||
*/
|
||||
struct dp_peer_be {
|
||||
struct dp_peer peer;
|
||||
};
|
||||
|
||||
/**
|
||||
* dp_get_soc_context_size_be() - get context size for target specific DP soc
|
||||
*
|
||||
* Return: value in bytes for BE specific soc structure
|
||||
*/
|
||||
qdf_size_t dp_get_soc_context_size_be(void);
|
||||
|
||||
/**
|
||||
* dp_initialize_arch_ops_be() - initialize BE specific arch ops
|
||||
* @arch_ops: arch ops pointer
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void dp_initialize_arch_ops_be(struct dp_arch_ops *arch_ops);
|
||||
|
||||
/**
|
||||
* dp_get_context_size_be() - get BE specific size for peer/vdev/pdev/soc
|
||||
* @arch_ops: arch ops pointer
|
||||
*
|
||||
* Return: size in bytes for the context_type
|
||||
*/
|
||||
qdf_size_t dp_get_context_size_be(enum dp_context_type context_type);
|
||||
|
||||
/**
|
||||
* dp_get_be_soc_from_dp_soc() - get dp_soc_be from dp_soc
|
||||
* @soc: dp_soc pointer
|
||||
*
|
||||
* Return: dp_soc_be pointer
|
||||
*/
|
||||
static inline struct dp_soc_be *dp_get_be_soc_from_dp_soc(struct dp_soc *soc)
|
||||
{
|
||||
return (struct dp_soc_be *)soc;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_get_be_pdev_from_dp_pdev() - get dp_pdev_be from dp_pdev
|
||||
* @pdev: dp_pdev pointer
|
||||
*
|
||||
* Return: dp_pdev_be pointer
|
||||
*/
|
||||
static inline
|
||||
struct dp_pdev_be *dp_get_be_pdev_from_dp_pdev(struct dp_pdev *pdev)
|
||||
{
|
||||
return (struct dp_pdev_be *)pdev;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_get_be_vdev_from_dp_vdev() - get dp_vdev_be from dp_vdev
|
||||
* @vdev: dp_vdev pointer
|
||||
*
|
||||
* Return: dp_vdev_be pointer
|
||||
*/
|
||||
static inline
|
||||
struct dp_vdev_be *dp_get_be_vdev_from_dp_vdev(struct dp_vdev *vdev)
|
||||
{
|
||||
return (struct dp_vdev_be *)vdev;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_get_be_peer_from_dp_peer() - get dp_peer_be from dp_peer
|
||||
* @peer: dp_peer pointer
|
||||
*
|
||||
* Return: dp_peer_be pointer
|
||||
*/
|
||||
static inline
|
||||
struct dp_peer_be *dp_get_be_peer_from_dp_peer(struct dp_peer *peer)
|
||||
{
|
||||
return (struct dp_peer_be *)peer;
|
||||
}
|
||||
#endif
|
325
dp/wifi3.0/be/dp_be_tx.c
Normal file
325
dp/wifi3.0/be/dp_be_tx.c
Normal file
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2021 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.
|
||||
*/
|
||||
|
||||
#include "cdp_txrx_cmn_struct.h"
|
||||
#include "dp_types.h"
|
||||
#include "dp_tx.h"
|
||||
#include "dp_be_tx.h"
|
||||
#include "dp_tx_desc.h"
|
||||
#include "hal_tx.h"
|
||||
#include <hal_be_api.h>
|
||||
|
||||
void dp_tx_comp_get_params_from_hal_desc_be(struct dp_soc *soc,
|
||||
void *tx_comp_hal_desc,
|
||||
struct dp_tx_desc_s **r_tx_desc)
|
||||
{
|
||||
uint8_t pool_id;
|
||||
uint32_t tx_desc_id;
|
||||
|
||||
tx_desc_id = hal_tx_comp_get_desc_id(tx_comp_hal_desc);
|
||||
pool_id = (tx_desc_id & DP_TX_DESC_ID_POOL_MASK) >>
|
||||
DP_TX_DESC_ID_POOL_OS;
|
||||
|
||||
/* Find Tx descriptor */
|
||||
*r_tx_desc = dp_tx_desc_find(soc, pool_id,
|
||||
(tx_desc_id & DP_TX_DESC_ID_PAGE_MASK) >>
|
||||
DP_TX_DESC_ID_PAGE_OS,
|
||||
(tx_desc_id & DP_TX_DESC_ID_OFFSET_MASK) >>
|
||||
DP_TX_DESC_ID_OFFSET_OS);
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
dp_tx_hw_enqueue_be(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
struct dp_tx_desc_s *tx_desc, uint16_t fw_metadata,
|
||||
struct cdp_tx_exception_metadata *tx_exc_metadata,
|
||||
struct dp_tx_msdu_info_s *msdu_info)
|
||||
{
|
||||
void *hal_tx_desc;
|
||||
uint32_t *hal_tx_desc_cached;
|
||||
int coalesce = 0;
|
||||
struct dp_tx_queue *tx_q = &msdu_info->tx_queue;
|
||||
uint8_t ring_id = tx_q->ring_id & DP_TX_QUEUE_MASK;
|
||||
uint8_t tid = msdu_info->tid;
|
||||
struct dp_vdev_be *be_vdev;
|
||||
uint8_t cached_desc[HAL_TX_DESC_LEN_BYTES] = { 0 };
|
||||
uint8_t bm_id = dp_tx_get_rbm_id(soc, ring_id);
|
||||
hal_ring_handle_t hal_ring_hdl = NULL;
|
||||
QDF_STATUS status = QDF_STATUS_E_RESOURCES;
|
||||
|
||||
be_vdev = dp_get_be_vdev_from_dp_vdev(vdev);
|
||||
|
||||
if (!dp_tx_is_desc_id_valid(soc, tx_desc->id)) {
|
||||
dp_err_rl("Invalid tx desc id:%d", tx_desc->id);
|
||||
return QDF_STATUS_E_RESOURCES;
|
||||
}
|
||||
|
||||
hal_tx_desc_cached = (void *)cached_desc;
|
||||
|
||||
hal_tx_desc_set_buf_addr(soc->hal_soc, hal_tx_desc_cached,
|
||||
tx_desc->dma_addr, bm_id, tx_desc->id,
|
||||
(tx_desc->flags & DP_TX_DESC_FLAG_FRAG));
|
||||
hal_tx_desc_set_lmac_id(soc->hal_soc, hal_tx_desc_cached,
|
||||
vdev->lmac_id);
|
||||
|
||||
hal_tx_desc_set_search_index(soc->hal_soc, hal_tx_desc_cached,
|
||||
vdev->bss_ast_idx);
|
||||
/*
|
||||
* Bank_ID is used as DSCP_TABLE number in beryllium
|
||||
* So there is no explicit field used for DSCP_TID_TABLE_NUM.
|
||||
*/
|
||||
|
||||
hal_tx_desc_set_cache_set_num(soc->hal_soc, hal_tx_desc_cached,
|
||||
(vdev->bss_ast_hash & 0xF));
|
||||
|
||||
hal_tx_desc_set_fw_metadata(hal_tx_desc_cached, fw_metadata);
|
||||
hal_tx_desc_set_buf_length(hal_tx_desc_cached, tx_desc->length);
|
||||
hal_tx_desc_set_buf_offset(hal_tx_desc_cached, tx_desc->pkt_offset);
|
||||
|
||||
if (tx_desc->flags & DP_TX_DESC_FLAG_TO_FW)
|
||||
hal_tx_desc_set_to_fw(hal_tx_desc_cached, 1);
|
||||
|
||||
/* verify checksum offload configuration*/
|
||||
if (vdev->csum_enabled &&
|
||||
((qdf_nbuf_get_tx_cksum(tx_desc->nbuf) ==
|
||||
QDF_NBUF_TX_CKSUM_TCP_UDP) ||
|
||||
qdf_nbuf_is_tso(tx_desc->nbuf))) {
|
||||
hal_tx_desc_set_l3_checksum_en(hal_tx_desc_cached, 1);
|
||||
hal_tx_desc_set_l4_checksum_en(hal_tx_desc_cached, 1);
|
||||
}
|
||||
|
||||
hal_tx_desc_set_bank_id(hal_tx_desc_cached, be_vdev->bank_id);
|
||||
|
||||
hal_tx_desc_set_vdev_id(hal_tx_desc_cached, vdev->vdev_id);
|
||||
|
||||
if (tid != HTT_TX_EXT_TID_INVALID)
|
||||
hal_tx_desc_set_hlos_tid(hal_tx_desc_cached, tid);
|
||||
|
||||
if (qdf_unlikely(vdev->pdev->delay_stats_flag) ||
|
||||
qdf_unlikely(wlan_cfg_is_peer_ext_stats_enabled(soc->wlan_cfg_ctx)))
|
||||
tx_desc->timestamp = qdf_ktime_to_ms(qdf_ktime_real_get());
|
||||
|
||||
dp_verbose_debug("length:%d , type = %d, dma_addr %llx, offset %d desc id %u",
|
||||
tx_desc->length,
|
||||
(tx_desc->flags & DP_TX_DESC_FLAG_FRAG),
|
||||
(uint64_t)tx_desc->dma_addr, tx_desc->pkt_offset,
|
||||
tx_desc->id);
|
||||
|
||||
hal_ring_hdl = dp_tx_get_hal_ring_hdl(soc, ring_id);
|
||||
|
||||
if (qdf_unlikely(dp_tx_hal_ring_access_start(soc, hal_ring_hdl))) {
|
||||
dp_err("HAL RING Access Failed -- %pK", hal_ring_hdl);
|
||||
DP_STATS_INC(soc, tx.tcl_ring_full[ring_id], 1);
|
||||
DP_STATS_INC(vdev, tx_i.dropped.enqueue_fail, 1);
|
||||
return status;
|
||||
}
|
||||
|
||||
hal_tx_desc = hal_srng_src_get_next(soc->hal_soc, hal_ring_hdl);
|
||||
if (qdf_unlikely(!hal_tx_desc)) {
|
||||
dp_verbose_debug("TCL ring full ring_id:%d", ring_id);
|
||||
DP_STATS_INC(soc, tx.tcl_ring_full[ring_id], 1);
|
||||
DP_STATS_INC(vdev, tx_i.dropped.enqueue_fail, 1);
|
||||
goto ring_access_fail;
|
||||
}
|
||||
|
||||
tx_desc->flags |= DP_TX_DESC_FLAG_QUEUED_TX;
|
||||
dp_vdev_peer_stats_update_protocol_cnt_tx(vdev, tx_desc->nbuf);
|
||||
|
||||
/* Sync cached descriptor with HW */
|
||||
hal_tx_desc_sync(hal_tx_desc_cached, hal_tx_desc);
|
||||
|
||||
coalesce = dp_tx_attempt_coalescing(soc, vdev, tx_desc, tid);
|
||||
|
||||
DP_STATS_INC_PKT(vdev, tx_i.processed, 1, tx_desc->length);
|
||||
dp_tx_update_stats(soc, tx_desc->nbuf);
|
||||
status = QDF_STATUS_SUCCESS;
|
||||
|
||||
dp_tx_hw_desc_update_evt((uint8_t *)hal_tx_desc_cached,
|
||||
hal_ring_hdl, soc);
|
||||
|
||||
ring_access_fail:
|
||||
dp_tx_ring_access_end_wrapper(soc, hal_ring_hdl, coalesce);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS dp_tx_init_bank_profiles(struct dp_soc_be *be_soc)
|
||||
{
|
||||
int i, num_tcl_banks;
|
||||
|
||||
num_tcl_banks = hal_tx_get_num_tcl_banks(be_soc->soc.hal_soc);
|
||||
be_soc->num_bank_profiles = num_tcl_banks;
|
||||
be_soc->bank_profiles = qdf_mem_malloc(num_tcl_banks *
|
||||
sizeof(*be_soc->bank_profiles));
|
||||
if (!be_soc->bank_profiles) {
|
||||
dp_err("unable to allocate memory for DP TX Profiles!");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
qdf_mutex_create(&be_soc->tx_bank_lock);
|
||||
|
||||
for (i = 0; i < num_tcl_banks; i++) {
|
||||
be_soc->bank_profiles[i].is_configured = false;
|
||||
qdf_atomic_init(&be_soc->bank_profiles[i].ref_count);
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void dp_tx_deinit_bank_profiles(struct dp_soc_be *be_soc)
|
||||
{
|
||||
qdf_mem_free(be_soc->bank_profiles);
|
||||
qdf_mutex_destroy(&be_soc->tx_bank_lock);
|
||||
}
|
||||
|
||||
static
|
||||
void dp_tx_get_vdev_bank_config(struct dp_vdev_be *be_vdev,
|
||||
union hal_tx_bank_config *bank_config)
|
||||
{
|
||||
struct dp_vdev *vdev = &be_vdev->vdev;
|
||||
struct dp_soc *soc = vdev->pdev->soc;
|
||||
|
||||
bank_config->epd = 0;
|
||||
|
||||
bank_config->encap_type = vdev->tx_encap_type;
|
||||
|
||||
/* Only valid for raw frames. Needs work for RAW mode */
|
||||
bank_config->encrypt_type = 0;
|
||||
|
||||
bank_config->src_buffer_swap = 0;
|
||||
bank_config->link_meta_swap = 0;
|
||||
|
||||
if (soc->is_peer_map_unmap_v2 && vdev->opmode == wlan_op_mode_sta)
|
||||
vdev->search_type = HAL_TX_ADDR_INDEX_SEARCH;
|
||||
else
|
||||
vdev->search_type = HAL_TX_ADDR_SEARCH_DEFAULT;
|
||||
|
||||
bank_config->index_lookup_enable = 0;
|
||||
|
||||
bank_config->addrx_en =
|
||||
(vdev->hal_desc_addr_search_flags & HAL_TX_DESC_ADDRX_EN) ?
|
||||
1 : 0;
|
||||
bank_config->addry_en =
|
||||
(vdev->hal_desc_addr_search_flags & HAL_TX_DESC_ADDRY_EN) ?
|
||||
1 : 0;
|
||||
|
||||
bank_config->mesh_enable = vdev->mesh_vdev ? 1 : 0;
|
||||
|
||||
/* Disabling vdev id check for now. Needs revist. */
|
||||
bank_config->vdev_id_check_en = be_vdev->vdev_id_check_en;
|
||||
|
||||
bank_config->pmac_id = vdev->lmac_id;
|
||||
|
||||
bank_config->mcast_pkt_ctrl = 0;
|
||||
}
|
||||
|
||||
int dp_tx_get_bank_profile(struct dp_soc_be *be_soc,
|
||||
struct dp_vdev_be *be_vdev)
|
||||
{
|
||||
char *temp_str = "";
|
||||
bool found_match = false;
|
||||
int bank_id = DP_BE_INVALID_BANK_ID;
|
||||
int i;
|
||||
int unconfigured_slot = DP_BE_INVALID_BANK_ID;
|
||||
int zero_ref_count_slot = DP_BE_INVALID_BANK_ID;
|
||||
union hal_tx_bank_config vdev_config = {0};
|
||||
|
||||
/* convert vdev params into hal_tx_bank_config */
|
||||
dp_tx_get_vdev_bank_config(be_vdev, &vdev_config);
|
||||
|
||||
qdf_mutex_acquire(&be_soc->tx_bank_lock);
|
||||
/* go over all banks and find a matching/unconfigured/unsed bank */
|
||||
for (i = 0; i < be_soc->num_bank_profiles; i++) {
|
||||
if (be_soc->bank_profiles[i].is_configured &&
|
||||
(be_soc->bank_profiles[i].bank_config.val ^
|
||||
vdev_config.val) == 0) {
|
||||
found_match = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (unconfigured_slot == DP_BE_INVALID_BANK_ID &&
|
||||
!be_soc->bank_profiles[i].is_configured)
|
||||
unconfigured_slot = i;
|
||||
else if (zero_ref_count_slot == DP_BE_INVALID_BANK_ID &&
|
||||
!qdf_atomic_read(&be_soc->bank_profiles[i].ref_count))
|
||||
zero_ref_count_slot = i;
|
||||
}
|
||||
|
||||
if (found_match) {
|
||||
temp_str = "matching";
|
||||
bank_id = i;
|
||||
goto inc_ref_and_return;
|
||||
}
|
||||
if (unconfigured_slot != DP_BE_INVALID_BANK_ID) {
|
||||
temp_str = "unconfigured";
|
||||
bank_id = unconfigured_slot;
|
||||
goto configure_and_return;
|
||||
}
|
||||
if (zero_ref_count_slot != DP_BE_INVALID_BANK_ID) {
|
||||
temp_str = "zero_ref_count";
|
||||
bank_id = zero_ref_count_slot;
|
||||
}
|
||||
if (bank_id == DP_BE_INVALID_BANK_ID) {
|
||||
dp_alert("unable to find TX bank!");
|
||||
QDF_BUG(0);
|
||||
return bank_id;
|
||||
}
|
||||
|
||||
configure_and_return:
|
||||
be_soc->bank_profiles[bank_id].is_configured = true;
|
||||
be_soc->bank_profiles[bank_id].bank_config.val = vdev_config.val;
|
||||
hal_tx_populate_bank_register(be_soc->soc.hal_soc,
|
||||
&be_soc->bank_profiles[bank_id].bank_config,
|
||||
bank_id);
|
||||
inc_ref_and_return:
|
||||
qdf_atomic_inc(&be_soc->bank_profiles[bank_id].ref_count);
|
||||
qdf_mutex_release(&be_soc->tx_bank_lock);
|
||||
|
||||
dp_info("found %s slot at index %d, input:0x%x match:0x%x ref_count %u",
|
||||
temp_str, bank_id, vdev_config.val,
|
||||
be_soc->bank_profiles[bank_id].bank_config.val,
|
||||
qdf_atomic_read(&be_soc->bank_profiles[bank_id].ref_count));
|
||||
|
||||
dp_info("epd:%x encap:%x encryp:%x src_buf_swap:%x link_meta_swap:%x addrx_en:%x addry_en:%x mesh_en:%x vdev_id_check:%x pmac_id:%x mcast_pkt_ctrl:%x",
|
||||
be_soc->bank_profiles[bank_id].bank_config.epd,
|
||||
be_soc->bank_profiles[bank_id].bank_config.encap_type,
|
||||
be_soc->bank_profiles[bank_id].bank_config.encrypt_type,
|
||||
be_soc->bank_profiles[bank_id].bank_config.src_buffer_swap,
|
||||
be_soc->bank_profiles[bank_id].bank_config.link_meta_swap,
|
||||
be_soc->bank_profiles[bank_id].bank_config.addrx_en,
|
||||
be_soc->bank_profiles[bank_id].bank_config.addry_en,
|
||||
be_soc->bank_profiles[bank_id].bank_config.mesh_enable,
|
||||
be_soc->bank_profiles[bank_id].bank_config.vdev_id_check_en,
|
||||
be_soc->bank_profiles[bank_id].bank_config.pmac_id,
|
||||
be_soc->bank_profiles[bank_id].bank_config.mcast_pkt_ctrl);
|
||||
|
||||
return bank_id;
|
||||
}
|
||||
|
||||
void dp_tx_put_bank_profile(struct dp_soc_be *be_soc,
|
||||
struct dp_vdev_be *be_vdev)
|
||||
{
|
||||
qdf_mutex_acquire(&be_soc->tx_bank_lock);
|
||||
qdf_atomic_dec(&be_soc->bank_profiles[be_vdev->bank_id].ref_count);
|
||||
qdf_mutex_release(&be_soc->tx_bank_lock);
|
||||
}
|
||||
|
||||
void dp_tx_update_bank_profile(struct dp_soc_be *be_soc,
|
||||
struct dp_vdev_be *be_vdev)
|
||||
{
|
||||
dp_tx_put_bank_profile(be_soc, be_vdev);
|
||||
be_vdev->bank_id = dp_tx_get_bank_profile(be_soc, be_vdev);
|
||||
}
|
112
dp/wifi3.0/be/dp_be_tx.h
Normal file
112
dp/wifi3.0/be/dp_be_tx.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2021 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.
|
||||
*/
|
||||
#ifndef __DP_BE_TX_H
|
||||
#define __DP_BE_TX_H
|
||||
/**
|
||||
* DOC: dp_be_tx.h
|
||||
*
|
||||
* BE specific TX Datapath header file. Need not be exposed to common DP code.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <dp_types.h>
|
||||
#include "dp_be.h"
|
||||
|
||||
/* Invalid TX Bank ID value */
|
||||
#define DP_BE_INVALID_BANK_ID -1
|
||||
|
||||
/**
|
||||
* dp_tx_hw_enqueue_be() - Enqueue to TCL HW for transmit for BE target
|
||||
* @soc: DP Soc Handle
|
||||
* @vdev: DP vdev handle
|
||||
* @tx_desc: Tx Descriptor Handle
|
||||
* @fw_metadata: Metadata to send to Target Firmware along with frame
|
||||
* @tx_exc_metadata: Handle that holds exception path meta data
|
||||
* @msdu_info: msdu_info containing information about TX buffer
|
||||
*
|
||||
* Gets the next free TCL HW DMA descriptor and sets up required parameters
|
||||
* from software Tx descriptor
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS: success
|
||||
* QDF_STATUS_E_RESOURCES: Error return
|
||||
*/
|
||||
QDF_STATUS dp_tx_hw_enqueue_be(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
struct dp_tx_desc_s *tx_desc,
|
||||
uint16_t fw_metadata,
|
||||
struct cdp_tx_exception_metadata *metadata,
|
||||
struct dp_tx_msdu_info_s *msdu_info);
|
||||
|
||||
/**
|
||||
* dp_tx_comp_get_params_from_hal_desc_be() - Get TX desc from HAL comp desc
|
||||
* @soc: DP soc handle
|
||||
* @tx_comp_hal_desc: HAL TX Comp Descriptor
|
||||
* @r_tx_desc: SW Tx Descriptor retrieved from HAL desc.
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_tx_comp_get_params_from_hal_desc_be(struct dp_soc *soc,
|
||||
void *tx_comp_hal_desc,
|
||||
struct dp_tx_desc_s **r_tx_desc);
|
||||
|
||||
/**
|
||||
* dp_tx_init_bank_profiles() - Init TX bank profiles
|
||||
* @soc: DP soc handle
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS or QDF error code.
|
||||
*/
|
||||
QDF_STATUS dp_tx_init_bank_profiles(struct dp_soc_be *soc);
|
||||
|
||||
/**
|
||||
* dp_tx_deinit_bank_profiles() - De-Init TX bank profiles
|
||||
* @soc: DP soc handle
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_tx_deinit_bank_profiles(struct dp_soc_be *soc);
|
||||
|
||||
/**
|
||||
* dp_tx_get_bank_profile() - get TX bank profile for vdev
|
||||
* @soc: DP soc handle
|
||||
* @be_vdev: BE vdev pointer
|
||||
*
|
||||
* Return: bank profile allocated to vdev or DP_BE_INVALID_BANK_ID
|
||||
*/
|
||||
int dp_tx_get_bank_profile(struct dp_soc_be *soc,
|
||||
struct dp_vdev_be *be_vdev);
|
||||
|
||||
/**
|
||||
* dp_tx_put_bank_profile() - release TX bank profile for vdev
|
||||
* @soc: DP soc handle
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_tx_put_bank_profile(struct dp_soc_be *soc, struct dp_vdev_be *be_vdev);
|
||||
|
||||
/**
|
||||
* dp_tx_update_bank_profile() - release existing and allocate new bank profile
|
||||
* @soc: DP soc handle
|
||||
* @be_vdev: pointer to be_vdev structure
|
||||
*
|
||||
* The function releases the existing bank profile allocated to the vdev and
|
||||
* looks for a new bank profile based on updated dp_vdev TX params.
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_tx_update_bank_profile(struct dp_soc_be *be_soc,
|
||||
struct dp_vdev_be *be_vdev);
|
||||
#endif
|
80
dp/wifi3.0/dp_arch_ops.c
Normal file
80
dp/wifi3.0/dp_arch_ops.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2021 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.
|
||||
*/
|
||||
|
||||
#include "dp_types.h"
|
||||
#include "cdp_txrx_cmn_reg.h"
|
||||
|
||||
void dp_configure_arch_ops(struct dp_soc *soc);
|
||||
qdf_size_t dp_get_soc_context_size(uint16_t device_id);
|
||||
|
||||
#ifdef CONFIG_LITHIUM
|
||||
void dp_initialize_arch_ops_li(struct dp_arch_ops *arch_ops);
|
||||
qdf_size_t dp_get_soc_context_size_li(void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BERYLLIUM
|
||||
void dp_initialize_arch_ops_be(struct dp_arch_ops *arch_ops);
|
||||
qdf_size_t dp_get_soc_context_size_be(void);
|
||||
#endif
|
||||
|
||||
static void dp_initialize_default_arch_ops(struct dp_arch_ops *arch_ops)
|
||||
{
|
||||
/* assign dummy functions for arch_ops which are architecture specific */
|
||||
}
|
||||
|
||||
qdf_size_t dp_get_soc_context_size(uint16_t device_id)
|
||||
|
||||
{
|
||||
switch (cdp_get_arch_type_from_devid(device_id)) {
|
||||
#ifdef CONFIG_LITHIUM
|
||||
case LITHIUM_DP:
|
||||
return dp_get_soc_context_size_li();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BERYLLIUM
|
||||
case BERYLLIUM_DP:
|
||||
return dp_get_soc_context_size_be();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
QDF_BUG(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dp_configure_arch_ops(struct dp_soc *soc)
|
||||
{
|
||||
dp_initialize_default_arch_ops(&soc->arch_ops);
|
||||
|
||||
switch (cdp_get_arch_type_from_devid(soc->device_id)) {
|
||||
#ifdef CONFIG_LITHIUM
|
||||
case LITHIUM_DP:
|
||||
dp_initialize_arch_ops_li(&soc->arch_ops);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BERYLLIUM
|
||||
case BERYLLIUM_DP:
|
||||
dp_initialize_arch_ops_be(&soc->arch_ops);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
QDF_BUG(0);
|
||||
}
|
||||
}
|
@@ -1835,9 +1835,19 @@ void dp_peer_stats_update_protocol_cnt(struct cdp_soc_t *soc,
|
||||
bool is_egress,
|
||||
bool is_rx);
|
||||
|
||||
void dp_vdev_peer_stats_update_protocol_cnt_tx(struct dp_vdev *vdev_hdl,
|
||||
qdf_nbuf_t nbuf);
|
||||
|
||||
#else
|
||||
#define dp_vdev_peer_stats_update_protocol_cnt(vdev, nbuf, peer, \
|
||||
is_egress, is_rx)
|
||||
|
||||
static inline
|
||||
void dp_vdev_peer_stats_update_protocol_cnt_tx(struct dp_vdev *vdev_hdl,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
|
||||
|
@@ -54,6 +54,7 @@
|
||||
#include "qdf_mem.h" /* qdf_mem_malloc,free */
|
||||
#include "cfg_ucfg_api.h"
|
||||
#include "dp_mon_filter.h"
|
||||
|
||||
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
|
||||
#include "cdp_txrx_flow_ctrl_v2.h"
|
||||
#else
|
||||
@@ -118,6 +119,9 @@ cdp_dump_flow_pool_info(struct cdp_soc_t *soc)
|
||||
__QDF_TRACE_FL(QDF_TRACE_LEVEL_INFO_HIGH, QDF_MODULE_ID_DP_VDEV, ## params)
|
||||
#define dp_vdev_debug(params...) QDF_TRACE_DEBUG(QDF_MODULE_ID_DP_VDEV, params)
|
||||
|
||||
void dp_configure_arch_ops(struct dp_soc *soc);
|
||||
qdf_size_t dp_get_soc_context_size(uint16_t device_id);
|
||||
|
||||
/*
|
||||
* The max size of cdp_peer_stats_param_t is limited to 16 bytes.
|
||||
* If the buffer size is exceeding this size limit,
|
||||
@@ -5345,6 +5349,8 @@ static void dp_soc_detach(struct cdp_soc_t *txrx_soc)
|
||||
{
|
||||
struct dp_soc *soc = (struct dp_soc *)txrx_soc;
|
||||
|
||||
soc->arch_ops.txrx_soc_detach(soc);
|
||||
|
||||
dp_soc_swlm_detach(soc);
|
||||
dp_soc_tx_desc_sw_pools_free(soc);
|
||||
dp_soc_srng_free(soc);
|
||||
@@ -6104,12 +6110,17 @@ static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc,
|
||||
enum wlan_op_mode op_mode,
|
||||
enum wlan_op_subtype subtype)
|
||||
{
|
||||
int i = 0;
|
||||
qdf_size_t vdev_context_size;
|
||||
struct dp_soc *soc = (struct dp_soc *)cdp_soc;
|
||||
struct dp_pdev *pdev =
|
||||
dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
|
||||
pdev_id);
|
||||
struct dp_vdev *vdev = qdf_mem_malloc(sizeof(*vdev));
|
||||
int i = 0;
|
||||
struct dp_vdev *vdev;
|
||||
|
||||
vdev_context_size =
|
||||
soc->arch_ops.txrx_get_context_size(DP_CONTEXT_TYPE_VDEV);
|
||||
vdev = qdf_mem_malloc(vdev_context_size);
|
||||
|
||||
if (!pdev) {
|
||||
dp_init_err("%pK: DP PDEV is Null for pdev id %d",
|
||||
@@ -6221,6 +6232,9 @@ static QDF_STATUS dp_vdev_attach_wifi3(struct cdp_soc_t *cdp_soc,
|
||||
QDF_MAC_ADDR_REF(vdev->mac_addr.raw));
|
||||
DP_STATS_INIT(vdev);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(soc->arch_ops.txrx_vdev_attach(soc, vdev)))
|
||||
goto fail0;
|
||||
|
||||
if (wlan_op_mode_sta == vdev->opmode)
|
||||
dp_peer_create_wifi3((struct cdp_soc_t *)soc, vdev_id,
|
||||
vdev->mac_addr.raw);
|
||||
@@ -6411,6 +6425,8 @@ static QDF_STATUS dp_vdev_detach_wifi3(struct cdp_soc_t *cdp_soc,
|
||||
if (!vdev)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
soc->arch_ops.txrx_vdev_detach(soc, vdev);
|
||||
|
||||
pdev = vdev->pdev;
|
||||
|
||||
vap_self_peer = dp_sta_vdev_self_peer_ref_n_get(soc, vdev,
|
||||
@@ -12871,12 +12887,13 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
|
||||
goto fail0;
|
||||
}
|
||||
|
||||
soc = qdf_mem_malloc(sizeof(*soc));
|
||||
soc = qdf_mem_malloc(dp_get_soc_context_size(device_id));
|
||||
if (!soc) {
|
||||
dp_err("DP SOC memory allocation failed");
|
||||
goto fail0;
|
||||
}
|
||||
|
||||
dp_info("soc memory allocated %pk", soc);
|
||||
soc->hif_handle = hif_handle;
|
||||
soc->hal_soc = hif_get_hal_handle(soc->hif_handle);
|
||||
if (!soc->hal_soc)
|
||||
@@ -12890,6 +12907,8 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
|
||||
soc->osdev = qdf_osdev;
|
||||
soc->num_hw_dscp_tid_map = HAL_MAX_HW_DSCP_TID_MAPS;
|
||||
|
||||
dp_configure_arch_ops(soc);
|
||||
|
||||
/* Reset wbm sg list and flags */
|
||||
dp_rx_wbm_sg_list_reset(soc);
|
||||
|
||||
@@ -12925,6 +12944,11 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
|
||||
goto fail5;
|
||||
}
|
||||
|
||||
if (!QDF_IS_STATUS_SUCCESS(soc->arch_ops.txrx_soc_attach(soc))) {
|
||||
dp_err("unable to do target specific attach");
|
||||
goto fail6;
|
||||
}
|
||||
|
||||
dp_soc_swlm_attach(soc);
|
||||
dp_soc_set_interrupt_mode(soc);
|
||||
dp_soc_set_def_pdev(soc);
|
||||
@@ -12935,6 +12959,8 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
|
||||
qdf_skb_total_mem_stats_read());
|
||||
|
||||
return soc;
|
||||
fail6:
|
||||
dp_soc_tx_desc_sw_pools_free(soc);
|
||||
fail5:
|
||||
dp_soc_srng_free(soc);
|
||||
fail4:
|
||||
|
@@ -58,22 +58,6 @@
|
||||
/* invalid peer id for reinject*/
|
||||
#define DP_INVALID_PEER 0XFFFE
|
||||
|
||||
/*mapping between hal encrypt type and cdp_sec_type*/
|
||||
#define MAX_CDP_SEC_TYPE 12
|
||||
static const uint8_t sec_type_map[MAX_CDP_SEC_TYPE] = {
|
||||
HAL_TX_ENCRYPT_TYPE_NO_CIPHER,
|
||||
HAL_TX_ENCRYPT_TYPE_WEP_128,
|
||||
HAL_TX_ENCRYPT_TYPE_WEP_104,
|
||||
HAL_TX_ENCRYPT_TYPE_WEP_40,
|
||||
HAL_TX_ENCRYPT_TYPE_TKIP_WITH_MIC,
|
||||
HAL_TX_ENCRYPT_TYPE_TKIP_NO_MIC,
|
||||
HAL_TX_ENCRYPT_TYPE_AES_CCMP_128,
|
||||
HAL_TX_ENCRYPT_TYPE_WAPI,
|
||||
HAL_TX_ENCRYPT_TYPE_AES_CCMP_256,
|
||||
HAL_TX_ENCRYPT_TYPE_AES_GCMP_128,
|
||||
HAL_TX_ENCRYPT_TYPE_AES_GCMP_256,
|
||||
HAL_TX_ENCRYPT_TYPE_WAPI_GCM_SM4};
|
||||
|
||||
#ifdef CONFIG_WLAN_SYSFS_MEM_STATS
|
||||
/**
|
||||
* dp_update_tx_desc_stats - Update the increase or decrease in
|
||||
@@ -488,7 +472,7 @@ dp_tx_desc_release(struct dp_tx_desc_s *tx_desc, uint8_t desc_pool_id)
|
||||
qdf_atomic_dec(&soc->num_tx_exception);
|
||||
|
||||
if (HAL_TX_COMP_RELEASE_SOURCE_TQM ==
|
||||
hal_tx_comp_get_buffer_source(&tx_desc->comp))
|
||||
tx_desc->buffer_src)
|
||||
comp_status = hal_tx_comp_get_release_reason(&tx_desc->comp,
|
||||
soc->hal_soc);
|
||||
else
|
||||
@@ -1326,28 +1310,28 @@ static void dp_tx_raw_prepare_unset(struct dp_soc *soc,
|
||||
}
|
||||
|
||||
#ifdef VDEV_PEER_PROTOCOL_COUNT
|
||||
#define dp_vdev_peer_stats_update_protocol_cnt_tx(vdev_hdl, nbuf) \
|
||||
{ \
|
||||
qdf_nbuf_t nbuf_local; \
|
||||
struct dp_vdev *vdev_local = vdev_hdl; \
|
||||
do { \
|
||||
if (qdf_likely(!((vdev_local)->peer_protocol_count_track))) \
|
||||
break; \
|
||||
nbuf_local = nbuf; \
|
||||
if (qdf_unlikely(((vdev_local)->tx_encap_type) == \
|
||||
htt_cmn_pkt_type_raw)) \
|
||||
break; \
|
||||
else if (qdf_unlikely(qdf_nbuf_is_nonlinear((nbuf_local)))) \
|
||||
break; \
|
||||
else if (qdf_nbuf_is_tso((nbuf_local))) \
|
||||
break; \
|
||||
dp_vdev_peer_stats_update_protocol_cnt((vdev_local), \
|
||||
(nbuf_local), \
|
||||
NULL, 1, 0); \
|
||||
} while (0); \
|
||||
void dp_vdev_peer_stats_update_protocol_cnt_tx(struct dp_vdev *vdev_hdl,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
qdf_nbuf_t nbuf_local;
|
||||
struct dp_vdev *vdev_local = vdev_hdl;
|
||||
|
||||
do {
|
||||
if (qdf_likely(!((vdev_local)->peer_protocol_count_track)))
|
||||
break;
|
||||
nbuf_local = nbuf;
|
||||
if (qdf_unlikely(((vdev_local)->tx_encap_type) ==
|
||||
htt_cmn_pkt_type_raw))
|
||||
break;
|
||||
else if (qdf_unlikely(qdf_nbuf_is_nonlinear((nbuf_local))))
|
||||
break;
|
||||
else if (qdf_nbuf_is_tso((nbuf_local)))
|
||||
break;
|
||||
dp_vdev_peer_stats_update_protocol_cnt((vdev_local),
|
||||
(nbuf_local),
|
||||
NULL, 1, 0);
|
||||
} while (0);
|
||||
}
|
||||
#else
|
||||
#define dp_vdev_peer_stats_update_protocol_cnt_tx(vdev_hdl, skb)
|
||||
#endif
|
||||
|
||||
#ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR
|
||||
@@ -1358,22 +1342,13 @@ static void dp_tx_raw_prepare_unset(struct dp_soc *soc,
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
static inline void dp_tx_update_stats(struct dp_soc *soc,
|
||||
qdf_nbuf_t nbuf)
|
||||
void dp_tx_update_stats(struct dp_soc *soc,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
DP_STATS_INC_PKT(soc, tx.egress, 1, qdf_nbuf_len(nbuf));
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_attempt_coalescing() - Check and attempt TCL register write coalescing
|
||||
* @soc: Datapath soc handle
|
||||
* @tx_desc: tx packet descriptor
|
||||
* @tid: TID for pkt transmission
|
||||
*
|
||||
* Returns: 1, if coalescing is to be done
|
||||
* 0, if coalescing is not to be done
|
||||
*/
|
||||
static inline int
|
||||
int
|
||||
dp_tx_attempt_coalescing(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
struct dp_tx_desc_s *tx_desc,
|
||||
uint8_t tid)
|
||||
@@ -1409,15 +1384,7 @@ dp_tx_attempt_coalescing(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* dp_tx_ring_access_end() - HAL ring access end for data transmission
|
||||
* @soc: Datapath soc handle
|
||||
* @hal_ring_hdl: HAL ring handle
|
||||
* @coalesce: Coalesce the current write or not
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
static inline void
|
||||
void
|
||||
dp_tx_ring_access_end(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl,
|
||||
int coalesce)
|
||||
{
|
||||
@@ -1427,26 +1394,6 @@ dp_tx_ring_access_end(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl,
|
||||
dp_tx_hal_ring_access_end(soc, hal_ring_hdl);
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void dp_tx_update_stats(struct dp_soc *soc,
|
||||
qdf_nbuf_t nbuf)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int
|
||||
dp_tx_attempt_coalescing(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
struct dp_tx_desc_s *tx_desc,
|
||||
uint8_t tid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
dp_tx_ring_access_end(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl,
|
||||
int coalesce)
|
||||
{
|
||||
dp_tx_hal_ring_access_end(soc, hal_ring_hdl);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FEATURE_RUNTIME_PM
|
||||
@@ -1461,7 +1408,7 @@ dp_tx_ring_access_end(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl,
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
static inline void
|
||||
void
|
||||
dp_tx_ring_access_end_wrapper(struct dp_soc *soc,
|
||||
hal_ring_handle_t hal_ring_hdl,
|
||||
int coalesce)
|
||||
@@ -1504,191 +1451,8 @@ dp_tx_ring_access_end_wrapper(struct dp_soc *soc,
|
||||
dp_runtime_put(soc);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static inline void
|
||||
dp_tx_ring_access_end_wrapper(struct dp_soc *soc,
|
||||
hal_ring_handle_t hal_ring_hdl,
|
||||
int coalesce)
|
||||
{
|
||||
dp_tx_ring_access_end(soc, hal_ring_hdl, coalesce);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DP_TX_HW_DESC_HISTORY
|
||||
static inline void
|
||||
dp_tx_hw_desc_update_evt(uint8_t *hal_tx_desc_cached,
|
||||
hal_ring_handle_t hal_ring_hdl,
|
||||
struct dp_soc *soc)
|
||||
{
|
||||
struct dp_tx_hw_desc_evt *evt;
|
||||
uint64_t idx = 0;
|
||||
|
||||
if (!soc->tx_hw_desc_history)
|
||||
return;
|
||||
|
||||
idx = ++soc->tx_hw_desc_history->index;
|
||||
if (idx == DP_TX_HW_DESC_HIST_MAX)
|
||||
soc->tx_hw_desc_history->index = 0;
|
||||
idx = qdf_do_div_rem(idx, DP_TX_HW_DESC_HIST_MAX);
|
||||
|
||||
evt = &soc->tx_hw_desc_history->entry[idx];
|
||||
qdf_mem_copy(evt->tcl_desc, hal_tx_desc_cached, HAL_TX_DESC_LEN_BYTES);
|
||||
evt->posted = qdf_get_log_timestamp();
|
||||
hal_get_sw_hptp(soc->hal_soc, hal_ring_hdl, &evt->tp, &evt->hp);
|
||||
}
|
||||
#else
|
||||
static inline void
|
||||
dp_tx_hw_desc_update_evt(uint8_t *hal_tx_desc_cached,
|
||||
hal_ring_handle_t hal_ring_hdl,
|
||||
struct dp_soc *soc)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* dp_tx_hw_enqueue() - Enqueue to TCL HW for transmit
|
||||
* @soc: DP Soc Handle
|
||||
* @vdev: DP vdev handle
|
||||
* @tx_desc: Tx Descriptor Handle
|
||||
* @tid: TID from HLOS for overriding default DSCP-TID mapping
|
||||
* @fw_metadata: Metadata to send to Target Firmware along with frame
|
||||
* @ring_id: Ring ID of H/W ring to which we enqueue the packet
|
||||
* @tx_exc_metadata: Handle that holds exception path meta data
|
||||
*
|
||||
* Gets the next free TCL HW DMA descriptor and sets up required parameters
|
||||
* from software Tx descriptor
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS: success
|
||||
* QDF_STATUS_E_RESOURCES: Error return
|
||||
*/
|
||||
static QDF_STATUS
|
||||
dp_tx_hw_enqueue(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
struct dp_tx_desc_s *tx_desc, uint16_t fw_metadata,
|
||||
struct cdp_tx_exception_metadata *tx_exc_metadata,
|
||||
struct dp_tx_msdu_info_s *msdu_info)
|
||||
{
|
||||
void *hal_tx_desc;
|
||||
uint32_t *hal_tx_desc_cached;
|
||||
int coalesce = 0;
|
||||
struct dp_tx_queue *tx_q = &msdu_info->tx_queue;
|
||||
uint8_t ring_id = tx_q->ring_id & DP_TX_QUEUE_MASK;
|
||||
uint8_t tid = msdu_info->tid;
|
||||
|
||||
/*
|
||||
* Setting it initialization statically here to avoid
|
||||
* a memset call jump with qdf_mem_set call
|
||||
*/
|
||||
uint8_t cached_desc[HAL_TX_DESC_LEN_BYTES] = { 0 };
|
||||
|
||||
enum cdp_sec_type sec_type = ((tx_exc_metadata &&
|
||||
tx_exc_metadata->sec_type != CDP_INVALID_SEC_TYPE) ?
|
||||
tx_exc_metadata->sec_type : vdev->sec_type);
|
||||
|
||||
/* Return Buffer Manager ID */
|
||||
uint8_t bm_id = dp_tx_get_rbm_id(soc, ring_id);
|
||||
|
||||
hal_ring_handle_t hal_ring_hdl = NULL;
|
||||
|
||||
QDF_STATUS status = QDF_STATUS_E_RESOURCES;
|
||||
|
||||
if (!dp_tx_is_desc_id_valid(soc, tx_desc->id)) {
|
||||
dp_err_rl("Invalid tx desc id:%d", tx_desc->id);
|
||||
return QDF_STATUS_E_RESOURCES;
|
||||
}
|
||||
|
||||
hal_tx_desc_cached = (void *) cached_desc;
|
||||
|
||||
hal_tx_desc_set_buf_addr(soc->hal_soc, hal_tx_desc_cached,
|
||||
tx_desc->dma_addr, bm_id, tx_desc->id,
|
||||
(tx_desc->flags & DP_TX_DESC_FLAG_FRAG));
|
||||
hal_tx_desc_set_lmac_id(soc->hal_soc, hal_tx_desc_cached,
|
||||
vdev->lmac_id);
|
||||
hal_tx_desc_set_search_type(soc->hal_soc, hal_tx_desc_cached,
|
||||
vdev->search_type);
|
||||
hal_tx_desc_set_search_index(soc->hal_soc, hal_tx_desc_cached,
|
||||
vdev->bss_ast_idx);
|
||||
hal_tx_desc_set_dscp_tid_table_id(soc->hal_soc, hal_tx_desc_cached,
|
||||
vdev->dscp_tid_map_id);
|
||||
|
||||
hal_tx_desc_set_encrypt_type(hal_tx_desc_cached,
|
||||
sec_type_map[sec_type]);
|
||||
hal_tx_desc_set_cache_set_num(soc->hal_soc, hal_tx_desc_cached,
|
||||
(vdev->bss_ast_hash & 0xF));
|
||||
|
||||
hal_tx_desc_set_fw_metadata(hal_tx_desc_cached, fw_metadata);
|
||||
hal_tx_desc_set_buf_length(hal_tx_desc_cached, tx_desc->length);
|
||||
hal_tx_desc_set_buf_offset(hal_tx_desc_cached, tx_desc->pkt_offset);
|
||||
hal_tx_desc_set_encap_type(hal_tx_desc_cached, tx_desc->tx_encap_type);
|
||||
hal_tx_desc_set_addr_search_flags(hal_tx_desc_cached,
|
||||
vdev->hal_desc_addr_search_flags);
|
||||
|
||||
if (tx_desc->flags & DP_TX_DESC_FLAG_TO_FW)
|
||||
hal_tx_desc_set_to_fw(hal_tx_desc_cached, 1);
|
||||
|
||||
/* verify checksum offload configuration*/
|
||||
if (vdev->csum_enabled &&
|
||||
((qdf_nbuf_get_tx_cksum(tx_desc->nbuf) == QDF_NBUF_TX_CKSUM_TCP_UDP)
|
||||
|| qdf_nbuf_is_tso(tx_desc->nbuf))) {
|
||||
hal_tx_desc_set_l3_checksum_en(hal_tx_desc_cached, 1);
|
||||
hal_tx_desc_set_l4_checksum_en(hal_tx_desc_cached, 1);
|
||||
}
|
||||
|
||||
if (tid != HTT_TX_EXT_TID_INVALID)
|
||||
hal_tx_desc_set_hlos_tid(hal_tx_desc_cached, tid);
|
||||
|
||||
if (tx_desc->flags & DP_TX_DESC_FLAG_MESH)
|
||||
hal_tx_desc_set_mesh_en(soc->hal_soc, hal_tx_desc_cached, 1);
|
||||
|
||||
if (qdf_unlikely(vdev->pdev->delay_stats_flag) ||
|
||||
qdf_unlikely(wlan_cfg_is_peer_ext_stats_enabled(
|
||||
soc->wlan_cfg_ctx)))
|
||||
tx_desc->timestamp = qdf_ktime_to_ms(qdf_ktime_real_get());
|
||||
|
||||
dp_verbose_debug("length:%d , type = %d, dma_addr %llx, offset %d desc id %u",
|
||||
tx_desc->length,
|
||||
(tx_desc->flags & DP_TX_DESC_FLAG_FRAG),
|
||||
(uint64_t)tx_desc->dma_addr, tx_desc->pkt_offset,
|
||||
tx_desc->id);
|
||||
|
||||
hal_ring_hdl = dp_tx_get_hal_ring_hdl(soc, ring_id);
|
||||
|
||||
if (qdf_unlikely(dp_tx_hal_ring_access_start(soc, hal_ring_hdl))) {
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s %d : HAL RING Access Failed -- %pK",
|
||||
__func__, __LINE__, hal_ring_hdl);
|
||||
DP_STATS_INC(soc, tx.tcl_ring_full[ring_id], 1);
|
||||
DP_STATS_INC(vdev, tx_i.dropped.enqueue_fail, 1);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Sync cached descriptor with HW */
|
||||
|
||||
hal_tx_desc = hal_srng_src_get_next(soc->hal_soc, hal_ring_hdl);
|
||||
if (qdf_unlikely(!hal_tx_desc)) {
|
||||
dp_verbose_debug("TCL ring full ring_id:%d", ring_id);
|
||||
DP_STATS_INC(soc, tx.tcl_ring_full[ring_id], 1);
|
||||
DP_STATS_INC(vdev, tx_i.dropped.enqueue_fail, 1);
|
||||
goto ring_access_fail;
|
||||
}
|
||||
|
||||
tx_desc->flags |= DP_TX_DESC_FLAG_QUEUED_TX;
|
||||
dp_vdev_peer_stats_update_protocol_cnt_tx(vdev, tx_desc->nbuf);
|
||||
hal_tx_desc_sync(hal_tx_desc_cached, hal_tx_desc);
|
||||
coalesce = dp_tx_attempt_coalescing(soc, vdev, tx_desc, tid);
|
||||
DP_STATS_INC_PKT(vdev, tx_i.processed, 1, tx_desc->length);
|
||||
dp_tx_update_stats(soc, tx_desc->nbuf);
|
||||
status = QDF_STATUS_SUCCESS;
|
||||
|
||||
dp_tx_hw_desc_update_evt((uint8_t *)hal_tx_desc_cached,
|
||||
hal_ring_hdl, soc);
|
||||
|
||||
ring_access_fail:
|
||||
dp_tx_ring_access_end_wrapper(soc, hal_ring_hdl, coalesce);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* dp_cce_classify() - Classify the frame based on CCE rules
|
||||
* @vdev: DP vdev handle
|
||||
@@ -2244,8 +2008,9 @@ dp_tx_send_msdu_single(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||
dp_tx_desc_history_add(soc, tx_desc->dma_addr, nbuf,
|
||||
tx_desc->id, DP_TX_DESC_MAP);
|
||||
/* Enqueue the Tx MSDU descriptor to HW for transmit */
|
||||
status = dp_tx_hw_enqueue(soc, vdev, tx_desc, htt_tcl_metadata,
|
||||
tx_exc_metadata, msdu_info);
|
||||
status = soc->arch_ops.tx_hw_enqueue(soc, vdev, tx_desc,
|
||||
htt_tcl_metadata,
|
||||
tx_exc_metadata, msdu_info);
|
||||
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
dp_tx_err_rl("Tx_hw_enqueue Fail tx_desc %pK queue %d",
|
||||
@@ -2474,8 +2239,9 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
||||
/*
|
||||
* Enqueue the Tx MSDU descriptor to HW for transmit
|
||||
*/
|
||||
status = dp_tx_hw_enqueue(soc, vdev, tx_desc, htt_tcl_metadata,
|
||||
NULL, msdu_info);
|
||||
status = soc->arch_ops.tx_hw_enqueue(soc, vdev, tx_desc,
|
||||
htt_tcl_metadata,
|
||||
NULL, msdu_info);
|
||||
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
dp_info("Tx_hw_enqueue Fail tx_desc %pK queue %d",
|
||||
@@ -4626,8 +4392,6 @@ uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
|
||||
{
|
||||
void *tx_comp_hal_desc;
|
||||
uint8_t buffer_src;
|
||||
uint8_t pool_id;
|
||||
uint32_t tx_desc_id;
|
||||
struct dp_tx_desc_s *tx_desc = NULL;
|
||||
struct dp_tx_desc_s *head_desc = NULL;
|
||||
struct dp_tx_desc_s *tail_desc = NULL;
|
||||
@@ -4662,8 +4426,8 @@ more_data:
|
||||
tx_comp_hal_desc = dp_srng_dst_get_next(soc, hal_ring_hdl);
|
||||
if (qdf_unlikely(!tx_comp_hal_desc))
|
||||
break;
|
||||
|
||||
buffer_src = hal_tx_comp_get_buffer_source(tx_comp_hal_desc);
|
||||
buffer_src = hal_tx_comp_get_buffer_source(soc->hal_soc,
|
||||
tx_comp_hal_desc);
|
||||
|
||||
/* If this buffer was not released by TQM or FW, then it is not
|
||||
* Tx completion indication, assert */
|
||||
@@ -4710,18 +4474,15 @@ more_data:
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get descriptor id */
|
||||
tx_desc_id = hal_tx_comp_get_desc_id(tx_comp_hal_desc);
|
||||
pool_id = (tx_desc_id & DP_TX_DESC_ID_POOL_MASK) >>
|
||||
DP_TX_DESC_ID_POOL_OS;
|
||||
|
||||
/* Find Tx descriptor */
|
||||
tx_desc = dp_tx_desc_find(soc, pool_id,
|
||||
(tx_desc_id & DP_TX_DESC_ID_PAGE_MASK) >>
|
||||
DP_TX_DESC_ID_PAGE_OS,
|
||||
(tx_desc_id & DP_TX_DESC_ID_OFFSET_MASK) >>
|
||||
DP_TX_DESC_ID_OFFSET_OS);
|
||||
|
||||
soc->arch_ops.tx_comp_get_params_from_hal_desc(soc,
|
||||
tx_comp_hal_desc,
|
||||
&tx_desc);
|
||||
if (!tx_desc) {
|
||||
dp_err("unable to retrieve tx_desc!");
|
||||
QDF_BUG(0);
|
||||
continue;
|
||||
}
|
||||
tx_desc->buffer_src = buffer_src;
|
||||
/*
|
||||
* If the release source is FW, process the HTT status
|
||||
*/
|
||||
@@ -4737,6 +4498,7 @@ more_data:
|
||||
hal_tx_comp_get_peer_id(tx_comp_hal_desc);
|
||||
tx_desc->tx_status =
|
||||
hal_tx_comp_get_tx_status(tx_comp_hal_desc);
|
||||
tx_desc->buffer_src = buffer_src;
|
||||
/*
|
||||
* If the fast completion mode is enabled extended
|
||||
* metadata from descriptor is not copied
|
||||
@@ -4753,31 +4515,23 @@ more_data:
|
||||
((tx_desc->vdev_id == DP_INVALID_VDEV_ID) &&
|
||||
!tx_desc->flags)) {
|
||||
dp_tx_comp_info_rl("Descriptor freed in vdev_detach %d",
|
||||
tx_desc_id);
|
||||
tx_desc->id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (qdf_unlikely(tx_desc->pdev->is_pdev_down)) {
|
||||
dp_tx_comp_info_rl("pdev in down state %d",
|
||||
tx_desc_id);
|
||||
tx_desc->id);
|
||||
tx_desc->flags |= DP_TX_DESC_FLAG_TX_COMP_ERR;
|
||||
dp_tx_comp_free_buf(soc, tx_desc);
|
||||
dp_tx_desc_release(tx_desc, tx_desc->pool_id);
|
||||
goto next_desc;
|
||||
}
|
||||
|
||||
/* Pool id is not matching. Error */
|
||||
if (tx_desc->pool_id != pool_id) {
|
||||
dp_tx_comp_alert("Tx Comp pool id %d not matched %d",
|
||||
pool_id, tx_desc->pool_id);
|
||||
|
||||
qdf_assert_always(0);
|
||||
}
|
||||
|
||||
if (!(tx_desc->flags & DP_TX_DESC_FLAG_ALLOCATED) ||
|
||||
!(tx_desc->flags & DP_TX_DESC_FLAG_QUEUED_TX)) {
|
||||
dp_tx_comp_alert("Txdesc invalid, flgs = %x,id = %d",
|
||||
tx_desc->flags, tx_desc_id);
|
||||
tx_desc->flags, tx_desc->id);
|
||||
qdf_assert_always(0);
|
||||
}
|
||||
|
||||
@@ -5502,3 +5256,4 @@ QDF_STATUS dp_tso_soc_detach(struct cdp_soc_t *txrx_soc)
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include "if_meta_hdr.h"
|
||||
#endif
|
||||
#include "dp_internal.h"
|
||||
#include "hal_tx.h"
|
||||
|
||||
#define DP_INVALID_VDEV_ID 0xFF
|
||||
|
||||
@@ -457,11 +458,11 @@ static inline hal_ring_handle_t dp_tx_get_hal_ring_hdl(struct dp_soc *soc,
|
||||
*
|
||||
* Return - HAL ring handle
|
||||
*/
|
||||
static inline uint8_t dp_tx_get_rbm_id(struct dp_soc *doc,
|
||||
static inline uint8_t dp_tx_get_rbm_id(struct dp_soc *soc,
|
||||
uint8_t ring_id)
|
||||
{
|
||||
return (ring_id ? HAL_WBM_SW0_BM_ID + (ring_id - 1) :
|
||||
HAL_WBM_SW2_BM_ID);
|
||||
return (ring_id ? soc->wbm_sw0_bm_id + (ring_id - 1) :
|
||||
HAL_WBM_SW2_BM_ID(soc->wbm_sw0_bm_id));
|
||||
}
|
||||
|
||||
#else /* QCA_OL_TX_MULTIQ_SUPPORT */
|
||||
@@ -485,7 +486,7 @@ static inline hal_ring_handle_t dp_tx_get_hal_ring_hdl(struct dp_soc *soc,
|
||||
static inline uint8_t dp_tx_get_rbm_id(struct dp_soc *soc,
|
||||
uint8_t ring_id)
|
||||
{
|
||||
return (ring_id + HAL_WBM_SW0_BM_ID);
|
||||
return (ring_id + soc->wbm_sw0_bm_id);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -676,4 +677,113 @@ dp_send_completion_to_pkt_capture(struct dp_soc *soc,
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR
|
||||
/**
|
||||
* dp_tx_update_stats() - Update soc level tx stats
|
||||
* @soc: DP soc handle
|
||||
* @nbuf: packet being transmitted
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
void dp_tx_update_stats(struct dp_soc *soc,
|
||||
qdf_nbuf_t nbuf);
|
||||
|
||||
/**
|
||||
* dp_tx_attempt_coalescing() - Check and attempt TCL register write coalescing
|
||||
* @soc: Datapath soc handle
|
||||
* @tx_desc: tx packet descriptor
|
||||
* @tid: TID for pkt transmission
|
||||
*
|
||||
* Returns: 1, if coalescing is to be done
|
||||
* 0, if coalescing is not to be done
|
||||
*/
|
||||
int
|
||||
dp_tx_attempt_coalescing(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
struct dp_tx_desc_s *tx_desc,
|
||||
uint8_t tid);
|
||||
|
||||
/**
|
||||
* dp_tx_ring_access_end() - HAL ring access end for data transmission
|
||||
* @soc: Datapath soc handle
|
||||
* @hal_ring_hdl: HAL ring handle
|
||||
* @coalesce: Coalesce the current write or not
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
void
|
||||
dp_tx_ring_access_end(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl,
|
||||
int coalesce);
|
||||
#else
|
||||
/**
|
||||
* dp_tx_update_stats() - Update soc level tx stats
|
||||
* @soc: DP soc handle
|
||||
* @nbuf: packet being transmitted
|
||||
*
|
||||
* Returns: none
|
||||
*/
|
||||
static inline void dp_tx_update_stats(struct dp_soc *soc,
|
||||
qdf_nbuf_t nbuf) { }
|
||||
static inline void
|
||||
dp_tx_ring_access_end(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl,
|
||||
int coalesce)
|
||||
{
|
||||
dp_tx_hal_ring_access_end(soc, hal_ring_hdl);
|
||||
}
|
||||
|
||||
static inline int
|
||||
dp_tx_attempt_coalescing(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
struct dp_tx_desc_s *tx_desc,
|
||||
uint8_t tid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WLAN_DP_FEATURE_SW_LATENCY_MGR */
|
||||
|
||||
#ifdef FEATURE_RUNTIME_PM
|
||||
void
|
||||
dp_tx_ring_access_end_wrapper(struct dp_soc *soc,
|
||||
hal_ring_handle_t hal_ring_hdl,
|
||||
int coalesce);
|
||||
#else
|
||||
static inline void
|
||||
dp_tx_ring_access_end_wrapper(struct dp_soc *soc,
|
||||
hal_ring_handle_t hal_ring_hdl,
|
||||
int coalesce)
|
||||
{
|
||||
dp_tx_ring_access_end(soc, hal_ring_hdl, coalesce);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DP_TX_HW_DESC_HISTORY
|
||||
static inline void
|
||||
dp_tx_hw_desc_update_evt(uint8_t *hal_tx_desc_cached,
|
||||
hal_ring_handle_t hal_ring_hdl,
|
||||
struct dp_soc *soc)
|
||||
{
|
||||
struct dp_tx_hw_desc_evt *evt;
|
||||
uint64_t idx = 0;
|
||||
|
||||
if (!soc->tx_hw_desc_history)
|
||||
return;
|
||||
|
||||
idx = ++soc->tx_hw_desc_history->index;
|
||||
if (idx == DP_TX_HW_DESC_HIST_MAX)
|
||||
soc->tx_hw_desc_history->index = 0;
|
||||
idx = qdf_do_div_rem(idx, DP_TX_HW_DESC_HIST_MAX);
|
||||
|
||||
evt = &soc->tx_hw_desc_history->entry[idx];
|
||||
qdf_mem_copy(evt->tcl_desc, hal_tx_desc_cached, HAL_TX_DESC_LEN_BYTES);
|
||||
evt->posted = qdf_get_log_timestamp();
|
||||
hal_get_sw_hptp(soc->hal_soc, hal_ring_hdl, &evt->tp, &evt->hp);
|
||||
}
|
||||
#else
|
||||
static inline void
|
||||
dp_tx_hw_desc_update_evt(uint8_t *hal_tx_desc_cached,
|
||||
hal_ring_handle_t hal_ring_hdl,
|
||||
struct dp_soc *soc)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -57,6 +57,7 @@
|
||||
#ifdef WLAN_TX_PKT_CAPTURE_ENH
|
||||
#include "dp_tx_capture.h"
|
||||
#endif
|
||||
//#include "dp_tx.h"
|
||||
|
||||
#define REPT_MU_MIMO 1
|
||||
#define REPT_MU_OFDMA_MIMO 3
|
||||
@@ -504,7 +505,8 @@ struct dp_tx_ext_desc_pool_s {
|
||||
* @tx_encap_type: Transmit encap type (i.e. Raw, Native Wi-Fi, Ethernet).
|
||||
* This is maintained in descriptor to allow more efficient
|
||||
* processing in completion event processing code.
|
||||
* This field is filled in with the htt_pkt_type enum.
|
||||
* This field is filled in with the htt_pkt_type enum.
|
||||
* @buffer_src: buffer source TQM, REO, FW etc.
|
||||
* @frm_type: Frame Type - ToDo check if this is redundant
|
||||
* @pkt_offset: Offset from which the actual packet data starts
|
||||
* @me_buffer: Pointer to ME buffer - store this so that it can be freed on
|
||||
@@ -522,7 +524,9 @@ struct dp_tx_desc_s {
|
||||
uint8_t tx_status;
|
||||
uint16_t peer_id;
|
||||
struct dp_pdev *pdev;
|
||||
uint8_t tx_encap_type;
|
||||
uint8_t tx_encap_type:2,
|
||||
buffer_src:3,
|
||||
reserved:3;
|
||||
uint8_t frm_type;
|
||||
uint8_t pkt_offset;
|
||||
uint8_t pool_id;
|
||||
@@ -1491,6 +1495,64 @@ struct ipa_dp_tx_rsc {
|
||||
};
|
||||
#endif
|
||||
|
||||
struct dp_tx_msdu_info_s;
|
||||
/*
|
||||
* enum dp_context_type- DP Context Type
|
||||
* @DP_CONTEXT_TYPE_SOC: Context type DP SOC
|
||||
* @DP_CONTEXT_TYPE_PDEV: Context type DP PDEV
|
||||
* @DP_CONTEXT_TYPE_VDEV: Context type DP VDEV
|
||||
* @DP_CONTEXT_TYPE_PEER: Context type DP PEER
|
||||
*
|
||||
* Helper enums to be used to retrieve the size of the corresponding
|
||||
* data structure by passing the type.
|
||||
*/
|
||||
enum dp_context_type {
|
||||
DP_CONTEXT_TYPE_SOC,
|
||||
DP_CONTEXT_TYPE_PDEV,
|
||||
DP_CONTEXT_TYPE_VDEV,
|
||||
DP_CONTEXT_TYPE_PEER
|
||||
};
|
||||
|
||||
/*
|
||||
* struct dp_arch_ops- DP target specific arch ops
|
||||
* @DP_CONTEXT_TYPE_SOC: Context type DP SOC
|
||||
* @DP_CONTEXT_TYPE_PDEV: Context type DP PDEV
|
||||
* @tx_hw_enqueue: enqueue TX data to HW
|
||||
* @tx_comp_get_params_from_hal_desc: get software tx descriptor and release
|
||||
* source from HAL desc for wbm release ring
|
||||
* @txrx_set_vdev_param: target specific ops while setting vdev params
|
||||
*/
|
||||
struct dp_arch_ops {
|
||||
/* INIT/DEINIT Arch Ops */
|
||||
QDF_STATUS (*txrx_soc_attach)(struct dp_soc *soc);
|
||||
QDF_STATUS (*txrx_soc_detach)(struct dp_soc *soc);
|
||||
QDF_STATUS (*txrx_pdev_attach)(struct dp_pdev *pdev);
|
||||
QDF_STATUS (*txrx_pdev_detach)(struct dp_pdev *pdev);
|
||||
QDF_STATUS (*txrx_vdev_attach)(struct dp_soc *soc,
|
||||
struct dp_vdev *vdev);
|
||||
QDF_STATUS (*txrx_vdev_detach)(struct dp_soc *soc,
|
||||
struct dp_vdev *vdev);
|
||||
|
||||
/* TX RX Arch Ops */
|
||||
QDF_STATUS (*tx_hw_enqueue)(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
struct dp_tx_desc_s *tx_desc,
|
||||
uint16_t fw_metadata,
|
||||
struct cdp_tx_exception_metadata *metadata,
|
||||
struct dp_tx_msdu_info_s *msdu_info);
|
||||
|
||||
void (*tx_comp_get_params_from_hal_desc)(struct dp_soc *soc,
|
||||
void *tx_comp_hal_desc,
|
||||
struct dp_tx_desc_s **desc);
|
||||
/* Control Arch Ops */
|
||||
QDF_STATUS (*txrx_set_vdev_param)(struct dp_soc *soc,
|
||||
struct dp_vdev *vdev,
|
||||
enum cdp_vdev_param_type param,
|
||||
cdp_config_param_type val);
|
||||
|
||||
/* Misc Arch Ops */
|
||||
qdf_size_t (*txrx_get_context_size)(enum dp_context_type);
|
||||
};
|
||||
|
||||
/* SOC level structure for data path */
|
||||
struct dp_soc {
|
||||
/**
|
||||
@@ -1506,6 +1568,8 @@ struct dp_soc {
|
||||
/* OS device abstraction */
|
||||
qdf_device_t osdev;
|
||||
|
||||
struct dp_arch_ops arch_ops;
|
||||
|
||||
/*cce disable*/
|
||||
bool cce_disable;
|
||||
|
||||
@@ -1939,6 +2003,8 @@ struct dp_soc {
|
||||
qdf_spinlock_t reo_desc_deferred_freelist_lock;
|
||||
bool reo_desc_deferred_freelist_init;
|
||||
#endif
|
||||
/* BM id for first WBM2SW ring */
|
||||
uint32_t wbm_sw0_bm_id;
|
||||
};
|
||||
|
||||
#ifdef IPA_OFFLOAD
|
||||
@@ -3358,6 +3424,8 @@ struct dp_req_rx_hw_stats_t {
|
||||
bool is_query_timeout;
|
||||
};
|
||||
#endif
|
||||
/* soc level structure to declare arch specific ops for DP */
|
||||
|
||||
|
||||
void dp_hw_link_desc_pool_banks_free(struct dp_soc *soc, uint32_t mac_id);
|
||||
QDF_STATUS dp_hw_link_desc_pool_banks_alloc(struct dp_soc *soc,
|
||||
|
90
dp/wifi3.0/li/dp_li.c
Normal file
90
dp/wifi3.0/li/dp_li.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
|
||||
#include "dp_types.h"
|
||||
#include "dp_li.h"
|
||||
#include "dp_li_tx.h"
|
||||
#include "dp_li_rx.h"
|
||||
|
||||
qdf_size_t dp_get_context_size_li(enum dp_context_type context_type)
|
||||
{
|
||||
switch (context_type) {
|
||||
case DP_CONTEXT_TYPE_SOC:
|
||||
return sizeof(struct dp_soc_li);
|
||||
case DP_CONTEXT_TYPE_PDEV:
|
||||
return sizeof(struct dp_pdev_li);
|
||||
case DP_CONTEXT_TYPE_VDEV:
|
||||
return sizeof(struct dp_vdev_li);
|
||||
case DP_CONTEXT_TYPE_PEER:
|
||||
return sizeof(struct dp_peer_li);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static QDF_STATUS dp_soc_attach_li(struct dp_soc *soc)
|
||||
{
|
||||
soc->wbm_sw0_bm_id = hal_tx_get_wbm_sw0_bm_id();
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS dp_soc_detach_li(struct dp_soc *soc)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS dp_pdev_attach_li(struct dp_pdev *pdev)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS dp_pdev_detach_li(struct dp_pdev *pdev)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS dp_vdev_attach_li(struct dp_soc *soc, struct dp_vdev *vdev)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static QDF_STATUS dp_vdev_detach_li(struct dp_soc *soc, struct dp_vdev *vdev)
|
||||
{
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
qdf_size_t dp_get_soc_context_size_li(void)
|
||||
{
|
||||
return sizeof(struct dp_soc);
|
||||
}
|
||||
|
||||
void dp_initialize_arch_ops_li(struct dp_arch_ops *arch_ops)
|
||||
{
|
||||
arch_ops->tx_hw_enqueue = dp_tx_hw_enqueue_li;
|
||||
arch_ops->txrx_get_context_size = dp_get_context_size_li;
|
||||
arch_ops->txrx_soc_attach = dp_soc_attach_li;
|
||||
arch_ops->txrx_soc_detach = dp_soc_detach_li;
|
||||
arch_ops->txrx_pdev_attach = dp_pdev_attach_li;
|
||||
arch_ops->txrx_pdev_detach = dp_pdev_detach_li;
|
||||
arch_ops->txrx_vdev_attach = dp_vdev_attach_li;
|
||||
arch_ops->txrx_vdev_detach = dp_vdev_detach_li;
|
||||
arch_ops->tx_comp_get_params_from_hal_desc =
|
||||
dp_tx_comp_get_params_from_hal_desc_li;
|
||||
arch_ops->dp_rx_process = dp_rx_process_li;
|
||||
}
|
81
dp/wifi3.0/li/dp_li.h
Normal file
81
dp/wifi3.0/li/dp_li.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2021 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.
|
||||
*/
|
||||
#ifndef __DP_LI_H
|
||||
#define __DP_LI_H
|
||||
|
||||
#include <dp_types.h>
|
||||
#include <hal_li_tx.h>
|
||||
|
||||
/**
|
||||
* struct dp_soc_li - Extended DP soc for LI targets
|
||||
* @soc: dp soc structure
|
||||
*/
|
||||
struct dp_soc_li {
|
||||
struct dp_soc soc;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dp_pdev_li - Extended DP pdev for LI targets
|
||||
* @pdev: dp_pdev structure
|
||||
*/
|
||||
struct dp_pdev_li {
|
||||
struct dp_pdev pdev;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dp_vdev_li - Extended DP vdev for LI targets
|
||||
* @vdev: dp_vdev structure
|
||||
*/
|
||||
struct dp_vdev_li {
|
||||
struct dp_vdev vdev;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dp_peer_li - Extended DP peer for LI targets
|
||||
* @peer: dp_peer structure
|
||||
*/
|
||||
struct dp_peer_li {
|
||||
struct dp_peer peer;
|
||||
};
|
||||
|
||||
/**
|
||||
* dp_get_soc_context_size_LI() - get context size for dp_soc_li
|
||||
*
|
||||
* Return: value in bytes for LI specific soc structure
|
||||
*/
|
||||
|
||||
qdf_size_t dp_get_soc_context_size_li(void);
|
||||
|
||||
/**
|
||||
* dp_initialize_arch_ops_li() - initialize LI specific arch ops
|
||||
* @arch_ops: arch ops pointer
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void dp_initialize_arch_ops_li(struct dp_arch_ops *arch_ops);
|
||||
|
||||
/**
|
||||
* dp_get_context_size_li() - get LI specific size for peer/vdev/pdev/soc
|
||||
* @arch_ops: arch ops pointer
|
||||
*
|
||||
* Return: size in bytes for the context_type
|
||||
*/
|
||||
|
||||
qdf_size_t dp_get_context_size_li(enum dp_context_type context_type);
|
||||
|
||||
#endif
|
192
dp/wifi3.0/li/dp_li_tx.c
Normal file
192
dp/wifi3.0/li/dp_li_tx.c
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2021 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.
|
||||
*/
|
||||
#include "cdp_txrx_cmn_struct.h"
|
||||
#include "dp_types.h"
|
||||
#include "dp_tx.h"
|
||||
#include "dp_li_tx.h"
|
||||
#include "dp_tx_desc.h"
|
||||
#include <hal_li_api.h>
|
||||
#include <hal_li_tx.h>
|
||||
|
||||
/*mapping between hal encrypt type and cdp_sec_type*/
|
||||
#define MAX_CDP_SEC_TYPE 12
|
||||
uint8_t sec_type_map[MAX_CDP_SEC_TYPE] = {HAL_TX_ENCRYPT_TYPE_NO_CIPHER,
|
||||
HAL_TX_ENCRYPT_TYPE_WEP_128,
|
||||
HAL_TX_ENCRYPT_TYPE_WEP_104,
|
||||
HAL_TX_ENCRYPT_TYPE_WEP_40,
|
||||
HAL_TX_ENCRYPT_TYPE_TKIP_WITH_MIC,
|
||||
HAL_TX_ENCRYPT_TYPE_TKIP_NO_MIC,
|
||||
HAL_TX_ENCRYPT_TYPE_AES_CCMP_128,
|
||||
HAL_TX_ENCRYPT_TYPE_WAPI,
|
||||
HAL_TX_ENCRYPT_TYPE_AES_CCMP_256,
|
||||
HAL_TX_ENCRYPT_TYPE_AES_GCMP_128,
|
||||
HAL_TX_ENCRYPT_TYPE_AES_GCMP_256,
|
||||
HAL_TX_ENCRYPT_TYPE_WAPI_GCM_SM4};
|
||||
|
||||
void dp_tx_comp_get_params_from_hal_desc_li(struct dp_soc *soc,
|
||||
void *tx_comp_hal_desc,
|
||||
struct dp_tx_desc_s **r_tx_desc)
|
||||
{
|
||||
uint8_t pool_id;
|
||||
uint32_t tx_desc_id;
|
||||
|
||||
tx_desc_id = hal_tx_comp_get_desc_id(tx_comp_hal_desc);
|
||||
pool_id = (tx_desc_id & DP_TX_DESC_ID_POOL_MASK) >>
|
||||
DP_TX_DESC_ID_POOL_OS;
|
||||
|
||||
/* Find Tx descriptor */
|
||||
*r_tx_desc = dp_tx_desc_find(soc, pool_id,
|
||||
(tx_desc_id & DP_TX_DESC_ID_PAGE_MASK) >>
|
||||
DP_TX_DESC_ID_PAGE_OS,
|
||||
(tx_desc_id & DP_TX_DESC_ID_OFFSET_MASK) >>
|
||||
DP_TX_DESC_ID_OFFSET_OS);
|
||||
/* Pool id is not matching. Error */
|
||||
if ((*r_tx_desc)->pool_id != pool_id) {
|
||||
dp_tx_comp_alert("Tx Comp pool id %d not matched %d",
|
||||
pool_id, (*r_tx_desc)->pool_id);
|
||||
|
||||
qdf_assert_always(0);
|
||||
}
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
dp_tx_hw_enqueue_li(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
struct dp_tx_desc_s *tx_desc, uint16_t fw_metadata,
|
||||
struct cdp_tx_exception_metadata *tx_exc_metadata,
|
||||
struct dp_tx_msdu_info_s *msdu_info)
|
||||
{
|
||||
void *hal_tx_desc;
|
||||
uint32_t *hal_tx_desc_cached;
|
||||
int coalesce = 0;
|
||||
struct dp_tx_queue *tx_q = &msdu_info->tx_queue;
|
||||
uint8_t ring_id = tx_q->ring_id & DP_TX_QUEUE_MASK;
|
||||
uint8_t tid = msdu_info->tid;
|
||||
|
||||
/*
|
||||
* Setting it initialization statically here to avoid
|
||||
* a memset call jump with qdf_mem_set call
|
||||
*/
|
||||
uint8_t cached_desc[HAL_TX_DESC_LEN_BYTES] = { 0 };
|
||||
|
||||
enum cdp_sec_type sec_type = ((tx_exc_metadata &&
|
||||
tx_exc_metadata->sec_type != CDP_INVALID_SEC_TYPE) ?
|
||||
tx_exc_metadata->sec_type : vdev->sec_type);
|
||||
|
||||
/* Return Buffer Manager ID */
|
||||
uint8_t bm_id = dp_tx_get_rbm_id(soc, ring_id);
|
||||
|
||||
hal_ring_handle_t hal_ring_hdl = NULL;
|
||||
|
||||
QDF_STATUS status = QDF_STATUS_E_RESOURCES;
|
||||
|
||||
if (!dp_tx_is_desc_id_valid(soc, tx_desc->id)) {
|
||||
dp_err_rl("Invalid tx desc id:%d", tx_desc->id);
|
||||
return QDF_STATUS_E_RESOURCES;
|
||||
}
|
||||
|
||||
hal_tx_desc_cached = (void *)cached_desc;
|
||||
|
||||
hal_tx_desc_set_buf_addr(soc->hal_soc, hal_tx_desc_cached,
|
||||
tx_desc->dma_addr, bm_id, tx_desc->id,
|
||||
(tx_desc->flags & DP_TX_DESC_FLAG_FRAG));
|
||||
hal_tx_desc_set_lmac_id(soc->hal_soc, hal_tx_desc_cached,
|
||||
vdev->lmac_id);
|
||||
hal_tx_desc_set_search_type(soc->hal_soc, hal_tx_desc_cached,
|
||||
vdev->search_type);
|
||||
hal_tx_desc_set_search_index(soc->hal_soc, hal_tx_desc_cached,
|
||||
vdev->bss_ast_idx);
|
||||
hal_tx_desc_set_dscp_tid_table_id(soc->hal_soc, hal_tx_desc_cached,
|
||||
vdev->dscp_tid_map_id);
|
||||
|
||||
hal_tx_desc_set_encrypt_type(hal_tx_desc_cached,
|
||||
sec_type_map[sec_type]);
|
||||
hal_tx_desc_set_cache_set_num(soc->hal_soc, hal_tx_desc_cached,
|
||||
(vdev->bss_ast_hash & 0xF));
|
||||
|
||||
hal_tx_desc_set_fw_metadata(hal_tx_desc_cached, fw_metadata);
|
||||
hal_tx_desc_set_buf_length(hal_tx_desc_cached, tx_desc->length);
|
||||
hal_tx_desc_set_buf_offset(hal_tx_desc_cached, tx_desc->pkt_offset);
|
||||
hal_tx_desc_set_encap_type(hal_tx_desc_cached, tx_desc->tx_encap_type);
|
||||
hal_tx_desc_set_addr_search_flags(hal_tx_desc_cached,
|
||||
vdev->hal_desc_addr_search_flags);
|
||||
|
||||
if (tx_desc->flags & DP_TX_DESC_FLAG_TO_FW)
|
||||
hal_tx_desc_set_to_fw(hal_tx_desc_cached, 1);
|
||||
|
||||
/* verify checksum offload configuration*/
|
||||
if (vdev->csum_enabled &&
|
||||
((qdf_nbuf_get_tx_cksum(tx_desc->nbuf) ==
|
||||
QDF_NBUF_TX_CKSUM_TCP_UDP) ||
|
||||
qdf_nbuf_is_tso(tx_desc->nbuf))) {
|
||||
hal_tx_desc_set_l3_checksum_en(hal_tx_desc_cached, 1);
|
||||
hal_tx_desc_set_l4_checksum_en(hal_tx_desc_cached, 1);
|
||||
}
|
||||
|
||||
if (tid != HTT_TX_EXT_TID_INVALID)
|
||||
hal_tx_desc_set_hlos_tid(hal_tx_desc_cached, tid);
|
||||
|
||||
if (tx_desc->flags & DP_TX_DESC_FLAG_MESH)
|
||||
hal_tx_desc_set_mesh_en(soc->hal_soc, hal_tx_desc_cached, 1);
|
||||
|
||||
if (qdf_unlikely(vdev->pdev->delay_stats_flag) ||
|
||||
qdf_unlikely(wlan_cfg_is_peer_ext_stats_enabled(soc->wlan_cfg_ctx)))
|
||||
tx_desc->timestamp = qdf_ktime_to_ms(qdf_ktime_real_get());
|
||||
|
||||
dp_verbose_debug("length:%d , type = %d, dma_addr %llx, offset %d desc id %u",
|
||||
tx_desc->length,
|
||||
(tx_desc->flags & DP_TX_DESC_FLAG_FRAG),
|
||||
(uint64_t)tx_desc->dma_addr, tx_desc->pkt_offset,
|
||||
tx_desc->id);
|
||||
|
||||
hal_ring_hdl = dp_tx_get_hal_ring_hdl(soc, ring_id);
|
||||
|
||||
if (qdf_unlikely(dp_tx_hal_ring_access_start(soc, hal_ring_hdl))) {
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s %d : HAL RING Access Failed -- %pK",
|
||||
__func__, __LINE__, hal_ring_hdl);
|
||||
DP_STATS_INC(soc, tx.tcl_ring_full[ring_id], 1);
|
||||
DP_STATS_INC(vdev, tx_i.dropped.enqueue_fail, 1);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Sync cached descriptor with HW */
|
||||
|
||||
hal_tx_desc = hal_srng_src_get_next(soc->hal_soc, hal_ring_hdl);
|
||||
if (qdf_unlikely(!hal_tx_desc)) {
|
||||
dp_verbose_debug("TCL ring full ring_id:%d", ring_id);
|
||||
DP_STATS_INC(soc, tx.tcl_ring_full[ring_id], 1);
|
||||
DP_STATS_INC(vdev, tx_i.dropped.enqueue_fail, 1);
|
||||
goto ring_access_fail;
|
||||
}
|
||||
|
||||
tx_desc->flags |= DP_TX_DESC_FLAG_QUEUED_TX;
|
||||
dp_vdev_peer_stats_update_protocol_cnt_tx(vdev, tx_desc->nbuf);
|
||||
hal_tx_desc_sync(hal_tx_desc_cached, hal_tx_desc);
|
||||
coalesce = dp_tx_attempt_coalescing(soc, vdev, tx_desc, tid);
|
||||
DP_STATS_INC_PKT(vdev, tx_i.processed, 1, tx_desc->length);
|
||||
dp_tx_update_stats(soc, tx_desc->nbuf);
|
||||
status = QDF_STATUS_SUCCESS;
|
||||
|
||||
dp_tx_hw_desc_update_evt((uint8_t *)hal_tx_desc_cached,
|
||||
hal_ring_hdl, soc);
|
||||
|
||||
ring_access_fail:
|
||||
dp_tx_ring_access_end_wrapper(soc, hal_ring_hdl, coalesce);
|
||||
|
||||
return status;
|
||||
}
|
55
dp/wifi3.0/li/dp_li_tx.h
Normal file
55
dp/wifi3.0/li/dp_li_tx.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2021 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.
|
||||
*/
|
||||
#ifndef __DP_LI_TX_H
|
||||
#define __DP_LI_TX_H
|
||||
|
||||
#include <dp_types.h>
|
||||
|
||||
/**
|
||||
* dp_tx_hw_enqueue_li() - Enqueue to TCL HW for transmit
|
||||
* @soc: DP Soc Handle
|
||||
* @vdev: DP vdev handle
|
||||
* @tx_desc: Tx Descriptor Handle
|
||||
* @tid: TID from HLOS for overriding default DSCP-TID mapping
|
||||
* @fw_metadata: Metadata to send to Target Firmware along with frame
|
||||
* @ring_id: Ring ID of H/W ring to which we enqueue the packet
|
||||
* @tx_exc_metadata: Handle that holds exception path meta data
|
||||
*
|
||||
* Gets the next free TCL HW DMA descriptor and sets up required parameters
|
||||
* from software Tx descriptor
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS: success
|
||||
* QDF_STATUS_E_RESOURCES: Error return
|
||||
*/
|
||||
QDF_STATUS
|
||||
dp_tx_hw_enqueue_li(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||
struct dp_tx_desc_s *tx_desc, uint16_t fw_metadata,
|
||||
struct cdp_tx_exception_metadata *tx_exc_metadata,
|
||||
struct dp_tx_msdu_info_s *msdu_info);
|
||||
/**
|
||||
* dp_tx_comp_get_params_from_hal_desc_li() - Get TX desc from HAL comp desc
|
||||
* @soc: DP soc handle
|
||||
* @tx_comp_hal_desc: HAL TX Comp Descriptor
|
||||
* @r_tx_desc: SW Tx Descriptor retrieved from HAL desc.
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void dp_tx_comp_get_params_from_hal_desc_li(struct dp_soc *soc,
|
||||
void *tx_comp_hal_desc,
|
||||
struct dp_tx_desc_s **r_tx_desc);
|
||||
#endif
|
Reference in New Issue
Block a user