]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
wl1271: 11n Support, functionality and configuration ability
authorShahar Levi <shahar_levi@ti.com>
Wed, 13 Oct 2010 14:09:41 +0000 (16:09 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 15 Nov 2010 18:25:12 +0000 (13:25 -0500)
Add 11n ability in scan, connection and using MCS rates.
The configuration is temporary due to the code incomplete and
still in testing process. That plans to be remove in the future.

Signed-off-by: Shahar Levi <shahar_levi@ti.com>
Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
drivers/net/wireless/wl12xx/Kconfig
drivers/net/wireless/wl12xx/wl1271_main.c
drivers/net/wireless/wl12xx/wl1271_rx.c
drivers/net/wireless/wl12xx/wl1271_tx.c

index b447559f1db52dbf2780afff4ca3454fbecf6dbd..1b3b7bdd6a192df3db47b31b1fced0344bb5ede7 100644 (file)
@@ -18,6 +18,16 @@ config WL1271
          If you choose to build a module, it'll be called wl1271. Say N if
          unsure.
 
+config WL1271_HT
+        bool "TI wl1271 802.11 HT support (EXPERIMENTAL)"
+        depends on WL1271 && EXPERIMENTAL
+        default n
+        ---help---
+          This will enable 802.11 HT support for TI wl1271 chipset.
+
+         That configuration is temporary due to the code incomplete and
+         still in testing process.
+
 config WL1271_SPI
        tristate "TI wl1271 SPI support"
        depends on WL1271 && SPI_MASTER
index 5d5f4c6a964429a7a0d446ce716eab87b0485b3d..532ccd01cf6f0af918a02a825e692a499d48c936 100644 (file)
@@ -861,12 +861,32 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        struct ieee80211_sta *sta = txinfo->control.sta;
        unsigned long flags;
 
-       /* peek into the rates configured in the STA entry */
+       /*
+        * peek into the rates configured in the STA entry.
+        * The rates set after connection stage, The first block only BG sets:
+        * the compare is for bit 0-16 of sta_rate_set. The second block add
+        * HT rates in case of HT supported.
+        */
        spin_lock_irqsave(&wl->wl_lock, flags);
-       if (sta && sta->supp_rates[conf->channel->band] != wl->sta_rate_set) {
+       if (sta &&
+           (sta->supp_rates[conf->channel->band] !=
+           (wl->sta_rate_set & HW_BG_RATES_MASK))) {
                wl->sta_rate_set = sta->supp_rates[conf->channel->band];
                set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
        }
+
+#ifdef CONFIG_WL1271_HT
+       if (sta &&
+           sta->ht_cap.ht_supported &&
+           ((wl->sta_rate_set >> HW_HT_RATES_OFFSET) !=
+             sta->ht_cap.mcs.rx_mask[0])) {
+               /* Clean MCS bits before setting them */
+               wl->sta_rate_set &= HW_BG_RATES_MASK;
+               wl->sta_rate_set |=
+                       (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
+               set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
+       }
+#endif
        spin_unlock_irqrestore(&wl->wl_lock, flags);
 
        /* queue the packet */
@@ -1720,6 +1740,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
 {
        enum wl1271_cmd_ps_mode mode;
        struct wl1271 *wl = hw->priv;
+       struct ieee80211_sta *sta = ieee80211_find_sta(vif, bss_conf->bssid);
        bool do_join = false;
        bool set_assoc = false;
        int ret;
@@ -1938,6 +1959,37 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
                }
        }
 
+       /*
+        * Takes care of: New association with HT enable,
+        *                HT information change in beacon.
+        */
+       if (sta &&
+           (changed & BSS_CHANGED_HT) &&
+           (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
+               ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true);
+               if (ret < 0) {
+                       wl1271_warning("Set ht cap true failed %d", ret);
+                       goto out_sleep;
+               }
+                       ret = wl1271_acx_set_ht_information(wl,
+                               bss_conf->ht_operation_mode);
+               if (ret < 0) {
+                       wl1271_warning("Set ht information failed %d", ret);
+                       goto out_sleep;
+               }
+       }
+       /*
+        * Takes care of: New association without HT,
+        *                Disassociation.
+        */
+       else if (sta && (changed & BSS_CHANGED_ASSOC)) {
+               ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, false);
+               if (ret < 0) {
+                       wl1271_warning("Set ht cap false failed %d", ret);
+                       goto out_sleep;
+               }
+       }
+
        if (changed & BSS_CHANGED_ARP_FILTER) {
                __be32 addr = bss_conf->arp_addr_list[0];
                WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
@@ -2118,14 +2170,14 @@ static struct ieee80211_channel wl1271_channels[] = {
 /* mapping to indexes for wl1271_rates */
 static const u8 wl1271_rate_to_idx_2ghz[] = {
        /* MCS rates are used only with 11n */
-       CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */
-       CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */
-       CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */
-       CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */
-       CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */
-       CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */
-       CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */
-       CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */
+       7,                            /* CONF_HW_RXTX_RATE_MCS7 */
+       6,                            /* CONF_HW_RXTX_RATE_MCS6 */
+       5,                            /* CONF_HW_RXTX_RATE_MCS5 */
+       4,                            /* CONF_HW_RXTX_RATE_MCS4 */
+       3,                            /* CONF_HW_RXTX_RATE_MCS3 */
+       2,                            /* CONF_HW_RXTX_RATE_MCS2 */
+       1,                            /* CONF_HW_RXTX_RATE_MCS1 */
+       0,                            /* CONF_HW_RXTX_RATE_MCS0 */
 
        11,                            /* CONF_HW_RXTX_RATE_54   */
        10,                            /* CONF_HW_RXTX_RATE_48   */
@@ -2148,6 +2200,7 @@ static const u8 wl1271_rate_to_idx_2ghz[] = {
 /* 11n STA capabilities */
 #define HW_RX_HIGHEST_RATE     72
 
+#ifdef CONFIG_WL1271_HT
 #define WL1271_HT_CAP { \
        .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20, \
        .ht_supported = true, \
@@ -2159,6 +2212,11 @@ static const u8 wl1271_rate_to_idx_2ghz[] = {
                .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
                }, \
 }
+#else
+#define WL1271_HT_CAP { \
+       .ht_supported = false, \
+}
+#endif
 
 /* can't be const, mac80211 writes to this */
 static struct ieee80211_supported_band wl1271_band_2ghz = {
@@ -2166,6 +2224,7 @@ static struct ieee80211_supported_band wl1271_band_2ghz = {
        .n_channels = ARRAY_SIZE(wl1271_channels),
        .bitrates = wl1271_rates,
        .n_bitrates = ARRAY_SIZE(wl1271_rates),
+       .ht_cap = WL1271_HT_CAP,
 };
 
 /* 5 GHz data rates for WL1273 */
@@ -2248,14 +2307,14 @@ static struct ieee80211_channel wl1271_channels_5ghz[] = {
 /* mapping to indexes for wl1271_rates_5ghz */
 static const u8 wl1271_rate_to_idx_5ghz[] = {
        /* MCS rates are used only with 11n */
-       CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */
-       CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */
-       CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */
-       CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */
-       CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */
-       CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */
-       CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */
-       CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */
+       7,                            /* CONF_HW_RXTX_RATE_MCS7 */
+       6,                            /* CONF_HW_RXTX_RATE_MCS6 */
+       5,                            /* CONF_HW_RXTX_RATE_MCS5 */
+       4,                            /* CONF_HW_RXTX_RATE_MCS4 */
+       3,                            /* CONF_HW_RXTX_RATE_MCS3 */
+       2,                            /* CONF_HW_RXTX_RATE_MCS2 */
+       1,                            /* CONF_HW_RXTX_RATE_MCS1 */
+       0,                            /* CONF_HW_RXTX_RATE_MCS0 */
 
        7,                             /* CONF_HW_RXTX_RATE_54   */
        6,                             /* CONF_HW_RXTX_RATE_48   */
@@ -2280,6 +2339,7 @@ static struct ieee80211_supported_band wl1271_band_5ghz = {
        .n_channels = ARRAY_SIZE(wl1271_channels_5ghz),
        .bitrates = wl1271_rates_5ghz,
        .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz),
+       .ht_cap = WL1271_HT_CAP,
 };
 
 static const u8 *wl1271_band_rate_to_idx[] = {
index bea133b6e4893e2d61cbeff1e4d1f31d1faa42c4..ac13f7d252198f2ee9542ac866260257ee83885a 100644 (file)
@@ -53,6 +53,12 @@ static void wl1271_rx_status(struct wl1271 *wl,
        status->band = wl->band;
        status->rate_idx = wl1271_rate_to_idx(wl, desc->rate);
 
+#ifdef CONFIG_WL1271_HT
+       /* 11n support */
+       if (desc->rate <= CONF_HW_RXTX_RATE_MCS0)
+               status->flag |= RX_FLAG_HT;
+#endif
+
        status->signal = desc->rssi;
 
        /*
index dc3172bea0ddd224fe6fb0ccd68e62fe7291e707..87a5aed00c8c18f11efcf3fba68861f24db36f53 100644 (file)
@@ -209,6 +209,17 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
                rate_set >>= 1;
        }
 
+#ifdef CONFIG_WL1271_HT
+       /* MCS rates indication are on bits 16 - 23 */
+       rate_set >>= HW_HT_RATES_OFFSET - band->n_bitrates;
+
+       for (bit = 0; bit < 8; bit++) {
+               if (rate_set & 0x1)
+                       enabled_rates |= (CONF_HW_BIT_RATE_MCS_0 << bit);
+               rate_set >>= 1;
+       }
+#endif
+
        return enabled_rates;
 }