85970a0366f05761513fb31513afc36cf83416ac
[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 inline int
32 txgbe_is_sfp(struct txgbe_hw *hw)
33 {
34         switch (hw->phy.type) {
35         case txgbe_phy_sfp_avago:
36         case txgbe_phy_sfp_ftl:
37         case txgbe_phy_sfp_intel:
38         case txgbe_phy_sfp_unknown:
39         case txgbe_phy_sfp_tyco_passive:
40         case txgbe_phy_sfp_unknown_passive:
41                 return 1;
42         default:
43                 return 0;
44         }
45 }
46
47 static int
48 eth_txgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused)
49 {
50         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
51         struct txgbe_hw *hw = TXGBE_DEV_HW(eth_dev);
52         struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
53         const struct rte_memzone *mz;
54         int err;
55
56         PMD_INIT_FUNC_TRACE();
57
58         eth_dev->dev_ops = &txgbe_eth_dev_ops;
59
60         rte_eth_copy_pci_info(eth_dev, pci_dev);
61
62         /* Vendor and Device ID need to be set before init of shared code */
63         hw->device_id = pci_dev->id.device_id;
64         hw->vendor_id = pci_dev->id.vendor_id;
65         hw->hw_addr = (void *)pci_dev->mem_resource[0].addr;
66         hw->allow_unsupported_sfp = 1;
67
68         /* Reserve memory for interrupt status block */
69         mz = rte_eth_dma_zone_reserve(eth_dev, "txgbe_driver", -1,
70                 16, TXGBE_ALIGN, SOCKET_ID_ANY);
71         if (mz == NULL)
72                 return -ENOMEM;
73
74         hw->isb_dma = TMZ_PADDR(mz);
75         hw->isb_mem = TMZ_VADDR(mz);
76
77         /* Initialize the shared code (base driver) */
78         err = txgbe_init_shared_code(hw);
79         if (err != 0) {
80                 PMD_INIT_LOG(ERR, "Shared code init failed: %d", err);
81                 return -EIO;
82         }
83
84         /* Allocate memory for storing MAC addresses */
85         eth_dev->data->mac_addrs = rte_zmalloc("txgbe", RTE_ETHER_ADDR_LEN *
86                                                hw->mac.num_rar_entries, 0);
87         if (eth_dev->data->mac_addrs == NULL) {
88                 PMD_INIT_LOG(ERR,
89                              "Failed to allocate %u bytes needed to store "
90                              "MAC addresses",
91                              RTE_ETHER_ADDR_LEN * hw->mac.num_rar_entries);
92                 return -ENOMEM;
93         }
94
95         /* Copy the permanent MAC address */
96         rte_ether_addr_copy((struct rte_ether_addr *)hw->mac.perm_addr,
97                         &eth_dev->data->mac_addrs[0]);
98
99         /* Allocate memory for storing hash filter MAC addresses */
100         eth_dev->data->hash_mac_addrs = rte_zmalloc("txgbe",
101                         RTE_ETHER_ADDR_LEN * TXGBE_VMDQ_NUM_UC_MAC, 0);
102         if (eth_dev->data->hash_mac_addrs == NULL) {
103                 PMD_INIT_LOG(ERR,
104                              "Failed to allocate %d bytes needed to store MAC addresses",
105                              RTE_ETHER_ADDR_LEN * TXGBE_VMDQ_NUM_UC_MAC);
106                 return -ENOMEM;
107         }
108
109         if (txgbe_is_sfp(hw) && hw->phy.sfp_type != txgbe_sfp_type_not_present)
110                 PMD_INIT_LOG(DEBUG, "MAC: %d, PHY: %d, SFP+: %d",
111                              (int)hw->mac.type, (int)hw->phy.type,
112                              (int)hw->phy.sfp_type);
113         else
114                 PMD_INIT_LOG(DEBUG, "MAC: %d, PHY: %d",
115                              (int)hw->mac.type, (int)hw->phy.type);
116
117         PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x",
118                      eth_dev->data->port_id, pci_dev->id.vendor_id,
119                      pci_dev->id.device_id);
120
121         /* enable uio/vfio intr/eventfd mapping */
122         rte_intr_enable(intr_handle);
123
124         return 0;
125 }
126
127 static int
128 eth_txgbe_dev_uninit(struct rte_eth_dev *eth_dev)
129 {
130         PMD_INIT_FUNC_TRACE();
131
132         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
133                 return 0;
134
135         txgbe_dev_close(eth_dev);
136
137         return 0;
138 }
139
140 static int
141 eth_txgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
142                 struct rte_pci_device *pci_dev)
143 {
144         struct rte_eth_dev *pf_ethdev;
145         struct rte_eth_devargs eth_da;
146         int retval;
147
148         if (pci_dev->device.devargs) {
149                 retval = rte_eth_devargs_parse(pci_dev->device.devargs->args,
150                                 &eth_da);
151                 if (retval)
152                         return retval;
153         } else {
154                 memset(&eth_da, 0, sizeof(eth_da));
155         }
156
157         retval = rte_eth_dev_create(&pci_dev->device, pci_dev->device.name,
158                         sizeof(struct txgbe_adapter),
159                         eth_dev_pci_specific_init, pci_dev,
160                         eth_txgbe_dev_init, NULL);
161
162         if (retval || eth_da.nb_representor_ports < 1)
163                 return retval;
164
165         pf_ethdev = rte_eth_dev_allocated(pci_dev->device.name);
166         if (pf_ethdev == NULL)
167                 return -ENODEV;
168
169         return 0;
170 }
171
172 static int eth_txgbe_pci_remove(struct rte_pci_device *pci_dev)
173 {
174         struct rte_eth_dev *ethdev;
175
176         ethdev = rte_eth_dev_allocated(pci_dev->device.name);
177         if (!ethdev)
178                 return -ENODEV;
179
180         return rte_eth_dev_destroy(ethdev, eth_txgbe_dev_uninit);
181 }
182
183 static struct rte_pci_driver rte_txgbe_pmd = {
184         .id_table = pci_id_txgbe_map,
185         .drv_flags = RTE_PCI_DRV_NEED_MAPPING |
186                      RTE_PCI_DRV_INTR_LSC,
187         .probe = eth_txgbe_pci_probe,
188         .remove = eth_txgbe_pci_remove,
189 };
190
191 /*
192  * Reset and stop device.
193  */
194 static int
195 txgbe_dev_close(struct rte_eth_dev *dev)
196 {
197         struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
198         struct rte_intr_handle *intr_handle = &pci_dev->intr_handle;
199
200         PMD_INIT_FUNC_TRACE();
201
202         /* disable uio intr before callback unregister */
203         rte_intr_disable(intr_handle);
204
205         rte_free(dev->data->mac_addrs);
206         dev->data->mac_addrs = NULL;
207
208         rte_free(dev->data->hash_mac_addrs);
209         dev->data->hash_mac_addrs = NULL;
210
211         return 0;
212 }
213
214 static const struct eth_dev_ops txgbe_eth_dev_ops = {
215 };
216
217 RTE_PMD_REGISTER_PCI(net_txgbe, rte_txgbe_pmd);
218 RTE_PMD_REGISTER_PCI_TABLE(net_txgbe, pci_id_txgbe_map);
219 RTE_PMD_REGISTER_KMOD_DEP(net_txgbe, "* igb_uio | uio_pci_generic | vfio-pci");
220
221 RTE_LOG_REGISTER(txgbe_logtype_init, pmd.net.txgbe.init, NOTICE);
222 RTE_LOG_REGISTER(txgbe_logtype_driver, pmd.net.txgbe.driver, NOTICE);
223
224 #ifdef RTE_LIBRTE_TXGBE_DEBUG_RX
225         RTE_LOG_REGISTER(txgbe_logtype_rx, pmd.net.txgbe.rx, DEBUG);
226 #endif
227 #ifdef RTE_LIBRTE_TXGBE_DEBUG_TX
228         RTE_LOG_REGISTER(txgbe_logtype_tx, pmd.net.txgbe.tx, DEBUG);
229 #endif
230
231 #ifdef RTE_LIBRTE_TXGBE_DEBUG_TX_FREE
232         RTE_LOG_REGISTER(txgbe_logtype_tx_free, pmd.net.txgbe.tx_free, DEBUG);
233 #endif