772 lines
21 KiB
C
772 lines
21 KiB
C
/*
|
|
* Copyright (c) 2017-2018 Cavium, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. 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.
|
|
*
|
|
* 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 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$
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* File: qlnx_def.h
|
|
* Author : David C Somayajulu, Cavium Inc., San Jose, CA 95131.
|
|
*/
|
|
|
|
#ifndef _QLNX_DEF_H_
|
|
#define _QLNX_DEF_H_
|
|
|
|
#define VER_SIZE 16
|
|
|
|
struct qlnx_ivec {
|
|
uint32_t rss_idx;
|
|
void *ha;
|
|
struct resource *irq;
|
|
void *handle;
|
|
int irq_rid;
|
|
};
|
|
|
|
typedef struct qlnx_ivec qlnx_ivec_t;
|
|
|
|
//#define QLNX_MAX_RSS 30
|
|
#define QLNX_MAX_VF_RSS 4
|
|
#define QLNX_MAX_RSS 36
|
|
#define QLNX_DEFAULT_RSS 16
|
|
#define QLNX_MAX_TC 1
|
|
|
|
enum QLNX_STATE {
|
|
QLNX_STATE_CLOSED,
|
|
QLNX_STATE_OPEN,
|
|
};
|
|
|
|
#define HILO_U64(hi, lo) ((((u64)(hi)) << 32) + (lo))
|
|
|
|
#define MAX_NUM_TC 8
|
|
#define MAX_NUM_PRI 8
|
|
|
|
#ifndef BITS_PER_BYTE
|
|
#define BITS_PER_BYTE 8
|
|
#endif /* #ifndef BITS_PER_BYTE */
|
|
|
|
/*
|
|
* RX ring buffer contains pointer to kmalloc() data only,
|
|
*/
|
|
struct sw_rx_data {
|
|
void *data;
|
|
bus_dmamap_t map;
|
|
dma_addr_t dma_addr;
|
|
};
|
|
|
|
enum qlnx_agg_state {
|
|
QLNX_AGG_STATE_NONE = 0,
|
|
QLNX_AGG_STATE_START = 1,
|
|
QLNX_AGG_STATE_ERROR = 2
|
|
};
|
|
|
|
struct qlnx_agg_info {
|
|
/* rx_buf is a data buffer that can be placed /consumed from rx bd
|
|
* chain. It has two purposes: We will preallocate the data buffer
|
|
* for each aggregation when we open the interface and will place this
|
|
* buffer on the rx-bd-ring when we receive TPA_START. We don't want
|
|
* to be in a state where allocation fails, as we can't reuse the
|
|
* consumer buffer in the rx-chain since FW may still be writing to it
|
|
* (since header needs to be modified for TPA.
|
|
* The second purpose is to keep a pointer to the bd buffer during
|
|
* aggregation.
|
|
*/
|
|
struct sw_rx_data rx_buf;
|
|
enum qlnx_agg_state agg_state;
|
|
uint16_t placement_offset;
|
|
struct mbuf *mpf; /* first mbuf in chain */
|
|
struct mbuf *mpl; /* last mbuf in chain */
|
|
};
|
|
|
|
#define RX_RING_SIZE_POW 13
|
|
#define RX_RING_SIZE (1 << RX_RING_SIZE_POW)
|
|
|
|
#define TX_RING_SIZE_POW 14
|
|
#define TX_RING_SIZE (1 << TX_RING_SIZE_POW)
|
|
|
|
struct qlnx_rx_queue {
|
|
volatile __le16 *hw_cons_ptr;
|
|
struct sw_rx_data sw_rx_ring[RX_RING_SIZE];
|
|
uint16_t sw_rx_cons;
|
|
uint16_t sw_rx_prod;
|
|
struct ecore_chain rx_bd_ring;
|
|
struct ecore_chain rx_comp_ring;
|
|
void __iomem *hw_rxq_prod_addr;
|
|
void *handle;
|
|
|
|
/* LRO */
|
|
struct qlnx_agg_info tpa_info[ETH_TPA_MAX_AGGS_NUM];
|
|
|
|
uint32_t rx_buf_size;
|
|
|
|
uint16_t num_rx_buffers;
|
|
uint16_t rxq_id;
|
|
|
|
#ifdef QLNX_SOFT_LRO
|
|
struct lro_ctrl lro;
|
|
#endif
|
|
};
|
|
|
|
union db_prod {
|
|
struct eth_db_data data;
|
|
uint32_t raw;
|
|
};
|
|
|
|
struct sw_tx_bd {
|
|
struct mbuf *mp;
|
|
bus_dmamap_t map;
|
|
uint8_t flags;
|
|
int nsegs;
|
|
|
|
/* Set on the first BD descriptor when there is a split BD */
|
|
#define QLNX_TSO_SPLIT_BD (1<<0)
|
|
};
|
|
|
|
#define QLNX_MAX_SEGMENTS 255
|
|
struct qlnx_tx_queue {
|
|
int index; /* Queue index */
|
|
volatile __le16 *hw_cons_ptr;
|
|
struct sw_tx_bd sw_tx_ring[TX_RING_SIZE];
|
|
uint16_t sw_tx_cons;
|
|
uint16_t sw_tx_prod;
|
|
struct ecore_chain tx_pbl;
|
|
void __iomem *doorbell_addr;
|
|
void *handle;
|
|
union db_prod tx_db;
|
|
|
|
bus_dma_segment_t segs[QLNX_MAX_SEGMENTS];
|
|
|
|
uint16_t num_tx_buffers;
|
|
};
|
|
|
|
#define BD_UNMAP_ADDR(bd) HILO_U64(le32toh((bd)->addr.hi), \
|
|
le32toh((bd)->addr.lo))
|
|
#define BD_UNMAP_LEN(bd) (le16toh((bd)->nbytes))
|
|
|
|
#define BD_SET_UNMAP_ADDR_LEN(bd, maddr, len) \
|
|
do { \
|
|
(bd)->addr.hi = htole32(U64_HI(maddr)); \
|
|
(bd)->addr.lo = htole32(U64_LO(maddr)); \
|
|
(bd)->nbytes = htole16(len); \
|
|
} while (0);
|
|
|
|
#define QLNX_FP_MAX_SEGS 24
|
|
|
|
struct qlnx_fastpath {
|
|
void *edev;
|
|
uint8_t rss_id;
|
|
struct ecore_sb_info *sb_info;
|
|
struct qlnx_rx_queue *rxq;
|
|
struct qlnx_tx_queue *txq[MAX_NUM_TC];
|
|
char name[64];
|
|
|
|
struct mtx tx_mtx;
|
|
char tx_mtx_name[32];
|
|
struct buf_ring *tx_br;
|
|
uint32_t tx_ring_full;
|
|
|
|
struct task fp_task;
|
|
struct taskqueue *fp_taskqueue;
|
|
|
|
/* transmit statistics */
|
|
uint64_t tx_pkts_processed;
|
|
uint64_t tx_pkts_freed;
|
|
uint64_t tx_pkts_transmitted;
|
|
uint64_t tx_pkts_completed;
|
|
uint64_t tx_tso_pkts;
|
|
uint64_t tx_non_tso_pkts;
|
|
|
|
#ifdef QLNX_TRACE_PERF_DATA
|
|
uint64_t tx_pkts_trans_ctx;
|
|
uint64_t tx_pkts_compl_ctx;
|
|
uint64_t tx_pkts_trans_fp;
|
|
uint64_t tx_pkts_compl_fp;
|
|
uint64_t tx_pkts_compl_intr;
|
|
#endif
|
|
|
|
uint64_t tx_lso_wnd_min_len;
|
|
uint64_t tx_defrag;
|
|
uint64_t tx_nsegs_gt_elem_left;
|
|
uint32_t tx_tso_max_nsegs;
|
|
uint32_t tx_tso_min_nsegs;
|
|
uint32_t tx_tso_max_pkt_len;
|
|
uint32_t tx_tso_min_pkt_len;
|
|
uint64_t tx_pkts[QLNX_FP_MAX_SEGS];
|
|
|
|
#ifdef QLNX_TRACE_PERF_DATA
|
|
uint64_t tx_pkts_hist[QLNX_FP_MAX_SEGS];
|
|
uint64_t tx_comInt[QLNX_FP_MAX_SEGS];
|
|
uint64_t tx_pkts_q[QLNX_FP_MAX_SEGS];
|
|
#endif
|
|
|
|
uint64_t err_tx_nsegs_gt_elem_left;
|
|
uint64_t err_tx_dmamap_create;
|
|
uint64_t err_tx_defrag_dmamap_load;
|
|
uint64_t err_tx_non_tso_max_seg;
|
|
uint64_t err_tx_dmamap_load;
|
|
uint64_t err_tx_defrag;
|
|
uint64_t err_tx_free_pkt_null;
|
|
uint64_t err_tx_cons_idx_conflict;
|
|
|
|
uint64_t lro_cnt_64;
|
|
uint64_t lro_cnt_128;
|
|
uint64_t lro_cnt_256;
|
|
uint64_t lro_cnt_512;
|
|
uint64_t lro_cnt_1024;
|
|
|
|
/* receive statistics */
|
|
uint64_t rx_pkts;
|
|
uint64_t tpa_start;
|
|
uint64_t tpa_cont;
|
|
uint64_t tpa_end;
|
|
uint64_t err_m_getcl;
|
|
uint64_t err_m_getjcl;
|
|
uint64_t err_rx_hw_errors;
|
|
uint64_t err_rx_alloc_errors;
|
|
uint64_t err_rx_jumbo_chain_pkts;
|
|
uint64_t err_rx_mp_null;
|
|
uint64_t err_rx_tpa_invalid_agg_num;
|
|
};
|
|
|
|
struct qlnx_update_vport_params {
|
|
uint8_t vport_id;
|
|
uint8_t update_vport_active_rx_flg;
|
|
uint8_t vport_active_rx_flg;
|
|
uint8_t update_vport_active_tx_flg;
|
|
uint8_t vport_active_tx_flg;
|
|
uint8_t update_inner_vlan_removal_flg;
|
|
uint8_t inner_vlan_removal_flg;
|
|
struct ecore_rss_params *rss_params;
|
|
struct ecore_sge_tpa_params *sge_tpa_params;
|
|
};
|
|
|
|
/*
|
|
* link related
|
|
*/
|
|
struct qlnx_link_output {
|
|
bool link_up;
|
|
uint32_t supported_caps;
|
|
uint32_t advertised_caps;
|
|
uint32_t link_partner_caps;
|
|
uint32_t speed; /* In Mb/s */
|
|
bool autoneg;
|
|
uint32_t media_type;
|
|
uint32_t duplex;
|
|
};
|
|
typedef struct qlnx_link_output qlnx_link_output_t;
|
|
|
|
#define QLNX_LINK_DUPLEX 0x0001
|
|
|
|
#define QLNX_LINK_CAP_FIBRE 0x0001
|
|
#define QLNX_LINK_CAP_Autoneg 0x0002
|
|
#define QLNX_LINK_CAP_Pause 0x0004
|
|
#define QLNX_LINK_CAP_Asym_Pause 0x0008
|
|
#define QLNX_LINK_CAP_1000baseT_Half 0x0010
|
|
#define QLNX_LINK_CAP_1000baseT_Full 0x0020
|
|
#define QLNX_LINK_CAP_10000baseKR_Full 0x0040
|
|
#define QLNX_LINK_CAP_25000baseKR_Full 0x0080
|
|
#define QLNX_LINK_CAP_40000baseLR4_Full 0x0100
|
|
#define QLNX_LINK_CAP_50000baseKR2_Full 0x0200
|
|
#define QLNX_LINK_CAP_100000baseKR4_Full 0x0400
|
|
|
|
/* Functions definition */
|
|
|
|
#define XMIT_PLAIN 0
|
|
#define XMIT_L4_CSUM (1 << 0)
|
|
#define XMIT_LSO (1 << 1)
|
|
|
|
#define CQE_FLAGS_ERR (PARSING_AND_ERR_FLAGS_IPHDRERROR_MASK << \
|
|
PARSING_AND_ERR_FLAGS_IPHDRERROR_SHIFT | \
|
|
PARSING_AND_ERR_FLAGS_L4CHKSMERROR_MASK << \
|
|
PARSING_AND_ERR_FLAGS_L4CHKSMERROR_SHIFT | \
|
|
PARSING_AND_ERR_FLAGS_TUNNELIPHDRERROR_MASK << \
|
|
PARSING_AND_ERR_FLAGS_TUNNELIPHDRERROR_SHIFT | \
|
|
PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMERROR_MASK << \
|
|
PARSING_AND_ERR_FLAGS_TUNNELL4CHKSMERROR_SHIFT)
|
|
|
|
#define RX_COPY_THRESH 92
|
|
#define ETH_MAX_PACKET_SIZE 1500
|
|
|
|
#define QLNX_MFW_VERSION_LENGTH 32
|
|
#define QLNX_STORMFW_VERSION_LENGTH 32
|
|
|
|
#define QLNX_TX_ELEM_RESERVE 2
|
|
#define QLNX_TX_ELEM_THRESH 128
|
|
#define QLNX_TX_ELEM_MAX_THRESH 512
|
|
#define QLNX_TX_ELEM_MIN_THRESH 32
|
|
#define QLNX_TX_COMPL_THRESH 32
|
|
|
|
#define QLNX_TPA_MAX_AGG_BUFFERS (20)
|
|
|
|
#define QLNX_MAX_NUM_MULTICAST_ADDRS ECORE_MAX_MC_ADDRS
|
|
typedef struct _qlnx_mcast {
|
|
uint16_t rsrvd;
|
|
uint8_t addr[6];
|
|
} __packed qlnx_mcast_t;
|
|
|
|
typedef struct _qlnx_vf_attr {
|
|
uint8_t mac_addr[ETHER_ADDR_LEN];
|
|
uint32_t num_rings;
|
|
} qlnx_vf_attr_t;
|
|
|
|
typedef struct _qlnx_sriov_task {
|
|
struct task pf_task;
|
|
struct taskqueue *pf_taskqueue;
|
|
|
|
#define QLNX_SRIOV_TASK_FLAGS_VF_PF_MSG 0x01
|
|
#define QLNX_SRIOV_TASK_FLAGS_VF_FLR_UPDATE 0x02
|
|
#define QLNX_SRIOV_TASK_FLAGS_BULLETIN_UPDATE 0x04
|
|
volatile uint32_t flags;
|
|
|
|
} qlnx_sriov_task_t;
|
|
|
|
/*
|
|
* Adapter structure contains the hardware independent information of the
|
|
* pci function.
|
|
*/
|
|
struct qlnx_host {
|
|
/* interface to ecore */
|
|
|
|
struct ecore_dev cdev;
|
|
|
|
uint32_t state;
|
|
|
|
/* some flags */
|
|
volatile struct {
|
|
volatile uint32_t
|
|
hw_init :1,
|
|
callout_init :1,
|
|
slowpath_start :1,
|
|
parent_tag :1,
|
|
lock_init :1;
|
|
} flags;
|
|
|
|
/* interface to o.s */
|
|
|
|
device_t pci_dev;
|
|
uint8_t pci_func;
|
|
uint8_t dev_unit;
|
|
uint16_t device_id;
|
|
|
|
struct ifnet *ifp;
|
|
int if_flags;
|
|
volatile int link_up;
|
|
struct ifmedia media;
|
|
uint16_t max_frame_size;
|
|
|
|
struct cdev *ioctl_dev;
|
|
|
|
/* resources */
|
|
struct resource *pci_reg;
|
|
int reg_rid;
|
|
|
|
struct resource *pci_dbells;
|
|
int dbells_rid;
|
|
uint64_t dbells_phys_addr;
|
|
uint32_t dbells_size;
|
|
|
|
struct resource *msix_bar;
|
|
int msix_rid;
|
|
|
|
int msix_count;
|
|
|
|
struct mtx hw_lock;
|
|
|
|
/* debug */
|
|
|
|
uint32_t dbg_level;
|
|
uint32_t dbg_trace_lro_cnt;
|
|
uint32_t dbg_trace_tso_pkt_len;
|
|
uint32_t dp_level;
|
|
uint32_t dp_module;
|
|
|
|
/* misc */
|
|
uint8_t mfw_ver[QLNX_MFW_VERSION_LENGTH];
|
|
uint8_t stormfw_ver[QLNX_STORMFW_VERSION_LENGTH];
|
|
uint32_t flash_size;
|
|
|
|
/* dma related */
|
|
|
|
bus_dma_tag_t parent_tag;
|
|
bus_dma_tag_t tx_tag;
|
|
bus_dma_tag_t rx_tag;
|
|
|
|
struct ecore_sb_info sb_array[QLNX_MAX_RSS];
|
|
struct qlnx_rx_queue rxq_array[QLNX_MAX_RSS];
|
|
struct qlnx_tx_queue txq_array[(QLNX_MAX_RSS * MAX_NUM_TC)];
|
|
struct qlnx_fastpath fp_array[QLNX_MAX_RSS];
|
|
|
|
/* tx related */
|
|
struct callout tx_callout;
|
|
uint32_t txr_idx;
|
|
|
|
/* rx related */
|
|
uint32_t rx_pkt_threshold;
|
|
uint32_t rx_jumbo_buf_eq_mtu;
|
|
|
|
/* slow path related */
|
|
struct resource *sp_irq[MAX_HWFNS_PER_DEVICE];
|
|
void *sp_handle[MAX_HWFNS_PER_DEVICE];
|
|
int sp_irq_rid[MAX_HWFNS_PER_DEVICE];
|
|
struct task sp_task[MAX_HWFNS_PER_DEVICE];
|
|
struct taskqueue *sp_taskqueue[MAX_HWFNS_PER_DEVICE];
|
|
|
|
struct callout qlnx_callout;
|
|
|
|
/* fast path related */
|
|
int num_rss;
|
|
int num_tc;
|
|
|
|
#define QLNX_MAX_TSS_CNT(ha) ((ha->num_rss) * (ha->num_tc))
|
|
|
|
qlnx_ivec_t irq_vec[QLNX_MAX_RSS];
|
|
|
|
uint8_t filter;
|
|
uint32_t nmcast;
|
|
qlnx_mcast_t mcast[QLNX_MAX_NUM_MULTICAST_ADDRS];
|
|
struct ecore_filter_mcast ecore_mcast;
|
|
uint8_t primary_mac[ETH_ALEN];
|
|
uint8_t prio_to_tc[MAX_NUM_PRI];
|
|
struct ecore_eth_stats hw_stats;
|
|
struct ecore_rss_params rss_params;
|
|
uint32_t rx_buf_size;
|
|
bool rx_csum_offload;
|
|
|
|
uint32_t rx_coalesce_usecs;
|
|
uint32_t tx_coalesce_usecs;
|
|
|
|
/* link related */
|
|
qlnx_link_output_t if_link;
|
|
|
|
/* global counters */
|
|
uint64_t sp_interrupts;
|
|
uint64_t err_illegal_intr;
|
|
uint64_t err_fp_null;
|
|
uint64_t err_get_proto_invalid_type;
|
|
|
|
/* error recovery related */
|
|
uint32_t error_recovery;
|
|
struct task err_task;
|
|
struct taskqueue *err_taskqueue;
|
|
|
|
/* grcdump related */
|
|
uint32_t err_inject;
|
|
uint32_t grcdump_taken;
|
|
uint32_t grcdump_dwords[QLNX_MAX_HW_FUNCS];
|
|
uint32_t grcdump_size[QLNX_MAX_HW_FUNCS];
|
|
void *grcdump[QLNX_MAX_HW_FUNCS];
|
|
|
|
uint32_t idle_chk_taken;
|
|
uint32_t idle_chk_dwords[QLNX_MAX_HW_FUNCS];
|
|
uint32_t idle_chk_size[QLNX_MAX_HW_FUNCS];
|
|
void *idle_chk[QLNX_MAX_HW_FUNCS];
|
|
|
|
/* storm stats related */
|
|
#define QLNX_STORM_STATS_TOTAL \
|
|
(QLNX_MAX_HW_FUNCS * QLNX_STORM_STATS_SAMPLES_PER_HWFN)
|
|
qlnx_storm_stats_t storm_stats[QLNX_STORM_STATS_TOTAL];
|
|
uint32_t storm_stats_index;
|
|
uint32_t storm_stats_enable;
|
|
uint32_t storm_stats_gather;
|
|
|
|
uint32_t personality;
|
|
|
|
uint16_t sriov_initialized;
|
|
uint16_t num_vfs;
|
|
qlnx_vf_attr_t *vf_attr;
|
|
qlnx_sriov_task_t sriov_task[MAX_HWFNS_PER_DEVICE];
|
|
uint32_t curr_vf;
|
|
|
|
void *next;
|
|
void *qlnx_rdma;
|
|
volatile int qlnxr_debug;
|
|
};
|
|
|
|
typedef struct qlnx_host qlnx_host_t;
|
|
|
|
/* note that align has to be a power of 2 */
|
|
#define QL_ALIGN(size, align) (((size) + ((align) - 1)) & (~((align) - 1)));
|
|
#define QL_MIN(x, y) ((x < y) ? x : y)
|
|
|
|
#define QL_RUNNING(ifp) \
|
|
((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) == \
|
|
IFF_DRV_RUNNING)
|
|
|
|
#define QLNX_MAX_MTU 9000
|
|
#define QLNX_MAX_SEGMENTS_NON_TSO (ETH_TX_MAX_BDS_PER_NON_LSO_PACKET - 1)
|
|
//#define QLNX_MAX_TSO_FRAME_SIZE ((64 * 1024 - 1) + 22)
|
|
#define QLNX_MAX_TSO_FRAME_SIZE 65536
|
|
#define QLNX_MAX_TX_MBUF_SIZE 65536 /* bytes - bd_len = 16bits */
|
|
|
|
#define QL_MAC_CMP(mac1, mac2) \
|
|
((((*(uint32_t *) mac1) == (*(uint32_t *) mac2) && \
|
|
(*(uint16_t *)(mac1 + 4)) == (*(uint16_t *)(mac2 + 4)))) ? 0 : 1)
|
|
#define for_each_rss(i) for (i = 0; i < ha->num_rss; i++)
|
|
|
|
/*
|
|
* Debug Related
|
|
*/
|
|
|
|
#ifdef QLNX_DEBUG
|
|
|
|
#define QL_DPRINT1(ha, x, ...) \
|
|
do { \
|
|
if ((ha)->dbg_level & 0x0001) { \
|
|
device_printf ((ha)->pci_dev, \
|
|
"[%s:%d]" x, \
|
|
__func__, __LINE__, \
|
|
## __VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define QL_DPRINT2(ha, x, ...) \
|
|
do { \
|
|
if ((ha)->dbg_level & 0x0002) { \
|
|
device_printf ((ha)->pci_dev, \
|
|
"[%s:%d]" x, \
|
|
__func__, __LINE__, \
|
|
## __VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define QL_DPRINT3(ha, x, ...) \
|
|
do { \
|
|
if ((ha)->dbg_level & 0x0004) { \
|
|
device_printf ((ha)->pci_dev, \
|
|
"[%s:%d]" x, \
|
|
__func__, __LINE__, \
|
|
## __VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define QL_DPRINT4(ha, x, ...) \
|
|
do { \
|
|
if ((ha)->dbg_level & 0x0008) { \
|
|
device_printf ((ha)->pci_dev, \
|
|
"[%s:%d]" x, \
|
|
__func__, __LINE__, \
|
|
## __VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define QL_DPRINT5(ha, x, ...) \
|
|
do { \
|
|
if ((ha)->dbg_level & 0x0010) { \
|
|
device_printf ((ha)->pci_dev, \
|
|
"[%s:%d]" x, \
|
|
__func__, __LINE__, \
|
|
## __VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define QL_DPRINT6(ha, x, ...) \
|
|
do { \
|
|
if ((ha)->dbg_level & 0x0020) { \
|
|
device_printf ((ha)->pci_dev, \
|
|
"[%s:%d]" x, \
|
|
__func__, __LINE__, \
|
|
## __VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define QL_DPRINT7(ha, x, ...) \
|
|
do { \
|
|
if ((ha)->dbg_level & 0x0040) { \
|
|
device_printf ((ha)->pci_dev, \
|
|
"[%s:%d]" x, \
|
|
__func__, __LINE__, \
|
|
## __VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define QL_DPRINT8(ha, x, ...) \
|
|
do { \
|
|
if ((ha)->dbg_level & 0x0080) { \
|
|
device_printf ((ha)->pci_dev, \
|
|
"[%s:%d]" x, \
|
|
__func__, __LINE__, \
|
|
## __VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define QL_DPRINT9(ha, x, ...) \
|
|
do { \
|
|
if ((ha)->dbg_level & 0x0100) { \
|
|
device_printf ((ha)->pci_dev, \
|
|
"[%s:%d]" x, \
|
|
__func__, __LINE__, \
|
|
## __VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define QL_DPRINT11(ha, x, ...) \
|
|
do { \
|
|
if ((ha)->dbg_level & 0x0400) { \
|
|
device_printf ((ha)->pci_dev, \
|
|
"[%s:%d]" x, \
|
|
__func__, __LINE__, \
|
|
## __VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define QL_DPRINT12(ha, x, ...) \
|
|
do { \
|
|
if ((ha)->dbg_level & 0x0800) { \
|
|
device_printf ((ha)->pci_dev, \
|
|
"[%s:%d]" x, \
|
|
__func__, __LINE__, \
|
|
## __VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define QL_DPRINT13(ha, x, ...) \
|
|
do { \
|
|
if ((ha)->dbg_level & 0x1000) { \
|
|
device_printf ((ha)->pci_dev, \
|
|
"[%s:%d]" x, \
|
|
__func__, __LINE__, \
|
|
## __VA_ARGS__); \
|
|
} \
|
|
} while (0)
|
|
|
|
#else
|
|
|
|
#define QL_DPRINT1(ha, x, ...)
|
|
#define QL_DPRINT2(ha, x, ...)
|
|
#define QL_DPRINT3(ha, x, ...)
|
|
#define QL_DPRINT4(ha, x, ...)
|
|
#define QL_DPRINT5(ha, x, ...)
|
|
#define QL_DPRINT6(ha, x, ...)
|
|
#define QL_DPRINT7(ha, x, ...)
|
|
#define QL_DPRINT8(ha, x, ...)
|
|
#define QL_DPRINT9(ha, x, ...)
|
|
#define QL_DPRINT11(ha, x, ...)
|
|
#define QL_DPRINT12(ha, x, ...)
|
|
#define QL_DPRINT13(ha, x, ...)
|
|
|
|
#endif /* #ifdef QLNX_DEBUG */
|
|
|
|
#define QL_ASSERT(ha, x, y) if (!x) panic y
|
|
|
|
#define QL_ERR_INJECT(ha, val) (ha->err_inject == val)
|
|
#define QL_RESET_ERR_INJECT(ha, val) {if (ha->err_inject == val) ha->err_inject = 0;}
|
|
#define QL_ERR_INJCT_TX_INT_DIFF 0x0001
|
|
#define QL_ERR_INJCT_TX_INT_MBUF_NULL 0x0002
|
|
|
|
/*
|
|
* exported functions
|
|
*/
|
|
extern int qlnx_make_cdev(qlnx_host_t *ha);
|
|
extern void qlnx_del_cdev(qlnx_host_t *ha);
|
|
extern int qlnx_grc_dump(qlnx_host_t *ha, uint32_t *num_dumped_dwords,
|
|
int hwfn_index);
|
|
extern int qlnx_idle_chk(qlnx_host_t *ha, uint32_t *num_dumped_dwords,
|
|
int hwfn_index);
|
|
extern uint8_t *qlnx_get_mac_addr(qlnx_host_t *ha);
|
|
extern void qlnx_fill_link(qlnx_host_t *ha, struct ecore_hwfn *hwfn,
|
|
struct qlnx_link_output *if_link);
|
|
extern int qlnx_set_lldp_tlvx(qlnx_host_t *ha, qlnx_lldp_sys_tlvs_t *lldp_tlvs);
|
|
extern int qlnx_vf_device(qlnx_host_t *ha);
|
|
extern void qlnx_free_mem_sb(qlnx_host_t *ha, struct ecore_sb_info *sb_info);
|
|
extern int qlnx_alloc_mem_sb(qlnx_host_t *ha, struct ecore_sb_info *sb_info,
|
|
u16 sb_id);
|
|
|
|
/*
|
|
* Some OS specific stuff
|
|
*/
|
|
|
|
#if (defined IFM_100G_SR4)
|
|
#define QLNX_IFM_100G_SR4 IFM_100G_SR4
|
|
#define QLNX_IFM_100G_LR4 IFM_100G_LR4
|
|
#define QLNX_IFM_100G_CR4 IFM_100G_CR4
|
|
#else
|
|
#define QLNX_IFM_100G_SR4 IFM_UNKNOWN
|
|
#define QLNX_IFM_100G_LR4 IFM_UNKNOWN
|
|
#endif /* #if (defined IFM_100G_SR4) */
|
|
|
|
#if (defined IFM_25G_SR)
|
|
#define QLNX_IFM_25G_SR IFM_25G_SR
|
|
#define QLNX_IFM_25G_CR IFM_25G_CR
|
|
#else
|
|
#define QLNX_IFM_25G_SR IFM_UNKNOWN
|
|
#define QLNX_IFM_25G_CR IFM_UNKNOWN
|
|
#endif /* #if (defined IFM_25G_SR) */
|
|
|
|
#if __FreeBSD_version < 1100000
|
|
|
|
#define QLNX_INC_IERRORS(ifp) ifp->if_ierrors++
|
|
#define QLNX_INC_IQDROPS(ifp) ifp->if_iqdrops++
|
|
#define QLNX_INC_IPACKETS(ifp) ifp->if_ipackets++
|
|
#define QLNX_INC_OPACKETS(ifp) ifp->if_opackets++
|
|
#define QLNX_INC_OBYTES(ifp, len) ifp->if_obytes += len
|
|
#define QLNX_INC_IBYTES(ifp, len) ifp->if_ibytes += len
|
|
|
|
#else
|
|
|
|
#define QLNX_INC_IERRORS(ifp) if_inc_counter(ifp, IFCOUNTER_IERRORS, 1)
|
|
#define QLNX_INC_IQDROPS(ifp) if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1)
|
|
#define QLNX_INC_IPACKETS(ifp) if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1)
|
|
#define QLNX_INC_OPACKETS(ifp) if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1)
|
|
|
|
#define QLNX_INC_OBYTES(ifp, len) \
|
|
if_inc_counter(ifp, IFCOUNTER_OBYTES, len)
|
|
#define QLNX_INC_IBYTES(ifp, len) \
|
|
if_inc_counter(ha->ifp, IFCOUNTER_IBYTES, len)
|
|
|
|
#endif /* #if __FreeBSD_version < 1100000 */
|
|
|
|
#define CQE_L3_PACKET(flags) \
|
|
((((flags) & PARSING_AND_ERR_FLAGS_L3TYPE_MASK) == e_l3_type_ipv4) || \
|
|
(((flags) & PARSING_AND_ERR_FLAGS_L3TYPE_MASK) == e_l3_type_ipv6))
|
|
|
|
#define CQE_IP_HDR_ERR(flags) \
|
|
((flags) & (PARSING_AND_ERR_FLAGS_IPHDRERROR_MASK \
|
|
<< PARSING_AND_ERR_FLAGS_IPHDRERROR_SHIFT))
|
|
|
|
#define CQE_L4_HAS_CSUM(flags) \
|
|
((flags) & (PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED_MASK \
|
|
<< PARSING_AND_ERR_FLAGS_L4CHKSMWASCALCULATED_SHIFT))
|
|
|
|
#define CQE_HAS_VLAN(flags) \
|
|
((flags) & (PARSING_AND_ERR_FLAGS_TAG8021QEXIST_MASK \
|
|
<< PARSING_AND_ERR_FLAGS_TAG8021QEXIST_SHIFT))
|
|
|
|
#ifndef QLNX_RDMA
|
|
#if defined(__i386__) || defined(__amd64__)
|
|
|
|
static __inline
|
|
void prefetch(void *x)
|
|
{
|
|
__asm volatile("prefetcht0 %0" :: "m" (*(unsigned long *)x));
|
|
}
|
|
|
|
#else
|
|
#define prefetch(x)
|
|
#endif
|
|
#endif
|
|
|
|
#endif /* #ifndef _QLNX_DEF_H_ */
|