]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/hatm/if_hatm.c
Update llvm to trunk r256945.
[FreeBSD/FreeBSD.git] / sys / dev / hatm / if_hatm.c
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  * ForeHE driver.
30  *
31  * This file contains the module and driver infrastructure stuff as well
32  * as a couple of utility functions and the entire initialisation.
33  */
34
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37
38 #include "opt_inet.h"
39 #include "opt_natm.h"
40
41 #include <sys/types.h>
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/malloc.h>
45 #include <sys/kernel.h>
46 #include <sys/bus.h>
47 #include <sys/errno.h>
48 #include <sys/conf.h>
49 #include <sys/module.h>
50 #include <sys/queue.h>
51 #include <sys/syslog.h>
52 #include <sys/lock.h>
53 #include <sys/mutex.h>
54 #include <sys/condvar.h>
55 #include <sys/sysctl.h>
56 #include <vm/uma.h>
57
58 #include <sys/sockio.h>
59 #include <sys/mbuf.h>
60 #include <sys/socket.h>
61
62 #include <net/if.h>
63 #include <net/if_var.h>
64 #include <net/if_media.h>
65 #include <net/if_atm.h>
66 #include <net/if_types.h>
67 #include <net/route.h>
68 #ifdef ENABLE_BPF
69 #include <net/bpf.h>
70 #endif
71 #include <netinet/in.h>
72 #include <netinet/if_atm.h>
73
74 #include <machine/bus.h>
75 #include <machine/resource.h>
76 #include <sys/bus.h>
77 #include <sys/rman.h>
78 #include <dev/pci/pcireg.h>
79 #include <dev/pci/pcivar.h>
80
81 #include <dev/utopia/utopia.h>
82 #include <dev/hatm/if_hatmconf.h>
83 #include <dev/hatm/if_hatmreg.h>
84 #include <dev/hatm/if_hatmvar.h>
85
86 static const struct {
87         uint16_t        vid;
88         uint16_t        did;
89         const char      *name;
90 } hatm_devs[] = {
91         { 0x1127, 0x400,
92           "FORE HE" },
93         { 0, 0, NULL }
94 };
95
96 SYSCTL_DECL(_hw_atm);
97
98 MODULE_DEPEND(hatm, utopia, 1, 1, 1);
99 MODULE_DEPEND(hatm, pci, 1, 1, 1);
100 MODULE_DEPEND(hatm, atm, 1, 1, 1);
101
102 #define EEPROM_DELAY    400 /* microseconds */
103
104 /* Read from EEPROM 0000 0011b */
105 static const uint32_t readtab[] = {
106         HE_REGM_HOST_PROM_SEL | HE_REGM_HOST_PROM_CLOCK,
107         0,
108         HE_REGM_HOST_PROM_CLOCK,
109         0,                              /* 0 */
110         HE_REGM_HOST_PROM_CLOCK,        
111         0,                              /* 0 */
112         HE_REGM_HOST_PROM_CLOCK,
113         0,                              /* 0 */
114         HE_REGM_HOST_PROM_CLOCK,
115         0,                              /* 0 */
116         HE_REGM_HOST_PROM_CLOCK,
117         0,                              /* 0 */
118         HE_REGM_HOST_PROM_CLOCK,
119         HE_REGM_HOST_PROM_DATA_IN,      /* 0 */
120         HE_REGM_HOST_PROM_CLOCK | HE_REGM_HOST_PROM_DATA_IN,
121         HE_REGM_HOST_PROM_DATA_IN,      /* 1 */
122         HE_REGM_HOST_PROM_CLOCK | HE_REGM_HOST_PROM_DATA_IN,
123         HE_REGM_HOST_PROM_DATA_IN,      /* 1 */
124 };
125 static const uint32_t clocktab[] = {
126         0, HE_REGM_HOST_PROM_CLOCK,
127         0, HE_REGM_HOST_PROM_CLOCK,
128         0, HE_REGM_HOST_PROM_CLOCK,
129         0, HE_REGM_HOST_PROM_CLOCK,
130         0, HE_REGM_HOST_PROM_CLOCK,
131         0, HE_REGM_HOST_PROM_CLOCK,
132         0, HE_REGM_HOST_PROM_CLOCK,
133         0, HE_REGM_HOST_PROM_CLOCK,
134         0
135 };
136
137 /*
138  * Convert cell rate to ATM Forum format
139  */
140 u_int
141 hatm_cps2atmf(uint32_t pcr)
142 {
143         u_int e;
144
145         if (pcr == 0)
146                 return (0);
147         pcr <<= 9;
148         e = 0;
149         while (pcr > (1024 - 1)) {
150                 e++;
151                 pcr >>= 1;
152         }
153         return ((1 << 14) | (e << 9) | (pcr & 0x1ff));
154 }
155 u_int
156 hatm_atmf2cps(uint32_t fcr)
157 {
158         fcr &= 0x7fff;
159
160         return ((1 << ((fcr >> 9) & 0x1f)) * (512 + (fcr & 0x1ff)) / 512
161           * (fcr >> 14));
162 }
163
164 /************************************************************
165  *
166  * Initialisation
167  */
168 /*
169  * Probe for a HE controller
170  */
171 static int
172 hatm_probe(device_t dev)
173 {
174         int i;
175
176         for (i = 0; hatm_devs[i].name; i++)
177                 if (pci_get_vendor(dev) == hatm_devs[i].vid &&
178                     pci_get_device(dev) == hatm_devs[i].did) {
179                         device_set_desc(dev, hatm_devs[i].name);
180                         return (BUS_PROBE_DEFAULT);
181                 }
182         return (ENXIO);
183 }
184
185 /*
186  * Allocate and map DMA-able memory. We support only contiguous mappings.
187  */
188 static void
189 dmaload_helper(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
190 {
191         if (error)
192                 return;
193         KASSERT(nsegs == 1, ("too many segments for DMA: %d", nsegs));
194         KASSERT(segs[0].ds_addr <= 0xffffffffUL,
195             ("phys addr too large %lx", (u_long)segs[0].ds_addr));
196
197         *(bus_addr_t *)arg = segs[0].ds_addr;
198 }
199 static int
200 hatm_alloc_dmamem(struct hatm_softc *sc, const char *what, struct dmamem *mem)
201 {
202         int error;
203
204         mem->base = NULL;
205
206         /*
207          * Alignement does not work in the bus_dmamem_alloc function below
208          * on FreeBSD. malloc seems to align objects at least to the object
209          * size so increase the size to the alignment if the size is lesser
210          * than the alignemnt.
211          * XXX on sparc64 this is (probably) not needed.
212          */
213         if (mem->size < mem->align)
214                 mem->size = mem->align;
215
216         error = bus_dma_tag_create(sc->parent_tag, mem->align, 0,
217             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
218             NULL, NULL, mem->size, 1,
219             BUS_SPACE_MAXSIZE_32BIT, BUS_DMA_ALLOCNOW,
220             NULL, NULL, &mem->tag);
221         if (error) {
222                 if_printf(sc->ifp, "DMA tag create (%s)\n", what);
223                 return (error);
224         }
225
226         error = bus_dmamem_alloc(mem->tag, &mem->base, 0, &mem->map);
227         if (error) {
228                 if_printf(sc->ifp, "DMA mem alloc (%s): %d\n",
229                     what, error);
230                 bus_dma_tag_destroy(mem->tag);
231                 mem->base = NULL;
232                 return (error);
233         }
234
235         error = bus_dmamap_load(mem->tag, mem->map, mem->base, mem->size,
236             dmaload_helper, &mem->paddr, BUS_DMA_NOWAIT);
237         if (error) {
238                 if_printf(sc->ifp, "DMA map load (%s): %d\n",
239                     what, error);
240                 bus_dmamem_free(mem->tag, mem->base, mem->map);
241                 bus_dma_tag_destroy(mem->tag);
242                 mem->base = NULL;
243                 return (error);
244         }
245
246         DBG(sc, DMA, ("%s S/A/V/P 0x%x 0x%x %p 0x%lx", what, mem->size,
247             mem->align, mem->base, (u_long)mem->paddr));
248
249         return (0);
250 }
251
252 /*
253  * Destroy all the resources of an DMA-able memory region.
254  */
255 static void
256 hatm_destroy_dmamem(struct dmamem *mem)
257 {
258         if (mem->base != NULL) {
259                 bus_dmamap_unload(mem->tag, mem->map);
260                 bus_dmamem_free(mem->tag, mem->base, mem->map);
261                 (void)bus_dma_tag_destroy(mem->tag);
262                 mem->base = NULL;
263         }
264 }
265
266 /*
267  * Initialize/destroy DMA maps for the large pool 0
268  */
269 static void
270 hatm_destroy_rmaps(struct hatm_softc *sc)
271 {
272         u_int b;
273
274         DBG(sc, ATTACH, ("destroying rmaps and lbuf pointers..."));
275         if (sc->rmaps != NULL) {
276                 for (b = 0; b < sc->lbufs_size; b++)
277                         bus_dmamap_destroy(sc->mbuf_tag, sc->rmaps[b]);
278                 free(sc->rmaps, M_DEVBUF);
279         }
280         if (sc->lbufs != NULL)
281                 free(sc->lbufs, M_DEVBUF);
282 }
283
284 static void
285 hatm_init_rmaps(struct hatm_softc *sc)
286 {
287         u_int b;
288         int err;
289
290         DBG(sc, ATTACH, ("allocating rmaps and lbuf pointers..."));
291         sc->lbufs = malloc(sizeof(sc->lbufs[0]) * sc->lbufs_size,
292             M_DEVBUF, M_ZERO | M_WAITOK);
293
294         /* allocate and create the DMA maps for the large pool */
295         sc->rmaps = malloc(sizeof(sc->rmaps[0]) * sc->lbufs_size,
296             M_DEVBUF, M_WAITOK);
297         for (b = 0; b < sc->lbufs_size; b++) {
298                 err = bus_dmamap_create(sc->mbuf_tag, 0, &sc->rmaps[b]);
299                 if (err != 0)
300                         panic("bus_dmamap_create: %d\n", err);
301         }
302 }
303
304 /*
305  * Initialize and destroy small mbuf page pointers and pages
306  */
307 static void
308 hatm_destroy_smbufs(struct hatm_softc *sc)
309 {
310         u_int i, b;
311         struct mbuf_page *pg;
312         struct mbuf_chunk_hdr *h;
313
314         if (sc->mbuf_pages != NULL) {
315                 for (i = 0; i < sc->mbuf_npages; i++) {
316                         pg = sc->mbuf_pages[i];
317                         for (b = 0; b < pg->hdr.nchunks; b++) {
318                                 h = (struct mbuf_chunk_hdr *) ((char *)pg +
319                                     b * pg->hdr.chunksize + pg->hdr.hdroff);
320                                 if (h->flags & MBUF_CARD)
321                                         if_printf(sc->ifp,
322                                             "%s -- mbuf page=%u card buf %u\n",
323                                             __func__, i, b);
324                                 if (h->flags & MBUF_USED)
325                                         if_printf(sc->ifp,
326                                             "%s -- mbuf page=%u used buf %u\n",
327                                             __func__, i, b);
328                         }
329                         bus_dmamap_unload(sc->mbuf_tag, pg->hdr.map);
330                         bus_dmamap_destroy(sc->mbuf_tag, pg->hdr.map);
331                         free(pg, M_DEVBUF);
332                 }
333                 free(sc->mbuf_pages, M_DEVBUF);
334         }
335 }
336
337 static void
338 hatm_init_smbufs(struct hatm_softc *sc)
339 {
340         sc->mbuf_pages = malloc(sizeof(sc->mbuf_pages[0]) *
341             sc->mbuf_max_pages, M_DEVBUF, M_WAITOK);
342         sc->mbuf_npages = 0;
343 }
344
345 /*
346  * Initialize/destroy TPDs. This is called from attach/detach.
347  */
348 static void
349 hatm_destroy_tpds(struct hatm_softc *sc)
350 {
351         struct tpd *t;
352
353         if (sc->tpds.base == NULL)
354                 return;
355
356         DBG(sc, ATTACH, ("releasing TPDs ..."));
357         if (sc->tpd_nfree != sc->tpd_total)
358                 if_printf(sc->ifp, "%u tpds still in use from %u\n",
359                     sc->tpd_total - sc->tpd_nfree, sc->tpd_total);
360         while ((t = SLIST_FIRST(&sc->tpd_free)) != NULL) {
361                 SLIST_REMOVE_HEAD(&sc->tpd_free, link);
362                 bus_dmamap_destroy(sc->tx_tag, t->map);
363         }
364         hatm_destroy_dmamem(&sc->tpds);
365         free(sc->tpd_used, M_DEVBUF);
366         DBG(sc, ATTACH, ("... done"));
367 }
368 static int
369 hatm_init_tpds(struct hatm_softc *sc)
370 {
371         int error;
372         u_int i;
373         struct tpd *t;
374
375         DBG(sc, ATTACH, ("allocating %u TPDs and maps ...", sc->tpd_total));
376         error = hatm_alloc_dmamem(sc, "TPD memory", &sc->tpds);
377         if (error != 0) {
378                 DBG(sc, ATTACH, ("... dmamem error=%d", error));
379                 return (error);
380         }
381
382         /* put all the TPDs on the free list and allocate DMA maps */
383         for (i = 0; i < sc->tpd_total; i++) {
384                 t = TPD_ADDR(sc, i);
385                 t->no = i;
386                 t->mbuf = NULL;
387                 error = bus_dmamap_create(sc->tx_tag, 0, &t->map);
388                 if (error != 0) {
389                         DBG(sc, ATTACH, ("... dmamap error=%d", error));
390                         while ((t = SLIST_FIRST(&sc->tpd_free)) != NULL) {
391                                 SLIST_REMOVE_HEAD(&sc->tpd_free, link);
392                                 bus_dmamap_destroy(sc->tx_tag, t->map);
393                         }
394                         hatm_destroy_dmamem(&sc->tpds);
395                         return (error);
396                 }
397
398                 SLIST_INSERT_HEAD(&sc->tpd_free, t, link);
399         }
400
401         /* allocate and zero bitmap */
402         sc->tpd_used = malloc(sizeof(uint8_t) * (sc->tpd_total + 7) / 8,
403             M_DEVBUF, M_ZERO | M_WAITOK);
404         sc->tpd_nfree = sc->tpd_total;
405
406         DBG(sc, ATTACH, ("... done"));
407
408         return (0);
409 }
410
411 /*
412  * Free all the TPDs that where given to the card. 
413  * An mbuf chain may be attached to a TPD - free it also and
414  * unload its associated DMA map.
415  */
416 static void
417 hatm_stop_tpds(struct hatm_softc *sc)
418 {
419         u_int i;
420         struct tpd *t;
421
422         DBG(sc, ATTACH, ("free TPDs ..."));
423         for (i = 0; i < sc->tpd_total; i++) {
424                 if (TPD_TST_USED(sc, i)) {
425                         t = TPD_ADDR(sc, i);
426                         if (t->mbuf) {
427                                 m_freem(t->mbuf);
428                                 t->mbuf = NULL;
429                                 bus_dmamap_unload(sc->tx_tag, t->map);
430                         }
431                         TPD_CLR_USED(sc, i);
432                         SLIST_INSERT_HEAD(&sc->tpd_free, t, link);
433                         sc->tpd_nfree++;
434                 }
435         }
436 }
437
438 /*
439  * This frees ALL resources of this interface and leaves the structure
440  * in an indeterminate state. This is called just before detaching or
441  * on a failed attach. No lock should be held.
442  */
443 static void
444 hatm_destroy(struct hatm_softc *sc)
445 {
446         u_int cid;
447
448         bus_teardown_intr(sc->dev, sc->irqres, sc->ih);
449
450         hatm_destroy_rmaps(sc);
451         hatm_destroy_smbufs(sc);
452         hatm_destroy_tpds(sc);
453
454         if (sc->vcc_zone != NULL) {
455                 for (cid = 0; cid < HE_MAX_VCCS; cid++)
456                         if (sc->vccs[cid] != NULL)
457                                 uma_zfree(sc->vcc_zone, sc->vccs[cid]);
458                 uma_zdestroy(sc->vcc_zone);
459         }
460
461         /*
462          * Release all memory allocated to the various queues and
463          * Status pages. These have there own flag which shows whether
464          * they are really allocated.
465          */
466         hatm_destroy_dmamem(&sc->irq_0.mem);
467         hatm_destroy_dmamem(&sc->rbp_s0.mem);
468         hatm_destroy_dmamem(&sc->rbp_l0.mem);
469         hatm_destroy_dmamem(&sc->rbp_s1.mem);
470         hatm_destroy_dmamem(&sc->rbrq_0.mem);
471         hatm_destroy_dmamem(&sc->rbrq_1.mem);
472         hatm_destroy_dmamem(&sc->tbrq.mem);
473         hatm_destroy_dmamem(&sc->tpdrq.mem);
474         hatm_destroy_dmamem(&sc->hsp_mem);
475
476         if (sc->irqres != NULL)
477                 bus_release_resource(sc->dev, SYS_RES_IRQ,
478                     sc->irqid, sc->irqres);
479
480         if (sc->tx_tag != NULL)
481                 if (bus_dma_tag_destroy(sc->tx_tag))
482                         if_printf(sc->ifp, "mbuf DMA tag busy\n");
483
484         if (sc->mbuf_tag != NULL)
485                 if (bus_dma_tag_destroy(sc->mbuf_tag))
486                         if_printf(sc->ifp, "mbuf DMA tag busy\n");
487
488         if (sc->parent_tag != NULL)
489                 if (bus_dma_tag_destroy(sc->parent_tag))
490                         if_printf(sc->ifp, "parent DMA tag busy\n");
491
492         if (sc->memres != NULL)
493                 bus_release_resource(sc->dev, SYS_RES_MEMORY,
494                     sc->memid, sc->memres);
495
496         sysctl_ctx_free(&sc->sysctl_ctx);
497
498         cv_destroy(&sc->cv_rcclose);
499         cv_destroy(&sc->vcc_cv);
500         mtx_destroy(&sc->mtx);
501
502         if (sc->ifp != NULL)
503                 if_free(sc->ifp);
504 }
505
506 /*
507  * 4.4 Card reset
508  */
509 static int
510 hatm_reset(struct hatm_softc *sc)
511 {
512         u_int v, count;
513
514         WRITE4(sc, HE_REGO_RESET_CNTL, 0x00);
515         BARRIER_W(sc);
516         WRITE4(sc, HE_REGO_RESET_CNTL, 0xff);
517         BARRIER_RW(sc);
518         count = 0;
519         while (((v = READ4(sc, HE_REGO_RESET_CNTL)) & HE_REGM_RESET_STATE) == 0) {
520                 BARRIER_R(sc);
521                 if (++count == 100) {
522                         if_printf(sc->ifp, "reset failed\n");
523                         return (ENXIO);
524                 }
525                 DELAY(1000);
526         }
527         return (0);
528 }
529
530 /*
531  * 4.5 Set Bus Width
532  */
533 static void
534 hatm_init_bus_width(struct hatm_softc *sc)
535 {
536         uint32_t v, v1;
537
538         v = READ4(sc, HE_REGO_HOST_CNTL);
539         BARRIER_R(sc);
540         if (v & HE_REGM_HOST_BUS64) {
541                 sc->pci64 = 1;
542                 v1 = pci_read_config(sc->dev, HE_PCIR_GEN_CNTL_0, 4);
543                 v1 |= HE_PCIM_CTL0_64BIT;
544                 pci_write_config(sc->dev, HE_PCIR_GEN_CNTL_0, v1, 4);
545
546                 v |= HE_REGM_HOST_DESC_RD64
547                     | HE_REGM_HOST_DATA_RD64
548                     | HE_REGM_HOST_DATA_WR64;
549                 WRITE4(sc, HE_REGO_HOST_CNTL, v);
550                 BARRIER_W(sc);
551         } else {
552                 sc->pci64 = 0;
553                 v = pci_read_config(sc->dev, HE_PCIR_GEN_CNTL_0, 4);
554                 v &= ~HE_PCIM_CTL0_64BIT;
555                 pci_write_config(sc->dev, HE_PCIR_GEN_CNTL_0, v, 4);
556         }
557 }
558
559 /*
560  * 4.6 Set Host Endianess
561  */
562 static void
563 hatm_init_endianess(struct hatm_softc *sc)
564 {
565         uint32_t v;
566
567         v = READ4(sc, HE_REGO_LB_SWAP);
568         BARRIER_R(sc);
569 #if BYTE_ORDER == BIG_ENDIAN
570         v |= HE_REGM_LBSWAP_INTR_SWAP |
571             HE_REGM_LBSWAP_DESC_WR_SWAP |
572             HE_REGM_LBSWAP_BIG_ENDIAN;
573         v &= ~(HE_REGM_LBSWAP_DATA_WR_SWAP |
574             HE_REGM_LBSWAP_DESC_RD_SWAP |
575             HE_REGM_LBSWAP_DATA_RD_SWAP);
576 #else
577         v &= ~(HE_REGM_LBSWAP_DATA_WR_SWAP |
578             HE_REGM_LBSWAP_DESC_RD_SWAP |
579             HE_REGM_LBSWAP_DATA_RD_SWAP |
580             HE_REGM_LBSWAP_INTR_SWAP |
581             HE_REGM_LBSWAP_DESC_WR_SWAP |
582             HE_REGM_LBSWAP_BIG_ENDIAN);
583 #endif
584
585         if (sc->he622)
586                 v |= HE_REGM_LBSWAP_XFER_SIZE;
587
588         WRITE4(sc, HE_REGO_LB_SWAP, v);
589         BARRIER_W(sc);
590 }
591
592 /*
593  * 4.7 Read EEPROM
594  */
595 static uint8_t
596 hatm_read_prom_byte(struct hatm_softc *sc, u_int addr)
597 {
598         uint32_t val, tmp_read, byte_read;
599         u_int i, j;
600         int n;
601
602         val = READ4(sc, HE_REGO_HOST_CNTL);
603         val &= HE_REGM_HOST_PROM_BITS;
604         BARRIER_R(sc);
605
606         val |= HE_REGM_HOST_PROM_WREN;
607         WRITE4(sc, HE_REGO_HOST_CNTL, val);
608         BARRIER_W(sc);
609
610         /* send READ */
611         for (i = 0; i < sizeof(readtab) / sizeof(readtab[0]); i++) {
612                 WRITE4(sc, HE_REGO_HOST_CNTL, val | readtab[i]);
613                 BARRIER_W(sc);
614                 DELAY(EEPROM_DELAY);
615         }
616
617         /* send ADDRESS */
618         for (n = 7, j = 0; n >= 0; n--) {
619                 WRITE4(sc, HE_REGO_HOST_CNTL, val | clocktab[j++] |
620                     (((addr >> n) & 1 ) << HE_REGS_HOST_PROM_DATA_IN));
621                 BARRIER_W(sc);
622                 DELAY(EEPROM_DELAY);
623                 WRITE4(sc, HE_REGO_HOST_CNTL, val | clocktab[j++] |
624                     (((addr >> n) & 1 ) << HE_REGS_HOST_PROM_DATA_IN));
625                 BARRIER_W(sc);
626                 DELAY(EEPROM_DELAY);
627         }
628
629         val &= ~HE_REGM_HOST_PROM_WREN;
630         WRITE4(sc, HE_REGO_HOST_CNTL, val);
631         BARRIER_W(sc);
632
633         /* read DATA */
634         byte_read = 0;
635         for (n = 7, j = 0; n >= 0; n--) {
636                 WRITE4(sc, HE_REGO_HOST_CNTL, val | clocktab[j++]);
637                 BARRIER_W(sc);
638                 DELAY(EEPROM_DELAY);
639                 tmp_read = READ4(sc, HE_REGO_HOST_CNTL);
640                 byte_read |= (uint8_t)(((tmp_read & HE_REGM_HOST_PROM_DATA_OUT)
641                                 >> HE_REGS_HOST_PROM_DATA_OUT) << n);
642                 WRITE4(sc, HE_REGO_HOST_CNTL, val | clocktab[j++]);
643                 BARRIER_W(sc);
644                 DELAY(EEPROM_DELAY);
645         }
646         WRITE4(sc, HE_REGO_HOST_CNTL, val | clocktab[j++]);
647         BARRIER_W(sc);
648         DELAY(EEPROM_DELAY);
649
650         return (byte_read);
651 }
652
653 static void
654 hatm_init_read_eeprom(struct hatm_softc *sc)
655 {
656         u_int n, count;
657         u_char byte;
658         uint32_t v;
659
660         for (n = count = 0; count < HE_EEPROM_PROD_ID_LEN; count++) {
661                 byte = hatm_read_prom_byte(sc, HE_EEPROM_PROD_ID + count);
662                 if (n > 0 || byte != ' ')
663                         sc->prod_id[n++] = byte;
664         }
665         while (n > 0 && sc->prod_id[n-1] == ' ')
666                 n--;
667         sc->prod_id[n] = '\0';
668
669         for (n = count = 0; count < HE_EEPROM_REV_LEN; count++) {
670                 byte = hatm_read_prom_byte(sc, HE_EEPROM_REV + count);
671                 if (n > 0 || byte != ' ')
672                         sc->rev[n++] = byte;
673         }
674         while (n > 0 && sc->rev[n-1] == ' ')
675                 n--;
676         sc->rev[n] = '\0';
677         IFP2IFATM(sc->ifp)->mib.hw_version = sc->rev[0];
678
679         IFP2IFATM(sc->ifp)->mib.serial =  hatm_read_prom_byte(sc, HE_EEPROM_M_SN + 0) << 0;
680         IFP2IFATM(sc->ifp)->mib.serial |= hatm_read_prom_byte(sc, HE_EEPROM_M_SN + 1) << 8;
681         IFP2IFATM(sc->ifp)->mib.serial |= hatm_read_prom_byte(sc, HE_EEPROM_M_SN + 2) << 16;
682         IFP2IFATM(sc->ifp)->mib.serial |= hatm_read_prom_byte(sc, HE_EEPROM_M_SN + 3) << 24;
683
684         v =  hatm_read_prom_byte(sc, HE_EEPROM_MEDIA + 0) << 0;
685         v |= hatm_read_prom_byte(sc, HE_EEPROM_MEDIA + 1) << 8;
686         v |= hatm_read_prom_byte(sc, HE_EEPROM_MEDIA + 2) << 16;
687         v |= hatm_read_prom_byte(sc, HE_EEPROM_MEDIA + 3) << 24;
688
689         switch (v) {
690           case HE_MEDIA_UTP155:
691                 IFP2IFATM(sc->ifp)->mib.media = IFM_ATM_UTP_155;
692                 IFP2IFATM(sc->ifp)->mib.pcr = ATM_RATE_155M;
693                 break;
694
695           case HE_MEDIA_MMF155:
696                 IFP2IFATM(sc->ifp)->mib.media = IFM_ATM_MM_155;
697                 IFP2IFATM(sc->ifp)->mib.pcr = ATM_RATE_155M;
698                 break;
699
700           case HE_MEDIA_MMF622:
701                 IFP2IFATM(sc->ifp)->mib.media = IFM_ATM_MM_622;
702                 IFP2IFATM(sc->ifp)->mib.device = ATM_DEVICE_HE622;
703                 IFP2IFATM(sc->ifp)->mib.pcr = ATM_RATE_622M;
704                 sc->he622 = 1;
705                 break;
706
707           case HE_MEDIA_SMF155:
708                 IFP2IFATM(sc->ifp)->mib.media = IFM_ATM_SM_155;
709                 IFP2IFATM(sc->ifp)->mib.pcr = ATM_RATE_155M;
710                 break;
711
712           case HE_MEDIA_SMF622:
713                 IFP2IFATM(sc->ifp)->mib.media = IFM_ATM_SM_622;
714                 IFP2IFATM(sc->ifp)->mib.device = ATM_DEVICE_HE622;
715                 IFP2IFATM(sc->ifp)->mib.pcr = ATM_RATE_622M;
716                 sc->he622 = 1;
717                 break;
718         }
719
720         IFP2IFATM(sc->ifp)->mib.esi[0] = hatm_read_prom_byte(sc, HE_EEPROM_MAC + 0);
721         IFP2IFATM(sc->ifp)->mib.esi[1] = hatm_read_prom_byte(sc, HE_EEPROM_MAC + 1);
722         IFP2IFATM(sc->ifp)->mib.esi[2] = hatm_read_prom_byte(sc, HE_EEPROM_MAC + 2);
723         IFP2IFATM(sc->ifp)->mib.esi[3] = hatm_read_prom_byte(sc, HE_EEPROM_MAC + 3);
724         IFP2IFATM(sc->ifp)->mib.esi[4] = hatm_read_prom_byte(sc, HE_EEPROM_MAC + 4);
725         IFP2IFATM(sc->ifp)->mib.esi[5] = hatm_read_prom_byte(sc, HE_EEPROM_MAC + 5);
726 }
727
728 /*
729  * Clear unused interrupt queue
730  */
731 static void
732 hatm_clear_irq(struct hatm_softc *sc, u_int group)
733 {
734         WRITE4(sc, HE_REGO_IRQ_BASE(group), 0);
735         WRITE4(sc, HE_REGO_IRQ_HEAD(group), 0);
736         WRITE4(sc, HE_REGO_IRQ_CNTL(group), 0);
737         WRITE4(sc, HE_REGO_IRQ_DATA(group), 0);
738 }
739
740 /*
741  * 4.10 Initialize interrupt queues
742  */
743 static void
744 hatm_init_irq(struct hatm_softc *sc, struct heirq *q, u_int group)
745 {
746         u_int i;
747
748         if (q->size == 0) {
749                 hatm_clear_irq(sc, group);
750                 return;
751         }
752
753         q->group = group;
754         q->sc = sc;
755         q->irq = q->mem.base;
756         q->head = 0;
757         q->tailp = q->irq + (q->size - 1);
758         *q->tailp = 0;
759
760         for (i = 0; i < q->size; i++)
761                 q->irq[i] = HE_REGM_ITYPE_INVALID;
762
763         WRITE4(sc, HE_REGO_IRQ_BASE(group), q->mem.paddr);
764         WRITE4(sc, HE_REGO_IRQ_HEAD(group),
765             ((q->size - 1) << HE_REGS_IRQ_HEAD_SIZE) |
766             (q->thresh << HE_REGS_IRQ_HEAD_THRESH));
767         WRITE4(sc, HE_REGO_IRQ_CNTL(group), q->line);
768         WRITE4(sc, HE_REGO_IRQ_DATA(group), 0);
769 }
770
771 /*
772  * 5.1.3 Initialize connection memory
773  */
774 static void
775 hatm_init_cm(struct hatm_softc *sc)
776 {
777         u_int rsra, mlbm, rabr, numbuffs;
778         u_int tsra, tabr, mtpd;
779         u_int n;
780
781         for (n = 0; n < HE_CONFIG_TXMEM; n++)
782                 WRITE_TCM4(sc, n, 0);
783         for (n = 0; n < HE_CONFIG_RXMEM; n++)
784                 WRITE_RCM4(sc, n, 0);
785
786         numbuffs = sc->r0_numbuffs + sc->r1_numbuffs + sc->tx_numbuffs;
787
788         rsra = 0;
789         mlbm = ((rsra + IFP2IFATM(sc->ifp)->mib.max_vccs * 8) + 0x7ff) & ~0x7ff;
790         rabr = ((mlbm + numbuffs * 2) + 0x7ff) & ~0x7ff;
791         sc->rsrb = ((rabr + 2048) + (2 * IFP2IFATM(sc->ifp)->mib.max_vccs - 1)) &
792             ~(2 * IFP2IFATM(sc->ifp)->mib.max_vccs - 1);
793
794         tsra = 0;
795         sc->tsrb = tsra + IFP2IFATM(sc->ifp)->mib.max_vccs * 8;
796         sc->tsrc = sc->tsrb + IFP2IFATM(sc->ifp)->mib.max_vccs * 4;
797         sc->tsrd = sc->tsrc + IFP2IFATM(sc->ifp)->mib.max_vccs * 2;
798         tabr = sc->tsrd + IFP2IFATM(sc->ifp)->mib.max_vccs * 1;
799         mtpd = ((tabr + 1024) + (16 * IFP2IFATM(sc->ifp)->mib.max_vccs - 1)) &
800             ~(16 * IFP2IFATM(sc->ifp)->mib.max_vccs - 1);
801
802         DBG(sc, ATTACH, ("rsra=%x mlbm=%x rabr=%x rsrb=%x",
803             rsra, mlbm, rabr, sc->rsrb));
804         DBG(sc, ATTACH, ("tsra=%x tsrb=%x tsrc=%x tsrd=%x tabr=%x mtpd=%x",
805             tsra, sc->tsrb, sc->tsrc, sc->tsrd, tabr, mtpd));
806
807         WRITE4(sc, HE_REGO_TSRB_BA, sc->tsrb);
808         WRITE4(sc, HE_REGO_TSRC_BA, sc->tsrc);
809         WRITE4(sc, HE_REGO_TSRD_BA, sc->tsrd);
810         WRITE4(sc, HE_REGO_TMABR_BA, tabr);
811         WRITE4(sc, HE_REGO_TPD_BA, mtpd);
812
813         WRITE4(sc, HE_REGO_RCMRSRB_BA, sc->rsrb);
814         WRITE4(sc, HE_REGO_RCMLBM_BA, mlbm);
815         WRITE4(sc, HE_REGO_RCMABR_BA, rabr);
816
817         BARRIER_W(sc);
818 }
819
820 /*
821  * 5.1.4 Initialize Local buffer Pools
822  */
823 static void
824 hatm_init_rx_buffer_pool(struct hatm_softc *sc,
825         u_int num,              /* bank */
826         u_int start,            /* start row */
827         u_int numbuffs          /* number of entries */
828 )
829 {
830         u_int row_size;         /* bytes per row */
831         uint32_t row_addr;      /* start address of this row */
832         u_int lbuf_size;        /* bytes per lbuf */
833         u_int lbufs_per_row;    /* number of lbufs per memory row */
834         uint32_t lbufd_index;   /* index of lbuf descriptor */
835         uint32_t lbufd_addr;    /* address of lbuf descriptor */
836         u_int lbuf_row_cnt;     /* current lbuf in current row */
837         uint32_t lbuf_addr;     /* address of current buffer */
838         u_int i;
839
840         row_size = sc->bytes_per_row;
841         row_addr = start * row_size;
842         lbuf_size = sc->cells_per_lbuf * 48;
843         lbufs_per_row = sc->cells_per_row / sc->cells_per_lbuf;
844
845         /* descriptor index */
846         lbufd_index = num;
847
848         /* 2 words per entry */
849         lbufd_addr = READ4(sc, HE_REGO_RCMLBM_BA) + lbufd_index * 2;
850
851         /* write head of queue */
852         WRITE4(sc, HE_REGO_RLBF_H(num), lbufd_index);
853
854         lbuf_row_cnt = 0;
855         for (i = 0; i < numbuffs; i++) {
856                 lbuf_addr = (row_addr + lbuf_row_cnt * lbuf_size) / 32;
857
858                 WRITE_RCM4(sc, lbufd_addr, lbuf_addr);
859
860                 lbufd_index += 2;
861                 WRITE_RCM4(sc, lbufd_addr + 1, lbufd_index);
862
863                 if (++lbuf_row_cnt == lbufs_per_row) {
864                         lbuf_row_cnt = 0;
865                         row_addr += row_size;
866                 }
867
868                 lbufd_addr += 2 * 2;
869         }
870
871         WRITE4(sc, HE_REGO_RLBF_T(num), lbufd_index - 2);
872         WRITE4(sc, HE_REGO_RLBF_C(num), numbuffs);
873
874         BARRIER_W(sc);
875 }
876
877 static void
878 hatm_init_tx_buffer_pool(struct hatm_softc *sc,
879         u_int start,            /* start row */
880         u_int numbuffs          /* number of entries */
881 )
882 {
883         u_int row_size;         /* bytes per row */
884         uint32_t row_addr;      /* start address of this row */
885         u_int lbuf_size;        /* bytes per lbuf */
886         u_int lbufs_per_row;    /* number of lbufs per memory row */
887         uint32_t lbufd_index;   /* index of lbuf descriptor */
888         uint32_t lbufd_addr;    /* address of lbuf descriptor */
889         u_int lbuf_row_cnt;     /* current lbuf in current row */
890         uint32_t lbuf_addr;     /* address of current buffer */
891         u_int i;
892
893         row_size = sc->bytes_per_row;
894         row_addr = start * row_size;
895         lbuf_size = sc->cells_per_lbuf * 48;
896         lbufs_per_row = sc->cells_per_row / sc->cells_per_lbuf;
897
898         /* descriptor index */
899         lbufd_index = sc->r0_numbuffs + sc->r1_numbuffs;
900
901         /* 2 words per entry */
902         lbufd_addr = READ4(sc, HE_REGO_RCMLBM_BA) + lbufd_index * 2;
903
904         /* write head of queue */
905         WRITE4(sc, HE_REGO_TLBF_H, lbufd_index);
906
907         lbuf_row_cnt = 0;
908         for (i = 0; i < numbuffs; i++) {
909                 lbuf_addr = (row_addr + lbuf_row_cnt * lbuf_size) / 32;
910
911                 WRITE_RCM4(sc, lbufd_addr, lbuf_addr);
912                 lbufd_index++;
913                 WRITE_RCM4(sc, lbufd_addr + 1, lbufd_index);
914
915                 if (++lbuf_row_cnt == lbufs_per_row) {
916                         lbuf_row_cnt = 0;
917                         row_addr += row_size;
918                 }
919
920                 lbufd_addr += 2;
921         }
922
923         WRITE4(sc, HE_REGO_TLBF_T, lbufd_index - 1);
924         BARRIER_W(sc);
925 }
926
927 /*
928  * 5.1.5 Initialize Intermediate Receive Queues
929  */
930 static void
931 hatm_init_imed_queues(struct hatm_softc *sc)
932 {
933         u_int n;
934
935         if (sc->he622) {
936                 for (n = 0; n < 8; n++) {
937                         WRITE4(sc, HE_REGO_INMQ_S(n), 0x10*n+0x000f);
938                         WRITE4(sc, HE_REGO_INMQ_L(n), 0x10*n+0x200f);
939                 }
940         } else {
941                 for (n = 0; n < 8; n++) {
942                         WRITE4(sc, HE_REGO_INMQ_S(n), n);
943                         WRITE4(sc, HE_REGO_INMQ_L(n), n+0x8);
944                 }
945         }
946 }
947
948 /*
949  * 5.1.7 Init CS block
950  */
951 static void
952 hatm_init_cs_block(struct hatm_softc *sc)
953 {
954         u_int n, i;
955         u_int clkfreg, cellrate, decr, tmp;
956         static const uint32_t erthr[2][5][3] = HE_REGT_CS_ERTHR;
957         static const uint32_t erctl[2][3] = HE_REGT_CS_ERCTL;
958         static const uint32_t erstat[2][2] = HE_REGT_CS_ERSTAT;
959         static const uint32_t rtfwr[2] = HE_REGT_CS_RTFWR;
960         static const uint32_t rtatr[2] = HE_REGT_CS_RTATR;
961         static const uint32_t bwalloc[2][6] = HE_REGT_CS_BWALLOC;
962         static const uint32_t orcf[2][2] = HE_REGT_CS_ORCF;
963
964         /* Clear Rate Controller Start Times and Occupied Flags */
965         for (n = 0; n < 32; n++)
966                 WRITE_MBOX4(sc, HE_REGO_CS_STTIM(n), 0);
967
968         clkfreg = sc->he622 ? HE_622_CLOCK : HE_155_CLOCK;
969         cellrate = sc->he622 ? ATM_RATE_622M : ATM_RATE_155M;
970         decr = cellrate / 32;
971
972         for (n = 0; n < 16; n++) {
973                 tmp = clkfreg / cellrate;
974                 WRITE_MBOX4(sc, HE_REGO_CS_TGRLD(n), tmp - 1);
975                 cellrate -= decr;
976         }
977
978         i = (sc->cells_per_lbuf == 2) ? 0
979            :(sc->cells_per_lbuf == 4) ? 1
980            :                            2;
981
982         /* table 5.2 */
983         WRITE_MBOX4(sc, HE_REGO_CS_ERTHR0, erthr[sc->he622][0][i]);
984         WRITE_MBOX4(sc, HE_REGO_CS_ERTHR1, erthr[sc->he622][1][i]);
985         WRITE_MBOX4(sc, HE_REGO_CS_ERTHR2, erthr[sc->he622][2][i]);
986         WRITE_MBOX4(sc, HE_REGO_CS_ERTHR3, erthr[sc->he622][3][i]);
987         WRITE_MBOX4(sc, HE_REGO_CS_ERTHR4, erthr[sc->he622][4][i]);
988
989         WRITE_MBOX4(sc, HE_REGO_CS_ERCTL0, erctl[sc->he622][0]);
990         WRITE_MBOX4(sc, HE_REGO_CS_ERCTL1, erctl[sc->he622][1]);
991         WRITE_MBOX4(sc, HE_REGO_CS_ERCTL2, erctl[sc->he622][2]);
992
993         WRITE_MBOX4(sc, HE_REGO_CS_ERSTAT0, erstat[sc->he622][0]);
994         WRITE_MBOX4(sc, HE_REGO_CS_ERSTAT1, erstat[sc->he622][1]);
995
996         WRITE_MBOX4(sc, HE_REGO_CS_RTFWR, rtfwr[sc->he622]);
997         WRITE_MBOX4(sc, HE_REGO_CS_RTATR, rtatr[sc->he622]);
998
999         WRITE_MBOX4(sc, HE_REGO_CS_TFBSET, bwalloc[sc->he622][0]);
1000         WRITE_MBOX4(sc, HE_REGO_CS_WCRMAX, bwalloc[sc->he622][1]);
1001         WRITE_MBOX4(sc, HE_REGO_CS_WCRMIN, bwalloc[sc->he622][2]);
1002         WRITE_MBOX4(sc, HE_REGO_CS_WCRINC, bwalloc[sc->he622][3]);
1003         WRITE_MBOX4(sc, HE_REGO_CS_WCRDEC, bwalloc[sc->he622][4]);
1004         WRITE_MBOX4(sc, HE_REGO_CS_WCRCEIL, bwalloc[sc->he622][5]);
1005
1006         WRITE_MBOX4(sc, HE_REGO_CS_OTPPER, orcf[sc->he622][0]);
1007         WRITE_MBOX4(sc, HE_REGO_CS_OTWPER, orcf[sc->he622][1]);
1008
1009         WRITE_MBOX4(sc, HE_REGO_CS_OTTLIM, 8);
1010
1011         for (n = 0; n < 8; n++)
1012                 WRITE_MBOX4(sc, HE_REGO_CS_HGRRT(n), 0);
1013 }
1014
1015 /*
1016  * 5.1.8 CS Block Connection Memory Initialisation
1017  */
1018 static void
1019 hatm_init_cs_block_cm(struct hatm_softc *sc)
1020 {
1021         u_int n, i;
1022         u_int expt, mant, etrm, wcr, ttnrm, tnrm;
1023         uint32_t rate;
1024         uint32_t clkfreq, cellrate, decr;
1025         uint32_t *rg, rtg, val = 0;
1026         uint64_t drate;
1027         u_int buf, buf_limit;
1028         uint32_t base = READ4(sc, HE_REGO_RCMABR_BA);
1029
1030         for (n = 0; n < HE_REGL_CM_GQTBL; n++)
1031                 WRITE_RCM4(sc, base + HE_REGO_CM_GQTBL + n, 0);
1032         for (n = 0; n < HE_REGL_CM_RGTBL; n++)
1033                 WRITE_RCM4(sc, base + HE_REGO_CM_RGTBL + n, 0);
1034
1035         tnrm = 0;
1036         for (n = 0; n < HE_REGL_CM_TNRMTBL * 4; n++) {
1037                 expt = (n >> 5) & 0x1f;
1038                 mant = ((n & 0x18) << 4) | 0x7f;
1039                 wcr = (1 << expt) * (mant + 512) / 512;
1040                 etrm = n & 0x7;
1041                 ttnrm = wcr / 10 / (1 << etrm);
1042                 if (ttnrm > 255)
1043                         ttnrm = 255;
1044                 else if(ttnrm < 2)
1045                         ttnrm = 2;
1046                 tnrm = (tnrm << 8) | (ttnrm & 0xff);
1047                 if (n % 4 == 0)
1048                         WRITE_RCM4(sc, base + HE_REGO_CM_TNRMTBL + (n/4), tnrm);
1049         }
1050
1051         clkfreq = sc->he622 ? HE_622_CLOCK : HE_155_CLOCK;
1052         buf_limit = 4;
1053
1054         cellrate = sc->he622 ? ATM_RATE_622M : ATM_RATE_155M;
1055         decr = cellrate / 32;
1056
1057         /* compute GRID top row in 1000 * cps */
1058         for (n = 0; n < 16; n++) {
1059                 u_int interval = clkfreq / cellrate;
1060                 sc->rate_grid[0][n] = (u_int64_t)clkfreq * 1000 / interval;
1061                 cellrate -= decr;
1062         }
1063
1064         /* compute the other rows according to 2.4 */
1065         for (i = 1; i < 16; i++)
1066                 for (n = 0; n < 16; n++)
1067                         sc->rate_grid[i][n] = sc->rate_grid[i-1][n] /
1068                             ((i < 14) ? 2 : 4);
1069
1070         /* first entry is line rate */
1071         n = hatm_cps2atmf(sc->he622 ? ATM_RATE_622M : ATM_RATE_155M);
1072         expt = (n >> 9) & 0x1f;
1073         mant = n & 0x1f0;
1074         sc->rate_grid[0][0] = (u_int64_t)(1<<expt) * 1000 * (mant+512) / 512;
1075
1076         /* now build the conversion table - each 32 bit word contains
1077          * two entries - this gives a total of 0x400 16 bit entries.
1078          * This table maps the truncated ATMF rate version into a grid index */
1079         cellrate = sc->he622 ? ATM_RATE_622M : ATM_RATE_155M;
1080         rg = &sc->rate_grid[15][15];
1081
1082         for (rate = 0; rate < 2 * HE_REGL_CM_RTGTBL; rate++) {
1083                 /* unpack the ATMF rate */
1084                 expt = rate >> 5;
1085                 mant = (rate & 0x1f) << 4;
1086
1087                 /* get the cell rate - minimum is 10 per second */
1088                 drate = (uint64_t)(1 << expt) * 1000 * (mant + 512) / 512;
1089                 if (drate < 10 * 1000)
1090                         drate = 10 * 1000;
1091
1092                 /* now look up the grid index */
1093                 while (drate >= *rg && rg-- > &sc->rate_grid[0][0])
1094                         ;
1095                 rg++;
1096                 rtg = rg - &sc->rate_grid[0][0];
1097
1098                 /* now compute the buffer limit */
1099                 buf = drate * sc->tx_numbuffs / (cellrate * 2) / 1000;
1100                 if (buf == 0)
1101                         buf = 1;
1102                 else if (buf > buf_limit)
1103                         buf = buf_limit;
1104
1105                 /* make value */
1106                 val = (val << 16) | (rtg << 8) | buf;
1107
1108                 /* write */
1109                 if (rate % 2 == 1)
1110                         WRITE_RCM4(sc, base + HE_REGO_CM_RTGTBL + rate/2, val);
1111         }
1112 }
1113
1114 /*
1115  * Clear an unused receive group buffer pool
1116  */
1117 static void
1118 hatm_clear_rpool(struct hatm_softc *sc, u_int group, u_int large)
1119 {
1120         WRITE4(sc, HE_REGO_RBP_S(large, group), 0);
1121         WRITE4(sc, HE_REGO_RBP_T(large, group), 0);
1122         WRITE4(sc, HE_REGO_RBP_QI(large, group), 1);
1123         WRITE4(sc, HE_REGO_RBP_BL(large, group), 0);
1124 }
1125
1126 /*
1127  * Initialize a receive group buffer pool
1128  */
1129 static void
1130 hatm_init_rpool(struct hatm_softc *sc, struct herbp *q, u_int group,
1131     u_int large)
1132 {
1133         if (q->size == 0) {
1134                 hatm_clear_rpool(sc, group, large);
1135                 return;
1136         }
1137
1138         bzero(q->mem.base, q->mem.size);
1139         q->rbp = q->mem.base;
1140         q->head = q->tail = 0;
1141
1142         DBG(sc, ATTACH, ("RBP%u%c=0x%lx", group, "SL"[large],
1143             (u_long)q->mem.paddr));
1144
1145         WRITE4(sc, HE_REGO_RBP_S(large, group), q->mem.paddr);
1146         WRITE4(sc, HE_REGO_RBP_T(large, group), 0);
1147         WRITE4(sc, HE_REGO_RBP_QI(large, group),
1148             ((q->size - 1) << HE_REGS_RBP_SIZE) |
1149             HE_REGM_RBP_INTR_ENB |
1150             (q->thresh << HE_REGS_RBP_THRESH));
1151         WRITE4(sc, HE_REGO_RBP_BL(large, group), (q->bsize >> 2) & ~1);
1152 }
1153
1154 /*
1155  * Clear an unused receive buffer return queue
1156  */
1157 static void
1158 hatm_clear_rbrq(struct hatm_softc *sc, u_int group)
1159 {
1160         WRITE4(sc, HE_REGO_RBRQ_ST(group), 0);
1161         WRITE4(sc, HE_REGO_RBRQ_H(group), 0);
1162         WRITE4(sc, HE_REGO_RBRQ_Q(group), (1 << HE_REGS_RBRQ_THRESH));
1163         WRITE4(sc, HE_REGO_RBRQ_I(group), 0);
1164 }
1165
1166 /*
1167  * Initialize receive buffer return queue
1168  */
1169 static void
1170 hatm_init_rbrq(struct hatm_softc *sc, struct herbrq *rq, u_int group)
1171 {
1172         if (rq->size == 0) {
1173                 hatm_clear_rbrq(sc, group);
1174                 return;
1175         }
1176
1177         rq->rbrq = rq->mem.base;
1178         rq->head = 0;
1179
1180         DBG(sc, ATTACH, ("RBRQ%u=0x%lx", group, (u_long)rq->mem.paddr));
1181
1182         WRITE4(sc, HE_REGO_RBRQ_ST(group), rq->mem.paddr);
1183         WRITE4(sc, HE_REGO_RBRQ_H(group), 0);
1184         WRITE4(sc, HE_REGO_RBRQ_Q(group),
1185             (rq->thresh << HE_REGS_RBRQ_THRESH) |
1186             ((rq->size - 1) << HE_REGS_RBRQ_SIZE));
1187         WRITE4(sc, HE_REGO_RBRQ_I(group),
1188             (rq->tout << HE_REGS_RBRQ_TIME) |
1189             (rq->pcnt << HE_REGS_RBRQ_COUNT));
1190 }
1191
1192 /*
1193  * Clear an unused transmit buffer return queue N
1194  */
1195 static void
1196 hatm_clear_tbrq(struct hatm_softc *sc, u_int group)
1197 {
1198         WRITE4(sc, HE_REGO_TBRQ_B_T(group), 0);
1199         WRITE4(sc, HE_REGO_TBRQ_H(group), 0);
1200         WRITE4(sc, HE_REGO_TBRQ_S(group), 0);
1201         WRITE4(sc, HE_REGO_TBRQ_THRESH(group), 1);
1202 }
1203
1204 /*
1205  * Initialize transmit buffer return queue N
1206  */
1207 static void
1208 hatm_init_tbrq(struct hatm_softc *sc, struct hetbrq *tq, u_int group)
1209 {
1210         if (tq->size == 0) {
1211                 hatm_clear_tbrq(sc, group);
1212                 return;
1213         }
1214
1215         tq->tbrq = tq->mem.base;
1216         tq->head = 0;
1217
1218         DBG(sc, ATTACH, ("TBRQ%u=0x%lx", group, (u_long)tq->mem.paddr));
1219
1220         WRITE4(sc, HE_REGO_TBRQ_B_T(group), tq->mem.paddr);
1221         WRITE4(sc, HE_REGO_TBRQ_H(group), 0);
1222         WRITE4(sc, HE_REGO_TBRQ_S(group), tq->size - 1);
1223         WRITE4(sc, HE_REGO_TBRQ_THRESH(group), tq->thresh);
1224 }
1225
1226 /*
1227  * Initialize TPDRQ
1228  */
1229 static void
1230 hatm_init_tpdrq(struct hatm_softc *sc)
1231 {
1232         struct hetpdrq *tq;
1233
1234         tq = &sc->tpdrq;
1235         tq->tpdrq = tq->mem.base;
1236         tq->tail = tq->head = 0;
1237
1238         DBG(sc, ATTACH, ("TPDRQ=0x%lx", (u_long)tq->mem.paddr));
1239
1240         WRITE4(sc, HE_REGO_TPDRQ_H, tq->mem.paddr);
1241         WRITE4(sc, HE_REGO_TPDRQ_T, 0);
1242         WRITE4(sc, HE_REGO_TPDRQ_S, tq->size - 1);
1243 }
1244
1245 /*
1246  * Function can be called by the infrastructure to start the card.
1247  */
1248 static void
1249 hatm_init(void *p)
1250 {
1251         struct hatm_softc *sc = p;
1252
1253         mtx_lock(&sc->mtx);
1254         hatm_stop(sc);
1255         hatm_initialize(sc);
1256         mtx_unlock(&sc->mtx);
1257 }
1258
1259 enum {
1260         CTL_ISTATS,
1261 };
1262
1263 /*
1264  * Sysctl handler
1265  */
1266 static int
1267 hatm_sysctl(SYSCTL_HANDLER_ARGS)
1268 {
1269         struct hatm_softc *sc = arg1;
1270         uint32_t *ret;
1271         int error;
1272         size_t len;
1273
1274         switch (arg2) {
1275
1276           case CTL_ISTATS:
1277                 len = sizeof(sc->istats);
1278                 break;
1279
1280           default:
1281                 panic("bad control code");
1282         }
1283
1284         ret = malloc(len, M_TEMP, M_WAITOK);
1285         mtx_lock(&sc->mtx);
1286
1287         switch (arg2) {
1288
1289           case CTL_ISTATS:
1290                 sc->istats.mcc += READ4(sc, HE_REGO_MCC);
1291                 sc->istats.oec += READ4(sc, HE_REGO_OEC);
1292                 sc->istats.dcc += READ4(sc, HE_REGO_DCC);
1293                 sc->istats.cec += READ4(sc, HE_REGO_CEC);
1294                 bcopy(&sc->istats, ret, sizeof(sc->istats));
1295                 break;
1296         }
1297         mtx_unlock(&sc->mtx);
1298
1299         error = SYSCTL_OUT(req, ret, len);
1300         free(ret, M_TEMP);
1301
1302         return (error);
1303 }
1304
1305 static int
1306 kenv_getuint(struct hatm_softc *sc, const char *var,
1307     u_int *ptr, u_int def, int rw)
1308 {
1309         char full[IFNAMSIZ + 3 + 20];
1310         char *val, *end;
1311         u_int u;
1312
1313         *ptr = def;
1314
1315         if (rw != 0) {
1316                 if (SYSCTL_ADD_UINT(&sc->sysctl_ctx,
1317                     SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, var,
1318                     CTLFLAG_RW, ptr, 0, "") == NULL)
1319                         return (ENOMEM);
1320         } else {
1321                 if (SYSCTL_ADD_UINT(&sc->sysctl_ctx,
1322                     SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, var,
1323                     CTLFLAG_RD, ptr, 0, "") == NULL)
1324                         return (ENOMEM);
1325         }
1326
1327         snprintf(full, sizeof(full), "hw.%s.%s",
1328             device_get_nameunit(sc->dev), var);
1329
1330         if ((val = kern_getenv(full)) == NULL)
1331                 return (0);
1332         u = strtoul(val, &end, 0);
1333         if (end == val || *end != '\0') {
1334                 freeenv(val);
1335                 return (EINVAL);
1336         }
1337         freeenv(val);
1338         if (bootverbose)
1339                 if_printf(sc->ifp, "%s=%u\n", full, u);
1340         *ptr = u;
1341         return (0);
1342 }
1343
1344 /*
1345  * Set configurable parameters. Many of these are configurable via
1346  * kenv.
1347  */
1348 static int
1349 hatm_configure(struct hatm_softc *sc)
1350 {
1351         /* Receive buffer pool 0 small */
1352         kenv_getuint(sc, "rbps0_size", &sc->rbp_s0.size,
1353             HE_CONFIG_RBPS0_SIZE, 0);
1354         kenv_getuint(sc, "rbps0_thresh", &sc->rbp_s0.thresh,
1355             HE_CONFIG_RBPS0_THRESH, 0);
1356         sc->rbp_s0.bsize = MBUF0_SIZE;
1357
1358         /* Receive buffer pool 0 large */
1359         kenv_getuint(sc, "rbpl0_size", &sc->rbp_l0.size,
1360             HE_CONFIG_RBPL0_SIZE, 0);
1361         kenv_getuint(sc, "rbpl0_thresh", &sc->rbp_l0.thresh,
1362             HE_CONFIG_RBPL0_THRESH, 0);
1363         sc->rbp_l0.bsize = MCLBYTES - MBUFL_OFFSET;
1364
1365         /* Receive buffer return queue 0 */
1366         kenv_getuint(sc, "rbrq0_size", &sc->rbrq_0.size,
1367             HE_CONFIG_RBRQ0_SIZE, 0);
1368         kenv_getuint(sc, "rbrq0_thresh", &sc->rbrq_0.thresh,
1369             HE_CONFIG_RBRQ0_THRESH, 0);
1370         kenv_getuint(sc, "rbrq0_tout", &sc->rbrq_0.tout,
1371             HE_CONFIG_RBRQ0_TOUT, 0);
1372         kenv_getuint(sc, "rbrq0_pcnt", &sc->rbrq_0.pcnt,
1373             HE_CONFIG_RBRQ0_PCNT, 0);
1374
1375         /* Receive buffer pool 1 small */
1376         kenv_getuint(sc, "rbps1_size", &sc->rbp_s1.size,
1377             HE_CONFIG_RBPS1_SIZE, 0);
1378         kenv_getuint(sc, "rbps1_thresh", &sc->rbp_s1.thresh,
1379             HE_CONFIG_RBPS1_THRESH, 0);
1380         sc->rbp_s1.bsize = MBUF1_SIZE;
1381
1382         /* Receive buffer return queue 1 */
1383         kenv_getuint(sc, "rbrq1_size", &sc->rbrq_1.size,
1384             HE_CONFIG_RBRQ1_SIZE, 0);
1385         kenv_getuint(sc, "rbrq1_thresh", &sc->rbrq_1.thresh,
1386             HE_CONFIG_RBRQ1_THRESH, 0);
1387         kenv_getuint(sc, "rbrq1_tout", &sc->rbrq_1.tout,
1388             HE_CONFIG_RBRQ1_TOUT, 0);
1389         kenv_getuint(sc, "rbrq1_pcnt", &sc->rbrq_1.pcnt,
1390             HE_CONFIG_RBRQ1_PCNT, 0);
1391
1392         /* Interrupt queue 0 */
1393         kenv_getuint(sc, "irq0_size", &sc->irq_0.size,
1394             HE_CONFIG_IRQ0_SIZE, 0);
1395         kenv_getuint(sc, "irq0_thresh", &sc->irq_0.thresh,
1396             HE_CONFIG_IRQ0_THRESH, 0);
1397         sc->irq_0.line = HE_CONFIG_IRQ0_LINE;
1398
1399         /* Transmit buffer return queue 0 */
1400         kenv_getuint(sc, "tbrq0_size", &sc->tbrq.size,
1401             HE_CONFIG_TBRQ_SIZE, 0);
1402         kenv_getuint(sc, "tbrq0_thresh", &sc->tbrq.thresh,
1403             HE_CONFIG_TBRQ_THRESH, 0);
1404
1405         /* Transmit buffer ready queue */
1406         kenv_getuint(sc, "tpdrq_size", &sc->tpdrq.size,
1407             HE_CONFIG_TPDRQ_SIZE, 0);
1408         /* Max TPDs per VCC */
1409         kenv_getuint(sc, "tpdmax", &sc->max_tpd,
1410             HE_CONFIG_TPD_MAXCC, 0);
1411
1412         /* external mbuf pages */
1413         kenv_getuint(sc, "max_mbuf_pages", &sc->mbuf_max_pages,
1414             HE_CONFIG_MAX_MBUF_PAGES, 0);
1415
1416         /* mpsafe */
1417         kenv_getuint(sc, "mpsafe", &sc->mpsafe, 0, 0);
1418         if (sc->mpsafe != 0)
1419                 sc->mpsafe = INTR_MPSAFE;
1420
1421         return (0);
1422 }
1423
1424 #ifdef HATM_DEBUG
1425
1426 /*
1427  * Get TSRs from connection memory
1428  */
1429 static int
1430 hatm_sysctl_tsr(SYSCTL_HANDLER_ARGS)
1431 {
1432         struct hatm_softc *sc = arg1;
1433         int error, i, j;
1434         uint32_t *val;
1435
1436         val = malloc(sizeof(uint32_t) * HE_MAX_VCCS * 15, M_TEMP, M_WAITOK);
1437
1438         mtx_lock(&sc->mtx);
1439         for (i = 0; i < HE_MAX_VCCS; i++)
1440                 for (j = 0; j <= 14; j++)
1441                         val[15 * i + j] = READ_TSR(sc, i, j);
1442         mtx_unlock(&sc->mtx);
1443
1444         error = SYSCTL_OUT(req, val, sizeof(uint32_t) * HE_MAX_VCCS * 15);
1445         free(val, M_TEMP);
1446         if (error != 0 || req->newptr == NULL)
1447                 return (error);
1448
1449         return (EPERM);
1450 }
1451
1452 /*
1453  * Get TPDs from connection memory
1454  */
1455 static int
1456 hatm_sysctl_tpd(SYSCTL_HANDLER_ARGS)
1457 {
1458         struct hatm_softc *sc = arg1;
1459         int error, i, j;
1460         uint32_t *val;
1461
1462         val = malloc(sizeof(uint32_t) * HE_MAX_VCCS * 16, M_TEMP, M_WAITOK);
1463
1464         mtx_lock(&sc->mtx);
1465         for (i = 0; i < HE_MAX_VCCS; i++)
1466                 for (j = 0; j < 16; j++)
1467                         val[16 * i + j] = READ_TCM4(sc, 16 * i + j);
1468         mtx_unlock(&sc->mtx);
1469
1470         error = SYSCTL_OUT(req, val, sizeof(uint32_t) * HE_MAX_VCCS * 16);
1471         free(val, M_TEMP);
1472         if (error != 0 || req->newptr == NULL)
1473                 return (error);
1474
1475         return (EPERM);
1476 }
1477
1478 /*
1479  * Get mbox registers
1480  */
1481 static int
1482 hatm_sysctl_mbox(SYSCTL_HANDLER_ARGS)
1483 {
1484         struct hatm_softc *sc = arg1;
1485         int error, i;
1486         uint32_t *val;
1487
1488         val = malloc(sizeof(uint32_t) * HE_REGO_CS_END, M_TEMP, M_WAITOK);
1489
1490         mtx_lock(&sc->mtx);
1491         for (i = 0; i < HE_REGO_CS_END; i++)
1492                 val[i] = READ_MBOX4(sc, i);
1493         mtx_unlock(&sc->mtx);
1494
1495         error = SYSCTL_OUT(req, val, sizeof(uint32_t) * HE_REGO_CS_END);
1496         free(val, M_TEMP);
1497         if (error != 0 || req->newptr == NULL)
1498                 return (error);
1499
1500         return (EPERM);
1501 }
1502
1503 /*
1504  * Get connection memory
1505  */
1506 static int
1507 hatm_sysctl_cm(SYSCTL_HANDLER_ARGS)
1508 {
1509         struct hatm_softc *sc = arg1;
1510         int error, i;
1511         uint32_t *val;
1512
1513         val = malloc(sizeof(uint32_t) * (HE_CONFIG_RXMEM + 1), M_TEMP, M_WAITOK);
1514
1515         mtx_lock(&sc->mtx);
1516         val[0] = READ4(sc, HE_REGO_RCMABR_BA);
1517         for (i = 0; i < HE_CONFIG_RXMEM; i++)
1518                 val[i + 1] = READ_RCM4(sc, i);
1519         mtx_unlock(&sc->mtx);
1520
1521         error = SYSCTL_OUT(req, val, sizeof(uint32_t) * (HE_CONFIG_RXMEM + 1));
1522         free(val, M_TEMP);
1523         if (error != 0 || req->newptr == NULL)
1524                 return (error);
1525
1526         return (EPERM);
1527 }
1528
1529 /*
1530  * Get local buffer memory
1531  */
1532 static int
1533 hatm_sysctl_lbmem(SYSCTL_HANDLER_ARGS)
1534 {
1535         struct hatm_softc *sc = arg1;
1536         int error, i;
1537         uint32_t *val;
1538         u_int bytes = (1 << 21);
1539
1540         val = malloc(bytes, M_TEMP, M_WAITOK);
1541
1542         mtx_lock(&sc->mtx);
1543         for (i = 0; i < bytes / 4; i++)
1544                 val[i] = READ_LB4(sc, i);
1545         mtx_unlock(&sc->mtx);
1546
1547         error = SYSCTL_OUT(req, val, bytes);
1548         free(val, M_TEMP);
1549         if (error != 0 || req->newptr == NULL)
1550                 return (error);
1551
1552         return (EPERM);
1553 }
1554
1555 /*
1556  * Get all card registers
1557  */
1558 static int
1559 hatm_sysctl_heregs(SYSCTL_HANDLER_ARGS)
1560 {
1561         struct hatm_softc *sc = arg1;
1562         int error, i;
1563         uint32_t *val;
1564
1565         val = malloc(HE_REGO_END, M_TEMP, M_WAITOK);
1566
1567         mtx_lock(&sc->mtx);
1568         for (i = 0; i < HE_REGO_END; i += 4)
1569                 val[i / 4] = READ4(sc, i);
1570         mtx_unlock(&sc->mtx);
1571
1572         error = SYSCTL_OUT(req, val, HE_REGO_END);
1573         free(val, M_TEMP);
1574         if (error != 0 || req->newptr == NULL)
1575                 return (error);
1576
1577         return (EPERM);
1578 }
1579 #endif
1580
1581 /*
1582  * Suni register access
1583  */
1584 /*
1585  * read at most n SUNI registers starting at reg into val
1586  */
1587 static int
1588 hatm_utopia_readregs(struct ifatm *ifatm, u_int reg, uint8_t *val, u_int *n)
1589 {
1590         u_int i;
1591         struct hatm_softc *sc = ifatm->ifp->if_softc;
1592
1593         if (reg >= (HE_REGO_SUNI_END - HE_REGO_SUNI) / 4)
1594                 return (EINVAL);
1595         if (reg + *n > (HE_REGO_SUNI_END - HE_REGO_SUNI) / 4)
1596                 *n = reg - (HE_REGO_SUNI_END - HE_REGO_SUNI) / 4;
1597
1598         mtx_assert(&sc->mtx, MA_OWNED);
1599         for (i = 0; i < *n; i++)
1600                 val[i] = READ4(sc, HE_REGO_SUNI + 4 * (reg + i));
1601
1602         return (0);
1603 }
1604
1605 /*
1606  * change the bits given by mask to them in val in register reg
1607  */
1608 static int
1609 hatm_utopia_writereg(struct ifatm *ifatm, u_int reg, u_int mask, u_int val)
1610 {
1611         uint32_t regval;
1612         struct hatm_softc *sc = ifatm->ifp->if_softc;
1613
1614         if (reg >= (HE_REGO_SUNI_END - HE_REGO_SUNI) / 4)
1615                 return (EINVAL);
1616
1617         mtx_assert(&sc->mtx, MA_OWNED);
1618         regval = READ4(sc, HE_REGO_SUNI + 4 * reg);
1619         regval = (regval & ~mask) | (val & mask);
1620         WRITE4(sc, HE_REGO_SUNI + 4 * reg, regval);
1621
1622         return (0);
1623 }
1624
1625 static struct utopia_methods hatm_utopia_methods = {
1626         hatm_utopia_readregs,
1627         hatm_utopia_writereg,
1628 };
1629
1630 /*
1631  * Detach - if it is running, stop. Destroy.
1632  */
1633 static int
1634 hatm_detach(device_t dev)
1635 {
1636         struct hatm_softc *sc = device_get_softc(dev);
1637
1638         mtx_lock(&sc->mtx);
1639         hatm_stop(sc);
1640         if (sc->utopia.state & UTP_ST_ATTACHED) {
1641                 utopia_stop(&sc->utopia);
1642                 utopia_detach(&sc->utopia);
1643         }
1644         mtx_unlock(&sc->mtx);
1645
1646         atm_ifdetach(sc->ifp);
1647
1648         hatm_destroy(sc);
1649
1650         return (0);
1651 }
1652
1653 /*
1654  * Attach to the device. Assume that no locking is needed here.
1655  * All resource we allocate here are freed by calling hatm_destroy.
1656  */
1657 static int
1658 hatm_attach(device_t dev)
1659 {
1660         struct hatm_softc *sc;
1661         int error;
1662         uint32_t v;
1663         struct ifnet *ifp;
1664
1665         sc = device_get_softc(dev);
1666
1667         ifp = sc->ifp = if_alloc(IFT_ATM);
1668         if (ifp == NULL) {
1669                 device_printf(dev, "could not if_alloc()\n");
1670                 return (ENOSPC);
1671         }
1672
1673         sc->dev = dev;
1674         IFP2IFATM(sc->ifp)->mib.device = ATM_DEVICE_HE155;
1675         IFP2IFATM(sc->ifp)->mib.serial = 0;
1676         IFP2IFATM(sc->ifp)->mib.hw_version = 0;
1677         IFP2IFATM(sc->ifp)->mib.sw_version = 0;
1678         IFP2IFATM(sc->ifp)->mib.vpi_bits = HE_CONFIG_VPI_BITS;
1679         IFP2IFATM(sc->ifp)->mib.vci_bits = HE_CONFIG_VCI_BITS;
1680         IFP2IFATM(sc->ifp)->mib.max_vpcs = 0;
1681         IFP2IFATM(sc->ifp)->mib.max_vccs = HE_MAX_VCCS;
1682         IFP2IFATM(sc->ifp)->mib.media = IFM_ATM_UNKNOWN;
1683         sc->he622 = 0;
1684         IFP2IFATM(sc->ifp)->phy = &sc->utopia;
1685
1686         SLIST_INIT(&sc->tpd_free);
1687
1688         mtx_init(&sc->mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF);
1689         cv_init(&sc->vcc_cv, "HEVCCcv");
1690         cv_init(&sc->cv_rcclose, "RCClose");
1691
1692         sysctl_ctx_init(&sc->sysctl_ctx);
1693
1694         /*
1695          * 4.2 BIOS Configuration
1696          */
1697         v = pci_read_config(dev, PCIR_COMMAND, 2);
1698         v |= PCIM_CMD_BUSMASTEREN | PCIM_CMD_MWRICEN;
1699         pci_write_config(dev, PCIR_COMMAND, v, 2);
1700
1701         /*
1702          * 4.3 PCI Bus Controller-Specific Initialisation
1703          */
1704         v = pci_read_config(dev, HE_PCIR_GEN_CNTL_0, 4);
1705         v |= HE_PCIM_CTL0_MRL | HE_PCIM_CTL0_MRM | HE_PCIM_CTL0_IGNORE_TIMEOUT;
1706 #if BYTE_ORDER == BIG_ENDIAN && 0
1707         v |= HE_PCIM_CTL0_BIGENDIAN;
1708 #endif
1709         pci_write_config(dev, HE_PCIR_GEN_CNTL_0, v, 4);
1710
1711         /*
1712          * Map memory
1713          */
1714         sc->memid = PCIR_BAR(0);
1715         sc->memres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->memid,
1716             RF_ACTIVE);
1717         if (sc->memres == NULL) {
1718                 device_printf(dev, "could not map memory\n");
1719                 error = ENXIO;
1720                 goto failed;
1721         }
1722         sc->memh = rman_get_bushandle(sc->memres);
1723         sc->memt = rman_get_bustag(sc->memres);
1724
1725         /*
1726          * ALlocate a DMA tag for subsequent allocations
1727          */
1728         if (bus_dma_tag_create(bus_get_dma_tag(sc->dev), 1, 0,
1729             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
1730             NULL, NULL,
1731             BUS_SPACE_MAXSIZE_32BIT, 1,
1732             BUS_SPACE_MAXSIZE_32BIT, 0,
1733             NULL, NULL, &sc->parent_tag)) {
1734                 device_printf(dev, "could not allocate DMA tag\n");
1735                 error = ENOMEM;
1736                 goto failed;
1737         }
1738
1739         if (bus_dma_tag_create(sc->parent_tag, 1, 0,
1740             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR,
1741             NULL, NULL,
1742             MBUF_ALLOC_SIZE, 1,
1743             MBUF_ALLOC_SIZE, 0,
1744             NULL, NULL, &sc->mbuf_tag)) {
1745                 device_printf(dev, "could not allocate mbuf DMA tag\n");
1746                 error = ENOMEM;
1747                 goto failed;
1748         }
1749
1750         /*
1751          * Allocate a DMA tag for packets to send. Here we have a problem with
1752          * the specification of the maximum number of segments. Theoretically
1753          * this would be the size of the transmit ring - 1 multiplied by 3,
1754          * but this would not work. So make the maximum number of TPDs
1755          * occupied by one packet a configuration parameter.
1756          */
1757         if (bus_dma_tag_create(bus_get_dma_tag(sc->dev), 1, 0,
1758             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
1759             HE_MAX_PDU, 3 * HE_CONFIG_MAX_TPD_PER_PACKET, HE_MAX_PDU, 0,
1760             NULL, NULL, &sc->tx_tag)) {
1761                 device_printf(dev, "could not allocate TX tag\n");
1762                 error = ENOMEM;
1763                 goto failed;
1764         }
1765
1766         /*
1767          * Setup the interrupt
1768          */
1769         sc->irqid = 0;
1770         sc->irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
1771             RF_SHAREABLE | RF_ACTIVE);
1772         if (sc->irqres == 0) {
1773                 device_printf(dev, "could not allocate irq\n");
1774                 error = ENXIO;
1775                 goto failed;
1776         }
1777
1778         ifp->if_softc = sc;
1779         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
1780
1781         /*
1782          * Make the sysctl tree
1783          */
1784         error = ENOMEM;
1785         if ((sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx,
1786             SYSCTL_STATIC_CHILDREN(_hw_atm), OID_AUTO,
1787             device_get_nameunit(dev), CTLFLAG_RD, 0, "")) == NULL)
1788                 goto failed;
1789
1790         if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
1791             OID_AUTO, "istats", CTLFLAG_RD | CTLTYPE_OPAQUE, sc, CTL_ISTATS,
1792             hatm_sysctl, "LU", "internal statistics") == NULL)
1793                 goto failed;
1794
1795 #ifdef HATM_DEBUG
1796         if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
1797             OID_AUTO, "tsr", CTLFLAG_RD | CTLTYPE_OPAQUE, sc, 0,
1798             hatm_sysctl_tsr, "S", "transmission status registers") == NULL)
1799                 goto failed;
1800
1801         if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
1802             OID_AUTO, "tpd", CTLFLAG_RD | CTLTYPE_OPAQUE, sc, 0,
1803             hatm_sysctl_tpd, "S", "transmission packet descriptors") == NULL)
1804                 goto failed;
1805
1806         if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
1807             OID_AUTO, "mbox", CTLFLAG_RD | CTLTYPE_OPAQUE, sc, 0,
1808             hatm_sysctl_mbox, "S", "mbox registers") == NULL)
1809                 goto failed;
1810
1811         if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
1812             OID_AUTO, "cm", CTLFLAG_RD | CTLTYPE_OPAQUE, sc, 0,
1813             hatm_sysctl_cm, "S", "connection memory") == NULL)
1814                 goto failed;
1815
1816         if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
1817             OID_AUTO, "heregs", CTLFLAG_RD | CTLTYPE_OPAQUE, sc, 0,
1818             hatm_sysctl_heregs, "S", "card registers") == NULL)
1819                 goto failed;
1820
1821         if (SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
1822             OID_AUTO, "lbmem", CTLFLAG_RD | CTLTYPE_OPAQUE, sc, 0,
1823             hatm_sysctl_lbmem, "S", "local memory") == NULL)
1824                 goto failed;
1825
1826         kenv_getuint(sc, "debug", &sc->debug, HATM_DEBUG, 1);
1827 #endif
1828
1829         /*
1830          * Configure
1831          */
1832         if ((error = hatm_configure(sc)) != 0)
1833                 goto failed;
1834
1835         /*
1836          * Compute memory parameters
1837          */
1838         if (sc->rbp_s0.size != 0) {
1839                 sc->rbp_s0.mask = (sc->rbp_s0.size - 1) << 3;
1840                 sc->rbp_s0.mem.size = sc->rbp_s0.size * 8;
1841                 sc->rbp_s0.mem.align = sc->rbp_s0.mem.size;
1842         }
1843         if (sc->rbp_l0.size != 0) {
1844                 sc->rbp_l0.mask = (sc->rbp_l0.size - 1) << 3;
1845                 sc->rbp_l0.mem.size = sc->rbp_l0.size * 8;
1846                 sc->rbp_l0.mem.align = sc->rbp_l0.mem.size;
1847         }
1848         if (sc->rbp_s1.size != 0) {
1849                 sc->rbp_s1.mask = (sc->rbp_s1.size - 1) << 3;
1850                 sc->rbp_s1.mem.size = sc->rbp_s1.size * 8;
1851                 sc->rbp_s1.mem.align = sc->rbp_s1.mem.size;
1852         }
1853         if (sc->rbrq_0.size != 0) {
1854                 sc->rbrq_0.mem.size = sc->rbrq_0.size * 8;
1855                 sc->rbrq_0.mem.align = sc->rbrq_0.mem.size;
1856         }
1857         if (sc->rbrq_1.size != 0) {
1858                 sc->rbrq_1.mem.size = sc->rbrq_1.size * 8;
1859                 sc->rbrq_1.mem.align = sc->rbrq_1.mem.size;
1860         }
1861
1862         sc->irq_0.mem.size = sc->irq_0.size * sizeof(uint32_t);
1863         sc->irq_0.mem.align = 4 * 1024;
1864
1865         sc->tbrq.mem.size = sc->tbrq.size * 4;
1866         sc->tbrq.mem.align = 2 * sc->tbrq.mem.size; /* ZZZ */
1867
1868         sc->tpdrq.mem.size = sc->tpdrq.size * 8;
1869         sc->tpdrq.mem.align = sc->tpdrq.mem.size;
1870
1871         sc->hsp_mem.size = sizeof(struct he_hsp);
1872         sc->hsp_mem.align = 1024;
1873
1874         sc->lbufs_size = sc->rbp_l0.size + sc->rbrq_0.size;
1875         sc->tpd_total = sc->tbrq.size + sc->tpdrq.size;
1876         sc->tpds.align = 64;
1877         sc->tpds.size = sc->tpd_total * HE_TPD_SIZE;
1878
1879         hatm_init_rmaps(sc);
1880         hatm_init_smbufs(sc);
1881         if ((error = hatm_init_tpds(sc)) != 0)
1882                 goto failed;
1883
1884         /*
1885          * Allocate memory
1886          */
1887         if ((error = hatm_alloc_dmamem(sc, "IRQ", &sc->irq_0.mem)) != 0 ||
1888             (error = hatm_alloc_dmamem(sc, "TBRQ0", &sc->tbrq.mem)) != 0 ||
1889             (error = hatm_alloc_dmamem(sc, "TPDRQ", &sc->tpdrq.mem)) != 0 ||
1890             (error = hatm_alloc_dmamem(sc, "HSP", &sc->hsp_mem)) != 0)
1891                 goto failed;
1892
1893         if (sc->rbp_s0.mem.size != 0 &&
1894             (error = hatm_alloc_dmamem(sc, "RBPS0", &sc->rbp_s0.mem)))
1895                 goto failed;
1896         if (sc->rbp_l0.mem.size != 0 &&
1897             (error = hatm_alloc_dmamem(sc, "RBPL0", &sc->rbp_l0.mem)))
1898                 goto failed;
1899         if (sc->rbp_s1.mem.size != 0 &&
1900             (error = hatm_alloc_dmamem(sc, "RBPS1", &sc->rbp_s1.mem)))
1901                 goto failed;
1902
1903         if (sc->rbrq_0.mem.size != 0 &&
1904             (error = hatm_alloc_dmamem(sc, "RBRQ0", &sc->rbrq_0.mem)))
1905                 goto failed;
1906         if (sc->rbrq_1.mem.size != 0 &&
1907             (error = hatm_alloc_dmamem(sc, "RBRQ1", &sc->rbrq_1.mem)))
1908                 goto failed;
1909
1910         if ((sc->vcc_zone = uma_zcreate("HE vccs", sizeof(struct hevcc),
1911             NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0)) == NULL) {
1912                 device_printf(dev, "cannot allocate zone for vccs\n");
1913                 goto failed;
1914         }
1915
1916         /*
1917          * 4.4 Reset the card.
1918          */
1919         if ((error = hatm_reset(sc)) != 0)
1920                 goto failed;
1921
1922         /*
1923          * Read the prom.
1924          */
1925         hatm_init_bus_width(sc);
1926         hatm_init_read_eeprom(sc);
1927         hatm_init_endianess(sc);
1928
1929         /*
1930          * Initialize interface
1931          */
1932         ifp->if_flags = IFF_SIMPLEX;
1933         ifp->if_ioctl = hatm_ioctl;
1934         ifp->if_start = hatm_start;
1935         ifp->if_init = hatm_init;
1936
1937         utopia_attach(&sc->utopia, IFP2IFATM(sc->ifp), &sc->media, &sc->mtx,
1938             &sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
1939             &hatm_utopia_methods);
1940         utopia_init_media(&sc->utopia);
1941
1942         /* these two SUNI routines need the lock */
1943         mtx_lock(&sc->mtx);
1944         /* poll while we are not running */
1945         sc->utopia.flags |= UTP_FL_POLL_CARRIER;
1946         utopia_start(&sc->utopia);
1947         utopia_reset(&sc->utopia);
1948         mtx_unlock(&sc->mtx);
1949
1950         atm_ifattach(ifp);
1951
1952 #ifdef ENABLE_BPF
1953         bpfattach(ifp, DLT_ATM_RFC1483, sizeof(struct atmllc));
1954 #endif
1955
1956         error = bus_setup_intr(dev, sc->irqres, sc->mpsafe | INTR_TYPE_NET,
1957             NULL, hatm_intr, &sc->irq_0, &sc->ih);
1958         if (error != 0) {
1959                 device_printf(dev, "could not setup interrupt\n");
1960                 hatm_detach(dev);
1961                 return (error);
1962         }
1963
1964         return (0);
1965
1966   failed:
1967         hatm_destroy(sc);
1968         return (error);
1969 }
1970
1971 /*
1972  * Start the interface. Assume a state as from attach().
1973  */
1974 void
1975 hatm_initialize(struct hatm_softc *sc)
1976 {
1977         uint32_t v;
1978         u_int cid;
1979         static const u_int layout[2][7] = HE_CONFIG_MEM_LAYOUT;
1980
1981         if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING)
1982                 return;
1983
1984         hatm_init_bus_width(sc);
1985         hatm_init_endianess(sc);
1986
1987         if_printf(sc->ifp, "%s, Rev. %s, S/N %u, "
1988             "MAC=%02x:%02x:%02x:%02x:%02x:%02x (%ubit PCI)\n",
1989             sc->prod_id, sc->rev, IFP2IFATM(sc->ifp)->mib.serial,
1990             IFP2IFATM(sc->ifp)->mib.esi[0], IFP2IFATM(sc->ifp)->mib.esi[1], IFP2IFATM(sc->ifp)->mib.esi[2],
1991             IFP2IFATM(sc->ifp)->mib.esi[3], IFP2IFATM(sc->ifp)->mib.esi[4], IFP2IFATM(sc->ifp)->mib.esi[5],
1992             sc->pci64 ? 64 : 32);
1993
1994         /*
1995          * 4.8 SDRAM Controller Initialisation
1996          * 4.9 Initialize RNUM value
1997          */
1998         if (sc->he622)
1999                 WRITE4(sc, HE_REGO_SDRAM_CNTL, HE_REGM_SDRAM_64BIT);
2000         else
2001                 WRITE4(sc, HE_REGO_SDRAM_CNTL, 0);
2002         BARRIER_W(sc);
2003
2004         v = READ4(sc, HE_REGO_LB_SWAP);
2005         BARRIER_R(sc);
2006         v |= 0xf << HE_REGS_LBSWAP_RNUM;
2007         WRITE4(sc, HE_REGO_LB_SWAP, v);
2008         BARRIER_W(sc);
2009
2010         hatm_init_irq(sc, &sc->irq_0, 0);
2011         hatm_clear_irq(sc, 1);
2012         hatm_clear_irq(sc, 2);
2013         hatm_clear_irq(sc, 3);
2014
2015         WRITE4(sc, HE_REGO_GRP_1_0_MAP, 0);
2016         WRITE4(sc, HE_REGO_GRP_3_2_MAP, 0);
2017         WRITE4(sc, HE_REGO_GRP_5_4_MAP, 0);
2018         WRITE4(sc, HE_REGO_GRP_7_6_MAP, 0);
2019         BARRIER_W(sc);
2020
2021         /*
2022          * 4.11 Enable PCI Bus Controller State Machine
2023          */
2024         v = READ4(sc, HE_REGO_HOST_CNTL);
2025         BARRIER_R(sc);
2026         v |= HE_REGM_HOST_OUTFF_ENB | HE_REGM_HOST_CMDFF_ENB |
2027             HE_REGM_HOST_QUICK_RD | HE_REGM_HOST_QUICK_WR;
2028         WRITE4(sc, HE_REGO_HOST_CNTL, v);
2029         BARRIER_W(sc);
2030
2031         /*
2032          * 5.1.1 Generic configuration state
2033          */
2034         sc->cells_per_row = layout[sc->he622][0];
2035         sc->bytes_per_row = layout[sc->he622][1];
2036         sc->r0_numrows = layout[sc->he622][2];
2037         sc->tx_numrows = layout[sc->he622][3];
2038         sc->r1_numrows = layout[sc->he622][4];
2039         sc->r0_startrow = layout[sc->he622][5];
2040         sc->tx_startrow = sc->r0_startrow + sc->r0_numrows;
2041         sc->r1_startrow = sc->tx_startrow + sc->tx_numrows;
2042         sc->cells_per_lbuf = layout[sc->he622][6];
2043
2044         sc->r0_numbuffs = sc->r0_numrows * (sc->cells_per_row /
2045             sc->cells_per_lbuf);
2046         sc->r1_numbuffs = sc->r1_numrows * (sc->cells_per_row /
2047             sc->cells_per_lbuf);
2048         sc->tx_numbuffs = sc->tx_numrows * (sc->cells_per_row /
2049             sc->cells_per_lbuf);
2050
2051         if (sc->r0_numbuffs > 2560)
2052                 sc->r0_numbuffs = 2560;
2053         if (sc->r1_numbuffs > 2560)
2054                 sc->r1_numbuffs = 2560;
2055         if (sc->tx_numbuffs > 5120)
2056                 sc->tx_numbuffs = 5120;
2057
2058         DBG(sc, ATTACH, ("cells_per_row=%u bytes_per_row=%u r0_numrows=%u "
2059             "tx_numrows=%u r1_numrows=%u r0_startrow=%u tx_startrow=%u "
2060             "r1_startrow=%u cells_per_lbuf=%u\nr0_numbuffs=%u r1_numbuffs=%u "
2061             "tx_numbuffs=%u\n", sc->cells_per_row, sc->bytes_per_row,
2062             sc->r0_numrows, sc->tx_numrows, sc->r1_numrows, sc->r0_startrow,
2063             sc->tx_startrow, sc->r1_startrow, sc->cells_per_lbuf,
2064             sc->r0_numbuffs, sc->r1_numbuffs, sc->tx_numbuffs));
2065
2066         /*
2067          * 5.1.2 Configure Hardware dependend registers
2068          */
2069         if (sc->he622) {
2070                 WRITE4(sc, HE_REGO_LBARB,
2071                     (0x2 << HE_REGS_LBARB_SLICE) |
2072                     (0xf << HE_REGS_LBARB_RNUM) |
2073                     (0x3 << HE_REGS_LBARB_THPRI) |
2074                     (0x3 << HE_REGS_LBARB_RHPRI) |
2075                     (0x2 << HE_REGS_LBARB_TLPRI) |
2076                     (0x1 << HE_REGS_LBARB_RLPRI) |
2077                     (0x28 << HE_REGS_LBARB_BUS_MULT) |
2078                     (0x50 << HE_REGS_LBARB_NET_PREF));
2079                 BARRIER_W(sc);
2080                 WRITE4(sc, HE_REGO_SDRAMCON,
2081                     /* HW bug: don't use banking */
2082                     /* HE_REGM_SDRAMCON_BANK | */
2083                     HE_REGM_SDRAMCON_WIDE |
2084                     (0x384 << HE_REGS_SDRAMCON_REF));
2085                 BARRIER_W(sc);
2086                 WRITE4(sc, HE_REGO_RCMCONFIG,
2087                     (0x1 << HE_REGS_RCMCONFIG_BANK_WAIT) |
2088                     (0x1 << HE_REGS_RCMCONFIG_RW_WAIT) |
2089                     (0x0 << HE_REGS_RCMCONFIG_TYPE));
2090                 WRITE4(sc, HE_REGO_TCMCONFIG,
2091                     (0x2 << HE_REGS_TCMCONFIG_BANK_WAIT) |
2092                     (0x1 << HE_REGS_TCMCONFIG_RW_WAIT) |
2093                     (0x0 << HE_REGS_TCMCONFIG_TYPE));
2094         } else {
2095                 WRITE4(sc, HE_REGO_LBARB,
2096                     (0x2 << HE_REGS_LBARB_SLICE) |
2097                     (0xf << HE_REGS_LBARB_RNUM) |
2098                     (0x3 << HE_REGS_LBARB_THPRI) |
2099                     (0x3 << HE_REGS_LBARB_RHPRI) |
2100                     (0x2 << HE_REGS_LBARB_TLPRI) |
2101                     (0x1 << HE_REGS_LBARB_RLPRI) |
2102                     (0x46 << HE_REGS_LBARB_BUS_MULT) |
2103                     (0x8C << HE_REGS_LBARB_NET_PREF));
2104                 BARRIER_W(sc);
2105                 WRITE4(sc, HE_REGO_SDRAMCON,
2106                     /* HW bug: don't use banking */
2107                     /* HE_REGM_SDRAMCON_BANK | */
2108                     (0x150 << HE_REGS_SDRAMCON_REF));
2109                 BARRIER_W(sc);
2110                 WRITE4(sc, HE_REGO_RCMCONFIG,
2111                     (0x0 << HE_REGS_RCMCONFIG_BANK_WAIT) |
2112                     (0x1 << HE_REGS_RCMCONFIG_RW_WAIT) |
2113                     (0x0 << HE_REGS_RCMCONFIG_TYPE));
2114                 WRITE4(sc, HE_REGO_TCMCONFIG,
2115                     (0x1 << HE_REGS_TCMCONFIG_BANK_WAIT) |
2116                     (0x1 << HE_REGS_TCMCONFIG_RW_WAIT) |
2117                     (0x0 << HE_REGS_TCMCONFIG_TYPE));
2118         }
2119         WRITE4(sc, HE_REGO_LBCONFIG, (sc->cells_per_lbuf * 48));
2120
2121         WRITE4(sc, HE_REGO_RLBC_H, 0);
2122         WRITE4(sc, HE_REGO_RLBC_T, 0);
2123         WRITE4(sc, HE_REGO_RLBC_H2, 0);
2124
2125         WRITE4(sc, HE_REGO_RXTHRSH, 512);
2126         WRITE4(sc, HE_REGO_LITHRSH, 256);
2127
2128         WRITE4(sc, HE_REGO_RLBF0_C, sc->r0_numbuffs);
2129         WRITE4(sc, HE_REGO_RLBF1_C, sc->r1_numbuffs);
2130
2131         if (sc->he622) {
2132                 WRITE4(sc, HE_REGO_RCCONFIG,
2133                     (8 << HE_REGS_RCCONFIG_UTDELAY) |
2134                     (IFP2IFATM(sc->ifp)->mib.vpi_bits << HE_REGS_RCCONFIG_VP) |
2135                     (IFP2IFATM(sc->ifp)->mib.vci_bits << HE_REGS_RCCONFIG_VC));
2136                 WRITE4(sc, HE_REGO_TXCONFIG,
2137                     (32 << HE_REGS_TXCONFIG_THRESH) |
2138                     (IFP2IFATM(sc->ifp)->mib.vci_bits << HE_REGS_TXCONFIG_VCI_MASK) |
2139                     (sc->tx_numbuffs << HE_REGS_TXCONFIG_LBFREE));
2140         } else {
2141                 WRITE4(sc, HE_REGO_RCCONFIG,
2142                     (0 << HE_REGS_RCCONFIG_UTDELAY) |
2143                     HE_REGM_RCCONFIG_UT_MODE |
2144                     (IFP2IFATM(sc->ifp)->mib.vpi_bits << HE_REGS_RCCONFIG_VP) |
2145                     (IFP2IFATM(sc->ifp)->mib.vci_bits << HE_REGS_RCCONFIG_VC));
2146                 WRITE4(sc, HE_REGO_TXCONFIG,
2147                     (32 << HE_REGS_TXCONFIG_THRESH) |
2148                     HE_REGM_TXCONFIG_UTMODE |
2149                     (IFP2IFATM(sc->ifp)->mib.vci_bits << HE_REGS_TXCONFIG_VCI_MASK) |
2150                     (sc->tx_numbuffs << HE_REGS_TXCONFIG_LBFREE));
2151         }
2152
2153         WRITE4(sc, HE_REGO_TXAAL5_PROTO, 0);
2154
2155         if (sc->rbp_s1.size != 0) {
2156                 WRITE4(sc, HE_REGO_RHCONFIG,
2157                     HE_REGM_RHCONFIG_PHYENB |
2158                     ((sc->he622 ? 0x41 : 0x31) << HE_REGS_RHCONFIG_PTMR_PRE) |
2159                     (1 << HE_REGS_RHCONFIG_OAM_GID));
2160         } else {
2161                 WRITE4(sc, HE_REGO_RHCONFIG,
2162                     HE_REGM_RHCONFIG_PHYENB |
2163                     ((sc->he622 ? 0x41 : 0x31) << HE_REGS_RHCONFIG_PTMR_PRE) |
2164                     (0 << HE_REGS_RHCONFIG_OAM_GID));
2165         }
2166         BARRIER_W(sc);
2167
2168         hatm_init_cm(sc);
2169
2170         hatm_init_rx_buffer_pool(sc, 0, sc->r0_startrow, sc->r0_numbuffs);
2171         hatm_init_rx_buffer_pool(sc, 1, sc->r1_startrow, sc->r1_numbuffs);
2172         hatm_init_tx_buffer_pool(sc, sc->tx_startrow, sc->tx_numbuffs);
2173
2174         hatm_init_imed_queues(sc);
2175
2176         /*
2177          * 5.1.6 Application tunable Parameters
2178          */
2179         WRITE4(sc, HE_REGO_MCC, 0);
2180         WRITE4(sc, HE_REGO_OEC, 0);
2181         WRITE4(sc, HE_REGO_DCC, 0);
2182         WRITE4(sc, HE_REGO_CEC, 0);
2183
2184         hatm_init_cs_block(sc);
2185         hatm_init_cs_block_cm(sc);
2186
2187         hatm_init_rpool(sc, &sc->rbp_s0, 0, 0);
2188         hatm_init_rpool(sc, &sc->rbp_l0, 0, 1);
2189         hatm_init_rpool(sc, &sc->rbp_s1, 1, 0);
2190         hatm_clear_rpool(sc, 1, 1);
2191         hatm_clear_rpool(sc, 2, 0);
2192         hatm_clear_rpool(sc, 2, 1);
2193         hatm_clear_rpool(sc, 3, 0);
2194         hatm_clear_rpool(sc, 3, 1);
2195         hatm_clear_rpool(sc, 4, 0);
2196         hatm_clear_rpool(sc, 4, 1);
2197         hatm_clear_rpool(sc, 5, 0);
2198         hatm_clear_rpool(sc, 5, 1);
2199         hatm_clear_rpool(sc, 6, 0);
2200         hatm_clear_rpool(sc, 6, 1);
2201         hatm_clear_rpool(sc, 7, 0);
2202         hatm_clear_rpool(sc, 7, 1);
2203         hatm_init_rbrq(sc, &sc->rbrq_0, 0);
2204         hatm_init_rbrq(sc, &sc->rbrq_1, 1);
2205         hatm_clear_rbrq(sc, 2);
2206         hatm_clear_rbrq(sc, 3);
2207         hatm_clear_rbrq(sc, 4);
2208         hatm_clear_rbrq(sc, 5);
2209         hatm_clear_rbrq(sc, 6);
2210         hatm_clear_rbrq(sc, 7);
2211
2212         sc->lbufs_next = 0;
2213         bzero(sc->lbufs, sizeof(sc->lbufs[0]) * sc->lbufs_size);
2214
2215         hatm_init_tbrq(sc, &sc->tbrq, 0);
2216         hatm_clear_tbrq(sc, 1);
2217         hatm_clear_tbrq(sc, 2);
2218         hatm_clear_tbrq(sc, 3);
2219         hatm_clear_tbrq(sc, 4);
2220         hatm_clear_tbrq(sc, 5);
2221         hatm_clear_tbrq(sc, 6);
2222         hatm_clear_tbrq(sc, 7);
2223
2224         hatm_init_tpdrq(sc);
2225
2226         WRITE4(sc, HE_REGO_UBUFF_BA, (sc->he622 ? 0x104780 : 0x800));
2227
2228         /*
2229          * Initialize HSP
2230          */
2231         bzero(sc->hsp_mem.base, sc->hsp_mem.size);
2232         sc->hsp = sc->hsp_mem.base;
2233         WRITE4(sc, HE_REGO_HSP_BA, sc->hsp_mem.paddr);
2234
2235         /*
2236          * 5.1.12 Enable transmit and receive
2237          * Enable bus master and interrupts
2238          */
2239         v = READ_MBOX4(sc, HE_REGO_CS_ERCTL0);
2240         v |= 0x18000000;
2241         WRITE_MBOX4(sc, HE_REGO_CS_ERCTL0, v);
2242
2243         v = READ4(sc, HE_REGO_RCCONFIG);
2244         v |= HE_REGM_RCCONFIG_RXENB;
2245         WRITE4(sc, HE_REGO_RCCONFIG, v);
2246
2247         v = pci_read_config(sc->dev, HE_PCIR_GEN_CNTL_0, 4);
2248         v |= HE_PCIM_CTL0_INIT_ENB | HE_PCIM_CTL0_INT_PROC_ENB;
2249         pci_write_config(sc->dev, HE_PCIR_GEN_CNTL_0, v, 4);
2250
2251         sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
2252         sc->ifp->if_baudrate = 53 * 8 * IFP2IFATM(sc->ifp)->mib.pcr;
2253
2254         sc->utopia.flags &= ~UTP_FL_POLL_CARRIER;
2255
2256         /* reopen vccs */
2257         for (cid = 0; cid < HE_MAX_VCCS; cid++)
2258                 if (sc->vccs[cid] != NULL)
2259                         hatm_load_vc(sc, cid, 1);
2260
2261         ATMEV_SEND_IFSTATE_CHANGED(IFP2IFATM(sc->ifp),
2262             sc->utopia.carrier == UTP_CARR_OK);
2263 }
2264
2265 /*
2266  * This functions stops the card and frees all resources allocated after
2267  * the attach. Must have the global lock.
2268  */
2269 void
2270 hatm_stop(struct hatm_softc *sc)
2271 {
2272         uint32_t v;
2273         u_int i, p, cid;
2274         struct mbuf_chunk_hdr *ch;
2275         struct mbuf_page *pg;
2276
2277         mtx_assert(&sc->mtx, MA_OWNED);
2278
2279         if (!(sc->ifp->if_drv_flags & IFF_DRV_RUNNING))
2280                 return;
2281         sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
2282
2283         ATMEV_SEND_IFSTATE_CHANGED(IFP2IFATM(sc->ifp),
2284             sc->utopia.carrier == UTP_CARR_OK);
2285
2286         sc->utopia.flags |= UTP_FL_POLL_CARRIER;
2287
2288         /*
2289          * Stop and reset the hardware so that everything remains
2290          * stable.
2291          */
2292         v = READ_MBOX4(sc, HE_REGO_CS_ERCTL0);
2293         v &= ~0x18000000;
2294         WRITE_MBOX4(sc, HE_REGO_CS_ERCTL0, v);
2295
2296         v = READ4(sc, HE_REGO_RCCONFIG);
2297         v &= ~HE_REGM_RCCONFIG_RXENB;
2298         WRITE4(sc, HE_REGO_RCCONFIG, v);
2299
2300         WRITE4(sc, HE_REGO_RHCONFIG, (0x2 << HE_REGS_RHCONFIG_PTMR_PRE));
2301         BARRIER_W(sc);
2302
2303         v = READ4(sc, HE_REGO_HOST_CNTL);
2304         BARRIER_R(sc);
2305         v &= ~(HE_REGM_HOST_OUTFF_ENB | HE_REGM_HOST_CMDFF_ENB);
2306         WRITE4(sc, HE_REGO_HOST_CNTL, v);
2307         BARRIER_W(sc);
2308
2309         /*
2310          * Disable bust master and interrupts
2311          */
2312         v = pci_read_config(sc->dev, HE_PCIR_GEN_CNTL_0, 4);
2313         v &= ~(HE_PCIM_CTL0_INIT_ENB | HE_PCIM_CTL0_INT_PROC_ENB);
2314         pci_write_config(sc->dev, HE_PCIR_GEN_CNTL_0, v, 4);
2315
2316         (void)hatm_reset(sc);
2317
2318         /*
2319          * Card resets the SUNI when resetted, so re-initialize it
2320          */
2321         utopia_reset(&sc->utopia);
2322
2323         /*
2324          * Give any waiters on closing a VCC a chance. They will stop
2325          * to wait if they see that IFF_DRV_RUNNING disappeared.
2326          */
2327         cv_broadcast(&sc->vcc_cv);
2328         cv_broadcast(&sc->cv_rcclose);
2329
2330         /*
2331          * Now free all resources.
2332          */
2333
2334         /*
2335          * Free the large mbufs that are given to the card.
2336          */
2337         for (i = 0 ; i < sc->lbufs_size; i++) {
2338                 if (sc->lbufs[i] != NULL) {
2339                         bus_dmamap_unload(sc->mbuf_tag, sc->rmaps[i]);
2340                         m_freem(sc->lbufs[i]);
2341                         sc->lbufs[i] = NULL;
2342                 }
2343         }
2344
2345         /*
2346          * Free small buffers
2347          */
2348         for (p = 0; p < sc->mbuf_npages; p++) {
2349                 pg = sc->mbuf_pages[p];
2350                 for (i = 0; i < pg->hdr.nchunks; i++) {
2351                         ch = (struct mbuf_chunk_hdr *) ((char *)pg +
2352                             i * pg->hdr.chunksize + pg->hdr.hdroff);
2353                         if (ch->flags & MBUF_CARD) {
2354                                 ch->flags &= ~MBUF_CARD;
2355                                 ch->flags |= MBUF_USED;
2356                                 hatm_ext_free(&sc->mbuf_list[pg->hdr.pool],
2357                                     (struct mbufx_free *)((u_char *)ch -
2358                                     pg->hdr.hdroff));
2359                         }
2360                 }
2361         }
2362
2363         hatm_stop_tpds(sc);
2364
2365         /*
2366          * Free all partial reassembled PDUs on any VCC.
2367          */
2368         for (cid = 0; cid < HE_MAX_VCCS; cid++) {
2369                 if (sc->vccs[cid] != NULL) {
2370                         if (sc->vccs[cid]->chain != NULL) {
2371                                 m_freem(sc->vccs[cid]->chain);
2372                                 sc->vccs[cid]->chain = NULL;
2373                                 sc->vccs[cid]->last = NULL;
2374                         }
2375                         if (!(sc->vccs[cid]->vflags & (HE_VCC_RX_OPEN |
2376                             HE_VCC_TX_OPEN))) {
2377                                 hatm_tx_vcc_closed(sc, cid);
2378                                 uma_zfree(sc->vcc_zone, sc->vccs[cid]);
2379                                 sc->vccs[cid] = NULL;
2380                                 sc->open_vccs--;
2381                         } else {
2382                                 sc->vccs[cid]->vflags = 0;
2383                                 sc->vccs[cid]->ntpds = 0;
2384                         }
2385                 }
2386         }
2387
2388         if (sc->rbp_s0.size != 0)
2389                 bzero(sc->rbp_s0.mem.base, sc->rbp_s0.mem.size);
2390         if (sc->rbp_l0.size != 0)
2391                 bzero(sc->rbp_l0.mem.base, sc->rbp_l0.mem.size);
2392         if (sc->rbp_s1.size != 0)
2393                 bzero(sc->rbp_s1.mem.base, sc->rbp_s1.mem.size);
2394         if (sc->rbrq_0.size != 0)
2395                 bzero(sc->rbrq_0.mem.base, sc->rbrq_0.mem.size);
2396         if (sc->rbrq_1.size != 0)
2397                 bzero(sc->rbrq_1.mem.base, sc->rbrq_1.mem.size);
2398
2399         bzero(sc->tbrq.mem.base, sc->tbrq.mem.size);
2400         bzero(sc->tpdrq.mem.base, sc->tpdrq.mem.size);
2401         bzero(sc->hsp_mem.base, sc->hsp_mem.size);
2402 }
2403
2404 /************************************************************
2405  *
2406  * Driver infrastructure
2407  */
2408 devclass_t hatm_devclass;
2409
2410 static device_method_t hatm_methods[] = {
2411         DEVMETHOD(device_probe,         hatm_probe),
2412         DEVMETHOD(device_attach,        hatm_attach),
2413         DEVMETHOD(device_detach,        hatm_detach),
2414         {0,0}
2415 };
2416 static driver_t hatm_driver = {
2417         "hatm",
2418         hatm_methods,
2419         sizeof(struct hatm_softc),
2420 };
2421 DRIVER_MODULE(hatm, pci, hatm_driver, hatm_devclass, NULL, 0);