diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 10887de4ae..6d50b2746c 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -245,22 +245,25 @@ dp_rx_process(struct dp_soc *soc, void *hal_ring, uint32_t quota) void *ring_desc; struct dp_rx_desc *rx_desc; qdf_nbuf_t nbuf; - union dp_rx_desc_list_elem_t *head = NULL; - union dp_rx_desc_list_elem_t *tail = NULL; + union dp_rx_desc_list_elem_t *head[MAX_PDEV_CNT] = { NULL }; + union dp_rx_desc_list_elem_t *tail[MAX_PDEV_CNT] = { NULL }; uint32_t rx_bufs_used = 0, rx_buf_cookie, l2_hdr_offset; uint16_t msdu_len; uint16_t peer_id; struct dp_peer *peer = NULL; struct dp_vdev *vdev = NULL; + struct dp_vdev *vdev_list[WLAN_UMAC_PSOC_MAX_VDEVS] = { NULL }; struct hal_rx_mpdu_desc_info mpdu_desc_info; struct hal_rx_msdu_desc_info msdu_desc_info; enum hal_reo_error_status error; uint32_t pkt_len; static uint32_t peer_mdata; uint8_t *rx_tlv_hdr; - uint32_t rx_bufs_reaped = 0; - struct dp_pdev *pdev; + uint32_t rx_bufs_reaped[MAX_PDEV_CNT] = { 0 }; uint32_t sgi, rate_mcs, tid; + uint64_t vdev_map = 0; + uint8_t mac_id; + uint16_t i, vdev_cnt = 0; /* Debug -- Remove later */ qdf_assert(soc && hal_ring); @@ -305,7 +308,7 @@ dp_rx_process(struct dp_soc *soc, void *hal_ring, uint32_t quota) rx_desc = dp_rx_cookie_2_va(soc, rx_buf_cookie); qdf_assert(rx_desc); - rx_bufs_reaped++; + rx_bufs_reaped[rx_desc->pool_id]++; /* TODO */ /* @@ -336,6 +339,13 @@ dp_rx_process(struct dp_soc *soc, void *hal_ring, uint32_t quota) FL("vdev is NULL")); qdf_nbuf_free(rx_desc->nbuf); goto fail; + + } + + if (!((vdev_map >> vdev->vdev_id) & 1)) { + vdev_map |= 1 << vdev->vdev_id; + vdev_list[vdev_cnt] = vdev; + vdev_cnt++; } /* Get MSDU DESC info */ @@ -356,31 +366,33 @@ dp_rx_process(struct dp_soc *soc, void *hal_ring, uint32_t quota) qdf_nbuf_queue_add(&vdev->rxq, rx_desc->nbuf); fail: - dp_rx_add_to_free_desc_list(&head, &tail, rx_desc); + dp_rx_add_to_free_desc_list(&head[rx_desc->pool_id], + &tail[rx_desc->pool_id], + rx_desc); } done: hal_srng_access_end(hal_soc, hal_ring); - if (!rx_bufs_reaped) - return 0; - else - /* Replenish buffers */ - /* Assume MAC id = 0, owner = 0 */ - dp_rx_buffers_replenish(soc, 0, rx_bufs_reaped, &head, &tail, + for (mac_id = 0; mac_id < MAX_PDEV_CNT; mac_id++) { + /* + * continue with next mac_id if no pkts were reaped + * from that pool + */ + if (!rx_bufs_reaped[mac_id]) + continue; + + dp_rx_buffers_replenish(soc, mac_id, + rx_bufs_reaped[mac_id], + &head[mac_id], + &tail[mac_id], HAL_RX_BUF_RBM_SW3_BM); - - pdev = soc->pdev_list[0]; - - if (qdf_unlikely(!pdev)) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - FL("pdev is NULL")); - goto fail1; } - TAILQ_FOREACH(vdev, &pdev->vdev_list, vdev_list_elem) { + for (i = 0; i < vdev_cnt; i++) { qdf_nbuf_t deliver_list_head = NULL; qdf_nbuf_t deliver_list_tail = NULL; + vdev = vdev_list[i]; while ((nbuf = qdf_nbuf_queue_remove(&vdev->rxq))) { rx_tlv_hdr = qdf_nbuf_data(nbuf); @@ -494,9 +506,6 @@ done: } return rx_bufs_used; /* Assume no scale factor for now */ -fail1: - qdf_assert(0); - return 0; } /** diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index baf84b9704..64c629d269 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -62,7 +62,7 @@ struct dp_rx_desc { qdf_nbuf_t nbuf; uint8_t *rx_buf_start; - uint16_t cookie; + uint32_t cookie; uint8_t pool_id; }; diff --git a/dp/wifi3.0/dp_rx_desc.c b/dp/wifi3.0/dp_rx_desc.c index 54799e444c..f6e5887242 100644 --- a/dp/wifi3.0/dp_rx_desc.c +++ b/dp/wifi3.0/dp_rx_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017 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 @@ -56,10 +56,12 @@ QDF_STATUS dp_rx_desc_pool_alloc(struct dp_soc *soc, uint32_t pool_id) &soc->rx_desc[pool_id].array[i+1]; soc->rx_desc[pool_id].array[i].rx_desc.cookie = i | (pool_id << 18); + soc->rx_desc[pool_id].array[i].rx_desc.pool_id = pool_id; } soc->rx_desc[pool_id].array[i].next = NULL; soc->rx_desc[pool_id].array[i].rx_desc.cookie = i | (pool_id << 18); + soc->rx_desc[pool_id].array[i].rx_desc.pool_id = pool_id; qdf_spin_unlock_bh(&soc->rx_desc_mutex[pool_id]); return QDF_STATUS_SUCCESS; } diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index 13eb6a5ca8..54984abddd 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -231,7 +231,7 @@ dp_rx_2k_jump_handle(struct dp_soc *soc, void *ring_desc, * REO or WBM ring * * @soc: core DP main context -* @ring_desc: opaque pointer to the REO error ring descriptor +* @rx_desc : pointer to the sw rx descriptor * @head: pointer to head of rx descriptors to be added to free list * @tail: pointer to tail of rx descriptors to be added to free list * quota: upper limit of descriptors that can be reaped @@ -247,29 +247,20 @@ dp_rx_2k_jump_handle(struct dp_soc *soc, void *ring_desc, * Return: uint32_t: No. of Rx buffers reaped */ static uint32_t -dp_rx_null_q_desc_handle(struct dp_soc *soc, void *ring_desc, +dp_rx_null_q_desc_handle(struct dp_soc *soc, struct dp_rx_desc *rx_desc, union dp_rx_desc_list_elem_t **head, union dp_rx_desc_list_elem_t **tail, uint32_t quota) { - uint32_t rx_buf_cookie; - struct dp_rx_desc *rx_desc; uint32_t rx_bufs_used = 0; uint32_t pkt_len, l2_hdr_offset; uint16_t msdu_len; qdf_nbuf_t nbuf; - struct dp_pdev *pdev0; - struct dp_vdev *vdev0; + struct dp_vdev *vdev; uint16_t peer_id = 0xFFFF; struct dp_peer *peer = NULL; uint32_t sgi, rate_mcs, tid; - rx_buf_cookie = HAL_RX_WBM_BUF_COOKIE_GET(ring_desc); - - rx_desc = dp_rx_cookie_2_va(soc, rx_buf_cookie); - - qdf_assert(rx_desc); - rx_bufs_used++; nbuf = rx_desc->nbuf; @@ -300,6 +291,16 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, void *ring_desc, qdf_assert(0); } + 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) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, + FL("peer is NULL")); + qdf_nbuf_free(nbuf); + goto fail; + } + sgi = hal_rx_msdu_start_sgi_get(rx_desc->rx_buf_start); rate_mcs = hal_rx_msdu_start_rate_mcs_get(rx_desc->rx_buf_start); tid = hal_rx_mpdu_start_tid_get(rx_desc->rx_buf_start); @@ -322,11 +323,6 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, void *ring_desc, /* 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 */ @@ -344,7 +340,7 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, void *ring_desc, qdf_nbuf_data(nbuf), 128, false); #endif /* NAPIER_EMULATION */ - if (peer && qdf_unlikely(peer->bss_peer)) { + if (qdf_unlikely(peer->bss_peer)) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, FL("received pkt with same src MAC")); @@ -355,23 +351,18 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, void *ring_desc, goto fail; } - pdev0 = soc->pdev_list[0];/* Hard code 0th elem */ + vdev = peer->vdev; - if (pdev0) { - vdev0 = (struct dp_vdev *)TAILQ_FIRST(&pdev0->vdev_list); - if (vdev0 && vdev0->osif_rx) { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, - FL("pdev0 %p vdev0 %p osif_rx %p"), pdev0, vdev0, - vdev0->osif_rx); - qdf_nbuf_set_next(nbuf, NULL); - vdev0->osif_rx(vdev0->osif_vdev, nbuf); - } else { - QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - FL("INVALID vdev0 %p OR osif_rx"), vdev0); - } + if (vdev && vdev->osif_rx) { + QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, + FL("vdev %p osif_rx %p"), vdev, + vdev->osif_rx); + + qdf_nbuf_set_next(nbuf, NULL); + vdev->osif_rx(vdev->osif_vdev, nbuf); } else { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR, - FL("INVALID pdev %p"), pdev0); + FL("INVALID vdev %p OR osif_rx"), vdev); } fail: @@ -549,7 +540,7 @@ done: /* Assume MAC id = 0, owner = 0 */ if (rx_bufs_used) dp_rx_buffers_replenish(soc, 0, rx_bufs_used, &head, &tail, - HAL_RX_BUF_RBM_SW3_BM); + HAL_RX_BUF_RBM_SW3_BM); return rx_bufs_used; /* Assume no scale factor for now */ } @@ -572,12 +563,14 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota) void *hal_soc; void *ring_desc; struct dp_rx_desc *rx_desc; - union dp_rx_desc_list_elem_t *head = NULL; - union dp_rx_desc_list_elem_t *tail = NULL; - uint32_t rx_bufs_used = 0; + union dp_rx_desc_list_elem_t *head[MAX_PDEV_CNT] = { NULL }; + union dp_rx_desc_list_elem_t *tail[MAX_PDEV_CNT] = { NULL }; + uint32_t rx_bufs_used[MAX_PDEV_CNT] = { 0 }; + uint32_t rx_bufs_reaped = 0; uint8_t buf_type, rbm; uint8_t wbm_err_src; uint32_t rx_buf_cookie; + uint8_t mac_id; /* Debug -- Remove later */ qdf_assert(soc && hal_ring); @@ -623,6 +616,11 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota) continue; } + rx_buf_cookie = HAL_RX_WBM_BUF_COOKIE_GET(ring_desc); + + rx_desc = dp_rx_cookie_2_va(soc, rx_buf_cookie); + qdf_assert(rx_desc); + /* XXX */ buf_type = HAL_RX_WBM_BUF_TYPE_GET(ring_desc); /* @@ -650,9 +648,12 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota) QDF_TRACE_LEVEL_WARN, "Got pkt with REO ERROR: %d", reo_error_code); - rx_bufs_used += + + rx_bufs_used[rx_desc->pool_id] += dp_rx_null_q_desc_handle(soc, - ring_desc, &head, &tail, quota); + rx_desc, + &head[rx_desc->pool_id], + &tail[rx_desc->pool_id], quota); continue; /* TODO */ /* Add per error code accounting */ @@ -689,29 +690,31 @@ dp_rx_wbm_err_process(struct dp_soc *soc, void *hal_ring, uint32_t quota) /* Should not come here */ qdf_assert(0); } - rx_buf_cookie = HAL_RX_WBM_BUF_COOKIE_GET(ring_desc); - rx_desc = dp_rx_cookie_2_va(soc, rx_buf_cookie); - - qdf_assert(rx_desc); - - rx_bufs_used++; + rx_bufs_used[rx_desc->pool_id]++; qdf_nbuf_unmap_single(soc->osdev, rx_desc->nbuf, QDF_DMA_BIDIRECTIONAL); qdf_nbuf_free(rx_desc->nbuf); - dp_rx_add_to_free_desc_list(&head, &tail, rx_desc); + dp_rx_add_to_free_desc_list(&head[rx_desc->pool_id], + &tail[rx_desc->pool_id], rx_desc); } done: hal_srng_access_end(hal_soc, hal_ring); /* Assume MAC id = 0, owner = 0 */ - if (rx_bufs_used) - dp_rx_buffers_replenish(soc, 0, rx_bufs_used, &head, &tail, - HAL_RX_BUF_RBM_SW3_BM); + for (mac_id = 0; mac_id < MAX_PDEV_CNT; mac_id++) { + if (rx_bufs_used[mac_id]) { + dp_rx_buffers_replenish(soc, mac_id, + rx_bufs_used[mac_id], + &head[mac_id], &tail[mac_id], + HAL_RX_BUF_RBM_SW3_BM); + rx_bufs_reaped += rx_bufs_used[mac_id]; + } + } - return rx_bufs_used; /* Assume no scale factor for now */ + return rx_bufs_reaped; /* Assume no scale factor for now */ } diff --git a/dp/wifi3.0/hal_rx.h b/dp/wifi3.0/hal_rx.h index c1a765815d..ed03f707d5 100644 --- a/dp/wifi3.0/hal_rx.h +++ b/dp/wifi3.0/hal_rx.h @@ -399,7 +399,7 @@ static inline void hal_rx_msdu_desc_info_get(void *desc_addr, * */ static inline void hal_rxdma_buff_addr_info_set(void *rxdma_entry, - qdf_dma_addr_t paddr, uint16_t cookie, uint8_t manager) + qdf_dma_addr_t paddr, uint32_t cookie, uint8_t manager) { uint32_t paddr_lo = ((u64)paddr & 0x00000000ffffffff); uint32_t paddr_hi = ((u64)paddr & 0xffffffff00000000) >> 32;