---help---
          Amount of time a discovery node waits for a host to complete
          enumeration before giving up.
+
+source "drivers/rapidio/switches/Kconfig"
 
 static int rio_sport_phys_table[] = {
        RIO_EFB_PAR_EP_FREE_ID,
        RIO_EFB_SER_EP_FREE_ID,
+       RIO_EFB_SER_EP_FREC_ID,
        -1,
 };
 
                        pr_debug("RIO: adding routing ops for %s\n", rio_name(rdev));
                        rdev->rswitch->add_entry = cur->add_hook;
                        rdev->rswitch->get_entry = cur->get_hook;
+                       rdev->rswitch->clr_table = cur->clr_hook;
+                       break;
                }
                cur++;
        }
 
+       if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) {
+               pr_debug("RIO: adding STD routing ops for %s\n",
+                       rio_name(rdev));
+               rdev->rswitch->add_entry = rio_std_route_add_entry;
+               rdev->rswitch->get_entry = rio_std_route_get_entry;
+               rdev->rswitch->clr_table = rio_std_route_clr_table;
+       }
+
        if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
                printk(KERN_ERR "RIO: missing routing ops for %s\n",
                       rio_name(rdev));
        if (rio_is_switch(rdev)) {
                rio_mport_read_config_32(port, destid, hopcount,
                                         RIO_SWP_INFO_CAR, &rdev->swpinfo);
-               rswitch = kmalloc(sizeof(struct rio_switch), GFP_KERNEL);
+               rswitch = kzalloc(sizeof(struct rio_switch), GFP_KERNEL);
                if (!rswitch)
                        goto cleanup;
                rswitch->switchid = next_switchid;
                             rdev->rswitch->switchid);
                rio_route_set_ops(rdev);
 
+               if (do_enum && rdev->rswitch->clr_table)
+                       rdev->rswitch->clr_table(port, destid, hopcount,
+                                                RIO_GLOBAL_TABLE);
+
                list_add_tail(&rswitch->node, &rio_switches);
 
        } else
                                continue;
 
                        if (RIO_INVALID_ROUTE == rswitch->route_table[destid]) {
+                               /* Skip if destid ends in empty switch*/
+                               if (rswitch->destid == destid)
+                                       continue;
 
                                sport = rio_get_swpinfo_inport(port,
                                                rswitch->destid, rswitch->hopcount);
 
        return rio_get_asm(vid, did, RIO_ANY_ID, RIO_ANY_ID, from);
 }
 
