Deleted Added
sdiff udiff text old ( 118168 ) new ( 118208 )
full compact
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:

--- 15 unchanged lines hidden (view full) ---

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 * Fore PCA200E driver for NATM
30 */
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: head/sys/dev/fatm/if_fatm.c 118208 2003-07-30 14:20:00Z harti $");
33
34#include "opt_inet.h"
35#include "opt_natm.h"
36
37#include <sys/types.h>
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/malloc.h>
41#include <sys/kernel.h>
42#include <sys/bus.h>
43#include <sys/errno.h>
44#include <sys/conf.h>
45#include <sys/module.h>
46#include <sys/queue.h>
47#include <sys/syslog.h>
48#include <sys/endian.h>
49#include <sys/sysctl.h>
50#include <sys/condvar.h>
51#include <vm/uma.h>
52
53#include <sys/sockio.h>
54#include <sys/mbuf.h>
55#include <sys/socket.h>
56
57#include <net/if.h>
58#include <net/if_media.h>
59#include <net/if_atm.h>

--- 456 unchanged lines hidden (view full) ---

516 wakeup(q);
517 }
518 }
519 utopia_reset_media(&sc->utopia);
520 }
521 sc->small_cnt = sc->large_cnt = 0;
522
523 /* Reset vcc info */
524 if (sc->vccs != NULL) {
525 for (i = 0; i < FORE_MAX_VCC + 1; i++)
526 if (sc->vccs[i] != NULL) {
527 uma_zfree(sc->vcc_zone, sc->vccs[i]);
528 sc->vccs[i] = NULL;
529 }
530 }
531
532 sc->open_vccs = 0;
533}
534
535/*
536 * Load the firmware into the board and save the entry point.
537 */
538static uint32_t

--- 907 unchanged lines hidden (view full) ---

