diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/htc_drv_txrx.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 86 | 
1 files changed, 56 insertions, 30 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 2571b443ac8..bd0b4acc3ec 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -20,19 +20,29 @@  /* TX */  /******/ +#define ATH9K_HTC_INIT_TXQ(subtype) do {			\ +		qi.tqi_subtype = subtype;			\ +		qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;		\ +		qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;		\ +		qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;		\ +		qi.tqi_physCompBuf = 0;				\ +		qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |	\ +			TXQ_FLAG_TXDESCINT_ENABLE;		\ +	} while (0) +  int get_hw_qnum(u16 queue, int *hwq_map)  {  	switch (queue) {  	case 0: -		return hwq_map[ATH9K_WME_AC_VO]; +		return hwq_map[WME_AC_VO];  	case 1: -		return hwq_map[ATH9K_WME_AC_VI]; +		return hwq_map[WME_AC_VI];  	case 2: -		return hwq_map[ATH9K_WME_AC_BE]; +		return hwq_map[WME_AC_BE];  	case 3: -		return hwq_map[ATH9K_WME_AC_BK]; +		return hwq_map[WME_AC_BK];  	default: -		return hwq_map[ATH9K_WME_AC_BE]; +		return hwq_map[WME_AC_BE];  	}  } @@ -71,7 +81,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)  	struct ath9k_htc_vif *avp;  	struct ath9k_htc_tx_ctl tx_ctl;  	enum htc_endpoint_id epid; -	u16 qnum, hw_qnum; +	u16 qnum;  	__le16 fc;  	u8 *tx_fhdr;  	u8 sta_idx; @@ -131,20 +141,23 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)  		memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));  		qnum = skb_get_queue_mapping(skb); -		hw_qnum = get_hw_qnum(qnum, priv->hwq_map); -		switch (hw_qnum) { +		switch (qnum) {  		case 0: -			epid = priv->data_be_ep; +			TX_QSTAT_INC(WME_AC_VO); +			epid = priv->data_vo_ep;  			break; -		case 2: +		case 1: +			TX_QSTAT_INC(WME_AC_VI);  			epid = priv->data_vi_ep;  			break; -		case 3: -			epid = priv->data_vo_ep; +		case 2: +			TX_QSTAT_INC(WME_AC_BE); +			epid = priv->data_be_ep;  			break; -		case 1: +		case 3:  		default: +			TX_QSTAT_INC(WME_AC_BK);  			epid = priv->data_bk_ep;  			break;  		} @@ -174,6 +187,19 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)  	return htc_send(priv->htc, skb, epid, &tx_ctl);  } +static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv, +				    struct ath9k_htc_sta *ista, u8 tid) +{ +	bool ret = false; + +	spin_lock_bh(&priv->tx_lock); +	if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP)) +		ret = true; +	spin_unlock_bh(&priv->tx_lock); + +	return ret; +} +  void ath9k_tx_tasklet(unsigned long data)  {  	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; @@ -203,8 +229,7 @@ void ath9k_tx_tasklet(unsigned long data)  		/* Check if we need to start aggregation */  		if (sta && conf_is_ht(&priv->hw->conf) && -		    (priv->op_flags & OP_TXAGGR) -		    && !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { +		    !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {  			if (ieee80211_is_data_qos(fc)) {  				u8 *qc, tid;  				struct ath9k_htc_sta *ista; @@ -213,10 +238,11 @@ void ath9k_tx_tasklet(unsigned long data)  				tid = qc[0] & 0xf;  				ista = (struct ath9k_htc_sta *)sta->drv_priv; -				if ((tid < ATH9K_HTC_MAX_TID) && -				    ista->tid_state[tid] == AGGR_STOP) { +				if (ath9k_htc_check_tx_aggr(priv, ista, tid)) {  					ieee80211_start_tx_ba_session(sta, tid); +					spin_lock_bh(&priv->tx_lock);  					ista->tid_state[tid] = AGGR_PROGRESS; +					spin_unlock_bh(&priv->tx_lock);  				}  			}  		} @@ -284,8 +310,7 @@ void ath9k_tx_cleanup(struct ath9k_htc_priv *priv)  } -bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, -			 enum ath9k_tx_queue_subtype subtype) +bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype)  {  	struct ath_hw *ah = priv->ah;  	struct ath_common *common = ath9k_hw_common(ah); @@ -293,13 +318,7 @@ bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv,  	int qnum;  	memset(&qi, 0, sizeof(qi)); - -	qi.tqi_subtype = subtype; -	qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; -	qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; -	qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT; -	qi.tqi_physCompBuf = 0; -	qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | TXQ_FLAG_TXDESCINT_ENABLE; +	ATH9K_HTC_INIT_TXQ(subtype);  	qnum = ath9k_hw_setuptxqueue(priv->ah, ATH9K_TX_QUEUE_DATA, &qi);  	if (qnum == -1) @@ -317,6 +336,16 @@ bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv,  	return true;  } +int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv) +{ +	struct ath9k_tx_queue_info qi; + +	memset(&qi, 0, sizeof(qi)); +	ATH9K_HTC_INIT_TXQ(0); + +	return ath9k_hw_setuptxqueue(priv->ah, ATH9K_TX_QUEUE_CAB, &qi); +} +  /******/  /* RX */  /******/ @@ -387,9 +416,6 @@ static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv)  	/* configure operational mode */  	ath9k_hw_setopmode(ah); -	/* Handle any link-level address change. */ -	ath9k_hw_setmac(ah, common->macaddr); -  	/* calculate and install multicast filter */  	mfilt[0] = mfilt[1] = ~0;  	ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); @@ -399,7 +425,7 @@ void ath9k_host_rx_init(struct ath9k_htc_priv *priv)  {  	ath9k_hw_rxena(priv->ah);  	ath9k_htc_opmode_init(priv); -	ath9k_hw_startpcureceive(priv->ah); +	ath9k_hw_startpcureceive(priv->ah, (priv->op_flags & OP_SCANNING));  	priv->rx.last_rssi = ATH_RSSI_DUMMY_MARKER;  }  |