Loading dp/wifi3.0/dp_htt.c +5 −1 Original line number Diff line number Diff line Loading @@ -50,6 +50,10 @@ #define HTT_SHIFT_UPPER_TIMESTAMP 32 #define HTT_MASK_UPPER_TIMESTAMP 0xFFFFFFFF00000000 #define HTT_HTC_PKT_STATUS_SUCCESS \ ((pkt->htc_pkt.Status != QDF_STATUS_E_CANCELED) && \ (pkt->htc_pkt.Status != QDF_STATUS_E_RESOURCES)) /* * dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap() - Get ppdu stats tlv * bitmap for sniffer mode Loading Loading @@ -619,7 +623,7 @@ static inline QDF_STATUS DP_HTT_SEND_HTC_PKT(struct htt_soc *soc, htt_command_record(soc->htt_logger_handle, cmd, buf); status = htc_send_pkt(soc->htc_soc, &pkt->htc_pkt); if (status == QDF_STATUS_SUCCESS) if (status == QDF_STATUS_SUCCESS && HTT_HTC_PKT_STATUS_SUCCESS) htt_htc_misc_pkt_list_add(soc, pkt); else soc->stats.fail_count++; Loading dp/wifi3.0/dp_ipa.c +41 −0 Original line number Diff line number Diff line Loading @@ -207,6 +207,28 @@ static QDF_STATUS __dp_ipa_tx_buf_smmu_mapping( return ret; } #ifndef QCA_OL_DP_SRNG_LOCK_LESS_ACCESS static void dp_ipa_set_reo_ctx_mapping_lock_required(struct dp_soc *soc, bool lock_required) { hal_ring_handle_t hal_ring_hdl; int ring; for (ring = 0; ring < MAX_REO_DEST_RINGS; ring++) { hal_ring_hdl = soc->reo_dest_ring[ring].hal_srng; hal_srng_lock(hal_ring_hdl); soc->ipa_reo_ctx_lock_required[ring] = lock_required; hal_srng_unlock(hal_ring_hdl); } } #else static void dp_ipa_set_reo_ctx_mapping_lock_required(struct dp_soc *soc, bool lock_required) { } #endif #ifdef RX_DESC_MULTI_PAGE_ALLOC static QDF_STATUS dp_ipa_handle_rx_buf_pool_smmu_mapping(struct dp_soc *soc, struct dp_pdev *pdev, Loading @@ -226,7 +248,9 @@ static QDF_STATUS dp_ipa_handle_rx_buf_pool_smmu_mapping(struct dp_soc *soc, pdev_id = pdev->pdev_id; rx_pool = &soc->rx_desc_buf[pdev_id]; dp_ipa_set_reo_ctx_mapping_lock_required(soc, true); qdf_spin_lock_bh(&rx_pool->lock); dp_ipa_rx_buf_smmu_mapping_lock(soc); num_desc = rx_pool->pool_size; num_desc_per_page = rx_pool->desc_pages.num_element_per_page; for (i = 0; i < num_desc; i++) { Loading Loading @@ -256,7 +280,9 @@ static QDF_STATUS dp_ipa_handle_rx_buf_pool_smmu_mapping(struct dp_soc *soc, __dp_ipa_handle_buf_smmu_mapping(soc, nbuf, rx_pool->buf_size, create); } dp_ipa_rx_buf_smmu_mapping_unlock(soc); qdf_spin_unlock_bh(&rx_pool->lock); dp_ipa_set_reo_ctx_mapping_lock_required(soc, false); return QDF_STATUS_SUCCESS; } Loading @@ -276,7 +302,9 @@ static QDF_STATUS dp_ipa_handle_rx_buf_pool_smmu_mapping(struct dp_soc *soc, pdev_id = pdev->pdev_id; rx_pool = &soc->rx_desc_buf[pdev_id]; dp_ipa_set_reo_ctx_mapping_lock_required(soc, true); qdf_spin_lock_bh(&rx_pool->lock); dp_ipa_rx_buf_smmu_mapping_lock(soc); for (i = 0; i < rx_pool->pool_size; i++) { if ((!(rx_pool->array[i].rx_desc.in_use)) || rx_pool->array[i].rx_desc.unmapped) Loading @@ -300,7 +328,9 @@ static QDF_STATUS dp_ipa_handle_rx_buf_pool_smmu_mapping(struct dp_soc *soc, __dp_ipa_handle_buf_smmu_mapping(soc, nbuf, rx_pool->buf_size, create); } dp_ipa_rx_buf_smmu_mapping_unlock(soc); qdf_spin_unlock_bh(&rx_pool->lock); dp_ipa_set_reo_ctx_mapping_lock_required(soc, false); return QDF_STATUS_SUCCESS; } Loading Loading @@ -1381,6 +1411,9 @@ QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, soc->ipa_first_tx_db_access = true; qdf_spinlock_create(&soc->ipa_rx_buf_map_lock); soc->ipa_rx_buf_map_lock_initialized = true; return QDF_STATUS_SUCCESS; } Loading Loading @@ -1596,6 +1629,9 @@ QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, soc->ipa_first_tx_db_access = true; qdf_spinlock_create(&soc->ipa_rx_buf_map_lock); soc->ipa_rx_buf_map_lock_initialized = true; QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, "%s: Tx: %s=%pK, %s=%d, %s=%pK, %s=%pK, %s=%d, %s=%pK, %s=%d, %s=%pK", __func__, Loading Loading @@ -1732,6 +1768,11 @@ QDF_STATUS dp_ipa_cleanup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, status = QDF_STATUS_E_FAILURE; } if (soc->ipa_rx_buf_map_lock_initialized) { qdf_spinlock_destroy(&soc->ipa_rx_buf_map_lock); soc->ipa_rx_buf_map_lock_initialized = false; } pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); if (qdf_unlikely(!pdev)) { dp_err_rl("Invalid pdev for pdev_id %d", pdev_id); Loading dp/wifi3.0/dp_ipa.h +81 −0 Original line number Diff line number Diff line Loading @@ -283,6 +283,65 @@ QDF_STATUS dp_ipa_tx_buf_smmu_mapping( QDF_STATUS dp_ipa_tx_buf_smmu_unmapping( struct cdp_soc_t *soc_hdl, uint8_t pdev_id); #ifndef QCA_OL_DP_SRNG_LOCK_LESS_ACCESS static inline void dp_ipa_rx_buf_smmu_mapping_lock(struct dp_soc *soc) { if (soc->ipa_rx_buf_map_lock_initialized) qdf_spin_lock_bh(&soc->ipa_rx_buf_map_lock); } static inline void dp_ipa_rx_buf_smmu_mapping_unlock(struct dp_soc *soc) { if (soc->ipa_rx_buf_map_lock_initialized) qdf_spin_unlock_bh(&soc->ipa_rx_buf_map_lock); } static inline void dp_ipa_reo_ctx_buf_mapping_lock(struct dp_soc *soc, uint32_t reo_ring_num) { if (!soc->ipa_reo_ctx_lock_required[reo_ring_num]) return; qdf_spin_lock_bh(&soc->ipa_rx_buf_map_lock); } static inline void dp_ipa_reo_ctx_buf_mapping_unlock(struct dp_soc *soc, uint32_t reo_ring_num) { if (!soc->ipa_reo_ctx_lock_required[reo_ring_num]) return; qdf_spin_unlock_bh(&soc->ipa_rx_buf_map_lock); } #else static inline void dp_ipa_rx_buf_smmu_mapping_lock(struct dp_soc *soc) { } static inline void dp_ipa_rx_buf_smmu_mapping_unlock(struct dp_soc *soc) { } static inline void dp_ipa_reo_ctx_buf_mapping_lock(struct dp_soc *soc, uint32_t reo_ring_num) { } static inline void dp_ipa_reo_ctx_buf_mapping_unlock(struct dp_soc *soc, uint32_t reo_ring_num) { } #endif #else static inline int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev) { Loading @@ -308,6 +367,28 @@ static inline QDF_STATUS dp_ipa_handle_rx_buf_smmu_mapping(struct dp_soc *soc, return QDF_STATUS_SUCCESS; } static inline void dp_ipa_rx_buf_smmu_mapping_lock(struct dp_soc *soc) { } static inline void dp_ipa_rx_buf_smmu_mapping_unlock(struct dp_soc *soc) { } static inline void dp_ipa_reo_ctx_buf_mapping_lock(struct dp_soc *soc, uint32_t reo_ring_num) { } static inline void dp_ipa_reo_ctx_buf_mapping_unlock(struct dp_soc *soc, uint32_t reo_ring_num) { } static inline qdf_nbuf_t dp_ipa_handle_rx_reo_reinject(struct dp_soc *soc, qdf_nbuf_t nbuf) { Loading dp/wifi3.0/dp_main.c +89 −23 Original line number Diff line number Diff line Loading @@ -2624,6 +2624,7 @@ static void dp_soc_interrupt_detach(struct cdp_soc_t *txrx_soc) if (soc->intr_mode == DP_INTR_POLL) { qdf_timer_free(&soc->int_timer); } else { hif_deconfigure_ext_group_interrupts(soc->hif_handle); hif_deregister_exec_group(soc->hif_handle, "dp_intr"); } Loading Loading @@ -4775,6 +4776,59 @@ static inline void dp_reo_desc_freelist_destroy(struct dp_soc *soc) qdf_spinlock_destroy(&soc->reo_desc_freelist_lock); } #ifdef WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY /* * dp_reo_desc_deferred_freelist_create() - Initialize the resources used * for deferred reo desc list * @psoc: Datapath soc handle * * Return: void */ static void dp_reo_desc_deferred_freelist_create(struct dp_soc *soc) { qdf_spinlock_create(&soc->reo_desc_deferred_freelist_lock); qdf_list_create(&soc->reo_desc_deferred_freelist, REO_DESC_DEFERRED_FREELIST_SIZE); soc->reo_desc_deferred_freelist_init = true; } /* * dp_reo_desc_deferred_freelist_destroy() - loop the deferred free list & * free the leftover REO QDESCs * @psoc: Datapath soc handle * * Return: void */ static void dp_reo_desc_deferred_freelist_destroy(struct dp_soc *soc) { struct reo_desc_deferred_freelist_node *desc; qdf_spin_lock_bh(&soc->reo_desc_deferred_freelist_lock); soc->reo_desc_deferred_freelist_init = false; while (qdf_list_remove_front(&soc->reo_desc_deferred_freelist, (qdf_list_node_t **)&desc) == QDF_STATUS_SUCCESS) { qdf_mem_unmap_nbytes_single(soc->osdev, desc->hw_qdesc_paddr, QDF_DMA_BIDIRECTIONAL, desc->hw_qdesc_alloc_size); qdf_mem_free(desc->hw_qdesc_vaddr_unaligned); qdf_mem_free(desc); } qdf_spin_unlock_bh(&soc->reo_desc_deferred_freelist_lock); qdf_list_destroy(&soc->reo_desc_deferred_freelist); qdf_spinlock_destroy(&soc->reo_desc_deferred_freelist_lock); } #else static inline void dp_reo_desc_deferred_freelist_create(struct dp_soc *soc) { } static inline void dp_reo_desc_deferred_freelist_destroy(struct dp_soc *soc) { } #endif /* !WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY */ /* * dp_soc_reset_txrx_ring_map() - reset tx ring map * @soc: DP SOC handle Loading Loading @@ -4855,6 +4909,7 @@ static void dp_soc_deinit(void *txrx_soc) dp_soc_reset_txrx_ring_map(soc); dp_reo_desc_freelist_destroy(soc); dp_reo_desc_deferred_freelist_destroy(soc); DEINIT_RX_HW_STATS_LOCK(soc); Loading Loading @@ -11412,6 +11467,29 @@ static struct cdp_mscs_ops dp_ops_mscs = { #endif #ifdef FEATURE_RUNTIME_PM /** * dp_flush_ring_hptp() - Update ring shadow * register HP/TP address when runtime * resume * @opaque_soc: DP soc context * * Return: None */ static void dp_flush_ring_hptp(struct dp_soc *soc, hal_ring_handle_t hal_srng) { if (hal_srng && hal_srng_get_clear_event(hal_srng, HAL_SRNG_FLUSH_EVENT)) { /* Acquire the lock */ hal_srng_access_start(soc->hal_soc, hal_srng); hal_srng_access_end(soc->hal_soc, hal_srng); hal_srng_set_flush_last_ts(hal_srng); dp_debug("flushed"); } } /** * dp_runtime_suspend() - ensure DP is ready to runtime suspend * @soc_hdl: Datapath soc handle Loading @@ -11425,6 +11503,7 @@ static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); struct dp_pdev *pdev; uint8_t i; pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); if (!pdev) { Loading @@ -11436,6 +11515,14 @@ static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) if (dp_get_tx_pending(dp_pdev_to_cdp_pdev(pdev)) > 0) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, FL("Abort suspend due to pending TX packets")); /* perform a force flush if tx is pending */ for (i = 0; i < soc->num_tcl_data_rings; i++) { hal_srng_set_event(soc->tcl_data_ring[i].hal_srng, HAL_SRNG_FLUSH_EVENT); dp_flush_ring_hptp(soc, soc->tcl_data_ring[i].hal_srng); } return QDF_STATUS_E_AGAIN; } Loading @@ -11453,29 +11540,6 @@ static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) return QDF_STATUS_SUCCESS; } /** * dp_flush_ring_hptp() - Update ring shadow * register HP/TP address when runtime * resume * @opaque_soc: DP soc context * * Return: None */ static void dp_flush_ring_hptp(struct dp_soc *soc, hal_ring_handle_t hal_srng) { if (hal_srng && hal_srng_get_clear_event(hal_srng, HAL_SRNG_FLUSH_EVENT)) { /* Acquire the lock */ hal_srng_access_start(soc->hal_soc, hal_srng); hal_srng_access_end(soc->hal_soc, hal_srng); hal_srng_set_flush_last_ts(hal_srng); dp_debug("flushed"); } } #define DP_FLUSH_WAIT_CNT 10 #define DP_RUNTIME_SUSPEND_WAIT_MS 10 /** Loading Loading @@ -12449,6 +12513,8 @@ void *dp_soc_init(struct dp_soc *soc, HTC_HANDLE htc_handle, /* initialize work queue for stats processing */ qdf_create_work(0, &soc->htt_stats.work, htt_t2h_stats_handler, soc); dp_reo_desc_deferred_freelist_create(soc); dp_info("Mem stats: DMA = %u HEAP = %u SKB = %u", qdf_dma_mem_stats_read(), qdf_heap_mem_stats_read(), Loading dp/wifi3.0/dp_peer.c +129 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,32 @@ dp_rx_reo_qdesc_history_add(struct reo_desc_list_node *free_desc, evt->type = type; } #ifdef WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY static inline void dp_rx_reo_qdesc_deferred_evt_add(struct reo_desc_deferred_freelist_node *desc, enum reo_qdesc_event_type type) { struct reo_qdesc_event *evt; uint32_t idx; reo_qdesc_history_idx++; idx = (reo_qdesc_history_idx & (REO_QDESC_HISTORY_SIZE - 1)); evt = &reo_qdesc_history[idx]; qdf_mem_copy(evt->peer_mac, desc->peer_mac, QDF_MAC_ADDR_SIZE); evt->qdesc_addr = desc->hw_qdesc_paddr; evt->ts = qdf_get_log_timestamp(); evt->type = type; } #define DP_RX_REO_QDESC_DEFERRED_FREE_EVT(desc) \ dp_rx_reo_qdesc_deferred_evt_add((desc), REO_QDESC_FREE) #define DP_RX_REO_QDESC_DEFERRED_GET_MAC(desc, freedesc) \ qdf_mem_copy(desc->peer_mac, freedesc->peer_mac, QDF_MAC_ADDR_SIZE) #endif /* WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY */ #define DP_RX_REO_QDESC_GET_MAC(freedesc, peer) \ qdf_mem_copy(freedesc->peer_mac, peer->mac_addr.raw, QDF_MAC_ADDR_SIZE) Loading @@ -103,12 +129,17 @@ dp_rx_reo_qdesc_history_add(struct reo_desc_list_node *free_desc, #define DP_RX_REO_QDESC_FREE_EVT(free_desc) \ dp_rx_reo_qdesc_history_add((free_desc), REO_QDESC_FREE) #else #define DP_RX_REO_QDESC_GET_MAC(freedesc, peer) #define DP_RX_REO_QDESC_UPDATE_EVT(free_desc) #define DP_RX_REO_QDESC_FREE_EVT(free_desc) #define DP_RX_REO_QDESC_DEFERRED_FREE_EVT(desc) #define DP_RX_REO_QDESC_DEFERRED_GET_MAC(desc, freedesc) #endif static inline void Loading Loading @@ -2319,6 +2350,95 @@ QDF_STATUS dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t return QDF_STATUS_SUCCESS; } #ifdef WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY /* * dp_reo_desc_defer_free_enqueue() - enqueue REO QDESC to be freed into * the deferred list * @soc: Datapath soc handle * @free_desc: REO DESC reference that needs to be freed * * Return: true if enqueued, else false */ static bool dp_reo_desc_defer_free_enqueue(struct dp_soc *soc, struct reo_desc_list_node *freedesc) { struct reo_desc_deferred_freelist_node *desc; if (!qdf_atomic_read(&soc->cmn_init_done)) return false; desc = qdf_mem_malloc(sizeof(*desc)); if (!desc) return false; desc->hw_qdesc_paddr = freedesc->rx_tid.hw_qdesc_paddr; desc->hw_qdesc_alloc_size = freedesc->rx_tid.hw_qdesc_alloc_size; desc->hw_qdesc_vaddr_unaligned = freedesc->rx_tid.hw_qdesc_vaddr_unaligned; desc->free_ts = qdf_get_system_timestamp(); DP_RX_REO_QDESC_DEFERRED_GET_MAC(desc, freedesc); qdf_spin_lock_bh(&soc->reo_desc_deferred_freelist_lock); if (!soc->reo_desc_deferred_freelist_init) { qdf_mem_free(desc); qdf_spin_unlock_bh(&soc->reo_desc_deferred_freelist_lock); return false; } qdf_list_insert_back(&soc->reo_desc_deferred_freelist, (qdf_list_node_t *)desc); qdf_spin_unlock_bh(&soc->reo_desc_deferred_freelist_lock); return true; } /* * dp_reo_desc_defer_free() - free the REO QDESC in the deferred list * based on time threshold * @soc: Datapath soc handle * @free_desc: REO DESC reference that needs to be freed * * Return: true if enqueued, else false */ static void dp_reo_desc_defer_free(struct dp_soc *soc) { struct reo_desc_deferred_freelist_node *desc; unsigned long curr_ts = qdf_get_system_timestamp(); qdf_spin_lock_bh(&soc->reo_desc_deferred_freelist_lock); while ((qdf_list_peek_front(&soc->reo_desc_deferred_freelist, (qdf_list_node_t **)&desc) == QDF_STATUS_SUCCESS) && (curr_ts > (desc->free_ts + REO_DESC_DEFERRED_FREE_MS))) { qdf_list_remove_front(&soc->reo_desc_deferred_freelist, (qdf_list_node_t **)&desc); DP_RX_REO_QDESC_DEFERRED_FREE_EVT(desc); qdf_mem_unmap_nbytes_single(soc->osdev, desc->hw_qdesc_paddr, QDF_DMA_BIDIRECTIONAL, desc->hw_qdesc_alloc_size); qdf_mem_free(desc->hw_qdesc_vaddr_unaligned); qdf_mem_free(desc); curr_ts = qdf_get_system_timestamp(); } qdf_spin_unlock_bh(&soc->reo_desc_deferred_freelist_lock); } #else static inline bool dp_reo_desc_defer_free_enqueue(struct dp_soc *soc, struct reo_desc_list_node *freedesc) { return false; } static void dp_reo_desc_defer_free(struct dp_soc *soc) { } #endif /* !WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY */ /* * dp_reo_desc_free() - Callback free reo descriptor memory after * HW cache flush Loading Loading @@ -2350,6 +2470,12 @@ static void dp_reo_desc_free(struct dp_soc *soc, void *cb_ctxt, curr_ts, (void *)(rx_tid->hw_qdesc_paddr), rx_tid->tid); /* REO desc is enqueued to be freed at a later point * in time, just free the freedesc alone and return */ if (dp_reo_desc_defer_free_enqueue(soc, freedesc)) goto out; DP_RX_REO_QDESC_FREE_EVT(freedesc); qdf_mem_unmap_nbytes_single(soc->osdev, Loading @@ -2357,6 +2483,7 @@ static void dp_reo_desc_free(struct dp_soc *soc, void *cb_ctxt, QDF_DMA_BIDIRECTIONAL, rx_tid->hw_qdesc_alloc_size); qdf_mem_free(rx_tid->hw_qdesc_vaddr_unaligned); out: qdf_mem_free(freedesc); } Loading Loading @@ -2822,6 +2949,8 @@ void dp_rx_tid_delete_cb(struct dp_soc *soc, void *cb_ctxt, } } qdf_spin_unlock_bh(&soc->reo_desc_freelist_lock); dp_reo_desc_defer_free(soc); } /* Loading Loading
dp/wifi3.0/dp_htt.c +5 −1 Original line number Diff line number Diff line Loading @@ -50,6 +50,10 @@ #define HTT_SHIFT_UPPER_TIMESTAMP 32 #define HTT_MASK_UPPER_TIMESTAMP 0xFFFFFFFF00000000 #define HTT_HTC_PKT_STATUS_SUCCESS \ ((pkt->htc_pkt.Status != QDF_STATUS_E_CANCELED) && \ (pkt->htc_pkt.Status != QDF_STATUS_E_RESOURCES)) /* * dp_htt_get_ppdu_sniffer_ampdu_tlv_bitmap() - Get ppdu stats tlv * bitmap for sniffer mode Loading Loading @@ -619,7 +623,7 @@ static inline QDF_STATUS DP_HTT_SEND_HTC_PKT(struct htt_soc *soc, htt_command_record(soc->htt_logger_handle, cmd, buf); status = htc_send_pkt(soc->htc_soc, &pkt->htc_pkt); if (status == QDF_STATUS_SUCCESS) if (status == QDF_STATUS_SUCCESS && HTT_HTC_PKT_STATUS_SUCCESS) htt_htc_misc_pkt_list_add(soc, pkt); else soc->stats.fail_count++; Loading
dp/wifi3.0/dp_ipa.c +41 −0 Original line number Diff line number Diff line Loading @@ -207,6 +207,28 @@ static QDF_STATUS __dp_ipa_tx_buf_smmu_mapping( return ret; } #ifndef QCA_OL_DP_SRNG_LOCK_LESS_ACCESS static void dp_ipa_set_reo_ctx_mapping_lock_required(struct dp_soc *soc, bool lock_required) { hal_ring_handle_t hal_ring_hdl; int ring; for (ring = 0; ring < MAX_REO_DEST_RINGS; ring++) { hal_ring_hdl = soc->reo_dest_ring[ring].hal_srng; hal_srng_lock(hal_ring_hdl); soc->ipa_reo_ctx_lock_required[ring] = lock_required; hal_srng_unlock(hal_ring_hdl); } } #else static void dp_ipa_set_reo_ctx_mapping_lock_required(struct dp_soc *soc, bool lock_required) { } #endif #ifdef RX_DESC_MULTI_PAGE_ALLOC static QDF_STATUS dp_ipa_handle_rx_buf_pool_smmu_mapping(struct dp_soc *soc, struct dp_pdev *pdev, Loading @@ -226,7 +248,9 @@ static QDF_STATUS dp_ipa_handle_rx_buf_pool_smmu_mapping(struct dp_soc *soc, pdev_id = pdev->pdev_id; rx_pool = &soc->rx_desc_buf[pdev_id]; dp_ipa_set_reo_ctx_mapping_lock_required(soc, true); qdf_spin_lock_bh(&rx_pool->lock); dp_ipa_rx_buf_smmu_mapping_lock(soc); num_desc = rx_pool->pool_size; num_desc_per_page = rx_pool->desc_pages.num_element_per_page; for (i = 0; i < num_desc; i++) { Loading Loading @@ -256,7 +280,9 @@ static QDF_STATUS dp_ipa_handle_rx_buf_pool_smmu_mapping(struct dp_soc *soc, __dp_ipa_handle_buf_smmu_mapping(soc, nbuf, rx_pool->buf_size, create); } dp_ipa_rx_buf_smmu_mapping_unlock(soc); qdf_spin_unlock_bh(&rx_pool->lock); dp_ipa_set_reo_ctx_mapping_lock_required(soc, false); return QDF_STATUS_SUCCESS; } Loading @@ -276,7 +302,9 @@ static QDF_STATUS dp_ipa_handle_rx_buf_pool_smmu_mapping(struct dp_soc *soc, pdev_id = pdev->pdev_id; rx_pool = &soc->rx_desc_buf[pdev_id]; dp_ipa_set_reo_ctx_mapping_lock_required(soc, true); qdf_spin_lock_bh(&rx_pool->lock); dp_ipa_rx_buf_smmu_mapping_lock(soc); for (i = 0; i < rx_pool->pool_size; i++) { if ((!(rx_pool->array[i].rx_desc.in_use)) || rx_pool->array[i].rx_desc.unmapped) Loading @@ -300,7 +328,9 @@ static QDF_STATUS dp_ipa_handle_rx_buf_pool_smmu_mapping(struct dp_soc *soc, __dp_ipa_handle_buf_smmu_mapping(soc, nbuf, rx_pool->buf_size, create); } dp_ipa_rx_buf_smmu_mapping_unlock(soc); qdf_spin_unlock_bh(&rx_pool->lock); dp_ipa_set_reo_ctx_mapping_lock_required(soc, false); return QDF_STATUS_SUCCESS; } Loading Loading @@ -1381,6 +1411,9 @@ QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, soc->ipa_first_tx_db_access = true; qdf_spinlock_create(&soc->ipa_rx_buf_map_lock); soc->ipa_rx_buf_map_lock_initialized = true; return QDF_STATUS_SUCCESS; } Loading Loading @@ -1596,6 +1629,9 @@ QDF_STATUS dp_ipa_setup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, soc->ipa_first_tx_db_access = true; qdf_spinlock_create(&soc->ipa_rx_buf_map_lock); soc->ipa_rx_buf_map_lock_initialized = true; QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG, "%s: Tx: %s=%pK, %s=%d, %s=%pK, %s=%pK, %s=%d, %s=%pK, %s=%d, %s=%pK", __func__, Loading Loading @@ -1732,6 +1768,11 @@ QDF_STATUS dp_ipa_cleanup(struct cdp_soc_t *soc_hdl, uint8_t pdev_id, status = QDF_STATUS_E_FAILURE; } if (soc->ipa_rx_buf_map_lock_initialized) { qdf_spinlock_destroy(&soc->ipa_rx_buf_map_lock); soc->ipa_rx_buf_map_lock_initialized = false; } pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); if (qdf_unlikely(!pdev)) { dp_err_rl("Invalid pdev for pdev_id %d", pdev_id); Loading
dp/wifi3.0/dp_ipa.h +81 −0 Original line number Diff line number Diff line Loading @@ -283,6 +283,65 @@ QDF_STATUS dp_ipa_tx_buf_smmu_mapping( QDF_STATUS dp_ipa_tx_buf_smmu_unmapping( struct cdp_soc_t *soc_hdl, uint8_t pdev_id); #ifndef QCA_OL_DP_SRNG_LOCK_LESS_ACCESS static inline void dp_ipa_rx_buf_smmu_mapping_lock(struct dp_soc *soc) { if (soc->ipa_rx_buf_map_lock_initialized) qdf_spin_lock_bh(&soc->ipa_rx_buf_map_lock); } static inline void dp_ipa_rx_buf_smmu_mapping_unlock(struct dp_soc *soc) { if (soc->ipa_rx_buf_map_lock_initialized) qdf_spin_unlock_bh(&soc->ipa_rx_buf_map_lock); } static inline void dp_ipa_reo_ctx_buf_mapping_lock(struct dp_soc *soc, uint32_t reo_ring_num) { if (!soc->ipa_reo_ctx_lock_required[reo_ring_num]) return; qdf_spin_lock_bh(&soc->ipa_rx_buf_map_lock); } static inline void dp_ipa_reo_ctx_buf_mapping_unlock(struct dp_soc *soc, uint32_t reo_ring_num) { if (!soc->ipa_reo_ctx_lock_required[reo_ring_num]) return; qdf_spin_unlock_bh(&soc->ipa_rx_buf_map_lock); } #else static inline void dp_ipa_rx_buf_smmu_mapping_lock(struct dp_soc *soc) { } static inline void dp_ipa_rx_buf_smmu_mapping_unlock(struct dp_soc *soc) { } static inline void dp_ipa_reo_ctx_buf_mapping_lock(struct dp_soc *soc, uint32_t reo_ring_num) { } static inline void dp_ipa_reo_ctx_buf_mapping_unlock(struct dp_soc *soc, uint32_t reo_ring_num) { } #endif #else static inline int dp_ipa_uc_detach(struct dp_soc *soc, struct dp_pdev *pdev) { Loading @@ -308,6 +367,28 @@ static inline QDF_STATUS dp_ipa_handle_rx_buf_smmu_mapping(struct dp_soc *soc, return QDF_STATUS_SUCCESS; } static inline void dp_ipa_rx_buf_smmu_mapping_lock(struct dp_soc *soc) { } static inline void dp_ipa_rx_buf_smmu_mapping_unlock(struct dp_soc *soc) { } static inline void dp_ipa_reo_ctx_buf_mapping_lock(struct dp_soc *soc, uint32_t reo_ring_num) { } static inline void dp_ipa_reo_ctx_buf_mapping_unlock(struct dp_soc *soc, uint32_t reo_ring_num) { } static inline qdf_nbuf_t dp_ipa_handle_rx_reo_reinject(struct dp_soc *soc, qdf_nbuf_t nbuf) { Loading
dp/wifi3.0/dp_main.c +89 −23 Original line number Diff line number Diff line Loading @@ -2624,6 +2624,7 @@ static void dp_soc_interrupt_detach(struct cdp_soc_t *txrx_soc) if (soc->intr_mode == DP_INTR_POLL) { qdf_timer_free(&soc->int_timer); } else { hif_deconfigure_ext_group_interrupts(soc->hif_handle); hif_deregister_exec_group(soc->hif_handle, "dp_intr"); } Loading Loading @@ -4775,6 +4776,59 @@ static inline void dp_reo_desc_freelist_destroy(struct dp_soc *soc) qdf_spinlock_destroy(&soc->reo_desc_freelist_lock); } #ifdef WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY /* * dp_reo_desc_deferred_freelist_create() - Initialize the resources used * for deferred reo desc list * @psoc: Datapath soc handle * * Return: void */ static void dp_reo_desc_deferred_freelist_create(struct dp_soc *soc) { qdf_spinlock_create(&soc->reo_desc_deferred_freelist_lock); qdf_list_create(&soc->reo_desc_deferred_freelist, REO_DESC_DEFERRED_FREELIST_SIZE); soc->reo_desc_deferred_freelist_init = true; } /* * dp_reo_desc_deferred_freelist_destroy() - loop the deferred free list & * free the leftover REO QDESCs * @psoc: Datapath soc handle * * Return: void */ static void dp_reo_desc_deferred_freelist_destroy(struct dp_soc *soc) { struct reo_desc_deferred_freelist_node *desc; qdf_spin_lock_bh(&soc->reo_desc_deferred_freelist_lock); soc->reo_desc_deferred_freelist_init = false; while (qdf_list_remove_front(&soc->reo_desc_deferred_freelist, (qdf_list_node_t **)&desc) == QDF_STATUS_SUCCESS) { qdf_mem_unmap_nbytes_single(soc->osdev, desc->hw_qdesc_paddr, QDF_DMA_BIDIRECTIONAL, desc->hw_qdesc_alloc_size); qdf_mem_free(desc->hw_qdesc_vaddr_unaligned); qdf_mem_free(desc); } qdf_spin_unlock_bh(&soc->reo_desc_deferred_freelist_lock); qdf_list_destroy(&soc->reo_desc_deferred_freelist); qdf_spinlock_destroy(&soc->reo_desc_deferred_freelist_lock); } #else static inline void dp_reo_desc_deferred_freelist_create(struct dp_soc *soc) { } static inline void dp_reo_desc_deferred_freelist_destroy(struct dp_soc *soc) { } #endif /* !WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY */ /* * dp_soc_reset_txrx_ring_map() - reset tx ring map * @soc: DP SOC handle Loading Loading @@ -4855,6 +4909,7 @@ static void dp_soc_deinit(void *txrx_soc) dp_soc_reset_txrx_ring_map(soc); dp_reo_desc_freelist_destroy(soc); dp_reo_desc_deferred_freelist_destroy(soc); DEINIT_RX_HW_STATS_LOCK(soc); Loading Loading @@ -11412,6 +11467,29 @@ static struct cdp_mscs_ops dp_ops_mscs = { #endif #ifdef FEATURE_RUNTIME_PM /** * dp_flush_ring_hptp() - Update ring shadow * register HP/TP address when runtime * resume * @opaque_soc: DP soc context * * Return: None */ static void dp_flush_ring_hptp(struct dp_soc *soc, hal_ring_handle_t hal_srng) { if (hal_srng && hal_srng_get_clear_event(hal_srng, HAL_SRNG_FLUSH_EVENT)) { /* Acquire the lock */ hal_srng_access_start(soc->hal_soc, hal_srng); hal_srng_access_end(soc->hal_soc, hal_srng); hal_srng_set_flush_last_ts(hal_srng); dp_debug("flushed"); } } /** * dp_runtime_suspend() - ensure DP is ready to runtime suspend * @soc_hdl: Datapath soc handle Loading @@ -11425,6 +11503,7 @@ static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) { struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl); struct dp_pdev *pdev; uint8_t i; pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); if (!pdev) { Loading @@ -11436,6 +11515,14 @@ static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) if (dp_get_tx_pending(dp_pdev_to_cdp_pdev(pdev)) > 0) { QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO, FL("Abort suspend due to pending TX packets")); /* perform a force flush if tx is pending */ for (i = 0; i < soc->num_tcl_data_rings; i++) { hal_srng_set_event(soc->tcl_data_ring[i].hal_srng, HAL_SRNG_FLUSH_EVENT); dp_flush_ring_hptp(soc, soc->tcl_data_ring[i].hal_srng); } return QDF_STATUS_E_AGAIN; } Loading @@ -11453,29 +11540,6 @@ static QDF_STATUS dp_runtime_suspend(struct cdp_soc_t *soc_hdl, uint8_t pdev_id) return QDF_STATUS_SUCCESS; } /** * dp_flush_ring_hptp() - Update ring shadow * register HP/TP address when runtime * resume * @opaque_soc: DP soc context * * Return: None */ static void dp_flush_ring_hptp(struct dp_soc *soc, hal_ring_handle_t hal_srng) { if (hal_srng && hal_srng_get_clear_event(hal_srng, HAL_SRNG_FLUSH_EVENT)) { /* Acquire the lock */ hal_srng_access_start(soc->hal_soc, hal_srng); hal_srng_access_end(soc->hal_soc, hal_srng); hal_srng_set_flush_last_ts(hal_srng); dp_debug("flushed"); } } #define DP_FLUSH_WAIT_CNT 10 #define DP_RUNTIME_SUSPEND_WAIT_MS 10 /** Loading Loading @@ -12449,6 +12513,8 @@ void *dp_soc_init(struct dp_soc *soc, HTC_HANDLE htc_handle, /* initialize work queue for stats processing */ qdf_create_work(0, &soc->htt_stats.work, htt_t2h_stats_handler, soc); dp_reo_desc_deferred_freelist_create(soc); dp_info("Mem stats: DMA = %u HEAP = %u SKB = %u", qdf_dma_mem_stats_read(), qdf_heap_mem_stats_read(), Loading
dp/wifi3.0/dp_peer.c +129 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,32 @@ dp_rx_reo_qdesc_history_add(struct reo_desc_list_node *free_desc, evt->type = type; } #ifdef WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY static inline void dp_rx_reo_qdesc_deferred_evt_add(struct reo_desc_deferred_freelist_node *desc, enum reo_qdesc_event_type type) { struct reo_qdesc_event *evt; uint32_t idx; reo_qdesc_history_idx++; idx = (reo_qdesc_history_idx & (REO_QDESC_HISTORY_SIZE - 1)); evt = &reo_qdesc_history[idx]; qdf_mem_copy(evt->peer_mac, desc->peer_mac, QDF_MAC_ADDR_SIZE); evt->qdesc_addr = desc->hw_qdesc_paddr; evt->ts = qdf_get_log_timestamp(); evt->type = type; } #define DP_RX_REO_QDESC_DEFERRED_FREE_EVT(desc) \ dp_rx_reo_qdesc_deferred_evt_add((desc), REO_QDESC_FREE) #define DP_RX_REO_QDESC_DEFERRED_GET_MAC(desc, freedesc) \ qdf_mem_copy(desc->peer_mac, freedesc->peer_mac, QDF_MAC_ADDR_SIZE) #endif /* WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY */ #define DP_RX_REO_QDESC_GET_MAC(freedesc, peer) \ qdf_mem_copy(freedesc->peer_mac, peer->mac_addr.raw, QDF_MAC_ADDR_SIZE) Loading @@ -103,12 +129,17 @@ dp_rx_reo_qdesc_history_add(struct reo_desc_list_node *free_desc, #define DP_RX_REO_QDESC_FREE_EVT(free_desc) \ dp_rx_reo_qdesc_history_add((free_desc), REO_QDESC_FREE) #else #define DP_RX_REO_QDESC_GET_MAC(freedesc, peer) #define DP_RX_REO_QDESC_UPDATE_EVT(free_desc) #define DP_RX_REO_QDESC_FREE_EVT(free_desc) #define DP_RX_REO_QDESC_DEFERRED_FREE_EVT(desc) #define DP_RX_REO_QDESC_DEFERRED_GET_MAC(desc, freedesc) #endif static inline void Loading Loading @@ -2319,6 +2350,95 @@ QDF_STATUS dp_rx_tid_update_wifi3(struct dp_peer *peer, int tid, uint32_t return QDF_STATUS_SUCCESS; } #ifdef WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY /* * dp_reo_desc_defer_free_enqueue() - enqueue REO QDESC to be freed into * the deferred list * @soc: Datapath soc handle * @free_desc: REO DESC reference that needs to be freed * * Return: true if enqueued, else false */ static bool dp_reo_desc_defer_free_enqueue(struct dp_soc *soc, struct reo_desc_list_node *freedesc) { struct reo_desc_deferred_freelist_node *desc; if (!qdf_atomic_read(&soc->cmn_init_done)) return false; desc = qdf_mem_malloc(sizeof(*desc)); if (!desc) return false; desc->hw_qdesc_paddr = freedesc->rx_tid.hw_qdesc_paddr; desc->hw_qdesc_alloc_size = freedesc->rx_tid.hw_qdesc_alloc_size; desc->hw_qdesc_vaddr_unaligned = freedesc->rx_tid.hw_qdesc_vaddr_unaligned; desc->free_ts = qdf_get_system_timestamp(); DP_RX_REO_QDESC_DEFERRED_GET_MAC(desc, freedesc); qdf_spin_lock_bh(&soc->reo_desc_deferred_freelist_lock); if (!soc->reo_desc_deferred_freelist_init) { qdf_mem_free(desc); qdf_spin_unlock_bh(&soc->reo_desc_deferred_freelist_lock); return false; } qdf_list_insert_back(&soc->reo_desc_deferred_freelist, (qdf_list_node_t *)desc); qdf_spin_unlock_bh(&soc->reo_desc_deferred_freelist_lock); return true; } /* * dp_reo_desc_defer_free() - free the REO QDESC in the deferred list * based on time threshold * @soc: Datapath soc handle * @free_desc: REO DESC reference that needs to be freed * * Return: true if enqueued, else false */ static void dp_reo_desc_defer_free(struct dp_soc *soc) { struct reo_desc_deferred_freelist_node *desc; unsigned long curr_ts = qdf_get_system_timestamp(); qdf_spin_lock_bh(&soc->reo_desc_deferred_freelist_lock); while ((qdf_list_peek_front(&soc->reo_desc_deferred_freelist, (qdf_list_node_t **)&desc) == QDF_STATUS_SUCCESS) && (curr_ts > (desc->free_ts + REO_DESC_DEFERRED_FREE_MS))) { qdf_list_remove_front(&soc->reo_desc_deferred_freelist, (qdf_list_node_t **)&desc); DP_RX_REO_QDESC_DEFERRED_FREE_EVT(desc); qdf_mem_unmap_nbytes_single(soc->osdev, desc->hw_qdesc_paddr, QDF_DMA_BIDIRECTIONAL, desc->hw_qdesc_alloc_size); qdf_mem_free(desc->hw_qdesc_vaddr_unaligned); qdf_mem_free(desc); curr_ts = qdf_get_system_timestamp(); } qdf_spin_unlock_bh(&soc->reo_desc_deferred_freelist_lock); } #else static inline bool dp_reo_desc_defer_free_enqueue(struct dp_soc *soc, struct reo_desc_list_node *freedesc) { return false; } static void dp_reo_desc_defer_free(struct dp_soc *soc) { } #endif /* !WLAN_DP_FEATURE_DEFERRED_REO_QDESC_DESTROY */ /* * dp_reo_desc_free() - Callback free reo descriptor memory after * HW cache flush Loading Loading @@ -2350,6 +2470,12 @@ static void dp_reo_desc_free(struct dp_soc *soc, void *cb_ctxt, curr_ts, (void *)(rx_tid->hw_qdesc_paddr), rx_tid->tid); /* REO desc is enqueued to be freed at a later point * in time, just free the freedesc alone and return */ if (dp_reo_desc_defer_free_enqueue(soc, freedesc)) goto out; DP_RX_REO_QDESC_FREE_EVT(freedesc); qdf_mem_unmap_nbytes_single(soc->osdev, Loading @@ -2357,6 +2483,7 @@ static void dp_reo_desc_free(struct dp_soc *soc, void *cb_ctxt, QDF_DMA_BIDIRECTIONAL, rx_tid->hw_qdesc_alloc_size); qdf_mem_free(rx_tid->hw_qdesc_vaddr_unaligned); out: qdf_mem_free(freedesc); } Loading Loading @@ -2822,6 +2949,8 @@ void dp_rx_tid_delete_cb(struct dp_soc *soc, void *cb_ctxt, } } qdf_spin_unlock_bh(&soc->reo_desc_freelist_lock); dp_reo_desc_defer_free(soc); } /* Loading