diff options
Diffstat (limited to 'drivers/net/wireless/wl12xx/main.c')
| -rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 143 |
1 files changed, 69 insertions, 74 deletions
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 254b7daccee1..61dea73f5fdc 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
| @@ -256,6 +256,7 @@ static struct conf_drv_settings default_conf = { | |||
| 256 | .bet_enable = CONF_BET_MODE_ENABLE, | 256 | .bet_enable = CONF_BET_MODE_ENABLE, |
| 257 | .bet_max_consecutive = 10, | 257 | .bet_max_consecutive = 10, |
| 258 | .psm_entry_retries = 5, | 258 | .psm_entry_retries = 5, |
| 259 | .psm_exit_retries = 255, | ||
| 259 | .psm_entry_nullfunc_retries = 3, | 260 | .psm_entry_nullfunc_retries = 3, |
| 260 | .psm_entry_hangover_period = 1, | 261 | .psm_entry_hangover_period = 1, |
| 261 | .keep_alive_interval = 55000, | 262 | .keep_alive_interval = 55000, |
| @@ -297,6 +298,16 @@ static struct conf_drv_settings default_conf = { | |||
| 297 | .tx_ba_win_size = 64, | 298 | .tx_ba_win_size = 64, |
| 298 | .inactivity_timeout = 10000, | 299 | .inactivity_timeout = 10000, |
| 299 | }, | 300 | }, |
| 301 | .mem = { | ||
| 302 | .num_stations = 1, | ||
| 303 | .ssid_profiles = 1, | ||
| 304 | .rx_block_num = 70, | ||
| 305 | .tx_min_block_num = 40, | ||
| 306 | .dynamic_memory = 0, | ||
| 307 | .min_req_tx_blocks = 104, | ||
| 308 | .min_req_rx_blocks = 22, | ||
| 309 | .tx_min = 27, | ||
| 310 | } | ||
| 300 | }; | 311 | }; |
| 301 | 312 | ||
| 302 | static void __wl1271_op_remove_interface(struct wl1271 *wl); | 313 | static void __wl1271_op_remove_interface(struct wl1271 *wl); |
| @@ -523,13 +534,19 @@ static int wl1271_plt_init(struct wl1271 *wl) | |||
| 523 | } | 534 | } |
| 524 | 535 | ||
| 525 | static void wl1271_fw_status(struct wl1271 *wl, | 536 | static void wl1271_fw_status(struct wl1271 *wl, |
| 526 | struct wl1271_fw_status *status) | 537 | struct wl1271_fw_full_status *full_status) |
| 527 | { | 538 | { |
| 539 | struct wl1271_fw_common_status *status = &full_status->common; | ||
| 528 | struct timespec ts; | 540 | struct timespec ts; |
| 529 | u32 total = 0; | 541 | u32 total = 0; |
| 530 | int i; | 542 | int i; |
| 531 | 543 | ||
| 532 | wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false); | 544 | if (wl->bss_type == BSS_TYPE_AP_BSS) |
| 545 | wl1271_raw_read(wl, FW_STATUS_ADDR, status, | ||
| 546 | sizeof(struct wl1271_fw_ap_status), false); | ||
| 547 | else | ||
| 548 | wl1271_raw_read(wl, FW_STATUS_ADDR, status, | ||
| 549 | sizeof(struct wl1271_fw_sta_status), false); | ||
| 533 | 550 | ||
| 534 | wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " | 551 | wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " |
| 535 | "drv_rx_counter = %d, tx_results_counter = %d)", | 552 | "drv_rx_counter = %d, tx_results_counter = %d)", |
| @@ -588,7 +605,7 @@ static void wl1271_irq_work(struct work_struct *work) | |||
| 588 | loopcount--; | 605 | loopcount--; |
| 589 | 606 | ||
| 590 | wl1271_fw_status(wl, wl->fw_status); | 607 | wl1271_fw_status(wl, wl->fw_status); |
| 591 | intr = le32_to_cpu(wl->fw_status->intr); | 608 | intr = le32_to_cpu(wl->fw_status->common.intr); |
| 592 | if (!intr) { | 609 | if (!intr) { |
| 593 | wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); | 610 | wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); |
| 594 | spin_lock_irqsave(&wl->wl_lock, flags); | 611 | spin_lock_irqsave(&wl->wl_lock, flags); |
| @@ -610,7 +627,7 @@ static void wl1271_irq_work(struct work_struct *work) | |||
| 610 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); | 627 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); |
| 611 | 628 | ||
| 612 | /* check for tx results */ | 629 | /* check for tx results */ |
| 613 | if (wl->fw_status->tx_results_counter != | 630 | if (wl->fw_status->common.tx_results_counter != |
| 614 | (wl->tx_results_count & 0xff)) | 631 | (wl->tx_results_count & 0xff)) |
| 615 | wl1271_tx_complete(wl); | 632 | wl1271_tx_complete(wl); |
| 616 | 633 | ||
| @@ -624,7 +641,7 @@ static void wl1271_irq_work(struct work_struct *work) | |||
| 624 | wl1271_tx_work_locked(wl); | 641 | wl1271_tx_work_locked(wl); |
| 625 | } | 642 | } |
| 626 | 643 | ||
| 627 | wl1271_rx(wl, wl->fw_status); | 644 | wl1271_rx(wl, &wl->fw_status->common); |
| 628 | } | 645 | } |
| 629 | 646 | ||
| 630 | if (intr & WL1271_ACX_INTR_EVENT_A) { | 647 | if (intr & WL1271_ACX_INTR_EVENT_A) { |
| @@ -961,39 +978,10 @@ int wl1271_plt_stop(struct wl1271 *wl) | |||
| 961 | static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 978 | static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
| 962 | { | 979 | { |
| 963 | struct wl1271 *wl = hw->priv; | 980 | struct wl1271 *wl = hw->priv; |
| 964 | struct ieee80211_conf *conf = &hw->conf; | ||
| 965 | struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); | ||
| 966 | struct ieee80211_sta *sta = txinfo->control.sta; | ||
| 967 | unsigned long flags; | 981 | unsigned long flags; |
| 968 | int q; | 982 | int q; |
| 969 | 983 | ||
| 970 | /* | ||
| 971 | * peek into the rates configured in the STA entry. | ||
| 972 | * The rates set after connection stage, The first block only BG sets: | ||
| 973 | * the compare is for bit 0-16 of sta_rate_set. The second block add | ||
| 974 | * HT rates in case of HT supported. | ||
| 975 | */ | ||
| 976 | spin_lock_irqsave(&wl->wl_lock, flags); | 984 | spin_lock_irqsave(&wl->wl_lock, flags); |
| 977 | if (sta && | ||
| 978 | (sta->supp_rates[conf->channel->band] != | ||
| 979 | (wl->sta_rate_set & HW_BG_RATES_MASK)) && | ||
| 980 | wl->bss_type != BSS_TYPE_AP_BSS) { | ||
| 981 | wl->sta_rate_set = sta->supp_rates[conf->channel->band]; | ||
| 982 | set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); | ||
| 983 | } | ||
| 984 | |||
| 985 | #ifdef CONFIG_WL12XX_HT | ||
| 986 | if (sta && | ||
| 987 | sta->ht_cap.ht_supported && | ||
| 988 | ((wl->sta_rate_set >> HW_HT_RATES_OFFSET) != | ||
| 989 | sta->ht_cap.mcs.rx_mask[0])) { | ||
| 990 | /* Clean MCS bits before setting them */ | ||
| 991 | wl->sta_rate_set &= HW_BG_RATES_MASK; | ||
| 992 | wl->sta_rate_set |= | ||
| 993 | (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET); | ||
| 994 | set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); | ||
| 995 | } | ||
| 996 | #endif | ||
| 997 | wl->tx_queue_count++; | 985 | wl->tx_queue_count++; |
| 998 | spin_unlock_irqrestore(&wl->wl_lock, flags); | 986 | spin_unlock_irqrestore(&wl->wl_lock, flags); |
| 999 | 987 | ||
| @@ -1228,7 +1216,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) | |||
| 1228 | wl->time_offset = 0; | 1216 | wl->time_offset = 0; |
| 1229 | wl->session_counter = 0; | 1217 | wl->session_counter = 0; |
| 1230 | wl->rate_set = CONF_TX_RATE_MASK_BASIC; | 1218 | wl->rate_set = CONF_TX_RATE_MASK_BASIC; |
| 1231 | wl->sta_rate_set = 0; | ||
| 1232 | wl->flags = 0; | 1219 | wl->flags = 0; |
| 1233 | wl->vif = NULL; | 1220 | wl->vif = NULL; |
| 1234 | wl->filters = 0; | 1221 | wl->filters = 0; |
| @@ -1415,7 +1402,6 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle) | |||
| 1415 | goto out; | 1402 | goto out; |
| 1416 | } | 1403 | } |
| 1417 | wl->rate_set = wl1271_tx_min_rate_get(wl); | 1404 | wl->rate_set = wl1271_tx_min_rate_get(wl); |
| 1418 | wl->sta_rate_set = 0; | ||
| 1419 | ret = wl1271_acx_sta_rate_policies(wl); | 1405 | ret = wl1271_acx_sta_rate_policies(wl); |
| 1420 | if (ret < 0) | 1406 | if (ret < 0) |
| 1421 | goto out; | 1407 | goto out; |
| @@ -2229,6 +2215,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, | |||
| 2229 | { | 2215 | { |
| 2230 | bool do_join = false, set_assoc = false; | 2216 | bool do_join = false, set_assoc = false; |
| 2231 | bool is_ibss = (wl->bss_type == BSS_TYPE_IBSS); | 2217 | bool is_ibss = (wl->bss_type == BSS_TYPE_IBSS); |
| 2218 | u32 sta_rate_set = 0; | ||
| 2232 | int ret; | 2219 | int ret; |
| 2233 | struct ieee80211_sta *sta; | 2220 | struct ieee80211_sta *sta; |
| 2234 | 2221 | ||
| @@ -2294,6 +2281,49 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, | |||
| 2294 | } | 2281 | } |
| 2295 | } | 2282 | } |
| 2296 | 2283 | ||
| 2284 | rcu_read_lock(); | ||
| 2285 | sta = ieee80211_find_sta(vif, bss_conf->bssid); | ||
| 2286 | if (sta) { | ||
| 2287 | /* save the supp_rates of the ap */ | ||
| 2288 | sta_rate_set = sta->supp_rates[wl->hw->conf.channel->band]; | ||
| 2289 | if (sta->ht_cap.ht_supported) | ||
| 2290 | sta_rate_set |= | ||
| 2291 | (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET); | ||
| 2292 | |||
| 2293 | /* handle new association with HT and HT information change */ | ||
| 2294 | if ((changed & BSS_CHANGED_HT) && | ||
| 2295 | (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { | ||
| 2296 | ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, | ||
| 2297 | true); | ||
| 2298 | if (ret < 0) { | ||
| 2299 | wl1271_warning("Set ht cap true failed %d", | ||
| 2300 | ret); | ||
| 2301 | rcu_read_unlock(); | ||
| 2302 | goto out; | ||
| 2303 | } | ||
| 2304 | ret = wl1271_acx_set_ht_information(wl, | ||
| 2305 | bss_conf->ht_operation_mode); | ||
| 2306 | if (ret < 0) { | ||
| 2307 | wl1271_warning("Set ht information failed %d", | ||
| 2308 | ret); | ||
| 2309 | rcu_read_unlock(); | ||
| 2310 | goto out; | ||
| 2311 | } | ||
| 2312 | } | ||
| 2313 | /* handle new association without HT and disassociation */ | ||
| 2314 | else if (changed & BSS_CHANGED_ASSOC) { | ||
| 2315 | ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, | ||
| 2316 | false); | ||
| 2317 | if (ret < 0) { | ||
| 2318 | wl1271_warning("Set ht cap false failed %d", | ||
| 2319 | ret); | ||
| 2320 | rcu_read_unlock(); | ||
| 2321 | goto out; | ||
| 2322 | } | ||
| 2323 | } | ||
| 2324 | } | ||
| 2325 | rcu_read_unlock(); | ||
| 2326 | |||
| 2297 | if ((changed & BSS_CHANGED_ASSOC)) { | 2327 | if ((changed & BSS_CHANGED_ASSOC)) { |
| 2298 | if (bss_conf->assoc) { | 2328 | if (bss_conf->assoc) { |
| 2299 | u32 rates; | 2329 | u32 rates; |
| @@ -2311,6 +2341,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, | |||
| 2311 | wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, | 2341 | wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, |
| 2312 | rates); | 2342 | rates); |
| 2313 | wl->basic_rate = wl1271_tx_min_rate_get(wl); | 2343 | wl->basic_rate = wl1271_tx_min_rate_get(wl); |
| 2344 | if (sta_rate_set) | ||
| 2345 | wl->rate_set = wl1271_tx_enabled_rates_get(wl, | ||
| 2346 | sta_rate_set); | ||
| 2314 | ret = wl1271_acx_sta_rate_policies(wl); | 2347 | ret = wl1271_acx_sta_rate_policies(wl); |
| 2315 | if (ret < 0) | 2348 | if (ret < 0) |
| 2316 | goto out; | 2349 | goto out; |
| @@ -2389,43 +2422,6 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, | |||
| 2389 | if (ret < 0) | 2422 | if (ret < 0) |
| 2390 | goto out; | 2423 | goto out; |
| 2391 | 2424 | ||
| 2392 | rcu_read_lock(); | ||
| 2393 | sta = ieee80211_find_sta(vif, bss_conf->bssid); | ||
| 2394 | if (sta) { | ||
| 2395 | /* handle new association with HT and HT information change */ | ||
| 2396 | if ((changed & BSS_CHANGED_HT) && | ||
| 2397 | (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { | ||
| 2398 | ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, | ||
| 2399 | true); | ||
| 2400 | if (ret < 0) { | ||
| 2401 | wl1271_warning("Set ht cap true failed %d", | ||
| 2402 | ret); | ||
| 2403 | rcu_read_unlock(); | ||
| 2404 | goto out; | ||
| 2405 | } | ||
| 2406 | ret = wl1271_acx_set_ht_information(wl, | ||
| 2407 | bss_conf->ht_operation_mode); | ||
| 2408 | if (ret < 0) { | ||
| 2409 | wl1271_warning("Set ht information failed %d", | ||
| 2410 | ret); | ||
| 2411 | rcu_read_unlock(); | ||
| 2412 | goto out; | ||
| 2413 | } | ||
| 2414 | } | ||
| 2415 | /* handle new association without HT and disassociation */ | ||
| 2416 | else if (changed & BSS_CHANGED_ASSOC) { | ||
| 2417 | ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, | ||
| 2418 | false); | ||
| 2419 | if (ret < 0) { | ||
| 2420 | wl1271_warning("Set ht cap false failed %d", | ||
| 2421 | ret); | ||
| 2422 | rcu_read_unlock(); | ||
| 2423 | goto out; | ||
| 2424 | } | ||
| 2425 | } | ||
| 2426 | } | ||
| 2427 | rcu_read_unlock(); | ||
| 2428 | |||
| 2429 | if (changed & BSS_CHANGED_ARP_FILTER) { | 2425 | if (changed & BSS_CHANGED_ARP_FILTER) { |
| 2430 | __be32 addr = bss_conf->arp_addr_list[0]; | 2426 | __be32 addr = bss_conf->arp_addr_list[0]; |
| 2431 | WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); | 2427 | WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); |
| @@ -3313,7 +3309,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void) | |||
| 3313 | wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC; | 3309 | wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC; |
| 3314 | wl->basic_rate = CONF_TX_RATE_MASK_BASIC; | 3310 | wl->basic_rate = CONF_TX_RATE_MASK_BASIC; |
| 3315 | wl->rate_set = CONF_TX_RATE_MASK_BASIC; | 3311 | wl->rate_set = CONF_TX_RATE_MASK_BASIC; |
| 3316 | wl->sta_rate_set = 0; | ||
| 3317 | wl->band = IEEE80211_BAND_2GHZ; | 3312 | wl->band = IEEE80211_BAND_2GHZ; |
| 3318 | wl->vif = NULL; | 3313 | wl->vif = NULL; |
| 3319 | wl->flags = 0; | 3314 | wl->flags = 0; |
