ath - Basic report - Additional DragonFly compatibility work
authorMatthew Dillon <dillon@apollo.backplane.com>
Thu, 2 Jan 2014 06:51:33 +0000 (22:51 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Thu, 2 Jan 2014 07:15:39 +0000 (23:15 -0800)
* Implement a quick and dirty if_start() as our ifp API is somewhat
  different.  FreeBSD has a ath_transmit() (per packet), which we do
  not have (and do not really want).

* The FreeBSD OACTIVE mechanics are completely different from ours.  Rip it
  out and add in DFly mechanics.  DFly uses OACTIVE for queue control.
  (not perfect but...)

* Add some more wlan_serialize_*() calls that I had forgotten.

* Fix a m_getcl() and several other instances where M_* flags were
  being used for mbuf operations (DragonFly renamed those to MB_* flags).

* Fix a m_getm() call in ath_edma_rxbuf_init() to use m_getjcl().

* Fix a bug in my previous TAILQ_FOREACH_SAFE() fix, in
  ath_edma_recv_proc_deferred_queue(), that I introduced,
  and another in ath_txfrag_cleanup().

* Fix the mbuf DMA segment defragmentation code in
  ath_tx_dmasetup().  DragonFly has a neat call that does all the work
  for us.

* Fix an apparent bug in ath_txq_sched() (-> adrian)

* Change ATH_TXBUF and ATH_RXBUF defaults to 256.

* Add missing MODULE directives in ath_dfs (null.c).

* Add AR9300* support from contrib, taken from FreeBSD

13 files changed:
sys/dev/netif/ath/ath/if_ath.c
sys/dev/netif/ath/ath/if_ath_ahb.c
sys/dev/netif/ath/ath/if_ath_misc.h
sys/dev/netif/ath/ath/if_ath_pci.c
sys/dev/netif/ath/ath/if_ath_rx.c
sys/dev/netif/ath/ath/if_ath_rx_edma.c
sys/dev/netif/ath/ath/if_ath_sysctl.c
sys/dev/netif/ath/ath/if_ath_tx.c
sys/dev/netif/ath/ath/if_ath_tx_edma.c
sys/dev/netif/ath/ath/if_athvar.h
sys/dev/netif/ath/ath_dfs/null/dfs_null.c
sys/dev/netif/ath/ath_hal/Makefile
sys/dev/netif/ath/ath_hal/ar5312/ar5312_attach.c

index 94bf072..888a1bb 100644 (file)
@@ -157,12 +157,13 @@ static void       ath_init(void *);
 static void    ath_stop_locked(struct ifnet *);
 static void    ath_stop(struct ifnet *);
 static int     ath_reset_vap(struct ieee80211vap *, u_long);
-#if 0
 static int     ath_transmit(struct ifnet *ifp, struct mbuf *m);
+#if 0
 static void    ath_qflush(struct ifnet *ifp);
 #endif
 static int     ath_media_change(struct ifnet *);
 static void    ath_watchdog(void *);
+static void    ath_start(struct ifnet *, struct ifaltq_subque *);
 static int     ath_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
 static void    ath_fatal_proc(void *, int);
 static void    ath_bmiss_vap(struct ieee80211vap *);
@@ -447,7 +448,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
 
        ATH_TXBUF_LOCK_INIT(sc);
 
-       sc->sc_tq = taskqueue_create("ath_taskq", M_NOWAIT,
+       sc->sc_tq = taskqueue_create("ath_taskq", M_INTWAIT,
                taskqueue_thread_enqueue, &sc->sc_tq);
        taskqueue_start_threads(&sc->sc_tq, 1, TDPRI_KERN_DAEMON, -1,
                "%s taskq", ifp->if_xname);
@@ -597,6 +598,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
        ifp->if_transmit = ath_transmit;
        ifp->if_qflush = ath_qflush;
 #endif
+       ifp->if_start = ath_start;
        ifp->if_ioctl = ath_ioctl;
        ifp->if_init = ath_init;
        ifq_set_maxlen(&ifp->if_snd, IFQ_MAXLEN);
@@ -2527,6 +2529,8 @@ ath_reset(struct ifnet *ifp, ATH_RESET_TYPE reset_type)
                }
        }
 
