04b9ce8e32
Manual verification on switch (TH3 device) admin@str2-xxxxx-01:~$ bcmcmd bsv bsv BRCM SAI ver: [6.0.0.10], OCP SAI ver: [1.9.1], SDK ver: [sdk-6.5.23] drivshell> admin@str2-xxxxx-01:~$ bcmcmd version version Broadcom Command Monitor: Copyright (c) 1998-2021 Broadcom Release: sdk-6.5.23 built 20211020 (Wed Oct 20 06:52:58 2021) From root@fedbbfdbee81:/__w/2/s/output/x86-xgsall-deb/hsdk Platform: X86 OS: Unix (Posix) Chips: BCM56640_A0, BCM56850_A0, BCM56340_A0, BCM56960_A0, BCM56860_A0, BCM56970_A0, BCM56870_A0, BCM56980_A0, BCM56980_B0, BCM56370_A0, BCM56275_A0, BCM56770_A0, Chips: BCM56780_A0, BCM56782_A0, BCM56784_A0, BCM56785_A0, BCM56786_A0, BCM56787_A0, BCM56788_A0, BCM56789_A0, BCM56880_A0, BCM56880_B0, BCM56881_A0, BCM56881_B0, BCM56883_A0, BCM56883_B0, BCM56990_A0, BCM56990_B0, BCM56991_B0, BCM56992_B0, BCM56996_A0, BCM56996_B0, BCM56997_A0, BCM56997_B0 Variant drivers: BCM56780_A0_CNA_1_2_10, BCM56780_A0_DNA_2_7_6_0, BCM56880_A0_CNA_1_2_9, BCM56880_A0_DNA_4_9_5_0 PHYs: BCM5400, BCM54182, BCM54185, BCM54180, BCM54140, BCM54192, BCM54195, BCM54190, BCM54194, BCM54210, BCM54220, BCM54280, BCM54282, BCM54240, BCM54285, BCM5428X, BCM54290, BCM54292, BCM54294, BCM54295, BCM54296, BCM56160-GPHY, BCM53540-GPHY, BCM56275-GPHY, BCM8750, BCM8752, BCM8754, BCM84740, BCM84164, BCM84758, BCM84780, BCM84784, BCM84318, BCM84328, Sesto, BCM82780, copper sfp drivshell>
885 lines
22 KiB
C
885 lines
22 KiB
C
/*! \file ngbde.h
|
|
*
|
|
* Shared definitions and APIs for NGBDE kernel module.
|
|
*
|
|
*/
|
|
/*
|
|
* $Copyright: Copyright 2018-2021 Broadcom. All rights reserved.
|
|
* The term 'Broadcom' refers to Broadcom Inc. and/or its subsidiaries.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* version 2 as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* A copy of the GNU General Public License version 2 (GPLv2) can
|
|
* be found in the LICENSES folder.$
|
|
*/
|
|
|
|
#ifndef NGBDE_H
|
|
#define NGBDE_H
|
|
|
|
#include <lkm/lkm.h>
|
|
#include <lkm/ngbde_kapi.h>
|
|
|
|
/*! Module name. */
|
|
#define MOD_NAME "linux_ngbde"
|
|
|
|
/*! Major number for associated charcter device file. */
|
|
#define MOD_MAJOR 120
|
|
|
|
/*! Read memory-mapped device register without byte-swap. */
|
|
#define NGBDE_IOREAD32(_a) __raw_readl(_a)
|
|
|
|
/*! Write memory-mapped device register without byte-swap. */
|
|
#define NGBDE_IOWRITE32(_v, _a) __raw_writel(_v, _a)
|
|
|
|
/*! Maximum number of I/O windows supported per device. */
|
|
#define NGBDE_NUM_IOWIN_MAX 3
|
|
|
|
/*! Maximum number of DMA memory pools supported per device. */
|
|
#define NGBDE_NUM_DMAPOOL_MAX 2
|
|
|
|
/*! Maximum number of IRQ status registers per interrupt source. */
|
|
#define NGBDE_NUM_IRQ_REGS_MAX 16
|
|
|
|
/*! Maximum number of IRQ lines (MSI vectors) per device. */
|
|
#define NGBDE_NUM_IRQS_MAX 1
|
|
|
|
/*!
|
|
* Maximum number of interrupt controller registers which may be
|
|
* written from both a user mode driver and a kernel mode driver.
|
|
*
|
|
* This feature is used when the kernel mode driver owns a subset of
|
|
* bits within a register, which is also used by the user mode driver.
|
|
*
|
|
* Both drivers must access such registers through a lock-protected
|
|
* access function.
|
|
*/
|
|
#define NGBDE_NUM_INTR_SHR_REGS_MAX 1
|
|
|
|
/*! I/O memory window definition. */
|
|
struct ngbde_memwin_s {
|
|
|
|
/*! Physical address of I/O window. */
|
|
phys_addr_t addr;
|
|
|
|
/*! Size of I/O window (in bytes). */
|
|
phys_addr_t size;
|
|
};
|
|
|
|
/*!
|
|
* \brief Shared register value.
|
|
*
|
|
* This structure contains the current value of a register where user
|
|
* mode and kernel mode owns different bits within the same
|
|
* register. In this case access must be carefully controlled to avoid
|
|
* that one context overwrites the bits owned by the other context.
|
|
*
|
|
* The structure also contains the offset of the shared register in
|
|
* order to identify the register (in case there is more than one
|
|
* shared register).
|
|
*/
|
|
typedef struct ngbde_shr_reg_s {
|
|
|
|
/*! Offset of the shared register. */
|
|
uint32_t reg_offs;
|
|
|
|
/*! Current value of the shared register. */
|
|
uint32_t cur_val;
|
|
|
|
} ngbde_shr_reg_t;
|
|
|
|
/*!
|
|
* \brief Shared interrupt mask register control.
|
|
*
|
|
* This defines which bits of an interrupt mask register are owned by
|
|
* user mode context, and which are owned by kernel context.
|
|
*
|
|
* The structure contains the corresponding interrupt status register
|
|
* in order to allow identification of the interrupt mask register
|
|
* irrespective of the host CPU being used.
|
|
*
|
|
* For example, if the host CPU is connected via PCI, then we use one
|
|
* mask register, but if the host CPU is an embedded ARM CPU, then we
|
|
* use a different mask register (for the same interrupt status
|
|
* register). By using the status register to identify the shared mask
|
|
* register, the kernel mode driver does not need to know which host
|
|
* CPU it is running off.
|
|
*/
|
|
typedef struct ngbde_irq_reg_s {
|
|
|
|
/*! Interrupt status register corresponding to the mask register. */
|
|
uint32_t status_reg;
|
|
|
|
/*! Interrupt status register is a bitwise AND of mask and raw status. */
|
|
bool status_is_masked;
|
|
|
|
/*! Shared interrupt mask register. */
|
|
uint32_t mask_reg;
|
|
|
|
/*! Mask register is of type "write 1 to clear". */
|
|
bool mask_w1tc;
|
|
|
|
/*! Mask identifying the register bits owned by the kernel mode driver. */
|
|
uint32_t kmask;
|
|
|
|
} ngbde_irq_reg_t;
|
|
|
|
/*!
|
|
* \name Interrupt ACK register access flags.
|
|
* \anchor NGBDE_INTR_ACK_F_xxx
|
|
*/
|
|
|
|
/*! \{ */
|
|
|
|
/*! ACK registers resides in PCI bridge I/O window. */
|
|
#define NGBDE_INTR_ACK_F_PAXB (1 << 0)
|
|
|
|
/*! \} */
|
|
|
|
/*!
|
|
* \brief Interrupt ACK register control.
|
|
*
|
|
* The structure contains the corresponding register offset
|
|
* and value in order to acknowledge interrupt in kernel driver.
|
|
*
|
|
* For example, if the host CPU is connected via PCI, then we use one
|
|
* ACK register, but if the host CPU is an embedded ARM CPU, then we
|
|
* use a different ACK register.
|
|
*/
|
|
typedef struct ngbde_intr_ack_reg_s {
|
|
|
|
/*! Ack register offset. */
|
|
uint32_t ack_reg;
|
|
|
|
/*! Ack value. */
|
|
uint32_t ack_val;
|
|
|
|
/*! Flags to indicate ack_reg resides in PCI bridge window. */
|
|
uint32_t flags;
|
|
|
|
} ngbde_intr_ack_reg_t;
|
|
|
|
/*!
|
|
* \brief BDE interrupt handler.
|
|
*
|
|
* The BDE will use a function of this type to register an interrupt
|
|
* handler with the Linux kernel.
|
|
*
|
|
* \param [in] data Interrupt handler context.
|
|
*
|
|
* \retval 0 Interrupt not recognized.
|
|
* \retval 1 Interrupt recognized and handled.
|
|
*/
|
|
typedef int (*ngbde_isr_f)(void *data);
|
|
|
|
/*!
|
|
* \brief Kernel interrupt control.
|
|
*
|
|
* This structure controls the sharing of interrupt processing between
|
|
* a user mode thread and a kernel mode interrupt handler.
|
|
*/
|
|
typedef struct ngbde_intr_ctrl_s {
|
|
|
|
/*! Handle for device I/O (for writing interrupt registers). */
|
|
uint8_t *iomem;
|
|
|
|
/*! Kernel device number (similar to user mode unit number). */
|
|
int kdev;
|
|
|
|
/*! Indicates that our interrupt handler is connected to the kernel. */
|
|
int irq_active;
|
|
|
|
/*! Interrupt number (IRQ# or MSI vector). */
|
|
int irq_vect;
|
|
|
|
/*! Number of interrupt status/mask register pairs. */
|
|
int num_regs;
|
|
|
|
/*! Interrupt status/mask register pairs for this device. */
|
|
ngbde_irq_reg_t regs[NGBDE_NUM_IRQ_REGS_MAX];
|
|
|
|
/*! Interrupt ACK register/value for this device. */
|
|
ngbde_intr_ack_reg_t intr_ack;
|
|
|
|
/*! Wait queue for user mode interrupt thread. */
|
|
wait_queue_head_t user_thread_wq;
|
|
|
|
/*! Flag to wake up user mode interrupt thread. */
|
|
atomic_t run_user_thread;
|
|
|
|
/*! Primary interrupt handler. */
|
|
ngbde_isr_f isr_func;
|
|
|
|
/*! Context for primary interrupt handler. */
|
|
void *isr_data;
|
|
|
|
/*! Secondary interrupt handler. */
|
|
ngbde_isr_f isr2_func;
|
|
|
|
/*! Context for secondary interrupt handler. */
|
|
void *isr2_data;
|
|
|
|
} ngbde_intr_ctrl_t;
|
|
|
|
/*! Convenience macro for 1 kilobyte. */
|
|
#define ONE_KB 1024
|
|
|
|
/*! Convenience macro for 1 megabyte. */
|
|
#define ONE_MB (1024*1024)
|
|
|
|
/*!
|
|
* \name DMA allocation types.
|
|
* \anchor NGBDE_DMA_T_xxx
|
|
*/
|
|
|
|
/*! \{ */
|
|
|
|
/*!
|
|
* Do not allocate any DMA memory.
|
|
*/
|
|
#define NGBDE_DMA_T_NONE 0
|
|
|
|
/*!
|
|
* Try different allocation methods until DMA memory is successfully
|
|
* allocated.
|
|
*/
|
|
#define NGBDE_DMA_T_AUTO 1
|
|
|
|
/*! Use kernel DMA API (dma_alloc_coherent). */
|
|
#define NGBDE_DMA_T_KAPI 2
|
|
|
|
/*! Use page allocator and map to physical address manually. */
|
|
#define NGBDE_DMA_T_PGMEM 3
|
|
|
|
/*! \} */
|
|
|
|
/*! DMA memory allocation control structure. */
|
|
typedef struct ngbde_dmactrl_s {
|
|
|
|
/*! Requested size of DMA memory block (in bytes). */
|
|
size_t size;
|
|
|
|
/*! Kernel flags for memory allocation. */
|
|
gfp_t flags;
|
|
|
|
/*! Preferred DMA memory type (NGBDE_DMA_T_xxx). */
|
|
int pref_type;
|
|
|
|
/*! Kernel device for DMA memory management. */
|
|
struct device *dev;
|
|
|
|
} ngbde_dmactrl_t;
|
|
|
|
/*! DMA memory descriptor. */
|
|
typedef struct ngbde_dmamem_s {
|
|
|
|
/*! Logical address of DMA memory block. */
|
|
void *vaddr;
|
|
|
|
/*! Physical address of DMA memory block. */
|
|
dma_addr_t paddr;
|
|
|
|
/*! Bus address of DMA memory block. */
|
|
dma_addr_t baddr;
|
|
|
|
/*! Actual size of DMA memory block (in bytes). */
|
|
size_t size;
|
|
|
|
/*! Actual DMA memory type (NGBDE_DMA_T_xxx). */
|
|
int type;
|
|
|
|
/*! Kernel device for DMA memory management. */
|
|
struct device *dev;
|
|
|
|
} ngbde_dmamem_t;
|
|
|
|
/*! DMA memory pool. */
|
|
typedef struct ngbde_dmapool_s {
|
|
|
|
/*! DMA control parameters. */
|
|
struct ngbde_dmactrl_s dmactrl;
|
|
|
|
/*! DMA memory resources. */
|
|
struct ngbde_dmamem_s dmamem;
|
|
|
|
} ngbde_dmapool_t;
|
|
|
|
/*! Switch device descriptor. */
|
|
struct ngbde_dev_s {
|
|
|
|
/*! Vendor ID (typically PCI vendor ID). */
|
|
uint16_t vendor_id;
|
|
|
|
/*! Device ID (typically PCI device ID). */
|
|
uint16_t device_id;
|
|
|
|
/*! Device revision (typically PCI revision). */
|
|
uint16_t revision;
|
|
|
|
/*! Additional device identification when primary ID is not unique. */
|
|
uint16_t model;
|
|
|
|
/*! Bus number (typically PCI bus number). */
|
|
int bus_no;
|
|
|
|
/*! Slot number (typically PCI slot number). */
|
|
int slot_no;
|
|
|
|
/*! Interrupt line associated with this device. */
|
|
int irq_line;
|
|
|
|
/*! Use MSI interrupts with this device. */
|
|
int use_msi;
|
|
|
|
/*! Non-zero if device was removed. */
|
|
int inactive;
|
|
|
|
/*! Physical I/O window for kernel driver device access. */
|
|
struct ngbde_memwin_s pio_win;
|
|
|
|
/*! Memory mapped I/O window for kernel driver device access. */
|
|
uint8_t *pio_mem;
|
|
|
|
/*! Physical I/O window for interrupt controller access. */
|
|
struct ngbde_memwin_s iio_win;
|
|
|
|
/*! Memory mapped I/O window for interrupt controller access. */
|
|
uint8_t *iio_mem;
|
|
|
|
/*! Physical I/O window for device PCI bridge access. */
|
|
struct ngbde_memwin_s paxb_win;
|
|
|
|
/*! Memory mapped I/O window for device PCI bridge access. */
|
|
uint8_t *paxb_mem;
|
|
|
|
/*! Current value of shared register (typically an IRQ mask register). */
|
|
struct ngbde_shr_reg_s intr_shr_reg[NGBDE_NUM_INTR_SHR_REGS_MAX];
|
|
|
|
/*! Lock for shared register synchronization. */
|
|
spinlock_t lock;
|
|
|
|
/*! Interrupt control information. */
|
|
struct ngbde_intr_ctrl_s intr_ctrl[NGBDE_NUM_IRQS_MAX];
|
|
|
|
/*! Linux PCI handle. */
|
|
struct pci_dev *pci_dev;
|
|
|
|
/*! Kernel device for DMA memory management. */
|
|
struct device *dma_dev;
|
|
|
|
/*! Physical device I/O. */
|
|
struct ngbde_memwin_s iowin[NGBDE_NUM_IOWIN_MAX];
|
|
|
|
/*! DMA memory pools. */
|
|
struct ngbde_dmapool_s dmapool[NGBDE_NUM_DMAPOOL_MAX];
|
|
|
|
/*! KNET handler. */
|
|
knet_func_f knet_func;
|
|
|
|
/*! Context for KNET handler. */
|
|
void *knet_data;
|
|
|
|
};
|
|
|
|
/*!
|
|
* \brief Linux IOCTL handler.
|
|
*
|
|
* This function handles communication between user mode and kernel
|
|
* mode.
|
|
*
|
|
* \param [in] file Device file handle.
|
|
* \param [in] cmd IOCTL command.
|
|
* \param [in] arg IOCTL command argument.
|
|
*
|
|
* \retval 0 No errors
|
|
*/
|
|
extern long
|
|
ngbde_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
|
|
|
|
/*!
|
|
* \brief Initialize procfs for BDE driver.
|
|
*
|
|
* Create procfs read interface for dumping probe information.
|
|
*
|
|
* \return 0 if no errors, otherwise -1.
|
|
*/
|
|
extern int
|
|
ngbde_procfs_init(void);
|
|
|
|
/*!
|
|
* \brief Clean up procfs for BDE driver.
|
|
*
|
|
* Clean up resources allocated by \ref ngbde_procfs_init.
|
|
*
|
|
* \return 0 if no errors, otherwise -1.
|
|
*/
|
|
extern int
|
|
ngbde_procfs_cleanup(void);
|
|
|
|
/*!
|
|
* \brief Allocate DMA memory pools for all probed devices.
|
|
*
|
|
* \return 0 if no errors, otherwise -1.
|
|
*/
|
|
extern int
|
|
ngbde_dma_init(void);
|
|
|
|
/*!
|
|
* \brief Free DMA memory pools for all probed devices.
|
|
*
|
|
* \return Nothing.
|
|
*/
|
|
extern void
|
|
ngbde_dma_cleanup(void);
|
|
|
|
/*!
|
|
* \brief Connect to hardware interrupt handler.
|
|
*
|
|
* \param [in] kdev Device number.
|
|
* \param [in] irq_num Interrupt number (MSI vector).
|
|
*
|
|
* \retval 0 No errors
|
|
* \retval -1 Something went wrong.
|
|
*/
|
|
extern int
|
|
ngbde_intr_connect(int kdev, unsigned int irq_num);
|
|
|
|
/*!
|
|
* \brief Disconnect from hardware interrupt handler.
|
|
*
|
|
* \param [in] kdev Device number.
|
|
* \param [in] irq_num Interrupt number (MSI vector).
|
|
*
|
|
* \retval 0 No errors
|
|
* \retval -1 Something went wrong.
|
|
*/
|
|
extern int
|
|
ngbde_intr_disconnect(int kdev, unsigned int irq_num);
|
|
|
|
/*!
|
|
* \brief Disconnect from all hardware interrupt handlers.
|
|
*/
|
|
void
|
|
ngbde_intr_cleanup(void);
|
|
|
|
/*!
|
|
* \brief Wait for hardware interrupt.
|
|
*
|
|
* A user mode thread will call this function and sleep until a
|
|
* hardware interrupt occurs.
|
|
*
|
|
* \param [in] kdev Device number.
|
|
* \param [in] irq_num Interrupt number (MSI vector).
|
|
*
|
|
* \retval 0 No errors
|
|
* \retval -1 Something went wrong.
|
|
*/
|
|
extern int
|
|
ngbde_intr_wait(int kdev, unsigned int irq_num);
|
|
|
|
/*!
|
|
* \brief Wake up sleeping interrupt thread.
|
|
*
|
|
* Wake up interrupt thread even if no interrupt has occurred.
|
|
*
|
|
* Intended for graceful shut-down procedure.
|
|
*
|
|
* \param [in] kdev Device number.
|
|
* \param [in] irq_num Interrupt number (MSI vector).
|
|
*
|
|
* \retval 0 No errors
|
|
* \retval -1 Something went wrong.
|
|
*/
|
|
extern int
|
|
ngbde_intr_stop(int kdev, unsigned int irq_num);
|
|
|
|
/*!
|
|
* \brief Clear list of interrupt status/mask registers.
|
|
*
|
|
* This function is typically called before new interrupt register
|
|
* information is added.
|
|
*
|
|
* \param [in] kdev Device number.
|
|
* \param [in] irq_num Interrupt number (MSI vector).
|
|
*
|
|
* \retval 0 No errors
|
|
* \retval -1 Something went wrong.
|
|
*/
|
|
extern int
|
|
ngbde_intr_regs_clr(int kdev, unsigned int irq_num);
|
|
|
|
/*!
|
|
* \brief Add interrupt status/mask register to monitor.
|
|
*
|
|
* This function adds a new interrupt status/mask register set to the
|
|
* list of registers monitored by the user-mode interrupt handler.
|
|
*
|
|
* The register list is used to determine whether a user-mode
|
|
* interrupt has occurred.
|
|
*
|
|
* See also \ref ngbde_intr_regs_clr.
|
|
*
|
|
* \param [in] kdev Device number.
|
|
* \param [in] irq_num Interrupt number (MSI vector).
|
|
* \param [in] ireg Interrupt status/mask register information.
|
|
*
|
|
* \retval 0 No errors
|
|
* \retval -1 Something went wrong.
|
|
*/
|
|
extern int
|
|
ngbde_intr_reg_add(int kdev, unsigned int irq_num,
|
|
struct ngbde_irq_reg_s *ireg);
|
|
|
|
/*!
|
|
* \brief Add interrupt ack register to monitor.
|
|
*
|
|
* This function adds a interrupt register and mask value
|
|
* to acknowledge corresponding irq_num.
|
|
*
|
|
* \param [in] kdev Device number.
|
|
* \param [in] irq_num Interrupt number (MSI vector).
|
|
* \param [in] ackreg Interrupt ack register information.
|
|
*
|
|
* \retval 0 No errors
|
|
* \retval -1 Something went wrong.
|
|
*/
|
|
extern int
|
|
ngbde_intr_ack_reg_add(int kdev, unsigned int irq_num,
|
|
struct ngbde_intr_ack_reg_s *ackreg);
|
|
|
|
/*!
|
|
* \brief Write shared interrupt mask register.
|
|
*
|
|
* This function is used by an interrupt handler when a shared
|
|
* interrupt mask register needs to be updated.
|
|
*
|
|
* Since the register is shared between multiple interrupt handlers,
|
|
* access must be protected by a lock.
|
|
*
|
|
* The register information provided via \ref ngbde_intr_reg_add is
|
|
* used to detemine which bits of the mask register belong to the user
|
|
* mode driver.
|
|
*
|
|
* Note that the mask register to access is referenced by the
|
|
* corresponding status register. This is because the mask register
|
|
* may be different depending on the host CPU interface being used
|
|
* (e.g. PCI vs. AXI). On the other hand, the status register is the
|
|
* same irrespective of the host CPU interface.
|
|
*
|
|
* \param [in] kdev Device number.
|
|
* \param [in] irq_num Interrupt number (MSI vector).
|
|
* \param [in] kapi Must be set to 1 if called from kernel API.
|
|
* \param [in] status_reg Corresponding interrupt status register offset.
|
|
* \param [in] mask_val New value to write to mask register.
|
|
*
|
|
* \retval 0 No errors
|
|
* \retval -1 Something went wrong.
|
|
*/
|
|
extern int
|
|
ngbde_intr_mask_write(int kdev, unsigned int irq_num, int kapi,
|
|
uint32_t status_reg, uint32_t mask_val);
|
|
|
|
/*!
|
|
* \brief Probe for PCI-attached Broadcom switch devices.
|
|
*
|
|
* \return 0 if no errors, otherwise -1.
|
|
*/
|
|
extern int
|
|
ngbde_pci_probe(void);
|
|
|
|
/*!
|
|
* \brief Clean up resources for PCI-attached Broadcom switch devices.
|
|
*
|
|
* \return 0 if no errors, otherwise -1.
|
|
*/
|
|
extern int
|
|
ngbde_pci_cleanup(void);
|
|
|
|
/*!
|
|
* \brief Add new switch device to BDE database.
|
|
*
|
|
* Add device information for probed or fixed switch device.
|
|
*
|
|
* \param [in] nd Switch device information.
|
|
*
|
|
* \return 0 if no errors, otherwise -1.
|
|
*/
|
|
extern int
|
|
ngbde_swdev_add(struct ngbde_dev_s *nd);
|
|
|
|
/*!
|
|
* \brief Get device information for a BDE switch device.
|
|
*
|
|
* \param [in] kdev Switch device number.
|
|
*
|
|
* \return Pointer to switch device structure or NULL on error.
|
|
*/
|
|
struct ngbde_dev_s *
|
|
ngbde_swdev_get(int kdev);
|
|
|
|
/*!
|
|
* \brief Get list of all probed switch devices.
|
|
*
|
|
* Return a pointer to the array of registered switch devices.
|
|
*
|
|
* \param [out] nd Pointer to array of switch devices.
|
|
* \param [in] num_nd number of valid entries in switch device array.
|
|
*
|
|
* \retval 0 No errors
|
|
*/
|
|
extern int
|
|
ngbde_swdev_get_all(struct ngbde_dev_s **nd, unsigned int *num_nd);
|
|
|
|
/*!
|
|
* \brief Allocate memory using page allocator
|
|
*
|
|
* For any sizes less than MEM_CHUNK_SIZE, we ask the page allocator
|
|
* for the entire memory block, otherwise we try to assemble a
|
|
* contiguous cmblock ourselves.
|
|
*
|
|
* Upon successful allocation, the memory block will be added to the
|
|
* global list of allocated memory blocks.
|
|
*
|
|
* \param [in] size Number of bytes to allocate.
|
|
* \param [in] flags Kernel flags (GFP_xxx) for memory allocation.
|
|
*
|
|
* \return Pointer to allocated memory or NULL if failure.
|
|
*/
|
|
void *
|
|
ngbde_pgmem_alloc(size_t size, gfp_t flags);
|
|
|
|
/*!
|
|
* \brief Free memory block allocated by ngbde_pgmem_alloc.
|
|
*
|
|
* \param [in] ptr Pointer returned by ngbde_pgmem_alloc.
|
|
*
|
|
* \return 0 if succesfully freed, otherwise -1.
|
|
*/
|
|
extern int
|
|
ngbde_pgmem_free(void *ptr);
|
|
|
|
/*!
|
|
* \brief Free all memory blocks allocated by ngbde_pgmem_alloc.
|
|
*
|
|
* This function will walk the global list of allocated memory blocks
|
|
* and free all associated resources.
|
|
*
|
|
* Intended for a full clean up before the module is unloaded.
|
|
*
|
|
* \return Nothing.
|
|
*/
|
|
extern void
|
|
ngbde_pgmem_free_all(void);
|
|
|
|
/*!
|
|
* \brief Map I/O memory in kernel driver.
|
|
*
|
|
* This function is used to provide device I/O access to a kernel mode
|
|
* driver.
|
|
*
|
|
* \param [in] devh Device handle (\ref ngbde_dev_s).
|
|
* \param [in] addr Physical address to map.
|
|
* \param [in] size Size of I/O window to map.
|
|
*
|
|
* \return Pointer to mapped I/O memory, or NULL on error.
|
|
*/
|
|
extern void *
|
|
ngbde_pio_map(void *devh, phys_addr_t addr, phys_addr_t size);
|
|
|
|
/*!
|
|
* \brief Unmap I/O memory in kernel driver.
|
|
*
|
|
* Unmap I/O memory previously mapped via \ref ngbde_pio_map.
|
|
*
|
|
* \param [in] devh Device handle (\ref ngbde_dev_s).
|
|
*
|
|
* \return Nothing.
|
|
*/
|
|
extern void
|
|
ngbde_pio_unmap(void *devh);
|
|
|
|
/*!
|
|
* \brief Unmap all I/O windows.
|
|
*/
|
|
extern void
|
|
ngbde_pio_cleanup(void);
|
|
|
|
/*!
|
|
* \brief Write a memory-mapped register from kernel driver.
|
|
*
|
|
* Write a 32-bit register using I/O memory previously mapped via \ref
|
|
* ngbde_pio_map.
|
|
*
|
|
* \param [in] devh Device handle (\ref ngbde_dev_s).
|
|
* \param [in] offs Register address offset.
|
|
* \param [in] val Value to write to register.
|
|
*
|
|
* \return Nothing.
|
|
*/
|
|
extern void
|
|
ngbde_pio_write32(void *devh, uint32_t offs, uint32_t val);
|
|
|
|
/*!
|
|
* \brief Read a memory-mapped register from kernel driver.
|
|
*
|
|
* Read a 32-bit register using I/O memory previously mapped via \ref
|
|
* ngbde_pio_map.
|
|
*
|
|
* \param [in] devh Device handle (\ref ngbde_dev_s).
|
|
* \param [in] offs Register address offset.
|
|
*
|
|
* \return Value read from register.
|
|
*/
|
|
extern uint32_t
|
|
ngbde_pio_read32(void *devh, uint32_t offs);
|
|
|
|
/*!
|
|
* \brief Map interrupt controller I/O memory.
|
|
*
|
|
* On some devices the interrupt controller is a device separate from
|
|
* the main switch device. This function is used to provide interrupt
|
|
* controller I/O access to a kernel mode driver.
|
|
*
|
|
* \param [in] devh Device handle (\ref ngbde_dev_s).
|
|
* \param [in] addr Physical address to map.
|
|
* \param [in] size Size of I/O window to map.
|
|
*
|
|
* \return Pointer to mapped I/O memory, or NULL on error.
|
|
*/
|
|
extern void *
|
|
ngbde_iio_map(void *devh, phys_addr_t addr, phys_addr_t size);
|
|
|
|
/*!
|
|
* \brief Unmap interrupt controller I/O memory.
|
|
*
|
|
* Unmap I/O memory previously mapped via \ref ngbde_iio_map.
|
|
*
|
|
* \param [in] devh Device handle (\ref ngbde_dev_s).
|
|
*
|
|
* \return Nothing.
|
|
*/
|
|
extern void
|
|
ngbde_iio_unmap(void *devh);
|
|
|
|
/*!
|
|
* \brief Unmap all interrupt controller I/O windows.
|
|
*/
|
|
extern void
|
|
ngbde_iio_cleanup(void);
|
|
|
|
/*!
|
|
* \brief Write a memory-mapped interrupt controller register.
|
|
*
|
|
* Write a 32-bit register using I/O memory previously mapped via \ref
|
|
* ngbde_iio_map.
|
|
*
|
|
* \param [in] devh Device handle (\ref ngbde_dev_s).
|
|
* \param [in] offs Register address offset.
|
|
* \param [in] val Value to write to register.
|
|
*
|
|
* \return Nothing.
|
|
*/
|
|
extern void
|
|
ngbde_iio_write32(void *devh, uint32_t offs, uint32_t val);
|
|
|
|
/*!
|
|
* \brief Read a memory-mapped interrupt controller register.
|
|
*
|
|
* Read a 32-bit register using I/O memory previously mapped via \ref
|
|
* ngbde_iio_map.
|
|
*
|
|
* \param [in] devh Device handle (\ref ngbde_dev_s).
|
|
* \param [in] offs Register address offset.
|
|
*
|
|
* \return Value read from register.
|
|
*/
|
|
extern uint32_t
|
|
ngbde_iio_read32(void *devh, uint32_t offs);
|
|
|
|
/*!
|
|
* \brief Map PCI bridge I/O memory.
|
|
*
|
|
* On some devices the interrupt controller is a device separate from
|
|
* the main switch device. This function is used to provide interrupt
|
|
* controller I/O access to a kernel mode driver.
|
|
*
|
|
* \param [in] devh Device handle (\ref ngbde_dev_s).
|
|
* \param [in] addr Physical address to map.
|
|
* \param [in] size Size of I/O window to map.
|
|
*
|
|
* \return Pointer to mapped I/O memory, or NULL on error.
|
|
*/
|
|
extern void *
|
|
ngbde_paxb_map(void *devh, phys_addr_t addr, phys_addr_t size);
|
|
|
|
/*!
|
|
* \brief Unmap PCI bridge I/O memory.
|
|
*
|
|
* Unmap I/O memory previously mapped via \ref ngbde_paxb_map.
|
|
*
|
|
* \param [in] devh Device handle (\ref ngbde_dev_s).
|
|
*
|
|
* \return Nothing.
|
|
*/
|
|
extern void
|
|
ngbde_paxb_unmap(void *devh);
|
|
|
|
/*!
|
|
* \brief Unmap all PCI bridge I/O windows.
|
|
*/
|
|
extern void
|
|
ngbde_paxb_cleanup(void);
|
|
|
|
/*!
|
|
* \brief Write a memory-mapped PCI bridge register.
|
|
*
|
|
* Write a 32-bit register using I/O memory previously mapped via \ref
|
|
* ngbde_paxb_map.
|
|
*
|
|
* \param [in] devh Device handle (\ref ngbde_dev_s).
|
|
* \param [in] offs Register address offset.
|
|
* \param [in] val Value to write to register.
|
|
*
|
|
* \return Nothing.
|
|
*/
|
|
extern void
|
|
ngbde_paxb_write32(void *devh, uint32_t offs, uint32_t val);
|
|
|
|
/*!
|
|
* \brief Read a memory-mapped PCI bridge register.
|
|
*
|
|
* Read a 32-bit register using I/O memory previously mapped via \ref
|
|
* ngbde_paxb_map.
|
|
*
|
|
* \param [in] devh Device handle (\ref ngbde_dev_s).
|
|
* \param [in] offs Register address offset.
|
|
*
|
|
* \return Value read from register.
|
|
*/
|
|
extern uint32_t
|
|
ngbde_paxb_read32(void *devh, uint32_t offs);
|
|
|
|
/*!
|
|
* \brief Probe for Broadcom switch devices on IPROC internal bus.
|
|
*
|
|
* \return 0 if no errors, otherwise -1.
|
|
*/
|
|
extern int
|
|
ngbde_iproc_probe(void);
|
|
|
|
/*!
|
|
* \brief Clean up resources for Broadcom switch devices on IPROC internal bus.
|
|
*
|
|
* \return 0 if no errors, otherwise -1.
|
|
*/
|
|
extern int
|
|
ngbde_iproc_cleanup(void);
|
|
|
|
#endif /* NGBDE_H */
|