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" 11e0444948SSelwin Sebastian #include "rte_time.h" 128691632fSRavi Kumar 138691632fSRavi Kumar static int eth_axgbe_dev_init(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); 18b142387bSThomas Monjalon static int 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); 6376d7664dSChandu Babu N static int axgbe_dev_rss_reta_update(struct rte_eth_dev *dev, 6476d7664dSChandu Babu N struct rte_eth_rss_reta_entry64 *reta_conf, 6576d7664dSChandu Babu N uint16_t reta_size); 6676d7664dSChandu Babu N static int axgbe_dev_rss_reta_query(struct rte_eth_dev *dev, 6776d7664dSChandu Babu N struct rte_eth_rss_reta_entry64 *reta_conf, 6876d7664dSChandu Babu N uint16_t reta_size); 6976d7664dSChandu Babu N static int axgbe_dev_rss_hash_update(struct rte_eth_dev *dev, 7076d7664dSChandu Babu N struct rte_eth_rss_conf *rss_conf); 7176d7664dSChandu Babu N static int axgbe_dev_rss_hash_conf_get(struct rte_eth_dev *dev, 7276d7664dSChandu Babu N struct rte_eth_rss_conf *rss_conf); 73bdad90d1SIvan Ilchenko static int axgbe_dev_info_get(struct rte_eth_dev *dev, 749e890103SRavi Kumar struct rte_eth_dev_info *dev_info); 75cf97f33eSAmaranath Somalapuram static int axgbe_flow_ctrl_get(struct rte_eth_dev *dev, 76cf97f33eSAmaranath Somalapuram struct rte_eth_fc_conf *fc_conf); 77cf97f33eSAmaranath Somalapuram static int axgbe_flow_ctrl_set(struct rte_eth_dev *dev, 78cf97f33eSAmaranath Somalapuram struct rte_eth_fc_conf *fc_conf); 79e0543d4eSAmaranath Somalapuram static int axgbe_priority_flow_ctrl_set(struct rte_eth_dev *dev, 80e0543d4eSAmaranath Somalapuram struct rte_eth_pfc_conf *pfc_conf); 817aed95c9SAmaranath Somalapuram static void axgbe_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, 827aed95c9SAmaranath Somalapuram struct rte_eth_rxq_info *qinfo); 837aed95c9SAmaranath Somalapuram static void axgbe_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, 847aed95c9SAmaranath Somalapuram struct rte_eth_txq_info *qinfo); 85410cf087SAmaranath Somalapuram const uint32_t *axgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev); 86b58d8781SGirish Nandibasappa static int axgb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); 878691632fSRavi Kumar 88e0444948SSelwin Sebastian static int 89e0444948SSelwin Sebastian axgbe_timesync_enable(struct rte_eth_dev *dev); 90e0444948SSelwin Sebastian static int 91e0444948SSelwin Sebastian axgbe_timesync_disable(struct rte_eth_dev *dev); 92e0444948SSelwin Sebastian static int 93e0444948SSelwin Sebastian axgbe_timesync_read_rx_timestamp(struct rte_eth_dev *dev, 94e0444948SSelwin Sebastian struct timespec *timestamp, uint32_t flags); 95e0444948SSelwin Sebastian static int 96e0444948SSelwin Sebastian axgbe_timesync_read_tx_timestamp(struct rte_eth_dev *dev, 97e0444948SSelwin Sebastian struct timespec *timestamp); 98e0444948SSelwin Sebastian static int 99e0444948SSelwin Sebastian axgbe_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta); 100e0444948SSelwin Sebastian static int 101e0444948SSelwin Sebastian axgbe_timesync_read_time(struct rte_eth_dev *dev, 102e0444948SSelwin Sebastian struct timespec *timestamp); 103e0444948SSelwin Sebastian static int 104e0444948SSelwin Sebastian axgbe_timesync_write_time(struct rte_eth_dev *dev, 105e0444948SSelwin Sebastian const struct timespec *timestamp); 106e0444948SSelwin Sebastian static void 107e0444948SSelwin Sebastian axgbe_set_tstamp_time(struct axgbe_port *pdata, unsigned int sec, 108e0444948SSelwin Sebastian unsigned int nsec); 109e0444948SSelwin Sebastian static void 110e0444948SSelwin Sebastian axgbe_update_tstamp_addend(struct axgbe_port *pdata, 111e0444948SSelwin Sebastian unsigned int addend); 112e0444948SSelwin Sebastian 1139d1ef6b2SChandu Babu N struct axgbe_xstats { 1149d1ef6b2SChandu Babu N char name[RTE_ETH_XSTATS_NAME_SIZE]; 1159d1ef6b2SChandu Babu N int offset; 1169d1ef6b2SChandu Babu N }; 1179d1ef6b2SChandu Babu N 1189d1ef6b2SChandu Babu N #define AXGMAC_MMC_STAT(_string, _var) \ 1199d1ef6b2SChandu Babu N { _string, \ 1209d1ef6b2SChandu Babu N offsetof(struct axgbe_mmc_stats, _var), \ 1219d1ef6b2SChandu Babu N } 1229d1ef6b2SChandu Babu N 1239d1ef6b2SChandu Babu N static const struct axgbe_xstats axgbe_xstats_strings[] = { 1249d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("tx_bytes", txoctetcount_gb), 1259d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("tx_packets", txframecount_gb), 1269d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("tx_unicast_packets", txunicastframes_gb), 1279d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("tx_broadcast_packets", txbroadcastframes_gb), 1289d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("tx_multicast_packets", txmulticastframes_gb), 1299d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("tx_vlan_packets", txvlanframes_g), 1309d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("tx_64_byte_packets", tx64octets_gb), 1319d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("tx_65_to_127_byte_packets", tx65to127octets_gb), 1329d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("tx_128_to_255_byte_packets", tx128to255octets_gb), 1339d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("tx_256_to_511_byte_packets", tx256to511octets_gb), 1349d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("tx_512_to_1023_byte_packets", tx512to1023octets_gb), 1359d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("tx_1024_to_max_byte_packets", tx1024tomaxoctets_gb), 1369d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("tx_underflow_errors", txunderflowerror), 1379d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("tx_pause_frames", txpauseframes), 1389d1ef6b2SChandu Babu N 1399d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_bytes", rxoctetcount_gb), 1409d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_packets", rxframecount_gb), 1419d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_unicast_packets", rxunicastframes_g), 1429d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_broadcast_packets", rxbroadcastframes_g), 1439d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_multicast_packets", rxmulticastframes_g), 1449d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_vlan_packets", rxvlanframes_gb), 1459d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_64_byte_packets", rx64octets_gb), 1469d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_65_to_127_byte_packets", rx65to127octets_gb), 1479d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_128_to_255_byte_packets", rx128to255octets_gb), 1489d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_256_to_511_byte_packets", rx256to511octets_gb), 1499d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_512_to_1023_byte_packets", rx512to1023octets_gb), 1509d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_1024_to_max_byte_packets", rx1024tomaxoctets_gb), 1519d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_undersize_packets", rxundersize_g), 1529d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_oversize_packets", rxoversize_g), 1539d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_crc_errors", rxcrcerror), 1549d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_crc_errors_small_packets", rxrunterror), 1559d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_crc_errors_giant_packets", rxjabbererror), 1569d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_length_errors", rxlengtherror), 1579d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_out_of_range_errors", rxoutofrangetype), 1589d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_fifo_overflow_errors", rxfifooverflow), 1599d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_watchdog_errors", rxwatchdogerror), 1609d1ef6b2SChandu Babu N AXGMAC_MMC_STAT("rx_pause_frames", rxpauseframes), 1619d1ef6b2SChandu Babu N }; 1629d1ef6b2SChandu Babu N 1639d1ef6b2SChandu Babu N #define AXGBE_XSTATS_COUNT ARRAY_SIZE(axgbe_xstats_strings) 1649d1ef6b2SChandu Babu N 1658691632fSRavi Kumar /* The set of PCI devices this driver supports */ 1668691632fSRavi Kumar #define AMD_PCI_VENDOR_ID 0x1022 167991e0b1dSSelwin Sebastian #define AMD_PCI_RV_ROOT_COMPLEX_ID 0x15d0 1688691632fSRavi Kumar #define AMD_PCI_AXGBE_DEVICE_V2A 0x1458 1698691632fSRavi Kumar #define AMD_PCI_AXGBE_DEVICE_V2B 0x1459 1708691632fSRavi Kumar 1718691632fSRavi Kumar static const struct rte_pci_id pci_id_axgbe_map[] = { 1728691632fSRavi Kumar {RTE_PCI_DEVICE(AMD_PCI_VENDOR_ID, AMD_PCI_AXGBE_DEVICE_V2A)}, 1738691632fSRavi Kumar {RTE_PCI_DEVICE(AMD_PCI_VENDOR_ID, AMD_PCI_AXGBE_DEVICE_V2B)}, 1748691632fSRavi Kumar { .vendor_id = 0, }, 1758691632fSRavi Kumar }; 1768691632fSRavi Kumar 177572890efSRavi Kumar static struct axgbe_version_data axgbe_v2a = { 1784ac7516bSRavi Kumar .init_function_ptrs_phy_impl = axgbe_init_function_ptrs_phy_v2, 179572890efSRavi Kumar .xpcs_access = AXGBE_XPCS_ACCESS_V2, 180572890efSRavi Kumar .mmc_64bit = 1, 181572890efSRavi Kumar .tx_max_fifo_size = 229376, 182572890efSRavi Kumar .rx_max_fifo_size = 229376, 183572890efSRavi Kumar .tx_tstamp_workaround = 1, 184572890efSRavi Kumar .ecc_support = 1, 185572890efSRavi Kumar .i2c_support = 1, 18600072056SRavi Kumar .an_cdr_workaround = 1, 187572890efSRavi Kumar }; 188572890efSRavi Kumar 189572890efSRavi Kumar static struct axgbe_version_data axgbe_v2b = { 1904ac7516bSRavi Kumar .init_function_ptrs_phy_impl = axgbe_init_function_ptrs_phy_v2, 191572890efSRavi Kumar .xpcs_access = AXGBE_XPCS_ACCESS_V2, 192572890efSRavi Kumar .mmc_64bit = 1, 193572890efSRavi Kumar .tx_max_fifo_size = 65536, 194572890efSRavi Kumar .rx_max_fifo_size = 65536, 195572890efSRavi Kumar .tx_tstamp_workaround = 1, 196572890efSRavi Kumar .ecc_support = 1, 197572890efSRavi Kumar .i2c_support = 1, 19800072056SRavi Kumar .an_cdr_workaround = 1, 199572890efSRavi Kumar }; 200572890efSRavi Kumar 2019e890103SRavi Kumar static const struct rte_eth_desc_lim rx_desc_lim = { 2029e890103SRavi Kumar .nb_max = AXGBE_MAX_RING_DESC, 2039e890103SRavi Kumar .nb_min = AXGBE_MIN_RING_DESC, 2049e890103SRavi Kumar .nb_align = 8, 2059e890103SRavi Kumar }; 2069e890103SRavi Kumar 2079e890103SRavi Kumar static const struct rte_eth_desc_lim tx_desc_lim = { 2089e890103SRavi Kumar .nb_max = AXGBE_MAX_RING_DESC, 2099e890103SRavi Kumar .nb_min = AXGBE_MIN_RING_DESC, 2109e890103SRavi Kumar .nb_align = 8, 2119e890103SRavi Kumar }; 2129e890103SRavi Kumar 2139e890103SRavi Kumar static const struct eth_dev_ops axgbe_eth_dev_ops = { 2147c4158a5SRavi Kumar .dev_configure = axgbe_dev_configure, 2157c4158a5SRavi Kumar .dev_start = axgbe_dev_start, 2167c4158a5SRavi Kumar .dev_stop = axgbe_dev_stop, 2179e890103SRavi Kumar .dev_close = axgbe_dev_close, 218fa3e0440SRavi Kumar .promiscuous_enable = axgbe_dev_promiscuous_enable, 219fa3e0440SRavi Kumar .promiscuous_disable = axgbe_dev_promiscuous_disable, 220fa3e0440SRavi Kumar .allmulticast_enable = axgbe_dev_allmulticast_enable, 221fa3e0440SRavi Kumar .allmulticast_disable = axgbe_dev_allmulticast_disable, 22249a5e622SChandu Babu N .mac_addr_set = axgbe_dev_mac_addr_set, 22349a5e622SChandu Babu N .mac_addr_add = axgbe_dev_mac_addr_add, 22449a5e622SChandu Babu N .mac_addr_remove = axgbe_dev_mac_addr_remove, 22549a5e622SChandu Babu N .set_mc_addr_list = axgbe_dev_set_mc_addr_list, 226e01d9b2eSChandu Babu N .uc_hash_table_set = axgbe_dev_uc_hash_table_set, 227e01d9b2eSChandu Babu N .uc_all_hash_table_set = axgbe_dev_uc_all_hash_table_set, 22844d45ffeSRavi Kumar .link_update = axgbe_dev_link_update, 229df4867cdSChandu Babu N .get_reg = axgbe_dev_get_regs, 2303e730511SRavi Kumar .stats_get = axgbe_dev_stats_get, 2313e730511SRavi Kumar .stats_reset = axgbe_dev_stats_reset, 2329d1ef6b2SChandu Babu N .xstats_get = axgbe_dev_xstats_get, 2339d1ef6b2SChandu Babu N .xstats_reset = axgbe_dev_xstats_reset, 2349d1ef6b2SChandu Babu N .xstats_get_names = axgbe_dev_xstats_get_names, 2359d1ef6b2SChandu Babu N .xstats_get_names_by_id = axgbe_dev_xstats_get_names_by_id, 2369d1ef6b2SChandu Babu N .xstats_get_by_id = axgbe_dev_xstats_get_by_id, 23776d7664dSChandu Babu N .reta_update = axgbe_dev_rss_reta_update, 23876d7664dSChandu Babu N .reta_query = axgbe_dev_rss_reta_query, 23976d7664dSChandu Babu N .rss_hash_update = axgbe_dev_rss_hash_update, 24076d7664dSChandu Babu N .rss_hash_conf_get = axgbe_dev_rss_hash_conf_get, 2419e890103SRavi Kumar .dev_infos_get = axgbe_dev_info_get, 2429e890103SRavi Kumar .rx_queue_setup = axgbe_dev_rx_queue_setup, 2439e890103SRavi Kumar .rx_queue_release = axgbe_dev_rx_queue_release, 2449e890103SRavi Kumar .tx_queue_setup = axgbe_dev_tx_queue_setup, 2459e890103SRavi Kumar .tx_queue_release = axgbe_dev_tx_queue_release, 246cf97f33eSAmaranath Somalapuram .flow_ctrl_get = axgbe_flow_ctrl_get, 247cf97f33eSAmaranath Somalapuram .flow_ctrl_set = axgbe_flow_ctrl_set, 248e0543d4eSAmaranath Somalapuram .priority_flow_ctrl_set = axgbe_priority_flow_ctrl_set, 2497aed95c9SAmaranath Somalapuram .rxq_info_get = axgbe_rxq_info_get, 2507aed95c9SAmaranath Somalapuram .txq_info_get = axgbe_txq_info_get, 251410cf087SAmaranath Somalapuram .dev_supported_ptypes_get = axgbe_dev_supported_ptypes_get, 252b58d8781SGirish Nandibasappa .mtu_set = axgb_mtu_set, 253e0444948SSelwin Sebastian .timesync_enable = axgbe_timesync_enable, 254e0444948SSelwin Sebastian .timesync_disable = axgbe_timesync_disable, 255e0444948SSelwin Sebastian .timesync_read_rx_timestamp = axgbe_timesync_read_rx_timestamp, 256e0444948SSelwin Sebastian .timesync_read_tx_timestamp = axgbe_timesync_read_tx_timestamp, 257e0444948SSelwin Sebastian .timesync_adjust_time = axgbe_timesync_adjust_time, 258e0444948SSelwin Sebastian .timesync_read_time = axgbe_timesync_read_time, 259e0444948SSelwin Sebastian .timesync_write_time = axgbe_timesync_write_time, 2609e890103SRavi Kumar }; 2619e890103SRavi Kumar 2627c4158a5SRavi Kumar static int axgbe_phy_reset(struct axgbe_port *pdata) 2637c4158a5SRavi Kumar { 2647c4158a5SRavi Kumar pdata->phy_link = -1; 2657c4158a5SRavi Kumar pdata->phy_speed = SPEED_UNKNOWN; 2667c4158a5SRavi Kumar return pdata->phy_if.phy_reset(pdata); 2677c4158a5SRavi Kumar } 2687c4158a5SRavi Kumar 269456ff159SRavi Kumar /* 270456ff159SRavi Kumar * Interrupt handler triggered by NIC for handling 271456ff159SRavi Kumar * specific interrupt. 272456ff159SRavi Kumar * 273456ff159SRavi Kumar * @param handle 274456ff159SRavi Kumar * Pointer to interrupt handle. 275456ff159SRavi Kumar * @param param 276456ff159SRavi Kumar * The address of parameter (struct rte_eth_dev *) regsitered before. 277456ff159SRavi Kumar * 278456ff159SRavi Kumar * @return 279456ff159SRavi Kumar * void 280456ff159SRavi Kumar */ 281456ff159SRavi Kumar static void 282456ff159SRavi Kumar axgbe_dev_interrupt_handler(void *param) 283456ff159SRavi Kumar { 284456ff159SRavi Kumar struct rte_eth_dev *dev = (struct rte_eth_dev *)param; 285456ff159SRavi Kumar struct axgbe_port *pdata = dev->data->dev_private; 2868590b93dSRavi Kumar unsigned int dma_isr, dma_ch_isr; 287456ff159SRavi Kumar 288456ff159SRavi Kumar pdata->phy_if.an_isr(pdata); 2898590b93dSRavi Kumar /*DMA related interrupts*/ 2908590b93dSRavi Kumar dma_isr = AXGMAC_IOREAD(pdata, DMA_ISR); 2914216cdc0SChandu Babu N PMD_DRV_LOG(DEBUG, "DMA_ISR=%#010x\n", dma_isr); 2928590b93dSRavi Kumar if (dma_isr) { 2938590b93dSRavi Kumar if (dma_isr & 1) { 2948590b93dSRavi Kumar dma_ch_isr = 2958590b93dSRavi Kumar AXGMAC_DMA_IOREAD((struct axgbe_rx_queue *) 2968590b93dSRavi Kumar pdata->rx_queues[0], 2978590b93dSRavi Kumar DMA_CH_SR); 2984216cdc0SChandu Babu N PMD_DRV_LOG(DEBUG, "DMA_CH0_ISR=%#010x\n", dma_ch_isr); 2998590b93dSRavi Kumar AXGMAC_DMA_IOWRITE((struct axgbe_rx_queue *) 3008590b93dSRavi Kumar pdata->rx_queues[0], 3018590b93dSRavi Kumar DMA_CH_SR, dma_ch_isr); 3028590b93dSRavi Kumar } 3038590b93dSRavi Kumar } 3046bee9d5fSNithin Dabilpuram /* Unmask interrupts since disabled after generation */ 3056bee9d5fSNithin Dabilpuram rte_intr_ack(&pdata->pci_dev->intr_handle); 306456ff159SRavi Kumar } 307456ff159SRavi Kumar 3087c4158a5SRavi Kumar /* 3097c4158a5SRavi Kumar * Configure device link speed and setup link. 3107c4158a5SRavi Kumar * It returns 0 on success. 3117c4158a5SRavi Kumar */ 3127c4158a5SRavi Kumar static int 3137c4158a5SRavi Kumar axgbe_dev_configure(struct rte_eth_dev *dev) 3147c4158a5SRavi Kumar { 3157c4158a5SRavi Kumar struct axgbe_port *pdata = dev->data->dev_private; 3167c4158a5SRavi Kumar /* Checksum offload to hardware */ 3177c4158a5SRavi Kumar pdata->rx_csum_enable = dev->data->dev_conf.rxmode.offloads & 3187c4158a5SRavi Kumar DEV_RX_OFFLOAD_CHECKSUM; 3197c4158a5SRavi Kumar return 0; 3207c4158a5SRavi Kumar } 3217c4158a5SRavi Kumar 3227c4158a5SRavi Kumar static int 3237c4158a5SRavi Kumar axgbe_dev_rx_mq_config(struct rte_eth_dev *dev) 3247c4158a5SRavi Kumar { 3250bc212a8SStephen Hemminger struct axgbe_port *pdata = dev->data->dev_private; 3267c4158a5SRavi Kumar 3277c4158a5SRavi Kumar if (dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_RSS) 3287c4158a5SRavi Kumar pdata->rss_enable = 1; 3297c4158a5SRavi Kumar else if (dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_NONE) 3307c4158a5SRavi Kumar pdata->rss_enable = 0; 3317c4158a5SRavi Kumar else 3327c4158a5SRavi Kumar return -1; 3337c4158a5SRavi Kumar return 0; 3347c4158a5SRavi Kumar } 3357c4158a5SRavi Kumar 3367c4158a5SRavi Kumar static int 3377c4158a5SRavi Kumar axgbe_dev_start(struct rte_eth_dev *dev) 3387c4158a5SRavi Kumar { 3390bc212a8SStephen Hemminger struct axgbe_port *pdata = dev->data->dev_private; 3407c4158a5SRavi Kumar int ret; 341965b3127SSelwin Sebastian struct rte_eth_dev_data *dev_data = dev->data; 342965b3127SSelwin Sebastian uint16_t max_pkt_len = dev_data->dev_conf.rxmode.max_rx_pkt_len; 343965b3127SSelwin Sebastian 344965b3127SSelwin Sebastian dev->dev_ops = &axgbe_eth_dev_ops; 3457c4158a5SRavi Kumar 3460bc212a8SStephen Hemminger PMD_INIT_FUNC_TRACE(); 3470bc212a8SStephen Hemminger 3487c4158a5SRavi Kumar /* Multiqueue RSS */ 3497c4158a5SRavi Kumar ret = axgbe_dev_rx_mq_config(dev); 3507c4158a5SRavi Kumar if (ret) { 3517c4158a5SRavi Kumar PMD_DRV_LOG(ERR, "Unable to config RX MQ\n"); 3527c4158a5SRavi Kumar return ret; 3537c4158a5SRavi Kumar } 3547c4158a5SRavi Kumar ret = axgbe_phy_reset(pdata); 3557c4158a5SRavi Kumar if (ret) { 3567c4158a5SRavi Kumar PMD_DRV_LOG(ERR, "phy reset failed\n"); 3577c4158a5SRavi Kumar return ret; 3587c4158a5SRavi Kumar } 3597c4158a5SRavi Kumar ret = pdata->hw_if.init(pdata); 3607c4158a5SRavi Kumar if (ret) { 3617c4158a5SRavi Kumar PMD_DRV_LOG(ERR, "dev_init failed\n"); 3627c4158a5SRavi Kumar return ret; 3637c4158a5SRavi Kumar } 3647c4158a5SRavi Kumar 3657c4158a5SRavi Kumar /* enable uio/vfio intr/eventfd mapping */ 3667c4158a5SRavi Kumar rte_intr_enable(&pdata->pci_dev->intr_handle); 3677c4158a5SRavi Kumar 3687c4158a5SRavi Kumar /* phy start*/ 3697c4158a5SRavi Kumar pdata->phy_if.phy_start(pdata); 3708590b93dSRavi Kumar axgbe_dev_enable_tx(dev); 3718590b93dSRavi Kumar axgbe_dev_enable_rx(dev); 3727c4158a5SRavi Kumar 3734693ae4aSJoyce Kong rte_bit_relaxed_clear32(AXGBE_STOPPED, &pdata->dev_state); 3744693ae4aSJoyce Kong rte_bit_relaxed_clear32(AXGBE_DOWN, &pdata->dev_state); 375965b3127SSelwin Sebastian if ((dev_data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_SCATTER) || 376965b3127SSelwin Sebastian max_pkt_len > pdata->rx_buf_size) 377965b3127SSelwin Sebastian dev_data->scattered_rx = 1; 378965b3127SSelwin Sebastian 379965b3127SSelwin Sebastian /* Scatter Rx handling */ 380965b3127SSelwin Sebastian if (dev_data->scattered_rx) 381965b3127SSelwin Sebastian dev->rx_pkt_burst = ð_axgbe_recv_scattered_pkts; 382965b3127SSelwin Sebastian else 383965b3127SSelwin Sebastian dev->rx_pkt_burst = &axgbe_recv_pkts; 384965b3127SSelwin Sebastian 3857c4158a5SRavi Kumar return 0; 3867c4158a5SRavi Kumar } 3877c4158a5SRavi Kumar 3887c4158a5SRavi Kumar /* Stop device: disable rx and tx functions to allow for reconfiguring. */ 3897c4158a5SRavi Kumar static void 3907c4158a5SRavi Kumar axgbe_dev_stop(struct rte_eth_dev *dev) 3917c4158a5SRavi Kumar { 3927c4158a5SRavi Kumar struct axgbe_port *pdata = dev->data->dev_private; 3937c4158a5SRavi Kumar 3940bc212a8SStephen Hemminger PMD_INIT_FUNC_TRACE(); 3950bc212a8SStephen Hemminger 3967c4158a5SRavi Kumar rte_intr_disable(&pdata->pci_dev->intr_handle); 3977c4158a5SRavi Kumar 3984693ae4aSJoyce Kong if (rte_bit_relaxed_get32(AXGBE_STOPPED, &pdata->dev_state)) 3997c4158a5SRavi Kumar return; 4007c4158a5SRavi Kumar 4014693ae4aSJoyce Kong rte_bit_relaxed_set32(AXGBE_STOPPED, &pdata->dev_state); 4028590b93dSRavi Kumar axgbe_dev_disable_tx(dev); 4038590b93dSRavi Kumar axgbe_dev_disable_rx(dev); 4047c4158a5SRavi Kumar 4057c4158a5SRavi Kumar pdata->phy_if.phy_stop(pdata); 4067c4158a5SRavi Kumar pdata->hw_if.exit(pdata); 4077c4158a5SRavi Kumar memset(&dev->data->dev_link, 0, sizeof(struct rte_eth_link)); 4084693ae4aSJoyce Kong rte_bit_relaxed_set32(AXGBE_DOWN, &pdata->dev_state); 4097c4158a5SRavi Kumar } 4107c4158a5SRavi Kumar 4119039c812SAndrew Rybchenko static int 412fa3e0440SRavi Kumar axgbe_dev_promiscuous_enable(struct rte_eth_dev *dev) 413fa3e0440SRavi Kumar { 414fa3e0440SRavi Kumar struct axgbe_port *pdata = dev->data->dev_private; 415fa3e0440SRavi Kumar 4160bc212a8SStephen Hemminger PMD_INIT_FUNC_TRACE(); 4170bc212a8SStephen Hemminger 418fa3e0440SRavi Kumar AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PR, 1); 4199039c812SAndrew Rybchenko 4209039c812SAndrew Rybchenko return 0; 421fa3e0440SRavi Kumar } 422fa3e0440SRavi Kumar 4239039c812SAndrew Rybchenko static int 424fa3e0440SRavi Kumar axgbe_dev_promiscuous_disable(struct rte_eth_dev *dev) 425fa3e0440SRavi Kumar { 426fa3e0440SRavi Kumar struct axgbe_port *pdata = dev->data->dev_private; 427fa3e0440SRavi Kumar 4280bc212a8SStephen Hemminger PMD_INIT_FUNC_TRACE(); 4290bc212a8SStephen Hemminger 430fa3e0440SRavi Kumar AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PR, 0); 4319039c812SAndrew Rybchenko 4329039c812SAndrew Rybchenko return 0; 433fa3e0440SRavi Kumar } 434fa3e0440SRavi Kumar 435ca041cd4SIvan Ilchenko static int 436fa3e0440SRavi Kumar axgbe_dev_allmulticast_enable(struct rte_eth_dev *dev) 437fa3e0440SRavi Kumar { 438fa3e0440SRavi Kumar struct axgbe_port *pdata = dev->data->dev_private; 439fa3e0440SRavi Kumar 4400bc212a8SStephen Hemminger PMD_INIT_FUNC_TRACE(); 4410bc212a8SStephen Hemminger 442fa3e0440SRavi Kumar if (AXGMAC_IOREAD_BITS(pdata, MAC_PFR, PM)) 443ca041cd4SIvan Ilchenko return 0; 444fa3e0440SRavi Kumar AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PM, 1); 445ca041cd4SIvan Ilchenko 446ca041cd4SIvan Ilchenko return 0; 447fa3e0440SRavi Kumar } 448fa3e0440SRavi Kumar 449ca041cd4SIvan Ilchenko static int 450fa3e0440SRavi Kumar axgbe_dev_allmulticast_disable(struct rte_eth_dev *dev) 451fa3e0440SRavi Kumar { 452fa3e0440SRavi Kumar struct axgbe_port *pdata = dev->data->dev_private; 453fa3e0440SRavi Kumar 4540bc212a8SStephen Hemminger PMD_INIT_FUNC_TRACE(); 4550bc212a8SStephen Hemminger 456fa3e0440SRavi Kumar if (!AXGMAC_IOREAD_BITS(pdata, MAC_PFR, PM)) 457ca041cd4SIvan Ilchenko return 0; 458fa3e0440SRavi Kumar AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, PM, 0); 459ca041cd4SIvan Ilchenko 460ca041cd4SIvan Ilchenko return 0; 461fa3e0440SRavi Kumar } 462fa3e0440SRavi Kumar 46349a5e622SChandu Babu N static int 46449a5e622SChandu Babu N axgbe_dev_mac_addr_set(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr) 46549a5e622SChandu Babu N { 46649a5e622SChandu Babu N struct axgbe_port *pdata = dev->data->dev_private; 46749a5e622SChandu Babu N 46849a5e622SChandu Babu N /* Set Default MAC Addr */ 46949a5e622SChandu Babu N axgbe_set_mac_addn_addr(pdata, (u8 *)mac_addr, 0); 47049a5e622SChandu Babu N 47149a5e622SChandu Babu N return 0; 47249a5e622SChandu Babu N } 47349a5e622SChandu Babu N 47449a5e622SChandu Babu N static int 47549a5e622SChandu Babu N axgbe_dev_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, 47649a5e622SChandu Babu N uint32_t index, uint32_t pool __rte_unused) 47749a5e622SChandu Babu N { 47849a5e622SChandu Babu N struct axgbe_port *pdata = dev->data->dev_private; 47949a5e622SChandu Babu N struct axgbe_hw_features *hw_feat = &pdata->hw_feat; 48049a5e622SChandu Babu N 48149a5e622SChandu Babu N if (index > hw_feat->addn_mac) { 48249a5e622SChandu Babu N PMD_DRV_LOG(ERR, "Invalid Index %d\n", index); 48349a5e622SChandu Babu N return -EINVAL; 48449a5e622SChandu Babu N } 48549a5e622SChandu Babu N axgbe_set_mac_addn_addr(pdata, (u8 *)mac_addr, index); 48649a5e622SChandu Babu N return 0; 48749a5e622SChandu Babu N } 48849a5e622SChandu Babu N 48976d7664dSChandu Babu N static int 49076d7664dSChandu Babu N axgbe_dev_rss_reta_update(struct rte_eth_dev *dev, 49176d7664dSChandu Babu N struct rte_eth_rss_reta_entry64 *reta_conf, 49276d7664dSChandu Babu N uint16_t reta_size) 49376d7664dSChandu Babu N { 49476d7664dSChandu Babu N struct axgbe_port *pdata = dev->data->dev_private; 49576d7664dSChandu Babu N unsigned int i, idx, shift; 49676d7664dSChandu Babu N int ret; 49776d7664dSChandu Babu N 49876d7664dSChandu Babu N if (!pdata->rss_enable) { 49976d7664dSChandu Babu N PMD_DRV_LOG(ERR, "RSS not enabled\n"); 50076d7664dSChandu Babu N return -ENOTSUP; 50176d7664dSChandu Babu N } 50276d7664dSChandu Babu N 50376d7664dSChandu Babu N if (reta_size == 0 || reta_size > AXGBE_RSS_MAX_TABLE_SIZE) { 50476d7664dSChandu Babu N PMD_DRV_LOG(ERR, "reta_size %d is not supported\n", reta_size); 50576d7664dSChandu Babu N return -EINVAL; 50676d7664dSChandu Babu N } 50776d7664dSChandu Babu N 50876d7664dSChandu Babu N for (i = 0; i < reta_size; i++) { 50976d7664dSChandu Babu N idx = i / RTE_RETA_GROUP_SIZE; 51076d7664dSChandu Babu N shift = i % RTE_RETA_GROUP_SIZE; 51176d7664dSChandu Babu N if ((reta_conf[idx].mask & (1ULL << shift)) == 0) 51276d7664dSChandu Babu N continue; 51376d7664dSChandu Babu N pdata->rss_table[i] = reta_conf[idx].reta[shift]; 51476d7664dSChandu Babu N } 51576d7664dSChandu Babu N 51676d7664dSChandu Babu N /* Program the lookup table */ 51776d7664dSChandu Babu N ret = axgbe_write_rss_lookup_table(pdata); 51876d7664dSChandu Babu N return ret; 51976d7664dSChandu Babu N } 52076d7664dSChandu Babu N 52176d7664dSChandu Babu N static int 52276d7664dSChandu Babu N axgbe_dev_rss_reta_query(struct rte_eth_dev *dev, 52376d7664dSChandu Babu N struct rte_eth_rss_reta_entry64 *reta_conf, 52476d7664dSChandu Babu N uint16_t reta_size) 52576d7664dSChandu Babu N { 52676d7664dSChandu Babu N struct axgbe_port *pdata = dev->data->dev_private; 52776d7664dSChandu Babu N unsigned int i, idx, shift; 52876d7664dSChandu Babu N 52976d7664dSChandu Babu N if (!pdata->rss_enable) { 53076d7664dSChandu Babu N PMD_DRV_LOG(ERR, "RSS not enabled\n"); 53176d7664dSChandu Babu N return -ENOTSUP; 53276d7664dSChandu Babu N } 53376d7664dSChandu Babu N 53476d7664dSChandu Babu N if (reta_size == 0 || reta_size > AXGBE_RSS_MAX_TABLE_SIZE) { 53576d7664dSChandu Babu N PMD_DRV_LOG(ERR, "reta_size %d is not supported\n", reta_size); 53676d7664dSChandu Babu N return -EINVAL; 53776d7664dSChandu Babu N } 53876d7664dSChandu Babu N 53976d7664dSChandu Babu N for (i = 0; i < reta_size; i++) { 54076d7664dSChandu Babu N idx = i / RTE_RETA_GROUP_SIZE; 54176d7664dSChandu Babu N shift = i % RTE_RETA_GROUP_SIZE; 54276d7664dSChandu Babu N if ((reta_conf[idx].mask & (1ULL << shift)) == 0) 54376d7664dSChandu Babu N continue; 54476d7664dSChandu Babu N reta_conf[idx].reta[shift] = pdata->rss_table[i]; 54576d7664dSChandu Babu N } 54676d7664dSChandu Babu N return 0; 54776d7664dSChandu Babu N } 54876d7664dSChandu Babu N 54976d7664dSChandu Babu N static int 55076d7664dSChandu Babu N axgbe_dev_rss_hash_update(struct rte_eth_dev *dev, 55176d7664dSChandu Babu N struct rte_eth_rss_conf *rss_conf) 55276d7664dSChandu Babu N { 55376d7664dSChandu Babu N struct axgbe_port *pdata = dev->data->dev_private; 55476d7664dSChandu Babu N int ret; 55576d7664dSChandu Babu N 55676d7664dSChandu Babu N if (!pdata->rss_enable) { 55776d7664dSChandu Babu N PMD_DRV_LOG(ERR, "RSS not enabled\n"); 55876d7664dSChandu Babu N return -ENOTSUP; 55976d7664dSChandu Babu N } 56076d7664dSChandu Babu N 56176d7664dSChandu Babu N if (rss_conf == NULL) { 56276d7664dSChandu Babu N PMD_DRV_LOG(ERR, "rss_conf value isn't valid\n"); 56376d7664dSChandu Babu N return -EINVAL; 56476d7664dSChandu Babu N } 56576d7664dSChandu Babu N 56676d7664dSChandu Babu N if (rss_conf->rss_key != NULL && 56776d7664dSChandu Babu N rss_conf->rss_key_len == AXGBE_RSS_HASH_KEY_SIZE) { 56876d7664dSChandu Babu N rte_memcpy(pdata->rss_key, rss_conf->rss_key, 56976d7664dSChandu Babu N AXGBE_RSS_HASH_KEY_SIZE); 57076d7664dSChandu Babu N /* Program the hash key */ 57176d7664dSChandu Babu N ret = axgbe_write_rss_hash_key(pdata); 57276d7664dSChandu Babu N if (ret != 0) 57376d7664dSChandu Babu N return ret; 57476d7664dSChandu Babu N } 57576d7664dSChandu Babu N 57676d7664dSChandu Babu N pdata->rss_hf = rss_conf->rss_hf & AXGBE_RSS_OFFLOAD; 57776d7664dSChandu Babu N 57876d7664dSChandu Babu N if (pdata->rss_hf & (ETH_RSS_IPV4 | ETH_RSS_IPV6)) 57976d7664dSChandu Babu N AXGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, IP2TE, 1); 58076d7664dSChandu Babu N if (pdata->rss_hf & 58176d7664dSChandu Babu N (ETH_RSS_NONFRAG_IPV4_TCP | ETH_RSS_NONFRAG_IPV6_TCP)) 58276d7664dSChandu Babu N AXGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, TCP4TE, 1); 58376d7664dSChandu Babu N if (pdata->rss_hf & 58476d7664dSChandu Babu N (ETH_RSS_NONFRAG_IPV4_UDP | ETH_RSS_NONFRAG_IPV6_UDP)) 58576d7664dSChandu Babu N AXGMAC_SET_BITS(pdata->rss_options, MAC_RSSCR, UDP4TE, 1); 58676d7664dSChandu Babu N 58776d7664dSChandu Babu N /* Set the RSS options */ 58876d7664dSChandu Babu N AXGMAC_IOWRITE(pdata, MAC_RSSCR, pdata->rss_options); 58976d7664dSChandu Babu N 59076d7664dSChandu Babu N return 0; 59176d7664dSChandu Babu N } 59276d7664dSChandu Babu N 59376d7664dSChandu Babu N static int 59476d7664dSChandu Babu N axgbe_dev_rss_hash_conf_get(struct rte_eth_dev *dev, 59576d7664dSChandu Babu N struct rte_eth_rss_conf *rss_conf) 59676d7664dSChandu Babu N { 59776d7664dSChandu Babu N struct axgbe_port *pdata = dev->data->dev_private; 59876d7664dSChandu Babu N 59976d7664dSChandu Babu N if (!pdata->rss_enable) { 60076d7664dSChandu Babu N PMD_DRV_LOG(ERR, "RSS not enabled\n"); 60176d7664dSChandu Babu N return -ENOTSUP; 60276d7664dSChandu Babu N } 60376d7664dSChandu Babu N 60476d7664dSChandu Babu N if (rss_conf == NULL) { 60576d7664dSChandu Babu N PMD_DRV_LOG(ERR, "rss_conf value isn't valid\n"); 60676d7664dSChandu Babu N return -EINVAL; 60776d7664dSChandu Babu N } 60876d7664dSChandu Babu N 60976d7664dSChandu Babu N if (rss_conf->rss_key != NULL && 61076d7664dSChandu Babu N rss_conf->rss_key_len >= AXGBE_RSS_HASH_KEY_SIZE) { 61176d7664dSChandu Babu N rte_memcpy(rss_conf->rss_key, pdata->rss_key, 61276d7664dSChandu Babu N AXGBE_RSS_HASH_KEY_SIZE); 61376d7664dSChandu Babu N } 61476d7664dSChandu Babu N rss_conf->rss_key_len = AXGBE_RSS_HASH_KEY_SIZE; 61576d7664dSChandu Babu N rss_conf->rss_hf = pdata->rss_hf; 61676d7664dSChandu Babu N return 0; 61776d7664dSChandu Babu N } 61876d7664dSChandu Babu N 61949a5e622SChandu Babu N static void 62049a5e622SChandu Babu N axgbe_dev_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index) 62149a5e622SChandu Babu N { 62249a5e622SChandu Babu N struct axgbe_port *pdata = dev->data->dev_private; 62349a5e622SChandu Babu N struct axgbe_hw_features *hw_feat = &pdata->hw_feat; 62449a5e622SChandu Babu N 62549a5e622SChandu Babu N if (index > hw_feat->addn_mac) { 62649a5e622SChandu Babu N PMD_DRV_LOG(ERR, "Invalid Index %d\n", index); 62749a5e622SChandu Babu N return; 62849a5e622SChandu Babu N } 62949a5e622SChandu Babu N axgbe_set_mac_addn_addr(pdata, NULL, index); 63049a5e622SChandu Babu N } 63149a5e622SChandu Babu N 63249a5e622SChandu Babu N static int 63349a5e622SChandu Babu N axgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev, 63449a5e622SChandu Babu N struct rte_ether_addr *mc_addr_set, 63549a5e622SChandu Babu N uint32_t nb_mc_addr) 63649a5e622SChandu Babu N { 63749a5e622SChandu Babu N struct axgbe_port *pdata = dev->data->dev_private; 63849a5e622SChandu Babu N struct axgbe_hw_features *hw_feat = &pdata->hw_feat; 63949a5e622SChandu Babu N uint32_t index = 1; /* 0 is always default mac */ 64049a5e622SChandu Babu N uint32_t i; 64149a5e622SChandu Babu N 64249a5e622SChandu Babu N if (nb_mc_addr > hw_feat->addn_mac) { 64349a5e622SChandu Babu N PMD_DRV_LOG(ERR, "Invalid Index %d\n", nb_mc_addr); 64449a5e622SChandu Babu N return -EINVAL; 64549a5e622SChandu Babu N } 64649a5e622SChandu Babu N 64749a5e622SChandu Babu N /* clear unicast addresses */ 64849a5e622SChandu Babu N for (i = 1; i < hw_feat->addn_mac; i++) { 64949a5e622SChandu Babu N if (rte_is_zero_ether_addr(&dev->data->mac_addrs[i])) 65049a5e622SChandu Babu N continue; 65149a5e622SChandu Babu N memset(&dev->data->mac_addrs[i], 0, 65249a5e622SChandu Babu N sizeof(struct rte_ether_addr)); 65349a5e622SChandu Babu N } 65449a5e622SChandu Babu N 65549a5e622SChandu Babu N while (nb_mc_addr--) 65649a5e622SChandu Babu N axgbe_set_mac_addn_addr(pdata, (u8 *)mc_addr_set++, index++); 65749a5e622SChandu Babu N 65849a5e622SChandu Babu N return 0; 65949a5e622SChandu Babu N } 66049a5e622SChandu Babu N 661e01d9b2eSChandu Babu N static int 662e01d9b2eSChandu Babu N axgbe_dev_uc_hash_table_set(struct rte_eth_dev *dev, 663e01d9b2eSChandu Babu N struct rte_ether_addr *mac_addr, uint8_t add) 664e01d9b2eSChandu Babu N { 665e01d9b2eSChandu Babu N struct axgbe_port *pdata = dev->data->dev_private; 666e01d9b2eSChandu Babu N struct axgbe_hw_features *hw_feat = &pdata->hw_feat; 667e01d9b2eSChandu Babu N 668e01d9b2eSChandu Babu N if (!hw_feat->hash_table_size) { 669e01d9b2eSChandu Babu N PMD_DRV_LOG(ERR, "MAC Hash Table not supported\n"); 670e01d9b2eSChandu Babu N return -ENOTSUP; 671e01d9b2eSChandu Babu N } 672e01d9b2eSChandu Babu N 673e01d9b2eSChandu Babu N axgbe_set_mac_hash_table(pdata, (u8 *)mac_addr, add); 674e01d9b2eSChandu Babu N 675e01d9b2eSChandu Babu N if (pdata->uc_hash_mac_addr > 0) { 676e01d9b2eSChandu Babu N AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1); 677e01d9b2eSChandu Babu N AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1); 678e01d9b2eSChandu Babu N } else { 679e01d9b2eSChandu Babu N AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 0); 680e01d9b2eSChandu Babu N AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0); 681e01d9b2eSChandu Babu N } 682e01d9b2eSChandu Babu N return 0; 683e01d9b2eSChandu Babu N } 684e01d9b2eSChandu Babu N 685e01d9b2eSChandu Babu N static int 686e01d9b2eSChandu Babu N axgbe_dev_uc_all_hash_table_set(struct rte_eth_dev *dev, uint8_t add) 687e01d9b2eSChandu Babu N { 688e01d9b2eSChandu Babu N struct axgbe_port *pdata = dev->data->dev_private; 689e01d9b2eSChandu Babu N struct axgbe_hw_features *hw_feat = &pdata->hw_feat; 690e01d9b2eSChandu Babu N uint32_t index; 691e01d9b2eSChandu Babu N 692e01d9b2eSChandu Babu N if (!hw_feat->hash_table_size) { 693e01d9b2eSChandu Babu N PMD_DRV_LOG(ERR, "MAC Hash Table not supported\n"); 694e01d9b2eSChandu Babu N return -ENOTSUP; 695e01d9b2eSChandu Babu N } 696e01d9b2eSChandu Babu N 697e01d9b2eSChandu Babu N for (index = 0; index < pdata->hash_table_count; index++) { 698e01d9b2eSChandu Babu N if (add) 699e01d9b2eSChandu Babu N pdata->uc_hash_table[index] = ~0; 700e01d9b2eSChandu Babu N else 701e01d9b2eSChandu Babu N pdata->uc_hash_table[index] = 0; 702e01d9b2eSChandu Babu N 703e01d9b2eSChandu Babu N PMD_DRV_LOG(DEBUG, "%s MAC hash table at Index %#x\n", 704e01d9b2eSChandu Babu N add ? "set" : "clear", index); 705e01d9b2eSChandu Babu N 706e01d9b2eSChandu Babu N AXGMAC_IOWRITE(pdata, MAC_HTR(index), 707e01d9b2eSChandu Babu N pdata->uc_hash_table[index]); 708e01d9b2eSChandu Babu N } 709e01d9b2eSChandu Babu N 710e01d9b2eSChandu Babu N if (add) { 711e01d9b2eSChandu Babu N AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1); 712e01d9b2eSChandu Babu N AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1); 713e01d9b2eSChandu Babu N } else { 714e01d9b2eSChandu Babu N AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 0); 715e01d9b2eSChandu Babu N AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0); 716e01d9b2eSChandu Babu N } 717e01d9b2eSChandu Babu N return 0; 718e01d9b2eSChandu Babu N } 719e01d9b2eSChandu Babu N 72044d45ffeSRavi Kumar /* return 0 means link status changed, -1 means not changed */ 72144d45ffeSRavi Kumar static int 72244d45ffeSRavi Kumar axgbe_dev_link_update(struct rte_eth_dev *dev, 72344d45ffeSRavi Kumar int wait_to_complete __rte_unused) 72444d45ffeSRavi Kumar { 72544d45ffeSRavi Kumar struct axgbe_port *pdata = dev->data->dev_private; 72644d45ffeSRavi Kumar struct rte_eth_link link; 72744d45ffeSRavi Kumar int ret = 0; 72844d45ffeSRavi Kumar 72944d45ffeSRavi Kumar PMD_INIT_FUNC_TRACE(); 73044d45ffeSRavi Kumar rte_delay_ms(800); 73144d45ffeSRavi Kumar 73244d45ffeSRavi Kumar pdata->phy_if.phy_status(pdata); 73344d45ffeSRavi Kumar 73444d45ffeSRavi Kumar memset(&link, 0, sizeof(struct rte_eth_link)); 73544d45ffeSRavi Kumar link.link_duplex = pdata->phy.duplex; 73644d45ffeSRavi Kumar link.link_status = pdata->phy_link; 73744d45ffeSRavi Kumar link.link_speed = pdata->phy_speed; 73844d45ffeSRavi Kumar link.link_autoneg = !(dev->data->dev_conf.link_speeds & 73944d45ffeSRavi Kumar ETH_LINK_SPEED_FIXED); 74044d45ffeSRavi Kumar ret = rte_eth_linkstatus_set(dev, &link); 74144d45ffeSRavi Kumar if (ret == -1) 74244d45ffeSRavi Kumar PMD_DRV_LOG(ERR, "No change in link status\n"); 74344d45ffeSRavi Kumar 74444d45ffeSRavi Kumar return ret; 74544d45ffeSRavi Kumar } 74644d45ffeSRavi Kumar 747df4867cdSChandu Babu N static int 748df4867cdSChandu Babu N axgbe_dev_get_regs(struct rte_eth_dev *dev, struct rte_dev_reg_info *regs) 749df4867cdSChandu Babu N { 750df4867cdSChandu Babu N struct axgbe_port *pdata = dev->data->dev_private; 751df4867cdSChandu Babu N 752df4867cdSChandu Babu N if (regs->data == NULL) { 753df4867cdSChandu Babu N regs->length = axgbe_regs_get_count(pdata); 754df4867cdSChandu Babu N regs->width = sizeof(uint32_t); 755df4867cdSChandu Babu N return 0; 756df4867cdSChandu Babu N } 757df4867cdSChandu Babu N 758df4867cdSChandu Babu N /* Only full register dump is supported */ 759df4867cdSChandu Babu N if (regs->length && 760df4867cdSChandu Babu N regs->length != (uint32_t)axgbe_regs_get_count(pdata)) 761df4867cdSChandu Babu N return -ENOTSUP; 762df4867cdSChandu Babu N 763df4867cdSChandu Babu N regs->version = pdata->pci_dev->id.vendor_id << 16 | 764df4867cdSChandu Babu N pdata->pci_dev->id.device_id; 765df4867cdSChandu Babu N axgbe_regs_dump(pdata, regs->data); 766df4867cdSChandu Babu N return 0; 767df4867cdSChandu Babu N } 7689d1ef6b2SChandu Babu N static void axgbe_read_mmc_stats(struct axgbe_port *pdata) 7699d1ef6b2SChandu Babu N { 7709d1ef6b2SChandu Babu N struct axgbe_mmc_stats *stats = &pdata->mmc_stats; 7719d1ef6b2SChandu Babu N 7729d1ef6b2SChandu Babu N /* Freeze counters */ 7739d1ef6b2SChandu Babu N AXGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 1); 7749d1ef6b2SChandu Babu N 7759d1ef6b2SChandu Babu N /* Tx counters */ 7769d1ef6b2SChandu Babu N stats->txoctetcount_gb += 7779d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_GB_LO); 7789d1ef6b2SChandu Babu N stats->txoctetcount_gb += 7799d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_GB_HI) << 32); 7809d1ef6b2SChandu Babu N 7819d1ef6b2SChandu Babu N stats->txframecount_gb += 7829d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_GB_LO); 7839d1ef6b2SChandu Babu N stats->txframecount_gb += 7849d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_GB_HI) << 32); 7859d1ef6b2SChandu Babu N 7869d1ef6b2SChandu Babu N stats->txbroadcastframes_g += 7879d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_G_LO); 7889d1ef6b2SChandu Babu N stats->txbroadcastframes_g += 7899d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_G_HI) << 32); 7909d1ef6b2SChandu Babu N 7919d1ef6b2SChandu Babu N stats->txmulticastframes_g += 7929d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_G_LO); 7939d1ef6b2SChandu Babu N stats->txmulticastframes_g += 7949d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_G_HI) << 32); 7959d1ef6b2SChandu Babu N 7969d1ef6b2SChandu Babu N stats->tx64octets_gb += 7979d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TX64OCTETS_GB_LO); 7989d1ef6b2SChandu Babu N stats->tx64octets_gb += 7999d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX64OCTETS_GB_HI) << 32); 8009d1ef6b2SChandu Babu N 8019d1ef6b2SChandu Babu N stats->tx65to127octets_gb += 8029d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TX65TO127OCTETS_GB_LO); 8039d1ef6b2SChandu Babu N stats->tx65to127octets_gb += 8049d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX65TO127OCTETS_GB_HI) << 32); 8059d1ef6b2SChandu Babu N 8069d1ef6b2SChandu Babu N stats->tx128to255octets_gb += 8079d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TX128TO255OCTETS_GB_LO); 8089d1ef6b2SChandu Babu N stats->tx128to255octets_gb += 8099d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX128TO255OCTETS_GB_HI) << 32); 8109d1ef6b2SChandu Babu N 8119d1ef6b2SChandu Babu N stats->tx256to511octets_gb += 8129d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TX256TO511OCTETS_GB_LO); 8139d1ef6b2SChandu Babu N stats->tx256to511octets_gb += 8149d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX256TO511OCTETS_GB_HI) << 32); 8159d1ef6b2SChandu Babu N 8169d1ef6b2SChandu Babu N stats->tx512to1023octets_gb += 8179d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TX512TO1023OCTETS_GB_LO); 8189d1ef6b2SChandu Babu N stats->tx512to1023octets_gb += 8199d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX512TO1023OCTETS_GB_HI) << 32); 8209d1ef6b2SChandu Babu N 8219d1ef6b2SChandu Babu N stats->tx1024tomaxoctets_gb += 8229d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TX1024TOMAXOCTETS_GB_LO); 8239d1ef6b2SChandu Babu N stats->tx1024tomaxoctets_gb += 8249d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TX1024TOMAXOCTETS_GB_HI) << 32); 8259d1ef6b2SChandu Babu N 8269d1ef6b2SChandu Babu N stats->txunicastframes_gb += 8279d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TXUNICASTFRAMES_GB_LO); 8289d1ef6b2SChandu Babu N stats->txunicastframes_gb += 8299d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXUNICASTFRAMES_GB_HI) << 32); 8309d1ef6b2SChandu Babu N 8319d1ef6b2SChandu Babu N stats->txmulticastframes_gb += 8329d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_GB_LO); 8339d1ef6b2SChandu Babu N stats->txmulticastframes_gb += 8349d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_GB_HI) << 32); 8359d1ef6b2SChandu Babu N 8369d1ef6b2SChandu Babu N stats->txbroadcastframes_g += 8379d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_GB_LO); 8389d1ef6b2SChandu Babu N stats->txbroadcastframes_g += 8399d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_GB_HI) << 32); 8409d1ef6b2SChandu Babu N 8419d1ef6b2SChandu Babu N stats->txunderflowerror += 8429d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TXUNDERFLOWERROR_LO); 8439d1ef6b2SChandu Babu N stats->txunderflowerror += 8449d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXUNDERFLOWERROR_HI) << 32); 8459d1ef6b2SChandu Babu N 8469d1ef6b2SChandu Babu N stats->txoctetcount_g += 8479d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_G_LO); 8489d1ef6b2SChandu Babu N stats->txoctetcount_g += 8499d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_G_HI) << 32); 8509d1ef6b2SChandu Babu N 8519d1ef6b2SChandu Babu N stats->txframecount_g += 8529d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_G_LO); 8539d1ef6b2SChandu Babu N stats->txframecount_g += 8549d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_G_HI) << 32); 8559d1ef6b2SChandu Babu N 8569d1ef6b2SChandu Babu N stats->txpauseframes += 8579d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TXPAUSEFRAMES_LO); 8589d1ef6b2SChandu Babu N stats->txpauseframes += 8599d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXPAUSEFRAMES_HI) << 32); 8609d1ef6b2SChandu Babu N 8619d1ef6b2SChandu Babu N stats->txvlanframes_g += 8629d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_TXVLANFRAMES_G_LO); 8639d1ef6b2SChandu Babu N stats->txvlanframes_g += 8649d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_TXVLANFRAMES_G_HI) << 32); 8659d1ef6b2SChandu Babu N 8669d1ef6b2SChandu Babu N /* Rx counters */ 8679d1ef6b2SChandu Babu N stats->rxframecount_gb += 8689d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXFRAMECOUNT_GB_LO); 8699d1ef6b2SChandu Babu N stats->rxframecount_gb += 8709d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXFRAMECOUNT_GB_HI) << 32); 8719d1ef6b2SChandu Babu N 8729d1ef6b2SChandu Babu N stats->rxoctetcount_gb += 8739d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_GB_LO); 8749d1ef6b2SChandu Babu N stats->rxoctetcount_gb += 8759d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_GB_HI) << 32); 8769d1ef6b2SChandu Babu N 8779d1ef6b2SChandu Babu N stats->rxoctetcount_g += 8789d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_G_LO); 8799d1ef6b2SChandu Babu N stats->rxoctetcount_g += 8809d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_G_HI) << 32); 8819d1ef6b2SChandu Babu N 8829d1ef6b2SChandu Babu N stats->rxbroadcastframes_g += 8839d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXBROADCASTFRAMES_G_LO); 8849d1ef6b2SChandu Babu N stats->rxbroadcastframes_g += 8859d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXBROADCASTFRAMES_G_HI) << 32); 8869d1ef6b2SChandu Babu N 8879d1ef6b2SChandu Babu N stats->rxmulticastframes_g += 8889d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXMULTICASTFRAMES_G_LO); 8899d1ef6b2SChandu Babu N stats->rxmulticastframes_g += 8909d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXMULTICASTFRAMES_G_HI) << 32); 8919d1ef6b2SChandu Babu N 8929d1ef6b2SChandu Babu N stats->rxcrcerror += 8939d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXCRCERROR_LO); 8949d1ef6b2SChandu Babu N stats->rxcrcerror += 8959d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXCRCERROR_HI) << 32); 8969d1ef6b2SChandu Babu N 8979d1ef6b2SChandu Babu N stats->rxrunterror += 8989d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXRUNTERROR); 8999d1ef6b2SChandu Babu N 9009d1ef6b2SChandu Babu N stats->rxjabbererror += 9019d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXJABBERERROR); 9029d1ef6b2SChandu Babu N 9039d1ef6b2SChandu Babu N stats->rxundersize_g += 9049d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXUNDERSIZE_G); 9059d1ef6b2SChandu Babu N 9069d1ef6b2SChandu Babu N stats->rxoversize_g += 9079d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXOVERSIZE_G); 9089d1ef6b2SChandu Babu N 9099d1ef6b2SChandu Babu N stats->rx64octets_gb += 9109d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RX64OCTETS_GB_LO); 9119d1ef6b2SChandu Babu N stats->rx64octets_gb += 9129d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX64OCTETS_GB_HI) << 32); 9139d1ef6b2SChandu Babu N 9149d1ef6b2SChandu Babu N stats->rx65to127octets_gb += 9159d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RX65TO127OCTETS_GB_LO); 9169d1ef6b2SChandu Babu N stats->rx65to127octets_gb += 9179d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX65TO127OCTETS_GB_HI) << 32); 9189d1ef6b2SChandu Babu N 9199d1ef6b2SChandu Babu N stats->rx128to255octets_gb += 9209d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RX128TO255OCTETS_GB_LO); 9219d1ef6b2SChandu Babu N stats->rx128to255octets_gb += 9229d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX128TO255OCTETS_GB_HI) << 32); 9239d1ef6b2SChandu Babu N 9249d1ef6b2SChandu Babu N stats->rx256to511octets_gb += 9259d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RX256TO511OCTETS_GB_LO); 9269d1ef6b2SChandu Babu N stats->rx256to511octets_gb += 9279d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX256TO511OCTETS_GB_HI) << 32); 9289d1ef6b2SChandu Babu N 9299d1ef6b2SChandu Babu N stats->rx512to1023octets_gb += 9309d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RX512TO1023OCTETS_GB_LO); 9319d1ef6b2SChandu Babu N stats->rx512to1023octets_gb += 9329d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX512TO1023OCTETS_GB_HI) << 32); 9339d1ef6b2SChandu Babu N 9349d1ef6b2SChandu Babu N stats->rx1024tomaxoctets_gb += 9359d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RX1024TOMAXOCTETS_GB_LO); 9369d1ef6b2SChandu Babu N stats->rx1024tomaxoctets_gb += 9379d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RX1024TOMAXOCTETS_GB_HI) << 32); 9389d1ef6b2SChandu Babu N 9399d1ef6b2SChandu Babu N stats->rxunicastframes_g += 9409d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXUNICASTFRAMES_G_LO); 9419d1ef6b2SChandu Babu N stats->rxunicastframes_g += 9429d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXUNICASTFRAMES_G_HI) << 32); 9439d1ef6b2SChandu Babu N 9449d1ef6b2SChandu Babu N stats->rxlengtherror += 9459d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXLENGTHERROR_LO); 9469d1ef6b2SChandu Babu N stats->rxlengtherror += 9479d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXLENGTHERROR_HI) << 32); 9489d1ef6b2SChandu Babu N 9499d1ef6b2SChandu Babu N stats->rxoutofrangetype += 9509d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXOUTOFRANGETYPE_LO); 9519d1ef6b2SChandu Babu N stats->rxoutofrangetype += 9529d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXOUTOFRANGETYPE_HI) << 32); 9539d1ef6b2SChandu Babu N 9549d1ef6b2SChandu Babu N stats->rxpauseframes += 9559d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXPAUSEFRAMES_LO); 9569d1ef6b2SChandu Babu N stats->rxpauseframes += 9579d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXPAUSEFRAMES_HI) << 32); 9589d1ef6b2SChandu Babu N 9599d1ef6b2SChandu Babu N stats->rxfifooverflow += 9609d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXFIFOOVERFLOW_LO); 9619d1ef6b2SChandu Babu N stats->rxfifooverflow += 9629d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXFIFOOVERFLOW_HI) << 32); 9639d1ef6b2SChandu Babu N 9649d1ef6b2SChandu Babu N stats->rxvlanframes_gb += 9659d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXVLANFRAMES_GB_LO); 9669d1ef6b2SChandu Babu N stats->rxvlanframes_gb += 9679d1ef6b2SChandu Babu N ((uint64_t)AXGMAC_IOREAD(pdata, MMC_RXVLANFRAMES_GB_HI) << 32); 9689d1ef6b2SChandu Babu N 9699d1ef6b2SChandu Babu N stats->rxwatchdogerror += 9709d1ef6b2SChandu Babu N AXGMAC_IOREAD(pdata, MMC_RXWATCHDOGERROR); 9719d1ef6b2SChandu Babu N 9729d1ef6b2SChandu Babu N /* Un-freeze counters */ 9739d1ef6b2SChandu Babu N AXGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 0); 9749d1ef6b2SChandu Babu N } 9759d1ef6b2SChandu Babu N 9769d1ef6b2SChandu Babu N static int 9779d1ef6b2SChandu Babu N axgbe_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats, 9789d1ef6b2SChandu Babu N unsigned int n) 9799d1ef6b2SChandu Babu N { 9809d1ef6b2SChandu Babu N struct axgbe_port *pdata = dev->data->dev_private; 9819d1ef6b2SChandu Babu N unsigned int i; 9829d1ef6b2SChandu Babu N 9839d1ef6b2SChandu Babu N if (!stats) 9849d1ef6b2SChandu Babu N return 0; 9859d1ef6b2SChandu Babu N 9869d1ef6b2SChandu Babu N axgbe_read_mmc_stats(pdata); 9879d1ef6b2SChandu Babu N 9889d1ef6b2SChandu Babu N for (i = 0; i < n && i < AXGBE_XSTATS_COUNT; i++) { 9899d1ef6b2SChandu Babu N stats[i].id = i; 9909d1ef6b2SChandu Babu N stats[i].value = *(u64 *)((uint8_t *)&pdata->mmc_stats + 9919d1ef6b2SChandu Babu N axgbe_xstats_strings[i].offset); 9929d1ef6b2SChandu Babu N } 9939d1ef6b2SChandu Babu N 9949d1ef6b2SChandu Babu N return i; 9959d1ef6b2SChandu Babu N } 9969d1ef6b2SChandu Babu N 9979d1ef6b2SChandu Babu N static int 9989d1ef6b2SChandu Babu N axgbe_dev_xstats_get_names(__rte_unused struct rte_eth_dev *dev, 9999d1ef6b2SChandu Babu N struct rte_eth_xstat_name *xstats_names, 10009d1ef6b2SChandu Babu N unsigned int n) 10019d1ef6b2SChandu Babu N { 10029d1ef6b2SChandu Babu N unsigned int i; 10039d1ef6b2SChandu Babu N 10049d1ef6b2SChandu Babu N if (n >= AXGBE_XSTATS_COUNT && xstats_names) { 10059d1ef6b2SChandu Babu N for (i = 0; i < AXGBE_XSTATS_COUNT; ++i) { 10069d1ef6b2SChandu Babu N snprintf(xstats_names[i].name, 10079d1ef6b2SChandu Babu N RTE_ETH_XSTATS_NAME_SIZE, "%s", 10089d1ef6b2SChandu Babu N axgbe_xstats_strings[i].name); 10099d1ef6b2SChandu Babu N } 10109d1ef6b2SChandu Babu N } 10119d1ef6b2SChandu Babu N 10129d1ef6b2SChandu Babu N return AXGBE_XSTATS_COUNT; 10139d1ef6b2SChandu Babu N } 10149d1ef6b2SChandu Babu N 10159d1ef6b2SChandu Babu N static int 10169d1ef6b2SChandu Babu N axgbe_dev_xstats_get_by_id(struct rte_eth_dev *dev, const uint64_t *ids, 10179d1ef6b2SChandu Babu N uint64_t *values, unsigned int n) 10189d1ef6b2SChandu Babu N { 10199d1ef6b2SChandu Babu N unsigned int i; 10209d1ef6b2SChandu Babu N uint64_t values_copy[AXGBE_XSTATS_COUNT]; 10219d1ef6b2SChandu Babu N 10229d1ef6b2SChandu Babu N if (!ids) { 10239d1ef6b2SChandu Babu N struct axgbe_port *pdata = dev->data->dev_private; 10249d1ef6b2SChandu Babu N 10259d1ef6b2SChandu Babu N if (n < AXGBE_XSTATS_COUNT) 10269d1ef6b2SChandu Babu N return AXGBE_XSTATS_COUNT; 10279d1ef6b2SChandu Babu N 10289d1ef6b2SChandu Babu N axgbe_read_mmc_stats(pdata); 10299d1ef6b2SChandu Babu N 10309d1ef6b2SChandu Babu N for (i = 0; i < AXGBE_XSTATS_COUNT; i++) { 10319d1ef6b2SChandu Babu N values[i] = *(u64 *)((uint8_t *)&pdata->mmc_stats + 10329d1ef6b2SChandu Babu N axgbe_xstats_strings[i].offset); 10339d1ef6b2SChandu Babu N } 10349d1ef6b2SChandu Babu N 10359d1ef6b2SChandu Babu N return i; 10369d1ef6b2SChandu Babu N } 10379d1ef6b2SChandu Babu N 10389d1ef6b2SChandu Babu N axgbe_dev_xstats_get_by_id(dev, NULL, values_copy, AXGBE_XSTATS_COUNT); 10399d1ef6b2SChandu Babu N 10409d1ef6b2SChandu Babu N for (i = 0; i < n; i++) { 10419d1ef6b2SChandu Babu N if (ids[i] >= AXGBE_XSTATS_COUNT) { 10429d1ef6b2SChandu Babu N PMD_DRV_LOG(ERR, "id value isn't valid\n"); 10439d1ef6b2SChandu Babu N return -1; 10449d1ef6b2SChandu Babu N } 10459d1ef6b2SChandu Babu N values[i] = values_copy[ids[i]]; 10469d1ef6b2SChandu Babu N } 10479d1ef6b2SChandu Babu N return n; 10489d1ef6b2SChandu Babu N } 10499d1ef6b2SChandu Babu N 10509d1ef6b2SChandu Babu N static int 10519d1ef6b2SChandu Babu N axgbe_dev_xstats_get_names_by_id(struct rte_eth_dev *dev, 10529d1ef6b2SChandu Babu N struct rte_eth_xstat_name *xstats_names, 10539d1ef6b2SChandu Babu N const uint64_t *ids, 10549d1ef6b2SChandu Babu N unsigned int size) 10559d1ef6b2SChandu Babu N { 10569d1ef6b2SChandu Babu N struct rte_eth_xstat_name xstats_names_copy[AXGBE_XSTATS_COUNT]; 10579d1ef6b2SChandu Babu N unsigned int i; 10589d1ef6b2SChandu Babu N 10599d1ef6b2SChandu Babu N if (!ids) 10609d1ef6b2SChandu Babu N return axgbe_dev_xstats_get_names(dev, xstats_names, size); 10619d1ef6b2SChandu Babu N 10629d1ef6b2SChandu Babu N axgbe_dev_xstats_get_names(dev, xstats_names_copy, size); 10639d1ef6b2SChandu Babu N 10649d1ef6b2SChandu Babu N for (i = 0; i < size; i++) { 10659d1ef6b2SChandu Babu N if (ids[i] >= AXGBE_XSTATS_COUNT) { 10669d1ef6b2SChandu Babu N PMD_DRV_LOG(ERR, "id value isn't valid\n"); 10679d1ef6b2SChandu Babu N return -1; 10689d1ef6b2SChandu Babu N } 10699d1ef6b2SChandu Babu N strcpy(xstats_names[i].name, xstats_names_copy[ids[i]].name); 10709d1ef6b2SChandu Babu N } 10719d1ef6b2SChandu Babu N return size; 10729d1ef6b2SChandu Babu N } 10739d1ef6b2SChandu Babu N 10749d1ef6b2SChandu Babu N static int 10759d1ef6b2SChandu Babu N axgbe_dev_xstats_reset(struct rte_eth_dev *dev) 10769d1ef6b2SChandu Babu N { 10779d1ef6b2SChandu Babu N struct axgbe_port *pdata = dev->data->dev_private; 10789d1ef6b2SChandu Babu N struct axgbe_mmc_stats *stats = &pdata->mmc_stats; 10799d1ef6b2SChandu Babu N 10809d1ef6b2SChandu Babu N /* MMC registers are configured for reset on read */ 10819d1ef6b2SChandu Babu N axgbe_read_mmc_stats(pdata); 10829d1ef6b2SChandu Babu N 10839d1ef6b2SChandu Babu N /* Reset stats */ 10849d1ef6b2SChandu Babu N memset(stats, 0, sizeof(*stats)); 10859d1ef6b2SChandu Babu N 10869d1ef6b2SChandu Babu N return 0; 10879d1ef6b2SChandu Babu N } 10889d1ef6b2SChandu Babu N 10893e730511SRavi Kumar static int 10903e730511SRavi Kumar axgbe_dev_stats_get(struct rte_eth_dev *dev, 10913e730511SRavi Kumar struct rte_eth_stats *stats) 10923e730511SRavi Kumar { 10933e730511SRavi Kumar struct axgbe_rx_queue *rxq; 10943e730511SRavi Kumar struct axgbe_tx_queue *txq; 10959d1ef6b2SChandu Babu N struct axgbe_port *pdata = dev->data->dev_private; 10969d1ef6b2SChandu Babu N struct axgbe_mmc_stats *mmc_stats = &pdata->mmc_stats; 10973e730511SRavi Kumar unsigned int i; 10983e730511SRavi Kumar 10999d1ef6b2SChandu Babu N axgbe_read_mmc_stats(pdata); 11009d1ef6b2SChandu Babu N 11019d1ef6b2SChandu Babu N stats->imissed = mmc_stats->rxfifooverflow; 11029d1ef6b2SChandu Babu N 11033e730511SRavi Kumar for (i = 0; i < dev->data->nb_rx_queues; i++) { 11043e730511SRavi Kumar rxq = dev->data->rx_queues[i]; 11053e730511SRavi Kumar stats->q_ipackets[i] = rxq->pkts; 11063e730511SRavi Kumar stats->ipackets += rxq->pkts; 11073e730511SRavi Kumar stats->q_ibytes[i] = rxq->bytes; 11083e730511SRavi Kumar stats->ibytes += rxq->bytes; 11099d1ef6b2SChandu Babu N stats->rx_nombuf += rxq->rx_mbuf_alloc_failed; 11109d1ef6b2SChandu Babu N stats->q_errors[i] = rxq->errors + rxq->rx_mbuf_alloc_failed; 11119d1ef6b2SChandu Babu N stats->ierrors += rxq->errors; 11123e730511SRavi Kumar } 11139d1ef6b2SChandu Babu N 11143e730511SRavi Kumar for (i = 0; i < dev->data->nb_tx_queues; i++) { 11153e730511SRavi Kumar txq = dev->data->tx_queues[i]; 11163e730511SRavi Kumar stats->q_opackets[i] = txq->pkts; 11173e730511SRavi Kumar stats->opackets += txq->pkts; 11183e730511SRavi Kumar stats->q_obytes[i] = txq->bytes; 11193e730511SRavi Kumar stats->obytes += txq->bytes; 11209d1ef6b2SChandu Babu N stats->oerrors += txq->errors; 11213e730511SRavi Kumar } 11223e730511SRavi Kumar 11233e730511SRavi Kumar return 0; 11243e730511SRavi Kumar } 11253e730511SRavi Kumar 11269970a9adSIgor Romanov static int 11273e730511SRavi Kumar axgbe_dev_stats_reset(struct rte_eth_dev *dev) 11283e730511SRavi Kumar { 11293e730511SRavi Kumar struct axgbe_rx_queue *rxq; 11303e730511SRavi Kumar struct axgbe_tx_queue *txq; 11313e730511SRavi Kumar unsigned int i; 11323e730511SRavi Kumar 11333e730511SRavi Kumar for (i = 0; i < dev->data->nb_rx_queues; i++) { 11343e730511SRavi Kumar rxq = dev->data->rx_queues[i]; 11353e730511SRavi Kumar rxq->pkts = 0; 11363e730511SRavi Kumar rxq->bytes = 0; 11373e730511SRavi Kumar rxq->errors = 0; 11389d1ef6b2SChandu Babu N rxq->rx_mbuf_alloc_failed = 0; 11393e730511SRavi Kumar } 11403e730511SRavi Kumar for (i = 0; i < dev->data->nb_tx_queues; i++) { 11413e730511SRavi Kumar txq = dev->data->tx_queues[i]; 11423e730511SRavi Kumar txq->pkts = 0; 11433e730511SRavi Kumar txq->bytes = 0; 11443e730511SRavi Kumar txq->errors = 0; 11453e730511SRavi Kumar } 11469970a9adSIgor Romanov 11479970a9adSIgor Romanov return 0; 11483e730511SRavi Kumar } 11493e730511SRavi Kumar 1150bdad90d1SIvan Ilchenko static int 1151cd8c7c7cSFerruh Yigit axgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) 11529e890103SRavi Kumar { 11539e890103SRavi Kumar struct axgbe_port *pdata = dev->data->dev_private; 11549e890103SRavi Kumar 11559e890103SRavi Kumar dev_info->max_rx_queues = pdata->rx_ring_count; 11569e890103SRavi Kumar dev_info->max_tx_queues = pdata->tx_ring_count; 11579e890103SRavi Kumar dev_info->min_rx_bufsize = AXGBE_RX_MIN_BUF_SIZE; 11589e890103SRavi Kumar dev_info->max_rx_pktlen = AXGBE_RX_MAX_BUF_SIZE; 115949a5e622SChandu Babu N dev_info->max_mac_addrs = pdata->hw_feat.addn_mac + 1; 1160e01d9b2eSChandu Babu N dev_info->max_hash_mac_addrs = pdata->hw_feat.hash_table_size; 11619e890103SRavi Kumar dev_info->speed_capa = ETH_LINK_SPEED_10G; 11629e890103SRavi Kumar 11639e890103SRavi Kumar dev_info->rx_offload_capa = 11649e890103SRavi Kumar DEV_RX_OFFLOAD_IPV4_CKSUM | 11659e890103SRavi Kumar DEV_RX_OFFLOAD_UDP_CKSUM | 116670815c9eSFerruh Yigit DEV_RX_OFFLOAD_TCP_CKSUM | 1167965b3127SSelwin Sebastian DEV_RX_OFFLOAD_JUMBO_FRAME | 1168965b3127SSelwin Sebastian DEV_RX_OFFLOAD_SCATTER | 116970815c9eSFerruh Yigit DEV_RX_OFFLOAD_KEEP_CRC; 11709e890103SRavi Kumar 11719e890103SRavi Kumar dev_info->tx_offload_capa = 11729e890103SRavi Kumar DEV_TX_OFFLOAD_IPV4_CKSUM | 11739e890103SRavi Kumar DEV_TX_OFFLOAD_UDP_CKSUM | 11749e890103SRavi Kumar DEV_TX_OFFLOAD_TCP_CKSUM; 11759e890103SRavi Kumar 11769e890103SRavi Kumar if (pdata->hw_feat.rss) { 11779e890103SRavi Kumar dev_info->flow_type_rss_offloads = AXGBE_RSS_OFFLOAD; 11789e890103SRavi Kumar dev_info->reta_size = pdata->hw_feat.hash_table_size; 11799e890103SRavi Kumar dev_info->hash_key_size = AXGBE_RSS_HASH_KEY_SIZE; 11809e890103SRavi Kumar } 11819e890103SRavi Kumar 11829e890103SRavi Kumar dev_info->rx_desc_lim = rx_desc_lim; 11839e890103SRavi Kumar dev_info->tx_desc_lim = tx_desc_lim; 11849e890103SRavi Kumar 11859e890103SRavi Kumar dev_info->default_rxconf = (struct rte_eth_rxconf) { 11869e890103SRavi Kumar .rx_free_thresh = AXGBE_RX_FREE_THRESH, 11879e890103SRavi Kumar }; 11889e890103SRavi Kumar 11899e890103SRavi Kumar dev_info->default_txconf = (struct rte_eth_txconf) { 11909e890103SRavi Kumar .tx_free_thresh = AXGBE_TX_FREE_THRESH, 11919e890103SRavi Kumar }; 1192bdad90d1SIvan Ilchenko 1193bdad90d1SIvan Ilchenko return 0; 11949e890103SRavi Kumar } 11959e890103SRavi Kumar 1196cf97f33eSAmaranath Somalapuram static int 1197cf97f33eSAmaranath Somalapuram axgbe_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 1198cf97f33eSAmaranath Somalapuram { 1199cf97f33eSAmaranath Somalapuram struct axgbe_port *pdata = dev->data->dev_private; 1200cf97f33eSAmaranath Somalapuram struct xgbe_fc_info fc = pdata->fc; 1201cf97f33eSAmaranath Somalapuram unsigned int reg, reg_val = 0; 1202cf97f33eSAmaranath Somalapuram 1203cf97f33eSAmaranath Somalapuram reg = MAC_Q0TFCR; 1204cf97f33eSAmaranath Somalapuram reg_val = AXGMAC_IOREAD(pdata, reg); 1205cf97f33eSAmaranath Somalapuram fc.low_water[0] = AXGMAC_MTL_IOREAD_BITS(pdata, 0, MTL_Q_RQFCR, RFA); 1206cf97f33eSAmaranath Somalapuram fc.high_water[0] = AXGMAC_MTL_IOREAD_BITS(pdata, 0, MTL_Q_RQFCR, RFD); 1207cf97f33eSAmaranath Somalapuram fc.pause_time[0] = AXGMAC_GET_BITS(reg_val, MAC_Q0TFCR, PT); 1208cf97f33eSAmaranath Somalapuram fc.autoneg = pdata->pause_autoneg; 1209cf97f33eSAmaranath Somalapuram 1210cf97f33eSAmaranath Somalapuram if (pdata->rx_pause && pdata->tx_pause) 1211cf97f33eSAmaranath Somalapuram fc.mode = RTE_FC_FULL; 1212cf97f33eSAmaranath Somalapuram else if (pdata->rx_pause) 1213cf97f33eSAmaranath Somalapuram fc.mode = RTE_FC_RX_PAUSE; 1214cf97f33eSAmaranath Somalapuram else if (pdata->tx_pause) 1215cf97f33eSAmaranath Somalapuram fc.mode = RTE_FC_TX_PAUSE; 1216cf97f33eSAmaranath Somalapuram else 1217cf97f33eSAmaranath Somalapuram fc.mode = RTE_FC_NONE; 1218cf97f33eSAmaranath Somalapuram 1219cf97f33eSAmaranath Somalapuram fc_conf->high_water = (1024 + (fc.low_water[0] << 9)) / 1024; 1220cf97f33eSAmaranath Somalapuram fc_conf->low_water = (1024 + (fc.high_water[0] << 9)) / 1024; 1221cf97f33eSAmaranath Somalapuram fc_conf->pause_time = fc.pause_time[0]; 1222cf97f33eSAmaranath Somalapuram fc_conf->send_xon = fc.send_xon; 1223cf97f33eSAmaranath Somalapuram fc_conf->mode = fc.mode; 1224cf97f33eSAmaranath Somalapuram 1225cf97f33eSAmaranath Somalapuram return 0; 1226cf97f33eSAmaranath Somalapuram } 1227cf97f33eSAmaranath Somalapuram 1228cf97f33eSAmaranath Somalapuram static int 1229cf97f33eSAmaranath Somalapuram axgbe_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) 1230cf97f33eSAmaranath Somalapuram { 1231cf97f33eSAmaranath Somalapuram struct axgbe_port *pdata = dev->data->dev_private; 1232cf97f33eSAmaranath Somalapuram struct xgbe_fc_info fc = pdata->fc; 1233cf97f33eSAmaranath Somalapuram unsigned int reg, reg_val = 0; 1234cf97f33eSAmaranath Somalapuram reg = MAC_Q0TFCR; 1235cf97f33eSAmaranath Somalapuram 1236cf97f33eSAmaranath Somalapuram pdata->pause_autoneg = fc_conf->autoneg; 1237cf97f33eSAmaranath Somalapuram pdata->phy.pause_autoneg = pdata->pause_autoneg; 1238cf97f33eSAmaranath Somalapuram fc.send_xon = fc_conf->send_xon; 1239cf97f33eSAmaranath Somalapuram AXGMAC_MTL_IOWRITE_BITS(pdata, 0, MTL_Q_RQFCR, RFA, 1240cf97f33eSAmaranath Somalapuram AXGMAC_FLOW_CONTROL_VALUE(1024 * fc_conf->high_water)); 1241cf97f33eSAmaranath Somalapuram AXGMAC_MTL_IOWRITE_BITS(pdata, 0, MTL_Q_RQFCR, RFD, 1242cf97f33eSAmaranath Somalapuram AXGMAC_FLOW_CONTROL_VALUE(1024 * fc_conf->low_water)); 1243cf97f33eSAmaranath Somalapuram AXGMAC_SET_BITS(reg_val, MAC_Q0TFCR, PT, fc_conf->pause_time); 1244cf97f33eSAmaranath Somalapuram AXGMAC_IOWRITE(pdata, reg, reg_val); 1245cf97f33eSAmaranath Somalapuram fc.mode = fc_conf->mode; 1246cf97f33eSAmaranath Somalapuram 1247cf97f33eSAmaranath Somalapuram if (fc.mode == RTE_FC_FULL) { 1248cf97f33eSAmaranath Somalapuram pdata->tx_pause = 1; 1249cf97f33eSAmaranath Somalapuram pdata->rx_pause = 1; 1250cf97f33eSAmaranath Somalapuram } else if (fc.mode == RTE_FC_RX_PAUSE) { 1251cf97f33eSAmaranath Somalapuram pdata->tx_pause = 0; 1252cf97f33eSAmaranath Somalapuram pdata->rx_pause = 1; 1253cf97f33eSAmaranath Somalapuram } else if (fc.mode == RTE_FC_TX_PAUSE) { 1254cf97f33eSAmaranath Somalapuram pdata->tx_pause = 1; 1255cf97f33eSAmaranath Somalapuram pdata->rx_pause = 0; 1256cf97f33eSAmaranath Somalapuram } else { 1257cf97f33eSAmaranath Somalapuram pdata->tx_pause = 0; 1258cf97f33eSAmaranath Somalapuram pdata->rx_pause = 0; 1259cf97f33eSAmaranath Somalapuram } 1260cf97f33eSAmaranath Somalapuram 1261cf97f33eSAmaranath Somalapuram if (pdata->tx_pause != (unsigned int)pdata->phy.tx_pause) 1262cf97f33eSAmaranath Somalapuram pdata->hw_if.config_tx_flow_control(pdata); 1263cf97f33eSAmaranath Somalapuram 1264cf97f33eSAmaranath Somalapuram if (pdata->rx_pause != (unsigned int)pdata->phy.rx_pause) 1265cf97f33eSAmaranath Somalapuram pdata->hw_if.config_rx_flow_control(pdata); 1266cf97f33eSAmaranath Somalapuram 1267cf97f33eSAmaranath Somalapuram pdata->hw_if.config_flow_control(pdata); 1268cf97f33eSAmaranath Somalapuram pdata->phy.tx_pause = pdata->tx_pause; 1269cf97f33eSAmaranath Somalapuram pdata->phy.rx_pause = pdata->rx_pause; 1270cf97f33eSAmaranath Somalapuram 1271cf97f33eSAmaranath Somalapuram return 0; 1272cf97f33eSAmaranath Somalapuram } 1273cf97f33eSAmaranath Somalapuram 1274e0543d4eSAmaranath Somalapuram static int 1275e0543d4eSAmaranath Somalapuram axgbe_priority_flow_ctrl_set(struct rte_eth_dev *dev, 1276e0543d4eSAmaranath Somalapuram struct rte_eth_pfc_conf *pfc_conf) 1277e0543d4eSAmaranath Somalapuram { 1278e0543d4eSAmaranath Somalapuram struct axgbe_port *pdata = dev->data->dev_private; 1279e0543d4eSAmaranath Somalapuram struct xgbe_fc_info fc = pdata->fc; 1280e0543d4eSAmaranath Somalapuram uint8_t tc_num; 1281e0543d4eSAmaranath Somalapuram 1282e0543d4eSAmaranath Somalapuram tc_num = pdata->pfc_map[pfc_conf->priority]; 1283e0543d4eSAmaranath Somalapuram 1284e0543d4eSAmaranath Somalapuram if (pfc_conf->priority >= pdata->hw_feat.tc_cnt) { 1285e0543d4eSAmaranath Somalapuram PMD_INIT_LOG(ERR, "Max supported traffic class: %d\n", 1286e0543d4eSAmaranath Somalapuram pdata->hw_feat.tc_cnt); 1287e0543d4eSAmaranath Somalapuram return -EINVAL; 1288e0543d4eSAmaranath Somalapuram } 1289e0543d4eSAmaranath Somalapuram 1290e0543d4eSAmaranath Somalapuram pdata->pause_autoneg = pfc_conf->fc.autoneg; 1291e0543d4eSAmaranath Somalapuram pdata->phy.pause_autoneg = pdata->pause_autoneg; 1292e0543d4eSAmaranath Somalapuram fc.send_xon = pfc_conf->fc.send_xon; 1293e0543d4eSAmaranath Somalapuram AXGMAC_MTL_IOWRITE_BITS(pdata, tc_num, MTL_Q_RQFCR, RFA, 1294e0543d4eSAmaranath Somalapuram AXGMAC_FLOW_CONTROL_VALUE(1024 * pfc_conf->fc.high_water)); 1295e0543d4eSAmaranath Somalapuram AXGMAC_MTL_IOWRITE_BITS(pdata, tc_num, MTL_Q_RQFCR, RFD, 1296e0543d4eSAmaranath Somalapuram AXGMAC_FLOW_CONTROL_VALUE(1024 * pfc_conf->fc.low_water)); 1297e0543d4eSAmaranath Somalapuram 1298e0543d4eSAmaranath Somalapuram switch (tc_num) { 1299e0543d4eSAmaranath Somalapuram case 0: 1300e0543d4eSAmaranath Somalapuram AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM0R, 1301e0543d4eSAmaranath Somalapuram PSTC0, pfc_conf->fc.pause_time); 1302e0543d4eSAmaranath Somalapuram break; 1303e0543d4eSAmaranath Somalapuram case 1: 1304e0543d4eSAmaranath Somalapuram AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM0R, 1305e0543d4eSAmaranath Somalapuram PSTC1, pfc_conf->fc.pause_time); 1306e0543d4eSAmaranath Somalapuram break; 1307e0543d4eSAmaranath Somalapuram case 2: 1308e0543d4eSAmaranath Somalapuram AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM0R, 1309e0543d4eSAmaranath Somalapuram PSTC2, pfc_conf->fc.pause_time); 1310e0543d4eSAmaranath Somalapuram break; 1311e0543d4eSAmaranath Somalapuram case 3: 1312e0543d4eSAmaranath Somalapuram AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM0R, 1313e0543d4eSAmaranath Somalapuram PSTC3, pfc_conf->fc.pause_time); 1314e0543d4eSAmaranath Somalapuram break; 1315e0543d4eSAmaranath Somalapuram case 4: 1316e0543d4eSAmaranath Somalapuram AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM1R, 1317e0543d4eSAmaranath Somalapuram PSTC4, pfc_conf->fc.pause_time); 1318e0543d4eSAmaranath Somalapuram break; 1319e0543d4eSAmaranath Somalapuram case 5: 1320e0543d4eSAmaranath Somalapuram AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM1R, 1321e0543d4eSAmaranath Somalapuram PSTC5, pfc_conf->fc.pause_time); 1322e0543d4eSAmaranath Somalapuram break; 1323e0543d4eSAmaranath Somalapuram case 7: 1324e0543d4eSAmaranath Somalapuram AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM1R, 1325e0543d4eSAmaranath Somalapuram PSTC6, pfc_conf->fc.pause_time); 1326e0543d4eSAmaranath Somalapuram break; 1327e0543d4eSAmaranath Somalapuram case 6: 1328e0543d4eSAmaranath Somalapuram AXGMAC_IOWRITE_BITS(pdata, MTL_TCPM1R, 1329e0543d4eSAmaranath Somalapuram PSTC7, pfc_conf->fc.pause_time); 1330e0543d4eSAmaranath Somalapuram break; 1331e0543d4eSAmaranath Somalapuram } 1332e0543d4eSAmaranath Somalapuram 1333e0543d4eSAmaranath Somalapuram fc.mode = pfc_conf->fc.mode; 1334e0543d4eSAmaranath Somalapuram 1335e0543d4eSAmaranath Somalapuram if (fc.mode == RTE_FC_FULL) { 1336e0543d4eSAmaranath Somalapuram pdata->tx_pause = 1; 1337e0543d4eSAmaranath Somalapuram pdata->rx_pause = 1; 1338e0543d4eSAmaranath Somalapuram AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 1); 1339e0543d4eSAmaranath Somalapuram } else if (fc.mode == RTE_FC_RX_PAUSE) { 1340e0543d4eSAmaranath Somalapuram pdata->tx_pause = 0; 1341e0543d4eSAmaranath Somalapuram pdata->rx_pause = 1; 1342e0543d4eSAmaranath Somalapuram AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 1); 1343e0543d4eSAmaranath Somalapuram } else if (fc.mode == RTE_FC_TX_PAUSE) { 1344e0543d4eSAmaranath Somalapuram pdata->tx_pause = 1; 1345e0543d4eSAmaranath Somalapuram pdata->rx_pause = 0; 1346e0543d4eSAmaranath Somalapuram AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 0); 1347e0543d4eSAmaranath Somalapuram } else { 1348e0543d4eSAmaranath Somalapuram pdata->tx_pause = 0; 1349e0543d4eSAmaranath Somalapuram pdata->rx_pause = 0; 1350e0543d4eSAmaranath Somalapuram AXGMAC_IOWRITE_BITS(pdata, MAC_RFCR, PFCE, 0); 1351e0543d4eSAmaranath Somalapuram } 1352e0543d4eSAmaranath Somalapuram 1353e0543d4eSAmaranath Somalapuram if (pdata->tx_pause != (unsigned int)pdata->phy.tx_pause) 1354e0543d4eSAmaranath Somalapuram pdata->hw_if.config_tx_flow_control(pdata); 1355e0543d4eSAmaranath Somalapuram 1356e0543d4eSAmaranath Somalapuram if (pdata->rx_pause != (unsigned int)pdata->phy.rx_pause) 1357e0543d4eSAmaranath Somalapuram pdata->hw_if.config_rx_flow_control(pdata); 1358e0543d4eSAmaranath Somalapuram pdata->hw_if.config_flow_control(pdata); 1359e0543d4eSAmaranath Somalapuram pdata->phy.tx_pause = pdata->tx_pause; 1360e0543d4eSAmaranath Somalapuram pdata->phy.rx_pause = pdata->rx_pause; 1361e0543d4eSAmaranath Somalapuram 1362e0543d4eSAmaranath Somalapuram return 0; 1363e0543d4eSAmaranath Somalapuram } 1364e0543d4eSAmaranath Somalapuram 13657aed95c9SAmaranath Somalapuram void 13667aed95c9SAmaranath Somalapuram axgbe_rxq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, 13677aed95c9SAmaranath Somalapuram struct rte_eth_rxq_info *qinfo) 13687aed95c9SAmaranath Somalapuram { 13697aed95c9SAmaranath Somalapuram struct axgbe_rx_queue *rxq; 13707aed95c9SAmaranath Somalapuram 13717aed95c9SAmaranath Somalapuram rxq = dev->data->rx_queues[queue_id]; 13727aed95c9SAmaranath Somalapuram qinfo->mp = rxq->mb_pool; 13737aed95c9SAmaranath Somalapuram qinfo->scattered_rx = dev->data->scattered_rx; 13747aed95c9SAmaranath Somalapuram qinfo->nb_desc = rxq->nb_desc; 13757aed95c9SAmaranath Somalapuram qinfo->conf.rx_free_thresh = rxq->free_thresh; 13767aed95c9SAmaranath Somalapuram } 13777aed95c9SAmaranath Somalapuram 13787aed95c9SAmaranath Somalapuram void 13797aed95c9SAmaranath Somalapuram axgbe_txq_info_get(struct rte_eth_dev *dev, uint16_t queue_id, 13807aed95c9SAmaranath Somalapuram struct rte_eth_txq_info *qinfo) 13817aed95c9SAmaranath Somalapuram { 13827aed95c9SAmaranath Somalapuram struct axgbe_tx_queue *txq; 13837aed95c9SAmaranath Somalapuram 13847aed95c9SAmaranath Somalapuram txq = dev->data->tx_queues[queue_id]; 13857aed95c9SAmaranath Somalapuram qinfo->nb_desc = txq->nb_desc; 13867aed95c9SAmaranath Somalapuram qinfo->conf.tx_free_thresh = txq->free_thresh; 13877aed95c9SAmaranath Somalapuram } 1388410cf087SAmaranath Somalapuram const uint32_t * 1389410cf087SAmaranath Somalapuram axgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev) 1390410cf087SAmaranath Somalapuram { 1391410cf087SAmaranath Somalapuram static const uint32_t ptypes[] = { 1392410cf087SAmaranath Somalapuram RTE_PTYPE_L2_ETHER, 1393410cf087SAmaranath Somalapuram RTE_PTYPE_L2_ETHER_TIMESYNC, 1394410cf087SAmaranath Somalapuram RTE_PTYPE_L2_ETHER_LLDP, 1395410cf087SAmaranath Somalapuram RTE_PTYPE_L2_ETHER_ARP, 1396410cf087SAmaranath Somalapuram RTE_PTYPE_L3_IPV4_EXT_UNKNOWN, 1397410cf087SAmaranath Somalapuram RTE_PTYPE_L3_IPV6_EXT_UNKNOWN, 1398410cf087SAmaranath Somalapuram RTE_PTYPE_L4_FRAG, 1399410cf087SAmaranath Somalapuram RTE_PTYPE_L4_ICMP, 1400410cf087SAmaranath Somalapuram RTE_PTYPE_L4_NONFRAG, 1401410cf087SAmaranath Somalapuram RTE_PTYPE_L4_SCTP, 1402410cf087SAmaranath Somalapuram RTE_PTYPE_L4_TCP, 1403410cf087SAmaranath Somalapuram RTE_PTYPE_L4_UDP, 1404410cf087SAmaranath Somalapuram RTE_PTYPE_TUNNEL_GRENAT, 1405410cf087SAmaranath Somalapuram RTE_PTYPE_TUNNEL_IP, 1406410cf087SAmaranath Somalapuram RTE_PTYPE_INNER_L2_ETHER, 1407410cf087SAmaranath Somalapuram RTE_PTYPE_INNER_L2_ETHER_VLAN, 1408410cf087SAmaranath Somalapuram RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN, 1409410cf087SAmaranath Somalapuram RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN, 1410410cf087SAmaranath Somalapuram RTE_PTYPE_INNER_L4_FRAG, 1411410cf087SAmaranath Somalapuram RTE_PTYPE_INNER_L4_ICMP, 1412410cf087SAmaranath Somalapuram RTE_PTYPE_INNER_L4_NONFRAG, 1413410cf087SAmaranath Somalapuram RTE_PTYPE_INNER_L4_SCTP, 1414410cf087SAmaranath Somalapuram RTE_PTYPE_INNER_L4_TCP, 1415410cf087SAmaranath Somalapuram RTE_PTYPE_INNER_L4_UDP, 1416410cf087SAmaranath Somalapuram RTE_PTYPE_UNKNOWN 1417410cf087SAmaranath Somalapuram }; 1418410cf087SAmaranath Somalapuram 1419410cf087SAmaranath Somalapuram if (dev->rx_pkt_burst == axgbe_recv_pkts) 1420410cf087SAmaranath Somalapuram return ptypes; 1421410cf087SAmaranath Somalapuram return NULL; 1422410cf087SAmaranath Somalapuram } 1423e0444948SSelwin Sebastian 1424b58d8781SGirish Nandibasappa static int axgb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) 1425b58d8781SGirish Nandibasappa { 1426b58d8781SGirish Nandibasappa struct rte_eth_dev_info dev_info; 1427b58d8781SGirish Nandibasappa struct axgbe_port *pdata = dev->data->dev_private; 1428b58d8781SGirish Nandibasappa uint32_t frame_size = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN; 1429b58d8781SGirish Nandibasappa unsigned int val = 0; 1430b58d8781SGirish Nandibasappa axgbe_dev_info_get(dev, &dev_info); 1431b58d8781SGirish Nandibasappa /* check that mtu is within the allowed range */ 1432b58d8781SGirish Nandibasappa if (mtu < RTE_ETHER_MIN_MTU || frame_size > dev_info.max_rx_pktlen) 1433b58d8781SGirish Nandibasappa return -EINVAL; 1434b58d8781SGirish Nandibasappa /* mtu setting is forbidden if port is start */ 1435b58d8781SGirish Nandibasappa if (dev->data->dev_started) { 1436b58d8781SGirish Nandibasappa PMD_DRV_LOG(ERR, "port %d must be stopped before configuration", 1437b58d8781SGirish Nandibasappa dev->data->port_id); 1438b58d8781SGirish Nandibasappa return -EBUSY; 1439b58d8781SGirish Nandibasappa } 1440b58d8781SGirish Nandibasappa if (frame_size > RTE_ETHER_MAX_LEN) { 1441b58d8781SGirish Nandibasappa dev->data->dev_conf.rxmode.offloads |= 1442b58d8781SGirish Nandibasappa DEV_RX_OFFLOAD_JUMBO_FRAME; 1443b58d8781SGirish Nandibasappa val = 1; 1444b58d8781SGirish Nandibasappa } else { 1445b58d8781SGirish Nandibasappa dev->data->dev_conf.rxmode.offloads &= 1446b58d8781SGirish Nandibasappa ~DEV_RX_OFFLOAD_JUMBO_FRAME; 1447b58d8781SGirish Nandibasappa val = 0; 1448b58d8781SGirish Nandibasappa } 1449b58d8781SGirish Nandibasappa AXGMAC_IOWRITE_BITS(pdata, MAC_RCR, JE, val); 1450b58d8781SGirish Nandibasappa dev->data->dev_conf.rxmode.max_rx_pkt_len = frame_size; 1451b58d8781SGirish Nandibasappa return 0; 1452b58d8781SGirish Nandibasappa } 1453e0444948SSelwin Sebastian 1454e0444948SSelwin Sebastian static void 1455e0444948SSelwin Sebastian axgbe_update_tstamp_time(struct axgbe_port *pdata, 1456e0444948SSelwin Sebastian unsigned int sec, unsigned int nsec, int addsub) 1457e0444948SSelwin Sebastian { 1458e0444948SSelwin Sebastian unsigned int count = 100; 1459e0444948SSelwin Sebastian uint32_t sub_val = 0; 1460e0444948SSelwin Sebastian uint32_t sub_val_sec = 0xFFFFFFFF; 1461e0444948SSelwin Sebastian uint32_t sub_val_nsec = 0x3B9ACA00; 1462e0444948SSelwin Sebastian 1463e0444948SSelwin Sebastian if (addsub) { 1464e0444948SSelwin Sebastian if (sec) 1465e0444948SSelwin Sebastian sub_val = sub_val_sec - (sec - 1); 1466e0444948SSelwin Sebastian else 1467e0444948SSelwin Sebastian sub_val = sec; 1468e0444948SSelwin Sebastian 1469e0444948SSelwin Sebastian AXGMAC_IOWRITE(pdata, MAC_STSUR, sub_val); 1470e0444948SSelwin Sebastian sub_val = sub_val_nsec - nsec; 1471e0444948SSelwin Sebastian AXGMAC_IOWRITE(pdata, MAC_STNUR, sub_val); 1472e0444948SSelwin Sebastian AXGMAC_IOWRITE_BITS(pdata, MAC_STNUR, ADDSUB, 1); 1473e0444948SSelwin Sebastian } else { 1474e0444948SSelwin Sebastian AXGMAC_IOWRITE(pdata, MAC_STSUR, sec); 1475e0444948SSelwin Sebastian AXGMAC_IOWRITE_BITS(pdata, MAC_STNUR, ADDSUB, 0); 1476e0444948SSelwin Sebastian AXGMAC_IOWRITE(pdata, MAC_STNUR, nsec); 1477e0444948SSelwin Sebastian } 1478e0444948SSelwin Sebastian AXGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSUPDT, 1); 1479e0444948SSelwin Sebastian /* Wait for time update to complete */ 1480e0444948SSelwin Sebastian while (--count && AXGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSUPDT)) 1481e0444948SSelwin Sebastian rte_delay_ms(1); 1482e0444948SSelwin Sebastian } 1483e0444948SSelwin Sebastian 1484e0444948SSelwin Sebastian static inline uint64_t 1485e0444948SSelwin Sebastian div_u64_rem(uint64_t dividend, uint32_t divisor, uint32_t *remainder) 1486e0444948SSelwin Sebastian { 1487e0444948SSelwin Sebastian *remainder = dividend % divisor; 1488e0444948SSelwin Sebastian return dividend / divisor; 1489e0444948SSelwin Sebastian } 1490e0444948SSelwin Sebastian 1491e0444948SSelwin Sebastian static inline uint64_t 1492e0444948SSelwin Sebastian div_u64(uint64_t dividend, uint32_t divisor) 1493e0444948SSelwin Sebastian { 1494e0444948SSelwin Sebastian uint32_t remainder; 1495e0444948SSelwin Sebastian return div_u64_rem(dividend, divisor, &remainder); 1496e0444948SSelwin Sebastian } 1497e0444948SSelwin Sebastian 1498e0444948SSelwin Sebastian static int 1499e0444948SSelwin Sebastian axgbe_adjfreq(struct axgbe_port *pdata, int64_t delta) 1500e0444948SSelwin Sebastian { 1501e0444948SSelwin Sebastian uint64_t adjust; 1502e0444948SSelwin Sebastian uint32_t addend, diff; 1503e0444948SSelwin Sebastian unsigned int neg_adjust = 0; 1504e0444948SSelwin Sebastian 1505e0444948SSelwin Sebastian if (delta < 0) { 1506e0444948SSelwin Sebastian neg_adjust = 1; 1507e0444948SSelwin Sebastian delta = -delta; 1508e0444948SSelwin Sebastian } 1509e0444948SSelwin Sebastian adjust = (uint64_t)pdata->tstamp_addend; 1510e0444948SSelwin Sebastian adjust *= delta; 1511e0444948SSelwin Sebastian diff = (uint32_t)div_u64(adjust, 1000000000UL); 1512e0444948SSelwin Sebastian addend = (neg_adjust) ? pdata->tstamp_addend - diff : 1513e0444948SSelwin Sebastian pdata->tstamp_addend + diff; 1514e0444948SSelwin Sebastian pdata->tstamp_addend = addend; 1515e0444948SSelwin Sebastian axgbe_update_tstamp_addend(pdata, addend); 1516e0444948SSelwin Sebastian return 0; 1517e0444948SSelwin Sebastian } 1518e0444948SSelwin Sebastian 1519e0444948SSelwin Sebastian static int 1520e0444948SSelwin Sebastian axgbe_timesync_adjust_time(struct rte_eth_dev *dev, int64_t delta) 1521e0444948SSelwin Sebastian { 1522e0444948SSelwin Sebastian struct axgbe_port *pdata = dev->data->dev_private; 1523e0444948SSelwin Sebastian struct timespec timestamp_delta; 1524e0444948SSelwin Sebastian 1525e0444948SSelwin Sebastian axgbe_adjfreq(pdata, delta); 1526e0444948SSelwin Sebastian pdata->systime_tc.nsec += delta; 1527e0444948SSelwin Sebastian 1528e0444948SSelwin Sebastian if (delta < 0) { 1529e0444948SSelwin Sebastian delta = -delta; 1530e0444948SSelwin Sebastian timestamp_delta = rte_ns_to_timespec(delta); 1531e0444948SSelwin Sebastian axgbe_update_tstamp_time(pdata, timestamp_delta.tv_sec, 1532e0444948SSelwin Sebastian timestamp_delta.tv_nsec, 1); 1533e0444948SSelwin Sebastian } else { 1534e0444948SSelwin Sebastian timestamp_delta = rte_ns_to_timespec(delta); 1535e0444948SSelwin Sebastian axgbe_update_tstamp_time(pdata, timestamp_delta.tv_sec, 1536e0444948SSelwin Sebastian timestamp_delta.tv_nsec, 0); 1537e0444948SSelwin Sebastian } 1538e0444948SSelwin Sebastian return 0; 1539e0444948SSelwin Sebastian } 1540e0444948SSelwin Sebastian 1541e0444948SSelwin Sebastian static int 1542e0444948SSelwin Sebastian axgbe_timesync_read_time(struct rte_eth_dev *dev, 1543e0444948SSelwin Sebastian struct timespec *timestamp) 1544e0444948SSelwin Sebastian { 1545e0444948SSelwin Sebastian uint64_t nsec; 1546e0444948SSelwin Sebastian struct axgbe_port *pdata = dev->data->dev_private; 1547e0444948SSelwin Sebastian 1548e0444948SSelwin Sebastian nsec = AXGMAC_IOREAD(pdata, MAC_STSR); 1549e0444948SSelwin Sebastian nsec *= NSEC_PER_SEC; 1550e0444948SSelwin Sebastian nsec += AXGMAC_IOREAD(pdata, MAC_STNR); 1551e0444948SSelwin Sebastian *timestamp = rte_ns_to_timespec(nsec); 1552e0444948SSelwin Sebastian return 0; 1553e0444948SSelwin Sebastian } 1554e0444948SSelwin Sebastian static int 1555e0444948SSelwin Sebastian axgbe_timesync_write_time(struct rte_eth_dev *dev, 1556e0444948SSelwin Sebastian const struct timespec *timestamp) 1557e0444948SSelwin Sebastian { 1558e0444948SSelwin Sebastian unsigned int count = 100; 1559e0444948SSelwin Sebastian struct axgbe_port *pdata = dev->data->dev_private; 1560e0444948SSelwin Sebastian 1561e0444948SSelwin Sebastian AXGMAC_IOWRITE(pdata, MAC_STSUR, timestamp->tv_sec); 1562e0444948SSelwin Sebastian AXGMAC_IOWRITE(pdata, MAC_STNUR, timestamp->tv_nsec); 1563e0444948SSelwin Sebastian AXGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSUPDT, 1); 1564e0444948SSelwin Sebastian /* Wait for time update to complete */ 1565e0444948SSelwin Sebastian while (--count && AXGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSUPDT)) 1566e0444948SSelwin Sebastian rte_delay_ms(1); 1567e0444948SSelwin Sebastian if (!count) 1568e0444948SSelwin Sebastian PMD_DRV_LOG(ERR, "Timed out update timestamp\n"); 1569e0444948SSelwin Sebastian return 0; 1570e0444948SSelwin Sebastian } 1571e0444948SSelwin Sebastian 1572e0444948SSelwin Sebastian static void 1573e0444948SSelwin Sebastian axgbe_update_tstamp_addend(struct axgbe_port *pdata, 1574e0444948SSelwin Sebastian uint32_t addend) 1575e0444948SSelwin Sebastian { 1576e0444948SSelwin Sebastian unsigned int count = 100; 1577e0444948SSelwin Sebastian 1578e0444948SSelwin Sebastian AXGMAC_IOWRITE(pdata, MAC_TSAR, addend); 1579e0444948SSelwin Sebastian AXGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSADDREG, 1); 1580e0444948SSelwin Sebastian 1581e0444948SSelwin Sebastian /* Wait for addend update to complete */ 1582e0444948SSelwin Sebastian while (--count && AXGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSADDREG)) 1583e0444948SSelwin Sebastian rte_delay_ms(1); 1584e0444948SSelwin Sebastian if (!count) 1585e0444948SSelwin Sebastian PMD_DRV_LOG(ERR, "Timed out updating timestamp addend register\n"); 1586e0444948SSelwin Sebastian } 1587e0444948SSelwin Sebastian 1588e0444948SSelwin Sebastian static void 1589e0444948SSelwin Sebastian axgbe_set_tstamp_time(struct axgbe_port *pdata, unsigned int sec, 1590e0444948SSelwin Sebastian unsigned int nsec) 1591e0444948SSelwin Sebastian { 1592e0444948SSelwin Sebastian unsigned int count = 100; 1593e0444948SSelwin Sebastian 1594e0444948SSelwin Sebastian /*System Time Sec Update*/ 1595e0444948SSelwin Sebastian AXGMAC_IOWRITE(pdata, MAC_STSUR, sec); 1596e0444948SSelwin Sebastian /*System Time nanoSec Update*/ 1597e0444948SSelwin Sebastian AXGMAC_IOWRITE(pdata, MAC_STNUR, nsec); 1598e0444948SSelwin Sebastian /*Initialize Timestamp*/ 1599e0444948SSelwin Sebastian AXGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSINIT, 1); 1600e0444948SSelwin Sebastian 1601e0444948SSelwin Sebastian /* Wait for time update to complete */ 1602e0444948SSelwin Sebastian while (--count && AXGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSINIT)) 1603e0444948SSelwin Sebastian rte_delay_ms(1); 1604e0444948SSelwin Sebastian if (!count) 1605e0444948SSelwin Sebastian PMD_DRV_LOG(ERR, "Timed out initializing timestamp\n"); 1606e0444948SSelwin Sebastian } 1607e0444948SSelwin Sebastian 1608e0444948SSelwin Sebastian static int 1609e0444948SSelwin Sebastian axgbe_timesync_enable(struct rte_eth_dev *dev) 1610e0444948SSelwin Sebastian { 1611e0444948SSelwin Sebastian struct axgbe_port *pdata = dev->data->dev_private; 1612e0444948SSelwin Sebastian unsigned int mac_tscr = 0; 1613e0444948SSelwin Sebastian uint64_t dividend; 1614e0444948SSelwin Sebastian struct timespec timestamp; 1615e0444948SSelwin Sebastian uint64_t nsec; 1616e0444948SSelwin Sebastian 1617e0444948SSelwin Sebastian /* Set one nano-second accuracy */ 1618e0444948SSelwin Sebastian AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSCTRLSSR, 1); 1619e0444948SSelwin Sebastian 1620e0444948SSelwin Sebastian /* Set fine timestamp update */ 1621e0444948SSelwin Sebastian AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSCFUPDT, 1); 1622e0444948SSelwin Sebastian 1623e0444948SSelwin Sebastian /* Overwrite earlier timestamps */ 1624e0444948SSelwin Sebastian AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TXTSSTSM, 1); 1625e0444948SSelwin Sebastian 1626e0444948SSelwin Sebastian AXGMAC_IOWRITE(pdata, MAC_TSCR, mac_tscr); 1627e0444948SSelwin Sebastian 1628e0444948SSelwin Sebastian /* Enabling processing of ptp over eth pkt */ 1629e0444948SSelwin Sebastian AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1); 1630e0444948SSelwin Sebastian AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1); 1631e0444948SSelwin Sebastian /* Enable timestamp for all pkts*/ 1632e0444948SSelwin Sebastian AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENALL, 1); 1633e0444948SSelwin Sebastian 1634e0444948SSelwin Sebastian /* enabling timestamp */ 1635e0444948SSelwin Sebastian AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1); 1636e0444948SSelwin Sebastian AXGMAC_IOWRITE(pdata, MAC_TSCR, mac_tscr); 1637e0444948SSelwin Sebastian 1638e0444948SSelwin Sebastian /* Exit if timestamping is not enabled */ 1639e0444948SSelwin Sebastian if (!AXGMAC_GET_BITS(mac_tscr, MAC_TSCR, TSENA)) { 1640e0444948SSelwin Sebastian PMD_DRV_LOG(ERR, "Exiting as timestamp is not enabled\n"); 1641e0444948SSelwin Sebastian return 0; 1642e0444948SSelwin Sebastian } 1643e0444948SSelwin Sebastian 1644e0444948SSelwin Sebastian /* Sub-second Increment Value*/ 1645e0444948SSelwin Sebastian AXGMAC_IOWRITE_BITS(pdata, MAC_SSIR, SSINC, AXGBE_TSTAMP_SSINC); 1646e0444948SSelwin Sebastian /* Sub-nanosecond Increment Value */ 1647e0444948SSelwin Sebastian AXGMAC_IOWRITE_BITS(pdata, MAC_SSIR, SNSINC, AXGBE_TSTAMP_SNSINC); 1648e0444948SSelwin Sebastian 1649e0444948SSelwin Sebastian pdata->ptpclk_rate = AXGBE_V2_PTP_CLOCK_FREQ; 1650e0444948SSelwin Sebastian dividend = 50000000; 1651e0444948SSelwin Sebastian dividend <<= 32; 1652e0444948SSelwin Sebastian pdata->tstamp_addend = div_u64(dividend, pdata->ptpclk_rate); 1653e0444948SSelwin Sebastian 1654e0444948SSelwin Sebastian axgbe_update_tstamp_addend(pdata, pdata->tstamp_addend); 1655e0444948SSelwin Sebastian axgbe_set_tstamp_time(pdata, 0, 0); 1656e0444948SSelwin Sebastian 1657e0444948SSelwin Sebastian /* Initialize the timecounter */ 1658e0444948SSelwin Sebastian memset(&pdata->systime_tc, 0, sizeof(struct rte_timecounter)); 1659e0444948SSelwin Sebastian 1660e0444948SSelwin Sebastian pdata->systime_tc.cc_mask = AXGBE_CYCLECOUNTER_MASK; 1661e0444948SSelwin Sebastian pdata->systime_tc.cc_shift = 0; 1662e0444948SSelwin Sebastian pdata->systime_tc.nsec_mask = 0; 1663e0444948SSelwin Sebastian 1664e0444948SSelwin Sebastian PMD_DRV_LOG(DEBUG, "Initializing system time counter with realtime\n"); 1665e0444948SSelwin Sebastian 1666e0444948SSelwin Sebastian /* Updating the counter once with clock real time */ 1667e0444948SSelwin Sebastian clock_gettime(CLOCK_REALTIME, ×tamp); 1668e0444948SSelwin Sebastian nsec = rte_timespec_to_ns(×tamp); 1669e0444948SSelwin Sebastian nsec = rte_timecounter_update(&pdata->systime_tc, nsec); 1670e0444948SSelwin Sebastian axgbe_set_tstamp_time(pdata, timestamp.tv_sec, timestamp.tv_nsec); 1671e0444948SSelwin Sebastian return 0; 1672e0444948SSelwin Sebastian } 1673e0444948SSelwin Sebastian 1674e0444948SSelwin Sebastian static int 1675e0444948SSelwin Sebastian axgbe_timesync_disable(struct rte_eth_dev *dev) 1676e0444948SSelwin Sebastian { 1677e0444948SSelwin Sebastian struct axgbe_port *pdata = dev->data->dev_private; 1678e0444948SSelwin Sebastian unsigned int mac_tscr = 0; 1679e0444948SSelwin Sebastian 1680e0444948SSelwin Sebastian /*disable timestamp for all pkts*/ 1681e0444948SSelwin Sebastian AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENALL, 0); 1682e0444948SSelwin Sebastian /*disable the addened register*/ 1683e0444948SSelwin Sebastian AXGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSADDREG, 0); 1684e0444948SSelwin Sebastian /* disable timestamp update */ 1685e0444948SSelwin Sebastian AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSCFUPDT, 0); 1686e0444948SSelwin Sebastian /*disable time stamp*/ 1687e0444948SSelwin Sebastian AXGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 0); 1688e0444948SSelwin Sebastian return 0; 1689e0444948SSelwin Sebastian } 1690e0444948SSelwin Sebastian 1691e0444948SSelwin Sebastian static int 1692e0444948SSelwin Sebastian axgbe_timesync_read_rx_timestamp(struct rte_eth_dev *dev, 1693e0444948SSelwin Sebastian struct timespec *timestamp, uint32_t flags) 1694e0444948SSelwin Sebastian { 1695e0444948SSelwin Sebastian uint64_t nsec = 0; 1696e0444948SSelwin Sebastian volatile union axgbe_rx_desc *desc; 1697e0444948SSelwin Sebastian uint16_t idx, pmt; 1698e0444948SSelwin Sebastian struct axgbe_rx_queue *rxq = *dev->data->rx_queues; 1699e0444948SSelwin Sebastian 1700e0444948SSelwin Sebastian idx = AXGBE_GET_DESC_IDX(rxq, rxq->cur); 1701e0444948SSelwin Sebastian desc = &rxq->desc[idx]; 1702e0444948SSelwin Sebastian 1703e0444948SSelwin Sebastian while (AXGMAC_GET_BITS_LE(desc->write.desc3, RX_NORMAL_DESC3, OWN)) 1704e0444948SSelwin Sebastian rte_delay_ms(1); 1705e0444948SSelwin Sebastian if (AXGMAC_GET_BITS_LE(desc->write.desc3, RX_NORMAL_DESC3, CTXT)) { 1706e0444948SSelwin Sebastian if (AXGMAC_GET_BITS_LE(desc->write.desc3, RX_CONTEXT_DESC3, TSA) && 1707e0444948SSelwin Sebastian !AXGMAC_GET_BITS_LE(desc->write.desc3, 1708e0444948SSelwin Sebastian RX_CONTEXT_DESC3, TSD)) { 1709e0444948SSelwin Sebastian pmt = AXGMAC_GET_BITS_LE(desc->write.desc3, 1710e0444948SSelwin Sebastian RX_CONTEXT_DESC3, PMT); 1711e0444948SSelwin Sebastian nsec = rte_le_to_cpu_32(desc->write.desc1); 1712e0444948SSelwin Sebastian nsec *= NSEC_PER_SEC; 1713e0444948SSelwin Sebastian nsec += rte_le_to_cpu_32(desc->write.desc0); 1714e0444948SSelwin Sebastian if (nsec != 0xffffffffffffffffULL) { 1715e0444948SSelwin Sebastian if (pmt == 0x01) 1716e0444948SSelwin Sebastian *timestamp = rte_ns_to_timespec(nsec); 1717e0444948SSelwin Sebastian PMD_DRV_LOG(DEBUG, 1718e0444948SSelwin Sebastian "flags = 0x%x nsec = %"PRIu64"\n", 1719e0444948SSelwin Sebastian flags, nsec); 1720e0444948SSelwin Sebastian } 1721e0444948SSelwin Sebastian } 1722e0444948SSelwin Sebastian } 1723e0444948SSelwin Sebastian 1724e0444948SSelwin Sebastian return 0; 1725e0444948SSelwin Sebastian } 1726e0444948SSelwin Sebastian 1727e0444948SSelwin Sebastian static int 1728e0444948SSelwin Sebastian axgbe_timesync_read_tx_timestamp(struct rte_eth_dev *dev, 1729e0444948SSelwin Sebastian struct timespec *timestamp) 1730e0444948SSelwin Sebastian { 1731e0444948SSelwin Sebastian uint64_t nsec; 1732e0444948SSelwin Sebastian struct axgbe_port *pdata = dev->data->dev_private; 1733e0444948SSelwin Sebastian unsigned int tx_snr, tx_ssr; 1734e0444948SSelwin Sebastian 1735e0444948SSelwin Sebastian rte_delay_us(5); 1736e0444948SSelwin Sebastian if (pdata->vdata->tx_tstamp_workaround) { 1737e0444948SSelwin Sebastian tx_snr = AXGMAC_IOREAD(pdata, MAC_TXSNR); 1738e0444948SSelwin Sebastian tx_ssr = AXGMAC_IOREAD(pdata, MAC_TXSSR); 1739e0444948SSelwin Sebastian 1740e0444948SSelwin Sebastian } else { 1741e0444948SSelwin Sebastian tx_ssr = AXGMAC_IOREAD(pdata, MAC_TXSSR); 1742e0444948SSelwin Sebastian tx_snr = AXGMAC_IOREAD(pdata, MAC_TXSNR); 1743e0444948SSelwin Sebastian } 1744e0444948SSelwin Sebastian if (AXGMAC_GET_BITS(tx_snr, MAC_TXSNR, TXTSSTSMIS)) { 1745e0444948SSelwin Sebastian PMD_DRV_LOG(DEBUG, "Waiting for TXTSSTSMIS\n"); 1746e0444948SSelwin Sebastian return 0; 1747e0444948SSelwin Sebastian } 1748e0444948SSelwin Sebastian nsec = tx_ssr; 1749e0444948SSelwin Sebastian nsec *= NSEC_PER_SEC; 1750e0444948SSelwin Sebastian nsec += tx_snr; 1751e0444948SSelwin Sebastian PMD_DRV_LOG(DEBUG, "nsec = %"PRIu64" tx_ssr = %d tx_snr = %d\n", 1752e0444948SSelwin Sebastian nsec, tx_ssr, tx_snr); 1753e0444948SSelwin Sebastian *timestamp = rte_ns_to_timespec(nsec); 1754e0444948SSelwin Sebastian return 0; 1755e0444948SSelwin Sebastian } 1756e0444948SSelwin Sebastian 1757572890efSRavi Kumar static void axgbe_get_all_hw_features(struct axgbe_port *pdata) 1758572890efSRavi Kumar { 1759572890efSRavi Kumar unsigned int mac_hfr0, mac_hfr1, mac_hfr2; 1760572890efSRavi Kumar struct axgbe_hw_features *hw_feat = &pdata->hw_feat; 1761572890efSRavi Kumar 1762572890efSRavi Kumar mac_hfr0 = AXGMAC_IOREAD(pdata, MAC_HWF0R); 1763572890efSRavi Kumar mac_hfr1 = AXGMAC_IOREAD(pdata, MAC_HWF1R); 1764572890efSRavi Kumar mac_hfr2 = AXGMAC_IOREAD(pdata, MAC_HWF2R); 1765572890efSRavi Kumar 1766572890efSRavi Kumar memset(hw_feat, 0, sizeof(*hw_feat)); 1767572890efSRavi Kumar 1768572890efSRavi Kumar hw_feat->version = AXGMAC_IOREAD(pdata, MAC_VR); 1769572890efSRavi Kumar 1770572890efSRavi Kumar /* Hardware feature register 0 */ 1771572890efSRavi Kumar hw_feat->gmii = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, GMIISEL); 1772572890efSRavi Kumar hw_feat->vlhash = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, VLHASH); 1773572890efSRavi Kumar hw_feat->sma = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, SMASEL); 1774572890efSRavi Kumar hw_feat->rwk = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, RWKSEL); 1775572890efSRavi Kumar hw_feat->mgk = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, MGKSEL); 1776572890efSRavi Kumar hw_feat->mmc = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, MMCSEL); 1777572890efSRavi Kumar hw_feat->aoe = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, ARPOFFSEL); 1778572890efSRavi Kumar hw_feat->ts = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TSSEL); 1779572890efSRavi Kumar hw_feat->eee = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, EEESEL); 1780572890efSRavi Kumar hw_feat->tx_coe = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TXCOESEL); 1781572890efSRavi Kumar hw_feat->rx_coe = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, RXCOESEL); 1782572890efSRavi Kumar hw_feat->addn_mac = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, 1783572890efSRavi Kumar ADDMACADRSEL); 1784572890efSRavi Kumar hw_feat->ts_src = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, TSSTSSEL); 1785572890efSRavi Kumar hw_feat->sa_vlan_ins = AXGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, SAVLANINS); 1786572890efSRavi Kumar 1787572890efSRavi Kumar /* Hardware feature register 1 */ 1788572890efSRavi Kumar hw_feat->rx_fifo_size = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, 1789572890efSRavi Kumar RXFIFOSIZE); 1790572890efSRavi Kumar hw_feat->tx_fifo_size = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, 1791572890efSRavi Kumar TXFIFOSIZE); 1792572890efSRavi Kumar hw_feat->adv_ts_hi = AXGMAC_GET_BITS(mac_hfr1, 1793572890efSRavi Kumar MAC_HWF1R, ADVTHWORD); 1794572890efSRavi Kumar hw_feat->dma_width = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, ADDR64); 1795572890efSRavi Kumar hw_feat->dcb = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DCBEN); 1796572890efSRavi Kumar hw_feat->sph = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, SPHEN); 1797572890efSRavi Kumar hw_feat->tso = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, TSOEN); 1798572890efSRavi Kumar hw_feat->dma_debug = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DBGMEMA); 1799572890efSRavi Kumar hw_feat->rss = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, RSSEN); 1800572890efSRavi Kumar hw_feat->tc_cnt = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, NUMTC); 1801572890efSRavi Kumar hw_feat->hash_table_size = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, 1802572890efSRavi Kumar HASHTBLSZ); 1803572890efSRavi Kumar hw_feat->l3l4_filter_num = AXGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, 1804572890efSRavi Kumar L3L4FNUM); 1805572890efSRavi Kumar 1806572890efSRavi Kumar /* Hardware feature register 2 */ 1807572890efSRavi Kumar hw_feat->rx_q_cnt = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, RXQCNT); 1808572890efSRavi Kumar hw_feat->tx_q_cnt = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, TXQCNT); 1809572890efSRavi Kumar hw_feat->rx_ch_cnt = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, RXCHCNT); 1810572890efSRavi Kumar hw_feat->tx_ch_cnt = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, TXCHCNT); 1811572890efSRavi Kumar hw_feat->pps_out_num = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, PPSOUTNUM); 1812572890efSRavi Kumar hw_feat->aux_snap_num = AXGMAC_GET_BITS(mac_hfr2, MAC_HWF2R, 1813572890efSRavi Kumar AUXSNAPNUM); 1814572890efSRavi Kumar 1815572890efSRavi Kumar /* Translate the Hash Table size into actual number */ 1816572890efSRavi Kumar switch (hw_feat->hash_table_size) { 1817572890efSRavi Kumar case 0: 1818572890efSRavi Kumar break; 1819572890efSRavi Kumar case 1: 1820572890efSRavi Kumar hw_feat->hash_table_size = 64; 1821572890efSRavi Kumar break; 1822572890efSRavi Kumar case 2: 1823572890efSRavi Kumar hw_feat->hash_table_size = 128; 1824572890efSRavi Kumar break; 1825572890efSRavi Kumar case 3: 1826572890efSRavi Kumar hw_feat->hash_table_size = 256; 1827572890efSRavi Kumar break; 1828572890efSRavi Kumar } 1829572890efSRavi Kumar 1830572890efSRavi Kumar /* Translate the address width setting into actual number */ 1831572890efSRavi Kumar switch (hw_feat->dma_width) { 1832572890efSRavi Kumar case 0: 1833572890efSRavi Kumar hw_feat->dma_width = 32; 1834572890efSRavi Kumar break; 1835572890efSRavi Kumar case 1: 1836572890efSRavi Kumar hw_feat->dma_width = 40; 1837572890efSRavi Kumar break; 1838572890efSRavi Kumar case 2: 1839572890efSRavi Kumar hw_feat->dma_width = 48; 1840572890efSRavi Kumar break; 1841572890efSRavi Kumar default: 1842572890efSRavi Kumar hw_feat->dma_width = 32; 1843572890efSRavi Kumar } 1844572890efSRavi Kumar 1845572890efSRavi Kumar /* The Queue, Channel and TC counts are zero based so increment them 1846572890efSRavi Kumar * to get the actual number 1847572890efSRavi Kumar */ 1848572890efSRavi Kumar hw_feat->rx_q_cnt++; 1849572890efSRavi Kumar hw_feat->tx_q_cnt++; 1850572890efSRavi Kumar hw_feat->rx_ch_cnt++; 1851572890efSRavi Kumar hw_feat->tx_ch_cnt++; 1852572890efSRavi Kumar hw_feat->tc_cnt++; 1853572890efSRavi Kumar 1854572890efSRavi Kumar /* Translate the fifo sizes into actual numbers */ 1855572890efSRavi Kumar hw_feat->rx_fifo_size = 1 << (hw_feat->rx_fifo_size + 7); 1856572890efSRavi Kumar hw_feat->tx_fifo_size = 1 << (hw_feat->tx_fifo_size + 7); 1857572890efSRavi Kumar } 1858572890efSRavi Kumar 1859572890efSRavi Kumar static void axgbe_init_all_fptrs(struct axgbe_port *pdata) 1860572890efSRavi Kumar { 1861572890efSRavi Kumar axgbe_init_function_ptrs_dev(&pdata->hw_if); 18624ac7516bSRavi Kumar axgbe_init_function_ptrs_phy(&pdata->phy_if); 18634ac7516bSRavi Kumar axgbe_init_function_ptrs_i2c(&pdata->i2c_if); 18644ac7516bSRavi Kumar pdata->vdata->init_function_ptrs_phy_impl(&pdata->phy_if); 1865572890efSRavi Kumar } 1866572890efSRavi Kumar 1867572890efSRavi Kumar static void axgbe_set_counts(struct axgbe_port *pdata) 1868572890efSRavi Kumar { 1869572890efSRavi Kumar /* Set all the function pointers */ 1870572890efSRavi Kumar axgbe_init_all_fptrs(pdata); 1871572890efSRavi Kumar 1872572890efSRavi Kumar /* Populate the hardware features */ 1873572890efSRavi Kumar axgbe_get_all_hw_features(pdata); 1874572890efSRavi Kumar 1875572890efSRavi Kumar /* Set default max values if not provided */ 1876572890efSRavi Kumar if (!pdata->tx_max_channel_count) 1877572890efSRavi Kumar pdata->tx_max_channel_count = pdata->hw_feat.tx_ch_cnt; 1878572890efSRavi Kumar if (!pdata->rx_max_channel_count) 1879572890efSRavi Kumar pdata->rx_max_channel_count = pdata->hw_feat.rx_ch_cnt; 1880572890efSRavi Kumar 1881572890efSRavi Kumar if (!pdata->tx_max_q_count) 1882572890efSRavi Kumar pdata->tx_max_q_count = pdata->hw_feat.tx_q_cnt; 1883572890efSRavi Kumar if (!pdata->rx_max_q_count) 1884572890efSRavi Kumar pdata->rx_max_q_count = pdata->hw_feat.rx_q_cnt; 1885572890efSRavi Kumar 1886572890efSRavi Kumar /* Calculate the number of Tx and Rx rings to be created 1887572890efSRavi Kumar * -Tx (DMA) Channels map 1-to-1 to Tx Queues so set 1888572890efSRavi Kumar * the number of Tx queues to the number of Tx channels 1889572890efSRavi Kumar * enabled 1890572890efSRavi Kumar * -Rx (DMA) Channels do not map 1-to-1 so use the actual 1891572890efSRavi Kumar * number of Rx queues or maximum allowed 1892572890efSRavi Kumar */ 1893572890efSRavi Kumar pdata->tx_ring_count = RTE_MIN(pdata->hw_feat.tx_ch_cnt, 1894572890efSRavi Kumar pdata->tx_max_channel_count); 1895572890efSRavi Kumar pdata->tx_ring_count = RTE_MIN(pdata->tx_ring_count, 1896572890efSRavi Kumar pdata->tx_max_q_count); 1897572890efSRavi Kumar 1898572890efSRavi Kumar pdata->tx_q_count = pdata->tx_ring_count; 1899572890efSRavi Kumar 1900572890efSRavi Kumar pdata->rx_ring_count = RTE_MIN(pdata->hw_feat.rx_ch_cnt, 1901572890efSRavi Kumar pdata->rx_max_channel_count); 1902572890efSRavi Kumar 1903572890efSRavi Kumar pdata->rx_q_count = RTE_MIN(pdata->hw_feat.rx_q_cnt, 1904572890efSRavi Kumar pdata->rx_max_q_count); 1905572890efSRavi Kumar } 1906572890efSRavi Kumar 1907572890efSRavi Kumar static void axgbe_default_config(struct axgbe_port *pdata) 1908572890efSRavi Kumar { 1909572890efSRavi Kumar pdata->pblx8 = DMA_PBL_X8_ENABLE; 1910572890efSRavi Kumar pdata->tx_sf_mode = MTL_TSF_ENABLE; 1911572890efSRavi Kumar pdata->tx_threshold = MTL_TX_THRESHOLD_64; 1912572890efSRavi Kumar pdata->tx_pbl = DMA_PBL_32; 1913572890efSRavi Kumar pdata->tx_osp_mode = DMA_OSP_ENABLE; 1914572890efSRavi Kumar pdata->rx_sf_mode = MTL_RSF_ENABLE; 1915572890efSRavi Kumar pdata->rx_threshold = MTL_RX_THRESHOLD_64; 1916572890efSRavi Kumar pdata->rx_pbl = DMA_PBL_32; 1917572890efSRavi Kumar pdata->pause_autoneg = 1; 1918572890efSRavi Kumar pdata->tx_pause = 0; 1919572890efSRavi Kumar pdata->rx_pause = 0; 1920572890efSRavi Kumar pdata->phy_speed = SPEED_UNKNOWN; 1921572890efSRavi Kumar pdata->power_down = 0; 1922572890efSRavi Kumar } 1923572890efSRavi Kumar 1924991e0b1dSSelwin Sebastian static int 1925991e0b1dSSelwin Sebastian pci_device_cmp(const struct rte_device *dev, const void *_pci_id) 1926991e0b1dSSelwin Sebastian { 1927991e0b1dSSelwin Sebastian const struct rte_pci_device *pdev = RTE_DEV_TO_PCI_CONST(dev); 1928991e0b1dSSelwin Sebastian const struct rte_pci_id *pcid = _pci_id; 1929991e0b1dSSelwin Sebastian 1930991e0b1dSSelwin Sebastian if (pdev->id.vendor_id == AMD_PCI_VENDOR_ID && 1931991e0b1dSSelwin Sebastian pdev->id.device_id == pcid->device_id) 1932991e0b1dSSelwin Sebastian return 0; 1933991e0b1dSSelwin Sebastian return 1; 1934991e0b1dSSelwin Sebastian } 1935991e0b1dSSelwin Sebastian 1936991e0b1dSSelwin Sebastian static bool 1937991e0b1dSSelwin Sebastian pci_search_device(int device_id) 1938991e0b1dSSelwin Sebastian { 1939991e0b1dSSelwin Sebastian struct rte_bus *pci_bus; 1940991e0b1dSSelwin Sebastian struct rte_pci_id dev_id; 1941991e0b1dSSelwin Sebastian 1942991e0b1dSSelwin Sebastian dev_id.device_id = device_id; 1943991e0b1dSSelwin Sebastian pci_bus = rte_bus_find_by_name("pci"); 1944991e0b1dSSelwin Sebastian return (pci_bus != NULL) && 1945991e0b1dSSelwin Sebastian (pci_bus->find_device(NULL, pci_device_cmp, &dev_id) != NULL); 1946991e0b1dSSelwin Sebastian } 1947991e0b1dSSelwin Sebastian 19488691632fSRavi Kumar /* 19498691632fSRavi Kumar * It returns 0 on success. 19508691632fSRavi Kumar */ 19518691632fSRavi Kumar static int 19528691632fSRavi Kumar eth_axgbe_dev_init(struct rte_eth_dev *eth_dev) 19538691632fSRavi Kumar { 19548691632fSRavi Kumar PMD_INIT_FUNC_TRACE(); 19558691632fSRavi Kumar struct axgbe_port *pdata; 19568691632fSRavi Kumar struct rte_pci_device *pci_dev; 1957572890efSRavi Kumar uint32_t reg, mac_lo, mac_hi; 195849a5e622SChandu Babu N uint32_t len; 1959572890efSRavi Kumar int ret; 19608691632fSRavi Kumar 19619e890103SRavi Kumar eth_dev->dev_ops = &axgbe_eth_dev_ops; 1962*479e6a42SThomas Monjalon eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE; 19639e890103SRavi Kumar 1964cbfc6111SFerruh Yigit eth_dev->rx_descriptor_status = axgbe_dev_rx_descriptor_status; 1965cbfc6111SFerruh Yigit eth_dev->tx_descriptor_status = axgbe_dev_tx_descriptor_status; 1966cbfc6111SFerruh Yigit 19678691632fSRavi Kumar /* 19688691632fSRavi Kumar * For secondary processes, we don't initialise any further as primary 19698691632fSRavi Kumar * has already done this work. 19708691632fSRavi Kumar */ 19718691632fSRavi Kumar if (rte_eal_process_type() != RTE_PROC_PRIMARY) 19728691632fSRavi Kumar return 0; 19738691632fSRavi Kumar 19740bc212a8SStephen Hemminger pdata = eth_dev->data->dev_private; 1975572890efSRavi Kumar /* initial state */ 19764693ae4aSJoyce Kong rte_bit_relaxed_set32(AXGBE_DOWN, &pdata->dev_state); 19774693ae4aSJoyce Kong rte_bit_relaxed_set32(AXGBE_STOPPED, &pdata->dev_state); 19788691632fSRavi Kumar pdata->eth_dev = eth_dev; 19798691632fSRavi Kumar 19808691632fSRavi Kumar pci_dev = RTE_DEV_TO_PCI(eth_dev->device); 19818691632fSRavi Kumar pdata->pci_dev = pci_dev; 19828691632fSRavi Kumar 1983991e0b1dSSelwin Sebastian /* 1984991e0b1dSSelwin Sebastian * Use root complex device ID to differentiate RV AXGBE vs SNOWY AXGBE 1985991e0b1dSSelwin Sebastian */ 1986991e0b1dSSelwin Sebastian if (pci_search_device(AMD_PCI_RV_ROOT_COMPLEX_ID)) { 1987991e0b1dSSelwin Sebastian pdata->xpcs_window_def_reg = PCS_V2_RV_WINDOW_DEF; 1988991e0b1dSSelwin Sebastian pdata->xpcs_window_sel_reg = PCS_V2_RV_WINDOW_SELECT; 1989991e0b1dSSelwin Sebastian } else { 1990991e0b1dSSelwin Sebastian pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF; 1991991e0b1dSSelwin Sebastian pdata->xpcs_window_sel_reg = PCS_V2_WINDOW_SELECT; 1992991e0b1dSSelwin Sebastian } 1993991e0b1dSSelwin Sebastian 1994572890efSRavi Kumar pdata->xgmac_regs = 19957784d0d3SRavi Kumar (void *)pci_dev->mem_resource[AXGBE_AXGMAC_BAR].addr; 19967784d0d3SRavi Kumar pdata->xprop_regs = (void *)((uint8_t *)pdata->xgmac_regs 19977784d0d3SRavi Kumar + AXGBE_MAC_PROP_OFFSET); 19987784d0d3SRavi Kumar pdata->xi2c_regs = (void *)((uint8_t *)pdata->xgmac_regs 19997784d0d3SRavi Kumar + AXGBE_I2C_CTRL_OFFSET); 20007784d0d3SRavi Kumar pdata->xpcs_regs = (void *)pci_dev->mem_resource[AXGBE_XPCS_BAR].addr; 2001572890efSRavi Kumar 2002572890efSRavi Kumar /* version specific driver data*/ 2003572890efSRavi Kumar if (pci_dev->id.device_id == AMD_PCI_AXGBE_DEVICE_V2A) 2004572890efSRavi Kumar pdata->vdata = &axgbe_v2a; 2005572890efSRavi Kumar else 2006572890efSRavi Kumar pdata->vdata = &axgbe_v2b; 2007572890efSRavi Kumar 2008572890efSRavi Kumar /* Configure the PCS indirect addressing support */ 2009991e0b1dSSelwin Sebastian reg = XPCS32_IOREAD(pdata, pdata->xpcs_window_def_reg); 2010572890efSRavi Kumar pdata->xpcs_window = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, OFFSET); 2011572890efSRavi Kumar pdata->xpcs_window <<= 6; 2012572890efSRavi Kumar pdata->xpcs_window_size = XPCS_GET_BITS(reg, PCS_V2_WINDOW_DEF, SIZE); 2013572890efSRavi Kumar pdata->xpcs_window_size = 1 << (pdata->xpcs_window_size + 7); 2014572890efSRavi Kumar pdata->xpcs_window_mask = pdata->xpcs_window_size - 1; 2015991e0b1dSSelwin Sebastian 2016572890efSRavi Kumar PMD_INIT_LOG(DEBUG, 2017572890efSRavi Kumar "xpcs window :%x, size :%x, mask :%x ", pdata->xpcs_window, 2018572890efSRavi Kumar pdata->xpcs_window_size, pdata->xpcs_window_mask); 2019572890efSRavi Kumar XP_IOWRITE(pdata, XP_INT_EN, 0x1fffff); 2020572890efSRavi Kumar 2021572890efSRavi Kumar /* Retrieve the MAC address */ 2022572890efSRavi Kumar mac_lo = XP_IOREAD(pdata, XP_MAC_ADDR_LO); 2023572890efSRavi Kumar mac_hi = XP_IOREAD(pdata, XP_MAC_ADDR_HI); 2024572890efSRavi Kumar pdata->mac_addr.addr_bytes[0] = mac_lo & 0xff; 2025572890efSRavi Kumar pdata->mac_addr.addr_bytes[1] = (mac_lo >> 8) & 0xff; 2026572890efSRavi Kumar pdata->mac_addr.addr_bytes[2] = (mac_lo >> 16) & 0xff; 2027572890efSRavi Kumar pdata->mac_addr.addr_bytes[3] = (mac_lo >> 24) & 0xff; 2028572890efSRavi Kumar pdata->mac_addr.addr_bytes[4] = mac_hi & 0xff; 2029572890efSRavi Kumar pdata->mac_addr.addr_bytes[5] = (mac_hi >> 8) & 0xff; 2030572890efSRavi Kumar 203149a5e622SChandu Babu N len = RTE_ETHER_ADDR_LEN * AXGBE_MAX_MAC_ADDRS; 203249a5e622SChandu Babu N eth_dev->data->mac_addrs = rte_zmalloc("axgbe_mac_addr", len, 0); 203349a5e622SChandu Babu N 2034572890efSRavi Kumar if (!eth_dev->data->mac_addrs) { 2035572890efSRavi Kumar PMD_INIT_LOG(ERR, 203649a5e622SChandu Babu N "Failed to alloc %u bytes needed to " 203749a5e622SChandu Babu N "store MAC addresses", len); 2038572890efSRavi Kumar return -ENOMEM; 2039572890efSRavi Kumar } 2040572890efSRavi Kumar 2041e01d9b2eSChandu Babu N /* Allocate memory for storing hash filter MAC addresses */ 2042e01d9b2eSChandu Babu N len = RTE_ETHER_ADDR_LEN * AXGBE_MAX_HASH_MAC_ADDRS; 2043e01d9b2eSChandu Babu N eth_dev->data->hash_mac_addrs = rte_zmalloc("axgbe_hash_mac_addr", 2044e01d9b2eSChandu Babu N len, 0); 2045e01d9b2eSChandu Babu N 2046e01d9b2eSChandu Babu N if (eth_dev->data->hash_mac_addrs == NULL) { 2047e01d9b2eSChandu Babu N PMD_INIT_LOG(ERR, 2048e01d9b2eSChandu Babu N "Failed to allocate %d bytes needed to " 2049e01d9b2eSChandu Babu N "store MAC addresses", len); 2050e01d9b2eSChandu Babu N return -ENOMEM; 2051e01d9b2eSChandu Babu N } 2052e01d9b2eSChandu Babu N 2053538da7a1SOlivier Matz if (!rte_is_valid_assigned_ether_addr(&pdata->mac_addr)) 2054538da7a1SOlivier Matz rte_eth_random_addr(pdata->mac_addr.addr_bytes); 2055572890efSRavi Kumar 2056572890efSRavi Kumar /* Copy the permanent MAC address */ 2057538da7a1SOlivier Matz rte_ether_addr_copy(&pdata->mac_addr, ð_dev->data->mac_addrs[0]); 2058572890efSRavi Kumar 2059572890efSRavi Kumar /* Clock settings */ 2060572890efSRavi Kumar pdata->sysclk_rate = AXGBE_V2_DMA_CLOCK_FREQ; 2061572890efSRavi Kumar pdata->ptpclk_rate = AXGBE_V2_PTP_CLOCK_FREQ; 2062572890efSRavi Kumar 2063572890efSRavi Kumar /* Set the DMA coherency values */ 2064572890efSRavi Kumar pdata->coherent = 1; 2065572890efSRavi Kumar pdata->axdomain = AXGBE_DMA_OS_AXDOMAIN; 2066572890efSRavi Kumar pdata->arcache = AXGBE_DMA_OS_ARCACHE; 2067572890efSRavi Kumar pdata->awcache = AXGBE_DMA_OS_AWCACHE; 2068572890efSRavi Kumar 2069572890efSRavi Kumar /* Set the maximum channels and queues */ 2070572890efSRavi Kumar reg = XP_IOREAD(pdata, XP_PROP_1); 2071572890efSRavi Kumar pdata->tx_max_channel_count = XP_GET_BITS(reg, XP_PROP_1, MAX_TX_DMA); 2072572890efSRavi Kumar pdata->rx_max_channel_count = XP_GET_BITS(reg, XP_PROP_1, MAX_RX_DMA); 2073572890efSRavi Kumar pdata->tx_max_q_count = XP_GET_BITS(reg, XP_PROP_1, MAX_TX_QUEUES); 2074572890efSRavi Kumar pdata->rx_max_q_count = XP_GET_BITS(reg, XP_PROP_1, MAX_RX_QUEUES); 2075572890efSRavi Kumar 2076572890efSRavi Kumar /* Set the hardware channel and queue counts */ 2077572890efSRavi Kumar axgbe_set_counts(pdata); 2078572890efSRavi Kumar 2079572890efSRavi Kumar /* Set the maximum fifo amounts */ 2080572890efSRavi Kumar reg = XP_IOREAD(pdata, XP_PROP_2); 2081572890efSRavi Kumar pdata->tx_max_fifo_size = XP_GET_BITS(reg, XP_PROP_2, TX_FIFO_SIZE); 2082572890efSRavi Kumar pdata->tx_max_fifo_size *= 16384; 2083572890efSRavi Kumar pdata->tx_max_fifo_size = RTE_MIN(pdata->tx_max_fifo_size, 2084572890efSRavi Kumar pdata->vdata->tx_max_fifo_size); 2085572890efSRavi Kumar pdata->rx_max_fifo_size = XP_GET_BITS(reg, XP_PROP_2, RX_FIFO_SIZE); 2086572890efSRavi Kumar pdata->rx_max_fifo_size *= 16384; 2087572890efSRavi Kumar pdata->rx_max_fifo_size = RTE_MIN(pdata->rx_max_fifo_size, 2088572890efSRavi Kumar pdata->vdata->rx_max_fifo_size); 2089572890efSRavi Kumar /* Issue software reset to DMA */ 2090572890efSRavi Kumar ret = pdata->hw_if.exit(pdata); 2091572890efSRavi Kumar if (ret) 2092572890efSRavi Kumar PMD_DRV_LOG(ERR, "hw_if->exit EBUSY error\n"); 2093572890efSRavi Kumar 2094572890efSRavi Kumar /* Set default configuration data */ 2095572890efSRavi Kumar axgbe_default_config(pdata); 2096572890efSRavi Kumar 2097572890efSRavi Kumar /* Set default max values if not provided */ 2098572890efSRavi Kumar if (!pdata->tx_max_fifo_size) 2099572890efSRavi Kumar pdata->tx_max_fifo_size = pdata->hw_feat.tx_fifo_size; 2100572890efSRavi Kumar if (!pdata->rx_max_fifo_size) 2101572890efSRavi Kumar pdata->rx_max_fifo_size = pdata->hw_feat.rx_fifo_size; 2102572890efSRavi Kumar 21039e890103SRavi Kumar pdata->tx_desc_count = AXGBE_MAX_RING_DESC; 21049e890103SRavi Kumar pdata->rx_desc_count = AXGBE_MAX_RING_DESC; 2105572890efSRavi Kumar pthread_mutex_init(&pdata->xpcs_mutex, NULL); 2106572890efSRavi Kumar pthread_mutex_init(&pdata->i2c_mutex, NULL); 2107572890efSRavi Kumar pthread_mutex_init(&pdata->an_mutex, NULL); 2108572890efSRavi Kumar pthread_mutex_init(&pdata->phy_mutex, NULL); 2109572890efSRavi Kumar 21104ac7516bSRavi Kumar ret = pdata->phy_if.phy_init(pdata); 21114ac7516bSRavi Kumar if (ret) { 21124ac7516bSRavi Kumar rte_free(eth_dev->data->mac_addrs); 2113e7f2fa88SDavid Marchand eth_dev->data->mac_addrs = NULL; 21144ac7516bSRavi Kumar return ret; 21154ac7516bSRavi Kumar } 21164ac7516bSRavi Kumar 2117456ff159SRavi Kumar rte_intr_callback_register(&pci_dev->intr_handle, 2118456ff159SRavi Kumar axgbe_dev_interrupt_handler, 2119456ff159SRavi Kumar (void *)eth_dev); 21208691632fSRavi Kumar PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x", 21218691632fSRavi Kumar eth_dev->data->port_id, pci_dev->id.vendor_id, 21228691632fSRavi Kumar pci_dev->id.device_id); 21238691632fSRavi Kumar 21248691632fSRavi Kumar return 0; 21258691632fSRavi Kumar } 21268691632fSRavi Kumar 21278691632fSRavi Kumar static int 2128*479e6a42SThomas Monjalon axgbe_dev_close(struct rte_eth_dev *eth_dev) 21298691632fSRavi Kumar { 2130456ff159SRavi Kumar struct rte_pci_device *pci_dev; 2131456ff159SRavi Kumar 21328691632fSRavi Kumar PMD_INIT_FUNC_TRACE(); 21338691632fSRavi Kumar 2134572890efSRavi Kumar if (rte_eal_process_type() != RTE_PROC_PRIMARY) 2135572890efSRavi Kumar return 0; 2136572890efSRavi Kumar 2137456ff159SRavi Kumar pci_dev = RTE_DEV_TO_PCI(eth_dev->device); 21389e890103SRavi Kumar eth_dev->dev_ops = NULL; 21398590b93dSRavi Kumar eth_dev->rx_pkt_burst = NULL; 21408590b93dSRavi Kumar eth_dev->tx_pkt_burst = NULL; 21419e890103SRavi Kumar axgbe_dev_clear_queues(eth_dev); 2142572890efSRavi Kumar 2143456ff159SRavi Kumar /* disable uio intr before callback unregister */ 2144456ff159SRavi Kumar rte_intr_disable(&pci_dev->intr_handle); 2145456ff159SRavi Kumar rte_intr_callback_unregister(&pci_dev->intr_handle, 2146456ff159SRavi Kumar axgbe_dev_interrupt_handler, 2147456ff159SRavi Kumar (void *)eth_dev); 2148456ff159SRavi Kumar 21498691632fSRavi Kumar return 0; 21508691632fSRavi Kumar } 21518691632fSRavi Kumar 21528691632fSRavi Kumar static int eth_axgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused, 21538691632fSRavi Kumar struct rte_pci_device *pci_dev) 21548691632fSRavi Kumar { 21558691632fSRavi Kumar return rte_eth_dev_pci_generic_probe(pci_dev, 21568691632fSRavi Kumar sizeof(struct axgbe_port), eth_axgbe_dev_init); 21578691632fSRavi Kumar } 21588691632fSRavi Kumar 21598691632fSRavi Kumar static int eth_axgbe_pci_remove(struct rte_pci_device *pci_dev) 21608691632fSRavi Kumar { 2161*479e6a42SThomas Monjalon return rte_eth_dev_pci_generic_remove(pci_dev, axgbe_dev_close); 21628691632fSRavi Kumar } 21638691632fSRavi Kumar 21648691632fSRavi Kumar static struct rte_pci_driver rte_axgbe_pmd = { 21658691632fSRavi Kumar .id_table = pci_id_axgbe_map, 21668691632fSRavi Kumar .drv_flags = RTE_PCI_DRV_NEED_MAPPING, 21678691632fSRavi Kumar .probe = eth_axgbe_pci_probe, 21688691632fSRavi Kumar .remove = eth_axgbe_pci_remove, 21698691632fSRavi Kumar }; 21708691632fSRavi Kumar 21718691632fSRavi Kumar RTE_PMD_REGISTER_PCI(net_axgbe, rte_axgbe_pmd); 21728691632fSRavi Kumar RTE_PMD_REGISTER_PCI_TABLE(net_axgbe, pci_id_axgbe_map); 21738691632fSRavi Kumar RTE_PMD_REGISTER_KMOD_DEP(net_axgbe, "* igb_uio | uio_pci_generic | vfio-pci"); 21749c99878aSJerin Jacob RTE_LOG_REGISTER(axgbe_logtype_init, pmd.net.axgbe.init, NOTICE); 21759c99878aSJerin Jacob RTE_LOG_REGISTER(axgbe_logtype_driver, pmd.net.axgbe.driver, NOTICE); 2176