Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 8 May 2011 11:54:38 +0000 (UTC)
From:      Bernhard Schmidt <bschmidt@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r221649 - head/sys/dev/iwn
Message-ID:  <201105081154.p48Bsc7e044690@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bschmidt
Date: Sun May  8 11:54:38 2011
New Revision: 221649
URL: http://svn.freebsd.org/changeset/base/221649

Log:
  Add support for transmitting frames at MCS rates.

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

Modified: head/sys/dev/iwn/if_iwn.c
==============================================================================
--- head/sys/dev/iwn/if_iwn.c	Sun May  8 11:49:50 2011	(r221648)
+++ head/sys/dev/iwn/if_iwn.c	Sun May  8 11:54:38 2011	(r221649)
@@ -2119,22 +2119,47 @@ iwn_newassoc(struct ieee80211_node *ni, 
 	struct ieee80211com *ic = ni->ni_ic;
 	struct iwn_softc *sc = ic->ic_ifp->if_softc;
 	struct iwn_node *wn = (void *)ni;
-	uint8_t txant;
+	uint8_t txant1, txant2;
 	int i, plcp, rate, ridx;
 
 	/* Use the first valid TX antenna. */
-	txant = IWN_LSB(sc->txchainmask);
+	txant1 = IWN_LSB(sc->txchainmask);
+	txant2 = IWN_LSB(sc->txchainmask & ~txant1);
+
+	if (IEEE80211_IS_CHAN_HT(ni->ni_chan)) {
+		ridx = ni->ni_rates.rs_nrates - 1;
+		for (i = ni->ni_htrates.rs_nrates - 1; i >= 0; i--) {
+			plcp = ni->ni_htrates.rs_rates[i] | IWN_RFLAG_MCS;
+			if (IEEE80211_IS_CHAN_HT40(ni->ni_chan)) {
+				plcp |= IWN_RFLAG_HT40;
+				if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40)
+					plcp |= IWN_RFLAG_SGI;
+			} else if (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20)
+				plcp |= IWN_RFLAG_SGI;
+			if (i > 7)
+				plcp |= IWN_RFLAG_ANT(txant1 | txant2);
+			else
+				plcp |= IWN_RFLAG_ANT(txant1);
+			if (ridx >= 0) {
+				rate = ni->ni_rates.rs_rates[ridx];
+				rate &= IEEE80211_RATE_VAL;
+				wn->ridx[rate] = plcp;
+			}
+			wn->ridx[IEEE80211_RATE_MCS | i] = plcp;
+			ridx--;
+		}
+	} else {
+		for (i = 0; i < ni->ni_rates.rs_nrates; i++) {
+			rate = ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL;
 
-	for (i = 0; i < ni->ni_rates.rs_nrates; i++) {
-		rate = ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL;
-		plcp = rate2plcp(rate);
-		ridx = ic->ic_rt->rateCodeToIndex[rate];
-
-		if (ridx < IWN_RIDX_OFDM6 &&
-		    IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
-			plcp |= IWN_RFLAG_CCK;
-		plcp |= IWN_RFLAG_ANT(txant);
-		wn->ridx[rate] = htole32(plcp);
+			plcp = rate2plcp(rate);
+			ridx = ic->ic_rt->rateCodeToIndex[rate];
+			if (ridx < IWN_RIDX_OFDM6 &&
+			    IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
+				plcp |= IWN_RFLAG_CCK;
+			plcp |= IWN_RFLAG_ANT(txant1);
+			wn->ridx[rate] = htole32(plcp);
+		}
 	}
 }
 
@@ -3849,11 +3874,21 @@ iwn_set_link_quality(struct iwn_softc *s
 	linkq.ampdu_limit = htole16(4000);	/* 4ms */
 
 	/* Start at highest available bit-rate. */
-	txrate = rs->rs_nrates - 1;
+	if (IEEE80211_IS_CHAN_HT(ni->ni_chan))
+		txrate = ni->ni_htrates.rs_nrates - 1;
+	else
+		txrate = rs->rs_nrates - 1;
 	for (i = 0; i < IWN_MAX_TX_RETRIES; i++) {
-		rate = rs->rs_rates[txrate] & IEEE80211_RATE_VAL;
+		if (IEEE80211_IS_CHAN_HT(ni->ni_chan))
+			rate = IEEE80211_RATE_MCS | txrate;
+		else
+			rate = rs->rs_rates[txrate] & IEEE80211_RATE_VAL;
 		linkq.retry[i] = wn->ridx[rate];
 
+		if ((le32toh(wn->ridx[rate]) & IWN_RFLAG_MCS) &&
+		    (le32toh(wn->ridx[rate]) & 0xff) > 7)
+			linkq.mimo = i + 1;
+
 		/* Next retry at immediate lower bit-rate. */
 		if (txrate > 0)
 			txrate--;

Modified: head/sys/dev/iwn/if_iwnreg.h
==============================================================================
--- head/sys/dev/iwn/if_iwnreg.h	Sun May  8 11:49:50 2011	(r221648)
+++ head/sys/dev/iwn/if_iwnreg.h	Sun May  8 11:54:38 2011	(r221649)
@@ -625,7 +625,12 @@ struct iwn4965_node_info {
 	uint32_t	reserved7;
 } __packed;
 
+#define IWN_RFLAG_MCS		(1 << 8)
 #define IWN_RFLAG_CCK		(1 << 9)
+#define IWN_RFLAG_GREENFIELD	(1 << 10)
+#define IWN_RFLAG_HT40		(1 << 11)
+#define IWN_RFLAG_DUPLICATE	(1 << 12)
+#define IWN_RFLAG_SGI		(1 << 13)
 #define IWN_RFLAG_ANT(x)	((x) << 14)
 
 /* Structure for command IWN_CMD_TX_DATA. */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105081154.p48Bsc7e044690>