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

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

Merge dda1e108 on remote branch

Change-Id: I154d3abae3475684e7cee72dfff68e99aca6d871
parents c9ad91f3 dda1e108
Loading
Loading
Loading
Loading
+69 −45
Original line number Diff line number Diff line
@@ -506,6 +506,9 @@ int dp_ipa_ring_resource_setup(struct dp_soc *soc,
						srng_params.ring_base_vaddr;
	soc->ipa_uc_tx_rsc.ipa_wbm_ring_size =
		(srng_params.num_entries * srng_params.entry_size) << 2;
	soc->ipa_uc_tx_rsc.ipa_wbm_hp_shadow_paddr =
		hal_srng_get_hp_addr(hal_soc_to_hal_soc_handle(hal_soc),
				     hal_srng_to_hal_ring_handle(hal_srng));
	addr_offset = (unsigned long)(hal_srng->u.dst_ring.tp_addr) -
		      (unsigned long)(hal_soc->dev_base_addr);
	soc->ipa_uc_tx_rsc.ipa_wbm_tp_paddr =
@@ -664,14 +667,33 @@ QDF_STATUS dp_ipa_get_resource(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
	return QDF_STATUS_SUCCESS;
}

static void dp_ipa_set_tx_doorbell_paddr(struct dp_soc *soc,
					 struct dp_ipa_resources *ipa_res)
{
	struct hal_srng *wbm_srng = (struct hal_srng *)
			soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng;

	hal_srng_dst_set_hp_paddr_confirm(wbm_srng,
					  ipa_res->tx_comp_doorbell_paddr);

	dp_info("paddr %pK vaddr %pK",
		(void *)ipa_res->tx_comp_doorbell_paddr,
		(void *)ipa_res->tx_comp_doorbell_vaddr);
}

#ifdef IPA_SET_RESET_TX_DB_PA
#define DP_IPA_SET_TX_DB_PADDR(soc, ipa_res)
#else
#define DP_IPA_SET_TX_DB_PADDR(soc, ipa_res) \
		dp_ipa_set_tx_doorbell_paddr(soc, ipa_res)
#endif

QDF_STATUS dp_ipa_set_doorbell_paddr(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 =
		dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
	struct dp_ipa_resources *ipa_res;
	struct hal_srng *wbm_srng = (struct hal_srng *)
			soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng;
	struct hal_srng *reo_srng = (struct hal_srng *)
			soc->reo_dest_ring[IPA_REO_DEST_RING_IDX].hal_srng;
	uint32_t tx_comp_doorbell_dmaaddr;
@@ -699,11 +721,7 @@ QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
		ipa_res->rx_ready_doorbell_paddr = rx_ready_doorbell_dmaaddr;
	}

	hal_srng_dst_set_hp_paddr(wbm_srng, ipa_res->tx_comp_doorbell_paddr);

	dp_info("paddr %pK vaddr %pK",
		(void *)ipa_res->tx_comp_doorbell_paddr,
		(void *)ipa_res->tx_comp_doorbell_vaddr);
	DP_IPA_SET_TX_DB_PADDR(soc, ipa_res);

	/*
	 * For RX, REO module on Napier/Hastings does reordering on incoming
@@ -712,7 +730,8 @@ QDF_STATUS dp_ipa_set_doorbell_paddr(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
	 * to IPA.
	 * Set the doorbell addr for the REO ring.
	 */
	hal_srng_dst_set_hp_paddr(reo_srng, ipa_res->rx_ready_doorbell_paddr);
	hal_srng_dst_set_hp_paddr_confirm(reo_srng,
					  ipa_res->rx_ready_doorbell_paddr);
	return QDF_STATUS_SUCCESS;
}

@@ -1637,6 +1656,36 @@ QDF_STATUS dp_ipa_cleanup_iface(char *ifname, bool is_ipv6_enabled)
	return QDF_STATUS_SUCCESS;
}

#ifdef IPA_SET_RESET_TX_DB_PA
static
QDF_STATUS dp_ipa_reset_tx_doorbell_pa(struct dp_soc *soc,
				       struct dp_ipa_resources *ipa_res)
{
	hal_ring_handle_t wbm_srng =
			soc->tx_comp_ring[IPA_TX_COMP_RING_IDX].hal_srng;
	qdf_dma_addr_t hp_addr;

