Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 198802
b: refs/heads/master
c: 07590ff
h: refs/heads/master
v: v3
  • Loading branch information
Alexandre Bounine authored and Linus Torvalds committed May 27, 2010
1 parent df222fd commit bc47ae3
Show file tree
Hide file tree
Showing 14 changed files with 506 additions and 12 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f67231f80126f4e08c79c7b2056989c5c89ad4c6
refs/heads/master: 07590ff03935a2efbc03bc7861f20c059576a479
2 changes: 2 additions & 0 deletions trunk/drivers/rapidio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ config RAPIDIO_DISC_TIMEOUT
---help---
Amount of time a discovery node waits for a host to complete
enumeration before giving up.

source "drivers/rapidio/switches/Kconfig"
20 changes: 19 additions & 1 deletion trunk/drivers/rapidio/rio-scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ static int rio_mport_phys_table[] = {
static int rio_sport_phys_table[] = {
RIO_EFB_PAR_EP_FREE_ID,
RIO_EFB_SER_EP_FREE_ID,
RIO_EFB_SER_EP_FREC_ID,
-1,
};

Expand Down Expand Up @@ -246,10 +247,20 @@ static void rio_route_set_ops(struct rio_dev *rdev)
pr_debug("RIO: adding routing ops for %s\n", rio_name(rdev));
rdev->rswitch->add_entry = cur->add_hook;
rdev->rswitch->get_entry = cur->get_hook;
rdev->rswitch->clr_table = cur->clr_hook;
break;
}
cur++;
}

if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) {
pr_debug("RIO: adding STD routing ops for %s\n",
rio_name(rdev));
rdev->rswitch->add_entry = rio_std_route_add_entry;
rdev->rswitch->get_entry = rio_std_route_get_entry;
rdev->rswitch->clr_table = rio_std_route_clr_table;
}

if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
printk(KERN_ERR "RIO: missing routing ops for %s\n",
rio_name(rdev));
Expand Down Expand Up @@ -349,7 +360,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
if (rio_is_switch(rdev)) {
rio_mport_read_config_32(port, destid, hopcount,
RIO_SWP_INFO_CAR, &rdev->swpinfo);
rswitch = kmalloc(sizeof(struct rio_switch), GFP_KERNEL);
rswitch = kzalloc(sizeof(struct rio_switch), GFP_KERNEL);
if (!rswitch)
goto cleanup;
rswitch->switchid = next_switchid;
Expand All @@ -369,6 +380,10 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
rdev->rswitch->switchid);
rio_route_set_ops(rdev);

if (do_enum && rdev->rswitch->clr_table)
rdev->rswitch->clr_table(port, destid, hopcount,
RIO_GLOBAL_TABLE);

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

} else
Expand Down Expand Up @@ -866,6 +881,9 @@ static void rio_update_route_tables(struct rio_mport *port)
continue;

if (RIO_INVALID_ROUTE == rswitch->route_table[destid]) {
/* Skip if destid ends in empty switch*/
if (rswitch->destid == destid)
continue;

sport = rio_get_swpinfo_inport(port,
rswitch->destid, rswitch->hopcount);
Expand Down
104 changes: 104 additions & 0 deletions trunk/drivers/rapidio/rio.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,110 @@ struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from)
return rio_get_asm(vid, did, RIO_ANY_ID, RIO_ANY_ID, from);
}

/**
* rio_std_route_add_entry - Add switch route table entry using standard
* registers defined in RIO specification rev.1.3
* @mport: Master port to issue transaction
* @destid: Destination ID of the device
* @hopcount: Number of switch hops to the device
* @table: routing table ID (global or port-specific)
* @route_destid: destID entry in the RT
* @route_port: destination port for specified destID
*/
int rio_std_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
u16 table, u16 route_destid, u8 route_port)
{
if (table == RIO_GLOBAL_TABLE) {
rio_mport_write_config_32(mport, destid, hopcount,
RIO_STD_RTE_CONF_DESTID_SEL_CSR,
(u32)route_destid);
rio_mport_write_config_32(mport, destid, hopcount,
RIO_STD_RTE_CONF_PORT_SEL_CSR,
(u32)route_port);
}
udelay(10);
return 0;
}

