net/atlantic: implement core logic for Tx/Rx
[dpdk.git] / drivers / net / atlantic / atl_ethdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Aquantia Corporation
3  */
4
5 #include <rte_ethdev_pci.h>
6
7 #include "atl_ethdev.h"
8 #include "atl_common.h"
9 #include "atl_hw_regs.h"
10 #include "atl_logs.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"
14
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);
17
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);
23
24 static int atl_fw_version_get(struct rte_eth_dev *dev, char *fw_version,
25                               size_t fw_size);
26
27 static void atl_dev_info_get(struct rte_eth_dev *dev,
28                                struct rte_eth_dev_info *dev_info);
29
30
31 static int eth_atl_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
32         struct rte_pci_device *pci_dev);
33 static int eth_atl_pci_remove(struct rte_pci_device *pci_dev);
34
35 static void atl_dev_info_get(struct rte_eth_dev *dev,
36                                 struct rte_eth_dev_info *dev_info);
37
38 int atl_logtype_init;
39 int atl_logtype_driver;
40
41 /*
42  * The set of PCI devices this driver supports
43  */
44 static const struct rte_pci_id pci_id_atl_map[] = {
45         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_0001) },
46         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_D100) },
47         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_D107) },
48         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_D108) },
49         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_D109) },
50
51         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC100) },
52         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC107) },
53         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC108) },
54         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC109) },
55         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC111) },
56         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC112) },
57
58         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC100S) },
59         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC107S) },
60         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC108S) },
61         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC109S) },
62         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC111S) },
63         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC112S) },
64
65         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC111E) },
66         { RTE_PCI_DEVICE(PCI_VENDOR_ID_AQUANTIA, AQ_DEVICE_ID_AQC112E) },
67         { .vendor_id = 0, /* sentinel */ },
68 };
69
70 static struct rte_pci_driver rte_atl_pmd = {
71         .id_table = pci_id_atl_map,
72         .drv_flags = RTE_PCI_DRV_NEED_MAPPING |
73                      RTE_PCI_DRV_IOVA_AS_VA,
74         .probe = eth_atl_pci_probe,
75         .remove = eth_atl_pci_remove,
76 };
77
78 static const struct eth_dev_ops atl_eth_dev_ops = {
79         .dev_configure        = atl_dev_configure,
80         .dev_start            = atl_dev_start,
81         .dev_stop             = atl_dev_stop,
82         .dev_close            = atl_dev_close,
83         .dev_reset            = atl_dev_reset,
84
85         .fw_version_get       = atl_fw_version_get,
86         .dev_infos_get        = atl_dev_info_get,
87 };
88
89 static inline int32_t
90 atl_reset_hw(struct aq_hw_s *hw)
91 {
92         return hw_atl_b0_hw_reset(hw);
93 }
94
95 static int
96 eth_atl_dev_init(struct rte_eth_dev *eth_dev)
97 {
98         struct atl_adapter *adapter =
99                 (struct atl_adapter *)eth_dev->data->dev_private;
100         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
101         struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
102         int err = 0;
103
104         PMD_INIT_FUNC_TRACE();
105
106         eth_dev->dev_ops = &atl_eth_dev_ops;
107         eth_dev->rx_pkt_burst = &atl_recv_pkts;
108         eth_dev->tx_pkt_burst = &atl_xmit_pkts;
109         eth_dev->tx_pkt_prepare = &atl_prep_pkts;
110
111         /* For secondary processes, the primary process has done all the work */
112         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
113                 return 0;
114
115         /* Vendor and Device ID need to be set before init of shared code */
116         hw->device_id = pci_dev->id.device_id;
117         hw->vendor_id = pci_dev->id.vendor_id;
118         hw->mmio = (void *)pci_dev->mem_resource[0].addr;
119
120         /* Hardware configuration - hardcode */
121         adapter->hw_cfg.is_lro = false;
122         adapter->hw_cfg.wol = false;
123
124         hw->aq_nic_cfg = &adapter->hw_cfg;
125
126         /* Allocate memory for storing MAC addresses */
127         eth_dev->data->mac_addrs = rte_zmalloc("atlantic", ETHER_ADDR_LEN, 0);
128         if (eth_dev->data->mac_addrs == NULL) {
129                 PMD_INIT_LOG(ERR, "MAC Malloc failed");
130                 return -ENOMEM;
131         }
132
133         err = hw_atl_utils_initfw(hw, &hw->aq_fw_ops);
134         if (err)
135                 return err;
136
137         /* Copy the permanent MAC address */
138         if (hw->aq_fw_ops->get_mac_permanent(hw,
139                         eth_dev->data->mac_addrs->addr_bytes) != 0)
140                 return -EINVAL;
141
142         return err;
143 }
144
145 static int
146 eth_atl_dev_uninit(struct rte_eth_dev *eth_dev)
147 {
148         struct aq_hw_s *hw;
149
150         PMD_INIT_FUNC_TRACE();
151
152         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
153                 return -EPERM;
154
155         hw = ATL_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
156
157         if (hw->adapter_stopped == 0)
158                 atl_dev_close(eth_dev);
159
160         eth_dev->dev_ops = NULL;
161         eth_dev->rx_pkt_burst = NULL;
162         eth_dev->tx_pkt_burst = NULL;
163
164         rte_free(eth_dev->data->mac_addrs);
165         eth_dev->data->mac_addrs = NULL;
166
167         return 0;
168 }
169
170 static int
171 eth_atl_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
172         struct rte_pci_device *pci_dev)
173 {
174         return rte_eth_dev_pci_generic_probe(pci_dev,
175                 sizeof(struct atl_adapter), eth_atl_dev_init);
176 }
177
178 static int
179 eth_atl_pci_remove(struct rte_pci_device *pci_dev)
180 {
181         return rte_eth_dev_pci_generic_remove(pci_dev, eth_atl_dev_uninit);
182 }
183
184 static int
185 atl_dev_configure(struct rte_eth_dev *dev __rte_unused)
186 {
187         return 0;
188 }
189
190 /*
191  * Configure device link speed and setup link.
192  * It returns 0 on success.
193  */
194 static int
195 atl_dev_start(struct rte_eth_dev *dev)
196 {
197         struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
198         int status;
199         int err;
200
201         PMD_INIT_FUNC_TRACE();
202
203         /* set adapter started */
204         hw->adapter_stopped = 0;
205
206         /* reinitialize adapter
207          * this calls reset and start
208          */
209         status = atl_reset_hw(hw);
210         if (status != 0)
211                 return -EIO;
212
213         err = hw_atl_b0_hw_init(hw, dev->data->mac_addrs->addr_bytes);
214
215         hw_atl_b0_hw_start(hw);
216         /* initialize transmission unit */
217         atl_tx_init(dev);
218
219         /* This can fail when allocating mbufs for descriptor rings */
220         err = atl_rx_init(dev);
221         if (err) {
222                 PMD_INIT_LOG(ERR, "Unable to initialize RX hardware");
223                 return -EIO;
224         }
225
226         PMD_INIT_LOG(DEBUG, "FW version: %u.%u.%u",
227                 hw->fw_ver_actual >> 24,
228                 (hw->fw_ver_actual >> 16) & 0xFF,
229                 hw->fw_ver_actual & 0xFFFF);
230         PMD_INIT_LOG(DEBUG, "Driver version: %s", ATL_PMD_DRIVER_VERSION);
231
232         return err;
233 }
234
235 /*
236  * Stop device: disable rx and tx functions to allow for reconfiguring.
237  */
238 static void
239 atl_dev_stop(struct rte_eth_dev *dev)
240 {
241         struct aq_hw_s *hw =
242                 ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
243
244         /* reset the NIC */
245         atl_reset_hw(hw);
246         hw->adapter_stopped = 1;
247 }
248
249 /*
250  * Reset and stop device.
251  */
252 static void
253 atl_dev_close(struct rte_eth_dev *dev)
254 {
255         PMD_INIT_FUNC_TRACE();
256
257         atl_dev_stop(dev);
258 }
259
260 static int
261 atl_dev_reset(struct rte_eth_dev *dev)
262 {
263         int ret;
264
265         ret = eth_atl_dev_uninit(dev);
266         if (ret)
267                 return ret;
268
269         ret = eth_atl_dev_init(dev);
270
271         return ret;
272 }
273
274 static int
275 atl_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
276 {
277         struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
278         uint32_t fw_ver = 0;
279         unsigned int ret = 0;
280
281         ret = hw_atl_utils_get_fw_version(hw, &fw_ver);
282         if (ret)
283                 return -EIO;
284
285         ret = snprintf(fw_version, fw_size, "%u.%u.%u", fw_ver >> 24,
286                        (fw_ver >> 16) & 0xFFU, fw_ver & 0xFFFFU);
287
288         ret += 1; /* add string null-terminator */
289
290         if (fw_size < ret)
291                 return ret;
292
293         return 0;
294 }
295
296 static void
297 atl_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
298 {
299         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
300
301         dev_info->max_rx_queues = 0;
302         dev_info->max_rx_queues = 0;
303
304         dev_info->max_vfs = pci_dev->max_vfs;
305
306         dev_info->max_hash_mac_addrs = 0;
307         dev_info->max_vmdq_pools = 0;
308         dev_info->vmdq_queue_num = 0;
309 }
310
311 RTE_PMD_REGISTER_PCI(net_atlantic, rte_atl_pmd);
312 RTE_PMD_REGISTER_PCI_TABLE(net_atlantic, pci_id_atl_map);
313 RTE_PMD_REGISTER_KMOD_DEP(net_atlantic, "* igb_uio | uio_pci_generic");
314
315 RTE_INIT(atl_init_log)
316 {
317         atl_logtype_init = rte_log_register("pmd.net.atlantic.init");
318         if (atl_logtype_init >= 0)
319                 rte_log_set_level(atl_logtype_init, RTE_LOG_NOTICE);
320         atl_logtype_driver = rte_log_register("pmd.net.atlantic.driver");
321         if (atl_logtype_driver >= 0)
322                 rte_log_set_level(atl_logtype_driver, RTE_LOG_NOTICE);
323 }
324