diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-09-16 16:20:43 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-09-16 16:20:43 -0400 |
commit | bd1a272806e6554c54959f2b46f6d40c182468c0 (patch) | |
tree | d254c7bac34710948cb6250e12b391a442ca2604 | |
parent | 55768fa6d9462c18c1ce3c862db3bf55bac3b1c7 (diff) | |
parent | c6ceb8726f0cee28c6ff1101e6c326e6d86ea749 (diff) |
Merge branch 'for-linville' of git://github.com/lucacoelho/wl12xx
-rw-r--r-- | drivers/net/wireless/wl12xx/boot.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 50 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/scan.c | 66 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl12xx.h | 3 |
6 files changed, 103 insertions, 29 deletions
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index cc70422c0575..6d5664bfc37d 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 82f4408e89ad..bde84027ab7f 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 | ||
2200 | static void wl1271_set_band_rate(struct wl1271 *wl) | 2201 | static 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 | ||
2208 | static bool wl12xx_is_roc(struct wl1271 *wl) | 2213 | static 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 7229eaa89018..af4ad2353f59 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 */ | ||
478 | static int | ||
479 | wl12xx_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; | ||
516 | out: | ||
517 | kfree(cmd); | ||
518 | return ret; | ||
519 | } | ||
520 | |||
476 | int wl1271_scan_sched_scan_config(struct wl1271 *wl, | 521 | int 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 0f1578577b1a..08227e69616b 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 7da35c0e411b..6519be4b2c38 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 61a7c2163ea2..fb2753c46300 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]; |