DPDK  18.11.11
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 #include <rte_malloc.h>
12 #include <rte_pci.h>
13 #include <rte_bus_pci.h>
14 #include <rte_config.h>
15 #include <rte_ethdev_driver.h>
16 
27 static inline void
28 rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
29  struct rte_pci_device *pci_dev)
30 {
31  if ((eth_dev == NULL) || (pci_dev == NULL)) {
32  RTE_ETHDEV_LOG(ERR, "NULL pointer eth_dev=%p pci_dev=%p",
33  (void *)eth_dev, (void *)pci_dev);
34  return;
35  }
36 
37  eth_dev->intr_handle = &pci_dev->intr_handle;
38 
39  if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
40  eth_dev->data->dev_flags = 0;
41  if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)
42  eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
43  if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_RMV)
44  eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_RMV;
45 
46  eth_dev->data->kdrv = pci_dev->kdrv;
47  eth_dev->data->numa_node = pci_dev->device.numa_node;
48  }
49 }
50 
51 static inline int
52 eth_dev_pci_specific_init(struct rte_eth_dev *eth_dev, void *bus_device) {
53  struct rte_pci_device *pci_dev = bus_device;
54 
55  if (!pci_dev)
56  return -ENODEV;
57 
58  rte_eth_copy_pci_info(eth_dev, pci_dev);
59 
60  return 0;
61 }
62 
77 static inline struct rte_eth_dev *
78 rte_eth_dev_pci_allocate(struct rte_pci_device *dev, size_t private_data_size)
79 {
80  struct rte_eth_dev *eth_dev;
81  const char *name;
82 
83  if (!dev)
84  return NULL;
85 
86  name = dev->device.name;
87 
88  if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
89  eth_dev = rte_eth_dev_allocate(name);
90  if (!eth_dev)
91  return NULL;
92 
93  if (private_data_size) {
94  eth_dev->data->dev_private = rte_zmalloc_socket(name,
95  private_data_size, RTE_CACHE_LINE_SIZE,
96  dev->device.numa_node);
97  if (!eth_dev->data->dev_private) {
98  rte_eth_dev_release_port(eth_dev);
99  return NULL;
100  }
101  }
102  } else {
103  eth_dev = rte_eth_dev_attach_secondary(name);
104  if (!eth_dev)
105  return NULL;
106  }
107 
108  eth_dev->device = &dev->device;
109  rte_eth_copy_pci_info(eth_dev, dev);
110  return eth_dev;
111 }
112 
113 static inline void
114 rte_eth_dev_pci_release(struct rte_eth_dev *eth_dev)
115 {
116  eth_dev->device = NULL;
117  eth_dev->intr_handle = NULL;
118 
119  /* free ether device */
120  rte_eth_dev_release_port(eth_dev);
121 }
122 
123 typedef int (*eth_dev_pci_callback_t)(struct rte_eth_dev *eth_dev);
124 
130 static inline int
131 rte_eth_dev_pci_generic_probe(struct rte_pci_device *pci_dev,
132  size_t private_data_size, eth_dev_pci_callback_t dev_init)
133 {
134  struct rte_eth_dev *eth_dev;
135  int ret;
136 
137  eth_dev = rte_eth_dev_pci_allocate(pci_dev, private_data_size);
138  if (!eth_dev)
139  return -ENOMEM;
140 
141  RTE_FUNC_PTR_OR_ERR_RET(*dev_init, -EINVAL);
142  ret = dev_init(eth_dev);
143  if (ret)
144  rte_eth_dev_pci_release(eth_dev);
145  else
146  rte_eth_dev_probing_finish(eth_dev);
147 
148  return ret;
149 }
150 
156 static inline int
157 rte_eth_dev_pci_generic_remove(struct rte_pci_device *pci_dev,
158  eth_dev_pci_callback_t dev_uninit)
159 {
160  struct rte_eth_dev *eth_dev;
161  int ret;
162 
163  eth_dev = rte_eth_dev_allocated(pci_dev->device.name);
164  if (!eth_dev)
165  return 0;
166 
167  if (dev_uninit) {
168  ret = dev_uninit(eth_dev);
169  if (ret)
170  return ret;
171  }
172 
173  rte_eth_dev_pci_release(eth_dev);
174  return 0;
175 }
176 
177 #endif /* _RTE_ETHDEV_PCI_H_ */
#define RTE_ETH_DEV_INTR_LSC
Definition: rte_ethdev.h:1341
enum rte_proc_type_t rte_eal_process_type(void)
#define RTE_ETH_DEV_INTR_RMV
Definition: rte_ethdev.h:1345
void * rte_zmalloc_socket(const char *type, size_t size, unsigned align, int socket)