aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-09-16 16:20:43 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-09-16 16:20:43 -0400
commitbd1a272806e6554c54959f2b46f6d40c182468c0 (patch)
treed254c7bac34710948cb6250e12b391a442ca2604 /drivers/net/wireless
parent55768fa6d9462c18c1ce3c862db3bf55bac3b1c7 (diff)
parentc6ceb8726f0cee28c6ff1101e6c326e6d86ea749 (diff)
Merge branch 'for-linville' of git://github.com/lucacoelho/wl12xx
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/wl12xx/boot.c4
-rw-r--r--drivers/net/wireless/wl12xx/main.c50
-rw-r--r--drivers/net/wireless/wl12xx/scan.c66
-rw-r--r--drivers/net/wireless/wl12xx/tx.c8
-rw-r--r--drivers/net/wireless/wl12xx/tx.h1
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h3
6 files changed, 103 insertions, 29 deletions
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
index cc70422c057..6d5664bfc37 100644
--- a/drivers/net/wireless/wl12xx/boot.c
+++ b/drivers/net/wireless/wl12xx/boot.c
@@ -294,9 +294,7 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
294 */ 294 */
295 if (wl->nvs_len == sizeof(struct wl1271_nvs_file) || 295 if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
296 wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) { 296 wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
297 /* for now 11a is unsupported in AP mode */ 297 if (nvs->general_params.dual_mode_select)
298 if (wl->bss_type != BSS_TYPE_AP_BSS &&
299 nvs->general_params.dual_mode_select)
300 wl->enable_11a = true; 298 wl->enable_11a = true;
301 } 299 }
302 300
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 82f4408e89a..bde84027ab7 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -236,7 +236,7 @@ static struct conf_drv_settings default_conf = {
236 .ps_poll_recovery_period = 700, 236 .ps_poll_recovery_period = 700,
237 .bet_enable = CONF_BET_MODE_ENABLE, 237 .bet_enable = CONF_BET_MODE_ENABLE,
238 .bet_max_consecutive = 50, 238 .bet_max_consecutive = 50,
239 .psm_entry_retries = 5, 239 .psm_entry_retries = 8,
240 .psm_exit_retries = 16, 240 .psm_exit_retries = 16,
241 .psm_entry_nullfunc_retries = 3, 241 .psm_entry_nullfunc_retries = 3,
242 .psm_entry_hangover_period = 1, 242 .psm_entry_hangover_period = 1,
@@ -2064,6 +2064,7 @@ deinit:
2064 wl->session_counter = 0; 2064 wl->session_counter = 0;
2065 wl->rate_set = CONF_TX_RATE_MASK_BASIC; 2065 wl->rate_set = CONF_TX_RATE_MASK_BASIC;
2066 wl->vif = NULL; 2066 wl->vif = NULL;
2067 wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
2067 wl1271_free_ap_keys(wl); 2068 wl1271_free_ap_keys(wl);
2068 memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map)); 2069 memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map));
2069 wl->ap_fw_ps_map = 0; 2070 wl->ap_fw_ps_map = 0;
@@ -2199,10 +2200,14 @@ out:
2199 2200
2200static void wl1271_set_band_rate(struct wl1271 *wl) 2201static void wl1271_set_band_rate(struct wl1271 *wl)
2201{ 2202{
2202 if (wl->band == IEEE80211_BAND_2GHZ) 2203 if (wl->band == IEEE80211_BAND_2GHZ) {
2203 wl->basic_rate_set = wl->conf.tx.basic_rate; 2204 wl->basic_rate_set = wl->conf.tx.basic_rate;
2204 else 2205 wl->rate_set = wl->conf.tx.basic_rate;
2206 } else {
2205 wl->basic_rate_set = wl->conf.tx.basic_rate_5; 2207 wl->basic_rate_set = wl->conf.tx.basic_rate_5;
2208 wl->rate_set = wl->conf.tx.basic_rate_5;
2209 }
2210
2206} 2211}
2207 2212
2208static bool wl12xx_is_roc(struct wl1271 *wl) 2213static bool wl12xx_is_roc(struct wl1271 *wl)
@@ -2653,6 +2658,17 @@ static int wl1271_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
2653 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 2658 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2654 }; 2659 };
2655 2660
2661 /*
2662 * A STA set to GEM cipher requires 2 tx spare blocks.
2663 * Return to default value when GEM cipher key is removed
2664 */
2665 if (key_type == KEY_GEM) {
2666 if (action == KEY_ADD_OR_REPLACE)
2667 wl->tx_spare_blocks = 2;
2668 else if (action == KEY_REMOVE)
2669 wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
2670 }
2671
2656 addr = sta ? sta->addr : bcast_addr; 2672 addr = sta ? sta->addr : bcast_addr;
2657 2673
2658 if (is_zero_ether_addr(addr)) { 2674 if (is_zero_ether_addr(addr)) {
@@ -3345,19 +3361,6 @@ sta_not_found:
3345 ret = wl1271_acx_conn_monit_params(wl, true); 3361 ret = wl1271_acx_conn_monit_params(wl, true);
3346 if (ret < 0) 3362 if (ret < 0)
3347 goto out; 3363 goto out;
3348
3349 /* If we want to go in PSM but we're not there yet */
3350 if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) &&
3351 !test_bit(WL1271_FLAG_PSM, &wl->flags)) {
3352 enum wl1271_cmd_ps_mode mode;
3353
3354 mode = STATION_POWER_SAVE_MODE;
3355 ret = wl1271_ps_set_mode(wl, mode,
3356 wl->basic_rate,
3357 true);
3358 if (ret < 0)
3359 goto out;
3360 }
3361 } else { 3364 } else {
3362 /* use defaults when not associated */ 3365 /* use defaults when not associated */
3363 bool was_assoc = 3366 bool was_assoc =
@@ -3501,6 +3504,19 @@ sta_not_found:
3501 if (ret < 0) 3504 if (ret < 0)
3502 goto out; 3505 goto out;
3503 } 3506 }
3507
3508 /* If we want to go in PSM but we're not there yet */
3509 if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) &&
3510 !test_bit(WL1271_FLAG_PSM, &wl->flags)) {
3511 enum wl1271_cmd_ps_mode mode;
3512
3513 mode = STATION_POWER_SAVE_MODE;
3514 ret = wl1271_ps_set_mode(wl, mode,
3515 wl->basic_rate,
3516 true);
3517 if (ret < 0)
3518 goto out;
3519 }
3504 } 3520 }
3505 3521
3506 /* Handle new association with HT. Do this after join. */ 3522 /* Handle new association with HT. Do this after join. */
@@ -4475,6 +4491,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
4475 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 4491 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4476 BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP); 4492 BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
4477 wl->hw->wiphy->max_scan_ssids = 1; 4493 wl->hw->wiphy->max_scan_ssids = 1;
4494 wl->hw->wiphy->max_sched_scan_ssids = 8;
4478 /* 4495 /*
4479 * Maximum length of elements in scanning probe request templates 4496 * Maximum length of elements in scanning probe request templates
4480 * should be the maximum length possible for a template, without 4497 * should be the maximum length possible for a template, without
@@ -4599,6 +4616,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
4599 wl->sched_scanning = false; 4616 wl->sched_scanning = false;
4600 wl->tx_security_seq = 0; 4617 wl->tx_security_seq = 0;
4601 wl->tx_security_last_seq_lsb = 0; 4618 wl->tx_security_last_seq_lsb = 0;
4619 wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
4602 wl->role_id = WL12XX_INVALID_ROLE_ID; 4620 wl->role_id = WL12XX_INVALID_ROLE_ID;
4603 wl->system_hlid = WL12XX_SYSTEM_HLID; 4621 wl->system_hlid = WL12XX_SYSTEM_HLID;
4604 wl->sta_hlid = WL12XX_INVALID_LINK_ID; 4622 wl->sta_hlid = WL12XX_INVALID_LINK_ID;
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c
index 7229eaa8901..af4ad2353f5 100644
--- a/drivers/net/wireless/wl12xx/scan.c
+++ b/drivers/net/wireless/wl12xx/scan.c
@@ -473,6 +473,51 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl,
473 cfg->passive[2] || cfg->active[2]; 473 cfg->passive[2] || cfg->active[2];
474} 474}
475 475
476/* Returns 0 if no wildcard is used, 1 if wildcard is used or a
477 * negative value on error */
478static int
479wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl,
480 struct cfg80211_sched_scan_request *req)
481{
482 struct wl1271_cmd_sched_scan_ssid_list *cmd = NULL;
483 struct cfg80211_ssid *ssid = req->ssids;
484 int ret, wildcard = 0;
485
486 wl1271_debug(DEBUG_CMD, "cmd sched scan ssid list");
487
488 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
489 if (!cmd)
490 return -ENOMEM;
491
492 while ((cmd->n_ssids < req->n_ssids) && ssid) {
493 if (ssid->ssid_len == 0) {
494 wildcard = 1;
495 cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_PUBLIC;
496 } else {
497 cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_HIDDEN;
498 }
499 cmd->ssids[cmd->n_ssids].len = ssid->ssid_len;
500 memcpy(cmd->ssids[cmd->n_ssids].ssid, ssid->ssid,
501 ssid->ssid_len);
502 ssid++;
503 cmd->n_ssids++;
504 }
505
506 wl1271_dump(DEBUG_SCAN, "SSID_LIST: ", cmd, sizeof(*cmd));
507
508 ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_SSID_CFG, cmd,
509 sizeof(*cmd), 0);
510 if (ret < 0) {
511 wl1271_error("cmd sched scan ssid list failed");
512 goto out;
513 }
514
515 ret = wildcard;
516out:
517 kfree(cmd);
518 return ret;
519}
520
476int wl1271_scan_sched_scan_config(struct wl1271 *wl, 521int wl1271_scan_sched_scan_config(struct wl1271 *wl,
477 struct cfg80211_sched_scan_request *req, 522 struct cfg80211_sched_scan_request *req,
478 struct ieee80211_sched_scan_ies *ies) 523 struct ieee80211_sched_scan_ies *ies)
@@ -504,14 +549,21 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
504 for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++) 549 for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++)
505 cfg->intervals[i] = cpu_to_le32(req->interval); 550 cfg->intervals[i] = cpu_to_le32(req->interval);
506 551
507 if (!force_passive && req->ssids[0].ssid_len && req->ssids[0].ssid) { 552 cfg->ssid_len = 0;
508 cfg->filter_type = SCAN_SSID_FILTER_SPECIFIC; 553 if (req->n_ssids == 0) {
509 cfg->ssid_len = req->ssids[0].ssid_len; 554 wl1271_debug(DEBUG_SCAN, "using SCAN_SSID_FILTER_ANY");
510 memcpy(cfg->ssid, req->ssids[0].ssid,
511 req->ssids[0].ssid_len);
512 } else {
513 cfg->filter_type = SCAN_SSID_FILTER_ANY; 555 cfg->filter_type = SCAN_SSID_FILTER_ANY;
514 cfg->ssid_len = 0; 556 } else {
557 ret = wl12xx_scan_sched_scan_ssid_list(wl, req);
558 if (ret < 0)
559 goto out;
560 if (ret) {
561 wl1271_debug(DEBUG_SCAN, "using SCAN_SSID_FILTER_DISABLED");
562 cfg->filter_type = SCAN_SSID_FILTER_DISABLED;
563 } else {
564 wl1271_debug(DEBUG_SCAN, "using SCAN_SSID_FILTER_LIST");
565 cfg->filter_type = SCAN_SSID_FILTER_LIST;
566 }
515 } 567 }
516 568
517 if (!wl1271_scan_sched_scan_channels(wl, req, cfg)) { 569 if (!wl1271_scan_sched_scan_channels(wl, req, cfg)) {
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index 0f1578577b1..08227e69616 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -204,9 +204,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
204 u32 len; 204 u32 len;
205 u32 total_blocks; 205 u32 total_blocks;
206 int id, ret = -EBUSY, ac; 206 int id, ret = -EBUSY, ac;
207 207 u32 spare_blocks = wl->tx_spare_blocks;
208 /* we use 1 spare block */
209 u32 spare_blocks = 1;
210 208
211 if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) 209 if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE)
212 return -EAGAIN; 210 return -EAGAIN;
@@ -220,6 +218,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
220 in the firmware */ 218 in the firmware */
221 len = wl12xx_calc_packet_alignment(wl, total_len); 219 len = wl12xx_calc_packet_alignment(wl, total_len);
222 220
221 /* in case of a dummy packet, use default amount of spare mem blocks */
222 if (unlikely(wl12xx_is_dummy_packet(wl, skb)))
223 spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
224
223 total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE + 225 total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE +
224 spare_blocks; 226 spare_blocks;
225 227
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h
index 7da35c0e411..6519be4b2c3 100644
--- a/drivers/net/wireless/wl12xx/tx.h
+++ b/drivers/net/wireless/wl12xx/tx.h
@@ -25,6 +25,7 @@
25#ifndef __TX_H__ 25#ifndef __TX_H__
26#define __TX_H__ 26#define __TX_H__
27 27
28#define TX_HW_BLOCK_SPARE_DEFAULT 1
28#define TX_HW_BLOCK_SIZE 252 29#define TX_HW_BLOCK_SIZE 252
29 30
30#define TX_HW_MGMT_PKT_LIFETIME_TU 2000 31#define TX_HW_MGMT_PKT_LIFETIME_TU 2000
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 61a7c2163ea..fb2753c4630 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -425,6 +425,9 @@ struct wl1271 {
425 u32 tx_allocated_blocks; 425 u32 tx_allocated_blocks;
426 u32 tx_results_count; 426 u32 tx_results_count;
427 427
428 /* amount of spare TX blocks to use */
429 u32 tx_spare_blocks;
430
428 /* Accounting for allocated / available Tx packets in HW */ 431 /* Accounting for allocated / available Tx packets in HW */
429 u32 tx_pkts_freed[NUM_TX_QUEUES]; 432 u32 tx_pkts_freed[NUM_TX_QUEUES];
430 u32 tx_allocated_pkts[NUM_TX_QUEUES]; 433 u32 tx_allocated_pkts[NUM_TX_QUEUES];