1/*
2 * Copyright (c) 2001-2003
3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * Author: Hartmut Brandt <harti@freebsd.org>
28 *
29 * $FreeBSD: head/sys/dev/fatm/if_fatmvar.h 118607 2003-08-07 15:04:27Z jhb $
30 *
31 * Fore PCA200E driver definitions.
32 */
33/*
34 * Debug statistics of the PCA200 driver
35 */
36struct istats {
37 uint32_t cmd_queue_full;
38 uint32_t get_stat_errors;
39 uint32_t clr_stat_errors;
40 uint32_t get_prom_errors;
41 uint32_t suni_reg_errors;
42 uint32_t tx_queue_full;
43 uint32_t tx_queue_almost_full;
44 uint32_t tx_pdu2big;
45 uint32_t tx_too_many_segs;
46 uint32_t tx_retry;
47 uint32_t fix_empty;
48 uint32_t fix_addr_copy;
49 uint32_t fix_addr_noext;
50 uint32_t fix_addr_ext;
51 uint32_t fix_len_noext;
52 uint32_t fix_len_copy;
53 uint32_t fix_len;
54 uint32_t rx_badvc;
55 uint32_t rx_closed;
56};
57
58/*
59 * Addresses on the on-board RAM are expressed as offsets to the
60 * start of that RAM.
61 */
62typedef uint32_t cardoff_t;
63
64/*
65 * The card uses a number of queues for communication with the host.
66 * Parts of the queue are located on the card (pointers to the status
67 * word and the ioblk and the command blocks), the rest in host memory.
68 * Each of these queues forms a ring, where the head and tail pointers are
69 * managed * either by the card or the host. For the receive queue the
70 * head is managed by the card (and not used altogether by the host) and the
71 * tail by the host - for all other queues its the other way around.
72 * The host resident parts of the queue entries contain pointers to
73 * the host resident status and the host resident ioblk (the latter not for
74 * the command queue) as well as DMA addresses for supply to the card.
75 */
76struct fqelem {
77 cardoff_t card; /* corresponding element on card */
78 bus_addr_t card_ioblk; /* ioblk address to supply to card */
79 volatile uint32_t *statp; /* host status pointer */
80 void *ioblk; /* host ioblk (not for commands) */
81};
82
83struct fqueue {
84 struct fqelem *chunk; /* pointer to the element array */
85 int head; /* queue head */
86 int tail; /* queue tail */
87};
88
89/*
90 * Queue manipulation macros
91 */
92#define NEXT_QUEUE_ENTRY(HEAD,LEN) ((HEAD) = ((HEAD) + 1) % LEN)
93#define GET_QUEUE(Q,TYPE,IDX) (&((TYPE *)(Q).chunk)[(IDX)])
94
95/*
96 * Now define structures for the different queues. Each of these structures
97 * must start with a struct fqelem.
98 */
99struct txqueue { /* transmit queue element */
100 struct fqelem q;
101 struct mbuf *m; /* the chain we are transmitting */
102 bus_dmamap_t map; /* map for the packet */
103};
104
105struct rxqueue { /* receive queue element */
106 struct fqelem q;
107};
108
109struct supqueue { /* supply queue element */
110 struct fqelem q;
111};
112
113struct cmdqueue;
114struct fatm_softc;
115
116typedef void (*completion_cb)(struct fatm_softc *, struct cmdqueue *);
117
118struct cmdqueue { /* command queue element */
119 struct fqelem q;
120 completion_cb cb; /* call on command completion */
121 int error; /* set if error occured */
122};
123
124/*
125 * Card-DMA-able memory is managed by means of the bus_dma* functions.
126 * To allocate a chunk of memory with a specific size and alignment one
127 * has to:
128 * 1. create a DMA tag
129 * 2. allocate the memory
130 * 3. load the memory into a map.
131 * This finally gives the physical address that can be given to the card.
132 * The card can DMA the entire 32-bit space without boundaries. We assume,
133 * that all the allocations can be mapped in one contiguous segment. This
134 * may be wrong in the future if we have more than 32 bit addresses.
135 * Allocation is done at attach time and managed by the following structure.
136 *
137 * This could be done easier with the NetBSD bus_dma* functions. They appear
138 * to be more useful and consistent.
139 */
140struct fatm_mem {
141 u_int size; /* size */
142 u_int align; /* alignment */
143 bus_dma_tag_t dmat; /* DMA tag */
144 void *mem; /* memory block */
145 bus_addr_t paddr; /* pysical address */
146 bus_dmamap_t map; /* map */
147};
148
149/*
150 * Each of these structures describes one receive buffer while the buffer
151 * is on the card or in the receive return queue. These structures are
152 * allocated at initialisation time together with the DMA maps. The handle that
153 * is given to the card is the index into the array of these structures.
154 */
155struct rbuf {
156 struct mbuf *m; /* the mbuf while we are on the card */
157 bus_dmamap_t map; /* the map */
158 LIST_ENTRY(rbuf) link; /* the free list link */
159};
160LIST_HEAD(rbuf_list, rbuf);
161
162/*
163 * The driver maintains a list of all open VCCs. Because we
164 * use only VPI=0 and a maximum VCI of 1024, the list is rather an array
165 * than a list. We also store the atm pseudoheader flags here and the
166 * rxhand (aka. protocol block).
167 */
168struct card_vcc {
169 struct atmio_vcc param; /* traffic parameters */
170 void *rxhand;
171 u_int vflags;
172 uint32_t ipackets;
173 uint32_t opackets;
174 uint32_t ibytes;
175 uint32_t obytes;
176};
177
178#define FATM_VCC_OPEN 0x00010000 /* is open */
179#define FATM_VCC_TRY_OPEN 0x00020000 /* is currently opening */
180#define FATM_VCC_TRY_CLOSE 0x00040000 /* is currently closing */
181#define FATM_VCC_BUSY 0x00070000 /* one of the above */
182#define FATM_VCC_REOPEN 0x00080000 /* reopening during init */
183
184/*
185 * Finally the softc structure
186 */
187struct fatm_softc {
188 struct ifatm ifatm; /* common part */
189 struct mtx mtx; /* lock this structure */
190 struct ifmedia media; /* media */
191
192 int init_state; /* initialisation step */
193 int memid; /* resource id for card memory */
194 struct resource *memres; /* resource for card memory */
195 bus_space_handle_t memh; /* handle for card memory */
196 bus_space_tag_t memt; /* tag for card memory */
197 int irqid; /* resource id for interrupt */
198 struct resource *irqres; /* resource for interrupt */
199 void *ih; /* interrupt handler */
200
201 bus_dma_tag_t parent_dmat; /* parent DMA tag */
202 struct fatm_mem stat_mem; /* memory for status blocks */
203 struct fatm_mem txq_mem; /* TX descriptor queue */
204 struct fatm_mem rxq_mem; /* RX descriptor queue */
205 struct fatm_mem s1q_mem; /* Small buffer 1 queue */
206 struct fatm_mem l1q_mem; /* Large buffer 1 queue */
207 struct fatm_mem prom_mem; /* PROM memory */
208
209 struct fqueue txqueue; /* transmission queue */
210 struct fqueue rxqueue; /* receive queue */
211 struct fqueue s1queue; /* SMALL S1 queue */
212 struct fqueue l1queue; /* LARGE S1 queue */
213 struct fqueue cmdqueue; /* command queue */
214
215 /* fields for access to the SUNI registers */
216 struct fatm_mem reg_mem; /* DMAable memory for readregs */
217 struct cv cv_regs; /* to serialize access to reg_mem */
218
219 /* fields for access to statistics */
220 struct fatm_mem sadi_mem; /* sadistics memory */
221 struct cv cv_stat; /* to serialize access to sadi_mem */
222
223 u_int flags;
224#define FATM_STAT_INUSE 0x0001
225#define FATM_REGS_INUSE 0x0002
226 u_int txcnt; /* number of used transmit desc */
227 int retry_tx; /* keep mbufs in queue if full */
228
229 struct card_vcc **vccs; /* table of vccs */
230 int open_vccs; /* number of vccs in use */
231 int small_cnt; /* number of buffers owned by card */
232 int large_cnt; /* number of buffers owned by card */
233 uma_zone_t vcc_zone; /* allocator for VCCs */
234
235 /* receiving */
236 struct rbuf *rbufs; /* rbuf array */
237 struct rbuf_list rbuf_free; /* free rbufs list */
238 struct rbuf_list rbuf_used; /* used rbufs list */
239 u_int rbuf_total; /* total number of buffs */
240 bus_dma_tag_t rbuf_tag; /* tag for rbuf mapping */
241
242 /* transmission */
243 bus_dma_tag_t tx_tag; /* transmission tag */
244
245 uint32_t heartbeat; /* last heartbeat */
246 u_int stop_cnt; /* how many times checked */
247
248 struct istats istats; /* internal statistics */
249
250 /* SUNI state */
251 struct utopia utopia;
252
253 /* sysctl support */
254 struct sysctl_ctx_list sysctl_ctx;
255 struct sysctl_oid *sysctl_tree;
256
257#ifdef FATM_DEBUG
258 /* debugging */
259 u_int debug;
260#endif
261};
262
263#ifndef FATM_DEBUG
264#define FATM_LOCK(SC) mtx_lock(&(SC)->mtx)
265#define FATM_UNLOCK(SC) mtx_unlock(&(SC)->mtx)
266#else
267#define FATM_LOCK(SC) do { \
268 DBG(SC, LOCK, ("locking in line %d", __LINE__)); \
269 mtx_lock(&(SC)->mtx); \
270 } while (0)
271#define FATM_UNLOCK(SC) do { \
272 DBG(SC, LOCK, ("unlocking in line %d", __LINE__)); \
273 mtx_unlock(&(SC)->mtx); \
274 } while (0)
275#endif
276#define FATM_CHECKLOCK(SC) mtx_assert(&sc->mtx, MA_OWNED)
277
278/*
279 * Macros to access host memory fields that are also access by the card.
280 * These fields need to little-endian always.
281 */
282#define H_GETSTAT(STATP) (le32toh(*(STATP)))
283#define H_SETSTAT(STATP, S) do { *(STATP) = htole32(S); } while (0)
284#define H_SETDESC(DESC, D) do { (DESC) = htole32(D); } while (0)
285
286#ifdef notyet
287#define H_SYNCSTAT_POSTREAD(SC, P) \
288 bus_dmamap_sync_size((SC)->stat_mem.dmat, \
289 (SC)->stat_mem.map, \
290 (volatile char *)(P) - (volatile char *)(SC)->stat_mem.mem, \
291 sizeof(volatile uint32_t), BUS_DMASYNC_POSTREAD)
292
293#define H_SYNCSTAT_PREWRITE(SC, P) \
294 bus_dmamap_sync_size((SC)->stat_mem.dmat, \
295 (SC)->stat_mem.map, \
296 (volatile char *)(P) - (volatile char *)(SC)->stat_mem.mem, \
297 sizeof(volatile uint32_t), BUS_DMASYNC_PREWRITE)
298
299#define H_SYNCQ_PREWRITE(M, P, SZ) \
300 bus_dmamap_sync_size((M)->dmat, (M)->map, \
301 (volatile char *)(P) - (volatile char *)(M)->mem, (SZ), \
302 BUS_DMASYNC_PREWRITE)
303
304#define H_SYNCQ_POSTREAD(M, P, SZ) \
305 bus_dmamap_sync_size((M)->dmat, (M)->map, \
306 (volatile char *)(P) - (volatile char *)(M)->mem, (SZ), \
307 BUS_DMASYNC_POSTREAD)
308#else
309#define H_SYNCSTAT_POSTREAD(SC, P) do { } while (0)
310#define H_SYNCSTAT_PREWRITE(SC, P) do { } while (0)
311#define H_SYNCQ_PREWRITE(M, P, SZ) do { } while (0)
312#define H_SYNCQ_POSTREAD(M, P, SZ) do { } while (0)
313#endif
314
315/*
316 * Macros to manipulate VPVCs
317 */
318#define MKVPVC(VPI,VCI) (((VPI) << 16) | (VCI))
319#define GETVPI(VPVC) (((VPVC) >> 16) & 0xff)
320#define GETVCI(VPVC) ((VPVC) & 0xffff)
321
322/*
323 * These macros encapsulate the bus_space functions for better readabiliy.
324 */
325#define WRITE4(SC, OFF, VAL) bus_space_write_4(SC->memt, SC->memh, OFF, VAL)
326#define WRITE1(SC, OFF, VAL) bus_space_write_1(SC->memt, SC->memh, OFF, VAL)
327
328#define READ4(SC, OFF) bus_space_read_4(SC->memt, SC->memh, OFF)
329#define READ1(SC, OFF) bus_space_read_1(SC->memt, SC->memh, OFF)
330
331#define BARRIER_R(SC) \
332 bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \
333 BUS_SPACE_BARRIER_READ)
334#define BARRIER_W(SC) \
335 bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \
336 BUS_SPACE_BARRIER_WRITE)
337#define BARRIER_RW(SC) \
338 bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \
339 BUS_SPACE_BARRIER_WRITE|BUS_SPACE_BARRIER_READ)
340
341#ifdef FATM_DEBUG
342#define DBG(SC, FL, PRINT) do { \
343 if ((SC)->debug & DBG_##FL) { \
344 if_printf(&(SC)->ifatm.ifnet, "%s: ", __func__); \
345 printf PRINT; \
346 printf("\n"); \
347 } \
348 } while (0)
349#define DBGC(SC, FL, PRINT) do { \
350 if ((SC)->debug & DBG_##FL) \
351 printf PRINT; \
352 } while (0)
353
354enum {
355 DBG_RCV = 0x0001,
356 DBG_XMIT = 0x0002,
357 DBG_VCC = 0x0004,
358 DBG_IOCTL = 0x0008,
359 DBG_ATTACH = 0x0010,
360 DBG_INIT = 0x0020,
361 DBG_DMA = 0x0040,
362 DBG_BEAT = 0x0080,
363 DBG_UART = 0x0100,
364 DBG_LOCK = 0x0200,
365
366 DBG_ALL = 0xffff
367};
368
369#else
370#define DBG(SC, FL, PRINT)
371#define DBGC(SC, FL, PRINT)
372#endif
373
374/*
375 * Configuration.
376 *
377 * This section contains tunable parameters and dependend defines.
378 */
379#define FATM_CMD_QLEN 16 /* command queue length */
380#ifndef TEST_DMA_SYNC
381#define FATM_TX_QLEN 128 /* transmit queue length */
382#define FATM_RX_QLEN 64 /* receive queue length */
383#else
384#define FATM_TX_QLEN 8 /* transmit queue length */
385#define FATM_RX_QLEN 8 /* receive queue length */
386#endif
387
388#define SMALL_SUPPLY_QLEN 16
389#define SMALL_POOL_SIZE 256
390#define SMALL_SUPPLY_BLKSIZE 8
391
392#define LARGE_SUPPLY_QLEN 16
393#define LARGE_POOL_SIZE 128
394#define LARGE_SUPPLY_BLKSIZE 8
2 * Copyright (c) 2001-2003
3 * Fraunhofer Institute for Open Communication Systems (FhG Fokus).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * Author: Hartmut Brandt <harti@freebsd.org>
28 *
29 * $FreeBSD: head/sys/dev/fatm/if_fatmvar.h 118607 2003-08-07 15:04:27Z jhb $
30 *
31 * Fore PCA200E driver definitions.
32 */
33/*
34 * Debug statistics of the PCA200 driver
35 */
36struct istats {
37 uint32_t cmd_queue_full;
38 uint32_t get_stat_errors;
39 uint32_t clr_stat_errors;
40 uint32_t get_prom_errors;
41 uint32_t suni_reg_errors;
42 uint32_t tx_queue_full;
43 uint32_t tx_queue_almost_full;
44 uint32_t tx_pdu2big;
45 uint32_t tx_too_many_segs;
46 uint32_t tx_retry;
47 uint32_t fix_empty;
48 uint32_t fix_addr_copy;
49 uint32_t fix_addr_noext;
50 uint32_t fix_addr_ext;
51 uint32_t fix_len_noext;
52 uint32_t fix_len_copy;
53 uint32_t fix_len;
54 uint32_t rx_badvc;
55 uint32_t rx_closed;
56};
57
58/*
59 * Addresses on the on-board RAM are expressed as offsets to the
60 * start of that RAM.
61 */
62typedef uint32_t cardoff_t;
63
64/*
65 * The card uses a number of queues for communication with the host.
66 * Parts of the queue are located on the card (pointers to the status
67 * word and the ioblk and the command blocks), the rest in host memory.
68 * Each of these queues forms a ring, where the head and tail pointers are
69 * managed * either by the card or the host. For the receive queue the
70 * head is managed by the card (and not used altogether by the host) and the
71 * tail by the host - for all other queues its the other way around.
72 * The host resident parts of the queue entries contain pointers to
73 * the host resident status and the host resident ioblk (the latter not for
74 * the command queue) as well as DMA addresses for supply to the card.
75 */
76struct fqelem {
77 cardoff_t card; /* corresponding element on card */
78 bus_addr_t card_ioblk; /* ioblk address to supply to card */
79 volatile uint32_t *statp; /* host status pointer */
80 void *ioblk; /* host ioblk (not for commands) */
81};
82
83struct fqueue {
84 struct fqelem *chunk; /* pointer to the element array */
85 int head; /* queue head */
86 int tail; /* queue tail */
87};
88
89/*
90 * Queue manipulation macros
91 */
92#define NEXT_QUEUE_ENTRY(HEAD,LEN) ((HEAD) = ((HEAD) + 1) % LEN)
93#define GET_QUEUE(Q,TYPE,IDX) (&((TYPE *)(Q).chunk)[(IDX)])
94
95/*
96 * Now define structures for the different queues. Each of these structures
97 * must start with a struct fqelem.
98 */
99struct txqueue { /* transmit queue element */
100 struct fqelem q;
101 struct mbuf *m; /* the chain we are transmitting */
102 bus_dmamap_t map; /* map for the packet */
103};
104
105struct rxqueue { /* receive queue element */
106 struct fqelem q;
107};
108
109struct supqueue { /* supply queue element */
110 struct fqelem q;
111};
112
113struct cmdqueue;
114struct fatm_softc;
115
116typedef void (*completion_cb)(struct fatm_softc *, struct cmdqueue *);
117
118struct cmdqueue { /* command queue element */
119 struct fqelem q;
120 completion_cb cb; /* call on command completion */
121 int error; /* set if error occured */
122};
123
124/*
125 * Card-DMA-able memory is managed by means of the bus_dma* functions.
126 * To allocate a chunk of memory with a specific size and alignment one
127 * has to:
128 * 1. create a DMA tag
129 * 2. allocate the memory
130 * 3. load the memory into a map.
131 * This finally gives the physical address that can be given to the card.
132 * The card can DMA the entire 32-bit space without boundaries. We assume,
133 * that all the allocations can be mapped in one contiguous segment. This
134 * may be wrong in the future if we have more than 32 bit addresses.
135 * Allocation is done at attach time and managed by the following structure.
136 *
137 * This could be done easier with the NetBSD bus_dma* functions. They appear
138 * to be more useful and consistent.
139 */
140struct fatm_mem {
141 u_int size; /* size */
142 u_int align; /* alignment */
143 bus_dma_tag_t dmat; /* DMA tag */
144 void *mem; /* memory block */
145 bus_addr_t paddr; /* pysical address */
146 bus_dmamap_t map; /* map */
147};
148
149/*
150 * Each of these structures describes one receive buffer while the buffer
151 * is on the card or in the receive return queue. These structures are
152 * allocated at initialisation time together with the DMA maps. The handle that
153 * is given to the card is the index into the array of these structures.
154 */
155struct rbuf {
156 struct mbuf *m; /* the mbuf while we are on the card */
157 bus_dmamap_t map; /* the map */
158 LIST_ENTRY(rbuf) link; /* the free list link */
159};
160LIST_HEAD(rbuf_list, rbuf);
161
162/*
163 * The driver maintains a list of all open VCCs. Because we
164 * use only VPI=0 and a maximum VCI of 1024, the list is rather an array
165 * than a list. We also store the atm pseudoheader flags here and the
166 * rxhand (aka. protocol block).
167 */
168struct card_vcc {
169 struct atmio_vcc param; /* traffic parameters */
170 void *rxhand;
171 u_int vflags;
172 uint32_t ipackets;
173 uint32_t opackets;
174 uint32_t ibytes;
175 uint32_t obytes;
176};
177
178#define FATM_VCC_OPEN 0x00010000 /* is open */
179#define FATM_VCC_TRY_OPEN 0x00020000 /* is currently opening */
180#define FATM_VCC_TRY_CLOSE 0x00040000 /* is currently closing */
181#define FATM_VCC_BUSY 0x00070000 /* one of the above */
182#define FATM_VCC_REOPEN 0x00080000 /* reopening during init */
183
184/*
185 * Finally the softc structure
186 */
187struct fatm_softc {
188 struct ifatm ifatm; /* common part */
189 struct mtx mtx; /* lock this structure */
190 struct ifmedia media; /* media */
191
192 int init_state; /* initialisation step */
193 int memid; /* resource id for card memory */
194 struct resource *memres; /* resource for card memory */
195 bus_space_handle_t memh; /* handle for card memory */
196 bus_space_tag_t memt; /* tag for card memory */
197 int irqid; /* resource id for interrupt */
198 struct resource *irqres; /* resource for interrupt */
199 void *ih; /* interrupt handler */
200
201 bus_dma_tag_t parent_dmat; /* parent DMA tag */
202 struct fatm_mem stat_mem; /* memory for status blocks */
203 struct fatm_mem txq_mem; /* TX descriptor queue */
204 struct fatm_mem rxq_mem; /* RX descriptor queue */
205 struct fatm_mem s1q_mem; /* Small buffer 1 queue */
206 struct fatm_mem l1q_mem; /* Large buffer 1 queue */
207 struct fatm_mem prom_mem; /* PROM memory */
208
209 struct fqueue txqueue; /* transmission queue */
210 struct fqueue rxqueue; /* receive queue */
211 struct fqueue s1queue; /* SMALL S1 queue */
212 struct fqueue l1queue; /* LARGE S1 queue */
213 struct fqueue cmdqueue; /* command queue */
214
215 /* fields for access to the SUNI registers */
216 struct fatm_mem reg_mem; /* DMAable memory for readregs */
217 struct cv cv_regs; /* to serialize access to reg_mem */
218
219 /* fields for access to statistics */
220 struct fatm_mem sadi_mem; /* sadistics memory */
221 struct cv cv_stat; /* to serialize access to sadi_mem */
222
223 u_int flags;
224#define FATM_STAT_INUSE 0x0001
225#define FATM_REGS_INUSE 0x0002
226 u_int txcnt; /* number of used transmit desc */
227 int retry_tx; /* keep mbufs in queue if full */
228
229 struct card_vcc **vccs; /* table of vccs */
230 int open_vccs; /* number of vccs in use */
231 int small_cnt; /* number of buffers owned by card */
232 int large_cnt; /* number of buffers owned by card */
233 uma_zone_t vcc_zone; /* allocator for VCCs */
234
235 /* receiving */
236 struct rbuf *rbufs; /* rbuf array */
237 struct rbuf_list rbuf_free; /* free rbufs list */
238 struct rbuf_list rbuf_used; /* used rbufs list */
239 u_int rbuf_total; /* total number of buffs */
240 bus_dma_tag_t rbuf_tag; /* tag for rbuf mapping */
241
242 /* transmission */
243 bus_dma_tag_t tx_tag; /* transmission tag */
244
245 uint32_t heartbeat; /* last heartbeat */
246 u_int stop_cnt; /* how many times checked */
247
248 struct istats istats; /* internal statistics */
249
250 /* SUNI state */
251 struct utopia utopia;
252
253 /* sysctl support */
254 struct sysctl_ctx_list sysctl_ctx;
255 struct sysctl_oid *sysctl_tree;
256
257#ifdef FATM_DEBUG
258 /* debugging */
259 u_int debug;
260#endif
261};
262
263#ifndef FATM_DEBUG
264#define FATM_LOCK(SC) mtx_lock(&(SC)->mtx)
265#define FATM_UNLOCK(SC) mtx_unlock(&(SC)->mtx)
266#else
267#define FATM_LOCK(SC) do { \
268 DBG(SC, LOCK, ("locking in line %d", __LINE__)); \
269 mtx_lock(&(SC)->mtx); \
270 } while (0)
271#define FATM_UNLOCK(SC) do { \
272 DBG(SC, LOCK, ("unlocking in line %d", __LINE__)); \
273 mtx_unlock(&(SC)->mtx); \
274 } while (0)
275#endif
276#define FATM_CHECKLOCK(SC) mtx_assert(&sc->mtx, MA_OWNED)
277
278/*
279 * Macros to access host memory fields that are also access by the card.
280 * These fields need to little-endian always.
281 */
282#define H_GETSTAT(STATP) (le32toh(*(STATP)))
283#define H_SETSTAT(STATP, S) do { *(STATP) = htole32(S); } while (0)
284#define H_SETDESC(DESC, D) do { (DESC) = htole32(D); } while (0)
285
286#ifdef notyet
287#define H_SYNCSTAT_POSTREAD(SC, P) \
288 bus_dmamap_sync_size((SC)->stat_mem.dmat, \
289 (SC)->stat_mem.map, \
290 (volatile char *)(P) - (volatile char *)(SC)->stat_mem.mem, \
291 sizeof(volatile uint32_t), BUS_DMASYNC_POSTREAD)
292
293#define H_SYNCSTAT_PREWRITE(SC, P) \
294 bus_dmamap_sync_size((SC)->stat_mem.dmat, \
295 (SC)->stat_mem.map, \
296 (volatile char *)(P) - (volatile char *)(SC)->stat_mem.mem, \
297 sizeof(volatile uint32_t), BUS_DMASYNC_PREWRITE)
298
299#define H_SYNCQ_PREWRITE(M, P, SZ) \
300 bus_dmamap_sync_size((M)->dmat, (M)->map, \
301 (volatile char *)(P) - (volatile char *)(M)->mem, (SZ), \
302 BUS_DMASYNC_PREWRITE)
303
304#define H_SYNCQ_POSTREAD(M, P, SZ) \
305 bus_dmamap_sync_size((M)->dmat, (M)->map, \
306 (volatile char *)(P) - (volatile char *)(M)->mem, (SZ), \
307 BUS_DMASYNC_POSTREAD)
308#else
309#define H_SYNCSTAT_POSTREAD(SC, P) do { } while (0)
310#define H_SYNCSTAT_PREWRITE(SC, P) do { } while (0)
311#define H_SYNCQ_PREWRITE(M, P, SZ) do { } while (0)
312#define H_SYNCQ_POSTREAD(M, P, SZ) do { } while (0)
313#endif
314
315/*
316 * Macros to manipulate VPVCs
317 */
318#define MKVPVC(VPI,VCI) (((VPI) << 16) | (VCI))
319#define GETVPI(VPVC) (((VPVC) >> 16) & 0xff)
320#define GETVCI(VPVC) ((VPVC) & 0xffff)
321
322/*
323 * These macros encapsulate the bus_space functions for better readabiliy.
324 */
325#define WRITE4(SC, OFF, VAL) bus_space_write_4(SC->memt, SC->memh, OFF, VAL)
326#define WRITE1(SC, OFF, VAL) bus_space_write_1(SC->memt, SC->memh, OFF, VAL)
327
328#define READ4(SC, OFF) bus_space_read_4(SC->memt, SC->memh, OFF)
329#define READ1(SC, OFF) bus_space_read_1(SC->memt, SC->memh, OFF)
330
331#define BARRIER_R(SC) \
332 bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \
333 BUS_SPACE_BARRIER_READ)
334#define BARRIER_W(SC) \
335 bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \
336 BUS_SPACE_BARRIER_WRITE)
337#define BARRIER_RW(SC) \
338 bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \
339 BUS_SPACE_BARRIER_WRITE|BUS_SPACE_BARRIER_READ)
340
341#ifdef FATM_DEBUG
342#define DBG(SC, FL, PRINT) do { \
343 if ((SC)->debug & DBG_##FL) { \
344 if_printf(&(SC)->ifatm.ifnet, "%s: ", __func__); \
345 printf PRINT; \
346 printf("\n"); \
347 } \
348 } while (0)
349#define DBGC(SC, FL, PRINT) do { \
350 if ((SC)->debug & DBG_##FL) \
351 printf PRINT; \
352 } while (0)
353
354enum {
355 DBG_RCV = 0x0001,
356 DBG_XMIT = 0x0002,
357 DBG_VCC = 0x0004,
358 DBG_IOCTL = 0x0008,
359 DBG_ATTACH = 0x0010,
360 DBG_INIT = 0x0020,
361 DBG_DMA = 0x0040,
362 DBG_BEAT = 0x0080,
363 DBG_UART = 0x0100,
364 DBG_LOCK = 0x0200,
365
366 DBG_ALL = 0xffff
367};
368
369#else
370#define DBG(SC, FL, PRINT)
371#define DBGC(SC, FL, PRINT)
372#endif
373
374/*
375 * Configuration.
376 *
377 * This section contains tunable parameters and dependend defines.
378 */
379#define FATM_CMD_QLEN 16 /* command queue length */
380#ifndef TEST_DMA_SYNC
381#define FATM_TX_QLEN 128 /* transmit queue length */
382#define FATM_RX_QLEN 64 /* receive queue length */
383#else
384#define FATM_TX_QLEN 8 /* transmit queue length */
385#define FATM_RX_QLEN 8 /* receive queue length */
386#endif
387
388#define SMALL_SUPPLY_QLEN 16
389#define SMALL_POOL_SIZE 256
390#define SMALL_SUPPLY_BLKSIZE 8
391
392#define LARGE_SUPPLY_QLEN 16
393#define LARGE_POOL_SIZE 128
394#define LARGE_SUPPLY_BLKSIZE 8