提交 90864fbc 编写于 作者: D David S. Miller

Merge branch 'for-davem' of...

Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
......@@ -158,6 +158,11 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah)
txlat = AR5K_REG_MS(usec_reg, AR5K_USEC_TX_LATENCY_5211);
rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211);
/*
* Set default Tx frame to Tx data start delay
*/
txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT;
/*
* 5210 initvals don't include usec settings
* so we need to use magic values here for
......
......@@ -21,11 +21,15 @@
#include <linux/ath9k_platform.h>
#include "ath9k.h"
const struct platform_device_id ath9k_platform_id_table[] = {
static const struct platform_device_id ath9k_platform_id_table[] = {
{
.name = "ath9k",
.driver_data = AR5416_AR9100_DEVID,
},
{
.name = "ar934x_wmac",
.driver_data = AR9300_DEVID_AR9340,
},
{},
};
......
......@@ -899,12 +899,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
* check here default level should not modify INI setting.
*/
if (use_new_ani(ah)) {
const struct ani_ofdm_level_entry *entry_ofdm;
const struct ani_cck_level_entry *entry_cck;
entry_ofdm = &ofdm_level_table[ATH9K_ANI_OFDM_DEF_LEVEL];
entry_cck = &cck_level_table[ATH9K_ANI_CCK_DEF_LEVEL];
ah->aniperiod = ATH9K_ANI_PERIOD_NEW;
ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW;
} else {
......
......@@ -18,13 +18,13 @@
#include "hw-ops.h"
#include "ar9003_phy.h"
#define MPASS 3
#define MAX_MEASUREMENT 8
#define MAX_DIFFERENCE 10
#define MAX_MAG_DELTA 11
#define MAX_PHS_DELTA 10
struct coeff {
int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS];
int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS];
int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
int iqc_coeff[2];
};
......@@ -185,6 +185,7 @@ static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
/* Accumulate IQ cal measures for active chains */
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
if (ah->txchainmask & BIT(i)) {
ah->totalPowerMeasI[i] +=
REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
ah->totalPowerMeasQ[i] +=
......@@ -197,6 +198,7 @@ static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
ah->totalPowerMeasQ[i],
ah->totalIqCorrMeas[i]);
}
}
}
static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
......@@ -608,36 +610,48 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
return true;
}
static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg)
static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
int max_delta)
{
int diff[MPASS];
diff[0] = abs(mp_coeff[0] - mp_coeff[1]);
diff[1] = abs(mp_coeff[1] - mp_coeff[2]);
diff[2] = abs(mp_coeff[2] - mp_coeff[0]);
if (diff[0] > MAX_DIFFERENCE &&
diff[1] > MAX_DIFFERENCE &&
diff[2] > MAX_DIFFERENCE)
return false;
if (diff[0] <= diff[1] && diff[0] <= diff[2])
*mp_avg = (mp_coeff[0] + mp_coeff[1]) / 2;
else if (diff[1] <= diff[2])
*mp_avg = (mp_coeff[1] + mp_coeff[2]) / 2;
int mp_max = -64, max_idx = 0;
int mp_min = 63, min_idx = 0;
int mp_avg = 0, i, outlier_idx = 0;
/* find min/max mismatch across all calibrated gains */
for (i = 0; i < nmeasurement; i++) {
mp_avg += mp_coeff[i];
if (mp_coeff[i] > mp_max) {
mp_max = mp_coeff[i];
max_idx = i;
} else if (mp_coeff[i] < mp_min) {
mp_min = mp_coeff[i];
min_idx = i;
}
}
/* find average (exclude max abs value) */
for (i = 0; i < nmeasurement; i++) {
if ((abs(mp_coeff[i]) < abs(mp_max)) ||
(abs(mp_coeff[i]) < abs(mp_min)))
mp_avg += mp_coeff[i];
}
mp_avg /= (nmeasurement - 1);
/* detect outlier */
if (abs(mp_max - mp_min) > max_delta) {
if (abs(mp_max - mp_avg) > abs(mp_min - mp_avg))
outlier_idx = max_idx;
else
*mp_avg = (mp_coeff[2] + mp_coeff[0]) / 2;
return true;
outlier_idx = min_idx;
}
mp_coeff[outlier_idx] = mp_avg;
}
static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
u8 num_chains,
struct coeff *coeff)
{
struct ath_common *common = ath9k_hw_common(ah);
int i, im, nmeasurement;
int magnitude, phase;
u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
......@@ -657,11 +671,6 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
/* Load the average of 2 passes */
for (i = 0; i < num_chains; i++) {
if (AR_SREV_9485(ah))
nmeasurement = REG_READ_FIELD(ah,
AR_PHY_TX_IQCAL_STATUS_B0_9485,
AR_PHY_CALIBRATED_GAINS_0);
else
nmeasurement = REG_READ_FIELD(ah,
AR_PHY_TX_IQCAL_STATUS_B0,
AR_PHY_CALIBRATED_GAINS_0);
......@@ -669,25 +678,21 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
if (nmeasurement > MAX_MEASUREMENT)
nmeasurement = MAX_MEASUREMENT;
for (im = 0; im < nmeasurement; im++) {
/*
* Determine which 2 passes are closest and compute avg
* magnitude
*/
if (!ar9003_hw_compute_closest_pass_and_avg(coeff->mag_coeff[i][im],
&magnitude))
goto disable_txiqcal;
/* detect outlier only if nmeasurement > 1 */
if (nmeasurement > 1) {
/* Detect magnitude outlier */
ar9003_hw_detect_outlier(coeff->mag_coeff[i],
nmeasurement, MAX_MAG_DELTA);
/*
* Determine which 2 passes are closest and compute avg
* phase
*/
if (!ar9003_hw_compute_closest_pass_and_avg(coeff->phs_coeff[i][im],
&phase))
goto disable_txiqcal;
/* Detect phase outlier */
ar9003_hw_detect_outlier(coeff->phs_coeff[i],
nmeasurement, MAX_PHS_DELTA);
}
coeff->iqc_coeff[0] = (magnitude & 0x7f) |
((phase & 0x7f) << 7);
for (im = 0; im < nmeasurement; im++) {
coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) |
((coeff->phs_coeff[i][im] & 0x7f) << 7);
if ((im % 2) == 0)
REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
......@@ -707,141 +712,37 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
return;
disable_txiqcal:
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x0);
REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x0);
ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n");
}
static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
static const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
AR_PHY_TX_IQCAL_STATUS_B0,
AR_PHY_TX_IQCAL_STATUS_B1,
AR_PHY_TX_IQCAL_STATUS_B2,
};
static const u32 chan_info_tab[] = {
AR_PHY_CHAN_INFO_TAB_0,
AR_PHY_CHAN_INFO_TAB_1,
AR_PHY_CHAN_INFO_TAB_2,
};
struct coeff coeff;
s32 iq_res[6];
s32 i, j, ip, im, nmeasurement;
u8 nchains = get_streams(common->tx_chainmask);
for (ip = 0; ip < MPASS; ip++) {
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
DELPT);
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
AR_PHY_TX_IQCAL_START_DO_CAL,
AR_PHY_TX_IQCAL_START_DO_CAL);
if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
AR_PHY_TX_IQCAL_START_DO_CAL,
0, AH_WAIT_TIMEOUT)) {
ath_dbg(common, ATH_DBG_CALIBRATE,
"Tx IQ Cal not complete.\n");
goto TX_IQ_CAL_FAILED;
}
nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0,
AR_PHY_CALIBRATED_GAINS_0);
if (nmeasurement > MAX_MEASUREMENT)
nmeasurement = MAX_MEASUREMENT;
for (i = 0; i < nchains; i++) {
ath_dbg(common, ATH_DBG_CALIBRATE,
"Doing Tx IQ Cal for chain %d.\n", i);
for (im = 0; im < nmeasurement; im++) {
if (REG_READ(ah, txiqcal_status[i]) &
AR_PHY_TX_IQCAL_STATUS_FAILED) {
ath_dbg(common, ATH_DBG_CALIBRATE,
"Tx IQ Cal failed for chain %d.\n", i);
goto TX_IQ_CAL_FAILED;
}
for (j = 0; j < 3; j++) {
u8 idx = 2 * j,
offset = 4 * (3 * im + j);
REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
AR_PHY_CHAN_INFO_TAB_S2_READ,
0);
/* 32 bits */
iq_res[idx] = REG_READ(ah,
chan_info_tab[i] +
offset);
REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
AR_PHY_CHAN_INFO_TAB_S2_READ,
1);
/* 16 bits */
iq_res[idx+1] = 0xffff & REG_READ(ah,
chan_info_tab[i] +
offset);
ath_dbg(common, ATH_DBG_CALIBRATE,
"IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
idx, iq_res[idx], idx+1, iq_res[idx+1]);
}
if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
coeff.iqc_coeff)) {
ath_dbg(common, ATH_DBG_CALIBRATE,
"Failed in calculation of IQ correction.\n");
goto TX_IQ_CAL_FAILED;
}
coeff.mag_coeff[i][im][ip] =
coeff.iqc_coeff[0] & 0x7f;
coeff.phs_coeff[i][im][ip] =
(coeff.iqc_coeff[0] >> 7) & 0x7f;
if (coeff.mag_coeff[i][im][ip] > 63)
coeff.mag_coeff[i][im][ip] -= 128;
if (coeff.phs_coeff[i][im][ip] > 63)
coeff.phs_coeff[i][im][ip] -= 128;
}
}
}
ar9003_hw_tx_iqcal_load_avg_2_passes(ah, nchains, &coeff);
return;
TX_IQ_CAL_FAILED:
ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
}
static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
{
u8 tx_gain_forced;
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1_9485,
AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT);
tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
AR_PHY_TXGAIN_FORCE);
if (tx_gain_forced)
REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
AR_PHY_TXGAIN_FORCE, 0);
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START_9485,
AR_PHY_TX_IQCAL_START_DO_CAL_9485, 1);
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
AR_PHY_TX_IQCAL_START_DO_CAL, 1);
if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
AR_PHY_TX_IQCAL_START_DO_CAL, 0,
AH_WAIT_TIMEOUT)) {
ath_dbg(common, ATH_DBG_CALIBRATE,
"Tx IQ Cal is not completed.\n");
return false;
}
return true;
}
static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
AR_PHY_TX_IQCAL_STATUS_B0_9485,
AR_PHY_TX_IQCAL_STATUS_B0,
AR_PHY_TX_IQCAL_STATUS_B1,
AR_PHY_TX_IQCAL_STATUS_B2,
};
......@@ -853,7 +754,7 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
struct coeff coeff;
s32 iq_res[6];
u8 num_chains = 0;
int i, ip, im, j;
int i, im, j;
int nmeasurement;
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
......@@ -861,10 +762,9 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
num_chains++;
}
for (ip = 0; ip < MPASS; ip++) {
for (i = 0; i < num_chains; i++) {
nmeasurement = REG_READ_FIELD(ah,
AR_PHY_TX_IQCAL_STATUS_B0_9485,
AR_PHY_TX_IQCAL_STATUS_B0,
AR_PHY_CALIBRATED_GAINS_0);
if (nmeasurement > MAX_MEASUREMENT)
nmeasurement = MAX_MEASUREMENT;
......@@ -912,20 +812,19 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
coeff.iqc_coeff)) {
ath_dbg(common, ATH_DBG_CALIBRATE,
"Failed in calculation of IQ correction.\n");
"Failed in calculation of \
IQ correction.\n");
goto tx_iqcal_fail;
}
coeff.mag_coeff[i][im][ip] =
coeff.iqc_coeff[0] & 0x7f;
coeff.phs_coeff[i][im][ip] =
coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f;
coeff.phs_coeff[i][im] =
(coeff.iqc_coeff[0] >> 7) & 0x7f;
if (coeff.mag_coeff[i][im][ip] > 63)
coeff.mag_coeff[i][im][ip] -= 128;
if (coeff.phs_coeff[i][im][ip] > 63)
coeff.phs_coeff[i][im][ip] -= 128;
}
if (coeff.mag_coeff[i][im] > 63)
coeff.mag_coeff[i][im] -= 128;
if (coeff.phs_coeff[i][im] > 63)
coeff.phs_coeff[i][im] -= 128;
}
}
ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff);
......@@ -940,31 +839,37 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
struct ath9k_channel *chan)
{
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_hw_capabilities *pCap = &ah->caps;
int val;
bool txiqcal_done = false;
val = REG_READ(ah, AR_ENT_OTP);
ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val);
if (AR_SREV_9485(ah))
ar9003_hw_set_chain_masks(ah, 0x1, 0x1);
else if (val & AR_ENT_OTP_CHAIN2_DISABLE)
/* Configure rx/tx chains before running AGC/TxiQ cals */
if (val & AR_ENT_OTP_CHAIN2_DISABLE)
ar9003_hw_set_chain_masks(ah, 0x3, 0x3);
else
/*
* 0x7 = 0b111 , AR9003 needs to be configured for 3-chain
* mode before running AGC/TxIQ cals
*/
ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
ar9003_hw_set_chain_masks(ah, pCap->rx_chainmask,
pCap->tx_chainmask);
/* Do Tx IQ Calibration */
if (AR_SREV_9485(ah))
ar9003_hw_tx_iq_cal_run(ah);
else
ar9003_hw_tx_iq_cal(ah);
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
DELPT);
/*
* For AR9485 or later chips, TxIQ cal runs as part of
* AGC calibration
*/
if (AR_SREV_9485_OR_LATER(ah))
txiqcal_done = true;
else {
txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
udelay(5);
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
}
/* Calibrate the AGC */
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
......@@ -979,7 +884,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
return false;
}
if (AR_SREV_9485(ah))
if (txiqcal_done)
ar9003_hw_tx_iq_cal_post_proc(ah);
/* Revert chainmasks to their original values before NF cal */
......
......@@ -3217,7 +3217,6 @@ static int ar9300_compress_decision(struct ath_hw *ah,
u8 *word, int length, int mdata_size)
{
struct ath_common *common = ath9k_hw_common(ah);
u8 *dptr;
const struct ar9300_eeprom *eep = NULL;
switch (code) {
......@@ -3235,7 +3234,6 @@ static int ar9300_compress_decision(struct ath_hw *ah,
break;
case _CompressBlock:
if (reference == 0) {
dptr = mptr;
} else {
eep = ar9003_eeprom_struct_find_by_id(reference);
if (eep == NULL) {
......@@ -3448,9 +3446,13 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
else {
REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB,
if (!AR_SREV_9340(ah)) {
REG_RMW_FIELD(ah, AR_CH0_THERM,
AR_CH0_THERM_XPABIASLVL_MSB,
bias >> 2);
REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1);
REG_RMW_FIELD(ah, AR_CH0_THERM,
AR_CH0_THERM_XPASHORT2GND, 1);
}
}
}
......@@ -3497,23 +3499,28 @@ static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
{
int chain;
static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
AR_PHY_SWITCH_CHAIN_0,
AR_PHY_SWITCH_CHAIN_1,
AR_PHY_SWITCH_CHAIN_2,
};
u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
if (!AR_SREV_9485(ah)) {
value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL,
value);
value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL,
value);
for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
if ((ah->rxchainmask & BIT(chain)) ||
(ah->txchainmask & BIT(chain))) {
value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
is2ghz);
REG_RMW_FIELD(ah, switch_chain_reg[chain],
AR_SWITCH_TABLE_ALL, value);
}
}
if (AR_SREV_9485(ah)) {
......@@ -3634,13 +3641,16 @@ static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
/* Test value. if 0 then attenuation is unused. Don't load anything. */
for (i = 0; i < 3; i++) {
if (ah->txchainmask & BIT(i)) {
value = ar9003_hw_atten_chain_get(ah, i, chan);
REG_RMW_FIELD(ah, ext_atten_reg[i],
AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
REG_RMW_FIELD(ah, ext_atten_reg[i],
AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value);
AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
value);
}
}
}
......@@ -3749,8 +3759,9 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
ar9003_hw_drive_strength_apply(ah);
ar9003_hw_atten_apply(ah, chan);
if (!AR_SREV_9340(ah))
ar9003_hw_internal_regulator_apply(ah);
if (AR_SREV_9485(ah))
if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
ar9003_hw_apply_tuning_caps(ah);
}
......
......@@ -18,6 +18,7 @@
#include "ar9003_mac.h"
#include "ar9003_2p2_initvals.h"
#include "ar9485_initvals.h"
#include "ar9340_initvals.h"
/* General hardware code for the AR9003 hadware family */
......@@ -28,7 +29,63 @@
*/
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
{
if (AR_SREV_9485_11(ah)) {
if (AR_SREV_9340(ah)) {
/* mac */
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
ar9340_1p0_mac_core,
ARRAY_SIZE(ar9340_1p0_mac_core), 2);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
ar9340_1p0_mac_postamble,
ARRAY_SIZE(ar9340_1p0_mac_postamble), 5);
/* bb */
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
ar9340_1p0_baseband_core,
ARRAY_SIZE(ar9340_1p0_baseband_core), 2);
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
ar9340_1p0_baseband_postamble,
ARRAY_SIZE(ar9340_1p0_baseband_postamble), 5);
/* radio */
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
ar9340_1p0_radio_core,
ARRAY_SIZE(ar9340_1p0_radio_core), 2);
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
ar9340_1p0_radio_postamble,
ARRAY_SIZE(ar9340_1p0_radio_postamble), 5);
/* soc */
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
ar9340_1p0_soc_preamble,
ARRAY_SIZE(ar9340_1p0_soc_preamble), 2);
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
ar9340_1p0_soc_postamble,
ARRAY_SIZE(ar9340_1p0_soc_postamble), 5);
/* rx/tx gain */
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9340Common_wo_xlna_rx_gain_table_1p0,
ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
5);
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9340Modes_high_ob_db_tx_gain_table_1p0,
ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0),
5);
INIT_INI_ARRAY(&ah->iniModesAdditional,
ar9340Modes_fast_clock_1p0,
ARRAY_SIZE(ar9340Modes_fast_clock_1p0),
3);
INIT_INI_ARRAY(&ah->iniModesAdditional_40M,
ar9340_1p0_radio_core_40M,
ARRAY_SIZE(ar9340_1p0_radio_core_40M),
2);
} else if (AR_SREV_9485_11(ah)) {
/* mac */
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
......@@ -163,7 +220,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
switch (ar9003_hw_get_tx_gain_idx(ah)) {
case 0:
default:
if (AR_SREV_9485_11(ah))
if (AR_SREV_9340(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
5);
else if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485_modes_lowest_ob_db_tx_gain_1_1,
ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
......@@ -175,7 +237,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
5);
break;
case 1:
if (AR_SREV_9485_11(ah))
if (AR_SREV_9340(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
5);
else if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485Modes_high_ob_db_tx_gain_1_1,
ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
......@@ -187,7 +254,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
5);
break;
case 2:
if (AR_SREV_9485_11(ah))
if (AR_SREV_9340(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
5);
else if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485Modes_low_ob_db_tx_gain_1_1,
ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
......@@ -199,7 +271,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
5);
break;
case 3:
if (AR_SREV_9485_11(ah))
if (AR_SREV_9340(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
5);
else if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485Modes_high_power_tx_gain_1_1,
ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
......@@ -218,7 +295,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
switch (ar9003_hw_get_rx_gain_idx(ah)) {
case 0:
default:
if (AR_SREV_9485_11(ah))
if (AR_SREV_9340(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9340Common_rx_gain_table_1p0,
ARRAY_SIZE(ar9340Common_rx_gain_table_1p0),
2);
else if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9485Common_wo_xlna_rx_gain_1_1,
ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
......@@ -230,7 +312,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
2);
break;
case 1:
if (AR_SREV_9485_11(ah))
if (AR_SREV_9340(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9340Common_wo_xlna_rx_gain_table_1p0,
ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
2);
else if (AR_SREV_9485_11(ah))
INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9485Common_wo_xlna_rx_gain_1_1,
ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
......
......@@ -86,14 +86,31 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
channelSel = (freq * 4) / 120;
chan_frac = (((freq * 4) % 120) * 0x20000) / 120;
channelSel = (channelSel << 17) | chan_frac;
} else if (AR_SREV_9340(ah)) {
if (ah->is_clk_25mhz) {
u32 chan_frac;
channelSel = (freq * 2) / 75;
chan_frac = (((freq * 2) % 75) * 0x20000) / 75;
channelSel = (channelSel << 17) | chan_frac;
} else
channelSel = CHANSEL_2G(freq) >> 1;
} else
channelSel = CHANSEL_2G(freq);
/* Set to 2G mode */
bMode = 1;
} else {
if (AR_SREV_9340(ah) && ah->is_clk_25mhz) {
u32 chan_frac;
channelSel = (freq * 2) / 75;
chan_frac = ((freq % 75) * 0x20000) / 75;
channelSel = (channelSel << 17) | chan_frac;
} else {
channelSel = CHANSEL_5G(freq);
/* Doubler is ON, so, divide channelSel by 2. */
channelSel >>= 1;
}
/* Set to 5G mode */
bMode = 0;
}
......@@ -151,7 +168,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
* is out-of-band and can be ignored.
*/
if (AR_SREV_9485(ah)) {
if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) {
spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah,
IS_CHAN_2GHZ(chan));
if (spur_fbin_ptr[0] == 0) /* No spur */
......@@ -176,7 +193,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
for (i = 0; i < max_spur_cnts; i++) {
negative = 0;
if (AR_SREV_9485(ah))
if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i],
IS_CHAN_2GHZ(chan)) - synth_freq;
else
......@@ -599,29 +616,25 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
unsigned int regWrites = 0, i;
struct ieee80211_channel *channel = chan->chan;
u32 modesIndex, freqIndex;
u32 modesIndex;
switch (chan->chanmode) {
case CHANNEL_A:
case CHANNEL_A_HT20:
modesIndex = 1;
freqIndex = 1;
break;
case CHANNEL_A_HT40PLUS:
case CHANNEL_A_HT40MINUS:
modesIndex = 2;
freqIndex = 1;
break;
case CHANNEL_G:
case CHANNEL_G_HT20:
case CHANNEL_B:
modesIndex = 4;
freqIndex = 2;
break;
case CHANNEL_G_HT40PLUS:
case CHANNEL_G_HT40MINUS:
modesIndex = 3;
freqIndex = 2;
break;
default:
......@@ -646,6 +659,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
REG_WRITE_ARRAY(&ah->iniModesAdditional,
modesIndex, regWrites);
if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites);
ar9003_hw_override_ini(ah);
ar9003_hw_set_channel_regs(ah, chan);
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
......
......@@ -548,15 +548,12 @@
#define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300)
#define AR_PHY_TX_IQCAL_START_9485 (AR_SM_BASE + 0x3c4)
#define AR_PHY_TX_IQCAL_START_DO_CAL_9485 0x80000000
#define AR_PHY_TX_IQCAL_START_DO_CAL_9485_S 31
#define AR_PHY_TX_IQCAL_CONTROL_1_9485 (AR_SM_BASE + 0x3c8)
#define AR_PHY_TX_IQCAL_STATUS_B0_9485 (AR_SM_BASE + 0x3f0)
#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448)
#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440)
#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c)
#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + AR_SREV_9485(ah) ? \
0x3c8 : 0x448)
#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + AR_SREV_9485(ah) ? \
0x3c4 : 0x440)
#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + AR_SREV_9485(ah) ? \
0x3f0 : 0x48c)
#define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \
(AR_SREV_9485(ah) ? \
0x3d0 : 0x450) + ((_i) << 2))
......@@ -588,7 +585,7 @@
#define AR_PHY_65NM_CH0_BIAS2 0x160c4
#define AR_PHY_65NM_CH0_BIAS4 0x160cc
#define AR_PHY_65NM_CH0_RXTX4 0x1610c
#define AR_PHY_65NM_CH0_THERM (AR_SREV_9485(ah) ? 0x1628c : 0x16290)
#define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 : 0x1628c)
#define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000
#define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
......@@ -758,8 +755,8 @@
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24
#define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004
#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000
#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18
#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000
#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18
#define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001
#define AR_PHY_TX_IQCAL_START_DO_CAL_S 0
......
此差异已折叠。
......@@ -423,6 +423,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status);
#define ATH_PAPRD_TIMEOUT 100 /* msecs */
void ath_hw_check(struct work_struct *work);
void ath_hw_pll_work(struct work_struct *work);
void ath_paprd_calibrate(struct work_struct *work);
void ath_ani_calibrate(unsigned long data);
......@@ -453,6 +454,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc);
#define ATH_LED_PIN_DEF 1
#define ATH_LED_PIN_9287 8
#define ATH_LED_PIN_9300 10
#define ATH_LED_PIN_9485 6
#ifdef CONFIG_MAC80211_LEDS
......
......@@ -781,12 +781,6 @@ void ath_set_beacon(struct ath_softc *sc)
break;
case NL80211_IFTYPE_STATION:
ath_beacon_config_sta(sc, cur_conf);
/*
* Request a re-configuration of Beacon related timers
* on the receipt of the first Beacon frame (i.e.,
* after time sync with the AP).
*/
sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
break;
default:
ath_dbg(common, ATH_DBG_CONFIG,
......
......@@ -51,6 +51,10 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
.bt_hold_rx_clear = true,
};
u32 i;
bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity;
if (AR_SREV_9300_20_OR_LATER(ah))
rxclear_polarity = !ath_bt_config.bt_rxclear_polarity;
btcoex_hw->bt_coex_mode =
(btcoex_hw->bt_coex_mode & AR_BT_QCU_THRESH) |
......@@ -59,7 +63,7 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
SM(ath_bt_config.bt_txframe_extend, AR_BT_TX_FRAME_EXTEND) |
SM(ath_bt_config.bt_mode, AR_BT_MODE) |
SM(ath_bt_config.bt_quiet_collision, AR_BT_QUIET) |
SM(ath_bt_config.bt_rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) |
SM(rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) |
SM(ath_bt_config.bt_priority_time, AR_BT_PRIORITY_TIME) |
SM(ath_bt_config.bt_first_slot_time, AR_BT_FIRST_SLOT_TIME) |
SM(qnum, AR_BT_QCU_THRESH);
......@@ -142,6 +146,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
}
EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight);
static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
{
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
......@@ -152,9 +157,22 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
* enable coex 3-wire
*/
REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_hw->bt_coex_mode);
REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights);
REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2);
if (AR_SREV_9300_20_OR_LATER(ah)) {
REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, ah->bt_coex_wlan_weight[0]);
REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, ah->bt_coex_wlan_weight[1]);
REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, ah->bt_coex_bt_weight[0]);
REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, ah->bt_coex_bt_weight[1]);
REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, ah->bt_coex_bt_weight[2]);
REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, ah->bt_coex_bt_weight[3]);
} else
REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights);
if (AR_SREV_9271(ah)) {
val = REG_READ(ah, 0x50040);
val &= 0xFFFFFEFF;
......@@ -202,10 +220,86 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
if (btcoex_hw->scheme == ATH_BTCOEX_CFG_3WIRE) {
REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE);
REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0);
REG_WRITE(ah, AR_BT_COEX_MODE2, 0);
if (AR_SREV_9300_20_OR_LATER(ah)) {
REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, 0);
REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, 0);
REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, 0);
REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, 0);
REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, 0);
REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, 0);
} else
REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0);
}
ah->btcoex_hw.enabled = false;
}
EXPORT_SYMBOL(ath9k_hw_btcoex_disable);
static void ar9003_btcoex_bt_stomp(struct ath_hw *ah,
enum ath_stomp_type stomp_type)
{
ah->bt_coex_bt_weight[0] = AR9300_BT_WGHT;
ah->bt_coex_bt_weight[1] = AR9300_BT_WGHT;
ah->bt_coex_bt_weight[2] = AR9300_BT_WGHT;
ah->bt_coex_bt_weight[3] = AR9300_BT_WGHT;
switch (stomp_type) {
case ATH_BTCOEX_STOMP_ALL:
ah->bt_coex_wlan_weight[0] = AR9300_STOMP_ALL_WLAN_WGHT0;
ah->bt_coex_wlan_weight[1] = AR9300_STOMP_ALL_WLAN_WGHT1;
break;
case ATH_BTCOEX_STOMP_LOW:
ah->bt_coex_wlan_weight[0] = AR9300_STOMP_LOW_WLAN_WGHT0;
ah->bt_coex_wlan_weight[1] = AR9300_STOMP_LOW_WLAN_WGHT1;
break;
case ATH_BTCOEX_STOMP_NONE:
ah->bt_coex_wlan_weight[0] = AR9300_STOMP_NONE_WLAN_WGHT0;
ah->bt_coex_wlan_weight[1] = AR9300_STOMP_NONE_WLAN_WGHT1;
break;
default:
ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
"Invalid Stomptype\n");
break;
}
ath9k_hw_btcoex_enable(ah);
}
/*
* Configures appropriate weight based on stomp type.
*/
void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
enum ath_stomp_type stomp_type)
{
if (AR_SREV_9300_20_OR_LATER(ah)) {
ar9003_btcoex_bt_stomp(ah, stomp_type);
return;
}
switch (stomp_type) {
case ATH_BTCOEX_STOMP_ALL:
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_ALL_WLAN_WGHT);
break;
case ATH_BTCOEX_STOMP_LOW:
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_LOW_WLAN_WGHT);
break;
case ATH_BTCOEX_STOMP_NONE:
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_NONE_WLAN_WGHT);
break;
default:
ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
"Invalid Stomptype\n");
break;
}
ath9k_hw_btcoex_enable(ah);
}
EXPORT_SYMBOL(ath9k_hw_btcoex_bt_stomp);
......@@ -19,9 +19,13 @@
#include "hw.h"
#define ATH_WLANACTIVE_GPIO 5
#define ATH_BTACTIVE_GPIO 6
#define ATH_BTPRIORITY_GPIO 7
#define ATH_WLANACTIVE_GPIO_9280 5
#define ATH_BTACTIVE_GPIO_9280 6
#define ATH_BTPRIORITY_GPIO_9285 7
#define ATH_WLANACTIVE_GPIO_9300 5
#define ATH_BTACTIVE_GPIO_9300 4
#define ATH_BTPRIORITY_GPIO_9300 8
#define ATH_BTCOEX_DEF_BT_PERIOD 45
#define ATH_BTCOEX_DEF_DUTY_CYCLE 55
......@@ -32,6 +36,14 @@
#define ATH_BT_CNT_THRESHOLD 3
#define ATH_BT_CNT_SCAN_THRESHOLD 15
/* Defines the BT AR_BT_COEX_WGHT used */
enum ath_stomp_type {
ATH_BTCOEX_NO_STOMP,
ATH_BTCOEX_STOMP_ALL,
ATH_BTCOEX_STOMP_LOW,
ATH_BTCOEX_STOMP_NONE
};
enum ath_btcoex_scheme {
ATH_BTCOEX_CFG_NONE,
ATH_BTCOEX_CFG_2WIRE,
......@@ -57,5 +69,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
u32 wlan_weight);
void ath9k_hw_btcoex_enable(struct ath_hw *ah);
void ath9k_hw_btcoex_disable(struct ath_hw *ah);
void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
enum ath_stomp_type stomp_type);
#endif
......@@ -158,37 +158,6 @@ int ath9k_cmn_count_streams(unsigned int chainmask, int max)
}
EXPORT_SYMBOL(ath9k_cmn_count_streams);
/*
* Configures appropriate weight based on stomp type.
*/
void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common,
enum ath_stomp_type stomp_type)
{
struct ath_hw *ah = common->ah;
switch (stomp_type) {
case ATH_BTCOEX_STOMP_ALL:
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_ALL_WLAN_WGHT);
break;
case ATH_BTCOEX_STOMP_LOW:
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_LOW_WLAN_WGHT);
break;
case ATH_BTCOEX_STOMP_NONE:
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
AR_STOMP_NONE_WLAN_WGHT);
break;
default:
ath_dbg(common, ATH_DBG_BTCOEX,
"Invalid Stomptype\n");
break;
}
ath9k_hw_btcoex_enable(ah);
}
EXPORT_SYMBOL(ath9k_cmn_btcoex_bt_stomp);
void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
u16 new_txpow, u16 *txpower)
{
......
......@@ -50,14 +50,6 @@
#define ATH_EP_RND(x, mul) \
((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
/* Defines the BT AR_BT_COEX_WGHT used */
enum ath_stomp_type {
ATH_BTCOEX_NO_STOMP,
ATH_BTCOEX_STOMP_ALL,
ATH_BTCOEX_STOMP_LOW,
ATH_BTCOEX_STOMP_NONE
};
int ath9k_cmn_padpos(__le16 frame_control);
int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
......
......@@ -326,6 +326,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
sc->debug.stats.istats.dtimsync++;
if (status & ATH9K_INT_DTIM)
sc->debug.stats.istats.dtim++;
if (status & ATH9K_INT_TSFOOR)
sc->debug.stats.istats.tsfoor++;
}
static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
......@@ -379,9 +381,12 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
"%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync);
len += snprintf(buf + len, sizeof(buf) - len,
"%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim);
len += snprintf(buf + len, sizeof(buf) - len,
"%8s: %10u\n", "TSFOOR", sc->debug.stats.istats.tsfoor);
len += snprintf(buf + len, sizeof(buf) - len,
"%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
if (len > sizeof(buf))
len = sizeof(buf);
......
......@@ -54,6 +54,9 @@ struct ath_buf;
* @dtimsync: DTIM sync lossage
* @dtim: RX Beacon with DTIM
* @bb_watchdog: Baseband watchdog
* @tsfoor: TSF out of range, indicates that the corrected TSF received
* from a beacon differs from the PCU's internal TSF by more than a
* (programmable) threshold
*/
struct ath_interrupt_stats {
u32 total;
......@@ -78,6 +81,7 @@ struct ath_interrupt_stats {
u32 dtimsync;
u32 dtim;
u32 bb_watchdog;
u32 tsfoor;
};
/**
......
......@@ -319,10 +319,9 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
u16 numXpdGain, xpdMask;
u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0};
u32 reg32, regOffset, regChainOffset, regval;
int16_t modalIdx, diff = 0;
int16_t diff = 0;
struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
xpdMask = pEepData->modalHeader.xpdGain;
if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
......
......@@ -231,6 +231,10 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
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 < AR_EEPROM_MODAL_SPURS; i++) {
word = swab16(pModal->spurChans[i].spurChan);
......
......@@ -46,6 +46,8 @@ void ath_init_leds(struct ath_softc *sc)
sc->sc_ah->led_pin = ATH_LED_PIN_9287;
else if (AR_SREV_9485(sc->sc_ah))
sc->sc_ah->led_pin = ATH_LED_PIN_9485;
else if (AR_SREV_9300(sc->sc_ah))
sc->sc_ah->led_pin = ATH_LED_PIN_9300;
else
sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
}
......@@ -138,10 +140,10 @@ static void ath_detect_bt_priority(struct ath_softc *sc)
static void ath9k_gen_timer_start(struct ath_hw *ah,
struct ath_gen_timer *timer,
u32 timer_next,
u32 trig_timeout,
u32 timer_period)
{
ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
ath9k_hw_gen_timer_start(ah, timer, trig_timeout, timer_period);
if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
ath9k_hw_disable_interrupts(ah);
......@@ -174,17 +176,17 @@ static void ath_btcoex_period_timer(unsigned long data)
struct ath_softc *sc = (struct ath_softc *) data;
struct ath_hw *ah = sc->sc_ah;
struct ath_btcoex *btcoex = &sc->btcoex;
struct ath_common *common = ath9k_hw_common(ah);
u32 timer_period;
bool is_btscan;
ath9k_ps_wakeup(sc);
ath_detect_bt_priority(sc);
is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
spin_lock_bh(&btcoex->btcoex_lock);
ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL :
ath9k_hw_btcoex_bt_stomp(ah, is_btscan ? ATH_BTCOEX_STOMP_ALL :
btcoex->bt_stomp_type);
spin_unlock_bh(&btcoex->btcoex_lock);
......@@ -195,11 +197,12 @@ static void ath_btcoex_period_timer(unsigned long data)
timer_period = is_btscan ? btcoex->btscan_no_stomp :
btcoex->btcoex_no_stomp;
ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, 0,
ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, timer_period,
timer_period * 10);
btcoex->hw_timer_enabled = true;
}
ath9k_ps_restore(sc);
mod_timer(&btcoex->period_timer, jiffies +
msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
}
......@@ -219,14 +222,16 @@ static void ath_btcoex_no_stomp_timer(void *arg)
ath_dbg(common, ATH_DBG_BTCOEX,
"no stomp timer running\n");
ath9k_ps_wakeup(sc);
spin_lock_bh(&btcoex->btcoex_lock);
if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE);
ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW);
ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW);
spin_unlock_bh(&btcoex->btcoex_lock);
ath9k_ps_restore(sc);
}
int ath_init_btcoex_timer(struct ath_softc *sc)
......
......@@ -17,6 +17,9 @@
#ifndef HTC_USB_H
#define HTC_USB_H
#define MAJOR_VERSION_REQ 1
#define MINOR_VERSION_REQ 2
#define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB))
#define AR9271_FIRMWARE 0x501000
......
......@@ -66,8 +66,6 @@ enum htc_opmode {
HTC_M_WDS = 2
};
#define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr)
#define ATH9K_HTC_AMPDU 1
#define ATH9K_HTC_NORMAL 2
#define ATH9K_HTC_BEACON 3
......@@ -75,7 +73,6 @@ enum htc_opmode {
#define ATH9K_HTC_TX_CTSONLY 0x1
#define ATH9K_HTC_TX_RTSCTS 0x2
#define ATH9K_HTC_TX_USE_MIN_RATE 0x100
struct tx_frame_hdr {
u8 data_type;
......@@ -106,15 +103,14 @@ struct tx_beacon_header {
u16 rev;
} __packed;
#define MAX_TX_AMPDU_SUBFRAMES_9271 17
#define MAX_TX_AMPDU_SUBFRAMES_7010 22
struct ath9k_htc_cap_target {
u32 flags;
u32 flags_ext;
u32 ampdu_limit;
__be32 ampdu_limit;
u8 ampdu_subframes;
u8 enable_coex;
u8 tx_chainmask;
u8 tx_chainmask_legacy;
u8 rtscts_ratecode;
u8 protmode;
u8 pad;
} __packed;
......@@ -175,6 +171,13 @@ struct ath9k_htc_target_rate {
struct ath9k_htc_rate rates;
};
struct ath9k_htc_target_rate_mask {
u8 vif_index;
u8 band;
__be32 mask;
u16 pad;
} __packed;
struct ath9k_htc_target_int_stats {
__be32 rx;
__be32 rxorn;
......@@ -382,25 +385,6 @@ static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
#define ATH_LED_PIN_9287 10
#define ATH_LED_PIN_9271 15
#define ATH_LED_PIN_7010 12
#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */
#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */
enum ath_led_type {
ATH_LED_RADIO,
ATH_LED_ASSOC,
ATH_LED_TX,
ATH_LED_RX
};
struct ath_led {
struct ath9k_htc_priv *priv;
struct led_classdev led_cdev;
enum ath_led_type led_type;
struct delayed_work brightness_work;
char name[32];
bool registered;
int brightness;
};
#define BSTUCK_THRESHOLD 10
......@@ -434,14 +418,11 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv);
#define OP_INVALID BIT(0)
#define OP_SCANNING BIT(1)
#define OP_LED_ASSOCIATED BIT(2)
#define OP_LED_ON BIT(3)
#define OP_ENABLE_BEACON BIT(4)
#define OP_LED_DEINIT BIT(5)
#define OP_BT_PRIORITY_DETECTED BIT(6)
#define OP_BT_SCAN BIT(7)
#define OP_ANI_RUNNING BIT(8)
#define OP_TSF_RESET BIT(9)
#define OP_ENABLE_BEACON BIT(2)
#define OP_BT_PRIORITY_DETECTED BIT(3)
#define OP_BT_SCAN BIT(4)
#define OP_ANI_RUNNING BIT(5)
#define OP_TSF_RESET BIT(6)
struct ath9k_htc_priv {
struct device *dev;
......@@ -501,15 +482,13 @@ struct ath9k_htc_priv {
bool ps_enabled;
bool ps_idle;
struct ath_led radio_led;
struct ath_led assoc_led;
struct ath_led tx_led;
struct ath_led rx_led;
struct delayed_work ath9k_led_blink_work;
int led_on_duration;
int led_off_duration;
int led_on_cnt;
int led_off_cnt;
#ifdef CONFIG_MAC80211_LEDS
enum led_brightness brightness;
bool led_registered;
char led_name[32];
struct led_classdev led_cdev;
struct work_struct led_work;
#endif
int beaconq;
int cabq;
......@@ -551,7 +530,8 @@ void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id,
void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
enum htc_endpoint_id ep_id, bool txok);
int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv);
int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
u8 enable_coex);
void ath9k_htc_station_work(struct work_struct *work);
void ath9k_htc_aggr_work(struct work_struct *work);
void ath9k_htc_ani_work(struct work_struct *work);
......@@ -593,9 +573,24 @@ void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw);
void ath9k_htc_radio_enable(struct ieee80211_hw *hw);
void ath9k_htc_radio_disable(struct ieee80211_hw *hw);
void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv);
#ifdef CONFIG_MAC80211_LEDS
void ath9k_init_leds(struct ath9k_htc_priv *priv);
void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
void ath9k_led_work(struct work_struct *work);
#else
static inline void ath9k_init_leds(struct ath9k_htc_priv *priv)
{
}
static inline void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
{
}
static inline void ath9k_led_work(struct work_struct *work)
{
}
#endif
int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
u16 devid, char *product, u32 drv_info);
......
......@@ -74,7 +74,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
__be32 htc_imask = 0;
u64 tsf;
int num_beacons, offset, dtim_dec_count, cfp_dec_count;
int ret;
int ret __attribute__ ((unused));
u8 cmd_rsp;
memset(&bs, 0, sizeof(bs));
......@@ -190,7 +190,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
enum ath9k_int imask = 0;
u32 nexttbtt, intval, tsftu;
__be32 htc_imask = 0;
int ret;
int ret __attribute__ ((unused));
u8 cmd_rsp;
u64 tsf;
......@@ -246,7 +246,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
enum ath9k_int imask = 0;
u32 nexttbtt, intval, tsftu;
__be32 htc_imask = 0;
int ret;
int ret __attribute__ ((unused));
u8 cmd_rsp;
u64 tsf;
......
......@@ -33,9 +33,15 @@ static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf,
memset(&cmd_rsp, 0, sizeof(cmd_rsp));
ath9k_htc_ps_wakeup(priv);
WMI_CMD(WMI_INT_STATS_CMDID);
if (ret)
if (ret) {
ath9k_htc_ps_restore(priv);
return -EINVAL;
}
ath9k_htc_ps_restore(priv);
len += snprintf(buf + len, sizeof(buf) - len,
"%20s : %10u\n", "RX",
......@@ -85,9 +91,15 @@ static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf,
memset(&cmd_rsp, 0, sizeof(cmd_rsp));
ath9k_htc_ps_wakeup(priv);
WMI_CMD(WMI_TX_STATS_CMDID);
if (ret)
if (ret) {
ath9k_htc_ps_restore(priv);
return -EINVAL;
}
ath9k_htc_ps_restore(priv);
len += snprintf(buf + len, sizeof(buf) - len,
"%20s : %10u\n", "Xretries",
......@@ -149,9 +161,15 @@ static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf,
memset(&cmd_rsp, 0, sizeof(cmd_rsp));
ath9k_htc_ps_wakeup(priv);
WMI_CMD(WMI_RX_STATS_CMDID);
if (ret)
if (ret) {
ath9k_htc_ps_restore(priv);
return -EINVAL;
}
ath9k_htc_ps_restore(priv);
len += snprintf(buf + len, sizeof(buf) - len,
"%20s : %10u\n", "NoBuf",
......@@ -474,6 +492,439 @@ static const struct file_operations fops_debug = {
.llseek = default_llseek,
};
static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath9k_htc_priv *priv = file->private_data;
struct ath_common *common = ath9k_hw_common(priv->ah);
struct base_eep_header *pBase = NULL;
unsigned int len = 0, size = 1500;
ssize_t retval = 0;
char *buf;
/*
* This can be done since all the 3 EEPROM families have the
* same base header upto a certain point, and we are interested in
* the data only upto that point.
*/
if (AR_SREV_9271(priv->ah))
pBase = (struct base_eep_header *)
&priv->ah->eeprom.map4k.baseEepHeader;
else if (priv->ah->hw_version.usbdev == AR9280_USB)
pBase = (struct base_eep_header *)
&priv->ah->eeprom.def.baseEepHeader;
else if (priv->ah->hw_version.usbdev == AR9287_USB)
pBase = (struct base_eep_header *)
&priv->ah->eeprom.map9287.baseEepHeader;
if (pBase == NULL) {
ath_err(common, "Unknown EEPROM type\n");
return 0;
}
buf = kzalloc(size, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
len += snprintf(buf + len, size - len,
"%20s : %10d\n", "Major Version",
pBase->version >> 12);
len += snprintf(buf + len, size - len,
"%20s : %10d\n", "Minor Version",
pBase->version & 0xFFF);
len += snprintf(buf + len, size - len,
"%20s : %10d\n", "Checksum",
pBase->checksum);
len += snprintf(buf + len, size - len,
"%20s : %10d\n", "Length",
pBase->length);
len += snprintf(buf + len, size - len,
"%20s : %10d\n", "RegDomain1",
pBase->regDmn[0]);
len += snprintf(buf + len, size - len,
"%20s : %10d\n", "RegDomain2",
pBase->regDmn[1]);
len += snprintf(buf + len, size - len,
"%20s : %10d\n",
"TX Mask", pBase->txMask);
len += snprintf(buf + len, size - len,
"%20s : %10d\n",
"RX Mask", pBase->rxMask);
len += snprintf(buf + len, size - len,
"%20s : %10d\n",
"Allow 5GHz",
!!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
len += snprintf(buf + len, size - len,
"%20s : %10d\n",
"Allow 2GHz",
!!(pBase->opCapFlags & AR5416_OPFLAGS_11G));
len += snprintf(buf + len, size - len,
"%20s : %10d\n",
"Disable 2GHz HT20",
!!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT20));
len += snprintf(buf + len, size - len,
"%20s : %10d\n",
"Disable 2GHz HT40",
!!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT40));
len += snprintf(buf + len, size - len,
"%20s : %10d\n",
"Disable 5Ghz HT20",
!!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT20));
len += snprintf(buf + len, size - len,
"%20s : %10d\n",
"Disable 5Ghz HT40",
!!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT40));
len += snprintf(buf + len, size - len,
"%20s : %10d\n",
"Big Endian",
!!(pBase->eepMisc & 0x01));
len += snprintf(buf + len, size - len,
"%20s : %10d\n",
"Cal Bin Major Ver",
(pBase->binBuildNumber >> 24) & 0xFF);
len += snprintf(buf + len, size - len,
"%20s : %10d\n",
"Cal Bin Minor Ver",
(pBase->binBuildNumber >> 16) & 0xFF);
len += snprintf(buf + len, size - len,
"%20s : %10d\n",
"Cal Bin Build",
(pBase->binBuildNumber >> 8) & 0xFF);
/*
* UB91 specific data.
*/
if (AR_SREV_9271(priv->ah)) {
struct base_eep_header_4k *pBase4k =
&priv->ah->eeprom.map4k.baseEepHeader;
len += snprintf(buf + len, size - len,
"%20s : %10d\n",
"TX Gain type",
pBase4k->txGainType);
}
/*
* UB95 specific data.
*/
if (priv->ah->hw_version.usbdev == AR9287_USB) {
struct base_eep_ar9287_header *pBase9287 =
&priv->ah->eeprom.map9287.baseEepHeader;
len += snprintf(buf + len, size - len,
"%20s : %10ddB\n",
"Power Table Offset",
pBase9287->pwrTableOffset);
len += snprintf(buf + len, size - len,
"%20s : %10d\n",
"OpenLoop Power Ctrl",
pBase9287->openLoopPwrCntl);
}
len += snprintf(buf + len, size - len,
"%20s : %02X:%02X:%02X:%02X:%02X:%02X\n",
"MacAddress",
pBase->macAddr[0], pBase->macAddr[1], pBase->macAddr[2],
pBase->macAddr[3], pBase->macAddr[4], pBase->macAddr[5]);
if (len > size)
len = size;
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
return retval;
}
static const struct file_operations fops_base_eeprom = {
.read = read_file_base_eeprom,
.open = ath9k_debugfs_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
static ssize_t read_4k_modal_eeprom(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
#define PR_EEP(_s, _val) \
do { \
len += snprintf(buf + len, size - len, "%20s : %10d\n", \
_s, (_val)); \
} while (0)
struct ath9k_htc_priv *priv = file->private_data;
struct modal_eep_4k_header *pModal = &priv->ah->eeprom.map4k.modalHeader;
unsigned int len = 0, size = 2048;
ssize_t retval = 0;
char *buf;
buf = kzalloc(size, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
PR_EEP("Switch Settle", pModal->switchSettling);
PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
PR_EEP("ADC Desired size", pModal->adcDesiredSize);
PR_EEP("PGA Desired size", pModal->pgaDesiredSize);
PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]);
PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
PR_EEP("CCA Threshold)", pModal->thresh62);
PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
PR_EEP("xpdGain", pModal->xpdGain);
PR_EEP("External PD", pModal->xpd);
PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
PR_EEP("O/D Bias Version", pModal->version);
PR_EEP("CCK OutputBias", pModal->ob_0);
PR_EEP("BPSK OutputBias", pModal->ob_1);
PR_EEP("QPSK OutputBias", pModal->ob_2);
PR_EEP("16QAM OutputBias", pModal->ob_3);
PR_EEP("64QAM OutputBias", pModal->ob_4);
PR_EEP("CCK Driver1_Bias", pModal->db1_0);
PR_EEP("BPSK Driver1_Bias", pModal->db1_1);
PR_EEP("QPSK Driver1_Bias", pModal->db1_2);
PR_EEP("16QAM Driver1_Bias", pModal->db1_3);
PR_EEP("64QAM Driver1_Bias", pModal->db1_4);
PR_EEP("CCK Driver2_Bias", pModal->db2_0);
PR_EEP("BPSK Driver2_Bias", pModal->db2_1);
PR_EEP("QPSK Driver2_Bias", pModal->db2_2);
PR_EEP("16QAM Driver2_Bias", pModal->db2_3);
PR_EEP("64QAM Driver2_Bias", pModal->db2_4);
PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]);
PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]);
PR_EEP("Ant. Diversity ctl1", pModal->antdiv_ctl1);
PR_EEP("Ant. Diversity ctl2", pModal->antdiv_ctl2);
PR_EEP("TX Diversity", pModal->tx_diversity);
if (len > size)
len = size;
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
return retval;
#undef PR_EEP
}
static ssize_t read_def_modal_eeprom(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
#define PR_EEP(_s, _val) \
do { \
if (pBase->opCapFlags & AR5416_OPFLAGS_11G) { \
pModal = &priv->ah->eeprom.def.modalHeader[1]; \
len += snprintf(buf + len, size - len, "%20s : %8d%7s", \
_s, (_val), "|"); \
} \
if (pBase->opCapFlags & AR5416_OPFLAGS_11A) { \
pModal = &priv->ah->eeprom.def.modalHeader[0]; \
len += snprintf(buf + len, size - len, "%9d\n", \
(_val)); \
} \
} while (0)
struct ath9k_htc_priv *priv = file->private_data;
struct base_eep_header *pBase = &priv->ah->eeprom.def.baseEepHeader;
struct modal_eep_header *pModal = NULL;
unsigned int len = 0, size = 3500;
ssize_t retval = 0;
char *buf;
buf = kzalloc(size, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
len += snprintf(buf + len, size - len,
"%31s %15s\n", "2G", "5G");
len += snprintf(buf + len, size - len,
"%32s %16s\n", "====", "====\n");
PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]);
PR_EEP("Chain2 Ant. Control", pModal->antCtrlChain[2]);
PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]);
PR_EEP("Chain2 Ant. Gain", pModal->antennaGainCh[2]);
PR_EEP("Switch Settle", pModal->switchSettling);
PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]);
PR_EEP("Chain2 TxRxAtten", pModal->txRxAttenCh[2]);
PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]);
PR_EEP("Chain2 RxTxMargin", pModal->rxTxMarginCh[2]);
PR_EEP("ADC Desired size", pModal->adcDesiredSize);
PR_EEP("PGA Desired size", pModal->pgaDesiredSize);
PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]);
PR_EEP("Chain1 xlna Gain", pModal->xlnaGainCh[1]);
PR_EEP("Chain2 xlna Gain", pModal->xlnaGainCh[2]);
PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
PR_EEP("CCA Threshold)", pModal->thresh62);
PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]);
PR_EEP("Chain2 NF Threshold", pModal->noiseFloorThreshCh[2]);
PR_EEP("xpdGain", pModal->xpdGain);
PR_EEP("External PD", pModal->xpd);
PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]);
PR_EEP("Chain2 I Coefficient", pModal->iqCalICh[2]);
PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]);
PR_EEP("Chain2 Q Coefficient", pModal->iqCalQCh[2]);
PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
PR_EEP("Chain0 OutputBias", pModal->ob);
PR_EEP("Chain0 DriverBias", pModal->db);
PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
PR_EEP("2chain pwr decrease", pModal->pwrDecreaseFor2Chain);
PR_EEP("3chain pwr decrease", pModal->pwrDecreaseFor3Chain);
PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]);
PR_EEP("Chain2 bswAtten", pModal->bswAtten[2]);
PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]);
PR_EEP("Chain2 bswMargin", pModal->bswMargin[2]);
PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]);
PR_EEP("Chain1 xatten2Db", pModal->xatten2Db[1]);
PR_EEP("Chain2 xatten2Db", pModal->xatten2Db[2]);
PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]);
PR_EEP("Chain1 xatten2Margin", pModal->xatten2Margin[1]);
PR_EEP("Chain2 xatten2Margin", pModal->xatten2Margin[2]);
PR_EEP("Chain1 OutputBias", pModal->ob_ch1);
PR_EEP("Chain1 DriverBias", pModal->db_ch1);
PR_EEP("LNA Control", pModal->lna_ctl);
PR_EEP("XPA Bias Freq0", pModal->xpaBiasLvlFreq[0]);
PR_EEP("XPA Bias Freq1", pModal->xpaBiasLvlFreq[1]);
PR_EEP("XPA Bias Freq2", pModal->xpaBiasLvlFreq[2]);
if (len > size)
len = size;
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
return retval;
#undef PR_EEP
}
static ssize_t read_9287_modal_eeprom(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
#define PR_EEP(_s, _val) \
do { \
len += snprintf(buf + len, size - len, "%20s : %10d\n", \
_s, (_val)); \
} while (0)
struct ath9k_htc_priv *priv = file->private_data;
struct modal_eep_ar9287_header *pModal = &priv->ah->eeprom.map9287.modalHeader;
unsigned int len = 0, size = 3000;
ssize_t retval = 0;
char *buf;
buf = kzalloc(size, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]);
PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]);
PR_EEP("Switch Settle", pModal->switchSettling);
PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]);
PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]);
PR_EEP("ADC Desired size", pModal->adcDesiredSize);
PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
PR_EEP("CCA Threshold)", pModal->thresh62);
PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]);
PR_EEP("xpdGain", pModal->xpdGain);
PR_EEP("External PD", pModal->xpd);
PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]);
PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]);
PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]);
PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]);
PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
PR_EEP("AR92x7 Version", pModal->version);
PR_EEP("DriverBias1", pModal->db1);
PR_EEP("DriverBias2", pModal->db1);
PR_EEP("CCK OutputBias", pModal->ob_cck);
PR_EEP("PSK OutputBias", pModal->ob_psk);
PR_EEP("QAM OutputBias", pModal->ob_qam);
PR_EEP("PAL_OFF OutputBias", pModal->ob_pal_off);
if (len > size)
len = size;
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
return retval;
#undef PR_EEP
}
static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath9k_htc_priv *priv = file->private_data;
if (AR_SREV_9271(priv->ah))
return read_4k_modal_eeprom(file, user_buf, count, ppos);
else if (priv->ah->hw_version.usbdev == AR9280_USB)
return read_def_modal_eeprom(file, user_buf, count, ppos);
else if (priv->ah->hw_version.usbdev == AR9287_USB)
return read_9287_modal_eeprom(file, user_buf, count, ppos);
return 0;
}
static const struct file_operations fops_modal_eeprom = {
.read = read_file_modal_eeprom,
.open = ath9k_debugfs_open,
.owner = THIS_MODULE,
.llseek = default_llseek,
};
int ath9k_htc_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
......@@ -500,6 +951,10 @@ int ath9k_htc_init_debug(struct ath_hw *ah)
priv, &fops_queue);
debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy,
priv, &fops_debug);
debugfs_create_file("base_eeprom", S_IRUSR, priv->debug.debugfs_phy,
priv, &fops_base_eeprom);
debugfs_create_file("modal_eeprom", S_IRUSR, priv->debug.debugfs_phy,
priv, &fops_modal_eeprom);
return 0;
}
......@@ -65,17 +65,19 @@ static void ath_btcoex_period_work(struct work_struct *work)
u32 timer_period;
bool is_btscan;
int ret;
u8 cmd_rsp, aggr;
ath_detect_bt_priority(priv);
is_btscan = !!(priv->op_flags & OP_BT_SCAN);
aggr = priv->op_flags & OP_BT_PRIORITY_DETECTED;
WMI_CMD_BUF(WMI_AGGR_LIMIT_CMD, &aggr);
ret = ath9k_htc_update_cap_target(priv,
!!(priv->op_flags & OP_BT_PRIORITY_DETECTED));
if (ret) {
ath_err(common, "Unable to set BTCOEX parameters\n");
return;
}
ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL :
ath9k_hw_btcoex_bt_stomp(priv->ah, is_btscan ? ATH_BTCOEX_STOMP_ALL :
btcoex->bt_stomp_type);
timer_period = is_btscan ? btcoex->btscan_no_stomp :
......@@ -103,9 +105,9 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work)
"time slice work for bt and wlan\n");
if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE);
ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW);
ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW);
}
void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv)
......@@ -152,140 +154,41 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv)
/* LED */
/*******/
static void ath9k_led_blink_work(struct work_struct *work)
#ifdef CONFIG_MAC80211_LEDS
void ath9k_led_work(struct work_struct *work)
{
struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
ath9k_led_blink_work.work);
if (!(priv->op_flags & OP_LED_ASSOCIATED))
return;
if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
(priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
else
ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
(priv->op_flags & OP_LED_ON) ? 1 : 0);
ieee80211_queue_delayed_work(priv->hw,
&priv->ath9k_led_blink_work,
(priv->op_flags & OP_LED_ON) ?
msecs_to_jiffies(priv->led_off_duration) :
msecs_to_jiffies(priv->led_on_duration));
priv->led_on_duration = priv->led_on_cnt ?
max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
ATH_LED_ON_DURATION_IDLE;
priv->led_off_duration = priv->led_off_cnt ?
max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
ATH_LED_OFF_DURATION_IDLE;
priv->led_on_cnt = priv->led_off_cnt = 0;
if (priv->op_flags & OP_LED_ON)
priv->op_flags &= ~OP_LED_ON;
else
priv->op_flags |= OP_LED_ON;
}
struct ath9k_htc_priv *priv = container_of(work,
struct ath9k_htc_priv,
led_work);
static void ath9k_led_brightness_work(struct work_struct *work)
{
struct ath_led *led = container_of(work, struct ath_led,
brightness_work.work);
struct ath9k_htc_priv *priv = led->priv;
switch (led->brightness) {
case LED_OFF:
if (led->led_type == ATH_LED_ASSOC ||
led->led_type == ATH_LED_RADIO) {
ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
(led->led_type == ATH_LED_RADIO));
priv->op_flags &= ~OP_LED_ASSOCIATED;
if (led->led_type == ATH_LED_RADIO)
priv->op_flags &= ~OP_LED_ON;
} else {
priv->led_off_cnt++;
}
break;
case LED_FULL:
if (led->led_type == ATH_LED_ASSOC) {
priv->op_flags |= OP_LED_ASSOCIATED;
ieee80211_queue_delayed_work(priv->hw,
&priv->ath9k_led_blink_work, 0);
} else if (led->led_type == ATH_LED_RADIO) {
ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
priv->op_flags |= OP_LED_ON;
} else {
priv->led_on_cnt++;
}
break;
default:
break;
}
(priv->brightness == LED_OFF));
}
static void ath9k_led_brightness(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
struct ath9k_htc_priv *priv = led->priv;
led->brightness = brightness;
if (!(priv->op_flags & OP_LED_DEINIT))
ieee80211_queue_delayed_work(priv->hw,
&led->brightness_work, 0);
}
void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
{
cancel_delayed_work_sync(&priv->radio_led.brightness_work);
cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
cancel_delayed_work_sync(&priv->tx_led.brightness_work);
cancel_delayed_work_sync(&priv->rx_led.brightness_work);
}
static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
char *trigger)
{
int ret;
led->priv = priv;
led->led_cdev.name = led->name;
led->led_cdev.default_trigger = trigger;
led->led_cdev.brightness_set = ath9k_led_brightness;
ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
if (ret)
ath_err(ath9k_hw_common(priv->ah),
"Failed to register led:%s", led->name);
else
led->registered = 1;
struct ath9k_htc_priv *priv = container_of(led_cdev,
struct ath9k_htc_priv,
led_cdev);
INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
return ret;
}
static void ath9k_unregister_led(struct ath_led *led)
{
if (led->registered) {
led_classdev_unregister(&led->led_cdev);
led->registered = 0;
}
/* Not locked, but it's just a tiny green light..*/
priv->brightness = brightness;
ieee80211_queue_work(priv->hw, &priv->led_work);
}
void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
{
priv->op_flags |= OP_LED_DEINIT;
ath9k_unregister_led(&priv->assoc_led);
priv->op_flags &= ~OP_LED_ASSOCIATED;
ath9k_unregister_led(&priv->tx_led);
ath9k_unregister_led(&priv->rx_led);
ath9k_unregister_led(&priv->radio_led);
if (!priv->led_registered)
return;
ath9k_led_brightness(&priv->led_cdev, LED_OFF);
led_classdev_unregister(&priv->led_cdev);
cancel_work_sync(&priv->led_work);
}
void ath9k_init_leds(struct ath9k_htc_priv *priv)
{
char *trigger;
int ret;
if (AR_SREV_9287(priv->ah))
......@@ -303,48 +206,21 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv)
/* LED off, active low */
ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
trigger = ieee80211_get_radio_led_name(priv->hw);
snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
"ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
ret = ath9k_register_led(priv, &priv->radio_led, trigger);
priv->radio_led.led_type = ATH_LED_RADIO;
if (ret)
goto fail;
trigger = ieee80211_get_assoc_led_name(priv->hw);
snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name),
"ath9k-%s::assoc", wiphy_name(priv->hw->wiphy));
ret = ath9k_register_led(priv, &priv->assoc_led, trigger);
priv->assoc_led.led_type = ATH_LED_ASSOC;
if (ret)
goto fail;
trigger = ieee80211_get_tx_led_name(priv->hw);
snprintf(priv->tx_led.name, sizeof(priv->tx_led.name),
"ath9k-%s::tx", wiphy_name(priv->hw->wiphy));
ret = ath9k_register_led(priv, &priv->tx_led, trigger);
priv->tx_led.led_type = ATH_LED_TX;
if (ret)
goto fail;
trigger = ieee80211_get_rx_led_name(priv->hw);
snprintf(priv->rx_led.name, sizeof(priv->rx_led.name),
"ath9k-%s::rx", wiphy_name(priv->hw->wiphy));
ret = ath9k_register_led(priv, &priv->rx_led, trigger);
priv->rx_led.led_type = ATH_LED_RX;
if (ret)
goto fail;
priv->op_flags &= ~OP_LED_DEINIT;
snprintf(priv->led_name, sizeof(priv->led_name),
"ath9k_htc-%s", wiphy_name(priv->hw->wiphy));
priv->led_cdev.name = priv->led_name;
priv->led_cdev.brightness_set = ath9k_led_brightness;
ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &priv->led_cdev);
if (ret < 0)
return;
fail:
cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
ath9k_deinit_leds(priv);
INIT_WORK(&priv->led_work, ath9k_led_work);
priv->led_registered = true;
return;
}
#endif
/*******************/
/* Rfkill */
......
......@@ -117,6 +117,21 @@ static struct ieee80211_rate ath9k_legacy_rates[] = {
RATE(540, 0x0c, 0),
};
#ifdef CONFIG_MAC80211_LEDS
static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = {
{ .throughput = 0 * 1024, .blink_time = 334 },
{ .throughput = 1 * 1024, .blink_time = 260 },
{ .throughput = 5 * 1024, .blink_time = 220 },
{ .throughput = 10 * 1024, .blink_time = 190 },
{ .throughput = 20 * 1024, .blink_time = 170 },
{ .throughput = 50 * 1024, .blink_time = 150 },
{ .throughput = 70 * 1024, .blink_time = 130 },
{ .throughput = 100 * 1024, .blink_time = 110 },
{ .throughput = 200 * 1024, .blink_time = 80 },
{ .throughput = 300 * 1024, .blink_time = 50 },
};
#endif
static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
{
int time_left;
......@@ -243,7 +258,7 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid,
*/
if (IS_AR7010_DEVICE(drv_info))
priv->htc->credits = 45;
priv->htc->credits = 48;
else
priv->htc->credits = 33;
......@@ -753,6 +768,12 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
hw->queues = 4;
hw->channel_change_time = 5000;
hw->max_listen_interval = 10;
if (AR_SREV_9271(priv->ah))
hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_9271;
else
hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_7010;
hw->vif_data_size = sizeof(struct ath9k_htc_vif);
hw->sta_data_size = sizeof(struct ath9k_htc_sta);
......@@ -802,6 +823,17 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
priv->fw_version_major,
priv->fw_version_minor);
/*
* Check if the available FW matches the driver's
* required version.
*/
if (priv->fw_version_major != MAJOR_VERSION_REQ ||
priv->fw_version_minor != MINOR_VERSION_REQ) {
dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n",
MAJOR_VERSION_REQ, MINOR_VERSION_REQ);
return -EINVAL;
}
return 0;
}
......@@ -846,6 +878,13 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
if (error != 0)
goto err_rx;
#ifdef CONFIG_MAC80211_LEDS
/* must be initialized before ieee80211_register_hw */
priv->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(priv->hw,
IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_htc_tpt_blink,
ARRAY_SIZE(ath9k_htc_tpt_blink));
#endif
/* Register with mac80211 */
error = ieee80211_register_hw(hw);
if (error)
......
......@@ -332,6 +332,11 @@ static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
hvif.index = priv->mon_vif_idx;
WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
if (ret) {
ath_err(common, "Unable to remove monitor interface at idx: %d\n",
priv->mon_vif_idx);
}
priv->nvifs--;
priv->vif_slot &= ~(1 << priv->mon_vif_idx);
}
......@@ -462,6 +467,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
struct ath9k_htc_sta *ista;
int ret, sta_idx;
u8 cmd_rsp;
u16 maxampdu;
if (priv->nstations >= ATH9K_HTC_MAX_STA)
return -ENOBUFS;
......@@ -485,7 +491,15 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
tsta.sta_index = sta_idx;
tsta.vif_index = avp->index;
if (!sta) {
tsta.maxampdu = cpu_to_be16(0xffff);
} else {
maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
sta->ht_cap.ampdu_factor);
tsta.maxampdu = cpu_to_be16(maxampdu);
}
if (sta && sta->ht_cap.ht_supported)
tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
......@@ -558,7 +572,8 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
return 0;
}
int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
u8 enable_coex)
{
struct ath9k_htc_cap_target tcap;
int ret;
......@@ -566,13 +581,9 @@ int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
/* FIXME: Values are hardcoded */
tcap.flags = 0x240c40;
tcap.flags_ext = 0x80601000;
tcap.ampdu_limit = 0xffff0000;
tcap.ampdu_subframes = 20;
tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask;
tcap.protmode = 1;
tcap.ampdu_limit = cpu_to_be32(0xffff);
tcap.ampdu_subframes = priv->hw->max_tx_aggregation_subframes;
tcap.enable_coex = enable_coex;
tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
......@@ -931,7 +942,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
ath9k_host_rx_init(priv);
ret = ath9k_htc_update_cap_target(priv);
ret = ath9k_htc_update_cap_target(priv, 0);
if (ret)
ath_dbg(common, ATH_DBG_CONFIG,
"Failed to update capability in target\n");
......@@ -964,7 +975,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
struct ath9k_htc_priv *priv = hw->priv;
struct ath_hw *ah = priv->ah;
struct ath_common *common = ath9k_hw_common(ah);
int ret = 0;
int ret __attribute__ ((unused));
u8 cmd_rsp;
mutex_lock(&priv->mutex);
......@@ -992,9 +1003,11 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
/* Cancel all the running timers/work .. */
cancel_work_sync(&priv->fatal_work);
cancel_work_sync(&priv->ps_work);
cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
#ifdef CONFIG_MAC80211_LEDS
cancel_work_sync(&priv->led_work);
#endif
ath9k_htc_stop_ani(priv);
ath9k_led_stop_brightness(priv);
mutex_lock(&priv->mutex);
......@@ -1135,6 +1148,10 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
hvif.index = avp->index;
WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
if (ret) {
ath_err(common, "Unable to remove interface at idx: %d\n",
avp->index);
}
priv->nvifs--;
priv->vif_slot &= ~(1 << avp->index);
......@@ -1567,6 +1584,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
int ret = 0;
mutex_lock(&priv->mutex);
ath9k_htc_ps_wakeup(priv);
switch (action) {
case IEEE80211_AMPDU_RX_START:
......@@ -1592,6 +1610,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
}
ath9k_htc_ps_restore(priv);
mutex_unlock(&priv->mutex);
return ret;
......@@ -1642,6 +1661,55 @@ static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
mutex_unlock(&priv->mutex);
}
/*
* Currently, this is used only for selecting the minimum rate
* for management frames, rate selection for data frames remain
* unaffected.
*/
static int ath9k_htc_set_bitrate_mask(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
const struct cfg80211_bitrate_mask *mask)
{
struct ath9k_htc_priv *priv = hw->priv;
struct ath_common *common = ath9k_hw_common(priv->ah);
struct ath9k_htc_target_rate_mask tmask;
struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
int ret = 0;
u8 cmd_rsp;
memset(&tmask, 0, sizeof(struct ath9k_htc_target_rate_mask));
tmask.vif_index = avp->index;
tmask.band = IEEE80211_BAND_2GHZ;
tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_2GHZ].legacy);
WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
if (ret) {
ath_err(common,
"Unable to set 2G rate mask for "
"interface at idx: %d\n", avp->index);
goto out;
}
tmask.band = IEEE80211_BAND_5GHZ;
tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_5GHZ].legacy);
WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
if (ret) {
ath_err(common,
"Unable to set 5G rate mask for "
"interface at idx: %d\n", avp->index);
goto out;
}
ath_dbg(common, ATH_DBG_CONFIG,
"Set bitrate masks: 0x%x, 0x%x\n",
mask->control[IEEE80211_BAND_2GHZ].legacy,
mask->control[IEEE80211_BAND_5GHZ].legacy);
out:
return ret;
}
struct ieee80211_ops ath9k_htc_ops = {
.tx = ath9k_htc_tx,
.start = ath9k_htc_start,
......@@ -1664,4 +1732,5 @@ struct ieee80211_ops ath9k_htc_ops = {
.set_rts_threshold = ath9k_htc_set_rts_threshold,
.rfkill_poll = ath9k_htc_rfkill_poll_state,
.set_coverage_class = ath9k_htc_set_coverage_class,
.set_bitrate_mask = ath9k_htc_set_bitrate_mask,
};
......@@ -446,7 +446,6 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
struct ieee80211_tx_info *tx_info;
struct ieee80211_tx_rate *rate;
struct ieee80211_conf *cur_conf = &priv->hw->conf;
struct ieee80211_supported_band *sband;
bool txok;
int slot;
......@@ -461,7 +460,6 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
tx_info = IEEE80211_SKB_CB(skb);
vif = tx_info->control.vif;
rate = &tx_info->status.rates[0];
sband = priv->hw->wiphy->bands[cur_conf->channel->band];
memset(&tx_info->status, 0, sizeof(tx_info->status));
......
......@@ -83,21 +83,10 @@ struct htc_ep_callbacks {
void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id);
};
#define HTC_TX_QUEUE_SIZE 256
struct htc_txq {
struct sk_buff *buf[HTC_TX_QUEUE_SIZE];
u32 txqdepth;
u16 txbuf_cnt;
u16 txq_head;
u16 txq_tail;
};
struct htc_endpoint {
u16 service_id;
struct htc_ep_callbacks ep_callbacks;
struct htc_txq htc_txq;
u32 max_txqdepth;
int max_msglen;
......
......@@ -247,6 +247,17 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
{
u32 val;
switch (ah->hw_version.devid) {
case AR5416_AR9100_DEVID:
ah->hw_version.macVersion = AR_SREV_VERSION_9100;
break;
case AR9300_DEVID_AR9340:
ah->hw_version.macVersion = AR_SREV_VERSION_9340;
val = REG_READ(ah, AR_SREV);
ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
return;
}
val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
if (val == 0xFF) {
......@@ -462,7 +473,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
return ecode;
}
if (!AR_SREV_9100(ah)) {
if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) {
ath9k_hw_ani_setup(ah);
ath9k_hw_ani_init(ah);
}
......@@ -484,9 +495,6 @@ static int __ath9k_hw_init(struct ath_hw *ah)
struct ath_common *common = ath9k_hw_common(ah);
int r = 0;
if (ah->hw_version.devid == AR5416_AR9100_DEVID)
ah->hw_version.macVersion = AR_SREV_VERSION_9100;
ath9k_hw_read_revisions(ah);
/*
......@@ -544,6 +552,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
case AR_SREV_VERSION_9271:
case AR_SREV_VERSION_9300:
case AR_SREV_VERSION_9485:
case AR_SREV_VERSION_9340:
break;
default:
ath_err(common,
......@@ -552,7 +561,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
return -EOPNOTSUPP;
}
if (AR_SREV_9271(ah) || AR_SREV_9100(ah))
if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah))
ah->is_pciexpress = false;
ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
......@@ -621,6 +630,7 @@ int ath9k_hw_init(struct ath_hw *ah)
case AR2427_DEVID_PCIE:
case AR9300_DEVID_PCIE:
case AR9300_DEVID_AR9485_PCIE:
case AR9300_DEVID_AR9340:
break;
default:
if (common->bus_ops->ath_bus_type == ATH_USB)
......@@ -663,7 +673,7 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
REGWRITE_BUFFER_FLUSH(ah);
}
unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
{
REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
udelay(100);
......@@ -676,7 +686,6 @@ unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
}
EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc);
#define DPLL3_PHASE_SHIFT_VAL 0x1
static void ath9k_hw_init_pll(struct ath_hw *ah,
struct ath9k_channel *chan)
{
......@@ -713,16 +722,48 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
AR_CH0_BB_DPLL2_PLL_PWD, 0x0);
udelay(1000);
} else if (AR_SREV_9340(ah)) {
u32 regval, pll2_divint, pll2_divfrac, refdiv;
REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
udelay(1000);
REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16);
udelay(100);
if (ah->is_clk_25mhz) {
pll2_divint = 0x54;
pll2_divfrac = 0x1eb85;
refdiv = 3;
} else {
pll2_divint = 88;
pll2_divfrac = 0;
refdiv = 5;
}
regval = REG_READ(ah, AR_PHY_PLL_MODE);
regval |= (0x1 << 16);
REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
udelay(100);
REG_WRITE(ah, AR_PHY_PLL_CONTROL, (refdiv << 27) |
(pll2_divint << 18) | pll2_divfrac);
udelay(100);
regval = REG_READ(ah, AR_PHY_PLL_MODE);
regval = (regval & 0x80071fff) | (0x1 << 30) | (0x1 << 13) |
(0x4 << 26) | (0x18 << 19);
REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
REG_WRITE(ah, AR_PHY_PLL_MODE,
REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff);
udelay(1000);
}
pll = ath9k_hw_compute_pll_control(ah, chan);
REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
if (AR_SREV_9485(ah))
if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
udelay(1000);
/* Switch the core clock for ar9271 to 117Mhz */
......@@ -734,17 +775,34 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
udelay(RTC_PLL_SETTLE_DELAY);
REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
if (AR_SREV_9340(ah)) {
if (ah->is_clk_25mhz) {
REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
} else {
REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
}
udelay(100);
}
}
static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
enum nl80211_iftype opmode)
{
u32 sync_default = AR_INTR_SYNC_DEFAULT;
u32 imr_reg = AR_IMR_TXERR |
AR_IMR_TXURN |
AR_IMR_RXERR |
AR_IMR_RXORN |
AR_IMR_BCNMISC;
if (AR_SREV_9340(ah))
sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
if (AR_SREV_9300_20_OR_LATER(ah)) {
imr_reg |= AR_IMR_RXOK_HP;
if (ah->config.rx_intr_mitigation)
......@@ -775,7 +833,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
if (!AR_SREV_9100(ah)) {
REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
}
......@@ -1487,6 +1545,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
}
#ifdef __BIG_ENDIAN
else if (AR_SREV_9340(ah))
REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0);
else
REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
#endif
......@@ -1793,7 +1853,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
struct ath_common *common = ath9k_hw_common(ah);
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
u16 capField = 0, eeval;
u16 eeval;
u8 ant_div_ctl1, tx_chainmask, rx_chainmask;
eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
......@@ -1804,8 +1864,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
eeval |= AR9285_RDEXT_DEFAULT;
regulatory->current_rd_ext = eeval;
capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
if (ah->opmode != NL80211_IFTYPE_AP &&
ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
if (regulatory->current_rd == 0x64 ||
......@@ -1898,16 +1956,24 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
else
pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) {
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO;
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
if (common->btcoex_enabled) {
if (AR_SREV_9300_20_OR_LATER(ah)) {
btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300;
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300;
btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9300;
} else if (AR_SREV_9280_20_OR_LATER(ah)) {
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9280;
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9280;
if (AR_SREV_9285(ah)) {
btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO;
btcoex_hw->btpriority_gpio =
ATH_BTPRIORITY_GPIO_9285;
} else {
btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
}
}
} else {
btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
}
......@@ -2359,11 +2425,11 @@ EXPORT_SYMBOL(ath_gen_timer_alloc);
void ath9k_hw_gen_timer_start(struct ath_hw *ah,
struct ath_gen_timer *timer,
u32 timer_next,
u32 trig_timeout,
u32 timer_period)
{
struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
u32 tsf;
u32 tsf, timer_next;
BUG_ON(!timer_period);
......@@ -2371,17 +2437,12 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah,
tsf = ath9k_hw_gettsf32(ah);
timer_next = tsf + trig_timeout;
ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER,
"current tsf %x period %x timer_next %x\n",
tsf, timer_period, timer_next);
/*
* Pull timer_next forward if the current TSF already passed it
* because of software latency
*/
if (timer_next < tsf)
timer_next = tsf + timer_period;
/*
* Program generic timer registers
*/
......
......@@ -43,6 +43,7 @@
#define AR9287_DEVID_PCI 0x002d
#define AR9287_DEVID_PCIE 0x002e
#define AR9300_DEVID_PCIE 0x0030
#define AR9300_DEVID_AR9340 0x0031
#define AR9300_DEVID_AR9485_PCIE 0x0032
#define AR5416_AR9100_DEVID 0x000b
......@@ -55,6 +56,9 @@
#define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa
#define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab
#define AR9300_NUM_BT_WEIGHTS 4
#define AR9300_NUM_WLAN_WEIGHTS 4
#define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1)
#define ATH_DEFAULT_NOISE_FLOOR -95
......@@ -121,7 +125,7 @@
#define AR_GPIO_BIT(_gpio) (1 << (_gpio))
#define BASE_ACTIVATE_DELAY 100
#define RTC_PLL_SETTLE_DELAY 100
#define RTC_PLL_SETTLE_DELAY (AR_SREV_9340(ah) ? 1000 : 100)
#define COEF_SCALE_S 24
#define HT40_CHANNEL_CENTER_SHIFT 10
......@@ -771,6 +775,8 @@ struct ath_hw {
/* Bluetooth coexistance */
struct ath_btcoex_hw btcoex_hw;
u32 bt_coex_bt_weight[AR9300_NUM_BT_WEIGHTS];
u32 bt_coex_wlan_weight[AR9300_NUM_WLAN_WEIGHTS];
u32 intr_txqs;
u8 txchainmask;
......@@ -799,6 +805,7 @@ struct ath_hw {
struct ar5416IniArray iniPcieSerdes;
struct ar5416IniArray iniPcieSerdesLowPower;
struct ar5416IniArray iniModesAdditional;
struct ar5416IniArray iniModesAdditional_40M;
struct ar5416IniArray iniModesRxGain;
struct ar5416IniArray iniModesTxGain;
struct ar5416IniArray iniModes_9271_1_0_only;
......@@ -845,6 +852,8 @@ struct ath_hw {
/* Enterprise mode cap */
u32 ent_mode;
bool is_clk_25mhz;
};
struct ath_bus_ops {
......@@ -928,7 +937,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
void ath9k_hw_reset_tsf(struct ath_hw *ah);
void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
void ath9k_hw_init_global_settings(struct ath_hw *ah);
unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
void ath9k_hw_set11nmac2040(struct ath_hw *ah);
void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
......
......@@ -574,6 +574,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
sc->sc_ah->gpio_mask = pdata->gpio_mask;
sc->sc_ah->gpio_val = pdata->gpio_val;
sc->sc_ah->led_pin = pdata->led_pin;
ah->is_clk_25mhz = pdata->is_clk_25mhz;
}
common = ath9k_hw_common(ah);
......@@ -800,6 +801,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
INIT_WORK(&sc->hw_check_work, ath_hw_check);
INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
ath_init_leds(sc);
......
......@@ -812,10 +812,14 @@ EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
void ath9k_hw_enable_interrupts(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
u32 sync_default = AR_INTR_SYNC_DEFAULT;
if (!(ah->imask & ATH9K_INT_GLOBAL))
return;
if (AR_SREV_9340(ah))
sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n");
REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
if (!AR_SREV_9100(ah)) {
......@@ -824,10 +828,8 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)
REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
AR_INTR_SYNC_DEFAULT);
REG_WRITE(ah, AR_INTR_SYNC_MASK,
AR_INTR_SYNC_DEFAULT);
REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default);
}
ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
......@@ -883,6 +885,9 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
mask |= AR_IMR_GENTMR;
}
if (ints & ATH9K_INT_GENTIMER)
mask |= AR_IMR_GENTMR;
if (ints & (ATH9K_INT_BMISC)) {
mask |= AR_IMR_BCNMISC;
if (ints & ATH9K_INT_TIM)
......
......@@ -624,6 +624,43 @@ void ath_hw_check(struct work_struct *work)
ath9k_ps_restore(sc);
}
static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
{
static int count;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
if (pll_sqsum >= 0x40000) {
count++;
if (count == 3) {
/* Rx is hung for more than 500ms. Reset it */
ath_dbg(common, ATH_DBG_RESET,
"Possible RX hang, resetting");
ath_reset(sc, true);
count = 0;
}
} else
count = 0;
}
void ath_hw_pll_work(struct work_struct *work)
{
struct ath_softc *sc = container_of(work, struct ath_softc,
hw_pll_work.work);
u32 pll_sqsum;
if (AR_SREV_9485(sc->sc_ah)) {
ath9k_ps_wakeup(sc);
pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
ath9k_ps_restore(sc);
ath_hw_pll_rx_hang_check(sc, pll_sqsum);
ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
}
}
void ath9k_tasklet(unsigned long data)
{
struct ath_softc *sc = (struct ath_softc *)data;
......@@ -1932,6 +1969,12 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
"Bss Info ASSOC %d, bssid: %pM\n",
bss_conf->aid, common->curbssid);
ath_beacon_config(sc, vif);
/*
* Request a re-configuration of Beacon related timers
* on the receipt of the first Beacon frame (i.e.,
* after time sync with the AP).
*/
sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
/* Reset rssi stats */
sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
......@@ -2219,9 +2262,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
int timeout = 200; /* ms */
int i, j;
ath9k_ps_wakeup(sc);
mutex_lock(&sc->mutex);
cancel_delayed_work_sync(&sc->tx_complete_work);
if (drop)
......@@ -2244,15 +2285,15 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
goto out;
}
ath9k_ps_wakeup(sc);
if (!ath_drain_all_txq(sc, false))
ath_reset(sc, false);
ath9k_ps_restore(sc);
ieee80211_wake_queues(hw);
out:
ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
mutex_unlock(&sc->mutex);
ath9k_ps_restore(sc);
}
static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
......
......@@ -45,4 +45,7 @@
#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
#define AR_PHY_PLL_CONTROL 0x16180
#define AR_PHY_PLL_MODE 0x16184
#endif
......@@ -854,14 +854,13 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
}
static bool ath_rc_update_per(struct ath_softc *sc,
static void ath_rc_update_per(struct ath_softc *sc,
const struct ath_rate_table *rate_table,
struct ath_rate_priv *ath_rc_priv,
struct ieee80211_tx_info *tx_info,
int tx_rate, int xretries, int retries,
u32 now_msec)
{
bool state_change = false;
int count, n_bad_frames;
u8 last_per;
static const u32 nretry_to_per_lookup[10] = {
......@@ -992,8 +991,6 @@ static bool ath_rc_update_per(struct ath_softc *sc,
}
}
return state_change;
}
static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
......@@ -1017,7 +1014,6 @@ static void ath_rc_update_ht(struct ath_softc *sc,
u32 now_msec = jiffies_to_msecs(jiffies);
int rate;
u8 last_per;
bool state_change = false;
const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
int size = ath_rc_priv->rate_table_size;
......@@ -1027,7 +1023,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
last_per = ath_rc_priv->per[tx_rate];
/* Update PER first */
state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
ath_rc_update_per(sc, rate_table, ath_rc_priv,
tx_info, tx_rate, xretries,
retries, now_msec);
......
......@@ -1339,7 +1339,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
struct ath_hw_antcomb_conf div_ant_conf;
struct ath_ant_comb *antcomb = &sc->ant_comb;
int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
int curr_main_set, curr_bias;
int curr_main_set;
int main_rssi = rs->rs_rssi_ctl0;
int alt_rssi = rs->rs_rssi_ctl1;
int rx_ant_conf, main_ant_conf;
......@@ -1393,7 +1393,6 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf);
curr_alt_set = div_ant_conf.alt_lna_conf;
curr_main_set = div_ant_conf.main_lna_conf;
curr_bias = div_ant_conf.fast_div_bias;
antcomb->count++;
......@@ -1743,7 +1742,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
if ((sc->ps_flags & (PS_WAIT_FOR_BEACON |
PS_WAIT_FOR_CAB |
PS_WAIT_FOR_PSPOLL_DATA)) ||
unlikely(ath9k_check_auto_sleep(sc)))
ath9k_check_auto_sleep(sc))
ath_rx_ps(sc, skb);
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
......
......@@ -693,7 +693,7 @@
#define AR_RC_APB 0x00000002
#define AR_RC_HOSTIF 0x00000100
#define AR_WA 0x4004
#define AR_WA (AR_SREV_9340(ah) ? 0x40c4 : 0x4004)
#define AR_WA_BIT6 (1 << 6)
#define AR_WA_BIT7 (1 << 7)
#define AR_WA_BIT23 (1 << 23)
......@@ -712,7 +712,7 @@
#define AR_PM_STATE 0x4008
#define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000
#define AR_HOST_TIMEOUT 0x4018
#define AR_HOST_TIMEOUT (AR_SREV_9340(ah) ? 0x4008 : 0x4018)
#define AR_HOST_TIMEOUT_APB_CNTR 0x0000FFFF
#define AR_HOST_TIMEOUT_APB_CNTR_S 0
#define AR_HOST_TIMEOUT_LCL_CNTR 0xFFFF0000
......@@ -742,7 +742,8 @@
#define EEPROM_PROTECT_WP_1024_2047 0x8000
#define AR_SREV \
((AR_SREV_9100(ah)) ? 0x0600 : 0x4020)
((AR_SREV_9100(ah)) ? 0x0600 : (AR_SREV_9340(ah) \
? 0x400c : 0x4020))
#define AR_SREV_ID \
((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF)
......@@ -790,6 +791,7 @@
#define AR_SREV_VERSION_9485 0x240
#define AR_SREV_REVISION_9485_10 0
#define AR_SREV_REVISION_9485_11 1
#define AR_SREV_VERSION_9340 0x300
#define AR_SREV_5416(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
......@@ -868,6 +870,11 @@
#define AR_SREV_9485_11(_ah) \
(AR_SREV_9485(_ah) && \
((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11))
#define AR_SREV_9485_OR_LATER(_ah) \
(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9485))
#define AR_SREV_9340(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340))
#define AR_SREV_9285E_20(_ah) \
(AR_SREV_9285_12_OR_LATER(_ah) && \
......@@ -910,11 +917,11 @@ enum ath_usb_dev {
#define AR_INTR_SPURIOUS 0xFFFFFFFF
#define AR_INTR_SYNC_CAUSE_CLR 0x4028
#define AR_INTR_SYNC_CAUSE (AR_SREV_9340(ah) ? 0x4010 : 0x4028)
#define AR_INTR_SYNC_CAUSE_CLR (AR_SREV_9340(ah) ? 0x4010 : 0x4028)
#define AR_INTR_SYNC_CAUSE 0x4028
#define AR_INTR_SYNC_ENABLE 0x402c
#define AR_INTR_SYNC_ENABLE (AR_SREV_9340(ah) ? 0x4014 : 0x402c)
#define AR_INTR_SYNC_ENABLE_GPIO 0xFFFC0000
#define AR_INTR_SYNC_ENABLE_GPIO_S 18
......@@ -954,24 +961,24 @@ enum {
};
#define AR_INTR_ASYNC_MASK 0x4030
#define AR_INTR_ASYNC_MASK (AR_SREV_9340(ah) ? 0x4018 : 0x4030)
#define AR_INTR_ASYNC_MASK_GPIO 0xFFFC0000
#define AR_INTR_ASYNC_MASK_GPIO_S 18
#define AR_INTR_SYNC_MASK 0x4034
#define AR_INTR_SYNC_MASK (AR_SREV_9340(ah) ? 0x401c : 0x4034)
#define AR_INTR_SYNC_MASK_GPIO 0xFFFC0000
#define AR_INTR_SYNC_MASK_GPIO_S 18
#define AR_INTR_ASYNC_CAUSE_CLR 0x4038
#define AR_INTR_ASYNC_CAUSE 0x4038
#define AR_INTR_ASYNC_CAUSE_CLR (AR_SREV_9340(ah) ? 0x4020 : 0x4038)
#define AR_INTR_ASYNC_CAUSE (AR_SREV_9340(ah) ? 0x4020 : 0x4038)
#define AR_INTR_ASYNC_ENABLE 0x403c
#define AR_INTR_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4024 : 0x403c)
#define AR_INTR_ASYNC_ENABLE_GPIO 0xFFFC0000
#define AR_INTR_ASYNC_ENABLE_GPIO_S 18
#define AR_PCIE_SERDES 0x4040
#define AR_PCIE_SERDES2 0x4044
#define AR_PCIE_PM_CTRL 0x4014
#define AR_PCIE_PM_CTRL (AR_SREV_9340(ah) ? 0x4004 : 0x4014)
#define AR_PCIE_PM_CTRL_ENA 0x00080000
#define AR_NUM_GPIO 14
......@@ -982,7 +989,7 @@ enum {
#define AR9300_NUM_GPIO 17
#define AR7010_NUM_GPIO 16
#define AR_GPIO_IN_OUT 0x4048
#define AR_GPIO_IN_OUT (AR_SREV_9340(ah) ? 0x4028 : 0x4048)
#define AR_GPIO_IN_VAL 0x0FFFC000
#define AR_GPIO_IN_VAL_S 14
#define AR928X_GPIO_IN_VAL 0x000FFC00
......@@ -996,11 +1003,12 @@ enum {
#define AR7010_GPIO_IN_VAL 0x0000FFFF
#define AR7010_GPIO_IN_VAL_S 0
#define AR_GPIO_IN 0x404c
#define AR_GPIO_IN (AR_SREV_9340(ah) ? 0x402c : 0x404c)
#define AR9300_GPIO_IN_VAL 0x0001FFFF
#define AR9300_GPIO_IN_VAL_S 0
#define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)
#define AR_GPIO_OE_OUT (AR_SREV_9340(ah) ? 0x4030 : \
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c))
#define AR_GPIO_OE_OUT_DRV 0x3
#define AR_GPIO_OE_OUT_DRV_NO 0x0
#define AR_GPIO_OE_OUT_DRV_LOW 0x1
......@@ -1022,11 +1030,13 @@ enum {
#define AR7010_GPIO_INT_MASK 0x52024
#define AR7010_GPIO_FUNCTION 0x52028
#define AR_GPIO_INTR_POL (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050)
#define AR_GPIO_INTR_POL (AR_SREV_9340(ah) ? 0x4038 : \
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050))
#define AR_GPIO_INTR_POL_VAL 0x0001FFFF
#define AR_GPIO_INTR_POL_VAL_S 0
#define AR_GPIO_INPUT_EN_VAL (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054)
#define AR_GPIO_INPUT_EN_VAL (AR_SREV_9340(ah) ? 0x403c : \
(AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054))
#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004
#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2
#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008
......@@ -1044,13 +1054,15 @@ enum {
#define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000
#define AR_GPIO_JTAG_DISABLE 0x00020000
#define AR_GPIO_INPUT_MUX1 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058)
#define AR_GPIO_INPUT_MUX1 (AR_SREV_9340(ah) ? 0x4040 : \
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058))
#define AR_GPIO_INPUT_MUX1_BT_ACTIVE 0x000f0000
#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16
#define AR_GPIO_INPUT_MUX1_BT_PRIORITY 0x00000f00
#define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S 8
#define AR_GPIO_INPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c)
#define AR_GPIO_INPUT_MUX2 (AR_SREV_9340(ah) ? 0x4044 : \
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c))
#define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f
#define AR_GPIO_INPUT_MUX2_CLK25_S 0
#define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0
......@@ -1058,13 +1070,18 @@ enum {
#define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00
#define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8
#define AR_GPIO_OUTPUT_MUX1 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060)
#define AR_GPIO_OUTPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064)
#define AR_GPIO_OUTPUT_MUX3 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068)
#define AR_GPIO_OUTPUT_MUX1 (AR_SREV_9340(ah) ? 0x4048 : \
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060))
#define AR_GPIO_OUTPUT_MUX2 (AR_SREV_9340(ah) ? 0x404c : \
(AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064))
#define AR_GPIO_OUTPUT_MUX3 (AR_SREV_9340(ah) ? 0x4050 : \
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068))
#define AR_INPUT_STATE (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c)
#define AR_INPUT_STATE (AR_SREV_9340(ah) ? 0x4054 : \
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c))
#define AR_EEPROM_STATUS_DATA (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c)
#define AR_EEPROM_STATUS_DATA (AR_SREV_9340(ah) ? 0x40c8 : \
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c))
#define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff
#define AR_EEPROM_STATUS_DATA_VAL_S 0
#define AR_EEPROM_STATUS_DATA_BUSY 0x00010000
......@@ -1072,17 +1089,19 @@ enum {
#define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000
#define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000
#define AR_OBS (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080)
#define AR_OBS (AR_SREV_9340(ah) ? 0x405c : \
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080))
#define AR_GPIO_PDPU (AR_SREV_9300_20_OR_LATER(ah) ? 0x4090 : 0x4088)
#define AR_PCIE_MSI (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094)
#define AR_PCIE_MSI (AR_SREV_9340(ah) ? 0x40d8 : \
(AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094))
#define AR_PCIE_MSI_ENABLE 0x00000001
#define AR_INTR_PRIO_SYNC_ENABLE 0x40c4
#define AR_INTR_PRIO_ASYNC_MASK 0x40c8
#define AR_INTR_PRIO_SYNC_MASK 0x40cc
#define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4
#define AR_INTR_PRIO_SYNC_ENABLE (AR_SREV_9340(ah) ? 0x4088 : 0x40c4)
#define AR_INTR_PRIO_ASYNC_MASK (AR_SREV_9340(ah) ? 0x408c : 0x40c8)
#define AR_INTR_PRIO_SYNC_MASK (AR_SREV_9340(ah) ? 0x4090 : 0x40cc)
#define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4)
#define AR_ENT_OTP 0x40d8
#define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000
#define AR_ENT_OTP_MPSD 0x00800000
......@@ -1163,6 +1182,7 @@ enum {
#define AR_RTC_PLL_REFDIV_5 0x000000c0
#define AR_RTC_PLL_CLKSEL 0x00000300
#define AR_RTC_PLL_CLKSEL_S 8
#define AR_RTC_PLL_BYPASS 0x00010000
#define PLL3 0x16188
#define PLL3_DO_MEAS_MASK 0x40000000
......@@ -1209,7 +1229,8 @@ enum {
/* RTC_DERIVED_* - only for AR9100 */
#define AR_RTC_DERIVED_CLK (AR_RTC_BASE + 0x0038)
#define AR_RTC_DERIVED_CLK \
(AR_SREV_9100(ah) ? (AR_RTC_BASE + 0x0038) : 0x7038)
#define AR_RTC_DERIVED_CLK_PERIOD 0x0000fffe
#define AR_RTC_DERIVED_CLK_PERIOD_S 1
......@@ -1688,6 +1709,22 @@ enum {
#define AR_BTCOEX_WL_WGHT 0xffff0000
#define AR_BTCOEX_WL_WGHT_S 16
#define AR_BT_COEX_WL_WEIGHTS0 0x8174
#define AR_BT_COEX_WL_WEIGHTS1 0x81c4
#define AR_BT_COEX_BT_WEIGHTS0 0x83ac
#define AR_BT_COEX_BT_WEIGHTS1 0x83b0
#define AR_BT_COEX_BT_WEIGHTS2 0x83b4
#define AR_BT_COEX_BT_WEIGHTS3 0x83b8
#define AR9300_BT_WGHT 0xcccc4444
#define AR9300_STOMP_ALL_WLAN_WGHT0 0xfffffff0
#define AR9300_STOMP_ALL_WLAN_WGHT1 0xfffffff0
#define AR9300_STOMP_LOW_WLAN_WGHT0 0x88888880
#define AR9300_STOMP_LOW_WLAN_WGHT1 0x88888880
#define AR9300_STOMP_NONE_WLAN_WGHT0 0x00000000
#define AR9300_STOMP_NONE_WLAN_WGHT1 0x00000000
#define AR_BT_COEX_MODE2 0x817c
#define AR_BT_BCN_MISS_THRESH 0x000000ff
#define AR_BT_BCN_MISS_THRESH_S 0
......
......@@ -79,8 +79,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
return "WMI_TX_STATS_CMDID";
case WMI_RX_STATS_CMDID:
return "WMI_RX_STATS_CMDID";
case WMI_AGGR_LIMIT_CMD:
return "WMI_AGGR_LIMIT_CMD";
case WMI_BITRATE_MASK_CMDID:
return "WMI_BITRATE_MASK_CMDID";
}
return "Bogus";
......
......@@ -111,7 +111,7 @@ enum wmi_cmd_id {
WMI_INT_STATS_CMDID,
WMI_TX_STATS_CMDID,
WMI_RX_STATS_CMDID,
WMI_AGGR_LIMIT_CMD = 0x0026,
WMI_BITRATE_MASK_CMDID,
};
enum wmi_event_id {
......
......@@ -2180,28 +2180,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
}
}
static void ath_hw_pll_work(struct work_struct *work)
{
struct ath_softc *sc = container_of(work, struct ath_softc,
hw_pll_work.work);
static int count;
if (AR_SREV_9485(sc->sc_ah)) {
if (ar9003_get_pll_sqsum_dvc(sc->sc_ah) >= 0x40000) {
count++;
if (count == 3) {
/* Rx is hung for more than 500ms. Reset it */
ath_reset(sc, true);
count = 0;
}
} else
count = 0;
ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
}
}
static void ath_tx_complete_poll_work(struct work_struct *work)
{
struct ath_softc *sc = container_of(work, struct ath_softc,
......@@ -2396,7 +2374,6 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
}
INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
error = ath_tx_edma_init(sc);
......
......@@ -448,6 +448,8 @@ struct carl9170_ba_stats {
struct carl9170_sta_info {
bool ht_sta;
bool sleeping;
atomic_t pending_frames;
unsigned int ampdu_max_len;
struct carl9170_sta_tid *agg[CARL9170_NUM_TID];
struct carl9170_ba_stats stats[CARL9170_NUM_TID];
......
......@@ -1193,6 +1193,8 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw,
struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
unsigned int i;
atomic_set(&sta_info->pending_frames, 0);
if (sta->ht_cap.ht_supported) {
if (sta->ht_cap.ampdu_density > 6) {
/*
......@@ -1467,99 +1469,17 @@ static void carl9170_op_sta_notify(struct ieee80211_hw *hw,
enum sta_notify_cmd cmd,
struct ieee80211_sta *sta)
{
struct ar9170 *ar = hw->priv;
struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
struct sk_buff *skb, *tmp;
struct sk_buff_head free;
int i;
switch (cmd) {
case STA_NOTIFY_SLEEP:
/*
* Since the peer is no longer listening, we have to return
* as many SKBs as possible back to the mac80211 stack.
* It will deal with the retry procedure, once the peer
* has become available again.
*
* NB: Ideally, the driver should return the all frames in
* the correct, ascending order. However, I think that this
* functionality should be implemented in the stack and not
* here...
*/
__skb_queue_head_init(&free);
if (sta->ht_cap.ht_supported) {
rcu_read_lock();
for (i = 0; i < CARL9170_NUM_TID; i++) {
struct carl9170_sta_tid *tid_info;
tid_info = rcu_dereference(sta_info->agg[i]);
if (!tid_info)
continue;
spin_lock_bh(&ar->tx_ampdu_list_lock);
if (tid_info->state >
CARL9170_TID_STATE_SUSPEND)
tid_info->state =
CARL9170_TID_STATE_SUSPEND;
spin_unlock_bh(&ar->tx_ampdu_list_lock);
spin_lock_bh(&tid_info->lock);
while ((skb = __skb_dequeue(&tid_info->queue)))
__skb_queue_tail(&free, skb);
spin_unlock_bh(&tid_info->lock);
}
rcu_read_unlock();
}
for (i = 0; i < ar->hw->queues; i++) {
spin_lock_bh(&ar->tx_pending[i].lock);
skb_queue_walk_safe(&ar->tx_pending[i], skb, tmp) {
struct _carl9170_tx_superframe *super;
struct ieee80211_hdr *hdr;
struct ieee80211_tx_info *info;
super = (void *) skb->data;
hdr = (void *) super->frame_data;
if (compare_ether_addr(hdr->addr1, sta->addr))
continue;
__skb_unlink(skb, &ar->tx_pending[i]);
info = IEEE80211_SKB_CB(skb);
if (info->flags & IEEE80211_TX_CTL_AMPDU)
atomic_dec(&ar->tx_ampdu_upload);
carl9170_tx_status(ar, skb, false);
}
spin_unlock_bh(&ar->tx_pending[i].lock);
}
while ((skb = __skb_dequeue(&free)))
carl9170_tx_status(ar, skb, false);
sta_info->sleeping = true;
if (atomic_read(&sta_info->pending_frames))
ieee80211_sta_block_awake(hw, sta, true);
break;
case STA_NOTIFY_AWAKE:
if (!sta->ht_cap.ht_supported)
return;
rcu_read_lock();
for (i = 0; i < CARL9170_NUM_TID; i++) {
struct carl9170_sta_tid *tid_info;
tid_info = rcu_dereference(sta_info->agg[i]);
if (!tid_info)
continue;
if ((tid_info->state == CARL9170_TID_STATE_SUSPEND))
tid_info->state = CARL9170_TID_STATE_IDLE;
}
rcu_read_unlock();
sta_info->sleeping = false;
break;
}
}
......
......@@ -2281,6 +2281,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
save_regs_phy[8] = 0;
} else {
save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
......@@ -2289,6 +2290,8 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
save_regs_phy[7] = 0;
save_regs_phy[8] = 0;
}
b43_nphy_rssi_select(dev, 5, type);
......@@ -3845,8 +3848,8 @@ static int b43_nphy_set_channel(struct b43_wldev *dev,
{
struct b43_phy *phy = &dev->phy;
const struct b43_nphy_channeltab_entry_rev2 *tabent_r2;
const struct b43_nphy_channeltab_entry_rev3 *tabent_r3;
const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL;
const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL;
u8 tmp;
......
......@@ -955,9 +955,6 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
if (priv->cfg->scan_rx_antennas[band])
rx_ant = priv->cfg->scan_rx_antennas[band];
if (priv->cfg->scan_tx_antennas[band])
scan_tx_antennas = priv->cfg->scan_tx_antennas[band];
priv->scan_tx_ant[band] = iwl4965_toggle_tx_ant(priv,
priv->scan_tx_ant[band],
scan_tx_antennas);
......
......@@ -211,10 +211,7 @@ int iwl_legacy_init_geos(struct iwl_priv *priv)
if (!iwl_legacy_is_channel_valid(ch))
continue;
if (iwl_legacy_is_channel_a_band(ch))
sband = &priv->bands[IEEE80211_BAND_5GHZ];
else
sband = &priv->bands[IEEE80211_BAND_2GHZ];
sband = &priv->bands[ch->band];
geo_ch = &sband->channels[sband->n_channels++];
......@@ -2117,10 +2114,9 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed)
IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
channel->hw_value, changed);
if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
test_bit(STATUS_SCANNING, &priv->status))) {
if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
scan_active = 1;
IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
IWL_DEBUG_MAC80211(priv, "scan active\n");
}
if (changed & (IEEE80211_CONF_CHANGE_SMPS |
......@@ -2433,11 +2429,13 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
if (!iwl_legacy_is_alive(priv))
return;
mutex_lock(&priv->mutex);
if (!iwl_legacy_is_alive(priv)) {
mutex_unlock(&priv->mutex);
return;
}
if (changes & BSS_CHANGED_QOS) {
unsigned long flags;
......@@ -2646,7 +2644,7 @@ irqreturn_t iwl_legacy_isr(int irq, void *data)
none:
/* re-enable interrupts here since we don't have anything to service. */
/* only Re-enable if diabled by irq */
/* only Re-enable if disabled by irq */
if (test_bit(STATUS_INT_ENABLED, &priv->status))
iwl_legacy_enable_interrupts(priv);
spin_unlock_irqrestore(&priv->lock, flags);
......
......@@ -287,7 +287,6 @@ struct iwl_cfg {
struct iwl_base_params *base_params;
/* params likely to change within a device family */
u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
enum iwl_led_mode led_mode;
};
......
......@@ -134,7 +134,7 @@ struct iwl_queue {
* space more than this */
int high_mark; /* high watermark, stop queue if free
* space less than this */
} __packed;
};
/* One for each TFD */
struct iwl_tx_info {
......@@ -290,6 +290,7 @@ enum {
CMD_SIZE_HUGE = (1 << 0),
CMD_ASYNC = (1 << 1),
CMD_WANT_SKB = (1 << 2),
CMD_MAPPED = (1 << 3),
};
#define DEF_CMD_PAYLOAD_SIZE 320
......@@ -1076,7 +1077,6 @@ struct iwl_priv {
spinlock_t hcmd_lock; /* protect hcmd */
spinlock_t reg_lock; /* protect hw register access */
struct mutex mutex;
struct mutex sync_cmd_mutex; /* enable serialization of sync commands */
/* basic pci-network driver stuff */
struct pci_dev *pci_dev;
......
......@@ -145,6 +145,8 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
int cmd_idx;
int ret;
lockdep_assert_held(&priv->mutex);
BUG_ON(cmd->flags & CMD_ASYNC);
/* A synchronous command can not have a callback set. */
......@@ -152,7 +154,6 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n",
iwl_legacy_get_cmd_string(cmd->id));
mutex_lock(&priv->sync_cmd_mutex);
set_bit(STATUS_HCMD_ACTIVE, &priv->status);
IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n",
......@@ -224,7 +225,6 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
cmd->reply_page = 0;
}
out:
mutex_unlock(&priv->sync_cmd_mutex);
return ret;
}
EXPORT_SYMBOL(iwl_legacy_send_cmd_sync);
......
......@@ -149,6 +149,12 @@ static inline void iwl_legacy_disable_interrupts(struct iwl_priv *priv)
IWL_DEBUG_ISR(priv, "Disabled interrupts\n");
}
static inline void iwl_legacy_enable_rfkill_int(struct iwl_priv *priv)
{
IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n");
iwl_write32(priv, CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
}
static inline void iwl_legacy_enable_interrupts(struct iwl_priv *priv)
{
IWL_DEBUG_ISR(priv, "Enabling interrupts\n");
......
......@@ -14,7 +14,6 @@ iwlagn-objs += iwl-6000.o
iwlagn-objs += iwl-1000.o
iwlagn-objs += iwl-2000.o
iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
......
......@@ -294,9 +294,6 @@ extern const u8 iwl_eeprom_band_1[14];
struct iwl_eeprom_ops {
const u32 regulatory_bands[7];
int (*acquire_semaphore) (struct iwl_priv *priv);
void (*release_semaphore) (struct iwl_priv *priv);
u16 (*calib_version) (struct iwl_priv *priv);
const u8* (*query_addr) (const struct iwl_priv *priv, size_t offset);
void (*update_enhanced_txpower) (struct iwl_priv *priv);
};
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
/**
/*
* This file contains declaration referring to
* functions defined in other source files
*/
......
此差异已折叠。
......@@ -20,7 +20,8 @@ static void lbs_ethtool_get_drvinfo(struct net_device *dev,
strcpy(info->version, lbs_driver_version);
}
/* All 8388 parts have 16KiB EEPROM size at the time of writing.
/*
* All 8388 parts have 16KiB EEPROM size at the time of writing.
* In case that changes this needs fixing.
*/
#define LBS_EEPROM_LEN 16384
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册