Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2015-2020 Beijing WangXun Technology Co., Ltd.
3 : : * Copyright(c) 2010-2017 Intel Corporation
4 : : */
5 : :
6 : : #include <stdio.h>
7 : : #include <errno.h>
8 : : #include <stdint.h>
9 : : #include <string.h>
10 : : #include <rte_common.h>
11 : : #include <ethdev_pci.h>
12 : :
13 : : #include <rte_interrupts.h>
14 : : #include <rte_log.h>
15 : : #include <rte_debug.h>
16 : : #include <rte_pci.h>
17 : : #include <rte_memory.h>
18 : : #include <rte_eal.h>
19 : : #include <rte_alarm.h>
20 : : #include <rte_kvargs.h>
21 : :
22 : : #include "txgbe_logs.h"
23 : : #include "base/txgbe.h"
24 : : #include "txgbe_ethdev.h"
25 : : #include "txgbe_rxtx.h"
26 : : #include "txgbe_regs_group.h"
27 : :
28 : : static const struct reg_info txgbe_regs_general[] = {
29 : : {TXGBE_RST, 1, 1, "TXGBE_RST"},
30 : : {TXGBE_STAT, 1, 1, "TXGBE_STAT"},
31 : : {TXGBE_PORTCTL, 1, 1, "TXGBE_PORTCTL"},
32 : : {TXGBE_SDP, 1, 1, "TXGBE_SDP"},
33 : : {TXGBE_SDPCTL, 1, 1, "TXGBE_SDPCTL"},
34 : : {TXGBE_LEDCTL, 1, 1, "TXGBE_LEDCTL"},
35 : : {0, 0, 0, ""}
36 : : };
37 : :
38 : : static const struct reg_info txgbe_regs_nvm[] = {
39 : : {0, 0, 0, ""}
40 : : };
41 : :
42 : : static const struct reg_info txgbe_regs_interrupt[] = {
43 : : {0, 0, 0, ""}
44 : : };
45 : :
46 : : static const struct reg_info txgbe_regs_fctl_others[] = {
47 : : {0, 0, 0, ""}
48 : : };
49 : :
50 : : static const struct reg_info txgbe_regs_rxdma[] = {
51 : : {0, 0, 0, ""}
52 : : };
53 : :
54 : : static const struct reg_info txgbe_regs_rx[] = {
55 : : {0, 0, 0, ""}
56 : : };
57 : :
58 : : static struct reg_info txgbe_regs_tx[] = {
59 : : {0, 0, 0, ""}
60 : : };
61 : :
62 : : static const struct reg_info txgbe_regs_wakeup[] = {
63 : : {0, 0, 0, ""}
64 : : };
65 : :
66 : : static const struct reg_info txgbe_regs_dcb[] = {
67 : : {0, 0, 0, ""}
68 : : };
69 : :
70 : : static const struct reg_info txgbe_regs_mac[] = {
71 : : {0, 0, 0, ""}
72 : : };
73 : :
74 : : static const struct reg_info txgbe_regs_diagnostic[] = {
75 : : {0, 0, 0, ""},
76 : : };
77 : :
78 : : /* PF registers */
79 : : static const struct reg_info *txgbe_regs_others[] = {
80 : : txgbe_regs_general,
81 : : txgbe_regs_nvm,
82 : : txgbe_regs_interrupt,
83 : : txgbe_regs_fctl_others,
84 : : txgbe_regs_rxdma,
85 : : txgbe_regs_rx,
86 : : txgbe_regs_tx,
87 : : txgbe_regs_wakeup,
88 : : txgbe_regs_dcb,
89 : : txgbe_regs_mac,
90 : : txgbe_regs_diagnostic,
91 : : NULL};
92 : :
93 : : static int txgbe_fdir_filter_init(struct rte_eth_dev *eth_dev);
94 : : static int txgbe_fdir_filter_uninit(struct rte_eth_dev *eth_dev);
95 : : static int txgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev);
96 : : static int txgbe_l2_tn_filter_uninit(struct rte_eth_dev *eth_dev);
97 : : static int txgbe_dev_set_link_up(struct rte_eth_dev *dev);
98 : : static int txgbe_dev_set_link_down(struct rte_eth_dev *dev);
99 : : static int txgbe_dev_close(struct rte_eth_dev *dev);
100 : : static int txgbe_dev_link_update(struct rte_eth_dev *dev,
101 : : int wait_to_complete);
102 : : static int txgbe_dev_stats_reset(struct rte_eth_dev *dev);
103 : : static void txgbe_vlan_hw_strip_enable(struct rte_eth_dev *dev, uint16_t queue);
104 : : static void txgbe_vlan_hw_strip_disable(struct rte_eth_dev *dev,
105 : : uint16_t queue);
106 : :
107 : : static void txgbe_dev_link_status_print(struct rte_eth_dev *dev);
108 : : static int txgbe_dev_lsc_interrupt_setup(struct rte_eth_dev *dev, uint8_t on);
109 : : static int txgbe_dev_macsec_interrupt_setup(struct rte_eth_dev *dev);
110 : : static int txgbe_dev_misc_interrupt_setup(struct rte_eth_dev *dev);
111 : : static int txgbe_dev_rxq_interrupt_setup(struct rte_eth_dev *dev);
112 : : static int txgbe_dev_interrupt_get_status(struct rte_eth_dev *dev,
113 : : struct rte_intr_handle *handle);
114 : : static int txgbe_dev_interrupt_action(struct rte_eth_dev *dev,
115 : : struct rte_intr_handle *handle);
116 : : static void txgbe_dev_interrupt_handler(void *param);
117 : : static void txgbe_dev_detect_sfp(void *param);
118 : : static void txgbe_dev_interrupt_delayed_handler(void *param);
119 : : static void txgbe_configure_msix(struct rte_eth_dev *dev);
120 : :
121 : : static int txgbe_filter_restore(struct rte_eth_dev *dev);
122 : : static void txgbe_l2_tunnel_conf(struct rte_eth_dev *dev);
123 : :
124 : : #define TXGBE_SET_HWSTRIP(h, q) do {\
125 : : uint32_t idx = (q) / (sizeof((h)->bitmap[0]) * NBBY); \
126 : : uint32_t bit = (q) % (sizeof((h)->bitmap[0]) * NBBY); \
127 : : (h)->bitmap[idx] |= 1 << bit;\
128 : : } while (0)
129 : :
130 : : #define TXGBE_CLEAR_HWSTRIP(h, q) do {\
131 : : uint32_t idx = (q) / (sizeof((h)->bitmap[0]) * NBBY); \
132 : : uint32_t bit = (q) % (sizeof((h)->bitmap[0]) * NBBY); \
133 : : (h)->bitmap[idx] &= ~(1 << bit);\
134 : : } while (0)
135 : :
136 : : #define TXGBE_GET_HWSTRIP(h, q, r) do {\
137 : : uint32_t idx = (q) / (sizeof((h)->bitmap[0]) * NBBY); \
138 : : uint32_t bit = (q) % (sizeof((h)->bitmap[0]) * NBBY); \
139 : : (r) = (h)->bitmap[idx] >> bit & 1;\
140 : : } while (0)
141 : :
142 : : /*
143 : : * The set of PCI devices this driver supports
144 : : */
145 : : static const struct rte_pci_id pci_id_txgbe_map[] = {
146 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, TXGBE_DEV_ID_SP1000) },
147 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, TXGBE_DEV_ID_WX1820) },
148 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, TXGBE_DEV_ID_AML) },
149 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, TXGBE_DEV_ID_AML5025) },
150 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, TXGBE_DEV_ID_AML5125) },
151 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, TXGBE_DEV_ID_AML5040) },
152 : : { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, TXGBE_DEV_ID_AML5140) },
153 : : { .vendor_id = 0, /* sentinel */ },
154 : : };
155 : :
156 : : static const struct rte_eth_desc_lim rx_desc_lim = {
157 : : .nb_max = TXGBE_RING_DESC_MAX,
158 : : .nb_min = TXGBE_RING_DESC_MIN,
159 : : .nb_align = TXGBE_RXD_ALIGN,
160 : : };
161 : :
162 : : static const struct rte_eth_desc_lim tx_desc_lim = {
163 : : .nb_max = TXGBE_RING_DESC_MAX,
164 : : .nb_min = TXGBE_RING_DESC_MIN,
165 : : .nb_align = TXGBE_TXD_ALIGN,
166 : : .nb_seg_max = TXGBE_TX_MAX_SEG,
167 : : .nb_mtu_seg_max = TXGBE_TX_MAX_SEG,
168 : : };
169 : :
170 : : static const struct eth_dev_ops txgbe_eth_dev_ops;
171 : :
172 : : #define HW_XSTAT(m) {#m, offsetof(struct txgbe_hw_stats, m)}
173 : : #define HW_XSTAT_NAME(m, n) {n, offsetof(struct txgbe_hw_stats, m)}
174 : : static const struct rte_txgbe_xstats_name_off rte_txgbe_stats_strings[] = {
175 : : /* MNG RxTx */
176 : : HW_XSTAT(mng_bmc2host_packets),
177 : : HW_XSTAT(mng_host2bmc_packets),
178 : : /* Basic RxTx */
179 : : HW_XSTAT(rx_packets),
180 : : HW_XSTAT(tx_packets),
181 : : HW_XSTAT(rx_bytes),
182 : : HW_XSTAT(tx_bytes),
183 : : HW_XSTAT(rx_total_bytes),
184 : : HW_XSTAT(rx_total_packets),
185 : : HW_XSTAT(tx_total_packets),
186 : : HW_XSTAT(rx_total_missed_packets),
187 : : HW_XSTAT(rx_broadcast_packets),
188 : : HW_XSTAT(tx_broadcast_packets),
189 : : HW_XSTAT(rx_multicast_packets),
190 : : HW_XSTAT(tx_multicast_packets),
191 : : HW_XSTAT(rx_management_packets),
192 : : HW_XSTAT(tx_management_packets),
193 : : HW_XSTAT(rx_management_dropped),
194 : : HW_XSTAT(rx_dma_drop),
195 : :
196 : : /* Basic Error */
197 : : HW_XSTAT(rx_rdb_drop),
198 : : HW_XSTAT(rx_crc_errors),
199 : : HW_XSTAT(rx_illegal_byte_errors),
200 : : HW_XSTAT(rx_error_bytes),
201 : : HW_XSTAT(rx_mac_short_packet_dropped),
202 : : HW_XSTAT(rx_length_errors),
203 : : HW_XSTAT(rx_undersize_errors),
204 : : HW_XSTAT(rx_fragment_errors),
205 : : HW_XSTAT(rx_oversize_cnt),
206 : : HW_XSTAT(rx_jabber_errors),
207 : : HW_XSTAT(rx_l3_l4_xsum_error),
208 : : HW_XSTAT(mac_local_errors),
209 : : HW_XSTAT(mac_remote_errors),
210 : :
211 : : /* Flow Director */
212 : : HW_XSTAT(flow_director_added_filters),
213 : : HW_XSTAT(flow_director_removed_filters),
214 : : HW_XSTAT(flow_director_filter_add_errors),
215 : : HW_XSTAT(flow_director_filter_remove_errors),
216 : : HW_XSTAT(flow_director_matched_filters),
217 : : HW_XSTAT(flow_director_missed_filters),
218 : :
219 : : /* FCoE */
220 : : HW_XSTAT(rx_fcoe_crc_errors),
221 : : HW_XSTAT(rx_fcoe_mbuf_allocation_errors),
222 : : HW_XSTAT(rx_fcoe_dropped),
223 : : HW_XSTAT(rx_fcoe_packets),
224 : : HW_XSTAT(tx_fcoe_packets),
225 : : HW_XSTAT(rx_fcoe_bytes),
226 : : HW_XSTAT(tx_fcoe_bytes),
227 : : HW_XSTAT(rx_fcoe_no_ddp),
228 : : HW_XSTAT(rx_fcoe_no_ddp_ext_buff),
229 : :
230 : : /* MACSEC */
231 : : HW_XSTAT(tx_macsec_pkts_untagged),
232 : : HW_XSTAT(tx_macsec_pkts_encrypted),
233 : : HW_XSTAT(tx_macsec_pkts_protected),
234 : : HW_XSTAT(tx_macsec_octets_encrypted),
235 : : HW_XSTAT(tx_macsec_octets_protected),
236 : : HW_XSTAT(rx_macsec_pkts_untagged),
237 : : HW_XSTAT(rx_macsec_pkts_badtag),
238 : : HW_XSTAT(rx_macsec_pkts_nosci),
239 : : HW_XSTAT(rx_macsec_pkts_unknownsci),
240 : : HW_XSTAT(rx_macsec_octets_decrypted),
241 : : HW_XSTAT(rx_macsec_octets_validated),
242 : : HW_XSTAT(rx_macsec_sc_pkts_unchecked),
243 : : HW_XSTAT(rx_macsec_sc_pkts_delayed),
244 : : HW_XSTAT(rx_macsec_sc_pkts_late),
245 : : HW_XSTAT(rx_macsec_sa_pkts_ok),
246 : : HW_XSTAT(rx_macsec_sa_pkts_invalid),
247 : : HW_XSTAT(rx_macsec_sa_pkts_notvalid),
248 : : HW_XSTAT(rx_macsec_sa_pkts_unusedsa),
249 : : HW_XSTAT(rx_macsec_sa_pkts_notusingsa),
250 : :
251 : : /* MAC RxTx */
252 : : HW_XSTAT(rx_size_64_packets),
253 : : HW_XSTAT(rx_size_65_to_127_packets),
254 : : HW_XSTAT(rx_size_128_to_255_packets),
255 : : HW_XSTAT(rx_size_256_to_511_packets),
256 : : HW_XSTAT(rx_size_512_to_1023_packets),
257 : : HW_XSTAT(rx_size_1024_to_max_packets),
258 : : HW_XSTAT(tx_size_64_packets),
259 : : HW_XSTAT(tx_size_65_to_127_packets),
260 : : HW_XSTAT(tx_size_128_to_255_packets),
261 : : HW_XSTAT(tx_size_256_to_511_packets),
262 : : HW_XSTAT(tx_size_512_to_1023_packets),
263 : : HW_XSTAT(tx_size_1024_to_max_packets),
264 : :
265 : : /* Flow Control */
266 : : HW_XSTAT(tx_xon_packets),
267 : : HW_XSTAT(rx_xon_packets),
268 : : HW_XSTAT(tx_xoff_packets),
269 : : HW_XSTAT(rx_xoff_packets),
270 : :
271 : : HW_XSTAT_NAME(tx_xon_packets, "tx_flow_control_xon_packets"),
272 : : HW_XSTAT_NAME(rx_xon_packets, "rx_flow_control_xon_packets"),
273 : : HW_XSTAT_NAME(tx_xoff_packets, "tx_flow_control_xoff_packets"),
274 : : HW_XSTAT_NAME(rx_xoff_packets, "rx_flow_control_xoff_packets"),
275 : : };
276 : :
277 : : #define TXGBE_NB_HW_STATS (sizeof(rte_txgbe_stats_strings) / \
278 : : sizeof(rte_txgbe_stats_strings[0]))
279 : :
280 : : /* Per-priority statistics */
281 : : #define UP_XSTAT(m) {#m, offsetof(struct txgbe_hw_stats, up[0].m)}
282 : : static const struct rte_txgbe_xstats_name_off rte_txgbe_up_strings[] = {
283 : : UP_XSTAT(rx_up_packets),
284 : : UP_XSTAT(tx_up_packets),
285 : : UP_XSTAT(rx_up_bytes),
286 : : UP_XSTAT(tx_up_bytes),
287 : : UP_XSTAT(rx_up_drop_packets),
288 : :
289 : : UP_XSTAT(tx_up_xon_packets),
290 : : UP_XSTAT(rx_up_xon_packets),
291 : : UP_XSTAT(tx_up_xoff_packets),
292 : : UP_XSTAT(rx_up_xoff_packets),
293 : : UP_XSTAT(rx_up_dropped),
294 : : UP_XSTAT(rx_up_mbuf_alloc_errors),
295 : : UP_XSTAT(tx_up_xon2off_packets),
296 : : };
297 : :
298 : : #define TXGBE_NB_UP_STATS (sizeof(rte_txgbe_up_strings) / \
299 : : sizeof(rte_txgbe_up_strings[0]))
300 : :
301 : : /* Per-queue statistics */
302 : : #define QP_XSTAT(m) {#m, offsetof(struct txgbe_hw_stats, qp[0].m)}
303 : : static const struct rte_txgbe_xstats_name_off rte_txgbe_qp_strings[] = {
304 : : QP_XSTAT(rx_qp_packets),
305 : : QP_XSTAT(tx_qp_packets),
306 : : QP_XSTAT(rx_qp_bytes),
307 : : QP_XSTAT(tx_qp_bytes),
308 : : QP_XSTAT(rx_qp_mc_packets),
309 : : };
310 : :
311 : : #define TXGBE_NB_QP_STATS (sizeof(rte_txgbe_qp_strings) / \
312 : : sizeof(rte_txgbe_qp_strings[0]))
313 : :
314 : : static inline int
315 : : txgbe_is_sfp(struct txgbe_hw *hw)
316 : : {
317 [ # # # # ]: 0 : switch (hw->phy.type) {
318 : : case txgbe_phy_sfp_avago:
319 : : case txgbe_phy_sfp_ftl:
320 : : case txgbe_phy_sfp_intel:
321 : : case txgbe_phy_sfp_unknown:
322 : : case txgbe_phy_sfp_tyco_passive:
323 : : case txgbe_phy_sfp_unknown_passive:
324 : : return 1;
325 : : default:
326 : : return 0;
327 : : }
328 : : }
329 : :
330 : : static inline int32_t
331 : 0 : txgbe_pf_reset_hw(struct txgbe_hw *hw)
332 : : {
333 : : uint32_t ctrl_ext;
334 : : int32_t status;
335 : :
336 : 0 : status = hw->mac.reset_hw(hw);
337 : :
338 : : ctrl_ext = rd32(hw, TXGBE_PORTCTL);
339 : : /* let hardware know driver is loaded */
340 : : ctrl_ext |= TXGBE_PORTCTL_DRVLOAD;
341 : : /* Set PF Reset Done bit so PF/VF Mail Ops can work */
342 : 0 : ctrl_ext |= TXGBE_PORTCTL_RSTDONE;
343 : : wr32(hw, TXGBE_PORTCTL, ctrl_ext);
344 : : txgbe_flush(hw);
345 : :
346 [ # # ]: 0 : if (status == TXGBE_ERR_SFP_NOT_PRESENT)
347 : : status = 0;
348 : 0 : return status;
349 : : }
350 : :
351 : : static inline void
352 : 0 : txgbe_enable_intr(struct rte_eth_dev *dev)
353 : : {
354 : 0 : struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
355 : : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
356 : : uint32_t gpie;
357 : :
358 : 0 : wr32(hw, TXGBE_IENMISC, intr->mask_misc);
359 : : wr32(hw, TXGBE_IMC(0), TXGBE_IMC_MASK);
360 : : wr32(hw, TXGBE_IMC(1), TXGBE_IMC_MASK);
361 : : txgbe_flush(hw);
362 : :
363 : : /* To avoid gpio intr lost, enable pcie intr first. Then enable gpio intr. */
364 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml) {
365 : : gpie = rd32(hw, TXGBE_GPIOINTEN);
366 : 0 : gpie |= TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3 | TXGBE_GPIOBIT_6;
367 : : wr32(hw, TXGBE_GPIOINTEN, gpie);
368 : :
369 : : gpie = rd32(hw, TXGBE_GPIOINTTYPE);
370 : 0 : gpie |= TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3 | TXGBE_GPIOBIT_6;
371 : : wr32(hw, TXGBE_GPIOINTTYPE, gpie);
372 : : }
373 : :
374 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml40) {
375 : : gpie = rd32(hw, TXGBE_GPIOINTEN);
376 : 0 : gpie |= TXGBE_GPIOBIT_4;
377 : : wr32(hw, TXGBE_GPIOINTEN, gpie);
378 : :
379 : : gpie = rd32(hw, TXGBE_GPIOINTTYPE);
380 : 0 : gpie |= TXGBE_GPIOBIT_4;
381 : : wr32(hw, TXGBE_GPIOINTTYPE, gpie);
382 : : }
383 : 0 : }
384 : :
385 : : static void
386 : 0 : txgbe_disable_intr(struct txgbe_hw *hw)
387 : : {
388 : 0 : PMD_INIT_FUNC_TRACE();
389 : :
390 : : wr32(hw, TXGBE_IENMISC, ~BIT_MASK32);
391 : : wr32(hw, TXGBE_IMS(0), TXGBE_IMC_MASK);
392 : : wr32(hw, TXGBE_IMS(1), TXGBE_IMC_MASK);
393 : : txgbe_flush(hw);
394 : 0 : }
395 : :
396 : : static int
397 : 0 : txgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
398 : : uint16_t queue_id,
399 : : uint8_t stat_idx,
400 : : uint8_t is_rx)
401 : : {
402 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(eth_dev);
403 : : struct txgbe_stat_mappings *stat_mappings =
404 : : TXGBE_DEV_STAT_MAPPINGS(eth_dev);
405 : : uint32_t qsmr_mask = 0;
406 : : uint32_t clearing_mask = QMAP_FIELD_RESERVED_BITS_MASK;
407 : : uint32_t q_map;
408 : : uint8_t n, offset;
409 : :
410 [ # # ]: 0 : if (!txgbe_is_pf(hw))
411 : : return -ENOSYS;
412 : :
413 [ # # ]: 0 : if (stat_idx & ~QMAP_FIELD_RESERVED_BITS_MASK)
414 : : return -EIO;
415 : :
416 [ # # ]: 0 : PMD_INIT_LOG(DEBUG, "Setting port %d, %s queue_id %d to stat index %d",
417 : : (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX",
418 : : queue_id, stat_idx);
419 : :
420 : 0 : n = (uint8_t)(queue_id / NB_QMAP_FIELDS_PER_QSM_REG);
421 [ # # ]: 0 : if (n >= TXGBE_NB_STAT_MAPPING) {
422 : 0 : PMD_INIT_LOG(ERR, "Nb of stat mapping registers exceeded");
423 : 0 : return -EIO;
424 : : }
425 : 0 : offset = (uint8_t)(queue_id % NB_QMAP_FIELDS_PER_QSM_REG);
426 : :
427 : : /* Now clear any previous stat_idx set */
428 : 0 : clearing_mask <<= (QSM_REG_NB_BITS_PER_QMAP_FIELD * offset);
429 [ # # ]: 0 : if (!is_rx)
430 : 0 : stat_mappings->tqsm[n] &= ~clearing_mask;
431 : : else
432 : 0 : stat_mappings->rqsm[n] &= ~clearing_mask;
433 : :
434 : : q_map = (uint32_t)stat_idx;
435 : 0 : q_map &= QMAP_FIELD_RESERVED_BITS_MASK;
436 : 0 : qsmr_mask = q_map << (QSM_REG_NB_BITS_PER_QMAP_FIELD * offset);
437 [ # # ]: 0 : if (!is_rx)
438 : 0 : stat_mappings->tqsm[n] |= qsmr_mask;
439 : : else
440 : 0 : stat_mappings->rqsm[n] |= qsmr_mask;
441 : :
442 : 0 : PMD_INIT_LOG(DEBUG, "Set port %d, %s queue_id %d to stat index %d",
443 : : (int)(eth_dev->data->port_id), is_rx ? "RX" : "TX",
444 : : queue_id, stat_idx);
445 [ # # # # ]: 0 : PMD_INIT_LOG(DEBUG, "%s[%d] = 0x%08x", is_rx ? "RQSMR" : "TQSM", n,
446 : : is_rx ? stat_mappings->rqsm[n] : stat_mappings->tqsm[n]);
447 : 0 : return 0;
448 : : }
449 : :
450 : : static void
451 : 0 : txgbe_dcb_init(struct txgbe_hw *hw, struct txgbe_dcb_config *dcb_config)
452 : : {
453 : : int i;
454 : : u8 bwgp;
455 : : struct txgbe_dcb_tc_config *tc;
456 : :
457 : : UNREFERENCED_PARAMETER(hw);
458 : :
459 : 0 : dcb_config->num_tcs.pg_tcs = TXGBE_DCB_TC_MAX;
460 : 0 : dcb_config->num_tcs.pfc_tcs = TXGBE_DCB_TC_MAX;
461 : : bwgp = (u8)(100 / TXGBE_DCB_TC_MAX);
462 [ # # ]: 0 : for (i = 0; i < TXGBE_DCB_TC_MAX; i++) {
463 : : tc = &dcb_config->tc_config[i];
464 : 0 : tc->path[TXGBE_DCB_TX_CONFIG].bwg_id = i;
465 : 0 : tc->path[TXGBE_DCB_TX_CONFIG].bwg_percent = bwgp + (i & 1);
466 : 0 : tc->path[TXGBE_DCB_RX_CONFIG].bwg_id = i;
467 : 0 : tc->path[TXGBE_DCB_RX_CONFIG].bwg_percent = bwgp + (i & 1);
468 : 0 : tc->pfc = txgbe_dcb_pfc_disabled;
469 : : }
470 : :
471 : : /* Initialize default user to priority mapping, UPx->TC0 */
472 : : tc = &dcb_config->tc_config[0];
473 : 0 : tc->path[TXGBE_DCB_TX_CONFIG].up_to_tc_bitmap = 0xFF;
474 : 0 : tc->path[TXGBE_DCB_RX_CONFIG].up_to_tc_bitmap = 0xFF;
475 [ # # ]: 0 : for (i = 0; i < TXGBE_DCB_BWG_MAX; i++) {
476 : 0 : dcb_config->bw_percentage[i][TXGBE_DCB_TX_CONFIG] = 100;
477 : 0 : dcb_config->bw_percentage[i][TXGBE_DCB_RX_CONFIG] = 100;
478 : : }
479 : 0 : dcb_config->rx_pba_cfg = txgbe_dcb_pba_equal;
480 : 0 : dcb_config->pfc_mode_enable = false;
481 : 0 : dcb_config->vt_mode = true;
482 : 0 : dcb_config->round_robin_enable = false;
483 : : /* support all DCB capabilities */
484 : 0 : dcb_config->support.capabilities = 0xFF;
485 : 0 : }
486 : :
487 : : /*
488 : : * Ensure that all locks are released before first NVM or PHY access
489 : : */
490 : : static void
491 : 0 : txgbe_swfw_lock_reset(struct txgbe_hw *hw)
492 : : {
493 : : uint16_t mask;
494 : :
495 : : /*
496 : : * These ones are more tricky since they are common to all ports; but
497 : : * swfw_sync retries last long enough (1s) to be almost sure that if
498 : : * lock can not be taken it is due to an improper lock of the
499 : : * semaphore.
500 : : */
501 : : mask = TXGBE_MNGSEM_SWPHY |
502 : : TXGBE_MNGSEM_SWMBX |
503 : : TXGBE_MNGSEM_SWFLASH;
504 [ # # ]: 0 : if (hw->mac.acquire_swfw_sync(hw, mask) < 0)
505 : 0 : PMD_DRV_LOG(DEBUG, "SWFW common locks released");
506 : :
507 : 0 : hw->mac.release_swfw_sync(hw, mask);
508 : 0 : }
509 : :
510 : : static int
511 : 0 : txgbe_handle_devarg(__rte_unused const char *key, const char *value,
512 : : void *extra_args)
513 : : {
514 : : uint16_t *n = extra_args;
515 : :
516 [ # # ]: 0 : if (value == NULL || extra_args == NULL)
517 : : return -EINVAL;
518 : :
519 : 0 : *n = (uint16_t)strtoul(value, NULL, 10);
520 [ # # # # ]: 0 : if (*n == USHRT_MAX && errno == ERANGE)
521 : 0 : return -1;
522 : :
523 : : return 0;
524 : : }
525 : :
526 : : static void
527 : 0 : txgbe_parse_devargs(struct txgbe_hw *hw, struct rte_devargs *devargs)
528 : : {
529 : : struct rte_kvargs *kvlist;
530 : 0 : u16 auto_neg = 1;
531 : 0 : u16 poll = 0;
532 : 0 : u16 present = 0;
533 : 0 : u16 sgmii = 0;
534 : 0 : u16 ffe_set = 0;
535 : 0 : u16 ffe_main = 27;
536 : 0 : u16 ffe_pre = 8;
537 : 0 : u16 ffe_post = 44;
538 : : /* New devargs for amberlite config */
539 : 0 : u16 tx_headwb = 1;
540 : 0 : u16 tx_headwb_size = 16;
541 : 0 : u16 rx_desc_merge = 1;
542 : :
543 [ # # ]: 0 : if (devargs == NULL)
544 : 0 : goto null;
545 : :
546 : 0 : kvlist = rte_kvargs_parse(devargs->args, txgbe_valid_arguments);
547 [ # # ]: 0 : if (kvlist == NULL)
548 : 0 : goto null;
549 : :
550 : 0 : rte_kvargs_process(kvlist, TXGBE_DEVARG_BP_AUTO,
551 : : &txgbe_handle_devarg, &auto_neg);
552 : 0 : rte_kvargs_process(kvlist, TXGBE_DEVARG_KR_POLL,
553 : : &txgbe_handle_devarg, &poll);
554 : 0 : rte_kvargs_process(kvlist, TXGBE_DEVARG_KR_PRESENT,
555 : : &txgbe_handle_devarg, &present);
556 : 0 : rte_kvargs_process(kvlist, TXGBE_DEVARG_KX_SGMII,
557 : : &txgbe_handle_devarg, &sgmii);
558 : 0 : rte_kvargs_process(kvlist, TXGBE_DEVARG_FFE_SET,
559 : : &txgbe_handle_devarg, &ffe_set);
560 : 0 : rte_kvargs_process(kvlist, TXGBE_DEVARG_FFE_MAIN,
561 : : &txgbe_handle_devarg, &ffe_main);
562 : 0 : rte_kvargs_process(kvlist, TXGBE_DEVARG_FFE_PRE,
563 : : &txgbe_handle_devarg, &ffe_pre);
564 : 0 : rte_kvargs_process(kvlist, TXGBE_DEVARG_FFE_POST,
565 : : &txgbe_handle_devarg, &ffe_post);
566 : 0 : rte_kvargs_process(kvlist, TXGBE_DEVARG_TX_HEAD_WB,
567 : : &txgbe_handle_devarg, &tx_headwb);
568 : 0 : rte_kvargs_process(kvlist, TXGBE_DEVARG_TX_HEAD_WB_SIZE,
569 : : &txgbe_handle_devarg, &tx_headwb_size);
570 : 0 : rte_kvargs_process(kvlist, TXGBE_DEVARG_RX_DESC_MERGE,
571 : : &txgbe_handle_devarg, &rx_desc_merge);
572 : 0 : rte_kvargs_free(kvlist);
573 : :
574 : 0 : null:
575 : 0 : hw->devarg.auto_neg = auto_neg;
576 : 0 : hw->devarg.poll = poll;
577 : 0 : hw->devarg.present = present;
578 : 0 : hw->devarg.sgmii = sgmii;
579 : 0 : hw->devarg.tx_headwb = tx_headwb;
580 : 0 : hw->devarg.tx_headwb_size = tx_headwb_size;
581 : 0 : hw->devarg.rx_desc_merge = rx_desc_merge;
582 : 0 : hw->phy.ffe_set = ffe_set;
583 : 0 : hw->phy.ffe_main = ffe_main;
584 : 0 : hw->phy.ffe_pre = ffe_pre;
585 : 0 : hw->phy.ffe_post = ffe_post;
586 : 0 : }
587 : :
588 : : static int
589 : 0 : eth_txgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
590 : : {
591 : 0 : struct txgbe_adapter *ad = eth_dev->data->dev_private;
592 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
593 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(eth_dev);
594 : 0 : struct txgbe_vfta *shadow_vfta = TXGBE_DEV_VFTA(eth_dev);
595 : 0 : struct txgbe_hwstrip *hwstrip = TXGBE_DEV_HWSTRIP(eth_dev);
596 : 0 : struct txgbe_dcb_config *dcb_config = TXGBE_DEV_DCB_CONFIG(eth_dev);
597 : 0 : struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(eth_dev);
598 : 0 : struct txgbe_bw_conf *bw_conf = TXGBE_DEV_BW_CONF(eth_dev);
599 : 0 : struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
600 : : const struct rte_memzone *mz;
601 : : uint32_t ctrl_ext;
602 : : uint16_t csum;
603 : : int err, i, ret;
604 : :
605 : 0 : PMD_INIT_FUNC_TRACE();
606 : :
607 : 0 : eth_dev->dev_ops = &txgbe_eth_dev_ops;
608 : 0 : eth_dev->rx_queue_count = txgbe_dev_rx_queue_count;
609 : 0 : eth_dev->rx_descriptor_status = txgbe_dev_rx_descriptor_status;
610 : 0 : eth_dev->tx_descriptor_status = txgbe_dev_tx_descriptor_status;
611 : 0 : eth_dev->rx_pkt_burst = &txgbe_recv_pkts;
612 : 0 : eth_dev->tx_pkt_burst = &txgbe_xmit_pkts;
613 : 0 : eth_dev->tx_pkt_prepare = &txgbe_prep_pkts;
614 : :
615 : : /*
616 : : * For secondary processes, we don't initialise any further as primary
617 : : * has already done this work. Only check we don't need a different
618 : : * RX and TX function.
619 : : */
620 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
621 : : struct txgbe_tx_queue *txq;
622 : : /* TX queue function in primary, set by last queue initialized
623 : : * Tx queue may not initialized by primary process
624 : : */
625 [ # # ]: 0 : if (eth_dev->data->tx_queues) {
626 : 0 : uint16_t nb_tx_queues = eth_dev->data->nb_tx_queues;
627 : 0 : txq = eth_dev->data->tx_queues[nb_tx_queues - 1];
628 : 0 : txgbe_set_tx_function(eth_dev, txq);
629 : : } else {
630 : : /* Use default TX function if we get here */
631 : 0 : PMD_INIT_LOG(NOTICE, "No TX queues configured yet. "
632 : : "Using default TX function.");
633 : : }
634 : :
635 : 0 : txgbe_set_rx_function(eth_dev);
636 : :
637 : 0 : return 0;
638 : : }
639 : :
640 : 0 : rte_atomic_store_explicit(&ad->link_thread_running, 0, rte_memory_order_seq_cst);
641 : 0 : rte_eth_copy_pci_info(eth_dev, pci_dev);
642 : :
643 : 0 : hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
644 : :
645 : : /* Vendor and Device ID need to be set before init of shared code */
646 : 0 : hw->back = pci_dev;
647 : 0 : hw->port_id = eth_dev->data->port_id;
648 : 0 : hw->device_id = pci_dev->id.device_id;
649 : 0 : hw->vendor_id = pci_dev->id.vendor_id;
650 [ # # ]: 0 : if (pci_dev->id.subsystem_vendor_id == PCI_VENDOR_ID_WANGXUN) {
651 : 0 : hw->subsystem_device_id = pci_dev->id.subsystem_device_id;
652 : : } else {
653 : 0 : u32 ssid = 0;
654 : :
655 : 0 : err = txgbe_flash_read_dword(hw, 0xFFFDC, &ssid);
656 [ # # ]: 0 : if (err) {
657 : 0 : PMD_INIT_LOG(ERR,
658 : : "Read of internal subsystem device id failed");
659 : 0 : return -ENODEV;
660 : : }
661 : 0 : hw->subsystem_device_id = (u16)ssid >> 8 | (u16)ssid << 8;
662 : : }
663 : 0 : hw->allow_unsupported_sfp = 1;
664 : :
665 : : /* Reserve memory for interrupt status block */
666 : 0 : mz = rte_eth_dma_zone_reserve(eth_dev, "txgbe_driver", -1,
667 : : 16, TXGBE_ALIGN, SOCKET_ID_ANY);
668 [ # # ]: 0 : if (mz == NULL)
669 : : return -ENOMEM;
670 : :
671 : 0 : hw->isb_dma = TMZ_PADDR(mz);
672 : 0 : hw->isb_mem = TMZ_VADDR(mz);
673 : :
674 : 0 : txgbe_parse_devargs(hw, pci_dev->device.devargs);
675 : : /* Initialize the shared code (base driver) */
676 : 0 : err = txgbe_init_shared_code(hw);
677 [ # # ]: 0 : if (err != 0) {
678 : 0 : PMD_INIT_LOG(ERR, "Shared code init failed: %d", err);
679 : 0 : return -EIO;
680 : : }
681 : :
682 : : /* Unlock any pending hardware semaphore */
683 : 0 : txgbe_swfw_lock_reset(hw);
684 : :
685 : : #ifdef RTE_LIB_SECURITY
686 : : /* Initialize security_ctx only for primary process*/
687 [ # # ]: 0 : if (txgbe_ipsec_ctx_create(eth_dev))
688 : : return -ENOMEM;
689 : : #endif
690 : :
691 : : /* Initialize DCB configuration*/
692 : : memset(dcb_config, 0, sizeof(struct txgbe_dcb_config));
693 : 0 : txgbe_dcb_init(hw, dcb_config);
694 : :
695 : : /* Get Hardware Flow Control setting */
696 : 0 : hw->fc.requested_mode = txgbe_fc_full;
697 : 0 : hw->fc.current_mode = txgbe_fc_full;
698 : 0 : hw->fc.pause_time = TXGBE_FC_PAUSE_TIME;
699 [ # # ]: 0 : for (i = 0; i < TXGBE_DCB_TC_MAX; i++) {
700 : 0 : hw->fc.low_water[i] = TXGBE_FC_XON_LOTH;
701 : 0 : hw->fc.high_water[i] = TXGBE_FC_XOFF_HITH;
702 : : }
703 : 0 : hw->fc.send_xon = 1;
704 : :
705 : 0 : err = hw->rom.init_params(hw);
706 [ # # ]: 0 : if (err != 0) {
707 : 0 : PMD_INIT_LOG(ERR, "The EEPROM init failed: %d", err);
708 : 0 : return -EIO;
709 : : }
710 : :
711 : : /* Make sure we have a good EEPROM before we read from it */
712 : 0 : err = hw->rom.validate_checksum(hw, &csum);
713 [ # # ]: 0 : if (err != 0) {
714 : 0 : PMD_INIT_LOG(ERR, "The EEPROM checksum is not valid: %d", err);
715 : 0 : return -EIO;
716 : : }
717 : :
718 : 0 : err = hw->mac.init_hw(hw);
719 : :
720 : : /*
721 : : * Devices with copper phys will fail to initialise if txgbe_init_hw()
722 : : * is called too soon after the kernel driver unbinding/binding occurs.
723 : : * The failure occurs in txgbe_identify_phy() for all devices,
724 : : * but for non-copper devies, txgbe_identify_sfp_module() is
725 : : * also called. See txgbe_identify_phy(). The reason for the
726 : : * failure is not known, and only occuts when virtualisation features
727 : : * are disabled in the bios. A delay of 200ms was found to be enough by
728 : : * trial-and-error, and is doubled to be safe.
729 : : */
730 [ # # # # ]: 0 : if (err && hw->phy.media_type == txgbe_media_type_copper) {
731 : : rte_delay_ms(200);
732 : 0 : err = hw->mac.init_hw(hw);
733 : : }
734 : :
735 [ # # ]: 0 : if (err == TXGBE_ERR_SFP_NOT_PRESENT)
736 : : err = 0;
737 : :
738 [ # # ]: 0 : if (err == TXGBE_ERR_EEPROM_VERSION) {
739 : 0 : PMD_INIT_LOG(ERR, "This device is a pre-production adapter/"
740 : : "LOM. Please be aware there may be issues associated "
741 : : "with your hardware.");
742 : 0 : PMD_INIT_LOG(ERR, "If you are experiencing problems "
743 : : "please contact your hardware representative "
744 : : "who provided you with this hardware.");
745 [ # # ]: 0 : } else if (err == TXGBE_ERR_SFP_NOT_SUPPORTED) {
746 : 0 : PMD_INIT_LOG(ERR, "Unsupported SFP+ Module");
747 : : }
748 [ # # ]: 0 : if (err) {
749 : 0 : PMD_INIT_LOG(ERR, "Hardware Initialization Failure: %d", err);
750 : 0 : return -EIO;
751 : : }
752 : :
753 : : /* Reset the hw statistics */
754 : 0 : txgbe_dev_stats_reset(eth_dev);
755 : :
756 : : /* disable interrupt */
757 : 0 : txgbe_disable_intr(hw);
758 : :
759 : : /* Allocate memory for storing MAC addresses */
760 : 0 : eth_dev->data->mac_addrs = rte_zmalloc("txgbe", RTE_ETHER_ADDR_LEN *
761 : 0 : hw->mac.num_rar_entries, 0);
762 [ # # ]: 0 : if (eth_dev->data->mac_addrs == NULL) {
763 : 0 : PMD_INIT_LOG(ERR,
764 : : "Failed to allocate %u bytes needed to store "
765 : : "MAC addresses",
766 : : RTE_ETHER_ADDR_LEN * hw->mac.num_rar_entries);
767 : 0 : return -ENOMEM;
768 : : }
769 : :
770 : : /* Copy the permanent MAC address */
771 : : rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.perm_addr,
772 : : ð_dev->data->mac_addrs[0]);
773 : :
774 : : /* Allocate memory for storing hash filter MAC addresses */
775 : 0 : eth_dev->data->hash_mac_addrs = rte_zmalloc("txgbe",
776 : : RTE_ETHER_ADDR_LEN * TXGBE_VMDQ_NUM_UC_MAC, 0);
777 [ # # ]: 0 : if (eth_dev->data->hash_mac_addrs == NULL) {
778 : 0 : PMD_INIT_LOG(ERR,
779 : : "Failed to allocate %d bytes needed to store MAC addresses",
780 : : RTE_ETHER_ADDR_LEN * TXGBE_VMDQ_NUM_UC_MAC);
781 : 0 : rte_free(eth_dev->data->mac_addrs);
782 : 0 : eth_dev->data->mac_addrs = NULL;
783 : 0 : return -ENOMEM;
784 : : }
785 : :
786 : : /* initialize the vfta */
787 : : memset(shadow_vfta, 0, sizeof(*shadow_vfta));
788 : :
789 : : /* initialize the hw strip bitmap*/
790 : : memset(hwstrip, 0, sizeof(*hwstrip));
791 : :
792 : : /* initialize PF if max_vfs not zero */
793 : 0 : ret = txgbe_pf_host_init(eth_dev);
794 [ # # ]: 0 : if (ret) {
795 : 0 : rte_free(eth_dev->data->mac_addrs);
796 : 0 : eth_dev->data->mac_addrs = NULL;
797 : 0 : rte_free(eth_dev->data->hash_mac_addrs);
798 : 0 : eth_dev->data->hash_mac_addrs = NULL;
799 : 0 : return ret;
800 : : }
801 : :
802 : : ctrl_ext = rd32(hw, TXGBE_PORTCTL);
803 : : /* let hardware know driver is loaded */
804 : : ctrl_ext |= TXGBE_PORTCTL_DRVLOAD;
805 : : /* Set PF Reset Done bit so PF/VF Mail Ops can work */
806 : 0 : ctrl_ext |= TXGBE_PORTCTL_RSTDONE;
807 : : wr32(hw, TXGBE_PORTCTL, ctrl_ext);
808 : : txgbe_flush(hw);
809 : :
810 [ # # ]: 0 : if (txgbe_is_sfp(hw) && hw->phy.sfp_type != txgbe_sfp_type_not_present)
811 : 0 : PMD_INIT_LOG(DEBUG, "MAC: %d, PHY: %d, SFP+: %d",
812 : : (int)hw->mac.type, (int)hw->phy.type,
813 : : (int)hw->phy.sfp_type);
814 : : else
815 : 0 : PMD_INIT_LOG(DEBUG, "MAC: %d, PHY: %d",
816 : : (int)hw->mac.type, (int)hw->phy.type);
817 : :
818 : 0 : PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x",
819 : : eth_dev->data->port_id, pci_dev->id.vendor_id,
820 : : pci_dev->id.device_id);
821 : :
822 : 0 : rte_intr_callback_register(intr_handle,
823 : : txgbe_dev_interrupt_handler, eth_dev);
824 : :
825 : : /* enable uio/vfio intr/eventfd mapping */
826 : 0 : rte_intr_enable(intr_handle);
827 : :
828 : : /* enable support intr */
829 : 0 : txgbe_enable_intr(eth_dev);
830 : :
831 : : /* initialize filter info */
832 : : memset(filter_info, 0,
833 : : sizeof(struct txgbe_filter_info));
834 : :
835 : : /* initialize 5tuple filter list */
836 : 0 : TAILQ_INIT(&filter_info->fivetuple_list);
837 : :
838 : : /* initialize flow director filter list & hash */
839 : 0 : txgbe_fdir_filter_init(eth_dev);
840 : :
841 : : /* initialize l2 tunnel filter list & hash */
842 : 0 : txgbe_l2_tn_filter_init(eth_dev);
843 : :
844 : : /* initialize flow filter lists */
845 : 0 : txgbe_filterlist_init();
846 : :
847 : : /* initialize bandwidth configuration info */
848 : : memset(bw_conf, 0, sizeof(struct txgbe_bw_conf));
849 : :
850 : : /* initialize Traffic Manager configuration */
851 : 0 : txgbe_tm_conf_init(eth_dev);
852 : :
853 : 0 : return 0;
854 : : }
855 : :
856 : : static int
857 : 0 : eth_txgbe_dev_uninit(struct rte_eth_dev *eth_dev)
858 : : {
859 : 0 : PMD_INIT_FUNC_TRACE();
860 : :
861 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
862 : : return 0;
863 : :
864 : 0 : txgbe_dev_close(eth_dev);
865 : :
866 : 0 : return 0;
867 : : }
868 : :
869 : 0 : int txgbe_ntuple_filter_uninit(struct rte_eth_dev *eth_dev)
870 : : {
871 : 0 : struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(eth_dev);
872 : : struct txgbe_5tuple_filter *p_5tuple;
873 : :
874 [ # # ]: 0 : while ((p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list))) {
875 [ # # ]: 0 : TAILQ_REMOVE(&filter_info->fivetuple_list,
876 : : p_5tuple,
877 : : entries);
878 : 0 : rte_free(p_5tuple);
879 : : }
880 : 0 : memset(filter_info->fivetuple_mask, 0,
881 : : sizeof(uint32_t) * TXGBE_5TUPLE_ARRAY_SIZE);
882 : :
883 : 0 : return 0;
884 : : }
885 : :
886 : 0 : static int txgbe_fdir_filter_uninit(struct rte_eth_dev *eth_dev)
887 : : {
888 : 0 : struct txgbe_hw_fdir_info *fdir_info = TXGBE_DEV_FDIR(eth_dev);
889 : : struct txgbe_fdir_filter *fdir_filter;
890 : :
891 : 0 : rte_free(fdir_info->hash_map);
892 : 0 : rte_hash_free(fdir_info->hash_handle);
893 : :
894 [ # # ]: 0 : while ((fdir_filter = TAILQ_FIRST(&fdir_info->fdir_list))) {
895 [ # # ]: 0 : TAILQ_REMOVE(&fdir_info->fdir_list,
896 : : fdir_filter,
897 : : entries);
898 : 0 : rte_free(fdir_filter);
899 : : }
900 : :
901 : 0 : return 0;
902 : : }
903 : :
904 : 0 : static int txgbe_l2_tn_filter_uninit(struct rte_eth_dev *eth_dev)
905 : : {
906 : 0 : struct txgbe_l2_tn_info *l2_tn_info = TXGBE_DEV_L2_TN(eth_dev);
907 : : struct txgbe_l2_tn_filter *l2_tn_filter;
908 : :
909 : 0 : rte_free(l2_tn_info->hash_map);
910 : 0 : rte_hash_free(l2_tn_info->hash_handle);
911 : :
912 [ # # ]: 0 : while ((l2_tn_filter = TAILQ_FIRST(&l2_tn_info->l2_tn_list))) {
913 [ # # ]: 0 : TAILQ_REMOVE(&l2_tn_info->l2_tn_list,
914 : : l2_tn_filter,
915 : : entries);
916 : 0 : rte_free(l2_tn_filter);
917 : : }
918 : :
919 : 0 : return 0;
920 : : }
921 : :
922 : 0 : static int txgbe_fdir_filter_init(struct rte_eth_dev *eth_dev)
923 : : {
924 : 0 : struct txgbe_hw_fdir_info *fdir_info = TXGBE_DEV_FDIR(eth_dev);
925 : : char fdir_hash_name[RTE_HASH_NAMESIZE];
926 : 0 : struct rte_hash_parameters fdir_hash_params = {
927 : : .name = fdir_hash_name,
928 : : .entries = TXGBE_MAX_FDIR_FILTER_NUM,
929 : : .key_len = sizeof(struct txgbe_atr_input),
930 : : .hash_func = rte_hash_crc,
931 : : .hash_func_init_val = 0,
932 : 0 : .socket_id = rte_socket_id(),
933 : : };
934 : :
935 : 0 : TAILQ_INIT(&fdir_info->fdir_list);
936 : 0 : snprintf(fdir_hash_name, RTE_HASH_NAMESIZE,
937 : 0 : "fdir_%s", TDEV_NAME(eth_dev));
938 : 0 : fdir_info->hash_handle = rte_hash_create(&fdir_hash_params);
939 [ # # ]: 0 : if (!fdir_info->hash_handle) {
940 : 0 : PMD_INIT_LOG(ERR, "Failed to create fdir hash table!");
941 : 0 : return -EINVAL;
942 : : }
943 : 0 : fdir_info->hash_map = rte_zmalloc("txgbe",
944 : : sizeof(struct txgbe_fdir_filter *) *
945 : : TXGBE_MAX_FDIR_FILTER_NUM,
946 : : 0);
947 [ # # ]: 0 : if (!fdir_info->hash_map) {
948 : 0 : PMD_INIT_LOG(ERR,
949 : : "Failed to allocate memory for fdir hash map!");
950 : 0 : rte_hash_free(fdir_info->hash_handle);
951 : 0 : return -ENOMEM;
952 : : }
953 : 0 : fdir_info->mask_added = FALSE;
954 : :
955 : 0 : return 0;
956 : : }
957 : :
958 : 0 : static int txgbe_l2_tn_filter_init(struct rte_eth_dev *eth_dev)
959 : : {
960 : 0 : struct txgbe_l2_tn_info *l2_tn_info = TXGBE_DEV_L2_TN(eth_dev);
961 : : char l2_tn_hash_name[RTE_HASH_NAMESIZE];
962 : 0 : struct rte_hash_parameters l2_tn_hash_params = {
963 : : .name = l2_tn_hash_name,
964 : : .entries = TXGBE_MAX_L2_TN_FILTER_NUM,
965 : : .key_len = sizeof(struct txgbe_l2_tn_key),
966 : : .hash_func = rte_hash_crc,
967 : : .hash_func_init_val = 0,
968 : 0 : .socket_id = rte_socket_id(),
969 : : };
970 : :
971 : 0 : TAILQ_INIT(&l2_tn_info->l2_tn_list);
972 : 0 : snprintf(l2_tn_hash_name, RTE_HASH_NAMESIZE,
973 : 0 : "l2_tn_%s", TDEV_NAME(eth_dev));
974 : 0 : l2_tn_info->hash_handle = rte_hash_create(&l2_tn_hash_params);
975 [ # # ]: 0 : if (!l2_tn_info->hash_handle) {
976 : 0 : PMD_INIT_LOG(ERR, "Failed to create L2 TN hash table!");
977 : 0 : return -EINVAL;
978 : : }
979 : 0 : l2_tn_info->hash_map = rte_zmalloc("txgbe",
980 : : sizeof(struct txgbe_l2_tn_filter *) *
981 : : TXGBE_MAX_L2_TN_FILTER_NUM,
982 : : 0);
983 [ # # ]: 0 : if (!l2_tn_info->hash_map) {
984 : 0 : PMD_INIT_LOG(ERR,
985 : : "Failed to allocate memory for L2 TN hash map!");
986 : 0 : rte_hash_free(l2_tn_info->hash_handle);
987 : 0 : return -ENOMEM;
988 : : }
989 : 0 : l2_tn_info->e_tag_en = FALSE;
990 : 0 : l2_tn_info->e_tag_fwd_en = FALSE;
991 : 0 : l2_tn_info->e_tag_ether_type = RTE_ETHER_TYPE_ETAG;
992 : :
993 : 0 : return 0;
994 : : }
995 : :
996 : : static int
997 : 0 : eth_txgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
998 : : struct rte_pci_device *pci_dev)
999 : : {
1000 : 0 : return rte_eth_dev_create(&pci_dev->device, pci_dev->device.name,
1001 : : sizeof(struct txgbe_adapter),
1002 : : eth_dev_pci_specific_init, pci_dev,
1003 : : eth_txgbe_dev_init, NULL);
1004 : : }
1005 : :
1006 : 0 : static int eth_txgbe_pci_remove(struct rte_pci_device *pci_dev)
1007 : : {
1008 : : struct rte_eth_dev *ethdev;
1009 : :
1010 : 0 : ethdev = rte_eth_dev_allocated(pci_dev->device.name);
1011 [ # # ]: 0 : if (!ethdev)
1012 : : return 0;
1013 : :
1014 : 0 : return rte_eth_dev_pci_generic_remove(pci_dev, eth_txgbe_dev_uninit);
1015 : : }
1016 : :
1017 : : static struct rte_pci_driver rte_txgbe_pmd = {
1018 : : .id_table = pci_id_txgbe_map,
1019 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING |
1020 : : RTE_PCI_DRV_INTR_LSC,
1021 : : .probe = eth_txgbe_pci_probe,
1022 : : .remove = eth_txgbe_pci_remove,
1023 : : };
1024 : :
1025 : : static int
1026 : 0 : txgbe_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
1027 : : {
1028 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
1029 : : struct txgbe_vfta *shadow_vfta = TXGBE_DEV_VFTA(dev);
1030 : : uint32_t vfta;
1031 : : uint32_t vid_idx;
1032 : : uint32_t vid_bit;
1033 : :
1034 : 0 : vid_idx = (uint32_t)((vlan_id >> 5) & 0x7F);
1035 : 0 : vid_bit = (uint32_t)(1 << (vlan_id & 0x1F));
1036 : 0 : vfta = rd32(hw, TXGBE_VLANTBL(vid_idx));
1037 [ # # ]: 0 : if (on)
1038 : 0 : vfta |= vid_bit;
1039 : : else
1040 : 0 : vfta &= ~vid_bit;
1041 : : wr32(hw, TXGBE_VLANTBL(vid_idx), vfta);
1042 : :
1043 : : /* update local VFTA copy */
1044 : 0 : shadow_vfta->vfta[vid_idx] = vfta;
1045 : :
1046 : 0 : return 0;
1047 : : }
1048 : :
1049 : : static void
1050 : 0 : txgbe_vlan_strip_q_set(struct rte_eth_dev *dev, uint16_t queue, int on)
1051 : : {
1052 [ # # ]: 0 : if (on)
1053 : 0 : txgbe_vlan_hw_strip_enable(dev, queue);
1054 : : else
1055 : 0 : txgbe_vlan_hw_strip_disable(dev, queue);
1056 : 0 : }
1057 : :
1058 : : static void
1059 : 0 : txgbe_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
1060 : : {
1061 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
1062 : :
1063 [ # # ]: 0 : if (!hw->adapter_stopped) {
1064 : 0 : PMD_DRV_LOG(ERR, "Please stop port first");
1065 : 0 : return;
1066 : : }
1067 : :
1068 : 0 : txgbe_vlan_strip_q_set(dev, queue, on);
1069 : : }
1070 : :
1071 : : static int
1072 : 0 : txgbe_vlan_tpid_set(struct rte_eth_dev *dev,
1073 : : enum rte_vlan_type vlan_type,
1074 : : uint16_t tpid)
1075 : : {
1076 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
1077 : : int ret = 0;
1078 : : uint32_t portctrl, vlan_ext, qinq;
1079 : :
1080 : : portctrl = rd32(hw, TXGBE_PORTCTL);
1081 : :
1082 : 0 : vlan_ext = (portctrl & TXGBE_PORTCTL_VLANEXT);
1083 [ # # # # ]: 0 : qinq = vlan_ext && (portctrl & TXGBE_PORTCTL_QINQ);
1084 [ # # # ]: 0 : switch (vlan_type) {
1085 : 0 : case RTE_ETH_VLAN_TYPE_INNER:
1086 [ # # ]: 0 : if (vlan_ext) {
1087 : 0 : wr32m(hw, TXGBE_VLANCTL,
1088 : : TXGBE_VLANCTL_TPID_MASK,
1089 : : TXGBE_VLANCTL_TPID(tpid));
1090 : 0 : wr32m(hw, TXGBE_DMATXCTRL,
1091 : : TXGBE_DMATXCTRL_TPID_MASK,
1092 : : TXGBE_DMATXCTRL_TPID(tpid));
1093 : : } else {
1094 : : ret = -ENOTSUP;
1095 : 0 : PMD_DRV_LOG(ERR, "Inner type is not supported"
1096 : : " by single VLAN");
1097 : : }
1098 : :
1099 [ # # ]: 0 : if (qinq) {
1100 : 0 : wr32m(hw, TXGBE_TAGTPID(0),
1101 : : TXGBE_TAGTPID_LSB_MASK,
1102 : : TXGBE_TAGTPID_LSB(tpid));
1103 : : }
1104 : : break;
1105 : 0 : case RTE_ETH_VLAN_TYPE_OUTER:
1106 [ # # ]: 0 : if (vlan_ext) {
1107 : : /* Only the high 16-bits is valid */
1108 : 0 : wr32m(hw, TXGBE_EXTAG,
1109 : : TXGBE_EXTAG_VLAN_MASK,
1110 : 0 : TXGBE_EXTAG_VLAN(tpid));
1111 : : } else {
1112 : 0 : wr32m(hw, TXGBE_VLANCTL,
1113 : : TXGBE_VLANCTL_TPID_MASK,
1114 : : TXGBE_VLANCTL_TPID(tpid));
1115 : 0 : wr32m(hw, TXGBE_DMATXCTRL,
1116 : : TXGBE_DMATXCTRL_TPID_MASK,
1117 : : TXGBE_DMATXCTRL_TPID(tpid));
1118 : : }
1119 : :
1120 [ # # ]: 0 : if (qinq) {
1121 : 0 : wr32m(hw, TXGBE_TAGTPID(0),
1122 : : TXGBE_TAGTPID_MSB_MASK,
1123 : 0 : TXGBE_TAGTPID_MSB(tpid));
1124 : : }
1125 : : break;
1126 : 0 : default:
1127 : 0 : PMD_DRV_LOG(ERR, "Unsupported VLAN type %d", vlan_type);
1128 : 0 : return -EINVAL;
1129 : : }
1130 : :
1131 : : return ret;
1132 : : }
1133 : :
1134 : : void
1135 : 0 : txgbe_vlan_hw_filter_disable(struct rte_eth_dev *dev)
1136 : : {
1137 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
1138 : : uint32_t vlnctrl;
1139 : :
1140 : 0 : PMD_INIT_FUNC_TRACE();
1141 : :
1142 : : /* Filter Table Disable */
1143 : : vlnctrl = rd32(hw, TXGBE_VLANCTL);
1144 : 0 : vlnctrl &= ~TXGBE_VLANCTL_VFE;
1145 : : wr32(hw, TXGBE_VLANCTL, vlnctrl);
1146 : 0 : }
1147 : :
1148 : : void
1149 : 0 : txgbe_vlan_hw_filter_enable(struct rte_eth_dev *dev)
1150 : : {
1151 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
1152 : : struct txgbe_vfta *shadow_vfta = TXGBE_DEV_VFTA(dev);
1153 : : uint32_t vlnctrl;
1154 : : uint16_t i;
1155 : :
1156 : 0 : PMD_INIT_FUNC_TRACE();
1157 : :
1158 : : /* Filter Table Enable */
1159 : : vlnctrl = rd32(hw, TXGBE_VLANCTL);
1160 : 0 : vlnctrl &= ~TXGBE_VLANCTL_CFIENA;
1161 : 0 : vlnctrl |= TXGBE_VLANCTL_VFE;
1162 : : wr32(hw, TXGBE_VLANCTL, vlnctrl);
1163 : :
1164 : : /* write whatever is in local vfta copy */
1165 [ # # ]: 0 : for (i = 0; i < TXGBE_VFTA_SIZE; i++)
1166 : 0 : wr32(hw, TXGBE_VLANTBL(i), shadow_vfta->vfta[i]);
1167 : 0 : }
1168 : :
1169 : : void
1170 : 0 : txgbe_vlan_hw_strip_bitmap_set(struct rte_eth_dev *dev, uint16_t queue, bool on)
1171 : : {
1172 : 0 : struct txgbe_hwstrip *hwstrip = TXGBE_DEV_HWSTRIP(dev);
1173 : : struct txgbe_rx_queue *rxq;
1174 : :
1175 [ # # ]: 0 : if (queue >= TXGBE_MAX_RX_QUEUE_NUM)
1176 : : return;
1177 : :
1178 [ # # ]: 0 : if (on)
1179 : 0 : TXGBE_SET_HWSTRIP(hwstrip, queue);
1180 : : else
1181 : 0 : TXGBE_CLEAR_HWSTRIP(hwstrip, queue);
1182 : :
1183 [ # # ]: 0 : if (queue >= dev->data->nb_rx_queues)
1184 : : return;
1185 : :
1186 : 0 : rxq = dev->data->rx_queues[queue];
1187 : :
1188 [ # # ]: 0 : if (on) {
1189 : 0 : rxq->vlan_flags = RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
1190 : 0 : rxq->offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
1191 : : } else {
1192 : 0 : rxq->vlan_flags = RTE_MBUF_F_RX_VLAN;
1193 : 0 : rxq->offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
1194 : : }
1195 : : }
1196 : :
1197 : : static void
1198 : 0 : txgbe_vlan_hw_strip_disable(struct rte_eth_dev *dev, uint16_t queue)
1199 : : {
1200 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
1201 : : uint32_t ctrl;
1202 : :
1203 : 0 : PMD_INIT_FUNC_TRACE();
1204 : :
1205 : 0 : ctrl = rd32(hw, TXGBE_RXCFG(queue));
1206 : 0 : ctrl &= ~TXGBE_RXCFG_VLAN;
1207 : : wr32(hw, TXGBE_RXCFG(queue), ctrl);
1208 : :
1209 : : /* record those setting for HW strip per queue */
1210 : 0 : txgbe_vlan_hw_strip_bitmap_set(dev, queue, 0);
1211 : 0 : }
1212 : :
1213 : : static void
1214 : 0 : txgbe_vlan_hw_strip_enable(struct rte_eth_dev *dev, uint16_t queue)
1215 : : {
1216 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
1217 : : uint32_t ctrl;
1218 : :
1219 : 0 : PMD_INIT_FUNC_TRACE();
1220 : :
1221 : 0 : ctrl = rd32(hw, TXGBE_RXCFG(queue));
1222 : 0 : ctrl |= TXGBE_RXCFG_VLAN;
1223 : : wr32(hw, TXGBE_RXCFG(queue), ctrl);
1224 : :
1225 : : /* record those setting for HW strip per queue */
1226 : 0 : txgbe_vlan_hw_strip_bitmap_set(dev, queue, 1);
1227 : 0 : }
1228 : :
1229 : : static void
1230 : 0 : txgbe_vlan_hw_extend_disable(struct rte_eth_dev *dev)
1231 : : {
1232 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
1233 : : uint32_t ctrl;
1234 : :
1235 : 0 : PMD_INIT_FUNC_TRACE();
1236 : :
1237 : : ctrl = rd32(hw, TXGBE_PORTCTL);
1238 : 0 : ctrl &= ~TXGBE_PORTCTL_VLANEXT;
1239 : : wr32(hw, TXGBE_PORTCTL, ctrl);
1240 : 0 : }
1241 : :
1242 : : static void
1243 : 0 : txgbe_vlan_hw_extend_enable(struct rte_eth_dev *dev)
1244 : : {
1245 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
1246 : : uint32_t ctrl;
1247 : :
1248 : 0 : PMD_INIT_FUNC_TRACE();
1249 : :
1250 : : ctrl = rd32(hw, TXGBE_PORTCTL);
1251 : 0 : ctrl |= TXGBE_PORTCTL_VLANEXT;
1252 : : wr32(hw, TXGBE_PORTCTL, ctrl);
1253 : 0 : }
1254 : :
1255 : : static void
1256 : 0 : txgbe_qinq_hw_strip_disable(struct rte_eth_dev *dev)
1257 : : {
1258 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
1259 : : uint32_t ctrl;
1260 : :
1261 : 0 : PMD_INIT_FUNC_TRACE();
1262 : :
1263 : : ctrl = rd32(hw, TXGBE_PORTCTL);
1264 : 0 : ctrl &= ~TXGBE_PORTCTL_QINQ;
1265 : : wr32(hw, TXGBE_PORTCTL, ctrl);
1266 : 0 : }
1267 : :
1268 : : static void
1269 : 0 : txgbe_qinq_hw_strip_enable(struct rte_eth_dev *dev)
1270 : : {
1271 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
1272 : : uint32_t ctrl;
1273 : :
1274 : 0 : PMD_INIT_FUNC_TRACE();
1275 : :
1276 : : ctrl = rd32(hw, TXGBE_PORTCTL);
1277 : 0 : ctrl |= TXGBE_PORTCTL_QINQ | TXGBE_PORTCTL_VLANEXT;
1278 : : wr32(hw, TXGBE_PORTCTL, ctrl);
1279 : 0 : }
1280 : :
1281 : : void
1282 : 0 : txgbe_vlan_hw_strip_config(struct rte_eth_dev *dev)
1283 : : {
1284 : : struct txgbe_rx_queue *rxq;
1285 : : uint16_t i;
1286 : :
1287 : 0 : PMD_INIT_FUNC_TRACE();
1288 : :
1289 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
1290 : 0 : rxq = dev->data->rx_queues[i];
1291 : :
1292 [ # # ]: 0 : if (rxq->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
1293 : 0 : txgbe_vlan_strip_q_set(dev, i, 1);
1294 : : else
1295 : 0 : txgbe_vlan_strip_q_set(dev, i, 0);
1296 : : }
1297 : 0 : }
1298 : :
1299 : : void
1300 : 0 : txgbe_config_vlan_strip_on_all_queues(struct rte_eth_dev *dev, int mask)
1301 : : {
1302 : : uint16_t i;
1303 : : struct rte_eth_rxmode *rxmode;
1304 : : struct txgbe_rx_queue *rxq;
1305 : :
1306 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_STRIP_MASK) {
1307 : 0 : rxmode = &dev->data->dev_conf.rxmode;
1308 [ # # ]: 0 : if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
1309 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
1310 : 0 : rxq = dev->data->rx_queues[i];
1311 : 0 : rxq->offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
1312 : : }
1313 : : else
1314 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
1315 : 0 : rxq = dev->data->rx_queues[i];
1316 : 0 : rxq->offloads &= ~RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
1317 : : }
1318 : : }
1319 : 0 : }
1320 : :
1321 : : static int
1322 : 0 : txgbe_vlan_offload_config(struct rte_eth_dev *dev, int mask)
1323 : : {
1324 : : struct rte_eth_rxmode *rxmode;
1325 : 0 : rxmode = &dev->data->dev_conf.rxmode;
1326 : :
1327 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_STRIP_MASK)
1328 : 0 : txgbe_vlan_hw_strip_config(dev);
1329 : :
1330 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_FILTER_MASK) {
1331 [ # # ]: 0 : if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER)
1332 : 0 : txgbe_vlan_hw_filter_enable(dev);
1333 : : else
1334 : 0 : txgbe_vlan_hw_filter_disable(dev);
1335 : : }
1336 : :
1337 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_EXTEND_MASK) {
1338 [ # # ]: 0 : if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND)
1339 : 0 : txgbe_vlan_hw_extend_enable(dev);
1340 : : else
1341 : 0 : txgbe_vlan_hw_extend_disable(dev);
1342 : : }
1343 : :
1344 [ # # ]: 0 : if (mask & RTE_ETH_QINQ_STRIP_MASK) {
1345 [ # # ]: 0 : if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_QINQ_STRIP)
1346 : 0 : txgbe_qinq_hw_strip_enable(dev);
1347 : : else
1348 : 0 : txgbe_qinq_hw_strip_disable(dev);
1349 : : }
1350 : :
1351 : 0 : return 0;
1352 : : }
1353 : :
1354 : : static int
1355 : 0 : txgbe_vlan_offload_set(struct rte_eth_dev *dev, int mask)
1356 : : {
1357 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
1358 : :
1359 [ # # # # ]: 0 : if (!hw->adapter_stopped && (mask & RTE_ETH_VLAN_STRIP_MASK)) {
1360 : 0 : PMD_DRV_LOG(ERR, "Please stop port first");
1361 : 0 : return -EPERM;
1362 : : }
1363 : :
1364 : 0 : txgbe_config_vlan_strip_on_all_queues(dev, mask);
1365 : :
1366 : 0 : txgbe_vlan_offload_config(dev, mask);
1367 : :
1368 : 0 : return 0;
1369 : : }
1370 : :
1371 : : static void
1372 : : txgbe_vmdq_vlan_hw_filter_enable(struct rte_eth_dev *dev)
1373 : : {
1374 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
1375 : : /* VLNCTL: enable vlan filtering and allow all vlan tags through */
1376 : : uint32_t vlanctrl = rd32(hw, TXGBE_VLANCTL);
1377 : :
1378 : 0 : vlanctrl |= TXGBE_VLANCTL_VFE; /* enable vlan filters */
1379 : : wr32(hw, TXGBE_VLANCTL, vlanctrl);
1380 : 0 : }
1381 : :
1382 : : static int
1383 : : txgbe_check_vf_rss_rxq_num(struct rte_eth_dev *dev, uint16_t nb_rx_q)
1384 : : {
1385 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1386 : :
1387 [ # # # ]: 0 : switch (nb_rx_q) {
1388 : 0 : case 1:
1389 : : case 2:
1390 : 0 : RTE_ETH_DEV_SRIOV(dev).active = RTE_ETH_64_POOLS;
1391 : 0 : break;
1392 : 0 : case 4:
1393 : 0 : RTE_ETH_DEV_SRIOV(dev).active = RTE_ETH_32_POOLS;
1394 : 0 : break;
1395 : : default:
1396 : : return -EINVAL;
1397 : : }
1398 : :
1399 : 0 : RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool =
1400 : 0 : TXGBE_MAX_RX_QUEUE_NUM / RTE_ETH_DEV_SRIOV(dev).active;
1401 : 0 : RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx =
1402 : 0 : pci_dev->max_vfs * RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool;
1403 : : return 0;
1404 : : }
1405 : :
1406 : : static int
1407 : 0 : txgbe_check_mq_mode(struct rte_eth_dev *dev)
1408 : : {
1409 : 0 : struct rte_eth_conf *dev_conf = &dev->data->dev_conf;
1410 : 0 : uint16_t nb_rx_q = dev->data->nb_rx_queues;
1411 : 0 : uint16_t nb_tx_q = dev->data->nb_tx_queues;
1412 : :
1413 [ # # ]: 0 : if (RTE_ETH_DEV_SRIOV(dev).active != 0) {
1414 : : /* check multi-queue mode */
1415 [ # # # # : 0 : switch (dev_conf->rxmode.mq_mode) {
# ]
1416 : 0 : case RTE_ETH_MQ_RX_VMDQ_DCB:
1417 : 0 : PMD_INIT_LOG(INFO, "RTE_ETH_MQ_RX_VMDQ_DCB mode supported in SRIOV");
1418 : 0 : break;
1419 : 0 : case RTE_ETH_MQ_RX_VMDQ_DCB_RSS:
1420 : : /* DCB/RSS VMDQ in SRIOV mode, not implement yet */
1421 : 0 : PMD_INIT_LOG(ERR, "SRIOV active,"
1422 : : " unsupported mq_mode rx %d.",
1423 : : dev_conf->rxmode.mq_mode);
1424 : 0 : return -EINVAL;
1425 : 0 : case RTE_ETH_MQ_RX_RSS:
1426 : : case RTE_ETH_MQ_RX_VMDQ_RSS:
1427 : 0 : dev->data->dev_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_VMDQ_RSS;
1428 [ # # ]: 0 : if (nb_rx_q <= RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool)
1429 : : if (txgbe_check_vf_rss_rxq_num(dev, nb_rx_q)) {
1430 : 0 : PMD_INIT_LOG(ERR, "SRIOV is active,"
1431 : : " invalid queue number"
1432 : : " for VMDQ RSS, allowed"
1433 : : " value are 1, 2 or 4.");
1434 : 0 : return -EINVAL;
1435 : : }
1436 : : break;
1437 : 0 : case RTE_ETH_MQ_RX_VMDQ_ONLY:
1438 : : case RTE_ETH_MQ_RX_NONE:
1439 : : /* if nothing mq mode configure, use default scheme */
1440 : 0 : dev->data->dev_conf.rxmode.mq_mode =
1441 : : RTE_ETH_MQ_RX_VMDQ_ONLY;
1442 : 0 : break;
1443 : 0 : default: /* RTE_ETH_MQ_RX_DCB, RTE_ETH_MQ_RX_DCB_RSS or RTE_ETH_MQ_TX_DCB*/
1444 : : /* SRIOV only works in VMDq enable mode */
1445 : 0 : PMD_INIT_LOG(ERR, "SRIOV is active,"
1446 : : " wrong mq_mode rx %d.",
1447 : : dev_conf->rxmode.mq_mode);
1448 : 0 : return -EINVAL;
1449 : : }
1450 : :
1451 [ # # ]: 0 : switch (dev_conf->txmode.mq_mode) {
1452 : 0 : case RTE_ETH_MQ_TX_VMDQ_DCB:
1453 : 0 : PMD_INIT_LOG(INFO, "RTE_ETH_MQ_TX_VMDQ_DCB mode supported in SRIOV");
1454 : 0 : dev->data->dev_conf.txmode.mq_mode = RTE_ETH_MQ_TX_VMDQ_DCB;
1455 : 0 : break;
1456 : 0 : default: /* RTE_ETH_MQ_TX_VMDQ_ONLY or RTE_ETH_MQ_TX_NONE */
1457 : 0 : dev->data->dev_conf.txmode.mq_mode =
1458 : : RTE_ETH_MQ_TX_VMDQ_ONLY;
1459 : 0 : break;
1460 : : }
1461 : :
1462 : : /* check valid queue number */
1463 [ # # # # ]: 0 : if ((nb_rx_q > RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool) ||
1464 : : (nb_tx_q > RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool)) {
1465 : 0 : PMD_INIT_LOG(ERR, "SRIOV is active,"
1466 : : " nb_rx_q=%d nb_tx_q=%d queue number"
1467 : : " must be less than or equal to %d.",
1468 : : nb_rx_q, nb_tx_q,
1469 : : RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool);
1470 : 0 : return -EINVAL;
1471 : : }
1472 : : } else {
1473 [ # # ]: 0 : if (dev_conf->rxmode.mq_mode == RTE_ETH_MQ_RX_VMDQ_DCB_RSS) {
1474 : 0 : PMD_INIT_LOG(ERR, "VMDQ+DCB+RSS mq_mode is"
1475 : : " not supported.");
1476 : 0 : return -EINVAL;
1477 : : }
1478 : : /* check configuration for vmdb+dcb mode */
1479 [ # # ]: 0 : if (dev_conf->rxmode.mq_mode == RTE_ETH_MQ_RX_VMDQ_DCB) {
1480 : : const struct rte_eth_vmdq_dcb_conf *conf;
1481 : :
1482 [ # # ]: 0 : if (nb_rx_q != TXGBE_VMDQ_DCB_NB_QUEUES) {
1483 : 0 : PMD_INIT_LOG(ERR, "VMDQ+DCB, nb_rx_q != %d.",
1484 : : TXGBE_VMDQ_DCB_NB_QUEUES);
1485 : 0 : return -EINVAL;
1486 : : }
1487 : : conf = &dev_conf->rx_adv_conf.vmdq_dcb_conf;
1488 [ # # ]: 0 : if (!(conf->nb_queue_pools == RTE_ETH_16_POOLS ||
1489 : : conf->nb_queue_pools == RTE_ETH_32_POOLS)) {
1490 : 0 : PMD_INIT_LOG(ERR, "VMDQ+DCB selected,"
1491 : : " nb_queue_pools must be %d or %d.",
1492 : : RTE_ETH_16_POOLS, RTE_ETH_32_POOLS);
1493 : 0 : return -EINVAL;
1494 : : }
1495 : : }
1496 [ # # ]: 0 : if (dev_conf->txmode.mq_mode == RTE_ETH_MQ_TX_VMDQ_DCB) {
1497 : : const struct rte_eth_vmdq_dcb_tx_conf *conf;
1498 : :
1499 [ # # ]: 0 : if (nb_tx_q != TXGBE_VMDQ_DCB_NB_QUEUES) {
1500 : 0 : PMD_INIT_LOG(ERR, "VMDQ+DCB, nb_tx_q != %d",
1501 : : TXGBE_VMDQ_DCB_NB_QUEUES);
1502 : 0 : return -EINVAL;
1503 : : }
1504 : : conf = &dev_conf->tx_adv_conf.vmdq_dcb_tx_conf;
1505 [ # # ]: 0 : if (!(conf->nb_queue_pools == RTE_ETH_16_POOLS ||
1506 : : conf->nb_queue_pools == RTE_ETH_32_POOLS)) {
1507 : 0 : PMD_INIT_LOG(ERR, "VMDQ+DCB selected,"
1508 : : " nb_queue_pools != %d and"
1509 : : " nb_queue_pools != %d.",
1510 : : RTE_ETH_16_POOLS, RTE_ETH_32_POOLS);
1511 : 0 : return -EINVAL;
1512 : : }
1513 : : }
1514 : :
1515 : : /* For DCB mode check our configuration before we go further */
1516 [ # # ]: 0 : if (dev_conf->rxmode.mq_mode == RTE_ETH_MQ_RX_DCB) {
1517 : : const struct rte_eth_dcb_rx_conf *conf;
1518 : :
1519 : : conf = &dev_conf->rx_adv_conf.dcb_rx_conf;
1520 [ # # ]: 0 : if (!(conf->nb_tcs == RTE_ETH_4_TCS ||
1521 : : conf->nb_tcs == RTE_ETH_8_TCS)) {
1522 : 0 : PMD_INIT_LOG(ERR, "DCB selected, nb_tcs != %d"
1523 : : " and nb_tcs != %d.",
1524 : : RTE_ETH_4_TCS, RTE_ETH_8_TCS);
1525 : 0 : return -EINVAL;
1526 : : }
1527 : : }
1528 : :
1529 [ # # ]: 0 : if (dev_conf->txmode.mq_mode == RTE_ETH_MQ_TX_DCB) {
1530 : : const struct rte_eth_dcb_tx_conf *conf;
1531 : :
1532 : : conf = &dev_conf->tx_adv_conf.dcb_tx_conf;
1533 [ # # ]: 0 : if (!(conf->nb_tcs == RTE_ETH_4_TCS ||
1534 : : conf->nb_tcs == RTE_ETH_8_TCS)) {
1535 : 0 : PMD_INIT_LOG(ERR, "DCB selected, nb_tcs != %d"
1536 : : " and nb_tcs != %d.",
1537 : : RTE_ETH_4_TCS, RTE_ETH_8_TCS);
1538 : 0 : return -EINVAL;
1539 : : }
1540 : : }
1541 : :
1542 : : /*
1543 : : * When DCB/VT is off, maximum number of queues changes
1544 : : */
1545 [ # # ]: 0 : if (dev_conf->txmode.mq_mode == RTE_ETH_MQ_TX_NONE) {
1546 [ # # ]: 0 : if (nb_tx_q > TXGBE_NONE_MODE_TX_NB_QUEUES) {
1547 : 0 : PMD_INIT_LOG(ERR,
1548 : : "Neither VT nor DCB are enabled, "
1549 : : "nb_tx_q > %d.",
1550 : : TXGBE_NONE_MODE_TX_NB_QUEUES);
1551 : 0 : return -EINVAL;
1552 : : }
1553 : : }
1554 : : }
1555 : : return 0;
1556 : : }
1557 : :
1558 : : static int
1559 : 0 : txgbe_dev_configure(struct rte_eth_dev *dev)
1560 : : {
1561 : 0 : struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
1562 : : struct txgbe_adapter *adapter = TXGBE_DEV_ADAPTER(dev);
1563 : : int ret;
1564 : :
1565 : 0 : PMD_INIT_FUNC_TRACE();
1566 : :
1567 [ # # ]: 0 : if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG)
1568 : 0 : dev->data->dev_conf.rxmode.offloads |= RTE_ETH_RX_OFFLOAD_RSS_HASH;
1569 : :
1570 : : /* multiple queue mode checking */
1571 : 0 : ret = txgbe_check_mq_mode(dev);
1572 [ # # ]: 0 : if (ret != 0) {
1573 : 0 : PMD_DRV_LOG(ERR, "txgbe_check_mq_mode fails with %d.",
1574 : : ret);
1575 : 0 : return ret;
1576 : : }
1577 : :
1578 : : /* set flag to update link status after init */
1579 : 0 : intr->flags |= TXGBE_FLAG_NEED_LINK_UPDATE;
1580 : :
1581 : : /*
1582 : : * Initialize to TRUE. If any of Rx queues doesn't meet the bulk
1583 : : * allocation Rx preconditions we will reset it.
1584 : : */
1585 : 0 : adapter->rx_bulk_alloc_allowed = true;
1586 : 0 : adapter->rx_vec_allowed = true;
1587 : :
1588 : 0 : return 0;
1589 : : }
1590 : :
1591 : 0 : static void txgbe_reinit_gpio_intr(struct txgbe_hw *hw)
1592 : : {
1593 : : u32 reg;
1594 : :
1595 : : wr32(hw, TXGBE_GPIOINTMASK, 0xFF);
1596 : : reg = rd32(hw, TXGBE_GPIORAWINTSTAT);
1597 : :
1598 [ # # ]: 0 : if (reg & TXGBE_GPIOBIT_0)
1599 : : wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_0);
1600 : :
1601 [ # # ]: 0 : if (reg & TXGBE_GPIOBIT_2)
1602 : : wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_2);
1603 : :
1604 [ # # ]: 0 : if (reg & TXGBE_GPIOBIT_3)
1605 : : wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_3);
1606 : :
1607 [ # # ]: 0 : if (reg & TXGBE_GPIOBIT_6)
1608 : : wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_6);
1609 : :
1610 : : wr32(hw, TXGBE_GPIOINTMASK, 0);
1611 : 0 : }
1612 : :
1613 : : static void
1614 : 0 : txgbe_dev_phy_intr_setup(struct rte_eth_dev *dev)
1615 : : {
1616 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
1617 : : struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
1618 : 0 : u8 device_type = hw->subsystem_device_id & 0xF0;
1619 : : uint32_t gpie;
1620 : :
1621 : 0 : if (device_type != TXGBE_DEV_ID_MAC_XAUI &&
1622 [ # # ]: 0 : device_type != TXGBE_DEV_ID_MAC_SGMII) {
1623 : : gpie = rd32(hw, TXGBE_GPIOINTEN);
1624 : 0 : gpie |= TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3 | TXGBE_GPIOBIT_6;
1625 : : wr32(hw, TXGBE_GPIOINTEN, gpie);
1626 : :
1627 : : gpie = rd32(hw, TXGBE_GPIOINTTYPE);
1628 : 0 : gpie |= TXGBE_GPIOBIT_2 | TXGBE_GPIOBIT_3 | TXGBE_GPIOBIT_6;
1629 : : wr32(hw, TXGBE_GPIOINTTYPE, gpie);
1630 : : }
1631 : :
1632 : 0 : intr->mask_misc |= TXGBE_ICRMISC_GPIO;
1633 : 0 : intr->mask_misc |= TXGBE_ICRMISC_ANDONE;
1634 : 0 : intr->mask_misc |= TXGBE_ICRMISC_HEAT;
1635 : 0 : }
1636 : :
1637 : : int
1638 : 0 : txgbe_set_vf_rate_limit(struct rte_eth_dev *dev, uint16_t vf,
1639 : : uint16_t tx_rate, uint64_t q_msk)
1640 : : {
1641 : : struct txgbe_hw *hw;
1642 : : struct txgbe_vf_info *vfinfo;
1643 : : struct rte_eth_link link;
1644 : : uint8_t nb_q_per_pool;
1645 : : uint32_t queue_stride;
1646 : : uint32_t queue_idx, idx = 0, vf_idx;
1647 : : uint32_t queue_end;
1648 : : uint16_t total_rate = 0;
1649 : : struct rte_pci_device *pci_dev;
1650 : : int ret;
1651 : :
1652 : 0 : pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1653 : 0 : ret = rte_eth_link_get_nowait(dev->data->port_id, &link);
1654 [ # # ]: 0 : if (ret < 0)
1655 : : return ret;
1656 : :
1657 [ # # ]: 0 : if (vf >= pci_dev->max_vfs)
1658 : : return -EINVAL;
1659 : :
1660 [ # # ]: 0 : if (tx_rate > link.link_speed)
1661 : : return -EINVAL;
1662 : :
1663 [ # # ]: 0 : if (q_msk == 0)
1664 : : return 0;
1665 : :
1666 : 0 : hw = TXGBE_DEV_HW(dev);
1667 : 0 : vfinfo = *(TXGBE_DEV_VFDATA(dev));
1668 : 0 : nb_q_per_pool = RTE_ETH_DEV_SRIOV(dev).nb_q_per_pool;
1669 : 0 : queue_stride = TXGBE_MAX_RX_QUEUE_NUM / RTE_ETH_DEV_SRIOV(dev).active;
1670 : 0 : queue_idx = vf * queue_stride;
1671 : 0 : queue_end = queue_idx + nb_q_per_pool - 1;
1672 [ # # ]: 0 : if (queue_end >= hw->mac.max_tx_queues)
1673 : : return -EINVAL;
1674 : :
1675 [ # # ]: 0 : if (vfinfo) {
1676 [ # # ]: 0 : for (vf_idx = 0; vf_idx < pci_dev->max_vfs; vf_idx++) {
1677 [ # # ]: 0 : if (vf_idx == vf)
1678 : 0 : continue;
1679 [ # # ]: 0 : for (idx = 0; idx < RTE_DIM(vfinfo[vf_idx].tx_rate);
1680 : 0 : idx++)
1681 : 0 : total_rate += vfinfo[vf_idx].tx_rate[idx];
1682 : : }
1683 : : } else {
1684 : : return -EINVAL;
1685 : : }
1686 : :
1687 : : /* Store tx_rate for this vf. */
1688 [ # # ]: 0 : for (idx = 0; idx < nb_q_per_pool; idx++) {
1689 [ # # ]: 0 : if (((uint64_t)0x1 << idx) & q_msk) {
1690 [ # # ]: 0 : if (vfinfo[vf].tx_rate[idx] != tx_rate)
1691 : 0 : vfinfo[vf].tx_rate[idx] = tx_rate;
1692 : 0 : total_rate += tx_rate;
1693 : : }
1694 : : }
1695 : :
1696 [ # # ]: 0 : if (total_rate > dev->data->dev_link.link_speed) {
1697 : : /* Reset stored TX rate of the VF if it causes exceed
1698 : : * link speed.
1699 : : */
1700 : 0 : memset(vfinfo[vf].tx_rate, 0, sizeof(vfinfo[vf].tx_rate));
1701 : 0 : return -EINVAL;
1702 : : }
1703 : :
1704 : : /* Set ARBTXRATE of each queue/pool for vf X */
1705 [ # # ]: 0 : for (; queue_idx <= queue_end; queue_idx++) {
1706 [ # # ]: 0 : if (0x1 & q_msk)
1707 : 0 : txgbe_set_queue_rate_limit(dev, queue_idx, tx_rate);
1708 : 0 : q_msk = q_msk >> 1;
1709 : : }
1710 : :
1711 : : return 0;
1712 : : }
1713 : :
1714 : : /*
1715 : : * Configure device link speed and setup link.
1716 : : * It returns 0 on success.
1717 : : */
1718 : : static int
1719 : 0 : txgbe_dev_start(struct rte_eth_dev *dev)
1720 : : {
1721 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
1722 : 0 : struct txgbe_hw_stats *hw_stats = TXGBE_DEV_STATS(dev);
1723 : 0 : struct txgbe_vf_info *vfinfo = *TXGBE_DEV_VFDATA(dev);
1724 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1725 : 0 : struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
1726 : : uint32_t intr_vector = 0;
1727 : : int err;
1728 : 0 : bool link_up = false, negotiate = 0;
1729 : 0 : uint32_t speed = 0;
1730 : : uint32_t allowed_speeds = 0;
1731 : : int mask = 0;
1732 : : int status;
1733 : : uint16_t vf, idx;
1734 : : uint32_t *link_speeds;
1735 : : struct txgbe_tm_conf *tm_conf = TXGBE_DEV_TM_CONF(dev);
1736 : : u32 links_reg;
1737 : :
1738 : 0 : PMD_INIT_FUNC_TRACE();
1739 : :
1740 : : /* Stop the link setup handler before resetting the HW. */
1741 : 0 : rte_eal_alarm_cancel(txgbe_dev_detect_sfp, dev);
1742 : 0 : txgbe_dev_wait_setup_link_complete(dev, 0);
1743 : :
1744 : : /* disable uio/vfio intr/eventfd mapping */
1745 : 0 : rte_intr_disable(intr_handle);
1746 : :
1747 : : /* stop adapter */
1748 : 0 : hw->adapter_stopped = 0;
1749 : 0 : txgbe_stop_hw(hw);
1750 : :
1751 : : /* reinitialize adapter
1752 : : * this calls reset and start
1753 : : */
1754 : 0 : hw->nb_rx_queues = dev->data->nb_rx_queues;
1755 : 0 : hw->nb_tx_queues = dev->data->nb_tx_queues;
1756 : 0 : status = txgbe_pf_reset_hw(hw);
1757 [ # # ]: 0 : if (status != 0)
1758 : : return -1;
1759 : 0 : hw->mac.start_hw(hw);
1760 : 0 : hw->mac.get_link_status = true;
1761 : 0 : hw->dev_start = true;
1762 : :
1763 : 0 : txgbe_set_pcie_master(hw, true);
1764 : :
1765 : : /* workaround for GPIO intr lost when mng_veto bit is set */
1766 [ # # ]: 0 : if (txgbe_check_reset_blocked(hw))
1767 : 0 : txgbe_reinit_gpio_intr(hw);
1768 : :
1769 : : /* configure PF module if SRIOV enabled */
1770 : 0 : txgbe_pf_host_configure(dev);
1771 : :
1772 : 0 : txgbe_dev_phy_intr_setup(dev);
1773 : :
1774 : : /* check and configure queue intr-vector mapping */
1775 [ # # ]: 0 : if ((rte_intr_cap_multiple(intr_handle) ||
1776 [ # # ]: 0 : !RTE_ETH_DEV_SRIOV(dev).active) &&
1777 [ # # ]: 0 : dev->data->dev_conf.intr_conf.rxq != 0) {
1778 : 0 : intr_vector = dev->data->nb_rx_queues;
1779 [ # # ]: 0 : if (rte_intr_efd_enable(intr_handle, intr_vector))
1780 : : return -1;
1781 : : }
1782 : :
1783 [ # # ]: 0 : if (rte_intr_dp_is_en(intr_handle)) {
1784 [ # # ]: 0 : if (rte_intr_vec_list_alloc(intr_handle, "intr_vec",
1785 : 0 : dev->data->nb_rx_queues)) {
1786 : 0 : PMD_INIT_LOG(ERR, "Failed to allocate %d rx_queues"
1787 : : " intr_vec", dev->data->nb_rx_queues);
1788 : 0 : return -ENOMEM;
1789 : : }
1790 : : }
1791 : : /* configure msix for sleep until rx interrupt */
1792 : 0 : txgbe_configure_msix(dev);
1793 : :
1794 : : /* initialize transmission unit */
1795 : 0 : txgbe_dev_tx_init(dev);
1796 : :
1797 : : /* This can fail when allocating mbufs for descriptor rings */
1798 : 0 : err = txgbe_dev_rx_init(dev);
1799 [ # # ]: 0 : if (err) {
1800 : 0 : PMD_INIT_LOG(ERR, "Unable to initialize RX hardware");
1801 : 0 : goto error;
1802 : : }
1803 : :
1804 : : mask = RTE_ETH_VLAN_STRIP_MASK | RTE_ETH_VLAN_FILTER_MASK |
1805 : : RTE_ETH_VLAN_EXTEND_MASK;
1806 : 0 : err = txgbe_vlan_offload_config(dev, mask);
1807 [ # # ]: 0 : if (err) {
1808 : 0 : PMD_INIT_LOG(ERR, "Unable to set VLAN offload");
1809 : 0 : goto error;
1810 : : }
1811 : :
1812 [ # # ]: 0 : if (dev->data->dev_conf.rxmode.mq_mode == RTE_ETH_MQ_RX_VMDQ_ONLY) {
1813 : : /* Enable vlan filtering for VMDq */
1814 : : txgbe_vmdq_vlan_hw_filter_enable(dev);
1815 : : }
1816 : :
1817 : : /* Configure DCB hw */
1818 : 0 : txgbe_configure_pb(dev);
1819 : 0 : txgbe_configure_port(dev);
1820 : 0 : txgbe_configure_dcb(dev);
1821 : :
1822 [ # # ]: 0 : if (TXGBE_DEV_FDIR_CONF(dev)->mode != RTE_FDIR_MODE_NONE) {
1823 : 0 : err = txgbe_fdir_configure(dev);
1824 [ # # ]: 0 : if (err)
1825 : 0 : goto error;
1826 : : }
1827 : :
1828 : : /* Restore vf rate limit */
1829 [ # # ]: 0 : if (vfinfo != NULL) {
1830 [ # # ]: 0 : for (vf = 0; vf < pci_dev->max_vfs; vf++)
1831 [ # # ]: 0 : for (idx = 0; idx < TXGBE_MAX_QUEUE_NUM_PER_VF; idx++)
1832 [ # # ]: 0 : if (vfinfo[vf].tx_rate[idx] != 0)
1833 : 0 : txgbe_set_vf_rate_limit(dev, vf,
1834 : : vfinfo[vf].tx_rate[idx],
1835 : 0 : 1 << idx);
1836 : : }
1837 : :
1838 : 0 : err = txgbe_dev_rxtx_start(dev);
1839 [ # # ]: 0 : if (err < 0) {
1840 : 0 : PMD_INIT_LOG(ERR, "Unable to start rxtx queues");
1841 : 0 : goto error;
1842 : : }
1843 : :
1844 : : /* Skip link setup if loopback mode is enabled. */
1845 [ # # ]: 0 : if (txgbe_is_pf(hw) &&
1846 [ # # ]: 0 : dev->data->dev_conf.lpbk_mode)
1847 : 0 : goto skip_link_setup;
1848 : :
1849 [ # # ]: 0 : if (txgbe_is_sfp(hw) && hw->phy.multispeed_fiber) {
1850 : 0 : err = hw->mac.setup_sfp(hw);
1851 [ # # ]: 0 : if (err)
1852 : 0 : goto error;
1853 : : }
1854 : :
1855 [ # # ]: 0 : if (hw->phy.media_type == txgbe_media_type_copper) {
1856 : : /* Turn on the copper */
1857 : 0 : hw->phy.set_phy_power(hw, true);
1858 : : } else {
1859 : : /* Turn on the laser */
1860 : 0 : hw->mac.enable_tx_laser(hw);
1861 : : }
1862 : :
1863 [ # # ]: 0 : if ((hw->subsystem_device_id & 0xFF) != TXGBE_DEV_ID_KR_KX_KX4)
1864 : 0 : err = hw->mac.check_link(hw, &speed, &link_up, 0);
1865 [ # # ]: 0 : if (err)
1866 : 0 : goto error;
1867 : 0 : dev->data->dev_link.link_status = link_up;
1868 : :
1869 : 0 : err = hw->mac.get_link_capabilities(hw, &speed, &negotiate);
1870 [ # # ]: 0 : if (err)
1871 : 0 : goto error;
1872 : :
1873 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml40)
1874 : : allowed_speeds = RTE_ETH_LINK_SPEED_40G;
1875 [ # # ]: 0 : else if (hw->mac.type == txgbe_mac_aml)
1876 : : allowed_speeds = RTE_ETH_LINK_SPEED_10G | RTE_ETH_LINK_SPEED_25G;
1877 : : else
1878 : : allowed_speeds = RTE_ETH_LINK_SPEED_100M | RTE_ETH_LINK_SPEED_1G |
1879 : : RTE_ETH_LINK_SPEED_10G;
1880 : :
1881 : 0 : link_speeds = &dev->data->dev_conf.link_speeds;
1882 [ # # ]: 0 : if (((*link_speeds) >> 1) & ~(allowed_speeds >> 1)) {
1883 : 0 : PMD_INIT_LOG(ERR, "Invalid link setting");
1884 : 0 : goto error;
1885 : : }
1886 : :
1887 : 0 : speed = 0x0;
1888 [ # # ]: 0 : if (*link_speeds == RTE_ETH_LINK_SPEED_AUTONEG) {
1889 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml40) {
1890 : 0 : speed = TXGBE_LINK_SPEED_40GB_FULL;
1891 [ # # ]: 0 : } else if (hw->mac.type == txgbe_mac_aml) {
1892 : 0 : speed = (TXGBE_LINK_SPEED_10GB_FULL |
1893 : : TXGBE_LINK_SPEED_25GB_FULL);
1894 : : } else {
1895 : 0 : speed = (TXGBE_LINK_SPEED_100M_FULL |
1896 : : TXGBE_LINK_SPEED_1GB_FULL |
1897 : : TXGBE_LINK_SPEED_10GB_FULL);
1898 : : }
1899 : 0 : hw->autoneg = true;
1900 : : } else {
1901 [ # # ]: 0 : if (*link_speeds & RTE_ETH_LINK_SPEED_40G)
1902 : 0 : speed |= TXGBE_LINK_SPEED_40GB_FULL;
1903 [ # # ]: 0 : if (*link_speeds & RTE_ETH_LINK_SPEED_25G)
1904 : 0 : speed |= TXGBE_LINK_SPEED_25GB_FULL;
1905 [ # # ]: 0 : if (*link_speeds & RTE_ETH_LINK_SPEED_10G)
1906 : 0 : speed |= TXGBE_LINK_SPEED_10GB_FULL;
1907 [ # # ]: 0 : if (*link_speeds & RTE_ETH_LINK_SPEED_1G)
1908 : 0 : speed |= TXGBE_LINK_SPEED_1GB_FULL;
1909 [ # # ]: 0 : if (*link_speeds & RTE_ETH_LINK_SPEED_100M)
1910 : 0 : speed |= TXGBE_LINK_SPEED_100M_FULL;
1911 : 0 : hw->autoneg = false;
1912 : : }
1913 : :
1914 : 0 : err = hw->mac.setup_link(hw, speed, link_up);
1915 [ # # ]: 0 : if (err)
1916 : 0 : goto error;
1917 : :
1918 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml) {
1919 : : links_reg = rd32(hw, TXGBE_PORT);
1920 [ # # ]: 0 : if (links_reg & TXGBE_PORT_LINKUP) {
1921 [ # # ]: 0 : if (links_reg & TXGBE_CFG_PORT_ST_AML_LINK_25G) {
1922 : 0 : wr32(hw, TXGBE_MACTXCFG,
1923 : 0 : (rd32(hw, TXGBE_MACTXCFG) &
1924 : : ~TXGBE_MAC_TX_CFG_AML_SPEED_MASK) |
1925 : : TXGBE_MAC_TX_CFG_AML_SPEED_25G);
1926 [ # # ]: 0 : } else if (links_reg & TXGBE_CFG_PORT_ST_AML_LINK_10G) {
1927 : 0 : wr32(hw, TXGBE_MACTXCFG,
1928 : 0 : (rd32(hw, TXGBE_MACTXCFG) &
1929 : : ~TXGBE_MAC_TX_CFG_AML_SPEED_MASK) |
1930 : : TXGBE_MAC_TX_CFG_AML_SPEED_10G);
1931 : : }
1932 : : }
1933 : :
1934 : : /* amlite: restart gpio */
1935 : : wr32(hw, TXGBE_GPIODIR, TXGBE_GPIOBIT_0 | TXGBE_GPIOBIT_1 |
1936 : : TXGBE_GPIOBIT_4 | TXGBE_GPIOBIT_5);
1937 : : wr32(hw, TXGBE_GPIODATA, TXGBE_GPIOBIT_4 | TXGBE_GPIOBIT_5);
1938 : : msleep(10);
1939 : : wr32(hw, TXGBE_GPIODATA, TXGBE_GPIOBIT_0);
1940 : : wr32m(hw, TXGBE_GPIO_INT_POLARITY, TXGBE_GPIO_INT_POLARITY_3, 0x0);
1941 [ # # ]: 0 : } else if (hw->mac.type == txgbe_mac_aml40) {
1942 : : links_reg = rd32(hw, TXGBE_PORT);
1943 [ # # ]: 0 : if (links_reg & TXGBE_PORT_LINKUP) {
1944 [ # # ]: 0 : if (links_reg & TXGBE_CFG_PORT_ST_AML_LINK_40G) {
1945 : 0 : wr32(hw, TXGBE_MACTXCFG,
1946 : : (rd32(hw, TXGBE_MACTXCFG) &
1947 : : ~TXGBE_MAC_TX_CFG_AML_SPEED_MASK) |
1948 : : TXGBE_MAC_TX_CFG_AML_SPEED_40G);
1949 : : }
1950 : : }
1951 : :
1952 : : wr32(hw, TXGBE_GPIODIR, TXGBE_GPIOBIT_0 | TXGBE_GPIOBIT_1
1953 : : | TXGBE_GPIOBIT_3);
1954 : : wr32(hw, TXGBE_GPIODATA, TXGBE_GPIOBIT_1);
1955 : : }
1956 : 0 : skip_link_setup:
1957 : :
1958 [ # # ]: 0 : if (rte_intr_allow_others(intr_handle)) {
1959 : : txgbe_dev_misc_interrupt_setup(dev);
1960 : : /* check if lsc interrupt is enabled */
1961 : 0 : if (dev->data->dev_conf.intr_conf.lsc != 0)
1962 : : txgbe_dev_lsc_interrupt_setup(dev, TRUE);
1963 : : else
1964 : : txgbe_dev_lsc_interrupt_setup(dev, FALSE);
1965 : : txgbe_dev_macsec_interrupt_setup(dev);
1966 : 0 : txgbe_set_ivar_map(hw, -1, 1, TXGBE_MISC_VEC_ID);
1967 : : } else {
1968 : 0 : rte_intr_callback_unregister(intr_handle,
1969 : : txgbe_dev_interrupt_handler, dev);
1970 [ # # ]: 0 : if (dev->data->dev_conf.intr_conf.lsc != 0)
1971 : 0 : PMD_INIT_LOG(INFO, "lsc won't enable because of"
1972 : : " no intr multiplex");
1973 : : }
1974 : :
1975 : : /* check if rxq interrupt is enabled */
1976 [ # # # # ]: 0 : if (dev->data->dev_conf.intr_conf.rxq != 0 &&
1977 : 0 : rte_intr_dp_is_en(intr_handle))
1978 : : txgbe_dev_rxq_interrupt_setup(dev);
1979 : :
1980 : : /* enable uio/vfio intr/eventfd mapping */
1981 : 0 : rte_intr_enable(intr_handle);
1982 : :
1983 : : /* resume enabled intr since hw reset */
1984 : 0 : txgbe_enable_intr(dev);
1985 : 0 : txgbe_l2_tunnel_conf(dev);
1986 : 0 : txgbe_filter_restore(dev);
1987 : :
1988 [ # # # # ]: 0 : if (tm_conf->root && !tm_conf->committed)
1989 : 0 : PMD_DRV_LOG(WARNING,
1990 : : "please call hierarchy_commit() "
1991 : : "before starting the port");
1992 : :
1993 : : /*
1994 : : * Update link status right before return, because it may
1995 : : * start link configuration process in a separate thread.
1996 : : */
1997 : : txgbe_dev_link_update(dev, 0);
1998 : :
1999 : : wr32m(hw, TXGBE_LEDCTL, 0xFFFFFFFF, TXGBE_LEDCTL_ORD_MASK);
2000 : :
2001 : 0 : txgbe_read_stats_registers(hw, hw_stats);
2002 : 0 : hw->offset_loaded = 1;
2003 : :
2004 : 0 : return 0;
2005 : :
2006 : 0 : error:
2007 : 0 : PMD_INIT_LOG(ERR, "failure in dev start: %d", err);
2008 : 0 : txgbe_dev_clear_queues(dev);
2009 : 0 : return -EIO;
2010 : : }
2011 : :
2012 : : /*
2013 : : * Stop device: disable rx and tx functions to allow for reconfiguring.
2014 : : */
2015 : : static int
2016 : 0 : txgbe_dev_stop(struct rte_eth_dev *dev)
2017 : : {
2018 : : struct rte_eth_link link;
2019 : 0 : struct txgbe_adapter *adapter = TXGBE_DEV_ADAPTER(dev);
2020 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
2021 : 0 : struct txgbe_vf_info *vfinfo = *TXGBE_DEV_VFDATA(dev);
2022 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
2023 : 0 : struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
2024 : : int vf;
2025 : : struct txgbe_tm_conf *tm_conf = TXGBE_DEV_TM_CONF(dev);
2026 : :
2027 [ # # ]: 0 : if (hw->adapter_stopped)
2028 : 0 : goto out;
2029 : :
2030 : 0 : PMD_INIT_FUNC_TRACE();
2031 : :
2032 : 0 : rte_eal_alarm_cancel(txgbe_dev_detect_sfp, dev);
2033 : 0 : rte_eal_alarm_cancel(txgbe_tx_queue_clear_error, dev);
2034 : 0 : txgbe_dev_wait_setup_link_complete(dev, 0);
2035 : :
2036 : : /* disable interrupts */
2037 : 0 : txgbe_disable_intr(hw);
2038 : :
2039 : : /* workaround for GPIO intr lost when mng_veto bit is set */
2040 [ # # ]: 0 : if (txgbe_check_reset_blocked(hw))
2041 : 0 : txgbe_reinit_gpio_intr(hw);
2042 : :
2043 : : /* reset the NIC */
2044 : 0 : txgbe_pf_reset_hw(hw);
2045 : 0 : hw->adapter_stopped = 0;
2046 : :
2047 : : /* stop adapter */
2048 : 0 : txgbe_stop_hw(hw);
2049 : :
2050 [ # # # # ]: 0 : for (vf = 0; vfinfo != NULL && vf < pci_dev->max_vfs; vf++)
2051 : 0 : vfinfo[vf].clear_to_send = false;
2052 : :
2053 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml)
2054 : : wr32m(hw, TXGBE_AML_EPCS_MISC_CTL,
2055 : : TXGBE_AML_LINK_STATUS_OVRD_EN, 0x0);
2056 : :
2057 : 0 : txgbe_dev_clear_queues(dev);
2058 : :
2059 : : /* Clear stored conf */
2060 : 0 : dev->data->scattered_rx = 0;
2061 : 0 : dev->data->lro = 0;
2062 : :
2063 : : /* Clear recorded link status */
2064 : : memset(&link, 0, sizeof(link));
2065 : 0 : rte_eth_linkstatus_set(dev, &link);
2066 : :
2067 [ # # ]: 0 : if (!rte_intr_allow_others(intr_handle))
2068 : : /* resume to the default handler */
2069 : 0 : rte_intr_callback_register(intr_handle,
2070 : : txgbe_dev_interrupt_handler,
2071 : : (void *)dev);
2072 : :
2073 : : /* Clean datapath event and queue/vec mapping */
2074 : 0 : rte_intr_efd_disable(intr_handle);
2075 : 0 : rte_intr_vec_list_free(intr_handle);
2076 : :
2077 : : /* reset hierarchy commit */
2078 : 0 : tm_conf->committed = false;
2079 : :
2080 : 0 : adapter->rss_reta_updated = 0;
2081 : : wr32m(hw, TXGBE_LEDCTL, 0xFFFFFFFF, TXGBE_LEDCTL_SEL_MASK);
2082 : :
2083 : 0 : txgbe_set_pcie_master(hw, true);
2084 : :
2085 : 0 : hw->adapter_stopped = true;
2086 : 0 : dev->data->dev_started = 0;
2087 : 0 : hw->dev_start = false;
2088 : :
2089 : 0 : out:
2090 : : /* close phy to prevent reset in dev_close from restarting physical link */
2091 [ # # ]: 0 : if (hw->phy.media_type == txgbe_media_type_copper) {
2092 : : /* Turn off the copper */
2093 : 0 : hw->phy.set_phy_power(hw, false);
2094 : : } else {
2095 : : /* Turn off the laser */
2096 : 0 : hw->mac.disable_tx_laser(hw);
2097 : : }
2098 : :
2099 : 0 : return 0;
2100 : : }
2101 : :
2102 : : /*
2103 : : * Set device link up: enable tx.
2104 : : */
2105 : : static int
2106 : 0 : txgbe_dev_set_link_up(struct rte_eth_dev *dev)
2107 : : {
2108 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
2109 : :
2110 [ # # ]: 0 : if (hw->phy.media_type == txgbe_media_type_copper) {
2111 : : /* Turn on the copper */
2112 : 0 : hw->phy.set_phy_power(hw, true);
2113 : : } else {
2114 : : /* Turn on the laser */
2115 : 0 : hw->mac.enable_tx_laser(hw);
2116 : 0 : hw->dev_start = true;
2117 : : txgbe_dev_link_update(dev, 0);
2118 : : }
2119 : :
2120 : 0 : return 0;
2121 : : }
2122 : :
2123 : : /*
2124 : : * Set device link down: disable tx.
2125 : : */
2126 : : static int
2127 : 0 : txgbe_dev_set_link_down(struct rte_eth_dev *dev)
2128 : : {
2129 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
2130 : :
2131 [ # # ]: 0 : if (hw->phy.media_type == txgbe_media_type_copper) {
2132 : : /* Turn off the copper */
2133 : 0 : hw->phy.set_phy_power(hw, false);
2134 : : } else {
2135 : : /* Turn off the laser */
2136 : 0 : hw->mac.disable_tx_laser(hw);
2137 : 0 : hw->dev_start = false;
2138 : : txgbe_dev_link_update(dev, 0);
2139 : : }
2140 : :
2141 : 0 : return 0;
2142 : : }
2143 : :
2144 : : /*
2145 : : * Reset and stop device.
2146 : : */
2147 : : static int
2148 : 0 : txgbe_dev_close(struct rte_eth_dev *dev)
2149 : : {
2150 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
2151 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
2152 : 0 : struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
2153 : : int retries = 0;
2154 : : int ret;
2155 : :
2156 : 0 : PMD_INIT_FUNC_TRACE();
2157 : :
2158 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
2159 : : return 0;
2160 : :
2161 : 0 : txgbe_pf_reset_hw(hw);
2162 : :
2163 : 0 : ret = txgbe_dev_stop(dev);
2164 : :
2165 : : /* Let firmware take over control of hardware */
2166 : : wr32m(hw, TXGBE_PORTCTL, TXGBE_PORTCTL_DRVLOAD, 0);
2167 : :
2168 : 0 : txgbe_dev_free_queues(dev);
2169 : :
2170 : 0 : txgbe_set_pcie_master(hw, false);
2171 : :
2172 : : /* reprogram the RAR[0] in case user changed it. */
2173 : 0 : txgbe_set_rar(hw, 0, hw->mac.addr, 0, true);
2174 : :
2175 : : /* Unlock any pending hardware semaphore */
2176 : 0 : txgbe_swfw_lock_reset(hw);
2177 : :
2178 : : /* disable uio intr before callback unregister */
2179 : 0 : rte_intr_disable(intr_handle);
2180 : :
2181 : : do {
2182 : 0 : ret = rte_intr_callback_unregister(intr_handle,
2183 : : txgbe_dev_interrupt_handler, dev);
2184 [ # # ]: 0 : if (ret >= 0 || ret == -ENOENT) {
2185 : : break;
2186 [ # # ]: 0 : } else if (ret != -EAGAIN) {
2187 : 0 : PMD_INIT_LOG(ERR,
2188 : : "intr callback unregister failed: %d",
2189 : : ret);
2190 : : }
2191 : : rte_delay_ms(100);
2192 [ # # ]: 0 : } while (retries++ < (10 + TXGBE_LINK_UP_TIME));
2193 : :
2194 : : /* cancel all alarm handler before remove dev */
2195 : 0 : rte_eal_alarm_cancel(txgbe_dev_interrupt_delayed_handler, dev);
2196 : 0 : rte_eal_alarm_cancel(txgbe_dev_detect_sfp, dev);
2197 : 0 : rte_eal_alarm_cancel(txgbe_dev_setup_link_alarm_handler, dev);
2198 : :
2199 : : /* uninitialize PF if max_vfs not zero */
2200 : 0 : txgbe_pf_host_uninit(dev);
2201 : :
2202 : 0 : rte_free(dev->data->mac_addrs);
2203 : 0 : dev->data->mac_addrs = NULL;
2204 : :
2205 : 0 : rte_free(dev->data->hash_mac_addrs);
2206 : 0 : dev->data->hash_mac_addrs = NULL;
2207 : :
2208 : : /* remove all the fdir filters & hash */
2209 : 0 : txgbe_fdir_filter_uninit(dev);
2210 : :
2211 : : /* remove all the L2 tunnel filters & hash */
2212 : 0 : txgbe_l2_tn_filter_uninit(dev);
2213 : :
2214 : : /* Remove all ntuple filters of the device */
2215 : 0 : txgbe_ntuple_filter_uninit(dev);
2216 : :
2217 : : /* clear all the filters list */
2218 : 0 : txgbe_filterlist_flush();
2219 : :
2220 : : /* Remove all Traffic Manager configuration */
2221 : 0 : txgbe_tm_conf_uninit(dev);
2222 : :
2223 : : #ifdef RTE_LIB_SECURITY
2224 : 0 : rte_free(dev->security_ctx);
2225 : 0 : dev->security_ctx = NULL;
2226 : : #endif
2227 : :
2228 : 0 : return ret;
2229 : : }
2230 : :
2231 : : /*
2232 : : * Reset PF device.
2233 : : */
2234 : : static int
2235 : 0 : txgbe_dev_reset(struct rte_eth_dev *dev)
2236 : : {
2237 : : int ret;
2238 : :
2239 : : /* When a DPDK PMD PF begin to reset PF port, it should notify all
2240 : : * its VF to make them align with it. The detailed notification
2241 : : * mechanism is PMD specific. As to txgbe PF, it is rather complex.
2242 : : * To avoid unexpected behavior in VF, currently reset of PF with
2243 : : * SR-IOV activation is not supported. It might be supported later.
2244 : : */
2245 [ # # ]: 0 : if (dev->data->sriov.active)
2246 : : return -ENOTSUP;
2247 : :
2248 : 0 : ret = eth_txgbe_dev_uninit(dev);
2249 [ # # ]: 0 : if (ret)
2250 : : return ret;
2251 : :
2252 : 0 : ret = eth_txgbe_dev_init(dev, NULL);
2253 : :
2254 : 0 : return ret;
2255 : : }
2256 : :
2257 : : #define UPDATE_QP_COUNTER_32bit(reg, last_counter, counter) \
2258 : : { \
2259 : : uint32_t current_counter = rd32(hw, reg); \
2260 : : if (current_counter < last_counter) \
2261 : : current_counter += 0x100000000LL; \
2262 : : if (!hw->offset_loaded) \
2263 : : last_counter = current_counter; \
2264 : : counter = current_counter - last_counter; \
2265 : : counter &= 0xFFFFFFFFLL; \
2266 : : }
2267 : :
2268 : : #define UPDATE_QP_COUNTER_36bit(reg_lsb, reg_msb, last_counter, counter) \
2269 : : { \
2270 : : uint64_t current_counter_lsb = rd32(hw, reg_lsb); \
2271 : : uint64_t current_counter_msb = rd32(hw, reg_msb); \
2272 : : uint64_t current_counter = (current_counter_msb << 32) | \
2273 : : current_counter_lsb; \
2274 : : if (current_counter < last_counter) \
2275 : : current_counter += 0x1000000000LL; \
2276 : : if (!hw->offset_loaded) \
2277 : : last_counter = current_counter; \
2278 : : counter = current_counter - last_counter; \
2279 : : counter &= 0xFFFFFFFFFLL; \
2280 : : }
2281 : :
2282 : : void
2283 : 0 : txgbe_read_stats_registers(struct txgbe_hw *hw,
2284 : : struct txgbe_hw_stats *hw_stats)
2285 : : {
2286 : : unsigned int i;
2287 : :
2288 : : /* QP Stats */
2289 [ # # ]: 0 : for (i = 0; i < hw->nb_rx_queues; i++) {
2290 [ # # ]: 0 : UPDATE_QP_COUNTER_32bit(TXGBE_QPRXPKT(i),
2291 : : hw->qp_last[i].rx_qp_packets,
2292 : : hw_stats->qp[i].rx_qp_packets);
2293 [ # # # # ]: 0 : UPDATE_QP_COUNTER_36bit(TXGBE_QPRXOCTL(i), TXGBE_QPRXOCTH(i),
2294 : : hw->qp_last[i].rx_qp_bytes,
2295 : : hw_stats->qp[i].rx_qp_bytes);
2296 [ # # ]: 0 : UPDATE_QP_COUNTER_32bit(TXGBE_QPRXMPKT(i),
2297 : : hw->qp_last[i].rx_qp_mc_packets,
2298 : : hw_stats->qp[i].rx_qp_mc_packets);
2299 : : }
2300 : :
2301 [ # # ]: 0 : for (i = 0; i < hw->nb_tx_queues; i++) {
2302 [ # # ]: 0 : UPDATE_QP_COUNTER_32bit(TXGBE_QPTXPKT(i),
2303 : : hw->qp_last[i].tx_qp_packets,
2304 : : hw_stats->qp[i].tx_qp_packets);
2305 [ # # # # ]: 0 : UPDATE_QP_COUNTER_36bit(TXGBE_QPTXOCTL(i), TXGBE_QPTXOCTH(i),
2306 : : hw->qp_last[i].tx_qp_bytes,
2307 : : hw_stats->qp[i].tx_qp_bytes);
2308 : : }
2309 : : /* PB Stats */
2310 [ # # ]: 0 : for (i = 0; i < TXGBE_MAX_UP; i++) {
2311 : 0 : hw_stats->up[i].rx_up_xon_packets +=
2312 : 0 : rd32(hw, TXGBE_PBRXUPXON(i));
2313 : 0 : hw_stats->up[i].rx_up_xoff_packets +=
2314 : 0 : rd32(hw, TXGBE_PBRXUPXOFF(i));
2315 : 0 : hw_stats->up[i].tx_up_xon_packets +=
2316 : 0 : rd32(hw, TXGBE_PBTXUPXON(i));
2317 : 0 : hw_stats->up[i].tx_up_xoff_packets +=
2318 : 0 : rd32(hw, TXGBE_PBTXUPXOFF(i));
2319 : 0 : hw_stats->up[i].tx_up_xon2off_packets +=
2320 : 0 : rd32(hw, TXGBE_PBTXUPOFF(i));
2321 : 0 : hw_stats->up[i].rx_up_dropped +=
2322 : 0 : rd32(hw, TXGBE_PBRXMISS(i));
2323 : : }
2324 : 0 : hw_stats->rx_xon_packets += rd32(hw, TXGBE_PBRXLNKXON);
2325 : 0 : hw_stats->rx_xoff_packets += rd32(hw, TXGBE_PBRXLNKXOFF);
2326 : 0 : hw_stats->tx_xon_packets += rd32(hw, TXGBE_PBTXLNKXON);
2327 : 0 : hw_stats->tx_xoff_packets += rd32(hw, TXGBE_PBTXLNKXOFF);
2328 : :
2329 : : /* DMA Stats */
2330 : 0 : hw_stats->rx_packets += rd32(hw, TXGBE_DMARXPKT);
2331 : 0 : hw_stats->tx_packets += rd32(hw, TXGBE_DMATXPKT);
2332 : :
2333 : 0 : hw_stats->rx_bytes += rd64(hw, TXGBE_DMARXOCTL);
2334 : 0 : hw_stats->tx_bytes += rd64(hw, TXGBE_DMATXOCTL);
2335 : 0 : hw_stats->rx_dma_drop += rd32(hw, TXGBE_DMARXDROP);
2336 : 0 : hw_stats->rx_rdb_drop += rd32(hw, TXGBE_PBRXDROP);
2337 : :
2338 : : /* MAC Stats */
2339 : 0 : hw_stats->rx_crc_errors += rd64(hw, TXGBE_MACRXERRCRCL);
2340 : 0 : hw_stats->rx_multicast_packets += rd64(hw, TXGBE_MACRXMPKTL);
2341 : 0 : hw_stats->tx_multicast_packets += rd64(hw, TXGBE_MACTXMPKTL);
2342 : :
2343 : 0 : hw_stats->rx_total_packets += rd64(hw, TXGBE_MACRXPKTL);
2344 : 0 : hw_stats->tx_total_packets += rd64(hw, TXGBE_MACTXPKTL);
2345 : 0 : hw_stats->rx_total_bytes += rd64(hw, TXGBE_MACRXGBOCTL);
2346 : :
2347 : 0 : hw_stats->rx_broadcast_packets += rd64(hw, TXGBE_MACRXOCTL);
2348 : 0 : hw_stats->tx_broadcast_packets += rd64(hw, TXGBE_MACTXOCTL);
2349 : :
2350 : 0 : hw_stats->rx_size_64_packets += rd64(hw, TXGBE_MACRX1TO64L);
2351 : 0 : hw_stats->rx_size_65_to_127_packets += rd64(hw, TXGBE_MACRX65TO127L);
2352 : 0 : hw_stats->rx_size_128_to_255_packets += rd64(hw, TXGBE_MACRX128TO255L);
2353 : 0 : hw_stats->rx_size_256_to_511_packets += rd64(hw, TXGBE_MACRX256TO511L);
2354 : 0 : hw_stats->rx_size_512_to_1023_packets +=
2355 : : rd64(hw, TXGBE_MACRX512TO1023L);
2356 : 0 : hw_stats->rx_size_1024_to_max_packets +=
2357 : : rd64(hw, TXGBE_MACRX1024TOMAXL);
2358 : 0 : hw_stats->tx_size_64_packets += rd64(hw, TXGBE_MACTX1TO64L);
2359 : 0 : hw_stats->tx_size_65_to_127_packets += rd64(hw, TXGBE_MACTX65TO127L);
2360 : 0 : hw_stats->tx_size_128_to_255_packets += rd64(hw, TXGBE_MACTX128TO255L);
2361 : 0 : hw_stats->tx_size_256_to_511_packets += rd64(hw, TXGBE_MACTX256TO511L);
2362 : 0 : hw_stats->tx_size_512_to_1023_packets +=
2363 : : rd64(hw, TXGBE_MACTX512TO1023L);
2364 : 0 : hw_stats->tx_size_1024_to_max_packets +=
2365 : : rd64(hw, TXGBE_MACTX1024TOMAXL);
2366 : :
2367 : 0 : hw_stats->rx_length_errors += rd64(hw, TXGBE_MACRXERRLENL);
2368 : 0 : hw_stats->rx_undersize_errors += rd32(hw, TXGBE_MACRXUNDERSIZE);
2369 : 0 : hw_stats->rx_oversize_cnt += rd32(hw, TXGBE_MACRXOVERSIZE);
2370 : 0 : hw_stats->rx_jabber_errors += rd32(hw, TXGBE_MACRXJABBER);
2371 : :
2372 : : /* MNG Stats */
2373 : 0 : hw_stats->mng_bmc2host_packets = rd32(hw, TXGBE_MNGBMC2OS);
2374 : 0 : hw_stats->mng_host2bmc_packets = rd32(hw, TXGBE_MNGOS2BMC);
2375 : 0 : hw_stats->rx_management_packets = rd32(hw, TXGBE_DMARXMNG);
2376 : 0 : hw_stats->tx_management_packets = rd32(hw, TXGBE_DMATXMNG);
2377 : :
2378 : : /* FCoE Stats */
2379 : 0 : hw_stats->rx_fcoe_crc_errors += rd32(hw, TXGBE_FCOECRC);
2380 : 0 : hw_stats->rx_fcoe_mbuf_allocation_errors += rd32(hw, TXGBE_FCOELAST);
2381 : 0 : hw_stats->rx_fcoe_dropped += rd32(hw, TXGBE_FCOERPDC);
2382 : 0 : hw_stats->rx_fcoe_packets += rd32(hw, TXGBE_FCOEPRC);
2383 : 0 : hw_stats->tx_fcoe_packets += rd32(hw, TXGBE_FCOEPTC);
2384 : 0 : hw_stats->rx_fcoe_bytes += rd32(hw, TXGBE_FCOEDWRC);
2385 : 0 : hw_stats->tx_fcoe_bytes += rd32(hw, TXGBE_FCOEDWTC);
2386 : :
2387 : : /* Flow Director Stats */
2388 : 0 : hw_stats->flow_director_matched_filters += rd32(hw, TXGBE_FDIRMATCH);
2389 : 0 : hw_stats->flow_director_missed_filters += rd32(hw, TXGBE_FDIRMISS);
2390 : 0 : hw_stats->flow_director_added_filters +=
2391 : 0 : TXGBE_FDIRUSED_ADD(rd32(hw, TXGBE_FDIRUSED));
2392 : 0 : hw_stats->flow_director_removed_filters +=
2393 : 0 : TXGBE_FDIRUSED_REM(rd32(hw, TXGBE_FDIRUSED));
2394 : 0 : hw_stats->flow_director_filter_add_errors +=
2395 : 0 : TXGBE_FDIRFAIL_ADD(rd32(hw, TXGBE_FDIRFAIL));
2396 : 0 : hw_stats->flow_director_filter_remove_errors +=
2397 : 0 : TXGBE_FDIRFAIL_REM(rd32(hw, TXGBE_FDIRFAIL));
2398 : :
2399 : : /* MACsec Stats */
2400 : 0 : hw_stats->tx_macsec_pkts_untagged += rd32(hw, TXGBE_LSECTX_UTPKT);
2401 : 0 : hw_stats->tx_macsec_pkts_encrypted +=
2402 : 0 : rd32(hw, TXGBE_LSECTX_ENCPKT);
2403 : 0 : hw_stats->tx_macsec_pkts_protected +=
2404 : 0 : rd32(hw, TXGBE_LSECTX_PROTPKT);
2405 : 0 : hw_stats->tx_macsec_octets_encrypted +=
2406 : 0 : rd32(hw, TXGBE_LSECTX_ENCOCT);
2407 : 0 : hw_stats->tx_macsec_octets_protected +=
2408 : 0 : rd32(hw, TXGBE_LSECTX_PROTOCT);
2409 : 0 : hw_stats->rx_macsec_pkts_untagged += rd32(hw, TXGBE_LSECRX_UTPKT);
2410 : 0 : hw_stats->rx_macsec_pkts_badtag += rd32(hw, TXGBE_LSECRX_BTPKT);
2411 : 0 : hw_stats->rx_macsec_pkts_nosci += rd32(hw, TXGBE_LSECRX_NOSCIPKT);
2412 : 0 : hw_stats->rx_macsec_pkts_unknownsci += rd32(hw, TXGBE_LSECRX_UNSCIPKT);
2413 : 0 : hw_stats->rx_macsec_octets_decrypted += rd32(hw, TXGBE_LSECRX_DECOCT);
2414 : 0 : hw_stats->rx_macsec_octets_validated += rd32(hw, TXGBE_LSECRX_VLDOCT);
2415 : 0 : hw_stats->rx_macsec_sc_pkts_unchecked +=
2416 : 0 : rd32(hw, TXGBE_LSECRX_UNCHKPKT);
2417 : 0 : hw_stats->rx_macsec_sc_pkts_delayed += rd32(hw, TXGBE_LSECRX_DLYPKT);
2418 : 0 : hw_stats->rx_macsec_sc_pkts_late += rd32(hw, TXGBE_LSECRX_LATEPKT);
2419 [ # # ]: 0 : for (i = 0; i < 2; i++) {
2420 : 0 : hw_stats->rx_macsec_sa_pkts_ok +=
2421 : 0 : rd32(hw, TXGBE_LSECRX_OKPKT(i));
2422 : 0 : hw_stats->rx_macsec_sa_pkts_invalid +=
2423 : 0 : rd32(hw, TXGBE_LSECRX_INVPKT(i));
2424 : 0 : hw_stats->rx_macsec_sa_pkts_notvalid +=
2425 : 0 : rd32(hw, TXGBE_LSECRX_BADPKT(i));
2426 : : }
2427 : 0 : hw_stats->rx_macsec_sa_pkts_unusedsa +=
2428 : 0 : rd32(hw, TXGBE_LSECRX_INVSAPKT);
2429 : 0 : hw_stats->rx_macsec_sa_pkts_notusingsa +=
2430 : 0 : rd32(hw, TXGBE_LSECRX_BADSAPKT);
2431 : :
2432 : 0 : hw_stats->rx_total_missed_packets = 0;
2433 [ # # ]: 0 : for (i = 0; i < TXGBE_MAX_UP; i++) {
2434 : 0 : hw_stats->rx_total_missed_packets +=
2435 : 0 : hw_stats->up[i].rx_up_dropped;
2436 : : }
2437 : 0 : }
2438 : :
2439 : : static int
2440 : 0 : txgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats,
2441 : : struct eth_queue_stats *qstats)
2442 : : {
2443 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
2444 : 0 : struct txgbe_hw_stats *hw_stats = TXGBE_DEV_STATS(dev);
2445 : : struct txgbe_stat_mappings *stat_mappings =
2446 : : TXGBE_DEV_STAT_MAPPINGS(dev);
2447 : : struct txgbe_tx_queue *txq;
2448 : : uint32_t i, j;
2449 : :
2450 : 0 : txgbe_read_stats_registers(hw, hw_stats);
2451 : :
2452 [ # # ]: 0 : if (stats == NULL)
2453 : : return -EINVAL;
2454 : :
2455 : : /* Fill out the rte_eth_stats statistics structure */
2456 : 0 : stats->ipackets = hw_stats->rx_packets;
2457 : 0 : stats->ibytes = hw_stats->rx_bytes;
2458 : 0 : stats->opackets = hw_stats->tx_packets;
2459 : 0 : stats->obytes = hw_stats->tx_bytes;
2460 : :
2461 [ # # ]: 0 : if (qstats != NULL) {
2462 : 0 : memset(&qstats->q_ipackets, 0, sizeof(qstats->q_ipackets));
2463 : 0 : memset(&qstats->q_opackets, 0, sizeof(qstats->q_opackets));
2464 : 0 : memset(&qstats->q_ibytes, 0, sizeof(qstats->q_ibytes));
2465 : 0 : memset(&qstats->q_obytes, 0, sizeof(qstats->q_obytes));
2466 : 0 : memset(&qstats->q_errors, 0, sizeof(qstats->q_errors));
2467 [ # # ]: 0 : for (i = 0; i < TXGBE_MAX_QP; i++) {
2468 : 0 : uint32_t n = i / NB_QMAP_FIELDS_PER_QSM_REG;
2469 : 0 : uint32_t offset = (i % NB_QMAP_FIELDS_PER_QSM_REG) * 8;
2470 : : uint32_t q_map;
2471 : :
2472 : 0 : q_map = (stat_mappings->rqsm[n] >> offset)
2473 : : & QMAP_FIELD_RESERVED_BITS_MASK;
2474 : : j = (q_map < RTE_ETHDEV_QUEUE_STAT_CNTRS
2475 : : ? q_map : q_map % RTE_ETHDEV_QUEUE_STAT_CNTRS);
2476 : 0 : qstats->q_ipackets[j] += hw_stats->qp[i].rx_qp_packets;
2477 : 0 : qstats->q_ibytes[j] += hw_stats->qp[i].rx_qp_bytes;
2478 : :
2479 : 0 : q_map = (stat_mappings->tqsm[n] >> offset)
2480 : : & QMAP_FIELD_RESERVED_BITS_MASK;
2481 : : j = (q_map < RTE_ETHDEV_QUEUE_STAT_CNTRS
2482 : : ? q_map : q_map % RTE_ETHDEV_QUEUE_STAT_CNTRS);
2483 : 0 : qstats->q_opackets[j] += hw_stats->qp[i].tx_qp_packets;
2484 : 0 : qstats->q_obytes[j] += hw_stats->qp[i].tx_qp_bytes;
2485 : : }
2486 : : }
2487 : :
2488 : : /* Rx Errors */
2489 : 0 : stats->imissed = hw_stats->rx_total_missed_packets +
2490 : 0 : hw_stats->rx_dma_drop;
2491 : 0 : stats->ierrors = hw_stats->rx_crc_errors +
2492 : 0 : hw_stats->rx_mac_short_packet_dropped +
2493 : 0 : hw_stats->rx_length_errors +
2494 : 0 : hw_stats->rx_undersize_errors +
2495 : 0 : hw_stats->rx_rdb_drop +
2496 : 0 : hw_stats->rx_illegal_byte_errors +
2497 : 0 : hw_stats->rx_error_bytes +
2498 : 0 : hw_stats->rx_fragment_errors +
2499 : 0 : hw_stats->rx_fcoe_crc_errors +
2500 : 0 : hw_stats->rx_fcoe_mbuf_allocation_errors;
2501 : :
2502 : : /* Tx Errors */
2503 : 0 : stats->oerrors = 0;
2504 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
2505 : 0 : txq = dev->data->tx_queues[i];
2506 : 0 : stats->oerrors += txq->desc_error;
2507 : : }
2508 : :
2509 : : return 0;
2510 : : }
2511 : :
2512 : : static int
2513 : 0 : txgbe_dev_stats_reset(struct rte_eth_dev *dev)
2514 : : {
2515 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
2516 : 0 : struct txgbe_hw_stats *hw_stats = TXGBE_DEV_STATS(dev);
2517 : : struct txgbe_tx_queue *txq;
2518 : : uint32_t i;
2519 : :
2520 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
2521 : 0 : txq = dev->data->tx_queues[i];
2522 : 0 : txq->desc_error = 0;
2523 : : }
2524 : :
2525 : : /* HW registers are cleared on read */
2526 : 0 : hw->offset_loaded = 0;
2527 : : txgbe_dev_stats_get(dev, NULL, NULL);
2528 : 0 : hw->offset_loaded = 1;
2529 : :
2530 : : /* Reset software totals */
2531 : : memset(hw_stats, 0, sizeof(*hw_stats));
2532 : :
2533 : 0 : return 0;
2534 : : }
2535 : :
2536 : : /* This function calculates the number of xstats based on the current config */
2537 : : static unsigned
2538 : : txgbe_xstats_calc_num(struct rte_eth_dev *dev)
2539 : : {
2540 : 0 : int nb_queues = max(dev->data->nb_rx_queues, dev->data->nb_tx_queues);
2541 : : return TXGBE_NB_HW_STATS +
2542 : 0 : TXGBE_NB_UP_STATS * TXGBE_MAX_UP +
2543 : : TXGBE_NB_QP_STATS * nb_queues;
2544 : : }
2545 : :
2546 : : static inline int
2547 : 0 : txgbe_get_name_by_id(uint32_t id, char *name, uint32_t size)
2548 : : {
2549 : : int nb, st;
2550 : :
2551 : : /* Extended stats from txgbe_hw_stats */
2552 [ # # ]: 0 : if (id < TXGBE_NB_HW_STATS) {
2553 : 0 : snprintf(name, size, "[hw]%s",
2554 : 0 : rte_txgbe_stats_strings[id].name);
2555 : 0 : return 0;
2556 : : }
2557 : 0 : id -= TXGBE_NB_HW_STATS;
2558 : :
2559 : : /* Priority Stats */
2560 [ # # ]: 0 : if (id < TXGBE_NB_UP_STATS * TXGBE_MAX_UP) {
2561 : 0 : nb = id / TXGBE_NB_UP_STATS;
2562 : 0 : st = id % TXGBE_NB_UP_STATS;
2563 : 0 : snprintf(name, size, "[p%u]%s", nb,
2564 : 0 : rte_txgbe_up_strings[st].name);
2565 : 0 : return 0;
2566 : : }
2567 : 0 : id -= TXGBE_NB_UP_STATS * TXGBE_MAX_UP;
2568 : :
2569 : : /* Queue Stats */
2570 [ # # ]: 0 : if (id < TXGBE_NB_QP_STATS * TXGBE_MAX_QP) {
2571 : 0 : nb = id / TXGBE_NB_QP_STATS;
2572 : 0 : st = id % TXGBE_NB_QP_STATS;
2573 : 0 : snprintf(name, size, "[q%u]%s", nb,
2574 : 0 : rte_txgbe_qp_strings[st].name);
2575 : 0 : return 0;
2576 : : }
2577 : : id -= TXGBE_NB_QP_STATS * TXGBE_MAX_QP;
2578 : :
2579 : 0 : return -(int)(id + 1);
2580 : : }
2581 : :
2582 : : static inline int
2583 : 0 : txgbe_get_offset_by_id(uint32_t id, uint32_t *offset)
2584 : : {
2585 : : int nb, st;
2586 : :
2587 : : /* Extended stats from txgbe_hw_stats */
2588 [ # # ]: 0 : if (id < TXGBE_NB_HW_STATS) {
2589 : 0 : *offset = rte_txgbe_stats_strings[id].offset;
2590 : 0 : return 0;
2591 : : }
2592 : 0 : id -= TXGBE_NB_HW_STATS;
2593 : :
2594 : : /* Priority Stats */
2595 [ # # ]: 0 : if (id < TXGBE_NB_UP_STATS * TXGBE_MAX_UP) {
2596 : 0 : nb = id / TXGBE_NB_UP_STATS;
2597 : 0 : st = id % TXGBE_NB_UP_STATS;
2598 : 0 : *offset = rte_txgbe_up_strings[st].offset +
2599 : : nb * (TXGBE_NB_UP_STATS * sizeof(uint64_t));
2600 : 0 : return 0;
2601 : : }
2602 : 0 : id -= TXGBE_NB_UP_STATS * TXGBE_MAX_UP;
2603 : :
2604 : : /* Queue Stats */
2605 [ # # ]: 0 : if (id < TXGBE_NB_QP_STATS * TXGBE_MAX_QP) {
2606 : 0 : nb = id / TXGBE_NB_QP_STATS;
2607 : 0 : st = id % TXGBE_NB_QP_STATS;
2608 : 0 : *offset = rte_txgbe_qp_strings[st].offset +
2609 : : nb * (TXGBE_NB_QP_STATS * sizeof(uint64_t));
2610 : 0 : return 0;
2611 : : }
2612 : :
2613 : : return -1;
2614 : : }
2615 : :
2616 : 0 : static int txgbe_dev_xstats_get_names(struct rte_eth_dev *dev,
2617 : : struct rte_eth_xstat_name *xstats_names, unsigned int limit)
2618 : : {
2619 : : unsigned int i, count;
2620 : :
2621 : : count = txgbe_xstats_calc_num(dev);
2622 [ # # ]: 0 : if (xstats_names == NULL)
2623 : 0 : return count;
2624 : :
2625 : : /* Note: limit >= cnt_stats checked upstream
2626 : : * in rte_eth_xstats_names()
2627 : : */
2628 : 0 : limit = min(limit, count);
2629 : :
2630 : : /* Extended stats from txgbe_hw_stats */
2631 [ # # ]: 0 : for (i = 0; i < limit; i++) {
2632 [ # # ]: 0 : if (txgbe_get_name_by_id(i, xstats_names[i].name,
2633 : : sizeof(xstats_names[i].name))) {
2634 : 0 : PMD_INIT_LOG(WARNING, "id value %d isn't valid", i);
2635 : 0 : break;
2636 : : }
2637 : : }
2638 : :
2639 : 0 : return i;
2640 : : }
2641 : :
2642 : 0 : static int txgbe_dev_xstats_get_names_by_id(struct rte_eth_dev *dev,
2643 : : const uint64_t *ids,
2644 : : struct rte_eth_xstat_name *xstats_names,
2645 : : unsigned int limit)
2646 : : {
2647 : : unsigned int i;
2648 : :
2649 [ # # ]: 0 : if (ids == NULL)
2650 : 0 : return txgbe_dev_xstats_get_names(dev, xstats_names, limit);
2651 : :
2652 [ # # ]: 0 : for (i = 0; i < limit; i++) {
2653 [ # # ]: 0 : if (txgbe_get_name_by_id(ids[i], xstats_names[i].name,
2654 : : sizeof(xstats_names[i].name))) {
2655 : 0 : PMD_INIT_LOG(WARNING, "id value %d isn't valid", i);
2656 : 0 : return -1;
2657 : : }
2658 : : }
2659 : :
2660 : 0 : return i;
2661 : : }
2662 : :
2663 : : static int
2664 : 0 : txgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *xstats,
2665 : : unsigned int limit)
2666 : : {
2667 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
2668 : 0 : struct txgbe_hw_stats *hw_stats = TXGBE_DEV_STATS(dev);
2669 : : unsigned int i, count;
2670 : :
2671 : 0 : txgbe_read_stats_registers(hw, hw_stats);
2672 : :
2673 : : /* If this is a reset xstats is NULL, and we have cleared the
2674 : : * registers by reading them.
2675 : : */
2676 : : count = txgbe_xstats_calc_num(dev);
2677 [ # # ]: 0 : if (xstats == NULL)
2678 : 0 : return count;
2679 : :
2680 : 0 : limit = min(limit, txgbe_xstats_calc_num(dev));
2681 : :
2682 : : /* Extended stats from txgbe_hw_stats */
2683 [ # # ]: 0 : for (i = 0; i < limit; i++) {
2684 : 0 : uint32_t offset = 0;
2685 : :
2686 [ # # ]: 0 : if (txgbe_get_offset_by_id(i, &offset)) {
2687 : 0 : PMD_INIT_LOG(WARNING, "id value %d isn't valid", i);
2688 : 0 : break;
2689 : : }
2690 : 0 : xstats[i].value = *(uint64_t *)(((char *)hw_stats) + offset);
2691 : 0 : xstats[i].id = i;
2692 : : }
2693 : :
2694 : 0 : return i;
2695 : : }
2696 : :
2697 : : static int
2698 : 0 : txgbe_dev_xstats_get_(struct rte_eth_dev *dev, uint64_t *values,
2699 : : unsigned int limit)
2700 : : {
2701 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
2702 : 0 : struct txgbe_hw_stats *hw_stats = TXGBE_DEV_STATS(dev);
2703 : : unsigned int i, count;
2704 : :
2705 : 0 : txgbe_read_stats_registers(hw, hw_stats);
2706 : :
2707 : : /* If this is a reset xstats is NULL, and we have cleared the
2708 : : * registers by reading them.
2709 : : */
2710 : : count = txgbe_xstats_calc_num(dev);
2711 [ # # ]: 0 : if (values == NULL)
2712 : 0 : return count;
2713 : :
2714 : 0 : limit = min(limit, txgbe_xstats_calc_num(dev));
2715 : :
2716 : : /* Extended stats from txgbe_hw_stats */
2717 [ # # ]: 0 : for (i = 0; i < limit; i++) {
2718 : : uint32_t offset;
2719 : :
2720 [ # # ]: 0 : if (txgbe_get_offset_by_id(i, &offset)) {
2721 : 0 : PMD_INIT_LOG(WARNING, "id value %d isn't valid", i);
2722 : 0 : break;
2723 : : }
2724 : 0 : values[i] = *(uint64_t *)(((char *)hw_stats) + offset);
2725 : : }
2726 : :
2727 : 0 : return i;
2728 : : }
2729 : :
2730 : : static int
2731 : 0 : txgbe_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
2732 : : uint64_t *values, unsigned int limit)
2733 : : {
2734 : 0 : struct txgbe_hw_stats *hw_stats = TXGBE_DEV_STATS(dev);
2735 : : unsigned int i;
2736 : :
2737 [ # # ]: 0 : if (ids == NULL)
2738 : 0 : return txgbe_dev_xstats_get_(dev, values, limit);
2739 : :
2740 [ # # ]: 0 : for (i = 0; i < limit; i++) {
2741 : : uint32_t offset;
2742 : :
2743 [ # # ]: 0 : if (txgbe_get_offset_by_id(ids[i], &offset)) {
2744 : 0 : PMD_INIT_LOG(WARNING, "id value %d isn't valid", i);
2745 : 0 : break;
2746 : : }
2747 : 0 : values[i] = *(uint64_t *)(((char *)hw_stats) + offset);
2748 : : }
2749 : :
2750 : 0 : return i;
2751 : : }
2752 : :
2753 : : static int
2754 : 0 : txgbe_dev_xstats_reset(struct rte_eth_dev *dev)
2755 : : {
2756 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
2757 : 0 : struct txgbe_hw_stats *hw_stats = TXGBE_DEV_STATS(dev);
2758 : :
2759 : : /* HW registers are cleared on read */
2760 : 0 : hw->offset_loaded = 0;
2761 : 0 : txgbe_read_stats_registers(hw, hw_stats);
2762 : 0 : hw->offset_loaded = 1;
2763 : :
2764 : : /* Reset software totals */
2765 : : memset(hw_stats, 0, sizeof(*hw_stats));
2766 : :
2767 : 0 : return 0;
2768 : : }
2769 : :
2770 : : static int
2771 : 0 : txgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
2772 : : {
2773 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
2774 : : u32 etrack_id;
2775 : : int ret;
2776 : :
2777 : 0 : hw->phy.get_fw_version(hw, &etrack_id);
2778 : :
2779 [ # # ]: 0 : ret = snprintf(fw_version, fw_size, "0x%08x", etrack_id);
2780 [ # # ]: 0 : if (ret < 0)
2781 : : return -EINVAL;
2782 : :
2783 : 0 : ret += 1; /* add the size of '\0' */
2784 [ # # ]: 0 : if (fw_size < (size_t)ret)
2785 : : return ret;
2786 : : else
2787 : 0 : return 0;
2788 : : }
2789 : :
2790 : : static int
2791 : 0 : txgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
2792 : : {
2793 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
2794 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
2795 : :
2796 : 0 : dev_info->max_rx_queues = (uint16_t)hw->mac.max_rx_queues;
2797 : 0 : dev_info->max_tx_queues = (uint16_t)hw->mac.max_tx_queues;
2798 : 0 : dev_info->min_rx_bufsize = 1024;
2799 : 0 : dev_info->max_rx_pktlen = TXGBE_MAX_MTU + TXGBE_ETH_OVERHEAD;
2800 : 0 : dev_info->min_mtu = RTE_ETHER_MIN_MTU;
2801 : 0 : dev_info->max_mtu = TXGBE_MAX_MTU;
2802 : 0 : dev_info->max_mac_addrs = hw->mac.num_rar_entries;
2803 : 0 : dev_info->max_hash_mac_addrs = TXGBE_VMDQ_NUM_UC_MAC;
2804 : 0 : dev_info->max_vfs = pci_dev->max_vfs;
2805 : 0 : dev_info->max_vmdq_pools = RTE_ETH_64_POOLS;
2806 : 0 : dev_info->vmdq_queue_num = dev_info->max_rx_queues;
2807 : 0 : dev_info->dev_capa &= ~RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP;
2808 : 0 : dev_info->rx_queue_offload_capa = txgbe_get_rx_queue_offloads(dev);
2809 : 0 : dev_info->rx_offload_capa = (txgbe_get_rx_port_offloads(dev) |
2810 : 0 : dev_info->rx_queue_offload_capa);
2811 : 0 : dev_info->tx_queue_offload_capa = txgbe_get_tx_queue_offloads(dev);
2812 : 0 : dev_info->tx_offload_capa = txgbe_get_tx_port_offloads(dev);
2813 : :
2814 : 0 : dev_info->default_rxconf = (struct rte_eth_rxconf) {
2815 : : .rx_thresh = {
2816 : : .pthresh = TXGBE_DEFAULT_RX_PTHRESH,
2817 : : .hthresh = TXGBE_DEFAULT_RX_HTHRESH,
2818 : : .wthresh = TXGBE_DEFAULT_RX_WTHRESH,
2819 : : },
2820 : : .rx_free_thresh = TXGBE_DEFAULT_RX_FREE_THRESH,
2821 : : .rx_drop_en = 0,
2822 : : .offloads = 0,
2823 : : };
2824 : :
2825 : 0 : dev_info->default_txconf = (struct rte_eth_txconf) {
2826 : : .tx_thresh = {
2827 : : .pthresh = TXGBE_DEFAULT_TX_PTHRESH,
2828 : : .hthresh = TXGBE_DEFAULT_TX_HTHRESH,
2829 : : .wthresh = TXGBE_DEFAULT_TX_WTHRESH,
2830 : : },
2831 : : .tx_free_thresh = TXGBE_DEFAULT_TX_FREE_THRESH,
2832 : : .offloads = 0,
2833 : : };
2834 : :
2835 : 0 : dev_info->rx_desc_lim = rx_desc_lim;
2836 : 0 : dev_info->tx_desc_lim = tx_desc_lim;
2837 : :
2838 : 0 : dev_info->hash_key_size = TXGBE_HKEY_MAX_INDEX * sizeof(uint32_t);
2839 : 0 : dev_info->reta_size = RTE_ETH_RSS_RETA_SIZE_128;
2840 : 0 : dev_info->flow_type_rss_offloads = TXGBE_RSS_OFFLOAD_ALL;
2841 : :
2842 : : dev_info->speed_capa = RTE_ETH_LINK_SPEED_1G | RTE_ETH_LINK_SPEED_10G;
2843 : 0 : dev_info->speed_capa |= RTE_ETH_LINK_SPEED_100M;
2844 : :
2845 : : /* Driver-preferred Rx/Tx parameters */
2846 : 0 : dev_info->default_rxportconf.burst_size = 32;
2847 : 0 : dev_info->default_txportconf.burst_size = 32;
2848 : 0 : dev_info->default_rxportconf.nb_queues = 1;
2849 : 0 : dev_info->default_txportconf.nb_queues = 1;
2850 : 0 : dev_info->default_rxportconf.ring_size = 256;
2851 : 0 : dev_info->default_txportconf.ring_size = 256;
2852 : :
2853 : 0 : return 0;
2854 : : }
2855 : :
2856 : : const uint32_t *
2857 : 0 : txgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev, size_t *no_of_elements)
2858 : : {
2859 [ # # # # ]: 0 : if (dev->rx_pkt_burst == txgbe_recv_pkts ||
2860 : : #if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM)
2861 [ # # ]: 0 : dev->rx_pkt_burst == txgbe_recv_pkts_vec ||
2862 [ # # ]: 0 : dev->rx_pkt_burst == txgbe_recv_scattered_pkts_vec ||
2863 : : #endif
2864 [ # # ]: 0 : dev->rx_pkt_burst == txgbe_recv_pkts_lro_single_alloc ||
2865 [ # # ]: 0 : dev->rx_pkt_burst == txgbe_recv_pkts_lro_bulk_alloc ||
2866 : : dev->rx_pkt_burst == txgbe_recv_pkts_bulk_alloc)
2867 : 0 : return txgbe_get_supported_ptypes(no_of_elements);
2868 : :
2869 : : return NULL;
2870 : : }
2871 : :
2872 : : static void
2873 : 0 : txgbe_dev_detect_sfp(void *param)
2874 : : {
2875 : : struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
2876 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
2877 : : u32 value = 0;
2878 : : s32 err;
2879 : :
2880 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml40) {
2881 : : value = rd32(hw, TXGBE_GPIOEXT);
2882 [ # # ]: 0 : if (value & TXGBE_SFP1_MOD_PRST_LS) {
2883 : : err = TXGBE_ERR_SFP_NOT_PRESENT;
2884 : 0 : goto out;
2885 : : }
2886 : : }
2887 : :
2888 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml) {
2889 : : value = rd32(hw, TXGBE_GPIOEXT);
2890 [ # # ]: 0 : if (value & TXGBE_SFP1_MOD_ABS_LS) {
2891 : : err = TXGBE_ERR_SFP_NOT_PRESENT;
2892 : 0 : goto out;
2893 : : }
2894 : : }
2895 : :
2896 : : /* wait for sfp module ready*/
2897 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40)
2898 : : msec_delay(200);
2899 : :
2900 : 0 : err = hw->phy.identify_sfp(hw);
2901 : : out:
2902 [ # # ]: 0 : if (err == TXGBE_ERR_SFP_NOT_SUPPORTED) {
2903 : 0 : PMD_DRV_LOG(ERR, "Unsupported SFP+ module type was detected.");
2904 [ # # ]: 0 : } else if (err == TXGBE_ERR_SFP_NOT_PRESENT) {
2905 : 0 : PMD_DRV_LOG(INFO, "SFP not present.");
2906 [ # # ]: 0 : } else if (err == 0) {
2907 : 0 : hw->mac.setup_sfp(hw);
2908 : 0 : PMD_DRV_LOG(INFO, "detected SFP+: %d", hw->phy.sfp_type);
2909 : 0 : txgbe_dev_setup_link_alarm_handler(dev);
2910 : : txgbe_dev_link_update(dev, 0);
2911 : : }
2912 : 0 : }
2913 : :
2914 : : static void
2915 : 0 : txgbe_dev_sfp_event(struct rte_eth_dev *dev)
2916 : : {
2917 : 0 : struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
2918 : : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
2919 : : u32 reg;
2920 : :
2921 : : wr32(hw, TXGBE_GPIOINTMASK, 0xFF);
2922 : : reg = rd32(hw, TXGBE_GPIORAWINTSTAT);
2923 : :
2924 [ # # ]: 0 : if (reg & TXGBE_GPIOBIT_0)
2925 : : wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_0);
2926 [ # # ]: 0 : if (reg & TXGBE_GPIOBIT_2) {
2927 : : wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_2);
2928 : 0 : rte_eal_alarm_set(1000 * 100, txgbe_dev_detect_sfp, dev);
2929 : : }
2930 [ # # ]: 0 : if (reg & TXGBE_GPIOBIT_3) {
2931 : : wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_3);
2932 : 0 : intr->flags |= TXGBE_FLAG_NEED_LINK_UPDATE;
2933 : : }
2934 [ # # ]: 0 : if (reg & TXGBE_GPIOBIT_6) {
2935 : : wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_6);
2936 : 0 : intr->flags |= TXGBE_FLAG_NEED_LINK_UPDATE;
2937 : : }
2938 : :
2939 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml40) {
2940 [ # # ]: 0 : if (reg & TXGBE_GPIOBIT_4) {
2941 : : wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_4);
2942 : 0 : rte_eal_alarm_set(1000 * 100, txgbe_dev_detect_sfp, dev);
2943 : : }
2944 [ # # ]: 0 : } else if (hw->mac.type == txgbe_mac_sp || hw->mac.type == txgbe_mac_aml) {
2945 [ # # ]: 0 : if (reg & TXGBE_GPIOBIT_0)
2946 : : wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_0);
2947 [ # # ]: 0 : if (reg & TXGBE_GPIOBIT_2) {
2948 : : wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_2);
2949 : 0 : rte_eal_alarm_set(1000 * 100, txgbe_dev_detect_sfp, dev);
2950 : : }
2951 [ # # ]: 0 : if (reg & TXGBE_GPIOBIT_3) {
2952 : : wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_3);
2953 : 0 : intr->flags |= TXGBE_FLAG_NEED_LINK_UPDATE;
2954 : : }
2955 [ # # ]: 0 : if (reg & TXGBE_GPIOBIT_6) {
2956 : : wr32(hw, TXGBE_GPIOEOI, TXGBE_GPIOBIT_6);
2957 : 0 : intr->flags |= TXGBE_FLAG_NEED_LINK_UPDATE;
2958 : : }
2959 : : }
2960 : : wr32(hw, TXGBE_GPIOINTMASK, 0);
2961 : 0 : }
2962 : :
2963 : : static void
2964 : 0 : txgbe_dev_overheat(struct rte_eth_dev *dev)
2965 : : {
2966 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
2967 : : s32 temp_state;
2968 : :
2969 : 0 : temp_state = hw->phy.check_overtemp(hw);
2970 [ # # ]: 0 : if (!temp_state)
2971 : : return;
2972 : :
2973 [ # # ]: 0 : if (temp_state == TXGBE_ERR_UNDERTEMP) {
2974 : 0 : PMD_DRV_LOG(CRIT, "Network adapter has been started again, "
2975 : : "since the temperature has been back to normal state.");
2976 : : wr32m(hw, TXGBE_PBRXCTL, TXGBE_PBRXCTL_ENA, TXGBE_PBRXCTL_ENA);
2977 : 0 : txgbe_dev_set_link_up(dev);
2978 [ # # ]: 0 : } else if (temp_state == TXGBE_ERR_OVERTEMP) {
2979 : 0 : PMD_DRV_LOG(CRIT, "Network adapter has been stopped because it has over heated.");
2980 : : wr32m(hw, TXGBE_PBRXCTL, TXGBE_PBRXCTL_ENA, 0);
2981 : 0 : txgbe_dev_set_link_down(dev);
2982 : : }
2983 : : }
2984 : :
2985 : : void
2986 : 0 : txgbe_dev_setup_link_alarm_handler(void *param)
2987 : : {
2988 : : struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
2989 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
2990 : : struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
2991 : : u32 speed;
2992 : 0 : bool autoneg = false;
2993 : :
2994 : 0 : speed = hw->phy.autoneg_advertised;
2995 [ # # ]: 0 : if (!speed)
2996 : 0 : hw->mac.get_link_capabilities(hw, &speed, &autoneg);
2997 : :
2998 : 0 : hw->mac.setup_link(hw, speed, true);
2999 : :
3000 : 0 : intr->flags &= ~TXGBE_FLAG_NEED_LINK_CONFIG;
3001 : 0 : }
3002 : :
3003 : : static void
3004 : 0 : txgbe_do_reset(struct rte_eth_dev *dev)
3005 : : {
3006 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
3007 : : struct txgbe_tx_queue *txq;
3008 : : u32 i;
3009 : :
3010 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
3011 : 0 : txq = dev->data->tx_queues[i];
3012 : 0 : txq->resetting = true;
3013 : : }
3014 : :
3015 : : rte_delay_ms(1);
3016 : 0 : wr32(hw, TXGBE_RST, TXGBE_RST_LAN(hw->bus.lan_id));
3017 : : txgbe_flush(hw);
3018 : :
3019 : 0 : PMD_DRV_LOG(ERR, "Please manually restart the port %d",
3020 : : dev->data->port_id);
3021 : 0 : }
3022 : :
3023 : : static void
3024 : 0 : txgbe_tx_ring_recovery(struct rte_eth_dev *dev)
3025 : : {
3026 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
3027 : 0 : u32 desc_error[4] = {0, 0, 0, 0};
3028 : : struct txgbe_tx_queue *txq;
3029 : : u32 i;
3030 : :
3031 : : /* check tdm fatal error */
3032 [ # # ]: 0 : for (i = 0; i < 4; i++) {
3033 : 0 : desc_error[i] = rd32(hw, TXGBE_TDM_DESC_FATAL(i));
3034 [ # # ]: 0 : if (desc_error[i] != 0) {
3035 : 0 : PMD_DRV_LOG(ERR, "TDM fatal error reg[%d]: 0x%x", i, desc_error[i]);
3036 : 0 : txgbe_do_reset(dev);
3037 : 0 : return;
3038 : : }
3039 : : }
3040 : :
3041 : : /* check tdm non-fatal error */
3042 [ # # ]: 0 : for (i = 0; i < 4; i++)
3043 : 0 : desc_error[i] = rd32(hw, TXGBE_TDM_DESC_NONFATAL(i));
3044 : :
3045 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
3046 [ # # ]: 0 : if (desc_error[i / 32] & (1 << i % 32)) {
3047 : 0 : PMD_DRV_LOG(ERR, "TDM non-fatal error, reset port[%d] queue[%d]",
3048 : : dev->data->port_id, i);
3049 : 0 : dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
3050 : 0 : txq = dev->data->tx_queues[i];
3051 : 0 : txq->resetting = true;
3052 : 0 : rte_eal_alarm_set(1000, txgbe_tx_queue_clear_error, (void *)dev);
3053 : : }
3054 : : }
3055 : : }
3056 : :
3057 : : /*
3058 : : * If @timeout_ms was 0, it means that it will not return until link complete.
3059 : : * It returns 1 on complete, return 0 on timeout.
3060 : : */
3061 : : int
3062 : 0 : txgbe_dev_wait_setup_link_complete(struct rte_eth_dev *dev, uint32_t timeout_ms)
3063 : : {
3064 : : #define WARNING_TIMEOUT 9000 /* 9s in total */
3065 : 0 : struct txgbe_adapter *ad = TXGBE_DEV_ADAPTER(dev);
3066 [ # # ]: 0 : uint32_t timeout = timeout_ms ? timeout_ms : WARNING_TIMEOUT;
3067 : :
3068 [ # # ]: 0 : while (rte_atomic_load_explicit(&ad->link_thread_running, rte_memory_order_seq_cst)) {
3069 : : msec_delay(1);
3070 : 0 : timeout--;
3071 : :
3072 [ # # ]: 0 : if (timeout_ms) {
3073 [ # # ]: 0 : if (!timeout)
3074 : : return 0;
3075 [ # # ]: 0 : } else if (!timeout) {
3076 : : /* It will not return until link complete */
3077 : : timeout = WARNING_TIMEOUT;
3078 : 0 : PMD_DRV_LOG(ERR, "TXGBE link thread not complete too long time!");
3079 : : }
3080 : : }
3081 : :
3082 : : return 1;
3083 : : }
3084 : :
3085 : : static uint32_t
3086 : 0 : txgbe_dev_setup_link_thread_handler(void *param)
3087 : : {
3088 : : struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
3089 : 0 : struct txgbe_adapter *ad = TXGBE_DEV_ADAPTER(dev);
3090 : :
3091 : 0 : rte_thread_detach(rte_thread_self());
3092 : 0 : txgbe_dev_setup_link_alarm_handler(dev);
3093 : 0 : rte_atomic_store_explicit(&ad->link_thread_running, 0, rte_memory_order_seq_cst);
3094 : 0 : return 0;
3095 : : }
3096 : :
3097 : : /* return 0 means link status changed, -1 means not changed */
3098 : : int
3099 : 0 : txgbe_dev_link_update_share(struct rte_eth_dev *dev,
3100 : : int wait_to_complete)
3101 : : {
3102 : 0 : struct txgbe_adapter *ad = TXGBE_DEV_ADAPTER(dev);
3103 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
3104 : : struct rte_eth_link link;
3105 [ # # ]: 0 : u32 link_speed = TXGBE_LINK_SPEED_UNKNOWN;
3106 : : struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
3107 : : bool link_up;
3108 : : int err;
3109 : : int wait = 1;
3110 : : u32 reg;
3111 : :
3112 : : memset(&link, 0, sizeof(link));
3113 : : link.link_status = RTE_ETH_LINK_DOWN;
3114 : : link.link_speed = RTE_ETH_SPEED_NUM_NONE;
3115 : : link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
3116 : 0 : link.link_autoneg = !(dev->data->dev_conf.link_speeds &
3117 : : RTE_ETH_LINK_SPEED_FIXED);
3118 : :
3119 : 0 : hw->mac.get_link_status = true;
3120 : :
3121 [ # # ]: 0 : if (intr->flags & TXGBE_FLAG_NEED_LINK_CONFIG)
3122 : 0 : return rte_eth_linkstatus_set(dev, &link);
3123 : :
3124 : : /* check if it needs to wait to complete, if lsc interrupt is enabled */
3125 [ # # # # ]: 0 : if (wait_to_complete == 0 || dev->data->dev_conf.intr_conf.lsc != 0)
3126 : : wait = 0;
3127 : :
3128 : 0 : err = hw->mac.check_link(hw, &link_speed, &link_up, wait);
3129 : :
3130 [ # # ]: 0 : if (err != 0) {
3131 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_100M;
3132 [ # # ]: 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
3133 : 0 : return rte_eth_linkstatus_set(dev, &link);
3134 : : }
3135 : :
3136 [ # # ]: 0 : if (link_up == 0) {
3137 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml)
3138 : : wr32m(hw, TXGBE_GPIO_INT_POLARITY,
3139 : : TXGBE_GPIO_INT_POLARITY_3, 0x0);
3140 [ # # ]: 0 : if ((hw->subsystem_device_id & 0xFF) ==
3141 : : TXGBE_DEV_ID_KR_KX_KX4) {
3142 : 0 : hw->mac.bp_down_event(hw);
3143 [ # # ]: 0 : } else if (hw->phy.media_type == txgbe_media_type_fiber &&
3144 [ # # ]: 0 : dev->data->dev_conf.intr_conf.lsc != 0) {
3145 : 0 : txgbe_dev_wait_setup_link_complete(dev, 0);
3146 [ # # ]: 0 : if (!rte_atomic_exchange_explicit(&ad->link_thread_running, 1,
3147 : : rte_memory_order_seq_cst)) {
3148 : : /* To avoid race condition between threads, set
3149 : : * the TXGBE_FLAG_NEED_LINK_CONFIG flag only
3150 : : * when there is no link thread running.
3151 : : */
3152 : 0 : intr->flags |= TXGBE_FLAG_NEED_LINK_CONFIG;
3153 [ # # ]: 0 : if (rte_thread_create_internal_control(&ad->link_thread_tid,
3154 : : "txgbe-link",
3155 : : txgbe_dev_setup_link_thread_handler, dev) < 0) {
3156 : 0 : PMD_DRV_LOG(ERR, "Create link thread failed!");
3157 : 0 : rte_atomic_store_explicit(&ad->link_thread_running, 0,
3158 : : rte_memory_order_seq_cst);
3159 : : }
3160 : : } else {
3161 : 0 : PMD_DRV_LOG(ERR,
3162 : : "Other link thread is running now!");
3163 : : }
3164 : : }
3165 : 0 : return rte_eth_linkstatus_set(dev, &link);
3166 [ # # ]: 0 : } else if (!hw->dev_start) {
3167 : 0 : return rte_eth_linkstatus_set(dev, &link);
3168 : : }
3169 : :
3170 : 0 : intr->flags &= ~TXGBE_FLAG_NEED_LINK_CONFIG;
3171 : 0 : link.link_status = RTE_ETH_LINK_UP;
3172 : 0 : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
3173 : :
3174 [ # # # # : 0 : switch (link_speed) {
# # # # ]
3175 : 0 : default:
3176 : : case TXGBE_LINK_SPEED_UNKNOWN:
3177 : : link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
3178 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_100M;
3179 : 0 : break;
3180 : :
3181 : 0 : case TXGBE_LINK_SPEED_100M_FULL:
3182 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_100M;
3183 : 0 : break;
3184 : :
3185 : 0 : case TXGBE_LINK_SPEED_1GB_FULL:
3186 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_1G;
3187 : 0 : break;
3188 : :
3189 : 0 : case TXGBE_LINK_SPEED_2_5GB_FULL:
3190 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_2_5G;
3191 : 0 : break;
3192 : :
3193 : 0 : case TXGBE_LINK_SPEED_5GB_FULL:
3194 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_5G;
3195 : 0 : break;
3196 : :
3197 : 0 : case TXGBE_LINK_SPEED_10GB_FULL:
3198 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_10G;
3199 : 0 : break;
3200 : :
3201 : 0 : case TXGBE_LINK_SPEED_25GB_FULL:
3202 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_25G;
3203 : 0 : break;
3204 : :
3205 : 0 : case TXGBE_LINK_SPEED_40GB_FULL:
3206 : 0 : link.link_speed = RTE_ETH_SPEED_NUM_40G;
3207 : 0 : break;
3208 : : }
3209 : :
3210 : : /* enable mac receiver */
3211 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40) {
3212 : 0 : txgbe_reconfig_mac(hw);
3213 : : wr32m(hw, TXGBE_MACRXCFG, TXGBE_MACRXCFG_ENA, TXGBE_MACRXCFG_ENA);
3214 : : }
3215 : :
3216 : : /* Re configure MAC RX */
3217 [ # # ]: 0 : if (txgbe_is_pf(hw)) {
3218 : : reg = rd32(hw, TXGBE_MACRXCFG);
3219 : : wr32(hw, TXGBE_MACRXCFG, reg);
3220 : : wr32m(hw, TXGBE_MACRXFLT, TXGBE_MACRXFLT_PROMISC,
3221 : : TXGBE_MACRXFLT_PROMISC);
3222 : : reg = rd32(hw, TXGBE_MAC_WDG_TIMEOUT);
3223 : : wr32(hw, TXGBE_MAC_WDG_TIMEOUT, reg);
3224 : : }
3225 : :
3226 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40) {
3227 : : reg = rd32(hw, TXGBE_PORT);
3228 [ # # ]: 0 : if (reg & TXGBE_PORT_LINKUP) {
3229 [ # # ]: 0 : if (reg & TXGBE_CFG_PORT_ST_AML_LINK_40G) {
3230 : 0 : wr32(hw, TXGBE_MACTXCFG,
3231 : : (rd32(hw, TXGBE_MACTXCFG) &
3232 : 0 : ~TXGBE_MAC_TX_CFG_AML_SPEED_MASK) | TXGBE_MACTXCFG_TXE |
3233 : : TXGBE_MAC_TX_CFG_AML_SPEED_40G);
3234 [ # # ]: 0 : } else if (reg & TXGBE_CFG_PORT_ST_AML_LINK_25G) {
3235 : 0 : wr32(hw, TXGBE_MACTXCFG,
3236 : : (rd32(hw, TXGBE_MACTXCFG) &
3237 : 0 : ~TXGBE_MAC_TX_CFG_AML_SPEED_MASK) | TXGBE_MACTXCFG_TXE |
3238 : : TXGBE_MAC_TX_CFG_AML_SPEED_25G);
3239 [ # # ]: 0 : } else if (reg & TXGBE_CFG_PORT_ST_AML_LINK_10G) {
3240 : 0 : wr32(hw, TXGBE_MACTXCFG,
3241 : : (rd32(hw, TXGBE_MACTXCFG) &
3242 : 0 : ~TXGBE_MAC_TX_CFG_AML_SPEED_MASK) | TXGBE_MACTXCFG_TXE |
3243 : : TXGBE_MAC_TX_CFG_AML_SPEED_10G);
3244 : : }
3245 : : }
3246 : : }
3247 : :
3248 : : return rte_eth_linkstatus_set(dev, &link);
3249 : : }
3250 : :
3251 : : static int
3252 : 0 : txgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
3253 : : {
3254 : 0 : return txgbe_dev_link_update_share(dev, wait_to_complete);
3255 : : }
3256 : :
3257 : : static int
3258 : 0 : txgbe_dev_promiscuous_enable(struct rte_eth_dev *dev)
3259 : : {
3260 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
3261 : : uint32_t fctrl;
3262 : :
3263 : : fctrl = rd32(hw, TXGBE_PSRCTL);
3264 : 0 : fctrl |= (TXGBE_PSRCTL_UCP | TXGBE_PSRCTL_MCP);
3265 : : wr32(hw, TXGBE_PSRCTL, fctrl);
3266 : :
3267 : 0 : return 0;
3268 : : }
3269 : :
3270 : : static int
3271 : 0 : txgbe_dev_promiscuous_disable(struct rte_eth_dev *dev)
3272 : : {
3273 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
3274 : : uint32_t fctrl;
3275 : :
3276 : : fctrl = rd32(hw, TXGBE_PSRCTL);
3277 : 0 : fctrl &= (~TXGBE_PSRCTL_UCP);
3278 [ # # ]: 0 : if (dev->data->all_multicast == 1)
3279 : 0 : fctrl |= TXGBE_PSRCTL_MCP;
3280 : : else
3281 : 0 : fctrl &= (~TXGBE_PSRCTL_MCP);
3282 : : wr32(hw, TXGBE_PSRCTL, fctrl);
3283 : :
3284 : 0 : return 0;
3285 : : }
3286 : :
3287 : : static int
3288 : 0 : txgbe_dev_allmulticast_enable(struct rte_eth_dev *dev)
3289 : : {
3290 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
3291 : : uint32_t fctrl;
3292 : :
3293 : : fctrl = rd32(hw, TXGBE_PSRCTL);
3294 : 0 : fctrl |= TXGBE_PSRCTL_MCP;
3295 : : wr32(hw, TXGBE_PSRCTL, fctrl);
3296 : :
3297 : 0 : return 0;
3298 : : }
3299 : :
3300 : : static int
3301 : 0 : txgbe_dev_allmulticast_disable(struct rte_eth_dev *dev)
3302 : : {
3303 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
3304 : : uint32_t fctrl;
3305 : :
3306 [ # # ]: 0 : if (dev->data->promiscuous == 1)
3307 : : return 0; /* must remain in all_multicast mode */
3308 : :
3309 : : fctrl = rd32(hw, TXGBE_PSRCTL);
3310 : 0 : fctrl &= (~TXGBE_PSRCTL_MCP);
3311 : : wr32(hw, TXGBE_PSRCTL, fctrl);
3312 : :
3313 : 0 : return 0;
3314 : : }
3315 : :
3316 : : /**
3317 : : * It clears the interrupt causes and enables the interrupt.
3318 : : * It will be called once only during nic initialized.
3319 : : *
3320 : : * @param dev
3321 : : * Pointer to struct rte_eth_dev.
3322 : : * @param on
3323 : : * Enable or Disable.
3324 : : *
3325 : : * @return
3326 : : * - On success, zero.
3327 : : * - On failure, a negative value.
3328 : : */
3329 : : static int
3330 : : txgbe_dev_lsc_interrupt_setup(struct rte_eth_dev *dev, uint8_t on)
3331 : : {
3332 : : struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
3333 : :
3334 : 0 : txgbe_dev_link_status_print(dev);
3335 : : if (on)
3336 : 0 : intr->mask_misc |= TXGBE_ICRMISC_LSC;
3337 : : else
3338 : 0 : intr->mask_misc &= ~TXGBE_ICRMISC_LSC;
3339 : :
3340 : : return 0;
3341 : : }
3342 : :
3343 : : static int
3344 : : txgbe_dev_misc_interrupt_setup(struct rte_eth_dev *dev)
3345 : : {
3346 : 0 : struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
3347 : : u64 mask;
3348 : :
3349 : : mask = TXGBE_ICR_MASK;
3350 : : mask &= (1ULL << TXGBE_MISC_VEC_ID);
3351 : 0 : intr->mask |= mask;
3352 : 0 : intr->mask_misc |= TXGBE_ICRMISC_GPIO;
3353 : : intr->mask_misc |= TXGBE_ICRMISC_ANDONE;
3354 [ # # ]: 0 : intr->mask_misc |= TXGBE_ICRMISC_TXDESC;
3355 : : return 0;
3356 : : }
3357 : :
3358 : : /**
3359 : : * It clears the interrupt causes and enables the interrupt.
3360 : : * It will be called once only during nic initialized.
3361 : : *
3362 : : * @param dev
3363 : : * Pointer to struct rte_eth_dev.
3364 : : *
3365 : : * @return
3366 : : * - On success, zero.
3367 : : * - On failure, a negative value.
3368 : : */
3369 : : static int
3370 : : txgbe_dev_rxq_interrupt_setup(struct rte_eth_dev *dev)
3371 : : {
3372 : 0 : struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
3373 : : u64 mask;
3374 : :
3375 : : mask = TXGBE_ICR_MASK;
3376 : : mask &= ~((1ULL << TXGBE_RX_VEC_START) - 1);
3377 : 0 : intr->mask |= mask;
3378 : :
3379 : 0 : return 0;
3380 : : }
3381 : :
3382 : : /**
3383 : : * It clears the interrupt causes and enables the interrupt.
3384 : : * It will be called once only during nic initialized.
3385 : : *
3386 : : * @param dev
3387 : : * Pointer to struct rte_eth_dev.
3388 : : *
3389 : : * @return
3390 : : * - On success, zero.
3391 : : * - On failure, a negative value.
3392 : : */
3393 : : static int
3394 : : txgbe_dev_macsec_interrupt_setup(struct rte_eth_dev *dev)
3395 : : {
3396 : 0 : struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
3397 : :
3398 : 0 : intr->mask_misc |= TXGBE_ICRMISC_LNKSEC;
3399 : :
3400 : : return 0;
3401 : : }
3402 : :
3403 : : /*
3404 : : * It reads ICR and sets flag (TXGBE_ICRMISC_LSC) for the link_update.
3405 : : *
3406 : : * @param dev
3407 : : * Pointer to struct rte_eth_dev.
3408 : : *
3409 : : * @return
3410 : : * - On success, zero.
3411 : : * - On failure, a negative value.
3412 : : */
3413 : : static int
3414 : 0 : txgbe_dev_interrupt_get_status(struct rte_eth_dev *dev,
3415 : : struct rte_intr_handle *intr_handle)
3416 : : {
3417 : : uint32_t eicr;
3418 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
3419 : : struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
3420 : :
3421 [ # # # # ]: 0 : if (rte_intr_type_get(intr_handle) != RTE_INTR_HANDLE_UIO &&
3422 : 0 : rte_intr_type_get(intr_handle) != RTE_INTR_HANDLE_VFIO_MSIX)
3423 : : wr32(hw, TXGBE_PX_INTA, 1);
3424 : :
3425 : : /* read-on-clear nic registers here */
3426 : 0 : eicr = ((u32 *)hw->isb_mem)[TXGBE_ISB_MISC];
3427 : 0 : PMD_DRV_LOG(DEBUG, "eicr %x", eicr);
3428 : :
3429 : 0 : intr->flags = 0;
3430 : :
3431 : : /* set flag for async link update */
3432 [ # # ]: 0 : if (eicr & TXGBE_ICRMISC_LSC)
3433 : 0 : intr->flags |= TXGBE_FLAG_NEED_LINK_UPDATE;
3434 : :
3435 [ # # ]: 0 : if (eicr & TXGBE_ICRMISC_ANDONE)
3436 : 0 : intr->flags |= TXGBE_FLAG_NEED_AN_CONFIG;
3437 : :
3438 [ # # ]: 0 : if (eicr & TXGBE_ICRMISC_VFMBX)
3439 : 0 : intr->flags |= TXGBE_FLAG_MAILBOX;
3440 : :
3441 [ # # ]: 0 : if (eicr & TXGBE_ICRMISC_LNKSEC)
3442 : 0 : intr->flags |= TXGBE_FLAG_MACSEC;
3443 : :
3444 [ # # ]: 0 : if (eicr & TXGBE_ICRMISC_GPIO)
3445 : 0 : intr->flags |= TXGBE_FLAG_PHY_INTERRUPT;
3446 : :
3447 [ # # ]: 0 : if (eicr & TXGBE_ICRMISC_HEAT)
3448 : 0 : intr->flags |= TXGBE_FLAG_OVERHEAT;
3449 : :
3450 [ # # ]: 0 : if (eicr & TXGBE_ICRMISC_TXDESC)
3451 : 0 : intr->flags |= TXGBE_FLAG_TX_DESC_ERR;
3452 : :
3453 : 0 : ((u32 *)hw->isb_mem)[TXGBE_ISB_MISC] = 0;
3454 : :
3455 : 0 : return 0;
3456 : : }
3457 : :
3458 : : /**
3459 : : * It gets and then prints the link status.
3460 : : *
3461 : : * @param dev
3462 : : * Pointer to struct rte_eth_dev.
3463 : : *
3464 : : * @return
3465 : : * - On success, zero.
3466 : : * - On failure, a negative value.
3467 : : */
3468 : : static void
3469 : 0 : txgbe_dev_link_status_print(struct rte_eth_dev *dev)
3470 : : {
3471 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
3472 : : struct rte_eth_link link;
3473 : :
3474 : 0 : rte_eth_linkstatus_get(dev, &link);
3475 : :
3476 [ # # ]: 0 : if (link.link_status) {
3477 [ # # ]: 0 : PMD_INIT_LOG(INFO, "Port %d: Link Up - speed %u Mbps - %s",
3478 : : (int)(dev->data->port_id),
3479 : : (unsigned int)link.link_speed,
3480 : : link.link_duplex == RTE_ETH_LINK_FULL_DUPLEX ?
3481 : : "full-duplex" : "half-duplex");
3482 : : } else {
3483 : 0 : PMD_INIT_LOG(INFO, " Port %d: Link Down",
3484 : : (int)(dev->data->port_id));
3485 : : }
3486 : 0 : PMD_INIT_LOG(DEBUG, "PCI Address: " PCI_PRI_FMT,
3487 : : pci_dev->addr.domain,
3488 : : pci_dev->addr.bus,
3489 : : pci_dev->addr.devid,
3490 : : pci_dev->addr.function);
3491 : 0 : }
3492 : :
3493 : : /*
3494 : : * It executes link_update after knowing an interrupt occurred.
3495 : : *
3496 : : * @param dev
3497 : : * Pointer to struct rte_eth_dev.
3498 : : *
3499 : : * @return
3500 : : * - On success, zero.
3501 : : * - On failure, a negative value.
3502 : : */
3503 : : static int
3504 : 0 : txgbe_dev_interrupt_action(struct rte_eth_dev *dev,
3505 : : struct rte_intr_handle *intr_handle)
3506 : : {
3507 : 0 : struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
3508 : : int64_t timeout;
3509 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
3510 : :
3511 : 0 : PMD_DRV_LOG(DEBUG, "intr action type %d", intr->flags);
3512 : :
3513 [ # # ]: 0 : if (intr->flags & TXGBE_FLAG_MAILBOX) {
3514 : 0 : txgbe_pf_mbx_process(dev);
3515 : 0 : intr->flags &= ~TXGBE_FLAG_MAILBOX;
3516 : : }
3517 : :
3518 [ # # ]: 0 : if (intr->flags & TXGBE_FLAG_PHY_INTERRUPT) {
3519 : 0 : txgbe_dev_sfp_event(dev);
3520 : 0 : intr->flags &= ~TXGBE_FLAG_PHY_INTERRUPT;
3521 : : }
3522 : :
3523 [ # # ]: 0 : if (intr->flags & TXGBE_FLAG_NEED_AN_CONFIG) {
3524 [ # # # # ]: 0 : if (hw->devarg.auto_neg == 1 && hw->devarg.poll == 0) {
3525 : 0 : hw->mac.kr_handle(hw);
3526 : 0 : intr->flags &= ~TXGBE_FLAG_NEED_AN_CONFIG;
3527 : : }
3528 : : }
3529 : :
3530 [ # # ]: 0 : if (intr->flags & TXGBE_FLAG_NEED_LINK_UPDATE) {
3531 : : struct rte_eth_link link;
3532 : :
3533 : : /*get the link status before link update, for predicting later*/
3534 : 0 : rte_eth_linkstatus_get(dev, &link);
3535 : :
3536 : : txgbe_dev_link_update(dev, 0);
3537 : :
3538 : : /* likely to up */
3539 [ # # ]: 0 : if (!link.link_status)
3540 : : /* handle it 1 sec later, wait it being stable */
3541 : : timeout = TXGBE_LINK_UP_CHECK_TIMEOUT;
3542 : : /* likely to down */
3543 [ # # ]: 0 : else if ((hw->subsystem_device_id & 0xFF) ==
3544 : 0 : TXGBE_DEV_ID_KR_KX_KX4 &&
3545 [ # # ]: 0 : hw->devarg.auto_neg == 1)
3546 : : /* handle it 2 sec later for backplane AN73 */
3547 : : timeout = 2000;
3548 : : else
3549 : : /* handle it 4 sec later, wait it being stable */
3550 : : timeout = TXGBE_LINK_DOWN_CHECK_TIMEOUT;
3551 : :
3552 : 0 : txgbe_dev_link_status_print(dev);
3553 [ # # ]: 0 : if (rte_eal_alarm_set(timeout * 1000,
3554 : : txgbe_dev_interrupt_delayed_handler,
3555 : : (void *)dev) < 0) {
3556 : 0 : PMD_DRV_LOG(ERR, "Error setting alarm");
3557 : : } else {
3558 : : /* only disable lsc interrupt */
3559 : 0 : intr->mask_misc &= ~TXGBE_ICRMISC_LSC;
3560 : :
3561 : 0 : intr->mask_orig = intr->mask;
3562 : : /* only disable all misc interrupts */
3563 : 0 : intr->mask &= ~(1ULL << TXGBE_MISC_VEC_ID);
3564 : : }
3565 : : }
3566 : :
3567 [ # # ]: 0 : if (intr->flags & TXGBE_FLAG_OVERHEAT) {
3568 : 0 : txgbe_dev_overheat(dev);
3569 : 0 : intr->flags &= ~TXGBE_FLAG_OVERHEAT;
3570 : : }
3571 : :
3572 [ # # ]: 0 : if (intr->flags & TXGBE_FLAG_TX_DESC_ERR) {
3573 : 0 : txgbe_tx_ring_recovery(dev);
3574 : 0 : intr->flags &= ~TXGBE_FLAG_TX_DESC_ERR;
3575 : : }
3576 : :
3577 : 0 : PMD_DRV_LOG(DEBUG, "enable intr immediately");
3578 : 0 : txgbe_enable_intr(dev);
3579 : 0 : rte_intr_enable(intr_handle);
3580 : :
3581 : 0 : return 0;
3582 : : }
3583 : :
3584 : : /**
3585 : : * Interrupt handler which shall be registered for alarm callback for delayed
3586 : : * handling specific interrupt to wait for the stable nic state. As the
3587 : : * NIC interrupt state is not stable for txgbe after link is just down,
3588 : : * it needs to wait 4 seconds to get the stable status.
3589 : : *
3590 : : * @param handle
3591 : : * Pointer to interrupt handle.
3592 : : * @param param
3593 : : * The address of parameter (struct rte_eth_dev *) registered before.
3594 : : *
3595 : : * @return
3596 : : * void
3597 : : */
3598 : : static void
3599 : 0 : txgbe_dev_interrupt_delayed_handler(void *param)
3600 : : {
3601 : : struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
3602 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
3603 : 0 : struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
3604 : 0 : struct txgbe_interrupt *intr = TXGBE_DEV_INTR(dev);
3605 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
3606 : : uint32_t eicr;
3607 : :
3608 : 0 : txgbe_disable_intr(hw);
3609 : :
3610 : 0 : eicr = ((u32 *)hw->isb_mem)[TXGBE_ISB_MISC];
3611 [ # # ]: 0 : if (eicr & TXGBE_ICRMISC_VFMBX)
3612 : 0 : txgbe_pf_mbx_process(dev);
3613 : :
3614 [ # # ]: 0 : if (intr->flags & TXGBE_FLAG_PHY_INTERRUPT) {
3615 : 0 : hw->phy.handle_lasi(hw);
3616 : 0 : intr->flags &= ~TXGBE_FLAG_PHY_INTERRUPT;
3617 : : }
3618 : :
3619 [ # # ]: 0 : if (intr->flags & TXGBE_FLAG_NEED_LINK_UPDATE) {
3620 : : txgbe_dev_link_update(dev, 0);
3621 : 0 : intr->flags &= ~TXGBE_FLAG_NEED_LINK_UPDATE;
3622 : 0 : txgbe_dev_link_status_print(dev);
3623 : 0 : rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
3624 : : NULL);
3625 : : }
3626 : :
3627 [ # # ]: 0 : if (intr->flags & TXGBE_FLAG_MACSEC) {
3628 : 0 : rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_MACSEC,
3629 : : NULL);
3630 : 0 : intr->flags &= ~TXGBE_FLAG_MACSEC;
3631 : : }
3632 : :
3633 : : /* restore original mask */
3634 [ # # ]: 0 : if (dev->data->dev_conf.intr_conf.lsc == 1)
3635 : 0 : intr->mask_misc |= TXGBE_ICRMISC_LSC;
3636 : :
3637 : 0 : intr->mask = intr->mask_orig;
3638 : 0 : intr->mask_orig = 0;
3639 : :
3640 : 0 : PMD_DRV_LOG(DEBUG, "enable intr in delayed handler S[%08x]", eicr);
3641 : 0 : txgbe_enable_intr(dev);
3642 : 0 : rte_intr_enable(intr_handle);
3643 : 0 : }
3644 : :
3645 : : /**
3646 : : * Interrupt handler triggered by NIC for handling
3647 : : * specific interrupt.
3648 : : *
3649 : : * @param handle
3650 : : * Pointer to interrupt handle.
3651 : : * @param param
3652 : : * The address of parameter (struct rte_eth_dev *) registered before.
3653 : : *
3654 : : * @return
3655 : : * void
3656 : : */
3657 : : static void
3658 : 0 : txgbe_dev_interrupt_handler(void *param)
3659 : : {
3660 : : struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
3661 : :
3662 : 0 : txgbe_dev_interrupt_get_status(dev, dev->intr_handle);
3663 : 0 : txgbe_dev_interrupt_action(dev, dev->intr_handle);
3664 : 0 : }
3665 : :
3666 : : static int
3667 : 0 : txgbe_dev_led_on(struct rte_eth_dev *dev)
3668 : : {
3669 : : struct txgbe_hw *hw;
3670 : :
3671 : 0 : hw = TXGBE_DEV_HW(dev);
3672 [ # # ]: 0 : return txgbe_led_on(hw, TXGBE_LEDCTL_ACTIVE) == 0 ? 0 : -ENOTSUP;
3673 : : }
3674 : :
3675 : : static int
3676 : 0 : txgbe_dev_led_off(struct rte_eth_dev *dev)
3677 : : {
3678 : : struct txgbe_hw *hw;
3679 : :
3680 : 0 : hw = TXGBE_DEV_HW(dev);
3681 [ # # ]: 0 : return txgbe_led_off(hw, TXGBE_LEDCTL_ACTIVE) == 0 ? 0 : -ENOTSUP;
3682 : : }
3683 : :
3684 : : static int
3685 : 0 : txgbe_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
3686 : : {
3687 : : struct txgbe_hw *hw;
3688 : : uint32_t mflcn_reg;
3689 : : uint32_t fccfg_reg;
3690 : : int rx_pause;
3691 : : int tx_pause;
3692 : :
3693 : 0 : hw = TXGBE_DEV_HW(dev);
3694 : :
3695 : 0 : fc_conf->pause_time = hw->fc.pause_time;
3696 : 0 : fc_conf->high_water = hw->fc.high_water[0];
3697 : 0 : fc_conf->low_water = hw->fc.low_water[0];
3698 : 0 : fc_conf->send_xon = hw->fc.send_xon;
3699 : 0 : fc_conf->autoneg = !hw->fc.disable_fc_autoneg;
3700 : :
3701 : : /*
3702 : : * Return rx_pause status according to actual setting of
3703 : : * RXFCCFG register.
3704 : : */
3705 : : mflcn_reg = rd32(hw, TXGBE_RXFCCFG);
3706 [ # # ]: 0 : if (mflcn_reg & (TXGBE_RXFCCFG_FC | TXGBE_RXFCCFG_PFC))
3707 : : rx_pause = 1;
3708 : : else
3709 : : rx_pause = 0;
3710 : :
3711 : : /*
3712 : : * Return tx_pause status according to actual setting of
3713 : : * TXFCCFG register.
3714 : : */
3715 : : fccfg_reg = rd32(hw, TXGBE_TXFCCFG);
3716 [ # # ]: 0 : if (fccfg_reg & (TXGBE_TXFCCFG_FC | TXGBE_TXFCCFG_PFC))
3717 : : tx_pause = 1;
3718 : : else
3719 : : tx_pause = 0;
3720 : :
3721 [ # # ]: 0 : if (rx_pause && tx_pause)
3722 : 0 : fc_conf->mode = RTE_ETH_FC_FULL;
3723 [ # # ]: 0 : else if (rx_pause)
3724 : 0 : fc_conf->mode = RTE_ETH_FC_RX_PAUSE;
3725 [ # # ]: 0 : else if (tx_pause)
3726 : 0 : fc_conf->mode = RTE_ETH_FC_TX_PAUSE;
3727 : : else
3728 : 0 : fc_conf->mode = RTE_ETH_FC_NONE;
3729 : :
3730 : 0 : return 0;
3731 : : }
3732 : :
3733 : : static int
3734 : 0 : txgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
3735 : : {
3736 : : struct txgbe_hw *hw;
3737 : : int err;
3738 : : uint32_t rx_buf_size;
3739 : : uint32_t max_high_water;
3740 : 0 : enum txgbe_fc_mode rte_fcmode_2_txgbe_fcmode[] = {
3741 : : txgbe_fc_none,
3742 : : txgbe_fc_rx_pause,
3743 : : txgbe_fc_tx_pause,
3744 : : txgbe_fc_full
3745 : : };
3746 : :
3747 : 0 : PMD_INIT_FUNC_TRACE();
3748 : :
3749 : 0 : hw = TXGBE_DEV_HW(dev);
3750 : : rx_buf_size = rd32(hw, TXGBE_PBRXSIZE(0));
3751 : 0 : PMD_INIT_LOG(DEBUG, "Rx packet buffer size = 0x%x", rx_buf_size);
3752 : :
3753 : : /*
3754 : : * At least reserve one Ethernet frame for watermark
3755 : : * high_water/low_water in kilo bytes for txgbe
3756 : : */
3757 : 0 : max_high_water = (rx_buf_size - RTE_ETHER_MAX_LEN) >> 10;
3758 [ # # ]: 0 : if (fc_conf->high_water > max_high_water ||
3759 [ # # ]: 0 : fc_conf->high_water < fc_conf->low_water) {
3760 : 0 : PMD_INIT_LOG(ERR, "Invalid high/low water setup value in KB");
3761 : 0 : PMD_INIT_LOG(ERR, "High_water must <= 0x%x", max_high_water);
3762 : 0 : return -EINVAL;
3763 : : }
3764 : :
3765 : 0 : hw->fc.requested_mode = rte_fcmode_2_txgbe_fcmode[fc_conf->mode];
3766 : 0 : hw->fc.pause_time = fc_conf->pause_time;
3767 : 0 : hw->fc.high_water[0] = fc_conf->high_water;
3768 : 0 : hw->fc.low_water[0] = fc_conf->low_water;
3769 : 0 : hw->fc.send_xon = fc_conf->send_xon;
3770 : 0 : hw->fc.disable_fc_autoneg = !fc_conf->autoneg;
3771 : 0 : hw->fc.mac_ctrl_frame_fwd = fc_conf->mac_ctrl_frame_fwd;
3772 : :
3773 : 0 : err = txgbe_fc_enable(hw);
3774 : :
3775 : : /* Not negotiated is not an error case */
3776 [ # # ]: 0 : if (err == 0 || err == TXGBE_ERR_FC_NOT_NEGOTIATED) {
3777 : 0 : wr32m(hw, TXGBE_MACRXFLT, TXGBE_MACRXFLT_CTL_MASK,
3778 [ # # ]: 0 : (fc_conf->mac_ctrl_frame_fwd
3779 : : ? TXGBE_MACRXFLT_CTL_NOPS : TXGBE_MACRXFLT_CTL_DROP));
3780 : : txgbe_flush(hw);
3781 : :
3782 : 0 : return 0;
3783 : : }
3784 : :
3785 : 0 : PMD_INIT_LOG(ERR, "txgbe_fc_enable = 0x%x", err);
3786 : 0 : return -EIO;
3787 : : }
3788 : :
3789 : : static int
3790 : 0 : txgbe_priority_flow_ctrl_set(struct rte_eth_dev *dev,
3791 : : struct rte_eth_pfc_conf *pfc_conf)
3792 : : {
3793 : : int err;
3794 : : uint32_t rx_buf_size;
3795 : : uint32_t max_high_water;
3796 : : uint8_t tc_num;
3797 : 0 : uint8_t map[TXGBE_DCB_UP_MAX] = { 0 };
3798 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
3799 : 0 : struct txgbe_dcb_config *dcb_config = TXGBE_DEV_DCB_CONFIG(dev);
3800 : :
3801 : 0 : enum txgbe_fc_mode rte_fcmode_2_txgbe_fcmode[] = {
3802 : : txgbe_fc_none,
3803 : : txgbe_fc_rx_pause,
3804 : : txgbe_fc_tx_pause,
3805 : : txgbe_fc_full
3806 : : };
3807 : :
3808 : 0 : PMD_INIT_FUNC_TRACE();
3809 : :
3810 : 0 : txgbe_dcb_unpack_map_cee(dcb_config, TXGBE_DCB_RX_CONFIG, map);
3811 : 0 : tc_num = map[pfc_conf->priority];
3812 : 0 : rx_buf_size = rd32(hw, TXGBE_PBRXSIZE(tc_num));
3813 : 0 : PMD_INIT_LOG(DEBUG, "Rx packet buffer size = 0x%x", rx_buf_size);
3814 : : /*
3815 : : * At least reserve one Ethernet frame for watermark
3816 : : * high_water/low_water in kilo bytes for txgbe
3817 : : */
3818 : 0 : max_high_water = (rx_buf_size - RTE_ETHER_MAX_LEN) >> 10;
3819 [ # # ]: 0 : if (pfc_conf->fc.high_water > max_high_water ||
3820 [ # # ]: 0 : pfc_conf->fc.high_water <= pfc_conf->fc.low_water) {
3821 : 0 : PMD_INIT_LOG(ERR, "Invalid high/low water setup value in KB");
3822 : 0 : PMD_INIT_LOG(ERR, "High_water must <= 0x%x", max_high_water);
3823 : 0 : return -EINVAL;
3824 : : }
3825 : :
3826 : 0 : hw->fc.requested_mode = rte_fcmode_2_txgbe_fcmode[pfc_conf->fc.mode];
3827 : 0 : hw->fc.pause_time = pfc_conf->fc.pause_time;
3828 : 0 : hw->fc.send_xon = pfc_conf->fc.send_xon;
3829 : 0 : hw->fc.low_water[tc_num] = pfc_conf->fc.low_water;
3830 : 0 : hw->fc.high_water[tc_num] = pfc_conf->fc.high_water;
3831 : :
3832 : 0 : err = txgbe_dcb_pfc_enable(hw, tc_num);
3833 : :
3834 : : /* Not negotiated is not an error case */
3835 [ # # ]: 0 : if (err == 0 || err == TXGBE_ERR_FC_NOT_NEGOTIATED)
3836 : : return 0;
3837 : :
3838 : 0 : PMD_INIT_LOG(ERR, "txgbe_dcb_pfc_enable = 0x%x", err);
3839 : 0 : return -EIO;
3840 : : }
3841 : :
3842 : : int
3843 : 0 : txgbe_dev_rss_reta_update(struct rte_eth_dev *dev,
3844 : : struct rte_eth_rss_reta_entry64 *reta_conf,
3845 : : uint16_t reta_size)
3846 : : {
3847 : : uint8_t i, j, mask;
3848 : : uint32_t reta;
3849 : : uint16_t idx, shift;
3850 : 0 : struct txgbe_adapter *adapter = TXGBE_DEV_ADAPTER(dev);
3851 : : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
3852 : :
3853 : 0 : PMD_INIT_FUNC_TRACE();
3854 : :
3855 [ # # ]: 0 : if (!txgbe_rss_update(hw->mac.type)) {
3856 : 0 : PMD_DRV_LOG(ERR, "RSS reta update is not supported on this "
3857 : : "NIC.");
3858 : 0 : return -ENOTSUP;
3859 : : }
3860 : :
3861 [ # # ]: 0 : if (reta_size != RTE_ETH_RSS_RETA_SIZE_128) {
3862 : 0 : PMD_DRV_LOG(ERR, "The size of hash lookup table configured "
3863 : : "(%d) doesn't match the number hardware can supported "
3864 : : "(%d)", reta_size, RTE_ETH_RSS_RETA_SIZE_128);
3865 : 0 : return -EINVAL;
3866 : : }
3867 : :
3868 [ # # ]: 0 : for (i = 0; i < reta_size; i += 4) {
3869 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
3870 : : shift = i % RTE_ETH_RETA_GROUP_SIZE;
3871 : 0 : mask = (uint8_t)RS64(reta_conf[idx].mask, shift, 0xF);
3872 [ # # ]: 0 : if (!mask)
3873 : 0 : continue;
3874 : :
3875 : 0 : reta = rd32at(hw, TXGBE_REG_RSSTBL, i >> 2);
3876 [ # # ]: 0 : for (j = 0; j < 4; j++) {
3877 [ # # ]: 0 : if (RS8(mask, j, 0x1)) {
3878 : 0 : reta &= ~(MS32(8 * j, 0xFF));
3879 : 0 : reta |= LS32(reta_conf[idx].reta[shift + j],
3880 : : 8 * j, 0xFF);
3881 : : }
3882 : : }
3883 : 0 : wr32at(hw, TXGBE_REG_RSSTBL, i >> 2, reta);
3884 : : }
3885 : 0 : adapter->rss_reta_updated = 1;
3886 : :
3887 : 0 : return 0;
3888 : : }
3889 : :
3890 : : int
3891 : 0 : txgbe_dev_rss_reta_query(struct rte_eth_dev *dev,
3892 : : struct rte_eth_rss_reta_entry64 *reta_conf,
3893 : : uint16_t reta_size)
3894 : : {
3895 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
3896 : : uint8_t i, j, mask;
3897 : : uint32_t reta;
3898 : : uint16_t idx, shift;
3899 : :
3900 : 0 : PMD_INIT_FUNC_TRACE();
3901 : :
3902 [ # # ]: 0 : if (reta_size != RTE_ETH_RSS_RETA_SIZE_128) {
3903 : 0 : PMD_DRV_LOG(ERR, "The size of hash lookup table configured "
3904 : : "(%d) doesn't match the number hardware can supported "
3905 : : "(%d)", reta_size, RTE_ETH_RSS_RETA_SIZE_128);
3906 : 0 : return -EINVAL;
3907 : : }
3908 : :
3909 [ # # ]: 0 : for (i = 0; i < reta_size; i += 4) {
3910 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
3911 : : shift = i % RTE_ETH_RETA_GROUP_SIZE;
3912 : 0 : mask = (uint8_t)RS64(reta_conf[idx].mask, shift, 0xF);
3913 [ # # ]: 0 : if (!mask)
3914 : 0 : continue;
3915 : :
3916 : 0 : reta = rd32at(hw, TXGBE_REG_RSSTBL, i >> 2);
3917 [ # # ]: 0 : for (j = 0; j < 4; j++) {
3918 [ # # ]: 0 : if (RS8(mask, j, 0x1))
3919 : 0 : reta_conf[idx].reta[shift + j] =
3920 : 0 : (uint16_t)RS32(reta, 8 * j, 0xFF);
3921 : : }
3922 : : }
3923 : :
3924 : : return 0;
3925 : : }
3926 : :
3927 : : static int
3928 : 0 : txgbe_add_rar(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
3929 : : uint32_t index, uint32_t pool)
3930 : : {
3931 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
3932 : : uint32_t enable_addr = 1;
3933 : :
3934 : 0 : return txgbe_set_rar(hw, index, mac_addr->addr_bytes,
3935 : : pool, enable_addr);
3936 : : }
3937 : :
3938 : : static void
3939 : 0 : txgbe_remove_rar(struct rte_eth_dev *dev, uint32_t index)
3940 : : {
3941 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
3942 : :
3943 : 0 : txgbe_clear_rar(hw, index);
3944 : 0 : }
3945 : :
3946 : : static int
3947 : 0 : txgbe_set_default_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *addr)
3948 : : {
3949 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
3950 : :
3951 : : txgbe_remove_rar(dev, 0);
3952 : 0 : txgbe_add_rar(dev, addr, 0, pci_dev->max_vfs);
3953 : :
3954 : 0 : return 0;
3955 : : }
3956 : :
3957 : : static int
3958 : 0 : txgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
3959 : : {
3960 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
3961 : : uint32_t frame_size = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN;
3962 : : struct rte_eth_dev_data *dev_data = dev->data;
3963 : :
3964 : : /* If device is started, refuse mtu that requires the support of
3965 : : * scattered packets when this feature has not been enabled before.
3966 : : */
3967 [ # # ]: 0 : if (dev_data->dev_started && !dev_data->scattered_rx &&
3968 : 0 : (frame_size + 2 * RTE_VLAN_HLEN >
3969 [ # # ]: 0 : dev->data->min_rx_buf_size - RTE_PKTMBUF_HEADROOM)) {
3970 : 0 : PMD_INIT_LOG(ERR, "Stop port first.");
3971 : 0 : return -EINVAL;
3972 : : }
3973 : :
3974 : 0 : wr32m(hw, TXGBE_FRMSZ, TXGBE_FRMSZ_MAX_MASK,
3975 : 0 : TXGBE_FRMSZ_MAX(frame_size));
3976 : :
3977 : 0 : return 0;
3978 : : }
3979 : :
3980 : : static uint32_t
3981 : 0 : txgbe_uta_vector(struct txgbe_hw *hw, struct rte_ether_addr *uc_addr)
3982 : : {
3983 : : uint32_t vector = 0;
3984 : :
3985 [ # # # # : 0 : switch (hw->mac.mc_filter_type) {
# ]
3986 : 0 : case 0: /* use bits [47:36] of the address */
3987 : 0 : vector = ((uc_addr->addr_bytes[4] >> 4) |
3988 : 0 : (((uint16_t)uc_addr->addr_bytes[5]) << 4));
3989 : 0 : break;
3990 : 0 : case 1: /* use bits [46:35] of the address */
3991 : 0 : vector = ((uc_addr->addr_bytes[4] >> 3) |
3992 : 0 : (((uint16_t)uc_addr->addr_bytes[5]) << 5));
3993 : 0 : break;
3994 : 0 : case 2: /* use bits [45:34] of the address */
3995 : 0 : vector = ((uc_addr->addr_bytes[4] >> 2) |
3996 : 0 : (((uint16_t)uc_addr->addr_bytes[5]) << 6));
3997 : 0 : break;
3998 : 0 : case 3: /* use bits [43:32] of the address */
3999 : 0 : vector = ((uc_addr->addr_bytes[4]) |
4000 : 0 : (((uint16_t)uc_addr->addr_bytes[5]) << 8));
4001 : 0 : break;
4002 : : default: /* Invalid mc_filter_type */
4003 : : break;
4004 : : }
4005 : :
4006 : : /* vector can only be 12-bits or boundary will be exceeded */
4007 : 0 : vector &= 0xFFF;
4008 : 0 : return vector;
4009 : : }
4010 : :
4011 : : static int
4012 : 0 : txgbe_uc_hash_table_set(struct rte_eth_dev *dev,
4013 : : struct rte_ether_addr *mac_addr, uint8_t on)
4014 : : {
4015 : : uint32_t vector;
4016 : : uint32_t uta_idx;
4017 : : uint32_t reg_val;
4018 : : uint32_t uta_mask;
4019 : : uint32_t psrctl;
4020 : :
4021 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4022 : : struct txgbe_uta_info *uta_info = TXGBE_DEV_UTA_INFO(dev);
4023 : :
4024 : : /* The UTA table only exists on pf hardware */
4025 [ # # ]: 0 : if (hw->mac.type < txgbe_mac_sp)
4026 : : return -ENOTSUP;
4027 : :
4028 : 0 : vector = txgbe_uta_vector(hw, mac_addr);
4029 : 0 : uta_idx = (vector >> 5) & 0x7F;
4030 : 0 : uta_mask = 0x1UL << (vector & 0x1F);
4031 : :
4032 [ # # ]: 0 : if (!!on == !!(uta_info->uta_shadow[uta_idx] & uta_mask))
4033 : : return 0;
4034 : :
4035 : 0 : reg_val = rd32(hw, TXGBE_UCADDRTBL(uta_idx));
4036 [ # # ]: 0 : if (on) {
4037 : 0 : uta_info->uta_in_use++;
4038 : 0 : reg_val |= uta_mask;
4039 : 0 : uta_info->uta_shadow[uta_idx] |= uta_mask;
4040 : : } else {
4041 : 0 : uta_info->uta_in_use--;
4042 : 0 : reg_val &= ~uta_mask;
4043 : 0 : uta_info->uta_shadow[uta_idx] &= ~uta_mask;
4044 : : }
4045 : :
4046 : : wr32(hw, TXGBE_UCADDRTBL(uta_idx), reg_val);
4047 : :
4048 : : psrctl = rd32(hw, TXGBE_PSRCTL);
4049 [ # # ]: 0 : if (uta_info->uta_in_use > 0)
4050 : 0 : psrctl |= TXGBE_PSRCTL_UCHFENA;
4051 : : else
4052 : 0 : psrctl &= ~TXGBE_PSRCTL_UCHFENA;
4053 : :
4054 : 0 : psrctl &= ~TXGBE_PSRCTL_ADHF12_MASK;
4055 : 0 : psrctl |= TXGBE_PSRCTL_ADHF12(hw->mac.mc_filter_type);
4056 : : wr32(hw, TXGBE_PSRCTL, psrctl);
4057 : :
4058 : 0 : return 0;
4059 : : }
4060 : :
4061 : : static int
4062 : 0 : txgbe_uc_all_hash_table_set(struct rte_eth_dev *dev, uint8_t on)
4063 : : {
4064 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4065 : : struct txgbe_uta_info *uta_info = TXGBE_DEV_UTA_INFO(dev);
4066 : : uint32_t psrctl;
4067 : : int i;
4068 : :
4069 : : /* The UTA table only exists on pf hardware */
4070 [ # # ]: 0 : if (hw->mac.type < txgbe_mac_sp)
4071 : : return -ENOTSUP;
4072 : :
4073 [ # # ]: 0 : if (on) {
4074 [ # # ]: 0 : for (i = 0; i < RTE_ETH_VMDQ_NUM_UC_HASH_ARRAY; i++) {
4075 : 0 : uta_info->uta_shadow[i] = ~0;
4076 : 0 : wr32(hw, TXGBE_UCADDRTBL(i), ~0);
4077 : : }
4078 : : } else {
4079 [ # # ]: 0 : for (i = 0; i < RTE_ETH_VMDQ_NUM_UC_HASH_ARRAY; i++) {
4080 : 0 : uta_info->uta_shadow[i] = 0;
4081 : 0 : wr32(hw, TXGBE_UCADDRTBL(i), 0);
4082 : : }
4083 : : }
4084 : :
4085 : : psrctl = rd32(hw, TXGBE_PSRCTL);
4086 [ # # ]: 0 : if (on)
4087 : 0 : psrctl |= TXGBE_PSRCTL_UCHFENA;
4088 : : else
4089 : 0 : psrctl &= ~TXGBE_PSRCTL_UCHFENA;
4090 : :
4091 : 0 : psrctl &= ~TXGBE_PSRCTL_ADHF12_MASK;
4092 : 0 : psrctl |= TXGBE_PSRCTL_ADHF12(hw->mac.mc_filter_type);
4093 : : wr32(hw, TXGBE_PSRCTL, psrctl);
4094 : :
4095 : 0 : return 0;
4096 : : }
4097 : :
4098 : : uint32_t
4099 : 0 : txgbe_convert_vm_rx_mask_to_val(uint16_t rx_mask, uint32_t orig_val)
4100 : : {
4101 : : uint32_t new_val = orig_val;
4102 : :
4103 [ # # ]: 0 : if (rx_mask & RTE_ETH_VMDQ_ACCEPT_UNTAG)
4104 : 0 : new_val |= TXGBE_POOLETHCTL_UTA;
4105 [ # # ]: 0 : if (rx_mask & RTE_ETH_VMDQ_ACCEPT_HASH_MC)
4106 : 0 : new_val |= TXGBE_POOLETHCTL_MCHA;
4107 [ # # ]: 0 : if (rx_mask & RTE_ETH_VMDQ_ACCEPT_HASH_UC)
4108 : 0 : new_val |= TXGBE_POOLETHCTL_UCHA;
4109 [ # # ]: 0 : if (rx_mask & RTE_ETH_VMDQ_ACCEPT_BROADCAST)
4110 : 0 : new_val |= TXGBE_POOLETHCTL_BCA;
4111 [ # # ]: 0 : if (rx_mask & RTE_ETH_VMDQ_ACCEPT_MULTICAST)
4112 : 0 : new_val |= TXGBE_POOLETHCTL_MCP;
4113 : :
4114 : 0 : return new_val;
4115 : : }
4116 : :
4117 : : static int
4118 : 0 : txgbe_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
4119 : : {
4120 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
4121 : 0 : struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
4122 : : uint32_t mask;
4123 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4124 : :
4125 [ # # ]: 0 : if (queue_id < 32) {
4126 : : mask = rd32(hw, TXGBE_IMC(0));
4127 : 0 : mask |= (1 << queue_id);
4128 : : wr32(hw, TXGBE_IMC(0), mask);
4129 [ # # ]: 0 : } else if (queue_id < 64) {
4130 : : mask = rd32(hw, TXGBE_IMC(1));
4131 : 0 : mask |= (1 << (queue_id - 32));
4132 : : wr32(hw, TXGBE_IMC(1), mask);
4133 : : }
4134 : 0 : rte_intr_enable(intr_handle);
4135 : :
4136 : 0 : return 0;
4137 : : }
4138 : :
4139 : : static int
4140 : 0 : txgbe_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
4141 : : {
4142 : : uint32_t mask;
4143 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4144 : :
4145 [ # # ]: 0 : if (queue_id < 32) {
4146 : : mask = rd32(hw, TXGBE_IMS(0));
4147 : 0 : mask |= (1 << queue_id);
4148 : : wr32(hw, TXGBE_IMS(0), mask);
4149 [ # # ]: 0 : } else if (queue_id < 64) {
4150 : : mask = rd32(hw, TXGBE_IMS(1));
4151 : 0 : mask |= (1 << (queue_id - 32));
4152 : : wr32(hw, TXGBE_IMS(1), mask);
4153 : : }
4154 : :
4155 : 0 : return 0;
4156 : : }
4157 : :
4158 : : /**
4159 : : * set the IVAR registers, mapping interrupt causes to vectors
4160 : : * @param hw
4161 : : * pointer to txgbe_hw struct
4162 : : * @direction
4163 : : * 0 for Rx, 1 for Tx, -1 for other causes
4164 : : * @queue
4165 : : * queue to map the corresponding interrupt to
4166 : : * @msix_vector
4167 : : * the vector to map to the corresponding queue
4168 : : */
4169 : : void
4170 : 0 : txgbe_set_ivar_map(struct txgbe_hw *hw, int8_t direction,
4171 : : uint8_t queue, uint8_t msix_vector)
4172 : : {
4173 : : uint32_t tmp, idx;
4174 : :
4175 [ # # ]: 0 : if (direction == -1) {
4176 : : /* other causes */
4177 : 0 : msix_vector |= TXGBE_IVARMISC_VLD;
4178 : : idx = 0;
4179 : : tmp = rd32(hw, TXGBE_IVARMISC);
4180 : 0 : tmp &= ~(0xFF << idx);
4181 : 0 : tmp |= (msix_vector << idx);
4182 : : wr32(hw, TXGBE_IVARMISC, tmp);
4183 : : } else {
4184 : : /* rx or tx causes */
4185 : 0 : msix_vector |= TXGBE_IVAR_VLD; /* Workaround for ICR lost */
4186 : 0 : idx = ((16 * (queue & 1)) + (8 * direction));
4187 : 0 : tmp = rd32(hw, TXGBE_IVAR(queue >> 1));
4188 : 0 : tmp &= ~(0xFF << idx);
4189 : 0 : tmp |= (msix_vector << idx);
4190 : : wr32(hw, TXGBE_IVAR(queue >> 1), tmp);
4191 : : }
4192 : 0 : }
4193 : :
4194 : : /**
4195 : : * Sets up the hardware to properly generate MSI-X interrupts
4196 : : * @hw
4197 : : * board private structure
4198 : : */
4199 : : static void
4200 : 0 : txgbe_configure_msix(struct rte_eth_dev *dev)
4201 : : {
4202 : 0 : struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
4203 : 0 : struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
4204 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4205 : : uint32_t queue_id, base = TXGBE_MISC_VEC_ID;
4206 : : uint32_t vec = TXGBE_MISC_VEC_ID;
4207 : : uint32_t gpie;
4208 : :
4209 : : /* won't configure msix register if no mapping is done
4210 : : * between intr vector and event fd
4211 : : * but if misx has been enabled already, need to configure
4212 : : * auto clean, auto mask and throttling.
4213 : : */
4214 : : gpie = rd32(hw, TXGBE_GPIE);
4215 [ # # ]: 0 : if (!rte_intr_dp_is_en(intr_handle) &&
4216 [ # # ]: 0 : !(gpie & TXGBE_GPIE_MSIX))
4217 : : return;
4218 : :
4219 [ # # ]: 0 : if (rte_intr_allow_others(intr_handle)) {
4220 : : base = TXGBE_RX_VEC_START;
4221 : : vec = base;
4222 : : }
4223 : :
4224 : : /* setup GPIE for MSI-x mode */
4225 : : gpie = rd32(hw, TXGBE_GPIE);
4226 : 0 : gpie |= TXGBE_GPIE_MSIX;
4227 : : wr32(hw, TXGBE_GPIE, gpie);
4228 : :
4229 : : /* Populate the IVAR table and set the ITR values to the
4230 : : * corresponding register.
4231 : : */
4232 [ # # ]: 0 : if (rte_intr_dp_is_en(intr_handle)) {
4233 [ # # ]: 0 : for (queue_id = 0; queue_id < dev->data->nb_rx_queues;
4234 : 0 : queue_id++) {
4235 : : /* by default, 1:1 mapping */
4236 : 0 : txgbe_set_ivar_map(hw, 0, queue_id, vec);
4237 : 0 : rte_intr_vec_list_index_set(intr_handle,
4238 : : queue_id, vec);
4239 : 0 : if (vec < base + rte_intr_nb_efd_get(intr_handle)
4240 [ # # ]: 0 : - 1)
4241 : 0 : vec++;
4242 : : }
4243 : :
4244 : 0 : txgbe_set_ivar_map(hw, -1, 1, TXGBE_MISC_VEC_ID);
4245 : : }
4246 : : wr32(hw, TXGBE_ITR(TXGBE_MISC_VEC_ID),
4247 : : TXGBE_ITR_IVAL_10G(TXGBE_QUEUE_ITR_INTERVAL_DEFAULT)
4248 : : | TXGBE_ITR_WRDSA);
4249 : : }
4250 : :
4251 : : static u16 txgbe_frac_to_bi(u16 frac, u16 denom, int max_bits)
4252 : : {
4253 : : u16 value = 0;
4254 : :
4255 [ # # ]: 0 : while (frac > 0 && max_bits > 0) {
4256 : 0 : max_bits -= 1;
4257 : 0 : frac *= 2;
4258 [ # # ]: 0 : if (frac >= denom) {
4259 : 0 : value |= BIT(max_bits);
4260 : 0 : frac -= denom;
4261 : : }
4262 : : }
4263 : :
4264 : : return value;
4265 : : }
4266 : :
4267 : : int
4268 : 0 : txgbe_set_queue_rate_limit(struct rte_eth_dev *dev,
4269 : : uint16_t queue_idx, uint32_t tx_rate)
4270 : : {
4271 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4272 : : uint32_t bcnrc_val;
4273 : : int factor_int, factor_fra;
4274 : : uint32_t link_speed;
4275 : :
4276 [ # # ]: 0 : if (queue_idx >= hw->mac.max_tx_queues)
4277 : : return -EINVAL;
4278 : :
4279 : : /*
4280 : : * Set global transmit compensation time to the MMW_SIZE in ARBTXMMW
4281 : : * register. MMW_SIZE=0x014 if 9728-byte jumbo is supported.
4282 : : */
4283 : : wr32(hw, TXGBE_ARBTXMMW, 0x14);
4284 : :
4285 [ # # ]: 0 : if (hw->mac.type == txgbe_mac_aml || hw->mac.type == txgbe_mac_aml40) {
4286 [ # # ]: 0 : if (tx_rate) {
4287 : : u16 frac;
4288 : :
4289 : 0 : link_speed = dev->data->dev_link.link_speed;
4290 : 0 : tx_rate = tx_rate * 105 / 100;
4291 : : /* Calculate the rate factor values to set */
4292 : 0 : factor_int = link_speed / tx_rate;
4293 : 0 : frac = (link_speed % tx_rate) * 10000 / tx_rate;
4294 : 0 : factor_fra = txgbe_frac_to_bi(frac, 10000, 14);
4295 [ # # ]: 0 : if (tx_rate > link_speed) {
4296 : : factor_int = 1;
4297 : : factor_fra = 0;
4298 : : }
4299 : :
4300 : : wr32(hw, TXGBE_TDM_RL_QUEUE_IDX, queue_idx);
4301 : 0 : wr32m(hw, TXGBE_TDM_RL_QUEUE_CFG,
4302 : 0 : TXGBE_TDM_FACTOR_INT_MASK, factor_int << TXGBE_TDM_FACTOR_INT_SHIFT);
4303 : 0 : wr32m(hw, TXGBE_TDM_RL_QUEUE_CFG,
4304 : 0 : TXGBE_TDM_FACTOR_FRA_MASK, factor_fra << TXGBE_TDM_FACTOR_FRA_SHIFT);
4305 : : wr32m(hw, TXGBE_TDM_RL_QUEUE_CFG,
4306 : : TXGBE_TDM_RL_EN, TXGBE_TDM_RL_EN);
4307 : : } else {
4308 : : wr32(hw, TXGBE_TDM_RL_QUEUE_IDX, queue_idx);
4309 : : wr32m(hw, TXGBE_TDM_RL_QUEUE_CFG,
4310 : : TXGBE_TDM_RL_EN, 0);
4311 : : }
4312 : : } else {
4313 [ # # ]: 0 : if (tx_rate != 0) {
4314 : 0 : bcnrc_val = TXGBE_ARBTXRATE_MAX(tx_rate);
4315 : 0 : bcnrc_val |= TXGBE_ARBTXRATE_MIN(tx_rate / 2);
4316 : : } else {
4317 : : bcnrc_val = 0;
4318 : : }
4319 : :
4320 : : /* Set ARBTXRATE of queue X */
4321 : : wr32(hw, TXGBE_ARBPOOLIDX, queue_idx);
4322 : : wr32(hw, TXGBE_ARBTXRATE, bcnrc_val);
4323 : : txgbe_flush(hw);
4324 : : }
4325 : :
4326 : : return 0;
4327 : : }
4328 : :
4329 : : int
4330 : 0 : txgbe_syn_filter_set(struct rte_eth_dev *dev,
4331 : : struct rte_eth_syn_filter *filter,
4332 : : bool add)
4333 : : {
4334 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4335 : : struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
4336 : : uint32_t syn_info;
4337 : : uint32_t synqf;
4338 : : uint16_t queue;
4339 : :
4340 [ # # ]: 0 : if (filter->queue >= TXGBE_MAX_RX_QUEUE_NUM)
4341 : : return -EINVAL;
4342 : :
4343 : 0 : syn_info = filter_info->syn_info;
4344 : :
4345 [ # # ]: 0 : if (add) {
4346 [ # # ]: 0 : if (syn_info & TXGBE_SYNCLS_ENA)
4347 : : return -EINVAL;
4348 [ # # ]: 0 : if (RTE_ETH_DEV_SRIOV(dev).active)
4349 : 0 : queue = RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx + filter->queue;
4350 : : else
4351 : : queue = filter->queue;
4352 : 0 : synqf = (uint32_t)TXGBE_SYNCLS_QPID(queue);
4353 : 0 : synqf |= TXGBE_SYNCLS_ENA;
4354 : :
4355 [ # # ]: 0 : if (filter->hig_pri)
4356 : 0 : synqf |= TXGBE_SYNCLS_HIPRIO;
4357 : : else
4358 : : synqf &= ~TXGBE_SYNCLS_HIPRIO;
4359 : : } else {
4360 : : synqf = rd32(hw, TXGBE_SYNCLS);
4361 [ # # ]: 0 : if (!(syn_info & TXGBE_SYNCLS_ENA))
4362 : : return -ENOENT;
4363 : 0 : synqf &= ~(TXGBE_SYNCLS_QPID_MASK | TXGBE_SYNCLS_ENA);
4364 : : }
4365 : :
4366 : 0 : filter_info->syn_info = synqf;
4367 : : wr32(hw, TXGBE_SYNCLS, synqf);
4368 : : txgbe_flush(hw);
4369 : : return 0;
4370 : : }
4371 : :
4372 : : static inline enum txgbe_5tuple_protocol
4373 : : convert_protocol_type(uint8_t protocol_value)
4374 : : {
4375 : 0 : if (protocol_value == IPPROTO_TCP)
4376 : : return TXGBE_5TF_PROT_TCP;
4377 [ # # ]: 0 : else if (protocol_value == IPPROTO_UDP)
4378 : : return TXGBE_5TF_PROT_UDP;
4379 [ # # ]: 0 : else if (protocol_value == IPPROTO_SCTP)
4380 : : return TXGBE_5TF_PROT_SCTP;
4381 : : else
4382 : 0 : return TXGBE_5TF_PROT_NONE;
4383 : : }
4384 : :
4385 : : /* inject a 5-tuple filter to HW */
4386 : : static inline void
4387 : 0 : txgbe_inject_5tuple_filter(struct rte_eth_dev *dev,
4388 : : struct txgbe_5tuple_filter *filter)
4389 : : {
4390 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4391 : : int i;
4392 : : uint32_t ftqf, sdpqf;
4393 : : uint32_t l34timir = 0;
4394 : : uint32_t mask = TXGBE_5TFCTL0_MASK;
4395 : :
4396 : 0 : i = filter->index;
4397 [ # # ]: 0 : sdpqf = TXGBE_5TFPORT_DST(be_to_le16(filter->filter_info.dst_port));
4398 [ # # ]: 0 : sdpqf |= TXGBE_5TFPORT_SRC(be_to_le16(filter->filter_info.src_port));
4399 : :
4400 : 0 : ftqf = TXGBE_5TFCTL0_PROTO(filter->filter_info.proto);
4401 : 0 : ftqf |= TXGBE_5TFCTL0_PRI(filter->filter_info.priority);
4402 [ # # ]: 0 : if (filter->filter_info.src_ip_mask == 0) /* 0 means compare. */
4403 : : mask &= ~TXGBE_5TFCTL0_MSADDR;
4404 [ # # ]: 0 : if (filter->filter_info.dst_ip_mask == 0)
4405 : 0 : mask &= ~TXGBE_5TFCTL0_MDADDR;
4406 [ # # ]: 0 : if (filter->filter_info.src_port_mask == 0)
4407 : 0 : mask &= ~TXGBE_5TFCTL0_MSPORT;
4408 [ # # ]: 0 : if (filter->filter_info.dst_port_mask == 0)
4409 : 0 : mask &= ~TXGBE_5TFCTL0_MDPORT;
4410 [ # # ]: 0 : if (filter->filter_info.proto_mask == 0)
4411 : 0 : mask &= ~TXGBE_5TFCTL0_MPROTO;
4412 : 0 : ftqf |= mask;
4413 : : ftqf |= TXGBE_5TFCTL0_MPOOL;
4414 : 0 : ftqf |= TXGBE_5TFCTL0_ENA;
4415 : :
4416 [ # # ]: 0 : wr32(hw, TXGBE_5TFDADDR(i), be_to_le32(filter->filter_info.dst_ip));
4417 [ # # ]: 0 : wr32(hw, TXGBE_5TFSADDR(i), be_to_le32(filter->filter_info.src_ip));
4418 : 0 : wr32(hw, TXGBE_5TFPORT(i), sdpqf);
4419 : 0 : wr32(hw, TXGBE_5TFCTL0(i), ftqf);
4420 : :
4421 [ # # ]: 0 : if (RTE_ETH_DEV_SRIOV(dev).active)
4422 : 0 : l34timir |= TXGBE_5TFCTL1_QP(RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx + filter->queue);
4423 : : else
4424 : 0 : l34timir |= TXGBE_5TFCTL1_QP(filter->queue);
4425 : 0 : wr32(hw, TXGBE_5TFCTL1(i), l34timir);
4426 : 0 : }
4427 : :
4428 : : /*
4429 : : * add a 5tuple filter
4430 : : *
4431 : : * @param
4432 : : * dev: Pointer to struct rte_eth_dev.
4433 : : * index: the index the filter allocates.
4434 : : * filter: pointer to the filter that will be added.
4435 : : * rx_queue: the queue id the filter assigned to.
4436 : : *
4437 : : * @return
4438 : : * - On success, zero.
4439 : : * - On failure, a negative value.
4440 : : */
4441 : : static int
4442 : 0 : txgbe_add_5tuple_filter(struct rte_eth_dev *dev,
4443 : : struct txgbe_5tuple_filter *filter)
4444 : : {
4445 : 0 : struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
4446 : : int i, idx, shift;
4447 : :
4448 : : /*
4449 : : * look for an unused 5tuple filter index,
4450 : : * and insert the filter to list.
4451 : : */
4452 [ # # ]: 0 : for (i = 0; i < TXGBE_MAX_FTQF_FILTERS; i++) {
4453 : 0 : idx = i / (sizeof(uint32_t) * NBBY);
4454 : 0 : shift = i % (sizeof(uint32_t) * NBBY);
4455 [ # # ]: 0 : if (!(filter_info->fivetuple_mask[idx] & (1 << shift))) {
4456 : 0 : filter_info->fivetuple_mask[idx] |= 1 << shift;
4457 : 0 : filter->index = i;
4458 : 0 : TAILQ_INSERT_TAIL(&filter_info->fivetuple_list,
4459 : : filter,
4460 : : entries);
4461 : 0 : break;
4462 : : }
4463 : : }
4464 [ # # ]: 0 : if (i >= TXGBE_MAX_FTQF_FILTERS) {
4465 : 0 : PMD_DRV_LOG(ERR, "5tuple filters are full.");
4466 : 0 : return -ENOSYS;
4467 : : }
4468 : :
4469 [ # # ]: 0 : if (txgbe_is_pf(TXGBE_DEV_HW(dev)))
4470 : 0 : txgbe_inject_5tuple_filter(dev, filter);
4471 : : else
4472 : 0 : txgbevf_inject_5tuple_filter(dev, filter);
4473 : :
4474 : : return 0;
4475 : : }
4476 : :
4477 : : /*
4478 : : * remove a 5tuple filter
4479 : : *
4480 : : * @param
4481 : : * dev: Pointer to struct rte_eth_dev.
4482 : : * filter: the pointer of the filter will be removed.
4483 : : */
4484 : : static void
4485 : 0 : txgbe_remove_5tuple_filter(struct rte_eth_dev *dev,
4486 : : struct txgbe_5tuple_filter *filter)
4487 : : {
4488 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4489 : : struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
4490 : 0 : uint16_t index = filter->index;
4491 : :
4492 : 0 : filter_info->fivetuple_mask[index / (sizeof(uint32_t) * NBBY)] &=
4493 : 0 : ~(1 << (index % (sizeof(uint32_t) * NBBY)));
4494 [ # # ]: 0 : TAILQ_REMOVE(&filter_info->fivetuple_list, filter, entries);
4495 : 0 : rte_free(filter);
4496 : :
4497 [ # # ]: 0 : if (!txgbe_is_pf(TXGBE_DEV_HW(dev))) {
4498 : 0 : txgbevf_remove_5tuple_filter(dev, index);
4499 : 0 : return;
4500 : : }
4501 : :
4502 : 0 : wr32(hw, TXGBE_5TFDADDR(index), 0);
4503 : 0 : wr32(hw, TXGBE_5TFSADDR(index), 0);
4504 : 0 : wr32(hw, TXGBE_5TFPORT(index), 0);
4505 : 0 : wr32(hw, TXGBE_5TFCTL0(index), 0);
4506 : 0 : wr32(hw, TXGBE_5TFCTL1(index), 0);
4507 : : }
4508 : :
4509 : : static inline struct txgbe_5tuple_filter *
4510 : : txgbe_5tuple_filter_lookup(struct txgbe_5tuple_filter_list *filter_list,
4511 : : struct txgbe_5tuple_filter_info *key)
4512 : : {
4513 : : struct txgbe_5tuple_filter *it;
4514 : :
4515 [ # # ]: 0 : TAILQ_FOREACH(it, filter_list, entries) {
4516 [ # # ]: 0 : if (memcmp(key, &it->filter_info,
4517 : : sizeof(struct txgbe_5tuple_filter_info)) == 0) {
4518 : : return it;
4519 : : }
4520 : : }
4521 : : return NULL;
4522 : : }
4523 : :
4524 : : /* translate elements in struct rte_eth_ntuple_filter
4525 : : * to struct txgbe_5tuple_filter_info
4526 : : */
4527 : : static inline int
4528 : 0 : ntuple_filter_to_5tuple(struct rte_eth_ntuple_filter *filter,
4529 : : struct txgbe_5tuple_filter_info *filter_info)
4530 : : {
4531 [ # # ]: 0 : if (filter->queue >= TXGBE_MAX_RX_QUEUE_NUM ||
4532 [ # # # # ]: 0 : filter->priority > TXGBE_5TUPLE_MAX_PRI ||
4533 : : filter->priority < TXGBE_5TUPLE_MIN_PRI)
4534 : : return -EINVAL;
4535 : :
4536 [ # # # ]: 0 : switch (filter->dst_ip_mask) {
4537 : 0 : case UINT32_MAX:
4538 : 0 : filter_info->dst_ip_mask = 0;
4539 : 0 : filter_info->dst_ip = filter->dst_ip;
4540 : 0 : break;
4541 : 0 : case 0:
4542 : 0 : filter_info->dst_ip_mask = 1;
4543 : 0 : break;
4544 : 0 : default:
4545 : 0 : PMD_DRV_LOG(ERR, "invalid dst_ip mask.");
4546 : 0 : return -EINVAL;
4547 : : }
4548 : :
4549 [ # # # ]: 0 : switch (filter->src_ip_mask) {
4550 : 0 : case UINT32_MAX:
4551 : 0 : filter_info->src_ip_mask = 0;
4552 : 0 : filter_info->src_ip = filter->src_ip;
4553 : 0 : break;
4554 : 0 : case 0:
4555 : 0 : filter_info->src_ip_mask = 1;
4556 : 0 : break;
4557 : 0 : default:
4558 : 0 : PMD_DRV_LOG(ERR, "invalid src_ip mask.");
4559 : 0 : return -EINVAL;
4560 : : }
4561 : :
4562 [ # # # ]: 0 : switch (filter->dst_port_mask) {
4563 : 0 : case UINT16_MAX:
4564 : 0 : filter_info->dst_port_mask = 0;
4565 : 0 : filter_info->dst_port = filter->dst_port;
4566 : 0 : break;
4567 : 0 : case 0:
4568 : 0 : filter_info->dst_port_mask = 1;
4569 : 0 : break;
4570 : 0 : default:
4571 : 0 : PMD_DRV_LOG(ERR, "invalid dst_port mask.");
4572 : 0 : return -EINVAL;
4573 : : }
4574 : :
4575 [ # # # ]: 0 : switch (filter->src_port_mask) {
4576 : 0 : case UINT16_MAX:
4577 : 0 : filter_info->src_port_mask = 0;
4578 : 0 : filter_info->src_port = filter->src_port;
4579 : 0 : break;
4580 : 0 : case 0:
4581 : 0 : filter_info->src_port_mask = 1;
4582 : 0 : break;
4583 : 0 : default:
4584 : 0 : PMD_DRV_LOG(ERR, "invalid src_port mask.");
4585 : 0 : return -EINVAL;
4586 : : }
4587 : :
4588 [ # # # ]: 0 : switch (filter->proto_mask) {
4589 : 0 : case UINT8_MAX:
4590 : 0 : filter_info->proto_mask = 0;
4591 : 0 : filter_info->proto =
4592 [ # # ]: 0 : convert_protocol_type(filter->proto);
4593 : 0 : break;
4594 : 0 : case 0:
4595 : 0 : filter_info->proto_mask = 1;
4596 : 0 : break;
4597 : 0 : default:
4598 : 0 : PMD_DRV_LOG(ERR, "invalid protocol mask.");
4599 : 0 : return -EINVAL;
4600 : : }
4601 : :
4602 : 0 : filter_info->priority = (uint8_t)filter->priority;
4603 : 0 : return 0;
4604 : : }
4605 : :
4606 : : /*
4607 : : * add or delete a ntuple filter
4608 : : *
4609 : : * @param
4610 : : * dev: Pointer to struct rte_eth_dev.
4611 : : * ntuple_filter: Pointer to struct rte_eth_ntuple_filter
4612 : : * add: if true, add filter, if false, remove filter
4613 : : *
4614 : : * @return
4615 : : * - On success, zero.
4616 : : * - On failure, a negative value.
4617 : : */
4618 : : int
4619 : 0 : txgbe_add_del_ntuple_filter(struct rte_eth_dev *dev,
4620 : : struct rte_eth_ntuple_filter *ntuple_filter,
4621 : : bool add)
4622 : : {
4623 : 0 : struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
4624 : : struct txgbe_5tuple_filter_info filter_5tuple;
4625 : : struct txgbe_5tuple_filter *filter;
4626 : : int ret;
4627 : :
4628 [ # # ]: 0 : if (ntuple_filter->flags != RTE_5TUPLE_FLAGS) {
4629 : 0 : PMD_DRV_LOG(ERR, "only 5tuple is supported.");
4630 : 0 : return -EINVAL;
4631 : : }
4632 : :
4633 : : memset(&filter_5tuple, 0, sizeof(struct txgbe_5tuple_filter_info));
4634 : 0 : ret = ntuple_filter_to_5tuple(ntuple_filter, &filter_5tuple);
4635 [ # # ]: 0 : if (ret < 0)
4636 : : return ret;
4637 : :
4638 : : filter = txgbe_5tuple_filter_lookup(&filter_info->fivetuple_list,
4639 : : &filter_5tuple);
4640 [ # # ]: 0 : if (filter != NULL && add) {
4641 : 0 : PMD_DRV_LOG(ERR, "filter exists.");
4642 : 0 : return -EEXIST;
4643 : : }
4644 [ # # ]: 0 : if (filter == NULL && !add) {
4645 : 0 : PMD_DRV_LOG(ERR, "filter doesn't exist.");
4646 : 0 : return -ENOENT;
4647 : : }
4648 : :
4649 [ # # ]: 0 : if (add) {
4650 : 0 : filter = rte_zmalloc("txgbe_5tuple_filter",
4651 : : sizeof(struct txgbe_5tuple_filter), 0);
4652 [ # # ]: 0 : if (filter == NULL)
4653 : : return -ENOMEM;
4654 [ # # ]: 0 : rte_memcpy(&filter->filter_info,
4655 : : &filter_5tuple,
4656 : : sizeof(struct txgbe_5tuple_filter_info));
4657 : 0 : filter->queue = ntuple_filter->queue;
4658 : 0 : ret = txgbe_add_5tuple_filter(dev, filter);
4659 [ # # ]: 0 : if (ret < 0) {
4660 : 0 : rte_free(filter);
4661 : 0 : return ret;
4662 : : }
4663 : : } else {
4664 : 0 : txgbe_remove_5tuple_filter(dev, filter);
4665 : : }
4666 : :
4667 : : return 0;
4668 : : }
4669 : :
4670 : : int
4671 : 0 : txgbe_add_del_ethertype_filter(struct rte_eth_dev *dev,
4672 : : struct rte_eth_ethertype_filter *filter,
4673 : : bool add)
4674 : : {
4675 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4676 : 0 : struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
4677 : : uint32_t etqf = 0;
4678 : : uint32_t etqs = 0;
4679 : : int ret;
4680 : : struct txgbe_ethertype_filter ethertype_filter;
4681 : :
4682 [ # # ]: 0 : if (filter->queue >= TXGBE_MAX_RX_QUEUE_NUM)
4683 : : return -EINVAL;
4684 : :
4685 [ # # ]: 0 : if (filter->ether_type == RTE_ETHER_TYPE_IPV4 ||
4686 : : filter->ether_type == RTE_ETHER_TYPE_IPV6) {
4687 : 0 : PMD_DRV_LOG(ERR, "unsupported ether_type(0x%04x) in"
4688 : : " ethertype filter.", filter->ether_type);
4689 : 0 : return -EINVAL;
4690 : : }
4691 : :
4692 [ # # ]: 0 : if (filter->flags & RTE_ETHTYPE_FLAGS_MAC) {
4693 : 0 : PMD_DRV_LOG(ERR, "mac compare is unsupported.");
4694 : 0 : return -EINVAL;
4695 : : }
4696 [ # # ]: 0 : if (filter->flags & RTE_ETHTYPE_FLAGS_DROP) {
4697 : 0 : PMD_DRV_LOG(ERR, "drop option is unsupported.");
4698 : 0 : return -EINVAL;
4699 : : }
4700 : :
4701 : 0 : ret = txgbe_ethertype_filter_lookup(filter_info, filter->ether_type);
4702 [ # # ]: 0 : if (ret >= 0 && add) {
4703 : 0 : PMD_DRV_LOG(ERR, "ethertype (0x%04x) filter exists.",
4704 : : filter->ether_type);
4705 : 0 : return -EEXIST;
4706 : : }
4707 [ # # ]: 0 : if (ret < 0 && !add) {
4708 : 0 : PMD_DRV_LOG(ERR, "ethertype (0x%04x) filter doesn't exist.",
4709 : : filter->ether_type);
4710 : 0 : return -ENOENT;
4711 : : }
4712 : :
4713 [ # # ]: 0 : if (add) {
4714 : : etqf = TXGBE_ETFLT_ENA;
4715 : 0 : etqf |= TXGBE_ETFLT_ETID(filter->ether_type);
4716 [ # # ]: 0 : if (RTE_ETH_DEV_SRIOV(dev).active) {
4717 : : int pool, queue;
4718 : :
4719 : 0 : pool = RTE_ETH_DEV_SRIOV(dev).def_vmdq_idx;
4720 : 0 : queue = RTE_ETH_DEV_SRIOV(dev).def_pool_q_idx + filter->queue;
4721 : 0 : etqf |= TXGBE_ETFLT_POOLENA;
4722 : 0 : etqf |= TXGBE_ETFLT_POOL(pool);
4723 : 0 : etqs |= TXGBE_ETCLS_QPID(queue);
4724 : : } else {
4725 : 0 : etqs |= TXGBE_ETCLS_QPID(filter->queue);
4726 : : }
4727 : 0 : etqs |= TXGBE_ETCLS_QENA;
4728 : :
4729 : 0 : ethertype_filter.ethertype = filter->ether_type;
4730 : 0 : ethertype_filter.etqf = etqf;
4731 : 0 : ethertype_filter.etqs = etqs;
4732 : 0 : ethertype_filter.conf = FALSE;
4733 : 0 : ret = txgbe_ethertype_filter_insert(filter_info,
4734 : : ðertype_filter);
4735 [ # # ]: 0 : if (ret < 0) {
4736 : 0 : PMD_DRV_LOG(ERR, "ethertype filters are full.");
4737 : 0 : return -ENOSPC;
4738 : : }
4739 : : } else {
4740 [ # # ]: 0 : ret = txgbe_ethertype_filter_remove(filter_info, (uint8_t)ret);
4741 : : if (ret < 0)
4742 : : return -ENOSYS;
4743 : : }
4744 : 0 : wr32(hw, TXGBE_ETFLT(ret), etqf);
4745 : 0 : wr32(hw, TXGBE_ETCLS(ret), etqs);
4746 : : txgbe_flush(hw);
4747 : :
4748 : : return 0;
4749 : : }
4750 : :
4751 : : static int
4752 : 0 : txgbe_dev_flow_ops_get(__rte_unused struct rte_eth_dev *dev,
4753 : : const struct rte_flow_ops **ops)
4754 : : {
4755 : 0 : *ops = &txgbe_flow_ops;
4756 : 0 : return 0;
4757 : : }
4758 : :
4759 : : static u8 *
4760 : 0 : txgbe_dev_addr_list_itr(__rte_unused struct txgbe_hw *hw,
4761 : : u8 **mc_addr_ptr, u32 *vmdq)
4762 : : {
4763 : : u8 *mc_addr;
4764 : :
4765 : 0 : *vmdq = 0;
4766 : 0 : mc_addr = *mc_addr_ptr;
4767 : 0 : *mc_addr_ptr = (mc_addr + sizeof(struct rte_ether_addr));
4768 : 0 : return mc_addr;
4769 : : }
4770 : :
4771 : : int
4772 : 0 : txgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
4773 : : struct rte_ether_addr *mc_addr_set,
4774 : : uint32_t nb_mc_addr)
4775 : : {
4776 : : struct txgbe_hw *hw;
4777 : : u8 *mc_addr_list;
4778 : :
4779 : 0 : hw = TXGBE_DEV_HW(dev);
4780 : : mc_addr_list = (u8 *)mc_addr_set;
4781 : 0 : return hw->mac.update_mc_addr_list(hw, mc_addr_list, nb_mc_addr,
4782 : : txgbe_dev_addr_list_itr, TRUE);
4783 : : }
4784 : :
4785 : : static uint64_t
4786 : : txgbe_read_systime_cyclecounter(struct rte_eth_dev *dev)
4787 : : {
4788 : : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4789 : : uint64_t systime_cycles;
4790 : :
4791 : 0 : systime_cycles = (uint64_t)rd32(hw, TXGBE_TSTIMEL);
4792 [ # # ]: 0 : systime_cycles |= (uint64_t)rd32(hw, TXGBE_TSTIMEH) << 32;
4793 : :
4794 : : return systime_cycles;
4795 : : }
4796 : :
4797 : : static uint64_t
4798 : : txgbe_read_rx_tstamp_cyclecounter(struct rte_eth_dev *dev)
4799 : : {
4800 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4801 : : uint64_t rx_tstamp_cycles;
4802 : :
4803 : : /* TSRXSTMPL stores ns and TSRXSTMPH stores seconds. */
4804 : 0 : rx_tstamp_cycles = (uint64_t)rd32(hw, TXGBE_TSRXSTMPL);
4805 [ # # ]: 0 : rx_tstamp_cycles |= (uint64_t)rd32(hw, TXGBE_TSRXSTMPH) << 32;
4806 : :
4807 : : return rx_tstamp_cycles;
4808 : : }
4809 : :
4810 : : static uint64_t
4811 : : txgbe_read_tx_tstamp_cyclecounter(struct rte_eth_dev *dev)
4812 : : {
4813 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4814 : : uint64_t tx_tstamp_cycles;
4815 : :
4816 : : /* TSTXSTMPL stores ns and TSTXSTMPH stores seconds. */
4817 : 0 : tx_tstamp_cycles = (uint64_t)rd32(hw, TXGBE_TSTXSTMPL);
4818 [ # # ]: 0 : tx_tstamp_cycles |= (uint64_t)rd32(hw, TXGBE_TSTXSTMPH) << 32;
4819 : :
4820 : : return tx_tstamp_cycles;
4821 : : }
4822 : :
4823 : : static void
4824 : 0 : txgbe_start_timecounters(struct rte_eth_dev *dev)
4825 : : {
4826 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4827 : : struct txgbe_adapter *adapter = TXGBE_DEV_ADAPTER(dev);
4828 : : struct rte_eth_link link;
4829 : : uint32_t incval = 0;
4830 : : uint32_t shift = 0;
4831 : :
4832 : : /* Get current link speed. */
4833 : : txgbe_dev_link_update(dev, 1);
4834 : 0 : rte_eth_linkstatus_get(dev, &link);
4835 : :
4836 [ # # # ]: 0 : switch (link.link_speed) {
4837 : : case RTE_ETH_SPEED_NUM_100M:
4838 : : incval = TXGBE_INCVAL_100;
4839 : : shift = TXGBE_INCVAL_SHIFT_100;
4840 : : break;
4841 : 0 : case RTE_ETH_SPEED_NUM_1G:
4842 : : incval = TXGBE_INCVAL_1GB;
4843 : : shift = TXGBE_INCVAL_SHIFT_1GB;
4844 : 0 : break;
4845 : 0 : case RTE_ETH_SPEED_NUM_10G:
4846 : : default:
4847 : : incval = TXGBE_INCVAL_10GB;
4848 : : shift = TXGBE_INCVAL_SHIFT_10GB;
4849 : 0 : break;
4850 : : }
4851 : :
4852 : 0 : wr32(hw, TXGBE_TSTIMEINC, TXGBE_TSTIMEINC_VP(incval, 2));
4853 : :
4854 : 0 : memset(&adapter->systime_tc, 0, sizeof(struct rte_timecounter));
4855 : 0 : memset(&adapter->rx_tstamp_tc, 0, sizeof(struct rte_timecounter));
4856 : 0 : memset(&adapter->tx_tstamp_tc, 0, sizeof(struct rte_timecounter));
4857 : :
4858 : 0 : adapter->systime_tc.cc_mask = TXGBE_CYCLECOUNTER_MASK;
4859 : 0 : adapter->systime_tc.cc_shift = shift;
4860 : 0 : adapter->systime_tc.nsec_mask = (1ULL << shift) - 1;
4861 : :
4862 : 0 : adapter->rx_tstamp_tc.cc_mask = TXGBE_CYCLECOUNTER_MASK;
4863 : 0 : adapter->rx_tstamp_tc.cc_shift = shift;
4864 : 0 : adapter->rx_tstamp_tc.nsec_mask = (1ULL << shift) - 1;
4865 : :
4866 : 0 : adapter->tx_tstamp_tc.cc_mask = TXGBE_CYCLECOUNTER_MASK;
4867 : 0 : adapter->tx_tstamp_tc.cc_shift = shift;
4868 : 0 : adapter->tx_tstamp_tc.nsec_mask = (1ULL << shift) - 1;
4869 : 0 : }
4870 : :
4871 : : static int
4872 : 0 : txgbe_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta)
4873 : : {
4874 : 0 : struct txgbe_adapter *adapter = TXGBE_DEV_ADAPTER(dev);
4875 : :
4876 : 0 : adapter->systime_tc.nsec += delta;
4877 : 0 : adapter->rx_tstamp_tc.nsec += delta;
4878 : 0 : adapter->tx_tstamp_tc.nsec += delta;
4879 : :
4880 : 0 : return 0;
4881 : : }
4882 : :
4883 : : static int
4884 : 0 : txgbe_timesync_write_time(struct rte_eth_dev *dev, const struct timespec *ts)
4885 : : {
4886 : : uint64_t ns;
4887 : 0 : struct txgbe_adapter *adapter = TXGBE_DEV_ADAPTER(dev);
4888 : :
4889 : : ns = rte_timespec_to_ns(ts);
4890 : : /* Set the timecounters to a new value. */
4891 : 0 : adapter->systime_tc.nsec = ns;
4892 : 0 : adapter->rx_tstamp_tc.nsec = ns;
4893 : 0 : adapter->tx_tstamp_tc.nsec = ns;
4894 : :
4895 : 0 : return 0;
4896 : : }
4897 : :
4898 : : static int
4899 : 0 : txgbe_timesync_read_time(struct rte_eth_dev *dev, struct timespec *ts)
4900 : : {
4901 : : uint64_t ns, systime_cycles;
4902 : 0 : struct txgbe_adapter *adapter = TXGBE_DEV_ADAPTER(dev);
4903 : :
4904 : : systime_cycles = txgbe_read_systime_cyclecounter(dev);
4905 : : ns = rte_timecounter_update(&adapter->systime_tc, systime_cycles);
4906 : 0 : *ts = rte_ns_to_timespec(ns);
4907 : :
4908 : 0 : return 0;
4909 : : }
4910 : :
4911 : : static int
4912 : 0 : txgbe_timesync_enable(struct rte_eth_dev *dev)
4913 : : {
4914 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4915 : : uint32_t tsync_ctl;
4916 : :
4917 : : /* Stop the timesync system time. */
4918 : : wr32(hw, TXGBE_TSTIMEINC, 0x0);
4919 : : /* Reset the timesync system time value. */
4920 : : wr32(hw, TXGBE_TSTIMEL, 0x0);
4921 : : wr32(hw, TXGBE_TSTIMEH, 0x0);
4922 : :
4923 : 0 : txgbe_start_timecounters(dev);
4924 : :
4925 : : /* Enable L2 filtering of IEEE1588/802.1AS Ethernet frame types. */
4926 : : wr32(hw, TXGBE_ETFLT(TXGBE_ETF_ID_1588),
4927 : : RTE_ETHER_TYPE_1588 | TXGBE_ETFLT_ENA | TXGBE_ETFLT_1588);
4928 : :
4929 : : /* Enable timestamping of received PTP packets. */
4930 : : tsync_ctl = rd32(hw, TXGBE_TSRXCTL);
4931 : 0 : tsync_ctl |= TXGBE_TSRXCTL_ENA;
4932 : : wr32(hw, TXGBE_TSRXCTL, tsync_ctl);
4933 : :
4934 : : /* Enable timestamping of transmitted PTP packets. */
4935 : : tsync_ctl = rd32(hw, TXGBE_TSTXCTL);
4936 : 0 : tsync_ctl |= TXGBE_TSTXCTL_ENA;
4937 : : wr32(hw, TXGBE_TSTXCTL, tsync_ctl);
4938 : :
4939 : : txgbe_flush(hw);
4940 : :
4941 : 0 : return 0;
4942 : : }
4943 : :
4944 : : static int
4945 : 0 : txgbe_timesync_disable(struct rte_eth_dev *dev)
4946 : : {
4947 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4948 : : uint32_t tsync_ctl;
4949 : :
4950 : : /* Disable timestamping of transmitted PTP packets. */
4951 : : tsync_ctl = rd32(hw, TXGBE_TSTXCTL);
4952 : 0 : tsync_ctl &= ~TXGBE_TSTXCTL_ENA;
4953 : : wr32(hw, TXGBE_TSTXCTL, tsync_ctl);
4954 : :
4955 : : /* Disable timestamping of received PTP packets. */
4956 : : tsync_ctl = rd32(hw, TXGBE_TSRXCTL);
4957 : 0 : tsync_ctl &= ~TXGBE_TSRXCTL_ENA;
4958 : : wr32(hw, TXGBE_TSRXCTL, tsync_ctl);
4959 : :
4960 : : /* Disable L2 filtering of IEEE1588/802.1AS Ethernet frame types. */
4961 : : wr32(hw, TXGBE_ETFLT(TXGBE_ETF_ID_1588), 0);
4962 : :
4963 : : /* Stop incrementing the System Time registers. */
4964 : : wr32(hw, TXGBE_TSTIMEINC, 0);
4965 : :
4966 : 0 : return 0;
4967 : : }
4968 : :
4969 : : static int
4970 : 0 : txgbe_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
4971 : : struct timespec *timestamp,
4972 : : uint32_t flags __rte_unused)
4973 : : {
4974 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4975 : : struct txgbe_adapter *adapter = TXGBE_DEV_ADAPTER(dev);
4976 : : uint32_t tsync_rxctl;
4977 : : uint64_t rx_tstamp_cycles;
4978 : : uint64_t ns;
4979 : :
4980 : : tsync_rxctl = rd32(hw, TXGBE_TSRXCTL);
4981 [ # # ]: 0 : if ((tsync_rxctl & TXGBE_TSRXCTL_VLD) == 0)
4982 : : return -EINVAL;
4983 : :
4984 : : rx_tstamp_cycles = txgbe_read_rx_tstamp_cyclecounter(dev);
4985 : : ns = rte_timecounter_update(&adapter->rx_tstamp_tc, rx_tstamp_cycles);
4986 : 0 : *timestamp = rte_ns_to_timespec(ns);
4987 : :
4988 : 0 : return 0;
4989 : : }
4990 : :
4991 : : static int
4992 : 0 : txgbe_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
4993 : : struct timespec *timestamp)
4994 : : {
4995 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
4996 : : struct txgbe_adapter *adapter = TXGBE_DEV_ADAPTER(dev);
4997 : : uint32_t tsync_txctl;
4998 : : uint64_t tx_tstamp_cycles;
4999 : : uint64_t ns;
5000 : :
5001 : : tsync_txctl = rd32(hw, TXGBE_TSTXCTL);
5002 [ # # ]: 0 : if ((tsync_txctl & TXGBE_TSTXCTL_VLD) == 0)
5003 : : return -EINVAL;
5004 : :
5005 : : tx_tstamp_cycles = txgbe_read_tx_tstamp_cyclecounter(dev);
5006 : : ns = rte_timecounter_update(&adapter->tx_tstamp_tc, tx_tstamp_cycles);
5007 : 0 : *timestamp = rte_ns_to_timespec(ns);
5008 : :
5009 : 0 : return 0;
5010 : : }
5011 : :
5012 : : static int
5013 : : txgbe_get_reg_length(struct rte_eth_dev *dev __rte_unused)
5014 : : {
5015 : : int count = 0;
5016 : : int g_ind = 0;
5017 : : const struct reg_info *reg_group;
5018 : : const struct reg_info **reg_set = txgbe_regs_others;
5019 : :
5020 [ # # # # ]: 0 : while ((reg_group = reg_set[g_ind++]))
5021 : 0 : count += txgbe_regs_group_count(reg_group);
5022 : :
5023 : : return count;
5024 : : }
5025 : :
5026 : : static int
5027 : 0 : txgbe_get_regs(struct rte_eth_dev *dev,
5028 : : struct rte_dev_reg_info *regs)
5029 : : {
5030 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5031 : 0 : uint32_t *data = regs->data;
5032 : : int g_ind = 0;
5033 : : int count = 0;
5034 : : const struct reg_info *reg_group;
5035 : : const struct reg_info **reg_set = txgbe_regs_others;
5036 : :
5037 [ # # ]: 0 : if (data == NULL) {
5038 : 0 : regs->length = txgbe_get_reg_length(dev);
5039 : 0 : regs->width = sizeof(uint32_t);
5040 : 0 : return 0;
5041 : : }
5042 : :
5043 : : /* Support only full register dump */
5044 [ # # ]: 0 : if (regs->length == 0 ||
5045 [ # # ]: 0 : regs->length == (uint32_t)txgbe_get_reg_length(dev)) {
5046 : 0 : regs->version = hw->mac.type << 24 |
5047 : 0 : hw->revision_id << 16 |
5048 : 0 : hw->device_id;
5049 [ # # ]: 0 : while ((reg_group = reg_set[g_ind++]))
5050 : 0 : count += txgbe_read_regs_group(dev, &data[count],
5051 : : reg_group);
5052 : : return 0;
5053 : : }
5054 : :
5055 : : return -ENOTSUP;
5056 : : }
5057 : :
5058 : : static int
5059 : 0 : txgbe_get_eeprom_length(struct rte_eth_dev *dev)
5060 : : {
5061 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5062 : :
5063 : : /* Return unit is byte count */
5064 : 0 : return hw->rom.word_size * 2;
5065 : : }
5066 : :
5067 : : static int
5068 : 0 : txgbe_get_eeprom(struct rte_eth_dev *dev,
5069 : : struct rte_dev_eeprom_info *in_eeprom)
5070 : : {
5071 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5072 : : struct txgbe_rom_info *eeprom = &hw->rom;
5073 : 0 : uint16_t *data = in_eeprom->data;
5074 : : int first, length;
5075 : :
5076 : 0 : first = in_eeprom->offset >> 1;
5077 : 0 : length = in_eeprom->length >> 1;
5078 [ # # ]: 0 : if (first > hw->rom.word_size ||
5079 [ # # ]: 0 : ((first + length) > hw->rom.word_size))
5080 : : return -EINVAL;
5081 : :
5082 : 0 : in_eeprom->magic = hw->vendor_id | (hw->device_id << 16);
5083 : :
5084 : 0 : return eeprom->readw_buffer(hw, first, length, data);
5085 : : }
5086 : :
5087 : : static int
5088 : 0 : txgbe_set_eeprom(struct rte_eth_dev *dev,
5089 : : struct rte_dev_eeprom_info *in_eeprom)
5090 : : {
5091 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5092 : : struct txgbe_rom_info *eeprom = &hw->rom;
5093 : 0 : uint16_t *data = in_eeprom->data;
5094 : : int first, length;
5095 : :
5096 : 0 : first = in_eeprom->offset >> 1;
5097 : 0 : length = in_eeprom->length >> 1;
5098 [ # # ]: 0 : if (first > hw->rom.word_size ||
5099 [ # # ]: 0 : ((first + length) > hw->rom.word_size))
5100 : : return -EINVAL;
5101 : :
5102 : 0 : in_eeprom->magic = hw->vendor_id | (hw->device_id << 16);
5103 : :
5104 : 0 : return eeprom->writew_buffer(hw, first, length, data);
5105 : : }
5106 : :
5107 : : static int
5108 : 0 : txgbe_get_module_info(struct rte_eth_dev *dev,
5109 : : struct rte_eth_dev_module_info *modinfo)
5110 : : {
5111 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5112 : : uint32_t status;
5113 : : uint8_t sff8472_rev, addr_mode;
5114 : : bool page_swap = false;
5115 : :
5116 : : /* Check whether we support SFF-8472 or not */
5117 : 0 : status = hw->phy.read_i2c_eeprom(hw,
5118 : : TXGBE_SFF_SFF_8472_COMP,
5119 : : &sff8472_rev);
5120 [ # # ]: 0 : if (status != 0)
5121 : : return -EIO;
5122 : :
5123 : : /* addressing mode is not supported */
5124 : 0 : status = hw->phy.read_i2c_eeprom(hw,
5125 : : TXGBE_SFF_SFF_8472_SWAP,
5126 : : &addr_mode);
5127 [ # # ]: 0 : if (status != 0)
5128 : : return -EIO;
5129 : :
5130 [ # # ]: 0 : if (addr_mode & TXGBE_SFF_ADDRESSING_MODE) {
5131 : 0 : PMD_DRV_LOG(ERR,
5132 : : "Address change required to access page 0xA2, "
5133 : : "but not supported. Please report the module "
5134 : : "type to the driver maintainers.");
5135 : : page_swap = true;
5136 : : }
5137 : :
5138 [ # # # # ]: 0 : if (sff8472_rev == TXGBE_SFF_SFF_8472_UNSUP || page_swap) {
5139 : : /* We have a SFP, but it does not support SFF-8472 */
5140 : 0 : modinfo->type = RTE_ETH_MODULE_SFF_8079;
5141 : 0 : modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8079_LEN;
5142 : : } else {
5143 : : /* We have a SFP which supports a revision of SFF-8472. */
5144 : 0 : modinfo->type = RTE_ETH_MODULE_SFF_8472;
5145 : 0 : modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN;
5146 : : }
5147 : :
5148 : : return 0;
5149 : : }
5150 : :
5151 : : static int
5152 : 0 : txgbe_get_module_eeprom(struct rte_eth_dev *dev,
5153 : : struct rte_dev_eeprom_info *info)
5154 : : {
5155 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5156 : : uint32_t status = TXGBE_ERR_PHY_ADDR_INVALID;
5157 : 0 : uint8_t databyte = 0xFF;
5158 : 0 : uint8_t *data = info->data;
5159 : : uint32_t i = 0;
5160 : :
5161 [ # # ]: 0 : if (info->length == 0)
5162 : : return -EINVAL;
5163 : :
5164 [ # # ]: 0 : for (i = info->offset; i < info->offset + info->length; i++) {
5165 [ # # ]: 0 : if (i < RTE_ETH_MODULE_SFF_8079_LEN)
5166 : 0 : status = hw->phy.read_i2c_eeprom(hw, i, &databyte);
5167 : : else
5168 : 0 : status = hw->phy.read_i2c_sff8472(hw, i, &databyte);
5169 : :
5170 [ # # ]: 0 : if (status != 0)
5171 : : return -EIO;
5172 : :
5173 : 0 : data[i - info->offset] = databyte;
5174 : : }
5175 : :
5176 : : return 0;
5177 : : }
5178 : :
5179 : : bool
5180 : 0 : txgbe_rss_update(enum txgbe_mac_type mac_type)
5181 : : {
5182 [ # # ]: 0 : switch (mac_type) {
5183 : : case txgbe_mac_sp:
5184 : : case txgbe_mac_sp_vf:
5185 : : case txgbe_mac_aml:
5186 : : case txgbe_mac_aml40:
5187 : : case txgbe_mac_aml_vf:
5188 : : return 1;
5189 : 0 : default:
5190 : 0 : return 0;
5191 : : }
5192 : : }
5193 : :
5194 : : static int
5195 : 0 : txgbe_dev_get_dcb_info(struct rte_eth_dev *dev,
5196 : : struct rte_eth_dcb_info *dcb_info)
5197 : : {
5198 : 0 : struct txgbe_dcb_config *dcb_config = TXGBE_DEV_DCB_CONFIG(dev);
5199 : : struct txgbe_dcb_tc_config *tc;
5200 : : struct rte_eth_dcb_tc_queue_mapping *tc_queue;
5201 : : uint8_t nb_tcs;
5202 : : uint8_t i, j;
5203 : :
5204 [ # # ]: 0 : if (dev->data->dev_conf.rxmode.mq_mode & RTE_ETH_MQ_RX_DCB_FLAG)
5205 : 0 : dcb_info->nb_tcs = dcb_config->num_tcs.pg_tcs;
5206 : : else
5207 : 0 : dcb_info->nb_tcs = 1;
5208 : :
5209 : : tc_queue = &dcb_info->tc_queue;
5210 : 0 : nb_tcs = dcb_info->nb_tcs;
5211 : :
5212 [ # # ]: 0 : if (dcb_config->vt_mode) { /* vt is enabled */
5213 : : struct rte_eth_vmdq_dcb_conf *vmdq_rx_conf =
5214 : : &dev->data->dev_conf.rx_adv_conf.vmdq_dcb_conf;
5215 [ # # ]: 0 : for (i = 0; i < RTE_ETH_DCB_NUM_USER_PRIORITIES; i++)
5216 : 0 : dcb_info->prio_tc[i] = vmdq_rx_conf->dcb_tc[i];
5217 [ # # ]: 0 : if (RTE_ETH_DEV_SRIOV(dev).active > 0) {
5218 [ # # ]: 0 : for (j = 0; j < nb_tcs; j++) {
5219 : 0 : tc_queue->tc_rxq[0][j].base = j;
5220 : 0 : tc_queue->tc_rxq[0][j].nb_queue = 1;
5221 : 0 : tc_queue->tc_txq[0][j].base = j;
5222 : 0 : tc_queue->tc_txq[0][j].nb_queue = 1;
5223 : : }
5224 : : } else {
5225 [ # # ]: 0 : for (i = 0; i < vmdq_rx_conf->nb_queue_pools; i++) {
5226 [ # # ]: 0 : for (j = 0; j < nb_tcs; j++) {
5227 : 0 : tc_queue->tc_rxq[i][j].base =
5228 : 0 : i * nb_tcs + j;
5229 : 0 : tc_queue->tc_rxq[i][j].nb_queue = 1;
5230 : 0 : tc_queue->tc_txq[i][j].base =
5231 : : i * nb_tcs + j;
5232 : 0 : tc_queue->tc_txq[i][j].nb_queue = 1;
5233 : : }
5234 : : }
5235 : : }
5236 : : } else { /* vt is disabled */
5237 : : struct rte_eth_dcb_rx_conf *rx_conf =
5238 : : &dev->data->dev_conf.rx_adv_conf.dcb_rx_conf;
5239 [ # # ]: 0 : for (i = 0; i < RTE_ETH_DCB_NUM_USER_PRIORITIES; i++)
5240 : 0 : dcb_info->prio_tc[i] = rx_conf->dcb_tc[i];
5241 [ # # ]: 0 : if (dcb_info->nb_tcs == RTE_ETH_4_TCS) {
5242 [ # # ]: 0 : for (i = 0; i < dcb_info->nb_tcs; i++) {
5243 : 0 : dcb_info->tc_queue.tc_rxq[0][i].base = i * 32;
5244 : 0 : dcb_info->tc_queue.tc_rxq[0][i].nb_queue = 16;
5245 : : }
5246 : 0 : dcb_info->tc_queue.tc_txq[0][0].base = 0;
5247 : 0 : dcb_info->tc_queue.tc_txq[0][1].base = 64;
5248 : 0 : dcb_info->tc_queue.tc_txq[0][2].base = 96;
5249 : 0 : dcb_info->tc_queue.tc_txq[0][3].base = 112;
5250 : 0 : dcb_info->tc_queue.tc_txq[0][0].nb_queue = 64;
5251 : 0 : dcb_info->tc_queue.tc_txq[0][1].nb_queue = 32;
5252 : 0 : dcb_info->tc_queue.tc_txq[0][2].nb_queue = 16;
5253 : 0 : dcb_info->tc_queue.tc_txq[0][3].nb_queue = 16;
5254 [ # # ]: 0 : } else if (dcb_info->nb_tcs == RTE_ETH_8_TCS) {
5255 [ # # ]: 0 : for (i = 0; i < dcb_info->nb_tcs; i++) {
5256 : 0 : dcb_info->tc_queue.tc_rxq[0][i].base = i * 16;
5257 : 0 : dcb_info->tc_queue.tc_rxq[0][i].nb_queue = 16;
5258 : : }
5259 : 0 : dcb_info->tc_queue.tc_txq[0][0].base = 0;
5260 : 0 : dcb_info->tc_queue.tc_txq[0][1].base = 32;
5261 : 0 : dcb_info->tc_queue.tc_txq[0][2].base = 64;
5262 : 0 : dcb_info->tc_queue.tc_txq[0][3].base = 80;
5263 : 0 : dcb_info->tc_queue.tc_txq[0][4].base = 96;
5264 : 0 : dcb_info->tc_queue.tc_txq[0][5].base = 104;
5265 : 0 : dcb_info->tc_queue.tc_txq[0][6].base = 112;
5266 : 0 : dcb_info->tc_queue.tc_txq[0][7].base = 120;
5267 : 0 : dcb_info->tc_queue.tc_txq[0][0].nb_queue = 32;
5268 : 0 : dcb_info->tc_queue.tc_txq[0][1].nb_queue = 32;
5269 : 0 : dcb_info->tc_queue.tc_txq[0][2].nb_queue = 16;
5270 : 0 : dcb_info->tc_queue.tc_txq[0][3].nb_queue = 16;
5271 : 0 : dcb_info->tc_queue.tc_txq[0][4].nb_queue = 8;
5272 : 0 : dcb_info->tc_queue.tc_txq[0][5].nb_queue = 8;
5273 : 0 : dcb_info->tc_queue.tc_txq[0][6].nb_queue = 8;
5274 : 0 : dcb_info->tc_queue.tc_txq[0][7].nb_queue = 8;
5275 : : }
5276 : : }
5277 [ # # ]: 0 : for (i = 0; i < dcb_info->nb_tcs; i++) {
5278 : 0 : tc = &dcb_config->tc_config[i];
5279 : 0 : dcb_info->tc_bws[i] = tc->path[TXGBE_DCB_TX_CONFIG].bwg_percent;
5280 : : }
5281 : 0 : return 0;
5282 : : }
5283 : :
5284 : : /* Update e-tag ether type */
5285 : : static int
5286 : 0 : txgbe_update_e_tag_eth_type(struct txgbe_hw *hw,
5287 : : uint16_t ether_type)
5288 : : {
5289 : : uint32_t etag_etype;
5290 : :
5291 : : etag_etype = rd32(hw, TXGBE_EXTAG);
5292 : 0 : etag_etype &= ~TXGBE_EXTAG_ETAG_MASK;
5293 : 0 : etag_etype |= ether_type;
5294 : : wr32(hw, TXGBE_EXTAG, etag_etype);
5295 : : txgbe_flush(hw);
5296 : :
5297 : 0 : return 0;
5298 : : }
5299 : :
5300 : : /* Enable e-tag tunnel */
5301 : : static int
5302 : 0 : txgbe_e_tag_enable(struct txgbe_hw *hw)
5303 : : {
5304 : : uint32_t etag_etype;
5305 : :
5306 : : etag_etype = rd32(hw, TXGBE_PORTCTL);
5307 : 0 : etag_etype |= TXGBE_PORTCTL_ETAG;
5308 : : wr32(hw, TXGBE_PORTCTL, etag_etype);
5309 : : txgbe_flush(hw);
5310 : :
5311 : 0 : return 0;
5312 : : }
5313 : :
5314 : : static int
5315 : 0 : txgbe_e_tag_filter_del(struct rte_eth_dev *dev,
5316 : : struct txgbe_l2_tunnel_conf *l2_tunnel)
5317 : : {
5318 : : int ret = 0;
5319 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5320 : : uint32_t i, rar_entries;
5321 : : uint32_t rar_low, rar_high;
5322 : :
5323 : 0 : rar_entries = hw->mac.num_rar_entries;
5324 : :
5325 [ # # ]: 0 : for (i = 1; i < rar_entries; i++) {
5326 : : wr32(hw, TXGBE_ETHADDRIDX, i);
5327 : : rar_high = rd32(hw, TXGBE_ETHADDRH);
5328 : : rar_low = rd32(hw, TXGBE_ETHADDRL);
5329 [ # # ]: 0 : if ((rar_high & TXGBE_ETHADDRH_VLD) &&
5330 [ # # ]: 0 : (rar_high & TXGBE_ETHADDRH_ETAG) &&
5331 : 0 : (TXGBE_ETHADDRL_ETAG(rar_low) ==
5332 [ # # ]: 0 : l2_tunnel->tunnel_id)) {
5333 : : wr32(hw, TXGBE_ETHADDRL, 0);
5334 : : wr32(hw, TXGBE_ETHADDRH, 0);
5335 : :
5336 : 0 : txgbe_clear_vmdq(hw, i, BIT_MASK32);
5337 : :
5338 : 0 : return ret;
5339 : : }
5340 : : }
5341 : :
5342 : : return ret;
5343 : : }
5344 : :
5345 : : static int
5346 : 0 : txgbe_e_tag_filter_add(struct rte_eth_dev *dev,
5347 : : struct txgbe_l2_tunnel_conf *l2_tunnel)
5348 : : {
5349 : : int ret = 0;
5350 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5351 : : uint32_t i, rar_entries;
5352 : : uint32_t rar_low, rar_high;
5353 : :
5354 : : /* One entry for one tunnel. Try to remove potential existing entry. */
5355 : 0 : txgbe_e_tag_filter_del(dev, l2_tunnel);
5356 : :
5357 : 0 : rar_entries = hw->mac.num_rar_entries;
5358 : :
5359 [ # # ]: 0 : for (i = 1; i < rar_entries; i++) {
5360 : : wr32(hw, TXGBE_ETHADDRIDX, i);
5361 : : rar_high = rd32(hw, TXGBE_ETHADDRH);
5362 [ # # ]: 0 : if (rar_high & TXGBE_ETHADDRH_VLD) {
5363 : : continue;
5364 : : } else {
5365 : 0 : txgbe_set_vmdq(hw, i, l2_tunnel->pool);
5366 : : rar_high = TXGBE_ETHADDRH_VLD | TXGBE_ETHADDRH_ETAG;
5367 : 0 : rar_low = l2_tunnel->tunnel_id;
5368 : :
5369 : : wr32(hw, TXGBE_ETHADDRL, rar_low);
5370 : : wr32(hw, TXGBE_ETHADDRH, rar_high);
5371 : :
5372 : 0 : return ret;
5373 : : }
5374 : : }
5375 : :
5376 : 0 : PMD_INIT_LOG(NOTICE, "The table of E-tag forwarding rule is full."
5377 : : " Please remove a rule before adding a new one.");
5378 : 0 : return -EINVAL;
5379 : : }
5380 : :
5381 : : static inline struct txgbe_l2_tn_filter *
5382 : : txgbe_l2_tn_filter_lookup(struct txgbe_l2_tn_info *l2_tn_info,
5383 : : struct txgbe_l2_tn_key *key)
5384 : : {
5385 : : int ret;
5386 : :
5387 : 0 : ret = rte_hash_lookup(l2_tn_info->hash_handle, (const void *)key);
5388 [ # # ]: 0 : if (ret < 0)
5389 : : return NULL;
5390 : :
5391 : 0 : return l2_tn_info->hash_map[ret];
5392 : : }
5393 : :
5394 : : static inline int
5395 : 0 : txgbe_insert_l2_tn_filter(struct txgbe_l2_tn_info *l2_tn_info,
5396 : : struct txgbe_l2_tn_filter *l2_tn_filter)
5397 : : {
5398 : : int ret;
5399 : :
5400 : 0 : ret = rte_hash_add_key(l2_tn_info->hash_handle,
5401 : 0 : &l2_tn_filter->key);
5402 : :
5403 [ # # ]: 0 : if (ret < 0) {
5404 : 0 : PMD_DRV_LOG(ERR,
5405 : : "Failed to insert L2 tunnel filter"
5406 : : " to hash table %d!",
5407 : : ret);
5408 : 0 : return ret;
5409 : : }
5410 : :
5411 : 0 : l2_tn_info->hash_map[ret] = l2_tn_filter;
5412 : :
5413 : 0 : TAILQ_INSERT_TAIL(&l2_tn_info->l2_tn_list, l2_tn_filter, entries);
5414 : :
5415 : 0 : return 0;
5416 : : }
5417 : :
5418 : : static inline int
5419 : 0 : txgbe_remove_l2_tn_filter(struct txgbe_l2_tn_info *l2_tn_info,
5420 : : struct txgbe_l2_tn_key *key)
5421 : : {
5422 : : int ret;
5423 : : struct txgbe_l2_tn_filter *l2_tn_filter;
5424 : :
5425 : 0 : ret = rte_hash_del_key(l2_tn_info->hash_handle, key);
5426 : :
5427 [ # # ]: 0 : if (ret < 0) {
5428 : 0 : PMD_DRV_LOG(ERR,
5429 : : "No such L2 tunnel filter to delete %d!",
5430 : : ret);
5431 : 0 : return ret;
5432 : : }
5433 : :
5434 : 0 : l2_tn_filter = l2_tn_info->hash_map[ret];
5435 : 0 : l2_tn_info->hash_map[ret] = NULL;
5436 : :
5437 [ # # ]: 0 : TAILQ_REMOVE(&l2_tn_info->l2_tn_list, l2_tn_filter, entries);
5438 : 0 : rte_free(l2_tn_filter);
5439 : :
5440 : 0 : return 0;
5441 : : }
5442 : :
5443 : : /* Add l2 tunnel filter */
5444 : : int
5445 : 0 : txgbe_dev_l2_tunnel_filter_add(struct rte_eth_dev *dev,
5446 : : struct txgbe_l2_tunnel_conf *l2_tunnel,
5447 : : bool restore)
5448 : : {
5449 : : int ret;
5450 : 0 : struct txgbe_l2_tn_info *l2_tn_info = TXGBE_DEV_L2_TN(dev);
5451 : : struct txgbe_l2_tn_key key;
5452 : : struct txgbe_l2_tn_filter *node;
5453 : :
5454 [ # # ]: 0 : if (!restore) {
5455 : 0 : key.l2_tn_type = l2_tunnel->l2_tunnel_type;
5456 : 0 : key.tn_id = l2_tunnel->tunnel_id;
5457 : :
5458 : : node = txgbe_l2_tn_filter_lookup(l2_tn_info, &key);
5459 : :
5460 [ # # ]: 0 : if (node) {
5461 : 0 : PMD_DRV_LOG(ERR,
5462 : : "The L2 tunnel filter already exists!");
5463 : 0 : return -EINVAL;
5464 : : }
5465 : :
5466 : 0 : node = rte_zmalloc("txgbe_l2_tn",
5467 : : sizeof(struct txgbe_l2_tn_filter),
5468 : : 0);
5469 [ # # ]: 0 : if (!node)
5470 : : return -ENOMEM;
5471 : :
5472 [ # # ]: 0 : rte_memcpy(&node->key,
5473 : : &key,
5474 : : sizeof(struct txgbe_l2_tn_key));
5475 : 0 : node->pool = l2_tunnel->pool;
5476 : 0 : ret = txgbe_insert_l2_tn_filter(l2_tn_info, node);
5477 [ # # ]: 0 : if (ret < 0) {
5478 : 0 : rte_free(node);
5479 : 0 : return ret;
5480 : : }
5481 : : }
5482 : :
5483 [ # # ]: 0 : switch (l2_tunnel->l2_tunnel_type) {
5484 : 0 : case RTE_ETH_L2_TUNNEL_TYPE_E_TAG:
5485 : 0 : ret = txgbe_e_tag_filter_add(dev, l2_tunnel);
5486 : 0 : break;
5487 : 0 : default:
5488 : 0 : PMD_DRV_LOG(ERR, "Invalid tunnel type");
5489 : : ret = -EINVAL;
5490 : 0 : break;
5491 : : }
5492 : :
5493 [ # # ]: 0 : if (!restore && ret < 0)
5494 : 0 : (void)txgbe_remove_l2_tn_filter(l2_tn_info, &key);
5495 : :
5496 : : return ret;
5497 : : }
5498 : :
5499 : : /* Delete l2 tunnel filter */
5500 : : int
5501 : 0 : txgbe_dev_l2_tunnel_filter_del(struct rte_eth_dev *dev,
5502 : : struct txgbe_l2_tunnel_conf *l2_tunnel)
5503 : : {
5504 : : int ret;
5505 : 0 : struct txgbe_l2_tn_info *l2_tn_info = TXGBE_DEV_L2_TN(dev);
5506 : : struct txgbe_l2_tn_key key;
5507 : :
5508 : 0 : key.l2_tn_type = l2_tunnel->l2_tunnel_type;
5509 : 0 : key.tn_id = l2_tunnel->tunnel_id;
5510 : 0 : ret = txgbe_remove_l2_tn_filter(l2_tn_info, &key);
5511 [ # # ]: 0 : if (ret < 0)
5512 : : return ret;
5513 : :
5514 [ # # ]: 0 : switch (l2_tunnel->l2_tunnel_type) {
5515 : 0 : case RTE_ETH_L2_TUNNEL_TYPE_E_TAG:
5516 : 0 : ret = txgbe_e_tag_filter_del(dev, l2_tunnel);
5517 : 0 : break;
5518 : 0 : default:
5519 : 0 : PMD_DRV_LOG(ERR, "Invalid tunnel type");
5520 : : ret = -EINVAL;
5521 : 0 : break;
5522 : : }
5523 : :
5524 : : return ret;
5525 : : }
5526 : :
5527 : : static int
5528 : : txgbe_e_tag_forwarding_en_dis(struct rte_eth_dev *dev, bool en)
5529 : : {
5530 : : int ret = 0;
5531 : : uint32_t ctrl;
5532 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5533 : :
5534 : : ctrl = rd32(hw, TXGBE_POOLCTL);
5535 : 0 : ctrl &= ~TXGBE_POOLCTL_MODE_MASK;
5536 : : if (en)
5537 : 0 : ctrl |= TXGBE_PSRPOOL_MODE_ETAG;
5538 : : wr32(hw, TXGBE_POOLCTL, ctrl);
5539 : :
5540 : 0 : return ret;
5541 : : }
5542 : :
5543 : : /* Add UDP tunneling port */
5544 : : static int
5545 : 0 : txgbe_dev_udp_tunnel_port_add(struct rte_eth_dev *dev,
5546 : : struct rte_eth_udp_tunnel *udp_tunnel)
5547 : : {
5548 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5549 : : int ret = 0;
5550 : :
5551 [ # # ]: 0 : if (udp_tunnel == NULL)
5552 : : return -EINVAL;
5553 : :
5554 [ # # # # : 0 : switch (udp_tunnel->prot_type) {
# ]
5555 : 0 : case RTE_ETH_TUNNEL_TYPE_VXLAN:
5556 [ # # ]: 0 : if (udp_tunnel->udp_port == 0) {
5557 : 0 : PMD_DRV_LOG(ERR, "Add VxLAN port 0 is not allowed.");
5558 : : ret = -EINVAL;
5559 : 0 : break;
5560 : : }
5561 : 0 : wr32(hw, TXGBE_VXLANPORT, udp_tunnel->udp_port);
5562 : : break;
5563 : 0 : case RTE_ETH_TUNNEL_TYPE_GENEVE:
5564 [ # # ]: 0 : if (udp_tunnel->udp_port == 0) {
5565 : 0 : PMD_DRV_LOG(ERR, "Add Geneve port 0 is not allowed.");
5566 : : ret = -EINVAL;
5567 : 0 : break;
5568 : : }
5569 : 0 : wr32(hw, TXGBE_GENEVEPORT, udp_tunnel->udp_port);
5570 : : break;
5571 : 0 : case RTE_ETH_TUNNEL_TYPE_TEREDO:
5572 [ # # ]: 0 : if (udp_tunnel->udp_port == 0) {
5573 : 0 : PMD_DRV_LOG(ERR, "Add Teredo port 0 is not allowed.");
5574 : : ret = -EINVAL;
5575 : 0 : break;
5576 : : }
5577 : 0 : wr32(hw, TXGBE_TEREDOPORT, udp_tunnel->udp_port);
5578 : : break;
5579 : 0 : case RTE_ETH_TUNNEL_TYPE_VXLAN_GPE:
5580 [ # # ]: 0 : if (udp_tunnel->udp_port == 0) {
5581 : 0 : PMD_DRV_LOG(ERR, "Add VxLAN port 0 is not allowed.");
5582 : : ret = -EINVAL;
5583 : 0 : break;
5584 : : }
5585 : 0 : wr32(hw, TXGBE_VXLANPORTGPE, udp_tunnel->udp_port);
5586 : : break;
5587 : 0 : default:
5588 : 0 : PMD_DRV_LOG(ERR, "Invalid tunnel type");
5589 : : ret = -EINVAL;
5590 : 0 : break;
5591 : : }
5592 : :
5593 : : txgbe_flush(hw);
5594 : :
5595 : : return ret;
5596 : : }
5597 : :
5598 : : /* Remove UDP tunneling port */
5599 : : static int
5600 : 0 : txgbe_dev_udp_tunnel_port_del(struct rte_eth_dev *dev,
5601 : : struct rte_eth_udp_tunnel *udp_tunnel)
5602 : : {
5603 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5604 : : int ret = 0;
5605 : : uint16_t cur_port;
5606 : :
5607 [ # # ]: 0 : if (udp_tunnel == NULL)
5608 : : return -EINVAL;
5609 : :
5610 [ # # # # : 0 : switch (udp_tunnel->prot_type) {
# ]
5611 : : case RTE_ETH_TUNNEL_TYPE_VXLAN:
5612 : 0 : cur_port = (uint16_t)rd32(hw, TXGBE_VXLANPORT);
5613 [ # # ]: 0 : if (cur_port != udp_tunnel->udp_port) {
5614 : 0 : PMD_DRV_LOG(ERR, "Port %u does not exist.",
5615 : : udp_tunnel->udp_port);
5616 : : ret = -EINVAL;
5617 : 0 : break;
5618 : : }
5619 : : wr32(hw, TXGBE_VXLANPORT, 0);
5620 : : break;
5621 : : case RTE_ETH_TUNNEL_TYPE_GENEVE:
5622 : 0 : cur_port = (uint16_t)rd32(hw, TXGBE_GENEVEPORT);
5623 [ # # ]: 0 : if (cur_port != udp_tunnel->udp_port) {
5624 : 0 : PMD_DRV_LOG(ERR, "Port %u does not exist.",
5625 : : udp_tunnel->udp_port);
5626 : : ret = -EINVAL;
5627 : 0 : break;
5628 : : }
5629 : : wr32(hw, TXGBE_GENEVEPORT, 0);
5630 : : break;
5631 : : case RTE_ETH_TUNNEL_TYPE_TEREDO:
5632 : 0 : cur_port = (uint16_t)rd32(hw, TXGBE_TEREDOPORT);
5633 [ # # ]: 0 : if (cur_port != udp_tunnel->udp_port) {
5634 : 0 : PMD_DRV_LOG(ERR, "Port %u does not exist.",
5635 : : udp_tunnel->udp_port);
5636 : : ret = -EINVAL;
5637 : 0 : break;
5638 : : }
5639 : : wr32(hw, TXGBE_TEREDOPORT, 0);
5640 : : break;
5641 : : case RTE_ETH_TUNNEL_TYPE_VXLAN_GPE:
5642 : 0 : cur_port = (uint16_t)rd32(hw, TXGBE_VXLANPORTGPE);
5643 [ # # ]: 0 : if (cur_port != udp_tunnel->udp_port) {
5644 : 0 : PMD_DRV_LOG(ERR, "Port %u does not exist.",
5645 : : udp_tunnel->udp_port);
5646 : : ret = -EINVAL;
5647 : 0 : break;
5648 : : }
5649 : : wr32(hw, TXGBE_VXLANPORTGPE, 0);
5650 : : break;
5651 : 0 : default:
5652 : 0 : PMD_DRV_LOG(ERR, "Invalid tunnel type");
5653 : : ret = -EINVAL;
5654 : 0 : break;
5655 : : }
5656 : :
5657 : : txgbe_flush(hw);
5658 : :
5659 : : return ret;
5660 : : }
5661 : :
5662 : : /* restore n-tuple filter */
5663 : : static inline void
5664 : : txgbe_ntuple_filter_restore(struct rte_eth_dev *dev)
5665 : : {
5666 : 0 : struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
5667 : : struct txgbe_5tuple_filter *node;
5668 : :
5669 [ # # ]: 0 : TAILQ_FOREACH(node, &filter_info->fivetuple_list, entries) {
5670 : 0 : txgbe_inject_5tuple_filter(dev, node);
5671 : : }
5672 : : }
5673 : :
5674 : : /* restore ethernet type filter */
5675 : : static inline void
5676 : 0 : txgbe_ethertype_filter_restore(struct rte_eth_dev *dev)
5677 : : {
5678 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5679 : : struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
5680 : : int i;
5681 : :
5682 [ # # ]: 0 : for (i = 0; i < TXGBE_ETF_ID_MAX; i++) {
5683 [ # # ]: 0 : if (filter_info->ethertype_mask & (1 << i)) {
5684 : 0 : wr32(hw, TXGBE_ETFLT(i),
5685 : : filter_info->ethertype_filters[i].etqf);
5686 : 0 : wr32(hw, TXGBE_ETCLS(i),
5687 : : filter_info->ethertype_filters[i].etqs);
5688 : : txgbe_flush(hw);
5689 : : }
5690 : : }
5691 : 0 : }
5692 : :
5693 : : /* restore SYN filter */
5694 : : static inline void
5695 : 0 : txgbe_syn_filter_restore(struct rte_eth_dev *dev)
5696 : : {
5697 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5698 : : struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
5699 : : uint32_t synqf;
5700 : :
5701 : 0 : synqf = filter_info->syn_info;
5702 : :
5703 [ # # ]: 0 : if (synqf & TXGBE_SYNCLS_ENA) {
5704 : : wr32(hw, TXGBE_SYNCLS, synqf);
5705 : : txgbe_flush(hw);
5706 : : }
5707 : 0 : }
5708 : :
5709 : : /* restore L2 tunnel filter */
5710 : : static inline void
5711 : 0 : txgbe_l2_tn_filter_restore(struct rte_eth_dev *dev)
5712 : : {
5713 : 0 : struct txgbe_l2_tn_info *l2_tn_info = TXGBE_DEV_L2_TN(dev);
5714 : : struct txgbe_l2_tn_filter *node;
5715 : : struct txgbe_l2_tunnel_conf l2_tn_conf;
5716 : :
5717 [ # # ]: 0 : TAILQ_FOREACH(node, &l2_tn_info->l2_tn_list, entries) {
5718 : 0 : l2_tn_conf.l2_tunnel_type = node->key.l2_tn_type;
5719 : 0 : l2_tn_conf.tunnel_id = node->key.tn_id;
5720 : 0 : l2_tn_conf.pool = node->pool;
5721 : 0 : (void)txgbe_dev_l2_tunnel_filter_add(dev, &l2_tn_conf, TRUE);
5722 : : }
5723 : 0 : }
5724 : :
5725 : : /* restore rss filter */
5726 : : static inline void
5727 : : txgbe_rss_filter_restore(struct rte_eth_dev *dev)
5728 : : {
5729 : 0 : struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
5730 : :
5731 [ # # ]: 0 : if (filter_info->rss_info.conf.queue_num)
5732 : 0 : txgbe_config_rss_filter(dev,
5733 : : &filter_info->rss_info, TRUE);
5734 : : }
5735 : :
5736 : : static int
5737 : 0 : txgbe_filter_restore(struct rte_eth_dev *dev)
5738 : : {
5739 : : txgbe_ntuple_filter_restore(dev);
5740 : 0 : txgbe_ethertype_filter_restore(dev);
5741 : 0 : txgbe_syn_filter_restore(dev);
5742 : 0 : txgbe_fdir_filter_restore(dev);
5743 : 0 : txgbe_l2_tn_filter_restore(dev);
5744 : : txgbe_rss_filter_restore(dev);
5745 : :
5746 : 0 : return 0;
5747 : : }
5748 : :
5749 : : static void
5750 : 0 : txgbe_l2_tunnel_conf(struct rte_eth_dev *dev)
5751 : : {
5752 : 0 : struct txgbe_l2_tn_info *l2_tn_info = TXGBE_DEV_L2_TN(dev);
5753 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5754 : :
5755 [ # # ]: 0 : if (l2_tn_info->e_tag_en)
5756 : 0 : (void)txgbe_e_tag_enable(hw);
5757 : :
5758 [ # # ]: 0 : if (l2_tn_info->e_tag_fwd_en)
5759 : : (void)txgbe_e_tag_forwarding_en_dis(dev, 1);
5760 : :
5761 : 0 : (void)txgbe_update_e_tag_eth_type(hw, l2_tn_info->e_tag_ether_type);
5762 : 0 : }
5763 : :
5764 : : /* remove all the n-tuple filters */
5765 : : void
5766 : 0 : txgbe_clear_all_ntuple_filter(struct rte_eth_dev *dev)
5767 : : {
5768 : 0 : struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
5769 : : struct txgbe_5tuple_filter *p_5tuple;
5770 : :
5771 [ # # ]: 0 : while ((p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list)))
5772 : 0 : txgbe_remove_5tuple_filter(dev, p_5tuple);
5773 : 0 : }
5774 : :
5775 : : /* remove all the ether type filters */
5776 : : void
5777 : 0 : txgbe_clear_all_ethertype_filter(struct rte_eth_dev *dev)
5778 : : {
5779 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5780 : : struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
5781 : : int i;
5782 : :
5783 [ # # ]: 0 : for (i = 0; i < TXGBE_ETF_ID_MAX; i++) {
5784 [ # # ]: 0 : if (filter_info->ethertype_mask & (1 << i) &&
5785 [ # # ]: 0 : !filter_info->ethertype_filters[i].conf) {
5786 : : (void)txgbe_ethertype_filter_remove(filter_info,
5787 : : (uint8_t)i);
5788 : 0 : wr32(hw, TXGBE_ETFLT(i), 0);
5789 : 0 : wr32(hw, TXGBE_ETCLS(i), 0);
5790 : : txgbe_flush(hw);
5791 : : }
5792 : : }
5793 : 0 : }
5794 : :
5795 : : /* remove the SYN filter */
5796 : : void
5797 : 0 : txgbe_clear_syn_filter(struct rte_eth_dev *dev)
5798 : : {
5799 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5800 : : struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
5801 : :
5802 [ # # ]: 0 : if (filter_info->syn_info & TXGBE_SYNCLS_ENA) {
5803 : 0 : filter_info->syn_info = 0;
5804 : :
5805 : : wr32(hw, TXGBE_SYNCLS, 0);
5806 : : txgbe_flush(hw);
5807 : : }
5808 : 0 : }
5809 : :
5810 : : /* remove all the L2 tunnel filters */
5811 : : int
5812 : 0 : txgbe_clear_all_l2_tn_filter(struct rte_eth_dev *dev)
5813 : : {
5814 : 0 : struct txgbe_l2_tn_info *l2_tn_info = TXGBE_DEV_L2_TN(dev);
5815 : : struct txgbe_l2_tn_filter *l2_tn_filter;
5816 : : struct txgbe_l2_tunnel_conf l2_tn_conf;
5817 : : int ret = 0;
5818 : :
5819 [ # # ]: 0 : while ((l2_tn_filter = TAILQ_FIRST(&l2_tn_info->l2_tn_list))) {
5820 : 0 : l2_tn_conf.l2_tunnel_type = l2_tn_filter->key.l2_tn_type;
5821 : 0 : l2_tn_conf.tunnel_id = l2_tn_filter->key.tn_id;
5822 : 0 : l2_tn_conf.pool = l2_tn_filter->pool;
5823 : 0 : ret = txgbe_dev_l2_tunnel_filter_del(dev, &l2_tn_conf);
5824 [ # # ]: 0 : if (ret < 0)
5825 : 0 : return ret;
5826 : : }
5827 : :
5828 : : return 0;
5829 : : }
5830 : :
5831 : : static int txgbe_fec_get_capa_speed_to_fec(struct rte_eth_fec_capa *speed_fec_capa)
5832 : : {
5833 : : int num = 2;
5834 : :
5835 : : if (speed_fec_capa) {
5836 : 0 : speed_fec_capa[0].speed = RTE_ETH_SPEED_NUM_10G;
5837 : 0 : speed_fec_capa[0].capa = RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC);
5838 : 0 : speed_fec_capa[1].speed = RTE_ETH_SPEED_NUM_25G;
5839 : 0 : speed_fec_capa[1].capa = RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
5840 : : RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) |
5841 : : RTE_ETH_FEC_MODE_CAPA_MASK(BASER) |
5842 : : RTE_ETH_FEC_MODE_CAPA_MASK(RS);
5843 : : }
5844 : :
5845 : : return num;
5846 : : }
5847 : :
5848 : 0 : static int txgbe_fec_get_capability(struct rte_eth_dev *dev,
5849 : : struct rte_eth_fec_capa *speed_fec_capa,
5850 : : unsigned int num)
5851 : : {
5852 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5853 : : u8 num_entries;
5854 : :
5855 [ # # ]: 0 : if (hw->mac.type != txgbe_mac_aml)
5856 : : return -EOPNOTSUPP;
5857 : :
5858 : : num_entries = txgbe_fec_get_capa_speed_to_fec(NULL);
5859 [ # # # # ]: 0 : if (!speed_fec_capa || num < num_entries)
5860 : : return num_entries;
5861 : :
5862 : 0 : return txgbe_fec_get_capa_speed_to_fec(speed_fec_capa);
5863 : : }
5864 : :
5865 : 0 : static int txgbe_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa)
5866 : : {
5867 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5868 : 0 : u32 speed = 0;
5869 : 0 : bool negotiate = false;
5870 : : u32 curr_fec_mode;
5871 : :
5872 : 0 : hw->mac.get_link_capabilities(hw, &speed, &negotiate);
5873 : :
5874 [ # # ]: 0 : if (hw->mac.type != txgbe_mac_aml ||
5875 [ # # ]: 0 : !(speed & TXGBE_LINK_SPEED_25GB_FULL))
5876 : : return -EOPNOTSUPP;
5877 : :
5878 [ # # ]: 0 : if (hw->fec_mode == TXGBE_PHY_FEC_AUTO)
5879 : : curr_fec_mode = RTE_ETH_FEC_MODE_CAPA_MASK(AUTO);
5880 [ # # ]: 0 : else if (hw->fec_mode == TXGBE_PHY_FEC_RS)
5881 : : curr_fec_mode = RTE_ETH_FEC_MODE_CAPA_MASK(RS);
5882 [ # # ]: 0 : else if (hw->fec_mode == TXGBE_PHY_FEC_BASER)
5883 : : curr_fec_mode = RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
5884 : : else
5885 : : curr_fec_mode = RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC);
5886 : :
5887 : 0 : *fec_capa = curr_fec_mode;
5888 : 0 : return 0;
5889 : : }
5890 : :
5891 : 0 : static int txgbe_fec_set(struct rte_eth_dev *dev, u32 fec_capa)
5892 : : {
5893 : 0 : struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
5894 : 0 : u32 orig_fec_mode = hw->fec_mode;
5895 : 0 : bool negotiate = false;
5896 : 0 : u32 speed = 0;
5897 : :
5898 : 0 : hw->mac.get_link_capabilities(hw, &speed, &negotiate);
5899 : :
5900 [ # # ]: 0 : if (hw->mac.type != txgbe_mac_aml ||
5901 [ # # ]: 0 : !(speed & TXGBE_LINK_SPEED_25GB_FULL))
5902 : : return -EOPNOTSUPP;
5903 : :
5904 [ # # ]: 0 : if (!fec_capa)
5905 : : return -EINVAL;
5906 : :
5907 [ # # ]: 0 : if (fec_capa & RTE_ETH_FEC_MODE_CAPA_MASK(AUTO))
5908 : 0 : hw->fec_mode = TXGBE_PHY_FEC_AUTO;
5909 : :
5910 [ # # ]: 0 : if (fec_capa & RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC))
5911 : 0 : hw->fec_mode = TXGBE_PHY_FEC_OFF;
5912 : :
5913 [ # # ]: 0 : if (fec_capa & RTE_ETH_FEC_MODE_CAPA_MASK(BASER))
5914 : 0 : hw->fec_mode = TXGBE_PHY_FEC_BASER;
5915 : :
5916 [ # # ]: 0 : if (fec_capa & RTE_ETH_FEC_MODE_CAPA_MASK(RS))
5917 : 0 : hw->fec_mode = TXGBE_PHY_FEC_RS;
5918 : :
5919 [ # # ]: 0 : if (hw->fec_mode != orig_fec_mode) {
5920 : 0 : txgbe_dev_setup_link_alarm_handler(dev);
5921 : : txgbe_dev_link_update(dev, 0);
5922 : : }
5923 : :
5924 : : return 0;
5925 : : }
5926 : :
5927 : : static const struct eth_dev_ops txgbe_eth_dev_ops = {
5928 : : .dev_configure = txgbe_dev_configure,
5929 : : .dev_infos_get = txgbe_dev_info_get,
5930 : : .dev_start = txgbe_dev_start,
5931 : : .dev_stop = txgbe_dev_stop,
5932 : : .dev_set_link_up = txgbe_dev_set_link_up,
5933 : : .dev_set_link_down = txgbe_dev_set_link_down,
5934 : : .dev_close = txgbe_dev_close,
5935 : : .dev_reset = txgbe_dev_reset,
5936 : : .promiscuous_enable = txgbe_dev_promiscuous_enable,
5937 : : .promiscuous_disable = txgbe_dev_promiscuous_disable,
5938 : : .allmulticast_enable = txgbe_dev_allmulticast_enable,
5939 : : .allmulticast_disable = txgbe_dev_allmulticast_disable,
5940 : : .link_update = txgbe_dev_link_update,
5941 : : .stats_get = txgbe_dev_stats_get,
5942 : : .xstats_get = txgbe_dev_xstats_get,
5943 : : .xstats_get_by_id = txgbe_dev_xstats_get_by_id,
5944 : : .stats_reset = txgbe_dev_stats_reset,
5945 : : .xstats_reset = txgbe_dev_xstats_reset,
5946 : : .xstats_get_names = txgbe_dev_xstats_get_names,
5947 : : .xstats_get_names_by_id = txgbe_dev_xstats_get_names_by_id,
5948 : : .queue_stats_mapping_set = txgbe_dev_queue_stats_mapping_set,
5949 : : .fw_version_get = txgbe_fw_version_get,
5950 : : .dev_supported_ptypes_get = txgbe_dev_supported_ptypes_get,
5951 : : .mtu_set = txgbe_dev_mtu_set,
5952 : : .vlan_filter_set = txgbe_vlan_filter_set,
5953 : : .vlan_tpid_set = txgbe_vlan_tpid_set,
5954 : : .vlan_offload_set = txgbe_vlan_offload_set,
5955 : : .vlan_strip_queue_set = txgbe_vlan_strip_queue_set,
5956 : : .rx_queue_start = txgbe_dev_rx_queue_start,
5957 : : .rx_queue_stop = txgbe_dev_rx_queue_stop,
5958 : : .tx_queue_start = txgbe_dev_tx_queue_start,
5959 : : .tx_queue_stop = txgbe_dev_tx_queue_stop,
5960 : : .rx_queue_setup = txgbe_dev_rx_queue_setup,
5961 : : .rx_queue_intr_enable = txgbe_dev_rx_queue_intr_enable,
5962 : : .rx_queue_intr_disable = txgbe_dev_rx_queue_intr_disable,
5963 : : .rx_queue_release = txgbe_dev_rx_queue_release,
5964 : : .tx_queue_setup = txgbe_dev_tx_queue_setup,
5965 : : .tx_queue_release = txgbe_dev_tx_queue_release,
5966 : : .dev_led_on = txgbe_dev_led_on,
5967 : : .dev_led_off = txgbe_dev_led_off,
5968 : : .flow_ctrl_get = txgbe_flow_ctrl_get,
5969 : : .flow_ctrl_set = txgbe_flow_ctrl_set,
5970 : : .priority_flow_ctrl_set = txgbe_priority_flow_ctrl_set,
5971 : : .mac_addr_add = txgbe_add_rar,
5972 : : .mac_addr_remove = txgbe_remove_rar,
5973 : : .mac_addr_set = txgbe_set_default_mac_addr,
5974 : : .uc_hash_table_set = txgbe_uc_hash_table_set,
5975 : : .uc_all_hash_table_set = txgbe_uc_all_hash_table_set,
5976 : : .set_queue_rate_limit = txgbe_set_queue_rate_limit,
5977 : : .reta_update = txgbe_dev_rss_reta_update,
5978 : : .reta_query = txgbe_dev_rss_reta_query,
5979 : : .rss_hash_update = txgbe_dev_rss_hash_update,
5980 : : .rss_hash_conf_get = txgbe_dev_rss_hash_conf_get,
5981 : : .flow_ops_get = txgbe_dev_flow_ops_get,
5982 : : .set_mc_addr_list = txgbe_dev_set_mc_addr_list,
5983 : : .rxq_info_get = txgbe_rxq_info_get,
5984 : : .txq_info_get = txgbe_txq_info_get,
5985 : : .timesync_enable = txgbe_timesync_enable,
5986 : : .timesync_disable = txgbe_timesync_disable,
5987 : : .timesync_read_rx_timestamp = txgbe_timesync_read_rx_timestamp,
5988 : : .timesync_read_tx_timestamp = txgbe_timesync_read_tx_timestamp,
5989 : : .get_reg = txgbe_get_regs,
5990 : : .get_eeprom_length = txgbe_get_eeprom_length,
5991 : : .get_eeprom = txgbe_get_eeprom,
5992 : : .set_eeprom = txgbe_set_eeprom,
5993 : : .get_module_info = txgbe_get_module_info,
5994 : : .get_module_eeprom = txgbe_get_module_eeprom,
5995 : : .get_dcb_info = txgbe_dev_get_dcb_info,
5996 : : .timesync_adjust_time = txgbe_timesync_adjust_time,
5997 : : .timesync_read_time = txgbe_timesync_read_time,
5998 : : .timesync_write_time = txgbe_timesync_write_time,
5999 : : .udp_tunnel_port_add = txgbe_dev_udp_tunnel_port_add,
6000 : : .udp_tunnel_port_del = txgbe_dev_udp_tunnel_port_del,
6001 : : .tm_ops_get = txgbe_tm_ops_get,
6002 : : .tx_done_cleanup = txgbe_dev_tx_done_cleanup,
6003 : : .fec_get_capability = txgbe_fec_get_capability,
6004 : : .fec_get = txgbe_fec_get,
6005 : : .fec_set = txgbe_fec_set,
6006 : : };
6007 : :
6008 : 253 : RTE_PMD_REGISTER_PCI(net_txgbe, rte_txgbe_pmd);
6009 : : RTE_PMD_REGISTER_PCI_TABLE(net_txgbe, pci_id_txgbe_map);
6010 : : RTE_PMD_REGISTER_KMOD_DEP(net_txgbe, "* igb_uio | uio_pci_generic | vfio-pci");
6011 : : RTE_PMD_REGISTER_PARAM_STRING(net_txgbe,
6012 : : TXGBE_DEVARG_BP_AUTO "=<0|1>"
6013 : : TXGBE_DEVARG_KR_POLL "=<0|1>"
6014 : : TXGBE_DEVARG_KR_PRESENT "=<0|1>"
6015 : : TXGBE_DEVARG_KX_SGMII "=<0|1>"
6016 : : TXGBE_DEVARG_FFE_SET "=<0-4>"
6017 : : TXGBE_DEVARG_FFE_MAIN "=<uint16>"
6018 : : TXGBE_DEVARG_FFE_PRE "=<uint16>"
6019 : : TXGBE_DEVARG_FFE_POST "=<uint16>"
6020 : : TXGBE_DEVARG_TX_HEAD_WB "=<0|1>"
6021 : : TXGBE_DEVARG_TX_HEAD_WB_SIZE "=<1|16>"
6022 : : TXGBE_DEVARG_RX_DESC_MERGE "=<0|1>");
6023 : :
6024 [ - + ]: 253 : RTE_LOG_REGISTER_SUFFIX(txgbe_logtype_init, init, NOTICE);
6025 [ - + ]: 253 : RTE_LOG_REGISTER_SUFFIX(txgbe_logtype_driver, driver, NOTICE);
6026 [ - + ]: 253 : RTE_LOG_REGISTER_SUFFIX(txgbe_logtype_bp, bp, NOTICE);
6027 : :
6028 : : #ifdef RTE_LIBRTE_TXGBE_DEBUG_RX
6029 : : RTE_LOG_REGISTER_SUFFIX(txgbe_logtype_rx, rx, DEBUG);
6030 : : #endif
6031 : : #ifdef RTE_LIBRTE_TXGBE_DEBUG_TX
6032 : : RTE_LOG_REGISTER_SUFFIX(txgbe_logtype_tx, tx, DEBUG);
6033 : : #endif
6034 : :
6035 : : #ifdef RTE_LIBRTE_TXGBE_DEBUG_TX_FREE
6036 : : RTE_LOG_REGISTER_SUFFIX(txgbe_logtype_tx_free, tx_free, DEBUG);
6037 : : #endif
|