linux/drivers/rapidio/devices/tsi721.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * RapidIO mport driver for Tsi721 PCIExpress-to-SRIO bridge
 *
 * Copyright 2011 Integrated Device Technology, Inc.
 * Alexandre Bounine <[email protected]>
 * Chul Kim <[email protected]>
 */

#include <linux/io.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/rio.h>
#include <linux/rio_drv.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/kfifo.h>
#include <linux/delay.h>

#include "tsi721.h"

#ifdef DEBUG
u32 tsi_dbg_level;
module_param_named(dbg_level, tsi_dbg_level, uint, S_IWUSR | S_IRUGO);
MODULE_PARM_DESC();
#endif

static int pcie_mrrs =;
module_param(pcie_mrrs, int, S_IRUGO);
MODULE_PARM_DESC();

static u8 mbox_sel =;
module_param(mbox_sel, byte, S_IRUGO);
MODULE_PARM_DESC();

static DEFINE_SPINLOCK(tsi721_maint_lock);

static void tsi721_omsg_handler(struct tsi721_device *priv, int ch);
static void tsi721_imsg_handler(struct tsi721_device *priv, int ch);

/**
 * tsi721_lcread - read from local SREP config space
 * @mport: RapidIO master port info
 * @index: ID of RapdiIO interface
 * @offset: Offset into configuration space
 * @len: Length (in bytes) of the maintenance transaction
 * @data: Value to be read into
 *
 * Generates a local SREP space read.
 *
 * Returns: %0 on success or %-EINVAL on failure.
 */
static int tsi721_lcread(struct rio_mport *mport, int index, u32 offset,
			 int len, u32 *data)
{}

/**
 * tsi721_lcwrite - write into local SREP config space
 * @mport: RapidIO master port info
 * @index: ID of RapdiIO interface
 * @offset: Offset into configuration space
 * @len: Length (in bytes) of the maintenance transaction
 * @data: Value to be written
 *
 * Generates a local write into SREP configuration space.
 *
 * Returns: %0 on success or %-EINVAL on failure.
 */
static int tsi721_lcwrite(struct rio_mport *mport, int index, u32 offset,
			  int len, u32 data)
{}

/**
 * tsi721_maint_dma - Helper function to generate RapidIO maintenance
 *                    transactions using designated Tsi721 DMA channel.
 * @priv: pointer to tsi721 private data
 * @sys_size: RapdiIO transport system size
 * @destid: Destination ID of transaction
 * @hopcount: Number of hops to target device
 * @offset: Offset into configuration space
 * @len: Length (in bytes) of the maintenance transaction
 * @data: Location to be read from or write into
 * @do_wr: Operation flag (1 == MAINT_WR)
 *
 * Generates a RapidIO maintenance transaction (Read or Write).
 * Returns: %0 on success and %-EINVAL or %-EFAULT on failure.
 */
static int tsi721_maint_dma(struct tsi721_device *priv, u32 sys_size,
			u16 destid, u8 hopcount, u32 offset, int len,
			u32 *data, int do_wr)
{}

/**
 * tsi721_cread_dma - Generate a RapidIO maintenance read transaction
 *                    using Tsi721 BDMA engine.
 * @mport: RapidIO master port control structure
 * @index: ID of RapdiIO interface
 * @destid: Destination ID of transaction
 * @hopcount: Number of hops to target device
 * @offset: Offset into configuration space
 * @len: Length (in bytes) of the maintenance transaction
 * @data: Location to be read into
 *
 * Generates a RapidIO maintenance read transaction.
 * Returns: %0 on success and %-EINVAL or %-EFAULT on failure.
 */
static int tsi721_cread_dma(struct rio_mport *mport, int index, u16 destid,
			u8 hopcount, u32 offset, int len, u32 *data)
{}

/**
 * tsi721_cwrite_dma - Generate a RapidIO maintenance write transaction
 *                     using Tsi721 BDMA engine
 * @mport: RapidIO master port control structure
 * @index: ID of RapdiIO interface
 * @destid: Destination ID of transaction
 * @hopcount: Number of hops to target device
 * @offset: Offset into configuration space
 * @len: Length (in bytes) of the maintenance transaction
 * @data: Value to be written
 *
 * Generates a RapidIO maintenance write transaction.
 * Returns: %0 on success and %-EINVAL or %-EFAULT on failure.
 */
static int tsi721_cwrite_dma(struct rio_mport *mport, int index, u16 destid,
			 u8 hopcount, u32 offset, int len, u32 data)
{}