1446 * Check the receive queue. Send any received PDU up the protocol stack
1447 * (except when there was an error or the VCI appears to be closed. In this
1448 * case discard the PDU).
1449 */
1450static void
1451fatm_intr_drain_rx(struct fatm_softc *sc)
1452{
1453 struct rxqueue *q;
1454 int stat, mlen;
1455 u_int i;
1456 uint32_t h;
1457 struct mbuf *last, *m0;
1458 struct rpd *rpd;
1459 struct rbuf *rb;
1460 u_int vci, vpi, pt;
1461 struct atm_pseudohdr aph;
1462 struct ifnet *ifp;
1463 struct card_vcc *vc;
1464
1465 for (;;) {
1466 q = GET_QUEUE(sc->rxqueue, struct rxqueue, sc->rxqueue.tail);
1467
1468 H_SYNCSTAT_POSTREAD(sc, q->q.statp);
1469 stat = H_GETSTAT(q->q.statp);
1470
1471 if ((stat & FATM_STAT_COMPLETE) == 0)
1472 break;
1473
1474 rpd = (struct rpd *)q->q.ioblk;
1475 H_SYNCQ_POSTREAD(&sc->rxq_mem, rpd, RPD_SIZE);
1476
1477 rpd->nseg = le32toh(rpd->nseg);
1478 mlen = 0;
1479 m0 = last = 0;
1480 for (i = 0; i < rpd->nseg; i++) {
1481 rb = sc->rbufs + rpd->segment[i].handle;
1482 if (m0 == NULL) {
1483 m0 = last = rb->m;
1484 } else {
1485 last->m_next = rb->m;

--- 23 unchanged lines hidden (view full) ---

1509 vpi = (h >> 20) & 0xff;
1510 vci = (h >> 4 ) & 0xffff;
1511 pt = (h >> 1 ) & 0x7;
1512
1513 /*
1514 * Locate the VCC this packet belongs to
1515 */
1516 if (!VC_OK(sc, vpi, vci))
1517 vc = NULL;
1518 else if ((vc = sc->vccs[vci]) == NULL ||
1519 !(sc->vccs[vci]->vflags & FATM_VCC_OPEN)) {
1520 sc->istats.rx_closed++;
1521 vc = NULL;
1522 }
1523
1524 DBG(sc, RCV, ("RCV: vc=%u.%u pt=%u mlen=%d %s", vpi, vci,
1525 pt, mlen, vc == NULL ? "dropped" : ""));
1526
1527 if (vc == NULL) {
1528 m_freem(m0);
1529 } else {
1530 ATM_PH_FLAGS(&aph) = vc->param.flags;
1531 ATM_PH_VPI(&aph) = vpi;
1532 ATM_PH_SETVCI(&aph, vci);
1533
1534 ifp = &sc->ifatm.ifnet;
1535 ifp->if_ipackets++;
1536
1537 vc->ipackets++;
1538 vc->ibytes += m0->m_pkthdr.len;
1539
1540 atm_input(ifp, &aph, m0, vc->rxhand);
1541 }
1542
1543 H_SETSTAT(q->q.statp, FATM_STAT_FREE);
1544 H_SYNCSTAT_PREWRITE(sc, q->q.statp);
1545
1546 WRITE4(sc, q->q.card, q->q.card_ioblk);
1547 BARRIER_W(sc);
1548

--- 350 unchanged lines hidden (view full) ---

1899}
1900
1901/*
1902 * Start output.
1903 *
1904 * Note, that we update the internal statistics without the lock here.
1905 */
1906static int
1907fatm_tx(struct fatm_softc *sc, struct mbuf *m, struct card_vcc *vc, u_int mlen)
1908{
1909 struct txqueue *q;
1910 u_int nblks;
1911 int error, aal, nsegs;
1912 struct tpd *tpd;
1913
1914 /*
1915 * Get a queue element.

--- 36 unchanged lines hidden (view full) ---

1952 }
1953 nsegs = tpd->spec;
1954
1955 bus_dmamap_sync(sc->tx_tag, q->map, BUS_DMASYNC_PREWRITE);
1956
1957 /*
1958 * OK. Now go and do it.
1959 */
1960 aal = (vc->param.aal == ATMIO_AAL_5) ? 5 : 0;
1961
1962 H_SETSTAT(q->q.statp, FATM_STAT_PENDING);
1963 H_SYNCSTAT_PREWRITE(sc, q->q.statp);
1964 q->m = m;
1965
1966 /*
1967 * If the transmit queue is almost full, schedule a
1968 * transmit interrupt so that transmit descriptors can
1969 * be recycled.
1970 */
1971 H_SETDESC(tpd->spec, TDX_MKSPEC((sc->txcnt >=
1972 (4 * FATM_TX_QLEN) / 5), aal, nsegs, mlen));
1973 H_SETDESC(tpd->atm_header, TDX_MKHDR(vc->param.vpi,
1974 vc->param.vci, 0, 0));
1975
1976 if (vc->param.traffic == ATMIO_TRAFFIC_UBR)
1977 H_SETDESC(tpd->stream, 0);
1978 else {
1979 u_int i;
1980
1981 for (i = 0; i < RATE_TABLE_SIZE; i++)
1982 if (rate_table[i].cell_rate < vc->param.tparam.pcr)
1983 break;
1984 if (i > 0)
1985 i--;
1986 H_SETDESC(tpd->stream, rate_table[i].ratio);
1987 }
1988 H_SYNCQ_PREWRITE(&sc->txq_mem, tpd, TPD_SIZE);
1989
1990 nblks = TDX_SEGS2BLKS(nsegs);
1991
1992 DBG(sc, XMIT, ("XMIT: mlen=%d spec=0x%x nsegs=%d blocks=%d",
1993 mlen, le32toh(tpd->spec), nsegs, nblks));
1994
1995 WRITE4(sc, q->q.card + 0, q->q.card_ioblk | nblks);
1996 BARRIER_W(sc);
1997
1998 sc->txcnt++;
1999 sc->ifatm.ifnet.if_opackets++;
2000 vc->obytes += m->m_pkthdr.len;
2001 vc->opackets++;
2002
2003 NEXT_QUEUE_ENTRY(sc->txqueue.head, FATM_TX_QLEN);
2004
2005 return (0);
2006}
2007
2008static void
2009fatm_start(struct ifnet *ifp)
2010{
2011 struct atm_pseudohdr aph;
2012 struct fatm_softc *sc;
2013 struct mbuf *m;
2014 u_int mlen, vpi, vci;
2015 struct card_vcc *vc;
2016
2017 sc = (struct fatm_softc *)ifp->if_softc;
2018
2019 while (1) {
2020 IF_DEQUEUE(&ifp->if_snd, m);
2021 if (m == NULL)
2022 break;
2023

--- 32 unchanged lines hidden (view full) ---

2056 * From here on we need the softc
2057 */
2058 FATM_LOCK(sc);
2059 if (!(ifp->if_flags & IFF_RUNNING)) {
2060 FATM_UNLOCK(sc);
2061 m_freem(m);
2062 break;
2063 }
2064 if (!VC_OK(sc, vpi, vci) || (vc = sc->vccs[vci]) == NULL ||
2065 !(vc->vflags & FATM_VCC_OPEN)) {
2066 FATM_UNLOCK(sc);
2067 m_freem(m);
2068 continue;
2069 }
2070 if (fatm_tx(sc, m, vc, mlen)) {
2071 FATM_UNLOCK(sc);
2072 break;
2073 }
2074 FATM_UNLOCK(sc);
2075 }
2076}
2077
2078/*
2079 * VCC managment
2080 *
2081 * This may seem complicated. The reason for this is, that we need an
2082 * asynchronuous open/close for the NATM VCCs because our ioctl handler
2083 * is called with the radix node head of the routing table locked. Therefor
2084 * we cannot sleep there and wait for the open/close to succeed. For this
2085 * reason we just initiate the operation from the ioctl.
2086 */

--- 28 unchanged lines hidden (view full) ---

2115 BARRIER_W(sc);
2116 WRITE4(sc, q->q.card + FATMOC_OP, cmd);
2117 BARRIER_W(sc);
2118
2119 return (q);
2120}
2121
2122/*
2123 * The VC has been opened/closed and somebody has been waiting for this.
2124 * Wake him up.
2125 */
2126static void
2127fatm_cmd_complete(struct fatm_softc *sc, struct cmdqueue *q)
2128{
2129
2130 H_SYNCSTAT_POSTREAD(sc, q->q.statp);
2131 if (H_GETSTAT(q->q.statp) & FATM_STAT_ERROR) {
2132 sc->istats.get_stat_errors++;
2133 q->error = EIO;
2134 }
2135 wakeup(q);
2136}
2137
2138/*
2139 * Open complete
2140 */
2141static void
2142fatm_open_finish(struct fatm_softc *sc, struct card_vcc *vc)
2143{
2144 vc->vflags &= ~FATM_VCC_TRY_OPEN;
2145 vc->vflags |= FATM_VCC_OPEN;
2146
2147 /* inform management if this is not an NG
2148 * VCC or it's an NG PVC. */
2149 if (!(vc->param.flags & ATMIO_FLAG_NG) ||
2150 (vc->param.flags & ATMIO_FLAG_PVC))
2151 ATMEV_SEND_VCC_CHANGED(&sc->ifatm, 0, vc->param.vci, 1);
2152}
2153
2154/*
2155 * The VC that we have tried to open asynchronuosly has been opened.
2156 */
2157static void
2158fatm_open_complete(struct fatm_softc *sc, struct cmdqueue *q)
2159{
2160 u_int vci;
2161 struct card_vcc *vc;
2162
2163 vci = GETVCI(READ4(sc, q->q.card + FATMOC_ACTIN_VPVC));
2164 vc = sc->vccs[vci];
2165 H_SYNCSTAT_POSTREAD(sc, q->q.statp);
2166 if (H_GETSTAT(q->q.statp) & FATM_STAT_ERROR) {
2167 sc->istats.get_stat_errors++;
2168 sc->vccs[vci] = NULL;
2169 uma_zfree(sc->vcc_zone, vc);
2170 if_printf(&sc->ifatm.ifnet, "opening VCI %u failed\n", vci);
2171 return;
2172 }
2173 fatm_open_finish(sc, vc);
2174}
2175
2176/*
2177 * Wait on the queue entry until the VCC is opened/closed.
2178 */
2179static int
2180fatm_waitvcc(struct fatm_softc *sc, struct cmdqueue *q)
2181{

--- 5 unchanged lines hidden (view full) ---

2187 error = msleep(q, &sc->mtx, PZERO | PCATCH, "fatm_vci", hz);
2188
2189 if (error != 0)
2190 return (error);
2191 return (q->error);
2192}
2193
2194/*
2195 * Start to open a VCC. This just initiates the operation.
2196 */
2197static int
2198fatm_open_vcc(struct fatm_softc *sc, struct atmio_openvcc *op, int wait)
2199{
2200 uint32_t cmd;
2201 int error;
2202 struct cmdqueue *q;
2203 struct card_vcc *vc;
2204
2205 /*
2206 * Check parameters
2207 */
2208 if ((op->param.flags & ATMIO_FLAG_NOTX) &&
2209 (op->param.flags & ATMIO_FLAG_NORX))
2210 return (EINVAL);
2211
2212 if (!VC_OK(sc, op->param.vpi, op->param.vci))
2213 return (EINVAL);
2214 if (op->param.aal != ATMIO_AAL_0 && op->param.aal != ATMIO_AAL_5)
2215 return (EINVAL);
2216
2217 vc = uma_zalloc(sc->vcc_zone, M_NOWAIT | M_ZERO);
2218 if (vc == NULL)
2219 return (ENOMEM);
2220
2221 error = 0;
2222
2223 FATM_LOCK(sc);
2224 if (!(sc->ifatm.ifnet.if_flags & IFF_RUNNING)) {
2225 error = EIO;
2226 goto done;
2227 }
2228 if (sc->vccs[op->param.vci] != NULL) {
2229 error = EBUSY;
2230 goto done;
2231 }
2232 vc->param = op->param;
2233 vc->rxhand = op->rxhand;
2234
2235 switch (op->param.traffic) {
2236
2237 case ATMIO_TRAFFIC_UBR:
2238 break;
2239
2240 case ATMIO_TRAFFIC_CBR:
2241 if (op->param.tparam.pcr == 0 ||
2242 op->param.tparam.pcr > sc->ifatm.mib.pcr) {
2243 error = EINVAL;
2244 goto done;
2245 }
2246 break;
2247
2248 default:
2249 error = EINVAL;
2250 goto done;
2251 return (EINVAL);
2252 }
2253 vc->ibytes = vc->obytes = 0;
2254 vc->ipackets = vc->opackets = 0;
2255
2256 /* Command and buffer strategy */
2257 cmd = FATM_OP_ACTIVATE_VCIN | FATM_OP_INTERRUPT_SEL | (0 << 16);
2258 if (op->param.aal == ATMIO_AAL_0)
2259 cmd |= (0 << 8);
2260 else
2261 cmd |= (5 << 8);
2262
2263 q = fatm_start_vcc(sc, op->param.vpi, op->param.vci, cmd, 1,
2264 wait ? fatm_cmd_complete : fatm_open_complete);
2265 if (q == NULL) {
2266 error = EIO;
2267 goto done;
2268 }
2269
2270 vc->vflags = FATM_VCC_TRY_OPEN;
2271 sc->vccs[op->param.vci] = vc;
2272 sc->open_vccs++;
2273
2274 if (wait) {
2275 error = fatm_waitvcc(sc, q);
2276 if (error != 0) {
2277 sc->vccs[op->param.vci] = NULL;
2278 sc->open_vccs--;
2279 goto done;
2280 }
2281 fatm_open_finish(sc, vc);
2282 }
2283
2284 /* don't free below */
2285 vc = NULL;
2286
2287 done:
2288 FATM_UNLOCK(sc);
2289 if (vc != NULL)
2290 uma_zfree(sc->vcc_zone, vc);
2291 return (error);
2292}
2293
2294/*
2295 * Finish close
2296 */
2297static void
2298fatm_close_finish(struct fatm_softc *sc, struct card_vcc *vc)
2299{
2300 /* inform management of this is not an NG
2301 * VCC or it's an NG PVC. */
2302 if (!(vc->param.flags & ATMIO_FLAG_NG) ||
2303 (vc->param.flags & ATMIO_FLAG_PVC))
2304 ATMEV_SEND_VCC_CHANGED(&sc->ifatm, 0, vc->param.vci, 0);
2305
2306 sc->vccs[vc->param.vci] = NULL;
2307 sc->open_vccs--;
2308
2309 uma_zfree(sc->vcc_zone, vc);
2310}
2311
2312/*
2313 * The VC has been closed.
2314 */
2315static void
2316fatm_close_complete(struct fatm_softc *sc, struct cmdqueue *q)
2317{
2318 u_int vci;
2319 struct card_vcc *vc;
2320
2321 vci = GETVCI(READ4(sc, q->q.card + FATMOC_ACTIN_VPVC));
2322 vc = sc->vccs[vci];
2323 H_SYNCSTAT_POSTREAD(sc, q->q.statp);
2324 if (H_GETSTAT(q->q.statp) & FATM_STAT_ERROR) {
2325 sc->istats.get_stat_errors++;
2326 /* keep the VCC in that state */
2327 if_printf(&sc->ifatm.ifnet, "closing VCI %u failed\n", vci);
2328 return;
2329 }
2330
2331 fatm_close_finish(sc, vc);
2332}
2333
2334/*
2335 * Initiate closing a VCC
2336 */
2337static int
2338fatm_close_vcc(struct fatm_softc *sc, struct atmio_closevcc *cl, int wait)
2339{
2340 int error;
2341 struct cmdqueue *q;
2342 struct card_vcc *vc;
2343
2344 if (!VC_OK(sc, cl->vpi, cl->vci))
2345 return (EINVAL);
2346
2347 error = 0;
2348
2349 FATM_LOCK(sc);
2350 if (!(sc->ifatm.ifnet.if_flags & IFF_RUNNING)) {
2351 error = EIO;
2352 goto done;
2353 }
2354 vc = sc->vccs[cl->vci];
2355 if (vc == NULL || !(vc->vflags & (FATM_VCC_OPEN | FATM_VCC_TRY_OPEN))) {
2356 error = ENOENT;
2357 goto done;
2358 }
2359
2360 q = fatm_start_vcc(sc, cl->vpi, cl->vci,
2361 FATM_OP_DEACTIVATE_VCIN | FATM_OP_INTERRUPT_SEL, 1,
2362 wait ? fatm_cmd_complete : fatm_close_complete);
2363 if (q == NULL) {
2364 error = EIO;
2365 goto done;
2366 }
2367
2368 vc->vflags &= ~(FATM_VCC_OPEN | FATM_VCC_TRY_OPEN);
2369 vc->vflags |= FATM_VCC_TRY_CLOSE;
2370
2371 if (wait) {
2372 error = fatm_waitvcc(sc, q);
2373 if (error != 0)
2374 goto done;
2375
2376 fatm_close_finish(sc, vc);
2377 }
2378
2379 done:
2380 FATM_UNLOCK(sc);
2381 return (error);
2382}
2383
2384/*
2385 * IOCTL handler
2386 */
2387static int
2388fatm_ioctl(struct ifnet *ifp, u_long cmd, caddr_t arg)
2389{
2390 int error;
2391 struct fatm_softc *sc = ifp->if_softc;
2392 struct ifaddr *ifa = (struct ifaddr *)arg;
2393 struct ifreq *ifr = (struct ifreq *)arg;
2394 struct atmio_closevcc *cl = (struct atmio_closevcc *)arg;
2395 struct atmio_openvcc *op = (struct atmio_openvcc *)arg;
2396 struct atm_pseudoioctl *pa = (struct atm_pseudoioctl *)arg;
2397 struct atmio_vcctable *vtab;
2398 struct atmio_openvcc ena;
2399 struct atmio_closevcc dis;
2400
2401 error = 0;
2402 switch (cmd) {
2403
2404 case SIOCATMENA: /* internal NATM use */
2405 bzero(&ena, sizeof(ena));
2406 ena.param.flags = ATM_PH_FLAGS(&pa->aph) &
2407 (ATM_PH_AAL5 | ATM_PH_LLCSNAP);
2408 ena.param.vpi = ATM_PH_VPI(&pa->aph);
2409 ena.param.vci = ATM_PH_VCI(&pa->aph);
2410 ena.param.aal = (ATM_PH_FLAGS(&pa->aph) & ATM_PH_AAL5) ?
2411 ATMIO_AAL_5 : ATMIO_AAL_0;
2412 ena.param.traffic = ATMIO_TRAFFIC_UBR;
2413 ena.rxhand = pa->rxhand;
2414 error = fatm_open_vcc(sc, &ena, 0);
2415 break;
2416
2417 case SIOCATMDIS: /* internal NATM use */
2418 bzero(&dis, sizeof(dis));
2419 dis.vpi = ATM_PH_VPI(&pa->aph);
2420 dis.vci = ATM_PH_VCI(&pa->aph);
2421 error = fatm_close_vcc(sc, &dis, 0);
2422 break;
2423
2424 case SIOCATMOPENVCC:
2425 error = fatm_open_vcc(sc, op, 1);
2426 break;
2427
2428 case SIOCATMCLOSEVCC:
2429 error = fatm_close_vcc(sc, cl, 1);
2430 break;
2431
2432 case SIOCSIFADDR:
2433 FATM_LOCK(sc);
2434 ifp->if_flags |= IFF_UP;
2435 if (!(ifp->if_flags & IFF_RUNNING))
2436 fatm_init_locked(sc);
2437 switch (ifa->ifa_addr->sa_family) {

--- 28 unchanged lines hidden (view full) ---

2466 if (ifp->if_flags & IFF_RUNNING)
2467 error = ifmedia_ioctl(ifp, ifr, &sc->media, cmd);
2468 else
2469 error = EINVAL;
2470 break;
2471
2472 case SIOCATMGVCCS:
2473 /* return vcc table */
2474 vtab = atm_getvccs((struct atmio_vcc **)sc->vccs,
2475 FORE_MAX_VCC + 1, sc->open_vccs, &sc->mtx, 1);
2476 error = copyout(vtab, ifr->ifr_data, sizeof(*vtab) +
2477 vtab->count * sizeof(vtab->vccs[0]));
2478 free(vtab, M_DEVBUF);
2479 break;
2480
2481 case SIOCATMGETVCCS: /* internal netgraph use */
2482 vtab = atm_getvccs((struct atmio_vcc **)sc->vccs,
2483 FORE_MAX_VCC + 1, sc->open_vccs, &sc->mtx, 0);
2484 if (vtab == NULL) {
2485 error = ENOMEM;
2486 break;
2487 }
2488 *(void **)arg = vtab;
2489 break;
2490
2491 default:

--- 45 unchanged lines hidden (view full) ---

2537 }
2538 }
2539
2540 while ((rb = LIST_FIRST(&sc->rbuf_free)) != NULL) {
2541 bus_dmamap_destroy(sc->rbuf_tag, rb->map);
2542 LIST_REMOVE(rb, link);
2543 }
2544
2545 if (sc->rbufs != NULL)
2546 free(sc->rbufs, M_DEVBUF);
2547 if (sc->vccs != NULL)
2548 free(sc->vccs, M_DEVBUF);
2549 if (sc->vcc_zone != NULL)
2550 uma_zdestroy(sc->vcc_zone);
2551
2552 if (sc->l1queue.chunk != NULL)
2553 free(sc->l1queue.chunk, M_DEVBUF);
2554 if (sc->s1queue.chunk != NULL)
2555 free(sc->s1queue.chunk, M_DEVBUF);
2556 if (sc->rxqueue.chunk != NULL)
2557 free(sc->rxqueue.chunk, M_DEVBUF);
2558 if (sc->txqueue.chunk != NULL)
2559 free(sc->txqueue.chunk, M_DEVBUF);
2560 if (sc->cmdqueue.chunk != NULL)
2561 free(sc->cmdqueue.chunk, M_DEVBUF);
2562
2563 destroy_dma_memory(&sc->reg_mem);
2564 destroy_dma_memory(&sc->sadi_mem);
2565 destroy_dma_memory(&sc->prom_mem);
2566#ifdef TEST_DMA_SYNC
2567 destroy_dma_memoryX(&sc->s1q_mem);
2568 destroy_dma_memoryX(&sc->l1q_mem);
2569 destroy_dma_memoryX(&sc->rxq_mem);

--- 371 unchanged lines hidden (view full) ---

2941 M_DEVBUF, M_ZERO | M_WAITOK);
2942 sc->rxqueue.chunk = malloc(FATM_RX_QLEN * sizeof(struct rxqueue),
2943 M_DEVBUF, M_ZERO | M_WAITOK);
2944 sc->s1queue.chunk = malloc(SMALL_SUPPLY_QLEN * sizeof(struct supqueue),
2945 M_DEVBUF, M_ZERO | M_WAITOK);
2946 sc->l1queue.chunk = malloc(LARGE_SUPPLY_QLEN * sizeof(struct supqueue),
2947 M_DEVBUF, M_ZERO | M_WAITOK);
2948
2949 sc->vccs = malloc((FORE_MAX_VCC + 1) * sizeof(sc->vccs[0]),
2950 M_DEVBUF, M_ZERO | M_WAITOK);
2951 sc->vcc_zone = uma_zcreate("FATM vccs", sizeof(struct card_vcc),
2952 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
2953 if (sc->vcc_zone == NULL) {
2954 error = ENOMEM;
2955 goto fail;
2956 }
2957
2958 /*
2959 * Allocate memory for the receive buffer headers. The total number
2960 * of headers should probably also include the maximum number of
2961 * buffers on the receive queue.
2962 */
2963 sc->rbuf_total = SMALL_POOL_SIZE + LARGE_POOL_SIZE;
2964 sc->rbufs = malloc(sc->rbuf_total * sizeof(struct rbuf),

--- 94 unchanged lines hidden ---