1 // SPDX-License-Identifier:    GPL-2.0
2 /*
3  * Copyright (C) 2018 Marvell International Ltd.
4  */
5 
6 #include <cpu_func.h>
7 #include <dm/device.h>
8 #include <malloc.h>
9 #include <net.h>
10 #include <phy.h>
11 #include <linux/delay.h>
12 
13 #include "nic_reg.h"
14 #include "nic.h"
15 #include "q_struct.h"
16 #include "nicvf_queues.h"
17 
nicvf_poll_reg(struct nicvf * nic,int qidx,u64 reg,int bit_pos,int bits,int val)18 static int nicvf_poll_reg(struct nicvf *nic, int qidx,
19 			  u64 reg, int bit_pos, int bits, int val)
20 {
21 	u64 bit_mask;
22 	u64 reg_val;
23 	int timeout = 10;
24 
25 	bit_mask = (1ULL << bits) - 1;
26 	bit_mask = (bit_mask << bit_pos);
27 
28 	while (timeout) {
29 		reg_val = nicvf_queue_reg_read(nic, reg, qidx);
30 		if (((reg_val & bit_mask) >> bit_pos) == val)
31 			return 0;
32 		udelay(2000);
33 		timeout--;
34 	}
35 	printf("Poll on reg 0x%llx failed\n", reg);
36 	return 1;
37 }
38 
nicvf_alloc_q_desc_mem(struct nicvf * nic,struct q_desc_mem * dmem,int q_len,int desc_size,int align_bytes)39 static int nicvf_alloc_q_desc_mem(struct nicvf *nic, struct q_desc_mem *dmem,
40 				  int q_len, int desc_size, int align_bytes)
41 {
42 	dmem->q_len = q_len;
43 	dmem->size = (desc_size * q_len) + align_bytes;
44 	/* Save address, need it while freeing */
45 	dmem->unalign_base = calloc(1, dmem->size);
46 	dmem->dma = (uintptr_t)dmem->unalign_base;
47 
48 	if (!dmem->unalign_base)
49 		return -1;
50 
51 	/* Align memory address for 'align_bytes' */
52 	dmem->phys_base = NICVF_ALIGNED_ADDR((u64)dmem->dma, align_bytes);
53 	dmem->base = dmem->unalign_base + (dmem->phys_base - dmem->dma);
54 
55 	return 0;
56 }
57 
nicvf_free_q_desc_mem(struct nicvf * nic,struct q_desc_mem * dmem)58 static void nicvf_free_q_desc_mem(struct nicvf *nic, struct q_desc_mem *dmem)
59 {
60 	if (!dmem)
61 		return;
62 
63 	free(dmem->unalign_base);
64 
65 	dmem->unalign_base = NULL;
66 	dmem->base = NULL;
67 }
68 
nicvf_rb_ptr_to_pkt(struct nicvf * nic,uintptr_t rb_ptr)69 static void *nicvf_rb_ptr_to_pkt(struct nicvf *nic, uintptr_t rb_ptr)
70 {
71 	return (void *)rb_ptr;
72 }
73 
nicvf_init_rbdr(struct nicvf * nic,struct rbdr * rbdr,int ring_len,int buf_size)74 static int nicvf_init_rbdr(struct nicvf *nic, struct rbdr *rbdr,
75 			   int ring_len, int buf_size)
76 {
77 	int idx;
78 	uintptr_t rbuf;
79 	struct rbdr_entry_t *desc;
80 
81 	if (nicvf_alloc_q_desc_mem(nic, &rbdr->dmem, ring_len,
82 				   sizeof(struct rbdr_entry_t),
83 				   NICVF_RCV_BUF_ALIGN_BYTES)) {
84 		printf("Unable to allocate memory for rcv buffer ring\n");
85 		return -1;
86 	}
87 
88 	rbdr->desc = rbdr->dmem.base;
89 	/* Buffer size has to be in multiples of 128 bytes */
90 	rbdr->dma_size = buf_size;
91 	rbdr->enable = true;
92 	rbdr->thresh = RBDR_THRESH;
93 
94 	debug("%s: %d: allocating %lld bytes for rcv buffers\n",
95 	      __func__, __LINE__,
96 	      ring_len * buf_size + NICVF_RCV_BUF_ALIGN_BYTES);
97 	rbdr->buf_mem = (uintptr_t)calloc(1, ring_len * buf_size
98 						+ NICVF_RCV_BUF_ALIGN_BYTES);
99 
100 	if (!rbdr->buf_mem) {
101 		printf("Unable to allocate memory for rcv buffers\n");
102 		return -1;
103 	}
104 
105 	rbdr->buffers = NICVF_ALIGNED_ADDR(rbdr->buf_mem,
106 					   NICVF_RCV_BUF_ALIGN_BYTES);
107 
108 	debug("%s: %d: rbdr->buf_mem: %lx, rbdr->buffers: %lx\n",
109 	      __func__, __LINE__, rbdr->buf_mem, rbdr->buffers);
110 
111 	for (idx = 0; idx < ring_len; idx++) {
112 		rbuf = rbdr->buffers + DMA_BUFFER_LEN * idx;
113 		desc = GET_RBDR_DESC(rbdr, idx);
114 		desc->buf_addr = rbuf >> NICVF_RCV_BUF_ALIGN;
115 		flush_dcache_range((uintptr_t)desc,
116 				   (uintptr_t)desc + sizeof(desc));
117 	}
118 	return 0;
119 }
120 
nicvf_free_rbdr(struct nicvf * nic,struct rbdr * rbdr)121 static void nicvf_free_rbdr(struct nicvf *nic, struct rbdr *rbdr)
122 {
123 	if (!rbdr)
124 		return;
125 
126 	rbdr->enable = false;
127 	if (!rbdr->dmem.base)
128 		return;
129 
130 	debug("%s: %d: rbdr->buf_mem: %p\n", __func__,
131 	      __LINE__, (void *)rbdr->buf_mem);
132 	free((void *)rbdr->buf_mem);
133 
134 	/* Free RBDR ring */
135 	nicvf_free_q_desc_mem(nic, &rbdr->dmem);
136 }
137 
138 /* Refill receive buffer descriptors with new buffers.
139  * This runs in softirq context .
140  */
nicvf_refill_rbdr(struct nicvf * nic)141 void nicvf_refill_rbdr(struct nicvf *nic)
142 {
143 	struct queue_set *qs = nic->qs;
144 	int rbdr_idx = qs->rbdr_cnt;
145 	unsigned long qcount, head, tail, rb_cnt;
146 	struct rbdr *rbdr;
147 
148 	if (!rbdr_idx)
149 		return;
150 	rbdr_idx--;
151 	rbdr = &qs->rbdr[rbdr_idx];
152 	/* Check if it's enabled */
153 	if (!rbdr->enable) {
154 		printf("Receive queue %d is disabled\n", rbdr_idx);
155 		return;
156 	}
157 
158 	/* check if valid descs reached or crossed threshold level */
159 	qcount = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_STATUS0, rbdr_idx);
160 	head = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_HEAD, rbdr_idx);
161 	tail = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_TAIL, rbdr_idx);
162 
163 	qcount &= 0x7FFFF;
164 
165 	rb_cnt = qs->rbdr_len - qcount - 1;
166 
167 	debug("%s: %d: qcount: %lu, head: %lx, tail: %lx, rb_cnt: %lu\n",
168 	      __func__, __LINE__, qcount, head, tail, rb_cnt);
169 
170 	/* Notify HW */
171 	nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_DOOR, rbdr_idx, rb_cnt);
172 
173 	asm volatile ("dsb sy");
174 }
175 
176 /* TBD: how to handle full packets received in CQ
177  * i.e conversion of buffers into SKBs
178  */
nicvf_init_cmp_queue(struct nicvf * nic,struct cmp_queue * cq,int q_len)179 static int nicvf_init_cmp_queue(struct nicvf *nic,
180 				struct cmp_queue *cq, int q_len)
181 {
182 	if (nicvf_alloc_q_desc_mem(nic, &cq->dmem, q_len,
183 				   CMP_QUEUE_DESC_SIZE,
184 				   NICVF_CQ_BASE_ALIGN_BYTES)) {
185 		printf("Unable to allocate memory for completion queue\n");
186 		return -1;
187 	}
188 	cq->desc = cq->dmem.base;
189 	if (!pass1_silicon(nic->rev_id, nic->nicpf->hw->model_id))
190 		cq->thresh = CMP_QUEUE_CQE_THRESH;
191 	else
192 		cq->thresh = 0;
193 	cq->intr_timer_thresh = CMP_QUEUE_TIMER_THRESH;
194 
195 	return 0;
196 }
197 
nicvf_free_cmp_queue(struct nicvf * nic,struct cmp_queue * cq)198 static void nicvf_free_cmp_queue(struct nicvf *nic, struct cmp_queue *cq)
199 {
200 	if (!cq)
201 		return;
202 	if (!cq->dmem.base)
203 		return;
204 
205 	nicvf_free_q_desc_mem(nic, &cq->dmem);
206 }
207 
nicvf_init_snd_queue(struct nicvf * nic,struct snd_queue * sq,int q_len)208 static int nicvf_init_snd_queue(struct nicvf *nic,
209 				struct snd_queue *sq, int q_len)
210 {
211 	if (nicvf_alloc_q_desc_mem(nic, &sq->dmem, q_len,
212 				   SND_QUEUE_DESC_SIZE,
213 				   NICVF_SQ_BASE_ALIGN_BYTES)) {
214 		printf("Unable to allocate memory for send queue\n");
215 		return -1;
216 	}
217 
218 	sq->desc = sq->dmem.base;
219 	sq->skbuff = calloc(q_len, sizeof(u64));
220 	sq->head = 0;
221 	sq->tail = 0;
222 	sq->free_cnt = q_len - 1;
223 	sq->thresh = SND_QUEUE_THRESH;
224 
225 	return 0;
226 }
227 
nicvf_free_snd_queue(struct nicvf * nic,struct snd_queue * sq)228 static void nicvf_free_snd_queue(struct nicvf *nic, struct snd_queue *sq)
229 {
230 	if (!sq)
231 		return;
232 	if (!sq->dmem.base)
233 		return;
234 
235 	debug("%s: %d\n", __func__, __LINE__);
236 	free(sq->skbuff);
237 
238 	nicvf_free_q_desc_mem(nic, &sq->dmem);
239 }
240 
nicvf_reclaim_snd_queue(struct nicvf * nic,struct queue_set * qs,int qidx)241 static void nicvf_reclaim_snd_queue(struct nicvf *nic,
242 				    struct queue_set *qs, int qidx)
243 {
244 	/* Disable send queue */
245 	nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_CFG, qidx, 0);
246 	/* Check if SQ is stopped */
247 	if (nicvf_poll_reg(nic, qidx, NIC_QSET_SQ_0_7_STATUS, 21, 1, 0x01))
248 		return;
249 	/* Reset send queue */
250 	nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_CFG, qidx, NICVF_SQ_RESET);
251 }
252 
nicvf_reclaim_rcv_queue(struct nicvf * nic,struct queue_set * qs,int qidx)253 static void nicvf_reclaim_rcv_queue(struct nicvf *nic,
254 				    struct queue_set *qs, int qidx)
255 {
256 	union nic_mbx mbx = {};
257 
258 	/* Make sure all packets in the pipeline are written back into mem */
259 	mbx.msg.msg = NIC_MBOX_MSG_RQ_SW_SYNC;
260 	nicvf_send_msg_to_pf(nic, &mbx);
261 }
262 
nicvf_reclaim_cmp_queue(struct nicvf * nic,struct queue_set * qs,int qidx)263 static void nicvf_reclaim_cmp_queue(struct nicvf *nic,
264 				    struct queue_set *qs, int qidx)
265 {
266 	/* Disable timer threshold (doesn't get reset upon CQ reset */
267 	nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG2, qidx, 0);
268 	/* Disable completion queue */
269 	nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG, qidx, 0);
270 	/* Reset completion queue */
271 	nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG, qidx, NICVF_CQ_RESET);
272 }
273 
nicvf_reclaim_rbdr(struct nicvf * nic,struct rbdr * rbdr,int qidx)274 static void nicvf_reclaim_rbdr(struct nicvf *nic,
275 			       struct rbdr *rbdr, int qidx)
276 {
277 	u64 tmp, fifo_state;
278 	int timeout = 10;
279 
280 	/* Save head and tail pointers for feeing up buffers */
281 	rbdr->head = nicvf_queue_reg_read(nic,
282 					  NIC_QSET_RBDR_0_1_HEAD,
283 					  qidx) >> 3;
284 	rbdr->tail = nicvf_queue_reg_read(nic,
285 					  NIC_QSET_RBDR_0_1_TAIL,
286 					  qidx) >> 3;
287 
288 	/* If RBDR FIFO is in 'FAIL' state then do a reset first
289 	 * before relaiming.
290 	 */
291 	fifo_state = nicvf_queue_reg_read(nic, NIC_QSET_RBDR_0_1_STATUS0, qidx);
292 	if (((fifo_state >> 62) & 0x03) == 0x3)
293 		nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_CFG,
294 				      qidx, NICVF_RBDR_RESET);
295 
296 	/* Disable RBDR */
297 	nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_CFG, qidx, 0);
298 	if (nicvf_poll_reg(nic, qidx, NIC_QSET_RBDR_0_1_STATUS0, 62, 2, 0x00))
299 		return;
300 	while (1) {
301 		tmp = nicvf_queue_reg_read(nic,
302 					   NIC_QSET_RBDR_0_1_PREFETCH_STATUS,
303 					   qidx);
304 		if ((tmp & 0xFFFFFFFF) == ((tmp >> 32) & 0xFFFFFFFF))
305 			break;
306 		mdelay(2000);
307 		timeout--;
308 		if (!timeout) {
309 			printf("Failed polling on prefetch status\n");
310 			return;
311 		}
312 	}
313 	nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_CFG,
314 			      qidx, NICVF_RBDR_RESET);
315 
316 	if (nicvf_poll_reg(nic, qidx, NIC_QSET_RBDR_0_1_STATUS0, 62, 2, 0x02))
317 		return;
318 	nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_CFG, qidx, 0x00);
319 	if (nicvf_poll_reg(nic, qidx, NIC_QSET_RBDR_0_1_STATUS0, 62, 2, 0x00))
320 		return;
321 }
322 
323 /* Configures receive queue */
nicvf_rcv_queue_config(struct nicvf * nic,struct queue_set * qs,int qidx,bool enable)324 static void nicvf_rcv_queue_config(struct nicvf *nic, struct queue_set *qs,
325 				   int qidx, bool enable)
326 {
327 	union nic_mbx mbx = {};
328 	struct rcv_queue *rq;
329 	union {
330 		struct rq_cfg s;
331 		u64    u;
332 	} rq_cfg;
333 
334 	rq = &qs->rq[qidx];
335 	rq->enable = enable;
336 
337 	/* Disable receive queue */
338 	nicvf_queue_reg_write(nic, NIC_QSET_RQ_0_7_CFG, qidx, 0);
339 
340 	if (!rq->enable) {
341 		nicvf_reclaim_rcv_queue(nic, qs, qidx);
342 		return;
343 	}
344 
345 	rq->cq_qs = qs->vnic_id;
346 	rq->cq_idx = qidx;
347 	rq->start_rbdr_qs = qs->vnic_id;
348 	rq->start_qs_rbdr_idx = qs->rbdr_cnt - 1;
349 	rq->cont_rbdr_qs = qs->vnic_id;
350 	rq->cont_qs_rbdr_idx = qs->rbdr_cnt - 1;
351 	/* all writes of RBDR data to be loaded into L2 Cache as well*/
352 	rq->caching = 1;
353 
354 	/* Send a mailbox msg to PF to config RQ */
355 	mbx.rq.msg = NIC_MBOX_MSG_RQ_CFG;
356 	mbx.rq.qs_num = qs->vnic_id;
357 	mbx.rq.rq_num = qidx;
358 	mbx.rq.cfg = (rq->caching << 26) | (rq->cq_qs << 19) |
359 			  (rq->cq_idx << 16) | (rq->cont_rbdr_qs << 9) |
360 			  (rq->cont_qs_rbdr_idx << 8) |
361 			  (rq->start_rbdr_qs << 1) | (rq->start_qs_rbdr_idx);
362 	nicvf_send_msg_to_pf(nic, &mbx);
363 
364 	mbx.rq.msg = NIC_MBOX_MSG_RQ_BP_CFG;
365 	mbx.rq.cfg = (1ULL << 63) | (1ULL << 62) | (qs->vnic_id << 0);
366 	nicvf_send_msg_to_pf(nic, &mbx);
367 
368 	/* RQ drop config
369 	 * Enable CQ drop to reserve sufficient CQEs for all tx packets
370 	 */
371 	mbx.rq.msg = NIC_MBOX_MSG_RQ_DROP_CFG;
372 	mbx.rq.cfg = (1ULL << 62) | (RQ_CQ_DROP << 8);
373 	nicvf_send_msg_to_pf(nic, &mbx);
374 	nicvf_queue_reg_write(nic, NIC_QSET_RQ_GEN_CFG, 0, 0x00);
375 
376 	/* Enable Receive queue */
377 	rq_cfg.s.ena = 1;
378 	rq_cfg.s.tcp_ena = 0;
379 	nicvf_queue_reg_write(nic, NIC_QSET_RQ_0_7_CFG, qidx, rq_cfg.u);
380 }
381 
nicvf_cmp_queue_config(struct nicvf * nic,struct queue_set * qs,int qidx,bool enable)382 void nicvf_cmp_queue_config(struct nicvf *nic, struct queue_set *qs,
383 			    int qidx, bool enable)
384 {
385 	struct cmp_queue *cq;
386 	union {
387 		u64 u;
388 		struct cq_cfg s;
389 	} cq_cfg;
390 
391 	cq = &qs->cq[qidx];
392 	cq->enable = enable;
393 
394 	if (!cq->enable) {
395 		nicvf_reclaim_cmp_queue(nic, qs, qidx);
396 		return;
397 	}
398 
399 	/* Reset completion queue */
400 	nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG, qidx, NICVF_CQ_RESET);
401 
402 	if (!cq->enable)
403 		return;
404 
405 	/* Set completion queue base address */
406 	nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_BASE,
407 			      qidx, (u64)(cq->dmem.phys_base));
408 
409 	/* Enable Completion queue */
410 	cq_cfg.s.ena = 1;
411 	cq_cfg.s.reset = 0;
412 	cq_cfg.s.caching = 0;
413 	cq_cfg.s.qsize = CMP_QSIZE;
414 	cq_cfg.s.avg_con = 0;
415 	nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG, qidx, cq_cfg.u);
416 
417 	/* Set threshold value for interrupt generation */
418 	nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_THRESH, qidx, cq->thresh);
419 	nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_CFG2, qidx,
420 			      cq->intr_timer_thresh);
421 }
422 
423 /* Configures transmit queue */
nicvf_snd_queue_config(struct nicvf * nic,struct queue_set * qs,int qidx,bool enable)424 static void nicvf_snd_queue_config(struct nicvf *nic, struct queue_set *qs,
425 				   int qidx, bool enable)
426 {
427 	union nic_mbx mbx = {};
428 	struct snd_queue *sq;
429 
430 	union {
431 		struct sq_cfg s;
432 		u64 u;
433 	} sq_cfg;
434 
435 	sq = &qs->sq[qidx];
436 	sq->enable = enable;
437 
438 	if (!sq->enable) {
439 		nicvf_reclaim_snd_queue(nic, qs, qidx);
440 		return;
441 	}
442 
443 	/* Reset send queue */
444 	nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_CFG, qidx, NICVF_SQ_RESET);
445 
446 	sq->cq_qs = qs->vnic_id;
447 	sq->cq_idx = qidx;
448 
449 	/* Send a mailbox msg to PF to config SQ */
450 	mbx.sq.msg = NIC_MBOX_MSG_SQ_CFG;
451 	mbx.sq.qs_num = qs->vnic_id;
452 	mbx.sq.sq_num = qidx;
453 	mbx.sq.sqs_mode = nic->sqs_mode;
454 	mbx.sq.cfg = (sq->cq_qs << 3) | sq->cq_idx;
455 	nicvf_send_msg_to_pf(nic, &mbx);
456 
457 	/* Set queue base address */
458 	nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_BASE,
459 			      qidx, (u64)(sq->dmem.phys_base));
460 
461 	/* Enable send queue  & set queue size */
462 	sq_cfg.s.ena = 1;
463 	sq_cfg.s.reset = 0;
464 	sq_cfg.s.ldwb = 0;
465 	sq_cfg.s.qsize = SND_QSIZE;
466 	sq_cfg.s.tstmp_bgx_intf = 0;
467 	nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_CFG, qidx, sq_cfg.u);
468 
469 	/* Set threshold value for interrupt generation */
470 	nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_THRESH, qidx, sq->thresh);
471 }
472 
473 /* Configures receive buffer descriptor ring */
nicvf_rbdr_config(struct nicvf * nic,struct queue_set * qs,int qidx,bool enable)474 static void nicvf_rbdr_config(struct nicvf *nic, struct queue_set *qs,
475 			      int qidx, bool enable)
476 {
477 	struct rbdr *rbdr;
478 	union {
479 		struct rbdr_cfg s;
480 		u64 u;
481 	} rbdr_cfg;
482 
483 	rbdr = &qs->rbdr[qidx];
484 	nicvf_reclaim_rbdr(nic, rbdr, qidx);
485 	if (!enable)
486 		return;
487 
488 	/* Set descriptor base address */
489 	nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_BASE,
490 			      qidx, (u64)(rbdr->dmem.phys_base));
491 
492 	/* Enable RBDR  & set queue size */
493 	/* Buffer size should be in multiples of 128 bytes */
494 	rbdr_cfg.s.ena = 1;
495 	rbdr_cfg.s.reset = 0;
496 	rbdr_cfg.s.ldwb = 0;
497 	rbdr_cfg.s.qsize = RBDR_SIZE;
498 	rbdr_cfg.s.avg_con = 0;
499 	rbdr_cfg.s.lines = rbdr->dma_size / 128;
500 	nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_CFG,
501 			      qidx, rbdr_cfg.u);
502 
503 	/* Notify HW */
504 	nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_DOOR,
505 			      qidx, qs->rbdr_len - 1);
506 
507 	/* Set threshold value for interrupt generation */
508 	nicvf_queue_reg_write(nic, NIC_QSET_RBDR_0_1_THRESH,
509 			      qidx, rbdr->thresh - 1);
510 }
511 
512 /* Requests PF to assign and enable Qset */
nicvf_qset_config(struct nicvf * nic,bool enable)513 void nicvf_qset_config(struct nicvf *nic, bool enable)
514 {
515 	union nic_mbx mbx = {};
516 	struct queue_set *qs = nic->qs;
517 	struct qs_cfg *qs_cfg;
518 
519 	if (!qs) {
520 		printf("Qset is still not allocated, don't init queues\n");
521 		return;
522 	}
523 
524 	qs->enable = enable;
525 	qs->vnic_id = nic->vf_id;
526 
527 	/* Send a mailbox msg to PF to config Qset */
528 	mbx.qs.msg = NIC_MBOX_MSG_QS_CFG;
529 	mbx.qs.num = qs->vnic_id;
530 #ifdef VNIC_MULTI_QSET_SUPPORT
531 	mbx.qs.sqs_count = nic->sqs_count;
532 #endif
533 
534 	mbx.qs.cfg = 0;
535 	qs_cfg = (struct qs_cfg *)&mbx.qs.cfg;
536 	if (qs->enable) {
537 		qs_cfg->ena = 1;
538 #ifdef __BIG_ENDIAN
539 		qs_cfg->be = 1;
540 #endif
541 		qs_cfg->vnic = qs->vnic_id;
542 	}
543 	nicvf_send_msg_to_pf(nic, &mbx);
544 }
545 
nicvf_free_resources(struct nicvf * nic)546 static void nicvf_free_resources(struct nicvf *nic)
547 {
548 	int qidx;
549 	struct queue_set *qs = nic->qs;
550 
551 	/* Free receive buffer descriptor ring */
552 	for (qidx = 0; qidx < qs->rbdr_cnt; qidx++)
553 		nicvf_free_rbdr(nic, &qs->rbdr[qidx]);
554 
555 	/* Free completion queue */
556 	for (qidx = 0; qidx < qs->cq_cnt; qidx++)
557 		nicvf_free_cmp_queue(nic, &qs->cq[qidx]);
558 
559 	/* Free send queue */
560 	for (qidx = 0; qidx < qs->sq_cnt; qidx++)
561 		nicvf_free_snd_queue(nic, &qs->sq[qidx]);
562 }
563 
nicvf_alloc_resources(struct nicvf * nic)564 static int nicvf_alloc_resources(struct nicvf *nic)
565 {
566 	int qidx;
567 	struct queue_set *qs = nic->qs;
568 
569 	/* Alloc receive buffer descriptor ring */
570 	for (qidx = 0; qidx < qs->rbdr_cnt; qidx++) {
571 		if (nicvf_init_rbdr(nic, &qs->rbdr[qidx], qs->rbdr_len,
572 				    DMA_BUFFER_LEN))
573 			goto alloc_fail;
574 	}
575 
576 	/* Alloc send queue */
577 	for (qidx = 0; qidx < qs->sq_cnt; qidx++) {
578 		if (nicvf_init_snd_queue(nic, &qs->sq[qidx], qs->sq_len))
579 			goto alloc_fail;
580 	}
581 
582 	/* Alloc completion queue */
583 	for (qidx = 0; qidx < qs->cq_cnt; qidx++) {
584 		if (nicvf_init_cmp_queue(nic, &qs->cq[qidx], qs->cq_len))
585 			goto alloc_fail;
586 	}
587 
588 	return 0;
589 alloc_fail:
590 	nicvf_free_resources(nic);
591 	return -1;
592 }
593 
nicvf_set_qset_resources(struct nicvf * nic)594 int nicvf_set_qset_resources(struct nicvf *nic)
595 {
596 	struct queue_set *qs;
597 
598 	qs = calloc(1, sizeof(struct queue_set));
599 	if (!qs)
600 		return -1;
601 	nic->qs = qs;
602 
603 	/* Set count of each queue */
604 	qs->rbdr_cnt = RBDR_CNT;
605 	qs->rq_cnt = 1;
606 	qs->sq_cnt = SND_QUEUE_CNT;
607 	qs->cq_cnt = CMP_QUEUE_CNT;
608 
609 	/* Set queue lengths */
610 	qs->rbdr_len = RCV_BUF_COUNT;
611 	qs->sq_len = SND_QUEUE_LEN;
612 	qs->cq_len = CMP_QUEUE_LEN;
613 
614 	nic->rx_queues = qs->rq_cnt;
615 	nic->tx_queues = qs->sq_cnt;
616 
617 	return 0;
618 }
619 
nicvf_config_data_transfer(struct nicvf * nic,bool enable)620 int nicvf_config_data_transfer(struct nicvf *nic, bool enable)
621 {
622 	bool disable = false;
623 	struct queue_set *qs = nic->qs;
624 	int qidx;
625 
626 	if (!qs)
627 		return 0;
628 
629 	if (enable) {
630 		if (nicvf_alloc_resources(nic))
631 			return -1;
632 
633 		for (qidx = 0; qidx < qs->sq_cnt; qidx++)
634 			nicvf_snd_queue_config(nic, qs, qidx, enable);
635 		for (qidx = 0; qidx < qs->cq_cnt; qidx++)
636 			nicvf_cmp_queue_config(nic, qs, qidx, enable);
637 		for (qidx = 0; qidx < qs->rbdr_cnt; qidx++)
638 			nicvf_rbdr_config(nic, qs, qidx, enable);
639 		for (qidx = 0; qidx < qs->rq_cnt; qidx++)
640 			nicvf_rcv_queue_config(nic, qs, qidx, enable);
641 	} else {
642 		for (qidx = 0; qidx < qs->rq_cnt; qidx++)
643 			nicvf_rcv_queue_config(nic, qs, qidx, disable);
644 		for (qidx = 0; qidx < qs->rbdr_cnt; qidx++)
645 			nicvf_rbdr_config(nic, qs, qidx, disable);
646 		for (qidx = 0; qidx < qs->sq_cnt; qidx++)
647 			nicvf_snd_queue_config(nic, qs, qidx, disable);
648 		for (qidx = 0; qidx < qs->cq_cnt; qidx++)
649 			nicvf_cmp_queue_config(nic, qs, qidx, disable);
650 
651 		nicvf_free_resources(nic);
652 	}
653 
654 	return 0;
655 }
656 
657 /* Get a free desc from SQ
658  * returns descriptor ponter & descriptor number
659  */
nicvf_get_sq_desc(struct snd_queue * sq,int desc_cnt)660 static int nicvf_get_sq_desc(struct snd_queue *sq, int desc_cnt)
661 {
662 	int qentry;
663 
664 	qentry = sq->tail;
665 	sq->free_cnt -= desc_cnt;
666 	sq->tail += desc_cnt;
667 	sq->tail &= (sq->dmem.q_len - 1);
668 
669 	return qentry;
670 }
671 
672 /* Free descriptor back to SQ for future use */
nicvf_put_sq_desc(struct snd_queue * sq,int desc_cnt)673 void nicvf_put_sq_desc(struct snd_queue *sq, int desc_cnt)
674 {
675 	sq->free_cnt += desc_cnt;
676 	sq->head += desc_cnt;
677 	sq->head &= (sq->dmem.q_len - 1);
678 }
679 
nicvf_get_nxt_sqentry(struct snd_queue * sq,int qentry)680 static int nicvf_get_nxt_sqentry(struct snd_queue *sq, int qentry)
681 {
682 	qentry++;
683 	qentry &= (sq->dmem.q_len - 1);
684 	return qentry;
685 }
686 
nicvf_sq_enable(struct nicvf * nic,struct snd_queue * sq,int qidx)687 void nicvf_sq_enable(struct nicvf *nic, struct snd_queue *sq, int qidx)
688 {
689 	u64 sq_cfg;
690 
691 	sq_cfg = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_CFG, qidx);
692 	sq_cfg |= NICVF_SQ_EN;
693 	nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_CFG, qidx, sq_cfg);
694 	/* Ring doorbell so that H/W restarts processing SQEs */
695 	nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_DOOR, qidx, 0);
696 }
697 
nicvf_sq_disable(struct nicvf * nic,int qidx)698 void nicvf_sq_disable(struct nicvf *nic, int qidx)
699 {
700 	u64 sq_cfg;
701 
702 	sq_cfg = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_CFG, qidx);
703 	sq_cfg &= ~NICVF_SQ_EN;
704 	nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_CFG, qidx, sq_cfg);
705 }
706 
nicvf_sq_free_used_descs(struct udevice * dev,struct snd_queue * sq,int qidx)707 void nicvf_sq_free_used_descs(struct udevice *dev, struct snd_queue *sq,
708 			      int qidx)
709 {
710 	u64 head;
711 	struct nicvf *nic = dev_get_priv(dev);
712 	struct sq_hdr_subdesc *hdr;
713 
714 	head = nicvf_queue_reg_read(nic, NIC_QSET_SQ_0_7_HEAD, qidx) >> 4;
715 
716 	while (sq->head != head) {
717 		hdr = (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, sq->head);
718 		if (hdr->subdesc_type != SQ_DESC_TYPE_HEADER) {
719 			nicvf_put_sq_desc(sq, 1);
720 			continue;
721 		}
722 		nicvf_put_sq_desc(sq, hdr->subdesc_cnt + 1);
723 	}
724 }
725 
726 /* Get the number of SQ descriptors needed to xmit this skb */
nicvf_sq_subdesc_required(struct nicvf * nic)727 static int nicvf_sq_subdesc_required(struct nicvf *nic)
728 {
729 	int subdesc_cnt = MIN_SQ_DESC_PER_PKT_XMIT;
730 
731 	return subdesc_cnt;
732 }
733 
734 /* Add SQ HEADER subdescriptor.
735  * First subdescriptor for every send descriptor.
736  */
737 static inline void
nicvf_sq_add_hdr_subdesc(struct nicvf * nic,struct snd_queue * sq,int qentry,int subdesc_cnt,void * pkt,size_t pkt_len)738 nicvf_sq_add_hdr_subdesc(struct nicvf *nic, struct snd_queue *sq, int qentry,
739 			 int subdesc_cnt, void *pkt, size_t pkt_len)
740 {
741 	struct sq_hdr_subdesc *hdr;
742 
743 	hdr = (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, qentry);
744 	sq->skbuff[qentry] = (uintptr_t)pkt;
745 
746 	memset(hdr, 0, SND_QUEUE_DESC_SIZE);
747 	hdr->subdesc_type = SQ_DESC_TYPE_HEADER;
748 	/* Enable notification via CQE after processing SQE */
749 	hdr->post_cqe = 1;
750 	/* No of subdescriptors following this */
751 	hdr->subdesc_cnt = subdesc_cnt;
752 	hdr->tot_len = pkt_len;
753 
754 	flush_dcache_range((uintptr_t)hdr,
755 			   (uintptr_t)hdr + sizeof(struct sq_hdr_subdesc));
756 }
757 
758 /* SQ GATHER subdescriptor
759  * Must follow HDR descriptor
760  */
nicvf_sq_add_gather_subdesc(struct snd_queue * sq,int qentry,size_t size,uintptr_t data)761 static inline void nicvf_sq_add_gather_subdesc(struct snd_queue *sq, int qentry,
762 					       size_t size, uintptr_t data)
763 {
764 	struct sq_gather_subdesc *gather;
765 
766 	qentry &= (sq->dmem.q_len - 1);
767 	gather = (struct sq_gather_subdesc *)GET_SQ_DESC(sq, qentry);
768 
769 	memset(gather, 0, SND_QUEUE_DESC_SIZE);
770 	gather->subdesc_type = SQ_DESC_TYPE_GATHER;
771 	gather->ld_type = NIC_SEND_LD_TYPE_E_LDD;
772 	gather->size = size;
773 	gather->addr = data;
774 
775 	flush_dcache_range((uintptr_t)gather,
776 			   (uintptr_t)gather + sizeof(struct sq_hdr_subdesc));
777 }
778 
779 /* Append an skb to a SQ for packet transfer. */
nicvf_sq_append_pkt(struct nicvf * nic,void * pkt,size_t pkt_size)780 int nicvf_sq_append_pkt(struct nicvf *nic, void *pkt, size_t pkt_size)
781 {
782 	int subdesc_cnt;
783 	int sq_num = 0, qentry;
784 	struct queue_set *qs;
785 	struct snd_queue *sq;
786 
787 	qs = nic->qs;
788 	sq = &qs->sq[sq_num];
789 
790 	subdesc_cnt = nicvf_sq_subdesc_required(nic);
791 	if (subdesc_cnt > sq->free_cnt)
792 		goto append_fail;
793 
794 	qentry = nicvf_get_sq_desc(sq, subdesc_cnt);
795 
796 	/* Add SQ header subdesc */
797 	nicvf_sq_add_hdr_subdesc(nic, sq, qentry, subdesc_cnt - 1,
798 				 pkt, pkt_size);
799 
800 	/* Add SQ gather subdescs */
801 	qentry = nicvf_get_nxt_sqentry(sq, qentry);
802 	nicvf_sq_add_gather_subdesc(sq, qentry, pkt_size, (uintptr_t)(pkt));
803 
804 	flush_dcache_range((uintptr_t)pkt,
805 			   (uintptr_t)pkt + pkt_size);
806 
807 	/* make sure all memory stores are done before ringing doorbell */
808 	asm volatile ("dsb sy");
809 
810 	/* Inform HW to xmit new packet */
811 	nicvf_queue_reg_write(nic, NIC_QSET_SQ_0_7_DOOR,
812 			      sq_num, subdesc_cnt);
813 	return 1;
814 
815 append_fail:
816 	printf("Not enough SQ descriptors to xmit pkt\n");
817 	return 0;
818 }
819 
frag_num(unsigned int i)820 static unsigned int frag_num(unsigned int i)
821 {
822 #ifdef __BIG_ENDIAN
823 	return (i & ~3) + 3 - (i & 3);
824 #else
825 	return i;
826 #endif
827 }
828 
nicvf_get_rcv_pkt(struct nicvf * nic,void * cq_desc,size_t * pkt_len)829 void *nicvf_get_rcv_pkt(struct nicvf *nic, void *cq_desc, size_t *pkt_len)
830 {
831 	int frag;
832 	int payload_len = 0, tot_len;
833 	void *pkt = NULL, *pkt_buf = NULL, *buffer;
834 	struct cqe_rx_t *cqe_rx;
835 	struct rbdr *rbdr;
836 	struct rcv_queue *rq;
837 	struct queue_set *qs = nic->qs;
838 	u16 *rb_lens = NULL;
839 	u64 *rb_ptrs = NULL;
840 
841 	cqe_rx = (struct cqe_rx_t *)cq_desc;
842 
843 	rq = &qs->rq[cqe_rx->rq_idx];
844 	rbdr = &qs->rbdr[rq->start_qs_rbdr_idx];
845 	rb_lens = cq_desc + (3 * sizeof(u64)); /* Use offsetof */
846 	/* Except 88xx pass1 on all other chips CQE_RX2_S is added to
847 	 * CQE_RX at word6, hence buffer pointers move by word
848 	 *
849 	 * Use existing 'hw_tso' flag which will be set for all chips
850 	 * except 88xx pass1 instead of a additional cache line
851 	 * access (or miss) by using pci dev's revision.
852 	 */
853 	if (!nic->hw_tso)
854 		rb_ptrs = (void *)cqe_rx + (6 * sizeof(u64));
855 	else
856 		rb_ptrs = (void *)cqe_rx + (7 * sizeof(u64));
857 
858 	/*
859 	 * Figure out packet length to create packet buffer
860 	 */
861 	for (frag = 0; frag < cqe_rx->rb_cnt; frag++)
862 		payload_len += rb_lens[frag_num(frag)];
863 	*pkt_len = payload_len;
864 	/* round up size to 8 byte multiple */
865 	tot_len = (payload_len & (~0x7)) + 8;
866 	buffer = calloc(1, tot_len);
867 	if (!buffer) {
868 		printf("%s - Failed to allocate packet buffer\n", __func__);
869 		return NULL;
870 	}
871 	pkt_buf = buffer;
872 	debug("total pkt buf %p len %ld tot_len %d\n", pkt_buf, *pkt_len,
873 	      tot_len);
874 	for (frag = 0; frag < cqe_rx->rb_cnt; frag++) {
875 		payload_len = rb_lens[frag_num(frag)];
876 
877 		invalidate_dcache_range((uintptr_t)(*rb_ptrs),
878 					(uintptr_t)(*rb_ptrs) + rbdr->dma_size);
879 
880 		/* First fragment */
881 		*rb_ptrs = *rb_ptrs - cqe_rx->align_pad;
882 
883 		pkt = nicvf_rb_ptr_to_pkt(nic, *rb_ptrs);
884 
885 		invalidate_dcache_range((uintptr_t)pkt,
886 					(uintptr_t)pkt + payload_len);
887 
888 		if (cqe_rx->align_pad)
889 			pkt += cqe_rx->align_pad;
890 		debug("pkt_buf %p, pkt %p payload_len %d\n", pkt_buf, pkt,
891 		      payload_len);
892 		memcpy(buffer, pkt, payload_len);
893 		buffer += payload_len;
894 		/* Next buffer pointer */
895 		rb_ptrs++;
896 	}
897 	return pkt_buf;
898 }
899 
900 /* Clear interrupt */
nicvf_clear_intr(struct nicvf * nic,int int_type,int q_idx)901 void nicvf_clear_intr(struct nicvf *nic, int int_type, int q_idx)
902 {
903 	u64 reg_val = 0;
904 
905 	switch (int_type) {
906 	case NICVF_INTR_CQ:
907 		reg_val = ((1ULL << q_idx) << NICVF_INTR_CQ_SHIFT);
908 	break;
909 	case NICVF_INTR_SQ:
910 		reg_val = ((1ULL << q_idx) << NICVF_INTR_SQ_SHIFT);
911 	break;
912 	case NICVF_INTR_RBDR:
913 		reg_val = ((1ULL << q_idx) << NICVF_INTR_RBDR_SHIFT);
914 	break;
915 	case NICVF_INTR_PKT_DROP:
916 		reg_val = (1ULL << NICVF_INTR_PKT_DROP_SHIFT);
917 	break;
918 	case NICVF_INTR_TCP_TIMER:
919 		reg_val = (1ULL << NICVF_INTR_TCP_TIMER_SHIFT);
920 	break;
921 	case NICVF_INTR_MBOX:
922 		reg_val = (1ULL << NICVF_INTR_MBOX_SHIFT);
923 	break;
924 	case NICVF_INTR_QS_ERR:
925 		reg_val |= (1ULL << NICVF_INTR_QS_ERR_SHIFT);
926 	break;
927 	default:
928 		printf("Failed to clear interrupt: unknown type\n");
929 	break;
930 	}
931 
932 	nicvf_reg_write(nic, NIC_VF_INT, reg_val);
933 }
934 
nicvf_update_rq_stats(struct nicvf * nic,int rq_idx)935 void nicvf_update_rq_stats(struct nicvf *nic, int rq_idx)
936 {
937 	struct rcv_queue *rq;
938 
939 #define GET_RQ_STATS(reg) \
940 	nicvf_reg_read(nic, NIC_QSET_RQ_0_7_STAT_0_1 |\
941 			    (rq_idx << NIC_Q_NUM_SHIFT) | ((reg) << 3))
942 
943 	rq = &nic->qs->rq[rq_idx];
944 	rq->stats.bytes = GET_RQ_STATS(RQ_SQ_STATS_OCTS);
945 	rq->stats.pkts = GET_RQ_STATS(RQ_SQ_STATS_PKTS);
946 }
947 
nicvf_update_sq_stats(struct nicvf * nic,int sq_idx)948 void nicvf_update_sq_stats(struct nicvf *nic, int sq_idx)
949 {
950 	struct snd_queue *sq;
951 
952 #define GET_SQ_STATS(reg) \
953 	nicvf_reg_read(nic, NIC_QSET_SQ_0_7_STAT_0_1 |\
954 			    (sq_idx << NIC_Q_NUM_SHIFT) | ((reg) << 3))
955 
956 	sq = &nic->qs->sq[sq_idx];
957 	sq->stats.bytes = GET_SQ_STATS(RQ_SQ_STATS_OCTS);
958 	sq->stats.pkts = GET_SQ_STATS(RQ_SQ_STATS_PKTS);
959 }
960 
961 /* Check for errors in the receive cmp.queue entry */
nicvf_check_cqe_rx_errs(struct nicvf * nic,struct cmp_queue * cq,void * cq_desc)962 int nicvf_check_cqe_rx_errs(struct nicvf *nic,
963 			    struct cmp_queue *cq, void *cq_desc)
964 {
965 	struct cqe_rx_t *cqe_rx;
966 	struct cmp_queue_stats *stats = &cq->stats;
967 
968 	cqe_rx = (struct cqe_rx_t *)cq_desc;
969 	if (!cqe_rx->err_level && !cqe_rx->err_opcode) {
970 		stats->rx.errop.good++;
971 		return 0;
972 	}
973 
974 	switch (cqe_rx->err_level) {
975 	case CQ_ERRLVL_MAC:
976 		stats->rx.errlvl.mac_errs++;
977 	break;
978 	case CQ_ERRLVL_L2:
979 		stats->rx.errlvl.l2_errs++;
980 	break;
981 	case CQ_ERRLVL_L3:
982 		stats->rx.errlvl.l3_errs++;
983 	break;
984 	case CQ_ERRLVL_L4:
985 		stats->rx.errlvl.l4_errs++;
986 	break;
987 	}
988 
989 	switch (cqe_rx->err_opcode) {
990 	case CQ_RX_ERROP_RE_PARTIAL:
991 		stats->rx.errop.partial_pkts++;
992 	break;
993 	case CQ_RX_ERROP_RE_JABBER:
994 		stats->rx.errop.jabber_errs++;
995 	break;
996 	case CQ_RX_ERROP_RE_FCS:
997 		stats->rx.errop.fcs_errs++;
998 	break;
999 	case CQ_RX_ERROP_RE_TERMINATE:
1000 		stats->rx.errop.terminate_errs++;
1001 	break;
1002 	case CQ_RX_ERROP_RE_RX_CTL:
1003 		stats->rx.errop.bgx_rx_errs++;
1004 	break;
1005 	case CQ_RX_ERROP_PREL2_ERR:
1006 		stats->rx.errop.prel2_errs++;
1007 	break;
1008 	case CQ_RX_ERROP_L2_FRAGMENT:
1009 		stats->rx.errop.l2_frags++;
1010 	break;
1011 	case CQ_RX_ERROP_L2_OVERRUN:
1012 		stats->rx.errop.l2_overruns++;
1013 	break;
1014 	case CQ_RX_ERROP_L2_PFCS:
1015 		stats->rx.errop.l2_pfcs++;
1016 	break;
1017 	case CQ_RX_ERROP_L2_PUNY:
1018 		stats->rx.errop.l2_puny++;
1019 	break;
1020 	case CQ_RX_ERROP_L2_MAL:
1021 		stats->rx.errop.l2_hdr_malformed++;
1022 	break;
1023 	case CQ_RX_ERROP_L2_OVERSIZE:
1024 		stats->rx.errop.l2_oversize++;
1025 	break;
1026 	case CQ_RX_ERROP_L2_UNDERSIZE:
1027 		stats->rx.errop.l2_undersize++;
1028 	break;
1029 	case CQ_RX_ERROP_L2_LENMISM:
1030 		stats->rx.errop.l2_len_mismatch++;
1031 	break;
1032 	case CQ_RX_ERROP_L2_PCLP:
1033 		stats->rx.errop.l2_pclp++;
1034 	break;
1035 	case CQ_RX_ERROP_IP_NOT:
1036 		stats->rx.errop.non_ip++;
1037 	break;
1038 	case CQ_RX_ERROP_IP_CSUM_ERR:
1039 		stats->rx.errop.ip_csum_err++;
1040 	break;
1041 	case CQ_RX_ERROP_IP_MAL:
1042 		stats->rx.errop.ip_hdr_malformed++;
1043 	break;
1044 	case CQ_RX_ERROP_IP_MALD:
1045 		stats->rx.errop.ip_payload_malformed++;
1046 	break;
1047 	case CQ_RX_ERROP_IP_HOP:
1048 		stats->rx.errop.ip_hop_errs++;
1049 	break;
1050 	case CQ_RX_ERROP_L3_ICRC:
1051 		stats->rx.errop.l3_icrc_errs++;
1052 	break;
1053 	case CQ_RX_ERROP_L3_PCLP:
1054 		stats->rx.errop.l3_pclp++;
1055 	break;
1056 	case CQ_RX_ERROP_L4_MAL:
1057 		stats->rx.errop.l4_malformed++;
1058 	break;
1059 	case CQ_RX_ERROP_L4_CHK:
1060 		stats->rx.errop.l4_csum_errs++;
1061 	break;
1062 	case CQ_RX_ERROP_UDP_LEN:
1063 		stats->rx.errop.udp_len_err++;
1064 	break;
1065 	case CQ_RX_ERROP_L4_PORT:
1066 		stats->rx.errop.bad_l4_port++;
1067 	break;
1068 	case CQ_RX_ERROP_TCP_FLAG:
1069 		stats->rx.errop.bad_tcp_flag++;
1070 	break;
1071 	case CQ_RX_ERROP_TCP_OFFSET:
1072 		stats->rx.errop.tcp_offset_errs++;
1073 	break;
1074 	case CQ_RX_ERROP_L4_PCLP:
1075 		stats->rx.errop.l4_pclp++;
1076 	break;
1077 	case CQ_RX_ERROP_RBDR_TRUNC:
1078 		stats->rx.errop.pkt_truncated++;
1079 	break;
1080 	}
1081 
1082 	return 1;
1083 }
1084 
1085 /* Check for errors in the send cmp.queue entry */
nicvf_check_cqe_tx_errs(struct nicvf * nic,struct cmp_queue * cq,void * cq_desc)1086 int nicvf_check_cqe_tx_errs(struct nicvf *nic,
1087 			    struct cmp_queue *cq, void *cq_desc)
1088 {
1089 	struct cqe_send_t *cqe_tx;
1090 	struct cmp_queue_stats *stats = &cq->stats;
1091 
1092 	cqe_tx = (struct cqe_send_t *)cq_desc;
1093 	switch (cqe_tx->send_status) {
1094 	case CQ_TX_ERROP_GOOD:
1095 		stats->tx.good++;
1096 		return 0;
1097 	break;
1098 	case CQ_TX_ERROP_DESC_FAULT:
1099 		stats->tx.desc_fault++;
1100 	break;
1101 	case CQ_TX_ERROP_HDR_CONS_ERR:
1102 		stats->tx.hdr_cons_err++;
1103 	break;
1104 	case CQ_TX_ERROP_SUBDC_ERR:
1105 		stats->tx.subdesc_err++;
1106 	break;
1107 	case CQ_TX_ERROP_IMM_SIZE_OFLOW:
1108 		stats->tx.imm_size_oflow++;
1109 	break;
1110 	case CQ_TX_ERROP_DATA_SEQUENCE_ERR:
1111 		stats->tx.data_seq_err++;
1112 	break;
1113 	case CQ_TX_ERROP_MEM_SEQUENCE_ERR:
1114 		stats->tx.mem_seq_err++;
1115 	break;
1116 	case CQ_TX_ERROP_LOCK_VIOL:
1117 		stats->tx.lock_viol++;
1118 	break;
1119 	case CQ_TX_ERROP_DATA_FAULT:
1120 		stats->tx.data_fault++;
1121 	break;
1122 	case CQ_TX_ERROP_TSTMP_CONFLICT:
1123 		stats->tx.tstmp_conflict++;
1124 	break;
1125 	case CQ_TX_ERROP_TSTMP_TIMEOUT:
1126 		stats->tx.tstmp_timeout++;
1127 	break;
1128 	case CQ_TX_ERROP_MEM_FAULT:
1129 		stats->tx.mem_fault++;
1130 	break;
1131 	case CQ_TX_ERROP_CK_OVERLAP:
1132 		stats->tx.csum_overlap++;
1133 	break;
1134 	case CQ_TX_ERROP_CK_OFLOW:
1135 		stats->tx.csum_overflow++;
1136 	break;
1137 	}
1138 
1139 	return 1;
1140 }
1141