+/**
+ * rio_std_route_add_entry - Add switch route table entry using standard
+ *   registers defined in RIO specification rev.1.3
+ * @mport: Master port to issue transaction
+ * @destid: Destination ID of the device
+ * @hopcount: Number of switch hops to the device
+ * @table: routing table ID (global or port-specific)
+ * @route_destid: destID entry in the RT
+ * @route_port: destination port for specified destID
+ */
+int rio_std_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
+                      u16 table, u16 route_destid, u8 route_port)
+{
+       if (table == RIO_GLOBAL_TABLE) {
+               rio_mport_write_config_32(mport, destid, hopcount,
+                               RIO_STD_RTE_CONF_DESTID_SEL_CSR,
+                               (u32)route_destid);
+               rio_mport_write_config_32(mport, destid, hopcount,
+                               RIO_STD_RTE_CONF_PORT_SEL_CSR,
+                               (u32)route_port);
+       }
+       udelay(10);
+       return 0;
+}
+
+/**
+ * rio_std_route_get_entry - Read switch route table entry (port number)
+ *   assosiated with specified destID using standard registers defined in RIO
+ *   specification rev.1.3
+ * @mport: Master port to issue transaction
+ * @destid: Destination ID of the device
+ * @hopcount: Number of switch hops to the device
+ * @table: routing table ID (global or port-specific)
+ * @route_destid: destID entry in the RT
+ * @route_port: returned destination port for specified destID
+ */
+int rio_std_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
+                      u16 table, u16 route_destid, u8 *route_port)
+{
+       u32 result;
+
+       if (table == RIO_GLOBAL_TABLE) {
+               rio_mport_write_config_32(mport, destid, hopcount,
+                               RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);
+               rio_mport_read_config_32(mport, destid, hopcount,
+                               RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);
+
+               *route_port = (u8)result;
+       }
+
+       return 0;
+}
+
+/**
+ * rio_std_route_clr_table - Clear swotch route table using standard registers
+ *   defined in RIO specification rev.1.3.
+ * @mport: Master port to issue transaction
+ * @local: Indicate a local master port or remote device access
+ * @destid: Destination ID of the device
+ * @hopcount: Number of switch hops to the device
+ * @table: routing table ID (global or port-specific)
+ */
+int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
+                      u16 table)
+{
+       u32 max_destid = 0xff;
+       u32 i, pef, id_inc = 1, ext_cfg = 0;
+       u32 port_sel = RIO_INVALID_ROUTE;
+
+       if (table == RIO_GLOBAL_TABLE) {
+               rio_mport_read_config_32(mport, destid, hopcount,
+                                        RIO_PEF_CAR, &pef);
+
+               if (mport->sys_size) {
+                       rio_mport_read_config_32(mport, destid, hopcount,
+                                                RIO_SWITCH_RT_LIMIT,
+                                                &max_destid);
+                       max_destid &= RIO_RT_MAX_DESTID;
+               }
+
+               if (pef & RIO_PEF_EXT_RT) {
+                       ext_cfg = 0x80000000;
+                       id_inc = 4;
+                       port_sel = (RIO_INVALID_ROUTE << 24) |
+                                  (RIO_INVALID_ROUTE << 16) |
+                                  (RIO_INVALID_ROUTE << 8) |
+                                  RIO_INVALID_ROUTE;
+               }
+
+               for (i = 0; i <= max_destid;) {
+                       rio_mport_write_config_32(mport, destid, hopcount,
+                                       RIO_STD_RTE_CONF_DESTID_SEL_CSR,
+                                       ext_cfg | i);
+                       rio_mport_write_config_32(mport, destid, hopcount,
+                                       RIO_STD_RTE_CONF_PORT_SEL_CSR,
+                                       port_sel);
+                       i += id_inc;
+               }
+       }
+
+       udelay(10);
+       return 0;
+}
+
 static void rio_fixup_device(struct rio_dev *dev)
 {
 }
 
 extern int rio_create_sysfs_dev_files(struct rio_dev *rdev);
 extern int rio_enum_mport(struct rio_mport *mport);
 extern int rio_disc_mport(struct rio_mport *mport);
+extern int rio_std_route_add_entry(struct rio_mport *mport, u16 destid,
+                                  u8 hopcount, u16 table, u16 route_destid,
+                                  u8 route_port);
+extern int rio_std_route_get_entry(struct rio_mport *mport, u16 destid,
+                                  u8 hopcount, u16 table, u16 route_destid,
+                                  u8 *route_port);
+extern int rio_std_route_clr_table(struct rio_mport *mport, u16 destid,
+                                  u8 hopcount, u16 table);
 
 /* Structures internal to the RIO core code */
 extern struct device_attribute rio_dev_attrs[];
 extern struct rio_route_ops __end_rio_route_ops[];
 
 /* Helpers internal to the RIO core code */
-#define DECLARE_RIO_ROUTE_SECTION(section, vid, did, add_hook, get_hook)  \
-       static struct rio_route_ops __rio_route_ops __used   \
-       __section(section)= { vid, did, add_hook, get_hook };
+#define DECLARE_RIO_ROUTE_SECTION(section, name, vid, did, add_hook, get_hook, clr_hook) \
+       static const struct rio_route_ops __rio_route_##name __used \
+       __section(section) = { vid, did, add_hook, get_hook, clr_hook };
 
 /**
  * DECLARE_RIO_ROUTE_OPS - Registers switch routing operations
  * rio_route_ops is initialized with the ops and placed into a
  * RIO-specific kernel section.
  */
-#define DECLARE_RIO_ROUTE_OPS(vid, did, add_hook, get_hook)            \
-       DECLARE_RIO_ROUTE_SECTION(.rio_route_ops,                       \
-                       vid, did, add_hook, get_hook)
+#define DECLARE_RIO_ROUTE_OPS(vid, did, add_hook, get_hook, clr_hook)  \
+       DECLARE_RIO_ROUTE_SECTION(.rio_route_ops, vid##did,             \
+                       vid, did, add_hook, get_hook, clr_hook)
 
 #define RIO_GET_DID(size, x)   (size ? (x & 0xffff) : ((x & 0x00ff0000) >> 16))
 #define RIO_SET_DID(size, x)   (size ? (x & 0xffff) : ((x & 0x000000ff) << 16))
 
