DPDK  19.11.14
rte_ethdev_pci.h
1 /*-
2  * BSD LICENSE
3  *
4  * Copyright(c) 2017 Brocade Communications Systems, Inc.
5  * Author: Jan Blunck <jblunck@infradead.org>
6  */
7 
8 #ifndef _RTE_ETHDEV_PCI_H_
9 #define _RTE_ETHDEV_PCI_H_
10 
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14 
15 #include <rte_malloc.h>
16 #include <rte_pci.h>
17 #include <rte_bus_pci.h>
18 #include <rte_config.h>
19 #include <rte_ethdev_driver.h>
20 
31 static inline void
32 rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
33  struct rte_pci_device *pci_dev)
34 {
35  if ((eth_dev == NULL) || (pci_dev == NULL)) {
36  RTE_ETHDEV_LOG(ERR, "NULL pointer eth_dev=%p pci_dev=%p",
37  (void *)eth_dev, (void *)pci_dev);
38  return;
39  }
40 
41  eth_dev->intr_handle = &pci_dev->intr_handle;
42 
43  if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
44  eth_dev->data->dev_flags = 0;
45  if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)
46  eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
47  if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_RMV)
48  eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_RMV;
49 
50  eth_dev->data->kdrv = pci_dev->kdrv;
51  eth_dev->data->numa_node = pci_dev->device.numa_node;
52  }
53 }
54 
55 static inline int
56 eth_dev_pci_specific_init(struct rte_eth_dev *eth_dev, void *bus_device)
57 {
58  struct rte_pci_device *pci_dev = (struct rte_pci_device *)bus_device;
59 
60  if (!pci_dev)
61  return -ENODEV;
62 
63  rte_eth_copy_pci_info(eth_dev, pci_dev);
64 
65  return 0;
66 }
67 
82 static inline struct rte_eth_dev *
83 rte_eth_dev_pci_allocate(struct rte_pci_device *dev, size_t private_data_size)
84 {
85  struct rte_eth_dev *eth_dev;
86  const char *name;
87 
88  if (!dev)
89  return NULL;
90 
91  name = dev->device.name;
92 
93  if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
94  eth_dev = rte_eth_dev_allocate(name);
95  if (!eth_dev)
96  return NULL;
97 
98  if (private_data_size) {
99  eth_dev->data->dev_private = rte_zmalloc_socket(name,
100  private_data_size, RTE_CACHE_LINE_SIZE,
101  dev->device.numa_node);
102  if (!eth_dev->data->dev_private) {
103  rte_eth_dev_release_port(eth_dev);
104  return NULL;
105  }
106  }
107  } else {
108  eth_dev = rte_eth_dev_attach_secondary(name);
109  if (!eth_dev)
110  return NULL;
111  }
112 
113  eth_dev->device = &dev->device;
114  rte_eth_copy_pci_info(eth_dev, dev);
115  return eth_dev;
116 }
117 
118 static inline void
119 rte_eth_dev_pci_release(struct rte_eth_dev *eth_dev)
120 {
121  eth_dev->device = NULL;
122  eth_dev->intr_handle = NULL;
123 
124  /* free ether device */
125  rte_eth_dev_release_port(eth_dev);
126 }
127 
128 typedef int (*eth_dev_pci_callback_t)(struct rte_eth_dev *eth_dev);
129 
135 static inline int
136 rte_eth_dev_pci_generic_probe(struct rte_pci_device *pci_dev,
137  size_t private_data_size, eth_dev_pci_callback_t dev_init)
138 {
139  struct rte_eth_dev *eth_dev;
140  int ret;
141 
142  eth_dev = rte_eth_dev_pci_allocate(pci_dev, private_data_size);
143  if (!eth_dev)
144  return -ENOMEM;
145 
146  RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
147  ret = dev_init(eth_dev);
148  if (ret)
149  rte_eth_dev_pci_release(eth_dev);
150  else
151  rte_eth_dev_probing_finish(eth_dev);
152 
153  return ret;
154 }
155 
161 static inline int
162 rte_eth_dev_pci_generic_remove(struct rte_pci_device *pci_dev,
163  eth_dev_pci_callback_t dev_uninit)
164 {
165  struct rte_eth_dev *eth_dev;
166  int ret;
167 
168  eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
169  if (!eth_dev)
170  return 0;
171 
172  /*
173  * In secondary process, a released eth device can be found by its name
174  * in shared memory.
175  * If the state of the eth device is RTE_ETH_DEV_UNUSED, it means the
176  * eth device has been released.
177  */
178  if (rte_eal_process_type() == RTE_PROC_SECONDARY &&
179  eth_dev->state == RTE_ETH_DEV_UNUSED)
180  return 0;
181 
182  if (dev_uninit) {
183  ret = dev_uninit(eth_dev);
184  if (ret)
185  return ret;
186  }
187 
188  rte_eth_dev_pci_release(eth_dev);
189  return 0;
190 }
191 
192 #ifdef __cplusplus
193 }
194 #endif
195 
196 #endif /* _RTE_ETHDEV_PCI_H_ */
#define RTE_ETH_DEV_INTR_LSC
Definition: rte_ethdev.h:1504
enum rte_proc_type_t rte_eal_process_type(void)
#define RTE_ETH_DEV_INTR_RMV
Definition: rte_ethdev.h:1508
void * rte_zmalloc_socket(const char *type, size_t size, unsigned align, int socket)