/**
* rio_std_route_get_entry - Read switch route table entry (port number)
* assosiated with specified destID using standard registers defined in RIO
* specification rev.1.3
* @mport: Master port to issue transaction
* @destid: Destination ID of the device
* @hopcount: Number of switch hops to the device
* @table: routing table ID (global or port-specific)
* @route_destid: destID entry in the RT
* @route_port: returned destination port for specified destID
*/
int rio_std_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
u16 table, u16 route_destid, u8 *route_port)
{
u32 result;

if (table == RIO_GLOBAL_TABLE) {
rio_mport_write_config_32(mport, destid, hopcount,
RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);
rio_mport_read_config_32(mport, destid, hopcount,
RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);

*route_port = (u8)result;
}

return 0;
}

/**
* rio_std_route_clr_table - Clear swotch route table using standard registers
* defined in RIO specification rev.1.3.
* @mport: Master port to issue transaction
* @local: Indicate a local master port or remote device access
* @destid: Destination ID of the device
* @hopcount: Number of switch hops to the device
* @table: routing table ID (global or port-specific)
*/
int rio_std_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
u16 table)
{
u32 max_destid = 0xff;
u32 i, pef, id_inc = 1, ext_cfg = 0;
u32 port_sel = RIO_INVALID_ROUTE;

if (table == RIO_GLOBAL_TABLE) {
rio_mport_read_config_32(mport, destid, hopcount,
RIO_PEF_CAR, &pef);

if (mport->sys_size) {
rio_mport_read_config_32(mport, destid, hopcount,
RIO_SWITCH_RT_LIMIT,
&max_destid);
max_destid &= RIO_RT_MAX_DESTID;
}

if (pef & RIO_PEF_EXT_RT) {
ext_cfg = 0x80000000;
id_inc = 4;
port_sel = (RIO_INVALID_ROUTE << 24) |
(RIO_INVALID_ROUTE << 16) |
(RIO_INVALID_ROUTE << 8) |
RIO_INVALID_ROUTE;
}

for (i = 0; i <= max_destid;) {
rio_mport_write_config_32(mport, destid, hopcount,
RIO_STD_RTE_CONF_DESTID_SEL_CSR,
ext_cfg | i);
rio_mport_write_config_32(mport, destid, hopcount,
RIO_STD_RTE_CONF_PORT_SEL_CSR,
port_sel);
i += id_inc;
}
}

udelay(10);
return 0;
}

static void rio_fixup_device(struct rio_dev *dev)
{
}
Expand Down
20 changes: 14 additions & 6 deletions trunk/drivers/rapidio/rio.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ extern u32 rio_mport_get_feature(struct rio_mport *mport, int local, u16 destid,
extern int rio_create_sysfs_dev_files(struct rio_dev *rdev);
extern int rio_enum_mport(struct rio_mport *mport);
extern int rio_disc_mport(struct rio_mport *mport);
extern int rio_std_route_add_entry(struct rio_mport *mport, u16 destid,
u8 hopcount, u16 table, u16 route_destid,
u8 route_port);
extern int rio_std_route_get_entry(struct rio_mport *mport, u16 destid,
u8 hopcount, u16 table, u16 route_destid,
u8 *route_port);
extern int rio_std_route_clr_table(struct rio_mport *mport, u16 destid,
u8 hopcount, u16 table);

/* Structures internal to the RIO core code */
extern struct device_attribute rio_dev_attrs[];
Expand All @@ -30,9 +38,9 @@ extern struct rio_route_ops __start_rio_route_ops[];
extern struct rio_route_ops __end_rio_route_ops[];

/* Helpers internal to the RIO core code */
#define DECLARE_RIO_ROUTE_SECTION(section, vid, did, add_hook, get_hook) \
static struct rio_route_ops __rio_route_ops __used \
__section(section)= { vid, did, add_hook, get_hook };
#define DECLARE_RIO_ROUTE_SECTION(section, name, vid, did, add_hook, get_hook, clr_hook) \
static const struct rio_route_ops __rio_route_##name __used \
__section(section) = { vid, did, add_hook, get_hook, clr_hook };

/**
* DECLARE_RIO_ROUTE_OPS - Registers switch routing operations
Expand All @@ -47,9 +55,9 @@ extern struct rio_route_ops __end_rio_route_ops[];
* rio_route_ops is initialized with the ops and placed into a
* RIO-specific kernel section.
*/
#define DECLARE_RIO_ROUTE_OPS(vid, did, add_hook, get_hook) \
DECLARE_RIO_ROUTE_SECTION(.rio_route_ops, \
vid, did, add_hook, get_hook)
#define DECLARE_RIO_ROUTE_OPS(vid, did, add_hook, get_hook, clr_hook) \
DECLARE_RIO_ROUTE_SECTION(.rio_route_ops, vid##did, \
vid, did, add_hook, get_hook, clr_hook)

#define RIO_GET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x00ff0000) >> 16))
#define RIO_SET_DID(size, x) (size ? (x & 0xffff) : ((x & 0x000000ff) << 16))
28 changes: 28 additions & 0 deletions trunk/drivers/rapidio/switches/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#
# RapidIO switches configuration
#
config RAPIDIO_TSI57X
bool "IDT Tsi57x SRIO switches support"
depends on RAPIDIO
---help---
Includes support for ITD Tsi57x family of serial RapidIO switches.

config RAPIDIO_CPS_XX
bool "IDT CPS-xx SRIO switches support"
depends on RAPIDIO
---help---
Includes support for ITD CPS-16/12/10/8 serial RapidIO switches.

config RAPIDIO_TSI568
bool "Tsi568 SRIO switch support"
depends on RAPIDIO
default n
---help---
Includes support for ITD Tsi568 serial RapidIO switch.

config RAPIDIO_TSI500
bool "Tsi500 Parallel RapidIO switch support"
depends on RAPIDIO
default n
---help---
Includes support for ITD Tsi500 parallel RapidIO switch.
5 changes: 4 additions & 1 deletion trunk/drivers/rapidio/switches/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@
# Makefile for RIO switches
#

obj-$(CONFIG_RAPIDIO) += tsi500.o
obj-$(CONFIG_RAPIDIO_TSI57X) += tsi57x.o
obj-$(CONFIG_RAPIDIO_CPS_XX) += idtcps.o
obj-$(CONFIG_RAPIDIO_TSI568) += tsi568.o
obj-$(CONFIG_RAPIDIO_TSI500) += tsi500.o
89 changes: 89 additions & 0 deletions trunk/drivers/rapidio/switches/idtcps.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* IDT CPS RapidIO switches support
*
* Copyright 2009 Integrated Device Technology, Inc.
*
* 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
* option) any later version.
*/