+#if 0
+       /* remove, DragonFly uses OACTIVE to control if_start calls */
        /*
         * This may have been set during an ath_start() call which
         * set this once it detected a concurrent TX was going on.
@@ -2535,6 +2539,7 @@ ath_reset(struct ifnet *ifp, ATH_RESET_TYPE reset_type)
        IF_LOCK(&ifp->if_snd);
        ifq_clr_oactive(&ifp->if_snd);
        IF_UNLOCK(&ifp->if_snd);
+#endif
 
        /* Handle any frames in the TX queue */
        /*
@@ -2728,14 +2733,18 @@ ath_getbuf(struct ath_softc *sc, ath_buf_type_t btype)
 
                DPRINTF(sc, ATH_DEBUG_XMIT, "%s: stop queue\n", __func__);
                sc->sc_stats.ast_tx_qstop++;
+#if 0
+               /* remove, DragonFly uses OACTIVE to control if_start calls */
                IF_LOCK(&ifp->if_snd);
                ifq_set_oactive(&ifp->if_snd);
                IF_UNLOCK(&ifp->if_snd);
+#endif
        }
        return bf;
 }
 
 #if 0
+
 static void
 ath_qflush(struct ifnet *ifp)
 {
@@ -2743,6 +2752,8 @@ ath_qflush(struct ifnet *ifp)
        /* XXX TODO */
 }
 
+#endif
+
 /*
  * Transmit a single frame.
  *
@@ -2770,9 +2781,14 @@ ath_transmit(struct ifnet *ifp, struct mbuf *m)
                ATH_PCU_UNLOCK(sc);
                IF_LOCK(&ifp->if_snd);
                sc->sc_stats.ast_tx_qstop++;
+#if 0
+               /* remove, DragonFly uses OACTIVE to control if_start calls */
                ifq_set_oactive(&ifp->if_snd);
+#endif
                IF_UNLOCK(&ifp->if_snd);
                ATH_KTR(sc, ATH_KTR_TX, 0, "ath_start_task: OACTIVE, finish");
+               m_freem(m);
+               m = NULL;
                return (ENOBUFS);       /* XXX should be EINVAL or? */
        }
        sc->sc_txstart_cnt++;
@@ -2860,9 +2876,12 @@ ath_transmit(struct ifnet *ifp, struct mbuf *m)
                 * above.
                 */
                sc->sc_stats.ast_tx_nobuf++;
+#if 0
+               /* remove, DragonFly uses OACTIVE to control if_start calls */
                IF_LOCK(&ifp->if_snd);
                ifq_set_oactive(&ifp->if_snd);
                IF_UNLOCK(&ifp->if_snd);
+#endif
                m_freem(m);
                m = NULL;
                retval = ENOBUFS;
@@ -3015,7 +3034,6 @@ finish:
        
        return (retval);
 }
-#endif
 
 static int
 ath_media_change(struct ifnet *ifp)
@@ -4317,9 +4335,12 @@ ath_tx_proc_q0(void *arg, int npending)
                sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah);
        if (TXQACTIVE(txqs, sc->sc_cabq->axq_qnum))
                ath_tx_processq(sc, sc->sc_cabq, 1);
+#if 0
+       /* remove, DragonFly uses OACTIVE to control if_start calls */
        IF_LOCK(&ifp->if_snd);
        ifq_clr_oactive(&ifp->if_snd);
        IF_UNLOCK(&ifp->if_snd);
+#endif
        sc->sc_wd_timer = 0;
 
        if (sc->sc_softled)
@@ -4372,9 +4393,12 @@ ath_tx_proc_q0123(void *arg, int npending)
        if (nacked)
                sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah);
 