--- /dev/null
+#
+# RapidIO switches configuration
+#
+config RAPIDIO_TSI57X
+       bool "IDT Tsi57x SRIO switches support"
+       depends on RAPIDIO
+       ---help---
+         Includes support for ITD Tsi57x family of serial RapidIO switches.
+
+config RAPIDIO_CPS_XX
+       bool "IDT CPS-xx SRIO switches support"
+       depends on RAPIDIO
+       ---help---
+         Includes support for ITD CPS-16/12/10/8 serial RapidIO switches.
+
+config RAPIDIO_TSI568
+       bool "Tsi568 SRIO switch support"
+       depends on RAPIDIO
+       default n
+       ---help---
+         Includes support for ITD Tsi568 serial RapidIO switch.
+
+config RAPIDIO_TSI500
+       bool "Tsi500 Parallel RapidIO switch support"
+       depends on RAPIDIO
+       default n
+       ---help---
+         Includes support for ITD Tsi500 parallel RapidIO switch.
 
 # Makefile for RIO switches
 #
 
-obj-$(CONFIG_RAPIDIO)  += tsi500.o
+obj-$(CONFIG_RAPIDIO_TSI57X)   += tsi57x.o
+obj-$(CONFIG_RAPIDIO_CPS_XX)   += idtcps.o
+obj-$(CONFIG_RAPIDIO_TSI568)   += tsi568.o
+obj-$(CONFIG_RAPIDIO_TSI500)   += tsi500.o
 
