Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2014-2018 Chelsio Communications.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include <sys/queue.h>
7 : : #include <stdio.h>
8 : : #include <errno.h>
9 : : #include <stdint.h>
10 : : #include <string.h>
11 : : #include <unistd.h>
12 : : #include <stdarg.h>
13 : : #include <inttypes.h>
14 : : #include <netinet/in.h>
15 : :
16 : : #include <rte_byteorder.h>
17 : : #include <rte_common.h>
18 : : #include <rte_cycles.h>
19 : : #include <rte_interrupts.h>
20 : : #include <rte_log.h>
21 : : #include <rte_debug.h>
22 : : #include <rte_pci.h>
23 : : #include <rte_branch_prediction.h>
24 : : #include <rte_memory.h>
25 : : #include <rte_memzone.h>
26 : : #include <rte_tailq.h>
27 : : #include <rte_eal.h>
28 : : #include <rte_alarm.h>
29 : : #include <rte_ether.h>
30 : : #include <ethdev_driver.h>
31 : : #include <rte_malloc.h>
32 : : #include <rte_random.h>
33 : : #include <dev_driver.h>
34 : :
35 : : #include "base/common.h"
36 : : #include "base/t4_regs.h"
37 : : #include "base/t4_msg.h"
38 : : #include "cxgbe.h"
39 : :
40 : : static inline void ship_tx_pkt_coalesce_wr(struct adapter *adap,
41 : : struct sge_eth_txq *txq);
42 : :
43 : : /*
44 : : * Max number of Rx buffers we replenish at a time.
45 : : */
46 : : #define MAX_RX_REFILL 64U
47 : :
48 : : #define NOMEM_TMR_IDX (SGE_NTIMERS - 1)
49 : :
50 : : /*
51 : : * Max Tx descriptor space we allow for an Ethernet packet to be inlined
52 : : * into a WR.
53 : : */
54 : : #define MAX_IMM_TX_PKT_LEN 256
55 : :
56 : : /*
57 : : * Max size of a WR sent through a control Tx queue.
58 : : */
59 : : #define MAX_CTRL_WR_LEN SGE_MAX_WR_LEN
60 : :
61 : : /*
62 : : * Bits 0..3 of rx_sw_desc.dma_addr have special meaning. The hardware uses
63 : : * these to specify the buffer size as an index into the SGE Free List Buffer
64 : : * Size register array. We also use bit 4, when the buffer has been unmapped
65 : : * for DMA, but this is of course never sent to the hardware and is only used
66 : : * to prevent double unmappings. All of the above requires that the Free List
67 : : * Buffers which we allocate have the bottom 5 bits free (0) -- i.e. are
68 : : * 32-byte or a power of 2 greater in alignment. Since the SGE's minimal
69 : : * Free List Buffer alignment is 32 bytes, this works out for us ...
70 : : */
71 : : enum {
72 : : RX_BUF_FLAGS = 0x1f, /* bottom five bits are special */
73 : : RX_BUF_SIZE = 0x0f, /* bottom three bits are for buf sizes */
74 : : RX_UNMAPPED_BUF = 0x10, /* buffer is not mapped */
75 : : };
76 : :
77 : : /**
78 : : * txq_avail - return the number of available slots in a Tx queue
79 : : * @q: the Tx queue
80 : : *
81 : : * Returns the number of descriptors in a Tx queue available to write new
82 : : * packets.
83 : : */
84 : : static inline unsigned int txq_avail(const struct sge_txq *q)
85 : : {
86 : 0 : return q->size - 1 - q->in_use;
87 : : }
88 : :
89 : : static int map_mbuf(struct rte_mbuf *mbuf, dma_addr_t *addr)
90 : : {
91 : : struct rte_mbuf *m = mbuf;
92 : :
93 [ # # # # ]: 0 : for (; m; m = m->next, addr++) {
94 [ # # # # ]: 0 : *addr = m->buf_iova + rte_pktmbuf_headroom(m);
95 [ # # # # ]: 0 : if (*addr == 0)
96 : 0 : goto out_err;
97 : : }
98 : : return 0;
99 : :
100 : : out_err:
101 : 0 : return -ENOMEM;
102 : : }
103 : :
104 : : /**
105 : : * free_tx_desc - reclaims Tx descriptors and their buffers
106 : : * @q: the Tx queue to reclaim descriptors from
107 : : * @n: the number of descriptors to reclaim
108 : : *
109 : : * Reclaims Tx descriptors from an SGE Tx queue and frees the associated
110 : : * Tx buffers. Called with the Tx queue lock held.
111 : : */
112 : 0 : static void free_tx_desc(struct sge_txq *q, unsigned int n)
113 : : {
114 : : struct tx_sw_desc *d;
115 : : unsigned int cidx = 0;
116 : :
117 : 0 : d = &q->sdesc[cidx];
118 [ # # ]: 0 : while (n--) {
119 [ # # ]: 0 : if (d->mbuf) { /* an SGL is present */
120 : 0 : rte_pktmbuf_free(d->mbuf);
121 : 0 : d->mbuf = NULL;
122 : : }
123 [ # # ]: 0 : if (d->coalesce.idx) {
124 : : int i;
125 : :
126 [ # # ]: 0 : for (i = 0; i < d->coalesce.idx; i++) {
127 : 0 : rte_pktmbuf_free(d->coalesce.mbuf[i]);
128 : 0 : d->coalesce.mbuf[i] = NULL;
129 : : }
130 : 0 : d->coalesce.idx = 0;
131 : : }
132 : 0 : ++d;
133 [ # # ]: 0 : if (++cidx == q->size) {
134 : : cidx = 0;
135 : 0 : d = q->sdesc;
136 : : }
137 : 0 : RTE_MBUF_PREFETCH_TO_FREE(&q->sdesc->mbuf->pool);
138 : : }
139 : 0 : }
140 : :
141 : 0 : static void reclaim_tx_desc(struct sge_txq *q, unsigned int n)
142 : : {
143 : : struct tx_sw_desc *d;
144 : 0 : unsigned int cidx = q->cidx;
145 : :
146 : 0 : d = &q->sdesc[cidx];
147 [ # # ]: 0 : while (n--) {
148 [ # # ]: 0 : if (d->mbuf) { /* an SGL is present */
149 : 0 : rte_pktmbuf_free(d->mbuf);
150 : 0 : d->mbuf = NULL;
151 : : }
152 : 0 : ++d;
153 [ # # ]: 0 : if (++cidx == q->size) {
154 : : cidx = 0;
155 : 0 : d = q->sdesc;
156 : : }
157 : : }
158 : 0 : q->cidx = cidx;
159 : 0 : }
160 : :
161 : : /**
162 : : * fl_cap - return the capacity of a free-buffer list
163 : : * @fl: the FL
164 : : *
165 : : * Returns the capacity of a free-buffer list. The capacity is less than
166 : : * the size because one descriptor needs to be left unpopulated, otherwise
167 : : * HW will think the FL is empty.
168 : : */
169 : : static inline unsigned int fl_cap(const struct sge_fl *fl)
170 : : {
171 : 0 : return fl->size - 8; /* 1 descriptor = 8 buffers */
172 : : }
173 : :
174 : : /**
175 : : * fl_starving - return whether a Free List is starving.
176 : : * @adapter: pointer to the adapter
177 : : * @fl: the Free List
178 : : *
179 : : * Tests specified Free List to see whether the number of buffers
180 : : * available to the hardware has fallen below our "starvation"
181 : : * threshold.
182 : : */
183 : : static inline bool fl_starving(const struct adapter *adapter,
184 : : const struct sge_fl *fl)
185 : : {
186 : : const struct sge *s = &adapter->sge;
187 : :
188 : 0 : return fl->avail - fl->pend_cred <= s->fl_starve_thres;
189 : : }
190 : :
191 : : static inline unsigned int get_buf_size(struct adapter *adapter,
192 : : const struct rx_sw_desc *d)
193 : : {
194 : 0 : return adapter->sge.fl_buffer_size[d->dma_addr & RX_BUF_SIZE];
195 : : }
196 : :
197 : : /**
198 : : * free_rx_bufs - free the Rx buffers on an SGE free list
199 : : * @q: the SGE free list to free buffers from
200 : : * @n: how many buffers to free
201 : : *
202 : : * Release the next @n buffers on an SGE free-buffer Rx queue. The
203 : : * buffers must be made inaccessible to HW before calling this function.
204 : : */
205 : 0 : static void free_rx_bufs(struct sge_fl *q, int n)
206 : : {
207 : 0 : unsigned int cidx = q->cidx;
208 : : struct rx_sw_desc *d;
209 : :
210 : 0 : d = &q->sdesc[cidx];
211 [ # # ]: 0 : while (n--) {
212 [ # # ]: 0 : if (d->buf) {
213 : 0 : rte_pktmbuf_free(d->buf);
214 : 0 : d->buf = NULL;
215 : : }
216 : 0 : ++d;
217 [ # # ]: 0 : if (++cidx == q->size) {
218 : : cidx = 0;
219 : 0 : d = q->sdesc;
220 : : }
221 : 0 : q->avail--;
222 : : }
223 : 0 : q->cidx = cidx;
224 : 0 : }
225 : :
226 : : /**
227 : : * unmap_rx_buf - unmap the current Rx buffer on an SGE free list
228 : : * @q: the SGE free list
229 : : *
230 : : * Unmap the current buffer on an SGE free-buffer Rx queue. The
231 : : * buffer must be made inaccessible to HW before calling this function.
232 : : *
233 : : * This is similar to @free_rx_bufs above but does not free the buffer.
234 : : * Do note that the FL still loses any further access to the buffer.
235 : : */
236 : : static void unmap_rx_buf(struct sge_fl *q)
237 : : {
238 : 0 : if (++q->cidx == q->size)
239 : 0 : q->cidx = 0;
240 : 0 : q->avail--;
241 : : }
242 : :
243 : 0 : static inline void ring_fl_db(struct adapter *adap, struct sge_fl *q)
244 : : {
245 [ # # ]: 0 : if (q->pend_cred >= 64) {
246 : 0 : u32 val = adap->params.arch.sge_fl_db;
247 : :
248 [ # # ]: 0 : if (is_t4(adap->params.chip))
249 : 0 : val |= V_PIDX(q->pend_cred / 8);
250 : : else
251 : 0 : val |= V_PIDX_T5(q->pend_cred / 8);
252 : :
253 : : /*
254 : : * Make sure all memory writes to the Free List queue are
255 : : * committed before we tell the hardware about them.
256 : : */
257 : : wmb();
258 : :
259 : : /*
260 : : * If we don't have access to the new User Doorbell (T5+), use
261 : : * the old doorbell mechanism; otherwise use the new BAR2
262 : : * mechanism.
263 : : */
264 [ # # ]: 0 : if (unlikely(!q->bar2_addr)) {
265 [ # # ]: 0 : u32 reg = is_pf4(adap) ? MYPF_REG(A_SGE_PF_KDOORBELL) :
266 : : T4VF_SGE_BASE_ADDR +
267 : : A_SGE_VF_KDOORBELL;
268 : :
269 : 0 : t4_write_reg_relaxed(adap, reg,
270 : 0 : val | V_QID(q->cntxt_id));
271 : : } else {
272 : 0 : writel_relaxed(val | V_QID(q->bar2_qid),
273 : 0 : (void *)((uintptr_t)q->bar2_addr +
274 : : SGE_UDB_KDOORBELL));
275 : :
276 : : /*
277 : : * This Write memory Barrier will force the write to
278 : : * the User Doorbell area to be flushed.
279 : : */
280 : : wmb();
281 : : }
282 : 0 : q->pend_cred &= 7;
283 : : }
284 : 0 : }
285 : :
286 : : static inline void set_rx_sw_desc(struct rx_sw_desc *sd, void *buf,
287 : : dma_addr_t mapping)
288 : : {
289 : 0 : sd->buf = buf;
290 : 0 : sd->dma_addr = mapping; /* includes size low bits */
291 : : }
292 : :
293 : : /**
294 : : * refill_fl_usembufs - refill an SGE Rx buffer ring with mbufs
295 : : * @adap: the adapter
296 : : * @q: the ring to refill
297 : : * @n: the number of new buffers to allocate
298 : : *
299 : : * (Re)populate an SGE free-buffer queue with up to @n new packet buffers,
300 : : * allocated with the supplied gfp flags. The caller must assure that
301 : : * @n does not exceed the queue's capacity. If afterwards the queue is
302 : : * found critically low mark it as starving in the bitmap of starving FLs.
303 : : *
304 : : * Returns the number of buffers allocated.
305 : : */
306 : 0 : static unsigned int refill_fl_usembufs(struct adapter *adap, struct sge_fl *q,
307 : : int n)
308 : 0 : {
309 : 0 : struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, fl);
310 : 0 : struct rx_sw_desc *sd = &q->sdesc[q->pidx];
311 : 0 : __be64 *d = &q->desc[q->pidx];
312 : 0 : struct rte_mbuf *buf_bulk[n];
313 : 0 : unsigned int cred = q->avail;
314 : : int ret, i;
315 : :
316 [ # # ]: 0 : ret = rte_mempool_get_bulk(rxq->rspq.mb_pool, (void *)buf_bulk, n);
317 [ # # ]: 0 : if (unlikely(ret != 0)) {
318 : 0 : dev_debug(adap, "%s: failed to allocated fl entries in bulk ..\n",
319 : : __func__);
320 : 0 : q->alloc_failed++;
321 : 0 : rxq->rspq.eth_dev->data->rx_mbuf_alloc_failed++;
322 : 0 : goto out;
323 : : }
324 : :
325 [ # # ]: 0 : for (i = 0; i < n; i++) {
326 : 0 : struct rte_mbuf *mbuf = buf_bulk[i];
327 : : dma_addr_t mapping;
328 : :
329 [ # # ]: 0 : if (!mbuf) {
330 : 0 : dev_debug(adap, "%s: mbuf alloc failed\n", __func__);
331 : 0 : q->alloc_failed++;
332 : 0 : rxq->rspq.eth_dev->data->rx_mbuf_alloc_failed++;
333 : 0 : goto out;
334 : : }
335 : :
336 : : rte_mbuf_refcnt_set(mbuf, 1);
337 : 0 : mbuf->data_off = RTE_PKTMBUF_HEADROOM;
338 : 0 : mbuf->next = NULL;
339 : 0 : mbuf->nb_segs = 1;
340 : 0 : mbuf->port = rxq->rspq.port_id;
341 : :
342 : 0 : mapping = (dma_addr_t)(mbuf->buf_iova + mbuf->data_off);
343 : 0 : mapping |= q->fl_buf_size_idx;
344 [ # # ]: 0 : *d++ = cpu_to_be64(mapping);
345 : : set_rx_sw_desc(sd, mbuf, mapping);
346 : 0 : sd++;
347 : :
348 : 0 : q->avail++;
349 [ # # ]: 0 : if (++q->pidx == q->size) {
350 : 0 : q->pidx = 0;
351 : 0 : sd = q->sdesc;
352 : 0 : d = q->desc;
353 : : }
354 : : }
355 : :
356 : 0 : out: cred = q->avail - cred;
357 : 0 : q->pend_cred += cred;
358 : 0 : ring_fl_db(adap, q);
359 : :
360 [ # # ]: 0 : if (unlikely(fl_starving(adap, q))) {
361 : : /*
362 : : * Make sure data has been written to free list
363 : : */
364 : : wmb();
365 : 0 : q->low++;
366 : : }
367 : :
368 : 0 : return cred;
369 : : }
370 : :
371 : : /**
372 : : * refill_fl - refill an SGE Rx buffer ring with mbufs
373 : : * @adap: the adapter
374 : : * @q: the ring to refill
375 : : * @n: the number of new buffers to allocate
376 : : *
377 : : * (Re)populate an SGE free-buffer queue with up to @n new packet buffers,
378 : : * allocated with the supplied gfp flags. The caller must assure that
379 : : * @n does not exceed the queue's capacity. Returns the number of buffers
380 : : * allocated.
381 : : */
382 : : static unsigned int refill_fl(struct adapter *adap, struct sge_fl *q, int n)
383 : : {
384 : 0 : return refill_fl_usembufs(adap, q, n);
385 : : }
386 : :
387 : : static inline void __refill_fl(struct adapter *adap, struct sge_fl *fl)
388 : : {
389 : : refill_fl(adap, fl, min(MAX_RX_REFILL, fl_cap(fl) - fl->avail));
390 : 0 : }
391 : :
392 : : /*
393 : : * Return the number of reclaimable descriptors in a Tx queue.
394 : : */
395 : : static inline int reclaimable(const struct sge_txq *q)
396 : : {
397 : 0 : int hw_cidx = ntohs(q->stat->cidx);
398 : :
399 : 0 : hw_cidx -= q->cidx;
400 [ # # # # ]: 0 : if (hw_cidx < 0)
401 : 0 : return hw_cidx + q->size;
402 : : return hw_cidx;
403 : : }
404 : :
405 : : /**
406 : : * reclaim_completed_tx - reclaims completed Tx descriptors
407 : : * @q: the Tx queue to reclaim completed descriptors from
408 : : *
409 : : * Reclaims Tx descriptors that the SGE has indicated it has processed.
410 : : */
411 [ # # ]: 0 : void reclaim_completed_tx(struct sge_txq *q)
412 : : {
413 : 0 : unsigned int avail = reclaimable(q);
414 : :
415 : : do {
416 : : /* reclaim as much as possible */
417 : 0 : reclaim_tx_desc(q, avail);
418 [ # # ]: 0 : q->in_use -= avail;
419 : 0 : avail = reclaimable(q);
420 [ # # ]: 0 : } while (avail);
421 : 0 : }
422 : :
423 : : /**
424 : : * sgl_len - calculates the size of an SGL of the given capacity
425 : : * @n: the number of SGL entries
426 : : *
427 : : * Calculates the number of flits needed for a scatter/gather list that
428 : : * can hold the given number of entries.
429 : : */
430 : : static inline unsigned int sgl_len(unsigned int n)
431 : : {
432 : : /*
433 : : * A Direct Scatter Gather List uses 32-bit lengths and 64-bit PCI DMA
434 : : * addresses. The DSGL Work Request starts off with a 32-bit DSGL
435 : : * ULPTX header, then Length0, then Address0, then, for 1 <= i <= N,
436 : : * repeated sequences of { Length[i], Length[i+1], Address[i],
437 : : * Address[i+1] } (this ensures that all addresses are on 64-bit
438 : : * boundaries). If N is even, then Length[N+1] should be set to 0 and
439 : : * Address[N+1] is omitted.
440 : : *
441 : : * The following calculation incorporates all of the above. It's
442 : : * somewhat hard to follow but, briefly: the "+2" accounts for the
443 : : * first two flits which include the DSGL header, Length0 and
444 : : * Address0; the "(3*(n-1))/2" covers the main body of list entries (3
445 : : * flits for every pair of the remaining N) +1 if (n-1) is odd; and
446 : : * finally the "+((n-1)&1)" adds the one remaining flit needed if
447 : : * (n-1) is odd ...
448 : : */
449 : 0 : n--;
450 : 0 : return (3 * n) / 2 + (n & 1) + 2;
451 : : }
452 : :
453 : : /**
454 : : * flits_to_desc - returns the num of Tx descriptors for the given flits
455 : : * @n: the number of flits
456 : : *
457 : : * Returns the number of Tx descriptors needed for the supplied number
458 : : * of flits.
459 : : */
460 : : static inline unsigned int flits_to_desc(unsigned int n)
461 : : {
462 : 0 : return DIV_ROUND_UP(n, 8);
463 : : }
464 : :
465 : : /**
466 : : * is_eth_imm - can an Ethernet packet be sent as immediate data?
467 : : * @m: the packet
468 : : *
469 : : * Returns whether an Ethernet packet is small enough to fit as
470 : : * immediate data. Return value corresponds to the headroom required.
471 : : */
472 : : static inline int is_eth_imm(const struct rte_mbuf *m)
473 : : {
474 : 0 : unsigned int hdrlen = (m->ol_flags & RTE_MBUF_F_TX_TCP_SEG) ?
475 : 0 : sizeof(struct cpl_tx_pkt_lso_core) : 0;
476 : :
477 : 0 : hdrlen += sizeof(struct cpl_tx_pkt);
478 [ # # ]: 0 : if (m->pkt_len <= MAX_IMM_TX_PKT_LEN - hdrlen)
479 : : return hdrlen;
480 : :
481 : : return 0;
482 : : }
483 : :
484 : : /**
485 : : * calc_tx_flits - calculate the number of flits for a packet Tx WR
486 : : * @m: the packet
487 : : * @adap: adapter structure pointer
488 : : *
489 : : * Returns the number of flits needed for a Tx WR for the given Ethernet
490 : : * packet, including the needed WR and CPL headers.
491 : : */
492 [ # # ]: 0 : static inline unsigned int calc_tx_flits(const struct rte_mbuf *m,
493 : : struct adapter *adap)
494 : : {
495 [ # # ]: 0 : size_t wr_size = is_pf4(adap) ? sizeof(struct fw_eth_tx_pkt_wr) :
496 : : sizeof(struct fw_eth_tx_pkt_vm_wr);
497 : : unsigned int flits;
498 : : int hdrlen;
499 : :
500 : : /*
501 : : * If the mbuf is small enough, we can pump it out as a work request
502 : : * with only immediate data. In that case we just have to have the
503 : : * TX Packet header plus the mbuf data in the Work Request.
504 : : */
505 : :
506 : : hdrlen = is_eth_imm(m);
507 : : if (hdrlen)
508 : 0 : return DIV_ROUND_UP(m->pkt_len + hdrlen, sizeof(__be64));
509 : :
510 : : /*
511 : : * Otherwise, we're going to have to construct a Scatter gather list
512 : : * of the mbuf body and fragments. We also include the flits necessary
513 : : * for the TX Packet Work Request and CPL. We always have a firmware
514 : : * Write Header (incorporated as part of the cpl_tx_pkt_lso and
515 : : * cpl_tx_pkt structures), followed by either a TX Packet Write CPL
516 : : * message or, if we're doing a Large Send Offload, an LSO CPL message
517 : : * with an embedded TX Packet Write CPL message.
518 : : */
519 : 0 : flits = sgl_len(m->nb_segs);
520 [ # # ]: 0 : if (m->tso_segsz)
521 : 0 : flits += (wr_size + sizeof(struct cpl_tx_pkt_lso_core) +
522 : 0 : sizeof(struct cpl_tx_pkt_core)) / sizeof(__be64);
523 : : else
524 : 0 : flits += (wr_size +
525 : 0 : sizeof(struct cpl_tx_pkt_core)) / sizeof(__be64);
526 : : return flits;
527 : : }
528 : :
529 : : /**
530 : : * write_sgl - populate a scatter/gather list for a packet
531 : : * @mbuf: the packet
532 : : * @q: the Tx queue we are writing into
533 : : * @sgl: starting location for writing the SGL
534 : : * @end: points right after the end of the SGL
535 : : * @start: start offset into mbuf main-body data to include in the SGL
536 : : * @addr: address of mapped region
537 : : *
538 : : * Generates a scatter/gather list for the buffers that make up a packet.
539 : : * The caller must provide adequate space for the SGL that will be written.
540 : : * The SGL includes all of the packet's page fragments and the data in its
541 : : * main body except for the first @start bytes. @sgl must be 16-byte
542 : : * aligned and within a Tx descriptor with available space. @end points
543 : : * write after the end of the SGL but does not account for any potential
544 : : * wrap around, i.e., @end > @sgl.
545 : : */
546 : 0 : static void write_sgl(struct rte_mbuf *mbuf, struct sge_txq *q,
547 : : struct ulptx_sgl *sgl, u64 *end, unsigned int start,
548 : : const dma_addr_t *addr)
549 : 0 : {
550 : : unsigned int i, len;
551 : : struct ulptx_sge_pair *to;
552 : : struct rte_mbuf *m = mbuf;
553 : 0 : unsigned int nfrags = m->nb_segs;
554 : 0 : struct ulptx_sge_pair buf[nfrags / 2];
555 : :
556 [ # # ]: 0 : len = m->data_len - start;
557 : 0 : sgl->len0 = htonl(len);
558 [ # # ]: 0 : sgl->addr0 = rte_cpu_to_be_64(addr[0]);
559 : :
560 [ # # ]: 0 : sgl->cmd_nsge = htonl(V_ULPTX_CMD(ULP_TX_SC_DSGL) |
561 : : V_ULPTX_NSGE(nfrags));
562 [ # # ]: 0 : if (likely(--nfrags == 0))
563 : 0 : return;
564 : : /*
565 : : * Most of the complexity below deals with the possibility we hit the
566 : : * end of the queue in the middle of writing the SGL. For this case
567 : : * only we create the SGL in a temporary buffer and then copy it.
568 : : */
569 [ # # ]: 0 : to = (u8 *)end > (u8 *)q->stat ? buf : sgl->sge;
570 : :
571 [ # # ]: 0 : for (i = 0; nfrags >= 2; nfrags -= 2, to++) {
572 : 0 : m = m->next;
573 [ # # ]: 0 : to->len[0] = rte_cpu_to_be_32(m->data_len);
574 : 0 : to->addr[0] = rte_cpu_to_be_64(addr[++i]);
575 : 0 : m = m->next;
576 [ # # ]: 0 : to->len[1] = rte_cpu_to_be_32(m->data_len);
577 : 0 : to->addr[1] = rte_cpu_to_be_64(addr[++i]);
578 : : }
579 [ # # ]: 0 : if (nfrags) {
580 : 0 : m = m->next;
581 [ # # ]: 0 : to->len[0] = rte_cpu_to_be_32(m->data_len);
582 : 0 : to->len[1] = rte_cpu_to_be_32(0);
583 [ # # ]: 0 : to->addr[0] = rte_cpu_to_be_64(addr[i + 1]);
584 : : }
585 [ # # ]: 0 : if (unlikely((u8 *)end > (u8 *)q->stat)) {
586 : 0 : unsigned int part0 = RTE_PTR_DIFF((u8 *)q->stat,
587 : : (u8 *)sgl->sge);
588 : : unsigned int part1;
589 : :
590 [ # # ]: 0 : if (likely(part0))
591 : : memcpy(sgl->sge, buf, part0);
592 : 0 : part1 = RTE_PTR_DIFF((u8 *)end, (u8 *)q->stat);
593 [ # # ]: 0 : rte_memcpy(q->desc, RTE_PTR_ADD((u8 *)buf, part0), part1);
594 : 0 : end = RTE_PTR_ADD((void *)q->desc, part1);
595 : : }
596 [ # # ]: 0 : if ((uintptr_t)end & 8) /* 0-pad to multiple of 16 */
597 : 0 : *(u64 *)end = 0;
598 : : }
599 : :
600 : : #define IDXDIFF(head, tail, wrap) \
601 : : ((head) >= (tail) ? (head) - (tail) : (wrap) - (tail) + (head))
602 : :
603 : : #define Q_IDXDIFF(q, idx) IDXDIFF((q)->pidx, (q)->idx, (q)->size)
604 : : #define R_IDXDIFF(q, idx) IDXDIFF((q)->cidx, (q)->idx, (q)->size)
605 : :
606 : : #define PIDXDIFF(head, tail, wrap) \
607 : : ((tail) >= (head) ? (tail) - (head) : (wrap) - (head) + (tail))
608 : : #define P_IDXDIFF(q, idx) PIDXDIFF((q)->cidx, idx, (q)->size)
609 : :
610 : : /**
611 : : * ring_tx_db - ring a Tx queue's doorbell
612 : : * @adap: the adapter
613 : : * @q: the Tx queue
614 : : * @n: number of new descriptors to give to HW
615 : : *
616 : : * Ring the doorbell for a Tx queue.
617 : : */
618 : 0 : static inline void ring_tx_db(struct adapter *adap, struct sge_txq *q)
619 : : {
620 [ # # ]: 0 : int n = Q_IDXDIFF(q, dbidx);
621 : :
622 : : /*
623 : : * Make sure that all writes to the TX Descriptors are committed
624 : : * before we tell the hardware about them.
625 : : */
626 : : rte_wmb();
627 : :
628 : : /*
629 : : * If we don't have access to the new User Doorbell (T5+), use the old
630 : : * doorbell mechanism; otherwise use the new BAR2 mechanism.
631 : : */
632 [ # # ]: 0 : if (unlikely(!q->bar2_addr)) {
633 : 0 : u32 val = V_PIDX(n);
634 : :
635 : : /*
636 : : * For T4 we need to participate in the Doorbell Recovery
637 : : * mechanism.
638 : : */
639 [ # # ]: 0 : if (!q->db_disabled)
640 : 0 : t4_write_reg(adap, MYPF_REG(A_SGE_PF_KDOORBELL),
641 : 0 : V_QID(q->cntxt_id) | val);
642 : : else
643 : 0 : q->db_pidx_inc += n;
644 : 0 : q->db_pidx = q->pidx;
645 : : } else {
646 : 0 : u32 val = V_PIDX_T5(n);
647 : :
648 : : /*
649 : : * T4 and later chips share the same PIDX field offset within
650 : : * the doorbell, but T5 and later shrank the field in order to
651 : : * gain a bit for Doorbell Priority. The field was absurdly
652 : : * large in the first place (14 bits) so we just use the T5
653 : : * and later limits and warn if a Queue ID is too large.
654 : : */
655 [ # # ]: 0 : WARN_ON(val & F_DBPRIO);
656 : :
657 : 0 : writel(val | V_QID(q->bar2_qid),
658 : 0 : (void *)((uintptr_t)q->bar2_addr + SGE_UDB_KDOORBELL));
659 : :
660 : : /*
661 : : * This Write Memory Barrier will force the write to the User
662 : : * Doorbell area to be flushed. This is needed to prevent
663 : : * writes on different CPUs for the same queue from hitting
664 : : * the adapter out of order. This is required when some Work
665 : : * Requests take the Write Combine Gather Buffer path (user
666 : : * doorbell area offset [SGE_UDB_WCDOORBELL..+63]) and some
667 : : * take the traditional path where we simply increment the
668 : : * PIDX (User Doorbell area SGE_UDB_KDOORBELL) and have the
669 : : * hardware DMA read the actual Work Request.
670 : : */
671 : : rte_wmb();
672 : : }
673 : 0 : q->dbidx = q->pidx;
674 : 0 : }
675 : :
676 : : /*
677 : : * Figure out what HW csum a packet wants and return the appropriate control
678 : : * bits.
679 : : */
680 : 0 : static u64 hwcsum(enum chip_type chip, const struct rte_mbuf *m)
681 : : {
682 : : int csum_type;
683 : :
684 [ # # ]: 0 : if (m->ol_flags & RTE_MBUF_F_TX_IP_CKSUM) {
685 [ # # # ]: 0 : switch (m->ol_flags & RTE_MBUF_F_TX_L4_MASK) {
686 : : case RTE_MBUF_F_TX_TCP_CKSUM:
687 : : csum_type = TX_CSUM_TCPIP;
688 : : break;
689 : 0 : case RTE_MBUF_F_TX_UDP_CKSUM:
690 : : csum_type = TX_CSUM_UDPIP;
691 : 0 : break;
692 : 0 : default:
693 : 0 : goto nocsum;
694 : : }
695 : : } else {
696 : 0 : goto nocsum;
697 : : }
698 : :
699 : : if (likely(csum_type >= TX_CSUM_TCPIP)) {
700 : 0 : u64 hdr_len = V_TXPKT_IPHDR_LEN(m->l3_len);
701 : 0 : int eth_hdr_len = m->l2_len;
702 : :
703 [ # # ]: 0 : if (CHELSIO_CHIP_VERSION(chip) <= CHELSIO_T5)
704 : 0 : hdr_len |= V_TXPKT_ETHHDR_LEN(eth_hdr_len);
705 : : else
706 : 0 : hdr_len |= V_T6_TXPKT_ETHHDR_LEN(eth_hdr_len);
707 : 0 : return V_TXPKT_CSUM_TYPE(csum_type) | hdr_len;
708 : : }
709 : 0 : nocsum:
710 : : /*
711 : : * unknown protocol, disable HW csum
712 : : * and hope a bad packet is detected
713 : : */
714 : : return F_TXPKT_L4CSUM_DIS;
715 : : }
716 : :
717 : : static inline void txq_advance(struct sge_txq *q, unsigned int n)
718 : : {
719 : 0 : q->in_use += n;
720 : 0 : q->pidx += n;
721 [ # # # # ]: 0 : if (q->pidx >= q->size)
722 : 0 : q->pidx -= q->size;
723 : : }
724 : :
725 : : #define MAX_COALESCE_LEN 64000
726 : :
727 : : static inline bool wraps_around(struct sge_txq *q, int ndesc)
728 : : {
729 : 0 : return (q->pidx + ndesc) > q->size ? true : false;
730 : : }
731 : :
732 : 0 : static void tx_timer_cb(void *data)
733 : : {
734 : : struct adapter *adap = (struct adapter *)data;
735 : 0 : struct sge_eth_txq *txq = &adap->sge.ethtxq[0];
736 : : int i;
737 : : unsigned int coal_idx;
738 : :
739 : : /* monitor any pending tx */
740 [ # # ]: 0 : for (i = 0; i < adap->sge.max_ethqsets; i++, txq++) {
741 [ # # ]: 0 : if (t4_os_trylock(&txq->txq_lock)) {
742 : 0 : coal_idx = txq->q.coalesce.idx;
743 [ # # ]: 0 : if (coal_idx) {
744 [ # # ]: 0 : if (coal_idx == txq->q.last_coal_idx &&
745 [ # # ]: 0 : txq->q.pidx == txq->q.last_pidx) {
746 : 0 : ship_tx_pkt_coalesce_wr(adap, txq);
747 : : } else {
748 : 0 : txq->q.last_coal_idx = coal_idx;
749 : 0 : txq->q.last_pidx = txq->q.pidx;
750 : : }
751 : : }
752 : : t4_os_unlock(&txq->txq_lock);
753 : : }
754 : : }
755 : 0 : rte_eal_alarm_set(50, tx_timer_cb, (void *)adap);
756 : 0 : }
757 : :
758 : : /**
759 : : * ship_tx_pkt_coalesce_wr - finalizes and ships a coalesce WR
760 : : * @ adap: adapter structure
761 : : * @txq: tx queue
762 : : *
763 : : * writes the different fields of the pkts WR and sends it.
764 : : */
765 : 0 : static inline void ship_tx_pkt_coalesce_wr(struct adapter *adap,
766 : : struct sge_eth_txq *txq)
767 : : {
768 : : struct fw_eth_tx_pkts_vm_wr *vmwr;
769 : : const size_t fw_hdr_copy_len = (sizeof(vmwr->ethmacdst) +
770 : : sizeof(vmwr->ethmacsrc) +
771 : : sizeof(vmwr->ethtype) +
772 : : sizeof(vmwr->vlantci));
773 : : struct fw_eth_tx_pkts_wr *wr;
774 : 0 : struct sge_txq *q = &txq->q;
775 : : unsigned int ndesc;
776 : : u32 wr_mid;
777 : :
778 : : /* fill the pkts WR header */
779 : 0 : wr = (void *)&q->desc[q->pidx];
780 : : vmwr = (void *)&q->desc[q->pidx];
781 : :
782 [ # # ]: 0 : wr_mid = V_FW_WR_LEN16(DIV_ROUND_UP(q->coalesce.flits, 2));
783 : : ndesc = flits_to_desc(q->coalesce.flits);
784 : 0 : wr->equiq_to_len16 = htonl(wr_mid);
785 [ # # ]: 0 : wr->plen = cpu_to_be16(q->coalesce.len);
786 : 0 : wr->npkt = q->coalesce.idx;
787 [ # # ]: 0 : wr->r3 = 0;
788 [ # # ]: 0 : if (is_pf4(adap)) {
789 : 0 : wr->type = q->coalesce.type;
790 [ # # ]: 0 : if (likely(wr->type != 0))
791 : 0 : wr->op_pkd = htonl(V_FW_WR_OP(FW_ETH_TX_PKTS2_WR));
792 : : else
793 : 0 : wr->op_pkd = htonl(V_FW_WR_OP(FW_ETH_TX_PKTS_WR));
794 : : } else {
795 : 0 : wr->op_pkd = htonl(V_FW_WR_OP(FW_ETH_TX_PKTS_VM_WR));
796 : 0 : vmwr->r4 = 0;
797 : 0 : memcpy((void *)vmwr->ethmacdst, (void *)q->coalesce.ethmacdst,
798 : : fw_hdr_copy_len);
799 : : }
800 : :
801 : : /* zero out coalesce structure members */
802 [ # # ]: 0 : memset((void *)&q->coalesce, 0, sizeof(struct eth_coalesce));
803 : :
804 : : txq_advance(q, ndesc);
805 : 0 : txq->stats.coal_wr++;
806 : 0 : txq->stats.coal_pkts += wr->npkt;
807 : :
808 [ # # # # ]: 0 : if (Q_IDXDIFF(q, equeidx) >= q->size / 2) {
809 : 0 : q->equeidx = q->pidx;
810 : 0 : wr_mid |= F_FW_WR_EQUEQ;
811 : 0 : wr->equiq_to_len16 = htonl(wr_mid);
812 : : }
813 : 0 : ring_tx_db(adap, q);
814 : 0 : }
815 : :
816 : : /**
817 : : * should_tx_packet_coalesce - decides whether to coalesce an mbuf or not
818 : : * @txq: tx queue where the mbuf is sent
819 : : * @mbuf: mbuf to be sent
820 : : * @nflits: return value for number of flits needed
821 : : * @adap: adapter structure
822 : : *
823 : : * This function decides if a packet should be coalesced or not.
824 : : */
825 : 0 : static inline int should_tx_packet_coalesce(struct sge_eth_txq *txq,
826 : : struct rte_mbuf *mbuf,
827 : : unsigned int *nflits,
828 : : struct adapter *adap)
829 : : {
830 : : struct fw_eth_tx_pkts_vm_wr *wr;
831 : : const size_t fw_hdr_copy_len = (sizeof(wr->ethmacdst) +
832 : : sizeof(wr->ethmacsrc) +
833 : : sizeof(wr->ethtype) +
834 : : sizeof(wr->vlantci));
835 : : struct sge_txq *q = &txq->q;
836 : : unsigned int flits, ndesc;
837 : : unsigned char type = 0;
838 : : int credits, wr_size;
839 : :
840 : : /* use coal WR type 1 when no frags are present */
841 [ # # ]: 0 : type = (mbuf->nb_segs == 1) ? 1 : 0;
842 [ # # ]: 0 : if (!is_pf4(adap)) {
843 [ # # ]: 0 : if (!type)
844 : : return 0;
845 : :
846 [ # # ]: 0 : if (q->coalesce.idx && memcmp((void *)q->coalesce.ethmacdst,
847 [ # # ]: 0 : rte_pktmbuf_mtod(mbuf, void *),
848 : : fw_hdr_copy_len))
849 : 0 : ship_tx_pkt_coalesce_wr(adap, txq);
850 : : }
851 : :
852 [ # # # # ]: 0 : if (unlikely(type != q->coalesce.type && q->coalesce.idx))
853 : 0 : ship_tx_pkt_coalesce_wr(adap, txq);
854 : :
855 : : /* calculate the number of flits required for coalescing this packet
856 : : * without the 2 flits of the WR header. These are added further down
857 : : * if we are just starting in new PKTS WR. sgl_len doesn't account for
858 : : * the possible 16 bytes alignment ULP TX commands so we do it here.
859 : : */
860 : 0 : flits = (sgl_len(mbuf->nb_segs) + 1) & ~1U;
861 [ # # ]: 0 : if (type == 0)
862 : 0 : flits += (sizeof(struct ulp_txpkt) +
863 : : sizeof(struct ulptx_idata)) / sizeof(__be64);
864 : 0 : flits += sizeof(struct cpl_tx_pkt_core) / sizeof(__be64);
865 : 0 : *nflits = flits;
866 : :
867 : : /* If coalescing is on, the mbuf is added to a pkts WR */
868 [ # # ]: 0 : if (q->coalesce.idx) {
869 : 0 : ndesc = DIV_ROUND_UP(q->coalesce.flits + flits, 8);
870 : 0 : credits = txq_avail(q) - ndesc;
871 : :
872 [ # # ]: 0 : if (unlikely(wraps_around(q, ndesc)))
873 : : return 0;
874 : :
875 : : /* If we are wrapping or this is last mbuf then, send the
876 : : * already coalesced mbufs and let the non-coalesce pass
877 : : * handle the mbuf.
878 : : */
879 [ # # ]: 0 : if (unlikely(credits < 0)) {
880 : 0 : ship_tx_pkt_coalesce_wr(adap, txq);
881 : 0 : return -EBUSY;
882 : : }
883 : :
884 : : /* If the max coalesce len or the max WR len is reached
885 : : * ship the WR and keep coalescing on.
886 : : */
887 [ # # # # ]: 0 : if (unlikely((q->coalesce.len + mbuf->pkt_len >
888 : : MAX_COALESCE_LEN) ||
889 : : (q->coalesce.flits + flits >
890 : : q->coalesce.max))) {
891 : 0 : ship_tx_pkt_coalesce_wr(adap, txq);
892 : 0 : goto new;
893 : : }
894 : : return 1;
895 : : }
896 : :
897 [ # # ]: 0 : new:
898 : : /* start a new pkts WR, the WR header is not filled below */
899 [ # # ]: 0 : wr_size = is_pf4(adap) ? sizeof(struct fw_eth_tx_pkts_wr) :
900 : : sizeof(struct fw_eth_tx_pkts_vm_wr);
901 : 0 : flits += wr_size / sizeof(__be64);
902 : 0 : ndesc = flits_to_desc(q->coalesce.flits + flits);
903 : 0 : credits = txq_avail(q) - ndesc;
904 : :
905 [ # # ]: 0 : if (unlikely(wraps_around(q, ndesc)))
906 : : return 0;
907 : :
908 [ # # ]: 0 : if (unlikely(credits < 0))
909 : : return -EBUSY;
910 : :
911 : 0 : q->coalesce.flits += wr_size / sizeof(__be64);
912 : 0 : q->coalesce.type = type;
913 : 0 : q->coalesce.ptr = (unsigned char *)&q->desc[q->pidx] +
914 : : q->coalesce.flits * sizeof(__be64);
915 [ # # ]: 0 : if (!is_pf4(adap))
916 : 0 : memcpy((void *)q->coalesce.ethmacdst,
917 : 0 : rte_pktmbuf_mtod(mbuf, void *), fw_hdr_copy_len);
918 : : return 1;
919 : : }
920 : :
921 : : /**
922 : : * tx_do_packet_coalesce - add an mbuf to a coalesce WR
923 : : * @txq: sge_eth_txq used send the mbuf
924 : : * @mbuf: mbuf to be sent
925 : : * @flits: flits needed for this mbuf
926 : : * @adap: adapter structure
927 : : * @pi: port_info structure
928 : : * @addr: mapped address of the mbuf
929 : : *
930 : : * Adds an mbuf to be sent as part of a coalesce WR by filling a
931 : : * ulp_tx_pkt command, ulp_tx_sc_imm command, cpl message and
932 : : * ulp_tx_sc_dsgl command.
933 : : */
934 : 0 : static inline int tx_do_packet_coalesce(struct sge_eth_txq *txq,
935 : : struct rte_mbuf *mbuf,
936 : : int flits, struct adapter *adap,
937 : : const struct port_info *pi,
938 : : dma_addr_t *addr, uint16_t nb_pkts)
939 : : {
940 : : u64 cntrl, *end;
941 : 0 : struct sge_txq *q = &txq->q;
942 : : struct ulp_txpkt *mc;
943 : : struct ulptx_idata *sc_imm;
944 : : struct cpl_tx_pkt_core *cpl;
945 : : struct tx_sw_desc *sd;
946 : 0 : unsigned int idx = q->coalesce.idx, len = mbuf->pkt_len;
947 : :
948 [ # # ]: 0 : if (q->coalesce.type == 0) {
949 : 0 : mc = (struct ulp_txpkt *)q->coalesce.ptr;
950 : 0 : mc->cmd_dest = htonl(V_ULPTX_CMD(4) | V_ULP_TXPKT_DEST(0) |
951 : : V_ULP_TXPKT_FID(adap->sge.fw_evtq.cntxt_id) |
952 : : F_ULP_TXPKT_RO);
953 : 0 : mc->len = htonl(DIV_ROUND_UP(flits, 2));
954 : : sc_imm = (struct ulptx_idata *)(mc + 1);
955 : 0 : sc_imm->cmd_more = htonl(V_ULPTX_CMD(ULP_TX_SC_IMM) |
956 : : F_ULP_TX_SC_MORE);
957 : 0 : sc_imm->len = htonl(sizeof(*cpl));
958 : 0 : end = (u64 *)mc + flits;
959 : 0 : cpl = (struct cpl_tx_pkt_core *)(sc_imm + 1);
960 : : } else {
961 : 0 : end = (u64 *)q->coalesce.ptr + flits;
962 : : cpl = (struct cpl_tx_pkt_core *)q->coalesce.ptr;
963 : : }
964 : :
965 : : /* update coalesce structure for this txq */
966 : 0 : q->coalesce.flits += flits;
967 : 0 : q->coalesce.ptr += flits * sizeof(__be64);
968 : 0 : q->coalesce.len += mbuf->pkt_len;
969 : :
970 : : /* fill the cpl message, same as in t4_eth_xmit, this should be kept
971 : : * similar to t4_eth_xmit
972 : : */
973 [ # # ]: 0 : if (mbuf->ol_flags & RTE_MBUF_F_TX_IP_CKSUM) {
974 : 0 : cntrl = hwcsum(adap->params.chip, mbuf) |
975 : : F_TXPKT_IPCSUM_DIS;
976 : 0 : txq->stats.tx_cso++;
977 : : } else {
978 : : cntrl = F_TXPKT_L4CSUM_DIS | F_TXPKT_IPCSUM_DIS;
979 : : }
980 : :
981 [ # # ]: 0 : if (mbuf->ol_flags & RTE_MBUF_F_TX_VLAN) {
982 : 0 : txq->stats.vlan_ins++;
983 : 0 : cntrl |= F_TXPKT_VLAN_VLD | V_TXPKT_VLAN(mbuf->vlan_tci);
984 : : }
985 : :
986 : : cpl->ctrl0 = htonl(V_TXPKT_OPCODE(CPL_TX_PKT_XT));
987 [ # # ]: 0 : if (is_pf4(adap))
988 : 0 : cpl->ctrl0 |= htonl(V_TXPKT_INTF(pi->tx_chan) |
989 : : V_TXPKT_PF(adap->pf));
990 : : else
991 : 0 : cpl->ctrl0 |= htonl(V_TXPKT_INTF(pi->port_id));
992 : 0 : cpl->pack = htons(0);
993 [ # # ]: 0 : cpl->len = htons(len);
994 [ # # ]: 0 : cpl->ctrl1 = cpu_to_be64(cntrl);
995 : 0 : write_sgl(mbuf, q, (struct ulptx_sgl *)(cpl + 1), end, 0, addr);
996 : 0 : txq->stats.pkts++;
997 : 0 : txq->stats.tx_bytes += len;
998 : :
999 : 0 : sd = &q->sdesc[q->pidx + (idx >> 1)];
1000 [ # # ]: 0 : if (!(idx & 1)) {
1001 [ # # ]: 0 : if (sd->coalesce.idx) {
1002 : : int i;
1003 : :
1004 [ # # ]: 0 : for (i = 0; i < sd->coalesce.idx; i++) {
1005 : 0 : rte_pktmbuf_free(sd->coalesce.mbuf[i]);
1006 : 0 : sd->coalesce.mbuf[i] = NULL;
1007 : : }
1008 : : }
1009 : : }
1010 : :
1011 : : /* store pointers to the mbuf and the sgl used in free_tx_desc.
1012 : : * each tx desc can hold two pointers corresponding to the value
1013 : : * of ETH_COALESCE_PKT_PER_DESC
1014 : : */
1015 : 0 : sd->coalesce.mbuf[idx & 1] = mbuf;
1016 : 0 : sd->coalesce.sgl[idx & 1] = (struct ulptx_sgl *)(cpl + 1);
1017 : 0 : sd->coalesce.idx = (idx & 1) + 1;
1018 : :
1019 : : /* Send the coalesced work request, only if max reached. However,
1020 : : * if lower latency is preferred over throughput, then don't wait
1021 : : * for coalescing the next Tx burst and send the packets now.
1022 : : */
1023 : 0 : q->coalesce.idx++;
1024 [ # # ]: 0 : if (q->coalesce.idx == adap->params.max_tx_coalesce_num ||
1025 [ # # # # ]: 0 : (adap->devargs.tx_mode_latency && q->coalesce.idx >= nb_pkts))
1026 : 0 : ship_tx_pkt_coalesce_wr(adap, txq);
1027 : :
1028 : 0 : return 0;
1029 : : }
1030 : :
1031 : : /**
1032 : : * t4_eth_xmit - add a packet to an Ethernet Tx queue
1033 : : * @txq: the egress queue
1034 : : * @mbuf: the packet
1035 : : *
1036 : : * Add a packet to an SGE Ethernet Tx queue. Runs with softirqs disabled.
1037 : : */
1038 : 0 : int t4_eth_xmit(struct sge_eth_txq *txq, struct rte_mbuf *mbuf,
1039 : : uint16_t nb_pkts)
1040 : 0 : {
1041 : : const struct port_info *pi;
1042 : : struct cpl_tx_pkt_lso_core *lso;
1043 : : struct adapter *adap;
1044 : : struct rte_mbuf *m = mbuf;
1045 : : struct fw_eth_tx_pkt_wr *wr;
1046 : : struct fw_eth_tx_pkt_vm_wr *vmwr;
1047 : : struct cpl_tx_pkt_core *cpl;
1048 : : struct tx_sw_desc *d;
1049 : 0 : dma_addr_t addr[m->nb_segs];
1050 : : unsigned int flits, ndesc, cflits;
1051 : : int l3hdr_len, l4hdr_len, eth_xtra_len;
1052 : : int len, last_desc;
1053 : : int should_coal, credits;
1054 : : u32 wr_mid;
1055 : : u64 cntrl, *end;
1056 : : bool v6;
1057 : : u32 max_pkt_len;
1058 : :
1059 : : /* Reject xmit if queue is stopped */
1060 [ # # ]: 0 : if (unlikely(txq->flags & EQ_STOPPED))
1061 : : return -(EBUSY);
1062 : :
1063 : : /*
1064 : : * The chip min packet length is 10 octets but play safe and reject
1065 : : * anything shorter than an Ethernet header.
1066 : : */
1067 [ # # ]: 0 : if (unlikely(m->pkt_len < RTE_ETHER_HDR_LEN)) {
1068 : 0 : out_free:
1069 : 0 : rte_pktmbuf_free(m);
1070 : 0 : return 0;
1071 : : }
1072 : :
1073 : 0 : max_pkt_len = txq->data->mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN;
1074 [ # # ]: 0 : if ((!(m->ol_flags & RTE_MBUF_F_TX_TCP_SEG)) &&
1075 [ # # ]: 0 : (unlikely(m->pkt_len > max_pkt_len)))
1076 : 0 : goto out_free;
1077 : :
1078 : 0 : pi = txq->data->dev_private;
1079 : 0 : adap = pi->adapter;
1080 : :
1081 : : cntrl = F_TXPKT_L4CSUM_DIS | F_TXPKT_IPCSUM_DIS;
1082 : : /* align the end of coalesce WR to a 512 byte boundary */
1083 : 0 : txq->q.coalesce.max = (8 - (txq->q.pidx & 7)) * 8;
1084 : :
1085 [ # # ]: 0 : if ((m->ol_flags & RTE_MBUF_F_TX_TCP_SEG) == 0) {
1086 : 0 : should_coal = should_tx_packet_coalesce(txq, mbuf, &cflits, adap);
1087 [ # # ]: 0 : if (should_coal > 0) {
1088 [ # # ]: 0 : if (unlikely(map_mbuf(mbuf, addr) < 0)) {
1089 : 0 : dev_warn(adap, "%s: mapping err for coalesce\n",
1090 : : __func__);
1091 : 0 : txq->stats.mapping_err++;
1092 : 0 : goto out_free;
1093 : : }
1094 : 0 : return tx_do_packet_coalesce(txq, mbuf, cflits, adap,
1095 : : pi, addr, nb_pkts);
1096 [ # # ]: 0 : } else if (should_coal < 0) {
1097 : : return should_coal;
1098 : : }
1099 : : }
1100 : :
1101 [ # # ]: 0 : if (txq->q.coalesce.idx)
1102 : 0 : ship_tx_pkt_coalesce_wr(adap, txq);
1103 : :
1104 : 0 : flits = calc_tx_flits(m, adap);
1105 : : ndesc = flits_to_desc(flits);
1106 : 0 : credits = txq_avail(&txq->q) - ndesc;
1107 : :
1108 [ # # ]: 0 : if (unlikely(credits < 0)) {
1109 : 0 : dev_debug(adap, "%s: Tx ring %u full; credits = %d\n",
1110 : : __func__, txq->q.cntxt_id, credits);
1111 : 0 : return -EBUSY;
1112 : : }
1113 : :
1114 [ # # ]: 0 : if (unlikely(map_mbuf(m, addr) < 0)) {
1115 : 0 : txq->stats.mapping_err++;
1116 : 0 : goto out_free;
1117 : : }
1118 : :
1119 : 0 : wr_mid = V_FW_WR_LEN16(DIV_ROUND_UP(flits, 2));
1120 [ # # # # ]: 0 : if (Q_IDXDIFF(&txq->q, equeidx) >= 64) {
1121 : 0 : txq->q.equeidx = txq->q.pidx;
1122 : 0 : wr_mid |= F_FW_WR_EQUEQ;
1123 : : }
1124 : :
1125 [ # # ]: 0 : wr = (void *)&txq->q.desc[txq->q.pidx];
1126 : : vmwr = (void *)&txq->q.desc[txq->q.pidx];
1127 [ # # ]: 0 : wr->equiq_to_len16 = htonl(wr_mid);
1128 [ # # ]: 0 : if (is_pf4(adap)) {
1129 : 0 : wr->r3 = rte_cpu_to_be_64(0);
1130 : 0 : end = (u64 *)wr + flits;
1131 : : } else {
1132 : : const size_t fw_hdr_copy_len = (sizeof(vmwr->ethmacdst) +
1133 : : sizeof(vmwr->ethmacsrc) +
1134 : : sizeof(vmwr->ethtype) +
1135 : : sizeof(vmwr->vlantci));
1136 : :
1137 : 0 : vmwr->r3[0] = rte_cpu_to_be_32(0);
1138 : 0 : vmwr->r3[1] = rte_cpu_to_be_32(0);
1139 : 0 : memcpy((void *)vmwr->ethmacdst, rte_pktmbuf_mtod(m, void *),
1140 : : fw_hdr_copy_len);
1141 : 0 : end = (u64 *)vmwr + flits;
1142 : : }
1143 : :
1144 : : len = sizeof(*cpl);
1145 : :
1146 : : /* Coalescing skipped and we send through normal path */
1147 [ # # ]: 0 : if (!(m->ol_flags & RTE_MBUF_F_TX_TCP_SEG)) {
1148 [ # # # # ]: 0 : wr->op_immdlen = htonl(V_FW_WR_OP(is_pf4(adap) ?
1149 : : FW_ETH_TX_PKT_WR :
1150 : : FW_ETH_TX_PKT_VM_WR) |
1151 : : V_FW_WR_IMMDLEN(len));
1152 [ # # ]: 0 : if (is_pf4(adap))
1153 : 0 : cpl = (void *)(wr + 1);
1154 : : else
1155 : 0 : cpl = (void *)(vmwr + 1);
1156 [ # # ]: 0 : if (m->ol_flags & RTE_MBUF_F_TX_IP_CKSUM) {
1157 : 0 : cntrl = hwcsum(adap->params.chip, m) |
1158 : : F_TXPKT_IPCSUM_DIS;
1159 : 0 : txq->stats.tx_cso++;
1160 : : }
1161 : : } else {
1162 [ # # ]: 0 : if (is_pf4(adap))
1163 : 0 : lso = (void *)(wr + 1);
1164 : : else
1165 : 0 : lso = (void *)(vmwr + 1);
1166 : 0 : v6 = (m->ol_flags & RTE_MBUF_F_TX_IPV6) != 0;
1167 : 0 : l3hdr_len = m->l3_len;
1168 : 0 : l4hdr_len = m->l4_len;
1169 : 0 : eth_xtra_len = m->l2_len - RTE_ETHER_HDR_LEN;
1170 : : len += sizeof(*lso);
1171 [ # # # # ]: 0 : wr->op_immdlen = htonl(V_FW_WR_OP(is_pf4(adap) ?
1172 : : FW_ETH_TX_PKT_WR :
1173 : : FW_ETH_TX_PKT_VM_WR) |
1174 : : V_FW_WR_IMMDLEN(len));
1175 : 0 : lso->lso_ctrl = htonl(V_LSO_OPCODE(CPL_TX_PKT_LSO) |
1176 : : F_LSO_FIRST_SLICE | F_LSO_LAST_SLICE |
1177 : : V_LSO_IPV6(v6) |
1178 : : V_LSO_ETHHDR_LEN(eth_xtra_len / 4) |
1179 : : V_LSO_IPHDR_LEN(l3hdr_len / 4) |
1180 : : V_LSO_TCPHDR_LEN(l4hdr_len / 4));
1181 : 0 : lso->ipid_ofst = htons(0);
1182 [ # # ]: 0 : lso->mss = htons(m->tso_segsz);
1183 : 0 : lso->seqno_offset = htonl(0);
1184 [ # # ]: 0 : if (is_t4(adap->params.chip))
1185 : 0 : lso->len = htonl(m->pkt_len);
1186 : : else
1187 : 0 : lso->len = htonl(V_LSO_T5_XFER_SIZE(m->pkt_len));
1188 : 0 : cpl = (void *)(lso + 1);
1189 : :
1190 [ # # ]: 0 : if (CHELSIO_CHIP_VERSION(adap->params.chip) <= CHELSIO_T5)
1191 : 0 : cntrl = V_TXPKT_ETHHDR_LEN(eth_xtra_len);
1192 : : else
1193 : 0 : cntrl = V_T6_TXPKT_ETHHDR_LEN(eth_xtra_len);
1194 : :
1195 [ # # ]: 0 : cntrl |= V_TXPKT_CSUM_TYPE(v6 ? TX_CSUM_TCPIP6 :
1196 : 0 : TX_CSUM_TCPIP) |
1197 : 0 : V_TXPKT_IPHDR_LEN(l3hdr_len);
1198 : 0 : txq->stats.tso++;
1199 : 0 : txq->stats.tx_cso += m->tso_segsz;
1200 : : }
1201 : :
1202 [ # # ]: 0 : if (m->ol_flags & RTE_MBUF_F_TX_VLAN) {
1203 : 0 : txq->stats.vlan_ins++;
1204 : 0 : cntrl |= F_TXPKT_VLAN_VLD | V_TXPKT_VLAN(m->vlan_tci);
1205 : : }
1206 : :
1207 : : cpl->ctrl0 = htonl(V_TXPKT_OPCODE(CPL_TX_PKT_XT));
1208 [ # # ]: 0 : if (is_pf4(adap))
1209 : 0 : cpl->ctrl0 |= htonl(V_TXPKT_INTF(pi->tx_chan) |
1210 : : V_TXPKT_PF(adap->pf));
1211 : : else
1212 : 0 : cpl->ctrl0 |= htonl(V_TXPKT_INTF(pi->port_id) |
1213 : : V_TXPKT_PF(0));
1214 : :
1215 : 0 : cpl->pack = htons(0);
1216 [ # # ]: 0 : cpl->len = htons(m->pkt_len);
1217 [ # # ]: 0 : cpl->ctrl1 = cpu_to_be64(cntrl);
1218 : :
1219 : 0 : txq->stats.pkts++;
1220 : 0 : txq->stats.tx_bytes += m->pkt_len;
1221 : 0 : last_desc = txq->q.pidx + ndesc - 1;
1222 [ # # ]: 0 : if (last_desc >= (int)txq->q.size)
1223 : 0 : last_desc -= txq->q.size;
1224 : :
1225 : 0 : d = &txq->q.sdesc[last_desc];
1226 [ # # ]: 0 : if (d->coalesce.idx) {
1227 : : int i;
1228 : :
1229 [ # # ]: 0 : for (i = 0; i < d->coalesce.idx; i++) {
1230 : 0 : rte_pktmbuf_free(d->coalesce.mbuf[i]);
1231 : 0 : d->coalesce.mbuf[i] = NULL;
1232 : : }
1233 : 0 : d->coalesce.idx = 0;
1234 : : }
1235 : 0 : write_sgl(m, &txq->q, (struct ulptx_sgl *)(cpl + 1), end, 0,
1236 : : addr);
1237 : 0 : txq->q.sdesc[last_desc].mbuf = m;
1238 [ # # ]: 0 : txq->q.sdesc[last_desc].sgl = (struct ulptx_sgl *)(cpl + 1);
1239 : : txq_advance(&txq->q, ndesc);
1240 : 0 : ring_tx_db(adap, &txq->q);
1241 : 0 : return 0;
1242 : : }
1243 : :
1244 : : /**
1245 : : * reclaim_completed_tx_imm - reclaim completed control-queue Tx descs
1246 : : * @q: the SGE control Tx queue
1247 : : *
1248 : : * This is a variant of reclaim_completed_tx() that is used for Tx queues
1249 : : * that send only immediate data (presently just the control queues) and
1250 : : * thus do not have any mbufs to release.
1251 : : */
1252 : : static inline void reclaim_completed_tx_imm(struct sge_txq *q)
1253 : : {
1254 [ # # ]: 0 : int hw_cidx = ntohs(q->stat->cidx);
1255 : 0 : int reclaim = hw_cidx - q->cidx;
1256 : :
1257 [ # # # # ]: 0 : if (reclaim < 0)
1258 : 0 : reclaim += q->size;
1259 : :
1260 : 0 : q->in_use -= reclaim;
1261 : 0 : q->cidx = hw_cidx;
1262 : : }
1263 : :
1264 : : /**
1265 : : * is_imm - check whether a packet can be sent as immediate data
1266 : : * @mbuf: the packet
1267 : : *
1268 : : * Returns true if a packet can be sent as a WR with immediate data.
1269 : : */
1270 : : static inline int is_imm(const struct rte_mbuf *mbuf)
1271 : : {
1272 : 0 : return mbuf->pkt_len <= MAX_CTRL_WR_LEN;
1273 : : }
1274 : :
1275 : : /**
1276 : : * inline_tx_mbuf: inline a packet's data into TX descriptors
1277 : : * @q: the TX queue where the packet will be inlined
1278 : : * @from: pointer to data portion of packet
1279 : : * @to: pointer after cpl where data has to be inlined
1280 : : * @len: length of data to inline
1281 : : *
1282 : : * Inline a packet's contents directly to TX descriptors, starting at
1283 : : * the given position within the TX DMA ring.
1284 : : * Most of the complexity of this operation is dealing with wrap arounds
1285 : : * in the middle of the packet we want to inline.
1286 : : */
1287 : 0 : static void inline_tx_mbuf(const struct sge_txq *q, caddr_t from, caddr_t *to,
1288 : : int len)
1289 : : {
1290 : 0 : int left = RTE_PTR_DIFF(q->stat, *to);
1291 : :
1292 [ # # ]: 0 : if (likely((uintptr_t)*to + len <= (uintptr_t)q->stat)) {
1293 : : rte_memcpy(*to, from, len);
1294 : 0 : *to = RTE_PTR_ADD(*to, len);
1295 : : } else {
1296 [ # # ]: 0 : rte_memcpy(*to, from, left);
1297 : 0 : from = RTE_PTR_ADD(from, left);
1298 : 0 : left = len - left;
1299 [ # # ]: 0 : rte_memcpy((void *)q->desc, from, left);
1300 : 0 : *to = RTE_PTR_ADD((void *)q->desc, left);
1301 : : }
1302 : 0 : }
1303 : :
1304 : : /**
1305 : : * ctrl_xmit - send a packet through an SGE control Tx queue
1306 : : * @q: the control queue
1307 : : * @mbuf: the packet
1308 : : *
1309 : : * Send a packet through an SGE control Tx queue. Packets sent through
1310 : : * a control queue must fit entirely as immediate data.
1311 : : */
1312 : 0 : static int ctrl_xmit(struct sge_ctrl_txq *q, struct rte_mbuf *mbuf)
1313 : : {
1314 : : unsigned int ndesc;
1315 : : struct fw_wr_hdr *wr;
1316 : : caddr_t dst;
1317 : :
1318 [ # # ]: 0 : if (unlikely(!is_imm(mbuf))) {
1319 : 0 : WARN_ON(1);
1320 : 0 : rte_pktmbuf_free(mbuf);
1321 : 0 : return -1;
1322 : : }
1323 : :
1324 [ # # ]: 0 : reclaim_completed_tx_imm(&q->q);
1325 : 0 : ndesc = DIV_ROUND_UP(mbuf->pkt_len, sizeof(struct tx_desc));
1326 : 0 : t4_os_lock(&q->ctrlq_lock);
1327 : :
1328 : 0 : q->full = txq_avail(&q->q) < ndesc ? 1 : 0;
1329 [ # # ]: 0 : if (unlikely(q->full)) {
1330 : : t4_os_unlock(&q->ctrlq_lock);
1331 : 0 : return -1;
1332 : : }
1333 : :
1334 : 0 : wr = (struct fw_wr_hdr *)&q->q.desc[q->q.pidx];
1335 : 0 : dst = (void *)wr;
1336 : 0 : inline_tx_mbuf(&q->q, rte_pktmbuf_mtod(mbuf, caddr_t),
1337 : 0 : &dst, mbuf->data_len);
1338 : :
1339 : : txq_advance(&q->q, ndesc);
1340 [ # # ]: 0 : if (unlikely(txq_avail(&q->q) < 64))
1341 : 0 : wr->lo |= htonl(F_FW_WR_EQUEQ);
1342 : :
1343 : 0 : q->txp++;
1344 : :
1345 : 0 : ring_tx_db(q->adapter, &q->q);
1346 : : t4_os_unlock(&q->ctrlq_lock);
1347 : :
1348 : 0 : rte_pktmbuf_free(mbuf);
1349 : 0 : return 0;
1350 : : }
1351 : :
1352 : : /**
1353 : : * t4_mgmt_tx - send a management message
1354 : : * @q: the control queue
1355 : : * @mbuf: the packet containing the management message
1356 : : *
1357 : : * Send a management message through control queue.
1358 : : */
1359 : 0 : int t4_mgmt_tx(struct sge_ctrl_txq *q, struct rte_mbuf *mbuf)
1360 : : {
1361 : 0 : return ctrl_xmit(q, mbuf);
1362 : : }
1363 : :
1364 : : /**
1365 : : * alloc_ring - allocate resources for an SGE descriptor ring
1366 : : * @dev: the port associated with the queue
1367 : : * @z_name: memzone's name
1368 : : * @queue_id: queue index
1369 : : * @socket_id: preferred socket id for memory allocations
1370 : : * @nelem: the number of descriptors
1371 : : * @elem_size: the size of each descriptor
1372 : : * @stat_size: extra space in HW ring for status information
1373 : : * @sw_size: the size of the SW state associated with each ring element
1374 : : * @phys: the physical address of the allocated ring
1375 : : * @metadata: address of the array holding the SW state for the ring
1376 : : *
1377 : : * Allocates resources for an SGE descriptor ring, such as Tx queues,
1378 : : * free buffer lists, or response queues. Each SGE ring requires
1379 : : * space for its HW descriptors plus, optionally, space for the SW state
1380 : : * associated with each HW entry (the metadata). The function returns
1381 : : * three values: the virtual address for the HW ring (the return value
1382 : : * of the function), the bus address of the HW ring, and the address
1383 : : * of the SW ring.
1384 : : */
1385 : 0 : static void *alloc_ring(struct rte_eth_dev *dev, const char *z_name,
1386 : : uint16_t queue_id, int socket_id, size_t nelem,
1387 : : size_t elem_size, size_t stat_size, size_t sw_size,
1388 : : dma_addr_t *phys, void *metadata)
1389 : : {
1390 : 0 : size_t len = CXGBE_MAX_RING_DESC_SIZE * elem_size + stat_size;
1391 : : char z_name_sw[RTE_MEMZONE_NAMESIZE];
1392 : : const struct rte_memzone *tz;
1393 : : void *s = NULL;
1394 : :
1395 : 0 : snprintf(z_name_sw, sizeof(z_name_sw), "eth_p%d_q%d_%s_sw_ring",
1396 : 0 : dev->data->port_id, queue_id, z_name);
1397 : :
1398 : 0 : dev_debug(adapter, "%s: nelem = %zu; elem_size = %zu; sw_size = %zu; "
1399 : : "stat_size = %zu; queue_id = %u; socket_id = %d; z_name = %s;"
1400 : : " z_name_sw = %s\n", __func__, nelem, elem_size, sw_size,
1401 : : stat_size, queue_id, socket_id, z_name, z_name_sw);
1402 : :
1403 : : /*
1404 : : * Allocate TX/RX ring hardware descriptors. A memzone large enough to
1405 : : * handle the maximum ring size is allocated in order to allow for
1406 : : * resizing in later calls to the queue setup function.
1407 : : */
1408 : 0 : tz = rte_eth_dma_zone_reserve(dev, z_name, queue_id, len, 4096,
1409 : : socket_id);
1410 [ # # ]: 0 : if (!tz)
1411 : : return NULL;
1412 : :
1413 [ # # ]: 0 : memset(tz->addr, 0, len);
1414 [ # # ]: 0 : if (sw_size) {
1415 : 0 : s = rte_zmalloc_socket(z_name_sw, nelem * sw_size,
1416 : : RTE_CACHE_LINE_SIZE, socket_id);
1417 : :
1418 [ # # ]: 0 : if (!s) {
1419 : 0 : dev_err(adapter, "%s: failed to get sw_ring memory\n",
1420 : : __func__);
1421 : 0 : return NULL;
1422 : : }
1423 : : }
1424 [ # # ]: 0 : if (metadata)
1425 : 0 : *(void **)metadata = s;
1426 : :
1427 : 0 : *phys = (uint64_t)tz->iova;
1428 : 0 : return tz->addr;
1429 : : }
1430 : :
1431 : : #define CXGB4_MSG_AN ((void *)1)
1432 : :
1433 : : /**
1434 : : * rspq_next - advance to the next entry in a response queue
1435 : : * @q: the queue
1436 : : *
1437 : : * Updates the state of a response queue to advance it to the next entry.
1438 : : */
1439 : : static inline void rspq_next(struct sge_rspq *q)
1440 : : {
1441 : 0 : q->cur_desc = (const __be64 *)((const char *)q->cur_desc + q->iqe_len);
1442 [ # # ]: 0 : if (unlikely(++q->cidx == q->size)) {
1443 : 0 : q->cidx = 0;
1444 : 0 : q->gen ^= 1;
1445 : 0 : q->cur_desc = q->desc;
1446 : : }
1447 : : }
1448 : :
1449 : : static inline void cxgbe_set_mbuf_info(struct rte_mbuf *pkt, uint32_t ptype,
1450 : : uint64_t ol_flags)
1451 : : {
1452 : 0 : pkt->packet_type |= ptype;
1453 : 0 : pkt->ol_flags |= ol_flags;
1454 : 0 : }
1455 : :
1456 : 0 : static inline void cxgbe_fill_mbuf_info(struct adapter *adap,
1457 : : const struct cpl_rx_pkt *cpl,
1458 : : struct rte_mbuf *pkt)
1459 : : {
1460 : : bool csum_ok;
1461 : : u16 err_vec;
1462 : :
1463 [ # # ]: 0 : if (adap->params.tp.rx_pkt_encap)
1464 : 0 : err_vec = G_T6_COMPR_RXERR_VEC(ntohs(cpl->err_vec));
1465 : : else
1466 : 0 : err_vec = ntohs(cpl->err_vec);
1467 : :
1468 [ # # # # ]: 0 : csum_ok = cpl->csum_calc && !err_vec;
1469 : :
1470 [ # # ]: 0 : if (cpl->vlan_ex)
1471 : : cxgbe_set_mbuf_info(pkt, RTE_PTYPE_L2_ETHER_VLAN,
1472 : : RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED);
1473 : : else
1474 : : cxgbe_set_mbuf_info(pkt, RTE_PTYPE_L2_ETHER, 0);
1475 : :
1476 [ # # ]: 0 : if (cpl->l2info & htonl(F_RXF_IP))
1477 [ # # ]: 0 : cxgbe_set_mbuf_info(pkt, RTE_PTYPE_L3_IPV4,
1478 : : csum_ok ? RTE_MBUF_F_RX_IP_CKSUM_GOOD :
1479 : : RTE_MBUF_F_RX_IP_CKSUM_BAD);
1480 [ # # ]: 0 : else if (cpl->l2info & htonl(F_RXF_IP6))
1481 [ # # ]: 0 : cxgbe_set_mbuf_info(pkt, RTE_PTYPE_L3_IPV6,
1482 : : csum_ok ? RTE_MBUF_F_RX_IP_CKSUM_GOOD :
1483 : : RTE_MBUF_F_RX_IP_CKSUM_BAD);
1484 : :
1485 [ # # ]: 0 : if (cpl->l2info & htonl(F_RXF_TCP))
1486 [ # # ]: 0 : cxgbe_set_mbuf_info(pkt, RTE_PTYPE_L4_TCP,
1487 : : csum_ok ? RTE_MBUF_F_RX_L4_CKSUM_GOOD :
1488 : : RTE_MBUF_F_RX_L4_CKSUM_BAD);
1489 [ # # ]: 0 : else if (cpl->l2info & htonl(F_RXF_UDP))
1490 [ # # ]: 0 : cxgbe_set_mbuf_info(pkt, RTE_PTYPE_L4_UDP,
1491 : : csum_ok ? RTE_MBUF_F_RX_L4_CKSUM_GOOD :
1492 : : RTE_MBUF_F_RX_L4_CKSUM_BAD);
1493 : 0 : }
1494 : :
1495 : : /**
1496 : : * process_responses - process responses from an SGE response queue
1497 : : * @q: the ingress queue to process
1498 : : * @budget: how many responses can be processed in this round
1499 : : * @rx_pkts: mbuf to put the pkts
1500 : : *
1501 : : * Process responses from an SGE response queue up to the supplied budget.
1502 : : * Responses include received packets as well as control messages from FW
1503 : : * or HW.
1504 : : *
1505 : : * Additionally choose the interrupt holdoff time for the next interrupt
1506 : : * on this queue. If the system is under memory shortage use a fairly
1507 : : * long delay to help recovery.
1508 : : */
1509 : 0 : static int process_responses(struct sge_rspq *q, int budget,
1510 : : struct rte_mbuf **rx_pkts)
1511 : : {
1512 : : int ret = 0, rsp_type;
1513 : : int budget_left = budget;
1514 : : const struct rsp_ctrl *rc;
1515 : 0 : struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq);
1516 : :
1517 [ # # ]: 0 : while (likely(budget_left)) {
1518 [ # # ]: 0 : if (q->cidx == ntohs(q->stat->pidx))
1519 : : break;
1520 : :
1521 : 0 : rc = (const struct rsp_ctrl *)
1522 : 0 : ((const char *)q->cur_desc + (q->iqe_len - sizeof(*rc)));
1523 : :
1524 : : /*
1525 : : * Ensure response has been read
1526 : : */
1527 : : rmb();
1528 : 0 : rsp_type = G_RSPD_TYPE(rc->u.type_gen);
1529 : :
1530 [ # # ]: 0 : if (likely(rsp_type == X_RSPD_TYPE_FLBUF)) {
1531 : 0 : struct sge *s = &q->adapter->sge;
1532 : : unsigned int stat_pidx;
1533 : : int stat_pidx_diff;
1534 : :
1535 [ # # ]: 0 : stat_pidx = ntohs(q->stat->pidx);
1536 [ # # ]: 0 : stat_pidx_diff = P_IDXDIFF(q, stat_pidx);
1537 [ # # ]: 0 : while (stat_pidx_diff && budget_left) {
1538 : 0 : const struct rx_sw_desc *rsd =
1539 : 0 : &rxq->fl.sdesc[rxq->fl.cidx];
1540 : 0 : const struct rss_header *rss_hdr =
1541 : : (const void *)q->cur_desc;
1542 : 0 : const struct cpl_rx_pkt *cpl =
1543 : : (const void *)&q->cur_desc[1];
1544 : : struct rte_mbuf *pkt, *npkt;
1545 : : u32 len, bufsz;
1546 : :
1547 : 0 : rc = (const struct rsp_ctrl *)
1548 : 0 : ((const char *)q->cur_desc +
1549 : 0 : (q->iqe_len - sizeof(*rc)));
1550 : :
1551 : 0 : rsp_type = G_RSPD_TYPE(rc->u.type_gen);
1552 [ # # ]: 0 : if (unlikely(rsp_type != X_RSPD_TYPE_FLBUF))
1553 : : break;
1554 : :
1555 [ # # ]: 0 : len = ntohl(rc->pldbuflen_qid);
1556 [ # # ]: 0 : BUG_ON(!(len & F_RSPD_NEWBUF));
1557 : 0 : pkt = rsd->buf;
1558 : : npkt = pkt;
1559 : 0 : len = G_RSPD_LEN(len);
1560 : 0 : pkt->pkt_len = len;
1561 : :
1562 : : /* Chain mbufs into len if necessary */
1563 [ # # ]: 0 : while (len) {
1564 : 0 : struct rte_mbuf *new_pkt = rsd->buf;
1565 : :
1566 : 0 : bufsz = min(get_buf_size(q->adapter,
1567 : : rsd), len);
1568 [ # # ]: 0 : new_pkt->data_len = bufsz;
1569 : : unmap_rx_buf(&rxq->fl);
1570 : 0 : len -= bufsz;
1571 : 0 : npkt->next = new_pkt;
1572 : : npkt = new_pkt;
1573 : 0 : pkt->nb_segs++;
1574 : 0 : rsd = &rxq->fl.sdesc[rxq->fl.cidx];
1575 : : }
1576 : 0 : npkt->next = NULL;
1577 : 0 : pkt->nb_segs--;
1578 : :
1579 : 0 : cxgbe_fill_mbuf_info(q->adapter, cpl, pkt);
1580 : :
1581 [ # # # # ]: 0 : if (!rss_hdr->filter_tid &&
1582 : : rss_hdr->hash_type) {
1583 : 0 : pkt->ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
1584 : 0 : pkt->hash.rss =
1585 : 0 : ntohl(rss_hdr->hash_val);
1586 : : }
1587 : :
1588 [ # # ]: 0 : if (cpl->vlan_ex)
1589 : 0 : pkt->vlan_tci = ntohs(cpl->vlan);
1590 : :
1591 [ # # ]: 0 : rte_pktmbuf_adj(pkt, s->pktshift);
1592 : 0 : rxq->stats.pkts++;
1593 : 0 : rxq->stats.rx_bytes += pkt->pkt_len;
1594 [ # # ]: 0 : rx_pkts[budget - budget_left] = pkt;
1595 : :
1596 : : rspq_next(q);
1597 : 0 : budget_left--;
1598 : 0 : stat_pidx_diff--;
1599 : : }
1600 : 0 : continue;
1601 [ # # ]: 0 : } else if (likely(rsp_type == X_RSPD_TYPE_CPL)) {
1602 : 0 : ret = q->handler(q, q->cur_desc, NULL);
1603 : : } else {
1604 : 0 : ret = q->handler(q, (const __be64 *)rc, CXGB4_MSG_AN);
1605 : : }
1606 : :
1607 [ # # ]: 0 : if (unlikely(ret)) {
1608 : : /* couldn't process descriptor, back off for recovery */
1609 : 0 : q->next_intr_params = V_QINTR_TIMER_IDX(NOMEM_TMR_IDX);
1610 : 0 : break;
1611 : : }
1612 : :
1613 : : rspq_next(q);
1614 : 0 : budget_left--;
1615 : : }
1616 : :
1617 : : /*
1618 : : * If this is a Response Queue with an associated Free List and
1619 : : * there's room for another chunk of new Free List buffer pointers,
1620 : : * refill the Free List.
1621 : : */
1622 : :
1623 [ # # # # ]: 0 : if (q->offset >= 0 && fl_cap(&rxq->fl) - rxq->fl.avail >= 64)
1624 : 0 : __refill_fl(q->adapter, &rxq->fl);
1625 : :
1626 : 0 : return budget - budget_left;
1627 : : }
1628 : :
1629 : 0 : int cxgbe_poll(struct sge_rspq *q, struct rte_mbuf **rx_pkts,
1630 : : unsigned int budget, unsigned int *work_done)
1631 : : {
1632 : 0 : struct sge_eth_rxq *rxq = container_of(q, struct sge_eth_rxq, rspq);
1633 : : unsigned int cidx_inc;
1634 : : unsigned int params;
1635 : : u32 val;
1636 : :
1637 [ # # ]: 0 : if (unlikely(rxq->flags & IQ_STOPPED)) {
1638 : 0 : *work_done = 0;
1639 : 0 : return 0;
1640 : : }
1641 : :
1642 : 0 : *work_done = process_responses(q, budget, rx_pkts);
1643 : :
1644 [ # # ]: 0 : if (*work_done) {
1645 [ # # ]: 0 : cidx_inc = R_IDXDIFF(q, gts_idx);
1646 : :
1647 [ # # # # ]: 0 : if (q->offset >= 0 && fl_cap(&rxq->fl) - rxq->fl.avail >= 64)
1648 : 0 : __refill_fl(q->adapter, &rxq->fl);
1649 : :
1650 : 0 : params = q->intr_params;
1651 : 0 : q->next_intr_params = params;
1652 : 0 : val = V_CIDXINC(cidx_inc) | V_SEINTARM(params);
1653 : :
1654 [ # # ]: 0 : if (unlikely(!q->bar2_addr)) {
1655 [ # # ]: 0 : u32 reg = is_pf4(q->adapter) ? MYPF_REG(A_SGE_PF_GTS) :
1656 : : T4VF_SGE_BASE_ADDR +
1657 : : A_SGE_VF_GTS;
1658 : :
1659 : 0 : t4_write_reg(q->adapter, reg,
1660 : 0 : val | V_INGRESSQID((u32)q->cntxt_id));
1661 : : } else {
1662 : 0 : writel(val | V_INGRESSQID(q->bar2_qid),
1663 : 0 : (void *)((uintptr_t)q->bar2_addr + SGE_UDB_GTS));
1664 : : /* This Write memory Barrier will force the
1665 : : * write to the User Doorbell area to be
1666 : : * flushed.
1667 : : */
1668 : : wmb();
1669 : : }
1670 : 0 : q->gts_idx = q->cidx;
1671 : : }
1672 : : return 0;
1673 : : }
1674 : :
1675 : : /**
1676 : : * bar2_address - return the BAR2 address for an SGE Queue's Registers
1677 : : * @adapter: the adapter
1678 : : * @qid: the SGE Queue ID
1679 : : * @qtype: the SGE Queue Type (Egress or Ingress)
1680 : : * @pbar2_qid: BAR2 Queue ID or 0 for Queue ID inferred SGE Queues
1681 : : *
1682 : : * Returns the BAR2 address for the SGE Queue Registers associated with
1683 : : * @qid. If BAR2 SGE Registers aren't available, returns NULL. Also
1684 : : * returns the BAR2 Queue ID to be used with writes to the BAR2 SGE
1685 : : * Queue Registers. If the BAR2 Queue ID is 0, then "Inferred Queue ID"
1686 : : * Registers are supported (e.g. the Write Combining Doorbell Buffer).
1687 : : */
1688 : : static void __iomem *bar2_address(struct adapter *adapter, unsigned int qid,
1689 : : enum t4_bar2_qtype qtype,
1690 : : unsigned int *pbar2_qid)
1691 : : {
1692 : : u64 bar2_qoffset;
1693 : : int ret;
1694 : :
1695 : 0 : ret = t4_bar2_sge_qregs(adapter, qid, qtype, &bar2_qoffset, pbar2_qid);
1696 [ # # # # : 0 : if (ret)
# # ]
1697 : : return NULL;
1698 : :
1699 : 0 : return adapter->bar2 + bar2_qoffset;
1700 : : }
1701 : :
1702 : 0 : int t4_sge_eth_rxq_start(struct adapter *adap, struct sge_eth_rxq *rxq)
1703 : : {
1704 [ # # ]: 0 : unsigned int fl_id = rxq->fl.size ? rxq->fl.cntxt_id : 0xffff;
1705 : :
1706 : 0 : rxq->flags &= ~IQ_STOPPED;
1707 : 0 : return t4_iq_start_stop(adap, adap->mbox, true, adap->pf, 0,
1708 : 0 : rxq->rspq.cntxt_id, fl_id, 0xffff);
1709 : : }
1710 : :
1711 : 0 : int t4_sge_eth_rxq_stop(struct adapter *adap, struct sge_eth_rxq *rxq)
1712 : : {
1713 [ # # ]: 0 : unsigned int fl_id = rxq->fl.size ? rxq->fl.cntxt_id : 0xffff;
1714 : :
1715 : 0 : rxq->flags |= IQ_STOPPED;
1716 : 0 : return t4_iq_start_stop(adap, adap->mbox, false, adap->pf, 0,
1717 : 0 : rxq->rspq.cntxt_id, fl_id, 0xffff);
1718 : : }
1719 : :
1720 [ # # ]: 0 : static int cxgbe_sge_fl_buf_size_index(const struct adapter *adap,
1721 : : struct rte_mempool *mp)
1722 : : {
1723 : : int fl_buf_size, size, delta, min_delta = INT_MAX;
1724 : : unsigned int i, match = UINT_MAX;
1725 : : const struct sge *s = &adap->sge;
1726 : :
1727 : 0 : size = rte_pktmbuf_data_room_size(mp) - RTE_PKTMBUF_HEADROOM;
1728 [ # # ]: 0 : for (i = 0; i < RTE_DIM(s->fl_buffer_size); i++) {
1729 : 0 : fl_buf_size = s->fl_buffer_size[i];
1730 [ # # ]: 0 : if (fl_buf_size > size || fl_buf_size == 0)
1731 : 0 : continue;
1732 : :
1733 : 0 : delta = size - fl_buf_size;
1734 [ # # ]: 0 : if (delta < 0)
1735 : 0 : delta = -delta;
1736 [ # # ]: 0 : if (delta < min_delta) {
1737 : : min_delta = delta;
1738 : : match = i;
1739 : : }
1740 : : }
1741 : :
1742 [ # # ]: 0 : if (match == UINT_MAX) {
1743 : 0 : dev_err(adap,
1744 : : "Could not find valid buffer size for mbuf data room: %d\n",
1745 : : size);
1746 : 0 : return -EINVAL;
1747 : : }
1748 : :
1749 : 0 : return match;
1750 : : }
1751 : :
1752 : : /*
1753 : : * @intr_idx: MSI/MSI-X vector if >=0, -(absolute qid + 1) if < 0
1754 : : * @cong: < 0 -> no congestion feedback, >= 0 -> congestion channel map
1755 : : */
1756 : 0 : int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
1757 : : struct rte_eth_dev *eth_dev, int intr_idx,
1758 : : struct sge_fl *fl, rspq_handler_t hnd, int cong,
1759 : : struct rte_mempool *mp, int queue_id, int socket_id)
1760 : : {
1761 : 0 : struct port_info *pi = eth_dev->data->dev_private;
1762 : : u8 pciechan, fl_buf_size_idx = 0;
1763 : : struct sge *s = &adap->sge;
1764 : : unsigned int nb_refill;
1765 : : struct fw_iq_cmd c;
1766 : : int ret, flsz = 0;
1767 : :
1768 [ # # ]: 0 : if (fl != NULL) {
1769 : 0 : ret = cxgbe_sge_fl_buf_size_index(adap, mp);
1770 [ # # ]: 0 : if (ret < 0)
1771 : : return ret;
1772 : :
1773 : 0 : fl_buf_size_idx = ret;
1774 : : }
1775 : :
1776 : : /* Size needs to be multiple of 16, including status entry. */
1777 : 0 : iq->size = cxgbe_roundup(iq->size, 16);
1778 : :
1779 : 0 : iq->desc = alloc_ring(eth_dev, fwevtq ? "fwq_ring" : "rx_ring",
1780 [ # # ]: 0 : queue_id, socket_id, iq->size, iq->iqe_len,
1781 : : 0, 0, &iq->phys_addr, NULL);
1782 [ # # ]: 0 : if (!iq->desc)
1783 : : return -ENOMEM;
1784 : :
1785 : : memset(&c, 0, sizeof(c));
1786 [ # # ]: 0 : c.op_to_vfn = htonl(V_FW_CMD_OP(FW_IQ_CMD) | F_FW_CMD_REQUEST |
1787 : : F_FW_CMD_WRITE | F_FW_CMD_EXEC);
1788 : :
1789 [ # # ]: 0 : if (is_pf4(adap)) {
1790 : 0 : pciechan = pi->tx_chan;
1791 : 0 : c.op_to_vfn |= htonl(V_FW_IQ_CMD_PFN(adap->pf) |
1792 : : V_FW_IQ_CMD_VFN(0));
1793 [ # # ]: 0 : if (cong >= 0)
1794 : 0 : c.iqns_to_fl0congen =
1795 [ # # ]: 0 : htonl(F_FW_IQ_CMD_IQFLINTCONGEN |
1796 : : V_FW_IQ_CMD_IQTYPE(cong ?
1797 : : FW_IQ_IQTYPE_NIC :
1798 : : FW_IQ_IQTYPE_OFLD) |
1799 : : F_FW_IQ_CMD_IQRO);
1800 : : } else {
1801 : 0 : pciechan = pi->port_id;
1802 : : }
1803 : :
1804 : 0 : c.alloc_to_len16 = htonl(F_FW_IQ_CMD_ALLOC | F_FW_IQ_CMD_IQSTART |
1805 : : (sizeof(c) / 16));
1806 : 0 : c.type_to_iqandstindex =
1807 [ # # ]: 0 : htonl(V_FW_IQ_CMD_TYPE(FW_IQ_TYPE_FL_INT_CAP) |
1808 : : V_FW_IQ_CMD_IQASYNCH(fwevtq) |
1809 : : V_FW_IQ_CMD_VIID(pi->viid) |
1810 : : V_FW_IQ_CMD_IQANDST(intr_idx < 0) |
1811 : : V_FW_IQ_CMD_IQANUD(X_UPDATEDELIVERY_STATUS_PAGE) |
1812 : : V_FW_IQ_CMD_IQANDSTINDEX(intr_idx >= 0 ? intr_idx :
1813 : : -intr_idx - 1));
1814 : 0 : c.iqdroprss_to_iqesize =
1815 [ # # ]: 0 : htons(V_FW_IQ_CMD_IQPCIECH(pciechan) |
1816 : : F_FW_IQ_CMD_IQGTSMODE |
1817 : : V_FW_IQ_CMD_IQINTCNTTHRESH(iq->pktcnt_idx) |
1818 : : V_FW_IQ_CMD_IQESIZE(ilog2(iq->iqe_len) - 4));
1819 : 0 : c.iqsize = htons(iq->size);
1820 [ # # ]: 0 : c.iqaddr = cpu_to_be64(iq->phys_addr);
1821 : :
1822 [ # # ]: 0 : if (fl) {
1823 : 0 : unsigned int chip_ver = CHELSIO_CHIP_VERSION(adap->params.chip);
1824 : :
1825 : : /*
1826 : : * Allocate the ring for the hardware free list (with space
1827 : : * for its status page) along with the associated software
1828 : : * descriptor ring. The free list size needs to be a multiple
1829 : : * of the Egress Queue Unit and at least 2 Egress Units larger
1830 : : * than the SGE's Egress Congestion Threshold
1831 : : * (fl_starve_thres - 1).
1832 : : */
1833 [ # # ]: 0 : if (fl->size < s->fl_starve_thres - 1 + 2 * 8)
1834 : 0 : fl->size = s->fl_starve_thres - 1 + 2 * 8;
1835 : 0 : fl->size = cxgbe_roundup(fl->size, 8);
1836 : :
1837 : 0 : fl->desc = alloc_ring(eth_dev, "fl_ring", queue_id, socket_id,
1838 : 0 : fl->size, sizeof(__be64), s->stat_len,
1839 : : sizeof(struct rx_sw_desc),
1840 : 0 : &fl->addr, &fl->sdesc);
1841 [ # # ]: 0 : if (!fl->desc) {
1842 : : ret = -ENOMEM;
1843 : 0 : goto err;
1844 : : }
1845 : :
1846 : 0 : flsz = fl->size / 8 + s->stat_len / sizeof(struct tx_desc);
1847 [ # # ]: 0 : c.iqns_to_fl0congen |=
1848 : : htonl(V_FW_IQ_CMD_FL0HOSTFCMODE(X_HOSTFCMODE_NONE) |
1849 : : F_FW_IQ_CMD_FL0FETCHRO | F_FW_IQ_CMD_FL0DATARO);
1850 [ # # # # ]: 0 : if (is_pf4(adap) && cong >= 0)
1851 : 0 : c.iqns_to_fl0congen |=
1852 : 0 : htonl(V_FW_IQ_CMD_FL0CNGCHMAP(cong) |
1853 : : F_FW_IQ_CMD_FL0CONGCIF |
1854 : : F_FW_IQ_CMD_FL0CONGEN);
1855 : :
1856 : : /* In T6, for egress queue type FL there is internal overhead
1857 : : * of 16B for header going into FLM module.
1858 : : * Hence maximum allowed burst size will be 448 bytes.
1859 : : */
1860 : 0 : c.fl0dcaen_to_fl0cidxfthresh =
1861 [ # # # # : 0 : htons(V_FW_IQ_CMD_FL0FBMIN(chip_ver <= CHELSIO_T5 ?
# # ]
1862 : : X_FETCHBURSTMIN_128B :
1863 : : X_FETCHBURSTMIN_64B) |
1864 : : V_FW_IQ_CMD_FL0FBMAX(chip_ver <= CHELSIO_T5 ?
1865 : : X_FETCHBURSTMAX_512B :
1866 : : X_FETCHBURSTMAX_256B));
1867 : 0 : c.fl0size = htons(flsz);
1868 [ # # ]: 0 : c.fl0addr = cpu_to_be64(fl->addr);
1869 : : }
1870 : :
1871 [ # # ]: 0 : if (is_pf4(adap))
1872 : 0 : ret = t4_wr_mbox(adap, adap->mbox, &c, sizeof(c), &c);
1873 : : else
1874 : : ret = t4vf_wr_mbox(adap, &c, sizeof(c), &c);
1875 [ # # ]: 0 : if (ret)
1876 : 0 : goto err;
1877 : :
1878 : 0 : iq->cur_desc = iq->desc;
1879 : 0 : iq->cidx = 0;
1880 : 0 : iq->gts_idx = 0;
1881 : 0 : iq->gen = 1;
1882 : 0 : iq->next_intr_params = iq->intr_params;
1883 : 0 : iq->cntxt_id = ntohs(c.iqid);
1884 : 0 : iq->abs_id = ntohs(c.physiqid);
1885 : 0 : iq->bar2_addr = bar2_address(adap, iq->cntxt_id, T4_BAR2_QTYPE_INGRESS,
1886 : : &iq->bar2_qid);
1887 : 0 : iq->size--; /* subtract status entry */
1888 : 0 : iq->stat = (void *)&iq->desc[iq->size * 8];
1889 : 0 : iq->eth_dev = eth_dev;
1890 : 0 : iq->handler = hnd;
1891 : 0 : iq->port_id = eth_dev->data->port_id;
1892 : 0 : iq->mb_pool = mp;
1893 : :
1894 : : /* set offset to -1 to distinguish ingress queues without FL */
1895 [ # # ]: 0 : iq->offset = fl ? 0 : -1;
1896 : :
1897 [ # # ]: 0 : if (fl) {
1898 : 0 : fl->cntxt_id = ntohs(c.fl0id);
1899 : 0 : fl->avail = 0;
1900 : 0 : fl->pend_cred = 0;
1901 : 0 : fl->pidx = 0;
1902 : 0 : fl->cidx = 0;
1903 : 0 : fl->alloc_failed = 0;
1904 : 0 : fl->fl_buf_size_idx = fl_buf_size_idx;
1905 : :
1906 : : /*
1907 : : * Note, we must initialize the BAR2 Free List User Doorbell
1908 : : * information before refilling the Free List!
1909 : : */
1910 : 0 : fl->bar2_addr = bar2_address(adap, fl->cntxt_id,
1911 : : T4_BAR2_QTYPE_EGRESS,
1912 : : &fl->bar2_qid);
1913 : :
1914 : 0 : nb_refill = refill_fl(adap, fl, fl_cap(fl));
1915 [ # # ]: 0 : if (nb_refill != fl_cap(fl)) {
1916 : : ret = -ENOMEM;
1917 : 0 : dev_err(adap, "%s: mbuf alloc failed with error: %d\n",
1918 : : __func__, ret);
1919 : 0 : goto refill_fl_err;
1920 : : }
1921 : : }
1922 : :
1923 : : /*
1924 : : * For T5 and later we attempt to set up the Congestion Manager values
1925 : : * of the new RX Ethernet Queue. This should really be handled by
1926 : : * firmware because it's more complex than any host driver wants to
1927 : : * get involved with and it's different per chip and this is almost
1928 : : * certainly wrong. Formware would be wrong as well, but it would be
1929 : : * a lot easier to fix in one place ... For now we do something very
1930 : : * simple (and hopefully less wrong).
1931 : : */
1932 [ # # # # : 0 : if (is_pf4(adap) && !is_t4(adap->params.chip) && cong >= 0) {
# # ]
1933 : 0 : u8 cng_ch_bits_log = adap->params.arch.cng_ch_bits_log;
1934 : : u32 param, val, ch_map = 0;
1935 : : int i;
1936 : :
1937 : 0 : param = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) |
1938 : 0 : V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DMAQ_CONM_CTXT) |
1939 : 0 : V_FW_PARAMS_PARAM_YZ(iq->cntxt_id));
1940 [ # # ]: 0 : if (cong == 0) {
1941 : 0 : val = V_CONMCTXT_CNGTPMODE(X_CONMCTXT_CNGTPMODE_QUEUE);
1942 : : } else {
1943 : : val = V_CONMCTXT_CNGTPMODE(
1944 : : X_CONMCTXT_CNGTPMODE_CHANNEL);
1945 [ # # ]: 0 : for (i = 0; i < 4; i++) {
1946 [ # # ]: 0 : if (cong & (1 << i))
1947 : 0 : ch_map |= 1 << (i << cng_ch_bits_log);
1948 : : }
1949 : 0 : val |= V_CONMCTXT_CNGCHMAP(ch_map);
1950 : : }
1951 : 0 : ret = t4_set_params(adap, adap->mbox, adap->pf, 0, 1,
1952 : : ¶m, &val);
1953 [ # # ]: 0 : if (ret)
1954 : 0 : dev_warn(adap->pdev_dev, "Failed to set Congestion Manager Context for Ingress Queue %d: %d\n",
1955 : : iq->cntxt_id, -ret);
1956 : : }
1957 : :
1958 : : return 0;
1959 : :
1960 : : refill_fl_err:
1961 : 0 : t4_iq_free(adap, adap->mbox, adap->pf, 0, FW_IQ_TYPE_FL_INT_CAP,
1962 : 0 : iq->cntxt_id, fl->cntxt_id, 0xffff);
1963 : 0 : err:
1964 : 0 : iq->cntxt_id = 0;
1965 : 0 : iq->abs_id = 0;
1966 [ # # ]: 0 : if (iq->desc)
1967 : 0 : iq->desc = NULL;
1968 : :
1969 [ # # # # ]: 0 : if (fl && fl->desc) {
1970 : 0 : rte_free(fl->sdesc);
1971 : 0 : fl->cntxt_id = 0;
1972 : 0 : fl->sdesc = NULL;
1973 : 0 : fl->desc = NULL;
1974 : : }
1975 : : return ret;
1976 : : }
1977 : :
1978 : 0 : static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id,
1979 : : unsigned int abs_id)
1980 : : {
1981 : 0 : q->cntxt_id = id;
1982 : 0 : q->abs_id = abs_id;
1983 : 0 : q->bar2_addr = bar2_address(adap, q->cntxt_id, T4_BAR2_QTYPE_EGRESS,
1984 : : &q->bar2_qid);
1985 : 0 : q->cidx = 0;
1986 : 0 : q->pidx = 0;
1987 : 0 : q->dbidx = 0;
1988 : 0 : q->in_use = 0;
1989 : 0 : q->equeidx = 0;
1990 : 0 : q->coalesce.idx = 0;
1991 : 0 : q->coalesce.len = 0;
1992 : 0 : q->coalesce.flits = 0;
1993 : 0 : q->last_coal_idx = 0;
1994 : 0 : q->last_pidx = 0;
1995 : 0 : q->stat = (void *)&q->desc[q->size];
1996 : 0 : }
1997 : :
1998 : 0 : int t4_sge_eth_txq_start(struct sge_eth_txq *txq)
1999 : : {
2000 : : /*
2001 : : * TODO: For flow-control, queue may be stopped waiting to reclaim
2002 : : * credits.
2003 : : * Ensure queue is in EQ_STOPPED state before starting it.
2004 : : */
2005 [ # # ]: 0 : if (!(txq->flags & EQ_STOPPED))
2006 : : return -(EBUSY);
2007 : :
2008 : 0 : txq->flags &= ~EQ_STOPPED;
2009 : :
2010 : 0 : return 0;
2011 : : }
2012 : :
2013 : 0 : int t4_sge_eth_txq_stop(struct sge_eth_txq *txq)
2014 : : {
2015 : 0 : txq->flags |= EQ_STOPPED;
2016 : :
2017 : 0 : return 0;
2018 : : }
2019 : :
2020 : 0 : int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
2021 : : struct rte_eth_dev *eth_dev, uint16_t queue_id,
2022 : : unsigned int iqid, int socket_id)
2023 : : {
2024 : : int ret, nentries;
2025 : : struct fw_eq_eth_cmd c;
2026 : : struct sge *s = &adap->sge;
2027 : 0 : struct port_info *pi = eth_dev->data->dev_private;
2028 : : u8 pciechan;
2029 : :
2030 : : /* Add status entries */
2031 : 0 : nentries = txq->q.size + s->stat_len / sizeof(struct tx_desc);
2032 : :
2033 : 0 : txq->q.desc = alloc_ring(eth_dev, "tx_ring", queue_id, socket_id,
2034 : : txq->q.size, sizeof(struct tx_desc),
2035 : : s->stat_len, sizeof(struct tx_sw_desc),
2036 : 0 : &txq->q.phys_addr, &txq->q.sdesc);
2037 [ # # ]: 0 : if (!txq->q.desc)
2038 : : return -ENOMEM;
2039 : :
2040 : : memset(&c, 0, sizeof(c));
2041 [ # # ]: 0 : c.op_to_vfn = htonl(V_FW_CMD_OP(FW_EQ_ETH_CMD) | F_FW_CMD_REQUEST |
2042 : : F_FW_CMD_WRITE | F_FW_CMD_EXEC);
2043 [ # # ]: 0 : if (is_pf4(adap)) {
2044 : 0 : pciechan = pi->tx_chan;
2045 : 0 : c.op_to_vfn |= htonl(V_FW_EQ_ETH_CMD_PFN(adap->pf) |
2046 : : V_FW_EQ_ETH_CMD_VFN(0));
2047 : : } else {
2048 : 0 : pciechan = pi->port_id;
2049 : : }
2050 : :
2051 : 0 : c.alloc_to_len16 = htonl(F_FW_EQ_ETH_CMD_ALLOC |
2052 : : F_FW_EQ_ETH_CMD_EQSTART | (sizeof(c) / 16));
2053 [ # # ]: 0 : c.autoequiqe_to_viid = htonl(F_FW_EQ_ETH_CMD_AUTOEQUEQE |
2054 : : V_FW_EQ_ETH_CMD_VIID(pi->viid));
2055 : 0 : c.fetchszm_to_iqid =
2056 : 0 : htonl(V_FW_EQ_ETH_CMD_HOSTFCMODE(X_HOSTFCMODE_NONE) |
2057 : : V_FW_EQ_ETH_CMD_PCIECHN(pciechan) |
2058 : : F_FW_EQ_ETH_CMD_FETCHRO | V_FW_EQ_ETH_CMD_IQID(iqid));
2059 : 0 : c.dcaen_to_eqsize =
2060 : 0 : htonl(V_FW_EQ_ETH_CMD_FBMIN(X_FETCHBURSTMIN_64B) |
2061 : : V_FW_EQ_ETH_CMD_FBMAX(X_FETCHBURSTMAX_512B) |
2062 : : V_FW_EQ_ETH_CMD_EQSIZE(nentries));
2063 [ # # ]: 0 : c.eqaddr = rte_cpu_to_be_64(txq->q.phys_addr);
2064 : :
2065 [ # # ]: 0 : if (is_pf4(adap))
2066 : 0 : ret = t4_wr_mbox(adap, adap->mbox, &c, sizeof(c), &c);
2067 : : else
2068 : : ret = t4vf_wr_mbox(adap, &c, sizeof(c), &c);
2069 [ # # ]: 0 : if (ret) {
2070 : 0 : rte_free(txq->q.sdesc);
2071 : 0 : txq->q.sdesc = NULL;
2072 : 0 : txq->q.desc = NULL;
2073 : 0 : return ret;
2074 : : }
2075 : :
2076 : 0 : init_txq(adap, &txq->q, G_FW_EQ_ETH_CMD_EQID(ntohl(c.eqid_pkd)),
2077 : 0 : G_FW_EQ_ETH_CMD_PHYSEQID(ntohl(c.physeqid_pkd)));
2078 : 0 : txq->stats.tso = 0;
2079 : 0 : txq->stats.pkts = 0;
2080 : 0 : txq->stats.tx_cso = 0;
2081 : 0 : txq->stats.coal_wr = 0;
2082 : 0 : txq->stats.vlan_ins = 0;
2083 : 0 : txq->stats.tx_bytes = 0;
2084 : 0 : txq->stats.coal_pkts = 0;
2085 : 0 : txq->stats.mapping_err = 0;
2086 : 0 : txq->flags |= EQ_STOPPED;
2087 : 0 : txq->eth_dev = eth_dev;
2088 : 0 : txq->data = eth_dev->data;
2089 : : t4_os_lock_init(&txq->txq_lock);
2090 : 0 : return 0;
2091 : : }
2092 : :
2093 : 0 : int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq,
2094 : : struct rte_eth_dev *eth_dev, uint16_t queue_id,
2095 : : unsigned int iqid, int socket_id)
2096 : : {
2097 : : int ret, nentries;
2098 : : struct fw_eq_ctrl_cmd c;
2099 : : struct sge *s = &adap->sge;
2100 : 0 : struct port_info *pi = eth_dev->data->dev_private;
2101 : :
2102 : : /* Add status entries */
2103 : 0 : nentries = txq->q.size + s->stat_len / sizeof(struct tx_desc);
2104 : :
2105 : 0 : txq->q.desc = alloc_ring(eth_dev, "ctrl_tx_ring", queue_id,
2106 : : socket_id, txq->q.size, sizeof(struct tx_desc),
2107 : 0 : 0, 0, &txq->q.phys_addr, NULL);
2108 [ # # ]: 0 : if (!txq->q.desc)
2109 : : return -ENOMEM;
2110 : :
2111 : : memset(&c, 0, sizeof(c));
2112 [ # # ]: 0 : c.op_to_vfn = htonl(V_FW_CMD_OP(FW_EQ_CTRL_CMD) | F_FW_CMD_REQUEST |
2113 : : F_FW_CMD_WRITE | F_FW_CMD_EXEC |
2114 : : V_FW_EQ_CTRL_CMD_PFN(adap->pf) |
2115 : : V_FW_EQ_CTRL_CMD_VFN(0));
2116 : 0 : c.alloc_to_len16 = htonl(F_FW_EQ_CTRL_CMD_ALLOC |
2117 : : F_FW_EQ_CTRL_CMD_EQSTART | (sizeof(c) / 16));
2118 : : c.cmpliqid_eqid = htonl(V_FW_EQ_CTRL_CMD_CMPLIQID(0));
2119 : : c.physeqid_pkd = htonl(0);
2120 : 0 : c.fetchszm_to_iqid =
2121 : 0 : htonl(V_FW_EQ_CTRL_CMD_HOSTFCMODE(X_HOSTFCMODE_NONE) |
2122 : : V_FW_EQ_CTRL_CMD_PCIECHN(pi->tx_chan) |
2123 : : F_FW_EQ_CTRL_CMD_FETCHRO | V_FW_EQ_CTRL_CMD_IQID(iqid));
2124 : 0 : c.dcaen_to_eqsize =
2125 : 0 : htonl(V_FW_EQ_CTRL_CMD_FBMIN(X_FETCHBURSTMIN_64B) |
2126 : : V_FW_EQ_CTRL_CMD_FBMAX(X_FETCHBURSTMAX_512B) |
2127 : : V_FW_EQ_CTRL_CMD_EQSIZE(nentries));
2128 [ # # ]: 0 : c.eqaddr = cpu_to_be64(txq->q.phys_addr);
2129 : :
2130 : 0 : ret = t4_wr_mbox(adap, adap->mbox, &c, sizeof(c), &c);
2131 [ # # ]: 0 : if (ret) {
2132 : 0 : txq->q.desc = NULL;
2133 : 0 : return ret;
2134 : : }
2135 : :
2136 : 0 : init_txq(adap, &txq->q, G_FW_EQ_CTRL_CMD_EQID(ntohl(c.cmpliqid_eqid)),
2137 : 0 : G_FW_EQ_CTRL_CMD_EQID(ntohl(c. physeqid_pkd)));
2138 : 0 : txq->adapter = adap;
2139 : 0 : txq->full = 0;
2140 : 0 : return 0;
2141 : : }
2142 : :
2143 : : static void free_txq(struct sge_txq *q)
2144 : : {
2145 : 0 : q->cntxt_id = 0;
2146 : 0 : q->sdesc = NULL;
2147 : 0 : q->desc = NULL;
2148 : 0 : }
2149 : :
2150 : 0 : static void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq,
2151 : : struct sge_fl *fl)
2152 : : {
2153 [ # # ]: 0 : unsigned int fl_id = fl ? fl->cntxt_id : 0xffff;
2154 : :
2155 : 0 : t4_iq_free(adap, adap->mbox, adap->pf, 0, FW_IQ_TYPE_FL_INT_CAP,
2156 : 0 : rq->cntxt_id, fl_id, 0xffff);
2157 : 0 : rq->cntxt_id = 0;
2158 : 0 : rq->abs_id = 0;
2159 : 0 : rq->desc = NULL;
2160 : :
2161 [ # # ]: 0 : if (fl) {
2162 : 0 : free_rx_bufs(fl, fl->avail);
2163 : 0 : rte_free(fl->sdesc);
2164 : 0 : fl->sdesc = NULL;
2165 : 0 : fl->cntxt_id = 0;
2166 : 0 : fl->desc = NULL;
2167 : : }
2168 : 0 : }
2169 : :
2170 : : /*
2171 : : * Clear all queues of the port
2172 : : *
2173 : : * Note: This function must only be called after rx and tx path
2174 : : * of the port have been disabled.
2175 : : */
2176 : 0 : void t4_sge_eth_clear_queues(struct port_info *pi)
2177 : : {
2178 : 0 : struct adapter *adap = pi->adapter;
2179 : : struct sge_eth_rxq *rxq;
2180 : : struct sge_eth_txq *txq;
2181 : : int i;
2182 : :
2183 : 0 : rxq = &adap->sge.ethrxq[pi->first_rxqset];
2184 [ # # ]: 0 : for (i = 0; i < pi->n_rx_qsets; i++, rxq++) {
2185 [ # # ]: 0 : if (rxq->rspq.desc)
2186 : 0 : t4_sge_eth_rxq_stop(adap, rxq);
2187 : : }
2188 : :
2189 : 0 : txq = &adap->sge.ethtxq[pi->first_txqset];
2190 [ # # ]: 0 : for (i = 0; i < pi->n_tx_qsets; i++, txq++) {
2191 [ # # ]: 0 : if (txq->q.desc) {
2192 : 0 : struct sge_txq *q = &txq->q;
2193 : :
2194 : 0 : t4_sge_eth_txq_stop(txq);
2195 : 0 : reclaim_completed_tx(q);
2196 : 0 : free_tx_desc(q, q->size);
2197 : 0 : q->equeidx = q->pidx;
2198 : : }
2199 : : }
2200 : 0 : }
2201 : :
2202 : 0 : void t4_sge_eth_rxq_release(struct adapter *adap, struct sge_eth_rxq *rxq)
2203 : : {
2204 [ # # ]: 0 : if (rxq->rspq.desc) {
2205 : 0 : t4_sge_eth_rxq_stop(adap, rxq);
2206 [ # # ]: 0 : free_rspq_fl(adap, &rxq->rspq, rxq->fl.size ? &rxq->fl : NULL);
2207 : : }
2208 : 0 : }
2209 : :
2210 : 0 : void t4_sge_eth_txq_release(struct adapter *adap, struct sge_eth_txq *txq)
2211 : : {
2212 [ # # ]: 0 : if (txq->q.desc) {
2213 : 0 : t4_sge_eth_txq_stop(txq);
2214 : 0 : reclaim_completed_tx(&txq->q);
2215 : 0 : t4_eth_eq_free(adap, adap->mbox, adap->pf, 0, txq->q.cntxt_id);
2216 : 0 : free_tx_desc(&txq->q, txq->q.size);
2217 : 0 : rte_free(txq->q.sdesc);
2218 : : free_txq(&txq->q);
2219 : : }
2220 : 0 : }
2221 : :
2222 : 0 : void t4_sge_eth_release_queues(struct port_info *pi)
2223 : : {
2224 : 0 : struct adapter *adap = pi->adapter;
2225 : : struct sge_eth_rxq *rxq;
2226 : : struct sge_eth_txq *txq;
2227 : : unsigned int i;
2228 : :
2229 : 0 : rxq = &adap->sge.ethrxq[pi->first_rxqset];
2230 : : /* clean up Ethernet Tx/Rx queues */
2231 [ # # ]: 0 : for (i = 0; i < pi->n_rx_qsets; i++, rxq++) {
2232 : : /* Free only the queues allocated */
2233 [ # # ]: 0 : if (rxq->rspq.desc) {
2234 : 0 : t4_sge_eth_rxq_release(adap, rxq);
2235 : 0 : rte_eth_dma_zone_free(rxq->rspq.eth_dev, "fl_ring", i);
2236 : 0 : rte_eth_dma_zone_free(rxq->rspq.eth_dev, "rx_ring", i);
2237 : 0 : rxq->rspq.eth_dev = NULL;
2238 : : }
2239 : : }
2240 : :
2241 : 0 : txq = &adap->sge.ethtxq[pi->first_txqset];
2242 [ # # ]: 0 : for (i = 0; i < pi->n_tx_qsets; i++, txq++) {
2243 : : /* Free only the queues allocated */
2244 [ # # ]: 0 : if (txq->q.desc) {
2245 : 0 : t4_sge_eth_txq_release(adap, txq);
2246 : 0 : rte_eth_dma_zone_free(txq->eth_dev, "tx_ring", i);
2247 : 0 : txq->eth_dev = NULL;
2248 : : }
2249 : : }
2250 : 0 : }
2251 : :
2252 : 0 : void t4_sge_tx_monitor_start(struct adapter *adap)
2253 : : {
2254 : 0 : rte_eal_alarm_set(50, tx_timer_cb, (void *)adap);
2255 : 0 : }
2256 : :
2257 : 0 : void t4_sge_tx_monitor_stop(struct adapter *adap)
2258 : : {
2259 : 0 : rte_eal_alarm_cancel(tx_timer_cb, (void *)adap);
2260 : 0 : }
2261 : :
2262 : : /**
2263 : : * t4_free_sge_resources - free SGE resources
2264 : : * @adap: the adapter
2265 : : *
2266 : : * Frees resources used by the SGE queue sets.
2267 : : */
2268 : 0 : void t4_free_sge_resources(struct adapter *adap)
2269 : : {
2270 : : unsigned int i;
2271 : :
2272 : : /* clean up control Tx queues */
2273 [ # # ]: 0 : for (i = 0; i < ARRAY_SIZE(adap->sge.ctrlq); i++) {
2274 : : struct sge_ctrl_txq *cq = &adap->sge.ctrlq[i];
2275 : :
2276 [ # # ]: 0 : if (cq->q.desc) {
2277 : : reclaim_completed_tx_imm(&cq->q);
2278 : 0 : t4_ctrl_eq_free(adap, adap->mbox, adap->pf, 0,
2279 : : cq->q.cntxt_id);
2280 : 0 : rte_eth_dma_zone_free(adap->eth_dev, "ctrl_tx_ring", i);
2281 : 0 : rte_mempool_free(cq->mb_pool);
2282 : : free_txq(&cq->q);
2283 : : }
2284 : : }
2285 : :
2286 : : /* clean up firmware event queue */
2287 [ # # ]: 0 : if (adap->sge.fw_evtq.desc) {
2288 : 0 : free_rspq_fl(adap, &adap->sge.fw_evtq, NULL);
2289 : 0 : rte_eth_dma_zone_free(adap->eth_dev, "fwq_ring", 0);
2290 : : }
2291 : 0 : }
2292 : :
2293 : : /**
2294 : : * t4_sge_init - initialize SGE
2295 : : * @adap: the adapter
2296 : : *
2297 : : * Performs SGE initialization needed every time after a chip reset.
2298 : : * We do not initialize any of the queues here, instead the driver
2299 : : * top-level must request those individually.
2300 : : *
2301 : : * Called in two different modes:
2302 : : *
2303 : : * 1. Perform actual hardware initialization and record hard-coded
2304 : : * parameters which were used. This gets used when we're the
2305 : : * Master PF and the Firmware Configuration File support didn't
2306 : : * work for some reason.
2307 : : *
2308 : : * 2. We're not the Master PF or initialization was performed with
2309 : : * a Firmware Configuration File. In this case we need to grab
2310 : : * any of the SGE operating parameters that we need to have in
2311 : : * order to do our job and make sure we can live with them ...
2312 : : */
2313 : 0 : static int t4_sge_init_soft(struct adapter *adap)
2314 : : {
2315 : : u32 timer_value_0_and_1, timer_value_2_and_3, timer_value_4_and_5;
2316 : : struct sge *s = &adap->sge;
2317 : : u32 ingress_rx_threshold;
2318 : : u8 i;
2319 : :
2320 : : /*
2321 : : * Verify that CPL messages are going to the Ingress Queue for
2322 : : * process_responses() and that only packet data is going to the
2323 : : * Free Lists.
2324 : : */
2325 [ # # ]: 0 : if ((t4_read_reg(adap, A_SGE_CONTROL) & F_RXPKTCPLMODE) !=
2326 : : V_RXPKTCPLMODE(X_RXPKTCPLMODE_SPLIT)) {
2327 : 0 : dev_err(adap, "bad SGE CPL MODE\n");
2328 : 0 : return -EINVAL;
2329 : : }
2330 : :
2331 : : /*
2332 : : * Read the Host Buffer Register Array indices that we want to
2333 : : * use ...
2334 : : */
2335 [ # # ]: 0 : for (i = 0; i < RTE_DIM(s->fl_buffer_size); i++)
2336 : 0 : s->fl_buffer_size[i] = t4_read_reg(adap,
2337 : 0 : A_SGE_FL_BUFFER_SIZE0 +
2338 : : i * sizeof(u32));
2339 : :
2340 : : /*
2341 : : * Retrieve our RX interrupt holdoff timer values and counter
2342 : : * threshold values from the SGE parameters.
2343 : : */
2344 : : timer_value_0_and_1 = t4_read_reg(adap, A_SGE_TIMER_VALUE_0_AND_1);
2345 : : timer_value_2_and_3 = t4_read_reg(adap, A_SGE_TIMER_VALUE_2_AND_3);
2346 : : timer_value_4_and_5 = t4_read_reg(adap, A_SGE_TIMER_VALUE_4_AND_5);
2347 : 0 : s->timer_val[0] = core_ticks_to_us(adap,
2348 : : G_TIMERVALUE0(timer_value_0_and_1));
2349 : 0 : s->timer_val[1] = core_ticks_to_us(adap,
2350 : : G_TIMERVALUE1(timer_value_0_and_1));
2351 : 0 : s->timer_val[2] = core_ticks_to_us(adap,
2352 : : G_TIMERVALUE2(timer_value_2_and_3));
2353 : 0 : s->timer_val[3] = core_ticks_to_us(adap,
2354 : : G_TIMERVALUE3(timer_value_2_and_3));
2355 : 0 : s->timer_val[4] = core_ticks_to_us(adap,
2356 : : G_TIMERVALUE4(timer_value_4_and_5));
2357 : 0 : s->timer_val[5] = core_ticks_to_us(adap,
2358 : : G_TIMERVALUE5(timer_value_4_and_5));
2359 : :
2360 : : ingress_rx_threshold = t4_read_reg(adap, A_SGE_INGRESS_RX_THRESHOLD);
2361 : 0 : s->counter_val[0] = G_THRESHOLD_0(ingress_rx_threshold);
2362 : 0 : s->counter_val[1] = G_THRESHOLD_1(ingress_rx_threshold);
2363 : 0 : s->counter_val[2] = G_THRESHOLD_2(ingress_rx_threshold);
2364 : 0 : s->counter_val[3] = G_THRESHOLD_3(ingress_rx_threshold);
2365 : :
2366 : 0 : return 0;
2367 : : }
2368 : :
2369 : 0 : int t4_sge_init(struct adapter *adap)
2370 : : {
2371 : : struct sge *s = &adap->sge;
2372 : : u32 sge_control, sge_conm_ctrl;
2373 : : int ret, egress_threshold;
2374 : :
2375 : : /*
2376 : : * Ingress Padding Boundary and Egress Status Page Size are set up by
2377 : : * t4_fixup_host_params().
2378 : : */
2379 : : sge_control = t4_read_reg(adap, A_SGE_CONTROL);
2380 : 0 : s->pktshift = G_PKTSHIFT(sge_control);
2381 [ # # ]: 0 : s->stat_len = (sge_control & F_EGRSTATUSPAGESIZE) ? 128 : 64;
2382 : 0 : ret = t4_sge_init_soft(adap);
2383 [ # # ]: 0 : if (ret < 0) {
2384 : 0 : dev_err(adap, "%s: t4_sge_init_soft failed, error %d\n",
2385 : : __func__, -ret);
2386 : 0 : return ret;
2387 : : }
2388 : :
2389 : : /*
2390 : : * A FL with <= fl_starve_thres buffers is starving and a periodic
2391 : : * timer will attempt to refill it. This needs to be larger than the
2392 : : * SGE's Egress Congestion Threshold. If it isn't, then we can get
2393 : : * stuck waiting for new packets while the SGE is waiting for us to
2394 : : * give it more Free List entries. (Note that the SGE's Egress
2395 : : * Congestion Threshold is in units of 2 Free List pointers.) For T4,
2396 : : * there was only a single field to control this. For T5 there's the
2397 : : * original field which now only applies to Unpacked Mode Free List
2398 : : * buffers and a new field which only applies to Packed Mode Free List
2399 : : * buffers.
2400 : : */
2401 : : sge_conm_ctrl = t4_read_reg(adap, A_SGE_CONM_CTRL);
2402 [ # # # # ]: 0 : if (is_t4(adap->params.chip) || adap->use_unpacked_mode)
2403 : 0 : egress_threshold = G_EGRTHRESHOLD(sge_conm_ctrl);
2404 : : else
2405 : 0 : egress_threshold = G_EGRTHRESHOLDPACKING(sge_conm_ctrl);
2406 : 0 : s->fl_starve_thres = 2 * egress_threshold + 1;
2407 : :
2408 : 0 : return 0;
2409 : : }
2410 : :
2411 : 0 : int t4vf_sge_init(struct adapter *adap)
2412 : : {
2413 : : struct sge_params *sge_params = &adap->params.sge;
2414 : : u32 sge_ingress_queues_per_page;
2415 : : u32 sge_egress_queues_per_page;
2416 : : u32 sge_ingress_rx_threshold;
2417 : : u32 sge_timer_value_0_and_1;
2418 : : u32 sge_timer_value_2_and_3;
2419 : : u32 sge_timer_value_4_and_5;
2420 : : u32 sge_congestion_control;
2421 : : struct sge *s = &adap->sge;
2422 : : unsigned int s_hps, s_qpp;
2423 : : u32 sge_host_page_size;
2424 : : u32 params[7], vals[7];
2425 : : u32 sge_control;
2426 : : int v;
2427 : : u8 i;
2428 : :
2429 : : /* query basic params from fw */
2430 : 0 : params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
2431 : : V_FW_PARAMS_PARAM_XYZ(A_SGE_CONTROL));
2432 : 0 : params[1] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
2433 : : V_FW_PARAMS_PARAM_XYZ(A_SGE_HOST_PAGE_SIZE));
2434 : 0 : params[2] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
2435 : : V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_0_AND_1));
2436 : 0 : params[3] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
2437 : : V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_2_AND_3));
2438 : 0 : params[4] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
2439 : : V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_4_AND_5));
2440 : 0 : v = t4vf_query_params(adap, 7, params, vals);
2441 [ # # ]: 0 : if (v != FW_SUCCESS)
2442 : : return v;
2443 : :
2444 : 0 : sge_control = vals[0];
2445 : 0 : sge_host_page_size = vals[1];
2446 : 0 : sge_timer_value_0_and_1 = vals[2];
2447 : 0 : sge_timer_value_2_and_3 = vals[3];
2448 : 0 : sge_timer_value_4_and_5 = vals[4];
2449 : :
2450 [ # # ]: 0 : for (i = 0; i < RTE_DIM(s->fl_buffer_size); i++) {
2451 : 0 : params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
2452 : 0 : V_FW_PARAMS_PARAM_XYZ(A_SGE_FL_BUFFER_SIZE0 +
2453 : : i * sizeof(u32)));
2454 : 0 : v = t4vf_query_params(adap, 1, params, vals);
2455 [ # # ]: 0 : if (v != FW_SUCCESS)
2456 : 0 : return v;
2457 : :
2458 : 0 : s->fl_buffer_size[i] = vals[0];
2459 : : }
2460 : :
2461 : : /*
2462 : : * Start by vetting the basic SGE parameters which have been set up by
2463 : : * the Physical Function Driver.
2464 : : */
2465 : :
2466 [ # # ]: 0 : if ((sge_control & F_RXPKTCPLMODE) !=
2467 : : V_RXPKTCPLMODE(X_RXPKTCPLMODE_SPLIT)) {
2468 : 0 : dev_err(adapter->pdev_dev, "bad SGE CPL MODE\n");
2469 : 0 : return -EINVAL;
2470 : : }
2471 : :
2472 : 0 : params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
2473 : : V_FW_PARAMS_PARAM_XYZ(A_SGE_INGRESS_RX_THRESHOLD));
2474 : 0 : params[1] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
2475 : : V_FW_PARAMS_PARAM_XYZ(A_SGE_CONM_CTRL));
2476 : 0 : v = t4vf_query_params(adap, 2, params, vals);
2477 [ # # ]: 0 : if (v != FW_SUCCESS)
2478 : : return v;
2479 : 0 : sge_ingress_rx_threshold = vals[0];
2480 : 0 : sge_congestion_control = vals[1];
2481 : 0 : params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
2482 : : V_FW_PARAMS_PARAM_XYZ(A_SGE_EGRESS_QUEUES_PER_PAGE_VF));
2483 : 0 : params[1] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
2484 : : V_FW_PARAMS_PARAM_XYZ(A_SGE_INGRESS_QUEUES_PER_PAGE_VF));
2485 : 0 : v = t4vf_query_params(adap, 2, params, vals);
2486 [ # # ]: 0 : if (v != FW_SUCCESS) {
2487 : 0 : dev_warn(adap, "Unable to get VF SGE Queues/Page; "
2488 : : "probably old firmware.\n");
2489 : 0 : return v;
2490 : : }
2491 : 0 : sge_egress_queues_per_page = vals[0];
2492 : 0 : sge_ingress_queues_per_page = vals[1];
2493 : :
2494 : : /*
2495 : : * We need the Queues/Page for our VF. This is based on the
2496 : : * PF from which we're instantiated and is indexed in the
2497 : : * register we just read.
2498 : : */
2499 : 0 : s_hps = (S_HOSTPAGESIZEPF0 +
2500 : 0 : (S_HOSTPAGESIZEPF1 - S_HOSTPAGESIZEPF0) * adap->pf);
2501 : 0 : sge_params->hps =
2502 : 0 : ((sge_host_page_size >> s_hps) & M_HOSTPAGESIZEPF0);
2503 : :
2504 : : s_qpp = (S_QUEUESPERPAGEPF0 +
2505 : : (S_QUEUESPERPAGEPF1 - S_QUEUESPERPAGEPF0) * adap->pf);
2506 : 0 : sge_params->eq_qpp =
2507 : 0 : ((sge_egress_queues_per_page >> s_qpp)
2508 : 0 : & M_QUEUESPERPAGEPF0);
2509 : 0 : sge_params->iq_qpp =
2510 : 0 : ((sge_ingress_queues_per_page >> s_qpp)
2511 : 0 : & M_QUEUESPERPAGEPF0);
2512 : :
2513 : : /*
2514 : : * Now translate the queried parameters into our internal forms.
2515 : : */
2516 : 0 : s->stat_len = ((sge_control & F_EGRSTATUSPAGESIZE)
2517 [ # # ]: 0 : ? 128 : 64);
2518 : 0 : s->pktshift = G_PKTSHIFT(sge_control);
2519 : :
2520 : : /*
2521 : : * A FL with <= fl_starve_thres buffers is starving and a periodic
2522 : : * timer will attempt to refill it. This needs to be larger than the
2523 : : * SGE's Egress Congestion Threshold. If it isn't, then we can get
2524 : : * stuck waiting for new packets while the SGE is waiting for us to
2525 : : * give it more Free List entries. (Note that the SGE's Egress
2526 : : * Congestion Threshold is in units of 2 Free List pointers.)
2527 : : */
2528 [ # # ]: 0 : switch (CHELSIO_CHIP_VERSION(adap->params.chip)) {
2529 : 0 : case CHELSIO_T5:
2530 : 0 : s->fl_starve_thres =
2531 : 0 : G_EGRTHRESHOLDPACKING(sge_congestion_control);
2532 : 0 : break;
2533 : 0 : case CHELSIO_T6:
2534 : : default:
2535 : 0 : s->fl_starve_thres =
2536 : 0 : G_T6_EGRTHRESHOLDPACKING(sge_congestion_control);
2537 : 0 : break;
2538 : : }
2539 : 0 : s->fl_starve_thres = s->fl_starve_thres * 2 + 1;
2540 : :
2541 : : /*
2542 : : * Save RX interrupt holdoff timer values and counter
2543 : : * threshold values from the SGE parameters.
2544 : : */
2545 : 0 : s->timer_val[0] = core_ticks_to_us(adap,
2546 : : G_TIMERVALUE0(sge_timer_value_0_and_1));
2547 : 0 : s->timer_val[1] = core_ticks_to_us(adap,
2548 : : G_TIMERVALUE1(sge_timer_value_0_and_1));
2549 : 0 : s->timer_val[2] = core_ticks_to_us(adap,
2550 : : G_TIMERVALUE2(sge_timer_value_2_and_3));
2551 : 0 : s->timer_val[3] = core_ticks_to_us(adap,
2552 : : G_TIMERVALUE3(sge_timer_value_2_and_3));
2553 : 0 : s->timer_val[4] = core_ticks_to_us(adap,
2554 : : G_TIMERVALUE4(sge_timer_value_4_and_5));
2555 : 0 : s->timer_val[5] = core_ticks_to_us(adap,
2556 : : G_TIMERVALUE5(sge_timer_value_4_and_5));
2557 : 0 : s->counter_val[0] = G_THRESHOLD_0(sge_ingress_rx_threshold);
2558 : 0 : s->counter_val[1] = G_THRESHOLD_1(sge_ingress_rx_threshold);
2559 : 0 : s->counter_val[2] = G_THRESHOLD_2(sge_ingress_rx_threshold);
2560 : 0 : s->counter_val[3] = G_THRESHOLD_3(sge_ingress_rx_threshold);
2561 : 0 : return 0;
2562 : : }
|