net/atlantic: configure device start/stop
[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
108         /* For secondary processes, the primary process has done all the work */
109         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
110                 return 0;
111
112         /* Vendor and Device ID need to be set before init of shared code */
113         hw->device_id = pci_dev->id.device_id;
114         hw->vendor_id = pci_dev->id.vendor_id;
115         hw->mmio = (void *)pci_dev->mem_resource[0].addr;
116
117         /* Hardware configuration - hardcode */
118         adapter->hw_cfg.is_lro = false;
119         adapter->hw_cfg.wol = false;
120
121         hw->aq_nic_cfg = &adapter->hw_cfg;
122
123         /* Allocate memory for storing MAC addresses */
124         eth_dev->data->mac_addrs = rte_zmalloc("atlantic", ETHER_ADDR_LEN, 0);
125         if (eth_dev->data->mac_addrs == NULL) {
126                 PMD_INIT_LOG(ERR, "MAC Malloc failed");
127                 return -ENOMEM;
128         }
129
130         err = hw_atl_utils_initfw(hw, &hw->aq_fw_ops);
131         if (err)
132                 return err;
133
134         /* Copy the permanent MAC address */
135         if (hw->aq_fw_ops->get_mac_permanent(hw,
136                         eth_dev->data->mac_addrs->addr_bytes) != 0)
137                 return -EINVAL;
138
139         return err;
140 }
141
142 static int
143 eth_atl_dev_uninit(struct rte_eth_dev *eth_dev)
144 {
145         struct aq_hw_s *hw;
146
147         PMD_INIT_FUNC_TRACE();
148
149         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
150                 return -EPERM;
151
152         hw = ATL_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
153
154         if (hw->adapter_stopped == 0)
155                 atl_dev_close(eth_dev);
156
157         eth_dev->dev_ops = NULL;
158
159         rte_free(eth_dev->data->mac_addrs);
160         eth_dev->data->mac_addrs = NULL;
161
162         return 0;
163 }
164
165 static int
166 eth_atl_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
167         struct rte_pci_device *pci_dev)
168 {
169         return rte_eth_dev_pci_generic_probe(pci_dev,
170                 sizeof(struct atl_adapter), eth_atl_dev_init);
171 }
172
173 static int
174 eth_atl_pci_remove(struct rte_pci_device *pci_dev)
175 {
176         return rte_eth_dev_pci_generic_remove(pci_dev, eth_atl_dev_uninit);
177 }
178
179 static int
180 atl_dev_configure(struct rte_eth_dev *dev __rte_unused)
181 {
182         return 0;
183 }
184
185 /*
186  * Configure device link speed and setup link.
187  * It returns 0 on success.
188  */
189 static int
190 atl_dev_start(struct rte_eth_dev *dev)
191 {
192         struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
193         int status;
194         int err;
195
196         PMD_INIT_FUNC_TRACE();
197
198         /* set adapter started */
199         hw->adapter_stopped = 0;
200
201         /* reinitialize adapter
202          * this calls reset and start
203          */
204         status = atl_reset_hw(hw);
205         if (status != 0)
206                 return -EIO;
207
208         err = hw_atl_b0_hw_init(hw, dev->data->mac_addrs->addr_bytes);
209
210         hw_atl_b0_hw_start(hw);
211
212         PMD_INIT_LOG(DEBUG, "FW version: %u.%u.%u",
213                 hw->fw_ver_actual >> 24,
214                 (hw->fw_ver_actual >> 16) & 0xFF,
215                 hw->fw_ver_actual & 0xFFFF);
216         PMD_INIT_LOG(DEBUG, "Driver version: %s", ATL_PMD_DRIVER_VERSION);
217
218         return err;
219 }
220
221 /*
222  * Stop device: disable rx and tx functions to allow for reconfiguring.
223  */
224 static void
225 atl_dev_stop(struct rte_eth_dev *dev)
226 {
227         struct aq_hw_s *hw =
228                 ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
229
230         /* reset the NIC */
231         atl_reset_hw(hw);
232         hw->adapter_stopped = 1;
233 }
234
235 /*
236  * Reset and stop device.
237  */
238 static void
239 atl_dev_close(struct rte_eth_dev *dev)
240 {
241         PMD_INIT_FUNC_TRACE();
242
243         atl_dev_stop(dev);
244 }
245
246 static int
247 atl_dev_reset(struct rte_eth_dev *dev)
248 {
249         int ret;
250
251         ret = eth_atl_dev_uninit(dev);
252         if (ret)
253                 return ret;
254
255         ret = eth_atl_dev_init(dev);
256
257         return ret;
258 }
259
260 static int
261 atl_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
262 {
263         struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
264         uint32_t fw_ver = 0;
265         unsigned int ret = 0;
266
267         ret = hw_atl_utils_get_fw_version(hw, &fw_ver);
268         if (ret)
269                 return -EIO;
270
271         ret = snprintf(fw_version, fw_size, "%u.%u.%u", fw_ver >> 24,
272                        (fw_ver >> 16) & 0xFFU, fw_ver & 0xFFFFU);
273
274         ret += 1; /* add string null-terminator */
275
276         if (fw_size < ret)
277                 return ret;
278
279         return 0;
280 }
281
282 static void
283 atl_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
284 {
285         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
286
287         dev_info->max_rx_queues = 0;
288         dev_info->max_rx_queues = 0;
289
290         dev_info->max_vfs = pci_dev->max_vfs;
291
292         dev_info->max_hash_mac_addrs = 0;
293         dev_info->max_vmdq_pools = 0;
294         dev_info->vmdq_queue_num = 0;
295 }
296
297 RTE_PMD_REGISTER_PCI(net_atlantic, rte_atl_pmd);
298 RTE_PMD_REGISTER_PCI_TABLE(net_atlantic, pci_id_atl_map);
299 RTE_PMD_REGISTER_KMOD_DEP(net_atlantic, "* igb_uio | uio_pci_generic");
300
301 RTE_INIT(atl_init_log)
302 {
303         atl_logtype_init = rte_log_register("pmd.net.atlantic.init");
304         if (atl_logtype_init >= 0)
305                 rte_log_set_level(atl_logtype_init, RTE_LOG_NOTICE);
306         atl_logtype_driver = rte_log_register("pmd.net.atlantic.driver");
307         if (atl_logtype_driver >= 0)
308                 rte_log_set_level(atl_logtype_driver, RTE_LOG_NOTICE);
309 }
310