1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
3 #include <linux/dma-mapping.h>
6 #include <linux/skbuff.h>
8 #include <uapi/linux/udp.h>
10 #include "funeth_ktls.h"
11 #include "funeth_txrx.h"
12 #include "funeth_trace.h"
13 #include "fun_queue.h"
15 #define FUN_XDP_CLEAN_THRES 32
16 #define FUN_XDP_CLEAN_BATCH 16
18 /* DMA-map a packet and return the (length, DMA_address) pairs for its
19 * segments. If a mapping error occurs -ENOMEM is returned. The packet
20 * consists of an skb_shared_info and one additional address/length pair.
22 static int fun_map_pkt(struct device
*dev
, const struct skb_shared_info
*si
,
23 void *data
, unsigned int data_len
,
24 dma_addr_t
*addr
, unsigned int *len
)
26 const skb_frag_t
*fp
, *end
;
29 *addr
= dma_map_single(dev
, data
, *len
, DMA_TO_DEVICE
);
30 if (dma_mapping_error(dev
, *addr
))
36 for (fp
= si
->frags
, end
= fp
+ si
->nr_frags
; fp
< end
; fp
++) {
37 *++len
= skb_frag_size(fp
);
38 *++addr
= skb_frag_dma_map(dev
, fp
, 0, *len
, DMA_TO_DEVICE
);
39 if (dma_mapping_error(dev
, *addr
))
45 while (fp
-- > si
->frags
)
46 dma_unmap_page(dev
, *--addr
, skb_frag_size(fp
), DMA_TO_DEVICE
);
48 dma_unmap_single(dev
, addr
[-1], data_len
, DMA_TO_DEVICE
);
52 /* Return the address just past the end of a Tx queue's descriptor ring.
53 * It exploits the fact that the HW writeback area is just after the end
54 * of the descriptor ring.
56 static void *txq_end(const struct funeth_txq
*q
)
58 return (void *)q
->hw_wb
;
61 /* Return the amount of space within a Tx ring from the given address to the
64 static unsigned int txq_to_end(const struct funeth_txq
*q
, void *p
)
66 return txq_end(q
) - p
;
69 /* Return the number of Tx descriptors occupied by a Tx request. */
70 static unsigned int tx_req_ndesc(const struct fun_eth_tx_req
*req
)
72 return DIV_ROUND_UP(req
->len8
, FUNETH_SQE_SIZE
/ 8);
75 /* Write a gather list to the Tx descriptor at @req from @ngle address/length
78 static struct fun_dataop_gl
*fun_write_gl(const struct funeth_txq
*q
,
79 struct fun_eth_tx_req
*req
,
80 const dma_addr_t
*addrs
,
81 const unsigned int *lens
,
84 struct fun_dataop_gl
*gle
;
87 req
->len8
= (sizeof(*req
) + ngle
* sizeof(*gle
)) / 8;
89 for (i
= 0, gle
= (struct fun_dataop_gl
*)req
->dataop
.imm
;
90 i
< ngle
&& txq_to_end(q
, gle
); i
++, gle
++)
91 fun_dataop_gl_init(gle
, 0, 0, lens
[i
], addrs
[i
]);
93 if (txq_to_end(q
, gle
) == 0) {
94 gle
= (struct fun_dataop_gl
*)q
->desc
;
95 for ( ; i
< ngle
; i
++, gle
++)
96 fun_dataop_gl_init(gle
, 0, 0, lens
[i
], addrs
[i
]);
102 static __be16
tcp_hdr_doff_flags(const struct tcphdr
*th
)
104 return *(__be16
*)&tcp_flag_word(th
);
107 static struct sk_buff
*fun_tls_tx(struct sk_buff
*skb
, struct funeth_txq
*q
,
108 unsigned int *tls_len
)
110 #if IS_ENABLED(CONFIG_TLS_DEVICE)
111 const struct fun_ktls_tx_ctx
*tls_ctx
;
114 datalen
= skb
->len
- skb_tcp_all_headers(skb
);
118 if (likely(!tls_offload_tx_resync_pending(skb
->sk
))) {
119 seq
= ntohl(tcp_hdr(skb
)->seq
);
120 tls_ctx
= tls_driver_ctx(skb
->sk
, TLS_OFFLOAD_CTX_DIR_TX
);
122 if (likely(tls_ctx
->next_seq
== seq
)) {
126 if (seq
- tls_ctx
->next_seq
< U32_MAX
/ 4) {
127 tls_offload_tx_resync_request(skb
->sk
, seq
,
132 FUN_QSTAT_INC(q
, tx_tls_fallback
);
133 skb
= tls_encrypt_skb(skb
);
135 FUN_QSTAT_INC(q
, tx_tls_drops
);
143 /* Write as many descriptors as needed for the supplied skb starting at the
144 * current producer location. The caller has made certain enough descriptors
147 * Returns the number of descriptors written, 0 on error.
149 static unsigned int write_pkt_desc(struct sk_buff
*skb
, struct funeth_txq
*q
,
150 unsigned int tls_len
)
152 unsigned int extra_bytes
= 0, extra_pkts
= 0;
153 unsigned int idx
= q
->prod_cnt
& q
->mask
;
154 const struct skb_shared_info
*shinfo
;
155 unsigned int lens
[MAX_SKB_FRAGS
+ 1];
156 dma_addr_t addrs
[MAX_SKB_FRAGS
+ 1];
157 struct fun_eth_tx_req
*req
;
158 struct fun_dataop_gl
*gle
;
159 const struct tcphdr
*th
;
160 unsigned int l4_hlen
;
164 shinfo
= skb_shinfo(skb
);
165 if (unlikely(fun_map_pkt(q
->dma_dev
, shinfo
, skb
->data
,
166 skb_headlen(skb
), addrs
, lens
))) {
167 FUN_QSTAT_INC(q
, tx_map_err
);
171 req
= fun_tx_desc_addr(q
, idx
);
172 req
->op
= FUN_ETH_OP_TX
;
175 req
->suboff8
= offsetof(struct fun_eth_tx_req
, dataop
);
177 req
->encap_proto
= 0;
179 if (likely(shinfo
->gso_size
)) {
180 if (skb
->encapsulation
) {
183 flags
= FUN_ETH_OUTER_EN
| FUN_ETH_INNER_LSO
|
184 FUN_ETH_UPDATE_INNER_L4_CKSUM
|
185 FUN_ETH_UPDATE_OUTER_L3_LEN
;
186 if (shinfo
->gso_type
& (SKB_GSO_UDP_TUNNEL
|
187 SKB_GSO_UDP_TUNNEL_CSUM
)) {
188 flags
|= FUN_ETH_UPDATE_OUTER_L4_LEN
|
190 if (shinfo
->gso_type
& SKB_GSO_UDP_TUNNEL_CSUM
)
191 flags
|= FUN_ETH_UPDATE_OUTER_L4_CKSUM
;
192 ol4_ofst
= skb_transport_offset(skb
);
194 ol4_ofst
= skb_inner_network_offset(skb
);
197 if (ip_hdr(skb
)->version
== 4)
198 flags
|= FUN_ETH_UPDATE_OUTER_L3_CKSUM
;
200 flags
|= FUN_ETH_OUTER_IPV6
;
202 if (skb
->inner_network_header
) {
203 if (inner_ip_hdr(skb
)->version
== 4)
204 flags
|= FUN_ETH_UPDATE_INNER_L3_CKSUM
|
205 FUN_ETH_UPDATE_INNER_L3_LEN
;
207 flags
|= FUN_ETH_INNER_IPV6
|
208 FUN_ETH_UPDATE_INNER_L3_LEN
;
210 th
= inner_tcp_hdr(skb
);
211 l4_hlen
= __tcp_hdrlen(th
);
212 fun_eth_offload_init(&req
->offload
, flags
,
214 tcp_hdr_doff_flags(th
), 0,
215 skb_inner_network_offset(skb
),
216 skb_inner_transport_offset(skb
),
217 skb_network_offset(skb
), ol4_ofst
);
218 FUN_QSTAT_INC(q
, tx_encap_tso
);
219 } else if (shinfo
->gso_type
& SKB_GSO_UDP_L4
) {
220 flags
= FUN_ETH_INNER_LSO
| FUN_ETH_INNER_UDP
|
221 FUN_ETH_UPDATE_INNER_L4_CKSUM
|
222 FUN_ETH_UPDATE_INNER_L4_LEN
|
223 FUN_ETH_UPDATE_INNER_L3_LEN
;
225 if (ip_hdr(skb
)->version
== 4)
226 flags
|= FUN_ETH_UPDATE_INNER_L3_CKSUM
;
228 flags
|= FUN_ETH_INNER_IPV6
;
230 l4_hlen
= sizeof(struct udphdr
);
231 fun_eth_offload_init(&req
->offload
, flags
,
233 cpu_to_be16(l4_hlen
<< 10), 0,
234 skb_network_offset(skb
),
235 skb_transport_offset(skb
), 0, 0);
236 FUN_QSTAT_INC(q
, tx_uso
);
238 /* HW considers one set of headers as inner */
239 flags
= FUN_ETH_INNER_LSO
|
240 FUN_ETH_UPDATE_INNER_L4_CKSUM
|
241 FUN_ETH_UPDATE_INNER_L3_LEN
;
242 if (shinfo
->gso_type
& SKB_GSO_TCPV6
)
243 flags
|= FUN_ETH_INNER_IPV6
;
245 flags
|= FUN_ETH_UPDATE_INNER_L3_CKSUM
;
247 l4_hlen
= __tcp_hdrlen(th
);
248 fun_eth_offload_init(&req
->offload
, flags
,
250 tcp_hdr_doff_flags(th
), 0,
251 skb_network_offset(skb
),
252 skb_transport_offset(skb
), 0, 0);
253 FUN_QSTAT_INC(q
, tx_tso
);
256 u64_stats_update_begin(&q
->syncp
);
257 q
->stats
.tx_cso
+= shinfo
->gso_segs
;
258 u64_stats_update_end(&q
->syncp
);
260 extra_pkts
= shinfo
->gso_segs
- 1;
261 extra_bytes
= (be16_to_cpu(req
->offload
.inner_l4_off
) +
262 l4_hlen
) * extra_pkts
;
263 } else if (likely(skb
->ip_summed
== CHECKSUM_PARTIAL
)) {
264 flags
= FUN_ETH_UPDATE_INNER_L4_CKSUM
;
265 if (skb
->csum_offset
== offsetof(struct udphdr
, check
))
266 flags
|= FUN_ETH_INNER_UDP
;
267 fun_eth_offload_init(&req
->offload
, flags
, 0, 0, 0, 0,
268 skb_checksum_start_offset(skb
), 0, 0);
269 FUN_QSTAT_INC(q
, tx_cso
);
271 fun_eth_offload_init(&req
->offload
, 0, 0, 0, 0, 0, 0, 0, 0);
274 ngle
= shinfo
->nr_frags
+ 1;
275 req
->dataop
= FUN_DATAOP_HDR_INIT(ngle
, 0, ngle
, 0, skb
->len
);
277 gle
= fun_write_gl(q
, req
, addrs
, lens
, ngle
);
279 if (IS_ENABLED(CONFIG_TLS_DEVICE
) && unlikely(tls_len
)) {
280 struct fun_eth_tls
*tls
= (struct fun_eth_tls
*)gle
;
281 struct fun_ktls_tx_ctx
*tls_ctx
;
283 req
->len8
+= FUNETH_TLS_SZ
/ 8;
284 req
->flags
= cpu_to_be16(FUN_ETH_TX_TLS
);
286 tls_ctx
= tls_driver_ctx(skb
->sk
, TLS_OFFLOAD_CTX_DIR_TX
);
287 tls
->tlsid
= tls_ctx
->tlsid
;
288 tls_ctx
->next_seq
+= tls_len
;
290 u64_stats_update_begin(&q
->syncp
);
291 q
->stats
.tx_tls_bytes
+= tls_len
;
292 q
->stats
.tx_tls_pkts
+= 1 + extra_pkts
;
293 u64_stats_update_end(&q
->syncp
);
296 u64_stats_update_begin(&q
->syncp
);
297 q
->stats
.tx_bytes
+= skb
->len
+ extra_bytes
;
298 q
->stats
.tx_pkts
+= 1 + extra_pkts
;
299 u64_stats_update_end(&q
->syncp
);
301 q
->info
[idx
].skb
= skb
;
303 trace_funeth_tx(q
, skb
->len
, idx
, req
->dataop
.ngather
);
304 return tx_req_ndesc(req
);
307 /* Return the number of available descriptors of a Tx queue.
308 * HW assumes head==tail means the ring is empty so we need to keep one
311 static unsigned int fun_txq_avail(const struct funeth_txq
*q
)
313 return q
->mask
- q
->prod_cnt
+ q
->cons_cnt
;
316 /* Stop a queue if it can't handle another worst-case packet. */
317 static void fun_tx_check_stop(struct funeth_txq
*q
)
319 if (likely(fun_txq_avail(q
) >= FUNETH_MAX_PKT_DESC
))
322 netif_tx_stop_queue(q
->ndq
);
324 /* NAPI reclaim is freeing packets in parallel with us and we may race.
325 * We have stopped the queue but check again after synchronizing with
329 if (likely(fun_txq_avail(q
) < FUNETH_MAX_PKT_DESC
))
330 FUN_QSTAT_INC(q
, tx_nstops
);
332 netif_tx_start_queue(q
->ndq
);
335 /* Return true if a queue has enough space to restart. Current condition is
336 * that the queue must be >= 1/4 empty.
338 static bool fun_txq_may_restart(struct funeth_txq
*q
)
340 return fun_txq_avail(q
) >= q
->mask
/ 4;
343 netdev_tx_t
fun_start_xmit(struct sk_buff
*skb
, struct net_device
*netdev
)
345 struct funeth_priv
*fp
= netdev_priv(netdev
);
346 unsigned int qid
= skb_get_queue_mapping(skb
);
347 struct funeth_txq
*q
= fp
->txqs
[qid
];
348 unsigned int tls_len
= 0;
351 if (tls_is_skb_tx_device_offloaded(skb
)) {
352 skb
= fun_tls_tx(skb
, q
, &tls_len
);
357 ndesc
= write_pkt_desc(skb
, q
, tls_len
);
358 if (unlikely(!ndesc
)) {
359 dev_kfree_skb_any(skb
);
363 q
->prod_cnt
+= ndesc
;
364 fun_tx_check_stop(q
);
366 skb_tx_timestamp(skb
);
368 if (__netdev_tx_sent_queue(q
->ndq
, skb
->len
, netdev_xmit_more()))
371 FUN_QSTAT_INC(q
, tx_more
);
376 /* A dropped packet may be the last one in a xmit_more train,
377 * ring the doorbell just in case.
379 if (!netdev_xmit_more())
384 /* Return a Tx queue's HW head index written back to host memory. */
385 static u16
txq_hw_head(const struct funeth_txq
*q
)
387 return (u16
)be64_to_cpu(*q
->hw_wb
);
390 /* Unmap the Tx packet starting at the given descriptor index and
391 * return the number of Tx descriptors it occupied.
393 static unsigned int fun_unmap_pkt(const struct funeth_txq
*q
, unsigned int idx
)
395 const struct fun_eth_tx_req
*req
= fun_tx_desc_addr(q
, idx
);
396 unsigned int ngle
= req
->dataop
.ngather
;
397 struct fun_dataop_gl
*gle
;
400 gle
= (struct fun_dataop_gl
*)req
->dataop
.imm
;
401 dma_unmap_single(q
->dma_dev
, be64_to_cpu(gle
->sgl_data
),
402 be32_to_cpu(gle
->sgl_len
), DMA_TO_DEVICE
);
404 for (gle
++; --ngle
&& txq_to_end(q
, gle
); gle
++)
405 dma_unmap_page(q
->dma_dev
, be64_to_cpu(gle
->sgl_data
),
406 be32_to_cpu(gle
->sgl_len
),
409 for (gle
= (struct fun_dataop_gl
*)q
->desc
; ngle
; ngle
--, gle
++)
410 dma_unmap_page(q
->dma_dev
, be64_to_cpu(gle
->sgl_data
),
411 be32_to_cpu(gle
->sgl_len
),
415 return tx_req_ndesc(req
);
418 /* Reclaim completed Tx descriptors and free their packets. Restart a stopped
419 * queue if we freed enough descriptors.
421 * Return true if we exhausted the budget while there is more work to be done.
423 static bool fun_txq_reclaim(struct funeth_txq
*q
, int budget
)
425 unsigned int npkts
= 0, nbytes
= 0, ndesc
= 0;
426 unsigned int head
, limit
, reclaim_idx
;
428 /* budget may be 0, e.g., netpoll */
429 limit
= budget
? budget
: UINT_MAX
;
431 for (head
= txq_hw_head(q
), reclaim_idx
= q
->cons_cnt
& q
->mask
;
432 head
!= reclaim_idx
&& npkts
< limit
; head
= txq_hw_head(q
)) {
433 /* The HW head is continually updated, ensure we don't read
434 * descriptor state before the head tells us to reclaim it.
435 * On the enqueue side the doorbell is an implicit write
441 unsigned int pkt_desc
= fun_unmap_pkt(q
, reclaim_idx
);
442 struct sk_buff
*skb
= q
->info
[reclaim_idx
].skb
;
444 trace_funeth_tx_free(q
, reclaim_idx
, pkt_desc
, head
);
447 napi_consume_skb(skb
, budget
);
449 reclaim_idx
= (reclaim_idx
+ pkt_desc
) & q
->mask
;
451 } while (reclaim_idx
!= head
&& npkts
< limit
);
454 q
->cons_cnt
+= ndesc
;
455 netdev_tx_completed_queue(q
->ndq
, npkts
, nbytes
);
456 smp_mb(); /* pairs with the one in fun_tx_check_stop() */
458 if (unlikely(netif_tx_queue_stopped(q
->ndq
) &&
459 fun_txq_may_restart(q
))) {
460 netif_tx_wake_queue(q
->ndq
);
461 FUN_QSTAT_INC(q
, tx_nrestarts
);
464 return reclaim_idx
!= head
;
467 /* The NAPI handler for Tx queues. */
468 int fun_txq_napi_poll(struct napi_struct
*napi
, int budget
)
470 struct fun_irq
*irq
= container_of(napi
, struct fun_irq
, napi
);
471 struct funeth_txq
*q
= irq
->txq
;
474 if (fun_txq_reclaim(q
, budget
))
475 return budget
; /* exhausted budget */
477 napi_complete(napi
); /* exhausted pending work */
478 db_val
= READ_ONCE(q
->irq_db_val
) | (q
->cons_cnt
& q
->mask
);
479 writel(db_val
, q
->db
);
483 /* Reclaim up to @budget completed Tx packets from a TX XDP queue. */
484 static unsigned int fun_xdpq_clean(struct funeth_txq
*q
, unsigned int budget
)
486 unsigned int npkts
= 0, ndesc
= 0, head
, reclaim_idx
;
488 for (head
= txq_hw_head(q
), reclaim_idx
= q
->cons_cnt
& q
->mask
;
489 head
!= reclaim_idx
&& npkts
< budget
; head
= txq_hw_head(q
)) {
490 /* The HW head is continually updated, ensure we don't read
491 * descriptor state before the head tells us to reclaim it.
492 * On the enqueue side the doorbell is an implicit write
498 unsigned int pkt_desc
= fun_unmap_pkt(q
, reclaim_idx
);
500 xdp_return_frame(q
->info
[reclaim_idx
].xdpf
);
502 trace_funeth_tx_free(q
, reclaim_idx
, pkt_desc
, head
);
504 reclaim_idx
= (reclaim_idx
+ pkt_desc
) & q
->mask
;
507 } while (reclaim_idx
!= head
&& npkts
< budget
);
510 q
->cons_cnt
+= ndesc
;
514 bool fun_xdp_tx(struct funeth_txq
*q
, struct xdp_frame
*xdpf
)
516 unsigned int idx
, nfrags
= 1, ndesc
= 1, tot_len
= xdpf
->len
;
517 const struct skb_shared_info
*si
= NULL
;
518 unsigned int lens
[MAX_SKB_FRAGS
+ 1];
519 dma_addr_t dma
[MAX_SKB_FRAGS
+ 1];
520 struct fun_eth_tx_req
*req
;
522 if (fun_txq_avail(q
) < FUN_XDP_CLEAN_THRES
)
523 fun_xdpq_clean(q
, FUN_XDP_CLEAN_BATCH
);
525 if (unlikely(xdp_frame_has_frags(xdpf
))) {
526 si
= xdp_get_shared_info_from_frame(xdpf
);
527 tot_len
= xdp_get_frame_len(xdpf
);
528 nfrags
+= si
->nr_frags
;
529 ndesc
= DIV_ROUND_UP((sizeof(*req
) + nfrags
*
530 sizeof(struct fun_dataop_gl
)),
534 if (unlikely(fun_txq_avail(q
) < ndesc
)) {
535 FUN_QSTAT_INC(q
, tx_xdp_full
);
539 if (unlikely(fun_map_pkt(q
->dma_dev
, si
, xdpf
->data
, xdpf
->len
, dma
,
541 FUN_QSTAT_INC(q
, tx_map_err
);
545 idx
= q
->prod_cnt
& q
->mask
;
546 req
= fun_tx_desc_addr(q
, idx
);
547 req
->op
= FUN_ETH_OP_TX
;
550 req
->suboff8
= offsetof(struct fun_eth_tx_req
, dataop
);
552 req
->encap_proto
= 0;
553 fun_eth_offload_init(&req
->offload
, 0, 0, 0, 0, 0, 0, 0, 0);
554 req
->dataop
= FUN_DATAOP_HDR_INIT(nfrags
, 0, nfrags
, 0, tot_len
);
556 fun_write_gl(q
, req
, dma
, lens
, nfrags
);
558 q
->info
[idx
].xdpf
= xdpf
;
560 u64_stats_update_begin(&q
->syncp
);
561 q
->stats
.tx_bytes
+= tot_len
;
563 u64_stats_update_end(&q
->syncp
);
565 trace_funeth_tx(q
, tot_len
, idx
, nfrags
);
566 q
->prod_cnt
+= ndesc
;
571 int fun_xdp_xmit_frames(struct net_device
*dev
, int n
,
572 struct xdp_frame
**frames
, u32 flags
)
574 struct funeth_priv
*fp
= netdev_priv(dev
);
575 struct funeth_txq
*q
, **xdpqs
;
578 if (unlikely(flags
& ~XDP_XMIT_FLAGS_MASK
))
581 xdpqs
= rcu_dereference_bh(fp
->xdpqs
);
582 if (unlikely(!xdpqs
))
585 q_idx
= smp_processor_id();
586 if (unlikely(q_idx
>= fp
->num_xdpqs
))
589 for (q
= xdpqs
[q_idx
], i
= 0; i
< n
; i
++)
590 if (!fun_xdp_tx(q
, frames
[i
]))
593 if (unlikely(flags
& XDP_XMIT_FLUSH
))
598 /* Purge a Tx queue of any queued packets. Should be called once HW access
599 * to the packets has been revoked, e.g., after the queue has been disabled.
601 static void fun_txq_purge(struct funeth_txq
*q
)
603 while (q
->cons_cnt
!= q
->prod_cnt
) {
604 unsigned int idx
= q
->cons_cnt
& q
->mask
;
606 q
->cons_cnt
+= fun_unmap_pkt(q
, idx
);
607 dev_kfree_skb_any(q
->info
[idx
].skb
);
609 netdev_tx_reset_queue(q
->ndq
);
612 static void fun_xdpq_purge(struct funeth_txq
*q
)
614 while (q
->cons_cnt
!= q
->prod_cnt
) {
615 unsigned int idx
= q
->cons_cnt
& q
->mask
;
617 q
->cons_cnt
+= fun_unmap_pkt(q
, idx
);
618 xdp_return_frame(q
->info
[idx
].xdpf
);
622 /* Create a Tx queue, allocating all the host resources needed. */
623 static struct funeth_txq
*fun_txq_create_sw(struct net_device
*dev
,
628 struct funeth_priv
*fp
= netdev_priv(dev
);
629 struct funeth_txq
*q
;
633 numa_node
= fun_irq_node(irq
); /* skb Tx queue */
635 numa_node
= cpu_to_node(qidx
); /* XDP Tx queue */
637 q
= kzalloc_node(sizeof(*q
), GFP_KERNEL
, numa_node
);
641 q
->dma_dev
= &fp
->pdev
->dev
;
642 q
->desc
= fun_alloc_ring_mem(q
->dma_dev
, ndesc
, FUNETH_SQE_SIZE
,
643 sizeof(*q
->info
), true, numa_node
,
644 &q
->dma_addr
, (void **)&q
->info
,
652 q
->numa_node
= numa_node
;
653 u64_stats_init(&q
->syncp
);
654 q
->init_state
= FUN_QSTATE_INIT_SW
;
660 netdev_err(dev
, "Can't allocate memory for %s queue %u\n",
661 irq
? "Tx" : "XDP", qidx
);
665 static void fun_txq_free_sw(struct funeth_txq
*q
)
667 struct funeth_priv
*fp
= netdev_priv(q
->netdev
);
669 fun_free_ring_mem(q
->dma_dev
, q
->mask
+ 1, FUNETH_SQE_SIZE
, true,
670 q
->desc
, q
->dma_addr
, q
->info
);
672 fp
->tx_packets
+= q
->stats
.tx_pkts
;
673 fp
->tx_bytes
+= q
->stats
.tx_bytes
;
674 fp
->tx_dropped
+= q
->stats
.tx_map_err
;
679 /* Allocate the device portion of a Tx queue. */
680 int fun_txq_create_dev(struct funeth_txq
*q
, struct fun_irq
*irq
)
682 struct funeth_priv
*fp
= netdev_priv(q
->netdev
);
683 unsigned int irq_idx
, ndesc
= q
->mask
+ 1;
690 irq_idx
= irq
? irq
->irq_idx
: 0;
692 err
= fun_sq_create(fp
->fdev
,
693 FUN_ADMIN_EPSQ_CREATE_FLAG_HEAD_WB_ADDRESS
|
694 FUN_ADMIN_RES_CREATE_FLAG_ALLOCATOR
, 0,
695 FUN_HCI_ID_INVALID
, ilog2(FUNETH_SQE_SIZE
), ndesc
,
696 q
->dma_addr
, fp
->tx_coal_count
, fp
->tx_coal_usec
,
697 irq_idx
, 0, fp
->fdev
->kern_end_qid
, 0,
702 err
= fun_create_and_bind_tx(fp
, q
->hw_qid
);
709 q
->ndq
= netdev_get_tx_queue(q
->netdev
, q
->qidx
);
710 q
->irq_db_val
= FUN_IRQ_SQ_DB(fp
->tx_coal_usec
,
712 writel(q
->irq_db_val
, q
->db
);
715 q
->init_state
= FUN_QSTATE_INIT_FULL
;
716 netif_info(fp
, ifup
, q
->netdev
,
717 "%s queue %u, depth %u, HW qid %u, IRQ idx %u, eth id %u, node %d\n",
718 irq
? "Tx" : "XDP", q
->qidx
, ndesc
, q
->hw_qid
, irq_idx
,
719 q
->ethid
, q
->numa_node
);
723 fun_destroy_sq(fp
->fdev
, q
->hw_qid
);
725 netdev_err(q
->netdev
,
726 "Failed to create %s queue %u on device, error %d\n",
727 irq
? "Tx" : "XDP", q
->qidx
, err
);
731 static void fun_txq_free_dev(struct funeth_txq
*q
)
733 struct funeth_priv
*fp
= netdev_priv(q
->netdev
);
735 if (q
->init_state
< FUN_QSTATE_INIT_FULL
)
738 netif_info(fp
, ifdown
, q
->netdev
,
739 "Freeing %s queue %u (id %u), IRQ %u, ethid %u\n",
740 q
->irq
? "Tx" : "XDP", q
->qidx
, q
->hw_qid
,
741 q
->irq
? q
->irq
->irq_idx
: 0, q
->ethid
);
743 fun_destroy_sq(fp
->fdev
, q
->hw_qid
);
744 fun_res_destroy(fp
->fdev
, FUN_ADMIN_OP_ETH
, 0, q
->ethid
);
753 q
->init_state
= FUN_QSTATE_INIT_SW
;
756 /* Create or advance a Tx queue, allocating all the host and device resources
757 * needed to reach the target state.
759 int funeth_txq_create(struct net_device
*dev
, unsigned int qidx
,
760 unsigned int ndesc
, struct fun_irq
*irq
, int state
,
761 struct funeth_txq
**qp
)
763 struct funeth_txq
*q
= *qp
;
767 q
= fun_txq_create_sw(dev
, qidx
, ndesc
, irq
);
771 if (q
->init_state
>= state
)
774 err
= fun_txq_create_dev(q
, irq
);
786 /* Free Tx queue resources until it reaches the target state.
787 * The queue must be already disconnected from the stack.
789 struct funeth_txq
*funeth_txq_free(struct funeth_txq
*q
, int state
)
791 if (state
< FUN_QSTATE_INIT_FULL
)
794 if (state
== FUN_QSTATE_DESTROYED
) {