Page MenuHomeFreeBSD

D9195.diff
No OneTemporary

D9195.diff

Index: sys/dev/ath/ath_hal/ah.c
===================================================================
--- sys/dev/ath/ath_hal/ah.c
+++ sys/dev/ath/ath_hal/ah.c
@@ -1415,6 +1415,8 @@
/*
* Get CCA setting.
+ *
+ * XXX TODO: this may not actually be the same on all chips! Grr!
*/
int
ath_hal_getcca(struct ath_hal *ah)
Index: sys/dev/ath/if_ath.c
===================================================================
--- sys/dev/ath/if_ath.c
+++ sys/dev/ath/if_ath.c
@@ -911,6 +911,8 @@
| IEEE80211_C_PMGT /* Station side power mgmt */
| IEEE80211_C_SWSLEEP
;
+ ic->ic_flags_ext =
+ IEEE80211_FEXT_SEQNO_OFFLOAD; /* driver does sequence number assignment */
/*
* Query the hal to figure out h/w crypto support.
*/
@@ -1010,6 +1012,28 @@
sc->sc_rx_lnamixer = ath_hal_hasrxlnamixer(ah);
sc->sc_hasdivcomb = ath_hal_hasdivantcomb(ah);
+ /*
+ * Some WB335 cards do not support antenna diversity. Since
+ * we use a hardcoded value for AR9565 instead of using the
+ * EEPROM/OTP data, remove the combining feature from
+ * the HW capabilities bitmap.
+ */
+ /*
+ * XXX TODO: check reference driver and ath9k for what to do
+ * here for WB335. I think we have to actually disable the
+ * LNA div processing in the HAL and instead use the hard
+ * coded values; and then use BT diversity.
+ *
+ * .. but also need to setup MCI too for WB335..
+ */
+#if 0
+ if (sc->sc_pci_devinfo & (ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_AR9565_2ANT)) {
+ device_printf(sc->sc_dev, "%s: WB335: disabling LNA mixer diversity\n",
+ __func__);
+ sc->sc_dolnadiv = 0;
+ }
+#endif
+
if (ath_hal_hasfastframes(ah))
ic->ic_caps |= IEEE80211_C_FF;
wmodes = ath_hal_getwirelessmodes(ah);
@@ -5649,6 +5673,31 @@
*/
IEEE80211_LOCK_ASSERT(ic);
+ /*
+ * XXX TODO: if nstate is _S_CAC, then we should disable
+ * ACK processing until CAC is completed.
+ */
+
+ /*
+ * XXX TODO: if we're on a passive channel, then we should
+ * not allow any ACKs or self-generated frames until we hear
+ * a beacon. Unfortunately there isn't a notification from
+ * net80211 so perhaps we could slot that particular check
+ * into the mgmt receive path and just ensure that we clear
+ * it on RX of beacons in passive mode (and only clear it
+ * once, obviously.)
+ */
+
+ /*
+ * XXX TODO: net80211 should be tracking whether channels
+ * have heard beacons and are thus considered "OK" for
+ * transmitting - and then inform the driver about this
+ * state change. That way if we hear an AP go quiet
+ * (and nothing else is beaconing on a channel) the
+ * channel can go back to being passive until another
+ * beacon is heard.
+ */
+
if (nstate == IEEE80211_S_RUN) {
/* NB: collect bss node again, it may have changed */
ieee80211_free_node(ni);
@@ -5670,6 +5719,14 @@
case IEEE80211_M_HOSTAP:
case IEEE80211_M_IBSS:
case IEEE80211_M_MBSS:
+
+ /*
+ * TODO: Enable ACK processing (ie, clear AR_DIAG_ACK_DIS.)
+ * For channels that are in CAC, we may have disabled
+ * this during CAC to ensure we don't ACK frames
+ * sent to us.
+ */
+
/*
* Allocate and setup the beacon frame.
*
@@ -6274,6 +6331,15 @@
*/
if (ath_dfs_process_radar_event(sc, sc->sc_curchan)) {
/* DFS event found, initiate channel change */
+
+ /*
+ * XXX TODO: immediately disable ACK processing
+ * on the current channel. This would be done
+ * by setting AR_DIAG_ACK_DIS (AR5212; may be
+ * different for others) until we are out of
+ * CAC.
+ */
+
/*
* XXX doesn't currently tell us whether the event
* XXX was found in the primary or extension
Index: sys/dev/ath/if_ath_beacon.c
===================================================================
--- sys/dev/ath/if_ath_beacon.c
+++ sys/dev/ath/if_ath_beacon.c
@@ -758,6 +758,12 @@
}
}
ath_beacon_setup(sc, bf);
+
+ /*
+ * Assign sequence number to the beacon frame from the NON-QOS TID.
+ */
+ ieee80211_tx_seqno_assign(bf->bf_node, bf->bf_m);
+
bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_PREWRITE);
/*
Index: sys/dev/ath/if_ath_tx.c
===================================================================
--- sys/dev/ath/if_ath_tx.c
+++ sys/dev/ath/if_ath_tx.c
@@ -2016,6 +2016,9 @@
subtype != IEEE80211_FC0_SUBTYPE_QOS_NULL) {
bf->bf_state.bfs_dobaw = 1;
}
+ } else {
+ /* XXX else - do seqno assignment for non-aggregate frames */
+ ieee80211_tx_seqno_assign(ni, m0);
}
/*
@@ -2030,7 +2033,7 @@
"%s: tid %d: ampdu pending, seqno %d\n",
__func__, tid, M_SEQNO_GET(m0));
- /* This also sets up the DMA map */
+ /* This also sets up the DMA map; crypto; frame parameters, etc */
r = ath_tx_normal_setup(sc, ni, bf, m0, txq);
if (r != 0)
@@ -2146,6 +2149,9 @@
/* XXX If it's an ADDBA, override the correct queue */
do_override = ath_tx_action_frame_override_queue(sc, ni, m0, &o_tid);
+ /* XXX do seqno assignment for frames; we don't do aggregate raw frames yet */
+ ieee80211_tx_seqno_assign(ni, m0);
+
/* Map ADDBA to the correct priority */
if (do_override) {
#if 0
Index: sys/net80211/ieee80211_freebsd.c
===================================================================
--- sys/net80211/ieee80211_freebsd.c
+++ sys/net80211/ieee80211_freebsd.c
@@ -592,7 +592,9 @@
* Assert the IC TX lock is held - this enforces the
* processing -> queuing order is maintained
*/
- IEEE80211_TX_LOCK_ASSERT(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_LOCK_ASSERT(ic);
+
error = ic->ic_transmit(ic, m);
if (error) {
struct ieee80211_node *ni;
@@ -619,7 +621,8 @@
* When transmitting via the VAP, we shouldn't hold
* any IC TX lock as the VAP TX path will acquire it.
*/
- IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(vap->iv_ic))
+ IEEE80211_TX_UNLOCK_ASSERT(vap->iv_ic);
return (ifp->if_transmit(ifp, m));
Index: sys/net80211/ieee80211_ht.c
===================================================================
--- sys/net80211/ieee80211_ht.c
+++ sys/net80211/ieee80211_ht.c
@@ -2430,7 +2430,11 @@
tid = tap->txa_tid;
/*
- * XXX TODO: This is racy with any other parallel TX going on. :(
+ * XXX TODO: This is racy with any other parallel TX going on.
+ *
+ * Ideally net80211/driver would suspend TX on this TID and then wait
+ * for it to complete, and then start ADDBA. That way we are
+ * completely aware of what the txseq should be.
*/
tap->txa_start = ni->ni_txseqs[tid];
@@ -2706,9 +2710,14 @@
* ic_raw_xmit will free the node reference
* regardless of queue/TX success or failure.
*/
- IEEE80211_TX_LOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_LOCK(ic);
+
ret = ieee80211_raw_output(vap, ni, m, NULL);
- IEEE80211_TX_UNLOCK(ic);
+
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_UNLOCK(ic);
+
if (ret != 0) {
IEEE80211_NOTE(vap, IEEE80211_MSG_DEBUG | IEEE80211_MSG_11N,
ni, "send BAR: failed: (ret = %d)\n",
Index: sys/net80211/ieee80211_hwmp.c
===================================================================
--- sys/net80211/ieee80211_hwmp.c
+++ sys/net80211/ieee80211_hwmp.c
@@ -646,7 +646,8 @@
return ENOMEM;
}
- IEEE80211_TX_LOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_LOCK(ic);
ieee80211_send_setup(ni, m,
IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ACTION,
@@ -664,7 +665,8 @@
params.ibp_try0 = ni->ni_txparms->maxretry;
params.ibp_power = ni->ni_txpower;
ret = ieee80211_raw_output(vap, ni, m, &params);
- IEEE80211_TX_UNLOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_UNLOCK(ic);
return (ret);
}
Index: sys/net80211/ieee80211_mesh.c
===================================================================
--- sys/net80211/ieee80211_mesh.c
+++ sys/net80211/ieee80211_mesh.c
@@ -1049,6 +1049,9 @@
* This consumes the node ref grabbed above and
* the mbuf, regardless of whether there's a problem
* or not.
+ *
+ * XXX TODO: this completely re-encapsulates the frame, which
+ * we need to check to see if it's the right thing to do.
*/
(void) ieee80211_vap_pkt_send_dest(vap, m, ni);
}
@@ -1234,10 +1237,18 @@
*
* Doing a direct parent transmit may not be the correct thing
* to do here; we'll have to re-think this soon.
+ *
+ * XXX TODO: this also means we don't allocate a new seqno to the
+ * given peer, can't do A-MPDU for 11n, etc. This path should
+ * really stash the mesh state in a mbuf tag or something and
+ * then pass it out the normal path to be encap'ed with the
+ * right header details!
*/
- IEEE80211_TX_LOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_LOCK(ic);
err = ieee80211_parent_xmitpkt(ic, mcopy);
- IEEE80211_TX_UNLOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_UNLOCK(ic);
if (!err)
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
}
Index: sys/net80211/ieee80211_output.c
===================================================================
--- sys/net80211/ieee80211_output.c
+++ sys/net80211/ieee80211_output.c
@@ -254,7 +254,8 @@
* point (where TX state is being checked/modified)
* through to driver queue.
*/
- IEEE80211_TX_LOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_LOCK(ic);
/*
* XXX make the encap and transmit code a separate function
@@ -268,7 +269,8 @@
m = ieee80211_encap(vap, ni, m);
if (m == NULL) {
/* NB: stat+msg handled in ieee80211_encap */
- IEEE80211_TX_UNLOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_UNLOCK(ic);
ieee80211_free_node(ni);
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
return (ENOBUFS);
@@ -280,7 +282,8 @@
* Unlock at this point - no need to hold it across
* ieee80211_free_node() (ie, the comlock)
*/
- IEEE80211_TX_UNLOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_UNLOCK(ic);
ic->ic_lastdata = ticks;
return (0);
@@ -657,7 +660,8 @@
/* NB: ieee80211_encap does not include 802.11 header */
IEEE80211_NODE_STAT_ADD(ni, tx_bytes, m->m_pkthdr.len);
- IEEE80211_TX_LOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_LOCK(ic);
/*
* NB: DLT_IEEE802_11_RADIO identifies the parameters are
@@ -668,7 +672,8 @@
ret = ieee80211_raw_output(vap, ni, m,
(const struct ieee80211_bpf_params *)(dst->sa_len ?
dst->sa_data : NULL));
- IEEE80211_TX_UNLOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_UNLOCK(ic);
return (ret);
bad:
if (m != NULL)
@@ -700,7 +705,8 @@
struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
ieee80211_seq seqno;
- IEEE80211_TX_LOCK_ASSERT(ni->ni_ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ni->ni_ic))
+ IEEE80211_TX_LOCK_ASSERT(ni->ni_ic);
wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | type;
if ((type & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) {
@@ -766,19 +772,14 @@
*(uint16_t *)&wh->i_dur[0] = 0;
/*
- * XXX TODO: this is what the TX lock is for.
- * Here we're incrementing sequence numbers, and they
- * need to be in lock-step with what the driver is doing
- * both in TX ordering and crypto encap (IV increment.)
- *
* If the driver does seqno itself, then we can skip
* assigning sequence numbers here, and we can avoid
* requiring the TX lock.
*/
tap = &ni->ni_tx_ampdu[tid];
- if (tid != IEEE80211_NONQOS_TID && IEEE80211_AMPDU_RUNNING(tap))
+ if (tid != IEEE80211_NONQOS_TID && IEEE80211_AMPDU_RUNNING(tap)) {
m->m_flags |= M_AMPDU_MPDU;
- else {
+ } else if (! IEEE80211_CONF_SEQNO_OFFLOAD(ni->ni_ic)) {
if (IEEE80211_HAS_SEQ(type & IEEE80211_FC0_TYPE_MASK,
type & IEEE80211_FC0_SUBTYPE_MASK))
seqno = ni->ni_txseqs[tid]++;
@@ -830,7 +831,8 @@
return ENOMEM;
}
- IEEE80211_TX_LOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_LOCK(ic);
wh = mtod(m, struct ieee80211_frame *);
ieee80211_send_setup(ni, m,
@@ -859,7 +861,8 @@
IEEE80211_NODE_STAT(ni, tx_mgmt);
ret = ieee80211_raw_output(vap, ni, m, params);
- IEEE80211_TX_UNLOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_UNLOCK(ic);
return (ret);
}
@@ -929,7 +932,8 @@
return ENOMEM;
}
- IEEE80211_TX_LOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_LOCK(ic);
wh = mtod(m, struct ieee80211_frame *); /* NB: a little lie */
if (ni->ni_flags & IEEE80211_NODE_QOS) {
@@ -979,7 +983,8 @@
wh->i_fc[1] & IEEE80211_FC1_PWR_MGT ? "ena" : "dis");
ret = ieee80211_raw_output(vap, ni, m, NULL);
- IEEE80211_TX_UNLOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_UNLOCK(ic);
return (ret);
}
@@ -1245,7 +1250,8 @@
uint8_t *qos;
int is_amsdu = 0;
- IEEE80211_TX_LOCK_ASSERT(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_LOCK_ASSERT(ic);
/*
* Copy existing Ethernet header to a safe place. The
@@ -1558,7 +1564,8 @@
* numbers. If the driver does it, then don't do it here;
* and we don't need the TX lock held.
*/
- if ((m->m_flags & M_AMPDU_MPDU) == 0) {
+ if (((m->m_flags & M_AMPDU_MPDU) == 0) &&
+ (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))) {
/*
* NB: don't assign a sequence # to potential
* aggregates; we expect this happens at the
@@ -1576,7 +1583,7 @@
htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
M_SEQNO_SET(m, seqno);
}
- } else {
+ } else if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic)) {
/*
* XXX TODO TX lock is needed for atomic updates of sequence
* numbers. If the driver does it, then don't do it here;
@@ -2213,7 +2220,8 @@
return ENOMEM;
}
- IEEE80211_TX_LOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_LOCK(ic);
ieee80211_send_setup(ni, m,
IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ,
IEEE80211_NONQOS_TID, sa, da, bssid);
@@ -2244,7 +2252,8 @@
params.ibp_try0 = tp->maxretry;
params.ibp_power = ni->ni_txpower;
ret = ieee80211_raw_output(vap, ni, m, &params);
- IEEE80211_TX_UNLOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_UNLOCK(ic);
ieee80211_free_node(bss);
return (ret);
}
@@ -2864,7 +2873,8 @@
M_PREPEND(m, sizeof(struct ieee80211_frame), M_NOWAIT);
KASSERT(m != NULL, ("no room for header"));
- IEEE80211_TX_LOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_LOCK(ic);
ieee80211_send_setup(bss, m,
IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP,
IEEE80211_NONQOS_TID, vap->iv_myaddr, da, bss->ni_bssid);
@@ -2880,7 +2890,8 @@
IEEE80211_NODE_STAT(bss, tx_mgmt);
ret = ieee80211_raw_output(vap, bss, m, NULL);
- IEEE80211_TX_UNLOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_UNLOCK(ic);
return (ret);
}
@@ -3360,10 +3371,12 @@
* If the driver identifies it does its own TX seqno management then
* we can skip this (and still not do the TX seqno.)
*/
- seqno = ni->ni_txseqs[IEEE80211_NONQOS_TID]++;
- *(uint16_t *)&wh->i_seq[0] =
- htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
- M_SEQNO_SET(m, seqno);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic)) {
+ seqno = ni->ni_txseqs[IEEE80211_NONQOS_TID]++;
+ *(uint16_t *)&wh->i_seq[0] =
+ htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
+ M_SEQNO_SET(m, seqno);
+ }
/* XXX faster to recalculate entirely or just changes? */
capinfo = ieee80211_getcapinfo(vap, ni->ni_chan);
@@ -3682,3 +3695,101 @@
}
m_freem(m);
}
+
+/*
+ * Assign a sequence number to the given frame.
+ *
+ * The frame must have:
+ *
+ * + the frametype / subtype already setup;
+ * + the TID must be in the mbuf already / packet header for QoS
+ * frames so it can be accessed.
+ *
+ * This can either be called by the driver in its own serialisation
+ * path, or in net80211 under the TX serialisation lock.
+ */
+void
+ieee80211_tx_seqno_assign(struct ieee80211_node *ni, struct mbuf *m)
+{
+ struct ieee80211_frame *wh;
+ int tid = IEEE80211_NONQOS_TID;
+ uint16_t seqno;
+ uint8_t type, subtype;
+
+ wh = mtod(m, struct ieee80211_frame *);
+
+ type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+ subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+
+ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_OUTPUT, ni,
+ "%s: called; type=0x%.2x, subtype=0x%.2x", __func__,
+ type, subtype);
+
+ /* Figure out if we need a sequence number or not */
+ if (! IEEE80211_HAS_SEQ(type, subtype)) {
+ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_OUTPUT, ni,
+ "%s: ! HAS_SEQ", __func__);
+ return;
+ }
+
+ /* ctrl - no sequence number */
+ if (IEEE80211_IS_CTL(wh)) {
+ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_OUTPUT, ni,
+ "%s: ! IS_CTL", __func__);
+ return;
+ }
+
+ /* mgmt - NONQOS_TID */
+ if (IEEE80211_IS_MGMT(wh)) {
+ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_OUTPUT, ni,
+ "%s: IS_MGMT; NONQOS-TID", __func__);
+ tid = IEEE80211_NONQOS_TID;
+ }
+
+ /* data - QoS - look at TID in frame; only if it needs it */
+ if (IEEE80211_IS_DATA(wh) &&
+ (subtype & IEEE80211_FC0_SUBTYPE_QOS)) {
+ struct ieee80211_qosframe *qwh;
+
+ qwh = mtod(m, struct ieee80211_qosframe *);
+ tid = qwh->i_qos[0] & IEEE80211_QOS_TID;
+
+ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_OUTPUT, ni,
+ "%s: QOS; TID=%d", __func__, tid);
+ }
+
+ /* data - non-QoS - NONQOS_TID - if it needs it */
+ if (IEEE80211_IS_DATA(wh) &&
+ ((subtype & IEEE80211_FC0_SUBTYPE_QOS) == 0)) {
+ tid = IEEE80211_NONQOS_TID;
+ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_OUTPUT, ni,
+ "%s: DATA; NON-QOS", __func__);
+ }
+
+ /*
+ * data + IEEE80211_FC0_SUBTYPE_QOS_NULL - use NONQOS_TID;
+ * otherwise A-MPDU BAW tracking gets confused.
+ */
+ if (IEEE80211_IS_DATA(wh) &&
+ (subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL)) {
+ tid = IEEE80211_NONQOS_TID;
+ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_OUTPUT, ni,
+ "%s: DATA; QOS-NULL", __func__);
+ }
+
+ /*
+ * Finally - assign the sequence number as appropriate.
+ */
+ wh = mtod(m, struct ieee80211_frame *);
+ IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_OUTPUT, ni,
+ "%s: seqno-assign: type=0x%x,subtype=0x%x, tid=%d, seqno=%d",
+ __func__,
+ type,
+ subtype,
+ tid,
+ ni->ni_txseqs[tid]);
+ seqno = ni->ni_txseqs[tid]++;
+ *(uint16_t *)wh->i_seq =
+ htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
+ M_SEQNO_SET(m, seqno);
+}
Index: sys/net80211/ieee80211_proto.h
===================================================================
--- sys/net80211/ieee80211_proto.h
+++ sys/net80211/ieee80211_proto.h
@@ -121,6 +121,7 @@
const struct ether_header *);
void ieee80211_tx_complete(struct ieee80211_node *,
struct mbuf *, int);
+void ieee80211_tx_seqno_assign(struct ieee80211_node *, struct mbuf *);
/*
* The formation of ProbeResponse frames requires guidance to
Index: sys/net80211/ieee80211_superg.c
===================================================================
--- sys/net80211/ieee80211_superg.c
+++ sys/net80211/ieee80211_superg.c
@@ -580,7 +580,8 @@
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
- IEEE80211_TX_LOCK_ASSERT(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_LOCK_ASSERT(ic);
/* encap and xmit */
m = ieee80211_encap(vap, ni, m);
@@ -653,9 +654,13 @@
M_AGE_SUB(m, quanta);
IEEE80211_FF_UNLOCK(ic);
- IEEE80211_TX_LOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_LOCK(ic);
+
ff_flush(head, m);
- IEEE80211_TX_UNLOCK(ic);
+
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_UNLOCK(ic);
}
static void
@@ -759,7 +764,8 @@
struct mbuf *mstaged;
uint32_t txtime, limit;
- IEEE80211_TX_UNLOCK_ASSERT(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_UNLOCK_ASSERT(ic);
IEEE80211_LOCK(ic);
limit = IEEE80211_TXOP_TO_US(
@@ -824,12 +830,14 @@
IEEE80211_FF_UNLOCK(ic);
if (mstaged != NULL) {
- IEEE80211_TX_LOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_LOCK(ic);
IEEE80211_NOTE(vap, IEEE80211_MSG_SUPERG, ni,
"%s: flush staged frame", __func__);
/* encap and xmit */
ff_transmit(ni, mstaged);
- IEEE80211_TX_UNLOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_UNLOCK(ic);
}
return m; /* NB: original frame */
}
Index: sys/net80211/ieee80211_wds.c
===================================================================
--- sys/net80211/ieee80211_wds.c
+++ sys/net80211/ieee80211_wds.c
@@ -288,11 +288,13 @@
/*
* Encapsulate the packet in prep for transmission.
*/
- IEEE80211_TX_LOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_LOCK(ic);
mcopy = ieee80211_encap(vap, ni, mcopy);
if (mcopy == NULL) {
/* NB: stat+msg handled in ieee80211_encap */
- IEEE80211_TX_UNLOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_UNLOCK(ic);
ieee80211_free_node(ni);
continue;
}
@@ -300,7 +302,8 @@
mcopy->m_pkthdr.rcvif = (void *) ni;
err = ieee80211_parent_xmitpkt(ic, mcopy);
- IEEE80211_TX_UNLOCK(ic);
+ if (! IEEE80211_CONF_SEQNO_OFFLOAD(ic))
+ IEEE80211_TX_UNLOCK(ic);
if (!err) {
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);

File Metadata

Mime Type
text/plain
Expires
Sat, Feb 7, 3:16 AM (15 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28452330
Default Alt Text
D9195.diff (20 KB)

Event Timeline