qcacmn: REO descriptor allocation change
Use normal allocation instead of alloc_consistent for REO descriptors to allow freeing from interrupt context. Also fixed an issue in ba_window_size setting in REO queues. Change-Id: I91b06e04c0343eb7fe8580d8655c6bc5e33cfe06
This commit is contained in:

committed by
Sandeep Puligilla

orang tua
34ff0b5a3c
melakukan
7957fa9705
@@ -1313,10 +1313,11 @@ static inline void dp_reo_desc_freelist_destroy(struct dp_soc *soc)
|
|||||||
while (qdf_list_remove_front(&soc->reo_desc_freelist,
|
while (qdf_list_remove_front(&soc->reo_desc_freelist,
|
||||||
(qdf_list_node_t **)&desc) == QDF_STATUS_SUCCESS) {
|
(qdf_list_node_t **)&desc) == QDF_STATUS_SUCCESS) {
|
||||||
rx_tid = &desc->rx_tid;
|
rx_tid = &desc->rx_tid;
|
||||||
qdf_mem_free_consistent(soc->osdev, soc->osdev->dev,
|
qdf_mem_unmap_nbytes_single(soc->osdev,
|
||||||
rx_tid->hw_qdesc_alloc_size,
|
rx_tid->hw_qdesc_paddr_unaligned,
|
||||||
rx_tid->hw_qdesc_vaddr_unaligned,
|
QDF_DMA_BIDIRECTIONAL,
|
||||||
rx_tid->hw_qdesc_paddr_unaligned, 0);
|
rx_tid->hw_qdesc_alloc_size);
|
||||||
|
qdf_mem_free(rx_tid->hw_qdesc_vaddr_unaligned);
|
||||||
qdf_mem_free(desc);
|
qdf_mem_free(desc);
|
||||||
}
|
}
|
||||||
qdf_spin_unlock_bh(&soc->reo_desc_freelist_lock);
|
qdf_spin_unlock_bh(&soc->reo_desc_freelist_lock);
|
||||||
|
@@ -534,15 +534,11 @@ static void dp_reo_desc_free(struct dp_soc *soc,
|
|||||||
(qdf_list_node_t **)&desc);
|
(qdf_list_node_t **)&desc);
|
||||||
list_size--;
|
list_size--;
|
||||||
rx_tid = &desc->rx_tid;
|
rx_tid = &desc->rx_tid;
|
||||||
/* Calling qdf_mem_free_consistent() in MCL is resulting in kernel BUG.
|
qdf_mem_unmap_nbytes_single(soc->osdev,
|
||||||
* Diasble this temporarily.
|
rx_tid->hw_qdesc_paddr_unaligned,
|
||||||
*/
|
QDF_DMA_BIDIRECTIONAL,
|
||||||
#ifndef QCA_WIFI_NAPIER_EMULATION
|
rx_tid->hw_qdesc_alloc_size);
|
||||||
qdf_mem_free_consistent(soc->osdev, soc->osdev->dev,
|
qdf_mem_free(rx_tid->hw_qdesc_vaddr_unaligned);
|
||||||
rx_tid->hw_qdesc_alloc_size,
|
|
||||||
rx_tid->hw_qdesc_vaddr_unaligned,
|
|
||||||
rx_tid->hw_qdesc_paddr_unaligned, 0);
|
|
||||||
#endif
|
|
||||||
qdf_mem_free(desc);
|
qdf_mem_free(desc);
|
||||||
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
|
||||||
@@ -552,6 +548,23 @@ static void dp_reo_desc_free(struct dp_soc *soc,
|
|||||||
qdf_spin_unlock_bh(&soc->reo_desc_freelist_lock);
|
qdf_spin_unlock_bh(&soc->reo_desc_freelist_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(QCA_WIFI_QCA8074) && defined(BUILD_X86)
|
||||||
|
/* Hawkeye emulation requires bus address to be >= 0x50000000 */
|
||||||
|
static inline int dp_reo_desc_addr_chk(qdf_dma_addr_t dma_addr)
|
||||||
|
{
|
||||||
|
if (dma_addr < 0x50000000)
|
||||||
|
return QDF_STATUS_E_FAILURE;
|
||||||
|
else
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline int dp_reo_desc_addr_chk(qdf_dma_addr_t dma_addr)
|
||||||
|
{
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* dp_rx_tid_setup_wifi3() – Setup receive TID state
|
* dp_rx_tid_setup_wifi3() – Setup receive TID state
|
||||||
* @peer: Datapath peer handle
|
* @peer: Datapath peer handle
|
||||||
@@ -562,7 +575,7 @@ static void dp_reo_desc_free(struct dp_soc *soc,
|
|||||||
* Return: 0 on success, error code on failure
|
* Return: 0 on success, error code on failure
|
||||||
*/
|
*/
|
||||||
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)
|
uint32_t ba_window_size, uint32_t start_seq)
|
||||||
{
|
{
|
||||||
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
struct dp_rx_tid *rx_tid = &peer->rx_tid[tid];
|
||||||
struct dp_vdev *vdev = peer->vdev;
|
struct dp_vdev *vdev = peer->vdev;
|
||||||
@@ -571,6 +584,7 @@ int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
|
|||||||
uint32_t hw_qdesc_align;
|
uint32_t hw_qdesc_align;
|
||||||
int hal_pn_type;
|
int hal_pn_type;
|
||||||
void *hw_qdesc_vaddr;
|
void *hw_qdesc_vaddr;
|
||||||
|
uint32_t alloc_tries = 0;
|
||||||
|
|
||||||
if (rx_tid->hw_qdesc_vaddr_unaligned != NULL)
|
if (rx_tid->hw_qdesc_vaddr_unaligned != NULL)
|
||||||
return dp_rx_tid_update_wifi3(peer, tid, ba_window_size,
|
return dp_rx_tid_update_wifi3(peer, tid, ba_window_size,
|
||||||
@@ -600,9 +614,10 @@ int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
|
|||||||
* exact size and see if we already have aligned address.
|
* exact size and see if we already have aligned address.
|
||||||
*/
|
*/
|
||||||
rx_tid->hw_qdesc_alloc_size = hw_qdesc_size;
|
rx_tid->hw_qdesc_alloc_size = hw_qdesc_size;
|
||||||
rx_tid->hw_qdesc_vaddr_unaligned = qdf_mem_alloc_consistent(
|
|
||||||
soc->osdev, soc->osdev->dev, rx_tid->hw_qdesc_alloc_size,
|
try_desc_alloc:
|
||||||
&(rx_tid->hw_qdesc_paddr_unaligned));
|
rx_tid->hw_qdesc_vaddr_unaligned =
|
||||||
|
qdf_mem_malloc(rx_tid->hw_qdesc_alloc_size);
|
||||||
|
|
||||||
if (!rx_tid->hw_qdesc_vaddr_unaligned) {
|
if (!rx_tid->hw_qdesc_vaddr_unaligned) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||||
@@ -616,16 +631,11 @@ int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
|
|||||||
/* Address allocated above is not alinged. Allocate extra
|
/* Address allocated above is not alinged. Allocate extra
|
||||||
* memory for alignment
|
* memory for alignment
|
||||||
*/
|
*/
|
||||||
qdf_mem_free_consistent(soc->osdev, soc->osdev->dev,
|
qdf_mem_free(rx_tid->hw_qdesc_vaddr_unaligned);
|
||||||
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_alloc_size =
|
||||||
hw_qdesc_size + hw_qdesc_align - 1;
|
hw_qdesc_size + hw_qdesc_align - 1;
|
||||||
rx_tid->hw_qdesc_vaddr_unaligned = qdf_mem_alloc_consistent(
|
rx_tid->hw_qdesc_vaddr_unaligned =
|
||||||
soc->osdev, soc->osdev->dev, rx_tid->hw_qdesc_alloc_size,
|
qdf_mem_malloc(rx_tid->hw_qdesc_alloc_size);
|
||||||
&(rx_tid->hw_qdesc_paddr_unaligned));
|
|
||||||
|
|
||||||
if (!rx_tid->hw_qdesc_vaddr_unaligned) {
|
if (!rx_tid->hw_qdesc_vaddr_unaligned) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||||
@@ -637,13 +647,8 @@ int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
|
|||||||
hw_qdesc_vaddr = rx_tid->hw_qdesc_vaddr_unaligned +
|
hw_qdesc_vaddr = rx_tid->hw_qdesc_vaddr_unaligned +
|
||||||
((unsigned long)(rx_tid->hw_qdesc_vaddr_unaligned) %
|
((unsigned long)(rx_tid->hw_qdesc_vaddr_unaligned) %
|
||||||
hw_qdesc_align);
|
hw_qdesc_align);
|
||||||
|
|
||||||
rx_tid->hw_qdesc_paddr = rx_tid->hw_qdesc_paddr_unaligned +
|
|
||||||
((unsigned long)hw_qdesc_vaddr -
|
|
||||||
(unsigned long)(rx_tid->hw_qdesc_vaddr_unaligned));
|
|
||||||
} else {
|
} else {
|
||||||
hw_qdesc_vaddr = rx_tid->hw_qdesc_vaddr_unaligned;
|
hw_qdesc_vaddr = rx_tid->hw_qdesc_vaddr_unaligned;
|
||||||
rx_tid->hw_qdesc_paddr = rx_tid->hw_qdesc_paddr_unaligned;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Ensure that sec_type is set before ADDBA is received.
|
/* TODO: Ensure that sec_type is set before ADDBA is received.
|
||||||
@@ -672,6 +677,27 @@ int dp_rx_tid_setup_wifi3(struct dp_peer *peer, int tid,
|
|||||||
hal_reo_qdesc_setup(soc->hal_soc, tid, ba_window_size, start_seq,
|
hal_reo_qdesc_setup(soc->hal_soc, tid, ba_window_size, start_seq,
|
||||||
hw_qdesc_vaddr, rx_tid->hw_qdesc_paddr, hal_pn_type);
|
hw_qdesc_vaddr, rx_tid->hw_qdesc_paddr, hal_pn_type);
|
||||||
|
|
||||||
|
qdf_mem_map_nbytes_single(soc->osdev, rx_tid->hw_qdesc_vaddr_unaligned,
|
||||||
|
QDF_DMA_BIDIRECTIONAL, rx_tid->hw_qdesc_alloc_size,
|
||||||
|
&(rx_tid->hw_qdesc_paddr_unaligned));
|
||||||
|
|
||||||
|
if (dp_reo_desc_addr_chk(rx_tid->hw_qdesc_paddr_unaligned) !=
|
||||||
|
QDF_STATUS_SUCCESS) {
|
||||||
|
if (alloc_tries++ < 10)
|
||||||
|
goto try_desc_alloc;
|
||||||
|
else {
|
||||||
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||||
|
"%s: Rx tid HW desc alloc failed (lowmem): tid %d\n",
|
||||||
|
__func__, tid);
|
||||||
|
return QDF_STATUS_E_NOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rx_tid->hw_qdesc_paddr = rx_tid->hw_qdesc_paddr_unaligned +
|
||||||
|
((unsigned long)hw_qdesc_vaddr -
|
||||||
|
(unsigned long)(rx_tid->hw_qdesc_vaddr_unaligned));
|
||||||
|
|
||||||
|
|
||||||
if (soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup) {
|
if (soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup) {
|
||||||
soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup(
|
soc->cdp_soc.ol_ops->peer_rx_reorder_queue_setup(
|
||||||
vdev->pdev->osif_pdev,
|
vdev->pdev->osif_pdev,
|
||||||
@@ -944,7 +970,7 @@ int dp_delba_process_wifi3(void *peer_handle,
|
|||||||
* replace with a new one without queue extenstion descript to save
|
* replace with a new one without queue extenstion descript to save
|
||||||
* memory
|
* memory
|
||||||
*/
|
*/
|
||||||
dp_rx_tid_update_wifi3(peer, tid, 0, 0);
|
dp_rx_tid_update_wifi3(peer, tid, 1, 0);
|
||||||
|
|
||||||
rx_tid->ba_status = DP_RX_BA_INACTIVE;
|
rx_tid->ba_status = DP_RX_BA_INACTIVE;
|
||||||
|
|
||||||
|
@@ -481,8 +481,11 @@ inline int hal_reo_cmd_update_rx_queue(void *reo_ring, struct hal_soc *soc,
|
|||||||
HAL_DESC_SET_FIELD(reo_desc, REO_UPDATE_RX_REO_QUEUE_3,
|
HAL_DESC_SET_FIELD(reo_desc, REO_UPDATE_RX_REO_QUEUE_3,
|
||||||
IGNORE_AMPDU_FLAG, p->ignore_ampdu);
|
IGNORE_AMPDU_FLAG, p->ignore_ampdu);
|
||||||
|
|
||||||
|
if (p->ba_window_size < 1)
|
||||||
|
p->ba_window_size = 1;
|
||||||
|
|
||||||
HAL_DESC_SET_FIELD(reo_desc, REO_UPDATE_RX_REO_QUEUE_4,
|
HAL_DESC_SET_FIELD(reo_desc, REO_UPDATE_RX_REO_QUEUE_4,
|
||||||
BA_WINDOW_SIZE, p->ba_window_size);
|
BA_WINDOW_SIZE, p->ba_window_size - 1);
|
||||||
|
|
||||||
HAL_DESC_SET_FIELD(reo_desc, REO_UPDATE_RX_REO_QUEUE_4,
|
HAL_DESC_SET_FIELD(reo_desc, REO_UPDATE_RX_REO_QUEUE_4,
|
||||||
PN_SIZE, p->pn_size);
|
PN_SIZE, p->pn_size);
|
||||||
|
@@ -136,6 +136,9 @@ void hal_reo_qdesc_setup(void *hal_soc, int tid, uint32_t ba_window_size,
|
|||||||
reg_val = TID_TO_WME_AC(tid);
|
reg_val = TID_TO_WME_AC(tid);
|
||||||
HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, AC, reg_val);
|
HAL_DESC_SET_FIELD(reo_queue_desc, RX_REO_QUEUE_2, AC, reg_val);
|
||||||
|
|
||||||
|
if (ba_window_size < 1)
|
||||||
|
ba_window_size = 1;
|
||||||
|
|
||||||
/* Set RTY bit for non-BA case. Duplicate detection is currently not
|
/* Set RTY bit for non-BA case. Duplicate detection is currently not
|
||||||
* done by HW in non-BA case if RTY bit is not set.
|
* done by HW in non-BA case if RTY bit is not set.
|
||||||
* TODO: This is a temporary War and should be removed once HW fix is
|
* TODO: This is a temporary War and should be removed once HW fix is
|
||||||
|
@@ -210,7 +210,7 @@ static inline uint32_t qdf_mem_map_nbytes_single(qdf_device_t osdev, void *buf,
|
|||||||
* Return: none
|
* Return: none
|
||||||
*/
|
*/
|
||||||
static inline void qdf_mem_unmap_nbytes_single(qdf_device_t osdev,
|
static inline void qdf_mem_unmap_nbytes_single(qdf_device_t osdev,
|
||||||
uint32_t phy_addr,
|
qdf_dma_addr_t phy_addr,
|
||||||
qdf_dma_dir_t dir,
|
qdf_dma_dir_t dir,
|
||||||
int nbytes)
|
int nbytes)
|
||||||
{
|
{
|
||||||
|
@@ -160,7 +160,7 @@ static inline uint32_t __qdf_mem_map_nbytes_single(qdf_device_t osdev,
|
|||||||
* @return - none
|
* @return - none
|
||||||
*/
|
*/
|
||||||
static inline void __qdf_mem_unmap_nbytes_single(qdf_device_t osdev,
|
static inline void __qdf_mem_unmap_nbytes_single(qdf_device_t osdev,
|
||||||
uint32_t phy_addr,
|
qdf_dma_addr_t phy_addr,
|
||||||
qdf_dma_dir_t dir, int nbytes)
|
qdf_dma_dir_t dir, int nbytes)
|
||||||
{
|
{
|
||||||
dma_unmap_single(osdev->dev, phy_addr, nbytes, dir);
|
dma_unmap_single(osdev->dev, phy_addr, nbytes, dir);
|
||||||
|
Reference in New Issue
Block a user