1
2
3
4
5
6
7#ifndef _NFB_TX_H_
8#define _NFB_TX_H_
9
10#include <nfb/nfb.h>
11#include <nfb/ndp.h>
12
13#include <ethdev_driver.h>
14#include <rte_ethdev.h>
15#include <rte_malloc.h>
16
17struct ndp_tx_queue {
18 struct nfb_device *nfb;
19 struct ndp_queue *queue;
20 uint16_t tx_queue_id;
21 volatile uint64_t tx_pkts;
22 volatile uint64_t tx_bytes;
23 volatile uint64_t err_pkts;
24};
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45int
46nfb_eth_tx_queue_setup(struct rte_eth_dev *dev,
47 uint16_t tx_queue_id,
48 uint16_t nb_tx_desc __rte_unused,
49 unsigned int socket_id,
50 const struct rte_eth_txconf *tx_conf __rte_unused);
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65int
66nfb_eth_tx_queue_init(struct nfb_device *nfb,
67 uint16_t tx_queue_id,
68 struct ndp_tx_queue *txq);
69
70
71
72
73
74
75
76void
77nfb_eth_tx_queue_release(void *q);
78
79
80
81
82
83
84
85
86
87
88
89
90int
91nfb_eth_tx_queue_start(struct rte_eth_dev *dev, uint16_t txq_id);
92
93
94
95
96
97
98
99
100
101
102
103
104int
105nfb_eth_tx_queue_stop(struct rte_eth_dev *dev, uint16_t txq_id);
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120static __rte_always_inline uint16_t
121nfb_eth_ndp_tx(void *queue,
122 struct rte_mbuf **bufs,
123 uint16_t nb_pkts)
124{
125 int i;
126 struct rte_mbuf *mbuf;
127 struct ndp_tx_queue *ndp = queue;
128 uint16_t num_tx = 0;
129 uint64_t num_bytes = 0;
130
131 void *dst;
132 uint32_t pkt_len;
133 uint8_t mbuf_segs;
134
135 struct ndp_packet packets[nb_pkts];
136
137 if (unlikely(ndp->queue == NULL || nb_pkts == 0)) {
138 RTE_LOG(ERR, PMD, "TX invalid arguments!\n");
139 return 0;
140 }
141
142 for (i = 0; i < nb_pkts; i++) {
143 packets[i].data_length = bufs[i]->pkt_len;
144 packets[i].header_length = 0;
145 }
146
147 num_tx = ndp_tx_burst_get(ndp->queue, packets, nb_pkts);
148
149 if (unlikely(num_tx != nb_pkts))
150 return 0;
151
152 for (i = 0; i < nb_pkts; ++i) {
153 mbuf = bufs[i];
154
155 pkt_len = mbuf->pkt_len;
156 mbuf_segs = mbuf->nb_segs;
157
158 num_bytes += pkt_len;
159 if (mbuf_segs == 1) {
160
161
162
163
164 rte_memcpy(packets[i].data,
165 rte_pktmbuf_mtod(mbuf, const void *),
166 pkt_len);
167 } else {
168
169 struct rte_mbuf *m = mbuf;
170 while (m) {
171 dst = packets[i].data;
172
173 rte_memcpy(dst,
174 rte_pktmbuf_mtod(m,
175 const void *),
176 m->data_len);
177 dst = ((uint8_t *)(dst)) +
178 m->data_len;
179 m = m->next;
180 }
181 }
182
183 rte_pktmbuf_free(mbuf);
184 }
185
186 ndp_tx_burst_flush(ndp->queue);
187
188 ndp->tx_pkts += num_tx;
189 ndp->err_pkts += nb_pkts - num_tx;
190 ndp->tx_bytes += num_bytes;
191 return num_tx;
192}
193
194#endif
195