3de0952fba
Submitted by: pkanneganti@cavium.com (Prasad V Kanneganti) MFC after: 1 week Sponsored by: Cavium Networks Differential Revision: https://reviews.freebsd.org/D12415
899 lines
24 KiB
C
899 lines
24 KiB
C
/*
|
|
* BSD LICENSE
|
|
*
|
|
* Copyright(c) 2017 Cavium, Inc.. All rights reserved.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in
|
|
* the documentation and/or other materials provided with the
|
|
* distribution.
|
|
* * Neither the name of Cavium, Inc. nor the names of its
|
|
* contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
/*$FreeBSD$*/
|
|
|
|
/*
|
|
* \brief Host Driver: This file defines the octeon device structure.
|
|
*/
|
|
|
|
#ifndef _LIO_DEVICE_H_
|
|
#define _LIO_DEVICE_H_
|
|
|
|
#include <sys/endian.h> /* for BYTE_ORDER */
|
|
|
|
/* PCI VendorId Device Id */
|
|
#define LIO_CN23XX_PF_PCIID 0x9702177d
|
|
/*
|
|
* Driver identifies chips by these Ids, created by clubbing together
|
|
* DeviceId+RevisionId; Where Revision Id is not used to distinguish
|
|
* between chips, a value of 0 is used for revision id.
|
|
*/
|
|
#define LIO_CN23XX_PF_VID 0x9702
|
|
#define LIO_CN2350_10G_SUBDEVICE 0x03
|
|
#define LIO_CN2350_10G_SUBDEVICE1 0x04
|
|
#define LIO_CN2360_10G_SUBDEVICE 0x05
|
|
#define LIO_CN2350_25G_SUBDEVICE 0x07
|
|
#define LIO_CN2360_25G_SUBDEVICE 0x06
|
|
|
|
|
|
/* Endian-swap modes supported by Octeon. */
|
|
enum lio_pci_swap_mode {
|
|
LIO_PCI_PASSTHROUGH = 0,
|
|
LIO_PCI_SWAP_64BIT = 1,
|
|
LIO_PCI_SWAP_32BIT = 2,
|
|
LIO_PCI_LW_SWAP_32BIT = 3
|
|
};
|
|
|
|
enum {
|
|
LIO_CFG_TYPE_DEFAULT = 0,
|
|
LIO_NUM_CFGS,
|
|
};
|
|
|
|
#define OCTEON_OUTPUT_INTR (2)
|
|
#define OCTEON_ALL_INTR 0xff
|
|
|
|
/*--------------- PCI BAR1 index registers -------------*/
|
|
|
|
/* BAR1 Mask */
|
|
#define LIO_PCI_BAR1_ENABLE_CA 1
|
|
#define LIO_PCI_BAR1_ENDIAN_MODE LIO_PCI_SWAP_64BIT
|
|
#define LIO_PCI_BAR1_ENTRY_VALID 1
|
|
#define LIO_PCI_BAR1_MASK ((LIO_PCI_BAR1_ENABLE_CA << 3) | \
|
|
(LIO_PCI_BAR1_ENDIAN_MODE << 1) | \
|
|
LIO_PCI_BAR1_ENTRY_VALID)
|
|
|
|
/*
|
|
* Octeon Device state.
|
|
* Each octeon device goes through each of these states
|
|
* as it is initialized.
|
|
*/
|
|
#define LIO_DEV_BEGIN_STATE 0x0
|
|
#define LIO_DEV_PCI_ENABLE_DONE 0x1
|
|
#define LIO_DEV_PCI_MAP_DONE 0x2
|
|
#define LIO_DEV_DISPATCH_INIT_DONE 0x3
|
|
#define LIO_DEV_INSTR_QUEUE_INIT_DONE 0x4
|
|
#define LIO_DEV_SC_BUFF_POOL_INIT_DONE 0x5
|
|
#define LIO_DEV_MSIX_ALLOC_VECTOR_DONE 0x6
|
|
#define LIO_DEV_RESP_LIST_INIT_DONE 0x7
|
|
#define LIO_DEV_DROQ_INIT_DONE 0x8
|
|
#define LIO_DEV_INTR_SET_DONE 0xa
|
|
#define LIO_DEV_IO_QUEUES_DONE 0xb
|
|
#define LIO_DEV_CONSOLE_INIT_DONE 0xc
|
|
#define LIO_DEV_HOST_OK 0xd
|
|
#define LIO_DEV_CORE_OK 0xe
|
|
#define LIO_DEV_RUNNING 0xf
|
|
#define LIO_DEV_IN_RESET 0x10
|
|
#define LIO_DEV_STATE_INVALID 0x11
|
|
|
|
#define LIO_DEV_STATES LIO_DEV_STATE_INVALID
|
|
|
|
/*
|
|
* Octeon Device interrupts
|
|
* These interrupt bits are set in int_status filed of
|
|
* octeon_device structure
|
|
*/
|
|
#define LIO_DEV_INTR_DMA0_FORCE 0x01
|
|
#define LIO_DEV_INTR_DMA1_FORCE 0x02
|
|
#define LIO_DEV_INTR_PKT_DATA 0x04
|
|
|
|
#define LIO_RESET_MSECS (3000)
|
|
|
|
/*---------------------------DISPATCH LIST-------------------------------*/
|
|
|
|
/*
|
|
* The dispatch list entry.
|
|
* The driver keeps a record of functions registered for each
|
|
* response header opcode in this structure. Since the opcode is
|
|
* hashed to index into the driver's list, more than one opcode
|
|
* can hash to the same entry, in which case the list field points
|
|
* to a linked list with the other entries.
|
|
*/
|
|
struct lio_dispatch {
|
|
/* Singly-linked tail queue node for this entry */
|
|
struct lio_stailq_node node;
|
|
|
|
/* Singly-linked tail queue head for this entry */
|
|
struct lio_stailq_head head;
|
|
|
|
/* The opcode for which the dispatch function & arg should be used */
|
|
uint16_t opcode;
|
|
|
|
/* The function to be called for a packet received by the driver */
|
|
lio_dispatch_fn_t dispatch_fn;
|
|
|
|
/*
|
|
* The application specified argument to be passed to the above
|
|
* function along with the received packet
|
|
*/
|
|
void *arg;
|
|
};
|
|
|
|
/* The dispatch list structure. */
|
|
struct lio_dispatch_list {
|
|
/* access to dispatch list must be atomic */
|
|
struct mtx lock;
|
|
|
|
/* Count of dispatch functions currently registered */
|
|
uint32_t count;
|
|
|
|
/* The list of dispatch functions */
|
|
struct lio_dispatch *dlist;
|
|
};
|
|
|
|
/*----------------------- THE OCTEON DEVICE ---------------------------*/
|
|
|
|
#define LIO_MEM_REGIONS 3
|
|
/*
|
|
* PCI address space information.
|
|
* Each of the 3 address spaces given by BAR0, BAR2 and BAR4 of
|
|
* Octeon gets mapped to different physical address spaces in
|
|
* the kernel.
|
|
*/
|
|
struct lio_mem_bus_space {
|
|
struct resource *pci_mem;
|
|
bus_space_tag_t tag;
|
|
bus_space_handle_t handle;
|
|
};
|
|
|
|
#define LIO_MAX_MAPS 32
|
|
|
|
struct lio_io_enable {
|
|
uint64_t iq;
|
|
uint64_t oq;
|
|
uint64_t iq64B;
|
|
};
|
|
|
|
struct lio_reg_list {
|
|
uint32_t pci_win_wr_addr;
|
|
|
|
uint32_t pci_win_rd_addr_hi;
|
|
uint32_t pci_win_rd_addr_lo;
|
|
uint32_t pci_win_rd_addr;
|
|
|
|
uint32_t pci_win_wr_data_hi;
|
|
uint32_t pci_win_wr_data_lo;
|
|
uint32_t pci_win_wr_data;
|
|
|
|
uint32_t pci_win_rd_data;
|
|
};
|
|
|
|
#define LIO_MAX_CONSOLE_READ_BYTES 512
|
|
|
|
typedef int (*octeon_console_print_fn)(struct octeon_device *oct,
|
|
uint32_t num, char *pre, char *suf);
|
|
struct lio_console {
|
|
uint32_t active;
|
|
uint32_t waiting;
|
|
uint64_t addr;
|
|
uint32_t buffer_size;
|
|
uint64_t input_base_addr;
|
|
uint64_t output_base_addr;
|
|
octeon_console_print_fn print;
|
|
char leftover[LIO_MAX_CONSOLE_READ_BYTES];
|
|
};
|
|
|
|
struct lio_board_info {
|
|
char name[LIO_BOARD_NAME];
|
|
char serial_number[LIO_SERIAL_NUM_LEN];
|
|
uint64_t major;
|
|
uint64_t minor;
|
|
};
|
|
|
|
struct lio_fn_list {
|
|
void (*setup_iq_regs) (struct octeon_device *, uint32_t);
|
|
void (*setup_oq_regs) (struct octeon_device *, uint32_t);
|
|
|
|
void (*process_interrupt_regs) (void *);
|
|
uint64_t (*msix_interrupt_handler) (void *);
|
|
int (*soft_reset) (struct octeon_device *);
|
|
int (*setup_device_regs) (struct octeon_device *);
|
|
void (*bar1_idx_setup) (struct octeon_device *, uint64_t,
|
|
uint32_t, int);
|
|
void (*bar1_idx_write) (struct octeon_device *, uint32_t,
|
|
uint32_t);
|
|
uint32_t (*bar1_idx_read) (struct octeon_device *, uint32_t);
|
|
uint32_t (*update_iq_read_idx) (struct lio_instr_queue *);
|
|
|
|
void (*enable_interrupt) (struct octeon_device *, uint8_t);
|
|
void (*disable_interrupt) (struct octeon_device *, uint8_t);
|
|
|
|
int (*enable_io_queues) (struct octeon_device *);
|
|
void (*disable_io_queues) (struct octeon_device *);
|
|
};
|
|
|
|
/* Must be multiple of 8, changing breaks ABI */
|
|
#define LIO_BOOTMEM_NAME_LEN 128
|
|
|
|
/*
|
|
* Structure for named memory blocks
|
|
* Number of descriptors
|
|
* available can be changed without affecting compatibility,
|
|
* but name length changes require a bump in the bootmem
|
|
* descriptor version
|
|
* Note: This structure must be naturally 64 bit aligned, as a single
|
|
* memory image will be used by both 32 and 64 bit programs.
|
|
*/
|
|
struct cvmx_bootmem_named_block_desc {
|
|
/* Base address of named block */
|
|
uint64_t base_addr;
|
|
|
|
/* Size actually allocated for named block */
|
|
uint64_t size;
|
|
|
|
/* name of named block */
|
|
char name[LIO_BOOTMEM_NAME_LEN];
|
|
};
|
|
|
|
struct lio_fw_info {
|
|
uint32_t max_nic_ports; /* max nic ports for the device */
|
|
uint32_t num_gmx_ports; /* num gmx ports */
|
|
uint64_t app_cap_flags; /* firmware cap flags */
|
|
|
|
/*
|
|
* The core application is running in this mode.
|
|
* See octeon-drv-opcodes.h for values.
|
|
*/
|
|
uint32_t app_mode;
|
|
char lio_firmware_version[32];
|
|
};
|
|
|
|
struct lio_callout {
|
|
struct callout timer;
|
|
void *ctxptr;
|
|
uint64_t ctxul;
|
|
};
|
|
|
|
#define LIO_NIC_STARTER_TIMEOUT 30000 /* 30000ms (30s) */
|
|
|
|
struct lio_tq {
|
|
struct taskqueue *tq;
|
|
struct timeout_task work;
|
|
void *ctxptr;
|
|
uint64_t ctxul;
|
|
};
|
|
|
|
struct lio_if_props {
|
|
/*
|
|
* Each interface in the Octeon device has a network
|
|
* device pointer (used for OS specific calls).
|
|
*/
|
|
int rx_on;
|
|
int gmxport;
|
|
struct ifnet *ifp;
|
|
};
|
|
|
|
#define LIO_MSIX_PO_INT 0x1
|
|
#define LIO_MSIX_PI_INT 0x2
|
|
|
|
struct lio_pf_vf_hs_word {
|
|
#if BYTE_ORDER == LITTLE_ENDIAN
|
|
/* PKIND value assigned for the DPI interface */
|
|
uint64_t pkind:8;
|
|
|
|
/* OCTEON core clock multiplier */
|
|
uint64_t core_tics_per_us:16;
|
|
|
|
/* OCTEON coprocessor clock multiplier */
|
|
uint64_t coproc_tics_per_us:16;
|
|
|
|
/* app that currently running on OCTEON */
|
|
uint64_t app_mode:8;
|
|
|
|
/* RESERVED */
|
|
uint64_t reserved:16;
|
|
|
|
#else /* BYTE_ORDER != LITTLE_ENDIAN */
|
|
|
|
/* RESERVED */
|
|
uint64_t reserved:16;
|
|
|
|
/* app that currently running on OCTEON */
|
|
uint64_t app_mode:8;
|
|
|
|
/* OCTEON coprocessor clock multiplier */
|
|
uint64_t coproc_tics_per_us:16;
|
|
|
|
/* OCTEON core clock multiplier */
|
|
uint64_t core_tics_per_us:16;
|
|
|
|
/* PKIND value assigned for the DPI interface */
|
|
uint64_t pkind:8;
|
|
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
|
};
|
|
|
|
struct lio_sriov_info {
|
|
|
|
/* Actual rings left for PF device */
|
|
uint32_t num_pf_rings;
|
|
|
|
/* SRN of PF usable IO queues */
|
|
uint32_t pf_srn;
|
|
|
|
/* total pf rings */
|
|
uint32_t trs;
|
|
};
|
|
|
|
struct lio_ioq_vector {
|
|
struct octeon_device *oct_dev;
|
|
struct resource *msix_res;
|
|
void *tag;
|
|
int droq_index;
|
|
int vector;
|
|
cpuset_t affinity_mask;
|
|
uint32_t ioq_num;
|
|
};
|
|
|
|
/*
|
|
* The Octeon device.
|
|
* Each Octeon device has this structure to represent all its
|
|
* components.
|
|
*/
|
|
struct octeon_device {
|
|
/* Lock for PCI window configuration accesses */
|
|
struct mtx pci_win_lock;
|
|
|
|
/* Lock for memory accesses */
|
|
struct mtx mem_access_lock;
|
|
|
|
/* PCI device pointer */
|
|
device_t device;
|
|
|
|
/* Chip specific information. */
|
|
void *chip;
|
|
|
|
/* Number of interfaces detected in this octeon device. */
|
|
uint32_t ifcount;
|
|
|
|
struct lio_if_props props;
|
|
|
|
/* Octeon Chip type. */
|
|
uint16_t chip_id;
|
|
|
|
uint16_t rev_id;
|
|
|
|
uint16_t subdevice_id;
|
|
|
|
uint16_t pf_num;
|
|
|
|
|
|
/* This device's id - set by the driver. */
|
|
uint32_t octeon_id;
|
|
|
|
/* This device's PCIe port used for traffic. */
|
|
uint16_t pcie_port;
|
|
|
|
uint16_t flags;
|
|
#define LIO_FLAG_MSIX_ENABLED (uint32_t)(1 << 2)
|
|
|
|
/* The state of this device */
|
|
volatile int status;
|
|
|
|
/* memory mapped io range */
|
|
struct lio_mem_bus_space mem_bus_space[LIO_MEM_REGIONS];
|
|
|
|
struct lio_reg_list reg_list;
|
|
|
|
struct lio_fn_list fn_list;
|
|
|
|
struct lio_board_info boardinfo;
|
|
|
|
uint32_t num_iqs;
|
|
|
|
/* The pool containing pre allocated buffers used for soft commands */
|
|
struct lio_sc_buffer_pool sc_buf_pool;
|
|
|
|
/* The input instruction queues */
|
|
struct lio_instr_queue *instr_queue[LIO_MAX_POSSIBLE_INSTR_QUEUES];
|
|
|
|
/* The doubly-linked list of instruction response */
|
|
struct lio_response_list response_list[LIO_MAX_RESPONSE_LISTS];
|
|
|
|
uint32_t num_oqs;
|
|
|
|
/* The DROQ output queues */
|
|
struct lio_droq *droq[LIO_MAX_POSSIBLE_OUTPUT_QUEUES];
|
|
|
|
struct lio_io_enable io_qmask;
|
|
|
|
/* List of dispatch functions */
|
|
struct lio_dispatch_list dispatch;
|
|
|
|
uint32_t int_status;
|
|
|
|
/* Physical location of the cvmx_bootmem_desc_t in octeon memory */
|
|
uint64_t bootmem_desc_addr;
|
|
|
|
/*
|
|
* Placeholder memory for named blocks.
|
|
* Assumes single-threaded access
|
|
*/
|
|
struct cvmx_bootmem_named_block_desc bootmem_named_block_desc;
|
|
|
|
/* Address of consoles descriptor */
|
|
uint64_t console_desc_addr;
|
|
|
|
/* Number of consoles available. 0 means they are inaccessible */
|
|
uint32_t num_consoles;
|
|
|
|
/* Console caches */
|
|
struct lio_console console[LIO_MAX_MAPS];
|
|
|
|
/* Console named block info */
|
|
struct {
|
|
uint64_t dram_region_base;
|
|
int bar1_index;
|
|
} console_nb_info;
|
|
|
|
/* Coprocessor clock rate. */
|
|
uint64_t coproc_clock_rate;
|
|
|
|
/*
|
|
* The core application is running in this mode. See lio_common.h
|
|
* for values.
|
|
*/
|
|
uint32_t app_mode;
|
|
|
|
struct lio_fw_info fw_info;
|
|
|
|
/* The name given to this device. */
|
|
char device_name[32];
|
|
|
|
struct lio_tq dma_comp_tq;
|
|
|
|
/* Lock for dma response list */
|
|
struct mtx cmd_resp_wqlock;
|
|
uint32_t cmd_resp_state;
|
|
|
|
struct lio_tq check_db_tq[LIO_MAX_POSSIBLE_INSTR_QUEUES];
|
|
|
|
struct lio_callout console_timer[LIO_MAX_MAPS];
|
|
|
|
int num_msix_irqs;
|
|
|
|
/* For PF, there is one non-ioq interrupt handler */
|
|
struct resource *msix_res;
|
|
int aux_vector;
|
|
void *tag;
|
|
|
|
#define INTRNAMSIZ (32)
|
|
#define IRQ_NAME_OFF(i) ((i) * INTRNAMSIZ)
|
|
|
|
struct lio_sriov_info sriov_info;
|
|
|
|
struct lio_pf_vf_hs_word pfvf_hsword;
|
|
|
|
int msix_on;
|
|
|
|
/* IOq information of it's corresponding MSI-X interrupt. */
|
|
struct lio_ioq_vector *ioq_vector;
|
|
|
|
int rx_pause;
|
|
int tx_pause;
|
|
|
|
/* TX/RX process pkt budget */
|
|
uint32_t rx_budget;
|
|
uint32_t tx_budget;
|
|
|
|
struct octeon_link_stats link_stats; /* stastics from firmware */
|
|
|
|
struct proc *watchdog_task;
|
|
|
|
volatile bool cores_crashed;
|
|
|
|
uint32_t rx_coalesce_usecs;
|
|
uint32_t rx_max_coalesced_frames;
|
|
uint32_t tx_max_coalesced_frames;
|
|
|
|
#define OCTEON_UBOOT_BUFFER_SIZE 512
|
|
char uboot_version[OCTEON_UBOOT_BUFFER_SIZE];
|
|
int uboot_len;
|
|
int uboot_sidx, uboot_eidx;
|
|
|
|
struct {
|
|
int bus;
|
|
int dev;
|
|
int func;
|
|
} loc;
|
|
|
|
volatile int *adapter_refcount; /* reference count of adapter */
|
|
};
|
|
|
|
#define LIO_DRV_ONLINE 1
|
|
#define LIO_DRV_OFFLINE 2
|
|
#define LIO_CN23XX_PF(oct) ((oct)->chip_id == LIO_CN23XX_PF_VID)
|
|
#define LIO_CHIP_CONF(oct, TYPE) \
|
|
(((struct lio_ ## TYPE *)((oct)->chip))->conf)
|
|
#define MAX_IO_PENDING_PKT_COUNT 100
|
|
|
|
/*------------------ Function Prototypes ----------------------*/
|
|
|
|
/* Initialize device list memory */
|
|
void lio_init_device_list(int conf_type);
|
|
|
|
/* Free memory for Input and Output queue structures for a octeon device */
|
|
void lio_free_device_mem(struct octeon_device *oct);
|
|
|
|
/*
|
|
* Look up a free entry in the octeon_device table and allocate resources
|
|
* for the octeon_device structure for an octeon device. Called at init
|
|
* time.
|
|
*/
|
|
struct octeon_device *lio_allocate_device(device_t device);
|
|
|
|
/*
|
|
* Register a device's bus location at initialization time.
|
|
* @param oct - pointer to the octeon device structure.
|
|
* @param bus - PCIe bus #
|
|
* @param dev - PCIe device #
|
|
* @param func - PCIe function #
|
|
* @param is_pf - TRUE for PF, FALSE for VF
|
|
* @return reference count of device's adapter
|
|
*/
|
|
int lio_register_device(struct octeon_device *oct, int bus, int dev,
|
|
int func, int is_pf);
|
|
|
|
/*
|
|
* Deregister a device at de-initialization time.
|
|
* @param oct - pointer to the octeon device structure.
|
|
* @return reference count of device's adapter
|
|
*/
|
|
int lio_deregister_device(struct octeon_device *oct);
|
|
|
|
/*
|
|
* Initialize the driver's dispatch list which is a mix of a hash table
|
|
* and a linked list. This is done at driver load time.
|
|
* @param octeon_dev - pointer to the octeon device structure.
|
|
* @return 0 on success, else -ve error value
|
|
*/
|
|
int lio_init_dispatch_list(struct octeon_device *octeon_dev);
|
|
|
|
/*
|
|
* Delete the driver's dispatch list and all registered entries.
|
|
* This is done at driver unload time.
|
|
* @param octeon_dev - pointer to the octeon device structure.
|
|
*/
|
|
void lio_delete_dispatch_list(struct octeon_device *octeon_dev);
|
|
|
|
/*
|
|
* Initialize the core device fields with the info returned by the FW.
|
|
* @param recv_info - Receive info structure
|
|
* @param buf - Receive buffer
|
|
*/
|
|
int lio_core_drv_init(struct lio_recv_info *recv_info, void *buf);
|
|
|
|
/*
|
|
* Gets the dispatch function registered to receive packets with a
|
|
* given opcode/subcode.
|
|
* @param octeon_dev - the octeon device pointer.
|
|
* @param opcode - the opcode for which the dispatch function
|
|
* is to checked.
|
|
* @param subcode - the subcode for which the dispatch function
|
|
* is to checked.
|
|
*
|
|
* @return Success: lio_dispatch_fn_t (dispatch function pointer)
|
|
* @return Failure: NULL
|
|
*
|
|
* Looks up the dispatch list to get the dispatch function for a
|
|
* given opcode.
|
|
*/
|
|
lio_dispatch_fn_t lio_get_dispatch(struct octeon_device *octeon_dev,
|
|
uint16_t opcode, uint16_t subcode);
|
|
|
|
/*
|
|
* Get the octeon device pointer.
|
|
* @param octeon_id - The id for which the octeon device pointer is required.
|
|
* @return Success: Octeon device pointer.
|
|
* @return Failure: NULL.
|
|
*/
|
|
struct octeon_device *lio_get_device(uint32_t octeon_id);
|
|
|
|
/*
|
|
* Get the octeon id assigned to the octeon device passed as argument.
|
|
* This function is exported to other modules.
|
|
* @param dev - octeon device pointer passed as a void *.
|
|
* @return octeon device id
|
|
*/
|
|
int lio_get_device_id(void *dev);
|
|
|
|
static inline uint16_t
|
|
OCTEON_MAJOR_REV(struct octeon_device *oct)
|
|
{
|
|
|
|
uint16_t rev = (oct->rev_id & 0xC) >> 2;
|
|
|
|
return ((rev == 0) ? 1 : rev);
|
|
}
|
|
|
|
static inline uint16_t
|
|
OCTEON_MINOR_REV(struct octeon_device *oct)
|
|
{
|
|
|
|
return (oct->rev_id & 0x3);
|
|
}
|
|
|
|
/*
|
|
* Read windowed register.
|
|
* @param oct - pointer to the Octeon device.
|
|
* @param addr - Address of the register to read.
|
|
*
|
|
* This routine is called to read from the indirectly accessed
|
|
* Octeon registers that are visible through a PCI BAR0 mapped window
|
|
* register.
|
|
* @return - 64 bit value read from the register.
|
|
*/
|
|
|
|
uint64_t lio_pci_readq(struct octeon_device *oct, uint64_t addr);
|
|
|
|
/*
|
|
* Write windowed register.
|
|
* @param oct - pointer to the Octeon device.
|
|
* @param val - Value to write
|
|
* @param addr - Address of the register to write
|
|
*
|
|
* This routine is called to write to the indirectly accessed
|
|
* Octeon registers that are visible through a PCI BAR0 mapped window
|
|
* register.
|
|
* @return Nothing.
|
|
*/
|
|
void lio_pci_writeq(struct octeon_device *oct, uint64_t val, uint64_t addr);
|
|
|
|
/*
|
|
* Checks if memory access is okay
|
|
*
|
|
* @param oct which octeon to send to
|
|
* @return Zero on success, negative on failure.
|
|
*/
|
|
int lio_mem_access_ok(struct octeon_device *oct);
|
|
|
|
/*
|
|
* Waits for DDR initialization.
|
|
*
|
|
* @param oct which octeon to send to
|
|
* @param timeout_in_ms pointer to how long to wait until DDR is initialized
|
|
* in ms.
|
|
* If contents are 0, it waits until contents are non-zero
|
|
* before starting to check.
|
|
* @return Zero on success, negative on failure.
|
|
*/
|
|
int lio_wait_for_ddr_init(struct octeon_device *oct,
|
|
unsigned long *timeout_in_ms);
|
|
|
|
/*
|
|
* Wait for u-boot to boot and be waiting for a command.
|
|
*
|
|
* @param wait_time_hundredths
|
|
* Maximum time to wait
|
|
*
|
|
* @return Zero on success, negative on failure.
|
|
*/
|
|
int lio_wait_for_bootloader(struct octeon_device *oct,
|
|
uint32_t wait_time_hundredths);
|
|
|
|
/*
|
|
* Initialize console access
|
|
*
|
|
* @param oct which octeon initialize
|
|
* @return Zero on success, negative on failure.
|
|
*/
|
|
int lio_init_consoles(struct octeon_device *oct);
|
|
|
|
/*
|
|
* Adds access to a console to the device.
|
|
*
|
|
* @param oct: which octeon to add to
|
|
* @param console_num: which console
|
|
* @param dbg_enb: ptr to debug enablement string, one of:
|
|
* * NULL for no debug output (i.e. disabled)
|
|
* * empty string enables debug output (via default method)
|
|
* * specific string to enable debug console output
|
|
*
|
|
* @return Zero on success, negative on failure.
|
|
*/
|
|
int lio_add_console(struct octeon_device *oct, uint32_t console_num,
|
|
char *dbg_enb);
|
|
|
|
/* write or read from a console */
|
|
int lio_console_write(struct octeon_device *oct, uint32_t console_num,
|
|
char *buffer, uint32_t write_request_size,
|
|
uint32_t flags);
|
|
|
|
/* Removes all attached consoles. */
|
|
void lio_remove_consoles(struct octeon_device *oct);
|
|
|
|
/*
|
|
* Send a string to u-boot on console 0 as a command.
|
|
*
|
|
* @param oct which octeon to send to
|
|
* @param cmd_str String to send
|
|
* @param wait_hundredths Time to wait for u-boot to accept the command.
|
|
*
|
|
* @return Zero on success, negative on failure.
|
|
*/
|
|
int lio_console_send_cmd(struct octeon_device *oct, char *cmd_str,
|
|
uint32_t wait_hundredths);
|
|
|
|
/*
|
|
* Parses, validates, and downloads firmware, then boots associated cores.
|
|
* @param oct which octeon to download firmware to
|
|
* @param data - The complete firmware file image
|
|
* @param size - The size of the data
|
|
*
|
|
* @return 0 if success.
|
|
* -EINVAL if file is incompatible or badly formatted.
|
|
* -ENODEV if no handler was found for the application type or an
|
|
* invalid octeon id was passed.
|
|
*/
|
|
int lio_download_firmware(struct octeon_device *oct, const uint8_t *data,
|
|
size_t size);
|
|
|
|
char *lio_get_state_string(volatile int *state_ptr);
|
|
|
|
/*
|
|
* Sets up instruction queues for the device
|
|
* @param oct which octeon to setup
|
|
*
|
|
* @return 0 if success. 1 if fails
|
|
*/
|
|
int lio_setup_instr_queue0(struct octeon_device *oct);
|
|
|
|
/*
|
|
* Sets up output queues for the device
|
|
* @param oct which octeon to setup
|
|
*
|
|
* @return 0 if success. 1 if fails
|
|
*/
|
|
int lio_setup_output_queue0(struct octeon_device *oct);
|
|
|
|
int lio_get_tx_qsize(struct octeon_device *oct, uint32_t q_no);
|
|
|
|
int lio_get_rx_qsize(struct octeon_device *oct, uint32_t q_no);
|
|
|
|
/*
|
|
* Retrieve the config for the device
|
|
* @param oct which octeon
|
|
* @param card_type type of card
|
|
*
|
|
* @returns pointer to configuration
|
|
*/
|
|
void *lio_get_config_info(struct octeon_device *oct, uint16_t card_type);
|
|
|
|
/*
|
|
* Gets the octeon device configuration
|
|
* @return - pointer to the octeon configuration struture
|
|
*/
|
|
struct lio_config *lio_get_conf(struct octeon_device *oct);
|
|
|
|
void lio_free_ioq_vector(struct octeon_device *oct);
|
|
int lio_allocate_ioq_vector(struct octeon_device *oct);
|
|
void lio_enable_irq(struct lio_droq *droq, struct lio_instr_queue *iq);
|
|
|
|
static inline uint32_t
|
|
lio_read_pci_cfg(struct octeon_device *oct, uint32_t reg)
|
|
{
|
|
|
|
return (pci_read_config(oct->device, reg, 4));
|
|
}
|
|
|
|
static inline void
|
|
lio_write_pci_cfg(struct octeon_device *oct, uint32_t reg, uint32_t value)
|
|
{
|
|
|
|
pci_write_config(oct->device, reg, value, 4);
|
|
}
|
|
|
|
static inline uint8_t
|
|
lio_read_csr8(struct octeon_device *oct, uint32_t reg)
|
|
{
|
|
|
|
return (bus_space_read_1(oct->mem_bus_space[0].tag,
|
|
oct->mem_bus_space[0].handle, reg));
|
|
}
|
|
|
|
static inline void
|
|
lio_write_csr8(struct octeon_device *oct, uint32_t reg, uint8_t val)
|
|
{
|
|
|
|
bus_space_write_1(oct->mem_bus_space[0].tag,
|
|
oct->mem_bus_space[0].handle, reg, val);
|
|
}
|
|
|
|
static inline uint16_t
|
|
lio_read_csr16(struct octeon_device *oct, uint32_t reg)
|
|
{
|
|
|
|
return (bus_space_read_2(oct->mem_bus_space[0].tag,
|
|
oct->mem_bus_space[0].handle, reg));
|
|
}
|
|
|
|
static inline void
|
|
lio_write_csr16(struct octeon_device *oct, uint32_t reg, uint16_t val)
|
|
{
|
|
|
|
bus_space_write_2(oct->mem_bus_space[0].tag,
|
|
oct->mem_bus_space[0].handle, reg, val);
|
|
}
|
|
|
|
static inline uint32_t
|
|
lio_read_csr32(struct octeon_device *oct, uint32_t reg)
|
|
{
|
|
|
|
return (bus_space_read_4(oct->mem_bus_space[0].tag,
|
|
oct->mem_bus_space[0].handle, reg));
|
|
}
|
|
|
|
static inline void
|
|
lio_write_csr32(struct octeon_device *oct, uint32_t reg, uint32_t val)
|
|
{
|
|
|
|
bus_space_write_4(oct->mem_bus_space[0].tag,
|
|
oct->mem_bus_space[0].handle, reg, val);
|
|
}
|
|
|
|
static inline uint64_t
|
|
lio_read_csr64(struct octeon_device *oct, uint32_t reg)
|
|
{
|
|
|
|
#ifdef __i386__
|
|
return (lio_read_csr32(oct, reg) |
|
|
((uint64_t)lio_read_csr32(oct, reg + 4) << 32));
|
|
#else
|
|
return (bus_space_read_8(oct->mem_bus_space[0].tag,
|
|
oct->mem_bus_space[0].handle, reg));
|
|
#endif
|
|
}
|
|
|
|
static inline void
|
|
lio_write_csr64(struct octeon_device *oct, uint32_t reg, uint64_t val)
|
|
{
|
|
|
|
#ifdef __i386__
|
|
lio_write_csr32(oct, reg, (uint32_t)val);
|
|
lio_write_csr32(oct, reg + 4, val >> 32);
|
|
#else
|
|
bus_space_write_8(oct->mem_bus_space[0].tag,
|
|
oct->mem_bus_space[0].handle, reg, val);
|
|
#endif
|
|
}
|
|
|
|
#endif /* _LIO_DEVICE_H_ */
|