aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>2009-12-11 08:41:06 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-12-28 16:31:35 -0500
commit830fb67b8e37fb03cf703b4e1217fe30ce32d579 (patch)
tree475d121a2ac44bcf33e6bb82f8011a53ddbb56a8 /drivers/net/wireless
parentec078d943b89c03e55ac9c8b28f39256d4d4045e (diff)
wl1271: Fix supported rate management
Previously, only basic rates were used for data transmission - resulting in reduced transfer rates. This patch takes enables the firmware to take advantage of the full set of data rates supported by the AP. Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com> Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com> Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h7
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.c24
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_acx.h5
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_init.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c59
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_tx.c37
6 files changed, 90 insertions, 44 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index c965c4a718f3..9290c92522b4 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -322,6 +322,10 @@ struct wl1271 {
322 enum wl1271_state state; 322 enum wl1271_state state;
323 struct mutex mutex; 323 struct mutex mutex;
324 324
325#define WL1271_FLAG_STA_RATES_CHANGED (0)
326#define WL1271_FLAG_STA_ASSOCIATED (1)
327 unsigned long flags;
328
325 struct wl1271_partition_set part; 329 struct wl1271_partition_set part;
326 330
327 struct wl1271_chip chip; 331 struct wl1271_chip chip;
@@ -394,7 +398,9 @@ struct wl1271 {
394 u16 aid; 398 u16 aid;
395 399
396 /* currently configured rate set */ 400 /* currently configured rate set */
401 u32 sta_rate_set;
397 u32 basic_rate_set; 402 u32 basic_rate_set;
403 u32 rate_set;
398 404
399 /* The current band */ 405 /* The current band */
400 enum ieee80211_band band; 406 enum ieee80211_band band;
@@ -416,7 +422,6 @@ struct wl1271 {
416 422
417 /* PSM mode requested */ 423 /* PSM mode requested */
418 bool psm_requested; 424 bool psm_requested;
419 bool associated;
420 425
421 /* retry counter for PSM entries */ 426 /* retry counter for PSM entries */
422 u8 psm_entry_retry; 427 u8 psm_entry_retry;
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c
index ea6427ad1bcb..0ea1a48c45fa 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.c
@@ -787,10 +787,11 @@ int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats)
787 return 0; 787 return 0;
788} 788}
789 789
790int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates) 790int wl1271_acx_rate_policies(struct wl1271 *wl)
791{ 791{
792 struct acx_rate_policy *acx; 792 struct acx_rate_policy *acx;
793 struct conf_tx_rate_class *c = &wl->conf.tx.rc_conf; 793 struct conf_tx_rate_class *c = &wl->conf.tx.rc_conf;
794 int idx = 0;
794 int ret = 0; 795 int ret = 0;
795 796
796 wl1271_debug(DEBUG_ACX, "acx rate policies"); 797 wl1271_debug(DEBUG_ACX, "acx rate policies");
@@ -802,12 +803,21 @@ int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates)
802 goto out; 803 goto out;
803 } 804 }
804 805
805 /* configure one default (one-size-fits-all) rate class */ 806 /* configure one basic rate class */
806 acx->rate_class_cnt = cpu_to_le32(1); 807 idx = ACX_TX_BASIC_RATE;
807 acx->rate_class[0].enabled_rates = cpu_to_le32(enabled_rates); 808 acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->basic_rate_set);
808 acx->rate_class[0].short_retry_limit = c->short_retry_limit; 809 acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
809 acx->rate_class[0].long_retry_limit = c->long_retry_limit; 810 acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
810 acx->rate_class[0].aflags = c->aflags; 811 acx->rate_class[idx].aflags = c->aflags;
812
813 /* configure one AP supported rate class */
814 idx = ACX_TX_AP_FULL_RATE;
815 acx->rate_class[idx].enabled_rates = cpu_to_le32(wl->rate_set);
816 acx->rate_class[idx].short_retry_limit = c->short_retry_limit;
817 acx->rate_class[idx].long_retry_limit = c->long_retry_limit;
818 acx->rate_class[idx].aflags = c->aflags;
819
820 acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT);
811 821
812 ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); 822 ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx));
813 if (ret < 0) { 823 if (ret < 0) {
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h
index 6640ebfb6162..b6a473f60658 100644
--- a/drivers/net/wireless/wl12xx/wl1271_acx.h
+++ b/drivers/net/wireless/wl12xx/wl1271_acx.h
@@ -826,6 +826,9 @@ struct acx_rate_class {
826 u8 reserved; 826 u8 reserved;
827}; 827};
828 828
829#define ACX_TX_BASIC_RATE 0
830#define ACX_TX_AP_FULL_RATE 1
831#define ACX_TX_RATE_POLICY_CNT 2
829struct acx_rate_policy { 832struct acx_rate_policy {
830 struct acx_header header; 833 struct acx_header header;
831 834
@@ -1058,7 +1061,7 @@ int wl1271_acx_set_preamble(struct wl1271 *wl, enum acx_preamble_type preamble);
1058int wl1271_acx_cts_protect(struct wl1271 *wl, 1061int wl1271_acx_cts_protect(struct wl1271 *wl,
1059 enum acx_ctsprotect_type ctsprotect); 1062 enum acx_ctsprotect_type ctsprotect);
1060int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats); 1063int wl1271_acx_statistics(struct wl1271 *wl, struct acx_statistics *stats);
1061int wl1271_acx_rate_policies(struct wl1271 *wl, u32 enabled_rates); 1064int wl1271_acx_rate_policies(struct wl1271 *wl);
1062int wl1271_acx_ac_cfg(struct wl1271 *wl); 1065int wl1271_acx_ac_cfg(struct wl1271 *wl);
1063int wl1271_acx_tid_cfg(struct wl1271 *wl); 1066int wl1271_acx_tid_cfg(struct wl1271 *wl);
1064int wl1271_acx_frag_threshold(struct wl1271 *wl); 1067int wl1271_acx_frag_threshold(struct wl1271 *wl);
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c
index c67889dd18fc..3b4ed070f439 100644
--- a/drivers/net/wireless/wl12xx/wl1271_init.c
+++ b/drivers/net/wireless/wl12xx/wl1271_init.c
@@ -284,7 +284,7 @@ int wl1271_hw_init(struct wl1271 *wl)
284 goto out_free_memmap; 284 goto out_free_memmap;
285 285
286 /* Configure TX rate classes */ 286 /* Configure TX rate classes */
287 ret = wl1271_acx_rate_policies(wl, CONF_TX_RATE_MASK_BASIC); 287 ret = wl1271_acx_rate_policies(wl);
288 if (ret < 0) 288 if (ret < 0)
289 goto out_free_memmap; 289 goto out_free_memmap;
290 290
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 7a73aaadd04c..775b1e82ca81 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -777,7 +777,20 @@ out:
777static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 777static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
778{ 778{
779 struct wl1271 *wl = hw->priv; 779 struct wl1271 *wl = hw->priv;
780 struct ieee80211_conf *conf = &hw->conf;
781 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
782 struct ieee80211_sta *sta = txinfo->control.sta;
783 unsigned long flags;
780 784
785 /* peek into the rates configured in the STA entry */
786 spin_lock_irqsave(&wl->wl_lock, flags);
787 if (sta && sta->supp_rates[conf->channel->band] != wl->sta_rate_set) {
788 wl->sta_rate_set = sta->supp_rates[conf->channel->band];
789 set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags);
790 }
791 spin_unlock_irqrestore(&wl->wl_lock, flags);
792
793 /* queue the packet */
781 skb_queue_tail(&wl->tx_queue, skb); 794 skb_queue_tail(&wl->tx_queue, skb);
782 795
783 /* 796 /*
@@ -1004,7 +1017,6 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1004 wl->elp = false; 1017 wl->elp = false;
1005 wl->psm = 0; 1018 wl->psm = 0;
1006 wl->psm_entry_retry = 0; 1019 wl->psm_entry_retry = 0;
1007 wl->associated = false;
1008 wl->tx_queue_stopped = false; 1020 wl->tx_queue_stopped = false;
1009 wl->power_level = WL1271_DEFAULT_POWER_LEVEL; 1021 wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
1010 wl->tx_blocks_available = 0; 1022 wl->tx_blocks_available = 0;
@@ -1016,6 +1028,9 @@ static void wl1271_op_stop(struct ieee80211_hw *hw)
1016 wl->time_offset = 0; 1028 wl->time_offset = 0;
1017 wl->session_counter = 0; 1029 wl->session_counter = 0;
1018 wl->joined = false; 1030 wl->joined = false;
1031 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
1032 wl->sta_rate_set = 0;
1033 wl->flags = 0;
1019 1034
1020 for (i = 0; i < NUM_TX_QUEUES; i++) 1035 for (i = 0; i < NUM_TX_QUEUES; i++)
1021 wl->tx_blocks_freed[i] = 0; 1036 wl->tx_blocks_freed[i] = 0;
@@ -1212,8 +1227,9 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1212 wl1271_join_channel(wl, channel); 1227 wl1271_join_channel(wl, channel);
1213 1228
1214 if (conf->flags & IEEE80211_CONF_IDLE) { 1229 if (conf->flags & IEEE80211_CONF_IDLE) {
1215 wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC; 1230 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
1216 wl1271_acx_rate_policies(wl, CONF_TX_RATE_MASK_BASIC); 1231 wl->sta_rate_set = 0;
1232 wl1271_acx_rate_policies(wl);
1217 } 1233 }
1218 } 1234 }
1219 1235
@@ -1229,7 +1245,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
1229 * If we're not, we'll enter it when joining an SSID, 1245 * If we're not, we'll enter it when joining an SSID,
1230 * through the bss_info_changed() hook. 1246 * through the bss_info_changed() hook.
1231 */ 1247 */
1232 if (wl->associated) { 1248 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) {
1233 wl1271_info("psm enabled"); 1249 wl1271_info("psm enabled");
1234 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE); 1250 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
1235 } 1251 }
@@ -1522,22 +1538,6 @@ out:
1522 return ret; 1538 return ret;
1523} 1539}
1524 1540
1525static u32 wl1271_enabled_rates_get(struct wl1271 *wl, u64 basic_rate_set)
1526{
1527 struct ieee80211_supported_band *band;
1528 u32 enabled_rates = 0;
1529 int bit;
1530
1531 band = wl->hw->wiphy->bands[wl->band];
1532 for (bit = 0; bit < band->n_bitrates; bit++) {
1533 if (basic_rate_set & 0x1)
1534 enabled_rates |= band->bitrates[bit].hw_value;
1535 basic_rate_set >>= 1;
1536 }
1537
1538 return enabled_rates;
1539}
1540
1541static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, 1541static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1542 struct ieee80211_vif *vif, 1542 struct ieee80211_vif *vif,
1543 struct ieee80211_bss_conf *bss_conf, 1543 struct ieee80211_bss_conf *bss_conf,
@@ -1616,7 +1616,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1616 if (changed & BSS_CHANGED_ASSOC) { 1616 if (changed & BSS_CHANGED_ASSOC) {
1617 if (bss_conf->assoc) { 1617 if (bss_conf->assoc) {
1618 wl->aid = bss_conf->aid; 1618 wl->aid = bss_conf->aid;
1619 wl->associated = true; 1619 set_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
1620 1620
1621 /* 1621 /*
1622 * with wl1271, we don't need to update the 1622 * with wl1271, we don't need to update the
@@ -1641,7 +1641,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1641 } 1641 }
1642 } else { 1642 } else {
1643 /* use defaults when not associated */ 1643 /* use defaults when not associated */
1644 wl->associated = false; 1644 clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
1645 wl->aid = 0; 1645 wl->aid = 0;
1646 } 1646 }
1647 1647
@@ -1676,17 +1676,6 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
1676 } 1676 }
1677 } 1677 }
1678 1678
1679 if (changed & BSS_CHANGED_BASIC_RATES) {
1680 wl->basic_rate_set = wl1271_enabled_rates_get(
1681 wl, bss_conf->basic_rates);
1682
1683 ret = wl1271_acx_rate_policies(wl, wl->basic_rate_set);
1684 if (ret < 0) {
1685 wl1271_warning("Set rate policies failed %d", ret);
1686 goto out_sleep;
1687 }
1688 }
1689
1690out_sleep: 1679out_sleep:
1691 wl1271_ps_elp_sleep(wl); 1680 wl1271_ps_elp_sleep(wl);
1692 1681
@@ -1969,14 +1958,16 @@ static int __devinit wl1271_probe(struct spi_device *spi)
1969 wl->psm = 0; 1958 wl->psm = 0;
1970 wl->psm_requested = false; 1959 wl->psm_requested = false;
1971 wl->psm_entry_retry = 0; 1960 wl->psm_entry_retry = 0;
1972 wl->associated = false;
1973 wl->tx_queue_stopped = false; 1961 wl->tx_queue_stopped = false;
1974 wl->power_level = WL1271_DEFAULT_POWER_LEVEL; 1962 wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
1975 wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC; 1963 wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC;
1964 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
1965 wl->sta_rate_set = 0;
1976 wl->band = IEEE80211_BAND_2GHZ; 1966 wl->band = IEEE80211_BAND_2GHZ;
1977 wl->vif = NULL; 1967 wl->vif = NULL;
1978 wl->joined = false; 1968 wl->joined = false;
1979 wl->gpio_power = false; 1969 wl->gpio_power = false;
1970 wl->flags = 0;
1980 1971
1981 for (i = 0; i < ACX_TX_DESCRIPTORS; i++) 1972 for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
1982 wl->tx_frames[i] = NULL; 1973 wl->tx_frames[i] = NULL;
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c
index 00af065c77c2..75f532706332 100644
--- a/drivers/net/wireless/wl12xx/wl1271_tx.c
+++ b/drivers/net/wireless/wl12xx/wl1271_tx.c
@@ -121,6 +121,11 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
121 pad = pad - skb->len; 121 pad = pad - skb->len;
122 tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD; 122 tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD;
123 123
124 /* if the packets are destined for AP (have a STA entry) send them
125 with AP rate policies, otherwise use default basic rates */
126 if (control->control.sta)
127 tx_attr |= ACX_TX_AP_FULL_RATE << TX_HW_ATTR_OFST_RATE_POLICY;
128
124 desc->tx_attr = cpu_to_le16(tx_attr); 129 desc->tx_attr = cpu_to_le16(tx_attr);
125 130
126 wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad); 131 wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad);
@@ -214,18 +219,50 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb)
214 return ret; 219 return ret;
215} 220}
216 221
222static u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set)
223{
224 struct ieee80211_supported_band *band;
225 u32 enabled_rates = 0;
226 int bit;
227
228 band = wl->hw->wiphy->bands[wl->band];
229 for (bit = 0; bit < band->n_bitrates; bit++) {
230 if (rate_set & 0x1)
231 enabled_rates |= band->bitrates[bit].hw_value;
232 rate_set >>= 1;
233 }
234
235 return enabled_rates;
236}
237
217void wl1271_tx_work(struct work_struct *work) 238void wl1271_tx_work(struct work_struct *work)
218{ 239{
219 struct wl1271 *wl = container_of(work, struct wl1271, tx_work); 240 struct wl1271 *wl = container_of(work, struct wl1271, tx_work);
220 struct sk_buff *skb; 241 struct sk_buff *skb;
221 bool woken_up = false; 242 bool woken_up = false;
243 u32 sta_rates = 0;
222 int ret; 244 int ret;
223 245
246 /* check if the rates supported by the AP have changed */
247 if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED,
248 &wl->flags))) {
249 unsigned long flags;
250 spin_lock_irqsave(&wl->wl_lock, flags);
251 sta_rates = wl->sta_rate_set;
252 spin_unlock_irqrestore(&wl->wl_lock, flags);
253 }
254
224 mutex_lock(&wl->mutex); 255 mutex_lock(&wl->mutex);
225 256
226 if (unlikely(wl->state == WL1271_STATE_OFF)) 257 if (unlikely(wl->state == WL1271_STATE_OFF))
227 goto out; 258 goto out;
228 259
260 /* if rates have changed, re-configure the rate policy */
261 if (unlikely(sta_rates)) {
262 wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates);
263 wl1271_acx_rate_policies(wl);
264 }
265
229 while ((skb = skb_dequeue(&wl->tx_queue))) { 266 while ((skb = skb_dequeue(&wl->tx_queue))) {
230 if (!woken_up) { 267 if (!woken_up) {
231 ret = wl1271_ps_elp_wakeup(wl, false); 268 ret = wl1271_ps_elp_wakeup(wl, false);