diff options
Diffstat (limited to 'drivers/rapidio/switches/idtcps.c')
-rw-r--r-- | drivers/rapidio/switches/idtcps.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/drivers/rapidio/switches/idtcps.c b/drivers/rapidio/switches/idtcps.c new file mode 100644 index 000000000000..7e3d03283dec --- /dev/null +++ b/drivers/rapidio/switches/idtcps.c | |||
@@ -0,0 +1,89 @@ | |||
1 | /* | ||
2 | * IDT CPS RapidIO switches support | ||
3 | * | ||
4 | * Copyright 2009 Integrated Device Technology, Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/rio.h> | ||
13 | #include <linux/rio_drv.h> | ||
14 | #include <linux/rio_ids.h> | ||
15 | #include "../rio.h" | ||
16 | |||
17 | #define CPS_NO_ROUTE 0xdf | ||
18 | |||
19 | static int | ||
20 | idtcps_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, | ||
21 | u16 table, u16 route_destid, u8 route_port) | ||
22 | { | ||
23 | u32 result; | ||
24 | |||
25 | if (table == RIO_GLOBAL_TABLE) { | ||
26 | rio_mport_write_config_32(mport, destid, hopcount, | ||
27 | RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid); | ||
28 | |||
29 | rio_mport_read_config_32(mport, destid, hopcount, | ||
30 | RIO_STD_RTE_CONF_PORT_SEL_CSR, &result); | ||
31 | |||
32 | result = (0xffffff00 & result) | (u32)route_port; | ||
33 | rio_mport_write_config_32(mport, destid, hopcount, | ||
34 | RIO_STD_RTE_CONF_PORT_SEL_CSR, result); | ||
35 | } | ||
36 | |||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static int | ||
41 | idtcps_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, | ||
42 | u16 table, u16 route_destid, u8 *route_port) | ||
43 | { | ||
44 | u32 result; | ||
45 | |||
46 | if (table == RIO_GLOBAL_TABLE) { | ||
47 | rio_mport_write_config_32(mport, destid, hopcount, | ||
48 | RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid); | ||
49 | |||
50 | rio_mport_read_config_32(mport, destid, hopcount, | ||
51 | RIO_STD_RTE_CONF_PORT_SEL_CSR, &result); | ||
52 | |||
53 | if (CPS_NO_ROUTE == (u8)result) | ||
54 | result = RIO_INVALID_ROUTE; | ||
55 | |||
56 | *route_port = (u8)result; | ||
57 | } | ||
58 | |||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | static int | ||
63 | idtcps_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, | ||
64 | u16 table) | ||
65 | { | ||
66 | u32 i; | ||
67 | |||
68 | if (table == RIO_GLOBAL_TABLE) { | ||
69 | for (i = 0x80000000; i <= 0x800000ff;) { | ||
70 | rio_mport_write_config_32(mport, destid, hopcount, | ||
71 | RIO_STD_RTE_CONF_DESTID_SEL_CSR, i); | ||
72 | rio_mport_write_config_32(mport, destid, hopcount, | ||
73 | RIO_STD_RTE_CONF_PORT_SEL_CSR, | ||
74 | (RIO_INVALID_ROUTE << 24) | | ||
75 | (RIO_INVALID_ROUTE << 16) | | ||
76 | (RIO_INVALID_ROUTE << 8) | RIO_INVALID_ROUTE); | ||
77 | i += 4; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS6Q, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); | ||
85 | DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS8, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); | ||
86 | DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS10Q, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); | ||
87 | DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS12, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); | ||
88 | DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS16, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); | ||
89 | DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDT70K200, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table); | ||