#include <linux/rio.h>
#include <linux/rio_drv.h>
#include <linux/rio_ids.h>
#include "../rio.h"

#define CPS_NO_ROUTE 0xdf

static int
idtcps_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
u16 table, u16 route_destid, u8 route_port)
{
u32 result;

if (table == RIO_GLOBAL_TABLE) {
rio_mport_write_config_32(mport, destid, hopcount,
RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);

rio_mport_read_config_32(mport, destid, hopcount,
RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);

result = (0xffffff00 & result) | (u32)route_port;
rio_mport_write_config_32(mport, destid, hopcount,
RIO_STD_RTE_CONF_PORT_SEL_CSR, result);
}

return 0;
}

static int
idtcps_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
u16 table, u16 route_destid, u8 *route_port)
{
u32 result;

if (table == RIO_GLOBAL_TABLE) {
rio_mport_write_config_32(mport, destid, hopcount,
RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);

rio_mport_read_config_32(mport, destid, hopcount,
RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);

if (CPS_NO_ROUTE == (u8)result)
result = RIO_INVALID_ROUTE;

*route_port = (u8)result;
}

return 0;
}

static int
idtcps_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
u16 table)
{
u32 i;

if (table == RIO_GLOBAL_TABLE) {
for (i = 0x80000000; i <= 0x800000ff;) {
rio_mport_write_config_32(mport, destid, hopcount,
RIO_STD_RTE_CONF_DESTID_SEL_CSR, i);
rio_mport_write_config_32(mport, destid, hopcount,
RIO_STD_RTE_CONF_PORT_SEL_CSR,
(RIO_INVALID_ROUTE << 24) |
(RIO_INVALID_ROUTE << 16) |
(RIO_INVALID_ROUTE << 8) | RIO_INVALID_ROUTE);
i += 4;
}
}

return 0;
}

DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS6Q, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS8, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS10Q, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS12, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDTCPS16, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
DECLARE_RIO_ROUTE_OPS(RIO_VID_IDT, RIO_DID_IDT70K200, idtcps_route_add_entry, idtcps_route_get_entry, idtcps_route_clr_table);
2 changes: 1 addition & 1 deletion trunk/drivers/rapidio/switches/tsi500.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@ tsi500_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 tab
return ret;
}

DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_route_add_entry, tsi500_route_get_entry);
DECLARE_RIO_ROUTE_OPS(RIO_VID_TUNDRA, RIO_DID_TSI500, tsi500_route_add_entry, tsi500_route_get_entry, NULL);
Loading

0 comments on commit bc47ae3

Please sign in to comment.