svn commit: r227328 - head/sys/dev/ath
Adrian Chadd
adrian at FreeBSD.org
Tue Nov 8 02:12:11 UTC 2011
Author: adrian
Date: Tue Nov 8 02:12:11 2011
New Revision: 227328
URL: http://svn.freebsd.org/changeset/base/227328
Log:
Begin merging in some of my 802.11n TX aggregation driver changes.
* Add a PCU lock, which isn't currently used but will eventually be
used to serialise some of the driver access.
* Add in all the software TX aggregation state, that's kept per-node
and per-TID.
* Add in the software and aggregation state to ath_buf.
* Add in hooks to ath_softc for aggregation state and the (upcoming)
aggregation TX state calls.
* Add / fix the HAL access macros.
Obtained from: Linux, ath9k
Sponsored by: Hobnob, Inc.
Modified:
head/sys/dev/ath/if_ath.c
head/sys/dev/ath/if_ath_ahb.c
head/sys/dev/ath/if_ath_pci.c
head/sys/dev/ath/if_ath_sysctl.c
head/sys/dev/ath/if_athvar.h
Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c Tue Nov 8 01:35:44 2011 (r227327)
+++ head/sys/dev/ath/if_ath.c Tue Nov 8 02:12:11 2011 (r227328)
@@ -3162,6 +3162,11 @@ ath_node_alloc(struct ieee80211vap *vap,
}
ath_rate_node_init(sc, an);
+ /* Setup the mutex - there's no associd yet so set the name to NULL */
+ snprintf(an->an_name, sizeof(an->an_name), "%s: node %p",
+ device_get_nameunit(sc->sc_dev), an);
+ mtx_init(&an->an_mtx, an->an_name, NULL, MTX_DEF);
+
DPRINTF(sc, ATH_DEBUG_NODE, "%s: an %p\n", __func__, an);
return &an->an_node;
}
@@ -3173,7 +3178,7 @@ ath_node_free(struct ieee80211_node *ni)
struct ath_softc *sc = ic->ic_ifp->if_softc;
DPRINTF(sc, ATH_DEBUG_NODE, "%s: ni %p\n", __func__, ni);
-
+ mtx_destroy(&ATH_NODE(ni)->an_mtx);
ath_rate_node_cleanup(sc, ATH_NODE(ni));
sc->sc_node_free(ni);
}
Modified: head/sys/dev/ath/if_ath_ahb.c
==============================================================================
--- head/sys/dev/ath/if_ath_ahb.c Tue Nov 8 01:35:44 2011 (r227327)
+++ head/sys/dev/ath/if_ath_ahb.c Tue Nov 8 02:12:11 2011 (r227328)
@@ -190,11 +190,13 @@ ath_ahb_attach(device_t dev)
}
ATH_LOCK_INIT(sc);
+ ATH_PCU_LOCK_INIT(sc);
error = ath_attach(AR9130_DEVID, sc);
if (error == 0) /* success */
return 0;
+ ATH_PCU_LOCK_DESTROY(sc);
ATH_LOCK_DESTROY(sc);
bus_dma_tag_destroy(sc->sc_dmat);
bad3:
@@ -234,6 +236,7 @@ ath_ahb_detach(device_t dev)
if (sc->sc_eepromdata)
free(sc->sc_eepromdata, M_TEMP);
+ ATH_PCU_LOCK_DESTROY(sc);
ATH_LOCK_DESTROY(sc);
return (0);
Modified: head/sys/dev/ath/if_ath_pci.c
==============================================================================
--- head/sys/dev/ath/if_ath_pci.c Tue Nov 8 01:35:44 2011 (r227327)
+++ head/sys/dev/ath/if_ath_pci.c Tue Nov 8 02:12:11 2011 (r227328)
@@ -190,11 +190,13 @@ ath_pci_attach(device_t dev)
}
ATH_LOCK_INIT(sc);
+ ATH_PCU_LOCK_INIT(sc);
error = ath_attach(pci_get_device(dev), sc);
if (error == 0) /* success */
return 0;
+ ATH_PCU_LOCK_DESTROY(sc);
ATH_LOCK_DESTROY(sc);
bus_dma_tag_destroy(sc->sc_dmat);
bad3:
@@ -230,6 +232,7 @@ ath_pci_detach(device_t dev)
bus_dma_tag_destroy(sc->sc_dmat);
bus_release_resource(dev, SYS_RES_MEMORY, BS_BAR, psc->sc_sr);
+ ATH_PCU_LOCK_DESTROY(sc);
ATH_LOCK_DESTROY(sc);
return (0);
Modified: head/sys/dev/ath/if_ath_sysctl.c
==============================================================================
--- head/sys/dev/ath/if_ath_sysctl.c Tue Nov 8 01:35:44 2011 (r227327)
+++ head/sys/dev/ath/if_ath_sysctl.c Tue Nov 8 02:12:11 2011 (r227328)
@@ -299,6 +299,68 @@ ath_sysctl_rfkill(SYSCTL_HANDLER_ARGS)
}
static int
+ath_sysctl_txagg(SYSCTL_HANDLER_ARGS)
+{
+ struct ath_softc *sc = arg1;
+ int i, t, param = 0;
+ int error;
+ struct ath_buf *bf;
+
+ error = sysctl_handle_int(oidp, ¶m, 0, req);
+ if (error || !req->newptr)
+ return error;
+
+ if (param != 1)
+ return 0;
+
+ printf("no tx bufs (empty list): %d\n", sc->sc_stats.ast_tx_getnobuf);
+ printf("no tx bufs (was busy): %d\n", sc->sc_stats.ast_tx_getbusybuf);
+
+ printf("aggr single packet: %d\n",
+ sc->sc_aggr_stats.aggr_single_pkt);
+ printf("aggr single packet w/ BAW closed: %d\n",
+ sc->sc_aggr_stats.aggr_baw_closed_single_pkt);
+ printf("aggr non-baw packet: %d\n",
+ sc->sc_aggr_stats.aggr_nonbaw_pkt);
+ printf("aggr aggregate packet: %d\n",
+ sc->sc_aggr_stats.aggr_aggr_pkt);
+ printf("aggr single packet low hwq: %d\n",
+ sc->sc_aggr_stats.aggr_low_hwq_single_pkt);
+ printf("aggr sched, no work: %d\n",
+ sc->sc_aggr_stats.aggr_sched_nopkt);
+ for (i = 0; i < 64; i++) {
+ printf("%2d: %10d ", i, sc->sc_aggr_stats.aggr_pkts[i]);
+ if (i % 4 == 3)
+ printf("\n");
+ }
+ printf("\n");
+
+ for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
+ if (ATH_TXQ_SETUP(sc, i)) {
+ printf("HW TXQ %d: axq_depth=%d, axq_aggr_depth=%d\n",
+ i,
+ sc->sc_txq[i].axq_depth,
+ sc->sc_txq[i].axq_aggr_depth);
+ }
+ }
+
+ i = t = 0;
+ ATH_TXBUF_LOCK(sc);
+ STAILQ_FOREACH(bf, &sc->sc_txbuf, bf_list) {
+ if (bf->bf_flags & ATH_BUF_BUSY) {
+ printf("Busy: %d\n", t);
+ i++;
+ }
+ t++;
+ }
+ ATH_TXBUF_UNLOCK(sc);
+ printf("Total TX buffers: %d; Total TX buffers busy: %d\n",
+ t, i);
+
+ return 0;
+}
+
+static int
ath_sysctl_rfsilent(SYSCTL_HANDLER_ARGS)
{
struct ath_softc *sc = arg1;
@@ -387,6 +449,24 @@ ath_sysctl_setcca(SYSCTL_HANDLER_ARGS)
}
#endif /* IEEE80211_SUPPORT_TDMA */
+static int
+ath_sysctl_forcebstuck(SYSCTL_HANDLER_ARGS)
+{
+ struct ath_softc *sc = arg1;
+ int val = 0;
+ int error;
+
+ error = sysctl_handle_int(oidp, &val, 0, req);
+ if (error || !req->newptr)
+ return error;
+ if (val == 0)
+ return 0;
+
+ taskqueue_enqueue_fast(sc->sc_tq, &sc->sc_bstucktask);
+ val = 0;
+ return 0;
+}
+
void
ath_sysctlattach(struct ath_softc *sc)
{
@@ -465,6 +545,15 @@ ath_sysctlattach(struct ath_softc *sc)
"rfkill", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
ath_sysctl_rfkill, "I", "enable/disable RF kill switch");
}
+
+ SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "txagg", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+ ath_sysctl_txagg, "I", "");
+
+ SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "forcebstuck", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+ ath_sysctl_forcebstuck, "I", "");
+
if (ath_hal_hasintmit(ah)) {
SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"intmit", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
@@ -474,6 +563,17 @@ ath_sysctlattach(struct ath_softc *sc)
SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"monpass", CTLFLAG_RW, &sc->sc_monpass, 0,
"mask of error frames to pass when monitoring");
+
+ SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "hwq_limit", CTLFLAG_RW, &sc->sc_hwq_limit, 0,
+ "");
+ SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "tid_hwq_lo", CTLFLAG_RW, &sc->sc_tid_hwq_lo, 0,
+ "");
+ SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
+ "tid_hwq_hi", CTLFLAG_RW, &sc->sc_tid_hwq_hi, 0,
+ "");
+
#ifdef IEEE80211_SUPPORT_TDMA
if (ath_hal_macversion(ah) > 0x78) {
sc->sc_tdmadbaprep = 2;
@@ -510,6 +610,8 @@ ath_sysctl_clearstats(SYSCTL_HANDLER_ARG
if (val == 0)
return 0; /* Not clearing the stats is still valid */
memset(&sc->sc_stats, 0, sizeof(sc->sc_stats));
+ memset(&sc->sc_aggr_stats, 0, sizeof(sc->sc_aggr_stats));
+
val = 0;
return 0;
}
Modified: head/sys/dev/ath/if_athvar.h
==============================================================================
--- head/sys/dev/ath/if_athvar.h Tue Nov 8 01:35:44 2011 (r227327)
+++ head/sys/dev/ath/if_athvar.h Tue Nov 8 02:12:11 2011 (r227328)
@@ -83,12 +83,73 @@ struct taskqueue;
struct kthread;
struct ath_buf;
+#define ATH_TID_MAX_BUFS (2 * IEEE80211_AGGR_BAWMAX)
+
+/*
+ * Per-TID state
+ *
+ * Note that TID 16 (WME_NUM_TID+1) is for handling non-QoS frames.
+ */
+struct ath_tid {
+ TAILQ_HEAD(,ath_buf) axq_q; /* pending buffers */
+ u_int axq_depth; /* SW queue depth */
+ char axq_name[48]; /* lock name */
+ struct ath_node *an; /* pointer to parent */
+ int tid; /* tid */
+ int ac; /* which AC gets this trafic */
+ int hwq_depth; /* how many buffers are on HW */
+
+ /*
+ * Entry on the ath_txq; when there's traffic
+ * to send
+ */
+ TAILQ_ENTRY(ath_tid) axq_qelem;
+ int sched;
+ int paused; /* >0 if the TID has been paused */
+
+ /*
+ * Is the TID being cleaned up after a transition
+ * from aggregation to non-aggregation?
+ * When this is set to 1, this TID will be paused
+ * and no further traffic will be queued until all
+ * the hardware packets pending for this TID have been
+ * TXed/completed; at which point (non-aggregation)
+ * traffic will resume being TXed.
+ */
+ int cleanup_inprogress;
+ /*
+ * How many hardware-queued packets are
+ * waiting to be cleaned up.
+ * This is only valid if cleanup_inprogress is 1.
+ */
+ int incomp;
+
+ /*
+ * The following implements a ring representing
+ * the frames in the current BAW.
+ * To avoid copying the array content each time
+ * the BAW is moved, the baw_head/baw_tail point
+ * to the current BAW begin/end; when the BAW is
+ * shifted the head/tail of the array are also
+ * appropriately shifted.
+ */
+ /* active tx buffers, beginning at current BAW */
+ struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];
+ /* where the baw head is in the array */
+ int baw_head;
+ /* where the BAW tail is in the array */
+ int baw_tail;
+};
+
/* driver-specific node state */
struct ath_node {
struct ieee80211_node an_node; /* base class */
u_int8_t an_mgmtrix; /* min h/w rate index */
u_int8_t an_mcastrix; /* mcast h/w rate index */
struct ath_buf *an_ff_buf[WME_NUM_AC]; /* ff staging area */
+ struct ath_tid an_tid[IEEE80211_TID_SIZE]; /* per-TID state */
+ char an_name[32]; /* eg "wlan0_a1" */
+ struct mtx an_mtx; /* protecting the ath_node state */
/* variable-length rate control state follows */
};
#define ATH_NODE(ni) ((struct ath_node *)(ni))
@@ -110,6 +171,7 @@ struct ath_node {
struct ath_buf {
STAILQ_ENTRY(ath_buf) bf_list;
+ struct ath_buf * bf_next; /* next buffer in the aggregate */
int bf_nseg;
uint16_t bf_txflags; /* tx descriptor flags */
uint16_t bf_flags; /* status flags (below) */
@@ -119,9 +181,63 @@ struct ath_buf {
bus_dmamap_t bf_dmamap; /* DMA map for mbuf chain */
struct mbuf *bf_m; /* mbuf for buf */
struct ieee80211_node *bf_node; /* pointer to the node */
+ struct ath_desc *bf_lastds; /* last descriptor for comp status */
+ struct ath_buf *bf_last; /* last buffer in aggregate, or self for non-aggregate */
bus_size_t bf_mapsize;
#define ATH_MAX_SCATTER ATH_TXDESC /* max(tx,rx,beacon) desc's */
bus_dma_segment_t bf_segs[ATH_MAX_SCATTER];
+
+ /* Completion function to call on TX complete (fail or not) */
+ /*
+ * "fail" here is set to 1 if the queue entries were removed
+ * through a call to ath_tx_draintxq().
+ */
+ void(* bf_comp) (struct ath_softc *sc, struct ath_buf *bf, int fail);
+
+ /* This state is kept to support software retries and aggregation */
+ struct {
+ int bfs_seqno; /* sequence number of this packet */
+ int bfs_retries; /* retry count */
+ uint16_t bfs_tid; /* packet TID (or TID_MAX for no QoS) */
+ uint16_t bfs_pri; /* packet AC priority */
+ struct ath_txq *bfs_txq; /* eventual dest hardware TXQ */
+ uint16_t bfs_pktdur; /* packet duration (at current rate?) */
+ uint16_t bfs_nframes; /* number of frames in aggregate */
+ uint16_t bfs_ndelim; /* number of delims for padding */
+
+ int bfs_aggr:1; /* part of aggregate? */
+ int bfs_aggrburst:1; /* part of aggregate burst? */
+ int bfs_isretried:1; /* retried frame? */
+ int bfs_dobaw:1; /* actually check against BAW? */
+ int bfs_addedbaw:1; /* has been added to the BAW */
+ int bfs_shpream:1; /* use short preamble */
+ int bfs_istxfrag:1; /* is fragmented */
+ int bfs_ismrr:1; /* do multi-rate TX retry */
+ int bfs_doprot:1; /* do RTS/CTS based protection */
+ int bfs_doratelookup:1; /* do rate lookup before each TX */
+ int bfs_nfl; /* next fragment length */
+
+ /*
+ * These fields are passed into the
+ * descriptor setup functions.
+ */
+ HAL_PKT_TYPE bfs_atype; /* packet type */
+ int bfs_pktlen; /* length of this packet */
+ int bfs_hdrlen; /* length of this packet header */
+ uint16_t bfs_al; /* length of aggregate */
+ int bfs_flags; /* HAL descriptor flags */
+ int bfs_txrate0; /* first TX rate */
+ int bfs_try0; /* first try count */
+ uint8_t bfs_ctsrate0; /* Non-zero - use this as ctsrate */
+ int bfs_keyix; /* crypto key index */
+ int bfs_txpower; /* tx power */
+ int bfs_txantenna; /* TX antenna config */
+ enum ieee80211_protmode bfs_protmode;
+ HAL_11N_RATE_SERIES bfs_rc11n[ATH_RC_NUM]; /* 11n TX series */
+ int bfs_ctsrate; /* CTS rate */
+ int bfs_ctsduration; /* CTS duration (pre-11n NICs) */
+ struct ath_rc_series bfs_rc[ATH_RC_NUM]; /* non-11n TX series */
+ } bf_state;
};
typedef STAILQ_HEAD(, ath_buf) ath_bufhead;
@@ -151,19 +267,27 @@ struct ath_descdma {
* hardware queue).
*/
struct ath_txq {
+ struct ath_softc *axq_softc; /* Needed for scheduling */
u_int axq_qnum; /* hardware q number */
#define ATH_TXQ_SWQ (HAL_NUM_TX_QUEUES+1) /* qnum for s/w only queue */
u_int axq_ac; /* WME AC */
u_int axq_flags;
#define ATH_TXQ_PUTPENDING 0x0001 /* ath_hal_puttxbuf pending */
u_int axq_depth; /* queue depth (stat only) */
+ u_int axq_aggr_depth; /* how many aggregates are queued */
u_int axq_intrcnt; /* interrupt count */
u_int32_t *axq_link; /* link ptr in last TX desc */
STAILQ_HEAD(, ath_buf) axq_q; /* transmit queue */
struct mtx axq_lock; /* lock on q and link */
char axq_name[12]; /* e.g. "ath0_txq4" */
+ /* Per-TID traffic queue for software -> hardware TX */
+ TAILQ_HEAD(axq_t_s,ath_tid) axq_tidq;
};
+#define ATH_NODE_LOCK(_an) mtx_lock(&(_an)->an_mtx)
+#define ATH_NODE_UNLOCK(_an) mtx_unlock(&(_an)->an_mtx)
+#define ATH_NODE_LOCK_ASSERT(_an) mtx_assert(&(_an)->an_mtx, MA_OWNED)
+
#define ATH_TXQ_LOCK_INIT(_sc, _tq) do { \
snprintf((_tq)->axq_name, sizeof((_tq)->axq_name), "%s_txq%u", \
device_get_nameunit((_sc)->sc_dev), (_tq)->axq_qnum); \
@@ -173,6 +297,7 @@ struct ath_txq {
#define ATH_TXQ_LOCK(_tq) mtx_lock(&(_tq)->axq_lock)
#define ATH_TXQ_UNLOCK(_tq) mtx_unlock(&(_tq)->axq_lock)
#define ATH_TXQ_LOCK_ASSERT(_tq) mtx_assert(&(_tq)->axq_lock, MA_OWNED)
+#define ATH_TXQ_IS_LOCKED(_tq) mtx_owned(&(_tq)->axq_lock)
#define ATH_TXQ_INSERT_TAIL(_tq, _elm, _field) do { \
STAILQ_INSERT_TAIL(&(_tq)->axq_q, (_elm), _field); \
@@ -205,9 +330,20 @@ struct ath_vap {
struct taskqueue;
struct ath_tx99;
+/*
+ * Whether to reset the TX/RX queue with or without
+ * a queue flush.
+ */
+typedef enum {
+ ATH_RESET_DEFAULT = 0,
+ ATH_RESET_NOLOSS = 1,
+ ATH_RESET_FULL = 2,
+} ATH_RESET_TYPE;
+
struct ath_softc {
struct ifnet *sc_ifp; /* interface common */
struct ath_stats sc_stats; /* interface statistics */
+ struct ath_tx_aggr_stats sc_aggr_stats;
int sc_debug;
int sc_nvaps; /* # vaps */
int sc_nstavaps; /* # station vaps */
@@ -216,12 +352,15 @@ struct ath_softc {
u_int8_t sc_nbssid0; /* # vap's using base mac */
uint32_t sc_bssidmask; /* bssid mask */
+ void (*sc_node_cleanup)(struct ieee80211_node *);
void (*sc_node_free)(struct ieee80211_node *);
device_t sc_dev;
HAL_BUS_TAG sc_st; /* bus space tag */
HAL_BUS_HANDLE sc_sh; /* bus space handle */
bus_dma_tag_t sc_dmat; /* bus DMA tag */
struct mtx sc_mtx; /* master lock (recursive) */
+ struct mtx sc_pcu_mtx; /* PCU access mutex */
+ char sc_pcu_mtx_name[32];
struct taskqueue *sc_tq; /* private task queue */
struct ath_hal *sc_ah; /* Atheros HAL */
struct ath_ratectrl *sc_rc; /* tx rate control support */
@@ -360,10 +499,38 @@ struct ath_softc {
int sc_txchainmask; /* currently configured TX chainmask */
int sc_rxchainmask; /* currently configured RX chainmask */
+ /*
+ * Aggregation twiddles
+ *
+ * hwq_limit: how busy to keep the hardware queue - don't schedule
+ * further packets to the hardware, regardless of the TID
+ * tid_hwq_lo: how low the per-TID hwq count has to be before the
+ * TID will be scheduled again
+ * tid_hwq_hi: how many frames to queue to the HWQ before the TID
+ * stops being scheduled.
+ */
+ int sc_hwq_limit;
+ int sc_tid_hwq_lo;
+ int sc_tid_hwq_hi;
+
/* DFS related state */
void *sc_dfs; /* Used by an optional DFS module */
int sc_dodfs; /* Whether to enable DFS rx filter bits */
struct task sc_dfstask; /* DFS processing task */
+
+ /* TX AMPDU handling */
+ int (*sc_addba_request)(struct ieee80211_node *,
+ struct ieee80211_tx_ampdu *, int, int, int);
+ int (*sc_addba_response)(struct ieee80211_node *,
+ struct ieee80211_tx_ampdu *, int, int, int);
+ void (*sc_addba_stop)(struct ieee80211_node *,
+ struct ieee80211_tx_ampdu *);
+ void (*sc_addba_response_timeout)
+ (struct ieee80211_node *,
+ struct ieee80211_tx_ampdu *);
+ void (*sc_bar_response)(struct ieee80211_node *ni,
+ struct ieee80211_tx_ampdu *tap,
+ int status);
};
#define ATH_LOCK_INIT(_sc) \
@@ -374,6 +541,37 @@ struct ath_softc {
#define ATH_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define ATH_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
+/*
+ * The PCU lock is non-recursive and should be treated as a spinlock.
+ * Although currently the interrupt code is run in netisr context and
+ * doesn't require this, this may change in the future.
+ * Please keep this in mind when protecting certain code paths
+ * with the PCU lock.
+ *
+ * The PCU lock is used to serialise access to the PCU so things such
+ * as TX, RX, state change (eg channel change), channel reset and updates
+ * from interrupt context (eg kickpcu, txqactive bits) do not clash.
+ *
+ * Although the current single-thread taskqueue mechanism protects the
+ * majority of these situations by simply serialising them, there are
+ * a few others which occur at the same time. These include the TX path
+ * (which only acquires ATH_LOCK when recycling buffers to the free list),
+ * ath_set_channel, the channel scanning API and perhaps quite a bit more.
+ */
+#define ATH_PCU_LOCK_INIT(_sc) do {\
+ snprintf((_sc)->sc_pcu_mtx_name, \
+ sizeof((_sc)->sc_pcu_mtx_name), \
+ "%s PCU lock", \
+ device_get_nameunit((_sc)->sc_dev)); \
+ mtx_init(&(_sc)->sc_pcu_mtx, (_sc)->sc_pcu_mtx_name, \
+ NULL, MTX_DEF); \
+ } while (0)
+#define ATH_PCU_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_pcu_mtx)
+#define ATH_PCU_LOCK(_sc) mtx_lock(&(_sc)->sc_pcu_mtx)
+#define ATH_PCU_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_pcu_mtx)
+#define ATH_PCU_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_pcu_mtx, \
+ MA_OWNED)
+
#define ATH_TXQ_SETUP(sc, i) ((sc)->sc_txqsetup & (1<<i))
#define ATH_TXBUF_LOCK_INIT(_sc) do { \
@@ -686,24 +884,33 @@ void ath_intr(void *);
#define ath_hal_gettxcompletionrates(_ah, _ds, _rates, _tries) \
((*(_ah)->ah_getTxCompletionRates)((_ah), (_ds), (_rates), (_tries)))
-#define ath_hal_chaintxdesc(_ah, _ds, _pktlen, _hdrlen, _type, _keyix, \
- _cipher, _delims, _seglen, _first, _last) \
- ((*(_ah)->ah_chainTxDesc((_ah), (_ds), (_pktlen), (_hdrlen), \
- (_type), (_keyix), (_cipher), (_delims), (_seglen), \
- (_first), (_last))))
#define ath_hal_setupfirsttxdesc(_ah, _ds, _aggrlen, _flags, _txpower, \
_txr0, _txtr0, _antm, _rcr, _rcd) \
((*(_ah)->ah_setupFirstTxDesc)((_ah), (_ds), (_aggrlen), (_flags), \
(_txpower), (_txr0), (_txtr0), (_antm), (_rcr), (_rcd)))
+#define ath_hal_chaintxdesc(_ah, _ds, _pktlen, _hdrlen, _type, _keyix, \
+ _cipher, _delims, _seglen, _first, _last) \
+ ((*(_ah)->ah_chainTxDesc)((_ah), (_ds), (_pktlen), (_hdrlen), \
+ (_type), (_keyix), (_cipher), (_delims), (_seglen), \
+ (_first), (_last)))
#define ath_hal_setuplasttxdesc(_ah, _ds, _ds0) \
((*(_ah)->ah_setupLastTxDesc)((_ah), (_ds), (_ds0)))
+
#define ath_hal_set11nratescenario(_ah, _ds, _dur, _rt, _series, _ns, _flags) \
((*(_ah)->ah_set11nRateScenario)((_ah), (_ds), (_dur), (_rt), \
(_series), (_ns), (_flags)))
+
+#define ath_hal_set11n_aggr_first(_ah, _ds, _len, _num) \
+ ((*(_ah)->ah_set11nAggrFirst)((_ah), (_ds), (_len), (_num)))
#define ath_hal_set11naggrmiddle(_ah, _ds, _num) \
- ((*(_ah)->ah_set11nAggrMiddle((_ah), (_ds), (_num))))
+ ((*(_ah)->ah_set11nAggrMiddle)((_ah), (_ds), (_num)))
+#define ath_hal_set11n_aggr_last(_ah, _ds) \
+ ((*(_ah)->ah_set11nAggrLast)((_ah), (_ds)))
+
#define ath_hal_set11nburstduration(_ah, _ds, _dur) \
((*(_ah)->ah_set11nBurstDuration)((_ah), (_ds), (_dur)))
+#define ath_hal_clr11n_aggr(_ah, _ds) \
+ ((*(_ah)->ah_clr11nAggr)((_ah), (_ds)))
/*
* This is badly-named; you need to set the correct parameters
More information about the svn-src-all
mailing list