xref: /illumos-gate/usr/src/uts/common/io/nge/nge.h (revision 51fc88a8)
16f3e57acSmx /*
247693af9Smx  * CDDL HEADER START
347693af9Smx  *
447693af9Smx  * The contents of this file are subject to the terms of the
547693af9Smx  * Common Development and Distribution License (the "License").
647693af9Smx  * You may not use this file except in compliance with the License.
747693af9Smx  *
847693af9Smx  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
947693af9Smx  * or http://www.opensolaris.org/os/licensing.
1047693af9Smx  * See the License for the specific language governing permissions
1147693af9Smx  * and limitations under the License.
1247693af9Smx  *
1347693af9Smx  * When distributing Covered Code, include this CDDL HEADER in each
1447693af9Smx  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1547693af9Smx  * If applicable, add the following below this CDDL HEADER, with the
1647693af9Smx  * fields enclosed by brackets "[]" replaced with your own identifying
1747693af9Smx  * information: Portions Copyright [yyyy] [name of copyright owner]
1847693af9Smx  *
1947693af9Smx  * CDDL HEADER END
206f3e57acSmx  */
216f3e57acSmx 
226f3e57acSmx /*
23a01a4735SWinson Wang - Sun Microsystems - Beijing China  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2447693af9Smx  * Use is subject to license terms.
256f3e57acSmx  */
266f3e57acSmx 
276f3e57acSmx #ifndef	_SYS_NGE_H
286f3e57acSmx #define	_SYS_NGE_H
296f3e57acSmx 
306f3e57acSmx #ifdef __cplusplus
316f3e57acSmx extern "C" {
326f3e57acSmx #endif
336f3e57acSmx 
346f3e57acSmx 
356f3e57acSmx #include <sys/types.h>
366f3e57acSmx #include <sys/stream.h>
376f3e57acSmx #include <sys/strsun.h>
386f3e57acSmx #include <sys/strsubr.h>
396f3e57acSmx #include <sys/stat.h>
406f3e57acSmx #include <sys/pci.h>
416f3e57acSmx #include <sys/note.h>
426f3e57acSmx #include <sys/modctl.h>
436f3e57acSmx #include <sys/kstat.h>
446f3e57acSmx #include <sys/ethernet.h>
456f3e57acSmx #include <sys/pattr.h>
466f3e57acSmx #include <sys/errno.h>
476f3e57acSmx #include <sys/dlpi.h>
486f3e57acSmx #include <sys/devops.h>
496f3e57acSmx #include <sys/debug.h>
506f3e57acSmx #include <sys/conf.h>
516f3e57acSmx #include <sys/callb.h>
526f3e57acSmx 
536f3e57acSmx #include <netinet/ip6.h>
546f3e57acSmx 
556f3e57acSmx #include <inet/common.h>
566f3e57acSmx #include <inet/ip.h>
576f3e57acSmx #include <netinet/udp.h>
586f3e57acSmx #include <inet/mi.h>
596f3e57acSmx #include <inet/nd.h>
606f3e57acSmx 
616f3e57acSmx #include <sys/ddi.h>
626f3e57acSmx #include <sys/sunddi.h>
636f3e57acSmx 
64da14cebeSEric Cheng #include <sys/mac_provider.h>
656f3e57acSmx #include <sys/mac_ether.h>
666f3e57acSmx 
676f3e57acSmx /*
686f3e57acSmx  * Reconfiguring the network devices requires the net_config privilege
696f3e57acSmx  * in Solaris 10+.
706f3e57acSmx  */
716f3e57acSmx extern int secpolicy_net_config(const cred_t *, boolean_t);
726f3e57acSmx 
736f3e57acSmx #include <sys/netlb.h>
746f3e57acSmx #include <sys/miiregs.h>
756f3e57acSmx 
766f3e57acSmx #include "nge_chip.h"
776f3e57acSmx 
786f3e57acSmx #define	PIO_ADDR(ngep, offset)	((void *)((caddr_t)(ngep)->io_regs+(offset)))
796f3e57acSmx /*
806f3e57acSmx  * Copy an ethernet address
816f3e57acSmx  */
826f3e57acSmx #define	ethaddr_copy(src, dst)	bcopy((src), (dst), ETHERADDRL)
836f3e57acSmx #define	ether_eq(a, b) (bcmp((caddr_t)(a), (caddr_t)(b), (ETHERADDRL)) == 0)
846f3e57acSmx 
856f3e57acSmx #define	BIS(w, b)	(((w) & (b)) ? B_TRUE : B_FALSE)
866f3e57acSmx #define	BIC(w, b)	(((w) & (b)) ? B_FALSE : B_TRUE)
876f3e57acSmx #define	UPORDOWN(x)	((x) ? "up" : "down")
886f3e57acSmx 
896f3e57acSmx #define	NGE_DRIVER_NAME		"nge"
906f3e57acSmx 
916f3e57acSmx /*
926f3e57acSmx  * 'Progress' bit flags ...
936f3e57acSmx  */
946f3e57acSmx #define	PROGRESS_CFG		0x0001	/* config space mapped		*/
956f3e57acSmx #define	PROGRESS_REGS		0x0002	/* registers mapped		*/
966f3e57acSmx #define	PROGRESS_BUFS		0x0004	/* registers mapped		*/
976f3e57acSmx #define	PROGRESS_RESCHED	0x0008	/* resched softint registered	*/
986f3e57acSmx #define	PROGRESS_FACTOTUM	0x0010	/* factotum softint registered	*/
996f3e57acSmx #define	PROGRESS_SWINT		0x0020	/* s/w interrupt registered	*/
1006f3e57acSmx #define	PROGRESS_INTR		0x0040	/* h/w interrupt registered	*/
1016f3e57acSmx 					/* and mutexen initialised	*/
1026f3e57acSmx #define	PROGRESS_HWINT		0x0080
1036f3e57acSmx #define	PROGRESS_PHY		0x0100	/* PHY initialised		*/
1046f3e57acSmx #define	PROGRESS_NDD		0x0200	/* NDD parameters set up	*/
1056f3e57acSmx #define	PROGRESS_KSTATS		0x0400	/* kstats created		*/
1066f3e57acSmx #define	PROGRESS_READY		0x0800	/* ready for work		*/
1076f3e57acSmx 
1086f3e57acSmx #define	NGE_HW_ERR		0x00
1096f3e57acSmx #define	NGE_HW_LINK		0x01
1106f3e57acSmx #define	NGE_HW_BM		0x02
1116f3e57acSmx #define	NGE_HW_RCHAN		0x03
1126f3e57acSmx #define	NGE_HW_TCHAN		0x04
1136f3e57acSmx #define	NGE_HW_ROM		0x05
1146f3e57acSmx #define	NGE_SW_PROBLEM_ID	0x06
1156f3e57acSmx 
1166f3e57acSmx 
1176f3e57acSmx /*
1186f3e57acSmx  * NOTES:
1196f3e57acSmx  *
1206f3e57acSmx  * #defines:
1216f3e57acSmx  *
1226f3e57acSmx  *	NGE_PCI_CONFIG_RNUMBER and NGE_PCI_OPREGS_RNUMBER are the
1236f3e57acSmx  *	register-set numbers to use for the config space registers
1246f3e57acSmx  *	and the operating registers respectively.  On an OBP-based
1256f3e57acSmx  *	machine, regset 0 refers to CONFIG space, and regset 1 will
1266f3e57acSmx  *	be the operating registers in MEMORY space.  If an expansion
1276f3e57acSmx  *	ROM is fitted, it may appear as a further register set.
1286f3e57acSmx  *
1296f3e57acSmx  *	NGE_DMA_MODE defines the mode (STREAMING/CONSISTENT) used
1306f3e57acSmx  *	for the data buffers.  The descriptors are always set up
1316f3e57acSmx  *	in CONSISTENT mode.
1326f3e57acSmx  *
1336f3e57acSmx  *	NGE_HEADROOM defines how much space we'll leave in allocated
1346f3e57acSmx  *	mblks before the first valid data byte.  This should be chosen
1356f3e57acSmx  *	to be 2 modulo 4, so that once the ethernet header (14 bytes)
1366f3e57acSmx  *	has been stripped off, the packet data will be 4-byte aligned.
1376f3e57acSmx  *	The remaining space can be used by upstream modules to prepend
1386f3e57acSmx  *	any headers required.
1396f3e57acSmx  */
1406f3e57acSmx 
1416f3e57acSmx 
1426f3e57acSmx #define	NGE_PCI_OPREGS_RNUMBER	1
1436f3e57acSmx #define	NGE_DMA_MODE		DDI_DMA_STREAMING
1446f3e57acSmx #define	NGE_HEADROOM		6
1456f3e57acSmx #define	ETHER_HEAD_LEN		14
1466f3e57acSmx #ifndef	VTAG_SIZE
1476f3e57acSmx #define	VTAG_SIZE		4
1486f3e57acSmx #endif
1496f3e57acSmx 
150*51fc88a8SWinson Wang - Sun Microsystems - Beijing China #define	NGE_CYCLIC_PERIOD	(1000000000)
1516f3e57acSmx 
1526f3e57acSmx #define	NGE_DEFAULT_MTU		1500
1536f3e57acSmx #define	NGE_DEFAULT_SDU		1518
1546f3e57acSmx #define	NGE_MTU_2500		2500
1556f3e57acSmx #define	NGE_MTU_4500		4500
1566f3e57acSmx #define	NGE_MAX_MTU		9000
1576f3e57acSmx #define	NGE_MAX_SDU		9018
1586f3e57acSmx 
15902d51d0dSjj #define	NGE_DESC_MIN		0x200
1606f3e57acSmx 
1616f3e57acSmx #define	NGE_STD_BUFSZ		1792
1626f3e57acSmx #define	NGE_JB2500_BUFSZ	(3*1024)
1636f3e57acSmx #define	NGE_JB4500_BUFSZ	(5*1024)
1646f3e57acSmx #define	NGE_JB9000_BUFSZ	(9*1024)
1656f3e57acSmx 
1666f3e57acSmx #define	NGE_SEND_SLOTS_DESC_1024	1024
1676f3e57acSmx #define	NGE_SEND_SLOTS_DESC_3072	3072
1686f3e57acSmx #define	NGE_SEND_JB2500_SLOTS_DESC	3072
1696f3e57acSmx #define	NGE_SEND_JB4500_SLOTS_DESC	2048
1706f3e57acSmx #define	NGE_SEND_JB9000_SLOTS_DESC	1024
1716f3e57acSmx #define	NGE_SEND_LOWMEM_SLOTS_DESC	1024
1726f3e57acSmx #define	NGE_SEND_SLOTS_BUF		3072
1736f3e57acSmx 
1746f3e57acSmx #define	NGE_RECV_SLOTS_DESC_1024	1024
1756f3e57acSmx #define	NGE_RECV_SLOTS_DESC_3072	3072
1766f3e57acSmx #define	NGE_RECV_JB2500_SLOTS_DESC	3072
1776f3e57acSmx #define	NGE_RECV_JB4500_SLOTS_DESC	2048
1786f3e57acSmx #define	NGE_RECV_JB9000_SLOTS_DESC	1024
1796f3e57acSmx #define	NGE_RECV_LOWMEM_SLOTS_DESC	1024
1806f3e57acSmx #define	NGE_RECV_SLOTS_BUF		6144
1816f3e57acSmx 
1826f3e57acSmx #define	NGE_SPLIT_32		32
1836f3e57acSmx #define	NGE_SPLIT_96		96
1846f3e57acSmx #define	NGE_SPLIT_256		256
1856f3e57acSmx 
1866f3e57acSmx #define	NGE_RX_COPY_SIZE	512
1876f3e57acSmx #define	NGE_TX_COPY_SIZE	512
1886f3e57acSmx #define	NGE_MAP_FRAGS		3
1896f3e57acSmx #define	NGE_MAX_COOKIES		3
1906f3e57acSmx #define	NGE_MAX_DMA_HDR		(4*1024)
1916f3e57acSmx 
19202d51d0dSjj /* Used by interrupt moderation */
193*51fc88a8SWinson Wang - Sun Microsystems - Beijing China #define	NGE_TFINT_DEFAULT	32
194*51fc88a8SWinson Wang - Sun Microsystems - Beijing China #define	NGE_POLL_TUNE		80000
195*51fc88a8SWinson Wang - Sun Microsystems - Beijing China #define	NGE_POLL_ENTER		10000
196*51fc88a8SWinson Wang - Sun Microsystems - Beijing China #define	NGE_POLL_MAX		1280000
19702d51d0dSjj #define	NGE_POLL_QUIET_TIME	100
19802d51d0dSjj #define	NGE_POLL_BUSY_TIME	2
1996f3e57acSmx 
2006f3e57acSmx /*
2016f3e57acSmx  * NGE-specific ioctls ...
2026f3e57acSmx  */
2036f3e57acSmx #define	NGE_IOC			((((('N' << 8) + 'G') << 8) + 'E') << 8)
2046f3e57acSmx 
2056f3e57acSmx /*
2066f3e57acSmx  * PHY register read/write ioctls, used by cable test software
2076f3e57acSmx  */
2086f3e57acSmx #define	NGE_MII_READ		(NGE_IOC|1)
2096f3e57acSmx #define	NGE_MII_WRITE		(NGE_IOC|2)
2106f3e57acSmx 
2116f3e57acSmx /*
2126f3e57acSmx  * SEEPROM read/write ioctls, for use by SEEPROM upgrade utility
2136f3e57acSmx  *
2146f3e57acSmx  * Note: SEEPROMs can only be accessed as 32-bit words, so <see_addr>
2156f3e57acSmx  * must be a multiple of 4.  Not all systems have a SEEPROM fitted!
2166f3e57acSmx  */
2176f3e57acSmx #define	NGE_SEE_READ		(NGE_IOC|3)
2186f3e57acSmx #define	NGE_SEE_WRITE		(NGE_IOC|4)
2196f3e57acSmx 
2206f3e57acSmx 
2216f3e57acSmx /*
2226f3e57acSmx  * These diagnostic IOCTLS are enabled only in DEBUG drivers
2236f3e57acSmx  */
2246f3e57acSmx #define	NGE_DIAG		(NGE_IOC|5)	/* currently a no-op	*/
2256f3e57acSmx #define	NGE_PEEK		(NGE_IOC|6)
2266f3e57acSmx #define	NGE_POKE		(NGE_IOC|7)
2276f3e57acSmx #define	NGE_PHY_RESET		(NGE_IOC|8)
2286f3e57acSmx #define	NGE_SOFT_RESET		(NGE_IOC|9)
2296f3e57acSmx #define	NGE_HARD_RESET		(NGE_IOC|10)
2306f3e57acSmx 
2316f3e57acSmx 
2326f3e57acSmx enum NGE_HW_OP {
2336f3e57acSmx 	NGE_CLEAR = 0,
2346f3e57acSmx 	NGE_SET
2356f3e57acSmx };
2366f3e57acSmx 
2376f3e57acSmx /*
2386f3e57acSmx  * Required state according to GLD
2396f3e57acSmx  */
2406f3e57acSmx enum nge_mac_state {
2416f3e57acSmx 	NGE_MAC_UNKNOWN,
2426f3e57acSmx 	NGE_MAC_RESET,
2436f3e57acSmx 	NGE_MAC_STOPPED,
2446f3e57acSmx 	NGE_MAC_STARTED,
2456f3e57acSmx 	NGE_MAC_UNATTACH
2466f3e57acSmx };
2476f3e57acSmx enum loop_type {
2486f3e57acSmx 	NGE_LOOP_NONE = 0,
2496f3e57acSmx 	NGE_LOOP_EXTERNAL_100,
2506f3e57acSmx 	NGE_LOOP_EXTERNAL_10,
2516f3e57acSmx 	NGE_LOOP_INTERNAL_PHY,
2526f3e57acSmx };
2536f3e57acSmx 
2546f3e57acSmx /*
2556f3e57acSmx  * (Internal) return values from send_msg subroutines
2566f3e57acSmx  */
2576f3e57acSmx enum send_status {
2586f3e57acSmx 	SEND_COPY_FAIL = -1,		/* => GLD_NORESOURCES	*/
2596f3e57acSmx 	SEND_MAP_FAIL,			/* => GLD_NORESOURCES	*/
2606f3e57acSmx 	SEND_COPY_SUCESS,		/* OK, msg queued	*/
2616f3e57acSmx 	SEND_MAP_SUCCESS		/* OK, free msg		*/
2626f3e57acSmx };
2636f3e57acSmx 
2646f3e57acSmx /*
2656f3e57acSmx  * (Internal) return values from ioctl subroutines
2666f3e57acSmx  */
2676f3e57acSmx enum ioc_reply {
2686f3e57acSmx 	IOC_INVAL = -1,			/* bad, NAK with EINVAL	*/
2696f3e57acSmx 	IOC_DONE,			/* OK, reply sent	*/
2706f3e57acSmx 	IOC_ACK,			/* OK, just send ACK	*/
2716f3e57acSmx 	IOC_REPLY,			/* OK, just send reply	*/
2726f3e57acSmx 	IOC_RESTART_ACK,		/* OK, restart & ACK	*/
2736f3e57acSmx 	IOC_RESTART_REPLY		/* OK, restart & reply	*/
2746f3e57acSmx };
2756f3e57acSmx 
2766f3e57acSmx enum nge_pp_type {
2776f3e57acSmx 	NGE_PP_SPACE_CFG = 0,
2786f3e57acSmx 	NGE_PP_SPACE_REG,
2796f3e57acSmx 	NGE_PP_SPACE_NIC,
2806f3e57acSmx 	NGE_PP_SPACE_MII,
2816f3e57acSmx 	NGE_PP_SPACE_NGE,
2826f3e57acSmx 	NGE_PP_SPACE_TXDESC,
2836f3e57acSmx 	NGE_PP_SPACE_TXBUFF,
2846f3e57acSmx 	NGE_PP_SPACE_RXDESC,
2856f3e57acSmx 	NGE_PP_SPACE_RXBUFF,
2866f3e57acSmx 	NGE_PP_SPACE_STATISTICS,
2876f3e57acSmx 	NGE_PP_SPACE_SEEPROM,
2886f3e57acSmx 	NGE_PP_SPACE_FLASH
2896f3e57acSmx };
2906f3e57acSmx 
2916f3e57acSmx /*
2926f3e57acSmx  * Flag to kstat type
2936f3e57acSmx  */
2946f3e57acSmx enum nge_kstat_type {
2956f3e57acSmx 	NGE_KSTAT_RAW = 0,
2966f3e57acSmx 	NGE_KSTAT_STATS,
2976f3e57acSmx 	NGE_KSTAT_CHIPID,
2986f3e57acSmx 	NGE_KSTAT_DEBUG,
2996f3e57acSmx 	NGE_KSTAT_COUNT
3006f3e57acSmx };
3016f3e57acSmx 
3026f3e57acSmx 
3036f3e57acSmx /*
3046f3e57acSmx  * Actual state of the nvidia's chip
3056f3e57acSmx  */
3066f3e57acSmx enum nge_chip_state {
3076f3e57acSmx 	NGE_CHIP_FAULT = -2,		/* fault, need reset	*/
3086f3e57acSmx 	NGE_CHIP_ERROR,			/* error, want reset	*/
3096f3e57acSmx 	NGE_CHIP_INITIAL,		/* Initial state only	*/
3106f3e57acSmx 	NGE_CHIP_RESET,			/* reset, need init	*/
3116f3e57acSmx 	NGE_CHIP_STOPPED,		/* Tx/Rx stopped	*/
3126f3e57acSmx 	NGE_CHIP_RUNNING		/* with interrupts	*/
3136f3e57acSmx };
3146f3e57acSmx 
3156f3e57acSmx enum nge_eeprom_size {
3166f3e57acSmx 	EEPROM_1K = 0,
3176f3e57acSmx 	EEPROM_2K,
3186f3e57acSmx 	EEPROM_4K,
3196f3e57acSmx 	EEPROM_8K,
3206f3e57acSmx 	EEPROM_16K,
3216f3e57acSmx 	EEPROM_32K,
3226f3e57acSmx 	EEPROM_64K
3236f3e57acSmx };
3246f3e57acSmx 
3256f3e57acSmx enum nge_eeprom_access_wid {
3266f3e57acSmx 	ACCESS_8BIT = 0,
3276f3e57acSmx 	ACCESS_16BIT
3286f3e57acSmx };
3296f3e57acSmx 
3306f3e57acSmx /*
3316f3e57acSmx  * MDIO operation
3326f3e57acSmx  */
3336f3e57acSmx enum nge_mdio_operation {
3346f3e57acSmx 	NGE_MDIO_READ = 0,
3356f3e57acSmx 	NGE_MDIO_WRITE
3366f3e57acSmx };
3376f3e57acSmx 
3386f3e57acSmx /*
3396f3e57acSmx  * Speed selection
3406f3e57acSmx  */
3416f3e57acSmx enum nge_speed {
3426f3e57acSmx 	UNKOWN_SPEED = 0,
3436f3e57acSmx 	NGE_10M,
3446f3e57acSmx 	NGE_100M,
3456f3e57acSmx 	NGE_1000M
3466f3e57acSmx };
3476f3e57acSmx 
3486f3e57acSmx /*
3496f3e57acSmx  * Duplex selection
3506f3e57acSmx  */
3516f3e57acSmx enum nge_duplex {
3526f3e57acSmx 	UNKOWN_DUPLEX = 0,
3536f3e57acSmx 	NGE_HD,
3546f3e57acSmx 	NGE_FD
3556f3e57acSmx };
3566f3e57acSmx 
3576f3e57acSmx typedef struct {
3586f3e57acSmx 	ether_addr_t		addr;		/* in canonical form	*/
3596f3e57acSmx 	uint8_t			spare;
3606f3e57acSmx 	uint8_t			set;		/* nonzero => valid	*/
3616f3e57acSmx } nge_mac_addr_t;
3626f3e57acSmx 
3636f3e57acSmx struct nge;
3646f3e57acSmx 
3656f3e57acSmx 
3666f3e57acSmx #define	CHIP_FLAG_COPPER	0x40
3676f3e57acSmx 
3686f3e57acSmx /*
3696f3e57acSmx  * Collection of physical-layer functions to:
3706f3e57acSmx  *	(re)initialise the physical layer
3716f3e57acSmx  *	update it to match software settings
3726f3e57acSmx  *	check for link status change
3736f3e57acSmx  */
3746f3e57acSmx typedef struct {
375c322ff79Smx 	boolean_t	(*phys_restart)(struct nge *);
3766f3e57acSmx 	void		(*phys_update)(struct nge *);
3776f3e57acSmx 	boolean_t	(*phys_check)(struct nge *);
3786f3e57acSmx } phys_ops_t;
3796f3e57acSmx 
3806f3e57acSmx struct nge_see_rw {
3816f3e57acSmx 	uint32_t	see_addr;	/* Byte offset within SEEPROM	*/
3826f3e57acSmx 	uint32_t	see_data;	/* Data read/data to write	*/
3836f3e57acSmx };
3846f3e57acSmx 
3856f3e57acSmx typedef struct {
3866f3e57acSmx 	uint64_t	pp_acc_size;	/* in bytes: 1,2,4,8	*/
3876f3e57acSmx 	uint64_t	pp_acc_space;	/* See #defines below	*/
3886f3e57acSmx 	uint64_t	pp_acc_offset;
3896f3e57acSmx 	uint64_t	pp_acc_data;	/* output for peek	*/
3906f3e57acSmx 					/* input for poke	*/
3916f3e57acSmx } nge_peekpoke_t;
3926f3e57acSmx 
3936f3e57acSmx typedef uintptr_t 	nge_regno_t;	/* register # (offset)	*/
3946f3e57acSmx 
3956f3e57acSmx typedef struct _mul_list {
3966f3e57acSmx 	struct _mul_list *next;
3976f3e57acSmx 	uint32_t ref_cnt;
3986f3e57acSmx 	ether_addr_t mul_addr;
3996f3e57acSmx }mul_item, *pmul_item;
4006f3e57acSmx 
4016f3e57acSmx /*
4026f3e57acSmx  * Describes one chunk of allocated DMA-able memory
4036f3e57acSmx  *
4046f3e57acSmx  * In some cases, this is a single chunk as allocated from the system;
4056f3e57acSmx  * but we also use this structure to represent slices carved off such
4066f3e57acSmx  * a chunk.  Even when we don't really need all the information, we
4076f3e57acSmx  * use this structure as a convenient way of correlating the various
4086f3e57acSmx  * ways of looking at a piece of memory (kernel VA, IO space DVMA,
4096f3e57acSmx  * handle+offset, etc).
4106f3e57acSmx  */
4116f3e57acSmx typedef struct dma_area
4126f3e57acSmx {
4136f3e57acSmx 
4146f3e57acSmx 	caddr_t			private;	/* pointer to nge */
4156f3e57acSmx 	frtn_t			rx_recycle;	/* recycle function */
4166f3e57acSmx 	mblk_t			*mp;
4176f3e57acSmx 	ddi_acc_handle_t	acc_hdl;	/* handle for memory	*/
4186f3e57acSmx 	void			*mem_va;	/* CPU VA of memory	*/
4196f3e57acSmx 	uint32_t		nslots;		/* number of slots	*/
4206f3e57acSmx 	uint32_t		size;		/* size per slot	*/
4216f3e57acSmx 	size_t			alength;	/* allocated size	*/
4226f3e57acSmx 						/* >= product of above	*/
4236f3e57acSmx 	ddi_dma_handle_t	dma_hdl;	/* DMA handle		*/
4246f3e57acSmx 	offset_t		offset;		/* relative to handle	*/
4256f3e57acSmx 	ddi_dma_cookie_t	cookie;		/* associated cookie	*/
4266f3e57acSmx 	uint32_t		ncookies;
4276f3e57acSmx 	uint32_t		signature;	/* buffer signature	*/
4286f3e57acSmx 						/* for deciding to free */
4296f3e57acSmx 						/* or to reuse buffers	*/
4306f3e57acSmx 	boolean_t		rx_delivered;	/* hold by upper layer	*/
4316f3e57acSmx 	struct dma_area		*next;
4326f3e57acSmx } dma_area_t;
4336f3e57acSmx 
4346f3e57acSmx #define	HOST_OWN	0x00000000
4356f3e57acSmx #define	CONTROLER_OWN	0x00000001
4366f3e57acSmx #define	NGE_END_PACKET	0x00000002
4376f3e57acSmx 
4386f3e57acSmx 
4396f3e57acSmx typedef struct nge_dmah_node
4406f3e57acSmx {
4416f3e57acSmx 	struct nge_dmah_node	*next;
4426f3e57acSmx 	ddi_dma_handle_t	hndl;
4436f3e57acSmx } nge_dmah_node_t;
4446f3e57acSmx 
4456f3e57acSmx typedef struct nge_dmah_list
4466f3e57acSmx {
4476f3e57acSmx 	nge_dmah_node_t	*head;
4486f3e57acSmx 	nge_dmah_node_t	*tail;
4496f3e57acSmx } nge_dmah_list_t;
4506f3e57acSmx 
4516f3e57acSmx /*
4526f3e57acSmx  * Software version of the Recv Descriptor
4536f3e57acSmx  * There's one of these for each recv buffer (up to 512 per ring)
4546f3e57acSmx  */
4556f3e57acSmx typedef struct sw_rx_sbd {
4566f3e57acSmx 
4576f3e57acSmx 	dma_area_t		desc;		/* (const) related h/w	*/
4586f3e57acSmx 						/* descriptor area	*/
4596f3e57acSmx 	dma_area_t		*bufp;		/* (const) related	*/
4606f3e57acSmx 						/* buffer area		*/
4616f3e57acSmx 	uint8_t			flags;
4626f3e57acSmx } sw_rx_sbd_t;
4636f3e57acSmx 
4646f3e57acSmx /*
4656f3e57acSmx  * Software version of the send Buffer Descriptor
4666f3e57acSmx  * There's one of these for each send buffer (up to 512 per ring)
4676f3e57acSmx  */
4686f3e57acSmx typedef struct sw_tx_sbd {
4696f3e57acSmx 
4706f3e57acSmx 	dma_area_t		desc;		/* (const) related h/w	*/
4716f3e57acSmx 						/* descriptor area	*/
4726f3e57acSmx 	dma_area_t		pbuf;		/* (const) related	*/
4736f3e57acSmx 						/* buffer area		*/
4746f3e57acSmx 	void			(*tx_recycle)(struct sw_tx_sbd *);
4756f3e57acSmx 	uint32_t		flags;
4766f3e57acSmx 	mblk_t			*mp;		/* related mblk, if any	*/
4776f3e57acSmx 	nge_dmah_list_t		mp_hndl;
4786f3e57acSmx 	uint32_t		frags;
4796f3e57acSmx 	uint32_t		ncookies;	/* dma cookie number */
4806f3e57acSmx 
4816f3e57acSmx } sw_tx_sbd_t;
4826f3e57acSmx 
4836f3e57acSmx /*
4846f3e57acSmx  * Software Receive Buffer (Producer) Ring Control Block
4856f3e57acSmx  * There's one of these for each receiver producer ring (up to 3),
4866f3e57acSmx  * but each holds buffers of a different size.
4876f3e57acSmx  */
4886f3e57acSmx typedef struct buff_ring {
4896f3e57acSmx 
4906f3e57acSmx 	uint64_t		nslots;		/* descriptor area	*/
4916f3e57acSmx 	struct nge		*ngep;		/* (const) containing	*/
4926f3e57acSmx 						/* driver soft state	*/
4936f3e57acSmx 						/* initialise same	*/
4946f3e57acSmx 	uint64_t		rx_hold;
4956f3e57acSmx 	sw_rx_sbd_t		*sw_rbds; 	/* software descriptors	*/
4966f3e57acSmx 	sw_rx_sbd_t		*free_rbds;	/* free ring */
4976f3e57acSmx 	dma_area_t		*free_list;	/* available buffer queue */
4986f3e57acSmx 	dma_area_t		*recycle_list;	/* recycling buffer queue */
4996f3e57acSmx 	kmutex_t		recycle_lock[1];
50075675fb7Svb 	uint32_t		buf_sign;	/* buffer ring signature */
50175675fb7Svb 						/* for deciding to free  */
50275675fb7Svb 						/* or to reuse buffers   */
5036f3e57acSmx 	boolean_t		rx_bcopy;
5046f3e57acSmx } buff_ring_t;
5056f3e57acSmx 
5066f3e57acSmx /*
5076f3e57acSmx  * Software Receive (Return) Ring Control Block
5086f3e57acSmx  * There's one of these for each receiver return ring (up to 16).
5096f3e57acSmx  */
5106f3e57acSmx typedef struct recv_ring {
5116f3e57acSmx 	/*
5126f3e57acSmx 	 * The elements flagged (const) in the comments below are
5136f3e57acSmx 	 * set up once during initialiation and thereafter unchanged.
5146f3e57acSmx 	 */
5156f3e57acSmx 	dma_area_t		desc;		/* (const) related h/w	*/
5166f3e57acSmx 						/* descriptor area	*/
5176f3e57acSmx 	struct nge		*ngep;		/* (const) containing	*/
5186f3e57acSmx 						/* driver soft state	*/
5196f3e57acSmx 	uint16_t		prod_index;	/* (const) ptr to h/w	*/
5206f3e57acSmx 						/* "producer index"	*/
5216f3e57acSmx 	mac_resource_handle_t	handle;
5226f3e57acSmx } recv_ring_t;
5236f3e57acSmx 
5246f3e57acSmx 
5256f3e57acSmx 
5266f3e57acSmx /*
5276f3e57acSmx  * Software Send Ring Control Block
5286f3e57acSmx  * There's one of these for each of (up to) 1 send rings
5296f3e57acSmx  */
5306f3e57acSmx typedef struct send_ring {
5316f3e57acSmx 	/*
5326f3e57acSmx 	 * The elements flagged (const) in the comments below are
5336f3e57acSmx 	 * set up once during initialiation and thereafter unchanged.
5346f3e57acSmx 	 */
5356f3e57acSmx 	dma_area_t		desc;		/* (const) related h/w	*/
5366f3e57acSmx 						/* descriptor area	*/
5376f3e57acSmx 	dma_area_t		buf[NGE_SEND_SLOTS_BUF];
5386f3e57acSmx 						/* buffer area(s)	*/
5396f3e57acSmx 	struct nge		*ngep;		/* (const) containing	*/
5406f3e57acSmx 						/* driver soft state	*/
5416f3e57acSmx 
542a55f7119SMiles Xu, Sun Microsystems 	uint32_t		tx_hwmark;
543a55f7119SMiles Xu, Sun Microsystems 	uint32_t		tx_lwmark;
5446f3e57acSmx 
5456f3e57acSmx 	/*
5466f3e57acSmx 	 * The tx_lock must be held when updating
5476f3e57acSmx 	 * the s/w producer index
5486f3e57acSmx 	 * (tx_next)
5496f3e57acSmx 	 */
5506f3e57acSmx 	kmutex_t		tx_lock[1];	/* serialize h/w update	*/
551a55f7119SMiles Xu, Sun Microsystems 	uint32_t		tx_next;	/* next slot to use	*/
552a55f7119SMiles Xu, Sun Microsystems 	uint32_t		tx_flow;
5536f3e57acSmx 
5546f3e57acSmx 	/*
5556f3e57acSmx 	 * These counters/indexes are manipulated in the transmit
5566f3e57acSmx 	 * path using atomics rather than mutexes for speed
5576f3e57acSmx 	 */
558a55f7119SMiles Xu, Sun Microsystems 	uint32_t		tx_free;	/* # of slots available	*/
5596f3e57acSmx 
5606f3e57acSmx 	/*
5616f3e57acSmx 	 * index (tc_next).
5626f3e57acSmx 	 */
5636f3e57acSmx 	kmutex_t		tc_lock[1];
564a55f7119SMiles Xu, Sun Microsystems 	uint32_t		tc_next;	/* next slot to recycle	*/
5656f3e57acSmx 						/* ("consumer index")	*/
5666f3e57acSmx 
5676f3e57acSmx 	sw_tx_sbd_t		*sw_sbds; 	/* software descriptors	*/
5686f3e57acSmx 
5696f3e57acSmx 	kmutex_t		dmah_lock;
5706f3e57acSmx 	nge_dmah_list_t		dmah_free;
5716f3e57acSmx 	nge_dmah_node_t		dmahndl[NGE_MAX_DMA_HDR];
5726f3e57acSmx 
5736f3e57acSmx } send_ring_t;
5746f3e57acSmx 
5756f3e57acSmx 
5766f3e57acSmx typedef struct {
5776f3e57acSmx 	uint32_t		businfo;	/* from private reg	*/
5786f3e57acSmx 	uint16_t		command;	/* saved during attach	*/
5796f3e57acSmx 
5806f3e57acSmx 	uint16_t		vendor;		/* vendor-id		*/
5816f3e57acSmx 	uint16_t		device;		/* device-id		*/
5826f3e57acSmx 	uint16_t		subven;		/* subsystem-vendor-id	*/
5836f3e57acSmx 	uint16_t		subdev;		/* subsystem-id		*/
5846f3e57acSmx 	uint8_t			class_code;
5856f3e57acSmx 	uint8_t			revision;	/* revision-id		*/
5866f3e57acSmx 	uint8_t			clsize;		/* cache-line-size	*/
5876f3e57acSmx 	uint8_t			latency;	/* latency-timer	*/
5886f3e57acSmx 	uint8_t			flags;
5896f3e57acSmx 
5906f3e57acSmx 	uint16_t		phy_type;	/* Fiber module type 	*/
5916f3e57acSmx 	uint64_t		hw_mac_addr;	/* from chip register	*/
5926f3e57acSmx 	nge_mac_addr_t		vendor_addr;	/* transform of same	*/
5936f3e57acSmx } chip_info_t;
5946f3e57acSmx 
5956f3e57acSmx 
5966f3e57acSmx typedef struct {
5976f3e57acSmx 	offset_t	index;
5986f3e57acSmx 	char		*name;
5996f3e57acSmx } nge_ksindex_t;
6006f3e57acSmx 
6016f3e57acSmx typedef struct {
6026f3e57acSmx 	uint64_t tso_err_mss;
6036f3e57acSmx 	uint64_t tso_dis;
6046f3e57acSmx 	uint64_t tso_err_nosum;
6056f3e57acSmx 	uint64_t tso_err_hov;
6066f3e57acSmx 	uint64_t tso_err_huf;
6076f3e57acSmx 	uint64_t tso_err_l2;
6086f3e57acSmx 	uint64_t tso_err_ip;
6096f3e57acSmx 	uint64_t tso_err_l4;
6106f3e57acSmx 	uint64_t tso_err_tcp;
6116f3e57acSmx 	uint64_t hsum_err_ip;
6126f3e57acSmx 	uint64_t hsum_err_l4;
6136f3e57acSmx }fe_statistics_t;
6146f3e57acSmx 
6156f3e57acSmx /*
6166f3e57acSmx  * statistics parameters to tune the driver
6176f3e57acSmx  */
6186f3e57acSmx typedef struct {
6196f3e57acSmx 	uint64_t		intr_count;
6206f3e57acSmx 	uint64_t		intr_lval;
6216f3e57acSmx 	uint64_t		recv_realloc;
6226f3e57acSmx 	uint64_t		poll_time;
6236f3e57acSmx 	uint64_t		recy_free;
6246f3e57acSmx 	uint64_t		recv_count;
6256f3e57acSmx 	uint64_t		xmit_count;
6266f3e57acSmx 	uint64_t		obytes;
6276f3e57acSmx 	uint64_t		rbytes;
6286f3e57acSmx 	uint64_t		mp_alloc_err;
6296f3e57acSmx 	uint64_t		dma_alloc_err;
6306f3e57acSmx 	uint64_t		kmem_alloc_err;
6316f3e57acSmx 	uint64_t		load_context;
6326f3e57acSmx 	uint64_t		ip_hwsum_err;
6336f3e57acSmx 	uint64_t		tcp_hwsum_err;
6346f3e57acSmx 	uint64_t		rx_nobuffer;
6356f3e57acSmx 	uint64_t		rx_err;
6366f3e57acSmx 	uint64_t		tx_stop_err;
6376f3e57acSmx 	uint64_t		tx_stall;
6386f3e57acSmx 	uint64_t		tx_rsrv_fail;
6396f3e57acSmx 	uint64_t		tx_resched;
6406f3e57acSmx 	fe_statistics_t	fe_err;
6416f3e57acSmx }nge_sw_statistics_t;
6426f3e57acSmx 
6436f3e57acSmx typedef struct {
6446f3e57acSmx 	nge_hw_statistics_t	hw_statistics;
6456f3e57acSmx 	nge_sw_statistics_t	sw_statistics;
6466f3e57acSmx }nge_statistics_t;
6476f3e57acSmx 
6486f3e57acSmx struct nge_desc_attr	{
6496f3e57acSmx 
6506f3e57acSmx 	size_t	rxd_size;
6516f3e57acSmx 	size_t	txd_size;
6526f3e57acSmx 
6536f3e57acSmx 	ddi_dma_attr_t	*dma_attr;
6546f3e57acSmx 	ddi_dma_attr_t	*tx_dma_attr;
6556f3e57acSmx 
6566f3e57acSmx 	void (*rxd_fill)(void *, const ddi_dma_cookie_t *, size_t);
6576f3e57acSmx 	uint32_t (*rxd_check)(const void *, size_t *);
6586f3e57acSmx 
6596f3e57acSmx 	void (*txd_fill)(void *, const ddi_dma_cookie_t *, size_t,
660*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 			uint32_t, boolean_t, boolean_t);
6616f3e57acSmx 
6629fa05d92SWinson Wang - Sun Microsystems - Beijing China 	uint32_t (*txd_check)(const void *);
6636f3e57acSmx };
6646f3e57acSmx 
6656f3e57acSmx typedef struct nge_desc_attr nge_desc_attr_t;
6666f3e57acSmx 
6676f3e57acSmx /*
6686f3e57acSmx  * Structure used to hold the device-specific config parameters.
6696f3e57acSmx  * The setting of such parameters may not consistent with the
6706f3e57acSmx  * hardware feature of the device. It's used for software purpose.
6716f3e57acSmx  */
6726f3e57acSmx typedef struct nge_dev_spec_param {
6736f3e57acSmx 	boolean_t	msi;		/* specifies msi support */
6746f3e57acSmx 	boolean_t	msi_x;		/* specifies msi_x support */
6756f3e57acSmx 	boolean_t	vlan;		/* specifies vlan support */
6769ae6bcf1Sjj 	boolean_t	advanced_pm;	/* advanced power management support */
677d27d4a13SMiles Xu, Sun Microsystems 	boolean_t	mac_addr_order; /* mac address order */
6786f3e57acSmx 	boolean_t	tx_pause_frame;	/* specifies tx pause frame support */
6796f3e57acSmx 	boolean_t	rx_pause_frame;	/* specifies rx pause frame support */
6806f3e57acSmx 	boolean_t	jumbo;		/* jumbo frame support */
6816f3e57acSmx 	boolean_t	tx_rx_64byte;	/* set the max tx/rx prd fetch size */
6826f3e57acSmx 	boolean_t	rx_hw_checksum;	/* specifies tx hw checksum feature */
6836f3e57acSmx 	uint32_t	tx_hw_checksum;	/* specifies rx hw checksum feature */
6846f3e57acSmx 	uint32_t	desc_type;	/* specifies descriptor type */
6856f3e57acSmx 	uint32_t	rx_desc_num;	/* specifies rx descriptor number */
6866f3e57acSmx 	uint32_t	tx_desc_num;	/* specifies tx descriptor number */
6876f3e57acSmx 	uint32_t	nge_split;	/* specifies the split number */
6886f3e57acSmx } nge_dev_spec_param_t;
6896f3e57acSmx 
6906f3e57acSmx typedef struct nge {
6916f3e57acSmx 	/*
6926f3e57acSmx 	 * These fields are set by attach() and unchanged thereafter ...
6936f3e57acSmx 	 */
6946f3e57acSmx 	dev_info_t		*devinfo;	/* device instance	*/
6956f3e57acSmx 	mac_handle_t		mh;		/* mac module handle    */
6966f3e57acSmx 	chip_info_t		chipinfo;
6976f3e57acSmx 	ddi_acc_handle_t	cfg_handle;	/* DDI I/O handle	*/
6986f3e57acSmx 	ddi_acc_handle_t	io_handle;	/* DDI I/O handle	*/
6996f3e57acSmx 	void			*io_regs;	/* mapped registers	*/
7006f3e57acSmx 
7016f3e57acSmx 	ddi_periodic_t		periodic_id;	/* periodical callback	*/
7026f3e57acSmx 	uint32_t		factotum_flag;
7036f3e57acSmx 	ddi_softint_handle_t	factotum_hdl;	/* factotum callback	*/
7046f3e57acSmx 	ddi_softint_handle_t	resched_hdl;	/* reschedule callback	*/
7056f3e57acSmx 	uint_t			soft_pri;
7066f3e57acSmx 
7076f3e57acSmx 	ddi_intr_handle_t 	*htable;	/* for array of interrupts */
7086f3e57acSmx 	int			intr_type;	/* type of interrupt */
7096f3e57acSmx 	int			intr_actual_cnt; /* alloc intrs count */
7106f3e57acSmx 	int			intr_req_cnt;	/* request intrs count */
7116f3e57acSmx 	uint_t			intr_pri;	/* interrupt priority	*/
7126f3e57acSmx 	int			intr_cap;	/* interrupt capabilities */
7136f3e57acSmx 
7146f3e57acSmx 	uint32_t		progress;	/* attach tracking	*/
7156f3e57acSmx 	uint32_t		debug;		/* flag to debug function */
7166f3e57acSmx 
7176f3e57acSmx 	char			ifname[8];	/* "nge0" ... "nge999" */
7186f3e57acSmx 
7196f3e57acSmx 
7206f3e57acSmx 	enum nge_mac_state	nge_mac_state;	/* definitions above	*/
7216f3e57acSmx 	enum nge_chip_state	nge_chip_state; /* definitions above	*/
7226f3e57acSmx 	boolean_t		promisc;
7236de4f663Smx 	boolean_t		record_promisc;
7246f3e57acSmx 	boolean_t		suspended;
7256f3e57acSmx 
7266f3e57acSmx 	int			resched_needed;
7276f3e57acSmx 	uint32_t		default_mtu;
7286f3e57acSmx 	uint32_t		max_sdu;
7296f3e57acSmx 	uint32_t		buf_size;
7306f3e57acSmx 	uint32_t		rx_desc;
7316f3e57acSmx 	uint32_t		tx_desc;
7326f3e57acSmx 	uint32_t		rx_buf;
7336f3e57acSmx 	uint32_t		nge_split;
7346f3e57acSmx 	uint32_t		watchdog;
7356f3e57acSmx 	uint32_t		lowmem_mode;
7366f3e57acSmx 
7376f3e57acSmx 
7386f3e57acSmx 	/*
7396f3e57acSmx 	 * Runtime read-write data starts here ...
7406f3e57acSmx 	 * 1 Receive Rings
7416f3e57acSmx 	 * 1 Send Rings
7426f3e57acSmx 	 *
7436f3e57acSmx 	 * Note: they're not necessarily all used.
7446f3e57acSmx 	 */
7456f3e57acSmx 	struct buff_ring	buff[1];
7466f3e57acSmx 	struct recv_ring	recv[1];
7476f3e57acSmx 	struct send_ring	send[1];
7486f3e57acSmx 
7496f3e57acSmx 
7506f3e57acSmx 	kmutex_t		genlock[1];
7516f3e57acSmx 	krwlock_t		rwlock[1];
7526f3e57acSmx 	kmutex_t		softlock[1];
7536f3e57acSmx 	uint32_t		intr_masks;
7546f3e57acSmx 	boolean_t		poll;
7556f3e57acSmx 	boolean_t		ch_intr_mode;
75602d51d0dSjj 	boolean_t		intr_moderation;
7576f3e57acSmx 	uint32_t		recv_count;
75802d51d0dSjj 	uint32_t		quiet_time;
75902d51d0dSjj 	uint32_t		busy_time;
760*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 	uint64_t		tpkts_last;
761*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 	uint32_t		tfint_threshold;
7626f3e57acSmx 	uint32_t		sw_intr_intv;
7636f3e57acSmx 	nge_mac_addr_t		cur_uni_addr;
7646f3e57acSmx 	uint32_t		rx_datahwm;
7656f3e57acSmx 	uint32_t		rx_prdlwm;
7666f3e57acSmx 	uint32_t		rx_prdhwm;
7676f3e57acSmx 	uint32_t		rx_def;
7686f3e57acSmx 	uint32_t		desc_mode;
7696f3e57acSmx 
7706f3e57acSmx 	mul_item		*pcur_mulist;
7716f3e57acSmx 	nge_mac_addr_t		cur_mul_addr;
7726f3e57acSmx 	nge_mac_addr_t		cur_mul_mask;
7736f3e57acSmx 
7746f3e57acSmx 	nge_desc_attr_t		desc_attr;
7756f3e57acSmx 
7766f3e57acSmx 	/*
7776f3e57acSmx 	 * Link state data (protected by genlock)
7786f3e57acSmx 	 */
7796f3e57acSmx 	int32_t			link_state;	/* See GLD #defines	*/
7806f3e57acSmx 	uint32_t		stall_cknum;	/* Stall check number */
7816f3e57acSmx 
7826f3e57acSmx 	uint32_t		phy_xmii_addr;
7836f3e57acSmx 	uint32_t		phy_id;
7846f3e57acSmx 	uint32_t		phy_mode;
7856f3e57acSmx 	const phys_ops_t	*physops;
7866f3e57acSmx 	uint16_t		phy_gen_status;
7876f3e57acSmx 
7886f3e57acSmx 	uint32_t		param_loop_mode;
7896f3e57acSmx 
7906f3e57acSmx 	kstat_t			*nge_kstats[NGE_KSTAT_COUNT];
7916f3e57acSmx 	nge_statistics_t	statistics;
7926f3e57acSmx 
7936f3e57acSmx 	nge_dev_spec_param_t	dev_spec_param;
7946f3e57acSmx 
7955a3d0718Smx 	uint32_t		param_en_pause:1,
7965a3d0718Smx 				param_en_asym_pause:1,
7975a3d0718Smx 				param_en_1000hdx:1,
7985a3d0718Smx 				param_en_1000fdx:1,
7995a3d0718Smx 				param_en_100fdx:1,
8005a3d0718Smx 				param_en_100hdx:1,
8015a3d0718Smx 				param_en_10fdx:1,
8025a3d0718Smx 				param_en_10hdx:1,
8034045d941Ssowmini 				param_adv_autoneg:1,
8044045d941Ssowmini 				param_adv_pause:1,
8054045d941Ssowmini 				param_adv_asym_pause:1,
8064045d941Ssowmini 				param_adv_1000fdx:1,
8074045d941Ssowmini 				param_adv_1000hdx:1,
8084045d941Ssowmini 				param_adv_100fdx:1,
8094045d941Ssowmini 				param_adv_100hdx:1,
8104045d941Ssowmini 				param_adv_10fdx:1,
8114045d941Ssowmini 				param_adv_10hdx:1,
8124045d941Ssowmini 				param_lp_autoneg:1,
8134045d941Ssowmini 				param_lp_pause:1,
8144045d941Ssowmini 				param_lp_asym_pause:1,
8154045d941Ssowmini 				param_lp_1000fdx:1,
8164045d941Ssowmini 				param_lp_1000hdx:1,
8174045d941Ssowmini 				param_lp_100fdx:1,
8184045d941Ssowmini 				param_lp_100hdx:1,
8194045d941Ssowmini 				param_lp_10fdx:1,
8204045d941Ssowmini 				param_lp_10hdx:1,
8214045d941Ssowmini 				param_link_up:1,
8224045d941Ssowmini 				param_link_autoneg:1,
8234045d941Ssowmini 				param_link_rx_pause:1,
8244045d941Ssowmini 				param_link_tx_pause:1,
8254045d941Ssowmini 				param_pad_to_32:2;
8264045d941Ssowmini 	uint64_t		param_link_speed;
8274045d941Ssowmini 	link_duplex_t		param_link_duplex;
8284045d941Ssowmini 	int			param_txbcopy_threshold;
8294045d941Ssowmini 	int			param_rxbcopy_threshold;
8304045d941Ssowmini 	int			param_recv_max_packet;
8314045d941Ssowmini 	int			param_poll_quiet_time;
8324045d941Ssowmini 	int			param_poll_busy_time;
8334045d941Ssowmini 	int			param_rx_intr_hwater;
8344045d941Ssowmini 	int			param_rx_intr_lwater;
8356f3e57acSmx } nge_t;
8366f3e57acSmx 
8376f3e57acSmx extern const nge_ksindex_t nge_statistics[];
8386f3e57acSmx 
8396f3e57acSmx /*
8406f3e57acSmx  * Sync a DMA area described by a dma_area_t
8416f3e57acSmx  */
8426f3e57acSmx #define	DMA_SYNC(area, flag)	((void) ddi_dma_sync((area).dma_hdl,	\
8436f3e57acSmx 				    (area).offset, (area).alength, (flag)))
8446f3e57acSmx 
8456f3e57acSmx /*
8466f3e57acSmx  * Find the (kernel virtual) address of block of memory
8476f3e57acSmx  * described by a dma_area_t
8486f3e57acSmx  */
8496f3e57acSmx #define	DMA_VPTR(area)		((area).mem_va)
8506f3e57acSmx 
8516f3e57acSmx /*
8526f3e57acSmx  * Zero a block of memory described by a dma_area_t
8536f3e57acSmx  */
8546f3e57acSmx #define	DMA_ZERO(area)		bzero(DMA_VPTR(area), (area).alength)
8556f3e57acSmx 
8566f3e57acSmx /*
8576f3e57acSmx  * Next/Prev value of a cyclic index
8586f3e57acSmx  */
8596f3e57acSmx #define	NEXT(index, limit)	((index) + 1 < (limit) ? (index) + 1 : 0)
8606f3e57acSmx #define	PREV(index, limit)	(0 == (index) ? (limit - 1) : (index) - 1)
8616f3e57acSmx 
8626f3e57acSmx #define	NEXT_INDEX(ndx, num, lim)\
8636f3e57acSmx 	(((ndx) + (num) < (lim)) ? ((ndx) + (num)) : ((ndx) + (num) - (lim)))
8646f3e57acSmx 
8656f3e57acSmx 
8666f3e57acSmx /*
8676f3e57acSmx  * Property lookups
8686f3e57acSmx  */
8696f3e57acSmx #define	NGE_PROP_EXISTS(d, n)	ddi_prop_exists(DDI_DEV_T_ANY, (d),	\
8706f3e57acSmx 					DDI_PROP_DONTPASS, (n))
8716f3e57acSmx #define	NGE_PROP_GET_INT(d, n)	ddi_prop_get_int(DDI_DEV_T_ANY, (d),	\
8726f3e57acSmx 					DDI_PROP_DONTPASS, (n), -1)
8736f3e57acSmx 
8746f3e57acSmx 
8756f3e57acSmx /*
8766f3e57acSmx  * Debugging ...
8776f3e57acSmx  */
8786f3e57acSmx #ifdef	DEBUG
8796f3e57acSmx #define	NGE_DEBUGGING		1
8806f3e57acSmx #else
8816f3e57acSmx #define	NGE_DEBUGGING		0
8826f3e57acSmx #endif	/* DEBUG */
8836f3e57acSmx 
8846f3e57acSmx /*
8856f3e57acSmx  * Bit flags in the 'debug' word ...
8866f3e57acSmx  */
8876f3e57acSmx #define	NGE_DBG_STOP		0x00000001	/* early debug_enter()	*/
8886f3e57acSmx #define	NGE_DBG_TRACE		0x00000002	/* general flow tracing	*/
8896f3e57acSmx 
8906f3e57acSmx #define	NGE_DBG_MII		0x00000010	/* low-level MII access	*/
8916f3e57acSmx #define	NGE_DBG_CHIP		0x00000020	/* low(ish)-level code	*/
8926f3e57acSmx 
8936f3e57acSmx #define	NGE_DBG_RECV		0x00000100	/* receive-side code	*/
8946f3e57acSmx #define	NGE_DBG_SEND		0x00000200	/* packet-send code	*/
8956f3e57acSmx 
8966f3e57acSmx #define	NGE_DBG_INIT		0x00100000	/* initialisation	*/
8976f3e57acSmx #define	NGE_DBG_NEMO		0x00200000	/* MAC layer entry points */
8986f3e57acSmx #define	NGE_DBG_STATS		0x00400000	/* statistics		*/
8996f3e57acSmx 
9006f3e57acSmx #define	NGE_DBG_BADIOC		0x01000000	/* unknown ioctls	*/
9016f3e57acSmx 
9026f3e57acSmx #define	NGE_DBG_NDD		0x10000000	/* NDD operations	*/
9036f3e57acSmx 
9046f3e57acSmx 
9056f3e57acSmx 
9066f3e57acSmx /*
9076f3e57acSmx  * 'Do-if-debugging' macro.  The parameter <command> should be one or more
9086f3e57acSmx  * C statements (but without the *final* semicolon), which will either be
9096f3e57acSmx  * compiled inline or completely ignored, depending on the NGE_DEBUGGING
9106f3e57acSmx  * compile-time flag.
9116f3e57acSmx  *
9126f3e57acSmx  * You should get a compile-time error (at least on a DEBUG build) if
9136f3e57acSmx  * your statement isn't actually a statement, rather than unexpected
9146f3e57acSmx  * run-time behaviour caused by unintended matching of if-then-elses etc.
9156f3e57acSmx  *
9166f3e57acSmx  * Note that the NGE_DDB() macro itself can only be used as a statement,
9176f3e57acSmx  * not an expression, and should always be followed by a semicolon.
9186f3e57acSmx  */
9196f3e57acSmx #if NGE_DEBUGGING
9206f3e57acSmx #define	NGE_DDB(command)	do {					\
9216f3e57acSmx 					{ command; }			\
9226f3e57acSmx 					_NOTE(CONSTANTCONDITION)	\
9236f3e57acSmx 				} while (0)
9246f3e57acSmx #else 	/* NGE_DEBUGGING */
9256f3e57acSmx #define	NGE_DDB(command)
9266f3e57acSmx /*
9276f3e57acSmx  * Old way of debugging.  This is a poor way, as it leeaves empty
9286f3e57acSmx  * statements that cause lint to croak.
9296f3e57acSmx  * #define	NGE_DDB(command)	do {				\
9306f3e57acSmx  * 					{ _NOTE(EMPTY); }		\
9316f3e57acSmx  * 					_NOTE(CONSTANTCONDITION)	\
9326f3e57acSmx  * 				} while (0)
9336f3e57acSmx  */
9346f3e57acSmx #endif	/* NGE_DEBUGGING */
9356f3e57acSmx 
9366f3e57acSmx /*
9376f3e57acSmx  * 'Internal' macros used to construct the TRACE/DEBUG macros below.
9386f3e57acSmx  * These provide the primitive conditional-call capability required.
9396f3e57acSmx  * Note: the parameter <args> is a parenthesised list of the actual
9406f3e57acSmx  * printf-style arguments to be passed to the debug function ...
9416f3e57acSmx  */
9426f3e57acSmx #define	NGE_XDB(b, w, f, args)	NGE_DDB(if ((b) & (w)) f args)
9436f3e57acSmx #define	NGE_GDB(b, args)	NGE_XDB(b, nge_debug, (*nge_gdb()), args)
9446f3e57acSmx #define	NGE_LDB(b, args)	NGE_XDB(b, ngep->debug, \
9456f3e57acSmx 				    (*nge_db(ngep)), args)
9466f3e57acSmx #define	NGE_CDB(f, args)	NGE_XDB(NGE_DBG, ngep->debug, f, args)
9476f3e57acSmx 
9486f3e57acSmx /*
9496f3e57acSmx  * Conditional-print macros.
9506f3e57acSmx  *
9516f3e57acSmx  * Define NGE_DBG to be the relevant member of the set of NGE_DBG_* values
9526f3e57acSmx  * above before using the NGE_GDEBUG() or NGE_DEBUG() macros.  The 'G'
9536f3e57acSmx  * versions look at the Global debug flag word (nge_debug); the non-G
9546f3e57acSmx  * versions look in the per-instance data (ngep->debug) and so require a
9556f3e57acSmx  * variable called 'ngep' to be in scope (and initialised!) before use.
9566f3e57acSmx  *
9576f3e57acSmx  * You could redefine NGE_TRC too if you really need two different
9586f3e57acSmx  * flavours of debugging output in the same area of code, but I don't
9596f3e57acSmx  * really recommend it.
9606f3e57acSmx  *
9616f3e57acSmx  * Note: the parameter <args> is a parenthesised list of the actual
9626f3e57acSmx  * arguments to be passed to the debug function, usually a printf-style
9636f3e57acSmx  * format string and corresponding values to be formatted.
9646f3e57acSmx  */
9656f3e57acSmx 
9666f3e57acSmx #define	NGE_TRC	NGE_DBG_TRACE
9676f3e57acSmx 
9686f3e57acSmx #define	NGE_GTRACE(args)	NGE_GDB(NGE_TRC, args)
9696f3e57acSmx #define	NGE_GDEBUG(args)	NGE_GDB(NGE_DBG, args)
9706f3e57acSmx #define	NGE_TRACE(args)		NGE_LDB(NGE_TRC, args)
9716f3e57acSmx #define	NGE_DEBUG(args)		NGE_LDB(NGE_DBG, args)
9726f3e57acSmx 
9736f3e57acSmx /*
9746f3e57acSmx  * Debug-only action macros
9756f3e57acSmx  */
9766f3e57acSmx 
9776f3e57acSmx 
9786f3e57acSmx #define	NGE_REPORT(args)	NGE_DDB(nge_log args)
9796f3e57acSmx 
9806f3e57acSmx boolean_t nge_atomic_decrease(uint64_t *count_p, uint64_t n);
9816f3e57acSmx void nge_atomic_increase(uint64_t *count_p, uint64_t n);
9826f3e57acSmx 
9836f3e57acSmx int nge_alloc_dma_mem(nge_t *ngep, size_t memsize,
9846f3e57acSmx     ddi_device_acc_attr_t *attr_p, uint_t dma_flags, dma_area_t *dma_p);
9856f3e57acSmx void nge_free_dma_mem(dma_area_t *dma_p);
9866f3e57acSmx int nge_restart(nge_t *ngep);
9876f3e57acSmx void nge_wake_factotum(nge_t *ngep);
9886f3e57acSmx 
9896f3e57acSmx uint8_t nge_reg_get8(nge_t *ngep, nge_regno_t regno);
9906f3e57acSmx void nge_reg_put8(nge_t *ngep, nge_regno_t regno, uint8_t data);
9916f3e57acSmx uint16_t nge_reg_get16(nge_t *ngep, nge_regno_t regno);
9926f3e57acSmx void nge_reg_put16(nge_t *ngep, nge_regno_t regno, uint16_t data);
9936f3e57acSmx uint32_t nge_reg_get32(nge_t *ngep, nge_regno_t regno);
9946f3e57acSmx void nge_reg_put32(nge_t *ngep, nge_regno_t regno, uint32_t data);
9956f3e57acSmx uint_t nge_chip_factotum(caddr_t args1, caddr_t args2);
9966f3e57acSmx void nge_chip_cfg_init(nge_t *ngep, chip_info_t *infop, boolean_t reset);
9976f3e57acSmx void nge_init_dev_spec_param(nge_t *ngep);
9986f3e57acSmx int nge_chip_stop(nge_t *ngep, boolean_t fault);
9996f3e57acSmx void nge_restore_mac_addr(nge_t *ngep);
10006f3e57acSmx int nge_chip_reset(nge_t *ngep);
10016f3e57acSmx int nge_chip_start(nge_t *ngep);
10026f3e57acSmx void nge_chip_sync(nge_t *ngep);
10036f3e57acSmx 
10046f3e57acSmx uint_t nge_chip_intr(caddr_t arg1, caddr_t arg2);
10056f3e57acSmx enum ioc_reply nge_chip_ioctl(nge_t *ngep, mblk_t *mp, struct iocblk *iocp);
10066f3e57acSmx 
10076f3e57acSmx void nge_phys_init(nge_t *ngep);
10086f3e57acSmx boolean_t nge_phy_reset(nge_t *ngep);
10096f3e57acSmx uint16_t nge_mii_get16(nge_t *ngep, nge_regno_t regno);
10106f3e57acSmx void nge_mii_put16(nge_t *ngep, nge_regno_t regno, uint16_t data);
10116f3e57acSmx 
10126f3e57acSmx void nge_recv_recycle(caddr_t arg);
10136f3e57acSmx void nge_receive(nge_t *ngep);
10146f3e57acSmx 
10156f3e57acSmx uint_t nge_reschedule(caddr_t args1, caddr_t args2);
10166f3e57acSmx mblk_t *nge_m_tx(void *arg, mblk_t *mp);
10176f3e57acSmx 
10186f3e57acSmx void nge_tx_recycle(nge_t *ngep, boolean_t is_intr);
10196f3e57acSmx void nge_tx_recycle_all(nge_t *ngep);
10206f3e57acSmx 
10216f3e57acSmx int nge_nd_init(nge_t *ngep);
10226f3e57acSmx void nge_nd_cleanup(nge_t *ngep);
10236f3e57acSmx 
10246f3e57acSmx 
10256f3e57acSmx void nge_init_kstats(nge_t *ngep, int instance);
10266f3e57acSmx void nge_fini_kstats(nge_t *ngep);
10276f3e57acSmx int nge_m_stat(void *arg, uint_t stat, uint64_t *val);
10286f3e57acSmx 
10296f3e57acSmx uint32_t nge_atomic_shl32(uint32_t *sp, uint_t count);
10306f3e57acSmx 
10316f3e57acSmx void nge_log(nge_t *ngep, const char *fmt, ...);
10326f3e57acSmx void nge_problem(nge_t *ngep, const char *fmt, ...);
10336f3e57acSmx void nge_error(nge_t *ngep, const char *fmt, ...);
10346f3e57acSmx void
10356f3e57acSmx nge_report(nge_t *ngep, uint8_t error_id);
10366f3e57acSmx 
10376f3e57acSmx void (*nge_db(nge_t *ngep))(const char *fmt, ...);
10386f3e57acSmx void (*nge_gdb(void))(const char *fmt, ...);
10396f3e57acSmx extern	uint32_t nge_debug;
10406f3e57acSmx 
10416f3e57acSmx /*
10426f3e57acSmx  * DESC MODE 2
10436f3e57acSmx  */
10446f3e57acSmx 
10456f3e57acSmx extern void nge_sum_rxd_fill(void *, const ddi_dma_cookie_t *, size_t);
10466f3e57acSmx extern uint32_t nge_sum_rxd_check(const void *, size_t *);
10476f3e57acSmx 
10486f3e57acSmx extern void nge_sum_txd_fill(void *, const ddi_dma_cookie_t *,
1049*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 				size_t, uint32_t, boolean_t, boolean_t);
10509fa05d92SWinson Wang - Sun Microsystems - Beijing China extern uint32_t nge_sum_txd_check(const void *);
10516f3e57acSmx 
10526f3e57acSmx /*
10536f3e57acSmx  * DESC MODE 3
10546f3e57acSmx  */
10556f3e57acSmx 
10566f3e57acSmx extern void nge_hot_rxd_fill(void *, const ddi_dma_cookie_t *, size_t);
10576f3e57acSmx extern uint32_t nge_hot_rxd_check(const void *, size_t *);
10586f3e57acSmx 
10596f3e57acSmx extern void nge_hot_txd_fill(void *, const ddi_dma_cookie_t *,
1060*51fc88a8SWinson Wang - Sun Microsystems - Beijing China 				size_t, uint32_t, boolean_t, boolean_t);
10619fa05d92SWinson Wang - Sun Microsystems - Beijing China extern uint32_t nge_hot_txd_check(const void *);
10626f3e57acSmx 
10636f3e57acSmx #ifdef __cplusplus
10646f3e57acSmx }
10656f3e57acSmx #endif
10666f3e57acSmx 
10676f3e57acSmx #endif	/* _SYS_NGE_H */
1068