aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMatt Porter <mporter@kernel.crashing.org>2005-11-07 04:00:17 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 10:53:46 -0500
commiteb188d0e857c436b5d365d5ccc629da5a06ed102 (patch)
tree1a80ceab7d2d18a672f5753d26bbd972543ce959 /drivers
parent70a50ebd9a94533964c19f918dbbd66763e3f9e5 (diff)
[PATCH] RapidIO support: core enum
Adds RapidIO enumeration/discovery. The core code implements enumeration/discovery, management of devices/resources, and interfaces for RIO drivers. Signed-off-by: Matt Porter <mporter@kernel.crashing.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/rapidio/rio-scan.c960
-rw-r--r--drivers/rapidio/switches/Makefile5
-rw-r--r--drivers/rapidio/switches/tsi500.c60
3 files changed, 1025 insertions, 0 deletions
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
new file mode 100644
index 000000000000..20e1d8f74597
--- /dev/null
+++ b/drivers/rapidio/rio-scan.c
@@ -0,0 +1,960 @@
1/*
2 * RapidIO enumeration and discovery support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
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/config.h>
14#include <linux/types.h>
15#include <linux/kernel.h>
16
17#include <linux/delay.h>
18#include <linux/init.h>
19#include <linux/rio.h>
20#include <linux/rio_drv.h>
21#include <linux/rio_ids.h>
22#include <linux/rio_regs.h>
23#include <linux/module.h>
24#include <linux/spinlock.h>
25#include <linux/timer.h>
26
27#include "rio.h"
28
29LIST_HEAD(rio_devices);
30static LIST_HEAD(rio_switches);
31
32#define RIO_ENUM_CMPL_MAGIC 0xdeadbeef
33
34static void rio_enum_timeout(unsigned long);
35
36spinlock_t rio_global_list_lock = SPIN_LOCK_UNLOCKED;
37static int next_destid = 0;
38static int next_switchid = 0;
39static int next_net = 0;
40
41static struct timer_list rio_enum_timer =
42TIMER_INITIALIZER(rio_enum_timeout, 0, 0);
43
44static int rio_mport_phys_table[] = {
45 RIO_EFB_PAR_EP_ID,
46 RIO_EFB_PAR_EP_REC_ID,
47 RIO_EFB_SER_EP_ID,
48 RIO_EFB_SER_EP_REC_ID,
49 -1,
50};
51
52static int rio_sport_phys_table[] = {
53 RIO_EFB_PAR_EP_FREE_ID,
54 RIO_EFB_SER_EP_FREE_ID,
55 -1,
56};
57
58extern struct rio_route_ops __start_rio_route_ops[];
59extern struct rio_route_ops __end_rio_route_ops[];
60
61/**
62 * rio_get_device_id - Get the base/extended device id for a device
63 * @port: RIO master port
64 * @destid: Destination ID of device
65 * @hopcount: Hopcount to device
66 *
67 * Reads the base/extended device id from a device. Returns the
68 * 8/16-bit device ID.
69 */
70static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)
71{
72 u32 result;
73
74 rio_mport_read_config_32(port, destid, hopcount, RIO_DID_CSR, &result);
75
76 return RIO_GET_DID(result);
77}
78
79/**
80 * rio_set_device_id - Set the base/extended device id for a device
81 * @port: RIO master port
82 * @destid: Destination ID of device
83 * @hopcount: Hopcount to device
84 * @did: Device ID value to be written
85 *
86 * Writes the base/extended device id from a device.
87 */
88static void
89rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did)
90{
91 rio_mport_write_config_32(port, destid, hopcount, RIO_DID_CSR,
92 RIO_SET_DID(did));
93}
94
95/**
96 * rio_local_set_device_id - Set the base/extended device id for a port
97 * @port: RIO master port
98 * @did: Device ID value to be written
99 *
100 * Writes the base/extended device id from a device.
101 */
102static void rio_local_set_device_id(struct rio_mport *port, u16 did)
103{
104 rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(did));
105}
106
107/**
108 * rio_clear_locks- Release all host locks and signal enumeration complete
109 * @port: Master port to issue transaction
110 *
111 * Marks the component tag CSR on each device with the enumeration
112 * complete flag. When complete, it then release the host locks on
113 * each device. Returns 0 on success or %-EINVAL on failure.
114 */
115static int rio_clear_locks(struct rio_mport *port)
116{
117 struct rio_dev *rdev;
118 u32 result;
119 int ret = 0;
120
121 /* Write component tag CSR magic complete value */
122 rio_local_write_config_32(port, RIO_COMPONENT_TAG_CSR,
123 RIO_ENUM_CMPL_MAGIC);
124 list_for_each_entry(rdev, &rio_devices, global_list)
125 rio_write_config_32(rdev, RIO_COMPONENT_TAG_CSR,
126 RIO_ENUM_CMPL_MAGIC);
127
128 /* Release host device id locks */
129 rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR,
130 port->host_deviceid);
131 rio_local_read_config_32(port, RIO_HOST_DID_LOCK_CSR, &result);
132 if ((result & 0xffff) != 0xffff) {
133 printk(KERN_INFO
134 "RIO: badness when releasing host lock on master port, result %8.8x\n",
135 result);
136 ret = -EINVAL;
137 }
138 list_for_each_entry(rdev, &rio_devices, global_list) {
139 rio_write_config_32(rdev, RIO_HOST_DID_LOCK_CSR,
140 port->host_deviceid);
141 rio_read_config_32(rdev, RIO_HOST_DID_LOCK_CSR, &result);
142 if ((result & 0xffff) != 0xffff) {
143 printk(KERN_INFO
144 "RIO: badness when releasing host lock on vid %4.4x did %4.4x\n",
145 rdev->vid, rdev->did);
146 ret = -EINVAL;
147 }
148 }
149
150 return ret;
151}
152
153/**
154 * rio_enum_host- Set host lock and initialize host destination ID
155 * @port: Master port to issue transaction
156 *
157 * Sets the local host master port lock and destination ID register
158 * with the host device ID value. The host device ID value is provided
159 * by the platform. Returns %0 on success or %-1 on failure.
160 */
161static int rio_enum_host(struct rio_mport *port)
162{
163 u32 result;
164
165 /* Set master port host device id lock */
166 rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR,
167 port->host_deviceid);
168
169 rio_local_read_config_32(port, RIO_HOST_DID_LOCK_CSR, &result);
170 if ((result & 0xffff) != port->host_deviceid)
171 return -1;
172
173 /* Set master port destid and init destid ctr */
174 rio_local_set_device_id(port, port->host_deviceid);
175
176 if (next_destid == port->host_deviceid)
177 next_destid++;
178
179 return 0;
180}
181
182/**
183 * rio_device_has_destid- Test if a device contains a destination ID register
184 * @port: Master port to issue transaction
185 * @src_ops: RIO device source operations
186 * @dst_ops: RIO device destination operations
187 *
188 * Checks the provided @src_ops and @dst_ops for the necessary transaction
189 * capabilities that indicate whether or not a device will implement a
190 * destination ID register. Returns 1 if true or 0 if false.
191 */
192static int rio_device_has_destid(struct rio_mport *port, int src_ops,
193 int dst_ops)
194{
195 if (((src_ops & RIO_SRC_OPS_READ) ||
196 (src_ops & RIO_SRC_OPS_WRITE) ||
197 (src_ops & RIO_SRC_OPS_ATOMIC_TST_SWP) ||
198 (src_ops & RIO_SRC_OPS_ATOMIC_INC) ||
199 (src_ops & RIO_SRC_OPS_ATOMIC_DEC) ||
200 (src_ops & RIO_SRC_OPS_ATOMIC_SET) ||
201 (src_ops & RIO_SRC_OPS_ATOMIC_CLR)) &&
202 ((dst_ops & RIO_DST_OPS_READ) ||
203 (dst_ops & RIO_DST_OPS_WRITE) ||
204 (dst_ops & RIO_DST_OPS_ATOMIC_TST_SWP) ||
205 (dst_ops & RIO_DST_OPS_ATOMIC_INC) ||
206 (dst_ops & RIO_DST_OPS_ATOMIC_DEC) ||
207 (dst_ops & RIO_DST_OPS_ATOMIC_SET) ||
208 (dst_ops & RIO_DST_OPS_ATOMIC_CLR))) {
209 return 1;
210 } else
211 return 0;
212}
213
214/**
215 * rio_release_dev- Frees a RIO device struct
216 * @dev: LDM device associated with a RIO device struct
217 *
218 * Gets the RIO device struct associated a RIO device struct.
219 * The RIO device struct is freed.
220 */
221static void rio_release_dev(struct device *dev)
222{
223 struct rio_dev *rdev;
224
225 rdev = to_rio_dev(dev);
226 kfree(rdev);
227}
228
229/**
230 * rio_is_switch- Tests if a RIO device has switch capabilities
231 * @rdev: RIO device
232 *
233 * Gets the RIO device Processing Element Features register
234 * contents and tests for switch capabilities. Returns 1 if
235 * the device is a switch or 0 if it is not a switch.
236 * The RIO device struct is freed.
237 */
238static int rio_is_switch(struct rio_dev *rdev)
239{
240 if (rdev->pef & RIO_PEF_SWITCH)
241 return 1;
242 return 0;
243}
244
245/**
246 * rio_route_set_ops- Sets routing operations for a particular vendor switch
247 * @rdev: RIO device
248 *
249 * Searches the RIO route ops table for known switch types. If the vid
250 * and did match a switch table entry, then set the add_entry() and
251 * get_entry() ops to the table entry values.
252 */
253static void rio_route_set_ops(struct rio_dev *rdev)
254{
255 struct rio_route_ops *cur = __start_rio_route_ops;
256 struct rio_route_ops *end = __end_rio_route_ops;
257
258 while (cur < end) {
259 if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
260 pr_debug("RIO: adding routing ops for %s\n", rio_name(rdev));
261 rdev->rswitch->add_entry = cur->add_hook;
262 rdev->rswitch->get_entry = cur->get_hook;
263 }
264 cur++;
265 }
266
267 if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
268 printk(KERN_ERR "RIO: missing routing ops for %s\n",
269 rio_name(rdev));
270}
271
272/**
273 * rio_add_device- Adds a RIO device to the device model
274 * @rdev: RIO device
275 *
276 * Adds the RIO device to the global device list and adds the RIO
277 * device to the RIO device list. Creates the generic sysfs nodes
278 * for an RIO device.
279 */
280static void __devinit rio_add_device(struct rio_dev *rdev)
281{
282 device_add(&rdev->dev);
283
284 spin_lock(&rio_global_list_lock);
285 list_add_tail(&rdev->global_list, &rio_devices);
286 spin_unlock(&rio_global_list_lock);
287
288 rio_create_sysfs_dev_files(rdev);
289}
290
291/**
292 * rio_setup_device- Allocates and sets up a RIO device
293 * @net: RIO network
294 * @port: Master port to send transactions
295 * @destid: Current destination ID
296 * @hopcount: Current hopcount
297 * @do_enum: Enumeration/Discovery mode flag
298 *
299 * Allocates a RIO device and configures fields based on configuration
300 * space contents. If device has a destination ID register, a destination
301 * ID is either assigned in enumeration mode or read from configuration
302 * space in discovery mode. If the device has switch capabilities, then
303 * a switch is allocated and configured appropriately. Returns a pointer
304 * to a RIO device on success or NULL on failure.
305 *
306 */
307static struct rio_dev *rio_setup_device(struct rio_net *net,
308 struct rio_mport *port, u16 destid,
309 u8 hopcount, int do_enum)
310{
311 struct rio_dev *rdev;
312 struct rio_switch *rswitch;
313 int result, rdid;
314
315 rdev = kmalloc(sizeof(struct rio_dev), GFP_KERNEL);
316 if (!rdev)
317 goto out;
318
319 memset(rdev, 0, sizeof(struct rio_dev));
320 rdev->net = net;
321 rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_ID_CAR,
322 &result);
323 rdev->did = result >> 16;
324 rdev->vid = result & 0xffff;
325 rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_INFO_CAR,
326 &rdev->device_rev);
327 rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_ID_CAR,
328 &result);
329 rdev->asm_did = result >> 16;
330 rdev->asm_vid = result & 0xffff;
331 rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_INFO_CAR,
332 &result);
333 rdev->asm_rev = result >> 16;
334 rio_mport_read_config_32(port, destid, hopcount, RIO_PEF_CAR,
335 &rdev->pef);
336 if (rdev->pef & RIO_PEF_EXT_FEATURES)
337 rdev->efptr = result & 0xffff;
338
339 rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR,
340 &rdev->src_ops);
341 rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR,
342 &rdev->dst_ops);
343
344 if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)
345 && do_enum) {
346 rio_set_device_id(port, destid, hopcount, next_destid);
347 rdev->destid = next_destid++;
348 if (next_destid == port->host_deviceid)
349 next_destid++;
350 } else
351 rdev->destid = rio_get_device_id(port, destid, hopcount);
352
353 /* If a PE has both switch and other functions, show it as a switch */
354 if (rio_is_switch(rdev)) {
355 rio_mport_read_config_32(port, destid, hopcount,
356 RIO_SWP_INFO_CAR, &rdev->swpinfo);
357 rswitch = kmalloc(sizeof(struct rio_switch), GFP_KERNEL);
358 if (!rswitch) {
359 kfree(rdev);
360 rdev = NULL;
361 goto out;
362 }
363 rswitch->switchid = next_switchid;
364 rswitch->hopcount = hopcount;
365 rswitch->destid = 0xffff;
366 /* Initialize switch route table */
367 for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES; rdid++)
368 rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
369 rdev->rswitch = rswitch;
370 sprintf(rio_name(rdev), "%02x:s:%04x", rdev->net->id,
371 rdev->rswitch->switchid);
372 rio_route_set_ops(rdev);
373
374 list_add_tail(&rswitch->node, &rio_switches);
375
376 } else
377 sprintf(rio_name(rdev), "%02x:e:%04x", rdev->net->id,
378 rdev->destid);
379
380 rdev->dev.bus = &rio_bus_type;
381
382 device_initialize(&rdev->dev);
383 rdev->dev.release = rio_release_dev;
384 rio_dev_get(rdev);
385
386 rdev->dev.dma_mask = (u64 *) 0xffffffff;
387 rdev->dev.coherent_dma_mask = 0xffffffffULL;
388
389 if ((rdev->pef & RIO_PEF_INB_DOORBELL) &&
390 (rdev->dst_ops & RIO_DST_OPS_DOORBELL))
391 rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE],
392 0, 0xffff);
393
394 rio_add_device(rdev);
395
396 out:
397 return rdev;
398}
399
400/**
401 * rio_sport_is_active- Tests if a switch port has an active connection.
402 * @port: Master port to send transaction
403 * @destid: Associated destination ID for switch
404 * @hopcount: Hopcount to reach switch
405 * @sport: Switch port number
406 *
407 * Reads the port error status CSR for a particular switch port to
408 * determine if the port has an active link. Returns
409 * %PORT_N_ERR_STS_PORT_OK if the port is active or %0 if it is
410 * inactive.
411 */
412static int
413rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport)
414{
415 u32 result;
416 u32 ext_ftr_ptr;
417
418 int *entry = rio_sport_phys_table;
419
420 do {
421 if ((ext_ftr_ptr =
422 rio_mport_get_feature(port, 0, destid, hopcount, *entry)))
423
424 break;
425 } while (*++entry >= 0);
426
427 if (ext_ftr_ptr)
428 rio_mport_read_config_32(port, destid, hopcount,
429 ext_ftr_ptr +
430 RIO_PORT_N_ERR_STS_CSR(sport),
431 &result);
432
433 return (result & PORT_N_ERR_STS_PORT_OK);
434}
435
436/**
437 * rio_route_add_entry- Add a route entry to a switch routing table
438 * @mport: Master port to send transaction
439 * @rdev: Switch device
440 * @table: Routing table ID
441 * @route_destid: Destination ID to be routed
442 * @route_port: Port number to be routed
443 *
444 * Calls the switch specific add_entry() method to add a route entry
445 * on a switch. The route table can be specified using the @table
446 * argument if a switch has per port routing tables or the normal
447 * use is to specific all tables (or the global table) by passing
448 * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
449 * on failure.
450 */
451static int rio_route_add_entry(struct rio_mport *mport, struct rio_dev *rdev,
452 u16 table, u16 route_destid, u8 route_port)
453{
454 return rdev->rswitch->add_entry(mport, rdev->rswitch->destid,
455 rdev->rswitch->hopcount, table,
456 route_destid, route_port);
457}
458
459/**
460 * rio_route_get_entry- Read a route entry in a switch routing table
461 * @mport: Master port to send transaction
462 * @rdev: Switch device
463 * @table: Routing table ID
464 * @route_destid: Destination ID to be routed
465 * @route_port: Pointer to read port number into
466 *
467 * Calls the switch specific get_entry() method to read a route entry
468 * in a switch. The route table can be specified using the @table
469 * argument if a switch has per port routing tables or the normal
470 * use is to specific all tables (or the global table) by passing
471 * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
472 * on failure.
473 */
474static int
475rio_route_get_entry(struct rio_mport *mport, struct rio_dev *rdev, u16 table,
476 u16 route_destid, u8 * route_port)
477{
478 return rdev->rswitch->get_entry(mport, rdev->rswitch->destid,
479 rdev->rswitch->hopcount, table,
480 route_destid, route_port);
481}
482
483/**
484 * rio_get_host_deviceid_lock- Reads the Host Device ID Lock CSR on a device
485 * @port: Master port to send transaction
486 * @hopcount: Number of hops to the device
487 *
488 * Used during enumeration to read the Host Device ID Lock CSR on a
489 * RIO device. Returns the value of the lock register.
490 */
491static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
492{
493 u32 result;
494
495 rio_mport_read_config_32(port, RIO_ANY_DESTID, hopcount,
496 RIO_HOST_DID_LOCK_CSR, &result);
497
498 return (u16) (result & 0xffff);
499}
500
501/**
502 * rio_get_swpinfo_inport- Gets the ingress port number
503 * @mport: Master port to send transaction
504 * @destid: Destination ID associated with the switch
505 * @hopcount: Number of hops to the device
506 *
507 * Returns port number being used to access the switch device.
508 */
509static u8
510rio_get_swpinfo_inport(struct rio_mport *mport, u16 destid, u8 hopcount)
511{
512 u32 result;
513
514 rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
515 &result);
516
517 return (u8) (result & 0xff);
518}
519
520/**
521 * rio_get_swpinfo_tports- Gets total number of ports on the switch
522 * @mport: Master port to send transaction
523 * @destid: Destination ID associated with the switch
524 * @hopcount: Number of hops to the device
525 *
526 * Returns total numbers of ports implemented by the switch device.
527 */
528static u8 rio_get_swpinfo_tports(struct rio_mport *mport, u16 destid,
529 u8 hopcount)
530{
531 u32 result;
532
533 rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
534 &result);
535
536 return RIO_GET_TOTAL_PORTS(result);
537}
538
539/**
540 * rio_net_add_mport- Add a master port to a RIO network
541 * @net: RIO network
542 * @port: Master port to add
543 *
544 * Adds a master port to the network list of associated master
545 * ports..
546 */
547static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port)
548{
549 spin_lock(&rio_global_list_lock);
550 list_add_tail(&port->nnode, &net->mports);
551 spin_unlock(&rio_global_list_lock);
552}
553
554/**
555 * rio_enum_peer- Recursively enumerate a RIO network through a master port
556 * @net: RIO network being enumerated
557 * @port: Master port to send transactions
558 * @hopcount: Number of hops into the network
559 *
560 * Recursively enumerates a RIO network. Transactions are sent via the
561 * master port passed in @port.
562 */
563static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
564 u8 hopcount)
565{
566 int port_num;
567 int num_ports;
568 int cur_destid;
569 struct rio_dev *rdev;
570 u16 destid;
571 int tmp;
572
573 if (rio_get_host_deviceid_lock(port, hopcount) == port->host_deviceid) {
574 pr_debug("RIO: PE already discovered by this host\n");
575 /*
576 * Already discovered by this host. Add it as another
577 * master port for the current network.
578 */
579 rio_net_add_mport(net, port);
580 return 0;
581 }
582
583 /* Attempt to acquire device lock */
584 rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
585 RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
586 while ((tmp = rio_get_host_deviceid_lock(port, hopcount))
587 < port->host_deviceid) {
588 /* Delay a bit */
589 mdelay(1);
590 /* Attempt to acquire device lock again */
591 rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
592 RIO_HOST_DID_LOCK_CSR,
593 port->host_deviceid);
594 }
595
596 if (rio_get_host_deviceid_lock(port, hopcount) > port->host_deviceid) {
597 pr_debug(
598 "RIO: PE locked by a higher priority host...retreating\n");
599 return -1;
600 }
601
602 /* Setup new RIO device */
603 if ((rdev = rio_setup_device(net, port, RIO_ANY_DESTID, hopcount, 1))) {
604 /* Add device to the global and bus/net specific list. */
605 list_add_tail(&rdev->net_list, &net->devices);
606 } else
607 return -1;
608
609 if (rio_is_switch(rdev)) {
610 next_switchid++;
611
612 for (destid = 0; destid < next_destid; destid++) {
613 rio_route_add_entry(port, rdev, RIO_GLOBAL_TABLE,
614 destid, rio_get_swpinfo_inport(port,
615 RIO_ANY_DESTID,
616 hopcount));
617 rdev->rswitch->route_table[destid] =
618 rio_get_swpinfo_inport(port, RIO_ANY_DESTID,
619 hopcount);
620 }
621
622 num_ports =
623 rio_get_swpinfo_tports(port, RIO_ANY_DESTID, hopcount);
624 pr_debug(
625 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
626 rio_name(rdev), rdev->vid, rdev->did, num_ports);
627 for (port_num = 0; port_num < num_ports; port_num++) {
628 if (rio_get_swpinfo_inport
629 (port, RIO_ANY_DESTID, hopcount) == port_num)
630 continue;
631
632 cur_destid = next_destid;
633
634 if (rio_sport_is_active
635 (port, RIO_ANY_DESTID, hopcount, port_num)) {
636 pr_debug(
637 "RIO: scanning device on port %d\n",
638 port_num);
639 rio_route_add_entry(port, rdev,
640 RIO_GLOBAL_TABLE,
641 RIO_ANY_DESTID, port_num);
642
643 if (rio_enum_peer(net, port, hopcount + 1) < 0)
644 return -1;
645
646 /* Update routing tables */
647 if (next_destid > cur_destid) {
648 for (destid = cur_destid;
649 destid < next_destid; destid++) {
650 rio_route_add_entry(port, rdev,
651 RIO_GLOBAL_TABLE,
652 destid,
653 port_num);
654 rdev->rswitch->
655 route_table[destid] =
656 port_num;
657 }
658 rdev->rswitch->destid = cur_destid;
659 }
660 }
661 }
662 } else
663 pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
664 rio_name(rdev), rdev->vid, rdev->did);
665
666 return 0;
667}
668
669/**
670 * rio_enum_complete- Tests if enumeration of a network is complete
671 * @port: Master port to send transaction
672 *
673 * Tests the Component Tag CSR for presence of the magic enumeration
674 * complete flag. Return %1 if enumeration is complete or %0 if
675 * enumeration is incomplete.
676 */
677static int rio_enum_complete(struct rio_mport *port)
678{
679 u32 tag_csr;
680 int ret = 0;
681
682 rio_local_read_config_32(port, RIO_COMPONENT_TAG_CSR, &tag_csr);
683
684 if (tag_csr == RIO_ENUM_CMPL_MAGIC)
685 ret = 1;
686
687 return ret;
688}
689
690/**
691 * rio_disc_peer- Recursively discovers a RIO network through a master port
692 * @net: RIO network being discovered
693 * @port: Master port to send transactions
694 * @destid: Current destination ID in network
695 * @hopcount: Number of hops into the network
696 *
697 * Recursively discovers a RIO network. Transactions are sent via the
698 * master port passed in @port.
699 */
700static int
701rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
702 u8 hopcount)
703{
704 u8 port_num, route_port;
705 int num_ports;
706 struct rio_dev *rdev;
707 u16 ndestid;
708
709 /* Setup new RIO device */
710 if ((rdev = rio_setup_device(net, port, destid, hopcount, 0))) {
711 /* Add device to the global and bus/net specific list. */
712 list_add_tail(&rdev->net_list, &net->devices);
713 } else
714 return -1;
715
716 if (rio_is_switch(rdev)) {
717 next_switchid++;
718
719 /* Associated destid is how we accessed this switch */
720 rdev->rswitch->destid = destid;
721
722 num_ports = rio_get_swpinfo_tports(port, destid, hopcount);
723 pr_debug(
724 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
725 rio_name(rdev), rdev->vid, rdev->did, num_ports);
726 for (port_num = 0; port_num < num_ports; port_num++) {
727 if (rio_get_swpinfo_inport(port, destid, hopcount) ==
728 port_num)
729 continue;
730
731 if (rio_sport_is_active
732 (port, destid, hopcount, port_num)) {
733 pr_debug(
734 "RIO: scanning device on port %d\n",
735 port_num);
736 for (ndestid = 0; ndestid < RIO_ANY_DESTID;
737 ndestid++) {
738 rio_route_get_entry(port, rdev,
739 RIO_GLOBAL_TABLE,
740 ndestid,
741 &route_port);
742 if (route_port == port_num)
743 break;
744 }
745
746 if (rio_disc_peer
747 (net, port, ndestid, hopcount + 1) < 0)
748 return -1;
749 }
750 }
751 } else
752 pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
753 rio_name(rdev), rdev->vid, rdev->did);
754
755 return 0;
756}
757
758/**
759 * rio_mport_is_active- Tests if master port link is active
760 * @port: Master port to test
761 *
762 * Reads the port error status CSR for the master port to
763 * determine if the port has an active link. Returns
764 * %PORT_N_ERR_STS_PORT_OK if the master port is active
765 * or %0 if it is inactive.
766 */
767static int rio_mport_is_active(struct rio_mport *port)
768{
769 u32 result = 0;
770 u32 ext_ftr_ptr;
771 int *entry = rio_mport_phys_table;
772
773 do {
774 if ((ext_ftr_ptr =
775 rio_mport_get_feature(port, 1, 0, 0, *entry)))
776 break;
777 } while (*++entry >= 0);
778
779 if (ext_ftr_ptr)
780 rio_local_read_config_32(port,
781 ext_ftr_ptr +
782 RIO_PORT_N_ERR_STS_CSR(port->index),
783 &result);
784
785 return (result & PORT_N_ERR_STS_PORT_OK);
786}
787
788/**
789 * rio_alloc_net- Allocate and configure a new RIO network
790 * @port: Master port associated with the RIO network
791 *
792 * Allocates a RIO network structure, initializes per-network
793 * list heads, and adds the associated master port to the
794 * network list of associated master ports. Returns a
795 * RIO network pointer on success or %NULL on failure.
796 */
797static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port)
798{
799 struct rio_net *net;
800
801 net = kmalloc(sizeof(struct rio_net), GFP_KERNEL);
802 if (net) {
803 memset(net, 0, sizeof(struct rio_net));
804 INIT_LIST_HEAD(&net->node);
805 INIT_LIST_HEAD(&net->devices);
806 INIT_LIST_HEAD(&net->mports);
807 list_add_tail(&port->nnode, &net->mports);
808 net->hport = port;
809 net->id = next_net++;
810 }
811 return net;
812}
813
814/**
815 * rio_enum_mport- Start enumeration through a master port
816 * @mport: Master port to send transactions
817 *
818 * Starts the enumeration process. If somebody has enumerated our
819 * master port device, then give up. If not and we have an active
820 * link, then start recursive peer enumeration. Returns %0 if
821 * enumeration succeeds or %-EBUSY if enumeration fails.
822 */
823int rio_enum_mport(struct rio_mport *mport)
824{
825 struct rio_net *net = NULL;
826 int rc = 0;
827
828 printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id,
829 mport->name);
830 /* If somebody else enumerated our master port device, bail. */
831 if (rio_enum_host(mport) < 0) {
832 printk(KERN_INFO
833 "RIO: master port %d device has been enumerated by a remote host\n",
834 mport->id);
835 rc = -EBUSY;
836 goto out;
837 }
838
839 /* If master port has an active link, allocate net and enum peers */
840 if (rio_mport_is_active(mport)) {
841 if (!(net = rio_alloc_net(mport))) {
842 printk(KERN_ERR "RIO: failed to allocate new net\n");
843 rc = -ENOMEM;
844 goto out;
845 }
846 if (rio_enum_peer(net, mport, 0) < 0) {
847 /* A higher priority host won enumeration, bail. */
848 printk(KERN_INFO
849 "RIO: master port %d device has lost enumeration to a remote host\n",
850 mport->id);
851 rio_clear_locks(mport);
852 rc = -EBUSY;
853 goto out;
854 }
855 rio_clear_locks(mport);
856 } else {
857 printk(KERN_INFO "RIO: master port %d link inactive\n",
858 mport->id);
859 rc = -EINVAL;
860 }
861
862 out:
863 return rc;
864}
865
866/**
867 * rio_build_route_tables- Generate route tables from switch route entries
868 *
869 * For each switch device, generate a route table by copying existing
870 * route entries from the switch.
871 */
872static void rio_build_route_tables(void)
873{
874 struct rio_dev *rdev;
875 int i;
876 u8 sport;
877
878 list_for_each_entry(rdev, &rio_devices, global_list)
879 if (rio_is_switch(rdev))
880 for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
881 if (rio_route_get_entry
882 (rdev->net->hport, rdev, RIO_GLOBAL_TABLE, i,
883 &sport) < 0)
884 continue;
885 rdev->rswitch->route_table[i] = sport;
886 }
887}
888
889/**
890 * rio_enum_timeout- Signal that enumeration timed out
891 * @data: Address of timeout flag.
892 *
893 * When the enumeration complete timer expires, set a flag that
894 * signals to the discovery process that enumeration did not
895 * complete in a sane amount of time.
896 */
897static void rio_enum_timeout(unsigned long data)
898{
899 /* Enumeration timed out, set flag */
900 *(int *)data = 1;
901}
902
903/**
904 * rio_disc_mport- Start discovery through a master port
905 * @mport: Master port to send transactions
906 *
907 * Starts the discovery process. If we have an active link,
908 * then wait for the signal that enumeration is complete.
909 * When enumeration completion is signaled, start recursive
910 * peer discovery. Returns %0 if discovery succeeds or %-EBUSY
911 * on failure.
912 */
913int rio_disc_mport(struct rio_mport *mport)
914{
915 struct rio_net *net = NULL;
916 int enum_timeout_flag = 0;
917
918 printk(KERN_INFO "RIO: discover master port %d, %s\n", mport->id,
919 mport->name);
920
921 /* If master port has an active link, allocate net and discover peers */
922 if (rio_mport_is_active(mport)) {
923 if (!(net = rio_alloc_net(mport))) {
924 printk(KERN_ERR "RIO: Failed to allocate new net\n");
925 goto bail;
926 }
927
928 pr_debug("RIO: wait for enumeration complete...");
929
930 rio_enum_timer.expires =
931 jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ;
932 rio_enum_timer.data = (unsigned long)&enum_timeout_flag;
933 add_timer(&rio_enum_timer);
934 while (!rio_enum_complete(mport)) {
935 mdelay(1);
936 if (enum_timeout_flag) {
937 del_timer_sync(&rio_enum_timer);
938 goto timeout;
939 }
940 }
941 del_timer_sync(&rio_enum_timer);
942
943 pr_debug("done\n");
944 if (rio_disc_peer(net, mport, RIO_ANY_DESTID, 0) < 0) {
945 printk(KERN_INFO
946 "RIO: master port %d device has failed discovery\n",
947 mport->id);
948 goto bail;
949 }
950
951 rio_build_route_tables();
952 }
953
954 return 0;
955
956 timeout:
957 pr_debug("timeout\n");
958 bail:
959 return -EBUSY;
960}
diff --git a/drivers/rapidio/switches/Makefile b/drivers/rapidio/switches/Makefile
new file mode 100644
index 000000000000..b924f8301761
--- /dev/null
+++ b/drivers/rapidio/switches/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for RIO switches
3#
4
5obj-$(CONFIG_RAPIDIO) += tsi500.o
diff --git a/drivers/rapidio/switches/tsi500.c b/drivers/rapidio/switches/tsi500.c
new file mode 100644
index 000000000000..c77c23bd9840
--- /dev/null
+++ b/drivers/rapidio/switches/tsi500.c
@@ -0,0 +1,60 @@
1/*
2 * RapidIO Tsi500 switch support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
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
18static int
19tsi500_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port)
20{
21 int i;
22 u32 offset = 0x10000 + 0xa00 + ((route_destid / 2)&~0x3);
23 u32 result;
24
25 if (table == 0xff) {
26 rio_mport_read_config_32(mport, destid, hopcount, offset, &result);
27 result &= ~(0xf << (4*(route_destid & 0x7)));
28 for (i=0;i<4;i++)
29 rio_mport_write_config_32(mport, destid, hopcount, offset + (0x20000*i), result | (route_port << (4*(route_destid & 0x7))));
30 }
31 else {
32 rio_mport_read_config_32(mport, destid, hopcount, offset + (0x20000*table), &result);
33 result &= ~(0xf << (4*(route_destid & 0x7)));
34 rio_mport_write_config_32(mport, destid, hopcount, offset + (0x20000*table), result | (route_port << (4*(route_destid & 0x7))));
35 }
36
37 return 0;
38}
39
40static int
41tsi500_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 *route_port)
42{
43 int ret = 0;
44 u32 offset = 0x10000 + 0xa00 + ((route_destid / 2)&~0x3);
45 u32 result;
46
47 if (table == 0xff)
48 rio_mport_read_config_32(mport, destid, hopcount, offset, &result);
49 else
50 rio_mport_read_config_32(mport, destid, hopcount, offset + (0x20000*table), &result);
51
52 result &= 0xf << (4*(route_destid & 0x7));
53 *route_port = result >> (4*(route_destid & 0x7));
54 if (*route_port > 3)
55 ret = -1;
56
57 return ret;
58}
59
60DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_route_add_entry, tsi500_route_get_entry);