Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic From FreeBSD. Lots has changed. I lazily yank t...



details:   https://anonhg.NetBSD.org/src/rev/9d9deb76b6c1
branches:  trunk
changeset: 566218:9d9deb76b6c1
user:      dyoung <dyoung%NetBSD.org@localhost>
date:      Fri Apr 30 23:59:48 2004 +0000

description:
>From FreeBSD.  Lots has changed.  I lazily yank text from the
FreeBSD commit log:

----------------------------
use correct malloc type to allocate struct ieee80211_node's

Noticed by:     phk
----------------------------
do proper subclassing of node free+copy; the previous hack falls apart when
the 802.11 layer does useful work

Obtained from:  madwifi
----------------------------
transmit beacon frames directly instead of defering them to a swi; there
was too much delay

Obtained from:  madwifi
----------------------------
update copyright notice for 2004
----------------------------
check more quickly (and directly) if an interrupt is pending; this reduces
work done in ath_intr when the irq is shared

Obtained from:  madwifi
----------------------------
cleanup descriptor allocation if attach fails

Obtained from:  madwifi
----------------------------
remove use IEEE80211_C_RCVMGT
----------------------------
radiotap updates:

o force little-endian byte order for header
o pad header to 32-bit boundary to guard against applications that assume
  packet data alignment
----------------------------
Don't announce MAC addresses twice.
(ieee80211_ifattach() calls ether_ifattach().)
----------------------------
Make this compile on amd64.

"I'll cope" by:  sam
----------------------------
When draining the tx queue reclaim any node references held in packets.
This fixes a problem when operating as an AP where clients would get
stuck in the node table because the reference count never went to zero.
----------------------------
When ath_hal_stoptxdma returns an error dma is still likely stopped
so don't just stop trying to send a beacon frame or we'll be more likely
to lose sync.  This only seems to happen on some older chips.
----------------------------
use ath_reset instead of ath_init when recovering from a watchdog timeout:
resetting the hardware is sufficient, no need to reset the 802.11 fsm
----------------------------
make hw.ath.debug a tunable
----------------------------
make hw.ath.outdoor and hw.ath.countrycode tunables
----------------------------
split debugging messages up into classes;
ah_debug is now treated as a bit vector
----------------------------
update radiotap support to reflect recent changes:

o move tx taps from ath_start to ath_tx_start so lots more
  state is available to tap
o add tx flags
o add tx rate
o add tx power (constant for the moment)
o add tx antenna state
----------------------------
o eliminate widespread on-stack mbuf use for bpf by introducing
  a new bpf_mtap2 routine that does the right thing for an mbuf
  and a variable-length chunk of data that should be prepended.
o while we're sweeping the drivers, use u_int32_t uniformly when
  when prepending the address family (several places were assuming
  sizeof(int) was 4)
o return M_ASSERTVALID to BPF_MTAP* now that all stack-allocated
  mbufs have been eliminated; this may better be moved to the bpf
  routines

diffstat:

 sys/dev/ic/ath.c |  371 ++++++++++++++++++++++++++++--------------------------
 1 files changed, 192 insertions(+), 179 deletions(-)

diffs (truncated from 911 to 300 lines):

diff -r 8d1b92d147dd -r 9d9deb76b6c1 sys/dev/ic/ath.c
--- a/sys/dev/ic/ath.c  Fri Apr 30 23:58:20 2004 +0000
+++ b/sys/dev/ic/ath.c  Fri Apr 30 23:59:48 2004 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: ath.c,v 1.24 2004/03/27 04:37:59 atatat Exp $  */
+/*     $NetBSD: ath.c,v 1.25 2004/04/30 23:59:48 dyoung Exp $  */
 
 /*-
- * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
+ * Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -38,10 +38,10 @@
 
 #include <sys/cdefs.h>
 #ifdef __FreeBSD__
-__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.36 2003/11/29 01:23:59 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath.c,v 1.54 2004/04/05 04:42:42 sam Exp $");
 #endif
 #ifdef __NetBSD__
-__KERNEL_RCSID(0, "$NetBSD: ath.c,v 1.24 2004/03/27 04:37:59 atatat Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ath.c,v 1.25 2004/04/30 23:59:48 dyoung Exp $");
 #endif
 
 /*
@@ -190,8 +190,10 @@
            0, "chip calibration interval (secs)");
 SYSCTL_INT(_hw_ath, OID_AUTO, outdoor, CTLFLAG_RD, &ath_outdoor,
            0, "enable/disable outdoor operation");
+TUNABLE_INT("hw.ath.outdoor", &ath_outdoor);
 SYSCTL_INT(_hw_ath, OID_AUTO, countrycode, CTLFLAG_RD, &ath_countrycode,
            0, "country code");
+TUNABLE_INT("hw.ath.countrycode", &ath_countrycode);
 SYSCTL_INT(_hw_ath, OID_AUTO, regdomain, CTLFLAG_RD, &ath_regdomain,
            0, "regulatory domain");
 #endif /* __FreeBSD__ */
