Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2024 Realtek Corporation. All rights reserved
3 : : */
4 : :
5 : : #include <stdio.h>
6 : : #include <errno.h>
7 : : #include <stdint.h>
8 : :
9 : : #include <rte_eal.h>
10 : :
11 : : #include <rte_common.h>
12 : : #include <rte_interrupts.h>
13 : : #include <rte_byteorder.h>
14 : : #include <rte_debug.h>
15 : : #include <rte_pci.h>
16 : : #include <bus_pci_driver.h>
17 : : #include <rte_ether.h>
18 : : #include <ethdev_driver.h>
19 : : #include <ethdev_pci.h>
20 : : #include <rte_memory.h>
21 : : #include <rte_malloc.h>
22 : : #include <dev_driver.h>
23 : :
24 : : #include "r8169_ethdev.h"
25 : : #include "r8169_hw.h"
26 : : #include "r8169_logs.h"
27 : :
28 : : /* Bit mask to indicate what bits required for building TX context */
29 : : #define RTL_TX_OFFLOAD_MASK (RTE_MBUF_F_TX_IPV6 | \
30 : : RTE_MBUF_F_TX_IPV4 | \
31 : : RTE_MBUF_F_TX_VLAN | \
32 : : RTE_MBUF_F_TX_IP_CKSUM | \
33 : : RTE_MBUF_F_TX_L4_MASK | \
34 : : RTE_MBUF_F_TX_TCP_SEG)
35 : :
36 : : #define MIN_PATCH_LENGTH 47
37 : : #define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
38 : :
39 : : /* Struct TxDesc in kernel r8169 */
40 : : struct rtl_tx_desc {
41 : : RTE_ATOMIC(u32) opts1;
42 : : u32 opts2;
43 : : u64 addr;
44 : : };
45 : :
46 : : /* Struct RxDesc in kernel r8169 */
47 : : struct rtl_rx_desc {
48 : : u32 opts1;
49 : : u32 opts2;
50 : : u64 addr;
51 : : };
52 : :
53 : : /* Structure associated with each descriptor of the TX ring of a TX queue. */
54 : : struct rtl_tx_entry {
55 : : struct rte_mbuf *mbuf;
56 : : };
57 : :
58 : : /* Structure associated with each descriptor of the RX ring of a RX queue. */
59 : : struct rtl_rx_entry {
60 : : struct rte_mbuf *mbuf;
61 : : };
62 : :
63 : : /* Structure associated with each TX queue. */
64 : : struct rtl_tx_queue {
65 : : struct rtl_tx_desc *hw_ring;
66 : : struct rtl_tx_entry *sw_ring;
67 : : struct rtl_hw *hw;
68 : : uint64_t hw_ring_phys_addr;
69 : : uint16_t nb_tx_desc;
70 : : RTE_ATOMIC(uint32_t) tx_tail;
71 : : uint16_t tx_head;
72 : : uint16_t queue_id;
73 : : uint16_t port_id;
74 : : uint16_t tx_free_thresh;
75 : : uint16_t tx_free;
76 : : };
77 : :
78 : : /* Structure associated with each RX queue. */
79 : : struct rtl_rx_queue {
80 : : struct rte_mempool *mb_pool;
81 : : struct rtl_rx_desc *hw_ring;
82 : : struct rtl_rx_entry *sw_ring;
83 : : struct rte_mbuf *pkt_first_seg; /* First segment of current packet. */
84 : : struct rte_mbuf *pkt_last_seg; /* Last segment of current packet. */
85 : : struct rtl_hw *hw;
86 : : uint64_t hw_ring_phys_addr;
87 : : uint64_t offloads;
88 : : uint16_t nb_rx_desc;
89 : : uint16_t rx_tail;
90 : : uint16_t nb_rx_hold;
91 : : uint16_t queue_id;
92 : : uint16_t port_id;
93 : : uint16_t rx_free_thresh;
94 : : };
95 : :
96 : : enum _DescStatusBit {
97 : : DescOwn = (1 << 31), /* Descriptor is owned by NIC. */
98 : : RingEnd = (1 << 30), /* End of descriptor ring */
99 : : FirstFrag = (1 << 29), /* First segment of a packet */
100 : : LastFrag = (1 << 28), /* Final segment of a packet */
101 : :
102 : : DescOwn_V3 = DescOwn, /* Descriptor is owned by NIC. */
103 : : RingEnd_V3 = RingEnd, /* End of descriptor ring */
104 : : FirstFrag_V3 = (1 << 25), /* First segment of a packet */
105 : : LastFrag_V3 = (1 << 24), /* Final segment of a packet */
106 : :
107 : : /* TX private */
108 : : /*------ offset 0 of TX descriptor ------*/
109 : : LargeSend = (1 << 27), /* TCP Large Send Offload (TSO) */
110 : : GiantSendv4 = (1 << 26), /* TCP Giant Send Offload V4 (GSOv4) */
111 : : GiantSendv6 = (1 << 25), /* TCP Giant Send Offload V6 (GSOv6) */
112 : : LargeSend_DP = (1 << 16), /* TCP Large Send Offload (TSO) */
113 : : MSSShift = 16, /* MSS value position */
114 : : MSSMask = 0x7FFU, /* MSS value 11 bits */
115 : : TxIPCS = (1 << 18), /* Calculate IP checksum */
116 : : TxUDPCS = (1 << 17), /* Calculate UDP/IP checksum */
117 : : TxTCPCS = (1 << 16), /* Calculate TCP/IP checksum */
118 : : TxVlanTag = (1 << 17), /* Add VLAN tag */
119 : :
120 : : /*@@@@@@ offset 4 of TX descriptor => bits for RTL8169 only begin @@@@@@*/
121 : : TxUDPCS_C = (1 << 31), /* Calculate UDP/IP checksum */
122 : : TxTCPCS_C = (1 << 30), /* Calculate TCP/IP checksum */
123 : : TxIPCS_C = (1 << 29), /* Calculate IP checksum */
124 : : TxIPV6F_C = (1 << 28), /* Indicate it is an IPv6 packet */
125 : : /*@@@@@@ offset 4 of tx descriptor => bits for RTL8169 only end @@@@@@*/
126 : :
127 : : /* RX private */
128 : : /* ------ offset 0 of RX descriptor ------ */
129 : : PID1 = (1 << 18), /* Protocol ID bit 1/2 */
130 : : PID0 = (1 << 17), /* Protocol ID bit 2/2 */
131 : :
132 : : #define RxProtoUDP PID1
133 : : #define RxProtoTCP PID0
134 : : #define RxProtoIP (PID1 | PID0)
135 : : #define RxProtoMask RxProtoIP
136 : :
137 : : RxIPF = (1 << 16), /* IP checksum failed */
138 : : RxUDPF = (1 << 15), /* UDP/IP checksum failed */
139 : : RxTCPF = (1 << 14), /* TCP/IP checksum failed */
140 : : RxVlanTag = (1 << 16), /* VLAN tag available */
141 : :
142 : : /*@@@@@@ offset 0 of RX descriptor => bits for RTL8169 only begin @@@@@@*/
143 : : RxUDPT = (1 << 18),
144 : : RxTCPT = (1 << 17),
145 : : /*@@@@@@ offset 0 of RX descriptor => bits for RTL8169 only end @@@@@@*/
146 : :
147 : : /*@@@@@@ offset 4 of RX descriptor => bits for RTL8169 only begin @@@@@@*/
148 : : RxV6F = (1 << 31),
149 : : RxV4F = (1 << 30),
150 : : /*@@@@@@ offset 4 of RX descriptor => bits for RTL8169 only end @@@@@@*/
151 : :
152 : : PID1_v3 = (1 << 29), /* Protocol ID bit 1/2 */
153 : : PID0_v3 = (1 << 28), /* Protocol ID bit 2/2 */
154 : :
155 : : #define RxProtoUDP_v3 PID1_v3
156 : : #define RxProtoTCP_v3 PID0_v3
157 : : #define RxProtoIP_v3 (PID1_v3 | PID0_v3)
158 : : #define RxProtoMask_v3 RxProtoIP_v3
159 : :
160 : : RxIPF_v3 = (1 << 26), /* IP checksum failed */
161 : : RxUDPF_v3 = (1 << 25), /* UDP/IP checksum failed */
162 : : RxTCPF_v3 = (1 << 24), /* TCP/IP checksum failed */
163 : : RxSCTPF_v3 = (1 << 23), /* TCP/IP checksum failed */
164 : : RxVlanTag_v3 = (RxVlanTag), /* VLAN tag available */
165 : :
166 : : /*@@@@@@ offset 0 of RX descriptor => bits for RTL8169 only begin @@@@@@*/
167 : : RxUDPT_v3 = (1 << 29),
168 : : RxTCPT_v3 = (1 << 28),
169 : : RxSCTP_v3 = (1 << 27),
170 : : /*@@@@@@ offset 0 of RX descriptor => bits for RTL8169 only end @@@@@@*/
171 : :
172 : : /*@@@@@@ offset 4 of RX descriptor => bits for RTL8169 only begin @@@@@@*/
173 : : RxV6F_v3 = RxV6F,
174 : : RxV4F_v3 = RxV4F,
175 : : /*@@@@@@ offset 4 of RX descriptor => bits for RTL8169 only end @@@@@@*/
176 : : };
177 : :
178 : : #define GTTCPHO_SHIFT 18
179 : : #define GTTCPHO_MAX 0x70U
180 : : #define GTPKTSIZE_MAX 0x3ffffU
181 : : #define TCPHO_SHIFT 18
182 : : #define TCPHO_MAX 0x3ffU
183 : : #define LSOPKTSIZE_MAX 0xffffU
184 : : #define MSS_MAX 0x07ffu /* MSS value */
185 : :
186 : : typedef void (*rtl_clear_rdu_func)(struct rtl_hw *);
187 : : static rtl_clear_rdu_func rtl_clear_rdu;
188 : :
189 : : /* ---------------------------------RX---------------------------------- */
190 : :
191 : : static void
192 : 0 : rtl_rx_queue_release_mbufs(struct rtl_rx_queue *rxq)
193 : : {
194 : : int i;
195 : :
196 : 0 : PMD_INIT_FUNC_TRACE();
197 : :
198 [ # # ]: 0 : if (rxq != NULL) {
199 [ # # ]: 0 : if (rxq->sw_ring != NULL) {
200 [ # # ]: 0 : for (i = 0; i < rxq->nb_rx_desc; i++) {
201 [ # # ]: 0 : if (rxq->sw_ring[i].mbuf != NULL) {
202 : : rte_pktmbuf_free_seg(rxq->sw_ring[i].mbuf);
203 : 0 : rxq->sw_ring[i].mbuf = NULL;
204 : : }
205 : : }
206 : : }
207 : : }
208 : 0 : }
209 : :
210 : : void
211 : 0 : rtl_rx_queue_release(struct rte_eth_dev *dev, uint16_t rx_queue_id)
212 : : {
213 : 0 : struct rtl_rx_queue *rxq = dev->data->rx_queues[rx_queue_id];
214 : :
215 : 0 : PMD_INIT_FUNC_TRACE();
216 : :
217 [ # # ]: 0 : if (rxq != NULL) {
218 : 0 : rtl_rx_queue_release_mbufs(rxq);
219 : 0 : rte_free(rxq->sw_ring);
220 : 0 : rte_free(rxq);
221 : : }
222 : 0 : }
223 : :
224 : : void
225 : 0 : rtl_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
226 : : struct rte_eth_rxq_info *qinfo)
227 : : {
228 : : struct rtl_rx_queue *rxq;
229 : :
230 : 0 : rxq = dev->data->rx_queues[queue_id];
231 : :
232 : 0 : qinfo->mp = rxq->mb_pool;
233 : 0 : qinfo->scattered_rx = dev->data->scattered_rx;
234 : 0 : qinfo->nb_desc = rxq->nb_rx_desc;
235 : :
236 : 0 : qinfo->conf.rx_free_thresh = rxq->rx_free_thresh;
237 : 0 : qinfo->conf.offloads = rxq->offloads;
238 : 0 : }
239 : :
240 : : static void
241 : : rtl_reset_rx_queue(struct rtl_rx_queue *rxq)
242 : : {
243 : : static const struct rtl_rx_desc zero_rxd = {0};
244 : : int i;
245 : :
246 [ # # # # ]: 0 : for (i = 0; i < rxq->nb_rx_desc; i++)
247 : 0 : rxq->hw_ring[i] = zero_rxd;
248 : :
249 : 0 : rxq->hw_ring[rxq->nb_rx_desc - 1].opts1 = rte_cpu_to_le_32(RingEnd);
250 : 0 : rxq->rx_tail = 0;
251 : 0 : rxq->pkt_first_seg = NULL;
252 : 0 : rxq->pkt_last_seg = NULL;
253 : : }
254 : :
255 : : uint64_t
256 : 0 : rtl_get_rx_port_offloads(void)
257 : : {
258 : : uint64_t offloads;
259 : :
260 : : offloads = RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
261 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
262 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
263 : : RTE_ETH_RX_OFFLOAD_SCATTER |
264 : : RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
265 : :
266 : 0 : return offloads;
267 : : }
268 : :
269 : : int
270 : 0 : rtl_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
271 : : uint16_t nb_rx_desc, unsigned int socket_id,
272 : : const struct rte_eth_rxconf *rx_conf,
273 : : struct rte_mempool *mb_pool)
274 : : {
275 : : struct rtl_rx_queue *rxq;
276 : : const struct rte_memzone *mz;
277 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
278 : 0 : struct rtl_hw *hw = &adapter->hw;
279 : : uint32_t size;
280 : :
281 : 0 : PMD_INIT_FUNC_TRACE();
282 : :
283 : : /*
284 : : * If this queue existed already, free the associated memory. The
285 : : * queue cannot be reused in case we need to allocate memory on
286 : : * different socket than was previously used.
287 : : */
288 [ # # ]: 0 : if (dev->data->rx_queues[queue_idx] != NULL) {
289 : 0 : rtl_rx_queue_release(dev, queue_idx);
290 : 0 : dev->data->rx_queues[queue_idx] = NULL;
291 : : }
292 : :
293 : : /* First allocate the rx queue data structure */
294 : 0 : rxq = rte_zmalloc_socket("r8169 RX queue", sizeof(struct rtl_rx_queue),
295 : : RTE_CACHE_LINE_SIZE, socket_id);
296 : :
297 [ # # ]: 0 : if (rxq == NULL) {
298 : 0 : PMD_INIT_LOG(ERR, "Cannot allocate Rx queue structure");
299 : 0 : return -ENOMEM;
300 : : }
301 : :
302 : : /* Setup queue */
303 : 0 : rxq->mb_pool = mb_pool;
304 : 0 : rxq->nb_rx_desc = nb_rx_desc;
305 : 0 : rxq->port_id = dev->data->port_id;
306 : 0 : rxq->queue_id = queue_idx;
307 : 0 : rxq->rx_free_thresh = rx_conf->rx_free_thresh;
308 : :
309 : : /* Allocate memory for the software ring */
310 : 0 : rxq->sw_ring = rte_calloc("r8169 sw rx ring", nb_rx_desc,
311 : : sizeof(struct rtl_rx_entry), RTE_CACHE_LINE_SIZE);
312 : :
313 [ # # ]: 0 : if (rxq->sw_ring == NULL) {
314 : 0 : PMD_INIT_LOG(ERR,
315 : : "Port %d: Cannot allocate software ring for queue %d",
316 : : rxq->port_id, rxq->queue_id);
317 : 0 : rte_free(rxq);
318 : 0 : return -ENOMEM;
319 : : }
320 : :
321 : : /*
322 : : * Allocate RX ring hardware descriptors. A memzone large enough to
323 : : * handle the maximum ring size is allocated in order to allow for
324 : : * resizing in later calls to the queue setup function.
325 : : */
326 : 0 : size = sizeof(struct rtl_rx_desc) * (nb_rx_desc + 1);
327 : 0 : mz = rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx, size,
328 : : RTL_RING_ALIGN, socket_id);
329 [ # # ]: 0 : if (mz == NULL) {
330 : 0 : PMD_INIT_LOG(ERR,
331 : : "Port %d: Cannot allocate software ring for queue %d",
332 : : rxq->port_id, rxq->queue_id);
333 : 0 : rtl_rx_queue_release(dev, rxq->queue_id);
334 : 0 : return -ENOMEM;
335 : : }
336 : :
337 : 0 : rxq->hw = hw;
338 : 0 : rxq->hw_ring = mz->addr;
339 : 0 : rxq->hw_ring_phys_addr = mz->iova;
340 : 0 : rxq->offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
341 : :
342 : : rtl_reset_rx_queue(rxq);
343 : :
344 : 0 : dev->data->rx_queues[queue_idx] = rxq;
345 : :
346 : 0 : return 0;
347 : : }
348 : :
349 : : static int
350 : 0 : rtl_alloc_rx_queue_mbufs(struct rtl_rx_queue *rxq)
351 : : {
352 : 0 : struct rtl_rx_entry *rxe = rxq->sw_ring;
353 : 0 : struct rtl_hw *hw = rxq->hw;
354 : : struct rtl_rx_desc *rxd;
355 : : int i;
356 : : uint64_t dma_addr;
357 : :
358 : 0 : rxd = &rxq->hw_ring[0];
359 : :
360 : : /* Initialize software ring entries */
361 [ # # ]: 0 : for (i = 0; i < rxq->nb_rx_desc; i++) {
362 : 0 : struct rte_mbuf *mbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
363 : :
364 [ # # ]: 0 : if (mbuf == NULL) {
365 : 0 : PMD_INIT_LOG(ERR, "RX mbuf alloc failed queue_id=%hu",
366 : : rxq->queue_id);
367 : 0 : return -ENOMEM;
368 : : }
369 : :
370 : : dma_addr = rte_cpu_to_le_64(rte_mbuf_data_iova_default(mbuf));
371 : :
372 : 0 : rxd = &rxq->hw_ring[i];
373 : 0 : rxd->addr = dma_addr;
374 : 0 : rxd->opts2 = 0;
375 : : rte_wmb();
376 : 0 : rxd->opts1 = rte_cpu_to_le_32(DescOwn | hw->rx_buf_sz);
377 : 0 : rxe[i].mbuf = mbuf;
378 : : }
379 : :
380 : : /* Mark as last desc */
381 : 0 : rxd->opts1 |= rte_cpu_to_le_32(RingEnd);
382 : :
383 : 0 : return 0;
384 : : }
385 : :
386 : : static void
387 : 0 : rtl8125_hw_set_features(struct rtl_hw *hw, uint64_t offloads)
388 : : {
389 : : u16 cp_cmd;
390 : : u32 rx_config;
391 : :
392 : 0 : rx_config = RTL_R32(hw, RxConfig);
393 [ # # ]: 0 : if (offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
394 : 0 : rx_config |= (EnableInnerVlan | EnableOuterVlan);
395 : : else
396 : 0 : rx_config &= ~(EnableInnerVlan | EnableOuterVlan);
397 : :
398 : 0 : RTL_W32(hw, RxConfig, rx_config);
399 : :
400 : 0 : cp_cmd = RTL_R16(hw, CPlusCmd);
401 : :
402 [ # # ]: 0 : if (offloads & RTE_ETH_RX_OFFLOAD_CHECKSUM)
403 : 0 : cp_cmd |= RxChkSum;
404 : : else
405 : 0 : cp_cmd &= ~RxChkSum;
406 : :
407 : 0 : RTL_W16(hw, CPlusCmd, cp_cmd);
408 : 0 : }
409 : :
410 : : static void
411 : : rtl8168_hw_set_features(struct rtl_hw *hw, uint64_t offloads)
412 : : {
413 : : u16 cp_cmd;
414 : :
415 : 0 : cp_cmd = RTL_R16(hw, CPlusCmd);
416 : :
417 [ # # ]: 0 : if (offloads & RTE_ETH_RX_OFFLOAD_CHECKSUM)
418 : 0 : cp_cmd |= RxChkSum;
419 : : else
420 : 0 : cp_cmd &= ~RxChkSum;
421 : :
422 [ # # ]: 0 : if (offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
423 : 0 : cp_cmd |= RxVlan;
424 : : else
425 : 0 : cp_cmd &= ~RxVlan;
426 : :
427 : 0 : RTL_W16(hw, CPlusCmd, cp_cmd);
428 : 0 : }
429 : :
430 : : static void
431 : 0 : rtl_hw_set_features(struct rtl_hw *hw, uint64_t offloads)
432 : : {
433 [ # # ]: 0 : if (rtl_is_8125(hw))
434 : 0 : rtl8125_hw_set_features(hw, offloads);
435 : : else
436 : : rtl8168_hw_set_features(hw, offloads);
437 : 0 : }
438 : :
439 : : static void
440 : : rtl_hw_set_rx_packet_filter(struct rtl_hw *hw)
441 : : {
442 : : int rx_mode;
443 : :
444 : 0 : hw->hw_ops.hw_init_rxcfg(hw);
445 : :
446 : : rx_mode = AcceptBroadcast | AcceptMyPhys;
447 : 0 : RTL_W32(hw, RxConfig, rx_mode | (RTL_R32(hw, RxConfig)));
448 : : }
449 : :
450 : : static void
451 : 0 : rtl8125_clear_rdu(struct rtl_hw *hw)
452 : : {
453 : 0 : RTL_W32(hw, ISR0_8125, (RxOK | RxErr | RxDescUnavail));
454 : 0 : }
455 : :
456 : : static void
457 : 0 : rtl8168_clear_rdu(struct rtl_hw *hw)
458 : : {
459 : 0 : RTL_W16(hw, IntrStatus, (RxOK | RxErr | RxDescUnavail));
460 : 0 : }
461 : :
462 : : int
463 : 0 : rtl_rx_init(struct rte_eth_dev *dev)
464 : : {
465 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
466 : 0 : struct rtl_hw *hw = &adapter->hw;
467 : : struct rtl_rx_queue *rxq;
468 : : int ret;
469 : : u32 csi_tmp, max_rx_pkt_size;
470 : :
471 : 0 : rxq = dev->data->rx_queues[0];
472 : :
473 [ # # ]: 0 : if (rxq->mb_pool == NULL) {
474 : 0 : PMD_INIT_LOG(ERR, "r8169 rx queue pool not setup!");
475 : 0 : return -ENOMEM;
476 : : }
477 : :
478 : 0 : RTL_W32(hw, RxDescAddrLow, ((u64)rxq->hw_ring_phys_addr & DMA_BIT_MASK(32)));
479 : 0 : RTL_W32(hw, RxDescAddrHigh, ((u64)rxq->hw_ring_phys_addr >> 32));
480 : :
481 : 0 : dev->rx_pkt_burst = rtl_recv_pkts;
482 [ # # ]: 0 : hw->rx_buf_sz = rte_pktmbuf_data_room_size(rxq->mb_pool) - RTE_PKTMBUF_HEADROOM;
483 : :
484 : 0 : max_rx_pkt_size = dev->data->mtu + RTL_ETH_OVERHEAD;
485 : :
486 [ # # # # ]: 0 : if (dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_SCATTER ||
487 : : max_rx_pkt_size > hw->rx_buf_sz) {
488 [ # # ]: 0 : if (!dev->data->scattered_rx)
489 : 0 : PMD_INIT_LOG(DEBUG, "forcing scatter mode");
490 : 0 : dev->rx_pkt_burst = rtl_recv_scattered_pkts;
491 : 0 : dev->data->scattered_rx = 1;
492 : : }
493 : :
494 : 0 : RTL_W16(hw, RxMaxSize, max_rx_pkt_size);
495 : :
496 : 0 : ret = rtl_alloc_rx_queue_mbufs(rxq);
497 [ # # ]: 0 : if (ret) {
498 : 0 : PMD_INIT_LOG(ERR, "r8169 rx mbuf alloc failed!");
499 : 0 : return ret;
500 : : }
501 : :
502 : 0 : rtl_enable_cfg9346_write(hw);
503 : :
504 [ # # ]: 0 : if (!rtl_is_8125(hw)) {
505 : : /* RX ftr mcu enable */
506 : 0 : csi_tmp = rtl_eri_read(hw, 0xDC, 1, ERIAR_ExGMAC);
507 : 0 : csi_tmp &= ~BIT_0;
508 : 0 : rtl_eri_write(hw, 0xDC, 1, csi_tmp, ERIAR_ExGMAC);
509 : 0 : csi_tmp |= BIT_0;
510 : 0 : rtl_eri_write(hw, 0xDC, 1, csi_tmp, ERIAR_ExGMAC);
511 : :
512 : : /* RSS disable */
513 : 0 : rtl_eri_write(hw, 0xC0, 2, 0x0000, ERIAR_ExGMAC); /* queue num = 1 */
514 : 0 : rtl_eri_write(hw, 0xB8, 4, 0x00000000, ERIAR_ExGMAC);
515 : : }
516 : :
517 : : /* RX accept type and csum vlan offload */
518 : 0 : rtl_hw_set_features(hw, rxq->offloads);
519 : :
520 : 0 : rtl_disable_rxdvgate(hw);
521 : :
522 : : /* Set Rx packet filter */
523 : : rtl_hw_set_rx_packet_filter(hw);
524 : :
525 : 0 : rtl_disable_cfg9346_write(hw);
526 : :
527 : 0 : RTL_W8(hw, ChipCmd, RTL_R8(hw, ChipCmd) | CmdRxEnb);
528 : :
529 : 0 : dev->data->rx_queue_state[0] = RTE_ETH_QUEUE_STATE_STARTED;
530 : :
531 [ # # ]: 0 : if (rtl_is_8125(hw))
532 : 0 : rtl_clear_rdu = rtl8125_clear_rdu;
533 : : else
534 : 0 : rtl_clear_rdu = rtl8168_clear_rdu;
535 : :
536 : : return 0;
537 : : }
538 : :
539 : : static inline void
540 : : rtl_mark_to_asic(struct rtl_rx_desc *rxd, u32 size)
541 : : {
542 : 0 : u32 eor = rte_le_to_cpu_32(rxd->opts1) & RingEnd;
543 : :
544 : 0 : rxd->opts1 = rte_cpu_to_le_32(DescOwn | eor | size);
545 : : }
546 : :
547 : : static inline uint64_t
548 : : rtl_rx_desc_error_to_pkt_flags(struct rtl_rx_queue *rxq, uint32_t opts1,
549 : : uint32_t opts2)
550 : : {
551 : : uint64_t pkt_flags = 0;
552 : :
553 [ # # # # ]: 0 : if (!(rxq->offloads & RTE_ETH_RX_OFFLOAD_CHECKSUM))
554 : 0 : goto exit;
555 : :
556 : : /* RX csum offload for RTL8169*/
557 [ # # # # : 0 : if (((opts2 & RxV4F) && !(opts1 & RxIPF)) || (opts2 & RxV6F)) {
# # # # #
# # # ]
558 : : pkt_flags |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
559 [ # # # # ]: 0 : if (((opts1 & RxTCPT) && !(opts1 & RxTCPF)) ||
560 [ # # # # ]: 0 : ((opts1 & RxUDPT) && !(opts1 & RxUDPF)))
561 : : pkt_flags |= RTE_MBUF_F_RX_L4_CKSUM_GOOD;
562 : : }
563 : :
564 : 0 : exit:
565 : : return pkt_flags;
566 : : }
567 : :
568 : : /* PMD receive function */
569 : : uint16_t
570 : 0 : rtl_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
571 : : {
572 : : struct rtl_rx_queue *rxq = (struct rtl_rx_queue *)rx_queue;
573 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[rxq->port_id];
574 : 0 : struct rtl_hw *hw = rxq->hw;
575 : : struct rtl_rx_desc *rxd;
576 : : struct rtl_rx_desc *hw_ring;
577 : : struct rtl_rx_entry *rxe;
578 : 0 : struct rtl_rx_entry *sw_ring = rxq->sw_ring;
579 : : struct rte_mbuf *new_mb;
580 : : struct rte_mbuf *rmb;
581 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
582 : : struct rtl_sw_stats *stats = &adapter->sw_stats;
583 : : uint16_t nb_rx = 0;
584 : : uint16_t nb_hold = 0;
585 : 0 : uint16_t tail = rxq->rx_tail;
586 : : uint16_t pkt_len = 0;
587 : 0 : const uint16_t nb_rx_desc = rxq->nb_rx_desc;
588 : : uint32_t opts1;
589 : : uint32_t opts2;
590 : : uint64_t dma_addr;
591 : :
592 : 0 : hw_ring = rxq->hw_ring;
593 : :
594 : : RTE_ASSERT(RTL_R8(hw, ChipCmd) & CmdRxEnb);
595 : :
596 [ # # ]: 0 : while (nb_rx < nb_pkts) {
597 : 0 : rxd = &hw_ring[tail];
598 : :
599 : 0 : opts1 = rte_le_to_cpu_32(rxd->opts1);
600 [ # # ]: 0 : if (opts1 & DescOwn)
601 : : break;
602 : :
603 : : /*
604 : : * This barrier is needed to keep us from reading
605 : : * any other fields out of the Rx descriptor until
606 : : * we know the status of DescOwn.
607 : : */
608 : : rte_rmb();
609 : :
610 [ # # ]: 0 : if (unlikely(opts1 & RxRES)) {
611 : 0 : stats->rx_errors++;
612 : 0 : rtl_mark_to_asic(rxd, hw->rx_buf_sz);
613 : 0 : nb_hold++;
614 : 0 : tail = (tail + 1) % nb_rx_desc;
615 : : } else {
616 : 0 : opts2 = rte_le_to_cpu_32(rxd->opts2);
617 : :
618 : 0 : new_mb = rte_mbuf_raw_alloc(rxq->mb_pool);
619 [ # # ]: 0 : if (new_mb == NULL) {
620 : : PMD_RX_LOG(DEBUG, "RX mbuf alloc failed port_id=%u "
621 : : "queue_id=%u",
622 : : (uint32_t)rxq->port_id, (uint32_t)rxq->queue_id);
623 : 0 : dev->data->rx_mbuf_alloc_failed++;
624 : 0 : break;
625 : : }
626 : :
627 : 0 : nb_hold++;
628 : 0 : rxe = &sw_ring[tail];
629 : :
630 : 0 : rmb = rxe->mbuf;
631 : :
632 : 0 : tail = (tail + 1) % nb_rx_desc;
633 : :
634 : : /* Prefetch next mbufs */
635 : 0 : rte_prefetch0(sw_ring[tail].mbuf);
636 : :
637 : : /*
638 : : * When next RX descriptor is on a cache-line boundary,
639 : : * prefetch the next 4 RX descriptors and the next 8 pointers
640 : : * to mbufs.
641 : : */
642 [ # # ]: 0 : if ((tail & 0x3) == 0) {
643 : : rte_prefetch0(&sw_ring[tail]);
644 : 0 : rte_prefetch0(&hw_ring[tail]);
645 : : }
646 : :
647 : : /* Refill the RX desc */
648 : 0 : rxe->mbuf = new_mb;
649 : : dma_addr = rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mb));
650 : :
651 : : /* Setup RX descriptor */
652 : 0 : rxd->addr = dma_addr;
653 : 0 : rxd->opts2 = 0;
654 : : rte_wmb();
655 : 0 : rtl_mark_to_asic(rxd, hw->rx_buf_sz);
656 : :
657 : 0 : pkt_len = opts1 & 0x00003fff;
658 : 0 : pkt_len -= RTE_ETHER_CRC_LEN;
659 : :
660 : 0 : rmb->data_off = RTE_PKTMBUF_HEADROOM;
661 : 0 : rte_prefetch1((char *)rmb->buf_addr + rmb->data_off);
662 : 0 : rmb->nb_segs = 1;
663 : 0 : rmb->next = NULL;
664 : 0 : rmb->pkt_len = pkt_len;
665 : 0 : rmb->data_len = pkt_len;
666 : 0 : rmb->port = rxq->port_id;
667 : :
668 [ # # ]: 0 : if (opts2 & RxVlanTag)
669 [ # # ]: 0 : rmb->vlan_tci = rte_bswap16(opts2 & 0xffff);
670 : :
671 : 0 : rmb->ol_flags = rtl_rx_desc_error_to_pkt_flags(rxq, opts1, opts2);
672 : :
673 : : /*
674 : : * Store the mbuf address into the next entry of the array
675 : : * of returned packets.
676 : : */
677 : 0 : rx_pkts[nb_rx++] = rmb;
678 : :
679 : 0 : stats->rx_bytes += pkt_len;
680 : 0 : stats->rx_packets++;
681 : : }
682 : : }
683 : :
684 : 0 : rxq->rx_tail = tail;
685 : :
686 : 0 : nb_hold = (uint16_t)(nb_hold + rxq->nb_rx_hold);
687 [ # # ]: 0 : if (nb_hold > rxq->rx_free_thresh) {
688 : : rte_wmb();
689 : :
690 : : /* Clear RDU */
691 : 0 : rtl_clear_rdu(hw);
692 : :
693 : : nb_hold = 0;
694 : : }
695 : :
696 : 0 : rxq->nb_rx_hold = nb_hold;
697 : :
698 : 0 : return nb_rx;
699 : : }
700 : :
701 : : /* PMD receive function for scattered pkts */
702 : : uint16_t
703 : 0 : rtl_recv_scattered_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
704 : : uint16_t nb_pkts)
705 : : {
706 : : struct rtl_rx_queue *rxq = (struct rtl_rx_queue *)rx_queue;
707 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[rxq->port_id];
708 : 0 : struct rtl_hw *hw = rxq->hw;
709 : : struct rtl_rx_desc *rxd;
710 : : struct rtl_rx_desc *hw_ring;
711 : : struct rtl_rx_entry *rxe;
712 : 0 : struct rtl_rx_entry *sw_ring = rxq->sw_ring;
713 : : struct rte_mbuf *first_seg;
714 : : struct rte_mbuf *last_seg;
715 : : struct rte_mbuf *new_mb;
716 : : struct rte_mbuf *rmb;
717 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
718 : : struct rtl_sw_stats *stats = &adapter->sw_stats;
719 : : uint16_t nb_rx = 0;
720 : : uint16_t nb_hold = 0;
721 : : uint16_t data_len = 0;
722 : 0 : uint16_t tail = rxq->rx_tail;
723 : 0 : const uint16_t nb_rx_desc = rxq->nb_rx_desc;
724 : : uint32_t opts1;
725 : : uint32_t opts2;
726 : : uint64_t dma_addr;
727 : :
728 : 0 : hw_ring = rxq->hw_ring;
729 : :
730 : : /*
731 : : * Retrieve RX context of current packet, if any.
732 : : */
733 : 0 : first_seg = rxq->pkt_first_seg;
734 : 0 : last_seg = rxq->pkt_last_seg;
735 : :
736 : : RTE_ASSERT(RTL_R8(hw, ChipCmd) & CmdRxEnb);
737 : :
738 [ # # ]: 0 : while (nb_rx < nb_pkts) {
739 : 0 : next_desc:
740 : 0 : rxd = &hw_ring[tail];
741 : :
742 : 0 : opts1 = rte_le_to_cpu_32(rxd->opts1);
743 [ # # ]: 0 : if (opts1 & DescOwn)
744 : : break;
745 : :
746 : : /*
747 : : * This barrier is needed to keep us from reading
748 : : * any other fields out of the Rx descriptor until
749 : : * we know the status of DescOwn
750 : : */
751 : : rte_rmb();
752 : :
753 [ # # ]: 0 : if (unlikely(opts1 & RxRES)) {
754 : 0 : stats->rx_errors++;
755 : 0 : rtl_mark_to_asic(rxd, hw->rx_buf_sz);
756 : 0 : nb_hold++;
757 : 0 : tail = (tail + 1) % nb_rx_desc;
758 : : } else {
759 : 0 : opts2 = rte_le_to_cpu_32(rxd->opts2);
760 : :
761 : 0 : new_mb = rte_mbuf_raw_alloc(rxq->mb_pool);
762 [ # # ]: 0 : if (new_mb == NULL) {
763 : : PMD_RX_LOG(DEBUG, "RX mbuf alloc failed port_id=%u "
764 : : "queue_id=%u",
765 : : (uint32_t)rxq->port_id, (uint32_t)rxq->queue_id);
766 : 0 : dev->data->rx_mbuf_alloc_failed++;
767 : 0 : break;
768 : : }
769 : :
770 : 0 : nb_hold++;
771 : 0 : rxe = &sw_ring[tail];
772 : :
773 : 0 : rmb = rxe->mbuf;
774 : :
775 : : /* Prefetch next mbufs */
776 : 0 : tail = (tail + 1) % nb_rx_desc;
777 : 0 : rte_prefetch0(sw_ring[tail].mbuf);
778 : :
779 : : /*
780 : : * When next RX descriptor is on a cache-line boundary,
781 : : * prefetch the next 4 RX descriptors and the next 8 pointers
782 : : * to mbufs.
783 : : */
784 [ # # ]: 0 : if ((tail & 0x3) == 0) {
785 : : rte_prefetch0(&sw_ring[tail]);
786 : 0 : rte_prefetch0(&hw_ring[tail]);
787 : : }
788 : :
789 : : /* Refill the RX desc */
790 : 0 : rxe->mbuf = new_mb;
791 : : dma_addr = rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mb));
792 : :
793 : : /* Setup RX descriptor */
794 : 0 : rxd->addr = dma_addr;
795 : 0 : rxd->opts2 = 0;
796 : : rte_wmb();
797 : 0 : rtl_mark_to_asic(rxd, hw->rx_buf_sz);
798 : :
799 : 0 : data_len = opts1 & 0x00003fff;
800 : 0 : rmb->data_len = data_len;
801 : 0 : rmb->data_off = RTE_PKTMBUF_HEADROOM;
802 : :
803 : : /*
804 : : * If this is the first buffer of the received packet,
805 : : * set the pointer to the first mbuf of the packet and
806 : : * initialize its context.
807 : : * Otherwise, update the total length and the number of segments
808 : : * of the current scattered packet, and update the pointer to
809 : : * the last mbuf of the current packet.
810 : : */
811 [ # # ]: 0 : if (first_seg == NULL) {
812 : : first_seg = rmb;
813 : 0 : first_seg->pkt_len = data_len;
814 : 0 : first_seg->nb_segs = 1;
815 : : } else {
816 : 0 : first_seg->pkt_len += data_len;
817 : 0 : first_seg->nb_segs++;
818 : 0 : last_seg->next = rmb;
819 : : }
820 : :
821 : : /*
822 : : * If this is not the last buffer of the received packet,
823 : : * update the pointer to the last mbuf of the current scattered
824 : : * packet and continue to parse the RX ring.
825 : : */
826 [ # # ]: 0 : if (!(opts1 & LastFrag)) {
827 : : last_seg = rmb;
828 : 0 : goto next_desc;
829 : : }
830 : :
831 : : /*
832 : : * This is the last buffer of the received packet.
833 : : */
834 : 0 : rmb->next = NULL;
835 : :
836 : 0 : first_seg->pkt_len -= RTE_ETHER_CRC_LEN;
837 [ # # ]: 0 : if (data_len <= RTE_ETHER_CRC_LEN) {
838 : : rte_pktmbuf_free_seg(rmb);
839 : 0 : first_seg->nb_segs--;
840 : 0 : last_seg->data_len = last_seg->data_len -
841 : : (RTE_ETHER_CRC_LEN - data_len);
842 : 0 : last_seg->next = NULL;
843 : : } else {
844 : 0 : rmb->data_len = data_len - RTE_ETHER_CRC_LEN;
845 : : }
846 : :
847 : 0 : first_seg->port = rxq->port_id;
848 : :
849 [ # # ]: 0 : if (opts2 & RxVlanTag)
850 [ # # ]: 0 : first_seg->vlan_tci = rte_bswap16(opts2 & 0xffff);
851 : :
852 : 0 : first_seg->ol_flags = rtl_rx_desc_error_to_pkt_flags(rxq, opts1, opts2);
853 : :
854 : 0 : rte_prefetch1((char *)first_seg->buf_addr + first_seg->data_off);
855 : :
856 : : /*
857 : : * Store the mbuf address into the next entry of the array
858 : : * of returned packets.
859 : : */
860 : 0 : rx_pkts[nb_rx++] = first_seg;
861 : :
862 : 0 : stats->rx_bytes += first_seg->pkt_len;
863 : 0 : stats->rx_packets++;
864 : :
865 : : /*
866 : : * Setup receipt context for a new packet.
867 : : */
868 : : first_seg = NULL;
869 : : }
870 : : }
871 : :
872 : : /*
873 : : * Record index of the next RX descriptor to probe.
874 : : */
875 : 0 : rxq->rx_tail = tail;
876 : :
877 : : /*
878 : : * Save receive context.
879 : : */
880 : 0 : rxq->pkt_first_seg = first_seg;
881 : 0 : rxq->pkt_last_seg = last_seg;
882 : :
883 : 0 : nb_hold = (uint16_t)(nb_hold + rxq->nb_rx_hold);
884 [ # # ]: 0 : if (nb_hold > rxq->rx_free_thresh) {
885 : : rte_wmb();
886 : :
887 : : /* Clear RDU */
888 : 0 : rtl_clear_rdu(hw);
889 : :
890 : : nb_hold = 0;
891 : : }
892 : :
893 : 0 : rxq->nb_rx_hold = nb_hold;
894 : :
895 : 0 : return nb_rx;
896 : : }
897 : :
898 : : /* ---------------------------------TX---------------------------------- */
899 : : static void
900 : 0 : rtl_tx_queue_release_mbufs(struct rtl_tx_queue *txq)
901 : : {
902 : : int i;
903 : :
904 : 0 : PMD_INIT_FUNC_TRACE();
905 : :
906 [ # # ]: 0 : if (txq != NULL) {
907 [ # # ]: 0 : if (txq->sw_ring != NULL) {
908 [ # # ]: 0 : for (i = 0; i < txq->nb_tx_desc; i++) {
909 [ # # ]: 0 : if (txq->sw_ring[i].mbuf != NULL) {
910 : : rte_pktmbuf_free_seg(txq->sw_ring[i].mbuf);
911 : 0 : txq->sw_ring[i].mbuf = NULL;
912 : : }
913 : : }
914 : : }
915 : : }
916 : 0 : }
917 : :
918 : : void
919 : 0 : rtl_tx_queue_release(struct rte_eth_dev *dev, uint16_t tx_queue_id)
920 : : {
921 : 0 : struct rtl_tx_queue *txq = dev->data->tx_queues[tx_queue_id];
922 : :
923 : 0 : PMD_INIT_FUNC_TRACE();
924 : :
925 [ # # ]: 0 : if (txq != NULL) {
926 : 0 : rtl_tx_queue_release_mbufs(txq);
927 : 0 : rte_free(txq->sw_ring);
928 : 0 : rte_free(txq);
929 : : }
930 : 0 : }
931 : :
932 : : void
933 : 0 : rtl_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
934 : : struct rte_eth_txq_info *qinfo)
935 : : {
936 : : struct rtl_tx_queue *txq;
937 : :
938 : 0 : txq = dev->data->tx_queues[queue_id];
939 : :
940 : 0 : qinfo->nb_desc = txq->nb_tx_desc;
941 : 0 : }
942 : :
943 : : static void
944 : : rtl_reset_tx_queue(struct rtl_tx_queue *txq)
945 : : {
946 : : static const struct rtl_tx_desc zero_txd = {0};
947 : : int i;
948 : :
949 [ # # # # ]: 0 : for (i = 0; i < txq->nb_tx_desc; i++)
950 : 0 : txq->hw_ring[i] = zero_txd;
951 : :
952 : 0 : txq->hw_ring[txq->nb_tx_desc - 1].opts1 = rte_cpu_to_le_32(RingEnd);
953 : :
954 : 0 : txq->tx_tail = 0;
955 : 0 : txq->tx_head = 0;
956 : 0 : txq->tx_free = txq->nb_tx_desc - 1;
957 : : }
958 : :
959 : : uint64_t
960 : 0 : rtl_get_tx_port_offloads(void)
961 : : {
962 : : uint64_t tx_offload_capa;
963 : :
964 : : tx_offload_capa = RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
965 : : RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
966 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
967 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
968 : : RTE_ETH_TX_OFFLOAD_TCP_TSO |
969 : : RTE_ETH_TX_OFFLOAD_MULTI_SEGS;
970 : :
971 : 0 : return tx_offload_capa;
972 : : }
973 : :
974 : : int
975 : 0 : rtl_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx,
976 : : uint16_t nb_tx_desc, unsigned int socket_id,
977 : : const struct rte_eth_txconf *tx_conf)
978 : : {
979 : : struct rtl_tx_queue *txq;
980 : : const struct rte_memzone *mz;
981 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
982 : 0 : struct rtl_hw *hw = &adapter->hw;
983 : : u32 size;
984 : :
985 : 0 : PMD_INIT_FUNC_TRACE();
986 : :
987 : : /*
988 : : * If this queue existed already, free the associated memory. The
989 : : * queue cannot be reused in case we need to allocate memory on
990 : : * different socket than was previously used.
991 : : */
992 [ # # ]: 0 : if (dev->data->tx_queues[queue_idx] != NULL) {
993 : 0 : rtl_tx_queue_release(dev, queue_idx);
994 : 0 : dev->data->tx_queues[queue_idx] = NULL;
995 : : }
996 : :
997 : 0 : txq = rte_zmalloc_socket("r8169 TX queue", sizeof(struct rtl_tx_queue),
998 : : RTE_CACHE_LINE_SIZE, socket_id);
999 : :
1000 [ # # ]: 0 : if (!txq) {
1001 : 0 : PMD_INIT_LOG(ERR, "Cannot allocate Tx queue structure");
1002 : 0 : return -ENOMEM;
1003 : : }
1004 : :
1005 : : /* Setup queue */
1006 : 0 : txq->nb_tx_desc = nb_tx_desc;
1007 : 0 : txq->port_id = dev->data->port_id;
1008 : 0 : txq->queue_id = queue_idx;
1009 : 0 : txq->tx_free_thresh = tx_conf->tx_free_thresh;
1010 : :
1011 : : /* Allocate memory for the software ring */
1012 : 0 : txq->sw_ring = rte_calloc("r8169 sw tx ring", nb_tx_desc,
1013 : : sizeof(struct rtl_tx_entry), RTE_CACHE_LINE_SIZE);
1014 : :
1015 [ # # ]: 0 : if (txq->sw_ring == NULL) {
1016 : 0 : PMD_INIT_LOG(ERR,
1017 : : "Port %d: Cannot allocate software ring for queue %d",
1018 : : txq->port_id, txq->queue_id);
1019 : 0 : rte_free(txq);
1020 : 0 : return -ENOMEM;
1021 : : }
1022 : :
1023 : : /*
1024 : : * Allocate TX ring hardware descriptors. A memzone large enough to
1025 : : * handle the maximum ring size is allocated in order to allow for
1026 : : * resizing in later calls to the queue setup function.
1027 : : */
1028 : 0 : size = sizeof(struct rtl_tx_desc) * (nb_tx_desc + 1);
1029 : 0 : mz = rte_eth_dma_zone_reserve(dev, "tx_ring", queue_idx, size,
1030 : : RTL_RING_ALIGN, socket_id);
1031 [ # # ]: 0 : if (mz == NULL) {
1032 : 0 : PMD_INIT_LOG(ERR,
1033 : : "Port %d: Cannot allocate hardware ring for queue %d",
1034 : : txq->port_id, txq->queue_id);
1035 : 0 : rtl_tx_queue_release(dev, txq->queue_id);
1036 : 0 : return -ENOMEM;
1037 : : }
1038 : :
1039 : 0 : txq->hw = hw;
1040 : 0 : txq->hw_ring = mz->addr;
1041 : 0 : txq->hw_ring_phys_addr = mz->iova;
1042 : :
1043 : : rtl_reset_tx_queue(txq);
1044 : :
1045 : : /* EnableTxNoClose */
1046 : 0 : hw->NextHwDesCloPtr0 = 0;
1047 : 0 : hw->BeginHwDesCloPtr0 = 0;
1048 : :
1049 : 0 : dev->data->tx_queues[queue_idx] = txq;
1050 : :
1051 : 0 : return 0;
1052 : : }
1053 : :
1054 : : static void
1055 : 0 : rtl8125_set_tx_tag_num(struct rtl_hw *hw)
1056 : : {
1057 : : u32 mac_ocp_data;
1058 : :
1059 : 0 : mac_ocp_data = rtl_mac_ocp_read(hw, 0xE614);
1060 : 0 : mac_ocp_data &= ~(BIT_10 | BIT_9 | BIT_8);
1061 [ # # # # ]: 0 : switch (hw->mcfg) {
1062 : 0 : case CFG_METHOD_50:
1063 : : case CFG_METHOD_51:
1064 : : case CFG_METHOD_53:
1065 : 0 : mac_ocp_data |= (2 << 8);
1066 : 0 : break;
1067 : 0 : case CFG_METHOD_69:
1068 : : case CFG_METHOD_70:
1069 : : case CFG_METHOD_71:
1070 [ # # ]: 0 : if (hw->EnableTxNoClose)
1071 : 0 : mac_ocp_data |= (4 << 8);
1072 : : else
1073 : 0 : mac_ocp_data |= (3 << 8);
1074 : : break;
1075 : 0 : case CFG_METHOD_91:
1076 : 0 : mac_ocp_data |= (15 << 8);
1077 : 0 : break;
1078 : 0 : default:
1079 : 0 : mac_ocp_data |= (3 << 8);
1080 : 0 : break;
1081 : : }
1082 : 0 : rtl_mac_ocp_write(hw, 0xE614, mac_ocp_data);
1083 : 0 : }
1084 : :
1085 : : /* Set MTPS: Max Tx Pkt Size */
1086 : : static void
1087 : : rtl8168_set_mtps(struct rtl_hw *hw)
1088 : : {
1089 [ # # ]: 0 : if (hw->mtu > RTE_ETHER_MTU)
1090 : 0 : RTL_W8(hw, MTPS, 0x27);
1091 : : else
1092 : 0 : RTL_W8(hw, MTPS, 0x3F);
1093 : : }
1094 : :
1095 : : int
1096 : 0 : rtl_tx_init(struct rte_eth_dev *dev)
1097 : : {
1098 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
1099 : 0 : struct rtl_hw *hw = &adapter->hw;
1100 : : struct rtl_tx_queue *txq;
1101 : :
1102 : 0 : txq = dev->data->tx_queues[0];
1103 : :
1104 : 0 : RTL_W32(hw, TxDescStartAddrLow,
1105 : : ((u64)txq->hw_ring_phys_addr & DMA_BIT_MASK(32)));
1106 : 0 : RTL_W32(hw, TxDescStartAddrHigh, ((u64)txq->hw_ring_phys_addr >> 32));
1107 : :
1108 : 0 : rtl_enable_cfg9346_write(hw);
1109 : :
1110 [ # # ]: 0 : if (rtl_is_8125(hw)) {
1111 : 0 : rtl8125_set_tx_tag_num(hw);
1112 : :
1113 : 0 : RTL_W8(hw, TDFNR, 0x10);
1114 : : } else {
1115 : : rtl8168_set_mtps(hw);
1116 : :
1117 : 0 : RTL_W8(hw, TDFNR, 0x4);
1118 : : }
1119 : :
1120 : 0 : rtl_disable_cfg9346_write(hw);
1121 : :
1122 : 0 : RTL_W8(hw, ChipCmd, RTL_R8(hw, ChipCmd) | CmdTxEnb);
1123 : :
1124 : 0 : dev->data->tx_queue_state[0] = RTE_ETH_QUEUE_STATE_STARTED;
1125 : :
1126 : 0 : return 0;
1127 : : }
1128 : :
1129 : : static inline uint32_t
1130 : : rtl_tx_vlan_tag(struct rte_mbuf *tx_pkt, uint64_t ol_flags)
1131 : : {
1132 : 0 : return (ol_flags & RTE_MBUF_F_TX_VLAN) ?
1133 [ # # ]: 0 : (TxVlanTag | rte_bswap16(tx_pkt->vlan_tci)) :
1134 : : 0;
1135 : : }
1136 : :
1137 : : static inline int
1138 : 0 : rtl_tso_setup(struct rte_mbuf *tx_pkt, uint64_t ol_flags, u32 *opts)
1139 : : {
1140 : : uint32_t mss;
1141 : : uint64_t l4_offset;
1142 : :
1143 : : /* Check if TCP segmentation required for this packet */
1144 [ # # ]: 0 : if (ol_flags & RTE_MBUF_F_TX_TCP_SEG) {
1145 : 0 : mss = tx_pkt->tso_segsz;
1146 : 0 : l4_offset = tx_pkt->l2_len + tx_pkt->l3_len;
1147 [ # # ]: 0 : if (l4_offset <= GTTCPHO_MAX) {
1148 : : /* Implies IP cksum in IPv4 */
1149 [ # # ]: 0 : if (ol_flags & RTE_MBUF_F_TX_IP_CKSUM)
1150 : 0 : opts[0] |= GiantSendv4;
1151 : : else
1152 : 0 : opts[0] |= GiantSendv6;
1153 : :
1154 : 0 : opts[0] |= l4_offset << GTTCPHO_SHIFT;
1155 : 0 : opts[1] |= RTE_MIN(mss, MSS_MAX) << 18;
1156 : :
1157 : 0 : return 1;
1158 : : }
1159 : : }
1160 : :
1161 : : return 0;
1162 : : }
1163 : :
1164 : : static inline void
1165 : 0 : rtl_setup_csum_offload(struct rte_mbuf *tx_pkt, uint64_t ol_flags,
1166 : : uint32_t *opts)
1167 : : {
1168 : : uint32_t csum_cmd = 0;
1169 : : uint64_t l4_offset;
1170 : :
1171 [ # # ]: 0 : if (ol_flags & RTE_MBUF_F_TX_IP_CKSUM)
1172 : : csum_cmd |= TxIPCS_C;
1173 : :
1174 [ # # # ]: 0 : switch (ol_flags & RTE_MBUF_F_TX_L4_MASK) {
1175 : 0 : case RTE_MBUF_F_TX_UDP_CKSUM:
1176 : 0 : csum_cmd |= TxUDPCS_C;
1177 : 0 : break;
1178 : 0 : case RTE_MBUF_F_TX_TCP_CKSUM:
1179 : 0 : csum_cmd |= TxTCPCS_C;
1180 : 0 : break;
1181 : : }
1182 : :
1183 [ # # ]: 0 : if (csum_cmd != 0) {
1184 [ # # ]: 0 : if (ol_flags & RTE_MBUF_F_TX_IPV6) {
1185 : 0 : l4_offset = tx_pkt->l2_len + tx_pkt->l3_len;
1186 : 0 : csum_cmd |= TxIPV6F_C;
1187 : 0 : csum_cmd |= l4_offset << TCPHO_SHIFT;
1188 : : } else {
1189 : 0 : csum_cmd |= TxIPCS_C;
1190 : : }
1191 : 0 : opts[1] |= csum_cmd;
1192 : : }
1193 : 0 : }
1194 : :
1195 : : static uint32_t
1196 : 0 : rtl8125_get_patch_pad_len(struct rte_mbuf *tx_pkt)
1197 : : {
1198 : : uint16_t dest_port;
1199 : : uint32_t pad_len = 0;
1200 : : int udp_hdr_len = sizeof(struct rte_udp_hdr);
1201 : : int trans_data_len, l4_offset;
1202 : : struct rte_udp_hdr *udp_hdr;
1203 : :
1204 [ # # # # ]: 0 : if (!(tx_pkt->l4_len && tx_pkt->data_len < 175))
1205 : 0 : goto no_padding;
1206 : :
1207 : 0 : l4_offset = tx_pkt->l2_len + tx_pkt->l3_len;
1208 : 0 : trans_data_len = tx_pkt->data_len - l4_offset;
1209 : :
1210 [ # # ]: 0 : if (trans_data_len > 3 && trans_data_len < MIN_PATCH_LENGTH) {
1211 : 0 : udp_hdr = rte_pktmbuf_mtod_offset(tx_pkt, struct rte_udp_hdr *, l4_offset);
1212 [ # # ]: 0 : dest_port = ntohs(udp_hdr->dst_port);
1213 [ # # ]: 0 : if (dest_port == 0x13f || dest_port == 0x140) {
1214 : 0 : pad_len = MIN_PATCH_LENGTH - trans_data_len;
1215 : 0 : goto out;
1216 : : }
1217 : : }
1218 : :
1219 [ # # ]: 0 : if (trans_data_len < udp_hdr_len)
1220 : 0 : pad_len = udp_hdr_len - trans_data_len;
1221 : :
1222 : 0 : out:
1223 [ # # ]: 0 : if ((tx_pkt->data_len + pad_len) < ETH_ZLEN)
1224 : 0 : pad_len = ETH_ZLEN - tx_pkt->data_len;
1225 : :
1226 : : return pad_len;
1227 : :
1228 : : no_padding:
1229 : :
1230 : 0 : return 0;
1231 : : }
1232 : :
1233 : : static void
1234 : 0 : rtl8125_ptp_patch(struct rte_mbuf *tx_pkt)
1235 : : {
1236 : : uint32_t pad_len;
1237 : : char *padding;
1238 : :
1239 [ # # ]: 0 : if (tx_pkt->packet_type & RTE_PTYPE_L4_UDP) {
1240 : 0 : pad_len = rtl8125_get_patch_pad_len(tx_pkt);
1241 [ # # ]: 0 : if (pad_len > 0) {
1242 : 0 : padding = rte_pktmbuf_append(tx_pkt, pad_len);
1243 [ # # ]: 0 : if (unlikely(padding == NULL))
1244 : 0 : PMD_DRV_LOG(ERR, "Not enough mbuf trailing space.");
1245 : 0 : memset(padding, 0, pad_len);
1246 : : }
1247 : : }
1248 : 0 : }
1249 : :
1250 : : static inline void
1251 : 0 : rtl_xmit_pkt(struct rtl_hw *hw, struct rtl_tx_queue *txq,
1252 : : struct rte_mbuf *tx_pkt)
1253 : : {
1254 : : struct rte_mbuf *m_seg;
1255 : 0 : struct rte_eth_dev *dev = &rte_eth_devices[txq->port_id];
1256 : 0 : struct rtl_adapter *adapter = RTL_DEV_PRIVATE(dev);
1257 : : struct rtl_sw_stats *stats = &adapter->sw_stats;
1258 : : struct rtl_tx_desc *txd;
1259 : : struct rtl_tx_entry *txe = NULL;
1260 : : uint16_t desc_count = 0;
1261 : 0 : const uint16_t nb_tx_desc = txq->nb_tx_desc;
1262 : : uint16_t tail;
1263 : : u32 len;
1264 : : u32 opts[2] = {0};
1265 : : u32 opts1;
1266 : : u32 opts2;
1267 : : int large_send;
1268 : : uint64_t buf_dma_addr;
1269 : : uint64_t ol_flags;
1270 : : uint64_t tx_ol_flags;
1271 : :
1272 : : /* Like cur_tx */
1273 : 0 : tail = (uint16_t)(txq->tx_tail % nb_tx_desc);
1274 : :
1275 : : /* If hardware offload required */
1276 : 0 : ol_flags = tx_pkt->ol_flags;
1277 : 0 : tx_ol_flags = ol_flags & RTL_TX_OFFLOAD_MASK;
1278 : :
1279 [ # # ]: 0 : opts[0] = DescOwn;
1280 : 0 : opts[1] = rtl_tx_vlan_tag(tx_pkt, tx_ol_flags);
1281 : :
1282 : 0 : large_send = rtl_tso_setup(tx_pkt, tx_ol_flags, opts);
1283 : :
1284 : : /* No TSO */
1285 [ # # ]: 0 : if (large_send == 0) {
1286 : 0 : rtl_setup_csum_offload(tx_pkt, tx_ol_flags, opts);
1287 : :
1288 [ # # ]: 0 : switch (hw->mcfg) {
1289 : 0 : case CFG_METHOD_48:
1290 : : case CFG_METHOD_49:
1291 : : case CFG_METHOD_50:
1292 : : case CFG_METHOD_51:
1293 : : case CFG_METHOD_52:
1294 : : case CFG_METHOD_53:
1295 : 0 : rtl8125_ptp_patch(tx_pkt);
1296 : 0 : break;
1297 : : }
1298 : : }
1299 : :
1300 [ # # ]: 0 : for (m_seg = tx_pkt; m_seg; m_seg = m_seg->next) {
1301 : 0 : opts1 = opts[0];
1302 : 0 : opts2 = opts[1];
1303 : :
1304 : 0 : len = m_seg->data_len;
1305 : :
1306 [ # # ]: 0 : if (len == 0)
1307 : : break;
1308 : :
1309 [ # # ]: 0 : txd = &txq->hw_ring[tail];
1310 : :
1311 : : buf_dma_addr = rte_mbuf_data_iova(m_seg);
1312 : 0 : txd->addr = rte_cpu_to_le_64(buf_dma_addr);
1313 : :
1314 : 0 : opts1 |= len;
1315 [ # # ]: 0 : if (m_seg == tx_pkt)
1316 : 0 : opts1 |= FirstFrag;
1317 [ # # ]: 0 : if (!m_seg->next)
1318 : 0 : opts1 |= LastFrag;
1319 [ # # ]: 0 : if (tail == nb_tx_desc - 1)
1320 : 0 : opts1 |= RingEnd;
1321 : :
1322 : : /* Store mbuf for freeing later */
1323 : 0 : txe = &txq->sw_ring[tail];
1324 : :
1325 [ # # ]: 0 : if (txe->mbuf)
1326 : : rte_pktmbuf_free_seg(txe->mbuf);
1327 : :
1328 : 0 : txe->mbuf = m_seg;
1329 : :
1330 : 0 : txd->opts2 = rte_cpu_to_le_32(opts2);
1331 : : rte_wmb();
1332 : 0 : txd->opts1 = rte_cpu_to_le_32(opts1);
1333 : :
1334 : 0 : tail = (tail + 1) % nb_tx_desc;
1335 : :
1336 : 0 : desc_count++;
1337 : :
1338 : 0 : stats->tx_bytes += len;
1339 : : }
1340 : :
1341 : 0 : txq->tx_tail += desc_count;
1342 : 0 : txq->tx_free -= desc_count;
1343 : :
1344 : 0 : stats->tx_packets++;
1345 : 0 : }
1346 : :
1347 : : static inline u32
1348 : : rtl_fast_mod_mask(const u32 input, const u32 mask)
1349 : : {
1350 : 0 : return input > mask ? input & mask : input;
1351 : : }
1352 : :
1353 : : static u32
1354 : : rtl_get_hw_clo_ptr(struct rtl_hw *hw)
1355 : : {
1356 [ # # # # : 0 : switch (hw->HwSuppTxNoCloseVer) {
# # ]
1357 : 0 : case 3:
1358 : 0 : return RTL_R16(hw, hw->hw_clo_ptr_reg);
1359 : 0 : case 4:
1360 : : case 5:
1361 : : case 6:
1362 : 0 : return RTL_R32(hw, hw->hw_clo_ptr_reg);
1363 : : default:
1364 : : return 0;
1365 : : }
1366 : : }
1367 : :
1368 : : static u32
1369 : : rtl_get_opts1(struct rtl_tx_desc *txd)
1370 : : {
1371 : 0 : u32 opts1 = rte_atomic_load_explicit(&txd->opts1, rte_memory_order_acquire);
1372 : :
1373 : : return rte_le_to_cpu_32(opts1);
1374 : : }
1375 : :
1376 : : static void
1377 : 0 : rtl8125_tx_clean(struct rtl_hw *hw, struct rtl_tx_queue *txq)
1378 : : {
1379 : 0 : struct rtl_tx_entry *sw_ring = txq->sw_ring;
1380 : : struct rtl_tx_entry *txe;
1381 : : struct rtl_tx_desc *txd;
1382 : 0 : const uint8_t enable_tx_no_close = hw->EnableTxNoClose;
1383 : 0 : const uint16_t nb_tx_desc = txq->nb_tx_desc;
1384 : 0 : uint16_t head = txq->tx_head;
1385 : : uint16_t desc_freed = 0;
1386 : : uint32_t tx_left;
1387 : : uint32_t tx_desc_closed, next_hw_desc_clo_ptr0;
1388 : :
1389 : : if (!txq)
1390 : : return;
1391 : :
1392 [ # # ]: 0 : if (enable_tx_no_close) {
1393 : : next_hw_desc_clo_ptr0 = rtl_get_hw_clo_ptr(hw);
1394 : 0 : hw->NextHwDesCloPtr0 = next_hw_desc_clo_ptr0;
1395 : 0 : tx_desc_closed = rtl_fast_mod_mask(next_hw_desc_clo_ptr0 -
1396 [ # # ]: 0 : hw->BeginHwDesCloPtr0, hw->MaxTxDescPtrMask);
1397 : 0 : tx_left = RTE_MIN(((rte_atomic_load_explicit(&txq->tx_tail,
1398 : : rte_memory_order_relaxed) % nb_tx_desc) - head),
1399 : : tx_desc_closed);
1400 : 0 : hw->BeginHwDesCloPtr0 += tx_left;
1401 : : } else {
1402 : 0 : tx_left = (rte_atomic_load_explicit(&txq->tx_tail,
1403 : 0 : rte_memory_order_relaxed) % nb_tx_desc) - head;
1404 : : }
1405 : :
1406 [ # # ]: 0 : while (tx_left > 0) {
1407 : 0 : txd = &txq->hw_ring[head];
1408 : :
1409 [ # # # # ]: 0 : if (!enable_tx_no_close && (rtl_get_opts1(txd) & DescOwn))
1410 : : break;
1411 : :
1412 : 0 : txe = &sw_ring[head];
1413 [ # # ]: 0 : if (txe->mbuf) {
1414 : : rte_pktmbuf_free_seg(txe->mbuf);
1415 : 0 : txe->mbuf = NULL;
1416 : : }
1417 : :
1418 : 0 : head = (head + 1) % nb_tx_desc;
1419 : 0 : desc_freed++;
1420 : 0 : tx_left--;
1421 : : }
1422 : 0 : txq->tx_free += desc_freed;
1423 : 0 : txq->tx_head = head;
1424 : : }
1425 : :
1426 : : static void
1427 : 0 : rtl8168_tx_clean(struct rtl_hw *hw __rte_unused, struct rtl_tx_queue *txq)
1428 : : {
1429 : 0 : struct rtl_tx_entry *sw_ring = txq->sw_ring;
1430 : : struct rtl_tx_entry *txe;
1431 : : struct rtl_tx_desc *txd;
1432 : 0 : const uint16_t nb_tx_desc = txq->nb_tx_desc;
1433 : 0 : const int tx_tail = txq->tx_tail % nb_tx_desc;
1434 : 0 : int head = txq->tx_head;
1435 : : uint16_t desc_freed = 0;
1436 : :
1437 : : if (!txq)
1438 : : return;
1439 : :
1440 : : while (1) {
1441 : 0 : txd = &txq->hw_ring[head];
1442 : :
1443 [ # # ]: 0 : if (rtl_get_opts1(txd) & DescOwn)
1444 : : break;
1445 : :
1446 : 0 : txe = &sw_ring[head];
1447 [ # # ]: 0 : if (txe->mbuf) {
1448 : : rte_pktmbuf_free_seg(txe->mbuf);
1449 : 0 : txe->mbuf = NULL;
1450 : : }
1451 : :
1452 : 0 : head = (head + 1) % nb_tx_desc;
1453 : 0 : desc_freed++;
1454 : :
1455 [ # # ]: 0 : if (head == tx_tail)
1456 : : break;
1457 : : }
1458 : :
1459 : 0 : txq->tx_free += desc_freed;
1460 : 0 : txq->tx_head = head;
1461 : : }
1462 : :
1463 : : static void
1464 : 0 : rtl_tx_clean(struct rtl_hw *hw, struct rtl_tx_queue *txq)
1465 : : {
1466 [ # # ]: 0 : if (rtl_is_8125(hw))
1467 : 0 : rtl8125_tx_clean(hw, txq);
1468 : : else
1469 : 0 : rtl8168_tx_clean(hw, txq);
1470 : 0 : }
1471 : :
1472 : : static int
1473 : 0 : rtl8125_tx_done_cleanup(void *tx_queue, uint32_t free_cnt)
1474 : : {
1475 : : struct rtl_tx_queue *txq = tx_queue;
1476 : 0 : struct rtl_hw *hw = txq->hw;
1477 : 0 : struct rtl_tx_entry *sw_ring = txq->sw_ring;
1478 : : struct rtl_tx_entry *txe;
1479 : : struct rtl_tx_desc *txd;
1480 : 0 : const uint8_t enable_tx_no_close = hw->EnableTxNoClose;
1481 : 0 : const uint16_t nb_tx_desc = txq->nb_tx_desc;
1482 : 0 : uint16_t head = txq->tx_head;
1483 : : uint16_t desc_freed = 0;
1484 : : uint32_t tx_left;
1485 : : uint32_t count = 0;
1486 : : uint32_t status;
1487 : : uint32_t tx_desc_closed, next_hw_desc_clo_ptr0;
1488 : :
1489 : : if (!txq)
1490 : : return -ENODEV;
1491 : :
1492 [ # # ]: 0 : if (enable_tx_no_close) {
1493 : : next_hw_desc_clo_ptr0 = rtl_get_hw_clo_ptr(hw);
1494 : 0 : hw->NextHwDesCloPtr0 = next_hw_desc_clo_ptr0;
1495 : 0 : tx_desc_closed = rtl_fast_mod_mask(next_hw_desc_clo_ptr0 -
1496 [ # # ]: 0 : hw->BeginHwDesCloPtr0, hw->MaxTxDescPtrMask);
1497 : 0 : tx_left = RTE_MIN(((rte_atomic_load_explicit(&txq->tx_tail,
1498 : : rte_memory_order_relaxed) % nb_tx_desc) - head),
1499 : : tx_desc_closed);
1500 : 0 : hw->BeginHwDesCloPtr0 += tx_left;
1501 : : } else {
1502 : 0 : tx_left = (rte_atomic_load_explicit(&txq->tx_tail,
1503 : 0 : rte_memory_order_relaxed) % nb_tx_desc) - head;
1504 : : }
1505 : :
1506 [ # # ]: 0 : while (tx_left > 0) {
1507 : 0 : txd = &txq->hw_ring[head];
1508 : :
1509 : : status = rtl_get_opts1(txd);
1510 : :
1511 [ # # ]: 0 : if (!enable_tx_no_close && (status & DescOwn))
1512 : : break;
1513 : :
1514 : 0 : txe = &sw_ring[head];
1515 [ # # ]: 0 : if (txe->mbuf) {
1516 : : rte_pktmbuf_free_seg(txe->mbuf);
1517 : 0 : txe->mbuf = NULL;
1518 : : }
1519 : :
1520 : 0 : head = (head + 1) % nb_tx_desc;
1521 : :
1522 : 0 : desc_freed++;
1523 : 0 : tx_left--;
1524 : :
1525 [ # # ]: 0 : if (status & LastFrag) {
1526 : 0 : count++;
1527 [ # # ]: 0 : if (count == free_cnt)
1528 : : break;
1529 : : }
1530 : : }
1531 : :
1532 : 0 : txq->tx_free += desc_freed;
1533 : 0 : txq->tx_head = head;
1534 : :
1535 : 0 : return count;
1536 : : }
1537 : :
1538 : : static int
1539 : 0 : rtl8168_tx_done_cleanup(void *tx_queue, uint32_t free_cnt)
1540 : : {
1541 : : struct rtl_tx_queue *txq = tx_queue;
1542 : 0 : struct rtl_tx_entry *sw_ring = txq->sw_ring;
1543 : : struct rtl_tx_entry *txe;
1544 : : struct rtl_tx_desc *txd;
1545 : 0 : const uint16_t nb_tx_desc = txq->nb_tx_desc;
1546 : 0 : const int tx_tail = txq->tx_tail % nb_tx_desc;
1547 : 0 : int head = txq->tx_head;
1548 : : uint16_t desc_freed = 0;
1549 : : int count = 0;
1550 : : uint32_t status;
1551 : :
1552 : : if (!txq)
1553 : : return -ENODEV;
1554 : :
1555 : : while (1) {
1556 : 0 : txd = &txq->hw_ring[head];
1557 : :
1558 : : status = rtl_get_opts1(txd);
1559 : :
1560 [ # # ]: 0 : if (status & DescOwn)
1561 : : break;
1562 : :
1563 : 0 : txe = &sw_ring[head];
1564 [ # # ]: 0 : if (txe->mbuf) {
1565 : : rte_pktmbuf_free_seg(txe->mbuf);
1566 : 0 : txe->mbuf = NULL;
1567 : : }
1568 : :
1569 : 0 : head = (head + 1) % nb_tx_desc;
1570 : 0 : desc_freed++;
1571 : :
1572 [ # # ]: 0 : if (status & LastFrag) {
1573 : 0 : count++;
1574 [ # # ]: 0 : if ((uint32_t)count == free_cnt)
1575 : : break;
1576 : : }
1577 : :
1578 [ # # ]: 0 : if (head == tx_tail)
1579 : : break;
1580 : : }
1581 : :
1582 : 0 : txq->tx_free += desc_freed;
1583 : 0 : txq->tx_head = head;
1584 : :
1585 : : return count;
1586 : : }
1587 : :
1588 : : int
1589 : 0 : rtl_tx_done_cleanup(void *tx_queue, uint32_t free_cnt)
1590 : : {
1591 : : struct rtl_tx_queue *txq = tx_queue;
1592 : 0 : struct rtl_hw *hw = txq->hw;
1593 : :
1594 [ # # ]: 0 : if (rtl_is_8125(hw))
1595 : 0 : return rtl8125_tx_done_cleanup(tx_queue, free_cnt);
1596 : : else
1597 : 0 : return rtl8168_tx_done_cleanup(tx_queue, free_cnt);
1598 : : }
1599 : :
1600 : : static void
1601 : : rtl8125_doorbell(struct rtl_hw *hw, struct rtl_tx_queue *txq)
1602 : : {
1603 [ # # ]: 0 : if (hw->EnableTxNoClose)
1604 [ # # ]: 0 : if (hw->HwSuppTxNoCloseVer > 3)
1605 : 0 : RTL_W32(hw, hw->sw_tail_ptr_reg, txq->tx_tail);
1606 : : else
1607 : 0 : RTL_W16(hw, hw->sw_tail_ptr_reg, txq->tx_tail);
1608 : : else
1609 : 0 : RTL_W16(hw, TPPOLL_8125, BIT_0);
1610 : : }
1611 : :
1612 : : static void
1613 : : rtl8168_doorbell(struct rtl_hw *hw)
1614 : : {
1615 : 0 : RTL_W8(hw, TxPoll, NPQ);
1616 : 0 : }
1617 : :
1618 : : static void
1619 : 0 : rtl_doorbell(struct rtl_hw *hw, struct rtl_tx_queue *txq)
1620 : : {
1621 [ # # ]: 0 : if (rtl_is_8125(hw))
1622 : : rtl8125_doorbell(hw, txq);
1623 : : else
1624 : : rtl8168_doorbell(hw);
1625 : 0 : }
1626 : :
1627 : : /* PMD transmit function */
1628 : : uint16_t
1629 : 0 : rtl_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
1630 : : {
1631 : : struct rtl_tx_queue *txq = tx_queue;
1632 : 0 : struct rtl_hw *hw = txq->hw;
1633 : : struct rte_mbuf *tx_pkt;
1634 : : uint16_t nb_tx;
1635 : :
1636 : : RTE_ASSERT(RTL_R8(hw, ChipCmd) & CmdTxEnb);
1637 : :
1638 : : PMD_TX_LOG(DEBUG,
1639 : : "port %d txq %d pkts: %d tx_free=%d tx_tail=%d tx_head=%d",
1640 : : txq->port_id, txq->queue_id, nb_pkts, txq->tx_free,
1641 : : txq->tx_tail, txq->tx_head);
1642 : :
1643 [ # # ]: 0 : for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
1644 : 0 : tx_pkt = *tx_pkts++;
1645 : :
1646 [ # # ]: 0 : if (txq->tx_free < tx_pkt->nb_segs)
1647 : : break;
1648 : :
1649 : : /* Check mbuf is valid */
1650 [ # # # # : 0 : if (tx_pkt->nb_segs == 0 || tx_pkt->pkt_len == 0 ||
# # ]
1651 [ # # ]: 0 : (tx_pkt->nb_segs > 1 && tx_pkt->next == NULL))
1652 : : break;
1653 : :
1654 : 0 : rtl_xmit_pkt(hw, txq, tx_pkt);
1655 : : }
1656 : :
1657 : : rte_wmb();
1658 : :
1659 [ # # ]: 0 : if (nb_tx > 0)
1660 : 0 : rtl_doorbell(hw, txq);
1661 : :
1662 : : PMD_TX_LOG(DEBUG, "%s %d transmitted", __func__, nb_tx);
1663 : :
1664 : 0 : rtl_tx_clean(hw, txq);
1665 : :
1666 : 0 : return nb_tx;
1667 : : }
1668 : :
1669 : : int
1670 : 0 : rtl_stop_queues(struct rte_eth_dev *dev)
1671 : : {
1672 : : struct rtl_tx_queue *txq;
1673 : : struct rtl_rx_queue *rxq;
1674 : :
1675 : 0 : PMD_INIT_FUNC_TRACE();
1676 : :
1677 : 0 : txq = dev->data->tx_queues[0];
1678 : :
1679 : 0 : rtl_tx_queue_release_mbufs(txq);
1680 : : rtl_reset_tx_queue(txq);
1681 : 0 : dev->data->tx_queue_state[0] = RTE_ETH_QUEUE_STATE_STOPPED;
1682 : :
1683 : 0 : rxq = dev->data->rx_queues[0];
1684 : :
1685 : 0 : rtl_rx_queue_release_mbufs(rxq);
1686 : : rtl_reset_rx_queue(rxq);
1687 : 0 : dev->data->rx_queue_state[0] = RTE_ETH_QUEUE_STATE_STOPPED;
1688 : :
1689 : 0 : return 0;
1690 : : }
1691 : :
1692 : : void
1693 : 0 : rtl_free_queues(struct rte_eth_dev *dev)
1694 : : {
1695 : 0 : PMD_INIT_FUNC_TRACE();
1696 : :
1697 : 0 : rte_eth_dma_zone_free(dev, "rx_ring", 0);
1698 : 0 : rtl_rx_queue_release(dev, 0);
1699 : 0 : dev->data->rx_queues[0] = 0;
1700 : 0 : dev->data->nb_rx_queues = 0;
1701 : :
1702 : 0 : rte_eth_dma_zone_free(dev, "tx_ring", 0);
1703 : 0 : rtl_tx_queue_release(dev, 0);
1704 : 0 : dev->data->tx_queues[0] = 0;
1705 : 0 : dev->data->nb_tx_queues = 0;
1706 : 0 : }
|