/**
 * tsi721_pw_handler - Tsi721 inbound port-write interrupt handler
 * @priv:  tsi721 device private structure
 *
 * Handles inbound port-write interrupts. Copies PW message from an internal
 * buffer into PW message FIFO and schedules deferred routine to process
 * queued messages.
 *
 * Returns: %0
 */
static int
tsi721_pw_handler(struct tsi721_device *priv)
{}

static void tsi721_pw_dpc(struct work_struct *work)
{}

/**
 * tsi721_pw_enable - enable/disable port-write interface init
 * @mport: Master port implementing the port write unit
 * @enable:    1=enable; 0=disable port-write message handling
 *
 * Returns: %0
 */
static int tsi721_pw_enable(struct rio_mport *mport, int enable)
{}

/**
 * tsi721_dsend - Send a RapidIO doorbell
 * @mport: RapidIO master port info
 * @index: ID of RapidIO interface
 * @destid: Destination ID of target device
 * @data: 16-bit info field of RapidIO doorbell
 *
 * Sends a RapidIO doorbell message.
 *
 * Returns: %0
 */
static int tsi721_dsend(struct rio_mport *mport, int index,
			u16 destid, u16 data)
{}

/**
 * tsi721_dbell_handler - Tsi721 doorbell interrupt handler
 * @priv: tsi721 device-specific data structure
 *
 * Handles inbound doorbell interrupts. Copies doorbell entry from an internal
 * buffer into DB message FIFO and schedules deferred  routine to process
 * queued DBs.
 *
 * Returns: %0
 */
static int
tsi721_dbell_handler(struct tsi721_device *priv)
{}

static void tsi721_db_dpc(struct work_struct *work)
{}

/**
 * tsi721_irqhandler - Tsi721 interrupt handler
 * @irq: Linux interrupt number
 * @ptr: Pointer to interrupt-specific data (tsi721_device structure)
 *
 * Handles Tsi721 interrupts signaled using MSI and INTA. Checks reported
 * interrupt events and calls an event-specific handler(s).
 *
 * Returns: %IRQ_HANDLED or %IRQ_NONE
 */
static irqreturn_t tsi721_irqhandler(int irq, void *ptr)
{}

static void tsi721_interrupts_init(struct tsi721_device *priv)
{}

#ifdef CONFIG_PCI_MSI
/**
 * tsi721_omsg_msix - MSI-X interrupt handler for outbound messaging
 * @irq: Linux interrupt number
 * @ptr: Pointer to interrupt-specific data (tsi721_device structure)
 *
 * Handles outbound messaging interrupts signaled using MSI-X.
 *
 * Returns: %IRQ_HANDLED
 */
static irqreturn_t tsi721_omsg_msix(int irq, void *ptr)
{}

/**
 * tsi721_imsg_msix - MSI-X interrupt handler for inbound messaging
 * @irq: Linux interrupt number
 * @ptr: Pointer to interrupt-specific data (tsi721_device structure)
 *
 * Handles inbound messaging interrupts signaled using MSI-X.
 *
 * Returns: %IRQ_HANDLED
 */
static irqreturn_t tsi721_imsg_msix(int irq, void *ptr)
{}

/**
 * tsi721_srio_msix - Tsi721 MSI-X SRIO MAC interrupt handler
 * @irq: Linux interrupt number
 * @ptr: Pointer to interrupt-specific data (tsi721_device structure)
 *
 * Handles Tsi721 interrupts from SRIO MAC.
 *
 * Returns: %IRQ_HANDLED
 */
static irqreturn_t tsi721_srio_msix(int irq, void *ptr)
{}

/**
 * tsi721_sr2pc_ch_msix - Tsi721 MSI-X SR2PC Channel interrupt handler
 * @irq: Linux interrupt number
 * @ptr: Pointer to interrupt-specific data (tsi721_device structure)
 *
 * Handles Tsi721 interrupts from SR2PC Channel.
 * NOTE: At this moment services only one SR2PC channel associated with inbound
 * doorbells.
 *
 * Returns: %IRQ_HANDLED
 */
static irqreturn_t tsi721_sr2pc_ch_msix(int irq, void *ptr)
{}

/**
 * tsi721_request_msix - register interrupt service for MSI-X mode.
 * @priv: tsi721 device-specific data structure
 *
 * Registers MSI-X interrupt service routines for interrupts that are active
 * immediately after mport initialization. Messaging interrupt service routines
 * should be registered during corresponding open requests.
 *
 * Returns: %0 on success or -errno value on failure.
 */
static int tsi721_request_msix(struct tsi721_device *priv)
{}

/**
 * tsi721_enable_msix - Attempts to enable MSI-X support for Tsi721.
 * @priv: pointer to tsi721 private data
 *
 * Configures MSI-X support for Tsi721. Supports only an exact number
 * of requested vectors.
 *
 * Returns: %0 on success or -errno value on failure.
 */
