diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/init.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 80 |
1 files changed, 45 insertions, 35 deletions
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 710192ed27ed..1fc2e5a26b52 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -57,6 +57,10 @@ static int ath9k_bt_ant_diversity; | |||
57 | module_param_named(bt_ant_diversity, ath9k_bt_ant_diversity, int, 0444); | 57 | module_param_named(bt_ant_diversity, ath9k_bt_ant_diversity, int, 0444); |
58 | MODULE_PARM_DESC(bt_ant_diversity, "Enable WLAN/BT RX antenna diversity"); | 58 | MODULE_PARM_DESC(bt_ant_diversity, "Enable WLAN/BT RX antenna diversity"); |
59 | 59 | ||
60 | static int ath9k_ps_enable; | ||
61 | module_param_named(ps_enable, ath9k_ps_enable, int, 0444); | ||
62 | MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave"); | ||
63 | |||
60 | bool is_ath9k_unloaded; | 64 | bool is_ath9k_unloaded; |
61 | /* We use the hw_value as an index into our private channel structure */ | 65 | /* We use the hw_value as an index into our private channel structure */ |
62 | 66 | ||
@@ -470,7 +474,6 @@ static int ath9k_init_queues(struct ath_softc *sc) | |||
470 | 474 | ||
471 | sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah); | 475 | sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah); |
472 | sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); | 476 | sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); |
473 | |||
474 | ath_cabq_update(sc); | 477 | ath_cabq_update(sc); |
475 | 478 | ||
476 | sc->tx.uapsdq = ath_txq_setup(sc, ATH9K_TX_QUEUE_UAPSD, 0); | 479 | sc->tx.uapsdq = ath_txq_setup(sc, ATH9K_TX_QUEUE_UAPSD, 0); |
@@ -554,7 +557,7 @@ static void ath9k_init_misc(struct ath_softc *sc) | |||
554 | sc->spec_config.fft_period = 0xF; | 557 | sc->spec_config.fft_period = 0xF; |
555 | } | 558 | } |
556 | 559 | ||
557 | static void ath9k_init_platform(struct ath_softc *sc) | 560 | static void ath9k_init_pcoem_platform(struct ath_softc *sc) |
558 | { | 561 | { |
559 | struct ath_hw *ah = sc->sc_ah; | 562 | struct ath_hw *ah = sc->sc_ah; |
560 | struct ath9k_hw_capabilities *pCap = &ah->caps; | 563 | struct ath9k_hw_capabilities *pCap = &ah->caps; |
@@ -589,6 +592,9 @@ static void ath9k_init_platform(struct ath_softc *sc) | |||
589 | if (sc->driver_data & ATH9K_PCI_AR9565_2ANT) | 592 | if (sc->driver_data & ATH9K_PCI_AR9565_2ANT) |
590 | ath_info(common, "WB335 2-ANT card detected\n"); | 593 | ath_info(common, "WB335 2-ANT card detected\n"); |
591 | 594 | ||
595 | if (sc->driver_data & ATH9K_PCI_KILLER) | ||
596 | ath_info(common, "Killer Wireless card detected\n"); | ||
597 | |||
592 | /* | 598 | /* |
593 | * Some WB335 cards do not support antenna diversity. Since | 599 | * Some WB335 cards do not support antenna diversity. Since |
594 | * we use a hardcoded value for AR9565 instead of using the | 600 | * we use a hardcoded value for AR9565 instead of using the |
@@ -661,6 +667,27 @@ static void ath9k_eeprom_release(struct ath_softc *sc) | |||
661 | release_firmware(sc->sc_ah->eeprom_blob); | 667 | release_firmware(sc->sc_ah->eeprom_blob); |
662 | } | 668 | } |
663 | 669 | ||
670 | static int ath9k_init_soc_platform(struct ath_softc *sc) | ||
671 | { | ||
672 | struct ath9k_platform_data *pdata = sc->dev->platform_data; | ||
673 | struct ath_hw *ah = sc->sc_ah; | ||
674 | int ret = 0; | ||
675 | |||
676 | if (!pdata) | ||
677 | return 0; | ||
678 | |||
679 | if (pdata->eeprom_name) { | ||
680 | ret = ath9k_eeprom_request(sc, pdata->eeprom_name); | ||
681 | if (ret) | ||
682 | return ret; | ||
683 | } | ||
684 | |||
685 | if (pdata->tx_gain_buffalo) | ||
686 | ah->config.tx_gain_buffalo = true; | ||
687 | |||
688 | return ret; | ||
689 | } | ||
690 | |||
664 | static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | 691 | static int ath9k_init_softc(u16 devid, struct ath_softc *sc, |
665 | const struct ath_bus_ops *bus_ops) | 692 | const struct ath_bus_ops *bus_ops) |
666 | { | 693 | { |
@@ -681,13 +708,13 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
681 | ah->reg_ops.read = ath9k_ioread32; | 708 | ah->reg_ops.read = ath9k_ioread32; |
682 | ah->reg_ops.write = ath9k_iowrite32; | 709 | ah->reg_ops.write = ath9k_iowrite32; |
683 | ah->reg_ops.rmw = ath9k_reg_rmw; | 710 | ah->reg_ops.rmw = ath9k_reg_rmw; |
684 | atomic_set(&ah->intr_ref_cnt, -1); | ||
685 | sc->sc_ah = ah; | 711 | sc->sc_ah = ah; |
686 | pCap = &ah->caps; | 712 | pCap = &ah->caps; |
687 | 713 | ||
688 | common = ath9k_hw_common(ah); | 714 | common = ath9k_hw_common(ah); |
689 | sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET); | 715 | sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET); |
690 | sc->tx99_power = MAX_RATE_POWER + 1; | 716 | sc->tx99_power = MAX_RATE_POWER + 1; |
717 | init_waitqueue_head(&sc->tx_wait); | ||
691 | 718 | ||
692 | if (!pdata) { | 719 | if (!pdata) { |
693 | ah->ah_flags |= AH_USE_EEPROM; | 720 | ah->ah_flags |= AH_USE_EEPROM; |
@@ -713,7 +740,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
713 | /* | 740 | /* |
714 | * Platform quirks. | 741 | * Platform quirks. |
715 | */ | 742 | */ |
716 | ath9k_init_platform(sc); | 743 | ath9k_init_pcoem_platform(sc); |
744 | |||
745 | ret = ath9k_init_soc_platform(sc); | ||
746 | if (ret) | ||
747 | return ret; | ||
717 | 748 | ||
718 | /* | 749 | /* |
719 | * Enable WLAN/BT RX Antenna diversity only when: | 750 | * Enable WLAN/BT RX Antenna diversity only when: |
@@ -727,7 +758,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
727 | common->bt_ant_diversity = 1; | 758 | common->bt_ant_diversity = 1; |
728 | 759 | ||
729 | spin_lock_init(&common->cc_lock); | 760 | spin_lock_init(&common->cc_lock); |
730 | |||
731 | spin_lock_init(&sc->sc_serial_rw); | 761 | spin_lock_init(&sc->sc_serial_rw); |
732 | spin_lock_init(&sc->sc_pm_lock); | 762 | spin_lock_init(&sc->sc_pm_lock); |
733 | mutex_init(&sc->mutex); | 763 | mutex_init(&sc->mutex); |
@@ -735,11 +765,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
735 | tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, | 765 | tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, |
736 | (unsigned long)sc); | 766 | (unsigned long)sc); |
737 | 767 | ||
768 | setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc); | ||
738 | INIT_WORK(&sc->hw_reset_work, ath_reset_work); | 769 | INIT_WORK(&sc->hw_reset_work, ath_reset_work); |
739 | INIT_WORK(&sc->hw_check_work, ath_hw_check); | ||
740 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); | 770 | INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); |
741 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | 771 | INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); |
742 | setup_timer(&sc->rx_poll_timer, ath_rx_poll, (unsigned long)sc); | ||
743 | 772 | ||
744 | /* | 773 | /* |
745 | * Cache line size is used to size and align various | 774 | * Cache line size is used to size and align various |
@@ -748,12 +777,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
748 | ath_read_cachesize(common, &csz); | 777 | ath_read_cachesize(common, &csz); |
749 | common->cachelsz = csz << 2; /* convert to bytes */ | 778 | common->cachelsz = csz << 2; /* convert to bytes */ |
750 | 779 | ||
751 | if (pdata && pdata->eeprom_name) { | ||
752 | ret = ath9k_eeprom_request(sc, pdata->eeprom_name); | ||
753 | if (ret) | ||
754 | return ret; | ||
755 | } | ||
756 | |||
757 | /* Initializes the hardware for all supported chipsets */ | 780 | /* Initializes the hardware for all supported chipsets */ |
758 | ret = ath9k_hw_init(ah); | 781 | ret = ath9k_hw_init(ah); |
759 | if (ret) | 782 | if (ret) |
@@ -851,6 +874,9 @@ static const struct ieee80211_iface_limit if_limits[] = { | |||
851 | 874 | ||
852 | static const struct ieee80211_iface_limit if_dfs_limits[] = { | 875 | static const struct ieee80211_iface_limit if_dfs_limits[] = { |
853 | { .max = 1, .types = BIT(NL80211_IFTYPE_AP) | | 876 | { .max = 1, .types = BIT(NL80211_IFTYPE_AP) | |
877 | #ifdef CONFIG_MAC80211_MESH | ||
878 | BIT(NL80211_IFTYPE_MESH_POINT) | | ||
879 | #endif | ||
854 | BIT(NL80211_IFTYPE_ADHOC) }, | 880 | BIT(NL80211_IFTYPE_ADHOC) }, |
855 | }; | 881 | }; |
856 | 882 | ||
@@ -873,16 +899,7 @@ static const struct ieee80211_iface_combination if_comb[] = { | |||
873 | } | 899 | } |
874 | }; | 900 | }; |
875 | 901 | ||
876 | #ifdef CONFIG_PM | 902 | static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) |
877 | static const struct wiphy_wowlan_support ath9k_wowlan_support = { | ||
878 | .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, | ||
879 | .n_patterns = MAX_NUM_USER_PATTERN, | ||
880 | .pattern_min_len = 1, | ||
881 | .pattern_max_len = MAX_PATTERN_SIZE, | ||
882 | }; | ||
883 | #endif | ||
884 | |||
885 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | ||
886 | { | 903 | { |
887 | struct ath_hw *ah = sc->sc_ah; | 904 | struct ath_hw *ah = sc->sc_ah; |
888 | struct ath_common *common = ath9k_hw_common(ah); | 905 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -890,13 +907,15 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
890 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 907 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
891 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 908 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
892 | IEEE80211_HW_SIGNAL_DBM | | 909 | IEEE80211_HW_SIGNAL_DBM | |
893 | IEEE80211_HW_SUPPORTS_PS | | ||
894 | IEEE80211_HW_PS_NULLFUNC_STACK | | 910 | IEEE80211_HW_PS_NULLFUNC_STACK | |
895 | IEEE80211_HW_SPECTRUM_MGMT | | 911 | IEEE80211_HW_SPECTRUM_MGMT | |
896 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 912 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
897 | IEEE80211_HW_SUPPORTS_RC_TABLE | | 913 | IEEE80211_HW_SUPPORTS_RC_TABLE | |
898 | IEEE80211_HW_SUPPORTS_HT_CCK_RATES; | 914 | IEEE80211_HW_SUPPORTS_HT_CCK_RATES; |
899 | 915 | ||
916 | if (ath9k_ps_enable) | ||
917 | hw->flags |= IEEE80211_HW_SUPPORTS_PS; | ||
918 | |||
900 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | 919 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { |
901 | hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; | 920 | hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; |
902 | 921 | ||
@@ -931,19 +950,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
931 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ; | 950 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ; |
932 | hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; | 951 | hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; |
933 | 952 | ||
934 | #ifdef CONFIG_PM_SLEEP | ||
935 | if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) && | ||
936 | (sc->driver_data & ATH9K_PCI_WOW) && | ||
937 | device_can_wakeup(sc->dev)) | ||
938 | hw->wiphy->wowlan = &ath9k_wowlan_support; | ||
939 | |||
940 | atomic_set(&sc->wow_sleep_proc_intr, -1); | ||
941 | atomic_set(&sc->wow_got_bmiss_intr, -1); | ||
942 | #endif | ||
943 | |||
944 | hw->queues = 4; | 953 | hw->queues = 4; |
945 | hw->max_rates = 4; | 954 | hw->max_rates = 4; |
946 | hw->channel_change_time = 5000; | ||
947 | hw->max_listen_interval = 1; | 955 | hw->max_listen_interval = 1; |
948 | hw->max_rate_tries = 10; | 956 | hw->max_rate_tries = 10; |
949 | hw->sta_data_size = sizeof(struct ath_node); | 957 | hw->sta_data_size = sizeof(struct ath_node); |
@@ -966,6 +974,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
966 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = | 974 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = |
967 | &sc->sbands[IEEE80211_BAND_5GHZ]; | 975 | &sc->sbands[IEEE80211_BAND_5GHZ]; |
968 | 976 | ||
977 | ath9k_init_wow(hw); | ||
969 | ath9k_reload_chainmask_settings(sc); | 978 | ath9k_reload_chainmask_settings(sc); |
970 | 979 | ||
971 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); | 980 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); |
@@ -1064,6 +1073,7 @@ static void ath9k_deinit_softc(struct ath_softc *sc) | |||
1064 | if (ATH_TXQ_SETUP(sc, i)) | 1073 | if (ATH_TXQ_SETUP(sc, i)) |
1065 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); | 1074 | ath_tx_cleanupq(sc, &sc->tx.txq[i]); |
1066 | 1075 | ||
1076 | del_timer_sync(&sc->sleep_timer); | ||
1067 | ath9k_hw_deinit(sc->sc_ah); | 1077 | ath9k_hw_deinit(sc->sc_ah); |
1068 | if (sc->dfs_detector != NULL) | 1078 | if (sc->dfs_detector != NULL) |
1069 | sc->dfs_detector->exit(sc->dfs_detector); | 1079 | sc->dfs_detector->exit(sc->dfs_detector); |