DPDK  20.08.0
rte_ethdev_pci.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017 Brocade Communications Systems, Inc.
3  * Author: Jan Blunck <jblunck@infradead.org>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * * Neither the name of the copyright holder nor the names of its
16  * contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef _RTE_ETHDEV_PCI_H_
33 #define _RTE_ETHDEV_PCI_H_
34 
35 #include <rte_malloc.h>
36 #include <rte_pci.h>
37 #include <rte_bus_pci.h>
38 #include <rte_config.h>
39 #include <rte_ethdev_driver.h>
40 
51 static inline void
52 rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
53  struct rte_pci_device *pci_dev)
54 {
55  if ((eth_dev == NULL) || (pci_dev == NULL)) {
56  RTE_ETHDEV_LOG(ERR, "NULL pointer eth_dev=%p pci_dev=%p",
57  (void *)eth_dev, (void *)pci_dev);
58  return;
59  }
60 
61  eth_dev->intr_handle = &pci_dev->intr_handle;
62 
63  if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
64  eth_dev->data->dev_flags = 0;
65  if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)
66  eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
67  if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_RMV)
68  eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_RMV;
69 
70  eth_dev->data->kdrv = pci_dev->kdrv;
71  eth_dev->data->numa_node = pci_dev->device.numa_node;
72  }
73 }
74 
75 static inline int
76 eth_dev_pci_specific_init(struct rte_eth_dev *eth_dev, void *bus_device) {
77  struct rte_pci_device *pci_dev = bus_device;
78 
79  if (!pci_dev)
80  return -ENODEV;
81 
82  rte_eth_copy_pci_info(eth_dev, pci_dev);
83 
84  return 0;
85 }
86 
101 static inline struct rte_eth_dev *
102 rte_eth_dev_pci_allocate(struct rte_pci_device *dev, size_t private_data_size)
103 {
104  struct rte_eth_dev *eth_dev;
105  const char *name;
106 
107  if (!dev)
108  return NULL;
109 
110  name = dev->device.name;
111 
112  if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
113  eth_dev = rte_eth_dev_allocate(name);
114  if (!eth_dev)
115  return NULL;
116 
117  if (private_data_size) {
118  eth_dev->data->dev_private = rte_zmalloc_socket(name,
119  private_data_size, RTE_CACHE_LINE_SIZE,
120  dev->device.numa_node);
121  if (!eth_dev->data->dev_private) {
122  rte_eth_dev_release_port(eth_dev);
123  return NULL;
124  }
125  }
126  } else {
127  eth_dev = rte_eth_dev_attach_secondary(name);
128  if (!eth_dev)
129  return NULL;
130  }
131 
132  eth_dev->device = &dev->device;
133  rte_eth_copy_pci_info(eth_dev, dev);
134  return eth_dev;
135 }
136 
137 static inline void
138 rte_eth_dev_pci_release(struct rte_eth_dev *eth_dev)
139 {
140  eth_dev->device = NULL;
141  eth_dev->intr_handle = NULL;
142 
143  /* free ether device */
144  rte_eth_dev_release_port(eth_dev);
145 }
146 
147 typedef int (*eth_dev_pci_callback_t)(struct rte_eth_dev *eth_dev);
148 
154 static inline int
155 rte_eth_dev_pci_generic_probe(struct rte_pci_device *pci_dev,
156  size_t private_data_size, eth_dev_pci_callback_t dev_init)
157 {
158  struct rte_eth_dev *eth_dev;
159  int ret;
160 
161  eth_dev = rte_eth_dev_pci_allocate(pci_dev, private_data_size);
162  if (!eth_dev)
163  return -ENOMEM;
164 
165  RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
166  ret = dev_init(eth_dev);
167  if (ret)
168  rte_eth_dev_pci_release(eth_dev);
169  else
170  rte_eth_dev_probing_finish(eth_dev);
171 
172  return ret;
173 }
174 
180 static inline int
181 rte_eth_dev_pci_generic_remove(struct rte_pci_device *pci_dev,
182  eth_dev_pci_callback_t dev_uninit)
183 {
184  struct rte_eth_dev *eth_dev;
185  int ret;
186 
187  eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
188  if (!eth_dev)
189  return 0;
190 
191  if (dev_uninit) {
192  ret = dev_uninit(eth_dev);
193  if (ret)
194  return ret;
195  }
196 
197  rte_eth_dev_pci_release(eth_dev);
198  return 0;
199 }
200 
201 #endif /* _RTE_ETHDEV_PCI_H_ */
#define RTE_ETH_DEV_INTR_LSC
Definition: rte_ethdev.h:1630
enum rte_proc_type_t rte_eal_process_type(void)
#define RTE_ETH_DEV_INTR_RMV
Definition: rte_ethdev.h:1634
void * rte_zmalloc_socket(const char *type, size_t size, unsigned align, int socket)