@@ -213,19 +215,35 @@
 #ifdef __FreeBSD__
 SYSCTL_INT(_hw_ath, OID_AUTO, debug, CTLFLAG_RW, &ath_debug,
            0, "control debugging printfs");
+TUNABLE_INT("hw.ath.debug", &ath_debug);
 #endif /* __FreeBSD__ */
-#define        IFF_DUMPPKTS(_ifp) \
-       (ath_debug || \
+#define        IFF_DUMPPKTS(_ifp, _m) \
+       ((ath_debug & _m) || \
            ((_ifp)->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
 static void ath_printrxbuf(struct ath_buf *bf, int);
 static void ath_printtxbuf(struct ath_buf *bf, int);
-#define        DPRINTF(X)      if (ath_debug) printf X
-#define        DPRINTF2(X)     if (ath_debug > 1) printf X
+enum {
+       ATH_DEBUG_XMIT          = 0x00000001,   /* basic xmit operation */
+       ATH_DEBUG_XMIT_DESC     = 0x00000002,   /* xmit descriptors */
+       ATH_DEBUG_RECV          = 0x00000004,   /* basic recv operation */
+       ATH_DEBUG_RECV_DESC     = 0x00000008,   /* recv descriptors */
+       ATH_DEBUG_RATE          = 0x00000010,   /* rate control */
+       ATH_DEBUG_RESET         = 0x00000020,   /* reset processing */
+       ATH_DEBUG_MODE          = 0x00000040,   /* mode init/setup */
+       ATH_DEBUG_BEACON        = 0x00000080,   /* beacon handling */
+       ATH_DEBUG_WATCHDOG      = 0x00000100,   /* watchdog timeout */
+       ATH_DEBUG_INTR          = 0x00001000,   /* ISR */
+       ATH_DEBUG_TX_PROC       = 0x00002000,   /* tx ISR proc */
+       ATH_DEBUG_RX_PROC       = 0x00004000,   /* rx ISR proc */
+       ATH_DEBUG_BEACON_PROC   = 0x00008000,   /* beacon ISR proc */
+       ATH_DEBUG_CALIBRATE     = 0x00010000,   /* periodic calibration */
+       ATH_DEBUG_ANY           = 0xffffffff
+};
+#define        DPRINTF(_m,X)   if (ath_debug & (_m)) printf X
 #else
-#define        IFF_DUMPPKTS(_ifp) \
+#define        IFF_DUMPPKTS(_ifp, _m) \
        (((_ifp)->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2))
-#define        DPRINTF(X)
-#define        DPRINTF2(X)
+#define        DPRINTF(_m, X)
 #endif
 
 #ifdef __NetBSD__
@@ -285,8 +303,8 @@
        if (error || newp == NULL)
                return (error);
 
-       DPRINTF2(("%s: t = %d, nodenum = %d, rnodenum = %d\n", __func__, t,
-           node.sysctl_num, rnode->sysctl_num));
+       DPRINTF(ATH_DEBUG_ANY, ("%s: t = %d, nodenum = %d, rnodenum = %d\n",
+           __func__, t, node.sysctl_num, rnode->sysctl_num));
 
        if (node.sysctl_num == ath_dwelltime_nodenum) {
                if (t <= 0)
@@ -407,7 +425,7 @@
        HAL_STATUS status;
        int error = 0;
 
-       DPRINTF(("ath_attach: devid 0x%x\n", devid));
+       DPRINTF(ATH_DEBUG_ANY, ("%s: devid 0x%x\n", __func__, devid));
 
 #ifdef __FreeBSD__
        /* set these up early for if_printf use */
@@ -483,7 +501,6 @@
 
        ATH_TASK_INIT(&sc->sc_txtask, ath_tx_proc, sc);
        ATH_TASK_INIT(&sc->sc_rxtask, ath_rx_proc, sc);
-       ATH_TASK_INIT(&sc->sc_swbatask, ath_beacon_proc, sc);
        ATH_TASK_INIT(&sc->sc_rxorntask, ath_rxorn_proc, sc);
        ATH_TASK_INIT(&sc->sc_fataltask, ath_fatal_proc, sc);
        ATH_TASK_INIT(&sc->sc_bmisstask, ath_bmiss_proc, sc);
@@ -501,7 +518,7 @@
        );
        if (sc->sc_txhalq == (u_int) -1) {
                if_printf(ifp, "unable to setup a data xmit queue!\n");
-               goto bad;
+               goto bad2;
        }
        sc->sc_bhalq = ath_hal_setuptxqueue(ah,
                HAL_TX_QUEUE_BEACON,
@@ -509,7 +526,7 @@
        );
        if (sc->sc_bhalq == (u_int) -1) {
                if_printf(ifp, "unable to setup a beacon xmit queue!\n");
-               goto bad;
+               goto bad2;
        }
 
        ifp->if_softc = sc;
@@ -537,7 +554,7 @@
                | IEEE80211_C_HOSTAP            /* hostap mode */
                | IEEE80211_C_MONITOR           /* monitor mode */
                | IEEE80211_C_SHPREAMBLE        /* short preamble supported */
-               | IEEE80211_C_RCVMGT;           /* recv management frames */
+               ;
 
        /* get mac address from hardware */
        ath_hal_getmac(ah, ic->ic_myaddr);
@@ -549,7 +566,9 @@
        ieee80211_ifattach(ifp);
        /* override default methods */
        ic->ic_node_alloc = ath_node_alloc;
+       sc->sc_node_free = ic->ic_node_free;
        ic->ic_node_free = ath_node_free;
+       sc->sc_node_copy = ic->ic_node_copy;
        ic->ic_node_copy = ath_node_copy;
        ic->ic_node_getrssi = ath_node_getrssi;
        sc->sc_newstate = ic->ic_newstate;
@@ -564,17 +583,20 @@
 #endif
        /*
         * Initialize constant fields.
+        * XXX make header lengths a multiple of 32-bits so subsequent
+        *     headers are properly aligned; this is a kludge to keep
+        *     certain applications happy.
         *
         * NB: the channel is setup each time we transition to the
         *     RUN state to avoid filling it in for each frame.
         */
-       sc->sc_tx_th.wt_ihdr.it_len = sizeof(sc->sc_tx_th);
-       sc->sc_tx_th.wt_ihdr.it_present = ATH_TX_RADIOTAP_PRESENT;
-
-       sc->sc_rx_th.wr_ihdr.it_len = sizeof(sc->sc_rx_th);
-       sc->sc_rx_th.wr_ihdr.it_present = ATH_RX_RADIOTAP_PRESENT;
-
-       if_printf(ifp, "802.11 address: %s\n", ether_sprintf(ic->ic_myaddr));
+       sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(u_int32_t));
+       sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len);
+       sc->sc_tx_th.wt_ihdr.it_present = htole32(ATH_TX_RADIOTAP_PRESENT);
+
+       sc->sc_rx_th_len = roundup(sizeof(sc->sc_rx_th), sizeof(u_int32_t));
+       sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len);
+       sc->sc_rx_th.wr_ihdr.it_present = htole32(ATH_RX_RADIOTAP_PRESENT);
 
 #ifdef __NetBSD__
        sc->sc_flags |= ATH_ATTACHED;
