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. */
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to