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

Commit de5bfb10 authored by Rakesh Pillai's avatar Rakesh Pillai Committed by snandini
Browse files

qcacmn: Add history to track the entries in rx rings

The rx rings are relatively of smaller size. Any
duplicate entry sent by hardware cannot be back-tracked
by just looking at the ring contents alone.

Hence add a history to track the entries for the
REO2SW, REO exception and SW2REO ring.

Change-Id: I9b0b311950d60a9421378ce0fcc0535be450f713
CRs-Fixed: 2739181
parent 9bfcd903
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -94,6 +94,12 @@ cdp_dump_flow_pool_info(struct cdp_soc_t *soc)
#define SET_PEER_REF_CNT_ONE(_peer)
#endif

#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY
struct dp_rx_history dp_rx_ring_hist[MAX_REO_DEST_RINGS];
struct dp_rx_reinject_history dp_rx_reinject_ring_hist;
struct dp_rx_err_history dp_rx_err_ring_hist;
#endif

/*
 * The max size of cdp_peer_stats_param_t is limited to 16 bytes.
 * If the buffer size is exceeding this size limit,
@@ -10790,6 +10796,28 @@ static void dp_process_wow_ack_rsp(struct cdp_soc_t *soc_hdl, uint8_t pdev_id)
	}
}

#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY
static void dp_soc_rx_history_attach(struct dp_soc *soc)
{
	int i;

	for (i = 0; i < MAX_REO_DEST_RINGS; i++) {
		soc->rx_ring_history[i] = &dp_rx_ring_hist[i];
		qdf_atomic_init(&soc->rx_ring_history[i]->index);
	}

	soc->rx_err_ring_history = &dp_rx_err_ring_hist;
	soc->rx_reinject_ring_history = &dp_rx_reinject_ring_hist;

	qdf_atomic_init(&soc->rx_err_ring_history->index);
	qdf_atomic_init(&soc->rx_reinject_ring_history->index);
}
#else
static inline void dp_soc_rx_history_attach(struct dp_soc *soc)
{
}
#endif

/**
 * dp_process_target_suspend_req() - process target suspend request
 * @soc_hdl: datapath soc handle
@@ -11001,6 +11029,7 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
	soc->osdev = qdf_osdev;
	soc->num_hw_dscp_tid_map = HAL_MAX_HW_DSCP_TID_MAPS;

	dp_soc_rx_history_attach(soc);
	wlan_set_srng_cfg(&soc->wlan_srng_cfg);
	qdf_mem_zero(&soc->vdev_id_map, sizeof(soc->vdev_id_map));

+28 −0
Original line number Diff line number Diff line
@@ -1902,6 +1902,33 @@ bool dp_rx_is_raw_frame_dropped(qdf_nbuf_t nbuf)
}
#endif

#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY
static inline void
dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num, hal_ring_desc_t ring_desc)
{
	struct dp_buf_info_record *record;
	uint8_t rbm;
	struct hal_buf_info hbi;
	uint32_t idx;

	hal_rx_reo_buf_paddr_get(ring_desc, &hbi);
	rbm = hal_rx_ret_buf_manager_get(ring_desc);

	idx = dp_history_get_next_index(&soc->rx_ring_history[ring_num]->index, DP_RX_HIST_MAX);
	record = &soc->rx_ring_history[ring_num]->entry[idx];

	record->timestamp = qdf_get_log_timestamp();
	record->hbi.paddr = hbi.paddr;
	record->hbi.sw_cookie = hbi.sw_cookie;
	record->hbi.rbm = rbm;
}
#else
static inline void
dp_rx_ring_record_entry(struct dp_soc *soc, uint8_t ring_num, hal_ring_desc_t ring_desc)
{
}
#endif

/**
 * dp_rx_process() - Brain of the Rx processing functionality
 *		     Called from the bottom half (tasklet/NET_RX_SOFTIRQ)
@@ -2021,6 +2048,7 @@ uint32_t dp_rx_process(struct dp_intr *int_ctx, hal_ring_handle_t hal_ring_hdl,
			qdf_assert(0);
		}

		dp_rx_ring_record_entry(soc, reo_ring_num, ring_desc);
		rx_buf_cookie = HAL_RX_REO_BUF_COOKIE_GET(ring_desc);
		status = dp_rx_cookie_check_and_invalidate(ring_desc);
		if (qdf_unlikely(QDF_IS_STATUS_ERROR(status))) {
+26 −0
Original line number Diff line number Diff line
@@ -1000,6 +1000,31 @@ dp_rx_defrag_nwifi_to_8023(struct dp_soc *soc,
	qdf_mem_free(rx_desc_info);
}

#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY
static inline void
dp_rx_reinject_ring_record_entry(struct dp_soc *soc, uint64_t paddr,
				 uint32_t sw_cookie, uint8_t rbm)
{
	struct dp_buf_info_record *record;
	uint32_t idx;

	idx = dp_history_get_next_index(&soc->rx_reinject_ring_history->index,
					DP_RX_REINJECT_HIST_MAX);
	record = &soc->rx_reinject_ring_history->entry[idx];

	record->timestamp = qdf_get_log_timestamp();
	record->hbi.paddr = paddr;
	record->hbi.sw_cookie = sw_cookie;
	record->hbi.rbm = rbm;
}
#else
static inline void
dp_rx_reinject_ring_record_entry(struct dp_soc *soc, uint64_t paddr,
				 uint32_t sw_cookie, uint8_t rbm)
{
}
#endif

/*
 * dp_rx_defrag_reo_reinject(): Reinject the fragment chain back into REO
 * @peer: Pointer to the peer
@@ -1133,6 +1158,7 @@ static QDF_STATUS dp_rx_defrag_reo_reinject(struct dp_peer *peer,
		return QDF_STATUS_E_FAILURE;
	}

	dp_rx_reinject_ring_record_entry(soc, paddr, cookie, DP_DEFRAG_RBM);
	paddr = (uint64_t)buf_info.paddr;
	/* buf addr */
	hal_rxdma_buff_addr_info_set(ent_ring_desc, paddr,
+25 −1
Original line number Diff line number Diff line
@@ -1383,6 +1383,28 @@ dp_rx_link_cookie_invalidate(hal_ring_desc_t ring_desc)
}
#endif

