c32648f7beb49d769c72c34d114a45317666ce9c
[dpdk.git] / drivers / net / hns3 / hns3_ethdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018-2019 Hisilicon Limited.
3  */
4
5 #include <errno.h>
6 #include <stdarg.h>
7 #include <stdbool.h>
8 #include <stdio.h>
9 #include <stdint.h>
10 #include <inttypes.h>
11 #include <unistd.h>
12 #include <rte_bus_pci.h>
13 #include <rte_common.h>
14 #include <rte_cycles.h>
15 #include <rte_dev.h>
16 #include <rte_eal.h>
17 #include <rte_ether.h>
18 #include <rte_ethdev_driver.h>
19 #include <rte_ethdev_pci.h>
20 #include <rte_io.h>
21 #include <rte_log.h>
22 #include <rte_pci.h>
23
24 #include "hns3_ethdev.h"
25 #include "hns3_logs.h"
26 #include "hns3_regs.h"
27
28 int hns3_logtype_init;
29 int hns3_logtype_driver;
30
31 static int
32 hns3_init_pf(struct rte_eth_dev *eth_dev)
33 {
34         struct rte_device *dev = eth_dev->device;
35         struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(dev);
36         struct hns3_adapter *hns = eth_dev->data->dev_private;
37         struct hns3_hw *hw = &hns->hw;
38         int ret;
39
40         PMD_INIT_FUNC_TRACE();
41
42         /* Get hardware io base address from pcie BAR2 IO space */
43         hw->io_base = pci_dev->mem_resource[2].addr;
44
45         /* Firmware command queue initialize */
46         ret = hns3_cmd_init_queue(hw);
47         if (ret) {
48                 PMD_INIT_LOG(ERR, "Failed to init cmd queue: %d", ret);
49                 goto err_cmd_init_queue;
50         }
51
52         /* Firmware command initialize */
53         ret = hns3_cmd_init(hw);
54         if (ret) {
55                 PMD_INIT_LOG(ERR, "Failed to init cmd: %d", ret);
56                 goto err_cmd_init;
57         }
58
59         return 0;
60
61 err_cmd_init:
62         hns3_cmd_destroy_queue(hw);
63
64 err_cmd_init_queue:
65         hw->io_base = NULL;
66
67         return ret;
68 }
69
70 static void
71 hns3_uninit_pf(struct rte_eth_dev *eth_dev)
72 {
73         struct hns3_adapter *hns = eth_dev->data->dev_private;
74         struct hns3_hw *hw = &hns->hw;
75
76         PMD_INIT_FUNC_TRACE();
77
78         hns3_cmd_uninit(hw);
79         hns3_cmd_destroy_queue(hw);
80         hw->io_base = NULL;
81 }
82
83 static void
84 hns3_dev_close(struct rte_eth_dev *eth_dev)
85 {
86         struct hns3_adapter *hns = eth_dev->data->dev_private;
87         struct hns3_hw *hw = &hns->hw;
88
89         hw->adapter_state = HNS3_NIC_CLOSING;
90         hns3_uninit_pf(eth_dev);
91         hw->adapter_state = HNS3_NIC_CLOSED;
92 }
93
94 static const struct eth_dev_ops hns3_eth_dev_ops = {
95         .dev_close          = hns3_dev_close,
96 };
97
98 static int
99 hns3_dev_init(struct rte_eth_dev *eth_dev)
100 {
101         struct hns3_adapter *hns = eth_dev->data->dev_private;
102         struct hns3_hw *hw = &hns->hw;
103         int ret;
104
105         PMD_INIT_FUNC_TRACE();
106
107         eth_dev->dev_ops = &hns3_eth_dev_ops;
108         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
109                 return 0;
110
111         hw->adapter_state = HNS3_NIC_UNINITIALIZED;
112         hns->is_vf = false;
113         hw->data = eth_dev->data;
114
115         ret = hns3_init_pf(eth_dev);
116         if (ret) {
117                 PMD_INIT_LOG(ERR, "Failed to init pf: %d", ret);
118                 goto err_init_pf;
119         }
120         hw->adapter_state = HNS3_NIC_INITIALIZED;
121         /*
122          * Pass the information to the rte_eth_dev_close() that it should also
123          * release the private port resources.
124          */
125         eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE;
126
127         return 0;
128
129 err_init_pf:
130         eth_dev->dev_ops = NULL;
131         eth_dev->rx_pkt_burst = NULL;
132         eth_dev->tx_pkt_burst = NULL;
133         eth_dev->tx_pkt_prepare = NULL;
134         return ret;
135 }
136
137 static int
138 hns3_dev_uninit(struct rte_eth_dev *eth_dev)
139 {
140         struct hns3_adapter *hns = eth_dev->data->dev_private;
141         struct hns3_hw *hw = &hns->hw;
142
143         PMD_INIT_FUNC_TRACE();
144
145         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
146                 return -EPERM;
147
148         eth_dev->dev_ops = NULL;
149         eth_dev->rx_pkt_burst = NULL;
150         eth_dev->tx_pkt_burst = NULL;
151         eth_dev->tx_pkt_prepare = NULL;
152         if (hw->adapter_state < HNS3_NIC_CLOSING)
153                 hns3_dev_close(eth_dev);
154
155         hw->adapter_state = HNS3_NIC_REMOVED;
156         return 0;
157 }
158
159 static int
160 eth_hns3_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
161                    struct rte_pci_device *pci_dev)
162 {
163         return rte_eth_dev_pci_generic_probe(pci_dev,
164                                              sizeof(struct hns3_adapter),
165                                              hns3_dev_init);
166 }
167
168 static int
169 eth_hns3_pci_remove(struct rte_pci_device *pci_dev)
170 {
171         return rte_eth_dev_pci_generic_remove(pci_dev, hns3_dev_uninit);
172 }
173
174 static const struct rte_pci_id pci_id_hns3_map[] = {
175         { RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HNS3_DEV_ID_GE) },
176         { RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HNS3_DEV_ID_25GE) },
177         { RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HNS3_DEV_ID_25GE_RDMA) },
178         { RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HNS3_DEV_ID_50GE_RDMA) },
179         { RTE_PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, HNS3_DEV_ID_100G_RDMA_MACSEC) },
180         { .vendor_id = 0, /* sentinel */ },
181 };
182
183 static struct rte_pci_driver rte_hns3_pmd = {
184         .id_table = pci_id_hns3_map,
185         .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
186         .probe = eth_hns3_pci_probe,
187         .remove = eth_hns3_pci_remove,
188 };
189
190 RTE_PMD_REGISTER_PCI(net_hns3, rte_hns3_pmd);
191 RTE_PMD_REGISTER_PCI_TABLE(net_hns3, pci_id_hns3_map);
192 RTE_PMD_REGISTER_KMOD_DEP(net_hns3, "* igb_uio | vfio-pci");
193
194 RTE_INIT(hns3_init_log)
195 {
196         hns3_logtype_init = rte_log_register("pmd.net.hns3.init");
197         if (hns3_logtype_init >= 0)
198                 rte_log_set_level(hns3_logtype_init, RTE_LOG_NOTICE);
199         hns3_logtype_driver = rte_log_register("pmd.net.hns3.driver");
200         if (hns3_logtype_driver >= 0)
201                 rte_log_set_level(hns3_logtype_driver, RTE_LOG_NOTICE);
202 }