Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e0423236 authored by Zhang Wei's avatar Zhang Wei Committed by Paul Mackerras
Browse files

[RAPIDIO] Auto-probe the RapidIO system size



The RapidIO system size will auto probe in RIO setup.  The route table
and rionet_active in rionet.c are changed to be allocated dynamically
according to the size of the system.

Signed-off-by: default avatarZhang Wei <wei.zhang@freescale.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent cc2bb696
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -1007,6 +1007,12 @@ int fsl_rio_setup(struct of_device *dev)
	rio_register_mport(port);

	priv->regs_win = ioremap(regs.start, regs.end - regs.start + 1);

	port->sys_size = (in_be32((priv->regs_win + RIO_PEF_CAR))
					& RIO_PEF_CTLS) >> 4;
	dev_info(&dev->dev, "RapidIO Common Transport System size: %d\n",
			port->sys_size ? 65536 : 256);

	priv->atmu_regs = (struct rio_atmu_regs *)(priv->regs_win
					+ RIO_ATMU_REGS_OFFSET);
	priv->maint_atmu_regs = priv->atmu_regs + 1;
+14 −2
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ static int rionet_capable = 1;
 * could be made into a hash table to save memory depending
 * on system trade-offs.
 */
static struct rio_dev *rionet_active[RIO_MAX_ROUTE_ENTRIES];
static struct rio_dev **rionet_active;

#define is_rionet_capable(pef, src_ops, dst_ops)		\
			((pef & RIO_PEF_INB_MBOX) &&		\
@@ -195,7 +195,8 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
	}

	if (eth->h_dest[0] & 0x01) {
		for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++)
		for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size);
				i++)
			if (rionet_active[i])
				rionet_queue_tx_msg(skb, ndev,
						    rionet_active[i]);
@@ -385,6 +386,8 @@ static void rionet_remove(struct rio_dev *rdev)
	struct net_device *ndev = NULL;
	struct rionet_peer *peer, *tmp;

	free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ?
					__ilog2(sizeof(void *)) + 4 : 0);
	unregister_netdev(ndev);
	kfree(ndev);

@@ -443,6 +446,15 @@ static int rionet_setup_netdev(struct rio_mport *mport)
		goto out;
	}

	rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
			mport->sys_size ? __ilog2(sizeof(void *)) + 4 : 0);
	if (!rionet_active) {
		rc = -ENOMEM;
		goto out;
	}
	memset((void *)rionet_active, 0, sizeof(void *) *
				RIO_MAX_ROUTE_ENTRIES(mport->sys_size));

	/* Set up private area */
	rnet = (struct rionet_private *)ndev->priv;
	rnet->mport = mport;
+0 −8
Original line number Diff line number Diff line
#
# RapidIO configuration
#
config RAPIDIO_8_BIT_TRANSPORT
	bool "8-bit transport addressing"
	depends on RAPIDIO
	---help---
	  By default, the kernel assumes a 16-bit addressed RapidIO
	  network. By selecting this option, the kernel will support
	  an 8-bit addressed network.

config RAPIDIO_DISC_TIMEOUT
	int "Discovery timeout duration (seconds)"
	depends on RAPIDIO
+39 −16
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)

	rio_mport_read_config_32(port, destid, hopcount, RIO_DID_CSR, &result);

	return RIO_GET_DID(result);
	return RIO_GET_DID(port->sys_size, result);
}

/**
@@ -88,7 +88,7 @@ static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount)
static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did)
{
	rio_mport_write_config_32(port, destid, hopcount, RIO_DID_CSR,
				  RIO_SET_DID(did));
				  RIO_SET_DID(port->sys_size, did));
}

/**
@@ -100,7 +100,8 @@ static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u
 */
static void rio_local_set_device_id(struct rio_mport *port, u16 did)
{
	rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(did));
	rio_local_write_config_32(port, RIO_DID_CSR, RIO_SET_DID(port->sys_size,
				did));
}

