brintos

brintos / linux-shallow public Read only

0
0
Text · 22.0 KiB · 80f7513 Raw
787 lines · c
1/*2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>4 * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>5 *6 * Permission to use, copy, modify, and distribute this software for any7 * purpose with or without fee is hereby granted, provided that the above8 * copyright notice and this permission notice appear in all copies.9 *10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.17 *18 */19 20/******************************\21 Hardware Descriptor Functions22\******************************/23 24#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt25 26#include "ath5k.h"27#include "reg.h"28#include "debug.h"29 30 31/**32 * DOC: Hardware descriptor functions33 *34 * Here we handle the processing of the low-level hw descriptors35 * that hw reads and writes via DMA for each TX and RX attempt (that means36 * we can also have descriptors for failed TX/RX tries). We have two kind of37 * descriptors for RX and TX, control descriptors tell the hw how to send or38 * receive a packet where to read/write it from/to etc and status descriptors39 * that contain information about how the packet was sent or received (errors40 * included).41 *42 * Descriptor format is not exactly the same for each MAC chip version so we43 * have function pointers on &struct ath5k_hw we initialize at runtime based on44 * the chip used.45 */46 47 48/************************\49* TX Control descriptors *50\************************/51 52/**53 * ath5k_hw_setup_2word_tx_desc() - Initialize a 2-word tx control descriptor54 * @ah: The &struct ath5k_hw55 * @desc: The &struct ath5k_desc56 * @pkt_len: Frame length in bytes57 * @hdr_len: Header length in bytes (only used on AR5210)58 * @padsize: Any padding we've added to the frame length59 * @type: One of enum ath5k_pkt_type60 * @tx_power: Tx power in 0.5dB steps61 * @tx_rate0: HW idx for transmission rate62 * @tx_tries0: Max number of retransmissions63 * @key_index: Index on key table to use for encryption64 * @antenna_mode: Which antenna to use (0 for auto)65 * @flags: One of AR5K_TXDESC_* flags (desc.h)66 * @rtscts_rate: HW idx for RTS/CTS transmission rate67 * @rtscts_duration: What to put on duration field on the header of RTS/CTS68 *69 * Internal function to initialize a 2-Word TX control descriptor70 * found on AR5210 and AR5211 MACs chips.71 *72 * Returns 0 on success or -EINVAL on false input73 */74static int75ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah,76			struct ath5k_desc *desc,77			unsigned int pkt_len, unsigned int hdr_len,78			int padsize,79			enum ath5k_pkt_type type,80			unsigned int tx_power,81			unsigned int tx_rate0, unsigned int tx_tries0,82			unsigned int key_index,83			unsigned int antenna_mode,84			unsigned int flags,85			unsigned int rtscts_rate, unsigned int rtscts_duration)86{87	u32 frame_type;88	struct ath5k_hw_2w_tx_ctl *tx_ctl;89	unsigned int frame_len;90 91	tx_ctl = &desc->ud.ds_tx5210.tx_ctl;92 93	/*94	 * Validate input95	 * - Zero retries don't make sense.96	 * - A zero rate will put the HW into a mode where it continuously sends97	 *   noise on the channel, so it is important to avoid this.98	 */99	if (unlikely(tx_tries0 == 0)) {100		ATH5K_ERR(ah, "zero retries\n");101		WARN_ON(1);102		return -EINVAL;103	}104	if (unlikely(tx_rate0 == 0)) {105		ATH5K_ERR(ah, "zero rate\n");106		WARN_ON(1);107		return -EINVAL;108	}109 110	/* Clear descriptor */111	memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));112 113	/* Setup control descriptor */114 115	/* Verify and set frame length */116 117	/* remove padding we might have added before */118	frame_len = pkt_len - padsize + FCS_LEN;119 120	if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)121		return -EINVAL;122 123	tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;124 125	/* Verify and set buffer length */126 127	/* NB: beacon's BufLen must be a multiple of 4 bytes */128	if (type == AR5K_PKT_TYPE_BEACON)129		pkt_len = roundup(pkt_len, 4);130 131	if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)132		return -EINVAL;133 134	tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;135 136	/*137	 * Verify and set header length (only 5210)138	 */139	if (ah->ah_version == AR5K_AR5210) {140		if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210)141			return -EINVAL;142		tx_ctl->tx_control_0 |=143			AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN_5210);144	}145 146	/*Differences between 5210-5211*/147	if (ah->ah_version == AR5K_AR5210) {148		switch (type) {149		case AR5K_PKT_TYPE_BEACON:150		case AR5K_PKT_TYPE_PROBE_RESP:151			frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;152			break;153		case AR5K_PKT_TYPE_PIFS:154			frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;155			break;156		default:157			frame_type = type;158			break;159		}160 161		tx_ctl->tx_control_0 |=162		AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_5210) |163		AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);164 165	} else {166		tx_ctl->tx_control_0 |=167			AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |168			AR5K_REG_SM(antenna_mode,169				AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);170		tx_ctl->tx_control_1 |=171			AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_5211);172	}173 174#define _TX_FLAGS(_c, _flag)					\175	if (flags & AR5K_TXDESC_##_flag) {			\176		tx_ctl->tx_control_##_c |=			\177			AR5K_2W_TX_DESC_CTL##_c##_##_flag;	\178	}179#define _TX_FLAGS_5211(_c, _flag)					\180	if (flags & AR5K_TXDESC_##_flag) {				\181		tx_ctl->tx_control_##_c |=				\182			AR5K_2W_TX_DESC_CTL##_c##_##_flag##_5211;	\183	}184	_TX_FLAGS(0, CLRDMASK);185	_TX_FLAGS(0, INTREQ);186	_TX_FLAGS(0, RTSENA);187 188	if (ah->ah_version == AR5K_AR5211) {189		_TX_FLAGS_5211(0, VEOL);190		_TX_FLAGS_5211(1, NOACK);191	}192 193#undef _TX_FLAGS194#undef _TX_FLAGS_5211195 196	/*197	 * WEP crap198	 */199	if (key_index != AR5K_TXKEYIX_INVALID) {200		tx_ctl->tx_control_0 |=201			AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;202		tx_ctl->tx_control_1 |=203			AR5K_REG_SM(key_index,204			AR5K_2W_TX_DESC_CTL1_ENC_KEY_IDX);205	}206 207	/*208	 * RTS/CTS Duration [5210 ?]209	 */210	if ((ah->ah_version == AR5K_AR5210) &&211			(flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))212		tx_ctl->tx_control_1 |= rtscts_duration &213				AR5K_2W_TX_DESC_CTL1_RTS_DURATION_5210;214 215	return 0;216}217 218/**219 * ath5k_hw_setup_4word_tx_desc() - Initialize a 4-word tx control descriptor220 * @ah: The &struct ath5k_hw221 * @desc: The &struct ath5k_desc222 * @pkt_len: Frame length in bytes223 * @hdr_len: Header length in bytes (only used on AR5210)224 * @padsize: Any padding we've added to the frame length225 * @type: One of enum ath5k_pkt_type226 * @tx_power: Tx power in 0.5dB steps227 * @tx_rate0: HW idx for transmission rate228 * @tx_tries0: Max number of retransmissions229 * @key_index: Index on key table to use for encryption230 * @antenna_mode: Which antenna to use (0 for auto)231 * @flags: One of AR5K_TXDESC_* flags (desc.h)232 * @rtscts_rate: HW idx for RTS/CTS transmission rate233 * @rtscts_duration: What to put on duration field on the header of RTS/CTS234 *235 * Internal function to initialize a 4-Word TX control descriptor236 * found on AR5212 and later MACs chips.237 *238 * Returns 0 on success or -EINVAL on false input239 */240static int241ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,242			struct ath5k_desc *desc,243			unsigned int pkt_len, unsigned int hdr_len,244			int padsize,245			enum ath5k_pkt_type type,246			unsigned int tx_power,247			unsigned int tx_rate0, unsigned int tx_tries0,248			unsigned int key_index,249			unsigned int antenna_mode,250			unsigned int flags,251			unsigned int rtscts_rate, unsigned int rtscts_duration)252{253	struct ath5k_hw_4w_tx_ctl *tx_ctl;254	unsigned int frame_len;255 256	/*257	 * Use local variables for these to reduce load/store access on258	 * uncached memory259	 */260	u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0;261 262	tx_ctl = &desc->ud.ds_tx5212.tx_ctl;263 264	/*265	 * Validate input266	 * - Zero retries don't make sense.267	 * - A zero rate will put the HW into a mode where it continuously sends268	 *   noise on the channel, so it is important to avoid this.269	 */270	if (unlikely(tx_tries0 == 0)) {271		ATH5K_ERR(ah, "zero retries\n");272		WARN_ON(1);273		return -EINVAL;274	}275	if (unlikely(tx_rate0 == 0)) {276		ATH5K_ERR(ah, "zero rate\n");277		WARN_ON(1);278		return -EINVAL;279	}280 281	tx_power += ah->ah_txpower.txp_offset;282	if (tx_power > AR5K_TUNE_MAX_TXPOWER)283		tx_power = AR5K_TUNE_MAX_TXPOWER;284 285	/* Clear descriptor status area */286	memset(&desc->ud.ds_tx5212.tx_stat, 0,287	       sizeof(desc->ud.ds_tx5212.tx_stat));288 289	/* Setup control descriptor */290 291	/* Verify and set frame length */292 293	/* remove padding we might have added before */294	frame_len = pkt_len - padsize + FCS_LEN;295 296	if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)297		return -EINVAL;298 299	txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;300 301	/* Verify and set buffer length */302 303	/* NB: beacon's BufLen must be a multiple of 4 bytes */304	if (type == AR5K_PKT_TYPE_BEACON)305		pkt_len = roundup(pkt_len, 4);306 307	if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)308		return -EINVAL;309 310	txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;311 312	txctl0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |313		  AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);314	txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);315	txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);316	txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;317 318#define _TX_FLAGS(_c, _flag)					\319	if (flags & AR5K_TXDESC_##_flag) {			\320		txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag;	\321	}322 323	_TX_FLAGS(0, CLRDMASK);324	_TX_FLAGS(0, VEOL);325	_TX_FLAGS(0, INTREQ);326	_TX_FLAGS(0, RTSENA);327	_TX_FLAGS(0, CTSENA);328	_TX_FLAGS(1, NOACK);329 330#undef _TX_FLAGS331 332	/*333	 * WEP crap334	 */335	if (key_index != AR5K_TXKEYIX_INVALID) {336		txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;337		txctl1 |= AR5K_REG_SM(key_index,338				AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX);339	}340 341	/*342	 * RTS/CTS343	 */344	if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) {345		if ((flags & AR5K_TXDESC_RTSENA) &&346				(flags & AR5K_TXDESC_CTSENA))347			return -EINVAL;348		txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION;349		txctl3 |= AR5K_REG_SM(rtscts_rate,350				AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);351	}352 353	tx_ctl->tx_control_0 = txctl0;354	tx_ctl->tx_control_1 = txctl1;355	tx_ctl->tx_control_2 = txctl2;356	tx_ctl->tx_control_3 = txctl3;357 358	return 0;359}360 361/**362 * ath5k_hw_setup_mrr_tx_desc() - Initialize an MRR tx control descriptor363 * @ah: The &struct ath5k_hw364 * @desc: The &struct ath5k_desc365 * @tx_rate1: HW idx for rate used on transmission series 1366 * @tx_tries1: Max number of retransmissions for transmission series 1367 * @tx_rate2: HW idx for rate used on transmission series 2368 * @tx_tries2: Max number of retransmissions for transmission series 2369 * @tx_rate3: HW idx for rate used on transmission series 3370 * @tx_tries3: Max number of retransmissions for transmission series 3371 *372 * Multi rate retry (MRR) tx control descriptors are available only on AR5212373 * MACs, they are part of the normal 4-word tx control descriptor (see above)374 * but we handle them through a separate function for better abstraction.375 *376 * Returns 0 on success or -EINVAL on invalid input377 */378int379ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah,380			struct ath5k_desc *desc,381			u_int tx_rate1, u_int tx_tries1,382			u_int tx_rate2, u_int tx_tries2,383			u_int tx_rate3, u_int tx_tries3)384{385	struct ath5k_hw_4w_tx_ctl *tx_ctl;386 387	/* no mrr support for cards older than 5212 */388	if (ah->ah_version < AR5K_AR5212)389		return 0;390 391	/*392	 * Rates can be 0 as long as the retry count is 0 too.393	 * A zero rate and nonzero retry count will put the HW into a mode where394	 * it continuously sends noise on the channel, so it is important to395	 * avoid this.396	 */397	if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||398		     (tx_rate2 == 0 && tx_tries2 != 0) ||399		     (tx_rate3 == 0 && tx_tries3 != 0))) {400		ATH5K_ERR(ah, "zero rate\n");401		WARN_ON(1);402		return -EINVAL;403	}404 405	if (ah->ah_version == AR5K_AR5212) {406		tx_ctl = &desc->ud.ds_tx5212.tx_ctl;407 408#define _XTX_TRIES(_n)							\409	if (tx_tries##_n) {						\410		tx_ctl->tx_control_2 |=					\411		    AR5K_REG_SM(tx_tries##_n,				\412		    AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n);		\413		tx_ctl->tx_control_3 |=					\414		    AR5K_REG_SM(tx_rate##_n,				\415		    AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n);		\416	}417 418		_XTX_TRIES(1);419		_XTX_TRIES(2);420		_XTX_TRIES(3);421 422#undef _XTX_TRIES423 424		return 1;425	}426 427	return 0;428}429 430 431/***********************\432* TX Status descriptors *433\***********************/434 435/**436 * ath5k_hw_proc_2word_tx_status() - Process a tx status descriptor on 5210/1437 * @ah: The &struct ath5k_hw438 * @desc: The &struct ath5k_desc439 * @ts: The &struct ath5k_tx_status440 */441static int442ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,443				struct ath5k_desc *desc,444				struct ath5k_tx_status *ts)445{446	struct ath5k_hw_tx_status *tx_status;447 448	tx_status = &desc->ud.ds_tx5210.tx_stat;449 450	/* No frame has been send or error */451	if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))452		return -EINPROGRESS;453 454	/*455	 * Get descriptor status456	 */457	ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,458		AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);459	ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,460		AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);461	ts->ts_final_retry = AR5K_REG_MS(tx_status->tx_status_0,462		AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);463	/*TODO: ts->ts_virtcol + test*/464	ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,465		AR5K_DESC_TX_STATUS1_SEQ_NUM);466	ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,467		AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);468	ts->ts_antenna = 1;469	ts->ts_status = 0;470	ts->ts_final_idx = 0;471 472	if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {473		if (tx_status->tx_status_0 &474				AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)475			ts->ts_status |= AR5K_TXERR_XRETRY;476 477		if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)478			ts->ts_status |= AR5K_TXERR_FIFO;479 480		if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)481			ts->ts_status |= AR5K_TXERR_FILT;482	}483 484	return 0;485}486 487/**488 * ath5k_hw_proc_4word_tx_status() - Process a tx status descriptor on 5212489 * @ah: The &struct ath5k_hw490 * @desc: The &struct ath5k_desc491 * @ts: The &struct ath5k_tx_status492 */493static int494ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,495				struct ath5k_desc *desc,496				struct ath5k_tx_status *ts)497{498	struct ath5k_hw_tx_status *tx_status;499	u32 txstat0, txstat1;500 501	tx_status = &desc->ud.ds_tx5212.tx_stat;502 503	txstat1 = READ_ONCE(tx_status->tx_status_1);504 505	/* No frame has been send or error */506	if (unlikely(!(txstat1 & AR5K_DESC_TX_STATUS1_DONE)))507		return -EINPROGRESS;508 509	txstat0 = READ_ONCE(tx_status->tx_status_0);510 511	/*512	 * Get descriptor status513	 */514	ts->ts_tstamp = AR5K_REG_MS(txstat0,515		AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);516	ts->ts_shortretry = AR5K_REG_MS(txstat0,517		AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);518	ts->ts_final_retry = AR5K_REG_MS(txstat0,519		AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);520	ts->ts_seqnum = AR5K_REG_MS(txstat1,521		AR5K_DESC_TX_STATUS1_SEQ_NUM);522	ts->ts_rssi = AR5K_REG_MS(txstat1,523		AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);524	ts->ts_antenna = (txstat1 &525		AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1;526	ts->ts_status = 0;527 528	ts->ts_final_idx = AR5K_REG_MS(txstat1,529			AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212);530 531	/* TX error */532	if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {533		if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)534			ts->ts_status |= AR5K_TXERR_XRETRY;535 536		if (txstat0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)537			ts->ts_status |= AR5K_TXERR_FIFO;538 539		if (txstat0 & AR5K_DESC_TX_STATUS0_FILTERED)540			ts->ts_status |= AR5K_TXERR_FILT;541	}542 543	return 0;544}545 546 547/****************\548* RX Descriptors *549\****************/550 551/**552 * ath5k_hw_setup_rx_desc() - Initialize an rx control descriptor553 * @ah: The &struct ath5k_hw554 * @desc: The &struct ath5k_desc555 * @size: RX buffer length in bytes556 * @flags: One of AR5K_RXDESC_* flags557 */558int559ath5k_hw_setup_rx_desc(struct ath5k_hw *ah,560			struct ath5k_desc *desc,561			u32 size, unsigned int flags)562{563	struct ath5k_hw_rx_ctl *rx_ctl;564 565	rx_ctl = &desc->ud.ds_rx.rx_ctl;566 567	/*568	 * Clear the descriptor569	 * If we don't clean the status descriptor,570	 * while scanning we get too many results,571	 * most of them virtual, after some secs572	 * of scanning system hangs. M.F.573	*/574	memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));575 576	if (unlikely(size & ~AR5K_DESC_RX_CTL1_BUF_LEN))577		return -EINVAL;578 579	/* Setup descriptor */580	rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;581 582	if (flags & AR5K_RXDESC_INTREQ)583		rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;584 585	return 0;586}587 588/**589 * ath5k_hw_proc_5210_rx_status() - Process the rx status descriptor on 5210/1590 * @ah: The &struct ath5k_hw591 * @desc: The &struct ath5k_desc592 * @rs: The &struct ath5k_rx_status593 *594 * Internal function used to process an RX status descriptor595 * on AR5210/5211 MAC.596 *597 * Returns 0 on success or -EINPROGRESS in case we haven't received the who;e598 * frame yet.599 */600static int601ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,602				struct ath5k_desc *desc,603				struct ath5k_rx_status *rs)604{605	struct ath5k_hw_rx_status *rx_status;606 607	rx_status = &desc->ud.ds_rx.rx_stat;608 609	/* No frame received / not ready */610	if (unlikely(!(rx_status->rx_status_1 &611			AR5K_5210_RX_DESC_STATUS1_DONE)))612		return -EINPROGRESS;613 614	memset(rs, 0, sizeof(struct ath5k_rx_status));615 616	/*617	 * Frame receive status618	 */619	rs->rs_datalen = rx_status->rx_status_0 &620		AR5K_5210_RX_DESC_STATUS0_DATA_LEN;621	rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,622		AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);623	rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,624		AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);625	rs->rs_more = !!(rx_status->rx_status_0 &626		AR5K_5210_RX_DESC_STATUS0_MORE);627	/* TODO: this timestamp is 13 bit, later on we assume 15 bit!628	 * also the HAL code for 5210 says the timestamp is bits [10..22] of the629	 * TSF, and extends the timestamp here to 15 bit.630	 * we need to check on 5210...631	 */632	rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,633		AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);634 635	if (ah->ah_version == AR5K_AR5211)636		rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,637				AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5211);638	else639		rs->rs_antenna = (rx_status->rx_status_0 &640				AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANT_5210)641				? 2 : 1;642 643	/*644	 * Key table status645	 */646	if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID)647		rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,648			AR5K_5210_RX_DESC_STATUS1_KEY_INDEX);649	else650		rs->rs_keyix = AR5K_RXKEYIX_INVALID;651 652	/*653	 * Receive/descriptor errors654	 */655	if (!(rx_status->rx_status_1 &656			AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {657		if (rx_status->rx_status_1 &658				AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)659			rs->rs_status |= AR5K_RXERR_CRC;660 661		/* only on 5210 */662		if ((ah->ah_version == AR5K_AR5210) &&663		    (rx_status->rx_status_1 &664				AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN_5210))665			rs->rs_status |= AR5K_RXERR_FIFO;666 667		if (rx_status->rx_status_1 &668				AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {669			rs->rs_status |= AR5K_RXERR_PHY;670			rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1,671				AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);672		}673 674		if (rx_status->rx_status_1 &675				AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)676			rs->rs_status |= AR5K_RXERR_DECRYPT;677	}678 679	return 0;680}681 682/**683 * ath5k_hw_proc_5212_rx_status() - Process the rx status descriptor on 5212684 * @ah: The &struct ath5k_hw685 * @desc: The &struct ath5k_desc686 * @rs: The &struct ath5k_rx_status687 *688 * Internal function used to process an RX status descriptor689 * on AR5212 and later MAC.690 *691 * Returns 0 on success or -EINPROGRESS in case we haven't received the who;e692 * frame yet.693 */694static int695ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,696				struct ath5k_desc *desc,697				struct ath5k_rx_status *rs)698{699	struct ath5k_hw_rx_status *rx_status;700	u32 rxstat0, rxstat1;701 702	rx_status = &desc->ud.ds_rx.rx_stat;703	rxstat1 = READ_ONCE(rx_status->rx_status_1);704 705	/* No frame received / not ready */706	if (unlikely(!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_DONE)))707		return -EINPROGRESS;708 709	memset(rs, 0, sizeof(struct ath5k_rx_status));710	rxstat0 = READ_ONCE(rx_status->rx_status_0);711 712	/*713	 * Frame receive status714	 */715	rs->rs_datalen = rxstat0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN;716	rs->rs_rssi = AR5K_REG_MS(rxstat0,717		AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);718	rs->rs_rate = AR5K_REG_MS(rxstat0,719		AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);720	rs->rs_antenna = AR5K_REG_MS(rxstat0,721		AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA);722	rs->rs_more = !!(rxstat0 & AR5K_5212_RX_DESC_STATUS0_MORE);723	rs->rs_tstamp = AR5K_REG_MS(rxstat1,724		AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);725 726	/*727	 * Key table status728	 */729	if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)730		rs->rs_keyix = AR5K_REG_MS(rxstat1,731					   AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);732	else733		rs->rs_keyix = AR5K_RXKEYIX_INVALID;734 735	/*736	 * Receive/descriptor errors737	 */738	if (!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {739		if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)740			rs->rs_status |= AR5K_RXERR_CRC;741 742		if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {743			rs->rs_status |= AR5K_RXERR_PHY;744			rs->rs_phyerr = AR5K_REG_MS(rxstat1,745				AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE);746			if (!ah->ah_capabilities.cap_has_phyerr_counters)747				ath5k_ani_phy_error_report(ah, rs->rs_phyerr);748		}749 750		if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)751			rs->rs_status |= AR5K_RXERR_DECRYPT;752 753		if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)754			rs->rs_status |= AR5K_RXERR_MIC;755	}756	return 0;757}758 759 760/********\761* Attach *762\********/763 764/**765 * ath5k_hw_init_desc_functions() - Init function pointers inside ah766 * @ah: The &struct ath5k_hw767 *768 * Maps the internal descriptor functions to the function pointers on ah, used769 * from above. This is used as an abstraction layer to handle the various chips770 * the same way.771 */772int773ath5k_hw_init_desc_functions(struct ath5k_hw *ah)774{775	if (ah->ah_version == AR5K_AR5212) {776		ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;777		ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;778		ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;779	} else if (ah->ah_version <= AR5K_AR5211) {780		ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;781		ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;782		ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;783	} else784		return -ENOTSUPP;785	return 0;786}787