nge.h revision da14cebe459d3275048785f25bd869cb09b5307f
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#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>
/*
* Reconfiguring the network devices requires the net_config privilege
* in Solaris 10+.
*/
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)))
/*
* Copy an ethernet address
*/
#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"
/*
* 'Progress' bit flags ...
*/
#define PROGRESS_CFG 0x0001 /* config space mapped */
#define PROGRESS_REGS 0x0002 /* registers mapped */
#define PROGRESS_BUFS 0x0004 /* registers mapped */
#define PROGRESS_RESCHED 0x0008 /* resched softint registered */
#define PROGRESS_FACTOTUM 0x0010 /* factotum softint registered */
#define PROGRESS_SWINT 0x0020 /* s/w interrupt registered */
#define PROGRESS_INTR 0x0040 /* h/w interrupt registered */
/* and mutexen initialised */
#define PROGRESS_HWINT 0x0080
#define PROGRESS_PHY 0x0100 /* PHY initialised */
#define PROGRESS_NDD 0x0200 /* NDD parameters set up */
#define PROGRESS_KSTATS 0x0400 /* kstats created */
#define PROGRESS_READY 0x0800 /* ready for work */
#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
/*
* NOTES:
*
* #defines:
*
* NGE_PCI_CONFIG_RNUMBER and NGE_PCI_OPREGS_RNUMBER are the
* register-set numbers to use for the config space registers
* and the operating registers respectively. On an OBP-based
* machine, regset 0 refers to CONFIG space, and regset 1 will
* be the operating registers in MEMORY space. If an expansion
* ROM is fitted, it may appear as a further register set.
*
* NGE_DMA_MODE defines the mode (STREAMING/CONSISTENT) used
* for the data buffers. The descriptors are always set up
* in CONSISTENT mode.
*
* NGE_HEADROOM defines how much space we'll leave in allocated
* mblks before the first valid data byte. This should be chosen
* to be 2 modulo 4, so that once the ethernet header (14 bytes)
* has been stripped off, the packet data will be 4-byte aligned.
* The remaining space can be used by upstream modules to prepend
* any headers required.
*/
#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_HALFTICK 268435456LL /* 2**28 ns! */
#define NGE_CYCLIC_PERIOD (4*NGE_HALFTICK) /* ~0.5s */
#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)
/* Used by interrupt moderation */
#define NGE_POLL_QUIET_TIME 100
#define NGE_POLL_BUSY_TIME 2
#define NGE_TX_N_INTR 128
/*
* NGE-specific ioctls ...
*/
#define NGE_IOC ((((('N' << 8) + 'G') << 8) + 'E') << 8)
/*
* PHY register read/write ioctls, used by cable test software
*/
#define NGE_MII_READ (NGE_IOC|1)
#define NGE_MII_WRITE (NGE_IOC|2)
/*
* SEEPROM read/write ioctls, for use by SEEPROM upgrade utility
*
* Note: SEEPROMs can only be accessed as 32-bit words, so <see_addr>
* must be a multiple of 4. Not all systems have a SEEPROM fitted!
*/
#define NGE_SEE_READ (NGE_IOC|3)
#define NGE_SEE_WRITE (NGE_IOC|4)
/*
* These diagnostic IOCTLS are enabled only in DEBUG drivers
*/
#define NGE_DIAG (NGE_IOC|5) /* currently a no-op */
#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
};
/*
* Required state according to GLD
*/
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,
};
/*
* (Internal) return values from send_msg subroutines
*/
enum send_status {
SEND_COPY_FAIL = -1, /* => GLD_NORESOURCES */
SEND_MAP_FAIL, /* => GLD_NORESOURCES */
SEND_COPY_SUCESS, /* OK, msg queued */
SEND_MAP_SUCCESS /* OK, free msg */
};
/*
* (Internal) return values from ioctl subroutines
*/
enum ioc_reply {
IOC_INVAL = -1, /* bad, NAK with EINVAL */
IOC_DONE, /* OK, reply sent */
IOC_ACK, /* OK, just send ACK */
IOC_REPLY, /* OK, just send reply */
IOC_RESTART_ACK, /* OK, restart & ACK */
IOC_RESTART_REPLY /* OK, 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
};
/*
* Flag to kstat type
*/
enum nge_kstat_type {
NGE_KSTAT_RAW = 0,
NGE_KSTAT_STATS,
NGE_KSTAT_CHIPID,
NGE_KSTAT_DEBUG,
NGE_KSTAT_COUNT
};
/*
* Actual state of the nvidia's chip
*/
enum nge_chip_state {
NGE_CHIP_FAULT = -2, /* fault, need reset */
NGE_CHIP_ERROR, /* error, want reset */
NGE_CHIP_INITIAL, /* Initial state only */
NGE_CHIP_RESET, /* reset, need init */
NGE_CHIP_STOPPED, /* Tx/Rx stopped */
NGE_CHIP_RUNNING /* with interrupts */
};
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
};
/*
* MDIO operation
*/
enum nge_mdio_operation {
NGE_MDIO_READ = 0,
NGE_MDIO_WRITE
};
/*
* Speed selection
*/
enum nge_speed {
UNKOWN_SPEED = 0,
NGE_10M,
NGE_100M,
NGE_1000M
};
/*
* Duplex selection
*/
enum nge_duplex {
UNKOWN_DUPLEX = 0,
NGE_HD,
NGE_FD
};
typedef struct {
ether_addr_t addr; /* in canonical form */
uint8_t spare;
uint8_t set; /* nonzero => valid */
} nge_mac_addr_t;
struct nge;
#define CHIP_FLAG_COPPER 0x40
/*
* Collection of physical-layer functions to:
* (re)initialise the physical layer
* update it to match software settings
* check for link status change
*/
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; /* Byte offset within SEEPROM */
uint32_t see_data; /* Data read/data to write */
};
typedef struct {
uint64_t pp_acc_size; /* in bytes: 1,2,4,8 */
uint64_t pp_acc_space; /* See #defines below */
uint64_t pp_acc_offset;
uint64_t pp_acc_data; /* output for peek */
/* input for poke */
} nge_peekpoke_t;
typedef uintptr_t nge_regno_t; /* register # (offset) */
typedef struct _mul_list {
struct _mul_list *next;
uint32_t ref_cnt;
ether_addr_t mul_addr;
}mul_item, *pmul_item;
/*
* Describes one chunk of allocated DMA-able memory
*
* In some cases, this is a single chunk as allocated from the system;
* but we also use this structure to represent slices carved off such
* a chunk. Even when we don't really need all the information, we
* use this structure as a convenient way of correlating the various
* ways of looking at a piece of memory (kernel VA, IO space DVMA,
* handle+offset, etc).
*/
typedef struct dma_area
{
caddr_t private; /* pointer to nge */
frtn_t rx_recycle; /* recycle function */
mblk_t *mp;
ddi_acc_handle_t acc_hdl; /* handle for memory */
void *mem_va; /* CPU VA of memory */
uint32_t nslots; /* number of slots */
uint32_t size; /* size per slot */
size_t alength; /* allocated size */
/* >= product of above */
ddi_dma_handle_t dma_hdl; /* DMA handle */
offset_t offset; /* relative to handle */
ddi_dma_cookie_t cookie; /* associated cookie */
uint32_t ncookies;
uint32_t signature; /* buffer signature */
/* for deciding to free */
/* or to reuse buffers */
boolean_t rx_delivered; /* hold by upper layer */
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;
/*
* Software version of the Recv Descriptor
* There's one of these for each recv buffer (up to 512 per ring)
*/
typedef struct sw_rx_sbd {
dma_area_t desc; /* (const) related h/w */
/* descriptor area */
dma_area_t *bufp; /* (const) related */
/* buffer area */
uint8_t flags;
} sw_rx_sbd_t;
/*
* Software version of the send Buffer Descriptor
* There's one of these for each send buffer (up to 512 per ring)
*/
typedef struct sw_tx_sbd {
dma_area_t desc; /* (const) related h/w */
/* descriptor area */
dma_area_t pbuf; /* (const) related */
/* buffer area */
void (*tx_recycle)(struct sw_tx_sbd *);
uint32_t flags;
mblk_t *mp; /* related mblk, if any */
nge_dmah_list_t mp_hndl;
uint32_t frags;
uint32_t ncookies; /* dma cookie number */
} sw_tx_sbd_t;
/*
* Software Receive Buffer (Producer) Ring Control Block
* There's one of these for each receiver producer ring (up to 3),
* but each holds buffers of a different size.
*/
typedef struct buff_ring {
uint64_t nslots; /* descriptor area */
struct nge *ngep; /* (const) containing */
/* driver soft state */
/* initialise same */
uint64_t rx_hold;
sw_rx_sbd_t *sw_rbds; /* software descriptors */
sw_rx_sbd_t *free_rbds; /* free ring */
dma_area_t *free_list; /* available buffer queue */
dma_area_t *recycle_list; /* recycling buffer queue */
kmutex_t recycle_lock[1];
uint32_t buf_sign; /* buffer ring signature */
/* for deciding to free */
/* or to reuse buffers */
boolean_t rx_bcopy;
} buff_ring_t;
/*
* Software Receive (Return) Ring Control Block
* There's one of these for each receiver return ring (up to 16).
*/
typedef struct recv_ring {
/*
* The elements flagged (const) in the comments below are
* set up once during initialiation and thereafter unchanged.
*/
dma_area_t desc; /* (const) related h/w */
/* descriptor area */
struct nge *ngep; /* (const) containing */
/* driver soft state */
uint16_t prod_index; /* (const) ptr to h/w */
/* "producer index" */
mac_resource_handle_t handle;
} recv_ring_t;
/*
* Software Send Ring Control Block
* There's one of these for each of (up to) 1 send rings
*/
typedef struct send_ring {
/*
* The elements flagged (const) in the comments below are
* set up once during initialiation and thereafter unchanged.
*/
dma_area_t desc; /* (const) related h/w */
/* descriptor area */
dma_area_t buf[NGE_SEND_SLOTS_BUF];
/* buffer area(s) */
struct nge *ngep; /* (const) containing */
/* driver soft state */
uint32_t tx_hwmark;
uint32_t tx_lwmark;
/*
* The tx_lock must be held when updating
* the s/w producer index
* (tx_next)
*/
kmutex_t tx_lock[1]; /* serialize h/w update */
uint32_t tx_next; /* next slot to use */
uint32_t tx_flow;
/*
* These counters/indexes are manipulated in the transmit
* path using atomics rather than mutexes for speed
*/
uint32_t tx_free; /* # of slots available */
/*
* index (tc_next).
*/
kmutex_t tc_lock[1];
uint32_t tc_next; /* next slot to recycle */
/* ("consumer index") */
sw_tx_sbd_t *sw_sbds; /* software descriptors */
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; /* from private reg */
uint16_t command; /* saved during attach */
uint16_t vendor; /* vendor-id */
uint16_t device; /* device-id */
uint16_t subven; /* subsystem-vendor-id */
uint16_t subdev; /* subsystem-id */
uint8_t class_code;
uint8_t revision; /* revision-id */
uint8_t clsize; /* cache-line-size */
uint8_t latency; /* latency-timer */
uint8_t flags;
uint16_t phy_type; /* Fiber module type */
uint64_t hw_mac_addr; /* from chip register */
nge_mac_addr_t vendor_addr; /* transform of same */
} 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;
/*
* statistics parameters to tune the driver
*/
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);
uint32_t (*txd_check)(const void *, size_t *);
};
typedef struct nge_desc_attr nge_desc_attr_t;
/*
* Structure used to hold the device-specific config parameters.
* The setting of such parameters may not consistent with the
* hardware feature of the device. It's used for software purpose.
*/
typedef struct nge_dev_spec_param {
boolean_t msi; /* specifies msi support */
boolean_t msi_x; /* specifies msi_x support */
boolean_t vlan; /* specifies vlan support */
boolean_t advanced_pm; /* advanced power management support */
boolean_t mac_addr_order; /* mac address order */
boolean_t tx_pause_frame; /* specifies tx pause frame support */
boolean_t rx_pause_frame; /* specifies rx pause frame support */
boolean_t jumbo; /* jumbo frame support */
boolean_t tx_rx_64byte; /* set the max tx/rx prd fetch size */
boolean_t rx_hw_checksum; /* specifies tx hw checksum feature */
uint32_t tx_hw_checksum; /* specifies rx hw checksum feature */
uint32_t desc_type; /* specifies descriptor type */
uint32_t rx_desc_num; /* specifies rx descriptor number */
uint32_t tx_desc_num; /* specifies tx descriptor number */
uint32_t nge_split; /* specifies the split number */
} nge_dev_spec_param_t;
typedef struct nge {
/*
* These fields are set by attach() and unchanged thereafter ...
*/
dev_info_t *devinfo; /* device instance */
mac_handle_t mh; /* mac module handle */
chip_info_t chipinfo;
ddi_acc_handle_t cfg_handle; /* DDI I/O handle */
ddi_acc_handle_t io_handle; /* DDI I/O handle */
void *io_regs; /* mapped registers */
ddi_periodic_t periodic_id; /* periodical callback */
uint32_t factotum_flag;
ddi_softint_handle_t factotum_hdl; /* factotum callback */
ddi_softint_handle_t resched_hdl; /* reschedule callback */
uint_t soft_pri;
ddi_intr_handle_t *htable; /* for array of interrupts */
int intr_type; /* type of interrupt */
int intr_actual_cnt; /* alloc intrs count */
int intr_req_cnt; /* request intrs count */
uint_t intr_pri; /* interrupt priority */
int intr_cap; /* interrupt capabilities */
uint32_t progress; /* attach tracking */
uint32_t debug; /* flag to debug function */
char ifname[8]; /* "nge0" ... "nge999" */
enum nge_mac_state nge_mac_state; /* definitions above */
enum nge_chip_state nge_chip_state; /* definitions above */
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;
/*
* Runtime read-write data starts here ...
* 1 Receive Rings
* 1 Send Rings
*
* Note: they're not necessarily all used.
*/
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 mac_addr_reversion;
uint32_t recv_count;
uint32_t quiet_time;
uint32_t busy_time;
uint32_t stint_count;
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;
/*
* Link state data (protected by genlock)
*/
int32_t link_state; /* See GLD #defines */
uint32_t stall_cknum; /* Stall check number */
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;
int param_tx_n_intr;
} nge_t;
extern const nge_ksindex_t nge_statistics[];
/*
* Sync a DMA area described by a dma_area_t
*/
#define DMA_SYNC(area, flag) ((void) ddi_dma_sync((area).dma_hdl, \
(area).offset, (area).alength, (flag)))
/*
* Find the (kernel virtual) address of block of memory
* described by a dma_area_t
*/
#define DMA_VPTR(area) ((area).mem_va)
/*
* Zero a block of memory described by a dma_area_t
*/
#define DMA_ZERO(area) bzero(DMA_VPTR(area), (area).alength)
/*
* Next/Prev value of a cyclic index
*/
#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)))
/*
* Property lookups
*/
#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)
/*
* Debugging ...
*/
#ifdef DEBUG
#define NGE_DEBUGGING 1
#else
#define NGE_DEBUGGING 0
#endif /* DEBUG */
/*
* Bit flags in the 'debug' word ...
*/
#define NGE_DBG_STOP 0x00000001 /* early debug_enter() */
#define NGE_DBG_TRACE 0x00000002 /* general flow tracing */
#define NGE_DBG_MII 0x00000010 /* low-level MII access */
#define NGE_DBG_CHIP 0x00000020 /* low(ish)-level code */
#define NGE_DBG_RECV 0x00000100 /* receive-side code */
#define NGE_DBG_SEND 0x00000200 /* packet-send code */
#define NGE_DBG_INIT 0x00100000 /* initialisation */
#define NGE_DBG_NEMO 0x00200000 /* MAC layer entry points */
#define NGE_DBG_STATS 0x00400000 /* statistics */
#define NGE_DBG_BADIOC 0x01000000 /* unknown ioctls */
#define NGE_DBG_NDD 0x10000000 /* NDD operations */
/*
* 'Do-if-debugging' macro. The parameter <command> should be one or more
* C statements (but without the *final* semicolon), which will either be
* compiled inline or completely ignored, depending on the NGE_DEBUGGING
* compile-time flag.
*
* You should get a compile-time error (at least on a DEBUG build) if
* your statement isn't actually a statement, rather than unexpected
* run-time behaviour caused by unintended matching of if-then-elses etc.
*
* Note that the NGE_DDB() macro itself can only be used as a statement,
* not an expression, and should always be followed by a semicolon.
*/
#if NGE_DEBUGGING
#define NGE_DDB(command) do { \
{ command; } \
_NOTE(CONSTANTCONDITION) \
} while (0)
#else /* NGE_DEBUGGING */
#define NGE_DDB(command)
/*
* Old way of debugging. This is a poor way, as it leeaves empty
* statements that cause lint to croak.
* #define NGE_DDB(command) do { \
* { _NOTE(EMPTY); } \
* _NOTE(CONSTANTCONDITION) \
* } while (0)
*/
#endif /* NGE_DEBUGGING */
/*
* 'Internal' macros used to construct the TRACE/DEBUG macros below.
* These provide the primitive conditional-call capability required.
* Note: the parameter <args> is a parenthesised list of the actual
* printf-style arguments to be passed to the debug function ...
*/
#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)
/*
* Conditional-print macros.
*
* Define NGE_DBG to be the relevant member of the set of NGE_DBG_* values
* above before using the NGE_GDEBUG() or NGE_DEBUG() macros. The 'G'
* versions look at the Global debug flag word (nge_debug); the non-G
* versions look in the per-instance data (ngep->debug) and so require a
* variable called 'ngep' to be in scope (and initialised!) before use.
*
* You could redefine NGE_TRC too if you really need two different
* flavours of debugging output in the same area of code, but I don't
* really recommend it.
*
* Note: the parameter <args> is a parenthesised list of the actual
* arguments to be passed to the debug function, usually a printf-style
* format string and corresponding values to be formatted.
*/
#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)
/*
* Debug-only action macros
*/
#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;
/*
* DESC MODE 2
*/
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);
extern uint32_t nge_sum_txd_check(const void *, size_t *);
/*
* DESC MODE 3
*/
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);
extern uint32_t nge_hot_txd_check(const void *, size_t *);
#ifdef __cplusplus
}
#endif
#endif /* _SYS_NGE_H */