1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#ifndef _SYS_DMFE_IMPL_H
27#define	_SYS_DMFE_IMPL_H
28
29#include <sys/types.h>
30#include <sys/stream.h>
31#include <sys/strsun.h>
32#include <sys/stat.h>
33#include <sys/pci.h>
34#include <sys/note.h>
35#include <sys/modctl.h>
36#include <sys/kstat.h>
37#include <sys/ethernet.h>
38#include <sys/devops.h>
39#include <sys/debug.h>
40#include <sys/conf.h>
41
42#include <sys/vlan.h>
43
44#include <sys/dditypes.h>
45#include <sys/ddi.h>
46#include <sys/sunddi.h>
47
48#include <sys/mii.h>
49#include <sys/mac_provider.h>
50#include <sys/mac_ether.h>
51#include "dmfe.h"
52
53#define	DMFE_MAX_PKT_SIZE	(VLAN_TAGSZ + ETHERMAX + ETHERFCSL)
54
55
56#define	DRIVER_NAME		"dmfe"
57
58/*
59 * Describes the identity of a specific chip
60 */
61typedef struct {
62	uint16_t		vendor;
63	uint16_t		device;
64	uint8_t			revision;
65	uint8_t			spare;
66} chip_id_t;
67
68/*
69 * Describes the state of a descriptor ring
70 *
71 * NOTE: n_free and next_busy are only used for the Tx descriptors
72 * and are not valid on the receive side.
73 */
74typedef struct {
75	uint32_t		n_desc;		/* # of descriptors	    */
76	uint32_t		n_free;		/* # of free descriptors    */
77	uint32_t		next_free;	/* next index to use/check  */
78	uint32_t		next_busy;	/* next index to reclaim    */
79} desc_state_t;
80
81/*
82 * Describes one chunk of allocated DMA-able memory
83 */
84typedef struct {
85	ddi_dma_handle_t	dma_hdl;
86	ddi_acc_handle_t	acc_hdl;
87	size_t			alength;	/* allocated size	*/
88	caddr_t			mem_va;		/* CPU VA of memory	*/
89	uint32_t		spare1;
90	uint32_t		mem_dvma;	/* DVMA addr of memory	*/
91	caddr_t			setup_va;
92	uint32_t		spare2;
93	uint32_t		setup_dvma;
94	int			spare3;
95	int			ncookies;
96} dma_area_t;
97
98/*
99 * Indexes into the driver-specific kstats, divided into:
100 *
101 *	cyclic activity
102 *	reasons for waking the factotum
103 *	the factotum's activities
104 */
105enum {
106	KS_CYCLIC_RUN,
107
108	KS_INTERRUPT,
109	KS_TX_STALL,
110	KS_CHIP_ERROR,
111
112	KS_FACTOTUM_RUN,
113	KS_RECOVERY,
114
115	KS_DRV_COUNT
116};
117
118/*
119 * Actual state of the DM9102A chip
120 */
121enum chip_state {
122	CHIP_ERROR = -1,			/* error, need reset	*/
123	CHIP_UNKNOWN,				/* Initial state only	*/
124	CHIP_RESET,				/* reset, need init	*/
125	CHIP_STOPPED,				/* Tx/Rx stopped	*/
126	CHIP_TX_ONLY,				/* Tx (re)started	*/
127	CHIP_TX_RX,				/* Tx & Rx (re)started	*/
128	CHIP_RUNNING				/* with interrupts	*/
129};
130
131/*
132 * Required state according to MAC
133 */
134enum mac_state {
135	DMFE_MAC_UNKNOWN,
136	DMFE_MAC_RESET,
137	DMFE_MAC_STOPPED,
138	DMFE_MAC_STARTED
139};
140
141/*
142 * (Internal) return values from ioctl subroutines
143 */
144enum ioc_reply {
145	IOC_INVAL = -1,				/* bad, NAK with EINVAL	*/
146	IOC_DONE,				/* OK, reply sent	*/
147	IOC_REPLY,				/* OK, just send reply	*/
148	IOC_ACK,				/* OK, just send ACK	*/
149	IOC_RESTART,				/* OK, restart & reply	*/
150	IOC_RESTART_ACK				/* OK, restart & ACK	*/
151};
152
153/*
154 * Per-instance soft-state structure
155 */
156typedef struct dmfe {
157	/*
158	 * These fields are set by attach() and unchanged thereafter ...
159	 */
160	dev_info_t		*devinfo;	/* device instance	*/
161	mac_handle_t		mh;		/* MAC instance data	*/
162	mii_handle_t		mii;		/* MII handle		*/
163	ddi_acc_handle_t	io_handle;	/* DDI I/O handle	*/
164	caddr_t			io_reg;		/* mapped registers	*/
165	boolean_t		suspended;
166
167	uint32_t		debug;		/* per-instance debug	*/
168	uint32_t		progress;	/* attach tracking	*/
169	chip_id_t		chipid;
170	uint8_t			vendor_addr[ETHERADDRL];
171	char			ifname[12];	/* "dmfeXXXX"		*/
172
173	dma_area_t		tx_desc;	/* transmit descriptors	*/
174	dma_area_t		tx_buff;	/* transmit buffers	*/
175	dma_area_t		rx_desc;	/* receive descriptors	*/
176	dma_area_t		rx_buff;	/* receive buffers	*/
177
178	ddi_periodic_t		cycid;		/* periodical callback 	*/
179	ddi_softintr_t		factotum_id;	/* identity of factotum	*/
180	ddi_iblock_cookie_t	iblk;
181
182	/*
183	 * Locks:
184	 *
185	 * <milock> is used only by the MII (PHY) level code, to ensure
186	 *	exclusive access during the bit-twiddling needed to send
187	 *	signals along the MII serial bus.  These operations are
188	 *	--S--L--O--W-- so we keep this lock separate, so that
189	 *	faster operations (e.g. interrupts) aren't delayed by
190	 *	waiting for it.
191	 *
192	 * <oplock> is a general "outer" lock, protecting most r/w data
193	 *	and chip state.  It is also acquired by the interrupt
194	 *	handler.
195	 *
196	 * <rxlock> is used to protect the Rx-side buffers, descriptors,
197	 *	and statistics during a single call to dmfe_getp().
198	 *	This is called from inside the interrupt handler, but
199	 *	<oplock> is not held across this call.
200	 *
201	 * <txlock> is an "inner" lock, and protects only the Tx-side
202	 *	data below and in the ring buffers/descriptors.  The
203	 *	Tx-side code uses only this lock, avoiding contention
204	 *	with the receive-side code.
205	 *
206	 * Any of the locks can be acquired singly, but where multiple
207	 * locks are acquired, they *must* be in the order:
208	 *
209	 *	milock >>> oplock >>> rxlock >>> txlock.
210	 *
211	 * *None* of these locks may be held across calls out to the
212	 * MAC routines mac_rx() or mac_tx_notify(); MAC locks must
213	 * be regarded as *outermost* locks in all cases, as they will
214	 * already be held before calling the ioctl() or get_stats()
215	 * entry points - which then have to acquire multiple locks, in
216	 * the order described here.
217	 */
218	kmutex_t		milock[1];
219	kmutex_t		oplock[1];
220	kmutex_t		rxlock[1];
221	kmutex_t		txlock[1];
222
223	/*
224	 * DMFE Extended kstats, protected by <oplock>
225	 */
226	kstat_t			*ksp_drv;
227	kstat_named_t		*knp_drv;
228
229	/*
230	 * GLD statistics; the prefix tells which lock each is protected by.
231	 */
232
233	uint64_t		rx_stats_ipackets;
234	uint64_t		rx_stats_multi;
235	uint64_t		rx_stats_bcast;
236	uint64_t		rx_stats_ierrors;
237	uint64_t		rx_stats_norcvbuf;
238	uint64_t		rx_stats_rbytes;
239	uint64_t		rx_stats_missed;
240	uint64_t		rx_stats_align;
241	uint64_t		rx_stats_fcs;
242	uint64_t		rx_stats_toolong;
243	uint64_t		rx_stats_macrcv_errors;
244	uint64_t		rx_stats_overflow;
245	uint64_t		rx_stats_short;
246
247	uint64_t		tx_stats_oerrors;
248	uint64_t		tx_stats_opackets;
249	uint64_t		tx_stats_multi;
250	uint64_t		tx_stats_bcast;
251	uint64_t		tx_stats_obytes;
252	uint64_t		tx_stats_collisions;
253	uint64_t		tx_stats_nocarrier;
254	uint64_t		tx_stats_xmtlatecoll;
255	uint64_t		tx_stats_excoll;
256	uint64_t		tx_stats_macxmt_errors;
257	uint64_t		tx_stats_jabber;
258	uint64_t		tx_stats_defer;
259	uint64_t		tx_stats_first_coll;
260	uint64_t		tx_stats_multi_coll;
261	uint64_t		tx_stats_underflow;
262
263	/*
264	 * These two sets of desciptors are manipulated during
265	 * packet receive/transmit respectively.
266	 */
267	desc_state_t		rx;		/* describes Rx ring	*/
268	desc_state_t		tx;		/* describes Tx ring	*/
269
270	/*
271	 * Miscellaneous Tx-side variables (protected by txlock)
272	 */
273	uint32_t		tx_pending_tix;	/* tix since reclaim	*/
274	uint8_t			*tx_mcast;	/* bitmask: pkt is mcast */
275	uint8_t			*tx_bcast;	/* bitmask: pkt is bcast */
276
277	/*
278	 * Miscellaneous operating variables (protected by oplock)
279	 */
280	uint16_t		factotum_flag;	/* callback pending	 */
281	uint16_t		need_setup;	/* send-setup pending	 */
282	uint32_t		opmode;		/* operating mode shadow */
283	uint32_t		imask;		/* interrupt mask shadow */
284	enum mac_state		mac_state;	/* RESET/STOPPED/STARTED */
285	enum chip_state		chip_state;	/* see above		 */
286
287	/*
288	 * Current Ethernet address & multicast map ...
289	 */
290	uint8_t			curr_addr[ETHERADDRL];
291	uint8_t			mcast_refs[MCASTBUF_SIZE];
292	boolean_t		addr_set;
293
294	/*
295	 * Guard element used to check data integrity
296	 */
297	uint64_t		dmfe_guard;
298} dmfe_t;
299
300/*
301 * 'Progress' bit flags ...
302 */
303#define	PROGRESS_CONFIG		0x0001	/* config space initialised	*/
304#define	PROGRESS_MUTEX		0x0002	/* mutexes initialized		*/
305#define	PROGRESS_REGS		0x0004	/* registers mapped		*/
306#define	PROGRESS_BUFS		0x0008	/* buffers allocated		*/
307#define	PROGRESS_SOFTINT	0x0010	/* softint registered		*/
308#define	PROGRESS_HWINT		0x0020	/* h/w interrupt registered	*/
309
310/*
311 * Sync a DMA area described by a dma_area_t
312 */
313#define	DMA_SYNC(descp, flag)	((void) ddi_dma_sync((descp)->dma_hdl,	\
314					0, (descp)->alength, flag))
315
316/*
317 * Next value of a cyclic index
318 */
319#define	NEXT(index, limit)	((index)+1 < (limit) ? (index)+1 : 0);
320
321/*
322 * Copy an ethernet address
323 */
324#define	ethaddr_copy(src, dst)	bcopy((src), (dst), ETHERADDRL)
325
326/*
327 * Get/set/increment a (64-bit) driver-private kstat
328 */
329#define	DRV_KS_GET(dmfep, id)						\
330	(((dmfep)->knp_drv) ? ((dmfep)->knp_drv)[id].value.ui64 : 0)
331
332#define	DRV_KS_SET(dmfep, id, val)					\
333	do {								\
334		if ((dmfep)->knp_drv)					\
335			((dmfep)->knp_drv)[id].value.ui64 = (val);	\
336		_NOTE(CONSTANTCONDITION)				\
337	} while (0)
338
339#define	DRV_KS_INC(dmfep, id)						\
340	do {								\
341		if ((dmfep)->knp_drv)					\
342			((dmfep)->knp_drv)[id].value.ui64 += 1;		\
343		_NOTE(CONSTANTCONDITION)				\
344	} while (0)
345
346
347#define	DMFE_GUARD		0x1919603003090218
348
349/*
350 * Inter-source-file linkage ...
351 */
352
353/* dmfe_log.c */
354void dmfe_warning(dmfe_t *dmfep, const char *fmt, ...);
355void dmfe_error(dmfe_t *dmfep, const char *fmt, ...);
356void dmfe_notice(dmfe_t *dmfep, const char *fmt, ...);
357void dmfe_log(dmfe_t *dmfep, const char *fmt, ...);
358void dmfe_log_init(void);
359void dmfe_log_fini(void);
360
361/* dmfe_main.c */
362uint32_t dmfe_chip_get32(dmfe_t *dmfep, off_t offset);
363void dmfe_chip_put32(dmfe_t *dmfep, off_t offset, uint32_t value);
364
365/* dmfe_mii.c */
366void dmfe_read_eeprom(dmfe_t *dmfep, uint16_t addr, uint8_t *ptr, int cnt);
367boolean_t dmfe_init_phy(dmfe_t *dmfep);
368
369#endif	/* _SYS_DMFE_IMPL_H */
370