diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index 67800185d6..63e5a5ec7c 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -715,6 +715,10 @@ int htt_srng_setup(struct htt_soc *soc, int mac_id, htt_ring_id = HTT_TX_MON_MON2HOST_DEST_RING; htt_ring_type = HTT_HW_TO_SW_RING; break; + case SW2RXDMA_LINK_RELEASE: + htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING; + htt_ring_type = HTT_SW_TO_HW_RING; + break; default: QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index 167d3ef06c..fb14e8797b 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -679,6 +679,18 @@ dp_monitor_get_link_desc_pages(struct dp_soc *soc, uint32_t mac_id) return NULL; } +static inline struct dp_srng* +dp_monitor_get_link_desc_ring(struct dp_soc *soc, uint32_t mac_id) +{ + return NULL; +} + +static inline uint32_t +dp_monitor_get_num_link_desc_ring_entries(struct dp_soc *soc) +{ + return 0; +} + static inline uint32_t * dp_monitor_get_total_link_descs(struct dp_soc *soc, uint32_t mac_id) { diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 2e1e158af9..62f0b8bc5e 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -1696,6 +1696,138 @@ static QDF_STATUS dp_soc_interrupt_attach_wrapper(struct cdp_soc_t *txrx_soc) #endif #endif +void dp_link_desc_ring_replenish(struct dp_soc *soc, uint32_t mac_id) +{ + uint32_t cookie = 0; + uint32_t page_idx = 0; + struct qdf_mem_multi_page_t *pages; + struct qdf_mem_dma_page_t *dma_pages; + uint32_t offset = 0; + uint32_t count = 0; + uint32_t desc_id = 0; + void *desc_srng; + int link_desc_size = hal_get_link_desc_size(soc->hal_soc); + uint32_t *total_link_descs_addr; + uint32_t total_link_descs; + uint32_t scatter_buf_num; + uint32_t num_entries_per_buf = 0; + uint32_t rem_entries; + uint32_t num_descs_per_page; + uint32_t num_scatter_bufs = 0; + uint8_t *scatter_buf_ptr; + void *desc; + + num_scatter_bufs = soc->num_scatter_bufs; + + if (mac_id == WLAN_INVALID_PDEV_ID) { + pages = &soc->link_desc_pages; + total_link_descs = soc->total_link_descs; + desc_srng = soc->wbm_idle_link_ring.hal_srng; + } else { + pages = dp_monitor_get_link_desc_pages(soc, mac_id); + /* dp_monitor_get_link_desc_pages returns NULL only + * if monitor SOC is NULL + */ + if (!pages) { + dp_err("can not get link desc pages"); + QDF_ASSERT(0); + return; + } + total_link_descs_addr = + dp_monitor_get_total_link_descs(soc, mac_id); + total_link_descs = *total_link_descs_addr; + desc_srng = dp_monitor_get_link_desc_ring(soc, mac_id); + } + + dma_pages = pages->dma_pages; + do { + qdf_mem_zero(dma_pages[page_idx].page_v_addr_start, + pages->page_size); + page_idx++; + } while (page_idx < pages->num_pages); + + if (desc_srng) { + hal_srng_access_start_unlocked(soc->hal_soc, desc_srng); + page_idx = 0; + count = 0; + offset = 0; + while ((desc = hal_srng_src_get_next(soc->hal_soc, + desc_srng)) && + (count < total_link_descs)) { + page_idx = count / pages->num_element_per_page; + if (desc_id == pages->num_element_per_page) + desc_id = 0; + + offset = count % pages->num_element_per_page; + cookie = LINK_DESC_COOKIE(desc_id, page_idx, + soc->link_desc_id_start); + + hal_set_link_desc_addr(soc->hal_soc, desc, cookie, + dma_pages[page_idx].page_p_addr + + (offset * link_desc_size), + soc->idle_link_bm_id); + count++; + desc_id++; + } + hal_srng_access_end_unlocked(soc->hal_soc, desc_srng); + } else { + /* Populate idle list scatter buffers with link descriptor + * pointers + */ + scatter_buf_num = 0; + num_entries_per_buf = hal_idle_scatter_buf_num_entries( + soc->hal_soc, + soc->wbm_idle_scatter_buf_size); + + scatter_buf_ptr = (uint8_t *)( + soc->wbm_idle_scatter_buf_base_vaddr[scatter_buf_num]); + rem_entries = num_entries_per_buf; + page_idx = 0; count = 0; + offset = 0; + num_descs_per_page = pages->num_element_per_page; + + while (count < total_link_descs) { + page_idx = count / num_descs_per_page; + offset = count % num_descs_per_page; + if (desc_id == pages->num_element_per_page) + desc_id = 0; + + cookie = LINK_DESC_COOKIE(desc_id, page_idx, + soc->link_desc_id_start); + hal_set_link_desc_addr(soc->hal_soc, + (void *)scatter_buf_ptr, + cookie, + dma_pages[page_idx].page_p_addr + + (offset * link_desc_size), + soc->idle_link_bm_id); + rem_entries--; + if (rem_entries) { + scatter_buf_ptr += link_desc_size; + } else { + rem_entries = num_entries_per_buf; + scatter_buf_num++; + if (scatter_buf_num >= num_scatter_bufs) + break; + scatter_buf_ptr = (uint8_t *) + (soc->wbm_idle_scatter_buf_base_vaddr[ + scatter_buf_num]); + } + count++; + desc_id++; + } + /* Setup link descriptor idle list in HW */ + hal_setup_link_idle_list(soc->hal_soc, + soc->wbm_idle_scatter_buf_base_paddr, + soc->wbm_idle_scatter_buf_base_vaddr, + num_scatter_bufs, soc->wbm_idle_scatter_buf_size, + (uint32_t)(scatter_buf_ptr - + (uint8_t *)(soc->wbm_idle_scatter_buf_base_vaddr[ + scatter_buf_num-1])), total_link_descs); + } +} + +qdf_export_symbol(dp_link_desc_ring_replenish); + /** * dp_soc_ppeds_stop() - Stop PPE DS processing * @soc_handle: DP SOC handle diff --git a/dp/wifi3.0/dp_rings.h b/dp/wifi3.0/dp_rings.h index a69c59ff48..a80533537c 100644 --- a/dp/wifi3.0/dp_rings.h +++ b/dp/wifi3.0/dp_rings.h @@ -26,6 +26,23 @@ #include #endif +#ifdef WLAN_FEATURE_DP_EVENT_HISTORY +static inline bool dp_is_mon_mask_valid(struct dp_soc *soc, + struct dp_intr *intr_ctx) +{ + if (intr_ctx->rx_mon_ring_mask) + return true; + + return false; +} +#else +static inline bool dp_is_mon_mask_valid(struct dp_soc *soc, + struct dp_intr *intr_ctx) +{ + return false; +} +#endif + #ifndef QCA_HOST_MODE_WIFI_DISABLED /** @@ -651,11 +668,24 @@ static inline QDF_STATUS dp_soc_srng_alloc(struct dp_soc *soc) static inline QDF_STATUS dp_soc_attach_poll(struct cdp_soc_t *txrx_soc) { struct dp_soc *soc = (struct dp_soc *)txrx_soc; + uint32_t lmac_id = 0; + int i; qdf_mem_set(&soc->mon_intr_id_lmac_map, sizeof(soc->mon_intr_id_lmac_map), DP_MON_INVALID_LMAC_ID); soc->intr_mode = DP_INTR_POLL; + for (i = 0; i < wlan_cfg_get_num_contexts(soc->wlan_cfg_ctx); i++) { + soc->intr_ctx[i].rx_mon_ring_mask = + wlan_cfg_get_rx_mon_ring_mask(soc->wlan_cfg_ctx, i); + + if (dp_is_mon_mask_valid(soc, &soc->intr_ctx[i])) { + hif_event_history_init(soc->hif_handle, i); + soc->mon_intr_id_lmac_map[lmac_id] = i; + lmac_id++; + } + } + qdf_timer_init(soc->osdev, &soc->int_timer, dp_interrupt_timer, (void *)soc, QDF_TIMER_TYPE_WAKE_APPS); diff --git a/dp/wifi3.0/dp_rings_main.c b/dp/wifi3.0/dp_rings_main.c index c9ecec76ef..dfb27fcd30 100644 --- a/dp/wifi3.0/dp_rings_main.c +++ b/dp/wifi3.0/dp_rings_main.c @@ -1447,23 +1447,6 @@ budget_done: #endif /* QCA_HOST_MODE_WIFI_DISABLED */ -#ifdef WLAN_FEATURE_DP_EVENT_HISTORY -static inline bool dp_is_mon_mask_valid(struct dp_soc *soc, - struct dp_intr *intr_ctx) -{ - if (intr_ctx->rx_mon_ring_mask) - return true; - - return false; -} -#else -static inline bool dp_is_mon_mask_valid(struct dp_soc *soc, - struct dp_intr *intr_ctx) -{ - return false; -} -#endif - QDF_STATUS dp_soc_attach_poll(struct cdp_soc_t *txrx_soc) { struct dp_soc *soc = (struct dp_soc *)txrx_soc; @@ -2257,138 +2240,6 @@ void dp_hw_link_desc_ring_deinit(struct dp_soc *soc) dp_srng_deinit(soc, &soc->wbm_idle_link_ring, WBM_IDLE_LINK, 0); } -void dp_link_desc_ring_replenish(struct dp_soc *soc, uint32_t mac_id) -{ - uint32_t cookie = 0; - uint32_t page_idx = 0; - struct qdf_mem_multi_page_t *pages; - struct qdf_mem_dma_page_t *dma_pages; - uint32_t offset = 0; - uint32_t count = 0; - uint32_t desc_id = 0; - void *desc_srng; - int link_desc_size = hal_get_link_desc_size(soc->hal_soc); - uint32_t *total_link_descs_addr; - uint32_t total_link_descs; - uint32_t scatter_buf_num; - uint32_t num_entries_per_buf = 0; - uint32_t rem_entries; - uint32_t num_descs_per_page; - uint32_t num_scatter_bufs = 0; - uint8_t *scatter_buf_ptr; - void *desc; - - num_scatter_bufs = soc->num_scatter_bufs; - - if (mac_id == WLAN_INVALID_PDEV_ID) { - pages = &soc->link_desc_pages; - total_link_descs = soc->total_link_descs; - desc_srng = soc->wbm_idle_link_ring.hal_srng; - } else { - pages = dp_monitor_get_link_desc_pages(soc, mac_id); - /* dp_monitor_get_link_desc_pages returns NULL only - * if monitor SOC is NULL - */ - if (!pages) { - dp_err("can not get link desc pages"); - QDF_ASSERT(0); - return; - } - total_link_descs_addr = - dp_monitor_get_total_link_descs(soc, mac_id); - total_link_descs = *total_link_descs_addr; - desc_srng = soc->rxdma_mon_desc_ring[mac_id].hal_srng; - } - - dma_pages = pages->dma_pages; - do { - qdf_mem_zero(dma_pages[page_idx].page_v_addr_start, - pages->page_size); - page_idx++; - } while (page_idx < pages->num_pages); - - if (desc_srng) { - hal_srng_access_start_unlocked(soc->hal_soc, desc_srng); - page_idx = 0; - count = 0; - offset = 0; - while ((desc = hal_srng_src_get_next(soc->hal_soc, - desc_srng)) && - (count < total_link_descs)) { - page_idx = count / pages->num_element_per_page; - if (desc_id == pages->num_element_per_page) - desc_id = 0; - - offset = count % pages->num_element_per_page; - cookie = LINK_DESC_COOKIE(desc_id, page_idx, - soc->link_desc_id_start); - - hal_set_link_desc_addr(soc->hal_soc, desc, cookie, - dma_pages[page_idx].page_p_addr - + (offset * link_desc_size), - soc->idle_link_bm_id); - count++; - desc_id++; - } - hal_srng_access_end_unlocked(soc->hal_soc, desc_srng); - } else { - /* Populate idle list scatter buffers with link descriptor - * pointers - */ - scatter_buf_num = 0; - num_entries_per_buf = hal_idle_scatter_buf_num_entries( - soc->hal_soc, - soc->wbm_idle_scatter_buf_size); - - scatter_buf_ptr = (uint8_t *)( - soc->wbm_idle_scatter_buf_base_vaddr[scatter_buf_num]); - rem_entries = num_entries_per_buf; - page_idx = 0; count = 0; - offset = 0; - num_descs_per_page = pages->num_element_per_page; - - while (count < total_link_descs) { - page_idx = count / num_descs_per_page; - offset = count % num_descs_per_page; - if (desc_id == pages->num_element_per_page) - desc_id = 0; - - cookie = LINK_DESC_COOKIE(desc_id, page_idx, - soc->link_desc_id_start); - hal_set_link_desc_addr(soc->hal_soc, - (void *)scatter_buf_ptr, - cookie, - dma_pages[page_idx].page_p_addr + - (offset * link_desc_size), - soc->idle_link_bm_id); - rem_entries--; - if (rem_entries) { - scatter_buf_ptr += link_desc_size; - } else { - rem_entries = num_entries_per_buf; - scatter_buf_num++; - if (scatter_buf_num >= num_scatter_bufs) - break; - scatter_buf_ptr = (uint8_t *) - (soc->wbm_idle_scatter_buf_base_vaddr[ - scatter_buf_num]); - } - count++; - desc_id++; - } - /* Setup link descriptor idle list in HW */ - hal_setup_link_idle_list(soc->hal_soc, - soc->wbm_idle_scatter_buf_base_paddr, - soc->wbm_idle_scatter_buf_base_vaddr, - num_scatter_bufs, soc->wbm_idle_scatter_buf_size, - (uint32_t)(scatter_buf_ptr - - (uint8_t *)(soc->wbm_idle_scatter_buf_base_vaddr[ - scatter_buf_num-1])), total_link_descs); - } -} - -qdf_export_symbol(dp_link_desc_ring_replenish); - #ifdef IPA_OFFLOAD #define USE_1_IPA_RX_REO_RING 1 #define USE_2_IPA_RX_REO_RINGS 2 diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 1779d8355d..87f293667d 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -2627,6 +2627,9 @@ struct dp_soc { /* RXDMA monitor status ring. TBD: Check format of this ring */ struct dp_srng rxdma_mon_status_ring[MAX_NUM_LMAC_HW]; + /* Ring to handover links to hw in monitor mode for SOFTUMAC arch */ + struct dp_srng sw2rxdma_link_ring[MAX_NUM_LMAC_HW]; + /* Number of PDEVs */ uint8_t pdev_count; @@ -5174,15 +5177,6 @@ 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, uint32_t mac_id); - -/** - * dp_link_desc_ring_replenish() - Replenish hw link desc rings - * @soc: DP SOC handle - * @mac_id: mac id - * - * Return: None - */ -void dp_link_desc_ring_replenish(struct dp_soc *soc, uint32_t mac_id); #else static inline void dp_hw_link_desc_pool_banks_free(struct dp_soc *soc, uint32_t mac_id) @@ -5194,13 +5188,17 @@ static inline QDF_STATUS dp_hw_link_desc_pool_banks_alloc(struct dp_soc *soc, { return QDF_STATUS_SUCCESS; } - -static inline void dp_link_desc_ring_replenish(struct dp_soc *soc, - uint32_t mac_id) -{ -} #endif +/** + * dp_link_desc_ring_replenish() - Replenish hw link desc rings + * @soc: DP SOC handle + * @mac_id: mac id + * + * Return: None + */ +void dp_link_desc_ring_replenish(struct dp_soc *soc, uint32_t mac_id); + #ifdef WLAN_FEATURE_RX_PREALLOC_BUFFER_POOL void dp_rx_refill_buff_pool_enqueue(struct dp_soc *soc); #else diff --git a/dp/wifi3.0/monitor/1.0/dp_mon_1.0.c b/dp/wifi3.0/monitor/1.0/dp_mon_1.0.c index 82f35d9176..2207aef70b 100644 --- a/dp/wifi3.0/monitor/1.0/dp_mon_1.0.c +++ b/dp/wifi3.0/monitor/1.0/dp_mon_1.0.c @@ -228,6 +228,8 @@ void dp_mon_rings_deinit_1_0(struct dp_pdev *pdev) dp_srng_deinit(soc, &soc->rxdma_mon_status_ring[lmac_id], RXDMA_MONITOR_STATUS, 0); + dp_srng_deinit(soc, &soc->sw2rxdma_link_ring[lmac_id], + SW2RXDMA_LINK_RELEASE, 0); dp_mon_dest_rings_deinit(pdev, lmac_id); } @@ -246,11 +248,46 @@ void dp_mon_rings_free_1_0(struct dp_pdev *pdev) pdev->pdev_id); dp_srng_free(soc, &soc->rxdma_mon_status_ring[lmac_id]); + dp_srng_free(soc, &soc->sw2rxdma_link_ring[lmac_id]); dp_mon_dest_rings_free(pdev, lmac_id); } } +#ifdef WLAN_SOFTUMAC_SUPPORT +static QDF_STATUS +dp_mon_sw2rxdma_link_ring_alloc(struct dp_pdev *pdev, int lmac_id) +{ + struct dp_soc *soc = pdev->soc; + struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx = pdev->wlan_cfg_ctx; + int entries; + + entries = wlan_cfg_get_dma_sw2rxdma_link_ring_size(pdev_cfg_ctx); + + return dp_srng_alloc(soc, &soc->sw2rxdma_link_ring[lmac_id], + SW2RXDMA_LINK_RELEASE, entries, 0); +} + +static QDF_STATUS +dp_mon_sw2rxdma_link_ring_init(struct dp_soc *soc, int lmac_id) +{ + return dp_srng_init(soc, &soc->sw2rxdma_link_ring[lmac_id], + SW2RXDMA_LINK_RELEASE, 0, lmac_id); +} +#else +static QDF_STATUS +dp_mon_sw2rxdma_link_ring_alloc(struct dp_pdev *pdev, int lmac_id) +{ + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS +dp_mon_sw2rxdma_link_ring_init(struct dp_soc *soc, int lmac_id) +{ + return QDF_STATUS_SUCCESS; +} +#endif + QDF_STATUS dp_mon_rings_init_1_0(struct dp_pdev *pdev) { struct dp_soc *soc = pdev->soc; @@ -269,6 +306,11 @@ QDF_STATUS dp_mon_rings_init_1_0(struct dp_pdev *pdev) goto fail1; } + if (dp_mon_sw2rxdma_link_ring_init(soc, lmac_id)) { + dp_mon_err("%pK: " RNG_ERR "sw2rxdma_link_ring", soc); + goto fail1; + } + if (dp_mon_dest_rings_init(pdev, lmac_id)) goto fail1; } @@ -301,6 +343,11 @@ QDF_STATUS dp_mon_rings_alloc_1_0(struct dp_pdev *pdev) goto fail1; } + if (dp_mon_sw2rxdma_link_ring_alloc(pdev, lmac_id)) { + dp_mon_err("%pK: " RNG_ERR "sw2rxdma_link_ring", soc); + goto fail1; + } + if (dp_mon_dest_rings_alloc(pdev, lmac_id)) goto fail1; } @@ -733,6 +780,18 @@ QDF_STATUS dp_mon_htt_srng_setup_1_0(struct dp_soc *soc, return status; } + if (!soc->sw2rxdma_link_ring[mac_id].hal_srng) + return QDF_STATUS_SUCCESS; + + status = htt_srng_setup(soc->htt_handle, mac_for_pdev, + soc->sw2rxdma_link_ring[mac_id].hal_srng, + SW2RXDMA_LINK_RELEASE); + + if (status != QDF_STATUS_SUCCESS) { + dp_mon_err("Failed to send htt srng setup message for sw2rxdma link ring"); + return status; + } + return status; } #else diff --git a/dp/wifi3.0/monitor/1.0/dp_rx_mon_1.0.h b/dp/wifi3.0/monitor/1.0/dp_rx_mon_1.0.h index f6665fa98c..f3ea0cb22d 100644 --- a/dp/wifi3.0/monitor/1.0/dp_rx_mon_1.0.h +++ b/dp/wifi3.0/monitor/1.0/dp_rx_mon_1.0.h @@ -911,6 +911,7 @@ void *dp_rx_cookie_2_mon_link_desc(struct dp_pdev *pdev, return dp_rx_cookie_2_link_desc_va(pdev->soc, buf_info); } +#ifndef WLAN_SOFTUMAC_SUPPORT /** * dp_rx_monitor_link_desc_return() - Return Link descriptor based on target * @pdev: core physical device context @@ -933,6 +934,17 @@ QDF_STATUS dp_rx_monitor_link_desc_return(struct dp_pdev *pdev, return dp_rx_link_desc_return_by_addr(pdev->soc, p_last_buf_addr_info, bm_action); } +#else +static inline +QDF_STATUS dp_rx_monitor_link_desc_return(struct dp_pdev *pdev, + hal_buff_addrinfo_t + p_last_buf_addr_info, + uint8_t mac_id, uint8_t bm_action) +{ + return dp_rx_mon_link_desc_return(pdev, p_last_buf_addr_info, + mac_id); +} +#endif static inline bool dp_is_rxdma_dst_ring_common(struct dp_pdev *pdev) { diff --git a/dp/wifi3.0/monitor/1.0/dp_rx_mon_dest_1.0.c b/dp/wifi3.0/monitor/1.0/dp_rx_mon_dest_1.0.c index 6b13fe760d..3b50002a31 100644 --- a/dp/wifi3.0/monitor/1.0/dp_rx_mon_dest_1.0.c +++ b/dp/wifi3.0/monitor/1.0/dp_rx_mon_dest_1.0.c @@ -105,7 +105,6 @@ QDF_STATUS dp_rx_mon_link_desc_return(struct dp_pdev *dp_pdev, hal_buff_addrinfo_t buf_addr_info, int mac_id) { - struct dp_srng *dp_srng; hal_ring_handle_t hal_ring_hdl; hal_soc_handle_t hal_soc; QDF_STATUS status = QDF_STATUS_E_FAILURE; @@ -113,8 +112,7 @@ dp_rx_mon_link_desc_return(struct dp_pdev *dp_pdev, hal_soc = dp_pdev->soc->hal_soc; - dp_srng = &dp_pdev->soc->rxdma_mon_desc_ring[mac_id]; - hal_ring_hdl = dp_srng->hal_srng; + hal_ring_hdl = dp_monitor_get_link_desc_ring(dp_pdev->soc, mac_id); qdf_assert(hal_ring_hdl); @@ -1186,6 +1184,108 @@ dp_rx_mon_check_n_drop_mpdu(struct dp_pdev *pdev, uint32_t mac_id, #endif #endif +#ifdef WLAN_SOFTUMAC_SUPPORT +static void dp_mon_hw_link_desc_bank_free(struct dp_soc *soc, uint32_t mac_id) +{ + struct qdf_mem_multi_page_t *pages; + + pages = dp_monitor_get_link_desc_pages(soc, mac_id); + if (!pages) { + dp_err("can not get mon link desc pages"); + QDF_ASSERT(0); + return; + } + + if (pages->dma_pages) { + wlan_minidump_remove((void *) + pages->dma_pages->page_v_addr_start, + pages->num_pages * pages->page_size, + soc->ctrl_psoc, + WLAN_MD_DP_SRNG_SW2RXDMA_LINK_RING, + "mon hw_link_desc_bank"); + dp_desc_multi_pages_mem_free(soc, QDF_DP_HW_LINK_DESC_TYPE, + pages, 0, false); + } +} + +static QDF_STATUS +dp_mon_hw_link_desc_bank_alloc(struct dp_soc *soc, uint32_t mac_id) +{ + struct qdf_mem_multi_page_t *pages; + uint32_t *total_link_descs, total_mem_size; + uint32_t num_entries; + uint32_t max_alloc_size = wlan_cfg_max_alloc_size(soc->wlan_cfg_ctx); + int link_desc_size = hal_get_link_desc_size(soc->hal_soc); + int link_desc_align = hal_get_link_desc_align(soc->hal_soc); + uint8_t minidump_str[MINIDUMP_STR_SIZE]; + + pages = dp_monitor_get_link_desc_pages(soc, mac_id); + if (!pages) { + dp_err("can not get mon link desc pages"); + QDF_ASSERT(0); + return QDF_STATUS_E_FAULT; + } + + /* If link descriptor banks are allocated, return from here */ + if (pages->num_pages) + return QDF_STATUS_SUCCESS; + + num_entries = dp_monitor_get_num_link_desc_ring_entries(soc, mac_id); + total_link_descs = dp_monitor_get_total_link_descs(soc, mac_id); + qdf_str_lcopy(minidump_str, "mon_link_desc_bank", + MINIDUMP_STR_SIZE); + + /* Round up to power of 2 */ + *total_link_descs = 1; + while (*total_link_descs < num_entries) + *total_link_descs <<= 1; + + dp_init_info("%pK: total_link_descs: %u, link_desc_size: %d", + soc, *total_link_descs, link_desc_size); + + total_mem_size = *total_link_descs * link_desc_size; + total_mem_size += link_desc_align; + + dp_init_info("%pK: total_mem_size: %d", soc, total_mem_size); + + dp_set_max_page_size(pages, max_alloc_size); + dp_desc_multi_pages_mem_alloc(soc, QDF_DP_HW_LINK_DESC_TYPE, + pages, link_desc_size, + *total_link_descs, 0, false); + + if (!pages->num_pages) { + dp_err("Multi page alloc fail for mon hw link desc pool"); + return QDF_STATUS_E_FAULT; + } + + wlan_minidump_log(pages->dma_pages->page_v_addr_start, + pages->num_pages * pages->page_size, + soc->ctrl_psoc, + WLAN_MD_DP_SRNG_SW2RXDMA_LINK_RING, + "mon hw_link_desc_bank"); + + return QDF_STATUS_SUCCESS; +} + +static void +dp_mon_link_desc_ring_replenish(struct dp_soc *soc, int mac_id) +{ + dp_link_desc_ring_replenish(soc, mac_id); +} +#else +static QDF_STATUS +dp_mon_hw_link_desc_bank_alloc(struct dp_soc *soc, uint32_t mac_id) +{ + return QDF_STATUS_SUCCESS; +} + +static void +dp_mon_hw_link_desc_bank_free(struct dp_soc *soc, uint32_t mac_id) {} + +static void +dp_mon_link_desc_ring_replenish(struct dp_soc *soc, int mac_id) {} +#endif + static void dp_rx_pdev_mon_cmn_desc_pool_free(struct dp_pdev *pdev, int mac_id) { @@ -1194,6 +1294,7 @@ dp_rx_pdev_mon_cmn_desc_pool_free(struct dp_pdev *pdev, int mac_id) int mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id); dp_rx_pdev_mon_status_desc_pool_free(pdev, mac_for_pdev); + dp_mon_hw_link_desc_bank_free(soc, mac_for_pdev); dp_rx_pdev_mon_dest_desc_pool_free(pdev, mac_for_pdev); } @@ -1235,6 +1336,7 @@ dp_rx_pdev_mon_cmn_desc_pool_init(struct dp_pdev *pdev, int mac_id) mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev->pdev_id); dp_rx_pdev_mon_status_desc_pool_init(pdev, mac_for_pdev); + dp_mon_link_desc_ring_replenish(soc, mac_for_pdev); dp_rx_pdev_mon_dest_desc_pool_init(pdev, mac_for_pdev); } @@ -1326,12 +1428,23 @@ dp_rx_pdev_mon_cmn_desc_pool_alloc(struct dp_pdev *pdev, int mac_id) goto fail; } + /* Allocate hw link desc bank for monitor mode for + * SOFTUMAC architecture. + */ + status = dp_mon_hw_link_desc_bank_alloc(soc, mac_for_pdev); + if (!QDF_IS_STATUS_SUCCESS(status)) { + dp_err("dp_mon_hw_link_desc_bank_alloc() failed"); + goto mon_status_dealloc; + } + status = dp_rx_pdev_mon_dest_desc_pool_alloc(pdev, mac_for_pdev); if (!QDF_IS_STATUS_SUCCESS(status)) - goto mon_status_dealloc; + goto link_desc_bank_free; return status; +link_desc_bank_free: + dp_mon_hw_link_desc_bank_free(soc, mac_for_pdev); mon_status_dealloc: dp_rx_pdev_mon_status_desc_pool_free(pdev, mac_for_pdev); fail: diff --git a/dp/wifi3.0/monitor/dp_mon.h b/dp/wifi3.0/monitor/dp_mon.h index 8bc2e2d18c..e6cf009953 100644 --- a/dp/wifi3.0/monitor/dp_mon.h +++ b/dp/wifi3.0/monitor/dp_mon.h @@ -1826,6 +1826,49 @@ dp_monitor_get_link_desc_pages(struct dp_soc *soc, uint32_t mac_id) return &soc->monitor_soc->mon_link_desc_pages[mac_id]; } +#ifndef WLAN_SOFTUMAC_SUPPORT +/* + * dp_monitor_get_link_desc_ring() - Get link desc ring + * @soc: point to soc + * @mac_id: mac id + * + * Return: return point to link desc ring + */ +static inline hal_ring_handle_t +dp_monitor_get_link_desc_ring(struct dp_soc *soc, uint32_t mac_id) +{ + return soc->rxdma_mon_desc_ring[mac_id].hal_srng; +} + +static inline uint32_t +dp_monitor_get_num_link_desc_ring_entries(struct dp_soc *soc, uint32_t mac_id) +{ + struct dp_srng *ring; + + ring = &soc->rxdma_mon_desc_ring[mac_id]; + + return ring->alloc_size / hal_srng_get_entrysize(soc->hal_soc, + RXDMA_MONITOR_DESC); +} +#else +static inline hal_ring_handle_t +dp_monitor_get_link_desc_ring(struct dp_soc *soc, uint32_t mac_id) +{ + return soc->sw2rxdma_link_ring[mac_id].hal_srng; +} + +static inline uint32_t +dp_monitor_get_num_link_desc_ring_entries(struct dp_soc *soc, uint32_t mac_id) +{ + struct dp_srng *ring; + + ring = &soc->sw2rxdma_link_ring[mac_id]; + + return ring->alloc_size / hal_srng_get_entrysize(soc->hal_soc, + SW2RXDMA_LINK_RELEASE); +} +#endif + /** * dp_monitor_get_total_link_descs() - Get total link descs * @soc: point to soc diff --git a/hal/wifi3.0/hal_internal.h b/hal/wifi3.0/hal_internal.h index 89cf1d2586..e1f8afe139 100644 --- a/hal/wifi3.0/hal_internal.h +++ b/hal/wifi3.0/hal_internal.h @@ -349,7 +349,8 @@ enum hal_srng_ring_id { #endif HAL_SRNG_WMAC1_TXMON2SW0, HAL_SRNG_SW2TXMON_BUF0, - HAL_SRNG_LMAC1_ID_END = (HAL_SRNG_SW2TXMON_BUF0 + 2), + HAL_SRNG_WMAC1_SW2RXDMA_LINK_RING = HAL_SRNG_SW2TXMON_BUF0 + 2, + HAL_SRNG_LMAC1_ID_END = HAL_SRNG_WMAC1_SW2RXDMA_LINK_RING, }; #define HAL_SRNG_DMAC_CMN_ID_END 0 @@ -395,6 +396,7 @@ enum hal_ring_type { TX_MONITOR_BUF, TX_MONITOR_DST, SW2RXDMA_NEW, + SW2RXDMA_LINK_RELEASE, MAX_RING_TYPES }; diff --git a/hal/wifi3.0/kiwi/hal_kiwi.c b/hal/wifi3.0/kiwi/hal_kiwi.c index f091d13c2b..d25008d457 100644 --- a/hal/wifi3.0/kiwi/hal_kiwi.c +++ b/hal/wifi3.0/kiwi/hal_kiwi.c @@ -2821,6 +2821,7 @@ struct hal_hw_srng_config hw_srng_table_kiwi[] = { {0}, #endif { /* SW2RXDMA_NEW */ 0}, + { /* SW2RXDMA_LINK_RELEASE */ 0}, }; /** diff --git a/hal/wifi3.0/qca5018/hal_5018.c b/hal/wifi3.0/qca5018/hal_5018.c index e3e32db18e..8b2c7d8b98 100644 --- a/hal/wifi3.0/qca5018/hal_5018.c +++ b/hal/wifi3.0/qca5018/hal_5018.c @@ -2300,6 +2300,7 @@ struct hal_hw_srng_config hw_srng_table_5018[] = { { /* TX_MONITOR_BUF */ 0}, { /* TX_MONITOR_DST */ 0}, { /* SW2RXDMA_NEW */ 0}, + { /* SW2RXDMA_LINK_RELEASE */ 0}, }; /** diff --git a/hal/wifi3.0/qca5332/hal_5332.c b/hal/wifi3.0/qca5332/hal_5332.c index 03cc27fe1f..85c3a2ace3 100644 --- a/hal/wifi3.0/qca5332/hal_5332.c +++ b/hal/wifi3.0/qca5332/hal_5332.c @@ -2095,6 +2095,7 @@ struct hal_hw_srng_config hw_srng_table_5332[] = { .max_size = HAL_RXDMA_MAX_RING_SIZE_BE, .dmac_cmn_ring = TRUE, }, + { /* SW2RXDMA_LINK_RELEASE */ 0}, }; /** diff --git a/hal/wifi3.0/qca6290/hal_6290.c b/hal/wifi3.0/qca6290/hal_6290.c index 66e73edef4..c818d01004 100644 --- a/hal/wifi3.0/qca6290/hal_6290.c +++ b/hal/wifi3.0/qca6290/hal_6290.c @@ -1648,6 +1648,7 @@ struct hal_hw_srng_config hw_srng_table_6290[] = { { /* TX_MONITOR_BUF */ 0}, { /* TX_MONITOR_DST */ 0}, { /* SW2RXDMA_NEW */ 0}, + { /* SW2RXDMA_LINK_RELEASE */ 0}, }; /** diff --git a/hal/wifi3.0/qca6390/hal_6390.c b/hal/wifi3.0/qca6390/hal_6390.c index 85da3ed229..71b4c80ae8 100644 --- a/hal/wifi3.0/qca6390/hal_6390.c +++ b/hal/wifi3.0/qca6390/hal_6390.c @@ -1734,6 +1734,7 @@ struct hal_hw_srng_config hw_srng_table_6390[] = { { /* TX_MONITOR_BUF */ 0}, { /* TX_MONITOR_DST */ 0}, { /* SW2RXDMA_NEW */ 0}, + { /* SW2RXDMA_LINK_RELEASE */ 0}, }; /** diff --git a/hal/wifi3.0/qca6490/hal_6490.c b/hal/wifi3.0/qca6490/hal_6490.c index 57ac6d406c..6f0b9d9f1f 100644 --- a/hal/wifi3.0/qca6490/hal_6490.c +++ b/hal/wifi3.0/qca6490/hal_6490.c @@ -2371,6 +2371,7 @@ struct hal_hw_srng_config hw_srng_table_6490[] = { { /* TX_MONITOR_BUF */ 0}, { /* TX_MONITOR_DST */ 0}, { /* SW2RXDMA_NEW */ 0}, + { /* SW2RXDMA_LINK_RELEASE */ 0}, }; /** diff --git a/hal/wifi3.0/qca6750/hal_6750.c b/hal/wifi3.0/qca6750/hal_6750.c index e4d668de81..15fb9aa2d9 100644 --- a/hal/wifi3.0/qca6750/hal_6750.c +++ b/hal/wifi3.0/qca6750/hal_6750.c @@ -2512,6 +2512,7 @@ struct hal_hw_srng_config hw_srng_table_6750[] = { { /* TX_MONITOR_BUF */ 0}, { /* TX_MONITOR_DST */ 0}, { /* SW2RXDMA_NEW */ 0}, + { /* SW2RXDMA_LINK_RELEASE */ 0}, }; /** diff --git a/hal/wifi3.0/qca8074v1/hal_8074v1.c b/hal/wifi3.0/qca8074v1/hal_8074v1.c index 4f0ad64584..a573efc8ea 100644 --- a/hal/wifi3.0/qca8074v1/hal_8074v1.c +++ b/hal/wifi3.0/qca8074v1/hal_8074v1.c @@ -1844,6 +1844,7 @@ struct hal_hw_srng_config hw_srng_table_8074[] = { { /* TX_MONITOR_BUF */ 0}, { /* TX_MONITOR_DST */ 0}, { /* SW2RXDMA_NEW */ 0}, + { /* SW2RXDMA_LINK_RELEASE */ 0}, }; /** diff --git a/hal/wifi3.0/qca8074v2/hal_8074v2.c b/hal/wifi3.0/qca8074v2/hal_8074v2.c index 1540d1173b..6b0c293897 100644 --- a/hal/wifi3.0/qca8074v2/hal_8074v2.c +++ b/hal/wifi3.0/qca8074v2/hal_8074v2.c @@ -1845,6 +1845,7 @@ struct hal_hw_srng_config hw_srng_table_8074v2[] = { { /* TX_MONITOR_BUF */ 0}, { /* TX_MONITOR_DST */ 0}, { /* SW2RXDMA_NEW */ 0}, + { /* SW2RXDMA_LINK_RELEASE */ 0}, }; diff --git a/hal/wifi3.0/qcn6122/hal_qcn6122.c b/hal/wifi3.0/qcn6122/hal_qcn6122.c index 8166f28436..79bb43e1b4 100644 --- a/hal/wifi3.0/qcn6122/hal_qcn6122.c +++ b/hal/wifi3.0/qcn6122/hal_qcn6122.c @@ -2399,6 +2399,7 @@ struct hal_hw_srng_config hw_srng_table_6122[] = { { /* TX_MONITOR_BUF */ 0}, { /* TX_MONITOR_DST */ 0}, { /* SW2RXDMA_NEW */ 0}, + { /* SW2RXDMA_LINK_RELEASE */ 0}, }; /** diff --git a/hal/wifi3.0/qcn6432/hal_6432.c b/hal/wifi3.0/qcn6432/hal_6432.c index 4886ef0bfa..81c86acb50 100644 --- a/hal/wifi3.0/qcn6432/hal_6432.c +++ b/hal/wifi3.0/qcn6432/hal_6432.c @@ -2278,6 +2278,7 @@ struct hal_hw_srng_config hw_srng_table_6432[] = { .max_size = HAL_RXDMA_MAX_RING_SIZE_BE, .dmac_cmn_ring = TRUE, }, + { /* SW2RXDMA_LINK_RELEASE */ 0}, }; /** diff --git a/hal/wifi3.0/qcn9000/hal_9000.c b/hal/wifi3.0/qcn9000/hal_9000.c index fc97a2b6e8..66ecf0a043 100644 --- a/hal/wifi3.0/qcn9000/hal_9000.c +++ b/hal/wifi3.0/qcn9000/hal_9000.c @@ -2400,6 +2400,7 @@ struct hal_hw_srng_config hw_srng_table_9000[] = { { /* TX_MONITOR_BUF */ 0}, { /* TX_MONITOR_DST */ 0}, { /* SW2RXDMA_NEW */ 0}, + { /* SW2RXDMA_LINK_RELEASE */ 0}, }; /** diff --git a/hal/wifi3.0/qcn9224/v2/hal_9224v2.c b/hal/wifi3.0/qcn9224/v2/hal_9224v2.c index 2bd3440b0c..d866b4d2a3 100644 --- a/hal/wifi3.0/qcn9224/v2/hal_9224v2.c +++ b/hal/wifi3.0/qcn9224/v2/hal_9224v2.c @@ -547,6 +547,7 @@ struct hal_hw_srng_config hw_srng_table_9224v2[] = { .max_size = HAL_RXDMA_MAX_RING_SIZE_BE, .dmac_cmn_ring = TRUE, }, + { /* SW2RXDMA_LINK_RELEASE */ 0}, }; /** diff --git a/hal/wifi3.0/wcn6450/hal_wcn6450.c b/hal/wifi3.0/wcn6450/hal_wcn6450.c index 1429bf1493..3c62cc1f4c 100644 --- a/hal/wifi3.0/wcn6450/hal_wcn6450.c +++ b/hal/wifi3.0/wcn6450/hal_wcn6450.c @@ -213,6 +213,20 @@ struct hal_hw_srng_config hw_srng_table_wcn6450[] = { { /* TX_MONITOR_BUF */ 0}, { /* TX_MONITOR_DST */ 0}, { /* SW2RXDMA_NEW */ 0}, + { /* SW2RXDMA_LINK_RELEASE */ + .start_ring_id = HAL_SRNG_WMAC1_SW2RXDMA_LINK_RING, + .max_rings = 1, + .entry_size = sizeof(struct wbm_buffer_ring) >> 2, + .lmac_ring = TRUE, + .ring_dir = HAL_SRNG_SRC_RING, + /* reg_start is not set because LMAC rings are not accessed + * from host + */ + .reg_start = {}, + .reg_size = {}, + .max_size = HAL_RXDMA_MAX_RING_SIZE, + }, + }; static void hal_get_hw_hptp_6450(struct hal_soc *hal_soc, @@ -260,9 +274,10 @@ static void hal_tx_init_cmd_credit_ring_6450(hal_soc_handle_t hal_soc_hdl, { } +#define LINK_DESC_SIZE (NUM_OF_DWORDS_RX_MSDU_LINK << 2) static uint32_t hal_get_link_desc_size_6450(void) { - return 0; + return LINK_DESC_SIZE; } static void hal_reo_status_get_header_6450(hal_ring_desc_t ring_desc,