0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/rio.h>
0010 #include <linux/rio_drv.h>
0011 #include <linux/rio_ids.h>
0012 #include <linux/module.h>
0013 #include "../rio.h"
0014
0015 #define CPS_DEFAULT_ROUTE 0xde
0016 #define CPS_NO_ROUTE 0xdf
0017
0018 #define IDTCPS_RIO_DOMAIN 0xf20020
0019
0020 static int
0021 idtcps_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
0022 u16 table, u16 route_destid, u8 route_port)
0023 {
0024 u32 result;
0025
0026 if (route_port == RIO_INVALID_ROUTE)
0027 route_port = CPS_DEFAULT_ROUTE;
0028
0029 if (table == RIO_GLOBAL_TABLE) {
0030 rio_mport_write_config_32(mport, destid, hopcount,
0031 RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);
0032
0033 rio_mport_read_config_32(mport, destid, hopcount,
0034 RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);
0035
0036 result = (0xffffff00 & result) | (u32)route_port;
0037 rio_mport_write_config_32(mport, destid, hopcount,
0038 RIO_STD_RTE_CONF_PORT_SEL_CSR, result);
0039 }
0040
0041 return 0;
0042 }
0043
0044 static int
0045 idtcps_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
0046 u16 table, u16 route_destid, u8 *route_port)
0047 {
0048 u32 result;
0049
0050 if (table == RIO_GLOBAL_TABLE) {
0051 rio_mport_write_config_32(mport, destid, hopcount,
0052 RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);
0053
0054 rio_mport_read_config_32(mport, destid, hopcount,
0055 RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);
0056
0057 if (CPS_DEFAULT_ROUTE == (u8)result ||
0058 CPS_NO_ROUTE == (u8)result)
0059 *route_port = RIO_INVALID_ROUTE;
0060 else
0061 *route_port = (u8)result;
0062 }
0063
0064 return 0;
0065 }
0066
0067 static int
0068 idtcps_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
0069 u16 table)
0070 {
0071 u32 i;
0072
0073 if (table == RIO_GLOBAL_TABLE) {
0074 for (i = 0x80000000; i <= 0x800000ff;) {
0075 rio_mport_write_config_32(mport, destid, hopcount,
0076 RIO_STD_RTE_CONF_DESTID_SEL_CSR, i);
0077 rio_mport_write_config_32(mport, destid, hopcount,
0078 RIO_STD_RTE_CONF_PORT_SEL_CSR,
0079 (CPS_DEFAULT_ROUTE << 24) |
0080 (CPS_DEFAULT_ROUTE << 16) |
0081 (CPS_DEFAULT_ROUTE << 8) | CPS_DEFAULT_ROUTE);
0082 i += 4;
0083 }
0084 }
0085
0086 return 0;
0087 }
0088
0089 static int
0090 idtcps_set_domain(struct rio_mport *mport, u16 destid, u8 hopcount,
0091 u8 sw_domain)
0092 {
0093
0094
0095
0096 rio_mport_write_config_32(mport, destid, hopcount,
0097 IDTCPS_RIO_DOMAIN, (u32)sw_domain);
0098 return 0;
0099 }
0100
0101 static int
0102 idtcps_get_domain(struct rio_mport *mport, u16 destid, u8 hopcount,
0103 u8 *sw_domain)
0104 {
0105 u32 regval;
0106
0107
0108
0109
0110 rio_mport_read_config_32(mport, destid, hopcount,
0111 IDTCPS_RIO_DOMAIN, ®val);
0112
0113 *sw_domain = (u8)(regval & 0xff);
0114
0115 return 0;
0116 }
0117
0118 static struct rio_switch_ops idtcps_switch_ops = {
0119 .owner = THIS_MODULE,
0120 .add_entry = idtcps_route_add_entry,
0121 .get_entry = idtcps_route_get_entry,
0122 .clr_table = idtcps_route_clr_table,
0123 .set_domain = idtcps_set_domain,
0124 .get_domain = idtcps_get_domain,
0125 .em_init = NULL,
0126 .em_handle = NULL,
0127 };
0128
0129 static int idtcps_probe(struct rio_dev *rdev, const struct rio_device_id *id)
0130 {
0131 pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
0132
0133 spin_lock(&rdev->rswitch->lock);
0134
0135 if (rdev->rswitch->ops) {
0136 spin_unlock(&rdev->rswitch->lock);
0137 return -EINVAL;
0138 }
0139
0140 rdev->rswitch->ops = &idtcps_switch_ops;
0141
0142 if (rdev->do_enum) {
0143
0144 rio_write_config_32(rdev,
0145 rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8);
0146
0147 rio_write_config_32(rdev,
0148 RIO_STD_RTE_DEFAULT_PORT, CPS_NO_ROUTE);
0149 }
0150
0151 spin_unlock(&rdev->rswitch->lock);
0152 return 0;
0153 }
0154
0155 static void idtcps_remove(struct rio_dev *rdev)
0156 {
0157 pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
0158 spin_lock(&rdev->rswitch->lock);
0159 if (rdev->rswitch->ops != &idtcps_switch_ops) {
0160 spin_unlock(&rdev->rswitch->lock);
0161 return;
0162 }
0163 rdev->rswitch->ops = NULL;
0164 spin_unlock(&rdev->rswitch->lock);
0165 }
0166
0167 static const struct rio_device_id idtcps_id_table[] = {
0168 {RIO_DEVICE(RIO_DID_IDTCPS6Q, RIO_VID_IDT)},
0169 {RIO_DEVICE(RIO_DID_IDTCPS8, RIO_VID_IDT)},
0170 {RIO_DEVICE(RIO_DID_IDTCPS10Q, RIO_VID_IDT)},
0171 {RIO_DEVICE(RIO_DID_IDTCPS12, RIO_VID_IDT)},
0172 {RIO_DEVICE(RIO_DID_IDTCPS16, RIO_VID_IDT)},
0173 {RIO_DEVICE(RIO_DID_IDT70K200, RIO_VID_IDT)},
0174 { 0, }
0175 };
0176
0177 static struct rio_driver idtcps_driver = {
0178 .name = "idtcps",
0179 .id_table = idtcps_id_table,
0180 .probe = idtcps_probe,
0181 .remove = idtcps_remove,
0182 };
0183
0184 static int __init idtcps_init(void)
0185 {
0186 return rio_register_driver(&idtcps_driver);
0187 }
0188
0189 static void __exit idtcps_exit(void)
0190 {
0191 rio_unregister_driver(&idtcps_driver);
0192 }
0193
0194 device_initcall(idtcps_init);
0195 module_exit(idtcps_exit);
0196
0197 MODULE_DESCRIPTION("IDT CPS Gen.1 Serial RapidIO switch family driver");
0198 MODULE_AUTHOR("Integrated Device Technology, Inc.");
0199 MODULE_LICENSE("GPL");