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