]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/patm/if_patmvar.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / patm / if_patmvar.h
1 /*-
2  * Copyright (c) 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  * Driver for IDT77252 (ABR) based cards like ProSum's.
32  */
33
34 /* legal values are 0, 1, 2 and 8 */
35 #define PATM_VPI_BITS   2
36 #define PATM_CFG_VPI    IDT_CFG_VP2
37
38 /* receive status queue size */
39 #define PATM_RSQ_SIZE           512
40 #define PATM_CFQ_RSQ_SIZE       IDT_CFG_RXQ512  
41
42 /* alignment for SQ memory */
43 #define PATM_SQ_ALIGNMENT       8192
44
45 #define PATM_PROATM_NAME_OFFSET 060
46 #define PATM_PROATM_NAME        "PROATM"
47 #define PATM_PROATM_MAC_OFFSET  044
48 #define PATM_IDT_MAC_OFFSET     0154
49
50 /* maximum number of packets on UBR queue */
51 #define PATM_DLFT_MAXQ          1000
52
53 /* maximum number of packets on other queues. This should depend on the
54  * traffic contract. */
55 #define PATM_TX_IFQLEN          100
56
57 /*
58  * Maximum number of DMA maps we allocate. This is the minimum that can be
59  * set larger via a sysctl.
60  * Starting number of DMA maps.
61  * Step for growing.
62  */
63 #define PATM_CFG_TXMAPS_MAX     1024
64 #define PATM_CFG_TXMAPS_INIT    128
65 #define PATM_CFG_TXMAPS_STEP    128
66
67 /* percents of TST slots to keep for non-CBR traffic */
68 #define PATM_TST_RESERVE        2
69
70 /*
71  * Structure to hold TX DMA maps
72  */
73 struct patm_txmap {
74         SLIST_ENTRY(patm_txmap) link;
75         bus_dmamap_t    map;
76 };
77
78 /*
79  * Receive buffers.
80  *
81  * We manage our own external mbufs for small receive buffers for two reasons:
82  * the card may consume a rather large number of buffers. Mapping each buffer
83  * would consume a lot of iospace on sparc64. Also the card allows us to set
84  * a 32-bit handle for identification of the buffers. On a 64-bit system this
85  * requires us to use a mapping between buffers and handles.
86  *
87  * For large buffers we use mbuf clusters directly. We track these by using
88  * an array of pointers (lbufs) to special structs and a free list of these
89  * structs.
90  *
91  * For AAL0 cell we use FBQ2 and make the 1 cell long.
92  */
93 /*
94  * Define the small buffer chunk so that we have at least 16 byte free
95  * at the end of the chunk and that there is an integral number of chunks
96  * in a page.
97  */
98 #define SMBUF_PAGE_SIZE         16384   /* 16k pages */
99 #define SMBUF_MAX_PAGES         64      /* maximum number of pages */
100 #define SMBUF_CHUNK_SIZE        256     /* 256 bytes per chunk */
101 #define SMBUF_CELLS             5
102 #define SMBUF_SIZE              (SMBUF_CELLS * 48)
103 #define SMBUF_THRESHOLD         9       /* 9/16 of queue size */
104 #define SMBUF_NI_THRESH         3
105 #define SMBUF_CI_THRESH         1
106
107 #define VMBUF_PAGE_SIZE         16384   /* 16k pages */
108 #define VMBUF_MAX_PAGES         16      /* maximum number of pages */
109 #define VMBUF_CHUNK_SIZE        64      /* 64 bytes per chunk */
110 #define VMBUF_CELLS             1
111 #define VMBUF_SIZE              (VMBUF_CELLS * 48)
112 #define VMBUF_THRESHOLD         15      /* 15/16 of size */
113
114 #define SMBUF_OFFSET    (SMBUF_CHUNK_SIZE - 8 - SMBUF_SIZE)
115 #define VMBUF_OFFSET    0
116
117 #define MBUF_SHANDLE    0x00000000
118 #define MBUF_LHANDLE    0x80000000
119 #define MBUF_VHANDLE    0x40000000
120 #define MBUF_HMASK      0x3fffffff
121
122 /*
123  * Large buffers
124  *
125  * The problem with these is the maximum count. When the card assembles
126  * a AAL5 pdu it moves a buffer from the FBQ to the VC. This frees space
127  * in the FBQ, put the buffer may pend on the card for an unlimited amount
128  * of time (we don't idle connections). This means that the upper limit
129  * on buffers on the card may be (no-of-open-vcs + FBQ_SIZE). Because
130  * this is far too much, make this a tuneable. We could also make
131  * this dynamic by allocating pages of several lbufs at once during run time.
132  */
133 #define LMBUF_MAX               (IDT_FBQ_SIZE * 2)
134 #define LMBUF_CELLS             (MCLBYTES / 48) /* 42 cells = 2048 byte */
135 #define LMBUF_SIZE              (LMBUF_CELLS * 48)
136 #define LMBUF_THRESHOLD         9       /* 9/16 of queue size */
137 #define LMBUF_OFFSET            (MCLBYTES - LMBUF_SIZE)
138 #define LMBUF_NI_THRESH         3
139 #define LMBUF_CI_THRESH         1
140
141 #define LMBUF_HANDLE            0x80000000
142
143 struct lmbuf {
144         SLIST_ENTRY(lmbuf)      link;   /* free list link */
145         bus_dmamap_t            map;    /* DMA map */
146         u_int                   handle; /* this is the handle index */
147         struct mbuf             *m;     /* the current mbuf */
148         bus_addr_t              phy;    /* phy addr */
149 };
150
151 #define PATM_CID(SC, VPI, VCI)  \
152     (((VPI) << IFP2IFATM((SC)->ifp)->mib.vci_bits) | (VCI))
153
154 /*
155  * Internal driver statistics
156  */
157 struct patm_stats {
158         uint32_t        raw_cells;
159         uint32_t        raw_no_vcc;
160         uint32_t        raw_no_buf;
161         uint32_t        tx_qfull;
162         uint32_t        tx_out_of_tbds;
163         uint32_t        tx_out_of_maps;
164         uint32_t        tx_load_err;
165 };
166
167 /*
168  * These are allocated as DMA able memory
169  */
170 struct patm_scd {
171         struct idt_tbd  scq[IDT_SCQ_SIZE];
172         LIST_ENTRY(patm_scd) link;      /* all active SCDs */
173         uint32_t        sram;           /* SRAM address */
174         bus_addr_t      phy;            /* physical address */
175         bus_dmamap_t    map;            /* DMA map */
176         u_int           tail;           /* next free entry for host */
177         int             space;          /* number of free entries (minus one) */
178         u_int           slots;          /* CBR slots allocated */
179         uint8_t         tag;            /* next tag for TSI */
180         uint8_t         last_tag;       /* last tag checked in interrupt */
181         uint8_t         num_on_card;    /* number of PDUs on tx queue */
182         uint8_t         lacr;           /* LogACR value */
183         uint8_t         init_er;        /* LogER value */
184         struct ifqueue  q;              /* queue of packets */
185         struct mbuf     *on_card[IDT_TSQE_TAG_SPACE];
186 };
187
188 /*
189  * Per-VCC data
190  */
191 struct patm_vcc {
192         struct atmio_vcc vcc;           /* caller's parameters */
193         void            *rxhand;        /* NATM handle */
194         u_int           vflags;         /* open and other flags */
195         uint32_t        ipackets;       /* packets received */
196         uint32_t        opackets;       /* packets sent */
197         uint64_t        ibytes;         /* bytes received */
198         uint64_t        obytes;         /* bytes sent */
199
200         struct mbuf     *chain;         /* currently received chain */
201         struct mbuf     *last;          /* end of chain */
202         u_int           cid;            /* index */
203         u_int           cps;            /* last ABR cps */
204         struct patm_scd *scd;
205 };
206 #define PATM_VCC_TX_OPEN        0x0001
207 #define PATM_VCC_RX_OPEN        0x0002
208 #define PATM_VCC_TX_CLOSING     0x0004
209 #define PATM_VCC_RX_CLOSING     0x0008
210 #define PATM_VCC_OPEN           0x000f  /* all the above */
211
212 #define PATM_RAW_CELL           0x0000  /* 53 byte cells */
213 #define PATM_RAW_NOHEC          0x0100  /* 52 byte cells */
214 #define PATM_RAW_CS             0x0200  /* 64 byte cell stream */
215 #define PATM_RAW_FORMAT         0x0300  /* format mask */
216
217 /*
218  * Per adapter data
219  */
220 struct patm_softc {
221         struct ifnet            *ifp;           /* common ATM stuff */
222         struct mtx              mtx;            /* lock */
223         struct ifmedia          media;          /* media */
224         device_t                dev;            /* device */
225         struct resource *       memres;         /* memory resource */
226         bus_space_handle_t      memh;           /* handle */
227         bus_space_tag_t         memt;           /* ... and tag */
228         int                     irqid;          /* resource id */
229         struct resource *       irqres;         /* resource */
230         void *                  ih;             /* interrupt handle */
231         struct utopia           utopia;         /* phy state */
232         const struct idt_mmap   *mmap;          /* SRAM memory map */
233         u_int                   flags;          /* see below */
234         u_int                   revision;       /* chip revision */
235
236         /* DMAable status queue memory */
237         size_t                  sq_size;        /* size of memory area */
238         bus_dma_tag_t           sq_tag;         /* DMA tag */
239         bus_dmamap_t            sq_map;         /* map */
240
241         bus_addr_t              tsq_phy;        /* phys addr. */
242         struct idt_tsqe         *tsq;           /* transmit status queue */
243         struct idt_tsqe         *tsq_next;      /* last processed entry */
244         struct idt_rsqe         *rsq;           /* receive status queue */
245         bus_addr_t              rsq_phy;        /* phys addr. */
246         u_int                   rsq_last;       /* last processed entry */
247         struct idt_rawhnd       *rawhnd;        /* raw cell handle */
248         bus_addr_t              rawhnd_phy;     /* phys addr. */
249
250         /* TST */
251         u_int                   tst_state;      /* active TST and others */
252         u_int                   tst_jump[2];    /* address of the jumps */
253         u_int                   tst_base[2];    /* base address of TST */
254         u_int                   *tst_soft;      /* soft TST */
255         struct mtx              tst_lock;
256         struct callout          tst_callout;
257         u_int                   tst_free;       /* free slots */
258         u_int                   tst_reserve;    /* non-CBR reserve */
259         u_int                   bwrem;          /* remaining bandwith */
260
261         /* sysctl support */
262         struct sysctl_ctx_list  sysctl_ctx;
263         struct sysctl_oid       *sysctl_tree;
264
265         /* EEPROM contents */
266         uint8_t                 eeprom[256];
267
268         /* large buffer mapping */
269         bus_dma_tag_t           lbuf_tag;       /* DMA tag */
270         u_int                   lbuf_max;       /* maximum number */
271         struct lmbuf            *lbufs;         /* array for indexing */
272         SLIST_HEAD(,lmbuf)      lbuf_free_list; /* free list */
273
274         /* small buffer handling */
275         bus_dma_tag_t           sbuf_tag;       /* DMA tag */
276         struct mbpool           *sbuf_pool;     /* pool */
277         struct mbpool           *vbuf_pool;     /* pool */
278
279         /* raw cell queue */
280         struct lmbuf            *rawh;          /* current header buf */
281         u_int                   rawi;           /* cell index into buffer */
282
283         /* statistics */
284         struct patm_stats       stats;          /* statistics */
285
286         /* Vccs */
287         struct patm_vcc         **vccs;         /* channel pointer array */
288         u_int                   vccs_open;      /* number of open channels */
289         uma_zone_t              vcc_zone;
290         struct cv               vcc_cv;
291
292         /* SCDs */
293         uint32_t                scd_free;       /* SRAM of first free SCD */
294         bus_dma_tag_t           scd_tag;
295         struct patm_scd         *scd0;
296         LIST_HEAD(, patm_scd)   scd_list;       /* list of all active SCDs */
297
298         /* Tx */
299         bus_dma_tag_t           tx_tag;         /* for transmission */
300         SLIST_HEAD(, patm_txmap) tx_maps_free;  /* free maps */
301         u_int                   tx_nmaps;       /* allocated maps */
302         u_int                   tx_maxmaps;     /* maximum number */
303         struct uma_zone         *tx_mapzone;    /* zone for maps */
304
305 #ifdef PATM_DEBUG
306         /* debugging */
307         u_int                   debug;
308 #endif
309 };
310
311 /* flags */
312 #define PATM_25M        0x0001          /* 25MBit card */
313 #define PATM_SBUFW      0x0002          /* warned */
314 #define PATM_VBUFW      0x0004          /* warned */
315 #define PATM_UNASS      0x0010          /* unassigned cells */
316
317 #define PATM_CLR        0x0007          /* clear on stop */
318
319 /* tst - uses unused fields */
320 #define TST_BOTH        0x03000000
321 #define TST_CH0         0x01000000
322 #define TST_CH1         0x02000000
323 /* tst_state */
324 #define TST_ACT1        0x0001          /* active TST */
325 #define TST_PENDING     0x0002          /* need update */
326 #define TST_WAIT        0x0004          /* wait fo jump */
327
328 #define patm_printf(SC, ...)    if_printf((SC)->ifp, __VA_ARGS__);
329
330 #ifdef PATM_DEBUG
331 /*
332  * Debugging
333  */
334 enum {
335         DBG_ATTACH      = 0x0001,       /* attaching the card */
336         DBG_INTR        = 0x0002,       /* interrupts */
337         DBG_REG         = 0x0004,       /* register access */
338         DBG_SRAM        = 0x0008,       /* SRAM access */
339         DBG_PHY         = 0x0010,       /* PHY access */
340         DBG_IOCTL       = 0x0020,       /* ioctl */
341         DBG_FREEQ       = 0x0040,       /* free bufq supply */
342         DBG_VCC         = 0x0080,       /* open/close */
343         DBG_TX          = 0x0100,       /* transmission */
344         DBG_TST         = 0x0200,       /* TST */
345
346         DBG_ALL         = 0xffff
347 };
348
349 #define patm_debug(SC, FLAG, ...) do {                                  \
350         if((SC)->debug & DBG_##FLAG) {                                  \
351                 if_printf((SC)->ifp, "%s: ", __func__); \
352                 printf(__VA_ARGS__);                                    \
353                 printf("\n");                                           \
354         }                                                               \
355     } while (0)
356 #else
357
358 #define patm_debug(SC, FLAG, ...) do { } while (0)
359
360 #endif
361
362 /* start output */
363 void patm_start(struct ifnet *);
364
365 /* ioctl handler */
366 int patm_ioctl(struct ifnet *, u_long, caddr_t);
367
368 /* start the interface */
369 void patm_init(void *);
370
371 /* start the interface with the lock held */
372 void patm_initialize(struct patm_softc *);
373
374 /* stop the interface */
375 void patm_stop(struct patm_softc *);
376
377 /* software reset of interface */
378 void patm_reset(struct patm_softc *);
379
380 /* interrupt handler */
381 void patm_intr(void *);
382
383 /* check RSQ */
384 void patm_intr_rsq(struct patm_softc *sc);
385
386 /* enable the vcc */
387 void patm_load_vc(struct patm_softc *sc, struct patm_vcc *vcc, int reload);
388
389 /* close the given vcc for transmission */
390 void patm_tx_vcc_close(struct patm_softc *, struct patm_vcc *);
391
392 /* close the given vcc for receive */
393 void patm_rx_vcc_close(struct patm_softc *, struct patm_vcc *);
394
395 /* transmission side finally closed */
396 void patm_tx_vcc_closed(struct patm_softc *, struct patm_vcc *);
397
398 /* receive side finally closed */
399 void patm_rx_vcc_closed(struct patm_softc *, struct patm_vcc *);
400
401 /* vcc closed */
402 void patm_vcc_closed(struct patm_softc *, struct patm_vcc *);
403
404 /* check if we can open this one */
405 int patm_tx_vcc_can_open(struct patm_softc *, struct patm_vcc *);
406
407 /* check if we can open this one */
408 int patm_rx_vcc_can_open(struct patm_softc *, struct patm_vcc *);
409
410 /* open it */
411 void patm_tx_vcc_open(struct patm_softc *, struct patm_vcc *);
412
413 /* open it */
414 void patm_rx_vcc_open(struct patm_softc *, struct patm_vcc *);
415
416 /* receive packet */
417 void patm_rx(struct patm_softc *, struct idt_rsqe *);
418
419 /* packet transmitted */
420 void patm_tx(struct patm_softc *, u_int, u_int);
421
422 /* VBR connection went idle */
423 void patm_tx_idle(struct patm_softc *, u_int);
424
425 /* allocate an SCQ */
426 struct patm_scd *patm_scd_alloc(struct patm_softc *);
427
428 /* free an SCD */
429 void patm_scd_free(struct patm_softc *sc, struct patm_scd *scd);
430
431 /* setup SCD in SRAM */
432 void patm_scd_setup(struct patm_softc *sc, struct patm_scd *scd);
433
434 /* setup TCT entry in SRAM */
435 void patm_tct_setup(struct patm_softc *, struct patm_scd *, struct patm_vcc *);
436
437 /* free a large buffer */
438 void patm_lbuf_free(struct patm_softc *sc, struct lmbuf *b);
439
440 /* Process the raw cell at the given address */
441 void patm_rx_raw(struct patm_softc *sc, u_char *cell);
442
443 /* load a one segment DMA map */
444 void patm_load_callback(void *, bus_dma_segment_t *, int, int);
445
446 /* network operation register access */
447 static __inline uint32_t
448 patm_nor_read(struct patm_softc *sc, u_int reg)
449 {
450         uint32_t val;
451
452         val = bus_space_read_4(sc->memt, sc->memh, reg);
453         patm_debug(sc, REG, "reg(0x%x)=%04x", reg, val);
454         return (val);
455 }
456 static __inline void
457 patm_nor_write(struct patm_softc *sc, u_int reg, uint32_t val)
458 {
459
460         patm_debug(sc, REG, "reg(0x%x)=%04x", reg, val);
461         bus_space_write_4(sc->memt, sc->memh, reg, val);
462 }
463
464 /* Execute command */
465 static __inline void
466 patm_cmd_wait(struct patm_softc *sc)
467 {
468         while (patm_nor_read(sc, IDT_NOR_STAT) & IDT_STAT_CMDBZ)
469                 ;
470 }
471 static __inline void
472 patm_cmd_exec(struct patm_softc *sc, uint32_t cmd)
473 {
474         patm_cmd_wait(sc);
475         patm_nor_write(sc, IDT_NOR_CMD, cmd);
476 }
477
478 /* Read/write SRAM at the given word address. */
479 static __inline uint32_t
480 patm_sram_read(struct patm_softc *sc, u_int addr)
481 {
482         uint32_t val;
483
484         patm_cmd_exec(sc, IDT_MKCMD_RSRAM(addr));
485         patm_cmd_wait(sc);
486         val = patm_nor_read(sc, IDT_NOR_D0);
487         patm_debug(sc, SRAM, "read %04x=%08x", addr, val);
488         return (val);
489 }
490 static __inline void
491 patm_sram_write(struct patm_softc *sc, u_int addr, uint32_t val)
492 {
493         patm_debug(sc, SRAM, "write %04x=%08x", addr, val);
494         patm_cmd_wait(sc);
495         patm_nor_write(sc, IDT_NOR_D0, val);
496         patm_cmd_exec(sc, IDT_MKCMD_WSRAM(addr, 0));
497 }
498 static __inline void
499 patm_sram_write4(struct patm_softc *sc, u_int addr, uint32_t v0, uint32_t v1,
500     uint32_t v2, uint32_t v3)
501 {
502         patm_debug(sc, SRAM, "write %04x=%08x,%08x,%08x,%08x",
503             addr, v0, v1, v2, v3);
504         patm_cmd_wait(sc);
505         patm_nor_write(sc, IDT_NOR_D0, v0);
506         patm_nor_write(sc, IDT_NOR_D1, v1);
507         patm_nor_write(sc, IDT_NOR_D2, v2);
508         patm_nor_write(sc, IDT_NOR_D3, v3);
509         patm_cmd_exec(sc, IDT_MKCMD_WSRAM(addr, 3));
510 }
511
512 #define LEGAL_VPI(SC, VPI) \
513         (((VPI) & ~((1 << IFP2IFATM((SC)->ifp)->mib.vpi_bits) - 1)) == 0)
514 #define LEGAL_VCI(SC, VCI) \
515         (((VCI) & ~((1 << IFP2IFATM((SC)->ifp)->mib.vci_bits) - 1)) == 0)
516
517 extern const uint32_t patm_rtables155[];
518 extern const uint32_t patm_rtables25[];
519 extern const u_int patm_rtables_size;
520 extern const u_int patm_rtables_ntab;