#ifdef WLAN_FEATURE_DP_RX_RING_HISTORY
static inline void
dp_rx_err_ring_record_entry(struct dp_soc *soc, uint64_t paddr, uint32_t sw_cookie, uint8_t rbm)
{
	struct dp_buf_info_record *record;
	uint32_t idx;

	idx = dp_history_get_next_index(&soc->rx_err_ring_history->index, DP_RX_ERR_HIST_MAX);
	record = &soc->rx_err_ring_history->entry[idx];

	record->timestamp = qdf_get_log_timestamp();
	record->hbi.paddr = paddr;
	record->hbi.sw_cookie = sw_cookie;
	record->hbi.rbm = rbm;
}
#else
static inline void
dp_rx_err_ring_record_entry(struct dp_soc *soc, uint64_t paddr, uint32_t sw_cookie, uint8_t rbm)
{
}
#endif

uint32_t
dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
		  hal_ring_handle_t hal_ring_hdl, uint32_t quota)
@@ -1466,7 +1488,9 @@ dp_rx_err_process(struct dp_intr *int_ctx, struct dp_soc *soc,
		link_desc_va = dp_rx_cookie_2_link_desc_va(soc, &hbi);
		hal_rx_msdu_list_get(soc->hal_soc, link_desc_va, &msdu_list,
				     &num_msdus);

		dp_rx_err_ring_record_entry(soc, msdu_list.paddr[0],
					    msdu_list.sw_cookie[0],
					    msdu_list.rbm[0]);
		if (qdf_unlikely((msdu_list.rbm[0] != DP_WBM2SW_RBM) &&
				(msdu_list.rbm[0] !=
					HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST) &&
+36 −0
Original line number Diff line number Diff line
@@ -916,6 +916,38 @@ struct htt_t2h_stats {
	uint32_t num_stats;
};

#define DP_RX_HIST_MAX 2048
#define DP_RX_ERR_HIST_MAX 4096
#define DP_RX_REINJECT_HIST_MAX 1024

struct dp_buf_info_record {
	struct hal_buf_info hbi;
	uint64_t timestamp;
};

struct dp_rx_history {
	qdf_atomic_t index;
	struct dp_buf_info_record entry[DP_RX_HIST_MAX];
};

struct dp_rx_err_history {
	qdf_atomic_t index;
	struct dp_buf_info_record entry[DP_RX_ERR_HIST_MAX];
};

struct dp_rx_reinject_history {
	qdf_atomic_t index;
	struct dp_buf_info_record entry[DP_RX_REINJECT_HIST_MAX];
};

static inline uint32_t dp_history_get_next_index(qdf_atomic_t *curr_idx,
						 uint32_t max_entries)
{
	uint32_t idx = qdf_atomic_inc_return(curr_idx);

	return idx & (max_entries - 1);
}

/* SOC level structure for data path */
struct dp_soc {
	/**
@@ -1164,6 +1196,10 @@ struct dp_soc {
		TAILQ_HEAD(, dp_ast_entry) * bins;
	} ast_hash;

	struct dp_rx_history *rx_ring_history[MAX_REO_DEST_RINGS];
	struct dp_rx_err_history *rx_err_ring_history;
	struct dp_rx_reinject_history *rx_reinject_ring_history;

	qdf_spinlock_t ast_lock;
	/*Timer for AST entry ageout maintainance */
	qdf_timer_t ast_aging_timer;