Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2a5b2a12 authored by Linux Build Service Account's avatar Linux Build Service Account
Browse files

Merge 75320ae8 on remote branch

Change-Id: I5f0330eb389dc203fb3d8b9548fca921613cf293
parents e7f979e8 75320ae8
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -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
@@ -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++;
+41 −0
Original line number Diff line number Diff line
@@ -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,
@@ -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++) {
@@ -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;
}
@@ -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)
@@ -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;
}
@@ -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;
}

@@ -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__,
@@ -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);
+81 −0
Original line number Diff line number Diff line
@@ -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)
{
@@ -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)
{
+89 −23
Original line number Diff line number Diff line
@@ -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");
	}

@@ -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
@@ -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);

@@ -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
@@ -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) {
@@ -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;
	}

@@ -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
/**
@@ -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(),
+129 −0
Original line number Diff line number Diff line
@@ -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)

@@ -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
@@ -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
@@ -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,
@@ -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);
}

@@ -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