[linux-yocto] [PATCH 06/28] include: rapidio updates

Charlie Paul cpaul.windriver at gmail.com
Fri May 2 09:22:10 PDT 2014


From: Paul Butler <paul.butler at windriver.com>

This patch adds the register definitions,
support for PW messages, destination IDs, direct IO and
driver support.

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