[linux-yocto] [PATCH 06/30] include: rapidio updates
Charlie Paul
cpaul.windriver at gmail.com
Thu Apr 17 19:36:54 PDT 2014
From: Paul Butler <paul.butler at windriver.com>
Signed-off-by: Paul Butler <paul.butler at windriver.com>
---
include/asm-generic/vmlinux.lds.h | 10 ++
include/linux/rio.h | 231 ++++++++++++++++++++++++++++++-------
include/linux/rio_dio.h | 67 +++++++++++
include/linux/rio_drv.h | 202 +++++++++++++++++++++++++-------
include/linux/rio_ids.h | 7 ++
include/linux/rio_regs.h | 26 +++++
include/linux/riopw.h | 30 +++++
7 files changed, 490 insertions(+), 83 deletions(-)
create mode 100644 include/linux/rio_dio.h
create mode 100644 include/linux/riopw.h
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 5d2ca6f..290711d 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -274,6 +274,16 @@
} \
\
/* RapidIO route ops */ \
+ .rio_dev_fixup : AT(ADDR(.rio_dev_fixup) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__start_rio_dev_fixup_early) = .; \
+ *(.rio_dev_fixup_early) \
+ VMLINUX_SYMBOL(__end_rio_dev_fixup_early) = .; \
+ VMLINUX_SYMBOL(__start_rio_dev_fixup_enable) = .; \
+ *(.rio_dev_fixup_enable) \
+ VMLINUX_SYMBOL(__end_rio_dev_fixup_enable) = .; \
+ } \
+ \
+ /* RapidIO route ops */ \
.rio_ops : AT(ADDR(.rio_ops) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start_rio_switch_ops) = .; \
*(.rio_switch_ops) \
diff --git a/include/linux/rio.h b/include/linux/rio.h
index 4d50611..ef300e2 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -20,6 +20,8 @@
#include <linux/errno.h>
#include <linux/device.h>
#include <linux/rio_regs.h>
+#include <linux/radix-tree.h>
+#include <asm/rio.h>
#define RIO_NO_HOPCOUNT -1
#define RIO_INVALID_DESTID 0xffff
@@ -37,10 +39,14 @@
entry is invalid (no route
exists for the device ID) */
+#define RIO_INVALID_ROUTE_WEIGHT 0xff /* Indicates that a route weight
+ entry is invalid (no route
+ exists for the device ID) */
+
#define RIO_MAX_ROUTE_ENTRIES(size) (size ? (1 << 16) : (1 << 8))
#define RIO_ANY_DESTID(size) (size ? 0xffff : 0xff)
-#define RIO_MAX_MBOX 4
+#define RIO_MAX_MBOX 8
#define RIO_MAX_MSG_SIZE 0x1000
/*
@@ -77,6 +83,9 @@
#define RIO_CTAG_RESRVD 0xfffe0000 /* Reserved */
#define RIO_CTAG_UDEVID 0x0001ffff /* Unique device identifier */
+#define RIO_DEVICE_INSERTION 1
+#define RIO_DEVICE_EXTRACTION 2
+
extern struct bus_type rio_bus_type;
extern struct device rio_bus;
extern struct list_head rio_devices; /* list of all devices */
@@ -85,6 +94,15 @@ struct rio_mport;
struct rio_dev;
union rio_pw_msg;
+struct rio_switch_port {
+ struct rio_dev *rdev;
+#ifdef CONFIG_RAPIDIO_DYNAMIC_ROUTES
+ u8 *route_weights_table;
+#endif
+};
+
+#define NEW_STYLE 1
+
/**
* struct rio_switch - RIO switch info
* @node: Node in global list of switches
@@ -104,7 +122,12 @@ union rio_pw_msg;
struct rio_switch {
struct list_head node;
u16 switchid;
+#ifdef OLD_STYLE
u8 *route_table;
+#else
+ u32 port_init;
+ int update_lut;
+#endif
u32 port_ok;
int (*add_entry) (struct rio_mport *mport, u16 destid, u8 hopcount,
u16 table, u16 route_destid, u8 route_port);
@@ -119,7 +142,9 @@ struct rio_switch {
int (*em_init) (struct rio_dev *dev);
int (*em_handle) (struct rio_dev *dev, u8 swport);
int (*sw_sysfs) (struct rio_dev *dev, int create);
- struct rio_dev *nextdev[0];
+#ifdef OLD_STYLE
+ struct rio_switch_port port[0];
+#endif
};
/**
@@ -151,10 +176,19 @@ struct rio_switch {
* @prev: Previous RIO device connected to the current one
* @rswitch: struct rio_switch (if valid for this device)
*/
+#ifdef NEW_STYLE
+struct rio_dyn {
+ int prev_port;
+ u16 prev_destid;
+ u32 swpinfo;
+};
+#endif
+
struct rio_dev {
struct list_head global_list; /* node in list of all RIO devices */
struct list_head net_list; /* node in per net list */
- struct rio_net *net; /* RIO net this device resides in */
+ struct list_head route_list; /* node in per net list */
+ struct rio_mport *hport; /* RIO net this device resides in */
u16 did;
u16 vid;
u32 device_rev;
@@ -176,7 +210,15 @@ struct rio_dev {
int (*pwcback) (struct rio_dev *rdev, union rio_pw_msg *msg, int step);
u16 destid;
u8 hopcount;
+#ifdef NEW_STYLE
+ int use_hw_lock;
+ int local_domain; /* Device enumerated/Device discovered */
+ int prev_port;
+ u16 prev_destid;
+ u8 return_port;
+#else
struct rio_dev *prev;
+#endif
struct rio_switch rswitch[0]; /* RIO switch info */
};
@@ -190,9 +232,15 @@ struct rio_dev {
* @res: Mailbox resource
* @mcback: Message event callback
*/
-struct rio_msg {
+struct rio_outb_msg {
struct resource *res;
- void (*mcback) (struct rio_mport * mport, void *dev_id, int mbox, int slot);
+ void (*mcback) (struct rio_mport *mport,
+ void *dev_id, int mbox, int rc, void *cookie);
+};
+struct rio_inb_msg {
+ struct resource *res;
+ void (*mcback) (struct rio_mport *mport,
+ void *dev_id, int mbox, int letter);
};
/**
@@ -205,7 +253,8 @@ struct rio_msg {
struct rio_dbell {
struct list_head node;
struct resource *res;
- void (*dinb) (struct rio_mport *mport, void *dev_id, u16 src, u16 dst, u16 info);
+ void (*dinb) (struct rio_mport *mport, void *dev_id,
+ u16 src, u16 dst, u16 info);
void *dev_id;
};
@@ -214,6 +263,46 @@ enum rio_phy_type {
RIO_PHY_SERIAL,
};
+struct rio_map_addr {
+ void __iomem *va;
+ resource_size_t phys;
+};
+
+/**
+ * Struct for RIO memory definition.
+ * @req_outb: The function for requesting outbound memory window.
+ * @map_outb: The function for mapping outbound memory window.
+ * @release_outb: The function for releasing outbound memory window.
+ */
+struct rio_mem_ops {
+ int (*req_outb) (struct rio_mport *, resource_size_t,
+ const char *, u32, u32 *);
+ int (*map_outb) (struct rio_mport *, u32,
+ u16, u32, u32, struct rio_map_addr *);
+ void (*release_outb) (struct rio_mport *, u32);
+};
+/**
+ * struct rio_net - RIO network info
+ * @node: Node in global list of RIO networks
+ * @devices: List of devices in this network
+ * @mports: List of master ports accessing this network
+ * @hport: Default port for accessing this network
+ * @id: RIO network ID
+ */
+struct rio_net {
+#ifdef NEW_STYLE
+ struct radix_tree_root dev_tree;
+ atomic_t rio_dev_num;
+ struct radix_tree_root dst_tree;
+ atomic_t rio_dst_num;
+ atomic_t rio_max_dest;
+ spinlock_t tree_lock;
+#else
+ struct list_head devices; /* list of devices in this net */
+#endif
+ unsigned char id; /* RIO network ID */
+};
+
/**
* struct rio_mport - RIO master port info
* @dbells: List of doorbell events
@@ -236,13 +325,19 @@ enum rio_phy_type {
struct rio_mport {
struct list_head dbells; /* list of doorbell events */
struct list_head node; /* node in global list of ports */
- struct list_head nnode; /* node in net list of ports */
+ struct rio_net net;
+
+#if defined(CONFIG_RAPIDIO_STATIC_DESTID) || defined(CONFIG_RAPIDIO_HOTPLUG)
+ struct device dev;
+#endif
struct resource iores;
struct resource riores[RIO_MAX_MPORT_RESOURCES];
- struct rio_msg inb_msg[RIO_MAX_MBOX];
- struct rio_msg outb_msg[RIO_MAX_MBOX];
+ struct rio_inb_msg inb_msg[RIO_MAX_MBOX];
+ struct rio_outb_msg outb_msg[RIO_MAX_MBOX];
int host_deviceid; /* Host device ID */
+ int enum_host;
struct rio_ops *ops; /* low-level architecture-dependent routines */
+ struct rio_mem_ops *mops; /* Memory functions */
unsigned char id; /* port ID, unique among all ports */
unsigned char index; /* port index, unique among all port
interfaces of the same type */
@@ -256,28 +351,33 @@ struct rio_mport {
void *priv; /* Master port private data */
};
-/**
- * struct rio_net - RIO network info
- * @node: Node in global list of RIO networks
- * @devices: List of devices in this network
- * @mports: List of master ports accessing this network
- * @hport: Default port for accessing this network
- * @id: RIO network ID
- */
-struct rio_net {
- struct list_head node; /* node in list of networks */
- struct list_head devices; /* list of devices in this net */
- struct list_head mports; /* list of ports accessing net */
- struct rio_mport *hport; /* primary port for accessing net */
- unsigned char id; /* RIO network ID */
-};
/* Definitions used by switch sysfs initialization callback */
#define RIO_SW_SYSFS_CREATE 1 /* Create switch attributes */
#define RIO_SW_SYSFS_REMOVE 0 /* Remove switch attributes */
/* Low-level architecture-dependent routines */
-
+#ifdef CONFIG_RAPIDIO_HOTPLUG
+
+#define RIO_HOT_SWAP_EXTRACT 0x1
+#define RIO_HOT_SWAP_INSERT 0x2
+#define RIO_HOT_SWAP_MPORT 0x4
+#define RIO_HOT_SWAP_LINK_PARTNER 0x8
+
+#define RIO_EXTRACT_LP(f) (((f) & \
+ (RIO_HOT_SWAP_EXTRACT | RIO_HOT_SWAP_LINK_PARTNER)) == \
+ (RIO_HOT_SWAP_EXTRACT | RIO_HOT_SWAP_LINK_PARTNER))
+#define RIO_EXTRACT_MP(f) (((f) & \
+ (RIO_HOT_SWAP_EXTRACT | RIO_HOT_SWAP_MPORT)) == \
+ (RIO_HOT_SWAP_EXTRACT | RIO_HOT_SWAP_MPORT))
+#define RIO_INSERT_LP(f) (((f) & \
+ (RIO_HOT_SWAP_INSERT | RIO_HOT_SWAP_LINK_PARTNER)) == \
+ (RIO_HOT_SWAP_INSERT | RIO_HOT_SWAP_LINK_PARTNER))
+#define RIO_INSERT_MP(f) (((f) & \
+ (RIO_HOT_SWAP_INSERT | RIO_HOT_SWAP_MPORT)) == \
+ (RIO_HOT_SWAP_INSERT | RIO_HOT_SWAP_MPORT))
+
+#endif
/**
* struct rio_ops - Low-level RIO configuration space operations
* @lcread: Callback to perform local (master port) read of config space.
@@ -295,28 +395,47 @@ struct rio_net {
* @get_inb_message: Callback to get a message from an inbound mailbox queue.
*/
struct rio_ops {
- int (*lcread) (struct rio_mport *mport, int index, u32 offset, int len,
- u32 *data);
- int (*lcwrite) (struct rio_mport *mport, int index, u32 offset, int len,
- u32 data);
+ int (*lcread) (struct rio_mport *mport, int index, u32 offset,
+ int len, u32 *data);
+ int (*lcwrite) (struct rio_mport *mport, int index, u32 offset,
+ int len, u32 data);
int (*cread) (struct rio_mport *mport, int index, u16 destid,
u8 hopcount, u32 offset, int len, u32 *data);
int (*cwrite) (struct rio_mport *mport, int index, u16 destid,
u8 hopcount, u32 offset, int len, u32 data);
- int (*dsend) (struct rio_mport *mport, int index, u16 destid, u16 data);
+ int (*dsend) (struct rio_mport *mport, int index,
+ u16 destid, u16 data);
int (*pwenable) (struct rio_mport *mport, int enable);
int (*open_outb_mbox)(struct rio_mport *mport, void *dev_id,
- int mbox, int entries);
+ int mbox, int entries, int prio);
void (*close_outb_mbox)(struct rio_mport *mport, int mbox);
int (*open_inb_mbox)(struct rio_mport *mport, void *dev_id,
int mbox, int entries);
void (*close_inb_mbox)(struct rio_mport *mport, int mbox);
int (*add_outb_message)(struct rio_mport *mport, struct rio_dev *rdev,
- int mbox, void *buffer, size_t len);
+ int mbox_dest, int letter, int flags,
+ void *buffer, size_t len, void *cookie);
int (*add_inb_buffer)(struct rio_mport *mport, int mbox, void *buf);
- void *(*get_inb_message)(struct rio_mport *mport, int mbox);
+ void *(*get_inb_message)(struct rio_mport *mport, int mbox, int letter,
+ int *sz, int *slot, u16 *destid);
+#ifdef CONFIG_RAPIDIO_HOTPLUG
+ int (*hotswap)(struct rio_mport *mport, u8 flags);
+ int (*port_notify_cb)(struct rio_mport *mport,
+ int enable,
+ void (*cb)(struct rio_mport *mport));
+ int (*port_op_state)(struct rio_mport *mport);
+#endif
+};
+
+#ifdef CONFIG_RAPIDIO_STATIC_DESTID
+
+struct rio_static_route {
+ u16 sw_destid;
+ u8 sw_port;
};
+#endif
+
#define RIO_RESOURCE_MEM 0x00000100
#define RIO_RESOURCE_DOORBELL 0x00000200
#define RIO_RESOURCE_MAILBOX 0x00000400
@@ -341,19 +460,25 @@ struct rio_ops {
* Provides info on a RIO device driver for insertion/removal and
* power management purposes.
*/
+struct rio_dynids {
+ spinlock_t lock; /* protects list, index */
+ struct list_head list; /* for IDs added at runtime */
+};
+
struct rio_driver {
struct list_head node;
char *name;
const struct rio_device_id *id_table;
- int (*probe) (struct rio_dev * dev, const struct rio_device_id * id);
- void (*remove) (struct rio_dev * dev);
- int (*suspend) (struct rio_dev * dev, u32 state);
- int (*resume) (struct rio_dev * dev);
- int (*enable_wake) (struct rio_dev * dev, u32 state, int enable);
+ int (*probe) (struct rio_dev *dev, const struct rio_device_id *id);
+ void (*remove) (struct rio_dev *dev);
+ int (*suspend) (struct rio_dev *dev, u32 state);
+ int (*resume) (struct rio_dev *dev);
+ int (*enable_wake) (struct rio_dev *dev, u32 state, int enable);
struct device_driver driver;
+ struct rio_dynids dynids;
};
-#define to_rio_driver(drv) container_of(drv,struct rio_driver, driver)
+#define to_rio_driver(drv) container_of(drv, struct rio_driver, driver)
/**
* struct rio_device_id - RIO device identifier
@@ -383,6 +508,25 @@ struct rio_switch_ops {
u16 vid, did;
int (*init_hook) (struct rio_dev *rdev, int do_enum);
};
+struct rio_dev_fixup {
+ u16 vid, did;
+ void (*fixup_hook) (struct rio_dev *rdev, u16 destid, u8 hopcount);
+};
+enum rio_fixup_pass {
+ rio_fixup_early,
+ rio_fixup_enable,
+};
+
+
+#define DECLARE_RIO_DEV_FIXUP_SECTION(section, name, vid, did, fixup_hook) \
+ static const struct rio_dev_fixup __rio_dev_fixup_##name __used \
+ __section(section) = { vid, did, fixup_hook };
+#define DECLARE_RIO_DEV_FIXUP_EARLY(vid, did, fixup_hook) \
+ DECLARE_RIO_DEV_FIXUP_SECTION(.rio_dev_fixup_early, \
+ vid##did##fixup_hook, vid, did, fixup_hook)
+#define DECLARE_RIO_DEV_FIXUP_ENABLE(vid, did, fixup_hook) \
+ DECLARE_RIO_DEV_FIXUP_SECTION(.rio_dev_fixup_enable, \
+ vid##did##fixup_hook, vid, did, fixup_hook)
union rio_pw_msg {
struct {
@@ -394,6 +538,13 @@ union rio_pw_msg {
} em;
u32 raw[RIO_PW_MSG_SIZE/sizeof(u32)];
};
+void rio_fixup_dev(enum rio_fixup_pass pass,
+ struct rio_dev *rdev,
+ u16 destid,
+ u8 hopcount);
+
+
+
/* Architecture and hardware-specific functions */
extern int rio_register_mport(struct rio_mport *);
@@ -401,5 +552,5 @@ extern int rio_open_inb_mbox(struct rio_mport *, void *, int, int);
extern void rio_close_inb_mbox(struct rio_mport *, int);
extern int rio_open_outb_mbox(struct rio_mport *, void *, int, int);
extern void rio_close_outb_mbox(struct rio_mport *, int);
-
+extern int rio_init_device(struct rio_dev *rdev);
#endif /* LINUX_RIO_H */
diff --git a/include/linux/rio_dio.h b/include/linux/rio_dio.h
new file mode 100644
index 0000000..4469278
--- /dev/null
+++ b/include/linux/rio_dio.h
@@ -0,0 +1,67 @@
+#ifndef _RIO_DIO_H_
+#define _RIO_DIO_H_
+
+
+#define RIO_IO_READ_HOME 0x00
+#define RIO_MAINT_READ 0x01
+#define RIO_MAINT_WRITE 0x10
+#define RIO_NREAD 0x02
+#define RIO_NWRITE 0x20
+#define RIO_NWRITE_R 0x40
+#define RIO_SWRITE 0x80
+
+#ifdef __KERNEL__
+
+#include <linux/kernel.h>
+#include <linux/kref.h>
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+
+struct rio_dio_win {
+ struct list_head node;
+ void *dio_channel;
+ struct rio_dev *rdev;
+ unsigned outb_win;
+ resource_size_t win_size;
+ struct kref kref;
+};
+
+/*
+ Setup / release methods
+*/
+struct rio_dio_win *rio_dio_req_region(void *dio_channel,
+ struct rio_dev *rdev,
+ resource_size_t size,
+ u32 flags);
+void rio_dio_region_put(struct rio_dio_win *io_win);
+int rio_dio_method_setup(void **dio_channel);
+void rio_dio_method_put(void *dio_channel);
+
+/*
+ Access methods
+*/
+int rio_dio_read_8(struct rio_dio_win *io_win, u32 offset,
+ u32 mflags, u8 *value);
+int rio_dio_read_16(struct rio_dio_win *io_win, u32 offset,
+ u32 mflags, u16 *value);
+int rio_dio_read_32(struct rio_dio_win *io_win, u32 offset,
+ u32 mflags, u32 *value);
+int rio_dio_read_buff(struct rio_dio_win *io_win, u32 offset,
+ u8 *dst, u32 mflags, u32 len);
+int rio_dio_write_8(struct rio_dio_win *io_win,
+ u32 offset, u32 mflags, u8 *src);
+int rio_dio_write_16(struct rio_dio_win *io_win,
+ u32 offset, u32 mflags, u16 *src);
+int rio_dio_write_32(struct rio_dio_win *io_win, u32 offset,
+ u32 mflags, u32 *src);
+int rio_dio_write_buff(struct rio_dio_win *io_win, u32 offset,
+ u8 *src, u32 mflags, u32 len);
+
+int rio_dio_const_win(struct rio_dio_win *io_win, void *buf, u32 len,
+ enum dma_data_direction dir, struct rio_map_addr *res);
+
+#endif /* __KERNEL__ */
+
+#endif
diff --git a/include/linux/rio_drv.h b/include/linux/rio_drv.h
index 7f07470..c320d77 100644
--- a/include/linux/rio_drv.h
+++ b/include/linux/rio_drv.h
@@ -21,28 +21,28 @@
#include <linux/rio.h>
extern int __rio_local_read_config_32(struct rio_mport *port, u32 offset,
- u32 * data);
+ u32 *data);
extern int __rio_local_write_config_32(struct rio_mport *port, u32 offset,
u32 data);
extern int __rio_local_read_config_16(struct rio_mport *port, u32 offset,
- u16 * data);
+ u16 *data);
extern int __rio_local_write_config_16(struct rio_mport *port, u32 offset,
u16 data);
extern int __rio_local_read_config_8(struct rio_mport *port, u32 offset,
- u8 * data);
+ u8 *data);
extern int __rio_local_write_config_8(struct rio_mport *port, u32 offset,
u8 data);
extern int rio_mport_read_config_32(struct rio_mport *port, u16 destid,
- u8 hopcount, u32 offset, u32 * data);
+ u8 hopcount, u32 offset, u32 *data);
extern int rio_mport_write_config_32(struct rio_mport *port, u16 destid,
u8 hopcount, u32 offset, u32 data);
extern int rio_mport_read_config_16(struct rio_mport *port, u16 destid,
- u8 hopcount, u32 offset, u16 * data);
+ u8 hopcount, u32 offset, u16 *data);
extern int rio_mport_write_config_16(struct rio_mport *port, u16 destid,
u8 hopcount, u32 offset, u16 data);
extern int rio_mport_read_config_8(struct rio_mport *port, u16 destid,
- u8 hopcount, u32 offset, u8 * data);
+ u8 hopcount, u32 offset, u8 *data);
extern int rio_mport_write_config_8(struct rio_mport *port, u16 destid,
u8 hopcount, u32 offset, u8 data);
@@ -56,7 +56,7 @@ extern int rio_mport_write_config_8(struct rio_mport *port, u16 destid,
* device's configuration space.
*/
static inline int rio_local_read_config_32(struct rio_mport *port, u32 offset,
- u32 * data)
+ u32 *data)
{
return __rio_local_read_config_32(port, offset, data);
}
@@ -86,7 +86,7 @@ static inline int rio_local_write_config_32(struct rio_mport *port, u32 offset,
* device's configuration space.
*/
static inline int rio_local_read_config_16(struct rio_mport *port, u32 offset,
- u16 * data)
+ u16 *data)
{
return __rio_local_read_config_16(port, offset, data);
}
@@ -117,7 +117,7 @@ static inline int rio_local_write_config_16(struct rio_mport *port, u32 offset,
* device's configuration space.
*/
static inline int rio_local_read_config_8(struct rio_mport *port, u32 offset,
- u8 * data)
+ u8 *data)
{
return __rio_local_read_config_8(port, offset, data);
}
@@ -147,10 +147,13 @@ static inline int rio_local_write_config_8(struct rio_mport *port, u32 offset,
* RIO device's configuration space.
*/
static inline int rio_read_config_32(struct rio_dev *rdev, u32 offset,
- u32 * data)
+ u32 *data)
{
- return rio_mport_read_config_32(rdev->net->hport, rdev->destid,
- rdev->hopcount, offset, data);
+ if (likely(rdev->destid != rdev->hport->host_deviceid))
+ return rio_mport_read_config_32(rdev->hport, rdev->destid,
+ rdev->hopcount, offset, data);
+ else
+ return rio_local_read_config_32(rdev->hport, offset, data);
};
/**
@@ -165,8 +168,11 @@ static inline int rio_read_config_32(struct rio_dev *rdev, u32 offset,
static inline int rio_write_config_32(struct rio_dev *rdev, u32 offset,
u32 data)
{
- return rio_mport_write_config_32(rdev->net->hport, rdev->destid,
- rdev->hopcount, offset, data);
+ if (likely(rdev->destid != rdev->hport->host_deviceid))
+ return rio_mport_write_config_32(rdev->hport, rdev->destid,
+ rdev->hopcount, offset, data);
+ else
+ return rio_local_write_config_32(rdev->hport, offset, data);
};
/**
@@ -179,10 +185,13 @@ static inline int rio_write_config_32(struct rio_dev *rdev, u32 offset,
* RIO device's configuration space.
*/
static inline int rio_read_config_16(struct rio_dev *rdev, u32 offset,
- u16 * data)
+ u16 *data)
{
- return rio_mport_read_config_16(rdev->net->hport, rdev->destid,
- rdev->hopcount, offset, data);
+ if (likely(rdev->destid != rdev->hport->host_deviceid))
+ return rio_mport_read_config_16(rdev->hport, rdev->destid,
+ rdev->hopcount, offset, data);
+ else
+ return rio_local_read_config_16(rdev->hport, offset, data);
};
/**
@@ -197,8 +206,11 @@ static inline int rio_read_config_16(struct rio_dev *rdev, u32 offset,
static inline int rio_write_config_16(struct rio_dev *rdev, u32 offset,
u16 data)
{
- return rio_mport_write_config_16(rdev->net->hport, rdev->destid,
- rdev->hopcount, offset, data);
+ if (likely(rdev->destid != rdev->hport->host_deviceid))
+ return rio_mport_write_config_16(rdev->hport, rdev->destid,
+ rdev->hopcount, offset, data);
+ else
+ return rio_local_write_config_16(rdev->hport, offset, data);
};
/**
@@ -210,10 +222,13 @@ static inline int rio_write_config_16(struct rio_dev *rdev, u32 offset,
* Reads 8 bits of data from the specified offset within the
* RIO device's configuration space.
*/
-static inline int rio_read_config_8(struct rio_dev *rdev, u32 offset, u8 * data)
+static inline int rio_read_config_8(struct rio_dev *rdev, u32 offset, u8 *data)
{
- return rio_mport_read_config_8(rdev->net->hport, rdev->destid,
- rdev->hopcount, offset, data);
+ if (likely(rdev->destid != rdev->hport->host_deviceid))
+ return rio_mport_read_config_8(rdev->hport, rdev->destid,
+ rdev->hopcount, offset, data);
+ else
+ return rio_local_read_config_8(rdev->hport, offset, data);
};
/**
@@ -227,8 +242,11 @@ static inline int rio_read_config_8(struct rio_dev *rdev, u32 offset, u8 * data)
*/
static inline int rio_write_config_8(struct rio_dev *rdev, u32 offset, u8 data)
{
- return rio_mport_write_config_8(rdev->net->hport, rdev->destid,
- rdev->hopcount, offset, data);
+ if (likely(rdev->destid != rdev->hport->host_deviceid))
+ return rio_mport_write_config_8(rdev->hport, rdev->destid,
+ rdev->hopcount, offset, data);
+ else
+ return rio_local_write_config_8(rdev->hport, offset, data);
};
extern int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid,
@@ -244,7 +262,7 @@ extern int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid,
*/
static inline int rio_send_doorbell(struct rio_dev *rdev, u16 data)
{
- return rio_mport_send_doorbell(rdev->net->hport, rdev->destid, data);
+ return rio_mport_send_doorbell(rdev->hport, rdev->destid, data);
};
/**
@@ -292,13 +310,13 @@ static inline void rio_init_dbell_res(struct resource *res, u16 start, u16 end)
* specific device. The assembly vendor and assembly device fields
* will be set to %RIO_ANY_ID.
*/
-#define RIO_DEVICE(dev,ven) \
+#define RIO_DEVICE(dev, ven) \
.did = (dev), .vid = (ven), \
.asm_did = RIO_ANY_ID, .asm_vid = RIO_ANY_ID
/* Mailbox management */
-extern int rio_request_outb_mbox(struct rio_mport *, void *, int, int,
- void (*)(struct rio_mport *, void *,int, int));
+extern int rio_request_outb_mbox(struct rio_mport *, void *, int, int, int,
+ void (*)(struct rio_mport *, void *, int, int, void *));
extern int rio_release_outb_mbox(struct rio_mport *, int);
/**
@@ -313,15 +331,18 @@ extern int rio_release_outb_mbox(struct rio_mport *, int);
* transmission. Returns 0 on success.
*/
static inline int rio_add_outb_message(struct rio_mport *mport,
- struct rio_dev *rdev, int mbox,
- void *buffer, size_t len)
+ struct rio_dev *rdev,
+ int mbox_dest, int letter, int flags,
+ void *buffer, size_t len,
+ void *cookie)
{
- return mport->ops->add_outb_message(mport, rdev, mbox,
- buffer, len);
+ return mport->ops->add_outb_message(mport, rdev,
+ mbox_dest, letter, flags,
+ buffer, len, cookie);
}
extern int rio_request_inb_mbox(struct rio_mport *, void *, int, int,
- void (*)(struct rio_mport *, void *, int, int));
+ void (*)(struct rio_mport *, void *, int, int));
extern int rio_release_inb_mbox(struct rio_mport *, int);
/**
@@ -346,30 +367,33 @@ static inline int rio_add_inb_buffer(struct rio_mport *mport, int mbox,
*
* Get a RIO message from an inbound mailbox queue. Returns 0 on success.
*/
-static inline void *rio_get_inb_message(struct rio_mport *mport, int mbox)
+static inline void *rio_get_inb_message(struct rio_mport *mport, int mbox,
+ int letter, int *sz, int *slot, u16 *destid)
{
- return mport->ops->get_inb_message(mport, mbox);
+ return mport->ops->get_inb_message(mport, mbox, letter, \
+ sz, slot, destid);
}
/* Doorbell management */
extern int rio_request_inb_dbell(struct rio_mport *, void *, u16, u16,
- void (*)(struct rio_mport *, void *, u16, u16, u16));
+ void (*)(struct rio_mport *, void *, u16, u16, u16));
extern int rio_release_inb_dbell(struct rio_mport *, u16, u16);
extern struct resource *rio_request_outb_dbell(struct rio_dev *, u16, u16);
extern int rio_release_outb_dbell(struct rio_dev *, struct resource *);
-/* Memory region management */
-int rio_claim_resource(struct rio_dev *, int);
-int rio_request_regions(struct rio_dev *, char *);
-void rio_release_regions(struct rio_dev *);
-int rio_request_region(struct rio_dev *, int, char *);
-void rio_release_region(struct rio_dev *, int);
+/* Memory low-level mapping functions */
+extern int rio_req_outb_region(struct rio_mport *, resource_size_t,
+ const char *, u32, u32*);
+extern int rio_map_outb_mem(struct rio_mport *,
+ u32, u16, u32, u32, struct rio_map_addr*);
+extern void rio_release_outb_region(struct rio_mport *, u32);
/* Port-Write management */
extern int rio_request_inb_pwrite(struct rio_dev *,
int (*)(struct rio_dev *, union rio_pw_msg*, int));
extern int rio_release_inb_pwrite(struct rio_dev *);
-extern int rio_inb_pwrite_handler(union rio_pw_msg *pw_msg);
+extern int rio_inb_pwrite_handler(struct rio_mport *mport, \
+ union rio_pw_msg *pw_msg);
/* LDM support */
int rio_register_driver(struct rio_driver *);
@@ -419,5 +443,97 @@ extern u16 rio_local_get_device_id(struct rio_mport *port);
extern struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from);
extern struct rio_dev *rio_get_asm(u16 vid, u16 did, u16 asm_vid, u16 asm_did,
struct rio_dev *from);
+extern struct rio_mport *rio_get_mport(int hostid, struct rio_mport *from);
+extern struct rio_dev **rio_get_all_devices(struct rio_mport *mport, int *n);
+extern struct rio_dev *lookup_rdev(struct rio_mport *mport, u16 destid);
+#define RIO_JOB_FLAG_STATIC 0x1
+
+extern int rio_job_init(struct rio_mport *mport, struct rio_dev *rdev,
+ int port, u32 flags, int hw_access, int event);
+extern struct rio_dev *rio_get_root_node(struct rio_mport *mport);
+extern int rio_lookup_next_destid(struct rio_mport *mport, u16 parent_destid,
+ int port_num, u8 hopcount, u16 *id);
+
+#if defined(CONFIG_RAPIDIO_HOTPLUG)
+
+extern void rio_rescan_mport(struct rio_mport *mport);
+extern void rio_remove_mport_net(struct rio_mport *mport, int hw_access);
+
+static inline int rio_hotswap(struct rio_mport *mport, u8 flags)
+{
+ if (mport->ops->hotswap)
+ return mport->ops->hotswap(mport, flags);
+ else
+ return -EINVAL;
+}
+static inline int rio_request_mport_cb(struct rio_mport *mport,
+ int enable,
+ void (*cb)(struct rio_mport *mport))
+{
+ if (mport->ops->port_notify_cb)
+ return mport->ops->port_notify_cb(mport, enable, cb);
+ else
+ return -EINVAL;
+}
+#define MPORT_STATE_OPERATIONAL 0
+#define MPORT_STATE_DOWN 1
+#define MPORT_STATE_UNKNOWN 3
+static inline int rio_port_op_state(struct rio_mport *mport)
+{
+ if (mport->ops->port_op_state)
+ return mport->ops->port_op_state(mport);
+ else
+ return MPORT_STATE_UNKNOWN;
+}
+
+extern int rio_setup_event(struct rio_dev *rdev, int portnum, int event);
+extern int rio_setup_event_force(struct rio_dev *rdev, int portnum, int event);
+
+#endif
+
+#ifdef CONFIG_RAPIDIO_STATIC_DESTID
+extern int rio_add_netid(u16 mport_destid, int net_id, int comptag);
+
+extern int rio_add_destid(struct rio_mport *mport,
+ u16 parent_destid, int parent_port,
+ int hopcount, u16 destid, u16 comptag);
+extern int rio_block_destid_route(struct rio_mport *mport,
+ u16 parent_destid, int parent_port,
+ int hopcount, u16 destid, u16 comptag);
+extern int rio_split_destid_route(struct rio_mport *mport, u16 parent_destid,
+ int parent_port, int hopcount, u16 destid,
+ u16 comptag, u8 return_port);
+extern int rio_legacy_destid_route(struct rio_mport *mport,
+ u16 parent_destid, int parent_port,
+ int hopcount, u16 destid, u16 comptag,
+ u8 lock_hw, u8 lut_update);
+extern void rio_release_destid(struct rio_mport *mport, u16 parent_destid,
+ int parent_port, int hopcount);
+extern int rio_add_static_route(struct rio_mport *mport, u16 parent_destid,
+ int parent_port, int hopcount,
+ struct rio_static_route *route, int num_routes);
+extern int rio_update_static_route(struct rio_mport *mport, u16 parent_destid,
+ int parent_port, int hopcount,
+ struct rio_static_route *route, int num_routes);
+extern int rio_remove_static_route(struct rio_mport *mport, u16 parent_destid,
+ int parent_port, int hopcount,
+ struct rio_static_route *route, int num_routes);
+extern int rio_lookup_static_routes(struct rio_mport *mport, u16 parent_destid,
+ int parent_port, int hopcount,
+ struct rio_static_route *sroute, int num_routes);
+extern struct rio_static_route *rio_static_route_table(struct rio_mport *mport,
+ u16 parent_destid,
+ int parent_port,
+ int hopcount,
+ u16 *destid,
+ int *n);
+extern int rio_remove_netid(u16 mport_destid, int net_id);
+extern int rio_find_netid(u16 mport_destid, int *net_id);
+extern int rio_release_node_table(struct rio_mport *mport);
+#endif
+
+#if defined(CONFIG_RAPIDIO_HOTPLUG) || defined(CONFIG_RAPIDIO_STATIC_DESTID)
+extern ssize_t rio_net_nodes_show(struct rio_mport *mport, char *buf);
+#endif
#endif /* LINUX_RIO_DRV_H */
diff --git a/include/linux/rio_ids.h b/include/linux/rio_ids.h
index b66d13d..ffca266 100644
--- a/include/linux/rio_ids.h
+++ b/include/linux/rio_ids.h
@@ -40,5 +40,12 @@
#define RIO_DID_IDTVPS1616 0x0377
#define RIO_DID_IDTSPS1616 0x0378
#define RIO_DID_TSI721 0x80ab
+#define RIO_VID_JENNIC 0x005a
+#define RIO_DID_ERICSSON_ULMA 0x0000
+#define RIO_DID_ERICSSON_MERCURY 0x0006
+#define RIO_DID_ERICSSON_HERMES 0x0007
+#define RIO_VID_TEXAS 0x0030
+#define RIO_DID_TEXAS_TCI6616 0xb941
+#define RIO_DID_TEXAS_TCI6616X 0x009d
#endif /* LINUX_RIO_IDS_H */
diff --git a/include/linux/rio_regs.h b/include/linux/rio_regs.h
index 218168a..d178b9b 100644
--- a/include/linux/rio_regs.h
+++ b/include/linux/rio_regs.h
@@ -42,8 +42,13 @@
#define RIO_PEF_INB_MBOX2 0x00200000 /* [II, <= 1.2] Mailbox 2 */
#define RIO_PEF_INB_MBOX3 0x00100000 /* [II, <= 1.2] Mailbox 3 */
#define RIO_PEF_INB_DOORBELL 0x00080000 /* [II, <= 1.2] Doorbells */
+#define RIO_PEF_FLOW_ARB 0x00000800 /* [III] Flow Arbitration support */
+#define RIO_PEF_MCAST 0x00000400 /* [III] Multicast support */
#define RIO_PEF_EXT_RT 0x00000200 /* [III, 1.3] Extended route table support */
#define RIO_PEF_STD_RT 0x00000100 /* [III, 1.3] Standard route table support */
+#define RIO_PEF_FCS 0x00000080 /* [III] Flow Control Support */
+#define RIO_PEF_CRC_ERR_REC 0x00000040 /* [III] CRC Error Recovery */
+#define RIO_PEF_CRFS 0x00000020 /* [III] Critical Request Flow Supt */
#define RIO_PEF_CTLS 0x00000010 /* [III] CTLS */
#define RIO_PEF_EXT_FEATURES 0x00000008 /* [I] EFT_PTR valid */
#define RIO_PEF_ADDR_66 0x00000004 /* [I] 66 bits */
@@ -167,6 +172,25 @@
#define RIO_STD_RTE_CONF_PORT_SEL_CSR 0x74
#define RIO_STD_RTE_DEFAULT_PORT 0x78
+#define RIO_MCAST_MASK_PORT_CSR 0x80 /* Multicast Mask Port CSR */
+#define RIO_MCAST_MASK(x) ((x) << 16) /* Multicast Mask */
+#define RIO_EGRESS_PORT_NUMBER(x) ((x) << 8) /* Port Number */
+#define RIO_MASK_CMD_ADD_PORT (0x1 << 4) /* Add Port Command */
+#define RIO_MASK_CMD_DEL_PORT (0x2 << 4) /* Delete Port Command */
+#define RIO_MASK_CMD_DEL_ALL_PORTS (0x4 << 4) /* Delete All Ports Cmd */
+#define RIO_MASK_CMD_ADD_ALL_PORTS (0x5 << 4) /* Add All Ports Cmd */
+#define RIO_MCAST_PORT_PRESENT (0x00000001) /* Port Present from Write
+ to Verify command */
+
+#define RIO_MCAST_ASSOC_SEL_CSR 0x84 /* Multicast Assoc Select CSR */
+#define RIO_MCAST_LARGE_DEST_ID(x) ((x) << 24) /* Large Destination Id */
+#define RIO_MCAST_DEST_ID(x) ((x) << 16) /* Destination Id */
+#define RIO_MCAST_MASK_NO(x) (x) /* Multicast Mask # */
+
+#define RIO_MCAST_ASSOC_OP_CSR 0x88 /* Multicast Assoc Operation CSR */
+#define RIO_MCAST_TRANS_ASSOC(x) ((x) << 7) /* Transport Association */
+#define RIO_MCAST_DEL_ASSOC (0x1 << 5) /* Delete Association */
+#define RIO_MCAST_ADD_ASSOC (0x3 << 5) /* Add Association */
/* 0x7c-0xf8 *//* Reserved */
/* 0x100-0xfff8 *//* [I] Extended Features Space */
/* 0x10000-0xfffff8 *//* [I] Implementation-defined Space */
@@ -251,10 +275,12 @@
#define RIO_PORT_N_CTL_PWIDTH_4 0x40000000
#define RIO_PORT_N_CTL_P_TYP_SER 0x00000001
#define RIO_PORT_N_CTL_LOCKOUT 0x00000002
+#define RIO_PORT_N_CTL_PORT_DIS 0x00800000
#define RIO_PORT_N_CTL_EN_RX_SER 0x00200000
#define RIO_PORT_N_CTL_EN_TX_SER 0x00400000
#define RIO_PORT_N_CTL_EN_RX_PAR 0x08000000
#define RIO_PORT_N_CTL_EN_TX_PAR 0x40000000
+#define RIO_PORT_N_CTL_ENUM_BOUNDARY 0x00020000
/*
* Error Management Extensions (RapidIO 1.3+, Part 8)
diff --git a/include/linux/riopw.h b/include/linux/riopw.h
new file mode 100644
index 0000000..ec7ef76f
--- /dev/null
+++ b/include/linux/riopw.h
@@ -0,0 +1,30 @@
+#ifndef _RIOPW_H_
+#define _RIOPW_H_
+
+#define RIOPW_IOC_MAGIC 'j' /* Arbitrary */
+#define RIOPW_IOC_MINNR 0x40
+#define RIOPW_IOC_MAXNR 0x80
+
+#define IOCTL_MPORT_GETHID _IOR(RIOPW_IOC_MAGIC, 0x40, int)
+#define IOCTL_MPORT_GETPWMSG _IOR(RIOPW_IOC_MAGIC, 0x45, int)
+
+#ifdef __KERNEL__
+#else
+
+#define RIO_PW_MSG_SIZE 64
+
+union rio_pw_msg {
+ struct {
+ unsigned int comptag; /* Component Tag CSR */
+ unsigned int errdetect; /* Port N Error Detect CSR */
+ unsigned int is_port; /* Implementation specific + PortID */
+ unsigned int ltlerrdet; /* LTL Error Detect CSR */
+ unsigned int padding[12];
+ } em;
+ unsigned int raw[RIO_PW_MSG_SIZE/sizeof(unsigned int)];
+};
+
+#endif
+
+
+#endif
--
1.7.9.5
More information about the linux-yocto
mailing list