xref: /openbmc/linux/drivers/net/wireless/ath/ath9k/ar9003_mac.c (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
1ae3bb6d4SVasanthakumar Thiagarajan /*
25b68138eSSujith Manoharan  * Copyright (c) 2010-2011 Atheros Communications Inc.
3ae3bb6d4SVasanthakumar Thiagarajan  *
4ae3bb6d4SVasanthakumar Thiagarajan  * Permission to use, copy, modify, and/or distribute this software for any
5ae3bb6d4SVasanthakumar Thiagarajan  * purpose with or without fee is hereby granted, provided that the above
6ae3bb6d4SVasanthakumar Thiagarajan  * copyright notice and this permission notice appear in all copies.
7ae3bb6d4SVasanthakumar Thiagarajan  *
8ae3bb6d4SVasanthakumar Thiagarajan  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9ae3bb6d4SVasanthakumar Thiagarajan  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10ae3bb6d4SVasanthakumar Thiagarajan  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11ae3bb6d4SVasanthakumar Thiagarajan  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12ae3bb6d4SVasanthakumar Thiagarajan  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13ae3bb6d4SVasanthakumar Thiagarajan  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14ae3bb6d4SVasanthakumar Thiagarajan  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15ae3bb6d4SVasanthakumar Thiagarajan  */
16ee40fa06SPaul Gortmaker #include <linux/export.h>
17ae3bb6d4SVasanthakumar Thiagarajan #include "hw.h"
18b622a720SLuis R. Rodriguez #include "ar9003_mac.h"
19f4701b5aSSujith Manoharan #include "ar9003_mci.h"
20ae3bb6d4SVasanthakumar Thiagarajan 
ar9003_hw_rx_enable(struct ath_hw * hw)21ae3bb6d4SVasanthakumar Thiagarajan static void ar9003_hw_rx_enable(struct ath_hw *hw)
22ae3bb6d4SVasanthakumar Thiagarajan {
23ae3bb6d4SVasanthakumar Thiagarajan 	REG_WRITE(hw, AR_CR, 0);
24ae3bb6d4SVasanthakumar Thiagarajan }
25ae3bb6d4SVasanthakumar Thiagarajan 
262b63a41dSFelix Fietkau static void
ar9003_set_txdesc(struct ath_hw * ah,void * ds,struct ath_tx_info * i)272b63a41dSFelix Fietkau ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
282b63a41dSFelix Fietkau {
292b63a41dSFelix Fietkau 	struct ar9003_txc *ads = ds;
302b63a41dSFelix Fietkau 	int checksum = 0;
312b63a41dSFelix Fietkau 	u32 val, ctl12, ctl17;
329da27232SSujith Manoharan 	u8 desc_len;
339da27232SSujith Manoharan 
34a4a2954fSSujith Manoharan 	desc_len = ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x18 : 0x17);
352b63a41dSFelix Fietkau 
362b63a41dSFelix Fietkau 	val = (ATHEROS_VENDOR_ID << AR_DescId_S) |
372b63a41dSFelix Fietkau 	      (1 << AR_TxRxDesc_S) |
382b63a41dSFelix Fietkau 	      (1 << AR_CtrlStat_S) |
399da27232SSujith Manoharan 	      (i->qcu << AR_TxQcuNum_S) | desc_len;
402b63a41dSFelix Fietkau 
412b63a41dSFelix Fietkau 	checksum += val;
4250f38181SMark Rutland 	WRITE_ONCE(ads->info, val);
432b63a41dSFelix Fietkau 
442b63a41dSFelix Fietkau 	checksum += i->link;
4550f38181SMark Rutland 	WRITE_ONCE(ads->link, i->link);
462b63a41dSFelix Fietkau 
472b63a41dSFelix Fietkau 	checksum += i->buf_addr[0];
4850f38181SMark Rutland 	WRITE_ONCE(ads->data0, i->buf_addr[0]);
492b63a41dSFelix Fietkau 	checksum += i->buf_addr[1];
5050f38181SMark Rutland 	WRITE_ONCE(ads->data1, i->buf_addr[1]);
512b63a41dSFelix Fietkau 	checksum += i->buf_addr[2];
5250f38181SMark Rutland 	WRITE_ONCE(ads->data2, i->buf_addr[2]);
532b63a41dSFelix Fietkau 	checksum += i->buf_addr[3];
5450f38181SMark Rutland 	WRITE_ONCE(ads->data3, i->buf_addr[3]);
552b63a41dSFelix Fietkau 
562b63a41dSFelix Fietkau 	checksum += (val = (i->buf_len[0] << AR_BufLen_S) & AR_BufLen);
5750f38181SMark Rutland 	WRITE_ONCE(ads->ctl3, val);
582b63a41dSFelix Fietkau 	checksum += (val = (i->buf_len[1] << AR_BufLen_S) & AR_BufLen);
5950f38181SMark Rutland 	WRITE_ONCE(ads->ctl5, val);
602b63a41dSFelix Fietkau 	checksum += (val = (i->buf_len[2] << AR_BufLen_S) & AR_BufLen);
6150f38181SMark Rutland 	WRITE_ONCE(ads->ctl7, val);
622b63a41dSFelix Fietkau 	checksum += (val = (i->buf_len[3] << AR_BufLen_S) & AR_BufLen);
6350f38181SMark Rutland 	WRITE_ONCE(ads->ctl9, val);
642b63a41dSFelix Fietkau 
652b63a41dSFelix Fietkau 	checksum = (u16) (((checksum & 0xffff) + (checksum >> 16)) & 0xffff);
6650f38181SMark Rutland 	WRITE_ONCE(ads->ctl10, checksum);
672b63a41dSFelix Fietkau 
682b63a41dSFelix Fietkau 	if (i->is_first || i->is_last) {
6950f38181SMark Rutland 		WRITE_ONCE(ads->ctl13, set11nTries(i->rates, 0)
702b63a41dSFelix Fietkau 			| set11nTries(i->rates, 1)
712b63a41dSFelix Fietkau 			| set11nTries(i->rates, 2)
722b63a41dSFelix Fietkau 			| set11nTries(i->rates, 3)
732b63a41dSFelix Fietkau 			| (i->dur_update ? AR_DurUpdateEna : 0)
7450f38181SMark Rutland 			| SM(0, AR_BurstDur));
752b63a41dSFelix Fietkau 
7650f38181SMark Rutland 		WRITE_ONCE(ads->ctl14, set11nRate(i->rates, 0)
772b63a41dSFelix Fietkau 			| set11nRate(i->rates, 1)
782b63a41dSFelix Fietkau 			| set11nRate(i->rates, 2)
7950f38181SMark Rutland 			| set11nRate(i->rates, 3));
802b63a41dSFelix Fietkau 	} else {
8150f38181SMark Rutland 		WRITE_ONCE(ads->ctl13, 0);
8250f38181SMark Rutland 		WRITE_ONCE(ads->ctl14, 0);
832b63a41dSFelix Fietkau 	}
842b63a41dSFelix Fietkau 
852b63a41dSFelix Fietkau 	ads->ctl20 = 0;
862b63a41dSFelix Fietkau 	ads->ctl21 = 0;
872b63a41dSFelix Fietkau 	ads->ctl22 = 0;
889da27232SSujith Manoharan 	ads->ctl23 = 0;
892b63a41dSFelix Fietkau 
902b63a41dSFelix Fietkau 	ctl17 = SM(i->keytype, AR_EncrType);
912b63a41dSFelix Fietkau 	if (!i->is_first) {
9250f38181SMark Rutland 		WRITE_ONCE(ads->ctl11, 0);
9350f38181SMark Rutland 		WRITE_ONCE(ads->ctl12, i->is_last ? 0 : AR_TxMore);
9450f38181SMark Rutland 		WRITE_ONCE(ads->ctl15, 0);
9550f38181SMark Rutland 		WRITE_ONCE(ads->ctl16, 0);
9650f38181SMark Rutland 		WRITE_ONCE(ads->ctl17, ctl17);
9750f38181SMark Rutland 		WRITE_ONCE(ads->ctl18, 0);
9850f38181SMark Rutland 		WRITE_ONCE(ads->ctl19, 0);
992b63a41dSFelix Fietkau 		return;
1002b63a41dSFelix Fietkau 	}
1012b63a41dSFelix Fietkau 
10250f38181SMark Rutland 	WRITE_ONCE(ads->ctl11, (i->pkt_len & AR_FrameLen)
1032b63a41dSFelix Fietkau 		| (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
1048b537686SLorenzo Bianconi 		| SM(i->txpower[0], AR_XmitPower0)
1052b63a41dSFelix Fietkau 		| (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
1062b63a41dSFelix Fietkau 		| (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
1072b63a41dSFelix Fietkau 		| (i->flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0)
1082b63a41dSFelix Fietkau 		| (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
1092b63a41dSFelix Fietkau 		| (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable :
11050f38181SMark Rutland 		   (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0)));
1112b63a41dSFelix Fietkau 
1122b63a41dSFelix Fietkau 	ctl12 = (i->keyix != ATH9K_TXKEYIX_INVALID ?
1132b63a41dSFelix Fietkau 		 SM(i->keyix, AR_DestIdx) : 0)
1142b63a41dSFelix Fietkau 		| SM(i->type, AR_FrameType)
1152b63a41dSFelix Fietkau 		| (i->flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
1162b63a41dSFelix Fietkau 		| (i->flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
1172b63a41dSFelix Fietkau 		| (i->flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
1182b63a41dSFelix Fietkau 
1192b63a41dSFelix Fietkau 	ctl17 |= (i->flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0);
1202b63a41dSFelix Fietkau 	switch (i->aggr) {
1212b63a41dSFelix Fietkau 	case AGGR_BUF_FIRST:
1222b63a41dSFelix Fietkau 		ctl17 |= SM(i->aggr_len, AR_AggrLen);
123221af813SGustavo A. R. Silva 		fallthrough;
1242b63a41dSFelix Fietkau 	case AGGR_BUF_MIDDLE:
1252b63a41dSFelix Fietkau 		ctl12 |= AR_IsAggr | AR_MoreAggr;
1262b63a41dSFelix Fietkau 		ctl17 |= SM(i->ndelim, AR_PadDelim);
1272b63a41dSFelix Fietkau 		break;
1282b63a41dSFelix Fietkau 	case AGGR_BUF_LAST:
1292b63a41dSFelix Fietkau 		ctl12 |= AR_IsAggr;
1302b63a41dSFelix Fietkau 		break;
1312b63a41dSFelix Fietkau 	case AGGR_BUF_NONE:
1322b63a41dSFelix Fietkau 		break;
1332b63a41dSFelix Fietkau 	}
1342b63a41dSFelix Fietkau 
1352b63a41dSFelix Fietkau 	val = (i->flags & ATH9K_TXDESC_PAPRD) >> ATH9K_TXDESC_PAPRD_S;
1362b63a41dSFelix Fietkau 	ctl12 |= SM(val, AR_PAPRDChainMask);
1372b63a41dSFelix Fietkau 
13850f38181SMark Rutland 	WRITE_ONCE(ads->ctl12, ctl12);
13950f38181SMark Rutland 	WRITE_ONCE(ads->ctl17, ctl17);
1402b63a41dSFelix Fietkau 
14150f38181SMark Rutland 	WRITE_ONCE(ads->ctl15, set11nPktDurRTSCTS(i->rates, 0)
14250f38181SMark Rutland 		| set11nPktDurRTSCTS(i->rates, 1));
1432b63a41dSFelix Fietkau 
14450f38181SMark Rutland 	WRITE_ONCE(ads->ctl16, set11nPktDurRTSCTS(i->rates, 2)
14550f38181SMark Rutland 		| set11nPktDurRTSCTS(i->rates, 3));
1462b63a41dSFelix Fietkau 
147a96474a7SWenli Looi 	WRITE_ONCE(ads->ctl18,
148a96474a7SWenli Looi 		  set11nRateFlags(i->rates, 0) | set11nChainSel(i->rates, 0)
149a96474a7SWenli Looi 		| set11nRateFlags(i->rates, 1) | set11nChainSel(i->rates, 1)
150a96474a7SWenli Looi 		| set11nRateFlags(i->rates, 2) | set11nChainSel(i->rates, 2)
151a96474a7SWenli Looi 		| set11nRateFlags(i->rates, 3) | set11nChainSel(i->rates, 3)
15250f38181SMark Rutland 		| SM(i->rtscts_rate, AR_RTSCTSRate));
1532b63a41dSFelix Fietkau 
15450f38181SMark Rutland 	WRITE_ONCE(ads->ctl19, AR_Not_Sounding);
1553ae351abSLorenzo Bianconi 
15650f38181SMark Rutland 	WRITE_ONCE(ads->ctl20, SM(i->txpower[1], AR_XmitPower1));
15750f38181SMark Rutland 	WRITE_ONCE(ads->ctl21, SM(i->txpower[2], AR_XmitPower2));
15850f38181SMark Rutland 	WRITE_ONCE(ads->ctl22, SM(i->txpower[3], AR_XmitPower3));
1592b63a41dSFelix Fietkau }
1602b63a41dSFelix Fietkau 
ar9003_calc_ptr_chksum(struct ar9003_txc * ads)161eb823253SVasanthakumar Thiagarajan static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
162eb823253SVasanthakumar Thiagarajan {
163eb823253SVasanthakumar Thiagarajan 	int checksum;
164eb823253SVasanthakumar Thiagarajan 
165eb823253SVasanthakumar Thiagarajan 	checksum = ads->info + ads->link
166eb823253SVasanthakumar Thiagarajan 		+ ads->data0 + ads->ctl3
167eb823253SVasanthakumar Thiagarajan 		+ ads->data1 + ads->ctl5
168eb823253SVasanthakumar Thiagarajan 		+ ads->data2 + ads->ctl7
169eb823253SVasanthakumar Thiagarajan 		+ ads->data3 + ads->ctl9;
170eb823253SVasanthakumar Thiagarajan 
171eb823253SVasanthakumar Thiagarajan 	return ((checksum & 0xffff) + (checksum >> 16)) & AR_TxPtrChkSum;
172eb823253SVasanthakumar Thiagarajan }
173eb823253SVasanthakumar Thiagarajan 
ar9003_hw_set_desc_link(void * ds,u32 ds_link)17487d5efbbSVasanthakumar Thiagarajan static void ar9003_hw_set_desc_link(void *ds, u32 ds_link)
17587d5efbbSVasanthakumar Thiagarajan {
176eb823253SVasanthakumar Thiagarajan 	struct ar9003_txc *ads = ds;
177eb823253SVasanthakumar Thiagarajan 
178eb823253SVasanthakumar Thiagarajan 	ads->link = ds_link;
179eb823253SVasanthakumar Thiagarajan 	ads->ctl10 &= ~AR_TxPtrChkSum;
180eb823253SVasanthakumar Thiagarajan 	ads->ctl10 |= ar9003_calc_ptr_chksum(ads);
18187d5efbbSVasanthakumar Thiagarajan }
18287d5efbbSVasanthakumar Thiagarajan 
ar9003_hw_get_isr(struct ath_hw * ah,enum ath9k_int * masked,u32 * sync_cause_p)1836a4d05dcSFelix Fietkau static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked,
1846a4d05dcSFelix Fietkau 			      u32 *sync_cause_p)
18555e82df4SVasanthakumar Thiagarajan {
1866c84ce08SVasanthakumar Thiagarajan 	u32 isr = 0;
1876c84ce08SVasanthakumar Thiagarajan 	u32 mask2 = 0;
1886c84ce08SVasanthakumar Thiagarajan 	struct ath9k_hw_capabilities *pCap = &ah->caps;
1896c84ce08SVasanthakumar Thiagarajan 	struct ath_common *common = ath9k_hw_common(ah);
19092a33298SRajkumar Manoharan 	u32 sync_cause = 0, async_cause, async_mask = AR_INTR_MAC_IRQ;
191ff9bd2d8SSven Eckelmann 	bool fatal_int;
19292a33298SRajkumar Manoharan 
19392a33298SRajkumar Manoharan 	if (ath9k_hw_mci_is_enabled(ah))
19492a33298SRajkumar Manoharan 		async_mask |= AR_INTR_ASYNC_MASK_MCI;
1956c84ce08SVasanthakumar Thiagarajan 
196*b3a663f0SWenli Looi 	async_cause = REG_READ(ah, AR_INTR_ASYNC_CAUSE(ah));
1974421d30fSMohammed Shafi Shajakhan 
19892a33298SRajkumar Manoharan 	if (async_cause & async_mask) {
199*b3a663f0SWenli Looi 		if ((REG_READ(ah, AR_RTC_STATUS(ah)) & AR_RTC_STATUS_M(ah))
2006c84ce08SVasanthakumar Thiagarajan 				== AR_RTC_STATUS_ON)
2016c84ce08SVasanthakumar Thiagarajan 			isr = REG_READ(ah, AR_ISR);
2026c84ce08SVasanthakumar Thiagarajan 	}
2036c84ce08SVasanthakumar Thiagarajan 
2044421d30fSMohammed Shafi Shajakhan 
205*b3a663f0SWenli Looi 	sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE(ah)) & AR_INTR_SYNC_DEFAULT;
2066c84ce08SVasanthakumar Thiagarajan 
2076c84ce08SVasanthakumar Thiagarajan 	*masked = 0;
2086c84ce08SVasanthakumar Thiagarajan 
20993fdd594SMohammed Shafi Shajakhan 	if (!isr && !sync_cause && !async_cause)
2106c84ce08SVasanthakumar Thiagarajan 		return false;
2116c84ce08SVasanthakumar Thiagarajan 
2126c84ce08SVasanthakumar Thiagarajan 	if (isr) {
2136c84ce08SVasanthakumar Thiagarajan 		if (isr & AR_ISR_BCNMISC) {
2146c84ce08SVasanthakumar Thiagarajan 			u32 isr2;
2156c84ce08SVasanthakumar Thiagarajan 			isr2 = REG_READ(ah, AR_ISR_S2);
2166c84ce08SVasanthakumar Thiagarajan 
2176c84ce08SVasanthakumar Thiagarajan 			mask2 |= ((isr2 & AR_ISR_S2_TIM) >>
2186c84ce08SVasanthakumar Thiagarajan 				  MAP_ISR_S2_TIM);
2196c84ce08SVasanthakumar Thiagarajan 			mask2 |= ((isr2 & AR_ISR_S2_DTIM) >>
2206c84ce08SVasanthakumar Thiagarajan 				  MAP_ISR_S2_DTIM);
2216c84ce08SVasanthakumar Thiagarajan 			mask2 |= ((isr2 & AR_ISR_S2_DTIMSYNC) >>
2226c84ce08SVasanthakumar Thiagarajan 				  MAP_ISR_S2_DTIMSYNC);
2236c84ce08SVasanthakumar Thiagarajan 			mask2 |= ((isr2 & AR_ISR_S2_CABEND) >>
2246c84ce08SVasanthakumar Thiagarajan 				  MAP_ISR_S2_CABEND);
2256c84ce08SVasanthakumar Thiagarajan 			mask2 |= ((isr2 & AR_ISR_S2_GTT) <<
2266c84ce08SVasanthakumar Thiagarajan 				  MAP_ISR_S2_GTT);
2276c84ce08SVasanthakumar Thiagarajan 			mask2 |= ((isr2 & AR_ISR_S2_CST) <<
2286c84ce08SVasanthakumar Thiagarajan 				  MAP_ISR_S2_CST);
2296c84ce08SVasanthakumar Thiagarajan 			mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >>
2306c84ce08SVasanthakumar Thiagarajan 				  MAP_ISR_S2_TSFOOR);
231aea702b7SLuis R. Rodriguez 			mask2 |= ((isr2 & AR_ISR_S2_BB_WATCHDOG) >>
232aea702b7SLuis R. Rodriguez 				  MAP_ISR_S2_BB_WATCHDOG);
2336c84ce08SVasanthakumar Thiagarajan 
2346c84ce08SVasanthakumar Thiagarajan 			if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
2356c84ce08SVasanthakumar Thiagarajan 				REG_WRITE(ah, AR_ISR_S2, isr2);
2366c84ce08SVasanthakumar Thiagarajan 				isr &= ~AR_ISR_BCNMISC;
2376c84ce08SVasanthakumar Thiagarajan 			}
2386c84ce08SVasanthakumar Thiagarajan 		}
2396c84ce08SVasanthakumar Thiagarajan 
2406c84ce08SVasanthakumar Thiagarajan 		if ((pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED))
2416c84ce08SVasanthakumar Thiagarajan 			isr = REG_READ(ah, AR_ISR_RAC);
2426c84ce08SVasanthakumar Thiagarajan 
2436c84ce08SVasanthakumar Thiagarajan 		if (isr == 0xffffffff) {
2446c84ce08SVasanthakumar Thiagarajan 			*masked = 0;
2456c84ce08SVasanthakumar Thiagarajan 			return false;
2466c84ce08SVasanthakumar Thiagarajan 		}
2476c84ce08SVasanthakumar Thiagarajan 
2486c84ce08SVasanthakumar Thiagarajan 		*masked = isr & ATH9K_INT_COMMON;
2496c84ce08SVasanthakumar Thiagarajan 
2506c84ce08SVasanthakumar Thiagarajan 		if (ah->config.rx_intr_mitigation)
2516c84ce08SVasanthakumar Thiagarajan 			if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
2526c84ce08SVasanthakumar Thiagarajan 				*masked |= ATH9K_INT_RXLP;
2536c84ce08SVasanthakumar Thiagarajan 
2546c84ce08SVasanthakumar Thiagarajan 		if (ah->config.tx_intr_mitigation)
2556c84ce08SVasanthakumar Thiagarajan 			if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
2566c84ce08SVasanthakumar Thiagarajan 				*masked |= ATH9K_INT_TX;
2576c84ce08SVasanthakumar Thiagarajan 
2586c84ce08SVasanthakumar Thiagarajan 		if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR))
2596c84ce08SVasanthakumar Thiagarajan 			*masked |= ATH9K_INT_RXLP;
2606c84ce08SVasanthakumar Thiagarajan 
2616c84ce08SVasanthakumar Thiagarajan 		if (isr & AR_ISR_HP_RXOK)
2626c84ce08SVasanthakumar Thiagarajan 			*masked |= ATH9K_INT_RXHP;
2636c84ce08SVasanthakumar Thiagarajan 
2646c84ce08SVasanthakumar Thiagarajan 		if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
2656c84ce08SVasanthakumar Thiagarajan 			*masked |= ATH9K_INT_TX;
2666c84ce08SVasanthakumar Thiagarajan 
2676c84ce08SVasanthakumar Thiagarajan 			if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
2686c84ce08SVasanthakumar Thiagarajan 				u32 s0, s1;
2696c84ce08SVasanthakumar Thiagarajan 				s0 = REG_READ(ah, AR_ISR_S0);
2706c84ce08SVasanthakumar Thiagarajan 				REG_WRITE(ah, AR_ISR_S0, s0);
2716c84ce08SVasanthakumar Thiagarajan 				s1 = REG_READ(ah, AR_ISR_S1);
2726c84ce08SVasanthakumar Thiagarajan 				REG_WRITE(ah, AR_ISR_S1, s1);
2736c84ce08SVasanthakumar Thiagarajan 
2746c84ce08SVasanthakumar Thiagarajan 				isr &= ~(AR_ISR_TXOK | AR_ISR_TXERR |
2756c84ce08SVasanthakumar Thiagarajan 					 AR_ISR_TXEOL);
2766c84ce08SVasanthakumar Thiagarajan 			}
2776c84ce08SVasanthakumar Thiagarajan 		}
2786c84ce08SVasanthakumar Thiagarajan 
2796c84ce08SVasanthakumar Thiagarajan 		if (isr & AR_ISR_GENTMR) {
2806c84ce08SVasanthakumar Thiagarajan 			u32 s5;
2816c84ce08SVasanthakumar Thiagarajan 
2826c84ce08SVasanthakumar Thiagarajan 			if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)
283*b3a663f0SWenli Looi 				s5 = REG_READ(ah, AR_ISR_S5_S(ah));
2846c84ce08SVasanthakumar Thiagarajan 			else
2856c84ce08SVasanthakumar Thiagarajan 				s5 = REG_READ(ah, AR_ISR_S5);
2866c84ce08SVasanthakumar Thiagarajan 
2876c84ce08SVasanthakumar Thiagarajan 			ah->intr_gen_timer_trigger =
2886c84ce08SVasanthakumar Thiagarajan 				MS(s5, AR_ISR_S5_GENTIMER_TRIG);
2896c84ce08SVasanthakumar Thiagarajan 
2906c84ce08SVasanthakumar Thiagarajan 			ah->intr_gen_timer_thresh =
2916c84ce08SVasanthakumar Thiagarajan 				MS(s5, AR_ISR_S5_GENTIMER_THRESH);
2926c84ce08SVasanthakumar Thiagarajan 
2936c84ce08SVasanthakumar Thiagarajan 			if (ah->intr_gen_timer_trigger)
2946c84ce08SVasanthakumar Thiagarajan 				*masked |= ATH9K_INT_GENTIMER;
2956c84ce08SVasanthakumar Thiagarajan 
2966c84ce08SVasanthakumar Thiagarajan 			if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
2976c84ce08SVasanthakumar Thiagarajan 				REG_WRITE(ah, AR_ISR_S5, s5);
2986c84ce08SVasanthakumar Thiagarajan 				isr &= ~AR_ISR_GENTMR;
2996c84ce08SVasanthakumar Thiagarajan 			}
3006c84ce08SVasanthakumar Thiagarajan 
3016c84ce08SVasanthakumar Thiagarajan 		}
3026c84ce08SVasanthakumar Thiagarajan 
3036c84ce08SVasanthakumar Thiagarajan 		*masked |= mask2;
3046c84ce08SVasanthakumar Thiagarajan 
3056c84ce08SVasanthakumar Thiagarajan 		if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
3066c84ce08SVasanthakumar Thiagarajan 			REG_WRITE(ah, AR_ISR, isr);
3076c84ce08SVasanthakumar Thiagarajan 
3086c84ce08SVasanthakumar Thiagarajan 			(void) REG_READ(ah, AR_ISR);
3096c84ce08SVasanthakumar Thiagarajan 		}
310aea702b7SLuis R. Rodriguez 
311aea702b7SLuis R. Rodriguez 		if (*masked & ATH9K_INT_BB_WATCHDOG)
312aea702b7SLuis R. Rodriguez 			ar9003_hw_bb_watchdog_read(ah);
3136c84ce08SVasanthakumar Thiagarajan 	}
3146c84ce08SVasanthakumar Thiagarajan 
3155a1e2735SSujith Manoharan 	if (async_cause & AR_INTR_ASYNC_MASK_MCI)
3165a1e2735SSujith Manoharan 		ar9003_mci_get_isr(ah, masked);
317cc78d6b1SMohammed Shafi Shajakhan 
3186c84ce08SVasanthakumar Thiagarajan 	if (sync_cause) {
3196a4d05dcSFelix Fietkau 		if (sync_cause_p)
3206a4d05dcSFelix Fietkau 			*sync_cause_p = sync_cause;
321ff9bd2d8SSven Eckelmann 		fatal_int =
322ff9bd2d8SSven Eckelmann 			(sync_cause &
323ff9bd2d8SSven Eckelmann 			 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
324ff9bd2d8SSven Eckelmann 			? true : false;
325ff9bd2d8SSven Eckelmann 
326ff9bd2d8SSven Eckelmann 		if (fatal_int) {
327ff9bd2d8SSven Eckelmann 			if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
328ff9bd2d8SSven Eckelmann 				ath_dbg(common, ANY,
329ff9bd2d8SSven Eckelmann 					"received PCI FATAL interrupt\n");
330ff9bd2d8SSven Eckelmann 			}
331ff9bd2d8SSven Eckelmann 			if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
332ff9bd2d8SSven Eckelmann 				ath_dbg(common, ANY,
333ff9bd2d8SSven Eckelmann 					"received PCI PERR interrupt\n");
334ff9bd2d8SSven Eckelmann 			}
335ff9bd2d8SSven Eckelmann 			*masked |= ATH9K_INT_FATAL;
336ff9bd2d8SSven Eckelmann 		}
337462e58f2SBen Greear 
3386c84ce08SVasanthakumar Thiagarajan 		if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
3396c84ce08SVasanthakumar Thiagarajan 			REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
3406c84ce08SVasanthakumar Thiagarajan 			REG_WRITE(ah, AR_RC, 0);
3416c84ce08SVasanthakumar Thiagarajan 			*masked |= ATH9K_INT_FATAL;
3426c84ce08SVasanthakumar Thiagarajan 		}
3436c84ce08SVasanthakumar Thiagarajan 
3446c84ce08SVasanthakumar Thiagarajan 		if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT)
345d2182b69SJoe Perches 			ath_dbg(common, INTERRUPT,
3466c84ce08SVasanthakumar Thiagarajan 				"AR_INTR_SYNC_LOCAL_TIMEOUT\n");
3476c84ce08SVasanthakumar Thiagarajan 
348*b3a663f0SWenli Looi 		REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR(ah), sync_cause);
349*b3a663f0SWenli Looi 		(void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR(ah));
3506c84ce08SVasanthakumar Thiagarajan 
3516c84ce08SVasanthakumar Thiagarajan 	}
35255e82df4SVasanthakumar Thiagarajan 	return true;
35355e82df4SVasanthakumar Thiagarajan }
35455e82df4SVasanthakumar Thiagarajan 
ar9003_hw_proc_txdesc(struct ath_hw * ah,void * ds,struct ath_tx_status * ts)355cc610ac0SVasanthakumar Thiagarajan static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
356cc610ac0SVasanthakumar Thiagarajan 				 struct ath_tx_status *ts)
357cc610ac0SVasanthakumar Thiagarajan {
358994089dbSVasanthakumar Thiagarajan 	struct ar9003_txs *ads;
359e0e9bc82SFelix Fietkau 	u32 status;
360994089dbSVasanthakumar Thiagarajan 
361994089dbSVasanthakumar Thiagarajan 	ads = &ah->ts_ring[ah->ts_tail];
362994089dbSVasanthakumar Thiagarajan 
36350f38181SMark Rutland 	status = READ_ONCE(ads->status8);
364e0e9bc82SFelix Fietkau 	if ((status & AR_TxDone) == 0)
365994089dbSVasanthakumar Thiagarajan 		return -EINPROGRESS;
366994089dbSVasanthakumar Thiagarajan 
367994089dbSVasanthakumar Thiagarajan 	ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
368994089dbSVasanthakumar Thiagarajan 
369994089dbSVasanthakumar Thiagarajan 	if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) ||
370994089dbSVasanthakumar Thiagarajan 	    (MS(ads->ds_info, AR_TxRxDesc) != 1)) {
371d2182b69SJoe Perches 		ath_dbg(ath9k_hw_common(ah), XMIT,
372994089dbSVasanthakumar Thiagarajan 			"Tx Descriptor error %x\n", ads->ds_info);
373994089dbSVasanthakumar Thiagarajan 		memset(ads, 0, sizeof(*ads));
374994089dbSVasanthakumar Thiagarajan 		return -EIO;
375994089dbSVasanthakumar Thiagarajan 	}
376994089dbSVasanthakumar Thiagarajan 
377e0e9bc82SFelix Fietkau 	ts->ts_rateindex = MS(status, AR_FinalTxIdx);
378e0e9bc82SFelix Fietkau 	ts->ts_seqnum = MS(status, AR_SeqNum);
379e0e9bc82SFelix Fietkau 	ts->tid = MS(status, AR_TxTid);
380e0e9bc82SFelix Fietkau 
381d6157bf7SFelix Fietkau 	ts->qid = MS(ads->ds_info, AR_TxQcuNum);
382994089dbSVasanthakumar Thiagarajan 	ts->desc_id = MS(ads->status1, AR_TxDescId);
383994089dbSVasanthakumar Thiagarajan 	ts->ts_tstamp = ads->status4;
384994089dbSVasanthakumar Thiagarajan 	ts->ts_status = 0;
385994089dbSVasanthakumar Thiagarajan 	ts->ts_flags  = 0;
386994089dbSVasanthakumar Thiagarajan 
3872a15b394SRajkumar Manoharan 	if (status & AR_TxOpExceeded)
3882a15b394SRajkumar Manoharan 		ts->ts_status |= ATH9K_TXERR_XTXOP;
38950f38181SMark Rutland 	status = READ_ONCE(ads->status2);
390e0e9bc82SFelix Fietkau 	ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
391e0e9bc82SFelix Fietkau 	ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
392e0e9bc82SFelix Fietkau 	ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
393e0e9bc82SFelix Fietkau 	if (status & AR_TxBaStatus) {
394994089dbSVasanthakumar Thiagarajan 		ts->ts_flags |= ATH9K_TX_BA;
395994089dbSVasanthakumar Thiagarajan 		ts->ba_low = ads->status5;
396994089dbSVasanthakumar Thiagarajan 		ts->ba_high = ads->status6;
397994089dbSVasanthakumar Thiagarajan 	}
398994089dbSVasanthakumar Thiagarajan 
39950f38181SMark Rutland 	status = READ_ONCE(ads->status3);
400e0e9bc82SFelix Fietkau 	if (status & AR_ExcessiveRetries)
401e0e9bc82SFelix Fietkau 		ts->ts_status |= ATH9K_TXERR_XRETRY;
402e0e9bc82SFelix Fietkau 	if (status & AR_Filtered)
403e0e9bc82SFelix Fietkau 		ts->ts_status |= ATH9K_TXERR_FILT;
404e0e9bc82SFelix Fietkau 	if (status & AR_FIFOUnderrun) {
405e0e9bc82SFelix Fietkau 		ts->ts_status |= ATH9K_TXERR_FIFO;
406e0e9bc82SFelix Fietkau 		ath9k_hw_updatetxtriglevel(ah, true);
407e0e9bc82SFelix Fietkau 	}
408e0e9bc82SFelix Fietkau 	if (status & AR_TxTimerExpired)
409e0e9bc82SFelix Fietkau 		ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
410e0e9bc82SFelix Fietkau 	if (status & AR_DescCfgErr)
411e0e9bc82SFelix Fietkau 		ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
412e0e9bc82SFelix Fietkau 	if (status & AR_TxDataUnderrun) {
413e0e9bc82SFelix Fietkau 		ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
414e0e9bc82SFelix Fietkau 		ath9k_hw_updatetxtriglevel(ah, true);
415e0e9bc82SFelix Fietkau 	}
416e0e9bc82SFelix Fietkau 	if (status & AR_TxDelimUnderrun) {
417e0e9bc82SFelix Fietkau 		ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
418e0e9bc82SFelix Fietkau 		ath9k_hw_updatetxtriglevel(ah, true);
419e0e9bc82SFelix Fietkau 	}
420e0e9bc82SFelix Fietkau 	ts->ts_shortretry = MS(status, AR_RTSFailCnt);
421e0e9bc82SFelix Fietkau 	ts->ts_longretry = MS(status, AR_DataFailCnt);
422e0e9bc82SFelix Fietkau 	ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
423994089dbSVasanthakumar Thiagarajan 
42450f38181SMark Rutland 	status = READ_ONCE(ads->status7);
425e0e9bc82SFelix Fietkau 	ts->ts_rssi = MS(status, AR_TxRSSICombined);
426e0e9bc82SFelix Fietkau 	ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
427e0e9bc82SFelix Fietkau 	ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
428e0e9bc82SFelix Fietkau 	ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12);
429994089dbSVasanthakumar Thiagarajan 
430994089dbSVasanthakumar Thiagarajan 	memset(ads, 0, sizeof(*ads));
431994089dbSVasanthakumar Thiagarajan 
432cc610ac0SVasanthakumar Thiagarajan 	return 0;
433cc610ac0SVasanthakumar Thiagarajan }
434994089dbSVasanthakumar Thiagarajan 
ar9003_hw_get_duration(struct ath_hw * ah,const void * ds,int index)435315dd114SFelix Fietkau static int ar9003_hw_get_duration(struct ath_hw *ah, const void *ds, int index)
436315dd114SFelix Fietkau {
437315dd114SFelix Fietkau 	const struct ar9003_txc *adc = ds;
438315dd114SFelix Fietkau 
439315dd114SFelix Fietkau 	switch (index) {
440315dd114SFelix Fietkau 	case 0:
44150f38181SMark Rutland 		return MS(READ_ONCE(adc->ctl15), AR_PacketDur0);
442315dd114SFelix Fietkau 	case 1:
44350f38181SMark Rutland 		return MS(READ_ONCE(adc->ctl15), AR_PacketDur1);
444315dd114SFelix Fietkau 	case 2:
44550f38181SMark Rutland 		return MS(READ_ONCE(adc->ctl16), AR_PacketDur2);
446315dd114SFelix Fietkau 	case 3:
44750f38181SMark Rutland 		return MS(READ_ONCE(adc->ctl16), AR_PacketDur3);
448315dd114SFelix Fietkau 	default:
449315dd114SFelix Fietkau 		return 0;
450315dd114SFelix Fietkau 	}
451315dd114SFelix Fietkau }
452315dd114SFelix Fietkau 
ar9003_hw_attach_mac_ops(struct ath_hw * hw)453ae3bb6d4SVasanthakumar Thiagarajan void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
454ae3bb6d4SVasanthakumar Thiagarajan {
455ae3bb6d4SVasanthakumar Thiagarajan 	struct ath_hw_ops *ops = ath9k_hw_ops(hw);
456ae3bb6d4SVasanthakumar Thiagarajan 
457ae3bb6d4SVasanthakumar Thiagarajan 	ops->rx_enable = ar9003_hw_rx_enable;
45887d5efbbSVasanthakumar Thiagarajan 	ops->set_desc_link = ar9003_hw_set_desc_link;
45955e82df4SVasanthakumar Thiagarajan 	ops->get_isr = ar9003_hw_get_isr;
4602b63a41dSFelix Fietkau 	ops->set_txdesc = ar9003_set_txdesc;
461cc610ac0SVasanthakumar Thiagarajan 	ops->proc_txdesc = ar9003_hw_proc_txdesc;
462315dd114SFelix Fietkau 	ops->get_duration = ar9003_hw_get_duration;
463ae3bb6d4SVasanthakumar Thiagarajan }
464ad7b8060SVasanthakumar Thiagarajan 
ath9k_hw_set_rx_bufsize(struct ath_hw * ah,u16 buf_size)465ad7b8060SVasanthakumar Thiagarajan void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
466ad7b8060SVasanthakumar Thiagarajan {
467ad7b8060SVasanthakumar Thiagarajan 	REG_WRITE(ah, AR_DATABUF_SIZE, buf_size & AR_DATABUF_SIZE_MASK);
468ad7b8060SVasanthakumar Thiagarajan }
469ad7b8060SVasanthakumar Thiagarajan EXPORT_SYMBOL(ath9k_hw_set_rx_bufsize);
470ad7b8060SVasanthakumar Thiagarajan 
ath9k_hw_addrxbuf_edma(struct ath_hw * ah,u32 rxdp,enum ath9k_rx_qtype qtype)471ad7b8060SVasanthakumar Thiagarajan void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp,
472ad7b8060SVasanthakumar Thiagarajan 			    enum ath9k_rx_qtype qtype)
473ad7b8060SVasanthakumar Thiagarajan {
474ad7b8060SVasanthakumar Thiagarajan 	if (qtype == ATH9K_RX_QUEUE_HP)
475ad7b8060SVasanthakumar Thiagarajan 		REG_WRITE(ah, AR_HP_RXDP, rxdp);
476ad7b8060SVasanthakumar Thiagarajan 	else
477ad7b8060SVasanthakumar Thiagarajan 		REG_WRITE(ah, AR_LP_RXDP, rxdp);
478ad7b8060SVasanthakumar Thiagarajan }
479ad7b8060SVasanthakumar Thiagarajan EXPORT_SYMBOL(ath9k_hw_addrxbuf_edma);
480ad7b8060SVasanthakumar Thiagarajan 
ath9k_hw_process_rxdesc_edma(struct ath_hw * ah,struct ath_rx_status * rxs,void * buf_addr)481ad7b8060SVasanthakumar Thiagarajan int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
482ad7b8060SVasanthakumar Thiagarajan 				 void *buf_addr)
483ad7b8060SVasanthakumar Thiagarajan {
48450c8cd44SHimanshu Jha 	struct ar9003_rxs *rxsp = buf_addr;
485ad7b8060SVasanthakumar Thiagarajan 	unsigned int phyerr;
486ad7b8060SVasanthakumar Thiagarajan 
487ad7b8060SVasanthakumar Thiagarajan 	if ((rxsp->status11 & AR_RxDone) == 0)
488ad7b8060SVasanthakumar Thiagarajan 		return -EINPROGRESS;
489ad7b8060SVasanthakumar Thiagarajan 
490ad7b8060SVasanthakumar Thiagarajan 	if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
491ad7b8060SVasanthakumar Thiagarajan 		return -EINVAL;
492ad7b8060SVasanthakumar Thiagarajan 
493ad7b8060SVasanthakumar Thiagarajan 	if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
494ad7b8060SVasanthakumar Thiagarajan 		return -EINPROGRESS;
495ad7b8060SVasanthakumar Thiagarajan 
496ad7b8060SVasanthakumar Thiagarajan 	rxs->rs_status = 0;
497ad7b8060SVasanthakumar Thiagarajan 	rxs->rs_flags =  0;
4987fdd69c5SJohannes Berg 	rxs->enc_flags = 0;
499da6a4352SJohannes Berg 	rxs->bw = RATE_INFO_BW_20;
500ad7b8060SVasanthakumar Thiagarajan 
501ad7b8060SVasanthakumar Thiagarajan 	rxs->rs_datalen = rxsp->status2 & AR_DataLen;
502ad7b8060SVasanthakumar Thiagarajan 	rxs->rs_tstamp =  rxsp->status3;
503ad7b8060SVasanthakumar Thiagarajan 
504ad7b8060SVasanthakumar Thiagarajan 	/* XXX: Keycache */
505ad7b8060SVasanthakumar Thiagarajan 	rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
506e45e91d8SFelix Fietkau 	rxs->rs_rssi_ctl[0] = MS(rxsp->status1, AR_RxRSSIAnt00);
507e45e91d8SFelix Fietkau 	rxs->rs_rssi_ctl[1] = MS(rxsp->status1, AR_RxRSSIAnt01);
508e45e91d8SFelix Fietkau 	rxs->rs_rssi_ctl[2] = MS(rxsp->status1, AR_RxRSSIAnt02);
509e45e91d8SFelix Fietkau 	rxs->rs_rssi_ext[0] = MS(rxsp->status5, AR_RxRSSIAnt10);
510e45e91d8SFelix Fietkau 	rxs->rs_rssi_ext[1] = MS(rxsp->status5, AR_RxRSSIAnt11);
511e45e91d8SFelix Fietkau 	rxs->rs_rssi_ext[2] = MS(rxsp->status5, AR_RxRSSIAnt12);
512ad7b8060SVasanthakumar Thiagarajan 
513ad7b8060SVasanthakumar Thiagarajan 	if (rxsp->status11 & AR_RxKeyIdxValid)
514ad7b8060SVasanthakumar Thiagarajan 		rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
515ad7b8060SVasanthakumar Thiagarajan 	else
516ad7b8060SVasanthakumar Thiagarajan 		rxs->rs_keyix = ATH9K_RXKEYIX_INVALID;
517ad7b8060SVasanthakumar Thiagarajan 
518ad7b8060SVasanthakumar Thiagarajan 	rxs->rs_rate = MS(rxsp->status1, AR_RxRate);
519ad7b8060SVasanthakumar Thiagarajan 	rxs->rs_more = (rxsp->status2 & AR_RxMore) ? 1 : 0;
520ad7b8060SVasanthakumar Thiagarajan 
521009af8fbSSujith Manoharan 	rxs->rs_firstaggr = (rxsp->status11 & AR_RxFirstAggr) ? 1 : 0;
522ad7b8060SVasanthakumar Thiagarajan 	rxs->rs_isaggr = (rxsp->status11 & AR_RxAggr) ? 1 : 0;
523ad7b8060SVasanthakumar Thiagarajan 	rxs->rs_moreaggr = (rxsp->status11 & AR_RxMoreAggr) ? 1 : 0;
524ad7b8060SVasanthakumar Thiagarajan 	rxs->rs_antenna = (MS(rxsp->status4, AR_RxAntenna) & 0x7);
5257fdd69c5SJohannes Berg 	rxs->enc_flags |= (rxsp->status4 & AR_GI) ? RX_ENC_FLAG_SHORT_GI : 0;
526238ebd8bSPhilipp Borgers 	rxs->enc_flags |=
527238ebd8bSPhilipp Borgers 		(rxsp->status4 & AR_STBC) ? (1 << RX_ENC_FLAG_STBC_SHIFT) : 0;
5282f242bf4SJohannes Berg 	rxs->bw = (rxsp->status4 & AR_2040) ? RATE_INFO_BW_40 : RATE_INFO_BW_20;
529ad7b8060SVasanthakumar Thiagarajan 
530ad7b8060SVasanthakumar Thiagarajan 	rxs->evm0 = rxsp->status6;
531ad7b8060SVasanthakumar Thiagarajan 	rxs->evm1 = rxsp->status7;
532ad7b8060SVasanthakumar Thiagarajan 	rxs->evm2 = rxsp->status8;
533ad7b8060SVasanthakumar Thiagarajan 	rxs->evm3 = rxsp->status9;
534ad7b8060SVasanthakumar Thiagarajan 	rxs->evm4 = (rxsp->status10 & 0xffff);
535ad7b8060SVasanthakumar Thiagarajan 
536ad7b8060SVasanthakumar Thiagarajan 	if (rxsp->status11 & AR_PreDelimCRCErr)
537ad7b8060SVasanthakumar Thiagarajan 		rxs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
538ad7b8060SVasanthakumar Thiagarajan 
539ad7b8060SVasanthakumar Thiagarajan 	if (rxsp->status11 & AR_PostDelimCRCErr)
540ad7b8060SVasanthakumar Thiagarajan 		rxs->rs_flags |= ATH9K_RX_DELIM_CRC_POST;
541ad7b8060SVasanthakumar Thiagarajan 
542ad7b8060SVasanthakumar Thiagarajan 	if (rxsp->status11 & AR_DecryptBusyErr)
543ad7b8060SVasanthakumar Thiagarajan 		rxs->rs_flags |= ATH9K_RX_DECRYPT_BUSY;
544ad7b8060SVasanthakumar Thiagarajan 
545ad7b8060SVasanthakumar Thiagarajan 	if ((rxsp->status11 & AR_RxFrameOK) == 0) {
5469171acc7SLuis R. Rodriguez 		/*
5479171acc7SLuis R. Rodriguez 		 * AR_CRCErr will bet set to true if we're on the last
5489171acc7SLuis R. Rodriguez 		 * subframe and the AR_PostDelimCRCErr is caught.
5499171acc7SLuis R. Rodriguez 		 * In a way this also gives us a guarantee that when
5509171acc7SLuis R. Rodriguez 		 * (!(AR_CRCErr) && (AR_PostDelimCRCErr)) we cannot
5519171acc7SLuis R. Rodriguez 		 * possibly be reviewing the last subframe. AR_CRCErr
5529171acc7SLuis R. Rodriguez 		 * is the CRC of the actual data.
5539171acc7SLuis R. Rodriguez 		 */
5541c30cc19SFelix Fietkau 		if (rxsp->status11 & AR_CRCErr)
555ad7b8060SVasanthakumar Thiagarajan 			rxs->rs_status |= ATH9K_RXERR_CRC;
556f4fb4b21SZefir Kurtisi 		else if (rxsp->status11 & AR_DecryptCRCErr)
557f4fb4b21SZefir Kurtisi 			rxs->rs_status |= ATH9K_RXERR_DECRYPT;
558f4fb4b21SZefir Kurtisi 		else if (rxsp->status11 & AR_MichaelErr)
559f4fb4b21SZefir Kurtisi 			rxs->rs_status |= ATH9K_RXERR_MIC;
560f4fb4b21SZefir Kurtisi 		if (rxsp->status11 & AR_PHYErr) {
561ad7b8060SVasanthakumar Thiagarajan 			phyerr = MS(rxsp->status11, AR_PHYErrCode);
5629171acc7SLuis R. Rodriguez 			/*
5639171acc7SLuis R. Rodriguez 			 * If we reach a point here where AR_PostDelimCRCErr is
5649171acc7SLuis R. Rodriguez 			 * true it implies we're *not* on the last subframe. In
5659171acc7SLuis R. Rodriguez 			 * in that case that we know already that the CRC of
5669171acc7SLuis R. Rodriguez 			 * the frame was OK, and MAC would send an ACK for that
5679171acc7SLuis R. Rodriguez 			 * subframe, even if we did get a phy error of type
5689171acc7SLuis R. Rodriguez 			 * ATH9K_PHYERR_OFDM_RESTART. This is only applicable
5699171acc7SLuis R. Rodriguez 			 * to frame that are prior to the last subframe.
5709171acc7SLuis R. Rodriguez 			 * The AR_PostDelimCRCErr is the CRC for the MPDU
5719171acc7SLuis R. Rodriguez 			 * delimiter, which contains the 4 reserved bits,
5729171acc7SLuis R. Rodriguez 			 * the MPDU length (12 bits), and follows the MPDU
5739171acc7SLuis R. Rodriguez 			 * delimiter for an A-MPDU subframe (0x4E = 'N' ASCII).
5749171acc7SLuis R. Rodriguez 			 */
5759171acc7SLuis R. Rodriguez 			if ((phyerr == ATH9K_PHYERR_OFDM_RESTART) &&
5769171acc7SLuis R. Rodriguez 			    (rxsp->status11 & AR_PostDelimCRCErr)) {
5779171acc7SLuis R. Rodriguez 				rxs->rs_phyerr = 0;
5789171acc7SLuis R. Rodriguez 			} else {
5799171acc7SLuis R. Rodriguez 				rxs->rs_status |= ATH9K_RXERR_PHY;
580ad7b8060SVasanthakumar Thiagarajan 				rxs->rs_phyerr = phyerr;
5819171acc7SLuis R. Rodriguez 			}
58228ab58bdSPeter Senna Tschudin 		}
5837a532fe7SFelix Fietkau 	}
5847a532fe7SFelix Fietkau 
585846d9363SFelix Fietkau 	if (rxsp->status11 & AR_KeyMiss)
586846d9363SFelix Fietkau 		rxs->rs_status |= ATH9K_RXERR_KEYMISS;
587ad7b8060SVasanthakumar Thiagarajan 
588ad7b8060SVasanthakumar Thiagarajan 	return 0;
589ad7b8060SVasanthakumar Thiagarajan }
590ad7b8060SVasanthakumar Thiagarajan EXPORT_SYMBOL(ath9k_hw_process_rxdesc_edma);
591744d4025SVasanthakumar Thiagarajan 
ath9k_hw_reset_txstatus_ring(struct ath_hw * ah)592744d4025SVasanthakumar Thiagarajan void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah)
593744d4025SVasanthakumar Thiagarajan {
594744d4025SVasanthakumar Thiagarajan 	ah->ts_tail = 0;
595744d4025SVasanthakumar Thiagarajan 
596744d4025SVasanthakumar Thiagarajan 	memset((void *) ah->ts_ring, 0,
597744d4025SVasanthakumar Thiagarajan 		ah->ts_size * sizeof(struct ar9003_txs));
598744d4025SVasanthakumar Thiagarajan 
599d2182b69SJoe Perches 	ath_dbg(ath9k_hw_common(ah), XMIT,
600744d4025SVasanthakumar Thiagarajan 		"TS Start 0x%x End 0x%x Virt %p, Size %d\n",
601744d4025SVasanthakumar Thiagarajan 		ah->ts_paddr_start, ah->ts_paddr_end,
602744d4025SVasanthakumar Thiagarajan 		ah->ts_ring, ah->ts_size);
603744d4025SVasanthakumar Thiagarajan 
604744d4025SVasanthakumar Thiagarajan 	REG_WRITE(ah, AR_Q_STATUS_RING_START, ah->ts_paddr_start);
605744d4025SVasanthakumar Thiagarajan 	REG_WRITE(ah, AR_Q_STATUS_RING_END, ah->ts_paddr_end);
606744d4025SVasanthakumar Thiagarajan }
607744d4025SVasanthakumar Thiagarajan 
ath9k_hw_setup_statusring(struct ath_hw * ah,void * ts_start,u32 ts_paddr_start,u16 size)608744d4025SVasanthakumar Thiagarajan void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start,
609744d4025SVasanthakumar Thiagarajan 			       u32 ts_paddr_start,
610016c2177SRajkumar Manoharan 			       u16 size)
611744d4025SVasanthakumar Thiagarajan {
612744d4025SVasanthakumar Thiagarajan 
613744d4025SVasanthakumar Thiagarajan 	ah->ts_paddr_start = ts_paddr_start;
614744d4025SVasanthakumar Thiagarajan 	ah->ts_paddr_end = ts_paddr_start + (size * sizeof(struct ar9003_txs));
615744d4025SVasanthakumar Thiagarajan 	ah->ts_size = size;
61650c8cd44SHimanshu Jha 	ah->ts_ring = ts_start;
617744d4025SVasanthakumar Thiagarajan 
618744d4025SVasanthakumar Thiagarajan 	ath9k_hw_reset_txstatus_ring(ah);
619744d4025SVasanthakumar Thiagarajan }
620744d4025SVasanthakumar Thiagarajan EXPORT_SYMBOL(ath9k_hw_setup_statusring);
621