aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorShahar Levi <shahar_levi@ti.com>2010-10-13 10:09:41 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-11-15 13:25:12 -0500
commit18357850b694ba3fa29363c7d86ccd8783f4a065 (patch)
treea4fed3c7ff755751ad2f6910485b73483630f9cb /drivers/net
parentc4db1c879679e795689ef3c9dd7d3f6568ea14c5 (diff)
wl1271: 11n Support, functionality and configuration ability
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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig10
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c96
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_rx.c6
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.c11
4 files changed, 105 insertions, 18 deletions
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index b447559f1db5..1b3b7bdd6a19 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -18,6 +18,16 @@ config WL1271
18 If you choose to build a module, it'll be called wl1271. Say N if 18 If you choose to build a module, it'll be called wl1271. Say N if
19 unsure. 19 unsure.
20 20
21config WL1271_HT
22 bool "TI wl1271 802.11 HT support (EXPERIMENTAL)"
23 depends on WL1271 && EXPERIMENTAL
24 default n
25 ---help---
26 This will enable 802.11 HT support for TI wl1271 chipset.
27
28 That configuration is temporary due to the code incomplete and
29 still in testing process.
30
21config WL1271_SPI 31config WL1271_SPI
22 tristate "TI wl1271 SPI support" 32 tristate "TI wl1271 SPI support"
23 depends on WL1271 && SPI_MASTER 33 depends on WL1271 && SPI_MASTER
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 5d5f4c6a9644..532ccd01cf6f 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -861,12 +861,32 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
861 struct ieee80211_sta *sta = txinfo->control.sta; 861 struct ieee80211_sta *sta = txinfo->control.sta;
862 unsigned long flags; 862 unsigned long flags;
863 863
864 /* peek into the rates configured in the STA entry */ 864 /*
865 * peek into the rates configured in the STA entry.
866 * The rates set after connection stage, The first block only BG sets:
867 * the compare is for bit 0-16 of sta_rate_set. The second block add
868 * HT rates in case of HT supported.
869 */
865 spin_lock_irqsave(&wl->wl_lock, flags); 870 spin_lock_irqsave(&wl->wl_lock, flags);
866 if (sta && sta->supp_rates[conf->channel->band] != wl->sta_rate_set) { 871 if (sta &&
872 (sta->supp_rates[conf->channel->band] !=
873 (wl->sta_rate_set & HW_BG_RATES_MASK))) {
867 wl->sta_rate_set = sta->supp_rates[conf->channel->band]; 874 wl->sta_rate_set = sta->supp_rates[conf->channel->band];
868 set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); 875 set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
869 } 876 }
877
878#ifdef CONFIG_WL1271_HT
879 if (sta &&
880 sta->ht_cap.ht_supported &&
881 ((wl->sta_rate_set >> HW_HT_RATES_OFFSET) !=
882 sta->ht_cap.mcs.rx_mask[0])) {
883 /* Clean MCS bits before setting them */
884 wl->sta_rate_set &= HW_BG_RATES_MASK;
885 wl->sta_rate_set |=
886 (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET);
887 set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
888 }
889#endif
870 spin_unlock_irqrestore(&wl->wl_lock, flags); 890 spin_unlock_irqrestore(&wl->wl_lock, flags);
871 891
872 /* queue the packet */ 892 /* queue the packet */
@@ -1720,6 +1740,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1720{ 1740{
1721 enum wl1271_cmd_ps_mode mode; 1741 enum wl1271_cmd_ps_mode mode;
1722 struct wl1271 *wl = hw->priv; 1742 struct wl1271 *wl = hw->priv;
1743 struct ieee80211_sta *sta = ieee80211_find_sta(vif, bss_conf->bssid);
1723 bool do_join = false; 1744 bool do_join = false;
1724 bool set_assoc = false; 1745 bool set_assoc = false;
1725 int ret; 1746 int ret;
@@ -1938,6 +1959,37 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1938 } 1959 }
1939 } 1960 }
1940 1961
1962 /*
1963 * Takes care of: New association with HT enable,
1964 * HT information change in beacon.
1965 */
1966 if (sta &&
1967 (changed & BSS_CHANGED_HT) &&
1968 (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
1969 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true);
1970 if (ret < 0) {
1971 wl1271_warning("Set ht cap true failed %d", ret);
1972 goto out_sleep;
1973 }
1974 ret = wl1271_acx_set_ht_information(wl,
1975 bss_conf->ht_operation_mode);
1976 if (ret < 0) {
1977 wl1271_warning("Set ht information failed %d", ret);
1978 goto out_sleep;
1979 }
1980 }
1981 /*
1982 * Takes care of: New association without HT,
1983 * Disassociation.
1984 */
1985 else if (sta && (changed & BSS_CHANGED_ASSOC)) {
1986 ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, false);
1987 if (ret < 0) {
1988 wl1271_warning("Set ht cap false failed %d", ret);
1989 goto out_sleep;
1990 }
1991 }
1992
1941 if (changed & BSS_CHANGED_ARP_FILTER) { 1993 if (changed & BSS_CHANGED_ARP_FILTER) {
1942 __be32 addr = bss_conf->arp_addr_list[0]; 1994 __be32 addr = bss_conf->arp_addr_list[0];
1943 WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); 1995 WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
@@ -2118,14 +2170,14 @@ static struct ieee80211_channel wl1271_channels[] = {
2118/* mapping to indexes for wl1271_rates */ 2170/* mapping to indexes for wl1271_rates */
2119static const u8 wl1271_rate_to_idx_2ghz[] = { 2171static const u8 wl1271_rate_to_idx_2ghz[] = {
2120 /* MCS rates are used only with 11n */ 2172 /* MCS rates are used only with 11n */
2121 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */ 2173 7, /* CONF_HW_RXTX_RATE_MCS7 */
2122 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */ 2174 6, /* CONF_HW_RXTX_RATE_MCS6 */
2123 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */ 2175 5, /* CONF_HW_RXTX_RATE_MCS5 */
2124 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */ 2176 4, /* CONF_HW_RXTX_RATE_MCS4 */
2125 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */ 2177 3, /* CONF_HW_RXTX_RATE_MCS3 */
2126 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */ 2178 2, /* CONF_HW_RXTX_RATE_MCS2 */
2127 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */ 2179 1, /* CONF_HW_RXTX_RATE_MCS1 */
2128 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */ 2180 0, /* CONF_HW_RXTX_RATE_MCS0 */
2129 2181
2130 11, /* CONF_HW_RXTX_RATE_54 */ 2182 11, /* CONF_HW_RXTX_RATE_54 */
2131 10, /* CONF_HW_RXTX_RATE_48 */ 2183 10, /* CONF_HW_RXTX_RATE_48 */
@@ -2148,6 +2200,7 @@ static const u8 wl1271_rate_to_idx_2ghz[] = {
2148/* 11n STA capabilities */ 2200/* 11n STA capabilities */
2149#define HW_RX_HIGHEST_RATE 72 2201#define HW_RX_HIGHEST_RATE 72
2150 2202
2203#ifdef CONFIG_WL1271_HT
2151#define WL1271_HT_CAP { \ 2204#define WL1271_HT_CAP { \
2152 .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20, \ 2205 .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20, \
2153 .ht_supported = true, \ 2206 .ht_supported = true, \
@@ -2159,6 +2212,11 @@ static const u8 wl1271_rate_to_idx_2ghz[] = {
2159 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ 2212 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
2160 }, \ 2213 }, \
2161} 2214}
2215#else
2216#define WL1271_HT_CAP { \
2217 .ht_supported = false, \
2218}
2219#endif
2162 2220
2163/* can't be const, mac80211 writes to this */ 2221/* can't be const, mac80211 writes to this */
2164static struct ieee80211_supported_band wl1271_band_2ghz = { 2222static struct ieee80211_supported_band wl1271_band_2ghz = {
@@ -2166,6 +2224,7 @@ static struct ieee80211_supported_band wl1271_band_2ghz = {
2166 .n_channels = ARRAY_SIZE(wl1271_channels), 2224 .n_channels = ARRAY_SIZE(wl1271_channels),
2167 .bitrates = wl1271_rates, 2225 .bitrates = wl1271_rates,
2168 .n_bitrates = ARRAY_SIZE(wl1271_rates), 2226 .n_bitrates = ARRAY_SIZE(wl1271_rates),
2227 .ht_cap = WL1271_HT_CAP,
2169}; 2228};
2170 2229
2171/* 5 GHz data rates for WL1273 */ 2230/* 5 GHz data rates for WL1273 */
@@ -2248,14 +2307,14 @@ static struct ieee80211_channel wl1271_channels_5ghz[] = {
2248/* mapping to indexes for wl1271_rates_5ghz */ 2307/* mapping to indexes for wl1271_rates_5ghz */
2249static const u8 wl1271_rate_to_idx_5ghz[] = { 2308static const u8 wl1271_rate_to_idx_5ghz[] = {
2250 /* MCS rates are used only with 11n */ 2309 /* MCS rates are used only with 11n */
2251 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS7 */ 2310 7, /* CONF_HW_RXTX_RATE_MCS7 */
2252 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS6 */ 2311 6, /* CONF_HW_RXTX_RATE_MCS6 */
2253 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS5 */ 2312 5, /* CONF_HW_RXTX_RATE_MCS5 */
2254 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS4 */ 2313 4, /* CONF_HW_RXTX_RATE_MCS4 */
2255 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS3 */ 2314 3, /* CONF_HW_RXTX_RATE_MCS3 */
2256 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS2 */ 2315 2, /* CONF_HW_RXTX_RATE_MCS2 */
2257 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS1 */ 2316 1, /* CONF_HW_RXTX_RATE_MCS1 */
2258 CONF_HW_RXTX_RATE_UNSUPPORTED, /* CONF_HW_RXTX_RATE_MCS0 */ 2317 0, /* CONF_HW_RXTX_RATE_MCS0 */
2259 2318
2260 7, /* CONF_HW_RXTX_RATE_54 */ 2319 7, /* CONF_HW_RXTX_RATE_54 */
2261 6, /* CONF_HW_RXTX_RATE_48 */ 2320 6, /* CONF_HW_RXTX_RATE_48 */
@@ -2280,6 +2339,7 @@ static struct ieee80211_supported_band wl1271_band_5ghz = {
2280 .n_channels = ARRAY_SIZE(wl1271_channels_5ghz), 2339 .n_channels = ARRAY_SIZE(wl1271_channels_5ghz),
2281 .bitrates = wl1271_rates_5ghz, 2340 .bitrates = wl1271_rates_5ghz,
2282 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz), 2341 .n_bitrates = ARRAY_SIZE(wl1271_rates_5ghz),
2342 .ht_cap = WL1271_HT_CAP,
2283}; 2343};
2284 2344
2285static const u8 *wl1271_band_rate_to_idx[] = { 2345static const u8 *wl1271_band_rate_to_idx[] = {
diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c
index bea133b6e489..ac13f7d25219 100644
--- a/drivers/net/wireless/wl12xx/wl1271_rx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_rx.c
@@ -53,6 +53,12 @@ static void wl1271_rx_status(struct wl1271 *wl,
53 status->band = wl->band; 53 status->band = wl->band;
54 status->rate_idx = wl1271_rate_to_idx(wl, desc->rate); 54 status->rate_idx = wl1271_rate_to_idx(wl, desc->rate);
55 55
56#ifdef CONFIG_WL1271_HT
57 /* 11n support */
58 if (desc->rate <= CONF_HW_RXTX_RATE_MCS0)
59 status->flag |= RX_FLAG_HT;
60#endif
61
56 status->signal = desc->rssi; 62 status->signal = desc->rssi;
57 63
58 /* 64 /*
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
index dc3172bea0dd..87a5aed00c8c 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -209,6 +209,17 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
209 rate_set >>= 1; 209 rate_set >>= 1;
210 } 210 }
211 211
212#ifdef CONFIG_WL1271_HT
213 /* MCS rates indication are on bits 16 - 23 */
214 rate_set >>= HW_HT_RATES_OFFSET - band->n_bitrates;
215
216 for (bit = 0; bit < 8; bit++) {
217 if (rate_set & 0x1)
218 enabled_rates |= (CONF_HW_BIT_RATE_MCS_0 << bit);
219 rate_set >>= 1;
220 }
221#endif
222
212 return enabled_rates; 223 return enabled_rates;
213} 224}
214 225