net/txgbe: add device init and uninit
[dpdk.git] / drivers / net / txgbe / txgbe_ethdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2015-2020
3  */
4
5 #include <stdio.h>
6 #include <errno.h>
7 #include <stdint.h>
8 #include <string.h>
9 #include <rte_common.h>
10 #include <rte_ethdev_pci.h>
11 #include <rte_pci.h>
12 #include <rte_memory.h>
13
14 #include "txgbe_logs.h"
15 #include "base/txgbe.h"
16 #include "txgbe_ethdev.h"
17
18 static int txgbe_dev_close(struct rte_eth_dev *dev);
19
20 /*
21  * The set of PCI devices this driver supports
22  */
23 static const struct rte_pci_id pci_id_txgbe_map[] = {
24         { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, TXGBE_DEV_ID_RAPTOR_SFP) },
25         { RTE_PCI_DEVICE(PCI_VENDOR_ID_WANGXUN, TXGBE_DEV_ID_WX1820_SFP) },
26         { .vendor_id = 0, /* sentinel */ },
27 };
28
29 static const struct eth_dev_ops txgbe_eth_dev_ops;
30
31 static int
32 eth_txgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
33 {
34         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
35         struct txgbe_hw *hw = TXGBE_DEV_HW(eth_dev);
36         struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
37         const struct rte_memzone *mz;
38
39         PMD_INIT_FUNC_TRACE();
40
41         eth_dev->dev_ops = &txgbe_eth_dev_ops;
42
43         rte_eth_copy_pci_info(eth_dev, pci_dev);
44
45         /* Vendor and Device ID need to be set before init of shared code */
46         hw->device_id = pci_dev->id.device_id;
47         hw->vendor_id = pci_dev->id.vendor_id;
48         hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
49         hw->allow_unsupported_sfp = 1;
50
51         /* Reserve memory for interrupt status block */
52         mz = rte_eth_dma_zone_reserve(eth_dev, "txgbe_driver", -1,
53                 16, TXGBE_ALIGN, SOCKET_ID_ANY);
54         if (mz == NULL)
55                 return -ENOMEM;
56
57         hw->isb_dma = TMZ_PADDR(mz);
58         hw->isb_mem = TMZ_VADDR(mz);
59
60         /* Allocate memory for storing MAC addresses */
61         eth_dev->data->mac_addrs = rte_zmalloc("txgbe", RTE_ETHER_ADDR_LEN *
62                                                hw->mac.num_rar_entries, 0);
63         if (eth_dev->data->mac_addrs == NULL) {
64                 PMD_INIT_LOG(ERR,
65                              "Failed to allocate %u bytes needed to store "
66                              "MAC addresses",
67                              RTE_ETHER_ADDR_LEN * hw->mac.num_rar_entries);
68                 return -ENOMEM;
69         }
70
71         /* Copy the permanent MAC address */
72         rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.perm_addr,
73                         &eth_dev->data->mac_addrs[0]);
74
75         /* Allocate memory for storing hash filter MAC addresses */
76         eth_dev->data->hash_mac_addrs = rte_zmalloc("txgbe",
77                         RTE_ETHER_ADDR_LEN * TXGBE_VMDQ_NUM_UC_MAC, 0);
78         if (eth_dev->data->hash_mac_addrs == NULL) {
79                 PMD_INIT_LOG(ERR,
80                              "Failed to allocate %d bytes needed to store MAC addresses",
81                              RTE_ETHER_ADDR_LEN * TXGBE_VMDQ_NUM_UC_MAC);
82                 return -ENOMEM;
83         }
84
85         PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x",
86                      eth_dev->data->port_id, pci_dev->id.vendor_id,
87                      pci_dev->id.device_id);
88
89         /* enable uio/vfio intr/eventfd mapping */
90         rte_intr_enable(intr_handle);
91
92         return 0;
93 }
94
95 static int
96 eth_txgbe_dev_uninit(struct rte_eth_dev *eth_dev)
97 {
98         PMD_INIT_FUNC_TRACE();
99
100         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
101                 return 0;
102
103         txgbe_dev_close(eth_dev);
104
105         return 0;
106 }
107
108 static int
109 eth_txgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
110                 struct rte_pci_device *pci_dev)
111 {
112         struct rte_eth_dev *pf_ethdev;
113         struct rte_eth_devargs eth_da;
114         int retval;
115
116         if (pci_dev->device.devargs) {
117                 retval = rte_eth_devargs_parse(pci_dev->device.devargs->args,
118                                 &eth_da);
119                 if (retval)
120                         return retval;
121         } else {
122                 memset(&eth_da, 0, sizeof(eth_da));
123         }
124
125         retval = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name,
126                         sizeof(struct txgbe_adapter),
127                         eth_dev_pci_specific_init, pci_dev,
128                         eth_txgbe_dev_init, NULL);
129
130         if (retval || eth_da.nb_representor_ports < 1)
131                 return retval;
132
133         pf_ethdev = rte_eth_dev_allocated(pci_dev->device.name);
134         if (pf_ethdev == NULL)
135                 return -ENODEV;
136
137         return 0;
138 }
139
140 static int eth_txgbe_pci_remove(struct rte_pci_device *pci_dev)
141 {
142         struct rte_eth_dev *ethdev;
143
144         ethdev = rte_eth_dev_allocated(pci_dev->device.name);
145         if (!ethdev)
146                 return -ENODEV;
147
148         return rte_eth_dev_destroy(ethdev, eth_txgbe_dev_uninit);
149 }
150
151 static struct rte_pci_driver rte_txgbe_pmd = {
152         .id_table = pci_id_txgbe_map,
153         .drv_flags = RTE_PCI_DRV_NEED_MAPPING |
154                      RTE_PCI_DRV_INTR_LSC,
155         .probe = eth_txgbe_pci_probe,
156         .remove = eth_txgbe_pci_remove,
157 };
158
159 /*
160  * Reset and stop device.
161  */
162 static int
163 txgbe_dev_close(struct rte_eth_dev *dev)
164 {
165         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
166         struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
167
168         PMD_INIT_FUNC_TRACE();
169
170         /* disable uio intr before callback unregister */
171         rte_intr_disable(intr_handle);
172
173         rte_free(dev->data->mac_addrs);
174         dev->data->mac_addrs = NULL;
175
176         rte_free(dev->data->hash_mac_addrs);
177         dev->data->hash_mac_addrs = NULL;
178
179         return 0;
180 }
181
182 static const struct eth_dev_ops txgbe_eth_dev_ops = {
183 };
184
185 RTE_PMD_REGISTER_PCI(net_txgbe, rte_txgbe_pmd);
186 RTE_PMD_REGISTER_PCI_TABLE(net_txgbe, pci_id_txgbe_map);
187 RTE_PMD_REGISTER_KMOD_DEP(net_txgbe, "* igb_uio | uio_pci_generic | vfio-pci");
188
189 RTE_LOG_REGISTER(txgbe_logtype_init, pmd.net.txgbe.init, NOTICE);
190 RTE_LOG_REGISTER(txgbe_logtype_driver, pmd.net.txgbe.driver, NOTICE);
191
192 #ifdef RTE_LIBRTE_TXGBE_DEBUG_RX
193         RTE_LOG_REGISTER(txgbe_logtype_rx, pmd.net.txgbe.rx, DEBUG);
194 #endif
195 #ifdef RTE_LIBRTE_TXGBE_DEBUG_TX
196         RTE_LOG_REGISTER(txgbe_logtype_tx, pmd.net.txgbe.tx, DEBUG);
197 #endif
198
199 #ifdef RTE_LIBRTE_TXGBE_DEBUG_TX_FREE
200         RTE_LOG_REGISTER(txgbe_logtype_tx_free, pmd.net.txgbe.tx_free, DEBUG);
201 #endif