xref: /dpdk/drivers/net/atlantic/atl_ethdev.c (revision ba6a168a06581b5b3d523f984722a3e5f65bbb82)
15bcf1649SPavel Belous /* SPDX-License-Identifier: BSD-3-Clause
25bcf1649SPavel Belous  * Copyright(c) 2018 Aquantia Corporation
35bcf1649SPavel Belous  */
45bcf1649SPavel Belous 
56723c0fcSBruce Richardson #include <rte_string_fns.h>
6df96fd0dSBruce Richardson #include <ethdev_pci.h>
79f7e206aSPavel Belous #include <rte_alarm.h>
85bcf1649SPavel Belous 
95bcf1649SPavel Belous #include "atl_ethdev.h"
105bcf1649SPavel Belous #include "atl_common.h"
11bb42aa9fSPavel Belous #include "atl_hw_regs.h"
12bb42aa9fSPavel Belous #include "atl_logs.h"
13bb42aa9fSPavel Belous #include "hw_atl/hw_atl_llh.h"
14bb42aa9fSPavel Belous #include "hw_atl/hw_atl_b0.h"
15bb42aa9fSPavel Belous #include "hw_atl/hw_atl_b0_internal.h"
165bcf1649SPavel Belous 
175bcf1649SPavel Belous static int eth_atl_dev_init(struct rte_eth_dev *eth_dev);
185bcf1649SPavel Belous static int  atl_dev_configure(struct rte_eth_dev *dev);
195bcf1649SPavel Belous static int  atl_dev_start(struct rte_eth_dev *dev);
2062024eb8SIvan Ilchenko static int atl_dev_stop(struct rte_eth_dev *dev);
217943ba05SPavel Belous static int  atl_dev_set_link_up(struct rte_eth_dev *dev);
227943ba05SPavel Belous static int  atl_dev_set_link_down(struct rte_eth_dev *dev);
23b142387bSThomas Monjalon static int  atl_dev_close(struct rte_eth_dev *dev);
245bcf1649SPavel Belous static int  atl_dev_reset(struct rte_eth_dev *dev);
259039c812SAndrew Rybchenko static int  atl_dev_promiscuous_enable(struct rte_eth_dev *dev);
269039c812SAndrew Rybchenko static int  atl_dev_promiscuous_disable(struct rte_eth_dev *dev);
27ca041cd4SIvan Ilchenko static int atl_dev_allmulticast_enable(struct rte_eth_dev *dev);
28ca041cd4SIvan Ilchenko static int atl_dev_allmulticast_disable(struct rte_eth_dev *dev);
297943ba05SPavel Belous static int  atl_dev_link_update(struct rte_eth_dev *dev, int wait);
305bcf1649SPavel Belous 
31fbe059e8SPavel Belous static int atl_dev_xstats_get_names(struct rte_eth_dev *dev __rte_unused,
32fbe059e8SPavel Belous 				    struct rte_eth_xstat_name *xstats_names,
33fbe059e8SPavel Belous 				    unsigned int size);
34fbe059e8SPavel Belous 
35fbe059e8SPavel Belous static int atl_dev_stats_get(struct rte_eth_dev *dev,
36fbe059e8SPavel Belous 				struct rte_eth_stats *stats);
37fbe059e8SPavel Belous 
38fbe059e8SPavel Belous static int atl_dev_xstats_get(struct rte_eth_dev *dev,
39fbe059e8SPavel Belous 			      struct rte_eth_xstat *stats, unsigned int n);
40fbe059e8SPavel Belous 
419970a9adSIgor Romanov static int atl_dev_stats_reset(struct rte_eth_dev *dev);
42fbe059e8SPavel Belous 
43bb42aa9fSPavel Belous static int atl_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
44bb42aa9fSPavel Belous 			      size_t fw_size);
45bb42aa9fSPavel Belous 
46*ba6a168aSSivaramakrishnan Venkat static const uint32_t *atl_dev_supported_ptypes_get(struct rte_eth_dev *dev,
47*ba6a168aSSivaramakrishnan Venkat 						    size_t *no_of_elements);
48bb42aa9fSPavel Belous 
494c4340ffSPavel Belous static int atl_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
504c4340ffSPavel Belous 
51f7c2c2c8SPavel Belous /* VLAN stuff */
52f7c2c2c8SPavel Belous static int atl_vlan_filter_set(struct rte_eth_dev *dev,
53f7c2c2c8SPavel Belous 		uint16_t vlan_id, int on);
54f7c2c2c8SPavel Belous 
55f7c2c2c8SPavel Belous static int atl_vlan_offload_set(struct rte_eth_dev *dev, int mask);
56f7c2c2c8SPavel Belous 
57f7c2c2c8SPavel Belous static void atl_vlan_strip_queue_set(struct rte_eth_dev *dev,
58f7c2c2c8SPavel Belous 				     uint16_t queue_id, int on);
59f7c2c2c8SPavel Belous 
60f7c2c2c8SPavel Belous static int atl_vlan_tpid_set(struct rte_eth_dev *dev,
61f7c2c2c8SPavel Belous 			     enum rte_vlan_type vlan_type, uint16_t tpid);
62f7c2c2c8SPavel Belous 
63ce4e8d41SPavel Belous /* EEPROM */
64ce4e8d41SPavel Belous static int atl_dev_get_eeprom_length(struct rte_eth_dev *dev);
65ce4e8d41SPavel Belous static int atl_dev_get_eeprom(struct rte_eth_dev *dev,
66ce4e8d41SPavel Belous 			      struct rte_dev_eeprom_info *eeprom);
67ce4e8d41SPavel Belous static int atl_dev_set_eeprom(struct rte_eth_dev *dev,
68ce4e8d41SPavel Belous 			      struct rte_dev_eeprom_info *eeprom);
69ce4e8d41SPavel Belous 
70ce44e50aSPavel Belous /* Regs */
71ce44e50aSPavel Belous static int atl_dev_get_regs(struct rte_eth_dev *dev,
72ce44e50aSPavel Belous 			    struct rte_dev_reg_info *regs);
73ce44e50aSPavel Belous 
744c1c8f76SPavel Belous /* Flow control */
754c1c8f76SPavel Belous static int atl_flow_ctrl_get(struct rte_eth_dev *dev,
764c1c8f76SPavel Belous 			       struct rte_eth_fc_conf *fc_conf);
774c1c8f76SPavel Belous static int atl_flow_ctrl_set(struct rte_eth_dev *dev,
784c1c8f76SPavel Belous 			       struct rte_eth_fc_conf *fc_conf);
794c1c8f76SPavel Belous 
807943ba05SPavel Belous static void atl_dev_link_status_print(struct rte_eth_dev *dev);
817943ba05SPavel Belous 
827943ba05SPavel Belous /* Interrupts */
837943ba05SPavel Belous static int atl_dev_rxq_interrupt_setup(struct rte_eth_dev *dev);
847943ba05SPavel Belous static int atl_dev_lsc_interrupt_setup(struct rte_eth_dev *dev, uint8_t on);
857943ba05SPavel Belous static int atl_dev_interrupt_get_status(struct rte_eth_dev *dev);
867943ba05SPavel Belous static int atl_dev_interrupt_action(struct rte_eth_dev *dev,
877943ba05SPavel Belous 				    struct rte_intr_handle *handle);
887943ba05SPavel Belous static void atl_dev_interrupt_handler(void *param);
897943ba05SPavel Belous 
90275d21b5SPavel Belous 
91275d21b5SPavel Belous static int atl_add_mac_addr(struct rte_eth_dev *dev,
926d13ea8eSOlivier Matz 			    struct rte_ether_addr *mac_addr,
93275d21b5SPavel Belous 			    uint32_t index, uint32_t pool);
94275d21b5SPavel Belous static void atl_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index);
95275d21b5SPavel Belous static int atl_set_default_mac_addr(struct rte_eth_dev *dev,
966d13ea8eSOlivier Matz 					   struct rte_ether_addr *mac_addr);
97275d21b5SPavel Belous 
98275d21b5SPavel Belous static int atl_dev_set_mc_addr_list(struct rte_eth_dev *dev,
996d13ea8eSOlivier Matz 				    struct rte_ether_addr *mc_addr_set,
100275d21b5SPavel Belous 				    uint32_t nb_mc_addr);
101275d21b5SPavel Belous 
1023af0d308SIgor Russkikh /* RSS */
1033af0d308SIgor Russkikh static int atl_reta_update(struct rte_eth_dev *dev,
1043af0d308SIgor Russkikh 			     struct rte_eth_rss_reta_entry64 *reta_conf,
1053af0d308SIgor Russkikh 			     uint16_t reta_size);
1063af0d308SIgor Russkikh static int atl_reta_query(struct rte_eth_dev *dev,
1073af0d308SIgor Russkikh 			    struct rte_eth_rss_reta_entry64 *reta_conf,
1083af0d308SIgor Russkikh 			    uint16_t reta_size);
1093af0d308SIgor Russkikh static int atl_rss_hash_update(struct rte_eth_dev *dev,
1103af0d308SIgor Russkikh 				 struct rte_eth_rss_conf *rss_conf);
1113af0d308SIgor Russkikh static int atl_rss_hash_conf_get(struct rte_eth_dev *dev,
1123af0d308SIgor Russkikh 				   struct rte_eth_rss_conf *rss_conf);
1133af0d308SIgor Russkikh 
1143af0d308SIgor Russkikh 
1155bcf1649SPavel Belous static int eth_atl_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
1165bcf1649SPavel Belous 	struct rte_pci_device *pci_dev);
1175bcf1649SPavel Belous static int eth_atl_pci_remove(struct rte_pci_device *pci_dev);
1185bcf1649SPavel Belous 
119bdad90d1SIvan Ilchenko static int atl_dev_info_get(struct rte_eth_dev *dev,
1205bcf1649SPavel Belous 				struct rte_eth_dev_info *dev_info);
1215bcf1649SPavel Belous 
1225bcf1649SPavel Belous /*
1235bcf1649SPavel Belous  * The set of PCI devices this driver supports
1245bcf1649SPavel Belous  */
1255bcf1649SPavel Belous static const struct rte_pci_id pci_id_atl_map[] = {
1265bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_0001) },
1275bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_D100) },
1285bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_D107) },
1295bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_D108) },
1305bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_D109) },
1315bcf1649SPavel Belous 
1325bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC100) },
1335bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC107) },
1345bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC108) },
1355bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC109) },
1365bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC111) },
1375bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC112) },
1385bcf1649SPavel Belous 
1395bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC100S) },
1405bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC107S) },
1415bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC108S) },
1425bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC109S) },
1435bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC111S) },
1445bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC112S) },
1455bcf1649SPavel Belous 
1465bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC111E) },
1475bcf1649SPavel Belous 	{ RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC112E) },
1485bcf1649SPavel Belous 	{ .vendor_id = 0, /* sentinel */ },
1495bcf1649SPavel Belous };
1505bcf1649SPavel Belous 
1515bcf1649SPavel Belous static struct rte_pci_driver rte_atl_pmd = {
1525bcf1649SPavel Belous 	.id_table = pci_id_atl_map,
153b76fafb1SDavid Marchand 	.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
1545bcf1649SPavel Belous 	.probe = eth_atl_pci_probe,
1555bcf1649SPavel Belous 	.remove = eth_atl_pci_remove,
1565bcf1649SPavel Belous };
1575bcf1649SPavel Belous 
158295968d1SFerruh Yigit #define ATL_RX_OFFLOADS (RTE_ETH_RX_OFFLOAD_VLAN_STRIP \
159295968d1SFerruh Yigit 			| RTE_ETH_RX_OFFLOAD_IPV4_CKSUM \
160295968d1SFerruh Yigit 			| RTE_ETH_RX_OFFLOAD_UDP_CKSUM \
161295968d1SFerruh Yigit 			| RTE_ETH_RX_OFFLOAD_TCP_CKSUM \
162295968d1SFerruh Yigit 			| RTE_ETH_RX_OFFLOAD_MACSEC_STRIP \
163295968d1SFerruh Yigit 			| RTE_ETH_RX_OFFLOAD_VLAN_FILTER)
1643d38e3dcSIgor Russkikh 
165295968d1SFerruh Yigit #define ATL_TX_OFFLOADS (RTE_ETH_TX_OFFLOAD_VLAN_INSERT \
166295968d1SFerruh Yigit 			| RTE_ETH_TX_OFFLOAD_IPV4_CKSUM \
167295968d1SFerruh Yigit 			| RTE_ETH_TX_OFFLOAD_UDP_CKSUM \
168295968d1SFerruh Yigit 			| RTE_ETH_TX_OFFLOAD_TCP_CKSUM \
169295968d1SFerruh Yigit 			| RTE_ETH_TX_OFFLOAD_TCP_TSO \
170295968d1SFerruh Yigit 			| RTE_ETH_TX_OFFLOAD_MACSEC_INSERT \
171295968d1SFerruh Yigit 			| RTE_ETH_TX_OFFLOAD_MULTI_SEGS)
1722b1472d7SPavel Belous 
173d1093f66SIgor Russkikh #define SFP_EEPROM_SIZE 0x100
174d1093f66SIgor Russkikh 
1753d38e3dcSIgor Russkikh static const struct rte_eth_desc_lim rx_desc_lim = {
1763d38e3dcSIgor Russkikh 	.nb_max = ATL_MAX_RING_DESC,
1773d38e3dcSIgor Russkikh 	.nb_min = ATL_MIN_RING_DESC,
1783d38e3dcSIgor Russkikh 	.nb_align = ATL_RXD_ALIGN,
1793d38e3dcSIgor Russkikh };
1803d38e3dcSIgor Russkikh 
1812b1472d7SPavel Belous static const struct rte_eth_desc_lim tx_desc_lim = {
1822b1472d7SPavel Belous 	.nb_max = ATL_MAX_RING_DESC,
1832b1472d7SPavel Belous 	.nb_min = ATL_MIN_RING_DESC,
1842b1472d7SPavel Belous 	.nb_align = ATL_TXD_ALIGN,
1852b1472d7SPavel Belous 	.nb_seg_max = ATL_TX_MAX_SEG,
1862b1472d7SPavel Belous 	.nb_mtu_seg_max = ATL_TX_MAX_SEG,
1872b1472d7SPavel Belous };
1882b1472d7SPavel Belous 
18909d4dfa8SPavel Belous enum atl_xstats_type {
19009d4dfa8SPavel Belous 	XSTATS_TYPE_MSM = 0,
19109d4dfa8SPavel Belous 	XSTATS_TYPE_MACSEC,
19209d4dfa8SPavel Belous };
19309d4dfa8SPavel Belous 
194fbe059e8SPavel Belous #define ATL_XSTATS_FIELD(name) { \
195fbe059e8SPavel Belous 	#name, \
19609d4dfa8SPavel Belous 	offsetof(struct aq_stats_s, name), \
19709d4dfa8SPavel Belous 	XSTATS_TYPE_MSM \
19809d4dfa8SPavel Belous }
19909d4dfa8SPavel Belous 
20009d4dfa8SPavel Belous #define ATL_MACSEC_XSTATS_FIELD(name) { \
20109d4dfa8SPavel Belous 	#name, \
20209d4dfa8SPavel Belous 	offsetof(struct macsec_stats, name), \
20309d4dfa8SPavel Belous 	XSTATS_TYPE_MACSEC \
204fbe059e8SPavel Belous }
205fbe059e8SPavel Belous 
206fbe059e8SPavel Belous struct atl_xstats_tbl_s {
207fbe059e8SPavel Belous 	const char *name;
208fbe059e8SPavel Belous 	unsigned int offset;
20909d4dfa8SPavel Belous 	enum atl_xstats_type type;
210fbe059e8SPavel Belous };
211fbe059e8SPavel Belous 
212fbe059e8SPavel Belous static struct atl_xstats_tbl_s atl_xstats_tbl[] = {
213fbe059e8SPavel Belous 	ATL_XSTATS_FIELD(uprc),
214fbe059e8SPavel Belous 	ATL_XSTATS_FIELD(mprc),
215fbe059e8SPavel Belous 	ATL_XSTATS_FIELD(bprc),
216fbe059e8SPavel Belous 	ATL_XSTATS_FIELD(erpt),
217fbe059e8SPavel Belous 	ATL_XSTATS_FIELD(uptc),
218fbe059e8SPavel Belous 	ATL_XSTATS_FIELD(mptc),
219fbe059e8SPavel Belous 	ATL_XSTATS_FIELD(bptc),
220fbe059e8SPavel Belous 	ATL_XSTATS_FIELD(erpr),
221fbe059e8SPavel Belous 	ATL_XSTATS_FIELD(ubrc),
222fbe059e8SPavel Belous 	ATL_XSTATS_FIELD(ubtc),
223fbe059e8SPavel Belous 	ATL_XSTATS_FIELD(mbrc),
224fbe059e8SPavel Belous 	ATL_XSTATS_FIELD(mbtc),
225fbe059e8SPavel Belous 	ATL_XSTATS_FIELD(bbrc),
226fbe059e8SPavel Belous 	ATL_XSTATS_FIELD(bbtc),
22709d4dfa8SPavel Belous 	/* Ingress Common Counters */
22809d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_ctl_pkts),
22909d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_tagged_miss_pkts),
23009d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_untagged_miss_pkts),
23109d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_notag_pkts),
23209d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_untagged_pkts),
23309d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_bad_tag_pkts),
23409d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_no_sci_pkts),
23509d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_unknown_sci_pkts),
23609d4dfa8SPavel Belous 	/* Ingress SA Counters */
23709d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_untagged_hit_pkts),
23809d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_not_using_sa),
23909d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_unused_sa),
24009d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_not_valid_pkts),
24109d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_invalid_pkts),
24209d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_ok_pkts),
24309d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_unchecked_pkts),
24409d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_validated_octets),
24509d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(in_decrypted_octets),
24609d4dfa8SPavel Belous 	/* Egress Common Counters */
24709d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(out_ctl_pkts),
24809d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(out_unknown_sa_pkts),
24909d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(out_untagged_pkts),
25009d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(out_too_long),
25109d4dfa8SPavel Belous 	/* Egress SC Counters */
25209d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(out_sc_protected_pkts),
25309d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(out_sc_encrypted_pkts),
25409d4dfa8SPavel Belous 	/* Egress SA Counters */
25509d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(out_sa_hit_drop_redirect),
25609d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(out_sa_protected2_pkts),
25709d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(out_sa_protected_pkts),
25809d4dfa8SPavel Belous 	ATL_MACSEC_XSTATS_FIELD(out_sa_encrypted_pkts),
259fbe059e8SPavel Belous };
260fbe059e8SPavel Belous 
2615bcf1649SPavel Belous static const struct eth_dev_ops atl_eth_dev_ops = {
2625bcf1649SPavel Belous 	.dev_configure	      = atl_dev_configure,
2635bcf1649SPavel Belous 	.dev_start	      = atl_dev_start,
2645bcf1649SPavel Belous 	.dev_stop	      = atl_dev_stop,
2657943ba05SPavel Belous 	.dev_set_link_up      = atl_dev_set_link_up,
2667943ba05SPavel Belous 	.dev_set_link_down    = atl_dev_set_link_down,
2675bcf1649SPavel Belous 	.dev_close	      = atl_dev_close,
2685bcf1649SPavel Belous 	.dev_reset	      = atl_dev_reset,
269bb42aa9fSPavel Belous 
270a9ba50efSPavel Belous 	/* PROMISC */
271a9ba50efSPavel Belous 	.promiscuous_enable   = atl_dev_promiscuous_enable,
272a9ba50efSPavel Belous 	.promiscuous_disable  = atl_dev_promiscuous_disable,
273a9ba50efSPavel Belous 	.allmulticast_enable  = atl_dev_allmulticast_enable,
274a9ba50efSPavel Belous 	.allmulticast_disable = atl_dev_allmulticast_disable,
275a9ba50efSPavel Belous 
2767943ba05SPavel Belous 	/* Link */
2777943ba05SPavel Belous 	.link_update	      = atl_dev_link_update,
2787943ba05SPavel Belous 
279ce44e50aSPavel Belous 	.get_reg              = atl_dev_get_regs,
280ce44e50aSPavel Belous 
281fbe059e8SPavel Belous 	/* Stats */
282fbe059e8SPavel Belous 	.stats_get	      = atl_dev_stats_get,
283fbe059e8SPavel Belous 	.xstats_get	      = atl_dev_xstats_get,
284fbe059e8SPavel Belous 	.xstats_get_names     = atl_dev_xstats_get_names,
285fbe059e8SPavel Belous 	.stats_reset	      = atl_dev_stats_reset,
286fbe059e8SPavel Belous 	.xstats_reset	      = atl_dev_stats_reset,
287fbe059e8SPavel Belous 
288bb42aa9fSPavel Belous 	.fw_version_get       = atl_fw_version_get,
2895bcf1649SPavel Belous 	.dev_infos_get	      = atl_dev_info_get,
2903d38e3dcSIgor Russkikh 	.dev_supported_ptypes_get = atl_dev_supported_ptypes_get,
2913d38e3dcSIgor Russkikh 
2924c4340ffSPavel Belous 	.mtu_set              = atl_dev_mtu_set,
2934c4340ffSPavel Belous 
294f7c2c2c8SPavel Belous 	/* VLAN */
295f7c2c2c8SPavel Belous 	.vlan_filter_set      = atl_vlan_filter_set,
296f7c2c2c8SPavel Belous 	.vlan_offload_set     = atl_vlan_offload_set,
297f7c2c2c8SPavel Belous 	.vlan_tpid_set        = atl_vlan_tpid_set,
298f7c2c2c8SPavel Belous 	.vlan_strip_queue_set = atl_vlan_strip_queue_set,
299f7c2c2c8SPavel Belous 
3003d38e3dcSIgor Russkikh 	/* Queue Control */
3013d38e3dcSIgor Russkikh 	.rx_queue_start	      = atl_rx_queue_start,
3023d38e3dcSIgor Russkikh 	.rx_queue_stop	      = atl_rx_queue_stop,
3033d38e3dcSIgor Russkikh 	.rx_queue_setup       = atl_rx_queue_setup,
3043d38e3dcSIgor Russkikh 	.rx_queue_release     = atl_rx_queue_release,
3052b1472d7SPavel Belous 
3062b1472d7SPavel Belous 	.tx_queue_start	      = atl_tx_queue_start,
3072b1472d7SPavel Belous 	.tx_queue_stop	      = atl_tx_queue_stop,
3082b1472d7SPavel Belous 	.tx_queue_setup       = atl_tx_queue_setup,
3092b1472d7SPavel Belous 	.tx_queue_release     = atl_tx_queue_release,
3107943ba05SPavel Belous 
3117943ba05SPavel Belous 	.rx_queue_intr_enable = atl_dev_rx_queue_intr_enable,
3127943ba05SPavel Belous 	.rx_queue_intr_disable = atl_dev_rx_queue_intr_disable,
313391de329SPavel Belous 
314ce4e8d41SPavel Belous 	/* EEPROM */
315ce4e8d41SPavel Belous 	.get_eeprom_length    = atl_dev_get_eeprom_length,
316ce4e8d41SPavel Belous 	.get_eeprom           = atl_dev_get_eeprom,
317ce4e8d41SPavel Belous 	.set_eeprom           = atl_dev_set_eeprom,
318ce4e8d41SPavel Belous 
3194c1c8f76SPavel Belous 	/* Flow Control */
3204c1c8f76SPavel Belous 	.flow_ctrl_get	      = atl_flow_ctrl_get,
3214c1c8f76SPavel Belous 	.flow_ctrl_set	      = atl_flow_ctrl_set,
3224c1c8f76SPavel Belous 
323275d21b5SPavel Belous 	/* MAC */
324275d21b5SPavel Belous 	.mac_addr_add	      = atl_add_mac_addr,
325275d21b5SPavel Belous 	.mac_addr_remove      = atl_remove_mac_addr,
326275d21b5SPavel Belous 	.mac_addr_set	      = atl_set_default_mac_addr,
327275d21b5SPavel Belous 	.set_mc_addr_list     = atl_dev_set_mc_addr_list,
328391de329SPavel Belous 	.rxq_info_get	      = atl_rxq_info_get,
329391de329SPavel Belous 	.txq_info_get	      = atl_txq_info_get,
3303af0d308SIgor Russkikh 
3313af0d308SIgor Russkikh 	.reta_update          = atl_reta_update,
3323af0d308SIgor Russkikh 	.reta_query           = atl_reta_query,
3333af0d308SIgor Russkikh 	.rss_hash_update      = atl_rss_hash_update,
3343af0d308SIgor Russkikh 	.rss_hash_conf_get    = atl_rss_hash_conf_get,
3355bcf1649SPavel Belous };
3365bcf1649SPavel Belous 
337bb42aa9fSPavel Belous static inline int32_t
atl_reset_hw(struct aq_hw_s * hw)338bb42aa9fSPavel Belous atl_reset_hw(struct aq_hw_s *hw)
339bb42aa9fSPavel Belous {
340bb42aa9fSPavel Belous 	return hw_atl_b0_hw_reset(hw);
341bb42aa9fSPavel Belous }
342bb42aa9fSPavel Belous 
3437943ba05SPavel Belous static inline void
atl_enable_intr(struct rte_eth_dev * dev)3447943ba05SPavel Belous atl_enable_intr(struct rte_eth_dev *dev)
3457943ba05SPavel Belous {
3467943ba05SPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
3477943ba05SPavel Belous 
3487943ba05SPavel Belous 	hw_atl_itr_irq_msk_setlsw_set(hw, 0xffffffff);
3497943ba05SPavel Belous }
3507943ba05SPavel Belous 
3517943ba05SPavel Belous static void
atl_disable_intr(struct aq_hw_s * hw)3527943ba05SPavel Belous atl_disable_intr(struct aq_hw_s *hw)
3537943ba05SPavel Belous {
3547943ba05SPavel Belous 	PMD_INIT_FUNC_TRACE();
3557943ba05SPavel Belous 	hw_atl_itr_irq_msk_clearlsw_set(hw, 0xffffffff);
3567943ba05SPavel Belous }
3577943ba05SPavel Belous 
3585bcf1649SPavel Belous static int
eth_atl_dev_init(struct rte_eth_dev * eth_dev)3595bcf1649SPavel Belous eth_atl_dev_init(struct rte_eth_dev *eth_dev)
3605bcf1649SPavel Belous {
36178e4a0faSStephen Hemminger 	struct atl_adapter *adapter = eth_dev->data->dev_private;
362bb42aa9fSPavel Belous 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
363d61138d4SHarman Kalra 	struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
364bb42aa9fSPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
365bb42aa9fSPavel Belous 	int err = 0;
366bb42aa9fSPavel Belous 
367bb42aa9fSPavel Belous 	PMD_INIT_FUNC_TRACE();
368bb42aa9fSPavel Belous 
3695bcf1649SPavel Belous 	eth_dev->dev_ops = &atl_eth_dev_ops;
370cbfc6111SFerruh Yigit 
371cbfc6111SFerruh Yigit 	eth_dev->rx_queue_count       = atl_rx_queue_count;
372cbfc6111SFerruh Yigit 	eth_dev->rx_descriptor_status = atl_dev_rx_descriptor_status;
373cbfc6111SFerruh Yigit 	eth_dev->tx_descriptor_status = atl_dev_tx_descriptor_status;
374cbfc6111SFerruh Yigit 
375b78958e2SPavel Belous 	eth_dev->rx_pkt_burst = &atl_recv_pkts;
376b78958e2SPavel Belous 	eth_dev->tx_pkt_burst = &atl_xmit_pkts;
377b78958e2SPavel Belous 	eth_dev->tx_pkt_prepare = &atl_prep_pkts;
3785bcf1649SPavel Belous 
379bb42aa9fSPavel Belous 	/* For secondary processes, the primary process has done all the work */
380bb42aa9fSPavel Belous 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
381bb42aa9fSPavel Belous 		return 0;
382bb42aa9fSPavel Belous 
383f30e69b4SFerruh Yigit 	eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
384f30e69b4SFerruh Yigit 
385bb42aa9fSPavel Belous 	/* Vendor and Device ID need to be set before init of shared code */
386bb42aa9fSPavel Belous 	hw->device_id = pci_dev->id.device_id;
387bb42aa9fSPavel Belous 	hw->vendor_id = pci_dev->id.vendor_id;
388bb42aa9fSPavel Belous 	hw->mmio = (void *)pci_dev->mem_resource[0].addr;
389bb42aa9fSPavel Belous 
390bb42aa9fSPavel Belous 	/* Hardware configuration - hardcode */
391bb42aa9fSPavel Belous 	adapter->hw_cfg.is_lro = false;
392bb42aa9fSPavel Belous 	adapter->hw_cfg.wol = false;
3933af0d308SIgor Russkikh 	adapter->hw_cfg.is_rss = false;
3943af0d308SIgor Russkikh 	adapter->hw_cfg.num_rss_queues = HW_ATL_B0_RSS_MAX;
3953af0d308SIgor Russkikh 
3967943ba05SPavel Belous 	adapter->hw_cfg.link_speed_msk = AQ_NIC_RATE_10G |
3977943ba05SPavel Belous 			  AQ_NIC_RATE_5G |
3987943ba05SPavel Belous 			  AQ_NIC_RATE_2G5 |
3997943ba05SPavel Belous 			  AQ_NIC_RATE_1G |
4007943ba05SPavel Belous 			  AQ_NIC_RATE_100M;
401bb42aa9fSPavel Belous 
4024c1c8f76SPavel Belous 	adapter->hw_cfg.flow_control = (AQ_NIC_FC_RX | AQ_NIC_FC_TX);
4033af0d308SIgor Russkikh 	adapter->hw_cfg.aq_rss.indirection_table_size =
4043af0d308SIgor Russkikh 		HW_ATL_B0_RSS_REDIRECTION_MAX;
4053af0d308SIgor Russkikh 
406bb42aa9fSPavel Belous 	hw->aq_nic_cfg = &adapter->hw_cfg;
407bb42aa9fSPavel Belous 
408e9924638SPavel Belous 	pthread_mutex_init(&hw->mbox_mutex, NULL);
409e9924638SPavel Belous 
4107943ba05SPavel Belous 	/* disable interrupt */
4117943ba05SPavel Belous 	atl_disable_intr(hw);
4127943ba05SPavel Belous 
4135bcf1649SPavel Belous 	/* Allocate memory for storing MAC addresses */
41435b2d13fSOlivier Matz 	eth_dev->data->mac_addrs = rte_zmalloc("atlantic",
41535b2d13fSOlivier Matz 					RTE_ETHER_ADDR_LEN, 0);
416bb42aa9fSPavel Belous 	if (eth_dev->data->mac_addrs == NULL) {
417bb42aa9fSPavel Belous 		PMD_INIT_LOG(ERR, "MAC Malloc failed");
4185bcf1649SPavel Belous 		return -ENOMEM;
419bb42aa9fSPavel Belous 	}
4205bcf1649SPavel Belous 
421bb42aa9fSPavel Belous 	err = hw_atl_utils_initfw(hw, &hw->aq_fw_ops);
422bb42aa9fSPavel Belous 	if (err)
423bb42aa9fSPavel Belous 		return err;
424bb42aa9fSPavel Belous 
425bb42aa9fSPavel Belous 	/* Copy the permanent MAC address */
426bb42aa9fSPavel Belous 	if (hw->aq_fw_ops->get_mac_permanent(hw,
427bb42aa9fSPavel Belous 			eth_dev->data->mac_addrs->addr_bytes) != 0)
428bb42aa9fSPavel Belous 		return -EINVAL;
429bb42aa9fSPavel Belous 
430fbe059e8SPavel Belous 	/* Reset the hw statistics */
431fbe059e8SPavel Belous 	atl_dev_stats_reset(eth_dev);
432fbe059e8SPavel Belous 
4337943ba05SPavel Belous 	rte_intr_callback_register(intr_handle,
4347943ba05SPavel Belous 				   atl_dev_interrupt_handler, eth_dev);
4357943ba05SPavel Belous 
4367943ba05SPavel Belous 	/* enable uio/vfio intr/eventfd mapping */
4377943ba05SPavel Belous 	rte_intr_enable(intr_handle);
4387943ba05SPavel Belous 
4397943ba05SPavel Belous 	/* enable support intr */
4407943ba05SPavel Belous 	atl_enable_intr(eth_dev);
4417943ba05SPavel Belous 
442bb42aa9fSPavel Belous 	return err;
4435bcf1649SPavel Belous }
4445bcf1649SPavel Belous 
4455bcf1649SPavel Belous static int
eth_atl_pci_probe(struct rte_pci_driver * pci_drv __rte_unused,struct rte_pci_device * pci_dev)4465bcf1649SPavel Belous eth_atl_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
4475bcf1649SPavel Belous 	struct rte_pci_device *pci_dev)
4485bcf1649SPavel Belous {
4495bcf1649SPavel Belous 	return rte_eth_dev_pci_generic_probe(pci_dev,
4505bcf1649SPavel Belous 		sizeof(struct atl_adapter), eth_atl_dev_init);
4515bcf1649SPavel Belous }
4525bcf1649SPavel Belous 
4535bcf1649SPavel Belous static int
eth_atl_pci_remove(struct rte_pci_device * pci_dev)4545bcf1649SPavel Belous eth_atl_pci_remove(struct rte_pci_device *pci_dev)
4555bcf1649SPavel Belous {
456d1d5d742SThomas Monjalon 	return rte_eth_dev_pci_generic_remove(pci_dev, atl_dev_close);
4575bcf1649SPavel Belous }
4585bcf1649SPavel Belous 
4595bcf1649SPavel Belous static int
atl_dev_configure(struct rte_eth_dev * dev)4607943ba05SPavel Belous atl_dev_configure(struct rte_eth_dev *dev)
4615bcf1649SPavel Belous {
4627943ba05SPavel Belous 	struct atl_interrupt *intr =
4637943ba05SPavel Belous 		ATL_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
4647943ba05SPavel Belous 
4657943ba05SPavel Belous 	PMD_INIT_FUNC_TRACE();
4667943ba05SPavel Belous 
4677943ba05SPavel Belous 	/* set flag to update link status after init */
4687943ba05SPavel Belous 	intr->flags |= ATL_FLAG_NEED_LINK_UPDATE;
4697943ba05SPavel Belous 
4705bcf1649SPavel Belous 	return 0;
4715bcf1649SPavel Belous }
4725bcf1649SPavel Belous 
4735bcf1649SPavel Belous /*
4745bcf1649SPavel Belous  * Configure device link speed and setup link.
4755bcf1649SPavel Belous  * It returns 0 on success.
4765bcf1649SPavel Belous  */
4775bcf1649SPavel Belous static int
atl_dev_start(struct rte_eth_dev * dev)478bb42aa9fSPavel Belous atl_dev_start(struct rte_eth_dev *dev)
4795bcf1649SPavel Belous {
480bb42aa9fSPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
4817943ba05SPavel Belous 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
482d61138d4SHarman Kalra 	struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
4837943ba05SPavel Belous 	uint32_t intr_vector = 0;
484bb42aa9fSPavel Belous 	int status;
485bb42aa9fSPavel Belous 	int err;
486bb42aa9fSPavel Belous 
487bb42aa9fSPavel Belous 	PMD_INIT_FUNC_TRACE();
488bb42aa9fSPavel Belous 
489bb42aa9fSPavel Belous 	/* set adapter started */
490bb42aa9fSPavel Belous 	hw->adapter_stopped = 0;
491bb42aa9fSPavel Belous 
492295968d1SFerruh Yigit 	if (dev->data->dev_conf.link_speeds & RTE_ETH_LINK_SPEED_FIXED) {
4937943ba05SPavel Belous 		PMD_INIT_LOG(ERR,
4947943ba05SPavel Belous 		"Invalid link_speeds for port %u, fix speed not supported",
4957943ba05SPavel Belous 				dev->data->port_id);
4967943ba05SPavel Belous 		return -EINVAL;
4977943ba05SPavel Belous 	}
4987943ba05SPavel Belous 
4997943ba05SPavel Belous 	/* disable uio/vfio intr/eventfd mapping */
5007943ba05SPavel Belous 	rte_intr_disable(intr_handle);
5017943ba05SPavel Belous 
502bb42aa9fSPavel Belous 	/* reinitialize adapter
503bb42aa9fSPavel Belous 	 * this calls reset and start
504bb42aa9fSPavel Belous 	 */
505bb42aa9fSPavel Belous 	status = atl_reset_hw(hw);
506bb42aa9fSPavel Belous 	if (status != 0)
507bb42aa9fSPavel Belous 		return -EIO;
508bb42aa9fSPavel Belous 
509bb42aa9fSPavel Belous 	err = hw_atl_b0_hw_init(hw, dev->data->mac_addrs->addr_bytes);
510bb42aa9fSPavel Belous 
511bb42aa9fSPavel Belous 	hw_atl_b0_hw_start(hw);
5127943ba05SPavel Belous 	/* check and configure queue intr-vector mapping */
5137943ba05SPavel Belous 	if ((rte_intr_cap_multiple(intr_handle) ||
5147943ba05SPavel Belous 	    !RTE_ETH_DEV_SRIOV(dev).active) &&
5157943ba05SPavel Belous 	    dev->data->dev_conf.intr_conf.rxq != 0) {
5167943ba05SPavel Belous 		intr_vector = dev->data->nb_rx_queues;
5177943ba05SPavel Belous 		if (intr_vector > ATL_MAX_INTR_QUEUE_NUM) {
5187943ba05SPavel Belous 			PMD_INIT_LOG(ERR, "At most %d intr queues supported",
5197943ba05SPavel Belous 					ATL_MAX_INTR_QUEUE_NUM);
5207943ba05SPavel Belous 			return -ENOTSUP;
5217943ba05SPavel Belous 		}
5227943ba05SPavel Belous 		if (rte_intr_efd_enable(intr_handle, intr_vector)) {
5237943ba05SPavel Belous 			PMD_INIT_LOG(ERR, "rte_intr_efd_enable failed");
5247943ba05SPavel Belous 			return -1;
5257943ba05SPavel Belous 		}
5267943ba05SPavel Belous 	}
5277943ba05SPavel Belous 
528d61138d4SHarman Kalra 	if (rte_intr_dp_is_en(intr_handle)) {
529d61138d4SHarman Kalra 		if (rte_intr_vec_list_alloc(intr_handle, "intr_vec",
530d61138d4SHarman Kalra 						   dev->data->nb_rx_queues)) {
5317943ba05SPavel Belous 			PMD_INIT_LOG(ERR, "Failed to allocate %d rx_queues"
5327943ba05SPavel Belous 				     " intr_vec", dev->data->nb_rx_queues);
5337943ba05SPavel Belous 			return -ENOMEM;
5347943ba05SPavel Belous 		}
5357943ba05SPavel Belous 	}
5367943ba05SPavel Belous 
537b78958e2SPavel Belous 	/* initialize transmission unit */
538b78958e2SPavel Belous 	atl_tx_init(dev);
539b78958e2SPavel Belous 
540b78958e2SPavel Belous 	/* This can fail when allocating mbufs for descriptor rings */
541b78958e2SPavel Belous 	err = atl_rx_init(dev);
542b78958e2SPavel Belous 	if (err) {
543b78958e2SPavel Belous 		PMD_INIT_LOG(ERR, "Unable to initialize RX hardware");
5443d38e3dcSIgor Russkikh 		goto error;
545b78958e2SPavel Belous 	}
546bb42aa9fSPavel Belous 
547bb42aa9fSPavel Belous 	PMD_INIT_LOG(DEBUG, "FW version: %u.%u.%u",
548bb42aa9fSPavel Belous 		hw->fw_ver_actual >> 24,
549bb42aa9fSPavel Belous 		(hw->fw_ver_actual >> 16) & 0xFF,
550bb42aa9fSPavel Belous 		hw->fw_ver_actual & 0xFFFF);
551bb42aa9fSPavel Belous 	PMD_INIT_LOG(DEBUG, "Driver version: %s", ATL_PMD_DRIVER_VERSION);
552bb42aa9fSPavel Belous 
5533d38e3dcSIgor Russkikh 	err = atl_start_queues(dev);
5543d38e3dcSIgor Russkikh 	if (err < 0) {
5553d38e3dcSIgor Russkikh 		PMD_INIT_LOG(ERR, "Unable to start rxtx queues");
5563d38e3dcSIgor Russkikh 		goto error;
5573d38e3dcSIgor Russkikh 	}
5583d38e3dcSIgor Russkikh 
55951a071cdSIgor Russkikh 	err = atl_dev_set_link_up(dev);
56051a071cdSIgor Russkikh 
5617943ba05SPavel Belous 	err = hw->aq_fw_ops->update_link_status(hw);
5627943ba05SPavel Belous 
5637943ba05SPavel Belous 	if (err)
5647943ba05SPavel Belous 		goto error;
5657943ba05SPavel Belous 
5667943ba05SPavel Belous 	dev->data->dev_link.link_status = hw->aq_link_status.mbps != 0;
5677943ba05SPavel Belous 
5687943ba05SPavel Belous 	if (rte_intr_allow_others(intr_handle)) {
5697943ba05SPavel Belous 		/* check if lsc interrupt is enabled */
5707943ba05SPavel Belous 		if (dev->data->dev_conf.intr_conf.lsc != 0)
5717943ba05SPavel Belous 			atl_dev_lsc_interrupt_setup(dev, true);
5727943ba05SPavel Belous 		else
5737943ba05SPavel Belous 			atl_dev_lsc_interrupt_setup(dev, false);
5747943ba05SPavel Belous 	} else {
5757943ba05SPavel Belous 		rte_intr_callback_unregister(intr_handle,
5767943ba05SPavel Belous 					     atl_dev_interrupt_handler, dev);
5777943ba05SPavel Belous 		if (dev->data->dev_conf.intr_conf.lsc != 0)
5787943ba05SPavel Belous 			PMD_INIT_LOG(INFO, "lsc won't enable because of"
5797943ba05SPavel Belous 				     " no intr multiplex");
5807943ba05SPavel Belous 	}
5817943ba05SPavel Belous 
5827943ba05SPavel Belous 	/* check if rxq interrupt is enabled */
5837943ba05SPavel Belous 	if (dev->data->dev_conf.intr_conf.rxq != 0 &&
5847943ba05SPavel Belous 	    rte_intr_dp_is_en(intr_handle))
5857943ba05SPavel Belous 		atl_dev_rxq_interrupt_setup(dev);
5867943ba05SPavel Belous 
5877943ba05SPavel Belous 	/* enable uio/vfio intr/eventfd mapping */
5887943ba05SPavel Belous 	rte_intr_enable(intr_handle);
5897943ba05SPavel Belous 
5907943ba05SPavel Belous 	/* resume enabled intr since hw reset */
5917943ba05SPavel Belous 	atl_enable_intr(dev);
5927943ba05SPavel Belous 
5933d38e3dcSIgor Russkikh 	return 0;
5943d38e3dcSIgor Russkikh 
5953d38e3dcSIgor Russkikh error:
5963d38e3dcSIgor Russkikh 	atl_stop_queues(dev);
5973d38e3dcSIgor Russkikh 	return -EIO;
5985bcf1649SPavel Belous }
5995bcf1649SPavel Belous 
6005bcf1649SPavel Belous /*
6015bcf1649SPavel Belous  * Stop device: disable rx and tx functions to allow for reconfiguring.
6025bcf1649SPavel Belous  */
60362024eb8SIvan Ilchenko static int
atl_dev_stop(struct rte_eth_dev * dev)604bb42aa9fSPavel Belous atl_dev_stop(struct rte_eth_dev *dev)
6055bcf1649SPavel Belous {
6067943ba05SPavel Belous 	struct rte_eth_link link;
607bb42aa9fSPavel Belous 	struct aq_hw_s *hw =
608bb42aa9fSPavel Belous 		ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
6097943ba05SPavel Belous 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
610d61138d4SHarman Kalra 	struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
6117943ba05SPavel Belous 
6127943ba05SPavel Belous 	PMD_INIT_FUNC_TRACE();
613b8f5d2aeSThomas Monjalon 	dev->data->dev_started = 0;
6147943ba05SPavel Belous 
6157943ba05SPavel Belous 	/* disable interrupts */
6167943ba05SPavel Belous 	atl_disable_intr(hw);
617bb42aa9fSPavel Belous 
618bb42aa9fSPavel Belous 	/* reset the NIC */
619bb42aa9fSPavel Belous 	atl_reset_hw(hw);
620bb42aa9fSPavel Belous 	hw->adapter_stopped = 1;
6213d38e3dcSIgor Russkikh 
6223d38e3dcSIgor Russkikh 	atl_stop_queues(dev);
6233d38e3dcSIgor Russkikh 
6243d38e3dcSIgor Russkikh 	/* Clear stored conf */
6253d38e3dcSIgor Russkikh 	dev->data->scattered_rx = 0;
6263d38e3dcSIgor Russkikh 	dev->data->lro = 0;
6277943ba05SPavel Belous 
6287943ba05SPavel Belous 	/* Clear recorded link status */
6297943ba05SPavel Belous 	memset(&link, 0, sizeof(link));
6307943ba05SPavel Belous 	rte_eth_linkstatus_set(dev, &link);
6317943ba05SPavel Belous 
6327943ba05SPavel Belous 	if (!rte_intr_allow_others(intr_handle))
6337943ba05SPavel Belous 		/* resume to the default handler */
6347943ba05SPavel Belous 		rte_intr_callback_register(intr_handle,
6357943ba05SPavel Belous 					   atl_dev_interrupt_handler,
6367943ba05SPavel Belous 					   (void *)dev);
6377943ba05SPavel Belous 
6387943ba05SPavel Belous 	/* Clean datapath event and queue/vec mapping */
6397943ba05SPavel Belous 	rte_intr_efd_disable(intr_handle);
640d61138d4SHarman Kalra 	rte_intr_vec_list_free(intr_handle);
64162024eb8SIvan Ilchenko 
64262024eb8SIvan Ilchenko 	return 0;
6437943ba05SPavel Belous }
6447943ba05SPavel Belous 
6457943ba05SPavel Belous /*
6467943ba05SPavel Belous  * Set device link up: enable tx.
6477943ba05SPavel Belous  */
6487943ba05SPavel Belous static int
atl_dev_set_link_up(struct rte_eth_dev * dev)6497943ba05SPavel Belous atl_dev_set_link_up(struct rte_eth_dev *dev)
6507943ba05SPavel Belous {
6517943ba05SPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
65251a071cdSIgor Russkikh 	uint32_t link_speeds = dev->data->dev_conf.link_speeds;
65351a071cdSIgor Russkikh 	uint32_t speed_mask = 0;
6547943ba05SPavel Belous 
655295968d1SFerruh Yigit 	if (link_speeds == RTE_ETH_LINK_SPEED_AUTONEG) {
65651a071cdSIgor Russkikh 		speed_mask = hw->aq_nic_cfg->link_speed_msk;
65751a071cdSIgor Russkikh 	} else {
658295968d1SFerruh Yigit 		if (link_speeds & RTE_ETH_LINK_SPEED_10G)
65951a071cdSIgor Russkikh 			speed_mask |= AQ_NIC_RATE_10G;
660295968d1SFerruh Yigit 		if (link_speeds & RTE_ETH_LINK_SPEED_5G)
66151a071cdSIgor Russkikh 			speed_mask |= AQ_NIC_RATE_5G;
662295968d1SFerruh Yigit 		if (link_speeds & RTE_ETH_LINK_SPEED_1G)
66351a071cdSIgor Russkikh 			speed_mask |= AQ_NIC_RATE_1G;
664295968d1SFerruh Yigit 		if (link_speeds & RTE_ETH_LINK_SPEED_2_5G)
66551a071cdSIgor Russkikh 			speed_mask |=  AQ_NIC_RATE_2G5;
666295968d1SFerruh Yigit 		if (link_speeds & RTE_ETH_LINK_SPEED_100M)
66751a071cdSIgor Russkikh 			speed_mask |= AQ_NIC_RATE_100M;
66851a071cdSIgor Russkikh 	}
66951a071cdSIgor Russkikh 
67051a071cdSIgor Russkikh 	return hw->aq_fw_ops->set_link_speed(hw, speed_mask);
6717943ba05SPavel Belous }
6727943ba05SPavel Belous 
6737943ba05SPavel Belous /*
6747943ba05SPavel Belous  * Set device link down: disable tx.
6757943ba05SPavel Belous  */
6767943ba05SPavel Belous static int
atl_dev_set_link_down(struct rte_eth_dev * dev)6777943ba05SPavel Belous atl_dev_set_link_down(struct rte_eth_dev *dev)
6787943ba05SPavel Belous {
6797943ba05SPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
6807943ba05SPavel Belous 
6817943ba05SPavel Belous 	return hw->aq_fw_ops->set_link_speed(hw, 0);
6825bcf1649SPavel Belous }
6835bcf1649SPavel Belous 
6845bcf1649SPavel Belous /*
6855bcf1649SPavel Belous  * Reset and stop device.
6865bcf1649SPavel Belous  */
687b142387bSThomas Monjalon static int
atl_dev_close(struct rte_eth_dev * dev)688bb42aa9fSPavel Belous atl_dev_close(struct rte_eth_dev *dev)
6895bcf1649SPavel Belous {
690d1d5d742SThomas Monjalon 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
691d61138d4SHarman Kalra 	struct rte_intr_handle *intr_handle = pci_dev->intr_handle;
692d1d5d742SThomas Monjalon 	struct aq_hw_s *hw;
69362024eb8SIvan Ilchenko 	int ret;
694d1d5d742SThomas Monjalon 
695bb42aa9fSPavel Belous 	PMD_INIT_FUNC_TRACE();
696bb42aa9fSPavel Belous 
697d1d5d742SThomas Monjalon 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
698d1d5d742SThomas Monjalon 		return 0;
699d1d5d742SThomas Monjalon 
700d1d5d742SThomas Monjalon 	hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
701d1d5d742SThomas Monjalon 
70262024eb8SIvan Ilchenko 	ret = atl_dev_stop(dev);
7033d38e3dcSIgor Russkikh 
7043d38e3dcSIgor Russkikh 	atl_free_queues(dev);
705b142387bSThomas Monjalon 
706d1d5d742SThomas Monjalon 	/* disable uio intr before callback unregister */
707d1d5d742SThomas Monjalon 	rte_intr_disable(intr_handle);
708d1d5d742SThomas Monjalon 	rte_intr_callback_unregister(intr_handle,
709d1d5d742SThomas Monjalon 				     atl_dev_interrupt_handler, dev);
710d1d5d742SThomas Monjalon 
711d1d5d742SThomas Monjalon 	pthread_mutex_destroy(&hw->mbox_mutex);
712d1d5d742SThomas Monjalon 
71362024eb8SIvan Ilchenko 	return ret;
7145bcf1649SPavel Belous }
7155bcf1649SPavel Belous 
7165bcf1649SPavel Belous static int
atl_dev_reset(struct rte_eth_dev * dev)7175bcf1649SPavel Belous atl_dev_reset(struct rte_eth_dev *dev)
7185bcf1649SPavel Belous {
7195bcf1649SPavel Belous 	int ret;
7205bcf1649SPavel Belous 
721d1d5d742SThomas Monjalon 	ret = atl_dev_close(dev);
7225bcf1649SPavel Belous 	if (ret)
7235bcf1649SPavel Belous 		return ret;
7245bcf1649SPavel Belous 
7255bcf1649SPavel Belous 	ret = eth_atl_dev_init(dev);
7265bcf1649SPavel Belous 
7275bcf1649SPavel Belous 	return ret;
7285bcf1649SPavel Belous }
7295bcf1649SPavel Belous 
7309f7e206aSPavel Belous static int
atl_dev_configure_macsec(struct rte_eth_dev * dev)7319f7e206aSPavel Belous atl_dev_configure_macsec(struct rte_eth_dev *dev)
7329f7e206aSPavel Belous {
7339f7e206aSPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
7349f7e206aSPavel Belous 	struct aq_hw_cfg_s *cf = ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
7359f7e206aSPavel Belous 	struct aq_macsec_config *aqcfg = &cf->aq_macsec;
7369f7e206aSPavel Belous 	struct macsec_msg_fw_request msg_macsec;
7379f7e206aSPavel Belous 	struct macsec_msg_fw_response response;
7389f7e206aSPavel Belous 
7399f7e206aSPavel Belous 	if (!aqcfg->common.macsec_enabled ||
7409f7e206aSPavel Belous 	    hw->aq_fw_ops->send_macsec_req == NULL)
7419f7e206aSPavel Belous 		return 0;
7429f7e206aSPavel Belous 
7439f7e206aSPavel Belous 	memset(&msg_macsec, 0, sizeof(msg_macsec));
7449f7e206aSPavel Belous 
7459f7e206aSPavel Belous 	/* Creating set of sc/sa structures from parameters provided by DPDK */
7469f7e206aSPavel Belous 
7479f7e206aSPavel Belous 	/* Configure macsec */
7489f7e206aSPavel Belous 	msg_macsec.msg_type = macsec_cfg_msg;
7499f7e206aSPavel Belous 	msg_macsec.cfg.enabled = aqcfg->common.macsec_enabled;
7509f7e206aSPavel Belous 	msg_macsec.cfg.interrupts_enabled = 1;
7519f7e206aSPavel Belous 
7529f7e206aSPavel Belous 	hw->aq_fw_ops->send_macsec_req(hw, &msg_macsec, &response);
7539f7e206aSPavel Belous 
7549f7e206aSPavel Belous 	if (response.result)
7559f7e206aSPavel Belous 		return -1;
7569f7e206aSPavel Belous 
7579f7e206aSPavel Belous 	memset(&msg_macsec, 0, sizeof(msg_macsec));
7589f7e206aSPavel Belous 
7599f7e206aSPavel Belous 	/* Configure TX SC */
7609f7e206aSPavel Belous 
7619f7e206aSPavel Belous 	msg_macsec.msg_type = macsec_add_tx_sc_msg;
7629f7e206aSPavel Belous 	msg_macsec.txsc.index = 0; /* TXSC always one (??) */
7639f7e206aSPavel Belous 	msg_macsec.txsc.protect = aqcfg->common.encryption_enabled;
7649f7e206aSPavel Belous 
7659f7e206aSPavel Belous 	/* MAC addr for TX */
7669f7e206aSPavel Belous 	msg_macsec.txsc.mac_sa[0] = rte_bswap32(aqcfg->txsc.mac[1]);
7679f7e206aSPavel Belous 	msg_macsec.txsc.mac_sa[1] = rte_bswap32(aqcfg->txsc.mac[0]);
7689f7e206aSPavel Belous 	msg_macsec.txsc.sa_mask = 0x3f;
7699f7e206aSPavel Belous 
7709f7e206aSPavel Belous 	msg_macsec.txsc.da_mask = 0;
7719f7e206aSPavel Belous 	msg_macsec.txsc.tci = 0x0B;
7729f7e206aSPavel Belous 	msg_macsec.txsc.curr_an = 0; /* SA index which currently used */
7739f7e206aSPavel Belous 
7749f7e206aSPavel Belous 	/*
7759f7e206aSPavel Belous 	 * Creating SCI (Secure Channel Identifier).
7769f7e206aSPavel Belous 	 * SCI constructed from Source MAC and Port identifier
7779f7e206aSPavel Belous 	 */
7789f7e206aSPavel Belous 	uint32_t sci_hi_part = (msg_macsec.txsc.mac_sa[1] << 16) |
7799f7e206aSPavel Belous 			       (msg_macsec.txsc.mac_sa[0] >> 16);
7809f7e206aSPavel Belous 	uint32_t sci_low_part = (msg_macsec.txsc.mac_sa[0] << 16);
7819f7e206aSPavel Belous 
7829f7e206aSPavel Belous 	uint32_t port_identifier = 1;
7839f7e206aSPavel Belous 
7849f7e206aSPavel Belous 	msg_macsec.txsc.sci[1] = sci_hi_part;
7859f7e206aSPavel Belous 	msg_macsec.txsc.sci[0] = sci_low_part | port_identifier;
7869f7e206aSPavel Belous 
7879f7e206aSPavel Belous 	hw->aq_fw_ops->send_macsec_req(hw, &msg_macsec, &response);
7889f7e206aSPavel Belous 
7899f7e206aSPavel Belous 	if (response.result)
7909f7e206aSPavel Belous 		return -1;
7919f7e206aSPavel Belous 
7929f7e206aSPavel Belous 	memset(&msg_macsec, 0, sizeof(msg_macsec));
7939f7e206aSPavel Belous 
7949f7e206aSPavel Belous 	/* Configure RX SC */
7959f7e206aSPavel Belous 
7969f7e206aSPavel Belous 	msg_macsec.msg_type = macsec_add_rx_sc_msg;
7979f7e206aSPavel Belous 	msg_macsec.rxsc.index = aqcfg->rxsc.pi;
7989f7e206aSPavel Belous 	msg_macsec.rxsc.replay_protect =
7999f7e206aSPavel Belous 		aqcfg->common.replay_protection_enabled;
8009f7e206aSPavel Belous 	msg_macsec.rxsc.anti_replay_window = 0;
8019f7e206aSPavel Belous 
8029f7e206aSPavel Belous 	/* MAC addr for RX */
8039f7e206aSPavel Belous 	msg_macsec.rxsc.mac_da[0] = rte_bswap32(aqcfg->rxsc.mac[1]);
8049f7e206aSPavel Belous 	msg_macsec.rxsc.mac_da[1] = rte_bswap32(aqcfg->rxsc.mac[0]);
8059f7e206aSPavel Belous 	msg_macsec.rxsc.da_mask = 0;//0x3f;
8069f7e206aSPavel Belous 
8079f7e206aSPavel Belous 	msg_macsec.rxsc.sa_mask = 0;
8089f7e206aSPavel Belous 
8099f7e206aSPavel Belous 	hw->aq_fw_ops->send_macsec_req(hw, &msg_macsec, &response);
8109f7e206aSPavel Belous 
8119f7e206aSPavel Belous 	if (response.result)
8129f7e206aSPavel Belous 		return -1;
8139f7e206aSPavel Belous 
8149f7e206aSPavel Belous 	memset(&msg_macsec, 0, sizeof(msg_macsec));
8159f7e206aSPavel Belous 
8169f7e206aSPavel Belous 	/* Configure RX SC */
8179f7e206aSPavel Belous 
8189f7e206aSPavel Belous 	msg_macsec.msg_type = macsec_add_tx_sa_msg;
8199f7e206aSPavel Belous 	msg_macsec.txsa.index = aqcfg->txsa.idx;
8209f7e206aSPavel Belous 	msg_macsec.txsa.next_pn = aqcfg->txsa.pn;
8219f7e206aSPavel Belous 
8229f7e206aSPavel Belous 	msg_macsec.txsa.key[0] = rte_bswap32(aqcfg->txsa.key[3]);
8239f7e206aSPavel Belous 	msg_macsec.txsa.key[1] = rte_bswap32(aqcfg->txsa.key[2]);
8249f7e206aSPavel Belous 	msg_macsec.txsa.key[2] = rte_bswap32(aqcfg->txsa.key[1]);
8259f7e206aSPavel Belous 	msg_macsec.txsa.key[3] = rte_bswap32(aqcfg->txsa.key[0]);
8269f7e206aSPavel Belous 
8279f7e206aSPavel Belous 	hw->aq_fw_ops->send_macsec_req(hw, &msg_macsec, &response);
8289f7e206aSPavel Belous 
8299f7e206aSPavel Belous 	if (response.result)
8309f7e206aSPavel Belous 		return -1;
8319f7e206aSPavel Belous 
8329f7e206aSPavel Belous 	memset(&msg_macsec, 0, sizeof(msg_macsec));
8339f7e206aSPavel Belous 
8349f7e206aSPavel Belous 	/* Configure RX SA */
8359f7e206aSPavel Belous 
8369f7e206aSPavel Belous 	msg_macsec.msg_type = macsec_add_rx_sa_msg;
8379f7e206aSPavel Belous 	msg_macsec.rxsa.index = aqcfg->rxsa.idx;
8389f7e206aSPavel Belous 	msg_macsec.rxsa.next_pn = aqcfg->rxsa.pn;
8399f7e206aSPavel Belous 
8409f7e206aSPavel Belous 	msg_macsec.rxsa.key[0] = rte_bswap32(aqcfg->rxsa.key[3]);
8419f7e206aSPavel Belous 	msg_macsec.rxsa.key[1] = rte_bswap32(aqcfg->rxsa.key[2]);
8429f7e206aSPavel Belous 	msg_macsec.rxsa.key[2] = rte_bswap32(aqcfg->rxsa.key[1]);
8439f7e206aSPavel Belous 	msg_macsec.rxsa.key[3] = rte_bswap32(aqcfg->rxsa.key[0]);
8449f7e206aSPavel Belous 
8459f7e206aSPavel Belous 	hw->aq_fw_ops->send_macsec_req(hw, &msg_macsec, &response);
8469f7e206aSPavel Belous 
8479f7e206aSPavel Belous 	if (response.result)
8489f7e206aSPavel Belous 		return -1;
8499f7e206aSPavel Belous 
8509f7e206aSPavel Belous 	return 0;
8519f7e206aSPavel Belous }
8529f7e206aSPavel Belous 
atl_macsec_enable(struct rte_eth_dev * dev,uint8_t encr,uint8_t repl_prot)853ec0dec44SPavel Belous int atl_macsec_enable(struct rte_eth_dev *dev,
854ec0dec44SPavel Belous 		      uint8_t encr, uint8_t repl_prot)
855ec0dec44SPavel Belous {
856ec0dec44SPavel Belous 	struct aq_hw_cfg_s *cfg =
857ec0dec44SPavel Belous 		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
858ec0dec44SPavel Belous 
859ec0dec44SPavel Belous 	cfg->aq_macsec.common.macsec_enabled = 1;
860ec0dec44SPavel Belous 	cfg->aq_macsec.common.encryption_enabled = encr;
861ec0dec44SPavel Belous 	cfg->aq_macsec.common.replay_protection_enabled = repl_prot;
862ec0dec44SPavel Belous 
863ec0dec44SPavel Belous 	return 0;
864ec0dec44SPavel Belous }
865ec0dec44SPavel Belous 
atl_macsec_disable(struct rte_eth_dev * dev)866ec0dec44SPavel Belous int atl_macsec_disable(struct rte_eth_dev *dev)
867ec0dec44SPavel Belous {
868ec0dec44SPavel Belous 	struct aq_hw_cfg_s *cfg =
869ec0dec44SPavel Belous 		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
870ec0dec44SPavel Belous 
871ec0dec44SPavel Belous 	cfg->aq_macsec.common.macsec_enabled = 0;
872ec0dec44SPavel Belous 
873ec0dec44SPavel Belous 	return 0;
874ec0dec44SPavel Belous }
875ec0dec44SPavel Belous 
atl_macsec_config_txsc(struct rte_eth_dev * dev,uint8_t * mac)876ec0dec44SPavel Belous int atl_macsec_config_txsc(struct rte_eth_dev *dev, uint8_t *mac)
877ec0dec44SPavel Belous {
878ec0dec44SPavel Belous 	struct aq_hw_cfg_s *cfg =
879ec0dec44SPavel Belous 		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
880ec0dec44SPavel Belous 
881ec0dec44SPavel Belous 	memset(&cfg->aq_macsec.txsc.mac, 0, sizeof(cfg->aq_macsec.txsc.mac));
88235b2d13fSOlivier Matz 	memcpy((uint8_t *)&cfg->aq_macsec.txsc.mac + 2, mac,
88335b2d13fSOlivier Matz 		RTE_ETHER_ADDR_LEN);
884ec0dec44SPavel Belous 
885ec0dec44SPavel Belous 	return 0;
886ec0dec44SPavel Belous }
887ec0dec44SPavel Belous 
atl_macsec_config_rxsc(struct rte_eth_dev * dev,uint8_t * mac,uint16_t pi)888ec0dec44SPavel Belous int atl_macsec_config_rxsc(struct rte_eth_dev *dev,
889ec0dec44SPavel Belous 			   uint8_t *mac, uint16_t pi)
890ec0dec44SPavel Belous {
891ec0dec44SPavel Belous 	struct aq_hw_cfg_s *cfg =
892ec0dec44SPavel Belous 		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
893ec0dec44SPavel Belous 
894ec0dec44SPavel Belous 	memset(&cfg->aq_macsec.rxsc.mac, 0, sizeof(cfg->aq_macsec.rxsc.mac));
89535b2d13fSOlivier Matz 	memcpy((uint8_t *)&cfg->aq_macsec.rxsc.mac + 2, mac,
89635b2d13fSOlivier Matz 		RTE_ETHER_ADDR_LEN);
897ec0dec44SPavel Belous 	cfg->aq_macsec.rxsc.pi = pi;
898ec0dec44SPavel Belous 
899ec0dec44SPavel Belous 	return 0;
900ec0dec44SPavel Belous }
901ec0dec44SPavel Belous 
atl_macsec_select_txsa(struct rte_eth_dev * dev,uint8_t idx,uint8_t an,uint32_t pn,uint8_t * key)902ec0dec44SPavel Belous int atl_macsec_select_txsa(struct rte_eth_dev *dev,
903ec0dec44SPavel Belous 			   uint8_t idx, uint8_t an,
904ec0dec44SPavel Belous 			   uint32_t pn, uint8_t *key)
905ec0dec44SPavel Belous {
906ec0dec44SPavel Belous 	struct aq_hw_cfg_s *cfg =
907ec0dec44SPavel Belous 		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
908ec0dec44SPavel Belous 
909ec0dec44SPavel Belous 	cfg->aq_macsec.txsa.idx = idx;
910ec0dec44SPavel Belous 	cfg->aq_macsec.txsa.pn = pn;
911ec0dec44SPavel Belous 	cfg->aq_macsec.txsa.an = an;
912ec0dec44SPavel Belous 
913ec0dec44SPavel Belous 	memcpy(&cfg->aq_macsec.txsa.key, key, 16);
914ec0dec44SPavel Belous 	return 0;
915ec0dec44SPavel Belous }
916ec0dec44SPavel Belous 
atl_macsec_select_rxsa(struct rte_eth_dev * dev,uint8_t idx,uint8_t an,uint32_t pn,uint8_t * key)917ec0dec44SPavel Belous int atl_macsec_select_rxsa(struct rte_eth_dev *dev,
918ec0dec44SPavel Belous 			   uint8_t idx, uint8_t an,
919ec0dec44SPavel Belous 			   uint32_t pn, uint8_t *key)
920ec0dec44SPavel Belous {
921ec0dec44SPavel Belous 	struct aq_hw_cfg_s *cfg =
922ec0dec44SPavel Belous 		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
923ec0dec44SPavel Belous 
924ec0dec44SPavel Belous 	cfg->aq_macsec.rxsa.idx = idx;
925ec0dec44SPavel Belous 	cfg->aq_macsec.rxsa.pn = pn;
926ec0dec44SPavel Belous 	cfg->aq_macsec.rxsa.an = an;
927ec0dec44SPavel Belous 
928ec0dec44SPavel Belous 	memcpy(&cfg->aq_macsec.rxsa.key, key, 16);
929ec0dec44SPavel Belous 	return 0;
930ec0dec44SPavel Belous }
931fbe059e8SPavel Belous 
932fbe059e8SPavel Belous static int
atl_dev_stats_get(struct rte_eth_dev * dev,struct rte_eth_stats * stats)933fbe059e8SPavel Belous atl_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
934fbe059e8SPavel Belous {
935fbe059e8SPavel Belous 	struct atl_adapter *adapter = ATL_DEV_TO_ADAPTER(dev);
936fbe059e8SPavel Belous 	struct aq_hw_s *hw = &adapter->hw;
937fbe059e8SPavel Belous 	struct atl_sw_stats *swstats = &adapter->sw_stats;
938fbe059e8SPavel Belous 	unsigned int i;
939fbe059e8SPavel Belous 
940fbe059e8SPavel Belous 	hw->aq_fw_ops->update_stats(hw);
941fbe059e8SPavel Belous 
942fbe059e8SPavel Belous 	/* Fill out the rte_eth_stats statistics structure */
943fbe059e8SPavel Belous 	stats->ipackets = hw->curr_stats.dma_pkt_rc;
944fbe059e8SPavel Belous 	stats->ibytes = hw->curr_stats.dma_oct_rc;
945fbe059e8SPavel Belous 	stats->imissed = hw->curr_stats.dpc;
946fbe059e8SPavel Belous 	stats->ierrors = hw->curr_stats.erpt;
947fbe059e8SPavel Belous 
948fbe059e8SPavel Belous 	stats->opackets = hw->curr_stats.dma_pkt_tc;
949fbe059e8SPavel Belous 	stats->obytes = hw->curr_stats.dma_oct_tc;
950fbe059e8SPavel Belous 	stats->oerrors = 0;
951fbe059e8SPavel Belous 
952fbe059e8SPavel Belous 	stats->rx_nombuf = swstats->rx_nombuf;
953fbe059e8SPavel Belous 
954fbe059e8SPavel Belous 	for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
955fbe059e8SPavel Belous 		stats->q_ipackets[i] = swstats->q_ipackets[i];
956fbe059e8SPavel Belous 		stats->q_opackets[i] = swstats->q_opackets[i];
957fbe059e8SPavel Belous 		stats->q_ibytes[i] = swstats->q_ibytes[i];
958fbe059e8SPavel Belous 		stats->q_obytes[i] = swstats->q_obytes[i];
959fbe059e8SPavel Belous 		stats->q_errors[i] = swstats->q_errors[i];
960fbe059e8SPavel Belous 	}
961fbe059e8SPavel Belous 	return 0;
962fbe059e8SPavel Belous }
963fbe059e8SPavel Belous 
9649970a9adSIgor Romanov static int
atl_dev_stats_reset(struct rte_eth_dev * dev)965fbe059e8SPavel Belous atl_dev_stats_reset(struct rte_eth_dev *dev)
966fbe059e8SPavel Belous {
967fbe059e8SPavel Belous 	struct atl_adapter *adapter = ATL_DEV_TO_ADAPTER(dev);
968fbe059e8SPavel Belous 	struct aq_hw_s *hw = &adapter->hw;
969fbe059e8SPavel Belous 
970fbe059e8SPavel Belous 	hw->aq_fw_ops->update_stats(hw);
971fbe059e8SPavel Belous 
972fbe059e8SPavel Belous 	/* Reset software totals */
973fbe059e8SPavel Belous 	memset(&hw->curr_stats, 0, sizeof(hw->curr_stats));
974fbe059e8SPavel Belous 
975fbe059e8SPavel Belous 	memset(&adapter->sw_stats, 0, sizeof(adapter->sw_stats));
9769970a9adSIgor Romanov 
9779970a9adSIgor Romanov 	return 0;
978fbe059e8SPavel Belous }
979fbe059e8SPavel Belous 
980fbe059e8SPavel Belous static int
atl_dev_xstats_get_count(struct rte_eth_dev * dev)9819f3318d1SPavel Belous atl_dev_xstats_get_count(struct rte_eth_dev *dev)
9829f3318d1SPavel Belous {
9839f3318d1SPavel Belous 	struct atl_adapter *adapter =
9849f3318d1SPavel Belous 		(struct atl_adapter *)dev->data->dev_private;
9859f3318d1SPavel Belous 
9869f3318d1SPavel Belous 	struct aq_hw_s *hw = &adapter->hw;
9879f3318d1SPavel Belous 	unsigned int i, count = 0;
9889f3318d1SPavel Belous 
9899f3318d1SPavel Belous 	for (i = 0; i < RTE_DIM(atl_xstats_tbl); i++) {
9909f3318d1SPavel Belous 		if (atl_xstats_tbl[i].type == XSTATS_TYPE_MACSEC &&
9919f3318d1SPavel Belous 			((hw->caps_lo & BIT(CAPS_LO_MACSEC)) == 0))
9929f3318d1SPavel Belous 			continue;
9939f3318d1SPavel Belous 
9949f3318d1SPavel Belous 		count++;
9959f3318d1SPavel Belous 	}
9969f3318d1SPavel Belous 
9979f3318d1SPavel Belous 	return count;
9989f3318d1SPavel Belous }
9999f3318d1SPavel Belous 
10009f3318d1SPavel Belous static int
atl_dev_xstats_get_names(struct rte_eth_dev * dev __rte_unused,struct rte_eth_xstat_name * xstats_names,unsigned int size)1001fbe059e8SPavel Belous atl_dev_xstats_get_names(struct rte_eth_dev *dev __rte_unused,
1002fbe059e8SPavel Belous 			 struct rte_eth_xstat_name *xstats_names,
1003fbe059e8SPavel Belous 			 unsigned int size)
1004fbe059e8SPavel Belous {
1005fbe059e8SPavel Belous 	unsigned int i;
10069f3318d1SPavel Belous 	unsigned int count = atl_dev_xstats_get_count(dev);
1007fbe059e8SPavel Belous 
10089f3318d1SPavel Belous 	if (xstats_names) {
10099f3318d1SPavel Belous 		for (i = 0; i < size && i < count; i++) {
10109f3318d1SPavel Belous 			snprintf(xstats_names[i].name,
10119f3318d1SPavel Belous 				RTE_ETH_XSTATS_NAME_SIZE, "%s",
10129f3318d1SPavel Belous 				atl_xstats_tbl[i].name);
10139f3318d1SPavel Belous 		}
10149f3318d1SPavel Belous 	}
1015fbe059e8SPavel Belous 
10169f3318d1SPavel Belous 	return count;
1017fbe059e8SPavel Belous }
1018fbe059e8SPavel Belous 
1019fbe059e8SPavel Belous static int
atl_dev_xstats_get(struct rte_eth_dev * dev,struct rte_eth_xstat * stats,unsigned int n)1020fbe059e8SPavel Belous atl_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats,
1021fbe059e8SPavel Belous 		   unsigned int n)
1022fbe059e8SPavel Belous {
102378e4a0faSStephen Hemminger 	struct atl_adapter *adapter = dev->data->dev_private;
1024fbe059e8SPavel Belous 	struct aq_hw_s *hw = &adapter->hw;
102509d4dfa8SPavel Belous 	struct get_stats req = { 0 };
102609d4dfa8SPavel Belous 	struct macsec_msg_fw_request msg = { 0 };
102709d4dfa8SPavel Belous 	struct macsec_msg_fw_response resp = { 0 };
102809d4dfa8SPavel Belous 	int err = -1;
1029fbe059e8SPavel Belous 	unsigned int i;
10309f3318d1SPavel Belous 	unsigned int count = atl_dev_xstats_get_count(dev);
1031fbe059e8SPavel Belous 
1032fbe059e8SPavel Belous 	if (!stats)
10339f3318d1SPavel Belous 		return count;
1034fbe059e8SPavel Belous 
103509d4dfa8SPavel Belous 	if (hw->aq_fw_ops->send_macsec_req != NULL) {
103609d4dfa8SPavel Belous 		req.ingress_sa_index = 0xff;
103709d4dfa8SPavel Belous 		req.egress_sc_index = 0xff;
103809d4dfa8SPavel Belous 		req.egress_sa_index = 0xff;
103909d4dfa8SPavel Belous 
104009d4dfa8SPavel Belous 		msg.msg_type = macsec_get_stats_msg;
104109d4dfa8SPavel Belous 		msg.stats = req;
104209d4dfa8SPavel Belous 
104309d4dfa8SPavel Belous 		err = hw->aq_fw_ops->send_macsec_req(hw, &msg, &resp);
1044fbe059e8SPavel Belous 	}
1045fbe059e8SPavel Belous 
10469f3318d1SPavel Belous 	for (i = 0; i < n && i < count; i++) {
104709d4dfa8SPavel Belous 		stats[i].id = i;
104809d4dfa8SPavel Belous 
104909d4dfa8SPavel Belous 		switch (atl_xstats_tbl[i].type) {
105009d4dfa8SPavel Belous 		case XSTATS_TYPE_MSM:
105109d4dfa8SPavel Belous 			stats[i].value = *(u64 *)((uint8_t *)&hw->curr_stats +
105209d4dfa8SPavel Belous 					 atl_xstats_tbl[i].offset);
105309d4dfa8SPavel Belous 			break;
105409d4dfa8SPavel Belous 		case XSTATS_TYPE_MACSEC:
10559f3318d1SPavel Belous 			if (!err) {
10569f3318d1SPavel Belous 				stats[i].value =
10579f3318d1SPavel Belous 					*(u64 *)((uint8_t *)&resp.stats +
105809d4dfa8SPavel Belous 					atl_xstats_tbl[i].offset);
10599f3318d1SPavel Belous 			}
106009d4dfa8SPavel Belous 			break;
106109d4dfa8SPavel Belous 		}
106209d4dfa8SPavel Belous 	}
10639f3318d1SPavel Belous 
10645ab51dbfSIgor Russkikh 	return i;
1065fbe059e8SPavel Belous }
1066fbe059e8SPavel Belous 
1067bb42aa9fSPavel Belous static int
atl_fw_version_get(struct rte_eth_dev * dev,char * fw_version,size_t fw_size)1068bb42aa9fSPavel Belous atl_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
1069bb42aa9fSPavel Belous {
1070bb42aa9fSPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1071bb42aa9fSPavel Belous 	uint32_t fw_ver = 0;
1072d345d6c9SFerruh Yigit 	int ret = 0;
1073bb42aa9fSPavel Belous 
1074bb42aa9fSPavel Belous 	ret = hw_atl_utils_get_fw_version(hw, &fw_ver);
1075bb42aa9fSPavel Belous 	if (ret)
1076bb42aa9fSPavel Belous 		return -EIO;
1077bb42aa9fSPavel Belous 
1078bb42aa9fSPavel Belous 	ret = snprintf(fw_version, fw_size, "%u.%u.%u", fw_ver >> 24,
1079bb42aa9fSPavel Belous 		       (fw_ver >> 16) & 0xFFU, fw_ver & 0xFFFFU);
1080d345d6c9SFerruh Yigit 	if (ret < 0)
1081d345d6c9SFerruh Yigit 		return -EINVAL;
1082bb42aa9fSPavel Belous 
1083bb42aa9fSPavel Belous 	ret += 1; /* add string null-terminator */
1084d345d6c9SFerruh Yigit 	if (fw_size < (size_t)ret)
1085bb42aa9fSPavel Belous 		return ret;
1086bb42aa9fSPavel Belous 
1087bb42aa9fSPavel Belous 	return 0;
1088bb42aa9fSPavel Belous }
1089bb42aa9fSPavel Belous 
1090bdad90d1SIvan Ilchenko static int
atl_dev_info_get(struct rte_eth_dev * dev,struct rte_eth_dev_info * dev_info)10915bcf1649SPavel Belous atl_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
10925bcf1649SPavel Belous {
10935bcf1649SPavel Belous 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
10945bcf1649SPavel Belous 
10953d38e3dcSIgor Russkikh 	dev_info->max_rx_queues = AQ_HW_MAX_RX_QUEUES;
10963d38e3dcSIgor Russkikh 	dev_info->max_tx_queues = AQ_HW_MAX_TX_QUEUES;
10975bcf1649SPavel Belous 
10983d38e3dcSIgor Russkikh 	dev_info->min_rx_bufsize = 1024;
10993d38e3dcSIgor Russkikh 	dev_info->max_rx_pktlen = HW_ATL_B0_MTU_JUMBO;
11003d38e3dcSIgor Russkikh 	dev_info->max_mac_addrs = HW_ATL_B0_MAC_MAX;
11015bcf1649SPavel Belous 	dev_info->max_vfs = pci_dev->max_vfs;
11025bcf1649SPavel Belous 
11035bcf1649SPavel Belous 	dev_info->max_hash_mac_addrs = 0;
11045bcf1649SPavel Belous 	dev_info->max_vmdq_pools = 0;
11055bcf1649SPavel Belous 	dev_info->vmdq_queue_num = 0;
11063d38e3dcSIgor Russkikh 
11073d38e3dcSIgor Russkikh 	dev_info->rx_offload_capa = ATL_RX_OFFLOADS;
11083d38e3dcSIgor Russkikh 
11092b1472d7SPavel Belous 	dev_info->tx_offload_capa = ATL_TX_OFFLOADS;
11102b1472d7SPavel Belous 
11112b1472d7SPavel Belous 
11123d38e3dcSIgor Russkikh 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
11133d38e3dcSIgor Russkikh 		.rx_free_thresh = ATL_DEFAULT_RX_FREE_THRESH,
11143d38e3dcSIgor Russkikh 	};
11153d38e3dcSIgor Russkikh 
11162b1472d7SPavel Belous 	dev_info->default_txconf = (struct rte_eth_txconf) {
11172b1472d7SPavel Belous 		.tx_free_thresh = ATL_DEFAULT_TX_FREE_THRESH,
11182b1472d7SPavel Belous 	};
11192b1472d7SPavel Belous 
11203d38e3dcSIgor Russkikh 	dev_info->rx_desc_lim = rx_desc_lim;
11212b1472d7SPavel Belous 	dev_info->tx_desc_lim = tx_desc_lim;
11227943ba05SPavel Belous 
11233af0d308SIgor Russkikh 	dev_info->hash_key_size = HW_ATL_B0_RSS_HASHKEY_BITS / 8;
11243af0d308SIgor Russkikh 	dev_info->reta_size = HW_ATL_B0_RSS_REDIRECTION_MAX;
11253af0d308SIgor Russkikh 	dev_info->flow_type_rss_offloads = ATL_RSS_OFFLOAD_ALL;
11263af0d308SIgor Russkikh 
1127295968d1SFerruh Yigit 	dev_info->speed_capa = RTE_ETH_LINK_SPEED_1G | RTE_ETH_LINK_SPEED_10G;
1128295968d1SFerruh Yigit 	dev_info->speed_capa |= RTE_ETH_LINK_SPEED_100M;
1129295968d1SFerruh Yigit 	dev_info->speed_capa |= RTE_ETH_LINK_SPEED_2_5G;
1130295968d1SFerruh Yigit 	dev_info->speed_capa |= RTE_ETH_LINK_SPEED_5G;
1131bdad90d1SIvan Ilchenko 
1132bdad90d1SIvan Ilchenko 	return 0;
11333d38e3dcSIgor Russkikh }
11343d38e3dcSIgor Russkikh 
11353d38e3dcSIgor Russkikh static const uint32_t *
atl_dev_supported_ptypes_get(struct rte_eth_dev * dev,size_t * no_of_elements)1136*ba6a168aSSivaramakrishnan Venkat atl_dev_supported_ptypes_get(struct rte_eth_dev *dev, size_t *no_of_elements)
11373d38e3dcSIgor Russkikh {
11383d38e3dcSIgor Russkikh 	static const uint32_t ptypes[] = {
11393d38e3dcSIgor Russkikh 		RTE_PTYPE_L2_ETHER,
11403d38e3dcSIgor Russkikh 		RTE_PTYPE_L2_ETHER_ARP,
11413d38e3dcSIgor Russkikh 		RTE_PTYPE_L2_ETHER_VLAN,
11423d38e3dcSIgor Russkikh 		RTE_PTYPE_L3_IPV4,
11433d38e3dcSIgor Russkikh 		RTE_PTYPE_L3_IPV6,
11443d38e3dcSIgor Russkikh 		RTE_PTYPE_L4_TCP,
11453d38e3dcSIgor Russkikh 		RTE_PTYPE_L4_UDP,
11463d38e3dcSIgor Russkikh 		RTE_PTYPE_L4_SCTP,
11473d38e3dcSIgor Russkikh 		RTE_PTYPE_L4_ICMP,
11483d38e3dcSIgor Russkikh 	};
11493d38e3dcSIgor Russkikh 
1150*ba6a168aSSivaramakrishnan Venkat 	if (dev->rx_pkt_burst == atl_recv_pkts) {
1151*ba6a168aSSivaramakrishnan Venkat 		*no_of_elements = RTE_DIM(ptypes);
11523d38e3dcSIgor Russkikh 		return ptypes;
1153*ba6a168aSSivaramakrishnan Venkat 	}
11543d38e3dcSIgor Russkikh 
11553d38e3dcSIgor Russkikh 	return NULL;
11565bcf1649SPavel Belous }
11575bcf1649SPavel Belous 
11589f7e206aSPavel Belous static void
atl_dev_delayed_handler(void * param)11599f7e206aSPavel Belous atl_dev_delayed_handler(void *param)
11609f7e206aSPavel Belous {
11619f7e206aSPavel Belous 	struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
11629f7e206aSPavel Belous 
11639f7e206aSPavel Belous 	atl_dev_configure_macsec(dev);
11649f7e206aSPavel Belous }
11659f7e206aSPavel Belous 
11669f7e206aSPavel Belous 
11677943ba05SPavel Belous /* return 0 means link status changed, -1 means not changed */
11687943ba05SPavel Belous static int
atl_dev_link_update(struct rte_eth_dev * dev,int wait __rte_unused)11697943ba05SPavel Belous atl_dev_link_update(struct rte_eth_dev *dev, int wait __rte_unused)
11707943ba05SPavel Belous {
11717943ba05SPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
11727943ba05SPavel Belous 	struct rte_eth_link link, old;
1173921eb6b8SPavel Belous 	u32 fc = AQ_NIC_FC_OFF;
11747943ba05SPavel Belous 	int err = 0;
11757943ba05SPavel Belous 
1176295968d1SFerruh Yigit 	link.link_status = RTE_ETH_LINK_DOWN;
11777943ba05SPavel Belous 	link.link_speed = 0;
1178295968d1SFerruh Yigit 	link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
1179295968d1SFerruh Yigit 	link.link_autoneg = hw->is_autoneg ? RTE_ETH_LINK_AUTONEG : RTE_ETH_LINK_FIXED;
11807943ba05SPavel Belous 	memset(&old, 0, sizeof(old));
11817943ba05SPavel Belous 
11827943ba05SPavel Belous 	/* load old link status */
11837943ba05SPavel Belous 	rte_eth_linkstatus_get(dev, &old);
11847943ba05SPavel Belous 
11857943ba05SPavel Belous 	/* read current link status */
11867943ba05SPavel Belous 	err = hw->aq_fw_ops->update_link_status(hw);
11877943ba05SPavel Belous 
11887943ba05SPavel Belous 	if (err)
11897943ba05SPavel Belous 		return 0;
11907943ba05SPavel Belous 
11917943ba05SPavel Belous 	if (hw->aq_link_status.mbps == 0) {
11927943ba05SPavel Belous 		/* write default (down) link status */
11937943ba05SPavel Belous 		rte_eth_linkstatus_set(dev, &link);
11947943ba05SPavel Belous 		if (link.link_status == old.link_status)
11957943ba05SPavel Belous 			return -1;
11967943ba05SPavel Belous 		return 0;
11977943ba05SPavel Belous 	}
11987943ba05SPavel Belous 
1199295968d1SFerruh Yigit 	link.link_status = RTE_ETH_LINK_UP;
1200295968d1SFerruh Yigit 	link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
12017943ba05SPavel Belous 	link.link_speed = hw->aq_link_status.mbps;
12027943ba05SPavel Belous 
12037943ba05SPavel Belous 	rte_eth_linkstatus_set(dev, &link);
12047943ba05SPavel Belous 
12057943ba05SPavel Belous 	if (link.link_status == old.link_status)
12067943ba05SPavel Belous 		return -1;
12077943ba05SPavel Belous 
1208921eb6b8SPavel Belous 	/* Driver has to update flow control settings on RX block
1209921eb6b8SPavel Belous 	 * on any link event.
1210921eb6b8SPavel Belous 	 * We should query FW whether it negotiated FC.
1211921eb6b8SPavel Belous 	 */
1212921eb6b8SPavel Belous 	if (hw->aq_fw_ops->get_flow_control) {
1213921eb6b8SPavel Belous 		hw->aq_fw_ops->get_flow_control(hw, &fc);
1214921eb6b8SPavel Belous 		hw_atl_b0_set_fc(hw, fc, 0U);
1215921eb6b8SPavel Belous 	}
1216921eb6b8SPavel Belous 
12179f7e206aSPavel Belous 	if (rte_eal_alarm_set(1000 * 1000,
12189f7e206aSPavel Belous 			      atl_dev_delayed_handler, (void *)dev) < 0)
12199f7e206aSPavel Belous 		PMD_DRV_LOG(ERR, "rte_eal_alarm_set fail");
12209f7e206aSPavel Belous 
12217943ba05SPavel Belous 	return 0;
12227943ba05SPavel Belous }
12237943ba05SPavel Belous 
12249039c812SAndrew Rybchenko static int
atl_dev_promiscuous_enable(struct rte_eth_dev * dev)1225a9ba50efSPavel Belous atl_dev_promiscuous_enable(struct rte_eth_dev *dev)
1226a9ba50efSPavel Belous {
1227a9ba50efSPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1228a9ba50efSPavel Belous 
1229a9ba50efSPavel Belous 	hw_atl_rpfl2promiscuous_mode_en_set(hw, true);
12309039c812SAndrew Rybchenko 
12319039c812SAndrew Rybchenko 	return 0;
1232a9ba50efSPavel Belous }
1233a9ba50efSPavel Belous 
12349039c812SAndrew Rybchenko static int
atl_dev_promiscuous_disable(struct rte_eth_dev * dev)1235a9ba50efSPavel Belous atl_dev_promiscuous_disable(struct rte_eth_dev *dev)
1236a9ba50efSPavel Belous {
1237a9ba50efSPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1238a9ba50efSPavel Belous 
1239a9ba50efSPavel Belous 	hw_atl_rpfl2promiscuous_mode_en_set(hw, false);
12409039c812SAndrew Rybchenko 
12419039c812SAndrew Rybchenko 	return 0;
1242a9ba50efSPavel Belous }
1243a9ba50efSPavel Belous 
1244ca041cd4SIvan Ilchenko static int
atl_dev_allmulticast_enable(struct rte_eth_dev * dev)1245a9ba50efSPavel Belous atl_dev_allmulticast_enable(struct rte_eth_dev *dev)
1246a9ba50efSPavel Belous {
1247a9ba50efSPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1248a9ba50efSPavel Belous 
1249a9ba50efSPavel Belous 	hw_atl_rpfl2_accept_all_mc_packets_set(hw, true);
1250ca041cd4SIvan Ilchenko 
1251ca041cd4SIvan Ilchenko 	return 0;
1252a9ba50efSPavel Belous }
1253a9ba50efSPavel Belous 
1254ca041cd4SIvan Ilchenko static int
atl_dev_allmulticast_disable(struct rte_eth_dev * dev)1255a9ba50efSPavel Belous atl_dev_allmulticast_disable(struct rte_eth_dev *dev)
1256a9ba50efSPavel Belous {
1257a9ba50efSPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1258a9ba50efSPavel Belous 
1259a9ba50efSPavel Belous 	if (dev->data->promiscuous == 1)
1260ca041cd4SIvan Ilchenko 		return 0; /* must remain in all_multicast mode */
1261a9ba50efSPavel Belous 
1262a9ba50efSPavel Belous 	hw_atl_rpfl2_accept_all_mc_packets_set(hw, false);
1263ca041cd4SIvan Ilchenko 
1264ca041cd4SIvan Ilchenko 	return 0;
1265a9ba50efSPavel Belous }
12667943ba05SPavel Belous 
12677943ba05SPavel Belous /**
12687943ba05SPavel Belous  * It clears the interrupt causes and enables the interrupt.
12697943ba05SPavel Belous  * It will be called once only during nic initialized.
12707943ba05SPavel Belous  *
12717943ba05SPavel Belous  * @param dev
12727943ba05SPavel Belous  *  Pointer to struct rte_eth_dev.
12737943ba05SPavel Belous  * @param on
12747943ba05SPavel Belous  *  Enable or Disable.
12757943ba05SPavel Belous  *
12767943ba05SPavel Belous  * @return
12777943ba05SPavel Belous  *  - On success, zero.
12787943ba05SPavel Belous  *  - On failure, a negative value.
12797943ba05SPavel Belous  */
12807943ba05SPavel Belous 
12817943ba05SPavel Belous static int
atl_dev_lsc_interrupt_setup(struct rte_eth_dev * dev,uint8_t on __rte_unused)12827943ba05SPavel Belous atl_dev_lsc_interrupt_setup(struct rte_eth_dev *dev, uint8_t on __rte_unused)
12837943ba05SPavel Belous {
12847943ba05SPavel Belous 	atl_dev_link_status_print(dev);
12857943ba05SPavel Belous 	return 0;
12867943ba05SPavel Belous }
12877943ba05SPavel Belous 
12887943ba05SPavel Belous static int
atl_dev_rxq_interrupt_setup(struct rte_eth_dev * dev __rte_unused)12897943ba05SPavel Belous atl_dev_rxq_interrupt_setup(struct rte_eth_dev *dev __rte_unused)
12907943ba05SPavel Belous {
12917943ba05SPavel Belous 	return 0;
12927943ba05SPavel Belous }
12937943ba05SPavel Belous 
12947943ba05SPavel Belous 
12957943ba05SPavel Belous static int
atl_dev_interrupt_get_status(struct rte_eth_dev * dev)12967943ba05SPavel Belous atl_dev_interrupt_get_status(struct rte_eth_dev *dev)
12977943ba05SPavel Belous {
12987943ba05SPavel Belous 	struct atl_interrupt *intr =
12997943ba05SPavel Belous 		ATL_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
13007943ba05SPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
13017943ba05SPavel Belous 	u64 cause = 0;
13027943ba05SPavel Belous 
13037943ba05SPavel Belous 	hw_atl_b0_hw_irq_read(hw, &cause);
13047943ba05SPavel Belous 
13057943ba05SPavel Belous 	atl_disable_intr(hw);
13069f7e206aSPavel Belous 
13079f7e206aSPavel Belous 	if (cause & BIT(ATL_IRQ_CAUSE_LINK))
13089f7e206aSPavel Belous 		intr->flags |= ATL_FLAG_NEED_LINK_UPDATE;
13097943ba05SPavel Belous 
13107943ba05SPavel Belous 	return 0;
13117943ba05SPavel Belous }
13127943ba05SPavel Belous 
13137943ba05SPavel Belous /**
13147943ba05SPavel Belous  * It gets and then prints the link status.
13157943ba05SPavel Belous  *
13167943ba05SPavel Belous  * @param dev
13177943ba05SPavel Belous  *  Pointer to struct rte_eth_dev.
13187943ba05SPavel Belous  *
13197943ba05SPavel Belous  * @return
13207943ba05SPavel Belous  *  - On success, zero.
13217943ba05SPavel Belous  *  - On failure, a negative value.
13227943ba05SPavel Belous  */
13237943ba05SPavel Belous static void
atl_dev_link_status_print(struct rte_eth_dev * dev)13247943ba05SPavel Belous atl_dev_link_status_print(struct rte_eth_dev *dev)
13257943ba05SPavel Belous {
13267943ba05SPavel Belous 	struct rte_eth_link link;
13277943ba05SPavel Belous 
13287943ba05SPavel Belous 	memset(&link, 0, sizeof(link));
13297943ba05SPavel Belous 	rte_eth_linkstatus_get(dev, &link);
13307943ba05SPavel Belous 	if (link.link_status) {
13317943ba05SPavel Belous 		PMD_DRV_LOG(INFO, "Port %d: Link Up - speed %u Mbps - %s",
13327943ba05SPavel Belous 					(int)(dev->data->port_id),
13337943ba05SPavel Belous 					(unsigned int)link.link_speed,
1334295968d1SFerruh Yigit 			link.link_duplex == RTE_ETH_LINK_FULL_DUPLEX ?
13357943ba05SPavel Belous 					"full-duplex" : "half-duplex");
13367943ba05SPavel Belous 	} else {
13377943ba05SPavel Belous 		PMD_DRV_LOG(INFO, " Port %d: Link Down",
13387943ba05SPavel Belous 				(int)(dev->data->port_id));
13397943ba05SPavel Belous 	}
13407943ba05SPavel Belous 
13417943ba05SPavel Belous 
13427943ba05SPavel Belous #ifdef DEBUG
13437943ba05SPavel Belous {
13447943ba05SPavel Belous 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
13457943ba05SPavel Belous 
13467943ba05SPavel Belous 	PMD_DRV_LOG(DEBUG, "PCI Address: " PCI_PRI_FMT,
13477943ba05SPavel Belous 				pci_dev->addr.domain,
13487943ba05SPavel Belous 				pci_dev->addr.bus,
13497943ba05SPavel Belous 				pci_dev->addr.devid,
13507943ba05SPavel Belous 				pci_dev->addr.function);
13517943ba05SPavel Belous }
13527943ba05SPavel Belous #endif
13537943ba05SPavel Belous 
13547943ba05SPavel Belous 	PMD_DRV_LOG(INFO, "Link speed:%d", link.link_speed);
13557943ba05SPavel Belous }
13567943ba05SPavel Belous 
13577943ba05SPavel Belous /*
13587943ba05SPavel Belous  * It executes link_update after knowing an interrupt occurred.
13597943ba05SPavel Belous  *
13607943ba05SPavel Belous  * @param dev
13617943ba05SPavel Belous  *  Pointer to struct rte_eth_dev.
13627943ba05SPavel Belous  *
13637943ba05SPavel Belous  * @return
13647943ba05SPavel Belous  *  - On success, zero.
13657943ba05SPavel Belous  *  - On failure, a negative value.
13667943ba05SPavel Belous  */
13677943ba05SPavel Belous static int
atl_dev_interrupt_action(struct rte_eth_dev * dev,struct rte_intr_handle * intr_handle)13687943ba05SPavel Belous atl_dev_interrupt_action(struct rte_eth_dev *dev,
13697943ba05SPavel Belous 			   struct rte_intr_handle *intr_handle)
13707943ba05SPavel Belous {
13717943ba05SPavel Belous 	struct atl_interrupt *intr =
13727943ba05SPavel Belous 		ATL_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
137378e4a0faSStephen Hemminger 	struct atl_adapter *adapter = dev->data->dev_private;
13749f7e206aSPavel Belous 	struct aq_hw_s *hw = &adapter->hw;
13757943ba05SPavel Belous 
13769f7e206aSPavel Belous 	if (!(intr->flags & ATL_FLAG_NEED_LINK_UPDATE))
13779f7e206aSPavel Belous 		goto done;
13789f7e206aSPavel Belous 
13797943ba05SPavel Belous 	intr->flags &= ~ATL_FLAG_NEED_LINK_UPDATE;
13809f7e206aSPavel Belous 
13819f7e206aSPavel Belous 	/* Notify userapp if link status changed */
13829f7e206aSPavel Belous 	if (!atl_dev_link_update(dev, 0)) {
13837943ba05SPavel Belous 		atl_dev_link_status_print(dev);
13845723fbedSFerruh Yigit 		rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
13859f7e206aSPavel Belous 	} else {
13869f7e206aSPavel Belous 		if (hw->aq_fw_ops->send_macsec_req == NULL)
13879f7e206aSPavel Belous 			goto done;
13887943ba05SPavel Belous 
13899f7e206aSPavel Belous 		/* Check macsec Keys expired */
13909f7e206aSPavel Belous 		struct get_stats req = { 0 };
13919f7e206aSPavel Belous 		struct macsec_msg_fw_request msg = { 0 };
13929f7e206aSPavel Belous 		struct macsec_msg_fw_response resp = { 0 };
13939f7e206aSPavel Belous 
13949f7e206aSPavel Belous 		req.ingress_sa_index = 0x0;
13959f7e206aSPavel Belous 		req.egress_sc_index = 0x0;
13969f7e206aSPavel Belous 		req.egress_sa_index = 0x0;
13979f7e206aSPavel Belous 		msg.msg_type = macsec_get_stats_msg;
13989f7e206aSPavel Belous 		msg.stats = req;
13999f7e206aSPavel Belous 
14009f7e206aSPavel Belous 		int err = hw->aq_fw_ops->send_macsec_req(hw, &msg, &resp);
14019f7e206aSPavel Belous 		if (err) {
14029f7e206aSPavel Belous 			PMD_DRV_LOG(ERR, "send_macsec_req fail");
14039f7e206aSPavel Belous 			goto done;
14049f7e206aSPavel Belous 		}
14059f7e206aSPavel Belous 		if (resp.stats.egress_threshold_expired ||
14069f7e206aSPavel Belous 		    resp.stats.ingress_threshold_expired ||
14079f7e206aSPavel Belous 		    resp.stats.egress_expired ||
14089f7e206aSPavel Belous 		    resp.stats.ingress_expired) {
14099f7e206aSPavel Belous 			PMD_DRV_LOG(INFO, "RTE_ETH_EVENT_MACSEC");
14105723fbedSFerruh Yigit 			rte_eth_dev_callback_process(dev,
14119f7e206aSPavel Belous 				RTE_ETH_EVENT_MACSEC, NULL);
14129f7e206aSPavel Belous 		}
14139f7e206aSPavel Belous 	}
14149f7e206aSPavel Belous done:
14157943ba05SPavel Belous 	atl_enable_intr(dev);
14166bee9d5fSNithin Dabilpuram 	rte_intr_ack(intr_handle);
14177943ba05SPavel Belous 
14187943ba05SPavel Belous 	return 0;
14197943ba05SPavel Belous }
14207943ba05SPavel Belous 
14217943ba05SPavel Belous /**
14227943ba05SPavel Belous  * Interrupt handler triggered by NIC  for handling
14237943ba05SPavel Belous  * specific interrupt.
14247943ba05SPavel Belous  *
14257943ba05SPavel Belous  * @param handle
14267943ba05SPavel Belous  *  Pointer to interrupt handle.
14277943ba05SPavel Belous  * @param param
14287be78d02SJosh Soref  *  The address of parameter (struct rte_eth_dev *) registered before.
14297943ba05SPavel Belous  *
14307943ba05SPavel Belous  * @return
14317943ba05SPavel Belous  *  void
14327943ba05SPavel Belous  */
14337943ba05SPavel Belous static void
atl_dev_interrupt_handler(void * param)14347943ba05SPavel Belous atl_dev_interrupt_handler(void *param)
14357943ba05SPavel Belous {
14367943ba05SPavel Belous 	struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
14377943ba05SPavel Belous 
14387943ba05SPavel Belous 	atl_dev_interrupt_get_status(dev);
14397943ba05SPavel Belous 	atl_dev_interrupt_action(dev, dev->intr_handle);
14407943ba05SPavel Belous }
14417943ba05SPavel Belous 
1442ce4e8d41SPavel Belous 
1443ce4e8d41SPavel Belous static int
atl_dev_get_eeprom_length(struct rte_eth_dev * dev __rte_unused)1444ce4e8d41SPavel Belous atl_dev_get_eeprom_length(struct rte_eth_dev *dev __rte_unused)
1445ce4e8d41SPavel Belous {
1446ce4e8d41SPavel Belous 	return SFP_EEPROM_SIZE;
1447ce4e8d41SPavel Belous }
1448ce4e8d41SPavel Belous 
atl_dev_get_eeprom(struct rte_eth_dev * dev,struct rte_dev_eeprom_info * eeprom)1449f73061d5SPavel Belous int atl_dev_get_eeprom(struct rte_eth_dev *dev,
1450f73061d5SPavel Belous 		       struct rte_dev_eeprom_info *eeprom)
1451ce4e8d41SPavel Belous {
1452ce4e8d41SPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1453f73061d5SPavel Belous 	uint32_t dev_addr = SMBUS_DEVICE_ID;
1454ce4e8d41SPavel Belous 
1455ce4e8d41SPavel Belous 	if (hw->aq_fw_ops->get_eeprom == NULL)
1456ce4e8d41SPavel Belous 		return -ENOTSUP;
1457ce4e8d41SPavel Belous 
1458f73061d5SPavel Belous 	if (eeprom->length + eeprom->offset > SFP_EEPROM_SIZE ||
1459f73061d5SPavel Belous 	    eeprom->data == NULL)
1460ce4e8d41SPavel Belous 		return -EINVAL;
1461ce4e8d41SPavel Belous 
146299ceaad8SIgor Russkikh 	if (eeprom->magic > 0x7F)
146399ceaad8SIgor Russkikh 		return -EINVAL;
146499ceaad8SIgor Russkikh 
1465f73061d5SPavel Belous 	if (eeprom->magic)
1466f73061d5SPavel Belous 		dev_addr = eeprom->magic;
1467f73061d5SPavel Belous 
1468f73061d5SPavel Belous 	return hw->aq_fw_ops->get_eeprom(hw, dev_addr, eeprom->data,
1469f73061d5SPavel Belous 					 eeprom->length, eeprom->offset);
1470ce4e8d41SPavel Belous }
1471ce4e8d41SPavel Belous 
atl_dev_set_eeprom(struct rte_eth_dev * dev,struct rte_dev_eeprom_info * eeprom)1472f73061d5SPavel Belous int atl_dev_set_eeprom(struct rte_eth_dev *dev,
1473f73061d5SPavel Belous 		       struct rte_dev_eeprom_info *eeprom)
1474ce4e8d41SPavel Belous {
1475ce4e8d41SPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1476f73061d5SPavel Belous 	uint32_t dev_addr = SMBUS_DEVICE_ID;
1477ce4e8d41SPavel Belous 
1478ce4e8d41SPavel Belous 	if (hw->aq_fw_ops->set_eeprom == NULL)
1479ce4e8d41SPavel Belous 		return -ENOTSUP;
1480ce4e8d41SPavel Belous 
148105d5b1d6SPavel Belous 	if (eeprom->length + eeprom->offset > SFP_EEPROM_SIZE ||
148205d5b1d6SPavel Belous 	    eeprom->data == NULL)
1483ce4e8d41SPavel Belous 		return -EINVAL;
1484ce4e8d41SPavel Belous 
148599ceaad8SIgor Russkikh 	if (eeprom->magic > 0x7F)
148699ceaad8SIgor Russkikh 		return -EINVAL;
148799ceaad8SIgor Russkikh 
1488f73061d5SPavel Belous 	if (eeprom->magic)
1489f73061d5SPavel Belous 		dev_addr = eeprom->magic;
1490f73061d5SPavel Belous 
149105d5b1d6SPavel Belous 	return hw->aq_fw_ops->set_eeprom(hw, dev_addr, eeprom->data,
149205d5b1d6SPavel Belous 					 eeprom->length, eeprom->offset);
1493ce4e8d41SPavel Belous }
14944c1c8f76SPavel Belous 
14954c1c8f76SPavel Belous static int
atl_dev_get_regs(struct rte_eth_dev * dev,struct rte_dev_reg_info * regs)1496ce44e50aSPavel Belous atl_dev_get_regs(struct rte_eth_dev *dev, struct rte_dev_reg_info *regs)
1497ce44e50aSPavel Belous {
1498ce44e50aSPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1499ce44e50aSPavel Belous 	u32 mif_id;
1500ce44e50aSPavel Belous 	int err;
1501ce44e50aSPavel Belous 
1502ce44e50aSPavel Belous 	if (regs->data == NULL) {
1503ce44e50aSPavel Belous 		regs->length = hw_atl_utils_hw_get_reg_length();
1504ce44e50aSPavel Belous 		regs->width = sizeof(u32);
1505ce44e50aSPavel Belous 		return 0;
1506ce44e50aSPavel Belous 	}
1507ce44e50aSPavel Belous 
1508ce44e50aSPavel Belous 	/* Only full register dump is supported */
1509ce44e50aSPavel Belous 	if (regs->length && regs->length != hw_atl_utils_hw_get_reg_length())
1510ce44e50aSPavel Belous 		return -ENOTSUP;
1511ce44e50aSPavel Belous 
1512ce44e50aSPavel Belous 	err = hw_atl_utils_hw_get_regs(hw, regs->data);
1513ce44e50aSPavel Belous 
1514ce44e50aSPavel Belous 	/* Device version */
1515ce44e50aSPavel Belous 	mif_id = hw_atl_reg_glb_mif_id_get(hw);
1516ce44e50aSPavel Belous 	regs->version = mif_id & 0xFFU;
1517ce44e50aSPavel Belous 
1518ce44e50aSPavel Belous 	return err;
1519ce44e50aSPavel Belous }
1520ce44e50aSPavel Belous 
1521ce44e50aSPavel Belous static int
atl_flow_ctrl_get(struct rte_eth_dev * dev,struct rte_eth_fc_conf * fc_conf)15224c1c8f76SPavel Belous atl_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
15234c1c8f76SPavel Belous {
15244c1c8f76SPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1525921eb6b8SPavel Belous 	u32 fc = AQ_NIC_FC_OFF;
15264c1c8f76SPavel Belous 
1527921eb6b8SPavel Belous 	if (hw->aq_fw_ops->get_flow_control == NULL)
1528921eb6b8SPavel Belous 		return -ENOTSUP;
1529921eb6b8SPavel Belous 
1530921eb6b8SPavel Belous 	hw->aq_fw_ops->get_flow_control(hw, &fc);
1531921eb6b8SPavel Belous 
1532921eb6b8SPavel Belous 	if (fc == AQ_NIC_FC_OFF)
1533295968d1SFerruh Yigit 		fc_conf->mode = RTE_ETH_FC_NONE;
1534c1339892SPavel Belous 	else if ((fc & AQ_NIC_FC_RX) && (fc & AQ_NIC_FC_TX))
1535295968d1SFerruh Yigit 		fc_conf->mode = RTE_ETH_FC_FULL;
1536921eb6b8SPavel Belous 	else if (fc & AQ_NIC_FC_RX)
1537295968d1SFerruh Yigit 		fc_conf->mode = RTE_ETH_FC_RX_PAUSE;
1538c1339892SPavel Belous 	else if (fc & AQ_NIC_FC_TX)
1539295968d1SFerruh Yigit 		fc_conf->mode = RTE_ETH_FC_TX_PAUSE;
15404c1c8f76SPavel Belous 
15414c1c8f76SPavel Belous 	return 0;
15424c1c8f76SPavel Belous }
15434c1c8f76SPavel Belous 
15444c1c8f76SPavel Belous static int
atl_flow_ctrl_set(struct rte_eth_dev * dev,struct rte_eth_fc_conf * fc_conf)15454c1c8f76SPavel Belous atl_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
15464c1c8f76SPavel Belous {
15474c1c8f76SPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
15484c1c8f76SPavel Belous 	uint32_t old_flow_control = hw->aq_nic_cfg->flow_control;
15494c1c8f76SPavel Belous 
15504c1c8f76SPavel Belous 
15514c1c8f76SPavel Belous 	if (hw->aq_fw_ops->set_flow_control == NULL)
15524c1c8f76SPavel Belous 		return -ENOTSUP;
15534c1c8f76SPavel Belous 
1554295968d1SFerruh Yigit 	if (fc_conf->mode == RTE_ETH_FC_NONE)
15554c1c8f76SPavel Belous 		hw->aq_nic_cfg->flow_control = AQ_NIC_FC_OFF;
1556295968d1SFerruh Yigit 	else if (fc_conf->mode == RTE_ETH_FC_RX_PAUSE)
15574c1c8f76SPavel Belous 		hw->aq_nic_cfg->flow_control = AQ_NIC_FC_RX;
1558295968d1SFerruh Yigit 	else if (fc_conf->mode == RTE_ETH_FC_TX_PAUSE)
15594c1c8f76SPavel Belous 		hw->aq_nic_cfg->flow_control = AQ_NIC_FC_TX;
1560295968d1SFerruh Yigit 	else if (fc_conf->mode == RTE_ETH_FC_FULL)
15614c1c8f76SPavel Belous 		hw->aq_nic_cfg->flow_control = (AQ_NIC_FC_RX | AQ_NIC_FC_TX);
15624c1c8f76SPavel Belous 
15634c1c8f76SPavel Belous 	if (old_flow_control != hw->aq_nic_cfg->flow_control)
15644c1c8f76SPavel Belous 		return hw->aq_fw_ops->set_flow_control(hw);
15654c1c8f76SPavel Belous 
15664c1c8f76SPavel Belous 	return 0;
15674c1c8f76SPavel Belous }
15684c1c8f76SPavel Belous 
15693af0d308SIgor Russkikh static int
atl_update_mac_addr(struct rte_eth_dev * dev,uint32_t index,u8 * mac_addr,bool enable)1570275d21b5SPavel Belous atl_update_mac_addr(struct rte_eth_dev *dev, uint32_t index,
1571275d21b5SPavel Belous 		    u8 *mac_addr, bool enable)
1572275d21b5SPavel Belous {
1573275d21b5SPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1574275d21b5SPavel Belous 	unsigned int h = 0U;
1575275d21b5SPavel Belous 	unsigned int l = 0U;
1576275d21b5SPavel Belous 	int err;
1577275d21b5SPavel Belous 
1578275d21b5SPavel Belous 	if (mac_addr) {
1579275d21b5SPavel Belous 		h = (mac_addr[0] << 8) | (mac_addr[1]);
1580275d21b5SPavel Belous 		l = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
1581275d21b5SPavel Belous 			(mac_addr[4] << 8) | mac_addr[5];
1582275d21b5SPavel Belous 	}
1583275d21b5SPavel Belous 
1584275d21b5SPavel Belous 	hw_atl_rpfl2_uc_flr_en_set(hw, 0U, index);
1585275d21b5SPavel Belous 	hw_atl_rpfl2unicast_dest_addresslsw_set(hw, l, index);
1586275d21b5SPavel Belous 	hw_atl_rpfl2unicast_dest_addressmsw_set(hw, h, index);
1587275d21b5SPavel Belous 
1588275d21b5SPavel Belous 	if (enable)
1589275d21b5SPavel Belous 		hw_atl_rpfl2_uc_flr_en_set(hw, 1U, index);
1590275d21b5SPavel Belous 
1591275d21b5SPavel Belous 	err = aq_hw_err_from_flags(hw);
1592275d21b5SPavel Belous 
1593275d21b5SPavel Belous 	return err;
1594275d21b5SPavel Belous }
1595275d21b5SPavel Belous 
1596275d21b5SPavel Belous static int
atl_add_mac_addr(struct rte_eth_dev * dev,struct rte_ether_addr * mac_addr,uint32_t index __rte_unused,uint32_t pool __rte_unused)15976d13ea8eSOlivier Matz atl_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
1598275d21b5SPavel Belous 			uint32_t index __rte_unused, uint32_t pool __rte_unused)
1599275d21b5SPavel Belous {
1600538da7a1SOlivier Matz 	if (rte_is_zero_ether_addr(mac_addr)) {
1601275d21b5SPavel Belous 		PMD_DRV_LOG(ERR, "Invalid Ethernet Address");
1602275d21b5SPavel Belous 		return -EINVAL;
1603275d21b5SPavel Belous 	}
1604275d21b5SPavel Belous 
1605275d21b5SPavel Belous 	return atl_update_mac_addr(dev, index, (u8 *)mac_addr, true);
1606275d21b5SPavel Belous }
1607275d21b5SPavel Belous 
1608275d21b5SPavel Belous static void
atl_remove_mac_addr(struct rte_eth_dev * dev,uint32_t index)1609275d21b5SPavel Belous atl_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index)
1610275d21b5SPavel Belous {
1611275d21b5SPavel Belous 	atl_update_mac_addr(dev, index, NULL, false);
1612275d21b5SPavel Belous }
1613275d21b5SPavel Belous 
1614275d21b5SPavel Belous static int
atl_set_default_mac_addr(struct rte_eth_dev * dev,struct rte_ether_addr * addr)16156d13ea8eSOlivier Matz atl_set_default_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *addr)
1616275d21b5SPavel Belous {
1617275d21b5SPavel Belous 	atl_remove_mac_addr(dev, 0);
1618275d21b5SPavel Belous 	atl_add_mac_addr(dev, addr, 0, 0);
1619275d21b5SPavel Belous 	return 0;
1620275d21b5SPavel Belous }
1621275d21b5SPavel Belous 
1622275d21b5SPavel Belous static int
atl_dev_mtu_set(struct rte_eth_dev * dev,uint16_t mtu)16234c4340ffSPavel Belous atl_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
16244c4340ffSPavel Belous {
16254c4340ffSPavel Belous 	struct rte_eth_dev_info dev_info;
1626bdad90d1SIvan Ilchenko 	int ret;
162735b2d13fSOlivier Matz 	uint32_t frame_size = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN;
16284c4340ffSPavel Belous 
1629bdad90d1SIvan Ilchenko 	ret = atl_dev_info_get(dev, &dev_info);
1630bdad90d1SIvan Ilchenko 	if (ret != 0)
1631bdad90d1SIvan Ilchenko 		return ret;
16324c4340ffSPavel Belous 
163335b2d13fSOlivier Matz 	if (mtu < RTE_ETHER_MIN_MTU || frame_size > dev_info.max_rx_pktlen)
16344c4340ffSPavel Belous 		return -EINVAL;
16354c4340ffSPavel Belous 
16364c4340ffSPavel Belous 	return 0;
16374c4340ffSPavel Belous }
16384c4340ffSPavel Belous 
16394c4340ffSPavel Belous static int
atl_vlan_filter_set(struct rte_eth_dev * dev,uint16_t vlan_id,int on)1640f7c2c2c8SPavel Belous atl_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
1641f7c2c2c8SPavel Belous {
1642f7c2c2c8SPavel Belous 	struct aq_hw_cfg_s *cfg =
1643f7c2c2c8SPavel Belous 		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
1644f7c2c2c8SPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1645f7c2c2c8SPavel Belous 	int err = 0;
1646f7c2c2c8SPavel Belous 	int i = 0;
1647f7c2c2c8SPavel Belous 
1648f7c2c2c8SPavel Belous 	PMD_INIT_FUNC_TRACE();
1649f7c2c2c8SPavel Belous 
1650f7c2c2c8SPavel Belous 	for (i = 0; i < HW_ATL_B0_MAX_VLAN_IDS; i++) {
1651f7c2c2c8SPavel Belous 		if (cfg->vlan_filter[i] == vlan_id) {
1652f7c2c2c8SPavel Belous 			if (!on) {
1653f7c2c2c8SPavel Belous 				/* Disable VLAN filter. */
1654f7c2c2c8SPavel Belous 				hw_atl_rpf_vlan_flr_en_set(hw, 0U, i);
1655f7c2c2c8SPavel Belous 
1656f7c2c2c8SPavel Belous 				/* Clear VLAN filter entry */
1657f7c2c2c8SPavel Belous 				cfg->vlan_filter[i] = 0;
1658f7c2c2c8SPavel Belous 			}
1659f7c2c2c8SPavel Belous 			break;
1660f7c2c2c8SPavel Belous 		}
1661f7c2c2c8SPavel Belous 	}
1662f7c2c2c8SPavel Belous 
1663f7c2c2c8SPavel Belous 	/* VLAN_ID was not found. So, nothing to delete. */
1664f7c2c2c8SPavel Belous 	if (i == HW_ATL_B0_MAX_VLAN_IDS && !on)
1665f7c2c2c8SPavel Belous 		goto exit;
1666f7c2c2c8SPavel Belous 
1667f7c2c2c8SPavel Belous 	/* VLAN_ID already exist, or already removed above. Nothing to do. */
1668f7c2c2c8SPavel Belous 	if (i != HW_ATL_B0_MAX_VLAN_IDS)
1669f7c2c2c8SPavel Belous 		goto exit;
1670f7c2c2c8SPavel Belous 
1671f7c2c2c8SPavel Belous 	/* Try to found free VLAN filter to add new VLAN_ID */
1672f7c2c2c8SPavel Belous 	for (i = 0; i < HW_ATL_B0_MAX_VLAN_IDS; i++) {
1673f7c2c2c8SPavel Belous 		if (cfg->vlan_filter[i] == 0)
1674f7c2c2c8SPavel Belous 			break;
1675f7c2c2c8SPavel Belous 	}
1676f7c2c2c8SPavel Belous 
1677f7c2c2c8SPavel Belous 	if (i == HW_ATL_B0_MAX_VLAN_IDS) {
1678f7c2c2c8SPavel Belous 		/* We have no free VLAN filter to add new VLAN_ID*/
1679f7c2c2c8SPavel Belous 		err = -ENOMEM;
1680f7c2c2c8SPavel Belous 		goto exit;
1681f7c2c2c8SPavel Belous 	}
1682f7c2c2c8SPavel Belous 
1683f7c2c2c8SPavel Belous 	cfg->vlan_filter[i] = vlan_id;
1684f7c2c2c8SPavel Belous 	hw_atl_rpf_vlan_flr_act_set(hw, 1U, i);
1685f7c2c2c8SPavel Belous 	hw_atl_rpf_vlan_id_flr_set(hw, vlan_id, i);
1686f7c2c2c8SPavel Belous 	hw_atl_rpf_vlan_flr_en_set(hw, 1U, i);
1687f7c2c2c8SPavel Belous 
1688f7c2c2c8SPavel Belous exit:
1689f7c2c2c8SPavel Belous 	/* Enable VLAN promisc mode if vlan_filter empty  */
1690f7c2c2c8SPavel Belous 	for (i = 0; i < HW_ATL_B0_MAX_VLAN_IDS; i++) {
1691f7c2c2c8SPavel Belous 		if (cfg->vlan_filter[i] != 0)
1692f7c2c2c8SPavel Belous 			break;
1693f7c2c2c8SPavel Belous 	}
1694f7c2c2c8SPavel Belous 
1695f7c2c2c8SPavel Belous 	hw_atl_rpf_vlan_prom_mode_en_set(hw, i == HW_ATL_B0_MAX_VLAN_IDS);
1696f7c2c2c8SPavel Belous 
1697f7c2c2c8SPavel Belous 	return err;
1698f7c2c2c8SPavel Belous }
1699f7c2c2c8SPavel Belous 
1700f7c2c2c8SPavel Belous static int
atl_enable_vlan_filter(struct rte_eth_dev * dev,int en)1701f7c2c2c8SPavel Belous atl_enable_vlan_filter(struct rte_eth_dev *dev, int en)
1702f7c2c2c8SPavel Belous {
1703f7c2c2c8SPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1704f7c2c2c8SPavel Belous 	struct aq_hw_cfg_s *cfg =
1705f7c2c2c8SPavel Belous 		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
1706f7c2c2c8SPavel Belous 	int i;
1707f7c2c2c8SPavel Belous 
1708f7c2c2c8SPavel Belous 	PMD_INIT_FUNC_TRACE();
1709f7c2c2c8SPavel Belous 
1710f7c2c2c8SPavel Belous 	for (i = 0; i < HW_ATL_B0_MAX_VLAN_IDS; i++) {
1711f7c2c2c8SPavel Belous 		if (cfg->vlan_filter[i])
1712f7c2c2c8SPavel Belous 			hw_atl_rpf_vlan_flr_en_set(hw, en, i);
1713f7c2c2c8SPavel Belous 	}
1714f7c2c2c8SPavel Belous 	return 0;
1715f7c2c2c8SPavel Belous }
1716f7c2c2c8SPavel Belous 
1717f7c2c2c8SPavel Belous static int
atl_vlan_offload_set(struct rte_eth_dev * dev,int mask)1718f7c2c2c8SPavel Belous atl_vlan_offload_set(struct rte_eth_dev *dev, int mask)
1719f7c2c2c8SPavel Belous {
1720f7c2c2c8SPavel Belous 	struct aq_hw_cfg_s *cfg =
1721f7c2c2c8SPavel Belous 		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
1722f7c2c2c8SPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1723f7c2c2c8SPavel Belous 	int ret = 0;
1724f7c2c2c8SPavel Belous 	int i;
1725f7c2c2c8SPavel Belous 
1726f7c2c2c8SPavel Belous 	PMD_INIT_FUNC_TRACE();
1727f7c2c2c8SPavel Belous 
1728295968d1SFerruh Yigit 	ret = atl_enable_vlan_filter(dev, mask & RTE_ETH_VLAN_FILTER_MASK);
1729f7c2c2c8SPavel Belous 
1730295968d1SFerruh Yigit 	cfg->vlan_strip = !!(mask & RTE_ETH_VLAN_STRIP_MASK);
1731f7c2c2c8SPavel Belous 
1732f7c2c2c8SPavel Belous 	for (i = 0; i < dev->data->nb_rx_queues; i++)
1733f7c2c2c8SPavel Belous 		hw_atl_rpo_rx_desc_vlan_stripping_set(hw, cfg->vlan_strip, i);
1734f7c2c2c8SPavel Belous 
1735295968d1SFerruh Yigit 	if (mask & RTE_ETH_VLAN_EXTEND_MASK)
1736f7c2c2c8SPavel Belous 		ret = -ENOTSUP;
1737f7c2c2c8SPavel Belous 
1738f7c2c2c8SPavel Belous 	return ret;
1739f7c2c2c8SPavel Belous }
1740f7c2c2c8SPavel Belous 
1741f7c2c2c8SPavel Belous static int
atl_vlan_tpid_set(struct rte_eth_dev * dev,enum rte_vlan_type vlan_type,uint16_t tpid)1742f7c2c2c8SPavel Belous atl_vlan_tpid_set(struct rte_eth_dev *dev, enum rte_vlan_type vlan_type,
1743f7c2c2c8SPavel Belous 		  uint16_t tpid)
1744f7c2c2c8SPavel Belous {
1745f7c2c2c8SPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1746f7c2c2c8SPavel Belous 	int err = 0;
1747f7c2c2c8SPavel Belous 
1748f7c2c2c8SPavel Belous 	PMD_INIT_FUNC_TRACE();
1749f7c2c2c8SPavel Belous 
1750f7c2c2c8SPavel Belous 	switch (vlan_type) {
1751295968d1SFerruh Yigit 	case RTE_ETH_VLAN_TYPE_INNER:
1752f7c2c2c8SPavel Belous 		hw_atl_rpf_vlan_inner_etht_set(hw, tpid);
1753f7c2c2c8SPavel Belous 		break;
1754295968d1SFerruh Yigit 	case RTE_ETH_VLAN_TYPE_OUTER:
1755f7c2c2c8SPavel Belous 		hw_atl_rpf_vlan_outer_etht_set(hw, tpid);
1756f7c2c2c8SPavel Belous 		break;
1757f7c2c2c8SPavel Belous 	default:
1758f7c2c2c8SPavel Belous 		PMD_DRV_LOG(ERR, "Unsupported VLAN type");
1759f7c2c2c8SPavel Belous 		err = -ENOTSUP;
1760f7c2c2c8SPavel Belous 	}
1761f7c2c2c8SPavel Belous 
1762f7c2c2c8SPavel Belous 	return err;
1763f7c2c2c8SPavel Belous }
1764f7c2c2c8SPavel Belous 
1765f7c2c2c8SPavel Belous static void
atl_vlan_strip_queue_set(struct rte_eth_dev * dev,uint16_t queue_id,int on)1766f7c2c2c8SPavel Belous atl_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue_id, int on)
1767f7c2c2c8SPavel Belous {
1768f7c2c2c8SPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1769f7c2c2c8SPavel Belous 
1770f7c2c2c8SPavel Belous 	PMD_INIT_FUNC_TRACE();
1771f7c2c2c8SPavel Belous 
1772f7c2c2c8SPavel Belous 	if (queue_id > dev->data->nb_rx_queues) {
1773f7c2c2c8SPavel Belous 		PMD_DRV_LOG(ERR, "Invalid queue id");
1774f7c2c2c8SPavel Belous 		return;
1775f7c2c2c8SPavel Belous 	}
1776f7c2c2c8SPavel Belous 
1777f7c2c2c8SPavel Belous 	hw_atl_rpo_rx_desc_vlan_stripping_set(hw, on, queue_id);
1778f7c2c2c8SPavel Belous }
1779f7c2c2c8SPavel Belous 
1780f7c2c2c8SPavel Belous static int
atl_dev_set_mc_addr_list(struct rte_eth_dev * dev,struct rte_ether_addr * mc_addr_set,uint32_t nb_mc_addr)1781275d21b5SPavel Belous atl_dev_set_mc_addr_list(struct rte_eth_dev *dev,
17826d13ea8eSOlivier Matz 			  struct rte_ether_addr *mc_addr_set,
1783275d21b5SPavel Belous 			  uint32_t nb_mc_addr)
1784275d21b5SPavel Belous {
1785275d21b5SPavel Belous 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1786275d21b5SPavel Belous 	u32 i;
1787275d21b5SPavel Belous 
1788275d21b5SPavel Belous 	if (nb_mc_addr > AQ_HW_MULTICAST_ADDRESS_MAX - HW_ATL_B0_MAC_MIN)
1789275d21b5SPavel Belous 		return -EINVAL;
1790275d21b5SPavel Belous 
1791275d21b5SPavel Belous 	/* Update whole uc filters table */
1792275d21b5SPavel Belous 	for (i = 0; i < AQ_HW_MULTICAST_ADDRESS_MAX - HW_ATL_B0_MAC_MIN; i++) {
1793275d21b5SPavel Belous 		u8 *mac_addr = NULL;
1794275d21b5SPavel Belous 		u32 l = 0, h = 0;
1795275d21b5SPavel Belous 
1796275d21b5SPavel Belous 		if (i < nb_mc_addr) {
1797275d21b5SPavel Belous 			mac_addr = mc_addr_set[i].addr_bytes;
1798275d21b5SPavel Belous 			l = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
1799275d21b5SPavel Belous 				(mac_addr[4] << 8) | mac_addr[5];
1800275d21b5SPavel Belous 			h = (mac_addr[0] << 8) | mac_addr[1];
1801275d21b5SPavel Belous 		}
1802275d21b5SPavel Belous 
1803275d21b5SPavel Belous 		hw_atl_rpfl2_uc_flr_en_set(hw, 0U, HW_ATL_B0_MAC_MIN + i);
1804275d21b5SPavel Belous 		hw_atl_rpfl2unicast_dest_addresslsw_set(hw, l,
1805275d21b5SPavel Belous 							HW_ATL_B0_MAC_MIN + i);
1806275d21b5SPavel Belous 		hw_atl_rpfl2unicast_dest_addressmsw_set(hw, h,
1807275d21b5SPavel Belous 							HW_ATL_B0_MAC_MIN + i);
1808275d21b5SPavel Belous 		hw_atl_rpfl2_uc_flr_en_set(hw, !!mac_addr,
1809275d21b5SPavel Belous 					   HW_ATL_B0_MAC_MIN + i);
1810275d21b5SPavel Belous 	}
1811275d21b5SPavel Belous 
1812275d21b5SPavel Belous 	return 0;
1813275d21b5SPavel Belous }
1814275d21b5SPavel Belous 
1815275d21b5SPavel Belous static int
atl_reta_update(struct rte_eth_dev * dev,struct rte_eth_rss_reta_entry64 * reta_conf,uint16_t reta_size)18163af0d308SIgor Russkikh atl_reta_update(struct rte_eth_dev *dev,
18173af0d308SIgor Russkikh 		   struct rte_eth_rss_reta_entry64 *reta_conf,
18183af0d308SIgor Russkikh 		   uint16_t reta_size)
18193af0d308SIgor Russkikh {
18203af0d308SIgor Russkikh 	int i;
18213af0d308SIgor Russkikh 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
18223af0d308SIgor Russkikh 	struct aq_hw_cfg_s *cf = ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
18233af0d308SIgor Russkikh 
18243af0d308SIgor Russkikh 	for (i = 0; i < reta_size && i < cf->aq_rss.indirection_table_size; i++)
18253af0d308SIgor Russkikh 		cf->aq_rss.indirection_table[i] = min(reta_conf->reta[i],
18263af0d308SIgor Russkikh 					dev->data->nb_rx_queues - 1);
18273af0d308SIgor Russkikh 
18283af0d308SIgor Russkikh 	hw_atl_b0_hw_rss_set(hw, &cf->aq_rss);
18293af0d308SIgor Russkikh 	return 0;
18303af0d308SIgor Russkikh }
18313af0d308SIgor Russkikh 
18323af0d308SIgor Russkikh static int
atl_reta_query(struct rte_eth_dev * dev,struct rte_eth_rss_reta_entry64 * reta_conf,uint16_t reta_size)18333af0d308SIgor Russkikh atl_reta_query(struct rte_eth_dev *dev,
18343af0d308SIgor Russkikh 		    struct rte_eth_rss_reta_entry64 *reta_conf,
18353af0d308SIgor Russkikh 		    uint16_t reta_size)
18363af0d308SIgor Russkikh {
18373af0d308SIgor Russkikh 	int i;
18383af0d308SIgor Russkikh 	struct aq_hw_cfg_s *cf = ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
18393af0d308SIgor Russkikh 
18403af0d308SIgor Russkikh 	for (i = 0; i < reta_size && i < cf->aq_rss.indirection_table_size; i++)
18413af0d308SIgor Russkikh 		reta_conf->reta[i] = cf->aq_rss.indirection_table[i];
18423af0d308SIgor Russkikh 	reta_conf->mask = ~0U;
18433af0d308SIgor Russkikh 	return 0;
18443af0d308SIgor Russkikh }
18453af0d308SIgor Russkikh 
18463af0d308SIgor Russkikh static int
atl_rss_hash_update(struct rte_eth_dev * dev,struct rte_eth_rss_conf * rss_conf)18473af0d308SIgor Russkikh atl_rss_hash_update(struct rte_eth_dev *dev,
18483af0d308SIgor Russkikh 				 struct rte_eth_rss_conf *rss_conf)
18493af0d308SIgor Russkikh {
18503af0d308SIgor Russkikh 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
18513af0d308SIgor Russkikh 	struct aq_hw_cfg_s *cfg =
18523af0d308SIgor Russkikh 		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
18533af0d308SIgor Russkikh 	static u8 def_rss_key[40] = {
18543af0d308SIgor Russkikh 		0x1e, 0xad, 0x71, 0x87, 0x65, 0xfc, 0x26, 0x7d,
18553af0d308SIgor Russkikh 		0x0d, 0x45, 0x67, 0x74, 0xcd, 0x06, 0x1a, 0x18,
18563af0d308SIgor Russkikh 		0xb6, 0xc1, 0xf0, 0xc7, 0xbb, 0x18, 0xbe, 0xf8,
18573af0d308SIgor Russkikh 		0x19, 0x13, 0x4b, 0xa9, 0xd0, 0x3e, 0xfe, 0x70,
18583af0d308SIgor Russkikh 		0x25, 0x03, 0xab, 0x50, 0x6a, 0x8b, 0x82, 0x0c
18593af0d308SIgor Russkikh 	};
18603af0d308SIgor Russkikh 
18613af0d308SIgor Russkikh 	cfg->is_rss = !!rss_conf->rss_hf;
18623af0d308SIgor Russkikh 	if (rss_conf->rss_key) {
18633af0d308SIgor Russkikh 		memcpy(cfg->aq_rss.hash_secret_key, rss_conf->rss_key,
18643af0d308SIgor Russkikh 		       rss_conf->rss_key_len);
18653af0d308SIgor Russkikh 		cfg->aq_rss.hash_secret_key_size = rss_conf->rss_key_len;
18663af0d308SIgor Russkikh 	} else {
18673af0d308SIgor Russkikh 		memcpy(cfg->aq_rss.hash_secret_key, def_rss_key,
18683af0d308SIgor Russkikh 		       sizeof(def_rss_key));
18693af0d308SIgor Russkikh 		cfg->aq_rss.hash_secret_key_size = sizeof(def_rss_key);
18703af0d308SIgor Russkikh 	}
18713af0d308SIgor Russkikh 
18723af0d308SIgor Russkikh 	hw_atl_b0_hw_rss_set(hw, &cfg->aq_rss);
18733af0d308SIgor Russkikh 	hw_atl_b0_hw_rss_hash_set(hw, &cfg->aq_rss);
18743af0d308SIgor Russkikh 	return 0;
18753af0d308SIgor Russkikh }
18763af0d308SIgor Russkikh 
18773af0d308SIgor Russkikh static int
atl_rss_hash_conf_get(struct rte_eth_dev * dev,struct rte_eth_rss_conf * rss_conf)18783af0d308SIgor Russkikh atl_rss_hash_conf_get(struct rte_eth_dev *dev,
18793af0d308SIgor Russkikh 				 struct rte_eth_rss_conf *rss_conf)
18803af0d308SIgor Russkikh {
18813af0d308SIgor Russkikh 	struct aq_hw_cfg_s *cfg =
18823af0d308SIgor Russkikh 		ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
18833af0d308SIgor Russkikh 
18843af0d308SIgor Russkikh 	rss_conf->rss_hf = cfg->is_rss ? ATL_RSS_OFFLOAD_ALL : 0;
18853af0d308SIgor Russkikh 	if (rss_conf->rss_key) {
18863af0d308SIgor Russkikh 		rss_conf->rss_key_len = cfg->aq_rss.hash_secret_key_size;
18873af0d308SIgor Russkikh 		memcpy(rss_conf->rss_key, cfg->aq_rss.hash_secret_key,
18883af0d308SIgor Russkikh 		       rss_conf->rss_key_len);
18893af0d308SIgor Russkikh 	}
18903af0d308SIgor Russkikh 
18913af0d308SIgor Russkikh 	return 0;
18923af0d308SIgor Russkikh }
18933af0d308SIgor Russkikh 
1894ec0dec44SPavel Belous static bool
is_device_supported(struct rte_eth_dev * dev,struct rte_pci_driver * drv)1895ec0dec44SPavel Belous is_device_supported(struct rte_eth_dev *dev, struct rte_pci_driver *drv)
1896ec0dec44SPavel Belous {
1897ec0dec44SPavel Belous 	if (strcmp(dev->device->driver->name, drv->driver.name))
1898ec0dec44SPavel Belous 		return false;
1899ec0dec44SPavel Belous 
1900ec0dec44SPavel Belous 	return true;
1901ec0dec44SPavel Belous }
1902ec0dec44SPavel Belous 
1903ec0dec44SPavel Belous bool
is_atlantic_supported(struct rte_eth_dev * dev)1904ec0dec44SPavel Belous is_atlantic_supported(struct rte_eth_dev *dev)
1905ec0dec44SPavel Belous {
1906ec0dec44SPavel Belous 	return is_device_supported(dev, &rte_atl_pmd);
1907ec0dec44SPavel Belous }
1908ec0dec44SPavel Belous 
19095bcf1649SPavel Belous RTE_PMD_REGISTER_PCI(net_atlantic, rte_atl_pmd);
19105bcf1649SPavel Belous RTE_PMD_REGISTER_PCI_TABLE(net_atlantic, pci_id_atl_map);
19115bcf1649SPavel Belous RTE_PMD_REGISTER_KMOD_DEP(net_atlantic, "* igb_uio | uio_pci_generic");
1912eeded204SDavid Marchand RTE_LOG_REGISTER_SUFFIX(atl_logtype_init, init, NOTICE);
1913eeded204SDavid Marchand RTE_LOG_REGISTER_SUFFIX(atl_logtype_driver, driver, NOTICE);
1914