	if (!wbm_srng)
		return QDF_STATUS_E_FAILURE;

	hp_addr = soc->ipa_uc_tx_rsc.ipa_wbm_hp_shadow_paddr;

	hal_srng_dst_set_hp_paddr_confirm((struct hal_srng *)wbm_srng, hp_addr);

	dp_info("Reset WBM HP addr paddr: %pK", (void *)hp_addr);

	return QDF_STATUS_SUCCESS;
}

#define DP_IPA_EP_SET_TX_DB_PA(soc, ipa_res) \
				dp_ipa_set_tx_doorbell_paddr((soc), (ipa_res))
#define DP_IPA_RESET_TX_DB_PA(soc, ipa_res) \
				dp_ipa_reset_tx_doorbell_pa((soc), (ipa_res))
#else
#define DP_IPA_EP_SET_TX_DB_PA(soc, ipa_res)
#define DP_IPA_RESET_TX_DB_PA(soc, ipa_res)
#endif

QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
{
	struct dp_soc *soc = cdp_soc_t_to_dp_soc(soc_hdl);
@@ -1655,6 +1704,7 @@ QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
	ipa_res = &pdev->ipa_resource;

	qdf_atomic_set(&soc->ipa_pipes_enabled, 1);
	DP_IPA_EP_SET_TX_DB_PA(soc, ipa_res);
	dp_ipa_handle_rx_buf_pool_smmu_mapping(soc, pdev, true);

	result = qdf_ipa_wdi_enable_pipes();
@@ -1663,6 +1713,7 @@ QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
			  "%s: Enable WDI PIPE fail, code %d",
			  __func__, result);
		qdf_atomic_set(&soc->ipa_pipes_enabled, 0);
		DP_IPA_RESET_TX_DB_PA(soc, ipa_res);
		dp_ipa_handle_rx_buf_pool_smmu_mapping(soc, pdev, false);
		return QDF_STATUS_E_FAILURE;
	}
@@ -1677,55 +1728,28 @@ QDF_STATUS dp_ipa_enable_pipes(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
	return QDF_STATUS_SUCCESS;
}

/*
 * dp_ipa_get_tx_comp_pending_check() - Check if tx completions are pending.
 * @soc: DP pdev Context
 *
 * Ring full condition is checked to find if buffers are left for
 * processing as host only allocates buffers in this ring and IPA HW processes
 * the buffer.
 *
 * Return: True if tx completions are pending
 */
static bool dp_ipa_get_tx_comp_pending_check(struct dp_soc *soc)
{
	struct dp_srng *tx_comp_ring =
				&soc->tx_comp_ring[IPA_TX_COMP_RING_IDX];
	uint32_t hp, tp, entry_size, buf_cnt;

	hal_get_hw_hptp(soc->hal_soc, tx_comp_ring->hal_srng, &hp, &tp,
			WBM2SW_RELEASE);
	entry_size = hal_srng_get_entrysize(soc->hal_soc, WBM2SW_RELEASE) >> 2;

	if (hp > tp)
		buf_cnt = (hp - tp) / entry_size;
	else
		buf_cnt = (tx_comp_ring->num_entries - tp + hp) / entry_size;

	return (soc->ipa_uc_tx_rsc.alloc_tx_buf_cnt != buf_cnt);
}