/**
@@ -350,8 +351,18 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
		rswitch->switchid = next_switchid;
		rswitch->hopcount = hopcount;
		rswitch->destid = destid;
		rswitch->route_table = kzalloc(sizeof(u8)*
					RIO_MAX_ROUTE_ENTRIES(port->sys_size),
					GFP_KERNEL);
		if (!rswitch->route_table) {
			kfree(rdev);
			rdev = NULL;
			kfree(rswitch);
			goto out;
		}
		/* Initialize switch route table */
		for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES; rdid++)
		for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES(port->sys_size);
				rdid++)
			rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
		rdev->rswitch = rswitch;
		sprintf(rio_name(rdev), "%02x:s:%04x", rdev->net->id,
@@ -480,7 +491,7 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
{
	u32 result;

	rio_mport_read_config_32(port, RIO_ANY_DESTID, hopcount,
	rio_mport_read_config_32(port, RIO_ANY_DESTID(port->sys_size), hopcount,
				 RIO_HOST_DID_LOCK_CSR, &result);

	return (u16) (result & 0xffff);
@@ -571,14 +582,16 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
	}

	/* Attempt to acquire device lock */
	rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
	rio_mport_write_config_32(port, RIO_ANY_DESTID(port->sys_size),
				  hopcount,
				  RIO_HOST_DID_LOCK_CSR, port->host_deviceid);
	while ((tmp = rio_get_host_deviceid_lock(port, hopcount))
	       < port->host_deviceid) {
		/* Delay a bit */
		mdelay(1);
		/* Attempt to acquire device lock again */
		rio_mport_write_config_32(port, RIO_ANY_DESTID, hopcount,
		rio_mport_write_config_32(port, RIO_ANY_DESTID(port->sys_size),
					  hopcount,
					  RIO_HOST_DID_LOCK_CSR,
					  port->host_deviceid);
	}
@@ -590,7 +603,9 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
	}

	/* Setup new RIO device */
	if ((rdev = rio_setup_device(net, port, RIO_ANY_DESTID, hopcount, 1))) {
	rdev = rio_setup_device(net, port, RIO_ANY_DESTID(port->sys_size),
					hopcount, 1);
	if (rdev) {
		/* Add device to the global and bus/net specific list. */
		list_add_tail(&rdev->net_list, &net->devices);
	} else
@@ -598,7 +613,8 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,

	if (rio_is_switch(rdev)) {
		next_switchid++;
		sw_inport = rio_get_swpinfo_inport(port, RIO_ANY_DESTID, hopcount);
		sw_inport = rio_get_swpinfo_inport(port,
				RIO_ANY_DESTID(port->sys_size), hopcount);
		rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE,
				    port->host_deviceid, sw_inport);
		rdev->rswitch->route_table[port->host_deviceid] = sw_inport;
@@ -612,7 +628,8 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
		}

		num_ports =
		    rio_get_swpinfo_tports(port, RIO_ANY_DESTID, hopcount);
		    rio_get_swpinfo_tports(port, RIO_ANY_DESTID(port->sys_size),
						hopcount);
		pr_debug(
		    "RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
		    rio_name(rdev), rdev->vid, rdev->did, num_ports);
@@ -624,13 +641,15 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
			cur_destid = next_destid;

			if (rio_sport_is_active
			    (port, RIO_ANY_DESTID, hopcount, port_num)) {
			    (port, RIO_ANY_DESTID(port->sys_size), hopcount,
			     port_num)) {
				pr_debug(
				    "RIO: scanning device on port %d\n",
				    port_num);
				rio_route_add_entry(port, rdev->rswitch,
						RIO_GLOBAL_TABLE,
						    RIO_ANY_DESTID, port_num);
						RIO_ANY_DESTID(port->sys_size),
						port_num);

				if (rio_enum_peer(net, port, hopcount + 1) < 0)
					return -1;
@@ -735,7 +754,8 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
				pr_debug(
				    "RIO: scanning device on port %d\n",
				    port_num);
				for (ndestid = 0; ndestid < RIO_ANY_DESTID;
				for (ndestid = 0;
				     ndestid < RIO_ANY_DESTID(port->sys_size);
				     ndestid++) {
					rio_route_get_entry(port, rdev->rswitch,
							    RIO_GLOBAL_TABLE,
@@ -917,7 +937,9 @@ static void rio_build_route_tables(void)

	list_for_each_entry(rdev, &rio_devices, global_list)
	    if (rio_is_switch(rdev))
		for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
		for (i = 0;
		     i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
		     i++) {
			if (rio_route_get_entry
			    (rdev->net->hport, rdev->rswitch, RIO_GLOBAL_TABLE,
			     i, &sport) < 0)
@@ -981,7 +1003,8 @@ int rio_disc_mport(struct rio_mport *mport)
		del_timer_sync(&rio_enum_timer);

		pr_debug("done\n");
		if (rio_disc_peer(net, mport, RIO_ANY_DESTID, 0) < 0) {
		if (rio_disc_peer(net, mport, RIO_ANY_DESTID(mport->sys_size),
					0) < 0) {
			printk(KERN_INFO
			       "RIO: master port %d device has failed discovery\n",
			       mport->id);
+2 −1
Original line number Diff line number Diff line
@@ -43,7 +43,8 @@ static ssize_t routes_show(struct device *dev, struct device_attribute *attr, ch
	if (!rdev->rswitch)
		goto out;

	for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
	for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
			i++) {
		if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE)
			continue;
		str +=
Loading