#ifndef _LIO_DEVICE_H_
#define _LIO_DEVICE_H_
#include <sys/endian.h>
#define LIO_CN23XX_PF_PCIID 0x9702177d
#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
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
#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)
#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
#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)
struct lio_dispatch {
struct lio_stailq_node node;
struct lio_stailq_head head;
uint16_t opcode;
lio_dispatch_fn_t dispatch_fn;
void *arg;
};
struct lio_dispatch_list {
struct mtx lock;
uint32_t count;
struct lio_dispatch *dlist;
};
#define LIO_MEM_REGIONS 3
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 *);
};
#define LIO_BOOTMEM_NAME_LEN 128
struct cvmx_bootmem_named_block_desc {
uint64_t base_addr;
uint64_t size;
char name[LIO_BOOTMEM_NAME_LEN];
};
struct lio_fw_info {
uint32_t max_nic_ports;
uint32_t num_gmx_ports;
uint64_t app_cap_flags;
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
struct lio_tq {
struct taskqueue *tq;
struct timeout_task work;
void *ctxptr;
uint64_t ctxul;
};
struct lio_if_props {
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
uint64_t pkind:8;
uint64_t core_tics_per_us:16;
uint64_t coproc_tics_per_us:16;
uint64_t app_mode:8;
uint64_t reserved:16;
#else
uint64_t reserved:16;
uint64_t app_mode:8;
uint64_t coproc_tics_per_us:16;
uint64_t core_tics_per_us:16;
uint64_t pkind:8;
#endif
};
struct lio_sriov_info {
uint32_t num_pf_rings;
uint32_t pf_srn;
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;
};
struct octeon_device {
struct mtx pci_win_lock;
struct mtx mem_access_lock;
device_t device;
void *chip;
uint32_t ifcount;
struct lio_if_props props;
uint16_t chip_id;
uint16_t rev_id;
uint16_t subdevice_id;
uint16_t pf_num;
uint32_t octeon_id;
uint16_t pcie_port;
uint16_t flags;
#define LIO_FLAG_MSIX_ENABLED (uint32_t)(1 << 2)
volatile int status;
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;
struct lio_sc_buffer_pool sc_buf_pool;
struct lio_instr_queue *instr_queue[LIO_MAX_POSSIBLE_INSTR_QUEUES];
struct lio_response_list response_list[LIO_MAX_RESPONSE_LISTS];
uint32_t num_oqs;
struct lio_droq *droq[LIO_MAX_POSSIBLE_OUTPUT_QUEUES];
struct lio_io_enable io_qmask;
struct lio_dispatch_list dispatch;
uint32_t int_status;
uint64_t bootmem_desc_addr;
struct cvmx_bootmem_named_block_desc bootmem_named_block_desc;
uint64_t console_desc_addr;
uint32_t num_consoles;
struct lio_console console[LIO_MAX_MAPS];
struct {
uint64_t dram_region_base;
int bar1_index;
} console_nb_info;
uint64_t coproc_clock_rate;
uint32_t app_mode;
struct lio_fw_info fw_info;
char device_name[32];
struct lio_tq dma_comp_tq;
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;
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;
struct lio_ioq_vector *ioq_vector;
int rx_pause;
int tx_pause;
uint32_t rx_budget;
uint32_t tx_budget;
struct octeon_link_stats link_stats;
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;
};
#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
void lio_init_device_list(int conf_type);
void lio_free_device_mem(struct octeon_device *oct);
struct octeon_device *lio_allocate_device(device_t device);
int lio_register_device(struct octeon_device *oct, int bus, int dev,
int func, int is_pf);
int lio_deregister_device(struct octeon_device *oct);
int lio_init_dispatch_list(struct octeon_device *octeon_dev);
void lio_delete_dispatch_list(struct octeon_device *octeon_dev);
int lio_core_drv_init(struct lio_recv_info *recv_info, void *buf);
lio_dispatch_fn_t lio_get_dispatch(struct octeon_device *octeon_dev,
uint16_t opcode, uint16_t subcode);
struct octeon_device *lio_get_device(uint32_t octeon_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);
}
uint64_t lio_pci_readq(struct octeon_device *oct, uint64_t addr);
void lio_pci_writeq(struct octeon_device *oct, uint64_t val, uint64_t addr);
int lio_mem_access_ok(struct octeon_device *oct);
int lio_wait_for_ddr_init(struct octeon_device *oct,
unsigned long *timeout_in_ms);
int lio_wait_for_bootloader(struct octeon_device *oct,
uint32_t wait_time_hundredths);
int lio_init_consoles(struct octeon_device *oct);
int lio_add_console(struct octeon_device *oct, uint32_t console_num,
char *dbg_enb);
int lio_console_write(struct octeon_device *oct, uint32_t console_num,
char *buffer, uint32_t write_request_size,
uint32_t flags);
void lio_remove_consoles(struct octeon_device *oct);
int lio_console_send_cmd(struct octeon_device *oct, char *cmd_str,
uint32_t wait_hundredths);
int lio_download_firmware(struct octeon_device *oct, const uint8_t *data,
size_t size);
char *lio_get_state_string(volatile int *state_ptr);
int lio_setup_instr_queue0(struct octeon_device *oct);
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);
void *lio_get_config_info(struct octeon_device *oct, uint16_t card_type);
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