aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k/main.c
diff options
context:
space:
mode:
authorSujith <Sujith.Manoharan@atheros.com>2008-10-29 00:47:13 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-11-10 15:16:06 -0500
commit9c84b7978f1b99048bf31be5a0218cd509e74148 (patch)
tree91f60b0986c75c6536c467a475568e33ff757245 /drivers/net/wireless/ath9k/main.c
parent50fdae2c7bcb6417997f90c3d9853a59a9ed06ce (diff)
ath9k: Streamline attach/detach
Simplify attach and detach routines by consolidating the stop and suspend functions. Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath9k/main.c')
-rw-r--r--drivers/net/wireless/ath9k/main.c185
1 files changed, 79 insertions, 106 deletions
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 0194e44034e..0d600020554 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -616,6 +616,7 @@ fail:
616} 616}
617 617
618#ifdef CONFIG_RFKILL 618#ifdef CONFIG_RFKILL
619
619/*******************/ 620/*******************/
620/* Rfkill */ 621/* Rfkill */
621/*******************/ 622/*******************/
@@ -816,43 +817,72 @@ static void ath_deinit_rfkill(struct ath_softc *sc)
816 sc->rf_kill.rfkill = NULL; 817 sc->rf_kill.rfkill = NULL;
817 } 818 }
818} 819}
820
821static int ath_start_rfkill_poll(struct ath_softc *sc)
822{
823 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
824 queue_delayed_work(sc->hw->workqueue,
825 &sc->rf_kill.rfkill_poll, 0);
826
827 if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) {
828 if (rfkill_register(sc->rf_kill.rfkill)) {
829 DPRINTF(sc, ATH_DBG_FATAL,
830 "Unable to register rfkill\n");
831 rfkill_free(sc->rf_kill.rfkill);
832
833 /* Deinitialize the device */
834 if (sc->pdev->irq)
835 free_irq(sc->pdev->irq, sc);
836 ath_detach(sc);
837 pci_iounmap(sc->pdev, sc->mem);
838 pci_release_region(sc->pdev, 0);
839 pci_disable_device(sc->pdev);
840 ieee80211_free_hw(hw);
841 return -EIO;
842 } else {
843 sc->sc_flags |= SC_OP_RFKILL_REGISTERED;
844 }
845 }
846
847 return 0;
848}
819#endif /* CONFIG_RFKILL */ 849#endif /* CONFIG_RFKILL */
820 850
821static int ath_detach(struct ath_softc *sc) 851static void ath_detach(struct ath_softc *sc)
822{ 852{
823 struct ieee80211_hw *hw = sc->hw; 853 struct ieee80211_hw *hw = sc->hw;
854 int i = 0;
824 855
825 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__); 856 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__);
826 857
827 /* Deinit LED control */ 858 ieee80211_unregister_hw(hw);
859
828 ath_deinit_leds(sc); 860 ath_deinit_leds(sc);
829 861
830#ifdef CONFIG_RFKILL 862#ifdef CONFIG_RFKILL
831 /* deinit rfkill */
832 ath_deinit_rfkill(sc); 863 ath_deinit_rfkill(sc);
833#endif 864#endif
834
835 /* Unregister hw */
836
837 ieee80211_unregister_hw(hw);
838
839 /* unregister Rate control */
840 ath_rate_control_unregister(); 865 ath_rate_control_unregister();
841 866 ath_rate_detach(sc->sc_rc);
842 /* tx/rx cleanup */
843 867
844 ath_rx_cleanup(sc); 868 ath_rx_cleanup(sc);
845 ath_tx_cleanup(sc); 869 ath_tx_cleanup(sc);
846 870
847 /* Deinit */ 871 tasklet_kill(&sc->intr_tq);
872 tasklet_kill(&sc->bcon_tasklet);
848 873
849 ath_deinit(sc); 874 if (!(sc->sc_flags & SC_OP_INVALID))
875 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
850 876
851 return 0; 877 /* cleanup tx queues */
878 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
879 if (ATH_TXQ_SETUP(sc, i))
880 ath_tx_cleanupq(sc, &sc->sc_txq[i]);
881
882 ath9k_hw_detach(sc->sc_ah);
852} 883}
853 884
854static int ath_attach(u16 devid, 885static int ath_attach(u16 devid, struct ath_softc *sc)
855 struct ath_softc *sc)
856{ 886{
857 struct ieee80211_hw *hw = sc->hw; 887 struct ieee80211_hw *hw = sc->hw;
858 int error = 0; 888 int error = 0;
@@ -867,36 +897,15 @@ static int ath_attach(u16 devid,
867 897
868 SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr); 898 SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr);
869 899
870 /* setup channels and rates */ 900 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
871 901 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
872 sc->sbands[IEEE80211_BAND_2GHZ].channels = 902 IEEE80211_HW_SIGNAL_DBM |
873 sc->channels[IEEE80211_BAND_2GHZ]; 903 IEEE80211_HW_AMPDU_AGGREGATION;
874 sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
875 sc->rates[IEEE80211_BAND_2GHZ];
876 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
877
878 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
879 /* Setup HT capabilities for 2.4Ghz*/
880 setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
881
882 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
883 &sc->sbands[IEEE80211_BAND_2GHZ];
884
885 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) {
886 sc->sbands[IEEE80211_BAND_5GHZ].channels =
887 sc->channels[IEEE80211_BAND_5GHZ];
888 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
889 sc->rates[IEEE80211_BAND_5GHZ];
890 sc->sbands[IEEE80211_BAND_5GHZ].band =
891 IEEE80211_BAND_5GHZ;
892
893 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
894 /* Setup HT capabilities for 5Ghz*/
895 setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
896 904
897 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 905 hw->wiphy->interface_modes =
898 &sc->sbands[IEEE80211_BAND_5GHZ]; 906 BIT(NL80211_IFTYPE_AP) |
899 } 907 BIT(NL80211_IFTYPE_STATION) |
908 BIT(NL80211_IFTYPE_ADHOC);
900 909
901 hw->queues = 4; 910 hw->queues = 4;
902 hw->sta_data_size = sizeof(struct ath_node); 911 hw->sta_data_size = sizeof(struct ath_node);
@@ -913,6 +922,17 @@ static int ath_attach(u16 devid,
913 goto bad; 922 goto bad;
914 } 923 }
915 924
925 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) {
926 setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
927 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes))
928 setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
929 }
930
931 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &sc->sbands[IEEE80211_BAND_2GHZ];
932 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes))
933 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
934 &sc->sbands[IEEE80211_BAND_5GHZ];
935
916 error = ieee80211_register_hw(hw); 936 error = ieee80211_register_hw(hw);
917 if (error != 0) { 937 if (error != 0) {
918 ath_rate_control_unregister(); 938 ath_rate_control_unregister();
@@ -963,49 +983,26 @@ static int ath9k_start(struct ieee80211_hw *hw)
963 pos = ath_get_channel(sc, curchan); 983 pos = ath_get_channel(sc, curchan);
964 if (pos == -1) { 984 if (pos == -1) {
965 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__); 985 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__);
966 return -EINVAL; 986 error = -EINVAL;
987 goto exit;
967 } 988 }
968 989
969 sc->sc_ah->ah_channels[pos].chanmode = 990 sc->sc_ah->ah_channels[pos].chanmode =
970 (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A; 991 (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A;
971 992
972 /* open ath_dev */
973 error = ath_open(sc, &sc->sc_ah->ah_channels[pos]); 993 error = ath_open(sc, &sc->sc_ah->ah_channels[pos]);
974 if (error) { 994 if (error) {
975 DPRINTF(sc, ATH_DBG_FATAL, 995 DPRINTF(sc, ATH_DBG_FATAL,
976 "%s: Unable to complete ath_open\n", __func__); 996 "%s: Unable to complete ath_open\n", __func__);
977 return error; 997 goto exit;
978 } 998 }
979 999
980#ifdef CONFIG_RFKILL 1000#ifdef CONFIG_RFKILL
981 /* Start rfkill polling */ 1001 error = ath_start_rfkill_poll(sc);
982 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
983 queue_delayed_work(sc->hw->workqueue,
984 &sc->rf_kill.rfkill_poll, 0);
985
986 if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) {
987 if (rfkill_register(sc->rf_kill.rfkill)) {
988 DPRINTF(sc, ATH_DBG_FATAL,
989 "Unable to register rfkill\n");
990 rfkill_free(sc->rf_kill.rfkill);
991
992 /* Deinitialize the device */
993 if (sc->pdev->irq)
994 free_irq(sc->pdev->irq, sc);
995 ath_detach(sc);
996 pci_iounmap(sc->pdev, sc->mem);
997 pci_release_region(sc->pdev, 0);
998 pci_disable_device(sc->pdev);
999 ieee80211_free_hw(hw);
1000 return -EIO;
1001 } else {
1002 sc->sc_flags |= SC_OP_RFKILL_REGISTERED;
1003 }
1004 }
1005#endif 1002#endif
1006 1003
1007 ieee80211_wake_queues(hw); 1004exit:
1008 return 0; 1005 return error;
1009} 1006}
1010 1007
1011static int ath9k_tx(struct ieee80211_hw *hw, 1008static int ath9k_tx(struct ieee80211_hw *hw,
@@ -1065,21 +1062,15 @@ exit:
1065static void ath9k_stop(struct ieee80211_hw *hw) 1062static void ath9k_stop(struct ieee80211_hw *hw)
1066{ 1063{
1067 struct ath_softc *sc = hw->priv; 1064 struct ath_softc *sc = hw->priv;
1068 int error;
1069 1065
1070 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Driver halt\n", __func__); 1066 if (sc->sc_flags & SC_OP_INVALID) {
1071 1067 DPRINTF(sc, ATH_DBG_ANY, "%s: Device not present\n", __func__);
1072 error = ath_suspend(sc); 1068 return;
1073 if (error) 1069 }
1074 DPRINTF(sc, ATH_DBG_CONFIG,
1075 "%s: Device is no longer present\n", __func__);
1076 1070
1077 ieee80211_stop_queues(hw); 1071 ath_stop(sc);
1078 1072
1079#ifdef CONFIG_RFKILL 1073 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Driver halt\n", __func__);
1080 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1081 cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
1082#endif
1083} 1074}
1084 1075
1085static int ath9k_add_interface(struct ieee80211_hw *hw, 1076static int ath9k_add_interface(struct ieee80211_hw *hw,
@@ -1643,17 +1634,6 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1643 goto bad2; 1634 goto bad2;
1644 } 1635 }
1645 1636
1646 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
1647 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1648 IEEE80211_HW_SIGNAL_DBM |
1649 IEEE80211_HW_NOISE_DBM |
1650 IEEE80211_HW_AMPDU_AGGREGATION;
1651
1652 hw->wiphy->interface_modes =
1653 BIT(NL80211_IFTYPE_AP) |
1654 BIT(NL80211_IFTYPE_STATION) |
1655 BIT(NL80211_IFTYPE_ADHOC);
1656
1657 SET_IEEE80211_DEV(hw, &pdev->dev); 1637 SET_IEEE80211_DEV(hw, &pdev->dev);
1658 pci_set_drvdata(pdev, hw); 1638 pci_set_drvdata(pdev, hw);
1659 1639
@@ -1701,17 +1681,10 @@ static void ath_pci_remove(struct pci_dev *pdev)
1701{ 1681{
1702 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 1682 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
1703 struct ath_softc *sc = hw->priv; 1683 struct ath_softc *sc = hw->priv;
1704 enum ath9k_int status;
1705 1684
1706 if (pdev->irq) {
1707 ath9k_hw_set_interrupts(sc->sc_ah, 0);
1708 /* clear the ISR */
1709 ath9k_hw_getisr(sc->sc_ah, &status);
1710 sc->sc_flags |= SC_OP_INVALID;
1711 free_irq(pdev->irq, sc);
1712 }
1713 ath_detach(sc); 1685 ath_detach(sc);
1714 1686 if (pdev->irq)
1687 free_irq(pdev->irq, sc);
1715 pci_iounmap(pdev, sc->mem); 1688 pci_iounmap(pdev, sc->mem);
1716 pci_release_region(pdev, 0); 1689 pci_release_region(pdev, 0);
1717 pci_disable_device(pdev); 1690 pci_disable_device(pdev);