#ifndef _IGC_H
#define _IGC_H
#include <sys/types.h>
#include <sys/mac_provider.h>
#include <sys/mac_ether.h>
#include <sys/vlan.h>
#include <sys/dlpi.h>
#include <sys/pattr.h>
#include <sys/list.h>
#include <core/igc_hw.h>
#include <core/igc_api.h>
#ifdef __cplusplus
extern "C" {
#endif
#define IGC_MOD_NAME "igc"
#define IGC_PCI_BAR 1
#define IGC_MAX_RX_RINGS_I225 4
#define IGC_MAX_TX_RINGS_I225 4
#define IGC_MAX_MTU_I225 9216
#define IGC_DEFAULT_ADV IGC_ALL_SPEED_DUPLEX_2500
#define IGC_FC_PAUSE_TIME 0x0680
#define IGC_DEF_RX_RING_SIZE 512
#define IGC_DEF_TX_RING_SIZE 512
#define IGC_DEF_RX_RING_INTR_LIMIT 256
#define IGC_DEF_RX_BIND 256
#define IGC_DEF_TX_BIND 512
#define IGC_DEF_TX_NOTIFY_MIN 4
#define IGC_DEF_TX_RECYCLE_MIN 32
#define IGC_DEF_TX_GAP 2
#define IGC_MAX_TX_COOKIES 18
#define IGC_RX_BUF_IP_ALIGN 2
#define IGC_BUF_ALIGN 0x400
#define IGC_RX_POLL_INTR -1
#define IGC_DEF_EITR 200
#ifdef DEBUG
#define IGC_DMA_SYNC(buf, flag) ASSERT0(ddi_dma_sync((buf)->idb_hdl, \
0, 0, flag))
#else
#define IGC_DMA_SYNC(buf, flag) (void) ddi_dma_sync((buf)->idb_hdl, \
0, 0, flag)
#endif
typedef enum igc_attach {
IGC_ATTACH_REGS = 1 << 0,
IGC_ATTACH_INTR_ALLOC = 1 << 1,
IGC_ATTACH_MUTEX = 1 << 2,
IGC_ATTACH_INTR_HANDLER = 1 << 3,
IGC_ATTACH_LED = 1 << 4,
IGC_ATTACH_STATS = 1 << 5,
IGC_ATTACH_MAC = 1 << 6,
IGC_ATTACH_INTR_EN = 1 << 7,
IGC_ATTACH_MAC_START = 1 << 8,
IGC_ATTACH_RX_DATA = 1 << 9,
IGC_ATTACH_TX_DATA = 1 << 10
} igc_attach_t;
typedef struct igc_limits {
uint32_t il_max_rx_rings;
uint32_t il_max_tx_rings;
uint32_t il_max_mtu;
} igc_limits_t;
typedef struct igc_dma_buffer {
caddr_t idb_va;
ddi_acc_handle_t idb_acc;
ddi_dma_handle_t idb_hdl;
size_t idb_size;
size_t idb_alloc_len;
} igc_dma_buffer_t;
typedef struct igc_rx_buffer {
struct igc_rx_ring *irb_ring;
mblk_t *irb_mp;
igc_dma_buffer_t irb_dma;
frtn_t irb_free_rtn;
bool irb_loaned;
} igc_rx_buffer_t;
typedef enum igc_rx_ring_flags {
IGC_RXR_F_POLL = 1 << 0
} igc_rx_ring_flags_t;
typedef struct igc_rx_stats {
kstat_named_t irs_rbytes;
kstat_named_t irs_ipackets;
kstat_named_t irs_desc_error;
kstat_named_t irs_copy_nomem;
kstat_named_t irs_bind_nobuf;
kstat_named_t irs_bind_nomp;
kstat_named_t irs_nbind;
kstat_named_t irs_ncopy;
kstat_named_t irs_ixsm;
kstat_named_t irs_l3cksum_err;
kstat_named_t irs_l4cksum_err;
kstat_named_t irs_hcksum_miss;
kstat_named_t irs_hcksum_hit;
} igc_rx_stats_t;
typedef struct igc_rx_ring {
struct igc *irr_igc;
igc_rx_ring_flags_t irr_flags;
uint32_t irr_idx;
uint32_t irr_intr_idx;
mac_ring_handle_t irr_rh;
kmutex_t irr_lock;
uint64_t irr_gen;
igc_rx_stats_t irr_stat;
kstat_t *irr_kstat;
igc_dma_buffer_t irr_desc_dma;
union igc_adv_rx_desc *irr_ring;
uint32_t irr_next;
igc_rx_buffer_t *irr_arena;
igc_rx_buffer_t **irr_work_list;
igc_rx_buffer_t **irr_free_list;
kmutex_t irr_free_lock;
kcondvar_t irr_free_cv;
uint32_t irr_nfree;
} igc_rx_ring_t;
typedef struct igc_tx_buffer {
list_node_t itb_node;
mblk_t *itb_mp;
igc_dma_buffer_t itb_dma;
ddi_dma_handle_t itb_bind_hdl;
bool itb_first;
bool itb_bind;
uint32_t itb_last_desc;
size_t itb_len;
} igc_tx_buffer_t;
typedef struct igc_tx_context_data {
uint8_t itc_l2hlen;
uint8_t itc_l3hlen;
uint8_t itc_l4hlen;
uint8_t itc_l4proto;
uint16_t itc_l3proto;
uint32_t itc_mss;
uint32_t itc_cksum;
uint32_t itc_lso;
} igc_tx_context_data_t;
typedef struct igc_tx_stats {
kstat_named_t its_obytes;
kstat_named_t its_opackets;
kstat_named_t its_bad_meo;
kstat_named_t its_ring_full;
kstat_named_t its_no_tx_bufs;
kstat_named_t its_tx_copy;
kstat_named_t its_tx_bind;
kstat_named_t its_tx_bind_fail;
} igc_tx_stats_t;
typedef struct igc_tx_ring {
struct igc *itr_igc;
uint32_t itr_idx;
uint32_t itr_intr_idx;
mac_ring_handle_t itr_rh;
kmutex_t itr_lock;
igc_tx_stats_t itr_stat;
kstat_t *itr_kstat;
igc_dma_buffer_t itr_desc_dma;
union igc_adv_tx_desc *itr_ring;
uint32_t itr_ring_head;
uint32_t itr_ring_tail;
uint32_t itr_ring_free;
bool itr_mac_blocked;
bool itr_recycle;
igc_tx_context_data_t itr_tx_ctx;
igc_tx_buffer_t *itr_arena;
igc_tx_buffer_t **itr_work_list;
list_t itr_free_list;
} igc_tx_ring_t;
typedef struct igc_addr {
uint8_t ia_mac[ETHERADDRL];
bool ia_valid;
} igc_addr_t;
typedef struct igc_stats {
kstat_named_t is_crcerrs;
kstat_named_t is_algnerrc;
kstat_named_t is_mpc;
kstat_named_t is_scc;
kstat_named_t is_ecol;
kstat_named_t is_mcc;
kstat_named_t is_latecol;
kstat_named_t is_colc;
kstat_named_t is_rerc;
kstat_named_t is_dc;
kstat_named_t is_tncrs;
kstat_named_t is_htdpmc;
kstat_named_t is_rlec;
kstat_named_t is_xonrxc;
kstat_named_t is_xontxc;
kstat_named_t is_xoffrxc;
kstat_named_t is_xofftxc;
kstat_named_t is_fcruc;
kstat_named_t is_prc64;
kstat_named_t is_prc127;
kstat_named_t is_prc255;
kstat_named_t is_prc1023;
kstat_named_t is_prc1522;
kstat_named_t is_gprc;
kstat_named_t is_bprc;
kstat_named_t is_mprc;
kstat_named_t is_gptc;
kstat_named_t is_gorc;
kstat_named_t is_gotc;
kstat_named_t is_rnbc;
kstat_named_t is_ruc;
kstat_named_t is_rfc;
kstat_named_t is_roc;
kstat_named_t is_rjc;
kstat_named_t is_mgtprc;
kstat_named_t is_mgtpdc;
kstat_named_t is_mgtptc;
kstat_named_t is_tor;
kstat_named_t is_tot;
kstat_named_t is_tpr;
kstat_named_t is_tpt;
kstat_named_t is_ptc64;
kstat_named_t is_ptc127;
kstat_named_t is_ptc255;
kstat_named_t is_ptc511;
kstat_named_t is_ptc1023;
kstat_named_t is_ptc1522;
kstat_named_t is_mptc;
kstat_named_t is_bptc;
kstat_named_t is_tsctc;
kstat_named_t is_iac;
kstat_named_t is_rxdmtc;
} igc_stats_t;
typedef struct igc {
dev_info_t *igc_dip;
igc_attach_t igc_attach;
ddi_acc_handle_t igc_cfgspace;
caddr_t igc_regs_base;
off_t igc_regs_size;
ddi_acc_handle_t igc_regs_hdl;
uint_t igc_intr_pri;
int igc_intr_cap;
uint_t igc_intr_type;
size_t igc_intr_size;
int igc_nintrs;
ddi_intr_handle_t *igc_intr_handles;
uint32_t igc_eims;
struct igc_hw igc_hw;
igc_limits_t igc_limits;
uint32_t igc_nrx_rings;
uint32_t igc_ntx_rings;
uint32_t igc_rx_ndesc;
uint32_t igc_tx_ndesc;
uint32_t igc_rx_nbuf;
uint32_t igc_tx_nbuf;
uint32_t igc_rx_nfree;
uint32_t igc_rx_intr_nframes;
uint32_t igc_rx_bind_thresh;
uint32_t igc_tx_bind_thresh;
uint32_t igc_tx_notify_thresh;
uint32_t igc_tx_recycle_thresh;
uint32_t igc_tx_gap;
uint32_t igc_eitr;
kmutex_t igc_lock;
uint32_t igc_mtu;
uint32_t igc_max_frame;
uint32_t igc_rx_buf_size;
uint32_t igc_tx_buf_size;
uint16_t igc_nucast;
uint16_t igc_nmcast;
igc_addr_t *igc_ucast;
igc_addr_t *igc_mcast;
ether_addr_t *igc_mcast_raw;
link_state_t igc_link_state;
link_duplex_t igc_link_duplex;
uint16_t igc_link_speed;
mac_led_mode_t igc_led_mode;
bool igc_promisc;
igc_rx_ring_t *igc_rx_rings;
igc_tx_ring_t *igc_tx_rings;
mac_handle_t igc_mac_hdl;
mac_group_handle_t igc_rxg_hdl;
uint32_t igc_ledctl;
uint32_t igc_ledctl_on;
uint32_t igc_ledctl_off;
uint32_t igc_ledctl_blink;
kstat_t *igc_ksp;
igc_stats_t igc_stats;
uint16_t igc_phy_ctrl;
uint16_t igc_phy_status;
uint16_t igc_phy_an_adv;
uint16_t igc_phy_an_exp;
uint16_t igc_phy_lp;
uint16_t igc_phy_1000t_ctrl;
uint16_t igc_phy_1000t_status;
uint16_t igc_phy_ext_status;
uint16_t igc_phy_mmd_ctrl;
uint16_t igc_phy_mmd_sts;
} igc_t;
extern uint32_t igc_read32(igc_t *igc, uint32_t);
extern void igc_write32(igc_t *igc, uint32_t, uint32_t);
extern void igc_hw_buf_update(igc_t *);
extern bool igc_hw_common_init(igc_t *);
extern void igc_multicast_sync(igc_t *);
extern void igc_hw_intr_enable(igc_t *igc);
extern void igc_hw_intr_disable(igc_t *igc);
extern bool igc_rx_data_alloc(igc_t *);
extern void igc_rx_data_free(igc_t *);
extern void igc_rx_hw_init(igc_t *);
extern mblk_t *igc_ring_rx(igc_rx_ring_t *, int);
extern void igc_rx_drain(igc_t *);
extern mblk_t *igc_ring_tx(void *, mblk_t *);
extern void igc_tx_recycle(igc_t *, igc_tx_ring_t *);
extern bool igc_tx_data_alloc(igc_t *);
extern void igc_tx_data_free(igc_t *);
extern void igc_tx_hw_init(igc_t *);
extern bool igc_stats_init(igc_t *);
extern void igc_stats_fini(igc_t *);
extern bool igc_rx_ring_stats_init(igc_t *, igc_rx_ring_t *);
extern void igc_rx_ring_stats_fini(igc_rx_ring_t *);
extern bool igc_tx_ring_stats_init(igc_t *, igc_tx_ring_t *);
extern void igc_tx_ring_stats_fini(igc_tx_ring_t *);
extern void igc_stats_update_u64(igc_t *, kstat_named_t *, uint32_t);
extern bool igc_mac_register(igc_t *);
#ifdef __cplusplus
}
#endif
#endif