]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/dev/fatm/if_fatmvar.h
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / dev / fatm / if_fatmvar.h
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$
30  *
31  * Fore PCA200E driver definitions.
32  */
33 /*
34  * Debug statistics of the PCA200 driver
35  */
36 struct 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  */
62 typedef 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  */
76 struct 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
83 struct 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  */
99 struct 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
105 struct rxqueue {                /* receive queue element */
106         struct fqelem   q;
107 };
108
109 struct supqueue {               /* supply queue element */
110         struct fqelem   q;
111 };
112
113 struct cmdqueue;
114 struct fatm_softc;
115
116 typedef void (*completion_cb)(struct fatm_softc *, struct cmdqueue *);
117
118 struct 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  */
140 struct 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  */
155 struct 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 };
160 LIST_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  */
168 struct 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  */
187 struct fatm_softc {
188         struct ifnet    *ifp;           /* common part */
189         struct mtx      mtx;            /* lock this structure */
190         struct ifmedia  media;          /* media */
191         struct callout  watchdog_timer;
192
193         int             init_state;     /* initialisation step */
194         int             memid;          /* resource id for card memory */
195         struct resource *memres;        /* resource for card memory */
196         bus_space_handle_t memh;        /* handle for card memory */
197         bus_space_tag_t memt;           /* tag for card memory */
198         int             irqid;          /* resource id for interrupt */
199         struct resource *irqres;        /* resource for interrupt */
200         void            *ih;            /* interrupt handler */
201
202         bus_dma_tag_t   parent_dmat;    /* parent DMA tag */
203         struct fatm_mem stat_mem;       /* memory for status blocks */
204         struct fatm_mem txq_mem;        /* TX descriptor queue */
205         struct fatm_mem rxq_mem;        /* RX descriptor queue */
206         struct fatm_mem s1q_mem;        /* Small buffer 1 queue */
207         struct fatm_mem l1q_mem;        /* Large buffer 1 queue */
208         struct fatm_mem prom_mem;       /* PROM memory */
209
210         struct fqueue   txqueue;        /* transmission queue */
211         struct fqueue   rxqueue;        /* receive queue */
212         struct fqueue   s1queue;        /* SMALL S1 queue */
213         struct fqueue   l1queue;        /* LARGE S1 queue */
214         struct fqueue   cmdqueue;       /* command queue */
215
216         /* fields for access to the SUNI registers */
217         struct fatm_mem reg_mem;        /* DMAable memory for readregs */
218         struct cv       cv_regs;        /* to serialize access to reg_mem */
219
220         /* fields for access to statistics */
221         struct fatm_mem sadi_mem;       /* sadistics memory */
222         struct cv       cv_stat;        /* to serialize access to sadi_mem */
223
224         u_int           flags;
225 #define FATM_STAT_INUSE 0x0001
226 #define FATM_REGS_INUSE 0x0002
227         u_int           txcnt;          /* number of used transmit desc */
228         int             retry_tx;       /* keep mbufs in queue if full */
229
230         struct card_vcc **vccs;         /* table of vccs */
231         int             open_vccs;      /* number of vccs in use */
232         int             small_cnt;      /* number of buffers owned by card */
233         int             large_cnt;      /* number of buffers owned by card */
234         uma_zone_t      vcc_zone;       /* allocator for VCCs */
235
236         /* receiving */
237         struct rbuf     *rbufs;         /* rbuf array */
238         struct rbuf_list rbuf_free;     /* free rbufs list */
239         struct rbuf_list rbuf_used;     /* used rbufs list */
240         u_int           rbuf_total;     /* total number of buffs */
241         bus_dma_tag_t   rbuf_tag;       /* tag for rbuf mapping */
242
243         /* transmission */
244         bus_dma_tag_t   tx_tag;         /* transmission tag */
245
246         uint32_t        heartbeat;      /* last heartbeat */
247         u_int           stop_cnt;       /* how many times checked */
248
249         struct istats   istats;         /* internal statistics */
250
251         /* SUNI state */
252         struct utopia   utopia;
253
254         /* sysctl support */
255         struct sysctl_ctx_list sysctl_ctx;
256         struct sysctl_oid *sysctl_tree;
257
258 #ifdef FATM_DEBUG
259         /* debugging */
260         u_int           debug;
261 #endif
262 };
263
264 #ifndef FATM_DEBUG
265 #define FATM_LOCK(SC)           mtx_lock(&(SC)->mtx)
266 #define FATM_UNLOCK(SC)         mtx_unlock(&(SC)->mtx)
267 #else
268 #define FATM_LOCK(SC)   do {                                    \
269         DBG(SC, LOCK, ("locking in line %d", __LINE__));        \
270         mtx_lock(&(SC)->mtx);                                   \
271     } while (0)
272 #define FATM_UNLOCK(SC) do {                                    \
273         DBG(SC, LOCK, ("unlocking in line %d", __LINE__));      \
274         mtx_unlock(&(SC)->mtx);                                 \
275     } while (0)
276 #endif
277 #define FATM_CHECKLOCK(SC)      mtx_assert(&sc->mtx, MA_OWNED)
278
279 /*
280  * Macros to access host memory fields that are also access by the card.
281  * These fields need to little-endian always.
282  */
283 #define H_GETSTAT(STATP)        (le32toh(*(STATP)))
284 #define H_SETSTAT(STATP, S)     do { *(STATP) = htole32(S); } while (0)
285 #define H_SETDESC(DESC, D)      do { (DESC) = htole32(D); } while (0)
286
287 #ifdef notyet
288 #define H_SYNCSTAT_POSTREAD(SC, P)                                      \
289         bus_dmamap_sync_size((SC)->stat_mem.dmat,                       \
290             (SC)->stat_mem.map,                                         \
291             (volatile char *)(P) - (volatile char *)(SC)->stat_mem.mem, \
292             sizeof(volatile uint32_t), BUS_DMASYNC_POSTREAD)
293
294 #define H_SYNCSTAT_PREWRITE(SC, P)                                      \
295         bus_dmamap_sync_size((SC)->stat_mem.dmat,                       \
296             (SC)->stat_mem.map,                                         \
297             (volatile char *)(P) - (volatile char *)(SC)->stat_mem.mem, \
298             sizeof(volatile uint32_t), BUS_DMASYNC_PREWRITE)
299
300 #define H_SYNCQ_PREWRITE(M, P, SZ)                                      \
301         bus_dmamap_sync_size((M)->dmat, (M)->map,                       \
302             (volatile char *)(P) - (volatile char *)(M)->mem, (SZ),     \
303             BUS_DMASYNC_PREWRITE)
304
305 #define H_SYNCQ_POSTREAD(M, P, SZ)                                      \
306         bus_dmamap_sync_size((M)->dmat, (M)->map,                       \
307             (volatile char *)(P) - (volatile char *)(M)->mem, (SZ),     \
308             BUS_DMASYNC_POSTREAD)
309 #else
310 #define H_SYNCSTAT_POSTREAD(SC, P)      do { } while (0)
311 #define H_SYNCSTAT_PREWRITE(SC, P)      do { } while (0)
312 #define H_SYNCQ_PREWRITE(M, P, SZ)      do { } while (0)
313 #define H_SYNCQ_POSTREAD(M, P, SZ)      do { } while (0)
314 #endif
315
316 /*
317  * Macros to manipulate VPVCs
318  */
319 #define MKVPVC(VPI,VCI) (((VPI) << 16) | (VCI))
320 #define GETVPI(VPVC)            (((VPVC) >> 16) & 0xff)
321 #define GETVCI(VPVC)            ((VPVC) & 0xffff)
322
323 /*
324  * These macros encapsulate the bus_space functions for better readabiliy.
325  */
326 #define WRITE4(SC, OFF, VAL) bus_space_write_4(SC->memt, SC->memh, OFF, VAL)
327 #define WRITE1(SC, OFF, VAL) bus_space_write_1(SC->memt, SC->memh, OFF, VAL)
328
329 #define READ4(SC, OFF) bus_space_read_4(SC->memt, SC->memh, OFF)
330 #define READ1(SC, OFF) bus_space_read_1(SC->memt, SC->memh, OFF)
331
332 #define BARRIER_R(SC) \
333         bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \
334             BUS_SPACE_BARRIER_READ)
335 #define BARRIER_W(SC) \
336         bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \
337             BUS_SPACE_BARRIER_WRITE)
338 #define BARRIER_RW(SC) \
339         bus_space_barrier(SC->memt, SC->memh, 0, FATMO_END, \
340             BUS_SPACE_BARRIER_WRITE|BUS_SPACE_BARRIER_READ)
341
342 #ifdef FATM_DEBUG
343 #define DBG(SC, FL, PRINT) do {                                         \
344         if ((SC)->debug & DBG_##FL) {                                   \
345                 if_printf(&(SC)->ifatm.ifnet, "%s: ", __func__);        \
346                 printf PRINT;                                           \
347                 printf("\n");                                           \
348         }                                                               \
349     } while (0)
350 #define DBGC(SC, FL, PRINT) do {                                        \
351         if ((SC)->debug & DBG_##FL)                                     \
352                 printf PRINT;                                           \
353     } while (0)
354
355 enum {
356         DBG_RCV         = 0x0001,
357         DBG_XMIT        = 0x0002,
358         DBG_VCC         = 0x0004,
359         DBG_IOCTL       = 0x0008,
360         DBG_ATTACH      = 0x0010,
361         DBG_INIT        = 0x0020,
362         DBG_DMA         = 0x0040,
363         DBG_BEAT        = 0x0080,
364         DBG_UART        = 0x0100,
365         DBG_LOCK        = 0x0200,
366
367         DBG_ALL         = 0xffff
368 };
369
370 #else
371 #define DBG(SC, FL, PRINT)
372 #define DBGC(SC, FL, PRINT)
373 #endif
374
375 /*
376  * Configuration.
377  *
378  * This section contains tunable parameters and dependend defines.
379  */
380 #define FATM_CMD_QLEN           16              /* command queue length */
381 #ifndef TEST_DMA_SYNC
382 #define FATM_TX_QLEN            128             /* transmit queue length */
383 #define FATM_RX_QLEN            64              /* receive queue length */
384 #else
385 #define FATM_TX_QLEN            8               /* transmit queue length */
386 #define FATM_RX_QLEN            8               /* receive queue length */
387 #endif
388
389 #define SMALL_SUPPLY_QLEN       16
390 #define SMALL_POOL_SIZE         256
391 #define SMALL_SUPPLY_BLKSIZE    8
392
393 #define LARGE_SUPPLY_QLEN       16
394 #define LARGE_POOL_SIZE         128
395 #define LARGE_SUPPLY_BLKSIZE    8