mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 22:51:35 +00:00
Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
ath.git patches for 4.11. Major changes: ath9k * cleanup eeprom endian handling * add airtime fairness scheduling ath10k * fix issues for new QCA9377 firmware version * support dev_coredump() for firmware crash dump * enable channel 169 on 5 GHz band
This commit is contained in:
commit
50913e32c6
@ -694,8 +694,11 @@ static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
|
||||
"boot get otp board id result 0x%08x board_id %d chip_id %d\n",
|
||||
result, board_id, chip_id);
|
||||
|
||||
if ((result & ATH10K_BMI_BOARD_ID_STATUS_MASK) != 0)
|
||||
if ((result & ATH10K_BMI_BOARD_ID_STATUS_MASK) != 0 ||
|
||||
(board_id == 0)) {
|
||||
ath10k_warn(ar, "board id is not exist in otp, ignore it\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
ar->id.bmi_ids_valid = true;
|
||||
ar->id.bmi_board_id = board_id;
|
||||
@ -1510,6 +1513,7 @@ static int ath10k_init_hw_params(struct ath10k *ar)
|
||||
static void ath10k_core_restart(struct work_struct *work)
|
||||
{
|
||||
struct ath10k *ar = container_of(work, struct ath10k, restart_work);
|
||||
int ret;
|
||||
|
||||
set_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);
|
||||
|
||||
@ -1561,6 +1565,11 @@ static void ath10k_core_restart(struct work_struct *work)
|
||||
}
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
ret = ath10k_debug_fw_devcoredump(ar);
|
||||
if (ret)
|
||||
ath10k_warn(ar, "failed to send firmware crash dump via devcoredump: %d",
|
||||
ret);
|
||||
}
|
||||
|
||||
static void ath10k_core_set_coverage_class_work(struct work_struct *work)
|
||||
|
@ -46,7 +46,7 @@
|
||||
#define WMI_READY_TIMEOUT (5 * HZ)
|
||||
#define ATH10K_FLUSH_TIMEOUT_HZ (5 * HZ)
|
||||
#define ATH10K_CONNECTION_LOSS_HZ (3 * HZ)
|
||||
#define ATH10K_NUM_CHANS 39
|
||||
#define ATH10K_NUM_CHANS 40
|
||||
|
||||
/* Antenna noise floor */
|
||||
#define ATH10K_DEFAULT_NOISE_FLOOR -95
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/devcoredump.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "debug.h"
|
||||
@ -721,7 +722,8 @@ ath10k_debug_get_new_fw_crash_data(struct ath10k *ar)
|
||||
}
|
||||
EXPORT_SYMBOL(ath10k_debug_get_new_fw_crash_data);
|
||||
|
||||
static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar)
|
||||
static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar,
|
||||
bool mark_read)
|
||||
{
|
||||
struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data;
|
||||
struct ath10k_dump_file_data *dump_data;
|
||||
@ -790,19 +792,54 @@ static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar)
|
||||
sizeof(crash_data->registers));
|
||||
sofar += sizeof(*dump_tlv) + sizeof(crash_data->registers);
|
||||
|
||||
ar->debug.fw_crash_data->crashed_since_read = false;
|
||||
ar->debug.fw_crash_data->crashed_since_read = !mark_read;
|
||||
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
return dump_data;
|
||||
}
|
||||
|
||||
int ath10k_debug_fw_devcoredump(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_dump_file_data *dump;
|
||||
void *dump_ptr;
|
||||
u32 dump_len;
|
||||
|
||||
/* To keep the dump file available also for debugfs don't mark the
|
||||
* file read, only debugfs should do that.
|
||||
*/
|
||||
dump = ath10k_build_dump_file(ar, false);
|
||||
if (!dump) {
|
||||
ath10k_warn(ar, "no crash dump data found for devcoredump");
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
/* Make a copy of the dump file for dev_coredumpv() as during the
|
||||
* transition period we need to own the original file. Once
|
||||
* fw_crash_dump debugfs file is removed no need to have a copy
|
||||
* anymore.
|
||||
*/
|
||||
dump_len = le32_to_cpu(dump->len);
|
||||
dump_ptr = vzalloc(dump_len);
|
||||
|
||||
if (!dump_ptr)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(dump_ptr, dump, dump_len);
|
||||
|
||||
dev_coredumpv(ar->dev, dump_ptr, dump_len, GFP_KERNEL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_fw_crash_dump_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct ath10k *ar = inode->i_private;
|
||||
struct ath10k_dump_file_data *dump;
|
||||
|
||||
dump = ath10k_build_dump_file(ar);
|
||||
ath10k_warn(ar, "fw_crash_dump debugfs file is deprecated, please use /sys/class/devcoredump instead.");
|
||||
|
||||
dump = ath10k_build_dump_file(ar, true);
|
||||
if (!dump)
|
||||
return -ENODATA;
|
||||
|
||||
|
@ -84,6 +84,9 @@ struct ath10k_fw_crash_data *
|
||||
ath10k_debug_get_new_fw_crash_data(struct ath10k *ar);
|
||||
|
||||
void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len);
|
||||
|
||||
int ath10k_debug_fw_devcoredump(struct ath10k *ar);
|
||||
|
||||
#define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++)
|
||||
|
||||
void ath10k_debug_get_et_strings(struct ieee80211_hw *hw,
|
||||
@ -166,6 +169,11 @@ static inline u32 ath10k_debug_get_fw_dbglog_level(struct ath10k *ar)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ath10k_debug_fw_devcoredump(struct ath10k *ar)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ATH10K_DFS_STAT_INC(ar, c) do { } while (0)
|
||||
|
||||
#define ath10k_debug_get_et_strings NULL
|
||||
|
@ -239,6 +239,7 @@ static void ath10k_htt_tx_free_cont_txbuf(struct ath10k_htt *htt)
|
||||
|
||||
size = htt->max_num_pending_tx * sizeof(struct ath10k_htt_txbuf);
|
||||
dma_free_coherent(ar->dev, size, htt->txbuf.vaddr, htt->txbuf.paddr);
|
||||
htt->txbuf.vaddr = NULL;
|
||||
}
|
||||
|
||||
static int ath10k_htt_tx_alloc_cont_txbuf(struct ath10k_htt *htt)
|
||||
@ -268,6 +269,7 @@ static void ath10k_htt_tx_free_cont_frag_desc(struct ath10k_htt *htt)
|
||||
size,
|
||||
htt->frag_desc.vaddr,
|
||||
htt->frag_desc.paddr);
|
||||
htt->frag_desc.vaddr = NULL;
|
||||
}
|
||||
|
||||
static int ath10k_htt_tx_alloc_cont_frag_desc(struct ath10k_htt *htt)
|
||||
|
@ -512,7 +512,7 @@ ath10k_rx_desc_get_l3_pad_bytes(struct ath10k_hw_params *hw,
|
||||
/* Target specific defines for WMI-TLV firmware */
|
||||
#define TARGET_TLV_NUM_VDEVS 4
|
||||
#define TARGET_TLV_NUM_STATIONS 32
|
||||
#define TARGET_TLV_NUM_PEERS 35
|
||||
#define TARGET_TLV_NUM_PEERS 33
|
||||
#define TARGET_TLV_NUM_TDLS_VDEVS 1
|
||||
#define TARGET_TLV_NUM_TIDS ((TARGET_TLV_NUM_PEERS) * 2)
|
||||
#define TARGET_TLV_NUM_MSDU_DESC (1024 + 32)
|
||||
|
@ -1227,6 +1227,36 @@ static int ath10k_monitor_recalc(struct ath10k *ar)
|
||||
return ath10k_monitor_stop(ar);
|
||||
}
|
||||
|
||||
static bool ath10k_mac_can_set_cts_prot(struct ath10k_vif *arvif)
|
||||
{
|
||||
struct ath10k *ar = arvif->ar;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
if (!arvif->is_started) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "defer cts setup, vdev is not ready yet\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ath10k_mac_set_cts_prot(struct ath10k_vif *arvif)
|
||||
{
|
||||
struct ath10k *ar = arvif->ar;
|
||||
u32 vdev_param;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
vdev_param = ar->wmi.vdev_param->protection_mode;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_protection %d\n",
|
||||
arvif->vdev_id, arvif->use_cts_prot);
|
||||
|
||||
return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
|
||||
arvif->use_cts_prot ? 1 : 0);
|
||||
}
|
||||
|
||||
static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
|
||||
{
|
||||
struct ath10k *ar = arvif->ar;
|
||||
@ -1245,6 +1275,9 @@ static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
|
||||
rts_cts |= SM(WMI_RTSCTS_FOR_SECOND_RATESERIES,
|
||||
WMI_RTSCTS_PROFILE);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d recalc rts/cts prot %d\n",
|
||||
arvif->vdev_id, rts_cts);
|
||||
|
||||
return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
|
||||
rts_cts);
|
||||
}
|
||||
@ -3495,7 +3528,6 @@ static int ath10k_mac_tx_submit(struct ath10k *ar,
|
||||
*/
|
||||
static int ath10k_mac_tx(struct ath10k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
enum ath10k_hw_txrx_mode txmode,
|
||||
enum ath10k_mac_tx_path txpath,
|
||||
struct sk_buff *skb)
|
||||
@ -3637,7 +3669,7 @@ void ath10k_offchan_tx_work(struct work_struct *work)
|
||||
txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
|
||||
txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
|
||||
|
||||
ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
|
||||
ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to transmit offchannel frame: %d\n",
|
||||
ret);
|
||||
@ -3824,7 +3856,7 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
|
||||
spin_unlock_bh(&ar->htt.tx_lock);
|
||||
}
|
||||
|
||||
ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
|
||||
ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb);
|
||||
if (unlikely(ret)) {
|
||||
ath10k_warn(ar, "failed to push frame: %d\n", ret);
|
||||
|
||||
@ -4105,7 +4137,7 @@ static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
|
||||
spin_unlock_bh(&ar->htt.tx_lock);
|
||||
}
|
||||
|
||||
ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
|
||||
ret = ath10k_mac_tx(ar, vif, txmode, txpath, skb);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to transmit frame: %d\n", ret);
|
||||
if (is_htt) {
|
||||
@ -4669,7 +4701,8 @@ static int ath10k_mac_txpower_recalc(struct ath10k *ar)
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
list_for_each_entry(arvif, &ar->arvifs, list) {
|
||||
WARN_ON(arvif->txpower < 0);
|
||||
if (arvif->txpower <= 0)
|
||||
continue;
|
||||
|
||||
if (txpower == -1)
|
||||
txpower = arvif->txpower;
|
||||
@ -4677,8 +4710,8 @@ static int ath10k_mac_txpower_recalc(struct ath10k *ar)
|
||||
txpower = min(txpower, arvif->txpower);
|
||||
}
|
||||
|
||||
if (WARN_ON(txpower == -1))
|
||||
return -EINVAL;
|
||||
if (txpower == -1)
|
||||
return 0;
|
||||
|
||||
ret = ath10k_mac_txpower_setup(ar, txpower);
|
||||
if (ret) {
|
||||
@ -5194,6 +5227,10 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
|
||||
ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
|
||||
}
|
||||
|
||||
ret = ath10k_mac_txpower_recalc(ar);
|
||||
if (ret)
|
||||
ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
|
||||
|
||||
spin_lock_bh(&ar->htt.tx_lock);
|
||||
ath10k_mac_vif_tx_unlock_all(arvif);
|
||||
spin_unlock_bh(&ar->htt.tx_lock);
|
||||
@ -5328,20 +5365,18 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
|
||||
|
||||
if (changed & BSS_CHANGED_ERP_CTS_PROT) {
|
||||
arvif->use_cts_prot = info->use_cts_prot;
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
|
||||
arvif->vdev_id, info->use_cts_prot);
|
||||
|
||||
ret = ath10k_recalc_rtscts_prot(arvif);
|
||||
if (ret)
|
||||
ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
|
||||
vdev_param = ar->wmi.vdev_param->protection_mode;
|
||||
ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
|
||||
info->use_cts_prot ? 1 : 0);
|
||||
if (ret)
|
||||
ath10k_warn(ar, "failed to set protection mode %d on vdev %i: %d\n",
|
||||
info->use_cts_prot, arvif->vdev_id, ret);
|
||||
if (ath10k_mac_can_set_cts_prot(arvif)) {
|
||||
ret = ath10k_mac_set_cts_prot(arvif);
|
||||
if (ret)
|
||||
ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_ERP_SLOT) {
|
||||
@ -7364,6 +7399,13 @@ ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
|
||||
arvif->is_up = true;
|
||||
}
|
||||
|
||||
if (ath10k_mac_can_set_cts_prot(arvif)) {
|
||||
ret = ath10k_mac_set_cts_prot(arvif);
|
||||
if (ret)
|
||||
ath10k_warn(ar, "failed to set cts protection for vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
}
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return 0;
|
||||
|
||||
@ -7548,6 +7590,7 @@ static const struct ieee80211_channel ath10k_5ghz_channels[] = {
|
||||
CHAN5G(157, 5785, 0),
|
||||
CHAN5G(161, 5805, 0),
|
||||
CHAN5G(165, 5825, 0),
|
||||
CHAN5G(169, 5845, 0),
|
||||
};
|
||||
|
||||
struct ath10k *ath10k_mac_create(size_t priv_size)
|
||||
|
@ -1973,7 +1973,7 @@ static int ath10k_pci_get_num_banks(struct ath10k *ar)
|
||||
}
|
||||
break;
|
||||
case QCA9377_1_0_DEVICE_ID:
|
||||
return 2;
|
||||
return 4;
|
||||
}
|
||||
|
||||
ath10k_warn(ar, "unknown number of banks, assuming 1\n");
|
||||
@ -3132,7 +3132,7 @@ int ath10k_pci_setup_resource(struct ath10k *ar)
|
||||
setup_timer(&ar_pci->rx_post_retry, ath10k_pci_rx_replenish_retry,
|
||||
(unsigned long)ar);
|
||||
|
||||
if (QCA_REV_6174(ar))
|
||||
if (QCA_REV_6174(ar) || QCA_REV_9377(ar))
|
||||
ath10k_pci_override_ce_config(ar);
|
||||
|
||||
ret = ath10k_pci_alloc_pipes(ar);
|
||||
|
@ -1105,8 +1105,10 @@ static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
|
||||
struct ath10k_fw_stats_pdev *dst;
|
||||
|
||||
src = data;
|
||||
if (data_len < sizeof(*src))
|
||||
if (data_len < sizeof(*src)) {
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
data += sizeof(*src);
|
||||
data_len -= sizeof(*src);
|
||||
@ -1126,8 +1128,10 @@ static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
|
||||
struct ath10k_fw_stats_vdev *dst;
|
||||
|
||||
src = data;
|
||||
if (data_len < sizeof(*src))
|
||||
if (data_len < sizeof(*src)) {
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
data += sizeof(*src);
|
||||
data_len -= sizeof(*src);
|
||||
@ -1145,8 +1149,10 @@ static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar,
|
||||
struct ath10k_fw_stats_peer *dst;
|
||||
|
||||
src = data;
|
||||
if (data_len < sizeof(*src))
|
||||
if (data_len < sizeof(*src)) {
|
||||
kfree(tb);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
data += sizeof(*src);
|
||||
data_len -= sizeof(*src);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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,6 +69,9 @@
|
||||
#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 \
|
||||
|
@ -112,6 +112,8 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
|
||||
#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,
|
||||
@ -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;
|
||||
@ -1005,6 +1033,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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
@ -71,8 +76,8 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
|
||||
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;
|
||||
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);
|
||||
|
||||
word = swab16(eep->baseEepHeader.length);
|
||||
eep->baseEepHeader.length = word;
|
||||
for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++)
|
||||
EEPROM_FIELD_SWAB32(eep->modalHeader.antCtrlChain[i]);
|
||||
|
||||
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;
|
||||
}
|
||||
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
|
||||
};
|
||||
|
@ -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)
|
||||
@ -74,9 +79,9 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah)
|
||||
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;
|
||||
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);
|
||||
|
||||
word = swab16(eep->baseEepHeader.checksum);
|
||||
eep->baseEepHeader.checksum = word;
|
||||
for (i = 0; i < AR9287_MAX_CHAINS; i++)
|
||||
EEPROM_FIELD_SWAB32(eep->modalHeader.antCtrlChain[i]);
|
||||
|
||||
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;
|
||||
}
|
||||
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
|
||||
};
|
||||
|
@ -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))
|
||||
@ -130,10 +135,10 @@ static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
|
||||
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;
|
||||
u32 j;
|
||||
|
||||
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;
|
||||
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
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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))
|
||||
|
@ -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,53 @@ 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_txq *txq,
|
||||
struct ath_buf *bf, struct ath_tx_status *ts)
|
||||
{
|
||||
struct ath_node *an;
|
||||
struct ath_acq *acq = &sc->cur_chan->acq[txq->mac80211_qnum];
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct ieee80211_hw *hw = sc->hw;
|
||||
struct ieee80211_tx_rate rates[4];
|
||||
struct ieee80211_sta *sta;
|
||||
int i;
|
||||
u32 airtime = 0;
|
||||
|
||||
skb = bf->bf_mpdu;
|
||||
if(!skb)
|
||||
return;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
memcpy(rates, bf->rates, sizeof(rates));
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
|
||||
if(!sta)
|
||||
goto exit;
|
||||
|
||||
|
||||
an = (struct ath_node *) sta->drv_priv;
|
||||
|
||||
airtime += ts->duration * (ts->ts_longretry + 1);
|
||||
|
||||
for(i=0; i < ts->ts_rateindex; i++)
|
||||
airtime += ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc, i) * rates[i].count;
|
||||
|
||||
if (!!(sc->airtime_flags & AIRTIME_USE_TX)) {
|
||||
spin_lock_bh(&acq->lock);
|
||||
an->airtime_deficit[txq->mac80211_qnum] -= airtime;
|
||||
if (an->airtime_deficit[txq->mac80211_qnum] <= 0)
|
||||
__ath_tx_queue_tid(sc, ath_get_skb_tid(sc, an, skb));
|
||||
spin_unlock_bh(&acq->lock);
|
||||
}
|
||||
ath_debug_airtime(sc, an, 0, airtime);
|
||||
|
||||
exit:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
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)
|
||||
@ -709,6 +767,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
|
||||
|
||||
ts->duration = ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc,
|
||||
ts->ts_rateindex);
|
||||
ath_tx_count_airtime(sc, txq, bf, ts);
|
||||
|
||||
hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data;
|
||||
sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2);
|
||||
@ -1068,8 +1127,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 +1210,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 +1527,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 +1549,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 +1672,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 +1971,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 +1983,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)
|
||||
goto out;
|
||||
|
||||
if (sc->cur_chan->stopped)
|
||||
break;
|
||||
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);
|
||||
|
||||
tid = list_first_entry(tid_list, struct ath_atx_tid, list);
|
||||
list_del_init(&tid->list);
|
||||
|
||||
if (ath_tx_sched_aggr(sc, txq, tid, &stop))
|
||||
sent = true;
|
||||
|
||||
/*
|
||||
* 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 (stop)
|
||||
break;
|
||||
|
||||
if (tid == last_tid) {
|
||||
if (!sent)
|
||||
break;
|
||||
|
||||
sent = false;
|
||||
last_tid = list_entry(tid_list->prev,
|
||||
struct ath_atx_tid, list);
|
||||
}
|
||||
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 (!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 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);
|
||||
}
|
||||
@ -2818,6 +2885,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;
|
||||
|
Loading…
Reference in New Issue
Block a user