+#if 0
+       /* remove, DragonFly uses OACTIVE to control if_start calls */
        IF_LOCK(&ifp->if_snd);
        ifq_clr_oactive(&ifp->if_snd);
        IF_UNLOCK(&ifp->if_snd);
+#endif
        sc->sc_wd_timer = 0;
 
        if (sc->sc_softled)
@@ -4418,10 +4442,13 @@ ath_tx_proc(void *arg, int npending)
        if (nacked)
                sc->sc_lastrx = ath_hal_gettsf64(sc->sc_ah);
 
+#if 0
+       /* remove, DragonFly uses OACTIVE to control if_start calls */
        /* XXX check this inside of IF_LOCK? */
        IF_LOCK(&ifp->if_snd);
        ifq_clr_oactive(&ifp->if_snd);
        IF_UNLOCK(&ifp->if_snd);
+#endif
        sc->sc_wd_timer = 0;
 
        if (sc->sc_softled)
@@ -4445,6 +4472,8 @@ ath_txq_sched_tasklet(void *arg, int npending)
        struct ath_softc *sc = arg;
        int i;
 
+       wlan_serialize_enter();
+
        /* XXX is skipping ok? */
        ATH_PCU_LOCK(sc);
 #if 0
@@ -4452,6 +4481,7 @@ ath_txq_sched_tasklet(void *arg, int npending)
                device_printf(sc->sc_dev,
                    "%s: sc_inreset_cnt > 0; skipping\n", __func__);
                ATH_PCU_UNLOCK(sc);
+               wlan_serialize_exit();
                return;
        }
 #endif
@@ -4469,6 +4499,7 @@ ath_txq_sched_tasklet(void *arg, int npending)
        ATH_PCU_LOCK(sc);
        sc->sc_txproc_cnt--;
        ATH_PCU_UNLOCK(sc);
+       wlan_serialize_exit();
 }
 
 void
@@ -4926,9 +4957,12 @@ ath_legacy_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
                }
        }
 #endif /* ATH_DEBUG */
+#if 0
+       /* remove, DragonFly uses OACTIVE to control if_start calls */
        IF_LOCK(&ifp->if_snd);
        ifq_clr_oactive(&ifp->if_snd);
        IF_UNLOCK(&ifp->if_snd);
+#endif
        sc->sc_wd_timer = 0;
 }
 
@@ -5089,9 +5123,12 @@ finish:
        ath_hal_intrset(ah, sc->sc_imask);
        ATH_PCU_UNLOCK(sc);
 
+#if 0
+       /* remove, DragonFly uses OACTIVE to control if_start calls */
        IF_LOCK(&ifp->if_snd);
        ifq_clr_oactive(&ifp->if_snd);
        IF_UNLOCK(&ifp->if_snd);
+#endif
        ath_txrx_start(sc);
        /* XXX ath_start? */
 
@@ -5371,7 +5408,9 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
        if (vap->iv_state == IEEE80211_S_CSA && nstate == IEEE80211_S_RUN)
                csa_run_transition = 1;
 
+       wlan_serialize_exit();
        callout_drain(&sc->sc_cal_ch);
+       wlan_serialize_enter();
        ath_hal_setledstate(ah, leds[nstate]);  /* set LED */
 
        if (nstate == IEEE80211_S_SCAN) {
@@ -5898,6 +5937,32 @@ ath_watchdog(void *arg)
        wlan_serialize_exit();
 }
 
+/*
+ * (DragonFly network start)
+ */
+static void
+ath_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
+{
+       struct ath_softc *sc = ifp->if_softc;
+       struct mbuf *m;
+
+       wlan_assert_serialized();
+       ASSERT_ALTQ_SQ_DEFAULT(ifp, ifsq);
+
+       if ((ifp->if_flags & IFF_RUNNING) == 0 || sc->sc_invalid) {
+               ifq_purge(&ifp->if_snd);
+               return;
+       }
+       ifq_set_oactive(&ifp->if_snd);
+       for (;;) {
+               m = ifq_dequeue(&ifp->if_snd);
+               if (m == NULL)
+                       break;
+               ath_transmit(ifp, m);
+       }
+       ifq_clr_oactive(&ifp->if_snd);
+}
+
 /*
  * Fetch the rate control statistics for the given node.
  */
