Deleted Added
sdiff udiff text old ( 121687 ) new ( 122112 )
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:

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

27 * Author: Hartmut Brandt <harti@freebsd.org>
28 *
29 * ForeHE driver.
30 *
31 * Transmission.
32 */
33
34#include <sys/cdefs.h>
35__FBSDID("$FreeBSD: head/sys/dev/hatm/if_hatm_tx.c 122112 2003-11-05 11:43:06Z harti $");
36
37#include "opt_inet.h"
38#include "opt_natm.h"
39
40#include <sys/types.h>
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/kernel.h>

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

73#include <dev/pci/pcireg.h>
74#include <dev/pci/pcivar.h>
75
76#include <dev/utopia/utopia.h>
77#include <dev/hatm/if_hatmconf.h>
78#include <dev/hatm/if_hatmreg.h>
79#include <dev/hatm/if_hatmvar.h>
80
81
82/*
83 * These macros are used to trace the flow of transmit mbufs and to
84 * detect transmit mbuf leaks in the driver.
85 */
86#ifdef HATM_DEBUG
87#define hatm_free_txmbuf(SC) \
88 do { \
89 if (--sc->txmbuf < 0) \
90 DBG(sc, TX, ("txmbuf below 0!")); \
91 else if (sc->txmbuf == 0) \
92 DBG(sc, TX, ("txmbuf now 0")); \
93 } while (0)
94#define hatm_get_txmbuf(SC) \
95 do { \
96 if (++sc->txmbuf > 20000) \
97 DBG(sc, TX ("txmbuf %u", sc->txmbuf)); \
98 else if (sc->txmbuf == 1) \
99 DBG(sc, TX, ("txmbuf leaves 0")); \
100 } while (0)
101#else
102#define hatm_free_txmbuf(SC) do { } while (0)
103#define hatm_get_txmbuf(SC) do { } while (0)
104#endif
105
106/*
107 * Allocate a new TPD, zero the TPD part. Cannot return NULL if
108 * flag is 0. The TPD is removed from the free list and its used
109 * bit is set.
110 */
111static struct tpd *
112hatm_alloc_tpd(struct hatm_softc *sc, u_int flags)
113{
114 struct tpd *t;

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

144 * and the mbuf is freed. The TPD is put back onto the free list and
145 * its used bit is cleared.
146 */
147static void
148hatm_free_tpd(struct hatm_softc *sc, struct tpd *tpd)
149{
150 if (tpd->mbuf != NULL) {
151 bus_dmamap_unload(sc->tx_tag, tpd->map);
152 hatm_free_txmbuf(sc);
153 m_freem(tpd->mbuf);
154 tpd->mbuf = NULL;
155 }
156
157 /* insert TPD into free list */
158 SLIST_INSERT_HEAD(&sc->tpd_free, tpd, link);
159 TPD_CLR_USED(sc, tpd->no);
160 sc->tpd_nfree++;

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

365 mtx_lock(&sc->mtx);
366 arg.sc = sc;
367
368 while (1) {
369 IF_DEQUEUE(&ifp->if_snd, m);
370 if (m == NULL)
371 break;
372
373 hatm_get_txmbuf(sc);
374
375 if (m->m_len < sizeof(*aph))
376 if ((m = m_pullup(m, sizeof(*aph))) == NULL) {
377 hatm_free_txmbuf(sc);
378 continue;
379 }
380
381 aph = mtod(m, struct atm_pseudohdr *);
382 arg.vci = ATM_PH_VCI(aph);
383 arg.vpi = ATM_PH_VPI(aph);
384 m_adj(m, sizeof(*aph));
385
386 if ((len = m->m_pkthdr.len) == 0) {
387 hatm_free_txmbuf(sc);
388 m_freem(m);
389 continue;
390 }
391
392 if ((arg.vpi & ~HE_VPI_MASK) || (arg.vci & ~HE_VCI_MASK) ||
393 (arg.vci == 0)) {
394 hatm_free_txmbuf(sc);
395 m_freem(m);
396 continue;
397 }
398 cid = HE_CID(arg.vpi, arg.vci);
399 arg.vcc = sc->vccs[cid];
400
401 if (arg.vcc == NULL || !(arg.vcc->vflags & HE_VCC_OPEN)) {
402 hatm_free_txmbuf(sc);
403 m_freem(m);
404 continue;
405 }
406 if (arg.vcc->vflags & HE_VCC_FLOW_CTRL) {
407 hatm_free_txmbuf(sc);
408 m_freem(m);
409 sc->istats.flow_drop++;
410 continue;
411 }
412
413 arg.pti = 0;
414 if (arg.vcc->param.aal == ATMIO_AAL_RAW) {
415 if (len < 52) {
416 /* too short */
417 hatm_free_txmbuf(sc);
418 m_freem(m);
419 continue;
420 }
421
422 /*
423 * Get the header and ignore except
424 * payload type and CLP.
425 */
426 if (m->m_len < 4 && (m = m_pullup(m, 4)) == NULL) {
427 hatm_free_txmbuf(sc);
428 continue;
429 }
430 arg.pti = mtod(m, u_char *)[3] & 0xf;
431 arg.pti = ((arg.pti & 0xe) << 2) | ((arg.pti & 1) << 1);
432 m_adj(m, 4);
433 len -= 4;
434
435 if (len % 48 != 0) {
436 m_adj(m, -((int)(len % 48)));
437 len -= len % 48;

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

444 (arg.vcc->param.flags & ATM_PH_LLCSNAP))
445 BPF_MTAP(ifp, m);
446#endif
447
448 /* Now load a DMA map with the packet. Allocate the first
449 * TPD to get a map. Additional TPDs may be allocated by the
450 * callback. */
451 if ((tpd = hatm_alloc_tpd(sc, M_NOWAIT)) == NULL) {
452 hatm_free_txmbuf(sc);
453 m_freem(m);
454 sc->ifatm.ifnet.if_oerrors++;
455 continue;
456 }
457 tpd->cid = cid;
458 tpd->tpd.addr |= arg.pti;
459 arg.first = tpd;
460 arg.error = 0;
461 arg.mbuf = m;
462
463 error = bus_dmamap_load_mbuf(sc->tx_tag, tpd->map, m,
464 hatm_load_txbuf, &arg, BUS_DMA_NOWAIT);
465
466 if (error == EFBIG) {
467 /* try to defragment the packet */
468 sc->istats.defrag++;
469 m = m_defrag(m, M_DONTWAIT);
470 if (m == NULL) {
471 tpd->mbuf = NULL;
472 hatm_free_txmbuf(sc);
473 hatm_free_tpd(sc, tpd);
474 sc->ifatm.ifnet.if_oerrors++;
475 continue;
476 }
477 arg.mbuf = m;
478 error = bus_dmamap_load_mbuf(sc->tx_tag, tpd->map, m,
479 hatm_load_txbuf, &arg, BUS_DMA_NOWAIT);
480 }
481

--- 345 unchanged lines hidden ---