aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/rapidio/Kconfig11
-rw-r--r--drivers/rapidio/rio-scan.c79
-rw-r--r--include/linux/rio_regs.h5
3 files changed, 94 insertions, 1 deletions
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index 606cb172c1e5..bcb5c2063370 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -9,4 +9,15 @@ config RAPIDIO_DISC_TIMEOUT
9 Amount of time a discovery node waits for a host to complete 9 Amount of time a discovery node waits for a host to complete
10 enumeration before giving up. 10 enumeration before giving up.
11 11
12config RAPIDIO_ENABLE_RX_TX_PORTS
13 bool "Enable RapidIO Input/Output Ports"
14 depends on RAPIDIO
15 ---help---
16 The RapidIO specification describes a Output port transmit
17 enable and a Input port receive enable. The recommended state
18 for Input ports and Output ports should be disabled. When
19 this switch is set the RapidIO subsystem will enable all
20 ports for Input/Output direction to allow other traffic
21 than Maintenance transfers.
22
12source "drivers/rapidio/switches/Kconfig" 23source "drivers/rapidio/switches/Kconfig"
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 74633cc6b2eb..1faa1a5756e2 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -8,6 +8,10 @@
8 * Alex Bounine <alexandre.bounine@idt.com> 8 * Alex Bounine <alexandre.bounine@idt.com>
9 * - Added Port-Write/Error Management initialization and handling 9 * - Added Port-Write/Error Management initialization and handling
10 * 10 *
11 * Copyright 2009 Sysgo AG
12 * Thomas Moll <thomas.moll@sysgo.com>
13 * - Added Input- Output- enable functionality, to allow full communication
14 *
11 * This program is free software; you can redistribute it and/or modify it 15 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the 16 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your 17 * Free Software Foundation; either version 2 of the License, or (at your
@@ -328,6 +332,65 @@ static int __devinit rio_add_device(struct rio_dev *rdev)
328} 332}
329 333
330/** 334/**
335 * 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/**
331 * rio_setup_device- Allocates and sets up a RIO device 394 * rio_setup_device- Allocates and sets up a RIO device
332 * @net: RIO network 395 * @net: RIO network
333 * @port: Master port to send transactions 396 * @port: Master port to send transactions
@@ -430,9 +493,14 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
430 493
431 list_add_tail(&rswitch->node, &rio_switches); 494 list_add_tail(&rswitch->node, &rio_switches);
432 495
433 } else 496 } else {
497 if (do_enum)
498 /*Enable Input Output Port (transmitter reviever)*/
499 rio_enable_rx_tx_port(port, 0, destid, hopcount, 0);
500
434 dev_set_name(&rdev->dev, "%02x:e:%04x", rdev->net->id, 501 dev_set_name(&rdev->dev, "%02x:e:%04x", rdev->net->id,
435 rdev->destid); 502 rdev->destid);
503 }
436 504
437 rdev->dev.bus = &rio_bus_type; 505 rdev->dev.bus = &rio_bus_type;
438 506
@@ -812,6 +880,11 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
812 rio_name(rdev), rdev->vid, rdev->did, num_ports); 880 rio_name(rdev), rdev->vid, rdev->did, num_ports);
813 sw_destid = next_destid; 881 sw_destid = next_destid;
814 for (port_num = 0; port_num < num_ports; port_num++) { 882 for (port_num = 0; port_num < num_ports; port_num++) {
883 /*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
815 if (sw_inport == port_num) { 888 if (sw_inport == port_num) {
816 rdev->rswitch->port_ok |= (1 << port_num); 889 rdev->rswitch->port_ok |= (1 << port_num);
817 continue; 890 continue;
@@ -1132,6 +1205,10 @@ int __devinit rio_enum_mport(struct rio_mport *mport)
1132 rc = -ENOMEM; 1205 rc = -ENOMEM;
1133 goto out; 1206 goto out;
1134 } 1207 }
1208
1209 /* Enable Input Output Port (transmitter reviever) */
1210 rio_enable_rx_tx_port(mport, 1, 0, 0, 0);
1211
1135 if (rio_enum_peer(net, mport, 0) < 0) { 1212 if (rio_enum_peer(net, mport, 0) < 0) {
1136 /* A higher priority host won enumeration, bail. */ 1213 /* A higher priority host won enumeration, bail. */
1137 printk(KERN_INFO 1214 printk(KERN_INFO
diff --git a/include/linux/rio_regs.h b/include/linux/rio_regs.h
index 96ba2159d9fe..aedee0489fb4 100644
--- a/include/linux/rio_regs.h
+++ b/include/linux/rio_regs.h
@@ -243,7 +243,12 @@
243#define RIO_PORT_N_CTL_PWIDTH 0xc0000000 243#define RIO_PORT_N_CTL_PWIDTH 0xc0000000
244#define RIO_PORT_N_CTL_PWIDTH_1 0x00000000 244#define RIO_PORT_N_CTL_PWIDTH_1 0x00000000
245#define RIO_PORT_N_CTL_PWIDTH_4 0x40000000 245#define RIO_PORT_N_CTL_PWIDTH_4 0x40000000
246#define RIO_PORT_N_CTL_P_TYP_SER 0x00000001
246#define RIO_PORT_N_CTL_LOCKOUT 0x00000002 247#define RIO_PORT_N_CTL_LOCKOUT 0x00000002
248#define RIO_PORT_N_CTL_EN_RX_SER 0x00200000
249#define RIO_PORT_N_CTL_EN_TX_SER 0x00400000
250#define RIO_PORT_N_CTL_EN_RX_PAR 0x08000000
251#define RIO_PORT_N_CTL_EN_TX_PAR 0x40000000
247 252
248/* 253/*
249 * Error Management Extensions (RapidIO 1.3+, Part 8) 254 * Error Management Extensions (RapidIO 1.3+, Part 8)