static int tsi721_enable_msix(struct tsi721_device *priv)
{}
#endif /* CONFIG_PCI_MSI */

static int tsi721_request_irq(struct tsi721_device *priv)
{}

static void tsi721_free_irq(struct tsi721_device *priv)
{}

static int
tsi721_obw_alloc(struct tsi721_device *priv, struct tsi721_obw_bar *pbar,
		 u32 size, int *win_id)
{}

static int tsi721_map_outb_win(struct rio_mport *mport, u16 destid, u64 rstart,
			u32 size, u32 flags, dma_addr_t *laddr)
{}

static void tsi721_unmap_outb_win(struct rio_mport *mport,
				  u16 destid, u64 rstart)
{}

/**
 * tsi721_init_pc2sr_mapping - initializes outbound (PCIe->SRIO)
 * translation regions.
 * @priv: pointer to tsi721 private data
 *
 * Disables SREP translation regions.
 */
static void tsi721_init_pc2sr_mapping(struct tsi721_device *priv)
{}

/**
 * tsi721_rio_map_inb_mem -- Mapping inbound memory region.
 * @mport: RapidIO master port
 * @lstart: Local memory space start address.
 * @rstart: RapidIO space start address.
 * @size: The mapping region size.
 * @flags: Flags for mapping. 0 for using default flags.
 *
 * Return: 0 -- Success.
 *
 * This function will create the inbound mapping
 * from rstart to lstart.
 */
static int tsi721_rio_map_inb_mem(struct rio_mport *mport, dma_addr_t lstart,
		u64 rstart, u64 size, u32 flags)
{}

/**
 * tsi721_rio_unmap_inb_mem -- Unmapping inbound memory region.
 * @mport: RapidIO master port
 * @lstart: Local memory space start address.
 */
static void tsi721_rio_unmap_inb_mem(struct rio_mport *mport,
				dma_addr_t lstart)
{}

/**
 * tsi721_init_sr2pc_mapping - initializes inbound (SRIO->PCIe)
 * translation regions.
 * @priv: pointer to tsi721 private data
 *
 * Disables inbound windows.
 */
static void tsi721_init_sr2pc_mapping(struct tsi721_device *priv)
{}

/*
 * tsi721_close_sr2pc_mapping - closes all active inbound (SRIO->PCIe)
 * translation regions.
 * @priv: pointer to tsi721 device private data
 */
static void tsi721_close_sr2pc_mapping(struct tsi721_device *priv)
{}

/**
 * tsi721_port_write_init - Inbound port write interface init
 * @priv: pointer to tsi721 private data
 *
 * Initializes inbound port write handler.
 * Returns: %0 on success or %-ENOMEM on failure.
 */
static int tsi721_port_write_init(struct tsi721_device *priv)
{}

static void tsi721_port_write_free(struct tsi721_device *priv)
{}

static int tsi721_doorbell_init(struct tsi721_device *priv)
{}

static void tsi721_doorbell_free(struct tsi721_device *priv)
{}

/**
 * tsi721_bdma_maint_init - Initialize maintenance request BDMA channel.
 * @priv: pointer to tsi721 private data
 *
 * Initialize BDMA channel allocated for RapidIO maintenance read/write
 * request generation
 *
 * Returns: %0 on success or %-ENOMEM on failure.
 */
static int tsi721_bdma_maint_init(struct tsi721_device *priv)
{}

static int tsi721_bdma_maint_free(struct tsi721_device *priv)
{}

/* Enable Inbound Messaging Interrupts */
static void
tsi721_imsg_interrupt_enable(struct tsi721_device *priv, int ch,
				  u32 inte_mask)
{}

/* Disable Inbound Messaging Interrupts */
static void
tsi721_imsg_interrupt_disable(struct tsi721_device *priv, int ch,
				   u32 inte_mask)
{}

/* Enable Outbound Messaging interrupts */
static void
tsi721_omsg_interrupt_enable(struct tsi721_device *priv, int ch,
				  u32 inte_mask)
{}

/* Disable Outbound Messaging interrupts */
static void
tsi721_omsg_interrupt_disable(struct tsi721_device *priv, int ch,
				   u32 inte_mask)
{}

/**
 * tsi721_add_outb_message - Add message to the Tsi721 outbound message queue
 * @mport: Master port with outbound message queue
 * @rdev: Target of outbound message
 * @mbox: Outbound mailbox
 * @buffer: Message to add to outbound queue
 * @len: Length of message
 *
 * Returns: %0 on success or -errno value on failure.
 */
static int
tsi721_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
			void *buffer, size_t len)
{}

