diff options
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_acx.c | 25 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_acx.h | 68 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_boot.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_cmd.c | 218 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_cmd.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_conf.h | 330 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_debugfs.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_event.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_init.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_io.h | 13 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_main.c | 496 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_sdio.c | 74 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_spi.c | 35 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_tx.h | 3 |
15 files changed, 748 insertions, 559 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index 0deb4fdf916b..8f11506f8310 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h | |||
@@ -53,6 +53,8 @@ enum { | |||
53 | DEBUG_MAC80211 = BIT(11), | 53 | DEBUG_MAC80211 = BIT(11), |
54 | DEBUG_CMD = BIT(12), | 54 | DEBUG_CMD = BIT(12), |
55 | DEBUG_ACX = BIT(13), | 55 | DEBUG_ACX = BIT(13), |
56 | DEBUG_SDIO = BIT(14), | ||
57 | DEBUG_FILTERS = BIT(15), | ||
56 | DEBUG_ALL = ~0, | 58 | DEBUG_ALL = ~0, |
57 | }; | 59 | }; |
58 | 60 | ||
@@ -344,12 +346,14 @@ struct wl1271_if_operations { | |||
344 | bool fixed); | 346 | bool fixed); |
345 | void (*reset)(struct wl1271 *wl); | 347 | void (*reset)(struct wl1271 *wl); |
346 | void (*init)(struct wl1271 *wl); | 348 | void (*init)(struct wl1271 *wl); |
349 | void (*power)(struct wl1271 *wl, bool enable); | ||
347 | struct device* (*dev)(struct wl1271 *wl); | 350 | struct device* (*dev)(struct wl1271 *wl); |
348 | void (*enable_irq)(struct wl1271 *wl); | 351 | void (*enable_irq)(struct wl1271 *wl); |
349 | void (*disable_irq)(struct wl1271 *wl); | 352 | void (*disable_irq)(struct wl1271 *wl); |
350 | }; | 353 | }; |
351 | 354 | ||
352 | struct wl1271 { | 355 | struct wl1271 { |
356 | struct platform_device *plat_dev; | ||
353 | struct ieee80211_hw *hw; | 357 | struct ieee80211_hw *hw; |
354 | bool mac80211_registered; | 358 | bool mac80211_registered; |
355 | 359 | ||
@@ -456,6 +460,7 @@ struct wl1271 { | |||
456 | /* Default key (for WEP) */ | 460 | /* Default key (for WEP) */ |
457 | u32 default_key; | 461 | u32 default_key; |
458 | 462 | ||
463 | unsigned int filters; | ||
459 | unsigned int rx_config; | 464 | unsigned int rx_config; |
460 | unsigned int rx_filter; | 465 | unsigned int rx_filter; |
461 | 466 | ||
@@ -483,6 +488,8 @@ struct wl1271 { | |||
483 | /* Current chipset configuration */ | 488 | /* Current chipset configuration */ |
484 | struct conf_drv_settings conf; | 489 | struct conf_drv_settings conf; |
485 | 490 | ||
491 | bool sg_enabled; | ||
492 | |||
486 | struct list_head list; | 493 | struct list_head list; |
487 | }; | 494 | }; |
488 | 495 | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c index 60e20876e6d8..7e337cea9905 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.c +++ b/drivers/net/wireless/wl12xx/wl1271_acx.c | |||
@@ -534,7 +534,7 @@ out: | |||
534 | } | 534 | } |
535 | 535 | ||
536 | 536 | ||
537 | int wl1271_acx_sg_enable(struct wl1271 *wl) | 537 | int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable) |
538 | { | 538 | { |
539 | struct acx_bt_wlan_coex *pta; | 539 | struct acx_bt_wlan_coex *pta; |
540 | int ret; | 540 | int ret; |
@@ -547,7 +547,10 @@ int wl1271_acx_sg_enable(struct wl1271 *wl) | |||
547 | goto out; | 547 | goto out; |
548 | } | 548 | } |
549 | 549 | ||
550 | pta->enable = SG_ENABLE; | 550 | if (enable) |
551 | pta->enable = wl->conf.sg.state; | ||
552 | else | ||
553 | pta->enable = CONF_SG_DISABLE; | ||
551 | 554 | ||
552 | ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta)); | 555 | ret = wl1271_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta)); |
553 | if (ret < 0) { | 556 | if (ret < 0) { |
@@ -564,7 +567,7 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl) | |||
564 | { | 567 | { |
565 | struct acx_bt_wlan_coex_param *param; | 568 | struct acx_bt_wlan_coex_param *param; |
566 | struct conf_sg_settings *c = &wl->conf.sg; | 569 | struct conf_sg_settings *c = &wl->conf.sg; |
567 | int ret; | 570 | int i, ret; |
568 | 571 | ||
569 | wl1271_debug(DEBUG_ACX, "acx sg cfg"); | 572 | wl1271_debug(DEBUG_ACX, "acx sg cfg"); |
570 | 573 | ||
@@ -575,19 +578,9 @@ int wl1271_acx_sg_cfg(struct wl1271 *wl) | |||
575 | } | 578 | } |
576 | 579 | ||
577 | /* BT-WLAN coext parameters */ | 580 | /* BT-WLAN coext parameters */ |
578 | param->per_threshold = cpu_to_le32(c->per_threshold); | 581 | for (i = 0; i < CONF_SG_PARAMS_MAX; i++) |
579 | param->max_scan_compensation_time = | 582 | param->params[i] = c->params[i]; |
580 | cpu_to_le32(c->max_scan_compensation_time); | 583 | param->param_idx = CONF_SG_PARAMS_ALL; |
581 | param->nfs_sample_interval = cpu_to_le16(c->nfs_sample_interval); | ||
582 | param->load_ratio = c->load_ratio; | ||
583 | param->auto_ps_mode = c->auto_ps_mode; | ||
584 | param->probe_req_compensation = c->probe_req_compensation; | ||
585 | param->scan_window_compensation = c->scan_window_compensation; | ||
586 | param->antenna_config = c->antenna_config; | ||
587 | param->beacon_miss_threshold = c->beacon_miss_threshold; | ||
588 | param->rate_adaptation_threshold = | ||
589 | cpu_to_le32(c->rate_adaptation_threshold); | ||
590 | param->rate_adaptation_snr = c->rate_adaptation_snr; | ||
591 | 584 | ||
592 | ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param)); | 585 | ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param)); |
593 | if (ret < 0) { | 586 | if (ret < 0) { |
diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h index aeccc98581eb..8e5870fa9609 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.h +++ b/drivers/net/wireless/wl12xx/wl1271_acx.h | |||
@@ -392,81 +392,27 @@ struct acx_conn_monit_params { | |||
392 | __le32 bss_lose_timeout; /* number of TU's from synch fail */ | 392 | __le32 bss_lose_timeout; /* number of TU's from synch fail */ |
393 | } __attribute__ ((packed)); | 393 | } __attribute__ ((packed)); |
394 | 394 | ||
395 | enum { | ||
396 | SG_ENABLE = 0, | ||
397 | SG_DISABLE, | ||
398 | SG_SENSE_NO_ACTIVITY, | ||
399 | SG_SENSE_ACTIVE | ||
400 | }; | ||
401 | |||
402 | struct acx_bt_wlan_coex { | 395 | struct acx_bt_wlan_coex { |
403 | struct acx_header header; | 396 | struct acx_header header; |
404 | 397 | ||
405 | /* | ||
406 | * 0 -> PTA enabled | ||
407 | * 1 -> PTA disabled | ||
408 | * 2 -> sense no active mode, i.e. | ||
409 | * an interrupt is sent upon | ||
410 | * BT activity. | ||
411 | * 3 -> PTA is switched on in response | ||
412 | * to the interrupt sending. | ||
413 | */ | ||
414 | u8 enable; | 398 | u8 enable; |
415 | u8 pad[3]; | 399 | u8 pad[3]; |
416 | } __attribute__ ((packed)); | 400 | } __attribute__ ((packed)); |
417 | 401 | ||
418 | struct acx_dco_itrim_params { | 402 | struct acx_bt_wlan_coex_param { |
419 | struct acx_header header; | 403 | struct acx_header header; |
420 | 404 | ||
421 | u8 enable; | 405 | __le32 params[CONF_SG_PARAMS_MAX]; |
406 | u8 param_idx; | ||
422 | u8 padding[3]; | 407 | u8 padding[3]; |
423 | __le32 timeout; | ||
424 | } __attribute__ ((packed)); | 408 | } __attribute__ ((packed)); |
425 | 409 | ||
426 | #define PTA_ANTENNA_TYPE_DEF (0) | 410 | struct acx_dco_itrim_params { |
427 | #define PTA_BT_HP_MAXTIME_DEF (2000) | ||
428 | #define PTA_WLAN_HP_MAX_TIME_DEF (5000) | ||
429 | #define PTA_SENSE_DISABLE_TIMER_DEF (1350) | ||
430 | #define PTA_PROTECTIVE_RX_TIME_DEF (1500) | ||
431 | #define PTA_PROTECTIVE_TX_TIME_DEF (1500) | ||
432 | #define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000) | ||
433 | #define PTA_SIGNALING_TYPE_DEF (1) | ||
434 | #define PTA_AFH_LEVERAGE_ON_DEF (0) | ||
435 | #define PTA_NUMBER_QUIET_CYCLE_DEF (0) | ||
436 | #define PTA_MAX_NUM_CTS_DEF (3) | ||
437 | #define PTA_NUMBER_OF_WLAN_PACKETS_DEF (2) | ||
438 | #define PTA_NUMBER_OF_BT_PACKETS_DEF (2) | ||
439 | #define PTA_PROTECTIVE_RX_TIME_FAST_DEF (1500) | ||
440 | #define PTA_PROTECTIVE_TX_TIME_FAST_DEF (3000) | ||
441 | #define PTA_CYCLE_TIME_FAST_DEF (8700) | ||
442 | #define PTA_RX_FOR_AVALANCHE_DEF (5) | ||
443 | #define PTA_ELP_HP_DEF (0) | ||
444 | #define PTA_ANTI_STARVE_PERIOD_DEF (500) | ||
445 | #define PTA_ANTI_STARVE_NUM_CYCLE_DEF (4) | ||
446 | #define PTA_ALLOW_PA_SD_DEF (1) | ||
447 | #define PTA_TIME_BEFORE_BEACON_DEF (6300) | ||
448 | #define PTA_HPDM_MAX_TIME_DEF (1600) | ||
449 | #define PTA_TIME_OUT_NEXT_WLAN_DEF (2550) | ||
450 | #define PTA_AUTO_MODE_NO_CTS_DEF (0) | ||
451 | #define PTA_BT_HP_RESPECTED_DEF (3) | ||
452 | #define PTA_WLAN_RX_MIN_RATE_DEF (24) | ||
453 | #define PTA_ACK_MODE_DEF (1) | ||
454 | |||
455 | struct acx_bt_wlan_coex_param { | ||
456 | struct acx_header header; | 411 | struct acx_header header; |
457 | 412 | ||
458 | __le32 per_threshold; | 413 | u8 enable; |
459 | __le32 max_scan_compensation_time; | ||
460 | __le16 nfs_sample_interval; | ||
461 | u8 load_ratio; | ||
462 | u8 auto_ps_mode; | ||
463 | u8 probe_req_compensation; | ||
464 | u8 scan_window_compensation; | ||
465 | u8 antenna_config; | ||
466 | u8 beacon_miss_threshold; | ||
467 | __le32 rate_adaptation_threshold; | ||
468 | s8 rate_adaptation_snr; | ||
469 | u8 padding[3]; | 414 | u8 padding[3]; |
415 | __le32 timeout; | ||
470 | } __attribute__ ((packed)); | 416 | } __attribute__ ((packed)); |
471 | 417 | ||
472 | struct acx_energy_detection { | 418 | struct acx_energy_detection { |
@@ -1059,7 +1005,7 @@ int wl1271_acx_dco_itrim_params(struct wl1271 *wl); | |||
1059 | int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter); | 1005 | int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, bool enable_filter); |
1060 | int wl1271_acx_beacon_filter_table(struct wl1271 *wl); | 1006 | int wl1271_acx_beacon_filter_table(struct wl1271 *wl); |
1061 | int wl1271_acx_conn_monit_params(struct wl1271 *wl); | 1007 | int wl1271_acx_conn_monit_params(struct wl1271 *wl); |
1062 | int wl1271_acx_sg_enable(struct wl1271 *wl); | 1008 | int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable); |
1063 | int wl1271_acx_sg_cfg(struct wl1271 *wl); | 1009 | int wl1271_acx_sg_cfg(struct wl1271 *wl); |
1064 | int wl1271_acx_cca_threshold(struct wl1271 *wl); | 1010 | int wl1271_acx_cca_threshold(struct wl1271 *wl); |
1065 | int wl1271_acx_bcn_dtim_options(struct wl1271 *wl); | 1011 | int wl1271_acx_bcn_dtim_options(struct wl1271 *wl); |
diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c index f88d52e87e82..41c6affbee29 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ b/drivers/net/wireless/wl12xx/wl1271_boot.c | |||
@@ -228,6 +228,14 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) | |||
228 | nvs_len = sizeof(wl->nvs->nvs); | 228 | nvs_len = sizeof(wl->nvs->nvs); |
229 | nvs_ptr = (u8 *)wl->nvs->nvs; | 229 | nvs_ptr = (u8 *)wl->nvs->nvs; |
230 | 230 | ||
231 | /* update current MAC address to NVS */ | ||
232 | nvs_ptr[11] = wl->mac_addr[0]; | ||
233 | nvs_ptr[10] = wl->mac_addr[1]; | ||
234 | nvs_ptr[6] = wl->mac_addr[2]; | ||
235 | nvs_ptr[5] = wl->mac_addr[3]; | ||
236 | nvs_ptr[4] = wl->mac_addr[4]; | ||
237 | nvs_ptr[3] = wl->mac_addr[5]; | ||
238 | |||
231 | /* | 239 | /* |
232 | * Layout before the actual NVS tables: | 240 | * Layout before the actual NVS tables: |
233 | * 1 byte : burst length. | 241 | * 1 byte : burst length. |
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index d59b3830a6a5..d005729e0312 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/crc7.h> | 26 | #include <linux/crc7.h> |
27 | #include <linux/spi/spi.h> | 27 | #include <linux/spi/spi.h> |
28 | #include <linux/etherdevice.h> | 28 | #include <linux/etherdevice.h> |
29 | #include <linux/ieee80211.h> | ||
29 | 30 | ||
30 | #include "wl1271.h" | 31 | #include "wl1271.h" |
31 | #include "wl1271_reg.h" | 32 | #include "wl1271_reg.h" |
@@ -280,15 +281,6 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) | |||
280 | join->rx_filter_options = cpu_to_le32(wl->rx_filter); | 281 | join->rx_filter_options = cpu_to_le32(wl->rx_filter); |
281 | join->bss_type = bss_type; | 282 | join->bss_type = bss_type; |
282 | 283 | ||
283 | /* | ||
284 | * FIXME: disable temporarily all filters because after commit | ||
285 | * 9cef8737 "mac80211: fix managed mode BSSID handling" broke | ||
286 | * association. The filter logic needs to be implemented properly | ||
287 | * and once that is done, this hack can be removed. | ||
288 | */ | ||
289 | join->rx_config_options = cpu_to_le32(0); | ||
290 | join->rx_filter_options = cpu_to_le32(WL1271_DEFAULT_RX_FILTER); | ||
291 | |||
292 | if (wl->band == IEEE80211_BAND_2GHZ) | 284 | if (wl->band == IEEE80211_BAND_2GHZ) |
293 | join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_1MBPS | | 285 | join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_1MBPS | |
294 | CONF_HW_BIT_RATE_2MBPS | | 286 | CONF_HW_BIT_RATE_2MBPS | |
@@ -546,9 +538,9 @@ out: | |||
546 | return ret; | 538 | return ret; |
547 | } | 539 | } |
548 | 540 | ||
549 | int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len, | 541 | int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, |
550 | u8 active_scan, u8 high_prio, u8 band, | 542 | const u8 *ie, size_t ie_len, u8 active_scan, |
551 | u8 probe_requests) | 543 | u8 high_prio, u8 band, u8 probe_requests) |
552 | { | 544 | { |
553 | 545 | ||
554 | struct wl1271_cmd_trigger_scan_to *trigger = NULL; | 546 | struct wl1271_cmd_trigger_scan_to *trigger = NULL; |
@@ -619,12 +611,13 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len, | |||
619 | 611 | ||
620 | params->params.num_channels = j; | 612 | params->params.num_channels = j; |
621 | 613 | ||
622 | if (len && ssid) { | 614 | if (ssid_len && ssid) { |
623 | params->params.ssid_len = len; | 615 | params->params.ssid_len = ssid_len; |
624 | memcpy(params->params.ssid, ssid, len); | 616 | memcpy(params->params.ssid, ssid, ssid_len); |
625 | } | 617 | } |
626 | 618 | ||
627 | ret = wl1271_cmd_build_probe_req(wl, ssid, len, ieee_band); | 619 | ret = wl1271_cmd_build_probe_req(wl, ssid, ssid_len, |
620 | ie, ie_len, ieee_band); | ||
628 | if (ret < 0) { | 621 | if (ret < 0) { |
629 | wl1271_error("PROBE request template failed"); | 622 | wl1271_error("PROBE request template failed"); |
630 | goto out; | 623 | goto out; |
@@ -655,9 +648,9 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len, | |||
655 | wl->scan.active = active_scan; | 648 | wl->scan.active = active_scan; |
656 | wl->scan.high_prio = high_prio; | 649 | wl->scan.high_prio = high_prio; |
657 | wl->scan.probe_requests = probe_requests; | 650 | wl->scan.probe_requests = probe_requests; |
658 | if (len && ssid) { | 651 | if (ssid_len && ssid) { |
659 | wl->scan.ssid_len = len; | 652 | wl->scan.ssid_len = ssid_len; |
660 | memcpy(wl->scan.ssid, ssid, len); | 653 | memcpy(wl->scan.ssid, ssid, ssid_len); |
661 | } else | 654 | } else |
662 | wl->scan.ssid_len = 0; | 655 | wl->scan.ssid_len = 0; |
663 | } | 656 | } |
@@ -714,155 +707,102 @@ out: | |||
714 | return ret; | 707 | return ret; |
715 | } | 708 | } |
716 | 709 | ||
717 | static int wl1271_build_basic_rates(u8 *rates, u8 band) | 710 | int wl1271_cmd_build_null_data(struct wl1271 *wl) |
718 | { | 711 | { |
719 | u8 index = 0; | 712 | struct sk_buff *skb = NULL; |
720 | 713 | int size; | |
721 | if (band == IEEE80211_BAND_2GHZ) { | 714 | void *ptr; |
722 | rates[index++] = | 715 | int ret = -ENOMEM; |
723 | IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; | ||
724 | rates[index++] = | ||
725 | IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; | ||
726 | rates[index++] = | ||
727 | IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB; | ||
728 | rates[index++] = | ||
729 | IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB; | ||
730 | } else if (band == IEEE80211_BAND_5GHZ) { | ||
731 | rates[index++] = | ||
732 | IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB; | ||
733 | rates[index++] = | ||
734 | IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB; | ||
735 | rates[index++] = | ||
736 | IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB; | ||
737 | } else { | ||
738 | wl1271_error("build_basic_rates invalid band: %d", band); | ||
739 | } | ||
740 | 716 | ||
741 | return index; | ||
742 | } | ||
743 | 717 | ||
744 | static int wl1271_build_extended_rates(u8 *rates, u8 band) | 718 | if (wl->bss_type == BSS_TYPE_IBSS) { |
745 | { | 719 | size = sizeof(struct wl12xx_null_data_template); |
746 | u8 index = 0; | 720 | ptr = NULL; |
747 | |||
748 | if (band == IEEE80211_BAND_2GHZ) { | ||
749 | rates[index++] = IEEE80211_OFDM_RATE_6MB; | ||
750 | rates[index++] = IEEE80211_OFDM_RATE_9MB; | ||
751 | rates[index++] = IEEE80211_OFDM_RATE_12MB; | ||
752 | rates[index++] = IEEE80211_OFDM_RATE_18MB; | ||
753 | rates[index++] = IEEE80211_OFDM_RATE_24MB; | ||
754 | rates[index++] = IEEE80211_OFDM_RATE_36MB; | ||
755 | rates[index++] = IEEE80211_OFDM_RATE_48MB; | ||
756 | rates[index++] = IEEE80211_OFDM_RATE_54MB; | ||
757 | } else if (band == IEEE80211_BAND_5GHZ) { | ||
758 | rates[index++] = | ||
759 | IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB; | ||
760 | rates[index++] = | ||
761 | IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB; | ||
762 | rates[index++] = | ||
763 | IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB; | ||
764 | rates[index++] = | ||
765 | IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB; | ||
766 | rates[index++] = | ||
767 | IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB; | ||
768 | rates[index++] = | ||
769 | IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB; | ||
770 | } else { | 721 | } else { |
771 | wl1271_error("build_basic_rates invalid band: %d", band); | 722 | skb = ieee80211_nullfunc_get(wl->hw, wl->vif); |
723 | if (!skb) | ||
724 | goto out; | ||
725 | size = skb->len; | ||
726 | ptr = skb->data; | ||
772 | } | 727 | } |
773 | 728 | ||
774 | return index; | 729 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size); |
775 | } | ||
776 | 730 | ||
777 | int wl1271_cmd_build_null_data(struct wl1271 *wl) | 731 | out: |
778 | { | 732 | dev_kfree_skb(skb); |
779 | struct wl12xx_null_data_template template; | 733 | if (ret) |
780 | 734 | wl1271_warning("cmd buld null data failed %d", ret); | |
781 | if (!is_zero_ether_addr(wl->bssid)) { | ||
782 | memcpy(template.header.da, wl->bssid, ETH_ALEN); | ||
783 | memcpy(template.header.bssid, wl->bssid, ETH_ALEN); | ||
784 | } else { | ||
785 | memset(template.header.da, 0xff, ETH_ALEN); | ||
786 | memset(template.header.bssid, 0xff, ETH_ALEN); | ||
787 | } | ||
788 | |||
789 | memcpy(template.header.sa, wl->mac_addr, ETH_ALEN); | ||
790 | template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | | ||
791 | IEEE80211_STYPE_NULLFUNC | | ||
792 | IEEE80211_FCTL_TODS); | ||
793 | 735 | ||
794 | return wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, &template, | 736 | return ret; |
795 | sizeof(template)); | ||
796 | 737 | ||
797 | } | 738 | } |
798 | 739 | ||
799 | int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid) | 740 | int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid) |
800 | { | 741 | { |
801 | struct wl12xx_ps_poll_template template; | 742 | struct sk_buff *skb; |
802 | 743 | int ret = 0; | |
803 | memcpy(template.bssid, wl->bssid, ETH_ALEN); | ||
804 | memcpy(template.ta, wl->mac_addr, ETH_ALEN); | ||
805 | |||
806 | /* aid in PS-Poll has its two MSBs each set to 1 */ | ||
807 | template.aid = cpu_to_le16(1 << 15 | 1 << 14 | aid); | ||
808 | 744 | ||
809 | template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); | 745 | skb = ieee80211_pspoll_get(wl->hw, wl->vif); |
746 | if (!skb) | ||
747 | goto out; | ||
810 | 748 | ||
811 | return wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, &template, | 749 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, skb->data, |
812 | sizeof(template)); | 750 | skb->len); |
813 | 751 | ||
752 | out: | ||
753 | dev_kfree_skb(skb); | ||
754 | return ret; | ||
814 | } | 755 | } |
815 | 756 | ||
816 | int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len, | 757 | int wl1271_cmd_build_probe_req(struct wl1271 *wl, |
817 | u8 band) | 758 | const u8 *ssid, size_t ssid_len, |
759 | const u8 *ie, size_t ie_len, u8 band) | ||
818 | { | 760 | { |
819 | struct wl12xx_probe_req_template template; | 761 | struct sk_buff *skb; |
820 | struct wl12xx_ie_rates *rates; | ||
821 | char *ptr; | ||
822 | u16 size; | ||
823 | int ret; | 762 | int ret; |
824 | 763 | ||
825 | ptr = (char *)&template; | 764 | skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, |
826 | size = sizeof(struct ieee80211_header); | 765 | ie, ie_len); |
827 | 766 | if (!skb) { | |
828 | memset(template.header.da, 0xff, ETH_ALEN); | 767 | ret = -ENOMEM; |
829 | memset(template.header.bssid, 0xff, ETH_ALEN); | 768 | goto out; |
830 | memcpy(template.header.sa, wl->mac_addr, ETH_ALEN); | 769 | } |
831 | template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); | 770 | |
832 | 771 | wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); | |
833 | /* IEs */ | ||
834 | /* SSID */ | ||
835 | template.ssid.header.id = WLAN_EID_SSID; | ||
836 | template.ssid.header.len = ssid_len; | ||
837 | if (ssid_len && ssid) | ||
838 | memcpy(template.ssid.ssid, ssid, ssid_len); | ||
839 | size += sizeof(struct wl12xx_ie_header) + ssid_len; | ||
840 | ptr += size; | ||
841 | |||
842 | /* Basic Rates */ | ||
843 | rates = (struct wl12xx_ie_rates *)ptr; | ||
844 | rates->header.id = WLAN_EID_SUPP_RATES; | ||
845 | rates->header.len = wl1271_build_basic_rates(rates->rates, band); | ||
846 | size += sizeof(struct wl12xx_ie_header) + rates->header.len; | ||
847 | ptr += sizeof(struct wl12xx_ie_header) + rates->header.len; | ||
848 | |||
849 | /* Extended rates */ | ||
850 | rates = (struct wl12xx_ie_rates *)ptr; | ||
851 | rates->header.id = WLAN_EID_EXT_SUPP_RATES; | ||
852 | rates->header.len = wl1271_build_extended_rates(rates->rates, band); | ||
853 | size += sizeof(struct wl12xx_ie_header) + rates->header.len; | ||
854 | |||
855 | wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size); | ||
856 | 772 | ||
857 | if (band == IEEE80211_BAND_2GHZ) | 773 | if (band == IEEE80211_BAND_2GHZ) |
858 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, | 774 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, |
859 | &template, size); | 775 | skb->data, skb->len); |
860 | else | 776 | else |
861 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, | 777 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, |
862 | &template, size); | 778 | skb->data, skb->len); |
779 | |||
780 | out: | ||
781 | dev_kfree_skb(skb); | ||
863 | return ret; | 782 | return ret; |
864 | } | 783 | } |
865 | 784 | ||
785 | int wl1271_build_qos_null_data(struct wl1271 *wl) | ||
786 | { | ||
787 | struct ieee80211_qos_hdr template; | ||
788 | |||
789 | memset(&template, 0, sizeof(template)); | ||
790 | |||
791 | memcpy(template.addr1, wl->bssid, ETH_ALEN); | ||
792 | memcpy(template.addr2, wl->mac_addr, ETH_ALEN); | ||
793 | memcpy(template.addr3, wl->bssid, ETH_ALEN); | ||
794 | |||
795 | template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | | ||
796 | IEEE80211_STYPE_QOS_NULLFUNC | | ||
797 | IEEE80211_FCTL_TODS); | ||
798 | |||
799 | /* FIXME: not sure what priority to use here */ | ||
800 | template.qos_ctrl = cpu_to_le16(0); | ||
801 | |||
802 | return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template, | ||
803 | sizeof(template)); | ||
804 | } | ||
805 | |||
866 | int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) | 806 | int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) |
867 | { | 807 | { |
868 | struct wl1271_cmd_set_keys *cmd; | 808 | struct wl1271_cmd_set_keys *cmd; |
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h index 4297205b8d6d..6324bbf36843 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.h +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h | |||
@@ -41,15 +41,17 @@ int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); | |||
41 | int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send); | 41 | int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send); |
42 | int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, | 42 | int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, |
43 | size_t len); | 43 | size_t len); |
44 | int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len, | 44 | int wl1271_cmd_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, |
45 | u8 active_scan, u8 high_prio, u8 band, | 45 | const u8 *ie, size_t ie_len, u8 active_scan, |
46 | u8 probe_requests); | 46 | u8 high_prio, u8 band, u8 probe_requests); |
47 | int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, | 47 | int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, |
48 | void *buf, size_t buf_len); | 48 | void *buf, size_t buf_len); |
49 | int wl1271_cmd_build_null_data(struct wl1271 *wl); | 49 | int wl1271_cmd_build_null_data(struct wl1271 *wl); |
50 | int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid); | 50 | int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid); |
51 | int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len, | 51 | int wl1271_cmd_build_probe_req(struct wl1271 *wl, |
52 | u8 band); | 52 | const u8 *ssid, size_t ssid_len, |
53 | const u8 *ie, size_t ie_len, u8 band); | ||
54 | int wl1271_build_qos_null_data(struct wl1271 *wl); | ||
53 | int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); | 55 | int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id); |
54 | int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, | 56 | int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, |
55 | u8 key_size, const u8 *key, const u8 *addr, | 57 | u8 key_size, const u8 *key, const u8 *addr, |
diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h index 6f9e75cc5640..7fcfe06b1412 100644 --- a/drivers/net/wireless/wl12xx/wl1271_conf.h +++ b/drivers/net/wireless/wl12xx/wl1271_conf.h | |||
@@ -65,110 +65,318 @@ enum { | |||
65 | CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS, | 65 | CONF_HW_RATE_INDEX_MAX = CONF_HW_RATE_INDEX_54MBPS, |
66 | }; | 66 | }; |
67 | 67 | ||
68 | struct conf_sg_settings { | 68 | enum { |
69 | CONF_SG_DISABLE = 0, | ||
70 | CONF_SG_PROTECTIVE, | ||
71 | CONF_SG_OPPORTUNISTIC | ||
72 | }; | ||
73 | |||
74 | enum { | ||
69 | /* | 75 | /* |
70 | * Defines the PER threshold in PPM of the BT voice of which reaching | 76 | * PER threshold in PPM of the BT voice |
71 | * this value will trigger raising the priority of the BT voice by | ||
72 | * the BT IP until next NFS sample interval time as defined in | ||
73 | * nfs_sample_interval. | ||
74 | * | 77 | * |
75 | * Unit: PER value in PPM (parts per million) | 78 | * Range: 0 - 10000000 |
76 | * #Error_packets / #Total_packets | 79 | */ |
80 | CONF_SG_BT_PER_THRESHOLD = 0, | ||
77 | 81 | ||
78 | * Range: u32 | 82 | /* |
83 | * Number of consequent RX_ACTIVE activities to override BT voice | ||
84 | * frames to ensure WLAN connection | ||
85 | * | ||
86 | * Range: 0 - 100 | ||
87 | */ | ||
88 | CONF_SG_HV3_MAX_OVERRIDE, | ||
89 | |||
90 | /* | ||
91 | * Defines the PER threshold of the BT voice | ||
92 | * | ||
93 | * Range: 0 - 65000 | ||
94 | */ | ||
95 | CONF_SG_BT_NFS_SAMPLE_INTERVAL, | ||
96 | |||
97 | /* | ||
98 | * Defines the load ratio of BT | ||
99 | * | ||
100 | * Range: 0 - 100 (%) | ||
101 | */ | ||
102 | CONF_SG_BT_LOAD_RATIO, | ||
103 | |||
104 | /* | ||
105 | * Defines whether the SG will force WLAN host to enter/exit PSM | ||
106 | * | ||
107 | * Range: 1 - SG can force, 0 - host handles PSM | ||
108 | */ | ||
109 | CONF_SG_AUTO_PS_MODE, | ||
110 | |||
111 | /* | ||
112 | * Compensation percentage of probe requests when scan initiated | ||
113 | * during BT voice/ACL link. | ||
114 | * | ||
115 | * Range: 0 - 255 (%) | ||
116 | */ | ||
117 | CONF_SG_AUTO_SCAN_PROBE_REQ, | ||
118 | |||
119 | /* | ||
120 | * Compensation percentage of probe requests when active scan initiated | ||
121 | * during BT voice | ||
122 | * | ||
123 | * Range: 0 - 255 (%) | ||
124 | */ | ||
125 | CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3, | ||
126 | |||
127 | /* | ||
128 | * Defines antenna configuration (single/dual antenna) | ||
129 | * | ||
130 | * Range: 0 - single antenna, 1 - dual antenna | ||
131 | */ | ||
132 | CONF_SG_ANTENNA_CONFIGURATION, | ||
133 | |||
134 | /* | ||
135 | * The threshold (percent) of max consequtive beacon misses before | ||
136 | * increasing priority of beacon reception. | ||
137 | * | ||
138 | * Range: 0 - 100 (%) | ||
139 | */ | ||
140 | CONF_SG_BEACON_MISS_PERCENT, | ||
141 | |||
142 | /* | ||
143 | * The rate threshold below which receiving a data frame from the AP | ||
144 | * will increase the priority of the data frame above BT traffic. | ||
145 | * | ||
146 | * Range: 0,2, 5(=5.5), 6, 9, 11, 12, 18, 24, 36, 48, 54 | ||
147 | */ | ||
148 | CONF_SG_RATE_ADAPT_THRESH, | ||
149 | |||
150 | /* | ||
151 | * Not used currently. | ||
152 | * | ||
153 | * Range: 0 | ||
154 | */ | ||
155 | CONF_SG_RATE_ADAPT_SNR, | ||
156 | |||
157 | /* | ||
158 | * Configure the min and max time BT gains the antenna | ||
159 | * in WLAN PSM / BT master basic rate | ||
160 | * | ||
161 | * Range: 0 - 255 (ms) | ||
162 | */ | ||
163 | CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR, | ||
164 | CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR, | ||
165 | |||
166 | /* | ||
167 | * The time after it expires no new WLAN trigger frame is trasmitted | ||
168 | * in WLAN PSM / BT master basic rate | ||
169 | * | ||
170 | * Range: 0 - 255 (ms) | ||
171 | */ | ||
172 | CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR, | ||
173 | |||
174 | /* | ||
175 | * Configure the min and max time BT gains the antenna | ||
176 | * in WLAN PSM / BT slave basic rate | ||
177 | * | ||
178 | * Range: 0 - 255 (ms) | ||
79 | */ | 179 | */ |
80 | u32 per_threshold; | 180 | CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR, |
181 | CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR, | ||
81 | 182 | ||
82 | /* | 183 | /* |
83 | * This value is an absolute time in micro-seconds to limit the | 184 | * The time after it expires no new WLAN trigger frame is trasmitted |
84 | * maximum scan duration compensation while in SG | 185 | * in WLAN PSM / BT slave basic rate |
186 | * | ||
187 | * Range: 0 - 255 (ms) | ||
85 | */ | 188 | */ |
86 | u32 max_scan_compensation_time; | 189 | CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR, |
87 | 190 | ||
88 | /* Defines the PER threshold of the BT voice of which reaching this | 191 | /* |
89 | * value will trigger raising the priority of the BT voice until next | 192 | * Configure the min and max time BT gains the antenna |
90 | * NFS sample interval time as defined in sample_interval. | 193 | * in WLAN PSM / BT master EDR |
91 | * | 194 | * |
92 | * Unit: msec | 195 | * Range: 0 - 255 (ms) |
93 | * Range: 1-65000 | ||
94 | */ | 196 | */ |
95 | u16 nfs_sample_interval; | 197 | CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR, |
198 | CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR, | ||
96 | 199 | ||
97 | /* | 200 | /* |
98 | * Defines the load ratio for the BT. | 201 | * The time after it expires no new WLAN trigger frame is trasmitted |
99 | * The WLAN ratio is: 100 - load_ratio | 202 | * in WLAN PSM / BT master EDR |
100 | * | 203 | * |
101 | * Unit: Percent | 204 | * Range: 0 - 255 (ms) |
102 | * Range: 0-100 | ||
103 | */ | 205 | */ |
104 | u8 load_ratio; | 206 | CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR, |
105 | 207 | ||
106 | /* | 208 | /* |
107 | * true - Co-ex is allowed to enter/exit P.S automatically and | 209 | * Configure the min and max time BT gains the antenna |
108 | * transparently to the host | 210 | * in WLAN PSM / BT slave EDR |
109 | * | 211 | * |
110 | * false - Co-ex is disallowed to enter/exit P.S and will trigger an | 212 | * Range: 0 - 255 (ms) |
111 | * event to the host to notify for the need to enter/exit P.S | 213 | */ |
112 | * due to BT change state | 214 | CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR, |
215 | CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR, | ||
216 | |||
217 | /* | ||
218 | * The time after it expires no new WLAN trigger frame is trasmitted | ||
219 | * in WLAN PSM / BT slave EDR | ||
113 | * | 220 | * |
221 | * Range: 0 - 255 (ms) | ||
114 | */ | 222 | */ |
115 | u8 auto_ps_mode; | 223 | CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR, |
116 | 224 | ||
117 | /* | 225 | /* |
118 | * This parameter defines the compensation percentage of num of probe | 226 | * RX guard time before the beginning of a new BT voice frame during |
119 | * requests in case scan is initiated during BT voice/BT ACL | 227 | * which no new WLAN trigger frame is transmitted. |
120 | * guaranteed link. | ||
121 | * | 228 | * |
122 | * Unit: Percent | 229 | * Range: 0 - 100000 (us) |
123 | * Range: 0-255 (0 - No compensation) | ||
124 | */ | 230 | */ |
125 | u8 probe_req_compensation; | 231 | CONF_SG_RXT, |
126 | 232 | ||
127 | /* | 233 | /* |
128 | * This parameter defines the compensation percentage of scan window | 234 | * TX guard time before the beginning of a new BT voice frame during |
129 | * size in case scan is initiated during BT voice/BT ACL Guaranteed | 235 | * which no new WLAN frame is transmitted. |
130 | * link. | ||
131 | * | 236 | * |
132 | * Unit: Percent | 237 | * Range: 0 - 100000 (us) |
133 | * Range: 0-255 (0 - No compensation) | ||
134 | */ | 238 | */ |
135 | u8 scan_window_compensation; | 239 | |
240 | CONF_SG_TXT, | ||
136 | 241 | ||
137 | /* | 242 | /* |
138 | * Defines the antenna configuration. | 243 | * Enable adaptive RXT/TXT algorithm. If disabled, the host values |
244 | * will be utilized. | ||
139 | * | 245 | * |
140 | * Range: 0 - Single Antenna; 1 - Dual Antenna | 246 | * Range: 0 - disable, 1 - enable |
141 | */ | 247 | */ |
142 | u8 antenna_config; | 248 | CONF_SG_ADAPTIVE_RXT_TXT, |
143 | 249 | ||
144 | /* | 250 | /* |
145 | * The percent out of the Max consecutive beacon miss roaming trigger | 251 | * The used WLAN legacy service period during active BT ACL link |
146 | * which is the threshold for raising the priority of beacon | ||
147 | * reception. | ||
148 | * | 252 | * |
149 | * Range: 1-100 | 253 | * Range: 0 - 255 (ms) |
150 | * N = MaxConsecutiveBeaconMiss | ||
151 | * P = coexMaxConsecutiveBeaconMissPrecent | ||
152 | * Threshold = MIN( N-1, round(N * P / 100)) | ||
153 | */ | 254 | */ |
154 | u8 beacon_miss_threshold; | 255 | CONF_SG_PS_POLL_TIMEOUT, |
155 | 256 | ||
156 | /* | 257 | /* |
157 | * The RX rate threshold below which rate adaptation is assumed to be | 258 | * The used WLAN UPSD service period during active BT ACL link |
158 | * occurring at the AP which will raise priority for ACTIVE_RX and RX | ||
159 | * SP. | ||
160 | * | 259 | * |
161 | * Range: HW_BIT_RATE_* | 260 | * Range: 0 - 255 (ms) |
162 | */ | 261 | */ |
163 | u32 rate_adaptation_threshold; | 262 | CONF_SG_UPSD_TIMEOUT, |
164 | 263 | ||
165 | /* | 264 | /* |
166 | * The SNR above which the RX rate threshold indicating AP rate | 265 | * Configure the min and max time BT gains the antenna |
167 | * adaptation is valid | 266 | * in WLAN Active / BT master EDR |
168 | * | 267 | * |
169 | * Range: -128 - 127 | 268 | * Range: 0 - 255 (ms) |
170 | */ | 269 | */ |
171 | s8 rate_adaptation_snr; | 270 | CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR, |
271 | CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR, | ||
272 | |||
273 | /* | ||
274 | * The maximum time WLAN can gain the antenna for | ||
275 | * in WLAN Active / BT master EDR | ||
276 | * | ||
277 | * Range: 0 - 255 (ms) | ||
278 | */ | ||
279 | CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR, | ||
280 | |||
281 | /* | ||
282 | * Configure the min and max time BT gains the antenna | ||
283 | * in WLAN Active / BT slave EDR | ||
284 | * | ||
285 | * Range: 0 - 255 (ms) | ||
286 | */ | ||
287 | CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR, | ||
288 | CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR, | ||
289 | |||
290 | /* | ||
291 | * The maximum time WLAN can gain the antenna for | ||
292 | * in WLAN Active / BT slave EDR | ||
293 | * | ||
294 | * Range: 0 - 255 (ms) | ||
295 | */ | ||
296 | CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR, | ||
297 | |||
298 | /* | ||
299 | * Configure the min and max time BT gains the antenna | ||
300 | * in WLAN Active / BT basic rate | ||
301 | * | ||
302 | * Range: 0 - 255 (ms) | ||
303 | */ | ||
304 | CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR, | ||
305 | CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR, | ||
306 | |||
307 | /* | ||
308 | * The maximum time WLAN can gain the antenna for | ||
309 | * in WLAN Active / BT basic rate | ||
310 | * | ||
311 | * Range: 0 - 255 (ms) | ||
312 | */ | ||
313 | CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR, | ||
314 | |||
315 | /* | ||
316 | * Compensation percentage of WLAN passive scan window if initiated | ||
317 | * during BT voice | ||
318 | * | ||
319 | * Range: 0 - 1000 (%) | ||
320 | */ | ||
321 | CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3, | ||
322 | |||
323 | /* | ||
324 | * Compensation percentage of WLAN passive scan window if initiated | ||
325 | * during BT A2DP | ||
326 | * | ||
327 | * Range: 0 - 1000 (%) | ||
328 | */ | ||
329 | CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP, | ||
330 | |||
331 | /* | ||
332 | * Fixed time ensured for BT traffic to gain the antenna during WLAN | ||
333 | * passive scan. | ||
334 | * | ||
335 | * Range: 0 - 1000 ms | ||
336 | */ | ||
337 | CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME, | ||
338 | |||
339 | /* | ||
340 | * Fixed time ensured for WLAN traffic to gain the antenna during WLAN | ||
341 | * passive scan. | ||
342 | * | ||
343 | * Range: 0 - 1000 ms | ||
344 | */ | ||
345 | CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME, | ||
346 | |||
347 | /* | ||
348 | * Number of consequent BT voice frames not interrupted by WLAN | ||
349 | * | ||
350 | * Range: 0 - 100 | ||
351 | */ | ||
352 | CONF_SG_HV3_MAX_SERVED, | ||
353 | |||
354 | /* | ||
355 | * Protection time of the DHCP procedure. | ||
356 | * | ||
357 | * Range: 0 - 100000 (ms) | ||
358 | */ | ||
359 | CONF_SG_DHCP_TIME, | ||
360 | |||
361 | /* | ||
362 | * Compensation percentage of WLAN active scan window if initiated | ||
363 | * during BT A2DP | ||
364 | * | ||
365 | * Range: 0 - 1000 (%) | ||
366 | */ | ||
367 | CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP, | ||
368 | CONF_SG_TEMP_PARAM_1, | ||
369 | CONF_SG_TEMP_PARAM_2, | ||
370 | CONF_SG_TEMP_PARAM_3, | ||
371 | CONF_SG_TEMP_PARAM_4, | ||
372 | CONF_SG_TEMP_PARAM_5, | ||
373 | CONF_SG_PARAMS_MAX, | ||
374 | CONF_SG_PARAMS_ALL = 0xff | ||
375 | }; | ||
376 | |||
377 | struct conf_sg_settings { | ||
378 | __le32 params[CONF_SG_PARAMS_MAX]; | ||
379 | u8 state; | ||
172 | }; | 380 | }; |
173 | 381 | ||
174 | enum conf_rx_queue_type { | 382 | enum conf_rx_queue_type { |
diff --git a/drivers/net/wireless/wl12xx/wl1271_debugfs.c b/drivers/net/wireless/wl12xx/wl1271_debugfs.c index 8d7588ca68fd..3c0f5b1ac272 100644 --- a/drivers/net/wireless/wl12xx/wl1271_debugfs.c +++ b/drivers/net/wireless/wl12xx/wl1271_debugfs.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "wl1271.h" | 28 | #include "wl1271.h" |
29 | #include "wl1271_acx.h" | 29 | #include "wl1271_acx.h" |
30 | #include "wl1271_ps.h" | 30 | #include "wl1271_ps.h" |
31 | #include "wl1271_io.h" | ||
31 | 32 | ||
32 | /* ms */ | 33 | /* ms */ |
33 | #define WL1271_DEBUGFS_STATS_LIFETIME 1000 | 34 | #define WL1271_DEBUGFS_STATS_LIFETIME 1000 |
@@ -276,13 +277,10 @@ static ssize_t gpio_power_write(struct file *file, | |||
276 | goto out; | 277 | goto out; |
277 | } | 278 | } |
278 | 279 | ||
279 | if (value) { | 280 | if (value) |
280 | wl->set_power(true); | 281 | wl1271_power_on(wl); |
281 | set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); | 282 | else |
282 | } else { | 283 | wl1271_power_off(wl); |
283 | wl->set_power(false); | ||
284 | clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); | ||
285 | } | ||
286 | 284 | ||
287 | out: | 285 | out: |
288 | mutex_unlock(&wl->mutex); | 286 | mutex_unlock(&wl->mutex); |
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c index 5533519a1418..4d35af96c597 100644 --- a/drivers/net/wireless/wl12xx/wl1271_event.c +++ b/drivers/net/wireless/wl12xx/wl1271_event.c | |||
@@ -44,7 +44,9 @@ static int wl1271_event_scan_complete(struct wl1271 *wl, | |||
44 | * scanning as it checks that. | 44 | * scanning as it checks that. |
45 | */ | 45 | */ |
46 | clear_bit(WL1271_FLAG_SCANNING, &wl->flags); | 46 | clear_bit(WL1271_FLAG_SCANNING, &wl->flags); |
47 | /* FIXME: ie missing! */ | ||
47 | wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len, | 48 | wl1271_cmd_scan(wl, wl->scan.ssid, wl->scan.ssid_len, |
49 | NULL, 0, | ||
48 | wl->scan.active, | 50 | wl->scan.active, |
49 | wl->scan.high_prio, | 51 | wl->scan.high_prio, |
50 | WL1271_SCAN_BAND_5_GHZ, | 52 | WL1271_SCAN_BAND_5_GHZ, |
diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c index 86c30a86a456..d9335fc2a575 100644 --- a/drivers/net/wireless/wl12xx/wl1271_init.c +++ b/drivers/net/wireless/wl12xx/wl1271_init.c | |||
@@ -160,11 +160,11 @@ int wl1271_init_pta(struct wl1271 *wl) | |||
160 | { | 160 | { |
161 | int ret; | 161 | int ret; |
162 | 162 | ||
163 | ret = wl1271_acx_sg_enable(wl); | 163 | ret = wl1271_acx_sg_cfg(wl); |
164 | if (ret < 0) | 164 | if (ret < 0) |
165 | return ret; | 165 | return ret; |
166 | 166 | ||
167 | ret = wl1271_acx_sg_cfg(wl); | 167 | ret = wl1271_acx_sg_enable(wl, wl->sg_enabled); |
168 | if (ret < 0) | 168 | if (ret < 0) |
169 | return ret; | 169 | return ret; |
170 | 170 | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_io.h b/drivers/net/wireless/wl12xx/wl1271_io.h index 95d2168f8af4..d8837ef0bb40 100644 --- a/drivers/net/wireless/wl12xx/wl1271_io.h +++ b/drivers/net/wireless/wl12xx/wl1271_io.h | |||
@@ -138,6 +138,18 @@ static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val) | |||
138 | wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val); | 138 | wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val); |
139 | } | 139 | } |
140 | 140 | ||
141 | static inline void wl1271_power_off(struct wl1271 *wl) | ||
142 | { | ||
143 | wl->if_ops->power(wl, false); | ||
144 | clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); | ||
145 | } | ||
146 | |||
147 | static inline void wl1271_power_on(struct wl1271 *wl) | ||
148 | { | ||
149 | wl->if_ops->power(wl, true); | ||
150 | set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); | ||
151 | } | ||
152 | |||
141 | 153 | ||
142 | /* Top Register IO */ | 154 | /* Top Register IO */ |
143 | void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val); | 155 | void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val); |
@@ -149,6 +161,7 @@ int wl1271_set_partition(struct wl1271 *wl, | |||
149 | /* Functions from wl1271_main.c */ | 161 | /* Functions from wl1271_main.c */ |
150 | 162 | ||
151 | int wl1271_register_hw(struct wl1271 *wl); | 163 | int wl1271_register_hw(struct wl1271 *wl); |
164 | void wl1271_unregister_hw(struct wl1271 *wl); | ||
152 | int wl1271_init_ieee80211(struct wl1271 *wl); | 165 | int wl1271_init_ieee80211(struct wl1271 *wl); |
153 | struct ieee80211_hw *wl1271_alloc_hw(void); | 166 | struct ieee80211_hw *wl1271_alloc_hw(void); |
154 | int wl1271_free_hw(struct wl1271 *wl); | 167 | int wl1271_free_hw(struct wl1271 *wl); |
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 0a4ff7b02f59..3daba6c0c77f 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/etherdevice.h> | 29 | #include <linux/etherdevice.h> |
30 | #include <linux/vmalloc.h> | 30 | #include <linux/vmalloc.h> |
31 | #include <linux/inetdevice.h> | 31 | #include <linux/inetdevice.h> |
32 | #include <linux/platform_device.h> | ||
32 | 33 | ||
33 | #include "wl1271.h" | 34 | #include "wl1271.h" |
34 | #include "wl12xx_80211.h" | 35 | #include "wl12xx_80211.h" |
@@ -48,17 +49,57 @@ | |||
48 | 49 | ||
49 | static struct conf_drv_settings default_conf = { | 50 | static struct conf_drv_settings default_conf = { |
50 | .sg = { | 51 | .sg = { |
51 | .per_threshold = 7500, | 52 | .params = { |
52 | .max_scan_compensation_time = 120000, | 53 | [CONF_SG_BT_PER_THRESHOLD] = 7500, |
53 | .nfs_sample_interval = 400, | 54 | [CONF_SG_HV3_MAX_OVERRIDE] = 0, |
54 | .load_ratio = 50, | 55 | [CONF_SG_BT_NFS_SAMPLE_INTERVAL] = 400, |
55 | .auto_ps_mode = 0, | 56 | [CONF_SG_BT_LOAD_RATIO] = 50, |
56 | .probe_req_compensation = 170, | 57 | [CONF_SG_AUTO_PS_MODE] = 0, |
57 | .scan_window_compensation = 50, | 58 | [CONF_SG_AUTO_SCAN_PROBE_REQ] = 170, |
58 | .antenna_config = 0, | 59 | [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3] = 50, |
59 | .beacon_miss_threshold = 60, | 60 | [CONF_SG_ANTENNA_CONFIGURATION] = 0, |
60 | .rate_adaptation_threshold = CONF_HW_BIT_RATE_12MBPS, | 61 | [CONF_SG_BEACON_MISS_PERCENT] = 60, |
61 | .rate_adaptation_snr = 0 | 62 | [CONF_SG_RATE_ADAPT_THRESH] = 12, |
63 | [CONF_SG_RATE_ADAPT_SNR] = 0, | ||
64 | [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR] = 10, | ||
65 | [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR] = 30, | ||
66 | [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR] = 8, | ||
67 | [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR] = 20, | ||
68 | [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR] = 50, | ||
69 | /* Note: with UPSD, this should be 4 */ | ||
70 | [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR] = 8, | ||
71 | [CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR] = 7, | ||
72 | [CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR] = 25, | ||
73 | [CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR] = 20, | ||
74 | /* Note: with UPDS, this should be 15 */ | ||
75 | [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR] = 8, | ||
76 | /* Note: with UPDS, this should be 50 */ | ||
77 | [CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR] = 40, | ||
78 | /* Note: with UPDS, this should be 10 */ | ||
79 | [CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR] = 20, | ||
80 | [CONF_SG_RXT] = 1200, | ||
81 | [CONF_SG_TXT] = 1000, | ||
82 | [CONF_SG_ADAPTIVE_RXT_TXT] = 1, | ||
83 | [CONF_SG_PS_POLL_TIMEOUT] = 10, | ||
84 | [CONF_SG_UPSD_TIMEOUT] = 10, | ||
85 | [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR] = 7, | ||
86 | [CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR] = 15, | ||
87 | [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR] = 15, | ||
88 | [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR] = 8, | ||
89 | [CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR] = 20, | ||
90 | [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR] = 15, | ||
91 | [CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR] = 20, | ||
92 | [CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR] = 50, | ||
93 | [CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR] = 10, | ||
94 | [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3] = 200, | ||
95 | [CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP] = 800, | ||
96 | [CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME] = 75, | ||
97 | [CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME] = 15, | ||
98 | [CONF_SG_HV3_MAX_SERVED] = 6, | ||
99 | [CONF_SG_DHCP_TIME] = 5000, | ||
100 | [CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP] = 100, | ||
101 | }, | ||
102 | .state = CONF_SG_PROTECTIVE, | ||
62 | }, | 103 | }, |
63 | .rx = { | 104 | .rx = { |
64 | .rx_msdu_life_time = 512000, | 105 | .rx_msdu_life_time = 512000, |
@@ -240,6 +281,21 @@ static struct conf_drv_settings default_conf = { | |||
240 | } | 281 | } |
241 | }; | 282 | }; |
242 | 283 | ||
284 | static void wl1271_device_release(struct device *dev) | ||
285 | { | ||
286 | |||
287 | } | ||
288 | |||
289 | static struct platform_device wl1271_device = { | ||
290 | .name = "wl1271", | ||
291 | .id = -1, | ||
292 | |||
293 | /* device model insists to have a release function */ | ||
294 | .dev = { | ||
295 | .release = wl1271_device_release, | ||
296 | }, | ||
297 | }; | ||
298 | |||
243 | static LIST_HEAD(wl_list); | 299 | static LIST_HEAD(wl_list); |
244 | 300 | ||
245 | static void wl1271_conf_init(struct wl1271 *wl) | 301 | static void wl1271_conf_init(struct wl1271 *wl) |
@@ -359,18 +415,6 @@ static int wl1271_plt_init(struct wl1271 *wl) | |||
359 | return ret; | 415 | return ret; |
360 | } | 416 | } |
361 | 417 | ||
362 | static void wl1271_power_off(struct wl1271 *wl) | ||
363 | { | ||
364 | wl->set_power(false); | ||
365 | clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); | ||
366 | } | ||
367 | |||
368 | static void wl1271_power_on(struct wl1271 *wl) | ||
369 | { | ||
370 | wl->set_power(true); | ||
371 | set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); | ||
372 | } | ||
373 | |||
374 | static void wl1271_fw_status(struct wl1271 *wl, | 418 | static void wl1271_fw_status(struct wl1271 *wl, |
375 | struct wl1271_fw_status *status) | 419 | struct wl1271_fw_status *status) |
376 | { | 420 | { |
@@ -526,40 +570,6 @@ out: | |||
526 | return ret; | 570 | return ret; |
527 | } | 571 | } |
528 | 572 | ||
529 | static int wl1271_update_mac_addr(struct wl1271 *wl) | ||
530 | { | ||
531 | int ret = 0; | ||
532 | u8 *nvs_ptr = (u8 *)wl->nvs->nvs; | ||
533 | |||
534 | /* get mac address from the NVS */ | ||
535 | wl->mac_addr[0] = nvs_ptr[11]; | ||
536 | wl->mac_addr[1] = nvs_ptr[10]; | ||
537 | wl->mac_addr[2] = nvs_ptr[6]; | ||
538 | wl->mac_addr[3] = nvs_ptr[5]; | ||
539 | wl->mac_addr[4] = nvs_ptr[4]; | ||
540 | wl->mac_addr[5] = nvs_ptr[3]; | ||
541 | |||
542 | /* FIXME: if it is a zero-address, we should bail out. Now, instead, | ||
543 | we randomize an address */ | ||
544 | if (is_zero_ether_addr(wl->mac_addr)) { | ||
545 | static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf}; | ||
546 | memcpy(wl->mac_addr, nokia_oui, 3); | ||
547 | get_random_bytes(wl->mac_addr + 3, 3); | ||
548 | |||
549 | /* update this address to the NVS */ | ||
550 | nvs_ptr[11] = wl->mac_addr[0]; | ||
551 | nvs_ptr[10] = wl->mac_addr[1]; | ||
552 | nvs_ptr[6] = wl->mac_addr[2]; | ||
553 | nvs_ptr[5] = wl->mac_addr[3]; | ||
554 | nvs_ptr[4] = wl->mac_addr[4]; | ||
555 | nvs_ptr[3] = wl->mac_addr[5]; | ||
556 | } | ||
557 | |||
558 | SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr); | ||
559 | |||
560 | return ret; | ||
561 | } | ||
562 | |||
563 | static int wl1271_fetch_nvs(struct wl1271 *wl) | 573 | static int wl1271_fetch_nvs(struct wl1271 *wl) |
564 | { | 574 | { |
565 | const struct firmware *fw; | 575 | const struct firmware *fw; |
@@ -589,8 +599,6 @@ static int wl1271_fetch_nvs(struct wl1271 *wl) | |||
589 | 599 | ||
590 | memcpy(wl->nvs, fw->data, sizeof(struct wl1271_nvs_file)); | 600 | memcpy(wl->nvs, fw->data, sizeof(struct wl1271_nvs_file)); |
591 | 601 | ||
592 | ret = wl1271_update_mac_addr(wl); | ||
593 | |||
594 | out: | 602 | out: |
595 | release_firmware(fw); | 603 | release_firmware(fw); |
596 | 604 | ||
@@ -908,13 +916,58 @@ static struct notifier_block wl1271_dev_notifier = { | |||
908 | 916 | ||
909 | static int wl1271_op_start(struct ieee80211_hw *hw) | 917 | static int wl1271_op_start(struct ieee80211_hw *hw) |
910 | { | 918 | { |
919 | wl1271_debug(DEBUG_MAC80211, "mac80211 start"); | ||
920 | |||
921 | /* | ||
922 | * We have to delay the booting of the hardware because | ||
923 | * we need to know the local MAC address before downloading and | ||
924 | * initializing the firmware. The MAC address cannot be changed | ||
925 | * after boot, and without the proper MAC address, the firmware | ||
926 | * will not function properly. | ||
927 | * | ||
928 | * The MAC address is first known when the corresponding interface | ||
929 | * is added. That is where we will initialize the hardware. | ||
930 | */ | ||
931 | |||
932 | return 0; | ||
933 | } | ||
934 | |||
935 | static void wl1271_op_stop(struct ieee80211_hw *hw) | ||
936 | { | ||
937 | wl1271_debug(DEBUG_MAC80211, "mac80211 stop"); | ||
938 | } | ||
939 | |||
940 | static int wl1271_op_add_interface(struct ieee80211_hw *hw, | ||
941 | struct ieee80211_vif *vif) | ||
942 | { | ||
911 | struct wl1271 *wl = hw->priv; | 943 | struct wl1271 *wl = hw->priv; |
912 | int retries = WL1271_BOOT_RETRIES; | 944 | int retries = WL1271_BOOT_RETRIES; |
913 | int ret = 0; | 945 | int ret = 0; |
914 | 946 | ||
915 | wl1271_debug(DEBUG_MAC80211, "mac80211 start"); | 947 | wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", |
948 | vif->type, vif->addr); | ||
916 | 949 | ||
917 | mutex_lock(&wl->mutex); | 950 | mutex_lock(&wl->mutex); |
951 | if (wl->vif) { | ||
952 | ret = -EBUSY; | ||
953 | goto out; | ||
954 | } | ||
955 | |||
956 | wl->vif = vif; | ||
957 | |||
958 | switch (vif->type) { | ||
959 | case NL80211_IFTYPE_STATION: | ||
960 | wl->bss_type = BSS_TYPE_STA_BSS; | ||
961 | break; | ||
962 | case NL80211_IFTYPE_ADHOC: | ||
963 | wl->bss_type = BSS_TYPE_IBSS; | ||
964 | break; | ||
965 | default: | ||
966 | ret = -EOPNOTSUPP; | ||
967 | goto out; | ||
968 | } | ||
969 | |||
970 | memcpy(wl->mac_addr, vif->addr, ETH_ALEN); | ||
918 | 971 | ||
919 | if (wl->state != WL1271_STATE_OFF) { | 972 | if (wl->state != WL1271_STATE_OFF) { |
920 | wl1271_error("cannot start because not in off state: %d", | 973 | wl1271_error("cannot start because not in off state: %d", |
@@ -970,19 +1023,20 @@ out: | |||
970 | return ret; | 1023 | return ret; |
971 | } | 1024 | } |
972 | 1025 | ||
973 | static void wl1271_op_stop(struct ieee80211_hw *hw) | 1026 | static void wl1271_op_remove_interface(struct ieee80211_hw *hw, |
1027 | struct ieee80211_vif *vif) | ||
974 | { | 1028 | { |
975 | struct wl1271 *wl = hw->priv; | 1029 | struct wl1271 *wl = hw->priv; |
976 | int i; | 1030 | int i; |
977 | 1031 | ||
978 | wl1271_info("down"); | ||
979 | |||
980 | wl1271_debug(DEBUG_MAC80211, "mac80211 stop"); | ||
981 | |||
982 | unregister_inetaddr_notifier(&wl1271_dev_notifier); | 1032 | unregister_inetaddr_notifier(&wl1271_dev_notifier); |
983 | list_del(&wl->list); | ||
984 | 1033 | ||
985 | mutex_lock(&wl->mutex); | 1034 | mutex_lock(&wl->mutex); |
1035 | wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); | ||
1036 | |||
1037 | wl1271_info("down"); | ||
1038 | |||
1039 | list_del(&wl->list); | ||
986 | 1040 | ||
987 | WARN_ON(wl->state != WL1271_STATE_ON); | 1041 | WARN_ON(wl->state != WL1271_STATE_ON); |
988 | 1042 | ||
@@ -1026,6 +1080,8 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) | |||
1026 | wl->rate_set = CONF_TX_RATE_MASK_BASIC; | 1080 | wl->rate_set = CONF_TX_RATE_MASK_BASIC; |
1027 | wl->sta_rate_set = 0; | 1081 | wl->sta_rate_set = 0; |
1028 | wl->flags = 0; | 1082 | wl->flags = 0; |
1083 | wl->vif = NULL; | ||
1084 | wl->filters = 0; | ||
1029 | 1085 | ||
1030 | for (i = 0; i < NUM_TX_QUEUES; i++) | 1086 | for (i = 0; i < NUM_TX_QUEUES; i++) |
1031 | wl->tx_blocks_freed[i] = 0; | 1087 | wl->tx_blocks_freed[i] = 0; |
@@ -1034,119 +1090,39 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) | |||
1034 | mutex_unlock(&wl->mutex); | 1090 | mutex_unlock(&wl->mutex); |
1035 | } | 1091 | } |
1036 | 1092 | ||
1037 | static int wl1271_op_add_interface(struct ieee80211_hw *hw, | 1093 | static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters) |
1038 | struct ieee80211_vif *vif) | ||
1039 | { | 1094 | { |
1040 | struct wl1271 *wl = hw->priv; | 1095 | wl->rx_config = WL1271_DEFAULT_RX_CONFIG; |
1041 | int ret = 0; | 1096 | wl->rx_filter = WL1271_DEFAULT_RX_FILTER; |
1042 | 1097 | ||
1043 | wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", | 1098 | /* combine requested filters with current filter config */ |
1044 | vif->type, vif->addr); | 1099 | filters = wl->filters | filters; |
1045 | 1100 | ||
1046 | mutex_lock(&wl->mutex); | 1101 | wl1271_debug(DEBUG_FILTERS, "RX filters set: "); |
1047 | if (wl->vif) { | ||
1048 | ret = -EBUSY; | ||
1049 | goto out; | ||
1050 | } | ||
1051 | 1102 | ||
1052 | wl->vif = vif; | 1103 | if (filters & FIF_PROMISC_IN_BSS) { |
1053 | 1104 | wl1271_debug(DEBUG_FILTERS, " - FIF_PROMISC_IN_BSS"); | |
1054 | switch (vif->type) { | 1105 | wl->rx_config &= ~CFG_UNI_FILTER_EN; |
1055 | case NL80211_IFTYPE_STATION: | 1106 | wl->rx_config |= CFG_BSSID_FILTER_EN; |
1056 | wl->bss_type = BSS_TYPE_STA_BSS; | ||
1057 | break; | ||
1058 | case NL80211_IFTYPE_ADHOC: | ||
1059 | wl->bss_type = BSS_TYPE_IBSS; | ||
1060 | break; | ||
1061 | default: | ||
1062 | ret = -EOPNOTSUPP; | ||
1063 | goto out; | ||
1064 | } | 1107 | } |
1065 | 1108 | if (filters & FIF_BCN_PRBRESP_PROMISC) { | |
1066 | /* FIXME: what if conf->mac_addr changes? */ | 1109 | wl1271_debug(DEBUG_FILTERS, " - FIF_BCN_PRBRESP_PROMISC"); |
1067 | 1110 | wl->rx_config &= ~CFG_BSSID_FILTER_EN; | |
1068 | out: | 1111 | wl->rx_config &= ~CFG_SSID_FILTER_EN; |
1069 | mutex_unlock(&wl->mutex); | ||
1070 | return ret; | ||
1071 | } | ||
1072 | |||
1073 | static void wl1271_op_remove_interface(struct ieee80211_hw *hw, | ||
1074 | struct ieee80211_vif *vif) | ||
1075 | { | ||
1076 | struct wl1271 *wl = hw->priv; | ||
1077 | |||
1078 | mutex_lock(&wl->mutex); | ||
1079 | wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); | ||
1080 | wl->vif = NULL; | ||
1081 | mutex_unlock(&wl->mutex); | ||
1082 | } | ||
1083 | |||
1084 | #if 0 | ||
1085 | static int wl1271_op_config_interface(struct ieee80211_hw *hw, | ||
1086 | struct ieee80211_vif *vif, | ||
1087 | struct ieee80211_if_conf *conf) | ||
1088 | { | ||
1089 | struct wl1271 *wl = hw->priv; | ||
1090 | struct sk_buff *beacon; | ||
1091 | int ret; | ||
1092 | |||
1093 | wl1271_debug(DEBUG_MAC80211, "mac80211 config_interface bssid %pM", | ||
1094 | conf->bssid); | ||
1095 | wl1271_dump_ascii(DEBUG_MAC80211, "ssid: ", conf->ssid, | ||
1096 | conf->ssid_len); | ||
1097 | |||
1098 | mutex_lock(&wl->mutex); | ||
1099 | |||
1100 | ret = wl1271_ps_elp_wakeup(wl, false); | ||
1101 | if (ret < 0) | ||
1102 | goto out; | ||
1103 | |||
1104 | if (memcmp(wl->bssid, conf->bssid, ETH_ALEN)) { | ||
1105 | wl1271_debug(DEBUG_MAC80211, "bssid changed"); | ||
1106 | |||
1107 | memcpy(wl->bssid, conf->bssid, ETH_ALEN); | ||
1108 | |||
1109 | ret = wl1271_cmd_join(wl, wl->bss_type); | ||
1110 | if (ret < 0) | ||
1111 | goto out_sleep; | ||
1112 | |||
1113 | ret = wl1271_cmd_build_null_data(wl); | ||
1114 | if (ret < 0) | ||
1115 | goto out_sleep; | ||
1116 | } | 1112 | } |
1117 | 1113 | if (filters & FIF_OTHER_BSS) { | |
1118 | wl->ssid_len = conf->ssid_len; | 1114 | wl1271_debug(DEBUG_FILTERS, " - FIF_OTHER_BSS"); |
1119 | if (wl->ssid_len) | 1115 | wl->rx_config &= ~CFG_BSSID_FILTER_EN; |
1120 | memcpy(wl->ssid, conf->ssid, wl->ssid_len); | 1116 | } |
1121 | 1117 | if (filters & FIF_CONTROL) { | |
1122 | if (conf->changed & IEEE80211_IFCC_BEACON) { | 1118 | wl1271_debug(DEBUG_FILTERS, " - FIF_CONTROL"); |
1123 | beacon = ieee80211_beacon_get(hw, vif); | 1119 | wl->rx_filter |= CFG_RX_CTL_EN; |
1124 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON, | 1120 | } |
1125 | beacon->data, beacon->len); | 1121 | if (filters & FIF_FCSFAIL) { |
1126 | 1122 | wl1271_debug(DEBUG_FILTERS, " - FIF_FCSFAIL"); | |
1127 | if (ret < 0) { | 1123 | wl->rx_filter |= CFG_RX_FCS_ERROR; |
1128 | dev_kfree_skb(beacon); | ||
1129 | goto out_sleep; | ||
1130 | } | ||
1131 | |||
1132 | ret = wl1271_cmd_template_set(wl, CMD_TEMPL_PROBE_RESPONSE, | ||
1133 | beacon->data, beacon->len); | ||
1134 | |||
1135 | dev_kfree_skb(beacon); | ||
1136 | |||
1137 | if (ret < 0) | ||
1138 | goto out_sleep; | ||
1139 | } | 1124 | } |
1140 | |||
1141 | out_sleep: | ||
1142 | wl1271_ps_elp_sleep(wl); | ||
1143 | |||
1144 | out: | ||
1145 | mutex_unlock(&wl->mutex); | ||
1146 | |||
1147 | return ret; | ||
1148 | } | 1125 | } |
1149 | #endif | ||
1150 | 1126 | ||
1151 | static int wl1271_join_channel(struct wl1271 *wl, int channel) | 1127 | static int wl1271_join_channel(struct wl1271 *wl, int channel) |
1152 | { | 1128 | { |
@@ -1155,12 +1131,12 @@ static int wl1271_join_channel(struct wl1271 *wl, int channel) | |||
1155 | static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde, | 1131 | static const u8 dummy_bssid[ETH_ALEN] = { 0x0b, 0xad, 0xde, |
1156 | 0xad, 0xbe, 0xef }; | 1132 | 0xad, 0xbe, 0xef }; |
1157 | 1133 | ||
1158 | /* disable mac filter, so we hear everything */ | ||
1159 | wl->rx_config &= ~CFG_BSSID_FILTER_EN; | ||
1160 | |||
1161 | wl->channel = channel; | 1134 | wl->channel = channel; |
1162 | memcpy(wl->bssid, dummy_bssid, ETH_ALEN); | 1135 | memcpy(wl->bssid, dummy_bssid, ETH_ALEN); |
1163 | 1136 | ||
1137 | /* pass through frames from all BSS */ | ||
1138 | wl1271_configure_filters(wl, FIF_OTHER_BSS); | ||
1139 | |||
1164 | /* the dummy join is performed always with STATION BSS type to allow | 1140 | /* the dummy join is performed always with STATION BSS type to allow |
1165 | also ad-hoc mode to listen to the surroundings without sending any | 1141 | also ad-hoc mode to listen to the surroundings without sending any |
1166 | beacons yet. */ | 1142 | beacons yet. */ |
@@ -1186,7 +1162,9 @@ static int wl1271_unjoin_channel(struct wl1271 *wl) | |||
1186 | clear_bit(WL1271_FLAG_JOINED, &wl->flags); | 1162 | clear_bit(WL1271_FLAG_JOINED, &wl->flags); |
1187 | wl->channel = 0; | 1163 | wl->channel = 0; |
1188 | memset(wl->bssid, 0, ETH_ALEN); | 1164 | memset(wl->bssid, 0, ETH_ALEN); |
1189 | wl->rx_config = WL1271_DEFAULT_RX_CONFIG; | 1165 | |
1166 | /* stop filterting packets based on bssid */ | ||
1167 | wl1271_configure_filters(wl, FIF_OTHER_BSS); | ||
1190 | 1168 | ||
1191 | out: | 1169 | out: |
1192 | return ret; | 1170 | return ret; |
@@ -1359,14 +1337,14 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw, | |||
1359 | if (ret < 0) | 1337 | if (ret < 0) |
1360 | goto out_sleep; | 1338 | goto out_sleep; |
1361 | 1339 | ||
1362 | kfree(fp); | ||
1363 | |||
1364 | /* FIXME: We still need to set our filters properly */ | ||
1365 | |||
1366 | /* determine, whether supported filter values have changed */ | 1340 | /* determine, whether supported filter values have changed */ |
1367 | if (changed == 0) | 1341 | if (changed == 0) |
1368 | goto out_sleep; | 1342 | goto out_sleep; |
1369 | 1343 | ||
1344 | /* configure filters */ | ||
1345 | wl->filters = *total; | ||
1346 | wl1271_configure_filters(wl, 0); | ||
1347 | |||
1370 | /* apply configured filters */ | 1348 | /* apply configured filters */ |
1371 | ret = wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter); | 1349 | ret = wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter); |
1372 | if (ret < 0) | 1350 | if (ret < 0) |
@@ -1377,6 +1355,7 @@ out_sleep: | |||
1377 | 1355 | ||
1378 | out: | 1356 | out: |
1379 | mutex_unlock(&wl->mutex); | 1357 | mutex_unlock(&wl->mutex); |
1358 | kfree(fp); | ||
1380 | } | 1359 | } |
1381 | 1360 | ||
1382 | static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 1361 | static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
@@ -1522,10 +1501,12 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, | |||
1522 | goto out; | 1501 | goto out; |
1523 | 1502 | ||
1524 | if (wl1271_11a_enabled()) | 1503 | if (wl1271_11a_enabled()) |
1525 | ret = wl1271_cmd_scan(hw->priv, ssid, len, 1, 0, | 1504 | ret = wl1271_cmd_scan(hw->priv, ssid, len, |
1505 | req->ie, req->ie_len, 1, 0, | ||
1526 | WL1271_SCAN_BAND_DUAL, 3); | 1506 | WL1271_SCAN_BAND_DUAL, 3); |
1527 | else | 1507 | else |
1528 | ret = wl1271_cmd_scan(hw->priv, ssid, len, 1, 0, | 1508 | ret = wl1271_cmd_scan(hw->priv, ssid, len, |
1509 | req->ie, req->ie_len, 1, 0, | ||
1529 | WL1271_SCAN_BAND_2_4_GHZ, 3); | 1510 | WL1271_SCAN_BAND_2_4_GHZ, 3); |
1530 | 1511 | ||
1531 | wl1271_ps_elp_sleep(wl); | 1512 | wl1271_ps_elp_sleep(wl); |
@@ -1638,14 +1619,14 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1638 | * and enable the BSSID filter | 1619 | * and enable the BSSID filter |
1639 | */ | 1620 | */ |
1640 | memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) { | 1621 | memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) { |
1641 | wl->rx_config |= CFG_BSSID_FILTER_EN; | ||
1642 | memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); | 1622 | memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); |
1623 | |||
1643 | ret = wl1271_cmd_build_null_data(wl); | 1624 | ret = wl1271_cmd_build_null_data(wl); |
1644 | if (ret < 0) { | 1625 | if (ret < 0) |
1645 | wl1271_warning("cmd buld null data failed %d", | ||
1646 | ret); | ||
1647 | goto out_sleep; | 1626 | goto out_sleep; |
1648 | } | 1627 | |
1628 | /* filter out all packets not from this BSSID */ | ||
1629 | wl1271_configure_filters(wl, 0); | ||
1649 | 1630 | ||
1650 | /* Need to update the BSSID (for filtering etc) */ | 1631 | /* Need to update the BSSID (for filtering etc) */ |
1651 | do_join = true; | 1632 | do_join = true; |
@@ -1735,6 +1716,7 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
1735 | const struct ieee80211_tx_queue_params *params) | 1716 | const struct ieee80211_tx_queue_params *params) |
1736 | { | 1717 | { |
1737 | struct wl1271 *wl = hw->priv; | 1718 | struct wl1271 *wl = hw->priv; |
1719 | u8 ps_scheme; | ||
1738 | int ret; | 1720 | int ret; |
1739 | 1721 | ||
1740 | mutex_lock(&wl->mutex); | 1722 | mutex_lock(&wl->mutex); |
@@ -1745,17 +1727,22 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
1745 | if (ret < 0) | 1727 | if (ret < 0) |
1746 | goto out; | 1728 | goto out; |
1747 | 1729 | ||
1730 | /* the txop is confed in units of 32us by the mac80211, we need us */ | ||
1748 | ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue), | 1731 | ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue), |
1749 | params->cw_min, params->cw_max, | 1732 | params->cw_min, params->cw_max, |
1750 | params->aifs, params->txop); | 1733 | params->aifs, params->txop << 5); |
1751 | if (ret < 0) | 1734 | if (ret < 0) |
1752 | goto out_sleep; | 1735 | goto out_sleep; |
1753 | 1736 | ||
1737 | if (params->uapsd) | ||
1738 | ps_scheme = CONF_PS_SCHEME_UPSD_TRIGGER; | ||
1739 | else | ||
1740 | ps_scheme = CONF_PS_SCHEME_LEGACY; | ||
1741 | |||
1754 | ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue), | 1742 | ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue), |
1755 | CONF_CHANNEL_TYPE_EDCF, | 1743 | CONF_CHANNEL_TYPE_EDCF, |
1756 | wl1271_tx_get_queue(queue), | 1744 | wl1271_tx_get_queue(queue), |
1757 | CONF_PS_SCHEME_LEGACY_PSPOLL, | 1745 | ps_scheme, CONF_ACK_POLICY_LEGACY, 0, 0); |
1758 | CONF_ACK_POLICY_LEGACY, 0, 0); | ||
1759 | if (ret < 0) | 1746 | if (ret < 0) |
1760 | goto out_sleep; | 1747 | goto out_sleep; |
1761 | 1748 | ||
@@ -1925,7 +1912,6 @@ static const struct ieee80211_ops wl1271_ops = { | |||
1925 | .add_interface = wl1271_op_add_interface, | 1912 | .add_interface = wl1271_op_add_interface, |
1926 | .remove_interface = wl1271_op_remove_interface, | 1913 | .remove_interface = wl1271_op_remove_interface, |
1927 | .config = wl1271_op_config, | 1914 | .config = wl1271_op_config, |
1928 | /* .config_interface = wl1271_op_config_interface, */ | ||
1929 | .prepare_multicast = wl1271_op_prepare_multicast, | 1915 | .prepare_multicast = wl1271_op_prepare_multicast, |
1930 | .configure_filter = wl1271_op_configure_filter, | 1916 | .configure_filter = wl1271_op_configure_filter, |
1931 | .tx = wl1271_op_tx, | 1917 | .tx = wl1271_op_tx, |
@@ -1937,6 +1923,68 @@ static const struct ieee80211_ops wl1271_ops = { | |||
1937 | CFG80211_TESTMODE_CMD(wl1271_tm_cmd) | 1923 | CFG80211_TESTMODE_CMD(wl1271_tm_cmd) |
1938 | }; | 1924 | }; |
1939 | 1925 | ||
1926 | static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev, | ||
1927 | struct device_attribute *attr, | ||
1928 | char *buf) | ||
1929 | { | ||
1930 | struct wl1271 *wl = dev_get_drvdata(dev); | ||
1931 | ssize_t len; | ||
1932 | |||
1933 | /* FIXME: what's the maximum length of buf? page size?*/ | ||
1934 | len = 500; | ||
1935 | |||
1936 | mutex_lock(&wl->mutex); | ||
1937 | len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n", | ||
1938 | wl->sg_enabled); | ||
1939 | mutex_unlock(&wl->mutex); | ||
1940 | |||
1941 | return len; | ||
1942 | |||
1943 | } | ||
1944 | |||
1945 | static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev, | ||
1946 | struct device_attribute *attr, | ||
1947 | const char *buf, size_t count) | ||
1948 | { | ||
1949 | struct wl1271 *wl = dev_get_drvdata(dev); | ||
1950 | unsigned long res; | ||
1951 | int ret; | ||
1952 | |||
1953 | ret = strict_strtoul(buf, 10, &res); | ||
1954 | |||
1955 | if (ret < 0) { | ||
1956 | wl1271_warning("incorrect value written to bt_coex_mode"); | ||
1957 | return count; | ||
1958 | } | ||
1959 | |||
1960 | mutex_lock(&wl->mutex); | ||
1961 | |||
1962 | res = !!res; | ||
1963 | |||
1964 | if (res == wl->sg_enabled) | ||
1965 | goto out; | ||
1966 | |||
1967 | wl->sg_enabled = res; | ||
1968 | |||
1969 | if (wl->state == WL1271_STATE_OFF) | ||
1970 | goto out; | ||
1971 | |||
1972 | ret = wl1271_ps_elp_wakeup(wl, false); | ||
1973 | if (ret < 0) | ||
1974 | goto out; | ||
1975 | |||
1976 | wl1271_acx_sg_enable(wl, wl->sg_enabled); | ||
1977 | wl1271_ps_elp_sleep(wl); | ||
1978 | |||
1979 | out: | ||
1980 | mutex_unlock(&wl->mutex); | ||
1981 | return count; | ||
1982 | } | ||
1983 | |||
1984 | static DEVICE_ATTR(bt_coex_state, S_IRUGO | S_IWUSR, | ||
1985 | wl1271_sysfs_show_bt_coex_state, | ||
1986 | wl1271_sysfs_store_bt_coex_state); | ||
1987 | |||
1940 | int wl1271_register_hw(struct wl1271 *wl) | 1988 | int wl1271_register_hw(struct wl1271 *wl) |
1941 | { | 1989 | { |
1942 | int ret; | 1990 | int ret; |
@@ -1960,6 +2008,14 @@ int wl1271_register_hw(struct wl1271 *wl) | |||
1960 | } | 2008 | } |
1961 | EXPORT_SYMBOL_GPL(wl1271_register_hw); | 2009 | EXPORT_SYMBOL_GPL(wl1271_register_hw); |
1962 | 2010 | ||
2011 | void wl1271_unregister_hw(struct wl1271 *wl) | ||
2012 | { | ||
2013 | ieee80211_unregister_hw(wl->hw); | ||
2014 | wl->mac80211_registered = false; | ||
2015 | |||
2016 | } | ||
2017 | EXPORT_SYMBOL_GPL(wl1271_unregister_hw); | ||
2018 | |||
1963 | int wl1271_init_ieee80211(struct wl1271 *wl) | 2019 | int wl1271_init_ieee80211(struct wl1271 *wl) |
1964 | { | 2020 | { |
1965 | /* The tx descriptor buffer and the TKIP space. */ | 2021 | /* The tx descriptor buffer and the TKIP space. */ |
@@ -1974,6 +2030,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl) | |||
1974 | IEEE80211_HW_NOISE_DBM | | 2030 | IEEE80211_HW_NOISE_DBM | |
1975 | IEEE80211_HW_BEACON_FILTER | | 2031 | IEEE80211_HW_BEACON_FILTER | |
1976 | IEEE80211_HW_SUPPORTS_PS | | 2032 | IEEE80211_HW_SUPPORTS_PS | |
2033 | IEEE80211_HW_SUPPORTS_UAPSD | | ||
1977 | IEEE80211_HW_HAS_RATE_CONTROL; | 2034 | IEEE80211_HW_HAS_RATE_CONTROL; |
1978 | 2035 | ||
1979 | wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | | 2036 | wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
@@ -1984,6 +2041,8 @@ int wl1271_init_ieee80211(struct wl1271 *wl) | |||
1984 | if (wl1271_11a_enabled()) | 2041 | if (wl1271_11a_enabled()) |
1985 | wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; | 2042 | wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; |
1986 | 2043 | ||
2044 | wl->hw->queues = 4; | ||
2045 | |||
1987 | SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl)); | 2046 | SET_IEEE80211_DEV(wl->hw, wl1271_wl_to_dev(wl)); |
1988 | 2047 | ||
1989 | return 0; | 2048 | return 0; |
@@ -1995,21 +2054,34 @@ EXPORT_SYMBOL_GPL(wl1271_init_ieee80211); | |||
1995 | struct ieee80211_hw *wl1271_alloc_hw(void) | 2054 | struct ieee80211_hw *wl1271_alloc_hw(void) |
1996 | { | 2055 | { |
1997 | struct ieee80211_hw *hw; | 2056 | struct ieee80211_hw *hw; |
2057 | struct platform_device *plat_dev = NULL; | ||
1998 | struct wl1271 *wl; | 2058 | struct wl1271 *wl; |
1999 | int i; | 2059 | int i, ret; |
2060 | static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf}; | ||
2000 | 2061 | ||
2001 | hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); | 2062 | hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); |
2002 | if (!hw) { | 2063 | if (!hw) { |
2003 | wl1271_error("could not alloc ieee80211_hw"); | 2064 | wl1271_error("could not alloc ieee80211_hw"); |
2004 | return ERR_PTR(-ENOMEM); | 2065 | ret = -ENOMEM; |
2066 | goto err_hw_alloc; | ||
2005 | } | 2067 | } |
2006 | 2068 | ||
2069 | plat_dev = kmalloc(sizeof(wl1271_device), GFP_KERNEL); | ||
2070 | if (!plat_dev) { | ||
2071 | wl1271_error("could not allocate platform_device"); | ||
2072 | ret = -ENOMEM; | ||
2073 | goto err_plat_alloc; | ||
2074 | } | ||
2075 | |||
2076 | memcpy(plat_dev, &wl1271_device, sizeof(wl1271_device)); | ||
2077 | |||
2007 | wl = hw->priv; | 2078 | wl = hw->priv; |
2008 | memset(wl, 0, sizeof(*wl)); | 2079 | memset(wl, 0, sizeof(*wl)); |
2009 | 2080 | ||
2010 | INIT_LIST_HEAD(&wl->list); | 2081 | INIT_LIST_HEAD(&wl->list); |
2011 | 2082 | ||
2012 | wl->hw = hw; | 2083 | wl->hw = hw; |
2084 | wl->plat_dev = plat_dev; | ||
2013 | 2085 | ||
2014 | skb_queue_head_init(&wl->tx_queue); | 2086 | skb_queue_head_init(&wl->tx_queue); |
2015 | 2087 | ||
@@ -2027,6 +2099,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) | |||
2027 | wl->band = IEEE80211_BAND_2GHZ; | 2099 | wl->band = IEEE80211_BAND_2GHZ; |
2028 | wl->vif = NULL; | 2100 | wl->vif = NULL; |
2029 | wl->flags = 0; | 2101 | wl->flags = 0; |
2102 | wl->sg_enabled = true; | ||
2030 | 2103 | ||
2031 | for (i = 0; i < ACX_TX_DESCRIPTORS; i++) | 2104 | for (i = 0; i < ACX_TX_DESCRIPTORS; i++) |
2032 | wl->tx_frames[i] = NULL; | 2105 | wl->tx_frames[i] = NULL; |
@@ -2036,18 +2109,55 @@ struct ieee80211_hw *wl1271_alloc_hw(void) | |||
2036 | wl->state = WL1271_STATE_OFF; | 2109 | wl->state = WL1271_STATE_OFF; |
2037 | mutex_init(&wl->mutex); | 2110 | mutex_init(&wl->mutex); |
2038 | 2111 | ||
2112 | /* | ||
2113 | * FIXME: we should use a zero MAC address here, but for now we | ||
2114 | * generate a random Nokia address. | ||
2115 | */ | ||
2116 | memcpy(wl->mac_addr, nokia_oui, 3); | ||
2117 | get_random_bytes(wl->mac_addr + 3, 3); | ||
2118 | |||
2039 | /* Apply default driver configuration. */ | 2119 | /* Apply default driver configuration. */ |
2040 | wl1271_conf_init(wl); | 2120 | wl1271_conf_init(wl); |
2041 | 2121 | ||
2042 | wl1271_debugfs_init(wl); | 2122 | wl1271_debugfs_init(wl); |
2043 | 2123 | ||
2124 | /* Register platform device */ | ||
2125 | ret = platform_device_register(wl->plat_dev); | ||
2126 | if (ret) { | ||
2127 | wl1271_error("couldn't register platform device"); | ||
2128 | goto err_hw; | ||
2129 | } | ||
2130 | dev_set_drvdata(&wl->plat_dev->dev, wl); | ||
2131 | |||
2132 | /* Create sysfs file to control bt coex state */ | ||
2133 | ret = device_create_file(&wl->plat_dev->dev, &dev_attr_bt_coex_state); | ||
2134 | if (ret < 0) { | ||
2135 | wl1271_error("failed to create sysfs file bt_coex_state"); | ||
2136 | goto err_platform; | ||
2137 | } | ||
2138 | |||
2044 | return hw; | 2139 | return hw; |
2140 | |||
2141 | err_platform: | ||
2142 | platform_device_unregister(wl->plat_dev); | ||
2143 | |||
2144 | err_hw: | ||
2145 | wl1271_debugfs_exit(wl); | ||
2146 | kfree(plat_dev); | ||
2147 | |||
2148 | err_plat_alloc: | ||
2149 | ieee80211_free_hw(hw); | ||
2150 | |||
2151 | err_hw_alloc: | ||
2152 | |||
2153 | return ERR_PTR(ret); | ||
2045 | } | 2154 | } |
2046 | EXPORT_SYMBOL_GPL(wl1271_alloc_hw); | 2155 | EXPORT_SYMBOL_GPL(wl1271_alloc_hw); |
2047 | 2156 | ||
2048 | int wl1271_free_hw(struct wl1271 *wl) | 2157 | int wl1271_free_hw(struct wl1271 *wl) |
2049 | { | 2158 | { |
2050 | ieee80211_unregister_hw(wl->hw); | 2159 | platform_device_unregister(wl->plat_dev); |
2160 | kfree(wl->plat_dev); | ||
2051 | 2161 | ||
2052 | wl1271_debugfs_exit(wl); | 2162 | wl1271_debugfs_exit(wl); |
2053 | 2163 | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c index 1f204db30c27..3c03de74dbfc 100644 --- a/drivers/net/wireless/wl12xx/wl1271_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c | |||
@@ -102,15 +102,14 @@ static void wl1271_sdio_init(struct wl1271 *wl) | |||
102 | } | 102 | } |
103 | 103 | ||
104 | static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, | 104 | static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, |
105 | size_t len, bool fixed) | 105 | size_t len, bool fixed) |
106 | { | 106 | { |
107 | int ret; | 107 | int ret; |
108 | struct sdio_func *func = wl_to_func(wl); | 108 | struct sdio_func *func = wl_to_func(wl); |
109 | 109 | ||
110 | sdio_claim_host(func); | ||
111 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { | 110 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { |
112 | ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); | 111 | ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); |
113 | wl1271_debug(DEBUG_SPI, "sdio read 52 addr 0x%x, byte 0x%02x", | 112 | wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x", |
114 | addr, ((u8 *)buf)[0]); | 113 | addr, ((u8 *)buf)[0]); |
115 | } else { | 114 | } else { |
116 | if (fixed) | 115 | if (fixed) |
@@ -118,32 +117,30 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, | |||
118 | else | 117 | else |
119 | ret = sdio_memcpy_fromio(func, buf, addr, len); | 118 | ret = sdio_memcpy_fromio(func, buf, addr, len); |
120 | 119 | ||
121 | wl1271_debug(DEBUG_SPI, "sdio read 53 addr 0x%x, %d bytes", | 120 | wl1271_debug(DEBUG_SDIO, "sdio read 53 addr 0x%x, %d bytes", |
122 | addr, len); | 121 | addr, len); |
123 | wl1271_dump_ascii(DEBUG_SPI, "data: ", buf, len); | 122 | wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); |
124 | } | 123 | } |
125 | 124 | ||
126 | if (ret) | 125 | if (ret) |
127 | wl1271_error("sdio read failed (%d)", ret); | 126 | wl1271_error("sdio read failed (%d)", ret); |
128 | 127 | ||
129 | sdio_release_host(func); | ||
130 | } | 128 | } |
131 | 129 | ||
132 | static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, | 130 | static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, |
133 | size_t len, bool fixed) | 131 | size_t len, bool fixed) |
134 | { | 132 | { |
135 | int ret; | 133 | int ret; |
136 | struct sdio_func *func = wl_to_func(wl); | 134 | struct sdio_func *func = wl_to_func(wl); |
137 | 135 | ||
138 | sdio_claim_host(func); | ||
139 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { | 136 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { |
140 | sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); | 137 | sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); |
141 | wl1271_debug(DEBUG_SPI, "sdio write 52 addr 0x%x, byte 0x%02x", | 138 | wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", |
142 | addr, ((u8 *)buf)[0]); | 139 | addr, ((u8 *)buf)[0]); |
143 | } else { | 140 | } else { |
144 | wl1271_debug(DEBUG_SPI, "sdio write 53 addr 0x%x, %d bytes", | 141 | wl1271_debug(DEBUG_SDIO, "sdio write 53 addr 0x%x, %d bytes", |
145 | addr, len); | 142 | addr, len); |
146 | wl1271_dump_ascii(DEBUG_SPI, "data: ", buf, len); | 143 | wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); |
147 | 144 | ||
148 | if (fixed) | 145 | if (fixed) |
149 | ret = sdio_writesb(func, addr, buf, len); | 146 | ret = sdio_writesb(func, addr, buf, len); |
@@ -153,7 +150,23 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, | |||
153 | if (ret) | 150 | if (ret) |
154 | wl1271_error("sdio write failed (%d)", ret); | 151 | wl1271_error("sdio write failed (%d)", ret); |
155 | 152 | ||
156 | sdio_release_host(func); | 153 | } |
154 | |||
155 | static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable) | ||
156 | { | ||
157 | struct sdio_func *func = wl_to_func(wl); | ||
158 | |||
159 | /* Let the SDIO stack handle wlan_enable control, so we | ||
160 | * keep host claimed while wlan is in use to keep wl1271 | ||
161 | * alive. | ||
162 | */ | ||
163 | if (enable) { | ||
164 | sdio_claim_host(func); | ||
165 | sdio_enable_func(func); | ||
166 | } else { | ||
167 | sdio_disable_func(func); | ||
168 | sdio_release_host(func); | ||
169 | } | ||
157 | } | 170 | } |
158 | 171 | ||
159 | static struct wl1271_if_operations sdio_ops = { | 172 | static struct wl1271_if_operations sdio_ops = { |
@@ -161,15 +174,12 @@ static struct wl1271_if_operations sdio_ops = { | |||
161 | .write = wl1271_sdio_raw_write, | 174 | .write = wl1271_sdio_raw_write, |
162 | .reset = wl1271_sdio_reset, | 175 | .reset = wl1271_sdio_reset, |
163 | .init = wl1271_sdio_init, | 176 | .init = wl1271_sdio_init, |
177 | .power = wl1271_sdio_set_power, | ||
164 | .dev = wl1271_sdio_wl_to_dev, | 178 | .dev = wl1271_sdio_wl_to_dev, |
165 | .enable_irq = wl1271_sdio_enable_interrupts, | 179 | .enable_irq = wl1271_sdio_enable_interrupts, |
166 | .disable_irq = wl1271_sdio_disable_interrupts | 180 | .disable_irq = wl1271_sdio_disable_interrupts |
167 | }; | 181 | }; |
168 | 182 | ||
169 | static void wl1271_sdio_set_power(bool enable) | ||
170 | { | ||
171 | } | ||
172 | |||
173 | static int __devinit wl1271_probe(struct sdio_func *func, | 183 | static int __devinit wl1271_probe(struct sdio_func *func, |
174 | const struct sdio_device_id *id) | 184 | const struct sdio_device_id *id) |
175 | { | 185 | { |
@@ -190,8 +200,6 @@ static int __devinit wl1271_probe(struct sdio_func *func, | |||
190 | wl->if_priv = func; | 200 | wl->if_priv = func; |
191 | wl->if_ops = &sdio_ops; | 201 | wl->if_ops = &sdio_ops; |
192 | 202 | ||
193 | wl->set_power = wl1271_sdio_set_power; | ||
194 | |||
195 | /* Grab access to FN0 for ELP reg. */ | 203 | /* Grab access to FN0 for ELP reg. */ |
196 | func->card->quirks |= MMC_QUIRK_LENIENT_FN0; | 204 | func->card->quirks |= MMC_QUIRK_LENIENT_FN0; |
197 | 205 | ||
@@ -220,28 +228,18 @@ static int __devinit wl1271_probe(struct sdio_func *func, | |||
220 | if (ret) | 228 | if (ret) |
221 | goto out_irq; | 229 | goto out_irq; |
222 | 230 | ||
223 | sdio_claim_host(func); | ||
224 | sdio_set_drvdata(func, wl); | 231 | sdio_set_drvdata(func, wl); |
225 | 232 | ||
226 | ret = sdio_enable_func(func); | ||
227 | if (ret) | ||
228 | goto out_release; | ||
229 | |||
230 | sdio_release_host(func); | ||
231 | |||
232 | wl1271_notice("initialized"); | 233 | wl1271_notice("initialized"); |
233 | 234 | ||
234 | return 0; | 235 | return 0; |
235 | 236 | ||
236 | out_release: | ||
237 | sdio_release_host(func); | ||
238 | |||
239 | out_irq: | 237 | out_irq: |
240 | free_irq(wl->irq, wl); | 238 | free_irq(wl->irq, wl); |
241 | 239 | ||
242 | 240 | ||
243 | out_free: | 241 | out_free: |
244 | ieee80211_free_hw(hw); | 242 | wl1271_free_hw(wl); |
245 | 243 | ||
246 | return ret; | 244 | return ret; |
247 | } | 245 | } |
@@ -250,24 +248,10 @@ static void __devexit wl1271_remove(struct sdio_func *func) | |||
250 | { | 248 | { |
251 | struct wl1271 *wl = sdio_get_drvdata(func); | 249 | struct wl1271 *wl = sdio_get_drvdata(func); |
252 | 250 | ||
253 | ieee80211_unregister_hw(wl->hw); | ||
254 | |||
255 | sdio_claim_host(func); | ||
256 | sdio_disable_func(func); | ||
257 | sdio_release_host(func); | ||
258 | |||
259 | free_irq(wl->irq, wl); | 251 | free_irq(wl->irq, wl); |
260 | 252 | ||
261 | kfree(wl->target_mem_map); | 253 | wl1271_unregister_hw(wl); |
262 | vfree(wl->fw); | 254 | wl1271_free_hw(wl); |
263 | wl->fw = NULL; | ||
264 | kfree(wl->nvs); | ||
265 | wl->nvs = NULL; | ||
266 | |||
267 | kfree(wl->fw_status); | ||
268 | kfree(wl->tx_res_if); | ||
269 | |||
270 | ieee80211_free_hw(wl->hw); | ||
271 | } | 255 | } |
272 | 256 | ||
273 | static struct sdio_driver wl1271_sdio_driver = { | 257 | static struct sdio_driver wl1271_sdio_driver = { |
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c index ed285fec2a08..f44b05a32b0d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_spi.c +++ b/drivers/net/wireless/wl12xx/wl1271_spi.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/crc7.h> | 26 | #include <linux/crc7.h> |
28 | #include <linux/spi/spi.h> | 27 | #include <linux/spi/spi.h> |
29 | #include <linux/spi/wl12xx.h> | 28 | #include <linux/spi/wl12xx.h> |
@@ -332,26 +331,18 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) | |||
332 | return IRQ_HANDLED; | 331 | return IRQ_HANDLED; |
333 | } | 332 | } |
334 | 333 | ||
335 | static void wl1271_device_release(struct device *dev) | 334 | static void wl1271_spi_set_power(struct wl1271 *wl, bool enable) |
336 | { | 335 | { |
337 | 336 | if (wl->set_power) | |
337 | wl->set_power(enable); | ||
338 | } | 338 | } |
339 | 339 | ||
340 | static struct platform_device wl1271_device = { | ||
341 | .name = "wl1271", | ||
342 | .id = -1, | ||
343 | |||
344 | /* device model insists to have a release function */ | ||
345 | .dev = { | ||
346 | .release = wl1271_device_release, | ||
347 | }, | ||
348 | }; | ||
349 | |||
350 | static struct wl1271_if_operations spi_ops = { | 340 | static struct wl1271_if_operations spi_ops = { |
351 | .read = wl1271_spi_raw_read, | 341 | .read = wl1271_spi_raw_read, |
352 | .write = wl1271_spi_raw_write, | 342 | .write = wl1271_spi_raw_write, |
353 | .reset = wl1271_spi_reset, | 343 | .reset = wl1271_spi_reset, |
354 | .init = wl1271_spi_init, | 344 | .init = wl1271_spi_init, |
345 | .power = wl1271_spi_set_power, | ||
355 | .dev = wl1271_spi_wl_to_dev, | 346 | .dev = wl1271_spi_wl_to_dev, |
356 | .enable_irq = wl1271_spi_enable_interrupts, | 347 | .enable_irq = wl1271_spi_enable_interrupts, |
357 | .disable_irq = wl1271_spi_disable_interrupts | 348 | .disable_irq = wl1271_spi_disable_interrupts |
@@ -415,33 +406,23 @@ static int __devinit wl1271_probe(struct spi_device *spi) | |||
415 | 406 | ||
416 | disable_irq(wl->irq); | 407 | disable_irq(wl->irq); |
417 | 408 | ||
418 | ret = platform_device_register(&wl1271_device); | ||
419 | if (ret) { | ||
420 | wl1271_error("couldn't register platform device"); | ||
421 | goto out_irq; | ||
422 | } | ||
423 | dev_set_drvdata(&wl1271_device.dev, wl); | ||
424 | |||
425 | ret = wl1271_init_ieee80211(wl); | 409 | ret = wl1271_init_ieee80211(wl); |
426 | if (ret) | 410 | if (ret) |
427 | goto out_platform; | 411 | goto out_irq; |
428 | 412 | ||
429 | ret = wl1271_register_hw(wl); | 413 | ret = wl1271_register_hw(wl); |
430 | if (ret) | 414 | if (ret) |
431 | goto out_platform; | 415 | goto out_irq; |
432 | 416 | ||
433 | wl1271_notice("initialized"); | 417 | wl1271_notice("initialized"); |
434 | 418 | ||
435 | return 0; | 419 | return 0; |
436 | 420 | ||
437 | out_platform: | ||
438 | platform_device_unregister(&wl1271_device); | ||
439 | |||
440 | out_irq: | 421 | out_irq: |
441 | free_irq(wl->irq, wl); | 422 | free_irq(wl->irq, wl); |
442 | 423 | ||
443 | out_free: | 424 | out_free: |
444 | ieee80211_free_hw(hw); | 425 | wl1271_free_hw(wl); |
445 | 426 | ||
446 | return ret; | 427 | return ret; |
447 | } | 428 | } |
@@ -450,9 +431,9 @@ static int __devexit wl1271_remove(struct spi_device *spi) | |||
450 | { | 431 | { |
451 | struct wl1271 *wl = dev_get_drvdata(&spi->dev); | 432 | struct wl1271 *wl = dev_get_drvdata(&spi->dev); |
452 | 433 | ||
453 | platform_device_unregister(&wl1271_device); | ||
454 | free_irq(wl->irq, wl); | 434 | free_irq(wl->irq, wl); |
455 | 435 | ||
436 | wl1271_unregister_hw(wl); | ||
456 | wl1271_free_hw(wl); | 437 | wl1271_free_hw(wl); |
457 | 438 | ||
458 | return 0; | 439 | return 0; |
diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h index 8b9f6b4f5652..5e6c27a57415 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.h +++ b/drivers/net/wireless/wl12xx/wl1271_tx.h | |||
@@ -125,9 +125,6 @@ struct wl1271_tx_hw_res_if { | |||
125 | 125 | ||
126 | static inline int wl1271_tx_get_queue(int queue) | 126 | static inline int wl1271_tx_get_queue(int queue) |
127 | { | 127 | { |
128 | /* FIXME: use best effort until WMM is enabled */ | ||
129 | return CONF_TX_AC_BE; | ||
130 | |||
131 | switch (queue) { | 128 | switch (queue) { |
132 | case 0: | 129 | case 0: |
133 | return CONF_TX_AC_VO; | 130 | return CONF_TX_AC_VO; |