@@ -591,6 +613,8 @@
                        sc->sc_dev.dv_xname);
 #endif
        return 0;
+bad2:
+       ath_desc_free(sc);
 bad:
        if (ah)
                ath_hal_detach(ah);
@@ -604,9 +628,9 @@
        struct ifnet *ifp = &sc->sc_ic.ic_if;
        ath_softc_critsect_decl(s);
 
-       DPRINTF(("ath_detach: if_flags %x\n", ifp->if_flags));
        if ((sc->sc_flags & ATH_ATTACHED) == 0)
                return (0);
+       DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags %x\n", __func__, ifp->if_flags));
 
        ath_softc_critsect_begin(sc, s);
        ath_stop(ifp);
@@ -640,7 +664,7 @@
        struct ath_softc *sc = arg;
        int s;
 
-       DPRINTF(("ath_power(%d)\n", why));
+       DPRINTF(ATH_DEBUG_ANY, ("ath_power(%d)\n", why));
 
        s = splnet();
        switch (why) {
@@ -665,7 +689,7 @@
 {
        struct ifnet *ifp = &sc->sc_ic.ic_if;
 
-       DPRINTF(("ath_suspend: if_flags %x\n", ifp->if_flags));
+       DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags %x\n", __func__, ifp->if_flags));
 
        ath_stop(ifp);
        if (sc->sc_power != NULL)
@@ -677,7 +701,7 @@
 {
        struct ifnet *ifp = &sc->sc_ic.ic_if;
 
-       DPRINTF(("ath_resume: if_flags %x\n", ifp->if_flags));
+       DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags %x\n", __func__, ifp->if_flags));
 
        if (ifp->if_flags & IFF_UP) {
                ath_init(ifp);
@@ -708,7 +732,7 @@
 #else
        struct ifnet *ifp = &sc->sc_ic.ic_if;
 
-       DPRINTF(("ath_shutdown: if_flags %x\n", ifp->if_flags));
+       DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags %x\n", __func__, ifp->if_flags));
 
        ath_stop(ifp);
 #endif
@@ -742,17 +766,20 @@
                 * The hardware is not ready/present, don't touch anything.
                 * Note this can happen early on if the IRQ is shared.
                 */
-               DPRINTF(("ath_intr: invalid; ignored\n"));
+               DPRINTF(ATH_DEBUG_ANY, ("%s: invalid; ignored\n", __func__));
                return 0;
        }
+       if (!ath_hal_intrpend(ah))              /* shared irq, not for us */
+               return 0;
        if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) {
-               DPRINTF(("ath_intr: if_flags 0x%x\n", ifp->if_flags));
+               DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags 0x%x\n",
+                       __func__, ifp->if_flags));
                ath_hal_getisr(ah, &status);    /* clear ISR */
                ath_hal_intrset(ah, 0);         /* disable further intr's */
                return 1; /* XXX */
        }
        ath_hal_getisr(ah, &status);            /* NB: clears ISR too */
