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