DPDK  20.11.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 
6 #ifndef _RTE_ETHDEV_PCI_H_
7 #define _RTE_ETHDEV_PCI_H_
8 
9 #include <rte_malloc.h>
10 #include <rte_pci.h>
11 #include <rte_bus_pci.h>
12 #include <rte_config.h>
13 #include <rte_ethdev_driver.h>
14 
25 static inline void
26 rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
27  struct rte_pci_device *pci_dev)
28 {
29  if ((eth_dev == NULL) || (pci_dev == NULL)) {
30  RTE_ETHDEV_LOG(ERR, "NULL pointer eth_dev=%p pci_dev=%p",
31  (void *)eth_dev, (void *)pci_dev);
32  return;
33  }
34 
35  eth_dev->intr_handle = &pci_dev->intr_handle;
36 
37  if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
38  eth_dev->data->dev_flags = 0;
39  if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)
40  eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
41  if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_RMV)
42  eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_RMV;
43 
44  eth_dev->data->numa_node = pci_dev->device.numa_node;
45  }
46 }
47 
48 static inline int
49 eth_dev_pci_specific_init(struct rte_eth_dev *eth_dev, void *bus_device) {
50  struct rte_pci_device *pci_dev = bus_device;
51 
52  if (!pci_dev)
53  return -ENODEV;
54 
55  rte_eth_copy_pci_info(eth_dev, pci_dev);
56 
57  return 0;
58 }
59 
74 static inline struct rte_eth_dev *
75 rte_eth_dev_pci_allocate(struct rte_pci_device *dev, size_t private_data_size)
76 {
77  struct rte_eth_dev *eth_dev;
78  const char *name;
79 
80  if (!dev)
81  return NULL;
82 
83  name = dev->device.name;
84 
85  if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
86  eth_dev = rte_eth_dev_allocate(name);
87  if (!eth_dev)
88  return NULL;
89 
90  if (private_data_size) {
91  eth_dev->data->dev_private = rte_zmalloc_socket(name,
92  private_data_size, RTE_CACHE_LINE_SIZE,
93  dev->device.numa_node);
94  if (!eth_dev->data->dev_private) {
95  rte_eth_dev_release_port(eth_dev);
96  return NULL;
97  }
98  }
99  } else {
100  eth_dev = rte_eth_dev_attach_secondary(name);
101  if (!eth_dev)
102  return NULL;
103  }
104 
105  eth_dev->device = &dev->device;
106  rte_eth_copy_pci_info(eth_dev, dev);
107  return eth_dev;
108 }
109 
110 typedef int (*eth_dev_pci_callback_t)(struct rte_eth_dev *eth_dev);
111 
117 static inline int
118 rte_eth_dev_pci_generic_probe(struct rte_pci_device *pci_dev,
119  size_t private_data_size, eth_dev_pci_callback_t dev_init)
120 {
121  struct rte_eth_dev *eth_dev;
122  int ret;
123 
124  eth_dev = rte_eth_dev_pci_allocate(pci_dev, private_data_size);
125  if (!eth_dev)
126  return -ENOMEM;
127 
128  RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
129  ret = dev_init(eth_dev);
130  if (ret)
131  rte_eth_dev_release_port(eth_dev);
132  else
133  rte_eth_dev_probing_finish(eth_dev);
134 
135  return ret;
136 }
137 
143 static inline int
144 rte_eth_dev_pci_generic_remove(struct rte_pci_device *pci_dev,
145  eth_dev_pci_callback_t dev_uninit)
146 {
147  struct rte_eth_dev *eth_dev;
148  int ret;
149 
150  eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
151  if (!eth_dev)
152  return 0;
153 
154  if (dev_uninit) {
155  ret = dev_uninit(eth_dev);
156  if (ret)
157  return ret;
158  }
159 
160  rte_eth_dev_release_port(eth_dev);
161  return 0;
162 }
163 
164 #endif /* _RTE_ETHDEV_PCI_H_ */
enum rte_proc_type_t rte_eal_process_type(void)
#define RTE_ETH_DEV_INTR_RMV
Definition: rte_ethdev.h:1812
#define RTE_ETH_DEV_INTR_LSC
Definition: rte_ethdev.h:1808
void * rte_zmalloc_socket(const char *type, size_t size, unsigned align, int socket) __rte_alloc_size(2)