xref: /onnv-gate/usr/src/uts/common/io/nge/nge.h (revision 5578:c0773208044e)
1*5578Smx205022 /*
2*5578Smx205022  * CDDL HEADER START
3*5578Smx205022  *
4*5578Smx205022  * The contents of this file are subject to the terms of the
5*5578Smx205022  * Common Development and Distribution License (the "License").
6*5578Smx205022  * You may not use this file except in compliance with the License.
7*5578Smx205022  *
8*5578Smx205022  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5578Smx205022  * or http://www.opensolaris.org/os/licensing.
10*5578Smx205022  * See the License for the specific language governing permissions
11*5578Smx205022  * and limitations under the License.
12*5578Smx205022  *
13*5578Smx205022  * When distributing Covered Code, include this CDDL HEADER in each
14*5578Smx205022  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5578Smx205022  * If applicable, add the following below this CDDL HEADER, with the
16*5578Smx205022  * fields enclosed by brackets "[]" replaced with your own identifying
17*5578Smx205022  * information: Portions Copyright [yyyy] [name of copyright owner]
18*5578Smx205022  *
19*5578Smx205022  * CDDL HEADER END
20*5578Smx205022  */
21*5578Smx205022 
225574Smx205022 /*
235574Smx205022  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
245574Smx205022  * Use is subject to license terms.
255574Smx205022  */
265574Smx205022 
275574Smx205022 #ifndef	_SYS_NGE_H
285574Smx205022 #define	_SYS_NGE_H
295574Smx205022 
305574Smx205022 #pragma ident	"%Z%%M%	%I%	%E% SMI"
315574Smx205022 
325574Smx205022 #ifdef __cplusplus
335574Smx205022 extern "C" {
345574Smx205022 #endif
355574Smx205022 
365574Smx205022 
375574Smx205022 #include <sys/types.h>
385574Smx205022 #include <sys/stream.h>
395574Smx205022 #include <sys/strsun.h>
405574Smx205022 #include <sys/strsubr.h>
415574Smx205022 #include <sys/stat.h>
425574Smx205022 #include <sys/pci.h>
435574Smx205022 #include <sys/note.h>
445574Smx205022 #include <sys/modctl.h>
455574Smx205022 #include <sys/kstat.h>
465574Smx205022 #include <sys/ethernet.h>
475574Smx205022 #include <sys/pattr.h>
485574Smx205022 #include <sys/errno.h>
495574Smx205022 #include <sys/dlpi.h>
505574Smx205022 #include <sys/devops.h>
515574Smx205022 #include <sys/debug.h>
525574Smx205022 #include <sys/conf.h>
535574Smx205022 #include <sys/callb.h>
545574Smx205022 
555574Smx205022 #include <netinet/ip6.h>
565574Smx205022 
575574Smx205022 #include <inet/common.h>
585574Smx205022 #include <inet/ip.h>
595574Smx205022 #include <netinet/udp.h>
605574Smx205022 #include <inet/mi.h>
615574Smx205022 #include <inet/nd.h>
625574Smx205022 
635574Smx205022 #include <sys/ddi.h>
645574Smx205022 #include <sys/sunddi.h>
655574Smx205022 
665574Smx205022 #include <sys/mac.h>
675574Smx205022 #include <sys/mac_ether.h>
685574Smx205022 
695574Smx205022 /*
705574Smx205022  * Reconfiguring the network devices requires the net_config privilege
715574Smx205022  * in Solaris 10+.
725574Smx205022  */
735574Smx205022 extern int secpolicy_net_config(const cred_t *, boolean_t);
745574Smx205022 
755574Smx205022 #include <sys/netlb.h>
765574Smx205022 #include <sys/miiregs.h>
775574Smx205022 
785574Smx205022 #include "nge_chip.h"
795574Smx205022 
805574Smx205022 #define	PIO_ADDR(ngep, offset)	((void *)((caddr_t)(ngep)->io_regs+(offset)))
815574Smx205022 /*
825574Smx205022  * Copy an ethernet address
835574Smx205022  */
845574Smx205022 #define	ethaddr_copy(src, dst)	bcopy((src), (dst), ETHERADDRL)
855574Smx205022 #define	ether_eq(a, b) (bcmp((caddr_t)(a), (caddr_t)(b), (ETHERADDRL)) == 0)
865574Smx205022 
875574Smx205022 #define	BIS(w, b)	(((w) & (b)) ? B_TRUE : B_FALSE)
885574Smx205022 #define	BIC(w, b)	(((w) & (b)) ? B_FALSE : B_TRUE)
895574Smx205022 #define	UPORDOWN(x)	((x) ? "up" : "down")
905574Smx205022 
915574Smx205022 #define	NGE_DRIVER_NAME		"nge"
925574Smx205022 
935574Smx205022 /*
945574Smx205022  * 'Progress' bit flags ...
955574Smx205022  */
965574Smx205022 #define	PROGRESS_CFG		0x0001	/* config space mapped		*/
975574Smx205022 #define	PROGRESS_REGS		0x0002	/* registers mapped		*/
985574Smx205022 #define	PROGRESS_BUFS		0x0004	/* registers mapped		*/
995574Smx205022 #define	PROGRESS_RESCHED	0x0008	/* resched softint registered	*/
1005574Smx205022 #define	PROGRESS_FACTOTUM	0x0010	/* factotum softint registered	*/
1015574Smx205022 #define	PROGRESS_SWINT		0x0020	/* s/w interrupt registered	*/
1025574Smx205022 #define	PROGRESS_INTR		0x0040	/* h/w interrupt registered	*/
1035574Smx205022 					/* and mutexen initialised	*/
1045574Smx205022 #define	PROGRESS_HWINT		0x0080
1055574Smx205022 #define	PROGRESS_PHY		0x0100	/* PHY initialised		*/
1065574Smx205022 #define	PROGRESS_NDD		0x0200	/* NDD parameters set up	*/
1075574Smx205022 #define	PROGRESS_KSTATS		0x0400	/* kstats created		*/
1085574Smx205022 #define	PROGRESS_READY		0x0800	/* ready for work		*/
1095574Smx205022 
1105574Smx205022 #define	NGE_HW_ERR		0x00
1115574Smx205022 #define	NGE_HW_LINK		0x01
1125574Smx205022 #define	NGE_HW_BM		0x02
1135574Smx205022 #define	NGE_HW_RCHAN		0x03
1145574Smx205022 #define	NGE_HW_TCHAN		0x04
1155574Smx205022 #define	NGE_HW_ROM		0x05
1165574Smx205022 #define	NGE_SW_PROBLEM_ID	0x06
1175574Smx205022 
1185574Smx205022 
1195574Smx205022 /*
1205574Smx205022  * NOTES:
1215574Smx205022  *
1225574Smx205022  * #defines:
1235574Smx205022  *
1245574Smx205022  *	NGE_PCI_CONFIG_RNUMBER and NGE_PCI_OPREGS_RNUMBER are the
1255574Smx205022  *	register-set numbers to use for the config space registers
1265574Smx205022  *	and the operating registers respectively.  On an OBP-based
1275574Smx205022  *	machine, regset 0 refers to CONFIG space, and regset 1 will
1285574Smx205022  *	be the operating registers in MEMORY space.  If an expansion
1295574Smx205022  *	ROM is fitted, it may appear as a further register set.
1305574Smx205022  *
1315574Smx205022  *	NGE_DMA_MODE defines the mode (STREAMING/CONSISTENT) used
1325574Smx205022  *	for the data buffers.  The descriptors are always set up
1335574Smx205022  *	in CONSISTENT mode.
1345574Smx205022  *
1355574Smx205022  *	NGE_HEADROOM defines how much space we'll leave in allocated
1365574Smx205022  *	mblks before the first valid data byte.  This should be chosen
1375574Smx205022  *	to be 2 modulo 4, so that once the ethernet header (14 bytes)
1385574Smx205022  *	has been stripped off, the packet data will be 4-byte aligned.
1395574Smx205022  *	The remaining space can be used by upstream modules to prepend
1405574Smx205022  *	any headers required.
1415574Smx205022  */
1425574Smx205022 
1435574Smx205022 
1445574Smx205022 #define	NGE_PCI_OPREGS_RNUMBER	1
1455574Smx205022 #define	NGE_DMA_MODE		DDI_DMA_STREAMING
1465574Smx205022 #define	NGE_HEADROOM		6
1475574Smx205022 #define	ETHER_HEAD_LEN		14
1485574Smx205022 #ifndef	VTAG_SIZE
1495574Smx205022 #define	VTAG_SIZE		4
1505574Smx205022 #endif
1515574Smx205022 
1525574Smx205022 #define	NGE_HALFTICK		268435456LL		/* 2**28 ns!	*/
1535574Smx205022 #define	NGE_CYCLIC_PERIOD	(4*NGE_HALFTICK)	/*    ~0.5s	*/
1545574Smx205022 
1555574Smx205022 #define	NGE_DEFAULT_MTU		1500
1565574Smx205022 #define	NGE_DEFAULT_SDU		1518
1575574Smx205022 #define	NGE_MTU_2500		2500
1585574Smx205022 #define	NGE_MTU_4500		4500
1595574Smx205022 #define	NGE_MAX_MTU		9000
1605574Smx205022 #define	NGE_MAX_SDU		9018
1615574Smx205022 
1625574Smx205022 #define	NGE_DESC_MIN		0x100
1635574Smx205022 
1645574Smx205022 #define	NGE_STD_BUFSZ		1792
1655574Smx205022 #define	NGE_JB2500_BUFSZ	(3*1024)
1665574Smx205022 #define	NGE_JB4500_BUFSZ	(5*1024)
1675574Smx205022 #define	NGE_JB9000_BUFSZ	(9*1024)
1685574Smx205022 
1695574Smx205022 #define	NGE_SEND_SLOTS_DESC_1024	1024
1705574Smx205022 #define	NGE_SEND_SLOTS_DESC_3072	3072
1715574Smx205022 #define	NGE_SEND_JB2500_SLOTS_DESC	3072
1725574Smx205022 #define	NGE_SEND_JB4500_SLOTS_DESC	2048
1735574Smx205022 #define	NGE_SEND_JB9000_SLOTS_DESC	1024
1745574Smx205022 #define	NGE_SEND_LOWMEM_SLOTS_DESC	1024
1755574Smx205022 #define	NGE_SEND_SLOTS_BUF		3072
1765574Smx205022 
1775574Smx205022 #define	NGE_RECV_SLOTS_DESC_1024	1024
1785574Smx205022 #define	NGE_RECV_SLOTS_DESC_3072	3072
1795574Smx205022 #define	NGE_RECV_JB2500_SLOTS_DESC	3072
1805574Smx205022 #define	NGE_RECV_JB4500_SLOTS_DESC	2048
1815574Smx205022 #define	NGE_RECV_JB9000_SLOTS_DESC	1024
1825574Smx205022 #define	NGE_RECV_LOWMEM_SLOTS_DESC	1024
1835574Smx205022 #define	NGE_RECV_SLOTS_BUF		6144
1845574Smx205022 
1855574Smx205022 #define	NGE_SPLIT_32		32
1865574Smx205022 #define	NGE_SPLIT_96		96
1875574Smx205022 #define	NGE_SPLIT_256		256
1885574Smx205022 
1895574Smx205022 #define	NGE_RX_COPY_SIZE	512
1905574Smx205022 #define	NGE_TX_COPY_SIZE	512
1915574Smx205022 #define	NGE_MAP_FRAGS		3
1925574Smx205022 #define	NGE_MAX_COOKIES		3
1935574Smx205022 #define	NGE_MAX_DMA_HDR		(4*1024)
1945574Smx205022 
1955574Smx205022 /* Used by interrupt blank */
1965574Smx205022 #define	NGE_TICKS_CNT	128
1975574Smx205022 #define	NGE_RX_PKT_CNT	8
1985574Smx205022 
1995574Smx205022 /*
2005574Smx205022  * NGE-specific ioctls ...
2015574Smx205022  */
2025574Smx205022 #define	NGE_IOC			((((('N' << 8) + 'G') << 8) + 'E') << 8)
2035574Smx205022 
2045574Smx205022 /*
2055574Smx205022  * PHY register read/write ioctls, used by cable test software
2065574Smx205022  */
2075574Smx205022 #define	NGE_MII_READ		(NGE_IOC|1)
2085574Smx205022 #define	NGE_MII_WRITE		(NGE_IOC|2)
2095574Smx205022 
2105574Smx205022 /*
2115574Smx205022  * SEEPROM read/write ioctls, for use by SEEPROM upgrade utility
2125574Smx205022  *
2135574Smx205022  * Note: SEEPROMs can only be accessed as 32-bit words, so <see_addr>
2145574Smx205022  * must be a multiple of 4.  Not all systems have a SEEPROM fitted!
2155574Smx205022  */
2165574Smx205022 #define	NGE_SEE_READ		(NGE_IOC|3)
2175574Smx205022 #define	NGE_SEE_WRITE		(NGE_IOC|4)
2185574Smx205022 
2195574Smx205022 
2205574Smx205022 /*
2215574Smx205022  * These diagnostic IOCTLS are enabled only in DEBUG drivers
2225574Smx205022  */
2235574Smx205022 #define	NGE_DIAG		(NGE_IOC|5)	/* currently a no-op	*/
2245574Smx205022 #define	NGE_PEEK		(NGE_IOC|6)
2255574Smx205022 #define	NGE_POKE		(NGE_IOC|7)
2265574Smx205022 #define	NGE_PHY_RESET		(NGE_IOC|8)
2275574Smx205022 #define	NGE_SOFT_RESET		(NGE_IOC|9)
2285574Smx205022 #define	NGE_HARD_RESET		(NGE_IOC|10)
2295574Smx205022 
2305574Smx205022 
2315574Smx205022 enum NGE_HW_OP {
2325574Smx205022 	NGE_CLEAR = 0,
2335574Smx205022 	NGE_SET
2345574Smx205022 };
2355574Smx205022 
2365574Smx205022 /*
2375574Smx205022  * Required state according to GLD
2385574Smx205022  */
2395574Smx205022 enum nge_mac_state {
2405574Smx205022 	NGE_MAC_UNKNOWN,
2415574Smx205022 	NGE_MAC_RESET,
2425574Smx205022 	NGE_MAC_STOPPED,
2435574Smx205022 	NGE_MAC_STARTED,
2445574Smx205022 	NGE_MAC_UNATTACH
2455574Smx205022 };
2465574Smx205022 enum loop_type {
2475574Smx205022 	NGE_LOOP_NONE = 0,
2485574Smx205022 	NGE_LOOP_EXTERNAL_100,
2495574Smx205022 	NGE_LOOP_EXTERNAL_10,
2505574Smx205022 	NGE_LOOP_INTERNAL_PHY,
2515574Smx205022 };
2525574Smx205022 
2535574Smx205022 /*
2545574Smx205022  * (Internal) return values from send_msg subroutines
2555574Smx205022  */
2565574Smx205022 enum send_status {
2575574Smx205022 	SEND_COPY_FAIL = -1,		/* => GLD_NORESOURCES	*/
2585574Smx205022 	SEND_MAP_FAIL,			/* => GLD_NORESOURCES	*/
2595574Smx205022 	SEND_COPY_SUCESS,		/* OK, msg queued	*/
2605574Smx205022 	SEND_MAP_SUCCESS		/* OK, free msg		*/
2615574Smx205022 };
2625574Smx205022 
2635574Smx205022 
2645574Smx205022 /*
2655574Smx205022  * NDD parameter indexes, divided into:
2665574Smx205022  *
2675574Smx205022  *	read-only parameters describing the hardware's capabilities
2685574Smx205022  *	read-write parameters controlling the advertised capabilities
2695574Smx205022  *	read-only parameters describing the partner's capabilities
2705574Smx205022  *	read-only parameters describing the link state
2715574Smx205022  */
2725574Smx205022 enum {
2735574Smx205022 	PARAM_AUTONEG_CAP,
2745574Smx205022 	PARAM_PAUSE_CAP,
2755574Smx205022 	PARAM_ASYM_PAUSE_CAP,
2765574Smx205022 	PARAM_1000FDX_CAP,
2775574Smx205022 	PARAM_1000HDX_CAP,
2785574Smx205022 	PARAM_100T4_CAP,
2795574Smx205022 	PARAM_100FDX_CAP,
2805574Smx205022 	PARAM_100HDX_CAP,
2815574Smx205022 	PARAM_10FDX_CAP,
2825574Smx205022 	PARAM_10HDX_CAP,
2835574Smx205022 
2845574Smx205022 	PARAM_ADV_AUTONEG_CAP,
2855574Smx205022 	PARAM_ADV_PAUSE_CAP,
2865574Smx205022 	PARAM_ADV_ASYM_PAUSE_CAP,
2875574Smx205022 	PARAM_ADV_1000FDX_CAP,
2885574Smx205022 	PARAM_ADV_1000HDX_CAP,
2895574Smx205022 	PARAM_ADV_100T4_CAP,
2905574Smx205022 	PARAM_ADV_100FDX_CAP,
2915574Smx205022 	PARAM_ADV_100HDX_CAP,
2925574Smx205022 	PARAM_ADV_10FDX_CAP,
2935574Smx205022 	PARAM_ADV_10HDX_CAP,
2945574Smx205022 
2955574Smx205022 	PARAM_LP_AUTONEG_CAP,
2965574Smx205022 	PARAM_LP_PAUSE_CAP,
2975574Smx205022 	PARAM_LP_ASYM_PAUSE_CAP,
2985574Smx205022 	PARAM_LP_1000FDX_CAP,
2995574Smx205022 	PARAM_LP_1000HDX_CAP,
3005574Smx205022 	PARAM_LP_100T4_CAP,
3015574Smx205022 	PARAM_LP_100FDX_CAP,
3025574Smx205022 	PARAM_LP_100HDX_CAP,
3035574Smx205022 	PARAM_LP_10FDX_CAP,
3045574Smx205022 	PARAM_LP_10HDX_CAP,
3055574Smx205022 
3065574Smx205022 	PARAM_LINK_STATUS,
3075574Smx205022 	PARAM_LINK_SPEED,
3085574Smx205022 	PARAM_LINK_DUPLEX,
3095574Smx205022 
3105574Smx205022 	PARAM_LINK_AUTONEG,
3115574Smx205022 	PARAM_LINK_RX_PAUSE,
3125574Smx205022 	PARAM_LINK_TX_PAUSE,
3135574Smx205022 
3145574Smx205022 	PARAM_LOOP_MODE,
3155574Smx205022 	PARAM_TXBCOPY_THRESHOLD,
3165574Smx205022 	PARAM_RXBCOPY_THRESHOLD,
3175574Smx205022 	PARAM_RECV_MAX_PACKET,
3185574Smx205022 
3195574Smx205022 	PARAM_COUNT
3205574Smx205022 };
3215574Smx205022 
3225574Smx205022 
3235574Smx205022 /*
3245574Smx205022  * (Internal) return values from ioctl subroutines
3255574Smx205022  */
3265574Smx205022 enum ioc_reply {
3275574Smx205022 	IOC_INVAL = -1,			/* bad, NAK with EINVAL	*/
3285574Smx205022 	IOC_DONE,			/* OK, reply sent	*/
3295574Smx205022 	IOC_ACK,			/* OK, just send ACK	*/
3305574Smx205022 	IOC_REPLY,			/* OK, just send reply	*/
3315574Smx205022 	IOC_RESTART_ACK,		/* OK, restart & ACK	*/
3325574Smx205022 	IOC_RESTART_REPLY		/* OK, restart & reply	*/
3335574Smx205022 };
3345574Smx205022 
3355574Smx205022 enum nge_pp_type {
3365574Smx205022 	NGE_PP_SPACE_CFG = 0,
3375574Smx205022 	NGE_PP_SPACE_REG,
3385574Smx205022 	NGE_PP_SPACE_NIC,
3395574Smx205022 	NGE_PP_SPACE_MII,
3405574Smx205022 	NGE_PP_SPACE_NGE,
3415574Smx205022 	NGE_PP_SPACE_TXDESC,
3425574Smx205022 	NGE_PP_SPACE_TXBUFF,
3435574Smx205022 	NGE_PP_SPACE_RXDESC,
3445574Smx205022 	NGE_PP_SPACE_RXBUFF,
3455574Smx205022 	NGE_PP_SPACE_STATISTICS,
3465574Smx205022 	NGE_PP_SPACE_SEEPROM,
3475574Smx205022 	NGE_PP_SPACE_FLASH
3485574Smx205022 };
3495574Smx205022 
3505574Smx205022 /*
3515574Smx205022  * Flag to kstat type
3525574Smx205022  */
3535574Smx205022 enum nge_kstat_type {
3545574Smx205022 	NGE_KSTAT_RAW = 0,
3555574Smx205022 	NGE_KSTAT_STATS,
3565574Smx205022 	NGE_KSTAT_CHIPID,
3575574Smx205022 	NGE_KSTAT_DEBUG,
3585574Smx205022 	NGE_KSTAT_COUNT
3595574Smx205022 };
3605574Smx205022 
3615574Smx205022 
3625574Smx205022 /*
3635574Smx205022  * Actual state of the nvidia's chip
3645574Smx205022  */
3655574Smx205022 enum nge_chip_state {
3665574Smx205022 	NGE_CHIP_FAULT = -2,		/* fault, need reset	*/
3675574Smx205022 	NGE_CHIP_ERROR,			/* error, want reset	*/
3685574Smx205022 	NGE_CHIP_INITIAL,		/* Initial state only	*/
3695574Smx205022 	NGE_CHIP_RESET,			/* reset, need init	*/
3705574Smx205022 	NGE_CHIP_STOPPED,		/* Tx/Rx stopped	*/
3715574Smx205022 	NGE_CHIP_RUNNING		/* with interrupts	*/
3725574Smx205022 };
3735574Smx205022 
3745574Smx205022 enum nge_eeprom_size {
3755574Smx205022 	EEPROM_1K = 0,
3765574Smx205022 	EEPROM_2K,
3775574Smx205022 	EEPROM_4K,
3785574Smx205022 	EEPROM_8K,
3795574Smx205022 	EEPROM_16K,
3805574Smx205022 	EEPROM_32K,
3815574Smx205022 	EEPROM_64K
3825574Smx205022 };
3835574Smx205022 
3845574Smx205022 enum nge_eeprom_access_wid {
3855574Smx205022 	ACCESS_8BIT = 0,
3865574Smx205022 	ACCESS_16BIT
3875574Smx205022 };
3885574Smx205022 
3895574Smx205022 /*
3905574Smx205022  * MDIO operation
3915574Smx205022  */
3925574Smx205022 enum nge_mdio_operation {
3935574Smx205022 	NGE_MDIO_READ = 0,
3945574Smx205022 	NGE_MDIO_WRITE
3955574Smx205022 };
3965574Smx205022 
3975574Smx205022 /*
3985574Smx205022  * Speed selection
3995574Smx205022  */
4005574Smx205022 enum nge_speed {
4015574Smx205022 	UNKOWN_SPEED = 0,
4025574Smx205022 	NGE_10M,
4035574Smx205022 	NGE_100M,
4045574Smx205022 	NGE_1000M
4055574Smx205022 };
4065574Smx205022 
4075574Smx205022 /*
4085574Smx205022  * Duplex selection
4095574Smx205022  */
4105574Smx205022 enum nge_duplex {
4115574Smx205022 	UNKOWN_DUPLEX = 0,
4125574Smx205022 	NGE_HD,
4135574Smx205022 	NGE_FD
4145574Smx205022 };
4155574Smx205022 
4165574Smx205022 typedef struct {
4175574Smx205022 	ether_addr_t		addr;		/* in canonical form	*/
4185574Smx205022 	uint8_t			spare;
4195574Smx205022 	uint8_t			set;		/* nonzero => valid	*/
4205574Smx205022 } nge_mac_addr_t;
4215574Smx205022 
4225574Smx205022 struct nge;
4235574Smx205022 
4245574Smx205022 /*
4255574Smx205022  * Named Data (ND) Parameter Management Structure
4265574Smx205022  */
4275574Smx205022 typedef struct {
4285574Smx205022 	int			ndp_info;
4295574Smx205022 	int			ndp_min;
4305574Smx205022 	int			ndp_max;
4315574Smx205022 	int			ndp_val;
4325574Smx205022 	char			*ndp_name;
4335574Smx205022 } nd_param_t;
4345574Smx205022 
4355574Smx205022 
4365574Smx205022 #define	CHIP_FLAG_COPPER	0x40
4375574Smx205022 
4385574Smx205022 /*
4395574Smx205022  * Collection of physical-layer functions to:
4405574Smx205022  *	(re)initialise the physical layer
4415574Smx205022  *	update it to match software settings
4425574Smx205022  *	check for link status change
4435574Smx205022  */
4445574Smx205022 typedef struct {
4455574Smx205022 	void		(*phys_restart)(struct nge *);
4465574Smx205022 	void		(*phys_update)(struct nge *);
4475574Smx205022 	boolean_t	(*phys_check)(struct nge *);
4485574Smx205022 } phys_ops_t;
4495574Smx205022 
4505574Smx205022 struct nge_see_rw {
4515574Smx205022 	uint32_t	see_addr;	/* Byte offset within SEEPROM	*/
4525574Smx205022 	uint32_t	see_data;	/* Data read/data to write	*/
4535574Smx205022 };
4545574Smx205022 
4555574Smx205022 typedef struct {
4565574Smx205022 	uint64_t	pp_acc_size;	/* in bytes: 1,2,4,8	*/
4575574Smx205022 	uint64_t	pp_acc_space;	/* See #defines below	*/
4585574Smx205022 	uint64_t	pp_acc_offset;
4595574Smx205022 	uint64_t	pp_acc_data;	/* output for peek	*/
4605574Smx205022 					/* input for poke	*/
4615574Smx205022 } nge_peekpoke_t;
4625574Smx205022 
4635574Smx205022 typedef uintptr_t 	nge_regno_t;	/* register # (offset)	*/
4645574Smx205022 
4655574Smx205022 typedef struct _mul_list {
4665574Smx205022 	struct _mul_list *next;
4675574Smx205022 	uint32_t ref_cnt;
4685574Smx205022 	ether_addr_t mul_addr;
4695574Smx205022 }mul_item, *pmul_item;
4705574Smx205022 
4715574Smx205022 /*
4725574Smx205022  * Describes one chunk of allocated DMA-able memory
4735574Smx205022  *
4745574Smx205022  * In some cases, this is a single chunk as allocated from the system;
4755574Smx205022  * but we also use this structure to represent slices carved off such
4765574Smx205022  * a chunk.  Even when we don't really need all the information, we
4775574Smx205022  * use this structure as a convenient way of correlating the various
4785574Smx205022  * ways of looking at a piece of memory (kernel VA, IO space DVMA,
4795574Smx205022  * handle+offset, etc).
4805574Smx205022  */
4815574Smx205022 typedef struct dma_area
4825574Smx205022 {
4835574Smx205022 
4845574Smx205022 	caddr_t			private;	/* pointer to nge */
4855574Smx205022 	frtn_t			rx_recycle;	/* recycle function */
4865574Smx205022 	mblk_t			*mp;
4875574Smx205022 	ddi_acc_handle_t	acc_hdl;	/* handle for memory	*/
4885574Smx205022 	void			*mem_va;	/* CPU VA of memory	*/
4895574Smx205022 	uint32_t		nslots;		/* number of slots	*/
4905574Smx205022 	uint32_t		size;		/* size per slot	*/
4915574Smx205022 	size_t			alength;	/* allocated size	*/
4925574Smx205022 						/* >= product of above	*/
4935574Smx205022 	ddi_dma_handle_t	dma_hdl;	/* DMA handle		*/
4945574Smx205022 	offset_t		offset;		/* relative to handle	*/
4955574Smx205022 	ddi_dma_cookie_t	cookie;		/* associated cookie	*/
4965574Smx205022 	uint32_t		ncookies;
4975574Smx205022 	uint32_t		signature;	/* buffer signature	*/
4985574Smx205022 						/* for deciding to free */
4995574Smx205022 						/* or to reuse buffers	*/
5005574Smx205022 	boolean_t		rx_delivered;	/* hold by upper layer	*/
5015574Smx205022 	struct dma_area		*next;
5025574Smx205022 } dma_area_t;
5035574Smx205022 
5045574Smx205022 #define	HOST_OWN	0x00000000
5055574Smx205022 #define	CONTROLER_OWN	0x00000001
5065574Smx205022 #define	NGE_END_PACKET	0x00000002
5075574Smx205022 
5085574Smx205022 
5095574Smx205022 typedef struct nge_dmah_node
5105574Smx205022 {
5115574Smx205022 	struct nge_dmah_node	*next;
5125574Smx205022 	ddi_dma_handle_t	hndl;
5135574Smx205022 } nge_dmah_node_t;
5145574Smx205022 
5155574Smx205022 typedef struct nge_dmah_list
5165574Smx205022 {
5175574Smx205022 	nge_dmah_node_t	*head;
5185574Smx205022 	nge_dmah_node_t	*tail;
5195574Smx205022 } nge_dmah_list_t;
5205574Smx205022 
5215574Smx205022 /*
5225574Smx205022  * Software version of the Recv Descriptor
5235574Smx205022  * There's one of these for each recv buffer (up to 512 per ring)
5245574Smx205022  */
5255574Smx205022 typedef struct sw_rx_sbd {
5265574Smx205022 
5275574Smx205022 	dma_area_t		desc;		/* (const) related h/w	*/
5285574Smx205022 						/* descriptor area	*/
5295574Smx205022 	dma_area_t		*bufp;		/* (const) related	*/
5305574Smx205022 						/* buffer area		*/
5315574Smx205022 	uint8_t			flags;
5325574Smx205022 } sw_rx_sbd_t;
5335574Smx205022 
5345574Smx205022 /*
5355574Smx205022  * Software version of the send Buffer Descriptor
5365574Smx205022  * There's one of these for each send buffer (up to 512 per ring)
5375574Smx205022  */
5385574Smx205022 typedef struct sw_tx_sbd {
5395574Smx205022 
5405574Smx205022 	dma_area_t		desc;		/* (const) related h/w	*/
5415574Smx205022 						/* descriptor area	*/
5425574Smx205022 	dma_area_t		pbuf;		/* (const) related	*/
5435574Smx205022 						/* buffer area		*/
5445574Smx205022 	void			(*tx_recycle)(struct sw_tx_sbd *);
5455574Smx205022 	uint32_t		flags;
5465574Smx205022 	mblk_t			*mp;		/* related mblk, if any	*/
5475574Smx205022 	nge_dmah_list_t		mp_hndl;
5485574Smx205022 	uint32_t		frags;
5495574Smx205022 	uint32_t		ncookies;	/* dma cookie number */
5505574Smx205022 
5515574Smx205022 } sw_tx_sbd_t;
5525574Smx205022 
5535574Smx205022 /*
5545574Smx205022  * Software Receive Buffer (Producer) Ring Control Block
5555574Smx205022  * There's one of these for each receiver producer ring (up to 3),
5565574Smx205022  * but each holds buffers of a different size.
5575574Smx205022  */
5585574Smx205022 typedef struct buff_ring {
5595574Smx205022 
5605574Smx205022 	uint64_t		nslots;		/* descriptor area	*/
5615574Smx205022 	struct nge		*ngep;		/* (const) containing	*/
5625574Smx205022 						/* driver soft state	*/
5635574Smx205022 						/* initialise same	*/
5645574Smx205022 	uint64_t		rx_hold;
5655574Smx205022 	sw_rx_sbd_t		*sw_rbds; 	/* software descriptors	*/
5665574Smx205022 	sw_rx_sbd_t		*free_rbds;	/* free ring */
5675574Smx205022 	dma_area_t		*free_list;	/* available buffer queue */
5685574Smx205022 	dma_area_t		*recycle_list;	/* recycling buffer queue */
5695574Smx205022 	kmutex_t		recycle_lock[1];
5705574Smx205022 	uint32_t		buf_sign;
5715574Smx205022 	boolean_t		rx_bcopy;
5725574Smx205022 } buff_ring_t;
5735574Smx205022 
5745574Smx205022 /*
5755574Smx205022  * Software Receive (Return) Ring Control Block
5765574Smx205022  * There's one of these for each receiver return ring (up to 16).
5775574Smx205022  */
5785574Smx205022 typedef struct recv_ring {
5795574Smx205022 	/*
5805574Smx205022 	 * The elements flagged (const) in the comments below are
5815574Smx205022 	 * set up once during initialiation and thereafter unchanged.
5825574Smx205022 	 */
5835574Smx205022 	dma_area_t		desc;		/* (const) related h/w	*/
5845574Smx205022 						/* descriptor area	*/
5855574Smx205022 	struct nge		*ngep;		/* (const) containing	*/
5865574Smx205022 						/* driver soft state	*/
5875574Smx205022 	uint16_t		prod_index;	/* (const) ptr to h/w	*/
5885574Smx205022 						/* "producer index"	*/
5895574Smx205022 	mac_resource_handle_t	handle;
5905574Smx205022 } recv_ring_t;
5915574Smx205022 
5925574Smx205022 
5935574Smx205022 
5945574Smx205022 /*
5955574Smx205022  * Software Send Ring Control Block
5965574Smx205022  * There's one of these for each of (up to) 1 send rings
5975574Smx205022  */
5985574Smx205022 typedef struct send_ring {
5995574Smx205022 	/*
6005574Smx205022 	 * The elements flagged (const) in the comments below are
6015574Smx205022 	 * set up once during initialiation and thereafter unchanged.
6025574Smx205022 	 */
6035574Smx205022 	dma_area_t		desc;		/* (const) related h/w	*/
6045574Smx205022 						/* descriptor area	*/
6055574Smx205022 	dma_area_t		buf[NGE_SEND_SLOTS_BUF];
6065574Smx205022 						/* buffer area(s)	*/
6075574Smx205022 	struct nge		*ngep;		/* (const) containing	*/
6085574Smx205022 						/* driver soft state	*/
6095574Smx205022 
6105574Smx205022 	uint64_t		tx_hwmark;
6115574Smx205022 	uint64_t		tx_lwmark;
6125574Smx205022 
6135574Smx205022 	/*
6145574Smx205022 	 * The tx_lock must be held when updating
6155574Smx205022 	 * the s/w producer index
6165574Smx205022 	 * (tx_next)
6175574Smx205022 	 */
6185574Smx205022 	kmutex_t		tx_lock[1];	/* serialize h/w update	*/
6195574Smx205022 	uint64_t		tx_next;	/* next slot to use	*/
6205574Smx205022 	uint64_t		tx_flow;
6215574Smx205022 
6225574Smx205022 	/*
6235574Smx205022 	 * These counters/indexes are manipulated in the transmit
6245574Smx205022 	 * path using atomics rather than mutexes for speed
6255574Smx205022 	 */
6265574Smx205022 	uint64_t		tx_free;	/* # of slots available	*/
6275574Smx205022 
6285574Smx205022 	/*
6295574Smx205022 	 * index (tc_next).
6305574Smx205022 	 */
6315574Smx205022 	kmutex_t		tc_lock[1];
6325574Smx205022 	uint64_t		tc_next;	/* next slot to recycle	*/
6335574Smx205022 						/* ("consumer index")	*/
6345574Smx205022 
6355574Smx205022 	sw_tx_sbd_t		*sw_sbds; 	/* software descriptors	*/
6365574Smx205022 
6375574Smx205022 	kmutex_t		dmah_lock;
6385574Smx205022 	nge_dmah_list_t		dmah_free;
6395574Smx205022 	nge_dmah_node_t		dmahndl[NGE_MAX_DMA_HDR];
6405574Smx205022 
6415574Smx205022 } send_ring_t;
6425574Smx205022 
6435574Smx205022 
6445574Smx205022 typedef struct {
6455574Smx205022 	uint32_t		businfo;	/* from private reg	*/
6465574Smx205022 	uint16_t		command;	/* saved during attach	*/
6475574Smx205022 
6485574Smx205022 	uint16_t		vendor;		/* vendor-id		*/
6495574Smx205022 	uint16_t		device;		/* device-id		*/
6505574Smx205022 	uint16_t		subven;		/* subsystem-vendor-id	*/
6515574Smx205022 	uint16_t		subdev;		/* subsystem-id		*/
6525574Smx205022 	uint8_t			class_code;
6535574Smx205022 	uint8_t			revision;	/* revision-id		*/
6545574Smx205022 	uint8_t			clsize;		/* cache-line-size	*/
6555574Smx205022 	uint8_t			latency;	/* latency-timer	*/
6565574Smx205022 	uint8_t			flags;
6575574Smx205022 
6585574Smx205022 	uint16_t		phy_type;	/* Fiber module type 	*/
6595574Smx205022 	uint64_t		hw_mac_addr;	/* from chip register	*/
6605574Smx205022 	nge_mac_addr_t		vendor_addr;	/* transform of same	*/
6615574Smx205022 } chip_info_t;
6625574Smx205022 
6635574Smx205022 
6645574Smx205022 typedef struct {
6655574Smx205022 	offset_t	index;
6665574Smx205022 	char		*name;
6675574Smx205022 } nge_ksindex_t;
6685574Smx205022 
6695574Smx205022 typedef struct {
6705574Smx205022 	uint64_t tso_err_mss;
6715574Smx205022 	uint64_t tso_dis;
6725574Smx205022 	uint64_t tso_err_nosum;
6735574Smx205022 	uint64_t tso_err_hov;
6745574Smx205022 	uint64_t tso_err_huf;
6755574Smx205022 	uint64_t tso_err_l2;
6765574Smx205022 	uint64_t tso_err_ip;
6775574Smx205022 	uint64_t tso_err_l4;
6785574Smx205022 	uint64_t tso_err_tcp;
6795574Smx205022 	uint64_t hsum_err_ip;
6805574Smx205022 	uint64_t hsum_err_l4;
6815574Smx205022 }fe_statistics_t;
6825574Smx205022 
6835574Smx205022 /*
6845574Smx205022  * statistics parameters to tune the driver
6855574Smx205022  */
6865574Smx205022 typedef struct {
6875574Smx205022 	uint64_t		intr_count;
6885574Smx205022 	uint64_t		intr_lval;
6895574Smx205022 	uint64_t		recv_realloc;
6905574Smx205022 	uint64_t		poll_time;
6915574Smx205022 	uint64_t		recy_free;
6925574Smx205022 	uint64_t		recv_count;
6935574Smx205022 	uint64_t		xmit_count;
6945574Smx205022 	uint64_t		obytes;
6955574Smx205022 	uint64_t		rbytes;
6965574Smx205022 	uint64_t		mp_alloc_err;
6975574Smx205022 	uint64_t		dma_alloc_err;
6985574Smx205022 	uint64_t		kmem_alloc_err;
6995574Smx205022 	uint64_t		load_context;
7005574Smx205022 	uint64_t		ip_hwsum_err;
7015574Smx205022 	uint64_t		tcp_hwsum_err;
7025574Smx205022 	uint64_t		rx_nobuffer;
7035574Smx205022 	uint64_t		rx_err;
7045574Smx205022 	uint64_t		tx_stop_err;
7055574Smx205022 	uint64_t		tx_stall;
7065574Smx205022 	uint64_t		tx_rsrv_fail;
7075574Smx205022 	uint64_t		tx_resched;
7085574Smx205022 	fe_statistics_t	fe_err;
7095574Smx205022 }nge_sw_statistics_t;
7105574Smx205022 
7115574Smx205022 typedef struct {
7125574Smx205022 	nge_hw_statistics_t	hw_statistics;
7135574Smx205022 	nge_sw_statistics_t	sw_statistics;
7145574Smx205022 }nge_statistics_t;
7155574Smx205022 
7165574Smx205022 struct nge_desc_attr	{
7175574Smx205022 
7185574Smx205022 	size_t	rxd_size;
7195574Smx205022 	size_t	txd_size;
7205574Smx205022 
7215574Smx205022 	ddi_dma_attr_t	*dma_attr;
7225574Smx205022 	ddi_dma_attr_t	*tx_dma_attr;
7235574Smx205022 
7245574Smx205022 	void (*rxd_fill)(void *, const ddi_dma_cookie_t *, size_t);
7255574Smx205022 	uint32_t (*rxd_check)(const void *, size_t *);
7265574Smx205022 
7275574Smx205022 	void (*txd_fill)(void *, const ddi_dma_cookie_t *, size_t,
7285574Smx205022 			uint32_t, boolean_t);
7295574Smx205022 
7305574Smx205022 	uint32_t (*txd_check)(const void *, size_t *);
7315574Smx205022 };
7325574Smx205022 
7335574Smx205022 typedef struct nge_desc_attr nge_desc_attr_t;
7345574Smx205022 
7355574Smx205022 /*
7365574Smx205022  * Structure used to hold the device-specific config parameters.
7375574Smx205022  * The setting of such parameters may not consistent with the
7385574Smx205022  * hardware feature of the device. It's used for software purpose.
7395574Smx205022  */
7405574Smx205022 typedef struct nge_dev_spec_param {
7415574Smx205022 	boolean_t	msi;		/* specifies msi support */
7425574Smx205022 	boolean_t	msi_x;		/* specifies msi_x support */
7435574Smx205022 	boolean_t	vlan;		/* specifies vlan support */
7445574Smx205022 	boolean_t	tx_pause_frame;	/* specifies tx pause frame support */
7455574Smx205022 	boolean_t	rx_pause_frame;	/* specifies rx pause frame support */
7465574Smx205022 	boolean_t	jumbo;		/* jumbo frame support */
7475574Smx205022 	boolean_t	tx_rx_64byte;	/* set the max tx/rx prd fetch size */
7485574Smx205022 	boolean_t	rx_hw_checksum;	/* specifies tx hw checksum feature */
7495574Smx205022 	uint32_t	tx_hw_checksum;	/* specifies rx hw checksum feature */
7505574Smx205022 	uint32_t	desc_type;	/* specifies descriptor type */
7515574Smx205022 	uint32_t	rx_desc_num;	/* specifies rx descriptor number */
7525574Smx205022 	uint32_t	tx_desc_num;	/* specifies tx descriptor number */
7535574Smx205022 	uint32_t	nge_split;	/* specifies the split number */
7545574Smx205022 } nge_dev_spec_param_t;
7555574Smx205022 
7565574Smx205022 typedef struct nge {
7575574Smx205022 	/*
7585574Smx205022 	 * These fields are set by attach() and unchanged thereafter ...
7595574Smx205022 	 */
7605574Smx205022 	dev_info_t		*devinfo;	/* device instance	*/
7615574Smx205022 	mac_handle_t		mh;		/* mac module handle    */
7625574Smx205022 	chip_info_t		chipinfo;
7635574Smx205022 	ddi_acc_handle_t	cfg_handle;	/* DDI I/O handle	*/
7645574Smx205022 	ddi_acc_handle_t	io_handle;	/* DDI I/O handle	*/
7655574Smx205022 	void			*io_regs;	/* mapped registers	*/
7665574Smx205022 
7675574Smx205022 	ddi_periodic_t		periodic_id;	/* periodical callback	*/
7685574Smx205022 	uint32_t		factotum_flag;
7695574Smx205022 	ddi_softint_handle_t	factotum_hdl;	/* factotum callback	*/
7705574Smx205022 	ddi_softint_handle_t	resched_hdl;	/* reschedule callback	*/
7715574Smx205022 	uint_t			soft_pri;
7725574Smx205022 
7735574Smx205022 	ddi_intr_handle_t 	*htable;	/* for array of interrupts */
7745574Smx205022 	int			intr_type;	/* type of interrupt */
7755574Smx205022 	int			intr_actual_cnt; /* alloc intrs count */
7765574Smx205022 	int			intr_req_cnt;	/* request intrs count */
7775574Smx205022 	uint_t			intr_pri;	/* interrupt priority	*/
7785574Smx205022 	int			intr_cap;	/* interrupt capabilities */
7795574Smx205022 
7805574Smx205022 	uint32_t		progress;	/* attach tracking	*/
7815574Smx205022 	uint32_t		debug;		/* flag to debug function */
7825574Smx205022 
7835574Smx205022 	char			ifname[8];	/* "nge0" ... "nge999" */
7845574Smx205022 
7855574Smx205022 
7865574Smx205022 	enum nge_mac_state	nge_mac_state;	/* definitions above	*/
7875574Smx205022 	enum nge_chip_state	nge_chip_state; /* definitions above	*/
7885574Smx205022 	boolean_t		promisc;
7895574Smx205022 	boolean_t		suspended;
7905574Smx205022 
7915574Smx205022 	int			resched_needed;
7925574Smx205022 	uint32_t		default_mtu;
7935574Smx205022 	uint32_t		max_sdu;
7945574Smx205022 	uint32_t		buf_size;
7955574Smx205022 	uint32_t		rx_desc;
7965574Smx205022 	uint32_t		tx_desc;
7975574Smx205022 	uint32_t		rx_buf;
7985574Smx205022 	uint32_t		nge_split;
7995574Smx205022 	uint32_t		watchdog;
8005574Smx205022 	uint32_t		lowmem_mode;
8015574Smx205022 
8025574Smx205022 
8035574Smx205022 	/*
8045574Smx205022 	 * Runtime read-write data starts here ...
8055574Smx205022 	 * 1 Receive Rings
8065574Smx205022 	 * 1 Send Rings
8075574Smx205022 	 *
8085574Smx205022 	 * Note: they're not necessarily all used.
8095574Smx205022 	 */
8105574Smx205022 	struct buff_ring	buff[1];
8115574Smx205022 	struct recv_ring	recv[1];
8125574Smx205022 	struct send_ring	send[1];
8135574Smx205022 
8145574Smx205022 
8155574Smx205022 	kmutex_t		genlock[1];
8165574Smx205022 	krwlock_t		rwlock[1];
8175574Smx205022 	kmutex_t		softlock[1];
8185574Smx205022 	uint32_t		intr_masks;
8195574Smx205022 	boolean_t		poll;
8205574Smx205022 	boolean_t		ch_intr_mode;
8215574Smx205022 	uint32_t		recv_count;
8225574Smx205022 	uint32_t		poll_time;
8235574Smx205022 	uint32_t		sw_intr_intv;
8245574Smx205022 	nge_mac_addr_t		cur_uni_addr;
8255574Smx205022 	uint32_t		rx_datahwm;
8265574Smx205022 	uint32_t		rx_prdlwm;
8275574Smx205022 	uint32_t		rx_prdhwm;
8285574Smx205022 	uint32_t		rx_def;
8295574Smx205022 	uint32_t		desc_mode;
8305574Smx205022 
8315574Smx205022 	mul_item		*pcur_mulist;
8325574Smx205022 	nge_mac_addr_t		cur_mul_addr;
8335574Smx205022 	nge_mac_addr_t		cur_mul_mask;
8345574Smx205022 
8355574Smx205022 	nge_desc_attr_t		desc_attr;
8365574Smx205022 
8375574Smx205022 	/*
8385574Smx205022 	 * Link state data (protected by genlock)
8395574Smx205022 	 */
8405574Smx205022 	int32_t			link_state;	/* See GLD #defines	*/
8415574Smx205022 	uint32_t		stall_cknum;	/* Stall check number */
8425574Smx205022 
8435574Smx205022 	uint32_t		phy_xmii_addr;
8445574Smx205022 	uint32_t		phy_id;
8455574Smx205022 	uint32_t		phy_mode;
8465574Smx205022 	const phys_ops_t	*physops;
8475574Smx205022 	uint16_t		phy_gen_status;
8485574Smx205022 
8495574Smx205022 	uint32_t		param_loop_mode;
8505574Smx205022 
8515574Smx205022 	/*
8525574Smx205022 	 * NDD parameters (protected by genlock)
8535574Smx205022 	 */
8545574Smx205022 	caddr_t			nd_data_p;
8555574Smx205022 	nd_param_t		nd_params[PARAM_COUNT];
8565574Smx205022 
8575574Smx205022 	kstat_t			*nge_kstats[NGE_KSTAT_COUNT];
8585574Smx205022 	nge_statistics_t	statistics;
8595574Smx205022 
8605574Smx205022 	nge_dev_spec_param_t	dev_spec_param;
8615574Smx205022 
8625574Smx205022 } nge_t;
8635574Smx205022 
8645574Smx205022 extern const nge_ksindex_t nge_statistics[];
8655574Smx205022 
8665574Smx205022 /*
8675574Smx205022  * Shorthand for the NDD parameters
8685574Smx205022  */
8695574Smx205022 #define	param_adv_autoneg	nd_params[PARAM_ADV_AUTONEG_CAP].ndp_val
8705574Smx205022 #define	param_adv_pause		nd_params[PARAM_ADV_PAUSE_CAP].ndp_val
8715574Smx205022 #define	param_adv_asym_pause	nd_params[PARAM_ADV_ASYM_PAUSE_CAP].ndp_val
8725574Smx205022 #define	param_adv_1000fdx	nd_params[PARAM_ADV_1000FDX_CAP].ndp_val
8735574Smx205022 #define	param_adv_1000hdx	nd_params[PARAM_ADV_1000HDX_CAP].ndp_val
8745574Smx205022 #define	param_adv_100fdx	nd_params[PARAM_ADV_100FDX_CAP].ndp_val
8755574Smx205022 #define	param_adv_100hdx	nd_params[PARAM_ADV_100HDX_CAP].ndp_val
8765574Smx205022 #define	param_adv_10fdx		nd_params[PARAM_ADV_10FDX_CAP].ndp_val
8775574Smx205022 #define	param_adv_10hdx		nd_params[PARAM_ADV_10HDX_CAP].ndp_val
8785574Smx205022 
8795574Smx205022 #define	param_lp_autoneg	nd_params[PARAM_LP_AUTONEG_CAP].ndp_val
8805574Smx205022 #define	param_lp_pause		nd_params[PARAM_LP_PAUSE_CAP].ndp_val
8815574Smx205022 #define	param_lp_asym_pause	nd_params[PARAM_LP_ASYM_PAUSE_CAP].ndp_val
8825574Smx205022 #define	param_lp_1000fdx	nd_params[PARAM_LP_1000FDX_CAP].ndp_val
8835574Smx205022 #define	param_lp_1000hdx	nd_params[PARAM_LP_1000HDX_CAP].ndp_val
8845574Smx205022 #define	param_lp_100fdx		nd_params[PARAM_LP_100FDX_CAP].ndp_val
8855574Smx205022 #define	param_lp_100hdx		nd_params[PARAM_LP_100HDX_CAP].ndp_val
8865574Smx205022 #define	param_lp_10fdx		nd_params[PARAM_LP_10FDX_CAP].ndp_val
8875574Smx205022 #define	param_lp_10hdx		nd_params[PARAM_LP_10HDX_CAP].ndp_val
8885574Smx205022 
8895574Smx205022 #define	param_link_up		nd_params[PARAM_LINK_STATUS].ndp_val
8905574Smx205022 #define	param_link_speed	nd_params[PARAM_LINK_SPEED].ndp_val
8915574Smx205022 #define	param_link_duplex	nd_params[PARAM_LINK_DUPLEX].ndp_val
8925574Smx205022 
8935574Smx205022 #define	param_link_autoneg	nd_params[PARAM_LINK_AUTONEG].ndp_val
8945574Smx205022 #define	param_link_rx_pause	nd_params[PARAM_LINK_RX_PAUSE].ndp_val
8955574Smx205022 #define	param_link_tx_pause	nd_params[PARAM_LINK_TX_PAUSE].ndp_val
8965574Smx205022 
8975574Smx205022 #define	param_loop_mode		nd_params[PARAM_LOOP_MODE].ndp_val
8985574Smx205022 
8995574Smx205022 #define	param_txbcopy_threshold	nd_params[PARAM_TXBCOPY_THRESHOLD].ndp_val
9005574Smx205022 #define	param_rxbcopy_threshold	nd_params[PARAM_RXBCOPY_THRESHOLD].ndp_val
9015574Smx205022 #define	param_recv_max_packet	nd_params[PARAM_RECV_MAX_PACKET].ndp_val
9025574Smx205022 
9035574Smx205022 /*
9045574Smx205022  * Sync a DMA area described by a dma_area_t
9055574Smx205022  */
9065574Smx205022 #define	DMA_SYNC(area, flag)	((void) ddi_dma_sync((area).dma_hdl,	\
9075574Smx205022 				    (area).offset, (area).alength, (flag)))
9085574Smx205022 
9095574Smx205022 /*
9105574Smx205022  * Find the (kernel virtual) address of block of memory
9115574Smx205022  * described by a dma_area_t
9125574Smx205022  */
9135574Smx205022 #define	DMA_VPTR(area)		((area).mem_va)
9145574Smx205022 
9155574Smx205022 /*
9165574Smx205022  * Zero a block of memory described by a dma_area_t
9175574Smx205022  */
9185574Smx205022 #define	DMA_ZERO(area)		bzero(DMA_VPTR(area), (area).alength)
9195574Smx205022 
9205574Smx205022 /*
9215574Smx205022  * Next/Prev value of a cyclic index
9225574Smx205022  */
9235574Smx205022 #define	NEXT(index, limit)	((index) + 1 < (limit) ? (index) + 1 : 0)
9245574Smx205022 #define	PREV(index, limit)	(0 == (index) ? (limit - 1) : (index) - 1)
9255574Smx205022 
9265574Smx205022 #define	NEXT_INDEX(ndx, num, lim)\
9275574Smx205022 	(((ndx) + (num) < (lim)) ? ((ndx) + (num)) : ((ndx) + (num) - (lim)))
9285574Smx205022 
9295574Smx205022 
9305574Smx205022 /*
9315574Smx205022  * Property lookups
9325574Smx205022  */
9335574Smx205022 #define	NGE_PROP_EXISTS(d, n)	ddi_prop_exists(DDI_DEV_T_ANY, (d),	\
9345574Smx205022 					DDI_PROP_DONTPASS, (n))
9355574Smx205022 #define	NGE_PROP_GET_INT(d, n)	ddi_prop_get_int(DDI_DEV_T_ANY, (d),	\
9365574Smx205022 					DDI_PROP_DONTPASS, (n), -1)
9375574Smx205022 
9385574Smx205022 
9395574Smx205022 /*
9405574Smx205022  * Debugging ...
9415574Smx205022  */
9425574Smx205022 #ifdef	DEBUG
9435574Smx205022 #define	NGE_DEBUGGING		1
9445574Smx205022 #else
9455574Smx205022 #define	NGE_DEBUGGING		0
9465574Smx205022 #endif	/* DEBUG */
9475574Smx205022 
9485574Smx205022 /*
9495574Smx205022  * Bit flags in the 'debug' word ...
9505574Smx205022  */
9515574Smx205022 #define	NGE_DBG_STOP		0x00000001	/* early debug_enter()	*/
9525574Smx205022 #define	NGE_DBG_TRACE		0x00000002	/* general flow tracing	*/
9535574Smx205022 
9545574Smx205022 #define	NGE_DBG_MII		0x00000010	/* low-level MII access	*/
9555574Smx205022 #define	NGE_DBG_CHIP		0x00000020	/* low(ish)-level code	*/
9565574Smx205022 
9575574Smx205022 #define	NGE_DBG_RECV		0x00000100	/* receive-side code	*/
9585574Smx205022 #define	NGE_DBG_SEND		0x00000200	/* packet-send code	*/
9595574Smx205022 
9605574Smx205022 #define	NGE_DBG_INIT		0x00100000	/* initialisation	*/
9615574Smx205022 #define	NGE_DBG_NEMO		0x00200000	/* MAC layer entry points */
9625574Smx205022 #define	NGE_DBG_STATS		0x00400000	/* statistics		*/
9635574Smx205022 
9645574Smx205022 #define	NGE_DBG_BADIOC		0x01000000	/* unknown ioctls	*/
9655574Smx205022 
9665574Smx205022 #define	NGE_DBG_NDD		0x10000000	/* NDD operations	*/
9675574Smx205022 
9685574Smx205022 
9695574Smx205022 
9705574Smx205022 /*
9715574Smx205022  * 'Do-if-debugging' macro.  The parameter <command> should be one or more
9725574Smx205022  * C statements (but without the *final* semicolon), which will either be
9735574Smx205022  * compiled inline or completely ignored, depending on the NGE_DEBUGGING
9745574Smx205022  * compile-time flag.
9755574Smx205022  *
9765574Smx205022  * You should get a compile-time error (at least on a DEBUG build) if
9775574Smx205022  * your statement isn't actually a statement, rather than unexpected
9785574Smx205022  * run-time behaviour caused by unintended matching of if-then-elses etc.
9795574Smx205022  *
9805574Smx205022  * Note that the NGE_DDB() macro itself can only be used as a statement,
9815574Smx205022  * not an expression, and should always be followed by a semicolon.
9825574Smx205022  */
9835574Smx205022 #if NGE_DEBUGGING
9845574Smx205022 #define	NGE_DDB(command)	do {					\
9855574Smx205022 					{ command; }			\
9865574Smx205022 					_NOTE(CONSTANTCONDITION)	\
9875574Smx205022 				} while (0)
9885574Smx205022 #else 	/* NGE_DEBUGGING */
9895574Smx205022 #define	NGE_DDB(command)
9905574Smx205022 /*
9915574Smx205022  * Old way of debugging.  This is a poor way, as it leeaves empty
9925574Smx205022  * statements that cause lint to croak.
9935574Smx205022  * #define	NGE_DDB(command)	do {				\
9945574Smx205022  * 					{ _NOTE(EMPTY); }		\
9955574Smx205022  * 					_NOTE(CONSTANTCONDITION)	\
9965574Smx205022  * 				} while (0)
9975574Smx205022  */
9985574Smx205022 #endif	/* NGE_DEBUGGING */
9995574Smx205022 
10005574Smx205022 /*
10015574Smx205022  * 'Internal' macros used to construct the TRACE/DEBUG macros below.
10025574Smx205022  * These provide the primitive conditional-call capability required.
10035574Smx205022  * Note: the parameter <args> is a parenthesised list of the actual
10045574Smx205022  * printf-style arguments to be passed to the debug function ...
10055574Smx205022  */
10065574Smx205022 #define	NGE_XDB(b, w, f, args)	NGE_DDB(if ((b) & (w)) f args)
10075574Smx205022 #define	NGE_GDB(b, args)	NGE_XDB(b, nge_debug, (*nge_gdb()), args)
10085574Smx205022 #define	NGE_LDB(b, args)	NGE_XDB(b, ngep->debug, \
10095574Smx205022 				    (*nge_db(ngep)), args)
10105574Smx205022 #define	NGE_CDB(f, args)	NGE_XDB(NGE_DBG, ngep->debug, f, args)
10115574Smx205022 
10125574Smx205022 /*
10135574Smx205022  * Conditional-print macros.
10145574Smx205022  *
10155574Smx205022  * Define NGE_DBG to be the relevant member of the set of NGE_DBG_* values
10165574Smx205022  * above before using the NGE_GDEBUG() or NGE_DEBUG() macros.  The 'G'
10175574Smx205022  * versions look at the Global debug flag word (nge_debug); the non-G
10185574Smx205022  * versions look in the per-instance data (ngep->debug) and so require a
10195574Smx205022  * variable called 'ngep' to be in scope (and initialised!) before use.
10205574Smx205022  *
10215574Smx205022  * You could redefine NGE_TRC too if you really need two different
10225574Smx205022  * flavours of debugging output in the same area of code, but I don't
10235574Smx205022  * really recommend it.
10245574Smx205022  *
10255574Smx205022  * Note: the parameter <args> is a parenthesised list of the actual
10265574Smx205022  * arguments to be passed to the debug function, usually a printf-style
10275574Smx205022  * format string and corresponding values to be formatted.
10285574Smx205022  */
10295574Smx205022 
10305574Smx205022 #define	NGE_TRC	NGE_DBG_TRACE
10315574Smx205022 
10325574Smx205022 #define	NGE_GTRACE(args)	NGE_GDB(NGE_TRC, args)
10335574Smx205022 #define	NGE_GDEBUG(args)	NGE_GDB(NGE_DBG, args)
10345574Smx205022 #define	NGE_TRACE(args)		NGE_LDB(NGE_TRC, args)
10355574Smx205022 #define	NGE_DEBUG(args)		NGE_LDB(NGE_DBG, args)
10365574Smx205022 
10375574Smx205022 /*
10385574Smx205022  * Debug-only action macros
10395574Smx205022  */
10405574Smx205022 
10415574Smx205022 
10425574Smx205022 #define	NGE_REPORT(args)	NGE_DDB(nge_log args)
10435574Smx205022 
10445574Smx205022 boolean_t nge_atomic_decrease(uint64_t *count_p, uint64_t n);
10455574Smx205022 void nge_atomic_increase(uint64_t *count_p, uint64_t n);
10465574Smx205022 
10475574Smx205022 int nge_alloc_dma_mem(nge_t *ngep, size_t memsize,
10485574Smx205022     ddi_device_acc_attr_t *attr_p, uint_t dma_flags, dma_area_t *dma_p);
10495574Smx205022 void nge_free_dma_mem(dma_area_t *dma_p);
10505574Smx205022 int nge_restart(nge_t *ngep);
10515574Smx205022 void nge_wake_factotum(nge_t *ngep);
10525574Smx205022 
10535574Smx205022 uint8_t nge_reg_get8(nge_t *ngep, nge_regno_t regno);
10545574Smx205022 void nge_reg_put8(nge_t *ngep, nge_regno_t regno, uint8_t data);
10555574Smx205022 uint16_t nge_reg_get16(nge_t *ngep, nge_regno_t regno);
10565574Smx205022 void nge_reg_put16(nge_t *ngep, nge_regno_t regno, uint16_t data);
10575574Smx205022 uint32_t nge_reg_get32(nge_t *ngep, nge_regno_t regno);
10585574Smx205022 void nge_reg_put32(nge_t *ngep, nge_regno_t regno, uint32_t data);
10595574Smx205022 uint_t nge_chip_factotum(caddr_t args1, caddr_t args2);
10605574Smx205022 void nge_chip_cfg_init(nge_t *ngep, chip_info_t *infop, boolean_t reset);
10615574Smx205022 void nge_init_dev_spec_param(nge_t *ngep);
10625574Smx205022 int nge_chip_stop(nge_t *ngep, boolean_t fault);
10635574Smx205022 void nge_restore_mac_addr(nge_t *ngep);
10645574Smx205022 int nge_chip_reset(nge_t *ngep);
10655574Smx205022 int nge_chip_start(nge_t *ngep);
10665574Smx205022 void nge_chip_sync(nge_t *ngep);
10675574Smx205022 
10685574Smx205022 uint_t nge_chip_intr(caddr_t arg1, caddr_t arg2);
10695574Smx205022 enum ioc_reply nge_chip_ioctl(nge_t *ngep, mblk_t *mp, struct iocblk *iocp);
10705574Smx205022 
10715574Smx205022 void nge_phys_init(nge_t *ngep);
10725574Smx205022 boolean_t nge_phy_reset(nge_t *ngep);
10735574Smx205022 uint16_t nge_mii_get16(nge_t *ngep, nge_regno_t regno);
10745574Smx205022 void nge_mii_put16(nge_t *ngep, nge_regno_t regno, uint16_t data);
10755574Smx205022 
10765574Smx205022 void nge_recv_recycle(caddr_t arg);
10775574Smx205022 void nge_receive(nge_t *ngep);
10785574Smx205022 
10795574Smx205022 uint_t nge_reschedule(caddr_t args1, caddr_t args2);
10805574Smx205022 mblk_t *nge_m_tx(void *arg, mblk_t *mp);
10815574Smx205022 
10825574Smx205022 void nge_tx_recycle(nge_t *ngep, boolean_t is_intr);
10835574Smx205022 void nge_tx_recycle_all(nge_t *ngep);
10845574Smx205022 
10855574Smx205022 enum ioc_reply nge_nd_ioctl(nge_t *ngep, queue_t *wq,
10865574Smx205022     mblk_t *mp, struct iocblk *iocp);
10875574Smx205022 int nge_nd_init(nge_t *ngep);
10885574Smx205022 void nge_nd_cleanup(nge_t *ngep);
10895574Smx205022 
10905574Smx205022 
10915574Smx205022 void nge_init_kstats(nge_t *ngep, int instance);
10925574Smx205022 void nge_fini_kstats(nge_t *ngep);
10935574Smx205022 int nge_m_stat(void *arg, uint_t stat, uint64_t *val);
10945574Smx205022 
10955574Smx205022 uint32_t nge_atomic_shl32(uint32_t *sp, uint_t count);
10965574Smx205022 
10975574Smx205022 void nge_log(nge_t *ngep, const char *fmt, ...);
10985574Smx205022 void nge_problem(nge_t *ngep, const char *fmt, ...);
10995574Smx205022 void nge_error(nge_t *ngep, const char *fmt, ...);
11005574Smx205022 void
11015574Smx205022 nge_report(nge_t *ngep, uint8_t error_id);
11025574Smx205022 
11035574Smx205022 void (*nge_db(nge_t *ngep))(const char *fmt, ...);
11045574Smx205022 void (*nge_gdb(void))(const char *fmt, ...);
11055574Smx205022 extern	uint32_t nge_debug;
11065574Smx205022 
11075574Smx205022 /*
11085574Smx205022  * DESC MODE 2
11095574Smx205022  */
11105574Smx205022 
11115574Smx205022 extern void nge_sum_rxd_fill(void *, const ddi_dma_cookie_t *, size_t);
11125574Smx205022 extern uint32_t nge_sum_rxd_check(const void *, size_t *);
11135574Smx205022 
11145574Smx205022 extern void nge_sum_txd_fill(void *, const ddi_dma_cookie_t *,
11155574Smx205022 				size_t, uint32_t, boolean_t);
11165574Smx205022 extern uint32_t nge_sum_txd_check(const void *, size_t *);
11175574Smx205022 
11185574Smx205022 /*
11195574Smx205022  * DESC MODE 3
11205574Smx205022  */
11215574Smx205022 
11225574Smx205022 extern void nge_hot_rxd_fill(void *, const ddi_dma_cookie_t *, size_t);
11235574Smx205022 extern uint32_t nge_hot_rxd_check(const void *, size_t *);
11245574Smx205022 
11255574Smx205022 extern void nge_hot_txd_fill(void *, const ddi_dma_cookie_t *,
11265574Smx205022 				size_t, uint32_t, boolean_t);
11275574Smx205022 extern uint32_t nge_hot_txd_check(const void *, size_t *);
11285574Smx205022 
11295574Smx205022 #ifdef __cplusplus
11305574Smx205022 }
11315574Smx205022 #endif
11325574Smx205022 
11335574Smx205022 #endif	/* _SYS_NGE_H */
1134