Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144184742
D9195.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
20 KB
Referenced Files
None
Subscribers
None
D9195.diff
View Options
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, ¶ms);
- 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, ¶ms);
- 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
Details
Attached
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)
Attached To
Mode
D9195: [net80211] initial "driver does sequence number handling" This implements: * optionally deferring sequence number allocation into the driver * don't grab/release the net80211 TX lock if the driver does sequence number allocation * write a...
Attached
Detach File
Event Timeline
Log In to Comment