1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Aquantia Corporation
5 #include <rte_ethdev_pci.h>
7 #include "atl_ethdev.h"
8 #include "atl_common.h"
9 #include "atl_hw_regs.h"
11 #include "hw_atl/hw_atl_llh.h"
12 #include "hw_atl/hw_atl_b0.h"
13 #include "hw_atl/hw_atl_b0_internal.h"
15 static int eth_atl_dev_init(struct rte_eth_dev *eth_dev);
16 static int eth_atl_dev_uninit(struct rte_eth_dev *eth_dev);
18 static int atl_dev_configure(struct rte_eth_dev *dev);
19 static int atl_dev_start(struct rte_eth_dev *dev);
20 static void atl_dev_stop(struct rte_eth_dev *dev);
21 static void atl_dev_close(struct rte_eth_dev *dev);
22 static int atl_dev_reset(struct rte_eth_dev *dev);
24 static int atl_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
27 static void atl_dev_info_get(struct rte_eth_dev *dev,
28 struct rte_eth_dev_info *dev_info);
30 static const uint32_t *atl_dev_supported_ptypes_get(struct rte_eth_dev *dev);
32 static int eth_atl_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
33 struct rte_pci_device *pci_dev);
34 static int eth_atl_pci_remove(struct rte_pci_device *pci_dev);
36 static void atl_dev_info_get(struct rte_eth_dev *dev,
37 struct rte_eth_dev_info *dev_info);
40 int atl_logtype_driver;
43 * The set of PCI devices this driver supports
45 static const struct rte_pci_id pci_id_atl_map[] = {
46 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_0001) },
47 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_D100) },
48 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_D107) },
49 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_D108) },
50 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_D109) },
52 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC100) },
53 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC107) },
54 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC108) },
55 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC109) },
56 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC111) },
57 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC112) },
59 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC100S) },
60 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC107S) },
61 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC108S) },
62 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC109S) },
63 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC111S) },
64 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC112S) },
66 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC111E) },
67 { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC112E) },
68 { .vendor_id = 0, /* sentinel */ },
71 static struct rte_pci_driver rte_atl_pmd = {
72 .id_table = pci_id_atl_map,
73 .drv_flags = RTE_PCI_DRV_NEED_MAPPING |
74 RTE_PCI_DRV_IOVA_AS_VA,
75 .probe = eth_atl_pci_probe,
76 .remove = eth_atl_pci_remove,
79 #define ATL_RX_OFFLOADS (DEV_RX_OFFLOAD_VLAN_STRIP \
80 | DEV_RX_OFFLOAD_IPV4_CKSUM \
81 | DEV_RX_OFFLOAD_UDP_CKSUM \
82 | DEV_RX_OFFLOAD_TCP_CKSUM \
83 | DEV_RX_OFFLOAD_JUMBO_FRAME)
85 #define ATL_TX_OFFLOADS (DEV_TX_OFFLOAD_VLAN_INSERT \
86 | DEV_TX_OFFLOAD_IPV4_CKSUM \
87 | DEV_TX_OFFLOAD_UDP_CKSUM \
88 | DEV_TX_OFFLOAD_TCP_CKSUM \
89 | DEV_TX_OFFLOAD_TCP_TSO \
90 | DEV_TX_OFFLOAD_MULTI_SEGS)
92 static const struct rte_eth_desc_lim rx_desc_lim = {
93 .nb_max = ATL_MAX_RING_DESC,
94 .nb_min = ATL_MIN_RING_DESC,
95 .nb_align = ATL_RXD_ALIGN,
98 static const struct rte_eth_desc_lim tx_desc_lim = {
99 .nb_max = ATL_MAX_RING_DESC,
100 .nb_min = ATL_MIN_RING_DESC,
101 .nb_align = ATL_TXD_ALIGN,
102 .nb_seg_max = ATL_TX_MAX_SEG,
103 .nb_mtu_seg_max = ATL_TX_MAX_SEG,
106 static const struct eth_dev_ops atl_eth_dev_ops = {
107 .dev_configure = atl_dev_configure,
108 .dev_start = atl_dev_start,
109 .dev_stop = atl_dev_stop,
110 .dev_close = atl_dev_close,
111 .dev_reset = atl_dev_reset,
113 .fw_version_get = atl_fw_version_get,
114 .dev_infos_get = atl_dev_info_get,
115 .dev_supported_ptypes_get = atl_dev_supported_ptypes_get,
118 .rx_queue_start = atl_rx_queue_start,
119 .rx_queue_stop = atl_rx_queue_stop,
120 .rx_queue_setup = atl_rx_queue_setup,
121 .rx_queue_release = atl_rx_queue_release,
123 .tx_queue_start = atl_tx_queue_start,
124 .tx_queue_stop = atl_tx_queue_stop,
125 .tx_queue_setup = atl_tx_queue_setup,
126 .tx_queue_release = atl_tx_queue_release,
129 static inline int32_t
130 atl_reset_hw(struct aq_hw_s *hw)
132 return hw_atl_b0_hw_reset(hw);
136 eth_atl_dev_init(struct rte_eth_dev *eth_dev)
138 struct atl_adapter *adapter =
139 (struct atl_adapter *)eth_dev->data->dev_private;
140 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
141 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
144 PMD_INIT_FUNC_TRACE();
146 eth_dev->dev_ops = &atl_eth_dev_ops;
147 eth_dev->rx_pkt_burst = &atl_recv_pkts;
148 eth_dev->tx_pkt_burst = &atl_xmit_pkts;
149 eth_dev->tx_pkt_prepare = &atl_prep_pkts;
151 /* For secondary processes, the primary process has done all the work */
152 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
155 /* Vendor and Device ID need to be set before init of shared code */
156 hw->device_id = pci_dev->id.device_id;
157 hw->vendor_id = pci_dev->id.vendor_id;
158 hw->mmio = (void *)pci_dev->mem_resource[0].addr;
160 /* Hardware configuration - hardcode */
161 adapter->hw_cfg.is_lro = false;
162 adapter->hw_cfg.wol = false;
164 hw->aq_nic_cfg = &adapter->hw_cfg;
166 /* Allocate memory for storing MAC addresses */
167 eth_dev->data->mac_addrs = rte_zmalloc("atlantic", ETHER_ADDR_LEN, 0);
168 if (eth_dev->data->mac_addrs == NULL) {
169 PMD_INIT_LOG(ERR, "MAC Malloc failed");
173 err = hw_atl_utils_initfw(hw, &hw->aq_fw_ops);
177 /* Copy the permanent MAC address */
178 if (hw->aq_fw_ops->get_mac_permanent(hw,
179 eth_dev->data->mac_addrs->addr_bytes) != 0)
186 eth_atl_dev_uninit(struct rte_eth_dev *eth_dev)
190 PMD_INIT_FUNC_TRACE();
192 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
195 hw = ATL_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
197 if (hw->adapter_stopped == 0)
198 atl_dev_close(eth_dev);
200 eth_dev->dev_ops = NULL;
201 eth_dev->rx_pkt_burst = NULL;
202 eth_dev->tx_pkt_burst = NULL;
204 rte_free(eth_dev->data->mac_addrs);
205 eth_dev->data->mac_addrs = NULL;
211 eth_atl_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
212 struct rte_pci_device *pci_dev)
214 return rte_eth_dev_pci_generic_probe(pci_dev,
215 sizeof(struct atl_adapter), eth_atl_dev_init);
219 eth_atl_pci_remove(struct rte_pci_device *pci_dev)
221 return rte_eth_dev_pci_generic_remove(pci_dev, eth_atl_dev_uninit);
225 atl_dev_configure(struct rte_eth_dev *dev __rte_unused)
231 * Configure device link speed and setup link.
232 * It returns 0 on success.
235 atl_dev_start(struct rte_eth_dev *dev)
237 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
241 PMD_INIT_FUNC_TRACE();
243 /* set adapter started */
244 hw->adapter_stopped = 0;
246 /* reinitialize adapter
247 * this calls reset and start
249 status = atl_reset_hw(hw);
253 err = hw_atl_b0_hw_init(hw, dev->data->mac_addrs->addr_bytes);
255 hw_atl_b0_hw_start(hw);
256 /* initialize transmission unit */
259 /* This can fail when allocating mbufs for descriptor rings */
260 err = atl_rx_init(dev);
262 PMD_INIT_LOG(ERR, "Unable to initialize RX hardware");
266 PMD_INIT_LOG(DEBUG, "FW version: %u.%u.%u",
267 hw->fw_ver_actual >> 24,
268 (hw->fw_ver_actual >> 16) & 0xFF,
269 hw->fw_ver_actual & 0xFFFF);
270 PMD_INIT_LOG(DEBUG, "Driver version: %s", ATL_PMD_DRIVER_VERSION);
272 err = atl_start_queues(dev);
274 PMD_INIT_LOG(ERR, "Unable to start rxtx queues");
281 atl_stop_queues(dev);
286 * Stop device: disable rx and tx functions to allow for reconfiguring.
289 atl_dev_stop(struct rte_eth_dev *dev)
292 ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
296 hw->adapter_stopped = 1;
298 atl_stop_queues(dev);
300 /* Clear stored conf */
301 dev->data->scattered_rx = 0;
306 * Reset and stop device.
309 atl_dev_close(struct rte_eth_dev *dev)
311 PMD_INIT_FUNC_TRACE();
315 atl_free_queues(dev);
319 atl_dev_reset(struct rte_eth_dev *dev)
323 ret = eth_atl_dev_uninit(dev);
327 ret = eth_atl_dev_init(dev);
333 atl_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
335 struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
337 unsigned int ret = 0;
339 ret = hw_atl_utils_get_fw_version(hw, &fw_ver);
343 ret = snprintf(fw_version, fw_size, "%u.%u.%u", fw_ver >> 24,
344 (fw_ver >> 16) & 0xFFU, fw_ver & 0xFFFFU);
346 ret += 1; /* add string null-terminator */
355 atl_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
357 struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
359 dev_info->max_rx_queues = AQ_HW_MAX_RX_QUEUES;
360 dev_info->max_tx_queues = AQ_HW_MAX_TX_QUEUES;
362 dev_info->min_rx_bufsize = 1024;
363 dev_info->max_rx_pktlen = HW_ATL_B0_MTU_JUMBO;
364 dev_info->max_mac_addrs = HW_ATL_B0_MAC_MAX;
365 dev_info->max_vfs = pci_dev->max_vfs;
367 dev_info->max_hash_mac_addrs = 0;
368 dev_info->max_vmdq_pools = 0;
369 dev_info->vmdq_queue_num = 0;
371 dev_info->rx_offload_capa = ATL_RX_OFFLOADS;
373 dev_info->tx_offload_capa = ATL_TX_OFFLOADS;
376 dev_info->default_rxconf = (struct rte_eth_rxconf) {
377 .rx_free_thresh = ATL_DEFAULT_RX_FREE_THRESH,
380 dev_info->default_txconf = (struct rte_eth_txconf) {
381 .tx_free_thresh = ATL_DEFAULT_TX_FREE_THRESH,
384 dev_info->rx_desc_lim = rx_desc_lim;
385 dev_info->tx_desc_lim = tx_desc_lim;
388 static const uint32_t *
389 atl_dev_supported_ptypes_get(struct rte_eth_dev *dev)
391 static const uint32_t ptypes[] = {
393 RTE_PTYPE_L2_ETHER_ARP,
394 RTE_PTYPE_L2_ETHER_VLAN,
404 if (dev->rx_pkt_burst == atl_recv_pkts)
410 RTE_PMD_REGISTER_PCI(net_atlantic, rte_atl_pmd);
411 RTE_PMD_REGISTER_PCI_TABLE(net_atlantic, pci_id_atl_map);
412 RTE_PMD_REGISTER_KMOD_DEP(net_atlantic, "* igb_uio | uio_pci_generic");
414 RTE_INIT(atl_init_log)
416 atl_logtype_init = rte_log_register("pmd.net.atlantic.init");
417 if (atl_logtype_init >= 0)
418 rte_log_set_level(atl_logtype_init, RTE_LOG_NOTICE);
419 atl_logtype_driver = rte_log_register("pmd.net.atlantic.driver");
420 if (atl_logtype_driver >= 0)
421 rte_log_set_level(atl_logtype_driver, RTE_LOG_NOTICE);