提交 a85c9bb8 编写于 作者: D David S. Miller
...@@ -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);
txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); if (!(IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))) {
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
udelay(5); REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); udelay(5);
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,11 +282,12 @@ void ath9k_hw_btcoex_enable(struct ath_hw *ah) ...@@ -284,11 +282,12 @@ 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:
if (AR_SREV_9462(ah)) {
ath9k_hw_btcoex_enable_mci(ah);
return;
}
ath9k_hw_btcoex_enable_3wire(ah); ath9k_hw_btcoex_enable_3wire(ah);
break; break;
case ATH_BTCOEX_CFG_MCI:
ath9k_hw_btcoex_enable_mci(ah);
return;
} }
REG_RMW(ah, AR_GPIO_PDPU, REG_RMW(ah, AR_GPIO_PDPU,
...@@ -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,15 +297,15 @@ static bool pseq_handler_create_sequences(struct pri_detector *pde, ...@@ -220,15 +297,15 @@ 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);
...@@ -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,17 +402,16 @@ int ath9k_init_btcoex(struct ath_softc *sc) ...@@ -402,17 +402,16 @@ 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.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; INIT_LIST_HEAD(&sc->btcoex.mci.info);
sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
INIT_LIST_HEAD(&sc->btcoex.mci.info);
r = ath_mci_setup(sc); r = ath_mci_setup(sc);
if (r) if (r)
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,13 +2025,25 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, ...@@ -2026,13 +2025,25 @@ 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);
ath_beacon_config(sc, vif); else
avp->is_bslot_active = false;
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,11 +1253,20 @@ int iwl_setup_interface(struct iwl_priv *priv, struct iwl_rxon_context *ctx) ...@@ -1250,11 +1253,20 @@ 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;
} }
static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif) struct ieee80211_vif *vif)
{ {
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
......
...@@ -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,
......
...@@ -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"
......
...@@ -42,3 +42,6 @@ obj-$(CONFIG_MWIFIEX_SDIO) += mwifiex_sdio.o ...@@ -42,3 +42,6 @@ obj-$(CONFIG_MWIFIEX_SDIO) += mwifiex_sdio.o
mwifiex_pcie-y += pcie.o mwifiex_pcie-y += pcie.o
obj-$(CONFIG_MWIFIEX_PCIE) += mwifiex_pcie.o obj-$(CONFIG_MWIFIEX_PCIE) += mwifiex_pcie.o
mwifiex_usb-y += usb.o
obj-$(CONFIG_MWIFIEX_USB) += mwifiex_usb.o
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册