aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx/main.c')
-rw-r--r--drivers/net/wireless/wl12xx/main.c143
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
302static void __wl1271_op_remove_interface(struct wl1271 *wl); 313static void __wl1271_op_remove_interface(struct wl1271 *wl);
@@ -523,13 +534,19 @@ static int wl1271_plt_init(struct wl1271 *wl)
523} 534}
524 535
525static void wl1271_fw_status(struct wl1271 *wl, 536static 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)
961static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 978static 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;