#ifndef _SYS_NGE_H
#define _SYS_NGE_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/types.h>
#include <sys/stream.h>
#include <sys/strsun.h>
#include <sys/strsubr.h>
#include <sys/stat.h>
#include <sys/pci.h>
#include <sys/note.h>
#include <sys/modctl.h>
#include <sys/kstat.h>
#include <sys/ethernet.h>
#include <sys/pattr.h>
#include <sys/errno.h>
#include <sys/dlpi.h>
#include <sys/devops.h>
#include <sys/debug.h>
#include <sys/conf.h>
#include <sys/callb.h>
#include <netinet/ip6.h>
#include <inet/common.h>
#include <inet/ip.h>
#include <netinet/udp.h>
#include <inet/mi.h>
#include <inet/nd.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/mac_provider.h>
#include <sys/mac_ether.h>
extern int secpolicy_net_config(const cred_t *, boolean_t);
#include <sys/netlb.h>
#include <sys/miiregs.h>
#include "nge_chip.h"
#define PIO_ADDR(ngep, offset) ((void *)((caddr_t)(ngep)->io_regs+(offset)))
#define ethaddr_copy(src, dst) bcopy((src), (dst), ETHERADDRL)
#define ether_eq(a, b) (bcmp((caddr_t)(a), (caddr_t)(b), (ETHERADDRL)) == 0)
#define BIS(w, b) (((w) & (b)) ? B_TRUE : B_FALSE)
#define BIC(w, b) (((w) & (b)) ? B_FALSE : B_TRUE)
#define UPORDOWN(x) ((x) ? "up" : "down")
#define NGE_DRIVER_NAME "nge"
#define PROGRESS_CFG 0x0001
#define PROGRESS_REGS 0x0002
#define PROGRESS_BUFS 0x0004
#define PROGRESS_RESCHED 0x0008
#define PROGRESS_FACTOTUM 0x0010
#define PROGRESS_SWINT 0x0020
#define PROGRESS_INTR 0x0040
#define PROGRESS_HWINT 0x0080
#define PROGRESS_PHY 0x0100
#define PROGRESS_NDD 0x0200
#define PROGRESS_KSTATS 0x0400
#define PROGRESS_READY 0x0800
#define NGE_HW_ERR 0x00
#define NGE_HW_LINK 0x01
#define NGE_HW_BM 0x02
#define NGE_HW_RCHAN 0x03
#define NGE_HW_TCHAN 0x04
#define NGE_HW_ROM 0x05
#define NGE_SW_PROBLEM_ID 0x06
#define NGE_PCI_OPREGS_RNUMBER 1
#define NGE_DMA_MODE DDI_DMA_STREAMING
#define NGE_HEADROOM 6
#define ETHER_HEAD_LEN 14
#ifndef VTAG_SIZE
#define VTAG_SIZE 4
#endif
#define NGE_CYCLIC_PERIOD (1000000000)
#define NGE_DEFAULT_MTU 1500
#define NGE_DEFAULT_SDU 1518
#define NGE_MTU_2500 2500
#define NGE_MTU_4500 4500
#define NGE_MAX_MTU 9000
#define NGE_MAX_SDU 9018
#define NGE_DESC_MIN 0x200
#define NGE_STD_BUFSZ 1792
#define NGE_JB2500_BUFSZ (3*1024)
#define NGE_JB4500_BUFSZ (5*1024)
#define NGE_JB9000_BUFSZ (9*1024)
#define NGE_SEND_SLOTS_DESC_1024 1024
#define NGE_SEND_SLOTS_DESC_3072 3072
#define NGE_SEND_JB2500_SLOTS_DESC 3072
#define NGE_SEND_JB4500_SLOTS_DESC 2048
#define NGE_SEND_JB9000_SLOTS_DESC 1024
#define NGE_SEND_LOWMEM_SLOTS_DESC 1024
#define NGE_SEND_SLOTS_BUF 3072
#define NGE_RECV_SLOTS_DESC_1024 1024
#define NGE_RECV_SLOTS_DESC_3072 3072
#define NGE_RECV_JB2500_SLOTS_DESC 3072
#define NGE_RECV_JB4500_SLOTS_DESC 2048
#define NGE_RECV_JB9000_SLOTS_DESC 1024
#define NGE_RECV_LOWMEM_SLOTS_DESC 1024
#define NGE_RECV_SLOTS_BUF 6144
#define NGE_SPLIT_32 32
#define NGE_SPLIT_96 96
#define NGE_SPLIT_256 256
#define NGE_RX_COPY_SIZE 512
#define NGE_TX_COPY_SIZE 512
#define NGE_MAP_FRAGS 3
#define NGE_MAX_COOKIES 3
#define NGE_MAX_DMA_HDR (4*1024)
#define NGE_TFINT_DEFAULT 32
#define NGE_POLL_TUNE 80000
#define NGE_POLL_ENTER 10000
#define NGE_POLL_MAX 1280000
#define NGE_POLL_QUIET_TIME 100
#define NGE_POLL_BUSY_TIME 2
#define NGE_IOC ((((('N' << 8) + 'G') << 8) + 'E') << 8)
#define NGE_MII_READ (NGE_IOC|1)
#define NGE_MII_WRITE (NGE_IOC|2)
#define NGE_SEE_READ (NGE_IOC|3)
#define NGE_SEE_WRITE (NGE_IOC|4)
#define NGE_DIAG (NGE_IOC|5)
#define NGE_PEEK (NGE_IOC|6)
#define NGE_POKE (NGE_IOC|7)
#define NGE_PHY_RESET (NGE_IOC|8)
#define NGE_SOFT_RESET (NGE_IOC|9)
#define NGE_HARD_RESET (NGE_IOC|10)
enum NGE_HW_OP {
NGE_CLEAR = 0,
NGE_SET
};
enum nge_mac_state {
NGE_MAC_UNKNOWN,
NGE_MAC_RESET,
NGE_MAC_STOPPED,
NGE_MAC_STARTED,
NGE_MAC_UNATTACH
};
enum loop_type {
NGE_LOOP_NONE = 0,
NGE_LOOP_EXTERNAL_100,
NGE_LOOP_EXTERNAL_10,
NGE_LOOP_INTERNAL_PHY,
};
enum send_status {
SEND_COPY_FAIL = -1,
SEND_MAP_FAIL,
SEND_COPY_SUCESS,
SEND_MAP_SUCCESS
};
enum ioc_reply {
IOC_INVAL = -1,
IOC_DONE,
IOC_ACK,
IOC_REPLY,
IOC_RESTART_ACK,
IOC_RESTART_REPLY
};
enum nge_pp_type {
NGE_PP_SPACE_CFG = 0,
NGE_PP_SPACE_REG,
NGE_PP_SPACE_NIC,
NGE_PP_SPACE_MII,
NGE_PP_SPACE_NGE,
NGE_PP_SPACE_TXDESC,
NGE_PP_SPACE_TXBUFF,
NGE_PP_SPACE_RXDESC,
NGE_PP_SPACE_RXBUFF,
NGE_PP_SPACE_STATISTICS,
NGE_PP_SPACE_SEEPROM,
NGE_PP_SPACE_FLASH
};
enum nge_kstat_type {
NGE_KSTAT_RAW = 0,
NGE_KSTAT_STATS,
NGE_KSTAT_CHIPID,
NGE_KSTAT_DEBUG,
NGE_KSTAT_COUNT
};
enum nge_chip_state {
NGE_CHIP_FAULT = -2,
NGE_CHIP_ERROR,
NGE_CHIP_INITIAL,
NGE_CHIP_RESET,
NGE_CHIP_STOPPED,
NGE_CHIP_RUNNING
};
enum nge_eeprom_size {
EEPROM_1K = 0,
EEPROM_2K,
EEPROM_4K,
EEPROM_8K,
EEPROM_16K,
EEPROM_32K,
EEPROM_64K
};
enum nge_eeprom_access_wid {
ACCESS_8BIT = 0,
ACCESS_16BIT
};
enum nge_mdio_operation {
NGE_MDIO_READ = 0,
NGE_MDIO_WRITE
};
enum nge_speed {
UNKOWN_SPEED = 0,
NGE_10M,
NGE_100M,
NGE_1000M
};
enum nge_duplex {
UNKOWN_DUPLEX = 0,
NGE_HD,
NGE_FD
};
typedef struct {
ether_addr_t addr;
uint8_t spare;
uint8_t set;
} nge_mac_addr_t;
struct nge;
#define CHIP_FLAG_COPPER 0x40
typedef struct {
boolean_t (*phys_restart)(struct nge *);
void (*phys_update)(struct nge *);
boolean_t (*phys_check)(struct nge *);
} phys_ops_t;
struct nge_see_rw {
uint32_t see_addr;
uint32_t see_data;
};
typedef struct {
uint64_t pp_acc_size;
uint64_t pp_acc_space;
uint64_t pp_acc_offset;
uint64_t pp_acc_data;
} nge_peekpoke_t;
typedef uintptr_t nge_regno_t;
typedef struct _mul_list {
struct _mul_list *next;
uint32_t ref_cnt;
ether_addr_t mul_addr;
}mul_item, *pmul_item;
typedef struct dma_area
{
caddr_t private;
frtn_t rx_recycle;
mblk_t *mp;
ddi_acc_handle_t acc_hdl;
void *mem_va;
uint32_t nslots;
uint32_t size;
size_t alength;
ddi_dma_handle_t dma_hdl;
offset_t offset;
ddi_dma_cookie_t cookie;
uint32_t ncookies;
uint32_t signature;
boolean_t rx_delivered;
struct dma_area *next;
} dma_area_t;
#define HOST_OWN 0x00000000
#define CONTROLER_OWN 0x00000001
#define NGE_END_PACKET 0x00000002
typedef struct nge_dmah_node
{
struct nge_dmah_node *next;
ddi_dma_handle_t hndl;
} nge_dmah_node_t;
typedef struct nge_dmah_list
{
nge_dmah_node_t *head;
nge_dmah_node_t *tail;
} nge_dmah_list_t;
typedef struct sw_rx_sbd {
dma_area_t desc;
dma_area_t *bufp;
uint8_t flags;
} sw_rx_sbd_t;
typedef struct sw_tx_sbd {
dma_area_t desc;
dma_area_t pbuf;
void (*tx_recycle)(struct sw_tx_sbd *);
uint32_t flags;
mblk_t *mp;
nge_dmah_list_t mp_hndl;
uint32_t frags;
uint32_t ncookies;
} sw_tx_sbd_t;
typedef struct buff_ring {
uint64_t nslots;
struct nge *ngep;
uint64_t rx_hold;
sw_rx_sbd_t *sw_rbds;
sw_rx_sbd_t *free_rbds;
dma_area_t *free_list;
dma_area_t *recycle_list;
kmutex_t recycle_lock[1];
uint32_t buf_sign;
boolean_t rx_bcopy;
} buff_ring_t;
typedef struct recv_ring {
dma_area_t desc;
struct nge *ngep;
uint16_t prod_index;
mac_resource_handle_t handle;
} recv_ring_t;
typedef struct send_ring {
dma_area_t desc;
dma_area_t buf[NGE_SEND_SLOTS_BUF];
struct nge *ngep;
uint32_t tx_hwmark;
uint32_t tx_lwmark;
kmutex_t tx_lock[1];
uint32_t tx_next;
uint32_t tx_flow;
uint32_t tx_free;
kmutex_t tc_lock[1];
uint32_t tc_next;
sw_tx_sbd_t *sw_sbds;
kmutex_t dmah_lock;
nge_dmah_list_t dmah_free;
nge_dmah_node_t dmahndl[NGE_MAX_DMA_HDR];
} send_ring_t;
typedef struct {
uint32_t businfo;
uint16_t command;
uint16_t vendor;
uint16_t device;
uint16_t subven;
uint16_t subdev;
uint8_t class_code;
uint8_t revision;
uint8_t clsize;
uint8_t latency;
uint8_t flags;
uint16_t phy_type;
uint64_t hw_mac_addr;
nge_mac_addr_t vendor_addr;
} chip_info_t;
typedef struct {
offset_t index;
char *name;
} nge_ksindex_t;
typedef struct {
uint64_t tso_err_mss;
uint64_t tso_dis;
uint64_t tso_err_nosum;
uint64_t tso_err_hov;
uint64_t tso_err_huf;
uint64_t tso_err_l2;
uint64_t tso_err_ip;
uint64_t tso_err_l4;
uint64_t tso_err_tcp;
uint64_t hsum_err_ip;
uint64_t hsum_err_l4;
}fe_statistics_t;
typedef struct {
uint64_t intr_count;
uint64_t intr_lval;
uint64_t recv_realloc;
uint64_t poll_time;
uint64_t recy_free;
uint64_t recv_count;
uint64_t xmit_count;
uint64_t obytes;
uint64_t rbytes;
uint64_t mp_alloc_err;
uint64_t dma_alloc_err;
uint64_t kmem_alloc_err;
uint64_t load_context;
uint64_t ip_hwsum_err;
uint64_t tcp_hwsum_err;
uint64_t rx_nobuffer;
uint64_t rx_err;
uint64_t tx_stop_err;
uint64_t tx_stall;
uint64_t tx_rsrv_fail;
uint64_t tx_resched;
fe_statistics_t fe_err;
}nge_sw_statistics_t;
typedef struct {
nge_hw_statistics_t hw_statistics;
nge_sw_statistics_t sw_statistics;
}nge_statistics_t;
struct nge_desc_attr {
size_t rxd_size;
size_t txd_size;
ddi_dma_attr_t *dma_attr;
ddi_dma_attr_t *tx_dma_attr;
void (*rxd_fill)(void *, const ddi_dma_cookie_t *, size_t);
uint32_t (*rxd_check)(const void *, size_t *);
void (*txd_fill)(void *, const ddi_dma_cookie_t *, size_t,
uint32_t, boolean_t, boolean_t);
uint32_t (*txd_check)(const void *);
};
typedef struct nge_desc_attr nge_desc_attr_t;
typedef struct nge_dev_spec_param {
boolean_t msi;
boolean_t msi_x;
boolean_t vlan;
boolean_t advanced_pm;
boolean_t mac_addr_order;
boolean_t tx_pause_frame;
boolean_t rx_pause_frame;
boolean_t jumbo;
boolean_t tx_rx_64byte;
boolean_t rx_hw_checksum;
uint32_t tx_hw_checksum;
uint32_t desc_type;
uint32_t rx_desc_num;
uint32_t tx_desc_num;
uint32_t nge_split;
} nge_dev_spec_param_t;
typedef struct nge {
dev_info_t *devinfo;
mac_handle_t mh;
chip_info_t chipinfo;
ddi_acc_handle_t cfg_handle;
ddi_acc_handle_t io_handle;
void *io_regs;
ddi_periodic_t periodic_id;
uint32_t factotum_flag;
ddi_softint_handle_t factotum_hdl;
ddi_softint_handle_t resched_hdl;
uint_t soft_pri;
ddi_intr_handle_t *htable;
int intr_type;
int intr_actual_cnt;
int intr_req_cnt;
uint_t intr_pri;
int intr_cap;
uint32_t progress;
uint32_t debug;
char ifname[8];
enum nge_mac_state nge_mac_state;
enum nge_chip_state nge_chip_state;
boolean_t promisc;
boolean_t record_promisc;
boolean_t suspended;
int resched_needed;
uint32_t default_mtu;
uint32_t max_sdu;
uint32_t buf_size;
uint32_t rx_desc;
uint32_t tx_desc;
uint32_t rx_buf;
uint32_t nge_split;
uint32_t watchdog;
uint32_t lowmem_mode;
struct buff_ring buff[1];
struct recv_ring recv[1];
struct send_ring send[1];
kmutex_t genlock[1];
krwlock_t rwlock[1];
kmutex_t softlock[1];
uint32_t intr_masks;
boolean_t poll;
boolean_t ch_intr_mode;
boolean_t intr_moderation;
uint32_t recv_count;
uint32_t quiet_time;
uint32_t busy_time;
uint64_t tpkts_last;
uint32_t tfint_threshold;
uint32_t sw_intr_intv;
nge_mac_addr_t cur_uni_addr;
uint32_t rx_datahwm;
uint32_t rx_prdlwm;
uint32_t rx_prdhwm;
uint32_t rx_def;
uint32_t desc_mode;
mul_item *pcur_mulist;
nge_mac_addr_t cur_mul_addr;
nge_mac_addr_t cur_mul_mask;
nge_desc_attr_t desc_attr;
int32_t link_state;
uint32_t stall_cknum;
uint32_t phy_xmii_addr;
uint32_t phy_id;
uint32_t phy_mode;
const phys_ops_t *physops;
uint16_t phy_gen_status;
uint32_t param_loop_mode;
kstat_t *nge_kstats[NGE_KSTAT_COUNT];
nge_statistics_t statistics;
nge_dev_spec_param_t dev_spec_param;
uint32_t param_en_pause:1,
param_en_asym_pause:1,
param_en_1000hdx:1,
param_en_1000fdx:1,
param_en_100fdx:1,
param_en_100hdx:1,
param_en_10fdx:1,
param_en_10hdx:1,
param_adv_autoneg:1,
param_adv_pause:1,
param_adv_asym_pause:1,
param_adv_1000fdx:1,
param_adv_1000hdx:1,
param_adv_100fdx:1,
param_adv_100hdx:1,
param_adv_10fdx:1,
param_adv_10hdx:1,
param_lp_autoneg:1,
param_lp_pause:1,
param_lp_asym_pause:1,
param_lp_1000fdx:1,
param_lp_1000hdx:1,
param_lp_100fdx:1,
param_lp_100hdx:1,
param_lp_10fdx:1,
param_lp_10hdx:1,
param_link_up:1,
param_link_autoneg:1,
param_link_rx_pause:1,
param_link_tx_pause:1,
param_pad_to_32:2;
uint64_t param_link_speed;
link_duplex_t param_link_duplex;
int param_txbcopy_threshold;
int param_rxbcopy_threshold;
int param_recv_max_packet;
int param_poll_quiet_time;
int param_poll_busy_time;
int param_rx_intr_hwater;
int param_rx_intr_lwater;
} nge_t;
extern const nge_ksindex_t nge_statistics[];
#define DMA_SYNC(area, flag) ((void) ddi_dma_sync((area).dma_hdl, \
(area).offset, (area).alength, (flag)))
#define DMA_VPTR(area) ((area).mem_va)
#define DMA_ZERO(area) bzero(DMA_VPTR(area), (area).alength)
#define NEXT(index, limit) ((index) + 1 < (limit) ? (index) + 1 : 0)
#define PREV(index, limit) (0 == (index) ? (limit - 1) : (index) - 1)
#define NEXT_INDEX(ndx, num, lim)\
(((ndx) + (num) < (lim)) ? ((ndx) + (num)) : ((ndx) + (num) - (lim)))
#define NGE_PROP_EXISTS(d, n) ddi_prop_exists(DDI_DEV_T_ANY, (d), \
DDI_PROP_DONTPASS, (n))
#define NGE_PROP_GET_INT(d, n) ddi_prop_get_int(DDI_DEV_T_ANY, (d), \
DDI_PROP_DONTPASS, (n), -1)
#ifdef DEBUG
#define NGE_DEBUGGING 1
#else
#define NGE_DEBUGGING 0
#endif
#define NGE_DBG_STOP 0x00000001
#define NGE_DBG_TRACE 0x00000002
#define NGE_DBG_MII 0x00000010
#define NGE_DBG_CHIP 0x00000020
#define NGE_DBG_RECV 0x00000100
#define NGE_DBG_SEND 0x00000200
#define NGE_DBG_INIT 0x00100000
#define NGE_DBG_NEMO 0x00200000
#define NGE_DBG_STATS 0x00400000
#define NGE_DBG_BADIOC 0x01000000
#define NGE_DBG_NDD 0x10000000
#if NGE_DEBUGGING
#define NGE_DDB(command) do { \
{ command; } \
_NOTE(CONSTANTCONDITION) \
} while (0)
#else
#define NGE_DDB(command)
#endif
#define NGE_XDB(b, w, f, args) NGE_DDB(if ((b) & (w)) f args)
#define NGE_GDB(b, args) NGE_XDB(b, nge_debug, (*nge_gdb()), args)
#define NGE_LDB(b, args) NGE_XDB(b, ngep->debug, \
(*nge_db(ngep)), args)
#define NGE_CDB(f, args) NGE_XDB(NGE_DBG, ngep->debug, f, args)
#define NGE_TRC NGE_DBG_TRACE
#define NGE_GTRACE(args) NGE_GDB(NGE_TRC, args)
#define NGE_GDEBUG(args) NGE_GDB(NGE_DBG, args)
#define NGE_TRACE(args) NGE_LDB(NGE_TRC, args)
#define NGE_DEBUG(args) NGE_LDB(NGE_DBG, args)
#define NGE_REPORT(args) NGE_DDB(nge_log args)
boolean_t nge_atomic_decrease(uint64_t *count_p, uint64_t n);
void nge_atomic_increase(uint64_t *count_p, uint64_t n);
int nge_alloc_dma_mem(nge_t *ngep, size_t memsize,
ddi_device_acc_attr_t *attr_p, uint_t dma_flags, dma_area_t *dma_p);
void nge_free_dma_mem(dma_area_t *dma_p);
int nge_restart(nge_t *ngep);
void nge_wake_factotum(nge_t *ngep);
uint8_t nge_reg_get8(nge_t *ngep, nge_regno_t regno);
void nge_reg_put8(nge_t *ngep, nge_regno_t regno, uint8_t data);
uint16_t nge_reg_get16(nge_t *ngep, nge_regno_t regno);
void nge_reg_put16(nge_t *ngep, nge_regno_t regno, uint16_t data);
uint32_t nge_reg_get32(nge_t *ngep, nge_regno_t regno);
void nge_reg_put32(nge_t *ngep, nge_regno_t regno, uint32_t data);
uint_t nge_chip_factotum(caddr_t args1, caddr_t args2);
void nge_chip_cfg_init(nge_t *ngep, chip_info_t *infop, boolean_t reset);
void nge_init_dev_spec_param(nge_t *ngep);
int nge_chip_stop(nge_t *ngep, boolean_t fault);
void nge_restore_mac_addr(nge_t *ngep);
int nge_chip_reset(nge_t *ngep);
int nge_chip_start(nge_t *ngep);
void nge_chip_sync(nge_t *ngep);
uint_t nge_chip_intr(caddr_t arg1, caddr_t arg2);
enum ioc_reply nge_chip_ioctl(nge_t *ngep, mblk_t *mp, struct iocblk *iocp);
void nge_phys_init(nge_t *ngep);
boolean_t nge_phy_reset(nge_t *ngep);
uint16_t nge_mii_get16(nge_t *ngep, nge_regno_t regno);
void nge_mii_put16(nge_t *ngep, nge_regno_t regno, uint16_t data);
void nge_recv_recycle(caddr_t arg);
void nge_receive(nge_t *ngep);
uint_t nge_reschedule(caddr_t args1, caddr_t args2);
mblk_t *nge_m_tx(void *arg, mblk_t *mp);
void nge_tx_recycle(nge_t *ngep, boolean_t is_intr);
void nge_tx_recycle_all(nge_t *ngep);
int nge_nd_init(nge_t *ngep);
void nge_nd_cleanup(nge_t *ngep);
void nge_init_kstats(nge_t *ngep, int instance);
void nge_fini_kstats(nge_t *ngep);
int nge_m_stat(void *arg, uint_t stat, uint64_t *val);
uint32_t nge_atomic_shl32(uint32_t *sp, uint_t count);
void nge_log(nge_t *ngep, const char *fmt, ...);
void nge_problem(nge_t *ngep, const char *fmt, ...);
void nge_error(nge_t *ngep, const char *fmt, ...);
void
nge_report(nge_t *ngep, uint8_t error_id);
void (*nge_db(nge_t *ngep))(const char *fmt, ...);
void (*nge_gdb(void))(const char *fmt, ...);
extern uint32_t nge_debug;
extern void nge_sum_rxd_fill(void *, const ddi_dma_cookie_t *, size_t);
extern uint32_t nge_sum_rxd_check(const void *, size_t *);
extern void nge_sum_txd_fill(void *, const ddi_dma_cookie_t *,
size_t, uint32_t, boolean_t, boolean_t);
extern uint32_t nge_sum_txd_check(const void *);
extern void nge_hot_rxd_fill(void *, const ddi_dma_cookie_t *, size_t);
extern uint32_t nge_hot_rxd_check(const void *, size_t *);
extern void nge_hot_txd_fill(void *, const ddi_dma_cookie_t *,
size_t, uint32_t, boolean_t, boolean_t);
extern uint32_t nge_hot_txd_check(const void *);
#ifdef __cplusplus
}
#endif
#endif