index b707ca6..dae489a 100644 (file)
@@ -244,7 +244,9 @@ ath_ahb_attach(device_t dev)
        ATH_TX_IC_LOCK_INIT(sc);
        ATH_TXSTATUS_LOCK_INIT(sc);
 
+       wlan_serialize_enter();
        error = ath_attach(device_id, sc);
+       wlan_serialize_exit();
        if (error == 0)                                 /* success */
                return 0;
 
index 0c99bc7..cc3df2f 100644 (file)
@@ -122,7 +122,6 @@ extern      void ath_tx_update_tim(struct ath_softc *sc,
  * if_ath.c and do the ath_start() call there.  Once that's done,
  * we can kill this.
  */
-extern void ath_start(struct ifnet *ifp);
 extern void ath_start_task(void *arg, int npending);
 
 extern void ath_tx_dump(struct ath_softc *sc, struct ath_txq *txq);
index 322a0b1..54c409e 100644 (file)
@@ -252,7 +252,9 @@ ath_pci_attach(device_t dev)
        ATH_TX_IC_LOCK_INIT(sc);
        ATH_TXSTATUS_LOCK_INIT(sc);
 
+       wlan_serialize_enter();
        error = ath_attach(pci_get_device(dev), sc);
+       wlan_serialize_exit();
        if (error == 0)                                 /* success */
                return 0;
 
index 35ef856..84af07a 100644 (file)
@@ -239,7 +239,7 @@ ath_legacy_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf)
                 * multiple of the cache line size.  Not doing this
                 * causes weird stuff to happen (for the 5210 at least).
                 */
-               m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+               m = m_getcl(MB_WAIT, MT_DATA, M_PKTHDR);
                if (m == NULL) {
                        DPRINTF(sc, ATH_DEBUG_ANY,
                                "%s: no mbuf/cluster\n", __func__);
@@ -1088,6 +1088,7 @@ ath_legacy_rx_tasklet(void *arg, int npending)
 {
        struct ath_softc *sc = arg;
 
+       wlan_serialize_enter();
        ATH_KTR(sc, ATH_KTR_RXPROC, 1, "ath_rx_proc: pending=%d", npending);
        DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending);
        ATH_PCU_LOCK(sc);
@@ -1095,11 +1096,13 @@ ath_legacy_rx_tasklet(void *arg, int npending)
                device_printf(sc->sc_dev,
                    "%s: sc_inreset_cnt > 0; skipping\n", __func__);
                ATH_PCU_UNLOCK(sc);
+               wlan_serialize_exit();
                return;
        }
        ATH_PCU_UNLOCK(sc);
 
        ath_rx_proc(sc, 1);
+       wlan_serialize_exit();
 }
 
 static void
index a35e5c1..cdb9fdf 100644 (file)
@@ -469,6 +469,7 @@ ath_edma_recv_proc_deferred_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype,
        int ngood = 0;
        uint64_t tsf;
        struct ath_buf *bf;
+       struct ath_buf *next;
        struct ath_rx_status *rs;
        int16_t nf;
        ath_bufhead rxlist;
@@ -490,7 +491,7 @@ ath_edma_recv_proc_deferred_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype,
        ATH_RX_UNLOCK(sc);
 
        /* Handle the completed descriptors */
