1 /* $NetBSD: pdq_ifsubr.c,v 1.52 2008/04/08 12:07:27 cegger Exp $ */
4 * Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 * Id: pdq_ifsubr.c,v 1.12 1997/06/05 01:56:35 thomas Exp
31 * DEC PDQ FDDI Controller; code for BSD derived operating systems
33 * This module provide bus independent BSD specific O/S functions.
34 * (ie. it provides an ifnet interface to the rest of the system)
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: pdq_ifsubr.c,v 1.52 2008/04/08 12:07:27 cegger Exp $");
44 #include <sys/param.h>
45 #include <sys/kernel.h>
47 #include <sys/protosw.h>
48 #include <sys/socket.h>
49 #include <sys/ioctl.h>
50 #include <sys/errno.h>
51 #include <sys/malloc.h>
52 #if defined(__FreeBSD__) && BSD < 199401
53 #include <sys/devconf.h>
54 #elif defined(__bsdi__) || defined(__NetBSD__)
55 #include <sys/device.h>
59 #include <net/if_types.h>
60 #include <net/if_dl.h>
61 #if !defined(__NetBSD__)
62 #include <net/route.h>
68 #include <net/bpfdesc.h>
72 #include <netinet/in.h>
73 #include <netinet/in_systm.h>
74 #include <netinet/in_var.h>
75 #include <netinet/ip.h>
76 #if defined(__NetBSD__)
77 #include <netinet/if_inarp.h>
80 #if defined(__FreeBSD__)
81 #include <netinet/if_ether.h>
82 #include <netinet/if_fddi.h>
84 #include <net/if_fddi.h>
88 #include <netinet/if_ether.h>
89 #include <i386/isa/isavar.h>
97 #if defined(__FreeBSD__)
99 * Yet another specific ifdef for FreeBSD as it diverges...
101 #include <dev/pdq/pdqvar.h>
102 #include <dev/pdq/pdqreg.h>
112 if (sc
->sc_if
.if_flags
& IFF_UP
) {
113 sc
->sc_if
.if_flags
|= IFF_RUNNING
;
115 if (sc
->sc_if
.if_flags
& IFF_PROMISC
) {
116 sc
->sc_pdq
->pdq_flags
|= PDQ_PROMISC
;
118 sc
->sc_pdq
->pdq_flags
&= ~PDQ_PROMISC
;
121 if (sc
->sc_if
.if_flags
& IFF_LINK1
) {
122 sc
->sc_pdq
->pdq_flags
|= PDQ_PASS_SMT
;
124 sc
->sc_pdq
->pdq_flags
&= ~PDQ_PASS_SMT
;
126 sc
->sc_pdq
->pdq_flags
|= PDQ_RUNNING
;
129 sc
->sc_if
.if_flags
&= ~IFF_RUNNING
;
130 sc
->sc_pdq
->pdq_flags
&= ~PDQ_RUNNING
;
131 pdq_stop(sc
->sc_pdq
);
140 * No progress was made on the transmit queue for PDQ_OS_TX_TRANSMIT
141 * seconds. Remove all queued packets.
144 ifp
->if_flags
&= ~IFF_OACTIVE
;
148 IFQ_DEQUEUE(&ifp
->if_snd
, m
);
151 PDQ_OS_DATABUF_FREE(PDQ_OS_IFP_TO_SOFTC(ifp
)->sc_pdq
, m
);
159 pdq_softc_t
* const sc
= PDQ_OS_IFP_TO_SOFTC(ifp
);
163 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
166 if (sc
->sc_if
.if_timer
== 0)
167 sc
->sc_if
.if_timer
= PDQ_OS_TX_TIMEOUT
;
169 if ((sc
->sc_pdq
->pdq_flags
& PDQ_TXOK
) == 0) {
170 sc
->sc_if
.if_flags
|= IFF_OACTIVE
;
173 sc
->sc_flags
|= PDQIF_DOWNCALL
;
175 IFQ_POLL(&ifp
->if_snd
, m
);
178 #if defined(PDQ_BUS_DMA) && !defined(PDQ_BUS_DMA_NOTX)
179 if ((m
->m_flags
& M_HASTXDMAMAP
) == 0) {
181 if (PDQ_OS_HDR_OFFSET
!= PDQ_RX_FC_OFFSET
) {
182 m
->m_data
[0] = PDQ_FDDI_PH0
;
183 m
->m_data
[1] = PDQ_FDDI_PH1
;
184 m
->m_data
[2] = PDQ_FDDI_PH2
;
186 if (!bus_dmamap_create(sc
->sc_dmatag
, m
->m_pkthdr
.len
, 255,
187 m
->m_pkthdr
.len
, 0, BUS_DMA_NOWAIT
, &map
)) {
188 if (!bus_dmamap_load_mbuf(sc
->sc_dmatag
, map
, m
,
189 BUS_DMA_WRITE
|BUS_DMA_NOWAIT
)) {
190 bus_dmamap_sync(sc
->sc_dmatag
, map
, 0, m
->m_pkthdr
.len
,
191 BUS_DMASYNC_PREWRITE
);
193 m
->m_flags
|= M_HASTXDMAMAP
;
196 if ((m
->m_flags
& M_HASTXDMAMAP
) == 0)
200 if (PDQ_OS_HDR_OFFSET
!= PDQ_RX_FC_OFFSET
) {
201 m
->m_data
[0] = PDQ_FDDI_PH0
;
202 m
->m_data
[1] = PDQ_FDDI_PH1
;
203 m
->m_data
[2] = PDQ_FDDI_PH2
;
207 if (pdq_queue_transmit_data(sc
->sc_pdq
, m
) == PDQ_FALSE
)
209 IFQ_DEQUEUE(&ifp
->if_snd
, m
);
212 ifp
->if_flags
|= IFF_OACTIVE
;
214 PDQ_DO_TYPE2_PRODUCER(sc
->sc_pdq
);
215 sc
->sc_flags
&= ~PDQIF_DOWNCALL
;
225 pdq_softc_t
*sc
= pdq
->pdq_os_ctx
;
226 struct fddi_header
*fh
;
228 sc
->sc_if
.if_ipackets
++;
229 #if defined(PDQ_BUS_DMA)
232 * Even though the first mbuf start at the first fddi header octet,
233 * the dmamap starts PDQ_OS_HDR_OFFSET octets earlier. Any additional
234 * mbufs will start normally.
236 int offset
= PDQ_OS_HDR_OFFSET
;
238 for (m0
= m
; m0
!= NULL
; m0
= m0
->m_next
, offset
= 0) {
239 pdq_os_databuf_sync(sc
, m0
, offset
, m0
->m_len
, BUS_DMASYNC_POSTREAD
);
240 bus_dmamap_unload(sc
->sc_dmatag
, M_GETCTX(m0
, bus_dmamap_t
));
241 bus_dmamap_destroy(sc
->sc_dmatag
, M_GETCTX(m0
, bus_dmamap_t
));
242 m0
->m_flags
&= ~M_HASRXDMAMAP
;
247 m
->m_pkthdr
.len
= pktlen
;
249 if (sc
->sc_bpf
!= NULL
)
252 fh
= mtod(m
, struct fddi_header
*);
253 if (drop
|| (fh
->fddi_fc
& (FDDIFC_L
|FDDIFC_F
)) != FDDIFC_LLC_ASYNC
) {
254 PDQ_OS_DATABUF_FREE(pdq
, m
);
258 m
->m_pkthdr
.rcvif
= &sc
->sc_if
;
259 (*sc
->sc_if
.if_input
)(&sc
->sc_if
, m
);
263 pdq_os_restart_transmitter(
266 pdq_softc_t
*sc
= pdq
->pdq_os_ctx
;
267 sc
->sc_if
.if_flags
&= ~IFF_OACTIVE
;
268 if (IFQ_IS_EMPTY(&sc
->sc_if
.if_snd
) == 0) {
269 sc
->sc_if
.if_timer
= PDQ_OS_TX_TIMEOUT
;
270 if ((sc
->sc_flags
& PDQIF_DOWNCALL
) == 0)
271 pdq_ifstart(&sc
->sc_if
);
273 sc
->sc_if
.if_timer
= 0;
278 pdq_os_transmit_done(
282 pdq_softc_t
*sc
= pdq
->pdq_os_ctx
;
284 if (sc
->sc_bpf
!= NULL
)
287 PDQ_OS_DATABUF_FREE(pdq
, m
);
288 sc
->sc_if
.if_opackets
++;
297 pdq_softc_t
*sc
= pdq
->pdq_os_ctx
;
298 struct ether_multistep step
;
299 struct ether_multi
*enm
;
302 * ADDR_FILTER_SET is always issued before FILTER_SET so
303 * we can play with PDQ_ALLMULTI and not worry about
304 * queueing a FILTER_SET ourselves.
307 pdq
->pdq_flags
&= ~PDQ_ALLMULTI
;
308 #if defined(IFF_ALLMULTI)
309 sc
->sc_if
.if_flags
&= ~IFF_ALLMULTI
;
312 ETHER_FIRST_MULTI(step
, PDQ_FDDICOM(sc
), enm
);
313 while (enm
!= NULL
&& num_addrs
> 0) {
314 if (memcmp(enm
->enm_addrlo
, enm
->enm_addrhi
, 6) == 0) {
315 ((u_short
*) addr
->lanaddr_bytes
)[0] = ((u_short
*) enm
->enm_addrlo
)[0];
316 ((u_short
*) addr
->lanaddr_bytes
)[1] = ((u_short
*) enm
->enm_addrlo
)[1];
317 ((u_short
*) addr
->lanaddr_bytes
)[2] = ((u_short
*) enm
->enm_addrlo
)[2];
321 pdq
->pdq_flags
|= PDQ_ALLMULTI
;
322 #if defined(IFF_ALLMULTI)
323 sc
->sc_if
.if_flags
|= IFF_ALLMULTI
;
326 ETHER_NEXT_MULTI(step
, enm
);
329 * If not all the address fit into the CAM, turn on all-multicast mode.
332 pdq
->pdq_flags
|= PDQ_ALLMULTI
;
333 #if defined(IFF_ALLMULTI)
334 sc
->sc_if
.if_flags
|= IFF_ALLMULTI
;
339 #if defined(IFM_FDDI)
344 pdq_softc_t
* const sc
= PDQ_OS_IFP_TO_SOFTC(ifp
);
346 if (sc
->sc_ifmedia
.ifm_media
& IFM_FDX
) {
347 if ((sc
->sc_pdq
->pdq_flags
& PDQ_WANT_FDX
) == 0) {
348 sc
->sc_pdq
->pdq_flags
|= PDQ_WANT_FDX
;
349 if (sc
->sc_pdq
->pdq_flags
& PDQ_RUNNING
)
352 } else if (sc
->sc_pdq
->pdq_flags
& PDQ_WANT_FDX
) {
353 sc
->sc_pdq
->pdq_flags
&= ~PDQ_WANT_FDX
;
354 if (sc
->sc_pdq
->pdq_flags
& PDQ_RUNNING
)
364 struct ifmediareq
*ifmr
)
366 pdq_softc_t
* const sc
= PDQ_OS_IFP_TO_SOFTC(ifp
);
368 ifmr
->ifm_status
= IFM_AVALID
;
369 if (sc
->sc_pdq
->pdq_flags
& PDQ_IS_ONRING
)
370 ifmr
->ifm_status
|= IFM_ACTIVE
;
372 ifmr
->ifm_active
= (ifmr
->ifm_current
& ~IFM_FDX
);
373 if (sc
->sc_pdq
->pdq_flags
& PDQ_IS_FDX
)
374 ifmr
->ifm_active
|= IFM_FDX
;
378 pdq_os_update_status(
382 pdq_softc_t
* const sc
= pdq
->pdq_os_ctx
;
383 const pdq_response_status_chars_get_t
*rsp
= arg
;
386 switch (rsp
->status_chars_get
.pmd_type
[0]) {
387 case PDQ_PMD_TYPE_ANSI_MUTLI_MODE
: media
= IFM_FDDI_MMF
; break;
388 case PDQ_PMD_TYPE_ANSI_SINGLE_MODE_TYPE_1
: media
= IFM_FDDI_SMF
; break;
389 case PDQ_PMD_TYPE_ANSI_SIGNLE_MODE_TYPE_2
: media
= IFM_FDDI_SMF
; break;
390 case PDQ_PMD_TYPE_UNSHIELDED_TWISTED_PAIR
: media
= IFM_FDDI_UTP
; break;
391 default: media
|= IFM_MANUAL
;
394 if (rsp
->status_chars_get
.station_type
== PDQ_STATION_TYPE_DAS
)
395 media
|= IFM_FDDI_DA
;
397 sc
->sc_ifmedia
.ifm_media
= media
| IFM_FDDI
;
399 #endif /* defined(IFM_FDDI) */
407 pdq_softc_t
*sc
= PDQ_OS_IFP_TO_SOFTC(ifp
);
410 s
= PDQ_OS_SPL_RAISE();
413 case SIOCINITIFADDR
: {
414 struct ifaddr
*ifa
= (struct ifaddr
*)data
;
416 ifp
->if_flags
|= IFF_UP
;
418 switch(ifa
->ifa_addr
->sa_family
) {
421 PDQ_ARP_IFINIT(sc
, ifa
);
430 if ((error
= ifioctl_common(ifp
, cmd
, data
)) != 0)
439 * Update multicast listeners
441 if ((error
= ether_ioctl(ifp
, cmd
, data
)) == ENETRESET
) {
442 if (sc
->sc_if
.if_flags
& IFF_RUNNING
)
449 #if defined(SIOCSIFMTU)
450 #if !defined(ifr_mtu)
451 #define ifr_mtu ifr_metric
454 struct ifreq
*ifr
= (struct ifreq
*)data
;
456 * Set the interface MTU.
458 if (ifr
->ifr_mtu
> FDDIMTU
) {
462 if ((error
= ifioctl_common(ifp
, cmd
, data
)) == ENETRESET
)
466 #endif /* SIOCSIFMTU */
468 #if defined(IFM_FDDI) && defined(SIOCSIFMEDIA)
471 struct ifreq
*ifr
= (struct ifreq
*)data
;
472 error
= ifmedia_ioctl(ifp
, ifr
, &sc
->sc_ifmedia
, cmd
);
478 error
= ether_ioctl(ifp
, cmd
, data
);
487 #ifndef IFF_NOTRAILERS
488 #define IFF_NOTRAILERS 0
494 ifnet_ret_t (*ifwatchdog
)(int unit
))
496 struct ifnet
*ifp
= &sc
->sc_if
;
498 ifp
->if_flags
= IFF_BROADCAST
|IFF_SIMPLEX
|IFF_NOTRAILERS
|IFF_MULTICAST
;
500 #if (defined(__FreeBSD__) && BSD >= 199506) || defined(__NetBSD__)
501 ifp
->if_watchdog
= pdq_ifwatchdog
;
503 ifp
->if_watchdog
= ifwatchdog
;
506 ifp
->if_ioctl
= pdq_ifioctl
;
507 #if !defined(__NetBSD__)
508 ifp
->if_output
= fddi_output
;
510 ifp
->if_start
= pdq_ifstart
;
511 IFQ_SET_READY(&ifp
->if_snd
);
513 #if defined(IFM_FDDI)
515 const int media
= sc
->sc_ifmedia
.ifm_media
;
516 ifmedia_init(&sc
->sc_ifmedia
, IFM_FDX
,
517 pdq_ifmedia_change
, pdq_ifmedia_status
);
518 ifmedia_add(&sc
->sc_ifmedia
, media
, 0, 0);
519 ifmedia_set(&sc
->sc_ifmedia
, media
);
524 #if defined(__NetBSD__)
525 fddi_ifattach(ifp
, (void *)&sc
->sc_pdq
->pdq_hwaddr
);
531 #if defined(PDQ_BUS_DMA)
533 pdq_os_memalloc_contig(
536 pdq_softc_t
* const sc
= pdq
->pdq_os_ctx
;
537 bus_dma_segment_t db_segs
[1], ui_segs
[1], cb_segs
[1];
538 int db_nsegs
= 0, ui_nsegs
= 0;
542 not_ok
= bus_dmamem_alloc(sc
->sc_dmatag
,
543 sizeof(*pdq
->pdq_dbp
), sizeof(*pdq
->pdq_dbp
),
544 sizeof(*pdq
->pdq_dbp
), db_segs
, 1, &db_nsegs
,
545 #if defined(__sparc__) || defined(__sparc64__)
546 BUS_DMA_NOWAIT
| BUS_DMA_COHERENT
);
552 not_ok
= bus_dmamem_map(sc
->sc_dmatag
, db_segs
, db_nsegs
,
553 sizeof(*pdq
->pdq_dbp
), (void **) &pdq
->pdq_dbp
,
558 not_ok
= bus_dmamap_create(sc
->sc_dmatag
, db_segs
[0].ds_len
, 1,
559 0x2000, 0, BUS_DMA_NOWAIT
, &sc
->sc_dbmap
);
563 not_ok
= bus_dmamap_load(sc
->sc_dmatag
, sc
->sc_dbmap
,
564 pdq
->pdq_dbp
, sizeof(*pdq
->pdq_dbp
),
565 NULL
, BUS_DMA_NOWAIT
);
569 pdq
->pdq_pa_descriptor_block
= sc
->sc_dbmap
->dm_segs
[0].ds_addr
;
570 not_ok
= bus_dmamem_alloc(sc
->sc_dmatag
,
571 PDQ_OS_PAGESIZE
, PDQ_OS_PAGESIZE
, PDQ_OS_PAGESIZE
,
572 ui_segs
, 1, &ui_nsegs
, BUS_DMA_NOWAIT
);
576 not_ok
= bus_dmamem_map(sc
->sc_dmatag
, ui_segs
, ui_nsegs
,
578 (void **) &pdq
->pdq_unsolicited_info
.ui_events
,
583 not_ok
= bus_dmamap_create(sc
->sc_dmatag
, ui_segs
[0].ds_len
, 1,
584 PDQ_OS_PAGESIZE
, 0, BUS_DMA_NOWAIT
,
589 not_ok
= bus_dmamap_load(sc
->sc_dmatag
, sc
->sc_uimap
,
590 pdq
->pdq_unsolicited_info
.ui_events
,
591 PDQ_OS_PAGESIZE
, NULL
, BUS_DMA_NOWAIT
);
595 pdq
->pdq_unsolicited_info
.ui_pa_bufstart
= sc
->sc_uimap
->dm_segs
[0].ds_addr
;
596 cb_segs
[0] = db_segs
[0];
597 cb_segs
[0].ds_addr
+= offsetof(pdq_descriptor_block_t
, pdqdb_consumer
);
598 cb_segs
[0].ds_len
= sizeof(pdq_consumer_block_t
);
599 #if defined(__sparc__) || defined(__sparc64__)
600 pdq
->pdq_cbp
= (pdq_consumer_block_t
*)((unsigned long int)pdq
->pdq_dbp
+
601 (unsigned long int)offsetof(pdq_descriptor_block_t
,pdqdb_consumer
));
603 not_ok
= bus_dmamem_map(sc
->sc_dmatag
, cb_segs
, 1,
604 sizeof(*pdq
->pdq_cbp
),
605 (void **)&pdq
->pdq_cbp
,
606 BUS_DMA_NOWAIT
|BUS_DMA_COHERENT
);
611 not_ok
= bus_dmamap_create(sc
->sc_dmatag
, cb_segs
[0].ds_len
, 1,
612 0x2000, 0, BUS_DMA_NOWAIT
, &sc
->sc_cbmap
);
616 not_ok
= bus_dmamap_load(sc
->sc_dmatag
, sc
->sc_cbmap
,
617 pdq
->pdq_cbp
, sizeof(*pdq
->pdq_cbp
),
618 NULL
, BUS_DMA_NOWAIT
);
621 pdq
->pdq_pa_consumer_block
= sc
->sc_cbmap
->dm_segs
[0].ds_addr
;
627 bus_dmamap_unload(sc
->sc_dmatag
, sc
->sc_cbmap
);
631 bus_dmamap_destroy(sc
->sc_dmatag
, sc
->sc_cbmap
);
635 bus_dmamem_unmap(sc
->sc_dmatag
,
636 (void *)pdq
->pdq_cbp
, sizeof(*pdq
->pdq_cbp
));
640 bus_dmamap_unload(sc
->sc_dmatag
, sc
->sc_uimap
);
644 bus_dmamap_destroy(sc
->sc_dmatag
, sc
->sc_uimap
);
648 bus_dmamem_unmap(sc
->sc_dmatag
,
649 (void *) pdq
->pdq_unsolicited_info
.ui_events
,
654 bus_dmamem_free(sc
->sc_dmatag
, ui_segs
, ui_nsegs
);
658 bus_dmamap_unload(sc
->sc_dmatag
, sc
->sc_dbmap
);
662 bus_dmamap_destroy(sc
->sc_dmatag
, sc
->sc_dbmap
);
666 bus_dmamem_unmap(sc
->sc_dmatag
,
667 (void *) pdq
->pdq_dbp
,
668 sizeof(*pdq
->pdq_dbp
));
672 bus_dmamem_free(sc
->sc_dmatag
, db_segs
, db_nsegs
);
681 pdq_os_descriptor_block_sync(
687 bus_dmamap_sync(sc
->sc_dmatag
, sc
->sc_dbmap
, offset
, length
, ops
);
691 pdq_os_consumer_block_sync(
695 bus_dmamap_sync(sc
->sc_dmatag
, sc
->sc_cbmap
, 0, sizeof(pdq_consumer_block_t
), ops
);
699 pdq_os_unsolicited_event_sync(
705 bus_dmamap_sync(sc
->sc_dmatag
, sc
->sc_uimap
, offset
, length
, ops
);
716 bus_dmamap_sync(sc
->sc_dmatag
, M_GETCTX(m
, bus_dmamap_t
), offset
, length
, ops
);
724 if (m
->m_flags
& (M_HASRXDMAMAP
|M_HASTXDMAMAP
)) {
725 bus_dmamap_t map
= M_GETCTX(m
, bus_dmamap_t
);
726 bus_dmamap_unload(sc
->sc_dmatag
, map
);
727 bus_dmamap_destroy(sc
->sc_dmatag
, map
);
728 m
->m_flags
&= ~(M_HASRXDMAMAP
|M_HASTXDMAMAP
);
734 pdq_os_databuf_alloc(
740 MGETHDR(m
, M_DONTWAIT
, MT_DATA
);
742 aprint_error_dev(&sc
->sc_dev
, "can't alloc small buf\n");
745 MCLGET(m
, M_DONTWAIT
);
746 if ((m
->m_flags
& M_EXT
) == 0) {
747 aprint_error_dev(&sc
->sc_dev
, "can't alloc cluster\n");
751 MCLAIM(m
, &PDQ_FDDICOM(sc
)->ec_rx_mowner
);
752 m
->m_pkthdr
.len
= m
->m_len
= PDQ_OS_DATABUF_SIZE
;
754 if (bus_dmamap_create(sc
->sc_dmatag
, PDQ_OS_DATABUF_SIZE
,
755 1, PDQ_OS_DATABUF_SIZE
, 0, BUS_DMA_NOWAIT
, &map
)) {
756 aprint_error_dev(&sc
->sc_dev
, "can't create dmamap\n");
760 if (bus_dmamap_load_mbuf(sc
->sc_dmatag
, map
, m
,
761 BUS_DMA_READ
|BUS_DMA_NOWAIT
)) {
762 aprint_error_dev(&sc
->sc_dev
, "can't load dmamap\n");
763 bus_dmamap_destroy(sc
->sc_dmatag
, map
);
767 m
->m_flags
|= M_HASRXDMAMAP
;