source: trunk/package/mac80211/patches/581-ath9k_merge_reset_functions.patch @ 28107

Last change on this file since 28107 was 28107, checked in by nbd, 5 years ago

ath9k: implement rx/tx antenna control

File size: 8.7 KB
  • drivers/net/wireless/ath/ath9k/main.c

    a b static int ath_update_survey_stats(struc 
    212212        return ret; 
    213213} 
    214214 
    215 /* 
    216  * Set/change channels.  If the channel is really being changed, it's done 
    217  * by reseting the chip.  To accomplish this we must first cleanup any pending 
    218  * DMA, then restart stuff. 
    219 */ 
    220 static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, 
    221                     struct ath9k_channel *hchan) 
     215static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx) 
    222216{ 
    223217        struct ath_hw *ah = sc->sc_ah; 
    224         struct ath_common *common = ath9k_hw_common(ah); 
    225         struct ieee80211_conf *conf = &common->hw->conf; 
    226         bool fastcc = true, stopped; 
    227         struct ieee80211_channel *channel = hw->conf.channel; 
    228         struct ath9k_hw_cal_data *caldata = NULL; 
    229         int r; 
     218        bool ret; 
    230219 
    231         if (sc->sc_flags & SC_OP_INVALID) 
    232                 return -EIO; 
     220        ieee80211_stop_queues(sc->hw); 
    233221 
    234222        sc->hw_busy_count = 0; 
    235  
    236         del_timer_sync(&common->ani.timer); 
    237223        cancel_work_sync(&sc->paprd_work); 
    238224        cancel_work_sync(&sc->hw_check_work); 
    239225        cancel_delayed_work_sync(&sc->tx_complete_work); 
    240226        cancel_delayed_work_sync(&sc->hw_pll_work); 
    241227 
    242         ath9k_ps_wakeup(sc); 
    243  
    244         spin_lock_bh(&sc->sc_pcu_lock); 
    245  
    246         /* 
    247          * This is only performed if the channel settings have 
    248          * actually changed. 
    249          * 
    250          * To switch channels clear any pending DMA operations; 
    251          * wait long enough for the RX fifo to drain, reset the 
    252          * hardware at the new frequency, and then re-enable 
    253          * the relevant bits of the h/w. 
    254          */ 
    255228        ath9k_hw_disable_interrupts(ah); 
    256         stopped = ath_drain_all_txq(sc, false); 
    257229 
    258         if (!ath_stoprecv(sc)) 
    259                 stopped = false; 
    260  
    261         if (!ath9k_hw_check_alive(ah)) 
    262                 stopped = false; 
    263  
    264         /* XXX: do not flush receive queue here. We don't want 
    265          * to flush data frames already in queue because of 
    266          * changing channel. */ 
     230        ret = ath_drain_all_txq(sc, retry_tx); 
    267231 
    268         if (!stopped || !(sc->sc_flags & SC_OP_OFFCHANNEL)) 
    269                 fastcc = false; 
     232        if (!ath_stoprecv(sc)) 
     233                ret = false; 
    270234 
    271         if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) 
    272                 caldata = &sc->caldata; 
     235        ath_flushrecv(sc); 
    273236 
    274         ath_dbg(common, ATH_DBG_CONFIG, 
    275                 "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n", 
    276                 sc->sc_ah->curchan->channel, 
    277                 channel->center_freq, conf_is_ht40(conf), 
    278                 fastcc); 
     237        return ret; 
     238} 
    279239 
    280         r = ath9k_hw_reset(ah, hchan, caldata, fastcc); 
    281         if (r) { 
    282                 ath_err(common, 
    283                         "Unable to reset channel (%u MHz), reset status %d\n", 
    284                         channel->center_freq, r); 
    285                 goto ps_restore; 
    286         } 
     240static bool ath_complete_reset(struct ath_softc *sc) 
     241{ 
     242        struct ath_hw *ah = sc->sc_ah; 
     243        struct ath_common *common = ath9k_hw_common(ah); 
    287244 
    288245        if (ath_startrecv(sc) != 0) { 
    289246                ath_err(common, "Unable to restart recv logic\n"); 
    290                 r = -EIO; 
    291                 goto ps_restore; 
     247                return false; 
    292248        } 
    293249 
    294250        ath9k_cmn_update_txpow(ah, sc->curtxpow, 
    static int ath_set_channel(struct ath_so 
    299255        if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) { 
    300256                if (sc->sc_flags & SC_OP_BEACONS) 
    301257                        ath_set_beacon(sc); 
     258 
    302259                ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); 
    303260                ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); 
    304261                if (!common->disable_ani) 
    305262                        ath_start_ani(common); 
    306263        } 
    307264 
    308  ps_restore: 
    309         ieee80211_wake_queues(hw); 
     265        ieee80211_wake_queues(sc->hw); 
     266 
     267        return true; 
     268} 
     269 
     270static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, 
     271                              bool retry_tx) 
     272{ 
     273        struct ath_hw *ah = sc->sc_ah; 
     274        struct ath_common *common = ath9k_hw_common(ah); 
     275        struct ath9k_hw_cal_data *caldata = NULL; 
     276        bool fastcc = true; 
     277        int r; 
     278 
     279        if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) { 
     280                fastcc = false; 
     281                caldata = &sc->caldata; 
     282        } 
    310283 
     284        if (!hchan) { 
     285                fastcc = false; 
     286                hchan = ah->curchan; 
     287        } 
     288 
     289        if (fastcc && !ath9k_hw_check_alive(ah)) 
     290                fastcc = false; 
     291 
     292        if (!ath_prepare_reset(sc, retry_tx)) 
     293                fastcc = false; 
     294 
     295        ath_dbg(common, ATH_DBG_CONFIG, 
     296                "Reset to %u MHz, HT40: %d fastcc: %d\n", 
     297                hchan->channel, !!(hchan->channelFlags & (CHANNEL_HT40MINUS | 
     298                                                          CHANNEL_HT40PLUS)), 
     299                fastcc); 
     300 
     301        r = ath9k_hw_reset(ah, hchan, caldata, fastcc); 
     302        if (r) { 
     303                ath_err(common, 
     304                        "Unable to reset channel, reset status %d\n", r); 
     305                return r; 
     306        } 
     307 
     308        if (!ath_complete_reset(sc)) 
     309                return -EIO; 
     310 
     311        return 0; 
     312} 
     313 
     314 
     315/* 
     316 * Set/change channels.  If the channel is really being changed, it's done 
     317 * by reseting the chip.  To accomplish this we must first cleanup any pending 
     318 * DMA, then restart stuff. 
     319*/ 
     320static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, 
     321                    struct ath9k_channel *hchan) 
     322{ 
     323        int r; 
     324 
     325        if (sc->sc_flags & SC_OP_INVALID) 
     326                return -EIO; 
     327 
     328        ath9k_ps_wakeup(sc); 
     329 
     330        spin_lock_bh(&sc->sc_pcu_lock); 
     331        r = ath_reset_internal(sc, hchan, false); 
    311332        spin_unlock_bh(&sc->sc_pcu_lock); 
    312333 
    313334        ath9k_ps_restore(sc); 
     335 
    314336        return r; 
    315337} 
    316338 
    static void ath_radio_enable(struct ath_ 
    893915                        channel->center_freq, r); 
    894916        } 
    895917 
    896         ath9k_cmn_update_txpow(ah, sc->curtxpow, 
    897                                sc->config.txpowlimit, &sc->curtxpow); 
    898         if (ath_startrecv(sc) != 0) { 
    899                 ath_err(common, "Unable to restart recv logic\n"); 
    900                 goto out; 
    901         } 
    902         if (sc->sc_flags & SC_OP_BEACONS) 
    903                 ath_set_beacon(sc);     /* restart beacons */ 
    904  
    905         /* Re-Enable  interrupts */ 
    906         ath9k_hw_set_interrupts(ah, ah->imask); 
    907         ath9k_hw_enable_interrupts(ah); 
     918        ath_complete_reset(sc); 
    908919 
    909920        /* Enable LED */ 
    910921        ath9k_hw_cfg_output(ah, ah->led_pin, 
    911922                            AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 
    912923        ath9k_hw_set_gpio(ah, ah->led_pin, 0); 
    913924 
    914         ieee80211_wake_queues(hw); 
    915         ieee80211_queue_delayed_work(hw, &sc->hw_pll_work, HZ/2); 
    916  
    917 out: 
    918925        spin_unlock_bh(&sc->sc_pcu_lock); 
    919926 
    920927        ath9k_ps_restore(sc); 
    void ath_radio_disable(struct ath_softc  
    942949                ath9k_hw_cfg_gpio_input(ah, ah->led_pin); 
    943950        } 
    944951 
    945         /* Disable interrupts */ 
    946         ath9k_hw_disable_interrupts(ah); 
    947  
    948         ath_drain_all_txq(sc, false);   /* clear pending tx frames */ 
    949  
    950         ath_stoprecv(sc);               /* turn off frame recv */ 
    951         ath_flushrecv(sc);              /* flush recv queue */ 
     952        ath_prepare_reset(sc, false); 
    952953 
    953954        if (!ah->curchan) 
    954955                ah->curchan = ath9k_cmn_get_curchannel(hw, ah); 
    void ath_radio_disable(struct ath_softc  
    970971 
    971972int ath_reset(struct ath_softc *sc, bool retry_tx) 
    972973{ 
    973         struct ath_hw *ah = sc->sc_ah; 
    974         struct ath_common *common = ath9k_hw_common(ah); 
    975         struct ieee80211_hw *hw = sc->hw; 
    976974        int r; 
    977975 
    978         sc->hw_busy_count = 0; 
    979  
    980         /* Stop ANI */ 
    981  
    982         del_timer_sync(&common->ani.timer); 
    983  
    984976        ath9k_ps_wakeup(sc); 
    985977 
    986         ieee80211_stop_queues(hw); 
    987  
    988         ath9k_hw_disable_interrupts(ah); 
    989         ath_drain_all_txq(sc, retry_tx); 
    990  
    991         ath_stoprecv(sc); 
    992         ath_flushrecv(sc); 
    993  
    994         r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); 
    995         if (r) 
    996                 ath_err(common, 
    997                         "Unable to reset hardware; reset status %d\n", r); 
    998  
    999         if (ath_startrecv(sc) != 0) 
    1000                 ath_err(common, "Unable to start recv logic\n"); 
    1001  
    1002         /* 
    1003          * We may be doing a reset in response to a request 
    1004          * that changes the channel so update any state that 
    1005          * might change as a result. 
    1006          */ 
    1007         ath9k_cmn_update_txpow(ah, sc->curtxpow, 
    1008                                sc->config.txpowlimit, &sc->curtxpow); 
    1009  
    1010         if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL))) 
    1011                 ath_set_beacon(sc);     /* restart beacons */ 
    1012  
    1013         ath9k_hw_set_interrupts(ah, ah->imask); 
    1014         ath9k_hw_enable_interrupts(ah); 
     978        r = ath_reset_internal(sc, NULL, retry_tx); 
    1015979 
    1016980        if (retry_tx) { 
    1017981                int i; 
    int ath_reset(struct ath_softc *sc, bool 
    1024988                } 
    1025989        } 
    1026990 
    1027         ieee80211_wake_queues(hw); 
    1028  
    1029         /* Start ANI */ 
    1030         if (!common->disable_ani) 
    1031                 ath_start_ani(common); 
    1032  
    1033991        ath9k_ps_restore(sc); 
    1034992 
    1035993        return r; 
    static int ath9k_start(struct ieee80211_ 
    10811039                goto mutex_unlock; 
    10821040        } 
    10831041 
    1084         /* 
    1085          * This is needed only to setup initial state 
    1086          * but it's best done after a reset. 
    1087          */ 
    1088         ath9k_cmn_update_txpow(ah, sc->curtxpow, 
    1089                         sc->config.txpowlimit, &sc->curtxpow); 
    1090  
    1091         /* 
    1092          * Setup the hardware after reset: 
    1093          * The receive engine is set going. 
    1094          * Frame transmit is handled entirely 
    1095          * in the frame output path; there's nothing to do 
    1096          * here except setup the interrupt mask. 
    1097          */ 
    1098         if (ath_startrecv(sc) != 0) { 
    1099                 ath_err(common, "Unable to start recv logic\n"); 
    1100                 r = -EIO; 
    1101                 spin_unlock_bh(&sc->sc_pcu_lock); 
    1102                 goto mutex_unlock; 
    1103         } 
    1104         spin_unlock_bh(&sc->sc_pcu_lock); 
    1105  
    11061042        /* Setup our intr mask. */ 
    11071043        ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | 
    11081044                    ATH9K_INT_RXORN | ATH9K_INT_FATAL | 
    static int ath9k_start(struct ieee80211_ 
    11251061 
    11261062        /* Disable BMISS interrupt when we're not associated */ 
    11271063        ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); 
    1128         ath9k_hw_set_interrupts(ah, ah->imask); 
    1129         ath9k_hw_enable_interrupts(ah); 
    11301064 
    1131         ieee80211_wake_queues(hw); 
     1065        if (!ath_complete_reset(sc)) { 
     1066                r = -EIO; 
     1067                spin_unlock_bh(&sc->sc_pcu_lock); 
     1068                goto mutex_unlock; 
     1069        } 
    11321070 
    1133         ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); 
     1071        spin_unlock_bh(&sc->sc_pcu_lock); 
    11341072 
    11351073        if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && 
    11361074            !ah->btcoex_hw.enabled) { 
Note: See TracBrowser for help on using the repository browser.