/**
 * tsi721_omsg_handler - Outbound Message Interrupt Handler
 * @priv: pointer to tsi721 private data
 * @ch:   number of OB MSG channel to service
 *
 * Services channel interrupts from outbound messaging engine.
 */
static void tsi721_omsg_handler(struct tsi721_device *priv, int ch)
{}

/**
 * tsi721_open_outb_mbox - Initialize Tsi721 outbound mailbox
 * @mport: Master port implementing Outbound Messaging Engine
 * @dev_id: Device specific pointer to pass on event
 * @mbox: Mailbox to open
 * @entries: Number of entries in the outbound mailbox ring
 *
 * Returns: %0 on success or -errno value on failure.
 */
static int tsi721_open_outb_mbox(struct rio_mport *mport, void *dev_id,
				 int mbox, int entries)
{}

/**
 * tsi721_close_outb_mbox - Close Tsi721 outbound mailbox
 * @mport: Master port implementing the outbound message unit
 * @mbox: Mailbox to close
 */
static void tsi721_close_outb_mbox(struct rio_mport *mport, int mbox)
{}

/**
 * tsi721_imsg_handler - Inbound Message Interrupt Handler
 * @priv: pointer to tsi721 private data
 * @ch: inbound message channel number to service
 *
 * Services channel interrupts from inbound messaging engine.
 */
static void tsi721_imsg_handler(struct tsi721_device *priv, int ch)
{}

/**
 * tsi721_open_inb_mbox - Initialize Tsi721 inbound mailbox
 * @mport: Master port implementing the Inbound Messaging Engine
 * @dev_id: Device specific pointer to pass on event
 * @mbox: Mailbox to open
 * @entries: Number of entries in the inbound mailbox ring
 *
 * Returns: %0 on success or -errno value on failure.
 */
static int tsi721_open_inb_mbox(struct rio_mport *mport, void *dev_id,
				int mbox, int entries)
{}

/**
 * tsi721_close_inb_mbox - Shut down Tsi721 inbound mailbox
 * @mport: Master port implementing the Inbound Messaging Engine
 * @mbox: Mailbox to close
 */
static void tsi721_close_inb_mbox(struct rio_mport *mport, int mbox)
{}

/**
 * tsi721_add_inb_buffer - Add buffer to the Tsi721 inbound message queue
 * @mport: Master port implementing the Inbound Messaging Engine
 * @mbox: Inbound mailbox number
 * @buf: Buffer to add to inbound queue
 *
 * Returns: %0 on success or -errno value on failure.
 */
static int tsi721_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf)
{}

/**
 * tsi721_get_inb_message - Fetch inbound message from the Tsi721 MSG Queue
 * @mport: Master port implementing the Inbound Messaging Engine
 * @mbox: Inbound mailbox number
 *
 * Returns: pointer to the message on success or %NULL on failure.
 */
static void *tsi721_get_inb_message(struct rio_mport *mport, int mbox)
{}

/**
 * tsi721_messages_init - Initialization of Messaging Engine
 * @priv: pointer to tsi721 private data
 *
 * Configures Tsi721 messaging engine.
 *
 * Returns: %0
 */
static int tsi721_messages_init(struct tsi721_device *priv)
{}

/**
 * tsi721_query_mport - Fetch inbound message from the Tsi721 MSG Queue
 * @mport: Master port implementing the Inbound Messaging Engine
 * @attr: mport device attributes
 *
 * Returns: pointer to the message on success or %NULL on failure.
 */
static int tsi721_query_mport(struct rio_mport *mport,
			      struct rio_mport_attr *attr)
{}

/**
 * tsi721_disable_ints - disables all device interrupts
 * @priv: pointer to tsi721 private data
 */
static void tsi721_disable_ints(struct tsi721_device *priv)
{}

static struct rio_ops tsi721_rio_ops =;

static void tsi721_mport_release(struct device *dev)
{}

/**
 * tsi721_setup_mport - Setup Tsi721 as RapidIO subsystem master port
 * @priv: pointer to tsi721 private data
 *
 * Configures Tsi721 as RapidIO master port.
 *
 * Returns: %0 on success or -errno value on failure.
 */
static int tsi721_setup_mport(struct tsi721_device *priv)
{}

static int tsi721_probe(struct pci_dev *pdev,
				  const struct pci_device_id *id)
{}

static void tsi721_remove(struct pci_dev *pdev)
{}

static void tsi721_shutdown(struct pci_dev *pdev)
{}

static const struct pci_device_id tsi721_pci_tbl[] =;

MODULE_DEVICE_TABLE(pci, tsi721_pci_tbl);

static struct pci_driver tsi721_driver =;

module_pci_driver();

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();