diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/gpio.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/gpio.c | 69 | 
1 files changed, 51 insertions, 18 deletions
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 281a9af0f1b..bacdb8fb4ef 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -132,17 +132,18 @@ static void ath_detect_bt_priority(struct ath_softc *sc)  	if (time_after(jiffies, btcoex->bt_priority_time +  			msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { -		sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); +		clear_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags); +		clear_bit(BT_OP_SCAN, &btcoex->op_flags);  		/* Detect if colocated bt started scanning */  		if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) {  			ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX,  				"BT scan detected\n"); -			sc->sc_flags |= (SC_OP_BT_SCAN | -					 SC_OP_BT_PRIORITY_DETECTED); +			set_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags); +			set_bit(BT_OP_SCAN, &btcoex->op_flags);  		} else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {  			ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX,  				"BT priority traffic detected\n"); -			sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED; +			set_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags);  		}  		btcoex->bt_priority_cnt = 0; @@ -190,13 +191,34 @@ static void ath_btcoex_period_timer(unsigned long data)  	struct ath_softc *sc = (struct ath_softc *) data;  	struct ath_hw *ah = sc->sc_ah;  	struct ath_btcoex *btcoex = &sc->btcoex; +	struct ath_mci_profile *mci = &btcoex->mci;  	u32 timer_period;  	bool is_btscan; +	unsigned long flags; + +	spin_lock_irqsave(&sc->sc_pm_lock, flags); +	if (sc->sc_ah->power_mode == ATH9K_PM_NETWORK_SLEEP) { +		spin_unlock_irqrestore(&sc->sc_pm_lock, flags); +		goto skip_hw_wakeup; +	} +	spin_unlock_irqrestore(&sc->sc_pm_lock, flags);  	ath9k_ps_wakeup(sc);  	if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI))  		ath_detect_bt_priority(sc); -	is_btscan = sc->sc_flags & SC_OP_BT_SCAN; +	is_btscan = test_bit(BT_OP_SCAN, &btcoex->op_flags); + +	btcoex->bt_wait_time += btcoex->btcoex_period; +	if (btcoex->bt_wait_time > ATH_BTCOEX_RX_WAIT_TIME) { +		if (ar9003_mci_state(ah, MCI_STATE_NEED_FTP_STOMP) && +		    (mci->num_pan || mci->num_other_acl)) +			ah->btcoex_hw.mci.stomp_ftp = +				(sc->rx.num_pkts < ATH_BTCOEX_STOMP_FTP_THRESH); +		else +			ah->btcoex_hw.mci.stomp_ftp = false; +		btcoex->bt_wait_time = 0; +		sc->rx.num_pkts = 0; +	}  	spin_lock_bh(&btcoex->btcoex_lock); @@ -218,9 +240,9 @@ static void ath_btcoex_period_timer(unsigned long data)  	}  	ath9k_ps_restore(sc); -	timer_period = btcoex->btcoex_period / 1000; -	mod_timer(&btcoex->period_timer, jiffies + -				  msecs_to_jiffies(timer_period)); +skip_hw_wakeup: +	timer_period = btcoex->btcoex_period; +	mod_timer(&btcoex->period_timer, jiffies + msecs_to_jiffies(timer_period));  }  /* @@ -233,14 +255,14 @@ static void ath_btcoex_no_stomp_timer(void *arg)  	struct ath_hw *ah = sc->sc_ah;  	struct ath_btcoex *btcoex = &sc->btcoex;  	struct ath_common *common = ath9k_hw_common(ah); -	bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN;  	ath_dbg(common, BTCOEX, "no stomp timer running\n");  	ath9k_ps_wakeup(sc);  	spin_lock_bh(&btcoex->btcoex_lock); -	if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) +	if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || +	    test_bit(BT_OP_SCAN, &btcoex->op_flags))  		ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);  	 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)  		ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); @@ -254,10 +276,10 @@ static int ath_init_btcoex_timer(struct ath_softc *sc)  {  	struct ath_btcoex *btcoex = &sc->btcoex; -	btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; -	btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * +	btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD; +	btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * 1000 *  		btcoex->btcoex_period / 100; -	btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * +	btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * 1000 *  				   btcoex->btcoex_period / 100;  	setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, @@ -292,7 +314,8 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc)  	btcoex->bt_priority_cnt = 0;  	btcoex->bt_priority_time = jiffies; -	sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); +	clear_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags); +	clear_bit(BT_OP_SCAN, &btcoex->op_flags);  	mod_timer(&btcoex->period_timer, jiffies);  } @@ -314,14 +337,22 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc)  	btcoex->hw_timer_enabled = false;  } +void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) +{ +	struct ath_btcoex *btcoex = &sc->btcoex; + +	ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); +} +  u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen)  { +	struct ath_btcoex *btcoex = &sc->btcoex;  	struct ath_mci_profile *mci = &sc->btcoex.mci;  	u16 aggr_limit = 0;  	if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit)  		aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4; -	else if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED) +	else if (test_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags))  		aggr_limit = min((max_4ms_framelen * 3) / 8,  				 (u32)ATH_AMPDU_LIMIT_MAX); @@ -362,9 +393,9 @@ void ath9k_stop_btcoex(struct ath_softc *sc)  	if (ah->btcoex_hw.enabled &&  	    ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { -		ath9k_hw_btcoex_disable(ah);  		if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)  			ath9k_btcoex_timer_pause(sc); +		ath9k_hw_btcoex_disable(ah);  		if (AR_SREV_9462(ah))  			ath_mci_flush_profile(&sc->btcoex.mci);  	} @@ -372,11 +403,13 @@ void ath9k_stop_btcoex(struct ath_softc *sc)  void ath9k_deinit_btcoex(struct ath_softc *sc)  { +	struct ath_hw *ah = sc->sc_ah; +          if ((sc->btcoex.no_stomp_timer) &&  	    ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE)  		ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); -	if (AR_SREV_9462(sc->sc_ah)) +	if (ath9k_hw_mci_is_enabled(ah))  		ath_mci_cleanup(sc);  } @@ -402,7 +435,7 @@ int ath9k_init_btcoex(struct ath_softc *sc)  		txq = sc->tx.txq_map[WME_AC_BE];  		ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);  		sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; -		if (AR_SREV_9462(ah)) { +		if (ath9k_hw_mci_is_enabled(ah)) {  			sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;  			INIT_LIST_HEAD(&sc->btcoex.mci.info);  |