blob: 1faa1a5756e2883f4e61847b0a51c45e087bf240 [file] [log] [blame]
Matt Portereb188d02005-11-07 01:00:17 -08001/*
2 * RapidIO enumeration and discovery support
3 *
4 * Copyright 2005 MontaVista Software, Inc.
5 * Matt Porter <mporter@kernel.crashing.org>
6 *
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -07007 * Copyright 2009 Integrated Device Technology, Inc.
8 * Alex Bounine <alexandre.bounine@idt.com>
9 * - Added Port-Write/Error Management initialization and handling
10 *
Thomas Moll933af4a2010-05-26 14:44:01 -070011 * Copyright 2009 Sysgo AG
12 * Thomas Moll <thomas.moll@sysgo.com>
13 * - Added Input- Output- enable functionality, to allow full communication
14 *
Matt Portereb188d02005-11-07 01:00:17 -080015 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
19 */
20
Matt Portereb188d02005-11-07 01:00:17 -080021#include <linux/types.h>
22#include <linux/kernel.h>
23
24#include <linux/delay.h>
Matt Porterfa78cc52005-11-07 01:00:18 -080025#include <linux/dma-mapping.h>
Matt Portereb188d02005-11-07 01:00:17 -080026#include <linux/init.h>
27#include <linux/rio.h>
28#include <linux/rio_drv.h>
29#include <linux/rio_ids.h>
30#include <linux/rio_regs.h>
31#include <linux/module.h>
32#include <linux/spinlock.h>
33#include <linux/timer.h>
Tim Schmielaude259682006-01-08 01:02:05 -080034#include <linux/jiffies.h>
35#include <linux/slab.h>
Matt Portereb188d02005-11-07 01:00:17 -080036
37#include "rio.h"
38
39LIST_HEAD(rio_devices);
40static LIST_HEAD(rio_switches);
41
Matt Portereb188d02005-11-07 01:00:17 -080042static void rio_enum_timeout(unsigned long);
43
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -070044static void rio_init_em(struct rio_dev *rdev);
45
Matt Porterfa78cc52005-11-07 01:00:18 -080046DEFINE_SPINLOCK(rio_global_list_lock);
47
Matt Portereb188d02005-11-07 01:00:17 -080048static int next_destid = 0;
49static int next_switchid = 0;
50static int next_net = 0;
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -070051static int next_comptag;
Matt Portereb188d02005-11-07 01:00:17 -080052
53static struct timer_list rio_enum_timer =
54TIMER_INITIALIZER(rio_enum_timeout, 0, 0);
55
56static int rio_mport_phys_table[] = {
57 RIO_EFB_PAR_EP_ID,
58 RIO_EFB_PAR_EP_REC_ID,
59 RIO_EFB_SER_EP_ID,
60 RIO_EFB_SER_EP_REC_ID,
61 -1,
62};
63
Matt Portereb188d02005-11-07 01:00:17 -080064/**
65 * rio_get_device_id - Get the base/extended device id for a device
66 * @port: RIO master port
67 * @destid: Destination ID of device
68 * @hopcount: Hopcount to device
69 *
70 * Reads the base/extended device id from a device. Returns the
71 * 8/16-bit device ID.
72 */
73static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)
74{
75 u32 result;
76
77 rio_mport_read_config_32(port, destid, hopcount, RIO_DID_CSR, &result);
78
Zhang Weie0423232008-04-18 13:33:42 -070079 return RIO_GET_DID(port->sys_size, result);
Matt Portereb188d02005-11-07 01:00:17 -080080}
81
82/**
83 * rio_set_device_id - Set the base/extended device id for a device
84 * @port: RIO master port
85 * @destid: Destination ID of device
86 * @hopcount: Hopcount to device
87 * @did: Device ID value to be written
88 *
89 * Writes the base/extended device id from a device.
90 */
Matt Porterfa78cc52005-11-07 01:00:18 -080091static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did)
Matt Portereb188d02005-11-07 01:00:17 -080092{
93 rio_mport_write_config_32(port, destid, hopcount, RIO_DID_CSR,
Zhang Weie0423232008-04-18 13:33:42 -070094 RIO_SET_DID(port->sys_size, did));
Matt Portereb188d02005-11-07 01:00:17 -080095}
96
97/**
98 * rio_local_set_device_id - Set the base/extended device id for a port
99 * @port: RIO master port
100 * @did: Device ID value to be written
101 *
102 * Writes the base/extended device id from a device.
103 */
104static void rio_local_set_device_id(struct rio_mport *port, u16 did)
105{
Zhang Weie0423232008-04-18 13:33:42 -0700106 rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(port->sys_size,
107 did));
Matt Portereb188d02005-11-07 01:00:17 -0800108}
109
110/**
111 * rio_clear_locks- Release all host locks and signal enumeration complete
112 * @port: Master port to issue transaction
113 *
114 * Marks the component tag CSR on each device with the enumeration
115 * complete flag. When complete, it then release the host locks on
116 * each device. Returns 0 on success or %-EINVAL on failure.
117 */
118static int rio_clear_locks(struct rio_mport *port)
119{
120 struct rio_dev *rdev;
121 u32 result;
122 int ret = 0;
123
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700124 /* Assign component tag to all devices */
125 next_comptag = 1;
126 rio_local_write_config_32(port, RIO_COMPONENT_TAG_CSR, next_comptag++);
127
128 list_for_each_entry(rdev, &rio_devices, global_list) {
129 /* Mark device as discovered */
130 rio_read_config_32(rdev,
131 rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR,
132 &result);
133 rio_write_config_32(rdev,
134 rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR,
135 result | RIO_PORT_GEN_DISCOVERED);
136
137 rio_write_config_32(rdev, RIO_COMPONENT_TAG_CSR, next_comptag);
138 rdev->comp_tag = next_comptag++;
139 if (next_comptag >= 0x10000) {
140 pr_err("RIO: Component Tag Counter Overflow\n");
141 break;
142 }
143 }
Matt Portereb188d02005-11-07 01:00:17 -0800144
145 /* Release host device id locks */
146 rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR,
147 port->host_deviceid);
148 rio_local_read_config_32(port, RIO_HOST_DID_LOCK_CSR, &result);
149 if ((result & 0xffff) != 0xffff) {
150 printk(KERN_INFO
151 "RIO: badness when releasing host lock on master port, result %8.8x\n",
152 result);
153 ret = -EINVAL;
154 }
155 list_for_each_entry(rdev, &rio_devices, global_list) {
156 rio_write_config_32(rdev, RIO_HOST_DID_LOCK_CSR,
157 port->host_deviceid);
158 rio_read_config_32(rdev, RIO_HOST_DID_LOCK_CSR, &result);
159 if ((result & 0xffff) != 0xffff) {
160 printk(KERN_INFO
161 "RIO: badness when releasing host lock on vid %4.4x did %4.4x\n",
162 rdev->vid, rdev->did);
163 ret = -EINVAL;
164 }
165 }
166
167 return ret;
168}
169
170/**
171 * rio_enum_host- Set host lock and initialize host destination ID
172 * @port: Master port to issue transaction
173 *
174 * Sets the local host master port lock and destination ID register
175 * with the host device ID value. The host device ID value is provided
176 * by the platform. Returns %0 on success or %-1 on failure.
177 */
178static int rio_enum_host(struct rio_mport *port)
179{
180 u32 result;
181
182 /* Set master port host device id lock */
183 rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR,
184 port->host_deviceid);
185
186 rio_local_read_config_32(port, RIO_HOST_DID_LOCK_CSR, &result);
187 if ((result & 0xffff) != port->host_deviceid)
188 return -1;
189
190 /* Set master port destid and init destid ctr */
191 rio_local_set_device_id(port, port->host_deviceid);
192
193 if (next_destid == port->host_deviceid)
194 next_destid++;
195
196 return 0;
197}
198
199/**
200 * rio_device_has_destid- Test if a device contains a destination ID register
201 * @port: Master port to issue transaction
202 * @src_ops: RIO device source operations
203 * @dst_ops: RIO device destination operations
204 *
205 * Checks the provided @src_ops and @dst_ops for the necessary transaction
206 * capabilities that indicate whether or not a device will implement a
207 * destination ID register. Returns 1 if true or 0 if false.
208 */
209static int rio_device_has_destid(struct rio_mport *port, int src_ops,
210 int dst_ops)
211{
Matt Porterfa78cc52005-11-07 01:00:18 -0800212 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;
213
214 return !!((src_ops | dst_ops) & mask);
Matt Portereb188d02005-11-07 01:00:17 -0800215}
216
217/**
218 * rio_release_dev- Frees a RIO device struct
219 * @dev: LDM device associated with a RIO device struct
220 *
221 * Gets the RIO device struct associated a RIO device struct.
222 * The RIO device struct is freed.
223 */
224static void rio_release_dev(struct device *dev)
225{
226 struct rio_dev *rdev;
227
228 rdev = to_rio_dev(dev);
229 kfree(rdev);
230}
231
232/**
233 * rio_is_switch- Tests if a RIO device has switch capabilities
234 * @rdev: RIO device
235 *
236 * Gets the RIO device Processing Element Features register
237 * contents and tests for switch capabilities. Returns 1 if
238 * the device is a switch or 0 if it is not a switch.
239 * The RIO device struct is freed.
240 */
241static int rio_is_switch(struct rio_dev *rdev)
242{
243 if (rdev->pef & RIO_PEF_SWITCH)
244 return 1;
245 return 0;
246}
247
248/**
249 * rio_route_set_ops- Sets routing operations for a particular vendor switch
250 * @rdev: RIO device
251 *
252 * Searches the RIO route ops table for known switch types. If the vid
253 * and did match a switch table entry, then set the add_entry() and
254 * get_entry() ops to the table entry values.
255 */
256static void rio_route_set_ops(struct rio_dev *rdev)
257{
258 struct rio_route_ops *cur = __start_rio_route_ops;
259 struct rio_route_ops *end = __end_rio_route_ops;
260
261 while (cur < end) {
262 if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
263 pr_debug("RIO: adding routing ops for %s\n", rio_name(rdev));
264 rdev->rswitch->add_entry = cur->add_hook;
265 rdev->rswitch->get_entry = cur->get_hook;
Alexandre Bounine07590ff2010-05-26 14:43:57 -0700266 rdev->rswitch->clr_table = cur->clr_hook;
267 break;
Matt Portereb188d02005-11-07 01:00:17 -0800268 }
269 cur++;
270 }
271
Alexandre Bounine07590ff2010-05-26 14:43:57 -0700272 if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) {
273 pr_debug("RIO: adding STD routing ops for %s\n",
274 rio_name(rdev));
275 rdev->rswitch->add_entry = rio_std_route_add_entry;
276 rdev->rswitch->get_entry = rio_std_route_get_entry;
277 rdev->rswitch->clr_table = rio_std_route_clr_table;
278 }
279
Matt Portereb188d02005-11-07 01:00:17 -0800280 if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
281 printk(KERN_ERR "RIO: missing routing ops for %s\n",
282 rio_name(rdev));
283}
284
285/**
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700286 * rio_em_set_ops- Sets Error Managment operations for a particular vendor switch
287 * @rdev: RIO device
288 *
289 * Searches the RIO EM ops table for known switch types. If the vid
290 * and did match a switch table entry, then set the em_init() and
291 * em_handle() ops to the table entry values.
292 */
293static void rio_em_set_ops(struct rio_dev *rdev)
294{
295 struct rio_em_ops *cur = __start_rio_em_ops;
296 struct rio_em_ops *end = __end_rio_em_ops;
297
298 while (cur < end) {
299 if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
300 pr_debug("RIO: adding EM ops for %s\n", rio_name(rdev));
301 rdev->rswitch->em_init = cur->init_hook;
302 rdev->rswitch->em_handle = cur->handler_hook;
303 break;
304 }
305 cur++;
306 }
307}
308
309/**
Matt Portereb188d02005-11-07 01:00:17 -0800310 * rio_add_device- Adds a RIO device to the device model
311 * @rdev: RIO device
312 *
313 * Adds the RIO device to the global device list and adds the RIO
314 * device to the RIO device list. Creates the generic sysfs nodes
315 * for an RIO device.
316 */
Yang Li5f28c522009-05-11 22:36:02 +0000317static int __devinit rio_add_device(struct rio_dev *rdev)
Matt Portereb188d02005-11-07 01:00:17 -0800318{
Yang Li5f28c522009-05-11 22:36:02 +0000319 int err;
320
321 err = device_add(&rdev->dev);
322 if (err)
323 return err;
Matt Portereb188d02005-11-07 01:00:17 -0800324
325 spin_lock(&rio_global_list_lock);
326 list_add_tail(&rdev->global_list, &rio_devices);
327 spin_unlock(&rio_global_list_lock);
328
329 rio_create_sysfs_dev_files(rdev);
Yang Li5f28c522009-05-11 22:36:02 +0000330
331 return 0;
Matt Portereb188d02005-11-07 01:00:17 -0800332}
333
334/**
Thomas Moll933af4a2010-05-26 14:44:01 -0700335 * rio_enable_rx_tx_port - enable input reciever and output transmitter of
336 * given port
337 * @port: Master port associated with the RIO network
338 * @local: local=1 select local port otherwise a far device is reached
339 * @destid: Destination ID of the device to check host bit
340 * @hopcount: Number of hops to reach the target
341 * @port_num: Port (-number on switch) to enable on a far end device
342 *
343 * Returns 0 or 1 from on General Control Command and Status Register
344 * (EXT_PTR+0x3C)
345 */
346inline int rio_enable_rx_tx_port(struct rio_mport *port,
347 int local, u16 destid,
348 u8 hopcount, u8 port_num) {
349#ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS
350 u32 regval;
351 u32 ext_ftr_ptr;
352
353 /*
354 * enable rx input tx output port
355 */
356 pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = "
357 "%d, port_num = %d)\n", local, destid, hopcount, port_num);
358
359 ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount);
360
361 if (local) {
362 rio_local_read_config_32(port, ext_ftr_ptr +
363 RIO_PORT_N_CTL_CSR(0),
364 &regval);
365 } else {
366 if (rio_mport_read_config_32(port, destid, hopcount,
367 ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), &regval) < 0)
368 return -EIO;
369 }
370
371 if (regval & RIO_PORT_N_CTL_P_TYP_SER) {
372 /* serial */
373 regval = regval | RIO_PORT_N_CTL_EN_RX_SER
374 | RIO_PORT_N_CTL_EN_TX_SER;
375 } else {
376 /* parallel */
377 regval = regval | RIO_PORT_N_CTL_EN_RX_PAR
378 | RIO_PORT_N_CTL_EN_TX_PAR;
379 }
380
381 if (local) {
382 rio_local_write_config_32(port, ext_ftr_ptr +
383 RIO_PORT_N_CTL_CSR(0), regval);
384 } else {
385 if (rio_mport_write_config_32(port, destid, hopcount,
386 ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0)
387 return -EIO;
388 }
389#endif
390 return 0;
391}
392
393/**
Matt Portereb188d02005-11-07 01:00:17 -0800394 * rio_setup_device- Allocates and sets up a RIO device
395 * @net: RIO network
396 * @port: Master port to send transactions
397 * @destid: Current destination ID
398 * @hopcount: Current hopcount
399 * @do_enum: Enumeration/Discovery mode flag
400 *
401 * Allocates a RIO device and configures fields based on configuration
402 * space contents. If device has a destination ID register, a destination
403 * ID is either assigned in enumeration mode or read from configuration
404 * space in discovery mode. If the device has switch capabilities, then
405 * a switch is allocated and configured appropriately. Returns a pointer
406 * to a RIO device on success or NULL on failure.
407 *
408 */
Li Yang181a6ff2009-05-12 16:36:03 +0800409static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
Matt Portereb188d02005-11-07 01:00:17 -0800410 struct rio_mport *port, u16 destid,
411 u8 hopcount, int do_enum)
412{
Yang Li5f28c522009-05-11 22:36:02 +0000413 int ret = 0;
Matt Portereb188d02005-11-07 01:00:17 -0800414 struct rio_dev *rdev;
Yang Li5f28c522009-05-11 22:36:02 +0000415 struct rio_switch *rswitch = NULL;
Matt Portereb188d02005-11-07 01:00:17 -0800416 int result, rdid;
417
Yoann Padioleaudd00cc42007-07-19 01:49:03 -0700418 rdev = kzalloc(sizeof(struct rio_dev), GFP_KERNEL);
Matt Portereb188d02005-11-07 01:00:17 -0800419 if (!rdev)
Yang Li5f28c522009-05-11 22:36:02 +0000420 return NULL;
Matt Portereb188d02005-11-07 01:00:17 -0800421
Matt Portereb188d02005-11-07 01:00:17 -0800422 rdev->net = net;
423 rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_ID_CAR,
424 &result);
425 rdev->did = result >> 16;
426 rdev->vid = result & 0xffff;
427 rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_INFO_CAR,
428 &rdev->device_rev);
429 rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_ID_CAR,
430 &result);
431 rdev->asm_did = result >> 16;
432 rdev->asm_vid = result & 0xffff;
433 rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_INFO_CAR,
434 &result);
435 rdev->asm_rev = result >> 16;
436 rio_mport_read_config_32(port, destid, hopcount, RIO_PEF_CAR,
437 &rdev->pef);
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700438 if (rdev->pef & RIO_PEF_EXT_FEATURES) {
Matt Portereb188d02005-11-07 01:00:17 -0800439 rdev->efptr = result & 0xffff;
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700440 rdev->phys_efptr = rio_mport_get_physefb(port, 0, destid,
441 hopcount);
442
443 rdev->em_efptr = rio_mport_get_feature(port, 0, destid,
444 hopcount, RIO_EFB_ERR_MGMNT);
445 }
Matt Portereb188d02005-11-07 01:00:17 -0800446
447 rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR,
448 &rdev->src_ops);
449 rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR,
450 &rdev->dst_ops);
451
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800452 if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) {
453 if (do_enum) {
454 rio_set_device_id(port, destid, hopcount, next_destid);
455 rdev->destid = next_destid++;
456 if (next_destid == port->host_deviceid)
457 next_destid++;
458 } else
459 rdev->destid = rio_get_device_id(port, destid, hopcount);
Matt Portereb188d02005-11-07 01:00:17 -0800460 } else
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800461 /* Switch device has an associated destID */
462 rdev->destid = RIO_INVALID_DESTID;
Matt Portereb188d02005-11-07 01:00:17 -0800463
464 /* If a PE has both switch and other functions, show it as a switch */
465 if (rio_is_switch(rdev)) {
466 rio_mport_read_config_32(port, destid, hopcount,
467 RIO_SWP_INFO_CAR, &rdev->swpinfo);
Alexandre Bounine07590ff2010-05-26 14:43:57 -0700468 rswitch = kzalloc(sizeof(struct rio_switch), GFP_KERNEL);
Yang Li5f28c522009-05-11 22:36:02 +0000469 if (!rswitch)
470 goto cleanup;
Matt Portereb188d02005-11-07 01:00:17 -0800471 rswitch->switchid = next_switchid;
472 rswitch->hopcount = hopcount;
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800473 rswitch->destid = destid;
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700474 rswitch->port_ok = 0;
Zhang Weie0423232008-04-18 13:33:42 -0700475 rswitch->route_table = kzalloc(sizeof(u8)*
476 RIO_MAX_ROUTE_ENTRIES(port->sys_size),
477 GFP_KERNEL);
Yang Li5f28c522009-05-11 22:36:02 +0000478 if (!rswitch->route_table)
479 goto cleanup;
Matt Portereb188d02005-11-07 01:00:17 -0800480 /* Initialize switch route table */
Zhang Weie0423232008-04-18 13:33:42 -0700481 for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES(port->sys_size);
482 rdid++)
Matt Portereb188d02005-11-07 01:00:17 -0800483 rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
484 rdev->rswitch = rswitch;
Kay Sieversb53c75832008-12-04 10:01:52 -0800485 dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id,
486 rdev->rswitch->switchid);
Matt Portereb188d02005-11-07 01:00:17 -0800487 rio_route_set_ops(rdev);
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700488 rio_em_set_ops(rdev);
Matt Portereb188d02005-11-07 01:00:17 -0800489
Alexandre Bounine07590ff2010-05-26 14:43:57 -0700490 if (do_enum && rdev->rswitch->clr_table)
491 rdev->rswitch->clr_table(port, destid, hopcount,
492 RIO_GLOBAL_TABLE);
493
Matt Portereb188d02005-11-07 01:00:17 -0800494 list_add_tail(&rswitch->node, &rio_switches);
495
Thomas Moll933af4a2010-05-26 14:44:01 -0700496 } else {
497 if (do_enum)
498 /*Enable Input Output Port (transmitter reviever)*/
499 rio_enable_rx_tx_port(port, 0, destid, hopcount, 0);
500
Kay Sieversb53c75832008-12-04 10:01:52 -0800501 dev_set_name(&rdev->dev, "%02x:e:%04x", rdev->net->id,
502 rdev->destid);
Thomas Moll933af4a2010-05-26 14:44:01 -0700503 }
Matt Portereb188d02005-11-07 01:00:17 -0800504
505 rdev->dev.bus = &rio_bus_type;
506
507 device_initialize(&rdev->dev);
508 rdev->dev.release = rio_release_dev;
509 rio_dev_get(rdev);
510
Yang Hongyang284901a2009-04-06 19:01:15 -0700511 rdev->dma_mask = DMA_BIT_MASK(32);
Matt Porterfa78cc52005-11-07 01:00:18 -0800512 rdev->dev.dma_mask = &rdev->dma_mask;
Yang Hongyang284901a2009-04-06 19:01:15 -0700513 rdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
Matt Portereb188d02005-11-07 01:00:17 -0800514
515 if ((rdev->pef & RIO_PEF_INB_DOORBELL) &&
516 (rdev->dst_ops & RIO_DST_OPS_DOORBELL))
517 rio_init_dbell_res(&rdev->riores[RIO_DOORBELL_RESOURCE],
518 0, 0xffff);
519
Yang Li5f28c522009-05-11 22:36:02 +0000520 ret = rio_add_device(rdev);
521 if (ret)
522 goto cleanup;
Matt Portereb188d02005-11-07 01:00:17 -0800523
Matt Portereb188d02005-11-07 01:00:17 -0800524 return rdev;
Yang Li5f28c522009-05-11 22:36:02 +0000525
526cleanup:
527 if (rswitch) {
528 kfree(rswitch->route_table);
529 kfree(rswitch);
530 }
531 kfree(rdev);
532 return NULL;
Matt Portereb188d02005-11-07 01:00:17 -0800533}
534
535/**
536 * rio_sport_is_active- Tests if a switch port has an active connection.
537 * @port: Master port to send transaction
538 * @destid: Associated destination ID for switch
539 * @hopcount: Hopcount to reach switch
540 * @sport: Switch port number
541 *
542 * Reads the port error status CSR for a particular switch port to
543 * determine if the port has an active link. Returns
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700544 * %RIO_PORT_N_ERR_STS_PORT_OK if the port is active or %0 if it is
Matt Portereb188d02005-11-07 01:00:17 -0800545 * inactive.
546 */
547static int
548rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport)
549{
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700550 u32 result = 0;
Matt Portereb188d02005-11-07 01:00:17 -0800551 u32 ext_ftr_ptr;
552
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700553 ext_ftr_ptr = rio_mport_get_efb(port, 0, destid, hopcount, 0);
Matt Portereb188d02005-11-07 01:00:17 -0800554
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700555 while (ext_ftr_ptr) {
556 rio_mport_read_config_32(port, destid, hopcount,
557 ext_ftr_ptr, &result);
558 result = RIO_GET_BLOCK_ID(result);
559 if ((result == RIO_EFB_SER_EP_FREE_ID) ||
560 (result == RIO_EFB_SER_EP_FREE_ID_V13P) ||
561 (result == RIO_EFB_SER_EP_FREC_ID))
Matt Portereb188d02005-11-07 01:00:17 -0800562 break;
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700563
564 ext_ftr_ptr = rio_mport_get_efb(port, 0, destid, hopcount,
565 ext_ftr_ptr);
566 }
Matt Portereb188d02005-11-07 01:00:17 -0800567
568 if (ext_ftr_ptr)
569 rio_mport_read_config_32(port, destid, hopcount,
570 ext_ftr_ptr +
571 RIO_PORT_N_ERR_STS_CSR(sport),
572 &result);
573
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700574 return result & RIO_PORT_N_ERR_STS_PORT_OK;
Matt Portereb188d02005-11-07 01:00:17 -0800575}
576
577/**
Alexandre Bounine818a04a2010-05-26 14:43:58 -0700578 * rio_lock_device - Acquires host device lock for specified device
579 * @port: Master port to send transaction
580 * @destid: Destination ID for device/switch
581 * @hopcount: Hopcount to reach switch
582 * @wait_ms: Max wait time in msec (0 = no timeout)
583 *
584 * Attepts to acquire host device lock for specified device
585 * Returns 0 if device lock acquired or EINVAL if timeout expires.
586 */
587static int
588rio_lock_device(struct rio_mport *port, u16 destid, u8 hopcount, int wait_ms)
589{
590 u32 result;
591 int tcnt = 0;
592
593 /* Attempt to acquire device lock */
594 rio_mport_write_config_32(port, destid, hopcount,
595 RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
596 rio_mport_read_config_32(port, destid, hopcount,
597 RIO_HOST_DID_LOCK_CSR, &result);
598
599 while (result != port->host_deviceid) {
600 if (wait_ms != 0 && tcnt == wait_ms) {
601 pr_debug("RIO: timeout when locking device %x:%x\n",
602 destid, hopcount);
603 return -EINVAL;
604 }
605
606 /* Delay a bit */
607 mdelay(1);
608 tcnt++;
609 /* Try to acquire device lock again */
610 rio_mport_write_config_32(port, destid,
611 hopcount,
612 RIO_HOST_DID_LOCK_CSR,
613 port->host_deviceid);
614 rio_mport_read_config_32(port, destid,
615 hopcount,
616 RIO_HOST_DID_LOCK_CSR, &result);
617 }
618
619 return 0;
620}
621
622/**
623 * rio_unlock_device - Releases host device lock for specified device
624 * @port: Master port to send transaction
625 * @destid: Destination ID for device/switch
626 * @hopcount: Hopcount to reach switch
627 *
628 * Returns 0 if device lock released or EINVAL if fails.
629 */
630static int
631rio_unlock_device(struct rio_mport *port, u16 destid, u8 hopcount)
632{
633 u32 result;
634
635 /* Release device lock */
636 rio_mport_write_config_32(port, destid,
637 hopcount,
638 RIO_HOST_DID_LOCK_CSR,
639 port->host_deviceid);
640 rio_mport_read_config_32(port, destid, hopcount,
641 RIO_HOST_DID_LOCK_CSR, &result);
642 if ((result & 0xffff) != 0xffff) {
643 pr_debug("RIO: badness when releasing device lock %x:%x\n",
644 destid, hopcount);
645 return -EINVAL;
646 }
647
648 return 0;
649}
650
651/**
Matt Portereb188d02005-11-07 01:00:17 -0800652 * rio_route_add_entry- Add a route entry to a switch routing table
653 * @mport: Master port to send transaction
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800654 * @rswitch: Switch device
Matt Portereb188d02005-11-07 01:00:17 -0800655 * @table: Routing table ID
656 * @route_destid: Destination ID to be routed
657 * @route_port: Port number to be routed
Alexandre Bounine818a04a2010-05-26 14:43:58 -0700658 * @lock: lock switch device flag
Matt Portereb188d02005-11-07 01:00:17 -0800659 *
660 * Calls the switch specific add_entry() method to add a route entry
661 * on a switch. The route table can be specified using the @table
662 * argument if a switch has per port routing tables or the normal
663 * use is to specific all tables (or the global table) by passing
664 * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
665 * on failure.
666 */
Alexandre Bounine818a04a2010-05-26 14:43:58 -0700667static int
668rio_route_add_entry(struct rio_mport *mport, struct rio_switch *rswitch,
669 u16 table, u16 route_destid, u8 route_port, int lock)
Matt Portereb188d02005-11-07 01:00:17 -0800670{
Alexandre Bounine818a04a2010-05-26 14:43:58 -0700671 int rc;
672
673 if (lock) {
674 rc = rio_lock_device(mport, rswitch->destid,
675 rswitch->hopcount, 1000);
676 if (rc)
677 return rc;
678 }
679
680 rc = rswitch->add_entry(mport, rswitch->destid,
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800681 rswitch->hopcount, table,
Matt Portereb188d02005-11-07 01:00:17 -0800682 route_destid, route_port);
Alexandre Bounine818a04a2010-05-26 14:43:58 -0700683 if (lock)
684 rio_unlock_device(mport, rswitch->destid, rswitch->hopcount);
685
686 return rc;
Matt Portereb188d02005-11-07 01:00:17 -0800687}
688
689/**
690 * rio_route_get_entry- Read a route entry in a switch routing table
691 * @mport: Master port to send transaction
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800692 * @rswitch: Switch device
Matt Portereb188d02005-11-07 01:00:17 -0800693 * @table: Routing table ID
694 * @route_destid: Destination ID to be routed
695 * @route_port: Pointer to read port number into
Alexandre Bounine818a04a2010-05-26 14:43:58 -0700696 * @lock: lock switch device flag
Matt Portereb188d02005-11-07 01:00:17 -0800697 *
698 * Calls the switch specific get_entry() method to read a route entry
699 * in a switch. The route table can be specified using the @table
700 * argument if a switch has per port routing tables or the normal
701 * use is to specific all tables (or the global table) by passing
702 * %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
703 * on failure.
704 */
705static int
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800706rio_route_get_entry(struct rio_mport *mport, struct rio_switch *rswitch, u16 table,
Alexandre Bounine818a04a2010-05-26 14:43:58 -0700707 u16 route_destid, u8 *route_port, int lock)
Matt Portereb188d02005-11-07 01:00:17 -0800708{
Alexandre Bounine818a04a2010-05-26 14:43:58 -0700709 int rc;
710
711 if (lock) {
712 rc = rio_lock_device(mport, rswitch->destid,
713 rswitch->hopcount, 1000);
714 if (rc)
715 return rc;
716 }
717
718 rc = rswitch->get_entry(mport, rswitch->destid,
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800719 rswitch->hopcount, table,
Matt Portereb188d02005-11-07 01:00:17 -0800720 route_destid, route_port);
Alexandre Bounine818a04a2010-05-26 14:43:58 -0700721 if (lock)
722 rio_unlock_device(mport, rswitch->destid, rswitch->hopcount);
723
724 return rc;
Matt Portereb188d02005-11-07 01:00:17 -0800725}
726
727/**
728 * rio_get_host_deviceid_lock- Reads the Host Device ID Lock CSR on a device
729 * @port: Master port to send transaction
730 * @hopcount: Number of hops to the device
731 *
732 * Used during enumeration to read the Host Device ID Lock CSR on a
733 * RIO device. Returns the value of the lock register.
734 */
735static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
736{
737 u32 result;
738
Zhang Weie0423232008-04-18 13:33:42 -0700739 rio_mport_read_config_32(port, RIO_ANY_DESTID(port->sys_size), hopcount,
Matt Portereb188d02005-11-07 01:00:17 -0800740 RIO_HOST_DID_LOCK_CSR, &result);
741
742 return (u16) (result & 0xffff);
743}
744
745/**
746 * rio_get_swpinfo_inport- Gets the ingress port number
747 * @mport: Master port to send transaction
748 * @destid: Destination ID associated with the switch
749 * @hopcount: Number of hops to the device
750 *
751 * Returns port number being used to access the switch device.
752 */
753static u8
754rio_get_swpinfo_inport(struct rio_mport *mport, u16 destid, u8 hopcount)
755{
756 u32 result;
757
758 rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
759 &result);
760
761 return (u8) (result & 0xff);
762}
763
764/**
765 * rio_get_swpinfo_tports- Gets total number of ports on the switch
766 * @mport: Master port to send transaction
767 * @destid: Destination ID associated with the switch
768 * @hopcount: Number of hops to the device
769 *
770 * Returns total numbers of ports implemented by the switch device.
771 */
772static u8 rio_get_swpinfo_tports(struct rio_mport *mport, u16 destid,
773 u8 hopcount)
774{
775 u32 result;
776
777 rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
778 &result);
779
780 return RIO_GET_TOTAL_PORTS(result);
781}
782
783/**
784 * rio_net_add_mport- Add a master port to a RIO network
785 * @net: RIO network
786 * @port: Master port to add
787 *
788 * Adds a master port to the network list of associated master
789 * ports..
790 */
791static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port)
792{
793 spin_lock(&rio_global_list_lock);
794 list_add_tail(&port->nnode, &net->mports);
795 spin_unlock(&rio_global_list_lock);
796}
797
798/**
799 * rio_enum_peer- Recursively enumerate a RIO network through a master port
800 * @net: RIO network being enumerated
801 * @port: Master port to send transactions
802 * @hopcount: Number of hops into the network
803 *
804 * Recursively enumerates a RIO network. Transactions are sent via the
805 * master port passed in @port.
806 */
Li Yang181a6ff2009-05-12 16:36:03 +0800807static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
Matt Portereb188d02005-11-07 01:00:17 -0800808 u8 hopcount)
809{
810 int port_num;
811 int num_ports;
812 int cur_destid;
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800813 int sw_destid;
814 int sw_inport;
Matt Portereb188d02005-11-07 01:00:17 -0800815 struct rio_dev *rdev;
816 u16 destid;
817 int tmp;
818
819 if (rio_get_host_deviceid_lock(port, hopcount) == port->host_deviceid) {
820 pr_debug("RIO: PE already discovered by this host\n");
821 /*
822 * Already discovered by this host. Add it as another
823 * master port for the current network.
824 */
825 rio_net_add_mport(net, port);
826 return 0;
827 }
828
829 /* Attempt to acquire device lock */
Zhang Weie0423232008-04-18 13:33:42 -0700830 rio_mport_write_config_32(port, RIO_ANY_DESTID(port->sys_size),
831 hopcount,
Matt Portereb188d02005-11-07 01:00:17 -0800832 RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
833 while ((tmp = rio_get_host_deviceid_lock(port, hopcount))
834 < port->host_deviceid) {
835 /* Delay a bit */
836 mdelay(1);
837 /* Attempt to acquire device lock again */
Zhang Weie0423232008-04-18 13:33:42 -0700838 rio_mport_write_config_32(port, RIO_ANY_DESTID(port->sys_size),
839 hopcount,
Matt Portereb188d02005-11-07 01:00:17 -0800840 RIO_HOST_DID_LOCK_CSR,
841 port->host_deviceid);
842 }
843
844 if (rio_get_host_deviceid_lock(port, hopcount) > port->host_deviceid) {
845 pr_debug(
846 "RIO: PE locked by a higher priority host...retreating\n");
847 return -1;
848 }
849
850 /* Setup new RIO device */
Zhang Weie0423232008-04-18 13:33:42 -0700851 rdev = rio_setup_device(net, port, RIO_ANY_DESTID(port->sys_size),
852 hopcount, 1);
853 if (rdev) {
Matt Portereb188d02005-11-07 01:00:17 -0800854 /* Add device to the global and bus/net specific list. */
855 list_add_tail(&rdev->net_list, &net->devices);
856 } else
857 return -1;
858
859 if (rio_is_switch(rdev)) {
860 next_switchid++;
Zhang Weie0423232008-04-18 13:33:42 -0700861 sw_inport = rio_get_swpinfo_inport(port,
862 RIO_ANY_DESTID(port->sys_size), hopcount);
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800863 rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE,
Alexandre Bounine818a04a2010-05-26 14:43:58 -0700864 port->host_deviceid, sw_inport, 0);
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800865 rdev->rswitch->route_table[port->host_deviceid] = sw_inport;
Matt Portereb188d02005-11-07 01:00:17 -0800866
867 for (destid = 0; destid < next_destid; destid++) {
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800868 if (destid == port->host_deviceid)
869 continue;
870 rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE,
Alexandre Bounine818a04a2010-05-26 14:43:58 -0700871 destid, sw_inport, 0);
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800872 rdev->rswitch->route_table[destid] = sw_inport;
Matt Portereb188d02005-11-07 01:00:17 -0800873 }
874
875 num_ports =
Zhang Weie0423232008-04-18 13:33:42 -0700876 rio_get_swpinfo_tports(port, RIO_ANY_DESTID(port->sys_size),
877 hopcount);
Matt Portereb188d02005-11-07 01:00:17 -0800878 pr_debug(
879 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
880 rio_name(rdev), rdev->vid, rdev->did, num_ports);
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800881 sw_destid = next_destid;
Matt Portereb188d02005-11-07 01:00:17 -0800882 for (port_num = 0; port_num < num_ports; port_num++) {
Thomas Moll933af4a2010-05-26 14:44:01 -0700883 /*Enable Input Output Port (transmitter reviever)*/
884 rio_enable_rx_tx_port(port, 0,
885 RIO_ANY_DESTID(port->sys_size),
886 hopcount, port_num);
887
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700888 if (sw_inport == port_num) {
889 rdev->rswitch->port_ok |= (1 << port_num);
Matt Portereb188d02005-11-07 01:00:17 -0800890 continue;
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700891 }
Matt Portereb188d02005-11-07 01:00:17 -0800892
893 cur_destid = next_destid;
894
895 if (rio_sport_is_active
Zhang Weie0423232008-04-18 13:33:42 -0700896 (port, RIO_ANY_DESTID(port->sys_size), hopcount,
897 port_num)) {
Matt Portereb188d02005-11-07 01:00:17 -0800898 pr_debug(
899 "RIO: scanning device on port %d\n",
900 port_num);
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700901 rdev->rswitch->port_ok |= (1 << port_num);
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800902 rio_route_add_entry(port, rdev->rswitch,
Zhang Weie0423232008-04-18 13:33:42 -0700903 RIO_GLOBAL_TABLE,
904 RIO_ANY_DESTID(port->sys_size),
Alexandre Bounine818a04a2010-05-26 14:43:58 -0700905 port_num, 0);
Matt Portereb188d02005-11-07 01:00:17 -0800906
907 if (rio_enum_peer(net, port, hopcount + 1) < 0)
908 return -1;
909
910 /* Update routing tables */
911 if (next_destid > cur_destid) {
912 for (destid = cur_destid;
913 destid < next_destid; destid++) {
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800914 if (destid == port->host_deviceid)
915 continue;
916 rio_route_add_entry(port, rdev->rswitch,
Matt Portereb188d02005-11-07 01:00:17 -0800917 RIO_GLOBAL_TABLE,
918 destid,
Alexandre Bounine818a04a2010-05-26 14:43:58 -0700919 port_num,
920 0);
Matt Portereb188d02005-11-07 01:00:17 -0800921 rdev->rswitch->
922 route_table[destid] =
923 port_num;
924 }
Matt Portereb188d02005-11-07 01:00:17 -0800925 }
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700926 } else {
927 /* If switch supports Error Management,
928 * set PORT_LOCKOUT bit for unused port
929 */
930 if (rdev->em_efptr)
931 rio_set_port_lockout(rdev, port_num, 1);
932
933 rdev->rswitch->port_ok &= ~(1 << port_num);
Matt Portereb188d02005-11-07 01:00:17 -0800934 }
935 }
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800936
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700937 /* Direct Port-write messages to the enumeratiing host */
938 if ((rdev->src_ops & RIO_SRC_OPS_PORT_WRITE) &&
939 (rdev->em_efptr)) {
940 rio_write_config_32(rdev,
941 rdev->em_efptr + RIO_EM_PW_TGT_DEVID,
942 (port->host_deviceid << 16) |
943 (port->sys_size << 15));
944 }
945
946 rio_init_em(rdev);
947
Alexandre Bouninec70555b2007-02-10 01:46:47 -0800948 /* Check for empty switch */
949 if (next_destid == sw_destid) {
950 next_destid++;
951 if (next_destid == port->host_deviceid)
952 next_destid++;
953 }
954
955 rdev->rswitch->destid = sw_destid;
Matt Portereb188d02005-11-07 01:00:17 -0800956 } else
957 pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
958 rio_name(rdev), rdev->vid, rdev->did);
959
960 return 0;
961}
962
963/**
964 * rio_enum_complete- Tests if enumeration of a network is complete
965 * @port: Master port to send transaction
966 *
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700967 * Tests the Component Tag CSR for non-zero value (enumeration
968 * complete flag). Return %1 if enumeration is complete or %0 if
Matt Portereb188d02005-11-07 01:00:17 -0800969 * enumeration is incomplete.
970 */
971static int rio_enum_complete(struct rio_mport *port)
972{
973 u32 tag_csr;
Matt Portereb188d02005-11-07 01:00:17 -0800974
975 rio_local_read_config_32(port, RIO_COMPONENT_TAG_CSR, &tag_csr);
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -0700976 return (tag_csr & 0xffff) ? 1 : 0;
Matt Portereb188d02005-11-07 01:00:17 -0800977}
978
979/**
980 * rio_disc_peer- Recursively discovers a RIO network through a master port
981 * @net: RIO network being discovered
982 * @port: Master port to send transactions
983 * @destid: Current destination ID in network
984 * @hopcount: Number of hops into the network
985 *
986 * Recursively discovers a RIO network. Transactions are sent via the
987 * master port passed in @port.
988 */
Li Yang181a6ff2009-05-12 16:36:03 +0800989static int __devinit
Matt Portereb188d02005-11-07 01:00:17 -0800990rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
991 u8 hopcount)
992{
993 u8 port_num, route_port;
994 int num_ports;
995 struct rio_dev *rdev;
996 u16 ndestid;
997
998 /* Setup new RIO device */
999 if ((rdev = rio_setup_device(net, port, destid, hopcount, 0))) {
1000 /* Add device to the global and bus/net specific list. */
1001 list_add_tail(&rdev->net_list, &net->devices);
1002 } else
1003 return -1;
1004
1005 if (rio_is_switch(rdev)) {
1006 next_switchid++;
1007
1008 /* Associated destid is how we accessed this switch */
1009 rdev->rswitch->destid = destid;
1010
1011 num_ports = rio_get_swpinfo_tports(port, destid, hopcount);
1012 pr_debug(
1013 "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
1014 rio_name(rdev), rdev->vid, rdev->did, num_ports);
1015 for (port_num = 0; port_num < num_ports; port_num++) {
1016 if (rio_get_swpinfo_inport(port, destid, hopcount) ==
1017 port_num)
1018 continue;
1019
1020 if (rio_sport_is_active
1021 (port, destid, hopcount, port_num)) {
1022 pr_debug(
1023 "RIO: scanning device on port %d\n",
1024 port_num);
Alexandre Bounine818a04a2010-05-26 14:43:58 -07001025
1026 rio_lock_device(port, destid, hopcount, 1000);
1027
Zhang Weie0423232008-04-18 13:33:42 -07001028 for (ndestid = 0;
1029 ndestid < RIO_ANY_DESTID(port->sys_size);
Matt Portereb188d02005-11-07 01:00:17 -08001030 ndestid++) {
Alexandre Bouninec70555b2007-02-10 01:46:47 -08001031 rio_route_get_entry(port, rdev->rswitch,
Matt Portereb188d02005-11-07 01:00:17 -08001032 RIO_GLOBAL_TABLE,
1033 ndestid,
Alexandre Bounine818a04a2010-05-26 14:43:58 -07001034 &route_port, 0);
Matt Portereb188d02005-11-07 01:00:17 -08001035 if (route_port == port_num)
1036 break;
1037 }
1038
Alexandre Bounine818a04a2010-05-26 14:43:58 -07001039 rio_unlock_device(port, destid, hopcount);
Matt Portereb188d02005-11-07 01:00:17 -08001040 if (rio_disc_peer
1041 (net, port, ndestid, hopcount + 1) < 0)
1042 return -1;
1043 }
1044 }
1045 } else
1046 pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
1047 rio_name(rdev), rdev->vid, rdev->did);
1048
1049 return 0;
1050}
1051
1052/**
1053 * rio_mport_is_active- Tests if master port link is active
1054 * @port: Master port to test
1055 *
1056 * Reads the port error status CSR for the master port to
1057 * determine if the port has an active link. Returns
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -07001058 * %RIO_PORT_N_ERR_STS_PORT_OK if the master port is active
Matt Portereb188d02005-11-07 01:00:17 -08001059 * or %0 if it is inactive.
1060 */
1061static int rio_mport_is_active(struct rio_mport *port)
1062{
1063 u32 result = 0;
1064 u32 ext_ftr_ptr;
1065 int *entry = rio_mport_phys_table;
1066
1067 do {
1068 if ((ext_ftr_ptr =
1069 rio_mport_get_feature(port, 1, 0, 0, *entry)))
1070 break;
1071 } while (*++entry >= 0);
1072
1073 if (ext_ftr_ptr)
1074 rio_local_read_config_32(port,
1075 ext_ftr_ptr +
1076 RIO_PORT_N_ERR_STS_CSR(port->index),
1077 &result);
1078
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -07001079 return result & RIO_PORT_N_ERR_STS_PORT_OK;
Matt Portereb188d02005-11-07 01:00:17 -08001080}
1081
1082/**
1083 * rio_alloc_net- Allocate and configure a new RIO network
1084 * @port: Master port associated with the RIO network
1085 *
1086 * Allocates a RIO network structure, initializes per-network
1087 * list heads, and adds the associated master port to the
1088 * network list of associated master ports. Returns a
1089 * RIO network pointer on success or %NULL on failure.
1090 */
1091static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port)
1092{
1093 struct rio_net *net;
1094
Yoann Padioleaudd00cc42007-07-19 01:49:03 -07001095 net = kzalloc(sizeof(struct rio_net), GFP_KERNEL);
Matt Portereb188d02005-11-07 01:00:17 -08001096 if (net) {
Matt Portereb188d02005-11-07 01:00:17 -08001097 INIT_LIST_HEAD(&net->node);
1098 INIT_LIST_HEAD(&net->devices);
1099 INIT_LIST_HEAD(&net->mports);
1100 list_add_tail(&port->nnode, &net->mports);
1101 net->hport = port;
1102 net->id = next_net++;
1103 }
1104 return net;
1105}
1106
1107/**
Alexandre Bouninec70555b2007-02-10 01:46:47 -08001108 * rio_update_route_tables- Updates route tables in switches
1109 * @port: Master port associated with the RIO network
1110 *
1111 * For each enumerated device, ensure that each switch in a system
1112 * has correct routing entries. Add routes for devices that where
1113 * unknown dirung the first enumeration pass through the switch.
1114 */
1115static void rio_update_route_tables(struct rio_mport *port)
1116{
1117 struct rio_dev *rdev;
1118 struct rio_switch *rswitch;
1119 u8 sport;
1120 u16 destid;
1121
1122 list_for_each_entry(rdev, &rio_devices, global_list) {
1123
1124 destid = (rio_is_switch(rdev))?rdev->rswitch->destid:rdev->destid;
1125
1126 list_for_each_entry(rswitch, &rio_switches, node) {
1127
1128 if (rio_is_switch(rdev) && (rdev->rswitch == rswitch))
1129 continue;
1130
1131 if (RIO_INVALID_ROUTE == rswitch->route_table[destid]) {
Alexandre Bounine07590ff2010-05-26 14:43:57 -07001132 /* Skip if destid ends in empty switch*/
1133 if (rswitch->destid == destid)
1134 continue;
Alexandre Bouninec70555b2007-02-10 01:46:47 -08001135
1136 sport = rio_get_swpinfo_inport(port,
1137 rswitch->destid, rswitch->hopcount);
1138
1139 if (rswitch->add_entry) {
Alexandre Bounine818a04a2010-05-26 14:43:58 -07001140 rio_route_add_entry(port, rswitch,
1141 RIO_GLOBAL_TABLE, destid,
1142 sport, 0);
Alexandre Bouninec70555b2007-02-10 01:46:47 -08001143 rswitch->route_table[destid] = sport;
1144 }
1145 }
1146 }
1147 }
1148}
1149
1150/**
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -07001151 * rio_init_em - Initializes RIO Error Management (for switches)
1152 * @port: Master port associated with the RIO network
1153 *
1154 * For each enumerated switch, call device-specific error management
1155 * initialization routine (if supplied by the switch driver).
1156 */
1157static void rio_init_em(struct rio_dev *rdev)
1158{
1159 if (rio_is_switch(rdev) && (rdev->em_efptr) &&
1160 (rdev->rswitch->em_init)) {
1161 rdev->rswitch->em_init(rdev);
1162 }
1163}
1164
1165/**
1166 * rio_pw_enable - Enables/disables port-write handling by a master port
1167 * @port: Master port associated with port-write handling
1168 * @enable: 1=enable, 0=disable
1169 */
1170static void rio_pw_enable(struct rio_mport *port, int enable)
1171{
1172 if (port->ops->pwenable)
1173 port->ops->pwenable(port, enable);
1174}
1175
1176/**
Matt Portereb188d02005-11-07 01:00:17 -08001177 * rio_enum_mport- Start enumeration through a master port
1178 * @mport: Master port to send transactions
1179 *
1180 * Starts the enumeration process. If somebody has enumerated our
1181 * master port device, then give up. If not and we have an active
1182 * link, then start recursive peer enumeration. Returns %0 if
1183 * enumeration succeeds or %-EBUSY if enumeration fails.
1184 */
Al Viro37d33d12008-11-22 17:36:24 +00001185int __devinit rio_enum_mport(struct rio_mport *mport)
Matt Portereb188d02005-11-07 01:00:17 -08001186{
1187 struct rio_net *net = NULL;
1188 int rc = 0;
1189
1190 printk(KERN_INFO "RIO: enumerate master port %d, %s\n", mport->id,
1191 mport->name);
1192 /* If somebody else enumerated our master port device, bail. */
1193 if (rio_enum_host(mport) < 0) {
1194 printk(KERN_INFO
1195 "RIO: master port %d device has been enumerated by a remote host\n",
1196 mport->id);
1197 rc = -EBUSY;
1198 goto out;
1199 }
1200
1201 /* If master port has an active link, allocate net and enum peers */
1202 if (rio_mport_is_active(mport)) {
1203 if (!(net = rio_alloc_net(mport))) {
1204 printk(KERN_ERR "RIO: failed to allocate new net\n");
1205 rc = -ENOMEM;
1206 goto out;
1207 }
Thomas Moll933af4a2010-05-26 14:44:01 -07001208
1209 /* Enable Input Output Port (transmitter reviever) */
1210 rio_enable_rx_tx_port(mport, 1, 0, 0, 0);
1211
Matt Portereb188d02005-11-07 01:00:17 -08001212 if (rio_enum_peer(net, mport, 0) < 0) {
1213 /* A higher priority host won enumeration, bail. */
1214 printk(KERN_INFO
1215 "RIO: master port %d device has lost enumeration to a remote host\n",
1216 mport->id);
1217 rio_clear_locks(mport);
1218 rc = -EBUSY;
1219 goto out;
1220 }
Alexandre Bouninec70555b2007-02-10 01:46:47 -08001221 rio_update_route_tables(mport);
Matt Portereb188d02005-11-07 01:00:17 -08001222 rio_clear_locks(mport);
Alexandre Bouninee5cabeb2010-05-26 14:43:59 -07001223 rio_pw_enable(mport, 1);
Matt Portereb188d02005-11-07 01:00:17 -08001224 } else {
1225 printk(KERN_INFO "RIO: master port %d link inactive\n",
1226 mport->id);
1227 rc = -EINVAL;
1228 }
1229
1230 out:
1231 return rc;
1232}
1233
1234/**
1235 * rio_build_route_tables- Generate route tables from switch route entries
1236 *
1237 * For each switch device, generate a route table by copying existing
1238 * route entries from the switch.
1239 */
1240static void rio_build_route_tables(void)
1241{
1242 struct rio_dev *rdev;
1243 int i;
1244 u8 sport;
1245
1246 list_for_each_entry(rdev, &rio_devices, global_list)
Alexandre Bounine818a04a2010-05-26 14:43:58 -07001247 if (rio_is_switch(rdev)) {
1248 rio_lock_device(rdev->net->hport, rdev->rswitch->destid,
1249 rdev->rswitch->hopcount, 1000);
1250 for (i = 0;
1251 i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
1252 i++) {
1253 if (rio_route_get_entry
1254 (rdev->net->hport, rdev->rswitch,
1255 RIO_GLOBAL_TABLE, i, &sport, 0) < 0)
1256 continue;
1257 rdev->rswitch->route_table[i] = sport;
1258 }
1259
1260 rio_unlock_device(rdev->net->hport,
1261 rdev->rswitch->destid,
1262 rdev->rswitch->hopcount);
Matt Portereb188d02005-11-07 01:00:17 -08001263 }
1264}
1265
1266/**
1267 * rio_enum_timeout- Signal that enumeration timed out
1268 * @data: Address of timeout flag.
1269 *
1270 * When the enumeration complete timer expires, set a flag that
1271 * signals to the discovery process that enumeration did not
1272 * complete in a sane amount of time.
1273 */
1274static void rio_enum_timeout(unsigned long data)
1275{
1276 /* Enumeration timed out, set flag */
1277 *(int *)data = 1;
1278}
1279
1280/**
1281 * rio_disc_mport- Start discovery through a master port
1282 * @mport: Master port to send transactions
1283 *
1284 * Starts the discovery process. If we have an active link,
1285 * then wait for the signal that enumeration is complete.
1286 * When enumeration completion is signaled, start recursive
1287 * peer discovery. Returns %0 if discovery succeeds or %-EBUSY
1288 * on failure.
1289 */
Al Viro37d33d12008-11-22 17:36:24 +00001290int __devinit rio_disc_mport(struct rio_mport *mport)
Matt Portereb188d02005-11-07 01:00:17 -08001291{
1292 struct rio_net *net = NULL;
1293 int enum_timeout_flag = 0;
1294
1295 printk(KERN_INFO "RIO: discover master port %d, %s\n", mport->id,
1296 mport->name);
1297
1298 /* If master port has an active link, allocate net and discover peers */
1299 if (rio_mport_is_active(mport)) {
1300 if (!(net = rio_alloc_net(mport))) {
1301 printk(KERN_ERR "RIO: Failed to allocate new net\n");
1302 goto bail;
1303 }
1304
1305 pr_debug("RIO: wait for enumeration complete...");
1306
1307 rio_enum_timer.expires =
1308 jiffies + CONFIG_RAPIDIO_DISC_TIMEOUT * HZ;
1309 rio_enum_timer.data = (unsigned long)&enum_timeout_flag;
1310 add_timer(&rio_enum_timer);
1311 while (!rio_enum_complete(mport)) {
1312 mdelay(1);
1313 if (enum_timeout_flag) {
1314 del_timer_sync(&rio_enum_timer);
1315 goto timeout;
1316 }
1317 }
1318 del_timer_sync(&rio_enum_timer);
1319
1320 pr_debug("done\n");
Alexandre Bounine818a04a2010-05-26 14:43:58 -07001321
1322 /* Read DestID assigned by enumerator */
1323 rio_local_read_config_32(mport, RIO_DID_CSR,
1324 &mport->host_deviceid);
1325 mport->host_deviceid = RIO_GET_DID(mport->sys_size,
1326 mport->host_deviceid);
1327
Zhang Weie0423232008-04-18 13:33:42 -07001328 if (rio_disc_peer(net, mport, RIO_ANY_DESTID(mport->sys_size),
1329 0) < 0) {
Matt Portereb188d02005-11-07 01:00:17 -08001330 printk(KERN_INFO
1331 "RIO: master port %d device has failed discovery\n",
1332 mport->id);
1333 goto bail;
1334 }
1335
1336 rio_build_route_tables();
1337 }
1338
1339 return 0;
1340
1341 timeout:
1342 pr_debug("timeout\n");
1343 bail:
1344 return -EBUSY;
1345}