diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/mac.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/mac.c | 126 | 
1 files changed, 44 insertions, 82 deletions
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index edc1cbbfeca..9cf7a7d0e11 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -209,15 +209,8 @@ bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,  {  	u32 cw;  	struct ath_common *common = ath9k_hw_common(ah); -	struct ath9k_hw_capabilities *pCap = &ah->caps;  	struct ath9k_tx_queue_info *qi; -	if (q >= pCap->total_queues) { -		ath_dbg(common, ATH_DBG_QUEUE, -			"Set TXQ properties, invalid queue: %u\n", q); -		return false; -	} -  	qi = &ah->txq[q];  	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {  		ath_dbg(common, ATH_DBG_QUEUE, @@ -280,15 +273,8 @@ bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,  			    struct ath9k_tx_queue_info *qinfo)  {  	struct ath_common *common = ath9k_hw_common(ah); -	struct ath9k_hw_capabilities *pCap = &ah->caps;  	struct ath9k_tx_queue_info *qi; -	if (q >= pCap->total_queues) { -		ath_dbg(common, ATH_DBG_QUEUE, -			"Get TXQ properties, invalid queue: %u\n", q); -		return false; -	} -  	qi = &ah->txq[q];  	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {  		ath_dbg(common, ATH_DBG_QUEUE, @@ -320,28 +306,27 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,  {  	struct ath_common *common = ath9k_hw_common(ah);  	struct ath9k_tx_queue_info *qi; -	struct ath9k_hw_capabilities *pCap = &ah->caps;  	int q;  	switch (type) {  	case ATH9K_TX_QUEUE_BEACON: -		q = pCap->total_queues - 1; +		q = ATH9K_NUM_TX_QUEUES - 1;  		break;  	case ATH9K_TX_QUEUE_CAB: -		q = pCap->total_queues - 2; +		q = ATH9K_NUM_TX_QUEUES - 2;  		break;  	case ATH9K_TX_QUEUE_PSPOLL:  		q = 1;  		break;  	case ATH9K_TX_QUEUE_UAPSD: -		q = pCap->total_queues - 3; +		q = ATH9K_NUM_TX_QUEUES - 3;  		break;  	case ATH9K_TX_QUEUE_DATA: -		for (q = 0; q < pCap->total_queues; q++) +		for (q = 0; q < ATH9K_NUM_TX_QUEUES; q++)  			if (ah->txq[q].tqi_type ==  			    ATH9K_TX_QUEUE_INACTIVE)  				break; -		if (q == pCap->total_queues) { +		if (q == ATH9K_NUM_TX_QUEUES) {  			ath_err(common, "No available TX queue\n");  			return -1;  		} @@ -382,15 +367,9 @@ EXPORT_SYMBOL(ath9k_hw_setuptxqueue);  bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)  { -	struct ath9k_hw_capabilities *pCap = &ah->caps;  	struct ath_common *common = ath9k_hw_common(ah);  	struct ath9k_tx_queue_info *qi; -	if (q >= pCap->total_queues) { -		ath_dbg(common, ATH_DBG_QUEUE, -			"Release TXQ, invalid queue: %u\n", q); -		return false; -	}  	qi = &ah->txq[q];  	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {  		ath_dbg(common, ATH_DBG_QUEUE, @@ -414,18 +393,11 @@ EXPORT_SYMBOL(ath9k_hw_releasetxqueue);  bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)  { -	struct ath9k_hw_capabilities *pCap = &ah->caps;  	struct ath_common *common = ath9k_hw_common(ah);  	struct ath9k_channel *chan = ah->curchan;  	struct ath9k_tx_queue_info *qi;  	u32 cwMin, chanCwMin, value; -	if (q >= pCap->total_queues) { -		ath_dbg(common, ATH_DBG_QUEUE, -			"Reset TXQ, invalid queue: %u\n", q); -		return false; -	} -  	qi = &ah->txq[q];  	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {  		ath_dbg(common, ATH_DBG_QUEUE, @@ -465,10 +437,9 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)  		REG_WRITE(ah, AR_QCBRCFG(q),  			  SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |  			  SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH)); -		REG_WRITE(ah, AR_QMISC(q), -			  REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | -			  (qi->tqi_cbrOverflowLimit ? -			   AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0)); +		REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_FSP_CBR | +			    (qi->tqi_cbrOverflowLimit ? +			     AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));  	}  	if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {  		REG_WRITE(ah, AR_QRDYTIMECFG(q), @@ -481,40 +452,31 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)  		  (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));  	if (qi->tqi_burstTime -	    && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) { -		REG_WRITE(ah, AR_QMISC(q), -			  REG_READ(ah, AR_QMISC(q)) | -			  AR_Q_MISC_RDYTIME_EXP_POLICY); +	    && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) +		REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_RDYTIME_EXP_POLICY); -	} - -	if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) { -		REG_WRITE(ah, AR_DMISC(q), -			  REG_READ(ah, AR_DMISC(q)) | -			  AR_D_MISC_POST_FR_BKOFF_DIS); -	} +	if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) +		REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS);  	REGWRITE_BUFFER_FLUSH(ah); -	if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) { -		REG_WRITE(ah, AR_DMISC(q), -			  REG_READ(ah, AR_DMISC(q)) | -			  AR_D_MISC_FRAG_BKOFF_EN); -	} +	if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) +		REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_FRAG_BKOFF_EN); +  	switch (qi->tqi_type) {  	case ATH9K_TX_QUEUE_BEACON:  		ENABLE_REGWRITE_BUFFER(ah); -		REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) -			  | AR_Q_MISC_FSP_DBA_GATED -			  | AR_Q_MISC_BEACON_USE -			  | AR_Q_MISC_CBR_INCR_DIS1); +		REG_SET_BIT(ah, AR_QMISC(q), +			    AR_Q_MISC_FSP_DBA_GATED +			    | AR_Q_MISC_BEACON_USE +			    | AR_Q_MISC_CBR_INCR_DIS1); -		REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) -			  | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << +		REG_SET_BIT(ah, AR_DMISC(q), +			    (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<  			     AR_D_MISC_ARB_LOCKOUT_CNTRL_S) -			  | AR_D_MISC_BEACON_USE -			  | AR_D_MISC_POST_FR_BKOFF_DIS); +			    | AR_D_MISC_BEACON_USE +			    | AR_D_MISC_POST_FR_BKOFF_DIS);  		REGWRITE_BUFFER_FLUSH(ah); @@ -533,41 +495,38 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)  	case ATH9K_TX_QUEUE_CAB:  		ENABLE_REGWRITE_BUFFER(ah); -		REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) -			  | AR_Q_MISC_FSP_DBA_GATED -			  | AR_Q_MISC_CBR_INCR_DIS1 -			  | AR_Q_MISC_CBR_INCR_DIS0); +		REG_SET_BIT(ah, AR_QMISC(q), +			    AR_Q_MISC_FSP_DBA_GATED +			    | AR_Q_MISC_CBR_INCR_DIS1 +			    | AR_Q_MISC_CBR_INCR_DIS0);  		value = (qi->tqi_readyTime -  			 (ah->config.sw_beacon_response_time -  			  ah->config.dma_beacon_response_time) -  			 ah->config.additional_swba_backoff) * 1024;  		REG_WRITE(ah, AR_QRDYTIMECFG(q),  			  value | AR_Q_RDYTIMECFG_EN); -		REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) -			  | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << +		REG_SET_BIT(ah, AR_DMISC(q), +			    (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<  			     AR_D_MISC_ARB_LOCKOUT_CNTRL_S));  		REGWRITE_BUFFER_FLUSH(ah);  		break;  	case ATH9K_TX_QUEUE_PSPOLL: -		REG_WRITE(ah, AR_QMISC(q), -			  REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1); +		REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_CBR_INCR_DIS1);  		break;  	case ATH9K_TX_QUEUE_UAPSD: -		REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) | -			  AR_D_MISC_POST_FR_BKOFF_DIS); +		REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS);  		break;  	default:  		break;  	}  	if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) { -		REG_WRITE(ah, AR_DMISC(q), -			  REG_READ(ah, AR_DMISC(q)) | -			  SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL, -			     AR_D_MISC_ARB_LOCKOUT_CNTRL) | -			  AR_D_MISC_POST_FR_BKOFF_DIS); +		REG_SET_BIT(ah, AR_DMISC(q), +			    SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL, +			       AR_D_MISC_ARB_LOCKOUT_CNTRL) | +			    AR_D_MISC_POST_FR_BKOFF_DIS);  	}  	if (AR_SREV_9300_20_OR_LATER(ah)) @@ -754,7 +713,6 @@ EXPORT_SYMBOL(ath9k_hw_abortpcurecv);  bool ath9k_hw_stopdmarecv(struct ath_hw *ah, bool *reset)  {  #define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */ -#define AH_RX_TIME_QUANTUM     100     /* usec */  	struct ath_common *common = ath9k_hw_common(ah);  	u32 mac_status, last_mac_status = 0;  	int i; @@ -797,7 +755,6 @@ bool ath9k_hw_stopdmarecv(struct ath_hw *ah, bool *reset)  		return true;  	} -#undef AH_RX_TIME_QUANTUM  #undef AH_RX_STOP_DMA_TIMEOUT  }  EXPORT_SYMBOL(ath9k_hw_stopdmarecv); @@ -855,10 +812,14 @@ EXPORT_SYMBOL(ath9k_hw_disable_interrupts);  void ath9k_hw_enable_interrupts(struct ath_hw *ah)  {  	struct ath_common *common = ath9k_hw_common(ah); +	u32 sync_default = AR_INTR_SYNC_DEFAULT;  	if (!(ah->imask & ATH9K_INT_GLOBAL))  		return; +	if (AR_SREV_9340(ah)) +		sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; +  	ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n");  	REG_WRITE(ah, AR_IER, AR_IER_ENABLE);  	if (!AR_SREV_9100(ah)) { @@ -867,10 +828,8 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)  		REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ); -		REG_WRITE(ah, AR_INTR_SYNC_ENABLE, -			  AR_INTR_SYNC_DEFAULT); -		REG_WRITE(ah, AR_INTR_SYNC_MASK, -			  AR_INTR_SYNC_DEFAULT); +		REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default); +		REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default);  	}  	ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",  		REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); @@ -926,6 +885,9 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)  			mask |= AR_IMR_GENTMR;  	} +	if (ints & ATH9K_INT_GENTIMER) +		mask |= AR_IMR_GENTMR; +  	if (ints & (ATH9K_INT_BMISC)) {  		mask |= AR_IMR_BCNMISC;  		if (ints & ATH9K_INT_TIM)  |