1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2d30ea906Sjfb8856606 * Copyright(c) 2018 Aquantia Corporation
3d30ea906Sjfb8856606 */
4d30ea906Sjfb8856606
54418919fSjohnjiang #include <rte_string_fns.h>
6d30ea906Sjfb8856606 #include <rte_ethdev_pci.h>
74418919fSjohnjiang #include <rte_alarm.h>
8d30ea906Sjfb8856606
9d30ea906Sjfb8856606 #include "atl_ethdev.h"
10d30ea906Sjfb8856606 #include "atl_common.h"
11d30ea906Sjfb8856606 #include "atl_hw_regs.h"
12d30ea906Sjfb8856606 #include "atl_logs.h"
13d30ea906Sjfb8856606 #include "hw_atl/hw_atl_llh.h"
14d30ea906Sjfb8856606 #include "hw_atl/hw_atl_b0.h"
15d30ea906Sjfb8856606 #include "hw_atl/hw_atl_b0_internal.h"
16d30ea906Sjfb8856606
17d30ea906Sjfb8856606 static int eth_atl_dev_init(struct rte_eth_dev *eth_dev);
18d30ea906Sjfb8856606 static int atl_dev_configure(struct rte_eth_dev *dev);
19d30ea906Sjfb8856606 static int atl_dev_start(struct rte_eth_dev *dev);
20*2d9fd380Sjfb8856606 static int atl_dev_stop(struct rte_eth_dev *dev);
21d30ea906Sjfb8856606 static int atl_dev_set_link_up(struct rte_eth_dev *dev);
22d30ea906Sjfb8856606 static int atl_dev_set_link_down(struct rte_eth_dev *dev);
23*2d9fd380Sjfb8856606 static int atl_dev_close(struct rte_eth_dev *dev);
24d30ea906Sjfb8856606 static int atl_dev_reset(struct rte_eth_dev *dev);
254418919fSjohnjiang static int atl_dev_promiscuous_enable(struct rte_eth_dev *dev);
264418919fSjohnjiang static int atl_dev_promiscuous_disable(struct rte_eth_dev *dev);
274418919fSjohnjiang static int atl_dev_allmulticast_enable(struct rte_eth_dev *dev);
284418919fSjohnjiang static int atl_dev_allmulticast_disable(struct rte_eth_dev *dev);
29d30ea906Sjfb8856606 static int atl_dev_link_update(struct rte_eth_dev *dev, int wait);
30d30ea906Sjfb8856606
31d30ea906Sjfb8856606 static int atl_dev_xstats_get_names(struct rte_eth_dev *dev __rte_unused,
32d30ea906Sjfb8856606 struct rte_eth_xstat_name *xstats_names,
33d30ea906Sjfb8856606 unsigned int size);
34d30ea906Sjfb8856606
35d30ea906Sjfb8856606 static int atl_dev_stats_get(struct rte_eth_dev *dev,
36d30ea906Sjfb8856606 struct rte_eth_stats *stats);
37d30ea906Sjfb8856606
38d30ea906Sjfb8856606 static int atl_dev_xstats_get(struct rte_eth_dev *dev,
39d30ea906Sjfb8856606 struct rte_eth_xstat *stats, unsigned int n);
40d30ea906Sjfb8856606
414418919fSjohnjiang static int atl_dev_stats_reset(struct rte_eth_dev *dev);
42d30ea906Sjfb8856606
43d30ea906Sjfb8856606 static int atl_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
44d30ea906Sjfb8856606 size_t fw_size);
45d30ea906Sjfb8856606
46d30ea906Sjfb8856606 static const uint32_t *atl_dev_supported_ptypes_get(struct rte_eth_dev *dev);
47d30ea906Sjfb8856606
48d30ea906Sjfb8856606 static int atl_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
49d30ea906Sjfb8856606
50d30ea906Sjfb8856606 /* VLAN stuff */
51d30ea906Sjfb8856606 static int atl_vlan_filter_set(struct rte_eth_dev *dev,
52d30ea906Sjfb8856606 uint16_t vlan_id, int on);
53d30ea906Sjfb8856606
54d30ea906Sjfb8856606 static int atl_vlan_offload_set(struct rte_eth_dev *dev, int mask);
55d30ea906Sjfb8856606
56d30ea906Sjfb8856606 static void atl_vlan_strip_queue_set(struct rte_eth_dev *dev,
57d30ea906Sjfb8856606 uint16_t queue_id, int on);
58d30ea906Sjfb8856606
59d30ea906Sjfb8856606 static int atl_vlan_tpid_set(struct rte_eth_dev *dev,
60d30ea906Sjfb8856606 enum rte_vlan_type vlan_type, uint16_t tpid);
61d30ea906Sjfb8856606
62d30ea906Sjfb8856606 /* EEPROM */
63d30ea906Sjfb8856606 static int atl_dev_get_eeprom_length(struct rte_eth_dev *dev);
64d30ea906Sjfb8856606 static int atl_dev_get_eeprom(struct rte_eth_dev *dev,
65d30ea906Sjfb8856606 struct rte_dev_eeprom_info *eeprom);
66d30ea906Sjfb8856606 static int atl_dev_set_eeprom(struct rte_eth_dev *dev,
67d30ea906Sjfb8856606 struct rte_dev_eeprom_info *eeprom);
68d30ea906Sjfb8856606
69d30ea906Sjfb8856606 /* Regs */
70d30ea906Sjfb8856606 static int atl_dev_get_regs(struct rte_eth_dev *dev,
71d30ea906Sjfb8856606 struct rte_dev_reg_info *regs);
72d30ea906Sjfb8856606
73d30ea906Sjfb8856606 /* Flow control */
74d30ea906Sjfb8856606 static int atl_flow_ctrl_get(struct rte_eth_dev *dev,
75d30ea906Sjfb8856606 struct rte_eth_fc_conf *fc_conf);
76d30ea906Sjfb8856606 static int atl_flow_ctrl_set(struct rte_eth_dev *dev,
77d30ea906Sjfb8856606 struct rte_eth_fc_conf *fc_conf);
78d30ea906Sjfb8856606
79d30ea906Sjfb8856606 static void atl_dev_link_status_print(struct rte_eth_dev *dev);
80d30ea906Sjfb8856606
81d30ea906Sjfb8856606 /* Interrupts */
82d30ea906Sjfb8856606 static int atl_dev_rxq_interrupt_setup(struct rte_eth_dev *dev);
83d30ea906Sjfb8856606 static int atl_dev_lsc_interrupt_setup(struct rte_eth_dev *dev, uint8_t on);
84d30ea906Sjfb8856606 static int atl_dev_interrupt_get_status(struct rte_eth_dev *dev);
85d30ea906Sjfb8856606 static int atl_dev_interrupt_action(struct rte_eth_dev *dev,
86d30ea906Sjfb8856606 struct rte_intr_handle *handle);
87d30ea906Sjfb8856606 static void atl_dev_interrupt_handler(void *param);
88d30ea906Sjfb8856606
89d30ea906Sjfb8856606
90d30ea906Sjfb8856606 static int atl_add_mac_addr(struct rte_eth_dev *dev,
914418919fSjohnjiang struct rte_ether_addr *mac_addr,
92d30ea906Sjfb8856606 uint32_t index, uint32_t pool);
93d30ea906Sjfb8856606 static void atl_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index);
94d30ea906Sjfb8856606 static int atl_set_default_mac_addr(struct rte_eth_dev *dev,
954418919fSjohnjiang struct rte_ether_addr *mac_addr);
96d30ea906Sjfb8856606
97d30ea906Sjfb8856606 static int atl_dev_set_mc_addr_list(struct rte_eth_dev *dev,
984418919fSjohnjiang struct rte_ether_addr *mc_addr_set,
99d30ea906Sjfb8856606 uint32_t nb_mc_addr);
100d30ea906Sjfb8856606
101d30ea906Sjfb8856606 /* RSS */
102d30ea906Sjfb8856606 static int atl_reta_update(struct rte_eth_dev *dev,
103d30ea906Sjfb8856606 struct rte_eth_rss_reta_entry64 *reta_conf,
104d30ea906Sjfb8856606 uint16_t reta_size);
105d30ea906Sjfb8856606 static int atl_reta_query(struct rte_eth_dev *dev,
106d30ea906Sjfb8856606 struct rte_eth_rss_reta_entry64 *reta_conf,
107d30ea906Sjfb8856606 uint16_t reta_size);
108d30ea906Sjfb8856606 static int atl_rss_hash_update(struct rte_eth_dev *dev,
109d30ea906Sjfb8856606 struct rte_eth_rss_conf *rss_conf);
110d30ea906Sjfb8856606 static int atl_rss_hash_conf_get(struct rte_eth_dev *dev,
111d30ea906Sjfb8856606 struct rte_eth_rss_conf *rss_conf);
112d30ea906Sjfb8856606
113d30ea906Sjfb8856606
114d30ea906Sjfb8856606 static int eth_atl_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
115d30ea906Sjfb8856606 struct rte_pci_device *pci_dev);
116d30ea906Sjfb8856606 static int eth_atl_pci_remove(struct rte_pci_device *pci_dev);
117d30ea906Sjfb8856606
1184418919fSjohnjiang static int atl_dev_info_get(struct rte_eth_dev *dev,
119d30ea906Sjfb8856606 struct rte_eth_dev_info *dev_info);
120d30ea906Sjfb8856606
121d30ea906Sjfb8856606 /*
122d30ea906Sjfb8856606 * The set of PCI devices this driver supports
123d30ea906Sjfb8856606 */
124d30ea906Sjfb8856606 static const struct rte_pci_id pci_id_atl_map[] = {
125d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_0001) },
126d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_D100) },
127d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_D107) },
128d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_D108) },
129d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_D109) },
130d30ea906Sjfb8856606
131d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC100) },
132d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC107) },
133d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC108) },
134d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC109) },
135d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC111) },
136d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC112) },
137d30ea906Sjfb8856606
138d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC100S) },
139d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC107S) },
140d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC108S) },
141d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC109S) },
142d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC111S) },
143d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC112S) },
144d30ea906Sjfb8856606
145d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC111E) },
146d30ea906Sjfb8856606 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC112E) },
147d30ea906Sjfb8856606 { .vendor_id = 0, /* sentinel */ },
148d30ea906Sjfb8856606 };
149d30ea906Sjfb8856606
150d30ea906Sjfb8856606 static struct rte_pci_driver rte_atl_pmd = {
151d30ea906Sjfb8856606 .id_table = pci_id_atl_map,
1524418919fSjohnjiang .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
153d30ea906Sjfb8856606 .probe = eth_atl_pci_probe,
154d30ea906Sjfb8856606 .remove = eth_atl_pci_remove,
155d30ea906Sjfb8856606 };
156d30ea906Sjfb8856606
157d30ea906Sjfb8856606 #define ATL_RX_OFFLOADS (DEV_RX_OFFLOAD_VLAN_STRIP \
158d30ea906Sjfb8856606 | DEV_RX_OFFLOAD_IPV4_CKSUM \
159d30ea906Sjfb8856606 | DEV_RX_OFFLOAD_UDP_CKSUM \
160d30ea906Sjfb8856606 | DEV_RX_OFFLOAD_TCP_CKSUM \
1611646932aSjfb8856606 | DEV_RX_OFFLOAD_JUMBO_FRAME \
1624418919fSjohnjiang | DEV_RX_OFFLOAD_MACSEC_STRIP \
1631646932aSjfb8856606 | DEV_RX_OFFLOAD_VLAN_FILTER)
164d30ea906Sjfb8856606
165d30ea906Sjfb8856606 #define ATL_TX_OFFLOADS (DEV_TX_OFFLOAD_VLAN_INSERT \
166d30ea906Sjfb8856606 | DEV_TX_OFFLOAD_IPV4_CKSUM \
167d30ea906Sjfb8856606 | DEV_TX_OFFLOAD_UDP_CKSUM \
168d30ea906Sjfb8856606 | DEV_TX_OFFLOAD_TCP_CKSUM \
169d30ea906Sjfb8856606 | DEV_TX_OFFLOAD_TCP_TSO \
1704418919fSjohnjiang | DEV_TX_OFFLOAD_MACSEC_INSERT \
171d30ea906Sjfb8856606 | DEV_TX_OFFLOAD_MULTI_SEGS)
172d30ea906Sjfb8856606
1731646932aSjfb8856606 #define SFP_EEPROM_SIZE 0x100
1741646932aSjfb8856606
175d30ea906Sjfb8856606 static const struct rte_eth_desc_lim rx_desc_lim = {
176d30ea906Sjfb8856606 .nb_max = ATL_MAX_RING_DESC,
177d30ea906Sjfb8856606 .nb_min = ATL_MIN_RING_DESC,
178d30ea906Sjfb8856606 .nb_align = ATL_RXD_ALIGN,
179d30ea906Sjfb8856606 };
180d30ea906Sjfb8856606
181d30ea906Sjfb8856606 static const struct rte_eth_desc_lim tx_desc_lim = {
182d30ea906Sjfb8856606 .nb_max = ATL_MAX_RING_DESC,
183d30ea906Sjfb8856606 .nb_min = ATL_MIN_RING_DESC,
184d30ea906Sjfb8856606 .nb_align = ATL_TXD_ALIGN,
185d30ea906Sjfb8856606 .nb_seg_max = ATL_TX_MAX_SEG,
186d30ea906Sjfb8856606 .nb_mtu_seg_max = ATL_TX_MAX_SEG,
187d30ea906Sjfb8856606 };
188d30ea906Sjfb8856606
1894418919fSjohnjiang enum atl_xstats_type {
1904418919fSjohnjiang XSTATS_TYPE_MSM = 0,
1914418919fSjohnjiang XSTATS_TYPE_MACSEC,
1924418919fSjohnjiang };
1934418919fSjohnjiang
194d30ea906Sjfb8856606 #define ATL_XSTATS_FIELD(name) { \
195d30ea906Sjfb8856606 #name, \
1964418919fSjohnjiang offsetof(struct aq_stats_s, name), \
1974418919fSjohnjiang XSTATS_TYPE_MSM \
1984418919fSjohnjiang }
1994418919fSjohnjiang
2004418919fSjohnjiang #define ATL_MACSEC_XSTATS_FIELD(name) { \
2014418919fSjohnjiang #name, \
2024418919fSjohnjiang offsetof(struct macsec_stats, name), \
2034418919fSjohnjiang XSTATS_TYPE_MACSEC \
204d30ea906Sjfb8856606 }
205d30ea906Sjfb8856606
206d30ea906Sjfb8856606 struct atl_xstats_tbl_s {
207d30ea906Sjfb8856606 const char *name;
208d30ea906Sjfb8856606 unsigned int offset;
2094418919fSjohnjiang enum atl_xstats_type type;
210d30ea906Sjfb8856606 };
211d30ea906Sjfb8856606
212d30ea906Sjfb8856606 static struct atl_xstats_tbl_s atl_xstats_tbl[] = {
213d30ea906Sjfb8856606 ATL_XSTATS_FIELD(uprc),
214d30ea906Sjfb8856606 ATL_XSTATS_FIELD(mprc),
215d30ea906Sjfb8856606 ATL_XSTATS_FIELD(bprc),
216d30ea906Sjfb8856606 ATL_XSTATS_FIELD(erpt),
217d30ea906Sjfb8856606 ATL_XSTATS_FIELD(uptc),
218d30ea906Sjfb8856606 ATL_XSTATS_FIELD(mptc),
219d30ea906Sjfb8856606 ATL_XSTATS_FIELD(bptc),
220d30ea906Sjfb8856606 ATL_XSTATS_FIELD(erpr),
221d30ea906Sjfb8856606 ATL_XSTATS_FIELD(ubrc),
222d30ea906Sjfb8856606 ATL_XSTATS_FIELD(ubtc),
223d30ea906Sjfb8856606 ATL_XSTATS_FIELD(mbrc),
224d30ea906Sjfb8856606 ATL_XSTATS_FIELD(mbtc),
225d30ea906Sjfb8856606 ATL_XSTATS_FIELD(bbrc),
226d30ea906Sjfb8856606 ATL_XSTATS_FIELD(bbtc),
2274418919fSjohnjiang /* Ingress Common Counters */
2284418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_ctl_pkts),
2294418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_tagged_miss_pkts),
2304418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_untagged_miss_pkts),
2314418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_notag_pkts),
2324418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_untagged_pkts),
2334418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_bad_tag_pkts),
2344418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_no_sci_pkts),
2354418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_unknown_sci_pkts),
2364418919fSjohnjiang /* Ingress SA Counters */
2374418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_untagged_hit_pkts),
2384418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_not_using_sa),
2394418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_unused_sa),
2404418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_not_valid_pkts),
2414418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_invalid_pkts),
2424418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_ok_pkts),
2434418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_unchecked_pkts),
2444418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_validated_octets),
2454418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(in_decrypted_octets),
2464418919fSjohnjiang /* Egress Common Counters */
2474418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(out_ctl_pkts),
2484418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(out_unknown_sa_pkts),
2494418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(out_untagged_pkts),
2504418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(out_too_long),
2514418919fSjohnjiang /* Egress SC Counters */
2524418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(out_sc_protected_pkts),
2534418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(out_sc_encrypted_pkts),
2544418919fSjohnjiang /* Egress SA Counters */
2554418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(out_sa_hit_drop_redirect),
2564418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(out_sa_protected2_pkts),
2574418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(out_sa_protected_pkts),
2584418919fSjohnjiang ATL_MACSEC_XSTATS_FIELD(out_sa_encrypted_pkts),
259d30ea906Sjfb8856606 };
260d30ea906Sjfb8856606
261d30ea906Sjfb8856606 static const struct eth_dev_ops atl_eth_dev_ops = {
262d30ea906Sjfb8856606 .dev_configure = atl_dev_configure,
263d30ea906Sjfb8856606 .dev_start = atl_dev_start,
264d30ea906Sjfb8856606 .dev_stop = atl_dev_stop,
265d30ea906Sjfb8856606 .dev_set_link_up = atl_dev_set_link_up,
266d30ea906Sjfb8856606 .dev_set_link_down = atl_dev_set_link_down,
267d30ea906Sjfb8856606 .dev_close = atl_dev_close,
268d30ea906Sjfb8856606 .dev_reset = atl_dev_reset,
269d30ea906Sjfb8856606
270d30ea906Sjfb8856606 /* PROMISC */
271d30ea906Sjfb8856606 .promiscuous_enable = atl_dev_promiscuous_enable,
272d30ea906Sjfb8856606 .promiscuous_disable = atl_dev_promiscuous_disable,
273d30ea906Sjfb8856606 .allmulticast_enable = atl_dev_allmulticast_enable,
274d30ea906Sjfb8856606 .allmulticast_disable = atl_dev_allmulticast_disable,
275d30ea906Sjfb8856606
276d30ea906Sjfb8856606 /* Link */
277d30ea906Sjfb8856606 .link_update = atl_dev_link_update,
278d30ea906Sjfb8856606
279d30ea906Sjfb8856606 .get_reg = atl_dev_get_regs,
280d30ea906Sjfb8856606
281d30ea906Sjfb8856606 /* Stats */
282d30ea906Sjfb8856606 .stats_get = atl_dev_stats_get,
283d30ea906Sjfb8856606 .xstats_get = atl_dev_xstats_get,
284d30ea906Sjfb8856606 .xstats_get_names = atl_dev_xstats_get_names,
285d30ea906Sjfb8856606 .stats_reset = atl_dev_stats_reset,
286d30ea906Sjfb8856606 .xstats_reset = atl_dev_stats_reset,
287d30ea906Sjfb8856606
288d30ea906Sjfb8856606 .fw_version_get = atl_fw_version_get,
289d30ea906Sjfb8856606 .dev_infos_get = atl_dev_info_get,
290d30ea906Sjfb8856606 .dev_supported_ptypes_get = atl_dev_supported_ptypes_get,
291d30ea906Sjfb8856606
292d30ea906Sjfb8856606 .mtu_set = atl_dev_mtu_set,
293d30ea906Sjfb8856606
294d30ea906Sjfb8856606 /* VLAN */
295d30ea906Sjfb8856606 .vlan_filter_set = atl_vlan_filter_set,
296d30ea906Sjfb8856606 .vlan_offload_set = atl_vlan_offload_set,
297d30ea906Sjfb8856606 .vlan_tpid_set = atl_vlan_tpid_set,
298d30ea906Sjfb8856606 .vlan_strip_queue_set = atl_vlan_strip_queue_set,
299d30ea906Sjfb8856606
300d30ea906Sjfb8856606 /* Queue Control */
301d30ea906Sjfb8856606 .rx_queue_start = atl_rx_queue_start,
302d30ea906Sjfb8856606 .rx_queue_stop = atl_rx_queue_stop,
303d30ea906Sjfb8856606 .rx_queue_setup = atl_rx_queue_setup,
304d30ea906Sjfb8856606 .rx_queue_release = atl_rx_queue_release,
305d30ea906Sjfb8856606
306d30ea906Sjfb8856606 .tx_queue_start = atl_tx_queue_start,
307d30ea906Sjfb8856606 .tx_queue_stop = atl_tx_queue_stop,
308d30ea906Sjfb8856606 .tx_queue_setup = atl_tx_queue_setup,
309d30ea906Sjfb8856606 .tx_queue_release = atl_tx_queue_release,
310d30ea906Sjfb8856606
311d30ea906Sjfb8856606 .rx_queue_intr_enable = atl_dev_rx_queue_intr_enable,
312d30ea906Sjfb8856606 .rx_queue_intr_disable = atl_dev_rx_queue_intr_disable,
313d30ea906Sjfb8856606
314d30ea906Sjfb8856606 /* EEPROM */
315d30ea906Sjfb8856606 .get_eeprom_length = atl_dev_get_eeprom_length,
316d30ea906Sjfb8856606 .get_eeprom = atl_dev_get_eeprom,
317d30ea906Sjfb8856606 .set_eeprom = atl_dev_set_eeprom,
318d30ea906Sjfb8856606
319d30ea906Sjfb8856606 /* Flow Control */
320d30ea906Sjfb8856606 .flow_ctrl_get = atl_flow_ctrl_get,
321d30ea906Sjfb8856606 .flow_ctrl_set = atl_flow_ctrl_set,
322d30ea906Sjfb8856606
323d30ea906Sjfb8856606 /* MAC */
324d30ea906Sjfb8856606 .mac_addr_add = atl_add_mac_addr,
325d30ea906Sjfb8856606 .mac_addr_remove = atl_remove_mac_addr,
326d30ea906Sjfb8856606 .mac_addr_set = atl_set_default_mac_addr,
327d30ea906Sjfb8856606 .set_mc_addr_list = atl_dev_set_mc_addr_list,
328d30ea906Sjfb8856606 .rxq_info_get = atl_rxq_info_get,
329d30ea906Sjfb8856606 .txq_info_get = atl_txq_info_get,
330d30ea906Sjfb8856606
331d30ea906Sjfb8856606 .reta_update = atl_reta_update,
332d30ea906Sjfb8856606 .reta_query = atl_reta_query,
333d30ea906Sjfb8856606 .rss_hash_update = atl_rss_hash_update,
334d30ea906Sjfb8856606 .rss_hash_conf_get = atl_rss_hash_conf_get,
335d30ea906Sjfb8856606 };
336d30ea906Sjfb8856606
337d30ea906Sjfb8856606 static inline int32_t
atl_reset_hw(struct aq_hw_s * hw)338d30ea906Sjfb8856606 atl_reset_hw(struct aq_hw_s *hw)
339d30ea906Sjfb8856606 {
340d30ea906Sjfb8856606 return hw_atl_b0_hw_reset(hw);
341d30ea906Sjfb8856606 }
342d30ea906Sjfb8856606
343d30ea906Sjfb8856606 static inline void
atl_enable_intr(struct rte_eth_dev * dev)344d30ea906Sjfb8856606 atl_enable_intr(struct rte_eth_dev *dev)
345d30ea906Sjfb8856606 {
346d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
347d30ea906Sjfb8856606
348d30ea906Sjfb8856606 hw_atl_itr_irq_msk_setlsw_set(hw, 0xffffffff);
349d30ea906Sjfb8856606 }
350d30ea906Sjfb8856606
351d30ea906Sjfb8856606 static void
atl_disable_intr(struct aq_hw_s * hw)352d30ea906Sjfb8856606 atl_disable_intr(struct aq_hw_s *hw)
353d30ea906Sjfb8856606 {
354d30ea906Sjfb8856606 PMD_INIT_FUNC_TRACE();
355d30ea906Sjfb8856606 hw_atl_itr_irq_msk_clearlsw_set(hw, 0xffffffff);
356d30ea906Sjfb8856606 }
357d30ea906Sjfb8856606
358d30ea906Sjfb8856606 static int
eth_atl_dev_init(struct rte_eth_dev * eth_dev)359d30ea906Sjfb8856606 eth_atl_dev_init(struct rte_eth_dev *eth_dev)
360d30ea906Sjfb8856606 {
3614b05018fSfengbojiang struct atl_adapter *adapter = eth_dev->data->dev_private;
362d30ea906Sjfb8856606 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
363d30ea906Sjfb8856606 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
364d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
365d30ea906Sjfb8856606 int err = 0;
366d30ea906Sjfb8856606
367d30ea906Sjfb8856606 PMD_INIT_FUNC_TRACE();
368d30ea906Sjfb8856606
369d30ea906Sjfb8856606 eth_dev->dev_ops = &atl_eth_dev_ops;
370*2d9fd380Sjfb8856606
371*2d9fd380Sjfb8856606 eth_dev->rx_queue_count = atl_rx_queue_count;
372*2d9fd380Sjfb8856606 eth_dev->rx_descriptor_status = atl_dev_rx_descriptor_status;
373*2d9fd380Sjfb8856606 eth_dev->tx_descriptor_status = atl_dev_tx_descriptor_status;
374*2d9fd380Sjfb8856606
375d30ea906Sjfb8856606 eth_dev->rx_pkt_burst = &atl_recv_pkts;
376d30ea906Sjfb8856606 eth_dev->tx_pkt_burst = &atl_xmit_pkts;
377d30ea906Sjfb8856606 eth_dev->tx_pkt_prepare = &atl_prep_pkts;
378d30ea906Sjfb8856606
379d30ea906Sjfb8856606 /* For secondary processes, the primary process has done all the work */
380d30ea906Sjfb8856606 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
381d30ea906Sjfb8856606 return 0;
382d30ea906Sjfb8856606
383*2d9fd380Sjfb8856606 eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
384*2d9fd380Sjfb8856606
385d30ea906Sjfb8856606 /* Vendor and Device ID need to be set before init of shared code */
386d30ea906Sjfb8856606 hw->device_id = pci_dev->id.device_id;
387d30ea906Sjfb8856606 hw->vendor_id = pci_dev->id.vendor_id;
388d30ea906Sjfb8856606 hw->mmio = (void *)pci_dev->mem_resource[0].addr;
389d30ea906Sjfb8856606
390d30ea906Sjfb8856606 /* Hardware configuration - hardcode */
391d30ea906Sjfb8856606 adapter->hw_cfg.is_lro = false;
392d30ea906Sjfb8856606 adapter->hw_cfg.wol = false;
393d30ea906Sjfb8856606 adapter->hw_cfg.is_rss = false;
394d30ea906Sjfb8856606 adapter->hw_cfg.num_rss_queues = HW_ATL_B0_RSS_MAX;
395d30ea906Sjfb8856606
396d30ea906Sjfb8856606 adapter->hw_cfg.link_speed_msk = AQ_NIC_RATE_10G |
397d30ea906Sjfb8856606 AQ_NIC_RATE_5G |
398d30ea906Sjfb8856606 AQ_NIC_RATE_2G5 |
399d30ea906Sjfb8856606 AQ_NIC_RATE_1G |
400d30ea906Sjfb8856606 AQ_NIC_RATE_100M;
401d30ea906Sjfb8856606
402d30ea906Sjfb8856606 adapter->hw_cfg.flow_control = (AQ_NIC_FC_RX | AQ_NIC_FC_TX);
403d30ea906Sjfb8856606 adapter->hw_cfg.aq_rss.indirection_table_size =
404d30ea906Sjfb8856606 HW_ATL_B0_RSS_REDIRECTION_MAX;
405d30ea906Sjfb8856606
406d30ea906Sjfb8856606 hw->aq_nic_cfg = &adapter->hw_cfg;
407d30ea906Sjfb8856606
4084418919fSjohnjiang pthread_mutex_init(&hw->mbox_mutex, NULL);
4094418919fSjohnjiang
410d30ea906Sjfb8856606 /* disable interrupt */
411d30ea906Sjfb8856606 atl_disable_intr(hw);
412d30ea906Sjfb8856606
413d30ea906Sjfb8856606 /* Allocate memory for storing MAC addresses */
4144418919fSjohnjiang eth_dev->data->mac_addrs = rte_zmalloc("atlantic",
4154418919fSjohnjiang RTE_ETHER_ADDR_LEN, 0);
416d30ea906Sjfb8856606 if (eth_dev->data->mac_addrs == NULL) {
417d30ea906Sjfb8856606 PMD_INIT_LOG(ERR, "MAC Malloc failed");
418d30ea906Sjfb8856606 return -ENOMEM;
419d30ea906Sjfb8856606 }
420d30ea906Sjfb8856606
421d30ea906Sjfb8856606 err = hw_atl_utils_initfw(hw, &hw->aq_fw_ops);
422d30ea906Sjfb8856606 if (err)
423d30ea906Sjfb8856606 return err;
424d30ea906Sjfb8856606
425d30ea906Sjfb8856606 /* Copy the permanent MAC address */
426d30ea906Sjfb8856606 if (hw->aq_fw_ops->get_mac_permanent(hw,
427d30ea906Sjfb8856606 eth_dev->data->mac_addrs->addr_bytes) != 0)
428d30ea906Sjfb8856606 return -EINVAL;
429d30ea906Sjfb8856606
430d30ea906Sjfb8856606 /* Reset the hw statistics */
431d30ea906Sjfb8856606 atl_dev_stats_reset(eth_dev);
432d30ea906Sjfb8856606
433d30ea906Sjfb8856606 rte_intr_callback_register(intr_handle,
434d30ea906Sjfb8856606 atl_dev_interrupt_handler, eth_dev);
435d30ea906Sjfb8856606
436d30ea906Sjfb8856606 /* enable uio/vfio intr/eventfd mapping */
437d30ea906Sjfb8856606 rte_intr_enable(intr_handle);
438d30ea906Sjfb8856606
439d30ea906Sjfb8856606 /* enable support intr */
440d30ea906Sjfb8856606 atl_enable_intr(eth_dev);
441d30ea906Sjfb8856606
442d30ea906Sjfb8856606 return err;
443d30ea906Sjfb8856606 }
444d30ea906Sjfb8856606
445d30ea906Sjfb8856606 static int
eth_atl_pci_probe(struct rte_pci_driver * pci_drv __rte_unused,struct rte_pci_device * pci_dev)446d30ea906Sjfb8856606 eth_atl_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
447d30ea906Sjfb8856606 struct rte_pci_device *pci_dev)
448d30ea906Sjfb8856606 {
449d30ea906Sjfb8856606 return rte_eth_dev_pci_generic_probe(pci_dev,
450d30ea906Sjfb8856606 sizeof(struct atl_adapter), eth_atl_dev_init);
451d30ea906Sjfb8856606 }
452d30ea906Sjfb8856606
453d30ea906Sjfb8856606 static int
eth_atl_pci_remove(struct rte_pci_device * pci_dev)454d30ea906Sjfb8856606 eth_atl_pci_remove(struct rte_pci_device *pci_dev)
455d30ea906Sjfb8856606 {
456*2d9fd380Sjfb8856606 return rte_eth_dev_pci_generic_remove(pci_dev, atl_dev_close);
457d30ea906Sjfb8856606 }
458d30ea906Sjfb8856606
459d30ea906Sjfb8856606 static int
atl_dev_configure(struct rte_eth_dev * dev)460d30ea906Sjfb8856606 atl_dev_configure(struct rte_eth_dev *dev)
461d30ea906Sjfb8856606 {
462d30ea906Sjfb8856606 struct atl_interrupt *intr =
463d30ea906Sjfb8856606 ATL_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
464d30ea906Sjfb8856606
465d30ea906Sjfb8856606 PMD_INIT_FUNC_TRACE();
466d30ea906Sjfb8856606
467d30ea906Sjfb8856606 /* set flag to update link status after init */
468d30ea906Sjfb8856606 intr->flags |= ATL_FLAG_NEED_LINK_UPDATE;
469d30ea906Sjfb8856606
470d30ea906Sjfb8856606 return 0;
471d30ea906Sjfb8856606 }
472d30ea906Sjfb8856606
473d30ea906Sjfb8856606 /*
474d30ea906Sjfb8856606 * Configure device link speed and setup link.
475d30ea906Sjfb8856606 * It returns 0 on success.
476d30ea906Sjfb8856606 */
477d30ea906Sjfb8856606 static int
atl_dev_start(struct rte_eth_dev * dev)478d30ea906Sjfb8856606 atl_dev_start(struct rte_eth_dev *dev)
479d30ea906Sjfb8856606 {
480d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
481d30ea906Sjfb8856606 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
482d30ea906Sjfb8856606 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
483d30ea906Sjfb8856606 uint32_t intr_vector = 0;
484d30ea906Sjfb8856606 int status;
485d30ea906Sjfb8856606 int err;
486d30ea906Sjfb8856606
487d30ea906Sjfb8856606 PMD_INIT_FUNC_TRACE();
488d30ea906Sjfb8856606
489d30ea906Sjfb8856606 /* set adapter started */
490d30ea906Sjfb8856606 hw->adapter_stopped = 0;
491d30ea906Sjfb8856606
492d30ea906Sjfb8856606 if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) {
493d30ea906Sjfb8856606 PMD_INIT_LOG(ERR,
494d30ea906Sjfb8856606 "Invalid link_speeds for port %u, fix speed not supported",
495d30ea906Sjfb8856606 dev->data->port_id);
496d30ea906Sjfb8856606 return -EINVAL;
497d30ea906Sjfb8856606 }
498d30ea906Sjfb8856606
499d30ea906Sjfb8856606 /* disable uio/vfio intr/eventfd mapping */
500d30ea906Sjfb8856606 rte_intr_disable(intr_handle);
501d30ea906Sjfb8856606
502d30ea906Sjfb8856606 /* reinitialize adapter
503d30ea906Sjfb8856606 * this calls reset and start
504d30ea906Sjfb8856606 */
505d30ea906Sjfb8856606 status = atl_reset_hw(hw);
506d30ea906Sjfb8856606 if (status != 0)
507d30ea906Sjfb8856606 return -EIO;
508d30ea906Sjfb8856606
509d30ea906Sjfb8856606 err = hw_atl_b0_hw_init(hw, dev->data->mac_addrs->addr_bytes);
510d30ea906Sjfb8856606
511d30ea906Sjfb8856606 hw_atl_b0_hw_start(hw);
512d30ea906Sjfb8856606 /* check and configure queue intr-vector mapping */
513d30ea906Sjfb8856606 if ((rte_intr_cap_multiple(intr_handle) ||
514d30ea906Sjfb8856606 !RTE_ETH_DEV_SRIOV(dev).active) &&
515d30ea906Sjfb8856606 dev->data->dev_conf.intr_conf.rxq != 0) {
516d30ea906Sjfb8856606 intr_vector = dev->data->nb_rx_queues;
517d30ea906Sjfb8856606 if (intr_vector > ATL_MAX_INTR_QUEUE_NUM) {
518d30ea906Sjfb8856606 PMD_INIT_LOG(ERR, "At most %d intr queues supported",
519d30ea906Sjfb8856606 ATL_MAX_INTR_QUEUE_NUM);
520d30ea906Sjfb8856606 return -ENOTSUP;
521d30ea906Sjfb8856606 }
522d30ea906Sjfb8856606 if (rte_intr_efd_enable(intr_handle, intr_vector)) {
523d30ea906Sjfb8856606 PMD_INIT_LOG(ERR, "rte_intr_efd_enable failed");
524d30ea906Sjfb8856606 return -1;
525d30ea906Sjfb8856606 }
526d30ea906Sjfb8856606 }
527d30ea906Sjfb8856606
528d30ea906Sjfb8856606 if (rte_intr_dp_is_en(intr_handle) && !intr_handle->intr_vec) {
529d30ea906Sjfb8856606 intr_handle->intr_vec = rte_zmalloc("intr_vec",
530d30ea906Sjfb8856606 dev->data->nb_rx_queues * sizeof(int), 0);
531d30ea906Sjfb8856606 if (intr_handle->intr_vec == NULL) {
532d30ea906Sjfb8856606 PMD_INIT_LOG(ERR, "Failed to allocate %d rx_queues"
533d30ea906Sjfb8856606 " intr_vec", dev->data->nb_rx_queues);
534d30ea906Sjfb8856606 return -ENOMEM;
535d30ea906Sjfb8856606 }
536d30ea906Sjfb8856606 }
537d30ea906Sjfb8856606
538d30ea906Sjfb8856606 /* initialize transmission unit */
539d30ea906Sjfb8856606 atl_tx_init(dev);
540d30ea906Sjfb8856606
541d30ea906Sjfb8856606 /* This can fail when allocating mbufs for descriptor rings */
542d30ea906Sjfb8856606 err = atl_rx_init(dev);
543d30ea906Sjfb8856606 if (err) {
544d30ea906Sjfb8856606 PMD_INIT_LOG(ERR, "Unable to initialize RX hardware");
545d30ea906Sjfb8856606 goto error;
546d30ea906Sjfb8856606 }
547d30ea906Sjfb8856606
548d30ea906Sjfb8856606 PMD_INIT_LOG(DEBUG, "FW version: %u.%u.%u",
549d30ea906Sjfb8856606 hw->fw_ver_actual >> 24,
550d30ea906Sjfb8856606 (hw->fw_ver_actual >> 16) & 0xFF,
551d30ea906Sjfb8856606 hw->fw_ver_actual & 0xFFFF);
552d30ea906Sjfb8856606 PMD_INIT_LOG(DEBUG, "Driver version: %s", ATL_PMD_DRIVER_VERSION);
553d30ea906Sjfb8856606
554d30ea906Sjfb8856606 err = atl_start_queues(dev);
555d30ea906Sjfb8856606 if (err < 0) {
556d30ea906Sjfb8856606 PMD_INIT_LOG(ERR, "Unable to start rxtx queues");
557d30ea906Sjfb8856606 goto error;
558d30ea906Sjfb8856606 }
559d30ea906Sjfb8856606
5601646932aSjfb8856606 err = atl_dev_set_link_up(dev);
5611646932aSjfb8856606
562d30ea906Sjfb8856606 err = hw->aq_fw_ops->update_link_status(hw);
563d30ea906Sjfb8856606
564d30ea906Sjfb8856606 if (err)
565d30ea906Sjfb8856606 goto error;
566d30ea906Sjfb8856606
567d30ea906Sjfb8856606 dev->data->dev_link.link_status = hw->aq_link_status.mbps != 0;
568d30ea906Sjfb8856606
569d30ea906Sjfb8856606 if (rte_intr_allow_others(intr_handle)) {
570d30ea906Sjfb8856606 /* check if lsc interrupt is enabled */
571d30ea906Sjfb8856606 if (dev->data->dev_conf.intr_conf.lsc != 0)
572d30ea906Sjfb8856606 atl_dev_lsc_interrupt_setup(dev, true);
573d30ea906Sjfb8856606 else
574d30ea906Sjfb8856606 atl_dev_lsc_interrupt_setup(dev, false);
575d30ea906Sjfb8856606 } else {
576d30ea906Sjfb8856606 rte_intr_callback_unregister(intr_handle,
577d30ea906Sjfb8856606 atl_dev_interrupt_handler, dev);
578d30ea906Sjfb8856606 if (dev->data->dev_conf.intr_conf.lsc != 0)
579d30ea906Sjfb8856606 PMD_INIT_LOG(INFO, "lsc won't enable because of"
580d30ea906Sjfb8856606 " no intr multiplex");
581d30ea906Sjfb8856606 }
582d30ea906Sjfb8856606
583d30ea906Sjfb8856606 /* check if rxq interrupt is enabled */
584d30ea906Sjfb8856606 if (dev->data->dev_conf.intr_conf.rxq != 0 &&
585d30ea906Sjfb8856606 rte_intr_dp_is_en(intr_handle))
586d30ea906Sjfb8856606 atl_dev_rxq_interrupt_setup(dev);
587d30ea906Sjfb8856606
588d30ea906Sjfb8856606 /* enable uio/vfio intr/eventfd mapping */
589d30ea906Sjfb8856606 rte_intr_enable(intr_handle);
590d30ea906Sjfb8856606
591d30ea906Sjfb8856606 /* resume enabled intr since hw reset */
592d30ea906Sjfb8856606 atl_enable_intr(dev);
593d30ea906Sjfb8856606
594d30ea906Sjfb8856606 return 0;
595d30ea906Sjfb8856606
596d30ea906Sjfb8856606 error:
597d30ea906Sjfb8856606 atl_stop_queues(dev);
598d30ea906Sjfb8856606 return -EIO;
599d30ea906Sjfb8856606 }
600d30ea906Sjfb8856606
601d30ea906Sjfb8856606 /*
602d30ea906Sjfb8856606 * Stop device: disable rx and tx functions to allow for reconfiguring.
603d30ea906Sjfb8856606 */
604*2d9fd380Sjfb8856606 static int
atl_dev_stop(struct rte_eth_dev * dev)605d30ea906Sjfb8856606 atl_dev_stop(struct rte_eth_dev *dev)
606d30ea906Sjfb8856606 {
607d30ea906Sjfb8856606 struct rte_eth_link link;
608d30ea906Sjfb8856606 struct aq_hw_s *hw =
609d30ea906Sjfb8856606 ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
610d30ea906Sjfb8856606 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
611d30ea906Sjfb8856606 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
612d30ea906Sjfb8856606
613d30ea906Sjfb8856606 PMD_INIT_FUNC_TRACE();
614*2d9fd380Sjfb8856606 dev->data->dev_started = 0;
615d30ea906Sjfb8856606
616d30ea906Sjfb8856606 /* disable interrupts */
617d30ea906Sjfb8856606 atl_disable_intr(hw);
618d30ea906Sjfb8856606
619d30ea906Sjfb8856606 /* reset the NIC */
620d30ea906Sjfb8856606 atl_reset_hw(hw);
621d30ea906Sjfb8856606 hw->adapter_stopped = 1;
622d30ea906Sjfb8856606
623d30ea906Sjfb8856606 atl_stop_queues(dev);
624d30ea906Sjfb8856606
625d30ea906Sjfb8856606 /* Clear stored conf */
626d30ea906Sjfb8856606 dev->data->scattered_rx = 0;
627d30ea906Sjfb8856606 dev->data->lro = 0;
628d30ea906Sjfb8856606
629d30ea906Sjfb8856606 /* Clear recorded link status */
630d30ea906Sjfb8856606 memset(&link, 0, sizeof(link));
631d30ea906Sjfb8856606 rte_eth_linkstatus_set(dev, &link);
632d30ea906Sjfb8856606
633d30ea906Sjfb8856606 if (!rte_intr_allow_others(intr_handle))
634d30ea906Sjfb8856606 /* resume to the default handler */
635d30ea906Sjfb8856606 rte_intr_callback_register(intr_handle,
636d30ea906Sjfb8856606 atl_dev_interrupt_handler,
637d30ea906Sjfb8856606 (void *)dev);
638d30ea906Sjfb8856606
639d30ea906Sjfb8856606 /* Clean datapath event and queue/vec mapping */
640d30ea906Sjfb8856606 rte_intr_efd_disable(intr_handle);
641d30ea906Sjfb8856606 if (intr_handle->intr_vec != NULL) {
642d30ea906Sjfb8856606 rte_free(intr_handle->intr_vec);
643d30ea906Sjfb8856606 intr_handle->intr_vec = NULL;
644d30ea906Sjfb8856606 }
645*2d9fd380Sjfb8856606
646*2d9fd380Sjfb8856606 return 0;
647d30ea906Sjfb8856606 }
648d30ea906Sjfb8856606
649d30ea906Sjfb8856606 /*
650d30ea906Sjfb8856606 * Set device link up: enable tx.
651d30ea906Sjfb8856606 */
652d30ea906Sjfb8856606 static int
atl_dev_set_link_up(struct rte_eth_dev * dev)653d30ea906Sjfb8856606 atl_dev_set_link_up(struct rte_eth_dev *dev)
654d30ea906Sjfb8856606 {
655d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
6561646932aSjfb8856606 uint32_t link_speeds = dev->data->dev_conf.link_speeds;
6571646932aSjfb8856606 uint32_t speed_mask = 0;
658d30ea906Sjfb8856606
6591646932aSjfb8856606 if (link_speeds == ETH_LINK_SPEED_AUTONEG) {
6601646932aSjfb8856606 speed_mask = hw->aq_nic_cfg->link_speed_msk;
6611646932aSjfb8856606 } else {
6621646932aSjfb8856606 if (link_speeds & ETH_LINK_SPEED_10G)
6631646932aSjfb8856606 speed_mask |= AQ_NIC_RATE_10G;
6641646932aSjfb8856606 if (link_speeds & ETH_LINK_SPEED_5G)
6651646932aSjfb8856606 speed_mask |= AQ_NIC_RATE_5G;
6661646932aSjfb8856606 if (link_speeds & ETH_LINK_SPEED_1G)
6671646932aSjfb8856606 speed_mask |= AQ_NIC_RATE_1G;
6681646932aSjfb8856606 if (link_speeds & ETH_LINK_SPEED_2_5G)
6691646932aSjfb8856606 speed_mask |= AQ_NIC_RATE_2G5;
6701646932aSjfb8856606 if (link_speeds & ETH_LINK_SPEED_100M)
6711646932aSjfb8856606 speed_mask |= AQ_NIC_RATE_100M;
6721646932aSjfb8856606 }
6731646932aSjfb8856606
6741646932aSjfb8856606 return hw->aq_fw_ops->set_link_speed(hw, speed_mask);
675d30ea906Sjfb8856606 }
676d30ea906Sjfb8856606
677d30ea906Sjfb8856606 /*
678d30ea906Sjfb8856606 * Set device link down: disable tx.
679d30ea906Sjfb8856606 */
680d30ea906Sjfb8856606 static int
atl_dev_set_link_down(struct rte_eth_dev * dev)681d30ea906Sjfb8856606 atl_dev_set_link_down(struct rte_eth_dev *dev)
682d30ea906Sjfb8856606 {
683d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
684d30ea906Sjfb8856606
685d30ea906Sjfb8856606 return hw->aq_fw_ops->set_link_speed(hw, 0);
686d30ea906Sjfb8856606 }
687d30ea906Sjfb8856606
688d30ea906Sjfb8856606 /*
689d30ea906Sjfb8856606 * Reset and stop device.
690d30ea906Sjfb8856606 */
691*2d9fd380Sjfb8856606 static int
atl_dev_close(struct rte_eth_dev * dev)692d30ea906Sjfb8856606 atl_dev_close(struct rte_eth_dev *dev)
693d30ea906Sjfb8856606 {
694*2d9fd380Sjfb8856606 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
695*2d9fd380Sjfb8856606 struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
696*2d9fd380Sjfb8856606 struct aq_hw_s *hw;
697*2d9fd380Sjfb8856606 int ret;
698*2d9fd380Sjfb8856606
699d30ea906Sjfb8856606 PMD_INIT_FUNC_TRACE();
700d30ea906Sjfb8856606
701*2d9fd380Sjfb8856606 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
702*2d9fd380Sjfb8856606 return 0;
703*2d9fd380Sjfb8856606
704*2d9fd380Sjfb8856606 hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
705*2d9fd380Sjfb8856606
706*2d9fd380Sjfb8856606 ret = atl_dev_stop(dev);
707d30ea906Sjfb8856606
708d30ea906Sjfb8856606 atl_free_queues(dev);
709*2d9fd380Sjfb8856606
710*2d9fd380Sjfb8856606 /* disable uio intr before callback unregister */
711*2d9fd380Sjfb8856606 rte_intr_disable(intr_handle);
712*2d9fd380Sjfb8856606 rte_intr_callback_unregister(intr_handle,
713*2d9fd380Sjfb8856606 atl_dev_interrupt_handler, dev);
714*2d9fd380Sjfb8856606
715*2d9fd380Sjfb8856606 pthread_mutex_destroy(&hw->mbox_mutex);
716*2d9fd380Sjfb8856606
717*2d9fd380Sjfb8856606 return ret;
718d30ea906Sjfb8856606 }
719d30ea906Sjfb8856606
720d30ea906Sjfb8856606 static int
atl_dev_reset(struct rte_eth_dev * dev)721d30ea906Sjfb8856606 atl_dev_reset(struct rte_eth_dev *dev)
722d30ea906Sjfb8856606 {
723d30ea906Sjfb8856606 int ret;
724d30ea906Sjfb8856606
725*2d9fd380Sjfb8856606 ret = atl_dev_close(dev);
726d30ea906Sjfb8856606 if (ret)
727d30ea906Sjfb8856606 return ret;
728d30ea906Sjfb8856606
729d30ea906Sjfb8856606 ret = eth_atl_dev_init(dev);
730d30ea906Sjfb8856606
731d30ea906Sjfb8856606 return ret;
732d30ea906Sjfb8856606 }
733d30ea906Sjfb8856606
7344418919fSjohnjiang static int
atl_dev_configure_macsec(struct rte_eth_dev * dev)7354418919fSjohnjiang atl_dev_configure_macsec(struct rte_eth_dev *dev)
7364418919fSjohnjiang {
7374418919fSjohnjiang struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
7384418919fSjohnjiang struct aq_hw_cfg_s *cf = ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
7394418919fSjohnjiang struct aq_macsec_config *aqcfg = &cf->aq_macsec;
7404418919fSjohnjiang struct macsec_msg_fw_request msg_macsec;
7414418919fSjohnjiang struct macsec_msg_fw_response response;
7424418919fSjohnjiang
7434418919fSjohnjiang if (!aqcfg->common.macsec_enabled ||
7444418919fSjohnjiang hw->aq_fw_ops->send_macsec_req == NULL)
7454418919fSjohnjiang return 0;
7464418919fSjohnjiang
7474418919fSjohnjiang memset(&msg_macsec, 0, sizeof(msg_macsec));
7484418919fSjohnjiang
7494418919fSjohnjiang /* Creating set of sc/sa structures from parameters provided by DPDK */
7504418919fSjohnjiang
7514418919fSjohnjiang /* Configure macsec */
7524418919fSjohnjiang msg_macsec.msg_type = macsec_cfg_msg;
7534418919fSjohnjiang msg_macsec.cfg.enabled = aqcfg->common.macsec_enabled;
7544418919fSjohnjiang msg_macsec.cfg.interrupts_enabled = 1;
7554418919fSjohnjiang
7564418919fSjohnjiang hw->aq_fw_ops->send_macsec_req(hw, &msg_macsec, &response);
7574418919fSjohnjiang
7584418919fSjohnjiang if (response.result)
7594418919fSjohnjiang return -1;
7604418919fSjohnjiang
7614418919fSjohnjiang memset(&msg_macsec, 0, sizeof(msg_macsec));
7624418919fSjohnjiang
7634418919fSjohnjiang /* Configure TX SC */
7644418919fSjohnjiang
7654418919fSjohnjiang msg_macsec.msg_type = macsec_add_tx_sc_msg;
7664418919fSjohnjiang msg_macsec.txsc.index = 0; /* TXSC always one (??) */
7674418919fSjohnjiang msg_macsec.txsc.protect = aqcfg->common.encryption_enabled;
7684418919fSjohnjiang
7694418919fSjohnjiang /* MAC addr for TX */
7704418919fSjohnjiang msg_macsec.txsc.mac_sa[0] = rte_bswap32(aqcfg->txsc.mac[1]);
7714418919fSjohnjiang msg_macsec.txsc.mac_sa[1] = rte_bswap32(aqcfg->txsc.mac[0]);
7724418919fSjohnjiang msg_macsec.txsc.sa_mask = 0x3f;
7734418919fSjohnjiang
7744418919fSjohnjiang msg_macsec.txsc.da_mask = 0;
7754418919fSjohnjiang msg_macsec.txsc.tci = 0x0B;
7764418919fSjohnjiang msg_macsec.txsc.curr_an = 0; /* SA index which currently used */
7774418919fSjohnjiang
7784418919fSjohnjiang /*
7794418919fSjohnjiang * Creating SCI (Secure Channel Identifier).
7804418919fSjohnjiang * SCI constructed from Source MAC and Port identifier
7814418919fSjohnjiang */
7824418919fSjohnjiang uint32_t sci_hi_part = (msg_macsec.txsc.mac_sa[1] << 16) |
7834418919fSjohnjiang (msg_macsec.txsc.mac_sa[0] >> 16);
7844418919fSjohnjiang uint32_t sci_low_part = (msg_macsec.txsc.mac_sa[0] << 16);
7854418919fSjohnjiang
7864418919fSjohnjiang uint32_t port_identifier = 1;
7874418919fSjohnjiang
7884418919fSjohnjiang msg_macsec.txsc.sci[1] = sci_hi_part;
7894418919fSjohnjiang msg_macsec.txsc.sci[0] = sci_low_part | port_identifier;
7904418919fSjohnjiang
7914418919fSjohnjiang hw->aq_fw_ops->send_macsec_req(hw, &msg_macsec, &response);
7924418919fSjohnjiang
7934418919fSjohnjiang if (response.result)
7944418919fSjohnjiang return -1;
7954418919fSjohnjiang
7964418919fSjohnjiang memset(&msg_macsec, 0, sizeof(msg_macsec));
7974418919fSjohnjiang
7984418919fSjohnjiang /* Configure RX SC */
7994418919fSjohnjiang
8004418919fSjohnjiang msg_macsec.msg_type = macsec_add_rx_sc_msg;
8014418919fSjohnjiang msg_macsec.rxsc.index = aqcfg->rxsc.pi;
8024418919fSjohnjiang msg_macsec.rxsc.replay_protect =
8034418919fSjohnjiang aqcfg->common.replay_protection_enabled;
8044418919fSjohnjiang msg_macsec.rxsc.anti_replay_window = 0;
8054418919fSjohnjiang
8064418919fSjohnjiang /* MAC addr for RX */
8074418919fSjohnjiang msg_macsec.rxsc.mac_da[0] = rte_bswap32(aqcfg->rxsc.mac[1]);
8084418919fSjohnjiang msg_macsec.rxsc.mac_da[1] = rte_bswap32(aqcfg->rxsc.mac[0]);
8094418919fSjohnjiang msg_macsec.rxsc.da_mask = 0;//0x3f;
8104418919fSjohnjiang
8114418919fSjohnjiang msg_macsec.rxsc.sa_mask = 0;
8124418919fSjohnjiang
8134418919fSjohnjiang hw->aq_fw_ops->send_macsec_req(hw, &msg_macsec, &response);
8144418919fSjohnjiang
8154418919fSjohnjiang if (response.result)
8164418919fSjohnjiang return -1;
8174418919fSjohnjiang
8184418919fSjohnjiang memset(&msg_macsec, 0, sizeof(msg_macsec));
8194418919fSjohnjiang
8204418919fSjohnjiang /* Configure RX SC */
8214418919fSjohnjiang
8224418919fSjohnjiang msg_macsec.msg_type = macsec_add_tx_sa_msg;
8234418919fSjohnjiang msg_macsec.txsa.index = aqcfg->txsa.idx;
8244418919fSjohnjiang msg_macsec.txsa.next_pn = aqcfg->txsa.pn;
8254418919fSjohnjiang
8264418919fSjohnjiang msg_macsec.txsa.key[0] = rte_bswap32(aqcfg->txsa.key[3]);
8274418919fSjohnjiang msg_macsec.txsa.key[1] = rte_bswap32(aqcfg->txsa.key[2]);
8284418919fSjohnjiang msg_macsec.txsa.key[2] = rte_bswap32(aqcfg->txsa.key[1]);
8294418919fSjohnjiang msg_macsec.txsa.key[3] = rte_bswap32(aqcfg->txsa.key[0]);
8304418919fSjohnjiang
8314418919fSjohnjiang hw->aq_fw_ops->send_macsec_req(hw, &msg_macsec, &response);
8324418919fSjohnjiang
8334418919fSjohnjiang if (response.result)
8344418919fSjohnjiang return -1;
8354418919fSjohnjiang
8364418919fSjohnjiang memset(&msg_macsec, 0, sizeof(msg_macsec));
8374418919fSjohnjiang
8384418919fSjohnjiang /* Configure RX SA */
8394418919fSjohnjiang
8404418919fSjohnjiang msg_macsec.msg_type = macsec_add_rx_sa_msg;
8414418919fSjohnjiang msg_macsec.rxsa.index = aqcfg->rxsa.idx;
8424418919fSjohnjiang msg_macsec.rxsa.next_pn = aqcfg->rxsa.pn;
8434418919fSjohnjiang
8444418919fSjohnjiang msg_macsec.rxsa.key[0] = rte_bswap32(aqcfg->rxsa.key[3]);
8454418919fSjohnjiang msg_macsec.rxsa.key[1] = rte_bswap32(aqcfg->rxsa.key[2]);
8464418919fSjohnjiang msg_macsec.rxsa.key[2] = rte_bswap32(aqcfg->rxsa.key[1]);
8474418919fSjohnjiang msg_macsec.rxsa.key[3] = rte_bswap32(aqcfg->rxsa.key[0]);
8484418919fSjohnjiang
8494418919fSjohnjiang hw->aq_fw_ops->send_macsec_req(hw, &msg_macsec, &response);
8504418919fSjohnjiang
8514418919fSjohnjiang if (response.result)
8524418919fSjohnjiang return -1;
8534418919fSjohnjiang
8544418919fSjohnjiang return 0;
8554418919fSjohnjiang }
8564418919fSjohnjiang
atl_macsec_enable(struct rte_eth_dev * dev,uint8_t encr,uint8_t repl_prot)8574418919fSjohnjiang int atl_macsec_enable(struct rte_eth_dev *dev,
8584418919fSjohnjiang uint8_t encr, uint8_t repl_prot)
8594418919fSjohnjiang {
8604418919fSjohnjiang struct aq_hw_cfg_s *cfg =
8614418919fSjohnjiang ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
8624418919fSjohnjiang
8634418919fSjohnjiang cfg->aq_macsec.common.macsec_enabled = 1;
8644418919fSjohnjiang cfg->aq_macsec.common.encryption_enabled = encr;
8654418919fSjohnjiang cfg->aq_macsec.common.replay_protection_enabled = repl_prot;
8664418919fSjohnjiang
8674418919fSjohnjiang return 0;
8684418919fSjohnjiang }
8694418919fSjohnjiang
atl_macsec_disable(struct rte_eth_dev * dev)8704418919fSjohnjiang int atl_macsec_disable(struct rte_eth_dev *dev)
8714418919fSjohnjiang {
8724418919fSjohnjiang struct aq_hw_cfg_s *cfg =
8734418919fSjohnjiang ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
8744418919fSjohnjiang
8754418919fSjohnjiang cfg->aq_macsec.common.macsec_enabled = 0;
8764418919fSjohnjiang
8774418919fSjohnjiang return 0;
8784418919fSjohnjiang }
8794418919fSjohnjiang
atl_macsec_config_txsc(struct rte_eth_dev * dev,uint8_t * mac)8804418919fSjohnjiang int atl_macsec_config_txsc(struct rte_eth_dev *dev, uint8_t *mac)
8814418919fSjohnjiang {
8824418919fSjohnjiang struct aq_hw_cfg_s *cfg =
8834418919fSjohnjiang ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
8844418919fSjohnjiang
8854418919fSjohnjiang memset(&cfg->aq_macsec.txsc.mac, 0, sizeof(cfg->aq_macsec.txsc.mac));
8864418919fSjohnjiang memcpy((uint8_t *)&cfg->aq_macsec.txsc.mac + 2, mac,
8874418919fSjohnjiang RTE_ETHER_ADDR_LEN);
8884418919fSjohnjiang
8894418919fSjohnjiang return 0;
8904418919fSjohnjiang }
8914418919fSjohnjiang
atl_macsec_config_rxsc(struct rte_eth_dev * dev,uint8_t * mac,uint16_t pi)8924418919fSjohnjiang int atl_macsec_config_rxsc(struct rte_eth_dev *dev,
8934418919fSjohnjiang uint8_t *mac, uint16_t pi)
8944418919fSjohnjiang {
8954418919fSjohnjiang struct aq_hw_cfg_s *cfg =
8964418919fSjohnjiang ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
8974418919fSjohnjiang
8984418919fSjohnjiang memset(&cfg->aq_macsec.rxsc.mac, 0, sizeof(cfg->aq_macsec.rxsc.mac));
8994418919fSjohnjiang memcpy((uint8_t *)&cfg->aq_macsec.rxsc.mac + 2, mac,
9004418919fSjohnjiang RTE_ETHER_ADDR_LEN);
9014418919fSjohnjiang cfg->aq_macsec.rxsc.pi = pi;
9024418919fSjohnjiang
9034418919fSjohnjiang return 0;
9044418919fSjohnjiang }
9054418919fSjohnjiang
atl_macsec_select_txsa(struct rte_eth_dev * dev,uint8_t idx,uint8_t an,uint32_t pn,uint8_t * key)9064418919fSjohnjiang int atl_macsec_select_txsa(struct rte_eth_dev *dev,
9074418919fSjohnjiang uint8_t idx, uint8_t an,
9084418919fSjohnjiang uint32_t pn, uint8_t *key)
9094418919fSjohnjiang {
9104418919fSjohnjiang struct aq_hw_cfg_s *cfg =
9114418919fSjohnjiang ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
9124418919fSjohnjiang
9134418919fSjohnjiang cfg->aq_macsec.txsa.idx = idx;
9144418919fSjohnjiang cfg->aq_macsec.txsa.pn = pn;
9154418919fSjohnjiang cfg->aq_macsec.txsa.an = an;
9164418919fSjohnjiang
9174418919fSjohnjiang memcpy(&cfg->aq_macsec.txsa.key, key, 16);
9184418919fSjohnjiang return 0;
9194418919fSjohnjiang }
9204418919fSjohnjiang
atl_macsec_select_rxsa(struct rte_eth_dev * dev,uint8_t idx,uint8_t an,uint32_t pn,uint8_t * key)9214418919fSjohnjiang int atl_macsec_select_rxsa(struct rte_eth_dev *dev,
9224418919fSjohnjiang uint8_t idx, uint8_t an,
9234418919fSjohnjiang uint32_t pn, uint8_t *key)
9244418919fSjohnjiang {
9254418919fSjohnjiang struct aq_hw_cfg_s *cfg =
9264418919fSjohnjiang ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
9274418919fSjohnjiang
9284418919fSjohnjiang cfg->aq_macsec.rxsa.idx = idx;
9294418919fSjohnjiang cfg->aq_macsec.rxsa.pn = pn;
9304418919fSjohnjiang cfg->aq_macsec.rxsa.an = an;
9314418919fSjohnjiang
9324418919fSjohnjiang memcpy(&cfg->aq_macsec.rxsa.key, key, 16);
9334418919fSjohnjiang return 0;
9344418919fSjohnjiang }
935d30ea906Sjfb8856606
936d30ea906Sjfb8856606 static int
atl_dev_stats_get(struct rte_eth_dev * dev,struct rte_eth_stats * stats)937d30ea906Sjfb8856606 atl_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
938d30ea906Sjfb8856606 {
939d30ea906Sjfb8856606 struct atl_adapter *adapter = ATL_DEV_TO_ADAPTER(dev);
940d30ea906Sjfb8856606 struct aq_hw_s *hw = &adapter->hw;
941d30ea906Sjfb8856606 struct atl_sw_stats *swstats = &adapter->sw_stats;
942d30ea906Sjfb8856606 unsigned int i;
943d30ea906Sjfb8856606
944d30ea906Sjfb8856606 hw->aq_fw_ops->update_stats(hw);
945d30ea906Sjfb8856606
946d30ea906Sjfb8856606 /* Fill out the rte_eth_stats statistics structure */
947d30ea906Sjfb8856606 stats->ipackets = hw->curr_stats.dma_pkt_rc;
948d30ea906Sjfb8856606 stats->ibytes = hw->curr_stats.dma_oct_rc;
949d30ea906Sjfb8856606 stats->imissed = hw->curr_stats.dpc;
950d30ea906Sjfb8856606 stats->ierrors = hw->curr_stats.erpt;
951d30ea906Sjfb8856606
952d30ea906Sjfb8856606 stats->opackets = hw->curr_stats.dma_pkt_tc;
953d30ea906Sjfb8856606 stats->obytes = hw->curr_stats.dma_oct_tc;
954d30ea906Sjfb8856606 stats->oerrors = 0;
955d30ea906Sjfb8856606
956d30ea906Sjfb8856606 stats->rx_nombuf = swstats->rx_nombuf;
957d30ea906Sjfb8856606
958d30ea906Sjfb8856606 for (i = 0; i < RTE_ETHDEV_QUEUE_STAT_CNTRS; i++) {
959d30ea906Sjfb8856606 stats->q_ipackets[i] = swstats->q_ipackets[i];
960d30ea906Sjfb8856606 stats->q_opackets[i] = swstats->q_opackets[i];
961d30ea906Sjfb8856606 stats->q_ibytes[i] = swstats->q_ibytes[i];
962d30ea906Sjfb8856606 stats->q_obytes[i] = swstats->q_obytes[i];
963d30ea906Sjfb8856606 stats->q_errors[i] = swstats->q_errors[i];
964d30ea906Sjfb8856606 }
965d30ea906Sjfb8856606 return 0;
966d30ea906Sjfb8856606 }
967d30ea906Sjfb8856606
9684418919fSjohnjiang static int
atl_dev_stats_reset(struct rte_eth_dev * dev)969d30ea906Sjfb8856606 atl_dev_stats_reset(struct rte_eth_dev *dev)
970d30ea906Sjfb8856606 {
971d30ea906Sjfb8856606 struct atl_adapter *adapter = ATL_DEV_TO_ADAPTER(dev);
972d30ea906Sjfb8856606 struct aq_hw_s *hw = &adapter->hw;
973d30ea906Sjfb8856606
974d30ea906Sjfb8856606 hw->aq_fw_ops->update_stats(hw);
975d30ea906Sjfb8856606
976d30ea906Sjfb8856606 /* Reset software totals */
977d30ea906Sjfb8856606 memset(&hw->curr_stats, 0, sizeof(hw->curr_stats));
978d30ea906Sjfb8856606
979d30ea906Sjfb8856606 memset(&adapter->sw_stats, 0, sizeof(adapter->sw_stats));
9804418919fSjohnjiang
9814418919fSjohnjiang return 0;
9824418919fSjohnjiang }
9834418919fSjohnjiang
9844418919fSjohnjiang static int
atl_dev_xstats_get_count(struct rte_eth_dev * dev)9854418919fSjohnjiang atl_dev_xstats_get_count(struct rte_eth_dev *dev)
9864418919fSjohnjiang {
9874418919fSjohnjiang struct atl_adapter *adapter =
9884418919fSjohnjiang (struct atl_adapter *)dev->data->dev_private;
9894418919fSjohnjiang
9904418919fSjohnjiang struct aq_hw_s *hw = &adapter->hw;
9914418919fSjohnjiang unsigned int i, count = 0;
9924418919fSjohnjiang
9934418919fSjohnjiang for (i = 0; i < RTE_DIM(atl_xstats_tbl); i++) {
9944418919fSjohnjiang if (atl_xstats_tbl[i].type == XSTATS_TYPE_MACSEC &&
9954418919fSjohnjiang ((hw->caps_lo & BIT(CAPS_LO_MACSEC)) == 0))
9964418919fSjohnjiang continue;
9974418919fSjohnjiang
9984418919fSjohnjiang count++;
9994418919fSjohnjiang }
10004418919fSjohnjiang
10014418919fSjohnjiang return count;
1002d30ea906Sjfb8856606 }
1003d30ea906Sjfb8856606
1004d30ea906Sjfb8856606 static int
atl_dev_xstats_get_names(struct rte_eth_dev * dev __rte_unused,struct rte_eth_xstat_name * xstats_names,unsigned int size)1005d30ea906Sjfb8856606 atl_dev_xstats_get_names(struct rte_eth_dev *dev __rte_unused,
1006d30ea906Sjfb8856606 struct rte_eth_xstat_name *xstats_names,
1007d30ea906Sjfb8856606 unsigned int size)
1008d30ea906Sjfb8856606 {
1009d30ea906Sjfb8856606 unsigned int i;
10104418919fSjohnjiang unsigned int count = atl_dev_xstats_get_count(dev);
1011d30ea906Sjfb8856606
10124418919fSjohnjiang if (xstats_names) {
10134418919fSjohnjiang for (i = 0; i < size && i < count; i++) {
10144418919fSjohnjiang snprintf(xstats_names[i].name,
10154418919fSjohnjiang RTE_ETH_XSTATS_NAME_SIZE, "%s",
1016d30ea906Sjfb8856606 atl_xstats_tbl[i].name);
10174418919fSjohnjiang }
10184418919fSjohnjiang }
1019d30ea906Sjfb8856606
10204418919fSjohnjiang return count;
1021d30ea906Sjfb8856606 }
1022d30ea906Sjfb8856606
1023d30ea906Sjfb8856606 static int
atl_dev_xstats_get(struct rte_eth_dev * dev,struct rte_eth_xstat * stats,unsigned int n)1024d30ea906Sjfb8856606 atl_dev_xstats_get(struct rte_eth_dev *dev, struct rte_eth_xstat *stats,
1025d30ea906Sjfb8856606 unsigned int n)
1026d30ea906Sjfb8856606 {
10274418919fSjohnjiang struct atl_adapter *adapter = dev->data->dev_private;
1028d30ea906Sjfb8856606 struct aq_hw_s *hw = &adapter->hw;
10294418919fSjohnjiang struct get_stats req = { 0 };
10304418919fSjohnjiang struct macsec_msg_fw_request msg = { 0 };
10314418919fSjohnjiang struct macsec_msg_fw_response resp = { 0 };
10324418919fSjohnjiang int err = -1;
1033d30ea906Sjfb8856606 unsigned int i;
10344418919fSjohnjiang unsigned int count = atl_dev_xstats_get_count(dev);
1035d30ea906Sjfb8856606
1036d30ea906Sjfb8856606 if (!stats)
10374418919fSjohnjiang return count;
1038d30ea906Sjfb8856606
10394418919fSjohnjiang if (hw->aq_fw_ops->send_macsec_req != NULL) {
10404418919fSjohnjiang req.ingress_sa_index = 0xff;
10414418919fSjohnjiang req.egress_sc_index = 0xff;
10424418919fSjohnjiang req.egress_sa_index = 0xff;
10434418919fSjohnjiang
10444418919fSjohnjiang msg.msg_type = macsec_get_stats_msg;
10454418919fSjohnjiang msg.stats = req;
10464418919fSjohnjiang
10474418919fSjohnjiang err = hw->aq_fw_ops->send_macsec_req(hw, &msg, &resp);
10484418919fSjohnjiang }
10494418919fSjohnjiang
10504418919fSjohnjiang for (i = 0; i < n && i < count; i++) {
1051d30ea906Sjfb8856606 stats[i].id = i;
10524418919fSjohnjiang
10534418919fSjohnjiang switch (atl_xstats_tbl[i].type) {
10544418919fSjohnjiang case XSTATS_TYPE_MSM:
1055d30ea906Sjfb8856606 stats[i].value = *(u64 *)((uint8_t *)&hw->curr_stats +
1056d30ea906Sjfb8856606 atl_xstats_tbl[i].offset);
10574418919fSjohnjiang break;
10584418919fSjohnjiang case XSTATS_TYPE_MACSEC:
10594418919fSjohnjiang if (!err) {
10604418919fSjohnjiang stats[i].value =
10614418919fSjohnjiang *(u64 *)((uint8_t *)&resp.stats +
10624418919fSjohnjiang atl_xstats_tbl[i].offset);
10634418919fSjohnjiang }
10644418919fSjohnjiang break;
10654418919fSjohnjiang }
1066d30ea906Sjfb8856606 }
1067d30ea906Sjfb8856606
10681646932aSjfb8856606 return i;
1069d30ea906Sjfb8856606 }
1070d30ea906Sjfb8856606
1071d30ea906Sjfb8856606 static int
atl_fw_version_get(struct rte_eth_dev * dev,char * fw_version,size_t fw_size)1072d30ea906Sjfb8856606 atl_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
1073d30ea906Sjfb8856606 {
1074d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1075d30ea906Sjfb8856606 uint32_t fw_ver = 0;
1076d30ea906Sjfb8856606 unsigned int ret = 0;
1077d30ea906Sjfb8856606
1078d30ea906Sjfb8856606 ret = hw_atl_utils_get_fw_version(hw, &fw_ver);
1079d30ea906Sjfb8856606 if (ret)
1080d30ea906Sjfb8856606 return -EIO;
1081d30ea906Sjfb8856606
1082d30ea906Sjfb8856606 ret = snprintf(fw_version, fw_size, "%u.%u.%u", fw_ver >> 24,
1083d30ea906Sjfb8856606 (fw_ver >> 16) & 0xFFU, fw_ver & 0xFFFFU);
1084d30ea906Sjfb8856606
1085d30ea906Sjfb8856606 ret += 1; /* add string null-terminator */
1086d30ea906Sjfb8856606
1087d30ea906Sjfb8856606 if (fw_size < ret)
1088d30ea906Sjfb8856606 return ret;
1089d30ea906Sjfb8856606
1090d30ea906Sjfb8856606 return 0;
1091d30ea906Sjfb8856606 }
1092d30ea906Sjfb8856606
10934418919fSjohnjiang static int
atl_dev_info_get(struct rte_eth_dev * dev,struct rte_eth_dev_info * dev_info)1094d30ea906Sjfb8856606 atl_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
1095d30ea906Sjfb8856606 {
1096d30ea906Sjfb8856606 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1097d30ea906Sjfb8856606
1098d30ea906Sjfb8856606 dev_info->max_rx_queues = AQ_HW_MAX_RX_QUEUES;
1099d30ea906Sjfb8856606 dev_info->max_tx_queues = AQ_HW_MAX_TX_QUEUES;
1100d30ea906Sjfb8856606
1101d30ea906Sjfb8856606 dev_info->min_rx_bufsize = 1024;
1102d30ea906Sjfb8856606 dev_info->max_rx_pktlen = HW_ATL_B0_MTU_JUMBO;
1103d30ea906Sjfb8856606 dev_info->max_mac_addrs = HW_ATL_B0_MAC_MAX;
1104d30ea906Sjfb8856606 dev_info->max_vfs = pci_dev->max_vfs;
1105d30ea906Sjfb8856606
1106d30ea906Sjfb8856606 dev_info->max_hash_mac_addrs = 0;
1107d30ea906Sjfb8856606 dev_info->max_vmdq_pools = 0;
1108d30ea906Sjfb8856606 dev_info->vmdq_queue_num = 0;
1109d30ea906Sjfb8856606
1110d30ea906Sjfb8856606 dev_info->rx_offload_capa = ATL_RX_OFFLOADS;
1111d30ea906Sjfb8856606
1112d30ea906Sjfb8856606 dev_info->tx_offload_capa = ATL_TX_OFFLOADS;
1113d30ea906Sjfb8856606
1114d30ea906Sjfb8856606
1115d30ea906Sjfb8856606 dev_info->default_rxconf = (struct rte_eth_rxconf) {
1116d30ea906Sjfb8856606 .rx_free_thresh = ATL_DEFAULT_RX_FREE_THRESH,
1117d30ea906Sjfb8856606 };
1118d30ea906Sjfb8856606
1119d30ea906Sjfb8856606 dev_info->default_txconf = (struct rte_eth_txconf) {
1120d30ea906Sjfb8856606 .tx_free_thresh = ATL_DEFAULT_TX_FREE_THRESH,
1121d30ea906Sjfb8856606 };
1122d30ea906Sjfb8856606
1123d30ea906Sjfb8856606 dev_info->rx_desc_lim = rx_desc_lim;
1124d30ea906Sjfb8856606 dev_info->tx_desc_lim = tx_desc_lim;
1125d30ea906Sjfb8856606
1126d30ea906Sjfb8856606 dev_info->hash_key_size = HW_ATL_B0_RSS_HASHKEY_BITS / 8;
1127d30ea906Sjfb8856606 dev_info->reta_size = HW_ATL_B0_RSS_REDIRECTION_MAX;
1128d30ea906Sjfb8856606 dev_info->flow_type_rss_offloads = ATL_RSS_OFFLOAD_ALL;
1129d30ea906Sjfb8856606
1130d30ea906Sjfb8856606 dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
1131d30ea906Sjfb8856606 dev_info->speed_capa |= ETH_LINK_SPEED_100M;
1132d30ea906Sjfb8856606 dev_info->speed_capa |= ETH_LINK_SPEED_2_5G;
1133d30ea906Sjfb8856606 dev_info->speed_capa |= ETH_LINK_SPEED_5G;
11344418919fSjohnjiang
11354418919fSjohnjiang return 0;
1136d30ea906Sjfb8856606 }
1137d30ea906Sjfb8856606
1138d30ea906Sjfb8856606 static const uint32_t *
atl_dev_supported_ptypes_get(struct rte_eth_dev * dev)1139d30ea906Sjfb8856606 atl_dev_supported_ptypes_get(struct rte_eth_dev *dev)
1140d30ea906Sjfb8856606 {
1141d30ea906Sjfb8856606 static const uint32_t ptypes[] = {
1142d30ea906Sjfb8856606 RTE_PTYPE_L2_ETHER,
1143d30ea906Sjfb8856606 RTE_PTYPE_L2_ETHER_ARP,
1144d30ea906Sjfb8856606 RTE_PTYPE_L2_ETHER_VLAN,
1145d30ea906Sjfb8856606 RTE_PTYPE_L3_IPV4,
1146d30ea906Sjfb8856606 RTE_PTYPE_L3_IPV6,
1147d30ea906Sjfb8856606 RTE_PTYPE_L4_TCP,
1148d30ea906Sjfb8856606 RTE_PTYPE_L4_UDP,
1149d30ea906Sjfb8856606 RTE_PTYPE_L4_SCTP,
1150d30ea906Sjfb8856606 RTE_PTYPE_L4_ICMP,
1151d30ea906Sjfb8856606 RTE_PTYPE_UNKNOWN
1152d30ea906Sjfb8856606 };
1153d30ea906Sjfb8856606
1154d30ea906Sjfb8856606 if (dev->rx_pkt_burst == atl_recv_pkts)
1155d30ea906Sjfb8856606 return ptypes;
1156d30ea906Sjfb8856606
1157d30ea906Sjfb8856606 return NULL;
1158d30ea906Sjfb8856606 }
1159d30ea906Sjfb8856606
11604418919fSjohnjiang static void
atl_dev_delayed_handler(void * param)11614418919fSjohnjiang atl_dev_delayed_handler(void *param)
11624418919fSjohnjiang {
11634418919fSjohnjiang struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
11644418919fSjohnjiang
11654418919fSjohnjiang atl_dev_configure_macsec(dev);
11664418919fSjohnjiang }
11674418919fSjohnjiang
11684418919fSjohnjiang
1169d30ea906Sjfb8856606 /* return 0 means link status changed, -1 means not changed */
1170d30ea906Sjfb8856606 static int
atl_dev_link_update(struct rte_eth_dev * dev,int wait __rte_unused)1171d30ea906Sjfb8856606 atl_dev_link_update(struct rte_eth_dev *dev, int wait __rte_unused)
1172d30ea906Sjfb8856606 {
1173d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1174d30ea906Sjfb8856606 struct rte_eth_link link, old;
11751646932aSjfb8856606 u32 fc = AQ_NIC_FC_OFF;
1176d30ea906Sjfb8856606 int err = 0;
1177d30ea906Sjfb8856606
1178d30ea906Sjfb8856606 link.link_status = ETH_LINK_DOWN;
1179d30ea906Sjfb8856606 link.link_speed = 0;
1180d30ea906Sjfb8856606 link.link_duplex = ETH_LINK_FULL_DUPLEX;
1181d30ea906Sjfb8856606 link.link_autoneg = hw->is_autoneg ? ETH_LINK_AUTONEG : ETH_LINK_FIXED;
1182d30ea906Sjfb8856606 memset(&old, 0, sizeof(old));
1183d30ea906Sjfb8856606
1184d30ea906Sjfb8856606 /* load old link status */
1185d30ea906Sjfb8856606 rte_eth_linkstatus_get(dev, &old);
1186d30ea906Sjfb8856606
1187d30ea906Sjfb8856606 /* read current link status */
1188d30ea906Sjfb8856606 err = hw->aq_fw_ops->update_link_status(hw);
1189d30ea906Sjfb8856606
1190d30ea906Sjfb8856606 if (err)
1191d30ea906Sjfb8856606 return 0;
1192d30ea906Sjfb8856606
1193d30ea906Sjfb8856606 if (hw->aq_link_status.mbps == 0) {
1194d30ea906Sjfb8856606 /* write default (down) link status */
1195d30ea906Sjfb8856606 rte_eth_linkstatus_set(dev, &link);
1196d30ea906Sjfb8856606 if (link.link_status == old.link_status)
1197d30ea906Sjfb8856606 return -1;
1198d30ea906Sjfb8856606 return 0;
1199d30ea906Sjfb8856606 }
1200d30ea906Sjfb8856606
1201d30ea906Sjfb8856606 link.link_status = ETH_LINK_UP;
1202d30ea906Sjfb8856606 link.link_duplex = ETH_LINK_FULL_DUPLEX;
1203d30ea906Sjfb8856606 link.link_speed = hw->aq_link_status.mbps;
1204d30ea906Sjfb8856606
1205d30ea906Sjfb8856606 rte_eth_linkstatus_set(dev, &link);
1206d30ea906Sjfb8856606
1207d30ea906Sjfb8856606 if (link.link_status == old.link_status)
1208d30ea906Sjfb8856606 return -1;
1209d30ea906Sjfb8856606
12101646932aSjfb8856606 /* Driver has to update flow control settings on RX block
12111646932aSjfb8856606 * on any link event.
12121646932aSjfb8856606 * We should query FW whether it negotiated FC.
12131646932aSjfb8856606 */
12141646932aSjfb8856606 if (hw->aq_fw_ops->get_flow_control) {
12151646932aSjfb8856606 hw->aq_fw_ops->get_flow_control(hw, &fc);
12161646932aSjfb8856606 hw_atl_b0_set_fc(hw, fc, 0U);
12171646932aSjfb8856606 }
12181646932aSjfb8856606
12194418919fSjohnjiang if (rte_eal_alarm_set(1000 * 1000,
12204418919fSjohnjiang atl_dev_delayed_handler, (void *)dev) < 0)
12214418919fSjohnjiang PMD_DRV_LOG(ERR, "rte_eal_alarm_set fail");
12224418919fSjohnjiang
1223d30ea906Sjfb8856606 return 0;
1224d30ea906Sjfb8856606 }
1225d30ea906Sjfb8856606
12264418919fSjohnjiang static int
atl_dev_promiscuous_enable(struct rte_eth_dev * dev)1227d30ea906Sjfb8856606 atl_dev_promiscuous_enable(struct rte_eth_dev *dev)
1228d30ea906Sjfb8856606 {
1229d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1230d30ea906Sjfb8856606
1231d30ea906Sjfb8856606 hw_atl_rpfl2promiscuous_mode_en_set(hw, true);
12324418919fSjohnjiang
12334418919fSjohnjiang return 0;
1234d30ea906Sjfb8856606 }
1235d30ea906Sjfb8856606
12364418919fSjohnjiang static int
atl_dev_promiscuous_disable(struct rte_eth_dev * dev)1237d30ea906Sjfb8856606 atl_dev_promiscuous_disable(struct rte_eth_dev *dev)
1238d30ea906Sjfb8856606 {
1239d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1240d30ea906Sjfb8856606
1241d30ea906Sjfb8856606 hw_atl_rpfl2promiscuous_mode_en_set(hw, false);
12424418919fSjohnjiang
12434418919fSjohnjiang return 0;
1244d30ea906Sjfb8856606 }
1245d30ea906Sjfb8856606
12464418919fSjohnjiang static int
atl_dev_allmulticast_enable(struct rte_eth_dev * dev)1247d30ea906Sjfb8856606 atl_dev_allmulticast_enable(struct rte_eth_dev *dev)
1248d30ea906Sjfb8856606 {
1249d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1250d30ea906Sjfb8856606
1251d30ea906Sjfb8856606 hw_atl_rpfl2_accept_all_mc_packets_set(hw, true);
12524418919fSjohnjiang
12534418919fSjohnjiang return 0;
1254d30ea906Sjfb8856606 }
1255d30ea906Sjfb8856606
12564418919fSjohnjiang static int
atl_dev_allmulticast_disable(struct rte_eth_dev * dev)1257d30ea906Sjfb8856606 atl_dev_allmulticast_disable(struct rte_eth_dev *dev)
1258d30ea906Sjfb8856606 {
1259d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1260d30ea906Sjfb8856606
1261d30ea906Sjfb8856606 if (dev->data->promiscuous == 1)
12624418919fSjohnjiang return 0; /* must remain in all_multicast mode */
1263d30ea906Sjfb8856606
1264d30ea906Sjfb8856606 hw_atl_rpfl2_accept_all_mc_packets_set(hw, false);
12654418919fSjohnjiang
12664418919fSjohnjiang return 0;
1267d30ea906Sjfb8856606 }
1268d30ea906Sjfb8856606
1269d30ea906Sjfb8856606 /**
1270d30ea906Sjfb8856606 * It clears the interrupt causes and enables the interrupt.
1271d30ea906Sjfb8856606 * It will be called once only during nic initialized.
1272d30ea906Sjfb8856606 *
1273d30ea906Sjfb8856606 * @param dev
1274d30ea906Sjfb8856606 * Pointer to struct rte_eth_dev.
1275d30ea906Sjfb8856606 * @param on
1276d30ea906Sjfb8856606 * Enable or Disable.
1277d30ea906Sjfb8856606 *
1278d30ea906Sjfb8856606 * @return
1279d30ea906Sjfb8856606 * - On success, zero.
1280d30ea906Sjfb8856606 * - On failure, a negative value.
1281d30ea906Sjfb8856606 */
1282d30ea906Sjfb8856606
1283d30ea906Sjfb8856606 static int
atl_dev_lsc_interrupt_setup(struct rte_eth_dev * dev,uint8_t on __rte_unused)1284d30ea906Sjfb8856606 atl_dev_lsc_interrupt_setup(struct rte_eth_dev *dev, uint8_t on __rte_unused)
1285d30ea906Sjfb8856606 {
1286d30ea906Sjfb8856606 atl_dev_link_status_print(dev);
1287d30ea906Sjfb8856606 return 0;
1288d30ea906Sjfb8856606 }
1289d30ea906Sjfb8856606
1290d30ea906Sjfb8856606 static int
atl_dev_rxq_interrupt_setup(struct rte_eth_dev * dev __rte_unused)1291d30ea906Sjfb8856606 atl_dev_rxq_interrupt_setup(struct rte_eth_dev *dev __rte_unused)
1292d30ea906Sjfb8856606 {
1293d30ea906Sjfb8856606 return 0;
1294d30ea906Sjfb8856606 }
1295d30ea906Sjfb8856606
1296d30ea906Sjfb8856606
1297d30ea906Sjfb8856606 static int
atl_dev_interrupt_get_status(struct rte_eth_dev * dev)1298d30ea906Sjfb8856606 atl_dev_interrupt_get_status(struct rte_eth_dev *dev)
1299d30ea906Sjfb8856606 {
1300d30ea906Sjfb8856606 struct atl_interrupt *intr =
1301d30ea906Sjfb8856606 ATL_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
1302d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1303d30ea906Sjfb8856606 u64 cause = 0;
1304d30ea906Sjfb8856606
1305d30ea906Sjfb8856606 hw_atl_b0_hw_irq_read(hw, &cause);
1306d30ea906Sjfb8856606
1307d30ea906Sjfb8856606 atl_disable_intr(hw);
13084418919fSjohnjiang
13094418919fSjohnjiang if (cause & BIT(ATL_IRQ_CAUSE_LINK))
13104418919fSjohnjiang intr->flags |= ATL_FLAG_NEED_LINK_UPDATE;
1311d30ea906Sjfb8856606
1312d30ea906Sjfb8856606 return 0;
1313d30ea906Sjfb8856606 }
1314d30ea906Sjfb8856606
1315d30ea906Sjfb8856606 /**
1316d30ea906Sjfb8856606 * It gets and then prints the link status.
1317d30ea906Sjfb8856606 *
1318d30ea906Sjfb8856606 * @param dev
1319d30ea906Sjfb8856606 * Pointer to struct rte_eth_dev.
1320d30ea906Sjfb8856606 *
1321d30ea906Sjfb8856606 * @return
1322d30ea906Sjfb8856606 * - On success, zero.
1323d30ea906Sjfb8856606 * - On failure, a negative value.
1324d30ea906Sjfb8856606 */
1325d30ea906Sjfb8856606 static void
atl_dev_link_status_print(struct rte_eth_dev * dev)1326d30ea906Sjfb8856606 atl_dev_link_status_print(struct rte_eth_dev *dev)
1327d30ea906Sjfb8856606 {
1328d30ea906Sjfb8856606 struct rte_eth_link link;
1329d30ea906Sjfb8856606
1330d30ea906Sjfb8856606 memset(&link, 0, sizeof(link));
1331d30ea906Sjfb8856606 rte_eth_linkstatus_get(dev, &link);
1332d30ea906Sjfb8856606 if (link.link_status) {
1333d30ea906Sjfb8856606 PMD_DRV_LOG(INFO, "Port %d: Link Up - speed %u Mbps - %s",
1334d30ea906Sjfb8856606 (int)(dev->data->port_id),
1335d30ea906Sjfb8856606 (unsigned int)link.link_speed,
1336d30ea906Sjfb8856606 link.link_duplex == ETH_LINK_FULL_DUPLEX ?
1337d30ea906Sjfb8856606 "full-duplex" : "half-duplex");
1338d30ea906Sjfb8856606 } else {
1339d30ea906Sjfb8856606 PMD_DRV_LOG(INFO, " Port %d: Link Down",
1340d30ea906Sjfb8856606 (int)(dev->data->port_id));
1341d30ea906Sjfb8856606 }
1342d30ea906Sjfb8856606
1343d30ea906Sjfb8856606
1344d30ea906Sjfb8856606 #ifdef DEBUG
1345d30ea906Sjfb8856606 {
1346d30ea906Sjfb8856606 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
1347d30ea906Sjfb8856606
1348d30ea906Sjfb8856606 PMD_DRV_LOG(DEBUG, "PCI Address: " PCI_PRI_FMT,
1349d30ea906Sjfb8856606 pci_dev->addr.domain,
1350d30ea906Sjfb8856606 pci_dev->addr.bus,
1351d30ea906Sjfb8856606 pci_dev->addr.devid,
1352d30ea906Sjfb8856606 pci_dev->addr.function);
1353d30ea906Sjfb8856606 }
1354d30ea906Sjfb8856606 #endif
1355d30ea906Sjfb8856606
1356d30ea906Sjfb8856606 PMD_DRV_LOG(INFO, "Link speed:%d", link.link_speed);
1357d30ea906Sjfb8856606 }
1358d30ea906Sjfb8856606
1359d30ea906Sjfb8856606 /*
1360d30ea906Sjfb8856606 * It executes link_update after knowing an interrupt occurred.
1361d30ea906Sjfb8856606 *
1362d30ea906Sjfb8856606 * @param dev
1363d30ea906Sjfb8856606 * Pointer to struct rte_eth_dev.
1364d30ea906Sjfb8856606 *
1365d30ea906Sjfb8856606 * @return
1366d30ea906Sjfb8856606 * - On success, zero.
1367d30ea906Sjfb8856606 * - On failure, a negative value.
1368d30ea906Sjfb8856606 */
1369d30ea906Sjfb8856606 static int
atl_dev_interrupt_action(struct rte_eth_dev * dev,struct rte_intr_handle * intr_handle)1370d30ea906Sjfb8856606 atl_dev_interrupt_action(struct rte_eth_dev *dev,
1371d30ea906Sjfb8856606 struct rte_intr_handle *intr_handle)
1372d30ea906Sjfb8856606 {
1373d30ea906Sjfb8856606 struct atl_interrupt *intr =
1374d30ea906Sjfb8856606 ATL_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
13754418919fSjohnjiang struct atl_adapter *adapter = dev->data->dev_private;
13764418919fSjohnjiang struct aq_hw_s *hw = &adapter->hw;
1377d30ea906Sjfb8856606
13784418919fSjohnjiang if (!(intr->flags & ATL_FLAG_NEED_LINK_UPDATE))
13794418919fSjohnjiang goto done;
13804418919fSjohnjiang
1381d30ea906Sjfb8856606 intr->flags &= ~ATL_FLAG_NEED_LINK_UPDATE;
13824418919fSjohnjiang
13834418919fSjohnjiang /* Notify userapp if link status changed */
13844418919fSjohnjiang if (!atl_dev_link_update(dev, 0)) {
1385d30ea906Sjfb8856606 atl_dev_link_status_print(dev);
1386*2d9fd380Sjfb8856606 rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC, NULL);
13874418919fSjohnjiang } else {
13884418919fSjohnjiang if (hw->aq_fw_ops->send_macsec_req == NULL)
13894418919fSjohnjiang goto done;
1390d30ea906Sjfb8856606
13914418919fSjohnjiang /* Check macsec Keys expired */
13924418919fSjohnjiang struct get_stats req = { 0 };
13934418919fSjohnjiang struct macsec_msg_fw_request msg = { 0 };
13944418919fSjohnjiang struct macsec_msg_fw_response resp = { 0 };
13954418919fSjohnjiang
13964418919fSjohnjiang req.ingress_sa_index = 0x0;
13974418919fSjohnjiang req.egress_sc_index = 0x0;
13984418919fSjohnjiang req.egress_sa_index = 0x0;
13994418919fSjohnjiang msg.msg_type = macsec_get_stats_msg;
14004418919fSjohnjiang msg.stats = req;
14014418919fSjohnjiang
14024418919fSjohnjiang int err = hw->aq_fw_ops->send_macsec_req(hw, &msg, &resp);
14034418919fSjohnjiang if (err) {
14044418919fSjohnjiang PMD_DRV_LOG(ERR, "send_macsec_req fail");
14054418919fSjohnjiang goto done;
14064418919fSjohnjiang }
14074418919fSjohnjiang if (resp.stats.egress_threshold_expired ||
14084418919fSjohnjiang resp.stats.ingress_threshold_expired ||
14094418919fSjohnjiang resp.stats.egress_expired ||
14104418919fSjohnjiang resp.stats.ingress_expired) {
14114418919fSjohnjiang PMD_DRV_LOG(INFO, "RTE_ETH_EVENT_MACSEC");
1412*2d9fd380Sjfb8856606 rte_eth_dev_callback_process(dev,
14134418919fSjohnjiang RTE_ETH_EVENT_MACSEC, NULL);
14144418919fSjohnjiang }
14154418919fSjohnjiang }
14164418919fSjohnjiang done:
1417d30ea906Sjfb8856606 atl_enable_intr(dev);
14184418919fSjohnjiang rte_intr_ack(intr_handle);
1419d30ea906Sjfb8856606
1420d30ea906Sjfb8856606 return 0;
1421d30ea906Sjfb8856606 }
1422d30ea906Sjfb8856606
1423d30ea906Sjfb8856606 /**
1424d30ea906Sjfb8856606 * Interrupt handler triggered by NIC for handling
1425d30ea906Sjfb8856606 * specific interrupt.
1426d30ea906Sjfb8856606 *
1427d30ea906Sjfb8856606 * @param handle
1428d30ea906Sjfb8856606 * Pointer to interrupt handle.
1429d30ea906Sjfb8856606 * @param param
1430d30ea906Sjfb8856606 * The address of parameter (struct rte_eth_dev *) regsitered before.
1431d30ea906Sjfb8856606 *
1432d30ea906Sjfb8856606 * @return
1433d30ea906Sjfb8856606 * void
1434d30ea906Sjfb8856606 */
1435d30ea906Sjfb8856606 static void
atl_dev_interrupt_handler(void * param)1436d30ea906Sjfb8856606 atl_dev_interrupt_handler(void *param)
1437d30ea906Sjfb8856606 {
1438d30ea906Sjfb8856606 struct rte_eth_dev *dev = (struct rte_eth_dev *)param;
1439d30ea906Sjfb8856606
1440d30ea906Sjfb8856606 atl_dev_interrupt_get_status(dev);
1441d30ea906Sjfb8856606 atl_dev_interrupt_action(dev, dev->intr_handle);
1442d30ea906Sjfb8856606 }
1443d30ea906Sjfb8856606
14444418919fSjohnjiang
1445d30ea906Sjfb8856606 static int
atl_dev_get_eeprom_length(struct rte_eth_dev * dev __rte_unused)1446d30ea906Sjfb8856606 atl_dev_get_eeprom_length(struct rte_eth_dev *dev __rte_unused)
1447d30ea906Sjfb8856606 {
1448d30ea906Sjfb8856606 return SFP_EEPROM_SIZE;
1449d30ea906Sjfb8856606 }
1450d30ea906Sjfb8856606
atl_dev_get_eeprom(struct rte_eth_dev * dev,struct rte_dev_eeprom_info * eeprom)14514418919fSjohnjiang int atl_dev_get_eeprom(struct rte_eth_dev *dev,
14524418919fSjohnjiang struct rte_dev_eeprom_info *eeprom)
1453d30ea906Sjfb8856606 {
1454d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
14554418919fSjohnjiang uint32_t dev_addr = SMBUS_DEVICE_ID;
1456d30ea906Sjfb8856606
1457d30ea906Sjfb8856606 if (hw->aq_fw_ops->get_eeprom == NULL)
1458d30ea906Sjfb8856606 return -ENOTSUP;
1459d30ea906Sjfb8856606
14601646932aSjfb8856606 if (eeprom->length + eeprom->offset > SFP_EEPROM_SIZE ||
14611646932aSjfb8856606 eeprom->data == NULL)
1462d30ea906Sjfb8856606 return -EINVAL;
1463d30ea906Sjfb8856606
14641646932aSjfb8856606 if (eeprom->magic > 0x7F)
14651646932aSjfb8856606 return -EINVAL;
14661646932aSjfb8856606
14671646932aSjfb8856606 if (eeprom->magic)
14681646932aSjfb8856606 dev_addr = eeprom->magic;
14691646932aSjfb8856606
14701646932aSjfb8856606 return hw->aq_fw_ops->get_eeprom(hw, dev_addr, eeprom->data,
14711646932aSjfb8856606 eeprom->length, eeprom->offset);
1472d30ea906Sjfb8856606 }
1473d30ea906Sjfb8856606
atl_dev_set_eeprom(struct rte_eth_dev * dev,struct rte_dev_eeprom_info * eeprom)14744418919fSjohnjiang int atl_dev_set_eeprom(struct rte_eth_dev *dev,
14754418919fSjohnjiang struct rte_dev_eeprom_info *eeprom)
1476d30ea906Sjfb8856606 {
1477d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
14784418919fSjohnjiang uint32_t dev_addr = SMBUS_DEVICE_ID;
1479d30ea906Sjfb8856606
1480d30ea906Sjfb8856606 if (hw->aq_fw_ops->set_eeprom == NULL)
1481d30ea906Sjfb8856606 return -ENOTSUP;
1482d30ea906Sjfb8856606
14831646932aSjfb8856606 if (eeprom->length + eeprom->offset > SFP_EEPROM_SIZE ||
14841646932aSjfb8856606 eeprom->data == NULL)
1485d30ea906Sjfb8856606 return -EINVAL;
1486d30ea906Sjfb8856606
14871646932aSjfb8856606 if (eeprom->magic > 0x7F)
14881646932aSjfb8856606 return -EINVAL;
14891646932aSjfb8856606
14901646932aSjfb8856606 if (eeprom->magic)
14911646932aSjfb8856606 dev_addr = eeprom->magic;
14921646932aSjfb8856606
14931646932aSjfb8856606 return hw->aq_fw_ops->set_eeprom(hw, dev_addr, eeprom->data,
14941646932aSjfb8856606 eeprom->length, eeprom->offset);
1495d30ea906Sjfb8856606 }
1496d30ea906Sjfb8856606
1497d30ea906Sjfb8856606 static int
atl_dev_get_regs(struct rte_eth_dev * dev,struct rte_dev_reg_info * regs)1498d30ea906Sjfb8856606 atl_dev_get_regs(struct rte_eth_dev *dev, struct rte_dev_reg_info *regs)
1499d30ea906Sjfb8856606 {
1500d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1501d30ea906Sjfb8856606 u32 mif_id;
1502d30ea906Sjfb8856606 int err;
1503d30ea906Sjfb8856606
1504d30ea906Sjfb8856606 if (regs->data == NULL) {
1505d30ea906Sjfb8856606 regs->length = hw_atl_utils_hw_get_reg_length();
1506d30ea906Sjfb8856606 regs->width = sizeof(u32);
1507d30ea906Sjfb8856606 return 0;
1508d30ea906Sjfb8856606 }
1509d30ea906Sjfb8856606
1510d30ea906Sjfb8856606 /* Only full register dump is supported */
1511d30ea906Sjfb8856606 if (regs->length && regs->length != hw_atl_utils_hw_get_reg_length())
1512d30ea906Sjfb8856606 return -ENOTSUP;
1513d30ea906Sjfb8856606
1514d30ea906Sjfb8856606 err = hw_atl_utils_hw_get_regs(hw, regs->data);
1515d30ea906Sjfb8856606
1516d30ea906Sjfb8856606 /* Device version */
1517d30ea906Sjfb8856606 mif_id = hw_atl_reg_glb_mif_id_get(hw);
1518d30ea906Sjfb8856606 regs->version = mif_id & 0xFFU;
1519d30ea906Sjfb8856606
1520d30ea906Sjfb8856606 return err;
1521d30ea906Sjfb8856606 }
1522d30ea906Sjfb8856606
1523d30ea906Sjfb8856606 static int
atl_flow_ctrl_get(struct rte_eth_dev * dev,struct rte_eth_fc_conf * fc_conf)1524d30ea906Sjfb8856606 atl_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
1525d30ea906Sjfb8856606 {
1526d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
15271646932aSjfb8856606 u32 fc = AQ_NIC_FC_OFF;
1528d30ea906Sjfb8856606
15291646932aSjfb8856606 if (hw->aq_fw_ops->get_flow_control == NULL)
15301646932aSjfb8856606 return -ENOTSUP;
15311646932aSjfb8856606
15321646932aSjfb8856606 hw->aq_fw_ops->get_flow_control(hw, &fc);
15331646932aSjfb8856606
15341646932aSjfb8856606 if (fc == AQ_NIC_FC_OFF)
1535d30ea906Sjfb8856606 fc_conf->mode = RTE_FC_NONE;
15361646932aSjfb8856606 else if ((fc & AQ_NIC_FC_RX) && (fc & AQ_NIC_FC_TX))
1537d30ea906Sjfb8856606 fc_conf->mode = RTE_FC_FULL;
15381646932aSjfb8856606 else if (fc & AQ_NIC_FC_RX)
1539d30ea906Sjfb8856606 fc_conf->mode = RTE_FC_RX_PAUSE;
15401646932aSjfb8856606 else if (fc & AQ_NIC_FC_TX)
1541d30ea906Sjfb8856606 fc_conf->mode = RTE_FC_TX_PAUSE;
15424418919fSjohnjiang
1543d30ea906Sjfb8856606 return 0;
1544d30ea906Sjfb8856606 }
1545d30ea906Sjfb8856606
1546d30ea906Sjfb8856606 static int
atl_flow_ctrl_set(struct rte_eth_dev * dev,struct rte_eth_fc_conf * fc_conf)1547d30ea906Sjfb8856606 atl_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
1548d30ea906Sjfb8856606 {
1549d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1550d30ea906Sjfb8856606 uint32_t old_flow_control = hw->aq_nic_cfg->flow_control;
1551d30ea906Sjfb8856606
1552d30ea906Sjfb8856606
1553d30ea906Sjfb8856606 if (hw->aq_fw_ops->set_flow_control == NULL)
1554d30ea906Sjfb8856606 return -ENOTSUP;
1555d30ea906Sjfb8856606
1556d30ea906Sjfb8856606 if (fc_conf->mode == RTE_FC_NONE)
1557d30ea906Sjfb8856606 hw->aq_nic_cfg->flow_control = AQ_NIC_FC_OFF;
1558d30ea906Sjfb8856606 else if (fc_conf->mode == RTE_FC_RX_PAUSE)
1559d30ea906Sjfb8856606 hw->aq_nic_cfg->flow_control = AQ_NIC_FC_RX;
1560d30ea906Sjfb8856606 else if (fc_conf->mode == RTE_FC_TX_PAUSE)
1561d30ea906Sjfb8856606 hw->aq_nic_cfg->flow_control = AQ_NIC_FC_TX;
1562d30ea906Sjfb8856606 else if (fc_conf->mode == RTE_FC_FULL)
1563d30ea906Sjfb8856606 hw->aq_nic_cfg->flow_control = (AQ_NIC_FC_RX | AQ_NIC_FC_TX);
1564d30ea906Sjfb8856606
1565d30ea906Sjfb8856606 if (old_flow_control != hw->aq_nic_cfg->flow_control)
1566d30ea906Sjfb8856606 return hw->aq_fw_ops->set_flow_control(hw);
1567d30ea906Sjfb8856606
1568d30ea906Sjfb8856606 return 0;
1569d30ea906Sjfb8856606 }
1570d30ea906Sjfb8856606
1571d30ea906Sjfb8856606 static int
atl_update_mac_addr(struct rte_eth_dev * dev,uint32_t index,u8 * mac_addr,bool enable)1572d30ea906Sjfb8856606 atl_update_mac_addr(struct rte_eth_dev *dev, uint32_t index,
1573d30ea906Sjfb8856606 u8 *mac_addr, bool enable)
1574d30ea906Sjfb8856606 {
1575d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1576d30ea906Sjfb8856606 unsigned int h = 0U;
1577d30ea906Sjfb8856606 unsigned int l = 0U;
1578d30ea906Sjfb8856606 int err;
1579d30ea906Sjfb8856606
1580d30ea906Sjfb8856606 if (mac_addr) {
1581d30ea906Sjfb8856606 h = (mac_addr[0] << 8) | (mac_addr[1]);
1582d30ea906Sjfb8856606 l = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
1583d30ea906Sjfb8856606 (mac_addr[4] << 8) | mac_addr[5];
1584d30ea906Sjfb8856606 }
1585d30ea906Sjfb8856606
1586d30ea906Sjfb8856606 hw_atl_rpfl2_uc_flr_en_set(hw, 0U, index);
1587d30ea906Sjfb8856606 hw_atl_rpfl2unicast_dest_addresslsw_set(hw, l, index);
1588d30ea906Sjfb8856606 hw_atl_rpfl2unicast_dest_addressmsw_set(hw, h, index);
1589d30ea906Sjfb8856606
1590d30ea906Sjfb8856606 if (enable)
1591d30ea906Sjfb8856606 hw_atl_rpfl2_uc_flr_en_set(hw, 1U, index);
1592d30ea906Sjfb8856606
1593d30ea906Sjfb8856606 err = aq_hw_err_from_flags(hw);
1594d30ea906Sjfb8856606
1595d30ea906Sjfb8856606 return err;
1596d30ea906Sjfb8856606 }
1597d30ea906Sjfb8856606
1598d30ea906Sjfb8856606 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)15994418919fSjohnjiang atl_add_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr,
1600d30ea906Sjfb8856606 uint32_t index __rte_unused, uint32_t pool __rte_unused)
1601d30ea906Sjfb8856606 {
16024418919fSjohnjiang if (rte_is_zero_ether_addr(mac_addr)) {
1603d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "Invalid Ethernet Address");
1604d30ea906Sjfb8856606 return -EINVAL;
1605d30ea906Sjfb8856606 }
1606d30ea906Sjfb8856606
1607d30ea906Sjfb8856606 return atl_update_mac_addr(dev, index, (u8 *)mac_addr, true);
1608d30ea906Sjfb8856606 }
1609d30ea906Sjfb8856606
1610d30ea906Sjfb8856606 static void
atl_remove_mac_addr(struct rte_eth_dev * dev,uint32_t index)1611d30ea906Sjfb8856606 atl_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index)
1612d30ea906Sjfb8856606 {
1613d30ea906Sjfb8856606 atl_update_mac_addr(dev, index, NULL, false);
1614d30ea906Sjfb8856606 }
1615d30ea906Sjfb8856606
1616d30ea906Sjfb8856606 static int
atl_set_default_mac_addr(struct rte_eth_dev * dev,struct rte_ether_addr * addr)16174418919fSjohnjiang atl_set_default_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *addr)
1618d30ea906Sjfb8856606 {
1619d30ea906Sjfb8856606 atl_remove_mac_addr(dev, 0);
1620d30ea906Sjfb8856606 atl_add_mac_addr(dev, addr, 0, 0);
1621d30ea906Sjfb8856606 return 0;
1622d30ea906Sjfb8856606 }
1623d30ea906Sjfb8856606
1624d30ea906Sjfb8856606 static int
atl_dev_mtu_set(struct rte_eth_dev * dev,uint16_t mtu)1625d30ea906Sjfb8856606 atl_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
1626d30ea906Sjfb8856606 {
1627d30ea906Sjfb8856606 struct rte_eth_dev_info dev_info;
16284418919fSjohnjiang int ret;
16294418919fSjohnjiang uint32_t frame_size = mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN;
1630d30ea906Sjfb8856606
16314418919fSjohnjiang ret = atl_dev_info_get(dev, &dev_info);
16324418919fSjohnjiang if (ret != 0)
16334418919fSjohnjiang return ret;
1634d30ea906Sjfb8856606
16354418919fSjohnjiang if (mtu < RTE_ETHER_MIN_MTU || frame_size > dev_info.max_rx_pktlen)
1636d30ea906Sjfb8856606 return -EINVAL;
1637d30ea906Sjfb8856606
1638d30ea906Sjfb8856606 /* update max frame size */
1639d30ea906Sjfb8856606 dev->data->dev_conf.rxmode.max_rx_pkt_len = frame_size;
1640d30ea906Sjfb8856606
1641d30ea906Sjfb8856606 return 0;
1642d30ea906Sjfb8856606 }
1643d30ea906Sjfb8856606
1644d30ea906Sjfb8856606 static int
atl_vlan_filter_set(struct rte_eth_dev * dev,uint16_t vlan_id,int on)1645d30ea906Sjfb8856606 atl_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
1646d30ea906Sjfb8856606 {
1647d30ea906Sjfb8856606 struct aq_hw_cfg_s *cfg =
1648d30ea906Sjfb8856606 ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
1649d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1650d30ea906Sjfb8856606 int err = 0;
1651d30ea906Sjfb8856606 int i = 0;
1652d30ea906Sjfb8856606
1653d30ea906Sjfb8856606 PMD_INIT_FUNC_TRACE();
1654d30ea906Sjfb8856606
1655d30ea906Sjfb8856606 for (i = 0; i < HW_ATL_B0_MAX_VLAN_IDS; i++) {
1656d30ea906Sjfb8856606 if (cfg->vlan_filter[i] == vlan_id) {
1657d30ea906Sjfb8856606 if (!on) {
1658d30ea906Sjfb8856606 /* Disable VLAN filter. */
1659d30ea906Sjfb8856606 hw_atl_rpf_vlan_flr_en_set(hw, 0U, i);
1660d30ea906Sjfb8856606
1661d30ea906Sjfb8856606 /* Clear VLAN filter entry */
1662d30ea906Sjfb8856606 cfg->vlan_filter[i] = 0;
1663d30ea906Sjfb8856606 }
1664d30ea906Sjfb8856606 break;
1665d30ea906Sjfb8856606 }
1666d30ea906Sjfb8856606 }
1667d30ea906Sjfb8856606
1668d30ea906Sjfb8856606 /* VLAN_ID was not found. So, nothing to delete. */
1669d30ea906Sjfb8856606 if (i == HW_ATL_B0_MAX_VLAN_IDS && !on)
1670d30ea906Sjfb8856606 goto exit;
1671d30ea906Sjfb8856606
1672d30ea906Sjfb8856606 /* VLAN_ID already exist, or already removed above. Nothing to do. */
1673d30ea906Sjfb8856606 if (i != HW_ATL_B0_MAX_VLAN_IDS)
1674d30ea906Sjfb8856606 goto exit;
1675d30ea906Sjfb8856606
1676d30ea906Sjfb8856606 /* Try to found free VLAN filter to add new VLAN_ID */
1677d30ea906Sjfb8856606 for (i = 0; i < HW_ATL_B0_MAX_VLAN_IDS; i++) {
1678d30ea906Sjfb8856606 if (cfg->vlan_filter[i] == 0)
1679d30ea906Sjfb8856606 break;
1680d30ea906Sjfb8856606 }
1681d30ea906Sjfb8856606
1682d30ea906Sjfb8856606 if (i == HW_ATL_B0_MAX_VLAN_IDS) {
1683d30ea906Sjfb8856606 /* We have no free VLAN filter to add new VLAN_ID*/
1684d30ea906Sjfb8856606 err = -ENOMEM;
1685d30ea906Sjfb8856606 goto exit;
1686d30ea906Sjfb8856606 }
1687d30ea906Sjfb8856606
1688d30ea906Sjfb8856606 cfg->vlan_filter[i] = vlan_id;
1689d30ea906Sjfb8856606 hw_atl_rpf_vlan_flr_act_set(hw, 1U, i);
1690d30ea906Sjfb8856606 hw_atl_rpf_vlan_id_flr_set(hw, vlan_id, i);
1691d30ea906Sjfb8856606 hw_atl_rpf_vlan_flr_en_set(hw, 1U, i);
1692d30ea906Sjfb8856606
1693d30ea906Sjfb8856606 exit:
1694d30ea906Sjfb8856606 /* Enable VLAN promisc mode if vlan_filter empty */
1695d30ea906Sjfb8856606 for (i = 0; i < HW_ATL_B0_MAX_VLAN_IDS; i++) {
1696d30ea906Sjfb8856606 if (cfg->vlan_filter[i] != 0)
1697d30ea906Sjfb8856606 break;
1698d30ea906Sjfb8856606 }
1699d30ea906Sjfb8856606
1700d30ea906Sjfb8856606 hw_atl_rpf_vlan_prom_mode_en_set(hw, i == HW_ATL_B0_MAX_VLAN_IDS);
1701d30ea906Sjfb8856606
1702d30ea906Sjfb8856606 return err;
1703d30ea906Sjfb8856606 }
1704d30ea906Sjfb8856606
1705d30ea906Sjfb8856606 static int
atl_enable_vlan_filter(struct rte_eth_dev * dev,int en)1706d30ea906Sjfb8856606 atl_enable_vlan_filter(struct rte_eth_dev *dev, int en)
1707d30ea906Sjfb8856606 {
1708d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1709d30ea906Sjfb8856606 struct aq_hw_cfg_s *cfg =
1710d30ea906Sjfb8856606 ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
1711d30ea906Sjfb8856606 int i;
1712d30ea906Sjfb8856606
1713d30ea906Sjfb8856606 PMD_INIT_FUNC_TRACE();
1714d30ea906Sjfb8856606
1715d30ea906Sjfb8856606 for (i = 0; i < HW_ATL_B0_MAX_VLAN_IDS; i++) {
1716d30ea906Sjfb8856606 if (cfg->vlan_filter[i])
1717d30ea906Sjfb8856606 hw_atl_rpf_vlan_flr_en_set(hw, en, i);
1718d30ea906Sjfb8856606 }
1719d30ea906Sjfb8856606 return 0;
1720d30ea906Sjfb8856606 }
1721d30ea906Sjfb8856606
1722d30ea906Sjfb8856606 static int
atl_vlan_offload_set(struct rte_eth_dev * dev,int mask)1723d30ea906Sjfb8856606 atl_vlan_offload_set(struct rte_eth_dev *dev, int mask)
1724d30ea906Sjfb8856606 {
1725d30ea906Sjfb8856606 struct aq_hw_cfg_s *cfg =
1726d30ea906Sjfb8856606 ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
1727d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1728d30ea906Sjfb8856606 int ret = 0;
1729d30ea906Sjfb8856606 int i;
1730d30ea906Sjfb8856606
1731d30ea906Sjfb8856606 PMD_INIT_FUNC_TRACE();
1732d30ea906Sjfb8856606
1733d30ea906Sjfb8856606 ret = atl_enable_vlan_filter(dev, mask & ETH_VLAN_FILTER_MASK);
1734d30ea906Sjfb8856606
1735d30ea906Sjfb8856606 cfg->vlan_strip = !!(mask & ETH_VLAN_STRIP_MASK);
1736d30ea906Sjfb8856606
1737d30ea906Sjfb8856606 for (i = 0; i < dev->data->nb_rx_queues; i++)
1738d30ea906Sjfb8856606 hw_atl_rpo_rx_desc_vlan_stripping_set(hw, cfg->vlan_strip, i);
1739d30ea906Sjfb8856606
1740d30ea906Sjfb8856606 if (mask & ETH_VLAN_EXTEND_MASK)
1741d30ea906Sjfb8856606 ret = -ENOTSUP;
1742d30ea906Sjfb8856606
1743d30ea906Sjfb8856606 return ret;
1744d30ea906Sjfb8856606 }
1745d30ea906Sjfb8856606
1746d30ea906Sjfb8856606 static int
atl_vlan_tpid_set(struct rte_eth_dev * dev,enum rte_vlan_type vlan_type,uint16_t tpid)1747d30ea906Sjfb8856606 atl_vlan_tpid_set(struct rte_eth_dev *dev, enum rte_vlan_type vlan_type,
1748d30ea906Sjfb8856606 uint16_t tpid)
1749d30ea906Sjfb8856606 {
1750d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1751d30ea906Sjfb8856606 int err = 0;
1752d30ea906Sjfb8856606
1753d30ea906Sjfb8856606 PMD_INIT_FUNC_TRACE();
1754d30ea906Sjfb8856606
1755d30ea906Sjfb8856606 switch (vlan_type) {
1756d30ea906Sjfb8856606 case ETH_VLAN_TYPE_INNER:
1757d30ea906Sjfb8856606 hw_atl_rpf_vlan_inner_etht_set(hw, tpid);
1758d30ea906Sjfb8856606 break;
1759d30ea906Sjfb8856606 case ETH_VLAN_TYPE_OUTER:
1760d30ea906Sjfb8856606 hw_atl_rpf_vlan_outer_etht_set(hw, tpid);
1761d30ea906Sjfb8856606 break;
1762d30ea906Sjfb8856606 default:
1763d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "Unsupported VLAN type");
1764d30ea906Sjfb8856606 err = -ENOTSUP;
1765d30ea906Sjfb8856606 }
1766d30ea906Sjfb8856606
1767d30ea906Sjfb8856606 return err;
1768d30ea906Sjfb8856606 }
1769d30ea906Sjfb8856606
1770d30ea906Sjfb8856606 static void
atl_vlan_strip_queue_set(struct rte_eth_dev * dev,uint16_t queue_id,int on)1771d30ea906Sjfb8856606 atl_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue_id, int on)
1772d30ea906Sjfb8856606 {
1773d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1774d30ea906Sjfb8856606
1775d30ea906Sjfb8856606 PMD_INIT_FUNC_TRACE();
1776d30ea906Sjfb8856606
1777d30ea906Sjfb8856606 if (queue_id > dev->data->nb_rx_queues) {
1778d30ea906Sjfb8856606 PMD_DRV_LOG(ERR, "Invalid queue id");
1779d30ea906Sjfb8856606 return;
1780d30ea906Sjfb8856606 }
1781d30ea906Sjfb8856606
1782d30ea906Sjfb8856606 hw_atl_rpo_rx_desc_vlan_stripping_set(hw, on, queue_id);
1783d30ea906Sjfb8856606 }
1784d30ea906Sjfb8856606
1785d30ea906Sjfb8856606 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)1786d30ea906Sjfb8856606 atl_dev_set_mc_addr_list(struct rte_eth_dev *dev,
17874418919fSjohnjiang struct rte_ether_addr *mc_addr_set,
1788d30ea906Sjfb8856606 uint32_t nb_mc_addr)
1789d30ea906Sjfb8856606 {
1790d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1791d30ea906Sjfb8856606 u32 i;
1792d30ea906Sjfb8856606
1793d30ea906Sjfb8856606 if (nb_mc_addr > AQ_HW_MULTICAST_ADDRESS_MAX - HW_ATL_B0_MAC_MIN)
1794d30ea906Sjfb8856606 return -EINVAL;
1795d30ea906Sjfb8856606
1796d30ea906Sjfb8856606 /* Update whole uc filters table */
1797d30ea906Sjfb8856606 for (i = 0; i < AQ_HW_MULTICAST_ADDRESS_MAX - HW_ATL_B0_MAC_MIN; i++) {
1798d30ea906Sjfb8856606 u8 *mac_addr = NULL;
1799d30ea906Sjfb8856606 u32 l = 0, h = 0;
1800d30ea906Sjfb8856606
1801d30ea906Sjfb8856606 if (i < nb_mc_addr) {
1802d30ea906Sjfb8856606 mac_addr = mc_addr_set[i].addr_bytes;
1803d30ea906Sjfb8856606 l = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
1804d30ea906Sjfb8856606 (mac_addr[4] << 8) | mac_addr[5];
1805d30ea906Sjfb8856606 h = (mac_addr[0] << 8) | mac_addr[1];
1806d30ea906Sjfb8856606 }
1807d30ea906Sjfb8856606
1808d30ea906Sjfb8856606 hw_atl_rpfl2_uc_flr_en_set(hw, 0U, HW_ATL_B0_MAC_MIN + i);
1809d30ea906Sjfb8856606 hw_atl_rpfl2unicast_dest_addresslsw_set(hw, l,
1810d30ea906Sjfb8856606 HW_ATL_B0_MAC_MIN + i);
1811d30ea906Sjfb8856606 hw_atl_rpfl2unicast_dest_addressmsw_set(hw, h,
1812d30ea906Sjfb8856606 HW_ATL_B0_MAC_MIN + i);
1813d30ea906Sjfb8856606 hw_atl_rpfl2_uc_flr_en_set(hw, !!mac_addr,
1814d30ea906Sjfb8856606 HW_ATL_B0_MAC_MIN + i);
1815d30ea906Sjfb8856606 }
1816d30ea906Sjfb8856606
1817d30ea906Sjfb8856606 return 0;
1818d30ea906Sjfb8856606 }
1819d30ea906Sjfb8856606
1820d30ea906Sjfb8856606 static int
atl_reta_update(struct rte_eth_dev * dev,struct rte_eth_rss_reta_entry64 * reta_conf,uint16_t reta_size)1821d30ea906Sjfb8856606 atl_reta_update(struct rte_eth_dev *dev,
1822d30ea906Sjfb8856606 struct rte_eth_rss_reta_entry64 *reta_conf,
1823d30ea906Sjfb8856606 uint16_t reta_size)
1824d30ea906Sjfb8856606 {
1825d30ea906Sjfb8856606 int i;
1826d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1827d30ea906Sjfb8856606 struct aq_hw_cfg_s *cf = ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
1828d30ea906Sjfb8856606
1829d30ea906Sjfb8856606 for (i = 0; i < reta_size && i < cf->aq_rss.indirection_table_size; i++)
1830d30ea906Sjfb8856606 cf->aq_rss.indirection_table[i] = min(reta_conf->reta[i],
1831d30ea906Sjfb8856606 dev->data->nb_rx_queues - 1);
1832d30ea906Sjfb8856606
1833d30ea906Sjfb8856606 hw_atl_b0_hw_rss_set(hw, &cf->aq_rss);
1834d30ea906Sjfb8856606 return 0;
1835d30ea906Sjfb8856606 }
1836d30ea906Sjfb8856606
1837d30ea906Sjfb8856606 static int
atl_reta_query(struct rte_eth_dev * dev,struct rte_eth_rss_reta_entry64 * reta_conf,uint16_t reta_size)1838d30ea906Sjfb8856606 atl_reta_query(struct rte_eth_dev *dev,
1839d30ea906Sjfb8856606 struct rte_eth_rss_reta_entry64 *reta_conf,
1840d30ea906Sjfb8856606 uint16_t reta_size)
1841d30ea906Sjfb8856606 {
1842d30ea906Sjfb8856606 int i;
1843d30ea906Sjfb8856606 struct aq_hw_cfg_s *cf = ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
1844d30ea906Sjfb8856606
1845d30ea906Sjfb8856606 for (i = 0; i < reta_size && i < cf->aq_rss.indirection_table_size; i++)
1846d30ea906Sjfb8856606 reta_conf->reta[i] = cf->aq_rss.indirection_table[i];
1847d30ea906Sjfb8856606 reta_conf->mask = ~0U;
1848d30ea906Sjfb8856606 return 0;
1849d30ea906Sjfb8856606 }
1850d30ea906Sjfb8856606
1851d30ea906Sjfb8856606 static int
atl_rss_hash_update(struct rte_eth_dev * dev,struct rte_eth_rss_conf * rss_conf)1852d30ea906Sjfb8856606 atl_rss_hash_update(struct rte_eth_dev *dev,
1853d30ea906Sjfb8856606 struct rte_eth_rss_conf *rss_conf)
1854d30ea906Sjfb8856606 {
1855d30ea906Sjfb8856606 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1856d30ea906Sjfb8856606 struct aq_hw_cfg_s *cfg =
1857d30ea906Sjfb8856606 ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
1858d30ea906Sjfb8856606 static u8 def_rss_key[40] = {
1859d30ea906Sjfb8856606 0x1e, 0xad, 0x71, 0x87, 0x65, 0xfc, 0x26, 0x7d,
1860d30ea906Sjfb8856606 0x0d, 0x45, 0x67, 0x74, 0xcd, 0x06, 0x1a, 0x18,
1861d30ea906Sjfb8856606 0xb6, 0xc1, 0xf0, 0xc7, 0xbb, 0x18, 0xbe, 0xf8,
1862d30ea906Sjfb8856606 0x19, 0x13, 0x4b, 0xa9, 0xd0, 0x3e, 0xfe, 0x70,
1863d30ea906Sjfb8856606 0x25, 0x03, 0xab, 0x50, 0x6a, 0x8b, 0x82, 0x0c
1864d30ea906Sjfb8856606 };
1865d30ea906Sjfb8856606
1866d30ea906Sjfb8856606 cfg->is_rss = !!rss_conf->rss_hf;
1867d30ea906Sjfb8856606 if (rss_conf->rss_key) {
1868d30ea906Sjfb8856606 memcpy(cfg->aq_rss.hash_secret_key, rss_conf->rss_key,
1869d30ea906Sjfb8856606 rss_conf->rss_key_len);
1870d30ea906Sjfb8856606 cfg->aq_rss.hash_secret_key_size = rss_conf->rss_key_len;
1871d30ea906Sjfb8856606 } else {
1872d30ea906Sjfb8856606 memcpy(cfg->aq_rss.hash_secret_key, def_rss_key,
1873d30ea906Sjfb8856606 sizeof(def_rss_key));
1874d30ea906Sjfb8856606 cfg->aq_rss.hash_secret_key_size = sizeof(def_rss_key);
1875d30ea906Sjfb8856606 }
1876d30ea906Sjfb8856606
1877d30ea906Sjfb8856606 hw_atl_b0_hw_rss_set(hw, &cfg->aq_rss);
1878d30ea906Sjfb8856606 hw_atl_b0_hw_rss_hash_set(hw, &cfg->aq_rss);
1879d30ea906Sjfb8856606 return 0;
1880d30ea906Sjfb8856606 }
1881d30ea906Sjfb8856606
1882d30ea906Sjfb8856606 static int
atl_rss_hash_conf_get(struct rte_eth_dev * dev,struct rte_eth_rss_conf * rss_conf)1883d30ea906Sjfb8856606 atl_rss_hash_conf_get(struct rte_eth_dev *dev,
1884d30ea906Sjfb8856606 struct rte_eth_rss_conf *rss_conf)
1885d30ea906Sjfb8856606 {
1886d30ea906Sjfb8856606 struct aq_hw_cfg_s *cfg =
1887d30ea906Sjfb8856606 ATL_DEV_PRIVATE_TO_CFG(dev->data->dev_private);
1888d30ea906Sjfb8856606
1889d30ea906Sjfb8856606 rss_conf->rss_hf = cfg->is_rss ? ATL_RSS_OFFLOAD_ALL : 0;
1890d30ea906Sjfb8856606 if (rss_conf->rss_key) {
1891d30ea906Sjfb8856606 rss_conf->rss_key_len = cfg->aq_rss.hash_secret_key_size;
1892d30ea906Sjfb8856606 memcpy(rss_conf->rss_key, cfg->aq_rss.hash_secret_key,
1893d30ea906Sjfb8856606 rss_conf->rss_key_len);
1894d30ea906Sjfb8856606 }
1895d30ea906Sjfb8856606
1896d30ea906Sjfb8856606 return 0;
1897d30ea906Sjfb8856606 }
1898d30ea906Sjfb8856606
18994418919fSjohnjiang static bool
is_device_supported(struct rte_eth_dev * dev,struct rte_pci_driver * drv)19004418919fSjohnjiang is_device_supported(struct rte_eth_dev *dev, struct rte_pci_driver *drv)
19014418919fSjohnjiang {
19024418919fSjohnjiang if (strcmp(dev->device->driver->name, drv->driver.name))
19034418919fSjohnjiang return false;
19044418919fSjohnjiang
19054418919fSjohnjiang return true;
19064418919fSjohnjiang }
19074418919fSjohnjiang
19084418919fSjohnjiang bool
is_atlantic_supported(struct rte_eth_dev * dev)19094418919fSjohnjiang is_atlantic_supported(struct rte_eth_dev *dev)
19104418919fSjohnjiang {
19114418919fSjohnjiang return is_device_supported(dev, &rte_atl_pmd);
19124418919fSjohnjiang }
19134418919fSjohnjiang
1914d30ea906Sjfb8856606 RTE_PMD_REGISTER_PCI(net_atlantic, rte_atl_pmd);
1915d30ea906Sjfb8856606 RTE_PMD_REGISTER_PCI_TABLE(net_atlantic, pci_id_atl_map);
1916d30ea906Sjfb8856606 RTE_PMD_REGISTER_KMOD_DEP(net_atlantic, "* igb_uio | uio_pci_generic");
1917*2d9fd380Sjfb8856606 RTE_LOG_REGISTER(atl_logtype_init, pmd.net.atlantic.init, NOTICE);
1918*2d9fd380Sjfb8856606 RTE_LOG_REGISTER(atl_logtype_driver, pmd.net.atlantic.driver, NOTICE);
1919