xref: /dpdk/drivers/net/pfe/pfe_hif_lib.c (revision f665790a5dbad7b645ff46f31d65e977324e7bfc)
15253fe37SGagandeep Singh /* SPDX-License-Identifier: BSD-3-Clause
2f513f620SSachin Saxena  * Copyright 2018-2019 NXP
35253fe37SGagandeep Singh  */
45253fe37SGagandeep Singh 
55253fe37SGagandeep Singh #include "pfe_logs.h"
65253fe37SGagandeep Singh #include "pfe_mod.h"
75253fe37SGagandeep Singh 
8fe38ad9bSGagandeep Singh unsigned int emac_txq_cnt;
9fe38ad9bSGagandeep Singh 
10fe38ad9bSGagandeep Singh /*
11fe38ad9bSGagandeep Singh  * @pfe_hal_lib.c
12fe38ad9bSGagandeep Singh  * Common functions used by HIF client drivers
13fe38ad9bSGagandeep Singh  */
14fe38ad9bSGagandeep Singh 
15fe38ad9bSGagandeep Singh /*HIF shared memory Global variable */
16fe38ad9bSGagandeep Singh struct hif_shm ghif_shm;
17fe38ad9bSGagandeep Singh 
18592041a0SGagandeep Singh /* Cleanup the HIF shared memory, release HIF rx_buffer_pool.
19592041a0SGagandeep Singh  * This function should be called after pfe_hif_exit
20592041a0SGagandeep Singh  *
21592041a0SGagandeep Singh  * @param[in] hif_shm		Shared memory address location in DDR
22592041a0SGagandeep Singh  */
23592041a0SGagandeep Singh void
24592041a0SGagandeep Singh pfe_hif_shm_clean(struct hif_shm *hif_shm)
25592041a0SGagandeep Singh {
26592041a0SGagandeep Singh 	unsigned int i;
27592041a0SGagandeep Singh 	void *pkt;
28592041a0SGagandeep Singh 
29592041a0SGagandeep Singh 	for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) {
30592041a0SGagandeep Singh 		pkt = hif_shm->rx_buf_pool[i];
31592041a0SGagandeep Singh 		if (pkt)
32592041a0SGagandeep Singh 			rte_pktmbuf_free((struct rte_mbuf *)pkt);
33592041a0SGagandeep Singh 	}
34592041a0SGagandeep Singh }
35592041a0SGagandeep Singh 
36592041a0SGagandeep Singh /* Initialize shared memory used between HIF driver and clients,
37592041a0SGagandeep Singh  * allocate rx_buffer_pool required for HIF Rx descriptors.
38592041a0SGagandeep Singh  * This function should be called before initializing HIF driver.
39592041a0SGagandeep Singh  *
40592041a0SGagandeep Singh  * @param[in] hif_shm		Shared memory address location in DDR
417be78d02SJosh Soref  * @return			0 - on succes, <0 on fail to initialize
42592041a0SGagandeep Singh  */
43592041a0SGagandeep Singh int
44592041a0SGagandeep Singh pfe_hif_shm_init(struct hif_shm *hif_shm, struct rte_mempool *mb_pool)
45592041a0SGagandeep Singh {
46592041a0SGagandeep Singh 	unsigned int i;
47592041a0SGagandeep Singh 	struct rte_mbuf *mbuf;
48592041a0SGagandeep Singh 
49592041a0SGagandeep Singh 	memset(hif_shm, 0, sizeof(struct hif_shm));
50592041a0SGagandeep Singh 	hif_shm->rx_buf_pool_cnt = HIF_RX_DESC_NT;
51592041a0SGagandeep Singh 
52592041a0SGagandeep Singh 	for (i = 0; i < hif_shm->rx_buf_pool_cnt; i++) {
53592041a0SGagandeep Singh 		mbuf = rte_cpu_to_le_64(rte_pktmbuf_alloc(mb_pool));
54592041a0SGagandeep Singh 		if (mbuf)
55592041a0SGagandeep Singh 			hif_shm->rx_buf_pool[i] = mbuf;
56592041a0SGagandeep Singh 		else
57592041a0SGagandeep Singh 			goto err0;
58592041a0SGagandeep Singh 	}
59592041a0SGagandeep Singh 
60592041a0SGagandeep Singh 	return 0;
61592041a0SGagandeep Singh 
62592041a0SGagandeep Singh err0:
63592041a0SGagandeep Singh 	PFE_PMD_ERR("Low memory");
64592041a0SGagandeep Singh 	pfe_hif_shm_clean(hif_shm);
65592041a0SGagandeep Singh 	return -ENOMEM;
66592041a0SGagandeep Singh }
67592041a0SGagandeep Singh 
68fe38ad9bSGagandeep Singh /*This function sends indication to HIF driver
69fe38ad9bSGagandeep Singh  *
70fe38ad9bSGagandeep Singh  * @param[in] hif	hif context
71fe38ad9bSGagandeep Singh  */
72fe38ad9bSGagandeep Singh static void
73fe38ad9bSGagandeep Singh hif_lib_indicate_hif(struct pfe_hif *hif, int req, int data1, int
74fe38ad9bSGagandeep Singh 		     data2)
75fe38ad9bSGagandeep Singh {
76fe38ad9bSGagandeep Singh 	hif_process_client_req(hif, req, data1, data2);
77fe38ad9bSGagandeep Singh }
78fe38ad9bSGagandeep Singh 
79fe38ad9bSGagandeep Singh void
80fe38ad9bSGagandeep Singh hif_lib_indicate_client(struct hif_client_s *client, int event_type,
81fe38ad9bSGagandeep Singh 			int qno)
82fe38ad9bSGagandeep Singh {
83fe38ad9bSGagandeep Singh 	if (!client || event_type >= HIF_EVENT_MAX ||
84fe38ad9bSGagandeep Singh 	    qno >= HIF_CLIENT_QUEUES_MAX)
85fe38ad9bSGagandeep Singh 		return;
86fe38ad9bSGagandeep Singh 
87fe38ad9bSGagandeep Singh 	if (!test_and_set_bit(qno, &client->queue_mask[event_type]))
88fe38ad9bSGagandeep Singh 		client->event_handler(client->priv, event_type, qno);
89fe38ad9bSGagandeep Singh }
90fe38ad9bSGagandeep Singh 
91fe38ad9bSGagandeep Singh /*This function releases Rx queue descriptors memory and pre-filled buffers
92fe38ad9bSGagandeep Singh  *
93fe38ad9bSGagandeep Singh  * @param[in] client	hif_client context
94fe38ad9bSGagandeep Singh  */
95fe38ad9bSGagandeep Singh static void
96fe38ad9bSGagandeep Singh hif_lib_client_release_rx_buffers(struct hif_client_s *client)
97fe38ad9bSGagandeep Singh {
98fe38ad9bSGagandeep Singh 	struct rte_mempool *pool;
99fe38ad9bSGagandeep Singh 	struct rte_pktmbuf_pool_private *mb_priv;
100fe38ad9bSGagandeep Singh 	struct rx_queue_desc *desc;
101fe38ad9bSGagandeep Singh 	unsigned int qno, ii;
102fe38ad9bSGagandeep Singh 	void *buf;
103fe38ad9bSGagandeep Singh 
104fe38ad9bSGagandeep Singh 	pool = client->pfe->hif.shm->pool;
105fe38ad9bSGagandeep Singh 	mb_priv = rte_mempool_get_priv(pool);
106fe38ad9bSGagandeep Singh 	for (qno = 0; qno < client->rx_qn; qno++) {
107fe38ad9bSGagandeep Singh 		desc = client->rx_q[qno].base;
108fe38ad9bSGagandeep Singh 
109fe38ad9bSGagandeep Singh 		for (ii = 0; ii < client->rx_q[qno].size; ii++) {
110fe38ad9bSGagandeep Singh 			buf = (void *)desc->data;
111fe38ad9bSGagandeep Singh 			if (buf) {
1127be78d02SJosh Soref 			/* Data pointer to mbuf pointer calculation:
113fe38ad9bSGagandeep Singh 			 * "Data - User private data - headroom - mbufsize"
1147be78d02SJosh Soref 			 * Actual data pointer given to HIF BDs was
115fe38ad9bSGagandeep Singh 			 * "mbuf->data_offset - PFE_PKT_HEADER_SZ"
116fe38ad9bSGagandeep Singh 			 */
117fe38ad9bSGagandeep Singh 				buf = buf + PFE_PKT_HEADER_SZ
118fe38ad9bSGagandeep Singh 					- sizeof(struct rte_mbuf)
119fe38ad9bSGagandeep Singh 					- RTE_PKTMBUF_HEADROOM
120fe38ad9bSGagandeep Singh 					- mb_priv->mbuf_priv_size;
121fe38ad9bSGagandeep Singh 				rte_pktmbuf_free((struct rte_mbuf *)buf);
122fe38ad9bSGagandeep Singh 				desc->ctrl = 0;
123fe38ad9bSGagandeep Singh 			}
124fe38ad9bSGagandeep Singh 			desc++;
125fe38ad9bSGagandeep Singh 		}
126fe38ad9bSGagandeep Singh 	}
127fe38ad9bSGagandeep Singh 	rte_free(client->rx_qbase);
128fe38ad9bSGagandeep Singh }
129fe38ad9bSGagandeep Singh 
130fe38ad9bSGagandeep Singh /*This function allocates memory for the rxq descriptors and pre-fill rx queues
131fe38ad9bSGagandeep Singh  * with buffers.
132fe38ad9bSGagandeep Singh  * @param[in] client	client context
133fe38ad9bSGagandeep Singh  * @param[in] q_size	size of the rxQ, all queues are of same size
134fe38ad9bSGagandeep Singh  */
135fe38ad9bSGagandeep Singh static int
136fe38ad9bSGagandeep Singh hif_lib_client_init_rx_buffers(struct hif_client_s *client,
137fe38ad9bSGagandeep Singh 					  int q_size)
138fe38ad9bSGagandeep Singh {
139fe38ad9bSGagandeep Singh 	struct rx_queue_desc *desc;
140fe38ad9bSGagandeep Singh 	struct hif_client_rx_queue *queue;
141fe38ad9bSGagandeep Singh 	unsigned int ii, qno;
142fe38ad9bSGagandeep Singh 
143fe38ad9bSGagandeep Singh 	/*Allocate memory for the client queues */
144fe38ad9bSGagandeep Singh 	client->rx_qbase = rte_malloc(NULL, client->rx_qn * q_size *
145fe38ad9bSGagandeep Singh 			sizeof(struct rx_queue_desc), RTE_CACHE_LINE_SIZE);
146fe38ad9bSGagandeep Singh 	if (!client->rx_qbase)
147fe38ad9bSGagandeep Singh 		goto err;
148fe38ad9bSGagandeep Singh 
149fe38ad9bSGagandeep Singh 	for (qno = 0; qno < client->rx_qn; qno++) {
150fe38ad9bSGagandeep Singh 		queue = &client->rx_q[qno];
151fe38ad9bSGagandeep Singh 
152fe38ad9bSGagandeep Singh 		queue->base = client->rx_qbase + qno * q_size * sizeof(struct
153fe38ad9bSGagandeep Singh 				rx_queue_desc);
154fe38ad9bSGagandeep Singh 		queue->size = q_size;
155fe38ad9bSGagandeep Singh 		queue->read_idx = 0;
156fe38ad9bSGagandeep Singh 		queue->write_idx = 0;
157fe38ad9bSGagandeep Singh 		queue->queue_id = 0;
158fe38ad9bSGagandeep Singh 		queue->port_id = client->port_id;
159fe38ad9bSGagandeep Singh 		queue->priv = client->priv;
160*f665790aSDavid Marchand 		PFE_PMD_DEBUG("rx queue: %d, base: %p, size: %d", qno,
161fe38ad9bSGagandeep Singh 			      queue->base, queue->size);
162fe38ad9bSGagandeep Singh 	}
163fe38ad9bSGagandeep Singh 
164fe38ad9bSGagandeep Singh 	for (qno = 0; qno < client->rx_qn; qno++) {
165fe38ad9bSGagandeep Singh 		queue = &client->rx_q[qno];
166fe38ad9bSGagandeep Singh 		desc = queue->base;
167fe38ad9bSGagandeep Singh 
168fe38ad9bSGagandeep Singh 		for (ii = 0; ii < queue->size; ii++) {
169fe38ad9bSGagandeep Singh 			desc->ctrl = CL_DESC_OWN;
170fe38ad9bSGagandeep Singh 			desc++;
171fe38ad9bSGagandeep Singh 		}
172fe38ad9bSGagandeep Singh 	}
173fe38ad9bSGagandeep Singh 
174fe38ad9bSGagandeep Singh 	return 0;
175fe38ad9bSGagandeep Singh 
176fe38ad9bSGagandeep Singh err:
177fe38ad9bSGagandeep Singh 	return 1;
178fe38ad9bSGagandeep Singh }
179fe38ad9bSGagandeep Singh 
180fe38ad9bSGagandeep Singh 
181fe38ad9bSGagandeep Singh static void
182fe38ad9bSGagandeep Singh hif_lib_client_cleanup_tx_queue(struct hif_client_tx_queue *queue)
183fe38ad9bSGagandeep Singh {
184fe38ad9bSGagandeep Singh 	/*
185fe38ad9bSGagandeep Singh 	 * Check if there are any pending packets. Client must flush the tx
186fe38ad9bSGagandeep Singh 	 * queues before unregistering, by calling by calling
187fe38ad9bSGagandeep Singh 	 * hif_lib_tx_get_next_complete()
188fe38ad9bSGagandeep Singh 	 *
189fe38ad9bSGagandeep Singh 	 * Hif no longer calls since we are no longer registered
190fe38ad9bSGagandeep Singh 	 */
191fe38ad9bSGagandeep Singh 	if (queue->tx_pending)
192fe38ad9bSGagandeep Singh 		PFE_PMD_ERR("pending transmit packet");
193fe38ad9bSGagandeep Singh }
194fe38ad9bSGagandeep Singh 
195fe38ad9bSGagandeep Singh static void
196fe38ad9bSGagandeep Singh hif_lib_client_release_tx_buffers(struct hif_client_s *client)
197fe38ad9bSGagandeep Singh {
198fe38ad9bSGagandeep Singh 	unsigned int qno;
199fe38ad9bSGagandeep Singh 
200fe38ad9bSGagandeep Singh 	for (qno = 0; qno < client->tx_qn; qno++)
201fe38ad9bSGagandeep Singh 		hif_lib_client_cleanup_tx_queue(&client->tx_q[qno]);
202fe38ad9bSGagandeep Singh 
203fe38ad9bSGagandeep Singh 	rte_free(client->tx_qbase);
204fe38ad9bSGagandeep Singh }
205fe38ad9bSGagandeep Singh 
206fe38ad9bSGagandeep Singh static int
207fe38ad9bSGagandeep Singh hif_lib_client_init_tx_buffers(struct hif_client_s *client, int
208fe38ad9bSGagandeep Singh 						q_size)
209fe38ad9bSGagandeep Singh {
210fe38ad9bSGagandeep Singh 	struct hif_client_tx_queue *queue;
211fe38ad9bSGagandeep Singh 	unsigned int qno;
212fe38ad9bSGagandeep Singh 
213fe38ad9bSGagandeep Singh 	client->tx_qbase = rte_malloc(NULL, client->tx_qn * q_size *
214fe38ad9bSGagandeep Singh 			sizeof(struct tx_queue_desc), RTE_CACHE_LINE_SIZE);
215fe38ad9bSGagandeep Singh 	if (!client->tx_qbase)
216fe38ad9bSGagandeep Singh 		return 1;
217fe38ad9bSGagandeep Singh 
218fe38ad9bSGagandeep Singh 	for (qno = 0; qno < client->tx_qn; qno++) {
219fe38ad9bSGagandeep Singh 		queue = &client->tx_q[qno];
220fe38ad9bSGagandeep Singh 
221fe38ad9bSGagandeep Singh 		queue->base = client->tx_qbase + qno * q_size * sizeof(struct
222fe38ad9bSGagandeep Singh 				tx_queue_desc);
223fe38ad9bSGagandeep Singh 		queue->size = q_size;
224fe38ad9bSGagandeep Singh 		queue->read_idx = 0;
225fe38ad9bSGagandeep Singh 		queue->write_idx = 0;
226fe38ad9bSGagandeep Singh 		queue->tx_pending = 0;
227fe38ad9bSGagandeep Singh 		queue->nocpy_flag = 0;
228fe38ad9bSGagandeep Singh 		queue->prev_tmu_tx_pkts = 0;
229fe38ad9bSGagandeep Singh 		queue->done_tmu_tx_pkts = 0;
230fe38ad9bSGagandeep Singh 		queue->priv = client->priv;
231fe38ad9bSGagandeep Singh 		queue->queue_id = 0;
232fe38ad9bSGagandeep Singh 		queue->port_id = client->port_id;
233fe38ad9bSGagandeep Singh 
234fe38ad9bSGagandeep Singh 		PFE_PMD_DEBUG("tx queue: %d, base: %p, size: %d", qno,
235fe38ad9bSGagandeep Singh 			 queue->base, queue->size);
236fe38ad9bSGagandeep Singh 	}
237fe38ad9bSGagandeep Singh 
238fe38ad9bSGagandeep Singh 	return 0;
239fe38ad9bSGagandeep Singh }
240fe38ad9bSGagandeep Singh 
241fe38ad9bSGagandeep Singh static int
242fe38ad9bSGagandeep Singh hif_lib_event_dummy(__rte_unused void *priv,
243fe38ad9bSGagandeep Singh 		__rte_unused int event_type, __rte_unused int qno)
244fe38ad9bSGagandeep Singh {
245fe38ad9bSGagandeep Singh 	return 0;
246fe38ad9bSGagandeep Singh }
247fe38ad9bSGagandeep Singh 
2485253fe37SGagandeep Singh int
249fe38ad9bSGagandeep Singh hif_lib_client_register(struct hif_client_s *client)
250fe38ad9bSGagandeep Singh {
251fe38ad9bSGagandeep Singh 	struct hif_shm *hif_shm;
252fe38ad9bSGagandeep Singh 	struct hif_client_shm *client_shm;
253fe38ad9bSGagandeep Singh 	int err, i;
254fe38ad9bSGagandeep Singh 
255fe38ad9bSGagandeep Singh 	PMD_INIT_FUNC_TRACE();
256fe38ad9bSGagandeep Singh 
257fe38ad9bSGagandeep Singh 	/*Allocate memory before spin_lock*/
258fe38ad9bSGagandeep Singh 	if (hif_lib_client_init_rx_buffers(client, client->rx_qsize)) {
259fe38ad9bSGagandeep Singh 		err = -ENOMEM;
260fe38ad9bSGagandeep Singh 		goto err_rx;
261fe38ad9bSGagandeep Singh 	}
262fe38ad9bSGagandeep Singh 
263fe38ad9bSGagandeep Singh 	if (hif_lib_client_init_tx_buffers(client, client->tx_qsize)) {
264fe38ad9bSGagandeep Singh 		err = -ENOMEM;
265fe38ad9bSGagandeep Singh 		goto err_tx;
266fe38ad9bSGagandeep Singh 	}
267fe38ad9bSGagandeep Singh 
268fe38ad9bSGagandeep Singh 	rte_spinlock_lock(&client->pfe->hif.lock);
269fe38ad9bSGagandeep Singh 	if (!(client->pfe) || client->id >= HIF_CLIENTS_MAX ||
270fe38ad9bSGagandeep Singh 	    client->pfe->hif_client[client->id]) {
271fe38ad9bSGagandeep Singh 		err = -EINVAL;
272fe38ad9bSGagandeep Singh 		goto err;
273fe38ad9bSGagandeep Singh 	}
274fe38ad9bSGagandeep Singh 
275fe38ad9bSGagandeep Singh 	hif_shm = client->pfe->hif.shm;
276fe38ad9bSGagandeep Singh 
277fe38ad9bSGagandeep Singh 	if (!client->event_handler)
278fe38ad9bSGagandeep Singh 		client->event_handler = hif_lib_event_dummy;
279fe38ad9bSGagandeep Singh 
280fe38ad9bSGagandeep Singh 	/*Initialize client specific shared memory */
281fe38ad9bSGagandeep Singh 	client_shm = (struct hif_client_shm *)&hif_shm->client[client->id];
282fe38ad9bSGagandeep Singh 	client_shm->rx_qbase = (unsigned long)client->rx_qbase;
283fe38ad9bSGagandeep Singh 	client_shm->rx_qsize = client->rx_qsize;
284fe38ad9bSGagandeep Singh 	client_shm->tx_qbase = (unsigned long)client->tx_qbase;
285fe38ad9bSGagandeep Singh 	client_shm->tx_qsize = client->tx_qsize;
286fe38ad9bSGagandeep Singh 	client_shm->ctrl = (client->tx_qn << CLIENT_CTRL_TX_Q_CNT_OFST) |
287fe38ad9bSGagandeep Singh 				(client->rx_qn << CLIENT_CTRL_RX_Q_CNT_OFST);
288fe38ad9bSGagandeep Singh 
289fe38ad9bSGagandeep Singh 	for (i = 0; i < HIF_EVENT_MAX; i++) {
290fe38ad9bSGagandeep Singh 		client->queue_mask[i] = 0;  /*
291fe38ad9bSGagandeep Singh 					     * By default all events are
292fe38ad9bSGagandeep Singh 					     * unmasked
293fe38ad9bSGagandeep Singh 					     */
294fe38ad9bSGagandeep Singh 	}
295fe38ad9bSGagandeep Singh 
296fe38ad9bSGagandeep Singh 	/*Indicate to HIF driver*/
297fe38ad9bSGagandeep Singh 	hif_lib_indicate_hif(&client->pfe->hif, REQUEST_CL_REGISTER,
298fe38ad9bSGagandeep Singh 			client->id, 0);
299fe38ad9bSGagandeep Singh 
300fe38ad9bSGagandeep Singh 	PFE_PMD_DEBUG("client: %p, client_id: %d, tx_qsize: %d, rx_qsize: %d",
301fe38ad9bSGagandeep Singh 		      client, client->id, client->tx_qsize, client->rx_qsize);
302fe38ad9bSGagandeep Singh 
303fe38ad9bSGagandeep Singh 	client->cpu_id = -1;
304fe38ad9bSGagandeep Singh 
305fe38ad9bSGagandeep Singh 	client->pfe->hif_client[client->id] = client;
306fe38ad9bSGagandeep Singh 	rte_spinlock_unlock(&client->pfe->hif.lock);
307fe38ad9bSGagandeep Singh 
308fe38ad9bSGagandeep Singh 	return 0;
309fe38ad9bSGagandeep Singh 
310fe38ad9bSGagandeep Singh err:
311fe38ad9bSGagandeep Singh 	rte_spinlock_unlock(&client->pfe->hif.lock);
312fe38ad9bSGagandeep Singh 	hif_lib_client_release_tx_buffers(client);
313fe38ad9bSGagandeep Singh 
314fe38ad9bSGagandeep Singh err_tx:
315fe38ad9bSGagandeep Singh 	hif_lib_client_release_rx_buffers(client);
316fe38ad9bSGagandeep Singh 
317fe38ad9bSGagandeep Singh err_rx:
318fe38ad9bSGagandeep Singh 	return err;
319fe38ad9bSGagandeep Singh }
320fe38ad9bSGagandeep Singh 
321fe38ad9bSGagandeep Singh int
322fe38ad9bSGagandeep Singh hif_lib_client_unregister(struct hif_client_s *client)
323fe38ad9bSGagandeep Singh {
324fe38ad9bSGagandeep Singh 	struct pfe *pfe = client->pfe;
325fe38ad9bSGagandeep Singh 	u32 client_id = client->id;
326fe38ad9bSGagandeep Singh 
327fe38ad9bSGagandeep Singh 	PFE_PMD_INFO("client: %p, client_id: %d, txQ_depth: %d, rxQ_depth: %d",
328fe38ad9bSGagandeep Singh 		     client, client->id, client->tx_qsize, client->rx_qsize);
329fe38ad9bSGagandeep Singh 
330fe38ad9bSGagandeep Singh 	rte_spinlock_lock(&pfe->hif.lock);
331fe38ad9bSGagandeep Singh 	hif_lib_indicate_hif(&pfe->hif, REQUEST_CL_UNREGISTER, client->id, 0);
332fe38ad9bSGagandeep Singh 
333fe38ad9bSGagandeep Singh 	hif_lib_client_release_tx_buffers(client);
334fe38ad9bSGagandeep Singh 	hif_lib_client_release_rx_buffers(client);
335fe38ad9bSGagandeep Singh 	pfe->hif_client[client_id] = NULL;
336fe38ad9bSGagandeep Singh 	rte_spinlock_unlock(&pfe->hif.lock);
337fe38ad9bSGagandeep Singh 
338fe38ad9bSGagandeep Singh 	return 0;
339fe38ad9bSGagandeep Singh }
340fe38ad9bSGagandeep Singh 
341fe38ad9bSGagandeep Singh int
342fe38ad9bSGagandeep Singh hif_lib_event_handler_start(struct hif_client_s *client, int event,
343fe38ad9bSGagandeep Singh 				int qno)
344fe38ad9bSGagandeep Singh {
345fe38ad9bSGagandeep Singh 	struct hif_client_rx_queue *queue = &client->rx_q[qno];
346fe38ad9bSGagandeep Singh 	struct rx_queue_desc *desc = queue->base + queue->read_idx;
347fe38ad9bSGagandeep Singh 
348fe38ad9bSGagandeep Singh 	if (event >= HIF_EVENT_MAX || qno >= HIF_CLIENT_QUEUES_MAX) {
349fe38ad9bSGagandeep Singh 		PFE_PMD_WARN("Unsupported event : %d  queue number : %d",
350fe38ad9bSGagandeep Singh 				event, qno);
351fe38ad9bSGagandeep Singh 		return -1;
352fe38ad9bSGagandeep Singh 	}
353fe38ad9bSGagandeep Singh 
354fe38ad9bSGagandeep Singh 	test_and_clear_bit(qno, &client->queue_mask[event]);
355fe38ad9bSGagandeep Singh 
356fe38ad9bSGagandeep Singh 	switch (event) {
357fe38ad9bSGagandeep Singh 	case EVENT_RX_PKT_IND:
358fe38ad9bSGagandeep Singh 		if (!(desc->ctrl & CL_DESC_OWN))
359fe38ad9bSGagandeep Singh 			hif_lib_indicate_client(client,
360fe38ad9bSGagandeep Singh 						EVENT_RX_PKT_IND, qno);
361fe38ad9bSGagandeep Singh 		break;
362fe38ad9bSGagandeep Singh 
363fe38ad9bSGagandeep Singh 	case EVENT_HIGH_RX_WM:
364fe38ad9bSGagandeep Singh 	case EVENT_TXDONE_IND:
365fe38ad9bSGagandeep Singh 	default:
366fe38ad9bSGagandeep Singh 		break;
367fe38ad9bSGagandeep Singh 	}
368fe38ad9bSGagandeep Singh 
369fe38ad9bSGagandeep Singh 	return 0;
370fe38ad9bSGagandeep Singh }
371fe38ad9bSGagandeep Singh 
37236220514SGagandeep Singh #ifdef RTE_LIBRTE_PFE_SW_PARSE
37336220514SGagandeep Singh static inline void
37436220514SGagandeep Singh pfe_sw_parse_pkt(struct rte_mbuf *mbuf)
37536220514SGagandeep Singh {
37636220514SGagandeep Singh 	struct rte_net_hdr_lens hdr_lens;
37736220514SGagandeep Singh 
37836220514SGagandeep Singh 	mbuf->packet_type = rte_net_get_ptype(mbuf, &hdr_lens,
37936220514SGagandeep Singh 			RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK
38036220514SGagandeep Singh 			| RTE_PTYPE_L4_MASK);
38136220514SGagandeep Singh 	mbuf->l2_len = hdr_lens.l2_len;
38236220514SGagandeep Singh 	mbuf->l3_len = hdr_lens.l3_len;
38336220514SGagandeep Singh }
38436220514SGagandeep Singh #endif
38536220514SGagandeep Singh 
38636220514SGagandeep Singh /*
38736220514SGagandeep Singh  * This function gets one packet from the specified client queue
38836220514SGagandeep Singh  * It also refill the rx buffer
38936220514SGagandeep Singh  */
39036220514SGagandeep Singh int
39136220514SGagandeep Singh hif_lib_receive_pkt(struct hif_client_rx_queue *queue,
39236220514SGagandeep Singh 		struct rte_mempool *pool, struct rte_mbuf **rx_pkts,
39336220514SGagandeep Singh 		uint16_t nb_pkts)
39436220514SGagandeep Singh {
39536220514SGagandeep Singh 	struct rx_queue_desc *desc;
39636220514SGagandeep Singh 	struct pfe_eth_priv_s *priv = queue->priv;
39736220514SGagandeep Singh 	struct rte_pktmbuf_pool_private *mb_priv;
39836220514SGagandeep Singh 	struct rte_mbuf *mbuf, *p_mbuf = NULL, *first_mbuf = NULL;
39936220514SGagandeep Singh 	struct rte_eth_stats *stats = &priv->stats;
40036220514SGagandeep Singh 	int i, wait_for_last = 0;
40136220514SGagandeep Singh #ifndef RTE_LIBRTE_PFE_SW_PARSE
40236220514SGagandeep Singh 	struct pfe_parse *parse_res;
40336220514SGagandeep Singh #endif
40436220514SGagandeep Singh 
40536220514SGagandeep Singh 	for (i = 0; i < nb_pkts;) {
40636220514SGagandeep Singh 		do {
40736220514SGagandeep Singh 			desc = queue->base + queue->read_idx;
40836220514SGagandeep Singh 			if ((desc->ctrl & CL_DESC_OWN)) {
40936220514SGagandeep Singh 				stats->ipackets += i;
41036220514SGagandeep Singh 				return i;
41136220514SGagandeep Singh 			}
41236220514SGagandeep Singh 
41336220514SGagandeep Singh 			mb_priv = rte_mempool_get_priv(pool);
41436220514SGagandeep Singh 
41536220514SGagandeep Singh 			mbuf = desc->data + PFE_PKT_HEADER_SZ
41636220514SGagandeep Singh 				- sizeof(struct rte_mbuf)
41736220514SGagandeep Singh 				- RTE_PKTMBUF_HEADROOM
41836220514SGagandeep Singh 				- mb_priv->mbuf_priv_size;
41936220514SGagandeep Singh 			mbuf->next = NULL;
42036220514SGagandeep Singh 			if (desc->ctrl & CL_DESC_FIRST) {
42136220514SGagandeep Singh 				/* TODO size of priv data if present in
42236220514SGagandeep Singh 				 * descriptor
42336220514SGagandeep Singh 				 */
42436220514SGagandeep Singh 				u16 size = 0;
42536220514SGagandeep Singh 				mbuf->pkt_len = CL_DESC_BUF_LEN(desc->ctrl)
42636220514SGagandeep Singh 						- PFE_PKT_HEADER_SZ - size;
42736220514SGagandeep Singh 				mbuf->data_len = mbuf->pkt_len;
42836220514SGagandeep Singh 				mbuf->port = queue->port_id;
42936220514SGagandeep Singh #ifdef RTE_LIBRTE_PFE_SW_PARSE
43036220514SGagandeep Singh 				pfe_sw_parse_pkt(mbuf);
43136220514SGagandeep Singh #else
43236220514SGagandeep Singh 				parse_res = (struct pfe_parse *)(desc->data +
43336220514SGagandeep Singh 					    PFE_HIF_SIZE);
43436220514SGagandeep Singh 				mbuf->packet_type = parse_res->packet_type;
43536220514SGagandeep Singh #endif
43636220514SGagandeep Singh 				mbuf->nb_segs = 1;
43736220514SGagandeep Singh 				first_mbuf = mbuf;
43836220514SGagandeep Singh 				rx_pkts[i++] = first_mbuf;
43936220514SGagandeep Singh 			} else {
44036220514SGagandeep Singh 				mbuf->data_len = CL_DESC_BUF_LEN(desc->ctrl);
44136220514SGagandeep Singh 				mbuf->data_off = mbuf->data_off -
44236220514SGagandeep Singh 						 PFE_PKT_HEADER_SZ;
44336220514SGagandeep Singh 				first_mbuf->pkt_len += mbuf->data_len;
44436220514SGagandeep Singh 				first_mbuf->nb_segs++;
44536220514SGagandeep Singh 				p_mbuf->next = mbuf;
44636220514SGagandeep Singh 			}
44736220514SGagandeep Singh 			stats->ibytes += mbuf->data_len;
44836220514SGagandeep Singh 			p_mbuf = mbuf;
44936220514SGagandeep Singh 
45036220514SGagandeep Singh 			if (desc->ctrl & CL_DESC_LAST)
45136220514SGagandeep Singh 				wait_for_last = 0;
45236220514SGagandeep Singh 			else
45336220514SGagandeep Singh 				wait_for_last = 1;
45436220514SGagandeep Singh 			/*
45536220514SGagandeep Singh 			 * Needed so we don't free a buffer/page
45636220514SGagandeep Singh 			 * twice on module_exit
45736220514SGagandeep Singh 			 */
45836220514SGagandeep Singh 			desc->data = NULL;
45936220514SGagandeep Singh 
46036220514SGagandeep Singh 			/*
46136220514SGagandeep Singh 			 * Ensure everything else is written to DDR before
46236220514SGagandeep Singh 			 * writing bd->ctrl
46336220514SGagandeep Singh 			 */
46436220514SGagandeep Singh 			rte_wmb();
46536220514SGagandeep Singh 
46636220514SGagandeep Singh 			desc->ctrl = CL_DESC_OWN;
46736220514SGagandeep Singh 			queue->read_idx = (queue->read_idx + 1) &
46836220514SGagandeep Singh 					  (queue->size - 1);
46936220514SGagandeep Singh 		} while (wait_for_last);
47036220514SGagandeep Singh 	}
47136220514SGagandeep Singh 	stats->ipackets += i;
47236220514SGagandeep Singh 	return i;
47336220514SGagandeep Singh }
47436220514SGagandeep Singh 
47536220514SGagandeep Singh static inline void
47636220514SGagandeep Singh hif_hdr_write(struct hif_hdr *pkt_hdr, unsigned int
47736220514SGagandeep Singh 	      client_id, unsigned int qno,
47836220514SGagandeep Singh 	      u32 client_ctrl)
47936220514SGagandeep Singh {
4807be78d02SJosh Soref 	/* Optimize the write since the destination may be non-cacheable */
48136220514SGagandeep Singh 	if (!((unsigned long)pkt_hdr & 0x3)) {
48236220514SGagandeep Singh 		((u32 *)pkt_hdr)[0] = (client_ctrl << 16) | (qno << 8) |
48336220514SGagandeep Singh 					client_id;
48436220514SGagandeep Singh 	} else {
48536220514SGagandeep Singh 		((u16 *)pkt_hdr)[0] = (qno << 8) | (client_id & 0xFF);
48636220514SGagandeep Singh 		((u16 *)pkt_hdr)[1] = (client_ctrl & 0xFFFF);
48736220514SGagandeep Singh 	}
48836220514SGagandeep Singh }
48936220514SGagandeep Singh 
49036220514SGagandeep Singh /*This function puts the given packet in the specific client queue */
49136220514SGagandeep Singh void
49236220514SGagandeep Singh hif_lib_xmit_pkt(struct hif_client_s *client, unsigned int qno,
49336220514SGagandeep Singh 		 void *data, void *data1, unsigned int len,
49436220514SGagandeep Singh 		 u32 client_ctrl, unsigned int flags, void *client_data)
49536220514SGagandeep Singh {
49636220514SGagandeep Singh 	struct hif_client_tx_queue *queue = &client->tx_q[qno];
49736220514SGagandeep Singh 	struct tx_queue_desc *desc = queue->base + queue->write_idx;
49836220514SGagandeep Singh 
49936220514SGagandeep Singh 	/* First buffer */
50036220514SGagandeep Singh 	if (flags & HIF_FIRST_BUFFER) {
50136220514SGagandeep Singh 		data1 -= PFE_HIF_SIZE;
50236220514SGagandeep Singh 		data -= PFE_HIF_SIZE;
50336220514SGagandeep Singh 		len += PFE_HIF_SIZE;
50436220514SGagandeep Singh 
50536220514SGagandeep Singh 		hif_hdr_write(data1, client->id, qno, client_ctrl);
50636220514SGagandeep Singh 	}
50736220514SGagandeep Singh 
50836220514SGagandeep Singh 	desc->data = client_data;
50936220514SGagandeep Singh 	desc->ctrl = CL_DESC_OWN | CL_DESC_FLAGS(flags);
51036220514SGagandeep Singh 
51136220514SGagandeep Singh 	hif_xmit_pkt(&client->pfe->hif, client->id, qno, data, len, flags);
51236220514SGagandeep Singh 
51336220514SGagandeep Singh 	queue->write_idx = (queue->write_idx + 1) & (queue->size - 1);
51436220514SGagandeep Singh 
51536220514SGagandeep Singh 	queue->tx_pending++;
51636220514SGagandeep Singh }
51736220514SGagandeep Singh 
518fe38ad9bSGagandeep Singh void *
519fe38ad9bSGagandeep Singh hif_lib_tx_get_next_complete(struct hif_client_s *client, int qno,
520fe38ad9bSGagandeep Singh 				   unsigned int *flags, __rte_unused  int count)
521fe38ad9bSGagandeep Singh {
522fe38ad9bSGagandeep Singh 	struct hif_client_tx_queue *queue = &client->tx_q[qno];
523fe38ad9bSGagandeep Singh 	struct tx_queue_desc *desc = queue->base + queue->read_idx;
524fe38ad9bSGagandeep Singh 
525fe38ad9bSGagandeep Singh 	PFE_DP_LOG(DEBUG, "qno : %d rd_indx: %d pending:%d",
526fe38ad9bSGagandeep Singh 		   qno, queue->read_idx, queue->tx_pending);
527fe38ad9bSGagandeep Singh 
528fe38ad9bSGagandeep Singh 	if (!queue->tx_pending)
529fe38ad9bSGagandeep Singh 		return NULL;
530fe38ad9bSGagandeep Singh 
531fe38ad9bSGagandeep Singh 	if (queue->nocpy_flag && !queue->done_tmu_tx_pkts) {
532fe38ad9bSGagandeep Singh 		u32 tmu_tx_pkts = 0;
533fe38ad9bSGagandeep Singh 
534fe38ad9bSGagandeep Singh 		if (queue->prev_tmu_tx_pkts > tmu_tx_pkts)
535fe38ad9bSGagandeep Singh 			queue->done_tmu_tx_pkts = UINT_MAX -
536fe38ad9bSGagandeep Singh 				queue->prev_tmu_tx_pkts + tmu_tx_pkts;
537fe38ad9bSGagandeep Singh 		else
538fe38ad9bSGagandeep Singh 			queue->done_tmu_tx_pkts = tmu_tx_pkts -
539fe38ad9bSGagandeep Singh 						queue->prev_tmu_tx_pkts;
540fe38ad9bSGagandeep Singh 
541fe38ad9bSGagandeep Singh 		queue->prev_tmu_tx_pkts  = tmu_tx_pkts;
542fe38ad9bSGagandeep Singh 
543fe38ad9bSGagandeep Singh 		if (!queue->done_tmu_tx_pkts)
544fe38ad9bSGagandeep Singh 			return NULL;
545fe38ad9bSGagandeep Singh 	}
546fe38ad9bSGagandeep Singh 
547fe38ad9bSGagandeep Singh 	if (desc->ctrl & CL_DESC_OWN)
548fe38ad9bSGagandeep Singh 		return NULL;
549fe38ad9bSGagandeep Singh 
550fe38ad9bSGagandeep Singh 	queue->read_idx = (queue->read_idx + 1) & (queue->size - 1);
551fe38ad9bSGagandeep Singh 	queue->tx_pending--;
552fe38ad9bSGagandeep Singh 
553fe38ad9bSGagandeep Singh 	*flags = CL_DESC_GET_FLAGS(desc->ctrl);
554fe38ad9bSGagandeep Singh 
555fe38ad9bSGagandeep Singh 	if (queue->done_tmu_tx_pkts && (*flags & HIF_LAST_BUFFER))
556fe38ad9bSGagandeep Singh 		queue->done_tmu_tx_pkts--;
557fe38ad9bSGagandeep Singh 
558fe38ad9bSGagandeep Singh 	return desc->data;
559fe38ad9bSGagandeep Singh }
560fe38ad9bSGagandeep Singh 
561fe38ad9bSGagandeep Singh int
562fe38ad9bSGagandeep Singh pfe_hif_lib_init(struct pfe *pfe)
5635253fe37SGagandeep Singh {
5645253fe37SGagandeep Singh 	PMD_INIT_FUNC_TRACE();
5655253fe37SGagandeep Singh 
566fe38ad9bSGagandeep Singh 	emac_txq_cnt = EMAC_TXQ_CNT;
567fe38ad9bSGagandeep Singh 	pfe->hif.shm = &ghif_shm;
568fe38ad9bSGagandeep Singh 
5695253fe37SGagandeep Singh 	return 0;
5705253fe37SGagandeep Singh }
5715253fe37SGagandeep Singh 
5725253fe37SGagandeep Singh void
5735253fe37SGagandeep Singh pfe_hif_lib_exit(__rte_unused struct pfe *pfe)
5745253fe37SGagandeep Singh {
5755253fe37SGagandeep Singh 	PMD_INIT_FUNC_TRACE();
5765253fe37SGagandeep Singh }
577