--- /dev/null
+/*
+ * IDT CPS RapidIO switches support
+ *
+ * Copyright 2009 Integrated Device Technology, Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/rio_ids.h>
+#include "../rio.h"
+
+#define CPS_NO_ROUTE 0xdf
+
+static int
+idtcps_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
+                      u16 table, u16 route_destid, u8 route_port)
+{
+       u32 result;
+
+       if (table == RIO_GLOBAL_TABLE) {
+               rio_mport_write_config_32(mport, destid, hopcount,
+                               RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);
+
+               rio_mport_read_config_32(mport, destid, hopcount,
+                               RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);
+
+               result = (0xffffff00 & result) | (u32)route_port;
+               rio_mport_write_config_32(mport, destid, hopcount,
+                               RIO_STD_RTE_CONF_PORT_SEL_CSR, result);
+       }
+
+       return 0;
+}
+
+static int
+idtcps_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
+                      u16 table, u16 route_destid, u8 *route_port)
+{
+       u32 result;
+
+       if (table == RIO_GLOBAL_TABLE) {
+               rio_mport_write_config_32(mport, destid, hopcount,
+                               RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);
+
+               rio_mport_read_config_32(mport, destid, hopcount,
+                               RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);
+
+               if (CPS_NO_ROUTE == (u8)result)
+                       result = RIO_INVALID_ROUTE;
+
+               *route_port = (u8)result;
+       }
+
+       return 0;
+}
+
+static int
+idtcps_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
+                      u16 table)
+{
+       u32 i;
+
+       if (table == RIO_GLOBAL_TABLE) {
+               for (i = 0x80000000; i <= 0x800000ff;) {
+                       rio_mport_write_config_32(mport, destid, hopcount,
+                               RIO_STD_RTE_CONF_DESTID_SEL_CSR, i);
+                       rio_mport_write_config_32(mport, destid, hopcount,
+                               RIO_STD_RTE_CONF_PORT_SEL_CSR,
+                               (RIO_INVALID_ROUTE << 24) |
+                               (RIO_INVALID_ROUTE << 16) |
+                               (RIO_INVALID_ROUTE << 8) | RIO_INVALID_ROUTE);
+                       i += 4;
+               }
+       }
+
+       return 0;
+}
+
+DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS6Q, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
+DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS8, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
+DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS10Q, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
+DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS12, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
+DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS16, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
+DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDT70K200, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
 
        return ret;
 }
 
-DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_route_add_entry, tsi500_route_get_entry);
+DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_route_add_entry, tsi500_route_get_entry, NULL);
 
--- /dev/null
+/*
+ * RapidIO Tsi568 switch support
+ *
+ * Copyright 2009-2010 Integrated Device Technology, Inc.
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/rio_ids.h>
+#include <linux/delay.h>
+#include "../rio.h"
+
+/* Global (broadcast) route registers */
+#define SPBC_ROUTE_CFG_DESTID  0x10070
+#define SPBC_ROUTE_CFG_PORT    0x10074
+
+/* Per port route registers */
+#define SPP_ROUTE_CFG_DESTID(n)        (0x11070 + 0x100*n)
+#define SPP_ROUTE_CFG_PORT(n)  (0x11074 + 0x100*n)
+
+static int
+tsi568_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
+                      u16 table, u16 route_destid, u8 route_port)
+{
+       if (table == RIO_GLOBAL_TABLE) {
+               rio_mport_write_config_32(mport, destid, hopcount,
+                                       SPBC_ROUTE_CFG_DESTID, route_destid);
+               rio_mport_write_config_32(mport, destid, hopcount,
+                                       SPBC_ROUTE_CFG_PORT, route_port);
+       } else {
+               rio_mport_write_config_32(mport, destid, hopcount,
+                                       SPP_ROUTE_CFG_DESTID(table),
+                                       route_destid);
+               rio_mport_write_config_32(mport, destid, hopcount,
+                                       SPP_ROUTE_CFG_PORT(table), route_port);
+       }
+
+       udelay(10);
+
+       return 0;
+}
+
+static int
+tsi568_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
+                      u16 table, u16 route_destid, u8 *route_port)
+{
+       int ret = 0;
+       u32 result;
+
+       if (table == RIO_GLOBAL_TABLE) {
+               rio_mport_write_config_32(mport, destid, hopcount,
+                                       SPBC_ROUTE_CFG_DESTID, route_destid);
+               rio_mport_read_config_32(mport, destid, hopcount,
+                                       SPBC_ROUTE_CFG_PORT, &result);
+       } else {
+               rio_mport_write_config_32(mport, destid, hopcount,
+                                       SPP_ROUTE_CFG_DESTID(table),
+                                       route_destid);
+               rio_mport_read_config_32(mport, destid, hopcount,
+                                       SPP_ROUTE_CFG_PORT(table), &result);
+       }
+
+       *route_port = result;
+       if (*route_port > 15)
+               ret = -1;
+
+       return ret;
+}
+
+static int
+tsi568_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
+                      u16 table)
+{
+       u32 route_idx;
+       u32 lut_size;
+
+       lut_size = (mport->sys_size) ? 0x1ff : 0xff;
+
+       if (table == RIO_GLOBAL_TABLE) {
+               rio_mport_write_config_32(mport, destid, hopcount,
+                                       SPBC_ROUTE_CFG_DESTID, 0x80000000);
+               for (route_idx = 0; route_idx <= lut_size; route_idx++)
+                       rio_mport_write_config_32(mport, destid, hopcount,
+                                               SPBC_ROUTE_CFG_PORT,
+                                               RIO_INVALID_ROUTE);
+       } else {
+               rio_mport_write_config_32(mport, destid, hopcount,
+                                       SPP_ROUTE_CFG_DESTID(table),
+                                       0x80000000);
+               for (route_idx = 0; route_idx <= lut_size; route_idx++)
+                       rio_mport_write_config_32(mport, destid, hopcount,
+                                               SPP_ROUTE_CFG_PORT(table),
+                                               RIO_INVALID_ROUTE);
+       }
+
+       return 0;
+}
+
+DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI568, tsi568_route_add_entry, tsi568_route_get_entry, tsi568_route_clr_table);
 