QDF_STATUS dp_ipa_disable_pipes(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 =
		dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
	int timeout = TX_COMP_DRAIN_WAIT_TIMEOUT_MS;
	QDF_STATUS result;
	struct dp_ipa_resources *ipa_res;

	if (!pdev) {
		dp_err("%s invalid instance", __func__);
		return QDF_STATUS_E_FAILURE;
	}

	while (dp_ipa_get_tx_comp_pending_check(soc)) {
		qdf_sleep(TX_COMP_DRAIN_WAIT_MS);
		timeout -= TX_COMP_DRAIN_WAIT_MS;
		if (timeout <= 0) {
			dp_err("Tx completions pending. Force Disabling pipes");
			break;
		}
	}
	ipa_res = &pdev->ipa_resource;

	qdf_sleep(TX_COMP_DRAIN_WAIT_TIMEOUT_MS);
	/*
	 * Reset the tx completion doorbell address before invoking IPA disable
	 * pipes API to ensure that there is no access to IPA tx doorbell
	 * address post disable pipes.
	 */
	DP_IPA_RESET_TX_DB_PA(soc, ipa_res);

	result = qdf_ipa_wdi_disable_pipes();
	if (result) {
+41 −11
Original line number Diff line number Diff line
@@ -1373,7 +1373,7 @@ void dp_context_free_mem(struct dp_soc *soc, enum dp_ctxt_type ctxt_type,

	if (soc->cdp_soc.ol_ops->dp_prealloc_put_context) {
		status = soc->cdp_soc.ol_ops->dp_prealloc_put_context(
								DP_PDEV_TYPE,
								ctxt_type,
								vaddr);
	} else {
		dp_warn("dp_prealloc_get_context null!");
@@ -3799,6 +3799,28 @@ static QDF_STATUS dp_htt_ppdu_stats_attach(struct dp_pdev *pdev)
}

#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY
#ifndef RX_DEFRAG_DO_NOT_REINJECT
/**
 * dp_soc_rx_reinject_ring_history_attach - Attach the reo reinject ring
 *					    history.
 * @soc: DP soc handle
 *
 * Return: None
 */
static void dp_soc_rx_reinject_ring_history_attach(struct dp_soc *soc)
{
	soc->rx_reinject_ring_history = dp_context_alloc_mem(
			soc, DP_RX_REINJECT_RING_HIST_TYPE, rx_ring_hist_size);
	if (soc->rx_reinject_ring_history)
		qdf_atomic_init(&soc->rx_reinject_ring_history->index);
}
#else /* RX_DEFRAG_DO_NOT_REINJECT */
static inline void
dp_soc_rx_reinject_ring_history_attach(struct dp_soc *soc)
{
}
#endif /* RX_DEFRAG_DO_NOT_REINJECT */

/**
 * dp_soc_rx_history_attach() - Attach the ring history record buffers
 * @soc: DP soc structure
@@ -3818,23 +3840,23 @@ static void dp_soc_rx_history_attach(struct dp_soc *soc)
	uint32_t rx_err_ring_hist_size;
	uint32_t rx_reinject_hist_size;

	rx_ring_hist_size = sizeof(*soc->rx_ring_history[i]);
	rx_ring_hist_size = sizeof(*soc->rx_ring_history[0]);
	rx_err_ring_hist_size = sizeof(*soc->rx_err_ring_history);
	rx_reinject_hist_size = sizeof(*soc->rx_reinject_ring_history);

	for (i = 0; i < MAX_REO_DEST_RINGS; i++) {
		soc->rx_ring_history[i] = qdf_mem_malloc(rx_ring_hist_size);
		soc->rx_ring_history[i] = dp_context_alloc_mem(
				soc, DP_RX_RING_HIST_TYPE, rx_ring_hist_size);
		if (soc->rx_ring_history[i])
			qdf_atomic_init(&soc->rx_ring_history[i]->index);
	}

	soc->rx_err_ring_history = qdf_mem_malloc(rx_err_ring_hist_size);
	soc->rx_err_ring_history = dp_context_alloc_mem(
			soc, DP_RX_ERR_RING_HIST_TYPE, rx_ring_hist_size);
	if (soc->rx_err_ring_history)
		qdf_atomic_init(&soc->rx_err_ring_history->index);

	soc->rx_reinject_ring_history = qdf_mem_malloc(rx_reinject_hist_size);
	if (soc->rx_reinject_ring_history)
		qdf_atomic_init(&soc->rx_reinject_ring_history->index);
	dp_soc_rx_reinject_ring_history_attach(soc);
}

static void dp_soc_rx_history_detach(struct dp_soc *soc)
@@ -3842,10 +3864,18 @@ static void dp_soc_rx_history_detach(struct dp_soc *soc)
	int i;

	for (i = 0; i < MAX_REO_DEST_RINGS; i++)
		qdf_mem_free(soc->rx_ring_history[i]);
		dp_context_free_mem(soc, DP_RX_RING_HIST_TYPE,
				    soc->rx_ring_history[i]);

	dp_context_free_mem(soc, DP_RX_ERR_RING_HIST_TYPE,
			    soc->rx_err_ring_history);

	qdf_mem_free(soc->rx_err_ring_history);
	qdf_mem_free(soc->rx_reinject_ring_history);
	/*
	 * No need for a featurized detach since qdf_mem_free takes
	 * care of NULL pointer.
	 */
	dp_context_free_mem(soc, DP_RX_REINJECT_RING_HIST_TYPE,
			    soc->rx_reinject_ring_history);
}

#else
@@ -10817,7 +10847,7 @@ static void dp_rx_hw_stats_cb(struct dp_soc *soc, void *cb_ctxt,
		soc->ext_stats.rx_mpdu_received +=
					queue_status->mpdu_frms_cnt;
		soc->ext_stats.rx_mpdu_missed +=
					queue_status->late_recv_mpdu_cnt;
					queue_status->hole_cnt;
	}
	qdf_spin_unlock_bh(&soc->rx_hw_stats_lock);
}
+1 −1
Original line number Diff line number Diff line
@@ -1919,7 +1919,7 @@ dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num,
	struct hal_buf_info hbi;
	uint32_t idx;

	if (qdf_unlikely(!&soc->rx_ring_history[ring_num]))
	if (qdf_unlikely(!soc->rx_ring_history[ring_num]))
		return;

	hal_rx_reo_buf_paddr_get(ring_desc, &hbi);
+9 −1
Original line number Diff line number Diff line
@@ -284,9 +284,15 @@ enum dp_cpu_ring_map_types {
/**
 * enum dp_ctxt - context type
 * @DP_PDEV_TYPE: PDEV context
 * @DP_RX_RING_HIST_TYPE: Datapath rx ring history
 * @DP_RX_ERR_RING_HIST_TYPE: Datapath rx error ring history
 * @DP_RX_REINJECT_RING_HIST_TYPE: Datapath reinject ring history
 */
enum dp_ctxt_type {
	DP_PDEV_TYPE
	DP_PDEV_TYPE,
	DP_RX_RING_HIST_TYPE,
	DP_RX_ERR_RING_HIST_TYPE,
	DP_RX_REINJECT_RING_HIST_TYPE,
};

/**
@@ -1315,6 +1321,8 @@ struct dp_soc {
		void *ipa_wbm_ring_base_vaddr;
		uint32_t ipa_wbm_ring_size;
		qdf_dma_addr_t ipa_wbm_tp_paddr;
		/* WBM2SW HP shadow paddr */
		qdf_dma_addr_t ipa_wbm_hp_shadow_paddr;

		/* TX buffers populated into the WBM ring */
		void **tx_buf_pool_vaddr_unaligned;
+5 −4
Original line number Diff line number Diff line
@@ -153,8 +153,7 @@ static inline void hal_reg_write_result_check(struct hal_soc *hal_soc,
	}
}

#if !defined(QCA_WIFI_QCA6390) && !defined(QCA_WIFI_QCA6490) || \
    !defined(QCA_WIFI_QCA6750)
#if !defined(QCA_WIFI_QCA6390) && !defined(QCA_WIFI_QCA6490)
static inline void hal_lock_reg_access(struct hal_soc *soc,
				       unsigned long *flags)
{
@@ -1078,11 +1077,13 @@ void hal_reo_read_write_ctrl_ix(hal_soc_handle_t hal_soc_hdl, bool read,
				uint32_t *ix2, uint32_t *ix3);

/**
 * hal_srng_set_hp_paddr() - Set physical address to dest SRNG head pointer
 * hal_srng_set_hp_paddr_confirm() - Set physical address to dest SRNG head
 * pointer and confirm that write went through by reading back the value
 * @sring: sring pointer
 * @paddr: physical address
 */
extern void hal_srng_dst_set_hp_paddr(struct hal_srng *sring, uint64_t paddr);
extern void hal_srng_dst_set_hp_paddr_confirm(struct hal_srng *sring,
					      uint64_t paddr);

/**
 * hal_srng_dst_init_hp() - Initilaize head pointer with cached head pointer
Loading