xref: /titanic_52/usr/src/uts/common/io/bge/bge_impl.h (revision 25e4ecec2f99a20ac67dc9ed066f8b119c156075)
1f724721bSzh199473 /*
2f724721bSzh199473  * CDDL HEADER START
3f724721bSzh199473  *
4f724721bSzh199473  * The contents of this file are subject to the terms of the
5f724721bSzh199473  * Common Development and Distribution License (the "License").
6f724721bSzh199473  * You may not use this file except in compliance with the License.
7f724721bSzh199473  *
8f724721bSzh199473  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9f724721bSzh199473  * or http://www.opensolaris.org/os/licensing.
10f724721bSzh199473  * See the License for the specific language governing permissions
11f724721bSzh199473  * and limitations under the License.
12f724721bSzh199473  *
13f724721bSzh199473  * When distributing Covered Code, include this CDDL HEADER in each
14f724721bSzh199473  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15f724721bSzh199473  * If applicable, add the following below this CDDL HEADER, with the
16f724721bSzh199473  * fields enclosed by brackets "[]" replaced with your own identifying
17f724721bSzh199473  * information: Portions Copyright [yyyy] [name of copyright owner]
18f724721bSzh199473  *
19f724721bSzh199473  * CDDL HEADER END
20f724721bSzh199473  */
21f724721bSzh199473 
22f724721bSzh199473 /*
23087a28d1SDavid Gwynne  * Copyright (c) 2010-2013, by Broadcom, Inc.
24087a28d1SDavid Gwynne  * All Rights Reserved.
25087a28d1SDavid Gwynne  */
26087a28d1SDavid Gwynne 
27087a28d1SDavid Gwynne /*
28087a28d1SDavid Gwynne  * Copyright (c) 2002, 2010, Oracle and/or its affiliates.
29087a28d1SDavid Gwynne  * All rights reserved.
30f724721bSzh199473  */
31f724721bSzh199473 
32931dca7dSgs150176 #ifndef _BGE_IMPL_H
33931dca7dSgs150176 #define	_BGE_IMPL_H
34f724721bSzh199473 
35f724721bSzh199473 
36f724721bSzh199473 #ifdef __cplusplus
37f724721bSzh199473 extern "C" {
38f724721bSzh199473 #endif
39f724721bSzh199473 
40f724721bSzh199473 #include <sys/types.h>
41f724721bSzh199473 #include <sys/stream.h>
42f724721bSzh199473 #include <sys/strsun.h>
43f724721bSzh199473 #include <sys/strsubr.h>
44f724721bSzh199473 #include <sys/stat.h>
45f724721bSzh199473 #include <sys/pci.h>
46f724721bSzh199473 #include <sys/note.h>
47f724721bSzh199473 #include <sys/modctl.h>
48f724721bSzh199473 #include <sys/crc32.h>
49f724721bSzh199473 #ifdef	__sparcv9
50f724721bSzh199473 #include <v9/sys/membar.h>
51f724721bSzh199473 #endif	/* __sparcv9 */
52f724721bSzh199473 #include <sys/kstat.h>
53f724721bSzh199473 #include <sys/ethernet.h>
54f724721bSzh199473 #include <sys/errno.h>
55f724721bSzh199473 #include <sys/dlpi.h>
56f724721bSzh199473 #include <sys/devops.h>
57f724721bSzh199473 #include <sys/debug.h>
58f724721bSzh199473 #include <sys/conf.h>
59f724721bSzh199473 
60f724721bSzh199473 #include <netinet/ip6.h>
61f724721bSzh199473 
62f724721bSzh199473 #include <inet/common.h>
63f724721bSzh199473 #include <inet/ip.h>
64f724721bSzh199473 #include <inet/mi.h>
65f724721bSzh199473 #include <inet/nd.h>
66f724721bSzh199473 #include <sys/pattr.h>
67f724721bSzh199473 
68dd4eeefdSeota #include <sys/disp.h>
69e7801d59Ssowmini #include <sys/cmn_err.h>
70f724721bSzh199473 #include <sys/ddi.h>
71f724721bSzh199473 #include <sys/sunddi.h>
72f724721bSzh199473 
73f724721bSzh199473 #include <sys/ddifm.h>
74f724721bSzh199473 #include <sys/fm/protocol.h>
75f724721bSzh199473 #include <sys/fm/util.h>
76f724721bSzh199473 #include <sys/fm/io/ddi.h>
77f724721bSzh199473 
78da14cebeSEric Cheng #include <sys/mac_provider.h>
79f724721bSzh199473 #include <sys/mac_ether.h>
80f724721bSzh199473 
81f724721bSzh199473 #ifdef __amd64
82f724721bSzh199473 #include <sys/x86_archext.h>
83f724721bSzh199473 #endif
84f724721bSzh199473 
85087a28d1SDavid Gwynne #ifndef VLAN_TAGSZ
86087a28d1SDavid Gwynne #define VLAN_TAGSZ 4
87087a28d1SDavid Gwynne #endif
88087a28d1SDavid Gwynne 
89087a28d1SDavid Gwynne #define BGE_STR_SIZE 32
90087a28d1SDavid Gwynne 
91087a28d1SDavid Gwynne #ifndef OFFSETOF
92087a28d1SDavid Gwynne #define OFFSETOF(_s, _f) \
93087a28d1SDavid Gwynne     ((uint32_t)((uint8_t *)(&((_s *)0)->_f) - \
94087a28d1SDavid Gwynne                 (uint8_t *)((uint8_t *) 0)))
95087a28d1SDavid Gwynne #endif
96087a28d1SDavid Gwynne 
97f724721bSzh199473 /*
98f724721bSzh199473  * <sys/ethernet.h> *may* already have provided the typedef ether_addr_t;
99f724721bSzh199473  * but of course C doesn't provide a way to check this directly.  So here
100f724721bSzh199473  * we rely on the fact that the symbol ETHERTYPE_AT was added to the
101f724721bSzh199473  * header file (as a #define, which we *can* test for) at the same time
102f724721bSzh199473  * as the typedef for ether_addr_t ;-!
103f724721bSzh199473  */
104f724721bSzh199473 #ifndef	ETHERTYPE_AT
105f724721bSzh199473 typedef uchar_t ether_addr_t[ETHERADDRL];
106f724721bSzh199473 #endif	/* ETHERTYPE_AT */
107f724721bSzh199473 
108f724721bSzh199473 /*
109f724721bSzh199473  * Reconfiguring the network devices requires the net_config privilege
110ee754f13Sgs150176  * in Solaris 10+.
111f724721bSzh199473  */
112f724721bSzh199473 extern int secpolicy_net_config(const cred_t *, boolean_t);
113f724721bSzh199473 
114f724721bSzh199473 #include <sys/miiregs.h>		/* by fjlite out of intel 	*/
115f724721bSzh199473 
116f724721bSzh199473 #include "bge.h"
117f724721bSzh199473 #include "bge_hw.h"
118f724721bSzh199473 
119f724721bSzh199473 /*
120f724721bSzh199473  * Compile-time feature switches ...
121f724721bSzh199473  */
122f724721bSzh199473 #define	BGE_DO_PPIO		0	/* peek/poke ioctls		*/
123f724721bSzh199473 #define	BGE_RX_SOFTINT		0	/* softint per receive ring	*/
124f724721bSzh199473 #define	BGE_CHOOSE_SEND_METHOD	0	/* send by copying only		*/
125f724721bSzh199473 
126f724721bSzh199473 /*
127f724721bSzh199473  * NOTES:
128f724721bSzh199473  *
129f724721bSzh199473  * #defines:
130f724721bSzh199473  *
131f724721bSzh199473  *	BGE_PCI_CONFIG_RNUMBER and BGE_PCI_OPREGS_RNUMBER are the
132f724721bSzh199473  *	register-set numbers to use for the config space registers
133f724721bSzh199473  *	and the operating registers respectively.  On an OBP-based
134f724721bSzh199473  *	machine, regset 0 refers to CONFIG space, and regset 1 will
135f724721bSzh199473  *	be the operating registers in MEMORY space.  If an expansion
136f724721bSzh199473  *	ROM is fitted, it may appear as a further register set.
137f724721bSzh199473  *
138f724721bSzh199473  *	BGE_DMA_MODE defines the mode (STREAMING/CONSISTENT) used
139f724721bSzh199473  *	for the data buffers.  The descriptors are always set up
140f724721bSzh199473  *	in CONSISTENT mode.
141f724721bSzh199473  *
142f724721bSzh199473  *	BGE_HEADROOM defines how much space we'll leave in allocated
143f724721bSzh199473  *	mblks before the first valid data byte.  This should be chosen
144f724721bSzh199473  *	to be 2 modulo 4, so that once the ethernet header (14 bytes)
145f724721bSzh199473  *	has been stripped off, the packet data will be 4-byte aligned.
146f724721bSzh199473  *	The remaining space can be used by upstream modules to prepend
147f724721bSzh199473  *	any headers required.
148f724721bSzh199473  */
149f724721bSzh199473 
150f724721bSzh199473 #define	BGE_PCI_CONFIG_RNUMBER	0
151f724721bSzh199473 #define	BGE_PCI_OPREGS_RNUMBER	1
152087a28d1SDavid Gwynne #define	BGE_PCI_APEREGS_RNUMBER	2
153f724721bSzh199473 #define	BGE_DMA_MODE		DDI_DMA_STREAMING
154f724721bSzh199473 #define	BGE_HEADROOM		34
155f724721bSzh199473 
156f724721bSzh199473 /*
157f724721bSzh199473  *	BGE_HALFTICK is half the period of the cyclic callback (in
158f724721bSzh199473  *	nanoseconds), chosen so that 0.5s <= cyclic period <= 1s.
159f724721bSzh199473  *	Other time values are derived as odd multiples of this value
160f724721bSzh199473  *	so that there's little chance of ambiguity w.r.t. which tick
161f724721bSzh199473  *	a timeout expires on.
162f724721bSzh199473  *
163f724721bSzh199473  *	BGE_PHY_STABLE_TIME is the period for which the contents of the
164f724721bSzh199473  *	PHY's status register must remain unchanging before we accept
165f724721bSzh199473  *	that the link has come up.  [Sometimes the link comes up, only
166f724721bSzh199473  *	to go down again within a short time as the autonegotiation
167f724721bSzh199473  *	process cycles through various options before finding the best
168f724721bSzh199473  *	compatible mode.  We don't want to report repeated link up/down
169f724721bSzh199473  *	cycles, so we wait until we think it's stable.]
170f724721bSzh199473  *
171f724721bSzh199473  *	BGE_SERDES_STABLE_TIME is the analogous value for the SerDes
172f724721bSzh199473  *	interface.  It's much shorter, 'cos the SerDes doesn't show
173f724721bSzh199473  *	these effects as much as the copper PHY.
174f724721bSzh199473  *
175f724721bSzh199473  *	BGE_LINK_SETTLE_TIME is the period during which we regard link
176f724721bSzh199473  *	up/down cycles as an normal event after resetting/reprogramming
177f724721bSzh199473  *	the PHY.  During this time, link up/down messages are sent to
178f724721bSzh199473  *	the log only, not the console.  At any other time, link change
179f724721bSzh199473  *	events are regarded as unexpected and sent to both console & log.
180f724721bSzh199473  *
181f724721bSzh199473  *	These latter two values have no theoretical justification, but
182f724721bSzh199473  *	are derived from observations and heuristics - the values below
183f724721bSzh199473  *	just seem to work quite well.
184f724721bSzh199473  */
185f724721bSzh199473 
186f724721bSzh199473 #define	BGE_HALFTICK		268435456LL		/* 2**28 ns!	*/
1872adae974Syong tan - Sun Microsystems - Beijing China #define	BGE_CYCLIC_PERIOD	(4*BGE_HALFTICK)	/*    ~1.0s	*/
188087a28d1SDavid Gwynne #define	BGE_CYCLIC_TIMEOUT	(drv_usectohz(1000000))	/*    ~1.0s	*/
189f724721bSzh199473 #define	BGE_SERDES_STABLE_TIME	(3*BGE_HALFTICK)	/*    ~0.8s	*/
190f724721bSzh199473 #define	BGE_PHY_STABLE_TIME	(11*BGE_HALFTICK)	/*    ~3.0s	*/
191f724721bSzh199473 #define	BGE_LINK_SETTLE_TIME	(111*BGE_HALFTICK)	/*   ~30.0s	*/
192f724721bSzh199473 
193f724721bSzh199473 /*
194f724721bSzh199473  * Indices used to identify the different buffer rings internally
195f724721bSzh199473  */
196f724721bSzh199473 #define	BGE_STD_BUFF_RING	0
197f724721bSzh199473 #define	BGE_JUMBO_BUFF_RING	1
198f724721bSzh199473 #define	BGE_MINI_BUFF_RING	2
199f724721bSzh199473 
200f724721bSzh199473 /*
201f724721bSzh199473  * Current implementation limits
202f724721bSzh199473  */
203f724721bSzh199473 #define	BGE_BUFF_RINGS_USED	2		/* std & jumbo ring	*/
204f724721bSzh199473 						/* for now		*/
205f724721bSzh199473 #define	BGE_RECV_RINGS_USED	16		/* up to 16 rtn rings	*/
206f724721bSzh199473 						/* for now		*/
207f724721bSzh199473 #define	BGE_SEND_RINGS_USED	4		/* up to 4 tx rings	*/
208f724721bSzh199473 						/* for now		*/
209f724721bSzh199473 #define	BGE_HASH_TABLE_SIZE	128		/* may be 256 later	*/
210f724721bSzh199473 
211f724721bSzh199473 /*
212f724721bSzh199473  * Ring/buffer size parameters
213f724721bSzh199473  *
214f724721bSzh199473  * All of the (up to) 16 TX rings & and the corresponding buffers are the
215f724721bSzh199473  * same size.
216f724721bSzh199473  *
217f724721bSzh199473  * Each of the (up to) 3 receive producer (aka buffer) rings is a different
218f724721bSzh199473  * size and has different sized buffers associated with it too.
219f724721bSzh199473  *
220f724721bSzh199473  * The (up to) 16 receive return rings have no buffers associated with them.
221f724721bSzh199473  * The number of slots per receive return ring must be 2048 if the mini
222f724721bSzh199473  * ring is enabled, otherwise it may be 1024.  See Broadcom document
223f724721bSzh199473  * 570X-PG102-R page 56.
224f724721bSzh199473  *
225f724721bSzh199473  * Note: only the 5700 supported external memory (and therefore the mini
226f724721bSzh199473  * ring); the 5702/3/4 don't.  This driver doesn't support the original
227f724721bSzh199473  * 5700, so we won't ever use the mini ring capability.
228f724721bSzh199473  */
229f724721bSzh199473 
230f724721bSzh199473 #define	BGE_SEND_RINGS_DEFAULT		1
231f724721bSzh199473 #define	BGE_RECV_RINGS_DEFAULT		1
232f724721bSzh199473 
233f724721bSzh199473 #define	BGE_SEND_BUFF_SIZE_DEFAULT	1536
234f724721bSzh199473 #define	BGE_SEND_BUFF_SIZE_JUMBO	9022
235f724721bSzh199473 #define	BGE_SEND_SLOTS_USED	512
236f724721bSzh199473 
237f724721bSzh199473 #define	BGE_STD_BUFF_SIZE	1536		/* 0x600		*/
238f724721bSzh199473 #define	BGE_STD_SLOTS_USED	512
239f724721bSzh199473 
240f724721bSzh199473 #define	BGE_JUMBO_BUFF_SIZE	9022		/* 9k			*/
241f724721bSzh199473 #define	BGE_JUMBO_SLOTS_USED	256
242f724721bSzh199473 
243f724721bSzh199473 #define	BGE_MINI_BUFF_SIZE	128		/* 64? 256?		*/
244f724721bSzh199473 #define	BGE_MINI_SLOTS_USED	0		/* must be 0; see above	*/
245f724721bSzh199473 
246f724721bSzh199473 #define	BGE_RECV_BUFF_SIZE	0
247f724721bSzh199473 #if	BGE_MINI_SLOTS_USED > 0
248f724721bSzh199473 #define	BGE_RECV_SLOTS_USED	2048		/* required		*/
249f724721bSzh199473 #else
250f724721bSzh199473 #define	BGE_RECV_SLOTS_USED	1024		/* could be 2048 anyway	*/
251f724721bSzh199473 #endif
252f724721bSzh199473 
253931dca7dSgs150176 #define	BGE_SEND_BUF_NUM	512
254931dca7dSgs150176 #define	BGE_SEND_BUF_ARRAY	16
255931dca7dSgs150176 #define	BGE_SEND_BUF_ARRAY_JUMBO	3
256931dca7dSgs150176 #define	BGE_SEND_BUF_MAX	(BGE_SEND_BUF_NUM*BGE_SEND_BUF_ARRAY)
257931dca7dSgs150176 
258f724721bSzh199473 /*
259f724721bSzh199473  * PCI type. PCI-Express or PCI/PCIX
260f724721bSzh199473  */
261f724721bSzh199473 #define	BGE_PCI		0
262f724721bSzh199473 #define	BGE_PCI_E	1
263f724721bSzh199473 #define	BGE_PCI_X	2
264f724721bSzh199473 
265f724721bSzh199473 /*
266f724721bSzh199473  * Statistic type. There are two type of statistic:
267f724721bSzh199473  * statistic block and statistic registers
268f724721bSzh199473  */
269f724721bSzh199473 #define	BGE_STAT_BLK	1
270f724721bSzh199473 #define	BGE_STAT_REG	2
271f724721bSzh199473 
272f724721bSzh199473 /*
273f724721bSzh199473  * MTU.for all chipsets ,the default is 1500 ,and some chipsets
274f724721bSzh199473  * support 9k jumbo frames size
275f724721bSzh199473  */
276f724721bSzh199473 #define	BGE_DEFAULT_MTU		1500
277f724721bSzh199473 #define	BGE_MAXIMUM_MTU		9000
278f724721bSzh199473 
279f724721bSzh199473 /*
280f724721bSzh199473  * Pad the h/w defined status block (which can be up to 80 bytes long)
281f724721bSzh199473  * to a power-of-two boundary
282f724721bSzh199473  */
283f724721bSzh199473 #define	BGE_STATUS_PADDING	(128 - sizeof (bge_status_t))
284f724721bSzh199473 
285f724721bSzh199473 /*
286f724721bSzh199473  * On platforms which support DVMA, we can simply allocate one big piece
287f724721bSzh199473  * of memory for all the Tx buffers and another for the Rx buffers, and
288f724721bSzh199473  * then carve them up as required.  It doesn't matter if they aren't just
289f724721bSzh199473  * one physically contiguous piece each, because both the CPU *and* the
290f724721bSzh199473  * I/O device can see them *as though they were*.
291f724721bSzh199473  *
292f724721bSzh199473  * However, if only physically-addressed DMA is possible, this doesn't
293f724721bSzh199473  * work; we can't expect to get enough contiguously-addressed memory for
294f724721bSzh199473  * all the buffers of each type, so in this case we request a number of
295f724721bSzh199473  * smaller pieces, each still large enough for several buffers but small
296f724721bSzh199473  * enough to fit within "an I/O page" (e.g. 64K).
297f724721bSzh199473  *
298f724721bSzh199473  * The #define below specifies how many pieces of memory are to be used;
299f724721bSzh199473  * 16 has been shown to work on an i86pc architecture but this could be
300f724721bSzh199473  * different on other non-DVMA platforms ...
301f724721bSzh199473  */
302f724721bSzh199473 #ifdef	_DMA_USES_VIRTADDR
303f724721bSzh199473 #define	BGE_SPLIT		1		/* no split required	*/
304f724721bSzh199473 #else
305f724721bSzh199473 #if ((BGE_BUFF_RINGS_USED > 1) || (BGE_SEND_RINGS_USED > 1) || \
306f724721bSzh199473 	(BGE_RECV_RINGS_USED > 1))
307f724721bSzh199473 #define	BGE_SPLIT		128		/* split 128 ways	*/
308f724721bSzh199473 #else
309f724721bSzh199473 #define	BGE_SPLIT		16		/* split 16 ways	*/
310f724721bSzh199473 #endif
311f724721bSzh199473 #endif	/* _DMA_USES_VIRTADDR */
312f724721bSzh199473 
313f724721bSzh199473 #define	BGE_RECV_RINGS_SPLIT	(BGE_RECV_RINGS_MAX + 1)
314f724721bSzh199473 
315f724721bSzh199473 /*
316f724721bSzh199473  * STREAMS parameters
317f724721bSzh199473  */
318f724721bSzh199473 #define	BGE_IDNUM		0		/* zero seems to work	*/
319f724721bSzh199473 #define	BGE_LOWAT		(256)
320f724721bSzh199473 #define	BGE_HIWAT		(256*1024)
321f724721bSzh199473 
322f724721bSzh199473 /*
323f724721bSzh199473  * Basic data types, for clarity in distinguishing 'numbers'
324f724721bSzh199473  * used for different purposes ...
325f724721bSzh199473  *
326f724721bSzh199473  * A <bge_regno_t> is a register 'address' (offset) in any one of
327f724721bSzh199473  * various address spaces (PCI config space, PCI memory-mapped I/O
328f724721bSzh199473  * register space, MII registers, etc).  None of these exceeds 64K,
329f724721bSzh199473  * so we could use a 16-bit representation but pointer-sized objects
330f724721bSzh199473  * are more "natural" in most architectures; they seem to be handled
331f724721bSzh199473  * more efficiently on SPARC and no worse on x86.
332f724721bSzh199473  *
333f724721bSzh199473  * BGE_REGNO_NONE represents the non-existent value in this space.
334f724721bSzh199473  */
335f724721bSzh199473 typedef uintptr_t bge_regno_t;			/* register # (offset)	*/
336f724721bSzh199473 #define	BGE_REGNO_NONE		(~(uintptr_t)0u)
337f724721bSzh199473 
338f724721bSzh199473 /*
339f724721bSzh199473  * Describes one chunk of allocated DMA-able memory
340f724721bSzh199473  *
341f724721bSzh199473  * In some cases, this is a single chunk as allocated from the system;
342f724721bSzh199473  * but we also use this structure to represent slices carved off such
343f724721bSzh199473  * a chunk.  Even when we don't really need all the information, we
344f724721bSzh199473  * use this structure as a convenient way of correlating the various
345f724721bSzh199473  * ways of looking at a piece of memory (kernel VA, IO space DVMA,
346f724721bSzh199473  * handle+offset, etc).
347f724721bSzh199473  */
348f724721bSzh199473 typedef struct {
349f724721bSzh199473 	ddi_acc_handle_t	acc_hdl;	/* handle for memory	*/
350f724721bSzh199473 	void			*mem_va;	/* CPU VA of memory	*/
351f724721bSzh199473 	uint32_t		nslots;		/* number of slots	*/
352f724721bSzh199473 	uint32_t		size;		/* size per slot	*/
353f724721bSzh199473 	size_t			alength;	/* allocated size	*/
354f724721bSzh199473 						/* >= product of above	*/
355f724721bSzh199473 
356f724721bSzh199473 	ddi_dma_handle_t	dma_hdl;	/* DMA handle		*/
357f724721bSzh199473 	offset_t		offset;		/* relative to handle	*/
358f724721bSzh199473 	ddi_dma_cookie_t	cookie;		/* associated cookie	*/
359f724721bSzh199473 	uint32_t		ncookies;	/* must be 1		*/
360f724721bSzh199473 	uint32_t		token;		/* arbitrary identifier	*/
361f724721bSzh199473 } dma_area_t;					/* 0x50 (80) bytes	*/
362f724721bSzh199473 
363931dca7dSgs150176 typedef struct bge_queue_item {
364931dca7dSgs150176 	struct bge_queue_item	*next;
365931dca7dSgs150176 	void			*item;
366931dca7dSgs150176 } bge_queue_item_t;
367931dca7dSgs150176 
368931dca7dSgs150176 typedef struct bge_queue {
369931dca7dSgs150176 	bge_queue_item_t	*head;
370931dca7dSgs150176 	uint32_t		count;
371931dca7dSgs150176 	kmutex_t		*lock;
372931dca7dSgs150176 } bge_queue_t;
373f724721bSzh199473 /*
374f724721bSzh199473  * Software version of the Receive Buffer Descriptor
375f724721bSzh199473  * There's one of these for each receive buffer (up to 256/512/1024 per ring).
376f724721bSzh199473  */
377f724721bSzh199473 typedef struct sw_rbd {
378f724721bSzh199473 	dma_area_t		pbuf;		/* (const) related	*/
379f724721bSzh199473 						/* buffer area		*/
380f724721bSzh199473 } sw_rbd_t;					/* 0x50 (80) bytes	*/
381f724721bSzh199473 
382f724721bSzh199473 /*
383f724721bSzh199473  * Software Receive Buffer (Producer) Ring Control Block
384f724721bSzh199473  * There's one of these for each receiver producer ring (up to 3),
385f724721bSzh199473  * but each holds buffers of a different size.
386f724721bSzh199473  */
387f724721bSzh199473 typedef struct buff_ring {
388f724721bSzh199473 	dma_area_t		desc;		/* (const) related h/w	*/
389f724721bSzh199473 						/* descriptor area	*/
390f724721bSzh199473 	dma_area_t		buf[BGE_SPLIT];	/* (const) related	*/
391f724721bSzh199473 						/* buffer area(s)	*/
392f724721bSzh199473 	bge_rcb_t		hw_rcb;		/* (const) image of h/w	*/
393f724721bSzh199473 						/* RCB, and used to	*/
394f724721bSzh199473 	struct bge		*bgep;		/* (const) containing	*/
395f724721bSzh199473 						/* driver soft state	*/
396f724721bSzh199473 						/* initialise same	*/
397f724721bSzh199473 	volatile uint16_t	*cons_index_p;	/* (const) ptr to h/w	*/
398f724721bSzh199473 						/* "consumer index"	*/
399f724721bSzh199473 						/* (in status block)	*/
400f724721bSzh199473 
401f724721bSzh199473 	/*
402f724721bSzh199473 	 * The rf_lock must be held when updating the h/w producer index
403f724721bSzh199473 	 * mailbox register (*chip_mbox_reg), or the s/w producer index
404f724721bSzh199473 	 * (rf_next).
405f724721bSzh199473 	 */
406f724721bSzh199473 	bge_regno_t		chip_mbx_reg;	/* (const) h/w producer	*/
407f724721bSzh199473 						/* index mailbox offset	*/
408f724721bSzh199473 	kmutex_t		rf_lock[1];	/* serialize refill	*/
409f724721bSzh199473 	uint64_t		rf_next;	/* next slot to refill	*/
410f724721bSzh199473 						/* ("producer index")	*/
411f724721bSzh199473 
412f724721bSzh199473 	sw_rbd_t		*sw_rbds; 	/* software descriptors	*/
413f724721bSzh199473 	void			*spare[4];	/* padding		*/
414f724721bSzh199473 } buff_ring_t;					/* 0x100 (256) bytes	*/
415f724721bSzh199473 
416da14cebeSEric Cheng typedef struct bge_multi_mac {
417da14cebeSEric Cheng 	int		naddr;		/* total supported addresses */
418da14cebeSEric Cheng 	int		naddrfree;	/* free addresses slots */
419da14cebeSEric Cheng 	ether_addr_t	mac_addr[MAC_ADDRESS_REGS_MAX];
420da14cebeSEric Cheng 	boolean_t	mac_addr_set[MAC_ADDRESS_REGS_MAX];
421da14cebeSEric Cheng } bge_multi_mac_t;
422da14cebeSEric Cheng 
423f724721bSzh199473 /*
424f724721bSzh199473  * Software Receive (Return) Ring Control Block
425f724721bSzh199473  * There's one of these for each receiver return ring (up to 16).
426f724721bSzh199473  */
427f724721bSzh199473 typedef struct recv_ring {
428f724721bSzh199473 	/*
429f724721bSzh199473 	 * The elements flagged (const) in the comments below are
430f724721bSzh199473 	 * set up once during initialiation and thereafter unchanged.
431f724721bSzh199473 	 */
432f724721bSzh199473 	dma_area_t		desc;		/* (const) related h/w	*/
433f724721bSzh199473 						/* descriptor area	*/
434f724721bSzh199473 	bge_rcb_t		hw_rcb;		/* (const) image of h/w	*/
435f724721bSzh199473 						/* RCB, and used to	*/
436f724721bSzh199473 						/* initialise same	*/
437f724721bSzh199473 	struct bge		*bgep;		/* (const) containing	*/
438f724721bSzh199473 						/* driver soft state	*/
439f724721bSzh199473 	ddi_softintr_t		rx_softint;	/* (const) per-ring	*/
440f724721bSzh199473 						/* receive callback	*/
441f724721bSzh199473 	volatile uint16_t	*prod_index_p;	/* (const) ptr to h/w	*/
442f724721bSzh199473 						/* "producer index"	*/
443f724721bSzh199473 						/* (in status block)	*/
444f724721bSzh199473 	/*
445f724721bSzh199473 	 * The rx_lock must be held when updating the h/w consumer index
446f724721bSzh199473 	 * mailbox register (*chip_mbox_reg), or the s/w consumer index
447f724721bSzh199473 	 * (rx_next).
448f724721bSzh199473 	 */
449f724721bSzh199473 	bge_regno_t		chip_mbx_reg;	/* (const) h/w consumer	*/
450f724721bSzh199473 						/* index mailbox offset	*/
451f724721bSzh199473 	kmutex_t		rx_lock[1];	/* serialize receive	*/
452f724721bSzh199473 	uint64_t		rx_next;	/* next slot to examine	*/
453da14cebeSEric Cheng 
454da14cebeSEric Cheng 	mac_ring_handle_t	ring_handle;
455da14cebeSEric Cheng 	mac_group_handle_t	ring_group_handle;
456da14cebeSEric Cheng 	uint64_t		ring_gen_num;
457da14cebeSEric Cheng 	bge_rule_info_t		*mac_addr_rule;
458da14cebeSEric Cheng 	uint8_t			mac_addr_val[ETHERADDRL];
459da14cebeSEric Cheng 	int			poll_flag;	/* Polling flag		*/
4600dc2366fSVenugopal Iyer 
4610dc2366fSVenugopal Iyer 	/* Per-ring statistics */
4620dc2366fSVenugopal Iyer 	uint64_t		rx_pkts;	/* Received Packets Count */
4630dc2366fSVenugopal Iyer 	uint64_t		rx_bytes;	/* Received Bytes Count */
4640dc2366fSVenugopal Iyer } recv_ring_t;
465f724721bSzh199473 
466da14cebeSEric Cheng 
467f724721bSzh199473 /*
468931dca7dSgs150176  * Send packet structure
469931dca7dSgs150176  */
470931dca7dSgs150176 typedef struct send_pkt {
471931dca7dSgs150176 	uint16_t		vlan_tci;
472931dca7dSgs150176 	uint32_t		pflags;
473931dca7dSgs150176 	boolean_t		tx_ready;
474931dca7dSgs150176 	bge_queue_item_t	*txbuf_item;
475931dca7dSgs150176 } send_pkt_t;
476931dca7dSgs150176 
477931dca7dSgs150176 /*
478931dca7dSgs150176  * Software version of tx buffer structure
479931dca7dSgs150176  */
480931dca7dSgs150176 typedef struct sw_txbuf {
481931dca7dSgs150176 	dma_area_t		buf;
482931dca7dSgs150176 	uint32_t		copy_len;
483931dca7dSgs150176 } sw_txbuf_t;
484931dca7dSgs150176 
485931dca7dSgs150176 /*
486f724721bSzh199473  * Software version of the Send Buffer Descriptor
487f724721bSzh199473  * There's one of these for each send buffer (up to 512 per ring)
488f724721bSzh199473  */
489f724721bSzh199473 typedef struct sw_sbd {
490f724721bSzh199473 	dma_area_t		desc;		/* (const) related h/w	*/
491f724721bSzh199473 						/* descriptor area	*/
492931dca7dSgs150176 	bge_queue_item_t	*pbuf;		/* (const) related	*/
493f724721bSzh199473 						/* buffer area		*/
494931dca7dSgs150176 } sw_sbd_t;
495f724721bSzh199473 
496f724721bSzh199473 /*
497f724721bSzh199473  * Software Send Ring Control Block
498f724721bSzh199473  * There's one of these for each of (up to) 16 send rings
499f724721bSzh199473  */
500f724721bSzh199473 typedef struct send_ring {
501f724721bSzh199473 	/*
502f724721bSzh199473 	 * The elements flagged (const) in the comments below are
503f724721bSzh199473 	 * set up once during initialiation and thereafter unchanged.
504f724721bSzh199473 	 */
505f724721bSzh199473 	dma_area_t		desc;		/* (const) related h/w	*/
506f724721bSzh199473 						/* descriptor area	*/
507931dca7dSgs150176 	dma_area_t		buf[BGE_SEND_BUF_ARRAY][BGE_SPLIT];
508f724721bSzh199473 						/* buffer area(s)	*/
509f724721bSzh199473 	bge_rcb_t		hw_rcb;		/* (const) image of h/w	*/
510f724721bSzh199473 						/* RCB, and used to	*/
511f724721bSzh199473 						/* initialise same	*/
512f724721bSzh199473 	struct bge		*bgep;		/* (const) containing	*/
513f724721bSzh199473 						/* driver soft state	*/
514f724721bSzh199473 	volatile uint16_t	*cons_index_p;	/* (const) ptr to h/w	*/
515f724721bSzh199473 						/* "consumer index"	*/
516f724721bSzh199473 						/* (in status block)	*/
517f724721bSzh199473 
518f724721bSzh199473 	bge_regno_t		chip_mbx_reg;	/* (const) h/w producer	*/
519f724721bSzh199473 						/* index mailbox offset	*/
520931dca7dSgs150176 	/*
521931dca7dSgs150176 	 * Tx buffer queue
522931dca7dSgs150176 	 */
523931dca7dSgs150176 	bge_queue_t		txbuf_queue;
524931dca7dSgs150176 	bge_queue_t		freetxbuf_queue;
525931dca7dSgs150176 	bge_queue_t		*txbuf_push_queue;
526931dca7dSgs150176 	bge_queue_t		*txbuf_pop_queue;
527931dca7dSgs150176 	kmutex_t		txbuf_lock[1];
528931dca7dSgs150176 	kmutex_t		freetxbuf_lock[1];
529931dca7dSgs150176 	bge_queue_item_t	*txbuf_head;
530931dca7dSgs150176 	send_pkt_t		*pktp;
531931dca7dSgs150176 	uint64_t		txpkt_next;
532931dca7dSgs150176 	uint64_t		txfill_next;
533931dca7dSgs150176 	sw_txbuf_t		*txbuf;
534931dca7dSgs150176 	uint32_t		tx_buffers;
535931dca7dSgs150176 	uint32_t		tx_buffers_low;
536931dca7dSgs150176 	uint32_t		tx_array_max;
537931dca7dSgs150176 	uint32_t		tx_array;
538f724721bSzh199473 	kmutex_t		tx_lock[1];	/* serialize h/w update	*/
539f724721bSzh199473 						/* ("producer index")	*/
540f724721bSzh199473 	uint64_t		tx_next;	/* next slot to use	*/
541f724721bSzh199473 	uint64_t		tx_flow;	/* # concurrent sends	*/
542931dca7dSgs150176 	uint64_t		tx_block;
543931dca7dSgs150176 	uint64_t		tx_nobd;
544931dca7dSgs150176 	uint64_t		tx_nobuf;
545931dca7dSgs150176 	uint64_t		tx_alloc_fail;
546f724721bSzh199473 
547f724721bSzh199473 	/*
548f724721bSzh199473 	 * These counters/indexes are manipulated in the transmit
549f724721bSzh199473 	 * path using atomics rather than mutexes for speed
550f724721bSzh199473 	 */
551f724721bSzh199473 	uint64_t		tx_free;	/* # of slots available	*/
552f724721bSzh199473 
553f724721bSzh199473 	/*
554f724721bSzh199473 	 * The tc_lock must be held while manipulating the s/w consumer
555f724721bSzh199473 	 * index (tc_next).
556f724721bSzh199473 	 */
557f724721bSzh199473 	kmutex_t		tc_lock[1];	/* serialize recycle	*/
558f724721bSzh199473 	uint64_t		tc_next;	/* next slot to recycle	*/
559f724721bSzh199473 						/* ("consumer index")	*/
560f724721bSzh199473 
561f724721bSzh199473 	sw_sbd_t		*sw_sbds; 	/* software descriptors	*/
562f724721bSzh199473 	uint64_t		mac_resid;	/* special per resource id */
563da14cebeSEric Cheng 	uint64_t		pushed_bytes;
564f724721bSzh199473 } send_ring_t;					/* 0x100 (256) bytes	*/
565f724721bSzh199473 
566f724721bSzh199473 typedef struct {
567f724721bSzh199473 	ether_addr_t		addr;		/* in canonical form	*/
568f724721bSzh199473 	uint8_t			spare;
569f724721bSzh199473 	boolean_t		set;		/* B_TRUE => valid	*/
570f724721bSzh199473 } bge_mac_addr_t;
571f724721bSzh199473 
572f724721bSzh199473 /*
573f724721bSzh199473  * The original 5700/01 supported only SEEPROMs.  Later chips (5702+)
574f724721bSzh199473  * support both SEEPROMs (using the same 2-wire CLK/DATA interface for
575f724721bSzh199473  * the hardware and a backwards-compatible software access method), and
576f724721bSzh199473  * buffered or unbuffered FLASH devices connected to the 4-wire SPI bus
577f724721bSzh199473  * and using a new software access method.
578f724721bSzh199473  *
579f724721bSzh199473  * The access methods for SEEPROM and Flash are generally similar, with
580f724721bSzh199473  * the chip handling the serialisation/deserialisation and handshaking,
581f724721bSzh199473  * but the registers used are different, as are a few details of the
582f724721bSzh199473  * protocol, and the timing, so we have to determine which (if any) is
583f724721bSzh199473  * fitted.
584f724721bSzh199473  *
585f724721bSzh199473  * The value UNKNOWN means just that; we haven't yet tried to determine
586f724721bSzh199473  * the device type.
587f724721bSzh199473  *
588f724721bSzh199473  * The value NONE can indicate either that a real and definite absence of
589f724721bSzh199473  * any NVmem has been detected, or that there may be NVmem but we can't
590f724721bSzh199473  * determine its type, perhaps because the NVconfig pins on the chip have
591f724721bSzh199473  * been wired up incorrectly.  In either case, access to the NVmem (if any)
592f724721bSzh199473  * is not supported.
593f724721bSzh199473  */
594f724721bSzh199473 enum bge_nvmem_type {
595f724721bSzh199473 	BGE_NVTYPE_NONE = -1,			/* (or indeterminable)	*/
596f724721bSzh199473 	BGE_NVTYPE_UNKNOWN,			/* not yet checked	*/
597f724721bSzh199473 	BGE_NVTYPE_SEEPROM,			/* BCM5700/5701 only	*/
598f724721bSzh199473 	BGE_NVTYPE_LEGACY_SEEPROM,		/* 5702+		*/
599f724721bSzh199473 	BGE_NVTYPE_UNBUFFERED_FLASH,		/* 5702+		*/
600f724721bSzh199473 	BGE_NVTYPE_BUFFERED_FLASH		/* 5702+		*/
601f724721bSzh199473 };
602f724721bSzh199473 
603f724721bSzh199473 /*
604f724721bSzh199473  * Describes the characteristics of a specific chip
605f724721bSzh199473  *
606f724721bSzh199473  * Note: elements from <businfo> to <latency> are filled in by during
607f724721bSzh199473  * the first phase of chip initialisation (see bge_chip_cfg_init()).
608f724721bSzh199473  * The remaining ones are determined just after the first RESET, in
609f724721bSzh199473  * bge_poll_firmware().  Thereafter, the entire structure is readonly.
610f724721bSzh199473  */
611f724721bSzh199473 typedef struct {
612f724721bSzh199473 	uint32_t		asic_rev;	/* masked from MHCR	*/
613087a28d1SDavid Gwynne 	uint32_t		asic_rev_prod_id; /* new revision ID format */
614f724721bSzh199473 	uint32_t		businfo;	/* from private reg	*/
615f724721bSzh199473 	uint16_t		command;	/* saved during attach	*/
616f724721bSzh199473 
617f724721bSzh199473 	uint16_t		vendor;		/* vendor-id		*/
618f724721bSzh199473 	uint16_t		device;		/* device-id		*/
619f724721bSzh199473 	uint16_t		subven;		/* subsystem-vendor-id	*/
620f724721bSzh199473 	uint16_t		subdev;		/* subsystem-id		*/
621f724721bSzh199473 	uint8_t			revision;	/* revision-id		*/
622f724721bSzh199473 	uint8_t			clsize;		/* cache-line-size	*/
623f724721bSzh199473 	uint8_t			latency;	/* latency-timer	*/
624f724721bSzh199473 
625f724721bSzh199473 	uint8_t			flags;
626f724721bSzh199473 	uint16_t		chip_label;	/* numeric part only	*/
627f724721bSzh199473 						/* (e.g. 5703/5794/etc)	*/
628f724721bSzh199473 	uint32_t		mbuf_base;	/* Mbuf pool parameters */
629f724721bSzh199473 	uint32_t		mbuf_length;	/* depend on chiptype	*/
630f724721bSzh199473 	uint32_t		pci_type;
631f724721bSzh199473 	uint32_t		statistic_type;
632f724721bSzh199473 	uint32_t		bge_dma_rwctrl;
633f724721bSzh199473 	uint32_t		bge_mlcr_default;
634f724721bSzh199473 	uint32_t		recv_slots;	/* receive ring size    */
635f724721bSzh199473 	enum bge_nvmem_type	nvtype;		/* SEEPROM or Flash	*/
636f724721bSzh199473 
637f724721bSzh199473 	uint16_t		jumbo_slots;
638f724721bSzh199473 	uint16_t		ethmax_size;
639f724721bSzh199473 	uint16_t		snd_buff_size;
640f724721bSzh199473 	uint16_t		recv_jumbo_size;
641f724721bSzh199473 	uint16_t		std_buf_size;
642f724721bSzh199473 	uint32_t		mbuf_hi_water;
643f724721bSzh199473 	uint32_t		mbuf_lo_water_rmac;
644f724721bSzh199473 	uint32_t		mbuf_lo_water_rdma;
645f724721bSzh199473 
646931dca7dSgs150176 	uint32_t		rx_rings;	/* from bge.conf	*/
647931dca7dSgs150176 	uint32_t		tx_rings;	/* from bge.conf	*/
648087a28d1SDavid Gwynne 	uint32_t		eee;		/* from bge.conf	*/
649931dca7dSgs150176 	uint32_t		default_mtu;	/* from bge.conf	*/
650f724721bSzh199473 
651f724721bSzh199473 	uint64_t		hw_mac_addr;	/* from chip register	*/
652f724721bSzh199473 	bge_mac_addr_t		vendor_addr;	/* transform of same	*/
653f724721bSzh199473 	boolean_t		msi_enabled;	/* default to true */
654e7801d59Ssowmini 
655e7801d59Ssowmini 	uint32_t		rx_ticks_norm;
656e7801d59Ssowmini 	uint32_t		rx_count_norm;
6574d6eaea5Syong tan - Sun Microsystems - Beijing China 	uint32_t		tx_ticks_norm;
6584d6eaea5Syong tan - Sun Microsystems - Beijing China 	uint32_t		tx_count_norm;
659dc3f9a75Syong tan - Sun Microsystems - Beijing China 	uint32_t		mask_pci_int;
660f724721bSzh199473 } chip_id_t;
661f724721bSzh199473 
662f724721bSzh199473 #define	CHIP_FLAG_SUPPORTED	0x80
663f724721bSzh199473 #define	CHIP_FLAG_SERDES	0x40
664f724721bSzh199473 #define	CHIP_FLAG_PARTIAL_CSUM	0x20
665f724721bSzh199473 #define	CHIP_FLAG_NO_JUMBO	0x1
666f724721bSzh199473 
667f724721bSzh199473 /*
668f724721bSzh199473  * Collection of physical-layer functions to:
669f724721bSzh199473  *	(re)initialise the physical layer
670f724721bSzh199473  *	update it to match software settings
671f724721bSzh199473  *	check for link status change
672f724721bSzh199473  */
673f724721bSzh199473 typedef struct {
674f724721bSzh199473 	int			(*phys_restart)(struct bge *, boolean_t);
675f724721bSzh199473 	int			(*phys_update)(struct bge *);
676f724721bSzh199473 	boolean_t		(*phys_check)(struct bge *, boolean_t);
677f724721bSzh199473 } phys_ops_t;
678f724721bSzh199473 
679f724721bSzh199473 
680f724721bSzh199473 /*
681f724721bSzh199473  * Actual state of the BCM570x chip
682f724721bSzh199473  */
683f724721bSzh199473 enum bge_chip_state {
684f724721bSzh199473 	BGE_CHIP_FAULT = -2,			/* fault, need reset	*/
685f724721bSzh199473 	BGE_CHIP_ERROR,				/* error, want reset	*/
686f724721bSzh199473 	BGE_CHIP_INITIAL,			/* Initial state only	*/
687f724721bSzh199473 	BGE_CHIP_RESET,				/* reset, need init	*/
688f724721bSzh199473 	BGE_CHIP_STOPPED,			/* Tx/Rx stopped	*/
689f724721bSzh199473 	BGE_CHIP_RUNNING			/* with interrupts	*/
690f724721bSzh199473 };
691f724721bSzh199473 
692f724721bSzh199473 enum bge_mac_state {
693f724721bSzh199473 	BGE_MAC_STOPPED = 0,
694f724721bSzh199473 	BGE_MAC_STARTED
695f724721bSzh199473 };
696f724721bSzh199473 
697f724721bSzh199473 /*
698f724721bSzh199473  * (Internal) return values from ioctl subroutines
699f724721bSzh199473  */
700f724721bSzh199473 enum ioc_reply {
701f724721bSzh199473 	IOC_INVAL = -1,				/* bad, NAK with EINVAL	*/
702f724721bSzh199473 	IOC_DONE,				/* OK, reply sent	*/
703f724721bSzh199473 	IOC_ACK,				/* OK, just send ACK	*/
704f724721bSzh199473 	IOC_REPLY,				/* OK, just send reply	*/
705f724721bSzh199473 	IOC_RESTART_ACK,			/* OK, restart & ACK	*/
706f724721bSzh199473 	IOC_RESTART_REPLY			/* OK, restart & reply	*/
707f724721bSzh199473 };
708f724721bSzh199473 
709f724721bSzh199473 /*
710f724721bSzh199473  * (Internal) return values from send_msg subroutines
711f724721bSzh199473  */
712f724721bSzh199473 enum send_status {
713f724721bSzh199473 	SEND_FAIL = -1,				/* Not OK		*/
714f724721bSzh199473 	SEND_KEEP,				/* OK, msg queued	*/
715f724721bSzh199473 	SEND_FREE				/* OK, free msg		*/
716f724721bSzh199473 };
717f724721bSzh199473 
718f724721bSzh199473 /*
719f724721bSzh199473  * (Internal) enumeration of this driver's kstats
720f724721bSzh199473  */
721f724721bSzh199473 enum {
722f724721bSzh199473 	BGE_KSTAT_RAW = 0,
723f724721bSzh199473 	BGE_KSTAT_STATS,
724f724721bSzh199473 	BGE_KSTAT_CHIPID,
725f724721bSzh199473 	BGE_KSTAT_DRIVER,
726f724721bSzh199473 	BGE_KSTAT_PHYS,
727f724721bSzh199473 
728f724721bSzh199473 	BGE_KSTAT_COUNT
729f724721bSzh199473 };
730f724721bSzh199473 
731f724721bSzh199473 #define	BGE_MAX_RESOURCES 255
732f724721bSzh199473 
733f724721bSzh199473 /*
734f724721bSzh199473  * Per-instance soft-state structure
735f724721bSzh199473  */
736f724721bSzh199473 typedef struct bge {
737f724721bSzh199473 	/*
738f724721bSzh199473 	 * These fields are set by attach() and unchanged thereafter ...
739f724721bSzh199473 	 */
740087a28d1SDavid Gwynne 	char			version[BGE_STR_SIZE];
741087a28d1SDavid Gwynne #define BGE_FW_VER_SIZE 32
742087a28d1SDavid Gwynne 	char			fw_version[BGE_FW_VER_SIZE];
743f724721bSzh199473 	dev_info_t		*devinfo;	/* device instance	*/
744087a28d1SDavid Gwynne 	uint32_t		pci_bus;	/* from "regs" prop */
745087a28d1SDavid Gwynne 	uint32_t		pci_dev;	/* from "regs" prop */
746087a28d1SDavid Gwynne 	uint32_t		pci_func;	/* from "regs" prop */
747f724721bSzh199473 	mac_handle_t		mh;		/* mac module handle	*/
748f724721bSzh199473 	ddi_acc_handle_t	cfg_handle;	/* DDI I/O handle	*/
749f724721bSzh199473 	ddi_acc_handle_t	io_handle;	/* DDI I/O handle	*/
750f724721bSzh199473 	void			*io_regs;	/* mapped registers	*/
751087a28d1SDavid Gwynne 	ddi_acc_handle_t	ape_handle;	/* DDI I/O handle	*/
752087a28d1SDavid Gwynne 	void			*ape_regs;	/* mapped registers	*/
753087a28d1SDavid Gwynne 	boolean_t		ape_enabled;
754087a28d1SDavid Gwynne 	boolean_t		ape_has_ncsi;
755087a28d1SDavid Gwynne 
756dd4eeefdSeota 	ddi_periodic_t		periodic_id;	/* periodical callback	*/
757f724721bSzh199473 	ddi_softintr_t		factotum_id;	/* factotum callback	*/
758931dca7dSgs150176 	ddi_softintr_t		drain_id;	/* reschedule callback	*/
759f724721bSzh199473 
760f724721bSzh199473 	ddi_intr_handle_t 	*htable;	/* For array of interrupts */
761f724721bSzh199473 	int			intr_type;	/* What type of interrupt */
762f724721bSzh199473 	int			intr_cnt;	/* # of intrs count returned */
763f724721bSzh199473 	uint_t			intr_pri;	/* Interrupt priority	*/
764f724721bSzh199473 	int			intr_cap;	/* Interrupt capabilities */
765f724721bSzh199473 	uint32_t		progress;	/* attach tracking	*/
766f724721bSzh199473 	uint32_t		debug;		/* per-instance debug	*/
767f724721bSzh199473 	chip_id_t		chipid;
768f724721bSzh199473 	const phys_ops_t	*physops;
769f724721bSzh199473 	char			ifname[8];	/* "bge0" ... "bge999"	*/
770f724721bSzh199473 
771f724721bSzh199473 	int			fm_capabilities;	/* FMA capabilities */
772f724721bSzh199473 
773f724721bSzh199473 	/*
774f724721bSzh199473 	 * These structures describe the blocks of memory allocated during
775f724721bSzh199473 	 * attach().  They remain unchanged thereafter, although the memory
776f724721bSzh199473 	 * they describe is carved up into various separate regions and may
777f724721bSzh199473 	 * therefore be described by other structures as well.
778f724721bSzh199473 	 */
779f724721bSzh199473 	dma_area_t		tx_desc;	/* transmit descriptors	*/
780f724721bSzh199473 	dma_area_t		rx_desc[BGE_RECV_RINGS_SPLIT];
781f724721bSzh199473 						/* receive descriptors	*/
782f724721bSzh199473 	dma_area_t		tx_buff[BGE_SPLIT];
783f724721bSzh199473 	dma_area_t		rx_buff[BGE_SPLIT];
784f724721bSzh199473 
785f724721bSzh199473 	/*
786f724721bSzh199473 	 * The memory described by the <dma_area> structures above
787f724721bSzh199473 	 * is carved up into various pieces, which are described by
788f724721bSzh199473 	 * the structures below.
789f724721bSzh199473 	 */
790f724721bSzh199473 	dma_area_t		statistics;	/* describes hardware	*/
791f724721bSzh199473 						/* statistics area	*/
792f724721bSzh199473 	dma_area_t		status_block;	/* describes hardware	*/
793f724721bSzh199473 						/* status block		*/
794f724721bSzh199473 	/*
795f724721bSzh199473 	 * For the BCM5705/5788/5721/5751/5752/5714 and 5715,
796f724721bSzh199473 	 * the statistic block is not available,the statistic counter must
797f724721bSzh199473 	 * be gotten from statistic registers.And bge_statistics_reg_t record
798f724721bSzh199473 	 * the statistic registers value
799f724721bSzh199473 	 */
800931dca7dSgs150176 	bge_statistics_reg_t	*pstats;
801f724721bSzh199473 
802f724721bSzh199473 	/*
803f724721bSzh199473 	 * Runtime read-write data starts here ...
804f724721bSzh199473 	 *
805f724721bSzh199473 	 * 3 Buffer Rings (std/jumbo/mini)
806f724721bSzh199473 	 * 16 Receive (Return) Rings
807f724721bSzh199473 	 * 16 Send Rings
808f724721bSzh199473 	 *
809f724721bSzh199473 	 * Note: they're not necessarily all used.
810f724721bSzh199473 	 */
811f724721bSzh199473 	buff_ring_t		buff[BGE_BUFF_RINGS_MAX]; /*  3*0x0100	*/
812da14cebeSEric Cheng 
813da14cebeSEric Cheng 	/* may be obsoleted */
814f724721bSzh199473 	recv_ring_t		recv[BGE_RECV_RINGS_MAX]; /* 16*0x0090	*/
815f724721bSzh199473 	send_ring_t		send[BGE_SEND_RINGS_MAX]; /* 16*0x0100	*/
816f724721bSzh199473 
817087a28d1SDavid Gwynne 	mac_resource_handle_t macRxResourceHandles[BGE_RECV_RINGS_MAX];
818087a28d1SDavid Gwynne 
819f724721bSzh199473 	/*
820f724721bSzh199473 	 * Locks:
821f724721bSzh199473 	 *
822f724721bSzh199473 	 * Each buffer ring contains its own <rf_lock> which regulates
823f724721bSzh199473 	 *	ring refilling.
824f724721bSzh199473 	 *
825f724721bSzh199473 	 * Each receive (return) ring contains its own <rx_lock> which
826f724721bSzh199473 	 *	protects the critical cyclic counters etc.
827f724721bSzh199473 	 *
828f724721bSzh199473 	 * Each send ring contains two locks: <tx_lock> for the send-path
829f724721bSzh199473 	 * 	protocol data and <tc_lock> for send-buffer recycling.
830f724721bSzh199473 	 *
831f724721bSzh199473 	 * Finally <genlock> is a general lock, protecting most other
832f724721bSzh199473 	 *	operational data in the state structure and chip register
833f724721bSzh199473 	 *	accesses.  It is acquired by the interrupt handler and
834f724721bSzh199473 	 *	most "mode-control" routines.
835f724721bSzh199473 	 *
836f724721bSzh199473 	 * Any of the locks can be acquired singly, but where multiple
837f724721bSzh199473 	 * locks are acquired, they *must* be in the order:
838f724721bSzh199473 	 *
839f724721bSzh199473 	 *	genlock >>> rx_lock >>> rf_lock >>> tx_lock >>> tc_lock.
840f724721bSzh199473 	 *
841f724721bSzh199473 	 * and within any one class of lock the rings must be locked in
842f724721bSzh199473 	 * ascending order (send[0].tc_lock >>> send[1].tc_lock), etc.
843f724721bSzh199473 	 *
844f724721bSzh199473 	 * Note: actually I don't believe there's any need to acquire
845f724721bSzh199473 	 * locks on multiple rings, or even locks of all these classes
846f724721bSzh199473 	 * concurrently; but I've set out the above order so there is a
847f724721bSzh199473 	 * clear definition of lock hierarchy in case it's ever needed.
848f724721bSzh199473 	 *
849f724721bSzh199473 	 * Note: the combinations of locks that are actually held
850f724721bSzh199473 	 * concurrently are:
851f724721bSzh199473 	 *
852f724721bSzh199473 	 *	genlock >>>			(bge_chip_interrupt())
853f724721bSzh199473 	 *		rx_lock[i] >>>		(bge_receive())
854f724721bSzh199473 	 *			rf_lock[n]	(bge_refill())
855f724721bSzh199473 	 *		tc_lock[i]		(bge_recycle())
856f724721bSzh199473 	 */
857f724721bSzh199473 	kmutex_t		genlock[1];
858f724721bSzh199473 	krwlock_t		errlock[1];
859f724721bSzh199473 	kmutex_t		softintrlock[1];
860f724721bSzh199473 
861f724721bSzh199473 	/*
862f724721bSzh199473 	 * Current Ethernet addresses and multicast hash (bitmap) and
863f724721bSzh199473 	 * refcount tables, protected by <genlock>
864f724721bSzh199473 	 */
865f724721bSzh199473 	bge_mac_addr_t		curr_addr[MAC_ADDRESS_REGS_MAX];
866f724721bSzh199473 	uint32_t		mcast_hash[BGE_HASH_TABLE_SIZE/32];
867f724721bSzh199473 	uint8_t			mcast_refs[BGE_HASH_TABLE_SIZE];
868f724721bSzh199473 	uint32_t		unicst_addr_total; /* total unicst addresses */
869f724721bSzh199473 	uint32_t		unicst_addr_avail;
870f724721bSzh199473 					/* unused unicst addr slots */
871f724721bSzh199473 
872f724721bSzh199473 	/*
873f724721bSzh199473 	 * Link state data (protected by genlock)
874f724721bSzh199473 	 */
875f724721bSzh199473 	link_state_t		link_state;
876f724721bSzh199473 
877f724721bSzh199473 	/*
878f724721bSzh199473 	 * Physical layer: copper only
879f724721bSzh199473 	 */
880f724721bSzh199473 	bge_regno_t		phy_mii_addr;	/* should be (const) 1!	*/
881f724721bSzh199473 	uint16_t		phy_gen_status;
882f724721bSzh199473 	uint16_t		phy_aux_status;
883f724721bSzh199473 
884f724721bSzh199473 	/*
885f724721bSzh199473 	 * Physical layer: serdes only
886f724721bSzh199473 	 */
887f724721bSzh199473 	uint32_t		serdes_status;
888f724721bSzh199473 	uint32_t		serdes_advert;
889f724721bSzh199473 	uint32_t		serdes_lpadv;
890f724721bSzh199473 
891f724721bSzh199473 	/*
892f724721bSzh199473 	 * Driver kstats, protected by <genlock> where necessary
893f724721bSzh199473 	 */
894f724721bSzh199473 	kstat_t			*bge_kstats[BGE_KSTAT_COUNT];
895f724721bSzh199473 
896f724721bSzh199473 	/*
897f724721bSzh199473 	 * Miscellaneous operating variables (protected by genlock)
898f724721bSzh199473 	 */
899f724721bSzh199473 	uint64_t		chip_resets;	/* # of chip RESETs	*/
900f724721bSzh199473 	uint64_t		missed_dmas;	/* # of missed DMAs	*/
9015952d588Szh199473 	uint64_t		missed_updates;	/* # of missed updates	*/
902f724721bSzh199473 	enum bge_mac_state	bge_mac_state;	/* definitions above	*/
903f724721bSzh199473 	enum bge_chip_state	bge_chip_state;	/* definitions above	*/
904f724721bSzh199473 	boolean_t		send_hw_tcp_csum;
905f724721bSzh199473 	boolean_t		recv_hw_tcp_csum;
906f724721bSzh199473 	boolean_t		promisc;
907e7801d59Ssowmini 	boolean_t		manual_reset;
908f724721bSzh199473 
909f724721bSzh199473 	/*
910f724721bSzh199473 	 * Miscellaneous operating variables (not synchronised)
911f724721bSzh199473 	 */
912f724721bSzh199473 	uint32_t		watchdog;	/* watches for Tx stall	*/
913f724721bSzh199473 	boolean_t		bge_intr_running;
914f724721bSzh199473 	boolean_t		bge_dma_error;
915931dca7dSgs150176 	boolean_t		tx_resched_needed;
916931dca7dSgs150176 	uint64_t		tx_resched;
917f724721bSzh199473 	uint32_t		factotum_flag;	/* softint pending	*/
918f724721bSzh199473 	uintptr_t		pagemask;
919087a28d1SDavid Gwynne 	boolean_t		rdma_length_bug_on_5719;
920f724721bSzh199473 
921f724721bSzh199473 	/*
922f724721bSzh199473 	 * NDD parameters (protected by genlock)
923f724721bSzh199473 	 */
924f724721bSzh199473 	caddr_t			nd_data_p;
925f724721bSzh199473 
926f724721bSzh199473 	/*
927f724721bSzh199473 	 * A flag to prevent excessive config space accesses
928f724721bSzh199473 	 * on platforms having BCM5714C/15C
929f724721bSzh199473 	 */
930f724721bSzh199473 	boolean_t		lastWriteZeroData;
931f724721bSzh199473 
932f724721bSzh199473 	/*
933f724721bSzh199473 	 * Spare space, plus guard element used to check data integrity
934f724721bSzh199473 	 */
935f724721bSzh199473 	uint64_t		spare[5];
936f724721bSzh199473 	uint64_t		bge_guard;
937f724721bSzh199473 
938f724721bSzh199473 	/*
939f724721bSzh199473 	 * Receive rules configure
940f724721bSzh199473 	 */
941f724721bSzh199473 	bge_recv_rule_t	recv_rules[RECV_RULES_NUM_MAX];
942f724721bSzh199473 
943f724721bSzh199473 #ifdef BGE_IPMI_ASF
944f724721bSzh199473 	boolean_t		asf_enabled;
945f724721bSzh199473 	boolean_t		asf_wordswapped;
946f724721bSzh199473 	boolean_t		asf_newhandshake;
947f724721bSzh199473 	boolean_t		asf_pseudostop;
948f724721bSzh199473 
949f724721bSzh199473 	uint32_t		asf_status;
950f724721bSzh199473 	timeout_id_t		asf_timeout_id;
951f724721bSzh199473 #endif
952e7801d59Ssowmini 	uint32_t		param_en_pause:1,
953e7801d59Ssowmini 				param_en_asym_pause:1,
954e7801d59Ssowmini 				param_en_1000hdx:1,
955e7801d59Ssowmini 				param_en_1000fdx:1,
956e7801d59Ssowmini 				param_en_100fdx:1,
957e7801d59Ssowmini 				param_en_100hdx:1,
958e7801d59Ssowmini 				param_en_10fdx:1,
959e7801d59Ssowmini 				param_en_10hdx:1,
9604045d941Ssowmini 				param_adv_autoneg:1,
9614045d941Ssowmini 				param_adv_1000fdx:1,
9624045d941Ssowmini 				param_adv_1000hdx:1,
9634045d941Ssowmini 				param_adv_100fdx:1,
9644045d941Ssowmini 				param_adv_100hdx:1,
9654045d941Ssowmini 				param_adv_10fdx:1,
9664045d941Ssowmini 				param_adv_10hdx:1,
9674045d941Ssowmini 				param_lp_autoneg:1,
9684045d941Ssowmini 				param_lp_pause:1,
9694045d941Ssowmini 				param_lp_asym_pause:1,
9704045d941Ssowmini 				param_lp_1000fdx:1,
9714045d941Ssowmini 				param_lp_1000hdx:1,
9724045d941Ssowmini 				param_lp_100fdx:1,
9734045d941Ssowmini 				param_lp_100hdx:1,
9744045d941Ssowmini 				param_lp_10fdx:1,
9754045d941Ssowmini 				param_lp_10hdx:1,
9764045d941Ssowmini 				param_link_up:1,
9774045d941Ssowmini 				param_link_autoneg:1,
9784045d941Ssowmini 				param_adv_pause:1,
9794045d941Ssowmini 				param_adv_asym_pause:1,
9804045d941Ssowmini 				param_link_rx_pause:1,
9814045d941Ssowmini 				param_link_tx_pause:1,
9824045d941Ssowmini 				param_pad_to_32:2;
983e7801d59Ssowmini 
984e7801d59Ssowmini 	uint32_t		param_loop_mode;
9854045d941Ssowmini 	uint32_t		param_msi_cnt;
9864045d941Ssowmini 	uint32_t 		param_drain_max;
9874045d941Ssowmini 	uint64_t		param_link_speed;
9884045d941Ssowmini 	link_duplex_t		param_link_duplex;
989087a28d1SDavid Gwynne 	uint32_t		eee_lpi_wait;
9904045d941Ssowmini 
9912adae974Syong tan - Sun Microsystems - Beijing China 	uint64_t		timestamp;
992f724721bSzh199473 } bge_t;
993f724721bSzh199473 
994087a28d1SDavid Gwynne #define CATC_TRIGGER(bgep, data) bge_reg_put32(bgep, 0x0a00, (data))
995087a28d1SDavid Gwynne 
996f724721bSzh199473 /*
997f724721bSzh199473  * 'Progress' bit flags ...
998f724721bSzh199473  */
999f724721bSzh199473 #define	PROGRESS_CFG		0x0001	/* config space mapped		*/
1000f724721bSzh199473 #define	PROGRESS_REGS		0x0002	/* registers mapped		*/
1001f724721bSzh199473 #define	PROGRESS_BUFS		0x0004	/* ring buffers allocated	*/
1002f724721bSzh199473 #define	PROGRESS_RESCHED	0x0010	/* resched softint registered	*/
1003f724721bSzh199473 #define	PROGRESS_FACTOTUM	0x0020	/* factotum softint registered	*/
1004f724721bSzh199473 #define	PROGRESS_HWINT		0x0040	/* h/w interrupt registered	*/
1005f724721bSzh199473 					/* and mutexen initialised	*/
1006f724721bSzh199473 #define	PROGRESS_INTR		0x0080	/* Intrs enabled		*/
1007f724721bSzh199473 #define	PROGRESS_PHY		0x0100	/* PHY initialised		*/
1008f724721bSzh199473 #define	PROGRESS_NDD		0x1000	/* NDD parameters set up	*/
1009f724721bSzh199473 #define	PROGRESS_KSTATS		0x2000	/* kstats created		*/
1010f724721bSzh199473 #define	PROGRESS_READY		0x8000	/* ready for work		*/
1011f724721bSzh199473 
1012f724721bSzh199473 
1013f724721bSzh199473 /*
1014f724721bSzh199473  * Sync a DMA area described by a dma_area_t
1015f724721bSzh199473  */
1016f724721bSzh199473 #define	DMA_SYNC(area, flag)	((void) ddi_dma_sync((area).dma_hdl,	\
1017f724721bSzh199473 				    (area).offset, (area).alength, (flag)))
1018f724721bSzh199473 
1019f724721bSzh199473 /*
1020f724721bSzh199473  * Find the (kernel virtual) address of block of memory
1021f724721bSzh199473  * described by a dma_area_t
1022f724721bSzh199473  */
1023f724721bSzh199473 #define	DMA_VPTR(area)		((area).mem_va)
1024f724721bSzh199473 
1025f724721bSzh199473 /*
1026f724721bSzh199473  * Zero a block of memory described by a dma_area_t
1027f724721bSzh199473  */
1028f724721bSzh199473 #define	DMA_ZERO(area)		bzero(DMA_VPTR(area), (area).alength)
1029f724721bSzh199473 
1030f724721bSzh199473 /*
1031f724721bSzh199473  * Next value of a cyclic index
1032f724721bSzh199473  */
1033931dca7dSgs150176 #define	NEXT(index, limit)	((index)+1 < (limit) ? (index)+1 : 0)
1034f724721bSzh199473 
1035f724721bSzh199473 /*
1036f724721bSzh199473  * Property lookups
1037f724721bSzh199473  */
1038f724721bSzh199473 #define	BGE_PROP_EXISTS(d, n)	ddi_prop_exists(DDI_DEV_T_ANY, (d),	\
1039f724721bSzh199473 					DDI_PROP_DONTPASS, (n))
1040f724721bSzh199473 #define	BGE_PROP_GET_INT(d, n)	ddi_prop_get_int(DDI_DEV_T_ANY, (d),	\
1041f724721bSzh199473 					DDI_PROP_DONTPASS, (n), -1)
1042f724721bSzh199473 
1043f724721bSzh199473 /*
1044f724721bSzh199473  * Copy an ethernet address
1045f724721bSzh199473  */
1046f724721bSzh199473 #define	ethaddr_copy(src, dst)	bcopy((src), (dst), ETHERADDRL)
1047f724721bSzh199473 
1048f724721bSzh199473 /*
1049f724721bSzh199473  * Endian swap
1050f724721bSzh199473  */
1051f724721bSzh199473 /* BEGIN CSTYLED */
1052f724721bSzh199473 #define BGE_BSWAP_32(x)		((((x) & 0xff000000) >> 24)  |		\
1053f724721bSzh199473                                  (((x) & 0x00ff0000) >> 8)   |		\
1054f724721bSzh199473                                  (((x) & 0x0000ff00) << 8)   |		\
1055f724721bSzh199473                                  (((x) & 0x000000ff) << 24))
1056f724721bSzh199473 /* END CSTYLED */
1057f724721bSzh199473 
1058f724721bSzh199473 /*
1059f724721bSzh199473  * Marker value placed at the end of the driver's state
1060f724721bSzh199473  */
1061f724721bSzh199473 #define	BGE_GUARD		0x1919306009031802
1062f724721bSzh199473 
1063f724721bSzh199473 /*
1064f724721bSzh199473  * Bit flags in the 'debug' word ...
1065f724721bSzh199473  */
1066f724721bSzh199473 #define	BGE_DBG_STOP		0x00000001	/* early debug_enter()	*/
1067f724721bSzh199473 #define	BGE_DBG_TRACE		0x00000002	/* general flow tracing	*/
1068087a28d1SDavid Gwynne #define	BGE_DBG_APE		0x00000004	/* low-level APE access	*/
1069087a28d1SDavid Gwynne #define	BGE_DBG_HPSD		0x00000008	/* low-level HPSD access*/
1070f724721bSzh199473 #define	BGE_DBG_REGS		0x00000010	/* low-level accesses	*/
1071f724721bSzh199473 #define	BGE_DBG_MII		0x00000020	/* low-level MII access	*/
1072f724721bSzh199473 #define	BGE_DBG_SEEPROM		0x00000040	/* low-level SEEPROM IO	*/
1073f724721bSzh199473 #define	BGE_DBG_CHIP		0x00000080	/* low(ish)-level code	*/
1074f724721bSzh199473 #define	BGE_DBG_RECV		0x00000100	/* receive-side code	*/
1075f724721bSzh199473 #define	BGE_DBG_SEND		0x00000200	/* packet-send code	*/
1076f724721bSzh199473 #define	BGE_DBG_INT		0x00001000	/* interrupt handler	*/
1077f724721bSzh199473 #define	BGE_DBG_FACT		0x00002000	/* factotum (softint)	*/
1078f724721bSzh199473 #define	BGE_DBG_PHY		0x00010000	/* Copper PHY code	*/
1079f724721bSzh199473 #define	BGE_DBG_SERDES		0x00020000	/* SerDes code		*/
1080f724721bSzh199473 #define	BGE_DBG_PHYS		0x00040000	/* Physical layer code	*/
1081f724721bSzh199473 #define	BGE_DBG_LINK		0x00080000	/* Link status check	*/
1082f724721bSzh199473 #define	BGE_DBG_INIT		0x00100000	/* initialisation	*/
1083f724721bSzh199473 #define	BGE_DBG_NEMO		0x00200000	/* nemo interaction	*/
1084f724721bSzh199473 #define	BGE_DBG_ADDR		0x00400000	/* address-setting code	*/
1085f724721bSzh199473 #define	BGE_DBG_STATS		0x00800000	/* statistics		*/
1086f724721bSzh199473 #define	BGE_DBG_IOCTL		0x01000000	/* ioctl handling	*/
1087f724721bSzh199473 #define	BGE_DBG_LOOP		0x02000000	/* loopback ioctl code	*/
1088f724721bSzh199473 #define	BGE_DBG_PPIO		0x04000000	/* Peek/poke ioctls	*/
1089f724721bSzh199473 #define	BGE_DBG_BADIOC		0x08000000	/* unknown ioctls	*/
1090f724721bSzh199473 #define	BGE_DBG_MCTL		0x10000000	/* mctl (csum) code	*/
1091f724721bSzh199473 #define	BGE_DBG_NDD		0x20000000	/* NDD operations	*/
1092087a28d1SDavid Gwynne #define	BGE_DBG_MEM		0x40000000	/* memory allocations and chunking */
1093f724721bSzh199473 
1094f724721bSzh199473 /*
1095f724721bSzh199473  * Debugging ...
1096f724721bSzh199473  */
1097f724721bSzh199473 #ifdef	DEBUG
1098f724721bSzh199473 #define	BGE_DEBUGGING		1
1099f724721bSzh199473 #else
1100*25e4ececSArne Jansen #define	BGE_DEBUGGING		0
1101f724721bSzh199473 #endif	/* DEBUG */
1102f724721bSzh199473 
1103f724721bSzh199473 
1104f724721bSzh199473 /*
1105f724721bSzh199473  * 'Do-if-debugging' macro.  The parameter <command> should be one or more
1106f724721bSzh199473  * C statements (but without the *final* semicolon), which will either be
1107f724721bSzh199473  * compiled inline or completely ignored, depending on the BGE_DEBUGGING
1108f724721bSzh199473  * compile-time flag.
1109f724721bSzh199473  *
1110f724721bSzh199473  * You should get a compile-time error (at least on a DEBUG build) if
1111f724721bSzh199473  * your statement isn't actually a statement, rather than unexpected
1112f724721bSzh199473  * run-time behaviour caused by unintended matching of if-then-elses etc.
1113f724721bSzh199473  *
1114f724721bSzh199473  * Note that the BGE_DDB() macro itself can only be used as a statement,
1115f724721bSzh199473  * not an expression, and should always be followed by a semicolon.
1116f724721bSzh199473  */
1117f724721bSzh199473 #if	BGE_DEBUGGING
1118f724721bSzh199473 #define	BGE_DDB(command)	do {					\
1119f724721bSzh199473 					{ command; }			\
1120f724721bSzh199473 					_NOTE(CONSTANTCONDITION)	\
1121f724721bSzh199473 				} while (0)
1122f724721bSzh199473 #else 	/* BGE_DEBUGGING */
1123f724721bSzh199473 #define	BGE_DDB(command)	do {					\
1124f724721bSzh199473 					{ _NOTE(EMPTY); }		\
1125f724721bSzh199473 					_NOTE(CONSTANTCONDITION)	\
1126f724721bSzh199473 				} while (0)
1127f724721bSzh199473 #endif	/* BGE_DEBUGGING */
1128f724721bSzh199473 
1129f724721bSzh199473 /*
1130f724721bSzh199473  * 'Internal' macros used to construct the TRACE/DEBUG macros below.
1131f724721bSzh199473  * These provide the primitive conditional-call capability required.
1132f724721bSzh199473  * Note: the parameter <args> is a parenthesised list of the actual
1133f724721bSzh199473  * printf-style arguments to be passed to the debug function ...
1134f724721bSzh199473  */
1135f724721bSzh199473 #define	BGE_XDB(b, w, f, args)	BGE_DDB(if ((b) & (w)) f args)
1136f724721bSzh199473 #define	BGE_GDB(b, args)	BGE_XDB(b, bge_debug, (*bge_gdb()), args)
1137f724721bSzh199473 #define	BGE_LDB(b, args)	BGE_XDB(b, bgep->debug, (*bge_db(bgep)), args)
1138f724721bSzh199473 #define	BGE_CDB(f, args)	BGE_XDB(BGE_DBG, bgep->debug, f, args)
1139f724721bSzh199473 
1140087a28d1SDavid Gwynne #define DEVNAME(_sc) ((_sc)->ifname)
1141087a28d1SDavid Gwynne #define DPRINTF(f, ...) do { cmn_err(CE_NOTE, (f), __VA_ARGS__); } while (0)
1142087a28d1SDavid Gwynne 
1143f724721bSzh199473 /*
1144f724721bSzh199473  * Conditional-print macros.
1145f724721bSzh199473  *
1146f724721bSzh199473  * Define BGE_DBG to be the relevant member of the set of BGE_DBG_* values
1147f724721bSzh199473  * above before using the BGE_GDEBUG() or BGE_DEBUG() macros.  The 'G'
1148f724721bSzh199473  * versions look at the Global debug flag word (bge_debug); the non-G
1149f724721bSzh199473  * versions look in the per-instance data (bgep->debug) and so require a
1150f724721bSzh199473  * variable called 'bgep' to be in scope (and initialised!) before use.
1151f724721bSzh199473  *
1152f724721bSzh199473  * You could redefine BGE_TRC too if you really need two different
1153f724721bSzh199473  * flavours of debugging output in the same area of code, but I don't
1154f724721bSzh199473  * really recommend it.
1155f724721bSzh199473  *
1156f724721bSzh199473  * Note: the parameter <args> is a parenthesised list of the actual
1157f724721bSzh199473  * arguments to be passed to the debug function, usually a printf-style
1158f724721bSzh199473  * format string and corresponding values to be formatted.
1159f724721bSzh199473  */
1160f724721bSzh199473 
1161f724721bSzh199473 #define	BGE_TRC			BGE_DBG_TRACE	/* default 'trace' bit	*/
1162f724721bSzh199473 #define	BGE_GTRACE(args)	BGE_GDB(BGE_TRC, args)
1163f724721bSzh199473 #define	BGE_GDEBUG(args)	BGE_GDB(BGE_DBG, args)
1164f724721bSzh199473 #define	BGE_TRACE(args)		BGE_LDB(BGE_TRC, args)
1165f724721bSzh199473 #define	BGE_DEBUG(args)		BGE_LDB(BGE_DBG, args)
1166f724721bSzh199473 
1167f724721bSzh199473 /*
1168f724721bSzh199473  * Debug-only action macros
1169f724721bSzh199473  */
1170f724721bSzh199473 #define	BGE_BRKPT(bgep, s)	BGE_DDB(bge_dbg_enter(bgep, s))
1171f724721bSzh199473 #define	BGE_MARK(bgep)		BGE_DDB(bge_led_mark(bgep))
1172f724721bSzh199473 #define	BGE_PCICHK(bgep)	BGE_DDB(bge_pci_check(bgep))
1173f724721bSzh199473 #define	BGE_PKTDUMP(args)	BGE_DDB(bge_pkt_dump args)
1174f724721bSzh199473 #define	BGE_REPORT(args)	BGE_DDB(bge_log args)
1175f724721bSzh199473 
1176f724721bSzh199473 /*
1177f724721bSzh199473  * Inter-source-file linkage ...
1178f724721bSzh199473  */
1179f724721bSzh199473 
1180f724721bSzh199473 /* bge_chip.c */
1181f724721bSzh199473 uint16_t bge_mii_get16(bge_t *bgep, bge_regno_t regno);
1182f724721bSzh199473 void bge_mii_put16(bge_t *bgep, bge_regno_t regno, uint16_t value);
1183087a28d1SDavid Gwynne uint16_t bge_phydsp_read(bge_t *bgep, bge_regno_t regno);
1184087a28d1SDavid Gwynne void bge_phydsp_write(bge_t *bgep, bge_regno_t regno, uint16_t value);
1185f724721bSzh199473 uint32_t bge_reg_get32(bge_t *bgep, bge_regno_t regno);
1186f724721bSzh199473 void bge_reg_put32(bge_t *bgep, bge_regno_t regno, uint32_t value);
1187f724721bSzh199473 void bge_reg_set32(bge_t *bgep, bge_regno_t regno, uint32_t bits);
1188f724721bSzh199473 void bge_reg_clr32(bge_t *bgep, bge_regno_t regno, uint32_t bits);
1189087a28d1SDavid Gwynne uint32_t bge_ape_get32(bge_t *bgep, bge_regno_t regno);
1190087a28d1SDavid Gwynne void bge_ape_put32(bge_t *bgep, bge_regno_t regno, uint32_t value);
1191f724721bSzh199473 void bge_mbx_put(bge_t *bgep, bge_regno_t regno, uint64_t value);
1192087a28d1SDavid Gwynne void bge_ape_lock_init(bge_t *bgep);
1193087a28d1SDavid Gwynne int bge_ape_scratchpad_read(bge_t *bgep, uint32_t *data, uint32_t base_off, uint32_t lenToRead);
1194087a28d1SDavid Gwynne int bge_ape_scratchpad_write(bge_t *bgep, uint32_t dstoff, uint32_t *data, uint32_t lenToWrite);
1195087a28d1SDavid Gwynne int bge_nvmem_read32(bge_t *bgep, bge_regno_t addr, uint32_t *dp);
1196087a28d1SDavid Gwynne int bge_nvmem_write32(bge_t *bgep, bge_regno_t addr, uint32_t *dp);
1197f724721bSzh199473 void bge_chip_cfg_init(bge_t *bgep, chip_id_t *cidp, boolean_t enable_dma);
1198f724721bSzh199473 int bge_chip_id_init(bge_t *bgep);
11994d6eaea5Syong tan - Sun Microsystems - Beijing China void bge_chip_coalesce_update(bge_t *bgep);
1200f724721bSzh199473 int bge_chip_start(bge_t *bgep, boolean_t reset_phy);
1201f724721bSzh199473 void bge_chip_stop(bge_t *bgep, boolean_t fault);
120219397407SSherry Moore #ifndef __sparc
120319397407SSherry Moore void bge_chip_stop_nonblocking(bge_t *bgep);
120419397407SSherry Moore #endif
1205f724721bSzh199473 #ifdef BGE_IPMI_ASF
1206f724721bSzh199473 void bge_nic_put32(bge_t *bgep, bge_regno_t addr, uint32_t data);
1207f724721bSzh199473 #pragma	inline(bge_nic_put32)
1208f724721bSzh199473 uint32_t bge_nic_read32(bge_t *bgep, bge_regno_t addr);
1209a4de4ba2Sml149210 void bge_ind_put32(bge_t *bgep, bge_regno_t regno, uint32_t val);
1210a4de4ba2Sml149210 #pragma inline(bge_ind_put32)
1211a4de4ba2Sml149210 uint32_t bge_ind_get32(bge_t *bgep, bge_regno_t regno);
1212a4de4ba2Sml149210 #pragma inline(bge_ind_get32)
1213f724721bSzh199473 void bge_asf_update_status(bge_t *bgep);
1214f724721bSzh199473 void bge_asf_heartbeat(void *bgep);
1215f724721bSzh199473 void bge_asf_stop_timer(bge_t *bgep);
1216f724721bSzh199473 void bge_asf_get_config(bge_t *bgep);
1217f724721bSzh199473 void bge_asf_pre_reset_operations(bge_t *bgep, uint32_t mode);
1218f724721bSzh199473 void bge_asf_post_reset_old_mode(bge_t *bgep, uint32_t mode);
1219f724721bSzh199473 void bge_asf_post_reset_new_mode(bge_t *bgep, uint32_t mode);
1220f724721bSzh199473 int bge_chip_reset(bge_t *bgep, boolean_t enable_dma, uint_t asf_mode);
1221f724721bSzh199473 int bge_chip_sync(bge_t *bgep, boolean_t asf_keeplive);
1222f724721bSzh199473 #else
1223f724721bSzh199473 int bge_chip_reset(bge_t *bgep, boolean_t enable_dma);
1224f724721bSzh199473 int bge_chip_sync(bge_t *bgep);
1225f724721bSzh199473 #endif
1226da14cebeSEric Cheng void bge_chip_blank(void *arg, time_t ticks, uint_t count, int flag);
1227da14cebeSEric Cheng extern mblk_t *bge_poll_ring(void *, int);
1228f724721bSzh199473 uint_t bge_chip_factotum(caddr_t arg);
1229f724721bSzh199473 void bge_chip_cyclic(void *arg);
1230f724721bSzh199473 enum ioc_reply bge_chip_ioctl(bge_t *bgep, queue_t *wq, mblk_t *mp,
1231f724721bSzh199473 	struct iocblk *iocp);
1232f724721bSzh199473 uint_t bge_intr(caddr_t arg1, caddr_t arg2);
1233e7801d59Ssowmini void bge_sync_mac_modes(bge_t *);
1234f724721bSzh199473 extern uint32_t bge_rx_ticks_norm;
1235f724721bSzh199473 extern uint32_t bge_tx_ticks_norm;
1236f724721bSzh199473 extern uint32_t bge_rx_count_norm;
1237f724721bSzh199473 extern uint32_t bge_tx_count_norm;
12385952d588Szh199473 extern boolean_t bge_relaxed_ordering;
12395952d588Szh199473 
1240f724721bSzh199473 void   bge_chip_msi_trig(bge_t *bgep);
1241f724721bSzh199473 
1242f724721bSzh199473 /* bge_kstats.c */
1243f724721bSzh199473 void bge_init_kstats(bge_t *bgep, int instance);
1244f724721bSzh199473 void bge_fini_kstats(bge_t *bgep);
1245f724721bSzh199473 int bge_m_stat(void *arg, uint_t stat, uint64_t *val);
12460dc2366fSVenugopal Iyer int bge_rx_ring_stat(mac_ring_driver_t, uint_t, uint64_t *);
1247f724721bSzh199473 
1248f724721bSzh199473 /* bge_log.c */
1249f724721bSzh199473 #if	BGE_DEBUGGING
1250f724721bSzh199473 void (*bge_db(bge_t *bgep))(const char *fmt, ...);
1251f724721bSzh199473 void (*bge_gdb(void))(const char *fmt, ...);
1252f724721bSzh199473 void bge_pkt_dump(bge_t *bgep, bge_rbd_t *hbp, sw_rbd_t *sdp, const char *msg);
1253f724721bSzh199473 void bge_dbg_enter(bge_t *bgep, const char *msg);
1254f724721bSzh199473 #endif	/* BGE_DEBUGGING */
1255f724721bSzh199473 void bge_problem(bge_t *bgep, const char *fmt, ...);
1256f724721bSzh199473 void bge_log(bge_t *bgep, const char *fmt, ...);
1257f724721bSzh199473 void bge_error(bge_t *bgep, const char *fmt, ...);
1258f724721bSzh199473 void bge_fm_ereport(bge_t *bgep, char *detail);
1259f724721bSzh199473 extern kmutex_t bge_log_mutex[1];
1260f724721bSzh199473 extern uint32_t bge_debug;
1261f724721bSzh199473 
1262f724721bSzh199473 /* bge_main.c */
1263f724721bSzh199473 int bge_restart(bge_t *bgep, boolean_t reset_phy);
1264f724721bSzh199473 int bge_check_acc_handle(bge_t *bgep, ddi_acc_handle_t handle);
1265f724721bSzh199473 int bge_check_dma_handle(bge_t *bgep, ddi_dma_handle_t handle);
1266f724721bSzh199473 void bge_init_rings(bge_t *bgep);
1267f724721bSzh199473 void bge_fini_rings(bge_t *bgep);
1268931dca7dSgs150176 bge_queue_item_t *bge_alloc_txbuf_array(bge_t *bgep, send_ring_t *srp);
1269931dca7dSgs150176 void bge_free_txbuf_arrays(send_ring_t *srp);
1270f724721bSzh199473 int bge_alloc_bufs(bge_t *bgep);
1271f724721bSzh199473 void bge_free_bufs(bge_t *bgep);
1272f724721bSzh199473 void bge_intr_enable(bge_t *bgep);
1273f724721bSzh199473 void bge_intr_disable(bge_t *bgep);
1274e7801d59Ssowmini int bge_reprogram(bge_t *);
1275f724721bSzh199473 
1276087a28d1SDavid Gwynne /* bge_mii.c */
1277087a28d1SDavid Gwynne void bge_eee_init(bge_t *bgep);
1278087a28d1SDavid Gwynne void bge_eee_enable(bge_t * bgep);
1279f724721bSzh199473 int bge_phys_init(bge_t *bgep);
1280f724721bSzh199473 void bge_phys_reset(bge_t *bgep);
1281f724721bSzh199473 int bge_phys_idle(bge_t *bgep);
1282f724721bSzh199473 int bge_phys_update(bge_t *bgep);
1283f724721bSzh199473 boolean_t bge_phys_check(bge_t *bgep);
1284f724721bSzh199473 
1285f724721bSzh199473 /* bge_ndd.c */
1286f724721bSzh199473 int bge_nd_init(bge_t *bgep);
1287f724721bSzh199473 
1288f724721bSzh199473 /* bge_recv.c */
1289f724721bSzh199473 void bge_receive(bge_t *bgep, bge_status_t *bsp);
1290f724721bSzh199473 
1291f724721bSzh199473 /* bge_send.c */
1292f724721bSzh199473 mblk_t *bge_m_tx(void *arg, mblk_t *mp);
1293da14cebeSEric Cheng mblk_t *bge_ring_tx(void *arg, mblk_t *mp);
12942adae974Syong tan - Sun Microsystems - Beijing China boolean_t bge_recycle(bge_t *bgep, bge_status_t *bsp);
1295931dca7dSgs150176 uint_t bge_send_drain(caddr_t arg);
1296f724721bSzh199473 
1297931dca7dSgs150176 /* bge_atomic.c */
1298f724721bSzh199473 uint64_t bge_atomic_reserve(uint64_t *count_p, uint64_t n);
1299f724721bSzh199473 void bge_atomic_renounce(uint64_t *count_p, uint64_t n);
1300f724721bSzh199473 uint64_t bge_atomic_claim(uint64_t *count_p, uint64_t limit);
1301931dca7dSgs150176 uint64_t bge_atomic_next(uint64_t *sp, uint64_t limit);
1302931dca7dSgs150176 void bge_atomic_sub64(uint64_t *count_p, uint64_t n);
1303f724721bSzh199473 uint64_t bge_atomic_clr64(uint64_t *sp, uint64_t bits);
1304f724721bSzh199473 uint32_t bge_atomic_shl32(uint32_t *sp, uint_t count);
1305f724721bSzh199473 
13062fec4481SCarson Tan /* bge_mii_5906.c */
13072fec4481SCarson Tan void bge_adj_volt_5906(bge_t *bgep);
13082fec4481SCarson Tan 
1309f724721bSzh199473 /*
1310f724721bSzh199473  * Reset type
1311f724721bSzh199473  */
1312f724721bSzh199473 #define	BGE_SHUTDOWN_RESET	0
1313f724721bSzh199473 #define	BGE_INIT_RESET		1
1314f724721bSzh199473 #define	BGE_SUSPEND_RESET	2
1315f724721bSzh199473 
1316f724721bSzh199473 /* For asf_status */
1317f724721bSzh199473 #define	ASF_STAT_NONE		0
1318f724721bSzh199473 #define	ASF_STAT_STOP		1
1319f724721bSzh199473 #define	ASF_STAT_RUN		2
1320f724721bSzh199473 #define	ASF_STAT_RUN_INIT	3	/* attached but don't plumb */
1321f724721bSzh199473 
1322f724721bSzh199473 /* ASF modes for bge_reset() and bge_chip_reset() */
1323f724721bSzh199473 #define	ASF_MODE_NONE		0	/* don't launch asf	 */
1324f724721bSzh199473 #define	ASF_MODE_SHUTDOWN	1	/* asf shutdown mode	 */
1325f724721bSzh199473 #define	ASF_MODE_INIT		2	/* asf init mode	 */
1326f724721bSzh199473 #define	ASF_MODE_POST_SHUTDOWN	3	/* only do post-shutdown */
1327f724721bSzh199473 #define	ASF_MODE_POST_INIT	4	/* only do post-init	 */
1328f724721bSzh199473 
1329f724721bSzh199473 #define	BGE_ASF_HEARTBEAT_INTERVAL		1500000
1330f724721bSzh199473 
1331f724721bSzh199473 #ifdef __cplusplus
1332f724721bSzh199473 }
1333f724721bSzh199473 #endif
1334f724721bSzh199473 
1335931dca7dSgs150176 #endif	/* _BGE_IMPL_H */
1336