--- /dev/null
+/*
+ * RapidIO Tsi57x switch family support
+ *
+ * Copyright 2009 Integrated Device Technology, Inc.
+ * Copyright 2005 MontaVista Software, Inc.
+ * Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/rio.h>
+#include <linux/rio_drv.h>
+#include <linux/rio_ids.h>
+#include <linux/delay.h>
+#include "../rio.h"
+
+/* Global (broadcast) route registers */
+#define SPBC_ROUTE_CFG_DESTID  0x10070
+#define SPBC_ROUTE_CFG_PORT    0x10074
+
+/* Per port route registers */
+#define SPP_ROUTE_CFG_DESTID(n)        (0x11070 + 0x100*n)
+#define SPP_ROUTE_CFG_PORT(n)  (0x11074 + 0x100*n)
+
+static int
+tsi57x_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
+                      u16 table, u16 route_destid, u8 route_port)
+{
+       if (table == RIO_GLOBAL_TABLE) {
+               rio_mport_write_config_32(mport, destid, hopcount,
+                                         SPBC_ROUTE_CFG_DESTID, route_destid);
+               rio_mport_write_config_32(mport, destid, hopcount,
+                                         SPBC_ROUTE_CFG_PORT, route_port);
+       } else {
+               rio_mport_write_config_32(mport, destid, hopcount,
+                               SPP_ROUTE_CFG_DESTID(table), route_destid);
+               rio_mport_write_config_32(mport, destid, hopcount,
+                               SPP_ROUTE_CFG_PORT(table), route_port);
+       }
+
+       udelay(10);
+
+       return 0;
+}
+
+static int
+tsi57x_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
+                      u16 table, u16 route_destid, u8 *route_port)
+{
+       int ret = 0;
+       u32 result;
+
+       if (table == RIO_GLOBAL_TABLE) {
+               /* Use local RT of the ingress port to avoid possible
+                  race condition */
+               rio_mport_read_config_32(mport, destid, hopcount,
+                       RIO_SWP_INFO_CAR, &result);
+               table = (result & RIO_SWP_INFO_PORT_NUM_MASK);
+       }
+
+       rio_mport_write_config_32(mport, destid, hopcount,
+                               SPP_ROUTE_CFG_DESTID(table), route_destid);
+       rio_mport_read_config_32(mport, destid, hopcount,
+                               SPP_ROUTE_CFG_PORT(table), &result);
+
+       *route_port = (u8)result;
+       if (*route_port > 15)
+               ret = -1;
+
+       return ret;
+}
+
+static int
+tsi57x_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
+                      u16 table)
+{
+       u32 route_idx;
+       u32 lut_size;
+
+       lut_size = (mport->sys_size) ? 0x1ff : 0xff;
+
+       if (table == RIO_GLOBAL_TABLE) {
+               rio_mport_write_config_32(mport, destid, hopcount,
+                                         SPBC_ROUTE_CFG_DESTID, 0x80000000);
+               for (route_idx = 0; route_idx <= lut_size; route_idx++)
+                       rio_mport_write_config_32(mport, destid, hopcount,
+                                                 SPBC_ROUTE_CFG_PORT,
+                                                 RIO_INVALID_ROUTE);
+       } else {
+               rio_mport_write_config_32(mport, destid, hopcount,
+                               SPP_ROUTE_CFG_DESTID(table), 0x80000000);
+               for (route_idx = 0; route_idx <= lut_size; route_idx++)
+                       rio_mport_write_config_32(mport, destid, hopcount,
+                               SPP_ROUTE_CFG_PORT(table) , RIO_INVALID_ROUTE);
+       }
+
+       return 0;
+}
+
+DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI572, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table);
+DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI574, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table);
+DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI577, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table);
+DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI578, tsi57x_route_add_entry, tsi57x_route_get_entry, tsi57x_route_clr_table);
 
  * @route_table: Copy of switch routing table
  * @add_entry: Callback for switch-specific route add function
  * @get_entry: Callback for switch-specific route get function
+ * @clr_table: Callback for switch-specific clear route table function
  */
 struct rio_switch {
        struct list_head node;
                          u16 table, u16 route_destid, u8 route_port);
        int (*get_entry) (struct rio_mport * mport, u16 destid, u8 hopcount,
                          u16 table, u16 route_destid, u8 * route_port);
+       int (*clr_table) (struct rio_mport *mport, u16 destid, u8 hopcount,
+                         u16 table);
 };
 
 /* Low-level architecture-dependent routines */
  * @did: RIO device ID
  * @add_hook: Callback that adds a route entry
  * @get_hook: Callback that gets a route entry