-       DPRINTF2(("ath_intr: status 0x%x\n", status));
+       DPRINTF(ATH_DEBUG_INTR, ("%s: status 0x%x\n", __func__, status));
 #ifdef AR_DEBUG
        if (ath_debug &&
            (status & (HAL_INT_FATAL|HAL_INT_RXORN|HAL_INT_BMISS))) {
@@ -788,8 +815,14 @@
                        ATH_TASK_RUN_OR_ENQUEUE(&sc->sc_rxtask);
                if (status & HAL_INT_TX)
                        ATH_TASK_RUN_OR_ENQUEUE(&sc->sc_txtask);
-               if (status & HAL_INT_SWBA)
-                       ATH_TASK_RUN_OR_ENQUEUE(&sc->sc_swbatask);
+               if (status & HAL_INT_SWBA) {
+                       /*
+                        * Handle beacon transmission directly; deferring
+                        * this is too slow to meet timing constraints
+                        * under load.
+                        */
+                       ath_beacon_proc(sc, 0);
+               }
                if (status & HAL_INT_BMISS) {
                        sc->sc_stats.ast_bmiss++;
                        ATH_TASK_RUN_OR_ENQUEUE(&sc->sc_bmisstask);
@@ -822,7 +855,7 @@
        struct ath_softc *sc = arg;
        struct ieee80211com *ic = &sc->sc_ic;
 
-       DPRINTF(("ath_bmiss_proc: pending %u\n", pending));
+       DPRINTF(ATH_DEBUG_ANY, ("%s: pending %u\n", __func__, pending));
        if (ic->ic_opmode != IEEE80211_M_STA)
                return;
        if (ic->ic_state == IEEE80211_S_RUN) {
@@ -885,7 +918,8 @@
        int error = 0;
        ath_softc_critsect_decl(s);
 
-       DPRINTF(("ath_init: if_flags 0x%x\n", ifp->if_flags));
+       DPRINTF(ATH_DEBUG_ANY, ("%s: if_flags 0x%x\n",
+               __func__, ifp->if_flags));
 
 #ifdef __NetBSD__
        if ((error = ath_enable(sc)) != 0)
@@ -967,8 +1001,8 @@
        struct ath_hal *ah = sc->sc_ah;
        ath_softc_critsect_decl(s);
 
-       DPRINTF(("ath_stop: invalid %u if_flags 0x%x\n",
-               sc->sc_invalid, ifp->if_flags));
+       DPRINTF(ATH_DEBUG_ANY, ("%s: invalid %u if_flags 0x%x\n",
+               __func__, sc->sc_invalid, ifp->if_flags));
 
        ath_softc_critsect_begin(sc, s);
        if (ifp->if_flags & IFF_RUNNING) {



Home | Main Index | Thread Index | Old Index