svn commit: r257133 - head/sys/dev/iwn

Adrian Chadd adrian at FreeBSD.org
Fri Oct 25 19:44:54 UTC 2013


Author: adrian
Date: Fri Oct 25 19:44:53 2013
New Revision: 257133
URL: http://svnweb.freebsd.org/changeset/base/257133

Log:
  Temporarily disable multi-rate retry (link quality) and eliminate rate
  index lookups.
  
  * My recent(ish) change to iwn(4) and the net80211 rate control API to
    support 11n rates broke the link quality table use.  So, until I or
    someone else decides to fix it, let's just disable it for now.
  
  * Teach iwn_tx_data_raw() to use the iwn_rate_to_plcp() function.
  
  * Eliminate two uses of the net80211 rate index lookup functions - they
    are only for legacy rates and they're not needed here.
  
  This fixes some invalid looking rate control TX issues that showed up
  on my 4965 but it doesn't fix the two TX hangs I've noticed. Those look
  like DMA related issues.
  
  Tested:
  
  * 4965, STA mode
  * 5100, STA mode

Modified:
  head/sys/dev/iwn/if_iwn.c

Modified: head/sys/dev/iwn/if_iwn.c
==============================================================================
--- head/sys/dev/iwn/if_iwn.c	Fri Oct 25 19:39:22 2013	(r257132)
+++ head/sys/dev/iwn/if_iwn.c	Fri Oct 25 19:44:53 2013	(r257133)
@@ -3476,6 +3476,53 @@ iwn5000_reset_sched(struct iwn_softc *sc
 }
 #endif
 
