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

Merge branch 'master' of...

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

Conflicts:
	drivers/net/wireless/iwlwifi/iwl-testmode.c
...@@ -618,19 +618,10 @@ static void ar5008_hw_init_bb(struct ath_hw *ah, ...@@ -618,19 +618,10 @@ static void ar5008_hw_init_bb(struct ath_hw *ah,
u32 synthDelay; u32 synthDelay;
synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
if (IS_CHAN_B(chan))
synthDelay = (4 * synthDelay) / 22;
else
synthDelay /= 10;
if (IS_CHAN_HALF_RATE(chan))
synthDelay *= 2;
else if (IS_CHAN_QUARTER_RATE(chan))
synthDelay *= 4;
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
udelay(synthDelay + BASE_ACTIVATE_DELAY); ath9k_hw_synth_delay(ah, chan, synthDelay);
} }
static void ar5008_hw_init_chain_masks(struct ath_hw *ah) static void ar5008_hw_init_chain_masks(struct ath_hw *ah)
...@@ -948,12 +939,8 @@ static bool ar5008_hw_rfbus_req(struct ath_hw *ah) ...@@ -948,12 +939,8 @@ static bool ar5008_hw_rfbus_req(struct ath_hw *ah)
static void ar5008_hw_rfbus_done(struct ath_hw *ah) static void ar5008_hw_rfbus_done(struct ath_hw *ah)
{ {
u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
if (IS_CHAN_B(ah->curchan))
synthDelay = (4 * synthDelay) / 22;
else
synthDelay /= 10;
udelay(synthDelay + BASE_ACTIVATE_DELAY); ath9k_hw_synth_delay(ah, ah->curchan, synthDelay);
REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
} }
......
...@@ -1000,10 +1000,12 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, ...@@ -1000,10 +1000,12 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
if (mci && IS_CHAN_2GHZ(chan) && run_agc_cal) if (mci && IS_CHAN_2GHZ(chan) && run_agc_cal)
ar9003_mci_init_cal_req(ah, &is_reusable); ar9003_mci_init_cal_req(ah, &is_reusable);
if (!(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))) {
txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
udelay(5); udelay(5);
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
}
skip_tx_iqcal: skip_tx_iqcal:
if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
......
...@@ -4281,18 +4281,10 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) ...@@ -4281,18 +4281,10 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
#undef POW_SM #undef POW_SM
} }
static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq, static void ar9003_hw_get_legacy_target_powers(struct ath_hw *ah, u16 freq,
u8 *targetPowerValT2) u8 *targetPowerValT2,
bool is2GHz)
{ {
/* XXX: hard code for now, need to get from eeprom struct */
u8 ht40PowerIncForPdadc = 0;
bool is2GHz = false;
unsigned int i = 0;
struct ath_common *common = ath9k_hw_common(ah);
if (freq < 4000)
is2GHz = true;
targetPowerValT2[ALL_TARGET_LEGACY_6_24] = targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq, ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
is2GHz); is2GHz);
...@@ -4305,6 +4297,11 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq, ...@@ -4305,6 +4297,11 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq,
targetPowerValT2[ALL_TARGET_LEGACY_54] = targetPowerValT2[ALL_TARGET_LEGACY_54] =
ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq, ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
is2GHz); is2GHz);
}
static void ar9003_hw_get_cck_target_powers(struct ath_hw *ah, u16 freq,
u8 *targetPowerValT2)
{
targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] = targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L, ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
freq); freq);
...@@ -4314,6 +4311,11 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq, ...@@ -4314,6 +4311,11 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq,
ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq); ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
targetPowerValT2[ALL_TARGET_LEGACY_11S] = targetPowerValT2[ALL_TARGET_LEGACY_11S] =
ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq); ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
}
static void ar9003_hw_get_ht20_target_powers(struct ath_hw *ah, u16 freq,
u8 *targetPowerValT2, bool is2GHz)
{
targetPowerValT2[ALL_TARGET_HT20_0_8_16] = targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq, ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
is2GHz); is2GHz);
...@@ -4356,6 +4358,16 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq, ...@@ -4356,6 +4358,16 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq,
targetPowerValT2[ALL_TARGET_HT20_23] = targetPowerValT2[ALL_TARGET_HT20_23] =
ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq, ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
is2GHz); is2GHz);
}
static void ar9003_hw_get_ht40_target_powers(struct ath_hw *ah,
u16 freq,
u8 *targetPowerValT2,
bool is2GHz)
{
/* XXX: hard code for now, need to get from eeprom struct */
u8 ht40PowerIncForPdadc = 0;
targetPowerValT2[ALL_TARGET_HT40_0_8_16] = targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq, ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
is2GHz) + ht40PowerIncForPdadc; is2GHz) + ht40PowerIncForPdadc;
...@@ -4399,6 +4411,26 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq, ...@@ -4399,6 +4411,26 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq,
targetPowerValT2[ALL_TARGET_HT40_23] = targetPowerValT2[ALL_TARGET_HT40_23] =
ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq, ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
is2GHz) + ht40PowerIncForPdadc; is2GHz) + ht40PowerIncForPdadc;
}
static void ar9003_hw_get_target_power_eeprom(struct ath_hw *ah,
struct ath9k_channel *chan,
u8 *targetPowerValT2)
{
bool is2GHz = IS_CHAN_2GHZ(chan);
unsigned int i = 0;
struct ath_common *common = ath9k_hw_common(ah);
u16 freq = chan->channel;
if (is2GHz)
ar9003_hw_get_cck_target_powers(ah, freq, targetPowerValT2);
ar9003_hw_get_legacy_target_powers(ah, freq, targetPowerValT2, is2GHz);
ar9003_hw_get_ht20_target_powers(ah, freq, targetPowerValT2, is2GHz);
if (IS_CHAN_HT40(chan))
ar9003_hw_get_ht40_target_powers(ah, freq, targetPowerValT2,
is2GHz);
for (i = 0; i < ar9300RateSize; i++) { for (i = 0; i < ar9300RateSize; i++) {
ath_dbg(common, EEPROM, "TPC[%02d] 0x%08x\n", ath_dbg(common, EEPROM, "TPC[%02d] 0x%08x\n",
...@@ -4778,9 +4810,6 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah, ...@@ -4778,9 +4810,6 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit, scaledPower = ath9k_hw_get_scaled_power(ah, powerLimit,
antenna_reduction); antenna_reduction);
/*
* Get target powers from EEPROM - our baseline for TX Power
*/
if (is2ghz) { if (is2ghz) {
/* Setup for CTL modes */ /* Setup for CTL modes */
/* CTL_11B, CTL_11G, CTL_2GHT20 */ /* CTL_11B, CTL_11G, CTL_2GHT20 */
...@@ -4952,7 +4981,12 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, ...@@ -4952,7 +4981,12 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
unsigned int i = 0, paprd_scale_factor = 0; unsigned int i = 0, paprd_scale_factor = 0;
u8 pwr_idx, min_pwridx = 0; u8 pwr_idx, min_pwridx = 0;
ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2); memset(targetPowerValT2, 0 , sizeof(targetPowerValT2));
/*
* Get target powers from EEPROM - our baseline for TX Power
*/
ar9003_hw_get_target_power_eeprom(ah, chan, targetPowerValT2);
if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) { if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
if (IS_CHAN_2GHZ(chan)) if (IS_CHAN_2GHZ(chan))
......
...@@ -526,22 +526,10 @@ static void ar9003_hw_init_bb(struct ath_hw *ah, ...@@ -526,22 +526,10 @@ static void ar9003_hw_init_bb(struct ath_hw *ah,
* Value is in 100ns increments. * Value is in 100ns increments.
*/ */
synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
if (IS_CHAN_B(chan))
synthDelay = (4 * synthDelay) / 22;
else
synthDelay /= 10;
/* Activate the PHY (includes baseband activate + synthesizer on) */ /* Activate the PHY (includes baseband activate + synthesizer on) */
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
ath9k_hw_synth_delay(ah, chan, synthDelay);
/*
* There is an issue if the AP starts the calibration before
* the base band timeout completes. This could result in the
* rx_clear false triggering. As a workaround we add delay an
* extra BASE_ACTIVATE_DELAY usecs to ensure this condition
* does not happen.
*/
udelay(synthDelay + BASE_ACTIVATE_DELAY);
} }
static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
...@@ -723,6 +711,14 @@ static void ar9003_hw_set_rfmode(struct ath_hw *ah, ...@@ -723,6 +711,14 @@ static void ar9003_hw_set_rfmode(struct ath_hw *ah,
if (IS_CHAN_A_FAST_CLOCK(ah, chan)) if (IS_CHAN_A_FAST_CLOCK(ah, chan))
rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
if (IS_CHAN_QUARTER_RATE(chan))
rfMode |= AR_PHY_MODE_QUARTER;
if (IS_CHAN_HALF_RATE(chan))
rfMode |= AR_PHY_MODE_HALF;
if (rfMode & (AR_PHY_MODE_QUARTER | AR_PHY_MODE_HALF))
REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL,
AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW, 3);
REG_WRITE(ah, AR_PHY_MODE, rfMode); REG_WRITE(ah, AR_PHY_MODE, rfMode);
} }
...@@ -793,12 +789,8 @@ static bool ar9003_hw_rfbus_req(struct ath_hw *ah) ...@@ -793,12 +789,8 @@ static bool ar9003_hw_rfbus_req(struct ath_hw *ah)
static void ar9003_hw_rfbus_done(struct ath_hw *ah) static void ar9003_hw_rfbus_done(struct ath_hw *ah)
{ {
u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
if (IS_CHAN_B(ah->curchan))
synthDelay = (4 * synthDelay) / 22;
else
synthDelay /= 10;
udelay(synthDelay + BASE_ACTIVATE_DELAY); ath9k_hw_synth_delay(ah, ah->curchan, synthDelay);
REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
} }
......
...@@ -468,6 +468,9 @@ ...@@ -468,6 +468,9 @@
#define AR_PHY_ADDAC_PARA_CTL (AR_SM_BASE + 0x150) #define AR_PHY_ADDAC_PARA_CTL (AR_SM_BASE + 0x150)
#define AR_PHY_XPA_CFG (AR_SM_BASE + 0x158) #define AR_PHY_XPA_CFG (AR_SM_BASE + 0x158)
#define AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW 3
#define AR_PHY_FRAME_CTL_CF_OVERLAP_WINDOW_S 0
#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A 0x0001FC00 #define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A 0x0001FC00
#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_S 10 #define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_S 10
#define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A 0x3FF #define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A 0x3FF
......
...@@ -817,8 +817,10 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) ...@@ -817,8 +817,10 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status)
{ {
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
if (!ath_has_valid_bslot(sc)) if (!ath_has_valid_bslot(sc)) {
sc->sc_flags &= ~SC_OP_BEACONS;
return; return;
}
ath9k_ps_wakeup(sc); ath9k_ps_wakeup(sc);
if (status) { if (status) {
......
...@@ -108,9 +108,7 @@ void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah) ...@@ -108,9 +108,7 @@ void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah)
return; return;
} }
if (AR_SREV_9462(ah)) { if (AR_SREV_9300_20_OR_LATER(ah)) {
btcoex_hw->scheme = ATH_BTCOEX_CFG_MCI;
} else if (AR_SREV_9300_20_OR_LATER(ah)) {
btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300; btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300;
btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300; btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300;
...@@ -284,12 +282,13 @@ void ath9k_hw_btcoex_enable(struct ath_hw *ah) ...@@ -284,12 +282,13 @@ void ath9k_hw_btcoex_enable(struct ath_hw *ah)
ath9k_hw_btcoex_enable_2wire(ah); ath9k_hw_btcoex_enable_2wire(ah);
break; break;
case ATH_BTCOEX_CFG_3WIRE: case ATH_BTCOEX_CFG_3WIRE:
ath9k_hw_btcoex_enable_3wire(ah); if (AR_SREV_9462(ah)) {
break;
case ATH_BTCOEX_CFG_MCI:
ath9k_hw_btcoex_enable_mci(ah); ath9k_hw_btcoex_enable_mci(ah);
return; return;
} }
ath9k_hw_btcoex_enable_3wire(ah);
break;
}
REG_RMW(ah, AR_GPIO_PDPU, REG_RMW(ah, AR_GPIO_PDPU,
(0x2 << (btcoex_hw->btactive_gpio * 2)), (0x2 << (btcoex_hw->btactive_gpio * 2)),
...@@ -305,11 +304,12 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah) ...@@ -305,11 +304,12 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
int i; int i;
btcoex_hw->enabled = false; btcoex_hw->enabled = false;
if (btcoex_hw->scheme == ATH_BTCOEX_CFG_MCI) { if (AR_SREV_9462(ah)) {
ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++)
REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i), REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i),
btcoex_hw->wlan_weight[i]); btcoex_hw->wlan_weight[i]);
return;
} }
ath9k_hw_set_gpio(ah, btcoex_hw->wlanactive_gpio, 0); ath9k_hw_set_gpio(ah, btcoex_hw->wlanactive_gpio, 0);
......
...@@ -51,7 +51,6 @@ enum ath_btcoex_scheme { ...@@ -51,7 +51,6 @@ enum ath_btcoex_scheme {
ATH_BTCOEX_CFG_NONE, ATH_BTCOEX_CFG_NONE,
ATH_BTCOEX_CFG_2WIRE, ATH_BTCOEX_CFG_2WIRE,
ATH_BTCOEX_CFG_3WIRE, ATH_BTCOEX_CFG_3WIRE,
ATH_BTCOEX_CFG_MCI,
}; };
struct ath9k_hw_mci { struct ath9k_hw_mci {
......
...@@ -148,11 +148,13 @@ void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data, ...@@ -148,11 +148,13 @@ void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data,
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
DFS_STAT_INC(sc, pulses_total);
if ((rs->rs_phyerr != ATH9K_PHYERR_RADAR) && if ((rs->rs_phyerr != ATH9K_PHYERR_RADAR) &&
(rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT)) { (rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT)) {
ath_dbg(common, DFS, ath_dbg(common, DFS,
"Error: rs_phyer=0x%x not a radar error\n", "Error: rs_phyer=0x%x not a radar error\n",
rs->rs_phyerr); rs->rs_phyerr);
DFS_STAT_INC(sc, pulses_no_dfs);
return; return;
} }
...@@ -188,7 +190,9 @@ void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data, ...@@ -188,7 +190,9 @@ void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data,
"width=%d, rssi=%d, delta_ts=%llu\n", "width=%d, rssi=%d, delta_ts=%llu\n",
pe.freq, pe.ts, pe.width, pe.rssi, pe.ts-last_ts); pe.freq, pe.ts, pe.width, pe.rssi, pe.ts-last_ts);
last_ts = pe.ts; last_ts = pe.ts;
DFS_STAT_INC(sc, pulses_processed);
if (pd != NULL && pd->add_pulse(pd, &pe)) { if (pd != NULL && pd->add_pulse(pd, &pe)) {
DFS_STAT_INC(sc, radar_detected);
/* /*
* TODO: forward radar event to DFS management layer * TODO: forward radar event to DFS management layer
*/ */
......
...@@ -21,9 +21,15 @@ ...@@ -21,9 +21,15 @@
#include "ath9k.h" #include "ath9k.h"
#include "dfs_debug.h" #include "dfs_debug.h"
struct ath_dfs_pool_stats global_dfs_pool_stats = { 0 };
#define ATH9K_DFS_STAT(s, p) \ #define ATH9K_DFS_STAT(s, p) \
len += snprintf(buf + len, size - len, "%28s : %10u\n", s, \ len += snprintf(buf + len, size - len, "%28s : %10u\n", s, \
sc->debug.stats.dfs_stats.p); sc->debug.stats.dfs_stats.p);
#define ATH9K_DFS_POOL_STAT(s, p) \
len += snprintf(buf + len, size - len, "%28s : %10u\n", s, \
global_dfs_pool_stats.p);
static ssize_t read_file_dfs(struct file *file, char __user *user_buf, static ssize_t read_file_dfs(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
...@@ -43,6 +49,9 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf, ...@@ -43,6 +49,9 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf,
hw_ver->macVersion, hw_ver->macRev, hw_ver->macVersion, hw_ver->macRev,
(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_DFS) ? (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_DFS) ?
"enabled" : "disabled"); "enabled" : "disabled");
len += snprintf(buf + len, size - len, "Pulse detector statistics:\n");
ATH9K_DFS_STAT("pulse events reported ", pulses_total);
ATH9K_DFS_STAT("invalid pulse events ", pulses_no_dfs);
ATH9K_DFS_STAT("DFS pulses detected ", pulses_detected); ATH9K_DFS_STAT("DFS pulses detected ", pulses_detected);
ATH9K_DFS_STAT("Datalen discards ", datalen_discards); ATH9K_DFS_STAT("Datalen discards ", datalen_discards);
ATH9K_DFS_STAT("RSSI discards ", rssi_discards); ATH9K_DFS_STAT("RSSI discards ", rssi_discards);
...@@ -50,6 +59,18 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf, ...@@ -50,6 +59,18 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf,
ATH9K_DFS_STAT("Primary channel pulses ", pri_phy_errors); ATH9K_DFS_STAT("Primary channel pulses ", pri_phy_errors);
ATH9K_DFS_STAT("Secondary channel pulses", ext_phy_errors); ATH9K_DFS_STAT("Secondary channel pulses", ext_phy_errors);
ATH9K_DFS_STAT("Dual channel pulses ", dc_phy_errors); ATH9K_DFS_STAT("Dual channel pulses ", dc_phy_errors);
len += snprintf(buf + len, size - len, "Radar detector statistics "
"(current DFS region: %d)\n", sc->dfs_detector->region);
ATH9K_DFS_STAT("Pulse events processed ", pulses_processed);
ATH9K_DFS_STAT("Radars detected ", radar_detected);
len += snprintf(buf + len, size - len, "Global Pool statistics:\n");
ATH9K_DFS_POOL_STAT("Pool references ", pool_reference);
ATH9K_DFS_POOL_STAT("Pulses allocated ", pulse_allocated);
ATH9K_DFS_POOL_STAT("Pulses alloc error ", pulse_alloc_error);
ATH9K_DFS_POOL_STAT("Pulses in use ", pulse_used);
ATH9K_DFS_POOL_STAT("Seqs. allocated ", pseq_allocated);
ATH9K_DFS_POOL_STAT("Seqs. alloc error ", pseq_alloc_error);
ATH9K_DFS_POOL_STAT("Seqs. in use ", pseq_used);
if (len > size) if (len > size)
len = size; len = size;
...@@ -60,8 +81,33 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf, ...@@ -60,8 +81,33 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf,
return retval; return retval;
} }
/* magic number to prevent accidental reset of DFS statistics */
#define DFS_STATS_RESET_MAGIC 0x80000000
static ssize_t write_file_dfs(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
unsigned long val;
char buf[32];
ssize_t len;
len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len))
return -EFAULT;
buf[len] = '\0';
if (strict_strtoul(buf, 0, &val))
return -EINVAL;
if (val == DFS_STATS_RESET_MAGIC)
memset(&sc->debug.stats.dfs_stats, 0,
sizeof(sc->debug.stats.dfs_stats));
return count;
}
static const struct file_operations fops_dfs_stats = { static const struct file_operations fops_dfs_stats = {
.read = read_file_dfs, .read = read_file_dfs,
.write = write_file_dfs,
.open = simple_open, .open = simple_open,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.llseek = default_llseek, .llseek = default_llseek,
......
...@@ -22,17 +22,23 @@ ...@@ -22,17 +22,23 @@
#include "hw.h" #include "hw.h"
/** /**
* struct ath_dfs_stats - DFS Statistics * struct ath_dfs_stats - DFS Statistics per wiphy
* * @pulses_total: pulses reported by HW
* @pulses_detected: No. of pulses detected so far * @pulses_no_dfs: pulses wrongly reported as DFS
* @datalen_discards: No. of pulses discarded due to invalid datalen * @pulses_detected: pulses detected so far
* @rssi_discards: No. of pulses discarded due to invalid RSSI * @datalen_discards: pulses discarded due to invalid datalen
* @bwinfo_discards: No. of pulses discarded due to invalid BW info * @rssi_discards: pulses discarded due to invalid RSSI
* @pri_phy_errors: No. of pulses reported for primary channel * @bwinfo_discards: pulses discarded due to invalid BW info
* @ext_phy_errors: No. of pulses reported for extension channel * @pri_phy_errors: pulses reported for primary channel
* @dc_phy_errors: No. of pulses reported for primary + extension channel * @ext_phy_errors: pulses reported for extension channel
* @dc_phy_errors: pulses reported for primary + extension channel
* @pulses_processed: pulses forwarded to detector
* @radar_detected: radars detected
*/ */
struct ath_dfs_stats { struct ath_dfs_stats {
/* pulse stats */
u32 pulses_total;
u32 pulses_no_dfs;
u32 pulses_detected; u32 pulses_detected;
u32 datalen_discards; u32 datalen_discards;
u32 rssi_discards; u32 rssi_discards;
...@@ -40,18 +46,39 @@ struct ath_dfs_stats { ...@@ -40,18 +46,39 @@ struct ath_dfs_stats {
u32 pri_phy_errors; u32 pri_phy_errors;
u32 ext_phy_errors; u32 ext_phy_errors;
u32 dc_phy_errors; u32 dc_phy_errors;
/* pattern detection stats */
u32 pulses_processed;
u32 radar_detected;
}; };
/**
* struct ath_dfs_pool_stats - DFS Statistics for global pools
*/
struct ath_dfs_pool_stats {
u32 pool_reference;
u32 pulse_allocated;
u32 pulse_alloc_error;
u32 pulse_used;
u32 pseq_allocated;
u32 pseq_alloc_error;
u32 pseq_used;
};
#if defined(CONFIG_ATH9K_DFS_DEBUGFS) #if defined(CONFIG_ATH9K_DFS_DEBUGFS)
#define DFS_STAT_INC(sc, c) (sc->debug.stats.dfs_stats.c++) #define DFS_STAT_INC(sc, c) (sc->debug.stats.dfs_stats.c++)
void ath9k_dfs_init_debug(struct ath_softc *sc); void ath9k_dfs_init_debug(struct ath_softc *sc);
#define DFS_POOL_STAT_INC(c) (global_dfs_pool_stats.c++)
#define DFS_POOL_STAT_DEC(c) (global_dfs_pool_stats.c--)
extern struct ath_dfs_pool_stats global_dfs_pool_stats;
#else #else
#define DFS_STAT_INC(sc, c) do { } while (0) #define DFS_STAT_INC(sc, c) do { } while (0)
static inline void ath9k_dfs_init_debug(struct ath_softc *sc) { } static inline void ath9k_dfs_init_debug(struct ath_softc *sc) { }
#define DFS_POOL_STAT_INC(c) do { } while (0)
#define DFS_POOL_STAT_DEC(c) do { } while (0)
#endif /* CONFIG_ATH9K_DFS_DEBUGFS */ #endif /* CONFIG_ATH9K_DFS_DEBUGFS */
#endif /* ATH9K_DFS_DEBUG_H */ #endif /* ATH9K_DFS_DEBUG_H */
...@@ -15,9 +15,12 @@ ...@@ -15,9 +15,12 @@
*/ */
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h>
#include "ath9k.h"
#include "dfs_pattern_detector.h" #include "dfs_pattern_detector.h"
#include "dfs_pri_detector.h" #include "dfs_pri_detector.h"
#include "dfs_debug.h"
/** /**
* struct pri_sequence - sequence of pulses matching one PRI * struct pri_sequence - sequence of pulses matching one PRI
...@@ -94,6 +97,81 @@ static u32 pde_get_multiple(u32 val, u32 fraction, u32 tolerance) ...@@ -94,6 +97,81 @@ static u32 pde_get_multiple(u32 val, u32 fraction, u32 tolerance)
static u32 singleton_pool_references; static u32 singleton_pool_references;
static LIST_HEAD(pulse_pool); static LIST_HEAD(pulse_pool);
static LIST_HEAD(pseq_pool); static LIST_HEAD(pseq_pool);
static DEFINE_SPINLOCK(pool_lock);
static void pool_register_ref(void)
{
spin_lock_bh(&pool_lock);
singleton_pool_references++;
DFS_POOL_STAT_INC(pool_reference);
spin_unlock_bh(&pool_lock);
}
static void pool_deregister_ref(void)
{
spin_lock_bh(&pool_lock);
singleton_pool_references--;
DFS_POOL_STAT_DEC(pool_reference);
if (singleton_pool_references == 0) {
/* free singleton pools with no references left */
struct pri_sequence *ps, *ps0;
struct pulse_elem *p, *p0;
list_for_each_entry_safe(p, p0, &pulse_pool, head) {
list_del(&p->head);
DFS_POOL_STAT_DEC(pulse_allocated);
kfree(p);
}
list_for_each_entry_safe(ps, ps0, &pseq_pool, head) {
list_del(&ps->head);
DFS_POOL_STAT_DEC(pseq_allocated);
kfree(ps);
}
}
spin_unlock_bh(&pool_lock);
}
static void pool_put_pulse_elem(struct pulse_elem *pe)
{
spin_lock_bh(&pool_lock);
list_add(&pe->head, &pulse_pool);
DFS_POOL_STAT_DEC(pulse_used);
spin_unlock_bh(&pool_lock);
}
static void pool_put_pseq_elem(struct pri_sequence *pse)
{
spin_lock_bh(&pool_lock);
list_add(&pse->head, &pseq_pool);
DFS_POOL_STAT_DEC(pseq_used);
spin_unlock_bh(&pool_lock);
}
static struct pri_sequence *pool_get_pseq_elem(void)
{
struct pri_sequence *pse = NULL;
spin_lock_bh(&pool_lock);
if (!list_empty(&pseq_pool)) {
pse = list_first_entry(&pseq_pool, struct pri_sequence, head);
list_del(&pse->head);
DFS_POOL_STAT_INC(pseq_used);
}
spin_unlock_bh(&pool_lock);
return pse;
}
static struct pulse_elem *pool_get_pulse_elem(void)
{
struct pulse_elem *pe = NULL;
spin_lock_bh(&pool_lock);
if (!list_empty(&pulse_pool)) {
pe = list_first_entry(&pulse_pool, struct pulse_elem, head);
list_del(&pe->head);
DFS_POOL_STAT_INC(pulse_used);
}
spin_unlock_bh(&pool_lock);
return pe;
}
static struct pulse_elem *pulse_queue_get_tail(struct pri_detector *pde) static struct pulse_elem *pulse_queue_get_tail(struct pri_detector *pde)
{ {
...@@ -110,7 +188,7 @@ static bool pulse_queue_dequeue(struct pri_detector *pde) ...@@ -110,7 +188,7 @@ static bool pulse_queue_dequeue(struct pri_detector *pde)
list_del_init(&p->head); list_del_init(&p->head);
pde->count--; pde->count--;
/* give it back to pool */ /* give it back to pool */
list_add(&p->head, &pulse_pool); pool_put_pulse_elem(p);
} }
return (pde->count > 0); return (pde->count > 0);
} }
...@@ -138,16 +216,15 @@ static void pulse_queue_check_window(struct pri_detector *pde) ...@@ -138,16 +216,15 @@ static void pulse_queue_check_window(struct pri_detector *pde)
static bool pulse_queue_enqueue(struct pri_detector *pde, u64 ts) static bool pulse_queue_enqueue(struct pri_detector *pde, u64 ts)
{ {
struct pulse_elem *p; struct pulse_elem *p = pool_get_pulse_elem();
if (!list_empty(&pulse_pool)) { if (p == NULL) {
p = list_first_entry(&pulse_pool, struct pulse_elem, head);
list_del(&p->head);
} else {
p = kmalloc(sizeof(*p), GFP_KERNEL); p = kmalloc(sizeof(*p), GFP_KERNEL);
if (p == NULL) { if (p == NULL) {
pr_err("failed to allocate pulse_elem\n"); DFS_POOL_STAT_INC(pulse_alloc_error);
return false; return false;
} }
DFS_POOL_STAT_INC(pulse_allocated);
DFS_POOL_STAT_INC(pulse_used);
} }
INIT_LIST_HEAD(&p->head); INIT_LIST_HEAD(&p->head);
p->ts = ts; p->ts = ts;
...@@ -220,16 +297,16 @@ static bool pseq_handler_create_sequences(struct pri_detector *pde, ...@@ -220,16 +297,16 @@ static bool pseq_handler_create_sequences(struct pri_detector *pde,
/* this is a valid one, add it */ /* this is a valid one, add it */
ps.deadline_ts = ps.first_ts + ps.dur; ps.deadline_ts = ps.first_ts + ps.dur;
new_ps = pool_get_pseq_elem();
if (!list_empty(&pseq_pool)) { if (new_ps == NULL) {
new_ps = list_first_entry(&pseq_pool,
struct pri_sequence, head);
list_del(&new_ps->head);
} else {
new_ps = kmalloc(sizeof(*new_ps), GFP_KERNEL); new_ps = kmalloc(sizeof(*new_ps), GFP_KERNEL);
if (new_ps == NULL) if (new_ps == NULL) {
DFS_POOL_STAT_INC(pseq_alloc_error);
return false; return false;
} }
DFS_POOL_STAT_INC(pseq_allocated);
DFS_POOL_STAT_INC(pseq_used);
}
memcpy(new_ps, &ps, sizeof(ps)); memcpy(new_ps, &ps, sizeof(ps));
INIT_LIST_HEAD(&new_ps->head); INIT_LIST_HEAD(&new_ps->head);
list_add(&new_ps->head, &pde->sequences); list_add(&new_ps->head, &pde->sequences);
...@@ -250,7 +327,7 @@ pseq_handler_add_to_existing_seqs(struct pri_detector *pde, u64 ts) ...@@ -250,7 +327,7 @@ pseq_handler_add_to_existing_seqs(struct pri_detector *pde, u64 ts)
/* first ensure that sequence is within window */ /* first ensure that sequence is within window */
if (ts > ps->deadline_ts) { if (ts > ps->deadline_ts) {
list_del_init(&ps->head); list_del_init(&ps->head);
list_add(&ps->head, &pseq_pool); pool_put_pseq_elem(ps);
continue; continue;
} }
...@@ -299,11 +376,11 @@ static void pri_detector_reset(struct pri_detector *pde, u64 ts) ...@@ -299,11 +376,11 @@ static void pri_detector_reset(struct pri_detector *pde, u64 ts)
struct pulse_elem *p, *p0; struct pulse_elem *p, *p0;
list_for_each_entry_safe(ps, ps0, &pde->sequences, head) { list_for_each_entry_safe(ps, ps0, &pde->sequences, head) {
list_del_init(&ps->head); list_del_init(&ps->head);
list_add(&ps->head, &pseq_pool); pool_put_pseq_elem(ps);
} }
list_for_each_entry_safe(p, p0, &pde->pulses, head) { list_for_each_entry_safe(p, p0, &pde->pulses, head) {
list_del_init(&p->head); list_del_init(&p->head);
list_add(&p->head, &pulse_pool); pool_put_pulse_elem(p);
} }
pde->count = 0; pde->count = 0;
pde->last_ts = ts; pde->last_ts = ts;
...@@ -312,22 +389,7 @@ static void pri_detector_reset(struct pri_detector *pde, u64 ts) ...@@ -312,22 +389,7 @@ static void pri_detector_reset(struct pri_detector *pde, u64 ts)
static void pri_detector_exit(struct pri_detector *de) static void pri_detector_exit(struct pri_detector *de)
{ {
pri_detector_reset(de, 0); pri_detector_reset(de, 0);
pool_deregister_ref();
singleton_pool_references--;
if (singleton_pool_references == 0) {
/* free singleton pools with no references left */
struct pri_sequence *ps, *ps0;
struct pulse_elem *p, *p0;
list_for_each_entry_safe(p, p0, &pulse_pool, head) {
list_del(&p->head);
kfree(p);
}
list_for_each_entry_safe(ps, ps0, &pseq_pool, head) {
list_del(&ps->head);
kfree(ps);
}
}
kfree(de); kfree(de);
} }
...@@ -385,6 +447,6 @@ pri_detector_init(const struct radar_detector_specs *rs) ...@@ -385,6 +447,6 @@ pri_detector_init(const struct radar_detector_specs *rs)
de->max_count = rs->ppb * 2; de->max_count = rs->ppb * 2;
de->rs = rs; de->rs = rs;
singleton_pool_references++; pool_register_ref();
return de; return de;
} }
...@@ -365,7 +365,7 @@ void ath9k_stop_btcoex(struct ath_softc *sc) ...@@ -365,7 +365,7 @@ void ath9k_stop_btcoex(struct ath_softc *sc)
ath9k_hw_btcoex_disable(ah); ath9k_hw_btcoex_disable(ah);
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE)
ath9k_btcoex_timer_pause(sc); ath9k_btcoex_timer_pause(sc);
if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_MCI) if (AR_SREV_9462(ah))
ath_mci_flush_profile(&sc->btcoex.mci); ath_mci_flush_profile(&sc->btcoex.mci);
} }
} }
...@@ -376,7 +376,7 @@ void ath9k_deinit_btcoex(struct ath_softc *sc) ...@@ -376,7 +376,7 @@ void ath9k_deinit_btcoex(struct ath_softc *sc)
ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE) ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_3WIRE)
ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
if (ath9k_hw_get_btcoex_scheme(sc->sc_ah) == ATH_BTCOEX_CFG_MCI) if (AR_SREV_9462(sc->sc_ah))
ath_mci_cleanup(sc); ath_mci_cleanup(sc);
} }
...@@ -402,9 +402,7 @@ int ath9k_init_btcoex(struct ath_softc *sc) ...@@ -402,9 +402,7 @@ int ath9k_init_btcoex(struct ath_softc *sc)
txq = sc->tx.txq_map[WME_AC_BE]; txq = sc->tx.txq_map[WME_AC_BE];
ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
break; if (AR_SREV_9462(ah)) {
case ATH_BTCOEX_CFG_MCI:
sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
INIT_LIST_HEAD(&sc->btcoex.mci.info); INIT_LIST_HEAD(&sc->btcoex.mci.info);
...@@ -413,6 +411,7 @@ int ath9k_init_btcoex(struct ath_softc *sc) ...@@ -413,6 +411,7 @@ int ath9k_init_btcoex(struct ath_softc *sc)
return r; return r;
ath9k_hw_btcoex_init_mci(ah); ath9k_hw_btcoex_init_mci(ah);
}
break; break;
default: default:
......
...@@ -191,6 +191,22 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout) ...@@ -191,6 +191,22 @@ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
} }
EXPORT_SYMBOL(ath9k_hw_wait); EXPORT_SYMBOL(ath9k_hw_wait);
void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan,
int hw_delay)
{
if (IS_CHAN_B(chan))
hw_delay = (4 * hw_delay) / 22;
else
hw_delay /= 10;
if (IS_CHAN_HALF_RATE(chan))
hw_delay *= 2;
else if (IS_CHAN_QUARTER_RATE(chan))
hw_delay *= 4;
udelay(hw_delay + BASE_ACTIVATE_DELAY);
}
void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array, void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array,
int column, unsigned int *writecnt) int column, unsigned int *writecnt)
{ {
...@@ -1020,7 +1036,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) ...@@ -1020,7 +1036,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &common->hw->conf; struct ieee80211_conf *conf = &common->hw->conf;
const struct ath9k_channel *chan = ah->curchan; const struct ath9k_channel *chan = ah->curchan;
int acktimeout, ctstimeout; int acktimeout, ctstimeout, ack_offset = 0;
int slottime; int slottime;
int sifstime; int sifstime;
int rx_lat = 0, tx_lat = 0, eifs = 0; int rx_lat = 0, tx_lat = 0, eifs = 0;
...@@ -1041,6 +1057,11 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) ...@@ -1041,6 +1057,11 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
rx_lat = 37; rx_lat = 37;
tx_lat = 54; tx_lat = 54;
if (IS_CHAN_5GHZ(chan))
sifstime = 16;
else
sifstime = 10;
if (IS_CHAN_HALF_RATE(chan)) { if (IS_CHAN_HALF_RATE(chan)) {
eifs = 175; eifs = 175;
rx_lat *= 2; rx_lat *= 2;
...@@ -1048,8 +1069,9 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) ...@@ -1048,8 +1069,9 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
if (IS_CHAN_A_FAST_CLOCK(ah, chan)) if (IS_CHAN_A_FAST_CLOCK(ah, chan))
tx_lat += 11; tx_lat += 11;
sifstime *= 2;
ack_offset = 16;
slottime = 13; slottime = 13;
sifstime = 32;
} else if (IS_CHAN_QUARTER_RATE(chan)) { } else if (IS_CHAN_QUARTER_RATE(chan)) {
eifs = 340; eifs = 340;
rx_lat = (rx_lat * 4) - 1; rx_lat = (rx_lat * 4) - 1;
...@@ -1057,8 +1079,9 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) ...@@ -1057,8 +1079,9 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
if (IS_CHAN_A_FAST_CLOCK(ah, chan)) if (IS_CHAN_A_FAST_CLOCK(ah, chan))
tx_lat += 22; tx_lat += 22;
sifstime *= 4;
ack_offset = 32;
slottime = 21; slottime = 21;
sifstime = 64;
} else { } else {
if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) { if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) {
eifs = AR_D_GBL_IFS_EIFS_ASYNC_FIFO; eifs = AR_D_GBL_IFS_EIFS_ASYNC_FIFO;
...@@ -1072,14 +1095,10 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) ...@@ -1072,14 +1095,10 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
tx_lat = MS(reg, AR_USEC_TX_LAT); tx_lat = MS(reg, AR_USEC_TX_LAT);
slottime = ah->slottime; slottime = ah->slottime;
if (IS_CHAN_5GHZ(chan))
sifstime = 16;
else
sifstime = 10;
} }
/* As defined by IEEE 802.11-2007 17.3.8.6 */ /* As defined by IEEE 802.11-2007 17.3.8.6 */
acktimeout = slottime + sifstime + 3 * ah->coverage_class; acktimeout = slottime + sifstime + 3 * ah->coverage_class + ack_offset;
ctstimeout = acktimeout; ctstimeout = acktimeout;
/* /*
...@@ -1089,7 +1108,8 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) ...@@ -1089,7 +1108,8 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
* BA frames in some implementations, but it has been found to fix ACK * BA frames in some implementations, but it has been found to fix ACK
* timeout issues in other cases as well. * timeout issues in other cases as well.
*/ */
if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ) { if (conf->channel && conf->channel->band == IEEE80211_BAND_2GHZ &&
!IS_CHAN_HALF_RATE(chan) && !IS_CHAN_QUARTER_RATE(chan)) {
acktimeout += 64 - sifstime - ah->slottime; acktimeout += 64 - sifstime - ah->slottime;
ctstimeout += 48 - sifstime - ah->slottime; ctstimeout += 48 - sifstime - ah->slottime;
} }
...@@ -1667,6 +1687,10 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) ...@@ -1667,6 +1687,10 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan)
if (chan->channel == ah->curchan->channel) if (chan->channel == ah->curchan->channel)
goto fail; goto fail;
if ((ah->curchan->channelFlags | chan->channelFlags) &
(CHANNEL_HALF | CHANNEL_QUARTER))
goto fail;
if ((chan->channelFlags & CHANNEL_ALL) != if ((chan->channelFlags & CHANNEL_ALL) !=
(ah->curchan->channelFlags & CHANNEL_ALL)) (ah->curchan->channelFlags & CHANNEL_ALL))
goto fail; goto fail;
......
...@@ -923,6 +923,8 @@ void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); ...@@ -923,6 +923,8 @@ void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
/* General Operation */ /* General Operation */
void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan,
int hw_delay);
bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array, void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array,
int column, unsigned int *writecnt); int column, unsigned int *writecnt);
...@@ -959,7 +961,8 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); ...@@ -959,7 +961,8 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
#ifdef CONFIG_ATH9K_DEBUGFS #ifdef CONFIG_ATH9K_DEBUGFS
void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause); void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause);
#else #else
static void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause) {} static inline void ath9k_debug_sync_cause(struct ath_common *common,
u32 sync_cause) {}
#endif #endif
/* Generic hw timer primitives */ /* Generic hw timer primitives */
......
...@@ -646,6 +646,24 @@ void ath9k_reload_chainmask_settings(struct ath_softc *sc) ...@@ -646,6 +646,24 @@ void ath9k_reload_chainmask_settings(struct ath_softc *sc)
setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
} }
static const struct ieee80211_iface_limit if_limits[] = {
{ .max = 2048, .types = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_WDS) },
{ .max = 8, .types =
#ifdef CONFIG_MAC80211_MESH
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_P2P_GO) },
};
static const struct ieee80211_iface_combination if_comb = {
.limits = if_limits,
.n_limits = ARRAY_SIZE(if_limits),
.max_interfaces = 2048,
.num_different_channels = 1,
};
void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
{ {
...@@ -675,6 +693,9 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) ...@@ -675,6 +693,9 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_MESH_POINT); BIT(NL80211_IFTYPE_MESH_POINT);
hw->wiphy->iface_combinations = &if_comb;
hw->wiphy->n_iface_combinations = 1;
if (AR_SREV_5416(sc->sc_ah)) if (AR_SREV_5416(sc->sc_ah))
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
......
...@@ -133,8 +133,16 @@ EXPORT_SYMBOL(ath9k_hw_updatetxtriglevel); ...@@ -133,8 +133,16 @@ EXPORT_SYMBOL(ath9k_hw_updatetxtriglevel);
void ath9k_hw_abort_tx_dma(struct ath_hw *ah) void ath9k_hw_abort_tx_dma(struct ath_hw *ah)
{ {
int maxdelay = 1000;
int i, q; int i, q;
if (ah->curchan) {
if (IS_CHAN_HALF_RATE(ah->curchan))
maxdelay *= 2;
else if (IS_CHAN_QUARTER_RATE(ah->curchan))
maxdelay *= 4;
}
REG_WRITE(ah, AR_Q_TXD, AR_Q_TXD_M); REG_WRITE(ah, AR_Q_TXD, AR_Q_TXD_M);
REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF); REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF);
...@@ -142,7 +150,7 @@ void ath9k_hw_abort_tx_dma(struct ath_hw *ah) ...@@ -142,7 +150,7 @@ void ath9k_hw_abort_tx_dma(struct ath_hw *ah)
REG_SET_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF); REG_SET_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
for (q = 0; q < AR_NUM_QCU; q++) { for (q = 0; q < AR_NUM_QCU; q++) {
for (i = 0; i < 1000; i++) { for (i = 0; i < maxdelay; i++) {
if (i) if (i)
udelay(5); udelay(5);
......
...@@ -113,21 +113,25 @@ void ath9k_ps_restore(struct ath_softc *sc) ...@@ -113,21 +113,25 @@ void ath9k_ps_restore(struct ath_softc *sc)
struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_common *common = ath9k_hw_common(sc->sc_ah);
enum ath9k_power_mode mode; enum ath9k_power_mode mode;
unsigned long flags; unsigned long flags;
bool reset;
spin_lock_irqsave(&sc->sc_pm_lock, flags); spin_lock_irqsave(&sc->sc_pm_lock, flags);
if (--sc->ps_usecount != 0) if (--sc->ps_usecount != 0)
goto unlock; goto unlock;
if (sc->ps_idle && (sc->ps_flags & PS_WAIT_FOR_TX_ACK)) if (sc->ps_idle) {
ath9k_hw_setrxabort(sc->sc_ah, 1);
ath9k_hw_stopdmarecv(sc->sc_ah, &reset);
mode = ATH9K_PM_FULL_SLEEP; mode = ATH9K_PM_FULL_SLEEP;
else if (sc->ps_enabled && } else if (sc->ps_enabled &&
!(sc->ps_flags & (PS_WAIT_FOR_BEACON | !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
PS_WAIT_FOR_CAB | PS_WAIT_FOR_CAB |
PS_WAIT_FOR_PSPOLL_DATA | PS_WAIT_FOR_PSPOLL_DATA |
PS_WAIT_FOR_TX_ACK))) PS_WAIT_FOR_TX_ACK))) {
mode = ATH9K_PM_NETWORK_SLEEP; mode = ATH9K_PM_NETWORK_SLEEP;
else } else {
goto unlock; goto unlock;
}
spin_lock(&common->cc_lock); spin_lock(&common->cc_lock);
ath_hw_cycle_counters_update(common); ath_hw_cycle_counters_update(common);
...@@ -1100,14 +1104,7 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -1100,14 +1104,7 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
} }
} }
/* if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_NETWORK_SLEEP)) {
* Cannot tx while the hardware is in full sleep, it first needs a full
* chip reset to recover from that
*/
if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_FULL_SLEEP))
goto exit;
if (unlikely(sc->sc_ah->power_mode != ATH9K_PM_AWAKE)) {
/* /*
* We are using PS-Poll and mac80211 can request TX while in * We are using PS-Poll and mac80211 can request TX while in
* power save mode. Need to wake up hardware for the TX to be * power save mode. Need to wake up hardware for the TX to be
...@@ -1126,12 +1123,21 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -1126,12 +1123,21 @@ static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
} }
/* /*
* The actual restore operation will happen only after * The actual restore operation will happen only after
* the sc_flags bit is cleared. We are just dropping * the ps_flags bit is cleared. We are just dropping
* the ps_usecount here. * the ps_usecount here.
*/ */
ath9k_ps_restore(sc); ath9k_ps_restore(sc);
} }
/*
* Cannot tx while the hardware is in full sleep, it first needs a full
* chip reset to recover from that
*/
if (unlikely(sc->sc_ah->power_mode == ATH9K_PM_FULL_SLEEP)) {
ath_err(common, "TX while HW is in FULL_SLEEP mode\n");
goto exit;
}
memset(&txctl, 0, sizeof(struct ath_tx_control)); memset(&txctl, 0, sizeof(struct ath_tx_control));
txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)]; txctl.txq = sc->tx.txq_map[skb_get_queue_mapping(skb)];
...@@ -1245,7 +1251,6 @@ static void ath9k_reclaim_beacon(struct ath_softc *sc, ...@@ -1245,7 +1251,6 @@ static void ath9k_reclaim_beacon(struct ath_softc *sc,
ath9k_set_beaconing_status(sc, false); ath9k_set_beaconing_status(sc, false);
ath_beacon_return(sc, avp); ath_beacon_return(sc, avp);
ath9k_set_beaconing_status(sc, true); ath9k_set_beaconing_status(sc, true);
sc->sc_flags &= ~SC_OP_BEACONS;
} }
static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
...@@ -1376,17 +1381,9 @@ static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, ...@@ -1376,17 +1381,9 @@ static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw,
ath9k_calculate_summary_state(hw, vif); ath9k_calculate_summary_state(hw, vif);
if (ath9k_uses_beacons(vif->type)) { if (ath9k_uses_beacons(vif->type)) {
int error; /* Reserve a beacon slot for the vif */
/* This may fail because upper levels do not have beacons
* properly configured yet. That's OK, we assume it
* will be properly configured and then we will be notified
* in the info_changed method and set up beacons properly
* there.
*/
ath9k_set_beaconing_status(sc, false); ath9k_set_beaconing_status(sc, false);
error = ath_beacon_alloc(sc, vif); ath_beacon_alloc(sc, vif);
if (!error)
ath_beacon_config(sc, vif);
ath9k_set_beaconing_status(sc, true); ath9k_set_beaconing_status(sc, true);
} }
} }
...@@ -1537,6 +1534,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, ...@@ -1537,6 +1534,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
static void ath9k_enable_ps(struct ath_softc *sc) static void ath9k_enable_ps(struct ath_softc *sc)
{ {
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
sc->ps_enabled = true; sc->ps_enabled = true;
if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
...@@ -1546,11 +1544,13 @@ static void ath9k_enable_ps(struct ath_softc *sc) ...@@ -1546,11 +1544,13 @@ static void ath9k_enable_ps(struct ath_softc *sc)
} }
ath9k_hw_setrxabort(ah, 1); ath9k_hw_setrxabort(ah, 1);
} }
ath_dbg(common, PS, "PowerSave enabled\n");
} }
static void ath9k_disable_ps(struct ath_softc *sc) static void ath9k_disable_ps(struct ath_softc *sc)
{ {
struct ath_hw *ah = sc->sc_ah; struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
sc->ps_enabled = false; sc->ps_enabled = false;
ath9k_hw_setpower(ah, ATH9K_PM_AWAKE); ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
...@@ -1565,7 +1565,7 @@ static void ath9k_disable_ps(struct ath_softc *sc) ...@@ -1565,7 +1565,7 @@ static void ath9k_disable_ps(struct ath_softc *sc)
ath9k_hw_set_interrupts(ah); ath9k_hw_set_interrupts(ah);
} }
} }
ath_dbg(common, PS, "PowerSave disabled\n");
} }
static int ath9k_config(struct ieee80211_hw *hw, u32 changed) static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
...@@ -1993,7 +1993,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ...@@ -1993,7 +1993,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ath_vif *avp = (void *)vif->drv_priv; struct ath_vif *avp = (void *)vif->drv_priv;
int slottime; int slottime;
int error;
ath9k_ps_wakeup(sc); ath9k_ps_wakeup(sc);
mutex_lock(&sc->mutex); mutex_lock(&sc->mutex);
...@@ -2026,12 +2025,24 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ...@@ -2026,12 +2025,24 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
} }
} }
/* Enable transmission of beacons (AP, IBSS, MESH) */ /*
if ((changed & BSS_CHANGED_BEACON) || * In case of AP mode, the HW TSF has to be reset
((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { * when the beacon interval changes.
*/
if ((changed & BSS_CHANGED_BEACON_INT) &&
(vif->type == NL80211_IFTYPE_AP))
sc->sc_flags |= SC_OP_TSF_RESET;
/* Configure beaconing (AP, IBSS, MESH) */
if (ath9k_uses_beacons(vif->type) &&
((changed & BSS_CHANGED_BEACON) ||
(changed & BSS_CHANGED_BEACON_ENABLED) ||
(changed & BSS_CHANGED_BEACON_INT))) {
ath9k_set_beaconing_status(sc, false); ath9k_set_beaconing_status(sc, false);
error = ath_beacon_alloc(sc, vif); if (bss_conf->enable_beacon)
if (!error) ath_beacon_alloc(sc, vif);
else
avp->is_bslot_active = false;
ath_beacon_config(sc, vif); ath_beacon_config(sc, vif);
ath9k_set_beaconing_status(sc, true); ath9k_set_beaconing_status(sc, true);
} }
...@@ -2055,30 +2066,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ...@@ -2055,30 +2066,6 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
} }
} }
/* Disable transmission of beacons */
if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
!bss_conf->enable_beacon) {
ath9k_set_beaconing_status(sc, false);
avp->is_bslot_active = false;
ath9k_set_beaconing_status(sc, true);
}
if (changed & BSS_CHANGED_BEACON_INT) {
/*
* In case of AP mode, the HW TSF has to be reset
* when the beacon interval changes.
*/
if (vif->type == NL80211_IFTYPE_AP) {
sc->sc_flags |= SC_OP_TSF_RESET;
ath9k_set_beaconing_status(sc, false);
error = ath_beacon_alloc(sc, vif);
if (!error)
ath_beacon_config(sc, vif);
ath9k_set_beaconing_status(sc, true);
} else
ath_beacon_config(sc, vif);
}
mutex_unlock(&sc->mutex); mutex_unlock(&sc->mutex);
ath9k_ps_restore(sc); ath9k_ps_restore(sc);
} }
......
...@@ -812,6 +812,7 @@ static bool ath9k_rx_accept(struct ath_common *common, ...@@ -812,6 +812,7 @@ static bool ath9k_rx_accept(struct ath_common *common,
is_valid_tkip = rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && is_valid_tkip = rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID &&
test_bit(rx_stats->rs_keyix, common->tkip_keymap); test_bit(rx_stats->rs_keyix, common->tkip_keymap);
strip_mic = is_valid_tkip && ieee80211_is_data(fc) && strip_mic = is_valid_tkip && ieee80211_is_data(fc) &&
ieee80211_has_protected(fc) &&
!(rx_stats->rs_status & !(rx_stats->rs_status &
(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC | (ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC |
ATH9K_RXERR_KEYMISS)); ATH9K_RXERR_KEYMISS));
...@@ -907,7 +908,7 @@ static int ath9k_process_rate(struct ath_common *common, ...@@ -907,7 +908,7 @@ static int ath9k_process_rate(struct ath_common *common,
struct ieee80211_supported_band *sband; struct ieee80211_supported_band *sband;
enum ieee80211_band band; enum ieee80211_band band;
unsigned int i = 0; unsigned int i = 0;
struct ath_softc *sc = (struct ath_softc *) common->priv; struct ath_softc __maybe_unused *sc = common->priv;
band = hw->conf.channel->band; band = hw->conf.channel->band;
sband = hw->wiphy->bands[band]; sband = hw->wiphy->bands[band];
......
...@@ -5,7 +5,7 @@ iwlwifi-objs += iwl-ucode.o iwl-agn-tx.o iwl-debug.o ...@@ -5,7 +5,7 @@ iwlwifi-objs += iwl-ucode.o iwl-agn-tx.o iwl-debug.o
iwlwifi-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o iwlwifi-objs += iwl-agn-lib.o iwl-agn-calib.o iwl-io.o
iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o iwlwifi-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-rx.o
iwlwifi-objs += iwl-core.o iwl-eeprom.o iwl-power.o iwlwifi-objs += iwl-eeprom.o iwl-power.o
iwlwifi-objs += iwl-scan.o iwl-led.o iwlwifi-objs += iwl-scan.o iwl-led.o
iwlwifi-objs += iwl-agn-rxon.o iwl-agn-devices.o iwlwifi-objs += iwl-agn-rxon.o iwl-agn-devices.o
iwlwifi-objs += iwl-5000.o iwlwifi-objs += iwl-5000.o
......
...@@ -28,7 +28,8 @@ ...@@ -28,7 +28,8 @@
#include <linux/stringify.h> #include <linux/stringify.h>
#include "iwl-config.h" #include "iwl-config.h"
#include "iwl-cfg.h" #include "iwl-cfg.h"
#include "iwl-dev.h" /* still needed */ #include "iwl-csr.h"
#include "iwl-agn-hw.h"
/* Highest firmware API version supported */ /* Highest firmware API version supported */
#define IWL1000_UCODE_API_MAX 6 #define IWL1000_UCODE_API_MAX 6
...@@ -42,6 +43,10 @@ ...@@ -42,6 +43,10 @@
#define IWL1000_UCODE_API_MIN 1 #define IWL1000_UCODE_API_MIN 1
#define IWL100_UCODE_API_MIN 5 #define IWL100_UCODE_API_MIN 5
/* EEPROM version */
#define EEPROM_1000_TX_POWER_VERSION (4)
#define EEPROM_1000_EEPROM_VERSION (0x15C)
#define IWL1000_FW_PRE "iwlwifi-1000-" #define IWL1000_FW_PRE "iwlwifi-1000-"
#define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE __stringify(api) ".ucode" #define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE __stringify(api) ".ucode"
...@@ -66,7 +71,6 @@ static const struct iwl_base_params iwl1000_base_params = { ...@@ -66,7 +71,6 @@ static const struct iwl_base_params iwl1000_base_params = {
static const struct iwl_ht_params iwl1000_ht_params = { static const struct iwl_ht_params iwl1000_ht_params = {
.ht_greenfield_support = true, .ht_greenfield_support = true,
.use_rts_for_aggregation = true, /* use rts/cts protection */ .use_rts_for_aggregation = true, /* use rts/cts protection */
.smps_mode = IEEE80211_SMPS_DYNAMIC,
}; };
#define IWL_DEVICE_1000 \ #define IWL_DEVICE_1000 \
......
...@@ -28,7 +28,8 @@ ...@@ -28,7 +28,8 @@
#include <linux/stringify.h> #include <linux/stringify.h>
#include "iwl-config.h" #include "iwl-config.h"
#include "iwl-cfg.h" #include "iwl-cfg.h"
#include "iwl-dev.h" /* still needed */ #include "iwl-agn-hw.h"
#include "iwl-commands.h" /* needed for BT for now */
/* Highest firmware API version supported */ /* Highest firmware API version supported */
#define IWL2030_UCODE_API_MAX 6 #define IWL2030_UCODE_API_MAX 6
...@@ -48,6 +49,11 @@ ...@@ -48,6 +49,11 @@
#define IWL105_UCODE_API_MIN 5 #define IWL105_UCODE_API_MIN 5
#define IWL135_UCODE_API_MIN 5 #define IWL135_UCODE_API_MIN 5
/* EEPROM version */
#define EEPROM_2000_TX_POWER_VERSION (6)
#define EEPROM_2000_EEPROM_VERSION (0x805)
#define IWL2030_FW_PRE "iwlwifi-2030-" #define IWL2030_FW_PRE "iwlwifi-2030-"
#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE __stringify(api) ".ucode" #define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE __stringify(api) ".ucode"
......
...@@ -28,7 +28,8 @@ ...@@ -28,7 +28,8 @@
#include <linux/stringify.h> #include <linux/stringify.h>
#include "iwl-config.h" #include "iwl-config.h"
#include "iwl-cfg.h" #include "iwl-cfg.h"
#include "iwl-dev.h" /* still needed */ #include "iwl-agn-hw.h"
#include "iwl-csr.h"
/* Highest firmware API version supported */ /* Highest firmware API version supported */
#define IWL5000_UCODE_API_MAX 5 #define IWL5000_UCODE_API_MAX 5
...@@ -38,6 +39,12 @@ ...@@ -38,6 +39,12 @@
#define IWL5000_UCODE_API_MIN 1 #define IWL5000_UCODE_API_MIN 1
#define IWL5150_UCODE_API_MIN 1 #define IWL5150_UCODE_API_MIN 1
/* EEPROM versions */
#define EEPROM_5000_TX_POWER_VERSION (4)
#define EEPROM_5000_EEPROM_VERSION (0x11A)
#define EEPROM_5050_TX_POWER_VERSION (4)
#define EEPROM_5050_EEPROM_VERSION (0x21E)
#define IWL5000_FW_PRE "iwlwifi-5000-" #define IWL5000_FW_PRE "iwlwifi-5000-"
#define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE __stringify(api) ".ucode" #define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE __stringify(api) ".ucode"
......
...@@ -28,7 +28,8 @@ ...@@ -28,7 +28,8 @@
#include <linux/stringify.h> #include <linux/stringify.h>
#include "iwl-config.h" #include "iwl-config.h"
#include "iwl-cfg.h" #include "iwl-cfg.h"
#include "iwl-dev.h" /* still needed */ #include "iwl-agn-hw.h"
#include "iwl-commands.h" /* needed for BT for now */
/* Highest firmware API version supported */ /* Highest firmware API version supported */
#define IWL6000_UCODE_API_MAX 6 #define IWL6000_UCODE_API_MAX 6
...@@ -44,6 +45,20 @@ ...@@ -44,6 +45,20 @@
#define IWL6050_UCODE_API_MIN 4 #define IWL6050_UCODE_API_MIN 4
#define IWL6000G2_UCODE_API_MIN 4 #define IWL6000G2_UCODE_API_MIN 4
/* EEPROM versions */
#define EEPROM_6000_TX_POWER_VERSION (4)
#define EEPROM_6000_EEPROM_VERSION (0x423)
#define EEPROM_6050_TX_POWER_VERSION (4)
#define EEPROM_6050_EEPROM_VERSION (0x532)
#define EEPROM_6150_TX_POWER_VERSION (6)
#define EEPROM_6150_EEPROM_VERSION (0x553)
#define EEPROM_6005_TX_POWER_VERSION (6)
#define EEPROM_6005_EEPROM_VERSION (0x709)
#define EEPROM_6030_TX_POWER_VERSION (6)
#define EEPROM_6030_EEPROM_VERSION (0x709)
#define EEPROM_6035_TX_POWER_VERSION (6)
#define EEPROM_6035_EEPROM_VERSION (0x753)
#define IWL6000_FW_PRE "iwlwifi-6000-" #define IWL6000_FW_PRE "iwlwifi-6000-"
#define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE __stringify(api) ".ucode" #define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE __stringify(api) ".ucode"
......
...@@ -64,7 +64,6 @@ ...@@ -64,7 +64,6 @@
#include <net/mac80211.h> #include <net/mac80211.h>
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-agn-calib.h" #include "iwl-agn-calib.h"
#include "iwl-trans.h" #include "iwl-trans.h"
#include "iwl-agn.h" #include "iwl-agn.h"
...@@ -521,7 +520,7 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv) ...@@ -521,7 +520,7 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv)
iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]); iwl_prepare_legacy_sensitivity_tbl(priv, data, &cmd.enhance_table[0]);
if (cfg(priv)->base_params->hd_v2) { if (priv->cfg->base_params->hd_v2) {
cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] = cmd.enhance_table[HD_INA_NON_SQUARE_DET_OFDM_INDEX] =
HD_INA_NON_SQUARE_DET_OFDM_DATA_V2; HD_INA_NON_SQUARE_DET_OFDM_DATA_V2;
cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] = cmd.enhance_table[HD_INA_NON_SQUARE_DET_CCK_INDEX] =
...@@ -895,7 +894,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, ...@@ -895,7 +894,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv,
continue; continue;
} }
delta_g = (cfg(priv)->base_params->chain_noise_scale * delta_g = (priv->cfg->base_params->chain_noise_scale *
((s32)average_noise[default_chain] - ((s32)average_noise[default_chain] -
(s32)average_noise[i])) / 1500; (s32)average_noise[i])) / 1500;
...@@ -1051,8 +1050,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv) ...@@ -1051,8 +1050,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv)
return; return;
/* Analyze signal for disconnected antenna */ /* Analyze signal for disconnected antenna */
if (cfg(priv)->bt_params && if (priv->cfg->bt_params &&
cfg(priv)->bt_params->advanced_bt_coexist) { priv->cfg->bt_params->advanced_bt_coexist) {
/* Disable disconnected antenna algorithm for advanced /* Disable disconnected antenna algorithm for advanced
bt coex, assuming valid antennas are connected */ bt coex, assuming valid antennas are connected */
data->active_chains = priv->hw_params.valid_rx_ant; data->active_chains = priv->hw_params.valid_rx_ant;
......
...@@ -63,7 +63,6 @@ ...@@ -63,7 +63,6 @@
#define __iwl_calib_h__ #define __iwl_calib_h__
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-commands.h" #include "iwl-commands.h"
void iwl_chain_noise_calibration(struct iwl_priv *priv); void iwl_chain_noise_calibration(struct iwl_priv *priv);
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
/* /*
* DVM device-specific data & functions * DVM device-specific data & functions
*/ */
#include "iwl-core.h"
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-commands.h" #include "iwl-commands.h"
...@@ -60,13 +59,13 @@ static void iwl1000_set_ct_threshold(struct iwl_priv *priv) ...@@ -60,13 +59,13 @@ static void iwl1000_set_ct_threshold(struct iwl_priv *priv)
static void iwl1000_nic_config(struct iwl_priv *priv) static void iwl1000_nic_config(struct iwl_priv *priv)
{ {
/* set CSR_HW_CONFIG_REG for uCode use */ /* set CSR_HW_CONFIG_REG for uCode use */
iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
/* Setting digital SVR for 1000 card to 1.32V */ /* Setting digital SVR for 1000 card to 1.32V */
/* locking is acquired in iwl_set_bits_mask_prph() function */ /* locking is acquired in iwl_set_bits_mask_prph() function */
iwl_set_bits_mask_prph(trans(priv), APMG_DIGITAL_SVR_REG, iwl_set_bits_mask_prph(priv->trans, APMG_DIGITAL_SVR_REG,
APMG_SVR_DIGITAL_VOLTAGE_1_32, APMG_SVR_DIGITAL_VOLTAGE_1_32,
~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK); ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
} }
...@@ -175,7 +174,7 @@ static void iwl1000_hw_set_hw_params(struct iwl_priv *priv) ...@@ -175,7 +174,7 @@ static void iwl1000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.tx_chains_num = priv->hw_params.tx_chains_num =
num_of_ant(priv->hw_params.valid_tx_ant); num_of_ant(priv->hw_params.valid_tx_ant);
if (cfg(priv)->rx_with_siso_diversity) if (priv->cfg->rx_with_siso_diversity)
priv->hw_params.rx_chains_num = 1; priv->hw_params.rx_chains_num = 1;
else else
priv->hw_params.rx_chains_num = priv->hw_params.rx_chains_num =
...@@ -222,7 +221,7 @@ static void iwl2000_nic_config(struct iwl_priv *priv) ...@@ -222,7 +221,7 @@ static void iwl2000_nic_config(struct iwl_priv *priv)
{ {
iwl_rf_config(priv); iwl_rf_config(priv);
iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG,
CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER);
} }
...@@ -256,7 +255,7 @@ static void iwl2000_hw_set_hw_params(struct iwl_priv *priv) ...@@ -256,7 +255,7 @@ static void iwl2000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.tx_chains_num = priv->hw_params.tx_chains_num =
num_of_ant(priv->hw_params.valid_tx_ant); num_of_ant(priv->hw_params.valid_tx_ant);
if (cfg(priv)->rx_with_siso_diversity) if (priv->cfg->rx_with_siso_diversity)
priv->hw_params.rx_chains_num = 1; priv->hw_params.rx_chains_num = 1;
else else
priv->hw_params.rx_chains_num = priv->hw_params.rx_chains_num =
...@@ -318,7 +317,7 @@ static void iwl5000_nic_config(struct iwl_priv *priv) ...@@ -318,7 +317,7 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
* (PCIe power is lost before PERST# is asserted), * (PCIe power is lost before PERST# is asserted),
* causing ME FW to lose ownership and not being able to obtain it back. * causing ME FW to lose ownership and not being able to obtain it back.
*/ */
iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG, iwl_set_bits_mask_prph(priv->trans, APMG_PS_CTRL_REG,
APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
} }
...@@ -573,28 +572,28 @@ static void iwl6000_nic_config(struct iwl_priv *priv) ...@@ -573,28 +572,28 @@ static void iwl6000_nic_config(struct iwl_priv *priv)
{ {
iwl_rf_config(priv); iwl_rf_config(priv);
switch (cfg(priv)->device_family) { switch (priv->cfg->device_family) {
case IWL_DEVICE_FAMILY_6005: case IWL_DEVICE_FAMILY_6005:
case IWL_DEVICE_FAMILY_6030: case IWL_DEVICE_FAMILY_6030:
case IWL_DEVICE_FAMILY_6000: case IWL_DEVICE_FAMILY_6000:
break; break;
case IWL_DEVICE_FAMILY_6000i: case IWL_DEVICE_FAMILY_6000i:
/* 2x2 IPA phy type */ /* 2x2 IPA phy type */
iwl_write32(trans(priv), CSR_GP_DRIVER_REG, iwl_write32(priv->trans, CSR_GP_DRIVER_REG,
CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
break; break;
case IWL_DEVICE_FAMILY_6050: case IWL_DEVICE_FAMILY_6050:
/* Indicate calibration version to uCode. */ /* Indicate calibration version to uCode. */
if (iwl_eeprom_calib_version(priv) >= 6) if (iwl_eeprom_calib_version(priv) >= 6)
iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG,
CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
break; break;
case IWL_DEVICE_FAMILY_6150: case IWL_DEVICE_FAMILY_6150:
/* Indicate calibration version to uCode. */ /* Indicate calibration version to uCode. */
if (iwl_eeprom_calib_version(priv) >= 6) if (iwl_eeprom_calib_version(priv) >= 6)
iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG,
CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, iwl_set_bit(priv->trans, CSR_GP_DRIVER_REG,
CSR_GP_DRIVER_REG_BIT_6050_1x2); CSR_GP_DRIVER_REG_BIT_6050_1x2);
break; break;
default: default:
...@@ -633,7 +632,7 @@ static void iwl6000_hw_set_hw_params(struct iwl_priv *priv) ...@@ -633,7 +632,7 @@ static void iwl6000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.tx_chains_num = priv->hw_params.tx_chains_num =
num_of_ant(priv->hw_params.valid_tx_ant); num_of_ant(priv->hw_params.valid_tx_ant);
if (cfg(priv)->rx_with_siso_diversity) if (priv->cfg->rx_with_siso_diversity)
priv->hw_params.rx_chains_num = 1; priv->hw_params.rx_chains_num = 1;
else else
priv->hw_params.rx_chains_num = priv->hw_params.rx_chains_num =
......
...@@ -102,6 +102,17 @@ ...@@ -102,6 +102,17 @@
/* EEPROM */ /* EEPROM */
#define IWLAGN_EEPROM_IMG_SIZE 2048 #define IWLAGN_EEPROM_IMG_SIZE 2048
/* OTP */
/* lower blocks contain EEPROM image and calibration data */
#define OTP_LOW_IMAGE_SIZE (2 * 512 * sizeof(u16)) /* 2 KB */
/* high blocks contain PAPD data */
#define OTP_HIGH_IMAGE_SIZE_6x00 (6 * 512 * sizeof(u16)) /* 6 KB */
#define OTP_HIGH_IMAGE_SIZE_1000 (0x200 * sizeof(u16)) /* 1024 bytes */
#define OTP_MAX_LL_ITEMS_1000 (3) /* OTP blocks for 1000 */
#define OTP_MAX_LL_ITEMS_6x00 (4) /* OTP blocks for 6x00 */
#define OTP_MAX_LL_ITEMS_6x50 (7) /* OTP blocks for 6x50 */
#define OTP_MAX_LL_ITEMS_2x00 (4) /* OTP blocks for 2x00 */
#define IWLAGN_NUM_QUEUES 20 #define IWLAGN_NUM_QUEUES 20
......
...@@ -33,12 +33,11 @@ ...@@ -33,12 +33,11 @@
#include <linux/sched.h> #include <linux/sched.h>
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-io.h" #include "iwl-io.h"
#include "iwl-agn-hw.h" #include "iwl-agn-hw.h"
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-trans.h" #include "iwl-trans.h"
#include "iwl-shared.h" #include "iwl-modparams.h"
int iwlagn_hw_valid_rtc_data_addr(u32 addr) int iwlagn_hw_valid_rtc_data_addr(u32 addr)
{ {
...@@ -94,17 +93,6 @@ void iwlagn_temperature(struct iwl_priv *priv) ...@@ -94,17 +93,6 @@ void iwlagn_temperature(struct iwl_priv *priv)
iwl_tt_handler(priv); iwl_tt_handler(priv);
} }
struct iwl_mod_params iwlagn_mod_params = {
.amsdu_size_8K = 1,
.restart_fw = 1,
.plcp_check = true,
.bt_coex_active = true,
.power_level = IWL_POWER_INDEX_1,
.bt_ch_announce = true,
.auto_agg = true,
/* the rest are 0 by default */
};
int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band) int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band)
{ {
int idx = 0; int idx = 0;
...@@ -189,7 +177,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) ...@@ -189,7 +177,7 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
goto done; goto done;
} }
IWL_DEBUG_INFO(priv, "wait transmit/flush all frames\n"); IWL_DEBUG_INFO(priv, "wait transmit/flush all frames\n");
iwl_trans_wait_tx_queue_empty(trans(priv)); iwl_trans_wait_tx_queue_empty(priv->trans);
done: done:
ieee80211_wake_queues(priv->hw); ieee80211_wake_queues(priv->hw);
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
...@@ -312,21 +300,21 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) ...@@ -312,21 +300,21 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) != BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) !=
sizeof(basic.bt3_lookup_table)); sizeof(basic.bt3_lookup_table));
if (cfg(priv)->bt_params) { if (priv->cfg->bt_params) {
/* /*
* newer generation of devices (2000 series and newer) * newer generation of devices (2000 series and newer)
* use the version 2 of the bt command * use the version 2 of the bt command
* we need to make sure sending the host command * we need to make sure sending the host command
* with correct data structure to avoid uCode assert * with correct data structure to avoid uCode assert
*/ */
if (cfg(priv)->bt_params->bt_session_2) { if (priv->cfg->bt_params->bt_session_2) {
bt_cmd_v2.prio_boost = cpu_to_le32( bt_cmd_v2.prio_boost = cpu_to_le32(
cfg(priv)->bt_params->bt_prio_boost); priv->cfg->bt_params->bt_prio_boost);
bt_cmd_v2.tx_prio_boost = 0; bt_cmd_v2.tx_prio_boost = 0;
bt_cmd_v2.rx_prio_boost = 0; bt_cmd_v2.rx_prio_boost = 0;
} else { } else {
bt_cmd_v1.prio_boost = bt_cmd_v1.prio_boost =
cfg(priv)->bt_params->bt_prio_boost; priv->cfg->bt_params->bt_prio_boost;
bt_cmd_v1.tx_prio_boost = 0; bt_cmd_v1.tx_prio_boost = 0;
bt_cmd_v1.rx_prio_boost = 0; bt_cmd_v1.rx_prio_boost = 0;
} }
...@@ -345,7 +333,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) ...@@ -345,7 +333,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
* (might be in monitor mode), or the interface is in * (might be in monitor mode), or the interface is in
* IBSS mode (no proper uCode support for coex then). * IBSS mode (no proper uCode support for coex then).
*/ */
if (!iwlagn_mod_params.bt_coex_active || if (!iwlwifi_mod_params.bt_coex_active ||
priv->iw_mode == NL80211_IFTYPE_ADHOC) { priv->iw_mode == NL80211_IFTYPE_ADHOC) {
basic.flags = IWLAGN_BT_FLAG_COEX_MODE_DISABLED; basic.flags = IWLAGN_BT_FLAG_COEX_MODE_DISABLED;
} else { } else {
...@@ -374,7 +362,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) ...@@ -374,7 +362,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
priv->bt_full_concurrent ? priv->bt_full_concurrent ?
"full concurrency" : "3-wire"); "full concurrency" : "3-wire");
if (cfg(priv)->bt_params->bt_session_2) { if (priv->cfg->bt_params->bt_session_2) {
memcpy(&bt_cmd_v2.basic, &basic, memcpy(&bt_cmd_v2.basic, &basic,
sizeof(basic)); sizeof(basic));
ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG, ret = iwl_dvm_send_cmd_pdu(priv, REPLY_BT_CONFIG,
...@@ -740,8 +728,8 @@ static bool is_single_rx_stream(struct iwl_priv *priv) ...@@ -740,8 +728,8 @@ static bool is_single_rx_stream(struct iwl_priv *priv)
*/ */
static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
{ {
if (cfg(priv)->bt_params && if (priv->cfg->bt_params &&
cfg(priv)->bt_params->advanced_bt_coexist && priv->cfg->bt_params->advanced_bt_coexist &&
(priv->bt_full_concurrent || (priv->bt_full_concurrent ||
priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
/* /*
...@@ -812,8 +800,8 @@ void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ...@@ -812,8 +800,8 @@ void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
else else
active_chains = priv->hw_params.valid_rx_ant; active_chains = priv->hw_params.valid_rx_ant;
if (cfg(priv)->bt_params && if (priv->cfg->bt_params &&
cfg(priv)->bt_params->advanced_bt_coexist && priv->cfg->bt_params->advanced_bt_coexist &&
(priv->bt_full_concurrent || (priv->bt_full_concurrent ||
priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
/* /*
...@@ -1132,7 +1120,7 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) ...@@ -1132,7 +1120,7 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan)
memcpy(&rxon, &ctx->active, sizeof(rxon)); memcpy(&rxon, &ctx->active, sizeof(rxon));
priv->ucode_loaded = false; priv->ucode_loaded = false;
iwl_trans_stop_device(trans(priv)); iwl_trans_stop_device(priv->trans);
priv->wowlan = true; priv->wowlan = true;
...@@ -1154,7 +1142,7 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) ...@@ -1154,7 +1142,7 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan)
if (ret) if (ret)
goto out; goto out;
if (!iwlagn_mod_params.sw_crypto) { if (!iwlwifi_mod_params.sw_crypto) {
/* mark all keys clear */ /* mark all keys clear */
priv->ucode_key_table = 0; priv->ucode_key_table = 0;
ctx->key_mapping_keys = 0; ctx->key_mapping_keys = 0;
...@@ -1260,7 +1248,7 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) ...@@ -1260,7 +1248,7 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
return -EIO; return -EIO;
} }
return iwl_trans_send_cmd(trans(priv), cmd); return iwl_trans_send_cmd(priv->trans, cmd);
} }
int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id, int iwl_dvm_send_cmd_pdu(struct iwl_priv *priv, u8 id,
......
...@@ -36,9 +36,9 @@ ...@@ -36,9 +36,9 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-op-mode.h" #include "iwl-op-mode.h"
#include "iwl-modparams.h"
#define RS_NAME "iwl-agn-rs" #define RS_NAME "iwl-agn-rs"
...@@ -420,7 +420,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, ...@@ -420,7 +420,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
load = rs_tl_get_load(lq_data, tid); load = rs_tl_get_load(lq_data, tid);
if ((iwlagn_mod_params.auto_agg) || (load > IWL_AGG_LOAD_THRESHOLD)) { if ((iwlwifi_mod_params.auto_agg) || (load > IWL_AGG_LOAD_THRESHOLD)) {
IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
sta->addr, tid); sta->addr, tid);
ret = ieee80211_start_tx_ba_session(sta, tid, 5000); ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
...@@ -1085,7 +1085,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, ...@@ -1085,7 +1085,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
(priv->tm_fixed_rate != lq_sta->dbg_fixed_rate)) (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate))
rs_program_fix_rate(priv, lq_sta); rs_program_fix_rate(priv, lq_sta);
#endif #endif
if (cfg(priv)->bt_params && cfg(priv)->bt_params->advanced_bt_coexist) if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist)
rs_bt_update_lq(priv, ctx, lq_sta); rs_bt_update_lq(priv, ctx, lq_sta);
} }
...@@ -3063,11 +3063,11 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, ...@@ -3063,11 +3063,11 @@ static void rs_fill_link_cmd(struct iwl_priv *priv,
* overwrite if needed, pass aggregation time limit * overwrite if needed, pass aggregation time limit
* to uCode in uSec * to uCode in uSec
*/ */
if (priv && cfg(priv)->bt_params && if (priv && priv->cfg->bt_params &&
cfg(priv)->bt_params->agg_time_limit && priv->cfg->bt_params->agg_time_limit &&
priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
lq_cmd->agg_params.agg_time_limit = lq_cmd->agg_params.agg_time_limit =
cpu_to_le16(cfg(priv)->bt_params->agg_time_limit); cpu_to_le16(priv->cfg->bt_params->agg_time_limit);
} }
static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <net/mac80211.h> #include <net/mac80211.h>
#include "iwl-commands.h" #include "iwl-commands.h"
#include "iwl-config.h"
struct iwl_rate_info { struct iwl_rate_info {
u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
...@@ -174,32 +175,6 @@ enum { ...@@ -174,32 +175,6 @@ enum {
IWL_RATE_11M_IEEE = 22, IWL_RATE_11M_IEEE = 22,
}; };
#define IWL_CCK_BASIC_RATES_MASK \
(IWL_RATE_1M_MASK | \
IWL_RATE_2M_MASK)
#define IWL_CCK_RATES_MASK \
(IWL_CCK_BASIC_RATES_MASK | \
IWL_RATE_5M_MASK | \
IWL_RATE_11M_MASK)
#define IWL_OFDM_BASIC_RATES_MASK \
(IWL_RATE_6M_MASK | \
IWL_RATE_12M_MASK | \
IWL_RATE_24M_MASK)
#define IWL_OFDM_RATES_MASK \
(IWL_OFDM_BASIC_RATES_MASK | \
IWL_RATE_9M_MASK | \
IWL_RATE_18M_MASK | \
IWL_RATE_36M_MASK | \
IWL_RATE_48M_MASK | \
IWL_RATE_54M_MASK)
#define IWL_BASIC_RATES_MASK \
(IWL_OFDM_BASIC_RATES_MASK | \
IWL_CCK_BASIC_RATES_MASK)
#define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1) #define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
#define IWL_INVALID_VALUE -1 #define IWL_INVALID_VALUE -1
...@@ -306,15 +281,6 @@ enum iwl_table_type { ...@@ -306,15 +281,6 @@ enum iwl_table_type {
#define is_a_band(tbl) ((tbl) == LQ_A) #define is_a_band(tbl) ((tbl) == LQ_A)
#define is_g_and(tbl) ((tbl) == LQ_G) #define is_g_and(tbl) ((tbl) == LQ_G)
#define ANT_NONE 0x0
#define ANT_A BIT(0)
#define ANT_B BIT(1)
#define ANT_AB (ANT_A | ANT_B)
#define ANT_C BIT(2)
#define ANT_AC (ANT_A | ANT_C)
#define ANT_BC (ANT_B | ANT_C)
#define ANT_ABC (ANT_AB | ANT_C)
#define IWL_MAX_MCS_DISPLAY_SIZE 12 #define IWL_MAX_MCS_DISPLAY_SIZE 12
struct iwl_rate_mcs_info { struct iwl_rate_mcs_info {
......
...@@ -34,11 +34,10 @@ ...@@ -34,11 +34,10 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include "iwl-eeprom.h" #include "iwl-eeprom.h"
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-io.h" #include "iwl-io.h"
#include "iwl-agn-calib.h" #include "iwl-agn-calib.h"
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-shared.h" #include "iwl-modparams.h"
#define IWL_CMD_ENTRY(x) [x] = #x #define IWL_CMD_ENTRY(x) [x] = #x
...@@ -339,7 +338,7 @@ static void iwlagn_recover_from_statistics(struct iwl_priv *priv, ...@@ -339,7 +338,7 @@ static void iwlagn_recover_from_statistics(struct iwl_priv *priv,
if (msecs < 99) if (msecs < 99)
return; return;
if (iwlagn_mod_params.plcp_check && if (iwlwifi_mod_params.plcp_check &&
!iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) !iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs))
iwl_force_rf_reset(priv, false); iwl_force_rf_reset(priv, false);
} }
...@@ -604,16 +603,16 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, ...@@ -604,16 +603,16 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv,
if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
CT_CARD_DISABLED)) { CT_CARD_DISABLED)) {
iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_SET,
CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
iwl_write_direct32(trans(priv), HBUS_TARG_MBX_C, iwl_write_direct32(priv->trans, HBUS_TARG_MBX_C,
HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
if (!(flags & RXON_CARD_DISABLED)) { if (!(flags & RXON_CARD_DISABLED)) {
iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR,
CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
iwl_write_direct32(trans(priv), HBUS_TARG_MBX_C, iwl_write_direct32(priv->trans, HBUS_TARG_MBX_C,
HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
} }
if (flags & CT_CARD_DISABLED) if (flags & CT_CARD_DISABLED)
...@@ -636,7 +635,7 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, ...@@ -636,7 +635,7 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv,
wiphy_rfkill_set_hw_state(priv->hw->wiphy, wiphy_rfkill_set_hw_state(priv->hw->wiphy,
test_bit(STATUS_RF_KILL_HW, &priv->status)); test_bit(STATUS_RF_KILL_HW, &priv->status));
else else
wake_up(&trans(priv)->wait_command_queue); wake_up(&priv->trans->wait_command_queue);
return 0; return 0;
} }
...@@ -749,7 +748,7 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, ...@@ -749,7 +748,7 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
} }
/* In case of HW accelerated crypto and bad decryption, drop */ /* In case of HW accelerated crypto and bad decryption, drop */
if (!iwlagn_mod_params.sw_crypto && if (!iwlwifi_mod_params.sw_crypto &&
iwlagn_set_decrypted_flag(priv, hdr, ampdu_status, stats)) iwlagn_set_decrypted_flag(priv, hdr, ampdu_status, stats))
return; return;
...@@ -763,8 +762,6 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv, ...@@ -763,8 +762,6 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
p = rxb_steal_page(rxb); p = rxb_steal_page(rxb);
skb_add_rx_frag(skb, 0, p, offset, len, len); skb_add_rx_frag(skb, 0, p, offset, len, len);
iwl_update_stats(priv, false, fc, len);
/* /*
* Wake any queues that were stopped due to a passive channel tx * Wake any queues that were stopped due to a passive channel tx
* failure. This can happen because the regulatory enforcement in * failure. This can happen because the regulatory enforcement in
...@@ -970,7 +967,6 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, ...@@ -970,7 +967,6 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
/* Find max signal strength (dBm) among 3 antenna/receiver chains */ /* Find max signal strength (dBm) among 3 antenna/receiver chains */
rx_status.signal = iwlagn_calc_rssi(priv, phy_res); rx_status.signal = iwlagn_calc_rssi(priv, phy_res);
iwl_dbg_log_rx_data_frame(priv, len, header);
IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n", IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, TSF %llu\n",
rx_status.signal, (unsigned long long)rx_status.mactime); rx_status.signal, (unsigned long long)rx_status.mactime);
...@@ -1105,7 +1101,7 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) ...@@ -1105,7 +1101,7 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
iwl_notification_wait_init(&priv->notif_wait); iwl_notification_wait_init(&priv->notif_wait);
/* Set up BT Rx handlers */ /* Set up BT Rx handlers */
if (cfg(priv)->bt_params) if (priv->cfg->bt_params)
iwlagn_bt_rx_handler_setup(priv); iwlagn_bt_rx_handler_setup(priv);
} }
......
...@@ -27,10 +27,9 @@ ...@@ -27,10 +27,9 @@
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-core.h"
#include "iwl-agn-calib.h" #include "iwl-agn-calib.h"
#include "iwl-trans.h" #include "iwl-trans.h"
#include "iwl-shared.h" #include "iwl-modparams.h"
/* /*
* initialize rxon structure with default values from eeprom * initialize rxon structure with default values from eeprom
...@@ -88,11 +87,6 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, ...@@ -88,11 +87,6 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv,
iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif); iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif);
ctx->staging.ofdm_basic_rates =
(IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
ctx->staging.cck_basic_rates =
(IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
/* clear both MIX and PURE40 mode flag */ /* clear both MIX and PURE40 mode flag */
ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED |
RXON_FLG_CHANNEL_MODE_PURE_40); RXON_FLG_CHANNEL_MODE_PURE_40);
...@@ -531,9 +525,9 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, ...@@ -531,9 +525,9 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv,
} }
if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION && if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION &&
cfg(priv)->ht_params && cfg(priv)->ht_params->smps_mode) priv->cfg->ht_params && priv->cfg->ht_params->smps_mode)
ieee80211_request_smps(ctx->vif, ieee80211_request_smps(ctx->vif,
cfg(priv)->ht_params->smps_mode); priv->cfg->ht_params->smps_mode);
return 0; return 0;
} }
...@@ -772,19 +766,6 @@ void iwl_set_flags_for_band(struct iwl_priv *priv, ...@@ -772,19 +766,6 @@ void iwl_set_flags_for_band(struct iwl_priv *priv,
} }
} }
void iwl_set_rate(struct iwl_priv *priv)
{
struct iwl_rxon_context *ctx;
for_each_context(priv, ctx) {
ctx->staging.cck_basic_rates =
(IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
ctx->staging.ofdm_basic_rates =
(IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
}
}
static void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, static void iwl_set_rxon_hwcrypto(struct iwl_priv *priv,
struct iwl_rxon_context *ctx, int hw_decrypt) struct iwl_rxon_context *ctx, int hw_decrypt)
{ {
...@@ -960,6 +941,97 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv, ...@@ -960,6 +941,97 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv,
} }
#endif #endif
static void iwl_calc_basic_rates(struct iwl_priv *priv,
struct iwl_rxon_context *ctx)
{
int lowest_present_ofdm = 100;
int lowest_present_cck = 100;
u8 cck = 0;
u8 ofdm = 0;
if (ctx->vif) {
struct ieee80211_supported_band *sband;
unsigned long basic = ctx->vif->bss_conf.basic_rates;
int i;
sband = priv->hw->wiphy->bands[priv->hw->conf.channel->band];
for_each_set_bit(i, &basic, BITS_PER_LONG) {
int hw = sband->bitrates[i].hw_value;
if (hw >= IWL_FIRST_OFDM_RATE) {
ofdm |= BIT(hw - IWL_FIRST_OFDM_RATE);
if (lowest_present_ofdm > hw)
lowest_present_ofdm = hw;
} else {
BUILD_BUG_ON(IWL_FIRST_CCK_RATE != 0);
cck |= BIT(hw);
if (lowest_present_cck > hw)
lowest_present_cck = hw;
}
}
}
/*
* Now we've got the basic rates as bitmaps in the ofdm and cck
* variables. This isn't sufficient though, as there might not
* be all the right rates in the bitmap. E.g. if the only basic
* rates are 5.5 Mbps and 11 Mbps, we still need to add 1 Mbps
* and 6 Mbps because the 802.11-2007 standard says in 9.6:
*
* [...] a STA responding to a received frame shall transmit
* its Control Response frame [...] at the highest rate in the
* BSSBasicRateSet parameter that is less than or equal to the
* rate of the immediately previous frame in the frame exchange
* sequence ([...]) and that is of the same modulation class
* ([...]) as the received frame. If no rate contained in the
* BSSBasicRateSet parameter meets these conditions, then the
* control frame sent in response to a received frame shall be
* transmitted at the highest mandatory rate of the PHY that is
* less than or equal to the rate of the received frame, and
* that is of the same modulation class as the received frame.
*
* As a consequence, we need to add all mandatory rates that are
* lower than all of the basic rates to these bitmaps.
*/
if (IWL_RATE_24M_INDEX < lowest_present_ofdm)
ofdm |= IWL_RATE_24M_MASK >> IWL_FIRST_OFDM_RATE;
if (IWL_RATE_12M_INDEX < lowest_present_ofdm)
ofdm |= IWL_RATE_12M_MASK >> IWL_FIRST_OFDM_RATE;
/* 6M already there or needed so always add */
ofdm |= IWL_RATE_6M_MASK >> IWL_FIRST_OFDM_RATE;
/*
* CCK is a bit more complex with DSSS vs. HR/DSSS vs. ERP.
* Note, however:
* - if no CCK rates are basic, it must be ERP since there must
* be some basic rates at all, so they're OFDM => ERP PHY
* (or we're in 5 GHz, and the cck bitmap will never be used)
* - if 11M is a basic rate, it must be ERP as well, so add 5.5M
* - if 5.5M is basic, 1M and 2M are mandatory
* - if 2M is basic, 1M is mandatory
* - if 1M is basic, that's the only valid ACK rate.
* As a consequence, it's not as complicated as it sounds, just add
* any lower rates to the ACK rate bitmap.
*/
if (IWL_RATE_11M_INDEX < lowest_present_ofdm)
ofdm |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE;
if (IWL_RATE_5M_INDEX < lowest_present_ofdm)
ofdm |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE;
if (IWL_RATE_2M_INDEX < lowest_present_ofdm)
ofdm |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE;
/* 1M already there or needed so always add */
cck |= IWL_RATE_1M_MASK >> IWL_FIRST_CCK_RATE;
IWL_DEBUG_RATE(priv, "Set basic rates cck:0x%.2x ofdm:0x%.2x\n",
cck, ofdm);
/* "basic_rates" is a misnomer here -- should be called ACK rates */
ctx->staging.cck_basic_rates = cck;
ctx->staging.ofdm_basic_rates = ofdm;
}
/** /**
* iwlagn_commit_rxon - commit staging_rxon to hardware * iwlagn_commit_rxon - commit staging_rxon to hardware
* *
...@@ -999,6 +1071,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ...@@ -999,6 +1071,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
/* always get timestamp with Rx frame */ /* always get timestamp with Rx frame */
ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
/* recalculate basic rates */
iwl_calc_basic_rates(priv, ctx);
/* /*
* force CTS-to-self frames protection if RTS-CTS is not preferred * force CTS-to-self frames protection if RTS-CTS is not preferred
* one aggregation protection method * one aggregation protection method
...@@ -1055,7 +1130,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ...@@ -1055,7 +1130,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
return 0; return 0;
} }
iwl_set_rxon_hwcrypto(priv, ctx, !iwlagn_mod_params.sw_crypto); iwl_set_rxon_hwcrypto(priv, ctx, !iwlwifi_mod_params.sw_crypto);
IWL_DEBUG_INFO(priv, IWL_DEBUG_INFO(priv,
"Going to commit RXON\n" "Going to commit RXON\n"
...@@ -1187,13 +1262,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) ...@@ -1187,13 +1262,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
} }
iwl_update_bcast_stations(priv); iwl_update_bcast_stations(priv);
/*
* The list of supported rates and rate mask can be different
* for each band; since the band may have changed, reset
* the rate mask to what mac80211 lists.
*/
iwl_set_rate(priv);
} }
if (changed & (IEEE80211_CONF_CHANGE_PS | if (changed & (IEEE80211_CONF_CHANGE_PS |
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include <net/mac80211.h> #include <net/mac80211.h>
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-trans.h" #include "iwl-trans.h"
......
...@@ -37,11 +37,11 @@ ...@@ -37,11 +37,11 @@
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-eeprom.h" #include "iwl-eeprom.h"
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-io.h" #include "iwl-io.h"
#include "iwl-commands.h" #include "iwl-commands.h"
#include "iwl-debug.h" #include "iwl-debug.h"
#include "iwl-agn-tt.h" #include "iwl-agn-tt.h"
#include "iwl-modparams.h"
/* default Thermal Throttling transaction table /* default Thermal Throttling transaction table
* Current state | Throttling Down | Throttling Up * Current state | Throttling Down | Throttling Up
...@@ -179,19 +179,19 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) ...@@ -179,19 +179,19 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data)
if (tt->state == IWL_TI_CT_KILL) { if (tt->state == IWL_TI_CT_KILL) {
if (priv->thermal_throttle.ct_kill_toggle) { if (priv->thermal_throttle.ct_kill_toggle) {
iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR,
CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
priv->thermal_throttle.ct_kill_toggle = false; priv->thermal_throttle.ct_kill_toggle = false;
} else { } else {
iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_SET,
CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
priv->thermal_throttle.ct_kill_toggle = true; priv->thermal_throttle.ct_kill_toggle = true;
} }
iwl_read32(trans(priv), CSR_UCODE_DRV_GP1); iwl_read32(priv->trans, CSR_UCODE_DRV_GP1);
spin_lock_irqsave(&trans(priv)->reg_lock, flags); spin_lock_irqsave(&priv->trans->reg_lock, flags);
if (likely(iwl_grab_nic_access(trans(priv)))) if (likely(iwl_grab_nic_access(priv->trans)))
iwl_release_nic_access(trans(priv)); iwl_release_nic_access(priv->trans);
spin_unlock_irqrestore(&trans(priv)->reg_lock, flags); spin_unlock_irqrestore(&priv->trans->reg_lock, flags);
/* Reschedule the ct_kill timer to occur in /* Reschedule the ct_kill timer to occur in
* CT_KILL_EXIT_DURATION seconds to ensure we get a * CT_KILL_EXIT_DURATION seconds to ensure we get a
...@@ -632,7 +632,7 @@ void iwl_tt_initialize(struct iwl_priv *priv) ...@@ -632,7 +632,7 @@ void iwl_tt_initialize(struct iwl_priv *priv)
INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter); INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter);
INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit);
if (cfg(priv)->base_params->adv_thermal_throttle) { if (priv->cfg->base_params->adv_thermal_throttle) {
IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n"); IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n");
tt->restriction = kcalloc(IWL_TI_STATE_MAX, tt->restriction = kcalloc(IWL_TI_STATE_MAX,
sizeof(struct iwl_tt_restriction), sizeof(struct iwl_tt_restriction),
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include <linux/ieee80211.h> #include <linux/ieee80211.h>
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-io.h" #include "iwl-io.h"
#include "iwl-agn-hw.h" #include "iwl-agn-hw.h"
#include "iwl-agn.h" #include "iwl-agn.h"
...@@ -85,8 +84,8 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, ...@@ -85,8 +84,8 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
else if (ieee80211_is_back_req(fc)) else if (ieee80211_is_back_req(fc))
tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
else if (info->band == IEEE80211_BAND_2GHZ && else if (info->band == IEEE80211_BAND_2GHZ &&
cfg(priv)->bt_params && priv->cfg->bt_params &&
cfg(priv)->bt_params->advanced_bt_coexist && priv->cfg->bt_params->advanced_bt_coexist &&
(ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) || (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) ||
ieee80211_is_reassoc_req(fc) || ieee80211_is_reassoc_req(fc) ||
skb->protocol == cpu_to_be16(ETH_P_PAE))) skb->protocol == cpu_to_be16(ETH_P_PAE)))
...@@ -203,8 +202,8 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, ...@@ -203,8 +202,8 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
rate_flags |= RATE_MCS_CCK_MSK; rate_flags |= RATE_MCS_CCK_MSK;
/* Set up antennas */ /* Set up antennas */
if (cfg(priv)->bt_params && if (priv->cfg->bt_params &&
cfg(priv)->bt_params->advanced_bt_coexist && priv->cfg->bt_params->advanced_bt_coexist &&
priv->bt_full_concurrent) { priv->bt_full_concurrent) {
/* operated as 1x1 in full concurrency mode */ /* operated as 1x1 in full concurrency mode */
priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
...@@ -396,12 +395,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -396,12 +395,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
/* TODO need this for burst mode later on */ /* TODO need this for burst mode later on */
iwlagn_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id); iwlagn_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id);
iwl_dbg_log_tx_data_frame(priv, len, hdr);
iwlagn_tx_cmd_build_rate(priv, tx_cmd, info, fc); iwlagn_tx_cmd_build_rate(priv, tx_cmd, info, fc);
iwl_update_stats(priv, true, fc, len);
memset(&info->status, 0, sizeof(info->status)); memset(&info->status, 0, sizeof(info->status));
info->driver_data[0] = ctx; info->driver_data[0] = ctx;
...@@ -467,7 +463,11 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -467,7 +463,11 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
else else
txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)]; txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];
if (iwl_trans_tx(trans(priv), skb, dev_cmd, txq_id)) WARN_ON_ONCE(!is_agg && txq_id != info->hw_queue);
WARN_ON_ONCE(is_agg &&
priv->queue_to_mac80211[txq_id] != info->hw_queue);
if (iwl_trans_tx(priv->trans, skb, dev_cmd, txq_id))
goto drop_unlock_sta; goto drop_unlock_sta;
if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc) && if (ieee80211_is_data_qos(fc) && !ieee80211_is_qos_nullfunc(fc) &&
...@@ -496,14 +496,14 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -496,14 +496,14 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
return -1; return -1;
} }
static int iwlagn_alloc_agg_txq(struct iwl_priv *priv, int ac) static int iwlagn_alloc_agg_txq(struct iwl_priv *priv, int mq)
{ {
int q; int q;
for (q = IWLAGN_FIRST_AMPDU_QUEUE; for (q = IWLAGN_FIRST_AMPDU_QUEUE;
q < cfg(priv)->base_params->num_of_queues; q++) { q < priv->cfg->base_params->num_of_queues; q++) {
if (!test_and_set_bit(q, priv->agg_q_alloc)) { if (!test_and_set_bit(q, priv->agg_q_alloc)) {
priv->queue_to_ac[q] = ac; priv->queue_to_mac80211[q] = mq;
return q; return q;
} }
} }
...@@ -514,7 +514,7 @@ static int iwlagn_alloc_agg_txq(struct iwl_priv *priv, int ac) ...@@ -514,7 +514,7 @@ static int iwlagn_alloc_agg_txq(struct iwl_priv *priv, int ac)
static void iwlagn_dealloc_agg_txq(struct iwl_priv *priv, int q) static void iwlagn_dealloc_agg_txq(struct iwl_priv *priv, int q)
{ {
clear_bit(q, priv->agg_q_alloc); clear_bit(q, priv->agg_q_alloc);
priv->queue_to_ac[q] = IWL_INVALID_AC; priv->queue_to_mac80211[q] = IWL_INVALID_MAC80211_QUEUE;
} }
int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
...@@ -522,6 +522,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, ...@@ -522,6 +522,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
{ {
struct iwl_tid_data *tid_data; struct iwl_tid_data *tid_data;
int sta_id, txq_id; int sta_id, txq_id;
enum iwl_agg_state agg_state;
sta_id = iwl_sta_id(sta); sta_id = iwl_sta_id(sta);
...@@ -545,6 +546,13 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, ...@@ -545,6 +546,13 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
*/ */
IWL_DEBUG_HT(priv, "AGG stop before setup done\n"); IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
goto turn_off; goto turn_off;
case IWL_AGG_STARTING:
/*
* This can happen when the session is stopped before
* we receive ADDBA response
*/
IWL_DEBUG_HT(priv, "AGG stop before AGG became operational\n");
goto turn_off;
case IWL_AGG_ON: case IWL_AGG_ON:
break; break;
default: default:
...@@ -576,12 +584,17 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, ...@@ -576,12 +584,17 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n", IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n",
tid_data->agg.ssn); tid_data->agg.ssn);
turn_off: turn_off:
agg_state = priv->tid_data[sta_id][tid].agg.state;
priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF; priv->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF;
spin_unlock_bh(&priv->sta_lock); spin_unlock_bh(&priv->sta_lock);
if (test_bit(txq_id, priv->agg_q_alloc)) { if (test_bit(txq_id, priv->agg_q_alloc)) {
iwl_trans_tx_agg_disable(trans(priv), txq_id); /* If the transport didn't know that we wanted to start
* agreggation, don't tell it that we want to stop them
*/
if (agg_state != IWL_AGG_STARTING)
iwl_trans_tx_agg_disable(priv->trans, txq_id);
iwlagn_dealloc_agg_txq(priv, txq_id); iwlagn_dealloc_agg_txq(priv, txq_id);
} }
...@@ -593,6 +606,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, ...@@ -593,6 +606,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid, u16 *ssn) struct ieee80211_sta *sta, u16 tid, u16 *ssn)
{ {
struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
struct iwl_tid_data *tid_data; struct iwl_tid_data *tid_data;
int sta_id, txq_id, ret; int sta_id, txq_id, ret;
...@@ -612,7 +626,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, ...@@ -612,7 +626,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
return -ENXIO; return -ENXIO;
} }
txq_id = iwlagn_alloc_agg_txq(priv, tid_to_ac[tid]); txq_id = iwlagn_alloc_agg_txq(priv, ctx->ac_to_queue[tid_to_ac[tid]]);
if (txq_id < 0) { if (txq_id < 0) {
IWL_DEBUG_TX_QUEUES(priv, IWL_DEBUG_TX_QUEUES(priv,
"No free aggregation queue for %pM/%d\n", "No free aggregation queue for %pM/%d\n",
...@@ -634,7 +648,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, ...@@ -634,7 +648,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
if (*ssn == tid_data->next_reclaimed) { if (*ssn == tid_data->next_reclaimed) {
IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n", IWL_DEBUG_TX_QUEUES(priv, "Can proceed: ssn = next_recl = %d\n",
tid_data->agg.ssn); tid_data->agg.ssn);
tid_data->agg.state = IWL_AGG_ON; tid_data->agg.state = IWL_AGG_STARTING;
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
} else { } else {
IWL_DEBUG_TX_QUEUES(priv, "Can't proceed: ssn %d, " IWL_DEBUG_TX_QUEUES(priv, "Can't proceed: ssn %d, "
...@@ -661,11 +675,12 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif, ...@@ -661,11 +675,12 @@ int iwlagn_tx_agg_oper(struct iwl_priv *priv, struct ieee80211_vif *vif,
spin_lock_bh(&priv->sta_lock); spin_lock_bh(&priv->sta_lock);
ssn = priv->tid_data[sta_priv->sta_id][tid].agg.ssn; ssn = priv->tid_data[sta_priv->sta_id][tid].agg.ssn;
q = priv->tid_data[sta_priv->sta_id][tid].agg.txq_id; q = priv->tid_data[sta_priv->sta_id][tid].agg.txq_id;
priv->tid_data[sta_priv->sta_id][tid].agg.state = IWL_AGG_ON;
spin_unlock_bh(&priv->sta_lock); spin_unlock_bh(&priv->sta_lock);
fifo = ctx->ac_to_fifo[tid_to_ac[tid]]; fifo = ctx->ac_to_fifo[tid_to_ac[tid]];
iwl_trans_tx_agg_setup(trans(priv), q, fifo, iwl_trans_tx_agg_setup(priv->trans, q, fifo,
sta_priv->sta_id, tid, sta_priv->sta_id, tid,
buf_size, ssn); buf_size, ssn);
...@@ -732,7 +747,7 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid) ...@@ -732,7 +747,7 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid)
IWL_DEBUG_TX_QUEUES(priv, IWL_DEBUG_TX_QUEUES(priv,
"Can continue DELBA flow ssn = next_recl =" "Can continue DELBA flow ssn = next_recl ="
" %d", tid_data->next_reclaimed); " %d", tid_data->next_reclaimed);
iwl_trans_tx_agg_disable(trans(priv), iwl_trans_tx_agg_disable(priv->trans,
tid_data->agg.txq_id); tid_data->agg.txq_id);
iwlagn_dealloc_agg_txq(priv, tid_data->agg.txq_id); iwlagn_dealloc_agg_txq(priv, tid_data->agg.txq_id);
tid_data->agg.state = IWL_AGG_OFF; tid_data->agg.state = IWL_AGG_OFF;
...@@ -745,7 +760,7 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid) ...@@ -745,7 +760,7 @@ static void iwlagn_check_ratid_empty(struct iwl_priv *priv, int sta_id, u8 tid)
IWL_DEBUG_TX_QUEUES(priv, IWL_DEBUG_TX_QUEUES(priv,
"Can continue ADDBA flow ssn = next_recl =" "Can continue ADDBA flow ssn = next_recl ="
" %d", tid_data->next_reclaimed); " %d", tid_data->next_reclaimed);
tid_data->agg.state = IWL_AGG_ON; tid_data->agg.state = IWL_AGG_STARTING;
ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid); ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid);
} }
break; break;
...@@ -909,8 +924,8 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv, ...@@ -909,8 +924,8 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
* notification again. * notification again.
*/ */
if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 && if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 &&
cfg(priv)->bt_params && priv->cfg->bt_params &&
cfg(priv)->bt_params->advanced_bt_coexist) { priv->cfg->bt_params->advanced_bt_coexist) {
IWL_DEBUG_COEX(priv, "receive reply tx w/ bt_kill\n"); IWL_DEBUG_COEX(priv, "receive reply tx w/ bt_kill\n");
} }
...@@ -1092,7 +1107,7 @@ static int iwl_reclaim(struct iwl_priv *priv, int sta_id, int tid, ...@@ -1092,7 +1107,7 @@ static int iwl_reclaim(struct iwl_priv *priv, int sta_id, int tid,
return 1; return 1;
} }
iwl_trans_reclaim(trans(priv), txq_id, ssn, skbs); iwl_trans_reclaim(priv->trans, txq_id, ssn, skbs);
return 0; return 0;
} }
...@@ -1249,7 +1264,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, ...@@ -1249,7 +1264,7 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
* (in Tx queue's circular buffer) of first TFD/frame in window */ * (in Tx queue's circular buffer) of first TFD/frame in window */
u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn); u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
if (scd_flow >= cfg(priv)->base_params->num_of_queues) { if (scd_flow >= priv->cfg->base_params->num_of_queues) {
IWL_ERR(priv, IWL_ERR(priv,
"BUG_ON scd_flow is bigger than number of queues\n"); "BUG_ON scd_flow is bigger than number of queues\n");
return 0; return 0;
......
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
#define __iwl_agn_h__ #define __iwl_agn_h__
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-config.h"
/* The first 11 queues (0-10) are used otherwise */ /* The first 11 queues (0-10) are used otherwise */
#define IWLAGN_FIRST_AMPDU_QUEUE 11 #define IWLAGN_FIRST_AMPDU_QUEUE 11
...@@ -81,6 +82,7 @@ extern struct iwl_lib_ops iwl6000_lib; ...@@ -81,6 +82,7 @@ extern struct iwl_lib_ops iwl6000_lib;
extern struct iwl_lib_ops iwl6030_lib; extern struct iwl_lib_ops iwl6030_lib;
#define TIME_UNIT 1024
/***************************************************** /*****************************************************
* DRIVER STATUS FUNCTIONS * DRIVER STATUS FUNCTIONS
...@@ -154,7 +156,6 @@ void iwl_set_flags_for_band(struct iwl_priv *priv, ...@@ -154,7 +156,6 @@ void iwl_set_flags_for_band(struct iwl_priv *priv,
struct iwl_rxon_context *ctx, struct iwl_rxon_context *ctx,
enum ieee80211_band band, enum ieee80211_band band,
struct ieee80211_vif *vif); struct ieee80211_vif *vif);
void iwl_set_rate(struct iwl_priv *priv);
/* uCode */ /* uCode */
int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
...@@ -279,8 +280,8 @@ void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena); ...@@ -279,8 +280,8 @@ void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena);
static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv)
{ {
return cfg(priv)->bt_params && return priv->cfg->bt_params &&
cfg(priv)->bt_params->advanced_bt_coexist; priv->cfg->bt_params->advanced_bt_coexist;
} }
#ifdef CONFIG_IWLWIFI_DEBUG #ifdef CONFIG_IWLWIFI_DEBUG
...@@ -472,16 +473,29 @@ static inline void iwl_dvm_set_pmi(struct iwl_priv *priv, bool state) ...@@ -472,16 +473,29 @@ static inline void iwl_dvm_set_pmi(struct iwl_priv *priv, bool state)
set_bit(STATUS_POWER_PMI, &priv->status); set_bit(STATUS_POWER_PMI, &priv->status);
else else
clear_bit(STATUS_POWER_PMI, &priv->status); clear_bit(STATUS_POWER_PMI, &priv->status);
iwl_trans_set_pmi(trans(priv), state); iwl_trans_set_pmi(priv->trans, state);
} }
#ifdef CONFIG_IWLWIFI_DEBUGFS
int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
void iwl_dbgfs_unregister(struct iwl_priv *priv);
#else
static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
{
return 0;
}
static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
{
}
#endif /* CONFIG_IWLWIFI_DEBUGFS */
#ifdef CONFIG_IWLWIFI_DEBUG #ifdef CONFIG_IWLWIFI_DEBUG
#define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \ #define IWL_DEBUG_QUIET_RFKILL(m, fmt, args...) \
do { \ do { \
if (!iwl_is_rfkill((m))) \ if (!iwl_is_rfkill((m))) \
IWL_ERR(m, fmt, ##args); \ IWL_ERR(m, fmt, ##args); \
else \ else \
__iwl_err(trans(m)->dev, true, \ __iwl_err((m)->dev, true, \
!iwl_have_debug_level(IWL_DL_RADIO), \ !iwl_have_debug_level(IWL_DL_RADIO), \
fmt, ##args); \ fmt, ##args); \
} while (0) } while (0)
...@@ -491,7 +505,7 @@ do { \ ...@@ -491,7 +505,7 @@ do { \
if (!iwl_is_rfkill((m))) \ if (!iwl_is_rfkill((m))) \
IWL_ERR(m, fmt, ##args); \ IWL_ERR(m, fmt, ##args); \
else \ else \
__iwl_err(trans(m)->dev, true, true, fmt, ##args); \ __iwl_err((m)->dev, true, true, fmt, ##args); \
} while (0) } while (0)
#endif /* CONFIG_IWLWIFI_DEBUG */ #endif /* CONFIG_IWLWIFI_DEBUG */
......
...@@ -101,6 +101,34 @@ enum iwl_led_mode { ...@@ -101,6 +101,34 @@ enum iwl_led_mode {
IWL_LED_DISABLE, IWL_LED_DISABLE,
}; };
/*
* This is the threshold value of plcp error rate per 100mSecs. It is
* used to set and check for the validity of plcp_delta.
*/
#define IWL_MAX_PLCP_ERR_THRESHOLD_MIN 1
#define IWL_MAX_PLCP_ERR_THRESHOLD_DEF 50
#define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF 100
#define IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF 200
#define IWL_MAX_PLCP_ERR_THRESHOLD_MAX 255
#define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE 0
/* TX queue watchdog timeouts in mSecs */
#define IWL_WATCHHDOG_DISABLED 0
#define IWL_DEF_WD_TIMEOUT 2000
#define IWL_LONG_WD_TIMEOUT 10000
#define IWL_MAX_WD_TIMEOUT 120000
/* Antenna presence definitions */
#define ANT_NONE 0x0
#define ANT_A BIT(0)
#define ANT_B BIT(1)
#define ANT_C BIT(2)
#define ANT_AB (ANT_A | ANT_B)
#define ANT_AC (ANT_A | ANT_C)
#define ANT_BC (ANT_B | ANT_C)
#define ANT_ABC (ANT_A | ANT_B | ANT_C)
/* /*
* @max_ll_items: max number of OTP blocks * @max_ll_items: max number of OTP blocks
* @shadow_ram_support: shadow support for OTP memory * @shadow_ram_support: shadow support for OTP memory
......
/******************************************************************************
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2008 - 2012 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 <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <net/mac80211.h>
#include "iwl-eeprom.h"
#include "iwl-debug.h"
#include "iwl-core.h"
#include "iwl-io.h"
#include "iwl-power.h"
#include "iwl-shared.h"
#include "iwl-agn.h"
#include "iwl-trans.h"
#ifdef CONFIG_IWLWIFI_DEBUGFS
#define IWL_TRAFFIC_DUMP_SIZE (IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES)
void iwl_reset_traffic_log(struct iwl_priv *priv)
{
priv->tx_traffic_idx = 0;
priv->rx_traffic_idx = 0;
if (priv->tx_traffic)
memset(priv->tx_traffic, 0, IWL_TRAFFIC_DUMP_SIZE);
if (priv->rx_traffic)
memset(priv->rx_traffic, 0, IWL_TRAFFIC_DUMP_SIZE);
}
int iwl_alloc_traffic_mem(struct iwl_priv *priv)
{
u32 traffic_size = IWL_TRAFFIC_DUMP_SIZE;
if (iwl_have_debug_level(IWL_DL_TX)) {
if (!priv->tx_traffic) {
priv->tx_traffic =
kzalloc(traffic_size, GFP_KERNEL);
if (!priv->tx_traffic)
return -ENOMEM;
}
}
if (iwl_have_debug_level(IWL_DL_RX)) {
if (!priv->rx_traffic) {
priv->rx_traffic =
kzalloc(traffic_size, GFP_KERNEL);
if (!priv->rx_traffic)
return -ENOMEM;
}
}
iwl_reset_traffic_log(priv);
return 0;
}
void iwl_free_traffic_mem(struct iwl_priv *priv)
{
kfree(priv->tx_traffic);
priv->tx_traffic = NULL;
kfree(priv->rx_traffic);
priv->rx_traffic = NULL;
}
void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv,
u16 length, struct ieee80211_hdr *header)
{
__le16 fc;
u16 len;
if (likely(!iwl_have_debug_level(IWL_DL_TX)))
return;
if (!priv->tx_traffic)
return;
fc = header->frame_control;
if (ieee80211_is_data(fc)) {
len = (length > IWL_TRAFFIC_ENTRY_SIZE)
? IWL_TRAFFIC_ENTRY_SIZE : length;
memcpy((priv->tx_traffic +
(priv->tx_traffic_idx * IWL_TRAFFIC_ENTRY_SIZE)),
header, len);
priv->tx_traffic_idx =
(priv->tx_traffic_idx + 1) % IWL_TRAFFIC_ENTRIES;
}
}
void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv,
u16 length, struct ieee80211_hdr *header)
{
__le16 fc;
u16 len;
if (likely(!iwl_have_debug_level(IWL_DL_RX)))
return;
if (!priv->rx_traffic)
return;
fc = header->frame_control;
if (ieee80211_is_data(fc)) {
len = (length > IWL_TRAFFIC_ENTRY_SIZE)
? IWL_TRAFFIC_ENTRY_SIZE : length;
memcpy((priv->rx_traffic +
(priv->rx_traffic_idx * IWL_TRAFFIC_ENTRY_SIZE)),
header, len);
priv->rx_traffic_idx =
(priv->rx_traffic_idx + 1) % IWL_TRAFFIC_ENTRIES;
}
}
const char *get_mgmt_string(int cmd)
{
#define IWL_CMD(x) case x: return #x
switch (cmd) {
IWL_CMD(MANAGEMENT_ASSOC_REQ);
IWL_CMD(MANAGEMENT_ASSOC_RESP);
IWL_CMD(MANAGEMENT_REASSOC_REQ);
IWL_CMD(MANAGEMENT_REASSOC_RESP);
IWL_CMD(MANAGEMENT_PROBE_REQ);
IWL_CMD(MANAGEMENT_PROBE_RESP);
IWL_CMD(MANAGEMENT_BEACON);
IWL_CMD(MANAGEMENT_ATIM);
IWL_CMD(MANAGEMENT_DISASSOC);
IWL_CMD(MANAGEMENT_AUTH);
IWL_CMD(MANAGEMENT_DEAUTH);
IWL_CMD(MANAGEMENT_ACTION);
default:
return "UNKNOWN";
}
#undef IWL_CMD
}
const char *get_ctrl_string(int cmd)
{
#define IWL_CMD(x) case x: return #x
switch (cmd) {
IWL_CMD(CONTROL_BACK_REQ);
IWL_CMD(CONTROL_BACK);
IWL_CMD(CONTROL_PSPOLL);
IWL_CMD(CONTROL_RTS);
IWL_CMD(CONTROL_CTS);
IWL_CMD(CONTROL_ACK);
IWL_CMD(CONTROL_CFEND);
IWL_CMD(CONTROL_CFENDACK);
default:
return "UNKNOWN";
}
#undef IWL_CMD
}
void iwl_clear_traffic_stats(struct iwl_priv *priv)
{
memset(&priv->tx_stats, 0, sizeof(struct traffic_stats));
memset(&priv->rx_stats, 0, sizeof(struct traffic_stats));
}
/*
* if CONFIG_IWLWIFI_DEBUGFS defined, iwl_update_stats function will
* record all the MGMT, CTRL and DATA pkt for both TX and Rx pass.
* Use debugFs to display the rx/rx_statistics
* if CONFIG_IWLWIFI_DEBUGFS not being defined, then no MGMT and CTRL
* information will be recorded, but DATA pkt still will be recorded
* for the reason of iwl_led.c need to control the led blinking based on
* number of tx and rx data.
*
*/
void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len)
{
struct traffic_stats *stats;
if (is_tx)
stats = &priv->tx_stats;
else
stats = &priv->rx_stats;
if (ieee80211_is_mgmt(fc)) {
switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
stats->mgmt[MANAGEMENT_ASSOC_REQ]++;
break;
case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
stats->mgmt[MANAGEMENT_ASSOC_RESP]++;
break;
case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
stats->mgmt[MANAGEMENT_REASSOC_REQ]++;
break;
case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
stats->mgmt[MANAGEMENT_REASSOC_RESP]++;
break;
case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):
stats->mgmt[MANAGEMENT_PROBE_REQ]++;
break;
case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
stats->mgmt[MANAGEMENT_PROBE_RESP]++;
break;
case cpu_to_le16(IEEE80211_STYPE_BEACON):
stats->mgmt[MANAGEMENT_BEACON]++;
break;
case cpu_to_le16(IEEE80211_STYPE_ATIM):
stats->mgmt[MANAGEMENT_ATIM]++;
break;
case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
stats->mgmt[MANAGEMENT_DISASSOC]++;
break;
case cpu_to_le16(IEEE80211_STYPE_AUTH):
stats->mgmt[MANAGEMENT_AUTH]++;
break;
case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
stats->mgmt[MANAGEMENT_DEAUTH]++;
break;
case cpu_to_le16(IEEE80211_STYPE_ACTION):
stats->mgmt[MANAGEMENT_ACTION]++;
break;
}
} else if (ieee80211_is_ctl(fc)) {
switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
case cpu_to_le16(IEEE80211_STYPE_BACK_REQ):
stats->ctrl[CONTROL_BACK_REQ]++;
break;
case cpu_to_le16(IEEE80211_STYPE_BACK):
stats->ctrl[CONTROL_BACK]++;
break;
case cpu_to_le16(IEEE80211_STYPE_PSPOLL):
stats->ctrl[CONTROL_PSPOLL]++;
break;
case cpu_to_le16(IEEE80211_STYPE_RTS):
stats->ctrl[CONTROL_RTS]++;
break;
case cpu_to_le16(IEEE80211_STYPE_CTS):
stats->ctrl[CONTROL_CTS]++;
break;
case cpu_to_le16(IEEE80211_STYPE_ACK):
stats->ctrl[CONTROL_ACK]++;
break;
case cpu_to_le16(IEEE80211_STYPE_CFEND):
stats->ctrl[CONTROL_CFEND]++;
break;
case cpu_to_le16(IEEE80211_STYPE_CFENDACK):
stats->ctrl[CONTROL_CFENDACK]++;
break;
}
} else {
/* data */
stats->data_cnt++;
stats->data_bytes += len;
}
}
#endif
int iwl_cmd_echo_test(struct iwl_priv *priv)
{
int ret;
struct iwl_host_cmd cmd = {
.id = REPLY_ECHO,
.len = { 0 },
.flags = CMD_SYNC,
};
ret = iwl_dvm_send_cmd(priv, &cmd);
if (ret)
IWL_ERR(priv, "echo testing fail: 0X%x\n", ret);
else
IWL_DEBUG_INFO(priv, "echo testing pass\n");
return ret;
}
/******************************************************************************
*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GPL LICENSE SUMMARY
*
* Copyright(c) 2008 - 2012 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
*
* BSD LICENSE
*
* Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#ifndef __iwl_core_h__
#define __iwl_core_h__
#include "iwl-dev.h"
#include "iwl-io.h"
/************************
* forward declarations *
************************/
struct iwl_host_cmd;
struct iwl_cmd;
#define TIME_UNIT 1024
/***************************
* L i b *
***************************/
int iwl_cmd_echo_test(struct iwl_priv *priv);
#ifdef CONFIG_IWLWIFI_DEBUGFS
int iwl_alloc_traffic_mem(struct iwl_priv *priv);
void iwl_free_traffic_mem(struct iwl_priv *priv);
void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv,
u16 length, struct ieee80211_hdr *header);
void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv,
u16 length, struct ieee80211_hdr *header);
const char *get_mgmt_string(int cmd);
const char *get_ctrl_string(int cmd);
void iwl_clear_traffic_stats(struct iwl_priv *priv);
void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc,
u16 len);
void iwl_reset_traffic_log(struct iwl_priv *priv);
#else
static inline int iwl_alloc_traffic_mem(struct iwl_priv *priv)
{
return 0;
}
static inline void iwl_free_traffic_mem(struct iwl_priv *priv)
{
}
static inline void iwl_reset_traffic_log(struct iwl_priv *priv)
{
}
static inline void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv,
u16 length, struct ieee80211_hdr *header)
{
}
static inline void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv,
u16 length, struct ieee80211_hdr *header)
{
}
static inline void iwl_update_stats(struct iwl_priv *priv, bool is_tx,
__le16 fc, u16 len)
{
}
#endif
/*******************************************************************************
* Scanning
******************************************************************************/
/* traffic log definitions */
#define IWL_TRAFFIC_ENTRIES (256)
#define IWL_TRAFFIC_ENTRY_SIZE (64)
/*****************************************************
* S e n d i n g H o s t C o m m a n d s *
*****************************************************/
extern bool bt_siso_mode;
#endif /* __iwl_core_h__ */
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include "iwl-debug.h" #include "iwl-debug.h"
#include "iwl-devtrace.h"
#define __iwl_fn(fn) \ #define __iwl_fn(fn) \
void __iwl_ ##fn(struct device *dev, const char *fmt, ...) \ void __iwl_ ##fn(struct device *dev, const char *fmt, ...) \
......
...@@ -29,10 +29,13 @@ ...@@ -29,10 +29,13 @@
#ifndef __iwl_debug_h__ #ifndef __iwl_debug_h__
#define __iwl_debug_h__ #define __iwl_debug_h__
#include "iwl-shared.h" #include "iwl-modparams.h"
#include "iwl-devtrace.h"
struct iwl_priv;
static inline bool iwl_have_debug_level(u32 level)
{
return iwlwifi_mod_params.debug_level & level;
}
void __iwl_err(struct device *dev, bool rfkill_prefix, bool only_trace, void __iwl_err(struct device *dev, bool rfkill_prefix, bool only_trace,
const char *fmt, ...); const char *fmt, ...);
...@@ -41,10 +44,10 @@ void __iwl_info(struct device *dev, const char *fmt, ...); ...@@ -41,10 +44,10 @@ void __iwl_info(struct device *dev, const char *fmt, ...);
void __iwl_crit(struct device *dev, const char *fmt, ...); void __iwl_crit(struct device *dev, const char *fmt, ...);
/* No matter what is m (priv, bus, trans), this will work */ /* No matter what is m (priv, bus, trans), this will work */
#define IWL_ERR(m, f, a...) __iwl_err(trans(m)->dev, false, false, f, ## a) #define IWL_ERR(m, f, a...) __iwl_err((m)->dev, false, false, f, ## a)
#define IWL_WARN(m, f, a...) __iwl_warn(trans(m)->dev, f, ## a) #define IWL_WARN(m, f, a...) __iwl_warn((m)->dev, f, ## a)
#define IWL_INFO(m, f, a...) __iwl_info(trans(m)->dev, f, ## a) #define IWL_INFO(m, f, a...) __iwl_info((m)->dev, f, ## a)
#define IWL_CRIT(m, f, a...) __iwl_crit(trans(m)->dev, f, ## a) #define IWL_CRIT(m, f, a...) __iwl_crit((m)->dev, f, ## a)
#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING) #if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWLWIFI_DEVICE_TRACING)
void __iwl_dbg(struct device *dev, void __iwl_dbg(struct device *dev,
...@@ -65,9 +68,9 @@ do { \ ...@@ -65,9 +68,9 @@ do { \
} while (0) } while (0)
#define IWL_DEBUG(m, level, fmt, args...) \ #define IWL_DEBUG(m, level, fmt, args...) \
__iwl_dbg(trans(m)->dev, level, false, __func__, fmt, ##args) __iwl_dbg((m)->dev, level, false, __func__, fmt, ##args)
#define IWL_DEBUG_LIMIT(m, level, fmt, args...) \ #define IWL_DEBUG_LIMIT(m, level, fmt, args...) \
__iwl_dbg(trans(m)->dev, level, true, __func__, fmt, ##args) __iwl_dbg((m)->dev, level, true, __func__, fmt, ##args)
#ifdef CONFIG_IWLWIFI_DEBUG #ifdef CONFIG_IWLWIFI_DEBUG
#define iwl_print_hex_dump(m, level, p, len) \ #define iwl_print_hex_dump(m, level, p, len) \
...@@ -80,19 +83,6 @@ do { \ ...@@ -80,19 +83,6 @@ do { \
#define iwl_print_hex_dump(m, level, p, len) #define iwl_print_hex_dump(m, level, p, len)
#endif /* CONFIG_IWLWIFI_DEBUG */ #endif /* CONFIG_IWLWIFI_DEBUG */
#ifdef CONFIG_IWLWIFI_DEBUGFS
int iwl_dbgfs_register(struct iwl_priv *priv, const char *name);
void iwl_dbgfs_unregister(struct iwl_priv *priv);
#else
static inline int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
{
return 0;
}
static inline void iwl_dbgfs_unregister(struct iwl_priv *priv)
{
}
#endif /* CONFIG_IWLWIFI_DEBUGFS */
/* /*
* To use the debug system: * To use the debug system:
* *
......
...@@ -37,9 +37,9 @@ ...@@ -37,9 +37,9 @@
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-debug.h" #include "iwl-debug.h"
#include "iwl-core.h"
#include "iwl-io.h" #include "iwl-io.h"
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-modparams.h"
/* create and remove of files */ /* create and remove of files */
#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ #define DEBUGFS_ADD_FILE(name, parent, mode) do { \
...@@ -111,105 +111,6 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \ ...@@ -111,105 +111,6 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
.llseek = generic_file_llseek, \ .llseek = generic_file_llseek, \
}; };
static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos) {
struct iwl_priv *priv = file->private_data;
char *buf;
int pos = 0;
int cnt;
ssize_t ret;
const size_t bufsz = 100 +
sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf)
return -ENOMEM;
pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
pos += scnprintf(buf + pos, bufsz - pos,
"\t%25s\t\t: %u\n",
get_mgmt_string(cnt),
priv->tx_stats.mgmt[cnt]);
}
pos += scnprintf(buf + pos, bufsz - pos, "Control\n");
for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
pos += scnprintf(buf + pos, bufsz - pos,
"\t%25s\t\t: %u\n",
get_ctrl_string(cnt),
priv->tx_stats.ctrl[cnt]);
}
pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
priv->tx_stats.data_cnt);
pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
priv->tx_stats.data_bytes);
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
kfree(buf);
return ret;
}
static ssize_t iwl_dbgfs_clear_traffic_statistics_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
u32 clear_flag;
char buf[8];
int buf_size;
memset(buf, 0, sizeof(buf));
buf_size = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
if (sscanf(buf, "%x", &clear_flag) != 1)
return -EFAULT;
iwl_clear_traffic_stats(priv);
return count;
}
static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos) {
struct iwl_priv *priv = file->private_data;
char *buf;
int pos = 0;
int cnt;
ssize_t ret;
const size_t bufsz = 100 +
sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);
buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf)
return -ENOMEM;
pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");
for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {
pos += scnprintf(buf + pos, bufsz - pos,
"\t%25s\t\t: %u\n",
get_mgmt_string(cnt),
priv->rx_stats.mgmt[cnt]);
}
pos += scnprintf(buf + pos, bufsz - pos, "Control:\n");
for (cnt = 0; cnt < CONTROL_MAX; cnt++) {
pos += scnprintf(buf + pos, bufsz - pos,
"\t%25s\t\t: %u\n",
get_ctrl_string(cnt),
priv->rx_stats.ctrl[cnt]);
}
pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");
pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",
priv->rx_stats.data_cnt);
pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",
priv->rx_stats.data_bytes);
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
kfree(buf);
return ret;
}
static ssize_t iwl_dbgfs_sram_read(struct file *file, static ssize_t iwl_dbgfs_sram_read(struct file *file,
char __user *user_buf, char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
...@@ -230,10 +131,8 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, ...@@ -230,10 +131,8 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
/* default is to dump the entire data segment */ /* default is to dump the entire data segment */
if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
priv->dbgfs_sram_offset = 0x800000; priv->dbgfs_sram_offset = 0x800000;
if (!priv->ucode_loaded) { if (!priv->ucode_loaded)
IWL_ERR(priv, "No uCode has been loadded.\n");
return -EINVAL; return -EINVAL;
}
img = &priv->fw->img[priv->cur_ucode]; img = &priv->fw->img[priv->cur_ucode];
priv->dbgfs_sram_len = img->sec[IWL_UCODE_SECTION_DATA].len; priv->dbgfs_sram_len = img->sec[IWL_UCODE_SECTION_DATA].len;
} }
...@@ -259,7 +158,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, ...@@ -259,7 +158,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
sram = priv->dbgfs_sram_offset & ~0x3; sram = priv->dbgfs_sram_offset & ~0x3;
/* read the first u32 from sram */ /* read the first u32 from sram */
val = iwl_read_targ_mem(trans(priv), sram); val = iwl_read_targ_mem(priv->trans, sram);
for (; len; len--) { for (; len; len--) {
/* put the address at the start of every line */ /* put the address at the start of every line */
...@@ -278,7 +177,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, ...@@ -278,7 +177,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
if (++offset == 4) { if (++offset == 4) {
sram += 4; sram += 4;
offset = 0; offset = 0;
val = iwl_read_targ_mem(trans(priv), sram); val = iwl_read_targ_mem(priv->trans, sram);
} }
/* put in extra spaces and split lines for human readability */ /* put in extra spaces and split lines for human readability */
...@@ -408,26 +307,21 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file, ...@@ -408,26 +307,21 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
const u8 *ptr; const u8 *ptr;
char *buf; char *buf;
u16 eeprom_ver; u16 eeprom_ver;
size_t eeprom_len = cfg(priv)->base_params->eeprom_size; size_t eeprom_len = priv->cfg->base_params->eeprom_size;
buf_size = 4 * eeprom_len + 256; buf_size = 4 * eeprom_len + 256;
if (eeprom_len % 16) { if (eeprom_len % 16)
IWL_ERR(priv, "NVM size is not multiple of 16.\n");
return -ENODATA; return -ENODATA;
}
ptr = priv->eeprom; ptr = priv->eeprom;
if (!ptr) { if (!ptr)
IWL_ERR(priv, "Invalid EEPROM/OTP memory\n");
return -ENOMEM; return -ENOMEM;
}
/* 4 characters for byte 0xYY */ /* 4 characters for byte 0xYY */
buf = kzalloc(buf_size, GFP_KERNEL); buf = kzalloc(buf_size, GFP_KERNEL);
if (!buf) { if (!buf)
IWL_ERR(priv, "Can not allocate Buffer\n");
return -ENOMEM; return -ENOMEM;
}
eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, " pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, "
"version: 0x%x\n", "version: 0x%x\n",
...@@ -461,10 +355,8 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, ...@@ -461,10 +355,8 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
return -EAGAIN; return -EAGAIN;
buf = kzalloc(bufsz, GFP_KERNEL); buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf) { if (!buf)
IWL_ERR(priv, "Can not allocate Buffer\n");
return -ENOMEM; return -ENOMEM;
}
supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ); supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ);
if (supp_band) { if (supp_band) {
...@@ -566,10 +458,8 @@ static ssize_t iwl_dbgfs_rx_handlers_read(struct file *file, ...@@ -566,10 +458,8 @@ static ssize_t iwl_dbgfs_rx_handlers_read(struct file *file,
ssize_t ret; ssize_t ret;
buf = kzalloc(bufsz, GFP_KERNEL); buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf) { if (!buf)
IWL_ERR(priv, "Can not allocate Buffer\n");
return -ENOMEM; return -ENOMEM;
}
for (cnt = 0; cnt < REPLY_MAX; cnt++) { for (cnt = 0; cnt < REPLY_MAX; cnt++) {
if (priv->rx_handlers_stats[cnt] > 0) if (priv->rx_handlers_stats[cnt] > 0)
...@@ -683,11 +573,8 @@ static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file, ...@@ -683,11 +573,8 @@ static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file,
return -EFAULT; return -EFAULT;
if (!iwl_is_any_associated(priv)) if (!iwl_is_any_associated(priv))
priv->disable_ht40 = ht40 ? true : false; priv->disable_ht40 = ht40 ? true : false;
else { else
IWL_ERR(priv, "Sta associated with AP - "
"Change to 40MHz channel support is not allowed\n");
return -EINVAL; return -EINVAL;
}
return count; return count;
} }
...@@ -819,87 +706,6 @@ DEBUGFS_READ_FILE_OPS(temperature); ...@@ -819,87 +706,6 @@ DEBUGFS_READ_FILE_OPS(temperature);
DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override);
DEBUGFS_READ_FILE_OPS(current_sleep_command); DEBUGFS_READ_FILE_OPS(current_sleep_command);
static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
int pos = 0, ofs = 0;
int cnt = 0, entry;
char *buf;
int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
(cfg(priv)->base_params->num_of_queues * 32 * 8) + 400;
const u8 *ptr;
ssize_t ret;
buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf) {
IWL_ERR(priv, "Can not allocate buffer\n");
return -ENOMEM;
}
if (priv->tx_traffic && iwl_have_debug_level(IWL_DL_TX)) {
ptr = priv->tx_traffic;
pos += scnprintf(buf + pos, bufsz - pos,
"Tx Traffic idx: %u\n", priv->tx_traffic_idx);
for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
entry++, ofs += 16) {
pos += scnprintf(buf + pos, bufsz - pos,
"0x%.4x ", ofs);
hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
buf + pos, bufsz - pos, 0);
pos += strlen(buf + pos);
if (bufsz - pos > 0)
buf[pos++] = '\n';
}
}
}
if (priv->rx_traffic && iwl_have_debug_level(IWL_DL_RX)) {
ptr = priv->rx_traffic;
pos += scnprintf(buf + pos, bufsz - pos,
"Rx Traffic idx: %u\n", priv->rx_traffic_idx);
for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
entry++, ofs += 16) {
pos += scnprintf(buf + pos, bufsz - pos,
"0x%.4x ", ofs);
hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
buf + pos, bufsz - pos, 0);
pos += strlen(buf + pos);
if (bufsz - pos > 0)
buf[pos++] = '\n';
}
}
}
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
kfree(buf);
return ret;
}
static ssize_t iwl_dbgfs_traffic_log_write(struct file *file,
const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
char buf[8];
int buf_size;
int traffic_log;
memset(buf, 0, sizeof(buf));
buf_size = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
if (sscanf(buf, "%d", &traffic_log) != 1)
return -EFAULT;
if (traffic_log == 0)
iwl_reset_traffic_log(priv);
return count;
}
static const char *fmt_value = " %-30s %10u\n"; static const char *fmt_value = " %-30s %10u\n";
static const char *fmt_hex = " %-30s 0x%02X\n"; static const char *fmt_hex = " %-30s 0x%02X\n";
static const char *fmt_table = " %-30s %10u %10u %10u %10u\n"; static const char *fmt_table = " %-30s %10u %10u %10u %10u\n";
...@@ -950,10 +756,8 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, ...@@ -950,10 +756,8 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
return -EAGAIN; return -EAGAIN;
buf = kzalloc(bufsz, GFP_KERNEL); buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf) { if (!buf)
IWL_ERR(priv, "Can not allocate Buffer\n");
return -ENOMEM; return -ENOMEM;
}
/* /*
* the statistic information display here is based on * the statistic information display here is based on
...@@ -1379,10 +1183,8 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, ...@@ -1379,10 +1183,8 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
return -EAGAIN; return -EAGAIN;
buf = kzalloc(bufsz, GFP_KERNEL); buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf) { if (!buf)
IWL_ERR(priv, "Can not allocate Buffer\n");
return -ENOMEM; return -ENOMEM;
}
/* the statistic information display here is based on /* the statistic information display here is based on
* the last statistics notification from uCode * the last statistics notification from uCode
...@@ -1581,10 +1383,8 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, ...@@ -1581,10 +1383,8 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
return -EAGAIN; return -EAGAIN;
buf = kzalloc(bufsz, GFP_KERNEL); buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf) { if (!buf)
IWL_ERR(priv, "Can not allocate Buffer\n");
return -ENOMEM; return -ENOMEM;
}
/* the statistic information display here is based on /* the statistic information display here is based on
* the last statistics notification from uCode * the last statistics notification from uCode
...@@ -1707,16 +1507,11 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, ...@@ -1707,16 +1507,11 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
ret = iwl_send_statistics_request(priv, CMD_SYNC, false); ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
if (ret) { if (ret)
IWL_ERR(priv,
"Error sending statistics request: %zd\n", ret);
return -EAGAIN; return -EAGAIN;
}
buf = kzalloc(bufsz, GFP_KERNEL); buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf) { if (!buf)
IWL_ERR(priv, "Can not allocate Buffer\n");
return -ENOMEM; return -ENOMEM;
}
/* /*
* the statistic information display here is based on * the statistic information display here is based on
...@@ -1793,10 +1588,8 @@ static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file, ...@@ -1793,10 +1588,8 @@ static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file,
return -EAGAIN; return -EAGAIN;
buf = kzalloc(bufsz, GFP_KERNEL); buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf) { if (!buf)
IWL_ERR(priv, "Can not allocate Buffer\n");
return -ENOMEM; return -ENOMEM;
}
pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n"); pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n");
pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n", pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n",
...@@ -1936,10 +1729,8 @@ static ssize_t iwl_dbgfs_sensitivity_read(struct file *file, ...@@ -1936,10 +1729,8 @@ static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
data = &priv->sensitivity_data; data = &priv->sensitivity_data;
buf = kzalloc(bufsz, GFP_KERNEL); buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf) { if (!buf)
IWL_ERR(priv, "Can not allocate Buffer\n");
return -ENOMEM; return -ENOMEM;
}
pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n", pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",
data->auto_corr_ofdm); data->auto_corr_ofdm);
...@@ -2017,10 +1808,8 @@ static ssize_t iwl_dbgfs_chain_noise_read(struct file *file, ...@@ -2017,10 +1808,8 @@ static ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
data = &priv->chain_noise_data; data = &priv->chain_noise_data;
buf = kzalloc(bufsz, GFP_KERNEL); buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf) { if (!buf)
IWL_ERR(priv, "Can not allocate Buffer\n");
return -ENOMEM; return -ENOMEM;
}
pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n", pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",
data->active_chains); data->active_chains);
...@@ -2071,7 +1860,7 @@ static ssize_t iwl_dbgfs_power_save_status_read(struct file *file, ...@@ -2071,7 +1860,7 @@ static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
const size_t bufsz = sizeof(buf); const size_t bufsz = sizeof(buf);
u32 pwrsave_status; u32 pwrsave_status;
pwrsave_status = iwl_read32(trans(priv), CSR_GP_CNTRL) & pwrsave_status = iwl_read32(priv->trans, CSR_GP_CNTRL) &
CSR_GP_REG_POWER_SAVE_STATUS_MSK; CSR_GP_REG_POWER_SAVE_STATUS_MSK;
pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: "); pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");
...@@ -2380,7 +2169,7 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file, ...@@ -2380,7 +2169,7 @@ static ssize_t iwl_dbgfs_protection_mode_read(struct file *file,
char buf[40]; char buf[40];
const size_t bufsz = sizeof(buf); const size_t bufsz = sizeof(buf);
if (cfg(priv)->ht_params) if (priv->cfg->ht_params)
pos += scnprintf(buf + pos, bufsz - pos, pos += scnprintf(buf + pos, bufsz - pos,
"use %s for aggregation\n", "use %s for aggregation\n",
(priv->hw_params.use_rts_for_aggregation) ? (priv->hw_params.use_rts_for_aggregation) ?
...@@ -2400,7 +2189,7 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, ...@@ -2400,7 +2189,7 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
int buf_size; int buf_size;
int rts; int rts;
if (!cfg(priv)->ht_params) if (!priv->cfg->ht_params)
return -EINVAL; return -EINVAL;
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
...@@ -2416,6 +2205,23 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, ...@@ -2416,6 +2205,23 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
return count; return count;
} }
static int iwl_cmd_echo_test(struct iwl_priv *priv)
{
int ret;
struct iwl_host_cmd cmd = {
.id = REPLY_ECHO,
.len = { 0 },
.flags = CMD_SYNC,
};
ret = iwl_dvm_send_cmd(priv, &cmd);
if (ret)
IWL_ERR(priv, "echo testing fail: 0X%x\n", ret);
else
IWL_DEBUG_INFO(priv, "echo testing pass\n");
return ret;
}
static ssize_t iwl_dbgfs_echo_test_write(struct file *file, static ssize_t iwl_dbgfs_echo_test_write(struct file *file,
const char __user *user_buf, const char __user *user_buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
...@@ -2499,9 +2305,27 @@ static ssize_t iwl_dbgfs_calib_disabled_read(struct file *file, ...@@ -2499,9 +2305,27 @@ static ssize_t iwl_dbgfs_calib_disabled_read(struct file *file,
return simple_read_from_buffer(user_buf, count, ppos, buf, pos); return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
} }
DEBUGFS_READ_FILE_OPS(rx_statistics); static ssize_t iwl_dbgfs_calib_disabled_write(struct file *file,
DEBUGFS_READ_FILE_OPS(tx_statistics); const char __user *user_buf,
DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); size_t count, loff_t *ppos)
{
struct iwl_priv *priv = file->private_data;
char buf[8];
u32 calib_disabled;
int buf_size;
memset(buf, 0, sizeof(buf));
buf_size = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
if (sscanf(buf, "%x", &calib_disabled) != 1)
return -EFAULT;
priv->calib_disabled = calib_disabled;
return count;
}
DEBUGFS_READ_FILE_OPS(ucode_rx_stats); DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
DEBUGFS_READ_FILE_OPS(ucode_tx_stats); DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
DEBUGFS_READ_FILE_OPS(ucode_general_stats); DEBUGFS_READ_FILE_OPS(ucode_general_stats);
...@@ -2509,7 +2333,6 @@ DEBUGFS_READ_FILE_OPS(sensitivity); ...@@ -2509,7 +2333,6 @@ DEBUGFS_READ_FILE_OPS(sensitivity);
DEBUGFS_READ_FILE_OPS(chain_noise); DEBUGFS_READ_FILE_OPS(chain_noise);
DEBUGFS_READ_FILE_OPS(power_save_status); DEBUGFS_READ_FILE_OPS(power_save_status);
DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing);
DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);
DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta);
...@@ -2523,7 +2346,7 @@ DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); ...@@ -2523,7 +2346,7 @@ DEBUGFS_READ_WRITE_FILE_OPS(protection_mode);
DEBUGFS_READ_FILE_OPS(reply_tx_error); DEBUGFS_READ_FILE_OPS(reply_tx_error);
DEBUGFS_WRITE_FILE_OPS(echo_test); DEBUGFS_WRITE_FILE_OPS(echo_test);
DEBUGFS_READ_WRITE_FILE_OPS(log_event); DEBUGFS_READ_WRITE_FILE_OPS(log_event);
DEBUGFS_READ_FILE_OPS(calib_disabled); DEBUGFS_READ_WRITE_FILE_OPS(calib_disabled);
/* /*
* Create the debugfs files and directories * Create the debugfs files and directories
...@@ -2564,12 +2387,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) ...@@ -2564,12 +2387,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(temperature, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(temperature, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(rf_reset, dir_debug, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(rf_reset, dir_debug, S_IWUSR | S_IRUSR);
...@@ -2592,9 +2411,9 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) ...@@ -2592,9 +2411,9 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
/* Calibrations disabled/enabled status*/ /* Calibrations disabled/enabled status*/
DEBUGFS_ADD_FILE(calib_disabled, dir_rf, S_IRUSR); DEBUGFS_ADD_FILE(calib_disabled, dir_rf, S_IWUSR | S_IRUSR);
if (iwl_trans_dbgfs_register(trans(priv), dir_debug)) if (iwl_trans_dbgfs_register(priv->trans, dir_debug))
goto err; goto err;
return 0; return 0;
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include "iwl-fw.h"
#include "iwl-eeprom.h" #include "iwl-eeprom.h"
#include "iwl-csr.h" #include "iwl-csr.h"
#include "iwl-debug.h" #include "iwl-debug.h"
...@@ -47,7 +48,6 @@ ...@@ -47,7 +48,6 @@
#include "iwl-agn-rs.h" #include "iwl-agn-rs.h"
#include "iwl-agn-tt.h" #include "iwl-agn-tt.h"
#include "iwl-trans.h" #include "iwl-trans.h"
#include "iwl-shared.h"
#include "iwl-op-mode.h" #include "iwl-op-mode.h"
#include "iwl-notif-wait.h" #include "iwl-notif-wait.h"
...@@ -194,6 +194,7 @@ struct iwl_qos_info { ...@@ -194,6 +194,7 @@ struct iwl_qos_info {
* These states relate to a specific RA / TID. * These states relate to a specific RA / TID.
* *
* @IWL_AGG_OFF: aggregation is not used * @IWL_AGG_OFF: aggregation is not used
* @IWL_AGG_STARTING: aggregation are starting (between start and oper)
* @IWL_AGG_ON: aggregation session is up * @IWL_AGG_ON: aggregation session is up
* @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the * @IWL_EMPTYING_HW_QUEUE_ADDBA: establishing a BA session - waiting for the
* HW queue to be empty from packets for this RA /TID. * HW queue to be empty from packets for this RA /TID.
...@@ -202,6 +203,7 @@ struct iwl_qos_info { ...@@ -202,6 +203,7 @@ struct iwl_qos_info {
*/ */
enum iwl_agg_state { enum iwl_agg_state {
IWL_AGG_OFF = 0, IWL_AGG_OFF = 0,
IWL_AGG_STARTING,
IWL_AGG_ON, IWL_AGG_ON,
IWL_EMPTYING_HW_QUEUE_ADDBA, IWL_EMPTYING_HW_QUEUE_ADDBA,
IWL_EMPTYING_HW_QUEUE_DELBA, IWL_EMPTYING_HW_QUEUE_DELBA,
...@@ -504,44 +506,6 @@ struct reply_agg_tx_error_statistics { ...@@ -504,44 +506,6 @@ struct reply_agg_tx_error_statistics {
u32 unknown; u32 unknown;
}; };
/* management statistics */
enum iwl_mgmt_stats {
MANAGEMENT_ASSOC_REQ = 0,
MANAGEMENT_ASSOC_RESP,
MANAGEMENT_REASSOC_REQ,
MANAGEMENT_REASSOC_RESP,
MANAGEMENT_PROBE_REQ,
MANAGEMENT_PROBE_RESP,
MANAGEMENT_BEACON,
MANAGEMENT_ATIM,
MANAGEMENT_DISASSOC,
MANAGEMENT_AUTH,
MANAGEMENT_DEAUTH,
MANAGEMENT_ACTION,
MANAGEMENT_MAX,
};
/* control statistics */
enum iwl_ctrl_stats {
CONTROL_BACK_REQ = 0,
CONTROL_BACK,
CONTROL_PSPOLL,
CONTROL_RTS,
CONTROL_CTS,
CONTROL_ACK,
CONTROL_CFEND,
CONTROL_CFENDACK,
CONTROL_MAX,
};
struct traffic_stats {
#ifdef CONFIG_IWLWIFI_DEBUGFS
u32 mgmt[MANAGEMENT_MAX];
u32 ctrl[CONTROL_MAX];
u32 data_cnt;
u64 data_bytes;
#endif
};
/* /*
* schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds
* to perform continuous uCode event logging operation if enabled * to perform continuous uCode event logging operation if enabled
...@@ -568,25 +532,8 @@ struct iwl_event_log { ...@@ -568,25 +532,8 @@ struct iwl_event_log {
int wraps_more_count; int wraps_more_count;
}; };
/*
* This is the threshold value of plcp error rate per 100mSecs. It is
* used to set and check for the validity of plcp_delta.
*/
#define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (1)
#define IWL_MAX_PLCP_ERR_THRESHOLD_DEF (50)
#define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF (100)
#define IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF (200)
#define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255)
#define IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE (0)
#define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3) #define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3)
/* TX queue watchdog timeouts in mSecs */
#define IWL_WATCHHDOG_DISABLED (0)
#define IWL_DEF_WD_TIMEOUT (2000)
#define IWL_LONG_WD_TIMEOUT (10000)
#define IWL_MAX_WD_TIMEOUT (120000)
/* BT Antenna Coupling Threshold (dB) */ /* BT Antenna Coupling Threshold (dB) */
#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) #define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35)
...@@ -602,6 +549,13 @@ struct iwl_rf_reset { ...@@ -602,6 +549,13 @@ struct iwl_rf_reset {
unsigned long last_reset_jiffies; unsigned long last_reset_jiffies;
}; };
enum iwl_rxon_context_id {
IWL_RXON_CTX_BSS,
IWL_RXON_CTX_PAN,
NUM_IWL_RXON_CTX
};
/* extend beacon time format bit shifting */ /* extend beacon time format bit shifting */
/* /*
* for _agn devices * for _agn devices
...@@ -742,12 +696,15 @@ struct iwl_wipan_noa_data { ...@@ -742,12 +696,15 @@ struct iwl_wipan_noa_data {
}; };
/* Calibration disabling bit mask */ /* Calibration disabling bit mask */
#define IWL_SENSITIVITY_CALIB_DISABLED BIT(1) enum {
#define IWL_CHAIN_NOISE_CALIB_DISABLED BIT(2) IWL_CALIB_ENABLE_ALL = 0,
#define IWL_TX_POWER_CALIB_DISABLED BIT(3)
IWL_SENSITIVITY_CALIB_DISABLED = BIT(0),
IWL_CHAIN_NOISE_CALIB_DISABLED = BIT(1),
IWL_TX_POWER_CALIB_DISABLED = BIT(2),
#define IWL_CALIB_ENABLE_ALL 0 IWL_CALIB_DISABLE_ALL = 0xFFFFFFFF,
#define IWL_CALIB_DISABLE_ALL 0xFFFFFFFF };
#define IWL_OP_MODE_GET_DVM(_iwl_op_mode) \ #define IWL_OP_MODE_GET_DVM(_iwl_op_mode) \
((struct iwl_priv *) ((_iwl_op_mode)->op_mode_specific)) ((struct iwl_priv *) ((_iwl_op_mode)->op_mode_specific))
...@@ -758,8 +715,9 @@ struct iwl_wipan_noa_data { ...@@ -758,8 +715,9 @@ struct iwl_wipan_noa_data {
struct iwl_priv { struct iwl_priv {
/*data shared among all the driver's layers */ struct iwl_trans *trans;
struct iwl_shared *shrd; struct device *dev; /* for debug prints only */
const struct iwl_cfg *cfg;
const struct iwl_fw *fw; const struct iwl_fw *fw;
const struct iwl_lib_ops *lib; const struct iwl_lib_ops *lib;
unsigned long status; unsigned long status;
...@@ -769,9 +727,9 @@ struct iwl_priv { ...@@ -769,9 +727,9 @@ struct iwl_priv {
unsigned long transport_queue_stop; unsigned long transport_queue_stop;
bool passive_no_rx; bool passive_no_rx;
#define IWL_INVALID_AC 0xff #define IWL_INVALID_MAC80211_QUEUE 0xff
u8 queue_to_ac[IWL_MAX_HW_QUEUES]; u8 queue_to_mac80211[IWL_MAX_HW_QUEUES];
atomic_t ac_stop_count[IEEE80211_NUM_ACS]; atomic_t queue_stop_count[IWL_MAX_HW_QUEUES];
unsigned long agg_q_alloc[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; unsigned long agg_q_alloc[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)];
...@@ -880,10 +838,6 @@ struct iwl_priv { ...@@ -880,10 +838,6 @@ struct iwl_priv {
int activity_timer_active; int activity_timer_active;
/* counts mgmt, ctl, and data packets */
struct traffic_stats tx_stats;
struct traffic_stats rx_stats;
struct iwl_power_mgr power_data; struct iwl_power_mgr power_data;
struct iwl_tt_mgmt thermal_throttle; struct iwl_tt_mgmt thermal_throttle;
...@@ -1003,10 +957,6 @@ struct iwl_priv { ...@@ -1003,10 +957,6 @@ struct iwl_priv {
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
/* debugfs */ /* debugfs */
u16 tx_traffic_idx;
u16 rx_traffic_idx;
u8 *tx_traffic;
u8 *rx_traffic;
struct dentry *debugfs_dir; struct dentry *debugfs_dir;
u32 dbgfs_sram_offset, dbgfs_sram_len; u32 dbgfs_sram_offset, dbgfs_sram_len;
bool disable_ht40; bool disable_ht40;
...@@ -1051,7 +1001,6 @@ struct iwl_priv { ...@@ -1051,7 +1001,6 @@ struct iwl_priv {
}; /*iwl_priv */ }; /*iwl_priv */
extern struct kmem_cache *iwl_tx_cmd_pool; extern struct kmem_cache *iwl_tx_cmd_pool;
extern struct iwl_mod_params iwlagn_mod_params;
static inline struct iwl_rxon_context * static inline struct iwl_rxon_context *
iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif) iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif)
......
...@@ -67,9 +67,11 @@ ...@@ -67,9 +67,11 @@
#include "iwl-drv.h" #include "iwl-drv.h"
#include "iwl-trans.h" #include "iwl-trans.h"
#include "iwl-shared.h"
#include "iwl-op-mode.h" #include "iwl-op-mode.h"
#include "iwl-agn-hw.h" #include "iwl-agn-hw.h"
#include "iwl-fw.h"
#include "iwl-config.h"
#include "iwl-modparams.h"
/* private includes */ /* private includes */
#include "iwl-fw-file.h" #include "iwl-fw-file.h"
...@@ -77,8 +79,10 @@ ...@@ -77,8 +79,10 @@
/** /**
* struct iwl_drv - drv common data * struct iwl_drv - drv common data
* @fw: the iwl_fw structure * @fw: the iwl_fw structure
* @shrd: pointer to common shared structure
* @op_mode: the running op_mode * @op_mode: the running op_mode
* @trans: transport layer
* @dev: for debug prints only
* @cfg: configuration struct
* @fw_index: firmware revision to try loading * @fw_index: firmware revision to try loading
* @firmware_name: composite filename of ucode file to load * @firmware_name: composite filename of ucode file to load
* @request_firmware_complete: the firmware has been obtained from user space * @request_firmware_complete: the firmware has been obtained from user space
...@@ -86,8 +90,10 @@ ...@@ -86,8 +90,10 @@
struct iwl_drv { struct iwl_drv {
struct iwl_fw fw; struct iwl_fw fw;
struct iwl_shared *shrd;
struct iwl_op_mode *op_mode; struct iwl_op_mode *op_mode;
struct iwl_trans *trans;
struct device *dev;
const struct iwl_cfg *cfg;
int fw_index; /* firmware we're trying to load */ int fw_index; /* firmware we're trying to load */
char firmware_name[25]; /* name of firmware file to load */ char firmware_name[25]; /* name of firmware file to load */
...@@ -110,7 +116,7 @@ struct fw_sec { ...@@ -110,7 +116,7 @@ struct fw_sec {
static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc)
{ {
if (desc->v_addr) if (desc->v_addr)
dma_free_coherent(trans(drv)->dev, desc->len, dma_free_coherent(drv->trans->dev, desc->len,
desc->v_addr, desc->p_addr); desc->v_addr, desc->p_addr);
desc->v_addr = NULL; desc->v_addr = NULL;
desc->len = 0; desc->len = 0;
...@@ -138,7 +144,7 @@ static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, ...@@ -138,7 +144,7 @@ static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc,
return -EINVAL; return -EINVAL;
} }
desc->v_addr = dma_alloc_coherent(trans(drv)->dev, sec->size, desc->v_addr = dma_alloc_coherent(drv->trans->dev, sec->size,
&desc->p_addr, GFP_KERNEL); &desc->p_addr, GFP_KERNEL);
if (!desc->v_addr) if (!desc->v_addr)
return -ENOMEM; return -ENOMEM;
...@@ -156,8 +162,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); ...@@ -156,8 +162,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
static int iwl_request_firmware(struct iwl_drv *drv, bool first) static int iwl_request_firmware(struct iwl_drv *drv, bool first)
{ {
const struct iwl_cfg *cfg = cfg(drv); const char *name_pre = drv->cfg->fw_name_pre;
const char *name_pre = cfg->fw_name_pre;
char tag[8]; char tag[8];
if (first) { if (first) {
...@@ -166,14 +171,14 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) ...@@ -166,14 +171,14 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
strcpy(tag, UCODE_EXPERIMENTAL_TAG); strcpy(tag, UCODE_EXPERIMENTAL_TAG);
} else if (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) { } else if (drv->fw_index == UCODE_EXPERIMENTAL_INDEX) {
#endif #endif
drv->fw_index = cfg->ucode_api_max; drv->fw_index = drv->cfg->ucode_api_max;
sprintf(tag, "%d", drv->fw_index); sprintf(tag, "%d", drv->fw_index);
} else { } else {
drv->fw_index--; drv->fw_index--;
sprintf(tag, "%d", drv->fw_index); sprintf(tag, "%d", drv->fw_index);
} }
if (drv->fw_index < cfg->ucode_api_min) { if (drv->fw_index < drv->cfg->ucode_api_min) {
IWL_ERR(drv, "no suitable firmware found!\n"); IWL_ERR(drv, "no suitable firmware found!\n");
return -ENOENT; return -ENOENT;
} }
...@@ -186,7 +191,7 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) ...@@ -186,7 +191,7 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first)
drv->firmware_name); drv->firmware_name);
return request_firmware_nowait(THIS_MODULE, 1, drv->firmware_name, return request_firmware_nowait(THIS_MODULE, 1, drv->firmware_name,
trans(drv)->dev, drv->trans->dev,
GFP_KERNEL, drv, iwl_ucode_callback); GFP_KERNEL, drv, iwl_ucode_callback);
} }
...@@ -725,14 +730,13 @@ static int validate_sec_sizes(struct iwl_drv *drv, ...@@ -725,14 +730,13 @@ static int validate_sec_sizes(struct iwl_drv *drv,
static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
{ {
struct iwl_drv *drv = context; struct iwl_drv *drv = context;
const struct iwl_cfg *cfg = cfg(drv);
struct iwl_fw *fw = &drv->fw; struct iwl_fw *fw = &drv->fw;
struct iwl_ucode_header *ucode; struct iwl_ucode_header *ucode;
int err; int err;
struct iwl_firmware_pieces pieces; struct iwl_firmware_pieces pieces;
const unsigned int api_max = cfg->ucode_api_max; const unsigned int api_max = drv->cfg->ucode_api_max;
unsigned int api_ok = cfg->ucode_api_ok; unsigned int api_ok = drv->cfg->ucode_api_ok;
const unsigned int api_min = cfg->ucode_api_min; const unsigned int api_min = drv->cfg->ucode_api_min;
u32 api_ver; u32 api_ver;
int i; int i;
...@@ -811,7 +815,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) ...@@ -811,7 +815,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
* In mvm uCode there is no difference between data and instructions * In mvm uCode there is no difference between data and instructions
* sections. * sections.
*/ */
if (!fw->mvm_fw && validate_sec_sizes(drv, &pieces, cfg)) if (!fw->mvm_fw && validate_sec_sizes(drv, &pieces, drv->cfg))
goto try_again; goto try_again;
/* Allocate ucode buffers for card's bus-master loading ... */ /* Allocate ucode buffers for card's bus-master loading ... */
...@@ -835,14 +839,14 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) ...@@ -835,14 +839,14 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
fw->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; fw->init_evtlog_size = (pieces.init_evtlog_size - 16)/12;
else else
fw->init_evtlog_size = fw->init_evtlog_size =
cfg->base_params->max_event_log_size; drv->cfg->base_params->max_event_log_size;
fw->init_errlog_ptr = pieces.init_errlog_ptr; fw->init_errlog_ptr = pieces.init_errlog_ptr;
fw->inst_evtlog_ptr = pieces.inst_evtlog_ptr; fw->inst_evtlog_ptr = pieces.inst_evtlog_ptr;
if (pieces.inst_evtlog_size) if (pieces.inst_evtlog_size)
fw->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; fw->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12;
else else
fw->inst_evtlog_size = fw->inst_evtlog_size =
cfg->base_params->max_event_log_size; drv->cfg->base_params->max_event_log_size;
fw->inst_errlog_ptr = pieces.inst_errlog_ptr; fw->inst_errlog_ptr = pieces.inst_errlog_ptr;
/* /*
...@@ -858,7 +862,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) ...@@ -858,7 +862,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
release_firmware(ucode_raw); release_firmware(ucode_raw);
complete(&drv->request_firmware_complete); complete(&drv->request_firmware_complete);
drv->op_mode = iwl_dvm_ops.start(drv->shrd->trans, &drv->fw); drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw);
if (!drv->op_mode) if (!drv->op_mode)
goto out_unbind; goto out_unbind;
...@@ -878,24 +882,23 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) ...@@ -878,24 +882,23 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
release_firmware(ucode_raw); release_firmware(ucode_raw);
out_unbind: out_unbind:
complete(&drv->request_firmware_complete); complete(&drv->request_firmware_complete);
device_release_driver(trans(drv)->dev); device_release_driver(drv->trans->dev);
} }
int iwl_drv_start(struct iwl_shared *shrd, struct iwl_drv *iwl_drv_start(struct iwl_trans *trans,
struct iwl_trans *trans, const struct iwl_cfg *cfg) const struct iwl_cfg *cfg)
{ {
struct iwl_drv *drv; struct iwl_drv *drv;
int ret; int ret;
shrd->cfg = cfg;
drv = kzalloc(sizeof(*drv), GFP_KERNEL); drv = kzalloc(sizeof(*drv), GFP_KERNEL);
if (!drv) { if (!drv) {
dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_drv"); dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_drv");
return -ENOMEM; return NULL;
} }
drv->shrd = shrd; drv->trans = trans;
shrd->drv = drv; drv->dev = trans->dev;
drv->cfg = cfg;
init_completion(&drv->request_firmware_complete); init_completion(&drv->request_firmware_complete);
...@@ -904,16 +907,14 @@ int iwl_drv_start(struct iwl_shared *shrd, ...@@ -904,16 +907,14 @@ int iwl_drv_start(struct iwl_shared *shrd,
if (ret) { if (ret) {
dev_printk(KERN_ERR, trans->dev, "Couldn't request the fw"); dev_printk(KERN_ERR, trans->dev, "Couldn't request the fw");
kfree(drv); kfree(drv);
shrd->drv = NULL; drv = NULL;
} }
return ret; return drv;
} }
void iwl_drv_stop(struct iwl_shared *shrd) void iwl_drv_stop(struct iwl_drv *drv)
{ {
struct iwl_drv *drv = shrd->drv;
wait_for_completion(&drv->request_firmware_complete); wait_for_completion(&drv->request_firmware_complete);
/* op_mode can be NULL if its start failed */ /* op_mode can be NULL if its start failed */
...@@ -923,5 +924,91 @@ void iwl_drv_stop(struct iwl_shared *shrd) ...@@ -923,5 +924,91 @@ void iwl_drv_stop(struct iwl_shared *shrd)
iwl_dealloc_ucode(drv); iwl_dealloc_ucode(drv);
kfree(drv); kfree(drv);
shrd->drv = NULL;
} }
/* shared module parameters */
struct iwl_mod_params iwlwifi_mod_params = {
.amsdu_size_8K = 1,
.restart_fw = 1,
.plcp_check = true,
.bt_coex_active = true,
.power_level = IWL_POWER_INDEX_1,
.bt_ch_announce = true,
.auto_agg = true,
/* the rest are 0 by default */
};
#ifdef CONFIG_IWLWIFI_DEBUG
module_param_named(debug, iwlwifi_mod_params.debug_level, uint,
S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "debug output mask");
#endif
module_param_named(swcrypto, iwlwifi_mod_params.sw_crypto, int, S_IRUGO);
MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
module_param_named(11n_disable, iwlwifi_mod_params.disable_11n, uint, S_IRUGO);
MODULE_PARM_DESC(11n_disable,
"disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX");
module_param_named(amsdu_size_8K, iwlwifi_mod_params.amsdu_size_8K,
int, S_IRUGO);
MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
module_param_named(fw_restart, iwlwifi_mod_params.restart_fw, int, S_IRUGO);
MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling,
int, S_IRUGO);
MODULE_PARM_DESC(antenna_coupling,
"specify antenna coupling in dB (defualt: 0 dB)");
module_param_named(bt_ch_inhibition, iwlwifi_mod_params.bt_ch_announce,
bool, S_IRUGO);
MODULE_PARM_DESC(bt_ch_inhibition,
"Enable BT channel inhibition (default: enable)");
module_param_named(plcp_check, iwlwifi_mod_params.plcp_check, bool, S_IRUGO);
MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])");
module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO);
MODULE_PARM_DESC(wd_disable,
"Disable stuck queue watchdog timer 0=system default, "
"1=disable, 2=enable (default: 0)");
/*
* set bt_coex_active to true, uCode will do kill/defer
* every time the priority line is asserted (BT is sending signals on the
* priority line in the PCIx).
* set bt_coex_active to false, uCode will ignore the BT activity and
* perform the normal operation
*
* User might experience transmit issue on some platform due to WiFi/BT
* co-exist problem. The possible behaviors are:
* Able to scan and finding all the available AP
* Not able to associate with any AP
* On those platforms, WiFi communication can be restored by set
* "bt_coex_active" module parameter to "false"
*
* default: bt_coex_active = true (BT_COEX_ENABLE)
*/
module_param_named(bt_coex_active, iwlwifi_mod_params.bt_coex_active,
bool, S_IRUGO);
MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)");
module_param_named(led_mode, iwlwifi_mod_params.led_mode, int, S_IRUGO);
MODULE_PARM_DESC(led_mode, "0=system default, "
"1=On(RF On)/Off(RF Off), 2=blinking, 3=Off (default: 0)");
module_param_named(power_save, iwlwifi_mod_params.power_save,
bool, S_IRUGO);
MODULE_PARM_DESC(power_save,
"enable WiFi power management (default: disable)");
module_param_named(power_level, iwlwifi_mod_params.power_level,
int, S_IRUGO);
MODULE_PARM_DESC(power_level,
"default power save level (range from 1 - 5, default: 1)");
module_param_named(auto_agg, iwlwifi_mod_params.auto_agg,
bool, S_IRUGO);
MODULE_PARM_DESC(auto_agg,
"enable agg w/o check traffic load (default: enable)");
...@@ -63,7 +63,12 @@ ...@@ -63,7 +63,12 @@
#ifndef __iwl_drv_h__ #ifndef __iwl_drv_h__
#define __iwl_drv_h__ #define __iwl_drv_h__
#include "iwl-shared.h" /* for all modules */
#define DRV_NAME "iwlwifi"
#define IWLWIFI_VERSION "in-tree:"
#define DRV_COPYRIGHT "Copyright(c) 2003-2012 Intel Corporation"
#define DRV_AUTHOR "<ilw@linux.intel.com>"
/** /**
* DOC: Driver system flows - drv component * DOC: Driver system flows - drv component
...@@ -90,34 +95,32 @@ ...@@ -90,34 +95,32 @@
* 8) iwl_ucode_callback starts the wifi implementation to matches the fw * 8) iwl_ucode_callback starts the wifi implementation to matches the fw
*/ */
struct iwl_drv;
struct iwl_trans;
struct iwl_cfg;
/** /**
* iwl_drv_start - start the drv * iwl_drv_start - start the drv
* *
* @shrd: the shrd area
* @trans_ops: the ops of the transport * @trans_ops: the ops of the transport
* @cfg: device specific constants / virtual functions * @cfg: device specific constants / virtual functions
* *
* TODO: review the parameters given to this function
*
* starts the driver: fetches the firmware. This should be called by bus * starts the driver: fetches the firmware. This should be called by bus
* specific system flows implementations. For example, the bus specific probe * specific system flows implementations. For example, the bus specific probe
* function should do bus related operations only, and then call to this * function should do bus related operations only, and then call to this
* function. * function. It returns the driver object or %NULL if an error occured.
*/ */
int iwl_drv_start(struct iwl_shared *shrd, struct iwl_drv *iwl_drv_start(struct iwl_trans *trans,
struct iwl_trans *trans, const struct iwl_cfg *cfg); const struct iwl_cfg *cfg);
/** /**
* iwl_drv_stop - stop the drv * iwl_drv_stop - stop the drv
* *
* @shrd: the shrd area * @drv:
*
* TODO: review the parameters given to this function
* *
* Stop the driver. This should be called by bus specific system flows * Stop the driver. This should be called by bus specific system flows
* implementations. For example, the bus specific remove function should first * implementations. For example, the bus specific remove function should first
* call this function and then do the bus related operations only. * call this function and then do the bus related operations only.
*/ */
void iwl_drv_stop(struct iwl_shared *shrd); void iwl_drv_stop(struct iwl_drv *drv);
#endif /* __iwl_drv_h__ */ #endif /* __iwl_drv_h__ */
...@@ -68,9 +68,7 @@ ...@@ -68,9 +68,7 @@
#include <net/mac80211.h> #include <net/mac80211.h>
#include "iwl-commands.h"
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-debug.h" #include "iwl-debug.h"
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-eeprom.h" #include "iwl-eeprom.h"
...@@ -189,7 +187,7 @@ static void iwl_eeprom_release_semaphore(struct iwl_trans *trans) ...@@ -189,7 +187,7 @@ static void iwl_eeprom_release_semaphore(struct iwl_trans *trans)
static int iwl_eeprom_verify_signature(struct iwl_priv *priv) static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
{ {
u32 gp = iwl_read32(trans(priv), CSR_EEPROM_GP) & u32 gp = iwl_read32(priv->trans, CSR_EEPROM_GP) &
CSR_EEPROM_GP_VALID_MSK; CSR_EEPROM_GP_VALID_MSK;
int ret = 0; int ret = 0;
...@@ -236,8 +234,8 @@ int iwl_eeprom_check_version(struct iwl_priv *priv) ...@@ -236,8 +234,8 @@ int iwl_eeprom_check_version(struct iwl_priv *priv)
eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
calib_ver = iwl_eeprom_calib_version(priv); calib_ver = iwl_eeprom_calib_version(priv);
if (eeprom_ver < cfg(priv)->eeprom_ver || if (eeprom_ver < priv->cfg->eeprom_ver ||
calib_ver < cfg(priv)->eeprom_calib_ver) calib_ver < priv->cfg->eeprom_calib_ver)
goto err; goto err;
IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n", IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n",
...@@ -247,8 +245,8 @@ int iwl_eeprom_check_version(struct iwl_priv *priv) ...@@ -247,8 +245,8 @@ int iwl_eeprom_check_version(struct iwl_priv *priv)
err: err:
IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x " IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x "
"CALIB=0x%x < 0x%x\n", "CALIB=0x%x < 0x%x\n",
eeprom_ver, cfg(priv)->eeprom_ver, eeprom_ver, priv->cfg->eeprom_ver,
calib_ver, cfg(priv)->eeprom_calib_ver); calib_ver, priv->cfg->eeprom_calib_ver);
return -EINVAL; return -EINVAL;
} }
...@@ -259,7 +257,7 @@ int iwl_eeprom_init_hw_params(struct iwl_priv *priv) ...@@ -259,7 +257,7 @@ int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
priv->hw_params.sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP); priv->hw_params.sku = iwl_eeprom_query16(priv, EEPROM_SKU_CAP);
if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE && if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE &&
!cfg(priv)->ht_params) { !priv->cfg->ht_params) {
IWL_ERR(priv, "Invalid 11n configuration\n"); IWL_ERR(priv, "Invalid 11n configuration\n");
return -EINVAL; return -EINVAL;
} }
...@@ -277,10 +275,10 @@ int iwl_eeprom_init_hw_params(struct iwl_priv *priv) ...@@ -277,10 +275,10 @@ int iwl_eeprom_init_hw_params(struct iwl_priv *priv)
priv->hw_params.valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg); priv->hw_params.valid_rx_ant = EEPROM_RF_CFG_RX_ANT_MSK(radio_cfg);
/* check overrides (some devices have wrong EEPROM) */ /* check overrides (some devices have wrong EEPROM) */
if (cfg(priv)->valid_tx_ant) if (priv->cfg->valid_tx_ant)
priv->hw_params.valid_tx_ant = cfg(priv)->valid_tx_ant; priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
if (cfg(priv)->valid_rx_ant) if (priv->cfg->valid_rx_ant)
priv->hw_params.valid_rx_ant = cfg(priv)->valid_rx_ant; priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
if (!priv->hw_params.valid_tx_ant || !priv->hw_params.valid_rx_ant) { if (!priv->hw_params.valid_tx_ant || !priv->hw_params.valid_rx_ant) {
IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n", IWL_ERR(priv, "Invalid chain (0x%X, 0x%X)\n",
...@@ -349,7 +347,7 @@ static u32 eeprom_indirect_address(struct iwl_priv *priv, u32 address) ...@@ -349,7 +347,7 @@ static u32 eeprom_indirect_address(struct iwl_priv *priv, u32 address)
const u8 *iwl_eeprom_query_addr(struct iwl_priv *priv, size_t offset) const u8 *iwl_eeprom_query_addr(struct iwl_priv *priv, size_t offset)
{ {
u32 address = eeprom_indirect_address(priv, offset); u32 address = eeprom_indirect_address(priv, offset);
BUG_ON(address >= cfg(priv)->base_params->eeprom_size); BUG_ON(address >= priv->cfg->base_params->eeprom_size);
return &priv->eeprom[address]; return &priv->eeprom[address];
} }
...@@ -433,7 +431,7 @@ static int iwl_init_otp_access(struct iwl_trans *trans) ...@@ -433,7 +431,7 @@ static int iwl_init_otp_access(struct iwl_trans *trans)
* CSR auto clock gate disable bit - * CSR auto clock gate disable bit -
* this is only applicable for HW with OTP shadow RAM * this is only applicable for HW with OTP shadow RAM
*/ */
if (cfg(trans)->base_params->shadow_ram_support) if (trans->cfg->base_params->shadow_ram_support)
iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG, iwl_set_bit(trans, CSR_DBG_LINK_PWR_MGMT_REG,
CSR_RESET_LINK_PWR_MGMT_DISABLED); CSR_RESET_LINK_PWR_MGMT_DISABLED);
} }
...@@ -554,7 +552,7 @@ static int iwl_find_otp_image(struct iwl_trans *trans, ...@@ -554,7 +552,7 @@ static int iwl_find_otp_image(struct iwl_trans *trans,
} }
/* more in the link list, continue */ /* more in the link list, continue */
usedblocks++; usedblocks++;
} while (usedblocks <= cfg(trans)->base_params->max_ll_items); } while (usedblocks <= trans->cfg->base_params->max_ll_items);
/* OTP has no valid blocks */ /* OTP has no valid blocks */
IWL_DEBUG_EEPROM(trans, "OTP has no valid blocks\n"); IWL_DEBUG_EEPROM(trans, "OTP has no valid blocks\n");
...@@ -693,7 +691,7 @@ static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) ...@@ -693,7 +691,7 @@ static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
((txp->delta_20_in_40 & 0xf0) >> 4), ((txp->delta_20_in_40 & 0xf0) >> 4),
(txp->delta_20_in_40 & 0x0f)); (txp->delta_20_in_40 & 0x0f));
max_txp_avg = iwl_get_max_txpower_avg(cfg(priv), txp_array, idx, max_txp_avg = iwl_get_max_txpower_avg(priv->cfg, txp_array, idx,
&max_txp_avg_halfdbm); &max_txp_avg_halfdbm);
/* /*
...@@ -719,18 +717,18 @@ static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv) ...@@ -719,18 +717,18 @@ static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
{ {
__le16 *e; __le16 *e;
u32 gp = iwl_read32(trans(priv), CSR_EEPROM_GP); u32 gp = iwl_read32(priv->trans, CSR_EEPROM_GP);
int sz; int sz;
int ret; int ret;
u16 addr; u16 addr;
u16 validblockaddr = 0; u16 validblockaddr = 0;
u16 cache_addr = 0; u16 cache_addr = 0;
priv->nvm_device_type = iwl_get_nvm_type(trans(priv), hw_rev); priv->nvm_device_type = iwl_get_nvm_type(priv->trans, hw_rev);
if (priv->nvm_device_type == -ENOENT) if (priv->nvm_device_type == -ENOENT)
return -ENOENT; return -ENOENT;
/* allocate eeprom */ /* allocate eeprom */
sz = cfg(priv)->base_params->eeprom_size; sz = priv->cfg->base_params->eeprom_size;
IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz); IWL_DEBUG_EEPROM(priv, "NVM size = %d\n", sz);
priv->eeprom = kzalloc(sz, GFP_KERNEL); priv->eeprom = kzalloc(sz, GFP_KERNEL);
if (!priv->eeprom) { if (!priv->eeprom) {
...@@ -747,7 +745,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) ...@@ -747,7 +745,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
} }
/* Make sure driver (instead of uCode) is allowed to read EEPROM */ /* Make sure driver (instead of uCode) is allowed to read EEPROM */
ret = iwl_eeprom_acquire_semaphore(trans(priv)); ret = iwl_eeprom_acquire_semaphore(priv->trans);
if (ret < 0) { if (ret < 0) {
IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
ret = -ENOENT; ret = -ENOENT;
...@@ -756,22 +754,22 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) ...@@ -756,22 +754,22 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) { if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) {
ret = iwl_init_otp_access(trans(priv)); ret = iwl_init_otp_access(priv->trans);
if (ret) { if (ret) {
IWL_ERR(priv, "Failed to initialize OTP access.\n"); IWL_ERR(priv, "Failed to initialize OTP access.\n");
ret = -ENOENT; ret = -ENOENT;
goto done; goto done;
} }
iwl_write32(trans(priv), CSR_EEPROM_GP, iwl_write32(priv->trans, CSR_EEPROM_GP,
iwl_read32(trans(priv), CSR_EEPROM_GP) & iwl_read32(priv->trans, CSR_EEPROM_GP) &
~CSR_EEPROM_GP_IF_OWNER_MSK); ~CSR_EEPROM_GP_IF_OWNER_MSK);
iwl_set_bit(trans(priv), CSR_OTP_GP_REG, iwl_set_bit(priv->trans, CSR_OTP_GP_REG,
CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
/* traversing the linked list if no shadow ram supported */ /* traversing the linked list if no shadow ram supported */
if (!cfg(priv)->base_params->shadow_ram_support) { if (!priv->cfg->base_params->shadow_ram_support) {
if (iwl_find_otp_image(trans(priv), &validblockaddr)) { if (iwl_find_otp_image(priv->trans, &validblockaddr)) {
ret = -ENOENT; ret = -ENOENT;
goto done; goto done;
} }
...@@ -780,7 +778,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) ...@@ -780,7 +778,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
addr += sizeof(u16)) { addr += sizeof(u16)) {
__le16 eeprom_data; __le16 eeprom_data;
ret = iwl_read_otp_word(trans(priv), addr, ret = iwl_read_otp_word(priv->trans, addr,
&eeprom_data); &eeprom_data);
if (ret) if (ret)
goto done; goto done;
...@@ -792,10 +790,10 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) ...@@ -792,10 +790,10 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
for (addr = 0; addr < sz; addr += sizeof(u16)) { for (addr = 0; addr < sz; addr += sizeof(u16)) {
u32 r; u32 r;
iwl_write32(trans(priv), CSR_EEPROM_REG, iwl_write32(priv->trans, CSR_EEPROM_REG,
CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
ret = iwl_poll_bit(trans(priv), CSR_EEPROM_REG, ret = iwl_poll_bit(priv->trans, CSR_EEPROM_REG,
CSR_EEPROM_REG_READ_VALID_MSK, CSR_EEPROM_REG_READ_VALID_MSK,
CSR_EEPROM_REG_READ_VALID_MSK, CSR_EEPROM_REG_READ_VALID_MSK,
IWL_EEPROM_ACCESS_TIMEOUT); IWL_EEPROM_ACCESS_TIMEOUT);
...@@ -804,7 +802,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) ...@@ -804,7 +802,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
"Time out reading EEPROM[%d]\n", addr); "Time out reading EEPROM[%d]\n", addr);
goto done; goto done;
} }
r = iwl_read32(trans(priv), CSR_EEPROM_REG); r = iwl_read32(priv->trans, CSR_EEPROM_REG);
e[addr / 2] = cpu_to_le16(r >> 16); e[addr / 2] = cpu_to_le16(r >> 16);
} }
} }
...@@ -816,7 +814,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) ...@@ -816,7 +814,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
ret = 0; ret = 0;
done: done:
iwl_eeprom_release_semaphore(trans(priv)); iwl_eeprom_release_semaphore(priv->trans);
err: err:
if (ret) if (ret)
...@@ -1132,7 +1130,7 @@ void iwl_rf_config(struct iwl_priv *priv) ...@@ -1132,7 +1130,7 @@ void iwl_rf_config(struct iwl_priv *priv)
/* write radio config values to register */ /* write radio config values to register */
if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) {
iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG,
EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
EEPROM_RF_CFG_STEP_MSK(radio_cfg) | EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
EEPROM_RF_CFG_DASH_MSK(radio_cfg)); EEPROM_RF_CFG_DASH_MSK(radio_cfg));
...@@ -1144,7 +1142,7 @@ void iwl_rf_config(struct iwl_priv *priv) ...@@ -1144,7 +1142,7 @@ void iwl_rf_config(struct iwl_priv *priv)
WARN_ON(1); WARN_ON(1);
/* set CSR_HW_CONFIG_REG for uCode use */ /* set CSR_HW_CONFIG_REG for uCode use */
iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, iwl_set_bit(priv->trans, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
} }
...@@ -206,59 +206,6 @@ struct iwl_eeprom_calib_hdr { ...@@ -206,59 +206,6 @@ struct iwl_eeprom_calib_hdr {
/* 6000 regulatory - indirect access */ /* 6000 regulatory - indirect access */
#define EEPROM_6000_REG_BAND_24_HT40_CHANNELS ((0x80)\ #define EEPROM_6000_REG_BAND_24_HT40_CHANNELS ((0x80)\
| INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */ | INDIRECT_ADDRESS | INDIRECT_REGULATORY) /* 14 bytes */
/* 5000 Specific */
#define EEPROM_5000_TX_POWER_VERSION (4)
#define EEPROM_5000_EEPROM_VERSION (0x11A)
/* 5050 Specific */
#define EEPROM_5050_TX_POWER_VERSION (4)
#define EEPROM_5050_EEPROM_VERSION (0x21E)
/* 1000 Specific */
#define EEPROM_1000_TX_POWER_VERSION (4)
#define EEPROM_1000_EEPROM_VERSION (0x15C)
/* 6x00 Specific */
#define EEPROM_6000_TX_POWER_VERSION (4)
#define EEPROM_6000_EEPROM_VERSION (0x423)
/* 6x50 Specific */
#define EEPROM_6050_TX_POWER_VERSION (4)
#define EEPROM_6050_EEPROM_VERSION (0x532)
/* 6150 Specific */
#define EEPROM_6150_TX_POWER_VERSION (6)
#define EEPROM_6150_EEPROM_VERSION (0x553)
/* 6x05 Specific */
#define EEPROM_6005_TX_POWER_VERSION (6)
#define EEPROM_6005_EEPROM_VERSION (0x709)
/* 6x30 Specific */
#define EEPROM_6030_TX_POWER_VERSION (6)
#define EEPROM_6030_EEPROM_VERSION (0x709)
/* 2x00 Specific */
#define EEPROM_2000_TX_POWER_VERSION (6)
#define EEPROM_2000_EEPROM_VERSION (0x805)
/* 6x35 Specific */
#define EEPROM_6035_TX_POWER_VERSION (6)
#define EEPROM_6035_EEPROM_VERSION (0x753)
/* OTP */
/* lower blocks contain EEPROM image and calibration data */
#define OTP_LOW_IMAGE_SIZE (2 * 512 * sizeof(u16)) /* 2 KB */
/* high blocks contain PAPD data */
#define OTP_HIGH_IMAGE_SIZE_6x00 (6 * 512 * sizeof(u16)) /* 6 KB */
#define OTP_HIGH_IMAGE_SIZE_1000 (0x200 * sizeof(u16)) /* 1024 bytes */
#define OTP_MAX_LL_ITEMS_1000 (3) /* OTP blocks for 1000 */
#define OTP_MAX_LL_ITEMS_6x00 (4) /* OTP blocks for 6x00 */
#define OTP_MAX_LL_ITEMS_6x50 (7) /* OTP blocks for 6x50 */
#define OTP_MAX_LL_ITEMS_2x00 (4) /* OTP blocks for 2x00 */
/* 2.4 GHz */ /* 2.4 GHz */
extern const u8 iwl_eeprom_band_1[14]; extern const u8 iwl_eeprom_band_1[14];
......
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
#ifndef __iwl_fw_h__ #ifndef __iwl_fw_h__
#define __iwl_fw_h__ #define __iwl_fw_h__
#include <linux/types.h> #include <linux/types.h>
#include <net/mac80211.h>
/** /**
* enum iwl_ucode_tlv_flag - ucode API flags * enum iwl_ucode_tlv_flag - ucode API flags
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#define __iwl_io_h__ #define __iwl_io_h__
#include "iwl-devtrace.h" #include "iwl-devtrace.h"
#include "iwl-shared.h"
#include "iwl-trans.h" #include "iwl-trans.h"
static inline void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val) static inline void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val)
......
...@@ -36,11 +36,10 @@ ...@@ -36,11 +36,10 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-io.h" #include "iwl-io.h"
#include "iwl-trans.h" #include "iwl-trans.h"
#include "iwl-shared.h" #include "iwl-modparams.h"
/* Throughput OFF time(ms) ON time (ms) /* Throughput OFF time(ms) ON time (ms)
* >300 25 25 * >300 25 25
...@@ -71,7 +70,7 @@ static const struct ieee80211_tpt_blink iwl_blink[] = { ...@@ -71,7 +70,7 @@ static const struct ieee80211_tpt_blink iwl_blink[] = {
/* Set led register off */ /* Set led register off */
void iwlagn_led_enable(struct iwl_priv *priv) void iwlagn_led_enable(struct iwl_priv *priv)
{ {
iwl_write32(trans(priv), CSR_LED_REG, CSR_LED_REG_TRUN_ON); iwl_write32(priv->trans, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
} }
/* /*
...@@ -107,9 +106,9 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) ...@@ -107,9 +106,9 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
}; };
u32 reg; u32 reg;
reg = iwl_read32(trans(priv), CSR_LED_REG); reg = iwl_read32(priv->trans, CSR_LED_REG);
if (reg != (reg & CSR_LED_BSM_CTRL_MSK)) if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
iwl_write32(trans(priv), CSR_LED_REG, iwl_write32(priv->trans, CSR_LED_REG,
reg & CSR_LED_BSM_CTRL_MSK); reg & CSR_LED_BSM_CTRL_MSK);
return iwl_dvm_send_cmd(priv, &cmd); return iwl_dvm_send_cmd(priv, &cmd);
...@@ -138,11 +137,11 @@ static int iwl_led_cmd(struct iwl_priv *priv, ...@@ -138,11 +137,11 @@ static int iwl_led_cmd(struct iwl_priv *priv,
} }
IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n", IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n",
cfg(priv)->base_params->led_compensation); priv->cfg->base_params->led_compensation);
led_cmd.on = iwl_blink_compensation(priv, on, led_cmd.on = iwl_blink_compensation(priv, on,
cfg(priv)->base_params->led_compensation); priv->cfg->base_params->led_compensation);
led_cmd.off = iwl_blink_compensation(priv, off, led_cmd.off = iwl_blink_compensation(priv, off,
cfg(priv)->base_params->led_compensation); priv->cfg->base_params->led_compensation);
ret = iwl_send_led_cmd(priv, &led_cmd); ret = iwl_send_led_cmd(priv, &led_cmd);
if (!ret) { if (!ret) {
...@@ -175,7 +174,7 @@ static int iwl_led_blink_set(struct led_classdev *led_cdev, ...@@ -175,7 +174,7 @@ static int iwl_led_blink_set(struct led_classdev *led_cdev,
void iwl_leds_init(struct iwl_priv *priv) void iwl_leds_init(struct iwl_priv *priv)
{ {
int mode = iwlagn_mod_params.led_mode; int mode = iwlwifi_mod_params.led_mode;
int ret; int ret;
if (mode == IWL_LED_DISABLE) { if (mode == IWL_LED_DISABLE) {
...@@ -183,7 +182,7 @@ void iwl_leds_init(struct iwl_priv *priv) ...@@ -183,7 +182,7 @@ void iwl_leds_init(struct iwl_priv *priv)
return; return;
} }
if (mode == IWL_LED_DEFAULT) if (mode == IWL_LED_DEFAULT)
mode = cfg(priv)->led_mode; mode = priv->cfg->led_mode;
priv->led.name = kasprintf(GFP_KERNEL, "%s-led", priv->led.name = kasprintf(GFP_KERNEL, "%s-led",
wiphy_name(priv->hw->wiphy)); wiphy_name(priv->hw->wiphy));
...@@ -207,7 +206,7 @@ void iwl_leds_init(struct iwl_priv *priv) ...@@ -207,7 +206,7 @@ void iwl_leds_init(struct iwl_priv *priv)
break; break;
} }
ret = led_classdev_register(trans(priv)->dev, &priv->led); ret = led_classdev_register(priv->trans->dev, &priv->led);
if (ret) { if (ret) {
kfree(priv->led.name); kfree(priv->led.name);
return; return;
......
...@@ -44,13 +44,12 @@ ...@@ -44,13 +44,12 @@
#include "iwl-eeprom.h" #include "iwl-eeprom.h"
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-io.h" #include "iwl-io.h"
#include "iwl-agn-calib.h" #include "iwl-agn-calib.h"
#include "iwl-agn.h" #include "iwl-agn.h"
#include "iwl-shared.h"
#include "iwl-trans.h" #include "iwl-trans.h"
#include "iwl-op-mode.h" #include "iwl-op-mode.h"
#include "iwl-modparams.h"
/***************************************************************************** /*****************************************************************************
* *
...@@ -147,7 +146,13 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, ...@@ -147,7 +146,13 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
IEEE80211_HW_AMPDU_AGGREGATION | IEEE80211_HW_AMPDU_AGGREGATION |
IEEE80211_HW_NEED_DTIM_PERIOD | IEEE80211_HW_NEED_DTIM_PERIOD |
IEEE80211_HW_SPECTRUM_MGMT | IEEE80211_HW_SPECTRUM_MGMT |
IEEE80211_HW_REPORTS_TX_ACK_STATUS; IEEE80211_HW_REPORTS_TX_ACK_STATUS |
IEEE80211_HW_QUEUE_CONTROL |
IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
IEEE80211_HW_SCAN_WHILE_IDLE;
hw->offchannel_tx_hw_queue = IWL_AUX_QUEUE;
/* /*
* Including the following line will crash some AP's. This * Including the following line will crash some AP's. This
...@@ -156,10 +161,6 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, ...@@ -156,10 +161,6 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF; hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
*/ */
hw->flags |= IEEE80211_HW_SUPPORTS_PS |
IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
IEEE80211_HW_SCAN_WHILE_IDLE;
if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE) if (priv->hw_params.sku & EEPROM_SKU_CAP_11N_ENABLE)
hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
IEEE80211_HW_SUPPORTS_STATIC_SMPS; IEEE80211_HW_SUPPORTS_STATIC_SMPS;
...@@ -198,13 +199,13 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, ...@@ -198,13 +199,13 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
WIPHY_FLAG_IBSS_RSN; WIPHY_FLAG_IBSS_RSN;
if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len && if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
trans(priv)->ops->wowlan_suspend && priv->trans->ops->wowlan_suspend &&
device_can_wakeup(trans(priv)->dev)) { device_can_wakeup(priv->trans->dev)) {
hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_DISCONNECT |
WIPHY_WOWLAN_EAP_IDENTITY_REQ | WIPHY_WOWLAN_EAP_IDENTITY_REQ |
WIPHY_WOWLAN_RFKILL_RELEASE; WIPHY_WOWLAN_RFKILL_RELEASE;
if (!iwlagn_mod_params.sw_crypto) if (!iwlwifi_mod_params.sw_crypto)
hw->wiphy->wowlan.flags |= hw->wiphy->wowlan.flags |=
WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
WIPHY_WOWLAN_GTK_REKEY_FAILURE; WIPHY_WOWLAN_GTK_REKEY_FAILURE;
...@@ -216,7 +217,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, ...@@ -216,7 +217,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
IWLAGN_WOWLAN_MAX_PATTERN_LEN; IWLAGN_WOWLAN_MAX_PATTERN_LEN;
} }
if (iwlagn_mod_params.power_save) if (iwlwifi_mod_params.power_save)
hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
else else
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
...@@ -225,8 +226,11 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, ...@@ -225,8 +226,11 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
/* we create the 802.11 header and a zero-length SSID element */ /* we create the 802.11 header and a zero-length SSID element */
hw->wiphy->max_scan_ie_len = capa->max_probe_length - 24 - 2; hw->wiphy->max_scan_ie_len = capa->max_probe_length - 24 - 2;
/* Default value; 4 EDCA QOS priorities */ /*
hw->queues = 4; * We don't use all queues: 4 and 9 are unused and any
* aggregation queue gets mapped down to the AC queue.
*/
hw->queues = IWLAGN_FIRST_AMPDU_QUEUE;
hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
...@@ -237,7 +241,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, ...@@ -237,7 +241,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
&priv->bands[IEEE80211_BAND_5GHZ]; &priv->bands[IEEE80211_BAND_5GHZ];
hw->wiphy->hw_version = trans(priv)->hw_id; hw->wiphy->hw_version = priv->trans->hw_id;
iwl_leds_init(priv); iwl_leds_init(priv);
...@@ -356,7 +360,7 @@ void iwlagn_mac_stop(struct ieee80211_hw *hw) ...@@ -356,7 +360,7 @@ void iwlagn_mac_stop(struct ieee80211_hw *hw)
* even if interface is down, trans->down will leave the RF * even if interface is down, trans->down will leave the RF
* kill interrupt enabled * kill interrupt enabled
*/ */
iwl_trans_stop_hw(trans(priv)); iwl_trans_stop_hw(priv->trans, false);
IWL_DEBUG_MAC80211(priv, "leave\n"); IWL_DEBUG_MAC80211(priv, "leave\n");
} }
...@@ -367,7 +371,7 @@ void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw, ...@@ -367,7 +371,7 @@ void iwlagn_mac_set_rekey_data(struct ieee80211_hw *hw,
{ {
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
if (iwlagn_mod_params.sw_crypto) if (iwlwifi_mod_params.sw_crypto)
return; return;
IWL_DEBUG_MAC80211(priv, "enter\n"); IWL_DEBUG_MAC80211(priv, "enter\n");
...@@ -412,9 +416,9 @@ int iwlagn_mac_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) ...@@ -412,9 +416,9 @@ int iwlagn_mac_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
if (ret) if (ret)
goto error; goto error;
device_set_wakeup_enable(trans(priv)->dev, true); device_set_wakeup_enable(priv->trans->dev, true);
iwl_trans_wowlan_suspend(trans(priv)); iwl_trans_wowlan_suspend(priv->trans);
goto out; goto out;
...@@ -441,19 +445,19 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) ...@@ -441,19 +445,19 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
IWL_DEBUG_MAC80211(priv, "enter\n"); IWL_DEBUG_MAC80211(priv, "enter\n");
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, iwl_write32(priv->trans, CSR_UCODE_DRV_GP1_CLR,
CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE);
base = priv->device_pointers.error_event_table; base = priv->device_pointers.error_event_table;
if (iwlagn_hw_valid_rtc_data_addr(base)) { if (iwlagn_hw_valid_rtc_data_addr(base)) {
spin_lock_irqsave(&trans(priv)->reg_lock, flags); spin_lock_irqsave(&priv->trans->reg_lock, flags);
ret = iwl_grab_nic_access_silent(trans(priv)); ret = iwl_grab_nic_access_silent(priv->trans);
if (likely(ret == 0)) { if (likely(ret == 0)) {
iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base); iwl_write32(priv->trans, HBUS_TARG_MEM_RADDR, base);
status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); status = iwl_read32(priv->trans, HBUS_TARG_MEM_RDAT);
iwl_release_nic_access(trans(priv)); iwl_release_nic_access(priv->trans);
} }
spin_unlock_irqrestore(&trans(priv)->reg_lock, flags); spin_unlock_irqrestore(&priv->trans->reg_lock, flags);
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
if (ret == 0) { if (ret == 0) {
...@@ -468,7 +472,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) ...@@ -468,7 +472,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
if (priv->wowlan_sram) if (priv->wowlan_sram)
_iwl_read_targ_mem_words( _iwl_read_targ_mem_words(
trans(priv), 0x800000, priv->trans, 0x800000,
priv->wowlan_sram, priv->wowlan_sram,
img->sec[IWL_UCODE_SECTION_DATA].len / 4); img->sec[IWL_UCODE_SECTION_DATA].len / 4);
} }
...@@ -480,7 +484,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) ...@@ -480,7 +484,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw)
priv->wowlan = false; priv->wowlan = false;
device_set_wakeup_enable(trans(priv)->dev, false); device_set_wakeup_enable(priv->trans->dev, false);
iwlagn_prepare_restart(priv); iwlagn_prepare_restart(priv);
...@@ -533,7 +537,7 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, ...@@ -533,7 +537,7 @@ int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
IWL_DEBUG_MAC80211(priv, "enter\n"); IWL_DEBUG_MAC80211(priv, "enter\n");
if (iwlagn_mod_params.sw_crypto) { if (iwlwifi_mod_params.sw_crypto) {
IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n"); IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -644,7 +648,7 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, ...@@ -644,7 +648,7 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
switch (action) { switch (action) {
case IEEE80211_AMPDU_RX_START: case IEEE80211_AMPDU_RX_START:
if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG) if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_RXAGG)
break; break;
IWL_DEBUG_HT(priv, "start Rx\n"); IWL_DEBUG_HT(priv, "start Rx\n");
ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn); ret = iwl_sta_rx_agg_start(priv, sta, tid, *ssn);
...@@ -654,9 +658,9 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, ...@@ -654,9 +658,9 @@ int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
ret = iwl_sta_rx_agg_stop(priv, sta, tid); ret = iwl_sta_rx_agg_stop(priv, sta, tid);
break; break;
case IEEE80211_AMPDU_TX_START: case IEEE80211_AMPDU_TX_START:
if (!trans(priv)->ops->tx_agg_setup) if (!priv->trans->ops->tx_agg_setup)
break; break;
if (iwlagn_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG) if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_TXAGG)
break; break;
IWL_DEBUG_HT(priv, "start Tx\n"); IWL_DEBUG_HT(priv, "start Tx\n");
ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn);
...@@ -895,7 +899,6 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, ...@@ -895,7 +899,6 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
iwl_set_rxon_ht(priv, ht_conf); iwl_set_rxon_ht(priv, ht_conf);
iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif); iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif);
iwl_set_rate(priv);
/* /*
* at this point, staging_rxon has the * at this point, staging_rxon has the
* configuration for channel switch * configuration for channel switch
...@@ -1006,7 +1009,7 @@ void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) ...@@ -1006,7 +1009,7 @@ void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
} }
} }
IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n"); IWL_DEBUG_MAC80211(priv, "wait transmit/flush all frames\n");
iwl_trans_wait_tx_queue_empty(trans(priv)); iwl_trans_wait_tx_queue_empty(priv->trans);
done: done:
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "leave\n"); IWL_DEBUG_MAC80211(priv, "leave\n");
...@@ -1130,8 +1133,8 @@ void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw, ...@@ -1130,8 +1133,8 @@ void iwlagn_mac_rssi_callback(struct ieee80211_hw *hw,
IWL_DEBUG_MAC80211(priv, "enter\n"); IWL_DEBUG_MAC80211(priv, "enter\n");
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
if (cfg(priv)->bt_params && if (priv->cfg->bt_params &&
cfg(priv)->bt_params->advanced_bt_coexist) { priv->cfg->bt_params->advanced_bt_coexist) {
if (rssi_event == RSSI_EVENT_LOW) if (rssi_event == RSSI_EVENT_LOW)
priv->bt_enable_pspoll = true; priv->bt_enable_pspoll = true;
else if (rssi_event == RSSI_EVENT_HIGH) else if (rssi_event == RSSI_EVENT_HIGH)
...@@ -1220,7 +1223,7 @@ static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ...@@ -1220,7 +1223,7 @@ static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx) int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{ {
struct ieee80211_vif *vif = ctx->vif; struct ieee80211_vif *vif = ctx->vif;
int err; int err, ac;
lockdep_assert_held(&priv->mutex); lockdep_assert_held(&priv->mutex);
...@@ -1240,7 +1243,7 @@ int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ...@@ -1240,7 +1243,7 @@ int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
return err; return err;
} }
if (cfg(priv)->bt_params && cfg(priv)->bt_params->advanced_bt_coexist && if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist &&
vif->type == NL80211_IFTYPE_ADHOC) { vif->type == NL80211_IFTYPE_ADHOC) {
/* /*
* pretend to have high BT traffic as long as we * pretend to have high BT traffic as long as we
...@@ -1250,6 +1253,15 @@ int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ...@@ -1250,6 +1253,15 @@ int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH; priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
} }
/* set up queue mappings */
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
vif->hw_queue[ac] = ctx->ac_to_queue[ac];
if (vif->type == NL80211_IFTYPE_AP)
vif->cab_queue = ctx->mcast_queue;
else
vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
return 0; return 0;
} }
......
...@@ -68,42 +68,16 @@ ...@@ -68,42 +68,16 @@
#include <linux/gfp.h> #include <linux/gfp.h>
#include <net/mac80211.h> #include <net/mac80211.h>
#include "iwl-commands.h" extern struct iwl_mod_params iwlwifi_mod_params;
#include "iwl-fw.h"
#include "iwl-config.h"
/** enum iwl_power_level {
* DOC: shared area - role and goal IWL_POWER_INDEX_1,
* IWL_POWER_INDEX_2,
* The shared area contains all the data exported by the upper layer to the IWL_POWER_INDEX_3,
* other layers. Since the bus and transport layer shouldn't dereference IWL_POWER_INDEX_4,
* iwl_priv, all the data needed by the upper layer and the transport / bus IWL_POWER_INDEX_5,
* layer must be here. IWL_POWER_NUM
* The shared area also holds pointer to all the other layers. This allows a };
* layer to call a function from another layer.
*
* NOTE: All the layers hold a pointer to the shared area which must be shrd.
* A few macros assume that (_m)->shrd points to the shared area no matter
* what _m is.
*
* gets notifications about enumeration, suspend, resume.
* For the moment, the bus layer is not a linux kernel module as itself, and
* the module_init function of the driver must call the bus specific
* registration functions. These functions are listed at the end of this file.
* For the moment, there is only one implementation of this interface: PCI-e.
* This implementation is iwl-pci.c
*/
struct iwl_priv;
struct iwl_trans;
struct iwl_trans_ops;
#define DRV_NAME "iwlwifi"
#define IWLWIFI_VERSION "in-tree:"
#define DRV_COPYRIGHT "Copyright(c) 2003-2012 Intel Corporation"
#define DRV_AUTHOR "<ilw@linux.intel.com>"
extern struct iwl_mod_params iwlagn_mod_params;
#define IWL_DISABLE_HT_ALL BIT(0) #define IWL_DISABLE_HT_ALL BIT(0)
#define IWL_DISABLE_HT_TXAGG BIT(1) #define IWL_DISABLE_HT_TXAGG BIT(1)
...@@ -147,38 +121,4 @@ struct iwl_mod_params { ...@@ -147,38 +121,4 @@ struct iwl_mod_params {
bool auto_agg; bool auto_agg;
}; };
/**
* struct iwl_shared - shared fields for all the layers of the driver
*
* @wowlan: are we running wowlan uCode
* @bus: pointer to the bus layer data
* @cfg: see struct iwl_cfg
* @priv: pointer to the upper layer data
* @trans: pointer to the transport layer data
* @nic: pointer to the nic data
* @lock: protect general shared data
* @eeprom: pointer to the eeprom/OTP image
*/
struct iwl_shared {
const struct iwl_cfg *cfg;
struct iwl_trans *trans;
void *drv;
};
/*Whatever _m is (iwl_trans, iwl_priv, these macros will work */
#define cfg(_m) ((_m)->shrd->cfg)
#define trans(_m) ((_m)->shrd->trans)
static inline bool iwl_have_debug_level(u32 level)
{
return iwlagn_mod_params.debug_level & level;
}
enum iwl_rxon_context_id {
IWL_RXON_CTX_BSS,
IWL_RXON_CTX_PAN,
NUM_IWL_RXON_CTX
};
#endif /* #__iwl_shared_h__ */ #endif /* #__iwl_shared_h__ */
...@@ -69,6 +69,7 @@ struct sk_buff; ...@@ -69,6 +69,7 @@ struct sk_buff;
struct iwl_device_cmd; struct iwl_device_cmd;
struct iwl_rx_cmd_buffer; struct iwl_rx_cmd_buffer;
struct iwl_fw; struct iwl_fw;
struct iwl_cfg;
/** /**
* DOC: Operational mode - what is it ? * DOC: Operational mode - what is it ?
...@@ -129,6 +130,7 @@ struct iwl_fw; ...@@ -129,6 +130,7 @@ struct iwl_fw;
*/ */
struct iwl_op_mode_ops { struct iwl_op_mode_ops {
struct iwl_op_mode *(*start)(struct iwl_trans *trans, struct iwl_op_mode *(*start)(struct iwl_trans *trans,
const struct iwl_cfg *cfg,
const struct iwl_fw *fw); const struct iwl_fw *fw);
void (*stop)(struct iwl_op_mode *op_mode); void (*stop)(struct iwl_op_mode *op_mode);
int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb, int (*rx)(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
......
...@@ -65,14 +65,13 @@ ...@@ -65,14 +65,13 @@
#include <linux/string.h> #include <linux/string.h>
#include "iwl-debug.h" #include "iwl-debug.h"
#include "iwl-shared.h"
#include "iwl-dev.h" #include "iwl-dev.h"
#include "iwl-phy-db.h" #include "iwl-phy-db.h"
#define CHANNEL_NUM_SIZE 4 /* num of channels in calib_ch size */ #define CHANNEL_NUM_SIZE 4 /* num of channels in calib_ch size */
struct iwl_phy_db *iwl_phy_db_init(struct iwl_shared *shrd) struct iwl_phy_db *iwl_phy_db_init(struct device *dev)
{ {
struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db), struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db),
GFP_KERNEL); GFP_KERNEL);
...@@ -80,7 +79,7 @@ struct iwl_phy_db *iwl_phy_db_init(struct iwl_shared *shrd) ...@@ -80,7 +79,7 @@ struct iwl_phy_db *iwl_phy_db_init(struct iwl_shared *shrd)
if (!phy_db) if (!phy_db)
return phy_db; return phy_db;
phy_db->shrd = shrd; phy_db->dev = dev;
/* TODO: add default values of the phy db. */ /* TODO: add default values of the phy db. */
return phy_db; return phy_db;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/sched.h>
#include "dev.h" #include "dev.h"
#include "decl.h" #include "decl.h"
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册