aboutsummaryrefslogtreecommitdiffstats
path: root/vlib/vlib/pci/pci.h
diff options
context:
space:
mode:
authorDamjan Marion <damarion@cisco.com>2016-05-12 22:11:03 +0200
committerDave Barach <openvpp@barachs.net>2016-05-18 13:13:27 +0000
commit5a206eafdbf9370fead2dd26fcab09e7ff5544c4 (patch)
tree847c6322c640fafd3a1c40e691bc8b21a7f07009 /vlib/vlib/pci/pci.h
parenta2a48305df2dbcf3a930c2cd266754e2519d038e (diff)
Rework of the old PCI code
* adds support for VPP native PCI drivers using standard uio_pci_generic kernel driver * adds generic PCI interrupt callback * splits code to generic PCI handling and linux specific * adds new debug cli 'show pci [all]' Change-Id: I447c2285e319e9725d70688c1b70c9dedda51fdc Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'vlib/vlib/pci/pci.h')
-rw-r--r--vlib/vlib/pci/pci.h145
1 files changed, 103 insertions, 42 deletions
diff --git a/vlib/vlib/pci/pci.h b/vlib/vlib/pci/pci.h
index 737e28ea52a..7e8a9fcc80b 100644
--- a/vlib/vlib/pci/pci.h
+++ b/vlib/vlib/pci/pci.h
@@ -53,7 +53,7 @@ typedef CLIB_PACKED (union {
u32 as_u32;
}) vlib_pci_addr_t;
-typedef struct {
+typedef struct vlib_pci_device {
/* Operating system handle for this device. */
uword os_handle;
@@ -65,6 +65,24 @@ typedef struct {
pci_config_type1_regs_t config1;
u8 config_data[256];
};
+
+ /* Interrupt handler */
+ void (* interrupt_handler) (struct vlib_pci_device * dev);
+
+ /* Driver name */
+ u8 * driver_name;
+
+ /* Numa Node */
+ int numa_node;
+
+ /* Vital Product Data */
+ u8 * product_name;
+ u8 * vpd_r;
+ u8 * vpd_w;
+
+ /* Private data */
+ uword private_data;
+
} vlib_pci_device_t;
typedef struct {
@@ -75,8 +93,8 @@ typedef struct _pci_device_registration {
/* Driver init function. */
clib_error_t * (* init_function) (vlib_main_t * vm, vlib_pci_device_t * dev);
- char const *kernel_driver;
- u8 kernel_driver_running;
+ /* Interrupt handler */
+ void (* interrupt_handler) (vlib_pci_device_t * dev);
/* List of registrations */
struct _pci_device_registration * next_registration;
@@ -85,33 +103,46 @@ typedef struct _pci_device_registration {
pci_device_id_t supported_devices[];
} pci_device_registration_t;
+/* Pool of PCI devices. */
+typedef struct {
+ vlib_main_t * vlib_main;
+ vlib_pci_device_t * pci_devs;
+ pci_device_registration_t * pci_device_registrations;
+ uword * pci_dev_index_by_pci_addr;
+} vlib_pci_main_t;
+
+extern vlib_pci_main_t pci_main;
+
#define PCI_REGISTER_DEVICE(x,...) \
__VA_ARGS__ pci_device_registration_t x; \
static void __vlib_add_pci_device_registration_##x (void) \
__attribute__((__constructor__)) ; \
static void __vlib_add_pci_device_registration_##x (void) \
{ \
- linux_pci_main_t * lpm = vlib_unix_get_main(); \
- x.next_registration = lpm->pci_device_registrations; \
- lpm->pci_device_registrations = &x; \
+ vlib_pci_main_t * pm = &pci_main; \
+ x.next_registration = pm->pci_device_registrations; \
+ pm->pci_device_registrations = &x; \
} \
-__VA_ARGS__ pci_device_registration_t x
+__VA_ARGS__ pci_device_registration_t x
+clib_error_t *
+vlib_pci_bind_to_uio (vlib_pci_device_t * d, char * uio_driver_name);
/* Configuration space read/write. */
clib_error_t *
-os_read_write_pci_config (uword os_handle,
- vlib_read_or_write_t read_or_write,
- uword address,
- void * data,
- u32 n_bytes);
+vlib_pci_read_write_config (vlib_pci_device_t * dev,
+ vlib_read_or_write_t read_or_write,
+ uword address,
+ void * data,
+ u32 n_bytes);
#define _(t) \
static inline clib_error_t * \
-os_read_pci_config_##t (uword os_handle, uword address, t * data) \
+vlib_pci_read_config_##t (vlib_pci_device_t * dev, \
+ uword address, t * data) \
{ \
- return os_read_write_pci_config (os_handle, VLIB_READ, \
- address, data, sizeof (data[0])); \
+ return vlib_pci_read_write_config (dev, VLIB_READ,address, data, \
+ sizeof (data[0])); \
}
_ (u32);
@@ -122,9 +153,10 @@ _ (u8);
#define _(t) \
static inline clib_error_t * \
-os_write_pci_config_##t (uword os_handle, uword address, t * data) \
+vlib_pci_write_config_##t (vlib_pci_device_t * dev, uword address, \
+ t * data) \
{ \
- return os_read_write_pci_config (os_handle, VLIB_WRITE, \
+ return vlib_pci_read_write_config (dev, VLIB_WRITE, \
address, data, sizeof (data[0])); \
}
@@ -134,43 +166,72 @@ _ (u8);
#undef _
-clib_error_t *
-os_map_pci_resource (uword os_handle, u32 resource, void ** result);
+static inline clib_error_t *
+vlib_pci_intr_enable(vlib_pci_device_t * dev)
+{
+ u16 command;
+ clib_error_t * err;
-clib_error_t *
-os_map_pci_resource_fixed (uword os_handle, u32 resource, u8 * addr,
- void ** result);
+ err = vlib_pci_read_config_u16(dev, 4, &command);
-/* Free's device. */
-void os_free_pci_device (uword os_handle);
+ if (err)
+ return err;
-void os_add_pci_disable_interrupts_reg (uword os_handle, u32 resource, u32 reg_offset, u32 reg_value);
+ command &= ~PCI_COMMAND_INTX_DISABLE;
-format_function_t format_os_pci_handle;
+ return vlib_pci_write_config_u16(dev, 4, &command);
+}
-static inline uword
-unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
+static inline clib_error_t *
+vlib_pci_intr_disable(vlib_pci_device_t * dev)
{
- vlib_pci_addr_t * addr = va_arg (* args, vlib_pci_addr_t *);
- u32 x[4];
+ u16 command;
+ clib_error_t * err;
- if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
- return 0;
+ err = vlib_pci_read_config_u16(dev, 4, &command);
+
+ if (err)
+ return err;
- addr->domain = x[0];
- addr->bus = x[1];
- addr->slot = x[2];
- addr->function = x[3];
+ command |= PCI_COMMAND_INTX_DISABLE;
- return 1;
+ return vlib_pci_write_config_u16(dev, 4, &command);
}
-static inline u8 *
-format_vlib_pci_addr (u8 * s, va_list * va)
+static inline clib_error_t *
+vlib_pci_bus_master_enable(vlib_pci_device_t * dev)
{
- vlib_pci_addr_t * addr = va_arg (* va, vlib_pci_addr_t *);
- return format (s, "%04x:%02x:%02x.%x", addr->domain, addr->bus,
- addr->slot, addr->function);
+ clib_error_t * err;
+ u16 command;
+
+ /* Set bus master enable (BME) */
+ err = vlib_pci_read_config_u16(dev, 4, &command);
+
+ if (err)
+ return err;
+
+ if (!(command & PCI_COMMAND_BUS_MASTER))
+ return 0;
+
+ command |= PCI_COMMAND_BUS_MASTER;
+
+ return vlib_pci_write_config_u16(dev, 4, &command);
}
+clib_error_t *
+vlib_pci_map_resource (vlib_pci_device_t * dev, u32 resource, void ** result);
+
+clib_error_t *
+vlib_pci_map_resource_fixed (vlib_pci_device_t * dev, u32 resource, u8 * addr,
+ void ** result);
+
+/* Free's device. */
+void
+vlib_pci_free_device (vlib_pci_device_t * dev);
+
+unformat_function_t unformat_vlib_pci_addr;
+format_function_t format_vlib_pci_addr;
+format_function_t format_vlib_pci_handle;
+format_function_t format_vlib_pci_link_speed;
+
#endif /* included_vlib_pci_h */