2 * Copyright (c) 1997, 1998, 1999
3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
32 * $FreeBSD: src/sys/pci/if_sf.c,v 1.18.2.8 2001/12/16 15:46:07 luigi Exp $
33 * $DragonFly: src/sys/dev/netif/sf/if_sf.c,v 1.31 2008/01/05 14:02:37 swildner Exp $
37 * Adaptec AIC-6915 "Starfire" PCI fast ethernet driver for FreeBSD.
38 * Programming manual is available from:
39 * ftp.adaptec.com:/pub/BBS/userguides/aic6915_pg.pdf.
41 * Written by Bill Paul <wpaul@ctr.columbia.edu>
42 * Department of Electical Engineering
43 * Columbia University, New York City
47 * The Adaptec AIC-6915 "Starfire" is a 64-bit 10/100 PCI ethernet
48 * controller designed with flexibility and reducing CPU load in mind.
49 * The Starfire offers high and low priority buffer queues, a
50 * producer/consumer index mechanism and several different buffer
51 * queue and completion queue descriptor types. Any one of a number
52 * of different driver designs can be used, depending on system and
53 * OS requirements. This driver makes use of type0 transmit frame
54 * descriptors (since BSD fragments packets across an mbuf chain)
55 * and two RX buffer queues prioritized on size (one queue for small
56 * frames that will fit into a single mbuf, another with full size
57 * mbuf clusters for everything else). The producer/consumer indexes
58 * and completion queues are also used.
60 * One downside to the Starfire has to do with alignment: buffer
61 * queues must be aligned on 256-byte boundaries, and receive buffers
62 * must be aligned on longword boundaries. The receive buffer alignment
63 * causes problems on the Alpha platform, where the packet payload
64 * should be longword aligned. There is no simple way around this.
66 * For receive filtering, the Starfire offers 16 perfect filter slots
67 * and a 512-bit hash table.
69 * The Starfire has no internal transceiver, relying instead on an
70 * external MII-based transceiver. Accessing registers on external
71 * PHYs is done through a special register map rather than with the
72 * usual bitbang MDIO method.
74 * Acesssing the registers on the Starfire is a little tricky. The
75 * Starfire has a 512K internal register space. When programmed for
76 * PCI memory mapped mode, the entire register space can be accessed
77 * directly. However in I/O space mode, only 256 bytes are directly
78 * mapped into PCI I/O space. The other registers can be accessed
79 * indirectly using the SF_INDIRECTIO_ADDR and SF_INDIRECTIO_DATA
80 * registers inside the 256-byte I/O window.
83 #include <sys/param.h>
84 #include <sys/systm.h>
85 #include <sys/sockio.h>
87 #include <sys/malloc.h>
88 #include <sys/kernel.h>
89 #include <sys/socket.h>
90 #include <sys/serialize.h>
93 #include <sys/thread2.h>
96 #include <net/ifq_var.h>
97 #include <net/if_arp.h>
98 #include <net/ethernet.h>
99 #include <net/if_dl.h>
100 #include <net/if_media.h>
104 #include <vm/vm.h> /* for vtophys */
105 #include <vm/pmap.h> /* for vtophys */
107 #include <machine/clock.h> /* for DELAY */
109 #include "../mii_layer/mii.h"
110 #include "../mii_layer/miivar.h"
112 /* "controller miibus0" required. See GENERIC if you get errors here. */
113 #include "miibus_if.h"
115 #include <bus/pci/pcidevs.h>
116 #include <bus/pci/pcireg.h>
117 #include <bus/pci/pcivar.h>
119 #define SF_USEIOSPACE
121 #include "if_sfreg.h"
123 static struct sf_type sf_devs
[] = {
124 { PCI_VENDOR_ADP
, PCI_PRODUCT_ADP_AIC6915
,
125 "Adaptec AIC-6915 10/100BaseTX" },
129 static int sf_probe (device_t
);
130 static int sf_attach (device_t
);
131 static int sf_detach (device_t
);
132 static void sf_intr (void *);
133 static void sf_stats_update (void *);
134 static void sf_rxeof (struct sf_softc
*);
135 static void sf_txeof (struct sf_softc
*);
136 static int sf_encap (struct sf_softc
*,
137 struct sf_tx_bufdesc_type0
*,
139 static void sf_start (struct ifnet
*);
140 static int sf_ioctl (struct ifnet
*, u_long
, caddr_t
,
142 static void sf_init (void *);
143 static void sf_stop (struct sf_softc
*);
144 static void sf_watchdog (struct ifnet
*);
145 static void sf_shutdown (device_t
);
146 static int sf_ifmedia_upd (struct ifnet
*);
147 static void sf_ifmedia_sts (struct ifnet
*, struct ifmediareq
*);
148 static void sf_reset (struct sf_softc
*);
149 static int sf_init_rx_ring (struct sf_softc
*);
150 static void sf_init_tx_ring (struct sf_softc
*);
151 static int sf_newbuf (struct sf_softc
*,
152 struct sf_rx_bufdesc_type0
*,
154 static void sf_setmulti (struct sf_softc
*);
155 static int sf_setperf (struct sf_softc
*, int, caddr_t
);
156 static int sf_sethash (struct sf_softc
*, caddr_t
, int);
158 static int sf_setvlan (struct sf_softc
*, int, u_int32_t
);
161 static u_int8_t
sf_read_eeprom (struct sf_softc
*, int);
162 static u_int32_t
sf_calchash (caddr_t
);
164 static int sf_miibus_readreg (device_t
, int, int);
165 static int sf_miibus_writereg (device_t
, int, int, int);
166 static void sf_miibus_statchg (device_t
);
168 static u_int32_t
csr_read_4 (struct sf_softc
*, int);
169 static void csr_write_4 (struct sf_softc
*, int, u_int32_t
);
170 static void sf_txthresh_adjust (struct sf_softc
*);
173 #define SF_RES SYS_RES_IOPORT
174 #define SF_RID SF_PCI_LOIO
176 #define SF_RES SYS_RES_MEMORY
177 #define SF_RID SF_PCI_LOMEM
180 static device_method_t sf_methods
[] = {
181 /* Device interface */
182 DEVMETHOD(device_probe
, sf_probe
),
183 DEVMETHOD(device_attach
, sf_attach
),
184 DEVMETHOD(device_detach
, sf_detach
),
185 DEVMETHOD(device_shutdown
, sf_shutdown
),
188 DEVMETHOD(bus_print_child
, bus_generic_print_child
),
189 DEVMETHOD(bus_driver_added
, bus_generic_driver_added
),
192 DEVMETHOD(miibus_readreg
, sf_miibus_readreg
),
193 DEVMETHOD(miibus_writereg
, sf_miibus_writereg
),
194 DEVMETHOD(miibus_statchg
, sf_miibus_statchg
),
199 static driver_t sf_driver
= {
202 sizeof(struct sf_softc
),
205 static devclass_t sf_devclass
;
207 DECLARE_DUMMY_MODULE(if_sf
);
208 DRIVER_MODULE(if_sf
, pci
, sf_driver
, sf_devclass
, 0, 0);
209 DRIVER_MODULE(miibus
, sf
, miibus_driver
, miibus_devclass
, 0, 0);
211 #define SF_SETBIT(sc, reg, x) \
212 csr_write_4(sc, reg, csr_read_4(sc, reg) | x)
214 #define SF_CLRBIT(sc, reg, x) \
215 csr_write_4(sc, reg, csr_read_4(sc, reg) & ~x)
218 csr_read_4(struct sf_softc
*sc
, int reg
)
223 CSR_WRITE_4(sc
, SF_INDIRECTIO_ADDR
, reg
+ SF_RMAP_INTREG_BASE
);
224 val
= CSR_READ_4(sc
, SF_INDIRECTIO_DATA
);
226 val
= CSR_READ_4(sc
, (reg
+ SF_RMAP_INTREG_BASE
));
233 sf_read_eeprom(struct sf_softc
*sc
, int reg
)
237 val
= (csr_read_4(sc
, SF_EEADDR_BASE
+
238 (reg
& 0xFFFFFFFC)) >> (8 * (reg
& 3))) & 0xFF;
244 csr_write_4(struct sf_softc
*sc
, int reg
, u_int32_t val
)
247 CSR_WRITE_4(sc
, SF_INDIRECTIO_ADDR
, reg
+ SF_RMAP_INTREG_BASE
);
248 CSR_WRITE_4(sc
, SF_INDIRECTIO_DATA
, val
);
250 CSR_WRITE_4(sc
, (reg
+ SF_RMAP_INTREG_BASE
), val
);
256 sf_calchash(caddr_t addr
)
258 u_int32_t crc
, carry
;
262 /* Compute CRC for the address value. */
263 crc
= 0xFFFFFFFF; /* initial value */
265 for (i
= 0; i
< 6; i
++) {
267 for (j
= 0; j
< 8; j
++) {
268 carry
= ((crc
& 0x80000000) ? 1 : 0) ^ (c
& 0x01);
272 crc
= (crc
^ 0x04c11db6) | carry
;
276 /* return the filter bit position */
277 return(crc
>> 23 & 0x1FF);
281 * Copy the address 'mac' into the perfect RX filter entry at
282 * offset 'idx.' The perfect filter only has 16 entries so do
286 sf_setperf(struct sf_softc
*sc
, int idx
, caddr_t mac
)
290 if (idx
< 0 || idx
> SF_RXFILT_PERFECT_CNT
)
296 p
= (u_int16_t
*)mac
;
298 csr_write_4(sc
, SF_RXFILT_PERFECT_BASE
+
299 (idx
* SF_RXFILT_PERFECT_SKIP
), htons(p
[2]));
300 csr_write_4(sc
, SF_RXFILT_PERFECT_BASE
+
301 (idx
* SF_RXFILT_PERFECT_SKIP
) + 4, htons(p
[1]));
302 csr_write_4(sc
, SF_RXFILT_PERFECT_BASE
+
303 (idx
* SF_RXFILT_PERFECT_SKIP
) + 8, htons(p
[0]));
309 * Set the bit in the 512-bit hash table that corresponds to the
310 * specified mac address 'mac.' If 'prio' is nonzero, update the
311 * priority hash table instead of the filter hash table.
314 sf_sethash(struct sf_softc
*sc
, caddr_t mac
, int prio
)
321 h
= sf_calchash(mac
);
324 SF_SETBIT(sc
, SF_RXFILT_HASH_BASE
+ SF_RXFILT_HASH_PRIOOFF
+
325 (SF_RXFILT_HASH_SKIP
* (h
>> 4)), (1 << (h
& 0xF)));
327 SF_SETBIT(sc
, SF_RXFILT_HASH_BASE
+ SF_RXFILT_HASH_ADDROFF
+
328 (SF_RXFILT_HASH_SKIP
* (h
>> 4)), (1 << (h
& 0xF)));
336 * Set a VLAN tag in the receive filter.
339 sf_setvlan(struct sf_softc
*sc
, int idx
, u_int32_t vlan
)
341 if (idx
< 0 || idx
>> SF_RXFILT_HASH_CNT
)
344 csr_write_4(sc
, SF_RXFILT_HASH_BASE
+
345 (idx
* SF_RXFILT_HASH_SKIP
) + SF_RXFILT_HASH_VLANOFF
, vlan
);
352 sf_miibus_readreg(device_t dev
, int phy
, int reg
)
358 sc
= device_get_softc(dev
);
360 for (i
= 0; i
< SF_TIMEOUT
; i
++) {
361 val
= csr_read_4(sc
, SF_PHY_REG(phy
, reg
));
362 if (val
& SF_MII_DATAVALID
)
369 if ((val
& 0x0000FFFF) == 0xFFFF)
372 return(val
& 0x0000FFFF);
376 sf_miibus_writereg(device_t dev
, int phy
, int reg
, int val
)
382 sc
= device_get_softc(dev
);
384 csr_write_4(sc
, SF_PHY_REG(phy
, reg
), val
);
386 for (i
= 0; i
< SF_TIMEOUT
; i
++) {
387 busy
= csr_read_4(sc
, SF_PHY_REG(phy
, reg
));
388 if (!(busy
& SF_MII_BUSY
))
396 sf_miibus_statchg(device_t dev
)
399 struct mii_data
*mii
;
401 sc
= device_get_softc(dev
);
402 mii
= device_get_softc(sc
->sf_miibus
);
404 if ((mii
->mii_media_active
& IFM_GMASK
) == IFM_FDX
) {
405 SF_SETBIT(sc
, SF_MACCFG_1
, SF_MACCFG1_FULLDUPLEX
);
406 csr_write_4(sc
, SF_BKTOBKIPG
, SF_IPGT_FDX
);
408 SF_CLRBIT(sc
, SF_MACCFG_1
, SF_MACCFG1_FULLDUPLEX
);
409 csr_write_4(sc
, SF_BKTOBKIPG
, SF_IPGT_HDX
);
416 sf_setmulti(struct sf_softc
*sc
)
420 struct ifmultiaddr
*ifma
;
421 u_int8_t dummy
[] = { 0, 0, 0, 0, 0, 0 };
423 ifp
= &sc
->arpcom
.ac_if
;
425 /* First zot all the existing filters. */
426 for (i
= 1; i
< SF_RXFILT_PERFECT_CNT
; i
++)
427 sf_setperf(sc
, i
, (char *)&dummy
);
428 for (i
= SF_RXFILT_HASH_BASE
;
429 i
< (SF_RXFILT_HASH_MAX
+ 1); i
+= 4)
430 csr_write_4(sc
, i
, 0);
431 SF_CLRBIT(sc
, SF_RXFILT
, SF_RXFILT_ALLMULTI
);
433 /* Now program new ones. */
434 if (ifp
->if_flags
& IFF_ALLMULTI
|| ifp
->if_flags
& IFF_PROMISC
) {
435 SF_SETBIT(sc
, SF_RXFILT
, SF_RXFILT_ALLMULTI
);
438 /* First find the tail of the list. */
439 for (ifma
= ifp
->if_multiaddrs
.lh_first
; ifma
!= NULL
;
440 ifma
= ifma
->ifma_link
.le_next
) {
441 if (ifma
->ifma_link
.le_next
== NULL
)
444 /* Now traverse the list backwards. */
445 for (; ifma
!= NULL
&& ifma
!= (void *)&ifp
->if_multiaddrs
;
446 ifma
= (struct ifmultiaddr
*)ifma
->ifma_link
.le_prev
) {
447 if (ifma
->ifma_addr
->sa_family
!= AF_LINK
)
450 * Program the first 15 multicast groups
451 * into the perfect filter. For all others,
452 * use the hash table.
454 if (i
< SF_RXFILT_PERFECT_CNT
) {
456 LLADDR((struct sockaddr_dl
*)ifma
->ifma_addr
));
462 LLADDR((struct sockaddr_dl
*)ifma
->ifma_addr
), 0);
473 sf_ifmedia_upd(struct ifnet
*ifp
)
476 struct mii_data
*mii
;
479 mii
= device_get_softc(sc
->sf_miibus
);
481 if (mii
->mii_instance
) {
482 struct mii_softc
*miisc
;
483 for (miisc
= LIST_FIRST(&mii
->mii_phys
); miisc
!= NULL
;
484 miisc
= LIST_NEXT(miisc
, mii_list
))
485 mii_phy_reset(miisc
);
493 * Report current media status.
496 sf_ifmedia_sts(struct ifnet
*ifp
, struct ifmediareq
*ifmr
)
499 struct mii_data
*mii
;
502 mii
= device_get_softc(sc
->sf_miibus
);
505 ifmr
->ifm_active
= mii
->mii_media_active
;
506 ifmr
->ifm_status
= mii
->mii_media_status
;
512 sf_ioctl(struct ifnet
*ifp
, u_long command
, caddr_t data
, struct ucred
*cr
)
514 struct sf_softc
*sc
= ifp
->if_softc
;
515 struct ifreq
*ifr
= (struct ifreq
*) data
;
516 struct mii_data
*mii
;
521 if (ifp
->if_flags
& IFF_UP
) {
522 if (ifp
->if_flags
& IFF_RUNNING
&&
523 ifp
->if_flags
& IFF_PROMISC
&&
524 !(sc
->sf_if_flags
& IFF_PROMISC
)) {
525 SF_SETBIT(sc
, SF_RXFILT
, SF_RXFILT_PROMISC
);
526 } else if (ifp
->if_flags
& IFF_RUNNING
&&
527 !(ifp
->if_flags
& IFF_PROMISC
) &&
528 sc
->sf_if_flags
& IFF_PROMISC
) {
529 SF_CLRBIT(sc
, SF_RXFILT
, SF_RXFILT_PROMISC
);
530 } else if (!(ifp
->if_flags
& IFF_RUNNING
))
533 if (ifp
->if_flags
& IFF_RUNNING
)
536 sc
->sf_if_flags
= ifp
->if_flags
;
546 mii
= device_get_softc(sc
->sf_miibus
);
547 error
= ifmedia_ioctl(ifp
, ifr
, &mii
->mii_media
, command
);
550 error
= ether_ioctl(ifp
, command
, data
);
558 sf_reset(struct sf_softc
*sc
)
562 csr_write_4(sc
, SF_GEN_ETH_CTL
, 0);
563 SF_SETBIT(sc
, SF_MACCFG_1
, SF_MACCFG1_SOFTRESET
);
565 SF_CLRBIT(sc
, SF_MACCFG_1
, SF_MACCFG1_SOFTRESET
);
567 SF_SETBIT(sc
, SF_PCI_DEVCFG
, SF_PCIDEVCFG_RESET
);
569 for (i
= 0; i
< SF_TIMEOUT
; i
++) {
571 if (!(csr_read_4(sc
, SF_PCI_DEVCFG
) & SF_PCIDEVCFG_RESET
))
576 kprintf("sf%d: reset never completed!\n", sc
->sf_unit
);
578 /* Wait a little while for the chip to get its brains in order. */
584 * Probe for an Adaptec AIC-6915 chip. Check the PCI vendor and device
585 * IDs against our list and return a device name if we find a match.
586 * We also check the subsystem ID so that we can identify exactly which
587 * NIC has been found, if possible.
590 sf_probe(device_t dev
)
596 while(t
->sf_name
!= NULL
) {
597 if ((pci_get_vendor(dev
) == t
->sf_vid
) &&
598 (pci_get_device(dev
) == t
->sf_did
)) {
599 switch((pci_read_config(dev
,
600 SF_PCI_SUBVEN_ID
, 4) >> 16) & 0xFFFF) {
601 case AD_SUBSYSID_62011_REV0
:
602 case AD_SUBSYSID_62011_REV1
:
604 "Adaptec ANA-62011 10/100BaseTX");
607 case AD_SUBSYSID_62022
:
609 "Adaptec ANA-62022 10/100BaseTX");
612 case AD_SUBSYSID_62044_REV0
:
613 case AD_SUBSYSID_62044_REV1
:
615 "Adaptec ANA-62044 10/100BaseTX");
618 case AD_SUBSYSID_62020
:
620 "Adaptec ANA-62020 10/100BaseFX");
623 case AD_SUBSYSID_69011
:
625 "Adaptec ANA-69011 10/100BaseTX");
629 device_set_desc(dev
, t
->sf_name
);
641 * Attach the interface. Allocate softc structures, do ifmedia
642 * setup and ethernet/BPF attach.
645 sf_attach(device_t dev
)
651 int unit
, rid
, error
= 0;
653 sc
= device_get_softc(dev
);
654 unit
= device_get_unit(dev
);
657 * Handle power management nonsense.
659 command
= pci_read_config(dev
, SF_PCI_CAPID
, 4) & 0x000000FF;
660 if (command
== 0x01) {
662 command
= pci_read_config(dev
, SF_PCI_PWRMGMTCTRL
, 4);
663 if (command
& SF_PSTATE_MASK
) {
664 u_int32_t iobase
, membase
, irq
;
666 /* Save important PCI config data. */
667 iobase
= pci_read_config(dev
, SF_PCI_LOIO
, 4);
668 membase
= pci_read_config(dev
, SF_PCI_LOMEM
, 4);
669 irq
= pci_read_config(dev
, SF_PCI_INTLINE
, 4);
671 /* Reset the power state. */
672 kprintf("sf%d: chip is in D%d power mode "
673 "-- setting to D0\n", unit
, command
& SF_PSTATE_MASK
);
674 command
&= 0xFFFFFFFC;
675 pci_write_config(dev
, SF_PCI_PWRMGMTCTRL
, command
, 4);
677 /* Restore PCI config data. */
678 pci_write_config(dev
, SF_PCI_LOIO
, iobase
, 4);
679 pci_write_config(dev
, SF_PCI_LOMEM
, membase
, 4);
680 pci_write_config(dev
, SF_PCI_INTLINE
, irq
, 4);
685 * Map control/status registers.
687 command
= pci_read_config(dev
, PCIR_COMMAND
, 4);
688 command
|= (PCIM_CMD_PORTEN
|PCIM_CMD_MEMEN
|PCIM_CMD_BUSMASTEREN
);
689 pci_write_config(dev
, PCIR_COMMAND
, command
, 4);
690 command
= pci_read_config(dev
, PCIR_COMMAND
, 4);
693 if (!(command
& PCIM_CMD_PORTEN
)) {
694 kprintf("sf%d: failed to enable I/O ports!\n", unit
);
699 if (!(command
& PCIM_CMD_MEMEN
)) {
700 kprintf("sf%d: failed to enable memory mapping!\n", unit
);
707 sc
->sf_res
= bus_alloc_resource_any(dev
, SF_RES
, &rid
, RF_ACTIVE
);
709 if (sc
->sf_res
== NULL
) {
710 kprintf ("sf%d: couldn't map ports\n", unit
);
715 sc
->sf_btag
= rman_get_bustag(sc
->sf_res
);
716 sc
->sf_bhandle
= rman_get_bushandle(sc
->sf_res
);
718 /* Allocate interrupt */
720 sc
->sf_irq
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
, &rid
,
721 RF_SHAREABLE
| RF_ACTIVE
);
723 if (sc
->sf_irq
== NULL
) {
724 kprintf("sf%d: couldn't map interrupt\n", unit
);
729 callout_init(&sc
->sf_stat_timer
);
731 /* Reset the adapter. */
735 * Get station address from the EEPROM.
737 for (i
= 0; i
< ETHER_ADDR_LEN
; i
++)
738 sc
->arpcom
.ac_enaddr
[i
] =
739 sf_read_eeprom(sc
, SF_EE_NODEADDR
+ ETHER_ADDR_LEN
- i
);
743 /* Allocate the descriptor queues. */
744 sc
->sf_ldata
= contigmalloc(sizeof(struct sf_list_data
), M_DEVBUF
,
745 M_WAITOK
| M_ZERO
, 0, 0xffffffff, PAGE_SIZE
, 0);
747 if (sc
->sf_ldata
== NULL
) {
748 kprintf("sf%d: no memory for list buffers!\n", unit
);
754 if (mii_phy_probe(dev
, &sc
->sf_miibus
,
755 sf_ifmedia_upd
, sf_ifmedia_sts
)) {
756 kprintf("sf%d: MII without any phy!\n", sc
->sf_unit
);
761 ifp
= &sc
->arpcom
.ac_if
;
763 if_initname(ifp
, "sf", unit
);
764 ifp
->if_mtu
= ETHERMTU
;
765 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
766 ifp
->if_ioctl
= sf_ioctl
;
767 ifp
->if_start
= sf_start
;
768 ifp
->if_watchdog
= sf_watchdog
;
769 ifp
->if_init
= sf_init
;
770 ifp
->if_baudrate
= 10000000;
771 ifq_set_maxlen(&ifp
->if_snd
, SF_TX_DLIST_CNT
- 1);
772 ifq_set_ready(&ifp
->if_snd
);
775 * Call MI attach routine.
777 ether_ifattach(ifp
, sc
->arpcom
.ac_enaddr
, NULL
);
779 error
= bus_setup_intr(dev
, sc
->sf_irq
, INTR_NETSAFE
,
780 sf_intr
, sc
, &sc
->sf_intrhand
,
785 device_printf(dev
, "couldn't set up irq\n");
797 sf_detach(device_t dev
)
799 struct sf_softc
*sc
= device_get_softc(dev
);
800 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
802 if (device_is_attached(dev
)) {
803 lwkt_serialize_enter(ifp
->if_serializer
);
805 bus_teardown_intr(dev
, sc
->sf_irq
, sc
->sf_intrhand
);
806 lwkt_serialize_exit(ifp
->if_serializer
);
812 device_delete_child(dev
, sc
->sf_miibus
);
813 bus_generic_detach(dev
);
816 bus_release_resource(dev
, SYS_RES_IRQ
, 0, sc
->sf_irq
);
818 bus_release_resource(dev
, SF_RES
, SF_RID
, sc
->sf_res
);
821 contigfree(sc
->sf_ldata
, sizeof(struct sf_list_data
),
829 sf_init_rx_ring(struct sf_softc
*sc
)
831 struct sf_list_data
*ld
;
836 bzero((char *)ld
->sf_rx_dlist_big
,
837 sizeof(struct sf_rx_bufdesc_type0
) * SF_RX_DLIST_CNT
);
838 bzero((char *)ld
->sf_rx_clist
,
839 sizeof(struct sf_rx_cmpdesc_type3
) * SF_RX_CLIST_CNT
);
841 for (i
= 0; i
< SF_RX_DLIST_CNT
; i
++) {
842 if (sf_newbuf(sc
, &ld
->sf_rx_dlist_big
[i
], NULL
) == ENOBUFS
)
850 sf_init_tx_ring(struct sf_softc
*sc
)
852 struct sf_list_data
*ld
;
857 bzero((char *)ld
->sf_tx_dlist
,
858 sizeof(struct sf_tx_bufdesc_type0
) * SF_TX_DLIST_CNT
);
859 bzero((char *)ld
->sf_tx_clist
,
860 sizeof(struct sf_tx_cmpdesc_type0
) * SF_TX_CLIST_CNT
);
862 for (i
= 0; i
< SF_TX_DLIST_CNT
; i
++)
863 ld
->sf_tx_dlist
[i
].sf_id
= SF_TX_BUFDESC_ID
;
864 for (i
= 0; i
< SF_TX_CLIST_CNT
; i
++)
865 ld
->sf_tx_clist
[i
].sf_type
= SF_TXCMPTYPE_TX
;
867 ld
->sf_tx_dlist
[SF_TX_DLIST_CNT
- 1].sf_end
= 1;
874 sf_newbuf(struct sf_softc
*sc
, struct sf_rx_bufdesc_type0
*c
,
877 struct mbuf
*m_new
= NULL
;
880 MGETHDR(m_new
, MB_DONTWAIT
, MT_DATA
);
884 MCLGET(m_new
, MB_DONTWAIT
);
885 if (!(m_new
->m_flags
& M_EXT
)) {
889 m_new
->m_len
= m_new
->m_pkthdr
.len
= MCLBYTES
;
892 m_new
->m_len
= m_new
->m_pkthdr
.len
= MCLBYTES
;
893 m_new
->m_data
= m_new
->m_ext
.ext_buf
;
896 m_adj(m_new
, sizeof(u_int64_t
));
899 c
->sf_addrlo
= SF_RX_HOSTADDR(vtophys(mtod(m_new
, caddr_t
)));
906 * The starfire is programmed to use 'normal' mode for packet reception,
907 * which means we use the consumer/producer model for both the buffer
908 * descriptor queue and the completion descriptor queue. The only problem
909 * with this is that it involves a lot of register accesses: we have to
910 * read the RX completion consumer and producer indexes and the RX buffer
911 * producer index, plus the RX completion consumer and RX buffer producer
912 * indexes have to be updated. It would have been easier if Adaptec had
913 * put each index in a separate register, especially given that the damn
914 * NIC has a 512K register space.
916 * In spite of all the lovely features that Adaptec crammed into the 6915,
917 * it is marred by one truly stupid design flaw, which is that receive
918 * buffer addresses must be aligned on a longword boundary. This forces
919 * the packet payload to be unaligned, which is suboptimal on the x86 and
920 * completely unuseable on the Alpha. Our only recourse is to copy received
921 * packets into properly aligned buffers before handing them off.
925 sf_rxeof(struct sf_softc
*sc
)
929 struct sf_rx_bufdesc_type0
*desc
;
930 struct sf_rx_cmpdesc_type3
*cur_rx
;
931 u_int32_t rxcons
, rxprod
;
932 int cmpprodidx
, cmpconsidx
, bufprodidx
;
934 ifp
= &sc
->arpcom
.ac_if
;
936 rxcons
= csr_read_4(sc
, SF_CQ_CONSIDX
);
937 rxprod
= csr_read_4(sc
, SF_RXDQ_PTR_Q1
);
938 cmpprodidx
= SF_IDX_LO(csr_read_4(sc
, SF_CQ_PRODIDX
));
939 cmpconsidx
= SF_IDX_LO(rxcons
);
940 bufprodidx
= SF_IDX_LO(rxprod
);
942 while (cmpconsidx
!= cmpprodidx
) {
945 cur_rx
= &sc
->sf_ldata
->sf_rx_clist
[cmpconsidx
];
946 desc
= &sc
->sf_ldata
->sf_rx_dlist_big
[cur_rx
->sf_endidx
];
948 SF_INC(cmpconsidx
, SF_RX_CLIST_CNT
);
949 SF_INC(bufprodidx
, SF_RX_DLIST_CNT
);
951 if (!(cur_rx
->sf_status1
& SF_RXSTAT1_OK
)) {
953 sf_newbuf(sc
, desc
, m
);
957 m0
= m_devget(mtod(m
, char *) - ETHER_ALIGN
,
958 cur_rx
->sf_len
+ ETHER_ALIGN
, 0, ifp
, NULL
);
959 sf_newbuf(sc
, desc
, m
);
964 m_adj(m0
, ETHER_ALIGN
);
969 ifp
->if_input(ifp
, m
);
972 csr_write_4(sc
, SF_CQ_CONSIDX
,
973 (rxcons
& ~SF_CQ_CONSIDX_RXQ1
) | cmpconsidx
);
974 csr_write_4(sc
, SF_RXDQ_PTR_Q1
,
975 (rxprod
& ~SF_RXDQ_PRODIDX
) | bufprodidx
);
981 * Read the transmit status from the completion queue and release
982 * mbufs. Note that the buffer descriptor index in the completion
983 * descriptor is an offset from the start of the transmit buffer
984 * descriptor list in bytes. This is important because the manual
985 * gives the impression that it should match the producer/consumer
986 * index, which is the offset in 8 byte blocks.
989 sf_txeof(struct sf_softc
*sc
)
991 int txcons
, cmpprodidx
, cmpconsidx
;
992 struct sf_tx_cmpdesc_type1
*cur_cmp
;
993 struct sf_tx_bufdesc_type0
*cur_tx
;
996 ifp
= &sc
->arpcom
.ac_if
;
998 txcons
= csr_read_4(sc
, SF_CQ_CONSIDX
);
999 cmpprodidx
= SF_IDX_HI(csr_read_4(sc
, SF_CQ_PRODIDX
));
1000 cmpconsidx
= SF_IDX_HI(txcons
);
1002 while (cmpconsidx
!= cmpprodidx
) {
1003 cur_cmp
= &sc
->sf_ldata
->sf_tx_clist
[cmpconsidx
];
1004 cur_tx
= &sc
->sf_ldata
->sf_tx_dlist
[cur_cmp
->sf_index
>> 7];
1006 if (cur_cmp
->sf_txstat
& SF_TXSTAT_TX_OK
)
1009 if (cur_cmp
->sf_txstat
& SF_TXSTAT_TX_UNDERRUN
)
1010 sf_txthresh_adjust(sc
);
1015 if (cur_tx
->sf_mbuf
!= NULL
) {
1016 m_freem(cur_tx
->sf_mbuf
);
1017 cur_tx
->sf_mbuf
= NULL
;
1020 SF_INC(cmpconsidx
, SF_TX_CLIST_CNT
);
1024 ifp
->if_flags
&= ~IFF_OACTIVE
;
1026 csr_write_4(sc
, SF_CQ_CONSIDX
,
1027 (txcons
& ~SF_CQ_CONSIDX_TXQ
) |
1028 ((cmpconsidx
<< 16) & 0xFFFF0000));
1034 sf_txthresh_adjust(struct sf_softc
*sc
)
1039 txfctl
= csr_read_4(sc
, SF_TX_FRAMCTL
);
1040 txthresh
= txfctl
& SF_TXFRMCTL_TXTHRESH
;
1041 if (txthresh
< 0xFF) {
1043 txfctl
&= ~SF_TXFRMCTL_TXTHRESH
;
1046 kprintf("sf%d: tx underrun, increasing "
1047 "tx threshold to %d bytes\n",
1048 sc
->sf_unit
, txthresh
* 4);
1050 csr_write_4(sc
, SF_TX_FRAMCTL
, txfctl
);
1059 struct sf_softc
*sc
;
1064 ifp
= &sc
->arpcom
.ac_if
;
1066 if (!(csr_read_4(sc
, SF_ISR_SHADOW
) & SF_ISR_PCIINT_ASSERTED
))
1069 /* Disable interrupts. */
1070 csr_write_4(sc
, SF_IMR
, 0x00000000);
1073 status
= csr_read_4(sc
, SF_ISR
);
1075 csr_write_4(sc
, SF_ISR
, status
);
1077 if (!(status
& SF_INTRS
))
1080 if (status
& SF_ISR_RXDQ1_DMADONE
)
1083 if (status
& SF_ISR_TX_TXDONE
||
1084 status
& SF_ISR_TX_DMADONE
||
1085 status
& SF_ISR_TX_QUEUEDONE
)
1088 if (status
& SF_ISR_TX_LOFIFO
)
1089 sf_txthresh_adjust(sc
);
1091 if (status
& SF_ISR_ABNORMALINTR
) {
1092 if (status
& SF_ISR_STATSOFLOW
) {
1093 callout_stop(&sc
->sf_stat_timer
);
1094 sf_stats_update(sc
);
1100 /* Re-enable interrupts. */
1101 csr_write_4(sc
, SF_IMR
, SF_INTRS
);
1103 if (!ifq_is_empty(&ifp
->if_snd
))
1112 struct sf_softc
*sc
= xsc
;
1113 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
1119 /* Init all the receive filter registers */
1120 for (i
= SF_RXFILT_PERFECT_BASE
;
1121 i
< (SF_RXFILT_HASH_MAX
+ 1); i
+= 4)
1122 csr_write_4(sc
, i
, 0);
1124 /* Empty stats counter registers. */
1125 for (i
= 0; i
< sizeof(struct sf_stats
)/sizeof(u_int32_t
); i
++)
1126 csr_write_4(sc
, SF_STATS_BASE
+
1127 (i
+ sizeof(u_int32_t
)), 0);
1129 /* Init our MAC address */
1130 csr_write_4(sc
, SF_PAR0
, *(u_int32_t
*)(&sc
->arpcom
.ac_enaddr
[0]));
1131 csr_write_4(sc
, SF_PAR1
, *(u_int32_t
*)(&sc
->arpcom
.ac_enaddr
[4]));
1132 sf_setperf(sc
, 0, (caddr_t
)&sc
->arpcom
.ac_enaddr
);
1134 if (sf_init_rx_ring(sc
) == ENOBUFS
) {
1135 kprintf("sf%d: initialization failed: no "
1136 "memory for rx buffers\n", sc
->sf_unit
);
1140 sf_init_tx_ring(sc
);
1142 csr_write_4(sc
, SF_RXFILT
, SF_PERFMODE_NORMAL
|SF_HASHMODE_WITHVLAN
);
1144 /* If we want promiscuous mode, set the allframes bit. */
1145 if (ifp
->if_flags
& IFF_PROMISC
) {
1146 SF_SETBIT(sc
, SF_RXFILT
, SF_RXFILT_PROMISC
);
1148 SF_CLRBIT(sc
, SF_RXFILT
, SF_RXFILT_PROMISC
);
1151 if (ifp
->if_flags
& IFF_BROADCAST
) {
1152 SF_SETBIT(sc
, SF_RXFILT
, SF_RXFILT_BROAD
);
1154 SF_CLRBIT(sc
, SF_RXFILT
, SF_RXFILT_BROAD
);
1158 * Load the multicast filter.
1162 /* Init the completion queue indexes */
1163 csr_write_4(sc
, SF_CQ_CONSIDX
, 0);
1164 csr_write_4(sc
, SF_CQ_PRODIDX
, 0);
1166 /* Init the RX completion queue */
1167 csr_write_4(sc
, SF_RXCQ_CTL_1
,
1168 vtophys(sc
->sf_ldata
->sf_rx_clist
) & SF_RXCQ_ADDR
);
1169 SF_SETBIT(sc
, SF_RXCQ_CTL_1
, SF_RXCQTYPE_3
);
1171 /* Init RX DMA control. */
1172 SF_SETBIT(sc
, SF_RXDMA_CTL
, SF_RXDMA_REPORTBADPKTS
);
1174 /* Init the RX buffer descriptor queue. */
1175 csr_write_4(sc
, SF_RXDQ_ADDR_Q1
,
1176 vtophys(sc
->sf_ldata
->sf_rx_dlist_big
));
1177 csr_write_4(sc
, SF_RXDQ_CTL_1
, (MCLBYTES
<< 16) | SF_DESCSPACE_16BYTES
);
1178 csr_write_4(sc
, SF_RXDQ_PTR_Q1
, SF_RX_DLIST_CNT
- 1);
1180 /* Init the TX completion queue */
1181 csr_write_4(sc
, SF_TXCQ_CTL
,
1182 vtophys(sc
->sf_ldata
->sf_tx_clist
) & SF_RXCQ_ADDR
);
1184 /* Init the TX buffer descriptor queue. */
1185 csr_write_4(sc
, SF_TXDQ_ADDR_HIPRIO
,
1186 vtophys(sc
->sf_ldata
->sf_tx_dlist
));
1187 SF_SETBIT(sc
, SF_TX_FRAMCTL
, SF_TXFRMCTL_CPLAFTERTX
);
1188 csr_write_4(sc
, SF_TXDQ_CTL
,
1189 SF_TXBUFDESC_TYPE0
|SF_TXMINSPACE_128BYTES
|SF_TXSKIPLEN_8BYTES
);
1190 SF_SETBIT(sc
, SF_TXDQ_CTL
, SF_TXDQCTL_NODMACMP
);
1192 /* Enable autopadding of short TX frames. */
1193 SF_SETBIT(sc
, SF_MACCFG_1
, SF_MACCFG1_AUTOPAD
);
1195 /* Enable interrupts. */
1196 csr_write_4(sc
, SF_IMR
, SF_INTRS
);
1197 SF_SETBIT(sc
, SF_PCI_DEVCFG
, SF_PCIDEVCFG_INTR_ENB
);
1199 /* Enable the RX and TX engines. */
1200 SF_SETBIT(sc
, SF_GEN_ETH_CTL
, SF_ETHCTL_RX_ENB
|SF_ETHCTL_RXDMA_ENB
);
1201 SF_SETBIT(sc
, SF_GEN_ETH_CTL
, SF_ETHCTL_TX_ENB
|SF_ETHCTL_TXDMA_ENB
);
1203 /*mii_mediachg(mii);*/
1204 sf_ifmedia_upd(ifp
);
1206 ifp
->if_flags
|= IFF_RUNNING
;
1207 ifp
->if_flags
&= ~IFF_OACTIVE
;
1209 callout_reset(&sc
->sf_stat_timer
, hz
, sf_stats_update
, sc
);
1213 sf_encap(struct sf_softc
*sc
, struct sf_tx_bufdesc_type0
*c
,
1214 struct mbuf
*m_head
)
1217 struct sf_frag
*f
= NULL
;
1222 for (m
= m_head
, frag
= 0; m
!= NULL
; m
= m
->m_next
) {
1223 if (m
->m_len
!= 0) {
1224 if (frag
== SF_MAXFRAGS
)
1226 f
= &c
->sf_frags
[frag
];
1228 f
->sf_pktlen
= m_head
->m_pkthdr
.len
;
1229 f
->sf_fraglen
= m
->m_len
;
1230 f
->sf_addr
= vtophys(mtod(m
, vm_offset_t
));
1236 struct mbuf
*m_new
= NULL
;
1238 MGETHDR(m_new
, MB_DONTWAIT
, MT_DATA
);
1239 if (m_new
== NULL
) {
1240 kprintf("sf%d: no memory for tx list", sc
->sf_unit
);
1244 if (m_head
->m_pkthdr
.len
> MHLEN
) {
1245 MCLGET(m_new
, MB_DONTWAIT
);
1246 if (!(m_new
->m_flags
& M_EXT
)) {
1248 kprintf("sf%d: no memory for tx list",
1253 m_copydata(m_head
, 0, m_head
->m_pkthdr
.len
,
1254 mtod(m_new
, caddr_t
));
1255 m_new
->m_pkthdr
.len
= m_new
->m_len
= m_head
->m_pkthdr
.len
;
1258 f
= &c
->sf_frags
[0];
1259 f
->sf_fraglen
= f
->sf_pktlen
= m_head
->m_pkthdr
.len
;
1260 f
->sf_addr
= vtophys(mtod(m_head
, caddr_t
));
1264 c
->sf_mbuf
= m_head
;
1265 c
->sf_id
= SF_TX_BUFDESC_ID
;
1266 c
->sf_fragcnt
= frag
;
1275 sf_start(struct ifnet
*ifp
)
1277 struct sf_softc
*sc
;
1278 struct sf_tx_bufdesc_type0
*cur_tx
= NULL
;
1279 struct mbuf
*m_head
= NULL
;
1287 if (ifp
->if_flags
& IFF_OACTIVE
)
1290 txprod
= csr_read_4(sc
, SF_TXDQ_PRODIDX
);
1291 i
= SF_IDX_HI(txprod
) >> 4;
1293 if (sc
->sf_ldata
->sf_tx_dlist
[i
].sf_mbuf
!= NULL
) {
1294 kprintf("sf%d: TX ring full, resetting\n", sc
->sf_unit
);
1296 txprod
= csr_read_4(sc
, SF_TXDQ_PRODIDX
);
1297 i
= SF_IDX_HI(txprod
) >> 4;
1300 while(sc
->sf_ldata
->sf_tx_dlist
[i
].sf_mbuf
== NULL
) {
1301 if (sc
->sf_tx_cnt
>= (SF_TX_DLIST_CNT
- 5)) {
1302 ifp
->if_flags
|= IFF_OACTIVE
;
1306 m_head
= ifq_poll(&ifp
->if_snd
);
1310 cur_tx
= &sc
->sf_ldata
->sf_tx_dlist
[i
];
1311 if (sf_encap(sc
, cur_tx
, m_head
)) {
1312 ifp
->if_flags
|= IFF_OACTIVE
;
1316 ifq_dequeue(&ifp
->if_snd
, m_head
);
1317 BPF_MTAP(ifp
, cur_tx
->sf_mbuf
);
1319 SF_INC(i
, SF_TX_DLIST_CNT
);
1322 * Don't get the TX DMA queue get too full.
1324 if (sc
->sf_tx_cnt
> 64)
1332 csr_write_4(sc
, SF_TXDQ_PRODIDX
,
1333 (txprod
& ~SF_TXDQ_PRODIDX_HIPRIO
) |
1334 ((i
<< 20) & 0xFFFF0000));
1342 sf_stop(struct sf_softc
*sc
)
1347 ifp
= &sc
->arpcom
.ac_if
;
1349 callout_stop(&sc
->sf_stat_timer
);
1351 csr_write_4(sc
, SF_GEN_ETH_CTL
, 0);
1352 csr_write_4(sc
, SF_CQ_CONSIDX
, 0);
1353 csr_write_4(sc
, SF_CQ_PRODIDX
, 0);
1354 csr_write_4(sc
, SF_RXDQ_ADDR_Q1
, 0);
1355 csr_write_4(sc
, SF_RXDQ_CTL_1
, 0);
1356 csr_write_4(sc
, SF_RXDQ_PTR_Q1
, 0);
1357 csr_write_4(sc
, SF_TXCQ_CTL
, 0);
1358 csr_write_4(sc
, SF_TXDQ_ADDR_HIPRIO
, 0);
1359 csr_write_4(sc
, SF_TXDQ_CTL
, 0);
1364 for (i
= 0; i
< SF_RX_DLIST_CNT
; i
++) {
1365 if (sc
->sf_ldata
->sf_rx_dlist_big
[i
].sf_mbuf
!= NULL
) {
1366 m_freem(sc
->sf_ldata
->sf_rx_dlist_big
[i
].sf_mbuf
);
1367 sc
->sf_ldata
->sf_rx_dlist_big
[i
].sf_mbuf
= NULL
;
1371 for (i
= 0; i
< SF_TX_DLIST_CNT
; i
++) {
1372 if (sc
->sf_ldata
->sf_tx_dlist
[i
].sf_mbuf
!= NULL
) {
1373 m_freem(sc
->sf_ldata
->sf_tx_dlist
[i
].sf_mbuf
);
1374 sc
->sf_ldata
->sf_tx_dlist
[i
].sf_mbuf
= NULL
;
1378 ifp
->if_flags
&= ~(IFF_RUNNING
|IFF_OACTIVE
);
1384 * Note: it is important that this function not be interrupted. We
1385 * use a two-stage register access scheme: if we are interrupted in
1386 * between setting the indirect address register and reading from the
1387 * indirect data register, the contents of the address register could
1388 * be changed out from under us.
1391 sf_stats_update(void *xsc
)
1393 struct sf_softc
*sc
= xsc
;
1394 struct ifnet
*ifp
= &sc
->arpcom
.ac_if
;
1395 struct mii_data
*mii
= device_get_softc(sc
->sf_miibus
);
1396 struct sf_stats stats
;
1400 lwkt_serialize_enter(ifp
->if_serializer
);
1402 ptr
= (u_int32_t
*)&stats
;
1403 for (i
= 0; i
< sizeof(stats
)/sizeof(u_int32_t
); i
++)
1404 ptr
[i
] = csr_read_4(sc
, SF_STATS_BASE
+
1405 (i
+ sizeof(u_int32_t
)));
1407 for (i
= 0; i
< sizeof(stats
)/sizeof(u_int32_t
); i
++)
1408 csr_write_4(sc
, SF_STATS_BASE
+
1409 (i
+ sizeof(u_int32_t
)), 0);
1411 ifp
->if_collisions
+= stats
.sf_tx_single_colls
+
1412 stats
.sf_tx_multi_colls
+ stats
.sf_tx_excess_colls
;
1417 if (mii
->mii_media_status
& IFM_ACTIVE
&&
1418 IFM_SUBTYPE(mii
->mii_media_active
) != IFM_NONE
)
1420 if (!ifq_is_empty(&ifp
->if_snd
))
1424 callout_reset(&sc
->sf_stat_timer
, hz
, sf_stats_update
, sc
);
1426 lwkt_serialize_exit(ifp
->if_serializer
);
1430 sf_watchdog(struct ifnet
*ifp
)
1432 struct sf_softc
*sc
;
1437 kprintf("sf%d: watchdog timeout\n", sc
->sf_unit
);
1443 if (!ifq_is_empty(&ifp
->if_snd
))
1450 sf_shutdown(device_t dev
)
1452 struct sf_softc
*sc
;
1455 sc
= device_get_softc(dev
);
1456 ifp
= &sc
->arpcom
.ac_if
;
1457 lwkt_serialize_enter(ifp
->if_serializer
);
1459 lwkt_serialize_exit(ifp
->if_serializer
);