+/*
+ * Check whether OFDM 11g protection will be enabled for the given rate.
+ *
+ * The original driver code only enabled protection for OFDM rates.
+ * It didn't check to see whether it was operating in 11a or 11bg mode.
+ */
+static int
+iwn_check_rate_needs_protection(struct iwn_softc *sc,
+    struct ieee80211vap *vap, uint8_t rate)
+{
+	struct ieee80211com *ic = vap->iv_ic;
+
+	/*
+	 * Not in 2GHz mode? Then there's no need to enable OFDM
+	 * 11bg protection.
+	 */
+	if (! IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
+		return (0);
+	}
+
+	/*
+	 * 11bg protection not enabled? Then don't use it.
+	 */
+	if ((ic->ic_flags & IEEE80211_F_USEPROT) == 0)
+		return (0);
+
+	/*
+	 * If it's an 11n rate, then for now we enable
+	 * protection.
+	 */
+	if (rate & IEEE80211_RATE_MCS) {
+		return (1);
+	}
+
+	/*
+	 * Do a rate table lookup.  If the PHY is CCK,
+	 * don't do protection.
+	 */
+	if (ieee80211_rate2phytype(ic->ic_rt, rate) == IEEE80211_T_CCK)
+		return (0);
+
+	/*
+	 * Yup, enable protection.
+	 */
+	return (1);
+}
+
 static int
 iwn_tx_data(struct iwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
 {
@@ -3496,7 +3543,7 @@ iwn_tx_data(struct iwn_softc *sc, struct
 	uint16_t qos;
 	u_int hdrlen;
 	bus_dma_segment_t *seg, segs[IWN_MAX_SCATTER];
-	uint8_t tid, ridx, txant, type;
+	uint8_t tid, type;
 	int ac, i, totlen, error, pad, nsegs = 0, rate;
 
 	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);
@@ -3546,8 +3593,6 @@ iwn_tx_data(struct iwn_softc *sc, struct
 		(void) ieee80211_ratectl_rate(ni, NULL, 0);
 		rate = ni->ni_txrate;
 	}
-	ridx = ieee80211_legacy_rate_lookup(ic->ic_rt,
-	    rate & IEEE80211_RATE_VAL);
 
 	/* Encrypt the frame if need be. */
 	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
@@ -3604,13 +3649,15 @@ iwn_tx_data(struct iwn_softc *sc, struct
 		/* NB: Group frames are sent using CCK in 802.11b/g. */
 		if (totlen + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) {
 			flags |= IWN_TX_NEED_RTS;
-		} else if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
-		    ridx >= IWN_RIDX_OFDM6) {
+		} else if (iwn_check_rate_needs_protection(sc, vap, rate)) {
 			if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
 				flags |= IWN_TX_NEED_CTS;
 			else if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
 				flags |= IWN_TX_NEED_RTS;
 		}
+
+		/* XXX HT protection? */
+
 		if (flags & (IWN_TX_NEED_RTS | IWN_TX_NEED_CTS)) {
 			if (sc->hw_type != IWN_HW_REV_TYPE_4965) {
 				/* 5000 autoselects RTS/CTS or CTS-to-self. */
@@ -3654,6 +3701,7 @@ iwn_tx_data(struct iwn_softc *sc, struct
 	tx->data_ntries = 15;
 	tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
 	tx->rate = iwn_rate_to_plcp(sc, ni, rate);
+#if 0
 	if (tx->id == sc->broadcast_id) {
 		/* Group or management frame. */
 		tx->linkq = 0;
@@ -3661,9 +3709,21 @@ iwn_tx_data(struct iwn_softc *sc, struct
 		txant = IWN_LSB(sc->txchainmask);
 		tx->rate |= htole32(IWN_RFLAG_ANT(txant));
 	} else {
+		/*
+		 * XXX This is no longer true.  ni_rates may actually
+		 * XXX need to be ni_htrates (for 11n rates) and thus
+		 * XXX ridx is totally bogus here.
+		 *
+		 * XXX So, break this out into a function and look up
+		 * XXX the correct place to start the MRR table rate
+		 * XXX attempt.
+		 */
 		tx->linkq = ni->ni_rates.rs_nrates - ridx - 1;
 		flags |= IWN_TX_LINKQ;	/* enable MRR */
 	}
+#else
+	tx->linkq = 0;	/* Don't enable MRR for now */
+#endif
 	/* Set physical address of "scratch area". */
 	tx->loaddr = htole32(IWN_LOADDR(data->scratch_paddr));
 	tx->hiaddr = IWN_HIADDR(data->scratch_paddr);
@@ -3756,9 +3816,9 @@ iwn_tx_data_raw(struct iwn_softc *sc, st
     struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
 {
 	struct iwn_ops *ops = &sc->ops;
-	struct ifnet *ifp = sc->sc_ifp;
+//	struct ifnet *ifp = sc->sc_ifp;
 	struct ieee80211vap *vap = ni->ni_vap;
-	struct ieee80211com *ic = ifp->if_l2com;
+//	struct ieee80211com *ic = ifp->if_l2com;
 	struct iwn_tx_cmd *cmd;
 	struct iwn_cmd_data *tx;
 	struct ieee80211_frame *wh;
@@ -3770,7 +3830,7 @@ iwn_tx_data_raw(struct iwn_softc *sc, st
 	uint32_t flags;
 	u_int hdrlen;
 	int ac, totlen, error, pad, nsegs = 0, i, rate;
-	uint8_t ridx, type, txant;
+	uint8_t type;
 
 	DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);
 
@@ -3786,16 +3846,8 @@ iwn_tx_data_raw(struct iwn_softc *sc, st
 	desc = &ring->desc[ring->cur];
 	data = &ring->data[ring->cur];
 
-	/* Choose a TX rate index. */
+	/* Choose a TX rate. */
 	rate = params->ibp_rate0;
-	ridx = ieee80211_legacy_rate_lookup(ic->ic_rt,
-	    rate & IEEE80211_RATE_VAL);
-	if (ridx == (uint8_t)-1) {
-		/* XXX fall back to mcast/mgmt rate? */
-		m_freem(m);
-		return EINVAL;
-	}
-
 	totlen = m->m_pkthdr.len;
 
 	/* Prepare TX firmware command. */
@@ -3865,17 +3917,10 @@ iwn_tx_data_raw(struct iwn_softc *sc, st
 	tx->rts_ntries = params->ibp_try1;
 	tx->data_ntries = params->ibp_try0;
 	tx->lifetime = htole32(IWN_LIFETIME_INFINITE);
-
-	/* XXX should just use  iwn_rate_to_plcp() */
-	tx->rate = htole32(rate2plcp(rate));
-	if (ridx < IWN_RIDX_OFDM6 &&
-	    IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
-		tx->rate |= htole32(IWN_RFLAG_CCK);
+	tx->rate = iwn_rate_to_plcp(sc, ni, rate);
 
 	/* Group or management frame. */
 	tx->linkq = 0;
-	txant = IWN_LSB(sc->txchainmask);
-	tx->rate |= htole32(IWN_RFLAG_ANT(txant));
 
 	/* Set physical address of "scratch area". */
 	tx->loaddr = htole32(IWN_LOADDR(data->scratch_paddr));


More information about the svn-src-all mailing list