Root/
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/types.h> |
14 | #include <linux/kernel.h> |
15 | |
16 | #include <linux/delay.h> |
17 | #include <linux/dma-mapping.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 | #include <linux/jiffies.h> |
27 | #include <linux/slab.h> |
28 | |
29 | #include "rio.h" |
30 | |
31 | LIST_HEAD(rio_devices); |
32 | static LIST_HEAD(rio_switches); |
33 | |
34 | #define RIO_ENUM_CMPL_MAGIC 0xdeadbeef |
35 | |
36 | static void rio_enum_timeout(unsigned long); |
37 | |
38 | DEFINE_SPINLOCK(rio_global_list_lock); |
39 | |
40 | static int next_destid = 0; |
41 | static int next_switchid = 0; |
42 | static int next_net = 0; |
43 | |
44 | static struct timer_list rio_enum_timer = |
45 | TIMER_INITIALIZER(rio_enum_timeout, 0, 0); |
46 | |
47 | static int rio_mport_phys_table[] = { |
48 | RIO_EFB_PAR_EP_ID, |
49 | RIO_EFB_PAR_EP_REC_ID, |
50 | RIO_EFB_SER_EP_ID, |
51 | RIO_EFB_SER_EP_REC_ID, |
52 | -1, |
53 | }; |
54 | |
55 | static int rio_sport_phys_table[] = { |
56 | RIO_EFB_PAR_EP_FREE_ID, |
57 | RIO_EFB_SER_EP_FREE_ID, |
58 | -1, |
59 | }; |
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 | */ |
70 | static 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(port->sys_size, 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 | */ |
88 | static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did) |
89 | { |
90 | rio_mport_write_config_32(port, destid, hopcount, RIO_DID_CSR, |
91 | RIO_SET_DID(port->sys_size, did)); |
92 | } |
93 | |
94 | /** |
95 | * rio_local_set_device_id - Set the base/extended device id for a port |
96 | * @port: RIO master port |
97 | * @did: Device ID value to be written |
98 | * |
99 | * Writes the base/extended device id from a device. |
100 | */ |
101 | static void rio_local_set_device_id(struct rio_mport *port, u16 did) |
102 | { |
103 | rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(port->sys_size, |
104 | 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 | */ |
115 | static 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 | */ |
161 | static 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 | */ |
192 | static int rio_device_has_destid(struct rio_mport *port, int src_ops, |
193 | int dst_ops) |
194 | { |
195 | u32 mask = RIO_OPS_READ | RIO_OPS_WRITE | RIO_OPS_ATOMIC_TST_SWP | RIO_OPS_ATOMIC_INC | RIO_OPS_ATOMIC_DEC | RIO_OPS_ATOMIC_SET | RIO_OPS_ATOMIC_CLR; |
196 | |
197 | return !!((src_ops | dst_ops) & mask); |
198 | } |
199 | |
200 | /** |
201 | * rio_release_dev- Frees a RIO device struct |
202 | * @dev: LDM device associated with a RIO device struct |
203 | * |
204 | * Gets the RIO device struct associated a RIO device struct. |
205 | * The RIO device struct is freed. |
206 | */ |
207 | static void rio_release_dev(struct device *dev) |
208 | { |
209 | struct rio_dev *rdev; |
210 | |
211 | rdev = to_rio_dev(dev); |
212 | kfree(rdev); |
213 | } |
214 | |
215 | /** |
216 | * rio_is_switch- Tests if a RIO device has switch capabilities |
217 | * @rdev: RIO device |
218 | * |
219 | * Gets the RIO device Processing Element Features register |
220 | * contents and tests for switch capabilities. Returns 1 if |
221 | * the device is a switch or 0 if it is not a switch. |
222 | * The RIO device struct is freed. |
223 | */ |
224 | static int rio_is_switch(struct rio_dev *rdev) |
225 | { |
226 | if (rdev->pef & RIO_PEF_SWITCH) |
227 | return 1; |
228 | return 0; |
229 | } |
230 | |
231 | /** |
232 | * rio_route_set_ops- Sets routing operations for a particular vendor switch |
233 | * @rdev: RIO device |
234 | * |
235 | * Searches the RIO route ops table for known switch types. If the vid |
236 | * and did match a switch table entry, then set the add_entry() and |
237 | * get_entry() ops to the table entry values. |
238 | */ |
239 | static void rio_route_set_ops(struct rio_dev *rdev) |
240 | { |
241 | struct rio_route_ops *cur = __start_rio_route_ops; |
242 | struct rio_route_ops *end = __end_rio_route_ops; |
243 | |
244 | while (cur < end) { |
245 | if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) { |
246 | pr_debug("RIO: adding routing ops for %s\n", rio_name(rdev)); |
247 | rdev->rswitch->add_entry = cur->add_hook; |
248 | rdev->rswitch->get_entry = cur->get_hook; |
249 | } |
250 | cur++; |
251 | } |
252 | |
253 | if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry) |
254 | printk(KERN_ERR "RIO: missing routing ops for %s\n", |
255 | rio_name(rdev)); |
256 | } |
257 | |
258 | /** |
259 | * rio_add_device- Adds a RIO device to the device model |
260 | * @rdev: RIO device |
261 | * |
262 | * Adds the RIO device to the global device list and adds the RIO |
263 | * device to the RIO device list. Creates the generic sysfs nodes |
264 | * for an RIO device. |
265 | */ |
266 | static int __devinit rio_add_device(struct rio_dev *rdev) |
267 | { |
268 | int err; |
269 | |
270 | err = device_add(&rdev->dev); |
271 | if (err) |
272 | return err; |
273 | |
274 | spin_lock(&rio_global_list_lock); |
275 | list_add_tail(&rdev->global_list, &rio_devices); |
276 | spin_unlock(&rio_global_list_lock); |
277 | |
278 | rio_create_sysfs_dev_files(rdev); |
279 | |
280 | return 0; |
281 | } |
282 | |
283 | /** |
284 | * rio_setup_device- Allocates and sets up a RIO device |
285 | * @net: RIO network |
286 | * @port: Master port to send transactions |
287 | * @destid: Current destination ID |
288 | * @hopcount: Current hopcount |
289 | * @do_enum: Enumeration/Discovery mode flag |
290 | * |
291 | * Allocates a RIO device and configures fields based on configuration |
292 | * space contents. If device has a destination ID register, a destination |
293 | * ID is either assigned in enumeration mode or read from configuration |
294 | * space in discovery mode. If the device has switch capabilities, then |
295 | * a switch is allocated and configured appropriately. Returns a pointer |
296 | * to a RIO device on success or NULL on failure. |
297 | * |
298 | */ |
299 | static struct rio_dev __devinit *rio_setup_device(struct rio_net *net, |
300 | struct rio_mport *port, u16 destid, |
301 | u8 hopcount, int do_enum) |
302 | { |
303 | int ret = 0; |
304 | struct rio_dev *rdev; |
305 | struct rio_switch *rswitch = NULL; |
306 | int result, rdid; |
307 | |
308 | rdev = kzalloc(sizeof(struct rio_dev), GFP_KERNEL); |
309 | if (!rdev) |
310 | return NULL; |
311 | |
312 | rdev->net = net; |
313 | rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_ID_CAR, |
314 | &result); |
315 | rdev->did = result >> 16; |
316 | rdev->vid = result & 0xffff; |
317 | rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_INFO_CAR, |
318 | &rdev->device_rev); |
319 | rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_ID_CAR, |
320 | &result); |
321 | rdev->asm_did = result >> 16; |
322 | rdev->asm_vid = result & 0xffff; |
323 | rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_INFO_CAR, |
324 | &result); |
325 | rdev->asm_rev = result >> 16; |
326 | rio_mport_read_config_32(port, destid, hopcount, RIO_PEF_CAR, |
327 | &rdev->pef); |
328 | if (rdev->pef & RIO_PEF_EXT_FEATURES) |
329 | rdev->efptr = result & 0xffff; |
330 | |
331 | rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR, |
332 | &rdev->src_ops); |
333 | rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR, |
334 | &rdev->dst_ops); |
335 | |
336 | if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) { |
337 | if (do_enum) { |
338 | rio_set_device_id(port, destid, hopcount, next_destid); |
339 | rdev->destid = next_destid++; |
340 | if (next_destid == port->host_deviceid) |
341 | next_destid++; |
342 | } else |
343 | rdev->destid = rio_get_device_id(port, destid, hopcount); |
344 | } else |
345 | /* Switch device has an associated destID */ |
346 | rdev->destid = RIO_INVALID_DESTID; |
347 | |
348 | /* If a PE has both switch and other functions, show it as a switch */ |
349 | if (rio_is_switch(rdev)) { |
350 | rio_mport_read_config_32(port, destid, hopcount, |
351 | RIO_SWP_INFO_CAR, &rdev->swpinfo); |
352 | rswitch = kmalloc(sizeof(struct rio_switch), GFP_KERNEL); |
353 | if (!rswitch) |
354 | goto cleanup; |
355 | rswitch->switchid = next_switchid; |
356 | rswitch->hopcount = hopcount; |
357 | rswitch->destid = destid; |
358 | rswitch->route_table = kzalloc(sizeof(u8)* |
359 | RIO_MAX_ROUTE_ENTRIES(port->sys_size), |
360 | GFP_KERNEL); |
361 | if (!rswitch->route_table) |
362 | goto cleanup; |
363 | /* Initialize switch route table */ |
364 | for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES(port->sys_size); |
365 | rdid++) |
366 | rswitch->route_table[rdid] = RIO_INVALID_ROUTE; |
367 | rdev->rswitch = rswitch; |
368 | dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id, |
369 | rdev->rswitch->switchid); |
370 | rio_route_set_ops(rdev); |
371 | |
372 | list_add_tail(&rswitch->node, &rio_switches); |
373 | |
374 | } else |
375 | dev_set_name(&rdev->dev, "%02x:e:%04x", rdev->net->id, |
376 | rdev->destid); |
377 | |
378 | rdev->dev.bus = &rio_bus_type; |
379 | |
380 | device_initialize(&rdev->dev); |
381 | rdev->dev.release = rio_release_dev; |
382 | rio_dev_get(rdev); |
383 | |
384 | rdev->dma_mask = DMA_BIT_MASK(32); |
385 | rdev->dev.dma_mask = &rdev->dma_mask; |
386 | rdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); |
387 | |
388 | if ((rdev->pef & RIO_PEF_INB_DOORBELL) && |
389 | (rdev->dst_ops & RIO_DST_OPS_DOORBELL)) |
390 | rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE], |
391 | 0, 0xffff); |
392 | |
393 | ret = rio_add_device(rdev); |
394 | if (ret) |
395 | goto cleanup; |
396 | |
397 | return rdev; |
398 | |
399 | cleanup: |
400 | if (rswitch) { |
401 | kfree(rswitch->route_table); |
402 | kfree(rswitch); |
403 | } |
404 | kfree(rdev); |
405 | return NULL; |
406 | } |
407 | |
408 | /** |
409 | * rio_sport_is_active- Tests if a switch port has an active connection. |
410 | * @port: Master port to send transaction |
411 | * @destid: Associated destination ID for switch |
412 | * @hopcount: Hopcount to reach switch |
413 | * @sport: Switch port number |
414 | * |
415 | * Reads the port error status CSR for a particular switch port to |
416 | * determine if the port has an active link. Returns |
417 | * %PORT_N_ERR_STS_PORT_OK if the port is active or %0 if it is |
418 | * inactive. |
419 | */ |
420 | static int |
421 | rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport) |
422 | { |
423 | u32 result; |
424 | u32 ext_ftr_ptr; |
425 | |
426 | int *entry = rio_sport_phys_table; |
427 | |
428 | do { |
429 | if ((ext_ftr_ptr = |
430 | rio_mport_get_feature(port, 0, destid, hopcount, *entry))) |
431 | |
432 | break; |
433 | } while (*++entry >= 0); |
434 | |
435 | if (ext_ftr_ptr) |
436 | rio_mport_read_config_32(port, destid, hopcount, |
437 | ext_ftr_ptr + |
438 | RIO_PORT_N_ERR_STS_CSR(sport), |
439 | &result); |
440 | |
441 | return (result & PORT_N_ERR_STS_PORT_OK); |
442 | } |
443 | |
444 | /** |
445 | * rio_route_add_entry- Add a route entry to a switch routing table |
446 | * @mport: Master port to send transaction |
447 | * @rswitch: Switch device |
448 | * @table: Routing table ID |
449 | * @route_destid: Destination ID to be routed |
450 | * @route_port: Port number to be routed |
451 | * |
452 | * Calls the switch specific add_entry() method to add a route entry |
453 | * on a switch. The route table can be specified using the @table |
454 | * argument if a switch has per port routing tables or the normal |
455 | * use is to specific all tables (or the global table) by passing |
456 | * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL |
457 | * on failure. |
458 | */ |
459 | static int rio_route_add_entry(struct rio_mport *mport, struct rio_switch *rswitch, |
460 | u16 table, u16 route_destid, u8 route_port) |
461 | { |
462 | return rswitch->add_entry(mport, rswitch->destid, |
463 | rswitch->hopcount, table, |
464 | route_destid, route_port); |
465 | } |
466 | |
467 | /** |
468 | * rio_route_get_entry- Read a route entry in a switch routing table |
469 | * @mport: Master port to send transaction |
470 | * @rswitch: Switch device |
471 | * @table: Routing table ID |
472 | * @route_destid: Destination ID to be routed |
473 | * @route_port: Pointer to read port number into |
474 | * |
475 | * Calls the switch specific get_entry() method to read a route entry |
476 | * in a switch. The route table can be specified using the @table |
477 | * argument if a switch has per port routing tables or the normal |
478 | * use is to specific all tables (or the global table) by passing |
479 | * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL |
480 | * on failure. |
481 | */ |
482 | static int |
483 | rio_route_get_entry(struct rio_mport *mport, struct rio_switch *rswitch, u16 table, |
484 | u16 route_destid, u8 * route_port) |
485 | { |
486 | return rswitch->get_entry(mport, rswitch->destid, |
487 | rswitch->hopcount, table, |
488 | route_destid, route_port); |
489 | } |
490 | |
491 | /** |
492 | * rio_get_host_deviceid_lock- Reads the Host Device ID Lock CSR on a device |
493 | * @port: Master port to send transaction |
494 | * @hopcount: Number of hops to the device |
495 | * |
496 | * Used during enumeration to read the Host Device ID Lock CSR on a |
497 | * RIO device. Returns the value of the lock register. |
498 | */ |
499 | static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount) |
500 | { |
501 | u32 result; |
502 | |
503 | rio_mport_read_config_32(port, RIO_ANY_DESTID(port->sys_size), hopcount, |
504 | RIO_HOST_DID_LOCK_CSR, &result); |
505 | |
506 | return (u16) (result & 0xffff); |
507 | } |
508 | |
509 | /** |
510 | * rio_get_swpinfo_inport- Gets the ingress port number |
511 | * @mport: Master port to send transaction |
512 | * @destid: Destination ID associated with the switch |
513 | * @hopcount: Number of hops to the device |
514 | * |
515 | * Returns port number being used to access the switch device. |
516 | */ |
517 | static u8 |
518 | rio_get_swpinfo_inport(struct rio_mport *mport, u16 destid, u8 hopcount) |
519 | { |
520 | u32 result; |
521 | |
522 | rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR, |
523 | &result); |
524 | |
525 | return (u8) (result & 0xff); |
526 | } |
527 | |
528 | /** |
529 | * rio_get_swpinfo_tports- Gets total number of ports on the switch |
530 | * @mport: Master port to send transaction |
531 | * @destid: Destination ID associated with the switch |
532 | * @hopcount: Number of hops to the device |
533 | * |
534 | * Returns total numbers of ports implemented by the switch device. |
535 | */ |
536 | static u8 rio_get_swpinfo_tports(struct rio_mport *mport, u16 destid, |
537 | u8 hopcount) |
538 | { |
539 | u32 result; |
540 | |
541 | rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR, |
542 | &result); |
543 | |
544 | return RIO_GET_TOTAL_PORTS(result); |
545 | } |
546 | |
547 | /** |
548 | * rio_net_add_mport- Add a master port to a RIO network |
549 | * @net: RIO network |
550 | * @port: Master port to add |
551 | * |
552 | * Adds a master port to the network list of associated master |
553 | * ports.. |
554 | */ |
555 | static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port) |
556 | { |
557 | spin_lock(&rio_global_list_lock); |
558 | list_add_tail(&port->nnode, &net->mports); |
559 | spin_unlock(&rio_global_list_lock); |
560 | } |
561 | |
562 | /** |
563 | * rio_enum_peer- Recursively enumerate a RIO network through a master port |
564 | * @net: RIO network being enumerated |
565 | * @port: Master port to send transactions |
566 | * @hopcount: Number of hops into the network |
567 | * |
568 | * Recursively enumerates a RIO network. Transactions are sent via the |
569 | * master port passed in @port. |
570 | */ |
571 | static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port, |
572 | u8 hopcount) |
573 | { |
574 | int port_num; |
575 | int num_ports; |
576 | int cur_destid; |
577 | int sw_destid; |
578 | int sw_inport; |
579 | struct rio_dev *rdev; |
580 | u16 destid; |
581 | int tmp; |
582 | |
583 | if (rio_get_host_deviceid_lock(port, hopcount) == port->host_deviceid) { |
584 | pr_debug("RIO: PE already discovered by this host\n"); |
585 | /* |
586 | * Already discovered by this host. Add it as another |
587 | * master port for the current network. |
588 | */ |
589 | rio_net_add_mport(net, port); |
590 | return 0; |
591 | } |
592 | |
593 | /* Attempt to acquire device lock */ |
594 | rio_mport_write_config_32(port, RIO_ANY_DESTID(port->sys_size), |
595 | hopcount, |
596 | RIO_HOST_DID_LOCK_CSR, port->host_deviceid); |
597 | while ((tmp = rio_get_host_deviceid_lock(port, hopcount)) |
598 | < port->host_deviceid) { |
599 | /* Delay a bit */ |
600 | mdelay(1); |
601 | /* Attempt to acquire device lock again */ |
602 | rio_mport_write_config_32(port, RIO_ANY_DESTID(port->sys_size), |
603 | hopcount, |
604 | RIO_HOST_DID_LOCK_CSR, |
605 | port->host_deviceid); |
606 | } |
607 | |
608 | if (rio_get_host_deviceid_lock(port, hopcount) > port->host_deviceid) { |
609 | pr_debug( |
610 | "RIO: PE locked by a higher priority host...retreating\n"); |
611 | return -1; |
612 | } |
613 | |
614 | /* Setup new RIO device */ |
615 | rdev = rio_setup_device(net, port, RIO_ANY_DESTID(port->sys_size), |
616 | hopcount, 1); |
617 | if (rdev) { |
618 | /* Add device to the global and bus/net specific list. */ |
619 | list_add_tail(&rdev->net_list, &net->devices); |
620 | } else |
621 | return -1; |
622 | |
623 | if (rio_is_switch(rdev)) { |
624 | next_switchid++; |
625 | sw_inport = rio_get_swpinfo_inport(port, |
626 | RIO_ANY_DESTID(port->sys_size), hopcount); |
627 | rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, |
628 | port->host_deviceid, sw_inport); |
629 | rdev->rswitch->route_table[port->host_deviceid] = sw_inport; |
630 | |
631 | for (destid = 0; destid < next_destid; destid++) { |
632 | if (destid == port->host_deviceid) |
633 | continue; |
634 | rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE, |
635 | destid, sw_inport); |
636 | rdev->rswitch->route_table[destid] = sw_inport; |
637 | } |
638 | |
639 | num_ports = |
640 | rio_get_swpinfo_tports(port, RIO_ANY_DESTID(port->sys_size), |
641 | hopcount); |
642 | pr_debug( |
643 | "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n", |
644 | rio_name(rdev), rdev->vid, rdev->did, num_ports); |
645 | sw_destid = next_destid; |
646 | for (port_num = 0; port_num < num_ports; port_num++) { |
647 | if (sw_inport == port_num) |
648 | continue; |
649 | |
650 | cur_destid = next_destid; |
651 | |
652 | if (rio_sport_is_active |
653 | (port, RIO_ANY_DESTID(port->sys_size), hopcount, |
654 | port_num)) { |
655 | pr_debug( |
656 | "RIO: scanning device on port %d\n", |
657 | port_num); |
658 | rio_route_add_entry(port, rdev->rswitch, |
659 | RIO_GLOBAL_TABLE, |
660 | RIO_ANY_DESTID(port->sys_size), |
661 | port_num); |
662 | |
663 | if (rio_enum_peer(net, port, hopcount + 1) < 0) |
664 | return -1; |
665 | |
666 | /* Update routing tables */ |
667 | if (next_destid > cur_destid) { |
668 | for (destid = cur_destid; |
669 | destid < next_destid; destid++) { |
670 | if (destid == port->host_deviceid) |
671 | continue; |
672 | rio_route_add_entry(port, rdev->rswitch, |
673 | RIO_GLOBAL_TABLE, |
674 | destid, |
675 | port_num); |
676 | rdev->rswitch-> |
677 | route_table[destid] = |
678 | port_num; |
679 | } |
680 | } |
681 | } |
682 | } |
683 | |
684 | /* Check for empty switch */ |
685 | if (next_destid == sw_destid) { |
686 | next_destid++; |
687 | if (next_destid == port->host_deviceid) |
688 | next_destid++; |
689 | } |
690 | |
691 | rdev->rswitch->destid = sw_destid; |
692 | } else |
693 | pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n", |
694 | rio_name(rdev), rdev->vid, rdev->did); |
695 | |
696 | return 0; |
697 | } |
698 | |
699 | /** |
700 | * rio_enum_complete- Tests if enumeration of a network is complete |
701 | * @port: Master port to send transaction |
702 | * |
703 | * Tests the Component Tag CSR for presence of the magic enumeration |
704 | * complete flag. Return %1 if enumeration is complete or %0 if |
705 | * enumeration is incomplete. |
706 | */ |
707 | static int rio_enum_complete(struct rio_mport *port) |
708 | { |
709 | u32 tag_csr; |
710 | int ret = 0; |
711 | |
712 | rio_local_read_config_32(port, RIO_COMPONENT_TAG_CSR, &tag_csr); |
713 | |
714 | if (tag_csr == RIO_ENUM_CMPL_MAGIC) |
715 | ret = 1; |
716 | |
717 | return ret; |
718 | } |
719 | |
720 | /** |
721 | * rio_disc_peer- Recursively discovers a RIO network through a master port |
722 | * @net: RIO network being discovered |
723 | * @port: Master port to send transactions |
724 | * @destid: Current destination ID in network |
725 | * @hopcount: Number of hops into the network |
726 | * |
727 | * Recursively discovers a RIO network. Transactions are sent via the |
728 | * master port passed in @port. |
729 | */ |
730 | static int __devinit |
731 | rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, |
732 | u8 hopcount) |
733 | { |
734 | u8 port_num, route_port; |
735 | int num_ports; |
736 | struct rio_dev *rdev; |
737 | u16 ndestid; |
738 | |
739 | /* Setup new RIO device */ |
740 | if ((rdev = rio_setup_device(net, port, destid, hopcount, 0))) { |
741 | /* Add device to the global and bus/net specific list. */ |
742 | list_add_tail(&rdev->net_list, &net->devices); |
743 | } else |
744 | return -1; |
745 | |
746 | if (rio_is_switch(rdev)) { |
747 | next_switchid++; |
748 | |
749 | /* Associated destid is how we accessed this switch */ |
750 | rdev->rswitch->destid = destid; |
751 | |
752 | num_ports = rio_get_swpinfo_tports(port, destid, hopcount); |
753 | pr_debug( |
754 | "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n", |
755 | rio_name(rdev), rdev->vid, rdev->did, num_ports); |
756 | for (port_num = 0; port_num < num_ports; port_num++) { |
757 | if (rio_get_swpinfo_inport(port, destid, hopcount) == |
758 | port_num) |
759 | continue; |
760 | |
761 | if (rio_sport_is_active |
762 | (port, destid, hopcount, port_num)) { |
763 | pr_debug( |
764 | "RIO: scanning device on port %d\n", |
765 | port_num); |
766 | for (ndestid = 0; |
767 | ndestid < RIO_ANY_DESTID(port->sys_size); |
768 | ndestid++) { |
769 | rio_route_get_entry(port, rdev->rswitch, |
770 | RIO_GLOBAL_TABLE, |
771 | ndestid, |
772 | &route_port); |
773 | if (route_port == port_num) |
774 | break; |
775 | } |
776 | |
777 | if (rio_disc_peer |
778 | (net, port, ndestid, hopcount + 1) < 0) |
779 | return -1; |
780 | } |
781 | } |
782 | } else |
783 | pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n", |
784 | rio_name(rdev), rdev->vid, rdev->did); |
785 | |
786 | return 0; |
787 | } |
788 | |
789 | /** |
790 | * rio_mport_is_active- Tests if master port link is active |
791 | * @port: Master port to test |
792 | * |
793 | * Reads the port error status CSR for the master port to |
794 | * determine if the port has an active link. Returns |
795 | * %PORT_N_ERR_STS_PORT_OK if the master port is active |
796 | * or %0 if it is inactive. |
797 | */ |
798 | static int rio_mport_is_active(struct rio_mport *port) |
799 | { |
800 | u32 result = 0; |
801 | u32 ext_ftr_ptr; |
802 | int *entry = rio_mport_phys_table; |
803 | |
804 | do { |
805 | if ((ext_ftr_ptr = |
806 | rio_mport_get_feature(port, 1, 0, 0, *entry))) |
807 | break; |
808 | } while (*++entry >= 0); |
809 | |
810 | if (ext_ftr_ptr) |
811 | rio_local_read_config_32(port, |
812 | ext_ftr_ptr + |
813 | RIO_PORT_N_ERR_STS_CSR(port->index), |
814 | &result); |
815 | |
816 | return (result & PORT_N_ERR_STS_PORT_OK); |
817 | } |
818 | |
819 | /** |
820 | * rio_alloc_net- Allocate and configure a new RIO network |
821 | * @port: Master port associated with the RIO network |
822 | * |
823 | * Allocates a RIO network structure, initializes per-network |
824 | * list heads, and adds the associated master port to the |
825 | * network list of associated master ports. Returns a |
826 | * RIO network pointer on success or %NULL on failure. |
827 | */ |
828 | static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port) |
829 | { |
830 | struct rio_net *net; |
831 | |
832 | net = kzalloc(sizeof(struct rio_net), GFP_KERNEL); |
833 | if (net) { |
834 | INIT_LIST_HEAD(&net->node); |
835 | INIT_LIST_HEAD(&net->devices); |
836 | INIT_LIST_HEAD(&net->mports); |
837 | list_add_tail(&port->nnode, &net->mports); |
838 | net->hport = port; |
839 | net->id = next_net++; |
840 | } |
841 | return net; |
842 | } |
843 | |
844 | /** |
845 | * rio_update_route_tables- Updates route tables in switches |
846 | * @port: Master port associated with the RIO network |
847 | * |
848 | * For each enumerated device, ensure that each switch in a system |
849 | * has correct routing entries. Add routes for devices that where |
850 | * unknown dirung the first enumeration pass through the switch. |
851 | */ |
852 | static void rio_update_route_tables(struct rio_mport *port) |
853 | { |
854 | struct rio_dev *rdev; |
855 | struct rio_switch *rswitch; |
856 | u8 sport; |
857 | u16 destid; |
858 | |
859 | list_for_each_entry(rdev, &rio_devices, global_list) { |
860 | |
861 | destid = (rio_is_switch(rdev))?rdev->rswitch->destid:rdev->destid; |
862 | |
863 | list_for_each_entry(rswitch, &rio_switches, node) { |
864 | |
865 | if (rio_is_switch(rdev) && (rdev->rswitch == rswitch)) |
866 | continue; |
867 | |
868 | if (RIO_INVALID_ROUTE == rswitch->route_table[destid]) { |
869 | |
870 | sport = rio_get_swpinfo_inport(port, |
871 | rswitch->destid, rswitch->hopcount); |
872 | |
873 | if (rswitch->add_entry) { |
874 | rio_route_add_entry(port, rswitch, RIO_GLOBAL_TABLE, destid, sport); |
875 | rswitch->route_table[destid] = sport; |
876 | } |
877 | } |
878 | } |
879 | } |
880 | } |
881 | |
882 | /** |
883 | * rio_enum_mport- Start enumeration through a master port |
884 | * @mport: Master port to send transactions |
885 | * |
886 | * Starts the enumeration process. If somebody has enumerated our |
887 | * master port device, then give up. If not and we have an active |
888 | * link, then start recursive peer enumeration. Returns %0 if |
889 | * enumeration succeeds or %-EBUSY if enumeration fails. |
890 | */ |
891 | int __devinit rio_enum_mport(struct rio_mport *mport) |
892 | { |
893 | struct rio_net *net = NULL; |
894 | int rc = 0; |
895 | |
896 | printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id, |
897 | mport->name); |
898 | /* If somebody else enumerated our master port device, bail. */ |
899 | if (rio_enum_host(mport) < 0) { |
900 | printk(KERN_INFO |
901 | "RIO: master port %d device has been enumerated by a remote host\n", |
902 | mport->id); |
903 | rc = -EBUSY; |
904 | goto out; |
905 | } |
906 | |
907 | /* If master port has an active link, allocate net and enum peers */ |
908 | if (rio_mport_is_active(mport)) { |
909 | if (!(net = rio_alloc_net(mport))) { |
910 | printk(KERN_ERR "RIO: failed to allocate new net\n"); |
911 | rc = -ENOMEM; |
912 | goto out; |
913 | } |
914 | if (rio_enum_peer(net, mport, 0) < 0) { |
915 | /* A higher priority host won enumeration, bail. */ |
916 | printk(KERN_INFO |
917 | "RIO: master port %d device has lost enumeration to a remote host\n", |
918 | mport->id); |
919 | rio_clear_locks(mport); |
920 | rc = -EBUSY; |
921 | goto out; |
922 | } |
923 | rio_update_route_tables(mport); |
924 | rio_clear_locks(mport); |
925 | } else { |
926 | printk(KERN_INFO "RIO: master port %d link inactive\n", |
927 | mport->id); |
928 | rc = -EINVAL; |
929 | } |
930 | |
931 | out: |
932 | return rc; |
933 | } |
934 | |
935 | /** |
936 | * rio_build_route_tables- Generate route tables from switch route entries |
937 | * |
938 | * For each switch device, generate a route table by copying existing |
939 | * route entries from the switch. |
940 | */ |
941 | static void rio_build_route_tables(void) |
942 | { |
943 | struct rio_dev *rdev; |
944 | int i; |
945 | u8 sport; |
946 | |
947 | list_for_each_entry(rdev, &rio_devices, global_list) |
948 | if (rio_is_switch(rdev)) |
949 | for (i = 0; |
950 | i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size); |
951 | i++) { |
952 | if (rio_route_get_entry |
953 | (rdev->net->hport, rdev->rswitch, RIO_GLOBAL_TABLE, |
954 | i, &sport) < 0) |
955 | continue; |
956 | rdev->rswitch->route_table[i] = sport; |
957 | } |
958 | } |
959 | |
960 | /** |
961 | * rio_enum_timeout- Signal that enumeration timed out |
962 | * @data: Address of timeout flag. |
963 | * |
964 | * When the enumeration complete timer expires, set a flag that |
965 | * signals to the discovery process that enumeration did not |
966 | * complete in a sane amount of time. |
967 | */ |
968 | static void rio_enum_timeout(unsigned long data) |
969 | { |
970 | /* Enumeration timed out, set flag */ |
971 | *(int *)data = 1; |
972 | } |
973 | |
974 | /** |
975 | * rio_disc_mport- Start discovery through a master port |
976 | * @mport: Master port to send transactions |
977 | * |
978 | * Starts the discovery process. If we have an active link, |
979 | * then wait for the signal that enumeration is complete. |
980 | * When enumeration completion is signaled, start recursive |
981 | * peer discovery. Returns %0 if discovery succeeds or %-EBUSY |
982 | * on failure. |
983 | */ |
984 | int __devinit rio_disc_mport(struct rio_mport *mport) |
985 | { |
986 | struct rio_net *net = NULL; |
987 | int enum_timeout_flag = 0; |
988 | |
989 | printk(KERN_INFO "RIO: discover master port %d, %s\n", mport->id, |
990 | mport->name); |
991 | |
992 | /* If master port has an active link, allocate net and discover peers */ |
993 | if (rio_mport_is_active(mport)) { |
994 | if (!(net = rio_alloc_net(mport))) { |
995 | printk(KERN_ERR "RIO: Failed to allocate new net\n"); |
996 | goto bail; |
997 | } |
998 | |
999 | pr_debug("RIO: wait for enumeration complete..."); |
1000 | |
1001 | rio_enum_timer.expires = |
1002 | jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ; |
1003 | rio_enum_timer.data = (unsigned long)&enum_timeout_flag; |
1004 | add_timer(&rio_enum_timer); |
1005 | while (!rio_enum_complete(mport)) { |
1006 | mdelay(1); |
1007 | if (enum_timeout_flag) { |
1008 | del_timer_sync(&rio_enum_timer); |
1009 | goto timeout; |
1010 | } |
1011 | } |
1012 | del_timer_sync(&rio_enum_timer); |
1013 | |
1014 | pr_debug("done\n"); |
1015 | if (rio_disc_peer(net, mport, RIO_ANY_DESTID(mport->sys_size), |
1016 | 0) < 0) { |
1017 | printk(KERN_INFO |
1018 | "RIO: master port %d device has failed discovery\n", |
1019 | mport->id); |
1020 | goto bail; |
1021 | } |
1022 | |
1023 | rio_build_route_tables(); |
1024 | } |
1025 | |
1026 | return 0; |
1027 | |
1028 | timeout: |
1029 | pr_debug("timeout\n"); |
1030 | bail: |
1031 | return -EBUSY; |
1032 | } |
1033 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9