Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018 Advanced Micro Devices, Inc. All rights reserved.
3 : : * Copyright(c) 2018 Synopsys, Inc. All rights reserved.
4 : : */
5 : :
6 : : #include "axgbe_rxtx.h"
7 : : #include "axgbe_ethdev.h"
8 : : #include "axgbe_common.h"
9 : : #include "axgbe_phy.h"
10 : : #include "axgbe_regs.h"
11 : : #include "rte_time.h"
12 : :
13 : : #include "eal_filesystem.h"
14 : :
15 : : #include <rte_thread.h>
16 : : #include <rte_vect.h>
17 : :
18 : : #ifdef RTE_ARCH_X86
19 : : #include <cpuid.h>
20 : : #else
21 : : #define __cpuid(n, a, b, c, d)
22 : : #endif
23 : :
24 : : static int eth_axgbe_dev_init(struct rte_eth_dev *eth_dev);
25 : : static int axgbe_dev_configure(struct rte_eth_dev *dev);
26 : : static int axgbe_dev_start(struct rte_eth_dev *dev);
27 : : static int axgbe_dev_stop(struct rte_eth_dev *dev);
28 : : static void axgbe_dev_interrupt_handler(void *param);
29 : : static int axgbe_dev_close(struct rte_eth_dev *dev);
30 : : static int axgbe_dev_reset(struct rte_eth_dev *dev);
31 : : static int axgbe_dev_promiscuous_enable(struct rte_eth_dev *dev);
32 : : static int axgbe_dev_promiscuous_disable(struct rte_eth_dev *dev);
33 : : static int axgbe_dev_allmulticast_enable(struct rte_eth_dev *dev);
34 : : static int axgbe_dev_allmulticast_disable(struct rte_eth_dev *dev);
35 : : static int axgbe_dev_mac_addr_set(struct rte_eth_dev *dev,
36 : : struct rte_ether_addr *mac_addr);
37 : : static int axgbe_dev_mac_addr_add(struct rte_eth_dev *dev,
38 : : struct rte_ether_addr *mac_addr,
39 : : uint32_t index,
40 : : uint32_t vmdq);
41 : : static void axgbe_dev_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
42 : : static int axgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
43 : : struct rte_ether_addr *mc_addr_set,
44 : : uint32_t nb_mc_addr);
45 : : static int axgbe_dev_uc_hash_table_set(struct rte_eth_dev *dev,
46 : : struct rte_ether_addr *mac_addr,
47 : : uint8_t add);
48 : : static int axgbe_dev_uc_all_hash_table_set(struct rte_eth_dev *dev,
49 : : uint8_t add);
50 : : static int axgbe_dev_link_update(struct rte_eth_dev *dev,
51 : : int wait_to_complete);
52 : : static int axgbe_dev_get_regs(struct rte_eth_dev *dev,
53 : : struct rte_dev_reg_info *regs);
54 : : static int axgbe_dev_stats_get(struct rte_eth_dev *dev,
55 : : struct rte_eth_stats *stats,
56 : : struct eth_queue_stats *qstats);
57 : : static int axgbe_dev_stats_reset(struct rte_eth_dev *dev);
58 : : static int axgbe_dev_xstats_get(struct rte_eth_dev *dev,
59 : : struct rte_eth_xstat *stats,
60 : : unsigned int n);
61 : : static int
62 : : axgbe_dev_xstats_get_names(struct rte_eth_dev *dev,
63 : : struct rte_eth_xstat_name *xstats_names,
64 : : unsigned int size);
65 : : static int
66 : : axgbe_dev_xstats_get_by_id(struct rte_eth_dev *dev,
67 : : const uint64_t *ids,
68 : : uint64_t *values,
69 : : unsigned int n);
70 : : static int
71 : : axgbe_dev_xstats_get_names_by_id(struct rte_eth_dev *dev,
72 : : const uint64_t *ids,
73 : : struct rte_eth_xstat_name *xstats_names,
74 : : unsigned int size);
75 : : static int axgbe_dev_xstats_reset(struct rte_eth_dev *dev);
76 : : static int axgbe_dev_rss_reta_update(struct rte_eth_dev *dev,
77 : : struct rte_eth_rss_reta_entry64 *reta_conf,
78 : : uint16_t reta_size);
79 : : static int axgbe_dev_rss_reta_query(struct rte_eth_dev *dev,
80 : : struct rte_eth_rss_reta_entry64 *reta_conf,
81 : : uint16_t reta_size);
82 : : static int axgbe_dev_rss_hash_update(struct rte_eth_dev *dev,
83 : : struct rte_eth_rss_conf *rss_conf);
84 : : static int axgbe_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
85 : : struct rte_eth_rss_conf *rss_conf);
86 : : static int axgbe_dev_info_get(struct rte_eth_dev *dev,
87 : : struct rte_eth_dev_info *dev_info);
88 : : static int axgbe_flow_ctrl_get(struct rte_eth_dev *dev,
89 : : struct rte_eth_fc_conf *fc_conf);
90 : : static int axgbe_flow_ctrl_set(struct rte_eth_dev *dev,
91 : : struct rte_eth_fc_conf *fc_conf);
92 : : static int axgbe_priority_flow_ctrl_set(struct rte_eth_dev *dev,
93 : : struct rte_eth_pfc_conf *pfc_conf);
94 : : static void axgbe_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
95 : : struct rte_eth_rxq_info *qinfo);
96 : : static void axgbe_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
97 : : struct rte_eth_txq_info *qinfo);
98 : : const uint32_t *axgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev,
99 : : size_t *no_of_elements);
100 : : static int axgb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
101 : :
102 : : static int
103 : : axgbe_timesync_enable(struct rte_eth_dev *dev);
104 : : static int
105 : : axgbe_timesync_disable(struct rte_eth_dev *dev);
106 : : static int
107 : : axgbe_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
108 : : struct timespec *timestamp, uint32_t flags);
109 : : static int
110 : : axgbe_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
111 : : struct timespec *timestamp);
112 : : static int
113 : : axgbe_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta);
114 : : static int
115 : : axgbe_timesync_read_time(struct rte_eth_dev *dev,
116 : : struct timespec *timestamp);
117 : : static int
118 : : axgbe_timesync_write_time(struct rte_eth_dev *dev,
119 : : const struct timespec *timestamp);
120 : : static void
121 : : axgbe_set_tstamp_time(struct axgbe_port *pdata, unsigned int sec,
122 : : unsigned int nsec);
123 : : static void
124 : : axgbe_update_tstamp_addend(struct axgbe_port *pdata,
125 : : unsigned int addend);
126 : : static int
127 : : axgbe_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vid, int on);
128 : : static int axgbe_vlan_tpid_set(struct rte_eth_dev *dev,
129 : : enum rte_vlan_type vlan_type, uint16_t tpid);
130 : : static int axgbe_vlan_offload_set(struct rte_eth_dev *dev, int mask);
131 : :
132 : : struct axgbe_xstats {
133 : : char name[RTE_ETH_XSTATS_NAME_SIZE];
134 : : int offset;
135 : : };
136 : :
137 : : #define AXGMAC_MMC_STAT(_string, _var) \
138 : : { _string, \
139 : : offsetof(struct axgbe_mmc_stats, _var), \
140 : : }
141 : :
142 : : static const struct axgbe_xstats axgbe_xstats_strings[] = {
143 : : AXGMAC_MMC_STAT("tx_bytes", txoctetcount_gb),
144 : : AXGMAC_MMC_STAT("tx_packets", txframecount_gb),
145 : : AXGMAC_MMC_STAT("tx_unicast_packets", txunicastframes_gb),
146 : : AXGMAC_MMC_STAT("tx_broadcast_packets", txbroadcastframes_gb),
147 : : AXGMAC_MMC_STAT("tx_multicast_packets", txmulticastframes_gb),
148 : : AXGMAC_MMC_STAT("tx_vlan_packets", txvlanframes_g),
149 : : AXGMAC_MMC_STAT("tx_64_byte_packets", tx64octets_gb),
150 : : AXGMAC_MMC_STAT("tx_65_to_127_byte_packets", tx65to127octets_gb),
151 : : AXGMAC_MMC_STAT("tx_128_to_255_byte_packets", tx128to255octets_gb),
152 : : AXGMAC_MMC_STAT("tx_256_to_511_byte_packets", tx256to511octets_gb),
153 : : AXGMAC_MMC_STAT("tx_512_to_1023_byte_packets", tx512to1023octets_gb),
154 : : AXGMAC_MMC_STAT("tx_1024_to_max_byte_packets", tx1024tomaxoctets_gb),
155 : : AXGMAC_MMC_STAT("tx_underflow_errors", txunderflowerror),
156 : : AXGMAC_MMC_STAT("tx_pause_frames", txpauseframes),
157 : :
158 : : AXGMAC_MMC_STAT("rx_bytes", rxoctetcount_gb),
159 : : AXGMAC_MMC_STAT("rx_packets", rxframecount_gb),
160 : : AXGMAC_MMC_STAT("rx_unicast_packets", rxunicastframes_g),
161 : : AXGMAC_MMC_STAT("rx_broadcast_packets", rxbroadcastframes_g),
162 : : AXGMAC_MMC_STAT("rx_multicast_packets", rxmulticastframes_g),
163 : : AXGMAC_MMC_STAT("rx_vlan_packets", rxvlanframes_gb),
164 : : AXGMAC_MMC_STAT("rx_64_byte_packets", rx64octets_gb),
165 : : AXGMAC_MMC_STAT("rx_65_to_127_byte_packets", rx65to127octets_gb),
166 : : AXGMAC_MMC_STAT("rx_128_to_255_byte_packets", rx128to255octets_gb),
167 : : AXGMAC_MMC_STAT("rx_256_to_511_byte_packets", rx256to511octets_gb),
168 : : AXGMAC_MMC_STAT("rx_512_to_1023_byte_packets", rx512to1023octets_gb),
169 : : AXGMAC_MMC_STAT("rx_1024_to_max_byte_packets", rx1024tomaxoctets_gb),
170 : : AXGMAC_MMC_STAT("rx_undersize_packets", rxundersize_g),
171 : : AXGMAC_MMC_STAT("rx_oversize_packets", rxoversize_g),
172 : : AXGMAC_MMC_STAT("rx_crc_errors", rxcrcerror),
173 : : AXGMAC_MMC_STAT("rx_crc_errors_small_packets", rxrunterror),
174 : : AXGMAC_MMC_STAT("rx_crc_errors_giant_packets", rxjabbererror),
175 : : AXGMAC_MMC_STAT("rx_length_errors", rxlengtherror),
176 : : AXGMAC_MMC_STAT("rx_out_of_range_errors", rxoutofrangetype),
177 : : AXGMAC_MMC_STAT("rx_fifo_overflow_errors", rxfifooverflow),
178 : : AXGMAC_MMC_STAT("rx_watchdog_errors", rxwatchdogerror),
179 : : AXGMAC_MMC_STAT("rx_pause_frames", rxpauseframes),
180 : : };
181 : :
182 : : #define AXGBE_XSTATS_COUNT ARRAY_SIZE(axgbe_xstats_strings)
183 : :
184 : : /* The set of PCI devices this driver supports */
185 : : #define AMD_PCI_VENDOR_ID 0x1022
186 : :
187 : : #define Fam17h 0x17
188 : : #define Fam19h 0x19
189 : : #define Fam1Ah 0x1A
190 : :
191 : : #define CPUID_VENDOR_AuthenticAMD_ebx 0x68747541
192 : : #define CPUID_VENDOR_AuthenticAMD_ecx 0x444d4163
193 : : #define CPUID_VENDOR_AuthenticAMD_edx 0x69746e65
194 : :
195 : : #define AMD_PCI_AXGBE_DEVICE_V2A 0x1458
196 : : #define AMD_PCI_AXGBE_DEVICE_V2B 0x1459
197 : :
198 : : static const struct rte_pci_id pci_id_axgbe_map[] = {
199 : : {RTE_PCI_DEVICE(AMD_PCI_VENDOR_ID, AMD_PCI_AXGBE_DEVICE_V2A)},
200 : : {RTE_PCI_DEVICE(AMD_PCI_VENDOR_ID, AMD_PCI_AXGBE_DEVICE_V2B)},
201 : : { .vendor_id = 0, },
202 : : };
203 : :
204 : : static struct axgbe_version_data axgbe_v2a = {
205 : : .init_function_ptrs_phy_impl = axgbe_init_function_ptrs_phy_v2,
206 : : .xpcs_access = AXGBE_XPCS_ACCESS_V2,
207 : : .mmc_64bit = 1,
208 : : .tx_max_fifo_size = 229376,
209 : : .rx_max_fifo_size = 229376,
210 : : .tx_tstamp_workaround = 1,
211 : : .ecc_support = 1,
212 : : .i2c_support = 1,
213 : : .an_cdr_workaround = 1,
214 : : .enable_rrc = 1,
215 : : };
216 : :
217 : : static struct axgbe_version_data axgbe_v2b = {
218 : : .init_function_ptrs_phy_impl = axgbe_init_function_ptrs_phy_v2,
219 : : .xpcs_access = AXGBE_XPCS_ACCESS_V2,
220 : : .mmc_64bit = 1,
221 : : .tx_max_fifo_size = 65536,
222 : : .rx_max_fifo_size = 65536,
223 : : .tx_tstamp_workaround = 1,
224 : : .ecc_support = 1,
225 : : .i2c_support = 1,
226 : : .an_cdr_workaround = 1,
227 : : .enable_rrc = 1,
228 : : };
229 : :
230 : : static const struct rte_eth_desc_lim rx_desc_lim = {
231 : : .nb_max = AXGBE_MAX_RING_DESC,
232 : : .nb_min = AXGBE_MIN_RING_DESC,
233 : : .nb_align = 8,
234 : : };
235 : :
236 : : static const struct rte_eth_desc_lim tx_desc_lim = {
237 : : .nb_max = AXGBE_MAX_RING_DESC,
238 : : .nb_min = AXGBE_MIN_RING_DESC,
239 : : .nb_align = 8,
240 : : };
241 : :
242 : : static const struct eth_dev_ops axgbe_eth_dev_ops = {
243 : : .dev_configure = axgbe_dev_configure,
244 : : .dev_start = axgbe_dev_start,
245 : : .dev_stop = axgbe_dev_stop,
246 : : .dev_close = axgbe_dev_close,
247 : : .dev_reset = axgbe_dev_reset,
248 : : .promiscuous_enable = axgbe_dev_promiscuous_enable,
249 : : .promiscuous_disable = axgbe_dev_promiscuous_disable,
250 : : .allmulticast_enable = axgbe_dev_allmulticast_enable,
251 : : .allmulticast_disable = axgbe_dev_allmulticast_disable,
252 : : .mac_addr_set = axgbe_dev_mac_addr_set,
253 : : .mac_addr_add = axgbe_dev_mac_addr_add,
254 : : .mac_addr_remove = axgbe_dev_mac_addr_remove,
255 : : .set_mc_addr_list = axgbe_dev_set_mc_addr_list,
256 : : .uc_hash_table_set = axgbe_dev_uc_hash_table_set,
257 : : .uc_all_hash_table_set = axgbe_dev_uc_all_hash_table_set,
258 : : .link_update = axgbe_dev_link_update,
259 : : .get_reg = axgbe_dev_get_regs,
260 : : .stats_get = axgbe_dev_stats_get,
261 : : .stats_reset = axgbe_dev_stats_reset,
262 : : .xstats_get = axgbe_dev_xstats_get,
263 : : .xstats_reset = axgbe_dev_xstats_reset,
264 : : .xstats_get_names = axgbe_dev_xstats_get_names,
265 : : .xstats_get_names_by_id = axgbe_dev_xstats_get_names_by_id,
266 : : .xstats_get_by_id = axgbe_dev_xstats_get_by_id,
267 : : .reta_update = axgbe_dev_rss_reta_update,
268 : : .reta_query = axgbe_dev_rss_reta_query,
269 : : .rss_hash_update = axgbe_dev_rss_hash_update,
270 : : .rss_hash_conf_get = axgbe_dev_rss_hash_conf_get,
271 : : .dev_infos_get = axgbe_dev_info_get,
272 : : .rx_queue_setup = axgbe_dev_rx_queue_setup,
273 : : .rx_queue_release = axgbe_dev_rx_queue_release,
274 : : .tx_queue_setup = axgbe_dev_tx_queue_setup,
275 : : .tx_queue_release = axgbe_dev_tx_queue_release,
276 : : .flow_ctrl_get = axgbe_flow_ctrl_get,
277 : : .flow_ctrl_set = axgbe_flow_ctrl_set,
278 : : .priority_flow_ctrl_set = axgbe_priority_flow_ctrl_set,
279 : : .rxq_info_get = axgbe_rxq_info_get,
280 : : .txq_info_get = axgbe_txq_info_get,
281 : : .dev_supported_ptypes_get = axgbe_dev_supported_ptypes_get,
282 : : .mtu_set = axgb_mtu_set,
283 : : .vlan_filter_set = axgbe_vlan_filter_set,
284 : : .vlan_tpid_set = axgbe_vlan_tpid_set,
285 : : .vlan_offload_set = axgbe_vlan_offload_set,
286 : : .timesync_enable = axgbe_timesync_enable,
287 : : .timesync_disable = axgbe_timesync_disable,
288 : : .timesync_read_rx_timestamp = axgbe_timesync_read_rx_timestamp,
289 : : .timesync_read_tx_timestamp = axgbe_timesync_read_tx_timestamp,
290 : : .timesync_adjust_time = axgbe_timesync_adjust_time,
291 : : .timesync_read_time = axgbe_timesync_read_time,
292 : : .timesync_write_time = axgbe_timesync_write_time,
293 : : .fw_version_get = axgbe_dev_fw_version_get,
294 : : };
295 : :
296 : : static int axgbe_phy_reset(struct axgbe_port *pdata)
297 : : {
298 : 0 : pdata->phy_link = -1;
299 : 0 : pdata->phy_speed = SPEED_UNKNOWN;
300 : 0 : return pdata->phy_if.phy_reset(pdata);
301 : : }
302 : :
303 : : /*
304 : : * Interrupt handler triggered by NIC for handling
305 : : * specific interrupt.
306 : : *
307 : : * @param handle
308 : : * Pointer to interrupt handle.
309 : : * @param param
310 : : * The address of parameter (struct rte_eth_dev *) registered before.
311 : : *
312 : : * @return
313 : : * void
314 : : */
315 : : static void
316 : 0 : axgbe_dev_interrupt_handler(void *param)
317 : : {
318 : : struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
319 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
320 : : unsigned int dma_isr, dma_ch_isr;
321 : :
322 : 0 : pdata->phy_if.an_isr(pdata);
323 : : /*DMA related interrupts*/
324 : 0 : dma_isr = AXGMAC_IOREAD(pdata, DMA_ISR);
325 : 0 : PMD_DRV_LOG_LINE(DEBUG, "DMA_ISR=%#010x", dma_isr);
326 [ # # ]: 0 : if (dma_isr) {
327 [ # # ]: 0 : if (dma_isr & 1) {
328 : : dma_ch_isr =
329 : 0 : AXGMAC_DMA_IOREAD((struct axgbe_rx_queue *)
330 : : pdata->rx_queues[0],
331 : : DMA_CH_SR);
332 : 0 : PMD_DRV_LOG_LINE(DEBUG, "DMA_CH0_ISR=%#010x", dma_ch_isr);
333 : 0 : AXGMAC_DMA_IOWRITE((struct axgbe_rx_queue *)
334 : : pdata->rx_queues[0],
335 : : DMA_CH_SR, dma_ch_isr);
336 : : }
337 : : }
338 : : /* Unmask interrupts since disabled after generation */
339 : 0 : rte_intr_ack(pdata->pci_dev->intr_handle);
340 : 0 : }
341 : :
342 : : /*
343 : : * Configure device link speed and setup link.
344 : : * It returns 0 on success.
345 : : */
346 : : static int
347 : 0 : axgbe_dev_configure(struct rte_eth_dev *dev)
348 : : {
349 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
350 : : /* Checksum offload to hardware */
351 : 0 : pdata->rx_csum_enable = dev->data->dev_conf.rxmode.offloads &
352 : : RTE_ETH_RX_OFFLOAD_CHECKSUM;
353 : 0 : return 0;
354 : : }
355 : :
356 : : static int
357 : : axgbe_dev_rx_mq_config(struct rte_eth_dev *dev)
358 : : {
359 : : struct axgbe_port *pdata = dev->data->dev_private;
360 : :
361 : 0 : if (dev->data->dev_conf.rxmode.mq_mode == RTE_ETH_MQ_RX_RSS)
362 : 0 : pdata->rss_enable = 1;
363 [ # # ]: 0 : else if (dev->data->dev_conf.rxmode.mq_mode == RTE_ETH_MQ_RX_NONE)
364 : 0 : pdata->rss_enable = 0;
365 : : else
366 : : return -1;
367 : : return 0;
368 : : }
369 : :
370 : : static int
371 : 0 : axgbe_dev_start(struct rte_eth_dev *dev)
372 : : {
373 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
374 : : uint16_t i;
375 : : int ret;
376 : :
377 [ # # ]: 0 : dev->dev_ops = &axgbe_eth_dev_ops;
378 : :
379 : : PMD_INIT_FUNC_TRACE();
380 : :
381 : : /* Multiqueue RSS */
382 : : ret = axgbe_dev_rx_mq_config(dev);
383 : : if (ret) {
384 : 0 : PMD_DRV_LOG_LINE(ERR, "Unable to config RX MQ");
385 : 0 : return ret;
386 : : }
387 : : ret = axgbe_phy_reset(pdata);
388 [ # # ]: 0 : if (ret) {
389 : 0 : PMD_DRV_LOG_LINE(ERR, "phy reset failed");
390 : 0 : return ret;
391 : : }
392 : 0 : ret = pdata->hw_if.init(pdata);
393 [ # # ]: 0 : if (ret) {
394 : 0 : PMD_DRV_LOG_LINE(ERR, "dev_init failed");
395 : 0 : return ret;
396 : : }
397 : :
398 : : /* enable uio/vfio intr/eventfd mapping */
399 : 0 : rte_intr_enable(pdata->pci_dev->intr_handle);
400 : :
401 : : /* phy start*/
402 : 0 : pdata->phy_if.phy_start(pdata);
403 : 0 : axgbe_dev_enable_tx(dev);
404 : 0 : axgbe_dev_enable_rx(dev);
405 : :
406 : : rte_bit_relaxed_clear32(AXGBE_STOPPED, &pdata->dev_state);
407 : : rte_bit_relaxed_clear32(AXGBE_DOWN, &pdata->dev_state);
408 : :
409 : 0 : axgbe_set_rx_function(dev);
410 : 0 : axgbe_set_tx_function(dev);
411 : :
412 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++)
413 : 0 : dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
414 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++)
415 : 0 : dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
416 : :
417 : : return 0;
418 : : }
419 : :
420 : : /* Stop device: disable rx and tx functions to allow for reconfiguring. */
421 : : static int
422 : 0 : axgbe_dev_stop(struct rte_eth_dev *dev)
423 : : {
424 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
425 : :
426 : : PMD_INIT_FUNC_TRACE();
427 : :
428 : 0 : rte_intr_disable(pdata->pci_dev->intr_handle);
429 : :
430 [ # # ]: 0 : if (rte_bit_relaxed_get32(AXGBE_STOPPED, &pdata->dev_state))
431 : : return 0;
432 : :
433 : : rte_bit_relaxed_set32(AXGBE_STOPPED, &pdata->dev_state);
434 : 0 : axgbe_dev_disable_tx(dev);
435 : 0 : axgbe_dev_disable_rx(dev);
436 : :
437 : 0 : pdata->phy_if.phy_stop(pdata);
438 : 0 : pdata->hw_if.exit(pdata);
439 : 0 : memset(&dev->data->dev_link, 0, sizeof(struct rte_eth_link));
440 : : rte_bit_relaxed_set32(AXGBE_DOWN, &pdata->dev_state);
441 : :
442 : 0 : return 0;
443 : : }
444 : :
445 : : static int
446 : 0 : axgbe_dev_promiscuous_enable(struct rte_eth_dev *dev)
447 : : {
448 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
449 : :
450 : : PMD_INIT_FUNC_TRACE();
451 : :
452 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PR, 1);
453 : :
454 : 0 : return 0;
455 : : }
456 : :
457 : : static int
458 : 0 : axgbe_dev_promiscuous_disable(struct rte_eth_dev *dev)
459 : : {
460 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
461 : :
462 : : PMD_INIT_FUNC_TRACE();
463 : :
464 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PR, 0);
465 : :
466 : 0 : return 0;
467 : : }
468 : :
469 : : static int
470 : 0 : axgbe_dev_allmulticast_enable(struct rte_eth_dev *dev)
471 : : {
472 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
473 : :
474 : : PMD_INIT_FUNC_TRACE();
475 : :
476 [ # # ]: 0 : if (AXGMAC_IOREAD_BITS(pdata, MAC_PFR, PM))
477 : : return 0;
478 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PM, 1);
479 : :
480 : 0 : return 0;
481 : : }
482 : :
483 : : static int
484 : 0 : axgbe_dev_allmulticast_disable(struct rte_eth_dev *dev)
485 : : {
486 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
487 : :
488 : : PMD_INIT_FUNC_TRACE();
489 : :
490 [ # # ]: 0 : if (!AXGMAC_IOREAD_BITS(pdata, MAC_PFR, PM))
491 : : return 0;
492 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PM, 0);
493 : :
494 : 0 : return 0;
495 : : }
496 : :
497 : : static int
498 : 0 : axgbe_dev_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
499 : : {
500 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
501 : :
502 : : /* Set Default MAC Addr */
503 : 0 : axgbe_set_mac_addn_addr(pdata, (u8 *)mac_addr, 0);
504 : :
505 : 0 : return 0;
506 : : }
507 : :
508 : : static int
509 : 0 : axgbe_dev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
510 : : uint32_t index, uint32_t pool __rte_unused)
511 : : {
512 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
513 : : struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
514 : :
515 [ # # ]: 0 : if (index > hw_feat->addn_mac) {
516 : 0 : PMD_DRV_LOG_LINE(ERR, "Invalid Index %d", index);
517 : 0 : return -EINVAL;
518 : : }
519 : 0 : axgbe_set_mac_addn_addr(pdata, (u8 *)mac_addr, index);
520 : 0 : return 0;
521 : : }
522 : :
523 : : static int
524 : 0 : axgbe_dev_rss_reta_update(struct rte_eth_dev *dev,
525 : : struct rte_eth_rss_reta_entry64 *reta_conf,
526 : : uint16_t reta_size)
527 : : {
528 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
529 : : unsigned int i, idx, shift;
530 : : int ret;
531 : :
532 [ # # ]: 0 : if (!pdata->rss_enable) {
533 : 0 : PMD_DRV_LOG_LINE(ERR, "RSS not enabled");
534 : 0 : return -ENOTSUP;
535 : : }
536 : :
537 [ # # ]: 0 : if (reta_size == 0 || reta_size > AXGBE_RSS_MAX_TABLE_SIZE) {
538 : 0 : PMD_DRV_LOG_LINE(ERR, "reta_size %d is not supported", reta_size);
539 : 0 : return -EINVAL;
540 : : }
541 : :
542 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
543 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
544 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
545 [ # # ]: 0 : if ((reta_conf[idx].mask & (1ULL << shift)) == 0)
546 : 0 : continue;
547 : 0 : pdata->rss_table[i] = reta_conf[idx].reta[shift];
548 : : }
549 : :
550 : : /* Program the lookup table */
551 : 0 : ret = axgbe_write_rss_lookup_table(pdata);
552 : 0 : return ret;
553 : : }
554 : :
555 : : static int
556 : 0 : axgbe_dev_rss_reta_query(struct rte_eth_dev *dev,
557 : : struct rte_eth_rss_reta_entry64 *reta_conf,
558 : : uint16_t reta_size)
559 : : {
560 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
561 : : unsigned int i, idx, shift;
562 : :
563 [ # # ]: 0 : if (!pdata->rss_enable) {
564 : 0 : PMD_DRV_LOG_LINE(ERR, "RSS not enabled");
565 : 0 : return -ENOTSUP;
566 : : }
567 : :
568 [ # # ]: 0 : if (reta_size == 0 || reta_size > AXGBE_RSS_MAX_TABLE_SIZE) {
569 : 0 : PMD_DRV_LOG_LINE(ERR, "reta_size %d is not supported", reta_size);
570 : 0 : return -EINVAL;
571 : : }
572 : :
573 [ # # ]: 0 : for (i = 0; i < reta_size; i++) {
574 : 0 : idx = i / RTE_ETH_RETA_GROUP_SIZE;
575 : 0 : shift = i % RTE_ETH_RETA_GROUP_SIZE;
576 [ # # ]: 0 : if ((reta_conf[idx].mask & (1ULL << shift)) == 0)
577 : 0 : continue;
578 : 0 : reta_conf[idx].reta[shift] = pdata->rss_table[i];
579 : : }
580 : : return 0;
581 : : }
582 : :
583 : : static int
584 : 0 : axgbe_dev_rss_hash_update(struct rte_eth_dev *dev,
585 : : struct rte_eth_rss_conf *rss_conf)
586 : : {
587 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
588 : : int ret;
589 : :
590 [ # # ]: 0 : if (!pdata->rss_enable) {
591 : 0 : PMD_DRV_LOG_LINE(ERR, "RSS not enabled");
592 : 0 : return -ENOTSUP;
593 : : }
594 : :
595 [ # # ]: 0 : if (rss_conf == NULL) {
596 : 0 : PMD_DRV_LOG_LINE(ERR, "rss_conf value isn't valid");
597 : 0 : return -EINVAL;
598 : : }
599 : :
600 [ # # ]: 0 : if (rss_conf->rss_key != NULL &&
601 [ # # ]: 0 : rss_conf->rss_key_len == AXGBE_RSS_HASH_KEY_SIZE) {
602 [ # # ]: 0 : rte_memcpy(pdata->rss_key, rss_conf->rss_key,
603 : : AXGBE_RSS_HASH_KEY_SIZE);
604 : : /* Program the hash key */
605 : 0 : ret = axgbe_write_rss_hash_key(pdata);
606 [ # # ]: 0 : if (ret != 0)
607 : : return ret;
608 : : }
609 : :
610 : 0 : pdata->rss_hf = rss_conf->rss_hf & AXGBE_RSS_OFFLOAD;
611 : :
612 [ # # ]: 0 : if (pdata->rss_hf & (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_IPV6))
613 : 0 : AXGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, IP2TE, 1);
614 [ # # ]: 0 : if (pdata->rss_hf &
615 : : (RTE_ETH_RSS_NONFRAG_IPV4_TCP | RTE_ETH_RSS_NONFRAG_IPV6_TCP))
616 : 0 : AXGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, TCP4TE, 1);
617 [ # # ]: 0 : if (pdata->rss_hf &
618 : : (RTE_ETH_RSS_NONFRAG_IPV4_UDP | RTE_ETH_RSS_NONFRAG_IPV6_UDP))
619 : 0 : AXGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1);
620 : :
621 : : /* Set the RSS options */
622 : 0 : AXGMAC_IOWRITE(pdata, MAC_RSSCR, pdata->rss_options);
623 : :
624 : 0 : return 0;
625 : : }
626 : :
627 : : static int
628 : 0 : axgbe_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
629 : : struct rte_eth_rss_conf *rss_conf)
630 : : {
631 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
632 : :
633 [ # # ]: 0 : if (!pdata->rss_enable) {
634 : 0 : PMD_DRV_LOG_LINE(ERR, "RSS not enabled");
635 : 0 : return -ENOTSUP;
636 : : }
637 : :
638 [ # # ]: 0 : if (rss_conf == NULL) {
639 : 0 : PMD_DRV_LOG_LINE(ERR, "rss_conf value isn't valid");
640 : 0 : return -EINVAL;
641 : : }
642 : :
643 [ # # ]: 0 : if (rss_conf->rss_key != NULL &&
644 [ # # ]: 0 : rss_conf->rss_key_len >= AXGBE_RSS_HASH_KEY_SIZE) {
645 [ # # ]: 0 : rte_memcpy(rss_conf->rss_key, pdata->rss_key,
646 : : AXGBE_RSS_HASH_KEY_SIZE);
647 : : }
648 : 0 : rss_conf->rss_key_len = AXGBE_RSS_HASH_KEY_SIZE;
649 : 0 : rss_conf->rss_hf = pdata->rss_hf;
650 : 0 : return 0;
651 : : }
652 : :
653 : : static int
654 : 0 : axgbe_dev_reset(struct rte_eth_dev *dev)
655 : : {
656 : : int ret = 0;
657 : :
658 : 0 : ret = axgbe_dev_close(dev);
659 [ # # ]: 0 : if (ret)
660 : : return ret;
661 : :
662 : 0 : ret = eth_axgbe_dev_init(dev);
663 : :
664 : 0 : return ret;
665 : : }
666 : :
667 : : static void
668 : 0 : axgbe_dev_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
669 : : {
670 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
671 : : struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
672 : :
673 [ # # ]: 0 : if (index > hw_feat->addn_mac) {
674 : 0 : PMD_DRV_LOG_LINE(ERR, "Invalid Index %d", index);
675 : 0 : return;
676 : : }
677 : 0 : axgbe_set_mac_addn_addr(pdata, NULL, index);
678 : : }
679 : :
680 : : static int
681 : 0 : axgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
682 : : struct rte_ether_addr *mc_addr_set,
683 : : uint32_t nb_mc_addr)
684 : : {
685 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
686 : : struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
687 : : uint32_t index = 1; /* 0 is always default mac */
688 : : uint32_t i;
689 : :
690 [ # # ]: 0 : if (nb_mc_addr > hw_feat->addn_mac) {
691 : 0 : PMD_DRV_LOG_LINE(ERR, "Invalid Index %d", nb_mc_addr);
692 : 0 : return -EINVAL;
693 : : }
694 : :
695 : : /* clear unicast addresses */
696 [ # # ]: 0 : for (i = 1; i < hw_feat->addn_mac; i++) {
697 [ # # ]: 0 : if (rte_is_zero_ether_addr(&dev->data->mac_addrs[i]))
698 : 0 : continue;
699 : : memset(&dev->data->mac_addrs[i], 0,
700 : : sizeof(struct rte_ether_addr));
701 : : }
702 : :
703 [ # # ]: 0 : while (nb_mc_addr--)
704 : 0 : axgbe_set_mac_addn_addr(pdata, (u8 *)mc_addr_set++, index++);
705 : :
706 : : return 0;
707 : : }
708 : :
709 : : static int
710 : 0 : axgbe_dev_uc_hash_table_set(struct rte_eth_dev *dev,
711 : : struct rte_ether_addr *mac_addr, uint8_t add)
712 : : {
713 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
714 : : struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
715 : :
716 [ # # ]: 0 : if (!hw_feat->hash_table_size) {
717 : 0 : PMD_DRV_LOG_LINE(ERR, "MAC Hash Table not supported");
718 : 0 : return -ENOTSUP;
719 : : }
720 : :
721 : 0 : axgbe_set_mac_hash_table(pdata, (u8 *)mac_addr, add);
722 : :
723 [ # # ]: 0 : if (pdata->uc_hash_mac_addr > 0) {
724 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1);
725 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1);
726 : : } else {
727 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 0);
728 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0);
729 : : }
730 : : return 0;
731 : : }
732 : :
733 : : static int
734 : 0 : axgbe_dev_uc_all_hash_table_set(struct rte_eth_dev *dev, uint8_t add)
735 : : {
736 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
737 : : struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
738 : : uint32_t index;
739 : :
740 [ # # ]: 0 : if (!hw_feat->hash_table_size) {
741 : 0 : PMD_DRV_LOG_LINE(ERR, "MAC Hash Table not supported");
742 : 0 : return -ENOTSUP;
743 : : }
744 : :
745 [ # # ]: 0 : for (index = 0; index < pdata->hash_table_count; index++) {
746 [ # # ]: 0 : if (add)
747 : 0 : pdata->uc_hash_table[index] = ~0;
748 : : else
749 : 0 : pdata->uc_hash_table[index] = 0;
750 : :
751 [ # # ]: 0 : PMD_DRV_LOG_LINE(DEBUG, "%s MAC hash table at Index %#x",
752 : : add ? "set" : "clear", index);
753 : :
754 : 0 : AXGMAC_IOWRITE(pdata, MAC_HTR(index),
755 : : pdata->uc_hash_table[index]);
756 : : }
757 : :
758 [ # # ]: 0 : if (add) {
759 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1);
760 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1);
761 : : } else {
762 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 0);
763 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0);
764 : : }
765 : : return 0;
766 : : }
767 : :
768 : : /* return 0 means link status changed, -1 means not changed */
769 : : static int
770 : 0 : axgbe_dev_link_update(struct rte_eth_dev *dev,
771 : : int wait_to_complete __rte_unused)
772 : : {
773 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
774 : : struct rte_eth_link link;
775 : : int ret = 0;
776 : :
777 : : PMD_INIT_FUNC_TRACE();
778 : : rte_delay_ms(800);
779 : :
780 : 0 : pdata->phy_if.phy_status(pdata);
781 : :
782 : : memset(&link, 0, sizeof(struct rte_eth_link));
783 : 0 : link.link_duplex = pdata->phy.duplex;
784 : 0 : link.link_status = pdata->phy_link;
785 : 0 : link.link_speed = pdata->phy_speed;
786 [ # # ]: 0 : link.link_autoneg = !(dev->data->dev_conf.link_speeds &
787 : : RTE_ETH_LINK_SPEED_FIXED);
788 : : ret = rte_eth_linkstatus_set(dev, &link);
789 : : if (ret == 0)
790 : 0 : PMD_DRV_LOG_LINE(ERR, "Link status changed");
791 : :
792 : 0 : return ret;
793 : : }
794 : :
795 : : static int
796 : 0 : axgbe_dev_get_regs(struct rte_eth_dev *dev, struct rte_dev_reg_info *regs)
797 : : {
798 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
799 : :
800 [ # # ]: 0 : if (regs->data == NULL) {
801 : 0 : regs->length = axgbe_regs_get_count(pdata);
802 : 0 : regs->width = sizeof(uint32_t);
803 : 0 : return 0;
804 : : }
805 : :
806 : : /* Only full register dump is supported */
807 [ # # ]: 0 : if (regs->length &&
808 [ # # ]: 0 : regs->length != (uint32_t)axgbe_regs_get_count(pdata))
809 : : return -ENOTSUP;
810 : :
811 : 0 : regs->version = pdata->pci_dev->id.vendor_id << 16 |
812 : 0 : pdata->pci_dev->id.device_id;
813 : 0 : axgbe_regs_dump(pdata, regs->data);
814 : 0 : return 0;
815 : : }
816 : 0 : static void axgbe_read_mmc_stats(struct axgbe_port *pdata)
817 : : {
818 : : struct axgbe_mmc_stats *stats = &pdata->mmc_stats;
819 : :
820 : : /* Freeze counters */
821 : 0 : AXGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 1);
822 : :
823 : : /* Tx counters */
824 : 0 : stats->txoctetcount_gb +=
825 : 0 : AXGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_GB_LO);
826 : 0 : stats->txoctetcount_gb +=
827 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_GB_HI) << 32);
828 : :
829 : 0 : stats->txframecount_gb +=
830 : 0 : AXGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_GB_LO);
831 : 0 : stats->txframecount_gb +=
832 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_GB_HI) << 32);
833 : :
834 : 0 : stats->txbroadcastframes_g +=
835 : 0 : AXGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_G_LO);
836 : 0 : stats->txbroadcastframes_g +=
837 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_G_HI) << 32);
838 : :
839 : 0 : stats->txmulticastframes_g +=
840 : 0 : AXGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_G_LO);
841 : 0 : stats->txmulticastframes_g +=
842 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_G_HI) << 32);
843 : :
844 : 0 : stats->tx64octets_gb +=
845 : 0 : AXGMAC_IOREAD(pdata, MMC_TX64OCTETS_GB_LO);
846 : 0 : stats->tx64octets_gb +=
847 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX64OCTETS_GB_HI) << 32);
848 : :
849 : 0 : stats->tx65to127octets_gb +=
850 : 0 : AXGMAC_IOREAD(pdata, MMC_TX65TO127OCTETS_GB_LO);
851 : 0 : stats->tx65to127octets_gb +=
852 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX65TO127OCTETS_GB_HI) << 32);
853 : :
854 : 0 : stats->tx128to255octets_gb +=
855 : 0 : AXGMAC_IOREAD(pdata, MMC_TX128TO255OCTETS_GB_LO);
856 : 0 : stats->tx128to255octets_gb +=
857 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX128TO255OCTETS_GB_HI) << 32);
858 : :
859 : 0 : stats->tx256to511octets_gb +=
860 : 0 : AXGMAC_IOREAD(pdata, MMC_TX256TO511OCTETS_GB_LO);
861 : 0 : stats->tx256to511octets_gb +=
862 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX256TO511OCTETS_GB_HI) << 32);
863 : :
864 : 0 : stats->tx512to1023octets_gb +=
865 : 0 : AXGMAC_IOREAD(pdata, MMC_TX512TO1023OCTETS_GB_LO);
866 : 0 : stats->tx512to1023octets_gb +=
867 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX512TO1023OCTETS_GB_HI) << 32);
868 : :
869 : 0 : stats->tx1024tomaxoctets_gb +=
870 : 0 : AXGMAC_IOREAD(pdata, MMC_TX1024TOMAXOCTETS_GB_LO);
871 : 0 : stats->tx1024tomaxoctets_gb +=
872 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX1024TOMAXOCTETS_GB_HI) << 32);
873 : :
874 : 0 : stats->txunicastframes_gb +=
875 : 0 : AXGMAC_IOREAD(pdata, MMC_TXUNICASTFRAMES_GB_LO);
876 : 0 : stats->txunicastframes_gb +=
877 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXUNICASTFRAMES_GB_HI) << 32);
878 : :
879 : 0 : stats->txmulticastframes_gb +=
880 : 0 : AXGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_GB_LO);
881 : 0 : stats->txmulticastframes_gb +=
882 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_GB_HI) << 32);
883 : :
884 : 0 : stats->txbroadcastframes_g +=
885 : 0 : AXGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_GB_LO);
886 : 0 : stats->txbroadcastframes_g +=
887 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_GB_HI) << 32);
888 : :
889 : 0 : stats->txunderflowerror +=
890 : 0 : AXGMAC_IOREAD(pdata, MMC_TXUNDERFLOWERROR_LO);
891 : 0 : stats->txunderflowerror +=
892 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXUNDERFLOWERROR_HI) << 32);
893 : :
894 : 0 : stats->txoctetcount_g +=
895 : 0 : AXGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_G_LO);
896 : 0 : stats->txoctetcount_g +=
897 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_G_HI) << 32);
898 : :
899 : 0 : stats->txframecount_g +=
900 : 0 : AXGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_G_LO);
901 : 0 : stats->txframecount_g +=
902 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_G_HI) << 32);
903 : :
904 : 0 : stats->txpauseframes +=
905 : 0 : AXGMAC_IOREAD(pdata, MMC_TXPAUSEFRAMES_LO);
906 : 0 : stats->txpauseframes +=
907 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXPAUSEFRAMES_HI) << 32);
908 : :
909 : 0 : stats->txvlanframes_g +=
910 : 0 : AXGMAC_IOREAD(pdata, MMC_TXVLANFRAMES_G_LO);
911 : 0 : stats->txvlanframes_g +=
912 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXVLANFRAMES_G_HI) << 32);
913 : :
914 : : /* Rx counters */
915 : 0 : stats->rxframecount_gb +=
916 : 0 : AXGMAC_IOREAD(pdata, MMC_RXFRAMECOUNT_GB_LO);
917 : 0 : stats->rxframecount_gb +=
918 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXFRAMECOUNT_GB_HI) << 32);
919 : :
920 : 0 : stats->rxoctetcount_gb +=
921 : 0 : AXGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_GB_LO);
922 : 0 : stats->rxoctetcount_gb +=
923 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_GB_HI) << 32);
924 : :
925 : 0 : stats->rxoctetcount_g +=
926 : 0 : AXGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_G_LO);
927 : 0 : stats->rxoctetcount_g +=
928 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_G_HI) << 32);
929 : :
930 : 0 : stats->rxbroadcastframes_g +=
931 : 0 : AXGMAC_IOREAD(pdata, MMC_RXBROADCASTFRAMES_G_LO);
932 : 0 : stats->rxbroadcastframes_g +=
933 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXBROADCASTFRAMES_G_HI) << 32);
934 : :
935 : 0 : stats->rxmulticastframes_g +=
936 : 0 : AXGMAC_IOREAD(pdata, MMC_RXMULTICASTFRAMES_G_LO);
937 : 0 : stats->rxmulticastframes_g +=
938 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXMULTICASTFRAMES_G_HI) << 32);
939 : :
940 : 0 : stats->rxcrcerror +=
941 : 0 : AXGMAC_IOREAD(pdata, MMC_RXCRCERROR_LO);
942 : 0 : stats->rxcrcerror +=
943 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXCRCERROR_HI) << 32);
944 : :
945 : 0 : stats->rxrunterror +=
946 : 0 : AXGMAC_IOREAD(pdata, MMC_RXRUNTERROR);
947 : :
948 : 0 : stats->rxjabbererror +=
949 : 0 : AXGMAC_IOREAD(pdata, MMC_RXJABBERERROR);
950 : :
951 : 0 : stats->rxundersize_g +=
952 : 0 : AXGMAC_IOREAD(pdata, MMC_RXUNDERSIZE_G);
953 : :
954 : 0 : stats->rxoversize_g +=
955 : 0 : AXGMAC_IOREAD(pdata, MMC_RXOVERSIZE_G);
956 : :
957 : 0 : stats->rx64octets_gb +=
958 : 0 : AXGMAC_IOREAD(pdata, MMC_RX64OCTETS_GB_LO);
959 : 0 : stats->rx64octets_gb +=
960 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX64OCTETS_GB_HI) << 32);
961 : :
962 : 0 : stats->rx65to127octets_gb +=
963 : 0 : AXGMAC_IOREAD(pdata, MMC_RX65TO127OCTETS_GB_LO);
964 : 0 : stats->rx65to127octets_gb +=
965 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX65TO127OCTETS_GB_HI) << 32);
966 : :
967 : 0 : stats->rx128to255octets_gb +=
968 : 0 : AXGMAC_IOREAD(pdata, MMC_RX128TO255OCTETS_GB_LO);
969 : 0 : stats->rx128to255octets_gb +=
970 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX128TO255OCTETS_GB_HI) << 32);
971 : :
972 : 0 : stats->rx256to511octets_gb +=
973 : 0 : AXGMAC_IOREAD(pdata, MMC_RX256TO511OCTETS_GB_LO);
974 : 0 : stats->rx256to511octets_gb +=
975 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX256TO511OCTETS_GB_HI) << 32);
976 : :
977 : 0 : stats->rx512to1023octets_gb +=
978 : 0 : AXGMAC_IOREAD(pdata, MMC_RX512TO1023OCTETS_GB_LO);
979 : 0 : stats->rx512to1023octets_gb +=
980 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX512TO1023OCTETS_GB_HI) << 32);
981 : :
982 : 0 : stats->rx1024tomaxoctets_gb +=
983 : 0 : AXGMAC_IOREAD(pdata, MMC_RX1024TOMAXOCTETS_GB_LO);
984 : 0 : stats->rx1024tomaxoctets_gb +=
985 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX1024TOMAXOCTETS_GB_HI) << 32);
986 : :
987 : 0 : stats->rxunicastframes_g +=
988 : 0 : AXGMAC_IOREAD(pdata, MMC_RXUNICASTFRAMES_G_LO);
989 : 0 : stats->rxunicastframes_g +=
990 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXUNICASTFRAMES_G_HI) << 32);
991 : :
992 : 0 : stats->rxlengtherror +=
993 : 0 : AXGMAC_IOREAD(pdata, MMC_RXLENGTHERROR_LO);
994 : 0 : stats->rxlengtherror +=
995 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXLENGTHERROR_HI) << 32);
996 : :
997 : 0 : stats->rxoutofrangetype +=
998 : 0 : AXGMAC_IOREAD(pdata, MMC_RXOUTOFRANGETYPE_LO);
999 : 0 : stats->rxoutofrangetype +=
1000 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXOUTOFRANGETYPE_HI) << 32);
1001 : :
1002 : 0 : stats->rxpauseframes +=
1003 : 0 : AXGMAC_IOREAD(pdata, MMC_RXPAUSEFRAMES_LO);
1004 : 0 : stats->rxpauseframes +=
1005 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXPAUSEFRAMES_HI) << 32);
1006 : :
1007 : 0 : stats->rxfifooverflow +=
1008 : 0 : AXGMAC_IOREAD(pdata, MMC_RXFIFOOVERFLOW_LO);
1009 : 0 : stats->rxfifooverflow +=
1010 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXFIFOOVERFLOW_HI) << 32);
1011 : :
1012 : 0 : stats->rxvlanframes_gb +=
1013 : 0 : AXGMAC_IOREAD(pdata, MMC_RXVLANFRAMES_GB_LO);
1014 : 0 : stats->rxvlanframes_gb +=
1015 : 0 : ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXVLANFRAMES_GB_HI) << 32);
1016 : :
1017 : 0 : stats->rxwatchdogerror +=
1018 : 0 : AXGMAC_IOREAD(pdata, MMC_RXWATCHDOGERROR);
1019 : :
1020 : : /* Un-freeze counters */
1021 : 0 : AXGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 0);
1022 : 0 : }
1023 : :
1024 : : static int
1025 : 0 : axgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats,
1026 : : unsigned int n)
1027 : : {
1028 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1029 : : unsigned int i;
1030 : :
1031 [ # # ]: 0 : if (n < AXGBE_XSTATS_COUNT)
1032 : : return AXGBE_XSTATS_COUNT;
1033 : :
1034 : 0 : axgbe_read_mmc_stats(pdata);
1035 : :
1036 [ # # ]: 0 : for (i = 0; i < AXGBE_XSTATS_COUNT; i++) {
1037 : 0 : stats[i].id = i;
1038 : 0 : stats[i].value = *(u64 *)((uint8_t *)&pdata->mmc_stats +
1039 : 0 : axgbe_xstats_strings[i].offset);
1040 : : }
1041 : :
1042 : : return AXGBE_XSTATS_COUNT;
1043 : : }
1044 : :
1045 : : static int
1046 : 0 : axgbe_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
1047 : : struct rte_eth_xstat_name *xstats_names,
1048 : : unsigned int n)
1049 : : {
1050 : : unsigned int i;
1051 : :
1052 [ # # ]: 0 : if (n >= AXGBE_XSTATS_COUNT && xstats_names) {
1053 [ # # ]: 0 : for (i = 0; i < AXGBE_XSTATS_COUNT; ++i) {
1054 : 0 : snprintf(xstats_names[i].name,
1055 : : RTE_ETH_XSTATS_NAME_SIZE, "%s",
1056 : 0 : axgbe_xstats_strings[i].name);
1057 : : }
1058 : : }
1059 : :
1060 : 0 : return AXGBE_XSTATS_COUNT;
1061 : : }
1062 : :
1063 : : static int
1064 : 0 : axgbe_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
1065 : : uint64_t *values, unsigned int n)
1066 : : {
1067 : : unsigned int i;
1068 : : uint64_t values_copy[AXGBE_XSTATS_COUNT];
1069 : :
1070 [ # # ]: 0 : if (!ids) {
1071 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1072 : :
1073 [ # # ]: 0 : if (n < AXGBE_XSTATS_COUNT)
1074 : : return AXGBE_XSTATS_COUNT;
1075 : :
1076 : 0 : axgbe_read_mmc_stats(pdata);
1077 : :
1078 [ # # ]: 0 : for (i = 0; i < AXGBE_XSTATS_COUNT; i++) {
1079 : 0 : values[i] = *(u64 *)((uint8_t *)&pdata->mmc_stats +
1080 : 0 : axgbe_xstats_strings[i].offset);
1081 : : }
1082 : :
1083 : : return i;
1084 : : }
1085 : :
1086 : 0 : axgbe_dev_xstats_get_by_id(dev, NULL, values_copy, AXGBE_XSTATS_COUNT);
1087 : :
1088 [ # # ]: 0 : for (i = 0; i < n; i++) {
1089 [ # # ]: 0 : if (ids[i] >= AXGBE_XSTATS_COUNT) {
1090 : 0 : PMD_DRV_LOG_LINE(ERR, "id value isn't valid");
1091 : 0 : return -1;
1092 : : }
1093 : 0 : values[i] = values_copy[ids[i]];
1094 : : }
1095 : 0 : return n;
1096 : : }
1097 : :
1098 : : static int
1099 : 0 : axgbe_dev_xstats_get_names_by_id(struct rte_eth_dev *dev,
1100 : : const uint64_t *ids,
1101 : : struct rte_eth_xstat_name *xstats_names,
1102 : : unsigned int size)
1103 : : {
1104 : : struct rte_eth_xstat_name xstats_names_copy[AXGBE_XSTATS_COUNT];
1105 : : unsigned int i;
1106 : :
1107 [ # # ]: 0 : if (!ids)
1108 : 0 : return axgbe_dev_xstats_get_names(dev, xstats_names, size);
1109 : :
1110 : 0 : axgbe_dev_xstats_get_names(dev, xstats_names_copy, size);
1111 : :
1112 [ # # ]: 0 : for (i = 0; i < size; i++) {
1113 [ # # ]: 0 : if (ids[i] >= AXGBE_XSTATS_COUNT) {
1114 : 0 : PMD_DRV_LOG_LINE(ERR, "id value isn't valid");
1115 : 0 : return -1;
1116 : : }
1117 : 0 : strcpy(xstats_names[i].name, xstats_names_copy[ids[i]].name);
1118 : : }
1119 : 0 : return size;
1120 : : }
1121 : :
1122 : : static int
1123 : 0 : axgbe_dev_xstats_reset(struct rte_eth_dev *dev)
1124 : : {
1125 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1126 : 0 : struct axgbe_mmc_stats *stats = &pdata->mmc_stats;
1127 : :
1128 : : /* MMC registers are configured for reset on read */
1129 : 0 : axgbe_read_mmc_stats(pdata);
1130 : :
1131 : : /* Reset stats */
1132 : : memset(stats, 0, sizeof(*stats));
1133 : :
1134 : 0 : return 0;
1135 : : }
1136 : :
1137 : : static int
1138 : 0 : axgbe_dev_stats_get(struct rte_eth_dev *dev,
1139 : : struct rte_eth_stats *stats, struct eth_queue_stats *qstats)
1140 : : {
1141 : : struct axgbe_rx_queue *rxq;
1142 : : struct axgbe_tx_queue *txq;
1143 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1144 : : struct axgbe_mmc_stats *mmc_stats = &pdata->mmc_stats;
1145 : : unsigned int i;
1146 : :
1147 : 0 : axgbe_read_mmc_stats(pdata);
1148 : :
1149 : 0 : stats->imissed = mmc_stats->rxfifooverflow;
1150 : :
1151 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
1152 : 0 : rxq = dev->data->rx_queues[i];
1153 [ # # ]: 0 : if (rxq) {
1154 : 0 : stats->ipackets += rxq->pkts;
1155 : 0 : stats->ibytes += rxq->bytes;
1156 : 0 : stats->rx_nombuf += rxq->rx_mbuf_alloc_failed;
1157 : 0 : stats->ierrors += rxq->errors;
1158 : :
1159 [ # # ]: 0 : if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
1160 : 0 : qstats->q_ipackets[i] = rxq->pkts;
1161 : 0 : qstats->q_ibytes[i] = rxq->bytes;
1162 : 0 : qstats->q_errors[i] = rxq->errors + rxq->rx_mbuf_alloc_failed;
1163 : : }
1164 : : } else {
1165 : 0 : PMD_DRV_LOG_LINE(DEBUG, "Rx queue not setup for port %d",
1166 : : dev->data->port_id);
1167 : : }
1168 : : }
1169 : :
1170 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
1171 : 0 : txq = dev->data->tx_queues[i];
1172 [ # # ]: 0 : if (txq) {
1173 : 0 : stats->opackets += txq->pkts;
1174 : 0 : stats->obytes += txq->bytes;
1175 : 0 : stats->oerrors += txq->errors;
1176 : :
1177 [ # # ]: 0 : if (qstats != NULL && i < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
1178 : 0 : qstats->q_opackets[i] = txq->pkts;
1179 : 0 : qstats->q_obytes[i] = txq->bytes;
1180 : : }
1181 : : } else {
1182 : 0 : PMD_DRV_LOG_LINE(DEBUG, "Tx queue not setup for port %d",
1183 : : dev->data->port_id);
1184 : : }
1185 : : }
1186 : :
1187 : 0 : return 0;
1188 : : }
1189 : :
1190 : : static int
1191 : 0 : axgbe_dev_stats_reset(struct rte_eth_dev *dev)
1192 : : {
1193 : : struct axgbe_rx_queue *rxq;
1194 : : struct axgbe_tx_queue *txq;
1195 : : unsigned int i;
1196 : :
1197 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
1198 : 0 : rxq = dev->data->rx_queues[i];
1199 [ # # ]: 0 : if (rxq) {
1200 : 0 : rxq->pkts = 0;
1201 : 0 : rxq->bytes = 0;
1202 : 0 : rxq->errors = 0;
1203 : 0 : rxq->rx_mbuf_alloc_failed = 0;
1204 : : } else {
1205 : 0 : PMD_DRV_LOG_LINE(DEBUG, "Rx queue not setup for port %d",
1206 : : dev->data->port_id);
1207 : : }
1208 : : }
1209 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
1210 : 0 : txq = dev->data->tx_queues[i];
1211 [ # # ]: 0 : if (txq) {
1212 : 0 : txq->pkts = 0;
1213 : 0 : txq->bytes = 0;
1214 : 0 : txq->errors = 0;
1215 : : } else {
1216 : 0 : PMD_DRV_LOG_LINE(DEBUG, "Tx queue not setup for port %d",
1217 : : dev->data->port_id);
1218 : : }
1219 : : }
1220 : :
1221 : 0 : return 0;
1222 : : }
1223 : :
1224 : : static int
1225 : 0 : axgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
1226 : : {
1227 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1228 : :
1229 : 0 : dev_info->max_rx_queues = pdata->rx_ring_count;
1230 : 0 : dev_info->max_tx_queues = pdata->tx_ring_count;
1231 : 0 : dev_info->min_rx_bufsize = AXGBE_RX_MIN_BUF_SIZE;
1232 : 0 : dev_info->max_rx_pktlen = AXGBE_RX_MAX_BUF_SIZE;
1233 : 0 : dev_info->max_mac_addrs = pdata->hw_feat.addn_mac + 1;
1234 : 0 : dev_info->max_hash_mac_addrs = pdata->hw_feat.hash_table_size;
1235 : 0 : dev_info->speed_capa = RTE_ETH_LINK_SPEED_10G;
1236 : :
1237 : 0 : dev_info->rx_offload_capa =
1238 : : RTE_ETH_RX_OFFLOAD_VLAN_STRIP |
1239 : : RTE_ETH_RX_OFFLOAD_VLAN_FILTER |
1240 : : RTE_ETH_RX_OFFLOAD_VLAN_EXTEND |
1241 : : RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
1242 : : RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
1243 : : RTE_ETH_RX_OFFLOAD_TCP_CKSUM |
1244 : : RTE_ETH_RX_OFFLOAD_SCATTER |
1245 : : RTE_ETH_RX_OFFLOAD_KEEP_CRC;
1246 : :
1247 : 0 : dev_info->tx_offload_capa =
1248 : : RTE_ETH_TX_OFFLOAD_VLAN_INSERT |
1249 : : RTE_ETH_TX_OFFLOAD_QINQ_INSERT |
1250 : : RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
1251 : : RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
1252 : : RTE_ETH_TX_OFFLOAD_TCP_TSO |
1253 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
1254 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM;
1255 : :
1256 [ # # ]: 0 : if (pdata->hw_feat.rss) {
1257 : 0 : dev_info->flow_type_rss_offloads = AXGBE_RSS_OFFLOAD;
1258 : 0 : dev_info->reta_size = pdata->hw_feat.hash_table_size;
1259 : 0 : dev_info->hash_key_size = AXGBE_RSS_HASH_KEY_SIZE;
1260 : : }
1261 : :
1262 : 0 : dev_info->rx_desc_lim = rx_desc_lim;
1263 : 0 : dev_info->tx_desc_lim = tx_desc_lim;
1264 : :
1265 : 0 : dev_info->default_rxconf = (struct rte_eth_rxconf) {
1266 : : .rx_free_thresh = AXGBE_RX_FREE_THRESH,
1267 : : };
1268 : :
1269 : 0 : dev_info->default_txconf = (struct rte_eth_txconf) {
1270 : : .tx_free_thresh = AXGBE_TX_FREE_THRESH,
1271 : : };
1272 : :
1273 : 0 : return 0;
1274 : : }
1275 : :
1276 : : static int
1277 : 0 : axgbe_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
1278 : : {
1279 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1280 : 0 : struct xgbe_fc_info fc = pdata->fc;
1281 : : unsigned int reg, reg_val = 0;
1282 : :
1283 : : reg = MAC_Q0TFCR;
1284 : 0 : reg_val = AXGMAC_IOREAD(pdata, reg);
1285 : 0 : fc.low_water[0] = AXGMAC_MTL_IOREAD_BITS(pdata, 0, MTL_Q_RQFCR, RFA);
1286 : 0 : fc.high_water[0] = AXGMAC_MTL_IOREAD_BITS(pdata, 0, MTL_Q_RQFCR, RFD);
1287 : 0 : fc.pause_time[0] = AXGMAC_GET_BITS(reg_val, MAC_Q0TFCR, PT);
1288 : : fc.autoneg = pdata->pause_autoneg;
1289 : :
1290 [ # # # # ]: 0 : if (pdata->rx_pause && pdata->tx_pause)
1291 : : fc.mode = RTE_ETH_FC_FULL;
1292 [ # # ]: 0 : else if (pdata->rx_pause)
1293 : : fc.mode = RTE_ETH_FC_RX_PAUSE;
1294 [ # # ]: 0 : else if (pdata->tx_pause)
1295 : : fc.mode = RTE_ETH_FC_TX_PAUSE;
1296 : : else
1297 : : fc.mode = RTE_ETH_FC_NONE;
1298 : :
1299 : 0 : fc_conf->high_water = (1024 + (fc.low_water[0] << 9)) / 1024;
1300 : 0 : fc_conf->low_water = (1024 + (fc.high_water[0] << 9)) / 1024;
1301 : 0 : fc_conf->pause_time = fc.pause_time[0];
1302 : 0 : fc_conf->send_xon = fc.send_xon;
1303 : 0 : fc_conf->mode = fc.mode;
1304 : :
1305 : 0 : return 0;
1306 : : }
1307 : :
1308 : : static int
1309 : 0 : axgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
1310 : : {
1311 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1312 : : struct xgbe_fc_info fc = pdata->fc;
1313 : : unsigned int reg, reg_val = 0;
1314 : : reg = MAC_Q0TFCR;
1315 : :
1316 : 0 : pdata->pause_autoneg = fc_conf->autoneg;
1317 : 0 : pdata->phy.pause_autoneg = pdata->pause_autoneg;
1318 : : fc.send_xon = fc_conf->send_xon;
1319 [ # # ]: 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, 0, MTL_Q_RQFCR, RFA,
1320 : : AXGMAC_FLOW_CONTROL_VALUE(1024 * fc_conf->high_water));
1321 [ # # ]: 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, 0, MTL_Q_RQFCR, RFD,
1322 : : AXGMAC_FLOW_CONTROL_VALUE(1024 * fc_conf->low_water));
1323 : 0 : AXGMAC_SET_BITS(reg_val, MAC_Q0TFCR, PT, fc_conf->pause_time);
1324 : 0 : AXGMAC_IOWRITE(pdata, reg, reg_val);
1325 : 0 : fc.mode = fc_conf->mode;
1326 : :
1327 [ # # ]: 0 : if (fc.mode == RTE_ETH_FC_FULL) {
1328 : 0 : pdata->tx_pause = 1;
1329 : 0 : pdata->rx_pause = 1;
1330 [ # # ]: 0 : } else if (fc.mode == RTE_ETH_FC_RX_PAUSE) {
1331 : 0 : pdata->tx_pause = 0;
1332 : 0 : pdata->rx_pause = 1;
1333 [ # # ]: 0 : } else if (fc.mode == RTE_ETH_FC_TX_PAUSE) {
1334 : 0 : pdata->tx_pause = 1;
1335 : 0 : pdata->rx_pause = 0;
1336 : : } else {
1337 : 0 : pdata->tx_pause = 0;
1338 : 0 : pdata->rx_pause = 0;
1339 : : }
1340 : :
1341 [ # # ]: 0 : if (pdata->tx_pause != (unsigned int)pdata->phy.tx_pause)
1342 : 0 : pdata->hw_if.config_tx_flow_control(pdata);
1343 : :
1344 [ # # ]: 0 : if (pdata->rx_pause != (unsigned int)pdata->phy.rx_pause)
1345 : 0 : pdata->hw_if.config_rx_flow_control(pdata);
1346 : :
1347 : 0 : pdata->hw_if.config_flow_control(pdata);
1348 : 0 : pdata->phy.tx_pause = pdata->tx_pause;
1349 : 0 : pdata->phy.rx_pause = pdata->rx_pause;
1350 : :
1351 : 0 : return 0;
1352 : : }
1353 : :
1354 : : static int
1355 : 0 : axgbe_priority_flow_ctrl_set(struct rte_eth_dev *dev,
1356 : : struct rte_eth_pfc_conf *pfc_conf)
1357 : : {
1358 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1359 : : struct xgbe_fc_info fc = pdata->fc;
1360 : : uint8_t tc_num;
1361 : :
1362 : 0 : tc_num = pdata->pfc_map[pfc_conf->priority];
1363 : :
1364 [ # # ]: 0 : if (pfc_conf->priority >= pdata->hw_feat.tc_cnt) {
1365 : 0 : PMD_INIT_LOG(ERR, "Max supported traffic class: %d",
1366 : : pdata->hw_feat.tc_cnt);
1367 : 0 : return -EINVAL;
1368 : : }
1369 : :
1370 : 0 : pdata->pause_autoneg = pfc_conf->fc.autoneg;
1371 : 0 : pdata->phy.pause_autoneg = pdata->pause_autoneg;
1372 : : fc.send_xon = pfc_conf->fc.send_xon;
1373 [ # # ]: 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, tc_num, MTL_Q_RQFCR, RFA,
1374 : : AXGMAC_FLOW_CONTROL_VALUE(1024 * pfc_conf->fc.high_water));
1375 [ # # ]: 0 : AXGMAC_MTL_IOWRITE_BITS(pdata, tc_num, MTL_Q_RQFCR, RFD,
1376 : : AXGMAC_FLOW_CONTROL_VALUE(1024 * pfc_conf->fc.low_water));
1377 : :
1378 [ # # # # : 0 : switch (tc_num) {
# # # #
# ]
1379 : 0 : case 0:
1380 : 0 : AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM0R,
1381 : : PSTC0, pfc_conf->fc.pause_time);
1382 : : break;
1383 : 0 : case 1:
1384 : 0 : AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM0R,
1385 : : PSTC1, pfc_conf->fc.pause_time);
1386 : : break;
1387 : 0 : case 2:
1388 : 0 : AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM0R,
1389 : : PSTC2, pfc_conf->fc.pause_time);
1390 : : break;
1391 : 0 : case 3:
1392 : 0 : AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM0R,
1393 : : PSTC3, pfc_conf->fc.pause_time);
1394 : : break;
1395 : 0 : case 4:
1396 : 0 : AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM1R,
1397 : : PSTC4, pfc_conf->fc.pause_time);
1398 : : break;
1399 : 0 : case 5:
1400 : 0 : AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM1R,
1401 : : PSTC5, pfc_conf->fc.pause_time);
1402 : : break;
1403 : 0 : case 7:
1404 : 0 : AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM1R,
1405 : : PSTC6, pfc_conf->fc.pause_time);
1406 : : break;
1407 : 0 : case 6:
1408 : 0 : AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM1R,
1409 : : PSTC7, pfc_conf->fc.pause_time);
1410 : : break;
1411 : : }
1412 : :
1413 : 0 : fc.mode = pfc_conf->fc.mode;
1414 : :
1415 [ # # ]: 0 : if (fc.mode == RTE_ETH_FC_FULL) {
1416 : 0 : pdata->tx_pause = 1;
1417 : 0 : pdata->rx_pause = 1;
1418 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 1);
1419 [ # # ]: 0 : } else if (fc.mode == RTE_ETH_FC_RX_PAUSE) {
1420 : 0 : pdata->tx_pause = 0;
1421 : 0 : pdata->rx_pause = 1;
1422 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 1);
1423 [ # # ]: 0 : } else if (fc.mode == RTE_ETH_FC_TX_PAUSE) {
1424 : 0 : pdata->tx_pause = 1;
1425 : 0 : pdata->rx_pause = 0;
1426 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 0);
1427 : : } else {
1428 : 0 : pdata->tx_pause = 0;
1429 : 0 : pdata->rx_pause = 0;
1430 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 0);
1431 : : }
1432 : :
1433 [ # # ]: 0 : if (pdata->tx_pause != (unsigned int)pdata->phy.tx_pause)
1434 : 0 : pdata->hw_if.config_tx_flow_control(pdata);
1435 : :
1436 [ # # ]: 0 : if (pdata->rx_pause != (unsigned int)pdata->phy.rx_pause)
1437 : 0 : pdata->hw_if.config_rx_flow_control(pdata);
1438 : 0 : pdata->hw_if.config_flow_control(pdata);
1439 : 0 : pdata->phy.tx_pause = pdata->tx_pause;
1440 : 0 : pdata->phy.rx_pause = pdata->rx_pause;
1441 : :
1442 : 0 : return 0;
1443 : : }
1444 : :
1445 : : void
1446 : 0 : axgbe_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
1447 : : struct rte_eth_rxq_info *qinfo)
1448 : : {
1449 : : struct axgbe_rx_queue *rxq;
1450 : :
1451 : 0 : rxq = dev->data->rx_queues[queue_id];
1452 : 0 : qinfo->mp = rxq->mb_pool;
1453 : 0 : qinfo->scattered_rx = dev->data->scattered_rx;
1454 : 0 : qinfo->nb_desc = rxq->nb_desc;
1455 : 0 : qinfo->conf.rx_free_thresh = rxq->free_thresh;
1456 : 0 : }
1457 : :
1458 : : void
1459 : 0 : axgbe_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
1460 : : struct rte_eth_txq_info *qinfo)
1461 : : {
1462 : : struct axgbe_tx_queue *txq;
1463 : :
1464 : 0 : txq = dev->data->tx_queues[queue_id];
1465 : 0 : qinfo->nb_desc = txq->nb_desc;
1466 : 0 : qinfo->conf.tx_free_thresh = txq->free_thresh;
1467 : 0 : }
1468 : : const uint32_t *
1469 : 0 : axgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev, size_t *no_of_elements)
1470 : : {
1471 : : static const uint32_t ptypes[] = {
1472 : : RTE_PTYPE_L2_ETHER,
1473 : : RTE_PTYPE_L2_ETHER_TIMESYNC,
1474 : : RTE_PTYPE_L2_ETHER_LLDP,
1475 : : RTE_PTYPE_L2_ETHER_ARP,
1476 : : RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
1477 : : RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
1478 : : RTE_PTYPE_L4_FRAG,
1479 : : RTE_PTYPE_L4_ICMP,
1480 : : RTE_PTYPE_L4_NONFRAG,
1481 : : RTE_PTYPE_L4_SCTP,
1482 : : RTE_PTYPE_L4_TCP,
1483 : : RTE_PTYPE_L4_UDP,
1484 : : RTE_PTYPE_TUNNEL_GRENAT,
1485 : : RTE_PTYPE_TUNNEL_IP,
1486 : : RTE_PTYPE_INNER_L2_ETHER,
1487 : : RTE_PTYPE_INNER_L2_ETHER_VLAN,
1488 : : RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
1489 : : RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
1490 : : RTE_PTYPE_INNER_L4_FRAG,
1491 : : RTE_PTYPE_INNER_L4_ICMP,
1492 : : RTE_PTYPE_INNER_L4_NONFRAG,
1493 : : RTE_PTYPE_INNER_L4_SCTP,
1494 : : RTE_PTYPE_INNER_L4_TCP,
1495 : : RTE_PTYPE_INNER_L4_UDP,
1496 : : };
1497 : :
1498 [ # # ]: 0 : if (dev->rx_pkt_burst == axgbe_recv_pkts) {
1499 : 0 : *no_of_elements = RTE_DIM(ptypes);
1500 : 0 : return ptypes;
1501 : : }
1502 : : return NULL;
1503 : : }
1504 : :
1505 : 0 : static int axgb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
1506 : : {
1507 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1508 : : unsigned int val;
1509 : :
1510 : : /* mtu setting is forbidden if port is start */
1511 [ # # ]: 0 : if (dev->data->dev_started) {
1512 : 0 : PMD_DRV_LOG_LINE(ERR, "port %d must be stopped before configuration",
1513 : : dev->data->port_id);
1514 : 0 : return -EBUSY;
1515 : : }
1516 : 0 : val = mtu > RTE_ETHER_MTU ? 1 : 0;
1517 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_RCR, JE, val);
1518 : :
1519 : 0 : return 0;
1520 : : }
1521 : :
1522 : : static void
1523 : 0 : axgbe_update_tstamp_time(struct axgbe_port *pdata,
1524 : : unsigned int sec, unsigned int nsec, int addsub)
1525 : : {
1526 : : unsigned int count = 100;
1527 : : uint32_t sub_val = 0;
1528 : : uint32_t sub_val_sec = 0xFFFFFFFF;
1529 : : uint32_t sub_val_nsec = 0x3B9ACA00;
1530 : :
1531 [ # # ]: 0 : if (addsub) {
1532 [ # # ]: 0 : if (sec)
1533 : 0 : sub_val = sub_val_sec - (sec - 1);
1534 : : else
1535 : : sub_val = sec;
1536 : :
1537 : 0 : AXGMAC_IOWRITE(pdata, MAC_STSUR, sub_val);
1538 : 0 : sub_val = sub_val_nsec - nsec;
1539 : 0 : AXGMAC_IOWRITE(pdata, MAC_STNUR, sub_val);
1540 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_STNUR, ADDSUB, 1);
1541 : : } else {
1542 : 0 : AXGMAC_IOWRITE(pdata, MAC_STSUR, sec);
1543 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_STNUR, ADDSUB, 0);
1544 : 0 : AXGMAC_IOWRITE(pdata, MAC_STNUR, nsec);
1545 : : }
1546 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSUPDT, 1);
1547 : : /* Wait for time update to complete */
1548 [ # # # # ]: 0 : while (--count && AXGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSUPDT))
1549 : : rte_delay_ms(1);
1550 : 0 : }
1551 : :
1552 : : static inline uint64_t
1553 : : div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder)
1554 : : {
1555 : : *remainder = dividend % divisor;
1556 : 0 : return dividend / divisor;
1557 : : }
1558 : :
1559 : : static inline uint64_t
1560 : : div_u64(uint64_t dividend, uint32_t divisor)
1561 : : {
1562 : : uint32_t remainder;
1563 : : return div_u64_rem(dividend, divisor, &remainder);
1564 : : }
1565 : :
1566 : : static int
1567 : 0 : axgbe_adjfreq(struct axgbe_port *pdata, int64_t delta)
1568 : : {
1569 : : uint64_t adjust;
1570 : : uint32_t addend, diff;
1571 : : unsigned int neg_adjust = 0;
1572 : :
1573 [ # # ]: 0 : if (delta < 0) {
1574 : : neg_adjust = 1;
1575 : 0 : delta = -delta;
1576 : : }
1577 : 0 : adjust = (uint64_t)pdata->tstamp_addend;
1578 : 0 : adjust *= delta;
1579 : 0 : diff = (uint32_t)div_u64(adjust, 1000000000UL);
1580 [ # # ]: 0 : addend = (neg_adjust) ? pdata->tstamp_addend - diff :
1581 : : pdata->tstamp_addend + diff;
1582 : 0 : pdata->tstamp_addend = addend;
1583 : 0 : axgbe_update_tstamp_addend(pdata, addend);
1584 : 0 : return 0;
1585 : : }
1586 : :
1587 : : static int
1588 : 0 : axgbe_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta)
1589 : : {
1590 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1591 : : struct timespec timestamp_delta;
1592 : :
1593 : 0 : axgbe_adjfreq(pdata, delta);
1594 : 0 : pdata->systime_tc.nsec += delta;
1595 : :
1596 [ # # ]: 0 : if (delta < 0) {
1597 : 0 : delta = -delta;
1598 : 0 : timestamp_delta = rte_ns_to_timespec(delta);
1599 : 0 : axgbe_update_tstamp_time(pdata, timestamp_delta.tv_sec,
1600 : : timestamp_delta.tv_nsec, 1);
1601 : : } else {
1602 : : timestamp_delta = rte_ns_to_timespec(delta);
1603 : 0 : axgbe_update_tstamp_time(pdata, timestamp_delta.tv_sec,
1604 : : timestamp_delta.tv_nsec, 0);
1605 : : }
1606 : 0 : return 0;
1607 : : }
1608 : :
1609 : : static int
1610 : 0 : axgbe_timesync_read_time(struct rte_eth_dev *dev,
1611 : : struct timespec *timestamp)
1612 : : {
1613 : : uint64_t nsec;
1614 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1615 : :
1616 : 0 : nsec = AXGMAC_IOREAD(pdata, MAC_STSR);
1617 : 0 : nsec *= NSEC_PER_SEC;
1618 [ # # ]: 0 : nsec += AXGMAC_IOREAD(pdata, MAC_STNR);
1619 : 0 : *timestamp = rte_ns_to_timespec(nsec);
1620 : 0 : return 0;
1621 : : }
1622 : : static int
1623 : 0 : axgbe_timesync_write_time(struct rte_eth_dev *dev,
1624 : : const struct timespec *timestamp)
1625 : : {
1626 : : unsigned int count = 100;
1627 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1628 : :
1629 : 0 : AXGMAC_IOWRITE(pdata, MAC_STSUR, timestamp->tv_sec);
1630 : 0 : AXGMAC_IOWRITE(pdata, MAC_STNUR, timestamp->tv_nsec);
1631 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSUPDT, 1);
1632 : : /* Wait for time update to complete */
1633 [ # # # # ]: 0 : while (--count && AXGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSUPDT))
1634 : : rte_delay_ms(1);
1635 [ # # ]: 0 : if (!count)
1636 : 0 : PMD_DRV_LOG_LINE(ERR, "Timed out update timestamp");
1637 : 0 : return 0;
1638 : : }
1639 : :
1640 : : static void
1641 : 0 : axgbe_update_tstamp_addend(struct axgbe_port *pdata,
1642 : : uint32_t addend)
1643 : : {
1644 : : unsigned int count = 100;
1645 : :
1646 : 0 : AXGMAC_IOWRITE(pdata, MAC_TSAR, addend);
1647 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSADDREG, 1);
1648 : :
1649 : : /* Wait for addend update to complete */
1650 [ # # # # ]: 0 : while (--count && AXGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSADDREG))
1651 : : rte_delay_ms(1);
1652 [ # # ]: 0 : if (!count)
1653 : 0 : PMD_DRV_LOG_LINE(ERR, "Timed out updating timestamp addend register");
1654 : 0 : }
1655 : :
1656 : : static void
1657 : 0 : axgbe_set_tstamp_time(struct axgbe_port *pdata, unsigned int sec,
1658 : : unsigned int nsec)
1659 : : {
1660 : : unsigned int count = 100;
1661 : :
1662 : : /*System Time Sec Update*/
1663 : 0 : AXGMAC_IOWRITE(pdata, MAC_STSUR, sec);
1664 : : /*System Time nanoSec Update*/
1665 : 0 : AXGMAC_IOWRITE(pdata, MAC_STNUR, nsec);
1666 : : /*Initialize Timestamp*/
1667 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSINIT, 1);
1668 : :
1669 : : /* Wait for time update to complete */
1670 [ # # # # ]: 0 : while (--count && AXGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSINIT))
1671 : : rte_delay_ms(1);
1672 [ # # ]: 0 : if (!count)
1673 : 0 : PMD_DRV_LOG_LINE(ERR, "Timed out initializing timestamp");
1674 : 0 : }
1675 : :
1676 : : static int
1677 : 0 : axgbe_timesync_enable(struct rte_eth_dev *dev)
1678 : : {
1679 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1680 : : unsigned int mac_tscr = 0;
1681 : : uint64_t dividend;
1682 : : struct timespec timestamp;
1683 : : uint64_t nsec;
1684 : :
1685 : : /* Set one nano-second accuracy */
1686 : : AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSCTRLSSR, 1);
1687 : :
1688 : : /* Set fine timestamp update */
1689 : : AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSCFUPDT, 1);
1690 : :
1691 : : /* Overwrite earlier timestamps */
1692 : : AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TXTSSTSM, 1);
1693 : :
1694 : 0 : AXGMAC_IOWRITE(pdata, MAC_TSCR, mac_tscr);
1695 : :
1696 : : /* Enabling processing of ptp over eth pkt */
1697 : : AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1);
1698 : : AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
1699 : : /* Enable timestamp for all pkts*/
1700 : : AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENALL, 1);
1701 : :
1702 : : /* enabling timestamp */
1703 : : AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
1704 : 0 : AXGMAC_IOWRITE(pdata, MAC_TSCR, mac_tscr);
1705 : :
1706 : : /* Exit if timestamping is not enabled */
1707 : : if (!AXGMAC_GET_BITS(mac_tscr, MAC_TSCR, TSENA)) {
1708 : : PMD_DRV_LOG_LINE(ERR, "Exiting as timestamp is not enabled");
1709 : : return 0;
1710 : : }
1711 : :
1712 : : /* Sub-second Increment Value*/
1713 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_SSIR, SSINC, AXGBE_TSTAMP_SSINC);
1714 : : /* Sub-nanosecond Increment Value */
1715 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_SSIR, SNSINC, AXGBE_TSTAMP_SNSINC);
1716 : :
1717 : 0 : pdata->ptpclk_rate = AXGBE_V2_PTP_CLOCK_FREQ;
1718 : : dividend = 50000000;
1719 : : dividend <<= 32;
1720 : 0 : pdata->tstamp_addend = div_u64(dividend, pdata->ptpclk_rate);
1721 : :
1722 : 0 : axgbe_update_tstamp_addend(pdata, pdata->tstamp_addend);
1723 : 0 : axgbe_set_tstamp_time(pdata, 0, 0);
1724 : :
1725 : : /* Initialize the timecounter */
1726 : 0 : memset(&pdata->systime_tc, 0, sizeof(struct rte_timecounter));
1727 : :
1728 : 0 : pdata->systime_tc.cc_mask = AXGBE_CYCLECOUNTER_MASK;
1729 : : pdata->systime_tc.cc_shift = 0;
1730 : : pdata->systime_tc.nsec_mask = 0;
1731 : :
1732 : 0 : PMD_DRV_LOG_LINE(DEBUG, "Initializing system time counter with realtime");
1733 : :
1734 : : /* Updating the counter once with clock real time */
1735 : 0 : clock_gettime(CLOCK_REALTIME, ×tamp);
1736 : : nsec = rte_timespec_to_ns(×tamp);
1737 : : nsec = rte_timecounter_update(&pdata->systime_tc, nsec);
1738 : 0 : axgbe_set_tstamp_time(pdata, timestamp.tv_sec, timestamp.tv_nsec);
1739 : : return 0;
1740 : : }
1741 : :
1742 : : static int
1743 : 0 : axgbe_timesync_disable(struct rte_eth_dev *dev)
1744 : : {
1745 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1746 : : unsigned int mac_tscr = 0;
1747 : : unsigned int value = 0;
1748 : :
1749 : : /*disable timestamp for all pkts*/
1750 : : AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENALL, 0);
1751 : : /*disable the addened register*/
1752 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSADDREG, 0);
1753 : : /* disable timestamp update */
1754 : : AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSCFUPDT, 0);
1755 : : /*disable time stamp*/
1756 : : AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 0);
1757 : :
1758 : 0 : value = AXGMAC_IOREAD(pdata, MAC_TSCR);
1759 : : value |= mac_tscr;
1760 : 0 : AXGMAC_IOWRITE(pdata, MAC_TSCR, value);
1761 : :
1762 : 0 : return 0;
1763 : : }
1764 : :
1765 : : static int
1766 : 0 : axgbe_timesync_read_rx_timestamp(struct rte_eth_dev *dev,
1767 : : struct timespec *timestamp, uint32_t flags)
1768 : : {
1769 : : uint64_t nsec = 0;
1770 : : volatile union axgbe_rx_desc *desc;
1771 : : uint16_t idx, pmt;
1772 : 0 : struct axgbe_rx_queue *rxq = *dev->data->rx_queues;
1773 : :
1774 : 0 : idx = AXGBE_GET_DESC_IDX(rxq, rxq->cur);
1775 : 0 : desc = &rxq->desc[idx];
1776 : :
1777 [ # # ]: 0 : while (AXGMAC_GET_BITS_LE(desc->write.desc3, RX_NORMAL_DESC3, OWN))
1778 : : rte_delay_ms(1);
1779 [ # # ]: 0 : if (AXGMAC_GET_BITS_LE(desc->write.desc3, RX_NORMAL_DESC3, CTXT)) {
1780 [ # # ]: 0 : if (AXGMAC_GET_BITS_LE(desc->write.desc3, RX_CONTEXT_DESC3, TSA) &&
1781 [ # # ]: 0 : !AXGMAC_GET_BITS_LE(desc->write.desc3,
1782 : : RX_CONTEXT_DESC3, TSD)) {
1783 : 0 : pmt = AXGMAC_GET_BITS_LE(desc->write.desc3,
1784 : : RX_CONTEXT_DESC3, PMT);
1785 : 0 : nsec = rte_le_to_cpu_32(desc->write.desc1);
1786 : 0 : nsec *= NSEC_PER_SEC;
1787 : 0 : nsec += rte_le_to_cpu_32(desc->write.desc0);
1788 : : if (nsec != 0xffffffffffffffffULL) {
1789 [ # # ]: 0 : if (pmt == 0x01)
1790 : 0 : *timestamp = rte_ns_to_timespec(nsec);
1791 : 0 : PMD_DRV_LOG_LINE(DEBUG,
1792 : : "flags = 0x%x nsec = %"PRIu64,
1793 : : flags, nsec);
1794 : : }
1795 : : }
1796 : : }
1797 : :
1798 : 0 : return 0;
1799 : : }
1800 : :
1801 : : static int
1802 : 0 : axgbe_timesync_read_tx_timestamp(struct rte_eth_dev *dev,
1803 : : struct timespec *timestamp)
1804 : : {
1805 : : uint64_t nsec;
1806 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1807 : : unsigned int tx_snr, tx_ssr;
1808 : :
1809 : 0 : rte_delay_us(5);
1810 [ # # ]: 0 : if (pdata->vdata->tx_tstamp_workaround) {
1811 : 0 : tx_snr = AXGMAC_IOREAD(pdata, MAC_TXSNR);
1812 : 0 : tx_ssr = AXGMAC_IOREAD(pdata, MAC_TXSSR);
1813 : :
1814 : : } else {
1815 : 0 : tx_ssr = AXGMAC_IOREAD(pdata, MAC_TXSSR);
1816 : 0 : tx_snr = AXGMAC_IOREAD(pdata, MAC_TXSNR);
1817 : : }
1818 [ # # ]: 0 : if (AXGMAC_GET_BITS(tx_snr, MAC_TXSNR, TXTSSTSMIS)) {
1819 : 0 : PMD_DRV_LOG_LINE(DEBUG, "Waiting for TXTSSTSMIS");
1820 : 0 : return 0;
1821 : : }
1822 : 0 : nsec = tx_ssr;
1823 : 0 : nsec *= NSEC_PER_SEC;
1824 : 0 : nsec += tx_snr;
1825 : 0 : PMD_DRV_LOG_LINE(DEBUG, "nsec = %"PRIu64" tx_ssr = %d tx_snr = %d",
1826 : : nsec, tx_ssr, tx_snr);
1827 : 0 : *timestamp = rte_ns_to_timespec(nsec);
1828 : 0 : return 0;
1829 : : }
1830 : :
1831 : : static int
1832 : 0 : axgbe_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vid, int on)
1833 : : {
1834 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1835 : : unsigned long vid_bit, vid_idx;
1836 : :
1837 : 0 : vid_bit = VLAN_TABLE_BIT(vid);
1838 : 0 : vid_idx = VLAN_TABLE_IDX(vid);
1839 : :
1840 [ # # ]: 0 : if (on) {
1841 : 0 : PMD_DRV_LOG_LINE(DEBUG, "Set VLAN vid=%d for device = %s",
1842 : : vid, pdata->eth_dev->device->name);
1843 : 0 : pdata->active_vlans[vid_idx] |= vid_bit;
1844 : : } else {
1845 : 0 : PMD_DRV_LOG_LINE(DEBUG, "Reset VLAN vid=%d for device = %s",
1846 : : vid, pdata->eth_dev->device->name);
1847 : 0 : pdata->active_vlans[vid_idx] &= ~vid_bit;
1848 : : }
1849 : 0 : pdata->hw_if.update_vlan_hash_table(pdata);
1850 : 0 : return 0;
1851 : : }
1852 : :
1853 : : static int
1854 : 0 : axgbe_vlan_tpid_set(struct rte_eth_dev *dev,
1855 : : enum rte_vlan_type vlan_type,
1856 : : uint16_t tpid)
1857 : : {
1858 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1859 : : uint32_t reg = 0;
1860 : : uint32_t qinq = 0;
1861 : :
1862 : 0 : qinq = AXGMAC_IOREAD_BITS(pdata, MAC_VLANTR, EDVLP);
1863 : 0 : PMD_DRV_LOG_LINE(DEBUG, "EDVLP: qinq = 0x%x", qinq);
1864 : :
1865 [ # # # # : 0 : switch (vlan_type) {
# ]
1866 : 0 : case RTE_ETH_VLAN_TYPE_INNER:
1867 : 0 : PMD_DRV_LOG_LINE(DEBUG, "RTE_ETH_VLAN_TYPE_INNER");
1868 [ # # ]: 0 : if (qinq) {
1869 [ # # ]: 0 : if (tpid != 0x8100 && tpid != 0x88a8)
1870 : 0 : PMD_DRV_LOG_LINE(ERR,
1871 : : "tag supported 0x8100/0x88A8");
1872 : 0 : PMD_DRV_LOG_LINE(DEBUG, "qinq with inner tag");
1873 : :
1874 : : /*Enable Inner VLAN Tag */
1875 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ERIVLT, 1);
1876 : 0 : reg = AXGMAC_IOREAD_BITS(pdata, MAC_VLANTR, ERIVLT);
1877 : 0 : PMD_DRV_LOG_LINE(DEBUG, "bit ERIVLT = 0x%x", reg);
1878 : :
1879 : : } else {
1880 : 0 : PMD_DRV_LOG_LINE(ERR,
1881 : : "Inner type not supported in single tag");
1882 : : }
1883 : : break;
1884 : 0 : case RTE_ETH_VLAN_TYPE_OUTER:
1885 : 0 : PMD_DRV_LOG_LINE(DEBUG, "RTE_ETH_VLAN_TYPE_OUTER");
1886 [ # # ]: 0 : if (qinq) {
1887 : 0 : PMD_DRV_LOG_LINE(DEBUG, "double tagging is enabled");
1888 : : /*Enable outer VLAN tag*/
1889 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, ERIVLT, 0);
1890 : 0 : reg = AXGMAC_IOREAD_BITS(pdata, MAC_VLANTR, ERIVLT);
1891 : 0 : PMD_DRV_LOG_LINE(DEBUG, "bit ERIVLT = 0x%x", reg);
1892 : :
1893 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANIR, CSVL, 1);
1894 : 0 : reg = AXGMAC_IOREAD_BITS(pdata, MAC_VLANIR, CSVL);
1895 : 0 : PMD_DRV_LOG_LINE(DEBUG, "bit CSVL = 0x%x", reg);
1896 : : } else {
1897 [ # # ]: 0 : if (tpid != 0x8100 && tpid != 0x88a8)
1898 : 0 : PMD_DRV_LOG_LINE(ERR,
1899 : : "tag supported 0x8100/0x88A8");
1900 : : }
1901 : : break;
1902 : 0 : case RTE_ETH_VLAN_TYPE_MAX:
1903 : 0 : PMD_DRV_LOG_LINE(ERR, "RTE_ETH_VLAN_TYPE_MAX");
1904 : 0 : break;
1905 : 0 : case RTE_ETH_VLAN_TYPE_UNKNOWN:
1906 : 0 : PMD_DRV_LOG_LINE(ERR, "RTE_ETH_VLAN_TYPE_UNKNOWN");
1907 : 0 : break;
1908 : : }
1909 : 0 : return 0;
1910 : : }
1911 : :
1912 : 0 : static void axgbe_vlan_extend_enable(struct axgbe_port *pdata)
1913 : : {
1914 : : int qinq = 0;
1915 : :
1916 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EDVLP, 1);
1917 : 0 : qinq = AXGMAC_IOREAD_BITS(pdata, MAC_VLANTR, EDVLP);
1918 : 0 : PMD_DRV_LOG_LINE(DEBUG, "vlan double tag enabled EDVLP:qinq=0x%x", qinq);
1919 : 0 : }
1920 : :
1921 : 0 : static void axgbe_vlan_extend_disable(struct axgbe_port *pdata)
1922 : : {
1923 : : int qinq = 0;
1924 : :
1925 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANTR, EDVLP, 0);
1926 : 0 : qinq = AXGMAC_IOREAD_BITS(pdata, MAC_VLANTR, EDVLP);
1927 : 0 : PMD_DRV_LOG_LINE(DEBUG, "vlan double tag disable EDVLP:qinq=0x%x", qinq);
1928 : 0 : }
1929 : :
1930 : : static int
1931 : 0 : axgbe_vlan_offload_set(struct rte_eth_dev *dev, int mask)
1932 : : {
1933 : 0 : struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
1934 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
1935 : :
1936 : : /* Indicate that VLAN Tx CTAGs come from context descriptors */
1937 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANIR, CSVL, 0);
1938 : 0 : AXGMAC_IOWRITE_BITS(pdata, MAC_VLANIR, VLTI, 1);
1939 : :
1940 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_STRIP_MASK) {
1941 [ # # ]: 0 : if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
1942 : 0 : PMD_DRV_LOG_LINE(DEBUG, "Strip ON for device = %s",
1943 : : pdata->eth_dev->device->name);
1944 : 0 : pdata->hw_if.enable_rx_vlan_stripping(pdata);
1945 : : } else {
1946 : 0 : PMD_DRV_LOG_LINE(DEBUG, "Strip OFF for device = %s",
1947 : : pdata->eth_dev->device->name);
1948 : 0 : pdata->hw_if.disable_rx_vlan_stripping(pdata);
1949 : : }
1950 : : }
1951 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_FILTER_MASK) {
1952 [ # # ]: 0 : if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) {
1953 : 0 : PMD_DRV_LOG_LINE(DEBUG, "Filter ON for device = %s",
1954 : : pdata->eth_dev->device->name);
1955 : 0 : pdata->hw_if.enable_rx_vlan_filtering(pdata);
1956 : : } else {
1957 : 0 : PMD_DRV_LOG_LINE(DEBUG, "Filter OFF for device = %s",
1958 : : pdata->eth_dev->device->name);
1959 : 0 : pdata->hw_if.disable_rx_vlan_filtering(pdata);
1960 : : }
1961 : : }
1962 [ # # ]: 0 : if (mask & RTE_ETH_VLAN_EXTEND_MASK) {
1963 [ # # ]: 0 : if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND) {
1964 : 0 : PMD_DRV_LOG_LINE(DEBUG, "enabling vlan extended mode");
1965 : 0 : axgbe_vlan_extend_enable(pdata);
1966 : : /* Set global registers with default ethertype*/
1967 : 0 : axgbe_vlan_tpid_set(dev, RTE_ETH_VLAN_TYPE_OUTER,
1968 : : RTE_ETHER_TYPE_VLAN);
1969 : 0 : axgbe_vlan_tpid_set(dev, RTE_ETH_VLAN_TYPE_INNER,
1970 : : RTE_ETHER_TYPE_VLAN);
1971 : : } else {
1972 : 0 : PMD_DRV_LOG_LINE(DEBUG, "disabling vlan extended mode");
1973 : 0 : axgbe_vlan_extend_disable(pdata);
1974 : : }
1975 : : }
1976 : 0 : return 0;
1977 : : }
1978 : :
1979 : 0 : static void axgbe_get_all_hw_features(struct axgbe_port *pdata)
1980 : : {
1981 : : unsigned int mac_hfr0, mac_hfr1, mac_hfr2, mac_hfr3;
1982 : 0 : struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
1983 : :
1984 : 0 : mac_hfr0 = AXGMAC_IOREAD(pdata, MAC_HWF0R);
1985 : 0 : mac_hfr1 = AXGMAC_IOREAD(pdata, MAC_HWF1R);
1986 : 0 : mac_hfr2 = AXGMAC_IOREAD(pdata, MAC_HWF2R);
1987 : 0 : mac_hfr3 = AXGMAC_IOREAD(pdata, MAC_HWF3R);
1988 : :
1989 : : memset(hw_feat, 0, sizeof(*hw_feat));
1990 : :
1991 : 0 : hw_feat->version = AXGMAC_IOREAD(pdata, MAC_VR);
1992 : :
1993 : : /* Hardware feature register 0 */
1994 : 0 : hw_feat->gmii = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, GMIISEL);
1995 : 0 : hw_feat->vlhash = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, VLHASH);
1996 : 0 : hw_feat->sma = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, SMASEL);
1997 : 0 : hw_feat->rwk = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, RWKSEL);
1998 : 0 : hw_feat->mgk = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, MGKSEL);
1999 : 0 : hw_feat->mmc = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, MMCSEL);
2000 : 0 : hw_feat->aoe = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, ARPOFFSEL);
2001 : 0 : hw_feat->ts = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TSSEL);
2002 : 0 : hw_feat->eee = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, EEESEL);
2003 : 0 : hw_feat->tx_coe = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TXCOESEL);
2004 : 0 : hw_feat->rx_coe = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, RXCOESEL);
2005 : 0 : hw_feat->addn_mac = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R,
2006 : : ADDMACADRSEL);
2007 : 0 : hw_feat->ts_src = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TSSTSSEL);
2008 : 0 : hw_feat->sa_vlan_ins = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, SAVLANINS);
2009 : :
2010 : : /* Hardware feature register 1 */
2011 : 0 : hw_feat->rx_fifo_size = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
2012 : : RXFIFOSIZE);
2013 : 0 : hw_feat->tx_fifo_size = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
2014 : : TXFIFOSIZE);
2015 : 0 : hw_feat->adv_ts_hi = AXGMAC_GET_BITS(mac_hfr1,
2016 : : MAC_HWF1R, ADVTHWORD);
2017 : 0 : hw_feat->dma_width = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, ADDR64);
2018 : 0 : hw_feat->dcb = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DCBEN);
2019 : 0 : hw_feat->sph = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, SPHEN);
2020 : 0 : hw_feat->tso = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, TSOEN);
2021 : 0 : hw_feat->dma_debug = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DBGMEMA);
2022 : 0 : hw_feat->rss = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, RSSEN);
2023 : 0 : hw_feat->tc_cnt = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, NUMTC);
2024 : 0 : hw_feat->hash_table_size = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
2025 : : HASHTBLSZ);
2026 : 0 : hw_feat->l3l4_filter_num = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
2027 : : L3L4FNUM);
2028 : :
2029 : : /* Hardware feature register 2 */
2030 : 0 : hw_feat->rx_q_cnt = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, RXQCNT);
2031 : 0 : hw_feat->tx_q_cnt = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, TXQCNT);
2032 : 0 : hw_feat->rx_ch_cnt = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, RXCHCNT);
2033 : 0 : hw_feat->tx_ch_cnt = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, TXCHCNT);
2034 : 0 : hw_feat->pps_out_num = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, PPSOUTNUM);
2035 : 0 : hw_feat->aux_snap_num = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R,
2036 : : AUXSNAPNUM);
2037 : :
2038 : : /* Hardware feature register 3 */
2039 : 0 : hw_feat->tx_q_vlan_tag_ins = AXGMAC_GET_BITS(mac_hfr3,
2040 : : MAC_HWF3R, CBTISEL);
2041 : 0 : hw_feat->no_of_vlan_extn = AXGMAC_GET_BITS(mac_hfr3,
2042 : : MAC_HWF3R, NRVF);
2043 : :
2044 : : /* Translate the Hash Table size into actual number */
2045 [ # # # # ]: 0 : switch (hw_feat->hash_table_size) {
2046 : : case 0:
2047 : : break;
2048 : 0 : case 1:
2049 : 0 : hw_feat->hash_table_size = 64;
2050 : 0 : break;
2051 : 0 : case 2:
2052 : 0 : hw_feat->hash_table_size = 128;
2053 : 0 : break;
2054 : 0 : case 3:
2055 : 0 : hw_feat->hash_table_size = 256;
2056 : 0 : break;
2057 : : }
2058 : :
2059 : : /* Translate the address width setting into actual number */
2060 [ # # # # ]: 0 : switch (hw_feat->dma_width) {
2061 : 0 : case 0:
2062 : 0 : hw_feat->dma_width = 32;
2063 : 0 : break;
2064 : 0 : case 1:
2065 : 0 : hw_feat->dma_width = 40;
2066 : 0 : break;
2067 : 0 : case 2:
2068 : 0 : hw_feat->dma_width = 48;
2069 : 0 : break;
2070 : 0 : default:
2071 : 0 : hw_feat->dma_width = 32;
2072 : : }
2073 : :
2074 : : /* The Queue, Channel and TC counts are zero based so increment them
2075 : : * to get the actual number
2076 : : */
2077 : 0 : hw_feat->rx_q_cnt++;
2078 : 0 : hw_feat->tx_q_cnt++;
2079 : 0 : hw_feat->rx_ch_cnt++;
2080 : 0 : hw_feat->tx_ch_cnt++;
2081 : 0 : hw_feat->tc_cnt++;
2082 : :
2083 : : /* Translate the fifo sizes into actual numbers */
2084 : 0 : hw_feat->rx_fifo_size = 1 << (hw_feat->rx_fifo_size + 7);
2085 : 0 : hw_feat->tx_fifo_size = 1 << (hw_feat->tx_fifo_size + 7);
2086 : 0 : }
2087 : :
2088 : 0 : static void axgbe_init_all_fptrs(struct axgbe_port *pdata)
2089 : : {
2090 : 0 : axgbe_init_function_ptrs_dev(&pdata->hw_if);
2091 : 0 : axgbe_init_function_ptrs_phy(&pdata->phy_if);
2092 : 0 : axgbe_init_function_ptrs_i2c(&pdata->i2c_if);
2093 : 0 : pdata->vdata->init_function_ptrs_phy_impl(&pdata->phy_if);
2094 : 0 : }
2095 : :
2096 : 0 : static void axgbe_set_counts(struct axgbe_port *pdata)
2097 : : {
2098 : : /* Set all the function pointers */
2099 : 0 : axgbe_init_all_fptrs(pdata);
2100 : :
2101 : : /* Populate the hardware features */
2102 : 0 : axgbe_get_all_hw_features(pdata);
2103 : :
2104 : : /* Set default max values if not provided */
2105 [ # # ]: 0 : if (!pdata->tx_max_channel_count)
2106 : 0 : pdata->tx_max_channel_count = pdata->hw_feat.tx_ch_cnt;
2107 [ # # ]: 0 : if (!pdata->rx_max_channel_count)
2108 : 0 : pdata->rx_max_channel_count = pdata->hw_feat.rx_ch_cnt;
2109 : :
2110 [ # # ]: 0 : if (!pdata->tx_max_q_count)
2111 : 0 : pdata->tx_max_q_count = pdata->hw_feat.tx_q_cnt;
2112 [ # # ]: 0 : if (!pdata->rx_max_q_count)
2113 : 0 : pdata->rx_max_q_count = pdata->hw_feat.rx_q_cnt;
2114 : :
2115 : : /* Calculate the number of Tx and Rx rings to be created
2116 : : * -Tx (DMA) Channels map 1-to-1 to Tx Queues so set
2117 : : * the number of Tx queues to the number of Tx channels
2118 : : * enabled
2119 : : * -Rx (DMA) Channels do not map 1-to-1 so use the actual
2120 : : * number of Rx queues or maximum allowed
2121 : : */
2122 : 0 : pdata->tx_ring_count = RTE_MIN(pdata->hw_feat.tx_ch_cnt,
2123 : : pdata->tx_max_channel_count);
2124 : 0 : pdata->tx_ring_count = RTE_MIN(pdata->tx_ring_count,
2125 : : pdata->tx_max_q_count);
2126 : :
2127 : 0 : pdata->tx_q_count = pdata->tx_ring_count;
2128 : :
2129 : 0 : pdata->rx_ring_count = RTE_MIN(pdata->hw_feat.rx_ch_cnt,
2130 : : pdata->rx_max_channel_count);
2131 : :
2132 : 0 : pdata->rx_q_count = RTE_MIN(pdata->hw_feat.rx_q_cnt,
2133 : : pdata->rx_max_q_count);
2134 : 0 : }
2135 : :
2136 : : static void axgbe_default_config(struct axgbe_port *pdata)
2137 : : {
2138 : 0 : pdata->pblx8 = DMA_PBL_X8_ENABLE;
2139 : 0 : pdata->tx_sf_mode = MTL_TSF_ENABLE;
2140 : 0 : pdata->tx_threshold = MTL_TX_THRESHOLD_64;
2141 : 0 : pdata->tx_pbl = DMA_PBL_32;
2142 : 0 : pdata->tx_osp_mode = DMA_OSP_ENABLE;
2143 : 0 : pdata->rx_sf_mode = MTL_RSF_ENABLE;
2144 : 0 : pdata->rx_threshold = MTL_RX_THRESHOLD_64;
2145 : 0 : pdata->rx_pbl = DMA_PBL_32;
2146 : 0 : pdata->pause_autoneg = 1;
2147 : 0 : pdata->tx_pause = 0;
2148 : 0 : pdata->rx_pause = 0;
2149 : 0 : pdata->phy_speed = SPEED_UNKNOWN;
2150 : 0 : pdata->power_down = 0;
2151 : : }
2152 : :
2153 : : /* Used in dev_start by primary process and then
2154 : : * in dev_init by secondary process when attaching to an existing ethdev.
2155 : : */
2156 : : void
2157 : 0 : axgbe_set_tx_function(struct rte_eth_dev *dev)
2158 : : {
2159 : 0 : struct axgbe_port *pdata = dev->data->dev_private;
2160 : :
2161 : 0 : dev->tx_pkt_burst = &axgbe_xmit_pkts;
2162 : :
2163 [ # # ]: 0 : if (pdata->multi_segs_tx)
2164 : 0 : dev->tx_pkt_burst = &axgbe_xmit_pkts_seg;
2165 : : #ifdef RTE_ARCH_X86
2166 : 0 : struct axgbe_tx_queue *txq = dev->data->tx_queues[0];
2167 [ # # # # ]: 0 : if (!txq->vector_disable &&
2168 : 0 : rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128)
2169 : 0 : dev->tx_pkt_burst = &axgbe_xmit_pkts_vec;
2170 : : #endif
2171 : 0 : }
2172 : :
2173 : : void
2174 : 0 : axgbe_set_rx_function(struct rte_eth_dev *dev)
2175 : : {
2176 : 0 : struct rte_eth_dev_data *dev_data = dev->data;
2177 : : uint16_t max_pkt_len;
2178 : : struct axgbe_port *pdata;
2179 : :
2180 : 0 : pdata = dev->data->dev_private;
2181 : 0 : max_pkt_len = dev_data->mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN;
2182 [ # # ]: 0 : if ((dev_data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_SCATTER) ||
2183 [ # # ]: 0 : max_pkt_len > pdata->rx_buf_size)
2184 : 0 : dev_data->scattered_rx = 1;
2185 : : /* Scatter Rx handling */
2186 [ # # ]: 0 : if (dev_data->scattered_rx)
2187 : 0 : dev->rx_pkt_burst = ð_axgbe_recv_scattered_pkts;
2188 : : else
2189 : 0 : dev->rx_pkt_burst = &axgbe_recv_pkts;
2190 : 0 : }
2191 : :
2192 : : /*
2193 : : * It returns 0 on success.
2194 : : */
2195 : : static int
2196 : 0 : eth_axgbe_dev_init(struct rte_eth_dev *eth_dev)
2197 : : {
2198 : : PMD_INIT_FUNC_TRACE();
2199 : : struct axgbe_port *pdata;
2200 : : struct rte_pci_device *pci_dev;
2201 : : uint32_t reg, mac_lo, mac_hi;
2202 : : uint32_t len;
2203 : : int ret;
2204 : :
2205 : : unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
2206 : : unsigned char cpu_family = 0, cpu_model = 0;
2207 : :
2208 : 0 : eth_dev->dev_ops = &axgbe_eth_dev_ops;
2209 : :
2210 : 0 : eth_dev->rx_descriptor_status = axgbe_dev_rx_descriptor_status;
2211 : 0 : eth_dev->tx_descriptor_status = axgbe_dev_tx_descriptor_status;
2212 : :
2213 : 0 : eth_dev->tx_pkt_burst = &axgbe_xmit_pkts;
2214 : 0 : eth_dev->rx_pkt_burst = &axgbe_recv_pkts;
2215 : :
2216 : : /*
2217 : : * For secondary processes, we don't initialise any further as primary
2218 : : * has already done this work.
2219 : : */
2220 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
2221 : 0 : axgbe_set_tx_function(eth_dev);
2222 : 0 : axgbe_set_rx_function(eth_dev);
2223 : 0 : return 0;
2224 : : }
2225 : :
2226 : 0 : eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
2227 : :
2228 [ # # ]: 0 : pdata = eth_dev->data->dev_private;
2229 : : /* initial state */
2230 : : rte_bit_relaxed_set32(AXGBE_DOWN, &pdata->dev_state);
2231 : : rte_bit_relaxed_set32(AXGBE_STOPPED, &pdata->dev_state);
2232 : 0 : pdata->eth_dev = eth_dev;
2233 : :
2234 : 0 : pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
2235 : 0 : pdata->pci_dev = pci_dev;
2236 : :
2237 : 0 : pdata->xgmac_regs =
2238 : 0 : (void *)pci_dev->mem_resource[AXGBE_AXGMAC_BAR].addr;
2239 : 0 : pdata->xprop_regs = (void *)((uint8_t *)pdata->xgmac_regs
2240 : : + AXGBE_MAC_PROP_OFFSET);
2241 : 0 : pdata->xi2c_regs = (void *)((uint8_t *)pdata->xgmac_regs
2242 : : + AXGBE_I2C_CTRL_OFFSET);
2243 : 0 : pdata->xpcs_regs = (void *)pci_dev->mem_resource[AXGBE_XPCS_BAR].addr;
2244 : :
2245 : : /* version specific driver data*/
2246 [ # # ]: 0 : if (pci_dev->id.device_id == AMD_PCI_AXGBE_DEVICE_V2A)
2247 : 0 : pdata->vdata = &axgbe_v2a;
2248 : : else
2249 : 0 : pdata->vdata = &axgbe_v2b;
2250 : :
2251 : : /*
2252 : : * Use CPUID to get Family and model ID to identify the CPU
2253 : : */
2254 : 0 : __cpuid(0x0, eax, ebx, ecx, edx);
2255 : :
2256 : 0 : if (ebx == CPUID_VENDOR_AuthenticAMD_ebx &&
2257 [ # # # # ]: 0 : edx == CPUID_VENDOR_AuthenticAMD_edx &&
2258 : : ecx == CPUID_VENDOR_AuthenticAMD_ecx) {
2259 : : int unknown_cpu = 0;
2260 : : eax = 0; ebx = 0; ecx = 0; edx = 0;
2261 : :
2262 : 0 : __cpuid(0x1, eax, ebx, ecx, edx);
2263 : :
2264 : 0 : cpu_family = ((GET_BITS(eax, 8, 4)) + (GET_BITS(eax, 20, 8)));
2265 : 0 : cpu_model = ((GET_BITS(eax, 4, 4)) | (((GET_BITS(eax, 16, 4)) << 4) & 0xF0));
2266 : :
2267 [ # # # # ]: 0 : switch (cpu_family) {
2268 : 0 : case Fam17h:
2269 : : /* V1000/R1000 */
2270 [ # # ]: 0 : if (cpu_model >= 0x10 && cpu_model <= 0x1F) {
2271 : 0 : pdata->xpcs_window_def_reg = PCS_V2_RV_WINDOW_DEF;
2272 : 0 : pdata->xpcs_window_sel_reg = PCS_V2_RV_WINDOW_SELECT;
2273 : : /* EPYC 3000 */
2274 [ # # ]: 0 : } else if (cpu_model >= 0x01 && cpu_model <= 0x0F) {
2275 : 0 : pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF;
2276 : 0 : pdata->xpcs_window_sel_reg = PCS_V2_WINDOW_SELECT;
2277 : : } else {
2278 : : unknown_cpu = 1;
2279 : : }
2280 : : break;
2281 : 0 : case Fam19h:
2282 : : /* V3000 (Yellow Carp) */
2283 [ # # ]: 0 : if (cpu_model >= 0x44 && cpu_model <= 0x47) {
2284 : 0 : pdata->xpcs_window_def_reg = PCS_V2_YC_WINDOW_DEF;
2285 : 0 : pdata->xpcs_window_sel_reg = PCS_V2_YC_WINDOW_SELECT;
2286 : :
2287 : : /* Yellow Carp devices do not need cdr workaround */
2288 : 0 : pdata->vdata->an_cdr_workaround = 0;
2289 : :
2290 : : /* Yellow Carp devices do not need rrc */
2291 : 0 : pdata->vdata->enable_rrc = 0;
2292 : : } else {
2293 : : unknown_cpu = 1;
2294 : : }
2295 : : break;
2296 : 0 : case Fam1Ah:
2297 : : /* V4000 (krackan2e) */
2298 [ # # ]: 0 : if (cpu_model == 0x68) {
2299 : 0 : pdata->xpcs_window_def_reg = PCS_KR_WINDOW_DEF;
2300 : 0 : pdata->xpcs_window_sel_reg = PCS_KR_WINDOW_SELECT;
2301 : :
2302 : : /* V4000-Krackan2e devices do not need cdr workaround */
2303 : 0 : pdata->vdata->an_cdr_workaround = 0;
2304 : :
2305 : : /* V4000-Krackan2e devices do not need rrc */
2306 : 0 : pdata->vdata->enable_rrc = 0;
2307 : : } else {
2308 : : unknown_cpu = 1;
2309 : : }
2310 : : break;
2311 : : default:
2312 : : unknown_cpu = 1;
2313 : : break;
2314 : : }
2315 : : if (unknown_cpu) {
2316 : 0 : PMD_DRV_LOG_LINE(ERR, "Unknown CPU family, no supported axgbe device found");
2317 : 0 : return -ENODEV;
2318 : : }
2319 : : }
2320 : :
2321 : : /* Configure the PCS indirect addressing support */
2322 : 0 : reg = XPCS32_IOREAD(pdata, pdata->xpcs_window_def_reg);
2323 : 0 : pdata->xpcs_window = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, OFFSET);
2324 : 0 : pdata->xpcs_window <<= 6;
2325 : 0 : pdata->xpcs_window_size = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, SIZE);
2326 : 0 : pdata->xpcs_window_size = 1 << (pdata->xpcs_window_size + 7);
2327 : 0 : pdata->xpcs_window_mask = pdata->xpcs_window_size - 1;
2328 : :
2329 : 0 : PMD_INIT_LOG(DEBUG,
2330 : : "xpcs window :%x, size :%x, mask :%x ", pdata->xpcs_window,
2331 : : pdata->xpcs_window_size, pdata->xpcs_window_mask);
2332 : 0 : XP_IOWRITE(pdata, XP_INT_EN, 0x1fffff);
2333 : :
2334 : : /* Retrieve the MAC address */
2335 : 0 : mac_lo = XP_IOREAD(pdata, XP_MAC_ADDR_LO);
2336 : 0 : mac_hi = XP_IOREAD(pdata, XP_MAC_ADDR_HI);
2337 : 0 : pdata->mac_addr.addr_bytes[0] = mac_lo & 0xff;
2338 : 0 : pdata->mac_addr.addr_bytes[1] = (mac_lo >> 8) & 0xff;
2339 : 0 : pdata->mac_addr.addr_bytes[2] = (mac_lo >> 16) & 0xff;
2340 : 0 : pdata->mac_addr.addr_bytes[3] = (mac_lo >> 24) & 0xff;
2341 : 0 : pdata->mac_addr.addr_bytes[4] = mac_hi & 0xff;
2342 : 0 : pdata->mac_addr.addr_bytes[5] = (mac_hi >> 8) & 0xff;
2343 : :
2344 : : len = RTE_ETHER_ADDR_LEN * AXGBE_MAX_MAC_ADDRS;
2345 : 0 : eth_dev->data->mac_addrs = rte_zmalloc("axgbe_mac_addr", len, 0);
2346 : :
2347 [ # # ]: 0 : if (!eth_dev->data->mac_addrs) {
2348 : 0 : PMD_INIT_LOG(ERR,
2349 : : "Failed to alloc %u bytes needed to "
2350 : : "store MAC addresses", len);
2351 : 0 : return -ENOMEM;
2352 : : }
2353 : :
2354 : : /* Allocate memory for storing hash filter MAC addresses */
2355 : : len = RTE_ETHER_ADDR_LEN * AXGBE_MAX_HASH_MAC_ADDRS;
2356 : 0 : eth_dev->data->hash_mac_addrs = rte_zmalloc("axgbe_hash_mac_addr",
2357 : : len, 0);
2358 : :
2359 [ # # ]: 0 : if (eth_dev->data->hash_mac_addrs == NULL) {
2360 : 0 : PMD_INIT_LOG(ERR,
2361 : : "Failed to allocate %d bytes needed to "
2362 : : "store MAC addresses", len);
2363 : 0 : return -ENOMEM;
2364 : : }
2365 : :
2366 : : if (!rte_is_valid_assigned_ether_addr(&pdata->mac_addr))
2367 : 0 : rte_eth_random_addr(pdata->mac_addr.addr_bytes);
2368 : :
2369 : : /* Copy the permanent MAC address */
2370 : 0 : rte_ether_addr_copy(&pdata->mac_addr, ð_dev->data->mac_addrs[0]);
2371 : :
2372 : : /* Clock settings */
2373 : 0 : pdata->sysclk_rate = AXGBE_V2_DMA_CLOCK_FREQ;
2374 : 0 : pdata->ptpclk_rate = AXGBE_V2_PTP_CLOCK_FREQ;
2375 : :
2376 : : /* Set the DMA coherency values */
2377 : 0 : pdata->coherent = 1;
2378 : 0 : pdata->axdomain = AXGBE_DMA_OS_AXDOMAIN;
2379 : 0 : pdata->arcache = AXGBE_DMA_OS_ARCACHE;
2380 : 0 : pdata->awcache = AXGBE_DMA_OS_AWCACHE;
2381 : :
2382 : : /* Read the port property registers */
2383 : 0 : pdata->pp0 = XP_IOREAD(pdata, XP_PROP_0);
2384 : 0 : pdata->pp1 = XP_IOREAD(pdata, XP_PROP_1);
2385 : 0 : pdata->pp2 = XP_IOREAD(pdata, XP_PROP_2);
2386 : 0 : pdata->pp3 = XP_IOREAD(pdata, XP_PROP_3);
2387 : 0 : pdata->pp4 = XP_IOREAD(pdata, XP_PROP_4);
2388 : :
2389 : : /* Set the maximum channels and queues */
2390 : 0 : pdata->tx_max_channel_count = XP_GET_BITS(pdata->pp1, XP_PROP_1, MAX_TX_DMA);
2391 : 0 : pdata->rx_max_channel_count = XP_GET_BITS(pdata->pp1, XP_PROP_1, MAX_RX_DMA);
2392 : 0 : pdata->tx_max_q_count = XP_GET_BITS(pdata->pp1, XP_PROP_1, MAX_TX_QUEUES);
2393 : 0 : pdata->rx_max_q_count = XP_GET_BITS(pdata->pp1, XP_PROP_1, MAX_RX_QUEUES);
2394 : :
2395 : : /* Set the hardware channel and queue counts */
2396 : 0 : axgbe_set_counts(pdata);
2397 : :
2398 : : /* Set the maximum fifo amounts */
2399 : 0 : pdata->tx_max_fifo_size = XP_GET_BITS(pdata->pp2, XP_PROP_2, TX_FIFO_SIZE);
2400 : 0 : pdata->tx_max_fifo_size *= 16384;
2401 : 0 : pdata->tx_max_fifo_size = RTE_MIN(pdata->tx_max_fifo_size,
2402 : : pdata->vdata->tx_max_fifo_size);
2403 : 0 : pdata->rx_max_fifo_size = XP_GET_BITS(pdata->pp2, XP_PROP_2, RX_FIFO_SIZE);
2404 : 0 : pdata->rx_max_fifo_size *= 16384;
2405 : 0 : pdata->rx_max_fifo_size = RTE_MIN(pdata->rx_max_fifo_size,
2406 : : pdata->vdata->rx_max_fifo_size);
2407 : : /* Issue software reset to DMA */
2408 : 0 : ret = pdata->hw_if.exit(pdata);
2409 [ # # ]: 0 : if (ret)
2410 : 0 : PMD_DRV_LOG_LINE(ERR, "hw_if->exit EBUSY error");
2411 : :
2412 : : /* Set default configuration data */
2413 : : axgbe_default_config(pdata);
2414 : :
2415 : : /* Set default max values if not provided */
2416 [ # # ]: 0 : if (!pdata->tx_max_fifo_size)
2417 : 0 : pdata->tx_max_fifo_size = pdata->hw_feat.tx_fifo_size;
2418 [ # # ]: 0 : if (!pdata->rx_max_fifo_size)
2419 : 0 : pdata->rx_max_fifo_size = pdata->hw_feat.rx_fifo_size;
2420 : :
2421 : 0 : pdata->tx_desc_count = AXGBE_MAX_RING_DESC;
2422 : 0 : pdata->rx_desc_count = AXGBE_MAX_RING_DESC;
2423 : 0 : rte_thread_mutex_init_shared(&pdata->xpcs_mutex);
2424 : 0 : rte_thread_mutex_init_shared(&pdata->i2c_mutex);
2425 : 0 : rte_thread_mutex_init_shared(&pdata->an_mutex);
2426 : 0 : rte_thread_mutex_init_shared(&pdata->phy_mutex);
2427 : :
2428 : 0 : ret = pdata->phy_if.phy_init(pdata);
2429 [ # # ]: 0 : if (ret) {
2430 : 0 : rte_free(eth_dev->data->mac_addrs);
2431 : 0 : eth_dev->data->mac_addrs = NULL;
2432 : 0 : return ret;
2433 : : }
2434 : :
2435 : 0 : rte_intr_callback_register(pci_dev->intr_handle,
2436 : : axgbe_dev_interrupt_handler,
2437 : : (void *)eth_dev);
2438 : 0 : PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x",
2439 : : eth_dev->data->port_id, pci_dev->id.vendor_id,
2440 : : pci_dev->id.device_id);
2441 : :
2442 : 0 : return 0;
2443 : : }
2444 : :
2445 : : static int
2446 : 0 : axgbe_dev_close(struct rte_eth_dev *eth_dev)
2447 : : {
2448 : : struct rte_pci_device *pci_dev;
2449 : : struct axgbe_port *pdata;
2450 : :
2451 : : PMD_INIT_FUNC_TRACE();
2452 : :
2453 [ # # ]: 0 : if (rte_eal_process_type() != RTE_PROC_PRIMARY)
2454 : : return 0;
2455 : :
2456 : 0 : pdata = eth_dev->data->dev_private;
2457 : 0 : pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
2458 : 0 : axgbe_dev_clear_queues(eth_dev);
2459 : :
2460 : : /* disable uio intr before callback unregister */
2461 : 0 : rte_intr_disable(pci_dev->intr_handle);
2462 : 0 : rte_intr_callback_unregister(pci_dev->intr_handle,
2463 : : axgbe_dev_interrupt_handler,
2464 : : (void *)eth_dev);
2465 : :
2466 : : /* Disable all interrupts in the hardware */
2467 : 0 : XP_IOWRITE(pdata, XP_INT_EN, 0x0);
2468 : :
2469 : 0 : return 0;
2470 : : }
2471 : :
2472 : 0 : static int eth_axgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
2473 : : struct rte_pci_device *pci_dev)
2474 : : {
2475 : 0 : return rte_eth_dev_pci_generic_probe(pci_dev,
2476 : : sizeof(struct axgbe_port), eth_axgbe_dev_init);
2477 : : }
2478 : :
2479 : 0 : static int eth_axgbe_pci_remove(struct rte_pci_device *pci_dev)
2480 : : {
2481 : 0 : return rte_eth_dev_pci_generic_remove(pci_dev, axgbe_dev_close);
2482 : : }
2483 : :
2484 : : static struct rte_pci_driver rte_axgbe_pmd = {
2485 : : .id_table = pci_id_axgbe_map,
2486 : : .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
2487 : : .probe = eth_axgbe_pci_probe,
2488 : : .remove = eth_axgbe_pci_remove,
2489 : : };
2490 : :
2491 : 286 : RTE_PMD_REGISTER_PCI(net_axgbe, rte_axgbe_pmd);
2492 : : RTE_PMD_REGISTER_PCI_TABLE(net_axgbe, pci_id_axgbe_map);
2493 : : RTE_PMD_REGISTER_KMOD_DEP(net_axgbe, "* igb_uio | uio_pci_generic | vfio-pci");
2494 [ - + ]: 286 : RTE_LOG_REGISTER_SUFFIX(axgbe_logtype_init, init, NOTICE);
2495 [ - + ]: 286 : RTE_LOG_REGISTER_SUFFIX(axgbe_logtype_driver, driver, NOTICE);
|