Skip to content

Commit

Permalink
rapidio: add enabling SRIO port RX and TX
Browse files Browse the repository at this point in the history
Add the functionality to enable Input receiver and Output transmitter of
every port, to allow non-maintenance traffic.

Signed-off-by: Thomas Moll <thomas.moll@sysgo.com>
Signed-off-by: Alexandre Bounine <abounine@tundra.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Li Yang <leoli@freescale.com>
Cc: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Thomas Moll authored and torvalds committed May 27, 2010
1 parent a52c8f5 commit 933af4a
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 1 deletion.
11 changes: 11 additions & 0 deletions drivers/rapidio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,15 @@ config RAPIDIO_DISC_TIMEOUT
Amount of time a discovery node waits for a host to complete
enumeration before giving up.

config RAPIDIO_ENABLE_RX_TX_PORTS
bool "Enable RapidIO Input/Output Ports"
depends on RAPIDIO
---help---
The RapidIO specification describes a Output port transmit
enable and a Input port receive enable. The recommended state
for Input ports and Output ports should be disabled. When
this switch is set the RapidIO subsystem will enable all
ports for Input/Output direction to allow other traffic
than Maintenance transfers.

source "drivers/rapidio/switches/Kconfig"
79 changes: 78 additions & 1 deletion drivers/rapidio/rio-scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
* Alex Bounine <alexandre.bounine@idt.com>
* - Added Port-Write/Error Management initialization and handling
*
* Copyright 2009 Sysgo AG
* Thomas Moll <thomas.moll@sysgo.com>
* - Added Input- Output- enable functionality, to allow full communication
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
Expand Down Expand Up @@ -327,6 +331,65 @@ static int __devinit rio_add_device(struct rio_dev *rdev)
return 0;
}

/**
* rio_enable_rx_tx_port - enable input reciever and output transmitter of
* given port
* @port: Master port associated with the RIO network
* @local: local=1 select local port otherwise a far device is reached
* @destid: Destination ID of the device to check host bit
* @hopcount: Number of hops to reach the target
* @port_num: Port (-number on switch) to enable on a far end device
*
* Returns 0 or 1 from on General Control Command and Status Register
* (EXT_PTR+0x3C)
*/
inline int rio_enable_rx_tx_port(struct rio_mport *port,
int local, u16 destid,
u8 hopcount, u8 port_num) {
#ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS
u32 regval;
u32 ext_ftr_ptr;

/*
* enable rx input tx output port
*/
pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = "
"%d, port_num = %d)\n", local, destid, hopcount, port_num);

ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount);

if (local) {
rio_local_read_config_32(port, ext_ftr_ptr +
RIO_PORT_N_CTL_CSR(0),
&regval);
} else {
if (rio_mport_read_config_32(port, destid, hopcount,
ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), &regval) < 0)
return -EIO;
}

if (regval & RIO_PORT_N_CTL_P_TYP_SER) {
/* serial */
regval = regval | RIO_PORT_N_CTL_EN_RX_SER
| RIO_PORT_N_CTL_EN_TX_SER;
} else {
/* parallel */
regval = regval | RIO_PORT_N_CTL_EN_RX_PAR
| RIO_PORT_N_CTL_EN_TX_PAR;
}

if (local) {
rio_local_write_config_32(port, ext_ftr_ptr +
RIO_PORT_N_CTL_CSR(0), regval);
} else {
if (rio_mport_write_config_32(port, destid, hopcount,
ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0)
return -EIO;
}
#endif
return 0;
}

/**
* rio_setup_device- Allocates and sets up a RIO device
* @net: RIO network
Expand Down Expand Up @@ -430,9 +493,14 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,

list_add_tail(&rswitch->node, &rio_switches);

} else
} else {
if (do_enum)
/*Enable Input Output Port (transmitter reviever)*/
rio_enable_rx_tx_port(port, 0, destid, hopcount, 0);

dev_set_name(&rdev->dev, "%02x:e:%04x", rdev->net->id,
rdev->destid);
}

rdev->dev.bus = &rio_bus_type;

Expand Down Expand Up @@ -812,6 +880,11 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
rio_name(rdev), rdev->vid, rdev->did, num_ports);
sw_destid = next_destid;
for (port_num = 0; port_num < num_ports; port_num++) {
/*Enable Input Output Port (transmitter reviever)*/
rio_enable_rx_tx_port(port, 0,
RIO_ANY_DESTID(port->sys_size),
hopcount, port_num);

if (sw_inport == port_num) {
rdev->rswitch->port_ok |= (1 << port_num);
continue;
Expand Down Expand Up @@ -1132,6 +1205,10 @@ int __devinit rio_enum_mport(struct rio_mport *mport)
rc = -ENOMEM;
goto out;
}

/* Enable Input Output Port (transmitter reviever) */
rio_enable_rx_tx_port(mport, 1, 0, 0, 0);

if (rio_enum_peer(net, mport, 0) < 0) {
/* A higher priority host won enumeration, bail. */
printk(KERN_INFO
Expand Down
5 changes: 5 additions & 0 deletions include/linux/rio_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,12 @@
#define RIO_PORT_N_CTL_PWIDTH 0xc0000000
#define RIO_PORT_N_CTL_PWIDTH_1 0x00000000
#define RIO_PORT_N_CTL_PWIDTH_4 0x40000000
#define RIO_PORT_N_CTL_P_TYP_SER 0x00000001
#define RIO_PORT_N_CTL_LOCKOUT 0x00000002
#define RIO_PORT_N_CTL_EN_RX_SER 0x00200000
#define RIO_PORT_N_CTL_EN_TX_SER 0x00400000
#define RIO_PORT_N_CTL_EN_RX_PAR 0x08000000
#define RIO_PORT_N_CTL_EN_TX_PAR 0x40000000

/*
* Error Management Extensions (RapidIO 1.3+, Part 8)
Expand Down

0 comments on commit 933af4a

Please sign in to comment.