aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-02-22 10:15:09 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2017-02-22 10:15:09 -0800
commit3051bf36c25d5153051704291782f8d44e744d36 (patch)
tree72dfc8a1d12675c6f2981d13102df954b678f11b /drivers/net/wireless/ath/ath9k
parentMerge tag 'gcc-plugins-v4.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux (diff)
parentRevert "ath10k: Search SMBIOS for OEM board file extension" (diff)
downloadlinux-dev-3051bf36c25d5153051704291782f8d44e744d36.tar.xz
linux-dev-3051bf36c25d5153051704291782f8d44e744d36.zip
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: "Highlights: 1) Support TX_RING in AF_PACKET TPACKET_V3 mode, from Sowmini Varadhan. 2) Simplify classifier state on sk_buff in order to shrink it a bit. From Willem de Bruijn. 3) Introduce SIPHASH and it's usage for secure sequence numbers and syncookies. From Jason A. Donenfeld. 4) Reduce CPU usage for ICMP replies we are going to limit or suppress, from Jesper Dangaard Brouer. 5) Introduce Shared Memory Communications socket layer, from Ursula Braun. 6) Add RACK loss detection and allow it to actually trigger fast recovery instead of just assisting after other algorithms have triggered it. From Yuchung Cheng. 7) Add xmit_more and BQL support to mvneta driver, from Simon Guinot. 8) skb_cow_data avoidance in esp4 and esp6, from Steffen Klassert. 9) Export MPLS packet stats via netlink, from Robert Shearman. 10) Significantly improve inet port bind conflict handling, especially when an application is restarted and changes it's setting of reuseport. From Josef Bacik. 11) Implement TX batching in vhost_net, from Jason Wang. 12) Extend the dummy device so that VF (virtual function) features, such as configuration, can be more easily tested. From Phil Sutter. 13) Avoid two atomic ops per page on x86 in bnx2x driver, from Eric Dumazet. 14) Add new bpf MAP, implementing a longest prefix match trie. From Daniel Mack. 15) Packet sample offloading support in mlxsw driver, from Yotam Gigi. 16) Add new aquantia driver, from David VomLehn. 17) Add bpf tracepoints, from Daniel Borkmann. 18) Add support for port mirroring to b53 and bcm_sf2 drivers, from Florian Fainelli. 19) Remove custom busy polling in many drivers, it is done in the core networking since 4.5 times. From Eric Dumazet. 20) Support XDP adjust_head in virtio_net, from John Fastabend. 21) Fix several major holes in neighbour entry confirmation, from Julian Anastasov. 22) Add XDP support to bnxt_en driver, from Michael Chan. 23) VXLAN offloads for enic driver, from Govindarajulu Varadarajan. 24) Add IPVTAP driver (IP-VLAN based tap driver) from Sainath Grandhi. 25) Support GRO in IPSEC protocols, from Steffen Klassert" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1764 commits) Revert "ath10k: Search SMBIOS for OEM board file extension" net: socket: fix recvmmsg not returning error from sock_error bnxt_en: use eth_hw_addr_random() bpf: fix unlocking of jited image when module ronx not set arch: add ARCH_HAS_SET_MEMORY config net: napi_watchdog() can use napi_schedule_irqoff() tcp: Revert "tcp: tcp_probe: use spin_lock_bh()" net/hsr: use eth_hw_addr_random() net: mvpp2: enable building on 64-bit platforms net: mvpp2: switch to build_skb() in the RX path net: mvpp2: simplify MVPP2_PRS_RI_* definitions net: mvpp2: fix indentation of MVPP2_EXT_GLOBAL_CTRL_DEFAULT net: mvpp2: remove unused register definitions net: mvpp2: simplify mvpp2_bm_bufs_add() net: mvpp2: drop useless fields in mvpp2_bm_pool and related code net: mvpp2: remove unused 'tx_skb' field of 'struct mvpp2_tx_queue' net: mvpp2: release reference to txq_cpu[] entry after unmapping net: mvpp2: handle too large value in mvpp2_rx_time_coal_set() net: mvpp2: handle too large value handling in mvpp2_rx_pkts_coal_set() net: mvpp2: remove useless arguments in mvpp2_rx_{pkts, time}_coal_set ...
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig9
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile5
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c64
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c21
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c92
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h43
-rw-r--r--drivers/net/wireless/ath/ath9k/channel.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/common-debug.h27
-rw-r--r--drivers/net/wireless/ath/ath9k/common-spectral.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/common-spectral.h23
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h13
-rw-r--r--drivers/net/wireless/ath/ath9k/debug_sta.c54
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c42
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h85
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c139
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c131
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c165
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c46
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c44
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c43
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c65
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c174
29 files changed, 814 insertions, 519 deletions
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 8f231c67dd51..783a38f1a626 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -3,8 +3,8 @@ config ATH9K_HW
config ATH9K_COMMON
tristate
select ATH_COMMON
- select DEBUG_FS
- select RELAY
+config ATH9K_COMMON_DEBUG
+ bool
config ATH9K_DFS_DEBUGFS
def_bool y
depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED
@@ -60,12 +60,14 @@ config ATH9K_DEBUGFS
bool "Atheros ath9k debugging"
depends on ATH9K && DEBUG_FS
select MAC80211_DEBUGFS
+ select ATH9K_COMMON_DEBUG
select RELAY
---help---
Say Y, if you need access to ath9k's statistics for
interrupts, rate control, etc.
Also required for changing debug message flags at run time.
+ As well as access to the FFT/spectral data and TX99.
config ATH9K_STATION_STATISTICS
bool "Detailed station statistics"
@@ -174,8 +176,11 @@ config ATH9K_HTC
config ATH9K_HTC_DEBUGFS
bool "Atheros ath9k_htc debugging"
depends on ATH9K_HTC && DEBUG_FS
+ select ATH9K_COMMON_DEBUG
+ select RELAY
---help---
Say Y, if you need access to ath9k_htc's statistics.
+ As well as access to the FFT/spectral data.
config ATH9K_HWRNG
bool "Random number generator support"
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 76f9dc37500b..36a40ffdce15 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -60,8 +60,9 @@ obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o
ath9k_common-y:= common.o \
common-init.o \
common-beacon.o \
- common-debug.o \
- common-spectral.o
+
+ath9k_common-$(CONFIG_ATH9K_COMMON_DEBUG) += common-debug.o \
+ common-spectral.o
ath9k_htc-y += htc_hst.o \
hif_usb.o \
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 8eea8d22e72e..7922550c2159 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -524,7 +524,7 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah,
return true;
/* Setup rf parameters */
- eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
+ eepMinorRev = ah->eep_ops->get_eeprom_rev(ah);
for (i = 0; i < ah->iniBank6.ia_rows; i++)
ah->analogBank6Data[i] = INI_RA(&ah->iniBank6, i, modesIndex);
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index d480d2f3e185..ae68f674829b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -108,8 +108,7 @@ static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah)
{
u32 rxgain_type;
- if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >=
- AR5416_EEP_MINOR_VER_17) {
+ if (ah->eep_ops->get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_17) {
rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
@@ -129,8 +128,7 @@ static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah)
static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type)
{
- if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >=
- AR5416_EEP_MINOR_VER_19) {
+ if (ah->eep_ops->get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_19) {
if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9280Modes_high_power_tx_gain_9280_2);
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index f816909d9474..4b3c9b108197 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -220,8 +220,8 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
- ACCESS_ONCE(ads->ds_link) = i->link;
- ACCESS_ONCE(ads->ds_data) = i->buf_addr[0];
+ WRITE_ONCE(ads->ds_link, i->link);
+ WRITE_ONCE(ads->ds_data, i->buf_addr[0]);
ctl1 = i->buf_len[0] | (i->is_last ? 0 : AR_TxMore);
ctl6 = SM(i->keytype, AR_EncrType);
@@ -235,26 +235,26 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
if ((i->is_first || i->is_last) &&
i->aggr != AGGR_BUF_MIDDLE && i->aggr != AGGR_BUF_LAST) {
- ACCESS_ONCE(ads->ds_ctl2) = set11nTries(i->rates, 0)
+ WRITE_ONCE(ads->ds_ctl2, set11nTries(i->rates, 0)
| set11nTries(i->rates, 1)
| set11nTries(i->rates, 2)
| set11nTries(i->rates, 3)
| (i->dur_update ? AR_DurUpdateEna : 0)
- | SM(0, AR_BurstDur);
+ | SM(0, AR_BurstDur));
- ACCESS_ONCE(ads->ds_ctl3) = set11nRate(i->rates, 0)
+ WRITE_ONCE(ads->ds_ctl3, set11nRate(i->rates, 0)
| set11nRate(i->rates, 1)
| set11nRate(i->rates, 2)
- | set11nRate(i->rates, 3);
+ | set11nRate(i->rates, 3));
} else {
- ACCESS_ONCE(ads->ds_ctl2) = 0;
- ACCESS_ONCE(ads->ds_ctl3) = 0;
+ WRITE_ONCE(ads->ds_ctl2, 0);
+ WRITE_ONCE(ads->ds_ctl3, 0);
}
if (!i->is_first) {
- ACCESS_ONCE(ads->ds_ctl0) = 0;
- ACCESS_ONCE(ads->ds_ctl1) = ctl1;
- ACCESS_ONCE(ads->ds_ctl6) = ctl6;
+ WRITE_ONCE(ads->ds_ctl0, 0);
+ WRITE_ONCE(ads->ds_ctl1, ctl1);
+ WRITE_ONCE(ads->ds_ctl6, ctl6);
return;
}
@@ -279,7 +279,7 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
break;
}
- ACCESS_ONCE(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen)
+ WRITE_ONCE(ads->ds_ctl0, (i->pkt_len & AR_FrameLen)
| (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
| SM(i->txpower[0], AR_XmitPower0)
| (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
@@ -287,29 +287,29 @@ ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
| (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
| (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
| (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable :
- (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0));
+ (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0)));
- ACCESS_ONCE(ads->ds_ctl1) = ctl1;
- ACCESS_ONCE(ads->ds_ctl6) = ctl6;
+ WRITE_ONCE(ads->ds_ctl1, ctl1);
+ WRITE_ONCE(ads->ds_ctl6, ctl6);
if (i->aggr == AGGR_BUF_MIDDLE || i->aggr == AGGR_BUF_LAST)
return;
- ACCESS_ONCE(ads->ds_ctl4) = set11nPktDurRTSCTS(i->rates, 0)
- | set11nPktDurRTSCTS(i->rates, 1);
+ WRITE_ONCE(ads->ds_ctl4, set11nPktDurRTSCTS(i->rates, 0)
+ | set11nPktDurRTSCTS(i->rates, 1));
- ACCESS_ONCE(ads->ds_ctl5) = set11nPktDurRTSCTS(i->rates, 2)
- | set11nPktDurRTSCTS(i->rates, 3);
+ WRITE_ONCE(ads->ds_ctl5, set11nPktDurRTSCTS(i->rates, 2)
+ | set11nPktDurRTSCTS(i->rates, 3));
- ACCESS_ONCE(ads->ds_ctl7) = set11nRateFlags(i->rates, 0)
+ WRITE_ONCE(ads->ds_ctl7, set11nRateFlags(i->rates, 0)
| set11nRateFlags(i->rates, 1)
| set11nRateFlags(i->rates, 2)
| set11nRateFlags(i->rates, 3)
- | SM(i->rtscts_rate, AR_RTSCTSRate);
+ | SM(i->rtscts_rate, AR_RTSCTSRate));
- ACCESS_ONCE(ads->ds_ctl9) = SM(i->txpower[1], AR_XmitPower1);
- ACCESS_ONCE(ads->ds_ctl10) = SM(i->txpower[2], AR_XmitPower2);
- ACCESS_ONCE(ads->ds_ctl11) = SM(i->txpower[3], AR_XmitPower3);
+ WRITE_ONCE(ads->ds_ctl9, SM(i->txpower[1], AR_XmitPower1));
+ WRITE_ONCE(ads->ds_ctl10, SM(i->txpower[2], AR_XmitPower2));
+ WRITE_ONCE(ads->ds_ctl11, SM(i->txpower[3], AR_XmitPower3));
}
static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
@@ -318,7 +318,7 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
struct ar5416_desc *ads = AR5416DESC(ds);
u32 status;
- status = ACCESS_ONCE(ads->ds_txstatus9);
+ status = READ_ONCE(ads->ds_txstatus9);
if ((status & AR_TxDone) == 0)
return -EINPROGRESS;
@@ -332,7 +332,7 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
ts->ts_rateindex = MS(status, AR_FinalTxIdx);
ts->ts_seqnum = MS(status, AR_SeqNum);
- status = ACCESS_ONCE(ads->ds_txstatus0);
+ status = READ_ONCE(ads->ds_txstatus0);
ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
@@ -342,7 +342,7 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
ts->ba_high = ads->AR_BaBitmapHigh;
}
- status = ACCESS_ONCE(ads->ds_txstatus1);
+ status = READ_ONCE(ads->ds_txstatus1);
if (status & AR_FrmXmitOK)
ts->ts_status |= ATH9K_TX_ACKED;
else {
@@ -371,7 +371,7 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
ts->ts_longretry = MS(status, AR_DataFailCnt);
ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
- status = ACCESS_ONCE(ads->ds_txstatus5);
+ status = READ_ONCE(ads->ds_txstatus5);
ts->ts_rssi = MS(status, AR_TxRSSICombined);
ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
@@ -390,13 +390,13 @@ static int ar9002_hw_get_duration(struct ath_hw *ah, const void *ds, int index)
switch (index) {
case 0:
- return MS(ACCESS_ONCE(ads->ds_ctl4), AR_PacketDur0);
+ return MS(READ_ONCE(ads->ds_ctl4), AR_PacketDur0);
case 1:
- return MS(ACCESS_ONCE(ads->ds_ctl4), AR_PacketDur1);
+ return MS(READ_ONCE(ads->ds_ctl4), AR_PacketDur1);
case 2:
- return MS(ACCESS_ONCE(ads->ds_ctl5), AR_PacketDur2);
+ return MS(READ_ONCE(ads->ds_ctl5), AR_PacketDur2);
case 3:
- return MS(ACCESS_ONCE(ads->ds_ctl5), AR_PacketDur3);
+ return MS(READ_ONCE(ads->ds_ctl5), AR_PacketDur3);
default:
return -1;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 08607d7fdb56..3dbfd86ebe36 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -53,7 +53,7 @@ static const struct ar9300_eeprom ar9300_default = {
.txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
.opCapFlags = {
.opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
- .eepMisc = 0,
+ .eepMisc = AR9300_EEPMISC_LITTLE_ENDIAN,
},
.rfSilent = 0,
.blueToothOptions = 0,
@@ -631,7 +631,7 @@ static const struct ar9300_eeprom ar9300_x113 = {
.txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
.opCapFlags = {
.opFlags = AR5416_OPFLAGS_11A,
- .eepMisc = 0,
+ .eepMisc = AR9300_EEPMISC_LITTLE_ENDIAN,
},
.rfSilent = 0,
.blueToothOptions = 0,
@@ -1210,7 +1210,7 @@ static const struct ar9300_eeprom ar9300_h112 = {
.txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
.opCapFlags = {
.opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
- .eepMisc = 0,
+ .eepMisc = AR9300_EEPMISC_LITTLE_ENDIAN,
},
.rfSilent = 0,
.blueToothOptions = 0,
@@ -1789,7 +1789,7 @@ static const struct ar9300_eeprom ar9300_x112 = {
.txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
.opCapFlags = {
.opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
- .eepMisc = 0,
+ .eepMisc = AR9300_EEPMISC_LITTLE_ENDIAN,
},
.rfSilent = 0,
.blueToothOptions = 0,
@@ -2367,7 +2367,7 @@ static const struct ar9300_eeprom ar9300_h116 = {
.txrxMask = 0x33, /* 4 bits tx and 4 bits rx */
.opCapFlags = {
.opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
- .eepMisc = 0,
+ .eepMisc = AR9300_EEPMISC_LITTLE_ENDIAN,
},
.rfSilent = 0,
.blueToothOptions = 0,
@@ -3468,7 +3468,8 @@ static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
AR5416_OPFLAGS_N_5G_HT20));
PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags.opFlags &
AR5416_OPFLAGS_N_5G_HT40));
- PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc & 0x01));
+ PR_EEP("Big Endian", !!(pBase->opCapFlags.eepMisc &
+ AR5416_EEPMISC_BIG_ENDIAN));
PR_EEP("RF Silent", pBase->rfSilent);
PR_EEP("BT option", pBase->blueToothOptions);
PR_EEP("Device Cap", pBase->deviceCap);
@@ -5497,6 +5498,11 @@ unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
}
}
+static u8 ar9003_get_eepmisc(struct ath_hw *ah)
+{
+ return ah->eeprom.map4k.baseEepHeader.eepMisc;
+}
+
const struct eeprom_ops eep_ar9300_ops = {
.check_eeprom = ath9k_hw_ar9300_check_eeprom,
.get_eeprom = ath9k_hw_ar9300_get_eeprom,
@@ -5507,5 +5513,6 @@ const struct eeprom_ops eep_ar9300_ops = {
.set_board_values = ath9k_hw_ar9300_set_board_values,
.set_addac = ath9k_hw_ar9300_set_addac,
.set_txpower = ath9k_hw_ar9300_set_txpower,
- .get_spur_channel = ath9k_hw_ar9300_get_spur_channel
+ .get_spur_channel = ath9k_hw_ar9300_get_spur_channel,
+ .get_eepmisc = ar9003_get_eepmisc
};
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index 107bcfbbe0fb..bd2269c7de6b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -38,7 +38,6 @@
#define AR9300_NUM_CTLS_2G 12
#define AR9300_NUM_BAND_EDGES_5G 8
#define AR9300_NUM_BAND_EDGES_2G 4
-#define AR9300_EEPMISC_BIG_ENDIAN 0x01
#define AR9300_EEPMISC_WOW 0x02
#define AR9300_CUSTOMER_DATA_SIZE 20
@@ -70,16 +69,19 @@
#define AR9300_BASE_ADDR 0x3ff
#define AR9300_BASE_ADDR_512 0x1ff
+/* AR5416_EEPMISC_BIG_ENDIAN not set indicates little endian */
+#define AR9300_EEPMISC_LITTLE_ENDIAN 0
+
#define AR9300_OTP_BASE \
((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30000 : 0x14000)
#define AR9300_OTP_STATUS \
- ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x30018 : 0x15f18)
+ ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x31018 : 0x15f18)
#define AR9300_OTP_STATUS_TYPE 0x7
#define AR9300_OTP_STATUS_VALID 0x4
#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2
#define AR9300_OTP_STATUS_SM_BUSY 0x1
#define AR9300_OTP_READ_DATA \
- ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3001c : 0x15f1c)
+ ((AR_SREV_9340(ah) || AR_SREV_9550(ah)) ? 0x3101c : 0x15f1c)
enum targetPowerHTRates {
HT_TARGET_RATE_0_8_16,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index da84b705cbcd..cc5bb0a76baf 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -39,47 +39,47 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
(i->qcu << AR_TxQcuNum_S) | desc_len;
checksum += val;
- ACCESS_ONCE(ads->info) = val;
+ WRITE_ONCE(ads->info, val);
checksum += i->link;
- ACCESS_ONCE(ads->link) = i->link;
+ WRITE_ONCE(ads->link, i->link);
checksum += i->buf_addr[0];
- ACCESS_ONCE(ads->data0) = i->buf_addr[0];
+ WRITE_ONCE(ads->data0, i->buf_addr[0]);
checksum += i->buf_addr[1];
- ACCESS_ONCE(ads->data1) = i->buf_addr[1];
+ WRITE_ONCE(ads->data1, i->buf_addr[1]);
checksum += i->buf_addr[2];
- ACCESS_ONCE(ads->data2) = i->buf_addr[2];
+ WRITE_ONCE(ads->data2, i->buf_addr[2]);
checksum += i->buf_addr[3];
- ACCESS_ONCE(ads->data3) = i->buf_addr[3];
+ WRITE_ONCE(ads->data3, i->buf_addr[3]);
checksum += (val = (i->buf_len[0] << AR_BufLen_S) & AR_BufLen);
- ACCESS_ONCE(ads->ctl3) = val;
+ WRITE_ONCE(ads->ctl3, val);
checksum += (val = (i->buf_len[1] << AR_BufLen_S) & AR_BufLen);
- ACCESS_ONCE(ads->ctl5) = val;
+ WRITE_ONCE(ads->ctl5, val);
checksum += (val = (i->buf_len[2] << AR_BufLen_S) & AR_BufLen);
- ACCESS_ONCE(ads->ctl7) = val;
+ WRITE_ONCE(ads->ctl7, val);
checksum += (val = (i->buf_len[3] << AR_BufLen_S) & AR_BufLen);
- ACCESS_ONCE(ads->ctl9) = val;
+ WRITE_ONCE(ads->ctl9, val);
checksum = (u16) (((checksum & 0xffff) + (checksum >> 16)) & 0xffff);
- ACCESS_ONCE(ads->ctl10) = checksum;
+ WRITE_ONCE(ads->ctl10, checksum);
if (i->is_first || i->is_last) {
- ACCESS_ONCE(ads->ctl13) = set11nTries(i->rates, 0)
+ WRITE_ONCE(ads->ctl13, set11nTries(i->rates, 0)
| set11nTries(i->rates, 1)
| set11nTries(i->rates, 2)
| set11nTries(i->rates, 3)
| (i->dur_update ? AR_DurUpdateEna : 0)
- | SM(0, AR_BurstDur);
+ | SM(0, AR_BurstDur));
- ACCESS_ONCE(ads->ctl14) = set11nRate(i->rates, 0)
+ WRITE_ONCE(ads->ctl14, set11nRate(i->rates, 0)
| set11nRate(i->rates, 1)
| set11nRate(i->rates, 2)
- | set11nRate(i->rates, 3);
+ | set11nRate(i->rates, 3));
} else {
- ACCESS_ONCE(ads->ctl13) = 0;
- ACCESS_ONCE(ads->ctl14) = 0;
+ WRITE_ONCE(ads->ctl13, 0);
+ WRITE_ONCE(ads->ctl14, 0);
}
ads->ctl20 = 0;
@@ -89,17 +89,17 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
ctl17 = SM(i->keytype, AR_EncrType);
if (!i->is_first) {
- ACCESS_ONCE(ads->ctl11) = 0;
- ACCESS_ONCE(ads->ctl12) = i->is_last ? 0 : AR_TxMore;
- ACCESS_ONCE(ads->ctl15) = 0;
- ACCESS_ONCE(ads->ctl16) = 0;
- ACCESS_ONCE(ads->ctl17) = ctl17;
- ACCESS_ONCE(ads->ctl18) = 0;
- ACCESS_ONCE(ads->ctl19) = 0;
+ WRITE_ONCE(ads->ctl11, 0);
+ WRITE_ONCE(ads->ctl12, i->is_last ? 0 : AR_TxMore);
+ WRITE_ONCE(ads->ctl15, 0);
+ WRITE_ONCE(ads->ctl16, 0);
+ WRITE_ONCE(ads->ctl17, ctl17);
+ WRITE_ONCE(ads->ctl18, 0);
+ WRITE_ONCE(ads->ctl19, 0);
return;
}
- ACCESS_ONCE(ads->ctl11) = (i->pkt_len & AR_FrameLen)
+ WRITE_ONCE(ads->ctl11, (i->pkt_len & AR_FrameLen)
| (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
| SM(i->txpower[0], AR_XmitPower0)
| (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
@@ -107,7 +107,7 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
| (i->flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0)
| (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
| (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable :
- (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0));
+ (i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0)));
ctl12 = (i->keyix != ATH9K_TXKEYIX_INVALID ?
SM(i->keyix, AR_DestIdx) : 0)
@@ -135,26 +135,26 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
val = (i->flags & ATH9K_TXDESC_PAPRD) >> ATH9K_TXDESC_PAPRD_S;
ctl12 |= SM(val, AR_PAPRDChainMask);
- ACCESS_ONCE(ads->ctl12) = ctl12;
- ACCESS_ONCE(ads->ctl17) = ctl17;
+ WRITE_ONCE(ads->ctl12, ctl12);
+ WRITE_ONCE(ads->ctl17, ctl17);
- ACCESS_ONCE(ads->ctl15) = set11nPktDurRTSCTS(i->rates, 0)
- | set11nPktDurRTSCTS(i->rates, 1);
+ WRITE_ONCE(ads->ctl15, set11nPktDurRTSCTS(i->rates, 0)
+ | set11nPktDurRTSCTS(i->rates, 1));
- ACCESS_ONCE(ads->ctl16) = set11nPktDurRTSCTS(i->rates, 2)
- | set11nPktDurRTSCTS(i->rates, 3);
+ WRITE_ONCE(ads->ctl16, set11nPktDurRTSCTS(i->rates, 2)
+ | set11nPktDurRTSCTS(i->rates, 3));
- ACCESS_ONCE(ads->ctl18) = set11nRateFlags(i->rates, 0)
+ WRITE_ONCE(ads->ctl18, set11nRateFlags(i->rates, 0)
| set11nRateFlags(i->rates, 1)
| set11nRateFlags(i->rates, 2)
| set11nRateFlags(i->rates, 3)
- | SM(i->rtscts_rate, AR_RTSCTSRate);
+ | SM(i->rtscts_rate, AR_RTSCTSRate));
- ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding;
+ WRITE_ONCE(ads->ctl19, AR_Not_Sounding);
- ACCESS_ONCE(ads->ctl20) = SM(i->txpower[1], AR_XmitPower1);
- ACCESS_ONCE(ads->ctl21) = SM(i->txpower[2], AR_XmitPower2);
- ACCESS_ONCE(ads->ctl22) = SM(i->txpower[3], AR_XmitPower3);
+ WRITE_ONCE(ads->ctl20, SM(i->txpower[1], AR_XmitPower1));
+ WRITE_ONCE(ads->ctl21, SM(i->txpower[2], AR_XmitPower2));
+ WRITE_ONCE(ads->ctl22, SM(i->txpower[3], AR_XmitPower3));
}
static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
@@ -359,7 +359,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
ads = &ah->ts_ring[ah->ts_tail];
- status = ACCESS_ONCE(ads->status8);
+ status = READ_ONCE(ads->status8);
if ((status & AR_TxDone) == 0)
return -EINPROGRESS;
@@ -385,7 +385,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
if (status & AR_TxOpExceeded)
ts->ts_status |= ATH9K_TXERR_XTXOP;
- status = ACCESS_ONCE(ads->status2);
+ status = READ_ONCE(ads->status2);
ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
@@ -395,7 +395,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
ts->ba_high = ads->status6;
}
- status = ACCESS_ONCE(ads->status3);
+ status = READ_ONCE(ads->status3);
if (status & AR_ExcessiveRetries)
ts->ts_status |= ATH9K_TXERR_XRETRY;
if (status & AR_Filtered)
@@ -420,7 +420,7 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
ts->ts_longretry = MS(status, AR_DataFailCnt);
ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
- status = ACCESS_ONCE(ads->status7);
+ status = READ_ONCE(ads->status7);
ts->ts_rssi = MS(status, AR_TxRSSICombined);
ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
@@ -437,13 +437,13 @@ static int ar9003_hw_get_duration(struct ath_hw *ah, const void *ds, int index)
switch (index) {
case 0:
- return MS(ACCESS_ONCE(adc->ctl15), AR_PacketDur0);
+ return MS(READ_ONCE(adc->ctl15), AR_PacketDur0);
case 1:
- return MS(ACCESS_ONCE(adc->ctl15), AR_PacketDur1);
+ return MS(READ_ONCE(adc->ctl15), AR_PacketDur1);
case 2:
- return MS(ACCESS_ONCE(adc->ctl16), AR_PacketDur2);
+ return MS(READ_ONCE(adc->ctl16), AR_PacketDur2);
case 3:
- return MS(ACCESS_ONCE(adc->ctl16), AR_PacketDur3);
+ return MS(READ_ONCE(adc->ctl16), AR_PacketDur3);
default:
return 0;
}
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 378d3458fddb..cf076719c27e 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -108,10 +108,12 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
#define ATH_AGGR_MIN_QDEPTH 2
/* minimum h/w qdepth for non-aggregated traffic */
#define ATH_NON_AGGR_MIN_QDEPTH 8
-#define ATH_TX_COMPLETE_POLL_INT 1000
+#define ATH_HW_CHECK_POLL_INT 1000
#define ATH_TXFIFO_DEPTH 8
#define ATH_TX_ERROR 0x01
+#define ATH_AIRTIME_QUANTUM 300 /* usec */
+
/* Stop tx traffic 1ms before the GO goes away */
#define ATH_P2P_PS_STOP_TIME 1000
@@ -247,6 +249,9 @@ struct ath_atx_tid {
bool has_queued;
};
+void __ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid);
+void ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid);
+
struct ath_node {
struct ath_softc *sc;
struct ieee80211_sta *sta; /* station struct we're part of */
@@ -258,9 +263,12 @@ struct ath_node {
bool sleeping;
bool no_ps_filter;
+ s64 airtime_deficit[IEEE80211_NUM_ACS];
+ u32 airtime_rx_start;
#ifdef CONFIG_ATH9K_STATION_STATISTICS
struct ath_rx_rate_stats rx_rate_stats;
+ struct ath_airtime_stats airtime_stats;
#endif
u8 key_idx[4];
@@ -317,10 +325,16 @@ struct ath_rx {
/* Channel Context */
/*******************/
+struct ath_acq {
+ struct list_head acq_new;
+ struct list_head acq_old;
+ spinlock_t lock;
+};
+
struct ath_chanctx {
struct cfg80211_chan_def chandef;
struct list_head vifs;
- struct list_head acq[IEEE80211_NUM_ACS];
+ struct ath_acq acq[IEEE80211_NUM_ACS];
int hw_queue_base;
/* do not dereference, use for comparison only */
@@ -555,6 +569,15 @@ static inline void ath_chanctx_check_active(struct ath_softc *sc,
#endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */
+static inline void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq)
+{
+ spin_lock_bh(&txq->axq_lock);
+}
+static inline void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq)
+{
+ spin_unlock_bh(&txq->axq_lock);
+}
+
void ath_startrecv(struct ath_softc *sc);
bool ath_stoprecv(struct ath_softc *sc);
u32 ath_calcrxfilter(struct ath_softc *sc);
@@ -562,8 +585,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs);
void ath_rx_cleanup(struct ath_softc *sc);
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
-void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq);
-void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq);
void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq);
void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
bool ath_drain_all_txq(struct ath_softc *sc);
@@ -575,6 +596,8 @@ void ath_txq_schedule_all(struct ath_softc *sc);
int ath_tx_init(struct ath_softc *sc, int nbufs);
int ath_txq_update(struct ath_softc *sc, int qnum,
struct ath9k_tx_queue_info *q);
+u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen,
+ int width, int half_gi, bool shortPreamble);
void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop);
void ath_assign_seq(struct ath_common *common, struct sk_buff *skb);
int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
@@ -722,7 +745,7 @@ void ath9k_csa_update(struct ath_softc *sc);
#define ATH_PAPRD_TIMEOUT 100 /* msecs */
#define ATH_PLL_WORK_INTERVAL 100
-void ath_tx_complete_poll_work(struct work_struct *work);
+void ath_hw_check_work(struct work_struct *work);
void ath_reset_work(struct work_struct *work);
bool ath_hw_check(struct ath_softc *sc);
void ath_hw_pll_work(struct work_struct *work);
@@ -963,6 +986,11 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs);
#define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */
+#define AIRTIME_USE_TX BIT(0)
+#define AIRTIME_USE_RX BIT(1)
+#define AIRTIME_USE_NEW_QUEUES BIT(2)
+#define AIRTIME_ACTIVE(flags) (!!(flags & (AIRTIME_USE_TX|AIRTIME_USE_RX)))
+
struct ath_softc {
struct ieee80211_hw *hw;
struct device *dev;
@@ -970,6 +998,7 @@ struct ath_softc {
struct survey_info *cur_survey;
struct survey_info survey[ATH9K_NUM_CHANNELS];
+ spinlock_t intr_lock;
struct tasklet_struct intr_tq;
struct tasklet_struct bcon_tasklet;
struct ath_hw *sc_ah;
@@ -1005,6 +1034,8 @@ struct ath_softc {
short nbcnvifs;
unsigned long ps_usecount;
+ u16 airtime_flags; /* AIRTIME_* */
+
struct ath_rx rx;
struct ath_tx tx;
struct ath_beacon beacon;
@@ -1023,7 +1054,7 @@ struct ath_softc {
#ifdef CONFIG_ATH9K_DEBUGFS
struct ath9k_debug debug;
#endif
- struct delayed_work tx_complete_work;
+ struct delayed_work hw_check_work;
struct delayed_work hw_pll_work;
struct timer_list sleep_timer;
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
index 929dd70f48eb..b84539d89f1a 100644
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -118,8 +118,11 @@ void ath_chanctx_init(struct ath_softc *sc)
INIT_LIST_HEAD(&ctx->vifs);
ctx->txpower = ATH_TXPOWER_MAX;
ctx->flush_timeout = HZ / 5; /* 200ms */
- for (j = 0; j < ARRAY_SIZE(ctx->acq); j++)
- INIT_LIST_HEAD(&ctx->acq[j]);
+ for (j = 0; j < ARRAY_SIZE(ctx->acq); j++) {
+ INIT_LIST_HEAD(&ctx->acq[j].acq_new);
+ INIT_LIST_HEAD(&ctx->acq[j].acq_old);
+ spin_lock_init(&ctx->acq[j].lock);
+ }
}
}
@@ -1345,8 +1348,11 @@ void ath9k_offchannel_init(struct ath_softc *sc)
ctx->txpower = ATH_TXPOWER_MAX;
cfg80211_chandef_create(&ctx->chandef, chan, NL80211_CHAN_HT20);
- for (i = 0; i < ARRAY_SIZE(ctx->acq); i++)
- INIT_LIST_HEAD(&ctx->acq[i]);
+ for (i = 0; i < ARRAY_SIZE(ctx->acq); i++) {
+ INIT_LIST_HEAD(&ctx->acq[i].acq_new);
+ INIT_LIST_HEAD(&ctx->acq[i].acq_old);
+ spin_lock_init(&ctx->acq[i].lock);
+ }
sc->offchannel.chan.offchannel = true;
}
diff --git a/drivers/net/wireless/ath/ath9k/common-debug.h b/drivers/net/wireless/ath/ath9k/common-debug.h
index 7c9788490f7f..3376990d3a24 100644
--- a/drivers/net/wireless/ath/ath9k/common-debug.h
+++ b/drivers/net/wireless/ath/ath9k/common-debug.h
@@ -60,6 +60,7 @@ struct ath_rx_stats {
u32 rx_spectral;
};
+#ifdef CONFIG_ATH9K_COMMON_DEBUG
void ath9k_cmn_debug_modal_eeprom(struct dentry *debugfs_phy,
struct ath_hw *ah);
void ath9k_cmn_debug_base_eeprom(struct dentry *debugfs_phy,
@@ -70,3 +71,29 @@ void ath9k_cmn_debug_recv(struct dentry *debugfs_phy,
struct ath_rx_stats *rxstats);
void ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy,
struct ath_rx_stats *rxstats);
+#else
+static inline void ath9k_cmn_debug_modal_eeprom(struct dentry *debugfs_phy,
+ struct ath_hw *ah)
+{
+}
+
+static inline void ath9k_cmn_debug_base_eeprom(struct dentry *debugfs_phy,
+ struct ath_hw *ah)
+{
+}
+
+static inline void ath9k_cmn_debug_stat_rx(struct ath_rx_stats *rxstats,
+ struct ath_rx_status *rs)
+{
+}
+
+static inline void ath9k_cmn_debug_recv(struct dentry *debugfs_phy,
+ struct ath_rx_stats *rxstats)
+{
+}
+
+static inline void ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy,
+ struct ath_rx_stats *rxstats)
+{
+}
+#endif /* CONFIG_ATH9K_COMMON_DEBUG */
diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.c b/drivers/net/wireless/ath/ath9k/common-spectral.c
index eedf86b67cf5..0ffa23a61568 100644
--- a/drivers/net/wireless/ath/ath9k/common-spectral.c
+++ b/drivers/net/wireless/ath/ath9k/common-spectral.c
@@ -482,7 +482,7 @@ ath_cmn_is_fft_buf_full(struct ath_spec_scan_priv *spec_priv)
struct rchan *rc = spec_priv->rfs_chan_spec_scan;
for_each_online_cpu(i)
- ret += relay_buf_full(rc->buf[i]);
+ ret += relay_buf_full(*per_cpu_ptr(rc->buf, i));
i = num_online_cpus();
@@ -1075,7 +1075,7 @@ static struct rchan_callbacks rfs_spec_scan_cb = {
void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv)
{
- if (IS_ENABLED(CONFIG_ATH9K_DEBUGFS) && spec_priv->rfs_chan_spec_scan) {
+ if (spec_priv->rfs_chan_spec_scan) {
relay_close(spec_priv->rfs_chan_spec_scan);
spec_priv->rfs_chan_spec_scan = NULL;
}
diff --git a/drivers/net/wireless/ath/ath9k/common-spectral.h b/drivers/net/wireless/ath/ath9k/common-spectral.h
index 998743be9c67..5d1a51d83aa6 100644
--- a/drivers/net/wireless/ath/ath9k/common-spectral.h
+++ b/drivers/net/wireless/ath/ath9k/common-spectral.h
@@ -151,6 +151,7 @@ static inline u8 spectral_bitmap_weight(u8 *bins)
return bins[0] & 0x3f;
}
+#ifdef CONFIG_ATH9K_COMMON_DEBUG
void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv, struct dentry *debugfs_phy);
void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv);
@@ -161,5 +162,27 @@ int ath9k_cmn_spectral_scan_config(struct ath_common *common,
enum spectral_mode spectral_mode);
int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv, struct ieee80211_hdr *hdr,
struct ath_rx_status *rs, u64 tsf);
+#else
+static inline void ath9k_cmn_spectral_init_debug(struct ath_spec_scan_priv *spec_priv,
+ struct dentry *debugfs_phy)
+{
+}
+
+static inline void ath9k_cmn_spectral_deinit_debug(struct ath_spec_scan_priv *spec_priv)
+{
+}
+
+static inline void ath9k_cmn_spectral_scan_trigger(struct ath_common *common,
+ struct ath_spec_scan_priv *spec_priv)
+{
+}
+
+static inline int ath_cmn_process_fft(struct ath_spec_scan_priv *spec_priv,
+ struct ieee80211_hdr *hdr,
+ struct ath_rx_status *rs, u64 tsf)
+{
+ return 0;
+}
+#endif /* CONFIG_ATH9K_COMMON_DEBUG */
#endif /* SPECTRAL_H */
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 89a94dd5f2cb..43930c336987 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1399,5 +1399,8 @@ int ath9k_init_debug(struct ath_hw *ah)
debugfs_create_file("tpc", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, sc, &fops_tpc);
+ debugfs_create_u16("airtime_flags", S_IRUSR | S_IWUSR,
+ sc->debug.debugfs_phy, &sc->airtime_flags);
+
return 0;
}
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index a078cdd3170d..249f8141cd00 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -221,6 +221,11 @@ struct ath_rx_rate_stats {
} cck_stats[4];
};
+struct ath_airtime_stats {
+ u32 rx_airtime;
+ u32 tx_airtime;
+};
+
#define ANT_MAIN 0
#define ANT_ALT 1
@@ -314,12 +319,20 @@ ath9k_debug_sync_cause(struct ath_softc *sc, u32 sync_cause)
void ath_debug_rate_stats(struct ath_softc *sc,
struct ath_rx_status *rs,
struct sk_buff *skb);
+void ath_debug_airtime(struct ath_softc *sc,
+ struct ath_node *an,
+ u32 rx, u32 tx);
#else
static inline void ath_debug_rate_stats(struct ath_softc *sc,
struct ath_rx_status *rs,
struct sk_buff *skb)
{
}
+static inline void ath_debug_airtime(struct ath_softc *sc,
+ struct ath_node *an,
+ u32 rx, u32 tx)
+{
+}
#endif /* CONFIG_ATH9K_STATION_STATISTICS */
#endif /* DEBUG_H */
diff --git a/drivers/net/wireless/ath/ath9k/debug_sta.c b/drivers/net/wireless/ath/ath9k/debug_sta.c
index 2a3a3c4671bc..524cbf13ca9c 100644
--- a/drivers/net/wireless/ath/ath9k/debug_sta.c
+++ b/drivers/net/wireless/ath/ath9k/debug_sta.c
@@ -242,6 +242,59 @@ static const struct file_operations fops_node_recv = {
.llseek = default_llseek,
};
+void ath_debug_airtime(struct ath_softc *sc,
+ struct ath_node *an,
+ u32 rx,
+ u32 tx)
+{
+ struct ath_airtime_stats *astats = &an->airtime_stats;
+
+ astats->rx_airtime += rx;
+ astats->tx_airtime += tx;
+}
+
+static ssize_t read_airtime(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_node *an = file->private_data;
+ struct ath_airtime_stats *astats;
+ static const char *qname[4] = {
+ "VO", "VI", "BE", "BK"
+ };
+ u32 len = 0, size = 256;
+ char *buf;
+ size_t retval;
+ int i;
+
+ buf = kzalloc(size, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ astats = &an->airtime_stats;
+
+ len += scnprintf(buf + len, size - len, "RX: %u us\n", astats->rx_airtime);
+ len += scnprintf(buf + len, size - len, "TX: %u us\n", astats->tx_airtime);
+ len += scnprintf(buf + len, size - len, "Deficit: ");
+ for (i = 0; i < 4; i++)
+ len += scnprintf(buf+len, size - len, "%s: %lld us ", qname[i], an->airtime_deficit[i]);
+ if (len < size)
+ buf[len++] = '\n';
+
+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return retval;
+}
+
+
+static const struct file_operations fops_airtime = {
+ .read = read_airtime,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+
void ath9k_sta_add_debugfs(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
@@ -251,4 +304,5 @@ void ath9k_sta_add_debugfs(struct ieee80211_hw *hw,
debugfs_create_file("node_aggr", S_IRUGO, dir, an, &fops_node_aggr);
debugfs_create_file("node_recv", S_IRUGO, dir, an, &fops_node_recv);
+ debugfs_create_file("airtime", S_IRUGO, dir, an, &fops_airtime);
}
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index a449588a8009..fb80ec86e53d 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -160,6 +160,7 @@ int ath9k_hw_nvram_swap_data(struct ath_hw *ah, bool *swap_needed, int size)
u16 magic;
u16 *eepdata;
int i;
+ bool needs_byteswap = false;
struct ath_common *common = ath9k_hw_common(ah);
if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
@@ -167,31 +168,40 @@ int ath9k_hw_nvram_swap_data(struct ath_hw *ah, bool *swap_needed, int size)
return -EIO;
}
- *swap_needed = false;
if (swab16(magic) == AR5416_EEPROM_MAGIC) {
+ needs_byteswap = true;
+ ath_dbg(common, EEPROM,
+ "EEPROM needs byte-swapping to correct endianness.\n");
+ } else if (magic != AR5416_EEPROM_MAGIC) {
+ if (ath9k_hw_use_flash(ah)) {
+ ath_dbg(common, EEPROM,
+ "Ignoring invalid EEPROM magic (0x%04x).\n",
+ magic);
+ } else {
+ ath_err(common,
+ "Invalid EEPROM magic (0x%04x).\n", magic);
+ return -EINVAL;
+ }
+ }
+
+ if (needs_byteswap) {
if (ah->ah_flags & AH_NO_EEP_SWAP) {
ath_info(common,
"Ignoring endianness difference in EEPROM magic bytes.\n");
} else {
- *swap_needed = true;
- }
- } else if (magic != AR5416_EEPROM_MAGIC) {
- if (ath9k_hw_use_flash(ah))
- return 0;
+ eepdata = (u16 *)(&ah->eeprom);
- ath_err(common,
- "Invalid EEPROM Magic (0x%04x).\n", magic);
- return -EINVAL;
+ for (i = 0; i < size; i++)
+ eepdata[i] = swab16(eepdata[i]);
+ }
}
- eepdata = (u16 *)(&ah->eeprom);
-
- if (*swap_needed) {
+ if (ah->eep_ops->get_eepmisc(ah) & AR5416_EEPMISC_BIG_ENDIAN) {
+ *swap_needed = true;
ath_dbg(common, EEPROM,
- "EEPROM Endianness is not native.. Changing.\n");
-
- for (i = 0; i < size; i++)
- eepdata[i] = swab16(eepdata[i]);
+ "Big Endian EEPROM detected according to EEPMISC register.\n");
+ } else {
+ *swap_needed = false;
}
return 0;
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 4465c6566f20..30bf722e33ed 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -23,6 +23,17 @@
#include <net/cfg80211.h>
#include "ar9003_eeprom.h"
+/* helpers to swap EEPROM fields, which are stored as __le16 or __le32. Since
+ * we are 100% sure about it we __force these to u16/u32 for the swab calls to
+ * silence the sparse checks. These macros are used when we have a Big Endian
+ * EEPROM (according to AR5416_EEPMISC_BIG_ENDIAN) and need to convert the
+ * fields to __le16/__le32.
+ */
+#define EEPROM_FIELD_SWAB16(field) \
+ (field = (__force __le16)swab16((__force u16)field))
+#define EEPROM_FIELD_SWAB32(field) \
+ (field = (__force __le32)swab32((__force u32)field))
+
#ifdef __BIG_ENDIAN
#define AR5416_EEPROM_MAGIC 0x5aa5
#else
@@ -99,7 +110,6 @@
#define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x))
#define ath9k_hw_use_flash(_ah) (!(_ah->ah_flags & AH_USE_EEPROM))
-#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
#define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \
ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
#define OLC_FOR_AR9287_10_LATER (AR_SREV_9287_11_OR_LATER(ah) && \
@@ -121,6 +131,8 @@
#define AR5416_EEP_NO_BACK_VER 0x1
#define AR5416_EEP_VER 0xE
+#define AR5416_EEP_VER_MAJOR_SHIFT 12
+#define AR5416_EEP_VER_MAJOR_MASK 0xF000
#define AR5416_EEP_VER_MINOR_MASK 0x0FFF
#define AR5416_EEP_MINOR_VER_2 0x2
#define AR5416_EEP_MINOR_VER_3 0x3
@@ -161,6 +173,9 @@
#define AR5416_EEP_TXGAIN_ORIGINAL 0
#define AR5416_EEP_TXGAIN_HIGH_POWER 1
+/* Endianness of EEPROM content */
+#define AR5416_EEPMISC_BIG_ENDIAN 0x01
+
#define AR5416_EEP4K_START_LOC 64
#define AR5416_EEP4K_NUM_2G_CAL_PIERS 3
#define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3
@@ -174,7 +189,6 @@
#define AR9280_TX_GAIN_TABLE_SIZE 22
#define AR9287_EEP_VER 0xE
-#define AR9287_EEP_VER_MINOR_MASK 0xFFF
#define AR9287_EEP_MINOR_VER_1 0x1
#define AR9287_EEP_MINOR_VER_2 0x2
#define AR9287_EEP_MINOR_VER_3 0x3
@@ -191,7 +205,6 @@
#define AR9287_NUM_CTLS 12
#define AR9287_NUM_BAND_EDGES 4
#define AR9287_PD_GAIN_ICEPTS 1
-#define AR9287_EEPMISC_BIG_ENDIAN 0x01
#define AR9287_EEPMISC_WOW 0x02
#define AR9287_MAX_CHAINS 2
#define AR9287_ANT_16S 32
@@ -228,7 +241,6 @@ enum eeprom_param {
EEP_DB_5,
EEP_OB_2,
EEP_DB_2,
- EEP_MINOR_REV,
EEP_TX_MASK,
EEP_RX_MASK,
EEP_FSTCLK_5G,
@@ -269,19 +281,19 @@ enum ath9k_hal_freq_band {
};
struct base_eep_header {
- u16 length;
- u16 checksum;
- u16 version;
+ __le16 length;
+ __le16 checksum;
+ __le16 version;
u8 opCapFlags;
u8 eepMisc;
- u16 regDmn[2];
+ __le16 regDmn[2];
u8 macAddr[6];
u8 rxMask;
u8 txMask;
- u16 rfSilent;
- u16 blueToothOptions;
- u16 deviceCap;
- u32 binBuildNumber;
+ __le16 rfSilent;
+ __le16 blueToothOptions;
+ __le16 deviceCap;
+ __le32 binBuildNumber;
u8 deviceType;
u8 pwdclkind;
u8 fastClk5g;
@@ -299,33 +311,33 @@ struct base_eep_header {
} __packed;
struct base_eep_header_4k {
- u16 length;
- u16 checksum;
- u16 version;
+ __le16 length;
+ __le16 checksum;
+ __le16 version;
u8 opCapFlags;
u8 eepMisc;
- u16 regDmn[2];
+ __le16 regDmn[2];
u8 macAddr[6];
u8 rxMask;
u8 txMask;
- u16 rfSilent;
- u16 blueToothOptions;
- u16 deviceCap;
- u32 binBuildNumber;
+ __le16 rfSilent;
+ __le16 blueToothOptions;
+ __le16 deviceCap;
+ __le32 binBuildNumber;
u8 deviceType;
u8 txGainType;
} __packed;
struct spur_chan {
- u16 spurChan;
+ __le16 spurChan;
u8 spurRangeLow;
u8 spurRangeHigh;
} __packed;
struct modal_eep_header {
- u32 antCtrlChain[AR5416_MAX_CHAINS];
- u32 antCtrlCommon;
+ __le32 antCtrlChain[AR5416_MAX_CHAINS];
+ __le32 antCtrlCommon;
u8 antennaGainCh[AR5416_MAX_CHAINS];
u8 switchSettling;
u8 txRxAttenCh[AR5416_MAX_CHAINS];
@@ -360,7 +372,7 @@ struct modal_eep_header {
u8 db_ch1;
u8 lna_ctl;
u8 miscBits;
- u16 xpaBiasLvlFreq[3];
+ __le16 xpaBiasLvlFreq[3];
u8 futureModal[6];
struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
@@ -374,8 +386,8 @@ struct calDataPerFreqOpLoop {
} __packed;
struct modal_eep_4k_header {
- u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
- u32 antCtrlCommon;
+ __le32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
+ __le32 antCtrlCommon;
u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
u8 switchSettling;
u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
@@ -439,19 +451,19 @@ struct modal_eep_4k_header {
} __packed;
struct base_eep_ar9287_header {
- u16 length;
- u16 checksum;
- u16 version;
+ __le16 length;
+ __le16 checksum;
+ __le16 version;
u8 opCapFlags;
u8 eepMisc;
- u16 regDmn[2];
+ __le16 regDmn[2];
u8 macAddr[6];
u8 rxMask;
u8 txMask;
- u16 rfSilent;
- u16 blueToothOptions;
- u16 deviceCap;
- u32 binBuildNumber;
+ __le16 rfSilent;
+ __le16 blueToothOptions;
+ __le16 deviceCap;
+ __le32 binBuildNumber;
u8 deviceType;
u8 openLoopPwrCntl;
int8_t pwrTableOffset;
@@ -461,8 +473,8 @@ struct base_eep_ar9287_header {
} __packed;
struct modal_eep_ar9287_header {
- u32 antCtrlChain[AR9287_MAX_CHAINS];
- u32 antCtrlCommon;
+ __le32 antCtrlChain[AR9287_MAX_CHAINS];
+ __le32 antCtrlCommon;
int8_t antennaGainCh[AR9287_MAX_CHAINS];
u8 switchSettling;
u8 txRxAttenCh[AR9287_MAX_CHAINS];
@@ -653,6 +665,7 @@ struct eeprom_ops {
u16 cfgCtl, u8 twiceAntennaReduction,
u8 powerLimit, bool test);
u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
+ u8 (*get_eepmisc)(struct ath_hw *ah);
};
void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val);
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 5da0826bf1be..b8c0a08066a0 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -20,12 +20,17 @@
static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
{
- return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF);
+ u16 version = le16_to_cpu(ah->eeprom.map4k.baseEepHeader.version);
+
+ return (version & AR5416_EEP_VER_MAJOR_MASK) >>
+ AR5416_EEP_VER_MAJOR_SHIFT;
}
static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
{
- return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF);
+ u16 version = le16_to_cpu(ah->eeprom.map4k.baseEepHeader.version);
+
+ return version & AR5416_EEP_VER_MINOR_MASK;
}
#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
@@ -67,12 +72,12 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
return __ath9k_hw_4k_fill_eeprom(ah);
}
-#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
+#ifdef CONFIG_ATH9K_COMMON_DEBUG
static u32 ath9k_dump_4k_modal_eeprom(char *buf, u32 len, u32 size,
struct modal_eep_4k_header *modal_hdr)
{
- PR_EEP("Chain0 Ant. Control", modal_hdr->antCtrlChain[0]);
- PR_EEP("Ant. Common Control", modal_hdr->antCtrlCommon);
+ PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
+ PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]);
PR_EEP("Switch Settle", modal_hdr->switchSettling);
PR_EEP("Chain0 TxRxAtten", modal_hdr->txRxAttenCh[0]);
@@ -127,6 +132,7 @@ static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
{
struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
struct base_eep_header_4k *pBase = &eep->baseEepHeader;
+ u32 binBuildNumber = le32_to_cpu(pBase->binBuildNumber);
if (!dump_base_hdr) {
len += scnprintf(buf + len, size - len,
@@ -136,12 +142,12 @@ static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
goto out;
}
- PR_EEP("Major Version", pBase->version >> 12);
- PR_EEP("Minor Version", pBase->version & 0xFFF);
- PR_EEP("Checksum", pBase->checksum);
- PR_EEP("Length", pBase->length);
- PR_EEP("RegDomain1", pBase->regDmn[0]);
- PR_EEP("RegDomain2", pBase->regDmn[1]);
+ PR_EEP("Major Version", ath9k_hw_4k_get_eeprom_ver(ah));
+ PR_EEP("Minor Version", ath9k_hw_4k_get_eeprom_rev(ah));
+ PR_EEP("Checksum", le16_to_cpu(pBase->checksum));
+ PR_EEP("Length", le16_to_cpu(pBase->length));
+ PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
+ PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
PR_EEP("TX Mask", pBase->txMask);
PR_EEP("RX Mask", pBase->rxMask);
PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
@@ -154,10 +160,10 @@ static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
AR5416_OPFLAGS_N_5G_HT20));
PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags &
AR5416_OPFLAGS_N_5G_HT40));
- PR_EEP("Big Endian", !!(pBase->eepMisc & 0x01));
- PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF);
- PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF);
- PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF);
+ PR_EEP("Big Endian", !!(pBase->eepMisc & AR5416_EEPMISC_BIG_ENDIAN));
+ PR_EEP("Cal Bin Major Ver", (binBuildNumber >> 24) & 0xFF);
+ PR_EEP("Cal Bin Minor Ver", (binBuildNumber >> 16) & 0xFF);
+ PR_EEP("Cal Bin Build", (binBuildNumber >> 8) & 0xFF);
PR_EEP("TX Gain type", pBase->txGainType);
len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
@@ -189,54 +195,31 @@ static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
return err;
if (need_swap)
- el = swab16(eep->baseEepHeader.length);
+ el = swab16((__force u16)eep->baseEepHeader.length);
else
- el = eep->baseEepHeader.length;
+ el = le16_to_cpu(eep->baseEepHeader.length);
el = min(el / sizeof(u16), SIZE_EEPROM_4K);
if (!ath9k_hw_nvram_validate_checksum(ah, el))
return -EINVAL;
if (need_swap) {
- u32 integer;
- u16 word;
-
- word = swab16(eep->baseEepHeader.length);
- eep->baseEepHeader.length = word;
-
- word = swab16(eep->baseEepHeader.checksum);
- eep->baseEepHeader.checksum = word;
-
- word = swab16(eep->baseEepHeader.version);
- eep->baseEepHeader.version = word;
-
- word = swab16(eep->baseEepHeader.regDmn[0]);
- eep->baseEepHeader.regDmn[0] = word;
-
- word = swab16(eep->baseEepHeader.regDmn[1]);
- eep->baseEepHeader.regDmn[1] = word;
-
- word = swab16(eep->baseEepHeader.rfSilent);
- eep->baseEepHeader.rfSilent = word;
-
- word = swab16(eep->baseEepHeader.blueToothOptions);
- eep->baseEepHeader.blueToothOptions = word;
-
- word = swab16(eep->baseEepHeader.deviceCap);
- eep->baseEepHeader.deviceCap = word;
-
- integer = swab32(eep->modalHeader.antCtrlCommon);
- eep->modalHeader.antCtrlCommon = integer;
-
- for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
- integer = swab32(eep->modalHeader.antCtrlChain[i]);
- eep->modalHeader.antCtrlChain[i] = integer;
- }
-
- for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
- word = swab16(eep->modalHeader.spurChans[i].spurChan);
- eep->modalHeader.spurChans[i].spurChan = word;
- }
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.length);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.checksum);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.version);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[0]);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[1]);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.rfSilent);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.blueToothOptions);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.deviceCap);
+ EEPROM_FIELD_SWAB32(eep->modalHeader.antCtrlCommon);
+
+ for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++)
+ EEPROM_FIELD_SWAB32(eep->modalHeader.antCtrlChain[i]);
+
+ for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++)
+ EEPROM_FIELD_SWAB16(
+ eep->modalHeader.spurChans[i].spurChan);
}
if (!ath9k_hw_nvram_check_version(ah, AR5416_EEP_VER,
@@ -254,9 +237,6 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
struct modal_eep_4k_header *pModal = &eep->modalHeader;
struct base_eep_header_4k *pBase = &eep->baseEepHeader;
- u16 ver_minor;
-
- ver_minor = pBase->version & AR5416_EEP_VER_MINOR_MASK;
switch (param) {
case EEP_NFTHRESH_2:
@@ -268,19 +248,17 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
case EEP_MAC_MSW:
return get_unaligned_be16(pBase->macAddr + 4);
case EEP_REG_0:
- return pBase->regDmn[0];
+ return le16_to_cpu(pBase->regDmn[0]);
case EEP_OP_CAP:
- return pBase->deviceCap;
+ return le16_to_cpu(pBase->deviceCap);
case EEP_OP_MODE:
return pBase->opCapFlags;
case EEP_RF_SILENT:
- return pBase->rfSilent;
+ return le16_to_cpu(pBase->rfSilent);
case EEP_OB_2:
return pModal->ob_0;
case EEP_DB_2:
return pModal->db1_1;
- case EEP_MINOR_REV:
- return ver_minor;
case EEP_TX_MASK:
return pBase->txMask;
case EEP_RX_MASK:
@@ -319,14 +297,12 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
xpdMask = pEepData->modalHeader.xpdGain;
- if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_2) {
+ if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2)
pdGainOverlap_t2 =
pEepData->modalHeader.pdGainOverlap;
- } else {
+ else
pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
- }
pCalBChans = pEepData->calFreqPier2G;
numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS;
@@ -612,10 +588,8 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
memset(ratesArray, 0, sizeof(ratesArray));
- if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_2) {
+ if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2)
ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
- }
ath9k_hw_set_4k_power_per_rate_table(ah, chan,
&ratesArray[0], cfgCtl,
@@ -728,15 +702,14 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
{
ENABLE_REG_RMW_BUFFER(ah);
REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0,
- pModal->antCtrlChain[0], 0);
+ le32_to_cpu(pModal->antCtrlChain[0]), 0);
REG_RMW(ah, AR_PHY_TIMING_CTRL4(0),
SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF),
AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF);
- if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_3) {
+ if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_3) {
txRxAttenLocal = pModal->txRxAttenCh[0];
REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ,
@@ -795,7 +768,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
pModal = &eep->modalHeader;
txRxAttenLocal = 23;
- REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
+ REG_WRITE(ah, AR_PHY_SWITCH_COM, le32_to_cpu(pModal->antCtrlCommon));
/* Single chain for 4K EEPROM*/
ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal);
@@ -1014,16 +987,14 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
pModal->thresh62);
- if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_2) {
+ if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2) {
REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
pModal->txFrameToDataStart);
REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
pModal->txFrameToPaOn);
}
- if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_3) {
+ if (ath9k_hw_4k_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_3) {
if (IS_CHAN_HT40(chan))
REG_RMW_FIELD(ah, AR_PHY_SETTLING,
AR_PHY_SETTLING_SWITCH,
@@ -1061,7 +1032,12 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
{
- return ah->eeprom.map4k.modalHeader.spurChans[i].spurChan;
+ return le16_to_cpu(ah->eeprom.map4k.modalHeader.spurChans[i].spurChan);
+}
+
+static u8 ath9k_hw_4k_get_eepmisc(struct ath_hw *ah)
+{
+ return ah->eeprom.map4k.baseEepHeader.eepMisc;
}
const struct eeprom_ops eep_4k_ops = {
@@ -1073,5 +1049,6 @@ const struct eeprom_ops eep_4k_ops = {
.get_eeprom_rev = ath9k_hw_4k_get_eeprom_rev,
.set_board_values = ath9k_hw_4k_set_board_values,
.set_txpower = ath9k_hw_4k_set_txpower,
- .get_spur_channel = ath9k_hw_4k_get_spur_channel
+ .get_spur_channel = ath9k_hw_4k_get_spur_channel,
+ .get_eepmisc = ath9k_hw_4k_get_eepmisc
};
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index 1a019a39eda1..3caa149b1013 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -22,12 +22,17 @@
static int ath9k_hw_ar9287_get_eeprom_ver(struct ath_hw *ah)
{
- return (ah->eeprom.map9287.baseEepHeader.version >> 12) & 0xF;
+ u16 version = le16_to_cpu(ah->eeprom.map9287.baseEepHeader.version);
+
+ return (version & AR5416_EEP_VER_MAJOR_MASK) >>
+ AR5416_EEP_VER_MAJOR_SHIFT;
}
static int ath9k_hw_ar9287_get_eeprom_rev(struct ath_hw *ah)
{
- return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF;
+ u16 version = le16_to_cpu(ah->eeprom.map9287.baseEepHeader.version);
+
+ return version & AR5416_EEP_VER_MINOR_MASK;
}
static bool __ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
@@ -70,13 +75,13 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
return __ath9k_hw_ar9287_fill_eeprom(ah);
}
-#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
+#ifdef CONFIG_ATH9K_COMMON_DEBUG
static u32 ar9287_dump_modal_eeprom(char *buf, u32 len, u32 size,
struct modal_eep_ar9287_header *modal_hdr)
{
- PR_EEP("Chain0 Ant. Control", modal_hdr->antCtrlChain[0]);
- PR_EEP("Chain1 Ant. Control", modal_hdr->antCtrlChain[1]);
- PR_EEP("Ant. Common Control", modal_hdr->antCtrlCommon);
+ PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
+ PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
+ PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]);
PR_EEP("Chain1 Ant. Gain", modal_hdr->antennaGainCh[1]);
PR_EEP("Switch Settle", modal_hdr->switchSettling);
@@ -123,6 +128,7 @@ static u32 ath9k_hw_ar9287_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
{
struct ar9287_eeprom *eep = &ah->eeprom.map9287;
struct base_eep_ar9287_header *pBase = &eep->baseEepHeader;
+ u32 binBuildNumber = le32_to_cpu(pBase->binBuildNumber);
if (!dump_base_hdr) {
len += scnprintf(buf + len, size - len,
@@ -132,12 +138,12 @@ static u32 ath9k_hw_ar9287_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
goto out;
}
- PR_EEP("Major Version", pBase->version >> 12);
- PR_EEP("Minor Version", pBase->version & 0xFFF);
- PR_EEP("Checksum", pBase->checksum);
- PR_EEP("Length", pBase->length);
- PR_EEP("RegDomain1", pBase->regDmn[0]);
- PR_EEP("RegDomain2", pBase->regDmn[1]);
+ PR_EEP("Major Version", ath9k_hw_ar9287_get_eeprom_ver(ah));
+ PR_EEP("Minor Version", ath9k_hw_ar9287_get_eeprom_rev(ah));
+ PR_EEP("Checksum", le16_to_cpu(pBase->checksum));
+ PR_EEP("Length", le16_to_cpu(pBase->length));
+ PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
+ PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
PR_EEP("TX Mask", pBase->txMask);
PR_EEP("RX Mask", pBase->rxMask);
PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
@@ -150,10 +156,10 @@ static u32 ath9k_hw_ar9287_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
AR5416_OPFLAGS_N_5G_HT20));
PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags &
AR5416_OPFLAGS_N_5G_HT40));
- PR_EEP("Big Endian", !!(pBase->eepMisc & 0x01));
- PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF);
- PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF);
- PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF);
+ PR_EEP("Big Endian", !!(pBase->eepMisc & AR5416_EEPMISC_BIG_ENDIAN));
+ PR_EEP("Cal Bin Major Ver", (binBuildNumber >> 24) & 0xFF);
+ PR_EEP("Cal Bin Minor Ver", (binBuildNumber >> 16) & 0xFF);
+ PR_EEP("Cal Bin Build", (binBuildNumber >> 8) & 0xFF);
PR_EEP("Power Table Offset", pBase->pwrTableOffset);
PR_EEP("OpenLoop Power Ctrl", pBase->openLoopPwrCntl);
@@ -177,8 +183,7 @@ static u32 ath9k_hw_ar9287_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
{
- u32 el, integer;
- u16 word;
+ u32 el;
int i, err;
bool need_swap;
struct ar9287_eeprom *eep = &ah->eeprom.map9287;
@@ -188,51 +193,31 @@ static int ath9k_hw_ar9287_check_eeprom(struct ath_hw *ah)
return err;
if (need_swap)
- el = swab16(eep->baseEepHeader.length);
+ el = swab16((__force u16)eep->baseEepHeader.length);
else
- el = eep->baseEepHeader.length;
+ el = le16_to_cpu(eep->baseEepHeader.length);
el = min(el / sizeof(u16), SIZE_EEPROM_AR9287);
if (!ath9k_hw_nvram_validate_checksum(ah, el))
return -EINVAL;
if (need_swap) {
- word = swab16(eep->baseEepHeader.length);
- eep->baseEepHeader.length = word;
-
- word = swab16(eep->baseEepHeader.checksum);
- eep->baseEepHeader.checksum = word;
-
- word = swab16(eep->baseEepHeader.version);
- eep->baseEepHeader.version = word;
-
- word = swab16(eep->baseEepHeader.regDmn[0]);
- eep->baseEepHeader.regDmn[0] = word;
-
- word = swab16(eep->baseEepHeader.regDmn[1]);
- eep->baseEepHeader.regDmn[1] = word;
-
- word = swab16(eep->baseEepHeader.rfSilent);
- eep->baseEepHeader.rfSilent = word;
-
- word = swab16(eep->baseEepHeader.blueToothOptions);
- eep->baseEepHeader.blueToothOptions = word;
-
- word = swab16(eep->baseEepHeader.deviceCap);
- eep->baseEepHeader.deviceCap = word;
-
- integer = swab32(eep->modalHeader.antCtrlCommon);
- eep->modalHeader.antCtrlCommon = integer;
-
- for (i = 0; i < AR9287_MAX_CHAINS; i++) {
- integer = swab32(eep->modalHeader.antCtrlChain[i]);
- eep->modalHeader.antCtrlChain[i] = integer;
- }
-
- for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
- word = swab16(eep->modalHeader.spurChans[i].spurChan);
- eep->modalHeader.spurChans[i].spurChan = word;
- }
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.length);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.checksum);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.version);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[0]);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[1]);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.rfSilent);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.blueToothOptions);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.deviceCap);
+ EEPROM_FIELD_SWAB32(eep->modalHeader.antCtrlCommon);
+
+ for (i = 0; i < AR9287_MAX_CHAINS; i++)
+ EEPROM_FIELD_SWAB32(eep->modalHeader.antCtrlChain[i]);
+
+ for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++)
+ EEPROM_FIELD_SWAB16(
+ eep->modalHeader.spurChans[i].spurChan);
}
if (!ath9k_hw_nvram_check_version(ah, AR9287_EEP_VER,
@@ -250,9 +235,7 @@ static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah,
struct ar9287_eeprom *eep = &ah->eeprom.map9287;
struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
struct base_eep_ar9287_header *pBase = &eep->baseEepHeader;
- u16 ver_minor;
-
- ver_minor = pBase->version & AR9287_EEP_VER_MINOR_MASK;
+ u16 ver_minor = ath9k_hw_ar9287_get_eeprom_rev(ah);
switch (param) {
case EEP_NFTHRESH_2:
@@ -264,15 +247,13 @@ static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah,
case EEP_MAC_MSW:
return get_unaligned_be16(pBase->macAddr + 4);
case EEP_REG_0:
- return pBase->regDmn[0];
+ return le16_to_cpu(pBase->regDmn[0]);
case EEP_OP_CAP:
- return pBase->deviceCap;
+ return le16_to_cpu(pBase->deviceCap);
case EEP_OP_MODE:
return pBase->opCapFlags;
case EEP_RF_SILENT:
- return pBase->rfSilent;
- case EEP_MINOR_REV:
- return ver_minor;
+ return le16_to_cpu(pBase->rfSilent);
case EEP_TX_MASK:
return pBase->txMask;
case EEP_RX_MASK:
@@ -387,8 +368,7 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
xpdMask = pEepData->modalHeader.xpdGain;
- if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
- AR9287_EEP_MINOR_VER_2)
+ if (ath9k_hw_ar9287_get_eeprom_rev(ah) >= AR9287_EEP_MINOR_VER_2)
pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap;
else
pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
@@ -737,8 +717,7 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
memset(ratesArray, 0, sizeof(ratesArray));
- if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
- AR9287_EEP_MINOR_VER_2)
+ if (ath9k_hw_ar9287_get_eeprom_rev(ah) >= AR9287_EEP_MINOR_VER_2)
ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
ath9k_hw_set_ar9287_power_per_rate_table(ah, chan,
@@ -879,13 +858,13 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah,
pModal = &eep->modalHeader;
- REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
+ REG_WRITE(ah, AR_PHY_SWITCH_COM, le32_to_cpu(pModal->antCtrlCommon));
for (i = 0; i < AR9287_MAX_CHAINS; i++) {
regChainOffset = i * 0x1000;
REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
- pModal->antCtrlChain[i]);
+ le32_to_cpu(pModal->antCtrlChain[i]));
REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
(REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset)
@@ -983,7 +962,14 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah,
static u16 ath9k_hw_ar9287_get_spur_channel(struct ath_hw *ah,
u16 i, bool is2GHz)
{
- return ah->eeprom.map9287.modalHeader.spurChans[i].spurChan;
+ __le16 spur_ch = ah->eeprom.map9287.modalHeader.spurChans[i].spurChan;
+
+ return le16_to_cpu(spur_ch);
+}
+
+static u8 ath9k_hw_ar9287_get_eepmisc(struct ath_hw *ah)
+{
+ return ah->eeprom.map9287.baseEepHeader.eepMisc;
}
const struct eeprom_ops eep_ar9287_ops = {
@@ -995,5 +981,6 @@ const struct eeprom_ops eep_ar9287_ops = {
.get_eeprom_rev = ath9k_hw_ar9287_get_eeprom_rev,
.set_board_values = ath9k_hw_ar9287_set_board_values,
.set_txpower = ath9k_hw_ar9287_set_txpower,
- .get_spur_channel = ath9k_hw_ar9287_get_spur_channel
+ .get_spur_channel = ath9k_hw_ar9287_get_spur_channel,
+ .get_eepmisc = ath9k_hw_ar9287_get_eepmisc
};
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 959682f7909c..56b44fc7a8e6 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -79,12 +79,17 @@ static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
{
- return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
+ u16 version = le16_to_cpu(ah->eeprom.def.baseEepHeader.version);
+
+ return (version & AR5416_EEP_VER_MAJOR_MASK) >>
+ AR5416_EEP_VER_MAJOR_SHIFT;
}
static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
{
- return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
+ u16 version = le16_to_cpu(ah->eeprom.def.baseEepHeader.version);
+
+ return version & AR5416_EEP_VER_MINOR_MASK;
}
#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
@@ -126,14 +131,14 @@ static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
return __ath9k_hw_def_fill_eeprom(ah);
}
-#if defined(CONFIG_ATH9K_DEBUGFS) || defined(CONFIG_ATH9K_HTC_DEBUGFS)
+#ifdef CONFIG_ATH9K_COMMON_DEBUG
static u32 ath9k_def_dump_modal_eeprom(char *buf, u32 len, u32 size,
struct modal_eep_header *modal_hdr)
{
- PR_EEP("Chain0 Ant. Control", modal_hdr->antCtrlChain[0]);
- PR_EEP("Chain1 Ant. Control", modal_hdr->antCtrlChain[1]);
- PR_EEP("Chain2 Ant. Control", modal_hdr->antCtrlChain[2]);
- PR_EEP("Ant. Common Control", modal_hdr->antCtrlCommon);
+ PR_EEP("Chain0 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[0]));
+ PR_EEP("Chain1 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[1]));
+ PR_EEP("Chain2 Ant. Control", le16_to_cpu(modal_hdr->antCtrlChain[2]));
+ PR_EEP("Ant. Common Control", le32_to_cpu(modal_hdr->antCtrlCommon));
PR_EEP("Chain0 Ant. Gain", modal_hdr->antennaGainCh[0]);
PR_EEP("Chain1 Ant. Gain", modal_hdr->antennaGainCh[1]);
PR_EEP("Chain2 Ant. Gain", modal_hdr->antennaGainCh[2]);
@@ -189,9 +194,9 @@ static u32 ath9k_def_dump_modal_eeprom(char *buf, u32 len, u32 size,
PR_EEP("Chain1 OutputBias", modal_hdr->ob_ch1);
PR_EEP("Chain1 DriverBias", modal_hdr->db_ch1);
PR_EEP("LNA Control", modal_hdr->lna_ctl);
- PR_EEP("XPA Bias Freq0", modal_hdr->xpaBiasLvlFreq[0]);
- PR_EEP("XPA Bias Freq1", modal_hdr->xpaBiasLvlFreq[1]);
- PR_EEP("XPA Bias Freq2", modal_hdr->xpaBiasLvlFreq[2]);
+ PR_EEP("XPA Bias Freq0", le16_to_cpu(modal_hdr->xpaBiasLvlFreq[0]));
+ PR_EEP("XPA Bias Freq1", le16_to_cpu(modal_hdr->xpaBiasLvlFreq[1]));
+ PR_EEP("XPA Bias Freq2", le16_to_cpu(modal_hdr->xpaBiasLvlFreq[2]));
return len;
}
@@ -201,6 +206,7 @@ static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
{
struct ar5416_eeprom_def *eep = &ah->eeprom.def;
struct base_eep_header *pBase = &eep->baseEepHeader;
+ u32 binBuildNumber = le32_to_cpu(pBase->binBuildNumber);
if (!dump_base_hdr) {
len += scnprintf(buf + len, size - len,
@@ -214,12 +220,12 @@ static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
goto out;
}
- PR_EEP("Major Version", pBase->version >> 12);
- PR_EEP("Minor Version", pBase->version & 0xFFF);
- PR_EEP("Checksum", pBase->checksum);
- PR_EEP("Length", pBase->length);
- PR_EEP("RegDomain1", pBase->regDmn[0]);
- PR_EEP("RegDomain2", pBase->regDmn[1]);
+ PR_EEP("Major Version", ath9k_hw_def_get_eeprom_ver(ah));
+ PR_EEP("Minor Version", ath9k_hw_def_get_eeprom_rev(ah));
+ PR_EEP("Checksum", le16_to_cpu(pBase->checksum));
+ PR_EEP("Length", le16_to_cpu(pBase->length));
+ PR_EEP("RegDomain1", le16_to_cpu(pBase->regDmn[0]));
+ PR_EEP("RegDomain2", le16_to_cpu(pBase->regDmn[1]));
PR_EEP("TX Mask", pBase->txMask);
PR_EEP("RX Mask", pBase->rxMask);
PR_EEP("Allow 5GHz", !!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
@@ -232,10 +238,10 @@ static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr,
AR5416_OPFLAGS_N_5G_HT20));
PR_EEP("Disable 5Ghz HT40", !!(pBase->opCapFlags &
AR5416_OPFLAGS_N_5G_HT40));
- PR_EEP("Big Endian", !!(pBase->eepMisc & 0x01));
- PR_EEP("Cal Bin Major Ver", (pBase->binBuildNumber >> 24) & 0xFF);
- PR_EEP("Cal Bin Minor Ver", (pBase->binBuildNumber >> 16) & 0xFF);
- PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF);
+ PR_EEP("Big Endian", !!(pBase->eepMisc & AR5416_EEPMISC_BIG_ENDIAN));
+ PR_EEP("Cal Bin Major Ver", (binBuildNumber >> 24) & 0xFF);
+ PR_EEP("Cal Bin Minor Ver", (binBuildNumber >> 16) & 0xFF);
+ PR_EEP("Cal Bin Build", (binBuildNumber >> 8) & 0xFF);
PR_EEP("OpenLoop Power Ctrl", pBase->openLoopPwrCntl);
len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
@@ -268,61 +274,40 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
return err;
if (need_swap)
- el = swab16(eep->baseEepHeader.length);
+ el = swab16((__force u16)eep->baseEepHeader.length);
else
- el = eep->baseEepHeader.length;
+ el = le16_to_cpu(eep->baseEepHeader.length);
el = min(el / sizeof(u16), SIZE_EEPROM_DEF);
if (!ath9k_hw_nvram_validate_checksum(ah, el))
return -EINVAL;
if (need_swap) {
- u32 integer, j;
- u16 word;
-
- word = swab16(eep->baseEepHeader.length);
- eep->baseEepHeader.length = word;
-
- word = swab16(eep->baseEepHeader.checksum);
- eep->baseEepHeader.checksum = word;
-
- word = swab16(eep->baseEepHeader.version);
- eep->baseEepHeader.version = word;
-
- word = swab16(eep->baseEepHeader.regDmn[0]);
- eep->baseEepHeader.regDmn[0] = word;
-
- word = swab16(eep->baseEepHeader.regDmn[1]);
- eep->baseEepHeader.regDmn[1] = word;
-
- word = swab16(eep->baseEepHeader.rfSilent);
- eep->baseEepHeader.rfSilent = word;
-
- word = swab16(eep->baseEepHeader.blueToothOptions);
- eep->baseEepHeader.blueToothOptions = word;
+ u32 j;
- word = swab16(eep->baseEepHeader.deviceCap);
- eep->baseEepHeader.deviceCap = word;
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.length);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.checksum);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.version);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[0]);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.regDmn[1]);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.rfSilent);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.blueToothOptions);
+ EEPROM_FIELD_SWAB16(eep->baseEepHeader.deviceCap);
for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
struct modal_eep_header *pModal =
&eep->modalHeader[j];
- integer = swab32(pModal->antCtrlCommon);
- pModal->antCtrlCommon = integer;
+ EEPROM_FIELD_SWAB32(pModal->antCtrlCommon);
- for (i = 0; i < AR5416_MAX_CHAINS; i++) {
- integer = swab32(pModal->antCtrlChain[i]);
- pModal->antCtrlChain[i] = integer;
- }
- for (i = 0; i < 3; i++) {
- word = swab16(pModal->xpaBiasLvlFreq[i]);
- pModal->xpaBiasLvlFreq[i] = word;
- }
+ for (i = 0; i < AR5416_MAX_CHAINS; i++)
+ EEPROM_FIELD_SWAB32(pModal->antCtrlChain[i]);
- for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
- word = swab16(pModal->spurChans[i].spurChan);
- pModal->spurChans[i].spurChan = word;
- }
+ for (i = 0; i < 3; i++)
+ EEPROM_FIELD_SWAB16(pModal->xpaBiasLvlFreq[i]);
+
+ for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++)
+ EEPROM_FIELD_SWAB16(
+ pModal->spurChans[i].spurChan);
}
}
@@ -332,7 +317,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
/* Enable fixup for AR_AN_TOP2 if necessary */
if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
- ((eep->baseEepHeader.version & 0xff) > 0x0a) &&
+ ((le16_to_cpu(eep->baseEepHeader.version) & 0xff) > 0x0a) &&
(eep->baseEepHeader.pwdclkind == 0))
ah->need_an_top2_fixup = true;
@@ -365,13 +350,13 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
case EEP_MAC_MSW:
return get_unaligned_be16(pBase->macAddr + 4);
case EEP_REG_0:
- return pBase->regDmn[0];
+ return le16_to_cpu(pBase->regDmn[0]);
case EEP_OP_CAP:
- return pBase->deviceCap;
+ return le16_to_cpu(pBase->deviceCap);
case EEP_OP_MODE:
return pBase->opCapFlags;
case EEP_RF_SILENT:
- return pBase->rfSilent;
+ return le16_to_cpu(pBase->rfSilent);
case EEP_OB_5:
return pModal[0].ob;
case EEP_DB_5:
@@ -380,8 +365,6 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
return pModal[1].ob;
case EEP_DB_2:
return pModal[1].db;
- case EEP_MINOR_REV:
- return AR5416_VER_MASK;
case EEP_TX_MASK:
return pBase->txMask;
case EEP_RX_MASK:
@@ -393,27 +376,27 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
case EEP_TXGAIN_TYPE:
return pBase->txGainType;
case EEP_OL_PWRCTRL:
- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_19)
return pBase->openLoopPwrCntl ? true : false;
else
return false;
case EEP_RC_CHAIN_MASK:
- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_19)
return pBase->rcChainMask;
else
return 0;
case EEP_DAC_HPWR_5G:
- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_20)
return pBase->dacHiPwrMode_5G;
else
return 0;
case EEP_FRAC_N_5G:
- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_22)
return pBase->frac_n_5g;
else
return 0;
case EEP_PWR_TABLE_OFFSET:
- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_21)
+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_21)
return pBase->pwr_table_offset;
else
return AR5416_PWR_TABLE_OFFSET_DB;
@@ -436,7 +419,7 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
u8 txRxAttenLocal, int regChainOffset, int i)
{
ENABLE_REG_RMW_BUFFER(ah);
- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_3) {
txRxAttenLocal = pModal->txRxAttenCh[i];
if (AR_SREV_9280_20_OR_LATER(ah)) {
@@ -487,11 +470,13 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
struct ar5416_eeprom_def *eep = &ah->eeprom.def;
int i, regChainOffset;
u8 txRxAttenLocal;
+ u32 antCtrlCommon;
pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
+ antCtrlCommon = le32_to_cpu(pModal->antCtrlCommon);
- REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon & 0xffff);
+ REG_WRITE(ah, AR_PHY_SWITCH_COM, antCtrlCommon & 0xffff);
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
if (AR_SREV_9280(ah)) {
@@ -505,7 +490,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
regChainOffset = i * 0x1000;
REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
- pModal->antCtrlChain[i]);
+ le32_to_cpu(pModal->antCtrlChain[i]));
REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
(REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
@@ -605,7 +590,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
pModal->thresh62);
}
- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2) {
REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
AR_PHY_TX_END_DATA_START,
pModal->txFrameToDataStart);
@@ -613,7 +598,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
pModal->txFrameToPaOn);
}
- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_3) {
if (IS_CHAN_HT40(chan))
REG_RMW_FIELD(ah, AR_PHY_SETTLING,
AR_PHY_SETTLING_SWITCH,
@@ -621,13 +606,14 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
}
if (AR_SREV_9280_20_OR_LATER(ah) &&
- AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+ ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_19)
REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
pModal->miscBits);
- if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
+ if (AR_SREV_9280_20(ah) &&
+ ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_20) {
if (IS_CHAN_2GHZ(chan))
REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
eep->baseEepHeader.dacLpMode);
@@ -651,7 +637,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
static void ath9k_hw_def_set_addac(struct ath_hw *ah,
struct ath9k_channel *chan)
{
-#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
+#define XPA_LVL_FREQ(cnt) (le16_to_cpu(pModal->xpaBiasLvlFreq[cnt]))
struct modal_eep_header *pModal;
struct ar5416_eeprom_def *eep = &ah->eeprom.def;
u8 biaslevel;
@@ -798,8 +784,7 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
pwr_table_offset = ah->eep_ops->get_eeprom(ah, EEP_PWR_TABLE_OFFSET);
- if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_2) {
+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2) {
pdGainOverlap_t2 =
pEepData->modalHeader[modalIdx].pdGainOverlap;
} else {
@@ -1171,10 +1156,8 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
memset(ratesArray, 0, sizeof(ratesArray));
- if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
- AR5416_EEP_MINOR_VER_2) {
+ if (ath9k_hw_def_get_eeprom_rev(ah) >= AR5416_EEP_MINOR_VER_2)
ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
- }
ath9k_hw_set_def_power_per_rate_table(ah, chan,
&ratesArray[0], cfgCtl,
@@ -1314,7 +1297,14 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
{
- return ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan;
+ __le16 spch = ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan;
+
+ return le16_to_cpu(spch);
+}
+
+static u8 ath9k_hw_def_get_eepmisc(struct ath_hw *ah)
+{
+ return ah->eeprom.def.baseEepHeader.eepMisc;
}
const struct eeprom_ops eep_def_ops = {
@@ -1327,5 +1317,6 @@ const struct eeprom_ops eep_def_ops = {
.set_board_values = ath9k_hw_def_set_board_values,
.set_addac = ath9k_hw_def_set_addac,
.set_txpower = ath9k_hw_def_set_txpower,
- .get_spur_channel = ath9k_hw_def_get_spur_channel
+ .get_spur_channel = ath9k_hw_def_get_spur_channel,
+ .get_eepmisc = ath9k_hw_def_get_eepmisc
};
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index a35f78be8dec..8c5c2dd8fa7f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -731,7 +731,7 @@ u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
udelay(100);
if (WARN_ON_ONCE(i >= 100)) {
- ath_err(common, "PLL4 meaurement not done\n");
+ ath_err(common, "PLL4 measurement not done\n");
break;
}
@@ -1603,6 +1603,10 @@ bool ath9k_hw_check_alive(struct ath_hw *ah)
int count = 50;
u32 reg, last_val;
+ /* Check if chip failed to wake up */
+ if (REG_READ(ah, AR_CFG) == 0xdeadbeef)
+ return false;
+
if (AR_SREV_9300(ah))
return !ath9k_hw_detect_mac_hang(ah);
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 20794660d6ae..fa4b3cc1ba22 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -620,6 +620,8 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
/* Will be cleared in ath9k_start() */
set_bit(ATH_OP_INVALID, &common->op_flags);
+ sc->airtime_flags = (AIRTIME_USE_TX | AIRTIME_USE_RX |
+ AIRTIME_USE_NEW_QUEUES);
sc->sc_ah = ah;
sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET);
@@ -667,6 +669,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
common->bt_ant_diversity = 1;
spin_lock_init(&common->cc_lock);
+ spin_lock_init(&sc->intr_lock);
spin_lock_init(&sc->sc_serial_rw);
spin_lock_init(&sc->sc_pm_lock);
spin_lock_init(&sc->chan_lock);
@@ -679,6 +682,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
INIT_WORK(&sc->hw_reset_work, ath_reset_work);
INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
+ INIT_DELAYED_WORK(&sc->hw_check_work, ath_hw_check_work);
ath9k_init_channel_context(sc);
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index 5ad0feeebc86..27c50562dc47 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -20,20 +20,13 @@
* TX polling - checks if the TX engine is stuck somewhere
* and issues a chip reset if so.
*/
-void ath_tx_complete_poll_work(struct work_struct *work)
+static bool ath_tx_complete_check(struct ath_softc *sc)
{
- struct ath_softc *sc = container_of(work, struct ath_softc,
- tx_complete_work.work);
struct ath_txq *txq;
int i;
- bool needreset = false;
-
- if (sc->tx99_state) {
- ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
- "skip tx hung detection on tx99\n");
- return;
- }
+ if (sc->tx99_state)
+ return true;
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
txq = sc->tx.txq_map[i];
@@ -41,25 +34,36 @@ void ath_tx_complete_poll_work(struct work_struct *work)
ath_txq_lock(sc, txq);
if (txq->axq_depth) {
if (txq->axq_tx_inprogress) {
- needreset = true;
ath_txq_unlock(sc, txq);
- break;
- } else {
- txq->axq_tx_inprogress = true;
+ goto reset;
}
+
+ txq->axq_tx_inprogress = true;
}
ath_txq_unlock(sc, txq);
}
- if (needreset) {
- ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
- "tx hung, resetting the chip\n");
- ath9k_queue_reset(sc, RESET_TYPE_TX_HANG);
+ return true;
+
+reset:
+ ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
+ "tx hung, resetting the chip\n");
+ ath9k_queue_reset(sc, RESET_TYPE_TX_HANG);
+ return false;
+
+}
+
+void ath_hw_check_work(struct work_struct *work)
+{
+ struct ath_softc *sc = container_of(work, struct ath_softc,
+ hw_check_work.work);
+
+ if (!ath_hw_check(sc) ||
+ !ath_tx_complete_check(sc))
return;
- }
- ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
- msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT));
+ ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work,
+ msecs_to_jiffies(ATH_HW_CHECK_POLL_INT));
}
/*
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index bba85d1a6cd1..d937c39b3a0b 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -805,21 +805,12 @@ void ath9k_hw_disable_interrupts(struct ath_hw *ah)
}
EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
-void ath9k_hw_enable_interrupts(struct ath_hw *ah)
+static void __ath9k_hw_enable_interrupts(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
u32 sync_default = AR_INTR_SYNC_DEFAULT;
u32 async_mask;
- if (!(ah->imask & ATH9K_INT_GLOBAL))
- return;
-
- if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
- ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
- atomic_read(&ah->intr_ref_cnt));
- return;
- }
-
if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
AR_SREV_9561(ah))
sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
@@ -841,6 +832,39 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)
ath_dbg(common, INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
}
+
+void ath9k_hw_resume_interrupts(struct ath_hw *ah)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+
+ if (!(ah->imask & ATH9K_INT_GLOBAL))
+ return;
+
+ if (atomic_read(&ah->intr_ref_cnt) != 0) {
+ ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
+ atomic_read(&ah->intr_ref_cnt));
+ return;
+ }
+
+ __ath9k_hw_enable_interrupts(ah);
+}
+EXPORT_SYMBOL(ath9k_hw_resume_interrupts);
+
+void ath9k_hw_enable_interrupts(struct ath_hw *ah)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+
+ if (!(ah->imask & ATH9K_INT_GLOBAL))
+ return;
+
+ if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
+ ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
+ atomic_read(&ah->intr_ref_cnt));
+ return;
+ }
+
+ __ath9k_hw_enable_interrupts(ah);
+}
EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
void ath9k_hw_set_interrupts(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 3bab01435a86..770fc11b41d1 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -744,6 +744,7 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah);
void ath9k_hw_enable_interrupts(struct ath_hw *ah);
void ath9k_hw_disable_interrupts(struct ath_hw *ah);
void ath9k_hw_kill_interrupts(struct ath_hw *ah);
+void ath9k_hw_resume_interrupts(struct ath_hw *ah);
void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 59e3bd0f4c20..9e65d14e7b1e 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -70,10 +70,10 @@ static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq,
goto out;
if (txq->mac80211_qnum >= 0) {
- struct list_head *list;
+ struct ath_acq *acq;
- list = &sc->cur_chan->acq[txq->mac80211_qnum];
- if (!list_empty(list))
+ acq = &sc->cur_chan->acq[txq->mac80211_qnum];
+ if (!list_empty(&acq->acq_new) || !list_empty(&acq->acq_old))
pending = true;
}
out:
@@ -181,7 +181,7 @@ void ath9k_ps_restore(struct ath_softc *sc)
static void __ath_cancel_work(struct ath_softc *sc)
{
cancel_work_sync(&sc->paprd_work);
- cancel_delayed_work_sync(&sc->tx_complete_work);
+ cancel_delayed_work_sync(&sc->hw_check_work);
cancel_delayed_work_sync(&sc->hw_pll_work);
#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
@@ -198,7 +198,8 @@ void ath_cancel_work(struct ath_softc *sc)
void ath_restart_work(struct ath_softc *sc)
{
- ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
+ ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work,
+ ATH_HW_CHECK_POLL_INT);
if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9330(sc->sc_ah))
ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work,
@@ -373,21 +374,20 @@ void ath9k_tasklet(unsigned long data)
struct ath_common *common = ath9k_hw_common(ah);
enum ath_reset_type type;
unsigned long flags;
- u32 status = sc->intrstatus;
+ u32 status;
u32 rxmask;
+ spin_lock_irqsave(&sc->intr_lock, flags);
+ status = sc->intrstatus;
+ sc->intrstatus = 0;
+ spin_unlock_irqrestore(&sc->intr_lock, flags);
+
ath9k_ps_wakeup(sc);
spin_lock(&sc->sc_pcu_lock);
if (status & ATH9K_INT_FATAL) {
type = RESET_TYPE_FATAL_INT;
ath9k_queue_reset(sc, type);
-
- /*
- * Increment the ref. counter here so that
- * interrupts are enabled in the reset routine.
- */
- atomic_inc(&ah->intr_ref_cnt);
ath_dbg(common, RESET, "FATAL: Skipping interrupts\n");
goto out;
}
@@ -403,11 +403,6 @@ void ath9k_tasklet(unsigned long data)
type = RESET_TYPE_BB_WATCHDOG;
ath9k_queue_reset(sc, type);
- /*
- * Increment the ref. counter here so that
- * interrupts are enabled in the reset routine.
- */
- atomic_inc(&ah->intr_ref_cnt);
ath_dbg(common, RESET,
"BB_WATCHDOG: Skipping interrupts\n");
goto out;
@@ -420,7 +415,6 @@ void ath9k_tasklet(unsigned long data)
if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) {
type = RESET_TYPE_TX_GTT;
ath9k_queue_reset(sc, type);
- atomic_inc(&ah->intr_ref_cnt);
ath_dbg(common, RESET,
"GTT: Skipping interrupts\n");
goto out;
@@ -477,7 +471,7 @@ void ath9k_tasklet(unsigned long data)
ath9k_btcoex_handle_interrupt(sc, status);
/* re-enable hardware interrupt */
- ath9k_hw_enable_interrupts(ah);
+ ath9k_hw_resume_interrupts(ah);
out:
spin_unlock(&sc->sc_pcu_lock);
ath9k_ps_restore(sc);
@@ -541,7 +535,9 @@ irqreturn_t ath_isr(int irq, void *dev)
return IRQ_NONE;
/* Cache the status */
- sc->intrstatus = status;
+ spin_lock(&sc->intr_lock);
+ sc->intrstatus |= status;
+ spin_unlock(&sc->intr_lock);
if (status & SCHED_INTR)
sched = true;
@@ -587,7 +583,7 @@ chip_reset:
if (sched) {
/* turn off every interrupt */
- ath9k_hw_disable_interrupts(ah);
+ ath9k_hw_kill_interrupts(ah);
tasklet_schedule(&sc->intr_tq);
}
@@ -2091,7 +2087,7 @@ void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop,
int timeout;
bool drain_txq;
- cancel_delayed_work_sync(&sc->tx_complete_work);
+ cancel_delayed_work_sync(&sc->hw_check_work);
if (ah->ah_flags & AH_UNPLUGGED) {
ath_dbg(common, ANY, "Device has been unplugged!\n");
@@ -2129,7 +2125,8 @@ void __ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop,
ath9k_ps_restore(sc);
}
- ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
+ ieee80211_queue_delayed_work(hw, &sc->hw_check_work,
+ ATH_HW_CHECK_POLL_INT);
}
static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index fb4ba27d92b7..d79837fe333f 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1002,6 +1002,70 @@ static void ath9k_apply_ampdu_details(struct ath_softc *sc,
}
}
+static void ath_rx_count_airtime(struct ath_softc *sc,
+ struct ath_rx_status *rs,
+ struct sk_buff *skb)
+{
+ struct ath_node *an;
+ struct ath_acq *acq;
+ struct ath_vif *avp;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ieee80211_sta *sta;
+ struct ieee80211_rx_status *rxs;
+ const struct ieee80211_rate *rate;
+ bool is_sgi, is_40, is_sp;
+ int phy;
+ u16 len = rs->rs_datalen;
+ u32 airtime = 0;
+ u8 tidno, acno;
+
+ if (!ieee80211_is_data(hdr->frame_control))
+ return;
+
+ rcu_read_lock();
+
+ sta = ieee80211_find_sta_by_ifaddr(sc->hw, hdr->addr2, NULL);
+ if (!sta)
+ goto exit;
+ an = (struct ath_node *) sta->drv_priv;
+ avp = (struct ath_vif *) an->vif->drv_priv;
+ tidno = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
+ acno = TID_TO_WME_AC(tidno);
+ acq = &avp->chanctx->acq[acno];
+
+ rxs = IEEE80211_SKB_RXCB(skb);
+
+ is_sgi = !!(rxs->flag & RX_FLAG_SHORT_GI);
+ is_40 = !!(rxs->flag & RX_FLAG_40MHZ);
+ is_sp = !!(rxs->flag & RX_FLAG_SHORTPRE);
+
+ if (!!(rxs->flag & RX_FLAG_HT)) {
+ /* MCS rates */
+
+ airtime += ath_pkt_duration(sc, rxs->rate_idx, len,
+ is_40, is_sgi, is_sp);
+ } else {
+
+ phy = IS_CCK_RATE(rs->rs_rate) ? WLAN_RC_PHY_CCK : WLAN_RC_PHY_OFDM;
+ rate = &common->sbands[rxs->band].bitrates[rxs->rate_idx];
+ airtime += ath9k_hw_computetxtime(ah, phy, rate->bitrate * 100,
+ len, rxs->rate_idx, is_sp);
+ }
+
+ if (!!(sc->airtime_flags & AIRTIME_USE_RX)) {
+ spin_lock_bh(&acq->lock);
+ an->airtime_deficit[acno] -= airtime;
+ if (an->airtime_deficit[acno] <= 0)
+ __ath_tx_queue_tid(sc, ATH_AN_2_TID(an, tidno));
+ spin_unlock_bh(&acq->lock);
+ }
+ ath_debug_airtime(sc, an, airtime, 0);
+exit:
+ rcu_read_unlock();
+}
+
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
{
struct ath_rxbuf *bf;
@@ -1148,6 +1212,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
ath9k_antenna_check(sc, &rs);
ath9k_apply_ampdu_details(sc, &rs, rxs);
ath_debug_rate_stats(sc, &rs, skb);
+ ath_rx_count_airtime(sc, &rs, skb);
hdr = (struct ieee80211_hdr *)skb->data;
if (ieee80211_is_ack(hdr->frame_control))
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 4e2f3ac266c3..396bf05c6bf6 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -97,18 +97,6 @@ static void ath_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
dev_kfree_skb(skb);
}
-void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq)
- __acquires(&txq->axq_lock)
-{
- spin_lock_bh(&txq->axq_lock);
-}
-
-void ath_txq_unlock(struct ath_softc *sc, struct ath_txq *txq)
- __releases(&txq->axq_lock)
-{
- spin_unlock_bh(&txq->axq_lock);
-}
-
void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq)
__releases(&txq->axq_lock)
{
@@ -124,21 +112,44 @@ void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq)
ath_tx_status(hw, skb);
}
-static void ath_tx_queue_tid(struct ath_softc *sc, struct ath_txq *txq,
- struct ath_atx_tid *tid)
+void __ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
- struct list_head *list;
struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv;
struct ath_chanctx *ctx = avp->chanctx;
+ struct ath_acq *acq;
+ struct list_head *tid_list;
+ u8 acno = TID_TO_WME_AC(tid->tidno);
- if (!ctx)
+ if (!ctx || !list_empty(&tid->list))
return;
- list = &ctx->acq[TID_TO_WME_AC(tid->tidno)];
- if (list_empty(&tid->list))
- list_add_tail(&tid->list, list);
+
+ acq = &ctx->acq[acno];
+ if ((sc->airtime_flags & AIRTIME_USE_NEW_QUEUES) &&
+ tid->an->airtime_deficit[acno] > 0)
+ tid_list = &acq->acq_new;
+ else
+ tid_list = &acq->acq_old;
+
+ list_add_tail(&tid->list, tid_list);
}
+void ath_tx_queue_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+{
+ struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv;
+ struct ath_chanctx *ctx = avp->chanctx;
+ struct ath_acq *acq;
+
+ if (!ctx || !list_empty(&tid->list))
+ return;
+
+ acq = &ctx->acq[TID_TO_WME_AC(tid->tidno)];
+ spin_lock_bh(&acq->lock);
+ __ath_tx_queue_tid(sc, tid);
+ spin_unlock_bh(&acq->lock);
+}
+
+
void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue)
{
struct ath_softc *sc = hw->priv;
@@ -153,7 +164,7 @@ void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue)
ath_txq_lock(sc, txq);
tid->has_queued = true;
- ath_tx_queue_tid(sc, txq, tid);
+ ath_tx_queue_tid(sc, tid);
ath_txq_schedule(sc, txq);
ath_txq_unlock(sc, txq);
@@ -660,7 +671,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
skb_queue_splice_tail(&bf_pending, &tid->retry_q);
if (!an->sleeping) {
- ath_tx_queue_tid(sc, txq, tid);
+ ath_tx_queue_tid(sc, tid);
if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
tid->clear_ps_filter = true;
@@ -688,6 +699,33 @@ static bool bf_is_ampdu_not_probing(struct ath_buf *bf)
return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE);
}
+static void ath_tx_count_airtime(struct ath_softc *sc, struct ath_node *an,
+ struct ath_atx_tid *tid, struct ath_buf *bf,
+ struct ath_tx_status *ts)
+{
+ struct ath_txq *txq = tid->txq;
+ u32 airtime = 0;
+ int i;
+
+ airtime += ts->duration * (ts->ts_longretry + 1);
+ for(i = 0; i < ts->ts_rateindex; i++) {
+ int rate_dur = ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc, i);
+ airtime += rate_dur * bf->rates[i].count;
+ }
+
+ if (sc->airtime_flags & AIRTIME_USE_TX) {
+ int q = txq->mac80211_qnum;
+ struct ath_acq *acq = &sc->cur_chan->acq[q];
+
+ spin_lock_bh(&acq->lock);
+ an->airtime_deficit[q] -= airtime;
+ if (an->airtime_deficit[q] <= 0)
+ __ath_tx_queue_tid(sc, tid);
+ spin_unlock_bh(&acq->lock);
+ }
+ ath_debug_airtime(sc, an, 0, airtime);
+}
+
static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
struct ath_tx_status *ts, struct ath_buf *bf,
struct list_head *bf_head)
@@ -715,6 +753,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
if (sta) {
struct ath_node *an = (struct ath_node *)sta->drv_priv;
tid = ath_get_skb_tid(sc, an, bf->bf_mpdu);
+ ath_tx_count_airtime(sc, an, tid, bf, ts);
if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
tid->clear_ps_filter = true;
}
@@ -1068,8 +1107,8 @@ finish:
* width - 0 for 20 MHz, 1 for 40 MHz
* half_gi - to use 4us v/s 3.6 us for symbol time
*/
-static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen,
- int width, int half_gi, bool shortPreamble)
+u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen,
+ int width, int half_gi, bool shortPreamble)
{
u32 nbits, nsymbits, duration, nsymbols;
int streams;
@@ -1151,8 +1190,9 @@ static u8 ath_get_rate_txpower(struct ath_softc *sc, struct ath_buf *bf,
if (is_40) {
u8 power_ht40delta;
struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+ u16 eeprom_rev = ah->eep_ops->get_eeprom_rev(ah);
- if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
+ if (eeprom_rev >= AR5416_EEP_MINOR_VER_2) {
bool is_2ghz;
struct modal_eep_header *pmodal;
@@ -1467,7 +1507,7 @@ ath_tx_form_burst(struct ath_softc *sc, struct ath_txq *txq,
}
static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
- struct ath_atx_tid *tid, bool *stop)
+ struct ath_atx_tid *tid)
{
struct ath_buf *bf;
struct ieee80211_tx_info *tx_info;
@@ -1489,7 +1529,6 @@ static bool ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
if ((aggr && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) ||
(!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) {
__skb_queue_tail(&tid->retry_q, bf->bf_mpdu);
- *stop = true;
return false;
}
@@ -1613,7 +1652,7 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
ath_txq_lock(sc, txq);
tid->clear_ps_filter = true;
if (ath_tid_has_buffered(tid)) {
- ath_tx_queue_tid(sc, txq, tid);
+ ath_tx_queue_tid(sc, tid);
ath_txq_schedule(sc, txq);
}
ath_txq_unlock_complete(sc, txq);
@@ -1912,9 +1951,10 @@ void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ath_atx_tid *tid, *last_tid;
+ struct ath_atx_tid *tid;
struct list_head *tid_list;
- bool sent = false;
+ struct ath_acq *acq;
+ bool active = AIRTIME_ACTIVE(sc->airtime_flags);
if (txq->mac80211_qnum < 0)
return;
@@ -1923,48 +1963,55 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
return;
spin_lock_bh(&sc->chan_lock);
- tid_list = &sc->cur_chan->acq[txq->mac80211_qnum];
-
- if (list_empty(tid_list)) {
- spin_unlock_bh(&sc->chan_lock);
- return;
- }
-
rcu_read_lock();
+ acq = &sc->cur_chan->acq[txq->mac80211_qnum];
- last_tid = list_entry(tid_list->prev, struct ath_atx_tid, list);
- while (!list_empty(tid_list)) {
- bool stop = false;
-
- if (sc->cur_chan->stopped)
- break;
-
- tid = list_first_entry(tid_list, struct ath_atx_tid, list);
- list_del_init(&tid->list);
+ if (sc->cur_chan->stopped)
+ goto out;
- if (ath_tx_sched_aggr(sc, txq, tid, &stop))
- sent = true;
+begin:
+ tid_list = &acq->acq_new;
+ if (list_empty(tid_list)) {
+ tid_list = &acq->acq_old;
+ if (list_empty(tid_list))
+ goto out;
+ }
+ tid = list_first_entry(tid_list, struct ath_atx_tid, list);
- /*
- * add tid to round-robin queue if more frames
- * are pending for the tid
- */
- if (ath_tid_has_buffered(tid))
- ath_tx_queue_tid(sc, txq, tid);
+ if (active && tid->an->airtime_deficit[txq->mac80211_qnum] <= 0) {
+ spin_lock_bh(&acq->lock);
+ tid->an->airtime_deficit[txq->mac80211_qnum] += ATH_AIRTIME_QUANTUM;
+ list_move_tail(&tid->list, &acq->acq_old);
+ spin_unlock_bh(&acq->lock);
+ goto begin;
+ }
- if (stop)
- break;
+ if (!ath_tid_has_buffered(tid)) {
+ spin_lock_bh(&acq->lock);
+ if ((tid_list == &acq->acq_new) && !list_empty(&acq->acq_old))
+ list_move_tail(&tid->list, &acq->acq_old);
+ else {
+ list_del_init(&tid->list);
+ }
+ spin_unlock_bh(&acq->lock);
+ goto begin;
+ }
- if (tid == last_tid) {
- if (!sent)
- break;
- sent = false;
- last_tid = list_entry(tid_list->prev,
- struct ath_atx_tid, list);
+ /*
+ * If we succeed in scheduling something, immediately restart to make
+ * sure we keep the HW busy.
+ */
+ if(ath_tx_sched_aggr(sc, txq, tid)) {
+ if (!active) {
+ spin_lock_bh(&acq->lock);
+ list_move_tail(&tid->list, &acq->acq_old);
+ spin_unlock_bh(&acq->lock);
}
+ goto begin;
}
+out:
rcu_read_unlock();
spin_unlock_bh(&sc->chan_lock);
}
@@ -2805,8 +2852,6 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
return error;
}
- INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
-
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
error = ath_tx_edma_init(sc);
@@ -2818,6 +2863,9 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
struct ath_atx_tid *tid;
int tidno, acno;
+ for (acno = 0; acno < IEEE80211_NUM_ACS; acno++)
+ an->airtime_deficit[acno] = ATH_AIRTIME_QUANTUM;
+
for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) {
tid = ath_node_to_tid(an, tidno);
tid->an = an;