if_fatmvar.h revision 118596
1184902Srwatson/*
2184902Srwatson * Copyright (c) 2001-2003
3293161Sbrueffer *	Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4293161Sbrueffer * 	All rights reserved.
5293161Sbrueffer *
6293161Sbrueffer * Redistribution and use in source and binary forms, with or without
7293161Sbrueffer * modification, are permitted provided that the following conditions
8293161Sbrueffer * are met:
9293161Sbrueffer * 1. Redistributions of source code must retain the above copyright
10293161Sbrueffer *    notice, this list of conditions and the following disclaimer.
11293161Sbrueffer * 2. Redistributions in binary form must reproduce the above copyright
12293161Sbrueffer *    notice, this list of conditions and the following disclaimer in the
13293161Sbrueffer *    documentation and/or other materials provided with the distribution.
14244265Srwatson *
15244265Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16244265Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17244265Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18244265Srwatson * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19244265Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20243750Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21243750Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22243750Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23243750Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24243750Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25243750Srwatson * SUCH DAMAGE.
26243750Srwatson *
27243750Srwatson * Author: Hartmut Brandt <harti@freebsd.org>
28243750Srwatson *
29243750Srwatson * $FreeBSD: head/sys/dev/fatm/if_fatmvar.h 118596 2003-08-07 10:40:24Z harti $
30243750Srwatson *
31243750Srwatson * Fore PCA200E driver definitions.
32243750Srwatson */
33243750Srwatson/*
34243750Srwatson * Debug statistics of the PCA200 driver
35243750Srwatson */
36243750Srwatsonstruct istats {
37243750Srwatson	uint32_t	cmd_queue_full;
38243750Srwatson	uint32_t	get_stat_errors;
39243750Srwatson	uint32_t	clr_stat_errors;
40243750Srwatson	uint32_t	get_prom_errors;
41243750Srwatson	uint32_t	suni_reg_errors;
42243750Srwatson	uint32_t	tx_queue_full;
43243750Srwatson	uint32_t	tx_queue_almost_full;
44243750Srwatson	uint32_t	tx_pdu2big;
45196031Srwatson	uint32_t	tx_too_many_segs;
46196031Srwatson	uint32_t	tx_retry;
47196031Srwatson	uint32_t	fix_empty;
48196031Srwatson	uint32_t	fix_addr_copy;
49196031Srwatson	uint32_t	fix_addr_noext;
50196031Srwatson	uint32_t	fix_addr_ext;
51195740Srwatson	uint32_t	fix_len_noext;
52195740Srwatson	uint32_t	fix_len_copy;
53195740Srwatson	uint32_t	fix_len;
54195740Srwatson	uint32_t	rx_badvc;
55195740Srwatson	uint32_t	rx_closed;
56195740Srwatson};
57195740Srwatson
58195740Srwatson/*
59195740Srwatson * Addresses on the on-board RAM are expressed as offsets to the
60191273Srwatson * start of that RAM.
61191273Srwatson */
62191273Srwatsontypedef uint32_t cardoff_t;
63191273Srwatson
64191273Srwatson/*
65191273Srwatson * The card uses a number of queues for communication with the host.
66191273Srwatson * Parts of the queue are located on the card (pointers to the status
67191273Srwatson * word and the ioblk and the command blocks), the rest in host memory.
68191273Srwatson * Each of these queues forms a ring, where the head and tail pointers are
69191273Srwatson * managed * either by the card or the host. For the receive queue the
70191273Srwatson * head is managed by the card (and not used altogether by the host) and the
71191273Srwatson * tail by the host - for all other queues its the other way around.
72191273Srwatson * The host resident parts of the queue entries contain pointers to
73191273Srwatson * the host resident status and the host resident ioblk (the latter not for
74191273Srwatson * the command queue) as well as DMA addresses for supply to the card.
75191273Srwatson */
76191273Srwatsonstruct fqelem {
77191273Srwatson	cardoff_t	card;		/* corresponding element on card */
78189279Srwatson	bus_addr_t	card_ioblk;	/* ioblk address to supply to card */
79189279Srwatson	volatile uint32_t *statp;		/* host status pointer */
80189279Srwatson	void		*ioblk;		/* host ioblk (not for commands) */
81189279Srwatson};
82189279Srwatson
83189279Srwatsonstruct fqueue {
84189279Srwatson	struct fqelem	*chunk;		/* pointer to the element array */
85189279Srwatson	int		head;		/* queue head */
86189279Srwatson	int		tail;		/* queue tail */
87189279Srwatson};
88189279Srwatson
89189279Srwatson/*
90189279Srwatson * Queue manipulation macros
91189279Srwatson */
92189279Srwatson#define	NEXT_QUEUE_ENTRY(HEAD,LEN) ((HEAD) = ((HEAD) + 1) % LEN)
93189279Srwatson#define	GET_QUEUE(Q,TYPE,IDX)    (&((TYPE *)(Q).chunk)[(IDX)])
94189279Srwatson
95189279Srwatson/*
96189279Srwatson * Now define structures for the different queues. Each of these structures
97187214Srwatson * must start with a struct fqelem.
98187214Srwatson */
99187214Srwatsonstruct txqueue {		/* transmit queue element */
100187214Srwatson	struct fqelem	q;
101187214Srwatson	struct mbuf	*m;	/* the chain we are transmitting */
102187214Srwatson	bus_dmamap_t	map;	/* map for the packet */
103187214Srwatson};
104187214Srwatson
105187214Srwatsonstruct rxqueue {		/* receive queue element */
106187214Srwatson	struct fqelem	q;
107187214Srwatson};
108187214Srwatson
109187214Srwatsonstruct supqueue {		/* supply queue element */
110187214Srwatson	struct fqelem	q;
111187214Srwatson};
112187214Srwatson
113187214Srwatsonstruct cmdqueue;
114187214Srwatsonstruct fatm_softc;
115187214Srwatson
116186647Srwatsontypedef void (*completion_cb)(struct fatm_softc *, struct cmdqueue *);
117186647Srwatson
118186647Srwatsonstruct cmdqueue {		/* command queue element */
119186647Srwatson	struct fqelem	q;
120186647Srwatson	completion_cb	cb;	/* call on command completion */
121186647Srwatson	int		error;	/* set if error occured */
122186647Srwatson};
123186647Srwatson
124186647Srwatson/*
125186647Srwatson * Card-DMA-able memory is managed by means of the bus_dma* functions.
126186647Srwatson * To allocate a chunk of memory with a specific size and alignment one
127186647Srwatson * has to:
128186647Srwatson *	1. create a DMA tag
129186647Srwatson *	2. allocate the memory
130186647Srwatson *	3. load the memory into a map.
131186647Srwatson * This finally gives the physical address that can be given to the card.
132186647Srwatson * The card can DMA the entire 32-bit space without boundaries. We assume,
133186647Srwatson * that all the allocations can be mapped in one contiguous segment. This
134186647Srwatson * may be wrong in the future if we have more than 32 bit addresses.
135186647Srwatson * Allocation is done at attach time and managed by the following structure.
136186647Srwatson *
137186647Srwatson * This could be done easier with the NetBSD bus_dma* functions. They appear
138186647Srwatson * to be more useful and consistent.
139186647Srwatson */
140186647Srwatsonstruct fatm_mem {
141186647Srwatson	u_int		size;		/* size */
142186647Srwatson	u_int		align;		/* alignment */
143186647Srwatson	bus_dma_tag_t	dmat;		/* DMA tag */
144186647Srwatson	void 		*mem;		/* memory block */
145186647Srwatson	bus_addr_t	paddr;		/* pysical address */
146186647Srwatson	bus_dmamap_t	map;		/* map */
147186647Srwatson};
148186647Srwatson
149186647Srwatson/*
150186647Srwatson * Each of these structures describes one receive buffer while the buffer
151186647Srwatson * is on the card or in the receive return queue. These structures are
152186647Srwatson * allocated at initialisation time together with the DMA maps. The handle that
153186647Srwatson * is given to the card is the index into the array of these structures.
154186647Srwatson */
155186647Srwatsonstruct rbuf {
156186647Srwatson	struct mbuf	*m;	/* the mbuf while we are on the card */
157186647Srwatson	bus_dmamap_t	map;	/* the map */
158186647Srwatson	LIST_ENTRY(rbuf) link;	/* the free list link */
159186647Srwatson};
160186647SrwatsonLIST_HEAD(rbuf_list, rbuf);
161184902Srwatson
162184902Srwatson/*
163184902Srwatson * The driver maintains a list of all open VCCs. Because we
164184902Srwatson * use only VPI=0 and a maximum VCI of 1024, the list is rather an array
165184902Srwatson * than a list. We also store the atm pseudoheader flags here and the
166184902Srwatson * rxhand (aka. protocol block).
167184902Srwatson */
168184902Srwatsonstruct card_vcc {
169184902Srwatson	struct atmio_vcc param;		/* traffic parameters */
170184902Srwatson	void		*rxhand;
171184902Srwatson	uint		vflags;
172184902Srwatson	uint32_t	ipackets;
173184902Srwatson	uint32_t	opackets;
174184902Srwatson	uint32_t	ibytes;
175184902Srwatson	uint32_t	obytes;
176184902Srwatson};
177184902Srwatson
178184902Srwatson#define	FATM_VCC_OPEN		0x00010000	/* is open */
179184902Srwatson#define	FATM_VCC_TRY_OPEN	0x00020000	/* is currently opening */
180184902Srwatson#define	FATM_VCC_TRY_CLOSE	0x00040000	/* is currently closing */
181184902Srwatson#define	FATM_VCC_BUSY		0x00070000	/* one of the above */
182184902Srwatson#define	FATM_VCC_REOPEN		0x00080000	/* reopening during init */
183184902Srwatson
184184902Srwatson/*
185184902Srwatson * Finally the softc structure
186184902Srwatson */
187184902Srwatsonstruct fatm_softc {
188184902Srwatson	struct ifatm	ifatm;		/* common part */
189184902Srwatson	struct mtx	mtx;		/* lock this structure */
190184902Srwatson	struct ifmedia	media;		/* media */
191184902Srwatson
192184902Srwatson	int		init_state;	/* initialisation step */
193184902Srwatson	int		memid;		/* resource id for card memory */
194184902Srwatson	struct resource *memres;	/* resource for card memory */
195184902Srwatson	bus_space_handle_t memh;	/* handle for card memory */
196184902Srwatson	bus_space_tag_t	memt;		/* tag for card memory */
197184902Srwatson	int		irqid;		/* resource id for interrupt */
198184902Srwatson	struct resource *irqres;	/* resource for interrupt */
199184902Srwatson	void		*ih;		/* interrupt handler */
200184902Srwatson
201184902Srwatson	bus_dma_tag_t	parent_dmat;	/* parent DMA tag */
202184902Srwatson	struct fatm_mem	stat_mem;	/* memory for status blocks */
203184902Srwatson	struct fatm_mem	txq_mem;	/* TX descriptor queue */
204184902Srwatson	struct fatm_mem	rxq_mem;	/* RX descriptor queue */
205184902Srwatson	struct fatm_mem	s1q_mem;	/* Small buffer 1 queue */
206184902Srwatson	struct fatm_mem	l1q_mem;	/* Large buffer 1 queue */
207184902Srwatson	struct fatm_mem	prom_mem;	/* PROM memory */
208184902Srwatson
209184902Srwatson	struct fqueue	txqueue;	/* transmission queue */
210184902Srwatson	struct fqueue	rxqueue;	/* receive queue */
211184902Srwatson	struct fqueue	s1queue;	/* SMALL S1 queue */
212184902Srwatson	struct fqueue	l1queue;	/* LARGE S1 queue */
213184902Srwatson	struct fqueue	cmdqueue;	/* command queue */
214184902Srwatson
215184902Srwatson	/* fields for access to the SUNI registers */
216184902Srwatson	struct fatm_mem	reg_mem;	/* DMAable memory for readregs */
217184902Srwatson	struct cv	cv_regs;	/* to serialize access to reg_mem */
218184902Srwatson
219184902Srwatson	/* fields for access to statistics */
220184902Srwatson	struct fatm_mem	sadi_mem;	/* sadistics memory */
221184902Srwatson	struct cv	cv_stat;	/* to serialize access to sadi_mem */
222184902Srwatson
223184902Srwatson	u_int		flags;
224184902Srwatson#define	FATM_STAT_INUSE	0x0001
225184902Srwatson#define	FATM_REGS_INUSE	0x0002
226184902Srwatson	u_int		txcnt;		/* number of used transmit desc */
227184902Srwatson	int		retry_tx;	/* keep mbufs in queue if full */
228184902Srwatson
229184902Srwatson	struct card_vcc	**vccs;		/* table of vccs */
230184902Srwatson	int		open_vccs;	/* number of vccs in use */
231184902Srwatson	int		small_cnt;	/* number of buffers owned by card */
232184902Srwatson	int		large_cnt;	/* number of buffers owned by card */
233184902Srwatson	uma_zone_t	vcc_zone;	/* allocator for VCCs */
234184902Srwatson
235184902Srwatson	/* receiving */
236184902Srwatson	struct rbuf	*rbufs;		/* rbuf array */
237184902Srwatson	struct rbuf_list rbuf_free;	/* free rbufs list */
238184902Srwatson	struct rbuf_list rbuf_used;	/* used rbufs list */
239184902Srwatson	u_int		rbuf_total;	/* total number of buffs */
240184902Srwatson	bus_dma_tag_t	rbuf_tag;	/* tag for rbuf mapping */
241184902Srwatson
242184902Srwatson	/* transmission */
243184902Srwatson	bus_dma_tag_t	tx_tag;		/* transmission tag */
244184902Srwatson
245184902Srwatson	uint32_t	heartbeat;	/* last heartbeat */
246184902Srwatson	u_int		stop_cnt;	/* how many times checked */
247184902Srwatson
248184902Srwatson	struct istats	istats;		/* internal statistics */
249184902Srwatson
250184902Srwatson	/* SUNI state */
251184902Srwatson	struct utopia	utopia;
252184902Srwatson
253184902Srwatson	/* sysctl support */
254184902Srwatson	struct sysctl_ctx_list sysctl_ctx;
255184902Srwatson	struct sysctl_oid *sysctl_tree;
256184902Srwatson
257184902Srwatson#ifdef FATM_DEBUG
258184902Srwatson	/* debugging */
259184902Srwatson	u_int		debug;
260184902Srwatson#endif
261184902Srwatson};
262184902Srwatson
263184902Srwatson#ifndef FATM_DEBUG
264184902Srwatson#define	FATM_LOCK(SC)		mtx_lock(&(SC)->mtx)
265184902Srwatson#define	FATM_UNLOCK(SC)		mtx_unlock(&(SC)->mtx)
266184902Srwatson#else
267184902Srwatson#define	FATM_LOCK(SC)	do {					\
268184902Srwatson	DBG(SC, LOCK, ("locking in line %d", __LINE__));	\
269184902Srwatson	mtx_lock(&(SC)->mtx);					\
270184902Srwatson    } while (0)
271184902Srwatson#define	FATM_UNLOCK(SC)	do {					\
272184902Srwatson	DBG(SC, LOCK, ("unlocking in line %d", __LINE__));	\
273184902Srwatson	mtx_unlock(&(SC)->mtx);					\
274184902Srwatson    } while (0)
275184902Srwatson#endif
276184902Srwatson#define	FATM_CHECKLOCK(SC)	mtx_assert(&sc->mtx, MA_OWNED)
277184902Srwatson
278184902Srwatson/*
279184902Srwatson * Macros to access host memory fields that are also access by the card.
280184902Srwatson * These fields need to little-endian always.
281184902Srwatson */
282184902Srwatson#define	H_GETSTAT(STATP)	(le32toh(*(STATP)))
283184902Srwatson#define	H_SETSTAT(STATP, S)	do { *(STATP) = htole32(S); } while (0)
284184902Srwatson#define	H_SETDESC(DESC, D)	do { (DESC) = htole32(D); } while (0)
285184902Srwatson
286184902Srwatson#ifdef notyet
287184902Srwatson#define	H_SYNCSTAT_POSTREAD(SC, P)					\
288184902Srwatson	bus_dmamap_sync_size((SC)->stat_mem.dmat,			\
289184902Srwatson	    (SC)->stat_mem.map,						\
290184902Srwatson	    (volatile char *)(P) - (volatile char *)(SC)->stat_mem.mem,	\
291184902Srwatson	    sizeof(volatile uint32_t), BUS_DMASYNC_POSTREAD)
292184902Srwatson
293184902Srwatson#define	H_SYNCSTAT_PREWRITE(SC, P)					\
294184902Srwatson	bus_dmamap_sync_size((SC)->stat_mem.dmat,			\
295184902Srwatson	    (SC)->stat_mem.map,						\
296184902Srwatson	    (volatile char *)(P) - (volatile char *)(SC)->stat_mem.mem,	\
297184902Srwatson	    sizeof(volatile uint32_t), BUS_DMASYNC_PREWRITE)
298184902Srwatson
299184902Srwatson#define	H_SYNCQ_PREWRITE(M, P, SZ)					\
300184902Srwatson	bus_dmamap_sync_size((M)->dmat, (M)->map,			\
301184902Srwatson	    (volatile char *)(P) - (volatile char *)(M)->mem, (SZ),	\
302184902Srwatson	    BUS_DMASYNC_PREWRITE)
303184902Srwatson
304184902Srwatson#define	H_SYNCQ_POSTREAD(M, P, SZ)					\
305184902Srwatson	bus_dmamap_sync_size((M)->dmat, (M)->map,			\
306184902Srwatson	    (volatile char *)(P) - (volatile char *)(M)->mem, (SZ),	\
307184902Srwatson	    BUS_DMASYNC_POSTREAD)
308184902Srwatson#else
309184902Srwatson#define	H_SYNCSTAT_POSTREAD(SC, P)	do { } while (0)
310184902Srwatson#define	H_SYNCSTAT_PREWRITE(SC, P)	do { } while (0)
311184902Srwatson#define	H_SYNCQ_PREWRITE(M, P, SZ)	do { } while (0)
312184902Srwatson#define	H_SYNCQ_POSTREAD(M, P, SZ)	do { } while (0)
313184902Srwatson#endif
314184902Srwatson
315184902Srwatson/*
316184902Srwatson * Macros to manipulate VPVCs
317184902Srwatson */
318184902Srwatson#define	MKVPVC(VPI,VCI)	(((VPI) << 16) | (VCI))
319184902Srwatson#define	GETVPI(VPVC)		(((VPVC) >> 16) & 0xff)
320184902Srwatson#define	GETVCI(VPVC)		((VPVC) & 0xffff)
321184902Srwatson
322184902Srwatson/*
323184902Srwatson * These macros encapsulate the bus_space functions for better readabiliy.
324184902Srwatson */
325184902Srwatson#define	WRITE4(SC, OFF, VAL) bus_space_write_4(SC->memt, SC->memh, OFF, VAL)
326184902Srwatson#define	WRITE1(SC, OFF, VAL) bus_space_write_1(SC->memt, SC->memh, OFF, VAL)
327184902Srwatson
328184902Srwatson#define	READ4(SC, OFF) bus_space_read_4(SC->memt, SC->memh, OFF)
329184902Srwatson#define	READ1(SC, OFF) bus_space_read_1(SC->memt, SC->memh, OFF)
330184902Srwatson
331184902Srwatson#define	BARRIER_R(SC) \
332184902Srwatson	bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \
333184902Srwatson	    BUS_SPACE_BARRIER_READ)
334184902Srwatson#define	BARRIER_W(SC) \
335184902Srwatson	bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \
336184902Srwatson	    BUS_SPACE_BARRIER_WRITE)
337184902Srwatson#define	BARRIER_RW(SC) \
338184902Srwatson	bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \
339184902Srwatson	    BUS_SPACE_BARRIER_WRITE|BUS_SPACE_BARRIER_READ)
340184902Srwatson
341184902Srwatson#ifdef FATM_DEBUG
342184902Srwatson#define	DBG(SC, FL, PRINT) do {						\
343184902Srwatson	if ((SC)->debug & DBG_##FL) { 					\
344184902Srwatson		if_printf(&(SC)->ifatm.ifnet, "%s: ", __func__);	\
345184902Srwatson		printf PRINT;						\
346184902Srwatson		printf("\n");						\
347184902Srwatson	}								\
348184902Srwatson    } while (0)
349184902Srwatson#define	DBGC(SC, FL, PRINT) do {					\
350184902Srwatson	if ((SC)->debug & DBG_##FL) 					\
351184902Srwatson		printf PRINT;						\
352184902Srwatson    } while (0)
353184902Srwatson
354184902Srwatsonenum {
355184902Srwatson	DBG_RCV		= 0x0001,
356184902Srwatson	DBG_XMIT	= 0x0002,
357184902Srwatson	DBG_VCC		= 0x0004,
358184902Srwatson	DBG_IOCTL	= 0x0008,
359184902Srwatson	DBG_ATTACH	= 0x0010,
360184902Srwatson	DBG_INIT	= 0x0020,
361184902Srwatson	DBG_DMA		= 0x0040,
362184902Srwatson	DBG_BEAT	= 0x0080,
363184902Srwatson	DBG_UART	= 0x0100,
364184902Srwatson	DBG_LOCK	= 0x0200,
365184902Srwatson
366184902Srwatson	DBG_ALL		= 0xffff
367184902Srwatson};
368184902Srwatson
369184902Srwatson#else
370184902Srwatson#define	DBG(SC, FL, PRINT)
371184902Srwatson#define	DBGC(SC, FL, PRINT)
372184902Srwatson#endif
373184902Srwatson
374184902Srwatson/*
375184902Srwatson * Configuration.
376184902Srwatson *
377184902Srwatson * This section contains tunable parameters and dependend defines.
378184902Srwatson */
379184902Srwatson#define	FATM_CMD_QLEN		16		/* command queue length */
380184902Srwatson#ifndef TEST_DMA_SYNC
381184902Srwatson#define	FATM_TX_QLEN		128		/* transmit queue length */
382184902Srwatson#define	FATM_RX_QLEN		64		/* receive queue length */
383184902Srwatson#else
384184902Srwatson#define	FATM_TX_QLEN		8		/* transmit queue length */
385184902Srwatson#define	FATM_RX_QLEN		8		/* receive queue length */
386184902Srwatson#endif
387184902Srwatson
388184902Srwatson#define	SMALL_SUPPLY_QLEN	16
389184902Srwatson#define	SMALL_POOL_SIZE		256
390184902Srwatson#define	SMALL_SUPPLY_BLKSIZE	8
391184902Srwatson
392184902Srwatson#define	LARGE_SUPPLY_QLEN	16
393184902Srwatson#define	LARGE_POOL_SIZE		128
394184902Srwatson#define	LARGE_SUPPLY_BLKSIZE	8
395184902Srwatson