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