提交 a70171dc 编写于 作者: J John W. Linville

Merge branch 'master' of...

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem

Conflicts:
	drivers/net/wireless/libertas/if_cs.c
	drivers/net/wireless/rtlwifi/pci.c
	net/bluetooth/l2cap_sock.c
...@@ -158,6 +158,11 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah) ...@@ -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); txlat = AR5K_REG_MS(usec_reg, AR5K_USEC_TX_LATENCY_5211);
rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_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 * 5210 initvals don't include usec settings
* so we need to use magic values here for * so we need to use magic values here for
......
...@@ -21,11 +21,15 @@ ...@@ -21,11 +21,15 @@
#include <linux/ath9k_platform.h> #include <linux/ath9k_platform.h>
#include "ath9k.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", .name = "ath9k",
.driver_data = AR5416_AR9100_DEVID, .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) ...@@ -899,12 +899,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
* check here default level should not modify INI setting. * check here default level should not modify INI setting.
*/ */
if (use_new_ani(ah)) { 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->aniperiod = ATH9K_ANI_PERIOD_NEW;
ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW; ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW;
} else { } else {
......
...@@ -18,13 +18,13 @@ ...@@ -18,13 +18,13 @@
#include "hw-ops.h" #include "hw-ops.h"
#include "ar9003_phy.h" #include "ar9003_phy.h"
#define MPASS 3
#define MAX_MEASUREMENT 8 #define MAX_MEASUREMENT 8
#define MAX_DIFFERENCE 10 #define MAX_MAG_DELTA 11
#define MAX_PHS_DELTA 10
struct coeff { struct coeff {
int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS]; int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS]; int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
int iqc_coeff[2]; int iqc_coeff[2];
}; };
...@@ -185,17 +185,19 @@ static void ar9003_hw_iqcal_collect(struct ath_hw *ah) ...@@ -185,17 +185,19 @@ static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
/* Accumulate IQ cal measures for active chains */ /* Accumulate IQ cal measures for active chains */
for (i = 0; i < AR5416_MAX_CHAINS; i++) { for (i = 0; i < AR5416_MAX_CHAINS; i++) {
ah->totalPowerMeasI[i] += if (ah->txchainmask & BIT(i)) {
REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); ah->totalPowerMeasI[i] +=
ah->totalPowerMeasQ[i] += REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); ah->totalPowerMeasQ[i] +=
ah->totalIqCorrMeas[i] += REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); ah->totalIqCorrMeas[i] +=
ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
"%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
ah->cal_samples, i, ah->totalPowerMeasI[i], "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
ah->totalPowerMeasQ[i], ah->cal_samples, i, ah->totalPowerMeasI[i],
ah->totalIqCorrMeas[i]); ah->totalPowerMeasQ[i],
ah->totalIqCorrMeas[i]);
}
} }
} }
...@@ -608,36 +610,48 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, ...@@ -608,36 +610,48 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
return true; 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]; int mp_max = -64, max_idx = 0;
int mp_min = 63, min_idx = 0;
diff[0] = abs(mp_coeff[0] - mp_coeff[1]); int mp_avg = 0, i, outlier_idx = 0;
diff[1] = abs(mp_coeff[1] - mp_coeff[2]);
diff[2] = abs(mp_coeff[2] - mp_coeff[0]); /* find min/max mismatch across all calibrated gains */
for (i = 0; i < nmeasurement; i++) {
if (diff[0] > MAX_DIFFERENCE && mp_avg += mp_coeff[i];
diff[1] > MAX_DIFFERENCE && if (mp_coeff[i] > mp_max) {
diff[2] > MAX_DIFFERENCE) mp_max = mp_coeff[i];
return false; max_idx = i;
} else if (mp_coeff[i] < mp_min) {
mp_min = mp_coeff[i];
min_idx = i;
}
}
if (diff[0] <= diff[1] && diff[0] <= diff[2]) /* find average (exclude max abs value) */
*mp_avg = (mp_coeff[0] + mp_coeff[1]) / 2; for (i = 0; i < nmeasurement; i++) {
else if (diff[1] <= diff[2]) if ((abs(mp_coeff[i]) < abs(mp_max)) ||
*mp_avg = (mp_coeff[1] + mp_coeff[2]) / 2; (abs(mp_coeff[i]) < abs(mp_min)))
else mp_avg += mp_coeff[i];
*mp_avg = (mp_coeff[2] + mp_coeff[0]) / 2; }
mp_avg /= (nmeasurement - 1);
return true; /* 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
outlier_idx = min_idx;
}
mp_coeff[outlier_idx] = mp_avg;
} }
static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
u8 num_chains, u8 num_chains,
struct coeff *coeff) struct coeff *coeff)
{ {
struct ath_common *common = ath9k_hw_common(ah);
int i, im, nmeasurement; int i, im, nmeasurement;
int magnitude, phase;
u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS]; u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff)); memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
...@@ -657,37 +671,28 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, ...@@ -657,37 +671,28 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
/* Load the average of 2 passes */ /* Load the average of 2 passes */
for (i = 0; i < num_chains; i++) { for (i = 0; i < num_chains; i++) {
if (AR_SREV_9485(ah)) nmeasurement = REG_READ_FIELD(ah,
nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0,
AR_PHY_TX_IQCAL_STATUS_B0_9485, AR_PHY_CALIBRATED_GAINS_0);
AR_PHY_CALIBRATED_GAINS_0);
else
nmeasurement = REG_READ_FIELD(ah,
AR_PHY_TX_IQCAL_STATUS_B0,
AR_PHY_CALIBRATED_GAINS_0);
if (nmeasurement > MAX_MEASUREMENT) if (nmeasurement > MAX_MEASUREMENT)
nmeasurement = MAX_MEASUREMENT; nmeasurement = MAX_MEASUREMENT;
for (im = 0; im < nmeasurement; im++) { /* detect outlier only if nmeasurement > 1 */
/* if (nmeasurement > 1) {
* Determine which 2 passes are closest and compute avg /* Detect magnitude outlier */
* magnitude ar9003_hw_detect_outlier(coeff->mag_coeff[i],
*/ nmeasurement, MAX_MAG_DELTA);
if (!ar9003_hw_compute_closest_pass_and_avg(coeff->mag_coeff[i][im],
&magnitude))
goto disable_txiqcal;
/* /* Detect phase outlier */
* Determine which 2 passes are closest and compute avg ar9003_hw_detect_outlier(coeff->phs_coeff[i],
* phase nmeasurement, MAX_PHS_DELTA);
*/ }
if (!ar9003_hw_compute_closest_pass_and_avg(coeff->phs_coeff[i][im],
&phase)) for (im = 0; im < nmeasurement; im++) {
goto disable_txiqcal;
coeff->iqc_coeff[0] = (magnitude & 0x7f) | coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) |
((phase & 0x7f) << 7); ((coeff->phs_coeff[i][im] & 0x7f) << 7);
if ((im % 2) == 0) if ((im % 2) == 0)
REG_RMW_FIELD(ah, tx_corr_coeff[im][i], 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, ...@@ -707,141 +712,37 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
return; 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); 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; 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, tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
AR_PHY_TXGAIN_FORCE); AR_PHY_TXGAIN_FORCE);
if (tx_gain_forced) if (tx_gain_forced)
REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
AR_PHY_TXGAIN_FORCE, 0); AR_PHY_TXGAIN_FORCE, 0);
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START_9485, REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
AR_PHY_TX_IQCAL_START_DO_CAL_9485, 1); 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) static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
{ {
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
const u32 txiqcal_status[AR9300_MAX_CHAINS] = { 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_B1,
AR_PHY_TX_IQCAL_STATUS_B2, AR_PHY_TX_IQCAL_STATUS_B2,
}; };
...@@ -853,7 +754,7 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah) ...@@ -853,7 +754,7 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
struct coeff coeff; struct coeff coeff;
s32 iq_res[6]; s32 iq_res[6];
u8 num_chains = 0; u8 num_chains = 0;
int i, ip, im, j; int i, im, j;
int nmeasurement; int nmeasurement;
for (i = 0; i < AR9300_MAX_CHAINS; i++) { for (i = 0; i < AR9300_MAX_CHAINS; i++) {
...@@ -861,71 +762,69 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah) ...@@ -861,71 +762,69 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
num_chains++; num_chains++;
} }
for (ip = 0; ip < MPASS; ip++) { for (i = 0; i < num_chains; i++) {
for (i = 0; i < num_chains; i++) { nmeasurement = REG_READ_FIELD(ah,
nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0,
AR_PHY_TX_IQCAL_STATUS_B0_9485, AR_PHY_CALIBRATED_GAINS_0);
AR_PHY_CALIBRATED_GAINS_0); if (nmeasurement > MAX_MEASUREMENT)
if (nmeasurement > MAX_MEASUREMENT) nmeasurement = MAX_MEASUREMENT;
nmeasurement = MAX_MEASUREMENT;
for (im = 0; im < nmeasurement; im++) { for (im = 0; im < nmeasurement; im++) {
ath_dbg(common, ATH_DBG_CALIBRATE, ath_dbg(common, ATH_DBG_CALIBRATE,
"Doing Tx IQ Cal for chain %d.\n", i); "Doing Tx IQ Cal for chain %d.\n", i);
if (REG_READ(ah, txiqcal_status[i]) & if (REG_READ(ah, txiqcal_status[i]) &
AR_PHY_TX_IQCAL_STATUS_FAILED) { AR_PHY_TX_IQCAL_STATUS_FAILED) {
ath_dbg(common, ATH_DBG_CALIBRATE, ath_dbg(common, ATH_DBG_CALIBRATE,
"Tx IQ Cal failed for chain %d.\n", i); "Tx IQ Cal failed for chain %d.\n", i);
goto tx_iqcal_fail; goto tx_iqcal_fail;
} }
for (j = 0; j < 3; j++) { for (j = 0; j < 3; j++) {
u32 idx = 2 * j, offset = 4 * (3 * im + j); u32 idx = 2 * j, offset = 4 * (3 * im + j);
REG_RMW_FIELD(ah, REG_RMW_FIELD(ah,
AR_PHY_CHAN_INFO_MEMORY, AR_PHY_CHAN_INFO_MEMORY,
AR_PHY_CHAN_INFO_TAB_S2_READ, AR_PHY_CHAN_INFO_TAB_S2_READ,
0); 0);
/* 32 bits */ /* 32 bits */
iq_res[idx] = REG_READ(ah, iq_res[idx] = REG_READ(ah,
chan_info_tab[i] + chan_info_tab[i] +
offset); offset);
REG_RMW_FIELD(ah, REG_RMW_FIELD(ah,
AR_PHY_CHAN_INFO_MEMORY, AR_PHY_CHAN_INFO_MEMORY,
AR_PHY_CHAN_INFO_TAB_S2_READ, AR_PHY_CHAN_INFO_TAB_S2_READ,
1); 1);
/* 16 bits */ /* 16 bits */
iq_res[idx + 1] = 0xffff & REG_READ(ah, iq_res[idx + 1] = 0xffff & REG_READ(ah,
chan_info_tab[i] + offset); chan_info_tab[i] + offset);
ath_dbg(common, ATH_DBG_CALIBRATE, ath_dbg(common, ATH_DBG_CALIBRATE,
"IQ RES[%d]=0x%x" "IQ RES[%d]=0x%x"
"IQ_RES[%d]=0x%x\n", "IQ_RES[%d]=0x%x\n",
idx, iq_res[idx], idx + 1, idx, iq_res[idx], idx + 1,
iq_res[idx + 1]); iq_res[idx + 1]);
} }
if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
coeff.iqc_coeff)) { coeff.iqc_coeff)) {
ath_dbg(common, ATH_DBG_CALIBRATE, ath_dbg(common, ATH_DBG_CALIBRATE,
"Failed in calculation of IQ correction.\n"); "Failed in calculation of \
goto tx_iqcal_fail; IQ correction.\n");
} goto tx_iqcal_fail;
}
coeff.mag_coeff[i][im][ip] = coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f;
coeff.iqc_coeff[0] & 0x7f; coeff.phs_coeff[i][im] =
coeff.phs_coeff[i][im][ip] = (coeff.iqc_coeff[0] >> 7) & 0x7f;
(coeff.iqc_coeff[0] >> 7) & 0x7f;
if (coeff.mag_coeff[i][im][ip] > 63) if (coeff.mag_coeff[i][im] > 63)
coeff.mag_coeff[i][im][ip] -= 128; coeff.mag_coeff[i][im] -= 128;
if (coeff.phs_coeff[i][im][ip] > 63) if (coeff.phs_coeff[i][im] > 63)
coeff.phs_coeff[i][im][ip] -= 128; coeff.phs_coeff[i][im] -= 128;
}
} }
} }
ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff); 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, ...@@ -940,31 +839,37 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
struct ath9k_channel *chan) struct ath9k_channel *chan)
{ {
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_hw_capabilities *pCap = &ah->caps;
int val; int val;
bool txiqcal_done = false;
val = REG_READ(ah, AR_ENT_OTP); val = REG_READ(ah, AR_ENT_OTP);
ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val); ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val);
if (AR_SREV_9485(ah)) /* Configure rx/tx chains before running AGC/TxiQ cals */
ar9003_hw_set_chain_masks(ah, 0x1, 0x1); if (val & AR_ENT_OTP_CHAIN2_DISABLE)
else if (val & AR_ENT_OTP_CHAIN2_DISABLE)
ar9003_hw_set_chain_masks(ah, 0x3, 0x3); ar9003_hw_set_chain_masks(ah, 0x3, 0x3);
else else
/* ar9003_hw_set_chain_masks(ah, pCap->rx_chainmask,
* 0x7 = 0b111 , AR9003 needs to be configured for 3-chain pCap->tx_chainmask);
* mode before running AGC/TxIQ cals
*/
ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
/* Do Tx IQ Calibration */ /* Do Tx IQ Calibration */
if (AR_SREV_9485(ah)) REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
ar9003_hw_tx_iq_cal_run(ah); AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
else DELPT);
ar9003_hw_tx_iq_cal(ah);
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); /*
udelay(5); * For AR9485 or later chips, TxIQ cal runs as part of
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); * 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 */ /* Calibrate the AGC */
REG_WRITE(ah, AR_PHY_AGC_CONTROL, REG_WRITE(ah, AR_PHY_AGC_CONTROL,
...@@ -979,7 +884,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, ...@@ -979,7 +884,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
return false; return false;
} }
if (AR_SREV_9485(ah)) if (txiqcal_done)
ar9003_hw_tx_iq_cal_post_proc(ah); ar9003_hw_tx_iq_cal_post_proc(ah);
/* Revert chainmasks to their original values before NF cal */ /* Revert chainmasks to their original values before NF cal */
......
...@@ -3217,7 +3217,6 @@ static int ar9300_compress_decision(struct ath_hw *ah, ...@@ -3217,7 +3217,6 @@ static int ar9300_compress_decision(struct ath_hw *ah,
u8 *word, int length, int mdata_size) u8 *word, int length, int mdata_size)
{ {
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
u8 *dptr;
const struct ar9300_eeprom *eep = NULL; const struct ar9300_eeprom *eep = NULL;
switch (code) { switch (code) {
...@@ -3235,7 +3234,6 @@ static int ar9300_compress_decision(struct ath_hw *ah, ...@@ -3235,7 +3234,6 @@ static int ar9300_compress_decision(struct ath_hw *ah,
break; break;
case _CompressBlock: case _CompressBlock:
if (reference == 0) { if (reference == 0) {
dptr = mptr;
} else { } else {
eep = ar9003_eeprom_struct_find_by_id(reference); eep = ar9003_eeprom_struct_find_by_id(reference);
if (eep == NULL) { if (eep == NULL) {
...@@ -3448,9 +3446,13 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) ...@@ -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); REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
else { else {
REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); 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)) {
bias >> 2); REG_RMW_FIELD(ah, AR_CH0_THERM,
REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1); AR_CH0_THERM_XPABIASLVL_MSB,
bias >> 2);
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, ...@@ -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) 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); u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value); REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); 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); 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); for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value); if ((ah->rxchainmask & BIT(chain)) ||
(ah->txchainmask & BIT(chain))) {
if (!AR_SREV_9485(ah)) { value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz); is2ghz);
REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, REG_RMW_FIELD(ah, switch_chain_reg[chain],
value); 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);
} }
if (AR_SREV_9485(ah)) { if (AR_SREV_9485(ah)) {
...@@ -3634,13 +3641,16 @@ static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan) ...@@ -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. */ /* Test value. if 0 then attenuation is unused. Don't load anything. */
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
value = ar9003_hw_atten_chain_get(ah, i, chan); if (ah->txchainmask & BIT(i)) {
REG_RMW_FIELD(ah, ext_atten_reg[i], value = ar9003_hw_atten_chain_get(ah, i, chan);
AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); 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], value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value); REG_RMW_FIELD(ah, ext_atten_reg[i],
AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
value);
}
} }
} }
...@@ -3749,8 +3759,9 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, ...@@ -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_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
ar9003_hw_drive_strength_apply(ah); ar9003_hw_drive_strength_apply(ah);
ar9003_hw_atten_apply(ah, chan); ar9003_hw_atten_apply(ah, chan);
ar9003_hw_internal_regulator_apply(ah); if (!AR_SREV_9340(ah))
if (AR_SREV_9485(ah)) ar9003_hw_internal_regulator_apply(ah);
if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
ar9003_hw_apply_tuning_caps(ah); ar9003_hw_apply_tuning_caps(ah);
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "ar9003_mac.h" #include "ar9003_mac.h"
#include "ar9003_2p2_initvals.h" #include "ar9003_2p2_initvals.h"
#include "ar9485_initvals.h" #include "ar9485_initvals.h"
#include "ar9340_initvals.h"
/* General hardware code for the AR9003 hadware family */ /* General hardware code for the AR9003 hadware family */
...@@ -28,7 +29,63 @@ ...@@ -28,7 +29,63 @@
*/ */
static void ar9003_hw_init_mode_regs(struct ath_hw *ah) 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 */ /* mac */
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
...@@ -163,7 +220,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) ...@@ -163,7 +220,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
switch (ar9003_hw_get_tx_gain_idx(ah)) { switch (ar9003_hw_get_tx_gain_idx(ah)) {
case 0: case 0:
default: 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, INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485_modes_lowest_ob_db_tx_gain_1_1, ar9485_modes_lowest_ob_db_tx_gain_1_1,
ARRAY_SIZE(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) ...@@ -175,7 +237,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
5); 5);
break; break;
case 1: 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, INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485Modes_high_ob_db_tx_gain_1_1, ar9485Modes_high_ob_db_tx_gain_1_1,
ARRAY_SIZE(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) ...@@ -187,7 +254,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
5); 5);
break; break;
case 2: 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, INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485Modes_low_ob_db_tx_gain_1_1, ar9485Modes_low_ob_db_tx_gain_1_1,
ARRAY_SIZE(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) ...@@ -199,7 +271,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
5); 5);
break; break;
case 3: 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, INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485Modes_high_power_tx_gain_1_1, ar9485Modes_high_power_tx_gain_1_1,
ARRAY_SIZE(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) ...@@ -218,7 +295,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
switch (ar9003_hw_get_rx_gain_idx(ah)) { switch (ar9003_hw_get_rx_gain_idx(ah)) {
case 0: case 0:
default: 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, INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9485Common_wo_xlna_rx_gain_1_1, ar9485Common_wo_xlna_rx_gain_1_1,
ARRAY_SIZE(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) ...@@ -230,7 +312,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
2); 2);
break; break;
case 1: 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, INIT_INI_ARRAY(&ah->iniModesRxGain,
ar9485Common_wo_xlna_rx_gain_1_1, ar9485Common_wo_xlna_rx_gain_1_1,
ARRAY_SIZE(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) ...@@ -86,14 +86,31 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
channelSel = (freq * 4) / 120; channelSel = (freq * 4) / 120;
chan_frac = (((freq * 4) % 120) * 0x20000) / 120; chan_frac = (((freq * 4) % 120) * 0x20000) / 120;
channelSel = (channelSel << 17) | chan_frac; 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 } else
channelSel = CHANSEL_2G(freq); channelSel = CHANSEL_2G(freq);
/* Set to 2G mode */ /* Set to 2G mode */
bMode = 1; bMode = 1;
} else { } else {
channelSel = CHANSEL_5G(freq); if (AR_SREV_9340(ah) && ah->is_clk_25mhz) {
/* Doubler is ON, so, divide channelSel by 2. */ u32 chan_frac;
channelSel >>= 1;
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 */ /* Set to 5G mode */
bMode = 0; bMode = 0;
} }
...@@ -151,7 +168,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, ...@@ -151,7 +168,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
* is out-of-band and can be ignored. * 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, spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah,
IS_CHAN_2GHZ(chan)); IS_CHAN_2GHZ(chan));
if (spur_fbin_ptr[0] == 0) /* No spur */ if (spur_fbin_ptr[0] == 0) /* No spur */
...@@ -176,7 +193,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, ...@@ -176,7 +193,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
for (i = 0; i < max_spur_cnts; i++) { for (i = 0; i < max_spur_cnts; i++) {
negative = 0; negative = 0;
if (AR_SREV_9485(ah)) if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i],
IS_CHAN_2GHZ(chan)) - synth_freq; IS_CHAN_2GHZ(chan)) - synth_freq;
else else
...@@ -599,29 +616,25 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, ...@@ -599,29 +616,25 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
unsigned int regWrites = 0, i; unsigned int regWrites = 0, i;
struct ieee80211_channel *channel = chan->chan; struct ieee80211_channel *channel = chan->chan;
u32 modesIndex, freqIndex; u32 modesIndex;
switch (chan->chanmode) { switch (chan->chanmode) {
case CHANNEL_A: case CHANNEL_A:
case CHANNEL_A_HT20: case CHANNEL_A_HT20:
modesIndex = 1; modesIndex = 1;
freqIndex = 1;
break; break;
case CHANNEL_A_HT40PLUS: case CHANNEL_A_HT40PLUS:
case CHANNEL_A_HT40MINUS: case CHANNEL_A_HT40MINUS:
modesIndex = 2; modesIndex = 2;
freqIndex = 1;
break; break;
case CHANNEL_G: case CHANNEL_G:
case CHANNEL_G_HT20: case CHANNEL_G_HT20:
case CHANNEL_B: case CHANNEL_B:
modesIndex = 4; modesIndex = 4;
freqIndex = 2;
break; break;
case CHANNEL_G_HT40PLUS: case CHANNEL_G_HT40PLUS:
case CHANNEL_G_HT40MINUS: case CHANNEL_G_HT40MINUS:
modesIndex = 3; modesIndex = 3;
freqIndex = 2;
break; break;
default: default:
...@@ -646,6 +659,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, ...@@ -646,6 +659,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
REG_WRITE_ARRAY(&ah->iniModesAdditional, REG_WRITE_ARRAY(&ah->iniModesAdditional,
modesIndex, regWrites); 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_override_ini(ah);
ar9003_hw_set_channel_regs(ah, chan); ar9003_hw_set_channel_regs(ah, chan);
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
......
...@@ -548,15 +548,12 @@ ...@@ -548,15 +548,12 @@
#define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300) #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_CONTROL_1 (AR_SM_BASE + AR_SREV_9485(ah) ? \
#define AR_PHY_TX_IQCAL_START_DO_CAL_9485 0x80000000 0x3c8 : 0x448)
#define AR_PHY_TX_IQCAL_START_DO_CAL_9485_S 31 #define AR_PHY_TX_IQCAL_START (AR_SM_BASE + AR_SREV_9485(ah) ? \
#define AR_PHY_TX_IQCAL_CONTROL_1_9485 (AR_SM_BASE + 0x3c8) 0x3c4 : 0x440)
#define AR_PHY_TX_IQCAL_STATUS_B0_9485 (AR_SM_BASE + 0x3f0) #define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + AR_SREV_9485(ah) ? \
0x3f0 : 0x48c)
#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_CORR_COEFF_B0(_i) (AR_SM_BASE + \ #define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \
(AR_SREV_9485(ah) ? \ (AR_SREV_9485(ah) ? \
0x3d0 : 0x450) + ((_i) << 2)) 0x3d0 : 0x450) + ((_i) << 2))
...@@ -588,7 +585,7 @@ ...@@ -588,7 +585,7 @@
#define AR_PHY_65NM_CH0_BIAS2 0x160c4 #define AR_PHY_65NM_CH0_BIAS2 0x160c4
#define AR_PHY_65NM_CH0_BIAS4 0x160cc #define AR_PHY_65NM_CH0_BIAS4 0x160cc
#define AR_PHY_65NM_CH0_RXTX4 0x1610c #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 0x80000000
#define AR_PHY_65NM_CH0_THERM_LOCAL_S 31 #define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
...@@ -758,10 +755,10 @@ ...@@ -758,10 +755,10 @@
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24
#define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004 #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_IQCAL_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_S 18
#define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001 #define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001
#define AR_PHY_TX_IQCAL_START_DO_CAL_S 0 #define AR_PHY_TX_IQCAL_START_DO_CAL_S 0
#define AR_PHY_TX_IQCAL_STATUS_FAILED 0x00000001 #define AR_PHY_TX_IQCAL_STATUS_FAILED 0x00000001
#define AR_PHY_CALIBRATED_GAINS_0 0x3e #define AR_PHY_CALIBRATED_GAINS_0 0x3e
......
此差异已折叠。
...@@ -423,6 +423,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); ...@@ -423,6 +423,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status);
#define ATH_PAPRD_TIMEOUT 100 /* msecs */ #define ATH_PAPRD_TIMEOUT 100 /* msecs */
void ath_hw_check(struct work_struct *work); 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_paprd_calibrate(struct work_struct *work);
void ath_ani_calibrate(unsigned long data); void ath_ani_calibrate(unsigned long data);
...@@ -453,6 +454,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc); ...@@ -453,6 +454,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc);
#define ATH_LED_PIN_DEF 1 #define ATH_LED_PIN_DEF 1
#define ATH_LED_PIN_9287 8 #define ATH_LED_PIN_9287 8
#define ATH_LED_PIN_9300 10
#define ATH_LED_PIN_9485 6 #define ATH_LED_PIN_9485 6
#ifdef CONFIG_MAC80211_LEDS #ifdef CONFIG_MAC80211_LEDS
......
...@@ -781,12 +781,6 @@ void ath_set_beacon(struct ath_softc *sc) ...@@ -781,12 +781,6 @@ void ath_set_beacon(struct ath_softc *sc)
break; break;
case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_STATION:
ath_beacon_config_sta(sc, cur_conf); 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; break;
default: default:
ath_dbg(common, ATH_DBG_CONFIG, ath_dbg(common, ATH_DBG_CONFIG,
......
...@@ -51,6 +51,10 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) ...@@ -51,6 +51,10 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
.bt_hold_rx_clear = true, .bt_hold_rx_clear = true,
}; };
u32 i; 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 =
(btcoex_hw->bt_coex_mode & AR_BT_QCU_THRESH) | (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) ...@@ -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_txframe_extend, AR_BT_TX_FRAME_EXTEND) |
SM(ath_bt_config.bt_mode, AR_BT_MODE) | SM(ath_bt_config.bt_mode, AR_BT_MODE) |
SM(ath_bt_config.bt_quiet_collision, AR_BT_QUIET) | 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_priority_time, AR_BT_PRIORITY_TIME) |
SM(ath_bt_config.bt_first_slot_time, AR_BT_FIRST_SLOT_TIME) | SM(ath_bt_config.bt_first_slot_time, AR_BT_FIRST_SLOT_TIME) |
SM(qnum, AR_BT_QCU_THRESH); SM(qnum, AR_BT_QCU_THRESH);
...@@ -142,6 +146,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, ...@@ -142,6 +146,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
} }
EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight);
static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
{ {
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
...@@ -152,9 +157,22 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) ...@@ -152,9 +157,22 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
* enable coex 3-wire * enable coex 3-wire
*/ */
REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_hw->bt_coex_mode); 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); 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)) { if (AR_SREV_9271(ah)) {
val = REG_READ(ah, 0x50040); val = REG_READ(ah, 0x50040);
val &= 0xFFFFFEFF; val &= 0xFFFFFEFF;
...@@ -202,10 +220,86 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah) ...@@ -202,10 +220,86 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
if (btcoex_hw->scheme == ATH_BTCOEX_CFG_3WIRE) { 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_MODE, AR_BT_QUIET | AR_BT_MODE);
REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0);
REG_WRITE(ah, AR_BT_COEX_MODE2, 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; ah->btcoex_hw.enabled = false;
} }
EXPORT_SYMBOL(ath9k_hw_btcoex_disable); 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 @@ ...@@ -19,9 +19,13 @@
#include "hw.h" #include "hw.h"
#define ATH_WLANACTIVE_GPIO 5 #define ATH_WLANACTIVE_GPIO_9280 5
#define ATH_BTACTIVE_GPIO 6 #define ATH_BTACTIVE_GPIO_9280 6
#define ATH_BTPRIORITY_GPIO 7 #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_BT_PERIOD 45
#define ATH_BTCOEX_DEF_DUTY_CYCLE 55 #define ATH_BTCOEX_DEF_DUTY_CYCLE 55
...@@ -32,6 +36,14 @@ ...@@ -32,6 +36,14 @@
#define ATH_BT_CNT_THRESHOLD 3 #define ATH_BT_CNT_THRESHOLD 3
#define ATH_BT_CNT_SCAN_THRESHOLD 15 #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 { enum ath_btcoex_scheme {
ATH_BTCOEX_CFG_NONE, ATH_BTCOEX_CFG_NONE,
ATH_BTCOEX_CFG_2WIRE, ATH_BTCOEX_CFG_2WIRE,
...@@ -57,5 +69,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, ...@@ -57,5 +69,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
u32 wlan_weight); u32 wlan_weight);
void ath9k_hw_btcoex_enable(struct ath_hw *ah); void ath9k_hw_btcoex_enable(struct ath_hw *ah);
void ath9k_hw_btcoex_disable(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 #endif
...@@ -158,37 +158,6 @@ int ath9k_cmn_count_streams(unsigned int chainmask, int max) ...@@ -158,37 +158,6 @@ int ath9k_cmn_count_streams(unsigned int chainmask, int max)
} }
EXPORT_SYMBOL(ath9k_cmn_count_streams); 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, void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
u16 new_txpow, u16 *txpower) u16 new_txpow, u16 *txpower)
{ {
......
...@@ -50,14 +50,6 @@ ...@@ -50,14 +50,6 @@
#define ATH_EP_RND(x, mul) \ #define ATH_EP_RND(x, mul) \
((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (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_padpos(__le16 frame_control);
int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, 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) ...@@ -326,6 +326,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
sc->debug.stats.istats.dtimsync++; sc->debug.stats.istats.dtimsync++;
if (status & ATH9K_INT_DTIM) if (status & ATH9K_INT_DTIM)
sc->debug.stats.istats.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, 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, ...@@ -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); "%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync);
len += snprintf(buf + len, sizeof(buf) - len, len += snprintf(buf + len, sizeof(buf) - len,
"%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim); "%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, len += snprintf(buf + len, sizeof(buf) - len,
"%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total); "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
if (len > sizeof(buf)) if (len > sizeof(buf))
len = sizeof(buf); len = sizeof(buf);
......
...@@ -54,6 +54,9 @@ struct ath_buf; ...@@ -54,6 +54,9 @@ struct ath_buf;
* @dtimsync: DTIM sync lossage * @dtimsync: DTIM sync lossage
* @dtim: RX Beacon with DTIM * @dtim: RX Beacon with DTIM
* @bb_watchdog: Baseband watchdog * @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 { struct ath_interrupt_stats {
u32 total; u32 total;
...@@ -78,6 +81,7 @@ struct ath_interrupt_stats { ...@@ -78,6 +81,7 @@ struct ath_interrupt_stats {
u32 dtimsync; u32 dtimsync;
u32 dtim; u32 dtim;
u32 bb_watchdog; u32 bb_watchdog;
u32 tsfoor;
}; };
/** /**
......
...@@ -319,10 +319,9 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, ...@@ -319,10 +319,9 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
u16 numXpdGain, xpdMask; u16 numXpdGain, xpdMask;
u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0}; u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0};
u32 reg32, regOffset, regChainOffset, regval; u32 reg32, regOffset, regChainOffset, regval;
int16_t modalIdx, diff = 0; int16_t diff = 0;
struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
xpdMask = pEepData->modalHeader.xpdGain; xpdMask = pEepData->modalHeader.xpdGain;
if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >= if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
......
...@@ -231,6 +231,10 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) ...@@ -231,6 +231,10 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
integer = swab32(pModal->antCtrlChain[i]); integer = swab32(pModal->antCtrlChain[i]);
pModal->antCtrlChain[i] = integer; 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++) { for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
word = swab16(pModal->spurChans[i].spurChan); word = swab16(pModal->spurChans[i].spurChan);
......
...@@ -46,6 +46,8 @@ void ath_init_leds(struct ath_softc *sc) ...@@ -46,6 +46,8 @@ void ath_init_leds(struct ath_softc *sc)
sc->sc_ah->led_pin = ATH_LED_PIN_9287; sc->sc_ah->led_pin = ATH_LED_PIN_9287;
else if (AR_SREV_9485(sc->sc_ah)) else if (AR_SREV_9485(sc->sc_ah))
sc->sc_ah->led_pin = ATH_LED_PIN_9485; 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 else
sc->sc_ah->led_pin = ATH_LED_PIN_DEF; sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
} }
...@@ -138,10 +140,10 @@ static void ath_detect_bt_priority(struct ath_softc *sc) ...@@ -138,10 +140,10 @@ static void ath_detect_bt_priority(struct ath_softc *sc)
static void ath9k_gen_timer_start(struct ath_hw *ah, static void ath9k_gen_timer_start(struct ath_hw *ah,
struct ath_gen_timer *timer, struct ath_gen_timer *timer,
u32 timer_next, u32 trig_timeout,
u32 timer_period) 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) { if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
ath9k_hw_disable_interrupts(ah); ath9k_hw_disable_interrupts(ah);
...@@ -174,17 +176,17 @@ static void ath_btcoex_period_timer(unsigned long data) ...@@ -174,17 +176,17 @@ static void ath_btcoex_period_timer(unsigned long data)
struct ath_softc *sc = (struct ath_softc *) data; struct ath_softc *sc = (struct ath_softc *) data;
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
struct ath_btcoex *btcoex = &sc->btcoex; struct ath_btcoex *btcoex = &sc->btcoex;
struct ath_common *common = ath9k_hw_common(ah);
u32 timer_period; u32 timer_period;
bool is_btscan; bool is_btscan;
ath9k_ps_wakeup(sc);
ath_detect_bt_priority(sc); ath_detect_bt_priority(sc);
is_btscan = sc->sc_flags & SC_OP_BT_SCAN; is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
spin_lock_bh(&btcoex->btcoex_lock); 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); btcoex->bt_stomp_type);
spin_unlock_bh(&btcoex->btcoex_lock); spin_unlock_bh(&btcoex->btcoex_lock);
...@@ -195,11 +197,12 @@ static void ath_btcoex_period_timer(unsigned long data) ...@@ -195,11 +197,12 @@ static void ath_btcoex_period_timer(unsigned long data)
timer_period = is_btscan ? btcoex->btscan_no_stomp : timer_period = is_btscan ? btcoex->btscan_no_stomp :
btcoex->btcoex_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); timer_period * 10);
btcoex->hw_timer_enabled = true; btcoex->hw_timer_enabled = true;
} }
ath9k_ps_restore(sc);
mod_timer(&btcoex->period_timer, jiffies + mod_timer(&btcoex->period_timer, jiffies +
msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD)); msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
} }
...@@ -219,14 +222,16 @@ static void ath_btcoex_no_stomp_timer(void *arg) ...@@ -219,14 +222,16 @@ static void ath_btcoex_no_stomp_timer(void *arg)
ath_dbg(common, ATH_DBG_BTCOEX, ath_dbg(common, ATH_DBG_BTCOEX,
"no stomp timer running\n"); "no stomp timer running\n");
ath9k_ps_wakeup(sc);
spin_lock_bh(&btcoex->btcoex_lock); spin_lock_bh(&btcoex->btcoex_lock);
if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) 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) 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); spin_unlock_bh(&btcoex->btcoex_lock);
ath9k_ps_restore(sc);
} }
int ath_init_btcoex_timer(struct ath_softc *sc) int ath_init_btcoex_timer(struct ath_softc *sc)
......
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
#ifndef HTC_USB_H #ifndef HTC_USB_H
#define 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 IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB))
#define AR9271_FIRMWARE 0x501000 #define AR9271_FIRMWARE 0x501000
......
...@@ -66,8 +66,6 @@ enum htc_opmode { ...@@ -66,8 +66,6 @@ enum htc_opmode {
HTC_M_WDS = 2 HTC_M_WDS = 2
}; };
#define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr)
#define ATH9K_HTC_AMPDU 1 #define ATH9K_HTC_AMPDU 1
#define ATH9K_HTC_NORMAL 2 #define ATH9K_HTC_NORMAL 2
#define ATH9K_HTC_BEACON 3 #define ATH9K_HTC_BEACON 3
...@@ -75,7 +73,6 @@ enum htc_opmode { ...@@ -75,7 +73,6 @@ enum htc_opmode {
#define ATH9K_HTC_TX_CTSONLY 0x1 #define ATH9K_HTC_TX_CTSONLY 0x1
#define ATH9K_HTC_TX_RTSCTS 0x2 #define ATH9K_HTC_TX_RTSCTS 0x2
#define ATH9K_HTC_TX_USE_MIN_RATE 0x100
struct tx_frame_hdr { struct tx_frame_hdr {
u8 data_type; u8 data_type;
...@@ -106,15 +103,14 @@ struct tx_beacon_header { ...@@ -106,15 +103,14 @@ struct tx_beacon_header {
u16 rev; u16 rev;
} __packed; } __packed;
#define MAX_TX_AMPDU_SUBFRAMES_9271 17
#define MAX_TX_AMPDU_SUBFRAMES_7010 22
struct ath9k_htc_cap_target { struct ath9k_htc_cap_target {
u32 flags; __be32 ampdu_limit;
u32 flags_ext;
u32 ampdu_limit;
u8 ampdu_subframes; u8 ampdu_subframes;
u8 enable_coex;
u8 tx_chainmask; u8 tx_chainmask;
u8 tx_chainmask_legacy;
u8 rtscts_ratecode;
u8 protmode;
u8 pad; u8 pad;
} __packed; } __packed;
...@@ -175,6 +171,13 @@ struct ath9k_htc_target_rate { ...@@ -175,6 +171,13 @@ struct ath9k_htc_target_rate {
struct ath9k_htc_rate rates; 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 { struct ath9k_htc_target_int_stats {
__be32 rx; __be32 rx;
__be32 rxorn; __be32 rxorn;
...@@ -382,25 +385,6 @@ static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, ...@@ -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_9287 10
#define ATH_LED_PIN_9271 15 #define ATH_LED_PIN_9271 15
#define ATH_LED_PIN_7010 12 #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 #define BSTUCK_THRESHOLD 10
...@@ -434,14 +418,11 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); ...@@ -434,14 +418,11 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv);
#define OP_INVALID BIT(0) #define OP_INVALID BIT(0)
#define OP_SCANNING BIT(1) #define OP_SCANNING BIT(1)
#define OP_LED_ASSOCIATED BIT(2) #define OP_ENABLE_BEACON BIT(2)
#define OP_LED_ON BIT(3) #define OP_BT_PRIORITY_DETECTED BIT(3)
#define OP_ENABLE_BEACON BIT(4) #define OP_BT_SCAN BIT(4)
#define OP_LED_DEINIT BIT(5) #define OP_ANI_RUNNING BIT(5)
#define OP_BT_PRIORITY_DETECTED BIT(6) #define OP_TSF_RESET BIT(6)
#define OP_BT_SCAN BIT(7)
#define OP_ANI_RUNNING BIT(8)
#define OP_TSF_RESET BIT(9)
struct ath9k_htc_priv { struct ath9k_htc_priv {
struct device *dev; struct device *dev;
...@@ -501,15 +482,13 @@ struct ath9k_htc_priv { ...@@ -501,15 +482,13 @@ struct ath9k_htc_priv {
bool ps_enabled; bool ps_enabled;
bool ps_idle; bool ps_idle;
struct ath_led radio_led; #ifdef CONFIG_MAC80211_LEDS
struct ath_led assoc_led; enum led_brightness brightness;
struct ath_led tx_led; bool led_registered;
struct ath_led rx_led; char led_name[32];
struct delayed_work ath9k_led_blink_work; struct led_classdev led_cdev;
int led_on_duration; struct work_struct led_work;
int led_off_duration; #endif
int led_on_cnt;
int led_off_cnt;
int beaconq; int beaconq;
int cabq; int cabq;
...@@ -551,7 +530,8 @@ void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id, ...@@ -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, void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
enum htc_endpoint_id ep_id, bool txok); 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_station_work(struct work_struct *work);
void ath9k_htc_aggr_work(struct work_struct *work); void ath9k_htc_aggr_work(struct work_struct *work);
void ath9k_htc_ani_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); ...@@ -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_rfkill_poll_state(struct ieee80211_hw *hw);
void ath9k_htc_radio_enable(struct ieee80211_hw *hw); void ath9k_htc_radio_enable(struct ieee80211_hw *hw);
void ath9k_htc_radio_disable(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_init_leds(struct ath9k_htc_priv *priv);
void ath9k_deinit_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, int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
u16 devid, char *product, u32 drv_info); u16 devid, char *product, u32 drv_info);
......
...@@ -74,7 +74,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, ...@@ -74,7 +74,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
__be32 htc_imask = 0; __be32 htc_imask = 0;
u64 tsf; u64 tsf;
int num_beacons, offset, dtim_dec_count, cfp_dec_count; int num_beacons, offset, dtim_dec_count, cfp_dec_count;
int ret; int ret __attribute__ ((unused));
u8 cmd_rsp; u8 cmd_rsp;
memset(&bs, 0, sizeof(bs)); memset(&bs, 0, sizeof(bs));
...@@ -190,7 +190,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, ...@@ -190,7 +190,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
enum ath9k_int imask = 0; enum ath9k_int imask = 0;
u32 nexttbtt, intval, tsftu; u32 nexttbtt, intval, tsftu;
__be32 htc_imask = 0; __be32 htc_imask = 0;
int ret; int ret __attribute__ ((unused));
u8 cmd_rsp; u8 cmd_rsp;
u64 tsf; u64 tsf;
...@@ -246,7 +246,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, ...@@ -246,7 +246,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
enum ath9k_int imask = 0; enum ath9k_int imask = 0;
u32 nexttbtt, intval, tsftu; u32 nexttbtt, intval, tsftu;
__be32 htc_imask = 0; __be32 htc_imask = 0;
int ret; int ret __attribute__ ((unused));
u8 cmd_rsp; u8 cmd_rsp;
u64 tsf; u64 tsf;
......
...@@ -33,9 +33,15 @@ static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf, ...@@ -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)); memset(&cmd_rsp, 0, sizeof(cmd_rsp));
ath9k_htc_ps_wakeup(priv);
WMI_CMD(WMI_INT_STATS_CMDID); WMI_CMD(WMI_INT_STATS_CMDID);
if (ret) if (ret) {
ath9k_htc_ps_restore(priv);
return -EINVAL; return -EINVAL;
}
ath9k_htc_ps_restore(priv);
len += snprintf(buf + len, sizeof(buf) - len, len += snprintf(buf + len, sizeof(buf) - len,
"%20s : %10u\n", "RX", "%20s : %10u\n", "RX",
...@@ -85,9 +91,15 @@ static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf, ...@@ -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)); memset(&cmd_rsp, 0, sizeof(cmd_rsp));
ath9k_htc_ps_wakeup(priv);
WMI_CMD(WMI_TX_STATS_CMDID); WMI_CMD(WMI_TX_STATS_CMDID);
if (ret) if (ret) {
ath9k_htc_ps_restore(priv);
return -EINVAL; return -EINVAL;
}
ath9k_htc_ps_restore(priv);
len += snprintf(buf + len, sizeof(buf) - len, len += snprintf(buf + len, sizeof(buf) - len,
"%20s : %10u\n", "Xretries", "%20s : %10u\n", "Xretries",
...@@ -149,9 +161,15 @@ static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf, ...@@ -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)); memset(&cmd_rsp, 0, sizeof(cmd_rsp));
ath9k_htc_ps_wakeup(priv);
WMI_CMD(WMI_RX_STATS_CMDID); WMI_CMD(WMI_RX_STATS_CMDID);
if (ret) if (ret) {
ath9k_htc_ps_restore(priv);
return -EINVAL; return -EINVAL;
}
ath9k_htc_ps_restore(priv);
len += snprintf(buf + len, sizeof(buf) - len, len += snprintf(buf + len, sizeof(buf) - len,
"%20s : %10u\n", "NoBuf", "%20s : %10u\n", "NoBuf",
...@@ -474,6 +492,439 @@ static const struct file_operations fops_debug = { ...@@ -474,6 +492,439 @@ static const struct file_operations fops_debug = {
.llseek = default_llseek, .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) int ath9k_htc_init_debug(struct ath_hw *ah)
{ {
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
...@@ -485,21 +936,25 @@ int ath9k_htc_init_debug(struct ath_hw *ah) ...@@ -485,21 +936,25 @@ int ath9k_htc_init_debug(struct ath_hw *ah)
return -ENOMEM; return -ENOMEM;
debugfs_create_file("tgt_int_stats", S_IRUSR, priv->debug.debugfs_phy, debugfs_create_file("tgt_int_stats", S_IRUSR, priv->debug.debugfs_phy,
priv, &fops_tgt_int_stats); priv, &fops_tgt_int_stats);
debugfs_create_file("tgt_tx_stats", S_IRUSR, priv->debug.debugfs_phy, debugfs_create_file("tgt_tx_stats", S_IRUSR, priv->debug.debugfs_phy,
priv, &fops_tgt_tx_stats); priv, &fops_tgt_tx_stats);
debugfs_create_file("tgt_rx_stats", S_IRUSR, priv->debug.debugfs_phy, debugfs_create_file("tgt_rx_stats", S_IRUSR, priv->debug.debugfs_phy,
priv, &fops_tgt_rx_stats); priv, &fops_tgt_rx_stats);
debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy, debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy,
priv, &fops_xmit); priv, &fops_xmit);
debugfs_create_file("recv", S_IRUSR, priv->debug.debugfs_phy, debugfs_create_file("recv", S_IRUSR, priv->debug.debugfs_phy,
priv, &fops_recv); priv, &fops_recv);
debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy, debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy,
priv, &fops_slot); priv, &fops_slot);
debugfs_create_file("queue", S_IRUSR, priv->debug.debugfs_phy, debugfs_create_file("queue", S_IRUSR, priv->debug.debugfs_phy,
priv, &fops_queue); priv, &fops_queue);
debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy, debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy,
priv, &fops_debug); 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; return 0;
} }
...@@ -65,17 +65,19 @@ static void ath_btcoex_period_work(struct work_struct *work) ...@@ -65,17 +65,19 @@ static void ath_btcoex_period_work(struct work_struct *work)
u32 timer_period; u32 timer_period;
bool is_btscan; bool is_btscan;
int ret; int ret;
u8 cmd_rsp, aggr;
ath_detect_bt_priority(priv); ath_detect_bt_priority(priv);
is_btscan = !!(priv->op_flags & OP_BT_SCAN); is_btscan = !!(priv->op_flags & OP_BT_SCAN);
aggr = priv->op_flags & OP_BT_PRIORITY_DETECTED; ret = ath9k_htc_update_cap_target(priv,
!!(priv->op_flags & OP_BT_PRIORITY_DETECTED));
WMI_CMD_BUF(WMI_AGGR_LIMIT_CMD, &aggr); 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); btcoex->bt_stomp_type);
timer_period = is_btscan ? btcoex->btscan_no_stomp : timer_period = is_btscan ? btcoex->btscan_no_stomp :
...@@ -103,9 +105,9 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work) ...@@ -103,9 +105,9 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work)
"time slice work for bt and wlan\n"); "time slice work for bt and wlan\n");
if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) 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) 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) 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) ...@@ -152,140 +154,41 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv)
/* LED */ /* 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, struct ath9k_htc_priv *priv = container_of(work,
ath9k_led_blink_work.work); struct ath9k_htc_priv,
led_work);
if (!(priv->op_flags & OP_LED_ASSOCIATED)) ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
return; (priv->brightness == LED_OFF));
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;
}
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;
}
} }
static void ath9k_led_brightness(struct led_classdev *led_cdev, static void ath9k_led_brightness(struct led_classdev *led_cdev,
enum led_brightness brightness) enum led_brightness brightness)
{ {
struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); struct ath9k_htc_priv *priv = container_of(led_cdev,
struct ath9k_htc_priv *priv = led->priv; struct ath9k_htc_priv,
led_cdev);
led->brightness = brightness; /* Not locked, but it's just a tiny green light..*/
if (!(priv->op_flags & OP_LED_DEINIT)) priv->brightness = brightness;
ieee80211_queue_delayed_work(priv->hw, ieee80211_queue_work(priv->hw, &priv->led_work);
&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;
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;
}
} }
void ath9k_deinit_leds(struct ath9k_htc_priv *priv) void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
{ {
priv->op_flags |= OP_LED_DEINIT; if (!priv->led_registered)
ath9k_unregister_led(&priv->assoc_led); return;
priv->op_flags &= ~OP_LED_ASSOCIATED;
ath9k_unregister_led(&priv->tx_led); ath9k_led_brightness(&priv->led_cdev, LED_OFF);
ath9k_unregister_led(&priv->rx_led); led_classdev_unregister(&priv->led_cdev);
ath9k_unregister_led(&priv->radio_led); cancel_work_sync(&priv->led_work);
} }
void ath9k_init_leds(struct ath9k_htc_priv *priv) void ath9k_init_leds(struct ath9k_htc_priv *priv)
{ {
char *trigger;
int ret; int ret;
if (AR_SREV_9287(priv->ah)) if (AR_SREV_9287(priv->ah))
...@@ -303,48 +206,21 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv) ...@@ -303,48 +206,21 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv)
/* LED off, active low */ /* LED off, active low */
ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1); ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work); snprintf(priv->led_name, sizeof(priv->led_name),
"ath9k_htc-%s", wiphy_name(priv->hw->wiphy));
trigger = ieee80211_get_radio_led_name(priv->hw); priv->led_cdev.name = priv->led_name;
snprintf(priv->radio_led.name, sizeof(priv->radio_led.name), priv->led_cdev.brightness_set = ath9k_led_brightness;
"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;
return; ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &priv->led_cdev);
if (ret < 0)
return;
fail: INIT_WORK(&priv->led_work, ath9k_led_work);
cancel_delayed_work_sync(&priv->ath9k_led_blink_work); priv->led_registered = true;
ath9k_deinit_leds(priv);
return;
} }
#endif
/*******************/ /*******************/
/* Rfkill */ /* Rfkill */
......
...@@ -117,6 +117,21 @@ static struct ieee80211_rate ath9k_legacy_rates[] = { ...@@ -117,6 +117,21 @@ static struct ieee80211_rate ath9k_legacy_rates[] = {
RATE(540, 0x0c, 0), 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) static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
{ {
int time_left; int time_left;
...@@ -243,7 +258,7 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid, ...@@ -243,7 +258,7 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid,
*/ */
if (IS_AR7010_DEVICE(drv_info)) if (IS_AR7010_DEVICE(drv_info))
priv->htc->credits = 45; priv->htc->credits = 48;
else else
priv->htc->credits = 33; priv->htc->credits = 33;
...@@ -753,6 +768,12 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, ...@@ -753,6 +768,12 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
hw->queues = 4; hw->queues = 4;
hw->channel_change_time = 5000; hw->channel_change_time = 5000;
hw->max_listen_interval = 10; 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->vif_data_size = sizeof(struct ath9k_htc_vif);
hw->sta_data_size = sizeof(struct ath9k_htc_sta); hw->sta_data_size = sizeof(struct ath9k_htc_sta);
...@@ -802,6 +823,17 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv) ...@@ -802,6 +823,17 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
priv->fw_version_major, priv->fw_version_major,
priv->fw_version_minor); 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; return 0;
} }
...@@ -846,6 +878,13 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, ...@@ -846,6 +878,13 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
if (error != 0) if (error != 0)
goto err_rx; 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 */ /* Register with mac80211 */
error = ieee80211_register_hw(hw); error = ieee80211_register_hw(hw);
if (error) if (error)
......
...@@ -332,6 +332,11 @@ static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) ...@@ -332,6 +332,11 @@ static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
hvif.index = priv->mon_vif_idx; hvif.index = priv->mon_vif_idx;
WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); 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->nvifs--;
priv->vif_slot &= ~(1 << priv->mon_vif_idx); priv->vif_slot &= ~(1 << priv->mon_vif_idx);
} }
...@@ -462,6 +467,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, ...@@ -462,6 +467,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
struct ath9k_htc_sta *ista; struct ath9k_htc_sta *ista;
int ret, sta_idx; int ret, sta_idx;
u8 cmd_rsp; u8 cmd_rsp;
u16 maxampdu;
if (priv->nstations >= ATH9K_HTC_MAX_STA) if (priv->nstations >= ATH9K_HTC_MAX_STA)
return -ENOBUFS; return -ENOBUFS;
...@@ -485,7 +491,15 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, ...@@ -485,7 +491,15 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
tsta.sta_index = sta_idx; tsta.sta_index = sta_idx;
tsta.vif_index = avp->index; tsta.vif_index = avp->index;
tsta.maxampdu = cpu_to_be16(0xffff);
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) if (sta && sta->ht_cap.ht_supported)
tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
...@@ -558,7 +572,8 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv, ...@@ -558,7 +572,8 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
return 0; 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; struct ath9k_htc_cap_target tcap;
int ret; int ret;
...@@ -566,13 +581,9 @@ int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv) ...@@ -566,13 +581,9 @@ int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target)); memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
/* FIXME: Values are hardcoded */ tcap.ampdu_limit = cpu_to_be32(0xffff);
tcap.flags = 0x240c40; tcap.ampdu_subframes = priv->hw->max_tx_aggregation_subframes;
tcap.flags_ext = 0x80601000; tcap.enable_coex = enable_coex;
tcap.ampdu_limit = 0xffff0000;
tcap.ampdu_subframes = 20;
tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask;
tcap.protmode = 1;
tcap.tx_chainmask = priv->ah->caps.tx_chainmask; tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap); WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
...@@ -931,7 +942,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) ...@@ -931,7 +942,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
ath9k_host_rx_init(priv); ath9k_host_rx_init(priv);
ret = ath9k_htc_update_cap_target(priv); ret = ath9k_htc_update_cap_target(priv, 0);
if (ret) if (ret)
ath_dbg(common, ATH_DBG_CONFIG, ath_dbg(common, ATH_DBG_CONFIG,
"Failed to update capability in target\n"); "Failed to update capability in target\n");
...@@ -964,7 +975,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) ...@@ -964,7 +975,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
struct ath9k_htc_priv *priv = hw->priv; struct ath9k_htc_priv *priv = hw->priv;
struct ath_hw *ah = priv->ah; struct ath_hw *ah = priv->ah;
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
int ret = 0; int ret __attribute__ ((unused));
u8 cmd_rsp; u8 cmd_rsp;
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
...@@ -992,9 +1003,11 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) ...@@ -992,9 +1003,11 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
/* Cancel all the running timers/work .. */ /* Cancel all the running timers/work .. */
cancel_work_sync(&priv->fatal_work); cancel_work_sync(&priv->fatal_work);
cancel_work_sync(&priv->ps_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_htc_stop_ani(priv);
ath9k_led_stop_brightness(priv);
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
...@@ -1135,6 +1148,10 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, ...@@ -1135,6 +1148,10 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
hvif.index = avp->index; hvif.index = avp->index;
WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); 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->nvifs--;
priv->vif_slot &= ~(1 << avp->index); priv->vif_slot &= ~(1 << avp->index);
...@@ -1567,6 +1584,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, ...@@ -1567,6 +1584,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
int ret = 0; int ret = 0;
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
ath9k_htc_ps_wakeup(priv);
switch (action) { switch (action) {
case IEEE80211_AMPDU_RX_START: case IEEE80211_AMPDU_RX_START:
...@@ -1592,6 +1610,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, ...@@ -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"); ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
} }
ath9k_htc_ps_restore(priv);
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
return ret; return ret;
...@@ -1642,6 +1661,55 @@ static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw, ...@@ -1642,6 +1661,55 @@ static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
mutex_unlock(&priv->mutex); 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 = { struct ieee80211_ops ath9k_htc_ops = {
.tx = ath9k_htc_tx, .tx = ath9k_htc_tx,
.start = ath9k_htc_start, .start = ath9k_htc_start,
...@@ -1664,4 +1732,5 @@ struct ieee80211_ops ath9k_htc_ops = { ...@@ -1664,4 +1732,5 @@ struct ieee80211_ops ath9k_htc_ops = {
.set_rts_threshold = ath9k_htc_set_rts_threshold, .set_rts_threshold = ath9k_htc_set_rts_threshold,
.rfkill_poll = ath9k_htc_rfkill_poll_state, .rfkill_poll = ath9k_htc_rfkill_poll_state,
.set_coverage_class = ath9k_htc_set_coverage_class, .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, ...@@ -446,7 +446,6 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
struct ieee80211_tx_info *tx_info; struct ieee80211_tx_info *tx_info;
struct ieee80211_tx_rate *rate; struct ieee80211_tx_rate *rate;
struct ieee80211_conf *cur_conf = &priv->hw->conf; struct ieee80211_conf *cur_conf = &priv->hw->conf;
struct ieee80211_supported_band *sband;
bool txok; bool txok;
int slot; int slot;
...@@ -461,7 +460,6 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, ...@@ -461,7 +460,6 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
tx_info = IEEE80211_SKB_CB(skb); tx_info = IEEE80211_SKB_CB(skb);
vif = tx_info->control.vif; vif = tx_info->control.vif;
rate = &tx_info->status.rates[0]; rate = &tx_info->status.rates[0];
sband = priv->hw->wiphy->bands[cur_conf->channel->band];
memset(&tx_info->status, 0, sizeof(tx_info->status)); memset(&tx_info->status, 0, sizeof(tx_info->status));
......
...@@ -83,21 +83,10 @@ struct htc_ep_callbacks { ...@@ -83,21 +83,10 @@ struct htc_ep_callbacks {
void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id); 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 { struct htc_endpoint {
u16 service_id; u16 service_id;
struct htc_ep_callbacks ep_callbacks; struct htc_ep_callbacks ep_callbacks;
struct htc_txq htc_txq;
u32 max_txqdepth; u32 max_txqdepth;
int max_msglen; int max_msglen;
......
...@@ -247,6 +247,17 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah) ...@@ -247,6 +247,17 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
{ {
u32 val; 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; val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
if (val == 0xFF) { if (val == 0xFF) {
...@@ -462,7 +473,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah) ...@@ -462,7 +473,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
return ecode; return ecode;
} }
if (!AR_SREV_9100(ah)) { if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) {
ath9k_hw_ani_setup(ah); ath9k_hw_ani_setup(ah);
ath9k_hw_ani_init(ah); ath9k_hw_ani_init(ah);
} }
...@@ -484,9 +495,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) ...@@ -484,9 +495,6 @@ static int __ath9k_hw_init(struct ath_hw *ah)
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
int r = 0; int r = 0;
if (ah->hw_version.devid == AR5416_AR9100_DEVID)
ah->hw_version.macVersion = AR_SREV_VERSION_9100;
ath9k_hw_read_revisions(ah); ath9k_hw_read_revisions(ah);
/* /*
...@@ -544,6 +552,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) ...@@ -544,6 +552,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
case AR_SREV_VERSION_9271: case AR_SREV_VERSION_9271:
case AR_SREV_VERSION_9300: case AR_SREV_VERSION_9300:
case AR_SREV_VERSION_9485: case AR_SREV_VERSION_9485:
case AR_SREV_VERSION_9340:
break; break;
default: default:
ath_err(common, ath_err(common,
...@@ -552,7 +561,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) ...@@ -552,7 +561,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
return -EOPNOTSUPP; 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->is_pciexpress = false;
ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
...@@ -621,6 +630,7 @@ int ath9k_hw_init(struct ath_hw *ah) ...@@ -621,6 +630,7 @@ int ath9k_hw_init(struct ath_hw *ah)
case AR2427_DEVID_PCIE: case AR2427_DEVID_PCIE:
case AR9300_DEVID_PCIE: case AR9300_DEVID_PCIE:
case AR9300_DEVID_AR9485_PCIE: case AR9300_DEVID_AR9485_PCIE:
case AR9300_DEVID_AR9340:
break; break;
default: default:
if (common->bus_ops->ath_bus_type == ATH_USB) if (common->bus_ops->ath_bus_type == ATH_USB)
...@@ -663,7 +673,7 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) ...@@ -663,7 +673,7 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
REGWRITE_BUFFER_FLUSH(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); REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
udelay(100); udelay(100);
...@@ -676,7 +686,6 @@ unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) ...@@ -676,7 +686,6 @@ unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
} }
EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc);
#define DPLL3_PHASE_SHIFT_VAL 0x1
static void ath9k_hw_init_pll(struct ath_hw *ah, static void ath9k_hw_init_pll(struct ath_hw *ah,
struct ath9k_channel *chan) struct ath9k_channel *chan)
{ {
...@@ -713,16 +722,48 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, ...@@ -713,16 +722,48 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
AR_CH0_BB_DPLL2_PLL_PWD, 0x0); AR_CH0_BB_DPLL2_PLL_PWD, 0x0);
udelay(1000); udelay(1000);
} else if (AR_SREV_9340(ah)) {
u32 regval, pll2_divint, pll2_divfrac, refdiv;
REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); 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); pll = ath9k_hw_compute_pll_control(ah, chan);
REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
if (AR_SREV_9485(ah)) if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
udelay(1000); udelay(1000);
/* Switch the core clock for ar9271 to 117Mhz */ /* Switch the core clock for ar9271 to 117Mhz */
...@@ -734,17 +775,34 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, ...@@ -734,17 +775,34 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
udelay(RTC_PLL_SETTLE_DELAY); udelay(RTC_PLL_SETTLE_DELAY);
REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); 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, static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
enum nl80211_iftype opmode) enum nl80211_iftype opmode)
{ {
u32 sync_default = AR_INTR_SYNC_DEFAULT;
u32 imr_reg = AR_IMR_TXERR | u32 imr_reg = AR_IMR_TXERR |
AR_IMR_TXURN | AR_IMR_TXURN |
AR_IMR_RXERR | AR_IMR_RXERR |
AR_IMR_RXORN | AR_IMR_RXORN |
AR_IMR_BCNMISC; AR_IMR_BCNMISC;
if (AR_SREV_9340(ah))
sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
if (AR_SREV_9300_20_OR_LATER(ah)) { if (AR_SREV_9300_20_OR_LATER(ah)) {
imr_reg |= AR_IMR_RXOK_HP; imr_reg |= AR_IMR_RXOK_HP;
if (ah->config.rx_intr_mitigation) if (ah->config.rx_intr_mitigation)
...@@ -775,7 +833,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, ...@@ -775,7 +833,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
if (!AR_SREV_9100(ah)) { if (!AR_SREV_9100(ah)) {
REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); 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); REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
} }
...@@ -1487,7 +1545,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ...@@ -1487,7 +1545,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
} }
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
else 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); REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
#endif #endif
} }
...@@ -1793,7 +1853,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) ...@@ -1793,7 +1853,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
u16 capField = 0, eeval; u16 eeval;
u8 ant_div_ctl1, tx_chainmask, rx_chainmask; u8 ant_div_ctl1, tx_chainmask, rx_chainmask;
eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0); eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
...@@ -1804,8 +1864,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) ...@@ -1804,8 +1864,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
eeval |= AR9285_RDEXT_DEFAULT; eeval |= AR9285_RDEXT_DEFAULT;
regulatory->current_rd_ext = eeval; regulatory->current_rd_ext = eeval;
capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
if (ah->opmode != NL80211_IFTYPE_AP && if (ah->opmode != NL80211_IFTYPE_AP &&
ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) { ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
if (regulatory->current_rd == 0x64 || if (regulatory->current_rd == 0x64 ||
...@@ -1898,15 +1956,23 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) ...@@ -1898,15 +1956,23 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
else else
pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) { if (common->btcoex_enabled) {
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO; if (AR_SREV_9300_20_OR_LATER(ah)) {
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
if (AR_SREV_9285(ah)) {
btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO; btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300;
} else { btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300;
btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE; 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_9285;
} else {
btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
}
} }
} else { } else {
btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE; btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
...@@ -2359,11 +2425,11 @@ EXPORT_SYMBOL(ath_gen_timer_alloc); ...@@ -2359,11 +2425,11 @@ EXPORT_SYMBOL(ath_gen_timer_alloc);
void ath9k_hw_gen_timer_start(struct ath_hw *ah, void ath9k_hw_gen_timer_start(struct ath_hw *ah,
struct ath_gen_timer *timer, struct ath_gen_timer *timer,
u32 timer_next, u32 trig_timeout,
u32 timer_period) u32 timer_period)
{ {
struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
u32 tsf; u32 tsf, timer_next;
BUG_ON(!timer_period); BUG_ON(!timer_period);
...@@ -2371,17 +2437,12 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah, ...@@ -2371,17 +2437,12 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah,
tsf = ath9k_hw_gettsf32(ah); tsf = ath9k_hw_gettsf32(ah);
timer_next = tsf + trig_timeout;
ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER, ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER,
"current tsf %x period %x timer_next %x\n", "current tsf %x period %x timer_next %x\n",
tsf, timer_period, timer_next); 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 * Program generic timer registers
*/ */
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
#define AR9287_DEVID_PCI 0x002d #define AR9287_DEVID_PCI 0x002d
#define AR9287_DEVID_PCIE 0x002e #define AR9287_DEVID_PCIE 0x002e
#define AR9300_DEVID_PCIE 0x0030 #define AR9300_DEVID_PCIE 0x0030
#define AR9300_DEVID_AR9340 0x0031
#define AR9300_DEVID_AR9485_PCIE 0x0032 #define AR9300_DEVID_AR9485_PCIE 0x0032
#define AR5416_AR9100_DEVID 0x000b #define AR5416_AR9100_DEVID 0x000b
...@@ -55,6 +56,9 @@ ...@@ -55,6 +56,9 @@
#define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa #define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa
#define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab #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_AMPDU_LIMIT_MAX (64 * 1024 - 1)
#define ATH_DEFAULT_NOISE_FLOOR -95 #define ATH_DEFAULT_NOISE_FLOOR -95
...@@ -121,7 +125,7 @@ ...@@ -121,7 +125,7 @@
#define AR_GPIO_BIT(_gpio) (1 << (_gpio)) #define AR_GPIO_BIT(_gpio) (1 << (_gpio))
#define BASE_ACTIVATE_DELAY 100 #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 COEF_SCALE_S 24
#define HT40_CHANNEL_CENTER_SHIFT 10 #define HT40_CHANNEL_CENTER_SHIFT 10
...@@ -771,6 +775,8 @@ struct ath_hw { ...@@ -771,6 +775,8 @@ struct ath_hw {
/* Bluetooth coexistance */ /* Bluetooth coexistance */
struct ath_btcoex_hw btcoex_hw; 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; u32 intr_txqs;
u8 txchainmask; u8 txchainmask;
...@@ -799,6 +805,7 @@ struct ath_hw { ...@@ -799,6 +805,7 @@ struct ath_hw {
struct ar5416IniArray iniPcieSerdes; struct ar5416IniArray iniPcieSerdes;
struct ar5416IniArray iniPcieSerdesLowPower; struct ar5416IniArray iniPcieSerdesLowPower;
struct ar5416IniArray iniModesAdditional; struct ar5416IniArray iniModesAdditional;
struct ar5416IniArray iniModesAdditional_40M;
struct ar5416IniArray iniModesRxGain; struct ar5416IniArray iniModesRxGain;
struct ar5416IniArray iniModesTxGain; struct ar5416IniArray iniModesTxGain;
struct ar5416IniArray iniModes_9271_1_0_only; struct ar5416IniArray iniModes_9271_1_0_only;
...@@ -845,6 +852,8 @@ struct ath_hw { ...@@ -845,6 +852,8 @@ struct ath_hw {
/* Enterprise mode cap */ /* Enterprise mode cap */
u32 ent_mode; u32 ent_mode;
bool is_clk_25mhz;
}; };
struct ath_bus_ops { struct ath_bus_ops {
...@@ -928,7 +937,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); ...@@ -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_reset_tsf(struct ath_hw *ah);
void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
void ath9k_hw_init_global_settings(struct ath_hw *ah); 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_set11nmac2040(struct ath_hw *ah);
void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); 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, 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, ...@@ -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_mask = pdata->gpio_mask;
sc->sc_ah->gpio_val = pdata->gpio_val; sc->sc_ah->gpio_val = pdata->gpio_val;
sc->sc_ah->led_pin = pdata->led_pin; sc->sc_ah->led_pin = pdata->led_pin;
ah->is_clk_25mhz = pdata->is_clk_25mhz;
} }
common = ath9k_hw_common(ah); common = ath9k_hw_common(ah);
...@@ -800,6 +801,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, ...@@ -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->hw_check_work, ath_hw_check);
INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); 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; sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
ath_init_leds(sc); ath_init_leds(sc);
......
...@@ -812,10 +812,14 @@ EXPORT_SYMBOL(ath9k_hw_disable_interrupts); ...@@ -812,10 +812,14 @@ EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
void ath9k_hw_enable_interrupts(struct ath_hw *ah) void ath9k_hw_enable_interrupts(struct ath_hw *ah)
{ {
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
u32 sync_default = AR_INTR_SYNC_DEFAULT;
if (!(ah->imask & ATH9K_INT_GLOBAL)) if (!(ah->imask & ATH9K_INT_GLOBAL))
return; return;
if (AR_SREV_9340(ah))
sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n"); ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n");
REG_WRITE(ah, AR_IER, AR_IER_ENABLE); REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
if (!AR_SREV_9100(ah)) { if (!AR_SREV_9100(ah)) {
...@@ -824,10 +828,8 @@ void ath9k_hw_enable_interrupts(struct ath_hw *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_ASYNC_MASK, AR_INTR_MAC_IRQ);
REG_WRITE(ah, AR_INTR_SYNC_ENABLE, REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
AR_INTR_SYNC_DEFAULT); REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default);
REG_WRITE(ah, AR_INTR_SYNC_MASK,
AR_INTR_SYNC_DEFAULT);
} }
ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); 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) ...@@ -883,6 +885,9 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
mask |= AR_IMR_GENTMR; mask |= AR_IMR_GENTMR;
} }
if (ints & ATH9K_INT_GENTIMER)
mask |= AR_IMR_GENTMR;
if (ints & (ATH9K_INT_BMISC)) { if (ints & (ATH9K_INT_BMISC)) {
mask |= AR_IMR_BCNMISC; mask |= AR_IMR_BCNMISC;
if (ints & ATH9K_INT_TIM) if (ints & ATH9K_INT_TIM)
......
...@@ -624,6 +624,43 @@ void ath_hw_check(struct work_struct *work) ...@@ -624,6 +624,43 @@ void ath_hw_check(struct work_struct *work)
ath9k_ps_restore(sc); 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) void ath9k_tasklet(unsigned long data)
{ {
struct ath_softc *sc = (struct ath_softc *)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) ...@@ -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 Info ASSOC %d, bssid: %pM\n",
bss_conf->aid, common->curbssid); bss_conf->aid, common->curbssid);
ath_beacon_config(sc, vif); 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 */ /* Reset rssi stats */
sc->last_rssi = ATH_RSSI_DUMMY_MARKER; sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
sc->sc_ah->stats.avgbrssi = 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) ...@@ -2219,9 +2262,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
int timeout = 200; /* ms */ int timeout = 200; /* ms */
int i, j; int i, j;
ath9k_ps_wakeup(sc);
mutex_lock(&sc->mutex); mutex_lock(&sc->mutex);
cancel_delayed_work_sync(&sc->tx_complete_work); cancel_delayed_work_sync(&sc->tx_complete_work);
if (drop) if (drop)
...@@ -2244,15 +2285,15 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) ...@@ -2244,15 +2285,15 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
goto out; goto out;
} }
ath9k_ps_wakeup(sc);
if (!ath_drain_all_txq(sc, false)) if (!ath_drain_all_txq(sc, false))
ath_reset(sc, false); ath_reset(sc, false);
ath9k_ps_restore(sc);
ieee80211_wake_queues(hw); ieee80211_wake_queues(hw);
out: out:
ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
mutex_unlock(&sc->mutex); mutex_unlock(&sc->mutex);
ath9k_ps_restore(sc);
} }
static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
......
...@@ -45,4 +45,7 @@ ...@@ -45,4 +45,7 @@
#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000 #define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20 #define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
#define AR_PHY_PLL_CONTROL 0x16180
#define AR_PHY_PLL_MODE 0x16184
#endif #endif
...@@ -854,14 +854,13 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, ...@@ -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); 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, const struct ath_rate_table *rate_table,
struct ath_rate_priv *ath_rc_priv, struct ath_rate_priv *ath_rc_priv,
struct ieee80211_tx_info *tx_info, struct ieee80211_tx_info *tx_info,
int tx_rate, int xretries, int retries, int tx_rate, int xretries, int retries,
u32 now_msec) u32 now_msec)
{ {
bool state_change = false;
int count, n_bad_frames; int count, n_bad_frames;
u8 last_per; u8 last_per;
static const u32 nretry_to_per_lookup[10] = { static const u32 nretry_to_per_lookup[10] = {
...@@ -992,8 +991,6 @@ static bool ath_rc_update_per(struct ath_softc *sc, ...@@ -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, 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, ...@@ -1017,7 +1014,6 @@ static void ath_rc_update_ht(struct ath_softc *sc,
u32 now_msec = jiffies_to_msecs(jiffies); u32 now_msec = jiffies_to_msecs(jiffies);
int rate; int rate;
u8 last_per; u8 last_per;
bool state_change = false;
const struct ath_rate_table *rate_table = ath_rc_priv->rate_table; const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
int size = ath_rc_priv->rate_table_size; int size = ath_rc_priv->rate_table_size;
...@@ -1027,9 +1023,9 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1027,9 +1023,9 @@ static void ath_rc_update_ht(struct ath_softc *sc,
last_per = ath_rc_priv->per[tx_rate]; last_per = ath_rc_priv->per[tx_rate];
/* Update PER first */ /* 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, tx_info, tx_rate, xretries,
retries, now_msec); retries, now_msec);
/* /*
* If this rate looks bad (high PER) then stop using it for * If this rate looks bad (high PER) then stop using it for
......
...@@ -1339,7 +1339,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) ...@@ -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_hw_antcomb_conf div_ant_conf;
struct ath_ant_comb *antcomb = &sc->ant_comb; struct ath_ant_comb *antcomb = &sc->ant_comb;
int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; 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 main_rssi = rs->rs_rssi_ctl0;
int alt_rssi = rs->rs_rssi_ctl1; int alt_rssi = rs->rs_rssi_ctl1;
int rx_ant_conf, main_ant_conf; 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) ...@@ -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); ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf);
curr_alt_set = div_ant_conf.alt_lna_conf; curr_alt_set = div_ant_conf.alt_lna_conf;
curr_main_set = div_ant_conf.main_lna_conf; curr_main_set = div_ant_conf.main_lna_conf;
curr_bias = div_ant_conf.fast_div_bias;
antcomb->count++; antcomb->count++;
...@@ -1743,7 +1742,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) ...@@ -1743,7 +1742,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
if ((sc->ps_flags & (PS_WAIT_FOR_BEACON | if ((sc->ps_flags & (PS_WAIT_FOR_BEACON |
PS_WAIT_FOR_CAB | PS_WAIT_FOR_CAB |
PS_WAIT_FOR_PSPOLL_DATA)) || PS_WAIT_FOR_PSPOLL_DATA)) ||
unlikely(ath9k_check_auto_sleep(sc))) ath9k_check_auto_sleep(sc))
ath_rx_ps(sc, skb); ath_rx_ps(sc, skb);
spin_unlock_irqrestore(&sc->sc_pm_lock, flags); spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
......
...@@ -693,7 +693,7 @@ ...@@ -693,7 +693,7 @@
#define AR_RC_APB 0x00000002 #define AR_RC_APB 0x00000002
#define AR_RC_HOSTIF 0x00000100 #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_BIT6 (1 << 6)
#define AR_WA_BIT7 (1 << 7) #define AR_WA_BIT7 (1 << 7)
#define AR_WA_BIT23 (1 << 23) #define AR_WA_BIT23 (1 << 23)
...@@ -712,7 +712,7 @@ ...@@ -712,7 +712,7 @@
#define AR_PM_STATE 0x4008 #define AR_PM_STATE 0x4008
#define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000 #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 0x0000FFFF
#define AR_HOST_TIMEOUT_APB_CNTR_S 0 #define AR_HOST_TIMEOUT_APB_CNTR_S 0
#define AR_HOST_TIMEOUT_LCL_CNTR 0xFFFF0000 #define AR_HOST_TIMEOUT_LCL_CNTR 0xFFFF0000
...@@ -742,7 +742,8 @@ ...@@ -742,7 +742,8 @@
#define EEPROM_PROTECT_WP_1024_2047 0x8000 #define EEPROM_PROTECT_WP_1024_2047 0x8000
#define AR_SREV \ #define AR_SREV \
((AR_SREV_9100(ah)) ? 0x0600 : 0x4020) ((AR_SREV_9100(ah)) ? 0x0600 : (AR_SREV_9340(ah) \
? 0x400c : 0x4020))
#define AR_SREV_ID \ #define AR_SREV_ID \
((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF) ((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF)
...@@ -790,6 +791,7 @@ ...@@ -790,6 +791,7 @@
#define AR_SREV_VERSION_9485 0x240 #define AR_SREV_VERSION_9485 0x240
#define AR_SREV_REVISION_9485_10 0 #define AR_SREV_REVISION_9485_10 0
#define AR_SREV_REVISION_9485_11 1 #define AR_SREV_REVISION_9485_11 1
#define AR_SREV_VERSION_9340 0x300
#define AR_SREV_5416(_ah) \ #define AR_SREV_5416(_ah) \
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
...@@ -868,6 +870,11 @@ ...@@ -868,6 +870,11 @@
#define AR_SREV_9485_11(_ah) \ #define AR_SREV_9485_11(_ah) \
(AR_SREV_9485(_ah) && \ (AR_SREV_9485(_ah) && \
((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11)) ((_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) \ #define AR_SREV_9285E_20(_ah) \
(AR_SREV_9285_12_OR_LATER(_ah) && \ (AR_SREV_9285_12_OR_LATER(_ah) && \
...@@ -910,11 +917,11 @@ enum ath_usb_dev { ...@@ -910,11 +917,11 @@ enum ath_usb_dev {
#define AR_INTR_SPURIOUS 0xFFFFFFFF #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 0xFFFC0000
#define AR_INTR_SYNC_ENABLE_GPIO_S 18 #define AR_INTR_SYNC_ENABLE_GPIO_S 18
...@@ -954,24 +961,24 @@ enum { ...@@ -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 0xFFFC0000
#define AR_INTR_ASYNC_MASK_GPIO_S 18 #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 0xFFFC0000
#define AR_INTR_SYNC_MASK_GPIO_S 18 #define AR_INTR_SYNC_MASK_GPIO_S 18
#define AR_INTR_ASYNC_CAUSE_CLR 0x4038 #define AR_INTR_ASYNC_CAUSE_CLR (AR_SREV_9340(ah) ? 0x4020 : 0x4038)
#define AR_INTR_ASYNC_CAUSE 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 0xFFFC0000
#define AR_INTR_ASYNC_ENABLE_GPIO_S 18 #define AR_INTR_ASYNC_ENABLE_GPIO_S 18
#define AR_PCIE_SERDES 0x4040 #define AR_PCIE_SERDES 0x4040
#define AR_PCIE_SERDES2 0x4044 #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_PCIE_PM_CTRL_ENA 0x00080000
#define AR_NUM_GPIO 14 #define AR_NUM_GPIO 14
...@@ -982,7 +989,7 @@ enum { ...@@ -982,7 +989,7 @@ enum {
#define AR9300_NUM_GPIO 17 #define AR9300_NUM_GPIO 17
#define AR7010_NUM_GPIO 16 #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 0x0FFFC000
#define AR_GPIO_IN_VAL_S 14 #define AR_GPIO_IN_VAL_S 14
#define AR928X_GPIO_IN_VAL 0x000FFC00 #define AR928X_GPIO_IN_VAL 0x000FFC00
...@@ -996,11 +1003,12 @@ enum { ...@@ -996,11 +1003,12 @@ enum {
#define AR7010_GPIO_IN_VAL 0x0000FFFF #define AR7010_GPIO_IN_VAL 0x0000FFFF
#define AR7010_GPIO_IN_VAL_S 0 #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 0x0001FFFF
#define AR9300_GPIO_IN_VAL_S 0 #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 0x3
#define AR_GPIO_OE_OUT_DRV_NO 0x0 #define AR_GPIO_OE_OUT_DRV_NO 0x0
#define AR_GPIO_OE_OUT_DRV_LOW 0x1 #define AR_GPIO_OE_OUT_DRV_LOW 0x1
...@@ -1022,11 +1030,13 @@ enum { ...@@ -1022,11 +1030,13 @@ enum {
#define AR7010_GPIO_INT_MASK 0x52024 #define AR7010_GPIO_INT_MASK 0x52024
#define AR7010_GPIO_FUNCTION 0x52028 #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 0x0001FFFF
#define AR_GPIO_INTR_POL_VAL_S 0 #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_DEF 0x00000004
#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2 #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2
#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008 #define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008
...@@ -1044,13 +1054,15 @@ enum { ...@@ -1044,13 +1054,15 @@ enum {
#define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000 #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000
#define AR_GPIO_JTAG_DISABLE 0x00020000 #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 0x000f0000
#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16 #define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16
#define AR_GPIO_INPUT_MUX1_BT_PRIORITY 0x00000f00 #define AR_GPIO_INPUT_MUX1_BT_PRIORITY 0x00000f00
#define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S 8 #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 0x0000000f
#define AR_GPIO_INPUT_MUX2_CLK25_S 0 #define AR_GPIO_INPUT_MUX2_CLK25_S 0
#define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0 #define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0
...@@ -1058,13 +1070,18 @@ enum { ...@@ -1058,13 +1070,18 @@ enum {
#define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00 #define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00
#define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8 #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_MUX1 (AR_SREV_9340(ah) ? 0x4048 : \
#define AR_GPIO_OUTPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064) (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060))
#define AR_GPIO_OUTPUT_MUX3 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068) #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 0x0000ffff
#define AR_EEPROM_STATUS_DATA_VAL_S 0 #define AR_EEPROM_STATUS_DATA_VAL_S 0
#define AR_EEPROM_STATUS_DATA_BUSY 0x00010000 #define AR_EEPROM_STATUS_DATA_BUSY 0x00010000
...@@ -1072,17 +1089,19 @@ enum { ...@@ -1072,17 +1089,19 @@ enum {
#define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000 #define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000
#define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000 #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_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_PCIE_MSI_ENABLE 0x00000001
#define AR_INTR_PRIO_SYNC_ENABLE 0x40c4 #define AR_INTR_PRIO_SYNC_ENABLE (AR_SREV_9340(ah) ? 0x4088 : 0x40c4)
#define AR_INTR_PRIO_ASYNC_MASK 0x40c8 #define AR_INTR_PRIO_ASYNC_MASK (AR_SREV_9340(ah) ? 0x408c : 0x40c8)
#define AR_INTR_PRIO_SYNC_MASK 0x40cc #define AR_INTR_PRIO_SYNC_MASK (AR_SREV_9340(ah) ? 0x4090 : 0x40cc)
#define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4 #define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4)
#define AR_ENT_OTP 0x40d8 #define AR_ENT_OTP 0x40d8
#define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000 #define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000
#define AR_ENT_OTP_MPSD 0x00800000 #define AR_ENT_OTP_MPSD 0x00800000
...@@ -1163,6 +1182,7 @@ enum { ...@@ -1163,6 +1182,7 @@ enum {
#define AR_RTC_PLL_REFDIV_5 0x000000c0 #define AR_RTC_PLL_REFDIV_5 0x000000c0
#define AR_RTC_PLL_CLKSEL 0x00000300 #define AR_RTC_PLL_CLKSEL 0x00000300
#define AR_RTC_PLL_CLKSEL_S 8 #define AR_RTC_PLL_CLKSEL_S 8
#define AR_RTC_PLL_BYPASS 0x00010000
#define PLL3 0x16188 #define PLL3 0x16188
#define PLL3_DO_MEAS_MASK 0x40000000 #define PLL3_DO_MEAS_MASK 0x40000000
...@@ -1209,7 +1229,8 @@ enum { ...@@ -1209,7 +1229,8 @@ enum {
/* RTC_DERIVED_* - only for AR9100 */ /* 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 0x0000fffe
#define AR_RTC_DERIVED_CLK_PERIOD_S 1 #define AR_RTC_DERIVED_CLK_PERIOD_S 1
...@@ -1688,6 +1709,22 @@ enum { ...@@ -1688,6 +1709,22 @@ enum {
#define AR_BTCOEX_WL_WGHT 0xffff0000 #define AR_BTCOEX_WL_WGHT 0xffff0000
#define AR_BTCOEX_WL_WGHT_S 16 #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_COEX_MODE2 0x817c
#define AR_BT_BCN_MISS_THRESH 0x000000ff #define AR_BT_BCN_MISS_THRESH 0x000000ff
#define AR_BT_BCN_MISS_THRESH_S 0 #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) ...@@ -79,8 +79,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
return "WMI_TX_STATS_CMDID"; return "WMI_TX_STATS_CMDID";
case WMI_RX_STATS_CMDID: case WMI_RX_STATS_CMDID:
return "WMI_RX_STATS_CMDID"; return "WMI_RX_STATS_CMDID";
case WMI_AGGR_LIMIT_CMD: case WMI_BITRATE_MASK_CMDID:
return "WMI_AGGR_LIMIT_CMD"; return "WMI_BITRATE_MASK_CMDID";
} }
return "Bogus"; return "Bogus";
......
...@@ -111,7 +111,7 @@ enum wmi_cmd_id { ...@@ -111,7 +111,7 @@ enum wmi_cmd_id {
WMI_INT_STATS_CMDID, WMI_INT_STATS_CMDID,
WMI_TX_STATS_CMDID, WMI_TX_STATS_CMDID,
WMI_RX_STATS_CMDID, WMI_RX_STATS_CMDID,
WMI_AGGR_LIMIT_CMD = 0x0026, WMI_BITRATE_MASK_CMDID,
}; };
enum wmi_event_id { enum wmi_event_id {
......
...@@ -2180,28 +2180,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) ...@@ -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) static void ath_tx_complete_poll_work(struct work_struct *work)
{ {
struct ath_softc *sc = container_of(work, struct ath_softc, struct ath_softc *sc = container_of(work, struct ath_softc,
...@@ -2396,7 +2374,6 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) ...@@ -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->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) { if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
error = ath_tx_edma_init(sc); error = ath_tx_edma_init(sc);
......
...@@ -448,6 +448,8 @@ struct carl9170_ba_stats { ...@@ -448,6 +448,8 @@ struct carl9170_ba_stats {
struct carl9170_sta_info { struct carl9170_sta_info {
bool ht_sta; bool ht_sta;
bool sleeping;
atomic_t pending_frames;
unsigned int ampdu_max_len; unsigned int ampdu_max_len;
struct carl9170_sta_tid *agg[CARL9170_NUM_TID]; struct carl9170_sta_tid *agg[CARL9170_NUM_TID];
struct carl9170_ba_stats stats[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, ...@@ -1193,6 +1193,8 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw,
struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
unsigned int i; unsigned int i;
atomic_set(&sta_info->pending_frames, 0);
if (sta->ht_cap.ht_supported) { if (sta->ht_cap.ht_supported) {
if (sta->ht_cap.ampdu_density > 6) { if (sta->ht_cap.ampdu_density > 6) {
/* /*
...@@ -1467,99 +1469,17 @@ static void carl9170_op_sta_notify(struct ieee80211_hw *hw, ...@@ -1467,99 +1469,17 @@ static void carl9170_op_sta_notify(struct ieee80211_hw *hw,
enum sta_notify_cmd cmd, enum sta_notify_cmd cmd,
struct ieee80211_sta *sta) struct ieee80211_sta *sta)
{ {
struct ar9170 *ar = hw->priv;
struct carl9170_sta_info *sta_info = (void *) sta->drv_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) { switch (cmd) {
case STA_NOTIFY_SLEEP: case STA_NOTIFY_SLEEP:
/* sta_info->sleeping = true;
* Since the peer is no longer listening, we have to return if (atomic_read(&sta_info->pending_frames))
* as many SKBs as possible back to the mac80211 stack. ieee80211_sta_block_awake(hw, sta, true);
* 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);
break; break;
case STA_NOTIFY_AWAKE: case STA_NOTIFY_AWAKE:
if (!sta->ht_cap.ht_supported) sta_info->sleeping = false;
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();
break; break;
} }
} }
......
...@@ -2281,6 +2281,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, ...@@ -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[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[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[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
save_regs_phy[8] = 0;
} else { } else {
save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); 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, ...@@ -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[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1); 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[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); b43_nphy_rssi_select(dev, 5, type);
...@@ -3845,8 +3848,8 @@ static int b43_nphy_set_channel(struct b43_wldev *dev, ...@@ -3845,8 +3848,8 @@ static int b43_nphy_set_channel(struct b43_wldev *dev,
{ {
struct b43_phy *phy = &dev->phy; struct b43_phy *phy = &dev->phy;
const struct b43_nphy_channeltab_entry_rev2 *tabent_r2; const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL;
const struct b43_nphy_channeltab_entry_rev3 *tabent_r3; const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL;
u8 tmp; u8 tmp;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册