mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 07:37:31 -04:00
qcacmn: REO management changes
Changes to use REO HW command/status interface to update/delete REO queues. Change-Id: I3500d45db021ef314b4d03fa878314d407ddfe65
This commit is contained in:
parent
4f0c6b1732
commit
a0f09eae1d
7 changed files with 290 additions and 47 deletions
|
|
@ -90,4 +90,13 @@ extern void dp_addba_responsesetup_wifi3(void *peer_handle, uint8_t tid,
|
|||
uint16_t *buffersize, uint16_t *batimeout);
|
||||
extern int dp_delba_process_wifi3(void *peer_handle,
|
||||
int tid, uint16_t reasoncode);
|
||||
|
||||
extern int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
|
||||
uint32_t ba_window_size, uint32_t start_seq);
|
||||
|
||||
extern QDF_STATUS dp_reo_send_cmd(struct dp_soc *soc,
|
||||
enum hal_reo_cmd_type type, struct hal_reo_cmd_params *params,
|
||||
void (*callback_fn), void *data);
|
||||
|
||||
extern void dp_reo_status_ring_handler(struct dp_soc *soc);
|
||||
#endif /* #ifndef _DP_INTERNAL_H_ */
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
|
|||
uint8_t rx_mask = int_ctx->rx_ring_mask;
|
||||
uint8_t rx_err_mask = int_ctx->rx_err_ring_mask;
|
||||
uint8_t rx_wbm_rel_mask = int_ctx->rx_wbm_rel_ring_mask;
|
||||
uint8_t reo_status_mask = int_ctx->reo_status_ring_mask;
|
||||
|
||||
/* Process Tx completion interrupts first to return back buffers */
|
||||
if (tx_mask) {
|
||||
|
|
@ -211,6 +212,9 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
|
|||
}
|
||||
}
|
||||
|
||||
if (reo_status_mask)
|
||||
dp_reo_status_ring_handler(soc);
|
||||
|
||||
budget_done:
|
||||
return dp_budget - budget;
|
||||
}
|
||||
|
|
@ -255,6 +259,7 @@ static QDF_STATUS dp_soc_interrupt_attach(void *txrx_soc)
|
|||
soc->intr_ctx[i].rx_mon_ring_mask = 0xF;
|
||||
soc->intr_ctx[i].rx_err_ring_mask = 0x1;
|
||||
soc->intr_ctx[i].rx_wbm_rel_ring_mask = 0x1;
|
||||
soc->intr_ctx[i].reo_status_ring_mask = 0x1;
|
||||
soc->intr_ctx[i].soc = soc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "dp_internal.h"
|
||||
#include "dp_peer.h"
|
||||
#include <hal_api.h>
|
||||
#include <hal_reo.h>
|
||||
|
||||
/* Temporary definitions to be moved to wlan_cfg */
|
||||
static inline uint32_t wlan_cfg_max_peer_id(void *wlan_cfg_ctx)
|
||||
|
|
@ -401,6 +402,91 @@ dp_peer_find_detach(struct dp_soc *soc)
|
|||
dp_peer_find_hash_detach(soc);
|
||||
}
|
||||
|
||||
static void dp_rx_tid_stats_cb(struct dp_soc *soc, void *cb_ctxt,
|
||||
union hal_reo_status *reo_status)
|
||||
{
|
||||
struct dp_rx_tid *rx_tid = (struct dp_rx_tid *)cb_ctxt;
|
||||
struct hal_reo_queue_status *queue_status = &(reo_status->queue_status);
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: rx_tid: %d status: %d\n", __func__,
|
||||
rx_tid->tid, queue_status->header.status);
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"REO queue stats: \n"
|
||||
"ssn: %d\n"
|
||||
"curr_idx : %d\n"
|
||||
"pn_31_0 : %08x\n"
|
||||
"pn_63_32 : %08x\n"
|
||||
"pn_95_64 : %08x\n"
|
||||
"pn_127_96 : %08x\n"
|
||||
"last_rx_enq_tstamp : %08x\n"
|
||||
"last_rx_deq_tstamp : %08x\n"
|
||||
"rx_bitmap_31_0 : %08x\n"
|
||||
"rx_bitmap_63_32 : %08x\n"
|
||||
"rx_bitmap_95_64 : %08x\n"
|
||||
"rx_bitmap_127_96 : %08x\n"
|
||||
"rx_bitmap_159_128 : %08x\n"
|
||||
"rx_bitmap_191_160 : %08x\n"
|
||||
"rx_bitmap_223_192 : %08x\n"
|
||||
"rx_bitmap_255_224 : %08x\n"
|
||||
"curr_mpdu_cnt : %d\n"
|
||||
"curr_msdu_cnt : %d\n"
|
||||
"fwd_timeout_cnt : %d\n"
|
||||
"fwd_bar_cnt : %d\n"
|
||||
"dup_cnt : %d\n"
|
||||
"frms_in_order_cnt : %d\n"
|
||||
"bar_rcvd_cnt : %d\n"
|
||||
"mpdu_frms_cnt : %d\n"
|
||||
"msdu_frms_cnt : %d\n"
|
||||
"total_cnt : %d\n"
|
||||
"late_recv_mpdu_cnt : %d\n"
|
||||
"win_jump_2k : %d\n"
|
||||
"hole_cnt : %d\n",
|
||||
queue_status->ssn, queue_status->curr_idx,
|
||||
queue_status->pn_31_0, queue_status->pn_63_32,
|
||||
queue_status->pn_95_64, queue_status->pn_127_96,
|
||||
queue_status->last_rx_enq_tstamp,
|
||||
queue_status->last_rx_deq_tstamp,
|
||||
queue_status->rx_bitmap_31_0, queue_status->rx_bitmap_63_32,
|
||||
queue_status->rx_bitmap_95_64, queue_status->rx_bitmap_127_96,
|
||||
queue_status->rx_bitmap_159_128,
|
||||
queue_status->rx_bitmap_191_160,
|
||||
queue_status->rx_bitmap_223_192,
|
||||
queue_status->rx_bitmap_255_224,
|
||||
queue_status->curr_mpdu_cnt, queue_status->curr_msdu_cnt,
|
||||
queue_status->fwd_timeout_cnt, queue_status->fwd_bar_cnt,
|
||||
queue_status->dup_cnt, queue_status->frms_in_order_cnt,
|
||||
queue_status->bar_rcvd_cnt, queue_status->mpdu_frms_cnt,
|
||||
queue_status->msdu_frms_cnt, queue_status->total_cnt,
|
||||
queue_status->late_recv_mpdu_cnt, queue_status->win_jump_2k,
|
||||
queue_status->hole_cnt);
|
||||
}
|
||||
|
||||
static void dp_rx_tid_update_cb(struct dp_soc *soc, void *cb_ctxt,
|
||||
union hal_reo_status *reo_status)
|
||||
{
|
||||
struct dp_rx_tid *rx_tid = (struct dp_rx_tid *)cb_ctxt;
|
||||
struct hal_reo_cmd_params params;
|
||||
|
||||
if (reo_status->queue_status.header.status) {
|
||||
/* Should not happen normally. Just print error for now */
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: Rx tid HW desc update failed(%d): tid %d\n",
|
||||
__func__,
|
||||
reo_status->rx_queue_status.header.status,
|
||||
rx_tid->tid);
|
||||
}
|
||||
|
||||
qdf_mem_zero(¶ms, sizeof(params));
|
||||
|
||||
params.std.need_status = 1;
|
||||
params.std.addr_lo = rx_tid->hw_qdesc_paddr & 0xffffffff;
|
||||
params.std.addr_hi = (uint64_t)(rx_tid->hw_qdesc_paddr) >> 32;
|
||||
|
||||
dp_reo_send_cmd(soc, CMD_GET_QUEUE_STATS, ¶ms, dp_rx_tid_stats_cb, rx_tid);
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_find_peer_by_addr - find peer instance by mac address
|
||||
* @dev: physical device instance
|
||||
|
|
@ -442,7 +528,24 @@ void *dp_find_peer_by_addr(void *dev, uint8_t *peer_mac_addr,
|
|||
static int dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t
|
||||
ba_window_size, uint32_t start_seq)
|
||||
{
|
||||
/* TODO: Implement this once REO command API is available */
|
||||
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
||||
struct dp_soc *soc = peer->vdev->pdev->soc;
|
||||
struct hal_reo_cmd_params params;
|
||||
|
||||
qdf_mem_zero(¶ms, sizeof(params));
|
||||
|
||||
params.std.need_status = 1;
|
||||
params.std.addr_lo = rx_tid->hw_qdesc_paddr & 0xffffffff;
|
||||
params.std.addr_hi = (uint64_t)(rx_tid->hw_qdesc_paddr) >> 32;
|
||||
params.u.upd_queue_params.update_ba_window_size = 1;
|
||||
params.u.upd_queue_params.ba_window_size = ba_window_size;
|
||||
|
||||
if (start_seq < IEEE80211_SEQ_MAX) {
|
||||
params.u.upd_queue_params.update_ssn = 1;
|
||||
params.u.upd_queue_params.ssn = start_seq;
|
||||
}
|
||||
|
||||
dp_reo_send_cmd(soc, CMD_UPDATE_RX_REO_QUEUE, ¶ms, dp_rx_tid_update_cb, rx_tid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -455,7 +558,7 @@ static int dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t
|
|||
*
|
||||
* Return: 0 on success, error code on failure
|
||||
*/
|
||||
static int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
|
||||
int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
|
||||
uint32_t ba_window_size, uint32_t start_seq)
|
||||
{
|
||||
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
||||
|
|
@ -570,42 +673,34 @@ static int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
|
|||
peer->vdev->vdev_id, peer->mac_addr.raw,
|
||||
rx_tid->hw_qdesc_paddr, tid, tid);
|
||||
|
||||
if (tid == DP_NON_QOS_TID) {
|
||||
/* TODO: Setting up default queue - currently using
|
||||
* same queue for BE and non-qos traffic till BA
|
||||
* session is setup. Check if there are any HW
|
||||
* restrictions and also if this can be done for
|
||||
* all other TIDs
|
||||
*/
|
||||
soc->cdp_soc.ol_ops->
|
||||
peer_rx_reorder_queue_setup(soc->osif_soc,
|
||||
peer->vdev->vdev_id, peer->mac_addr.raw,
|
||||
rx_tid->hw_qdesc_paddr, 0, tid);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef notyet /* TBD: Enable this once REO command interface is available */
|
||||
/*
|
||||
* Rx TID deletion callback to free memory allocated for HW queue descriptor
|
||||
*/
|
||||
static void dp_rx_tid_delete_cb(struct dp_pdev *pdev, void *cb_ctxt, int status)
|
||||
static void dp_rx_tid_delete_cb(struct dp_soc *soc, void *cb_ctxt,
|
||||
union hal_reo_status *reo_status)
|
||||
{
|
||||
struct dp_soc *soc = pdev->soc;
|
||||
struct dp_rx_tid *rx_tid = (struct dp_rx_tid *)cb_ctxt;
|
||||
|
||||
if (status) {
|
||||
if (reo_status->rx_queue_status.header.status) {
|
||||
/* Should not happen normally. Just print error for now */
|
||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||
"%s: Rx tid HW desc deletion failed: tid %d\n",
|
||||
__func__, rx_tid->tid);
|
||||
"%s: Rx tid HW desc deletion failed(%d): tid %d\n",
|
||||
__func__,
|
||||
reo_status->rx_queue_status.header.status,
|
||||
rx_tid->tid);
|
||||
}
|
||||
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
|
||||
"%s: rx_tid: %d status: %d\n", __func__,
|
||||
rx_tid->tid, reo_status->rx_queue_status.header.status);
|
||||
qdf_mem_free_consistent(soc->osdev, soc->osdev->dev,
|
||||
rx_tid->hw_qdesc_alloc_size,
|
||||
rx_tid->hw_qdesc_vaddr_unaligned,
|
||||
rx_tid->hw_qdesc_paddr_unaligned, 0);
|
||||
rx_tid->hw_qdesc_alloc_size,
|
||||
rx_tid->hw_qdesc_vaddr_unaligned,
|
||||
rx_tid->hw_qdesc_paddr_unaligned, 0);
|
||||
|
||||
rx_tid->hw_qdesc_vaddr_unaligned = NULL;
|
||||
rx_tid->hw_qdesc_alloc_size = 0;
|
||||
|
|
@ -620,17 +715,22 @@ static void dp_rx_tid_delete_cb(struct dp_pdev *pdev, void *cb_ctxt, int status)
|
|||
*/
|
||||
static int dp_rx_tid_delete_wifi3(struct dp_peer *peer, int tid)
|
||||
{
|
||||
struct dp_rx_tid *rx_tid = peer->rx_tid[tid];
|
||||
dp_rx_tid_hw_update_valid(rx_tid->hw_qdesc_paddr, 0,
|
||||
struct dp_rx_tid *rx_tid = &(peer->rx_tid[tid]);
|
||||
struct dp_soc *soc = peer->vdev->pdev->soc;
|
||||
struct hal_reo_cmd_params params;
|
||||
|
||||
qdf_mem_zero(¶ms, sizeof(params));
|
||||
|
||||
params.std.need_status = 1;
|
||||
params.std.addr_lo = rx_tid->hw_qdesc_paddr & 0xffffffff;
|
||||
params.std.addr_hi = (uint64_t)(rx_tid->hw_qdesc_paddr) >> 32;
|
||||
params.u.upd_queue_params.update_vld = 1;
|
||||
params.u.upd_queue_params.vld = 0;
|
||||
|
||||
dp_reo_send_cmd(soc, CMD_UPDATE_RX_REO_QUEUE, ¶ms,
|
||||
dp_rx_tid_delete_cb, (void *)rx_tid);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int dp_rx_tid_delete_wifi3(struct dp_peer *peer, int tid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* dp_peer_rx_init() – Initialize receive TID state
|
||||
|
|
@ -663,6 +763,12 @@ void dp_peer_rx_init(struct dp_pdev *pdev, struct dp_peer *peer)
|
|||
/* Setup default (non-qos) rx tid queue */
|
||||
dp_rx_tid_setup_wifi3(peer, DP_NON_QOS_TID, 1, 0);
|
||||
|
||||
/* Setup rx tid queue for TID 0.
|
||||
* Other queues will be setup on receiving first packet, which will cause
|
||||
* NULL REO queue error
|
||||
*/
|
||||
dp_rx_tid_setup_wifi3(peer, 0, 1, 0);
|
||||
|
||||
/*
|
||||
* Set security defaults: no PN check, no security. The target may
|
||||
* send a HTT SEC_IND message to overwrite these defaults.
|
||||
|
|
@ -680,10 +786,9 @@ void dp_peer_rx_init(struct dp_pdev *pdev, struct dp_peer *peer)
|
|||
void dp_peer_rx_cleanup(struct dp_vdev *vdev, struct dp_peer *peer)
|
||||
{
|
||||
int tid;
|
||||
struct dp_rx_tid *rx_tid;
|
||||
uint32_t tid_delete_mask = 0;
|
||||
for (tid = 0; tid < DP_MAX_TIDS; tid++) {
|
||||
if (rx_tid->hw_qdesc_vaddr_unaligned != NULL) {
|
||||
if (peer->rx_tid[tid].hw_qdesc_vaddr_unaligned != NULL) {
|
||||
dp_rx_tid_delete_wifi3(peer, tid);
|
||||
tid_delete_mask |= (1 << tid);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,9 +19,11 @@
|
|||
#include "dp_types.h"
|
||||
#include "dp_rx.h"
|
||||
#include "dp_peer.h"
|
||||
#include "dp_internal.h"
|
||||
#include "hal_api.h"
|
||||
#include "qdf_trace.h"
|
||||
#include "qdf_nbuf.h"
|
||||
#include <ieee80211.h>
|
||||
|
||||
/**
|
||||
* dp_rx_cookie_2_link_desc_va() - Converts cookie to a virtual address of
|
||||
|
|
@ -254,6 +256,9 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, void *ring_desc,
|
|||
qdf_nbuf_t nbuf;
|
||||
struct dp_pdev *pdev0;
|
||||
struct dp_vdev *vdev0;
|
||||
uint32_t tid = 0;
|
||||
uint16_t peer_id;
|
||||
struct dp_peer *peer = NULL;
|
||||
|
||||
rx_buf_cookie = HAL_RX_WBM_BUF_COOKIE_GET(ring_desc);
|
||||
|
||||
|
|
@ -300,6 +305,22 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, void *ring_desc,
|
|||
if (l2_hdr_offset)
|
||||
qdf_nbuf_pull_head(nbuf, l2_hdr_offset);
|
||||
|
||||
if (hal_rx_mpdu_start_mpdu_qos_control_valid_get(
|
||||
rx_desc->rx_buf_start)) {
|
||||
/* TODO: Assuming that qos_control_valid also indicates
|
||||
* unicast. Should we check this?
|
||||
*/
|
||||
tid = hal_rx_mpdu_start_tid_get(rx_desc->rx_buf_start);
|
||||
peer_id = hal_rx_mpdu_start_sw_peer_id_get(
|
||||
rx_desc->rx_buf_start);
|
||||
peer = dp_peer_find_by_id(soc, peer_id);
|
||||
if (peer &&
|
||||
peer->rx_tid[tid].hw_qdesc_vaddr_unaligned == NULL) {
|
||||
/* IEEE80211_SEQ_MAX indicates invalid start_seq */
|
||||
dp_rx_tid_setup_wifi3(peer, tid, 1, IEEE80211_SEQ_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
pdev0 = soc->pdev_list[0];/* Hard code 0th elem */
|
||||
|
||||
if (pdev0) {
|
||||
|
|
|
|||
|
|
@ -249,6 +249,7 @@ struct dp_intr {
|
|||
uint8_t rx_mon_ring_mask; /* Rx monitor ring mask (0-2) */
|
||||
uint8_t rx_err_ring_mask; /* REO Exception Ring */
|
||||
uint8_t rx_wbm_rel_ring_mask; /* WBM2SW Rx Release Ring */
|
||||
uint8_t reo_status_ring_mask; /* REO command response ring */
|
||||
struct dp_soc *soc; /* Reference to SoC structure ,
|
||||
to get DMA ring handles */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -631,6 +631,75 @@ hal_rx_msdu_start_msdu_len_get(uint8_t *buf)
|
|||
return msdu_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get qos_control_valid from RX_MPDU_START
|
||||
*/
|
||||
#define HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET(_rx_mpdu_info) \
|
||||
(_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \
|
||||
RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_OFFSET)), \
|
||||
RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_MASK, \
|
||||
RX_MPDU_INFO_2_MPDU_SEQUENCE_CONTROL_VALID_LSB))
|
||||
|
||||
static inline uint32_t
|
||||
hal_rx_mpdu_start_mpdu_qos_control_valid_get(uint8_t *buf)
|
||||
{
|
||||
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
|
||||
struct rx_mpdu_start *mpdu_start =
|
||||
&pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
|
||||
uint32_t qos_control_valid;
|
||||
|
||||
qos_control_valid = HAL_RX_MPDU_INFO_QOS_CONTROL_VALID_GET(
|
||||
&(mpdu_start->rx_mpdu_info_details));
|
||||
|
||||
return qos_control_valid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get tid from RX_MPDU_START
|
||||
*/
|
||||
#define HAL_RX_MPDU_INFO_TID_GET(_rx_mpdu_info) \
|
||||
(_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \
|
||||
RX_MPDU_INFO_3_TID_OFFSET)), \
|
||||
RX_MPDU_INFO_3_TID_MASK, \
|
||||
RX_MPDU_INFO_3_TID_LSB))
|
||||
|
||||
static inline uint32_t
|
||||
hal_rx_mpdu_start_tid_get(uint8_t *buf)
|
||||
{
|
||||
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
|
||||
struct rx_mpdu_start *mpdu_start =
|
||||
&pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
|
||||
uint32_t tid;
|
||||
|
||||
tid = HAL_RX_MPDU_INFO_TID_GET(
|
||||
&(mpdu_start->rx_mpdu_info_details));
|
||||
|
||||
return tid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get SW peer id from RX_MPDU_START
|
||||
*/
|
||||
#define HAL_RX_MPDU_INFO_SW_PEER_ID_GET(_rx_mpdu_info) \
|
||||
(_HAL_MS((*_OFFSET_TO_WORD_PTR((_rx_mpdu_info), \
|
||||
RX_MPDU_INFO_1_SW_PEER_ID_OFFSET)), \
|
||||
RX_MPDU_INFO_1_SW_PEER_ID_MASK, \
|
||||
RX_MPDU_INFO_1_SW_PEER_ID_LSB))
|
||||
|
||||
static inline uint32_t
|
||||
hal_rx_mpdu_start_sw_peer_id_get(uint8_t *buf)
|
||||
{
|
||||
struct rx_pkt_tlvs *pkt_tlvs = (struct rx_pkt_tlvs *)buf;
|
||||
struct rx_mpdu_start *mpdu_start =
|
||||
&pkt_tlvs->mpdu_start_tlv.rx_mpdu_start;
|
||||
uint32_t sw_peer_id;
|
||||
|
||||
sw_peer_id = HAL_RX_MPDU_INFO_SW_PEER_ID_GET(
|
||||
&(mpdu_start->rx_mpdu_info_details));
|
||||
|
||||
return sw_peer_id;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* RX ERROR APIS
|
||||
******************************************************************************/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
|
@ -210,15 +210,22 @@ static inline int hal_srng_access_start(void *hal_soc, void *hal_ring)
|
|||
static inline void *hal_srng_dst_get_next(void *hal_soc, void *hal_ring)
|
||||
{
|
||||
struct hal_srng *srng = (struct hal_srng *)hal_ring;
|
||||
uint32_t *desc = &(srng->ring_base_vaddr[srng->u.dst_ring.tp]);
|
||||
volatile uint32_t *desc = &(srng->ring_base_vaddr[srng->u.dst_ring.tp]);
|
||||
uint32_t desc_loop_cnt;
|
||||
|
||||
desc_loop_cnt = (desc[srng->entry_size - 1] & SRNG_LOOP_CNT_MASK)
|
||||
>> SRNG_LOOP_CNT_LSB;
|
||||
|
||||
if (srng->u.dst_ring.loop_cnt == desc_loop_cnt) {
|
||||
srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size) &
|
||||
srng->ring_size_mask;
|
||||
/* TODO: Using % is expensive, but we have to do this since
|
||||
* size of some SRNG rings is not power of 2 (due to descriptor
|
||||
* sizes). Need to create separate API for rings used
|
||||
* per-packet, with sizes power of 2 (TCL2SW, REO2SW,
|
||||
* SW2RXDMA and CE rings)
|
||||
*/
|
||||
srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size) %
|
||||
srng->ring_size;
|
||||
|
||||
srng->u.dst_ring.loop_cnt = (srng->u.dst_ring.loop_cnt +
|
||||
!srng->u.dst_ring.tp) &
|
||||
(SRNG_LOOP_CNT_MASK >> SRNG_LOOP_CNT_LSB);
|
||||
|
|
@ -298,8 +305,15 @@ static inline void *hal_srng_src_reap_next(void *hal_soc, void *hal_ring)
|
|||
{
|
||||
struct hal_srng *srng = (struct hal_srng *)hal_ring;
|
||||
uint32_t *desc;
|
||||
uint32_t next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) &
|
||||
srng->ring_size_mask;
|
||||
|
||||
/* TODO: Using % is expensive, but we have to do this since
|
||||
* size of some SRNG rings is not power of 2 (due to descriptor
|
||||
* sizes). Need to create separate API for rings used
|
||||
* per-packet, with sizes power of 2 (TCL2SW, REO2SW,
|
||||
* SW2RXDMA and CE rings)
|
||||
*/
|
||||
uint32_t next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) %
|
||||
srng->ring_size;
|
||||
|
||||
if (next_reap_hp != srng->u.src_ring.cached_tp) {
|
||||
desc = &(srng->ring_base_vaddr[next_reap_hp]);
|
||||
|
|
@ -327,8 +341,9 @@ static inline void *hal_srng_src_get_next_reaped(void *hal_soc, void *hal_ring)
|
|||
|
||||
if (srng->u.src_ring.hp != srng->u.src_ring.reap_hp) {
|
||||
desc = &(srng->ring_base_vaddr[srng->u.src_ring.hp]);
|
||||
srng->u.src_ring.hp = (srng->u.src_ring.hp + srng->entry_size) &
|
||||
srng->ring_size_mask;
|
||||
srng->u.src_ring.hp = (srng->u.src_ring.hp + srng->entry_size) %
|
||||
srng->ring_size;
|
||||
|
||||
return (void *)desc;
|
||||
}
|
||||
|
||||
|
|
@ -346,8 +361,14 @@ static inline void *hal_srng_src_get_next_reaped(void *hal_soc, void *hal_ring)
|
|||
static inline uint32_t hal_srng_src_done_val(void *hal_soc, void *hal_ring)
|
||||
{
|
||||
struct hal_srng *srng = (struct hal_srng *)hal_ring;
|
||||
uint32_t next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) &
|
||||
srng->ring_size_mask;
|
||||
/* TODO: Using % is expensive, but we have to do this since
|
||||
* size of some SRNG rings is not power of 2 (due to descriptor
|
||||
* sizes). Need to create separate API for rings used
|
||||
* per-packet, with sizes power of 2 (TCL2SW, REO2SW,
|
||||
* SW2RXDMA and CE rings)
|
||||
*/
|
||||
uint32_t next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) %
|
||||
srng->ring_size;
|
||||
|
||||
if (next_reap_hp == srng->u.src_ring.cached_tp)
|
||||
return 0;
|
||||
|
|
@ -371,8 +392,14 @@ static inline void *hal_srng_src_get_next(void *hal_soc, void *hal_ring)
|
|||
{
|
||||
struct hal_srng *srng = (struct hal_srng *)hal_ring;
|
||||
uint32_t *desc;
|
||||
uint32_t next_hp = (srng->u.src_ring.hp + srng->entry_size) &
|
||||
srng->ring_size_mask;
|
||||
/* TODO: Using % is expensive, but we have to do this since
|
||||
* size of some SRNG rings is not power of 2 (due to descriptor
|
||||
* sizes). Need to create separate API for rings used
|
||||
* per-packet, with sizes power of 2 (TCL2SW, REO2SW,
|
||||
* SW2RXDMA and CE rings)
|
||||
*/
|
||||
uint32_t next_hp = (srng->u.src_ring.hp + srng->entry_size) %
|
||||
srng->ring_size;
|
||||
|
||||
if (next_hp != srng->u.src_ring.cached_tp) {
|
||||
desc = &(srng->ring_base_vaddr[srng->u.src_ring.hp]);
|
||||
|
|
@ -403,8 +430,14 @@ static inline void *hal_srng_src_peek(void *hal_soc, void *hal_ring)
|
|||
struct hal_srng *srng = (struct hal_srng *)hal_ring;
|
||||
uint32_t *desc;
|
||||
|
||||
if (((srng->u.src_ring.hp + srng->entry_size) &
|
||||
srng->ring_size_mask) != srng->u.src_ring.cached_tp) {
|
||||
/* TODO: Using % is expensive, but we have to do this since
|
||||
* size of some SRNG rings is not power of 2 (due to descriptor
|
||||
* sizes). Need to create separate API for rings used
|
||||
* per-packet, with sizes power of 2 (TCL2SW, REO2SW,
|
||||
* SW2RXDMA and CE rings)
|
||||
*/
|
||||
if (((srng->u.src_ring.hp + srng->entry_size) %
|
||||
srng->ring_size) != srng->u.src_ring.cached_tp) {
|
||||
desc = &(srng->ring_base_vaddr[srng->u.src_ring.hp]);
|
||||
return (void *)desc;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue