qcacmn: Add Lithium DP Tx core functionality

Implement Lithium Core Tx Data Path, Tx HW descriptor processing
and Tx Completion Path (Processing of WBM Release Ring)

CRs-Fixed: 1073253
Change-Id: I11bebc49177398a157fcd161228859e2ef860402
This commit is contained in:
Pamidipati, Vijay
2016-09-27 20:58:18 +05:30
committed by qcabuildsw
parent 2658be83e4
commit 576bd154a2
5 changed files with 1844 additions and 8 deletions

View File

@@ -563,6 +563,7 @@ static int dp_soc_cmn_setup(struct dp_soc *soc)
}
soc->num_tcl_data_rings = 0;
/* Tx data rings */
if (!wlan_cfg_per_pdev_tx_ring(soc->wlan_cfg_ctx)) {
soc->num_tcl_data_rings =
@@ -590,6 +591,12 @@ static int dp_soc_cmn_setup(struct dp_soc *soc)
soc->num_tcl_data_rings = 0;
}
if (dp_tx_soc_attach(soc)) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"%s: dp_tx_soc_attach failed\n", __func__);
goto fail1;
}
/* TCL command and status rings */
if (dp_srng_setup(soc, &soc->tcl_cmd_ring, TCL_CMD, 0, 0,
TCL_CMD_RING_SIZE)) {
@@ -755,6 +762,13 @@ void *dp_pdev_attach_wifi3(void *txrx_soc, void *ctrl_pdev,
soc->num_tcl_data_rings++;
}
/* Tx specific init */
if (dp_tx_pdev_attach(pdev)) {
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"%s: dp_tx_pdev_attach failed\n", __func__);
goto fail0;
}
/* Setup per PDEV REO rings if configured */
if (wlan_cfg_per_pdev_rx_ring(soc->wlan_cfg_ctx)) {
if (dp_srng_setup(soc, &soc->reo_dest_ring[pdev_id], REO_DST,
@@ -1022,6 +1036,8 @@ void *dp_vdev_attach_wifi3(void *txrx_pdev,
TAILQ_INSERT_TAIL(&pdev->vdev_list, vdev, vdev_list_elem);
pdev->vdev_count++;
dp_tx_vdev_attach(vdev);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"Created vdev %p (%02x:%02x:%02x:%02x:%02x:%02x)\n", vdev,
vdev->mac_addr.raw[0], vdev->mac_addr.raw[1],
@@ -1107,6 +1123,7 @@ void dp_vdev_detach_wifi3(void *vdev_handle,
}
qdf_spin_unlock_bh(&soc->peer_ref_mutex);
dp_tx_vdev_detach(vdev);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_HIGH,
"%s: deleting vdev object %p (%02x:%02x:%02x:%02x:%02x:%02x)\n",
__func__, vdev,

1441
dp/wifi3.0/dp_tx.c Normal file

File diff suppressed because it is too large Load Diff

200
dp/wifi3.0/dp_tx.h Normal file
View File

@@ -0,0 +1,200 @@
/*
* Copyright (c) 2016 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_TX_H
#define __DP_TX_H
#include <qdf_types.h>
#include <qdf_nbuf.h>
#include <dp_types.h>
#define DP_STATS_ADD(x, y, z)
#define DP_STATS_SUB(x, y, z)
#define DP_STATS_MSDU_INCR(x, y, z)
#define DP_TX_MAX_NUM_FRAGS 6
#define DP_TX_DESC_FLAG_ALLOCATED 0x1
#define DP_TX_DESC_FLAG_TO_FW 0x2
#define DP_TX_DESC_FLAG_FRAG 0x4
#define DP_TX_DESC_FLAG_RAW 0x8
#define DP_TX_DESC_FLAG_MESH 0x10
#define DP_TX_DESC_FLAG_QUEUED_TX 0x20
#define DP_TX_DESC_FLAG_COMPLETED_TX 0x40
#define DP_TX_FREE_SINGLE_BUF(soc, vdev, buf) \
do { \
qdf_nbuf_unmap(soc->osdev, buf, QDF_DMA_FROM_DEVICE); \
qdf_nbuf_free(buf); \
} while (0)
#define OCB_HEADER_VERSION 1
/**
* struct dp_tx_frag_info_s
* @vaddr: hlos vritual address for buffer
* @paddr_lo: physical address lower 32bits
* @paddr_hi: physical address higher bits
* @len: length of the buffer
*/
struct dp_tx_frag_info_s {
uint8_t *vaddr;
uint32_t paddr_lo;
uint16_t paddr_hi;
uint16_t len;
};
/**
* struct dp_tx_seg_info_s - Segmentation Descriptor
* @nbuf: NBUF pointer if segment corresponds to separate nbuf
* @frag_cnt: Fragment count in this segment
* @total_len: Total length of segment
* @frags: per-Fragment information
* @next: pointer to next MSDU segment
*/
struct dp_tx_seg_info_s {
qdf_nbuf_t nbuf;
uint16_t frag_cnt;
uint16_t total_len;
struct dp_tx_frag_info_s frags[DP_TX_MAX_NUM_FRAGS];
struct dp_tx_seg_info_s *next;
};
/**
* struct dp_tx_sg_info_s - Scatter Gather Descriptor
* @num_segs: Number of segments (TSO/ME) in the frame
* @total_len: Total length of the frame
* @curr_seg: Points to current segment descriptor to be processed. Chain of
* descriptors for SG frames/multicast-unicast converted packets.
*
* Used for SG (802.3 or Raw) frames and Multicast-Unicast converted frames to
* carry fragmentation information
* Raw Frames will be handed over to driver as an SKB chain with MPDU boundaries
* indicated through flags in SKB CB (first_msdu and last_msdu). This will be
* converted into set of skb sg (nr_frags) structures.
*/
struct dp_tx_sg_info_s {
uint32_t num_segs;
uint32_t total_len;
struct dp_tx_seg_info_s *curr_seg;
};
/**
* struct dp_tx_queue - Tx queue
* @desc_pool_id: Descriptor Pool to be used for the tx queue
* @ring_id: TCL descriptor ring ID corresponding to the tx queue
*
* Tx queue contains information of the software (Descriptor pool)
* and hardware resources (TCL ring id) to be used for a particular
* transmit queue (obtained from skb_queue_mapping in case of linux)
*/
struct dp_tx_queue {
uint8_t desc_pool_id;
uint8_t ring_id;
};
/**
* struct dp_tx_msdu_info_s - MSDU Descriptor
* @frm_type: Frame type - Regular/TSO/SG/Multicast enhancement
* @tx_queue: Tx queue on which this MSDU should be transmitted
* @num_seg: Number of segments (TSO)
* @tid: TID (override) that is sent from HLOS
* @u.tso_info: TSO information for TSO frame types
* (chain of the TSO segments, number of segments)
* @u.sg_info: Scatter Gather information for non-TSO SG frames
*
* This structure holds the complete MSDU information needed to program the
* Hardware TCL and MSDU extension descriptors for different frame types
*
*/
struct dp_tx_msdu_info_s {
enum dp_tx_frm_type frm_type;
struct dp_tx_queue tx_queue;
uint32_t num_seg;
uint8_t tid;
union {
struct qdf_tso_info_t tso_info;
struct dp_tx_sg_info_s sg_info;
} u;
};
struct meta_hdr_s {
uint8_t magic;
uint8_t flags;
uint8_t channel;
uint8_t keyix;
uint8_t rssi;
uint8_t silence;
uint8_t power;
uint8_t retries;
uint8_t max_tries[2];
uint8_t rates[2];
uint8_t unused[4];
};
#define METAHDR_FLAG_TX (1<<0) /* packet transmission */
#define METAHDR_FLAG_TX_FAIL (1<<1) /* transmission failed */
#define METAHDR_FLAG_TX_USED_ALT_RATE (1<<2) /* used alternate bitrate */
#define METAHDR_FLAG_AUTO_RATE (1<<5)
#define METAHDR_FLAG_NOENCRYPT (1<<6)
#define METAHDR_FLAG_NOQOS (1<<7)
#define METAHDR_FLAG_RX_ERR (1<<3) /* failed crc check */
#define METAHDR_FLAG_RX_MORE (1<<4) /* first part of a frag skb */
#define METAHDR_FLAG_LOG (1<<7)
#define METAHDR_FLAG_RX_4SS (1<<1) /* rx 4ss frame */
QDF_STATUS dp_tx_vdev_attach(struct dp_vdev *vdev);
QDF_STATUS dp_tx_vdev_detach(struct dp_vdev *vdev);
QDF_STATUS dp_tx_soc_attach(struct dp_soc *soc);
QDF_STATUS dp_tx_soc_detach(struct dp_soc *soc);
QDF_STATUS dp_tx_pdev_detach(struct dp_pdev *pdev);
QDF_STATUS dp_tx_pdev_attach(struct dp_pdev *pdev);
qdf_nbuf_t dp_tx_send(void *data_vdev, qdf_nbuf_t nbuf);
uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
uint32_t budget);
/* TODO TX_FEATURE_NOT_YET */
static inline void dp_tx_comp_process_exception(struct dp_tx_desc_s *tx_desc)
{
return;
}
static inline void dp_tx_comp_process_tx_status(struct dp_tx_desc_s *tx_desc)
{
return;
}
static inline QDF_STATUS dp_tx_flow_control(struct dp_vdev *vdev)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS dp_tx_prepare_tso(struct dp_vdev *vdev,
qdf_nbuf_t nbuf, struct dp_tx_msdu_info_s *msdu_info)
{
return QDF_STATUS_SUCCESS;
}
static inline qdf_nbuf_t dp_tx_prepare_me(struct dp_vdev *vdev,
qdf_nbuf_t nbuf, struct dp_tx_msdu_info_s *msdu_info)
{
return nbuf;
}
/* TODO TX_FEATURE_NOT_YET */
#endif

View File

@@ -29,6 +29,7 @@
#include <cdp_txrx_cmn.h>
#include <wdi_event_api.h> /* WDI subscriber event list */
#include <hal_tx.h>
#define MAX_PDEV_CNT 3
#define MAX_LINK_DESC_BANKS 8
#define MAX_TXDESC_POOLS 4
@@ -38,15 +39,150 @@
#define DP_MAX_TX_RINGS 8
#define DP_MAX_RX_RINGS 8
#define MAX_IDLE_SCATTER_BUFS 16
#define DP_MAX_IRQ_PER_CONTEXT 12
#define DP_MAX_INTERRUPT_CONTEXTS 8
#define MAX_TCL_DATA_RINGS 3
#define MAX_TXDESC_POOLS 3
#define MAX_TX_HW_QUEUES 3
#define DP_MAX_INTERRUPT_CONTEXTS 8
struct dp_soc_cmn;
struct dp_pdev;
struct dp_vdev;
union dp_tx_desc_list_elem_t;
struct dp_soc;
union dp_rx_desc_list_elem_t;
#define DP_MUTEX_TYPE qdf_spinlock_t
#define DP_FRAME_IS_MULTICAST(_a) (*(_a) & 0x01)
#define DP_FRAME_IS_IPV4_MULTICAST(_a) (*(_a) == 0x01)
#define DP_FRAME_IS_IPV6_MULTICAST(_a) \
((_a)[0] == 0x33 && \
(_a)[1] == 0x33)
#define DP_FRAME_IS_BROADCAST(_a) \
((_a)[0] == 0xff && \
(_a)[1] == 0xff && \
(_a)[2] == 0xff && \
(_a)[3] == 0xff && \
(_a)[4] == 0xff && \
(_a)[5] == 0xff)
/**
* enum dp_tx_frm_type
* @dp_tx_frm_std: Regular frame, no added header fragments
* @dp_tx_frm_tso: TSO segment, with a modified IP header added
* @dp_tx_frm_sg: SG segment
* @dp_tx_frm_audio: Audio frames, a custom LLC/SNAP header added
* @dp_tx_frm_me: Multicast to Unicast Converted frame
* @dp_tx_frm_raw: Raw Frame
*/
enum dp_tx_frm_type {
dp_tx_frm_std = 0,
dp_tx_frm_tso,
dp_tx_frm_sg,
dp_tx_frm_audio,
dp_tx_frm_me,
dp_tx_frm_raw,
};
/**
* struct dp_tx_ext_desc_elem_s
* @next: next extension descriptor pointer
* @vaddr: hlos virtual address pointer
* @paddr: physical address pointer for descriptor
*/
struct dp_tx_ext_desc_elem_s {
struct dp_tx_ext_desc_elem_s *next;
void *vaddr;
qdf_dma_addr_t paddr;
};
/**
* struct dp_tx_ext_desc_s - Tx Extension Descriptor Pool
* @elem_count: Number of descriptors in the pool
* @elem_size: Size of each descriptor
* @msdu_ext_desc: MSDU extension descriptor
* @desc_pages: multiple page allocation information for actual descriptors
* @link_elem_size: size of the link descriptor in cacheable memory used for
* chaining the extension descriptors
* @desc_link_pages: multiple page allocation information for link descriptors
*/
struct dp_tx_ext_desc_pool_s {
uint16_t elem_count;
int elem_size;
struct qdf_mem_multi_page_t desc_pages;
int link_elem_size;
struct qdf_mem_multi_page_t desc_link_pages;
struct dp_tx_ext_desc_elem_s *freelist;
qdf_spinlock_t lock;
qdf_dma_mem_context(memctx);
};
/**
* struct dp_tx_desc_s - Tx Descriptor
* @next: Next in the chain of descriptors in freelist or in the completion list
* @nbuf: Buffer Address
* @msdu_ext_desc: MSDU extension descriptor
* @id: Descriptor ID
* @vdev: vdev over which the packet was transmitted
* @pool_id: Pool ID - used when releasing the descripto
* @flags: Flags to track the state of descriptor and special frame handling
* @comp: Pool ID - used when releasing the descriptor
* @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.
* @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
* Tx completion of ME packet
*/
struct dp_tx_desc_s {
struct dp_tx_desc_s *next;
qdf_nbuf_t nbuf;
struct dp_tx_ext_desc_elem_s *msdu_ext_desc;
uint32_t id;
struct dp_vdev *vdev;
uint8_t pool_id;
uint8_t flags;
struct hal_tx_desc_comp_s comp;
uint16_t tx_encap_type;
uint8_t frm_type;
uint8_t pkt_offset;
void *me_buffer;
};
/**
* struct dp_tx_desc_pool_s - Tx Descriptor pool information
* @desc_reserved_size: Size to be reserved for housekeeping info
* in allocated memory for each descriptor
* @page_divider: Number of bits to shift to get page number from descriptor ID
* @offset_filter: Bit mask to get offset from descriptor ID
* @num_allocated: Number of allocated (in use) descriptors in the pool
* @elem_size: Size of each descriptor in the pool
* @elem_count: Total number of descriptors in the pool
* @freelist: Chain of free descriptors
* @desc_pages: multiple page allocation information
* @lock- Lock for descriptor allocation/free from/to the pool
*/
struct dp_tx_desc_pool_s {
uint16_t desc_reserved_size;
uint8_t page_divider;
uint32_t offset_filter;
uint32_t num_allocated;
uint16_t elem_size;
uint16_t elem_count;
struct dp_tx_desc_s *freelist;
struct qdf_mem_multi_page_t desc_pages;
qdf_spinlock_t lock;
};
struct dp_srng {
void *hal_srng;
void *base_vaddr_unaligned;
@@ -104,6 +240,18 @@ struct ol_if_ops {
/* TODO: Add any other control path calls required to OL_IF/WMA layer */
};
/* per interrupt context */
struct dp_intr {
uint8_t tx_ring_mask; /* WBM Tx completion rings (0-2)
associated with this napi context */
uint8_t rx_ring_mask; /* Rx REO rings (0-3) associated
with this interrupt context */
uint8_t rx_mon_ring_mask; /* Rx monitor ring mask (0-2) */
struct dp_soc *soc; /* Reference to SoC structure ,
to get DMA ring handles */
};
/* SOC level structure for data path */
struct dp_soc {
/* Common base structure - Should be the first member */
@@ -156,11 +304,14 @@ struct dp_soc {
uint32_t wbm_idle_scatter_buf_size;
/* Tx SW descriptor pool */
struct {
uint32_t pool_size;
union dp_tx_desc_list_elem_t *array;
union dp_tx_desc_list_elem_t *freelist;
} tx_desc[MAX_TXDESC_POOLS];
/* Tx SW descriptor pool */
struct dp_tx_desc_pool_s tx_desc[MAX_TXDESC_POOLS];
/* Tx MSDU Extension descriptor pool */
struct dp_tx_ext_desc_pool_s tx_ext_desc[MAX_TXDESC_POOLS];
/* Tx H/W queues lock */
qdf_spinlock_t tx_queue_lock[MAX_TX_HW_QUEUES];
/* Rx SW descriptor pool */
struct {
@@ -172,6 +323,9 @@ struct dp_soc {
/* HAL SOC handle */
void *hal_soc;
/* DP Interrupts */
struct dp_intr intr_ctx[DP_MAX_INTERRUPT_CONTEXTS];
/* REO destination rings */
struct dp_srng reo_dest_ring[MAX_REO_DEST_RINGS];
@@ -277,6 +431,9 @@ struct dp_soc {
struct {
/* TBD */
} stats;
/* Enable processing of Tx completion status words */
bool process_tx_status;
};
@@ -297,6 +454,9 @@ struct dp_pdev {
/* Empty ring used by firmware to post rx buffers to the MAC */
struct dp_srng rx_mac_buf_ring;
/* wlan_cfg pdev ctxt*/
struct wlan_cfg_dp_pdev_ctxt *wlan_cfg_ctx;
/* RXDMA monitor buffer replenish ring */
struct dp_srng rxdma_mon_buf_ring;
@@ -350,6 +510,9 @@ struct dp_pdev {
/* Enhanced Stats is enabled */
bool ap_stats_tx_cal_enable;
uint32_t num_tx_outstanding;
uint32_t num_tx_exception;
/* TBD */
};
@@ -373,6 +536,8 @@ union dp_align_mac_addr {
/* VDEV structure for data path state */
struct dp_vdev {
/* OS device abstraction */
qdf_device_t osdev;
/* physical device that is the parent of this virtual device */
struct dp_pdev *pdev;
@@ -443,12 +608,23 @@ struct dp_vdev {
/* Default HTT meta data for this VDEV */
/* TBD: check alignment constraints */
uint8_t htt_metadata[MAX_HTT_METADATA_LEN];
uint32_t htt_metadata_size;
uint16_t htt_tcl_metadata;
/* Mesh mode vdev */
uint32_t mesh_vdev;
/* DSCP-TID mapping table ID */
uint8_t dscp_tid_map_id;
/* Multicast enhancement enabled */
uint8_t mcast_enhancement_en;
uint32_t num_tx_outstanding;
uint8_t tx_ring_id;
struct dp_tx_desc_pool_s *tx_desc;
struct dp_tx_ext_desc_pool_s *tx_ext_desc;
/* TBD */
};
@@ -514,4 +690,3 @@ struct dp_peer {
};
#endif /* _DP_TYPES_H_ */

View File

@@ -87,6 +87,9 @@ do { \
#define HAL_TX_EXT_BUF_LEN_LSB TX_MSDU_EXTENSION_7_BUF0_LEN_LSB
#define HAL_TX_EXT_BUF_WD_SIZE 2
#define HAL_TX_DESC_ADDRX_EN 0x1
#define HAL_TX_DESC_ADDRY_EN 0x2
enum hal_tx_ret_buf_manager {
HAL_WBM_SW0_BM_ID = 3,
HAL_WBM_SW1_BM_ID = 4,