source: branches/backfire/package/mac80211/patches/582-ath9k_merge_reset_functions.patch @ 28138

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

mac80211: backport latest version from trunk (as of r28137)

File size: 11.8 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 void __ath_cancel_work(struct ath_softc *sc) 
    222216{ 
    223         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; 
    230  
    231         if (sc->sc_flags & SC_OP_INVALID) 
    232                 return -EIO; 
    233  
    234         sc->hw_busy_count = 0; 
    235  
    236         del_timer_sync(&common->ani.timer); 
    237217        cancel_work_sync(&sc->paprd_work); 
    238218        cancel_work_sync(&sc->hw_check_work); 
    239         cancel_work_sync(&sc->hw_reset_work); 
    240219        cancel_delayed_work_sync(&sc->tx_complete_work); 
    241220        cancel_delayed_work_sync(&sc->hw_pll_work); 
     221} 
    242222 
    243         ath9k_ps_wakeup(sc); 
     223static void ath_cancel_work(struct ath_softc *sc) 
     224{ 
     225        __ath_cancel_work(sc); 
     226        cancel_work_sync(&sc->hw_reset_work); 
     227} 
    244228 
    245         spin_lock_bh(&sc->sc_pcu_lock); 
     229static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) 
     230{ 
     231        struct ath_hw *ah = sc->sc_ah; 
     232        struct ath_common *common = ath9k_hw_common(ah); 
     233        bool ret; 
    246234 
    247         /* 
    248          * This is only performed if the channel settings have 
    249          * actually changed. 
    250          * 
    251          * To switch channels clear any pending DMA operations; 
    252          * wait long enough for the RX fifo to drain, reset the 
    253          * hardware at the new frequency, and then re-enable 
    254          * the relevant bits of the h/w. 
    255          */ 
    256         ath9k_hw_disable_interrupts(ah); 
    257         stopped = ath_drain_all_txq(sc, false); 
     235        ieee80211_stop_queues(sc->hw); 
    258236 
    259         if (!ath_stoprecv(sc)) 
    260                 stopped = false; 
     237        sc->hw_busy_count = 0; 
     238        del_timer_sync(&common->ani.timer); 
    261239 
    262         if (!ath9k_hw_check_alive(ah)) 
    263                 stopped = false; 
     240        ath9k_hw_disable_interrupts(ah); 
    264241 
    265         /* XXX: do not flush receive queue here. We don't want 
    266          * to flush data frames already in queue because of 
    267          * changing channel. */ 
     242        ret = ath_drain_all_txq(sc, retry_tx); 
    268243 
    269         if (!stopped || !(sc->sc_flags & SC_OP_OFFCHANNEL)) 
    270                 fastcc = false; 
     244        if (!ath_stoprecv(sc)) 
     245                ret = false; 
    271246 
    272         if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) 
    273                 caldata = &sc->caldata; 
     247        if (!flush) { 
     248                if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) 
     249                        ath_rx_tasklet(sc, 0, true); 
     250                ath_rx_tasklet(sc, 0, false); 
     251        } else { 
     252                ath_flushrecv(sc); 
     253        } 
    274254 
    275         ath_dbg(common, ATH_DBG_CONFIG, 
    276                 "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n", 
    277                 sc->sc_ah->curchan->channel, 
    278                 channel->center_freq, conf_is_ht40(conf), 
    279                 fastcc); 
     255        return ret; 
     256} 
    280257 
    281         r = ath9k_hw_reset(ah, hchan, caldata, fastcc); 
    282         if (r) { 
    283                 ath_err(common, 
    284                         "Unable to reset channel (%u MHz), reset status %d\n", 
    285                         channel->center_freq, r); 
    286                 goto ps_restore; 
    287         } 
     258static bool ath_complete_reset(struct ath_softc *sc, bool start) 
     259{ 
     260        struct ath_hw *ah = sc->sc_ah; 
     261        struct ath_common *common = ath9k_hw_common(ah); 
    288262 
    289263        if (ath_startrecv(sc) != 0) { 
    290264                ath_err(common, "Unable to restart recv logic\n"); 
    291                 r = -EIO; 
    292                 goto ps_restore; 
     265                return false; 
    293266        } 
    294267 
    295268        ath9k_cmn_update_txpow(ah, sc->curtxpow, 
    static int ath_set_channel(struct ath_so 
    297270        ath9k_hw_set_interrupts(ah, ah->imask); 
    298271        ath9k_hw_enable_interrupts(ah); 
    299272 
    300         if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) { 
     273        if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && start) { 
    301274                if (sc->sc_flags & SC_OP_BEACONS) 
    302275                        ath_set_beacon(sc); 
     276 
    303277                ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); 
    304278                ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); 
    305279                if (!common->disable_ani) 
    306280                        ath_start_ani(common); 
    307281        } 
    308282 
    309  ps_restore: 
    310         ieee80211_wake_queues(hw); 
     283        ieee80211_wake_queues(sc->hw); 
     284 
     285        return true; 
     286} 
     287 
     288static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, 
     289                              bool retry_tx) 
     290{ 
     291        struct ath_hw *ah = sc->sc_ah; 
     292        struct ath_common *common = ath9k_hw_common(ah); 
     293        struct ath9k_hw_cal_data *caldata = NULL; 
     294        bool fastcc = true; 
     295        bool flush = false; 
     296        int r; 
     297 
     298        __ath_cancel_work(sc); 
     299 
     300        spin_lock_bh(&sc->sc_pcu_lock); 
     301 
     302        sc->sc_flags &= ~SC_OP_HW_RESET; 
    311303 
     304        if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) { 
     305                fastcc = false; 
     306                caldata = &sc->caldata; 
     307        } 
     308 
     309        if (!hchan) { 
     310                fastcc = false; 
     311                flush = true; 
     312                hchan = ah->curchan; 
     313        } 
     314 
     315        if (fastcc && !ath9k_hw_check_alive(ah)) 
     316                fastcc = false; 
     317 
     318        if (!ath_prepare_reset(sc, retry_tx, flush)) 
     319                fastcc = false; 
     320 
     321        ath_dbg(common, ATH_DBG_CONFIG, 
     322                "Reset to %u MHz, HT40: %d fastcc: %d\n", 
     323                hchan->channel, !!(hchan->channelFlags & (CHANNEL_HT40MINUS | 
     324                                                          CHANNEL_HT40PLUS)), 
     325                fastcc); 
     326 
     327        r = ath9k_hw_reset(ah, hchan, caldata, fastcc); 
     328        if (r) { 
     329                ath_err(common, 
     330                        "Unable to reset channel, reset status %d\n", r); 
     331                goto out; 
     332        } 
     333 
     334        if (!ath_complete_reset(sc, true)) 
     335                r = -EIO; 
     336 
     337out: 
    312338        spin_unlock_bh(&sc->sc_pcu_lock); 
     339        return r; 
     340} 
     341 
     342 
     343/* 
     344 * Set/change channels.  If the channel is really being changed, it's done 
     345 * by reseting the chip.  To accomplish this we must first cleanup any pending 
     346 * DMA, then restart stuff. 
     347*/ 
     348static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, 
     349                    struct ath9k_channel *hchan) 
     350{ 
     351        int r; 
     352 
     353        if (sc->sc_flags & SC_OP_INVALID) 
     354                return -EIO; 
     355 
     356        ath9k_ps_wakeup(sc); 
     357 
     358        r = ath_reset_internal(sc, hchan, false); 
    313359 
    314360        ath9k_ps_restore(sc); 
     361 
    315362        return r; 
    316363} 
    317364 
    static void ath_radio_enable(struct ath_ 
    824871                        channel->center_freq, r); 
    825872        } 
    826873 
    827         ath9k_cmn_update_txpow(ah, sc->curtxpow, 
    828                                sc->config.txpowlimit, &sc->curtxpow); 
    829         if (ath_startrecv(sc) != 0) { 
    830                 ath_err(common, "Unable to restart recv logic\n"); 
    831                 goto out; 
    832         } 
    833         if (sc->sc_flags & SC_OP_BEACONS) 
    834                 ath_set_beacon(sc);     /* restart beacons */ 
    835  
    836         /* Re-Enable  interrupts */ 
    837         ath9k_hw_set_interrupts(ah, ah->imask); 
    838         ath9k_hw_enable_interrupts(ah); 
     874        ath_complete_reset(sc, true); 
    839875 
    840876        /* Enable LED */ 
    841877        ath9k_hw_cfg_output(ah, ah->led_pin, 
    842878                            AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 
    843879        ath9k_hw_set_gpio(ah, ah->led_pin, 0); 
    844880 
    845         ieee80211_wake_queues(hw); 
    846         ieee80211_queue_delayed_work(hw, &sc->hw_pll_work, HZ/2); 
    847  
    848 out: 
    849881        spin_unlock_bh(&sc->sc_pcu_lock); 
    850882 
    851883        ath9k_ps_restore(sc); 
    void ath_radio_disable(struct ath_softc  
    858890        int r; 
    859891 
    860892        ath9k_ps_wakeup(sc); 
    861         cancel_delayed_work_sync(&sc->hw_pll_work); 
    862893 
    863         spin_lock_bh(&sc->sc_pcu_lock); 
     894        ath_cancel_work(sc); 
    864895 
    865         ieee80211_stop_queues(hw); 
     896        spin_lock_bh(&sc->sc_pcu_lock); 
    866897 
    867898        /* 
    868899         * Keep the LED on when the radio is disabled 
    void ath_radio_disable(struct ath_softc  
    873904                ath9k_hw_cfg_gpio_input(ah, ah->led_pin); 
    874905        } 
    875906 
    876         /* Disable interrupts */ 
    877         ath9k_hw_disable_interrupts(ah); 
    878  
    879         ath_drain_all_txq(sc, false);   /* clear pending tx frames */ 
    880  
    881         ath_stoprecv(sc);               /* turn off frame recv */ 
    882         ath_flushrecv(sc);              /* flush recv queue */ 
     907        ath_prepare_reset(sc, false, true); 
    883908 
    884909        if (!ah->curchan) 
    885910                ah->curchan = ath9k_cmn_get_curchannel(hw, ah); 
    void ath_radio_disable(struct ath_softc  
    901926 
    902927static int ath_reset(struct ath_softc *sc, bool retry_tx) 
    903928{ 
    904         struct ath_hw *ah = sc->sc_ah; 
    905         struct ath_common *common = ath9k_hw_common(ah); 
    906         struct ieee80211_hw *hw = sc->hw; 
    907929        int r; 
    908930 
    909         sc->sc_flags &= ~SC_OP_HW_RESET; 
    910         sc->hw_busy_count = 0; 
    911  
    912         /* Stop ANI */ 
    913  
    914         del_timer_sync(&common->ani.timer); 
    915  
    916931        ath9k_ps_wakeup(sc); 
    917932 
    918         ieee80211_stop_queues(hw); 
    919  
    920         ath9k_hw_disable_interrupts(ah); 
    921         ath_drain_all_txq(sc, retry_tx); 
    922  
    923         ath_stoprecv(sc); 
    924         ath_flushrecv(sc); 
    925  
    926         r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); 
    927         if (r) 
    928                 ath_err(common, 
    929                         "Unable to reset hardware; reset status %d\n", r); 
    930  
    931         if (ath_startrecv(sc) != 0) 
    932                 ath_err(common, "Unable to start recv logic\n"); 
    933  
    934         /* 
    935          * We may be doing a reset in response to a request 
    936          * that changes the channel so update any state that 
    937          * might change as a result. 
    938          */ 
    939         ath9k_cmn_update_txpow(ah, sc->curtxpow, 
    940                                sc->config.txpowlimit, &sc->curtxpow); 
    941  
    942         if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL))) 
    943                 ath_set_beacon(sc);     /* restart beacons */ 
    944  
    945         ath9k_hw_set_interrupts(ah, ah->imask); 
    946         ath9k_hw_enable_interrupts(ah); 
     933        r = ath_reset_internal(sc, NULL, retry_tx); 
    947934 
    948935        if (retry_tx) { 
    949936                int i; 
    static int ath_reset(struct ath_softc *s 
    956943                } 
    957944        } 
    958945 
    959         ieee80211_wake_queues(hw); 
    960  
    961         /* Start ANI */ 
    962         if (!common->disable_ani) 
    963                 ath_start_ani(common); 
    964  
    965946        ath9k_ps_restore(sc); 
    966947 
    967948        return r; 
    void ath_reset_work(struct work_struct * 
    971952{ 
    972953        struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work); 
    973954 
    974         spin_lock_bh(&sc->sc_pcu_lock); 
    975955        ath_reset(sc, true); 
    976         spin_unlock_bh(&sc->sc_pcu_lock); 
    977956} 
    978957 
    979958void ath_hw_check(struct work_struct *work) 
    void ath_hw_check(struct work_struct *wo 
    994973        ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, " 
    995974                "busy=%d (try %d)\n", busy, sc->hw_busy_count + 1); 
    996975        if (busy >= 99) { 
    997                 if (++sc->hw_busy_count >= 3) { 
    998                         spin_lock_bh(&sc->sc_pcu_lock); 
    999                         ath_reset(sc, true); 
    1000                         spin_unlock_bh(&sc->sc_pcu_lock); 
    1001                 } 
     976                if (++sc->hw_busy_count >= 3) 
     977                        ieee80211_queue_work(sc->hw, &sc->hw_reset_work); 
    1002978 
    1003979        } else if (busy >= 0) 
    1004980                sc->hw_busy_count = 0; 
    static void ath_hw_pll_rx_hang_check(str 
    1018994                        /* Rx is hung for more than 500ms. Reset it */ 
    1019995                        ath_dbg(common, ATH_DBG_RESET, 
    1020996                                "Possible RX hang, resetting"); 
    1021                         spin_lock_bh(&sc->sc_pcu_lock); 
    1022                         ath_reset(sc, true); 
    1023                         spin_unlock_bh(&sc->sc_pcu_lock); 
     997                        ieee80211_queue_work(sc->hw, &sc->hw_reset_work); 
    1024998                        count = 0; 
    1025999                } 
    10261000        } else 
    static int ath9k_start(struct ieee80211_ 
    10911065                goto mutex_unlock; 
    10921066        } 
    10931067 
    1094         /* 
    1095          * This is needed only to setup initial state 
    1096          * but it's best done after a reset. 
    1097          */ 
    1098         ath9k_cmn_update_txpow(ah, sc->curtxpow, 
    1099                         sc->config.txpowlimit, &sc->curtxpow); 
    1100  
    1101         /* 
    1102          * Setup the hardware after reset: 
    1103          * The receive engine is set going. 
    1104          * Frame transmit is handled entirely 
    1105          * in the frame output path; there's nothing to do 
    1106          * here except setup the interrupt mask. 
    1107          */ 
    1108         if (ath_startrecv(sc) != 0) { 
    1109                 ath_err(common, "Unable to start recv logic\n"); 
    1110                 r = -EIO; 
    1111                 spin_unlock_bh(&sc->sc_pcu_lock); 
    1112                 goto mutex_unlock; 
    1113         } 
    1114         spin_unlock_bh(&sc->sc_pcu_lock); 
    1115  
    11161068        /* Setup our intr mask. */ 
    11171069        ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | 
    11181070                    ATH9K_INT_RXORN | ATH9K_INT_FATAL | 
    static int ath9k_start(struct ieee80211_ 
    11351087 
    11361088        /* Disable BMISS interrupt when we're not associated */ 
    11371089        ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); 
    1138         ath9k_hw_set_interrupts(ah, ah->imask); 
    1139         ath9k_hw_enable_interrupts(ah); 
    11401090 
    1141         ieee80211_wake_queues(hw); 
     1091        if (!ath_complete_reset(sc, false)) { 
     1092                r = -EIO; 
     1093                spin_unlock_bh(&sc->sc_pcu_lock); 
     1094                goto mutex_unlock; 
     1095        } 
    11421096 
    1143         ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); 
     1097        spin_unlock_bh(&sc->sc_pcu_lock); 
    11441098 
    11451099        if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && 
    11461100            !ah->btcoex_hw.enabled) { 
    static void ath9k_stop(struct ieee80211_ 
    12331187 
    12341188        mutex_lock(&sc->mutex); 
    12351189 
    1236         cancel_delayed_work_sync(&sc->tx_complete_work); 
    1237         cancel_delayed_work_sync(&sc->hw_pll_work); 
    1238         cancel_work_sync(&sc->paprd_work); 
    1239         cancel_work_sync(&sc->hw_check_work); 
    1240         cancel_work_sync(&sc->hw_reset_work); 
     1190        ath_cancel_work(sc); 
    12411191 
    12421192        if (sc->sc_flags & SC_OP_INVALID) { 
    12431193                ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); 
    static void ath9k_flush(struct ieee80211 
    23542304        ath9k_ps_wakeup(sc); 
    23552305        spin_lock_bh(&sc->sc_pcu_lock); 
    23562306        drain_txq = ath_drain_all_txq(sc, false); 
     2307        spin_unlock_bh(&sc->sc_pcu_lock); 
     2308 
    23572309        if (!drain_txq) 
    23582310                ath_reset(sc, false); 
    2359         spin_unlock_bh(&sc->sc_pcu_lock); 
     2311 
    23602312        ath9k_ps_restore(sc); 
    23612313        ieee80211_wake_queues(hw); 
    23622314 
Note: See TracBrowser for help on using the repository browser.