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 */
|
#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
|
static inline
|
||||||
ol_txrx_soc_handle cdp_soc_attach(u_int16_t devid,
|
ol_txrx_soc_handle cdp_soc_attach(u_int16_t devid,
|
||||||
struct hif_opaque_softc *hif_handle,
|
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_egress,
|
||||||
bool is_rx);
|
bool is_rx);
|
||||||
|
|
||||||
|
void dp_vdev_peer_stats_update_protocol_cnt_tx(struct dp_vdev *vdev_hdl,
|
||||||
|
qdf_nbuf_t nbuf);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define dp_vdev_peer_stats_update_protocol_cnt(vdev, nbuf, peer, \
|
#define dp_vdev_peer_stats_update_protocol_cnt(vdev, nbuf, peer, \
|
||||||
is_egress, is_rx)
|
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
|
#endif
|
||||||
|
|
||||||
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
|
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
|
||||||
|
@@ -54,6 +54,7 @@
|
|||||||
#include "qdf_mem.h" /* qdf_mem_malloc,free */
|
#include "qdf_mem.h" /* qdf_mem_malloc,free */
|
||||||
#include "cfg_ucfg_api.h"
|
#include "cfg_ucfg_api.h"
|
||||||
#include "dp_mon_filter.h"
|
#include "dp_mon_filter.h"
|
||||||
|
|
||||||
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
|
#ifdef QCA_LL_TX_FLOW_CONTROL_V2
|
||||||
#include "cdp_txrx_flow_ctrl_v2.h"
|
#include "cdp_txrx_flow_ctrl_v2.h"
|
||||||
#else
|
#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)
|
__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)
|
#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.
|
* The max size of cdp_peer_stats_param_t is limited to 16 bytes.
|
||||||
* If the buffer size is exceeding this size limit,
|
* 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;
|
struct dp_soc *soc = (struct dp_soc *)txrx_soc;
|
||||||
|
|
||||||
|
soc->arch_ops.txrx_soc_detach(soc);
|
||||||
|
|
||||||
dp_soc_swlm_detach(soc);
|
dp_soc_swlm_detach(soc);
|
||||||
dp_soc_tx_desc_sw_pools_free(soc);
|
dp_soc_tx_desc_sw_pools_free(soc);
|
||||||
dp_soc_srng_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_mode op_mode,
|
||||||
enum wlan_op_subtype subtype)
|
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_soc *soc = (struct dp_soc *)cdp_soc;
|
||||||
struct dp_pdev *pdev =
|
struct dp_pdev *pdev =
|
||||||
dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
|
dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
|
||||||
pdev_id);
|
pdev_id);
|
||||||
struct dp_vdev *vdev = qdf_mem_malloc(sizeof(*vdev));
|
struct dp_vdev *vdev;
|
||||||
int i = 0;
|
|
||||||
|
vdev_context_size =
|
||||||
|
soc->arch_ops.txrx_get_context_size(DP_CONTEXT_TYPE_VDEV);
|
||||||
|
vdev = qdf_mem_malloc(vdev_context_size);
|
||||||
|
|
||||||
if (!pdev) {
|
if (!pdev) {
|
||||||
dp_init_err("%pK: DP PDEV is Null for pdev id %d",
|
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));
|
QDF_MAC_ADDR_REF(vdev->mac_addr.raw));
|
||||||
DP_STATS_INIT(vdev);
|
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)
|
if (wlan_op_mode_sta == vdev->opmode)
|
||||||
dp_peer_create_wifi3((struct cdp_soc_t *)soc, vdev_id,
|
dp_peer_create_wifi3((struct cdp_soc_t *)soc, vdev_id,
|
||||||
vdev->mac_addr.raw);
|
vdev->mac_addr.raw);
|
||||||
@@ -6411,6 +6425,8 @@ static QDF_STATUS dp_vdev_detach_wifi3(struct cdp_soc_t *cdp_soc,
|
|||||||
if (!vdev)
|
if (!vdev)
|
||||||
return QDF_STATUS_E_FAILURE;
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
|
||||||
|
soc->arch_ops.txrx_vdev_detach(soc, vdev);
|
||||||
|
|
||||||
pdev = vdev->pdev;
|
pdev = vdev->pdev;
|
||||||
|
|
||||||
vap_self_peer = dp_sta_vdev_self_peer_ref_n_get(soc, vdev,
|
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;
|
goto fail0;
|
||||||
}
|
}
|
||||||
|
|
||||||
soc = qdf_mem_malloc(sizeof(*soc));
|
soc = qdf_mem_malloc(dp_get_soc_context_size(device_id));
|
||||||
if (!soc) {
|
if (!soc) {
|
||||||
dp_err("DP SOC memory allocation failed");
|
dp_err("DP SOC memory allocation failed");
|
||||||
goto fail0;
|
goto fail0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dp_info("soc memory allocated %pk", soc);
|
||||||
soc->hif_handle = hif_handle;
|
soc->hif_handle = hif_handle;
|
||||||
soc->hal_soc = hif_get_hal_handle(soc->hif_handle);
|
soc->hal_soc = hif_get_hal_handle(soc->hif_handle);
|
||||||
if (!soc->hal_soc)
|
if (!soc->hal_soc)
|
||||||
@@ -12890,6 +12907,8 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
|
|||||||
soc->osdev = qdf_osdev;
|
soc->osdev = qdf_osdev;
|
||||||
soc->num_hw_dscp_tid_map = HAL_MAX_HW_DSCP_TID_MAPS;
|
soc->num_hw_dscp_tid_map = HAL_MAX_HW_DSCP_TID_MAPS;
|
||||||
|
|
||||||
|
dp_configure_arch_ops(soc);
|
||||||
|
|
||||||
/* Reset wbm sg list and flags */
|
/* Reset wbm sg list and flags */
|
||||||
dp_rx_wbm_sg_list_reset(soc);
|
dp_rx_wbm_sg_list_reset(soc);
|
||||||
|
|
||||||
@@ -12925,6 +12944,11 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
|
|||||||
goto fail5;
|
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_swlm_attach(soc);
|
||||||
dp_soc_set_interrupt_mode(soc);
|
dp_soc_set_interrupt_mode(soc);
|
||||||
dp_soc_set_def_pdev(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());
|
qdf_skb_total_mem_stats_read());
|
||||||
|
|
||||||
return soc;
|
return soc;
|
||||||
|
fail6:
|
||||||
|
dp_soc_tx_desc_sw_pools_free(soc);
|
||||||
fail5:
|
fail5:
|
||||||
dp_soc_srng_free(soc);
|
dp_soc_srng_free(soc);
|
||||||
fail4:
|
fail4:
|
||||||
|
@@ -58,22 +58,6 @@
|
|||||||
/* invalid peer id for reinject*/
|
/* invalid peer id for reinject*/
|
||||||
#define DP_INVALID_PEER 0XFFFE
|
#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
|
#ifdef CONFIG_WLAN_SYSFS_MEM_STATS
|
||||||
/**
|
/**
|
||||||
* dp_update_tx_desc_stats - Update the increase or decrease in
|
* 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);
|
qdf_atomic_dec(&soc->num_tx_exception);
|
||||||
|
|
||||||
if (HAL_TX_COMP_RELEASE_SOURCE_TQM ==
|
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,
|
comp_status = hal_tx_comp_get_release_reason(&tx_desc->comp,
|
||||||
soc->hal_soc);
|
soc->hal_soc);
|
||||||
else
|
else
|
||||||
@@ -1326,28 +1310,28 @@ static void dp_tx_raw_prepare_unset(struct dp_soc *soc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VDEV_PEER_PROTOCOL_COUNT
|
#ifdef VDEV_PEER_PROTOCOL_COUNT
|
||||||
#define dp_vdev_peer_stats_update_protocol_cnt_tx(vdev_hdl, nbuf) \
|
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; \
|
qdf_nbuf_t nbuf_local;
|
||||||
do { \
|
struct dp_vdev *vdev_local = vdev_hdl;
|
||||||
if (qdf_likely(!((vdev_local)->peer_protocol_count_track))) \
|
|
||||||
break; \
|
do {
|
||||||
nbuf_local = nbuf; \
|
if (qdf_likely(!((vdev_local)->peer_protocol_count_track)))
|
||||||
if (qdf_unlikely(((vdev_local)->tx_encap_type) == \
|
break;
|
||||||
htt_cmn_pkt_type_raw)) \
|
nbuf_local = nbuf;
|
||||||
break; \
|
if (qdf_unlikely(((vdev_local)->tx_encap_type) ==
|
||||||
else if (qdf_unlikely(qdf_nbuf_is_nonlinear((nbuf_local)))) \
|
htt_cmn_pkt_type_raw))
|
||||||
break; \
|
break;
|
||||||
else if (qdf_nbuf_is_tso((nbuf_local))) \
|
else if (qdf_unlikely(qdf_nbuf_is_nonlinear((nbuf_local))))
|
||||||
break; \
|
break;
|
||||||
dp_vdev_peer_stats_update_protocol_cnt((vdev_local), \
|
else if (qdf_nbuf_is_tso((nbuf_local)))
|
||||||
(nbuf_local), \
|
break;
|
||||||
NULL, 1, 0); \
|
dp_vdev_peer_stats_update_protocol_cnt((vdev_local),
|
||||||
} while (0); \
|
(nbuf_local),
|
||||||
|
NULL, 1, 0);
|
||||||
|
} while (0);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
#define dp_vdev_peer_stats_update_protocol_cnt_tx(vdev_hdl, skb)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR
|
#ifdef WLAN_DP_FEATURE_SW_LATENCY_MGR
|
||||||
@@ -1358,22 +1342,13 @@ static void dp_tx_raw_prepare_unset(struct dp_soc *soc,
|
|||||||
*
|
*
|
||||||
* Returns: none
|
* Returns: none
|
||||||
*/
|
*/
|
||||||
static inline void dp_tx_update_stats(struct dp_soc *soc,
|
void dp_tx_update_stats(struct dp_soc *soc,
|
||||||
qdf_nbuf_t nbuf)
|
qdf_nbuf_t nbuf)
|
||||||
{
|
{
|
||||||
DP_STATS_INC_PKT(soc, tx.egress, 1, qdf_nbuf_len(nbuf));
|
DP_STATS_INC_PKT(soc, tx.egress, 1, qdf_nbuf_len(nbuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
int
|
||||||
* 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
|
|
||||||
dp_tx_attempt_coalescing(struct dp_soc *soc, struct dp_vdev *vdev,
|
dp_tx_attempt_coalescing(struct dp_soc *soc, struct dp_vdev *vdev,
|
||||||
struct dp_tx_desc_s *tx_desc,
|
struct dp_tx_desc_s *tx_desc,
|
||||||
uint8_t tid)
|
uint8_t tid)
|
||||||
@@ -1409,15 +1384,7 @@ dp_tx_attempt_coalescing(struct dp_soc *soc, struct dp_vdev *vdev,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void
|
||||||
* 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
|
|
||||||
dp_tx_ring_access_end(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl,
|
dp_tx_ring_access_end(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl,
|
||||||
int coalesce)
|
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);
|
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
|
#endif
|
||||||
|
|
||||||
#ifdef FEATURE_RUNTIME_PM
|
#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
|
* Returns: none
|
||||||
*/
|
*/
|
||||||
static inline void
|
void
|
||||||
dp_tx_ring_access_end_wrapper(struct dp_soc *soc,
|
dp_tx_ring_access_end_wrapper(struct dp_soc *soc,
|
||||||
hal_ring_handle_t hal_ring_hdl,
|
hal_ring_handle_t hal_ring_hdl,
|
||||||
int coalesce)
|
int coalesce)
|
||||||
@@ -1504,191 +1451,8 @@ dp_tx_ring_access_end_wrapper(struct dp_soc *soc,
|
|||||||
dp_runtime_put(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
|
#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
|
* dp_cce_classify() - Classify the frame based on CCE rules
|
||||||
* @vdev: DP vdev handle
|
* @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,
|
dp_tx_desc_history_add(soc, tx_desc->dma_addr, nbuf,
|
||||||
tx_desc->id, DP_TX_DESC_MAP);
|
tx_desc->id, DP_TX_DESC_MAP);
|
||||||
/* Enqueue the Tx MSDU descriptor to HW for transmit */
|
/* Enqueue the Tx MSDU descriptor to HW for transmit */
|
||||||
status = dp_tx_hw_enqueue(soc, vdev, tx_desc, htt_tcl_metadata,
|
status = soc->arch_ops.tx_hw_enqueue(soc, vdev, tx_desc,
|
||||||
tx_exc_metadata, msdu_info);
|
htt_tcl_metadata,
|
||||||
|
tx_exc_metadata, msdu_info);
|
||||||
|
|
||||||
if (status != QDF_STATUS_SUCCESS) {
|
if (status != QDF_STATUS_SUCCESS) {
|
||||||
dp_tx_err_rl("Tx_hw_enqueue Fail tx_desc %pK queue %d",
|
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
|
* Enqueue the Tx MSDU descriptor to HW for transmit
|
||||||
*/
|
*/
|
||||||
status = dp_tx_hw_enqueue(soc, vdev, tx_desc, htt_tcl_metadata,
|
status = soc->arch_ops.tx_hw_enqueue(soc, vdev, tx_desc,
|
||||||
NULL, msdu_info);
|
htt_tcl_metadata,
|
||||||
|
NULL, msdu_info);
|
||||||
|
|
||||||
if (status != QDF_STATUS_SUCCESS) {
|
if (status != QDF_STATUS_SUCCESS) {
|
||||||
dp_info("Tx_hw_enqueue Fail tx_desc %pK queue %d",
|
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;
|
void *tx_comp_hal_desc;
|
||||||
uint8_t buffer_src;
|
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 *tx_desc = NULL;
|
||||||
struct dp_tx_desc_s *head_desc = NULL;
|
struct dp_tx_desc_s *head_desc = NULL;
|
||||||
struct dp_tx_desc_s *tail_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);
|
tx_comp_hal_desc = dp_srng_dst_get_next(soc, hal_ring_hdl);
|
||||||
if (qdf_unlikely(!tx_comp_hal_desc))
|
if (qdf_unlikely(!tx_comp_hal_desc))
|
||||||
break;
|
break;
|
||||||
|
buffer_src = hal_tx_comp_get_buffer_source(soc->hal_soc,
|
||||||
buffer_src = hal_tx_comp_get_buffer_source(tx_comp_hal_desc);
|
tx_comp_hal_desc);
|
||||||
|
|
||||||
/* If this buffer was not released by TQM or FW, then it is not
|
/* If this buffer was not released by TQM or FW, then it is not
|
||||||
* Tx completion indication, assert */
|
* Tx completion indication, assert */
|
||||||
@@ -4710,18 +4474,15 @@ more_data:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get descriptor id */
|
soc->arch_ops.tx_comp_get_params_from_hal_desc(soc,
|
||||||
tx_desc_id = hal_tx_comp_get_desc_id(tx_comp_hal_desc);
|
tx_comp_hal_desc,
|
||||||
pool_id = (tx_desc_id & DP_TX_DESC_ID_POOL_MASK) >>
|
&tx_desc);
|
||||||
DP_TX_DESC_ID_POOL_OS;
|
if (!tx_desc) {
|
||||||
|
dp_err("unable to retrieve tx_desc!");
|
||||||
/* Find Tx descriptor */
|
QDF_BUG(0);
|
||||||
tx_desc = dp_tx_desc_find(soc, pool_id,
|
continue;
|
||||||
(tx_desc_id & DP_TX_DESC_ID_PAGE_MASK) >>
|
}
|
||||||
DP_TX_DESC_ID_PAGE_OS,
|
tx_desc->buffer_src = buffer_src;
|
||||||
(tx_desc_id & DP_TX_DESC_ID_OFFSET_MASK) >>
|
|
||||||
DP_TX_DESC_ID_OFFSET_OS);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the release source is FW, process the HTT status
|
* 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);
|
hal_tx_comp_get_peer_id(tx_comp_hal_desc);
|
||||||
tx_desc->tx_status =
|
tx_desc->tx_status =
|
||||||
hal_tx_comp_get_tx_status(tx_comp_hal_desc);
|
hal_tx_comp_get_tx_status(tx_comp_hal_desc);
|
||||||
|
tx_desc->buffer_src = buffer_src;
|
||||||
/*
|
/*
|
||||||
* If the fast completion mode is enabled extended
|
* If the fast completion mode is enabled extended
|
||||||
* metadata from descriptor is not copied
|
* metadata from descriptor is not copied
|
||||||
@@ -4753,31 +4515,23 @@ more_data:
|
|||||||
((tx_desc->vdev_id == DP_INVALID_VDEV_ID) &&
|
((tx_desc->vdev_id == DP_INVALID_VDEV_ID) &&
|
||||||
!tx_desc->flags)) {
|
!tx_desc->flags)) {
|
||||||
dp_tx_comp_info_rl("Descriptor freed in vdev_detach %d",
|
dp_tx_comp_info_rl("Descriptor freed in vdev_detach %d",
|
||||||
tx_desc_id);
|
tx_desc->id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qdf_unlikely(tx_desc->pdev->is_pdev_down)) {
|
if (qdf_unlikely(tx_desc->pdev->is_pdev_down)) {
|
||||||
dp_tx_comp_info_rl("pdev in down state %d",
|
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;
|
tx_desc->flags |= DP_TX_DESC_FLAG_TX_COMP_ERR;
|
||||||
dp_tx_comp_free_buf(soc, tx_desc);
|
dp_tx_comp_free_buf(soc, tx_desc);
|
||||||
dp_tx_desc_release(tx_desc, tx_desc->pool_id);
|
dp_tx_desc_release(tx_desc, tx_desc->pool_id);
|
||||||
goto next_desc;
|
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) ||
|
if (!(tx_desc->flags & DP_TX_DESC_FLAG_ALLOCATED) ||
|
||||||
!(tx_desc->flags & DP_TX_DESC_FLAG_QUEUED_TX)) {
|
!(tx_desc->flags & DP_TX_DESC_FLAG_QUEUED_TX)) {
|
||||||
dp_tx_comp_alert("Txdesc invalid, flgs = %x,id = %d",
|
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);
|
qdf_assert_always(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5502,3 +5256,4 @@ QDF_STATUS dp_tso_soc_detach(struct cdp_soc_t *txrx_soc)
|
|||||||
|
|
||||||
return QDF_STATUS_SUCCESS;
|
return QDF_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include "if_meta_hdr.h"
|
#include "if_meta_hdr.h"
|
||||||
#endif
|
#endif
|
||||||
#include "dp_internal.h"
|
#include "dp_internal.h"
|
||||||
|
#include "hal_tx.h"
|
||||||
|
|
||||||
#define DP_INVALID_VDEV_ID 0xFF
|
#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
|
* 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)
|
uint8_t ring_id)
|
||||||
{
|
{
|
||||||
return (ring_id ? HAL_WBM_SW0_BM_ID + (ring_id - 1) :
|
return (ring_id ? soc->wbm_sw0_bm_id + (ring_id - 1) :
|
||||||
HAL_WBM_SW2_BM_ID);
|
HAL_WBM_SW2_BM_ID(soc->wbm_sw0_bm_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* QCA_OL_TX_MULTIQ_SUPPORT */
|
#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,
|
static inline uint8_t dp_tx_get_rbm_id(struct dp_soc *soc,
|
||||||
uint8_t ring_id)
|
uint8_t ring_id)
|
||||||
{
|
{
|
||||||
return (ring_id + HAL_WBM_SW0_BM_ID);
|
return (ring_id + soc->wbm_sw0_bm_id);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -676,4 +677,113 @@ dp_send_completion_to_pkt_capture(struct dp_soc *soc,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
#endif
|
||||||
|
@@ -57,6 +57,7 @@
|
|||||||
#ifdef WLAN_TX_PKT_CAPTURE_ENH
|
#ifdef WLAN_TX_PKT_CAPTURE_ENH
|
||||||
#include "dp_tx_capture.h"
|
#include "dp_tx_capture.h"
|
||||||
#endif
|
#endif
|
||||||
|
//#include "dp_tx.h"
|
||||||
|
|
||||||
#define REPT_MU_MIMO 1
|
#define REPT_MU_MIMO 1
|
||||||
#define REPT_MU_OFDMA_MIMO 3
|
#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).
|
* @tx_encap_type: Transmit encap type (i.e. Raw, Native Wi-Fi, Ethernet).
|
||||||
* This is maintained in descriptor to allow more efficient
|
* This is maintained in descriptor to allow more efficient
|
||||||
* processing in completion event processing code.
|
* 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
|
* @frm_type: Frame Type - ToDo check if this is redundant
|
||||||
* @pkt_offset: Offset from which the actual packet data starts
|
* @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
|
* @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;
|
uint8_t tx_status;
|
||||||
uint16_t peer_id;
|
uint16_t peer_id;
|
||||||
struct dp_pdev *pdev;
|
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 frm_type;
|
||||||
uint8_t pkt_offset;
|
uint8_t pkt_offset;
|
||||||
uint8_t pool_id;
|
uint8_t pool_id;
|
||||||
@@ -1491,6 +1495,64 @@ struct ipa_dp_tx_rsc {
|
|||||||
};
|
};
|
||||||
#endif
|
#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 */
|
/* SOC level structure for data path */
|
||||||
struct dp_soc {
|
struct dp_soc {
|
||||||
/**
|
/**
|
||||||
@@ -1506,6 +1568,8 @@ struct dp_soc {
|
|||||||
/* OS device abstraction */
|
/* OS device abstraction */
|
||||||
qdf_device_t osdev;
|
qdf_device_t osdev;
|
||||||
|
|
||||||
|
struct dp_arch_ops arch_ops;
|
||||||
|
|
||||||
/*cce disable*/
|
/*cce disable*/
|
||||||
bool cce_disable;
|
bool cce_disable;
|
||||||
|
|
||||||
@@ -1939,6 +2003,8 @@ struct dp_soc {
|
|||||||
qdf_spinlock_t reo_desc_deferred_freelist_lock;
|
qdf_spinlock_t reo_desc_deferred_freelist_lock;
|
||||||
bool reo_desc_deferred_freelist_init;
|
bool reo_desc_deferred_freelist_init;
|
||||||
#endif
|
#endif
|
||||||
|
/* BM id for first WBM2SW ring */
|
||||||
|
uint32_t wbm_sw0_bm_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef IPA_OFFLOAD
|
#ifdef IPA_OFFLOAD
|
||||||
@@ -3358,6 +3424,8 @@ struct dp_req_rx_hw_stats_t {
|
|||||||
bool is_query_timeout;
|
bool is_query_timeout;
|
||||||
};
|
};
|
||||||
#endif
|
#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);
|
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,
|
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