xref: /dpdk/drivers/net/axgbe/axgbe_ethdev.c (revision 410cf0870c48e67483bfccbdd4c734097c01d2c4)
18691632fSRavi Kumar /*   SPDX-License-Identifier: BSD-3-Clause
28691632fSRavi Kumar  *   Copyright(c) 2018 Advanced Micro Devices, Inc. All rights reserved.
38691632fSRavi Kumar  *   Copyright(c) 2018 Synopsys, Inc. All rights reserved.
48691632fSRavi Kumar  */
58691632fSRavi Kumar 
69e890103SRavi Kumar #include "axgbe_rxtx.h"
78691632fSRavi Kumar #include "axgbe_ethdev.h"
8572890efSRavi Kumar #include "axgbe_common.h"
9572890efSRavi Kumar #include "axgbe_phy.h"
10df4867cdSChandu Babu N #include "axgbe_regs.h"
118691632fSRavi Kumar 
128691632fSRavi Kumar static int eth_axgbe_dev_init(struct rte_eth_dev *eth_dev);
138691632fSRavi Kumar static int eth_axgbe_dev_uninit(struct rte_eth_dev *eth_dev);
147c4158a5SRavi Kumar static int  axgbe_dev_configure(struct rte_eth_dev *dev);
157c4158a5SRavi Kumar static int  axgbe_dev_start(struct rte_eth_dev *dev);
167c4158a5SRavi Kumar static void axgbe_dev_stop(struct rte_eth_dev *dev);
17456ff159SRavi Kumar static void axgbe_dev_interrupt_handler(void *param);
189e890103SRavi Kumar static void axgbe_dev_close(struct rte_eth_dev *dev);
199039c812SAndrew Rybchenko static int axgbe_dev_promiscuous_enable(struct rte_eth_dev *dev);
209039c812SAndrew Rybchenko static int axgbe_dev_promiscuous_disable(struct rte_eth_dev *dev);
21ca041cd4SIvan Ilchenko static int axgbe_dev_allmulticast_enable(struct rte_eth_dev *dev);
22ca041cd4SIvan Ilchenko static int axgbe_dev_allmulticast_disable(struct rte_eth_dev *dev);
2349a5e622SChandu Babu N static int axgbe_dev_mac_addr_set(struct rte_eth_dev *dev,
2449a5e622SChandu Babu N 				  struct rte_ether_addr *mac_addr);
2549a5e622SChandu Babu N static int axgbe_dev_mac_addr_add(struct rte_eth_dev *dev,
2649a5e622SChandu Babu N 				  struct rte_ether_addr *mac_addr,
2749a5e622SChandu Babu N 				  uint32_t index,
2849a5e622SChandu Babu N 				  uint32_t vmdq);
2949a5e622SChandu Babu N static void axgbe_dev_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
3049a5e622SChandu Babu N static int axgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
3149a5e622SChandu Babu N 				      struct rte_ether_addr *mc_addr_set,
3249a5e622SChandu Babu N 				      uint32_t nb_mc_addr);
33e01d9b2eSChandu Babu N static int axgbe_dev_uc_hash_table_set(struct rte_eth_dev *dev,
34e01d9b2eSChandu Babu N 				       struct rte_ether_addr *mac_addr,
35e01d9b2eSChandu Babu N 				       uint8_t add);
36e01d9b2eSChandu Babu N static int axgbe_dev_uc_all_hash_table_set(struct rte_eth_dev *dev,
37e01d9b2eSChandu Babu N 					   uint8_t add);
3844d45ffeSRavi Kumar static int axgbe_dev_link_update(struct rte_eth_dev *dev,
3944d45ffeSRavi Kumar 				 int wait_to_complete);
40df4867cdSChandu Babu N static int axgbe_dev_get_regs(struct rte_eth_dev *dev,
41df4867cdSChandu Babu N 			      struct rte_dev_reg_info *regs);
423e730511SRavi Kumar static int axgbe_dev_stats_get(struct rte_eth_dev *dev,
433e730511SRavi Kumar 				struct rte_eth_stats *stats);
449970a9adSIgor Romanov static int axgbe_dev_stats_reset(struct rte_eth_dev *dev);
459d1ef6b2SChandu Babu N static int axgbe_dev_xstats_get(struct rte_eth_dev *dev,
469d1ef6b2SChandu Babu N 				struct rte_eth_xstat *stats,
479d1ef6b2SChandu Babu N 				unsigned int n);
489d1ef6b2SChandu Babu N static int
499d1ef6b2SChandu Babu N axgbe_dev_xstats_get_names(struct rte_eth_dev *dev,
509d1ef6b2SChandu Babu N 			   struct rte_eth_xstat_name *xstats_names,
519d1ef6b2SChandu Babu N 			   unsigned int size);
529d1ef6b2SChandu Babu N static int
539d1ef6b2SChandu Babu N axgbe_dev_xstats_get_by_id(struct rte_eth_dev *dev,
549d1ef6b2SChandu Babu N 			   const uint64_t *ids,
559d1ef6b2SChandu Babu N 			   uint64_t *values,
569d1ef6b2SChandu Babu N 			   unsigned int n);
579d1ef6b2SChandu Babu N static int
589d1ef6b2SChandu Babu N axgbe_dev_xstats_get_names_by_id(struct rte_eth_dev *dev,
599d1ef6b2SChandu Babu N 				 struct rte_eth_xstat_name *xstats_names,
609d1ef6b2SChandu Babu N 				 const uint64_t *ids,
619d1ef6b2SChandu Babu N 				 unsigned int size);
629d1ef6b2SChandu Babu N static int axgbe_dev_xstats_reset(struct rte_eth_dev *dev);
63bdad90d1SIvan Ilchenko static int  axgbe_dev_info_get(struct rte_eth_dev *dev,
649e890103SRavi Kumar 			       struct rte_eth_dev_info *dev_info);
65cf97f33eSAmaranath Somalapuram static int axgbe_flow_ctrl_get(struct rte_eth_dev *dev,
66cf97f33eSAmaranath Somalapuram 				struct rte_eth_fc_conf *fc_conf);
67cf97f33eSAmaranath Somalapuram static int axgbe_flow_ctrl_set(struct rte_eth_dev *dev,
68cf97f33eSAmaranath Somalapuram 				struct rte_eth_fc_conf *fc_conf);
69e0543d4eSAmaranath Somalapuram static int axgbe_priority_flow_ctrl_set(struct rte_eth_dev *dev,
70e0543d4eSAmaranath Somalapuram 				struct rte_eth_pfc_conf *pfc_conf);
717aed95c9SAmaranath Somalapuram static void axgbe_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
727aed95c9SAmaranath Somalapuram 	struct rte_eth_rxq_info *qinfo);
737aed95c9SAmaranath Somalapuram static void axgbe_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
747aed95c9SAmaranath Somalapuram 	struct rte_eth_txq_info *qinfo);
75*410cf087SAmaranath Somalapuram const uint32_t *axgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev);
768691632fSRavi Kumar 
779d1ef6b2SChandu Babu N struct axgbe_xstats {
789d1ef6b2SChandu Babu N 	char name[RTE_ETH_XSTATS_NAME_SIZE];
799d1ef6b2SChandu Babu N 	int offset;
809d1ef6b2SChandu Babu N };
819d1ef6b2SChandu Babu N 
829d1ef6b2SChandu Babu N #define AXGMAC_MMC_STAT(_string, _var)                           \
839d1ef6b2SChandu Babu N 	{ _string,                                              \
849d1ef6b2SChandu Babu N 	  offsetof(struct axgbe_mmc_stats, _var),       \
859d1ef6b2SChandu Babu N 	}
869d1ef6b2SChandu Babu N 
879d1ef6b2SChandu Babu N static const struct axgbe_xstats axgbe_xstats_strings[] = {
889d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_bytes", txoctetcount_gb),
899d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_packets", txframecount_gb),
909d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_unicast_packets", txunicastframes_gb),
919d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_broadcast_packets", txbroadcastframes_gb),
929d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_multicast_packets", txmulticastframes_gb),
939d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_vlan_packets", txvlanframes_g),
949d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_64_byte_packets", tx64octets_gb),
959d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_65_to_127_byte_packets", tx65to127octets_gb),
969d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_128_to_255_byte_packets", tx128to255octets_gb),
979d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_256_to_511_byte_packets", tx256to511octets_gb),
989d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_512_to_1023_byte_packets", tx512to1023octets_gb),
999d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_1024_to_max_byte_packets", tx1024tomaxoctets_gb),
1009d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_underflow_errors", txunderflowerror),
1019d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_pause_frames", txpauseframes),
1029d1ef6b2SChandu Babu N 
1039d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_bytes", rxoctetcount_gb),
1049d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_packets", rxframecount_gb),
1059d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_unicast_packets", rxunicastframes_g),
1069d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_broadcast_packets", rxbroadcastframes_g),
1079d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_multicast_packets", rxmulticastframes_g),
1089d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_vlan_packets", rxvlanframes_gb),
1099d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_64_byte_packets", rx64octets_gb),
1109d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_65_to_127_byte_packets", rx65to127octets_gb),
1119d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_128_to_255_byte_packets", rx128to255octets_gb),
1129d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_256_to_511_byte_packets", rx256to511octets_gb),
1139d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_512_to_1023_byte_packets", rx512to1023octets_gb),
1149d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_1024_to_max_byte_packets", rx1024tomaxoctets_gb),
1159d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_undersize_packets", rxundersize_g),
1169d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_oversize_packets", rxoversize_g),
1179d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_crc_errors", rxcrcerror),
1189d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_crc_errors_small_packets", rxrunterror),
1199d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_crc_errors_giant_packets", rxjabbererror),
1209d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_length_errors", rxlengtherror),
1219d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_out_of_range_errors", rxoutofrangetype),
1229d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_fifo_overflow_errors", rxfifooverflow),
1239d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_watchdog_errors", rxwatchdogerror),
1249d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_pause_frames", rxpauseframes),
1259d1ef6b2SChandu Babu N };
1269d1ef6b2SChandu Babu N 
1279d1ef6b2SChandu Babu N #define AXGBE_XSTATS_COUNT        ARRAY_SIZE(axgbe_xstats_strings)
1289d1ef6b2SChandu Babu N 
1298691632fSRavi Kumar /* The set of PCI devices this driver supports */
1308691632fSRavi Kumar #define AMD_PCI_VENDOR_ID       0x1022
131991e0b1dSSelwin Sebastian #define AMD_PCI_RV_ROOT_COMPLEX_ID	0x15d0
1328691632fSRavi Kumar #define AMD_PCI_AXGBE_DEVICE_V2A 0x1458
1338691632fSRavi Kumar #define AMD_PCI_AXGBE_DEVICE_V2B 0x1459
1348691632fSRavi Kumar 
1358691632fSRavi Kumar int axgbe_logtype_init;
1368691632fSRavi Kumar int axgbe_logtype_driver;
1378691632fSRavi Kumar 
1388691632fSRavi Kumar static const struct rte_pci_id pci_id_axgbe_map[] = {
1398691632fSRavi Kumar 	{RTE_PCI_DEVICE(AMD_PCI_VENDOR_ID, AMD_PCI_AXGBE_DEVICE_V2A)},
1408691632fSRavi Kumar 	{RTE_PCI_DEVICE(AMD_PCI_VENDOR_ID, AMD_PCI_AXGBE_DEVICE_V2B)},
1418691632fSRavi Kumar 	{ .vendor_id = 0, },
1428691632fSRavi Kumar };
1438691632fSRavi Kumar 
144572890efSRavi Kumar static struct axgbe_version_data axgbe_v2a = {
1454ac7516bSRavi Kumar 	.init_function_ptrs_phy_impl    = axgbe_init_function_ptrs_phy_v2,
146572890efSRavi Kumar 	.xpcs_access			= AXGBE_XPCS_ACCESS_V2,
147572890efSRavi Kumar 	.mmc_64bit			= 1,
148572890efSRavi Kumar 	.tx_max_fifo_size		= 229376,
149572890efSRavi Kumar 	.rx_max_fifo_size		= 229376,
150572890efSRavi Kumar 	.tx_tstamp_workaround		= 1,
151572890efSRavi Kumar 	.ecc_support			= 1,
152572890efSRavi Kumar 	.i2c_support			= 1,
15300072056SRavi Kumar 	.an_cdr_workaround		= 1,
154572890efSRavi Kumar };
155572890efSRavi Kumar 
156572890efSRavi Kumar static struct axgbe_version_data axgbe_v2b = {
1574ac7516bSRavi Kumar 	.init_function_ptrs_phy_impl    = axgbe_init_function_ptrs_phy_v2,
158572890efSRavi Kumar 	.xpcs_access			= AXGBE_XPCS_ACCESS_V2,
159572890efSRavi Kumar 	.mmc_64bit			= 1,
160572890efSRavi Kumar 	.tx_max_fifo_size		= 65536,
161572890efSRavi Kumar 	.rx_max_fifo_size		= 65536,
162572890efSRavi Kumar 	.tx_tstamp_workaround		= 1,
163572890efSRavi Kumar 	.ecc_support			= 1,
164572890efSRavi Kumar 	.i2c_support			= 1,
16500072056SRavi Kumar 	.an_cdr_workaround		= 1,
166572890efSRavi Kumar };
167572890efSRavi Kumar 
1689e890103SRavi Kumar static const struct rte_eth_desc_lim rx_desc_lim = {
1699e890103SRavi Kumar 	.nb_max = AXGBE_MAX_RING_DESC,
1709e890103SRavi Kumar 	.nb_min = AXGBE_MIN_RING_DESC,
1719e890103SRavi Kumar 	.nb_align = 8,
1729e890103SRavi Kumar };
1739e890103SRavi Kumar 
1749e890103SRavi Kumar static const struct rte_eth_desc_lim tx_desc_lim = {
1759e890103SRavi Kumar 	.nb_max = AXGBE_MAX_RING_DESC,
1769e890103SRavi Kumar 	.nb_min = AXGBE_MIN_RING_DESC,
1779e890103SRavi Kumar 	.nb_align = 8,
1789e890103SRavi Kumar };
1799e890103SRavi Kumar 
1809e890103SRavi Kumar static const struct eth_dev_ops axgbe_eth_dev_ops = {
1817c4158a5SRavi Kumar 	.dev_configure        = axgbe_dev_configure,
1827c4158a5SRavi Kumar 	.dev_start            = axgbe_dev_start,
1837c4158a5SRavi Kumar 	.dev_stop             = axgbe_dev_stop,
1849e890103SRavi Kumar 	.dev_close            = axgbe_dev_close,
185fa3e0440SRavi Kumar 	.promiscuous_enable   = axgbe_dev_promiscuous_enable,
186fa3e0440SRavi Kumar 	.promiscuous_disable  = axgbe_dev_promiscuous_disable,
187fa3e0440SRavi Kumar 	.allmulticast_enable  = axgbe_dev_allmulticast_enable,
188fa3e0440SRavi Kumar 	.allmulticast_disable = axgbe_dev_allmulticast_disable,
18949a5e622SChandu Babu N 	.mac_addr_set         = axgbe_dev_mac_addr_set,
19049a5e622SChandu Babu N 	.mac_addr_add         = axgbe_dev_mac_addr_add,
19149a5e622SChandu Babu N 	.mac_addr_remove      = axgbe_dev_mac_addr_remove,
19249a5e622SChandu Babu N 	.set_mc_addr_list     = axgbe_dev_set_mc_addr_list,
193e01d9b2eSChandu Babu N 	.uc_hash_table_set    = axgbe_dev_uc_hash_table_set,
194e01d9b2eSChandu Babu N 	.uc_all_hash_table_set = axgbe_dev_uc_all_hash_table_set,
19544d45ffeSRavi Kumar 	.link_update          = axgbe_dev_link_update,
196df4867cdSChandu Babu N 	.get_reg	      = axgbe_dev_get_regs,
1973e730511SRavi Kumar 	.stats_get            = axgbe_dev_stats_get,
1983e730511SRavi Kumar 	.stats_reset          = axgbe_dev_stats_reset,
1999d1ef6b2SChandu Babu N 	.xstats_get	      = axgbe_dev_xstats_get,
2009d1ef6b2SChandu Babu N 	.xstats_reset	      = axgbe_dev_xstats_reset,
2019d1ef6b2SChandu Babu N 	.xstats_get_names     = axgbe_dev_xstats_get_names,
2029d1ef6b2SChandu Babu N 	.xstats_get_names_by_id = axgbe_dev_xstats_get_names_by_id,
2039d1ef6b2SChandu Babu N 	.xstats_get_by_id     = axgbe_dev_xstats_get_by_id,
2049e890103SRavi Kumar 	.dev_infos_get        = axgbe_dev_info_get,
2059e890103SRavi Kumar 	.rx_queue_setup       = axgbe_dev_rx_queue_setup,
2069e890103SRavi Kumar 	.rx_queue_release     = axgbe_dev_rx_queue_release,
2079e890103SRavi Kumar 	.tx_queue_setup       = axgbe_dev_tx_queue_setup,
2089e890103SRavi Kumar 	.tx_queue_release     = axgbe_dev_tx_queue_release,
209cf97f33eSAmaranath Somalapuram 	.flow_ctrl_get        = axgbe_flow_ctrl_get,
210cf97f33eSAmaranath Somalapuram 	.flow_ctrl_set        = axgbe_flow_ctrl_set,
211e0543d4eSAmaranath Somalapuram 	.priority_flow_ctrl_set = axgbe_priority_flow_ctrl_set,
2127aed95c9SAmaranath Somalapuram 	.rxq_info_get                 = axgbe_rxq_info_get,
2137aed95c9SAmaranath Somalapuram 	.txq_info_get                 = axgbe_txq_info_get,
214*410cf087SAmaranath Somalapuram 	.dev_supported_ptypes_get     = axgbe_dev_supported_ptypes_get,
2159e890103SRavi Kumar };
2169e890103SRavi Kumar 
2177c4158a5SRavi Kumar static int axgbe_phy_reset(struct axgbe_port *pdata)
2187c4158a5SRavi Kumar {
2197c4158a5SRavi Kumar 	pdata->phy_link = -1;
2207c4158a5SRavi Kumar 	pdata->phy_speed = SPEED_UNKNOWN;
2217c4158a5SRavi Kumar 	return pdata->phy_if.phy_reset(pdata);
2227c4158a5SRavi Kumar }
2237c4158a5SRavi Kumar 
224456ff159SRavi Kumar /*
225456ff159SRavi Kumar  * Interrupt handler triggered by NIC  for handling
226456ff159SRavi Kumar  * specific interrupt.
227456ff159SRavi Kumar  *
228456ff159SRavi Kumar  * @param handle
229456ff159SRavi Kumar  *  Pointer to interrupt handle.
230456ff159SRavi Kumar  * @param param
231456ff159SRavi Kumar  *  The address of parameter (struct rte_eth_dev *) regsitered before.
232456ff159SRavi Kumar  *
233456ff159SRavi Kumar  * @return
234456ff159SRavi Kumar  *  void
235456ff159SRavi Kumar  */
236456ff159SRavi Kumar static void
237456ff159SRavi Kumar axgbe_dev_interrupt_handler(void *param)
238456ff159SRavi Kumar {
239456ff159SRavi Kumar 	struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
240456ff159SRavi Kumar 	struct axgbe_port *pdata = dev->data->dev_private;
2418590b93dSRavi Kumar 	unsigned int dma_isr, dma_ch_isr;
242456ff159SRavi Kumar 
243456ff159SRavi Kumar 	pdata->phy_if.an_isr(pdata);
2448590b93dSRavi Kumar 	/*DMA related interrupts*/
2458590b93dSRavi Kumar 	dma_isr = AXGMAC_IOREAD(pdata, DMA_ISR);
2464216cdc0SChandu Babu N 	PMD_DRV_LOG(DEBUG, "DMA_ISR=%#010x\n", dma_isr);
2478590b93dSRavi Kumar 	if (dma_isr) {
2488590b93dSRavi Kumar 		if (dma_isr & 1) {
2498590b93dSRavi Kumar 			dma_ch_isr =
2508590b93dSRavi Kumar 				AXGMAC_DMA_IOREAD((struct axgbe_rx_queue *)
2518590b93dSRavi Kumar 						  pdata->rx_queues[0],
2528590b93dSRavi Kumar 						  DMA_CH_SR);
2534216cdc0SChandu Babu N 			PMD_DRV_LOG(DEBUG, "DMA_CH0_ISR=%#010x\n", dma_ch_isr);
2548590b93dSRavi Kumar 			AXGMAC_DMA_IOWRITE((struct axgbe_rx_queue *)
2558590b93dSRavi Kumar 					   pdata->rx_queues[0],
2568590b93dSRavi Kumar 					   DMA_CH_SR, dma_ch_isr);
2578590b93dSRavi Kumar 		}
2588590b93dSRavi Kumar 	}
2596bee9d5fSNithin Dabilpuram 	/* Unmask interrupts since disabled after generation */
2606bee9d5fSNithin Dabilpuram 	rte_intr_ack(&pdata->pci_dev->intr_handle);
261456ff159SRavi Kumar }
262456ff159SRavi Kumar 
2637c4158a5SRavi Kumar /*
2647c4158a5SRavi Kumar  * Configure device link speed and setup link.
2657c4158a5SRavi Kumar  * It returns 0 on success.
2667c4158a5SRavi Kumar  */
2677c4158a5SRavi Kumar static int
2687c4158a5SRavi Kumar axgbe_dev_configure(struct rte_eth_dev *dev)
2697c4158a5SRavi Kumar {
2707c4158a5SRavi Kumar 	struct axgbe_port *pdata =  dev->data->dev_private;
2717c4158a5SRavi Kumar 	/* Checksum offload to hardware */
2727c4158a5SRavi Kumar 	pdata->rx_csum_enable = dev->data->dev_conf.rxmode.offloads &
2737c4158a5SRavi Kumar 				DEV_RX_OFFLOAD_CHECKSUM;
2747c4158a5SRavi Kumar 	return 0;
2757c4158a5SRavi Kumar }
2767c4158a5SRavi Kumar 
2777c4158a5SRavi Kumar static int
2787c4158a5SRavi Kumar axgbe_dev_rx_mq_config(struct rte_eth_dev *dev)
2797c4158a5SRavi Kumar {
2800bc212a8SStephen Hemminger 	struct axgbe_port *pdata = dev->data->dev_private;
2817c4158a5SRavi Kumar 
2827c4158a5SRavi Kumar 	if (dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_RSS)
2837c4158a5SRavi Kumar 		pdata->rss_enable = 1;
2847c4158a5SRavi Kumar 	else if (dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_NONE)
2857c4158a5SRavi Kumar 		pdata->rss_enable = 0;
2867c4158a5SRavi Kumar 	else
2877c4158a5SRavi Kumar 		return  -1;
2887c4158a5SRavi Kumar 	return 0;
2897c4158a5SRavi Kumar }
2907c4158a5SRavi Kumar 
2917c4158a5SRavi Kumar static int
2927c4158a5SRavi Kumar axgbe_dev_start(struct rte_eth_dev *dev)
2937c4158a5SRavi Kumar {
2940bc212a8SStephen Hemminger 	struct axgbe_port *pdata = dev->data->dev_private;
2957c4158a5SRavi Kumar 	int ret;
296965b3127SSelwin Sebastian 	struct rte_eth_dev_data *dev_data = dev->data;
297965b3127SSelwin Sebastian 	uint16_t max_pkt_len = dev_data->dev_conf.rxmode.max_rx_pkt_len;
298965b3127SSelwin Sebastian 
299965b3127SSelwin Sebastian 	dev->dev_ops = &axgbe_eth_dev_ops;
3007c4158a5SRavi Kumar 
3010bc212a8SStephen Hemminger 	PMD_INIT_FUNC_TRACE();
3020bc212a8SStephen Hemminger 
3037c4158a5SRavi Kumar 	/* Multiqueue RSS */
3047c4158a5SRavi Kumar 	ret = axgbe_dev_rx_mq_config(dev);
3057c4158a5SRavi Kumar 	if (ret) {
3067c4158a5SRavi Kumar 		PMD_DRV_LOG(ERR, "Unable to config RX MQ\n");
3077c4158a5SRavi Kumar 		return ret;
3087c4158a5SRavi Kumar 	}
3097c4158a5SRavi Kumar 	ret = axgbe_phy_reset(pdata);
3107c4158a5SRavi Kumar 	if (ret) {
3117c4158a5SRavi Kumar 		PMD_DRV_LOG(ERR, "phy reset failed\n");
3127c4158a5SRavi Kumar 		return ret;
3137c4158a5SRavi Kumar 	}
3147c4158a5SRavi Kumar 	ret = pdata->hw_if.init(pdata);
3157c4158a5SRavi Kumar 	if (ret) {
3167c4158a5SRavi Kumar 		PMD_DRV_LOG(ERR, "dev_init failed\n");
3177c4158a5SRavi Kumar 		return ret;
3187c4158a5SRavi Kumar 	}
3197c4158a5SRavi Kumar 
3207c4158a5SRavi Kumar 	/* enable uio/vfio intr/eventfd mapping */
3217c4158a5SRavi Kumar 	rte_intr_enable(&pdata->pci_dev->intr_handle);
3227c4158a5SRavi Kumar 
3237c4158a5SRavi Kumar 	/* phy start*/
3247c4158a5SRavi Kumar 	pdata->phy_if.phy_start(pdata);
3258590b93dSRavi Kumar 	axgbe_dev_enable_tx(dev);
3268590b93dSRavi Kumar 	axgbe_dev_enable_rx(dev);
3277c4158a5SRavi Kumar 
3287c4158a5SRavi Kumar 	axgbe_clear_bit(AXGBE_STOPPED, &pdata->dev_state);
3297c4158a5SRavi Kumar 	axgbe_clear_bit(AXGBE_DOWN, &pdata->dev_state);
330965b3127SSelwin Sebastian 	if ((dev_data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SCATTER) ||
331965b3127SSelwin Sebastian 				max_pkt_len > pdata->rx_buf_size)
332965b3127SSelwin Sebastian 		dev_data->scattered_rx = 1;
333965b3127SSelwin Sebastian 
334965b3127SSelwin Sebastian 	/*  Scatter Rx handling */
335965b3127SSelwin Sebastian 	if (dev_data->scattered_rx)
336965b3127SSelwin Sebastian 		dev->rx_pkt_burst = &eth_axgbe_recv_scattered_pkts;
337965b3127SSelwin Sebastian 	else
338965b3127SSelwin Sebastian 		dev->rx_pkt_burst = &axgbe_recv_pkts;
339965b3127SSelwin Sebastian 
3407c4158a5SRavi Kumar 	return 0;
3417c4158a5SRavi Kumar }
3427c4158a5SRavi Kumar 
3437c4158a5SRavi Kumar /* Stop device: disable rx and tx functions to allow for reconfiguring. */
3447c4158a5SRavi Kumar static void
3457c4158a5SRavi Kumar axgbe_dev_stop(struct rte_eth_dev *dev)
3467c4158a5SRavi Kumar {
3477c4158a5SRavi Kumar 	struct axgbe_port *pdata = dev->data->dev_private;
3487c4158a5SRavi Kumar 
3490bc212a8SStephen Hemminger 	PMD_INIT_FUNC_TRACE();
3500bc212a8SStephen Hemminger 
3517c4158a5SRavi Kumar 	rte_intr_disable(&pdata->pci_dev->intr_handle);
3527c4158a5SRavi Kumar 
3537c4158a5SRavi Kumar 	if (axgbe_test_bit(AXGBE_STOPPED, &pdata->dev_state))
3547c4158a5SRavi Kumar 		return;
3557c4158a5SRavi Kumar 
3567c4158a5SRavi Kumar 	axgbe_set_bit(AXGBE_STOPPED, &pdata->dev_state);
3578590b93dSRavi Kumar 	axgbe_dev_disable_tx(dev);
3588590b93dSRavi Kumar 	axgbe_dev_disable_rx(dev);
3597c4158a5SRavi Kumar 
3607c4158a5SRavi Kumar 	pdata->phy_if.phy_stop(pdata);
3617c4158a5SRavi Kumar 	pdata->hw_if.exit(pdata);
3627c4158a5SRavi Kumar 	memset(&dev->data->dev_link, 0, sizeof(struct rte_eth_link));
3637c4158a5SRavi Kumar 	axgbe_set_bit(AXGBE_DOWN, &pdata->dev_state);
3647c4158a5SRavi Kumar }
3657c4158a5SRavi Kumar 
3669e890103SRavi Kumar /* Clear all resources like TX/RX queues. */
3679e890103SRavi Kumar static void
3689e890103SRavi Kumar axgbe_dev_close(struct rte_eth_dev *dev)
3699e890103SRavi Kumar {
3709e890103SRavi Kumar 	axgbe_dev_clear_queues(dev);
3719e890103SRavi Kumar }
3729e890103SRavi Kumar 
3739039c812SAndrew Rybchenko static int
374fa3e0440SRavi Kumar axgbe_dev_promiscuous_enable(struct rte_eth_dev *dev)
375fa3e0440SRavi Kumar {
376fa3e0440SRavi Kumar 	struct axgbe_port *pdata = dev->data->dev_private;
377fa3e0440SRavi Kumar 
3780bc212a8SStephen Hemminger 	PMD_INIT_FUNC_TRACE();
3790bc212a8SStephen Hemminger 
380fa3e0440SRavi Kumar 	AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PR, 1);
3819039c812SAndrew Rybchenko 
3829039c812SAndrew Rybchenko 	return 0;
383fa3e0440SRavi Kumar }
384fa3e0440SRavi Kumar 
3859039c812SAndrew Rybchenko static int
386fa3e0440SRavi Kumar axgbe_dev_promiscuous_disable(struct rte_eth_dev *dev)
387fa3e0440SRavi Kumar {
388fa3e0440SRavi Kumar 	struct axgbe_port *pdata = dev->data->dev_private;
389fa3e0440SRavi Kumar 
3900bc212a8SStephen Hemminger 	PMD_INIT_FUNC_TRACE();
3910bc212a8SStephen Hemminger 
392fa3e0440SRavi Kumar 	AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PR, 0);
3939039c812SAndrew Rybchenko 
3949039c812SAndrew Rybchenko 	return 0;
395fa3e0440SRavi Kumar }
396fa3e0440SRavi Kumar 
397ca041cd4SIvan Ilchenko static int
398fa3e0440SRavi Kumar axgbe_dev_allmulticast_enable(struct rte_eth_dev *dev)
399fa3e0440SRavi Kumar {
400fa3e0440SRavi Kumar 	struct axgbe_port *pdata = dev->data->dev_private;
401fa3e0440SRavi Kumar 
4020bc212a8SStephen Hemminger 	PMD_INIT_FUNC_TRACE();
4030bc212a8SStephen Hemminger 
404fa3e0440SRavi Kumar 	if (AXGMAC_IOREAD_BITS(pdata, MAC_PFR, PM))
405ca041cd4SIvan Ilchenko 		return 0;
406fa3e0440SRavi Kumar 	AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PM, 1);
407ca041cd4SIvan Ilchenko 
408ca041cd4SIvan Ilchenko 	return 0;
409fa3e0440SRavi Kumar }
410fa3e0440SRavi Kumar 
411ca041cd4SIvan Ilchenko static int
412fa3e0440SRavi Kumar axgbe_dev_allmulticast_disable(struct rte_eth_dev *dev)
413fa3e0440SRavi Kumar {
414fa3e0440SRavi Kumar 	struct axgbe_port *pdata = dev->data->dev_private;
415fa3e0440SRavi Kumar 
4160bc212a8SStephen Hemminger 	PMD_INIT_FUNC_TRACE();
4170bc212a8SStephen Hemminger 
418fa3e0440SRavi Kumar 	if (!AXGMAC_IOREAD_BITS(pdata, MAC_PFR, PM))
419ca041cd4SIvan Ilchenko 		return 0;
420fa3e0440SRavi Kumar 	AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PM, 0);
421ca041cd4SIvan Ilchenko 
422ca041cd4SIvan Ilchenko 	return 0;
423fa3e0440SRavi Kumar }
424fa3e0440SRavi Kumar 
42549a5e622SChandu Babu N static int
42649a5e622SChandu Babu N axgbe_dev_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
42749a5e622SChandu Babu N {
42849a5e622SChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
42949a5e622SChandu Babu N 
43049a5e622SChandu Babu N 	/* Set Default MAC Addr */
43149a5e622SChandu Babu N 	axgbe_set_mac_addn_addr(pdata, (u8 *)mac_addr, 0);
43249a5e622SChandu Babu N 
43349a5e622SChandu Babu N 	return 0;
43449a5e622SChandu Babu N }
43549a5e622SChandu Babu N 
43649a5e622SChandu Babu N static int
43749a5e622SChandu Babu N axgbe_dev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
43849a5e622SChandu Babu N 			      uint32_t index, uint32_t pool __rte_unused)
43949a5e622SChandu Babu N {
44049a5e622SChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
44149a5e622SChandu Babu N 	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
44249a5e622SChandu Babu N 
44349a5e622SChandu Babu N 	if (index > hw_feat->addn_mac) {
44449a5e622SChandu Babu N 		PMD_DRV_LOG(ERR, "Invalid Index %d\n", index);
44549a5e622SChandu Babu N 		return -EINVAL;
44649a5e622SChandu Babu N 	}
44749a5e622SChandu Babu N 	axgbe_set_mac_addn_addr(pdata, (u8 *)mac_addr, index);
44849a5e622SChandu Babu N 	return 0;
44949a5e622SChandu Babu N }
45049a5e622SChandu Babu N 
45149a5e622SChandu Babu N static void
45249a5e622SChandu Babu N axgbe_dev_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
45349a5e622SChandu Babu N {
45449a5e622SChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
45549a5e622SChandu Babu N 	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
45649a5e622SChandu Babu N 
45749a5e622SChandu Babu N 	if (index > hw_feat->addn_mac) {
45849a5e622SChandu Babu N 		PMD_DRV_LOG(ERR, "Invalid Index %d\n", index);
45949a5e622SChandu Babu N 		return;
46049a5e622SChandu Babu N 	}
46149a5e622SChandu Babu N 	axgbe_set_mac_addn_addr(pdata, NULL, index);
46249a5e622SChandu Babu N }
46349a5e622SChandu Babu N 
46449a5e622SChandu Babu N static int
46549a5e622SChandu Babu N axgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
46649a5e622SChandu Babu N 				      struct rte_ether_addr *mc_addr_set,
46749a5e622SChandu Babu N 				      uint32_t nb_mc_addr)
46849a5e622SChandu Babu N {
46949a5e622SChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
47049a5e622SChandu Babu N 	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
47149a5e622SChandu Babu N 	uint32_t index = 1; /* 0 is always default mac */
47249a5e622SChandu Babu N 	uint32_t i;
47349a5e622SChandu Babu N 
47449a5e622SChandu Babu N 	if (nb_mc_addr > hw_feat->addn_mac) {
47549a5e622SChandu Babu N 		PMD_DRV_LOG(ERR, "Invalid Index %d\n", nb_mc_addr);
47649a5e622SChandu Babu N 		return -EINVAL;
47749a5e622SChandu Babu N 	}
47849a5e622SChandu Babu N 
47949a5e622SChandu Babu N 	/* clear unicast addresses */
48049a5e622SChandu Babu N 	for (i = 1; i < hw_feat->addn_mac; i++) {
48149a5e622SChandu Babu N 		if (rte_is_zero_ether_addr(&dev->data->mac_addrs[i]))
48249a5e622SChandu Babu N 			continue;
48349a5e622SChandu Babu N 		memset(&dev->data->mac_addrs[i], 0,
48449a5e622SChandu Babu N 		       sizeof(struct rte_ether_addr));
48549a5e622SChandu Babu N 	}
48649a5e622SChandu Babu N 
48749a5e622SChandu Babu N 	while (nb_mc_addr--)
48849a5e622SChandu Babu N 		axgbe_set_mac_addn_addr(pdata, (u8 *)mc_addr_set++, index++);
48949a5e622SChandu Babu N 
49049a5e622SChandu Babu N 	return 0;
49149a5e622SChandu Babu N }
49249a5e622SChandu Babu N 
493e01d9b2eSChandu Babu N static int
494e01d9b2eSChandu Babu N axgbe_dev_uc_hash_table_set(struct rte_eth_dev *dev,
495e01d9b2eSChandu Babu N 			    struct rte_ether_addr *mac_addr, uint8_t add)
496e01d9b2eSChandu Babu N {
497e01d9b2eSChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
498e01d9b2eSChandu Babu N 	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
499e01d9b2eSChandu Babu N 
500e01d9b2eSChandu Babu N 	if (!hw_feat->hash_table_size) {
501e01d9b2eSChandu Babu N 		PMD_DRV_LOG(ERR, "MAC Hash Table not supported\n");
502e01d9b2eSChandu Babu N 		return -ENOTSUP;
503e01d9b2eSChandu Babu N 	}
504e01d9b2eSChandu Babu N 
505e01d9b2eSChandu Babu N 	axgbe_set_mac_hash_table(pdata, (u8 *)mac_addr, add);
506e01d9b2eSChandu Babu N 
507e01d9b2eSChandu Babu N 	if (pdata->uc_hash_mac_addr > 0) {
508e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1);
509e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1);
510e01d9b2eSChandu Babu N 	} else {
511e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 0);
512e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0);
513e01d9b2eSChandu Babu N 	}
514e01d9b2eSChandu Babu N 	return 0;
515e01d9b2eSChandu Babu N }
516e01d9b2eSChandu Babu N 
517e01d9b2eSChandu Babu N static int
518e01d9b2eSChandu Babu N axgbe_dev_uc_all_hash_table_set(struct rte_eth_dev *dev, uint8_t add)
519e01d9b2eSChandu Babu N {
520e01d9b2eSChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
521e01d9b2eSChandu Babu N 	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
522e01d9b2eSChandu Babu N 	uint32_t index;
523e01d9b2eSChandu Babu N 
524e01d9b2eSChandu Babu N 	if (!hw_feat->hash_table_size) {
525e01d9b2eSChandu Babu N 		PMD_DRV_LOG(ERR, "MAC Hash Table not supported\n");
526e01d9b2eSChandu Babu N 		return -ENOTSUP;
527e01d9b2eSChandu Babu N 	}
528e01d9b2eSChandu Babu N 
529e01d9b2eSChandu Babu N 	for (index = 0; index < pdata->hash_table_count; index++) {
530e01d9b2eSChandu Babu N 		if (add)
531e01d9b2eSChandu Babu N 			pdata->uc_hash_table[index] = ~0;
532e01d9b2eSChandu Babu N 		else
533e01d9b2eSChandu Babu N 			pdata->uc_hash_table[index] = 0;
534e01d9b2eSChandu Babu N 
535e01d9b2eSChandu Babu N 		PMD_DRV_LOG(DEBUG, "%s MAC hash table at Index %#x\n",
536e01d9b2eSChandu Babu N 			    add ? "set" : "clear", index);
537e01d9b2eSChandu Babu N 
538e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE(pdata, MAC_HTR(index),
539e01d9b2eSChandu Babu N 			       pdata->uc_hash_table[index]);
540e01d9b2eSChandu Babu N 	}
541e01d9b2eSChandu Babu N 
542e01d9b2eSChandu Babu N 	if (add) {
543e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1);
544e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1);
545e01d9b2eSChandu Babu N 	} else {
546e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 0);
547e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0);
548e01d9b2eSChandu Babu N 	}
549e01d9b2eSChandu Babu N 	return 0;
550e01d9b2eSChandu Babu N }
551e01d9b2eSChandu Babu N 
55244d45ffeSRavi Kumar /* return 0 means link status changed, -1 means not changed */
55344d45ffeSRavi Kumar static int
55444d45ffeSRavi Kumar axgbe_dev_link_update(struct rte_eth_dev *dev,
55544d45ffeSRavi Kumar 		      int wait_to_complete __rte_unused)
55644d45ffeSRavi Kumar {
55744d45ffeSRavi Kumar 	struct axgbe_port *pdata = dev->data->dev_private;
55844d45ffeSRavi Kumar 	struct rte_eth_link link;
55944d45ffeSRavi Kumar 	int ret = 0;
56044d45ffeSRavi Kumar 
56144d45ffeSRavi Kumar 	PMD_INIT_FUNC_TRACE();
56244d45ffeSRavi Kumar 	rte_delay_ms(800);
56344d45ffeSRavi Kumar 
56444d45ffeSRavi Kumar 	pdata->phy_if.phy_status(pdata);
56544d45ffeSRavi Kumar 
56644d45ffeSRavi Kumar 	memset(&link, 0, sizeof(struct rte_eth_link));
56744d45ffeSRavi Kumar 	link.link_duplex = pdata->phy.duplex;
56844d45ffeSRavi Kumar 	link.link_status = pdata->phy_link;
56944d45ffeSRavi Kumar 	link.link_speed = pdata->phy_speed;
57044d45ffeSRavi Kumar 	link.link_autoneg = !(dev->data->dev_conf.link_speeds &
57144d45ffeSRavi Kumar 			      ETH_LINK_SPEED_FIXED);
57244d45ffeSRavi Kumar 	ret = rte_eth_linkstatus_set(dev, &link);
57344d45ffeSRavi Kumar 	if (ret == -1)
57444d45ffeSRavi Kumar 		PMD_DRV_LOG(ERR, "No change in link status\n");
57544d45ffeSRavi Kumar 
57644d45ffeSRavi Kumar 	return ret;
57744d45ffeSRavi Kumar }
57844d45ffeSRavi Kumar 
579df4867cdSChandu Babu N static int
580df4867cdSChandu Babu N axgbe_dev_get_regs(struct rte_eth_dev *dev, struct rte_dev_reg_info *regs)
581df4867cdSChandu Babu N {
582df4867cdSChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
583df4867cdSChandu Babu N 
584df4867cdSChandu Babu N 	if (regs->data == NULL) {
585df4867cdSChandu Babu N 		regs->length = axgbe_regs_get_count(pdata);
586df4867cdSChandu Babu N 		regs->width = sizeof(uint32_t);
587df4867cdSChandu Babu N 		return 0;
588df4867cdSChandu Babu N 	}
589df4867cdSChandu Babu N 
590df4867cdSChandu Babu N 	/* Only full register dump is supported */
591df4867cdSChandu Babu N 	if (regs->length &&
592df4867cdSChandu Babu N 	    regs->length != (uint32_t)axgbe_regs_get_count(pdata))
593df4867cdSChandu Babu N 		return -ENOTSUP;
594df4867cdSChandu Babu N 
595df4867cdSChandu Babu N 	regs->version = pdata->pci_dev->id.vendor_id << 16 |
596df4867cdSChandu Babu N 			pdata->pci_dev->id.device_id;
597df4867cdSChandu Babu N 	axgbe_regs_dump(pdata, regs->data);
598df4867cdSChandu Babu N 	return 0;
599df4867cdSChandu Babu N }
6009d1ef6b2SChandu Babu N static void axgbe_read_mmc_stats(struct axgbe_port *pdata)
6019d1ef6b2SChandu Babu N {
6029d1ef6b2SChandu Babu N 	struct axgbe_mmc_stats *stats = &pdata->mmc_stats;
6039d1ef6b2SChandu Babu N 
6049d1ef6b2SChandu Babu N 	/* Freeze counters */
6059d1ef6b2SChandu Babu N 	AXGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 1);
6069d1ef6b2SChandu Babu N 
6079d1ef6b2SChandu Babu N 	/* Tx counters */
6089d1ef6b2SChandu Babu N 	stats->txoctetcount_gb +=
6099d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_GB_LO);
6109d1ef6b2SChandu Babu N 	stats->txoctetcount_gb +=
6119d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_GB_HI) << 32);
6129d1ef6b2SChandu Babu N 
6139d1ef6b2SChandu Babu N 	stats->txframecount_gb +=
6149d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_GB_LO);
6159d1ef6b2SChandu Babu N 	stats->txframecount_gb +=
6169d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_GB_HI) << 32);
6179d1ef6b2SChandu Babu N 
6189d1ef6b2SChandu Babu N 	stats->txbroadcastframes_g +=
6199d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_G_LO);
6209d1ef6b2SChandu Babu N 	stats->txbroadcastframes_g +=
6219d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_G_HI) << 32);
6229d1ef6b2SChandu Babu N 
6239d1ef6b2SChandu Babu N 	stats->txmulticastframes_g +=
6249d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_G_LO);
6259d1ef6b2SChandu Babu N 	stats->txmulticastframes_g +=
6269d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_G_HI) << 32);
6279d1ef6b2SChandu Babu N 
6289d1ef6b2SChandu Babu N 	stats->tx64octets_gb +=
6299d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TX64OCTETS_GB_LO);
6309d1ef6b2SChandu Babu N 	stats->tx64octets_gb +=
6319d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX64OCTETS_GB_HI) << 32);
6329d1ef6b2SChandu Babu N 
6339d1ef6b2SChandu Babu N 	stats->tx65to127octets_gb +=
6349d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TX65TO127OCTETS_GB_LO);
6359d1ef6b2SChandu Babu N 	stats->tx65to127octets_gb +=
6369d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX65TO127OCTETS_GB_HI) << 32);
6379d1ef6b2SChandu Babu N 
6389d1ef6b2SChandu Babu N 	stats->tx128to255octets_gb +=
6399d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TX128TO255OCTETS_GB_LO);
6409d1ef6b2SChandu Babu N 	stats->tx128to255octets_gb +=
6419d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX128TO255OCTETS_GB_HI) << 32);
6429d1ef6b2SChandu Babu N 
6439d1ef6b2SChandu Babu N 	stats->tx256to511octets_gb +=
6449d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TX256TO511OCTETS_GB_LO);
6459d1ef6b2SChandu Babu N 	stats->tx256to511octets_gb +=
6469d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX256TO511OCTETS_GB_HI) << 32);
6479d1ef6b2SChandu Babu N 
6489d1ef6b2SChandu Babu N 	stats->tx512to1023octets_gb +=
6499d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TX512TO1023OCTETS_GB_LO);
6509d1ef6b2SChandu Babu N 	stats->tx512to1023octets_gb +=
6519d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX512TO1023OCTETS_GB_HI) << 32);
6529d1ef6b2SChandu Babu N 
6539d1ef6b2SChandu Babu N 	stats->tx1024tomaxoctets_gb +=
6549d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TX1024TOMAXOCTETS_GB_LO);
6559d1ef6b2SChandu Babu N 	stats->tx1024tomaxoctets_gb +=
6569d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX1024TOMAXOCTETS_GB_HI) << 32);
6579d1ef6b2SChandu Babu N 
6589d1ef6b2SChandu Babu N 	stats->txunicastframes_gb +=
6599d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXUNICASTFRAMES_GB_LO);
6609d1ef6b2SChandu Babu N 	stats->txunicastframes_gb +=
6619d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXUNICASTFRAMES_GB_HI) << 32);
6629d1ef6b2SChandu Babu N 
6639d1ef6b2SChandu Babu N 	stats->txmulticastframes_gb +=
6649d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_GB_LO);
6659d1ef6b2SChandu Babu N 	stats->txmulticastframes_gb +=
6669d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_GB_HI) << 32);
6679d1ef6b2SChandu Babu N 
6689d1ef6b2SChandu Babu N 	stats->txbroadcastframes_g +=
6699d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_GB_LO);
6709d1ef6b2SChandu Babu N 	stats->txbroadcastframes_g +=
6719d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_GB_HI) << 32);
6729d1ef6b2SChandu Babu N 
6739d1ef6b2SChandu Babu N 	stats->txunderflowerror +=
6749d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXUNDERFLOWERROR_LO);
6759d1ef6b2SChandu Babu N 	stats->txunderflowerror +=
6769d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXUNDERFLOWERROR_HI) << 32);
6779d1ef6b2SChandu Babu N 
6789d1ef6b2SChandu Babu N 	stats->txoctetcount_g +=
6799d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_G_LO);
6809d1ef6b2SChandu Babu N 	stats->txoctetcount_g +=
6819d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_G_HI) << 32);
6829d1ef6b2SChandu Babu N 
6839d1ef6b2SChandu Babu N 	stats->txframecount_g +=
6849d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_G_LO);
6859d1ef6b2SChandu Babu N 	stats->txframecount_g +=
6869d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_G_HI) << 32);
6879d1ef6b2SChandu Babu N 
6889d1ef6b2SChandu Babu N 	stats->txpauseframes +=
6899d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXPAUSEFRAMES_LO);
6909d1ef6b2SChandu Babu N 	stats->txpauseframes +=
6919d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXPAUSEFRAMES_HI) << 32);
6929d1ef6b2SChandu Babu N 
6939d1ef6b2SChandu Babu N 	stats->txvlanframes_g +=
6949d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXVLANFRAMES_G_LO);
6959d1ef6b2SChandu Babu N 	stats->txvlanframes_g +=
6969d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXVLANFRAMES_G_HI) << 32);
6979d1ef6b2SChandu Babu N 
6989d1ef6b2SChandu Babu N 	/* Rx counters */
6999d1ef6b2SChandu Babu N 	stats->rxframecount_gb +=
7009d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXFRAMECOUNT_GB_LO);
7019d1ef6b2SChandu Babu N 	stats->rxframecount_gb +=
7029d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXFRAMECOUNT_GB_HI) << 32);
7039d1ef6b2SChandu Babu N 
7049d1ef6b2SChandu Babu N 	stats->rxoctetcount_gb +=
7059d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_GB_LO);
7069d1ef6b2SChandu Babu N 	stats->rxoctetcount_gb +=
7079d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_GB_HI) << 32);
7089d1ef6b2SChandu Babu N 
7099d1ef6b2SChandu Babu N 	stats->rxoctetcount_g +=
7109d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_G_LO);
7119d1ef6b2SChandu Babu N 	stats->rxoctetcount_g +=
7129d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_G_HI) << 32);
7139d1ef6b2SChandu Babu N 
7149d1ef6b2SChandu Babu N 	stats->rxbroadcastframes_g +=
7159d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXBROADCASTFRAMES_G_LO);
7169d1ef6b2SChandu Babu N 	stats->rxbroadcastframes_g +=
7179d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXBROADCASTFRAMES_G_HI) << 32);
7189d1ef6b2SChandu Babu N 
7199d1ef6b2SChandu Babu N 	stats->rxmulticastframes_g +=
7209d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXMULTICASTFRAMES_G_LO);
7219d1ef6b2SChandu Babu N 	stats->rxmulticastframes_g +=
7229d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXMULTICASTFRAMES_G_HI) << 32);
7239d1ef6b2SChandu Babu N 
7249d1ef6b2SChandu Babu N 	stats->rxcrcerror +=
7259d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXCRCERROR_LO);
7269d1ef6b2SChandu Babu N 	stats->rxcrcerror +=
7279d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXCRCERROR_HI) << 32);
7289d1ef6b2SChandu Babu N 
7299d1ef6b2SChandu Babu N 	stats->rxrunterror +=
7309d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXRUNTERROR);
7319d1ef6b2SChandu Babu N 
7329d1ef6b2SChandu Babu N 	stats->rxjabbererror +=
7339d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXJABBERERROR);
7349d1ef6b2SChandu Babu N 
7359d1ef6b2SChandu Babu N 	stats->rxundersize_g +=
7369d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXUNDERSIZE_G);
7379d1ef6b2SChandu Babu N 
7389d1ef6b2SChandu Babu N 	stats->rxoversize_g +=
7399d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXOVERSIZE_G);
7409d1ef6b2SChandu Babu N 
7419d1ef6b2SChandu Babu N 	stats->rx64octets_gb +=
7429d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RX64OCTETS_GB_LO);
7439d1ef6b2SChandu Babu N 	stats->rx64octets_gb +=
7449d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX64OCTETS_GB_HI) << 32);
7459d1ef6b2SChandu Babu N 
7469d1ef6b2SChandu Babu N 	stats->rx65to127octets_gb +=
7479d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RX65TO127OCTETS_GB_LO);
7489d1ef6b2SChandu Babu N 	stats->rx65to127octets_gb +=
7499d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX65TO127OCTETS_GB_HI) << 32);
7509d1ef6b2SChandu Babu N 
7519d1ef6b2SChandu Babu N 	stats->rx128to255octets_gb +=
7529d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RX128TO255OCTETS_GB_LO);
7539d1ef6b2SChandu Babu N 	stats->rx128to255octets_gb +=
7549d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX128TO255OCTETS_GB_HI) << 32);
7559d1ef6b2SChandu Babu N 
7569d1ef6b2SChandu Babu N 	stats->rx256to511octets_gb +=
7579d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RX256TO511OCTETS_GB_LO);
7589d1ef6b2SChandu Babu N 	stats->rx256to511octets_gb +=
7599d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX256TO511OCTETS_GB_HI) << 32);
7609d1ef6b2SChandu Babu N 
7619d1ef6b2SChandu Babu N 	stats->rx512to1023octets_gb +=
7629d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RX512TO1023OCTETS_GB_LO);
7639d1ef6b2SChandu Babu N 	stats->rx512to1023octets_gb +=
7649d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX512TO1023OCTETS_GB_HI) << 32);
7659d1ef6b2SChandu Babu N 
7669d1ef6b2SChandu Babu N 	stats->rx1024tomaxoctets_gb +=
7679d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RX1024TOMAXOCTETS_GB_LO);
7689d1ef6b2SChandu Babu N 	stats->rx1024tomaxoctets_gb +=
7699d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX1024TOMAXOCTETS_GB_HI) << 32);
7709d1ef6b2SChandu Babu N 
7719d1ef6b2SChandu Babu N 	stats->rxunicastframes_g +=
7729d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXUNICASTFRAMES_G_LO);
7739d1ef6b2SChandu Babu N 	stats->rxunicastframes_g +=
7749d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXUNICASTFRAMES_G_HI) << 32);
7759d1ef6b2SChandu Babu N 
7769d1ef6b2SChandu Babu N 	stats->rxlengtherror +=
7779d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXLENGTHERROR_LO);
7789d1ef6b2SChandu Babu N 	stats->rxlengtherror +=
7799d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXLENGTHERROR_HI) << 32);
7809d1ef6b2SChandu Babu N 
7819d1ef6b2SChandu Babu N 	stats->rxoutofrangetype +=
7829d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXOUTOFRANGETYPE_LO);
7839d1ef6b2SChandu Babu N 	stats->rxoutofrangetype +=
7849d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXOUTOFRANGETYPE_HI) << 32);
7859d1ef6b2SChandu Babu N 
7869d1ef6b2SChandu Babu N 	stats->rxpauseframes +=
7879d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXPAUSEFRAMES_LO);
7889d1ef6b2SChandu Babu N 	stats->rxpauseframes +=
7899d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXPAUSEFRAMES_HI) << 32);
7909d1ef6b2SChandu Babu N 
7919d1ef6b2SChandu Babu N 	stats->rxfifooverflow +=
7929d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXFIFOOVERFLOW_LO);
7939d1ef6b2SChandu Babu N 	stats->rxfifooverflow +=
7949d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXFIFOOVERFLOW_HI) << 32);
7959d1ef6b2SChandu Babu N 
7969d1ef6b2SChandu Babu N 	stats->rxvlanframes_gb +=
7979d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXVLANFRAMES_GB_LO);
7989d1ef6b2SChandu Babu N 	stats->rxvlanframes_gb +=
7999d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXVLANFRAMES_GB_HI) << 32);
8009d1ef6b2SChandu Babu N 
8019d1ef6b2SChandu Babu N 	stats->rxwatchdogerror +=
8029d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXWATCHDOGERROR);
8039d1ef6b2SChandu Babu N 
8049d1ef6b2SChandu Babu N 	/* Un-freeze counters */
8059d1ef6b2SChandu Babu N 	AXGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 0);
8069d1ef6b2SChandu Babu N }
8079d1ef6b2SChandu Babu N 
8089d1ef6b2SChandu Babu N static int
8099d1ef6b2SChandu Babu N axgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats,
8109d1ef6b2SChandu Babu N 		     unsigned int n)
8119d1ef6b2SChandu Babu N {
8129d1ef6b2SChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
8139d1ef6b2SChandu Babu N 	unsigned int i;
8149d1ef6b2SChandu Babu N 
8159d1ef6b2SChandu Babu N 	if (!stats)
8169d1ef6b2SChandu Babu N 		return 0;
8179d1ef6b2SChandu Babu N 
8189d1ef6b2SChandu Babu N 	axgbe_read_mmc_stats(pdata);
8199d1ef6b2SChandu Babu N 
8209d1ef6b2SChandu Babu N 	for (i = 0; i < n && i < AXGBE_XSTATS_COUNT; i++) {
8219d1ef6b2SChandu Babu N 		stats[i].id = i;
8229d1ef6b2SChandu Babu N 		stats[i].value = *(u64 *)((uint8_t *)&pdata->mmc_stats +
8239d1ef6b2SChandu Babu N 				axgbe_xstats_strings[i].offset);
8249d1ef6b2SChandu Babu N 	}
8259d1ef6b2SChandu Babu N 
8269d1ef6b2SChandu Babu N 	return i;
8279d1ef6b2SChandu Babu N }
8289d1ef6b2SChandu Babu N 
8299d1ef6b2SChandu Babu N static int
8309d1ef6b2SChandu Babu N axgbe_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
8319d1ef6b2SChandu Babu N 			   struct rte_eth_xstat_name *xstats_names,
8329d1ef6b2SChandu Babu N 			   unsigned int n)
8339d1ef6b2SChandu Babu N {
8349d1ef6b2SChandu Babu N 	unsigned int i;
8359d1ef6b2SChandu Babu N 
8369d1ef6b2SChandu Babu N 	if (n >= AXGBE_XSTATS_COUNT && xstats_names) {
8379d1ef6b2SChandu Babu N 		for (i = 0; i < AXGBE_XSTATS_COUNT; ++i) {
8389d1ef6b2SChandu Babu N 			snprintf(xstats_names[i].name,
8399d1ef6b2SChandu Babu N 				 RTE_ETH_XSTATS_NAME_SIZE, "%s",
8409d1ef6b2SChandu Babu N 				 axgbe_xstats_strings[i].name);
8419d1ef6b2SChandu Babu N 		}
8429d1ef6b2SChandu Babu N 	}
8439d1ef6b2SChandu Babu N 
8449d1ef6b2SChandu Babu N 	return AXGBE_XSTATS_COUNT;
8459d1ef6b2SChandu Babu N }
8469d1ef6b2SChandu Babu N 
8479d1ef6b2SChandu Babu N static int
8489d1ef6b2SChandu Babu N axgbe_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
8499d1ef6b2SChandu Babu N 			   uint64_t *values, unsigned int n)
8509d1ef6b2SChandu Babu N {
8519d1ef6b2SChandu Babu N 	unsigned int i;
8529d1ef6b2SChandu Babu N 	uint64_t values_copy[AXGBE_XSTATS_COUNT];
8539d1ef6b2SChandu Babu N 
8549d1ef6b2SChandu Babu N 	if (!ids) {
8559d1ef6b2SChandu Babu N 		struct axgbe_port *pdata = dev->data->dev_private;
8569d1ef6b2SChandu Babu N 
8579d1ef6b2SChandu Babu N 		if (n < AXGBE_XSTATS_COUNT)
8589d1ef6b2SChandu Babu N 			return AXGBE_XSTATS_COUNT;
8599d1ef6b2SChandu Babu N 
8609d1ef6b2SChandu Babu N 		axgbe_read_mmc_stats(pdata);
8619d1ef6b2SChandu Babu N 
8629d1ef6b2SChandu Babu N 		for (i = 0; i < AXGBE_XSTATS_COUNT; i++) {
8639d1ef6b2SChandu Babu N 			values[i] = *(u64 *)((uint8_t *)&pdata->mmc_stats +
8649d1ef6b2SChandu Babu N 					axgbe_xstats_strings[i].offset);
8659d1ef6b2SChandu Babu N 		}
8669d1ef6b2SChandu Babu N 
8679d1ef6b2SChandu Babu N 		return i;
8689d1ef6b2SChandu Babu N 	}
8699d1ef6b2SChandu Babu N 
8709d1ef6b2SChandu Babu N 	axgbe_dev_xstats_get_by_id(dev, NULL, values_copy, AXGBE_XSTATS_COUNT);
8719d1ef6b2SChandu Babu N 
8729d1ef6b2SChandu Babu N 	for (i = 0; i < n; i++) {
8739d1ef6b2SChandu Babu N 		if (ids[i] >= AXGBE_XSTATS_COUNT) {
8749d1ef6b2SChandu Babu N 			PMD_DRV_LOG(ERR, "id value isn't valid\n");
8759d1ef6b2SChandu Babu N 			return -1;
8769d1ef6b2SChandu Babu N 		}
8779d1ef6b2SChandu Babu N 		values[i] = values_copy[ids[i]];
8789d1ef6b2SChandu Babu N 	}
8799d1ef6b2SChandu Babu N 	return n;
8809d1ef6b2SChandu Babu N }
8819d1ef6b2SChandu Babu N 
8829d1ef6b2SChandu Babu N static int
8839d1ef6b2SChandu Babu N axgbe_dev_xstats_get_names_by_id(struct rte_eth_dev *dev,
8849d1ef6b2SChandu Babu N 				 struct rte_eth_xstat_name *xstats_names,
8859d1ef6b2SChandu Babu N 				 const uint64_t *ids,
8869d1ef6b2SChandu Babu N 				 unsigned int size)
8879d1ef6b2SChandu Babu N {
8889d1ef6b2SChandu Babu N 	struct rte_eth_xstat_name xstats_names_copy[AXGBE_XSTATS_COUNT];
8899d1ef6b2SChandu Babu N 	unsigned int i;
8909d1ef6b2SChandu Babu N 
8919d1ef6b2SChandu Babu N 	if (!ids)
8929d1ef6b2SChandu Babu N 		return axgbe_dev_xstats_get_names(dev, xstats_names, size);
8939d1ef6b2SChandu Babu N 
8949d1ef6b2SChandu Babu N 	axgbe_dev_xstats_get_names(dev, xstats_names_copy, size);
8959d1ef6b2SChandu Babu N 
8969d1ef6b2SChandu Babu N 	for (i = 0; i < size; i++) {
8979d1ef6b2SChandu Babu N 		if (ids[i] >= AXGBE_XSTATS_COUNT) {
8989d1ef6b2SChandu Babu N 			PMD_DRV_LOG(ERR, "id value isn't valid\n");
8999d1ef6b2SChandu Babu N 			return -1;
9009d1ef6b2SChandu Babu N 		}
9019d1ef6b2SChandu Babu N 		strcpy(xstats_names[i].name, xstats_names_copy[ids[i]].name);
9029d1ef6b2SChandu Babu N 	}
9039d1ef6b2SChandu Babu N 	return size;
9049d1ef6b2SChandu Babu N }
9059d1ef6b2SChandu Babu N 
9069d1ef6b2SChandu Babu N static int
9079d1ef6b2SChandu Babu N axgbe_dev_xstats_reset(struct rte_eth_dev *dev)
9089d1ef6b2SChandu Babu N {
9099d1ef6b2SChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
9109d1ef6b2SChandu Babu N 	struct axgbe_mmc_stats *stats = &pdata->mmc_stats;
9119d1ef6b2SChandu Babu N 
9129d1ef6b2SChandu Babu N 	/* MMC registers are configured for reset on read */
9139d1ef6b2SChandu Babu N 	axgbe_read_mmc_stats(pdata);
9149d1ef6b2SChandu Babu N 
9159d1ef6b2SChandu Babu N 	/* Reset stats */
9169d1ef6b2SChandu Babu N 	memset(stats, 0, sizeof(*stats));
9179d1ef6b2SChandu Babu N 
9189d1ef6b2SChandu Babu N 	return 0;
9199d1ef6b2SChandu Babu N }
9209d1ef6b2SChandu Babu N 
9213e730511SRavi Kumar static int
9223e730511SRavi Kumar axgbe_dev_stats_get(struct rte_eth_dev *dev,
9233e730511SRavi Kumar 		    struct rte_eth_stats *stats)
9243e730511SRavi Kumar {
9253e730511SRavi Kumar 	struct axgbe_rx_queue *rxq;
9263e730511SRavi Kumar 	struct axgbe_tx_queue *txq;
9279d1ef6b2SChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
9289d1ef6b2SChandu Babu N 	struct axgbe_mmc_stats *mmc_stats = &pdata->mmc_stats;
9293e730511SRavi Kumar 	unsigned int i;
9303e730511SRavi Kumar 
9319d1ef6b2SChandu Babu N 	axgbe_read_mmc_stats(pdata);
9329d1ef6b2SChandu Babu N 
9339d1ef6b2SChandu Babu N 	stats->imissed = mmc_stats->rxfifooverflow;
9349d1ef6b2SChandu Babu N 
9353e730511SRavi Kumar 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
9363e730511SRavi Kumar 		rxq = dev->data->rx_queues[i];
9373e730511SRavi Kumar 		stats->q_ipackets[i] = rxq->pkts;
9383e730511SRavi Kumar 		stats->ipackets += rxq->pkts;
9393e730511SRavi Kumar 		stats->q_ibytes[i] = rxq->bytes;
9403e730511SRavi Kumar 		stats->ibytes += rxq->bytes;
9419d1ef6b2SChandu Babu N 		stats->rx_nombuf += rxq->rx_mbuf_alloc_failed;
9429d1ef6b2SChandu Babu N 		stats->q_errors[i] = rxq->errors + rxq->rx_mbuf_alloc_failed;
9439d1ef6b2SChandu Babu N 		stats->ierrors += rxq->errors;
9443e730511SRavi Kumar 	}
9459d1ef6b2SChandu Babu N 
9463e730511SRavi Kumar 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
9473e730511SRavi Kumar 		txq = dev->data->tx_queues[i];
9483e730511SRavi Kumar 		stats->q_opackets[i] = txq->pkts;
9493e730511SRavi Kumar 		stats->opackets += txq->pkts;
9503e730511SRavi Kumar 		stats->q_obytes[i] = txq->bytes;
9513e730511SRavi Kumar 		stats->obytes += txq->bytes;
9529d1ef6b2SChandu Babu N 		stats->oerrors += txq->errors;
9533e730511SRavi Kumar 	}
9543e730511SRavi Kumar 
9553e730511SRavi Kumar 	return 0;
9563e730511SRavi Kumar }
9573e730511SRavi Kumar 
9589970a9adSIgor Romanov static int
9593e730511SRavi Kumar axgbe_dev_stats_reset(struct rte_eth_dev *dev)
9603e730511SRavi Kumar {
9613e730511SRavi Kumar 	struct axgbe_rx_queue *rxq;
9623e730511SRavi Kumar 	struct axgbe_tx_queue *txq;
9633e730511SRavi Kumar 	unsigned int i;
9643e730511SRavi Kumar 
9653e730511SRavi Kumar 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
9663e730511SRavi Kumar 		rxq = dev->data->rx_queues[i];
9673e730511SRavi Kumar 		rxq->pkts = 0;
9683e730511SRavi Kumar 		rxq->bytes = 0;
9693e730511SRavi Kumar 		rxq->errors = 0;
9709d1ef6b2SChandu Babu N 		rxq->rx_mbuf_alloc_failed = 0;
9713e730511SRavi Kumar 	}
9723e730511SRavi Kumar 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
9733e730511SRavi Kumar 		txq = dev->data->tx_queues[i];
9743e730511SRavi Kumar 		txq->pkts = 0;
9753e730511SRavi Kumar 		txq->bytes = 0;
9763e730511SRavi Kumar 		txq->errors = 0;
9773e730511SRavi Kumar 	}
9789970a9adSIgor Romanov 
9799970a9adSIgor Romanov 	return 0;
9803e730511SRavi Kumar }
9813e730511SRavi Kumar 
982bdad90d1SIvan Ilchenko static int
983cd8c7c7cSFerruh Yigit axgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
9849e890103SRavi Kumar {
9859e890103SRavi Kumar 	struct axgbe_port *pdata = dev->data->dev_private;
9869e890103SRavi Kumar 
9879e890103SRavi Kumar 	dev_info->max_rx_queues = pdata->rx_ring_count;
9889e890103SRavi Kumar 	dev_info->max_tx_queues = pdata->tx_ring_count;
9899e890103SRavi Kumar 	dev_info->min_rx_bufsize = AXGBE_RX_MIN_BUF_SIZE;
9909e890103SRavi Kumar 	dev_info->max_rx_pktlen = AXGBE_RX_MAX_BUF_SIZE;
99149a5e622SChandu Babu N 	dev_info->max_mac_addrs = pdata->hw_feat.addn_mac + 1;
992e01d9b2eSChandu Babu N 	dev_info->max_hash_mac_addrs = pdata->hw_feat.hash_table_size;
9939e890103SRavi Kumar 	dev_info->speed_capa =  ETH_LINK_SPEED_10G;
9949e890103SRavi Kumar 
9959e890103SRavi Kumar 	dev_info->rx_offload_capa =
9969e890103SRavi Kumar 		DEV_RX_OFFLOAD_IPV4_CKSUM |
9979e890103SRavi Kumar 		DEV_RX_OFFLOAD_UDP_CKSUM  |
99870815c9eSFerruh Yigit 		DEV_RX_OFFLOAD_TCP_CKSUM  |
999965b3127SSelwin Sebastian 		DEV_RX_OFFLOAD_JUMBO_FRAME	|
1000965b3127SSelwin Sebastian 		DEV_RX_OFFLOAD_SCATTER	  |
100170815c9eSFerruh Yigit 		DEV_RX_OFFLOAD_KEEP_CRC;
10029e890103SRavi Kumar 
10039e890103SRavi Kumar 	dev_info->tx_offload_capa =
10049e890103SRavi Kumar 		DEV_TX_OFFLOAD_IPV4_CKSUM  |
10059e890103SRavi Kumar 		DEV_TX_OFFLOAD_UDP_CKSUM   |
10069e890103SRavi Kumar 		DEV_TX_OFFLOAD_TCP_CKSUM;
10079e890103SRavi Kumar 
10089e890103SRavi Kumar 	if (pdata->hw_feat.rss) {
10099e890103SRavi Kumar 		dev_info->flow_type_rss_offloads = AXGBE_RSS_OFFLOAD;
10109e890103SRavi Kumar 		dev_info->reta_size = pdata->hw_feat.hash_table_size;
10119e890103SRavi Kumar 		dev_info->hash_key_size =  AXGBE_RSS_HASH_KEY_SIZE;
10129e890103SRavi Kumar 	}
10139e890103SRavi Kumar 
10149e890103SRavi Kumar 	dev_info->rx_desc_lim = rx_desc_lim;
10159e890103SRavi Kumar 	dev_info->tx_desc_lim = tx_desc_lim;
10169e890103SRavi Kumar 
10179e890103SRavi Kumar 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
10189e890103SRavi Kumar 		.rx_free_thresh = AXGBE_RX_FREE_THRESH,
10199e890103SRavi Kumar 	};
10209e890103SRavi Kumar 
10219e890103SRavi Kumar 	dev_info->default_txconf = (struct rte_eth_txconf) {
10229e890103SRavi Kumar 		.tx_free_thresh = AXGBE_TX_FREE_THRESH,
10239e890103SRavi Kumar 	};
1024bdad90d1SIvan Ilchenko 
1025bdad90d1SIvan Ilchenko 	return 0;
10269e890103SRavi Kumar }
10279e890103SRavi Kumar 
1028cf97f33eSAmaranath Somalapuram static int
1029cf97f33eSAmaranath Somalapuram axgbe_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
1030cf97f33eSAmaranath Somalapuram {
1031cf97f33eSAmaranath Somalapuram 	struct axgbe_port *pdata = dev->data->dev_private;
1032cf97f33eSAmaranath Somalapuram 	struct xgbe_fc_info fc = pdata->fc;
1033cf97f33eSAmaranath Somalapuram 	unsigned int reg, reg_val = 0;
1034cf97f33eSAmaranath Somalapuram 
1035cf97f33eSAmaranath Somalapuram 	reg = MAC_Q0TFCR;
1036cf97f33eSAmaranath Somalapuram 	reg_val = AXGMAC_IOREAD(pdata, reg);
1037cf97f33eSAmaranath Somalapuram 	fc.low_water[0] =  AXGMAC_MTL_IOREAD_BITS(pdata, 0, MTL_Q_RQFCR, RFA);
1038cf97f33eSAmaranath Somalapuram 	fc.high_water[0] =  AXGMAC_MTL_IOREAD_BITS(pdata, 0, MTL_Q_RQFCR, RFD);
1039cf97f33eSAmaranath Somalapuram 	fc.pause_time[0] = AXGMAC_GET_BITS(reg_val, MAC_Q0TFCR, PT);
1040cf97f33eSAmaranath Somalapuram 	fc.autoneg = pdata->pause_autoneg;
1041cf97f33eSAmaranath Somalapuram 
1042cf97f33eSAmaranath Somalapuram 	if (pdata->rx_pause && pdata->tx_pause)
1043cf97f33eSAmaranath Somalapuram 		fc.mode = RTE_FC_FULL;
1044cf97f33eSAmaranath Somalapuram 	else if (pdata->rx_pause)
1045cf97f33eSAmaranath Somalapuram 		fc.mode = RTE_FC_RX_PAUSE;
1046cf97f33eSAmaranath Somalapuram 	else if (pdata->tx_pause)
1047cf97f33eSAmaranath Somalapuram 		fc.mode = RTE_FC_TX_PAUSE;
1048cf97f33eSAmaranath Somalapuram 	else
1049cf97f33eSAmaranath Somalapuram 		fc.mode = RTE_FC_NONE;
1050cf97f33eSAmaranath Somalapuram 
1051cf97f33eSAmaranath Somalapuram 	fc_conf->high_water =  (1024 + (fc.low_water[0] << 9)) / 1024;
1052cf97f33eSAmaranath Somalapuram 	fc_conf->low_water =  (1024 + (fc.high_water[0] << 9)) / 1024;
1053cf97f33eSAmaranath Somalapuram 	fc_conf->pause_time = fc.pause_time[0];
1054cf97f33eSAmaranath Somalapuram 	fc_conf->send_xon = fc.send_xon;
1055cf97f33eSAmaranath Somalapuram 	fc_conf->mode = fc.mode;
1056cf97f33eSAmaranath Somalapuram 
1057cf97f33eSAmaranath Somalapuram 	return 0;
1058cf97f33eSAmaranath Somalapuram }
1059cf97f33eSAmaranath Somalapuram 
1060cf97f33eSAmaranath Somalapuram static int
1061cf97f33eSAmaranath Somalapuram axgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
1062cf97f33eSAmaranath Somalapuram {
1063cf97f33eSAmaranath Somalapuram 	struct axgbe_port *pdata = dev->data->dev_private;
1064cf97f33eSAmaranath Somalapuram 	struct xgbe_fc_info fc = pdata->fc;
1065cf97f33eSAmaranath Somalapuram 	unsigned int reg, reg_val = 0;
1066cf97f33eSAmaranath Somalapuram 	reg = MAC_Q0TFCR;
1067cf97f33eSAmaranath Somalapuram 
1068cf97f33eSAmaranath Somalapuram 	pdata->pause_autoneg = fc_conf->autoneg;
1069cf97f33eSAmaranath Somalapuram 	pdata->phy.pause_autoneg = pdata->pause_autoneg;
1070cf97f33eSAmaranath Somalapuram 	fc.send_xon = fc_conf->send_xon;
1071cf97f33eSAmaranath Somalapuram 	AXGMAC_MTL_IOWRITE_BITS(pdata, 0, MTL_Q_RQFCR, RFA,
1072cf97f33eSAmaranath Somalapuram 			AXGMAC_FLOW_CONTROL_VALUE(1024 * fc_conf->high_water));
1073cf97f33eSAmaranath Somalapuram 	AXGMAC_MTL_IOWRITE_BITS(pdata, 0, MTL_Q_RQFCR, RFD,
1074cf97f33eSAmaranath Somalapuram 			AXGMAC_FLOW_CONTROL_VALUE(1024 * fc_conf->low_water));
1075cf97f33eSAmaranath Somalapuram 	AXGMAC_SET_BITS(reg_val, MAC_Q0TFCR, PT, fc_conf->pause_time);
1076cf97f33eSAmaranath Somalapuram 	AXGMAC_IOWRITE(pdata, reg, reg_val);
1077cf97f33eSAmaranath Somalapuram 	fc.mode = fc_conf->mode;
1078cf97f33eSAmaranath Somalapuram 
1079cf97f33eSAmaranath Somalapuram 	if (fc.mode == RTE_FC_FULL) {
1080cf97f33eSAmaranath Somalapuram 		pdata->tx_pause = 1;
1081cf97f33eSAmaranath Somalapuram 		pdata->rx_pause = 1;
1082cf97f33eSAmaranath Somalapuram 	} else if (fc.mode == RTE_FC_RX_PAUSE) {
1083cf97f33eSAmaranath Somalapuram 		pdata->tx_pause = 0;
1084cf97f33eSAmaranath Somalapuram 		pdata->rx_pause = 1;
1085cf97f33eSAmaranath Somalapuram 	} else if (fc.mode == RTE_FC_TX_PAUSE) {
1086cf97f33eSAmaranath Somalapuram 		pdata->tx_pause = 1;
1087cf97f33eSAmaranath Somalapuram 		pdata->rx_pause = 0;
1088cf97f33eSAmaranath Somalapuram 	} else {
1089cf97f33eSAmaranath Somalapuram 		pdata->tx_pause = 0;
1090cf97f33eSAmaranath Somalapuram 		pdata->rx_pause = 0;
1091cf97f33eSAmaranath Somalapuram 	}
1092cf97f33eSAmaranath Somalapuram 
1093cf97f33eSAmaranath Somalapuram 	if (pdata->tx_pause != (unsigned int)pdata->phy.tx_pause)
1094cf97f33eSAmaranath Somalapuram 		pdata->hw_if.config_tx_flow_control(pdata);
1095cf97f33eSAmaranath Somalapuram 
1096cf97f33eSAmaranath Somalapuram 	if (pdata->rx_pause != (unsigned int)pdata->phy.rx_pause)
1097cf97f33eSAmaranath Somalapuram 		pdata->hw_if.config_rx_flow_control(pdata);
1098cf97f33eSAmaranath Somalapuram 
1099cf97f33eSAmaranath Somalapuram 	pdata->hw_if.config_flow_control(pdata);
1100cf97f33eSAmaranath Somalapuram 	pdata->phy.tx_pause = pdata->tx_pause;
1101cf97f33eSAmaranath Somalapuram 	pdata->phy.rx_pause = pdata->rx_pause;
1102cf97f33eSAmaranath Somalapuram 
1103cf97f33eSAmaranath Somalapuram 	return 0;
1104cf97f33eSAmaranath Somalapuram }
1105cf97f33eSAmaranath Somalapuram 
1106e0543d4eSAmaranath Somalapuram static int
1107e0543d4eSAmaranath Somalapuram axgbe_priority_flow_ctrl_set(struct rte_eth_dev *dev,
1108e0543d4eSAmaranath Somalapuram 		struct rte_eth_pfc_conf *pfc_conf)
1109e0543d4eSAmaranath Somalapuram {
1110e0543d4eSAmaranath Somalapuram 	struct axgbe_port *pdata = dev->data->dev_private;
1111e0543d4eSAmaranath Somalapuram 	struct xgbe_fc_info fc = pdata->fc;
1112e0543d4eSAmaranath Somalapuram 	uint8_t tc_num;
1113e0543d4eSAmaranath Somalapuram 
1114e0543d4eSAmaranath Somalapuram 	tc_num = pdata->pfc_map[pfc_conf->priority];
1115e0543d4eSAmaranath Somalapuram 
1116e0543d4eSAmaranath Somalapuram 	if (pfc_conf->priority >= pdata->hw_feat.tc_cnt) {
1117e0543d4eSAmaranath Somalapuram 		PMD_INIT_LOG(ERR, "Max supported  traffic class: %d\n",
1118e0543d4eSAmaranath Somalapuram 				pdata->hw_feat.tc_cnt);
1119e0543d4eSAmaranath Somalapuram 	return -EINVAL;
1120e0543d4eSAmaranath Somalapuram 	}
1121e0543d4eSAmaranath Somalapuram 
1122e0543d4eSAmaranath Somalapuram 	pdata->pause_autoneg = pfc_conf->fc.autoneg;
1123e0543d4eSAmaranath Somalapuram 	pdata->phy.pause_autoneg = pdata->pause_autoneg;
1124e0543d4eSAmaranath Somalapuram 	fc.send_xon = pfc_conf->fc.send_xon;
1125e0543d4eSAmaranath Somalapuram 	AXGMAC_MTL_IOWRITE_BITS(pdata, tc_num, MTL_Q_RQFCR, RFA,
1126e0543d4eSAmaranath Somalapuram 		AXGMAC_FLOW_CONTROL_VALUE(1024 * pfc_conf->fc.high_water));
1127e0543d4eSAmaranath Somalapuram 	AXGMAC_MTL_IOWRITE_BITS(pdata, tc_num, MTL_Q_RQFCR, RFD,
1128e0543d4eSAmaranath Somalapuram 		AXGMAC_FLOW_CONTROL_VALUE(1024 * pfc_conf->fc.low_water));
1129e0543d4eSAmaranath Somalapuram 
1130e0543d4eSAmaranath Somalapuram 	switch (tc_num) {
1131e0543d4eSAmaranath Somalapuram 	case 0:
1132e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM0R,
1133e0543d4eSAmaranath Somalapuram 				PSTC0, pfc_conf->fc.pause_time);
1134e0543d4eSAmaranath Somalapuram 		break;
1135e0543d4eSAmaranath Somalapuram 	case 1:
1136e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM0R,
1137e0543d4eSAmaranath Somalapuram 				PSTC1, pfc_conf->fc.pause_time);
1138e0543d4eSAmaranath Somalapuram 		break;
1139e0543d4eSAmaranath Somalapuram 	case 2:
1140e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM0R,
1141e0543d4eSAmaranath Somalapuram 				PSTC2, pfc_conf->fc.pause_time);
1142e0543d4eSAmaranath Somalapuram 		break;
1143e0543d4eSAmaranath Somalapuram 	case 3:
1144e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM0R,
1145e0543d4eSAmaranath Somalapuram 				PSTC3, pfc_conf->fc.pause_time);
1146e0543d4eSAmaranath Somalapuram 		break;
1147e0543d4eSAmaranath Somalapuram 	case 4:
1148e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM1R,
1149e0543d4eSAmaranath Somalapuram 				PSTC4, pfc_conf->fc.pause_time);
1150e0543d4eSAmaranath Somalapuram 		break;
1151e0543d4eSAmaranath Somalapuram 	case 5:
1152e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM1R,
1153e0543d4eSAmaranath Somalapuram 				PSTC5, pfc_conf->fc.pause_time);
1154e0543d4eSAmaranath Somalapuram 		break;
1155e0543d4eSAmaranath Somalapuram 	case 7:
1156e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM1R,
1157e0543d4eSAmaranath Somalapuram 				PSTC6, pfc_conf->fc.pause_time);
1158e0543d4eSAmaranath Somalapuram 		break;
1159e0543d4eSAmaranath Somalapuram 	case 6:
1160e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM1R,
1161e0543d4eSAmaranath Somalapuram 				PSTC7, pfc_conf->fc.pause_time);
1162e0543d4eSAmaranath Somalapuram 		break;
1163e0543d4eSAmaranath Somalapuram 	}
1164e0543d4eSAmaranath Somalapuram 
1165e0543d4eSAmaranath Somalapuram 	fc.mode = pfc_conf->fc.mode;
1166e0543d4eSAmaranath Somalapuram 
1167e0543d4eSAmaranath Somalapuram 	if (fc.mode == RTE_FC_FULL) {
1168e0543d4eSAmaranath Somalapuram 		pdata->tx_pause = 1;
1169e0543d4eSAmaranath Somalapuram 		pdata->rx_pause = 1;
1170e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 1);
1171e0543d4eSAmaranath Somalapuram 	} else if (fc.mode == RTE_FC_RX_PAUSE) {
1172e0543d4eSAmaranath Somalapuram 		pdata->tx_pause = 0;
1173e0543d4eSAmaranath Somalapuram 		pdata->rx_pause = 1;
1174e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 1);
1175e0543d4eSAmaranath Somalapuram 	} else if (fc.mode == RTE_FC_TX_PAUSE) {
1176e0543d4eSAmaranath Somalapuram 		pdata->tx_pause = 1;
1177e0543d4eSAmaranath Somalapuram 		pdata->rx_pause = 0;
1178e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 0);
1179e0543d4eSAmaranath Somalapuram 	} else {
1180e0543d4eSAmaranath Somalapuram 		pdata->tx_pause = 0;
1181e0543d4eSAmaranath Somalapuram 		pdata->rx_pause = 0;
1182e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 0);
1183e0543d4eSAmaranath Somalapuram 	}
1184e0543d4eSAmaranath Somalapuram 
1185e0543d4eSAmaranath Somalapuram 	if (pdata->tx_pause != (unsigned int)pdata->phy.tx_pause)
1186e0543d4eSAmaranath Somalapuram 		pdata->hw_if.config_tx_flow_control(pdata);
1187e0543d4eSAmaranath Somalapuram 
1188e0543d4eSAmaranath Somalapuram 	if (pdata->rx_pause != (unsigned int)pdata->phy.rx_pause)
1189e0543d4eSAmaranath Somalapuram 		pdata->hw_if.config_rx_flow_control(pdata);
1190e0543d4eSAmaranath Somalapuram 	pdata->hw_if.config_flow_control(pdata);
1191e0543d4eSAmaranath Somalapuram 	pdata->phy.tx_pause = pdata->tx_pause;
1192e0543d4eSAmaranath Somalapuram 	pdata->phy.rx_pause = pdata->rx_pause;
1193e0543d4eSAmaranath Somalapuram 
1194e0543d4eSAmaranath Somalapuram 	return 0;
1195e0543d4eSAmaranath Somalapuram }
1196e0543d4eSAmaranath Somalapuram 
11977aed95c9SAmaranath Somalapuram void
11987aed95c9SAmaranath Somalapuram axgbe_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
11997aed95c9SAmaranath Somalapuram 	struct rte_eth_rxq_info *qinfo)
12007aed95c9SAmaranath Somalapuram {
12017aed95c9SAmaranath Somalapuram 	struct   axgbe_rx_queue *rxq;
12027aed95c9SAmaranath Somalapuram 
12037aed95c9SAmaranath Somalapuram 	rxq = dev->data->rx_queues[queue_id];
12047aed95c9SAmaranath Somalapuram 	qinfo->mp = rxq->mb_pool;
12057aed95c9SAmaranath Somalapuram 	qinfo->scattered_rx = dev->data->scattered_rx;
12067aed95c9SAmaranath Somalapuram 	qinfo->nb_desc = rxq->nb_desc;
12077aed95c9SAmaranath Somalapuram 	qinfo->conf.rx_free_thresh = rxq->free_thresh;
12087aed95c9SAmaranath Somalapuram }
12097aed95c9SAmaranath Somalapuram 
12107aed95c9SAmaranath Somalapuram void
12117aed95c9SAmaranath Somalapuram axgbe_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
12127aed95c9SAmaranath Somalapuram 	struct rte_eth_txq_info *qinfo)
12137aed95c9SAmaranath Somalapuram {
12147aed95c9SAmaranath Somalapuram 	struct  axgbe_tx_queue *txq;
12157aed95c9SAmaranath Somalapuram 
12167aed95c9SAmaranath Somalapuram 	txq = dev->data->tx_queues[queue_id];
12177aed95c9SAmaranath Somalapuram 	qinfo->nb_desc = txq->nb_desc;
12187aed95c9SAmaranath Somalapuram 	qinfo->conf.tx_free_thresh = txq->free_thresh;
12197aed95c9SAmaranath Somalapuram }
1220*410cf087SAmaranath Somalapuram const uint32_t *
1221*410cf087SAmaranath Somalapuram axgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev)
1222*410cf087SAmaranath Somalapuram {
1223*410cf087SAmaranath Somalapuram 	static const uint32_t ptypes[] = {
1224*410cf087SAmaranath Somalapuram 		RTE_PTYPE_L2_ETHER,
1225*410cf087SAmaranath Somalapuram 		RTE_PTYPE_L2_ETHER_TIMESYNC,
1226*410cf087SAmaranath Somalapuram 		RTE_PTYPE_L2_ETHER_LLDP,
1227*410cf087SAmaranath Somalapuram 		RTE_PTYPE_L2_ETHER_ARP,
1228*410cf087SAmaranath Somalapuram 		RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
1229*410cf087SAmaranath Somalapuram 		RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
1230*410cf087SAmaranath Somalapuram 		RTE_PTYPE_L4_FRAG,
1231*410cf087SAmaranath Somalapuram 		RTE_PTYPE_L4_ICMP,
1232*410cf087SAmaranath Somalapuram 		RTE_PTYPE_L4_NONFRAG,
1233*410cf087SAmaranath Somalapuram 		RTE_PTYPE_L4_SCTP,
1234*410cf087SAmaranath Somalapuram 		RTE_PTYPE_L4_TCP,
1235*410cf087SAmaranath Somalapuram 		RTE_PTYPE_L4_UDP,
1236*410cf087SAmaranath Somalapuram 		RTE_PTYPE_TUNNEL_GRENAT,
1237*410cf087SAmaranath Somalapuram 		RTE_PTYPE_TUNNEL_IP,
1238*410cf087SAmaranath Somalapuram 		RTE_PTYPE_INNER_L2_ETHER,
1239*410cf087SAmaranath Somalapuram 		RTE_PTYPE_INNER_L2_ETHER_VLAN,
1240*410cf087SAmaranath Somalapuram 		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
1241*410cf087SAmaranath Somalapuram 		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
1242*410cf087SAmaranath Somalapuram 		RTE_PTYPE_INNER_L4_FRAG,
1243*410cf087SAmaranath Somalapuram 		RTE_PTYPE_INNER_L4_ICMP,
1244*410cf087SAmaranath Somalapuram 		RTE_PTYPE_INNER_L4_NONFRAG,
1245*410cf087SAmaranath Somalapuram 		RTE_PTYPE_INNER_L4_SCTP,
1246*410cf087SAmaranath Somalapuram 		RTE_PTYPE_INNER_L4_TCP,
1247*410cf087SAmaranath Somalapuram 		RTE_PTYPE_INNER_L4_UDP,
1248*410cf087SAmaranath Somalapuram 		RTE_PTYPE_UNKNOWN
1249*410cf087SAmaranath Somalapuram 	};
1250*410cf087SAmaranath Somalapuram 
1251*410cf087SAmaranath Somalapuram 	if (dev->rx_pkt_burst == axgbe_recv_pkts)
1252*410cf087SAmaranath Somalapuram 		return ptypes;
1253*410cf087SAmaranath Somalapuram 	return NULL;
1254*410cf087SAmaranath Somalapuram }
12557aed95c9SAmaranath Somalapuram 
1256572890efSRavi Kumar static void axgbe_get_all_hw_features(struct axgbe_port *pdata)
1257572890efSRavi Kumar {
1258572890efSRavi Kumar 	unsigned int mac_hfr0, mac_hfr1, mac_hfr2;
1259572890efSRavi Kumar 	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
1260572890efSRavi Kumar 
1261572890efSRavi Kumar 	mac_hfr0 = AXGMAC_IOREAD(pdata, MAC_HWF0R);
1262572890efSRavi Kumar 	mac_hfr1 = AXGMAC_IOREAD(pdata, MAC_HWF1R);
1263572890efSRavi Kumar 	mac_hfr2 = AXGMAC_IOREAD(pdata, MAC_HWF2R);
1264572890efSRavi Kumar 
1265572890efSRavi Kumar 	memset(hw_feat, 0, sizeof(*hw_feat));
1266572890efSRavi Kumar 
1267572890efSRavi Kumar 	hw_feat->version = AXGMAC_IOREAD(pdata, MAC_VR);
1268572890efSRavi Kumar 
1269572890efSRavi Kumar 	/* Hardware feature register 0 */
1270572890efSRavi Kumar 	hw_feat->gmii        = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, GMIISEL);
1271572890efSRavi Kumar 	hw_feat->vlhash      = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, VLHASH);
1272572890efSRavi Kumar 	hw_feat->sma         = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, SMASEL);
1273572890efSRavi Kumar 	hw_feat->rwk         = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, RWKSEL);
1274572890efSRavi Kumar 	hw_feat->mgk         = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, MGKSEL);
1275572890efSRavi Kumar 	hw_feat->mmc         = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, MMCSEL);
1276572890efSRavi Kumar 	hw_feat->aoe         = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, ARPOFFSEL);
1277572890efSRavi Kumar 	hw_feat->ts          = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TSSEL);
1278572890efSRavi Kumar 	hw_feat->eee         = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, EEESEL);
1279572890efSRavi Kumar 	hw_feat->tx_coe      = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TXCOESEL);
1280572890efSRavi Kumar 	hw_feat->rx_coe      = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, RXCOESEL);
1281572890efSRavi Kumar 	hw_feat->addn_mac    = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R,
1282572890efSRavi Kumar 					      ADDMACADRSEL);
1283572890efSRavi Kumar 	hw_feat->ts_src      = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TSSTSSEL);
1284572890efSRavi Kumar 	hw_feat->sa_vlan_ins = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, SAVLANINS);
1285572890efSRavi Kumar 
1286572890efSRavi Kumar 	/* Hardware feature register 1 */
1287572890efSRavi Kumar 	hw_feat->rx_fifo_size  = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
1288572890efSRavi Kumar 						RXFIFOSIZE);
1289572890efSRavi Kumar 	hw_feat->tx_fifo_size  = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
1290572890efSRavi Kumar 						TXFIFOSIZE);
1291572890efSRavi Kumar 	hw_feat->adv_ts_hi     = AXGMAC_GET_BITS(mac_hfr1,
1292572890efSRavi Kumar 						 MAC_HWF1R, ADVTHWORD);
1293572890efSRavi Kumar 	hw_feat->dma_width     = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, ADDR64);
1294572890efSRavi Kumar 	hw_feat->dcb           = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DCBEN);
1295572890efSRavi Kumar 	hw_feat->sph           = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, SPHEN);
1296572890efSRavi Kumar 	hw_feat->tso           = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, TSOEN);
1297572890efSRavi Kumar 	hw_feat->dma_debug     = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DBGMEMA);
1298572890efSRavi Kumar 	hw_feat->rss           = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, RSSEN);
1299572890efSRavi Kumar 	hw_feat->tc_cnt	       = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, NUMTC);
1300572890efSRavi Kumar 	hw_feat->hash_table_size = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
1301572890efSRavi Kumar 						  HASHTBLSZ);
1302572890efSRavi Kumar 	hw_feat->l3l4_filter_num = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
1303572890efSRavi Kumar 						  L3L4FNUM);
1304572890efSRavi Kumar 
1305572890efSRavi Kumar 	/* Hardware feature register 2 */
1306572890efSRavi Kumar 	hw_feat->rx_q_cnt     = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, RXQCNT);
1307572890efSRavi Kumar 	hw_feat->tx_q_cnt     = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, TXQCNT);
1308572890efSRavi Kumar 	hw_feat->rx_ch_cnt    = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, RXCHCNT);
1309572890efSRavi Kumar 	hw_feat->tx_ch_cnt    = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, TXCHCNT);
1310572890efSRavi Kumar 	hw_feat->pps_out_num  = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, PPSOUTNUM);
1311572890efSRavi Kumar 	hw_feat->aux_snap_num = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R,
1312572890efSRavi Kumar 						AUXSNAPNUM);
1313572890efSRavi Kumar 
1314572890efSRavi Kumar 	/* Translate the Hash Table size into actual number */
1315572890efSRavi Kumar 	switch (hw_feat->hash_table_size) {
1316572890efSRavi Kumar 	case 0:
1317572890efSRavi Kumar 		break;
1318572890efSRavi Kumar 	case 1:
1319572890efSRavi Kumar 		hw_feat->hash_table_size = 64;
1320572890efSRavi Kumar 		break;
1321572890efSRavi Kumar 	case 2:
1322572890efSRavi Kumar 		hw_feat->hash_table_size = 128;
1323572890efSRavi Kumar 		break;
1324572890efSRavi Kumar 	case 3:
1325572890efSRavi Kumar 		hw_feat->hash_table_size = 256;
1326572890efSRavi Kumar 		break;
1327572890efSRavi Kumar 	}
1328572890efSRavi Kumar 
1329572890efSRavi Kumar 	/* Translate the address width setting into actual number */
1330572890efSRavi Kumar 	switch (hw_feat->dma_width) {
1331572890efSRavi Kumar 	case 0:
1332572890efSRavi Kumar 		hw_feat->dma_width = 32;
1333572890efSRavi Kumar 		break;
1334572890efSRavi Kumar 	case 1:
1335572890efSRavi Kumar 		hw_feat->dma_width = 40;
1336572890efSRavi Kumar 		break;
1337572890efSRavi Kumar 	case 2:
1338572890efSRavi Kumar 		hw_feat->dma_width = 48;
1339572890efSRavi Kumar 		break;
1340572890efSRavi Kumar 	default:
1341572890efSRavi Kumar 		hw_feat->dma_width = 32;
1342572890efSRavi Kumar 	}
1343572890efSRavi Kumar 
1344572890efSRavi Kumar 	/* The Queue, Channel and TC counts are zero based so increment them
1345572890efSRavi Kumar 	 * to get the actual number
1346572890efSRavi Kumar 	 */
1347572890efSRavi Kumar 	hw_feat->rx_q_cnt++;
1348572890efSRavi Kumar 	hw_feat->tx_q_cnt++;
1349572890efSRavi Kumar 	hw_feat->rx_ch_cnt++;
1350572890efSRavi Kumar 	hw_feat->tx_ch_cnt++;
1351572890efSRavi Kumar 	hw_feat->tc_cnt++;
1352572890efSRavi Kumar 
1353572890efSRavi Kumar 	/* Translate the fifo sizes into actual numbers */
1354572890efSRavi Kumar 	hw_feat->rx_fifo_size = 1 << (hw_feat->rx_fifo_size + 7);
1355572890efSRavi Kumar 	hw_feat->tx_fifo_size = 1 << (hw_feat->tx_fifo_size + 7);
1356572890efSRavi Kumar }
1357572890efSRavi Kumar 
1358572890efSRavi Kumar static void axgbe_init_all_fptrs(struct axgbe_port *pdata)
1359572890efSRavi Kumar {
1360572890efSRavi Kumar 	axgbe_init_function_ptrs_dev(&pdata->hw_if);
13614ac7516bSRavi Kumar 	axgbe_init_function_ptrs_phy(&pdata->phy_if);
13624ac7516bSRavi Kumar 	axgbe_init_function_ptrs_i2c(&pdata->i2c_if);
13634ac7516bSRavi Kumar 	pdata->vdata->init_function_ptrs_phy_impl(&pdata->phy_if);
1364572890efSRavi Kumar }
1365572890efSRavi Kumar 
1366572890efSRavi Kumar static void axgbe_set_counts(struct axgbe_port *pdata)
1367572890efSRavi Kumar {
1368572890efSRavi Kumar 	/* Set all the function pointers */
1369572890efSRavi Kumar 	axgbe_init_all_fptrs(pdata);
1370572890efSRavi Kumar 
1371572890efSRavi Kumar 	/* Populate the hardware features */
1372572890efSRavi Kumar 	axgbe_get_all_hw_features(pdata);
1373572890efSRavi Kumar 
1374572890efSRavi Kumar 	/* Set default max values if not provided */
1375572890efSRavi Kumar 	if (!pdata->tx_max_channel_count)
1376572890efSRavi Kumar 		pdata->tx_max_channel_count = pdata->hw_feat.tx_ch_cnt;
1377572890efSRavi Kumar 	if (!pdata->rx_max_channel_count)
1378572890efSRavi Kumar 		pdata->rx_max_channel_count = pdata->hw_feat.rx_ch_cnt;
1379572890efSRavi Kumar 
1380572890efSRavi Kumar 	if (!pdata->tx_max_q_count)
1381572890efSRavi Kumar 		pdata->tx_max_q_count = pdata->hw_feat.tx_q_cnt;
1382572890efSRavi Kumar 	if (!pdata->rx_max_q_count)
1383572890efSRavi Kumar 		pdata->rx_max_q_count = pdata->hw_feat.rx_q_cnt;
1384572890efSRavi Kumar 
1385572890efSRavi Kumar 	/* Calculate the number of Tx and Rx rings to be created
1386572890efSRavi Kumar 	 *  -Tx (DMA) Channels map 1-to-1 to Tx Queues so set
1387572890efSRavi Kumar 	 *   the number of Tx queues to the number of Tx channels
1388572890efSRavi Kumar 	 *   enabled
1389572890efSRavi Kumar 	 *  -Rx (DMA) Channels do not map 1-to-1 so use the actual
1390572890efSRavi Kumar 	 *   number of Rx queues or maximum allowed
1391572890efSRavi Kumar 	 */
1392572890efSRavi Kumar 	pdata->tx_ring_count = RTE_MIN(pdata->hw_feat.tx_ch_cnt,
1393572890efSRavi Kumar 				     pdata->tx_max_channel_count);
1394572890efSRavi Kumar 	pdata->tx_ring_count = RTE_MIN(pdata->tx_ring_count,
1395572890efSRavi Kumar 				     pdata->tx_max_q_count);
1396572890efSRavi Kumar 
1397572890efSRavi Kumar 	pdata->tx_q_count = pdata->tx_ring_count;
1398572890efSRavi Kumar 
1399572890efSRavi Kumar 	pdata->rx_ring_count = RTE_MIN(pdata->hw_feat.rx_ch_cnt,
1400572890efSRavi Kumar 				     pdata->rx_max_channel_count);
1401572890efSRavi Kumar 
1402572890efSRavi Kumar 	pdata->rx_q_count = RTE_MIN(pdata->hw_feat.rx_q_cnt,
1403572890efSRavi Kumar 				  pdata->rx_max_q_count);
1404572890efSRavi Kumar }
1405572890efSRavi Kumar 
1406572890efSRavi Kumar static void axgbe_default_config(struct axgbe_port *pdata)
1407572890efSRavi Kumar {
1408572890efSRavi Kumar 	pdata->pblx8 = DMA_PBL_X8_ENABLE;
1409572890efSRavi Kumar 	pdata->tx_sf_mode = MTL_TSF_ENABLE;
1410572890efSRavi Kumar 	pdata->tx_threshold = MTL_TX_THRESHOLD_64;
1411572890efSRavi Kumar 	pdata->tx_pbl = DMA_PBL_32;
1412572890efSRavi Kumar 	pdata->tx_osp_mode = DMA_OSP_ENABLE;
1413572890efSRavi Kumar 	pdata->rx_sf_mode = MTL_RSF_ENABLE;
1414572890efSRavi Kumar 	pdata->rx_threshold = MTL_RX_THRESHOLD_64;
1415572890efSRavi Kumar 	pdata->rx_pbl = DMA_PBL_32;
1416572890efSRavi Kumar 	pdata->pause_autoneg = 1;
1417572890efSRavi Kumar 	pdata->tx_pause = 0;
1418572890efSRavi Kumar 	pdata->rx_pause = 0;
1419572890efSRavi Kumar 	pdata->phy_speed = SPEED_UNKNOWN;
1420572890efSRavi Kumar 	pdata->power_down = 0;
1421572890efSRavi Kumar }
1422572890efSRavi Kumar 
1423991e0b1dSSelwin Sebastian static int
1424991e0b1dSSelwin Sebastian pci_device_cmp(const struct rte_device *dev, const void *_pci_id)
1425991e0b1dSSelwin Sebastian {
1426991e0b1dSSelwin Sebastian 	const struct rte_pci_device *pdev = RTE_DEV_TO_PCI_CONST(dev);
1427991e0b1dSSelwin Sebastian 	const struct rte_pci_id *pcid = _pci_id;
1428991e0b1dSSelwin Sebastian 
1429991e0b1dSSelwin Sebastian 	if (pdev->id.vendor_id == AMD_PCI_VENDOR_ID &&
1430991e0b1dSSelwin Sebastian 			pdev->id.device_id == pcid->device_id)
1431991e0b1dSSelwin Sebastian 		return 0;
1432991e0b1dSSelwin Sebastian 	return 1;
1433991e0b1dSSelwin Sebastian }
1434991e0b1dSSelwin Sebastian 
1435991e0b1dSSelwin Sebastian static bool
1436991e0b1dSSelwin Sebastian pci_search_device(int device_id)
1437991e0b1dSSelwin Sebastian {
1438991e0b1dSSelwin Sebastian 	struct rte_bus *pci_bus;
1439991e0b1dSSelwin Sebastian 	struct rte_pci_id dev_id;
1440991e0b1dSSelwin Sebastian 
1441991e0b1dSSelwin Sebastian 	dev_id.device_id = device_id;
1442991e0b1dSSelwin Sebastian 	pci_bus = rte_bus_find_by_name("pci");
1443991e0b1dSSelwin Sebastian 	return (pci_bus != NULL) &&
1444991e0b1dSSelwin Sebastian 		(pci_bus->find_device(NULL, pci_device_cmp, &dev_id) != NULL);
1445991e0b1dSSelwin Sebastian }
1446991e0b1dSSelwin Sebastian 
14478691632fSRavi Kumar /*
14488691632fSRavi Kumar  * It returns 0 on success.
14498691632fSRavi Kumar  */
14508691632fSRavi Kumar static int
14518691632fSRavi Kumar eth_axgbe_dev_init(struct rte_eth_dev *eth_dev)
14528691632fSRavi Kumar {
14538691632fSRavi Kumar 	PMD_INIT_FUNC_TRACE();
14548691632fSRavi Kumar 	struct axgbe_port *pdata;
14558691632fSRavi Kumar 	struct rte_pci_device *pci_dev;
1456572890efSRavi Kumar 	uint32_t reg, mac_lo, mac_hi;
145749a5e622SChandu Babu N 	uint32_t len;
1458572890efSRavi Kumar 	int ret;
14598691632fSRavi Kumar 
14609e890103SRavi Kumar 	eth_dev->dev_ops = &axgbe_eth_dev_ops;
14619e890103SRavi Kumar 
14628691632fSRavi Kumar 	/*
14638691632fSRavi Kumar 	 * For secondary processes, we don't initialise any further as primary
14648691632fSRavi Kumar 	 * has already done this work.
14658691632fSRavi Kumar 	 */
14668691632fSRavi Kumar 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
14678691632fSRavi Kumar 		return 0;
14688691632fSRavi Kumar 
14690bc212a8SStephen Hemminger 	pdata = eth_dev->data->dev_private;
1470572890efSRavi Kumar 	/* initial state */
1471572890efSRavi Kumar 	axgbe_set_bit(AXGBE_DOWN, &pdata->dev_state);
1472572890efSRavi Kumar 	axgbe_set_bit(AXGBE_STOPPED, &pdata->dev_state);
14738691632fSRavi Kumar 	pdata->eth_dev = eth_dev;
14748691632fSRavi Kumar 
14758691632fSRavi Kumar 	pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
14768691632fSRavi Kumar 	pdata->pci_dev = pci_dev;
14778691632fSRavi Kumar 
1478991e0b1dSSelwin Sebastian 	/*
1479991e0b1dSSelwin Sebastian 	 * Use root complex device ID to differentiate RV AXGBE vs SNOWY AXGBE
1480991e0b1dSSelwin Sebastian 	 */
1481991e0b1dSSelwin Sebastian 	if (pci_search_device(AMD_PCI_RV_ROOT_COMPLEX_ID)) {
1482991e0b1dSSelwin Sebastian 		pdata->xpcs_window_def_reg = PCS_V2_RV_WINDOW_DEF;
1483991e0b1dSSelwin Sebastian 		pdata->xpcs_window_sel_reg = PCS_V2_RV_WINDOW_SELECT;
1484991e0b1dSSelwin Sebastian 	} else {
1485991e0b1dSSelwin Sebastian 		pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF;
1486991e0b1dSSelwin Sebastian 		pdata->xpcs_window_sel_reg = PCS_V2_WINDOW_SELECT;
1487991e0b1dSSelwin Sebastian 	}
1488991e0b1dSSelwin Sebastian 
1489572890efSRavi Kumar 	pdata->xgmac_regs =
14907784d0d3SRavi Kumar 		(void *)pci_dev->mem_resource[AXGBE_AXGMAC_BAR].addr;
14917784d0d3SRavi Kumar 	pdata->xprop_regs = (void *)((uint8_t *)pdata->xgmac_regs
14927784d0d3SRavi Kumar 				     + AXGBE_MAC_PROP_OFFSET);
14937784d0d3SRavi Kumar 	pdata->xi2c_regs = (void *)((uint8_t *)pdata->xgmac_regs
14947784d0d3SRavi Kumar 				    + AXGBE_I2C_CTRL_OFFSET);
14957784d0d3SRavi Kumar 	pdata->xpcs_regs = (void *)pci_dev->mem_resource[AXGBE_XPCS_BAR].addr;
1496572890efSRavi Kumar 
1497572890efSRavi Kumar 	/* version specific driver data*/
1498572890efSRavi Kumar 	if (pci_dev->id.device_id == AMD_PCI_AXGBE_DEVICE_V2A)
1499572890efSRavi Kumar 		pdata->vdata = &axgbe_v2a;
1500572890efSRavi Kumar 	else
1501572890efSRavi Kumar 		pdata->vdata = &axgbe_v2b;
1502572890efSRavi Kumar 
1503572890efSRavi Kumar 	/* Configure the PCS indirect addressing support */
1504991e0b1dSSelwin Sebastian 	reg = XPCS32_IOREAD(pdata, pdata->xpcs_window_def_reg);
1505572890efSRavi Kumar 	pdata->xpcs_window = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, OFFSET);
1506572890efSRavi Kumar 	pdata->xpcs_window <<= 6;
1507572890efSRavi Kumar 	pdata->xpcs_window_size = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, SIZE);
1508572890efSRavi Kumar 	pdata->xpcs_window_size = 1 << (pdata->xpcs_window_size + 7);
1509572890efSRavi Kumar 	pdata->xpcs_window_mask = pdata->xpcs_window_size - 1;
1510991e0b1dSSelwin Sebastian 
1511572890efSRavi Kumar 	PMD_INIT_LOG(DEBUG,
1512572890efSRavi Kumar 		     "xpcs window :%x, size :%x, mask :%x ", pdata->xpcs_window,
1513572890efSRavi Kumar 		     pdata->xpcs_window_size, pdata->xpcs_window_mask);
1514572890efSRavi Kumar 	XP_IOWRITE(pdata, XP_INT_EN, 0x1fffff);
1515572890efSRavi Kumar 
1516572890efSRavi Kumar 	/* Retrieve the MAC address */
1517572890efSRavi Kumar 	mac_lo = XP_IOREAD(pdata, XP_MAC_ADDR_LO);
1518572890efSRavi Kumar 	mac_hi = XP_IOREAD(pdata, XP_MAC_ADDR_HI);
1519572890efSRavi Kumar 	pdata->mac_addr.addr_bytes[0] = mac_lo & 0xff;
1520572890efSRavi Kumar 	pdata->mac_addr.addr_bytes[1] = (mac_lo >> 8) & 0xff;
1521572890efSRavi Kumar 	pdata->mac_addr.addr_bytes[2] = (mac_lo >> 16) & 0xff;
1522572890efSRavi Kumar 	pdata->mac_addr.addr_bytes[3] = (mac_lo >> 24) & 0xff;
1523572890efSRavi Kumar 	pdata->mac_addr.addr_bytes[4] = mac_hi & 0xff;
1524572890efSRavi Kumar 	pdata->mac_addr.addr_bytes[5] = (mac_hi >> 8)  &  0xff;
1525572890efSRavi Kumar 
152649a5e622SChandu Babu N 	len = RTE_ETHER_ADDR_LEN * AXGBE_MAX_MAC_ADDRS;
152749a5e622SChandu Babu N 	eth_dev->data->mac_addrs = rte_zmalloc("axgbe_mac_addr", len, 0);
152849a5e622SChandu Babu N 
1529572890efSRavi Kumar 	if (!eth_dev->data->mac_addrs) {
1530572890efSRavi Kumar 		PMD_INIT_LOG(ERR,
153149a5e622SChandu Babu N 			     "Failed to alloc %u bytes needed to "
153249a5e622SChandu Babu N 			     "store MAC addresses", len);
1533572890efSRavi Kumar 		return -ENOMEM;
1534572890efSRavi Kumar 	}
1535572890efSRavi Kumar 
1536e01d9b2eSChandu Babu N 	/* Allocate memory for storing hash filter MAC addresses */
1537e01d9b2eSChandu Babu N 	len = RTE_ETHER_ADDR_LEN * AXGBE_MAX_HASH_MAC_ADDRS;
1538e01d9b2eSChandu Babu N 	eth_dev->data->hash_mac_addrs = rte_zmalloc("axgbe_hash_mac_addr",
1539e01d9b2eSChandu Babu N 						    len, 0);
1540e01d9b2eSChandu Babu N 
1541e01d9b2eSChandu Babu N 	if (eth_dev->data->hash_mac_addrs == NULL) {
1542e01d9b2eSChandu Babu N 		PMD_INIT_LOG(ERR,
1543e01d9b2eSChandu Babu N 			     "Failed to allocate %d bytes needed to "
1544e01d9b2eSChandu Babu N 			     "store MAC addresses", len);
1545e01d9b2eSChandu Babu N 		return -ENOMEM;
1546e01d9b2eSChandu Babu N 	}
1547e01d9b2eSChandu Babu N 
1548538da7a1SOlivier Matz 	if (!rte_is_valid_assigned_ether_addr(&pdata->mac_addr))
1549538da7a1SOlivier Matz 		rte_eth_random_addr(pdata->mac_addr.addr_bytes);
1550572890efSRavi Kumar 
1551572890efSRavi Kumar 	/* Copy the permanent MAC address */
1552538da7a1SOlivier Matz 	rte_ether_addr_copy(&pdata->mac_addr, &eth_dev->data->mac_addrs[0]);
1553572890efSRavi Kumar 
1554572890efSRavi Kumar 	/* Clock settings */
1555572890efSRavi Kumar 	pdata->sysclk_rate = AXGBE_V2_DMA_CLOCK_FREQ;
1556572890efSRavi Kumar 	pdata->ptpclk_rate = AXGBE_V2_PTP_CLOCK_FREQ;
1557572890efSRavi Kumar 
1558572890efSRavi Kumar 	/* Set the DMA coherency values */
1559572890efSRavi Kumar 	pdata->coherent = 1;
1560572890efSRavi Kumar 	pdata->axdomain = AXGBE_DMA_OS_AXDOMAIN;
1561572890efSRavi Kumar 	pdata->arcache = AXGBE_DMA_OS_ARCACHE;
1562572890efSRavi Kumar 	pdata->awcache = AXGBE_DMA_OS_AWCACHE;
1563572890efSRavi Kumar 
1564572890efSRavi Kumar 	/* Set the maximum channels and queues */
1565572890efSRavi Kumar 	reg = XP_IOREAD(pdata, XP_PROP_1);
1566572890efSRavi Kumar 	pdata->tx_max_channel_count = XP_GET_BITS(reg, XP_PROP_1, MAX_TX_DMA);
1567572890efSRavi Kumar 	pdata->rx_max_channel_count = XP_GET_BITS(reg, XP_PROP_1, MAX_RX_DMA);
1568572890efSRavi Kumar 	pdata->tx_max_q_count = XP_GET_BITS(reg, XP_PROP_1, MAX_TX_QUEUES);
1569572890efSRavi Kumar 	pdata->rx_max_q_count = XP_GET_BITS(reg, XP_PROP_1, MAX_RX_QUEUES);
1570572890efSRavi Kumar 
1571572890efSRavi Kumar 	/* Set the hardware channel and queue counts */
1572572890efSRavi Kumar 	axgbe_set_counts(pdata);
1573572890efSRavi Kumar 
1574572890efSRavi Kumar 	/* Set the maximum fifo amounts */
1575572890efSRavi Kumar 	reg = XP_IOREAD(pdata, XP_PROP_2);
1576572890efSRavi Kumar 	pdata->tx_max_fifo_size = XP_GET_BITS(reg, XP_PROP_2, TX_FIFO_SIZE);
1577572890efSRavi Kumar 	pdata->tx_max_fifo_size *= 16384;
1578572890efSRavi Kumar 	pdata->tx_max_fifo_size = RTE_MIN(pdata->tx_max_fifo_size,
1579572890efSRavi Kumar 					  pdata->vdata->tx_max_fifo_size);
1580572890efSRavi Kumar 	pdata->rx_max_fifo_size = XP_GET_BITS(reg, XP_PROP_2, RX_FIFO_SIZE);
1581572890efSRavi Kumar 	pdata->rx_max_fifo_size *= 16384;
1582572890efSRavi Kumar 	pdata->rx_max_fifo_size = RTE_MIN(pdata->rx_max_fifo_size,
1583572890efSRavi Kumar 					  pdata->vdata->rx_max_fifo_size);
1584572890efSRavi Kumar 	/* Issue software reset to DMA */
1585572890efSRavi Kumar 	ret = pdata->hw_if.exit(pdata);
1586572890efSRavi Kumar 	if (ret)
1587572890efSRavi Kumar 		PMD_DRV_LOG(ERR, "hw_if->exit EBUSY error\n");
1588572890efSRavi Kumar 
1589572890efSRavi Kumar 	/* Set default configuration data */
1590572890efSRavi Kumar 	axgbe_default_config(pdata);
1591572890efSRavi Kumar 
1592572890efSRavi Kumar 	/* Set default max values if not provided */
1593572890efSRavi Kumar 	if (!pdata->tx_max_fifo_size)
1594572890efSRavi Kumar 		pdata->tx_max_fifo_size = pdata->hw_feat.tx_fifo_size;
1595572890efSRavi Kumar 	if (!pdata->rx_max_fifo_size)
1596572890efSRavi Kumar 		pdata->rx_max_fifo_size = pdata->hw_feat.rx_fifo_size;
1597572890efSRavi Kumar 
15989e890103SRavi Kumar 	pdata->tx_desc_count = AXGBE_MAX_RING_DESC;
15999e890103SRavi Kumar 	pdata->rx_desc_count = AXGBE_MAX_RING_DESC;
1600572890efSRavi Kumar 	pthread_mutex_init(&pdata->xpcs_mutex, NULL);
1601572890efSRavi Kumar 	pthread_mutex_init(&pdata->i2c_mutex, NULL);
1602572890efSRavi Kumar 	pthread_mutex_init(&pdata->an_mutex, NULL);
1603572890efSRavi Kumar 	pthread_mutex_init(&pdata->phy_mutex, NULL);
1604572890efSRavi Kumar 
16054ac7516bSRavi Kumar 	ret = pdata->phy_if.phy_init(pdata);
16064ac7516bSRavi Kumar 	if (ret) {
16074ac7516bSRavi Kumar 		rte_free(eth_dev->data->mac_addrs);
1608e7f2fa88SDavid Marchand 		eth_dev->data->mac_addrs = NULL;
16094ac7516bSRavi Kumar 		return ret;
16104ac7516bSRavi Kumar 	}
16114ac7516bSRavi Kumar 
1612456ff159SRavi Kumar 	rte_intr_callback_register(&pci_dev->intr_handle,
1613456ff159SRavi Kumar 				   axgbe_dev_interrupt_handler,
1614456ff159SRavi Kumar 				   (void *)eth_dev);
16158691632fSRavi Kumar 	PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x",
16168691632fSRavi Kumar 		     eth_dev->data->port_id, pci_dev->id.vendor_id,
16178691632fSRavi Kumar 		     pci_dev->id.device_id);
16188691632fSRavi Kumar 
16198691632fSRavi Kumar 	return 0;
16208691632fSRavi Kumar }
16218691632fSRavi Kumar 
16228691632fSRavi Kumar static int
1623572890efSRavi Kumar eth_axgbe_dev_uninit(struct rte_eth_dev *eth_dev)
16248691632fSRavi Kumar {
1625456ff159SRavi Kumar 	struct rte_pci_device *pci_dev;
1626456ff159SRavi Kumar 
16278691632fSRavi Kumar 	PMD_INIT_FUNC_TRACE();
16288691632fSRavi Kumar 
1629572890efSRavi Kumar 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1630572890efSRavi Kumar 		return 0;
1631572890efSRavi Kumar 
1632456ff159SRavi Kumar 	pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
16339e890103SRavi Kumar 	eth_dev->dev_ops = NULL;
16348590b93dSRavi Kumar 	eth_dev->rx_pkt_burst = NULL;
16358590b93dSRavi Kumar 	eth_dev->tx_pkt_burst = NULL;
16369e890103SRavi Kumar 	axgbe_dev_clear_queues(eth_dev);
1637572890efSRavi Kumar 
1638456ff159SRavi Kumar 	/* disable uio intr before callback unregister */
1639456ff159SRavi Kumar 	rte_intr_disable(&pci_dev->intr_handle);
1640456ff159SRavi Kumar 	rte_intr_callback_unregister(&pci_dev->intr_handle,
1641456ff159SRavi Kumar 				     axgbe_dev_interrupt_handler,
1642456ff159SRavi Kumar 				     (void *)eth_dev);
1643456ff159SRavi Kumar 
16448691632fSRavi Kumar 	return 0;
16458691632fSRavi Kumar }
16468691632fSRavi Kumar 
16478691632fSRavi Kumar static int eth_axgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
16488691632fSRavi Kumar 	struct rte_pci_device *pci_dev)
16498691632fSRavi Kumar {
16508691632fSRavi Kumar 	return rte_eth_dev_pci_generic_probe(pci_dev,
16518691632fSRavi Kumar 		sizeof(struct axgbe_port), eth_axgbe_dev_init);
16528691632fSRavi Kumar }
16538691632fSRavi Kumar 
16548691632fSRavi Kumar static int eth_axgbe_pci_remove(struct rte_pci_device *pci_dev)
16558691632fSRavi Kumar {
16568691632fSRavi Kumar 	return rte_eth_dev_pci_generic_remove(pci_dev, eth_axgbe_dev_uninit);
16578691632fSRavi Kumar }
16588691632fSRavi Kumar 
16598691632fSRavi Kumar static struct rte_pci_driver rte_axgbe_pmd = {
16608691632fSRavi Kumar 	.id_table = pci_id_axgbe_map,
16618691632fSRavi Kumar 	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
16628691632fSRavi Kumar 	.probe = eth_axgbe_pci_probe,
16638691632fSRavi Kumar 	.remove = eth_axgbe_pci_remove,
16648691632fSRavi Kumar };
16658691632fSRavi Kumar 
16668691632fSRavi Kumar RTE_PMD_REGISTER_PCI(net_axgbe, rte_axgbe_pmd);
16678691632fSRavi Kumar RTE_PMD_REGISTER_PCI_TABLE(net_axgbe, pci_id_axgbe_map);
16688691632fSRavi Kumar RTE_PMD_REGISTER_KMOD_DEP(net_axgbe, "* igb_uio | uio_pci_generic | vfio-pci");
16698691632fSRavi Kumar 
1670f8e99896SThomas Monjalon RTE_INIT(axgbe_init_log)
16718691632fSRavi Kumar {
16728691632fSRavi Kumar 	axgbe_logtype_init = rte_log_register("pmd.net.axgbe.init");
16738691632fSRavi Kumar 	if (axgbe_logtype_init >= 0)
16748691632fSRavi Kumar 		rte_log_set_level(axgbe_logtype_init, RTE_LOG_NOTICE);
16758691632fSRavi Kumar 	axgbe_logtype_driver = rte_log_register("pmd.net.axgbe.driver");
16768691632fSRavi Kumar 	if (axgbe_logtype_driver >= 0)
16778691632fSRavi Kumar 		rte_log_set_level(axgbe_logtype_driver, RTE_LOG_NOTICE);
16788691632fSRavi Kumar }
1679