mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 14:12:06 +00:00
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
This commit is contained in:
commit
90864fbc76
@ -158,6 +158,11 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah)
|
||||
txlat = AR5K_REG_MS(usec_reg, AR5K_USEC_TX_LATENCY_5211);
|
||||
rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211);
|
||||
|
||||
/*
|
||||
* Set default Tx frame to Tx data start delay
|
||||
*/
|
||||
txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT;
|
||||
|
||||
/*
|
||||
* 5210 initvals don't include usec settings
|
||||
* so we need to use magic values here for
|
||||
|
@ -21,11 +21,15 @@
|
||||
#include <linux/ath9k_platform.h>
|
||||
#include "ath9k.h"
|
||||
|
||||
const struct platform_device_id ath9k_platform_id_table[] = {
|
||||
static const struct platform_device_id ath9k_platform_id_table[] = {
|
||||
{
|
||||
.name = "ath9k",
|
||||
.driver_data = AR5416_AR9100_DEVID,
|
||||
},
|
||||
{
|
||||
.name = "ar934x_wmac",
|
||||
.driver_data = AR9300_DEVID_AR9340,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
|
@ -899,12 +899,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
|
||||
* check here default level should not modify INI setting.
|
||||
*/
|
||||
if (use_new_ani(ah)) {
|
||||
const struct ani_ofdm_level_entry *entry_ofdm;
|
||||
const struct ani_cck_level_entry *entry_cck;
|
||||
|
||||
entry_ofdm = &ofdm_level_table[ATH9K_ANI_OFDM_DEF_LEVEL];
|
||||
entry_cck = &cck_level_table[ATH9K_ANI_CCK_DEF_LEVEL];
|
||||
|
||||
ah->aniperiod = ATH9K_ANI_PERIOD_NEW;
|
||||
ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW;
|
||||
} else {
|
||||
|
@ -18,13 +18,13 @@
|
||||
#include "hw-ops.h"
|
||||
#include "ar9003_phy.h"
|
||||
|
||||
#define MPASS 3
|
||||
#define MAX_MEASUREMENT 8
|
||||
#define MAX_DIFFERENCE 10
|
||||
#define MAX_MAG_DELTA 11
|
||||
#define MAX_PHS_DELTA 10
|
||||
|
||||
struct coeff {
|
||||
int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS];
|
||||
int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS];
|
||||
int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
|
||||
int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
|
||||
int iqc_coeff[2];
|
||||
};
|
||||
|
||||
@ -185,17 +185,19 @@ static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
|
||||
|
||||
/* Accumulate IQ cal measures for active chains */
|
||||
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
|
||||
ah->totalPowerMeasI[i] +=
|
||||
REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
|
||||
ah->totalPowerMeasQ[i] +=
|
||||
REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
|
||||
ah->totalIqCorrMeas[i] +=
|
||||
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
|
||||
ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
|
||||
"%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
|
||||
ah->cal_samples, i, ah->totalPowerMeasI[i],
|
||||
ah->totalPowerMeasQ[i],
|
||||
ah->totalIqCorrMeas[i]);
|
||||
if (ah->txchainmask & BIT(i)) {
|
||||
ah->totalPowerMeasI[i] +=
|
||||
REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
|
||||
ah->totalPowerMeasQ[i] +=
|
||||
REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
|
||||
ah->totalIqCorrMeas[i] +=
|
||||
(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
|
||||
ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
|
||||
"%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
|
||||
ah->cal_samples, i, ah->totalPowerMeasI[i],
|
||||
ah->totalPowerMeasQ[i],
|
||||
ah->totalIqCorrMeas[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -608,36 +610,48 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg)
|
||||
static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
|
||||
int max_delta)
|
||||
{
|
||||
int diff[MPASS];
|
||||
int mp_max = -64, max_idx = 0;
|
||||
int mp_min = 63, min_idx = 0;
|
||||
int mp_avg = 0, i, outlier_idx = 0;
|
||||
|
||||
diff[0] = abs(mp_coeff[0] - mp_coeff[1]);
|
||||
diff[1] = abs(mp_coeff[1] - mp_coeff[2]);
|
||||
diff[2] = abs(mp_coeff[2] - mp_coeff[0]);
|
||||
/* find min/max mismatch across all calibrated gains */
|
||||
for (i = 0; i < nmeasurement; i++) {
|
||||
mp_avg += mp_coeff[i];
|
||||
if (mp_coeff[i] > mp_max) {
|
||||
mp_max = mp_coeff[i];
|
||||
max_idx = i;
|
||||
} else if (mp_coeff[i] < mp_min) {
|
||||
mp_min = mp_coeff[i];
|
||||
min_idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (diff[0] > MAX_DIFFERENCE &&
|
||||
diff[1] > MAX_DIFFERENCE &&
|
||||
diff[2] > MAX_DIFFERENCE)
|
||||
return false;
|
||||
/* find average (exclude max abs value) */
|
||||
for (i = 0; i < nmeasurement; i++) {
|
||||
if ((abs(mp_coeff[i]) < abs(mp_max)) ||
|
||||
(abs(mp_coeff[i]) < abs(mp_min)))
|
||||
mp_avg += mp_coeff[i];
|
||||
}
|
||||
mp_avg /= (nmeasurement - 1);
|
||||
|
||||
if (diff[0] <= diff[1] && diff[0] <= diff[2])
|
||||
*mp_avg = (mp_coeff[0] + mp_coeff[1]) / 2;
|
||||
else if (diff[1] <= diff[2])
|
||||
*mp_avg = (mp_coeff[1] + mp_coeff[2]) / 2;
|
||||
else
|
||||
*mp_avg = (mp_coeff[2] + mp_coeff[0]) / 2;
|
||||
|
||||
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,
|
||||
u8 num_chains,
|
||||
struct coeff *coeff)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int i, im, nmeasurement;
|
||||
int magnitude, phase;
|
||||
u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
|
||||
|
||||
memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
|
||||
@ -657,37 +671,28 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
|
||||
|
||||
/* Load the average of 2 passes */
|
||||
for (i = 0; i < num_chains; i++) {
|
||||
if (AR_SREV_9485(ah))
|
||||
nmeasurement = REG_READ_FIELD(ah,
|
||||
AR_PHY_TX_IQCAL_STATUS_B0_9485,
|
||||
AR_PHY_CALIBRATED_GAINS_0);
|
||||
else
|
||||
nmeasurement = REG_READ_FIELD(ah,
|
||||
AR_PHY_TX_IQCAL_STATUS_B0,
|
||||
AR_PHY_CALIBRATED_GAINS_0);
|
||||
nmeasurement = REG_READ_FIELD(ah,
|
||||
AR_PHY_TX_IQCAL_STATUS_B0,
|
||||
AR_PHY_CALIBRATED_GAINS_0);
|
||||
|
||||
if (nmeasurement > MAX_MEASUREMENT)
|
||||
nmeasurement = MAX_MEASUREMENT;
|
||||
|
||||
/* detect outlier only if nmeasurement > 1 */
|
||||
if (nmeasurement > 1) {
|
||||
/* Detect magnitude outlier */
|
||||
ar9003_hw_detect_outlier(coeff->mag_coeff[i],
|
||||
nmeasurement, MAX_MAG_DELTA);
|
||||
|
||||
/* Detect phase outlier */
|
||||
ar9003_hw_detect_outlier(coeff->phs_coeff[i],
|
||||
nmeasurement, MAX_PHS_DELTA);
|
||||
}
|
||||
|
||||
for (im = 0; im < nmeasurement; im++) {
|
||||
/*
|
||||
* Determine which 2 passes are closest and compute avg
|
||||
* magnitude
|
||||
*/
|
||||
if (!ar9003_hw_compute_closest_pass_and_avg(coeff->mag_coeff[i][im],
|
||||
&magnitude))
|
||||
goto disable_txiqcal;
|
||||
|
||||
/*
|
||||
* Determine which 2 passes are closest and compute avg
|
||||
* phase
|
||||
*/
|
||||
if (!ar9003_hw_compute_closest_pass_and_avg(coeff->phs_coeff[i][im],
|
||||
&phase))
|
||||
goto disable_txiqcal;
|
||||
|
||||
coeff->iqc_coeff[0] = (magnitude & 0x7f) |
|
||||
((phase & 0x7f) << 7);
|
||||
coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) |
|
||||
((coeff->phs_coeff[i][im] & 0x7f) << 7);
|
||||
|
||||
if ((im % 2) == 0)
|
||||
REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
|
||||
@ -707,141 +712,37 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
|
||||
|
||||
return;
|
||||
|
||||
disable_txiqcal:
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
|
||||
AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
|
||||
AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x0);
|
||||
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n");
|
||||
}
|
||||
|
||||
static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
|
||||
static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
static const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
|
||||
AR_PHY_TX_IQCAL_STATUS_B0,
|
||||
AR_PHY_TX_IQCAL_STATUS_B1,
|
||||
AR_PHY_TX_IQCAL_STATUS_B2,
|
||||
};
|
||||
static const u32 chan_info_tab[] = {
|
||||
AR_PHY_CHAN_INFO_TAB_0,
|
||||
AR_PHY_CHAN_INFO_TAB_1,
|
||||
AR_PHY_CHAN_INFO_TAB_2,
|
||||
};
|
||||
struct coeff coeff;
|
||||
s32 iq_res[6];
|
||||
s32 i, j, ip, im, nmeasurement;
|
||||
u8 nchains = get_streams(common->tx_chainmask);
|
||||
|
||||
for (ip = 0; ip < MPASS; ip++) {
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
|
||||
AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
|
||||
DELPT);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
|
||||
AR_PHY_TX_IQCAL_START_DO_CAL,
|
||||
AR_PHY_TX_IQCAL_START_DO_CAL);
|
||||
|
||||
if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
|
||||
AR_PHY_TX_IQCAL_START_DO_CAL,
|
||||
0, AH_WAIT_TIMEOUT)) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Tx IQ Cal not complete.\n");
|
||||
goto TX_IQ_CAL_FAILED;
|
||||
}
|
||||
|
||||
nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0,
|
||||
AR_PHY_CALIBRATED_GAINS_0);
|
||||
if (nmeasurement > MAX_MEASUREMENT)
|
||||
nmeasurement = MAX_MEASUREMENT;
|
||||
|
||||
for (i = 0; i < nchains; i++) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Doing Tx IQ Cal for chain %d.\n", i);
|
||||
for (im = 0; im < nmeasurement; im++) {
|
||||
if (REG_READ(ah, txiqcal_status[i]) &
|
||||
AR_PHY_TX_IQCAL_STATUS_FAILED) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Tx IQ Cal failed for chain %d.\n", i);
|
||||
goto TX_IQ_CAL_FAILED;
|
||||
}
|
||||
|
||||
for (j = 0; j < 3; j++) {
|
||||
u8 idx = 2 * j,
|
||||
offset = 4 * (3 * im + j);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
|
||||
AR_PHY_CHAN_INFO_TAB_S2_READ,
|
||||
0);
|
||||
|
||||
/* 32 bits */
|
||||
iq_res[idx] = REG_READ(ah,
|
||||
chan_info_tab[i] +
|
||||
offset);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
|
||||
AR_PHY_CHAN_INFO_TAB_S2_READ,
|
||||
1);
|
||||
|
||||
/* 16 bits */
|
||||
iq_res[idx+1] = 0xffff & REG_READ(ah,
|
||||
chan_info_tab[i] +
|
||||
offset);
|
||||
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
|
||||
idx, iq_res[idx], idx+1, iq_res[idx+1]);
|
||||
}
|
||||
|
||||
if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
|
||||
coeff.iqc_coeff)) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Failed in calculation of IQ correction.\n");
|
||||
goto TX_IQ_CAL_FAILED;
|
||||
}
|
||||
coeff.mag_coeff[i][im][ip] =
|
||||
coeff.iqc_coeff[0] & 0x7f;
|
||||
coeff.phs_coeff[i][im][ip] =
|
||||
(coeff.iqc_coeff[0] >> 7) & 0x7f;
|
||||
|
||||
if (coeff.mag_coeff[i][im][ip] > 63)
|
||||
coeff.mag_coeff[i][im][ip] -= 128;
|
||||
if (coeff.phs_coeff[i][im][ip] > 63)
|
||||
coeff.phs_coeff[i][im][ip] -= 128;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ar9003_hw_tx_iqcal_load_avg_2_passes(ah, nchains, &coeff);
|
||||
|
||||
return;
|
||||
|
||||
TX_IQ_CAL_FAILED:
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
|
||||
}
|
||||
|
||||
static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
|
||||
{
|
||||
u8 tx_gain_forced;
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1_9485,
|
||||
AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT);
|
||||
tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
|
||||
AR_PHY_TXGAIN_FORCE);
|
||||
if (tx_gain_forced)
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
|
||||
AR_PHY_TXGAIN_FORCE, 0);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START_9485,
|
||||
AR_PHY_TX_IQCAL_START_DO_CAL_9485, 1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
|
||||
AR_PHY_TX_IQCAL_START_DO_CAL, 1);
|
||||
|
||||
if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
|
||||
AR_PHY_TX_IQCAL_START_DO_CAL, 0,
|
||||
AH_WAIT_TIMEOUT)) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Tx IQ Cal is not completed.\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
|
||||
AR_PHY_TX_IQCAL_STATUS_B0_9485,
|
||||
AR_PHY_TX_IQCAL_STATUS_B0,
|
||||
AR_PHY_TX_IQCAL_STATUS_B1,
|
||||
AR_PHY_TX_IQCAL_STATUS_B2,
|
||||
};
|
||||
@ -853,7 +754,7 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
|
||||
struct coeff coeff;
|
||||
s32 iq_res[6];
|
||||
u8 num_chains = 0;
|
||||
int i, ip, im, j;
|
||||
int i, im, j;
|
||||
int nmeasurement;
|
||||
|
||||
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
|
||||
@ -861,71 +762,69 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
|
||||
num_chains++;
|
||||
}
|
||||
|
||||
for (ip = 0; ip < MPASS; ip++) {
|
||||
for (i = 0; i < num_chains; i++) {
|
||||
nmeasurement = REG_READ_FIELD(ah,
|
||||
AR_PHY_TX_IQCAL_STATUS_B0_9485,
|
||||
AR_PHY_CALIBRATED_GAINS_0);
|
||||
if (nmeasurement > MAX_MEASUREMENT)
|
||||
nmeasurement = MAX_MEASUREMENT;
|
||||
for (i = 0; i < num_chains; i++) {
|
||||
nmeasurement = REG_READ_FIELD(ah,
|
||||
AR_PHY_TX_IQCAL_STATUS_B0,
|
||||
AR_PHY_CALIBRATED_GAINS_0);
|
||||
if (nmeasurement > MAX_MEASUREMENT)
|
||||
nmeasurement = MAX_MEASUREMENT;
|
||||
|
||||
for (im = 0; im < nmeasurement; im++) {
|
||||
for (im = 0; im < nmeasurement; im++) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Doing Tx IQ Cal for chain %d.\n", i);
|
||||
|
||||
if (REG_READ(ah, txiqcal_status[i]) &
|
||||
AR_PHY_TX_IQCAL_STATUS_FAILED) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Doing Tx IQ Cal for chain %d.\n", i);
|
||||
|
||||
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_iqcal_fail;
|
||||
}
|
||||
goto tx_iqcal_fail;
|
||||
}
|
||||
|
||||
for (j = 0; j < 3; j++) {
|
||||
u32 idx = 2 * j, offset = 4 * (3 * im + j);
|
||||
for (j = 0; j < 3; 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_TAB_S2_READ,
|
||||
0);
|
||||
|
||||
/* 32 bits */
|
||||
iq_res[idx] = REG_READ(ah,
|
||||
chan_info_tab[i] +
|
||||
offset);
|
||||
/* 32 bits */
|
||||
iq_res[idx] = REG_READ(ah,
|
||||
chan_info_tab[i] +
|
||||
offset);
|
||||
|
||||
REG_RMW_FIELD(ah,
|
||||
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);
|
||||
/* 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_iqcal_fail;
|
||||
}
|
||||
|
||||
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;
|
||||
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_iqcal_fail;
|
||||
}
|
||||
|
||||
coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f;
|
||||
coeff.phs_coeff[i][im] =
|
||||
(coeff.iqc_coeff[0] >> 7) & 0x7f;
|
||||
|
||||
if (coeff.mag_coeff[i][im] > 63)
|
||||
coeff.mag_coeff[i][im] -= 128;
|
||||
if (coeff.phs_coeff[i][im] > 63)
|
||||
coeff.phs_coeff[i][im] -= 128;
|
||||
}
|
||||
}
|
||||
ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff);
|
||||
@ -940,31 +839,37 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_hw_capabilities *pCap = &ah->caps;
|
||||
int val;
|
||||
bool txiqcal_done = false;
|
||||
|
||||
val = REG_READ(ah, AR_ENT_OTP);
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val);
|
||||
|
||||
if (AR_SREV_9485(ah))
|
||||
ar9003_hw_set_chain_masks(ah, 0x1, 0x1);
|
||||
else if (val & AR_ENT_OTP_CHAIN2_DISABLE)
|
||||
/* Configure rx/tx chains before running AGC/TxiQ cals */
|
||||
if (val & AR_ENT_OTP_CHAIN2_DISABLE)
|
||||
ar9003_hw_set_chain_masks(ah, 0x3, 0x3);
|
||||
else
|
||||
/*
|
||||
* 0x7 = 0b111 , AR9003 needs to be configured for 3-chain
|
||||
* mode before running AGC/TxIQ cals
|
||||
*/
|
||||
ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
|
||||
ar9003_hw_set_chain_masks(ah, pCap->rx_chainmask,
|
||||
pCap->tx_chainmask);
|
||||
|
||||
/* Do Tx IQ Calibration */
|
||||
if (AR_SREV_9485(ah))
|
||||
ar9003_hw_tx_iq_cal_run(ah);
|
||||
else
|
||||
ar9003_hw_tx_iq_cal(ah);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
|
||||
AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
|
||||
DELPT);
|
||||
|
||||
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
|
||||
udelay(5);
|
||||
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
|
||||
/*
|
||||
* For AR9485 or later chips, TxIQ cal runs as part of
|
||||
* AGC calibration
|
||||
*/
|
||||
if (AR_SREV_9485_OR_LATER(ah))
|
||||
txiqcal_done = true;
|
||||
else {
|
||||
txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
|
||||
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
|
||||
udelay(5);
|
||||
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
|
||||
}
|
||||
|
||||
/* Calibrate the AGC */
|
||||
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
|
||||
@ -979,7 +884,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AR_SREV_9485(ah))
|
||||
if (txiqcal_done)
|
||||
ar9003_hw_tx_iq_cal_post_proc(ah);
|
||||
|
||||
/* Revert chainmasks to their original values before NF cal */
|
||||
|
@ -3217,7 +3217,6 @@ static int ar9300_compress_decision(struct ath_hw *ah,
|
||||
u8 *word, int length, int mdata_size)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u8 *dptr;
|
||||
const struct ar9300_eeprom *eep = NULL;
|
||||
|
||||
switch (code) {
|
||||
@ -3235,7 +3234,6 @@ static int ar9300_compress_decision(struct ath_hw *ah,
|
||||
break;
|
||||
case _CompressBlock:
|
||||
if (reference == 0) {
|
||||
dptr = mptr;
|
||||
} else {
|
||||
eep = ar9003_eeprom_struct_find_by_id(reference);
|
||||
if (eep == NULL) {
|
||||
@ -3448,9 +3446,13 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
|
||||
REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
|
||||
else {
|
||||
REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
|
||||
REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB,
|
||||
bias >> 2);
|
||||
REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1);
|
||||
if (!AR_SREV_9340(ah)) {
|
||||
REG_RMW_FIELD(ah, AR_CH0_THERM,
|
||||
AR_CH0_THERM_XPABIASLVL_MSB,
|
||||
bias >> 2);
|
||||
REG_RMW_FIELD(ah, AR_CH0_THERM,
|
||||
AR_CH0_THERM_XPASHORT2GND, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3497,23 +3499,28 @@ static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
|
||||
|
||||
static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
|
||||
{
|
||||
int chain;
|
||||
static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
|
||||
AR_PHY_SWITCH_CHAIN_0,
|
||||
AR_PHY_SWITCH_CHAIN_1,
|
||||
AR_PHY_SWITCH_CHAIN_2,
|
||||
};
|
||||
|
||||
u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
|
||||
|
||||
value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
|
||||
|
||||
value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
|
||||
|
||||
if (!AR_SREV_9485(ah)) {
|
||||
value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL,
|
||||
value);
|
||||
|
||||
value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL,
|
||||
value);
|
||||
for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
|
||||
if ((ah->rxchainmask & BIT(chain)) ||
|
||||
(ah->txchainmask & BIT(chain))) {
|
||||
value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
|
||||
is2ghz);
|
||||
REG_RMW_FIELD(ah, switch_chain_reg[chain],
|
||||
AR_SWITCH_TABLE_ALL, value);
|
||||
}
|
||||
}
|
||||
|
||||
if (AR_SREV_9485(ah)) {
|
||||
@ -3634,13 +3641,16 @@ static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
|
||||
/* Test value. if 0 then attenuation is unused. Don't load anything. */
|
||||
for (i = 0; i < 3; i++) {
|
||||
value = ar9003_hw_atten_chain_get(ah, i, chan);
|
||||
REG_RMW_FIELD(ah, ext_atten_reg[i],
|
||||
AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
|
||||
if (ah->txchainmask & BIT(i)) {
|
||||
value = ar9003_hw_atten_chain_get(ah, i, chan);
|
||||
REG_RMW_FIELD(ah, ext_atten_reg[i],
|
||||
AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
|
||||
|
||||
value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
|
||||
REG_RMW_FIELD(ah, ext_atten_reg[i],
|
||||
AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value);
|
||||
value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
|
||||
REG_RMW_FIELD(ah, ext_atten_reg[i],
|
||||
AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
|
||||
value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3749,8 +3759,9 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
|
||||
ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
|
||||
ar9003_hw_drive_strength_apply(ah);
|
||||
ar9003_hw_atten_apply(ah, chan);
|
||||
ar9003_hw_internal_regulator_apply(ah);
|
||||
if (AR_SREV_9485(ah))
|
||||
if (!AR_SREV_9340(ah))
|
||||
ar9003_hw_internal_regulator_apply(ah);
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
|
||||
ar9003_hw_apply_tuning_caps(ah);
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "ar9003_mac.h"
|
||||
#include "ar9003_2p2_initvals.h"
|
||||
#include "ar9485_initvals.h"
|
||||
#include "ar9340_initvals.h"
|
||||
|
||||
/* General hardware code for the AR9003 hadware family */
|
||||
|
||||
@ -28,7 +29,63 @@
|
||||
*/
|
||||
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9485_11(ah)) {
|
||||
if (AR_SREV_9340(ah)) {
|
||||
/* mac */
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
|
||||
ar9340_1p0_mac_core,
|
||||
ARRAY_SIZE(ar9340_1p0_mac_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
|
||||
ar9340_1p0_mac_postamble,
|
||||
ARRAY_SIZE(ar9340_1p0_mac_postamble), 5);
|
||||
|
||||
/* bb */
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
|
||||
ar9340_1p0_baseband_core,
|
||||
ARRAY_SIZE(ar9340_1p0_baseband_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
|
||||
ar9340_1p0_baseband_postamble,
|
||||
ARRAY_SIZE(ar9340_1p0_baseband_postamble), 5);
|
||||
|
||||
/* radio */
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
|
||||
ar9340_1p0_radio_core,
|
||||
ARRAY_SIZE(ar9340_1p0_radio_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
|
||||
ar9340_1p0_radio_postamble,
|
||||
ARRAY_SIZE(ar9340_1p0_radio_postamble), 5);
|
||||
|
||||
/* soc */
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
|
||||
ar9340_1p0_soc_preamble,
|
||||
ARRAY_SIZE(ar9340_1p0_soc_preamble), 2);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
|
||||
ar9340_1p0_soc_postamble,
|
||||
ARRAY_SIZE(ar9340_1p0_soc_postamble), 5);
|
||||
|
||||
/* rx/tx gain */
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9340Common_wo_xlna_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
|
||||
5);
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_high_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
ar9340Modes_fast_clock_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_fast_clock_1p0),
|
||||
3);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional_40M,
|
||||
ar9340_1p0_radio_core_40M,
|
||||
ARRAY_SIZE(ar9340_1p0_radio_core_40M),
|
||||
2);
|
||||
} else if (AR_SREV_9485_11(ah)) {
|
||||
/* mac */
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
|
||||
@ -163,7 +220,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
|
||||
switch (ar9003_hw_get_tx_gain_idx(ah)) {
|
||||
case 0:
|
||||
default:
|
||||
if (AR_SREV_9485_11(ah))
|
||||
if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9485_modes_lowest_ob_db_tx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
|
||||
@ -175,7 +237,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
|
||||
5);
|
||||
break;
|
||||
case 1:
|
||||
if (AR_SREV_9485_11(ah))
|
||||
if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9485Modes_high_ob_db_tx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
|
||||
@ -187,7 +254,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
|
||||
5);
|
||||
break;
|
||||
case 2:
|
||||
if (AR_SREV_9485_11(ah))
|
||||
if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9485Modes_low_ob_db_tx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
|
||||
@ -199,7 +271,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
|
||||
5);
|
||||
break;
|
||||
case 3:
|
||||
if (AR_SREV_9485_11(ah))
|
||||
if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9485Modes_high_power_tx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
|
||||
@ -218,7 +295,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
|
||||
switch (ar9003_hw_get_rx_gain_idx(ah)) {
|
||||
case 0:
|
||||
default:
|
||||
if (AR_SREV_9485_11(ah))
|
||||
if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9340Common_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Common_rx_gain_table_1p0),
|
||||
2);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9485Common_wo_xlna_rx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
|
||||
@ -230,7 +312,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
|
||||
2);
|
||||
break;
|
||||
case 1:
|
||||
if (AR_SREV_9485_11(ah))
|
||||
if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9340Common_wo_xlna_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
|
||||
2);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9485Common_wo_xlna_rx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
|
||||
|
@ -86,14 +86,31 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
channelSel = (freq * 4) / 120;
|
||||
chan_frac = (((freq * 4) % 120) * 0x20000) / 120;
|
||||
channelSel = (channelSel << 17) | chan_frac;
|
||||
} else if (AR_SREV_9340(ah)) {
|
||||
if (ah->is_clk_25mhz) {
|
||||
u32 chan_frac;
|
||||
|
||||
channelSel = (freq * 2) / 75;
|
||||
chan_frac = (((freq * 2) % 75) * 0x20000) / 75;
|
||||
channelSel = (channelSel << 17) | chan_frac;
|
||||
} else
|
||||
channelSel = CHANSEL_2G(freq) >> 1;
|
||||
} else
|
||||
channelSel = CHANSEL_2G(freq);
|
||||
/* Set to 2G mode */
|
||||
bMode = 1;
|
||||
} else {
|
||||
channelSel = CHANSEL_5G(freq);
|
||||
/* Doubler is ON, so, divide channelSel by 2. */
|
||||
channelSel >>= 1;
|
||||
if (AR_SREV_9340(ah) && ah->is_clk_25mhz) {
|
||||
u32 chan_frac;
|
||||
|
||||
channelSel = (freq * 2) / 75;
|
||||
chan_frac = ((freq % 75) * 0x20000) / 75;
|
||||
channelSel = (channelSel << 17) | chan_frac;
|
||||
} else {
|
||||
channelSel = CHANSEL_5G(freq);
|
||||
/* Doubler is ON, so, divide channelSel by 2. */
|
||||
channelSel >>= 1;
|
||||
}
|
||||
/* Set to 5G mode */
|
||||
bMode = 0;
|
||||
}
|
||||
@ -151,7 +168,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
|
||||
* is out-of-band and can be ignored.
|
||||
*/
|
||||
|
||||
if (AR_SREV_9485(ah)) {
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) {
|
||||
spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah,
|
||||
IS_CHAN_2GHZ(chan));
|
||||
if (spur_fbin_ptr[0] == 0) /* No spur */
|
||||
@ -176,7 +193,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
|
||||
|
||||
for (i = 0; i < max_spur_cnts; i++) {
|
||||
negative = 0;
|
||||
if (AR_SREV_9485(ah))
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
|
||||
cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i],
|
||||
IS_CHAN_2GHZ(chan)) - synth_freq;
|
||||
else
|
||||
@ -599,29 +616,25 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
unsigned int regWrites = 0, i;
|
||||
struct ieee80211_channel *channel = chan->chan;
|
||||
u32 modesIndex, freqIndex;
|
||||
u32 modesIndex;
|
||||
|
||||
switch (chan->chanmode) {
|
||||
case CHANNEL_A:
|
||||
case CHANNEL_A_HT20:
|
||||
modesIndex = 1;
|
||||
freqIndex = 1;
|
||||
break;
|
||||
case CHANNEL_A_HT40PLUS:
|
||||
case CHANNEL_A_HT40MINUS:
|
||||
modesIndex = 2;
|
||||
freqIndex = 1;
|
||||
break;
|
||||
case CHANNEL_G:
|
||||
case CHANNEL_G_HT20:
|
||||
case CHANNEL_B:
|
||||
modesIndex = 4;
|
||||
freqIndex = 2;
|
||||
break;
|
||||
case CHANNEL_G_HT40PLUS:
|
||||
case CHANNEL_G_HT40MINUS:
|
||||
modesIndex = 3;
|
||||
freqIndex = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -646,6 +659,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
|
||||
REG_WRITE_ARRAY(&ah->iniModesAdditional,
|
||||
modesIndex, regWrites);
|
||||
|
||||
if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
|
||||
REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites);
|
||||
|
||||
ar9003_hw_override_ini(ah);
|
||||
ar9003_hw_set_channel_regs(ah, chan);
|
||||
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
|
||||
|
@ -548,15 +548,12 @@
|
||||
|
||||
#define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300)
|
||||
|
||||
#define AR_PHY_TX_IQCAL_START_9485 (AR_SM_BASE + 0x3c4)
|
||||
#define AR_PHY_TX_IQCAL_START_DO_CAL_9485 0x80000000
|
||||
#define AR_PHY_TX_IQCAL_START_DO_CAL_9485_S 31
|
||||
#define AR_PHY_TX_IQCAL_CONTROL_1_9485 (AR_SM_BASE + 0x3c8)
|
||||
#define AR_PHY_TX_IQCAL_STATUS_B0_9485 (AR_SM_BASE + 0x3f0)
|
||||
|
||||
#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448)
|
||||
#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440)
|
||||
#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c)
|
||||
#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + AR_SREV_9485(ah) ? \
|
||||
0x3c8 : 0x448)
|
||||
#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + AR_SREV_9485(ah) ? \
|
||||
0x3c4 : 0x440)
|
||||
#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + AR_SREV_9485(ah) ? \
|
||||
0x3f0 : 0x48c)
|
||||
#define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \
|
||||
(AR_SREV_9485(ah) ? \
|
||||
0x3d0 : 0x450) + ((_i) << 2))
|
||||
@ -588,7 +585,7 @@
|
||||
#define AR_PHY_65NM_CH0_BIAS2 0x160c4
|
||||
#define AR_PHY_65NM_CH0_BIAS4 0x160cc
|
||||
#define AR_PHY_65NM_CH0_RXTX4 0x1610c
|
||||
#define AR_PHY_65NM_CH0_THERM (AR_SREV_9485(ah) ? 0x1628c : 0x16290)
|
||||
#define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 : 0x1628c)
|
||||
|
||||
#define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000
|
||||
#define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
|
||||
@ -758,10 +755,10 @@
|
||||
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000
|
||||
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24
|
||||
#define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004
|
||||
#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000
|
||||
#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18
|
||||
#define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001
|
||||
#define AR_PHY_TX_IQCAL_START_DO_CAL_S 0
|
||||
#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000
|
||||
#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18
|
||||
#define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001
|
||||
#define AR_PHY_TX_IQCAL_START_DO_CAL_S 0
|
||||
|
||||
#define AR_PHY_TX_IQCAL_STATUS_FAILED 0x00000001
|
||||
#define AR_PHY_CALIBRATED_GAINS_0 0x3e
|
||||
|
1525
drivers/net/wireless/ath/ath9k/ar9340_initvals.h
Normal file
1525
drivers/net/wireless/ath/ath9k/ar9340_initvals.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -423,6 +423,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status);
|
||||
#define ATH_PAPRD_TIMEOUT 100 /* msecs */
|
||||
|
||||
void ath_hw_check(struct work_struct *work);
|
||||
void ath_hw_pll_work(struct work_struct *work);
|
||||
void ath_paprd_calibrate(struct work_struct *work);
|
||||
void ath_ani_calibrate(unsigned long data);
|
||||
|
||||
@ -453,6 +454,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc);
|
||||
|
||||
#define ATH_LED_PIN_DEF 1
|
||||
#define ATH_LED_PIN_9287 8
|
||||
#define ATH_LED_PIN_9300 10
|
||||
#define ATH_LED_PIN_9485 6
|
||||
|
||||
#ifdef CONFIG_MAC80211_LEDS
|
||||
|
@ -781,12 +781,6 @@ void ath_set_beacon(struct ath_softc *sc)
|
||||
break;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
ath_beacon_config_sta(sc, cur_conf);
|
||||
/*
|
||||
* Request a re-configuration of Beacon related timers
|
||||
* on the receipt of the first Beacon frame (i.e.,
|
||||
* after time sync with the AP).
|
||||
*/
|
||||
sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
|
||||
break;
|
||||
default:
|
||||
ath_dbg(common, ATH_DBG_CONFIG,
|
||||
|
@ -51,6 +51,10 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
|
||||
.bt_hold_rx_clear = true,
|
||||
};
|
||||
u32 i;
|
||||
bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity;
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah))
|
||||
rxclear_polarity = !ath_bt_config.bt_rxclear_polarity;
|
||||
|
||||
btcoex_hw->bt_coex_mode =
|
||||
(btcoex_hw->bt_coex_mode & AR_BT_QCU_THRESH) |
|
||||
@ -59,7 +63,7 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
|
||||
SM(ath_bt_config.bt_txframe_extend, AR_BT_TX_FRAME_EXTEND) |
|
||||
SM(ath_bt_config.bt_mode, AR_BT_MODE) |
|
||||
SM(ath_bt_config.bt_quiet_collision, AR_BT_QUIET) |
|
||||
SM(ath_bt_config.bt_rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) |
|
||||
SM(rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) |
|
||||
SM(ath_bt_config.bt_priority_time, AR_BT_PRIORITY_TIME) |
|
||||
SM(ath_bt_config.bt_first_slot_time, AR_BT_FIRST_SLOT_TIME) |
|
||||
SM(qnum, AR_BT_QCU_THRESH);
|
||||
@ -142,6 +146,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight);
|
||||
|
||||
|
||||
static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
|
||||
@ -152,9 +157,22 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
|
||||
* enable coex 3-wire
|
||||
*/
|
||||
REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_hw->bt_coex_mode);
|
||||
REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights);
|
||||
REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2);
|
||||
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, ah->bt_coex_wlan_weight[0]);
|
||||
REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, ah->bt_coex_wlan_weight[1]);
|
||||
REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, ah->bt_coex_bt_weight[0]);
|
||||
REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, ah->bt_coex_bt_weight[1]);
|
||||
REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, ah->bt_coex_bt_weight[2]);
|
||||
REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, ah->bt_coex_bt_weight[3]);
|
||||
|
||||
} else
|
||||
REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights);
|
||||
|
||||
|
||||
|
||||
if (AR_SREV_9271(ah)) {
|
||||
val = REG_READ(ah, 0x50040);
|
||||
val &= 0xFFFFFEFF;
|
||||
@ -202,10 +220,86 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
|
||||
|
||||
if (btcoex_hw->scheme == ATH_BTCOEX_CFG_3WIRE) {
|
||||
REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE);
|
||||
REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0);
|
||||
REG_WRITE(ah, AR_BT_COEX_MODE2, 0);
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, 0);
|
||||
REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, 0);
|
||||
REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, 0);
|
||||
REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, 0);
|
||||
REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, 0);
|
||||
REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, 0);
|
||||
} else
|
||||
REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0);
|
||||
|
||||
}
|
||||
|
||||
ah->btcoex_hw.enabled = false;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_btcoex_disable);
|
||||
|
||||
static void ar9003_btcoex_bt_stomp(struct ath_hw *ah,
|
||||
enum ath_stomp_type stomp_type)
|
||||
{
|
||||
ah->bt_coex_bt_weight[0] = AR9300_BT_WGHT;
|
||||
ah->bt_coex_bt_weight[1] = AR9300_BT_WGHT;
|
||||
ah->bt_coex_bt_weight[2] = AR9300_BT_WGHT;
|
||||
ah->bt_coex_bt_weight[3] = AR9300_BT_WGHT;
|
||||
|
||||
|
||||
switch (stomp_type) {
|
||||
case ATH_BTCOEX_STOMP_ALL:
|
||||
ah->bt_coex_wlan_weight[0] = AR9300_STOMP_ALL_WLAN_WGHT0;
|
||||
ah->bt_coex_wlan_weight[1] = AR9300_STOMP_ALL_WLAN_WGHT1;
|
||||
break;
|
||||
case ATH_BTCOEX_STOMP_LOW:
|
||||
ah->bt_coex_wlan_weight[0] = AR9300_STOMP_LOW_WLAN_WGHT0;
|
||||
ah->bt_coex_wlan_weight[1] = AR9300_STOMP_LOW_WLAN_WGHT1;
|
||||
break;
|
||||
case ATH_BTCOEX_STOMP_NONE:
|
||||
ah->bt_coex_wlan_weight[0] = AR9300_STOMP_NONE_WLAN_WGHT0;
|
||||
ah->bt_coex_wlan_weight[1] = AR9300_STOMP_NONE_WLAN_WGHT1;
|
||||
break;
|
||||
|
||||
default:
|
||||
ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
|
||||
"Invalid Stomptype\n");
|
||||
break;
|
||||
}
|
||||
|
||||
ath9k_hw_btcoex_enable(ah);
|
||||
}
|
||||
|
||||
/*
|
||||
* Configures appropriate weight based on stomp type.
|
||||
*/
|
||||
void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
|
||||
enum ath_stomp_type stomp_type)
|
||||
{
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
ar9003_btcoex_bt_stomp(ah, stomp_type);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (stomp_type) {
|
||||
case ATH_BTCOEX_STOMP_ALL:
|
||||
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
|
||||
AR_STOMP_ALL_WLAN_WGHT);
|
||||
break;
|
||||
case ATH_BTCOEX_STOMP_LOW:
|
||||
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
|
||||
AR_STOMP_LOW_WLAN_WGHT);
|
||||
break;
|
||||
case ATH_BTCOEX_STOMP_NONE:
|
||||
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
|
||||
AR_STOMP_NONE_WLAN_WGHT);
|
||||
break;
|
||||
default:
|
||||
ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
|
||||
"Invalid Stomptype\n");
|
||||
break;
|
||||
}
|
||||
|
||||
ath9k_hw_btcoex_enable(ah);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_btcoex_bt_stomp);
|
||||
|
@ -19,9 +19,13 @@
|
||||
|
||||
#include "hw.h"
|
||||
|
||||
#define ATH_WLANACTIVE_GPIO 5
|
||||
#define ATH_BTACTIVE_GPIO 6
|
||||
#define ATH_BTPRIORITY_GPIO 7
|
||||
#define ATH_WLANACTIVE_GPIO_9280 5
|
||||
#define ATH_BTACTIVE_GPIO_9280 6
|
||||
#define ATH_BTPRIORITY_GPIO_9285 7
|
||||
|
||||
#define ATH_WLANACTIVE_GPIO_9300 5
|
||||
#define ATH_BTACTIVE_GPIO_9300 4
|
||||
#define ATH_BTPRIORITY_GPIO_9300 8
|
||||
|
||||
#define ATH_BTCOEX_DEF_BT_PERIOD 45
|
||||
#define ATH_BTCOEX_DEF_DUTY_CYCLE 55
|
||||
@ -32,6 +36,14 @@
|
||||
#define ATH_BT_CNT_THRESHOLD 3
|
||||
#define ATH_BT_CNT_SCAN_THRESHOLD 15
|
||||
|
||||
/* Defines the BT AR_BT_COEX_WGHT used */
|
||||
enum ath_stomp_type {
|
||||
ATH_BTCOEX_NO_STOMP,
|
||||
ATH_BTCOEX_STOMP_ALL,
|
||||
ATH_BTCOEX_STOMP_LOW,
|
||||
ATH_BTCOEX_STOMP_NONE
|
||||
};
|
||||
|
||||
enum ath_btcoex_scheme {
|
||||
ATH_BTCOEX_CFG_NONE,
|
||||
ATH_BTCOEX_CFG_2WIRE,
|
||||
@ -57,5 +69,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
|
||||
u32 wlan_weight);
|
||||
void ath9k_hw_btcoex_enable(struct ath_hw *ah);
|
||||
void ath9k_hw_btcoex_disable(struct ath_hw *ah);
|
||||
void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
|
||||
enum ath_stomp_type stomp_type);
|
||||
|
||||
#endif
|
||||
|
@ -158,37 +158,6 @@ int ath9k_cmn_count_streams(unsigned int chainmask, int max)
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_cmn_count_streams);
|
||||
|
||||
/*
|
||||
* Configures appropriate weight based on stomp type.
|
||||
*/
|
||||
void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common,
|
||||
enum ath_stomp_type stomp_type)
|
||||
{
|
||||
struct ath_hw *ah = common->ah;
|
||||
|
||||
switch (stomp_type) {
|
||||
case ATH_BTCOEX_STOMP_ALL:
|
||||
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
|
||||
AR_STOMP_ALL_WLAN_WGHT);
|
||||
break;
|
||||
case ATH_BTCOEX_STOMP_LOW:
|
||||
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
|
||||
AR_STOMP_LOW_WLAN_WGHT);
|
||||
break;
|
||||
case ATH_BTCOEX_STOMP_NONE:
|
||||
ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
|
||||
AR_STOMP_NONE_WLAN_WGHT);
|
||||
break;
|
||||
default:
|
||||
ath_dbg(common, ATH_DBG_BTCOEX,
|
||||
"Invalid Stomptype\n");
|
||||
break;
|
||||
}
|
||||
|
||||
ath9k_hw_btcoex_enable(ah);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_cmn_btcoex_bt_stomp);
|
||||
|
||||
void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
|
||||
u16 new_txpow, u16 *txpower)
|
||||
{
|
||||
|
@ -50,14 +50,6 @@
|
||||
#define ATH_EP_RND(x, mul) \
|
||||
((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
|
||||
|
||||
/* Defines the BT AR_BT_COEX_WGHT used */
|
||||
enum ath_stomp_type {
|
||||
ATH_BTCOEX_NO_STOMP,
|
||||
ATH_BTCOEX_STOMP_ALL,
|
||||
ATH_BTCOEX_STOMP_LOW,
|
||||
ATH_BTCOEX_STOMP_NONE
|
||||
};
|
||||
|
||||
int ath9k_cmn_padpos(__le16 frame_control);
|
||||
int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
|
||||
void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
|
||||
|
@ -326,6 +326,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
|
||||
sc->debug.stats.istats.dtimsync++;
|
||||
if (status & ATH9K_INT_DTIM)
|
||||
sc->debug.stats.istats.dtim++;
|
||||
if (status & ATH9K_INT_TSFOOR)
|
||||
sc->debug.stats.istats.tsfoor++;
|
||||
}
|
||||
|
||||
static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
|
||||
@ -379,9 +381,12 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
|
||||
"%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "TSFOOR", sc->debug.stats.istats.tsfoor);
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
|
||||
|
||||
|
||||
if (len > sizeof(buf))
|
||||
len = sizeof(buf);
|
||||
|
||||
|
@ -54,6 +54,9 @@ struct ath_buf;
|
||||
* @dtimsync: DTIM sync lossage
|
||||
* @dtim: RX Beacon with DTIM
|
||||
* @bb_watchdog: Baseband watchdog
|
||||
* @tsfoor: TSF out of range, indicates that the corrected TSF received
|
||||
* from a beacon differs from the PCU's internal TSF by more than a
|
||||
* (programmable) threshold
|
||||
*/
|
||||
struct ath_interrupt_stats {
|
||||
u32 total;
|
||||
@ -78,6 +81,7 @@ struct ath_interrupt_stats {
|
||||
u32 dtimsync;
|
||||
u32 dtim;
|
||||
u32 bb_watchdog;
|
||||
u32 tsfoor;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -319,10 +319,9 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
|
||||
u16 numXpdGain, xpdMask;
|
||||
u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0};
|
||||
u32 reg32, regOffset, regChainOffset, regval;
|
||||
int16_t modalIdx, diff = 0;
|
||||
int16_t diff = 0;
|
||||
struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
|
||||
|
||||
modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
|
||||
xpdMask = pEepData->modalHeader.xpdGain;
|
||||
|
||||
if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
|
||||
|
@ -231,6 +231,10 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
|
||||
integer = swab32(pModal->antCtrlChain[i]);
|
||||
pModal->antCtrlChain[i] = integer;
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
word = swab16(pModal->xpaBiasLvlFreq[i]);
|
||||
pModal->xpaBiasLvlFreq[i] = word;
|
||||
}
|
||||
|
||||
for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
|
||||
word = swab16(pModal->spurChans[i].spurChan);
|
||||
|
@ -46,6 +46,8 @@ void ath_init_leds(struct ath_softc *sc)
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_9287;
|
||||
else if (AR_SREV_9485(sc->sc_ah))
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_9485;
|
||||
else if (AR_SREV_9300(sc->sc_ah))
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_9300;
|
||||
else
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
|
||||
}
|
||||
@ -138,10 +140,10 @@ static void ath_detect_bt_priority(struct ath_softc *sc)
|
||||
|
||||
static void ath9k_gen_timer_start(struct ath_hw *ah,
|
||||
struct ath_gen_timer *timer,
|
||||
u32 timer_next,
|
||||
u32 trig_timeout,
|
||||
u32 timer_period)
|
||||
{
|
||||
ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
|
||||
ath9k_hw_gen_timer_start(ah, timer, trig_timeout, timer_period);
|
||||
|
||||
if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
@ -174,17 +176,17 @@ static void ath_btcoex_period_timer(unsigned long data)
|
||||
struct ath_softc *sc = (struct ath_softc *) data;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_btcoex *btcoex = &sc->btcoex;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 timer_period;
|
||||
bool is_btscan;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath_detect_bt_priority(sc);
|
||||
|
||||
is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
|
||||
|
||||
spin_lock_bh(&btcoex->btcoex_lock);
|
||||
|
||||
ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL :
|
||||
ath9k_hw_btcoex_bt_stomp(ah, is_btscan ? ATH_BTCOEX_STOMP_ALL :
|
||||
btcoex->bt_stomp_type);
|
||||
|
||||
spin_unlock_bh(&btcoex->btcoex_lock);
|
||||
@ -195,11 +197,12 @@ static void ath_btcoex_period_timer(unsigned long data)
|
||||
|
||||
timer_period = is_btscan ? btcoex->btscan_no_stomp :
|
||||
btcoex->btcoex_no_stomp;
|
||||
ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, 0,
|
||||
ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, timer_period,
|
||||
timer_period * 10);
|
||||
btcoex->hw_timer_enabled = true;
|
||||
}
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
mod_timer(&btcoex->period_timer, jiffies +
|
||||
msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
|
||||
}
|
||||
@ -219,14 +222,16 @@ static void ath_btcoex_no_stomp_timer(void *arg)
|
||||
ath_dbg(common, ATH_DBG_BTCOEX,
|
||||
"no stomp timer running\n");
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
spin_lock_bh(&btcoex->btcoex_lock);
|
||||
|
||||
if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
|
||||
ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE);
|
||||
ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
|
||||
else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
|
||||
ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW);
|
||||
ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW);
|
||||
|
||||
spin_unlock_bh(&btcoex->btcoex_lock);
|
||||
ath9k_ps_restore(sc);
|
||||
}
|
||||
|
||||
int ath_init_btcoex_timer(struct ath_softc *sc)
|
||||
|
@ -17,6 +17,9 @@
|
||||
#ifndef HTC_USB_H
|
||||
#define HTC_USB_H
|
||||
|
||||
#define MAJOR_VERSION_REQ 1
|
||||
#define MINOR_VERSION_REQ 2
|
||||
|
||||
#define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB))
|
||||
|
||||
#define AR9271_FIRMWARE 0x501000
|
||||
|
@ -66,8 +66,6 @@ enum htc_opmode {
|
||||
HTC_M_WDS = 2
|
||||
};
|
||||
|
||||
#define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr)
|
||||
|
||||
#define ATH9K_HTC_AMPDU 1
|
||||
#define ATH9K_HTC_NORMAL 2
|
||||
#define ATH9K_HTC_BEACON 3
|
||||
@ -75,7 +73,6 @@ enum htc_opmode {
|
||||
|
||||
#define ATH9K_HTC_TX_CTSONLY 0x1
|
||||
#define ATH9K_HTC_TX_RTSCTS 0x2
|
||||
#define ATH9K_HTC_TX_USE_MIN_RATE 0x100
|
||||
|
||||
struct tx_frame_hdr {
|
||||
u8 data_type;
|
||||
@ -106,15 +103,14 @@ struct tx_beacon_header {
|
||||
u16 rev;
|
||||
} __packed;
|
||||
|
||||
#define MAX_TX_AMPDU_SUBFRAMES_9271 17
|
||||
#define MAX_TX_AMPDU_SUBFRAMES_7010 22
|
||||
|
||||
struct ath9k_htc_cap_target {
|
||||
u32 flags;
|
||||
u32 flags_ext;
|
||||
u32 ampdu_limit;
|
||||
__be32 ampdu_limit;
|
||||
u8 ampdu_subframes;
|
||||
u8 enable_coex;
|
||||
u8 tx_chainmask;
|
||||
u8 tx_chainmask_legacy;
|
||||
u8 rtscts_ratecode;
|
||||
u8 protmode;
|
||||
u8 pad;
|
||||
} __packed;
|
||||
|
||||
@ -175,6 +171,13 @@ struct ath9k_htc_target_rate {
|
||||
struct ath9k_htc_rate rates;
|
||||
};
|
||||
|
||||
struct ath9k_htc_target_rate_mask {
|
||||
u8 vif_index;
|
||||
u8 band;
|
||||
__be32 mask;
|
||||
u16 pad;
|
||||
} __packed;
|
||||
|
||||
struct ath9k_htc_target_int_stats {
|
||||
__be32 rx;
|
||||
__be32 rxorn;
|
||||
@ -382,25 +385,6 @@ static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
|
||||
#define ATH_LED_PIN_9287 10
|
||||
#define ATH_LED_PIN_9271 15
|
||||
#define ATH_LED_PIN_7010 12
|
||||
#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */
|
||||
#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */
|
||||
|
||||
enum ath_led_type {
|
||||
ATH_LED_RADIO,
|
||||
ATH_LED_ASSOC,
|
||||
ATH_LED_TX,
|
||||
ATH_LED_RX
|
||||
};
|
||||
|
||||
struct ath_led {
|
||||
struct ath9k_htc_priv *priv;
|
||||
struct led_classdev led_cdev;
|
||||
enum ath_led_type led_type;
|
||||
struct delayed_work brightness_work;
|
||||
char name[32];
|
||||
bool registered;
|
||||
int brightness;
|
||||
};
|
||||
|
||||
#define BSTUCK_THRESHOLD 10
|
||||
|
||||
@ -434,14 +418,11 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv);
|
||||
|
||||
#define OP_INVALID BIT(0)
|
||||
#define OP_SCANNING BIT(1)
|
||||
#define OP_LED_ASSOCIATED BIT(2)
|
||||
#define OP_LED_ON BIT(3)
|
||||
#define OP_ENABLE_BEACON BIT(4)
|
||||
#define OP_LED_DEINIT BIT(5)
|
||||
#define OP_BT_PRIORITY_DETECTED BIT(6)
|
||||
#define OP_BT_SCAN BIT(7)
|
||||
#define OP_ANI_RUNNING BIT(8)
|
||||
#define OP_TSF_RESET BIT(9)
|
||||
#define OP_ENABLE_BEACON BIT(2)
|
||||
#define OP_BT_PRIORITY_DETECTED BIT(3)
|
||||
#define OP_BT_SCAN BIT(4)
|
||||
#define OP_ANI_RUNNING BIT(5)
|
||||
#define OP_TSF_RESET BIT(6)
|
||||
|
||||
struct ath9k_htc_priv {
|
||||
struct device *dev;
|
||||
@ -501,15 +482,13 @@ struct ath9k_htc_priv {
|
||||
bool ps_enabled;
|
||||
bool ps_idle;
|
||||
|
||||
struct ath_led radio_led;
|
||||
struct ath_led assoc_led;
|
||||
struct ath_led tx_led;
|
||||
struct ath_led rx_led;
|
||||
struct delayed_work ath9k_led_blink_work;
|
||||
int led_on_duration;
|
||||
int led_off_duration;
|
||||
int led_on_cnt;
|
||||
int led_off_cnt;
|
||||
#ifdef CONFIG_MAC80211_LEDS
|
||||
enum led_brightness brightness;
|
||||
bool led_registered;
|
||||
char led_name[32];
|
||||
struct led_classdev led_cdev;
|
||||
struct work_struct led_work;
|
||||
#endif
|
||||
|
||||
int beaconq;
|
||||
int cabq;
|
||||
@ -551,7 +530,8 @@ void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id,
|
||||
void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
|
||||
enum htc_endpoint_id ep_id, bool txok);
|
||||
|
||||
int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv);
|
||||
int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
|
||||
u8 enable_coex);
|
||||
void ath9k_htc_station_work(struct work_struct *work);
|
||||
void ath9k_htc_aggr_work(struct work_struct *work);
|
||||
void ath9k_htc_ani_work(struct work_struct *work);
|
||||
@ -593,9 +573,24 @@ void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
|
||||
void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw);
|
||||
void ath9k_htc_radio_enable(struct ieee80211_hw *hw);
|
||||
void ath9k_htc_radio_disable(struct ieee80211_hw *hw);
|
||||
void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv);
|
||||
|
||||
#ifdef CONFIG_MAC80211_LEDS
|
||||
void ath9k_init_leds(struct ath9k_htc_priv *priv);
|
||||
void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
|
||||
void ath9k_led_work(struct work_struct *work);
|
||||
#else
|
||||
static inline void ath9k_init_leds(struct ath9k_htc_priv *priv)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath9k_led_work(struct work_struct *work)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
|
||||
u16 devid, char *product, u32 drv_info);
|
||||
|
@ -74,7 +74,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
|
||||
__be32 htc_imask = 0;
|
||||
u64 tsf;
|
||||
int num_beacons, offset, dtim_dec_count, cfp_dec_count;
|
||||
int ret;
|
||||
int ret __attribute__ ((unused));
|
||||
u8 cmd_rsp;
|
||||
|
||||
memset(&bs, 0, sizeof(bs));
|
||||
@ -190,7 +190,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
|
||||
enum ath9k_int imask = 0;
|
||||
u32 nexttbtt, intval, tsftu;
|
||||
__be32 htc_imask = 0;
|
||||
int ret;
|
||||
int ret __attribute__ ((unused));
|
||||
u8 cmd_rsp;
|
||||
u64 tsf;
|
||||
|
||||
@ -246,7 +246,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
|
||||
enum ath9k_int imask = 0;
|
||||
u32 nexttbtt, intval, tsftu;
|
||||
__be32 htc_imask = 0;
|
||||
int ret;
|
||||
int ret __attribute__ ((unused));
|
||||
u8 cmd_rsp;
|
||||
u64 tsf;
|
||||
|
||||
|
@ -33,9 +33,15 @@ static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf,
|
||||
|
||||
memset(&cmd_rsp, 0, sizeof(cmd_rsp));
|
||||
|
||||
ath9k_htc_ps_wakeup(priv);
|
||||
|
||||
WMI_CMD(WMI_INT_STATS_CMDID);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
ath9k_htc_ps_restore(priv);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ath9k_htc_ps_restore(priv);
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%20s : %10u\n", "RX",
|
||||
@ -85,9 +91,15 @@ static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf,
|
||||
|
||||
memset(&cmd_rsp, 0, sizeof(cmd_rsp));
|
||||
|
||||
ath9k_htc_ps_wakeup(priv);
|
||||
|
||||
WMI_CMD(WMI_TX_STATS_CMDID);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
ath9k_htc_ps_restore(priv);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ath9k_htc_ps_restore(priv);
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%20s : %10u\n", "Xretries",
|
||||
@ -149,9 +161,15 @@ static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf,
|
||||
|
||||
memset(&cmd_rsp, 0, sizeof(cmd_rsp));
|
||||
|
||||
ath9k_htc_ps_wakeup(priv);
|
||||
|
||||
WMI_CMD(WMI_RX_STATS_CMDID);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
ath9k_htc_ps_restore(priv);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ath9k_htc_ps_restore(priv);
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%20s : %10u\n", "NoBuf",
|
||||
@ -474,6 +492,439 @@ static const struct file_operations fops_debug = {
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath9k_htc_priv *priv = file->private_data;
|
||||
struct ath_common *common = ath9k_hw_common(priv->ah);
|
||||
struct base_eep_header *pBase = NULL;
|
||||
unsigned int len = 0, size = 1500;
|
||||
ssize_t retval = 0;
|
||||
char *buf;
|
||||
|
||||
/*
|
||||
* This can be done since all the 3 EEPROM families have the
|
||||
* same base header upto a certain point, and we are interested in
|
||||
* the data only upto that point.
|
||||
*/
|
||||
|
||||
if (AR_SREV_9271(priv->ah))
|
||||
pBase = (struct base_eep_header *)
|
||||
&priv->ah->eeprom.map4k.baseEepHeader;
|
||||
else if (priv->ah->hw_version.usbdev == AR9280_USB)
|
||||
pBase = (struct base_eep_header *)
|
||||
&priv->ah->eeprom.def.baseEepHeader;
|
||||
else if (priv->ah->hw_version.usbdev == AR9287_USB)
|
||||
pBase = (struct base_eep_header *)
|
||||
&priv->ah->eeprom.map9287.baseEepHeader;
|
||||
|
||||
if (pBase == NULL) {
|
||||
ath_err(common, "Unknown EEPROM type\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
buf = kzalloc(size, GFP_KERNEL);
|
||||
if (buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n", "Major Version",
|
||||
pBase->version >> 12);
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n", "Minor Version",
|
||||
pBase->version & 0xFFF);
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n", "Checksum",
|
||||
pBase->checksum);
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n", "Length",
|
||||
pBase->length);
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n", "RegDomain1",
|
||||
pBase->regDmn[0]);
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n", "RegDomain2",
|
||||
pBase->regDmn[1]);
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n",
|
||||
"TX Mask", pBase->txMask);
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n",
|
||||
"RX Mask", pBase->rxMask);
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n",
|
||||
"Allow 5GHz",
|
||||
!!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n",
|
||||
"Allow 2GHz",
|
||||
!!(pBase->opCapFlags & AR5416_OPFLAGS_11G));
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n",
|
||||
"Disable 2GHz HT20",
|
||||
!!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT20));
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n",
|
||||
"Disable 2GHz HT40",
|
||||
!!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT40));
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n",
|
||||
"Disable 5Ghz HT20",
|
||||
!!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT20));
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n",
|
||||
"Disable 5Ghz HT40",
|
||||
!!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT40));
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n",
|
||||
"Big Endian",
|
||||
!!(pBase->eepMisc & 0x01));
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n",
|
||||
"Cal Bin Major Ver",
|
||||
(pBase->binBuildNumber >> 24) & 0xFF);
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n",
|
||||
"Cal Bin Minor Ver",
|
||||
(pBase->binBuildNumber >> 16) & 0xFF);
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n",
|
||||
"Cal Bin Build",
|
||||
(pBase->binBuildNumber >> 8) & 0xFF);
|
||||
|
||||
/*
|
||||
* UB91 specific data.
|
||||
*/
|
||||
if (AR_SREV_9271(priv->ah)) {
|
||||
struct base_eep_header_4k *pBase4k =
|
||||
&priv->ah->eeprom.map4k.baseEepHeader;
|
||||
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n",
|
||||
"TX Gain type",
|
||||
pBase4k->txGainType);
|
||||
}
|
||||
|
||||
/*
|
||||
* UB95 specific data.
|
||||
*/
|
||||
if (priv->ah->hw_version.usbdev == AR9287_USB) {
|
||||
struct base_eep_ar9287_header *pBase9287 =
|
||||
&priv->ah->eeprom.map9287.baseEepHeader;
|
||||
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10ddB\n",
|
||||
"Power Table Offset",
|
||||
pBase9287->pwrTableOffset);
|
||||
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %10d\n",
|
||||
"OpenLoop Power Ctrl",
|
||||
pBase9287->openLoopPwrCntl);
|
||||
}
|
||||
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%20s : %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
"MacAddress",
|
||||
pBase->macAddr[0], pBase->macAddr[1], pBase->macAddr[2],
|
||||
pBase->macAddr[3], pBase->macAddr[4], pBase->macAddr[5]);
|
||||
if (len > size)
|
||||
len = size;
|
||||
|
||||
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
kfree(buf);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_base_eeprom = {
|
||||
.read = read_file_base_eeprom,
|
||||
.open = ath9k_debugfs_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t read_4k_modal_eeprom(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
#define PR_EEP(_s, _val) \
|
||||
do { \
|
||||
len += snprintf(buf + len, size - len, "%20s : %10d\n", \
|
||||
_s, (_val)); \
|
||||
} while (0)
|
||||
|
||||
struct ath9k_htc_priv *priv = file->private_data;
|
||||
struct modal_eep_4k_header *pModal = &priv->ah->eeprom.map4k.modalHeader;
|
||||
unsigned int len = 0, size = 2048;
|
||||
ssize_t retval = 0;
|
||||
char *buf;
|
||||
|
||||
buf = kzalloc(size, GFP_KERNEL);
|
||||
if (buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
|
||||
PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
|
||||
PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
|
||||
PR_EEP("Switch Settle", pModal->switchSettling);
|
||||
PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
|
||||
PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
|
||||
PR_EEP("ADC Desired size", pModal->adcDesiredSize);
|
||||
PR_EEP("PGA Desired size", pModal->pgaDesiredSize);
|
||||
PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]);
|
||||
PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
|
||||
PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
|
||||
PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
|
||||
PR_EEP("CCA Threshold)", pModal->thresh62);
|
||||
PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
|
||||
PR_EEP("xpdGain", pModal->xpdGain);
|
||||
PR_EEP("External PD", pModal->xpd);
|
||||
PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
|
||||
PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
|
||||
PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
|
||||
PR_EEP("O/D Bias Version", pModal->version);
|
||||
PR_EEP("CCK OutputBias", pModal->ob_0);
|
||||
PR_EEP("BPSK OutputBias", pModal->ob_1);
|
||||
PR_EEP("QPSK OutputBias", pModal->ob_2);
|
||||
PR_EEP("16QAM OutputBias", pModal->ob_3);
|
||||
PR_EEP("64QAM OutputBias", pModal->ob_4);
|
||||
PR_EEP("CCK Driver1_Bias", pModal->db1_0);
|
||||
PR_EEP("BPSK Driver1_Bias", pModal->db1_1);
|
||||
PR_EEP("QPSK Driver1_Bias", pModal->db1_2);
|
||||
PR_EEP("16QAM Driver1_Bias", pModal->db1_3);
|
||||
PR_EEP("64QAM Driver1_Bias", pModal->db1_4);
|
||||
PR_EEP("CCK Driver2_Bias", pModal->db2_0);
|
||||
PR_EEP("BPSK Driver2_Bias", pModal->db2_1);
|
||||
PR_EEP("QPSK Driver2_Bias", pModal->db2_2);
|
||||
PR_EEP("16QAM Driver2_Bias", pModal->db2_3);
|
||||
PR_EEP("64QAM Driver2_Bias", pModal->db2_4);
|
||||
PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
|
||||
PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
|
||||
PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
|
||||
PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
|
||||
PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
|
||||
PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
|
||||
PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
|
||||
PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]);
|
||||
PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]);
|
||||
PR_EEP("Ant. Diversity ctl1", pModal->antdiv_ctl1);
|
||||
PR_EEP("Ant. Diversity ctl2", pModal->antdiv_ctl2);
|
||||
PR_EEP("TX Diversity", pModal->tx_diversity);
|
||||
|
||||
if (len > size)
|
||||
len = size;
|
||||
|
||||
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
kfree(buf);
|
||||
|
||||
return retval;
|
||||
|
||||
#undef PR_EEP
|
||||
}
|
||||
|
||||
static ssize_t read_def_modal_eeprom(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
#define PR_EEP(_s, _val) \
|
||||
do { \
|
||||
if (pBase->opCapFlags & AR5416_OPFLAGS_11G) { \
|
||||
pModal = &priv->ah->eeprom.def.modalHeader[1]; \
|
||||
len += snprintf(buf + len, size - len, "%20s : %8d%7s", \
|
||||
_s, (_val), "|"); \
|
||||
} \
|
||||
if (pBase->opCapFlags & AR5416_OPFLAGS_11A) { \
|
||||
pModal = &priv->ah->eeprom.def.modalHeader[0]; \
|
||||
len += snprintf(buf + len, size - len, "%9d\n", \
|
||||
(_val)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
struct ath9k_htc_priv *priv = file->private_data;
|
||||
struct base_eep_header *pBase = &priv->ah->eeprom.def.baseEepHeader;
|
||||
struct modal_eep_header *pModal = NULL;
|
||||
unsigned int len = 0, size = 3500;
|
||||
ssize_t retval = 0;
|
||||
char *buf;
|
||||
|
||||
buf = kzalloc(size, GFP_KERNEL);
|
||||
if (buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%31s %15s\n", "2G", "5G");
|
||||
len += snprintf(buf + len, size - len,
|
||||
"%32s %16s\n", "====", "====\n");
|
||||
|
||||
PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
|
||||
PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]);
|
||||
PR_EEP("Chain2 Ant. Control", pModal->antCtrlChain[2]);
|
||||
PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
|
||||
PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
|
||||
PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]);
|
||||
PR_EEP("Chain2 Ant. Gain", pModal->antennaGainCh[2]);
|
||||
PR_EEP("Switch Settle", pModal->switchSettling);
|
||||
PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
|
||||
PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]);
|
||||
PR_EEP("Chain2 TxRxAtten", pModal->txRxAttenCh[2]);
|
||||
PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
|
||||
PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]);
|
||||
PR_EEP("Chain2 RxTxMargin", pModal->rxTxMarginCh[2]);
|
||||
PR_EEP("ADC Desired size", pModal->adcDesiredSize);
|
||||
PR_EEP("PGA Desired size", pModal->pgaDesiredSize);
|
||||
PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]);
|
||||
PR_EEP("Chain1 xlna Gain", pModal->xlnaGainCh[1]);
|
||||
PR_EEP("Chain2 xlna Gain", pModal->xlnaGainCh[2]);
|
||||
PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
|
||||
PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
|
||||
PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
|
||||
PR_EEP("CCA Threshold)", pModal->thresh62);
|
||||
PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
|
||||
PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]);
|
||||
PR_EEP("Chain2 NF Threshold", pModal->noiseFloorThreshCh[2]);
|
||||
PR_EEP("xpdGain", pModal->xpdGain);
|
||||
PR_EEP("External PD", pModal->xpd);
|
||||
PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
|
||||
PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]);
|
||||
PR_EEP("Chain2 I Coefficient", pModal->iqCalICh[2]);
|
||||
PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
|
||||
PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]);
|
||||
PR_EEP("Chain2 Q Coefficient", pModal->iqCalQCh[2]);
|
||||
PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
|
||||
PR_EEP("Chain0 OutputBias", pModal->ob);
|
||||
PR_EEP("Chain0 DriverBias", pModal->db);
|
||||
PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
|
||||
PR_EEP("2chain pwr decrease", pModal->pwrDecreaseFor2Chain);
|
||||
PR_EEP("3chain pwr decrease", pModal->pwrDecreaseFor3Chain);
|
||||
PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
|
||||
PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
|
||||
PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
|
||||
PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
|
||||
PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]);
|
||||
PR_EEP("Chain2 bswAtten", pModal->bswAtten[2]);
|
||||
PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
|
||||
PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]);
|
||||
PR_EEP("Chain2 bswMargin", pModal->bswMargin[2]);
|
||||
PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
|
||||
PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]);
|
||||
PR_EEP("Chain1 xatten2Db", pModal->xatten2Db[1]);
|
||||
PR_EEP("Chain2 xatten2Db", pModal->xatten2Db[2]);
|
||||
PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]);
|
||||
PR_EEP("Chain1 xatten2Margin", pModal->xatten2Margin[1]);
|
||||
PR_EEP("Chain2 xatten2Margin", pModal->xatten2Margin[2]);
|
||||
PR_EEP("Chain1 OutputBias", pModal->ob_ch1);
|
||||
PR_EEP("Chain1 DriverBias", pModal->db_ch1);
|
||||
PR_EEP("LNA Control", pModal->lna_ctl);
|
||||
PR_EEP("XPA Bias Freq0", pModal->xpaBiasLvlFreq[0]);
|
||||
PR_EEP("XPA Bias Freq1", pModal->xpaBiasLvlFreq[1]);
|
||||
PR_EEP("XPA Bias Freq2", pModal->xpaBiasLvlFreq[2]);
|
||||
|
||||
if (len > size)
|
||||
len = size;
|
||||
|
||||
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
kfree(buf);
|
||||
|
||||
return retval;
|
||||
|
||||
#undef PR_EEP
|
||||
}
|
||||
|
||||
static ssize_t read_9287_modal_eeprom(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
#define PR_EEP(_s, _val) \
|
||||
do { \
|
||||
len += snprintf(buf + len, size - len, "%20s : %10d\n", \
|
||||
_s, (_val)); \
|
||||
} while (0)
|
||||
|
||||
struct ath9k_htc_priv *priv = file->private_data;
|
||||
struct modal_eep_ar9287_header *pModal = &priv->ah->eeprom.map9287.modalHeader;
|
||||
unsigned int len = 0, size = 3000;
|
||||
ssize_t retval = 0;
|
||||
char *buf;
|
||||
|
||||
buf = kzalloc(size, GFP_KERNEL);
|
||||
if (buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
|
||||
PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]);
|
||||
PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
|
||||
PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
|
||||
PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]);
|
||||
PR_EEP("Switch Settle", pModal->switchSettling);
|
||||
PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
|
||||
PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]);
|
||||
PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
|
||||
PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]);
|
||||
PR_EEP("ADC Desired size", pModal->adcDesiredSize);
|
||||
PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
|
||||
PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
|
||||
PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
|
||||
PR_EEP("CCA Threshold)", pModal->thresh62);
|
||||
PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
|
||||
PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]);
|
||||
PR_EEP("xpdGain", pModal->xpdGain);
|
||||
PR_EEP("External PD", pModal->xpd);
|
||||
PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
|
||||
PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]);
|
||||
PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
|
||||
PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]);
|
||||
PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
|
||||
PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
|
||||
PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
|
||||
PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
|
||||
PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
|
||||
PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
|
||||
PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]);
|
||||
PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
|
||||
PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]);
|
||||
PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
|
||||
PR_EEP("AR92x7 Version", pModal->version);
|
||||
PR_EEP("DriverBias1", pModal->db1);
|
||||
PR_EEP("DriverBias2", pModal->db1);
|
||||
PR_EEP("CCK OutputBias", pModal->ob_cck);
|
||||
PR_EEP("PSK OutputBias", pModal->ob_psk);
|
||||
PR_EEP("QAM OutputBias", pModal->ob_qam);
|
||||
PR_EEP("PAL_OFF OutputBias", pModal->ob_pal_off);
|
||||
|
||||
if (len > size)
|
||||
len = size;
|
||||
|
||||
retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
kfree(buf);
|
||||
|
||||
return retval;
|
||||
|
||||
#undef PR_EEP
|
||||
}
|
||||
|
||||
static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath9k_htc_priv *priv = file->private_data;
|
||||
|
||||
if (AR_SREV_9271(priv->ah))
|
||||
return read_4k_modal_eeprom(file, user_buf, count, ppos);
|
||||
else if (priv->ah->hw_version.usbdev == AR9280_USB)
|
||||
return read_def_modal_eeprom(file, user_buf, count, ppos);
|
||||
else if (priv->ah->hw_version.usbdev == AR9287_USB)
|
||||
return read_9287_modal_eeprom(file, user_buf, count, ppos);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_modal_eeprom = {
|
||||
.read = read_file_modal_eeprom,
|
||||
.open = ath9k_debugfs_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
int ath9k_htc_init_debug(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
@ -485,21 +936,25 @@ int ath9k_htc_init_debug(struct ath_hw *ah)
|
||||
return -ENOMEM;
|
||||
|
||||
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,
|
||||
priv, &fops_tgt_tx_stats);
|
||||
priv, &fops_tgt_tx_stats);
|
||||
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,
|
||||
priv, &fops_xmit);
|
||||
priv, &fops_xmit);
|
||||
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,
|
||||
priv, &fops_slot);
|
||||
priv, &fops_slot);
|
||||
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,
|
||||
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;
|
||||
}
|
||||
|
@ -65,17 +65,19 @@ static void ath_btcoex_period_work(struct work_struct *work)
|
||||
u32 timer_period;
|
||||
bool is_btscan;
|
||||
int ret;
|
||||
u8 cmd_rsp, aggr;
|
||||
|
||||
ath_detect_bt_priority(priv);
|
||||
|
||||
is_btscan = !!(priv->op_flags & OP_BT_SCAN);
|
||||
|
||||
aggr = priv->op_flags & OP_BT_PRIORITY_DETECTED;
|
||||
ret = ath9k_htc_update_cap_target(priv,
|
||||
!!(priv->op_flags & OP_BT_PRIORITY_DETECTED));
|
||||
if (ret) {
|
||||
ath_err(common, "Unable to set BTCOEX parameters\n");
|
||||
return;
|
||||
}
|
||||
|
||||
WMI_CMD_BUF(WMI_AGGR_LIMIT_CMD, &aggr);
|
||||
|
||||
ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL :
|
||||
ath9k_hw_btcoex_bt_stomp(priv->ah, is_btscan ? ATH_BTCOEX_STOMP_ALL :
|
||||
btcoex->bt_stomp_type);
|
||||
|
||||
timer_period = is_btscan ? btcoex->btscan_no_stomp :
|
||||
@ -103,9 +105,9 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work)
|
||||
"time slice work for bt and wlan\n");
|
||||
|
||||
if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
|
||||
ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE);
|
||||
ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
|
||||
else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
|
||||
ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW);
|
||||
ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW);
|
||||
}
|
||||
|
||||
void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv)
|
||||
@ -152,140 +154,41 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv)
|
||||
/* LED */
|
||||
/*******/
|
||||
|
||||
static void ath9k_led_blink_work(struct work_struct *work)
|
||||
#ifdef CONFIG_MAC80211_LEDS
|
||||
void ath9k_led_work(struct work_struct *work)
|
||||
{
|
||||
struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
|
||||
ath9k_led_blink_work.work);
|
||||
struct ath9k_htc_priv *priv = container_of(work,
|
||||
struct ath9k_htc_priv,
|
||||
led_work);
|
||||
|
||||
if (!(priv->op_flags & OP_LED_ASSOCIATED))
|
||||
return;
|
||||
|
||||
if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
|
||||
(priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
|
||||
ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
|
||||
else
|
||||
ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
|
||||
(priv->op_flags & OP_LED_ON) ? 1 : 0);
|
||||
|
||||
ieee80211_queue_delayed_work(priv->hw,
|
||||
&priv->ath9k_led_blink_work,
|
||||
(priv->op_flags & OP_LED_ON) ?
|
||||
msecs_to_jiffies(priv->led_off_duration) :
|
||||
msecs_to_jiffies(priv->led_on_duration));
|
||||
|
||||
priv->led_on_duration = priv->led_on_cnt ?
|
||||
max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
|
||||
ATH_LED_ON_DURATION_IDLE;
|
||||
priv->led_off_duration = priv->led_off_cnt ?
|
||||
max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
|
||||
ATH_LED_OFF_DURATION_IDLE;
|
||||
priv->led_on_cnt = priv->led_off_cnt = 0;
|
||||
|
||||
if (priv->op_flags & OP_LED_ON)
|
||||
priv->op_flags &= ~OP_LED_ON;
|
||||
else
|
||||
priv->op_flags |= OP_LED_ON;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
|
||||
(priv->brightness == LED_OFF));
|
||||
}
|
||||
|
||||
static void ath9k_led_brightness(struct led_classdev *led_cdev,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
|
||||
struct ath9k_htc_priv *priv = led->priv;
|
||||
struct ath9k_htc_priv *priv = container_of(led_cdev,
|
||||
struct ath9k_htc_priv,
|
||||
led_cdev);
|
||||
|
||||
led->brightness = brightness;
|
||||
if (!(priv->op_flags & OP_LED_DEINIT))
|
||||
ieee80211_queue_delayed_work(priv->hw,
|
||||
&led->brightness_work, 0);
|
||||
}
|
||||
|
||||
void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
|
||||
{
|
||||
cancel_delayed_work_sync(&priv->radio_led.brightness_work);
|
||||
cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
|
||||
cancel_delayed_work_sync(&priv->tx_led.brightness_work);
|
||||
cancel_delayed_work_sync(&priv->rx_led.brightness_work);
|
||||
}
|
||||
|
||||
static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
|
||||
char *trigger)
|
||||
{
|
||||
int ret;
|
||||
|
||||
led->priv = priv;
|
||||
led->led_cdev.name = led->name;
|
||||
led->led_cdev.default_trigger = trigger;
|
||||
led->led_cdev.brightness_set = ath9k_led_brightness;
|
||||
|
||||
ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
|
||||
if (ret)
|
||||
ath_err(ath9k_hw_common(priv->ah),
|
||||
"Failed to register led:%s", led->name);
|
||||
else
|
||||
led->registered = 1;
|
||||
|
||||
INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ath9k_unregister_led(struct ath_led *led)
|
||||
{
|
||||
if (led->registered) {
|
||||
led_classdev_unregister(&led->led_cdev);
|
||||
led->registered = 0;
|
||||
}
|
||||
/* Not locked, but it's just a tiny green light..*/
|
||||
priv->brightness = brightness;
|
||||
ieee80211_queue_work(priv->hw, &priv->led_work);
|
||||
}
|
||||
|
||||
void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
|
||||
{
|
||||
priv->op_flags |= OP_LED_DEINIT;
|
||||
ath9k_unregister_led(&priv->assoc_led);
|
||||
priv->op_flags &= ~OP_LED_ASSOCIATED;
|
||||
ath9k_unregister_led(&priv->tx_led);
|
||||
ath9k_unregister_led(&priv->rx_led);
|
||||
ath9k_unregister_led(&priv->radio_led);
|
||||
if (!priv->led_registered)
|
||||
return;
|
||||
|
||||
ath9k_led_brightness(&priv->led_cdev, LED_OFF);
|
||||
led_classdev_unregister(&priv->led_cdev);
|
||||
cancel_work_sync(&priv->led_work);
|
||||
}
|
||||
|
||||
void ath9k_init_leds(struct ath9k_htc_priv *priv)
|
||||
{
|
||||
char *trigger;
|
||||
int ret;
|
||||
|
||||
if (AR_SREV_9287(priv->ah))
|
||||
@ -303,48 +206,21 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv)
|
||||
/* LED off, active low */
|
||||
ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
|
||||
|
||||
INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
|
||||
snprintf(priv->led_name, sizeof(priv->led_name),
|
||||
"ath9k_htc-%s", wiphy_name(priv->hw->wiphy));
|
||||
priv->led_cdev.name = priv->led_name;
|
||||
priv->led_cdev.brightness_set = ath9k_led_brightness;
|
||||
|
||||
trigger = ieee80211_get_radio_led_name(priv->hw);
|
||||
snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
|
||||
"ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
|
||||
ret = ath9k_register_led(priv, &priv->radio_led, trigger);
|
||||
priv->radio_led.led_type = ATH_LED_RADIO;
|
||||
if (ret)
|
||||
goto fail;
|
||||
ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &priv->led_cdev);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
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;
|
||||
INIT_WORK(&priv->led_work, ath9k_led_work);
|
||||
priv->led_registered = true;
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
|
||||
ath9k_deinit_leds(priv);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************/
|
||||
/* Rfkill */
|
||||
|
@ -117,6 +117,21 @@ static struct ieee80211_rate ath9k_legacy_rates[] = {
|
||||
RATE(540, 0x0c, 0),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MAC80211_LEDS
|
||||
static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = {
|
||||
{ .throughput = 0 * 1024, .blink_time = 334 },
|
||||
{ .throughput = 1 * 1024, .blink_time = 260 },
|
||||
{ .throughput = 5 * 1024, .blink_time = 220 },
|
||||
{ .throughput = 10 * 1024, .blink_time = 190 },
|
||||
{ .throughput = 20 * 1024, .blink_time = 170 },
|
||||
{ .throughput = 50 * 1024, .blink_time = 150 },
|
||||
{ .throughput = 70 * 1024, .blink_time = 130 },
|
||||
{ .throughput = 100 * 1024, .blink_time = 110 },
|
||||
{ .throughput = 200 * 1024, .blink_time = 80 },
|
||||
{ .throughput = 300 * 1024, .blink_time = 50 },
|
||||
};
|
||||
#endif
|
||||
|
||||
static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
|
||||
{
|
||||
int time_left;
|
||||
@ -243,7 +258,7 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid,
|
||||
*/
|
||||
|
||||
if (IS_AR7010_DEVICE(drv_info))
|
||||
priv->htc->credits = 45;
|
||||
priv->htc->credits = 48;
|
||||
else
|
||||
priv->htc->credits = 33;
|
||||
|
||||
@ -753,6 +768,12 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
|
||||
hw->queues = 4;
|
||||
hw->channel_change_time = 5000;
|
||||
hw->max_listen_interval = 10;
|
||||
|
||||
if (AR_SREV_9271(priv->ah))
|
||||
hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_9271;
|
||||
else
|
||||
hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_7010;
|
||||
|
||||
hw->vif_data_size = sizeof(struct ath9k_htc_vif);
|
||||
hw->sta_data_size = sizeof(struct ath9k_htc_sta);
|
||||
|
||||
@ -802,6 +823,17 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
|
||||
priv->fw_version_major,
|
||||
priv->fw_version_minor);
|
||||
|
||||
/*
|
||||
* Check if the available FW matches the driver's
|
||||
* required version.
|
||||
*/
|
||||
if (priv->fw_version_major != MAJOR_VERSION_REQ ||
|
||||
priv->fw_version_minor != MINOR_VERSION_REQ) {
|
||||
dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n",
|
||||
MAJOR_VERSION_REQ, MINOR_VERSION_REQ);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -846,6 +878,13 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
|
||||
if (error != 0)
|
||||
goto err_rx;
|
||||
|
||||
#ifdef CONFIG_MAC80211_LEDS
|
||||
/* must be initialized before ieee80211_register_hw */
|
||||
priv->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(priv->hw,
|
||||
IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_htc_tpt_blink,
|
||||
ARRAY_SIZE(ath9k_htc_tpt_blink));
|
||||
#endif
|
||||
|
||||
/* Register with mac80211 */
|
||||
error = ieee80211_register_hw(hw);
|
||||
if (error)
|
||||
|
@ -332,6 +332,11 @@ static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
|
||||
memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
|
||||
hvif.index = priv->mon_vif_idx;
|
||||
WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
|
||||
if (ret) {
|
||||
ath_err(common, "Unable to remove monitor interface at idx: %d\n",
|
||||
priv->mon_vif_idx);
|
||||
}
|
||||
|
||||
priv->nvifs--;
|
||||
priv->vif_slot &= ~(1 << priv->mon_vif_idx);
|
||||
}
|
||||
@ -462,6 +467,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
|
||||
struct ath9k_htc_sta *ista;
|
||||
int ret, sta_idx;
|
||||
u8 cmd_rsp;
|
||||
u16 maxampdu;
|
||||
|
||||
if (priv->nstations >= ATH9K_HTC_MAX_STA)
|
||||
return -ENOBUFS;
|
||||
@ -485,7 +491,15 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
|
||||
|
||||
tsta.sta_index = sta_idx;
|
||||
tsta.vif_index = avp->index;
|
||||
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)
|
||||
tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
|
||||
|
||||
@ -558,7 +572,8 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
|
||||
int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
|
||||
u8 enable_coex)
|
||||
{
|
||||
struct ath9k_htc_cap_target tcap;
|
||||
int ret;
|
||||
@ -566,13 +581,9 @@ int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
|
||||
|
||||
memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
|
||||
|
||||
/* FIXME: Values are hardcoded */
|
||||
tcap.flags = 0x240c40;
|
||||
tcap.flags_ext = 0x80601000;
|
||||
tcap.ampdu_limit = 0xffff0000;
|
||||
tcap.ampdu_subframes = 20;
|
||||
tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask;
|
||||
tcap.protmode = 1;
|
||||
tcap.ampdu_limit = cpu_to_be32(0xffff);
|
||||
tcap.ampdu_subframes = priv->hw->max_tx_aggregation_subframes;
|
||||
tcap.enable_coex = enable_coex;
|
||||
tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
|
||||
|
||||
WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
|
||||
@ -931,7 +942,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
|
||||
|
||||
ath9k_host_rx_init(priv);
|
||||
|
||||
ret = ath9k_htc_update_cap_target(priv);
|
||||
ret = ath9k_htc_update_cap_target(priv, 0);
|
||||
if (ret)
|
||||
ath_dbg(common, ATH_DBG_CONFIG,
|
||||
"Failed to update capability in target\n");
|
||||
@ -964,7 +975,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
|
||||
struct ath9k_htc_priv *priv = hw->priv;
|
||||
struct ath_hw *ah = priv->ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int ret = 0;
|
||||
int ret __attribute__ ((unused));
|
||||
u8 cmd_rsp;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
@ -992,9 +1003,11 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
|
||||
/* Cancel all the running timers/work .. */
|
||||
cancel_work_sync(&priv->fatal_work);
|
||||
cancel_work_sync(&priv->ps_work);
|
||||
cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
|
||||
|
||||
#ifdef CONFIG_MAC80211_LEDS
|
||||
cancel_work_sync(&priv->led_work);
|
||||
#endif
|
||||
ath9k_htc_stop_ani(priv);
|
||||
ath9k_led_stop_brightness(priv);
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
@ -1135,6 +1148,10 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
|
||||
memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
|
||||
hvif.index = avp->index;
|
||||
WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
|
||||
if (ret) {
|
||||
ath_err(common, "Unable to remove interface at idx: %d\n",
|
||||
avp->index);
|
||||
}
|
||||
priv->nvifs--;
|
||||
priv->vif_slot &= ~(1 << avp->index);
|
||||
|
||||
@ -1567,6 +1584,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
ath9k_htc_ps_wakeup(priv);
|
||||
|
||||
switch (action) {
|
||||
case IEEE80211_AMPDU_RX_START:
|
||||
@ -1592,6 +1610,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
|
||||
ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
|
||||
}
|
||||
|
||||
ath9k_htc_ps_restore(priv);
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
||||
return ret;
|
||||
@ -1642,6 +1661,55 @@ static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* Currently, this is used only for selecting the minimum rate
|
||||
* for management frames, rate selection for data frames remain
|
||||
* unaffected.
|
||||
*/
|
||||
static int ath9k_htc_set_bitrate_mask(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
const struct cfg80211_bitrate_mask *mask)
|
||||
{
|
||||
struct ath9k_htc_priv *priv = hw->priv;
|
||||
struct ath_common *common = ath9k_hw_common(priv->ah);
|
||||
struct ath9k_htc_target_rate_mask tmask;
|
||||
struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
|
||||
int ret = 0;
|
||||
u8 cmd_rsp;
|
||||
|
||||
memset(&tmask, 0, sizeof(struct ath9k_htc_target_rate_mask));
|
||||
|
||||
tmask.vif_index = avp->index;
|
||||
tmask.band = IEEE80211_BAND_2GHZ;
|
||||
tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_2GHZ].legacy);
|
||||
|
||||
WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
|
||||
if (ret) {
|
||||
ath_err(common,
|
||||
"Unable to set 2G rate mask for "
|
||||
"interface at idx: %d\n", avp->index);
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmask.band = IEEE80211_BAND_5GHZ;
|
||||
tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_5GHZ].legacy);
|
||||
|
||||
WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
|
||||
if (ret) {
|
||||
ath_err(common,
|
||||
"Unable to set 5G rate mask for "
|
||||
"interface at idx: %d\n", avp->index);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ath_dbg(common, ATH_DBG_CONFIG,
|
||||
"Set bitrate masks: 0x%x, 0x%x\n",
|
||||
mask->control[IEEE80211_BAND_2GHZ].legacy,
|
||||
mask->control[IEEE80211_BAND_5GHZ].legacy);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct ieee80211_ops ath9k_htc_ops = {
|
||||
.tx = ath9k_htc_tx,
|
||||
.start = ath9k_htc_start,
|
||||
@ -1664,4 +1732,5 @@ struct ieee80211_ops ath9k_htc_ops = {
|
||||
.set_rts_threshold = ath9k_htc_set_rts_threshold,
|
||||
.rfkill_poll = ath9k_htc_rfkill_poll_state,
|
||||
.set_coverage_class = ath9k_htc_set_coverage_class,
|
||||
.set_bitrate_mask = ath9k_htc_set_bitrate_mask,
|
||||
};
|
||||
|
@ -446,7 +446,6 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
|
||||
struct ieee80211_tx_info *tx_info;
|
||||
struct ieee80211_tx_rate *rate;
|
||||
struct ieee80211_conf *cur_conf = &priv->hw->conf;
|
||||
struct ieee80211_supported_band *sband;
|
||||
bool txok;
|
||||
int slot;
|
||||
|
||||
@ -461,7 +460,6 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
|
||||
tx_info = IEEE80211_SKB_CB(skb);
|
||||
vif = tx_info->control.vif;
|
||||
rate = &tx_info->status.rates[0];
|
||||
sband = priv->hw->wiphy->bands[cur_conf->channel->band];
|
||||
|
||||
memset(&tx_info->status, 0, sizeof(tx_info->status));
|
||||
|
||||
|
@ -83,21 +83,10 @@ struct htc_ep_callbacks {
|
||||
void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id);
|
||||
};
|
||||
|
||||
#define HTC_TX_QUEUE_SIZE 256
|
||||
|
||||
struct htc_txq {
|
||||
struct sk_buff *buf[HTC_TX_QUEUE_SIZE];
|
||||
u32 txqdepth;
|
||||
u16 txbuf_cnt;
|
||||
u16 txq_head;
|
||||
u16 txq_tail;
|
||||
};
|
||||
|
||||
struct htc_endpoint {
|
||||
u16 service_id;
|
||||
|
||||
struct htc_ep_callbacks ep_callbacks;
|
||||
struct htc_txq htc_txq;
|
||||
u32 max_txqdepth;
|
||||
int max_msglen;
|
||||
|
||||
|
@ -247,6 +247,17 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
switch (ah->hw_version.devid) {
|
||||
case AR5416_AR9100_DEVID:
|
||||
ah->hw_version.macVersion = AR_SREV_VERSION_9100;
|
||||
break;
|
||||
case AR9300_DEVID_AR9340:
|
||||
ah->hw_version.macVersion = AR_SREV_VERSION_9340;
|
||||
val = REG_READ(ah, AR_SREV);
|
||||
ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
|
||||
return;
|
||||
}
|
||||
|
||||
val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
|
||||
|
||||
if (val == 0xFF) {
|
||||
@ -462,7 +473,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
|
||||
return ecode;
|
||||
}
|
||||
|
||||
if (!AR_SREV_9100(ah)) {
|
||||
if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) {
|
||||
ath9k_hw_ani_setup(ah);
|
||||
ath9k_hw_ani_init(ah);
|
||||
}
|
||||
@ -484,9 +495,6 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int r = 0;
|
||||
|
||||
if (ah->hw_version.devid == AR5416_AR9100_DEVID)
|
||||
ah->hw_version.macVersion = AR_SREV_VERSION_9100;
|
||||
|
||||
ath9k_hw_read_revisions(ah);
|
||||
|
||||
/*
|
||||
@ -544,6 +552,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
||||
case AR_SREV_VERSION_9271:
|
||||
case AR_SREV_VERSION_9300:
|
||||
case AR_SREV_VERSION_9485:
|
||||
case AR_SREV_VERSION_9340:
|
||||
break;
|
||||
default:
|
||||
ath_err(common,
|
||||
@ -552,7 +561,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (AR_SREV_9271(ah) || AR_SREV_9100(ah))
|
||||
if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah))
|
||||
ah->is_pciexpress = false;
|
||||
|
||||
ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
|
||||
@ -621,6 +630,7 @@ int ath9k_hw_init(struct ath_hw *ah)
|
||||
case AR2427_DEVID_PCIE:
|
||||
case AR9300_DEVID_PCIE:
|
||||
case AR9300_DEVID_AR9485_PCIE:
|
||||
case AR9300_DEVID_AR9340:
|
||||
break;
|
||||
default:
|
||||
if (common->bus_ops->ath_bus_type == ATH_USB)
|
||||
@ -663,7 +673,7 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
|
||||
REGWRITE_BUFFER_FLUSH(ah);
|
||||
}
|
||||
|
||||
unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
|
||||
u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
|
||||
{
|
||||
REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
|
||||
udelay(100);
|
||||
@ -676,7 +686,6 @@ unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
|
||||
}
|
||||
EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc);
|
||||
|
||||
#define DPLL3_PHASE_SHIFT_VAL 0x1
|
||||
static void ath9k_hw_init_pll(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
@ -713,16 +722,48 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
|
||||
REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
|
||||
AR_CH0_BB_DPLL2_PLL_PWD, 0x0);
|
||||
udelay(1000);
|
||||
} else if (AR_SREV_9340(ah)) {
|
||||
u32 regval, pll2_divint, pll2_divfrac, refdiv;
|
||||
|
||||
REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
|
||||
AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
|
||||
REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
|
||||
udelay(1000);
|
||||
|
||||
REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16);
|
||||
udelay(100);
|
||||
|
||||
if (ah->is_clk_25mhz) {
|
||||
pll2_divint = 0x54;
|
||||
pll2_divfrac = 0x1eb85;
|
||||
refdiv = 3;
|
||||
} else {
|
||||
pll2_divint = 88;
|
||||
pll2_divfrac = 0;
|
||||
refdiv = 5;
|
||||
}
|
||||
|
||||
regval = REG_READ(ah, AR_PHY_PLL_MODE);
|
||||
regval |= (0x1 << 16);
|
||||
REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
|
||||
udelay(100);
|
||||
|
||||
REG_WRITE(ah, AR_PHY_PLL_CONTROL, (refdiv << 27) |
|
||||
(pll2_divint << 18) | pll2_divfrac);
|
||||
udelay(100);
|
||||
|
||||
regval = REG_READ(ah, AR_PHY_PLL_MODE);
|
||||
regval = (regval & 0x80071fff) | (0x1 << 30) | (0x1 << 13) |
|
||||
(0x4 << 26) | (0x18 << 19);
|
||||
REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
|
||||
REG_WRITE(ah, AR_PHY_PLL_MODE,
|
||||
REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff);
|
||||
udelay(1000);
|
||||
}
|
||||
|
||||
pll = ath9k_hw_compute_pll_control(ah, chan);
|
||||
|
||||
REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
|
||||
|
||||
if (AR_SREV_9485(ah))
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
|
||||
udelay(1000);
|
||||
|
||||
/* Switch the core clock for ar9271 to 117Mhz */
|
||||
@ -734,17 +775,34 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
|
||||
udelay(RTC_PLL_SETTLE_DELAY);
|
||||
|
||||
REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
|
||||
|
||||
if (AR_SREV_9340(ah)) {
|
||||
if (ah->is_clk_25mhz) {
|
||||
REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
|
||||
REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
|
||||
REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
|
||||
} else {
|
||||
REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
|
||||
REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
|
||||
REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
|
||||
}
|
||||
udelay(100);
|
||||
}
|
||||
}
|
||||
|
||||
static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
|
||||
enum nl80211_iftype opmode)
|
||||
{
|
||||
u32 sync_default = AR_INTR_SYNC_DEFAULT;
|
||||
u32 imr_reg = AR_IMR_TXERR |
|
||||
AR_IMR_TXURN |
|
||||
AR_IMR_RXERR |
|
||||
AR_IMR_RXORN |
|
||||
AR_IMR_BCNMISC;
|
||||
|
||||
if (AR_SREV_9340(ah))
|
||||
sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
imr_reg |= AR_IMR_RXOK_HP;
|
||||
if (ah->config.rx_intr_mitigation)
|
||||
@ -775,7 +833,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
|
||||
|
||||
if (!AR_SREV_9100(ah)) {
|
||||
REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
|
||||
REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
|
||||
REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
|
||||
REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
|
||||
}
|
||||
|
||||
@ -1487,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);
|
||||
}
|
||||
#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);
|
||||
#endif
|
||||
}
|
||||
@ -1793,7 +1853,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
|
||||
|
||||
u16 capField = 0, eeval;
|
||||
u16 eeval;
|
||||
u8 ant_div_ctl1, tx_chainmask, rx_chainmask;
|
||||
|
||||
eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
|
||||
@ -1804,8 +1864,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||
eeval |= AR9285_RDEXT_DEFAULT;
|
||||
regulatory->current_rd_ext = eeval;
|
||||
|
||||
capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
|
||||
|
||||
if (ah->opmode != NL80211_IFTYPE_AP &&
|
||||
ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
|
||||
if (regulatory->current_rd == 0x64 ||
|
||||
@ -1898,15 +1956,23 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||
else
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
|
||||
|
||||
if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) {
|
||||
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO;
|
||||
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
|
||||
|
||||
if (AR_SREV_9285(ah)) {
|
||||
if (common->btcoex_enabled) {
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
|
||||
btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO;
|
||||
} else {
|
||||
btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
|
||||
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300;
|
||||
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300;
|
||||
btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9300;
|
||||
} else if (AR_SREV_9280_20_OR_LATER(ah)) {
|
||||
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9280;
|
||||
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9280;
|
||||
|
||||
if (AR_SREV_9285(ah)) {
|
||||
btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
|
||||
btcoex_hw->btpriority_gpio =
|
||||
ATH_BTPRIORITY_GPIO_9285;
|
||||
} else {
|
||||
btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
|
||||
@ -2359,11 +2425,11 @@ EXPORT_SYMBOL(ath_gen_timer_alloc);
|
||||
|
||||
void ath9k_hw_gen_timer_start(struct ath_hw *ah,
|
||||
struct ath_gen_timer *timer,
|
||||
u32 timer_next,
|
||||
u32 trig_timeout,
|
||||
u32 timer_period)
|
||||
{
|
||||
struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
|
||||
u32 tsf;
|
||||
u32 tsf, timer_next;
|
||||
|
||||
BUG_ON(!timer_period);
|
||||
|
||||
@ -2371,17 +2437,12 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah,
|
||||
|
||||
tsf = ath9k_hw_gettsf32(ah);
|
||||
|
||||
timer_next = tsf + trig_timeout;
|
||||
|
||||
ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER,
|
||||
"current tsf %x period %x timer_next %x\n",
|
||||
tsf, timer_period, timer_next);
|
||||
|
||||
/*
|
||||
* Pull timer_next forward if the current TSF already passed it
|
||||
* because of software latency
|
||||
*/
|
||||
if (timer_next < tsf)
|
||||
timer_next = tsf + timer_period;
|
||||
|
||||
/*
|
||||
* Program generic timer registers
|
||||
*/
|
||||
|
@ -43,6 +43,7 @@
|
||||
#define AR9287_DEVID_PCI 0x002d
|
||||
#define AR9287_DEVID_PCIE 0x002e
|
||||
#define AR9300_DEVID_PCIE 0x0030
|
||||
#define AR9300_DEVID_AR9340 0x0031
|
||||
#define AR9300_DEVID_AR9485_PCIE 0x0032
|
||||
|
||||
#define AR5416_AR9100_DEVID 0x000b
|
||||
@ -55,6 +56,9 @@
|
||||
#define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa
|
||||
#define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab
|
||||
|
||||
#define AR9300_NUM_BT_WEIGHTS 4
|
||||
#define AR9300_NUM_WLAN_WEIGHTS 4
|
||||
|
||||
#define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1)
|
||||
|
||||
#define ATH_DEFAULT_NOISE_FLOOR -95
|
||||
@ -121,7 +125,7 @@
|
||||
#define AR_GPIO_BIT(_gpio) (1 << (_gpio))
|
||||
|
||||
#define BASE_ACTIVATE_DELAY 100
|
||||
#define RTC_PLL_SETTLE_DELAY 100
|
||||
#define RTC_PLL_SETTLE_DELAY (AR_SREV_9340(ah) ? 1000 : 100)
|
||||
#define COEF_SCALE_S 24
|
||||
#define HT40_CHANNEL_CENTER_SHIFT 10
|
||||
|
||||
@ -771,6 +775,8 @@ struct ath_hw {
|
||||
|
||||
/* Bluetooth coexistance */
|
||||
struct ath_btcoex_hw btcoex_hw;
|
||||
u32 bt_coex_bt_weight[AR9300_NUM_BT_WEIGHTS];
|
||||
u32 bt_coex_wlan_weight[AR9300_NUM_WLAN_WEIGHTS];
|
||||
|
||||
u32 intr_txqs;
|
||||
u8 txchainmask;
|
||||
@ -799,6 +805,7 @@ struct ath_hw {
|
||||
struct ar5416IniArray iniPcieSerdes;
|
||||
struct ar5416IniArray iniPcieSerdesLowPower;
|
||||
struct ar5416IniArray iniModesAdditional;
|
||||
struct ar5416IniArray iniModesAdditional_40M;
|
||||
struct ar5416IniArray iniModesRxGain;
|
||||
struct ar5416IniArray iniModesTxGain;
|
||||
struct ar5416IniArray iniModes_9271_1_0_only;
|
||||
@ -845,6 +852,8 @@ struct ath_hw {
|
||||
|
||||
/* Enterprise mode cap */
|
||||
u32 ent_mode;
|
||||
|
||||
bool is_clk_25mhz;
|
||||
};
|
||||
|
||||
struct ath_bus_ops {
|
||||
@ -928,7 +937,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
|
||||
void ath9k_hw_reset_tsf(struct ath_hw *ah);
|
||||
void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
|
||||
void ath9k_hw_init_global_settings(struct ath_hw *ah);
|
||||
unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
|
||||
u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
|
||||
void ath9k_hw_set11nmac2040(struct ath_hw *ah);
|
||||
void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
|
||||
void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
|
||||
|
@ -574,6 +574,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
|
||||
sc->sc_ah->gpio_mask = pdata->gpio_mask;
|
||||
sc->sc_ah->gpio_val = pdata->gpio_val;
|
||||
sc->sc_ah->led_pin = pdata->led_pin;
|
||||
ah->is_clk_25mhz = pdata->is_clk_25mhz;
|
||||
}
|
||||
|
||||
common = ath9k_hw_common(ah);
|
||||
@ -800,6 +801,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
|
||||
|
||||
INIT_WORK(&sc->hw_check_work, ath_hw_check);
|
||||
INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
|
||||
INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
|
||||
sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
|
||||
|
||||
ath_init_leds(sc);
|
||||
|
@ -812,10 +812,14 @@ EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
|
||||
void ath9k_hw_enable_interrupts(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
u32 sync_default = AR_INTR_SYNC_DEFAULT;
|
||||
|
||||
if (!(ah->imask & ATH9K_INT_GLOBAL))
|
||||
return;
|
||||
|
||||
if (AR_SREV_9340(ah))
|
||||
sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
|
||||
|
||||
ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n");
|
||||
REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
|
||||
if (!AR_SREV_9100(ah)) {
|
||||
@ -824,10 +828,8 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)
|
||||
REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
|
||||
|
||||
|
||||
REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
|
||||
AR_INTR_SYNC_DEFAULT);
|
||||
REG_WRITE(ah, AR_INTR_SYNC_MASK,
|
||||
AR_INTR_SYNC_DEFAULT);
|
||||
REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
|
||||
REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default);
|
||||
}
|
||||
ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
|
||||
REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
|
||||
@ -883,6 +885,9 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
|
||||
mask |= AR_IMR_GENTMR;
|
||||
}
|
||||
|
||||
if (ints & ATH9K_INT_GENTIMER)
|
||||
mask |= AR_IMR_GENTMR;
|
||||
|
||||
if (ints & (ATH9K_INT_BMISC)) {
|
||||
mask |= AR_IMR_BCNMISC;
|
||||
if (ints & ATH9K_INT_TIM)
|
||||
|
@ -624,6 +624,43 @@ out:
|
||||
ath9k_ps_restore(sc);
|
||||
}
|
||||
|
||||
static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
|
||||
{
|
||||
static int count;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
|
||||
if (pll_sqsum >= 0x40000) {
|
||||
count++;
|
||||
if (count == 3) {
|
||||
/* Rx is hung for more than 500ms. Reset it */
|
||||
ath_dbg(common, ATH_DBG_RESET,
|
||||
"Possible RX hang, resetting");
|
||||
ath_reset(sc, true);
|
||||
count = 0;
|
||||
}
|
||||
} else
|
||||
count = 0;
|
||||
}
|
||||
|
||||
void ath_hw_pll_work(struct work_struct *work)
|
||||
{
|
||||
struct ath_softc *sc = container_of(work, struct ath_softc,
|
||||
hw_pll_work.work);
|
||||
u32 pll_sqsum;
|
||||
|
||||
if (AR_SREV_9485(sc->sc_ah)) {
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
ath_hw_pll_rx_hang_check(sc, pll_sqsum);
|
||||
|
||||
ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ath9k_tasklet(unsigned long data)
|
||||
{
|
||||
struct ath_softc *sc = (struct ath_softc *)data;
|
||||
@ -1932,6 +1969,12 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
|
||||
"Bss Info ASSOC %d, bssid: %pM\n",
|
||||
bss_conf->aid, common->curbssid);
|
||||
ath_beacon_config(sc, vif);
|
||||
/*
|
||||
* Request a re-configuration of Beacon related timers
|
||||
* on the receipt of the first Beacon frame (i.e.,
|
||||
* after time sync with the AP).
|
||||
*/
|
||||
sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
|
||||
/* Reset rssi stats */
|
||||
sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
|
||||
sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
|
||||
@ -2219,9 +2262,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
|
||||
int timeout = 200; /* ms */
|
||||
int i, j;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
mutex_lock(&sc->mutex);
|
||||
|
||||
cancel_delayed_work_sync(&sc->tx_complete_work);
|
||||
|
||||
if (drop)
|
||||
@ -2244,15 +2285,15 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
if (!ath_drain_all_txq(sc, false))
|
||||
ath_reset(sc, false);
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
ieee80211_wake_queues(hw);
|
||||
|
||||
out:
|
||||
ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
|
||||
mutex_unlock(&sc->mutex);
|
||||
ath9k_ps_restore(sc);
|
||||
}
|
||||
|
||||
static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
|
||||
|
@ -45,4 +45,7 @@
|
||||
#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
|
||||
#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
|
||||
|
||||
#define AR_PHY_PLL_CONTROL 0x16180
|
||||
#define AR_PHY_PLL_MODE 0x16184
|
||||
|
||||
#endif
|
||||
|
@ -854,14 +854,13 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
|
||||
ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
|
||||
}
|
||||
|
||||
static bool ath_rc_update_per(struct ath_softc *sc,
|
||||
static void ath_rc_update_per(struct ath_softc *sc,
|
||||
const struct ath_rate_table *rate_table,
|
||||
struct ath_rate_priv *ath_rc_priv,
|
||||
struct ieee80211_tx_info *tx_info,
|
||||
int tx_rate, int xretries, int retries,
|
||||
u32 now_msec)
|
||||
{
|
||||
bool state_change = false;
|
||||
int count, n_bad_frames;
|
||||
u8 last_per;
|
||||
static const u32 nretry_to_per_lookup[10] = {
|
||||
@ -992,8 +991,6 @@ static bool ath_rc_update_per(struct ath_softc *sc,
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return state_change;
|
||||
}
|
||||
|
||||
static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
|
||||
@ -1017,7 +1014,6 @@ static void ath_rc_update_ht(struct ath_softc *sc,
|
||||
u32 now_msec = jiffies_to_msecs(jiffies);
|
||||
int rate;
|
||||
u8 last_per;
|
||||
bool state_change = false;
|
||||
const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
|
||||
int size = ath_rc_priv->rate_table_size;
|
||||
|
||||
@ -1027,9 +1023,9 @@ static void ath_rc_update_ht(struct ath_softc *sc,
|
||||
last_per = ath_rc_priv->per[tx_rate];
|
||||
|
||||
/* Update PER first */
|
||||
state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
|
||||
tx_info, tx_rate, xretries,
|
||||
retries, now_msec);
|
||||
ath_rc_update_per(sc, rate_table, ath_rc_priv,
|
||||
tx_info, tx_rate, xretries,
|
||||
retries, now_msec);
|
||||
|
||||
/*
|
||||
* 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)
|
||||
struct ath_hw_antcomb_conf div_ant_conf;
|
||||
struct ath_ant_comb *antcomb = &sc->ant_comb;
|
||||
int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
|
||||
int curr_main_set, curr_bias;
|
||||
int curr_main_set;
|
||||
int main_rssi = rs->rs_rssi_ctl0;
|
||||
int alt_rssi = rs->rs_rssi_ctl1;
|
||||
int rx_ant_conf, main_ant_conf;
|
||||
@ -1393,7 +1393,6 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
|
||||
ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf);
|
||||
curr_alt_set = div_ant_conf.alt_lna_conf;
|
||||
curr_main_set = div_ant_conf.main_lna_conf;
|
||||
curr_bias = div_ant_conf.fast_div_bias;
|
||||
|
||||
antcomb->count++;
|
||||
|
||||
@ -1743,7 +1742,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
|
||||
if ((sc->ps_flags & (PS_WAIT_FOR_BEACON |
|
||||
PS_WAIT_FOR_CAB |
|
||||
PS_WAIT_FOR_PSPOLL_DATA)) ||
|
||||
unlikely(ath9k_check_auto_sleep(sc)))
|
||||
ath9k_check_auto_sleep(sc))
|
||||
ath_rx_ps(sc, skb);
|
||||
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
|
||||
|
||||
|
@ -693,7 +693,7 @@
|
||||
#define AR_RC_APB 0x00000002
|
||||
#define AR_RC_HOSTIF 0x00000100
|
||||
|
||||
#define AR_WA 0x4004
|
||||
#define AR_WA (AR_SREV_9340(ah) ? 0x40c4 : 0x4004)
|
||||
#define AR_WA_BIT6 (1 << 6)
|
||||
#define AR_WA_BIT7 (1 << 7)
|
||||
#define AR_WA_BIT23 (1 << 23)
|
||||
@ -712,7 +712,7 @@
|
||||
#define AR_PM_STATE 0x4008
|
||||
#define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000
|
||||
|
||||
#define AR_HOST_TIMEOUT 0x4018
|
||||
#define AR_HOST_TIMEOUT (AR_SREV_9340(ah) ? 0x4008 : 0x4018)
|
||||
#define AR_HOST_TIMEOUT_APB_CNTR 0x0000FFFF
|
||||
#define AR_HOST_TIMEOUT_APB_CNTR_S 0
|
||||
#define AR_HOST_TIMEOUT_LCL_CNTR 0xFFFF0000
|
||||
@ -742,7 +742,8 @@
|
||||
#define EEPROM_PROTECT_WP_1024_2047 0x8000
|
||||
|
||||
#define AR_SREV \
|
||||
((AR_SREV_9100(ah)) ? 0x0600 : 0x4020)
|
||||
((AR_SREV_9100(ah)) ? 0x0600 : (AR_SREV_9340(ah) \
|
||||
? 0x400c : 0x4020))
|
||||
|
||||
#define AR_SREV_ID \
|
||||
((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF)
|
||||
@ -790,6 +791,7 @@
|
||||
#define AR_SREV_VERSION_9485 0x240
|
||||
#define AR_SREV_REVISION_9485_10 0
|
||||
#define AR_SREV_REVISION_9485_11 1
|
||||
#define AR_SREV_VERSION_9340 0x300
|
||||
|
||||
#define AR_SREV_5416(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
|
||||
@ -868,6 +870,11 @@
|
||||
#define AR_SREV_9485_11(_ah) \
|
||||
(AR_SREV_9485(_ah) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11))
|
||||
#define AR_SREV_9485_OR_LATER(_ah) \
|
||||
(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9485))
|
||||
|
||||
#define AR_SREV_9340(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340))
|
||||
|
||||
#define AR_SREV_9285E_20(_ah) \
|
||||
(AR_SREV_9285_12_OR_LATER(_ah) && \
|
||||
@ -910,11 +917,11 @@ enum ath_usb_dev {
|
||||
#define AR_INTR_SPURIOUS 0xFFFFFFFF
|
||||
|
||||
|
||||
#define AR_INTR_SYNC_CAUSE_CLR 0x4028
|
||||
#define AR_INTR_SYNC_CAUSE (AR_SREV_9340(ah) ? 0x4010 : 0x4028)
|
||||
#define AR_INTR_SYNC_CAUSE_CLR (AR_SREV_9340(ah) ? 0x4010 : 0x4028)
|
||||
|
||||
#define AR_INTR_SYNC_CAUSE 0x4028
|
||||
|
||||
#define AR_INTR_SYNC_ENABLE 0x402c
|
||||
#define AR_INTR_SYNC_ENABLE (AR_SREV_9340(ah) ? 0x4014 : 0x402c)
|
||||
#define AR_INTR_SYNC_ENABLE_GPIO 0xFFFC0000
|
||||
#define AR_INTR_SYNC_ENABLE_GPIO_S 18
|
||||
|
||||
@ -954,24 +961,24 @@ enum {
|
||||
|
||||
};
|
||||
|
||||
#define AR_INTR_ASYNC_MASK 0x4030
|
||||
#define AR_INTR_ASYNC_MASK (AR_SREV_9340(ah) ? 0x4018 : 0x4030)
|
||||
#define AR_INTR_ASYNC_MASK_GPIO 0xFFFC0000
|
||||
#define AR_INTR_ASYNC_MASK_GPIO_S 18
|
||||
|
||||
#define AR_INTR_SYNC_MASK 0x4034
|
||||
#define AR_INTR_SYNC_MASK (AR_SREV_9340(ah) ? 0x401c : 0x4034)
|
||||
#define AR_INTR_SYNC_MASK_GPIO 0xFFFC0000
|
||||
#define AR_INTR_SYNC_MASK_GPIO_S 18
|
||||
|
||||
#define AR_INTR_ASYNC_CAUSE_CLR 0x4038
|
||||
#define AR_INTR_ASYNC_CAUSE 0x4038
|
||||
#define AR_INTR_ASYNC_CAUSE_CLR (AR_SREV_9340(ah) ? 0x4020 : 0x4038)
|
||||
#define AR_INTR_ASYNC_CAUSE (AR_SREV_9340(ah) ? 0x4020 : 0x4038)
|
||||
|
||||
#define AR_INTR_ASYNC_ENABLE 0x403c
|
||||
#define AR_INTR_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4024 : 0x403c)
|
||||
#define AR_INTR_ASYNC_ENABLE_GPIO 0xFFFC0000
|
||||
#define AR_INTR_ASYNC_ENABLE_GPIO_S 18
|
||||
|
||||
#define AR_PCIE_SERDES 0x4040
|
||||
#define AR_PCIE_SERDES2 0x4044
|
||||
#define AR_PCIE_PM_CTRL 0x4014
|
||||
#define AR_PCIE_PM_CTRL (AR_SREV_9340(ah) ? 0x4004 : 0x4014)
|
||||
#define AR_PCIE_PM_CTRL_ENA 0x00080000
|
||||
|
||||
#define AR_NUM_GPIO 14
|
||||
@ -982,7 +989,7 @@ enum {
|
||||
#define AR9300_NUM_GPIO 17
|
||||
#define AR7010_NUM_GPIO 16
|
||||
|
||||
#define AR_GPIO_IN_OUT 0x4048
|
||||
#define AR_GPIO_IN_OUT (AR_SREV_9340(ah) ? 0x4028 : 0x4048)
|
||||
#define AR_GPIO_IN_VAL 0x0FFFC000
|
||||
#define AR_GPIO_IN_VAL_S 14
|
||||
#define AR928X_GPIO_IN_VAL 0x000FFC00
|
||||
@ -996,11 +1003,12 @@ enum {
|
||||
#define AR7010_GPIO_IN_VAL 0x0000FFFF
|
||||
#define AR7010_GPIO_IN_VAL_S 0
|
||||
|
||||
#define AR_GPIO_IN 0x404c
|
||||
#define AR_GPIO_IN (AR_SREV_9340(ah) ? 0x402c : 0x404c)
|
||||
#define AR9300_GPIO_IN_VAL 0x0001FFFF
|
||||
#define AR9300_GPIO_IN_VAL_S 0
|
||||
|
||||
#define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)
|
||||
#define AR_GPIO_OE_OUT (AR_SREV_9340(ah) ? 0x4030 : \
|
||||
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c))
|
||||
#define AR_GPIO_OE_OUT_DRV 0x3
|
||||
#define AR_GPIO_OE_OUT_DRV_NO 0x0
|
||||
#define AR_GPIO_OE_OUT_DRV_LOW 0x1
|
||||
@ -1022,11 +1030,13 @@ enum {
|
||||
#define AR7010_GPIO_INT_MASK 0x52024
|
||||
#define AR7010_GPIO_FUNCTION 0x52028
|
||||
|
||||
#define AR_GPIO_INTR_POL (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050)
|
||||
#define AR_GPIO_INTR_POL (AR_SREV_9340(ah) ? 0x4038 : \
|
||||
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050))
|
||||
#define AR_GPIO_INTR_POL_VAL 0x0001FFFF
|
||||
#define AR_GPIO_INTR_POL_VAL_S 0
|
||||
|
||||
#define AR_GPIO_INPUT_EN_VAL (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054)
|
||||
#define AR_GPIO_INPUT_EN_VAL (AR_SREV_9340(ah) ? 0x403c : \
|
||||
(AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054))
|
||||
#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004
|
||||
#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2
|
||||
#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008
|
||||
@ -1044,13 +1054,15 @@ enum {
|
||||
#define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000
|
||||
#define AR_GPIO_JTAG_DISABLE 0x00020000
|
||||
|
||||
#define AR_GPIO_INPUT_MUX1 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058)
|
||||
#define AR_GPIO_INPUT_MUX1 (AR_SREV_9340(ah) ? 0x4040 : \
|
||||
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058))
|
||||
#define AR_GPIO_INPUT_MUX1_BT_ACTIVE 0x000f0000
|
||||
#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16
|
||||
#define AR_GPIO_INPUT_MUX1_BT_PRIORITY 0x00000f00
|
||||
#define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S 8
|
||||
|
||||
#define AR_GPIO_INPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c)
|
||||
#define AR_GPIO_INPUT_MUX2 (AR_SREV_9340(ah) ? 0x4044 : \
|
||||
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c))
|
||||
#define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f
|
||||
#define AR_GPIO_INPUT_MUX2_CLK25_S 0
|
||||
#define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0
|
||||
@ -1058,13 +1070,18 @@ enum {
|
||||
#define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00
|
||||
#define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8
|
||||
|
||||
#define AR_GPIO_OUTPUT_MUX1 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060)
|
||||
#define AR_GPIO_OUTPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064)
|
||||
#define AR_GPIO_OUTPUT_MUX3 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068)
|
||||
#define AR_GPIO_OUTPUT_MUX1 (AR_SREV_9340(ah) ? 0x4048 : \
|
||||
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060))
|
||||
#define AR_GPIO_OUTPUT_MUX2 (AR_SREV_9340(ah) ? 0x404c : \
|
||||
(AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064))
|
||||
#define AR_GPIO_OUTPUT_MUX3 (AR_SREV_9340(ah) ? 0x4050 : \
|
||||
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068))
|
||||
|
||||
#define AR_INPUT_STATE (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c)
|
||||
#define AR_INPUT_STATE (AR_SREV_9340(ah) ? 0x4054 : \
|
||||
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c))
|
||||
|
||||
#define AR_EEPROM_STATUS_DATA (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c)
|
||||
#define AR_EEPROM_STATUS_DATA (AR_SREV_9340(ah) ? 0x40c8 : \
|
||||
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c))
|
||||
#define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff
|
||||
#define AR_EEPROM_STATUS_DATA_VAL_S 0
|
||||
#define AR_EEPROM_STATUS_DATA_BUSY 0x00010000
|
||||
@ -1072,17 +1089,19 @@ enum {
|
||||
#define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000
|
||||
#define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000
|
||||
|
||||
#define AR_OBS (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080)
|
||||
#define AR_OBS (AR_SREV_9340(ah) ? 0x405c : \
|
||||
(AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080))
|
||||
|
||||
#define AR_GPIO_PDPU (AR_SREV_9300_20_OR_LATER(ah) ? 0x4090 : 0x4088)
|
||||
|
||||
#define AR_PCIE_MSI (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094)
|
||||
#define AR_PCIE_MSI (AR_SREV_9340(ah) ? 0x40d8 : \
|
||||
(AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094))
|
||||
#define AR_PCIE_MSI_ENABLE 0x00000001
|
||||
|
||||
#define AR_INTR_PRIO_SYNC_ENABLE 0x40c4
|
||||
#define AR_INTR_PRIO_ASYNC_MASK 0x40c8
|
||||
#define AR_INTR_PRIO_SYNC_MASK 0x40cc
|
||||
#define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4
|
||||
#define AR_INTR_PRIO_SYNC_ENABLE (AR_SREV_9340(ah) ? 0x4088 : 0x40c4)
|
||||
#define AR_INTR_PRIO_ASYNC_MASK (AR_SREV_9340(ah) ? 0x408c : 0x40c8)
|
||||
#define AR_INTR_PRIO_SYNC_MASK (AR_SREV_9340(ah) ? 0x4090 : 0x40cc)
|
||||
#define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4)
|
||||
#define AR_ENT_OTP 0x40d8
|
||||
#define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000
|
||||
#define AR_ENT_OTP_MPSD 0x00800000
|
||||
@ -1163,6 +1182,7 @@ enum {
|
||||
#define AR_RTC_PLL_REFDIV_5 0x000000c0
|
||||
#define AR_RTC_PLL_CLKSEL 0x00000300
|
||||
#define AR_RTC_PLL_CLKSEL_S 8
|
||||
#define AR_RTC_PLL_BYPASS 0x00010000
|
||||
|
||||
#define PLL3 0x16188
|
||||
#define PLL3_DO_MEAS_MASK 0x40000000
|
||||
@ -1209,7 +1229,8 @@ enum {
|
||||
|
||||
/* RTC_DERIVED_* - only for AR9100 */
|
||||
|
||||
#define AR_RTC_DERIVED_CLK (AR_RTC_BASE + 0x0038)
|
||||
#define AR_RTC_DERIVED_CLK \
|
||||
(AR_SREV_9100(ah) ? (AR_RTC_BASE + 0x0038) : 0x7038)
|
||||
#define AR_RTC_DERIVED_CLK_PERIOD 0x0000fffe
|
||||
#define AR_RTC_DERIVED_CLK_PERIOD_S 1
|
||||
|
||||
@ -1688,6 +1709,22 @@ enum {
|
||||
#define AR_BTCOEX_WL_WGHT 0xffff0000
|
||||
#define AR_BTCOEX_WL_WGHT_S 16
|
||||
|
||||
#define AR_BT_COEX_WL_WEIGHTS0 0x8174
|
||||
#define AR_BT_COEX_WL_WEIGHTS1 0x81c4
|
||||
|
||||
#define AR_BT_COEX_BT_WEIGHTS0 0x83ac
|
||||
#define AR_BT_COEX_BT_WEIGHTS1 0x83b0
|
||||
#define AR_BT_COEX_BT_WEIGHTS2 0x83b4
|
||||
#define AR_BT_COEX_BT_WEIGHTS3 0x83b8
|
||||
|
||||
#define AR9300_BT_WGHT 0xcccc4444
|
||||
#define AR9300_STOMP_ALL_WLAN_WGHT0 0xfffffff0
|
||||
#define AR9300_STOMP_ALL_WLAN_WGHT1 0xfffffff0
|
||||
#define AR9300_STOMP_LOW_WLAN_WGHT0 0x88888880
|
||||
#define AR9300_STOMP_LOW_WLAN_WGHT1 0x88888880
|
||||
#define AR9300_STOMP_NONE_WLAN_WGHT0 0x00000000
|
||||
#define AR9300_STOMP_NONE_WLAN_WGHT1 0x00000000
|
||||
|
||||
#define AR_BT_COEX_MODE2 0x817c
|
||||
#define AR_BT_BCN_MISS_THRESH 0x000000ff
|
||||
#define AR_BT_BCN_MISS_THRESH_S 0
|
||||
|
@ -79,8 +79,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
|
||||
return "WMI_TX_STATS_CMDID";
|
||||
case WMI_RX_STATS_CMDID:
|
||||
return "WMI_RX_STATS_CMDID";
|
||||
case WMI_AGGR_LIMIT_CMD:
|
||||
return "WMI_AGGR_LIMIT_CMD";
|
||||
case WMI_BITRATE_MASK_CMDID:
|
||||
return "WMI_BITRATE_MASK_CMDID";
|
||||
}
|
||||
|
||||
return "Bogus";
|
||||
|
@ -111,7 +111,7 @@ enum wmi_cmd_id {
|
||||
WMI_INT_STATS_CMDID,
|
||||
WMI_TX_STATS_CMDID,
|
||||
WMI_RX_STATS_CMDID,
|
||||
WMI_AGGR_LIMIT_CMD = 0x0026,
|
||||
WMI_BITRATE_MASK_CMDID,
|
||||
};
|
||||
|
||||
enum wmi_event_id {
|
||||
|
@ -2180,28 +2180,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||
}
|
||||
}
|
||||
|
||||
static void ath_hw_pll_work(struct work_struct *work)
|
||||
{
|
||||
struct ath_softc *sc = container_of(work, struct ath_softc,
|
||||
hw_pll_work.work);
|
||||
static int count;
|
||||
|
||||
if (AR_SREV_9485(sc->sc_ah)) {
|
||||
if (ar9003_get_pll_sqsum_dvc(sc->sc_ah) >= 0x40000) {
|
||||
count++;
|
||||
|
||||
if (count == 3) {
|
||||
/* Rx is hung for more than 500ms. Reset it */
|
||||
ath_reset(sc, true);
|
||||
count = 0;
|
||||
}
|
||||
} else
|
||||
count = 0;
|
||||
|
||||
ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
|
||||
}
|
||||
}
|
||||
|
||||
static void ath_tx_complete_poll_work(struct work_struct *work)
|
||||
{
|
||||
struct ath_softc *sc = container_of(work, struct ath_softc,
|
||||
@ -2396,7 +2374,6 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
|
||||
}
|
||||
|
||||
INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
|
||||
INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
error = ath_tx_edma_init(sc);
|
||||
|
@ -448,6 +448,8 @@ struct carl9170_ba_stats {
|
||||
|
||||
struct carl9170_sta_info {
|
||||
bool ht_sta;
|
||||
bool sleeping;
|
||||
atomic_t pending_frames;
|
||||
unsigned int ampdu_max_len;
|
||||
struct carl9170_sta_tid *agg[CARL9170_NUM_TID];
|
||||
struct carl9170_ba_stats stats[CARL9170_NUM_TID];
|
||||
|
@ -1193,6 +1193,8 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw,
|
||||
struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
|
||||
unsigned int i;
|
||||
|
||||
atomic_set(&sta_info->pending_frames, 0);
|
||||
|
||||
if (sta->ht_cap.ht_supported) {
|
||||
if (sta->ht_cap.ampdu_density > 6) {
|
||||
/*
|
||||
@ -1467,99 +1469,17 @@ static void carl9170_op_sta_notify(struct ieee80211_hw *hw,
|
||||
enum sta_notify_cmd cmd,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct ar9170 *ar = hw->priv;
|
||||
struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
|
||||
struct sk_buff *skb, *tmp;
|
||||
struct sk_buff_head free;
|
||||
int i;
|
||||
|
||||
switch (cmd) {
|
||||
case STA_NOTIFY_SLEEP:
|
||||
/*
|
||||
* Since the peer is no longer listening, we have to return
|
||||
* as many SKBs as possible back to the mac80211 stack.
|
||||
* It will deal with the retry procedure, once the peer
|
||||
* has become available again.
|
||||
*
|
||||
* NB: Ideally, the driver should return the all frames in
|
||||
* the correct, ascending order. However, I think that this
|
||||
* functionality should be implemented in the stack and not
|
||||
* here...
|
||||
*/
|
||||
|
||||
__skb_queue_head_init(&free);
|
||||
|
||||
if (sta->ht_cap.ht_supported) {
|
||||
rcu_read_lock();
|
||||
for (i = 0; i < CARL9170_NUM_TID; i++) {
|
||||
struct carl9170_sta_tid *tid_info;
|
||||
|
||||
tid_info = rcu_dereference(sta_info->agg[i]);
|
||||
|
||||
if (!tid_info)
|
||||
continue;
|
||||
|
||||
spin_lock_bh(&ar->tx_ampdu_list_lock);
|
||||
if (tid_info->state >
|
||||
CARL9170_TID_STATE_SUSPEND)
|
||||
tid_info->state =
|
||||
CARL9170_TID_STATE_SUSPEND;
|
||||
spin_unlock_bh(&ar->tx_ampdu_list_lock);
|
||||
|
||||
spin_lock_bh(&tid_info->lock);
|
||||
while ((skb = __skb_dequeue(&tid_info->queue)))
|
||||
__skb_queue_tail(&free, skb);
|
||||
spin_unlock_bh(&tid_info->lock);
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
for (i = 0; i < ar->hw->queues; i++) {
|
||||
spin_lock_bh(&ar->tx_pending[i].lock);
|
||||
skb_queue_walk_safe(&ar->tx_pending[i], skb, tmp) {
|
||||
struct _carl9170_tx_superframe *super;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct ieee80211_tx_info *info;
|
||||
|
||||
super = (void *) skb->data;
|
||||
hdr = (void *) super->frame_data;
|
||||
|
||||
if (compare_ether_addr(hdr->addr1, sta->addr))
|
||||
continue;
|
||||
|
||||
__skb_unlink(skb, &ar->tx_pending[i]);
|
||||
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
if (info->flags & IEEE80211_TX_CTL_AMPDU)
|
||||
atomic_dec(&ar->tx_ampdu_upload);
|
||||
|
||||
carl9170_tx_status(ar, skb, false);
|
||||
}
|
||||
spin_unlock_bh(&ar->tx_pending[i].lock);
|
||||
}
|
||||
|
||||
while ((skb = __skb_dequeue(&free)))
|
||||
carl9170_tx_status(ar, skb, false);
|
||||
|
||||
sta_info->sleeping = true;
|
||||
if (atomic_read(&sta_info->pending_frames))
|
||||
ieee80211_sta_block_awake(hw, sta, true);
|
||||
break;
|
||||
|
||||
case STA_NOTIFY_AWAKE:
|
||||
if (!sta->ht_cap.ht_supported)
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
for (i = 0; i < CARL9170_NUM_TID; i++) {
|
||||
struct carl9170_sta_tid *tid_info;
|
||||
|
||||
tid_info = rcu_dereference(sta_info->agg[i]);
|
||||
|
||||
if (!tid_info)
|
||||
continue;
|
||||
|
||||
if ((tid_info->state == CARL9170_TID_STATE_SUSPEND))
|
||||
tid_info->state = CARL9170_TID_STATE_IDLE;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
sta_info->sleeping = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -104,6 +104,56 @@ static void carl9170_tx_accounting(struct ar9170 *ar, struct sk_buff *skb)
|
||||
spin_unlock_bh(&ar->tx_stats_lock);
|
||||
}
|
||||
|
||||
/* needs rcu_read_lock */
|
||||
static struct ieee80211_sta *__carl9170_get_tx_sta(struct ar9170 *ar,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct _carl9170_tx_superframe *super = (void *) skb->data;
|
||||
struct ieee80211_hdr *hdr = (void *) super->frame_data;
|
||||
struct ieee80211_vif *vif;
|
||||
unsigned int vif_id;
|
||||
|
||||
vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
|
||||
CARL9170_TX_SUPER_MISC_VIF_ID_S;
|
||||
|
||||
if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC))
|
||||
return NULL;
|
||||
|
||||
vif = rcu_dereference(ar->vif_priv[vif_id].vif);
|
||||
if (unlikely(!vif))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Normally we should use wrappers like ieee80211_get_DA to get
|
||||
* the correct peer ieee80211_sta.
|
||||
*
|
||||
* But there is a problem with indirect traffic (broadcasts, or
|
||||
* data which is designated for other stations) in station mode.
|
||||
* The frame will be directed to the AP for distribution and not
|
||||
* to the actual destination.
|
||||
*/
|
||||
|
||||
return ieee80211_find_sta(vif, hdr->addr1);
|
||||
}
|
||||
|
||||
static void carl9170_tx_ps_unblock(struct ar9170 *ar, struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_sta *sta;
|
||||
struct carl9170_sta_info *sta_info;
|
||||
|
||||
rcu_read_lock();
|
||||
sta = __carl9170_get_tx_sta(ar, skb);
|
||||
if (unlikely(!sta))
|
||||
goto out_rcu;
|
||||
|
||||
sta_info = (struct carl9170_sta_info *) sta->drv_priv;
|
||||
if (atomic_dec_return(&sta_info->pending_frames) == 0)
|
||||
ieee80211_sta_block_awake(ar->hw, sta, false);
|
||||
|
||||
out_rcu:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_tx_info *txinfo;
|
||||
@ -135,6 +185,7 @@ static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb)
|
||||
}
|
||||
|
||||
spin_unlock_bh(&ar->tx_stats_lock);
|
||||
|
||||
if (atomic_dec_and_test(&ar->tx_total_queued))
|
||||
complete(&ar->tx_flush);
|
||||
}
|
||||
@ -329,13 +380,10 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
|
||||
{
|
||||
struct _carl9170_tx_superframe *super = (void *) skb->data;
|
||||
struct ieee80211_hdr *hdr = (void *) super->frame_data;
|
||||
struct ieee80211_tx_info *tx_info;
|
||||
struct carl9170_tx_info *ar_info;
|
||||
struct carl9170_sta_info *sta_info;
|
||||
struct ieee80211_sta *sta;
|
||||
struct carl9170_sta_info *sta_info;
|
||||
struct carl9170_sta_tid *tid_info;
|
||||
struct ieee80211_vif *vif;
|
||||
unsigned int vif_id;
|
||||
u8 tid;
|
||||
|
||||
if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) ||
|
||||
@ -343,30 +391,10 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
|
||||
(!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR))))
|
||||
return;
|
||||
|
||||
tx_info = IEEE80211_SKB_CB(skb);
|
||||
ar_info = (void *) tx_info->rate_driver_data;
|
||||
|
||||
vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
|
||||
CARL9170_TX_SUPER_MISC_VIF_ID_S;
|
||||
|
||||
if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC))
|
||||
return;
|
||||
ar_info = (void *) txinfo->rate_driver_data;
|
||||
|
||||
rcu_read_lock();
|
||||
vif = rcu_dereference(ar->vif_priv[vif_id].vif);
|
||||
if (unlikely(!vif))
|
||||
goto out_rcu;
|
||||
|
||||
/*
|
||||
* Normally we should use wrappers like ieee80211_get_DA to get
|
||||
* the correct peer ieee80211_sta.
|
||||
*
|
||||
* But there is a problem with indirect traffic (broadcasts, or
|
||||
* data which is designated for other stations) in station mode.
|
||||
* The frame will be directed to the AP for distribution and not
|
||||
* to the actual destination.
|
||||
*/
|
||||
sta = ieee80211_find_sta(vif, hdr->addr1);
|
||||
sta = __carl9170_get_tx_sta(ar, skb);
|
||||
if (unlikely(!sta))
|
||||
goto out_rcu;
|
||||
|
||||
@ -427,6 +455,7 @@ void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
|
||||
if (txinfo->flags & IEEE80211_TX_CTL_AMPDU)
|
||||
carl9170_tx_status_process_ampdu(ar, skb, txinfo);
|
||||
|
||||
carl9170_tx_ps_unblock(ar, skb);
|
||||
carl9170_tx_put_skb(skb);
|
||||
}
|
||||
|
||||
@ -540,11 +569,7 @@ static void carl9170_tx_ampdu_timeout(struct ar9170 *ar)
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_tx_info *txinfo;
|
||||
struct carl9170_tx_info *arinfo;
|
||||
struct _carl9170_tx_superframe *super;
|
||||
struct ieee80211_sta *sta;
|
||||
struct ieee80211_vif *vif;
|
||||
struct ieee80211_hdr *hdr;
|
||||
unsigned int vif_id;
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) {
|
||||
@ -562,20 +587,7 @@ static void carl9170_tx_ampdu_timeout(struct ar9170 *ar)
|
||||
msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT)))
|
||||
goto unlock;
|
||||
|
||||
super = (void *) skb->data;
|
||||
hdr = (void *) super->frame_data;
|
||||
|
||||
vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
|
||||
CARL9170_TX_SUPER_MISC_VIF_ID_S;
|
||||
|
||||
if (WARN_ON(vif_id >= AR9170_MAX_VIRTUAL_MAC))
|
||||
goto unlock;
|
||||
|
||||
vif = rcu_dereference(ar->vif_priv[vif_id].vif);
|
||||
if (WARN_ON(!vif))
|
||||
goto unlock;
|
||||
|
||||
sta = ieee80211_find_sta(vif, hdr->addr1);
|
||||
sta = __carl9170_get_tx_sta(ar, skb);
|
||||
if (WARN_ON(!sta))
|
||||
goto unlock;
|
||||
|
||||
@ -1199,15 +1211,6 @@ static struct sk_buff *carl9170_tx_pick_skb(struct ar9170 *ar,
|
||||
arinfo = (void *) info->rate_driver_data;
|
||||
|
||||
arinfo->timeout = jiffies;
|
||||
|
||||
/*
|
||||
* increase ref count to "2".
|
||||
* Ref counting is the easiest way to solve the race between
|
||||
* the the urb's completion routine: carl9170_tx_callback and
|
||||
* wlan tx status functions: carl9170_tx_status/janitor.
|
||||
*/
|
||||
carl9170_tx_get_skb(skb);
|
||||
|
||||
return skb;
|
||||
|
||||
err_unlock:
|
||||
@ -1228,6 +1231,36 @@ void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb)
|
||||
__carl9170_tx_process_status(ar, super->s.cookie, q);
|
||||
}
|
||||
|
||||
static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_sta *sta;
|
||||
struct carl9170_sta_info *sta_info;
|
||||
|
||||
rcu_read_lock();
|
||||
sta = __carl9170_get_tx_sta(ar, skb);
|
||||
if (!sta)
|
||||
goto out_rcu;
|
||||
|
||||
sta_info = (void *) sta->drv_priv;
|
||||
if (unlikely(sta_info->sleeping)) {
|
||||
struct ieee80211_tx_info *tx_info;
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
tx_info = IEEE80211_SKB_CB(skb);
|
||||
if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
|
||||
atomic_dec(&ar->tx_ampdu_upload);
|
||||
|
||||
tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
|
||||
carl9170_tx_status(ar, skb, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
out_rcu:
|
||||
rcu_read_unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
static void carl9170_tx(struct ar9170 *ar)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
@ -1247,6 +1280,9 @@ static void carl9170_tx(struct ar9170 *ar)
|
||||
if (unlikely(!skb))
|
||||
break;
|
||||
|
||||
if (unlikely(carl9170_tx_ps_drop(ar, skb)))
|
||||
continue;
|
||||
|
||||
atomic_inc(&ar->tx_total_pending);
|
||||
|
||||
q = __carl9170_get_queue(ar, i);
|
||||
@ -1256,6 +1292,16 @@ static void carl9170_tx(struct ar9170 *ar)
|
||||
*/
|
||||
skb_queue_tail(&ar->tx_status[q], skb);
|
||||
|
||||
/*
|
||||
* increase ref count to "2".
|
||||
* Ref counting is the easiest way to solve the
|
||||
* race between the urb's completion routine:
|
||||
* carl9170_tx_callback
|
||||
* and wlan tx status functions:
|
||||
* carl9170_tx_status/janitor.
|
||||
*/
|
||||
carl9170_tx_get_skb(skb);
|
||||
|
||||
carl9170_usb_tx(ar, skb);
|
||||
schedule_garbagecollector = true;
|
||||
}
|
||||
@ -1368,6 +1414,11 @@ void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
* all ressouces which are associated with the frame.
|
||||
*/
|
||||
|
||||
if (sta) {
|
||||
struct carl9170_sta_info *stai = (void *) sta->drv_priv;
|
||||
atomic_inc(&stai->pending_frames);
|
||||
}
|
||||
|
||||
if (info->flags & IEEE80211_TX_CTL_AMPDU) {
|
||||
run = carl9170_tx_ampdu_queue(ar, sta, skb);
|
||||
if (run)
|
||||
|
@ -2281,6 +2281,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
|
||||
save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
|
||||
save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
|
||||
save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
|
||||
save_regs_phy[8] = 0;
|
||||
} else {
|
||||
save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
|
||||
save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
|
||||
@ -2289,6 +2290,8 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
|
||||
save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
|
||||
save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
|
||||
save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
|
||||
save_regs_phy[7] = 0;
|
||||
save_regs_phy[8] = 0;
|
||||
}
|
||||
|
||||
b43_nphy_rssi_select(dev, 5, type);
|
||||
@ -3845,8 +3848,8 @@ static int b43_nphy_set_channel(struct b43_wldev *dev,
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
||||
const struct b43_nphy_channeltab_entry_rev2 *tabent_r2;
|
||||
const struct b43_nphy_channeltab_entry_rev3 *tabent_r3;
|
||||
const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL;
|
||||
const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL;
|
||||
|
||||
u8 tmp;
|
||||
|
||||
|
@ -955,9 +955,6 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
|
||||
if (priv->cfg->scan_rx_antennas[band])
|
||||
rx_ant = priv->cfg->scan_rx_antennas[band];
|
||||
|
||||
if (priv->cfg->scan_tx_antennas[band])
|
||||
scan_tx_antennas = priv->cfg->scan_tx_antennas[band];
|
||||
|
||||
priv->scan_tx_ant[band] = iwl4965_toggle_tx_ant(priv,
|
||||
priv->scan_tx_ant[band],
|
||||
scan_tx_antennas);
|
||||
|
@ -211,10 +211,7 @@ int iwl_legacy_init_geos(struct iwl_priv *priv)
|
||||
if (!iwl_legacy_is_channel_valid(ch))
|
||||
continue;
|
||||
|
||||
if (iwl_legacy_is_channel_a_band(ch))
|
||||
sband = &priv->bands[IEEE80211_BAND_5GHZ];
|
||||
else
|
||||
sband = &priv->bands[IEEE80211_BAND_2GHZ];
|
||||
sband = &priv->bands[ch->band];
|
||||
|
||||
geo_ch = &sband->channels[sband->n_channels++];
|
||||
|
||||
@ -2117,10 +2114,9 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed)
|
||||
IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
|
||||
channel->hw_value, changed);
|
||||
|
||||
if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
|
||||
test_bit(STATUS_SCANNING, &priv->status))) {
|
||||
if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
|
||||
scan_active = 1;
|
||||
IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
|
||||
IWL_DEBUG_MAC80211(priv, "scan active\n");
|
||||
}
|
||||
|
||||
if (changed & (IEEE80211_CONF_CHANGE_SMPS |
|
||||
@ -2433,11 +2429,13 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw,
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
|
||||
|
||||
if (!iwl_legacy_is_alive(priv))
|
||||
return;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
if (!iwl_legacy_is_alive(priv)) {
|
||||
mutex_unlock(&priv->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (changes & BSS_CHANGED_QOS) {
|
||||
unsigned long flags;
|
||||
|
||||
@ -2646,7 +2644,7 @@ unplugged:
|
||||
|
||||
none:
|
||||
/* re-enable interrupts here since we don't have anything to service. */
|
||||
/* only Re-enable if diabled by irq */
|
||||
/* only Re-enable if disabled by irq */
|
||||
if (test_bit(STATUS_INT_ENABLED, &priv->status))
|
||||
iwl_legacy_enable_interrupts(priv);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
@ -287,7 +287,6 @@ struct iwl_cfg {
|
||||
struct iwl_base_params *base_params;
|
||||
/* params likely to change within a device family */
|
||||
u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
|
||||
u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
|
||||
enum iwl_led_mode led_mode;
|
||||
};
|
||||
|
||||
|
@ -134,7 +134,7 @@ struct iwl_queue {
|
||||
* space more than this */
|
||||
int high_mark; /* high watermark, stop queue if free
|
||||
* space less than this */
|
||||
} __packed;
|
||||
};
|
||||
|
||||
/* One for each TFD */
|
||||
struct iwl_tx_info {
|
||||
@ -290,6 +290,7 @@ enum {
|
||||
CMD_SIZE_HUGE = (1 << 0),
|
||||
CMD_ASYNC = (1 << 1),
|
||||
CMD_WANT_SKB = (1 << 2),
|
||||
CMD_MAPPED = (1 << 3),
|
||||
};
|
||||
|
||||
#define DEF_CMD_PAYLOAD_SIZE 320
|
||||
@ -1076,7 +1077,6 @@ struct iwl_priv {
|
||||
spinlock_t hcmd_lock; /* protect hcmd */
|
||||
spinlock_t reg_lock; /* protect hw register access */
|
||||
struct mutex mutex;
|
||||
struct mutex sync_cmd_mutex; /* enable serialization of sync commands */
|
||||
|
||||
/* basic pci-network driver stuff */
|
||||
struct pci_dev *pci_dev;
|
||||
|
@ -145,6 +145,8 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
|
||||
int cmd_idx;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&priv->mutex);
|
||||
|
||||
BUG_ON(cmd->flags & CMD_ASYNC);
|
||||
|
||||
/* A synchronous command can not have a callback set. */
|
||||
@ -152,7 +154,6 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n",
|
||||
iwl_legacy_get_cmd_string(cmd->id));
|
||||
mutex_lock(&priv->sync_cmd_mutex);
|
||||
|
||||
set_bit(STATUS_HCMD_ACTIVE, &priv->status);
|
||||
IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n",
|
||||
@ -224,7 +225,6 @@ fail:
|
||||
cmd->reply_page = 0;
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&priv->sync_cmd_mutex);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_legacy_send_cmd_sync);
|
||||
|
@ -149,6 +149,12 @@ static inline void iwl_legacy_disable_interrupts(struct iwl_priv *priv)
|
||||
IWL_DEBUG_ISR(priv, "Disabled interrupts\n");
|
||||
}
|
||||
|
||||
static inline void iwl_legacy_enable_rfkill_int(struct iwl_priv *priv)
|
||||
{
|
||||
IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n");
|
||||
iwl_write32(priv, CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
|
||||
}
|
||||
|
||||
static inline void iwl_legacy_enable_interrupts(struct iwl_priv *priv)
|
||||
{
|
||||
IWL_DEBUG_ISR(priv, "Enabling interrupts\n");
|
||||
|
@ -146,33 +146,32 @@ void iwl_legacy_cmd_queue_unmap(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
|
||||
struct iwl_queue *q = &txq->q;
|
||||
bool huge = false;
|
||||
int i;
|
||||
|
||||
if (q->n_bd == 0)
|
||||
return;
|
||||
|
||||
while (q->read_ptr != q->write_ptr) {
|
||||
/* we have no way to tell if it is a huge cmd ATM */
|
||||
i = iwl_legacy_get_cmd_index(q, q->read_ptr, 0);
|
||||
|
||||
if (txq->meta[i].flags & CMD_SIZE_HUGE)
|
||||
huge = true;
|
||||
else
|
||||
if (txq->meta[i].flags & CMD_MAPPED) {
|
||||
pci_unmap_single(priv->pci_dev,
|
||||
dma_unmap_addr(&txq->meta[i], mapping),
|
||||
dma_unmap_len(&txq->meta[i], len),
|
||||
PCI_DMA_BIDIRECTIONAL);
|
||||
txq->meta[i].flags = 0;
|
||||
}
|
||||
|
||||
q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd);
|
||||
}
|
||||
|
||||
if (huge) {
|
||||
i = q->n_window;
|
||||
i = q->n_window;
|
||||
if (txq->meta[i].flags & CMD_MAPPED) {
|
||||
pci_unmap_single(priv->pci_dev,
|
||||
dma_unmap_addr(&txq->meta[i], mapping),
|
||||
dma_unmap_len(&txq->meta[i], len),
|
||||
PCI_DMA_BIDIRECTIONAL);
|
||||
txq->meta[i].flags = 0;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_legacy_cmd_queue_unmap);
|
||||
@ -467,29 +466,27 @@ int iwl_legacy_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (iwl_legacy_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
|
||||
IWL_ERR(priv, "No space in command queue\n");
|
||||
IWL_ERR(priv, "Restarting adapter due to queue full\n");
|
||||
queue_work(priv->workqueue, &priv->restart);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->hcmd_lock, flags);
|
||||
|
||||
/* If this is a huge cmd, mark the huge flag also on the meta.flags
|
||||
* of the _original_ cmd. This is used for DMA mapping clean up.
|
||||
*/
|
||||
if (cmd->flags & CMD_SIZE_HUGE) {
|
||||
idx = iwl_legacy_get_cmd_index(q, q->write_ptr, 0);
|
||||
txq->meta[idx].flags = CMD_SIZE_HUGE;
|
||||
if (iwl_legacy_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
|
||||
spin_unlock_irqrestore(&priv->hcmd_lock, flags);
|
||||
|
||||
IWL_ERR(priv, "Restarting adapter due to command queue full\n");
|
||||
queue_work(priv->workqueue, &priv->restart);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
idx = iwl_legacy_get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
|
||||
out_cmd = txq->cmd[idx];
|
||||
out_meta = &txq->meta[idx];
|
||||
|
||||
if (WARN_ON(out_meta->flags & CMD_MAPPED)) {
|
||||
spin_unlock_irqrestore(&priv->hcmd_lock, flags);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */
|
||||
out_meta->flags = cmd->flags;
|
||||
out_meta->flags = cmd->flags | CMD_MAPPED;
|
||||
if (cmd->flags & CMD_WANT_SKB)
|
||||
out_meta->source = cmd;
|
||||
if (cmd->flags & CMD_ASYNC)
|
||||
@ -610,6 +607,7 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
struct iwl_device_cmd *cmd;
|
||||
struct iwl_cmd_meta *meta;
|
||||
struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
|
||||
unsigned long flags;
|
||||
|
||||
/* If a Tx command is being handled and it isn't in the actual
|
||||
* command queue then there a command routing bug has been introduced
|
||||
@ -623,14 +621,6 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
return;
|
||||
}
|
||||
|
||||
/* If this is a huge cmd, clear the huge flag on the meta.flags
|
||||
* of the _original_ cmd. So that iwl_legacy_cmd_queue_free won't unmap
|
||||
* the DMA buffer for the scan (huge) command.
|
||||
*/
|
||||
if (huge) {
|
||||
cmd_index = iwl_legacy_get_cmd_index(&txq->q, index, 0);
|
||||
txq->meta[cmd_index].flags = 0;
|
||||
}
|
||||
cmd_index = iwl_legacy_get_cmd_index(&txq->q, index, huge);
|
||||
cmd = txq->cmd[cmd_index];
|
||||
meta = &txq->meta[cmd_index];
|
||||
@ -647,6 +637,8 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
} else if (meta->callback)
|
||||
meta->callback(priv, cmd, pkt);
|
||||
|
||||
spin_lock_irqsave(&priv->hcmd_lock, flags);
|
||||
|
||||
iwl_legacy_hcmd_queue_reclaim(priv, txq_id, index, cmd_index);
|
||||
|
||||
if (!(meta->flags & CMD_ASYNC)) {
|
||||
@ -655,6 +647,10 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
iwl_legacy_get_cmd_string(cmd->hdr.cmd));
|
||||
wake_up_interruptible(&priv->wait_command_queue);
|
||||
}
|
||||
|
||||
/* Mark as unmapped */
|
||||
meta->flags = 0;
|
||||
|
||||
spin_unlock_irqrestore(&priv->hcmd_lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_legacy_tx_cmd_complete);
|
||||
|
@ -2748,11 +2748,12 @@ static void iwl3945_bg_init_alive_start(struct work_struct *data)
|
||||
struct iwl_priv *priv =
|
||||
container_of(data, struct iwl_priv, init_alive_start.work);
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
goto out;
|
||||
|
||||
iwl3945_init_alive_start(priv);
|
||||
out:
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
@ -2761,11 +2762,12 @@ static void iwl3945_bg_alive_start(struct work_struct *data)
|
||||
struct iwl_priv *priv =
|
||||
container_of(data, struct iwl_priv, alive_start.work);
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
goto out;
|
||||
|
||||
iwl3945_alive_start(priv);
|
||||
out:
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
@ -2995,10 +2997,12 @@ static void iwl3945_bg_restart(struct work_struct *data)
|
||||
} else {
|
||||
iwl3945_down(priv);
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
|
||||
mutex_unlock(&priv->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
__iwl3945_up(priv);
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
@ -3009,11 +3013,12 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
|
||||
struct iwl_priv *priv =
|
||||
container_of(data, struct iwl_priv, rx_replenish);
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
goto out;
|
||||
|
||||
iwl3945_rx_replenish(priv);
|
||||
out:
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
@ -3810,7 +3815,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
|
||||
INIT_LIST_HEAD(&priv->free_frames);
|
||||
|
||||
mutex_init(&priv->mutex);
|
||||
mutex_init(&priv->sync_cmd_mutex);
|
||||
|
||||
priv->ieee_channels = NULL;
|
||||
priv->ieee_rates = NULL;
|
||||
|
@ -1069,9 +1069,12 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv)
|
||||
}
|
||||
|
||||
/* Re-enable all interrupts */
|
||||
/* only Re-enable if diabled by irq */
|
||||
/* only Re-enable if disabled by irq */
|
||||
if (test_bit(STATUS_INT_ENABLED, &priv->status))
|
||||
iwl_legacy_enable_interrupts(priv);
|
||||
/* Re-enable RF_KILL if it occurred */
|
||||
else if (handled & CSR_INT_BIT_RF_KILL)
|
||||
iwl_legacy_enable_rfkill_int(priv);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
|
||||
if (iwl_legacy_get_debug_level(priv) & (IWL_DL_ISR)) {
|
||||
@ -2139,7 +2142,7 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv);
|
||||
static void __iwl4965_down(struct iwl_priv *priv)
|
||||
{
|
||||
unsigned long flags;
|
||||
int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
|
||||
int exit_pending;
|
||||
|
||||
IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
|
||||
|
||||
@ -2401,11 +2404,12 @@ static void iwl4965_bg_init_alive_start(struct work_struct *data)
|
||||
struct iwl_priv *priv =
|
||||
container_of(data, struct iwl_priv, init_alive_start.work);
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
goto out;
|
||||
|
||||
priv->cfg->ops->lib->init_alive_start(priv);
|
||||
out:
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
@ -2414,11 +2418,12 @@ static void iwl4965_bg_alive_start(struct work_struct *data)
|
||||
struct iwl_priv *priv =
|
||||
container_of(data, struct iwl_priv, alive_start.work);
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
goto out;
|
||||
|
||||
iwl4965_alive_start(priv);
|
||||
out:
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
@ -2468,10 +2473,12 @@ static void iwl4965_bg_restart(struct work_struct *data)
|
||||
} else {
|
||||
iwl4965_down(priv);
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
|
||||
mutex_unlock(&priv->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
__iwl4965_up(priv);
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
@ -2624,9 +2631,10 @@ void iwl4965_mac_stop(struct ieee80211_hw *hw)
|
||||
|
||||
flush_workqueue(priv->workqueue);
|
||||
|
||||
/* enable interrupts again in order to receive rfkill changes */
|
||||
/* User space software may expect getting rfkill changes
|
||||
* even if interface is down */
|
||||
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
|
||||
iwl_legacy_enable_interrupts(priv);
|
||||
iwl_legacy_enable_rfkill_int(priv);
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||
}
|
||||
@ -2847,21 +2855,22 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw,
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "enter\n");
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
if (iwl_legacy_is_rfkill(priv))
|
||||
goto out_exit;
|
||||
goto out;
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
|
||||
test_bit(STATUS_SCANNING, &priv->status))
|
||||
goto out_exit;
|
||||
goto out;
|
||||
|
||||
if (!iwl_legacy_is_associated_ctx(ctx))
|
||||
goto out_exit;
|
||||
goto out;
|
||||
|
||||
/* channel switch in progress */
|
||||
if (priv->switch_rxon.switch_in_progress == true)
|
||||
goto out_exit;
|
||||
goto out;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
if (priv->cfg->ops->lib->set_channel_switch) {
|
||||
|
||||
ch = channel->hw_value;
|
||||
@ -2917,7 +2926,6 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw,
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&priv->mutex);
|
||||
out_exit:
|
||||
if (!priv->switch_rxon.switch_in_progress)
|
||||
ieee80211_chswitch_done(ctx->vif, false);
|
||||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||
@ -3116,7 +3124,6 @@ static int iwl4965_init_drv(struct iwl_priv *priv)
|
||||
INIT_LIST_HEAD(&priv->free_frames);
|
||||
|
||||
mutex_init(&priv->mutex);
|
||||
mutex_init(&priv->sync_cmd_mutex);
|
||||
|
||||
priv->ieee_channels = NULL;
|
||||
priv->ieee_rates = NULL;
|
||||
@ -3406,14 +3413,14 @@ iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
* 8. Enable interrupts and read RFKILL state
|
||||
*********************************************/
|
||||
|
||||
/* enable interrupts if needed: hw bug w/a */
|
||||
/* enable rfkill interrupt: hw bug w/a */
|
||||
pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
|
||||
if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
|
||||
pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
|
||||
pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
|
||||
}
|
||||
|
||||
iwl_legacy_enable_interrupts(priv);
|
||||
iwl_legacy_enable_rfkill_int(priv);
|
||||
|
||||
/* If platform's RF_KILL switch is NOT set to KILL */
|
||||
if (iwl_read32(priv, CSR_GP_CNTRL) &
|
||||
|
@ -14,7 +14,6 @@ iwlagn-objs += iwl-6000.o
|
||||
iwlagn-objs += iwl-1000.o
|
||||
iwlagn-objs += iwl-2000.o
|
||||
|
||||
iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
|
||||
iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
|
||||
iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
|
||||
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include "iwl-agn.h"
|
||||
#include "iwl-helpers.h"
|
||||
#include "iwl-agn-hw.h"
|
||||
#include "iwl-agn-debugfs.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL1000_UCODE_API_MAX 5
|
||||
@ -121,10 +120,10 @@ static struct iwl_sensitivity_ranges iwl1000_sensitivity = {
|
||||
|
||||
static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
|
||||
{
|
||||
if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
|
||||
priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
|
||||
if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
|
||||
iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
|
||||
priv->cfg->base_params->num_of_queues =
|
||||
priv->cfg->mod_params->num_of_queues;
|
||||
iwlagn_mod_params.num_of_queues;
|
||||
|
||||
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
|
||||
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
|
||||
@ -197,21 +196,11 @@ static struct iwl_lib_ops iwl1000_lib = {
|
||||
EEPROM_REG_BAND_24_HT40_CHANNELS,
|
||||
EEPROM_REGULATORY_BAND_NO_HT40,
|
||||
},
|
||||
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
|
||||
.release_semaphore = iwlcore_eeprom_release_semaphore,
|
||||
.calib_version = iwlagn_eeprom_calib_version,
|
||||
.query_addr = iwlagn_eeprom_query_addr,
|
||||
},
|
||||
.temp_ops = {
|
||||
.temperature = iwlagn_temperature,
|
||||
},
|
||||
.debugfs_ops = {
|
||||
.rx_stats_read = iwl_ucode_rx_stats_read,
|
||||
.tx_stats_read = iwl_ucode_tx_stats_read,
|
||||
.general_stats_read = iwl_ucode_general_stats_read,
|
||||
.bt_stats_read = iwl_ucode_bt_stats_read,
|
||||
.reply_tx_error = iwl_reply_tx_error_read,
|
||||
},
|
||||
.txfifo_flush = iwlagn_txfifo_flush,
|
||||
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
|
||||
};
|
||||
@ -249,7 +238,6 @@ static struct iwl_ht_params iwl1000_ht_params = {
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
|
||||
.ops = &iwl1000_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl1000_base_params, \
|
||||
.led_mode = IWL_LED_BLINK
|
||||
|
||||
@ -271,7 +259,6 @@ struct iwl_cfg iwl1000_bg_cfg = {
|
||||
.eeprom_ver = EEPROM_1000_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, \
|
||||
.ops = &iwl1000_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl1000_base_params, \
|
||||
.led_mode = IWL_LED_RF_STATE, \
|
||||
.rx_with_siso_diversity = true
|
||||
|
@ -46,17 +46,16 @@
|
||||
#include "iwl-helpers.h"
|
||||
#include "iwl-agn-hw.h"
|
||||
#include "iwl-6000-hw.h"
|
||||
#include "iwl-agn-debugfs.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL2030_UCODE_API_MAX 5
|
||||
#define IWL2000_UCODE_API_MAX 5
|
||||
#define IWL200_UCODE_API_MAX 5
|
||||
#define IWL105_UCODE_API_MAX 5
|
||||
|
||||
/* Lowest firmware API version supported */
|
||||
#define IWL2030_UCODE_API_MIN 5
|
||||
#define IWL2000_UCODE_API_MIN 5
|
||||
#define IWL200_UCODE_API_MIN 5
|
||||
#define IWL105_UCODE_API_MIN 5
|
||||
|
||||
#define IWL2030_FW_PRE "iwlwifi-2030-"
|
||||
#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode"
|
||||
@ -64,8 +63,8 @@
|
||||
#define IWL2000_FW_PRE "iwlwifi-2000-"
|
||||
#define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode"
|
||||
|
||||
#define IWL200_FW_PRE "iwlwifi-200-"
|
||||
#define IWL200_MODULE_FIRMWARE(api) IWL200_FW_PRE #api ".ucode"
|
||||
#define IWL105_FW_PRE "iwlwifi-105-"
|
||||
#define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE #api ".ucode"
|
||||
|
||||
static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
|
||||
{
|
||||
@ -128,10 +127,10 @@ static struct iwl_sensitivity_ranges iwl2000_sensitivity = {
|
||||
|
||||
static int iwl2000_hw_set_hw_params(struct iwl_priv *priv)
|
||||
{
|
||||
if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
|
||||
priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
|
||||
if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
|
||||
iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
|
||||
priv->cfg->base_params->num_of_queues =
|
||||
priv->cfg->mod_params->num_of_queues;
|
||||
iwlagn_mod_params.num_of_queues;
|
||||
|
||||
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
|
||||
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
|
||||
@ -280,22 +279,12 @@ static struct iwl_lib_ops iwl2000_lib = {
|
||||
EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
|
||||
EEPROM_REGULATORY_BAND_NO_HT40,
|
||||
},
|
||||
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
|
||||
.release_semaphore = iwlcore_eeprom_release_semaphore,
|
||||
.calib_version = iwlagn_eeprom_calib_version,
|
||||
.query_addr = iwlagn_eeprom_query_addr,
|
||||
.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
|
||||
},
|
||||
.temp_ops = {
|
||||
.temperature = iwlagn_temperature,
|
||||
},
|
||||
.debugfs_ops = {
|
||||
.rx_stats_read = iwl_ucode_rx_stats_read,
|
||||
.tx_stats_read = iwl_ucode_tx_stats_read,
|
||||
.general_stats_read = iwl_ucode_general_stats_read,
|
||||
.bt_stats_read = iwl_ucode_bt_stats_read,
|
||||
.reply_tx_error = iwl_reply_tx_error_read,
|
||||
},
|
||||
.txfifo_flush = iwlagn_txfifo_flush,
|
||||
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
|
||||
};
|
||||
@ -312,13 +301,13 @@ static const struct iwl_ops iwl2030_ops = {
|
||||
.utils = &iwlagn_hcmd_utils,
|
||||
};
|
||||
|
||||
static const struct iwl_ops iwl200_ops = {
|
||||
static const struct iwl_ops iwl105_ops = {
|
||||
.lib = &iwl2000_lib,
|
||||
.hcmd = &iwlagn_hcmd,
|
||||
.utils = &iwlagn_hcmd_utils,
|
||||
};
|
||||
|
||||
static const struct iwl_ops iwl230_ops = {
|
||||
static const struct iwl_ops iwl135_ops = {
|
||||
.lib = &iwl2000_lib,
|
||||
.hcmd = &iwlagn_bt_hcmd,
|
||||
.utils = &iwlagn_hcmd_utils,
|
||||
@ -383,7 +372,6 @@ static struct iwl_bt_params iwl2030_bt_params = {
|
||||
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
|
||||
.ops = &iwl2000_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl2000_base_params, \
|
||||
.need_dc_calib = true, \
|
||||
.need_temp_offset_calib = true, \
|
||||
@ -409,7 +397,6 @@ struct iwl_cfg iwl2000_2bg_cfg = {
|
||||
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
|
||||
.ops = &iwl2030_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl2030_base_params, \
|
||||
.bt_params = &iwl2030_bt_params, \
|
||||
.need_dc_calib = true, \
|
||||
@ -429,14 +416,13 @@ struct iwl_cfg iwl2030_2bg_cfg = {
|
||||
IWL_DEVICE_2030,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_200 \
|
||||
.fw_name_pre = IWL200_FW_PRE, \
|
||||
.ucode_api_max = IWL200_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL200_UCODE_API_MIN, \
|
||||
#define IWL_DEVICE_105 \
|
||||
.fw_name_pre = IWL105_FW_PRE, \
|
||||
.ucode_api_max = IWL105_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL105_UCODE_API_MIN, \
|
||||
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
|
||||
.ops = &iwl200_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.ops = &iwl105_ops, \
|
||||
.base_params = &iwl2000_base_params, \
|
||||
.need_dc_calib = true, \
|
||||
.need_temp_offset_calib = true, \
|
||||
@ -444,25 +430,24 @@ struct iwl_cfg iwl2030_2bg_cfg = {
|
||||
.adv_pm = true, \
|
||||
.rx_with_siso_diversity = true \
|
||||
|
||||
struct iwl_cfg iwl200_bg_cfg = {
|
||||
.name = "200 Series 1x1 BG",
|
||||
IWL_DEVICE_200,
|
||||
struct iwl_cfg iwl105_bg_cfg = {
|
||||
.name = "105 Series 1x1 BG",
|
||||
IWL_DEVICE_105,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl200_bgn_cfg = {
|
||||
.name = "200 Series 1x1 BGN",
|
||||
IWL_DEVICE_200,
|
||||
struct iwl_cfg iwl105_bgn_cfg = {
|
||||
.name = "105 Series 1x1 BGN",
|
||||
IWL_DEVICE_105,
|
||||
.ht_params = &iwl2000_ht_params,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_230 \
|
||||
.fw_name_pre = IWL200_FW_PRE, \
|
||||
.ucode_api_max = IWL200_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL200_UCODE_API_MIN, \
|
||||
#define IWL_DEVICE_135 \
|
||||
.fw_name_pre = IWL105_FW_PRE, \
|
||||
.ucode_api_max = IWL105_UCODE_API_MAX, \
|
||||
.ucode_api_min = IWL105_UCODE_API_MIN, \
|
||||
.eeprom_ver = EEPROM_2000_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION, \
|
||||
.ops = &iwl230_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.ops = &iwl135_ops, \
|
||||
.base_params = &iwl2030_base_params, \
|
||||
.bt_params = &iwl2030_bt_params, \
|
||||
.need_dc_calib = true, \
|
||||
@ -471,17 +456,17 @@ struct iwl_cfg iwl200_bgn_cfg = {
|
||||
.adv_pm = true, \
|
||||
.rx_with_siso_diversity = true \
|
||||
|
||||
struct iwl_cfg iwl230_bg_cfg = {
|
||||
.name = "200 Series 1x1 BG/BT",
|
||||
IWL_DEVICE_230,
|
||||
struct iwl_cfg iwl135_bg_cfg = {
|
||||
.name = "105 Series 1x1 BG/BT",
|
||||
IWL_DEVICE_135,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl230_bgn_cfg = {
|
||||
.name = "200 Series 1x1 BGN/BT",
|
||||
IWL_DEVICE_230,
|
||||
struct iwl_cfg iwl135_bgn_cfg = {
|
||||
.name = "105 Series 1x1 BGN/BT",
|
||||
IWL_DEVICE_135,
|
||||
.ht_params = &iwl2000_ht_params,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL200_MODULE_FIRMWARE(IWL200_UCODE_API_MAX));
|
||||
MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX));
|
||||
|
@ -47,7 +47,6 @@
|
||||
#include "iwl-agn.h"
|
||||
#include "iwl-agn-hw.h"
|
||||
#include "iwl-5000-hw.h"
|
||||
#include "iwl-agn-debugfs.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL5000_UCODE_API_MAX 5
|
||||
@ -165,10 +164,10 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
|
||||
|
||||
static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
|
||||
{
|
||||
if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
|
||||
priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
|
||||
if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
|
||||
iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
|
||||
priv->cfg->base_params->num_of_queues =
|
||||
priv->cfg->mod_params->num_of_queues;
|
||||
iwlagn_mod_params.num_of_queues;
|
||||
|
||||
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
|
||||
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
|
||||
@ -210,10 +209,10 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
|
||||
|
||||
static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
|
||||
{
|
||||
if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
|
||||
priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
|
||||
if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
|
||||
iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
|
||||
priv->cfg->base_params->num_of_queues =
|
||||
priv->cfg->mod_params->num_of_queues;
|
||||
iwlagn_mod_params.num_of_queues;
|
||||
|
||||
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
|
||||
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
|
||||
@ -366,21 +365,11 @@ static struct iwl_lib_ops iwl5000_lib = {
|
||||
EEPROM_REG_BAND_24_HT40_CHANNELS,
|
||||
EEPROM_REG_BAND_52_HT40_CHANNELS
|
||||
},
|
||||
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
|
||||
.release_semaphore = iwlcore_eeprom_release_semaphore,
|
||||
.calib_version = iwlagn_eeprom_calib_version,
|
||||
.query_addr = iwlagn_eeprom_query_addr,
|
||||
},
|
||||
.temp_ops = {
|
||||
.temperature = iwlagn_temperature,
|
||||
},
|
||||
.debugfs_ops = {
|
||||
.rx_stats_read = iwl_ucode_rx_stats_read,
|
||||
.tx_stats_read = iwl_ucode_tx_stats_read,
|
||||
.general_stats_read = iwl_ucode_general_stats_read,
|
||||
.bt_stats_read = iwl_ucode_bt_stats_read,
|
||||
.reply_tx_error = iwl_reply_tx_error_read,
|
||||
},
|
||||
.txfifo_flush = iwlagn_txfifo_flush,
|
||||
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
|
||||
};
|
||||
@ -413,21 +402,11 @@ static struct iwl_lib_ops iwl5150_lib = {
|
||||
EEPROM_REG_BAND_24_HT40_CHANNELS,
|
||||
EEPROM_REG_BAND_52_HT40_CHANNELS
|
||||
},
|
||||
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
|
||||
.release_semaphore = iwlcore_eeprom_release_semaphore,
|
||||
.calib_version = iwlagn_eeprom_calib_version,
|
||||
.query_addr = iwlagn_eeprom_query_addr,
|
||||
},
|
||||
.temp_ops = {
|
||||
.temperature = iwl5150_temperature,
|
||||
},
|
||||
.debugfs_ops = {
|
||||
.rx_stats_read = iwl_ucode_rx_stats_read,
|
||||
.tx_stats_read = iwl_ucode_tx_stats_read,
|
||||
.general_stats_read = iwl_ucode_general_stats_read,
|
||||
.bt_stats_read = iwl_ucode_bt_stats_read,
|
||||
.reply_tx_error = iwl_reply_tx_error_read,
|
||||
},
|
||||
.txfifo_flush = iwlagn_txfifo_flush,
|
||||
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
|
||||
};
|
||||
@ -468,7 +447,6 @@ static struct iwl_ht_params iwl5000_ht_params = {
|
||||
.eeprom_ver = EEPROM_5000_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, \
|
||||
.ops = &iwl5000_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl5000_base_params, \
|
||||
.led_mode = IWL_LED_BLINK
|
||||
|
||||
@ -512,7 +490,6 @@ struct iwl_cfg iwl5350_agn_cfg = {
|
||||
.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
|
||||
.ops = &iwl5000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl5000_base_params,
|
||||
.ht_params = &iwl5000_ht_params,
|
||||
.led_mode = IWL_LED_BLINK,
|
||||
@ -526,7 +503,6 @@ struct iwl_cfg iwl5350_agn_cfg = {
|
||||
.eeprom_ver = EEPROM_5050_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, \
|
||||
.ops = &iwl5150_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl5000_base_params, \
|
||||
.need_dc_calib = true, \
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include "iwl-helpers.h"
|
||||
#include "iwl-agn-hw.h"
|
||||
#include "iwl-6000-hw.h"
|
||||
#include "iwl-agn-debugfs.h"
|
||||
|
||||
/* Highest firmware API version supported */
|
||||
#define IWL6000_UCODE_API_MAX 4
|
||||
@ -80,7 +79,7 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
|
||||
static void iwl6050_additional_nic_config(struct iwl_priv *priv)
|
||||
{
|
||||
/* Indicate calibration version to uCode. */
|
||||
if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
|
||||
if (iwlagn_eeprom_calib_version(priv) >= 6)
|
||||
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
|
||||
CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
|
||||
}
|
||||
@ -88,7 +87,7 @@ static void iwl6050_additional_nic_config(struct iwl_priv *priv)
|
||||
static void iwl6150_additional_nic_config(struct iwl_priv *priv)
|
||||
{
|
||||
/* Indicate calibration version to uCode. */
|
||||
if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
|
||||
if (iwlagn_eeprom_calib_version(priv) >= 6)
|
||||
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
|
||||
CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
|
||||
iwl_set_bit(priv, CSR_GP_DRIVER_REG,
|
||||
@ -154,10 +153,10 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = {
|
||||
|
||||
static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
|
||||
{
|
||||
if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
|
||||
priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
|
||||
if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
|
||||
iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
|
||||
priv->cfg->base_params->num_of_queues =
|
||||
priv->cfg->mod_params->num_of_queues;
|
||||
iwlagn_mod_params.num_of_queues;
|
||||
|
||||
priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
|
||||
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
|
||||
@ -305,22 +304,12 @@ static struct iwl_lib_ops iwl6000_lib = {
|
||||
EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
|
||||
EEPROM_REG_BAND_52_HT40_CHANNELS
|
||||
},
|
||||
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
|
||||
.release_semaphore = iwlcore_eeprom_release_semaphore,
|
||||
.calib_version = iwlagn_eeprom_calib_version,
|
||||
.query_addr = iwlagn_eeprom_query_addr,
|
||||
.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
|
||||
},
|
||||
.temp_ops = {
|
||||
.temperature = iwlagn_temperature,
|
||||
},
|
||||
.debugfs_ops = {
|
||||
.rx_stats_read = iwl_ucode_rx_stats_read,
|
||||
.tx_stats_read = iwl_ucode_tx_stats_read,
|
||||
.general_stats_read = iwl_ucode_general_stats_read,
|
||||
.bt_stats_read = iwl_ucode_bt_stats_read,
|
||||
.reply_tx_error = iwl_reply_tx_error_read,
|
||||
},
|
||||
.txfifo_flush = iwlagn_txfifo_flush,
|
||||
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
|
||||
};
|
||||
@ -354,22 +343,12 @@ static struct iwl_lib_ops iwl6030_lib = {
|
||||
EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
|
||||
EEPROM_REG_BAND_52_HT40_CHANNELS
|
||||
},
|
||||
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
|
||||
.release_semaphore = iwlcore_eeprom_release_semaphore,
|
||||
.calib_version = iwlagn_eeprom_calib_version,
|
||||
.query_addr = iwlagn_eeprom_query_addr,
|
||||
.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
|
||||
},
|
||||
.temp_ops = {
|
||||
.temperature = iwlagn_temperature,
|
||||
},
|
||||
.debugfs_ops = {
|
||||
.rx_stats_read = iwl_ucode_rx_stats_read,
|
||||
.tx_stats_read = iwl_ucode_tx_stats_read,
|
||||
.general_stats_read = iwl_ucode_general_stats_read,
|
||||
.bt_stats_read = iwl_ucode_bt_stats_read,
|
||||
.reply_tx_error = iwl_reply_tx_error_read,
|
||||
},
|
||||
.txfifo_flush = iwlagn_txfifo_flush,
|
||||
.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
|
||||
};
|
||||
@ -482,7 +461,6 @@ static struct iwl_bt_params iwl6000_bt_params = {
|
||||
.eeprom_ver = EEPROM_6005_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION, \
|
||||
.ops = &iwl6000_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl6000_g2_base_params, \
|
||||
.need_dc_calib = true, \
|
||||
.need_temp_offset_calib = true, \
|
||||
@ -511,7 +489,6 @@ struct iwl_cfg iwl6005_2bg_cfg = {
|
||||
.eeprom_ver = EEPROM_6030_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION, \
|
||||
.ops = &iwl6030_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl6000_g2_base_params, \
|
||||
.bt_params = &iwl6000_bt_params, \
|
||||
.need_dc_calib = true, \
|
||||
@ -593,7 +570,6 @@ struct iwl_cfg iwl130_bg_cfg = {
|
||||
.eeprom_ver = EEPROM_6000_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, \
|
||||
.ops = &iwl6000_ops, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl6000_base_params, \
|
||||
.pa_type = IWL_PA_INTERNAL, \
|
||||
.led_mode = IWL_LED_BLINK
|
||||
@ -623,7 +599,6 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
|
||||
.ops = &iwl6050_ops, \
|
||||
.eeprom_ver = EEPROM_6050_EEPROM_VERSION, \
|
||||
.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, \
|
||||
.mod_params = &iwlagn_mod_params, \
|
||||
.base_params = &iwl6050_base_params, \
|
||||
.need_dc_calib = true, \
|
||||
.led_mode = IWL_LED_BLINK, \
|
||||
@ -648,7 +623,6 @@ struct iwl_cfg iwl6150_bgn_cfg = {
|
||||
.eeprom_ver = EEPROM_6150_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION,
|
||||
.ops = &iwl6150_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6050_base_params,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
@ -664,7 +638,6 @@ struct iwl_cfg iwl6000_3agn_cfg = {
|
||||
.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
|
||||
.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
|
||||
.ops = &iwl6000_ops,
|
||||
.mod_params = &iwlagn_mod_params,
|
||||
.base_params = &iwl6000_base_params,
|
||||
.ht_params = &iwl6000_ht_params,
|
||||
.need_dc_calib = true,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,70 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
|
||||
* USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called LICENSE.GPL.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*****************************************************************************/
|
||||
|
||||
#include "iwl-dev.h"
|
||||
#include "iwl-core.h"
|
||||
#include "iwl-debug.h"
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
#else
|
||||
static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
@ -81,52 +81,13 @@
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* The device's EEPROM semaphore prevents conflicts between driver and uCode
|
||||
* when accessing the EEPROM; each access is a series of pulses to/from the
|
||||
* EEPROM chip, not a single event, so even reads could conflict if they
|
||||
* weren't arbitrated by the semaphore.
|
||||
*/
|
||||
int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
|
||||
{
|
||||
u16 count;
|
||||
int ret;
|
||||
|
||||
for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
|
||||
/* Request semaphore */
|
||||
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
|
||||
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
|
||||
|
||||
/* See if we got it */
|
||||
ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
|
||||
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
|
||||
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
|
||||
EEPROM_SEM_TIMEOUT);
|
||||
if (ret >= 0) {
|
||||
IWL_DEBUG_EEPROM(priv,
|
||||
"Acquired semaphore after %d tries.\n",
|
||||
count+1);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv)
|
||||
{
|
||||
iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
|
||||
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
|
||||
|
||||
}
|
||||
|
||||
int iwl_eeprom_check_version(struct iwl_priv *priv)
|
||||
{
|
||||
u16 eeprom_ver;
|
||||
u16 calib_ver;
|
||||
|
||||
eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
|
||||
calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv);
|
||||
calib_ver = iwlagn_eeprom_calib_version(priv);
|
||||
|
||||
if (eeprom_ver < priv->cfg->eeprom_ver ||
|
||||
calib_ver < priv->cfg->eeprom_calib_ver)
|
||||
|
@ -37,54 +37,6 @@
|
||||
#include "iwl-io.h"
|
||||
#include "iwl-agn.h"
|
||||
|
||||
int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
struct iwl5000_rxon_assoc_cmd rxon_assoc;
|
||||
const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
|
||||
const struct iwl_rxon_cmd *rxon2 = &ctx->active;
|
||||
|
||||
if ((rxon1->flags == rxon2->flags) &&
|
||||
(rxon1->filter_flags == rxon2->filter_flags) &&
|
||||
(rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
|
||||
(rxon1->ofdm_ht_single_stream_basic_rates ==
|
||||
rxon2->ofdm_ht_single_stream_basic_rates) &&
|
||||
(rxon1->ofdm_ht_dual_stream_basic_rates ==
|
||||
rxon2->ofdm_ht_dual_stream_basic_rates) &&
|
||||
(rxon1->ofdm_ht_triple_stream_basic_rates ==
|
||||
rxon2->ofdm_ht_triple_stream_basic_rates) &&
|
||||
(rxon1->acquisition_data == rxon2->acquisition_data) &&
|
||||
(rxon1->rx_chain == rxon2->rx_chain) &&
|
||||
(rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
|
||||
IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rxon_assoc.flags = ctx->staging.flags;
|
||||
rxon_assoc.filter_flags = ctx->staging.filter_flags;
|
||||
rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
|
||||
rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
|
||||
rxon_assoc.reserved1 = 0;
|
||||
rxon_assoc.reserved2 = 0;
|
||||
rxon_assoc.reserved3 = 0;
|
||||
rxon_assoc.ofdm_ht_single_stream_basic_rates =
|
||||
ctx->staging.ofdm_ht_single_stream_basic_rates;
|
||||
rxon_assoc.ofdm_ht_dual_stream_basic_rates =
|
||||
ctx->staging.ofdm_ht_dual_stream_basic_rates;
|
||||
rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
|
||||
rxon_assoc.ofdm_ht_triple_stream_basic_rates =
|
||||
ctx->staging.ofdm_ht_triple_stream_basic_rates;
|
||||
rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
|
||||
|
||||
ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd,
|
||||
sizeof(rxon_assoc), &rxon_assoc, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
|
||||
{
|
||||
struct iwl_tx_ant_config_cmd tx_ant_cmd = {
|
||||
@ -364,7 +316,6 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
|
||||
}
|
||||
|
||||
struct iwl_hcmd_ops iwlagn_hcmd = {
|
||||
.rxon_assoc = iwlagn_send_rxon_assoc,
|
||||
.commit_rxon = iwlagn_commit_rxon,
|
||||
.set_rxon_chain = iwlagn_set_rxon_chain,
|
||||
.set_tx_ant = iwlagn_send_tx_ant_config,
|
||||
@ -373,7 +324,6 @@ struct iwl_hcmd_ops iwlagn_hcmd = {
|
||||
};
|
||||
|
||||
struct iwl_hcmd_ops iwlagn_bt_hcmd = {
|
||||
.rxon_assoc = iwlagn_send_rxon_assoc,
|
||||
.commit_rxon = iwlagn_commit_rxon,
|
||||
.set_rxon_chain = iwlagn_set_rxon_chain,
|
||||
.set_tx_ant = iwlagn_send_tx_ant_config,
|
||||
|
@ -483,8 +483,6 @@ void iwlagn_rx_handler_setup(struct iwl_priv *priv)
|
||||
/* init calibration handlers */
|
||||
priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] =
|
||||
iwlagn_rx_calib_result;
|
||||
priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] =
|
||||
iwlagn_rx_calib_complete;
|
||||
priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx;
|
||||
|
||||
/* set up notification wait support */
|
||||
@ -667,7 +665,7 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
|
||||
|
||||
rb_timeout = RX_RB_TIMEOUT;
|
||||
|
||||
if (priv->cfg->mod_params->amsdu_size_8K)
|
||||
if (iwlagn_mod_params.amsdu_size_8K)
|
||||
rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
|
||||
else
|
||||
rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
|
||||
@ -1296,9 +1294,17 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
|
||||
* mean we never reach it, but at the same time work around
|
||||
* the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
|
||||
* here instead of IWL_GOOD_CRC_TH_DISABLED.
|
||||
*
|
||||
* This was fixed in later versions along with some other
|
||||
* scan changes, and the threshold behaves as a flag in those
|
||||
* versions.
|
||||
*/
|
||||
scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
|
||||
IWL_GOOD_CRC_TH_NEVER;
|
||||
if (priv->new_scan_threshold_behaviour)
|
||||
scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
|
||||
IWL_GOOD_CRC_TH_DISABLED;
|
||||
else
|
||||
scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
|
||||
IWL_GOOD_CRC_TH_NEVER;
|
||||
|
||||
band = priv->scan_band;
|
||||
|
||||
@ -2256,34 +2262,44 @@ int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
|
||||
/* notification wait support */
|
||||
void iwlagn_init_notification_wait(struct iwl_priv *priv,
|
||||
struct iwl_notification_wait *wait_entry,
|
||||
u8 cmd,
|
||||
void (*fn)(struct iwl_priv *priv,
|
||||
struct iwl_rx_packet *pkt),
|
||||
u8 cmd)
|
||||
struct iwl_rx_packet *pkt,
|
||||
void *data),
|
||||
void *fn_data)
|
||||
{
|
||||
wait_entry->fn = fn;
|
||||
wait_entry->fn_data = fn_data;
|
||||
wait_entry->cmd = cmd;
|
||||
wait_entry->triggered = false;
|
||||
wait_entry->aborted = false;
|
||||
|
||||
spin_lock_bh(&priv->_agn.notif_wait_lock);
|
||||
list_add(&wait_entry->list, &priv->_agn.notif_waits);
|
||||
spin_unlock_bh(&priv->_agn.notif_wait_lock);
|
||||
}
|
||||
|
||||
signed long iwlagn_wait_notification(struct iwl_priv *priv,
|
||||
struct iwl_notification_wait *wait_entry,
|
||||
unsigned long timeout)
|
||||
int iwlagn_wait_notification(struct iwl_priv *priv,
|
||||
struct iwl_notification_wait *wait_entry,
|
||||
unsigned long timeout)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = wait_event_timeout(priv->_agn.notif_waitq,
|
||||
wait_entry->triggered,
|
||||
wait_entry->triggered || wait_entry->aborted,
|
||||
timeout);
|
||||
|
||||
spin_lock_bh(&priv->_agn.notif_wait_lock);
|
||||
list_del(&wait_entry->list);
|
||||
spin_unlock_bh(&priv->_agn.notif_wait_lock);
|
||||
|
||||
return ret;
|
||||
if (wait_entry->aborted)
|
||||
return -EIO;
|
||||
|
||||
/* return value is always >= 0 */
|
||||
if (ret <= 0)
|
||||
return -ETIMEDOUT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void iwlagn_remove_notification(struct iwl_priv *priv,
|
||||
@ -2293,3 +2309,87 @@ void iwlagn_remove_notification(struct iwl_priv *priv,
|
||||
list_del(&wait_entry->list);
|
||||
spin_unlock_bh(&priv->_agn.notif_wait_lock);
|
||||
}
|
||||
|
||||
int iwlagn_start_device(struct iwl_priv *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (iwl_prepare_card_hw(priv)) {
|
||||
IWL_WARN(priv, "Exit HW not ready\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* If platform's RF_KILL switch is NOT set to KILL */
|
||||
if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
|
||||
clear_bit(STATUS_RF_KILL_HW, &priv->status);
|
||||
else
|
||||
set_bit(STATUS_RF_KILL_HW, &priv->status);
|
||||
|
||||
if (iwl_is_rfkill(priv)) {
|
||||
wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
|
||||
iwl_enable_interrupts(priv);
|
||||
return -ERFKILL;
|
||||
}
|
||||
|
||||
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
|
||||
|
||||
ret = iwlagn_hw_nic_init(priv);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Unable to init nic\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* make sure rfkill handshake bits are cleared */
|
||||
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
||||
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
|
||||
CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
|
||||
|
||||
/* clear (again), then enable host interrupts */
|
||||
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
|
||||
iwl_enable_interrupts(priv);
|
||||
|
||||
/* really make sure rfkill handshake bits are cleared */
|
||||
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
||||
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void iwlagn_stop_device(struct iwl_priv *priv)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/* stop and reset the on-board processor */
|
||||
iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
|
||||
|
||||
/* tell the device to stop sending interrupts */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
iwl_disable_interrupts(priv);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
iwl_synchronize_irq(priv);
|
||||
|
||||
/* device going down, Stop using ICT table */
|
||||
iwl_disable_ict(priv);
|
||||
|
||||
/*
|
||||
* If a HW restart happens during firmware loading,
|
||||
* then the firmware loading might call this function
|
||||
* and later it might be called again due to the
|
||||
* restart. So don't process again if the device is
|
||||
* already dead.
|
||||
*/
|
||||
if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) {
|
||||
iwlagn_txq_ctx_stop(priv);
|
||||
iwlagn_rxq_stop(priv);
|
||||
|
||||
/* Power-down device's busmaster DMA clocks */
|
||||
iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
|
||||
udelay(5);
|
||||
}
|
||||
|
||||
/* Make sure (redundant) we've released our request to stay awake */
|
||||
iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
|
||||
/* Stop the device, and put it in low power state */
|
||||
iwl_apm_stop(priv);
|
||||
}
|
||||
|
@ -58,8 +58,9 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
|
||||
u8 old_dev_type = send->dev_type;
|
||||
int ret;
|
||||
|
||||
iwlagn_init_notification_wait(priv, &disable_wait, NULL,
|
||||
REPLY_WIPAN_DEACTIVATION_COMPLETE);
|
||||
iwlagn_init_notification_wait(priv, &disable_wait,
|
||||
REPLY_WIPAN_DEACTIVATION_COMPLETE,
|
||||
NULL, NULL);
|
||||
|
||||
send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
|
||||
send->dev_type = RXON_DEV_TYPE_P2P;
|
||||
@ -72,13 +73,9 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
|
||||
IWL_ERR(priv, "Error disabling PAN (%d)\n", ret);
|
||||
iwlagn_remove_notification(priv, &disable_wait);
|
||||
} else {
|
||||
signed long wait_res;
|
||||
|
||||
wait_res = iwlagn_wait_notification(priv, &disable_wait, HZ);
|
||||
if (wait_res == 0) {
|
||||
ret = iwlagn_wait_notification(priv, &disable_wait, HZ);
|
||||
if (ret)
|
||||
IWL_ERR(priv, "Timed out waiting for PAN disable\n");
|
||||
ret = -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -124,6 +121,151 @@ static int iwlagn_update_beacon(struct iwl_priv *priv,
|
||||
return iwlagn_send_beacon_cmd(priv);
|
||||
}
|
||||
|
||||
static int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
struct iwl_rxon_assoc_cmd rxon_assoc;
|
||||
const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
|
||||
const struct iwl_rxon_cmd *rxon2 = &ctx->active;
|
||||
|
||||
if ((rxon1->flags == rxon2->flags) &&
|
||||
(rxon1->filter_flags == rxon2->filter_flags) &&
|
||||
(rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
|
||||
(rxon1->ofdm_ht_single_stream_basic_rates ==
|
||||
rxon2->ofdm_ht_single_stream_basic_rates) &&
|
||||
(rxon1->ofdm_ht_dual_stream_basic_rates ==
|
||||
rxon2->ofdm_ht_dual_stream_basic_rates) &&
|
||||
(rxon1->ofdm_ht_triple_stream_basic_rates ==
|
||||
rxon2->ofdm_ht_triple_stream_basic_rates) &&
|
||||
(rxon1->acquisition_data == rxon2->acquisition_data) &&
|
||||
(rxon1->rx_chain == rxon2->rx_chain) &&
|
||||
(rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
|
||||
IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC. Not resending.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rxon_assoc.flags = ctx->staging.flags;
|
||||
rxon_assoc.filter_flags = ctx->staging.filter_flags;
|
||||
rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
|
||||
rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
|
||||
rxon_assoc.reserved1 = 0;
|
||||
rxon_assoc.reserved2 = 0;
|
||||
rxon_assoc.reserved3 = 0;
|
||||
rxon_assoc.ofdm_ht_single_stream_basic_rates =
|
||||
ctx->staging.ofdm_ht_single_stream_basic_rates;
|
||||
rxon_assoc.ofdm_ht_dual_stream_basic_rates =
|
||||
ctx->staging.ofdm_ht_dual_stream_basic_rates;
|
||||
rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
|
||||
rxon_assoc.ofdm_ht_triple_stream_basic_rates =
|
||||
ctx->staging.ofdm_ht_triple_stream_basic_rates;
|
||||
rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
|
||||
|
||||
ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd,
|
||||
sizeof(rxon_assoc), &rxon_assoc, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwlagn_rxon_disconn(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx)
|
||||
{
|
||||
int ret;
|
||||
struct iwl_rxon_cmd *active = (void *)&ctx->active;
|
||||
|
||||
if (ctx->ctxid == IWL_RXON_CTX_BSS)
|
||||
ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
|
||||
else
|
||||
ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Un-assoc RXON clears the station table and WEP
|
||||
* keys, so we have to restore those afterwards.
|
||||
*/
|
||||
iwl_clear_ucode_stations(priv, ctx);
|
||||
iwl_restore_stations(priv, ctx);
|
||||
ret = iwl_restore_default_wep_keys(priv, ctx);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy(active, &ctx->staging, sizeof(*active));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwlagn_rxon_connect(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx)
|
||||
{
|
||||
int ret;
|
||||
struct iwl_rxon_cmd *active = (void *)&ctx->active;
|
||||
|
||||
/* RXON timing must be before associated RXON */
|
||||
ret = iwl_send_rxon_timing(priv, ctx);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
|
||||
return ret;
|
||||
}
|
||||
/* QoS info may be cleared by previous un-assoc RXON */
|
||||
iwlagn_update_qos(priv, ctx);
|
||||
|
||||
/*
|
||||
* We'll run into this code path when beaconing is
|
||||
* enabled, but then we also need to send the beacon
|
||||
* to the device.
|
||||
*/
|
||||
if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
|
||||
ret = iwlagn_update_beacon(priv, ctx->vif);
|
||||
if (ret) {
|
||||
IWL_ERR(priv,
|
||||
"Error sending required beacon (%d)!\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
priv->start_calib = 0;
|
||||
/*
|
||||
* Apply the new configuration.
|
||||
*
|
||||
* Associated RXON doesn't clear the station table in uCode,
|
||||
* so we don't need to restore stations etc. after this.
|
||||
*/
|
||||
ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
|
||||
sizeof(struct iwl_rxon_cmd), &ctx->staging);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
memcpy(active, &ctx->staging, sizeof(*active));
|
||||
|
||||
iwl_reprogram_ap_sta(priv, ctx);
|
||||
|
||||
/* IBSS beacon needs to be sent after setting assoc */
|
||||
if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
|
||||
if (iwlagn_update_beacon(priv, ctx->vif))
|
||||
IWL_ERR(priv, "Error sending IBSS beacon\n");
|
||||
iwl_init_sensitivity(priv);
|
||||
|
||||
/*
|
||||
* If we issue a new RXON command which required a tune then
|
||||
* we must send a new TXPOWER command or we won't be able to
|
||||
* Tx any frames.
|
||||
*
|
||||
* It's expected we set power here if channel is changing.
|
||||
*/
|
||||
ret = iwl_set_tx_power(priv, priv->tx_power_next, true);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* iwlagn_commit_rxon - commit staging_rxon to hardware
|
||||
*
|
||||
@ -131,6 +273,16 @@ static int iwlagn_update_beacon(struct iwl_priv *priv,
|
||||
* the active_rxon structure is updated with the new data. This
|
||||
* function correctly transitions out of the RXON_ASSOC_MSK state if
|
||||
* a HW tune is required based on the RXON structure changes.
|
||||
*
|
||||
* The connect/disconnect flow should be as the following:
|
||||
*
|
||||
* 1. make sure send RXON command with association bit unset if not connect
|
||||
* this should include the channel and the band for the candidate
|
||||
* to be connected to
|
||||
* 2. Add Station before RXON association with the AP
|
||||
* 3. RXON_timing has to send before RXON for connection
|
||||
* 4. full RXON command - associated bit set
|
||||
* 5. use RXON_ASSOC command to update any flags changes
|
||||
*/
|
||||
int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||
{
|
||||
@ -180,6 +332,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||
else
|
||||
ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
|
||||
|
||||
iwl_print_rx_config_cmd(priv, ctx);
|
||||
ret = iwl_check_rxon_cmd(priv, ctx);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
|
||||
@ -203,14 +356,13 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||
* and other flags for the current radio configuration.
|
||||
*/
|
||||
if (!iwl_full_rxon_required(priv, ctx)) {
|
||||
ret = iwl_send_rxon_assoc(priv, ctx);
|
||||
ret = iwlagn_send_rxon_assoc(priv, ctx);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy(active, &ctx->staging, sizeof(*active));
|
||||
iwl_print_rx_config_cmd(priv, ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -220,7 +372,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
|
||||
iwl_set_rxon_hwcrypto(priv, ctx, !iwlagn_mod_params.sw_crypto);
|
||||
|
||||
IWL_DEBUG_INFO(priv,
|
||||
"Going to commit RXON\n"
|
||||
@ -238,92 +390,13 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||
* set up filters in the device.
|
||||
*/
|
||||
if ((old_assoc && new_assoc) || !new_assoc) {
|
||||
if (ctx->ctxid == IWL_RXON_CTX_BSS)
|
||||
ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
|
||||
else
|
||||
ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
|
||||
ret = iwlagn_rxon_disconn(priv, ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
memcpy(active, &ctx->staging, sizeof(*active));
|
||||
|
||||
/*
|
||||
* Un-assoc RXON clears the station table and WEP
|
||||
* keys, so we have to restore those afterwards.
|
||||
*/
|
||||
iwl_clear_ucode_stations(priv, ctx);
|
||||
iwl_restore_stations(priv, ctx);
|
||||
ret = iwl_restore_default_wep_keys(priv, ctx);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* RXON timing must be before associated RXON */
|
||||
ret = iwl_send_rxon_timing(priv, ctx);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (new_assoc) {
|
||||
/* QoS info may be cleared by previous un-assoc RXON */
|
||||
iwlagn_update_qos(priv, ctx);
|
||||
|
||||
/*
|
||||
* We'll run into this code path when beaconing is
|
||||
* enabled, but then we also need to send the beacon
|
||||
* to the device.
|
||||
*/
|
||||
if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
|
||||
ret = iwlagn_update_beacon(priv, ctx->vif);
|
||||
if (ret) {
|
||||
IWL_ERR(priv,
|
||||
"Error sending required beacon (%d)!\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
priv->start_calib = 0;
|
||||
/*
|
||||
* Apply the new configuration.
|
||||
*
|
||||
* Associated RXON doesn't clear the station table in uCode,
|
||||
* so we don't need to restore stations etc. after this.
|
||||
*/
|
||||
ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
|
||||
sizeof(struct iwl_rxon_cmd), &ctx->staging);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
memcpy(active, &ctx->staging, sizeof(*active));
|
||||
|
||||
iwl_reprogram_ap_sta(priv, ctx);
|
||||
|
||||
/* IBSS beacon needs to be sent after setting assoc */
|
||||
if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
|
||||
if (iwlagn_update_beacon(priv, ctx->vif))
|
||||
IWL_ERR(priv, "Error sending IBSS beacon\n");
|
||||
}
|
||||
|
||||
iwl_print_rx_config_cmd(priv, ctx);
|
||||
|
||||
iwl_init_sensitivity(priv);
|
||||
|
||||
/*
|
||||
* If we issue a new RXON command which required a tune then we must
|
||||
* send a new TXPOWER command or we won't be able to Tx any frames.
|
||||
*
|
||||
* It's expected we set power here if channel is changing.
|
||||
*/
|
||||
ret = iwl_set_tx_power(priv, priv->tx_power_next, true);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
if (new_assoc)
|
||||
return iwlagn_rxon_connect(priv, ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -161,47 +161,19 @@ static int iwlagn_load_section(struct iwl_priv *priv, const char *name,
|
||||
}
|
||||
|
||||
static int iwlagn_load_given_ucode(struct iwl_priv *priv,
|
||||
struct fw_desc *inst_image,
|
||||
struct fw_desc *data_image)
|
||||
struct fw_img *image)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = iwlagn_load_section(priv, "INST", inst_image,
|
||||
ret = iwlagn_load_section(priv, "INST", &image->code,
|
||||
IWLAGN_RTC_INST_LOWER_BOUND);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return iwlagn_load_section(priv, "DATA", data_image,
|
||||
return iwlagn_load_section(priv, "DATA", &image->data,
|
||||
IWLAGN_RTC_DATA_LOWER_BOUND);
|
||||
}
|
||||
|
||||
int iwlagn_load_ucode(struct iwl_priv *priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* check whether init ucode should be loaded, or rather runtime ucode */
|
||||
if (priv->ucode_init.len && (priv->ucode_type == UCODE_NONE)) {
|
||||
IWL_DEBUG_INFO(priv, "Init ucode found. Loading init ucode...\n");
|
||||
ret = iwlagn_load_given_ucode(priv,
|
||||
&priv->ucode_init, &priv->ucode_init_data);
|
||||
if (!ret) {
|
||||
IWL_DEBUG_INFO(priv, "Init ucode load complete.\n");
|
||||
priv->ucode_type = UCODE_INIT;
|
||||
}
|
||||
} else {
|
||||
IWL_DEBUG_INFO(priv, "Init ucode not found, or already loaded. "
|
||||
"Loading runtime ucode...\n");
|
||||
ret = iwlagn_load_given_ucode(priv,
|
||||
&priv->ucode_code, &priv->ucode_data);
|
||||
if (!ret) {
|
||||
IWL_DEBUG_INFO(priv, "Runtime ucode load complete.\n");
|
||||
priv->ucode_type = UCODE_RT;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calibration
|
||||
*/
|
||||
@ -297,33 +269,9 @@ void iwlagn_rx_calib_result(struct iwl_priv *priv,
|
||||
iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
|
||||
}
|
||||
|
||||
void iwlagn_rx_calib_complete(struct iwl_priv *priv,
|
||||
struct iwl_rx_mem_buffer *rxb)
|
||||
static int iwlagn_init_alive_start(struct iwl_priv *priv)
|
||||
{
|
||||
IWL_DEBUG_INFO(priv, "Init. calibration is completed, restarting fw.\n");
|
||||
queue_work(priv->workqueue, &priv->restart);
|
||||
}
|
||||
|
||||
void iwlagn_init_alive_start(struct iwl_priv *priv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* initialize uCode was loaded... verify inst image.
|
||||
* This is a paranoid check, because we would not have gotten the
|
||||
* "initialize" alive if code weren't properly loaded. */
|
||||
if (iwl_verify_ucode(priv, &priv->ucode_init)) {
|
||||
/* Runtime instruction load was bad;
|
||||
* take it all the way back down so we can try again */
|
||||
IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
|
||||
goto restart;
|
||||
}
|
||||
|
||||
ret = iwlagn_alive_notify(priv);
|
||||
if (ret) {
|
||||
IWL_WARN(priv,
|
||||
"Could not complete ALIVE transition: %d\n", ret);
|
||||
goto restart;
|
||||
}
|
||||
int ret;
|
||||
|
||||
if (priv->cfg->bt_params &&
|
||||
priv->cfg->bt_params->advanced_bt_coexist) {
|
||||
@ -333,24 +281,25 @@ void iwlagn_init_alive_start(struct iwl_priv *priv)
|
||||
* no need to close the envlope since we are going
|
||||
* to load the runtime uCode later.
|
||||
*/
|
||||
iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
|
||||
ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
|
||||
BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
}
|
||||
iwlagn_send_calib_cfg(priv);
|
||||
|
||||
ret = iwlagn_send_calib_cfg(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/**
|
||||
* temperature offset calibration is only needed for runtime ucode,
|
||||
* so prepare the value now.
|
||||
*/
|
||||
if (priv->cfg->need_temp_offset_calib)
|
||||
iwlagn_set_temperature_offset_calib(priv);
|
||||
return iwlagn_set_temperature_offset_calib(priv);
|
||||
|
||||
return;
|
||||
|
||||
restart:
|
||||
/* real restart (first load init_ucode) */
|
||||
queue_work(priv->workqueue, &priv->restart);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwlagn_send_wimax_coex(struct iwl_priv *priv)
|
||||
@ -413,19 +362,22 @@ void iwlagn_send_prio_tbl(struct iwl_priv *priv)
|
||||
IWL_ERR(priv, "failed to send BT prio tbl command\n");
|
||||
}
|
||||
|
||||
void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
|
||||
int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
|
||||
{
|
||||
struct iwl_bt_coex_prot_env_cmd env_cmd;
|
||||
int ret;
|
||||
|
||||
env_cmd.action = action;
|
||||
env_cmd.type = type;
|
||||
if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV,
|
||||
sizeof(env_cmd), &env_cmd))
|
||||
ret = iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV,
|
||||
sizeof(env_cmd), &env_cmd);
|
||||
if (ret)
|
||||
IWL_ERR(priv, "failed to send BT env command\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int iwlagn_alive_notify(struct iwl_priv *priv)
|
||||
static int iwlagn_alive_notify(struct iwl_priv *priv)
|
||||
{
|
||||
const struct queue_to_fifo_ac *queue_to_fifo;
|
||||
struct iwl_rxon_context *ctx;
|
||||
@ -604,15 +556,164 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv,
|
||||
* iwl_verify_ucode - determine which instruction image is in SRAM,
|
||||
* and verify its contents
|
||||
*/
|
||||
int iwl_verify_ucode(struct iwl_priv *priv, struct fw_desc *fw_desc)
|
||||
static int iwl_verify_ucode(struct iwl_priv *priv, struct fw_img *img)
|
||||
{
|
||||
if (!iwlcore_verify_inst_sparse(priv, fw_desc)) {
|
||||
if (!iwlcore_verify_inst_sparse(priv, &img->code)) {
|
||||
IWL_DEBUG_INFO(priv, "uCode is good in inst SRAM\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
|
||||
|
||||
iwl_print_mismatch_inst(priv, fw_desc);
|
||||
iwl_print_mismatch_inst(priv, &img->code);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
struct iwlagn_alive_data {
|
||||
bool valid;
|
||||
u8 subtype;
|
||||
};
|
||||
|
||||
static void iwlagn_alive_fn(struct iwl_priv *priv,
|
||||
struct iwl_rx_packet *pkt,
|
||||
void *data)
|
||||
{
|
||||
struct iwlagn_alive_data *alive_data = data;
|
||||
struct iwl_alive_resp *palive;
|
||||
|
||||
palive = &pkt->u.alive_frame;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
|
||||
"0x%01X 0x%01X\n",
|
||||
palive->is_valid, palive->ver_type,
|
||||
palive->ver_subtype);
|
||||
|
||||
priv->device_pointers.error_event_table =
|
||||
le32_to_cpu(palive->error_event_table_ptr);
|
||||
priv->device_pointers.log_event_table =
|
||||
le32_to_cpu(palive->log_event_table_ptr);
|
||||
|
||||
alive_data->subtype = palive->ver_subtype;
|
||||
alive_data->valid = palive->is_valid == UCODE_VALID_OK;
|
||||
}
|
||||
|
||||
#define UCODE_ALIVE_TIMEOUT HZ
|
||||
#define UCODE_CALIB_TIMEOUT (2*HZ)
|
||||
|
||||
int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
|
||||
struct fw_img *image,
|
||||
int subtype, int alternate_subtype)
|
||||
{
|
||||
struct iwl_notification_wait alive_wait;
|
||||
struct iwlagn_alive_data alive_data;
|
||||
int ret;
|
||||
enum iwlagn_ucode_subtype old_type;
|
||||
|
||||
ret = iwlagn_start_device(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
iwlagn_init_notification_wait(priv, &alive_wait, REPLY_ALIVE,
|
||||
iwlagn_alive_fn, &alive_data);
|
||||
|
||||
old_type = priv->ucode_type;
|
||||
priv->ucode_type = subtype;
|
||||
|
||||
ret = iwlagn_load_given_ucode(priv, image);
|
||||
if (ret) {
|
||||
priv->ucode_type = old_type;
|
||||
iwlagn_remove_notification(priv, &alive_wait);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Remove all resets to allow NIC to operate */
|
||||
iwl_write32(priv, CSR_RESET, 0);
|
||||
|
||||
/*
|
||||
* Some things may run in the background now, but we
|
||||
* just wait for the ALIVE notification here.
|
||||
*/
|
||||
ret = iwlagn_wait_notification(priv, &alive_wait, UCODE_ALIVE_TIMEOUT);
|
||||
if (ret) {
|
||||
priv->ucode_type = old_type;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!alive_data.valid) {
|
||||
IWL_ERR(priv, "Loaded ucode is not valid!\n");
|
||||
priv->ucode_type = old_type;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (alive_data.subtype != subtype &&
|
||||
alive_data.subtype != alternate_subtype) {
|
||||
IWL_ERR(priv,
|
||||
"Loaded ucode is not expected type (got %d, expected %d)!\n",
|
||||
alive_data.subtype, subtype);
|
||||
priv->ucode_type = old_type;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = iwl_verify_ucode(priv, image);
|
||||
if (ret) {
|
||||
priv->ucode_type = old_type;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* delay a bit to give rfkill time to run */
|
||||
msleep(5);
|
||||
|
||||
ret = iwlagn_alive_notify(priv);
|
||||
if (ret) {
|
||||
IWL_WARN(priv,
|
||||
"Could not complete ALIVE transition: %d\n", ret);
|
||||
priv->ucode_type = old_type;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iwlagn_run_init_ucode(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_notification_wait calib_wait;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&priv->mutex);
|
||||
|
||||
/* No init ucode required? Curious, but maybe ok */
|
||||
if (!priv->ucode_init.code.len)
|
||||
return 0;
|
||||
|
||||
if (priv->ucode_type != UCODE_SUBTYPE_NONE_LOADED)
|
||||
return 0;
|
||||
|
||||
iwlagn_init_notification_wait(priv, &calib_wait,
|
||||
CALIBRATION_COMPLETE_NOTIFICATION,
|
||||
NULL, NULL);
|
||||
|
||||
/* Will also start the device */
|
||||
ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init,
|
||||
UCODE_SUBTYPE_INIT, -1);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
ret = iwlagn_init_alive_start(priv);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
/*
|
||||
* Some things may run in the background now, but we
|
||||
* just wait for the calibration complete notification.
|
||||
*/
|
||||
ret = iwlagn_wait_notification(priv, &calib_wait, UCODE_CALIB_TIMEOUT);
|
||||
|
||||
goto out;
|
||||
|
||||
error:
|
||||
iwlagn_remove_notification(priv, &calib_wait);
|
||||
out:
|
||||
/* Whatever happened, stop the device */
|
||||
iwlagn_stop_device(priv);
|
||||
return ret;
|
||||
}
|
||||
|
@ -769,7 +769,7 @@ static void iwl_rx_handle(struct iwl_priv *priv)
|
||||
if (w->cmd == pkt->hdr.cmd) {
|
||||
w->triggered = true;
|
||||
if (w->fn)
|
||||
w->fn(priv, pkt);
|
||||
w->fn(priv, pkt, w->fn_data);
|
||||
}
|
||||
}
|
||||
spin_unlock(&priv->_agn.notif_wait_lock);
|
||||
@ -846,14 +846,6 @@ static void iwl_rx_handle(struct iwl_priv *priv)
|
||||
iwlagn_rx_queue_restock(priv);
|
||||
}
|
||||
|
||||
/* call this function to flush any scheduled tasklet */
|
||||
static inline void iwl_synchronize_irq(struct iwl_priv *priv)
|
||||
{
|
||||
/* wait to make sure we flush pending tasklet*/
|
||||
synchronize_irq(priv->pci_dev->irq);
|
||||
tasklet_kill(&priv->irq_tasklet);
|
||||
}
|
||||
|
||||
/* tasklet for iwlagn interrupt */
|
||||
static void iwl_irq_tasklet(struct iwl_priv *priv)
|
||||
{
|
||||
@ -1181,18 +1173,42 @@ static struct attribute_group iwl_attribute_group = {
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static void iwl_dealloc_ucode_pci(struct iwl_priv *priv)
|
||||
static void iwl_free_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc)
|
||||
{
|
||||
iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code);
|
||||
iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data);
|
||||
iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init);
|
||||
iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data);
|
||||
if (desc->v_addr)
|
||||
dma_free_coherent(&pci_dev->dev, desc->len,
|
||||
desc->v_addr, desc->p_addr);
|
||||
desc->v_addr = NULL;
|
||||
desc->len = 0;
|
||||
}
|
||||
|
||||
static void iwl_nic_start(struct iwl_priv *priv)
|
||||
static void iwl_free_fw_img(struct pci_dev *pci_dev, struct fw_img *img)
|
||||
{
|
||||
/* Remove all resets to allow NIC to operate */
|
||||
iwl_write32(priv, CSR_RESET, 0);
|
||||
iwl_free_fw_desc(pci_dev, &img->code);
|
||||
iwl_free_fw_desc(pci_dev, &img->data);
|
||||
}
|
||||
|
||||
static int iwl_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc,
|
||||
const void *data, size_t len)
|
||||
{
|
||||
if (!len) {
|
||||
desc->v_addr = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
desc->v_addr = dma_alloc_coherent(&pci_dev->dev, len,
|
||||
&desc->p_addr, GFP_KERNEL);
|
||||
if (!desc->v_addr)
|
||||
return -ENOMEM;
|
||||
desc->len = len;
|
||||
memcpy(desc->v_addr, data, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void iwl_dealloc_ucode_pci(struct iwl_priv *priv)
|
||||
{
|
||||
iwl_free_fw_img(priv->pci_dev, &priv->ucode_rt);
|
||||
iwl_free_fw_img(priv->pci_dev, &priv->ucode_init);
|
||||
}
|
||||
|
||||
struct iwlagn_ucode_capabilities {
|
||||
@ -1661,24 +1677,20 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
|
||||
/* Runtime instructions and 2 copies of data:
|
||||
* 1) unmodified from disk
|
||||
* 2) backup cache for save/restore during power-downs */
|
||||
priv->ucode_code.len = pieces.inst_size;
|
||||
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code);
|
||||
|
||||
priv->ucode_data.len = pieces.data_size;
|
||||
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data);
|
||||
|
||||
if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr)
|
||||
if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.code,
|
||||
pieces.inst, pieces.inst_size))
|
||||
goto err_pci_alloc;
|
||||
if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.data,
|
||||
pieces.data, pieces.data_size))
|
||||
goto err_pci_alloc;
|
||||
|
||||
/* Initialization instructions and data */
|
||||
if (pieces.init_size && pieces.init_data_size) {
|
||||
priv->ucode_init.len = pieces.init_size;
|
||||
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init);
|
||||
|
||||
priv->ucode_init_data.len = pieces.init_data_size;
|
||||
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data);
|
||||
|
||||
if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr)
|
||||
if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.code,
|
||||
pieces.init, pieces.init_size))
|
||||
goto err_pci_alloc;
|
||||
if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.data,
|
||||
pieces.init_data, pieces.init_data_size))
|
||||
goto err_pci_alloc;
|
||||
}
|
||||
|
||||
@ -1704,6 +1716,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
|
||||
priv->cfg->base_params->max_event_log_size;
|
||||
priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr;
|
||||
|
||||
priv->new_scan_threshold_behaviour =
|
||||
!!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
|
||||
|
||||
if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) {
|
||||
priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
|
||||
priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
|
||||
@ -1715,39 +1730,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
|
||||
else
|
||||
priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
|
||||
|
||||
/* Copy images into buffers for card's bus-master reads ... */
|
||||
|
||||
/* Runtime instructions (first block of data in file) */
|
||||
IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n",
|
||||
pieces.inst_size);
|
||||
memcpy(priv->ucode_code.v_addr, pieces.inst, pieces.inst_size);
|
||||
|
||||
IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
|
||||
priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
|
||||
|
||||
/*
|
||||
* Runtime data
|
||||
* NOTE: Copy into backup buffer will be done in iwl_up()
|
||||
*/
|
||||
IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n",
|
||||
pieces.data_size);
|
||||
memcpy(priv->ucode_data.v_addr, pieces.data, pieces.data_size);
|
||||
|
||||
/* Initialization instructions */
|
||||
if (pieces.init_size) {
|
||||
IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n",
|
||||
pieces.init_size);
|
||||
memcpy(priv->ucode_init.v_addr, pieces.init, pieces.init_size);
|
||||
}
|
||||
|
||||
/* Initialization data */
|
||||
if (pieces.init_data_size) {
|
||||
IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n",
|
||||
pieces.init_data_size);
|
||||
memcpy(priv->ucode_init_data.v_addr, pieces.init_data,
|
||||
pieces.init_data_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* figure out the offset of chain noise reset and gain commands
|
||||
* base on the size of standard phy calibration commands table size
|
||||
@ -1878,9 +1860,10 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
|
||||
u32 desc, time, count, base, data1;
|
||||
u32 blink1, blink2, ilink1, ilink2;
|
||||
u32 pc, hcmd;
|
||||
struct iwl_error_event_table table;
|
||||
|
||||
base = priv->device_pointers.error_event_table;
|
||||
if (priv->ucode_type == UCODE_INIT) {
|
||||
if (priv->ucode_type == UCODE_SUBTYPE_INIT) {
|
||||
if (!base)
|
||||
base = priv->_agn.init_errlog_ptr;
|
||||
} else {
|
||||
@ -1891,11 +1874,15 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
|
||||
if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
|
||||
IWL_ERR(priv,
|
||||
"Not valid error log pointer 0x%08X for %s uCode\n",
|
||||
base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
|
||||
base,
|
||||
(priv->ucode_type == UCODE_SUBTYPE_INIT)
|
||||
? "Init" : "RT");
|
||||
return;
|
||||
}
|
||||
|
||||
count = iwl_read_targ_mem(priv, base);
|
||||
iwl_read_targ_mem_words(priv, base, &table, sizeof(table));
|
||||
|
||||
count = table.valid;
|
||||
|
||||
if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
|
||||
IWL_ERR(priv, "Start IWL Error Log Dump:\n");
|
||||
@ -1903,18 +1890,18 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
|
||||
priv->status, count);
|
||||
}
|
||||
|
||||
desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
|
||||
desc = table.error_id;
|
||||
priv->isr_stats.err_code = desc;
|
||||
pc = iwl_read_targ_mem(priv, base + 2 * sizeof(u32));
|
||||
blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32));
|
||||
blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32));
|
||||
ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32));
|
||||
ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32));
|
||||
data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32));
|
||||
data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32));
|
||||
line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
|
||||
time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
|
||||
hcmd = iwl_read_targ_mem(priv, base + 22 * sizeof(u32));
|
||||
pc = table.pc;
|
||||
blink1 = table.blink1;
|
||||
blink2 = table.blink2;
|
||||
ilink1 = table.ilink1;
|
||||
ilink2 = table.ilink2;
|
||||
data1 = table.data1;
|
||||
data2 = table.data2;
|
||||
line = table.line;
|
||||
time = table.tsf_low;
|
||||
hcmd = table.hcmd;
|
||||
|
||||
trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line,
|
||||
blink1, blink2, ilink1, ilink2);
|
||||
@ -1949,7 +1936,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
|
||||
return pos;
|
||||
|
||||
base = priv->device_pointers.log_event_table;
|
||||
if (priv->ucode_type == UCODE_INIT) {
|
||||
if (priv->ucode_type == UCODE_SUBTYPE_INIT) {
|
||||
if (!base)
|
||||
base = priv->_agn.init_evtlog_ptr;
|
||||
} else {
|
||||
@ -2062,7 +2049,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
|
||||
size_t bufsz = 0;
|
||||
|
||||
base = priv->device_pointers.log_event_table;
|
||||
if (priv->ucode_type == UCODE_INIT) {
|
||||
if (priv->ucode_type == UCODE_SUBTYPE_INIT) {
|
||||
logsize = priv->_agn.init_evtlog_size;
|
||||
if (!base)
|
||||
base = priv->_agn.init_evtlog_ptr;
|
||||
@ -2075,7 +2062,9 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
|
||||
if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
|
||||
IWL_ERR(priv,
|
||||
"Invalid event log pointer 0x%08X for %s uCode\n",
|
||||
base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
|
||||
base,
|
||||
(priv->ucode_type == UCODE_SUBTYPE_INIT)
|
||||
? "Init" : "RT");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -2222,31 +2211,15 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg)
|
||||
* from protocol/runtime uCode (initialization uCode's
|
||||
* Alive gets handled by iwl_init_alive_start()).
|
||||
*/
|
||||
static void iwl_alive_start(struct iwl_priv *priv)
|
||||
static int iwl_alive_start(struct iwl_priv *priv)
|
||||
{
|
||||
int ret = 0;
|
||||
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
|
||||
|
||||
iwl_reset_ict(priv);
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
|
||||
|
||||
/* Initialize uCode has loaded Runtime uCode ... verify inst image.
|
||||
* This is a paranoid check, because we would not have gotten the
|
||||
* "runtime" alive if code weren't properly loaded. */
|
||||
if (iwl_verify_ucode(priv, &priv->ucode_code)) {
|
||||
/* Runtime instruction load was bad;
|
||||
* take it all the way back down so we can try again */
|
||||
IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n");
|
||||
goto restart;
|
||||
}
|
||||
|
||||
ret = iwlagn_alive_notify(priv);
|
||||
if (ret) {
|
||||
IWL_WARN(priv,
|
||||
"Could not complete ALIVE transition [ntf]: %d\n", ret);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
|
||||
/* After the ALIVE response, we can send host commands to the uCode */
|
||||
set_bit(STATUS_ALIVE, &priv->status);
|
||||
|
||||
@ -2254,7 +2227,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
|
||||
iwl_setup_watchdog(priv);
|
||||
|
||||
if (iwl_is_rfkill(priv))
|
||||
return;
|
||||
return -ERFKILL;
|
||||
|
||||
/* download priority table before any calibration request */
|
||||
if (priv->cfg->bt_params &&
|
||||
@ -2268,10 +2241,14 @@ static void iwl_alive_start(struct iwl_priv *priv)
|
||||
iwlagn_send_prio_tbl(priv);
|
||||
|
||||
/* FIXME: w/a to force change uCode BT state machine */
|
||||
iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
|
||||
BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
|
||||
iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
|
||||
BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
|
||||
ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
|
||||
BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
|
||||
BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
if (priv->hw_params.calib_rt_cfg)
|
||||
iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg);
|
||||
@ -2313,29 +2290,22 @@ static void iwl_alive_start(struct iwl_priv *priv)
|
||||
set_bit(STATUS_READY, &priv->status);
|
||||
|
||||
/* Configure the adapter for unassociated operation */
|
||||
iwlcore_commit_rxon(priv, ctx);
|
||||
ret = iwlcore_commit_rxon(priv, ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* At this point, the NIC is initialized and operational */
|
||||
iwl_rf_kill_ct_config(priv);
|
||||
|
||||
IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
|
||||
wake_up_interruptible(&priv->wait_command_queue);
|
||||
|
||||
iwl_power_update_mode(priv, true);
|
||||
IWL_DEBUG_INFO(priv, "Updated power mode\n");
|
||||
|
||||
|
||||
return;
|
||||
|
||||
restart:
|
||||
queue_work(priv->workqueue, &priv->restart);
|
||||
return iwl_power_update_mode(priv, true);
|
||||
}
|
||||
|
||||
static void iwl_cancel_deferred_work(struct iwl_priv *priv);
|
||||
|
||||
static void __iwl_down(struct iwl_priv *priv)
|
||||
{
|
||||
unsigned long flags;
|
||||
int exit_pending;
|
||||
|
||||
IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
|
||||
@ -2367,32 +2337,10 @@ static void __iwl_down(struct iwl_priv *priv)
|
||||
if (!exit_pending)
|
||||
clear_bit(STATUS_EXIT_PENDING, &priv->status);
|
||||
|
||||
/* stop and reset the on-board processor */
|
||||
iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
|
||||
|
||||
/* tell the device to stop sending interrupts */
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
iwl_disable_interrupts(priv);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
iwl_synchronize_irq(priv);
|
||||
|
||||
if (priv->mac80211_registered)
|
||||
ieee80211_stop_queues(priv->hw);
|
||||
|
||||
/* If we have not previously called iwl_init() then
|
||||
* clear all bits but the RF Kill bit and return */
|
||||
if (!iwl_is_init(priv)) {
|
||||
priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
|
||||
STATUS_RF_KILL_HW |
|
||||
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
|
||||
STATUS_GEO_CONFIGURED |
|
||||
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
|
||||
STATUS_EXIT_PENDING;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* ...otherwise clear out all the status bits but the RF Kill
|
||||
* bit and continue taking the NIC down. */
|
||||
/* Clear out all status bits but a few that are stable across reset */
|
||||
priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
|
||||
STATUS_RF_KILL_HW |
|
||||
test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
|
||||
@ -2402,23 +2350,8 @@ static void __iwl_down(struct iwl_priv *priv)
|
||||
test_bit(STATUS_EXIT_PENDING, &priv->status) <<
|
||||
STATUS_EXIT_PENDING;
|
||||
|
||||
/* device going down, Stop using ICT table */
|
||||
iwl_disable_ict(priv);
|
||||
iwlagn_stop_device(priv);
|
||||
|
||||
iwlagn_txq_ctx_stop(priv);
|
||||
iwlagn_rxq_stop(priv);
|
||||
|
||||
/* Power-down device's busmaster DMA clocks */
|
||||
iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
|
||||
udelay(5);
|
||||
|
||||
/* Make sure (redundant) we've released our request to stay awake */
|
||||
iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
|
||||
|
||||
/* Stop the device, and put it in low power state */
|
||||
iwl_apm_stop(priv);
|
||||
|
||||
exit:
|
||||
dev_kfree_skb(priv->beacon_skb);
|
||||
priv->beacon_skb = NULL;
|
||||
|
||||
@ -2437,9 +2370,10 @@ static void iwl_down(struct iwl_priv *priv)
|
||||
|
||||
#define HW_READY_TIMEOUT (50)
|
||||
|
||||
/* Note: returns poll_bit return value, which is >= 0 if success */
|
||||
static int iwl_set_hw_ready(struct iwl_priv *priv)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
|
||||
CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
|
||||
@ -2449,25 +2383,21 @@ static int iwl_set_hw_ready(struct iwl_priv *priv)
|
||||
CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
|
||||
CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
|
||||
HW_READY_TIMEOUT);
|
||||
if (ret != -ETIMEDOUT)
|
||||
priv->hw_ready = true;
|
||||
else
|
||||
priv->hw_ready = false;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "hardware %s\n",
|
||||
(priv->hw_ready == 1) ? "ready" : "not ready");
|
||||
IWL_DEBUG_INFO(priv, "hardware%s ready\n", ret < 0 ? " not" : "");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwl_prepare_card_hw(struct iwl_priv *priv)
|
||||
/* Note: returns standard 0/-ERROR code */
|
||||
int iwl_prepare_card_hw(struct iwl_priv *priv)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter\n");
|
||||
|
||||
ret = iwl_set_hw_ready(priv);
|
||||
if (priv->hw_ready)
|
||||
return ret;
|
||||
if (ret >= 0)
|
||||
return 0;
|
||||
|
||||
/* If HW is not ready, prepare the conditions to check again */
|
||||
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
|
||||
@ -2477,10 +2407,13 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv)
|
||||
~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
|
||||
CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
|
||||
|
||||
/* HW should be ready by now, check again. */
|
||||
if (ret != -ETIMEDOUT)
|
||||
iwl_set_hw_ready(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* HW should be ready by now, check again. */
|
||||
ret = iwl_set_hw_ready(priv);
|
||||
if (ret >= 0)
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2489,9 +2422,10 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv)
|
||||
static int __iwl_up(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_rxon_context *ctx;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&priv->mutex);
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
|
||||
IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
|
||||
return -EIO;
|
||||
@ -2505,77 +2439,33 @@ static int __iwl_up(struct iwl_priv *priv)
|
||||
}
|
||||
}
|
||||
|
||||
iwl_prepare_card_hw(priv);
|
||||
|
||||
if (!priv->hw_ready) {
|
||||
IWL_WARN(priv, "Exit HW not ready\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* If platform's RF_KILL switch is NOT set to KILL */
|
||||
if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
|
||||
clear_bit(STATUS_RF_KILL_HW, &priv->status);
|
||||
else
|
||||
set_bit(STATUS_RF_KILL_HW, &priv->status);
|
||||
|
||||
if (iwl_is_rfkill(priv)) {
|
||||
wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
|
||||
|
||||
iwl_enable_interrupts(priv);
|
||||
IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
|
||||
|
||||
ret = iwlagn_hw_nic_init(priv);
|
||||
ret = iwlagn_run_init_ucode(priv);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Unable to init nic\n");
|
||||
return ret;
|
||||
IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* make sure rfkill handshake bits are cleared */
|
||||
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
||||
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
|
||||
CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
|
||||
|
||||
/* clear (again), then enable host interrupts */
|
||||
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
|
||||
iwl_enable_interrupts(priv);
|
||||
|
||||
/* really make sure rfkill handshake bits are cleared */
|
||||
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
||||
iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
|
||||
|
||||
for (i = 0; i < MAX_HW_RESTARTS; i++) {
|
||||
|
||||
/* load bootstrap state machine,
|
||||
* load bootstrap program into processor's memory,
|
||||
* prepare to load the "initialize" uCode */
|
||||
ret = iwlagn_load_ucode(priv);
|
||||
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n",
|
||||
ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* start card; "initialize" will load runtime ucode */
|
||||
iwl_nic_start(priv);
|
||||
|
||||
IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n");
|
||||
|
||||
return 0;
|
||||
ret = iwlagn_load_ucode_wait_alive(priv,
|
||||
&priv->ucode_rt,
|
||||
UCODE_SUBTYPE_REGULAR,
|
||||
UCODE_SUBTYPE_REGULAR_NEW);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = iwl_alive_start(priv);
|
||||
if (ret)
|
||||
goto error;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
set_bit(STATUS_EXIT_PENDING, &priv->status);
|
||||
__iwl_down(priv);
|
||||
clear_bit(STATUS_EXIT_PENDING, &priv->status);
|
||||
|
||||
/* tried to restart and config the device for as long as our
|
||||
* patience could withstand */
|
||||
IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i);
|
||||
return -EIO;
|
||||
IWL_ERR(priv, "Unable to initialize device.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -2585,39 +2475,6 @@ static int __iwl_up(struct iwl_priv *priv)
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void iwl_bg_init_alive_start(struct work_struct *data)
|
||||
{
|
||||
struct iwl_priv *priv =
|
||||
container_of(data, struct iwl_priv, init_alive_start.work);
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
|
||||
mutex_unlock(&priv->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
iwlagn_init_alive_start(priv);
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
static void iwl_bg_alive_start(struct work_struct *data)
|
||||
{
|
||||
struct iwl_priv *priv =
|
||||
container_of(data, struct iwl_priv, alive_start.work);
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
goto unlock;
|
||||
|
||||
/* enable dram interrupt */
|
||||
iwl_reset_ict(priv);
|
||||
|
||||
iwl_alive_start(priv);
|
||||
unlock:
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
static void iwl_bg_run_time_calib_work(struct work_struct *work)
|
||||
{
|
||||
struct iwl_priv *priv = container_of(work, struct iwl_priv,
|
||||
@ -2639,6 +2496,42 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
|
||||
static void iwlagn_prepare_restart(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_rxon_context *ctx;
|
||||
bool bt_full_concurrent;
|
||||
u8 bt_ci_compliance;
|
||||
u8 bt_load;
|
||||
u8 bt_status;
|
||||
|
||||
lockdep_assert_held(&priv->mutex);
|
||||
|
||||
for_each_context(priv, ctx)
|
||||
ctx->vif = NULL;
|
||||
priv->is_open = 0;
|
||||
|
||||
/*
|
||||
* __iwl_down() will clear the BT status variables,
|
||||
* which is correct, but when we restart we really
|
||||
* want to keep them so restore them afterwards.
|
||||
*
|
||||
* The restart process will later pick them up and
|
||||
* re-configure the hw when we reconfigure the BT
|
||||
* command.
|
||||
*/
|
||||
bt_full_concurrent = priv->bt_full_concurrent;
|
||||
bt_ci_compliance = priv->bt_ci_compliance;
|
||||
bt_load = priv->bt_traffic_load;
|
||||
bt_status = priv->bt_status;
|
||||
|
||||
__iwl_down(priv);
|
||||
|
||||
priv->bt_full_concurrent = bt_full_concurrent;
|
||||
priv->bt_ci_compliance = bt_ci_compliance;
|
||||
priv->bt_traffic_load = bt_load;
|
||||
priv->bt_status = bt_status;
|
||||
}
|
||||
|
||||
static void iwl_bg_restart(struct work_struct *data)
|
||||
{
|
||||
struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
|
||||
@ -2647,50 +2540,13 @@ static void iwl_bg_restart(struct work_struct *data)
|
||||
return;
|
||||
|
||||
if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
|
||||
struct iwl_rxon_context *ctx;
|
||||
bool bt_full_concurrent;
|
||||
u8 bt_ci_compliance;
|
||||
u8 bt_load;
|
||||
u8 bt_status;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
for_each_context(priv, ctx)
|
||||
ctx->vif = NULL;
|
||||
priv->is_open = 0;
|
||||
|
||||
/*
|
||||
* __iwl_down() will clear the BT status variables,
|
||||
* which is correct, but when we restart we really
|
||||
* want to keep them so restore them afterwards.
|
||||
*
|
||||
* The restart process will later pick them up and
|
||||
* re-configure the hw when we reconfigure the BT
|
||||
* command.
|
||||
*/
|
||||
bt_full_concurrent = priv->bt_full_concurrent;
|
||||
bt_ci_compliance = priv->bt_ci_compliance;
|
||||
bt_load = priv->bt_traffic_load;
|
||||
bt_status = priv->bt_status;
|
||||
|
||||
__iwl_down(priv);
|
||||
|
||||
priv->bt_full_concurrent = bt_full_concurrent;
|
||||
priv->bt_ci_compliance = bt_ci_compliance;
|
||||
priv->bt_traffic_load = bt_load;
|
||||
priv->bt_status = bt_status;
|
||||
|
||||
iwlagn_prepare_restart(priv);
|
||||
mutex_unlock(&priv->mutex);
|
||||
iwl_cancel_deferred_work(priv);
|
||||
ieee80211_restart_hw(priv->hw);
|
||||
} else {
|
||||
iwl_down(priv);
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
return;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
__iwl_up(priv);
|
||||
mutex_unlock(&priv->mutex);
|
||||
WARN_ON(1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2801,8 +2657,6 @@ unlock:
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define UCODE_READY_TIMEOUT (4 * HZ)
|
||||
|
||||
/*
|
||||
* Not a mac80211 entry point function, but it fits in with all the
|
||||
* other mac80211 functions grouped here.
|
||||
@ -2895,31 +2749,17 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw)
|
||||
mutex_lock(&priv->mutex);
|
||||
ret = __iwl_up(priv);
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (iwl_is_rfkill(priv))
|
||||
goto out;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Start UP work done.\n");
|
||||
|
||||
/* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from
|
||||
* mac80211 will not be run successfully. */
|
||||
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
|
||||
test_bit(STATUS_READY, &priv->status),
|
||||
UCODE_READY_TIMEOUT);
|
||||
if (!ret) {
|
||||
if (!test_bit(STATUS_READY, &priv->status)) {
|
||||
IWL_ERR(priv, "START_ALIVE timeout after %dms.\n",
|
||||
jiffies_to_msecs(UCODE_READY_TIMEOUT));
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
/* Now we should be done, and the READY bit should be set. */
|
||||
if (WARN_ON(!test_bit(STATUS_READY, &priv->status)))
|
||||
ret = -EIO;
|
||||
|
||||
iwlagn_led_enable(priv);
|
||||
|
||||
out:
|
||||
priv->is_open = 1;
|
||||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||
return 0;
|
||||
@ -2994,7 +2834,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "enter\n");
|
||||
|
||||
if (priv->cfg->mod_params->sw_crypto) {
|
||||
if (iwlagn_mod_params.sw_crypto) {
|
||||
IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@ -3506,8 +3346,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
|
||||
INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush);
|
||||
INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency);
|
||||
INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config);
|
||||
INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
|
||||
INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
|
||||
INIT_DELAYED_WORK(&priv->_agn.hw_roc_work, iwlagn_bg_roc_done);
|
||||
|
||||
iwl_setup_scan_deferred_work(priv);
|
||||
@ -3536,8 +3374,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
|
||||
if (priv->cfg->ops->lib->cancel_deferred_work)
|
||||
priv->cfg->ops->lib->cancel_deferred_work(priv);
|
||||
|
||||
cancel_delayed_work_sync(&priv->init_alive_start);
|
||||
cancel_delayed_work(&priv->alive_start);
|
||||
cancel_work_sync(&priv->run_time_calib_work);
|
||||
cancel_work_sync(&priv->beacon_update);
|
||||
|
||||
@ -3617,12 +3453,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
|
||||
priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF;
|
||||
}
|
||||
|
||||
/* Set the tx_power_user_lmt to the lowest power level
|
||||
* this value will get overwritten by channel max power avg
|
||||
* from eeprom */
|
||||
priv->tx_power_user_lmt = IWLAGN_TX_POWER_TARGET_POWER_MIN;
|
||||
priv->tx_power_next = IWLAGN_TX_POWER_TARGET_POWER_MIN;
|
||||
|
||||
ret = iwl_init_channel_map(priv);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
|
||||
@ -3692,14 +3522,14 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
|
||||
{
|
||||
priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
|
||||
priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
|
||||
if (priv->cfg->mod_params->amsdu_size_8K)
|
||||
if (iwlagn_mod_params.amsdu_size_8K)
|
||||
priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K);
|
||||
else
|
||||
priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K);
|
||||
|
||||
priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL;
|
||||
|
||||
if (priv->cfg->mod_params->disable_11n)
|
||||
if (iwlagn_mod_params.disable_11n)
|
||||
priv->cfg->sku &= ~IWL_SKU_N;
|
||||
|
||||
/* Device-specific setup */
|
||||
@ -3772,6 +3602,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
priv = hw->priv;
|
||||
/* At this point both hw and priv are allocated. */
|
||||
|
||||
priv->ucode_type = UCODE_SUBTYPE_NONE_LOADED;
|
||||
|
||||
/*
|
||||
* The default context is always valid,
|
||||
* more may be discovered when firmware
|
||||
@ -3912,8 +3744,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
* PCI Tx retries from interfering with C3 CPU state */
|
||||
pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
|
||||
|
||||
iwl_prepare_card_hw(priv);
|
||||
if (!priv->hw_ready) {
|
||||
if (iwl_prepare_card_hw(priv)) {
|
||||
IWL_WARN(priv, "Failed, HW not ready\n");
|
||||
goto out_iounmap;
|
||||
}
|
||||
@ -4069,17 +3900,9 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
|
||||
if (priv->mac80211_registered) {
|
||||
ieee80211_unregister_hw(priv->hw);
|
||||
priv->mac80211_registered = 0;
|
||||
} else {
|
||||
iwl_down(priv);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure device is reset to low power before unloading driver.
|
||||
* This may be redundant with iwl_down(), but there are paths to
|
||||
* run iwl_down() without calling apm_ops.stop(), and there are
|
||||
* paths to avoid running iwl_down() at all before leaving driver.
|
||||
* This (inexpensive) call *makes sure* device is reset.
|
||||
*/
|
||||
/* Reset to low power before unloading driver. */
|
||||
iwl_apm_stop(priv);
|
||||
|
||||
iwl_tt_exit(priv);
|
||||
@ -4306,21 +4129,21 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
|
||||
{IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)},
|
||||
{IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)},
|
||||
|
||||
/* 200 Series */
|
||||
{IWL_PCI_DEVICE(0x0894, 0x0022, iwl200_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0895, 0x0222, iwl200_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0894, 0x0422, iwl200_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0894, 0x0026, iwl200_bg_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0895, 0x0226, iwl200_bg_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0894, 0x0426, iwl200_bg_cfg)},
|
||||
/* 105 Series */
|
||||
{IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)},
|
||||
|
||||
/* 230 Series */
|
||||
{IWL_PCI_DEVICE(0x0892, 0x0062, iwl230_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0893, 0x0262, iwl230_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0892, 0x0462, iwl230_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0892, 0x0066, iwl230_bg_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0893, 0x0266, iwl230_bg_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0892, 0x0466, iwl230_bg_cfg)},
|
||||
/* 135 Series */
|
||||
{IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0892, 0x0066, iwl135_bg_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0893, 0x0266, iwl135_bg_cfg)},
|
||||
{IWL_PCI_DEVICE(0x0892, 0x0466, iwl135_bg_cfg)},
|
||||
|
||||
{0}
|
||||
};
|
||||
|
@ -102,10 +102,10 @@ extern struct iwl_cfg iwl2030_2bg_cfg;
|
||||
extern struct iwl_cfg iwl6035_2agn_cfg;
|
||||
extern struct iwl_cfg iwl6035_2abg_cfg;
|
||||
extern struct iwl_cfg iwl6035_2bg_cfg;
|
||||
extern struct iwl_cfg iwl200_bg_cfg;
|
||||
extern struct iwl_cfg iwl200_bgn_cfg;
|
||||
extern struct iwl_cfg iwl230_bg_cfg;
|
||||
extern struct iwl_cfg iwl230_bgn_cfg;
|
||||
extern struct iwl_cfg iwl105_bg_cfg;
|
||||
extern struct iwl_cfg iwl105_bgn_cfg;
|
||||
extern struct iwl_cfg iwl135_bg_cfg;
|
||||
extern struct iwl_cfg iwl135_bgn_cfg;
|
||||
|
||||
extern struct iwl_mod_params iwlagn_mod_params;
|
||||
extern struct iwl_hcmd_ops iwlagn_hcmd;
|
||||
@ -120,6 +120,19 @@ int iwl_alloc_isr_ict(struct iwl_priv *priv);
|
||||
void iwl_free_isr_ict(struct iwl_priv *priv);
|
||||
irqreturn_t iwl_isr_ict(int irq, void *data);
|
||||
|
||||
/* call this function to flush any scheduled tasklet */
|
||||
static inline void iwl_synchronize_irq(struct iwl_priv *priv)
|
||||
{
|
||||
/* wait to make sure we flush pending tasklet*/
|
||||
synchronize_irq(priv->pci_dev->irq);
|
||||
tasklet_kill(&priv->irq_tasklet);
|
||||
}
|
||||
|
||||
int iwl_prepare_card_hw(struct iwl_priv *priv);
|
||||
|
||||
int iwlagn_start_device(struct iwl_priv *priv);
|
||||
void iwlagn_stop_device(struct iwl_priv *priv);
|
||||
|
||||
/* tx queue */
|
||||
void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
|
||||
int txq_id, u32 index);
|
||||
@ -145,16 +158,14 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
|
||||
u32 changes);
|
||||
|
||||
/* uCode */
|
||||
int iwlagn_load_ucode(struct iwl_priv *priv);
|
||||
void iwlagn_rx_calib_result(struct iwl_priv *priv,
|
||||
struct iwl_rx_mem_buffer *rxb);
|
||||
void iwlagn_rx_calib_complete(struct iwl_priv *priv,
|
||||
struct iwl_rx_mem_buffer *rxb);
|
||||
void iwlagn_init_alive_start(struct iwl_priv *priv);
|
||||
int iwlagn_alive_notify(struct iwl_priv *priv);
|
||||
int iwl_verify_ucode(struct iwl_priv *priv, struct fw_desc *fw_desc);
|
||||
void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
|
||||
int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
|
||||
void iwlagn_send_prio_tbl(struct iwl_priv *priv);
|
||||
int iwlagn_run_init_ucode(struct iwl_priv *priv);
|
||||
int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
|
||||
struct fw_img *image,
|
||||
int subtype, int alternate_subtype);
|
||||
|
||||
/* lib */
|
||||
void iwl_check_abort_status(struct iwl_priv *priv,
|
||||
@ -245,8 +256,6 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
|
||||
struct ieee80211_vif *vif, bool add);
|
||||
|
||||
/* hcmd */
|
||||
int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx);
|
||||
int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
|
||||
int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
|
||||
|
||||
@ -318,17 +327,17 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
|
||||
/* eeprom */
|
||||
void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv);
|
||||
void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
|
||||
int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
|
||||
void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
|
||||
|
||||
/* notification wait support */
|
||||
void __acquires(wait_entry)
|
||||
iwlagn_init_notification_wait(struct iwl_priv *priv,
|
||||
struct iwl_notification_wait *wait_entry,
|
||||
u8 cmd,
|
||||
void (*fn)(struct iwl_priv *priv,
|
||||
struct iwl_rx_packet *pkt),
|
||||
u8 cmd);
|
||||
signed long __releases(wait_entry)
|
||||
struct iwl_rx_packet *pkt,
|
||||
void *data),
|
||||
void *fn_data);
|
||||
int __must_check __releases(wait_entry)
|
||||
iwlagn_wait_notification(struct iwl_priv *priv,
|
||||
struct iwl_notification_wait *wait_entry,
|
||||
unsigned long timeout);
|
||||
|
@ -386,7 +386,18 @@ struct iwl_tx_ant_config_cmd {
|
||||
*****************************************************************************/
|
||||
|
||||
#define UCODE_VALID_OK cpu_to_le32(0x1)
|
||||
#define INITIALIZE_SUBTYPE (9)
|
||||
|
||||
enum iwlagn_ucode_subtype {
|
||||
UCODE_SUBTYPE_REGULAR = 0,
|
||||
UCODE_SUBTYPE_REGULAR_NEW = 1,
|
||||
UCODE_SUBTYPE_INIT = 9,
|
||||
|
||||
/*
|
||||
* Not a valid subtype, the ucode has just a u8, so
|
||||
* we can use something > 0xff for this value.
|
||||
*/
|
||||
UCODE_SUBTYPE_NONE_LOADED = 0x100,
|
||||
};
|
||||
|
||||
/**
|
||||
* REPLY_ALIVE = 0x1 (response only, not a command)
|
||||
@ -422,49 +433,61 @@ struct iwl_tx_ant_config_cmd {
|
||||
*
|
||||
* 2) error_event_table_ptr indicates base of the error log. This contains
|
||||
* information about any uCode error that occurs. For agn, the format
|
||||
* of the error log is:
|
||||
*
|
||||
* __le32 valid; (nonzero) valid, (0) log is empty
|
||||
* __le32 error_id; type of error
|
||||
* __le32 pc; program counter
|
||||
* __le32 blink1; branch link
|
||||
* __le32 blink2; branch link
|
||||
* __le32 ilink1; interrupt link
|
||||
* __le32 ilink2; interrupt link
|
||||
* __le32 data1; error-specific data
|
||||
* __le32 data2; error-specific data
|
||||
* __le32 line; source code line of error
|
||||
* __le32 bcon_time; beacon timer
|
||||
* __le32 tsf_low; network timestamp function timer
|
||||
* __le32 tsf_hi; network timestamp function timer
|
||||
* __le32 gp1; GP1 timer register
|
||||
* __le32 gp2; GP2 timer register
|
||||
* __le32 gp3; GP3 timer register
|
||||
* __le32 ucode_ver; uCode version
|
||||
* __le32 hw_ver; HW Silicon version
|
||||
* __le32 brd_ver; HW board version
|
||||
* __le32 log_pc; log program counter
|
||||
* __le32 frame_ptr; frame pointer
|
||||
* __le32 stack_ptr; stack pointer
|
||||
* __le32 hcmd; last host command
|
||||
* __le32 isr0; isr status register LMPM_NIC_ISR0: rxtx_flag
|
||||
* __le32 isr1; isr status register LMPM_NIC_ISR1: host_flag
|
||||
* __le32 isr2; isr status register LMPM_NIC_ISR2: enc_flag
|
||||
* __le32 isr3; isr status register LMPM_NIC_ISR3: time_flag
|
||||
* __le32 isr4; isr status register LMPM_NIC_ISR4: wico interrupt
|
||||
* __le32 isr_pref; isr status register LMPM_NIC_PREF_STAT
|
||||
* __le32 wait_event; wait event() caller address
|
||||
* __le32 l2p_control; L2pControlField
|
||||
* __le32 l2p_duration; L2pDurationField
|
||||
* __le32 l2p_mhvalid; L2pMhValidBits
|
||||
* __le32 l2p_addr_match; L2pAddrMatchStat
|
||||
* __le32 lmpm_pmg_sel; indicate which clocks are turned on (LMPM_PMG_SEL)
|
||||
* __le32 u_timestamp; indicate when the date and time of the compilation
|
||||
* __le32 reserved;
|
||||
* of the error log is defined by struct iwl_error_event_table.
|
||||
*
|
||||
* The Linux driver can print both logs to the system log when a uCode error
|
||||
* occurs.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note: This structure is read from the device with IO accesses,
|
||||
* and the reading already does the endian conversion. As it is
|
||||
* read with u32-sized accesses, any members with a different size
|
||||
* need to be ordered correctly though!
|
||||
*/
|
||||
struct iwl_error_event_table {
|
||||
u32 valid; /* (nonzero) valid, (0) log is empty */
|
||||
u32 error_id; /* type of error */
|
||||
u32 pc; /* program counter */
|
||||
u32 blink1; /* branch link */
|
||||
u32 blink2; /* branch link */
|
||||
u32 ilink1; /* interrupt link */
|
||||
u32 ilink2; /* interrupt link */
|
||||
u32 data1; /* error-specific data */
|
||||
u32 data2; /* error-specific data */
|
||||
u32 line; /* source code line of error */
|
||||
u32 bcon_time; /* beacon timer */
|
||||
u32 tsf_low; /* network timestamp function timer */
|
||||
u32 tsf_hi; /* network timestamp function timer */
|
||||
u32 gp1; /* GP1 timer register */
|
||||
u32 gp2; /* GP2 timer register */
|
||||
u32 gp3; /* GP3 timer register */
|
||||
u32 ucode_ver; /* uCode version */
|
||||
u32 hw_ver; /* HW Silicon version */
|
||||
u32 brd_ver; /* HW board version */
|
||||
u32 log_pc; /* log program counter */
|
||||
u32 frame_ptr; /* frame pointer */
|
||||
u32 stack_ptr; /* stack pointer */
|
||||
u32 hcmd; /* last host command header */
|
||||
#if 0
|
||||
/* no need to read the remainder, we don't use the values */
|
||||
u32 isr0; /* isr status register LMPM_NIC_ISR0: rxtx_flag */
|
||||
u32 isr1; /* isr status register LMPM_NIC_ISR1: host_flag */
|
||||
u32 isr2; /* isr status register LMPM_NIC_ISR2: enc_flag */
|
||||
u32 isr3; /* isr status register LMPM_NIC_ISR3: time_flag */
|
||||
u32 isr4; /* isr status register LMPM_NIC_ISR4: wico interrupt */
|
||||
u32 isr_pref; /* isr status register LMPM_NIC_PREF_STAT */
|
||||
u32 wait_event; /* wait event() caller address */
|
||||
u32 l2p_control; /* L2pControlField */
|
||||
u32 l2p_duration; /* L2pDurationField */
|
||||
u32 l2p_mhvalid; /* L2pMhValidBits */
|
||||
u32 l2p_addr_match; /* L2pAddrMatchStat */
|
||||
u32 lmpm_pmg_sel; /* indicate which clocks are turned on (LMPM_PMG_SEL) */
|
||||
u32 u_timestamp; /* indicate when the date and time of the compilation */
|
||||
u32 flow_handler; /* FH read/write pointers, RX credit */
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
struct iwl_alive_resp {
|
||||
u8 ucode_minor;
|
||||
u8 ucode_major;
|
||||
@ -638,7 +661,7 @@ struct iwl_rxon_cmd {
|
||||
/*
|
||||
* REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
|
||||
*/
|
||||
struct iwl5000_rxon_assoc_cmd {
|
||||
struct iwl_rxon_assoc_cmd {
|
||||
__le32 flags;
|
||||
__le32 filter_flags;
|
||||
u8 ofdm_basic_rates;
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "iwl-power.h"
|
||||
#include "iwl-sta.h"
|
||||
#include "iwl-helpers.h"
|
||||
#include "iwl-agn.h"
|
||||
|
||||
|
||||
/*
|
||||
@ -94,7 +95,7 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
|
||||
max_bit_rate = MAX_BIT_RATE_40_MHZ;
|
||||
}
|
||||
|
||||
if (priv->cfg->mod_params->amsdu_size_8K)
|
||||
if (iwlagn_mod_params.amsdu_size_8K)
|
||||
ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
|
||||
|
||||
ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
|
||||
@ -135,6 +136,7 @@ int iwlcore_init_geos(struct iwl_priv *priv)
|
||||
struct ieee80211_channel *geo_ch;
|
||||
struct ieee80211_rate *rates;
|
||||
int i = 0;
|
||||
s8 max_tx_power = IWLAGN_TX_POWER_TARGET_POWER_MIN;
|
||||
|
||||
if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
|
||||
priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
|
||||
@ -208,8 +210,8 @@ int iwlcore_init_geos(struct iwl_priv *priv)
|
||||
|
||||
geo_ch->flags |= ch->ht40_extension_channel;
|
||||
|
||||
if (ch->max_power_avg > priv->tx_power_device_lmt)
|
||||
priv->tx_power_device_lmt = ch->max_power_avg;
|
||||
if (ch->max_power_avg > max_tx_power)
|
||||
max_tx_power = ch->max_power_avg;
|
||||
} else {
|
||||
geo_ch->flags |= IEEE80211_CHAN_DISABLED;
|
||||
}
|
||||
@ -222,6 +224,10 @@ int iwlcore_init_geos(struct iwl_priv *priv)
|
||||
geo_ch->flags);
|
||||
}
|
||||
|
||||
priv->tx_power_device_lmt = max_tx_power;
|
||||
priv->tx_power_user_lmt = max_tx_power;
|
||||
priv->tx_power_next = max_tx_power;
|
||||
|
||||
if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
|
||||
priv->cfg->sku & IWL_SKU_A) {
|
||||
IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
|
||||
@ -410,72 +416,72 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
|
||||
int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||
{
|
||||
struct iwl_rxon_cmd *rxon = &ctx->staging;
|
||||
bool error = false;
|
||||
u32 errors = 0;
|
||||
|
||||
if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
|
||||
if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) {
|
||||
IWL_WARN(priv, "check 2.4G: wrong narrow\n");
|
||||
error = true;
|
||||
errors |= BIT(0);
|
||||
}
|
||||
if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) {
|
||||
IWL_WARN(priv, "check 2.4G: wrong radar\n");
|
||||
error = true;
|
||||
errors |= BIT(1);
|
||||
}
|
||||
} else {
|
||||
if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) {
|
||||
IWL_WARN(priv, "check 5.2G: not short slot!\n");
|
||||
error = true;
|
||||
errors |= BIT(2);
|
||||
}
|
||||
if (rxon->flags & RXON_FLG_CCK_MSK) {
|
||||
IWL_WARN(priv, "check 5.2G: CCK!\n");
|
||||
error = true;
|
||||
errors |= BIT(3);
|
||||
}
|
||||
}
|
||||
if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) {
|
||||
IWL_WARN(priv, "mac/bssid mcast!\n");
|
||||
error = true;
|
||||
errors |= BIT(4);
|
||||
}
|
||||
|
||||
/* make sure basic rates 6Mbps and 1Mbps are supported */
|
||||
if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 &&
|
||||
(rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) {
|
||||
IWL_WARN(priv, "neither 1 nor 6 are basic\n");
|
||||
error = true;
|
||||
errors |= BIT(5);
|
||||
}
|
||||
|
||||
if (le16_to_cpu(rxon->assoc_id) > 2007) {
|
||||
IWL_WARN(priv, "aid > 2007\n");
|
||||
error = true;
|
||||
errors |= BIT(6);
|
||||
}
|
||||
|
||||
if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
|
||||
== (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) {
|
||||
IWL_WARN(priv, "CCK and short slot\n");
|
||||
error = true;
|
||||
errors |= BIT(7);
|
||||
}
|
||||
|
||||
if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
|
||||
== (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) {
|
||||
IWL_WARN(priv, "CCK and auto detect");
|
||||
error = true;
|
||||
errors |= BIT(8);
|
||||
}
|
||||
|
||||
if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
|
||||
RXON_FLG_TGG_PROTECT_MSK)) ==
|
||||
RXON_FLG_TGG_PROTECT_MSK) {
|
||||
IWL_WARN(priv, "TGg but no auto-detect\n");
|
||||
error = true;
|
||||
errors |= BIT(9);
|
||||
}
|
||||
|
||||
if (error)
|
||||
IWL_WARN(priv, "Tuning to channel %d\n",
|
||||
le16_to_cpu(rxon->channel));
|
||||
|
||||
if (error) {
|
||||
IWL_ERR(priv, "Invalid RXON\n");
|
||||
return -EINVAL;
|
||||
if (rxon->channel == 0) {
|
||||
IWL_WARN(priv, "zero channel is invalid\n");
|
||||
errors |= BIT(10);
|
||||
}
|
||||
return 0;
|
||||
|
||||
WARN(errors, "Invalid RXON (%#x), channel %d",
|
||||
errors, le16_to_cpu(rxon->channel));
|
||||
|
||||
return errors ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -867,6 +873,19 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv,
|
||||
}
|
||||
#endif
|
||||
|
||||
static void iwlagn_abort_notification_waits(struct iwl_priv *priv)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct iwl_notification_wait *wait_entry;
|
||||
|
||||
spin_lock_irqsave(&priv->_agn.notif_wait_lock, flags);
|
||||
list_for_each_entry(wait_entry, &priv->_agn.notif_waits, list)
|
||||
wait_entry->aborted = true;
|
||||
spin_unlock_irqrestore(&priv->_agn.notif_wait_lock, flags);
|
||||
|
||||
wake_up_all(&priv->_agn.notif_waitq);
|
||||
}
|
||||
|
||||
void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
|
||||
{
|
||||
unsigned int reload_msec;
|
||||
@ -878,6 +897,8 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
|
||||
/* Cancel currently queued command. */
|
||||
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
|
||||
|
||||
iwlagn_abort_notification_waits(priv);
|
||||
|
||||
/* Keep the restart process from trying to send host
|
||||
* commands by clearing the ready bit */
|
||||
clear_bit(STATUS_READY, &priv->status);
|
||||
@ -906,7 +927,7 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
|
||||
}
|
||||
|
||||
if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
|
||||
if (priv->cfg->mod_params->restart_fw) {
|
||||
if (iwlagn_mod_params.restart_fw) {
|
||||
IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
|
||||
"Restarting adapter due to uCode error.\n");
|
||||
queue_work(priv->workqueue, &priv->restart);
|
||||
@ -975,6 +996,8 @@ void iwl_apm_stop(struct iwl_priv *priv)
|
||||
{
|
||||
IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n");
|
||||
|
||||
clear_bit(STATUS_DEVICE_ENABLED, &priv->status);
|
||||
|
||||
/* Stop device's DMA activity */
|
||||
iwl_apm_stop_master(priv);
|
||||
|
||||
@ -1089,6 +1112,8 @@ int iwl_apm_init(struct iwl_priv *priv)
|
||||
iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
|
||||
APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
|
||||
|
||||
set_bit(STATUS_DEVICE_ENABLED, &priv->status);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
@ -1723,7 +1748,7 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external)
|
||||
* detect failure), then fw_restart module parameter
|
||||
* need to be check before performing firmware reload
|
||||
*/
|
||||
if (!external && !priv->cfg->mod_params->restart_fw) {
|
||||
if (!external && !iwlagn_mod_params.restart_fw) {
|
||||
IWL_DEBUG_INFO(priv, "Cancel firmware reload based on "
|
||||
"module parameter setting\n");
|
||||
break;
|
||||
@ -1740,6 +1765,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
{
|
||||
struct iwl_priv *priv = hw->priv;
|
||||
struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
|
||||
struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS];
|
||||
struct iwl_rxon_context *tmp;
|
||||
u32 interface_modes;
|
||||
int err;
|
||||
@ -1764,6 +1790,19 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Refuse a change that should be done by moving from the PAN
|
||||
* context to the BSS context instead, if the BSS context is
|
||||
* available and can support the new interface type.
|
||||
*/
|
||||
if (ctx->ctxid == IWL_RXON_CTX_PAN && !bss_ctx->vif &&
|
||||
(bss_ctx->interface_modes & BIT(newtype) ||
|
||||
bss_ctx->exclusive_interface_modes & BIT(newtype))) {
|
||||
BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ctx->exclusive_interface_modes & BIT(newtype)) {
|
||||
for_each_context(priv, tmp) {
|
||||
if (ctx == tmp)
|
||||
|
@ -90,7 +90,6 @@ struct iwl_cmd;
|
||||
#define IWL_CMD(x) case x: return #x
|
||||
|
||||
struct iwl_hcmd_ops {
|
||||
int (*rxon_assoc)(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
|
||||
int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
|
||||
void (*set_rxon_chain)(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx);
|
||||
@ -122,19 +121,6 @@ struct iwl_apm_ops {
|
||||
void (*config)(struct iwl_priv *priv);
|
||||
};
|
||||
|
||||
struct iwl_debugfs_ops {
|
||||
ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
ssize_t (*tx_stats_read)(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
ssize_t (*general_stats_read)(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
ssize_t (*bt_stats_read)(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
ssize_t (*reply_tx_error)(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
};
|
||||
|
||||
struct iwl_temp_ops {
|
||||
void (*temperature)(struct iwl_priv *priv);
|
||||
};
|
||||
@ -183,7 +169,6 @@ struct iwl_lib_ops {
|
||||
int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
|
||||
void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
|
||||
|
||||
struct iwl_debugfs_ops debugfs_ops;
|
||||
};
|
||||
|
||||
/* NIC specific ops */
|
||||
@ -326,8 +311,6 @@ struct iwl_cfg {
|
||||
u16 eeprom_ver;
|
||||
u16 eeprom_calib_ver;
|
||||
const struct iwl_ops *ops;
|
||||
/* module based parameters which can be set from modprobe cmd */
|
||||
const struct iwl_mod_params *mod_params;
|
||||
/* params not likely to change within a device family */
|
||||
struct iwl_base_params *base_params;
|
||||
/* params likely to change within a device family */
|
||||
@ -592,6 +575,7 @@ void iwlcore_free_geos(struct iwl_priv *priv);
|
||||
#define STATUS_SCAN_HW 15
|
||||
#define STATUS_POWER_PMI 16
|
||||
#define STATUS_FW_ERROR 17
|
||||
#define STATUS_DEVICE_ENABLED 18
|
||||
|
||||
|
||||
static inline int iwl_is_ready(struct iwl_priv *priv)
|
||||
@ -644,11 +628,6 @@ void iwl_apm_stop(struct iwl_priv *priv);
|
||||
int iwl_apm_init(struct iwl_priv *priv);
|
||||
|
||||
int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
|
||||
static inline int iwl_send_rxon_assoc(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx)
|
||||
{
|
||||
return priv->cfg->ops->hcmd->rxon_assoc(priv, ctx);
|
||||
}
|
||||
static inline int iwlcore_commit_rxon(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -479,6 +479,10 @@ struct fw_desc {
|
||||
u32 len; /* bytes */
|
||||
};
|
||||
|
||||
struct fw_img {
|
||||
struct fw_desc code, data;
|
||||
};
|
||||
|
||||
/* v1/v2 uCode file layout */
|
||||
struct iwl_ucode_header {
|
||||
__le32 ver; /* major/minor/API/serial */
|
||||
@ -543,12 +547,13 @@ enum iwl_ucode_tlv_type {
|
||||
* enum iwl_ucode_tlv_flag - ucode API flags
|
||||
* @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
|
||||
* was a separate TLV but moved here to save space.
|
||||
* @IWL_UCODE_TLV_FLAGS_RESERVED_1: reserved
|
||||
* @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
|
||||
* treats good CRC threshold as a boolean
|
||||
* @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
|
||||
*/
|
||||
enum iwl_ucode_tlv_flag {
|
||||
IWL_UCODE_TLV_FLAGS_PAN = BIT(0),
|
||||
IWL_UCODE_TLV_FLAGS_RESERVED_1 = BIT(1),
|
||||
IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1),
|
||||
IWL_UCODE_TLV_FLAGS_MFP = BIT(2),
|
||||
};
|
||||
|
||||
@ -794,12 +799,6 @@ struct iwl_calib_result {
|
||||
size_t buf_len;
|
||||
};
|
||||
|
||||
enum ucode_type {
|
||||
UCODE_NONE = 0,
|
||||
UCODE_INIT,
|
||||
UCODE_RT
|
||||
};
|
||||
|
||||
/* Sensitivity calib data */
|
||||
struct iwl_sensitivity_data {
|
||||
u32 auto_corr_ofdm;
|
||||
@ -1105,10 +1104,12 @@ struct iwl_force_reset {
|
||||
struct iwl_notification_wait {
|
||||
struct list_head list;
|
||||
|
||||
void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt);
|
||||
void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt,
|
||||
void *data);
|
||||
void *fn_data;
|
||||
|
||||
u8 cmd;
|
||||
bool triggered;
|
||||
bool triggered, aborted;
|
||||
};
|
||||
|
||||
enum iwl_rxon_context_id {
|
||||
@ -1263,6 +1264,8 @@ struct iwl_priv {
|
||||
/* max number of station keys */
|
||||
u8 sta_key_max_num;
|
||||
|
||||
bool new_scan_threshold_behaviour;
|
||||
|
||||
/* EEPROM MAC addresses */
|
||||
struct mac_address addresses[2];
|
||||
|
||||
@ -1270,11 +1273,10 @@ struct iwl_priv {
|
||||
int fw_index; /* firmware we're trying to load */
|
||||
u32 ucode_ver; /* version of ucode, copy of
|
||||
iwl_ucode.ver */
|
||||
struct fw_desc ucode_code; /* runtime inst */
|
||||
struct fw_desc ucode_data; /* runtime data original */
|
||||
struct fw_desc ucode_init; /* initialization inst */
|
||||
struct fw_desc ucode_init_data; /* initialization data */
|
||||
enum ucode_type ucode_type;
|
||||
struct fw_img ucode_rt;
|
||||
struct fw_img ucode_init;
|
||||
|
||||
enum iwlagn_ucode_subtype ucode_type;
|
||||
u8 ucode_write_complete; /* the image write is complete */
|
||||
char firmware_name[25];
|
||||
|
||||
@ -1472,8 +1474,6 @@ struct iwl_priv {
|
||||
|
||||
struct tasklet_struct irq_tasklet;
|
||||
|
||||
struct delayed_work init_alive_start;
|
||||
struct delayed_work alive_start;
|
||||
struct delayed_work scan_check;
|
||||
|
||||
/* TX Power */
|
||||
@ -1506,7 +1506,6 @@ struct iwl_priv {
|
||||
struct timer_list statistics_periodic;
|
||||
struct timer_list ucode_trace;
|
||||
struct timer_list watchdog;
|
||||
bool hw_ready;
|
||||
|
||||
struct iwl_event_log event_log;
|
||||
|
||||
|
@ -142,6 +142,45 @@ static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* The device's EEPROM semaphore prevents conflicts between driver and uCode
|
||||
* when accessing the EEPROM; each access is a series of pulses to/from the
|
||||
* EEPROM chip, not a single event, so even reads could conflict if they
|
||||
* weren't arbitrated by the semaphore.
|
||||
*/
|
||||
static int iwl_eeprom_acquire_semaphore(struct iwl_priv *priv)
|
||||
{
|
||||
u16 count;
|
||||
int ret;
|
||||
|
||||
for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
|
||||
/* Request semaphore */
|
||||
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
|
||||
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
|
||||
|
||||
/* See if we got it */
|
||||
ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
|
||||
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
|
||||
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
|
||||
EEPROM_SEM_TIMEOUT);
|
||||
if (ret >= 0) {
|
||||
IWL_DEBUG_EEPROM(priv,
|
||||
"Acquired semaphore after %d tries.\n",
|
||||
count+1);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iwl_eeprom_release_semaphore(struct iwl_priv *priv)
|
||||
{
|
||||
iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
|
||||
CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
|
||||
|
||||
}
|
||||
|
||||
static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
|
||||
{
|
||||
u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK;
|
||||
@ -421,7 +460,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
|
||||
}
|
||||
|
||||
/* Make sure driver (instead of uCode) is allowed to read EEPROM */
|
||||
ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv);
|
||||
ret = iwl_eeprom_acquire_semaphore(priv);
|
||||
if (ret < 0) {
|
||||
IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
|
||||
ret = -ENOENT;
|
||||
@ -488,7 +527,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
|
||||
|
||||
ret = 0;
|
||||
done:
|
||||
priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv);
|
||||
iwl_eeprom_release_semaphore(priv);
|
||||
|
||||
err:
|
||||
if (ret)
|
||||
@ -711,13 +750,6 @@ int iwl_init_channel_map(struct iwl_priv *priv)
|
||||
flags & EEPROM_CHANNEL_RADAR))
|
||||
? "" : "not ");
|
||||
|
||||
/* Set the tx_power_user_lmt to the highest power
|
||||
* supported by any channel */
|
||||
if (eeprom_ch_info[ch].max_power_avg >
|
||||
priv->tx_power_user_lmt)
|
||||
priv->tx_power_user_lmt =
|
||||
eeprom_ch_info[ch].max_power_avg;
|
||||
|
||||
ch_info++;
|
||||
}
|
||||
}
|
||||
|
@ -294,9 +294,6 @@ extern const u8 iwl_eeprom_band_1[14];
|
||||
|
||||
struct iwl_eeprom_ops {
|
||||
const u32 regulatory_bands[7];
|
||||
int (*acquire_semaphore) (struct iwl_priv *priv);
|
||||
void (*release_semaphore) (struct iwl_priv *priv);
|
||||
u16 (*calib_version) (struct iwl_priv *priv);
|
||||
const u8* (*query_addr) (const struct iwl_priv *priv, size_t offset);
|
||||
void (*update_enhanced_txpower) (struct iwl_priv *priv);
|
||||
};
|
||||
|
@ -64,30 +64,6 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd)
|
||||
return --index & (n_bd - 1);
|
||||
}
|
||||
|
||||
/* TODO: Move fw_desc functions to iwl-pci.ko */
|
||||
static inline void iwl_free_fw_desc(struct pci_dev *pci_dev,
|
||||
struct fw_desc *desc)
|
||||
{
|
||||
if (desc->v_addr)
|
||||
dma_free_coherent(&pci_dev->dev, desc->len,
|
||||
desc->v_addr, desc->p_addr);
|
||||
desc->v_addr = NULL;
|
||||
desc->len = 0;
|
||||
}
|
||||
|
||||
static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
|
||||
struct fw_desc *desc)
|
||||
{
|
||||
if (!desc->len) {
|
||||
desc->v_addr = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len,
|
||||
&desc->p_addr, GFP_KERNEL);
|
||||
return (desc->v_addr != NULL) ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* we have 8 bits used like this:
|
||||
*
|
||||
|
@ -73,10 +73,9 @@ int iwl_poll_bit(struct iwl_priv *priv, u32 addr,
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
int iwl_grab_nic_access(struct iwl_priv *priv)
|
||||
int iwl_grab_nic_access_silent(struct iwl_priv *priv)
|
||||
{
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
lockdep_assert_held(&priv->reg_lock);
|
||||
|
||||
@ -107,9 +106,6 @@ int iwl_grab_nic_access(struct iwl_priv *priv)
|
||||
(CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
|
||||
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
|
||||
if (ret < 0) {
|
||||
val = iwl_read32(priv, CSR_GP_CNTRL);
|
||||
IWL_ERR(priv,
|
||||
"MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
|
||||
iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
|
||||
return -EIO;
|
||||
}
|
||||
@ -117,6 +113,18 @@ int iwl_grab_nic_access(struct iwl_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iwl_grab_nic_access(struct iwl_priv *priv)
|
||||
{
|
||||
int ret = iwl_grab_nic_access_silent(priv);
|
||||
if (ret) {
|
||||
u32 val = iwl_read32(priv, CSR_GP_CNTRL);
|
||||
IWL_ERR(priv,
|
||||
"MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iwl_release_nic_access(struct iwl_priv *priv)
|
||||
{
|
||||
lockdep_assert_held(&priv->reg_lock);
|
||||
@ -242,20 +250,32 @@ void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
|
||||
spin_unlock_irqrestore(&priv->reg_lock, flags);
|
||||
}
|
||||
|
||||
u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
|
||||
void _iwl_read_targ_mem_words(struct iwl_priv *priv, u32 addr,
|
||||
void *buf, int words)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 value;
|
||||
int offs;
|
||||
u32 *vals = buf;
|
||||
|
||||
spin_lock_irqsave(&priv->reg_lock, flags);
|
||||
iwl_grab_nic_access(priv);
|
||||
|
||||
iwl_write32(priv, HBUS_TARG_MEM_RADDR, addr);
|
||||
rmb();
|
||||
value = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
|
||||
|
||||
for (offs = 0; offs < words; offs++)
|
||||
vals[offs] = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
|
||||
|
||||
iwl_release_nic_access(priv);
|
||||
spin_unlock_irqrestore(&priv->reg_lock, flags);
|
||||
}
|
||||
|
||||
u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
|
||||
{
|
||||
u32 value;
|
||||
|
||||
_iwl_read_targ_mem_words(priv, addr, &value, 1);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,7 @@ int iwl_poll_bit(struct iwl_priv *priv, u32 addr,
|
||||
int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask,
|
||||
int timeout);
|
||||
|
||||
int iwl_grab_nic_access_silent(struct iwl_priv *priv);
|
||||
int iwl_grab_nic_access(struct iwl_priv *priv);
|
||||
void iwl_release_nic_access(struct iwl_priv *priv);
|
||||
|
||||
@ -76,6 +77,16 @@ void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
|
||||
u32 bits, u32 mask);
|
||||
void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask);
|
||||
|
||||
void _iwl_read_targ_mem_words(struct iwl_priv *priv, u32 addr,
|
||||
void *buf, int words);
|
||||
|
||||
#define iwl_read_targ_mem_words(priv, addr, buf, bufsize) \
|
||||
do { \
|
||||
BUILD_BUG_ON((bufsize) % sizeof(u32)); \
|
||||
_iwl_read_targ_mem_words(priv, addr, buf, \
|
||||
(bufsize) / sizeof(u32));\
|
||||
} while (0)
|
||||
|
||||
u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr);
|
||||
void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val);
|
||||
#endif
|
||||
|
@ -225,55 +225,6 @@ err_bd:
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static void iwl_rx_reply_alive(struct iwl_priv *priv,
|
||||
struct iwl_rx_mem_buffer *rxb)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
struct iwl_alive_resp *palive;
|
||||
struct delayed_work *pwork;
|
||||
|
||||
palive = &pkt->u.alive_frame;
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
|
||||
"0x%01X 0x%01X\n",
|
||||
palive->is_valid, palive->ver_type,
|
||||
palive->ver_subtype);
|
||||
|
||||
priv->device_pointers.log_event_table =
|
||||
le32_to_cpu(palive->log_event_table_ptr);
|
||||
priv->device_pointers.error_event_table =
|
||||
le32_to_cpu(palive->error_event_table_ptr);
|
||||
|
||||
if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
|
||||
IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
|
||||
pwork = &priv->init_alive_start;
|
||||
} else {
|
||||
IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
|
||||
pwork = &priv->alive_start;
|
||||
}
|
||||
|
||||
/* We delay the ALIVE response by 5ms to
|
||||
* give the HW RF Kill time to activate... */
|
||||
if (palive->is_valid == UCODE_VALID_OK)
|
||||
queue_delayed_work(priv->workqueue, pwork,
|
||||
msecs_to_jiffies(5));
|
||||
else {
|
||||
IWL_WARN(priv, "%s uCode did not respond OK.\n",
|
||||
(palive->ver_subtype == INITIALIZE_SUBTYPE) ?
|
||||
"init" : "runtime");
|
||||
/*
|
||||
* If fail to load init uCode,
|
||||
* let's try to load the init uCode again.
|
||||
* We should not get into this situation, but if it
|
||||
* does happen, we should not move on and loading "runtime"
|
||||
* without proper calibrate the device.
|
||||
*/
|
||||
if (palive->ver_subtype == INITIALIZE_SUBTYPE)
|
||||
priv->ucode_type = UCODE_NONE;
|
||||
queue_work(priv->workqueue, &priv->restart);
|
||||
}
|
||||
}
|
||||
|
||||
static void iwl_rx_reply_error(struct iwl_priv *priv,
|
||||
struct iwl_rx_mem_buffer *rxb)
|
||||
{
|
||||
@ -482,7 +433,6 @@ static void iwl_recover_from_statistics(struct iwl_priv *priv,
|
||||
struct statistics_tx *tx,
|
||||
unsigned long stamp)
|
||||
{
|
||||
const struct iwl_mod_params *mod_params = priv->cfg->mod_params;
|
||||
unsigned int msecs;
|
||||
|
||||
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
@ -498,13 +448,13 @@ static void iwl_recover_from_statistics(struct iwl_priv *priv,
|
||||
if (msecs < 99)
|
||||
return;
|
||||
|
||||
if (mod_params->ack_check && !iwl_good_ack_health(priv, tx)) {
|
||||
if (iwlagn_mod_params.ack_check && !iwl_good_ack_health(priv, tx)) {
|
||||
IWL_ERR(priv, "low ack count detected, restart firmware\n");
|
||||
if (!iwl_force_reset(priv, IWL_FW_RESET, false))
|
||||
return;
|
||||
}
|
||||
|
||||
if (mod_params->plcp_check &&
|
||||
if (iwlagn_mod_params.plcp_check &&
|
||||
!iwl_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs))
|
||||
iwl_force_reset(priv, IWL_RF_RESET, false);
|
||||
}
|
||||
@ -895,7 +845,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
|
||||
}
|
||||
|
||||
/* In case of HW accelerated crypto and bad decryption, drop */
|
||||
if (!priv->cfg->mod_params->sw_crypto &&
|
||||
if (!iwlagn_mod_params.sw_crypto &&
|
||||
iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
|
||||
return;
|
||||
|
||||
@ -1125,7 +1075,6 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
|
||||
|
||||
handlers = priv->rx_handlers;
|
||||
|
||||
handlers[REPLY_ALIVE] = iwl_rx_reply_alive;
|
||||
handlers[REPLY_ERROR] = iwl_rx_reply_error;
|
||||
handlers[CHANNEL_SWITCH_NOTIFICATION] = iwl_rx_csa;
|
||||
handlers[SPECTRUM_MEASURE_NOTIFICATION] = iwl_rx_spectrum_measure_notif;
|
||||
|
@ -1,92 +0,0 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* Portions of this file are derived from the ieee80211 subsystem header files.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution in the
|
||||
* file called LICENSE.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <ilw@linux.intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __iwl_spectrum_h__
|
||||
#define __iwl_spectrum_h__
|
||||
enum { /* ieee80211_basic_report.map */
|
||||
IEEE80211_BASIC_MAP_BSS = (1 << 0),
|
||||
IEEE80211_BASIC_MAP_OFDM = (1 << 1),
|
||||
IEEE80211_BASIC_MAP_UNIDENTIFIED = (1 << 2),
|
||||
IEEE80211_BASIC_MAP_RADAR = (1 << 3),
|
||||
IEEE80211_BASIC_MAP_UNMEASURED = (1 << 4),
|
||||
/* Bits 5-7 are reserved */
|
||||
|
||||
};
|
||||
struct ieee80211_basic_report {
|
||||
u8 channel;
|
||||
__le64 start_time;
|
||||
__le16 duration;
|
||||
u8 map;
|
||||
} __packed;
|
||||
|
||||
enum { /* ieee80211_measurement_request.mode */
|
||||
/* Bit 0 is reserved */
|
||||
IEEE80211_MEASUREMENT_ENABLE = (1 << 1),
|
||||
IEEE80211_MEASUREMENT_REQUEST = (1 << 2),
|
||||
IEEE80211_MEASUREMENT_REPORT = (1 << 3),
|
||||
/* Bits 4-7 are reserved */
|
||||
};
|
||||
|
||||
enum {
|
||||
IEEE80211_REPORT_BASIC = 0, /* required */
|
||||
IEEE80211_REPORT_CCA = 1, /* optional */
|
||||
IEEE80211_REPORT_RPI = 2, /* optional */
|
||||
/* 3-255 reserved */
|
||||
};
|
||||
|
||||
struct ieee80211_measurement_params {
|
||||
u8 channel;
|
||||
__le64 start_time;
|
||||
__le16 duration;
|
||||
} __packed;
|
||||
|
||||
struct ieee80211_info_element {
|
||||
u8 id;
|
||||
u8 len;
|
||||
u8 data[0];
|
||||
} __packed;
|
||||
|
||||
struct ieee80211_measurement_request {
|
||||
struct ieee80211_info_element ie;
|
||||
u8 token;
|
||||
u8 mode;
|
||||
u8 type;
|
||||
struct ieee80211_measurement_params params[0];
|
||||
} __packed;
|
||||
|
||||
struct ieee80211_measurement_report {
|
||||
struct ieee80211_info_element ie;
|
||||
u8 token;
|
||||
u8 mode;
|
||||
u8 type;
|
||||
union {
|
||||
struct ieee80211_basic_report basic[0];
|
||||
} u;
|
||||
} __packed;
|
||||
|
||||
#endif
|
@ -621,9 +621,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
struct iwl_cmd_meta *meta;
|
||||
struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
|
||||
unsigned long flags;
|
||||
void (*callback) (struct iwl_priv *priv, struct iwl_device_cmd *cmd,
|
||||
struct iwl_rx_packet *pkt);
|
||||
|
||||
|
||||
/* If a Tx command is being handled and it isn't in the actual
|
||||
* command queue then there a command routing bug has been introduced
|
||||
@ -637,8 +634,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->hcmd_lock, flags);
|
||||
|
||||
cmd_index = get_cmd_index(&txq->q, index, huge);
|
||||
cmd = txq->cmd[cmd_index];
|
||||
meta = &txq->meta[cmd_index];
|
||||
@ -648,13 +643,14 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
dma_unmap_len(meta, len),
|
||||
PCI_DMA_BIDIRECTIONAL);
|
||||
|
||||
callback = NULL;
|
||||
/* Input error checking is done when commands are added to queue. */
|
||||
if (meta->flags & CMD_WANT_SKB) {
|
||||
meta->source->reply_page = (unsigned long)rxb_addr(rxb);
|
||||
rxb->page = NULL;
|
||||
} else
|
||||
callback = meta->callback;
|
||||
} else if (meta->callback)
|
||||
meta->callback(priv, cmd, pkt);
|
||||
|
||||
spin_lock_irqsave(&priv->hcmd_lock, flags);
|
||||
|
||||
iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index);
|
||||
|
||||
@ -669,7 +665,4 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
meta->flags = 0;
|
||||
|
||||
spin_unlock_irqrestore(&priv->hcmd_lock, flags);
|
||||
|
||||
if (callback)
|
||||
callback(priv, cmd, pkt);
|
||||
}
|
||||
|
@ -122,8 +122,10 @@ static u8 lbs_auth_to_authtype(enum nl80211_auth_type auth_type)
|
||||
}
|
||||
|
||||
|
||||
/* Various firmware commands need the list of supported rates, but with
|
||||
the hight-bit set for basic rates */
|
||||
/*
|
||||
* Various firmware commands need the list of supported rates, but with
|
||||
* the hight-bit set for basic rates
|
||||
*/
|
||||
static int lbs_add_rates(u8 *rates)
|
||||
{
|
||||
size_t i;
|
||||
@ -425,7 +427,7 @@ static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len)
|
||||
return ie_len + 2;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
/*
|
||||
* Set Channel
|
||||
*/
|
||||
|
||||
@ -452,7 +454,7 @@ static int lbs_cfg_set_channel(struct wiphy *wiphy,
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
/*
|
||||
* Scanning
|
||||
*/
|
||||
|
||||
@ -538,8 +540,10 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Validity check: the TLV holds TSF values with 8 bytes each, so
|
||||
* the size in the TLV must match the nr_sets value */
|
||||
/*
|
||||
* Validity check: the TLV holds TSF values with 8 bytes each, so
|
||||
* the size in the TLV must match the nr_sets value
|
||||
*/
|
||||
i = get_unaligned_le16(tsfdesc);
|
||||
tsfdesc += 2;
|
||||
if (i / 8 != scanresp->nr_sets) {
|
||||
@ -581,8 +585,10 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
|
||||
|
||||
/* To find out the channel, we must parse the IEs */
|
||||
ie = pos;
|
||||
/* 6+1+8+2+2: size of BSSID, RSSI, time stamp, beacon
|
||||
interval, capabilities */
|
||||
/*
|
||||
* 6+1+8+2+2: size of BSSID, RSSI, time stamp, beacon
|
||||
* interval, capabilities
|
||||
*/
|
||||
ielen = left = len - (6 + 1 + 8 + 2 + 2);
|
||||
while (left >= 2) {
|
||||
u8 id, elen;
|
||||
@ -790,7 +796,7 @@ static int lbs_cfg_scan(struct wiphy *wiphy,
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
/*
|
||||
* Events
|
||||
*/
|
||||
|
||||
@ -825,7 +831,7 @@ void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event)
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
/*
|
||||
* Connect/disconnect
|
||||
*/
|
||||
|
||||
@ -950,8 +956,10 @@ static int lbs_enable_rsn(struct lbs_private *priv, int enable)
|
||||
* Set WPA/WPA key material
|
||||
*/
|
||||
|
||||
/* like "struct cmd_ds_802_11_key_material", but with cmd_header. Once we
|
||||
* get rid of WEXT, this should go into host.h */
|
||||
/*
|
||||
* like "struct cmd_ds_802_11_key_material", but with cmd_header. Once we
|
||||
* get rid of WEXT, this should go into host.h
|
||||
*/
|
||||
|
||||
struct cmd_key_material {
|
||||
struct cmd_header hdr;
|
||||
@ -1536,7 +1544,7 @@ static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
/*
|
||||
* Get station
|
||||
*/
|
||||
|
||||
@ -1581,7 +1589,7 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
/*
|
||||
* "Site survey", here just current channel and noise level
|
||||
*/
|
||||
|
||||
@ -1614,7 +1622,7 @@ static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
/*
|
||||
* Change interface
|
||||
*/
|
||||
|
||||
@ -1656,11 +1664,12 @@ static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
/*
|
||||
* IBSS (Ad-Hoc)
|
||||
*/
|
||||
|
||||
/* The firmware needs the following bits masked out of the beacon-derived
|
||||
/*
|
||||
* The firmware needs the following bits masked out of the beacon-derived
|
||||
* capability field when associating/joining to a BSS:
|
||||
* 9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused)
|
||||
*/
|
||||
@ -1999,7 +2008,7 @@ static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
/*
|
||||
* Initialization
|
||||
*/
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* This file contains the handling of command.
|
||||
* It prepares command and sends it to firmware when it is ready.
|
||||
*/
|
||||
/*
|
||||
* This file contains the handling of command.
|
||||
* It prepares command and sends it to firmware when it is ready.
|
||||
*/
|
||||
|
||||
#include <linux/kfifo.h>
|
||||
#include <linux/sched.h>
|
||||
@ -16,14 +16,14 @@
|
||||
#define CAL_RSSI(snr, nf) ((s32)((s32)(snr) + CAL_NF(nf)))
|
||||
|
||||
/**
|
||||
* @brief Simple callback that copies response back into command
|
||||
* lbs_cmd_copyback - Simple callback that copies response back into command
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param extra A pointer to the original command structure for which
|
||||
* 'resp' is a response
|
||||
* @param resp A pointer to the command response
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @extra: A pointer to the original command structure for which
|
||||
* 'resp' is a response
|
||||
* @resp: A pointer to the command response
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
* returns: 0 on success, error on failure
|
||||
*/
|
||||
int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
|
||||
struct cmd_header *resp)
|
||||
@ -38,15 +38,15 @@ int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
|
||||
EXPORT_SYMBOL_GPL(lbs_cmd_copyback);
|
||||
|
||||
/**
|
||||
* @brief Simple callback that ignores the result. Use this if
|
||||
* you just want to send a command to the hardware, but don't
|
||||
* lbs_cmd_async_callback - Simple callback that ignores the result.
|
||||
* Use this if you just want to send a command to the hardware, but don't
|
||||
* care for the result.
|
||||
*
|
||||
* @param priv ignored
|
||||
* @param extra ignored
|
||||
* @param resp ignored
|
||||
* @priv: ignored
|
||||
* @extra: ignored
|
||||
* @resp: ignored
|
||||
*
|
||||
* @return 0 for success
|
||||
* returns: 0 for success
|
||||
*/
|
||||
static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra,
|
||||
struct cmd_header *resp)
|
||||
@ -56,10 +56,11 @@ static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra,
|
||||
|
||||
|
||||
/**
|
||||
* @brief Checks whether a command is allowed in Power Save mode
|
||||
* is_command_allowed_in_ps - tests if a command is allowed in Power Save mode
|
||||
*
|
||||
* @param command the command ID
|
||||
* @return 1 if allowed, 0 if not allowed
|
||||
* @cmd: the command ID
|
||||
*
|
||||
* returns: 1 if allowed, 0 if not allowed
|
||||
*/
|
||||
static u8 is_command_allowed_in_ps(u16 cmd)
|
||||
{
|
||||
@ -75,11 +76,12 @@ static u8 is_command_allowed_in_ps(u16 cmd)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the hardware details like MAC address and regulatory region
|
||||
* lbs_update_hw_spec - Updates the hardware details like MAC address
|
||||
* and regulatory region
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
* returns: 0 on success, error on failure
|
||||
*/
|
||||
int lbs_update_hw_spec(struct lbs_private *priv)
|
||||
{
|
||||
@ -217,14 +219,14 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
|
||||
EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
|
||||
|
||||
/**
|
||||
* @brief Sets the Power Save mode
|
||||
* lbs_set_ps_mode - Sets the Power Save mode
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param cmd_action The Power Save operation (PS_MODE_ACTION_ENTER_PS or
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @cmd_action: The Power Save operation (PS_MODE_ACTION_ENTER_PS or
|
||||
* PS_MODE_ACTION_EXIT_PS)
|
||||
* @param block Whether to block on a response or not
|
||||
* @block: Whether to block on a response or not
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
* returns: 0 on success, error on failure
|
||||
*/
|
||||
int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block)
|
||||
{
|
||||
@ -417,13 +419,13 @@ int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set an SNMP MIB value
|
||||
* lbs_set_snmp_mib - Set an SNMP MIB value
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param oid The OID to set in the firmware
|
||||
* @param val Value to set the OID to
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @oid: The OID to set in the firmware
|
||||
* @val: Value to set the OID to
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
* returns: 0 on success, error on failure
|
||||
*/
|
||||
int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val)
|
||||
{
|
||||
@ -467,13 +469,13 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get an SNMP MIB value
|
||||
* lbs_get_snmp_mib - Get an SNMP MIB value
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param oid The OID to retrieve from the firmware
|
||||
* @param out_val Location for the returned value
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @oid: The OID to retrieve from the firmware
|
||||
* @out_val: Location for the returned value
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
* returns: 0 on success, error on failure
|
||||
*/
|
||||
int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val)
|
||||
{
|
||||
@ -510,14 +512,14 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the min, max, and current TX power
|
||||
* lbs_get_tx_power - Get the min, max, and current TX power
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param curlevel Current power level in dBm
|
||||
* @param minlevel Minimum supported power level in dBm (optional)
|
||||
* @param maxlevel Maximum supported power level in dBm (optional)
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @curlevel: Current power level in dBm
|
||||
* @minlevel: Minimum supported power level in dBm (optional)
|
||||
* @maxlevel: Maximum supported power level in dBm (optional)
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
* returns: 0 on success, error on failure
|
||||
*/
|
||||
int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
|
||||
s16 *maxlevel)
|
||||
@ -545,12 +547,12 @@ int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the TX power
|
||||
* lbs_set_tx_power - Set the TX power
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param dbm The desired power level in dBm
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @dbm: The desired power level in dBm
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
* returns: 0 on success, error on failure
|
||||
*/
|
||||
int lbs_set_tx_power(struct lbs_private *priv, s16 dbm)
|
||||
{
|
||||
@ -573,12 +575,13 @@ int lbs_set_tx_power(struct lbs_private *priv, s16 dbm)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable monitor mode (only implemented on OLPC usb8388 FW)
|
||||
* lbs_set_monitor_mode - Enable or disable monitor mode
|
||||
* (only implemented on OLPC usb8388 FW)
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param enable 1 to enable monitor mode, 0 to disable
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @enable: 1 to enable monitor mode, 0 to disable
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
* returns: 0 on success, error on failure
|
||||
*/
|
||||
int lbs_set_monitor_mode(struct lbs_private *priv, int enable)
|
||||
{
|
||||
@ -604,11 +607,11 @@ int lbs_set_monitor_mode(struct lbs_private *priv, int enable)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the radio channel
|
||||
* lbs_get_channel - Get the radio channel
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
*
|
||||
* @return The channel on success, error on failure
|
||||
* returns: The channel on success, error on failure
|
||||
*/
|
||||
static int lbs_get_channel(struct lbs_private *priv)
|
||||
{
|
||||
@ -650,12 +653,12 @@ int lbs_update_channel(struct lbs_private *priv)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the radio channel
|
||||
* lbs_set_channel - Set the radio channel
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param channel The desired channel, or 0 to clear a locked channel
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @channel: The desired channel, or 0 to clear a locked channel
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
* returns: 0 on success, error on failure
|
||||
*/
|
||||
int lbs_set_channel(struct lbs_private *priv, u8 channel)
|
||||
{
|
||||
@ -686,12 +689,13 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get current RSSI and noise floor
|
||||
* lbs_get_rssi - Get current RSSI and noise floor
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param rssi On successful return, signal level in mBm
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @rssi: On successful return, signal level in mBm
|
||||
* @nf: On successful return, Noise floor
|
||||
*
|
||||
* @return The channel on success, error on failure
|
||||
* returns: The channel on success, error on failure
|
||||
*/
|
||||
int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf)
|
||||
{
|
||||
@ -719,13 +723,14 @@ int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send regulatory and 802.11d domain information to the firmware
|
||||
* lbs_set_11d_domain_info - Send regulatory and 802.11d domain information
|
||||
* to the firmware
|
||||
*
|
||||
* @param priv pointer to struct lbs_private
|
||||
* @param request cfg80211 regulatory request structure
|
||||
* @param bands the device's supported bands and channels
|
||||
* @priv: pointer to &struct lbs_private
|
||||
* @request: cfg80211 regulatory request structure
|
||||
* @bands: the device's supported bands and channels
|
||||
*
|
||||
* @return 0 on success, error code on failure
|
||||
* returns: 0 on success, error code on failure
|
||||
*/
|
||||
int lbs_set_11d_domain_info(struct lbs_private *priv,
|
||||
struct regulatory_request *request,
|
||||
@ -842,15 +847,15 @@ int lbs_set_11d_domain_info(struct lbs_private *priv,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read a MAC, Baseband, or RF register
|
||||
* lbs_get_reg - Read a MAC, Baseband, or RF register
|
||||
*
|
||||
* @param priv pointer to struct lbs_private
|
||||
* @param cmd register command, one of CMD_MAC_REG_ACCESS,
|
||||
* CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
|
||||
* @param offset byte offset of the register to get
|
||||
* @param value on success, the value of the register at 'offset'
|
||||
* @priv: pointer to &struct lbs_private
|
||||
* @reg: register command, one of CMD_MAC_REG_ACCESS,
|
||||
* CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
|
||||
* @offset: byte offset of the register to get
|
||||
* @value: on success, the value of the register at 'offset'
|
||||
*
|
||||
* @return 0 on success, error code on failure
|
||||
* returns: 0 on success, error code on failure
|
||||
*/
|
||||
int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value)
|
||||
{
|
||||
@ -886,15 +891,15 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a MAC, Baseband, or RF register
|
||||
* lbs_set_reg - Write a MAC, Baseband, or RF register
|
||||
*
|
||||
* @param priv pointer to struct lbs_private
|
||||
* @param cmd register command, one of CMD_MAC_REG_ACCESS,
|
||||
* CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
|
||||
* @param offset byte offset of the register to set
|
||||
* @param value the value to write to the register at 'offset'
|
||||
* @priv: pointer to &struct lbs_private
|
||||
* @reg: register command, one of CMD_MAC_REG_ACCESS,
|
||||
* CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
|
||||
* @offset: byte offset of the register to set
|
||||
* @value: the value to write to the register at 'offset'
|
||||
*
|
||||
* @return 0 on success, error code on failure
|
||||
* returns: 0 on success, error code on failure
|
||||
*/
|
||||
int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value)
|
||||
{
|
||||
@ -1023,7 +1028,7 @@ static void lbs_submit_command(struct lbs_private *priv,
|
||||
lbs_deb_leave(LBS_DEB_HOST);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* This function inserts command node to cmdfreeq
|
||||
* after cleans it. Requires priv->driver_lock held.
|
||||
*/
|
||||
@ -1125,11 +1130,12 @@ void lbs_set_mac_control(struct lbs_private *priv)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function allocates the command buffer and link
|
||||
* it to command free queue.
|
||||
* lbs_allocate_cmd_buffer - allocates the command buffer and links
|
||||
* it to command free queue
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @return 0 or -1
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
*
|
||||
* returns: 0 for success or -1 on error
|
||||
*/
|
||||
int lbs_allocate_cmd_buffer(struct lbs_private *priv)
|
||||
{
|
||||
@ -1171,10 +1177,11 @@ done:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function frees the command buffer.
|
||||
* lbs_free_cmd_buffer - free the command buffer
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @return 0 or -1
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
*
|
||||
* returns: 0 for success
|
||||
*/
|
||||
int lbs_free_cmd_buffer(struct lbs_private *priv)
|
||||
{
|
||||
@ -1211,11 +1218,13 @@ done:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function gets a free command node if available in
|
||||
* command free queue.
|
||||
* lbs_get_free_cmd_node - gets a free command node if available in
|
||||
* command free queue
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
*
|
||||
* returns: A pointer to &cmd_ctrl_node structure on success
|
||||
* or %NULL on error
|
||||
*/
|
||||
static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv)
|
||||
{
|
||||
@ -1245,12 +1254,12 @@ static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function executes next command in command
|
||||
* pending queue. It will put firmware back to PS mode
|
||||
* if applicable.
|
||||
* lbs_execute_next_command - execute next command in command
|
||||
* pending queue. Will put firmware back to PS mode if applicable.
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @return 0 or -1
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
*
|
||||
* returns: 0 on success or -1 on error
|
||||
*/
|
||||
int lbs_execute_next_command(struct lbs_private *priv)
|
||||
{
|
||||
@ -1454,12 +1463,12 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function checks condition and prepares to
|
||||
* send sleep confirm command to firmware if ok.
|
||||
* lbs_ps_confirm_sleep - checks condition and prepares to
|
||||
* send sleep confirm command to firmware if ok
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param psmode Power Saving mode
|
||||
* @return n/a
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
*
|
||||
* returns: n/a
|
||||
*/
|
||||
void lbs_ps_confirm_sleep(struct lbs_private *priv)
|
||||
{
|
||||
@ -1499,16 +1508,16 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv)
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configures the transmission power control functionality.
|
||||
* lbs_set_tpc_cfg - Configures the transmission power control functionality
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param enable Transmission power control enable
|
||||
* @param p0 Power level when link quality is good (dBm).
|
||||
* @param p1 Power level when link quality is fair (dBm).
|
||||
* @param p2 Power level when link quality is poor (dBm).
|
||||
* @param usesnr Use Signal to Noise Ratio in TPC
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @enable: Transmission power control enable
|
||||
* @p0: Power level when link quality is good (dBm).
|
||||
* @p1: Power level when link quality is fair (dBm).
|
||||
* @p2: Power level when link quality is poor (dBm).
|
||||
* @usesnr: Use Signal to Noise Ratio in TPC
|
||||
*
|
||||
* @return 0 on success
|
||||
* returns: 0 on success
|
||||
*/
|
||||
int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
|
||||
int8_t p2, int usesnr)
|
||||
@ -1531,15 +1540,15 @@ int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the power adaptation settings.
|
||||
* lbs_set_power_adapt_cfg - Configures the power adaptation settings
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param enable Power adaptation enable
|
||||
* @param p0 Power level for 1, 2, 5.5 and 11 Mbps (dBm).
|
||||
* @param p1 Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm).
|
||||
* @param p2 Power level for 48 and 54 Mbps (dBm).
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @enable: Power adaptation enable
|
||||
* @p0: Power level for 1, 2, 5.5 and 11 Mbps (dBm).
|
||||
* @p1: Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm).
|
||||
* @p2: Power level for 48 and 54 Mbps (dBm).
|
||||
*
|
||||
* @return 0 on Success
|
||||
* returns: 0 on Success
|
||||
*/
|
||||
|
||||
int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* This file contains the handling of command
|
||||
* responses as well as events generated by firmware.
|
||||
*/
|
||||
/*
|
||||
* This file contains the handling of command
|
||||
* responses as well as events generated by firmware.
|
||||
*/
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/sched.h>
|
||||
@ -12,12 +12,13 @@
|
||||
#include "cmd.h"
|
||||
|
||||
/**
|
||||
* @brief This function handles disconnect event. it
|
||||
* reports disconnect to upper layer, clean tx/rx packets,
|
||||
* reset link state etc.
|
||||
* lbs_mac_event_disconnected - handles disconnect event. It
|
||||
* reports disconnect to upper layer, clean tx/rx packets,
|
||||
* reset link state etc.
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @return n/a
|
||||
* @priv: A pointer to struct lbs_private structure
|
||||
*
|
||||
* returns: n/a
|
||||
*/
|
||||
void lbs_mac_event_disconnected(struct lbs_private *priv)
|
||||
{
|
||||
|
@ -849,15 +849,14 @@ static struct debug_data items[] = {
|
||||
static int num_of_items = ARRAY_SIZE(items);
|
||||
|
||||
/**
|
||||
* @brief proc read function
|
||||
* lbs_debugfs_read - proc read function
|
||||
*
|
||||
* @param page pointer to buffer
|
||||
* @param s read data starting position
|
||||
* @param off offset
|
||||
* @param cnt counter
|
||||
* @param eof end of file flag
|
||||
* @param data data to output
|
||||
* @return number of output data
|
||||
* @file: file to read
|
||||
* @userbuf: pointer to buffer
|
||||
* @count: number of bytes to read
|
||||
* @ppos: read data starting position
|
||||
*
|
||||
* returns: amount of data read or negative error code
|
||||
*/
|
||||
static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
@ -897,13 +896,14 @@ static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief proc write function
|
||||
* lbs_debugfs_write - proc write function
|
||||
*
|
||||
* @param f file pointer
|
||||
* @param buf pointer to data buffer
|
||||
* @param cnt data number to write
|
||||
* @param data data to write
|
||||
* @return number of data
|
||||
* @f: file pointer
|
||||
* @buf: pointer to data buffer
|
||||
* @cnt: data number to write
|
||||
* @ppos: file position
|
||||
*
|
||||
* returns: amount of data written
|
||||
*/
|
||||
static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf,
|
||||
size_t cnt, loff_t *ppos)
|
||||
@ -966,11 +966,11 @@ static const struct file_operations lbs_debug_fops = {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief create debug proc file
|
||||
* lbs_debug_init - create debug proc file
|
||||
*
|
||||
* @param priv pointer struct lbs_private
|
||||
* @param dev pointer net_device
|
||||
* @return N/A
|
||||
* @priv: pointer to &struct lbs_private
|
||||
*
|
||||
* returns: N/A
|
||||
*/
|
||||
static void lbs_debug_init(struct lbs_private *priv)
|
||||
{
|
||||
|
@ -1,8 +1,8 @@
|
||||
|
||||
/**
|
||||
* This file contains declaration referring to
|
||||
* functions defined in other source files
|
||||
*/
|
||||
/*
|
||||
* This file contains declaration referring to
|
||||
* functions defined in other source files
|
||||
*/
|
||||
|
||||
#ifndef _LBS_DECL_H_
|
||||
#define _LBS_DECL_H_
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* This header file contains global constant/enum definitions,
|
||||
* global variable declaration.
|
||||
*/
|
||||
/*
|
||||
* This header file contains global constant/enum definitions,
|
||||
* global variable declaration.
|
||||
*/
|
||||
#ifndef _LBS_DEFS_H_
|
||||
#define _LBS_DEFS_H_
|
||||
|
||||
@ -123,19 +123,19 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
|
||||
|
||||
|
||||
|
||||
/** Buffer Constants */
|
||||
/* Buffer Constants */
|
||||
|
||||
/* The size of SQ memory PPA, DPA are 8 DWORDs, that keep the physical
|
||||
* addresses of TxPD buffers. Station has only 8 TxPD available, Whereas
|
||||
* driver has more local TxPDs. Each TxPD on the host memory is associated
|
||||
* with a Tx control node. The driver maintains 8 RxPD descriptors for
|
||||
* station firmware to store Rx packet information.
|
||||
*
|
||||
* Current version of MAC has a 32x6 multicast address buffer.
|
||||
*
|
||||
* 802.11b can have up to 14 channels, the driver keeps the
|
||||
* BSSID(MAC address) of each APs or Ad hoc stations it has sensed.
|
||||
*/
|
||||
* addresses of TxPD buffers. Station has only 8 TxPD available, Whereas
|
||||
* driver has more local TxPDs. Each TxPD on the host memory is associated
|
||||
* with a Tx control node. The driver maintains 8 RxPD descriptors for
|
||||
* station firmware to store Rx packet information.
|
||||
*
|
||||
* Current version of MAC has a 32x6 multicast address buffer.
|
||||
*
|
||||
* 802.11b can have up to 14 channels, the driver keeps the
|
||||
* BSSID(MAC address) of each APs or Ad hoc stations it has sensed.
|
||||
*/
|
||||
|
||||
#define MRVDRV_MAX_MULTICAST_LIST_SIZE 32
|
||||
#define LBS_NUM_CMD_BUFFERS 10
|
||||
@ -166,7 +166,7 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
|
||||
#define WOL_RESULT_NOSPC_ERR 1
|
||||
#define WOL_RESULT_EEXIST_ERR 2
|
||||
|
||||
/** Misc constants */
|
||||
/* Misc constants */
|
||||
/* This section defines 802.11 specific contants */
|
||||
|
||||
#define MRVDRV_MAX_BSS_DESCRIPTS 16
|
||||
@ -183,7 +183,8 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
|
||||
|
||||
#define MARVELL_MESH_IE_LENGTH 9
|
||||
|
||||
/* Values used to populate the struct mrvl_mesh_ie. The only time you need this
|
||||
/*
|
||||
* Values used to populate the struct mrvl_mesh_ie. The only time you need this
|
||||
* is when enabling the mesh using CMD_MESH_CONFIG.
|
||||
*/
|
||||
#define MARVELL_MESH_IE_TYPE 4
|
||||
@ -193,7 +194,7 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
|
||||
#define MARVELL_MESH_METRIC_ID 0
|
||||
#define MARVELL_MESH_CAPABILITY 0
|
||||
|
||||
/** INT status Bit Definition*/
|
||||
/* INT status Bit Definition */
|
||||
#define MRVDRV_TX_DNLD_RDY 0x0001
|
||||
#define MRVDRV_RX_UPLD_RDY 0x0002
|
||||
#define MRVDRV_CMD_DNLD_RDY 0x0004
|
||||
@ -208,59 +209,63 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
|
||||
#define TPC_DEFAULT_P1 10
|
||||
#define TPC_DEFAULT_P2 13
|
||||
|
||||
/** TxPD status */
|
||||
/* TxPD status */
|
||||
|
||||
/* Station firmware use TxPD status field to report final Tx transmit
|
||||
* result, Bit masks are used to present combined situations.
|
||||
*/
|
||||
/*
|
||||
* Station firmware use TxPD status field to report final Tx transmit
|
||||
* result, Bit masks are used to present combined situations.
|
||||
*/
|
||||
|
||||
#define MRVDRV_TxPD_POWER_MGMT_NULL_PACKET 0x01
|
||||
#define MRVDRV_TxPD_POWER_MGMT_LAST_PACKET 0x08
|
||||
|
||||
/** Tx mesh flag */
|
||||
/* Currently we are using normal WDS flag as mesh flag.
|
||||
/* Tx mesh flag */
|
||||
/*
|
||||
* Currently we are using normal WDS flag as mesh flag.
|
||||
* TODO: change to proper mesh flag when MAC understands it.
|
||||
*/
|
||||
#define TxPD_CONTROL_WDS_FRAME (1<<17)
|
||||
#define TxPD_MESH_FRAME TxPD_CONTROL_WDS_FRAME
|
||||
|
||||
/** Mesh interface ID */
|
||||
/* Mesh interface ID */
|
||||
#define MESH_IFACE_ID 0x0001
|
||||
/** Mesh id should be in bits 14-13-12 */
|
||||
/* Mesh id should be in bits 14-13-12 */
|
||||
#define MESH_IFACE_BIT_OFFSET 0x000c
|
||||
/** Mesh enable bit in FW capability */
|
||||
/* Mesh enable bit in FW capability */
|
||||
#define MESH_CAPINFO_ENABLE_MASK (1<<16)
|
||||
|
||||
/** FW definition from Marvell v4 */
|
||||
/* FW definition from Marvell v4 */
|
||||
#define MRVL_FW_V4 (0x04)
|
||||
/** FW definition from Marvell v5 */
|
||||
/* FW definition from Marvell v5 */
|
||||
#define MRVL_FW_V5 (0x05)
|
||||
/** FW definition from Marvell v10 */
|
||||
/* FW definition from Marvell v10 */
|
||||
#define MRVL_FW_V10 (0x0a)
|
||||
/** FW major revision definition */
|
||||
/* FW major revision definition */
|
||||
#define MRVL_FW_MAJOR_REV(x) ((x)>>24)
|
||||
|
||||
/** RxPD status */
|
||||
/* RxPD status */
|
||||
|
||||
#define MRVDRV_RXPD_STATUS_OK 0x0001
|
||||
|
||||
/** RxPD status - Received packet types */
|
||||
/** Rx mesh flag */
|
||||
/* Currently we are using normal WDS flag as mesh flag.
|
||||
/* RxPD status - Received packet types */
|
||||
/* Rx mesh flag */
|
||||
/*
|
||||
* Currently we are using normal WDS flag as mesh flag.
|
||||
* TODO: change to proper mesh flag when MAC understands it.
|
||||
*/
|
||||
#define RxPD_CONTROL_WDS_FRAME (0x40)
|
||||
#define RxPD_MESH_FRAME RxPD_CONTROL_WDS_FRAME
|
||||
|
||||
/** RSSI-related defines */
|
||||
/* RSSI constants are used to implement 802.11 RSSI threshold
|
||||
* indication. if the Rx packet signal got too weak for 5 consecutive
|
||||
* times, miniport driver (driver) will report this event to wrapper
|
||||
*/
|
||||
/* RSSI-related defines */
|
||||
/*
|
||||
* RSSI constants are used to implement 802.11 RSSI threshold
|
||||
* indication. if the Rx packet signal got too weak for 5 consecutive
|
||||
* times, miniport driver (driver) will report this event to wrapper
|
||||
*/
|
||||
|
||||
#define MRVDRV_NF_DEFAULT_SCAN_VALUE (-96)
|
||||
|
||||
/** RTS/FRAG related defines */
|
||||
/* RTS/FRAG related defines */
|
||||
#define MRVDRV_RTS_MIN_VALUE 0
|
||||
#define MRVDRV_RTS_MAX_VALUE 2347
|
||||
#define MRVDRV_FRAG_MIN_VALUE 256
|
||||
@ -300,36 +305,36 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
|
||||
|
||||
#define MAX_LEDS 8
|
||||
|
||||
/** Global Variable Declaration */
|
||||
/* Global Variable Declaration */
|
||||
extern const char lbs_driver_version[];
|
||||
extern u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE];
|
||||
|
||||
|
||||
/** ENUM definition*/
|
||||
/** SNRNF_TYPE */
|
||||
/* ENUM definition */
|
||||
/* SNRNF_TYPE */
|
||||
enum SNRNF_TYPE {
|
||||
TYPE_BEACON = 0,
|
||||
TYPE_RXPD,
|
||||
MAX_TYPE_B
|
||||
};
|
||||
|
||||
/** SNRNF_DATA*/
|
||||
/* SNRNF_DATA */
|
||||
enum SNRNF_DATA {
|
||||
TYPE_NOAVG = 0,
|
||||
TYPE_AVG,
|
||||
MAX_TYPE_AVG
|
||||
};
|
||||
|
||||
/** LBS_802_11_POWER_MODE */
|
||||
/* LBS_802_11_POWER_MODE */
|
||||
enum LBS_802_11_POWER_MODE {
|
||||
LBS802_11POWERMODECAM,
|
||||
LBS802_11POWERMODEMAX_PSP,
|
||||
LBS802_11POWERMODEFAST_PSP,
|
||||
/*not a real mode, defined as an upper bound */
|
||||
/* not a real mode, defined as an upper bound */
|
||||
LBS802_11POWEMODEMAX
|
||||
};
|
||||
|
||||
/** PS_STATE */
|
||||
/* PS_STATE */
|
||||
enum PS_STATE {
|
||||
PS_STATE_FULL_POWER,
|
||||
PS_STATE_AWAKE,
|
||||
@ -337,7 +342,7 @@ enum PS_STATE {
|
||||
PS_STATE_SLEEP
|
||||
};
|
||||
|
||||
/** DNLD_STATE */
|
||||
/* DNLD_STATE */
|
||||
enum DNLD_STATE {
|
||||
DNLD_RES_RECEIVED,
|
||||
DNLD_DATA_SENT,
|
||||
@ -345,19 +350,19 @@ enum DNLD_STATE {
|
||||
DNLD_BOOTCMD_SENT,
|
||||
};
|
||||
|
||||
/** LBS_MEDIA_STATE */
|
||||
/* LBS_MEDIA_STATE */
|
||||
enum LBS_MEDIA_STATE {
|
||||
LBS_CONNECTED,
|
||||
LBS_DISCONNECTED
|
||||
};
|
||||
|
||||
/** LBS_802_11_PRIVACY_FILTER */
|
||||
/* LBS_802_11_PRIVACY_FILTER */
|
||||
enum LBS_802_11_PRIVACY_FILTER {
|
||||
LBS802_11PRIVFILTERACCEPTALL,
|
||||
LBS802_11PRIVFILTER8021XWEP
|
||||
};
|
||||
|
||||
/** mv_ms_type */
|
||||
/* mv_ms_type */
|
||||
enum mv_ms_type {
|
||||
MVMS_DAT = 0,
|
||||
MVMS_CMD = 1,
|
||||
@ -365,14 +370,14 @@ enum mv_ms_type {
|
||||
MVMS_EVENT
|
||||
};
|
||||
|
||||
/** KEY_TYPE_ID */
|
||||
/* KEY_TYPE_ID */
|
||||
enum KEY_TYPE_ID {
|
||||
KEY_TYPE_ID_WEP = 0,
|
||||
KEY_TYPE_ID_TKIP,
|
||||
KEY_TYPE_ID_AES
|
||||
};
|
||||
|
||||
/** KEY_INFO_WPA (applies to both TKIP and AES/CCMP) */
|
||||
/* KEY_INFO_WPA (applies to both TKIP and AES/CCMP) */
|
||||
enum KEY_INFO_WPA {
|
||||
KEY_INFO_WPA_MCAST = 0x01,
|
||||
KEY_INFO_WPA_UNICAST = 0x02,
|
||||
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* This file contains definitions and data structures specific
|
||||
* to Marvell 802.11 NIC. It contains the Device Information
|
||||
* structure struct lbs_private..
|
||||
*/
|
||||
/*
|
||||
* This file contains definitions and data structures specific
|
||||
* to Marvell 802.11 NIC. It contains the Device Information
|
||||
* structure struct lbs_private..
|
||||
*/
|
||||
#ifndef _LBS_DEV_H_
|
||||
#define _LBS_DEV_H_
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
#include <linux/kfifo.h>
|
||||
|
||||
/** sleep_params */
|
||||
/* sleep_params */
|
||||
struct sleep_params {
|
||||
uint16_t sp_error;
|
||||
uint16_t sp_offset;
|
||||
@ -23,7 +23,7 @@ struct sleep_params {
|
||||
};
|
||||
|
||||
|
||||
/** Private structure for the MV device */
|
||||
/* Private structure for the MV device */
|
||||
struct lbs_private {
|
||||
|
||||
/* Basic networking */
|
||||
@ -125,12 +125,12 @@ struct lbs_private {
|
||||
/* Events sent from hardware to driver */
|
||||
struct kfifo event_fifo;
|
||||
|
||||
/** thread to service interrupts */
|
||||
/* thread to service interrupts */
|
||||
struct task_struct *main_thread;
|
||||
wait_queue_head_t waitq;
|
||||
struct workqueue_struct *work_thread;
|
||||
|
||||
/** Encryption stuff */
|
||||
/* Encryption stuff */
|
||||
u8 authtype_auto;
|
||||
u8 wep_tx_key;
|
||||
u8 wep_key[4][WLAN_KEY_LEN_WEP104];
|
||||
@ -162,7 +162,7 @@ struct lbs_private {
|
||||
s16 txpower_min;
|
||||
s16 txpower_max;
|
||||
|
||||
/** Scanning */
|
||||
/* Scanning */
|
||||
struct delayed_work scan_work;
|
||||
int scan_channel;
|
||||
/* Queue of things waiting for scan completion */
|
||||
|
@ -20,7 +20,8 @@ static void lbs_ethtool_get_drvinfo(struct net_device *dev,
|
||||
strcpy(info->version, lbs_driver_version);
|
||||
}
|
||||
|
||||
/* All 8388 parts have 16KiB EEPROM size at the time of writing.
|
||||
/*
|
||||
* All 8388 parts have 16KiB EEPROM size at the time of writing.
|
||||
* In case that changes this needs fixing.
|
||||
*/
|
||||
#define LBS_EEPROM_LEN 16384
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* This file function prototypes, data structure
|
||||
* and definitions for all the host/station commands
|
||||
*/
|
||||
/*
|
||||
* This file function prototypes, data structure
|
||||
* and definitions for all the host/station commands
|
||||
*/
|
||||
|
||||
#ifndef _LBS_HOST_H_
|
||||
#define _LBS_HOST_H_
|
||||
@ -13,9 +13,10 @@
|
||||
|
||||
#define CMD_OPTION_WAITFORRSP 0x0002
|
||||
|
||||
/** Host command IDs */
|
||||
/* Host command IDs */
|
||||
|
||||
/* Return command are almost always the same as the host command, but with
|
||||
/*
|
||||
* Return command are almost always the same as the host command, but with
|
||||
* bit 15 set high. There are a few exceptions, though...
|
||||
*/
|
||||
#define CMD_RET(cmd) (0x8000 | cmd)
|
||||
@ -251,7 +252,7 @@ enum cmd_mesh_config_types {
|
||||
CMD_TYPE_MESH_GET_MESH_IE, /* GET_DEFAULTS is superset of GET_MESHIE */
|
||||
};
|
||||
|
||||
/** Card Event definition */
|
||||
/* Card Event definition */
|
||||
#define MACREG_INT_CODE_TX_PPA_FREE 0
|
||||
#define MACREG_INT_CODE_TX_DMA_DONE 1
|
||||
#define MACREG_INT_CODE_LINK_LOST_W_SCAN 2
|
||||
@ -624,12 +625,14 @@ struct cmd_ds_802_11_rf_channel {
|
||||
struct cmd_ds_802_11_rssi {
|
||||
struct cmd_header hdr;
|
||||
|
||||
/* request: number of beacons (N) to average the SNR and NF over
|
||||
/*
|
||||
* request: number of beacons (N) to average the SNR and NF over
|
||||
* response: SNR of most recent beacon
|
||||
*/
|
||||
__le16 n_or_snr;
|
||||
|
||||
/* The following fields are only set in the response.
|
||||
/*
|
||||
* The following fields are only set in the response.
|
||||
* In the request these are reserved and should be set to 0.
|
||||
*/
|
||||
__le16 nf; /* most recent beacon noise floor */
|
||||
@ -680,14 +683,16 @@ struct cmd_ds_802_11_ps_mode {
|
||||
|
||||
__le16 action;
|
||||
|
||||
/* Interval for keepalive in PS mode:
|
||||
/*
|
||||
* Interval for keepalive in PS mode:
|
||||
* 0x0000 = don't change
|
||||
* 0x001E = firmware default
|
||||
* 0xFFFF = disable
|
||||
*/
|
||||
__le16 nullpktinterval;
|
||||
|
||||
/* Number of DTIM intervals to wake up for:
|
||||
/*
|
||||
* Number of DTIM intervals to wake up for:
|
||||
* 0 = don't change
|
||||
* 1 = firmware default
|
||||
* 5 = max
|
||||
@ -697,7 +702,8 @@ struct cmd_ds_802_11_ps_mode {
|
||||
__le16 reserved;
|
||||
__le16 locallisteninterval;
|
||||
|
||||
/* AdHoc awake period (FW v9+ only):
|
||||
/*
|
||||
* AdHoc awake period (FW v9+ only):
|
||||
* 0 = don't change
|
||||
* 1 = always awake (IEEE standard behavior)
|
||||
* 2 - 31 = sleep for (n - 1) periods and awake for 1 period
|
||||
@ -771,7 +777,8 @@ struct adhoc_bssdesc {
|
||||
__le16 capability;
|
||||
u8 rates[MAX_RATES];
|
||||
|
||||
/* DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the
|
||||
/*
|
||||
* DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the
|
||||
* Adhoc join command and will cause a binary layout mismatch with
|
||||
* the firmware
|
||||
*/
|
||||
|
@ -312,7 +312,8 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
|
||||
#define CF8385_MANFID 0x02df
|
||||
#define CF8385_CARDID 0x8103
|
||||
|
||||
/* FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when
|
||||
/*
|
||||
* FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when
|
||||
* that gets fixed. Currently there's no way to access it from the probe hook.
|
||||
*/
|
||||
static inline u32 get_model(u16 manf_id, u16 card_id)
|
||||
@ -621,8 +622,10 @@ static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw)
|
||||
if (remain < count)
|
||||
count = remain;
|
||||
|
||||
/* "write the number of bytes to be sent to the I/O Command
|
||||
* write length register" */
|
||||
/*
|
||||
* "write the number of bytes to be sent to the I/O Command
|
||||
* write length register"
|
||||
*/
|
||||
if_cs_write16(card, IF_CS_CMD_LEN, count);
|
||||
|
||||
/* "write this to I/O Command port register as 16 bit writes */
|
||||
@ -631,16 +634,22 @@ static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw)
|
||||
&fw->data[sent],
|
||||
count >> 1);
|
||||
|
||||
/* "Assert the download over interrupt command in the Host
|
||||
* status register" */
|
||||
/*
|
||||
* "Assert the download over interrupt command in the Host
|
||||
* status register"
|
||||
*/
|
||||
if_cs_write8(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND);
|
||||
|
||||
/* "Assert the download over interrupt command in the Card
|
||||
* interrupt case register" */
|
||||
/*
|
||||
* "Assert the download over interrupt command in the Card
|
||||
* interrupt case register"
|
||||
*/
|
||||
if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_COMMAND);
|
||||
|
||||
/* "The host polls the Card Status register ... for 50 ms before
|
||||
declaring a failure */
|
||||
/*
|
||||
* "The host polls the Card Status register ... for 50 ms before
|
||||
* declaring a failure"
|
||||
*/
|
||||
ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS,
|
||||
IF_CS_BIT_COMMAND);
|
||||
if (ret < 0) {
|
||||
@ -841,7 +850,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
|
||||
|
||||
/*
|
||||
* Most of the libertas cards can do unaligned register access, but some
|
||||
* weird ones can not. That's especially true for the CF8305 card.
|
||||
* weird ones cannot. That's especially true for the CF8305 card.
|
||||
*/
|
||||
card->align_regs = 0;
|
||||
|
||||
@ -913,8 +922,10 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
|
||||
goto out3;
|
||||
}
|
||||
|
||||
/* Clear any interrupt cause that happened while sending
|
||||
* firmware/initializing card */
|
||||
/*
|
||||
* Clear any interrupt cause that happened while sending
|
||||
* firmware/initializing card
|
||||
*/
|
||||
if_cs_write16(card, IF_CS_CARD_INT_CAUSE, IF_CS_BIT_MASK);
|
||||
if_cs_enable_ints(card);
|
||||
|
||||
|
@ -143,8 +143,10 @@ static void spu_transaction_finish(struct if_spi_card *card)
|
||||
card->prev_xfer_time = jiffies;
|
||||
}
|
||||
|
||||
/* Write out a byte buffer to an SPI register,
|
||||
* using a series of 16-bit transfers. */
|
||||
/*
|
||||
* Write out a byte buffer to an SPI register,
|
||||
* using a series of 16-bit transfers.
|
||||
*/
|
||||
static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
|
||||
{
|
||||
int err = 0;
|
||||
@ -208,8 +210,10 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
|
||||
struct spi_transfer dummy_trans;
|
||||
struct spi_transfer data_trans;
|
||||
|
||||
/* You must take an even number of bytes from the SPU, even if you
|
||||
* don't care about the last one. */
|
||||
/*
|
||||
* You must take an even number of bytes from the SPU, even if you
|
||||
* don't care about the last one.
|
||||
*/
|
||||
BUG_ON(len & 0x1);
|
||||
|
||||
spu_transaction_init(card);
|
||||
@ -258,8 +262,10 @@ static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Read 32 bits from an SPI register.
|
||||
* The low 16 bits are read first. */
|
||||
/*
|
||||
* Read 32 bits from an SPI register.
|
||||
* The low 16 bits are read first.
|
||||
*/
|
||||
static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val)
|
||||
{
|
||||
__le32 buf;
|
||||
@ -271,13 +277,15 @@ static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Keep reading 16 bits from an SPI register until you get the correct result.
|
||||
/*
|
||||
* Keep reading 16 bits from an SPI register until you get the correct result.
|
||||
*
|
||||
* If mask = 0, the correct result is any non-zero number.
|
||||
* If mask != 0, the correct result is any number where
|
||||
* number & target_mask == target
|
||||
*
|
||||
* Returns -ETIMEDOUT if a second passes without the correct result. */
|
||||
* Returns -ETIMEDOUT if a second passes without the correct result.
|
||||
*/
|
||||
static int spu_wait_for_u16(struct if_spi_card *card, u16 reg,
|
||||
u16 target_mask, u16 target)
|
||||
{
|
||||
@ -305,8 +313,10 @@ static int spu_wait_for_u16(struct if_spi_card *card, u16 reg,
|
||||
}
|
||||
}
|
||||
|
||||
/* Read 16 bits from an SPI register until you receive a specific value.
|
||||
* Returns -ETIMEDOUT if a 4 tries pass without success. */
|
||||
/*
|
||||
* Read 16 bits from an SPI register until you receive a specific value.
|
||||
* Returns -ETIMEDOUT if a 4 tries pass without success.
|
||||
*/
|
||||
static int spu_wait_for_u32(struct if_spi_card *card, u32 reg, u32 target)
|
||||
{
|
||||
int err, try;
|
||||
@ -328,8 +338,10 @@ static int spu_set_interrupt_mode(struct if_spi_card *card,
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
/* We can suppress a host interrupt by clearing the appropriate
|
||||
* bit in the "host interrupt status mask" register */
|
||||
/*
|
||||
* We can suppress a host interrupt by clearing the appropriate
|
||||
* bit in the "host interrupt status mask" register
|
||||
*/
|
||||
if (suppress_host_int) {
|
||||
err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0);
|
||||
if (err)
|
||||
@ -345,10 +357,12 @@ static int spu_set_interrupt_mode(struct if_spi_card *card,
|
||||
return err;
|
||||
}
|
||||
|
||||
/* If auto-interrupts are on, the completion of certain transactions
|
||||
/*
|
||||
* If auto-interrupts are on, the completion of certain transactions
|
||||
* will trigger an interrupt automatically. If auto-interrupts
|
||||
* are off, we need to set the "Card Interrupt Cause" register to
|
||||
* trigger a card interrupt. */
|
||||
* trigger a card interrupt.
|
||||
*/
|
||||
if (auto_int) {
|
||||
err = spu_write_u16(card, IF_SPI_HOST_INT_CTRL_REG,
|
||||
IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO |
|
||||
@ -402,8 +416,10 @@ static int spu_init(struct if_spi_card *card, int use_dummy_writes)
|
||||
int err = 0;
|
||||
u32 delay;
|
||||
|
||||
/* We have to start up in timed delay mode so that we can safely
|
||||
* read the Delay Read Register. */
|
||||
/*
|
||||
* We have to start up in timed delay mode so that we can safely
|
||||
* read the Delay Read Register.
|
||||
*/
|
||||
card->use_dummy_writes = 0;
|
||||
err = spu_set_bus_mode(card,
|
||||
IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING |
|
||||
@ -459,8 +475,10 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card,
|
||||
|
||||
/* Load helper firmware image */
|
||||
while (bytes_remaining > 0) {
|
||||
/* Scratch pad 1 should contain the number of bytes we
|
||||
* want to download to the firmware */
|
||||
/*
|
||||
* Scratch pad 1 should contain the number of bytes we
|
||||
* want to download to the firmware
|
||||
*/
|
||||
err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG,
|
||||
HELPER_FW_LOAD_CHUNK_SZ);
|
||||
if (err)
|
||||
@ -472,8 +490,10 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card,
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
/* Feed the data into the command read/write port reg
|
||||
* in chunks of 64 bytes */
|
||||
/*
|
||||
* Feed the data into the command read/write port reg
|
||||
* in chunks of 64 bytes
|
||||
*/
|
||||
memset(temp, 0, sizeof(temp));
|
||||
memcpy(temp, fw,
|
||||
min(bytes_remaining, HELPER_FW_LOAD_CHUNK_SZ));
|
||||
@ -495,9 +515,11 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card,
|
||||
fw += HELPER_FW_LOAD_CHUNK_SZ;
|
||||
}
|
||||
|
||||
/* Once the helper / single stage firmware download is complete,
|
||||
/*
|
||||
* Once the helper / single stage firmware download is complete,
|
||||
* write 0 to scratch pad 1 and interrupt the
|
||||
* bootloader. This completes the helper download. */
|
||||
* bootloader. This completes the helper download.
|
||||
*/
|
||||
err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK);
|
||||
if (err)
|
||||
goto out;
|
||||
@ -517,16 +539,20 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Returns the length of the next packet the firmware expects us to send
|
||||
* Sets crc_err if the previous transfer had a CRC error. */
|
||||
/*
|
||||
* Returns the length of the next packet the firmware expects us to send.
|
||||
* Sets crc_err if the previous transfer had a CRC error.
|
||||
*/
|
||||
static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
|
||||
int *crc_err)
|
||||
{
|
||||
u16 len;
|
||||
int err = 0;
|
||||
|
||||
/* wait until the host interrupt status register indicates
|
||||
* that we are ready to download */
|
||||
/*
|
||||
* wait until the host interrupt status register indicates
|
||||
* that we are ready to download
|
||||
*/
|
||||
err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG,
|
||||
IF_SPI_HIST_CMD_DOWNLOAD_RDY,
|
||||
IF_SPI_HIST_CMD_DOWNLOAD_RDY);
|
||||
@ -587,8 +613,10 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card,
|
||||
goto out;
|
||||
}
|
||||
if (bytes < 0) {
|
||||
/* If there are no more bytes left, we would normally
|
||||
* expect to have terminated with len = 0 */
|
||||
/*
|
||||
* If there are no more bytes left, we would normally
|
||||
* expect to have terminated with len = 0
|
||||
*/
|
||||
lbs_pr_err("Firmware load wants more bytes "
|
||||
"than we have to offer.\n");
|
||||
break;
|
||||
@ -660,14 +688,18 @@ static int if_spi_c2h_cmd(struct if_spi_card *card)
|
||||
u16 len;
|
||||
u8 i;
|
||||
|
||||
/* We need a buffer big enough to handle whatever people send to
|
||||
* hw_host_to_card */
|
||||
/*
|
||||
* We need a buffer big enough to handle whatever people send to
|
||||
* hw_host_to_card
|
||||
*/
|
||||
BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_CMD_BUFFER_SIZE);
|
||||
BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_UPLD_SIZE);
|
||||
|
||||
/* It's just annoying if the buffer size isn't a multiple of 4, because
|
||||
* then we might have len < IF_SPI_CMD_BUF_SIZE but
|
||||
* ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE */
|
||||
/*
|
||||
* It's just annoying if the buffer size isn't a multiple of 4, because
|
||||
* then we might have len < IF_SPI_CMD_BUF_SIZE but
|
||||
* ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE
|
||||
*/
|
||||
BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE % 4 != 0);
|
||||
|
||||
lbs_deb_enter(LBS_DEB_SPI);
|
||||
@ -838,8 +870,10 @@ static void if_spi_host_to_card_worker(struct work_struct *work)
|
||||
|
||||
lbs_deb_enter(LBS_DEB_SPI);
|
||||
|
||||
/* Read the host interrupt status register to see what we
|
||||
* can do. */
|
||||
/*
|
||||
* Read the host interrupt status register to see what we
|
||||
* can do.
|
||||
*/
|
||||
err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG,
|
||||
&hiStatus);
|
||||
if (err) {
|
||||
@ -858,12 +892,15 @@ static void if_spi_host_to_card_worker(struct work_struct *work)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* workaround: in PS mode, the card does not set the Command
|
||||
* Download Ready bit, but it sets TX Download Ready. */
|
||||
/*
|
||||
* workaround: in PS mode, the card does not set the Command
|
||||
* Download Ready bit, but it sets TX Download Ready.
|
||||
*/
|
||||
if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY ||
|
||||
(card->priv->psstate != PS_STATE_FULL_POWER &&
|
||||
(hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) {
|
||||
/* This means two things. First of all,
|
||||
/*
|
||||
* This means two things. First of all,
|
||||
* if there was a previous command sent, the card has
|
||||
* successfully received it.
|
||||
* Secondly, it is now ready to download another
|
||||
@ -871,8 +908,7 @@ static void if_spi_host_to_card_worker(struct work_struct *work)
|
||||
*/
|
||||
lbs_host_to_card_done(card->priv);
|
||||
|
||||
/* Do we have any command packets from the host to
|
||||
* send? */
|
||||
/* Do we have any command packets from the host to send? */
|
||||
packet = NULL;
|
||||
spin_lock_irqsave(&card->buffer_lock, flags);
|
||||
if (!list_empty(&card->cmd_packet_list)) {
|
||||
@ -886,8 +922,7 @@ static void if_spi_host_to_card_worker(struct work_struct *work)
|
||||
if_spi_h2c(card, packet, MVMS_CMD);
|
||||
}
|
||||
if (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY) {
|
||||
/* Do we have any data packets from the host to
|
||||
* send? */
|
||||
/* Do we have any data packets from the host to send? */
|
||||
packet = NULL;
|
||||
spin_lock_irqsave(&card->buffer_lock, flags);
|
||||
if (!list_empty(&card->data_packet_list)) {
|
||||
@ -914,7 +949,8 @@ err:
|
||||
* Host to Card
|
||||
*
|
||||
* Called from Libertas to transfer some data to the WLAN device
|
||||
* We can't sleep here. */
|
||||
* We can't sleep here.
|
||||
*/
|
||||
static int if_spi_host_to_card(struct lbs_private *priv,
|
||||
u8 type, u8 *buf, u16 nb)
|
||||
{
|
||||
@ -1125,8 +1161,10 @@ static int __devinit if_spi_probe(struct spi_device *spi)
|
||||
if (err)
|
||||
goto free_card;
|
||||
|
||||
/* Register our card with libertas.
|
||||
* This will call alloc_etherdev */
|
||||
/*
|
||||
* Register our card with libertas.
|
||||
* This will call alloc_etherdev.
|
||||
*/
|
||||
priv = lbs_add_card(card, &spi->dev);
|
||||
if (!priv) {
|
||||
err = -ENOMEM;
|
||||
@ -1153,9 +1191,11 @@ static int __devinit if_spi_probe(struct spi_device *spi)
|
||||
goto terminate_workqueue;
|
||||
}
|
||||
|
||||
/* Start the card.
|
||||
/*
|
||||
* Start the card.
|
||||
* This will call register_netdev, and we'll start
|
||||
* getting interrupts... */
|
||||
* getting interrupts...
|
||||
*/
|
||||
err = lbs_start_card(priv);
|
||||
if (err)
|
||||
goto release_irq;
|
||||
|
@ -86,34 +86,34 @@
|
||||
#define IF_SPI_DEVICEID_CTRL_REG_TO_CARD_REV(dc) (dc & 0x000000ff)
|
||||
|
||||
/***************** IF_SPI_HOST_INT_CTRL_REG *****************/
|
||||
/** Host Interrupt Control bit : Wake up */
|
||||
/* Host Interrupt Control bit : Wake up */
|
||||
#define IF_SPI_HICT_WAKE_UP (1<<0)
|
||||
/** Host Interrupt Control bit : WLAN ready */
|
||||
/* Host Interrupt Control bit : WLAN ready */
|
||||
#define IF_SPI_HICT_WLAN_READY (1<<1)
|
||||
/*#define IF_SPI_HICT_FIFO_FIRST_HALF_EMPTY (1<<2) */
|
||||
/*#define IF_SPI_HICT_FIFO_SECOND_HALF_EMPTY (1<<3) */
|
||||
/*#define IF_SPI_HICT_IRQSRC_WLAN (1<<4) */
|
||||
/** Host Interrupt Control bit : Tx auto download */
|
||||
/* Host Interrupt Control bit : Tx auto download */
|
||||
#define IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO (1<<5)
|
||||
/** Host Interrupt Control bit : Rx auto upload */
|
||||
/* Host Interrupt Control bit : Rx auto upload */
|
||||
#define IF_SPI_HICT_RX_UPLOAD_OVER_AUTO (1<<6)
|
||||
/** Host Interrupt Control bit : Command auto download */
|
||||
/* Host Interrupt Control bit : Command auto download */
|
||||
#define IF_SPI_HICT_CMD_DOWNLOAD_OVER_AUTO (1<<7)
|
||||
/** Host Interrupt Control bit : Command auto upload */
|
||||
/* Host Interrupt Control bit : Command auto upload */
|
||||
#define IF_SPI_HICT_CMD_UPLOAD_OVER_AUTO (1<<8)
|
||||
|
||||
/***************** IF_SPI_CARD_INT_CAUSE_REG *****************/
|
||||
/** Card Interrupt Case bit : Tx download over */
|
||||
/* Card Interrupt Case bit : Tx download over */
|
||||
#define IF_SPI_CIC_TX_DOWNLOAD_OVER (1<<0)
|
||||
/** Card Interrupt Case bit : Rx upload over */
|
||||
/* Card Interrupt Case bit : Rx upload over */
|
||||
#define IF_SPI_CIC_RX_UPLOAD_OVER (1<<1)
|
||||
/** Card Interrupt Case bit : Command download over */
|
||||
/* Card Interrupt Case bit : Command download over */
|
||||
#define IF_SPI_CIC_CMD_DOWNLOAD_OVER (1<<2)
|
||||
/** Card Interrupt Case bit : Host event */
|
||||
/* Card Interrupt Case bit : Host event */
|
||||
#define IF_SPI_CIC_HOST_EVENT (1<<3)
|
||||
/** Card Interrupt Case bit : Command upload over */
|
||||
/* Card Interrupt Case bit : Command upload over */
|
||||
#define IF_SPI_CIC_CMD_UPLOAD_OVER (1<<4)
|
||||
/** Card Interrupt Case bit : Power down */
|
||||
/* Card Interrupt Case bit : Power down */
|
||||
#define IF_SPI_CIC_POWER_DOWN (1<<5)
|
||||
|
||||
/***************** IF_SPI_CARD_INT_STATUS_REG *****************/
|
||||
@ -138,51 +138,51 @@
|
||||
#define IF_SPI_HICU_CMD_RD_FIFO_UNDERFLOW (1<<10)
|
||||
|
||||
/***************** IF_SPI_HOST_INT_STATUS_REG *****************/
|
||||
/** Host Interrupt Status bit : Tx download ready */
|
||||
/* Host Interrupt Status bit : Tx download ready */
|
||||
#define IF_SPI_HIST_TX_DOWNLOAD_RDY (1<<0)
|
||||
/** Host Interrupt Status bit : Rx upload ready */
|
||||
/* Host Interrupt Status bit : Rx upload ready */
|
||||
#define IF_SPI_HIST_RX_UPLOAD_RDY (1<<1)
|
||||
/** Host Interrupt Status bit : Command download ready */
|
||||
/* Host Interrupt Status bit : Command download ready */
|
||||
#define IF_SPI_HIST_CMD_DOWNLOAD_RDY (1<<2)
|
||||
/** Host Interrupt Status bit : Card event */
|
||||
/* Host Interrupt Status bit : Card event */
|
||||
#define IF_SPI_HIST_CARD_EVENT (1<<3)
|
||||
/** Host Interrupt Status bit : Command upload ready */
|
||||
/* Host Interrupt Status bit : Command upload ready */
|
||||
#define IF_SPI_HIST_CMD_UPLOAD_RDY (1<<4)
|
||||
/** Host Interrupt Status bit : I/O write FIFO overflow */
|
||||
/* Host Interrupt Status bit : I/O write FIFO overflow */
|
||||
#define IF_SPI_HIST_IO_WR_FIFO_OVERFLOW (1<<5)
|
||||
/** Host Interrupt Status bit : I/O read FIFO underflow */
|
||||
/* Host Interrupt Status bit : I/O read FIFO underflow */
|
||||
#define IF_SPI_HIST_IO_RD_FIFO_UNDRFLOW (1<<6)
|
||||
/** Host Interrupt Status bit : Data write FIFO overflow */
|
||||
/* Host Interrupt Status bit : Data write FIFO overflow */
|
||||
#define IF_SPI_HIST_DATA_WR_FIFO_OVERFLOW (1<<7)
|
||||
/** Host Interrupt Status bit : Data read FIFO underflow */
|
||||
/* Host Interrupt Status bit : Data read FIFO underflow */
|
||||
#define IF_SPI_HIST_DATA_RD_FIFO_UNDERFLOW (1<<8)
|
||||
/** Host Interrupt Status bit : Command write FIFO overflow */
|
||||
/* Host Interrupt Status bit : Command write FIFO overflow */
|
||||
#define IF_SPI_HIST_CMD_WR_FIFO_OVERFLOW (1<<9)
|
||||
/** Host Interrupt Status bit : Command read FIFO underflow */
|
||||
/* Host Interrupt Status bit : Command read FIFO underflow */
|
||||
#define IF_SPI_HIST_CMD_RD_FIFO_UNDERFLOW (1<<10)
|
||||
|
||||
/***************** IF_SPI_HOST_INT_STATUS_MASK_REG *****************/
|
||||
/** Host Interrupt Status Mask bit : Tx download ready */
|
||||
/* Host Interrupt Status Mask bit : Tx download ready */
|
||||
#define IF_SPI_HISM_TX_DOWNLOAD_RDY (1<<0)
|
||||
/** Host Interrupt Status Mask bit : Rx upload ready */
|
||||
/* Host Interrupt Status Mask bit : Rx upload ready */
|
||||
#define IF_SPI_HISM_RX_UPLOAD_RDY (1<<1)
|
||||
/** Host Interrupt Status Mask bit : Command download ready */
|
||||
/* Host Interrupt Status Mask bit : Command download ready */
|
||||
#define IF_SPI_HISM_CMD_DOWNLOAD_RDY (1<<2)
|
||||
/** Host Interrupt Status Mask bit : Card event */
|
||||
/* Host Interrupt Status Mask bit : Card event */
|
||||
#define IF_SPI_HISM_CARDEVENT (1<<3)
|
||||
/** Host Interrupt Status Mask bit : Command upload ready */
|
||||
/* Host Interrupt Status Mask bit : Command upload ready */
|
||||
#define IF_SPI_HISM_CMD_UPLOAD_RDY (1<<4)
|
||||
/** Host Interrupt Status Mask bit : I/O write FIFO overflow */
|
||||
/* Host Interrupt Status Mask bit : I/O write FIFO overflow */
|
||||
#define IF_SPI_HISM_IO_WR_FIFO_OVERFLOW (1<<5)
|
||||
/** Host Interrupt Status Mask bit : I/O read FIFO underflow */
|
||||
/* Host Interrupt Status Mask bit : I/O read FIFO underflow */
|
||||
#define IF_SPI_HISM_IO_RD_FIFO_UNDERFLOW (1<<6)
|
||||
/** Host Interrupt Status Mask bit : Data write FIFO overflow */
|
||||
/* Host Interrupt Status Mask bit : Data write FIFO overflow */
|
||||
#define IF_SPI_HISM_DATA_WR_FIFO_OVERFLOW (1<<7)
|
||||
/** Host Interrupt Status Mask bit : Data write FIFO underflow */
|
||||
/* Host Interrupt Status Mask bit : Data write FIFO underflow */
|
||||
#define IF_SPI_HISM_DATA_RD_FIFO_UNDERFLOW (1<<8)
|
||||
/** Host Interrupt Status Mask bit : Command write FIFO overflow */
|
||||
/* Host Interrupt Status Mask bit : Command write FIFO overflow */
|
||||
#define IF_SPI_HISM_CMD_WR_FIFO_OVERFLOW (1<<9)
|
||||
/** Host Interrupt Status Mask bit : Command write FIFO underflow */
|
||||
/* Host Interrupt Status Mask bit : Command write FIFO underflow */
|
||||
#define IF_SPI_HISM_CMD_RD_FIFO_UNDERFLOW (1<<10)
|
||||
|
||||
/***************** IF_SPI_SPU_BUS_MODE_REG *****************/
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* This file contains functions used in USB interface module.
|
||||
*/
|
||||
/*
|
||||
* This file contains functions used in USB interface module.
|
||||
*/
|
||||
#include <linux/delay.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/firmware.h>
|
||||
@ -66,7 +66,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp);
|
||||
|
||||
/* sysfs hooks */
|
||||
|
||||
/**
|
||||
/*
|
||||
* Set function to write firmware to device's persistent memory
|
||||
*/
|
||||
static ssize_t if_usb_firmware_set(struct device *dev,
|
||||
@ -85,7 +85,7 @@ static ssize_t if_usb_firmware_set(struct device *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* lbs_flash_fw attribute to be exported per ethX interface through sysfs
|
||||
* (/sys/class/net/ethX/lbs_flash_fw). Use this like so to write firmware to
|
||||
* the device's persistent memory:
|
||||
@ -94,7 +94,14 @@ static ssize_t if_usb_firmware_set(struct device *dev,
|
||||
static DEVICE_ATTR(lbs_flash_fw, 0200, NULL, if_usb_firmware_set);
|
||||
|
||||
/**
|
||||
* Set function to write firmware to device's persistent memory
|
||||
* if_usb_boot2_set - write firmware to device's persistent memory
|
||||
*
|
||||
* @dev: target device
|
||||
* @attr: device attributes
|
||||
* @buf: firmware buffer to write
|
||||
* @count: number of bytes to write
|
||||
*
|
||||
* returns: number of bytes written or negative error code
|
||||
*/
|
||||
static ssize_t if_usb_boot2_set(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
@ -112,7 +119,7 @@ static ssize_t if_usb_boot2_set(struct device *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* lbs_flash_boot2 attribute to be exported per ethX interface through sysfs
|
||||
* (/sys/class/net/ethX/lbs_flash_boot2). Use this like so to write firmware
|
||||
* to the device's persistent memory:
|
||||
@ -121,9 +128,10 @@ static ssize_t if_usb_boot2_set(struct device *dev,
|
||||
static DEVICE_ATTR(lbs_flash_boot2, 0200, NULL, if_usb_boot2_set);
|
||||
|
||||
/**
|
||||
* @brief call back function to handle the status of the URB
|
||||
* @param urb pointer to urb structure
|
||||
* @return N/A
|
||||
* if_usb_write_bulk_callback - callback function to handle the status
|
||||
* of the URB
|
||||
* @urb: pointer to &urb structure
|
||||
* returns: N/A
|
||||
*/
|
||||
static void if_usb_write_bulk_callback(struct urb *urb)
|
||||
{
|
||||
@ -150,9 +158,9 @@ static void if_usb_write_bulk_callback(struct urb *urb)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief free tx/rx urb, skb and rx buffer
|
||||
* @param cardp pointer if_usb_card
|
||||
* @return N/A
|
||||
* if_usb_free - free tx/rx urb, skb and rx buffer
|
||||
* @cardp: pointer to &if_usb_card
|
||||
* returns: N/A
|
||||
*/
|
||||
static void if_usb_free(struct if_usb_card *cardp)
|
||||
{
|
||||
@ -231,10 +239,10 @@ static void if_usb_reset_olpc_card(struct lbs_private *priv)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief sets the configuration values
|
||||
* @param ifnum interface number
|
||||
* @param id pointer to usb_device_id
|
||||
* @return 0 on success, error code on failure
|
||||
* if_usb_probe - sets the configuration values
|
||||
* @intf: &usb_interface pointer
|
||||
* @id: pointer to usb_device_id
|
||||
* returns: 0 on success, error code on failure
|
||||
*/
|
||||
static int if_usb_probe(struct usb_interface *intf,
|
||||
const struct usb_device_id *id)
|
||||
@ -366,9 +374,9 @@ error:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief free resource and cleanup
|
||||
* @param intf USB interface structure
|
||||
* @return N/A
|
||||
* if_usb_disconnect - free resource and cleanup
|
||||
* @intf: USB interface structure
|
||||
* returns: N/A
|
||||
*/
|
||||
static void if_usb_disconnect(struct usb_interface *intf)
|
||||
{
|
||||
@ -398,9 +406,9 @@ static void if_usb_disconnect(struct usb_interface *intf)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function download FW
|
||||
* @param priv pointer to struct lbs_private
|
||||
* @return 0
|
||||
* if_usb_send_fw_pkt - download FW
|
||||
* @cardp: pointer to &struct if_usb_card
|
||||
* returns: 0
|
||||
*/
|
||||
static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
|
||||
{
|
||||
@ -486,11 +494,11 @@ static int if_usb_reset_device(struct if_usb_card *cardp)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function transfer the data to the device.
|
||||
* @param priv pointer to struct lbs_private
|
||||
* @param payload pointer to payload data
|
||||
* @param nb data length
|
||||
* @return 0 or -1
|
||||
* usb_tx_block - transfer the data to the device
|
||||
* @cardp: pointer to &struct if_usb_card
|
||||
* @payload: pointer to payload data
|
||||
* @nb: data length
|
||||
* returns: 0 for success or negative error code
|
||||
*/
|
||||
static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb)
|
||||
{
|
||||
@ -727,11 +735,11 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function reads of the packet into the upload buff,
|
||||
* wake up the main thread and initialise the Rx callack.
|
||||
* if_usb_receive - read the packet into the upload buffer,
|
||||
* wake up the main thread and initialise the Rx callack
|
||||
*
|
||||
* @param urb pointer to struct urb
|
||||
* @return N/A
|
||||
* @urb: pointer to &struct urb
|
||||
* returns: N/A
|
||||
*/
|
||||
static void if_usb_receive(struct urb *urb)
|
||||
{
|
||||
@ -802,12 +810,12 @@ rx_exit:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function downloads data to FW
|
||||
* @param priv pointer to struct lbs_private structure
|
||||
* @param type type of data
|
||||
* @param buf pointer to data buffer
|
||||
* @param len number of bytes
|
||||
* @return 0 or -1
|
||||
* if_usb_host_to_card - downloads data to FW
|
||||
* @priv: pointer to &struct lbs_private structure
|
||||
* @type: type of data
|
||||
* @payload: pointer to data buffer
|
||||
* @nb: number of bytes
|
||||
* returns: 0 for success or negative error code
|
||||
*/
|
||||
static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
|
||||
uint8_t *payload, uint16_t nb)
|
||||
@ -831,10 +839,11 @@ static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function issues Boot command to the Boot2 code
|
||||
* @param ivalue 1:Boot from FW by USB-Download
|
||||
* 2:Boot from FW in EEPROM
|
||||
* @return 0
|
||||
* if_usb_issue_boot_command - issues Boot command to the Boot2 code
|
||||
* @cardp: pointer to &if_usb_card
|
||||
* @ivalue: 1:Boot from FW by USB-Download
|
||||
* 2:Boot from FW in EEPROM
|
||||
* returns: 0 for success or negative error code
|
||||
*/
|
||||
static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue)
|
||||
{
|
||||
@ -853,11 +862,11 @@ static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue)
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function checks the validity of Boot2/FW image.
|
||||
* check_fwfile_format - check the validity of Boot2/FW image
|
||||
*
|
||||
* @param data pointer to image
|
||||
* len image length
|
||||
* @return 0 or -1
|
||||
* @data: pointer to image
|
||||
* @totlen: image length
|
||||
* returns: 0 (good) or 1 (failure)
|
||||
*/
|
||||
static int check_fwfile_format(const uint8_t *data, uint32_t totlen)
|
||||
{
|
||||
@ -901,13 +910,13 @@ static int check_fwfile_format(const uint8_t *data, uint32_t totlen)
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function programs the firmware subject to cmd
|
||||
* if_usb_prog_firmware - programs the firmware subject to cmd
|
||||
*
|
||||
* @param cardp the if_usb_card descriptor
|
||||
* fwname firmware or boot2 image file name
|
||||
* cmd either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW,
|
||||
* or BOOT_CMD_UPDATE_BOOT2.
|
||||
* @return 0 or error code
|
||||
* @cardp: the if_usb_card descriptor
|
||||
* @fwname: firmware or boot2 image file name
|
||||
* @cmd: either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW,
|
||||
* or BOOT_CMD_UPDATE_BOOT2.
|
||||
* returns: 0 or error code
|
||||
*/
|
||||
static int if_usb_prog_firmware(struct if_usb_card *cardp,
|
||||
const char *fwname, int cmd)
|
||||
|
@ -6,9 +6,9 @@
|
||||
|
||||
struct lbs_private;
|
||||
|
||||
/**
|
||||
* This file contains definition for USB interface.
|
||||
*/
|
||||
/*
|
||||
* This file contains definition for USB interface.
|
||||
*/
|
||||
#define CMD_TYPE_REQUEST 0xF00DFACE
|
||||
#define CMD_TYPE_DATA 0xBEADC0DE
|
||||
#define CMD_TYPE_INDICATION 0xBEEFFACE
|
||||
@ -40,7 +40,7 @@ struct bootcmdresp
|
||||
uint8_t pad[2];
|
||||
};
|
||||
|
||||
/** USB card description structure*/
|
||||
/* USB card description structure*/
|
||||
struct if_usb_card {
|
||||
struct usb_device *udev;
|
||||
uint32_t model; /* MODEL_* */
|
||||
@ -77,7 +77,7 @@ struct if_usb_card {
|
||||
__le16 boot2_version;
|
||||
};
|
||||
|
||||
/** fwheader */
|
||||
/* fwheader */
|
||||
struct fwheader {
|
||||
__le32 dnldcmd;
|
||||
__le32 baseaddr;
|
||||
@ -86,14 +86,14 @@ struct fwheader {
|
||||
};
|
||||
|
||||
#define FW_MAX_DATA_BLK_SIZE 600
|
||||
/** FWData */
|
||||
/* FWData */
|
||||
struct fwdata {
|
||||
struct fwheader hdr;
|
||||
__le32 seqnum;
|
||||
uint8_t data[0];
|
||||
};
|
||||
|
||||
/** fwsyncheader */
|
||||
/* fwsyncheader */
|
||||
struct fwsyncheader {
|
||||
__le32 cmd;
|
||||
__le32 seqnum;
|
||||
|
@ -1,8 +1,8 @@
|
||||
/**
|
||||
* This file contains the major functions in WLAN
|
||||
* driver. It includes init, exit, open, close and main
|
||||
* thread etc..
|
||||
*/
|
||||
/*
|
||||
* This file contains the major functions in WLAN
|
||||
* driver. It includes init, exit, open, close and main
|
||||
* thread etc..
|
||||
*/
|
||||
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/delay.h>
|
||||
@ -35,18 +35,20 @@ EXPORT_SYMBOL_GPL(lbs_debug);
|
||||
module_param_named(libertas_debug, lbs_debug, int, 0644);
|
||||
|
||||
|
||||
/* This global structure is used to send the confirm_sleep command as
|
||||
* fast as possible down to the firmware. */
|
||||
/*
|
||||
* This global structure is used to send the confirm_sleep command as
|
||||
* fast as possible down to the firmware.
|
||||
*/
|
||||
struct cmd_confirm_sleep confirm_sleep;
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* the table to keep region code
|
||||
*/
|
||||
u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
|
||||
{ 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
|
||||
|
||||
/**
|
||||
/*
|
||||
* FW rate table. FW refers to rates by their index in this table, not by the
|
||||
* rate value itself. Values of 0x00 are
|
||||
* reserved positions.
|
||||
@ -57,10 +59,10 @@ static u8 fw_data_rates[MAX_RATES] =
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief use index to get the data rate
|
||||
* lbs_fw_index_to_data_rate - use index to get the data rate
|
||||
*
|
||||
* @param idx The index of data rate
|
||||
* @return data rate or 0
|
||||
* @idx: The index of data rate
|
||||
* returns: data rate or 0
|
||||
*/
|
||||
u32 lbs_fw_index_to_data_rate(u8 idx)
|
||||
{
|
||||
@ -70,10 +72,10 @@ u32 lbs_fw_index_to_data_rate(u8 idx)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief use rate to get the index
|
||||
* lbs_data_rate_to_fw_index - use rate to get the index
|
||||
*
|
||||
* @param rate data rate
|
||||
* @return index or 0
|
||||
* @rate: data rate
|
||||
* returns: index or 0
|
||||
*/
|
||||
u8 lbs_data_rate_to_fw_index(u32 rate)
|
||||
{
|
||||
@ -91,10 +93,10 @@ u8 lbs_data_rate_to_fw_index(u32 rate)
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function opens the ethX interface
|
||||
* lbs_dev_open - open the ethX interface
|
||||
*
|
||||
* @param dev A pointer to net_device structure
|
||||
* @return 0 or -EBUSY if monitor mode active
|
||||
* @dev: A pointer to &net_device structure
|
||||
* returns: 0 or -EBUSY if monitor mode active
|
||||
*/
|
||||
static int lbs_dev_open(struct net_device *dev)
|
||||
{
|
||||
@ -120,10 +122,10 @@ static int lbs_dev_open(struct net_device *dev)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function closes the ethX interface
|
||||
* lbs_eth_stop - close the ethX interface
|
||||
*
|
||||
* @param dev A pointer to net_device structure
|
||||
* @return 0
|
||||
* @dev: A pointer to &net_device structure
|
||||
* returns: 0
|
||||
*/
|
||||
static int lbs_eth_stop(struct net_device *dev)
|
||||
{
|
||||
@ -336,12 +338,12 @@ void lbs_set_multicast_list(struct net_device *dev)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles the major jobs in the LBS driver.
|
||||
* lbs_thread - handles the major jobs in the LBS driver.
|
||||
* It handles all events generated by firmware, RX data received
|
||||
* from firmware and TX data sent from kernel.
|
||||
*
|
||||
* @param data A pointer to lbs_thread structure
|
||||
* @return 0
|
||||
* @data: A pointer to &lbs_thread structure
|
||||
* returns: 0
|
||||
*/
|
||||
static int lbs_thread(void *data)
|
||||
{
|
||||
@ -540,11 +542,11 @@ static int lbs_thread(void *data)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function gets the HW spec from the firmware and sets
|
||||
* some basic parameters.
|
||||
* lbs_setup_firmware - gets the HW spec from the firmware and sets
|
||||
* some basic parameters
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @return 0 or -1
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* returns: 0 or -1
|
||||
*/
|
||||
static int lbs_setup_firmware(struct lbs_private *priv)
|
||||
{
|
||||
@ -630,8 +632,10 @@ int lbs_resume(struct lbs_private *priv)
|
||||
EXPORT_SYMBOL_GPL(lbs_resume);
|
||||
|
||||
/**
|
||||
* This function handles the timeout of command sending.
|
||||
* It will re-send the same command again.
|
||||
* lbs_cmd_timeout_handler - handles the timeout of command sending.
|
||||
* It will re-send the same command again.
|
||||
*
|
||||
* @data: &struct lbs_private pointer
|
||||
*/
|
||||
static void lbs_cmd_timeout_handler(unsigned long data)
|
||||
{
|
||||
@ -655,8 +659,10 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
* This function put the device back to deep sleep mode when timer expires
|
||||
* and no activity (command, event, data etc.) is detected.
|
||||
* auto_deepsleep_timer_fn - put the device back to deep sleep mode when
|
||||
* timer expires and no activity (command, event, data etc.) is detected.
|
||||
* @data: &struct lbs_private pointer
|
||||
* returns: N/A
|
||||
*/
|
||||
static void auto_deepsleep_timer_fn(unsigned long data)
|
||||
{
|
||||
@ -792,11 +798,12 @@ static const struct net_device_ops lbs_netdev_ops = {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This function adds the card. it will probe the
|
||||
* lbs_add_card - adds the card. It will probe the
|
||||
* card, allocate the lbs_priv and initialize the device.
|
||||
*
|
||||
* @param card A pointer to card
|
||||
* @return A pointer to struct lbs_private structure
|
||||
* @card: A pointer to card
|
||||
* @dmdev: A pointer to &struct device
|
||||
* returns: A pointer to &struct lbs_private structure
|
||||
*/
|
||||
struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
|
||||
{
|
||||
@ -1057,19 +1064,19 @@ void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx)
|
||||
EXPORT_SYMBOL_GPL(lbs_notify_command_response);
|
||||
|
||||
/**
|
||||
* @brief Retrieves two-stage firmware
|
||||
* lbs_get_firmware - Retrieves two-stage firmware
|
||||
*
|
||||
* @param dev A pointer to device structure
|
||||
* @param user_helper User-defined helper firmware file
|
||||
* @param user_mainfw User-defined main firmware file
|
||||
* @param card_model Bus-specific card model ID used to filter firmware table
|
||||
* elements
|
||||
* @param fw_table Table of firmware file names and device model numbers
|
||||
* terminated by an entry with a NULL helper name
|
||||
* @param helper On success, the helper firmware; caller must free
|
||||
* @param mainfw On success, the main firmware; caller must free
|
||||
* @dev: A pointer to &device structure
|
||||
* @user_helper: User-defined helper firmware file
|
||||
* @user_mainfw: User-defined main firmware file
|
||||
* @card_model: Bus-specific card model ID used to filter firmware table
|
||||
* elements
|
||||
* @fw_table: Table of firmware file names and device model numbers
|
||||
* terminated by an entry with a NULL helper name
|
||||
* @helper: On success, the helper firmware; caller must free
|
||||
* @mainfw: On success, the main firmware; caller must free
|
||||
*
|
||||
* @return 0 on success, non-zero on failure
|
||||
* returns: 0 on success, non-zero on failure
|
||||
*/
|
||||
int lbs_get_firmware(struct device *dev, const char *user_helper,
|
||||
const char *user_mainfw, u32 card_model,
|
||||
|
@ -16,12 +16,15 @@
|
||||
* Mesh sysfs support
|
||||
*/
|
||||
|
||||
/**
|
||||
/*
|
||||
* Attributes exported through sysfs
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Get function for sysfs attribute anycast_mask
|
||||
* lbs_anycast_get - Get function for sysfs attribute anycast_mask
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer where data will be returned
|
||||
*/
|
||||
static ssize_t lbs_anycast_get(struct device *dev,
|
||||
struct device_attribute *attr, char * buf)
|
||||
@ -40,7 +43,11 @@ static ssize_t lbs_anycast_get(struct device *dev,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set function for sysfs attribute anycast_mask
|
||||
* lbs_anycast_set - Set function for sysfs attribute anycast_mask
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer that contains new attribute value
|
||||
* @count: size of buffer
|
||||
*/
|
||||
static ssize_t lbs_anycast_set(struct device *dev,
|
||||
struct device_attribute *attr, const char * buf, size_t count)
|
||||
@ -62,7 +69,10 @@ static ssize_t lbs_anycast_set(struct device *dev,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get function for sysfs attribute prb_rsp_limit
|
||||
* lbs_prb_rsp_limit_get - Get function for sysfs attribute prb_rsp_limit
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer where data will be returned
|
||||
*/
|
||||
static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
@ -85,7 +95,11 @@ static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set function for sysfs attribute prb_rsp_limit
|
||||
* lbs_prb_rsp_limit_set - Set function for sysfs attribute prb_rsp_limit
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer that contains new attribute value
|
||||
* @count: size of buffer
|
||||
*/
|
||||
static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
@ -114,7 +128,10 @@ static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
|
||||
}
|
||||
|
||||
/**
|
||||
* Get function for sysfs attribute mesh
|
||||
* lbs_mesh_get - Get function for sysfs attribute mesh
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer where data will be returned
|
||||
*/
|
||||
static ssize_t lbs_mesh_get(struct device *dev,
|
||||
struct device_attribute *attr, char * buf)
|
||||
@ -124,7 +141,11 @@ static ssize_t lbs_mesh_get(struct device *dev,
|
||||
}
|
||||
|
||||
/**
|
||||
* Set function for sysfs attribute mesh
|
||||
* lbs_mesh_set - Set function for sysfs attribute mesh
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer that contains new attribute value
|
||||
* @count: size of buffer
|
||||
*/
|
||||
static ssize_t lbs_mesh_set(struct device *dev,
|
||||
struct device_attribute *attr, const char * buf, size_t count)
|
||||
@ -151,19 +172,19 @@ static ssize_t lbs_mesh_set(struct device *dev,
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* lbs_mesh attribute to be exported per ethX interface
|
||||
* through sysfs (/sys/class/net/ethX/lbs_mesh)
|
||||
*/
|
||||
static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
|
||||
|
||||
/**
|
||||
/*
|
||||
* anycast_mask attribute to be exported per mshX interface
|
||||
* through sysfs (/sys/class/net/mshX/anycast_mask)
|
||||
*/
|
||||
static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
|
||||
|
||||
/**
|
||||
/*
|
||||
* prb_rsp_limit attribute to be exported per mshX interface
|
||||
* through sysfs (/sys/class/net/mshX/prb_rsp_limit)
|
||||
*/
|
||||
@ -274,10 +295,10 @@ int lbs_deinit_mesh(struct lbs_private *priv)
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function closes the mshX interface
|
||||
* lbs_mesh_stop - close the mshX interface
|
||||
*
|
||||
* @param dev A pointer to net_device structure
|
||||
* @return 0
|
||||
* @dev: A pointer to &net_device structure
|
||||
* returns: 0
|
||||
*/
|
||||
static int lbs_mesh_stop(struct net_device *dev)
|
||||
{
|
||||
@ -301,10 +322,10 @@ static int lbs_mesh_stop(struct net_device *dev)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function opens the mshX interface
|
||||
* lbs_mesh_dev_open - open the mshX interface
|
||||
*
|
||||
* @param dev A pointer to net_device structure
|
||||
* @return 0 or -EBUSY if monitor mode active
|
||||
* @dev: A pointer to &net_device structure
|
||||
* returns: 0 or -EBUSY if monitor mode active
|
||||
*/
|
||||
static int lbs_mesh_dev_open(struct net_device *dev)
|
||||
{
|
||||
@ -342,10 +363,10 @@ static const struct net_device_ops mesh_netdev_ops = {
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This function adds mshX interface
|
||||
* lbs_add_mesh - add mshX interface
|
||||
*
|
||||
* @param priv A pointer to the struct lbs_private structure
|
||||
* @return 0 if successful, -X otherwise
|
||||
* @priv: A pointer to the &struct lbs_private structure
|
||||
* returns: 0 if successful, -X otherwise
|
||||
*/
|
||||
int lbs_add_mesh(struct lbs_private *priv)
|
||||
{
|
||||
@ -456,13 +477,13 @@ void lbs_mesh_set_txpd(struct lbs_private *priv,
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Add or delete Mesh Blinding Table entries
|
||||
* lbs_mesh_bt_add_del - Add or delete Mesh Blinding Table entries
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param add TRUE to add the entry, FALSE to delete it
|
||||
* @param addr1 Destination address to blind or unblind
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @add: TRUE to add the entry, FALSE to delete it
|
||||
* @addr1: Destination address to blind or unblind
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
* returns: 0 on success, error on failure
|
||||
*/
|
||||
int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1)
|
||||
{
|
||||
@ -493,11 +514,11 @@ int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset/clear the mesh blinding table
|
||||
* lbs_mesh_bt_reset - Reset/clear the mesh blinding table
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
* returns: 0 on success, error on failure
|
||||
*/
|
||||
int lbs_mesh_bt_reset(struct lbs_private *priv)
|
||||
{
|
||||
@ -517,17 +538,18 @@ int lbs_mesh_bt_reset(struct lbs_private *priv)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the inverted status of the mesh blinding table
|
||||
* lbs_mesh_bt_get_inverted - Gets the inverted status of the mesh
|
||||
* blinding table
|
||||
*
|
||||
* Normally the firmware "blinds" or ignores traffic from mesh nodes in the
|
||||
* table, but an inverted table allows *only* traffic from nodes listed in
|
||||
* the table.
|
||||
* Normally the firmware "blinds" or ignores traffic from mesh nodes in the
|
||||
* table, but an inverted table allows *only* traffic from nodes listed in
|
||||
* the table.
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param invert On success, TRUE if the blinding table is inverted,
|
||||
* FALSE if it is not inverted
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @inverted: On success, TRUE if the blinding table is inverted,
|
||||
* FALSE if it is not inverted
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
* returns: 0 on success, error on failure
|
||||
*/
|
||||
int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted)
|
||||
{
|
||||
@ -551,18 +573,19 @@ int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the inverted status of the mesh blinding table
|
||||
* lbs_mesh_bt_set_inverted - Sets the inverted status of the mesh
|
||||
* blinding table
|
||||
*
|
||||
* Normally the firmware "blinds" or ignores traffic from mesh nodes in the
|
||||
* table, but an inverted table allows *only* traffic from nodes listed in
|
||||
* the table.
|
||||
* Normally the firmware "blinds" or ignores traffic from mesh nodes in the
|
||||
* table, but an inverted table allows *only* traffic from nodes listed in
|
||||
* the table.
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param invert TRUE to invert the blinding table (only traffic from
|
||||
* listed nodes allowed), FALSE to return it
|
||||
* to normal state (listed nodes ignored)
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @inverted: TRUE to invert the blinding table (only traffic from
|
||||
* listed nodes allowed), FALSE to return it
|
||||
* to normal state (listed nodes ignored)
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
* returns: 0 on success, error on failure
|
||||
*/
|
||||
int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted)
|
||||
{
|
||||
@ -583,13 +606,13 @@ int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief List an entry in the mesh blinding table
|
||||
* lbs_mesh_bt_get_entry - List an entry in the mesh blinding table
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param id The ID of the entry to list
|
||||
* @param addr1 MAC address associated with the table entry
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @id: The ID of the entry to list
|
||||
* @addr1: MAC address associated with the table entry
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
* returns: 0 on success, error on failure
|
||||
*/
|
||||
int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1)
|
||||
{
|
||||
@ -614,14 +637,14 @@ int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Access the mesh forwarding table
|
||||
* lbs_cmd_fwt_access - Access the mesh forwarding table
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param cmd_action The forwarding table action to perform
|
||||
* @param cmd The pre-filled FWT_ACCESS command
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @cmd_action: The forwarding table action to perform
|
||||
* @cmd: The pre-filled FWT_ACCESS command
|
||||
*
|
||||
* @return 0 on success and 'cmd' will be filled with the
|
||||
* firmware's response
|
||||
* returns: 0 on success and 'cmd' will be filled with the
|
||||
* firmware's response
|
||||
*/
|
||||
int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action,
|
||||
struct cmd_ds_fwt_access *cmd)
|
||||
@ -774,7 +797,10 @@ static int mesh_get_default_parameters(struct device *dev,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get function for sysfs attribute bootflag
|
||||
* bootflag_get - Get function for sysfs attribute bootflag
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer where data will be returned
|
||||
*/
|
||||
static ssize_t bootflag_get(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
@ -791,7 +817,11 @@ static ssize_t bootflag_get(struct device *dev,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set function for sysfs attribute bootflag
|
||||
* bootflag_set - Set function for sysfs attribute bootflag
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer that contains new attribute value
|
||||
* @count: size of buffer
|
||||
*/
|
||||
static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
@ -817,7 +847,10 @@ static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get function for sysfs attribute boottime
|
||||
* boottime_get - Get function for sysfs attribute boottime
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer where data will be returned
|
||||
*/
|
||||
static ssize_t boottime_get(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
@ -834,7 +867,11 @@ static ssize_t boottime_get(struct device *dev,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set function for sysfs attribute boottime
|
||||
* boottime_set - Set function for sysfs attribute boottime
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer that contains new attribute value
|
||||
* @count: size of buffer
|
||||
*/
|
||||
static ssize_t boottime_set(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
@ -869,7 +906,10 @@ static ssize_t boottime_set(struct device *dev,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get function for sysfs attribute channel
|
||||
* channel_get - Get function for sysfs attribute channel
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer where data will be returned
|
||||
*/
|
||||
static ssize_t channel_get(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
@ -886,7 +926,11 @@ static ssize_t channel_get(struct device *dev,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set function for sysfs attribute channel
|
||||
* channel_set - Set function for sysfs attribute channel
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer that contains new attribute value
|
||||
* @count: size of buffer
|
||||
*/
|
||||
static ssize_t channel_set(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
@ -912,7 +956,10 @@ static ssize_t channel_set(struct device *dev, struct device_attribute *attr,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get function for sysfs attribute mesh_id
|
||||
* mesh_id_get - Get function for sysfs attribute mesh_id
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer where data will be returned
|
||||
*/
|
||||
static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
@ -938,7 +985,11 @@ static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set function for sysfs attribute mesh_id
|
||||
* mesh_id_set - Set function for sysfs attribute mesh_id
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer that contains new attribute value
|
||||
* @count: size of buffer
|
||||
*/
|
||||
static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
@ -980,7 +1031,10 @@ static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get function for sysfs attribute protocol_id
|
||||
* protocol_id_get - Get function for sysfs attribute protocol_id
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer where data will be returned
|
||||
*/
|
||||
static ssize_t protocol_id_get(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
@ -997,7 +1051,11 @@ static ssize_t protocol_id_get(struct device *dev,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set function for sysfs attribute protocol_id
|
||||
* protocol_id_set - Set function for sysfs attribute protocol_id
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer that contains new attribute value
|
||||
* @count: size of buffer
|
||||
*/
|
||||
static ssize_t protocol_id_set(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
@ -1034,7 +1092,10 @@ static ssize_t protocol_id_set(struct device *dev,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get function for sysfs attribute metric_id
|
||||
* metric_id_get - Get function for sysfs attribute metric_id
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer where data will be returned
|
||||
*/
|
||||
static ssize_t metric_id_get(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
@ -1051,7 +1112,11 @@ static ssize_t metric_id_get(struct device *dev,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set function for sysfs attribute metric_id
|
||||
* metric_id_set - Set function for sysfs attribute metric_id
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer that contains new attribute value
|
||||
* @count: size of buffer
|
||||
*/
|
||||
static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
@ -1088,7 +1153,10 @@ static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get function for sysfs attribute capability
|
||||
* capability_get - Get function for sysfs attribute capability
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer where data will be returned
|
||||
*/
|
||||
static ssize_t capability_get(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
@ -1105,7 +1173,11 @@ static ssize_t capability_get(struct device *dev,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set function for sysfs attribute capability
|
||||
* capability_set - Set function for sysfs attribute capability
|
||||
* @dev: the &struct device
|
||||
* @attr: device attributes
|
||||
* @buf: buffer that contains new attribute value
|
||||
* @count: size of buffer
|
||||
*/
|
||||
static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Contains all definitions needed for the Libertas' MESH implementation.
|
||||
*/
|
||||
/*
|
||||
* Contains all definitions needed for the Libertas' MESH implementation.
|
||||
*/
|
||||
#ifndef _LBS_MESH_H_
|
||||
#define _LBS_MESH_H_
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* This file contains the handling of RX in wlan driver.
|
||||
*/
|
||||
/*
|
||||
* This file contains the handling of RX in wlan driver.
|
||||
*/
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
@ -40,12 +40,12 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
|
||||
struct sk_buff *skb);
|
||||
|
||||
/**
|
||||
* @brief This function processes received packet and forwards it
|
||||
* to kernel/upper layer
|
||||
* lbs_process_rxed_packet - processes received packet and forwards it
|
||||
* to kernel/upper layer
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private
|
||||
* @param skb A pointer to skb which includes the received packet
|
||||
* @return 0 or -1
|
||||
* @priv: A pointer to &struct lbs_private
|
||||
* @skb: A pointer to skb which includes the received packet
|
||||
* returns: 0 or -1
|
||||
*/
|
||||
int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
|
||||
{
|
||||
@ -156,11 +156,11 @@ done:
|
||||
EXPORT_SYMBOL_GPL(lbs_process_rxed_packet);
|
||||
|
||||
/**
|
||||
* @brief This function converts Tx/Rx rates from the Marvell WLAN format
|
||||
* (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s)
|
||||
* convert_mv_rate_to_radiotap - converts Tx/Rx rates from Marvell WLAN format
|
||||
* (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s)
|
||||
*
|
||||
* @param rate Input rate
|
||||
* @return Output Rate (0 if invalid)
|
||||
* @rate: Input rate
|
||||
* returns: Output Rate (0 if invalid)
|
||||
*/
|
||||
static u8 convert_mv_rate_to_radiotap(u8 rate)
|
||||
{
|
||||
@ -196,12 +196,12 @@ static u8 convert_mv_rate_to_radiotap(u8 rate)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function processes a received 802.11 packet and forwards it
|
||||
* to kernel/upper layer
|
||||
* process_rxed_802_11_packet - processes a received 802.11 packet and forwards
|
||||
* it to kernel/upper layer
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private
|
||||
* @param skb A pointer to skb which includes the received packet
|
||||
* @return 0 or -1
|
||||
* @priv: A pointer to &struct lbs_private
|
||||
* @skb: A pointer to skb which includes the received packet
|
||||
* returns: 0 or -1
|
||||
*/
|
||||
static int process_rxed_802_11_packet(struct lbs_private *priv,
|
||||
struct sk_buff *skb)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* This file contains the handling of TX in wlan driver.
|
||||
*/
|
||||
/*
|
||||
* This file contains the handling of TX in wlan driver.
|
||||
*/
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/sched.h>
|
||||
@ -13,11 +13,11 @@
|
||||
#include "dev.h"
|
||||
|
||||
/**
|
||||
* @brief This function converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE
|
||||
* units (500 Kb/s) into Marvell WLAN format (see Table 8 in Section 3.2.1)
|
||||
* convert_radiotap_rate_to_mv - converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE
|
||||
* units (500 Kb/s) into Marvell WLAN format (see Table 8 in Section 3.2.1)
|
||||
*
|
||||
* @param rate Input rate
|
||||
* @return Output Rate (0 if invalid)
|
||||
* @rate: Input rate
|
||||
* returns: Output Rate (0 if invalid)
|
||||
*/
|
||||
static u32 convert_radiotap_rate_to_mv(u8 rate)
|
||||
{
|
||||
@ -51,12 +51,12 @@ static u32 convert_radiotap_rate_to_mv(u8 rate)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function checks the conditions and sends packet to IF
|
||||
* layer if everything is ok.
|
||||
* lbs_hard_start_xmit - checks the conditions and sends packet to IF
|
||||
* layer if everything is ok
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param skb A pointer to skb which includes TX packet
|
||||
* @return 0 or -1
|
||||
* @skb: A pointer to skb which includes TX packet
|
||||
* @dev: A pointer to the &struct net_device
|
||||
* returns: 0 or -1
|
||||
*/
|
||||
netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
@ -168,13 +168,13 @@ netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function sends to the host the last transmitted packet,
|
||||
* filling the radiotap headers with transmission information.
|
||||
* lbs_send_tx_feedback - sends to the host the last transmitted packet,
|
||||
* filling the radiotap headers with transmission information.
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param status A 32 bit value containing transmission status.
|
||||
* @priv: A pointer to &struct lbs_private structure
|
||||
* @try_count: A 32-bit value containing transmission retry status.
|
||||
*
|
||||
* @returns void
|
||||
* returns: void
|
||||
*/
|
||||
void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count)
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user