-       TAILQ_FOREACH(bf, &rxlist, bf_list) {
+       TAILQ_FOREACH_MUTABLE(bf, &rxlist, bf_list, next) {
                /*
                 * Skip the RX descriptor status - start at the data offset
                 */
@@ -539,11 +540,13 @@ ath_edma_recv_tasklet(void *arg, int npending)
            __func__,
            npending);
 
+       wlan_serialize_enter();
        ATH_PCU_LOCK(sc);
        if (sc->sc_inreset_cnt > 0) {
                device_printf(sc->sc_dev, "%s: sc_inreset_cnt > 0; skipping\n",
                    __func__);
                ATH_PCU_UNLOCK(sc);
+               wlan_serialize_exit();
                return;
        }
        sc->sc_rxproc_cnt++;
@@ -569,6 +572,7 @@ ath_edma_recv_tasklet(void *arg, int npending)
        ATH_PCU_LOCK(sc);
        sc->sc_rxproc_cnt--;
        ATH_PCU_UNLOCK(sc);
+       wlan_serialize_exit();
 }
 
 /*
@@ -589,7 +593,9 @@ ath_edma_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf)
 
        ATH_RX_LOCK_ASSERT(sc);
 
-       m = m_getm(NULL, sc->sc_edma_bufsize, M_NOWAIT, MT_DATA);
+       m = m_getjcl(MB_DONTWAIT, MT_DATA, M_PKTHDR, sc->sc_edma_bufsize);
+/*     m = m_getcl(MB_WAIT, MT_DATA, M_PKTHDR);*/
+/*     m = m_getm(NULL, sc->sc_edma_bufsize, MB_WAIT, MT_DATA);*/
        if (! m)
                return (ENOBUFS);               /* XXX ?*/
 
index 6443142..32cb267 100644 (file)
@@ -613,7 +613,7 @@ ath_sysctl_forcebstuck(SYSCTL_HANDLER_ARGS)
        if (val == 0)
                goto done;
 
-       taskqueue_enqueue_fast(sc->sc_tq, &sc->sc_bstucktask);
+       taskqueue_enqueue(sc->sc_tq, &sc->sc_bstucktask);
        val = 0;
 done:
        wlan_serialize_exit();