+ * @clr_hook: Callback that clears a switch route table (may be NULL)
  *
  * Defines the operations that are necessary to manipulate the route
  * tables for a particular RIO switch device.
                         u16 table, u16 route_destid, u8 route_port);
        int (*get_hook) (struct rio_mport * mport, u16 destid, u8 hopcount,
                         u16 table, u16 route_destid, u8 * route_port);
+       int (*clr_hook) (struct rio_mport *mport, u16 destid, u8 hopcount,
+                        u16 table);
 };
 
 /* Architecture and hardware-specific functions */
 
 
 #define RIO_VID_TUNDRA                 0x000d
 #define RIO_DID_TSI500                 0x0500
+#define RIO_DID_TSI568                 0x0568
+#define RIO_DID_TSI572                 0x0572
+#define RIO_DID_TSI574                 0x0574
+#define RIO_DID_TSI576                 0x0578 /* Same ID as Tsi578 */
+#define RIO_DID_TSI577                 0x0577
+#define RIO_DID_TSI578                 0x0578
+
+#define RIO_VID_IDT                    0x0038
+#define RIO_DID_IDT70K200              0x0310
+#define RIO_DID_IDTCPS8                        0x035c
+#define RIO_DID_IDTCPS12               0x035d
+#define RIO_DID_IDTCPS16               0x035b
+#define RIO_DID_IDTCPS6Q               0x035f
+#define RIO_DID_IDTCPS10Q              0x035e
 
 #endif                         /* LINUX_RIO_IDS_H */
 
 #define  RIO_PEF_INB_MBOX2             0x00200000      /* [II] Mailbox 2 */
 #define  RIO_PEF_INB_MBOX3             0x00100000      /* [II] Mailbox 3 */
 #define  RIO_PEF_INB_DOORBELL          0x00080000      /* [II] Doorbells */
+#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_CTLS                  0x00000010      /* [III] CTLS */
 #define  RIO_PEF_EXT_FEATURES          0x00000008      /* [I] EFT_PTR valid */
 #define  RIO_PEF_ADDR_66               0x00000004      /* [I] 66 bits */
 #define  RIO_OPS_ATOMIC_CLR            0x00000010      /* [I] Atomic clr op */
 #define  RIO_OPS_PORT_WRITE            0x00000004      /* [I] Port-write op */
 
-                                       /* 0x20-0x3c *//* Reserved */
+                                       /* 0x20-0x30 *//* Reserved */
+
+#define        RIO_SWITCH_RT_LIMIT     0x34    /* [III, 1.3] Switch Route Table Destination ID Limit CAR */
+#define         RIO_RT_MAX_DESTID              0x0000ffff
 
 #define RIO_MBOX_CSR           0x40    /* [II] Mailbox CSR */
 #define  RIO_MBOX0_AVAIL               0x80000000      /* [II] Mbox 0 avail */
 #define RIO_HOST_DID_LOCK_CSR  0x68    /* [III] Host Base Device ID Lock CSR */
 #define RIO_COMPONENT_TAG_CSR  0x6c    /* [III] Component Tag CSR */
 
-                                       /* 0x70-0xf8 *//* Reserved */
+#define RIO_STD_RTE_CONF_DESTID_SEL_CSR        0x70
+#define RIO_STD_RTE_CONF_PORT_SEL_CSR  0x74
+#define RIO_STD_RTE_DEFAULT_PORT       0x78
+
+                                       /* 0x7c-0xf8 *//* Reserved */
                                        /* 0x100-0xfff8 *//* [I] Extended Features Space */
                                        /* 0x10000-0xfffff8 *//* [I] Implementation-defined Space */
 
 #define RIO_EFB_SER_EP_ID      0x0004  /* [VI] LP/Serial EP Devices */
 #define RIO_EFB_SER_EP_REC_ID  0x0005  /* [VI] LP/Serial EP Recovery Devices */
 #define RIO_EFB_SER_EP_FREE_ID 0x0006  /* [VI] LP/Serial EP Free Devices */
+#define RIO_EFB_SER_EP_FREC_ID 0x0009  /* [VI] LP/Serial EP Free Recovery Devices */
 
 /*
  * Physical 8/16 LP-LVDS