// SPDX-License-Identifier: GPL-2.0-or-later /* * RapidIO enumeration and discovery support * * Copyright 2005 MontaVista Software, Inc. * Matt Porter <[email protected]> * * Copyright 2009 Integrated Device Technology, Inc. * Alex Bounine <[email protected]> * - Added Port-Write/Error Management initialization and handling * * Copyright 2009 Sysgo AG * Thomas Moll <[email protected]> * - Added Input- Output- enable functionality, to allow full communication */ #include <linux/types.h> #include <linux/kernel.h> #include <linux/delay.h> #include <linux/dma-mapping.h> #include <linux/init.h> #include <linux/rio.h> #include <linux/rio_drv.h> #include <linux/rio_ids.h> #include <linux/rio_regs.h> #include <linux/module.h> #include <linux/spinlock.h> #include <linux/timer.h> #include <linux/sched.h> #include <linux/jiffies.h> #include <linux/slab.h> #include "rio.h" static void rio_init_em(struct rio_dev *rdev); struct rio_id_table { … }; static int next_destid = …; static int next_comptag = …; /** * rio_destid_alloc - Allocate next available destID for given network * @net: RIO network * * Returns next available device destination ID for the specified RIO network. * Marks allocated ID as one in use. * Returns RIO_INVALID_DESTID if new destID is not available. */ static u16 rio_destid_alloc(struct rio_net *net) { … } /** * rio_destid_reserve - Reserve the specified destID * @net: RIO network * @destid: destID to reserve * * Tries to reserve the specified destID. * Returns 0 if successful. */ static int rio_destid_reserve(struct rio_net *net, u16 destid) { … } /** * rio_destid_free - free a previously allocated destID * @net: RIO network * @destid: destID to free * * Makes the specified destID available for use. */ static void rio_destid_free(struct rio_net *net, u16 destid) { … } /** * rio_destid_first - return first destID in use * @net: RIO network */ static u16 rio_destid_first(struct rio_net *net) { … } /** * rio_destid_next - return next destID in use * @net: RIO network * @from: destination ID from which search shall continue */ static u16 rio_destid_next(struct rio_net *net, u16 from) { … } /** * rio_get_device_id - Get the base/extended device id for a device * @port: RIO master port * @destid: Destination ID of device * @hopcount: Hopcount to device * * Reads the base/extended device id from a device. Returns the * 8/16-bit device ID. */ static u16 rio_get_device_id(struct rio_mport *port, u16 destid, u8 hopcount) { … } /** * rio_set_device_id - Set the base/extended device id for a device * @port: RIO master port * @destid: Destination ID of device * @hopcount: Hopcount to device * @did: Device ID value to be written * * Writes the base/extended device id from a device. */ static void rio_set_device_id(struct rio_mport *port, u16 destid, u8 hopcount, u16 did) { … } /** * rio_clear_locks- Release all host locks and signal enumeration complete * @net: RIO network to run on * * Marks the component tag CSR on each device with the enumeration * complete flag. When complete, it then release the host locks on * each device. Returns 0 on success or %-EINVAL on failure. */ static int rio_clear_locks(struct rio_net *net) { … } /** * rio_enum_host- Set host lock and initialize host destination ID * @port: Master port to issue transaction * * Sets the local host master port lock and destination ID register * with the host device ID value. The host device ID value is provided * by the platform. Returns %0 on success or %-1 on failure. */ static int rio_enum_host(struct rio_mport *port) { … } /** * rio_device_has_destid- Test if a device contains a destination ID register * @port: Master port to issue transaction * @src_ops: RIO device source operations * @dst_ops: RIO device destination operations * * Checks the provided @src_ops and @dst_ops for the necessary transaction * capabilities that indicate whether or not a device will implement a * destination ID register. Returns 1 if true or 0 if false. */ static int rio_device_has_destid(struct rio_mport *port, int src_ops, int dst_ops) { … } /** * rio_release_dev- Frees a RIO device struct * @dev: LDM device associated with a RIO device struct * * Gets the RIO device struct associated a RIO device struct. * The RIO device struct is freed. */ static void rio_release_dev(struct device *dev) { … } /** * rio_is_switch- Tests if a RIO device has switch capabilities * @rdev: RIO device * * Gets the RIO device Processing Element Features register * contents and tests for switch capabilities. Returns 1 if * the device is a switch or 0 if it is not a switch. * The RIO device struct is freed. */ static int rio_is_switch(struct rio_dev *rdev) { … } /** * rio_setup_device- Allocates and sets up a RIO device * @net: RIO network * @port: Master port to send transactions * @destid: Current destination ID * @hopcount: Current hopcount * @do_enum: Enumeration/Discovery mode flag * * Allocates a RIO device and configures fields based on configuration * space contents. If device has a destination ID register, a destination * ID is either assigned in enumeration mode or read from configuration * space in discovery mode. If the device has switch capabilities, then * a switch is allocated and configured appropriately. Returns a pointer * to a RIO device on success or NULL on failure. * */ static struct rio_dev *rio_setup_device(struct rio_net *net, struct rio_mport *port, u16 destid, u8 hopcount, int do_enum) { … } /** * rio_sport_is_active- Tests if a switch port has an active connection. * @rdev: RapidIO device object * @sp: Switch port number * * Reads the port error status CSR for a particular switch port to * determine if the port has an active link. Returns * %RIO_PORT_N_ERR_STS_PORT_OK if the port is active or %0 if it is * inactive. */ static int rio_sport_is_active(struct rio_dev *rdev, int sp) { … } /** * rio_get_host_deviceid_lock- Reads the Host Device ID Lock CSR on a device * @port: Master port to send transaction * @hopcount: Number of hops to the device * * Used during enumeration to read the Host Device ID Lock CSR on a * RIO device. Returns the value of the lock register. */ static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount) { … } /** * rio_enum_peer- Recursively enumerate a RIO network through a master port * @net: RIO network being enumerated * @port: Master port to send transactions * @hopcount: Number of hops into the network * @prev: Previous RIO device connected to the enumerated one * @prev_port: Port on previous RIO device * * Recursively enumerates a RIO network. Transactions are sent via the * master port passed in @port. */ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port, u8 hopcount, struct rio_dev *prev, int prev_port) { … } /** * rio_enum_complete- Tests if enumeration of a network is complete * @port: Master port to send transaction * * Tests the PGCCSR discovered bit for non-zero value (enumeration * complete flag). Return %1 if enumeration is complete or %0 if * enumeration is incomplete. */ static int rio_enum_complete(struct rio_mport *port) { … } /** * rio_disc_peer- Recursively discovers a RIO network through a master port * @net: RIO network being discovered * @port: Master port to send transactions * @destid: Current destination ID in network * @hopcount: Number of hops into the network * @prev: previous rio_dev * @prev_port: previous port number * * Recursively discovers a RIO network. Transactions are sent via the * master port passed in @port. */ static int rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, u8 hopcount, struct rio_dev *prev, int prev_port) { … } /** * rio_mport_is_active- Tests if master port link is active * @port: Master port to test * * Reads the port error status CSR for the master port to * determine if the port has an active link. Returns * %RIO_PORT_N_ERR_STS_PORT_OK if the master port is active * or %0 if it is inactive. */ static int rio_mport_is_active(struct rio_mport *port) { … } static void rio_scan_release_net(struct rio_net *net) { … } static void rio_scan_release_dev(struct device *dev) { … } /* * rio_scan_alloc_net - Allocate and configure a new RIO network * @mport: Master port associated with the RIO network * @do_enum: Enumeration/Discovery mode flag * @start: logical minimal start id for new net * * Allocates a new RIO network structure and initializes enumerator-specific * part of it (if required). * Returns a RIO network pointer on success or %NULL on failure. */ static struct rio_net *rio_scan_alloc_net(struct rio_mport *mport, int do_enum, u16 start) { … } /** * rio_update_route_tables- Updates route tables in switches * @net: RIO network to run update on * * For each enumerated device, ensure that each switch in a system * has correct routing entries. Add routes for devices that where * unknown during the first enumeration pass through the switch. */ static void rio_update_route_tables(struct rio_net *net) { … } /** * rio_init_em - Initializes RIO Error Management (for switches) * @rdev: RIO device * * For each enumerated switch, call device-specific error management * initialization routine (if supplied by the switch driver). */ static void rio_init_em(struct rio_dev *rdev) { … } /** * rio_enum_mport- Start enumeration through a master port * @mport: Master port to send transactions * @flags: Enumeration control flags * * Starts the enumeration process. If somebody has enumerated our * master port device, then give up. If not and we have an active * link, then start recursive peer enumeration. Returns %0 if * enumeration succeeds or %-EBUSY if enumeration fails. */ static int rio_enum_mport(struct rio_mport *mport, u32 flags) { … } /** * rio_build_route_tables- Generate route tables from switch route entries * @net: RIO network to run route tables scan on * * For each switch device, generate a route table by copying existing * route entries from the switch. */ static void rio_build_route_tables(struct rio_net *net) { … } /** * rio_disc_mport- Start discovery through a master port * @mport: Master port to send transactions * @flags: discovery control flags * * Starts the discovery process. If we have an active link, * then wait for the signal that enumeration is complete (if wait * is allowed). * When enumeration completion is signaled, start recursive * peer discovery. Returns %0 if discovery succeeds or %-EBUSY * on failure. */ static int rio_disc_mport(struct rio_mport *mport, u32 flags) { … } static struct rio_scan rio_scan_ops = …; static bool scan; module_param(scan, bool, 0); MODULE_PARM_DESC(…) …; /** * rio_basic_attach: * * When this enumeration/discovery method is loaded as a module this function * registers its specific enumeration and discover routines for all available * RapidIO mport devices. The "scan" command line parameter controls ability of * the module to start RapidIO enumeration/discovery automatically. * * Returns 0 for success or -EIO if unable to register itself. * * This enumeration/discovery method cannot be unloaded and therefore does not * provide a matching cleanup_module routine. */ static int __init rio_basic_attach(void) { … } late_initcall(rio_basic_attach); MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;