diff --git a/sys/dev/iwx/if_iwx.c b/sys/dev/iwx/if_iwx.c --- a/sys/dev/iwx/if_iwx.c +++ b/sys/dev/iwx/if_iwx.c @@ -3429,6 +3429,14 @@ sc->sc_rx_ba_sessions--; } +/** + * @brief Allocate an AMPDU / aggregation session for the given node and TID. + * + * This allocates a TX queue specifically for that TID. + * + * Note that this routine currently doesn't return any status/errors, + * so the caller can't know if the aggregation session was setup or not. + */ static void iwx_sta_tx_agg_start(struct iwx_softc *sc, struct ieee80211_node *ni, uint8_t tid) @@ -3502,6 +3510,14 @@ IWX_UNLOCK(sc); } +/** + * @brief Task called to setup a deferred block-ack session. + * + * This sets up any/all pending blockack sessions as defined + * in sc->ba_tx.start_tidmask. + * + * Note: the call to iwx_sta_tx_agg_start() isn't being error checked. + */ static void iwx_ba_tx_task(void *arg, int npending __unused) { @@ -5627,7 +5643,6 @@ u_int hdrlen; uint32_t rate_n_flags; uint16_t num_tbs, flags, offload_assist = 0; - uint8_t type, subtype; int i, totlen, err, pad, qid; #define IWM_MAX_SCATTER 20 bus_dma_segment_t *seg, segs[IWM_MAX_SCATTER]; @@ -5638,38 +5653,32 @@ IWX_ASSERT_LOCKED(sc); wh = mtod(m, struct ieee80211_frame *); - type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; - subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; hdrlen = ieee80211_anyhdrsize(wh); + /* + * Note: we're currently putting all frames into one queue + * except for AMPDU queues. We should be able to choose + * other WME queues but first we need to verify they've been + * correctly setup for data. + */ qid = sc->first_data_qid; /* Put QoS frames on the data queue which maps to their TID. */ if (IEEE80211_QOS_HAS_SEQ(wh) && (sc->sc_flags & IWX_FLAG_AMPDUTX)) { uint16_t qos = ieee80211_gettid(wh); uint8_t tid = qos & IEEE80211_QOS_TID; -#if 0 + struct ieee80211_tx_ampdu *tap = &ni->ni_tx_ampdu[tid]; + + /* - * XXX-THJ: TODO when we enable ba we need to manage the - * mappings + * Only QoS data goes into an A-MPDU queue; + * don't add QoS null, the other data types, etc. */ - struct ieee80211_tx_ba *ba; - ba = &ni->ni_tx_ba[tid]; - - if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && - type == IEEE80211_FC0_TYPE_DATA && - subtype != IEEE80211_FC0_SUBTYPE_NODATA && - subtype != IEEE80211_FC0_SUBTYPE_BAR && - sc->aggqid[tid] != 0 /*&& - ba->ba_state == IEEE80211_BA_AGREED*/) { - qid = sc->aggqid[tid]; -#else - if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && - type == IEEE80211_FC0_TYPE_DATA && - subtype != IEEE80211_FC0_SUBTYPE_NODATA && + if (IEEE80211_AMPDU_RUNNING(tap) && + IEEE80211_IS_QOSDATA(wh) && + !IEEE80211_IS_MULTICAST(wh->i_addr1) && sc->aggqid[tid] != 0) { qid = sc->aggqid[tid]; -#endif } } @@ -10903,6 +10912,24 @@ return; } +/** + * @brief Called by net80211 to request an AMPDU session be established. + * + * This is called by net80211 to see if an AMPDU session can be established. + * Unfortunately it's done via a firmware command, we can't block here, + * net80211 sends an action frame if we return a success code (1) + * so the only thing to do is to tell net80211 we succeeded. + * + * @param ni ieee80211_node to establish AMPDU session for + * @param tap pointer to the per-TID state struct + * @param dialogtoken dialogtoken field from the BA request + * @param baparamset baparamset field from the BA request + * @param batimeout batimeout field from the BA request + * + * @returns 1 if the AMPDU request is successful and net80211 should send + * the action frame response, 0 if error (and net80211 won't send + * the action frame response.) + */ static int iwx_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, int dialogtoken, int baparamset, int batimeout) @@ -10914,7 +10941,14 @@ DPRINTF(("%s: tid=%i\n", __func__, tid)); sc->ba_tx.start_tidmask |= (1 << tid); taskqueue_enqueue(sc->sc_tq, &sc->ba_tx_task); - return 0; + + /* + * For now succeed and hand it back to net80211; later on it + * would be better to defer completing or rejecting it based + * on whether the AMPDU TX queue is created. + */ + return (sc->sc_addba_request(ni, tap, dialogtoken, baparamset, + batimeout)); }