]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/rapidio/switches/idtcps.c
rapidio: modify initialization of switch operations
[karo-tx-linux.git] / drivers / rapidio / switches / idtcps.c
1 /*
2  * IDT CPS RapidIO switches support
3  *
4  * Copyright 2009-2010 Integrated Device Technology, Inc.
5  * Alexandre Bounine <alexandre.bounine@idt.com>
6  *
7  * This program is free software; you can redistribute  it and/or modify it
8  * under  the terms of  the GNU General  Public License as published by the
9  * Free Software Foundation;  either version 2 of the  License, or (at your
10  * option) any later version.
11  */
12
13 #include <linux/rio.h>
14 #include <linux/rio_drv.h>
15 #include <linux/rio_ids.h>
16 #include "../rio.h"
17
18 #define CPS_NO_ROUTE 0xdf
19
20 static int
21 idtcps_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
22                        u16 table, u16 route_destid, u8 route_port)
23 {
24         u32 result;
25
26         if (table == RIO_GLOBAL_TABLE) {
27                 rio_mport_write_config_32(mport, destid, hopcount,
28                                 RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);
29
30                 rio_mport_read_config_32(mport, destid, hopcount,
31                                 RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);
32
33                 result = (0xffffff00 & result) | (u32)route_port;
34                 rio_mport_write_config_32(mport, destid, hopcount,
35                                 RIO_STD_RTE_CONF_PORT_SEL_CSR, result);
36         }
37
38         return 0;
39 }
40
41 static int
42 idtcps_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
43                        u16 table, u16 route_destid, u8 *route_port)
44 {
45         u32 result;
46
47         if (table == RIO_GLOBAL_TABLE) {
48                 rio_mport_write_config_32(mport, destid, hopcount,
49                                 RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);
50
51                 rio_mport_read_config_32(mport, destid, hopcount,
52                                 RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);
53
54                 if (CPS_NO_ROUTE == (u8)result)
55                         result = RIO_INVALID_ROUTE;
56
57                 *route_port = (u8)result;
58         }
59
60         return 0;
61 }
62
63 static int
64 idtcps_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
65                        u16 table)
66 {
67         u32 i;
68
69         if (table == RIO_GLOBAL_TABLE) {
70                 for (i = 0x80000000; i <= 0x800000ff;) {
71                         rio_mport_write_config_32(mport, destid, hopcount,
72                                 RIO_STD_RTE_CONF_DESTID_SEL_CSR, i);
73                         rio_mport_write_config_32(mport, destid, hopcount,
74                                 RIO_STD_RTE_CONF_PORT_SEL_CSR,
75                                 (RIO_INVALID_ROUTE << 24) |
76                                 (RIO_INVALID_ROUTE << 16) |
77                                 (RIO_INVALID_ROUTE << 8) | RIO_INVALID_ROUTE);
78                         i += 4;
79                 }
80         }
81
82         return 0;
83 }
84
85 static int idtcps_switch_init(struct rio_dev *rdev, int do_enum)
86 {
87         pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
88         rdev->rswitch->add_entry = idtcps_route_add_entry;
89         rdev->rswitch->get_entry = idtcps_route_get_entry;
90         rdev->rswitch->clr_table = idtcps_route_clr_table;
91         rdev->rswitch->em_init = NULL;
92         rdev->rswitch->em_handle = NULL;
93
94         return 0;
95 }
96
97 DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS6Q, idtcps_switch_init);
98 DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS8, idtcps_switch_init);
99 DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS10Q, idtcps_switch_init);
100 DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS12, idtcps_switch_init);
101 DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS16, idtcps_switch_init);
102 DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDT70K200, idtcps_switch_init);