aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath9k/main.c')
-rw-r--r--drivers/net/wireless/ath9k/main.c266
1 files changed, 266 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 07e5b5d877b6..b493dff5643e 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -672,6 +672,209 @@ fail:
672 ath_deinit_leds(sc); 672 ath_deinit_leds(sc);
673} 673}
674 674
675#ifdef CONFIG_RFKILL
676/*******************/
677/* Rfkill */
678/*******************/
679
680static void ath_radio_enable(struct ath_softc *sc)
681{
682 struct ath_hal *ah = sc->sc_ah;
683 int status;
684
685 spin_lock_bh(&sc->sc_resetlock);
686 if (!ath9k_hw_reset(ah, ah->ah_curchan,
687 sc->sc_ht_info.tx_chan_width,
688 sc->sc_tx_chainmask,
689 sc->sc_rx_chainmask,
690 sc->sc_ht_extprotspacing,
691 false, &status)) {
692 DPRINTF(sc, ATH_DBG_FATAL,
693 "%s: unable to reset channel %u (%uMhz) "
694 "flags 0x%x hal status %u\n", __func__,
695 ath9k_hw_mhz2ieee(ah,
696 ah->ah_curchan->channel,
697 ah->ah_curchan->channelFlags),
698 ah->ah_curchan->channel,
699 ah->ah_curchan->channelFlags, status);
700 }
701 spin_unlock_bh(&sc->sc_resetlock);
702
703 ath_update_txpow(sc);
704 if (ath_startrecv(sc) != 0) {
705 DPRINTF(sc, ATH_DBG_FATAL,
706 "%s: unable to restart recv logic\n", __func__);
707 return;
708 }
709
710 if (sc->sc_flags & SC_OP_BEACONS)
711 ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */
712
713 /* Re-Enable interrupts */
714 ath9k_hw_set_interrupts(ah, sc->sc_imask);
715
716 /* Enable LED */
717 ath9k_hw_cfg_output(ah, ATH_LED_PIN,
718 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
719 ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0);
720
721 ieee80211_wake_queues(sc->hw);
722}
723
724static void ath_radio_disable(struct ath_softc *sc)
725{
726 struct ath_hal *ah = sc->sc_ah;
727 int status;
728
729
730 ieee80211_stop_queues(sc->hw);
731
732 /* Disable LED */
733 ath9k_hw_set_gpio(ah, ATH_LED_PIN, 1);
734 ath9k_hw_cfg_gpio_input(ah, ATH_LED_PIN);
735
736 /* Disable interrupts */
737 ath9k_hw_set_interrupts(ah, 0);
738
739 ath_draintxq(sc, false); /* clear pending tx frames */
740 ath_stoprecv(sc); /* turn off frame recv */
741 ath_flushrecv(sc); /* flush recv queue */
742
743 spin_lock_bh(&sc->sc_resetlock);
744 if (!ath9k_hw_reset(ah, ah->ah_curchan,
745 sc->sc_ht_info.tx_chan_width,
746 sc->sc_tx_chainmask,
747 sc->sc_rx_chainmask,
748 sc->sc_ht_extprotspacing,
749 false, &status)) {
750 DPRINTF(sc, ATH_DBG_FATAL,
751 "%s: unable to reset channel %u (%uMhz) "
752 "flags 0x%x hal status %u\n", __func__,
753 ath9k_hw_mhz2ieee(ah,
754 ah->ah_curchan->channel,
755 ah->ah_curchan->channelFlags),
756 ah->ah_curchan->channel,
757 ah->ah_curchan->channelFlags, status);
758 }
759 spin_unlock_bh(&sc->sc_resetlock);
760
761 ath9k_hw_phy_disable(ah);
762 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
763}
764
765static bool ath_is_rfkill_set(struct ath_softc *sc)
766{
767 struct ath_hal *ah = sc->sc_ah;
768
769 return ath9k_hw_gpio_get(ah, ah->ah_rfkill_gpio) ==
770 ah->ah_rfkill_polarity;
771}
772
773/* h/w rfkill poll function */
774static void ath_rfkill_poll(struct work_struct *work)
775{
776 struct ath_softc *sc = container_of(work, struct ath_softc,
777 rf_kill.rfkill_poll.work);
778 bool radio_on;
779
780 if (sc->sc_flags & SC_OP_INVALID)
781 return;
782
783 radio_on = !ath_is_rfkill_set(sc);
784
785 /*
786 * enable/disable radio only when there is a
787 * state change in RF switch
788 */
789 if (radio_on == !!(sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED)) {
790 enum rfkill_state state;
791
792 if (sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED) {
793 state = radio_on ? RFKILL_STATE_SOFT_BLOCKED
794 : RFKILL_STATE_HARD_BLOCKED;
795 } else if (radio_on) {
796 ath_radio_enable(sc);
797 state = RFKILL_STATE_UNBLOCKED;
798 } else {
799 ath_radio_disable(sc);
800 state = RFKILL_STATE_HARD_BLOCKED;
801 }
802
803 if (state == RFKILL_STATE_HARD_BLOCKED)
804 sc->sc_flags |= SC_OP_RFKILL_HW_BLOCKED;
805 else
806 sc->sc_flags &= ~SC_OP_RFKILL_HW_BLOCKED;
807
808 rfkill_force_state(sc->rf_kill.rfkill, state);
809 }
810
811 queue_delayed_work(sc->hw->workqueue, &sc->rf_kill.rfkill_poll,
812 msecs_to_jiffies(ATH_RFKILL_POLL_INTERVAL));
813}
814
815/* s/w rfkill handler */
816static int ath_sw_toggle_radio(void *data, enum rfkill_state state)
817{
818 struct ath_softc *sc = data;
819
820 switch (state) {
821 case RFKILL_STATE_SOFT_BLOCKED:
822 if (!(sc->sc_flags & (SC_OP_RFKILL_HW_BLOCKED |
823 SC_OP_RFKILL_SW_BLOCKED)))
824 ath_radio_disable(sc);
825 sc->sc_flags |= SC_OP_RFKILL_SW_BLOCKED;
826 return 0;
827 case RFKILL_STATE_UNBLOCKED:
828 if ((sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED)) {
829 sc->sc_flags &= ~SC_OP_RFKILL_SW_BLOCKED;
830 if (sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED) {
831 DPRINTF(sc, ATH_DBG_FATAL, "Can't turn on the"
832 "radio as it is disabled by h/w \n");
833 return -EPERM;
834 }
835 ath_radio_enable(sc);
836 }
837 return 0;
838 default:
839 return -EINVAL;
840 }
841}
842
843/* Init s/w rfkill */
844static int ath_init_sw_rfkill(struct ath_softc *sc)
845{
846 sc->rf_kill.rfkill = rfkill_allocate(wiphy_dev(sc->hw->wiphy),
847 RFKILL_TYPE_WLAN);
848 if (!sc->rf_kill.rfkill) {
849 DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n");
850 return -ENOMEM;
851 }
852
853 snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name),
854 "ath9k-%s:rfkill", wiphy_name(sc->hw->wiphy));
855 sc->rf_kill.rfkill->name = sc->rf_kill.rfkill_name;
856 sc->rf_kill.rfkill->data = sc;
857 sc->rf_kill.rfkill->toggle_radio = ath_sw_toggle_radio;
858 sc->rf_kill.rfkill->state = RFKILL_STATE_UNBLOCKED;
859 sc->rf_kill.rfkill->user_claim_unsupported = 1;
860
861 return 0;
862}
863
864/* Deinitialize rfkill */
865static void ath_deinit_rfkill(struct ath_softc *sc)
866{
867 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
868 cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
869
870 if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) {
871 rfkill_unregister(sc->rf_kill.rfkill);
872 sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED;
873 sc->rf_kill.rfkill = NULL;
874 }
875}
876#endif /* CONFIG_RFKILL */
877
675static int ath_detach(struct ath_softc *sc) 878static int ath_detach(struct ath_softc *sc)
676{ 879{
677 struct ieee80211_hw *hw = sc->hw; 880 struct ieee80211_hw *hw = sc->hw;
@@ -681,6 +884,11 @@ static int ath_detach(struct ath_softc *sc)
681 /* Deinit LED control */ 884 /* Deinit LED control */
682 ath_deinit_leds(sc); 885 ath_deinit_leds(sc);
683 886
887#ifdef CONFIG_RFKILL
888 /* deinit rfkill */
889 ath_deinit_rfkill(sc);
890#endif
891
684 /* Unregister hw */ 892 /* Unregister hw */
685 893
686 ieee80211_unregister_hw(hw); 894 ieee80211_unregister_hw(hw);
@@ -777,6 +985,16 @@ static int ath_attach(u16 devid,
777 /* Initialize LED control */ 985 /* Initialize LED control */
778 ath_init_leds(sc); 986 ath_init_leds(sc);
779 987
988#ifdef CONFIG_RFKILL
989 /* Initialze h/w Rfkill */
990 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
991 INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll);
992
993 /* Initialize s/w rfkill */
994 if (ath_init_sw_rfkill(sc))
995 goto detach;
996#endif
997
780 /* initialize tx/rx engine */ 998 /* initialize tx/rx engine */
781 999
782 error = ath_tx_init(sc, ATH_TXBUF); 1000 error = ath_tx_init(sc, ATH_TXBUF);
@@ -822,6 +1040,33 @@ static int ath9k_start(struct ieee80211_hw *hw)
822 return error; 1040 return error;
823 } 1041 }
824 1042
1043#ifdef CONFIG_RFKILL
1044 /* Start rfkill polling */
1045 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1046 queue_delayed_work(sc->hw->workqueue,
1047 &sc->rf_kill.rfkill_poll, 0);
1048
1049 if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) {
1050 if (rfkill_register(sc->rf_kill.rfkill)) {
1051 DPRINTF(sc, ATH_DBG_FATAL,
1052 "Unable to register rfkill\n");
1053 rfkill_free(sc->rf_kill.rfkill);
1054
1055 /* Deinitialize the device */
1056 if (sc->pdev->irq)
1057 free_irq(sc->pdev->irq, sc);
1058 ath_detach(sc);
1059 pci_iounmap(sc->pdev, sc->mem);
1060 pci_release_region(sc->pdev, 0);
1061 pci_disable_device(sc->pdev);
1062 ieee80211_free_hw(hw);
1063 return -EIO;
1064 } else {
1065 sc->sc_flags |= SC_OP_RFKILL_REGISTERED;
1066 }
1067 }
1068#endif
1069
825 ieee80211_wake_queues(hw); 1070 ieee80211_wake_queues(hw);
826 return 0; 1071 return 0;
827} 1072}
@@ -883,6 +1128,11 @@ static void ath9k_stop(struct ieee80211_hw *hw)
883 "%s: Device is no longer present\n", __func__); 1128 "%s: Device is no longer present\n", __func__);
884 1129
885 ieee80211_stop_queues(hw); 1130 ieee80211_stop_queues(hw);
1131
1132#ifdef CONFIG_RFKILL
1133 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1134 cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
1135#endif
886} 1136}
887 1137
888static int ath9k_add_interface(struct ieee80211_hw *hw, 1138static int ath9k_add_interface(struct ieee80211_hw *hw,
@@ -1554,6 +1804,12 @@ static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
1554 struct ath_softc *sc = hw->priv; 1804 struct ath_softc *sc = hw->priv;
1555 1805
1556 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); 1806 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
1807
1808#ifdef CONFIG_RFKILL
1809 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1810 cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
1811#endif
1812
1557 pci_save_state(pdev); 1813 pci_save_state(pdev);
1558 pci_disable_device(pdev); 1814 pci_disable_device(pdev);
1559 pci_set_power_state(pdev, 3); 1815 pci_set_power_state(pdev, 3);
@@ -1586,6 +1842,16 @@ static int ath_pci_resume(struct pci_dev *pdev)
1586 AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 1842 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1587 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); 1843 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
1588 1844
1845#ifdef CONFIG_RFKILL
1846 /*
1847 * check the h/w rfkill state on resume
1848 * and start the rfkill poll timer
1849 */
1850 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1851 queue_delayed_work(sc->hw->workqueue,
1852 &sc->rf_kill.rfkill_poll, 0);
1853#endif
1854
1589 return 0; 1855 return 0;
1590} 1856}
1591 1857