diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/desc.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath5k/desc.c | 152 | 
1 files changed, 72 insertions, 80 deletions
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 7d7b646ab65..43244382f21 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c @@ -91,14 +91,13 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,  	tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;  	/* -	 * Verify and set header length -	 * XXX: I only found that on 5210 code, does it work on 5211 ? +	 * Verify and set header length (only 5210)  	 */  	if (ah->ah_version == AR5K_AR5210) { -		if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN) +		if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210)  			return -EINVAL;  		tx_ctl->tx_control_0 |= -			AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN); +			AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210);  	}  	/*Differences between 5210-5211*/ @@ -110,11 +109,11 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,  		case AR5K_PKT_TYPE_PIFS:  			frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;  		default: -			frame_type = type /*<< 2 ?*/; +			frame_type = type;  		}  		tx_ctl->tx_control_0 |= -		AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) | +		AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210) |  		AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);  	} else { @@ -123,21 +122,30 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,  			AR5K_REG_SM(antenna_mode,  				AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);  		tx_ctl->tx_control_1 |= -			AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE); +			AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211);  	} +  #define _TX_FLAGS(_c, _flag)					\  	if (flags & AR5K_TXDESC_##_flag) {			\  		tx_ctl->tx_control_##_c |=			\  			AR5K_2W_TX_DESC_CTL##_c##_##_flag;	\  	} - +#define _TX_FLAGS_5211(_c, _flag)					\ +	if (flags & AR5K_TXDESC_##_flag) {				\ +		tx_ctl->tx_control_##_c |=				\ +			AR5K_2W_TX_DESC_CTL##_c##_##_flag##_5211;	\ +	}  	_TX_FLAGS(0, CLRDMASK); -	_TX_FLAGS(0, VEOL);  	_TX_FLAGS(0, INTREQ);  	_TX_FLAGS(0, RTSENA); -	_TX_FLAGS(1, NOACK); + +	if (ah->ah_version == AR5K_AR5211) { +		_TX_FLAGS_5211(0, VEOL); +		_TX_FLAGS_5211(1, NOACK); +	}  #undef _TX_FLAGS +#undef _TX_FLAGS_5211  	/*  	 * WEP crap @@ -147,7 +155,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,  			AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;  		tx_ctl->tx_control_1 |=  			AR5K_REG_SM(key_index, -			AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX); +			AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX);  	}  	/* @@ -156,7 +164,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,  	if ((ah->ah_version == AR5K_AR5210) &&  			(flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))  		tx_ctl->tx_control_1 |= rtscts_duration & -				AR5K_2W_TX_DESC_CTL1_RTS_DURATION; +				AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210;  	return 0;  } @@ -176,7 +184,6 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,  	struct ath5k_hw_4w_tx_ctl *tx_ctl;  	unsigned int frame_len; -	ATH5K_TRACE(ah->ah_sc);  	tx_ctl = &desc->ud.ds_tx5212.tx_ctl;  	/* @@ -256,7 +263,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,  	if (key_index != AR5K_TXKEYIX_INVALID) {  		tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;  		tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, -				AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX); +				AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX);  	}  	/* @@ -278,13 +285,17 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,  /*   * Initialize a 4-word multi rate retry tx control descriptor on 5212   */ -static int +int  ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,  	unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,  	u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)  {  	struct ath5k_hw_4w_tx_ctl *tx_ctl; +	/* no mrr support for cards older than 5212 */ +	if (ah->ah_version < AR5K_AR5212) +		return 0; +  	/*  	 * Rates can be 0 as long as the retry count is 0 too.  	 * A zero rate and nonzero retry count will put the HW into a mode where @@ -324,15 +335,6 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,  	return 0;  } -/* no mrr support for cards older than 5212 */ -static int -ath5k_hw_setup_no_mrr(struct ath5k_hw *ah, struct ath5k_desc *desc, -	unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, -	u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3) -{ -	return 0; -} -  /*   * Proccess the tx status descriptor on 5210/5211   */ @@ -342,8 +344,6 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,  	struct ath5k_hw_2w_tx_ctl *tx_ctl;  	struct ath5k_hw_tx_status *tx_status; -	ATH5K_TRACE(ah->ah_sc); -  	tx_ctl = &desc->ud.ds_tx5210.tx_ctl;  	tx_status = &desc->ud.ds_tx5210.tx_stat; @@ -396,8 +396,6 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,  	struct ath5k_hw_4w_tx_ctl *tx_ctl;  	struct ath5k_hw_tx_status *tx_status; -	ATH5K_TRACE(ah->ah_sc); -  	tx_ctl = &desc->ud.ds_tx5212.tx_ctl;  	tx_status = &desc->ud.ds_tx5212.tx_stat; @@ -419,11 +417,11 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,  	ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,  		AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);  	ts->ts_antenna = (tx_status->tx_status_1 & -		AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1; +		AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1;  	ts->ts_status = 0;  	ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1, -			AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX); +			AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212);  	/* The longretry counter has the number of un-acked retries  	 * for the final rate. To get the total number of retries @@ -485,12 +483,11 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,  /*   * Initialize an rx control descriptor   */ -static int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, -			u32 size, unsigned int flags) +int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, +			   u32 size, unsigned int flags)  {  	struct ath5k_hw_rx_ctl *rx_ctl; -	ATH5K_TRACE(ah->ah_sc);  	rx_ctl = &desc->ud.ds_rx.rx_ctl;  	/* @@ -502,10 +499,11 @@ static int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,  	*/  	memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc)); +	if (unlikely(size & ~AR5K_DESC_RX_CTL1_BUF_LEN)) +		return -EINVAL; +  	/* Setup descriptor */  	rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN; -	if (unlikely(rx_ctl->rx_control_1 != size)) -		return -EINVAL;  	if (flags & AR5K_RXDESC_INTREQ)  		rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ; @@ -521,13 +519,15 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,  {  	struct ath5k_hw_rx_status *rx_status; -	rx_status = &desc->ud.ds_rx.u.rx_stat; +	rx_status = &desc->ud.ds_rx.rx_stat;  	/* No frame received / not ready */  	if (unlikely(!(rx_status->rx_status_1 & -	AR5K_5210_RX_DESC_STATUS1_DONE))) +			AR5K_5210_RX_DESC_STATUS1_DONE)))  		return -EINPROGRESS; +	memset(rs, 0, sizeof(struct ath5k_rx_status)); +  	/*  	 * Frame receive status  	 */ @@ -537,15 +537,23 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,  		AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);  	rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,  		AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE); -	rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, -		AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA);  	rs->rs_more = !!(rx_status->rx_status_0 &  		AR5K_5210_RX_DESC_STATUS0_MORE); -	/* TODO: this timestamp is 13 bit, later on we assume 15 bit */ +	/* TODO: this timestamp is 13 bit, later on we assume 15 bit! +	 * also the HAL code for 5210 says the timestamp is bits [10..22] of the +	 * TSF, and extends the timestamp here to 15 bit. +	 * we need to check on 5210... +	 */  	rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,  		AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); -	rs->rs_status = 0; -	rs->rs_phyerr = 0; + +	if (ah->ah_version == AR5K_AR5211) +		rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0, +				AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211); +	else +		rs->rs_antenna = (rx_status->rx_status_0 & +				AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210) +				? 2 : 1;  	/*  	 * Key table status @@ -560,19 +568,21 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,  	 * Receive/descriptor errors  	 */  	if (!(rx_status->rx_status_1 & -	AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { +			AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {  		if (rx_status->rx_status_1 &  				AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)  			rs->rs_status |= AR5K_RXERR_CRC; -		if (rx_status->rx_status_1 & -				AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN) +		/* only on 5210 */ +		if ((ah->ah_version == AR5K_AR5210) && +		    (rx_status->rx_status_1 & +				AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210))  			rs->rs_status |= AR5K_RXERR_FIFO;  		if (rx_status->rx_status_1 &  				AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {  			rs->rs_status |= AR5K_RXERR_PHY; -			rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1, +			rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1,  				AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);  		} @@ -588,22 +598,20 @@ static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,   * Proccess the rx status descriptor on 5212   */  static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, -		struct ath5k_desc *desc, struct ath5k_rx_status *rs) +					struct ath5k_desc *desc, +					struct ath5k_rx_status *rs)  {  	struct ath5k_hw_rx_status *rx_status; -	struct ath5k_hw_rx_error *rx_err; -	ATH5K_TRACE(ah->ah_sc); -	rx_status = &desc->ud.ds_rx.u.rx_stat; - -	/* Overlay on error */ -	rx_err = &desc->ud.ds_rx.u.rx_err; +	rx_status = &desc->ud.ds_rx.rx_stat;  	/* No frame received / not ready */  	if (unlikely(!(rx_status->rx_status_1 & -	AR5K_5212_RX_DESC_STATUS1_DONE))) +				AR5K_5212_RX_DESC_STATUS1_DONE)))  		return -EINPROGRESS; +	memset(rs, 0, sizeof(struct ath5k_rx_status)); +  	/*  	 * Frame receive status  	 */ @@ -619,15 +627,13 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,  		AR5K_5212_RX_DESC_STATUS0_MORE);  	rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,  		AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); -	rs->rs_status = 0; -	rs->rs_phyerr = 0;  	/*  	 * Key table status  	 */  	if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)  		rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, -				AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); +					   AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);  	else  		rs->rs_keyix = AR5K_RXKEYIX_INVALID; @@ -635,7 +641,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,  	 * Receive/descriptor errors  	 */  	if (!(rx_status->rx_status_1 & -	AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { +	    AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {  		if (rx_status->rx_status_1 &  				AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)  			rs->rs_status |= AR5K_RXERR_CRC; @@ -643,9 +649,10 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,  		if (rx_status->rx_status_1 &  				AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {  			rs->rs_status |= AR5K_RXERR_PHY; -			rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1, -					   AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); -			ath5k_ani_phy_error_report(ah, rs->rs_phyerr); +			rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1, +				AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE); +			if (!ah->ah_capabilities.cap_has_phyerr_counters) +				ath5k_ani_phy_error_report(ah, rs->rs_phyerr);  		}  		if (rx_status->rx_status_1 & @@ -656,7 +663,6 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,  				AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)  			rs->rs_status |= AR5K_RXERR_MIC;  	} -  	return 0;  } @@ -665,29 +671,15 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,   */  int ath5k_hw_init_desc_functions(struct ath5k_hw *ah)  { - -	if (ah->ah_version != AR5K_AR5210 && -		ah->ah_version != AR5K_AR5211 && -		ah->ah_version != AR5K_AR5212) -			return -ENOTSUPP; -  	if (ah->ah_version == AR5K_AR5212) { -		ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;  		ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc; -		ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_mrr_tx_desc;  		ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status; -	} else { -		ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; +		ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status; +	} else if (ah->ah_version <= AR5K_AR5211) {  		ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc; -		ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_no_mrr;  		ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status; -	} - -	if (ah->ah_version == AR5K_AR5212) -		ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status; -	else if (ah->ah_version <= AR5K_AR5211)  		ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status; - +	} else +		return -ENOTSUPP;  	return 0;  } -  |