xref: /dpdk/drivers/net/axgbe/axgbe_ethdev.c (revision 7aed95c93d88ebbd43e309bfbb4cffc23efb26a8)
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);
71*7aed95c9SAmaranath Somalapuram static void axgbe_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
72*7aed95c9SAmaranath Somalapuram 	struct rte_eth_rxq_info *qinfo);
73*7aed95c9SAmaranath Somalapuram static void axgbe_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
74*7aed95c9SAmaranath Somalapuram 	struct rte_eth_txq_info *qinfo);
758691632fSRavi Kumar 
769d1ef6b2SChandu Babu N struct axgbe_xstats {
779d1ef6b2SChandu Babu N 	char name[RTE_ETH_XSTATS_NAME_SIZE];
789d1ef6b2SChandu Babu N 	int offset;
799d1ef6b2SChandu Babu N };
809d1ef6b2SChandu Babu N 
819d1ef6b2SChandu Babu N #define AXGMAC_MMC_STAT(_string, _var)                           \
829d1ef6b2SChandu Babu N 	{ _string,                                              \
839d1ef6b2SChandu Babu N 	  offsetof(struct axgbe_mmc_stats, _var),       \
849d1ef6b2SChandu Babu N 	}
859d1ef6b2SChandu Babu N 
869d1ef6b2SChandu Babu N static const struct axgbe_xstats axgbe_xstats_strings[] = {
879d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_bytes", txoctetcount_gb),
889d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_packets", txframecount_gb),
899d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_unicast_packets", txunicastframes_gb),
909d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_broadcast_packets", txbroadcastframes_gb),
919d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_multicast_packets", txmulticastframes_gb),
929d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_vlan_packets", txvlanframes_g),
939d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_64_byte_packets", tx64octets_gb),
949d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_65_to_127_byte_packets", tx65to127octets_gb),
959d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_128_to_255_byte_packets", tx128to255octets_gb),
969d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_256_to_511_byte_packets", tx256to511octets_gb),
979d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_512_to_1023_byte_packets", tx512to1023octets_gb),
989d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_1024_to_max_byte_packets", tx1024tomaxoctets_gb),
999d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_underflow_errors", txunderflowerror),
1009d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("tx_pause_frames", txpauseframes),
1019d1ef6b2SChandu Babu N 
1029d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_bytes", rxoctetcount_gb),
1039d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_packets", rxframecount_gb),
1049d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_unicast_packets", rxunicastframes_g),
1059d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_broadcast_packets", rxbroadcastframes_g),
1069d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_multicast_packets", rxmulticastframes_g),
1079d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_vlan_packets", rxvlanframes_gb),
1089d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_64_byte_packets", rx64octets_gb),
1099d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_65_to_127_byte_packets", rx65to127octets_gb),
1109d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_128_to_255_byte_packets", rx128to255octets_gb),
1119d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_256_to_511_byte_packets", rx256to511octets_gb),
1129d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_512_to_1023_byte_packets", rx512to1023octets_gb),
1139d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_1024_to_max_byte_packets", rx1024tomaxoctets_gb),
1149d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_undersize_packets", rxundersize_g),
1159d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_oversize_packets", rxoversize_g),
1169d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_crc_errors", rxcrcerror),
1179d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_crc_errors_small_packets", rxrunterror),
1189d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_crc_errors_giant_packets", rxjabbererror),
1199d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_length_errors", rxlengtherror),
1209d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_out_of_range_errors", rxoutofrangetype),
1219d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_fifo_overflow_errors", rxfifooverflow),
1229d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_watchdog_errors", rxwatchdogerror),
1239d1ef6b2SChandu Babu N 	AXGMAC_MMC_STAT("rx_pause_frames", rxpauseframes),
1249d1ef6b2SChandu Babu N };
1259d1ef6b2SChandu Babu N 
1269d1ef6b2SChandu Babu N #define AXGBE_XSTATS_COUNT        ARRAY_SIZE(axgbe_xstats_strings)
1279d1ef6b2SChandu Babu N 
1288691632fSRavi Kumar /* The set of PCI devices this driver supports */
1298691632fSRavi Kumar #define AMD_PCI_VENDOR_ID       0x1022
130991e0b1dSSelwin Sebastian #define AMD_PCI_RV_ROOT_COMPLEX_ID	0x15d0
1318691632fSRavi Kumar #define AMD_PCI_AXGBE_DEVICE_V2A 0x1458
1328691632fSRavi Kumar #define AMD_PCI_AXGBE_DEVICE_V2B 0x1459
1338691632fSRavi Kumar 
1348691632fSRavi Kumar int axgbe_logtype_init;
1358691632fSRavi Kumar int axgbe_logtype_driver;
1368691632fSRavi Kumar 
1378691632fSRavi Kumar static const struct rte_pci_id pci_id_axgbe_map[] = {
1388691632fSRavi Kumar 	{RTE_PCI_DEVICE(AMD_PCI_VENDOR_ID, AMD_PCI_AXGBE_DEVICE_V2A)},
1398691632fSRavi Kumar 	{RTE_PCI_DEVICE(AMD_PCI_VENDOR_ID, AMD_PCI_AXGBE_DEVICE_V2B)},
1408691632fSRavi Kumar 	{ .vendor_id = 0, },
1418691632fSRavi Kumar };
1428691632fSRavi Kumar 
143572890efSRavi Kumar static struct axgbe_version_data axgbe_v2a = {
1444ac7516bSRavi Kumar 	.init_function_ptrs_phy_impl    = axgbe_init_function_ptrs_phy_v2,
145572890efSRavi Kumar 	.xpcs_access			= AXGBE_XPCS_ACCESS_V2,
146572890efSRavi Kumar 	.mmc_64bit			= 1,
147572890efSRavi Kumar 	.tx_max_fifo_size		= 229376,
148572890efSRavi Kumar 	.rx_max_fifo_size		= 229376,
149572890efSRavi Kumar 	.tx_tstamp_workaround		= 1,
150572890efSRavi Kumar 	.ecc_support			= 1,
151572890efSRavi Kumar 	.i2c_support			= 1,
15200072056SRavi Kumar 	.an_cdr_workaround		= 1,
153572890efSRavi Kumar };
154572890efSRavi Kumar 
155572890efSRavi Kumar static struct axgbe_version_data axgbe_v2b = {
1564ac7516bSRavi Kumar 	.init_function_ptrs_phy_impl    = axgbe_init_function_ptrs_phy_v2,
157572890efSRavi Kumar 	.xpcs_access			= AXGBE_XPCS_ACCESS_V2,
158572890efSRavi Kumar 	.mmc_64bit			= 1,
159572890efSRavi Kumar 	.tx_max_fifo_size		= 65536,
160572890efSRavi Kumar 	.rx_max_fifo_size		= 65536,
161572890efSRavi Kumar 	.tx_tstamp_workaround		= 1,
162572890efSRavi Kumar 	.ecc_support			= 1,
163572890efSRavi Kumar 	.i2c_support			= 1,
16400072056SRavi Kumar 	.an_cdr_workaround		= 1,
165572890efSRavi Kumar };
166572890efSRavi Kumar 
1679e890103SRavi Kumar static const struct rte_eth_desc_lim rx_desc_lim = {
1689e890103SRavi Kumar 	.nb_max = AXGBE_MAX_RING_DESC,
1699e890103SRavi Kumar 	.nb_min = AXGBE_MIN_RING_DESC,
1709e890103SRavi Kumar 	.nb_align = 8,
1719e890103SRavi Kumar };
1729e890103SRavi Kumar 
1739e890103SRavi Kumar static const struct rte_eth_desc_lim tx_desc_lim = {
1749e890103SRavi Kumar 	.nb_max = AXGBE_MAX_RING_DESC,
1759e890103SRavi Kumar 	.nb_min = AXGBE_MIN_RING_DESC,
1769e890103SRavi Kumar 	.nb_align = 8,
1779e890103SRavi Kumar };
1789e890103SRavi Kumar 
1799e890103SRavi Kumar static const struct eth_dev_ops axgbe_eth_dev_ops = {
1807c4158a5SRavi Kumar 	.dev_configure        = axgbe_dev_configure,
1817c4158a5SRavi Kumar 	.dev_start            = axgbe_dev_start,
1827c4158a5SRavi Kumar 	.dev_stop             = axgbe_dev_stop,
1839e890103SRavi Kumar 	.dev_close            = axgbe_dev_close,
184fa3e0440SRavi Kumar 	.promiscuous_enable   = axgbe_dev_promiscuous_enable,
185fa3e0440SRavi Kumar 	.promiscuous_disable  = axgbe_dev_promiscuous_disable,
186fa3e0440SRavi Kumar 	.allmulticast_enable  = axgbe_dev_allmulticast_enable,
187fa3e0440SRavi Kumar 	.allmulticast_disable = axgbe_dev_allmulticast_disable,
18849a5e622SChandu Babu N 	.mac_addr_set         = axgbe_dev_mac_addr_set,
18949a5e622SChandu Babu N 	.mac_addr_add         = axgbe_dev_mac_addr_add,
19049a5e622SChandu Babu N 	.mac_addr_remove      = axgbe_dev_mac_addr_remove,
19149a5e622SChandu Babu N 	.set_mc_addr_list     = axgbe_dev_set_mc_addr_list,
192e01d9b2eSChandu Babu N 	.uc_hash_table_set    = axgbe_dev_uc_hash_table_set,
193e01d9b2eSChandu Babu N 	.uc_all_hash_table_set = axgbe_dev_uc_all_hash_table_set,
19444d45ffeSRavi Kumar 	.link_update          = axgbe_dev_link_update,
195df4867cdSChandu Babu N 	.get_reg	      = axgbe_dev_get_regs,
1963e730511SRavi Kumar 	.stats_get            = axgbe_dev_stats_get,
1973e730511SRavi Kumar 	.stats_reset          = axgbe_dev_stats_reset,
1989d1ef6b2SChandu Babu N 	.xstats_get	      = axgbe_dev_xstats_get,
1999d1ef6b2SChandu Babu N 	.xstats_reset	      = axgbe_dev_xstats_reset,
2009d1ef6b2SChandu Babu N 	.xstats_get_names     = axgbe_dev_xstats_get_names,
2019d1ef6b2SChandu Babu N 	.xstats_get_names_by_id = axgbe_dev_xstats_get_names_by_id,
2029d1ef6b2SChandu Babu N 	.xstats_get_by_id     = axgbe_dev_xstats_get_by_id,
2039e890103SRavi Kumar 	.dev_infos_get        = axgbe_dev_info_get,
2049e890103SRavi Kumar 	.rx_queue_setup       = axgbe_dev_rx_queue_setup,
2059e890103SRavi Kumar 	.rx_queue_release     = axgbe_dev_rx_queue_release,
2069e890103SRavi Kumar 	.tx_queue_setup       = axgbe_dev_tx_queue_setup,
2079e890103SRavi Kumar 	.tx_queue_release     = axgbe_dev_tx_queue_release,
208cf97f33eSAmaranath Somalapuram 	.flow_ctrl_get        = axgbe_flow_ctrl_get,
209cf97f33eSAmaranath Somalapuram 	.flow_ctrl_set        = axgbe_flow_ctrl_set,
210e0543d4eSAmaranath Somalapuram 	.priority_flow_ctrl_set = axgbe_priority_flow_ctrl_set,
211*7aed95c9SAmaranath Somalapuram 	.rxq_info_get                 = axgbe_rxq_info_get,
212*7aed95c9SAmaranath Somalapuram 	.txq_info_get                 = axgbe_txq_info_get,
2139e890103SRavi Kumar };
2149e890103SRavi Kumar 
2157c4158a5SRavi Kumar static int axgbe_phy_reset(struct axgbe_port *pdata)
2167c4158a5SRavi Kumar {
2177c4158a5SRavi Kumar 	pdata->phy_link = -1;
2187c4158a5SRavi Kumar 	pdata->phy_speed = SPEED_UNKNOWN;
2197c4158a5SRavi Kumar 	return pdata->phy_if.phy_reset(pdata);
2207c4158a5SRavi Kumar }
2217c4158a5SRavi Kumar 
222456ff159SRavi Kumar /*
223456ff159SRavi Kumar  * Interrupt handler triggered by NIC  for handling
224456ff159SRavi Kumar  * specific interrupt.
225456ff159SRavi Kumar  *
226456ff159SRavi Kumar  * @param handle
227456ff159SRavi Kumar  *  Pointer to interrupt handle.
228456ff159SRavi Kumar  * @param param
229456ff159SRavi Kumar  *  The address of parameter (struct rte_eth_dev *) regsitered before.
230456ff159SRavi Kumar  *
231456ff159SRavi Kumar  * @return
232456ff159SRavi Kumar  *  void
233456ff159SRavi Kumar  */
234456ff159SRavi Kumar static void
235456ff159SRavi Kumar axgbe_dev_interrupt_handler(void *param)
236456ff159SRavi Kumar {
237456ff159SRavi Kumar 	struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
238456ff159SRavi Kumar 	struct axgbe_port *pdata = dev->data->dev_private;
2398590b93dSRavi Kumar 	unsigned int dma_isr, dma_ch_isr;
240456ff159SRavi Kumar 
241456ff159SRavi Kumar 	pdata->phy_if.an_isr(pdata);
2428590b93dSRavi Kumar 	/*DMA related interrupts*/
2438590b93dSRavi Kumar 	dma_isr = AXGMAC_IOREAD(pdata, DMA_ISR);
2444216cdc0SChandu Babu N 	PMD_DRV_LOG(DEBUG, "DMA_ISR=%#010x\n", dma_isr);
2458590b93dSRavi Kumar 	if (dma_isr) {
2468590b93dSRavi Kumar 		if (dma_isr & 1) {
2478590b93dSRavi Kumar 			dma_ch_isr =
2488590b93dSRavi Kumar 				AXGMAC_DMA_IOREAD((struct axgbe_rx_queue *)
2498590b93dSRavi Kumar 						  pdata->rx_queues[0],
2508590b93dSRavi Kumar 						  DMA_CH_SR);
2514216cdc0SChandu Babu N 			PMD_DRV_LOG(DEBUG, "DMA_CH0_ISR=%#010x\n", dma_ch_isr);
2528590b93dSRavi Kumar 			AXGMAC_DMA_IOWRITE((struct axgbe_rx_queue *)
2538590b93dSRavi Kumar 					   pdata->rx_queues[0],
2548590b93dSRavi Kumar 					   DMA_CH_SR, dma_ch_isr);
2558590b93dSRavi Kumar 		}
2568590b93dSRavi Kumar 	}
2576bee9d5fSNithin Dabilpuram 	/* Unmask interrupts since disabled after generation */
2586bee9d5fSNithin Dabilpuram 	rte_intr_ack(&pdata->pci_dev->intr_handle);
259456ff159SRavi Kumar }
260456ff159SRavi Kumar 
2617c4158a5SRavi Kumar /*
2627c4158a5SRavi Kumar  * Configure device link speed and setup link.
2637c4158a5SRavi Kumar  * It returns 0 on success.
2647c4158a5SRavi Kumar  */
2657c4158a5SRavi Kumar static int
2667c4158a5SRavi Kumar axgbe_dev_configure(struct rte_eth_dev *dev)
2677c4158a5SRavi Kumar {
2687c4158a5SRavi Kumar 	struct axgbe_port *pdata =  dev->data->dev_private;
2697c4158a5SRavi Kumar 	/* Checksum offload to hardware */
2707c4158a5SRavi Kumar 	pdata->rx_csum_enable = dev->data->dev_conf.rxmode.offloads &
2717c4158a5SRavi Kumar 				DEV_RX_OFFLOAD_CHECKSUM;
2727c4158a5SRavi Kumar 	return 0;
2737c4158a5SRavi Kumar }
2747c4158a5SRavi Kumar 
2757c4158a5SRavi Kumar static int
2767c4158a5SRavi Kumar axgbe_dev_rx_mq_config(struct rte_eth_dev *dev)
2777c4158a5SRavi Kumar {
2780bc212a8SStephen Hemminger 	struct axgbe_port *pdata = dev->data->dev_private;
2797c4158a5SRavi Kumar 
2807c4158a5SRavi Kumar 	if (dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_RSS)
2817c4158a5SRavi Kumar 		pdata->rss_enable = 1;
2827c4158a5SRavi Kumar 	else if (dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_NONE)
2837c4158a5SRavi Kumar 		pdata->rss_enable = 0;
2847c4158a5SRavi Kumar 	else
2857c4158a5SRavi Kumar 		return  -1;
2867c4158a5SRavi Kumar 	return 0;
2877c4158a5SRavi Kumar }
2887c4158a5SRavi Kumar 
2897c4158a5SRavi Kumar static int
2907c4158a5SRavi Kumar axgbe_dev_start(struct rte_eth_dev *dev)
2917c4158a5SRavi Kumar {
2920bc212a8SStephen Hemminger 	struct axgbe_port *pdata = dev->data->dev_private;
2937c4158a5SRavi Kumar 	int ret;
294965b3127SSelwin Sebastian 	struct rte_eth_dev_data *dev_data = dev->data;
295965b3127SSelwin Sebastian 	uint16_t max_pkt_len = dev_data->dev_conf.rxmode.max_rx_pkt_len;
296965b3127SSelwin Sebastian 
297965b3127SSelwin Sebastian 	dev->dev_ops = &axgbe_eth_dev_ops;
2987c4158a5SRavi Kumar 
2990bc212a8SStephen Hemminger 	PMD_INIT_FUNC_TRACE();
3000bc212a8SStephen Hemminger 
3017c4158a5SRavi Kumar 	/* Multiqueue RSS */
3027c4158a5SRavi Kumar 	ret = axgbe_dev_rx_mq_config(dev);
3037c4158a5SRavi Kumar 	if (ret) {
3047c4158a5SRavi Kumar 		PMD_DRV_LOG(ERR, "Unable to config RX MQ\n");
3057c4158a5SRavi Kumar 		return ret;
3067c4158a5SRavi Kumar 	}
3077c4158a5SRavi Kumar 	ret = axgbe_phy_reset(pdata);
3087c4158a5SRavi Kumar 	if (ret) {
3097c4158a5SRavi Kumar 		PMD_DRV_LOG(ERR, "phy reset failed\n");
3107c4158a5SRavi Kumar 		return ret;
3117c4158a5SRavi Kumar 	}
3127c4158a5SRavi Kumar 	ret = pdata->hw_if.init(pdata);
3137c4158a5SRavi Kumar 	if (ret) {
3147c4158a5SRavi Kumar 		PMD_DRV_LOG(ERR, "dev_init failed\n");
3157c4158a5SRavi Kumar 		return ret;
3167c4158a5SRavi Kumar 	}
3177c4158a5SRavi Kumar 
3187c4158a5SRavi Kumar 	/* enable uio/vfio intr/eventfd mapping */
3197c4158a5SRavi Kumar 	rte_intr_enable(&pdata->pci_dev->intr_handle);
3207c4158a5SRavi Kumar 
3217c4158a5SRavi Kumar 	/* phy start*/
3227c4158a5SRavi Kumar 	pdata->phy_if.phy_start(pdata);
3238590b93dSRavi Kumar 	axgbe_dev_enable_tx(dev);
3248590b93dSRavi Kumar 	axgbe_dev_enable_rx(dev);
3257c4158a5SRavi Kumar 
3267c4158a5SRavi Kumar 	axgbe_clear_bit(AXGBE_STOPPED, &pdata->dev_state);
3277c4158a5SRavi Kumar 	axgbe_clear_bit(AXGBE_DOWN, &pdata->dev_state);
328965b3127SSelwin Sebastian 	if ((dev_data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SCATTER) ||
329965b3127SSelwin Sebastian 				max_pkt_len > pdata->rx_buf_size)
330965b3127SSelwin Sebastian 		dev_data->scattered_rx = 1;
331965b3127SSelwin Sebastian 
332965b3127SSelwin Sebastian 	/*  Scatter Rx handling */
333965b3127SSelwin Sebastian 	if (dev_data->scattered_rx)
334965b3127SSelwin Sebastian 		dev->rx_pkt_burst = &eth_axgbe_recv_scattered_pkts;
335965b3127SSelwin Sebastian 	else
336965b3127SSelwin Sebastian 		dev->rx_pkt_burst = &axgbe_recv_pkts;
337965b3127SSelwin Sebastian 
3387c4158a5SRavi Kumar 	return 0;
3397c4158a5SRavi Kumar }
3407c4158a5SRavi Kumar 
3417c4158a5SRavi Kumar /* Stop device: disable rx and tx functions to allow for reconfiguring. */
3427c4158a5SRavi Kumar static void
3437c4158a5SRavi Kumar axgbe_dev_stop(struct rte_eth_dev *dev)
3447c4158a5SRavi Kumar {
3457c4158a5SRavi Kumar 	struct axgbe_port *pdata = dev->data->dev_private;
3467c4158a5SRavi Kumar 
3470bc212a8SStephen Hemminger 	PMD_INIT_FUNC_TRACE();
3480bc212a8SStephen Hemminger 
3497c4158a5SRavi Kumar 	rte_intr_disable(&pdata->pci_dev->intr_handle);
3507c4158a5SRavi Kumar 
3517c4158a5SRavi Kumar 	if (axgbe_test_bit(AXGBE_STOPPED, &pdata->dev_state))
3527c4158a5SRavi Kumar 		return;
3537c4158a5SRavi Kumar 
3547c4158a5SRavi Kumar 	axgbe_set_bit(AXGBE_STOPPED, &pdata->dev_state);
3558590b93dSRavi Kumar 	axgbe_dev_disable_tx(dev);
3568590b93dSRavi Kumar 	axgbe_dev_disable_rx(dev);
3577c4158a5SRavi Kumar 
3587c4158a5SRavi Kumar 	pdata->phy_if.phy_stop(pdata);
3597c4158a5SRavi Kumar 	pdata->hw_if.exit(pdata);
3607c4158a5SRavi Kumar 	memset(&dev->data->dev_link, 0, sizeof(struct rte_eth_link));
3617c4158a5SRavi Kumar 	axgbe_set_bit(AXGBE_DOWN, &pdata->dev_state);
3627c4158a5SRavi Kumar }
3637c4158a5SRavi Kumar 
3649e890103SRavi Kumar /* Clear all resources like TX/RX queues. */
3659e890103SRavi Kumar static void
3669e890103SRavi Kumar axgbe_dev_close(struct rte_eth_dev *dev)
3679e890103SRavi Kumar {
3689e890103SRavi Kumar 	axgbe_dev_clear_queues(dev);
3699e890103SRavi Kumar }
3709e890103SRavi Kumar 
3719039c812SAndrew Rybchenko static int
372fa3e0440SRavi Kumar axgbe_dev_promiscuous_enable(struct rte_eth_dev *dev)
373fa3e0440SRavi Kumar {
374fa3e0440SRavi Kumar 	struct axgbe_port *pdata = dev->data->dev_private;
375fa3e0440SRavi Kumar 
3760bc212a8SStephen Hemminger 	PMD_INIT_FUNC_TRACE();
3770bc212a8SStephen Hemminger 
378fa3e0440SRavi Kumar 	AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PR, 1);
3799039c812SAndrew Rybchenko 
3809039c812SAndrew Rybchenko 	return 0;
381fa3e0440SRavi Kumar }
382fa3e0440SRavi Kumar 
3839039c812SAndrew Rybchenko static int
384fa3e0440SRavi Kumar axgbe_dev_promiscuous_disable(struct rte_eth_dev *dev)
385fa3e0440SRavi Kumar {
386fa3e0440SRavi Kumar 	struct axgbe_port *pdata = dev->data->dev_private;
387fa3e0440SRavi Kumar 
3880bc212a8SStephen Hemminger 	PMD_INIT_FUNC_TRACE();
3890bc212a8SStephen Hemminger 
390fa3e0440SRavi Kumar 	AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PR, 0);
3919039c812SAndrew Rybchenko 
3929039c812SAndrew Rybchenko 	return 0;
393fa3e0440SRavi Kumar }
394fa3e0440SRavi Kumar 
395ca041cd4SIvan Ilchenko static int
396fa3e0440SRavi Kumar axgbe_dev_allmulticast_enable(struct rte_eth_dev *dev)
397fa3e0440SRavi Kumar {
398fa3e0440SRavi Kumar 	struct axgbe_port *pdata = dev->data->dev_private;
399fa3e0440SRavi Kumar 
4000bc212a8SStephen Hemminger 	PMD_INIT_FUNC_TRACE();
4010bc212a8SStephen Hemminger 
402fa3e0440SRavi Kumar 	if (AXGMAC_IOREAD_BITS(pdata, MAC_PFR, PM))
403ca041cd4SIvan Ilchenko 		return 0;
404fa3e0440SRavi Kumar 	AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PM, 1);
405ca041cd4SIvan Ilchenko 
406ca041cd4SIvan Ilchenko 	return 0;
407fa3e0440SRavi Kumar }
408fa3e0440SRavi Kumar 
409ca041cd4SIvan Ilchenko static int
410fa3e0440SRavi Kumar axgbe_dev_allmulticast_disable(struct rte_eth_dev *dev)
411fa3e0440SRavi Kumar {
412fa3e0440SRavi Kumar 	struct axgbe_port *pdata = dev->data->dev_private;
413fa3e0440SRavi Kumar 
4140bc212a8SStephen Hemminger 	PMD_INIT_FUNC_TRACE();
4150bc212a8SStephen Hemminger 
416fa3e0440SRavi Kumar 	if (!AXGMAC_IOREAD_BITS(pdata, MAC_PFR, PM))
417ca041cd4SIvan Ilchenko 		return 0;
418fa3e0440SRavi Kumar 	AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PM, 0);
419ca041cd4SIvan Ilchenko 
420ca041cd4SIvan Ilchenko 	return 0;
421fa3e0440SRavi Kumar }
422fa3e0440SRavi Kumar 
42349a5e622SChandu Babu N static int
42449a5e622SChandu Babu N axgbe_dev_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr)
42549a5e622SChandu Babu N {
42649a5e622SChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
42749a5e622SChandu Babu N 
42849a5e622SChandu Babu N 	/* Set Default MAC Addr */
42949a5e622SChandu Babu N 	axgbe_set_mac_addn_addr(pdata, (u8 *)mac_addr, 0);
43049a5e622SChandu Babu N 
43149a5e622SChandu Babu N 	return 0;
43249a5e622SChandu Babu N }
43349a5e622SChandu Babu N 
43449a5e622SChandu Babu N static int
43549a5e622SChandu Babu N axgbe_dev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
43649a5e622SChandu Babu N 			      uint32_t index, uint32_t pool __rte_unused)
43749a5e622SChandu Babu N {
43849a5e622SChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
43949a5e622SChandu Babu N 	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
44049a5e622SChandu Babu N 
44149a5e622SChandu Babu N 	if (index > hw_feat->addn_mac) {
44249a5e622SChandu Babu N 		PMD_DRV_LOG(ERR, "Invalid Index %d\n", index);
44349a5e622SChandu Babu N 		return -EINVAL;
44449a5e622SChandu Babu N 	}
44549a5e622SChandu Babu N 	axgbe_set_mac_addn_addr(pdata, (u8 *)mac_addr, index);
44649a5e622SChandu Babu N 	return 0;
44749a5e622SChandu Babu N }
44849a5e622SChandu Babu N 
44949a5e622SChandu Babu N static void
45049a5e622SChandu Babu N axgbe_dev_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
45149a5e622SChandu Babu N {
45249a5e622SChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
45349a5e622SChandu Babu N 	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
45449a5e622SChandu Babu N 
45549a5e622SChandu Babu N 	if (index > hw_feat->addn_mac) {
45649a5e622SChandu Babu N 		PMD_DRV_LOG(ERR, "Invalid Index %d\n", index);
45749a5e622SChandu Babu N 		return;
45849a5e622SChandu Babu N 	}
45949a5e622SChandu Babu N 	axgbe_set_mac_addn_addr(pdata, NULL, index);
46049a5e622SChandu Babu N }
46149a5e622SChandu Babu N 
46249a5e622SChandu Babu N static int
46349a5e622SChandu Babu N axgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
46449a5e622SChandu Babu N 				      struct rte_ether_addr *mc_addr_set,
46549a5e622SChandu Babu N 				      uint32_t nb_mc_addr)
46649a5e622SChandu Babu N {
46749a5e622SChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
46849a5e622SChandu Babu N 	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
46949a5e622SChandu Babu N 	uint32_t index = 1; /* 0 is always default mac */
47049a5e622SChandu Babu N 	uint32_t i;
47149a5e622SChandu Babu N 
47249a5e622SChandu Babu N 	if (nb_mc_addr > hw_feat->addn_mac) {
47349a5e622SChandu Babu N 		PMD_DRV_LOG(ERR, "Invalid Index %d\n", nb_mc_addr);
47449a5e622SChandu Babu N 		return -EINVAL;
47549a5e622SChandu Babu N 	}
47649a5e622SChandu Babu N 
47749a5e622SChandu Babu N 	/* clear unicast addresses */
47849a5e622SChandu Babu N 	for (i = 1; i < hw_feat->addn_mac; i++) {
47949a5e622SChandu Babu N 		if (rte_is_zero_ether_addr(&dev->data->mac_addrs[i]))
48049a5e622SChandu Babu N 			continue;
48149a5e622SChandu Babu N 		memset(&dev->data->mac_addrs[i], 0,
48249a5e622SChandu Babu N 		       sizeof(struct rte_ether_addr));
48349a5e622SChandu Babu N 	}
48449a5e622SChandu Babu N 
48549a5e622SChandu Babu N 	while (nb_mc_addr--)
48649a5e622SChandu Babu N 		axgbe_set_mac_addn_addr(pdata, (u8 *)mc_addr_set++, index++);
48749a5e622SChandu Babu N 
48849a5e622SChandu Babu N 	return 0;
48949a5e622SChandu Babu N }
49049a5e622SChandu Babu N 
491e01d9b2eSChandu Babu N static int
492e01d9b2eSChandu Babu N axgbe_dev_uc_hash_table_set(struct rte_eth_dev *dev,
493e01d9b2eSChandu Babu N 			    struct rte_ether_addr *mac_addr, uint8_t add)
494e01d9b2eSChandu Babu N {
495e01d9b2eSChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
496e01d9b2eSChandu Babu N 	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
497e01d9b2eSChandu Babu N 
498e01d9b2eSChandu Babu N 	if (!hw_feat->hash_table_size) {
499e01d9b2eSChandu Babu N 		PMD_DRV_LOG(ERR, "MAC Hash Table not supported\n");
500e01d9b2eSChandu Babu N 		return -ENOTSUP;
501e01d9b2eSChandu Babu N 	}
502e01d9b2eSChandu Babu N 
503e01d9b2eSChandu Babu N 	axgbe_set_mac_hash_table(pdata, (u8 *)mac_addr, add);
504e01d9b2eSChandu Babu N 
505e01d9b2eSChandu Babu N 	if (pdata->uc_hash_mac_addr > 0) {
506e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1);
507e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1);
508e01d9b2eSChandu Babu N 	} else {
509e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 0);
510e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0);
511e01d9b2eSChandu Babu N 	}
512e01d9b2eSChandu Babu N 	return 0;
513e01d9b2eSChandu Babu N }
514e01d9b2eSChandu Babu N 
515e01d9b2eSChandu Babu N static int
516e01d9b2eSChandu Babu N axgbe_dev_uc_all_hash_table_set(struct rte_eth_dev *dev, uint8_t add)
517e01d9b2eSChandu Babu N {
518e01d9b2eSChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
519e01d9b2eSChandu Babu N 	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
520e01d9b2eSChandu Babu N 	uint32_t index;
521e01d9b2eSChandu Babu N 
522e01d9b2eSChandu Babu N 	if (!hw_feat->hash_table_size) {
523e01d9b2eSChandu Babu N 		PMD_DRV_LOG(ERR, "MAC Hash Table not supported\n");
524e01d9b2eSChandu Babu N 		return -ENOTSUP;
525e01d9b2eSChandu Babu N 	}
526e01d9b2eSChandu Babu N 
527e01d9b2eSChandu Babu N 	for (index = 0; index < pdata->hash_table_count; index++) {
528e01d9b2eSChandu Babu N 		if (add)
529e01d9b2eSChandu Babu N 			pdata->uc_hash_table[index] = ~0;
530e01d9b2eSChandu Babu N 		else
531e01d9b2eSChandu Babu N 			pdata->uc_hash_table[index] = 0;
532e01d9b2eSChandu Babu N 
533e01d9b2eSChandu Babu N 		PMD_DRV_LOG(DEBUG, "%s MAC hash table at Index %#x\n",
534e01d9b2eSChandu Babu N 			    add ? "set" : "clear", index);
535e01d9b2eSChandu Babu N 
536e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE(pdata, MAC_HTR(index),
537e01d9b2eSChandu Babu N 			       pdata->uc_hash_table[index]);
538e01d9b2eSChandu Babu N 	}
539e01d9b2eSChandu Babu N 
540e01d9b2eSChandu Babu N 	if (add) {
541e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1);
542e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1);
543e01d9b2eSChandu Babu N 	} else {
544e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 0);
545e01d9b2eSChandu Babu N 		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0);
546e01d9b2eSChandu Babu N 	}
547e01d9b2eSChandu Babu N 	return 0;
548e01d9b2eSChandu Babu N }
549e01d9b2eSChandu Babu N 
55044d45ffeSRavi Kumar /* return 0 means link status changed, -1 means not changed */
55144d45ffeSRavi Kumar static int
55244d45ffeSRavi Kumar axgbe_dev_link_update(struct rte_eth_dev *dev,
55344d45ffeSRavi Kumar 		      int wait_to_complete __rte_unused)
55444d45ffeSRavi Kumar {
55544d45ffeSRavi Kumar 	struct axgbe_port *pdata = dev->data->dev_private;
55644d45ffeSRavi Kumar 	struct rte_eth_link link;
55744d45ffeSRavi Kumar 	int ret = 0;
55844d45ffeSRavi Kumar 
55944d45ffeSRavi Kumar 	PMD_INIT_FUNC_TRACE();
56044d45ffeSRavi Kumar 	rte_delay_ms(800);
56144d45ffeSRavi Kumar 
56244d45ffeSRavi Kumar 	pdata->phy_if.phy_status(pdata);
56344d45ffeSRavi Kumar 
56444d45ffeSRavi Kumar 	memset(&link, 0, sizeof(struct rte_eth_link));
56544d45ffeSRavi Kumar 	link.link_duplex = pdata->phy.duplex;
56644d45ffeSRavi Kumar 	link.link_status = pdata->phy_link;
56744d45ffeSRavi Kumar 	link.link_speed = pdata->phy_speed;
56844d45ffeSRavi Kumar 	link.link_autoneg = !(dev->data->dev_conf.link_speeds &
56944d45ffeSRavi Kumar 			      ETH_LINK_SPEED_FIXED);
57044d45ffeSRavi Kumar 	ret = rte_eth_linkstatus_set(dev, &link);
57144d45ffeSRavi Kumar 	if (ret == -1)
57244d45ffeSRavi Kumar 		PMD_DRV_LOG(ERR, "No change in link status\n");
57344d45ffeSRavi Kumar 
57444d45ffeSRavi Kumar 	return ret;
57544d45ffeSRavi Kumar }
57644d45ffeSRavi Kumar 
577df4867cdSChandu Babu N static int
578df4867cdSChandu Babu N axgbe_dev_get_regs(struct rte_eth_dev *dev, struct rte_dev_reg_info *regs)
579df4867cdSChandu Babu N {
580df4867cdSChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
581df4867cdSChandu Babu N 
582df4867cdSChandu Babu N 	if (regs->data == NULL) {
583df4867cdSChandu Babu N 		regs->length = axgbe_regs_get_count(pdata);
584df4867cdSChandu Babu N 		regs->width = sizeof(uint32_t);
585df4867cdSChandu Babu N 		return 0;
586df4867cdSChandu Babu N 	}
587df4867cdSChandu Babu N 
588df4867cdSChandu Babu N 	/* Only full register dump is supported */
589df4867cdSChandu Babu N 	if (regs->length &&
590df4867cdSChandu Babu N 	    regs->length != (uint32_t)axgbe_regs_get_count(pdata))
591df4867cdSChandu Babu N 		return -ENOTSUP;
592df4867cdSChandu Babu N 
593df4867cdSChandu Babu N 	regs->version = pdata->pci_dev->id.vendor_id << 16 |
594df4867cdSChandu Babu N 			pdata->pci_dev->id.device_id;
595df4867cdSChandu Babu N 	axgbe_regs_dump(pdata, regs->data);
596df4867cdSChandu Babu N 	return 0;
597df4867cdSChandu Babu N }
5989d1ef6b2SChandu Babu N static void axgbe_read_mmc_stats(struct axgbe_port *pdata)
5999d1ef6b2SChandu Babu N {
6009d1ef6b2SChandu Babu N 	struct axgbe_mmc_stats *stats = &pdata->mmc_stats;
6019d1ef6b2SChandu Babu N 
6029d1ef6b2SChandu Babu N 	/* Freeze counters */
6039d1ef6b2SChandu Babu N 	AXGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 1);
6049d1ef6b2SChandu Babu N 
6059d1ef6b2SChandu Babu N 	/* Tx counters */
6069d1ef6b2SChandu Babu N 	stats->txoctetcount_gb +=
6079d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_GB_LO);
6089d1ef6b2SChandu Babu N 	stats->txoctetcount_gb +=
6099d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_GB_HI) << 32);
6109d1ef6b2SChandu Babu N 
6119d1ef6b2SChandu Babu N 	stats->txframecount_gb +=
6129d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_GB_LO);
6139d1ef6b2SChandu Babu N 	stats->txframecount_gb +=
6149d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_GB_HI) << 32);
6159d1ef6b2SChandu Babu N 
6169d1ef6b2SChandu Babu N 	stats->txbroadcastframes_g +=
6179d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_G_LO);
6189d1ef6b2SChandu Babu N 	stats->txbroadcastframes_g +=
6199d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_G_HI) << 32);
6209d1ef6b2SChandu Babu N 
6219d1ef6b2SChandu Babu N 	stats->txmulticastframes_g +=
6229d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_G_LO);
6239d1ef6b2SChandu Babu N 	stats->txmulticastframes_g +=
6249d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_G_HI) << 32);
6259d1ef6b2SChandu Babu N 
6269d1ef6b2SChandu Babu N 	stats->tx64octets_gb +=
6279d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TX64OCTETS_GB_LO);
6289d1ef6b2SChandu Babu N 	stats->tx64octets_gb +=
6299d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX64OCTETS_GB_HI) << 32);
6309d1ef6b2SChandu Babu N 
6319d1ef6b2SChandu Babu N 	stats->tx65to127octets_gb +=
6329d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TX65TO127OCTETS_GB_LO);
6339d1ef6b2SChandu Babu N 	stats->tx65to127octets_gb +=
6349d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX65TO127OCTETS_GB_HI) << 32);
6359d1ef6b2SChandu Babu N 
6369d1ef6b2SChandu Babu N 	stats->tx128to255octets_gb +=
6379d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TX128TO255OCTETS_GB_LO);
6389d1ef6b2SChandu Babu N 	stats->tx128to255octets_gb +=
6399d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX128TO255OCTETS_GB_HI) << 32);
6409d1ef6b2SChandu Babu N 
6419d1ef6b2SChandu Babu N 	stats->tx256to511octets_gb +=
6429d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TX256TO511OCTETS_GB_LO);
6439d1ef6b2SChandu Babu N 	stats->tx256to511octets_gb +=
6449d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX256TO511OCTETS_GB_HI) << 32);
6459d1ef6b2SChandu Babu N 
6469d1ef6b2SChandu Babu N 	stats->tx512to1023octets_gb +=
6479d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TX512TO1023OCTETS_GB_LO);
6489d1ef6b2SChandu Babu N 	stats->tx512to1023octets_gb +=
6499d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX512TO1023OCTETS_GB_HI) << 32);
6509d1ef6b2SChandu Babu N 
6519d1ef6b2SChandu Babu N 	stats->tx1024tomaxoctets_gb +=
6529d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TX1024TOMAXOCTETS_GB_LO);
6539d1ef6b2SChandu Babu N 	stats->tx1024tomaxoctets_gb +=
6549d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX1024TOMAXOCTETS_GB_HI) << 32);
6559d1ef6b2SChandu Babu N 
6569d1ef6b2SChandu Babu N 	stats->txunicastframes_gb +=
6579d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXUNICASTFRAMES_GB_LO);
6589d1ef6b2SChandu Babu N 	stats->txunicastframes_gb +=
6599d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXUNICASTFRAMES_GB_HI) << 32);
6609d1ef6b2SChandu Babu N 
6619d1ef6b2SChandu Babu N 	stats->txmulticastframes_gb +=
6629d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_GB_LO);
6639d1ef6b2SChandu Babu N 	stats->txmulticastframes_gb +=
6649d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_GB_HI) << 32);
6659d1ef6b2SChandu Babu N 
6669d1ef6b2SChandu Babu N 	stats->txbroadcastframes_g +=
6679d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_GB_LO);
6689d1ef6b2SChandu Babu N 	stats->txbroadcastframes_g +=
6699d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_GB_HI) << 32);
6709d1ef6b2SChandu Babu N 
6719d1ef6b2SChandu Babu N 	stats->txunderflowerror +=
6729d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXUNDERFLOWERROR_LO);
6739d1ef6b2SChandu Babu N 	stats->txunderflowerror +=
6749d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXUNDERFLOWERROR_HI) << 32);
6759d1ef6b2SChandu Babu N 
6769d1ef6b2SChandu Babu N 	stats->txoctetcount_g +=
6779d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_G_LO);
6789d1ef6b2SChandu Babu N 	stats->txoctetcount_g +=
6799d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_G_HI) << 32);
6809d1ef6b2SChandu Babu N 
6819d1ef6b2SChandu Babu N 	stats->txframecount_g +=
6829d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_G_LO);
6839d1ef6b2SChandu Babu N 	stats->txframecount_g +=
6849d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_G_HI) << 32);
6859d1ef6b2SChandu Babu N 
6869d1ef6b2SChandu Babu N 	stats->txpauseframes +=
6879d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXPAUSEFRAMES_LO);
6889d1ef6b2SChandu Babu N 	stats->txpauseframes +=
6899d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXPAUSEFRAMES_HI) << 32);
6909d1ef6b2SChandu Babu N 
6919d1ef6b2SChandu Babu N 	stats->txvlanframes_g +=
6929d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_TXVLANFRAMES_G_LO);
6939d1ef6b2SChandu Babu N 	stats->txvlanframes_g +=
6949d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXVLANFRAMES_G_HI) << 32);
6959d1ef6b2SChandu Babu N 
6969d1ef6b2SChandu Babu N 	/* Rx counters */
6979d1ef6b2SChandu Babu N 	stats->rxframecount_gb +=
6989d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXFRAMECOUNT_GB_LO);
6999d1ef6b2SChandu Babu N 	stats->rxframecount_gb +=
7009d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXFRAMECOUNT_GB_HI) << 32);
7019d1ef6b2SChandu Babu N 
7029d1ef6b2SChandu Babu N 	stats->rxoctetcount_gb +=
7039d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_GB_LO);
7049d1ef6b2SChandu Babu N 	stats->rxoctetcount_gb +=
7059d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_GB_HI) << 32);
7069d1ef6b2SChandu Babu N 
7079d1ef6b2SChandu Babu N 	stats->rxoctetcount_g +=
7089d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_G_LO);
7099d1ef6b2SChandu Babu N 	stats->rxoctetcount_g +=
7109d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_G_HI) << 32);
7119d1ef6b2SChandu Babu N 
7129d1ef6b2SChandu Babu N 	stats->rxbroadcastframes_g +=
7139d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXBROADCASTFRAMES_G_LO);
7149d1ef6b2SChandu Babu N 	stats->rxbroadcastframes_g +=
7159d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXBROADCASTFRAMES_G_HI) << 32);
7169d1ef6b2SChandu Babu N 
7179d1ef6b2SChandu Babu N 	stats->rxmulticastframes_g +=
7189d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXMULTICASTFRAMES_G_LO);
7199d1ef6b2SChandu Babu N 	stats->rxmulticastframes_g +=
7209d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXMULTICASTFRAMES_G_HI) << 32);
7219d1ef6b2SChandu Babu N 
7229d1ef6b2SChandu Babu N 	stats->rxcrcerror +=
7239d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXCRCERROR_LO);
7249d1ef6b2SChandu Babu N 	stats->rxcrcerror +=
7259d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXCRCERROR_HI) << 32);
7269d1ef6b2SChandu Babu N 
7279d1ef6b2SChandu Babu N 	stats->rxrunterror +=
7289d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXRUNTERROR);
7299d1ef6b2SChandu Babu N 
7309d1ef6b2SChandu Babu N 	stats->rxjabbererror +=
7319d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXJABBERERROR);
7329d1ef6b2SChandu Babu N 
7339d1ef6b2SChandu Babu N 	stats->rxundersize_g +=
7349d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXUNDERSIZE_G);
7359d1ef6b2SChandu Babu N 
7369d1ef6b2SChandu Babu N 	stats->rxoversize_g +=
7379d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXOVERSIZE_G);
7389d1ef6b2SChandu Babu N 
7399d1ef6b2SChandu Babu N 	stats->rx64octets_gb +=
7409d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RX64OCTETS_GB_LO);
7419d1ef6b2SChandu Babu N 	stats->rx64octets_gb +=
7429d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX64OCTETS_GB_HI) << 32);
7439d1ef6b2SChandu Babu N 
7449d1ef6b2SChandu Babu N 	stats->rx65to127octets_gb +=
7459d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RX65TO127OCTETS_GB_LO);
7469d1ef6b2SChandu Babu N 	stats->rx65to127octets_gb +=
7479d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX65TO127OCTETS_GB_HI) << 32);
7489d1ef6b2SChandu Babu N 
7499d1ef6b2SChandu Babu N 	stats->rx128to255octets_gb +=
7509d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RX128TO255OCTETS_GB_LO);
7519d1ef6b2SChandu Babu N 	stats->rx128to255octets_gb +=
7529d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX128TO255OCTETS_GB_HI) << 32);
7539d1ef6b2SChandu Babu N 
7549d1ef6b2SChandu Babu N 	stats->rx256to511octets_gb +=
7559d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RX256TO511OCTETS_GB_LO);
7569d1ef6b2SChandu Babu N 	stats->rx256to511octets_gb +=
7579d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX256TO511OCTETS_GB_HI) << 32);
7589d1ef6b2SChandu Babu N 
7599d1ef6b2SChandu Babu N 	stats->rx512to1023octets_gb +=
7609d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RX512TO1023OCTETS_GB_LO);
7619d1ef6b2SChandu Babu N 	stats->rx512to1023octets_gb +=
7629d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX512TO1023OCTETS_GB_HI) << 32);
7639d1ef6b2SChandu Babu N 
7649d1ef6b2SChandu Babu N 	stats->rx1024tomaxoctets_gb +=
7659d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RX1024TOMAXOCTETS_GB_LO);
7669d1ef6b2SChandu Babu N 	stats->rx1024tomaxoctets_gb +=
7679d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX1024TOMAXOCTETS_GB_HI) << 32);
7689d1ef6b2SChandu Babu N 
7699d1ef6b2SChandu Babu N 	stats->rxunicastframes_g +=
7709d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXUNICASTFRAMES_G_LO);
7719d1ef6b2SChandu Babu N 	stats->rxunicastframes_g +=
7729d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXUNICASTFRAMES_G_HI) << 32);
7739d1ef6b2SChandu Babu N 
7749d1ef6b2SChandu Babu N 	stats->rxlengtherror +=
7759d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXLENGTHERROR_LO);
7769d1ef6b2SChandu Babu N 	stats->rxlengtherror +=
7779d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXLENGTHERROR_HI) << 32);
7789d1ef6b2SChandu Babu N 
7799d1ef6b2SChandu Babu N 	stats->rxoutofrangetype +=
7809d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXOUTOFRANGETYPE_LO);
7819d1ef6b2SChandu Babu N 	stats->rxoutofrangetype +=
7829d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXOUTOFRANGETYPE_HI) << 32);
7839d1ef6b2SChandu Babu N 
7849d1ef6b2SChandu Babu N 	stats->rxpauseframes +=
7859d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXPAUSEFRAMES_LO);
7869d1ef6b2SChandu Babu N 	stats->rxpauseframes +=
7879d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXPAUSEFRAMES_HI) << 32);
7889d1ef6b2SChandu Babu N 
7899d1ef6b2SChandu Babu N 	stats->rxfifooverflow +=
7909d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXFIFOOVERFLOW_LO);
7919d1ef6b2SChandu Babu N 	stats->rxfifooverflow +=
7929d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXFIFOOVERFLOW_HI) << 32);
7939d1ef6b2SChandu Babu N 
7949d1ef6b2SChandu Babu N 	stats->rxvlanframes_gb +=
7959d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXVLANFRAMES_GB_LO);
7969d1ef6b2SChandu Babu N 	stats->rxvlanframes_gb +=
7979d1ef6b2SChandu Babu N 	((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXVLANFRAMES_GB_HI) << 32);
7989d1ef6b2SChandu Babu N 
7999d1ef6b2SChandu Babu N 	stats->rxwatchdogerror +=
8009d1ef6b2SChandu Babu N 		AXGMAC_IOREAD(pdata, MMC_RXWATCHDOGERROR);
8019d1ef6b2SChandu Babu N 
8029d1ef6b2SChandu Babu N 	/* Un-freeze counters */
8039d1ef6b2SChandu Babu N 	AXGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 0);
8049d1ef6b2SChandu Babu N }
8059d1ef6b2SChandu Babu N 
8069d1ef6b2SChandu Babu N static int
8079d1ef6b2SChandu Babu N axgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats,
8089d1ef6b2SChandu Babu N 		     unsigned int n)
8099d1ef6b2SChandu Babu N {
8109d1ef6b2SChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
8119d1ef6b2SChandu Babu N 	unsigned int i;
8129d1ef6b2SChandu Babu N 
8139d1ef6b2SChandu Babu N 	if (!stats)
8149d1ef6b2SChandu Babu N 		return 0;
8159d1ef6b2SChandu Babu N 
8169d1ef6b2SChandu Babu N 	axgbe_read_mmc_stats(pdata);
8179d1ef6b2SChandu Babu N 
8189d1ef6b2SChandu Babu N 	for (i = 0; i < n && i < AXGBE_XSTATS_COUNT; i++) {
8199d1ef6b2SChandu Babu N 		stats[i].id = i;
8209d1ef6b2SChandu Babu N 		stats[i].value = *(u64 *)((uint8_t *)&pdata->mmc_stats +
8219d1ef6b2SChandu Babu N 				axgbe_xstats_strings[i].offset);
8229d1ef6b2SChandu Babu N 	}
8239d1ef6b2SChandu Babu N 
8249d1ef6b2SChandu Babu N 	return i;
8259d1ef6b2SChandu Babu N }
8269d1ef6b2SChandu Babu N 
8279d1ef6b2SChandu Babu N static int
8289d1ef6b2SChandu Babu N axgbe_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev,
8299d1ef6b2SChandu Babu N 			   struct rte_eth_xstat_name *xstats_names,
8309d1ef6b2SChandu Babu N 			   unsigned int n)
8319d1ef6b2SChandu Babu N {
8329d1ef6b2SChandu Babu N 	unsigned int i;
8339d1ef6b2SChandu Babu N 
8349d1ef6b2SChandu Babu N 	if (n >= AXGBE_XSTATS_COUNT && xstats_names) {
8359d1ef6b2SChandu Babu N 		for (i = 0; i < AXGBE_XSTATS_COUNT; ++i) {
8369d1ef6b2SChandu Babu N 			snprintf(xstats_names[i].name,
8379d1ef6b2SChandu Babu N 				 RTE_ETH_XSTATS_NAME_SIZE, "%s",
8389d1ef6b2SChandu Babu N 				 axgbe_xstats_strings[i].name);
8399d1ef6b2SChandu Babu N 		}
8409d1ef6b2SChandu Babu N 	}
8419d1ef6b2SChandu Babu N 
8429d1ef6b2SChandu Babu N 	return AXGBE_XSTATS_COUNT;
8439d1ef6b2SChandu Babu N }
8449d1ef6b2SChandu Babu N 
8459d1ef6b2SChandu Babu N static int
8469d1ef6b2SChandu Babu N axgbe_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids,
8479d1ef6b2SChandu Babu N 			   uint64_t *values, unsigned int n)
8489d1ef6b2SChandu Babu N {
8499d1ef6b2SChandu Babu N 	unsigned int i;
8509d1ef6b2SChandu Babu N 	uint64_t values_copy[AXGBE_XSTATS_COUNT];
8519d1ef6b2SChandu Babu N 
8529d1ef6b2SChandu Babu N 	if (!ids) {
8539d1ef6b2SChandu Babu N 		struct axgbe_port *pdata = dev->data->dev_private;
8549d1ef6b2SChandu Babu N 
8559d1ef6b2SChandu Babu N 		if (n < AXGBE_XSTATS_COUNT)
8569d1ef6b2SChandu Babu N 			return AXGBE_XSTATS_COUNT;
8579d1ef6b2SChandu Babu N 
8589d1ef6b2SChandu Babu N 		axgbe_read_mmc_stats(pdata);
8599d1ef6b2SChandu Babu N 
8609d1ef6b2SChandu Babu N 		for (i = 0; i < AXGBE_XSTATS_COUNT; i++) {
8619d1ef6b2SChandu Babu N 			values[i] = *(u64 *)((uint8_t *)&pdata->mmc_stats +
8629d1ef6b2SChandu Babu N 					axgbe_xstats_strings[i].offset);
8639d1ef6b2SChandu Babu N 		}
8649d1ef6b2SChandu Babu N 
8659d1ef6b2SChandu Babu N 		return i;
8669d1ef6b2SChandu Babu N 	}
8679d1ef6b2SChandu Babu N 
8689d1ef6b2SChandu Babu N 	axgbe_dev_xstats_get_by_id(dev, NULL, values_copy, AXGBE_XSTATS_COUNT);
8699d1ef6b2SChandu Babu N 
8709d1ef6b2SChandu Babu N 	for (i = 0; i < n; i++) {
8719d1ef6b2SChandu Babu N 		if (ids[i] >= AXGBE_XSTATS_COUNT) {
8729d1ef6b2SChandu Babu N 			PMD_DRV_LOG(ERR, "id value isn't valid\n");
8739d1ef6b2SChandu Babu N 			return -1;
8749d1ef6b2SChandu Babu N 		}
8759d1ef6b2SChandu Babu N 		values[i] = values_copy[ids[i]];
8769d1ef6b2SChandu Babu N 	}
8779d1ef6b2SChandu Babu N 	return n;
8789d1ef6b2SChandu Babu N }
8799d1ef6b2SChandu Babu N 
8809d1ef6b2SChandu Babu N static int
8819d1ef6b2SChandu Babu N axgbe_dev_xstats_get_names_by_id(struct rte_eth_dev *dev,
8829d1ef6b2SChandu Babu N 				 struct rte_eth_xstat_name *xstats_names,
8839d1ef6b2SChandu Babu N 				 const uint64_t *ids,
8849d1ef6b2SChandu Babu N 				 unsigned int size)
8859d1ef6b2SChandu Babu N {
8869d1ef6b2SChandu Babu N 	struct rte_eth_xstat_name xstats_names_copy[AXGBE_XSTATS_COUNT];
8879d1ef6b2SChandu Babu N 	unsigned int i;
8889d1ef6b2SChandu Babu N 
8899d1ef6b2SChandu Babu N 	if (!ids)
8909d1ef6b2SChandu Babu N 		return axgbe_dev_xstats_get_names(dev, xstats_names, size);
8919d1ef6b2SChandu Babu N 
8929d1ef6b2SChandu Babu N 	axgbe_dev_xstats_get_names(dev, xstats_names_copy, size);
8939d1ef6b2SChandu Babu N 
8949d1ef6b2SChandu Babu N 	for (i = 0; i < size; i++) {
8959d1ef6b2SChandu Babu N 		if (ids[i] >= AXGBE_XSTATS_COUNT) {
8969d1ef6b2SChandu Babu N 			PMD_DRV_LOG(ERR, "id value isn't valid\n");
8979d1ef6b2SChandu Babu N 			return -1;
8989d1ef6b2SChandu Babu N 		}
8999d1ef6b2SChandu Babu N 		strcpy(xstats_names[i].name, xstats_names_copy[ids[i]].name);
9009d1ef6b2SChandu Babu N 	}
9019d1ef6b2SChandu Babu N 	return size;
9029d1ef6b2SChandu Babu N }
9039d1ef6b2SChandu Babu N 
9049d1ef6b2SChandu Babu N static int
9059d1ef6b2SChandu Babu N axgbe_dev_xstats_reset(struct rte_eth_dev *dev)
9069d1ef6b2SChandu Babu N {
9079d1ef6b2SChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
9089d1ef6b2SChandu Babu N 	struct axgbe_mmc_stats *stats = &pdata->mmc_stats;
9099d1ef6b2SChandu Babu N 
9109d1ef6b2SChandu Babu N 	/* MMC registers are configured for reset on read */
9119d1ef6b2SChandu Babu N 	axgbe_read_mmc_stats(pdata);
9129d1ef6b2SChandu Babu N 
9139d1ef6b2SChandu Babu N 	/* Reset stats */
9149d1ef6b2SChandu Babu N 	memset(stats, 0, sizeof(*stats));
9159d1ef6b2SChandu Babu N 
9169d1ef6b2SChandu Babu N 	return 0;
9179d1ef6b2SChandu Babu N }
9189d1ef6b2SChandu Babu N 
9193e730511SRavi Kumar static int
9203e730511SRavi Kumar axgbe_dev_stats_get(struct rte_eth_dev *dev,
9213e730511SRavi Kumar 		    struct rte_eth_stats *stats)
9223e730511SRavi Kumar {
9233e730511SRavi Kumar 	struct axgbe_rx_queue *rxq;
9243e730511SRavi Kumar 	struct axgbe_tx_queue *txq;
9259d1ef6b2SChandu Babu N 	struct axgbe_port *pdata = dev->data->dev_private;
9269d1ef6b2SChandu Babu N 	struct axgbe_mmc_stats *mmc_stats = &pdata->mmc_stats;
9273e730511SRavi Kumar 	unsigned int i;
9283e730511SRavi Kumar 
9299d1ef6b2SChandu Babu N 	axgbe_read_mmc_stats(pdata);
9309d1ef6b2SChandu Babu N 
9319d1ef6b2SChandu Babu N 	stats->imissed = mmc_stats->rxfifooverflow;
9329d1ef6b2SChandu Babu N 
9333e730511SRavi Kumar 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
9343e730511SRavi Kumar 		rxq = dev->data->rx_queues[i];
9353e730511SRavi Kumar 		stats->q_ipackets[i] = rxq->pkts;
9363e730511SRavi Kumar 		stats->ipackets += rxq->pkts;
9373e730511SRavi Kumar 		stats->q_ibytes[i] = rxq->bytes;
9383e730511SRavi Kumar 		stats->ibytes += rxq->bytes;
9399d1ef6b2SChandu Babu N 		stats->rx_nombuf += rxq->rx_mbuf_alloc_failed;
9409d1ef6b2SChandu Babu N 		stats->q_errors[i] = rxq->errors + rxq->rx_mbuf_alloc_failed;
9419d1ef6b2SChandu Babu N 		stats->ierrors += rxq->errors;
9423e730511SRavi Kumar 	}
9439d1ef6b2SChandu Babu N 
9443e730511SRavi Kumar 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
9453e730511SRavi Kumar 		txq = dev->data->tx_queues[i];
9463e730511SRavi Kumar 		stats->q_opackets[i] = txq->pkts;
9473e730511SRavi Kumar 		stats->opackets += txq->pkts;
9483e730511SRavi Kumar 		stats->q_obytes[i] = txq->bytes;
9493e730511SRavi Kumar 		stats->obytes += txq->bytes;
9509d1ef6b2SChandu Babu N 		stats->oerrors += txq->errors;
9513e730511SRavi Kumar 	}
9523e730511SRavi Kumar 
9533e730511SRavi Kumar 	return 0;
9543e730511SRavi Kumar }
9553e730511SRavi Kumar 
9569970a9adSIgor Romanov static int
9573e730511SRavi Kumar axgbe_dev_stats_reset(struct rte_eth_dev *dev)
9583e730511SRavi Kumar {
9593e730511SRavi Kumar 	struct axgbe_rx_queue *rxq;
9603e730511SRavi Kumar 	struct axgbe_tx_queue *txq;
9613e730511SRavi Kumar 	unsigned int i;
9623e730511SRavi Kumar 
9633e730511SRavi Kumar 	for (i = 0; i < dev->data->nb_rx_queues; i++) {
9643e730511SRavi Kumar 		rxq = dev->data->rx_queues[i];
9653e730511SRavi Kumar 		rxq->pkts = 0;
9663e730511SRavi Kumar 		rxq->bytes = 0;
9673e730511SRavi Kumar 		rxq->errors = 0;
9689d1ef6b2SChandu Babu N 		rxq->rx_mbuf_alloc_failed = 0;
9693e730511SRavi Kumar 	}
9703e730511SRavi Kumar 	for (i = 0; i < dev->data->nb_tx_queues; i++) {
9713e730511SRavi Kumar 		txq = dev->data->tx_queues[i];
9723e730511SRavi Kumar 		txq->pkts = 0;
9733e730511SRavi Kumar 		txq->bytes = 0;
9743e730511SRavi Kumar 		txq->errors = 0;
9753e730511SRavi Kumar 	}
9769970a9adSIgor Romanov 
9779970a9adSIgor Romanov 	return 0;
9783e730511SRavi Kumar }
9793e730511SRavi Kumar 
980bdad90d1SIvan Ilchenko static int
981cd8c7c7cSFerruh Yigit axgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
9829e890103SRavi Kumar {
9839e890103SRavi Kumar 	struct axgbe_port *pdata = dev->data->dev_private;
9849e890103SRavi Kumar 
9859e890103SRavi Kumar 	dev_info->max_rx_queues = pdata->rx_ring_count;
9869e890103SRavi Kumar 	dev_info->max_tx_queues = pdata->tx_ring_count;
9879e890103SRavi Kumar 	dev_info->min_rx_bufsize = AXGBE_RX_MIN_BUF_SIZE;
9889e890103SRavi Kumar 	dev_info->max_rx_pktlen = AXGBE_RX_MAX_BUF_SIZE;
98949a5e622SChandu Babu N 	dev_info->max_mac_addrs = pdata->hw_feat.addn_mac + 1;
990e01d9b2eSChandu Babu N 	dev_info->max_hash_mac_addrs = pdata->hw_feat.hash_table_size;
9919e890103SRavi Kumar 	dev_info->speed_capa =  ETH_LINK_SPEED_10G;
9929e890103SRavi Kumar 
9939e890103SRavi Kumar 	dev_info->rx_offload_capa =
9949e890103SRavi Kumar 		DEV_RX_OFFLOAD_IPV4_CKSUM |
9959e890103SRavi Kumar 		DEV_RX_OFFLOAD_UDP_CKSUM  |
99670815c9eSFerruh Yigit 		DEV_RX_OFFLOAD_TCP_CKSUM  |
997965b3127SSelwin Sebastian 		DEV_RX_OFFLOAD_JUMBO_FRAME	|
998965b3127SSelwin Sebastian 		DEV_RX_OFFLOAD_SCATTER	  |
99970815c9eSFerruh Yigit 		DEV_RX_OFFLOAD_KEEP_CRC;
10009e890103SRavi Kumar 
10019e890103SRavi Kumar 	dev_info->tx_offload_capa =
10029e890103SRavi Kumar 		DEV_TX_OFFLOAD_IPV4_CKSUM  |
10039e890103SRavi Kumar 		DEV_TX_OFFLOAD_UDP_CKSUM   |
10049e890103SRavi Kumar 		DEV_TX_OFFLOAD_TCP_CKSUM;
10059e890103SRavi Kumar 
10069e890103SRavi Kumar 	if (pdata->hw_feat.rss) {
10079e890103SRavi Kumar 		dev_info->flow_type_rss_offloads = AXGBE_RSS_OFFLOAD;
10089e890103SRavi Kumar 		dev_info->reta_size = pdata->hw_feat.hash_table_size;
10099e890103SRavi Kumar 		dev_info->hash_key_size =  AXGBE_RSS_HASH_KEY_SIZE;
10109e890103SRavi Kumar 	}
10119e890103SRavi Kumar 
10129e890103SRavi Kumar 	dev_info->rx_desc_lim = rx_desc_lim;
10139e890103SRavi Kumar 	dev_info->tx_desc_lim = tx_desc_lim;
10149e890103SRavi Kumar 
10159e890103SRavi Kumar 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
10169e890103SRavi Kumar 		.rx_free_thresh = AXGBE_RX_FREE_THRESH,
10179e890103SRavi Kumar 	};
10189e890103SRavi Kumar 
10199e890103SRavi Kumar 	dev_info->default_txconf = (struct rte_eth_txconf) {
10209e890103SRavi Kumar 		.tx_free_thresh = AXGBE_TX_FREE_THRESH,
10219e890103SRavi Kumar 	};
1022bdad90d1SIvan Ilchenko 
1023bdad90d1SIvan Ilchenko 	return 0;
10249e890103SRavi Kumar }
10259e890103SRavi Kumar 
1026cf97f33eSAmaranath Somalapuram static int
1027cf97f33eSAmaranath Somalapuram axgbe_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
1028cf97f33eSAmaranath Somalapuram {
1029cf97f33eSAmaranath Somalapuram 	struct axgbe_port *pdata = dev->data->dev_private;
1030cf97f33eSAmaranath Somalapuram 	struct xgbe_fc_info fc = pdata->fc;
1031cf97f33eSAmaranath Somalapuram 	unsigned int reg, reg_val = 0;
1032cf97f33eSAmaranath Somalapuram 
1033cf97f33eSAmaranath Somalapuram 	reg = MAC_Q0TFCR;
1034cf97f33eSAmaranath Somalapuram 	reg_val = AXGMAC_IOREAD(pdata, reg);
1035cf97f33eSAmaranath Somalapuram 	fc.low_water[0] =  AXGMAC_MTL_IOREAD_BITS(pdata, 0, MTL_Q_RQFCR, RFA);
1036cf97f33eSAmaranath Somalapuram 	fc.high_water[0] =  AXGMAC_MTL_IOREAD_BITS(pdata, 0, MTL_Q_RQFCR, RFD);
1037cf97f33eSAmaranath Somalapuram 	fc.pause_time[0] = AXGMAC_GET_BITS(reg_val, MAC_Q0TFCR, PT);
1038cf97f33eSAmaranath Somalapuram 	fc.autoneg = pdata->pause_autoneg;
1039cf97f33eSAmaranath Somalapuram 
1040cf97f33eSAmaranath Somalapuram 	if (pdata->rx_pause && pdata->tx_pause)
1041cf97f33eSAmaranath Somalapuram 		fc.mode = RTE_FC_FULL;
1042cf97f33eSAmaranath Somalapuram 	else if (pdata->rx_pause)
1043cf97f33eSAmaranath Somalapuram 		fc.mode = RTE_FC_RX_PAUSE;
1044cf97f33eSAmaranath Somalapuram 	else if (pdata->tx_pause)
1045cf97f33eSAmaranath Somalapuram 		fc.mode = RTE_FC_TX_PAUSE;
1046cf97f33eSAmaranath Somalapuram 	else
1047cf97f33eSAmaranath Somalapuram 		fc.mode = RTE_FC_NONE;
1048cf97f33eSAmaranath Somalapuram 
1049cf97f33eSAmaranath Somalapuram 	fc_conf->high_water =  (1024 + (fc.low_water[0] << 9)) / 1024;
1050cf97f33eSAmaranath Somalapuram 	fc_conf->low_water =  (1024 + (fc.high_water[0] << 9)) / 1024;
1051cf97f33eSAmaranath Somalapuram 	fc_conf->pause_time = fc.pause_time[0];
1052cf97f33eSAmaranath Somalapuram 	fc_conf->send_xon = fc.send_xon;
1053cf97f33eSAmaranath Somalapuram 	fc_conf->mode = fc.mode;
1054cf97f33eSAmaranath Somalapuram 
1055cf97f33eSAmaranath Somalapuram 	return 0;
1056cf97f33eSAmaranath Somalapuram }
1057cf97f33eSAmaranath Somalapuram 
1058cf97f33eSAmaranath Somalapuram static int
1059cf97f33eSAmaranath Somalapuram axgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
1060cf97f33eSAmaranath Somalapuram {
1061cf97f33eSAmaranath Somalapuram 	struct axgbe_port *pdata = dev->data->dev_private;
1062cf97f33eSAmaranath Somalapuram 	struct xgbe_fc_info fc = pdata->fc;
1063cf97f33eSAmaranath Somalapuram 	unsigned int reg, reg_val = 0;
1064cf97f33eSAmaranath Somalapuram 	reg = MAC_Q0TFCR;
1065cf97f33eSAmaranath Somalapuram 
1066cf97f33eSAmaranath Somalapuram 	pdata->pause_autoneg = fc_conf->autoneg;
1067cf97f33eSAmaranath Somalapuram 	pdata->phy.pause_autoneg = pdata->pause_autoneg;
1068cf97f33eSAmaranath Somalapuram 	fc.send_xon = fc_conf->send_xon;
1069cf97f33eSAmaranath Somalapuram 	AXGMAC_MTL_IOWRITE_BITS(pdata, 0, MTL_Q_RQFCR, RFA,
1070cf97f33eSAmaranath Somalapuram 			AXGMAC_FLOW_CONTROL_VALUE(1024 * fc_conf->high_water));
1071cf97f33eSAmaranath Somalapuram 	AXGMAC_MTL_IOWRITE_BITS(pdata, 0, MTL_Q_RQFCR, RFD,
1072cf97f33eSAmaranath Somalapuram 			AXGMAC_FLOW_CONTROL_VALUE(1024 * fc_conf->low_water));
1073cf97f33eSAmaranath Somalapuram 	AXGMAC_SET_BITS(reg_val, MAC_Q0TFCR, PT, fc_conf->pause_time);
1074cf97f33eSAmaranath Somalapuram 	AXGMAC_IOWRITE(pdata, reg, reg_val);
1075cf97f33eSAmaranath Somalapuram 	fc.mode = fc_conf->mode;
1076cf97f33eSAmaranath Somalapuram 
1077cf97f33eSAmaranath Somalapuram 	if (fc.mode == RTE_FC_FULL) {
1078cf97f33eSAmaranath Somalapuram 		pdata->tx_pause = 1;
1079cf97f33eSAmaranath Somalapuram 		pdata->rx_pause = 1;
1080cf97f33eSAmaranath Somalapuram 	} else if (fc.mode == RTE_FC_RX_PAUSE) {
1081cf97f33eSAmaranath Somalapuram 		pdata->tx_pause = 0;
1082cf97f33eSAmaranath Somalapuram 		pdata->rx_pause = 1;
1083cf97f33eSAmaranath Somalapuram 	} else if (fc.mode == RTE_FC_TX_PAUSE) {
1084cf97f33eSAmaranath Somalapuram 		pdata->tx_pause = 1;
1085cf97f33eSAmaranath Somalapuram 		pdata->rx_pause = 0;
1086cf97f33eSAmaranath Somalapuram 	} else {
1087cf97f33eSAmaranath Somalapuram 		pdata->tx_pause = 0;
1088cf97f33eSAmaranath Somalapuram 		pdata->rx_pause = 0;
1089cf97f33eSAmaranath Somalapuram 	}
1090cf97f33eSAmaranath Somalapuram 
1091cf97f33eSAmaranath Somalapuram 	if (pdata->tx_pause != (unsigned int)pdata->phy.tx_pause)
1092cf97f33eSAmaranath Somalapuram 		pdata->hw_if.config_tx_flow_control(pdata);
1093cf97f33eSAmaranath Somalapuram 
1094cf97f33eSAmaranath Somalapuram 	if (pdata->rx_pause != (unsigned int)pdata->phy.rx_pause)
1095cf97f33eSAmaranath Somalapuram 		pdata->hw_if.config_rx_flow_control(pdata);
1096cf97f33eSAmaranath Somalapuram 
1097cf97f33eSAmaranath Somalapuram 	pdata->hw_if.config_flow_control(pdata);
1098cf97f33eSAmaranath Somalapuram 	pdata->phy.tx_pause = pdata->tx_pause;
1099cf97f33eSAmaranath Somalapuram 	pdata->phy.rx_pause = pdata->rx_pause;
1100cf97f33eSAmaranath Somalapuram 
1101cf97f33eSAmaranath Somalapuram 	return 0;
1102cf97f33eSAmaranath Somalapuram }
1103cf97f33eSAmaranath Somalapuram 
1104e0543d4eSAmaranath Somalapuram static int
1105e0543d4eSAmaranath Somalapuram axgbe_priority_flow_ctrl_set(struct rte_eth_dev *dev,
1106e0543d4eSAmaranath Somalapuram 		struct rte_eth_pfc_conf *pfc_conf)
1107e0543d4eSAmaranath Somalapuram {
1108e0543d4eSAmaranath Somalapuram 	struct axgbe_port *pdata = dev->data->dev_private;
1109e0543d4eSAmaranath Somalapuram 	struct xgbe_fc_info fc = pdata->fc;
1110e0543d4eSAmaranath Somalapuram 	uint8_t tc_num;
1111e0543d4eSAmaranath Somalapuram 
1112e0543d4eSAmaranath Somalapuram 	tc_num = pdata->pfc_map[pfc_conf->priority];
1113e0543d4eSAmaranath Somalapuram 
1114e0543d4eSAmaranath Somalapuram 	if (pfc_conf->priority >= pdata->hw_feat.tc_cnt) {
1115e0543d4eSAmaranath Somalapuram 		PMD_INIT_LOG(ERR, "Max supported  traffic class: %d\n",
1116e0543d4eSAmaranath Somalapuram 				pdata->hw_feat.tc_cnt);
1117e0543d4eSAmaranath Somalapuram 	return -EINVAL;
1118e0543d4eSAmaranath Somalapuram 	}
1119e0543d4eSAmaranath Somalapuram 
1120e0543d4eSAmaranath Somalapuram 	pdata->pause_autoneg = pfc_conf->fc.autoneg;
1121e0543d4eSAmaranath Somalapuram 	pdata->phy.pause_autoneg = pdata->pause_autoneg;
1122e0543d4eSAmaranath Somalapuram 	fc.send_xon = pfc_conf->fc.send_xon;
1123e0543d4eSAmaranath Somalapuram 	AXGMAC_MTL_IOWRITE_BITS(pdata, tc_num, MTL_Q_RQFCR, RFA,
1124e0543d4eSAmaranath Somalapuram 		AXGMAC_FLOW_CONTROL_VALUE(1024 * pfc_conf->fc.high_water));
1125e0543d4eSAmaranath Somalapuram 	AXGMAC_MTL_IOWRITE_BITS(pdata, tc_num, MTL_Q_RQFCR, RFD,
1126e0543d4eSAmaranath Somalapuram 		AXGMAC_FLOW_CONTROL_VALUE(1024 * pfc_conf->fc.low_water));
1127e0543d4eSAmaranath Somalapuram 
1128e0543d4eSAmaranath Somalapuram 	switch (tc_num) {
1129e0543d4eSAmaranath Somalapuram 	case 0:
1130e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM0R,
1131e0543d4eSAmaranath Somalapuram 				PSTC0, pfc_conf->fc.pause_time);
1132e0543d4eSAmaranath Somalapuram 		break;
1133e0543d4eSAmaranath Somalapuram 	case 1:
1134e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM0R,
1135e0543d4eSAmaranath Somalapuram 				PSTC1, pfc_conf->fc.pause_time);
1136e0543d4eSAmaranath Somalapuram 		break;
1137e0543d4eSAmaranath Somalapuram 	case 2:
1138e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM0R,
1139e0543d4eSAmaranath Somalapuram 				PSTC2, pfc_conf->fc.pause_time);
1140e0543d4eSAmaranath Somalapuram 		break;
1141e0543d4eSAmaranath Somalapuram 	case 3:
1142e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM0R,
1143e0543d4eSAmaranath Somalapuram 				PSTC3, pfc_conf->fc.pause_time);
1144e0543d4eSAmaranath Somalapuram 		break;
1145e0543d4eSAmaranath Somalapuram 	case 4:
1146e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM1R,
1147e0543d4eSAmaranath Somalapuram 				PSTC4, pfc_conf->fc.pause_time);
1148e0543d4eSAmaranath Somalapuram 		break;
1149e0543d4eSAmaranath Somalapuram 	case 5:
1150e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM1R,
1151e0543d4eSAmaranath Somalapuram 				PSTC5, pfc_conf->fc.pause_time);
1152e0543d4eSAmaranath Somalapuram 		break;
1153e0543d4eSAmaranath Somalapuram 	case 7:
1154e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM1R,
1155e0543d4eSAmaranath Somalapuram 				PSTC6, pfc_conf->fc.pause_time);
1156e0543d4eSAmaranath Somalapuram 		break;
1157e0543d4eSAmaranath Somalapuram 	case 6:
1158e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM1R,
1159e0543d4eSAmaranath Somalapuram 				PSTC7, pfc_conf->fc.pause_time);
1160e0543d4eSAmaranath Somalapuram 		break;
1161e0543d4eSAmaranath Somalapuram 	}
1162e0543d4eSAmaranath Somalapuram 
1163e0543d4eSAmaranath Somalapuram 	fc.mode = pfc_conf->fc.mode;
1164e0543d4eSAmaranath Somalapuram 
1165e0543d4eSAmaranath Somalapuram 	if (fc.mode == RTE_FC_FULL) {
1166e0543d4eSAmaranath Somalapuram 		pdata->tx_pause = 1;
1167e0543d4eSAmaranath Somalapuram 		pdata->rx_pause = 1;
1168e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 1);
1169e0543d4eSAmaranath Somalapuram 	} else if (fc.mode == RTE_FC_RX_PAUSE) {
1170e0543d4eSAmaranath Somalapuram 		pdata->tx_pause = 0;
1171e0543d4eSAmaranath Somalapuram 		pdata->rx_pause = 1;
1172e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 1);
1173e0543d4eSAmaranath Somalapuram 	} else if (fc.mode == RTE_FC_TX_PAUSE) {
1174e0543d4eSAmaranath Somalapuram 		pdata->tx_pause = 1;
1175e0543d4eSAmaranath Somalapuram 		pdata->rx_pause = 0;
1176e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 0);
1177e0543d4eSAmaranath Somalapuram 	} else {
1178e0543d4eSAmaranath Somalapuram 		pdata->tx_pause = 0;
1179e0543d4eSAmaranath Somalapuram 		pdata->rx_pause = 0;
1180e0543d4eSAmaranath Somalapuram 		AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 0);
1181e0543d4eSAmaranath Somalapuram 	}
1182e0543d4eSAmaranath Somalapuram 
1183e0543d4eSAmaranath Somalapuram 	if (pdata->tx_pause != (unsigned int)pdata->phy.tx_pause)
1184e0543d4eSAmaranath Somalapuram 		pdata->hw_if.config_tx_flow_control(pdata);
1185e0543d4eSAmaranath Somalapuram 
1186e0543d4eSAmaranath Somalapuram 	if (pdata->rx_pause != (unsigned int)pdata->phy.rx_pause)
1187e0543d4eSAmaranath Somalapuram 		pdata->hw_if.config_rx_flow_control(pdata);
1188e0543d4eSAmaranath Somalapuram 	pdata->hw_if.config_flow_control(pdata);
1189e0543d4eSAmaranath Somalapuram 	pdata->phy.tx_pause = pdata->tx_pause;
1190e0543d4eSAmaranath Somalapuram 	pdata->phy.rx_pause = pdata->rx_pause;
1191e0543d4eSAmaranath Somalapuram 
1192e0543d4eSAmaranath Somalapuram 	return 0;
1193e0543d4eSAmaranath Somalapuram }
1194e0543d4eSAmaranath Somalapuram 
1195*7aed95c9SAmaranath Somalapuram void
1196*7aed95c9SAmaranath Somalapuram axgbe_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
1197*7aed95c9SAmaranath Somalapuram 	struct rte_eth_rxq_info *qinfo)
1198*7aed95c9SAmaranath Somalapuram {
1199*7aed95c9SAmaranath Somalapuram 	struct   axgbe_rx_queue *rxq;
1200*7aed95c9SAmaranath Somalapuram 
1201*7aed95c9SAmaranath Somalapuram 	rxq = dev->data->rx_queues[queue_id];
1202*7aed95c9SAmaranath Somalapuram 	qinfo->mp = rxq->mb_pool;
1203*7aed95c9SAmaranath Somalapuram 	qinfo->scattered_rx = dev->data->scattered_rx;
1204*7aed95c9SAmaranath Somalapuram 	qinfo->nb_desc = rxq->nb_desc;
1205*7aed95c9SAmaranath Somalapuram 	qinfo->conf.rx_free_thresh = rxq->free_thresh;
1206*7aed95c9SAmaranath Somalapuram }
1207*7aed95c9SAmaranath Somalapuram 
1208*7aed95c9SAmaranath Somalapuram void
1209*7aed95c9SAmaranath Somalapuram axgbe_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
1210*7aed95c9SAmaranath Somalapuram 	struct rte_eth_txq_info *qinfo)
1211*7aed95c9SAmaranath Somalapuram {
1212*7aed95c9SAmaranath Somalapuram 	struct  axgbe_tx_queue *txq;
1213*7aed95c9SAmaranath Somalapuram 
1214*7aed95c9SAmaranath Somalapuram 	txq = dev->data->tx_queues[queue_id];
1215*7aed95c9SAmaranath Somalapuram 	qinfo->nb_desc = txq->nb_desc;
1216*7aed95c9SAmaranath Somalapuram 	qinfo->conf.tx_free_thresh = txq->free_thresh;
1217*7aed95c9SAmaranath Somalapuram }
1218*7aed95c9SAmaranath Somalapuram 
1219572890efSRavi Kumar static void axgbe_get_all_hw_features(struct axgbe_port *pdata)
1220572890efSRavi Kumar {
1221572890efSRavi Kumar 	unsigned int mac_hfr0, mac_hfr1, mac_hfr2;
1222572890efSRavi Kumar 	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
1223572890efSRavi Kumar 
1224572890efSRavi Kumar 	mac_hfr0 = AXGMAC_IOREAD(pdata, MAC_HWF0R);
1225572890efSRavi Kumar 	mac_hfr1 = AXGMAC_IOREAD(pdata, MAC_HWF1R);
1226572890efSRavi Kumar 	mac_hfr2 = AXGMAC_IOREAD(pdata, MAC_HWF2R);
1227572890efSRavi Kumar 
1228572890efSRavi Kumar 	memset(hw_feat, 0, sizeof(*hw_feat));
1229572890efSRavi Kumar 
1230572890efSRavi Kumar 	hw_feat->version = AXGMAC_IOREAD(pdata, MAC_VR);
1231572890efSRavi Kumar 
1232572890efSRavi Kumar 	/* Hardware feature register 0 */
1233572890efSRavi Kumar 	hw_feat->gmii        = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, GMIISEL);
1234572890efSRavi Kumar 	hw_feat->vlhash      = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, VLHASH);
1235572890efSRavi Kumar 	hw_feat->sma         = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, SMASEL);
1236572890efSRavi Kumar 	hw_feat->rwk         = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, RWKSEL);
1237572890efSRavi Kumar 	hw_feat->mgk         = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, MGKSEL);
1238572890efSRavi Kumar 	hw_feat->mmc         = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, MMCSEL);
1239572890efSRavi Kumar 	hw_feat->aoe         = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, ARPOFFSEL);
1240572890efSRavi Kumar 	hw_feat->ts          = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TSSEL);
1241572890efSRavi Kumar 	hw_feat->eee         = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, EEESEL);
1242572890efSRavi Kumar 	hw_feat->tx_coe      = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TXCOESEL);
1243572890efSRavi Kumar 	hw_feat->rx_coe      = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, RXCOESEL);
1244572890efSRavi Kumar 	hw_feat->addn_mac    = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R,
1245572890efSRavi Kumar 					      ADDMACADRSEL);
1246572890efSRavi Kumar 	hw_feat->ts_src      = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TSSTSSEL);
1247572890efSRavi Kumar 	hw_feat->sa_vlan_ins = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, SAVLANINS);
1248572890efSRavi Kumar 
1249572890efSRavi Kumar 	/* Hardware feature register 1 */
1250572890efSRavi Kumar 	hw_feat->rx_fifo_size  = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
1251572890efSRavi Kumar 						RXFIFOSIZE);
1252572890efSRavi Kumar 	hw_feat->tx_fifo_size  = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
1253572890efSRavi Kumar 						TXFIFOSIZE);
1254572890efSRavi Kumar 	hw_feat->adv_ts_hi     = AXGMAC_GET_BITS(mac_hfr1,
1255572890efSRavi Kumar 						 MAC_HWF1R, ADVTHWORD);
1256572890efSRavi Kumar 	hw_feat->dma_width     = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, ADDR64);
1257572890efSRavi Kumar 	hw_feat->dcb           = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DCBEN);
1258572890efSRavi Kumar 	hw_feat->sph           = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, SPHEN);
1259572890efSRavi Kumar 	hw_feat->tso           = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, TSOEN);
1260572890efSRavi Kumar 	hw_feat->dma_debug     = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DBGMEMA);
1261572890efSRavi Kumar 	hw_feat->rss           = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, RSSEN);
1262572890efSRavi Kumar 	hw_feat->tc_cnt	       = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, NUMTC);
1263572890efSRavi Kumar 	hw_feat->hash_table_size = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
1264572890efSRavi Kumar 						  HASHTBLSZ);
1265572890efSRavi Kumar 	hw_feat->l3l4_filter_num = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
1266572890efSRavi Kumar 						  L3L4FNUM);
1267572890efSRavi Kumar 
1268572890efSRavi Kumar 	/* Hardware feature register 2 */
1269572890efSRavi Kumar 	hw_feat->rx_q_cnt     = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, RXQCNT);
1270572890efSRavi Kumar 	hw_feat->tx_q_cnt     = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, TXQCNT);
1271572890efSRavi Kumar 	hw_feat->rx_ch_cnt    = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, RXCHCNT);
1272572890efSRavi Kumar 	hw_feat->tx_ch_cnt    = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, TXCHCNT);
1273572890efSRavi Kumar 	hw_feat->pps_out_num  = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, PPSOUTNUM);
1274572890efSRavi Kumar 	hw_feat->aux_snap_num = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R,
1275572890efSRavi Kumar 						AUXSNAPNUM);
1276572890efSRavi Kumar 
1277572890efSRavi Kumar 	/* Translate the Hash Table size into actual number */
1278572890efSRavi Kumar 	switch (hw_feat->hash_table_size) {
1279572890efSRavi Kumar 	case 0:
1280572890efSRavi Kumar 		break;
1281572890efSRavi Kumar 	case 1:
1282572890efSRavi Kumar 		hw_feat->hash_table_size = 64;
1283572890efSRavi Kumar 		break;
1284572890efSRavi Kumar 	case 2:
1285572890efSRavi Kumar 		hw_feat->hash_table_size = 128;
1286572890efSRavi Kumar 		break;
1287572890efSRavi Kumar 	case 3:
1288572890efSRavi Kumar 		hw_feat->hash_table_size = 256;
1289572890efSRavi Kumar 		break;
1290572890efSRavi Kumar 	}
1291572890efSRavi Kumar 
1292572890efSRavi Kumar 	/* Translate the address width setting into actual number */
1293572890efSRavi Kumar 	switch (hw_feat->dma_width) {
1294572890efSRavi Kumar 	case 0:
1295572890efSRavi Kumar 		hw_feat->dma_width = 32;
1296572890efSRavi Kumar 		break;
1297572890efSRavi Kumar 	case 1:
1298572890efSRavi Kumar 		hw_feat->dma_width = 40;
1299572890efSRavi Kumar 		break;
1300572890efSRavi Kumar 	case 2:
1301572890efSRavi Kumar 		hw_feat->dma_width = 48;
1302572890efSRavi Kumar 		break;
1303572890efSRavi Kumar 	default:
1304572890efSRavi Kumar 		hw_feat->dma_width = 32;
1305572890efSRavi Kumar 	}
1306572890efSRavi Kumar 
1307572890efSRavi Kumar 	/* The Queue, Channel and TC counts are zero based so increment them
1308572890efSRavi Kumar 	 * to get the actual number
1309572890efSRavi Kumar 	 */
1310572890efSRavi Kumar 	hw_feat->rx_q_cnt++;
1311572890efSRavi Kumar 	hw_feat->tx_q_cnt++;
1312572890efSRavi Kumar 	hw_feat->rx_ch_cnt++;
1313572890efSRavi Kumar 	hw_feat->tx_ch_cnt++;
1314572890efSRavi Kumar 	hw_feat->tc_cnt++;
1315572890efSRavi Kumar 
1316572890efSRavi Kumar 	/* Translate the fifo sizes into actual numbers */
1317572890efSRavi Kumar 	hw_feat->rx_fifo_size = 1 << (hw_feat->rx_fifo_size + 7);
1318572890efSRavi Kumar 	hw_feat->tx_fifo_size = 1 << (hw_feat->tx_fifo_size + 7);
1319572890efSRavi Kumar }
1320572890efSRavi Kumar 
1321572890efSRavi Kumar static void axgbe_init_all_fptrs(struct axgbe_port *pdata)
1322572890efSRavi Kumar {
1323572890efSRavi Kumar 	axgbe_init_function_ptrs_dev(&pdata->hw_if);
13244ac7516bSRavi Kumar 	axgbe_init_function_ptrs_phy(&pdata->phy_if);
13254ac7516bSRavi Kumar 	axgbe_init_function_ptrs_i2c(&pdata->i2c_if);
13264ac7516bSRavi Kumar 	pdata->vdata->init_function_ptrs_phy_impl(&pdata->phy_if);
1327572890efSRavi Kumar }
1328572890efSRavi Kumar 
1329572890efSRavi Kumar static void axgbe_set_counts(struct axgbe_port *pdata)
1330572890efSRavi Kumar {
1331572890efSRavi Kumar 	/* Set all the function pointers */
1332572890efSRavi Kumar 	axgbe_init_all_fptrs(pdata);
1333572890efSRavi Kumar 
1334572890efSRavi Kumar 	/* Populate the hardware features */
1335572890efSRavi Kumar 	axgbe_get_all_hw_features(pdata);
1336572890efSRavi Kumar 
1337572890efSRavi Kumar 	/* Set default max values if not provided */
1338572890efSRavi Kumar 	if (!pdata->tx_max_channel_count)
1339572890efSRavi Kumar 		pdata->tx_max_channel_count = pdata->hw_feat.tx_ch_cnt;
1340572890efSRavi Kumar 	if (!pdata->rx_max_channel_count)
1341572890efSRavi Kumar 		pdata->rx_max_channel_count = pdata->hw_feat.rx_ch_cnt;
1342572890efSRavi Kumar 
1343572890efSRavi Kumar 	if (!pdata->tx_max_q_count)
1344572890efSRavi Kumar 		pdata->tx_max_q_count = pdata->hw_feat.tx_q_cnt;
1345572890efSRavi Kumar 	if (!pdata->rx_max_q_count)
1346572890efSRavi Kumar 		pdata->rx_max_q_count = pdata->hw_feat.rx_q_cnt;
1347572890efSRavi Kumar 
1348572890efSRavi Kumar 	/* Calculate the number of Tx and Rx rings to be created
1349572890efSRavi Kumar 	 *  -Tx (DMA) Channels map 1-to-1 to Tx Queues so set
1350572890efSRavi Kumar 	 *   the number of Tx queues to the number of Tx channels
1351572890efSRavi Kumar 	 *   enabled
1352572890efSRavi Kumar 	 *  -Rx (DMA) Channels do not map 1-to-1 so use the actual
1353572890efSRavi Kumar 	 *   number of Rx queues or maximum allowed
1354572890efSRavi Kumar 	 */
1355572890efSRavi Kumar 	pdata->tx_ring_count = RTE_MIN(pdata->hw_feat.tx_ch_cnt,
1356572890efSRavi Kumar 				     pdata->tx_max_channel_count);
1357572890efSRavi Kumar 	pdata->tx_ring_count = RTE_MIN(pdata->tx_ring_count,
1358572890efSRavi Kumar 				     pdata->tx_max_q_count);
1359572890efSRavi Kumar 
1360572890efSRavi Kumar 	pdata->tx_q_count = pdata->tx_ring_count;
1361572890efSRavi Kumar 
1362572890efSRavi Kumar 	pdata->rx_ring_count = RTE_MIN(pdata->hw_feat.rx_ch_cnt,
1363572890efSRavi Kumar 				     pdata->rx_max_channel_count);
1364572890efSRavi Kumar 
1365572890efSRavi Kumar 	pdata->rx_q_count = RTE_MIN(pdata->hw_feat.rx_q_cnt,
1366572890efSRavi Kumar 				  pdata->rx_max_q_count);
1367572890efSRavi Kumar }
1368572890efSRavi Kumar 
1369572890efSRavi Kumar static void axgbe_default_config(struct axgbe_port *pdata)
1370572890efSRavi Kumar {
1371572890efSRavi Kumar 	pdata->pblx8 = DMA_PBL_X8_ENABLE;
1372572890efSRavi Kumar 	pdata->tx_sf_mode = MTL_TSF_ENABLE;
1373572890efSRavi Kumar 	pdata->tx_threshold = MTL_TX_THRESHOLD_64;
1374572890efSRavi Kumar 	pdata->tx_pbl = DMA_PBL_32;
1375572890efSRavi Kumar 	pdata->tx_osp_mode = DMA_OSP_ENABLE;
1376572890efSRavi Kumar 	pdata->rx_sf_mode = MTL_RSF_ENABLE;
1377572890efSRavi Kumar 	pdata->rx_threshold = MTL_RX_THRESHOLD_64;
1378572890efSRavi Kumar 	pdata->rx_pbl = DMA_PBL_32;
1379572890efSRavi Kumar 	pdata->pause_autoneg = 1;
1380572890efSRavi Kumar 	pdata->tx_pause = 0;
1381572890efSRavi Kumar 	pdata->rx_pause = 0;
1382572890efSRavi Kumar 	pdata->phy_speed = SPEED_UNKNOWN;
1383572890efSRavi Kumar 	pdata->power_down = 0;
1384572890efSRavi Kumar }
1385572890efSRavi Kumar 
1386991e0b1dSSelwin Sebastian static int
1387991e0b1dSSelwin Sebastian pci_device_cmp(const struct rte_device *dev, const void *_pci_id)
1388991e0b1dSSelwin Sebastian {
1389991e0b1dSSelwin Sebastian 	const struct rte_pci_device *pdev = RTE_DEV_TO_PCI_CONST(dev);
1390991e0b1dSSelwin Sebastian 	const struct rte_pci_id *pcid = _pci_id;
1391991e0b1dSSelwin Sebastian 
1392991e0b1dSSelwin Sebastian 	if (pdev->id.vendor_id == AMD_PCI_VENDOR_ID &&
1393991e0b1dSSelwin Sebastian 			pdev->id.device_id == pcid->device_id)
1394991e0b1dSSelwin Sebastian 		return 0;
1395991e0b1dSSelwin Sebastian 	return 1;
1396991e0b1dSSelwin Sebastian }
1397991e0b1dSSelwin Sebastian 
1398991e0b1dSSelwin Sebastian static bool
1399991e0b1dSSelwin Sebastian pci_search_device(int device_id)
1400991e0b1dSSelwin Sebastian {
1401991e0b1dSSelwin Sebastian 	struct rte_bus *pci_bus;
1402991e0b1dSSelwin Sebastian 	struct rte_pci_id dev_id;
1403991e0b1dSSelwin Sebastian 
1404991e0b1dSSelwin Sebastian 	dev_id.device_id = device_id;
1405991e0b1dSSelwin Sebastian 	pci_bus = rte_bus_find_by_name("pci");
1406991e0b1dSSelwin Sebastian 	return (pci_bus != NULL) &&
1407991e0b1dSSelwin Sebastian 		(pci_bus->find_device(NULL, pci_device_cmp, &dev_id) != NULL);
1408991e0b1dSSelwin Sebastian }
1409991e0b1dSSelwin Sebastian 
14108691632fSRavi Kumar /*
14118691632fSRavi Kumar  * It returns 0 on success.
14128691632fSRavi Kumar  */
14138691632fSRavi Kumar static int
14148691632fSRavi Kumar eth_axgbe_dev_init(struct rte_eth_dev *eth_dev)
14158691632fSRavi Kumar {
14168691632fSRavi Kumar 	PMD_INIT_FUNC_TRACE();
14178691632fSRavi Kumar 	struct axgbe_port *pdata;
14188691632fSRavi Kumar 	struct rte_pci_device *pci_dev;
1419572890efSRavi Kumar 	uint32_t reg, mac_lo, mac_hi;
142049a5e622SChandu Babu N 	uint32_t len;
1421572890efSRavi Kumar 	int ret;
14228691632fSRavi Kumar 
14239e890103SRavi Kumar 	eth_dev->dev_ops = &axgbe_eth_dev_ops;
14249e890103SRavi Kumar 
14258691632fSRavi Kumar 	/*
14268691632fSRavi Kumar 	 * For secondary processes, we don't initialise any further as primary
14278691632fSRavi Kumar 	 * has already done this work.
14288691632fSRavi Kumar 	 */
14298691632fSRavi Kumar 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
14308691632fSRavi Kumar 		return 0;
14318691632fSRavi Kumar 
14320bc212a8SStephen Hemminger 	pdata = eth_dev->data->dev_private;
1433572890efSRavi Kumar 	/* initial state */
1434572890efSRavi Kumar 	axgbe_set_bit(AXGBE_DOWN, &pdata->dev_state);
1435572890efSRavi Kumar 	axgbe_set_bit(AXGBE_STOPPED, &pdata->dev_state);
14368691632fSRavi Kumar 	pdata->eth_dev = eth_dev;
14378691632fSRavi Kumar 
14388691632fSRavi Kumar 	pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
14398691632fSRavi Kumar 	pdata->pci_dev = pci_dev;
14408691632fSRavi Kumar 
1441991e0b1dSSelwin Sebastian 	/*
1442991e0b1dSSelwin Sebastian 	 * Use root complex device ID to differentiate RV AXGBE vs SNOWY AXGBE
1443991e0b1dSSelwin Sebastian 	 */
1444991e0b1dSSelwin Sebastian 	if (pci_search_device(AMD_PCI_RV_ROOT_COMPLEX_ID)) {
1445991e0b1dSSelwin Sebastian 		pdata->xpcs_window_def_reg = PCS_V2_RV_WINDOW_DEF;
1446991e0b1dSSelwin Sebastian 		pdata->xpcs_window_sel_reg = PCS_V2_RV_WINDOW_SELECT;
1447991e0b1dSSelwin Sebastian 	} else {
1448991e0b1dSSelwin Sebastian 		pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF;
1449991e0b1dSSelwin Sebastian 		pdata->xpcs_window_sel_reg = PCS_V2_WINDOW_SELECT;
1450991e0b1dSSelwin Sebastian 	}
1451991e0b1dSSelwin Sebastian 
1452572890efSRavi Kumar 	pdata->xgmac_regs =
14537784d0d3SRavi Kumar 		(void *)pci_dev->mem_resource[AXGBE_AXGMAC_BAR].addr;
14547784d0d3SRavi Kumar 	pdata->xprop_regs = (void *)((uint8_t *)pdata->xgmac_regs
14557784d0d3SRavi Kumar 				     + AXGBE_MAC_PROP_OFFSET);
14567784d0d3SRavi Kumar 	pdata->xi2c_regs = (void *)((uint8_t *)pdata->xgmac_regs
14577784d0d3SRavi Kumar 				    + AXGBE_I2C_CTRL_OFFSET);
14587784d0d3SRavi Kumar 	pdata->xpcs_regs = (void *)pci_dev->mem_resource[AXGBE_XPCS_BAR].addr;
1459572890efSRavi Kumar 
1460572890efSRavi Kumar 	/* version specific driver data*/
1461572890efSRavi Kumar 	if (pci_dev->id.device_id == AMD_PCI_AXGBE_DEVICE_V2A)
1462572890efSRavi Kumar 		pdata->vdata = &axgbe_v2a;
1463572890efSRavi Kumar 	else
1464572890efSRavi Kumar 		pdata->vdata = &axgbe_v2b;
1465572890efSRavi Kumar 
1466572890efSRavi Kumar 	/* Configure the PCS indirect addressing support */
1467991e0b1dSSelwin Sebastian 	reg = XPCS32_IOREAD(pdata, pdata->xpcs_window_def_reg);
1468572890efSRavi Kumar 	pdata->xpcs_window = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, OFFSET);
1469572890efSRavi Kumar 	pdata->xpcs_window <<= 6;
1470572890efSRavi Kumar 	pdata->xpcs_window_size = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, SIZE);
1471572890efSRavi Kumar 	pdata->xpcs_window_size = 1 << (pdata->xpcs_window_size + 7);
1472572890efSRavi Kumar 	pdata->xpcs_window_mask = pdata->xpcs_window_size - 1;
1473991e0b1dSSelwin Sebastian 
1474572890efSRavi Kumar 	PMD_INIT_LOG(DEBUG,
1475572890efSRavi Kumar 		     "xpcs window :%x, size :%x, mask :%x ", pdata->xpcs_window,
1476572890efSRavi Kumar 		     pdata->xpcs_window_size, pdata->xpcs_window_mask);
1477572890efSRavi Kumar 	XP_IOWRITE(pdata, XP_INT_EN, 0x1fffff);
1478572890efSRavi Kumar 
1479572890efSRavi Kumar 	/* Retrieve the MAC address */
1480572890efSRavi Kumar 	mac_lo = XP_IOREAD(pdata, XP_MAC_ADDR_LO);
1481572890efSRavi Kumar 	mac_hi = XP_IOREAD(pdata, XP_MAC_ADDR_HI);
1482572890efSRavi Kumar 	pdata->mac_addr.addr_bytes[0] = mac_lo & 0xff;
1483572890efSRavi Kumar 	pdata->mac_addr.addr_bytes[1] = (mac_lo >> 8) & 0xff;
1484572890efSRavi Kumar 	pdata->mac_addr.addr_bytes[2] = (mac_lo >> 16) & 0xff;
1485572890efSRavi Kumar 	pdata->mac_addr.addr_bytes[3] = (mac_lo >> 24) & 0xff;
1486572890efSRavi Kumar 	pdata->mac_addr.addr_bytes[4] = mac_hi & 0xff;
1487572890efSRavi Kumar 	pdata->mac_addr.addr_bytes[5] = (mac_hi >> 8)  &  0xff;
1488572890efSRavi Kumar 
148949a5e622SChandu Babu N 	len = RTE_ETHER_ADDR_LEN * AXGBE_MAX_MAC_ADDRS;
149049a5e622SChandu Babu N 	eth_dev->data->mac_addrs = rte_zmalloc("axgbe_mac_addr", len, 0);
149149a5e622SChandu Babu N 
1492572890efSRavi Kumar 	if (!eth_dev->data->mac_addrs) {
1493572890efSRavi Kumar 		PMD_INIT_LOG(ERR,
149449a5e622SChandu Babu N 			     "Failed to alloc %u bytes needed to "
149549a5e622SChandu Babu N 			     "store MAC addresses", len);
1496572890efSRavi Kumar 		return -ENOMEM;
1497572890efSRavi Kumar 	}
1498572890efSRavi Kumar 
1499e01d9b2eSChandu Babu N 	/* Allocate memory for storing hash filter MAC addresses */
1500e01d9b2eSChandu Babu N 	len = RTE_ETHER_ADDR_LEN * AXGBE_MAX_HASH_MAC_ADDRS;
1501e01d9b2eSChandu Babu N 	eth_dev->data->hash_mac_addrs = rte_zmalloc("axgbe_hash_mac_addr",
1502e01d9b2eSChandu Babu N 						    len, 0);
1503e01d9b2eSChandu Babu N 
1504e01d9b2eSChandu Babu N 	if (eth_dev->data->hash_mac_addrs == NULL) {
1505e01d9b2eSChandu Babu N 		PMD_INIT_LOG(ERR,
1506e01d9b2eSChandu Babu N 			     "Failed to allocate %d bytes needed to "
1507e01d9b2eSChandu Babu N 			     "store MAC addresses", len);
1508e01d9b2eSChandu Babu N 		return -ENOMEM;
1509e01d9b2eSChandu Babu N 	}
1510e01d9b2eSChandu Babu N 
1511538da7a1SOlivier Matz 	if (!rte_is_valid_assigned_ether_addr(&pdata->mac_addr))
1512538da7a1SOlivier Matz 		rte_eth_random_addr(pdata->mac_addr.addr_bytes);
1513572890efSRavi Kumar 
1514572890efSRavi Kumar 	/* Copy the permanent MAC address */
1515538da7a1SOlivier Matz 	rte_ether_addr_copy(&pdata->mac_addr, &eth_dev->data->mac_addrs[0]);
1516572890efSRavi Kumar 
1517572890efSRavi Kumar 	/* Clock settings */
1518572890efSRavi Kumar 	pdata->sysclk_rate = AXGBE_V2_DMA_CLOCK_FREQ;
1519572890efSRavi Kumar 	pdata->ptpclk_rate = AXGBE_V2_PTP_CLOCK_FREQ;
1520572890efSRavi Kumar 
1521572890efSRavi Kumar 	/* Set the DMA coherency values */
1522572890efSRavi Kumar 	pdata->coherent = 1;
1523572890efSRavi Kumar 	pdata->axdomain = AXGBE_DMA_OS_AXDOMAIN;
1524572890efSRavi Kumar 	pdata->arcache = AXGBE_DMA_OS_ARCACHE;
1525572890efSRavi Kumar 	pdata->awcache = AXGBE_DMA_OS_AWCACHE;
1526572890efSRavi Kumar 
1527572890efSRavi Kumar 	/* Set the maximum channels and queues */
1528572890efSRavi Kumar 	reg = XP_IOREAD(pdata, XP_PROP_1);
1529572890efSRavi Kumar 	pdata->tx_max_channel_count = XP_GET_BITS(reg, XP_PROP_1, MAX_TX_DMA);
1530572890efSRavi Kumar 	pdata->rx_max_channel_count = XP_GET_BITS(reg, XP_PROP_1, MAX_RX_DMA);
1531572890efSRavi Kumar 	pdata->tx_max_q_count = XP_GET_BITS(reg, XP_PROP_1, MAX_TX_QUEUES);
1532572890efSRavi Kumar 	pdata->rx_max_q_count = XP_GET_BITS(reg, XP_PROP_1, MAX_RX_QUEUES);
1533572890efSRavi Kumar 
1534572890efSRavi Kumar 	/* Set the hardware channel and queue counts */
1535572890efSRavi Kumar 	axgbe_set_counts(pdata);
1536572890efSRavi Kumar 
1537572890efSRavi Kumar 	/* Set the maximum fifo amounts */
1538572890efSRavi Kumar 	reg = XP_IOREAD(pdata, XP_PROP_2);
1539572890efSRavi Kumar 	pdata->tx_max_fifo_size = XP_GET_BITS(reg, XP_PROP_2, TX_FIFO_SIZE);
1540572890efSRavi Kumar 	pdata->tx_max_fifo_size *= 16384;
1541572890efSRavi Kumar 	pdata->tx_max_fifo_size = RTE_MIN(pdata->tx_max_fifo_size,
1542572890efSRavi Kumar 					  pdata->vdata->tx_max_fifo_size);
1543572890efSRavi Kumar 	pdata->rx_max_fifo_size = XP_GET_BITS(reg, XP_PROP_2, RX_FIFO_SIZE);
1544572890efSRavi Kumar 	pdata->rx_max_fifo_size *= 16384;
1545572890efSRavi Kumar 	pdata->rx_max_fifo_size = RTE_MIN(pdata->rx_max_fifo_size,
1546572890efSRavi Kumar 					  pdata->vdata->rx_max_fifo_size);
1547572890efSRavi Kumar 	/* Issue software reset to DMA */
1548572890efSRavi Kumar 	ret = pdata->hw_if.exit(pdata);
1549572890efSRavi Kumar 	if (ret)
1550572890efSRavi Kumar 		PMD_DRV_LOG(ERR, "hw_if->exit EBUSY error\n");
1551572890efSRavi Kumar 
1552572890efSRavi Kumar 	/* Set default configuration data */
1553572890efSRavi Kumar 	axgbe_default_config(pdata);
1554572890efSRavi Kumar 
1555572890efSRavi Kumar 	/* Set default max values if not provided */
1556572890efSRavi Kumar 	if (!pdata->tx_max_fifo_size)
1557572890efSRavi Kumar 		pdata->tx_max_fifo_size = pdata->hw_feat.tx_fifo_size;
1558572890efSRavi Kumar 	if (!pdata->rx_max_fifo_size)
1559572890efSRavi Kumar 		pdata->rx_max_fifo_size = pdata->hw_feat.rx_fifo_size;
1560572890efSRavi Kumar 
15619e890103SRavi Kumar 	pdata->tx_desc_count = AXGBE_MAX_RING_DESC;
15629e890103SRavi Kumar 	pdata->rx_desc_count = AXGBE_MAX_RING_DESC;
1563572890efSRavi Kumar 	pthread_mutex_init(&pdata->xpcs_mutex, NULL);
1564572890efSRavi Kumar 	pthread_mutex_init(&pdata->i2c_mutex, NULL);
1565572890efSRavi Kumar 	pthread_mutex_init(&pdata->an_mutex, NULL);
1566572890efSRavi Kumar 	pthread_mutex_init(&pdata->phy_mutex, NULL);
1567572890efSRavi Kumar 
15684ac7516bSRavi Kumar 	ret = pdata->phy_if.phy_init(pdata);
15694ac7516bSRavi Kumar 	if (ret) {
15704ac7516bSRavi Kumar 		rte_free(eth_dev->data->mac_addrs);
1571e7f2fa88SDavid Marchand 		eth_dev->data->mac_addrs = NULL;
15724ac7516bSRavi Kumar 		return ret;
15734ac7516bSRavi Kumar 	}
15744ac7516bSRavi Kumar 
1575456ff159SRavi Kumar 	rte_intr_callback_register(&pci_dev->intr_handle,
1576456ff159SRavi Kumar 				   axgbe_dev_interrupt_handler,
1577456ff159SRavi Kumar 				   (void *)eth_dev);
15788691632fSRavi Kumar 	PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x",
15798691632fSRavi Kumar 		     eth_dev->data->port_id, pci_dev->id.vendor_id,
15808691632fSRavi Kumar 		     pci_dev->id.device_id);
15818691632fSRavi Kumar 
15828691632fSRavi Kumar 	return 0;
15838691632fSRavi Kumar }
15848691632fSRavi Kumar 
15858691632fSRavi Kumar static int
1586572890efSRavi Kumar eth_axgbe_dev_uninit(struct rte_eth_dev *eth_dev)
15878691632fSRavi Kumar {
1588456ff159SRavi Kumar 	struct rte_pci_device *pci_dev;
1589456ff159SRavi Kumar 
15908691632fSRavi Kumar 	PMD_INIT_FUNC_TRACE();
15918691632fSRavi Kumar 
1592572890efSRavi Kumar 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1593572890efSRavi Kumar 		return 0;
1594572890efSRavi Kumar 
1595456ff159SRavi Kumar 	pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
15969e890103SRavi Kumar 	eth_dev->dev_ops = NULL;
15978590b93dSRavi Kumar 	eth_dev->rx_pkt_burst = NULL;
15988590b93dSRavi Kumar 	eth_dev->tx_pkt_burst = NULL;
15999e890103SRavi Kumar 	axgbe_dev_clear_queues(eth_dev);
1600572890efSRavi Kumar 
1601456ff159SRavi Kumar 	/* disable uio intr before callback unregister */
1602456ff159SRavi Kumar 	rte_intr_disable(&pci_dev->intr_handle);
1603456ff159SRavi Kumar 	rte_intr_callback_unregister(&pci_dev->intr_handle,
1604456ff159SRavi Kumar 				     axgbe_dev_interrupt_handler,
1605456ff159SRavi Kumar 				     (void *)eth_dev);
1606456ff159SRavi Kumar 
16078691632fSRavi Kumar 	return 0;
16088691632fSRavi Kumar }
16098691632fSRavi Kumar 
16108691632fSRavi Kumar static int eth_axgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
16118691632fSRavi Kumar 	struct rte_pci_device *pci_dev)
16128691632fSRavi Kumar {
16138691632fSRavi Kumar 	return rte_eth_dev_pci_generic_probe(pci_dev,
16148691632fSRavi Kumar 		sizeof(struct axgbe_port), eth_axgbe_dev_init);
16158691632fSRavi Kumar }
16168691632fSRavi Kumar 
16178691632fSRavi Kumar static int eth_axgbe_pci_remove(struct rte_pci_device *pci_dev)
16188691632fSRavi Kumar {
16198691632fSRavi Kumar 	return rte_eth_dev_pci_generic_remove(pci_dev, eth_axgbe_dev_uninit);
16208691632fSRavi Kumar }
16218691632fSRavi Kumar 
16228691632fSRavi Kumar static struct rte_pci_driver rte_axgbe_pmd = {
16238691632fSRavi Kumar 	.id_table = pci_id_axgbe_map,
16248691632fSRavi Kumar 	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
16258691632fSRavi Kumar 	.probe = eth_axgbe_pci_probe,
16268691632fSRavi Kumar 	.remove = eth_axgbe_pci_remove,
16278691632fSRavi Kumar };
16288691632fSRavi Kumar 
16298691632fSRavi Kumar RTE_PMD_REGISTER_PCI(net_axgbe, rte_axgbe_pmd);
16308691632fSRavi Kumar RTE_PMD_REGISTER_PCI_TABLE(net_axgbe, pci_id_axgbe_map);
16318691632fSRavi Kumar RTE_PMD_REGISTER_KMOD_DEP(net_axgbe, "* igb_uio | uio_pci_generic | vfio-pci");
16328691632fSRavi Kumar 
1633f8e99896SThomas Monjalon RTE_INIT(axgbe_init_log)
16348691632fSRavi Kumar {
16358691632fSRavi Kumar 	axgbe_logtype_init = rte_log_register("pmd.net.axgbe.init");
16368691632fSRavi Kumar 	if (axgbe_logtype_init >= 0)
16378691632fSRavi Kumar 		rte_log_set_level(axgbe_logtype_init, RTE_LOG_NOTICE);
16388691632fSRavi Kumar 	axgbe_logtype_driver = rte_log_register("pmd.net.axgbe.driver");
16398691632fSRavi Kumar 	if (axgbe_logtype_driver >= 0)
16408691632fSRavi Kumar 		rte_log_set_level(axgbe_logtype_driver, RTE_LOG_NOTICE);
16418691632fSRavi Kumar }
1642