Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
ath.git patches for 4.8. Major changes: ath9k * implement temperature compensation support for AR9003+ ath10k * disable wake_tx_queue() mac80211 op for older devices to workaround throughput regression
This commit is contained in:
commit
593463ff1c
@ -676,6 +676,7 @@ struct ath10k_fw_components {
|
|||||||
struct ath10k {
|
struct ath10k {
|
||||||
struct ath_common ath_common;
|
struct ath_common ath_common;
|
||||||
struct ieee80211_hw *hw;
|
struct ieee80211_hw *hw;
|
||||||
|
struct ieee80211_ops *ops;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
u8 mac_addr[ETH_ALEN];
|
u8 mac_addr[ETH_ALEN];
|
||||||
|
|
||||||
|
@ -7506,21 +7506,32 @@ static const struct ieee80211_channel ath10k_5ghz_channels[] = {
|
|||||||
struct ath10k *ath10k_mac_create(size_t priv_size)
|
struct ath10k *ath10k_mac_create(size_t priv_size)
|
||||||
{
|
{
|
||||||
struct ieee80211_hw *hw;
|
struct ieee80211_hw *hw;
|
||||||
|
struct ieee80211_ops *ops;
|
||||||
struct ath10k *ar;
|
struct ath10k *ar;
|
||||||
|
|
||||||
hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops);
|
ops = kmemdup(&ath10k_ops, sizeof(ath10k_ops), GFP_KERNEL);
|
||||||
if (!hw)
|
if (!ops)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, ops);
|
||||||
|
if (!hw) {
|
||||||
|
kfree(ops);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ar = hw->priv;
|
ar = hw->priv;
|
||||||
ar->hw = hw;
|
ar->hw = hw;
|
||||||
|
ar->ops = ops;
|
||||||
|
|
||||||
return ar;
|
return ar;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ath10k_mac_destroy(struct ath10k *ar)
|
void ath10k_mac_destroy(struct ath10k *ar)
|
||||||
{
|
{
|
||||||
|
struct ieee80211_ops *ops = ar->ops;
|
||||||
|
|
||||||
ieee80211_free_hw(ar->hw);
|
ieee80211_free_hw(ar->hw);
|
||||||
|
kfree(ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct ieee80211_iface_limit ath10k_if_limits[] = {
|
static const struct ieee80211_iface_limit ath10k_if_limits[] = {
|
||||||
@ -7954,6 +7965,15 @@ int ath10k_mac_register(struct ath10k *ar)
|
|||||||
ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
|
ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Current wake_tx_queue implementation imposes a significant
|
||||||
|
* performance penalty in some setups. The tx scheduling code needs
|
||||||
|
* more work anyway so disable the wake_tx_queue unless firmware
|
||||||
|
* supports the pull-push mechanism.
|
||||||
|
*/
|
||||||
|
if (!test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL,
|
||||||
|
ar->running_fw->fw_file.fw_features))
|
||||||
|
ar->ops->wake_tx_queue = NULL;
|
||||||
|
|
||||||
ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
|
ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
|
||||||
ath10k_reg_notifier);
|
ath10k_reg_notifier);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -847,8 +847,6 @@ static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
|
|||||||
|
|
||||||
up(&ar->sem);
|
up(&ar->sem);
|
||||||
|
|
||||||
vif->sme_state = SME_DISCONNECTED;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1111,7 +1109,8 @@ void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
|
|||||||
|
|
||||||
cfg80211_chandef_create(&chandef,
|
cfg80211_chandef_create(&chandef,
|
||||||
ieee80211_get_channel(vif->ar->wiphy, freq),
|
ieee80211_get_channel(vif->ar->wiphy, freq),
|
||||||
(mode == WMI_11G_HT20) ?
|
(mode == WMI_11G_HT20 &&
|
||||||
|
ath6kl_band_2ghz.ht_cap.ht_supported) ?
|
||||||
NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
|
NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
|
||||||
|
|
||||||
mutex_lock(&vif->wdev.mtx);
|
mutex_lock(&vif->wdev.mtx);
|
||||||
@ -2978,6 +2977,7 @@ static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
|
|||||||
|
|
||||||
ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
|
ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
|
||||||
clear_bit(CONNECTED, &vif->flags);
|
clear_bit(CONNECTED, &vif->flags);
|
||||||
|
netif_carrier_off(vif->ndev);
|
||||||
|
|
||||||
/* Restore ht setting in firmware */
|
/* Restore ht setting in firmware */
|
||||||
return ath6kl_restore_htcap(vif);
|
return ath6kl_restore_htcap(vif);
|
||||||
|
@ -1401,6 +1401,10 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pad_before_data_start =
|
||||||
|
(le16_to_cpu(dhdr->info3) >> WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT)
|
||||||
|
& WMI_DATA_HDR_PAD_BEFORE_DATA_MASK;
|
||||||
|
|
||||||
/* Get the Power save state of the STA */
|
/* Get the Power save state of the STA */
|
||||||
if (vif->nw_type == AP_NETWORK) {
|
if (vif->nw_type == AP_NETWORK) {
|
||||||
meta_type = wmi_data_hdr_get_meta(dhdr);
|
meta_type = wmi_data_hdr_get_meta(dhdr);
|
||||||
@ -1408,7 +1412,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
|
|||||||
ps_state = !!((dhdr->info >> WMI_DATA_HDR_PS_SHIFT) &
|
ps_state = !!((dhdr->info >> WMI_DATA_HDR_PS_SHIFT) &
|
||||||
WMI_DATA_HDR_PS_MASK);
|
WMI_DATA_HDR_PS_MASK);
|
||||||
|
|
||||||
offset = sizeof(struct wmi_data_hdr);
|
offset = sizeof(struct wmi_data_hdr) + pad_before_data_start;
|
||||||
trig_state = !!(le16_to_cpu(dhdr->info3) & WMI_DATA_HDR_TRIG);
|
trig_state = !!(le16_to_cpu(dhdr->info3) & WMI_DATA_HDR_TRIG);
|
||||||
|
|
||||||
switch (meta_type) {
|
switch (meta_type) {
|
||||||
@ -1523,9 +1527,6 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
|
|||||||
seq_no = wmi_data_hdr_get_seqno(dhdr);
|
seq_no = wmi_data_hdr_get_seqno(dhdr);
|
||||||
meta_type = wmi_data_hdr_get_meta(dhdr);
|
meta_type = wmi_data_hdr_get_meta(dhdr);
|
||||||
dot11_hdr = wmi_data_hdr_get_dot11(dhdr);
|
dot11_hdr = wmi_data_hdr_get_dot11(dhdr);
|
||||||
pad_before_data_start =
|
|
||||||
(le16_to_cpu(dhdr->info3) >> WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT)
|
|
||||||
& WMI_DATA_HDR_PAD_BEFORE_DATA_MASK;
|
|
||||||
|
|
||||||
skb_pull(skb, sizeof(struct wmi_data_hdr));
|
skb_pull(skb, sizeof(struct wmi_data_hdr));
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
#include <linux/nl80211.h>
|
#include <linux/nl80211.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/ath9k_platform.h>
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include "ath9k.h"
|
#include "ath9k.h"
|
||||||
|
|
||||||
@ -58,20 +57,9 @@ static void ath_ahb_read_cachesize(struct ath_common *common, int *csz)
|
|||||||
|
|
||||||
static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
|
static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
|
||||||
{
|
{
|
||||||
struct ath_softc *sc = (struct ath_softc *)common->priv;
|
ath_err(common, "%s: eeprom data has to be provided externally\n",
|
||||||
struct platform_device *pdev = to_platform_device(sc->dev);
|
__func__);
|
||||||
struct ath9k_platform_data *pdata;
|
return false;
|
||||||
|
|
||||||
pdata = dev_get_platdata(&pdev->dev);
|
|
||||||
if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
|
|
||||||
ath_err(common,
|
|
||||||
"%s: flash read failed, offset %08x is out of range\n",
|
|
||||||
__func__, off);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
*data = pdata->eeprom_data[off];
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ath_bus_ops ath_ahb_bus_ops = {
|
static struct ath_bus_ops ath_ahb_bus_ops = {
|
||||||
|
@ -476,6 +476,7 @@ static void ar9002_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
|
|||||||
static void ar9002_hw_spectral_scan_config(struct ath_hw *ah,
|
static void ar9002_hw_spectral_scan_config(struct ath_hw *ah,
|
||||||
struct ath_spec_scan *param)
|
struct ath_spec_scan *param)
|
||||||
{
|
{
|
||||||
|
u32 repeat_bit;
|
||||||
u8 count;
|
u8 count;
|
||||||
|
|
||||||
if (!param->enabled) {
|
if (!param->enabled) {
|
||||||
@ -486,12 +487,15 @@ static void ar9002_hw_spectral_scan_config(struct ath_hw *ah,
|
|||||||
REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA);
|
REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA);
|
||||||
REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE);
|
REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE);
|
||||||
|
|
||||||
if (param->short_repeat)
|
if (AR_SREV_9280(ah))
|
||||||
REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
|
repeat_bit = AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT;
|
||||||
AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
|
|
||||||
else
|
else
|
||||||
REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN,
|
repeat_bit = AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI;
|
||||||
AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
|
|
||||||
|
if (param->short_repeat)
|
||||||
|
REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, repeat_bit);
|
||||||
|
else
|
||||||
|
REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN, repeat_bit);
|
||||||
|
|
||||||
/* on AR92xx, the highest bit of count will make the the chip send
|
/* on AR92xx, the highest bit of count will make the the chip send
|
||||||
* spectral samples endlessly. Check if this really was intended,
|
* spectral samples endlessly. Check if this really was intended,
|
||||||
@ -499,15 +503,25 @@ static void ar9002_hw_spectral_scan_config(struct ath_hw *ah,
|
|||||||
*/
|
*/
|
||||||
count = param->count;
|
count = param->count;
|
||||||
if (param->endless) {
|
if (param->endless) {
|
||||||
if (AR_SREV_9271(ah))
|
if (AR_SREV_9280(ah))
|
||||||
count = 0;
|
|
||||||
else
|
|
||||||
count = 0x80;
|
count = 0x80;
|
||||||
|
else
|
||||||
|
count = 0;
|
||||||
} else if (count & 0x80)
|
} else if (count & 0x80)
|
||||||
count = 0x7f;
|
count = 0x7f;
|
||||||
|
else if (!count)
|
||||||
|
count = 1;
|
||||||
|
|
||||||
|
if (AR_SREV_9280(ah)) {
|
||||||
|
REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
|
||||||
|
AR_PHY_SPECTRAL_SCAN_COUNT, count);
|
||||||
|
} else {
|
||||||
|
REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
|
||||||
|
AR_PHY_SPECTRAL_SCAN_COUNT_KIWI, count);
|
||||||
|
REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
|
||||||
|
AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT);
|
||||||
|
}
|
||||||
|
|
||||||
REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
|
|
||||||
AR_PHY_SPECTRAL_SCAN_COUNT, count);
|
|
||||||
REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
|
REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
|
||||||
AR_PHY_SPECTRAL_SCAN_PERIOD, param->period);
|
AR_PHY_SPECTRAL_SCAN_PERIOD, param->period);
|
||||||
REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
|
REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
|
||||||
|
@ -177,8 +177,11 @@
|
|||||||
#define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8
|
#define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8
|
||||||
#define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000 /* Number of reports, reg 68, bits 16-23*/
|
#define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000 /* Number of reports, reg 68, bits 16-23*/
|
||||||
#define AR_PHY_SPECTRAL_SCAN_COUNT_S 16
|
#define AR_PHY_SPECTRAL_SCAN_COUNT_S 16
|
||||||
|
#define AR_PHY_SPECTRAL_SCAN_COUNT_KIWI 0x0FFF0000 /* Number of reports, reg 68, bits 16-27*/
|
||||||
|
#define AR_PHY_SPECTRAL_SCAN_COUNT_KIWI_S 16
|
||||||
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 /* Short repeat, reg 68, bit 24*/
|
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 /* Short repeat, reg 68, bit 24*/
|
||||||
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 /* Short repeat, reg 68, bit 24*/
|
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI 0x10000000 /* Short repeat, reg 68, bit 28*/
|
||||||
|
#define AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT 0x40000000
|
||||||
|
|
||||||
#define AR_PHY_RX_DELAY 0x9914
|
#define AR_PHY_RX_DELAY 0x9914
|
||||||
#define AR_PHY_SEARCH_START_DELAY 0x9918
|
#define AR_PHY_SEARCH_START_DELAY 0x9918
|
||||||
|
@ -33,6 +33,7 @@ struct coeff {
|
|||||||
|
|
||||||
enum ar9003_cal_types {
|
enum ar9003_cal_types {
|
||||||
IQ_MISMATCH_CAL = BIT(0),
|
IQ_MISMATCH_CAL = BIT(0),
|
||||||
|
TEMP_COMP_CAL = BIT(1),
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ar9003_hw_setup_calibration(struct ath_hw *ah,
|
static void ar9003_hw_setup_calibration(struct ath_hw *ah,
|
||||||
@ -58,6 +59,12 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah,
|
|||||||
/* Kick-off cal */
|
/* Kick-off cal */
|
||||||
REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
|
REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
|
||||||
break;
|
break;
|
||||||
|
case TEMP_COMP_CAL:
|
||||||
|
ath_dbg(common, CALIBRATE,
|
||||||
|
"starting Temperature Compensation Calibration\n");
|
||||||
|
REG_SET_BIT(ah, AR_CH0_THERM, AR_CH0_THERM_LOCAL);
|
||||||
|
REG_SET_BIT(ah, AR_CH0_THERM, AR_CH0_THERM_START);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ath_err(common, "Invalid calibration type\n");
|
ath_err(common, "Invalid calibration type\n");
|
||||||
break;
|
break;
|
||||||
@ -75,50 +82,51 @@ static bool ar9003_hw_per_calibration(struct ath_hw *ah,
|
|||||||
struct ath9k_cal_list *currCal)
|
struct ath9k_cal_list *currCal)
|
||||||
{
|
{
|
||||||
struct ath9k_hw_cal_data *caldata = ah->caldata;
|
struct ath9k_hw_cal_data *caldata = ah->caldata;
|
||||||
/* Cal is assumed not done until explicitly set below */
|
const struct ath9k_percal_data *cur_caldata = currCal->calData;
|
||||||
bool iscaldone = false;
|
|
||||||
|
|
||||||
/* Calibration in progress. */
|
/* Calibration in progress. */
|
||||||
if (currCal->calState == CAL_RUNNING) {
|
if (currCal->calState == CAL_RUNNING) {
|
||||||
/* Check to see if it has finished. */
|
/* Check to see if it has finished. */
|
||||||
if (!(REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)) {
|
if (REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Accumulate cal measures for active chains
|
||||||
|
*/
|
||||||
|
if (cur_caldata->calCollect)
|
||||||
|
cur_caldata->calCollect(ah);
|
||||||
|
ah->cal_samples++;
|
||||||
|
|
||||||
|
if (ah->cal_samples >= cur_caldata->calNumSamples) {
|
||||||
|
unsigned int i, numChains = 0;
|
||||||
|
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
|
||||||
|
if (rxchainmask & (1 << i))
|
||||||
|
numChains++;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Accumulate cal measures for active chains
|
* Process accumulated data
|
||||||
*/
|
*/
|
||||||
currCal->calData->calCollect(ah);
|
if (cur_caldata->calPostProc)
|
||||||
ah->cal_samples++;
|
cur_caldata->calPostProc(ah, numChains);
|
||||||
|
|
||||||
if (ah->cal_samples >=
|
/* Calibration has finished. */
|
||||||
currCal->calData->calNumSamples) {
|
caldata->CalValid |= cur_caldata->calType;
|
||||||
unsigned int i, numChains = 0;
|
currCal->calState = CAL_DONE;
|
||||||
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
|
return true;
|
||||||
if (rxchainmask & (1 << i))
|
} else {
|
||||||
numChains++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Process accumulated data
|
|
||||||
*/
|
|
||||||
currCal->calData->calPostProc(ah, numChains);
|
|
||||||
|
|
||||||
/* Calibration has finished. */
|
|
||||||
caldata->CalValid |= currCal->calData->calType;
|
|
||||||
currCal->calState = CAL_DONE;
|
|
||||||
iscaldone = true;
|
|
||||||
} else {
|
|
||||||
/*
|
/*
|
||||||
* Set-up collection of another sub-sample until we
|
* Set-up collection of another sub-sample until we
|
||||||
* get desired number
|
* get desired number
|
||||||
*/
|
*/
|
||||||
ar9003_hw_setup_calibration(ah, currCal);
|
ar9003_hw_setup_calibration(ah, currCal);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (!(caldata->CalValid & currCal->calData->calType)) {
|
} else if (!(caldata->CalValid & cur_caldata->calType)) {
|
||||||
/* If current cal is marked invalid in channel, kick it off */
|
/* If current cal is marked invalid in channel, kick it off */
|
||||||
ath9k_hw_reset_calibration(ah, currCal);
|
ath9k_hw_reset_calibration(ah, currCal);
|
||||||
}
|
}
|
||||||
|
|
||||||
return iscaldone;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ar9003_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
|
static int ar9003_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||||
@ -315,9 +323,16 @@ static const struct ath9k_percal_data iq_cal_single_sample = {
|
|||||||
ar9003_hw_iqcalibrate
|
ar9003_hw_iqcalibrate
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct ath9k_percal_data temp_cal_single_sample = {
|
||||||
|
TEMP_COMP_CAL,
|
||||||
|
MIN_CAL_SAMPLES,
|
||||||
|
PER_MAX_LOG_COUNT,
|
||||||
|
};
|
||||||
|
|
||||||
static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
|
static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
|
||||||
{
|
{
|
||||||
ah->iq_caldata.calData = &iq_cal_single_sample;
|
ah->iq_caldata.calData = &iq_cal_single_sample;
|
||||||
|
ah->temp_caldata.calData = &temp_cal_single_sample;
|
||||||
|
|
||||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||||
ah->enabled_cals |= TX_IQ_CAL;
|
ah->enabled_cals |= TX_IQ_CAL;
|
||||||
@ -325,7 +340,7 @@ static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
|
|||||||
ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
|
ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ah->supp_cals = IQ_MISMATCH_CAL;
|
ah->supp_cals = IQ_MISMATCH_CAL | TEMP_COMP_CAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OFF_UPPER_LT 24
|
#define OFF_UPPER_LT 24
|
||||||
@ -1374,6 +1389,29 @@ static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ar9003_hw_init_cal_common(struct ath_hw *ah)
|
||||||
|
{
|
||||||
|
struct ath9k_hw_cal_data *caldata = ah->caldata;
|
||||||
|
|
||||||
|
/* Initialize list pointers */
|
||||||
|
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
|
||||||
|
|
||||||
|
INIT_CAL(&ah->iq_caldata);
|
||||||
|
INSERT_CAL(ah, &ah->iq_caldata);
|
||||||
|
|
||||||
|
INIT_CAL(&ah->temp_caldata);
|
||||||
|
INSERT_CAL(ah, &ah->temp_caldata);
|
||||||
|
|
||||||
|
/* Initialize current pointer to first element in list */
|
||||||
|
ah->cal_list_curr = ah->cal_list;
|
||||||
|
|
||||||
|
if (ah->cal_list_curr)
|
||||||
|
ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
|
||||||
|
|
||||||
|
if (caldata)
|
||||||
|
caldata->CalValid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah,
|
static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah,
|
||||||
struct ath9k_channel *chan)
|
struct ath9k_channel *chan)
|
||||||
{
|
{
|
||||||
@ -1533,21 +1571,7 @@ skip_tx_iqcal:
|
|||||||
/* Revert chainmask to runtime parameters */
|
/* Revert chainmask to runtime parameters */
|
||||||
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
|
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
|
||||||
|
|
||||||
/* Initialize list pointers */
|
ar9003_hw_init_cal_common(ah);
|
||||||
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
|
|
||||||
|
|
||||||
INIT_CAL(&ah->iq_caldata);
|
|
||||||
INSERT_CAL(ah, &ah->iq_caldata);
|
|
||||||
ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n");
|
|
||||||
|
|
||||||
/* Initialize current pointer to first element in list */
|
|
||||||
ah->cal_list_curr = ah->cal_list;
|
|
||||||
|
|
||||||
if (ah->cal_list_curr)
|
|
||||||
ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
|
|
||||||
|
|
||||||
if (caldata)
|
|
||||||
caldata->CalValid = 0;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1578,8 +1602,6 @@ static bool do_ar9003_agc_cal(struct ath_hw *ah)
|
|||||||
static bool ar9003_hw_init_cal_soc(struct ath_hw *ah,
|
static bool ar9003_hw_init_cal_soc(struct ath_hw *ah,
|
||||||
struct ath9k_channel *chan)
|
struct ath9k_channel *chan)
|
||||||
{
|
{
|
||||||
struct ath_common *common = ath9k_hw_common(ah);
|
|
||||||
struct ath9k_hw_cal_data *caldata = ah->caldata;
|
|
||||||
bool txiqcal_done = false;
|
bool txiqcal_done = false;
|
||||||
bool status = true;
|
bool status = true;
|
||||||
bool run_agc_cal = false, sep_iq_cal = false;
|
bool run_agc_cal = false, sep_iq_cal = false;
|
||||||
@ -1677,21 +1699,7 @@ skip_tx_iqcal:
|
|||||||
/* Revert chainmask to runtime parameters */
|
/* Revert chainmask to runtime parameters */
|
||||||
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
|
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
|
||||||
|
|
||||||
/* Initialize list pointers */
|
ar9003_hw_init_cal_common(ah);
|
||||||
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
|
|
||||||
|
|
||||||
INIT_CAL(&ah->iq_caldata);
|
|
||||||
INSERT_CAL(ah, &ah->iq_caldata);
|
|
||||||
ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n");
|
|
||||||
|
|
||||||
/* Initialize current pointer to first element in list */
|
|
||||||
ah->cal_list_curr = ah->cal_list;
|
|
||||||
|
|
||||||
if (ah->cal_list_curr)
|
|
||||||
ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
|
|
||||||
|
|
||||||
if (caldata)
|
|
||||||
caldata->CalValid = 0;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -689,13 +689,6 @@
|
|||||||
#define AR_CH0_TOP_XPABIASLVL (AR_SREV_9550(ah) ? 0x3c0 : 0x300)
|
#define AR_CH0_TOP_XPABIASLVL (AR_SREV_9550(ah) ? 0x3c0 : 0x300)
|
||||||
#define AR_CH0_TOP_XPABIASLVL_S (AR_SREV_9550(ah) ? 6 : 8)
|
#define AR_CH0_TOP_XPABIASLVL_S (AR_SREV_9550(ah) ? 6 : 8)
|
||||||
|
|
||||||
#define AR_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 : \
|
|
||||||
((AR_SREV_9485(ah) ? 0x1628c : 0x16294)))
|
|
||||||
#define AR_CH0_THERM_XPABIASLVL_MSB 0x3
|
|
||||||
#define AR_CH0_THERM_XPABIASLVL_MSB_S 0
|
|
||||||
#define AR_CH0_THERM_XPASHORT2GND 0x4
|
|
||||||
#define AR_CH0_THERM_XPASHORT2GND_S 2
|
|
||||||
|
|
||||||
#define AR_SWITCH_TABLE_COM_ALL (0xffff)
|
#define AR_SWITCH_TABLE_COM_ALL (0xffff)
|
||||||
#define AR_SWITCH_TABLE_COM_ALL_S (0)
|
#define AR_SWITCH_TABLE_COM_ALL_S (0)
|
||||||
#define AR_SWITCH_TABLE_COM_AR9462_ALL (0xffffff)
|
#define AR_SWITCH_TABLE_COM_AR9462_ALL (0xffffff)
|
||||||
@ -712,15 +705,17 @@
|
|||||||
#define AR_SWITCH_TABLE_ALL (0xfff)
|
#define AR_SWITCH_TABLE_ALL (0xfff)
|
||||||
#define AR_SWITCH_TABLE_ALL_S (0)
|
#define AR_SWITCH_TABLE_ALL_S (0)
|
||||||
|
|
||||||
#define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 :\
|
#define AR_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 :\
|
||||||
((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16294 : 0x1628c))
|
((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16294 : 0x1628c))
|
||||||
|
#define AR_CH0_THERM_XPABIASLVL_MSB 0x3
|
||||||
|
#define AR_CH0_THERM_XPABIASLVL_MSB_S 0
|
||||||
|
#define AR_CH0_THERM_XPASHORT2GND 0x4
|
||||||
|
#define AR_CH0_THERM_XPASHORT2GND_S 2
|
||||||
|
|
||||||
#define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000
|
#define AR_CH0_THERM_LOCAL 0x80000000
|
||||||
#define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
|
#define AR_CH0_THERM_START 0x20000000
|
||||||
#define AR_PHY_65NM_CH0_THERM_START 0x20000000
|
#define AR_CH0_THERM_SAR_ADC_OUT 0x0000ff00
|
||||||
#define AR_PHY_65NM_CH0_THERM_START_S 29
|
#define AR_CH0_THERM_SAR_ADC_OUT_S 8
|
||||||
#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT 0x0000ff00
|
|
||||||
#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_S 8
|
|
||||||
|
|
||||||
#define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \
|
#define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \
|
||||||
(AR_SREV_9462(ah) ? 0x16290 : 0x16284))
|
(AR_SREV_9462(ah) ? 0x16290 : 0x16284))
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hw.h"
|
#include "hw.h"
|
||||||
|
#include <linux/ath9k_platform.h>
|
||||||
|
|
||||||
void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val)
|
void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val)
|
||||||
{
|
{
|
||||||
@ -108,26 +109,42 @@ void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ath9k_hw_nvram_read_blob(struct ath_hw *ah, u32 off,
|
static bool ath9k_hw_nvram_read_array(u16 *blob, size_t blob_size,
|
||||||
u16 *data)
|
off_t offset, u16 *data)
|
||||||
{
|
{
|
||||||
u16 *blob_data;
|
if (offset > blob_size)
|
||||||
|
|
||||||
if (off * sizeof(u16) > ah->eeprom_blob->size)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
blob_data = (u16 *)ah->eeprom_blob->data;
|
*data = blob[offset];
|
||||||
*data = blob_data[off];
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ath9k_hw_nvram_read_pdata(struct ath9k_platform_data *pdata,
|
||||||
|
off_t offset, u16 *data)
|
||||||
|
{
|
||||||
|
return ath9k_hw_nvram_read_array(pdata->eeprom_data,
|
||||||
|
ARRAY_SIZE(pdata->eeprom_data),
|
||||||
|
offset, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ath9k_hw_nvram_read_firmware(const struct firmware *eeprom_blob,
|
||||||
|
off_t offset, u16 *data)
|
||||||
|
{
|
||||||
|
return ath9k_hw_nvram_read_array((u16 *) eeprom_blob->data,
|
||||||
|
eeprom_blob->size / sizeof(u16),
|
||||||
|
offset, data);
|
||||||
|
}
|
||||||
|
|
||||||
bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
|
bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
|
||||||
{
|
{
|
||||||
struct ath_common *common = ath9k_hw_common(ah);
|
struct ath_common *common = ath9k_hw_common(ah);
|
||||||
|
struct ath9k_platform_data *pdata = ah->dev->platform_data;
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
if (ah->eeprom_blob)
|
if (ah->eeprom_blob)
|
||||||
ret = ath9k_hw_nvram_read_blob(ah, off, data);
|
ret = ath9k_hw_nvram_read_firmware(ah->eeprom_blob, off, data);
|
||||||
|
else if (pdata && !pdata->use_eeprom && pdata->eeprom_data)
|
||||||
|
ret = ath9k_hw_nvram_read_pdata(pdata, off, data);
|
||||||
else
|
else
|
||||||
ret = common->bus_ops->eeprom_read(common, off, data);
|
ret = common->bus_ops->eeprom_read(common, off, data);
|
||||||
|
|
||||||
|
@ -830,6 +830,7 @@ struct ath_hw {
|
|||||||
/* Calibration */
|
/* Calibration */
|
||||||
u32 supp_cals;
|
u32 supp_cals;
|
||||||
struct ath9k_cal_list iq_caldata;
|
struct ath9k_cal_list iq_caldata;
|
||||||
|
struct ath9k_cal_list temp_caldata;
|
||||||
struct ath9k_cal_list adcgain_caldata;
|
struct ath9k_cal_list adcgain_caldata;
|
||||||
struct ath9k_cal_list adcdc_caldata;
|
struct ath9k_cal_list adcdc_caldata;
|
||||||
struct ath9k_cal_list *cal_list;
|
struct ath9k_cal_list *cal_list;
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include <linux/nl80211.h>
|
#include <linux/nl80211.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/pci-aspm.h>
|
#include <linux/pci-aspm.h>
|
||||||
#include <linux/ath9k_platform.h>
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include "ath9k.h"
|
#include "ath9k.h"
|
||||||
|
|
||||||
@ -786,37 +785,21 @@ static void ath_pci_read_cachesize(struct ath_common *common, int *csz)
|
|||||||
|
|
||||||
static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
|
static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
|
||||||
{
|
{
|
||||||
struct ath_softc *sc = (struct ath_softc *) common->priv;
|
struct ath_hw *ah = (struct ath_hw *) common->ah;
|
||||||
struct ath9k_platform_data *pdata = sc->dev->platform_data;
|
|
||||||
|
|
||||||
if (pdata && !pdata->use_eeprom) {
|
common->ops->read(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
|
||||||
if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
|
|
||||||
ath_err(common,
|
|
||||||
"%s: eeprom read failed, offset %08x is out of range\n",
|
|
||||||
__func__, off);
|
|
||||||
|
|
||||||
return false;
|
if (!ath9k_hw_wait(ah,
|
||||||
}
|
AR_EEPROM_STATUS_DATA,
|
||||||
|
AR_EEPROM_STATUS_DATA_BUSY |
|
||||||
*data = pdata->eeprom_data[off];
|
AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
|
||||||
} else {
|
AH_WAIT_TIMEOUT)) {
|
||||||
struct ath_hw *ah = (struct ath_hw *) common->ah;
|
return false;
|
||||||
|
|
||||||
common->ops->read(ah, AR5416_EEPROM_OFFSET +
|
|
||||||
(off << AR5416_EEPROM_S));
|
|
||||||
|
|
||||||
if (!ath9k_hw_wait(ah,
|
|
||||||
AR_EEPROM_STATUS_DATA,
|
|
||||||
AR_EEPROM_STATUS_DATA_BUSY |
|
|
||||||
AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
|
|
||||||
AH_WAIT_TIMEOUT)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
*data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA),
|
|
||||||
AR_EEPROM_STATUS_DATA_VAL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA),
|
||||||
|
AR_EEPROM_STATUS_DATA_VAL);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user