index 777a002..cab5eba 100644 (file)
@@ -239,10 +239,13 @@ ath_txfrag_cleanup(struct ath_softc *sc,
        ath_bufhead *frags, struct ieee80211_node *ni)
 {
        struct ath_buf *bf;
+       struct ath_buf *next;
 
        ATH_TXBUF_LOCK_ASSERT(sc);
 
-       while ((bf = TAILQ_FIRST(frags)) != NULL) {
+       next = TAILQ_FIRST(frags);
+       while ((bf = next) != NULL) {
+               next = TAILQ_NEXT(bf, bf_list);
                /* NB: bf assumed clean */
                TAILQ_REMOVE(frags, bf, bf_list);
                ath_returnbuf_head(sc, bf);
@@ -299,57 +302,25 @@ ath_freetx(struct mbuf *m)
 static int
 ath_tx_dmasetup(struct ath_softc *sc, struct ath_buf *bf, struct mbuf *m0)
 {
-       struct mbuf *m;
        int error;
 
        /*
         * Load the DMA map so any coalescing is done.  This
         * also calculates the number of descriptors we need.
         */
-       error = bus_dmamap_load_mbuf_segment(sc->sc_dmat, bf->bf_dmamap, m0,
-                                    bf->bf_segs, 1, &bf->bf_nseg,
+       error = bus_dmamap_load_mbuf_defrag(sc->sc_dmat, bf->bf_dmamap, &m0,
+                                    bf->bf_segs, ATH_TXDESC, &bf->bf_nseg,
                                     BUS_DMA_NOWAIT);
-       if (error == EFBIG) {
-               /* XXX packet requires too many descriptors */
-               bf->bf_nseg = ATH_MAX_SCATTER + 1;
-       } else if (error != 0) {
+       if (error != 0) {
                sc->sc_stats.ast_tx_busdma++;
                ath_freetx(m0);
                return error;
        }
+
        /*
-        * Discard null packets and check for packets that
-        * require too many TX descriptors.  We try to convert
-        * the latter to a cluster.
+        * Discard null packets.
         */
-       if (bf->bf_nseg > ATH_MAX_SCATTER) {            /* too many desc's, linearize */
-               sc->sc_stats.ast_tx_linear++;
-
-               /* scrap for now */
-#if 0
-               m = m_collapse(m0, M_NOWAIT, ATH_MAX_SCATTER);
-#else
-               m = NULL;
-#endif
-
-               if (m == NULL) {
-                       ath_freetx(m0);
-                       sc->sc_stats.ast_tx_nombuf++;
-                       return ENOMEM;
-               }
-               m0 = m;
-               error = bus_dmamap_load_mbuf_segment(sc->sc_dmat,
-                                            bf->bf_dmamap, m0,
-                                            bf->bf_segs, 1, &bf->bf_nseg,
-                                            BUS_DMA_NOWAIT);
-               if (error != 0) {
-                       sc->sc_stats.ast_tx_busdma++;
-                       ath_freetx(m0);
-                       return error;
-               }
-               KASSERT(bf->bf_nseg <= ATH_MAX_SCATTER,
-                   ("too many segments after defrag; nseg %u", bf->bf_nseg));
-       } else if (bf->bf_nseg == 0) {          /* null packet, discard */
+       if (bf->bf_nseg == 0) {
                sc->sc_stats.ast_tx_nodata++;
                ath_freetx(m0);
                return EIO;
@@ -5501,6 +5472,8 @@ ath_txq_sched(struct ath_softc *sc, struct ath_txq *txq)
                 * a frame; be careful.
                 */
                if (! ath_tx_tid_can_tx_or_sched(sc, tid)) {
+                       if (tid == last)
+                               break;
                        continue;
                }
                if (ath_tx_ampdu_running(sc, tid->an, tid->tid))
index afa0e1c..0f13ae2 100644 (file)
@@ -534,7 +534,9 @@ ath_edma_dma_txteardown(struct ath_softc *sc)
 static void
 ath_edma_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
 {
+#if 0
        struct ifnet *ifp = sc->sc_ifp;
+#endif
        int i;
 
        DPRINTF(sc, ATH_DEBUG_RESET, "%s: called\n", __func__);
@@ -576,9 +578,12 @@ ath_edma_tx_drain(struct ath_softc *sc, ATH_RESET_TYPE reset_type)
 
        /* XXX dump out the frames */
 
+#if 0
+       /* remove, DragonFly uses OACTIVE to control if_start calls */
        IF_LOCK(&ifp->if_snd);
        ifq_clr_oactive(&ifp->if_snd);
        IF_UNLOCK(&ifp->if_snd);
+#endif
        sc->sc_wd_timer = 0;
 }
 
@@ -595,7 +600,9 @@ ath_edma_tx_proc(void *arg, int npending)
        DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: called, npending=%d\n",
            __func__, npending);
 #endif
+       wlan_serialize_enter();
        ath_edma_tx_processq(sc, 1);
+       wlan_serialize_exit();
 }
 
 /*
@@ -831,11 +838,14 @@ ath_edma_tx_processq(struct ath_softc *sc, int dosched)
 
        sc->sc_wd_timer = 0;
 
+#if 0
+       /* remove, DragonFly uses OACTIVE to control if_start calls */
        if (idx > 0) {
                IF_LOCK(&sc->sc_ifp->if_snd);
                ifq_clr_oactive(&sc->sc_ifp->if_snd);
                IF_UNLOCK(&sc->sc_ifp->if_snd);
        }
+#endif
 
        /* Kick software scheduler */
        /*
index e13ff1e..b87f7bb 100644 (file)
  */
 #define        ATH_MGMT_TXBUF          32
 
+/*
+ * Newer chipsets probe far bigger fifos,
+ * a default of 40 RXBUFs is not enough.
+ */
+#ifdef __DragonFly__
+#define        ATH_TXBUF       256
+#define        ATH_RXBUF       256
+#endif
+
 /*
  * 802.11n requires more TX and RX buffers to do AMPDU.
  */
index 64964a7..8c43a2d 100644 (file)
@@ -288,3 +288,41 @@ ath_dfs_get_thresholds(struct ath_softc *sc, HAL_PHYERR_PARAM *param)
        ath_hal_getdfsthresh(sc->sc_ah, param);
        return (1);
 }
+
+/*
+ * Module glue.
+ */
+static int
+null_dfs_modevent(module_t mod, int type, void *unused)
+{
+        int error;
+
+        wlan_serialize_enter();
+
+        switch (type) {
+        case MOD_LOAD:
+                if (bootverbose) {
+                        kprintf("ath_dfs: WTF module\n");
+                }
+                error = 0;
+                break;
+        case MOD_UNLOAD:
+                error = 0;
+                break;
+        default:
+                error = EINVAL;
+                break;
+        }
+        wlan_serialize_exit();
+
+        return error;
+}
+
+static moduledata_t null_dfs_mod = {
+        "ath_dfs",
+        null_dfs_modevent,
+        0
+};
+
+DECLARE_MODULE(ath_dfs, null_dfs_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
+MODULE_VERSION(ath_dfs, 1);
index 86d640b..68bf257 100644 (file)
@@ -8,6 +8,9 @@ KMOD=   ath_hal
 .PATH: ${.CURDIR}/ar5211 ${.CURDIR}/ar5416 ${.CURDIR}/ar5312
 .PATH: ${.CURDIR}/ar5212 ${.CURDIR}/ar9003 ${.CURDIR}/ar9002
 .PATH: ${.CURDIR}/ar9001 ${.CURDIR}/ar5210
+.PATH: ${.CURDIR}/../../../../contrib/dev/ath/ath_hal/ar9300/
+
+HALCONTRIB= ${.CURDIR}/../../../../contrib/dev/ath/ath_hal
 
 SRCS=  ah_eeprom_9287.c ah_eeprom_v4k.c ah_regdomain.c
 SRCS+= ah_eeprom_v1.c ah_eeprom_v3.c ah_osdep.c ah.c ah_eeprom_v14.c
@@ -64,6 +67,15 @@ SRCS+=       ar5210_misc.c ar5210_xmit.c ar5210_power.c ar5210_keycache.c
 SRCS+= ar5210_beacon.c ar5210_reset.c ar5210_interrupts.c ar5210_attach.c
 SRCS+= ar5210_recv.c ar5210_phy.c
 
-CFLAGS+=  -I. -I${HAL}
+# AR9300
+#
+SRCS+= ar9300_ani.c ar9300_attach.c ar9300_beacon.c ar9300_eeprom.c
+SRCS+= ar9300_freebsd.c ar9300_gpio.c ar9300_interrupts.c ar9300_keycache.c
+SRCS+= ar9300_mci.c ar9300_misc.c ar9300_paprd.c ar9300_phy.c ar9300_power.c
+SRCS+= ar9300_radar.c ar9300_radio.c ar9300_recv.c ar9300_recv_ds.c
+SRCS+= ar9300_reset.c ar9300_stub.c ar9300_stub_funcs.c ar9300_timer.c
+SRCS+= ar9300_xmit.c ar9300_xmit_ds.c
+
+CFLAGS+=  -I. -I${HAL} -I${HALCONTRIB}
 
 .include <bsd.kmod.mk>
index 24b05e0..20551f0 100644 (file)
@@ -30,6 +30,8 @@
 #define AH_5212_COMMON
 #include "ar5212/ar5212.ini"
 
+#ifdef AH_SUPPORT_AR5312
+
 static  HAL_BOOL ar5312GetMacAddr(struct ath_hal *ah);
 
 static void
@@ -333,3 +335,5 @@ ar5312Probe(uint16_t vendorid, uint16_t devid)
        return AH_NULL;
 }
 AH_CHIP(AR5312, ar5312Probe, ar5312Attach);
+
+#endif