forked from luck/tmp_suning_uos_patched
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (78 commits) AX.25: Fix sysctl registration if !CONFIG_AX25_DAMA_SLAVE pktgen: mac count pktgen: random flow bridge: Eliminate unnecessary forward delay bridge: fix compile warning in net/bridge/br_netfilter.c ipv4: remove unused field in struct flowi (include/net/flow.h). tg3: Fix 'scheduling while atomic' errors net: Kill plain NET_XMIT_BYPASS. net_sched: Add qdisc __NET_XMIT_BYPASS flag net_sched: Add qdisc __NET_XMIT_STOLEN flag iwl3945: fix merge mistake for packet injection iwlwifi: grap nic access before accessing periphery registers iwlwifi: decrement rx skb counter in scan abort handler iwlwifi: fix unhandled interrupt when HW rfkill is on iwlwifi: implement iwl5000_calc_rssi iwlwifi: memory allocation optimization iwlwifi: HW bug fixes p54: Fix potential concurrent access to private data rt2x00: Disable link tuning in rt2500usb iwlwifi: Don't use buffer allocated on the stack for led names ...
This commit is contained in:
commit
e63e03273b
@ -7687,21 +7687,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
|
||||
*/
|
||||
static int tg3_init_hw(struct tg3 *tp, int reset_phy)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Force the chip into D0. */
|
||||
err = tg3_set_power_state(tp, PCI_D0);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
tg3_switch_clocks(tp);
|
||||
|
||||
tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
|
||||
|
||||
err = tg3_reset_hw(tp, reset_phy);
|
||||
|
||||
out:
|
||||
return err;
|
||||
return tg3_reset_hw(tp, reset_phy);
|
||||
}
|
||||
|
||||
#define TG3_STAT_ADD32(PSTAT, REG) \
|
||||
@ -8016,13 +8006,11 @@ static int tg3_open(struct net_device *dev)
|
||||
|
||||
netif_carrier_off(tp->dev);
|
||||
|
||||
tg3_full_lock(tp, 0);
|
||||
|
||||
err = tg3_set_power_state(tp, PCI_D0);
|
||||
if (err) {
|
||||
tg3_full_unlock(tp);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
tg3_full_lock(tp, 0);
|
||||
|
||||
tg3_disable_ints(tp);
|
||||
tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
|
||||
|
@ -649,6 +649,7 @@ config RTL8187
|
||||
Trendnet TEW-424UB
|
||||
ASUS P5B Deluxe
|
||||
Toshiba Satellite Pro series of laptops
|
||||
Asus Wireless Link
|
||||
|
||||
Thanks to Realtek for their support!
|
||||
|
||||
|
@ -186,11 +186,13 @@ struct ath5k_srev_name {
|
||||
#define AR5K_SREV_RAD_2111 0x20
|
||||
#define AR5K_SREV_RAD_5112 0x30
|
||||
#define AR5K_SREV_RAD_5112A 0x35
|
||||
#define AR5K_SREV_RAD_5112B 0x36
|
||||
#define AR5K_SREV_RAD_2112 0x40
|
||||
#define AR5K_SREV_RAD_2112A 0x45
|
||||
#define AR5K_SREV_RAD_SC0 0x56 /* Found on 2413/2414 */
|
||||
#define AR5K_SREV_RAD_SC1 0x63 /* Found on 5413/5414 */
|
||||
#define AR5K_SREV_RAD_SC2 0xa2 /* Found on 2424-5/5424 */
|
||||
#define AR5K_SREV_RAD_2112B 0x46
|
||||
#define AR5K_SREV_RAD_SC0 0x50 /* Found on 2413/2414 */
|
||||
#define AR5K_SREV_RAD_SC1 0x60 /* Found on 5413/5414 */
|
||||
#define AR5K_SREV_RAD_SC2 0xa0 /* Found on 2424-5/5424 */
|
||||
#define AR5K_SREV_RAD_5133 0xc0 /* MIMO found on 5418 */
|
||||
|
||||
/* IEEE defs */
|
||||
|
@ -2170,6 +2170,7 @@ ath5k_beacon_config(struct ath5k_softc *sc)
|
||||
|
||||
ath5k_hw_set_intr(ah, 0);
|
||||
sc->bmisscount = 0;
|
||||
sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
|
||||
|
||||
if (sc->opmode == IEEE80211_IF_TYPE_STA) {
|
||||
sc->imask |= AR5K_INT_BMISS;
|
||||
|
@ -129,7 +129,7 @@ static struct reg regs[] = {
|
||||
REG_STRUCT_INIT(AR5K_CPC1),
|
||||
REG_STRUCT_INIT(AR5K_CPC2),
|
||||
REG_STRUCT_INIT(AR5K_CPC3),
|
||||
REG_STRUCT_INIT(AR5K_CPCORN),
|
||||
REG_STRUCT_INIT(AR5K_CPCOVF),
|
||||
REG_STRUCT_INIT(AR5K_RESET_CTL),
|
||||
REG_STRUCT_INIT(AR5K_SLEEP_CTL),
|
||||
REG_STRUCT_INIT(AR5K_INTPEND),
|
||||
|
@ -63,7 +63,6 @@
|
||||
|
||||
struct ath5k_softc;
|
||||
struct ath5k_hw;
|
||||
struct ieee80211_hw_mode;
|
||||
struct sk_buff;
|
||||
struct ath5k_buf;
|
||||
|
||||
|
@ -139,6 +139,8 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
|
||||
for (c = 0; c < 2; c++) {
|
||||
|
||||
cur_reg = regs[c];
|
||||
|
||||
/* Save previous value */
|
||||
init_val = ath5k_hw_reg_read(ah, cur_reg);
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
@ -170,6 +172,10 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
|
||||
var_pattern = 0x003b080f;
|
||||
ath5k_hw_reg_write(ah, var_pattern, cur_reg);
|
||||
}
|
||||
|
||||
/* Restore previous value */
|
||||
ath5k_hw_reg_write(ah, init_val, cur_reg);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -287,67 +293,42 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
|
||||
/* Identify the radio chip*/
|
||||
if (ah->ah_version == AR5K_AR5210) {
|
||||
ah->ah_radio = AR5K_RF5110;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
|
||||
ah->ah_radio = AR5K_RF5111;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
|
||||
|
||||
ah->ah_radio = AR5K_RF5112;
|
||||
|
||||
if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
|
||||
} else {
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
|
||||
}
|
||||
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
|
||||
ah->ah_radio = AR5K_RF2413;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
|
||||
ah->ah_radio = AR5K_RF5413;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) {
|
||||
|
||||
/* AR5424 */
|
||||
if (srev >= AR5K_SREV_VER_AR5424) {
|
||||
ah->ah_radio = AR5K_RF5413;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5424;
|
||||
/* AR2424 */
|
||||
} else {
|
||||
ah->ah_radio = AR5K_RF2413; /* For testing */
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112A;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register returns 0x4 for radio revision
|
||||
* Register returns 0x0/0x04 for radio revision
|
||||
* so ath5k_hw_radio_revision doesn't parse the value
|
||||
* correctly. For now we are based on mac's srev to
|
||||
* identify RF2425 radio.
|
||||
*/
|
||||
} else if (srev == AR5K_SREV_VER_AR2425) {
|
||||
ah->ah_radio = AR5K_RF2425;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
|
||||
ah->ah_radio = AR5K_RF5111;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
|
||||
ah->ah_radio = AR5K_RF5112;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
|
||||
ah->ah_radio = AR5K_RF2413;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
|
||||
ah->ah_radio = AR5K_RF5413;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
|
||||
} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) {
|
||||
/* AR5424 */
|
||||
if (srev >= AR5K_SREV_VER_AR5424) {
|
||||
ah->ah_radio = AR5K_RF5413;
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
|
||||
/* AR2424 */
|
||||
} else {
|
||||
ah->ah_radio = AR5K_RF2413; /* For testing */
|
||||
ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
|
||||
}
|
||||
}
|
||||
|
||||
ah->ah_phy = AR5K_PHY(0);
|
||||
|
||||
/*
|
||||
* Identify AR5212-based PCI-E cards
|
||||
* And write some initial settings.
|
||||
*
|
||||
* (doing a "strings" on ndis driver
|
||||
* -ar5211.sys- reveals the following
|
||||
* pci-e related functions:
|
||||
*
|
||||
* pcieClockReq
|
||||
* pcieRxErrNotify
|
||||
* pcieL1SKPEnable
|
||||
* pcieAspm
|
||||
* pcieDisableAspmOnRfWake
|
||||
* pciePowerSaveEnable
|
||||
*
|
||||
* I guess these point to ClockReq but
|
||||
* i'm not sure.)
|
||||
* Write PCI-E power save settings
|
||||
*/
|
||||
if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
|
||||
ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080);
|
||||
@ -369,10 +350,15 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
|
||||
if (ret)
|
||||
goto err_free;
|
||||
|
||||
/* Write AR5K_PCICFG_UNK on 2112B and later chips */
|
||||
if (ah->ah_radio_5ghz_revision > AR5K_SREV_RAD_2112B ||
|
||||
srev > AR5K_SREV_VER_AR2413) {
|
||||
ath5k_hw_reg_write(ah, AR5K_PCICFG_UNK, AR5K_PCICFG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get card capabilities, values, ...
|
||||
*/
|
||||
|
||||
ret = ath5k_eeprom_init(ah);
|
||||
if (ret) {
|
||||
ATH5K_ERR(sc, "unable to init EEPROM\n");
|
||||
@ -843,27 +829,41 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
* Write some more initial register settings
|
||||
*/
|
||||
if (ah->ah_version == AR5K_AR5212) {
|
||||
ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11));
|
||||
ath5k_hw_reg_write(ah, 0x0002a002, 0x982c);
|
||||
|
||||
if (channel->hw_value == CHANNEL_G)
|
||||
if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413)
|
||||
ath5k_hw_reg_write(ah, 0x00f80d80,
|
||||
AR5K_PHY(83));
|
||||
0x994c);
|
||||
else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424)
|
||||
ath5k_hw_reg_write(ah, 0x00380140,
|
||||
AR5K_PHY(83));
|
||||
0x994c);
|
||||
else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425)
|
||||
ath5k_hw_reg_write(ah, 0x00fc0ec0,
|
||||
AR5K_PHY(83));
|
||||
0x994c);
|
||||
else /* 2425 */
|
||||
ath5k_hw_reg_write(ah, 0x00fc0fc0,
|
||||
AR5K_PHY(83));
|
||||
0x994c);
|
||||
else
|
||||
ath5k_hw_reg_write(ah, 0x00000000,
|
||||
AR5K_PHY(83));
|
||||
ath5k_hw_reg_write(ah, 0x00000000, 0x994c);
|
||||
|
||||
ath5k_hw_reg_write(ah, 0x000009b5, 0xa228);
|
||||
ath5k_hw_reg_write(ah, 0x0000000f, 0x8060);
|
||||
/* Some bits are disabled here, we know nothing about
|
||||
* register 0xa228 yet, most of the times this ends up
|
||||
* with a value 0x9b5 -haven't seen any dump with
|
||||
* a different value- */
|
||||
/* Got this from decompiling binary HAL */
|
||||
data = ath5k_hw_reg_read(ah, 0xa228);
|
||||
data &= 0xfffffdff;
|
||||
ath5k_hw_reg_write(ah, data, 0xa228);
|
||||
|
||||
data = ath5k_hw_reg_read(ah, 0xa228);
|
||||
data &= 0xfffe03ff;
|
||||
ath5k_hw_reg_write(ah, data, 0xa228);
|
||||
data = 0;
|
||||
|
||||
/* Just write 0x9b5 ? */
|
||||
/* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */
|
||||
ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
|
||||
ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
|
||||
ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL);
|
||||
}
|
||||
@ -879,6 +879,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
else
|
||||
data = 0xffb80d20;
|
||||
ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
|
||||
data = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -898,7 +899,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
|
||||
/*
|
||||
* Write RF registers
|
||||
* TODO:Does this work on 5211 (5111) ?
|
||||
*/
|
||||
ret = ath5k_hw_rfregs(ah, channel, mode);
|
||||
if (ret)
|
||||
@ -935,7 +935,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
return ret;
|
||||
|
||||
/* Set antenna mode */
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x44),
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL,
|
||||
ah->ah_antenna[ee_mode][0], 0xfffffc06);
|
||||
|
||||
/*
|
||||
@ -965,15 +965,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
|
||||
ath5k_hw_reg_write(ah,
|
||||
AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
|
||||
AR5K_PHY(0x5a));
|
||||
AR5K_PHY_NFTHRES);
|
||||
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x11),
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING,
|
||||
(ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
|
||||
0xffffc07f);
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x12),
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN,
|
||||
(ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000,
|
||||
0xfffc0fff);
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x14),
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE,
|
||||
(ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
|
||||
((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00),
|
||||
0xffff0000);
|
||||
@ -982,13 +982,13 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
(ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
|
||||
(ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
|
||||
(ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
|
||||
(ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY(0x0d));
|
||||
(ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
|
||||
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x0a),
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3,
|
||||
ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x19),
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF,
|
||||
(ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x49), 4, 0xffffff01);
|
||||
AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01);
|
||||
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
|
||||
AR5K_PHY_IQ_CORR_ENABLE |
|
||||
@ -1063,7 +1063,8 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
|
||||
|
||||
/*
|
||||
* 5111/5112 Specific
|
||||
* On 5211+ read activation -> rx delay
|
||||
* and use it.
|
||||
*/
|
||||
if (ah->ah_version != AR5K_AR5210) {
|
||||
data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
|
||||
@ -1071,32 +1072,45 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
data = (channel->hw_value & CHANNEL_CCK) ?
|
||||
((data << 2) / 22) : (data / 10);
|
||||
|
||||
udelay(100 + data);
|
||||
udelay(100 + (2 * data));
|
||||
data = 0;
|
||||
} else {
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable calibration and wait until completion
|
||||
* Perform ADC test (?)
|
||||
*/
|
||||
data = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
|
||||
for (i = 0; i <= 20; i++) {
|
||||
if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
|
||||
break;
|
||||
udelay(200);
|
||||
}
|
||||
ath5k_hw_reg_write(ah, data, AR5K_PHY_TST1);
|
||||
data = 0;
|
||||
|
||||
/*
|
||||
* Start automatic gain calibration
|
||||
*
|
||||
* During AGC calibration RX path is re-routed to
|
||||
* a signal detector so we don't receive anything.
|
||||
*
|
||||
* This method is used to calibrate some static offsets
|
||||
* used together with on-the fly I/Q calibration (the
|
||||
* one performed via ath5k_hw_phy_calibrate), that doesn't
|
||||
* interrupt rx path.
|
||||
*
|
||||
* If we are in a noisy environment AGC calibration may time
|
||||
* out.
|
||||
*/
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
|
||||
AR5K_PHY_AGCCTL_CAL);
|
||||
|
||||
if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
|
||||
AR5K_PHY_AGCCTL_CAL, 0, false)) {
|
||||
ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n",
|
||||
channel->center_freq);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* At the same time start I/Q calibration for QAM constellation
|
||||
* -no need for CCK- */
|
||||
ah->ah_calibration = false;
|
||||
|
||||
/* A and G modes can use QAM modulation which requires enabling
|
||||
* I and Q calibration. Don't bother in B mode. */
|
||||
if (!(mode == AR5K_MODE_11B)) {
|
||||
ah->ah_calibration = true;
|
||||
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
|
||||
@ -1105,6 +1119,30 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
AR5K_PHY_IQ_RUN);
|
||||
}
|
||||
|
||||
/* Wait for gain calibration to finish (we check for I/Q calibration
|
||||
* during ath5k_phy_calibrate) */
|
||||
if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
|
||||
AR5K_PHY_AGCCTL_CAL, 0, false)) {
|
||||
ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
|
||||
channel->center_freq);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Start noise floor calibration
|
||||
*
|
||||
* If we run NF calibration before AGC, it always times out.
|
||||
* Binary HAL starts NF and AGC calibration at the same time
|
||||
* and only waits for AGC to finish. I believe that's wrong because
|
||||
* during NF calibration, rx path is also routed to a detector, so if
|
||||
* it doesn't finish we won't have RX.
|
||||
*
|
||||
* XXX: Find an interval that's OK for all cards...
|
||||
*/
|
||||
ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Reset queues and start beacon timers at the end of the reset routine
|
||||
*/
|
||||
@ -1154,6 +1192,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
|
||||
ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
|
||||
ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING);
|
||||
|
||||
data = ath5k_hw_reg_read(ah, AR5K_USEC_5211) & 0xffffc07f ;
|
||||
data |= (ah->ah_phy_spending == AR5K_PHY_SPENDING_18) ?
|
||||
0x00000f80 : 0x00001380 ;
|
||||
ath5k_hw_reg_write(ah, data, AR5K_USEC_5211);
|
||||
data = 0;
|
||||
}
|
||||
|
||||
if (ah->ah_version == AR5K_AR5212) {
|
||||
@ -1226,7 +1270,7 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
|
||||
bool set_chip, u16 sleep_duration)
|
||||
{
|
||||
unsigned int i;
|
||||
u32 staid;
|
||||
u32 staid, data;
|
||||
|
||||
ATH5K_TRACE(ah->ah_sc);
|
||||
staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
|
||||
@ -1238,7 +1282,8 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
|
||||
case AR5K_PM_NETWORK_SLEEP:
|
||||
if (set_chip)
|
||||
ath5k_hw_reg_write(ah,
|
||||
AR5K_SLEEP_CTL_SLE | sleep_duration,
|
||||
AR5K_SLEEP_CTL_SLE_ALLOW |
|
||||
sleep_duration,
|
||||
AR5K_SLEEP_CTL);
|
||||
|
||||
staid |= AR5K_STA_ID1_PWR_SV;
|
||||
@ -1253,13 +1298,24 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
|
||||
break;
|
||||
|
||||
case AR5K_PM_AWAKE:
|
||||
|
||||
staid &= ~AR5K_STA_ID1_PWR_SV;
|
||||
|
||||
if (!set_chip)
|
||||
goto commit;
|
||||
|
||||
ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
|
||||
AR5K_SLEEP_CTL);
|
||||
/* Preserve sleep duration */
|
||||
data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
|
||||
if( data & 0xffc00000 ){
|
||||
data = 0;
|
||||
} else {
|
||||
data = data & 0xfffcffff;
|
||||
}
|
||||
|
||||
for (i = 5000; i > 0; i--) {
|
||||
ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
|
||||
udelay(15);
|
||||
|
||||
for (i = 50; i > 0; i--) {
|
||||
/* Check if the chip did wake up */
|
||||
if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
|
||||
AR5K_PCICFG_SPWR_DN) == 0)
|
||||
@ -1267,15 +1323,13 @@ int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
|
||||
|
||||
/* Wait a bit and retry */
|
||||
udelay(200);
|
||||
ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
|
||||
AR5K_SLEEP_CTL);
|
||||
ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
|
||||
}
|
||||
|
||||
/* Fail if the chip didn't wake up */
|
||||
if (i <= 0)
|
||||
return -EIO;
|
||||
|
||||
staid &= ~AR5K_STA_ID1_PWR_SV;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1304,6 +1358,7 @@ void ath5k_hw_start_rx(struct ath5k_hw *ah)
|
||||
{
|
||||
ATH5K_TRACE(ah->ah_sc);
|
||||
ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
|
||||
ath5k_hw_reg_read(ah, AR5K_CR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1390,6 +1445,7 @@ int ath5k_hw_tx_start(struct ath5k_hw *ah, unsigned int queue)
|
||||
}
|
||||
/* Start queue */
|
||||
ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
|
||||
ath5k_hw_reg_read(ah, AR5K_CR);
|
||||
} else {
|
||||
/* Return if queue is disabled */
|
||||
if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue))
|
||||
@ -1687,6 +1743,7 @@ enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask)
|
||||
* (they will be re-enabled afterwards).
|
||||
*/
|
||||
ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
|
||||
ath5k_hw_reg_read(ah, AR5K_IER);
|
||||
|
||||
old_mask = ah->ah_imr;
|
||||
|
||||
@ -3363,11 +3420,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
|
||||
ath5k_hw_reg_write(ah, ah->ah_turbo ?
|
||||
AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
|
||||
AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
|
||||
/* Set PHY register 0x9844 (??) */
|
||||
/* Set AR5K_PHY_SETTLING */
|
||||
ath5k_hw_reg_write(ah, ah->ah_turbo ?
|
||||
(ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x38 :
|
||||
(ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x1C,
|
||||
AR5K_PHY(17));
|
||||
(ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
|
||||
| 0x38 :
|
||||
(ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
|
||||
| 0x1C,
|
||||
AR5K_PHY_SETTLING);
|
||||
/* Set Frame Control Register */
|
||||
ath5k_hw_reg_write(ah, ah->ah_turbo ?
|
||||
(AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
|
||||
@ -3488,7 +3547,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
|
||||
AR5K_REG_ENABLE_BITS(ah,
|
||||
AR5K_QUEUE_MISC(queue),
|
||||
AR5K_QCU_MISC_TXE);
|
||||
AR5K_QCU_MISC_RDY_VEOL_POLICY);
|
||||
}
|
||||
|
||||
if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
|
||||
|
@ -489,7 +489,7 @@ static const struct ath5k_ini ar5212_ini[] = {
|
||||
{ AR5K_QUEUE_TXDP(9), 0x00000000 },
|
||||
{ AR5K_DCU_FP, 0x00000000 },
|
||||
{ AR5K_DCU_TXP, 0x00000000 },
|
||||
{ AR5K_DCU_TX_FILTER, 0x00000000 },
|
||||
{ AR5K_DCU_TX_FILTER_0_BASE, 0x00000000 },
|
||||
/* Unknown table */
|
||||
{ 0x1078, 0x00000000 },
|
||||
{ 0x10b8, 0x00000000 },
|
||||
@ -679,7 +679,7 @@ static const struct ath5k_ini ar5212_ini[] = {
|
||||
{ AR5K_PHY(645), 0x00106c10 },
|
||||
{ AR5K_PHY(646), 0x009c4060 },
|
||||
{ AR5K_PHY(647), 0x1483800a },
|
||||
/* { AR5K_PHY(648), 0x018830c6 },*/ /* 2413 */
|
||||
/* { AR5K_PHY(648), 0x018830c6 },*/ /* 2413/2425 */
|
||||
{ AR5K_PHY(648), 0x01831061 },
|
||||
{ AR5K_PHY(649), 0x00000400 },
|
||||
/*{ AR5K_PHY(650), 0x000001b5 },*/
|
||||
|
@ -1020,6 +1020,74 @@ static const struct ath5k_ini_rfgain rfgain_2413[] = {
|
||||
{ AR5K_RF_GAIN(63), { 0x000000f9 } },
|
||||
};
|
||||
|
||||
/* Initial RF Gain settings for RF2425 */
|
||||
static const struct ath5k_ini_rfgain rfgain_2425[] = {
|
||||
{ AR5K_RF_GAIN(0), { 0x00000000 } },
|
||||
{ AR5K_RF_GAIN(1), { 0x00000040 } },
|
||||
{ AR5K_RF_GAIN(2), { 0x00000080 } },
|
||||
{ AR5K_RF_GAIN(3), { 0x00000181 } },
|
||||
{ AR5K_RF_GAIN(4), { 0x000001c1 } },
|
||||
{ AR5K_RF_GAIN(5), { 0x00000001 } },
|
||||
{ AR5K_RF_GAIN(6), { 0x00000041 } },
|
||||
{ AR5K_RF_GAIN(7), { 0x00000081 } },
|
||||
{ AR5K_RF_GAIN(8), { 0x00000188 } },
|
||||
{ AR5K_RF_GAIN(9), { 0x000001c8 } },
|
||||
{ AR5K_RF_GAIN(10), { 0x00000008 } },
|
||||
{ AR5K_RF_GAIN(11), { 0x00000048 } },
|
||||
{ AR5K_RF_GAIN(12), { 0x00000088 } },
|
||||
{ AR5K_RF_GAIN(13), { 0x00000189 } },
|
||||
{ AR5K_RF_GAIN(14), { 0x000001c9 } },
|
||||
{ AR5K_RF_GAIN(15), { 0x00000009 } },
|
||||
{ AR5K_RF_GAIN(16), { 0x00000049 } },
|
||||
{ AR5K_RF_GAIN(17), { 0x00000089 } },
|
||||
{ AR5K_RF_GAIN(18), { 0x000001b0 } },
|
||||
{ AR5K_RF_GAIN(19), { 0x000001f0 } },
|
||||
{ AR5K_RF_GAIN(20), { 0x00000030 } },
|
||||
{ AR5K_RF_GAIN(21), { 0x00000070 } },
|
||||
{ AR5K_RF_GAIN(22), { 0x00000171 } },
|
||||
{ AR5K_RF_GAIN(23), { 0x000001b1 } },
|
||||
{ AR5K_RF_GAIN(24), { 0x000001f1 } },
|
||||
{ AR5K_RF_GAIN(25), { 0x00000031 } },
|
||||
{ AR5K_RF_GAIN(26), { 0x00000071 } },
|
||||
{ AR5K_RF_GAIN(27), { 0x000001b8 } },
|
||||
{ AR5K_RF_GAIN(28), { 0x000001f8 } },
|
||||
{ AR5K_RF_GAIN(29), { 0x00000038 } },
|
||||
{ AR5K_RF_GAIN(30), { 0x00000078 } },
|
||||
{ AR5K_RF_GAIN(31), { 0x000000b8 } },
|
||||
{ AR5K_RF_GAIN(32), { 0x000001b9 } },
|
||||
{ AR5K_RF_GAIN(33), { 0x000001f9 } },
|
||||
{ AR5K_RF_GAIN(34), { 0x00000039 } },
|
||||
{ AR5K_RF_GAIN(35), { 0x00000079 } },
|
||||
{ AR5K_RF_GAIN(36), { 0x000000b9 } },
|
||||
{ AR5K_RF_GAIN(37), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(38), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(39), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(40), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(41), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(42), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(43), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(44), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(45), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(46), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(47), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(48), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(49), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(50), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(51), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(52), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(53), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(54), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(55), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(56), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(57), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(58), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(59), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(60), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(61), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(62), { 0x000000f9 } },
|
||||
{ AR5K_RF_GAIN(63), { 0x000000f9 } },
|
||||
};
|
||||
|
||||
static const struct ath5k_gain_opt rfgain_opt_5112 = {
|
||||
1,
|
||||
8,
|
||||
@ -1588,8 +1656,8 @@ int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq)
|
||||
freq = 0; /* only 2Ghz */
|
||||
break;
|
||||
case AR5K_RF2425:
|
||||
ath5k_rfg = rfgain_2413;
|
||||
size = ARRAY_SIZE(rfgain_2413);
|
||||
ath5k_rfg = rfgain_2425;
|
||||
size = ARRAY_SIZE(rfgain_2425);
|
||||
freq = 0; /* only 2Ghz */
|
||||
break;
|
||||
default:
|
||||
@ -1830,9 +1898,6 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
|
||||
data = data0 = data1 = data2 = 0;
|
||||
c = channel->center_freq;
|
||||
|
||||
/*
|
||||
* Set the channel on the RF5112 or newer
|
||||
*/
|
||||
if (c < 4800) {
|
||||
if (!((c - 2224) % 5)) {
|
||||
data0 = ((2 * (c - 704)) - 3040) / 10;
|
||||
@ -1844,7 +1909,7 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
|
||||
return -EINVAL;
|
||||
|
||||
data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8);
|
||||
} else {
|
||||
} else if ((c - (c % 5)) != 2 || c > 5435) {
|
||||
if (!(c % 20) && c >= 5120) {
|
||||
data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
|
||||
data2 = ath5k_hw_bitswap(3, 2);
|
||||
@ -1856,6 +1921,9 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
|
||||
data2 = ath5k_hw_bitswap(1, 2);
|
||||
} else
|
||||
return -EINVAL;
|
||||
} else {
|
||||
data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
|
||||
data2 = ath5k_hw_bitswap(0, 2);
|
||||
}
|
||||
|
||||
data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
|
||||
@ -1866,6 +1934,45 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the channel on the RF2425
|
||||
*/
|
||||
static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
|
||||
struct ieee80211_channel *channel)
|
||||
{
|
||||
u32 data, data0, data2;
|
||||
u16 c;
|
||||
|
||||
data = data0 = data2 = 0;
|
||||
c = channel->center_freq;
|
||||
|
||||
if (c < 4800) {
|
||||
data0 = ath5k_hw_bitswap((c - 2272), 8);
|
||||
data2 = 0;
|
||||
/* ? 5GHz ? */
|
||||
} else if ((c - (c % 5)) != 2 || c > 5435) {
|
||||
if (!(c % 20) && c < 5120)
|
||||
data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
|
||||
else if (!(c % 10))
|
||||
data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
|
||||
else if (!(c % 5))
|
||||
data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
|
||||
else
|
||||
return -EINVAL;
|
||||
data2 = ath5k_hw_bitswap(1, 2);
|
||||
} else {
|
||||
data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
|
||||
data2 = ath5k_hw_bitswap(0, 2);
|
||||
}
|
||||
|
||||
data = (data0 << 4) | data2 << 2 | 0x1001;
|
||||
|
||||
ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
|
||||
ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set a channel on the radio chip
|
||||
*/
|
||||
@ -1895,6 +2002,9 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
|
||||
case AR5K_RF5111:
|
||||
ret = ath5k_hw_rf5111_channel(ah, channel);
|
||||
break;
|
||||
case AR5K_RF2425:
|
||||
ret = ath5k_hw_rf2425_channel(ah, channel);
|
||||
break;
|
||||
default:
|
||||
ret = ath5k_hw_rf5112_channel(ah, channel);
|
||||
break;
|
||||
@ -1903,6 +2013,15 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Set JAPAN setting for channel 14 */
|
||||
if (channel->center_freq == 2484) {
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
|
||||
AR5K_PHY_CCKTXCTL_JAPAN);
|
||||
} else {
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
|
||||
AR5K_PHY_CCKTXCTL_WORLD);
|
||||
}
|
||||
|
||||
ah->ah_current_channel.center_freq = channel->center_freq;
|
||||
ah->ah_current_channel.hw_value = channel->hw_value;
|
||||
ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
|
||||
@ -1933,6 +2052,8 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
|
||||
* http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL \
|
||||
* &p=1&u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&r=1&f=G&l=50&s1=7245893.PN.&OS=PN/7
|
||||
*
|
||||
* XXX: Since during noise floor calibration antennas are detached according to
|
||||
* the patent, we should stop tx queues here.
|
||||
*/
|
||||
int
|
||||
ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
|
||||
@ -1942,7 +2063,7 @@ ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
|
||||
s32 noise_floor;
|
||||
|
||||
/*
|
||||
* Enable noise floor calibration and wait until completion
|
||||
* Enable noise floor calibration
|
||||
*/
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
|
||||
AR5K_PHY_AGCCTL_NF);
|
||||
@ -1952,7 +2073,7 @@ ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
|
||||
if (ret) {
|
||||
ATH5K_ERR(ah->ah_sc,
|
||||
"noise floor calibration timeout (%uMHz)\n", freq);
|
||||
return ret;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Wait until the noise floor is calibrated and read the value */
|
||||
@ -1974,7 +2095,7 @@ ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
|
||||
if (noise_floor > AR5K_TUNE_NOISE_FLOOR) {
|
||||
ATH5K_ERR(ah->ah_sc,
|
||||
"noise floor calibration failed (%uMHz)\n", freq);
|
||||
return -EIO;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
ah->ah_noise_floor = noise_floor;
|
||||
@ -2087,38 +2208,66 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a PHY calibration on RF5111/5112
|
||||
* Perform a PHY calibration on RF5111/5112 and newer chips
|
||||
*/
|
||||
static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
|
||||
struct ieee80211_channel *channel)
|
||||
{
|
||||
u32 i_pwr, q_pwr;
|
||||
s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
|
||||
int i;
|
||||
ATH5K_TRACE(ah->ah_sc);
|
||||
|
||||
if (!ah->ah_calibration ||
|
||||
ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN)
|
||||
ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN)
|
||||
goto done;
|
||||
|
||||
ah->ah_calibration = false;
|
||||
/* Calibration has finished, get the results and re-run */
|
||||
for (i = 0; i <= 10; i++) {
|
||||
iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
|
||||
i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
|
||||
q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
|
||||
}
|
||||
|
||||
iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
|
||||
i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
|
||||
q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
|
||||
i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
|
||||
q_coffd = q_pwr >> 6;
|
||||
q_coffd = q_pwr >> 7;
|
||||
|
||||
/* No correction */
|
||||
if (i_coffd == 0 || q_coffd == 0)
|
||||
goto done;
|
||||
|
||||
i_coff = ((-iq_corr) / i_coffd) & 0x3f;
|
||||
q_coff = (((s32)i_pwr / q_coffd) - 64) & 0x1f;
|
||||
|
||||
/* Commit new IQ value */
|
||||
/* Boundary check */
|
||||
if (i_coff > 31)
|
||||
i_coff = 31;
|
||||
if (i_coff < -32)
|
||||
i_coff = -32;
|
||||
|
||||
q_coff = (((s32)i_pwr / q_coffd) - 128) & 0x1f;
|
||||
|
||||
/* Boundary check */
|
||||
if (q_coff > 15)
|
||||
q_coff = 15;
|
||||
if (q_coff < -16)
|
||||
q_coff = -16;
|
||||
|
||||
/* Commit new I/Q value */
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE |
|
||||
((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S));
|
||||
|
||||
/* Re-enable calibration -if we don't we'll commit
|
||||
* the same values again and again */
|
||||
AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
|
||||
AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
|
||||
AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN);
|
||||
|
||||
done:
|
||||
|
||||
/* TODO: Separate noise floor calibration from I/Q calibration
|
||||
* since noise floor calibration interrupts rx path while I/Q
|
||||
* calibration doesn't. We don't need to run noise floor calibration
|
||||
* as often as I/Q calibration.*/
|
||||
ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
|
||||
|
||||
/* Request RF gain */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -305,9 +305,10 @@ static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)
|
||||
#define _ipw_write8(ipw, ofs, val) writeb((val), (ipw)->hw_base + (ofs))
|
||||
|
||||
/* 8-bit direct write (for low 4K of SRAM/regs), with debug wrapper */
|
||||
#define ipw_write8(ipw, ofs, val) \
|
||||
#define ipw_write8(ipw, ofs, val) do { \
|
||||
IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, __LINE__, (u32)(ofs), (u32)(val)); \
|
||||
_ipw_write8(ipw, ofs, val)
|
||||
_ipw_write8(ipw, ofs, val); \
|
||||
} while (0)
|
||||
|
||||
/* 16-bit direct write (low 4K) */
|
||||
#define _ipw_write16(ipw, ofs, val) writew((val), (ipw)->hw_base + (ofs))
|
||||
|
@ -14,18 +14,49 @@ config IWLWIFI_LEDS
|
||||
default n
|
||||
|
||||
config IWLWIFI_RFKILL
|
||||
boolean "IWLWIFI RF kill support"
|
||||
boolean "Iwlwifi RF kill support"
|
||||
depends on IWLCORE
|
||||
|
||||
config IWL4965
|
||||
tristate "Intel Wireless WiFi 4965AGN"
|
||||
config IWLWIFI_DEBUG
|
||||
bool "Enable full debugging output in iwlagn driver"
|
||||
depends on IWLCORE
|
||||
---help---
|
||||
This option will enable debug tracing output for the iwlwifi drivers
|
||||
|
||||
This will result in the kernel module being ~100k larger. You can
|
||||
control which debug output is sent to the kernel log by setting the
|
||||
value in
|
||||
|
||||
/sys/class/net/wlan0/device/debug_level
|
||||
|
||||
This entry will only exist if this option is enabled.
|
||||
|
||||
To set a value, simply echo an 8-byte hex value to the same file:
|
||||
|
||||
% echo 0x43fff > /sys/class/net/wlan0/device/debug_level
|
||||
|
||||
You can find the list of debug mask values in:
|
||||
drivers/net/wireless/iwlwifi/iwl-debug.h
|
||||
|
||||
If this is your first time using this driver, you should say Y here
|
||||
as the debug information can assist others in helping you resolve
|
||||
any problems you may encounter.
|
||||
|
||||
config IWLWIFI_DEBUGFS
|
||||
bool "Iwlwifi debugfs support"
|
||||
depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS
|
||||
---help---
|
||||
Enable creation of debugfs files for the iwlwifi drivers.
|
||||
|
||||
config IWLAGN
|
||||
tristate "Intel Wireless WiFi Next Gen AGN"
|
||||
depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
|
||||
select FW_LOADER
|
||||
select IWLCORE
|
||||
---help---
|
||||
Select to build the driver supporting the:
|
||||
|
||||
Intel Wireless WiFi Link 4965AGN
|
||||
Intel Wireless WiFi Link Next-Gen AGN
|
||||
|
||||
This driver uses the kernel's mac80211 subsystem.
|
||||
|
||||
@ -42,60 +73,33 @@ config IWL4965
|
||||
If you want to compile the driver as a module ( = code which can be
|
||||
inserted in and removed from the running kernel whenever you want),
|
||||
say M here and read <file:Documentation/kbuild/modules.txt>. The
|
||||
module will be called iwl4965.ko.
|
||||
module will be called iwlagn.ko.
|
||||
|
||||
config IWL4965_LEDS
|
||||
bool "Enable LEDS features in iwl4965 driver"
|
||||
depends on IWL4965
|
||||
config IWLAGN_SPECTRUM_MEASUREMENT
|
||||
bool "Enable Spectrum Measurement in iwlagn driver"
|
||||
depends on IWLAGN
|
||||
---help---
|
||||
This option will enable spectrum measurement for the iwlagn driver.
|
||||
|
||||
config IWLAGN_LEDS
|
||||
bool "Enable LEDS features in iwlagn driver"
|
||||
depends on IWLAGN
|
||||
select IWLWIFI_LEDS
|
||||
---help---
|
||||
This option enables LEDS for the iwlwifi drivers
|
||||
This option enables LEDS for the iwlagn drivers
|
||||
|
||||
|
||||
config IWL4965_SPECTRUM_MEASUREMENT
|
||||
bool "Enable Spectrum Measurement in iwl4965 driver"
|
||||
depends on IWL4965
|
||||
config IWL4965
|
||||
bool "Intel Wireless WiFi 4965AGN"
|
||||
depends on IWLAGN
|
||||
---help---
|
||||
This option will enable spectrum measurement for the iwl4965 driver.
|
||||
|
||||
config IWLWIFI_DEBUG
|
||||
bool "Enable full debugging output in iwl4965 driver"
|
||||
depends on IWL4965
|
||||
---help---
|
||||
This option will enable debug tracing output for the iwl4965
|
||||
driver.
|
||||
|
||||
This will result in the kernel module being ~100k larger. You can
|
||||
control which debug output is sent to the kernel log by setting the
|
||||
value in
|
||||
|
||||
/sys/class/net/wlan0/device/debug_level
|
||||
|
||||
This entry will only exist if this option is enabled.
|
||||
|
||||
To set a value, simply echo an 8-byte hex value to the same file:
|
||||
|
||||
% echo 0x43fff > /sys/class/net/wlan0/device/debug_level
|
||||
|
||||
You can find the list of debug mask values in:
|
||||
drivers/net/wireless/iwlwifi/iwl-4965-debug.h
|
||||
|
||||
If this is your first time using this driver, you should say Y here
|
||||
as the debug information can assist others in helping you resolve
|
||||
any problems you may encounter.
|
||||
This option enables support for Intel Wireless WiFi Link 4965AGN
|
||||
|
||||
config IWL5000
|
||||
bool "Intel Wireless WiFi 5000AGN"
|
||||
depends on IWL4965
|
||||
depends on IWLAGN
|
||||
---help---
|
||||
This option enables support for Intel Wireless WiFi Link 5000AGN Family
|
||||
Dependency on 4965 is temporary
|
||||
|
||||
config IWLWIFI_DEBUGFS
|
||||
bool "Iwlwifi debugfs support"
|
||||
depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS
|
||||
---help---
|
||||
Enable creation of debugfs files for the iwlwifi drivers.
|
||||
|
||||
config IWL3945
|
||||
tristate "Intel PRO/Wireless 3945ABG/BG Network Connection"
|
||||
|
@ -6,15 +6,14 @@ iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
|
||||
iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
|
||||
iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
|
||||
|
||||
obj-$(CONFIG_IWLAGN) += iwlagn.o
|
||||
iwlagn-objs := iwl-agn.o iwl-agn-rs.o
|
||||
|
||||
iwlagn-$(CONFIG_IWL4965) += iwl-4965.o
|
||||
iwlagn-$(CONFIG_IWL5000) += iwl-5000.o
|
||||
|
||||
obj-$(CONFIG_IWL3945) += iwl3945.o
|
||||
iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o
|
||||
iwl3945-$(CONFIG_IWL3945_LEDS) += iwl-3945-led.o
|
||||
|
||||
obj-$(CONFIG_IWL4965) += iwl4965.o
|
||||
iwl4965-objs := iwl4965-base.o iwl-4965.o iwl-4965-rs.o
|
||||
|
||||
ifeq ($(CONFIG_IWL5000),y)
|
||||
iwl4965-objs += iwl-5000.o
|
||||
endif
|
||||
|
||||
|
||||
|
@ -206,12 +206,12 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
|
||||
static int iwl3945_led_register_led(struct iwl3945_priv *priv,
|
||||
struct iwl3945_led *led,
|
||||
enum led_type type, u8 set_led,
|
||||
const char *name, char *trigger)
|
||||
char *trigger)
|
||||
{
|
||||
struct device *device = wiphy_dev(priv->hw->wiphy);
|
||||
int ret;
|
||||
|
||||
led->led_dev.name = name;
|
||||
led->led_dev.name = led->name;
|
||||
led->led_dev.brightness_set = iwl3945_led_brightness_set;
|
||||
led->led_dev.default_trigger = trigger;
|
||||
|
||||
@ -308,7 +308,6 @@ void iwl3945_led_background(struct iwl3945_priv *priv)
|
||||
int iwl3945_led_register(struct iwl3945_priv *priv)
|
||||
{
|
||||
char *trigger;
|
||||
char name[32];
|
||||
int ret;
|
||||
|
||||
priv->last_blink_rate = 0;
|
||||
@ -318,7 +317,8 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
|
||||
priv->allow_blinking = 0;
|
||||
|
||||
trigger = ieee80211_get_radio_led_name(priv->hw);
|
||||
snprintf(name, sizeof(name), "iwl-%s:radio",
|
||||
snprintf(priv->led[IWL_LED_TRG_RADIO].name,
|
||||
sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s:radio",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
|
||||
priv->led[IWL_LED_TRG_RADIO].led_on = iwl3945_led_on;
|
||||
@ -327,19 +327,20 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
|
||||
|
||||
ret = iwl3945_led_register_led(priv,
|
||||
&priv->led[IWL_LED_TRG_RADIO],
|
||||
IWL_LED_TRG_RADIO, 1,
|
||||
name, trigger);
|
||||
IWL_LED_TRG_RADIO, 1, trigger);
|
||||
|
||||
if (ret)
|
||||
goto exit_fail;
|
||||
|
||||
trigger = ieee80211_get_assoc_led_name(priv->hw);
|
||||
snprintf(name, sizeof(name), "iwl-%s:assoc",
|
||||
snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
|
||||
sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
|
||||
ret = iwl3945_led_register_led(priv,
|
||||
&priv->led[IWL_LED_TRG_ASSOC],
|
||||
IWL_LED_TRG_ASSOC, 0,
|
||||
name, trigger);
|
||||
IWL_LED_TRG_ASSOC, 0, trigger);
|
||||
|
||||
/* for assoc always turn led on */
|
||||
priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on;
|
||||
priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on;
|
||||
@ -349,14 +350,13 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
|
||||
goto exit_fail;
|
||||
|
||||
trigger = ieee80211_get_rx_led_name(priv->hw);
|
||||
snprintf(name, sizeof(name), "iwl-%s:RX",
|
||||
snprintf(priv->led[IWL_LED_TRG_RX].name,
|
||||
sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s:RX",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
|
||||
|
||||
ret = iwl3945_led_register_led(priv,
|
||||
&priv->led[IWL_LED_TRG_RX],
|
||||
IWL_LED_TRG_RX, 0,
|
||||
name, trigger);
|
||||
IWL_LED_TRG_RX, 0, trigger);
|
||||
|
||||
priv->led[IWL_LED_TRG_RX].led_on = iwl3945_led_associated;
|
||||
priv->led[IWL_LED_TRG_RX].led_off = iwl3945_led_associated;
|
||||
@ -366,13 +366,14 @@ int iwl3945_led_register(struct iwl3945_priv *priv)
|
||||
goto exit_fail;
|
||||
|
||||
trigger = ieee80211_get_tx_led_name(priv->hw);
|
||||
snprintf(name, sizeof(name), "iwl-%s:TX",
|
||||
snprintf(priv->led[IWL_LED_TRG_TX].name,
|
||||
sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s:TX",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
|
||||
ret = iwl3945_led_register_led(priv,
|
||||
&priv->led[IWL_LED_TRG_TX],
|
||||
IWL_LED_TRG_TX, 0,
|
||||
name, trigger);
|
||||
IWL_LED_TRG_TX, 0, trigger);
|
||||
|
||||
priv->led[IWL_LED_TRG_TX].led_on = iwl3945_led_associated;
|
||||
priv->led[IWL_LED_TRG_TX].led_off = iwl3945_led_associated;
|
||||
priv->led[IWL_LED_TRG_TX].led_pattern = iwl3945_led_pattern;
|
||||
|
@ -50,6 +50,7 @@ enum led_type {
|
||||
struct iwl3945_led {
|
||||
struct iwl3945_priv *priv;
|
||||
struct led_classdev led_dev;
|
||||
char name[32];
|
||||
|
||||
int (*led_on) (struct iwl3945_priv *priv, int led_id);
|
||||
int (*led_off) (struct iwl3945_priv *priv, int led_id);
|
||||
|
@ -710,10 +710,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
|
||||
iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Convert 3945's rssi indicator to dBm */
|
||||
rx_status.signal = rx_stats->rssi - IWL_RSSI_OFFSET;
|
||||
@ -775,6 +772,11 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
|
||||
priv->last_rx_noise = rx_status.noise;
|
||||
}
|
||||
|
||||
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
|
||||
iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) {
|
||||
case IEEE80211_FTYPE_MGMT:
|
||||
switch (le16_to_cpu(header->frame_control) &
|
||||
@ -793,8 +795,7 @@ static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
|
||||
struct ieee80211_mgmt *mgmt =
|
||||
(struct ieee80211_mgmt *)header;
|
||||
__le32 *pos;
|
||||
pos =
|
||||
(__le32 *) & mgmt->u.beacon.
|
||||
pos = (__le32 *)&mgmt->u.beacon.
|
||||
timestamp;
|
||||
priv->timestamp0 = le32_to_cpu(pos[0]);
|
||||
priv->timestamp1 = le32_to_cpu(pos[1]);
|
||||
@ -1507,7 +1508,7 @@ static int iwl3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading)
|
||||
*/
|
||||
static inline int iwl3945_hw_reg_temp_out_of_range(int temperature)
|
||||
{
|
||||
return (((temperature < -260) || (temperature > 25)) ? 1 : 0);
|
||||
return ((temperature < -260) || (temperature > 25)) ? 1 : 0;
|
||||
}
|
||||
|
||||
int iwl3945_hw_get_temperature(struct iwl3945_priv *priv)
|
||||
@ -2628,7 +2629,7 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
|
||||
tx_beacon_cmd->tx.supp_rates[1] =
|
||||
(IWL_CCK_BASIC_RATES_MASK & 0xF);
|
||||
|
||||
return (sizeof(struct iwl3945_tx_beacon_cmd) + frame_size);
|
||||
return sizeof(struct iwl3945_tx_beacon_cmd) + frame_size;
|
||||
}
|
||||
|
||||
void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv)
|
||||
|
@ -341,39 +341,6 @@ static int iwl4965_eeprom_check_version(struct iwl_priv *priv)
|
||||
return -EINVAL;
|
||||
|
||||
}
|
||||
int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
|
||||
{
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
ret = iwl_grab_nic_access(priv);
|
||||
if (ret) {
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (src == IWL_PWR_SRC_VAUX) {
|
||||
u32 val;
|
||||
ret = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE,
|
||||
&val);
|
||||
|
||||
if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) {
|
||||
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
|
||||
APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
|
||||
~APMG_PS_CTRL_MSK_PWR_SRC);
|
||||
}
|
||||
} else {
|
||||
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
|
||||
APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
|
||||
~APMG_PS_CTRL_MSK_PWR_SRC);
|
||||
}
|
||||
|
||||
iwl_release_nic_access(priv);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Activate/Deactivat Tx DMA/FIFO channels according tx fifos mask
|
||||
@ -875,18 +842,6 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set card power command */
|
||||
static int iwl4965_set_power(struct iwl_priv *priv,
|
||||
void *cmd)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD,
|
||||
sizeof(struct iwl4965_powertable_cmd),
|
||||
cmd, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res)
|
||||
{
|
||||
s32 sign = 1;
|
||||
@ -1560,11 +1515,11 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
|
||||
c, atten_value, power_index,
|
||||
tx_power.s.radio_tx_gain[c],
|
||||
tx_power.s.dsp_predis_atten[c]);
|
||||
}/* for each chain */
|
||||
} /* for each chain */
|
||||
|
||||
tx_power_tbl->power_tbl[i].dw = cpu_to_le32(tx_power.dw);
|
||||
|
||||
}/* for each rate */
|
||||
} /* for each rate */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1701,38 +1656,6 @@ static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv)
|
||||
return le32_to_cpu(s->rb_closed) & 0xFFF;
|
||||
}
|
||||
|
||||
unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
|
||||
struct iwl_frame *frame, u8 rate)
|
||||
{
|
||||
struct iwl4965_tx_beacon_cmd *tx_beacon_cmd;
|
||||
unsigned int frame_size;
|
||||
|
||||
tx_beacon_cmd = &frame->u.beacon;
|
||||
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
|
||||
|
||||
tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
|
||||
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
|
||||
|
||||
frame_size = iwl4965_fill_beacon_frame(priv,
|
||||
tx_beacon_cmd->frame,
|
||||
iwl_bcast_addr,
|
||||
sizeof(frame->u) - sizeof(*tx_beacon_cmd));
|
||||
|
||||
BUG_ON(frame_size > MAX_MPDU_SIZE);
|
||||
tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
|
||||
|
||||
if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP))
|
||||
tx_beacon_cmd->tx.rate_n_flags =
|
||||
iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
|
||||
else
|
||||
tx_beacon_cmd->tx.rate_n_flags =
|
||||
iwl_hw_set_rate_n_flags(rate, 0);
|
||||
|
||||
tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK |
|
||||
TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK);
|
||||
return (sizeof(*tx_beacon_cmd) + frame_size);
|
||||
}
|
||||
|
||||
static int iwl4965_alloc_shared_mem(struct iwl_priv *priv)
|
||||
{
|
||||
priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
|
||||
@ -2079,39 +2002,6 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
const u8 *addr, u16 tid, u16 *ssn)
|
||||
{
|
||||
struct iwl_priv *priv = hw->priv;
|
||||
DECLARE_MAC_BUF(mac);
|
||||
|
||||
IWL_DEBUG_HT("A-MPDU action on addr %s tid %d\n",
|
||||
print_mac(mac, addr), tid);
|
||||
|
||||
if (!(priv->cfg->sku & IWL_SKU_N))
|
||||
return -EACCES;
|
||||
|
||||
switch (action) {
|
||||
case IEEE80211_AMPDU_RX_START:
|
||||
IWL_DEBUG_HT("start Rx\n");
|
||||
return iwl_rx_agg_start(priv, addr, tid, *ssn);
|
||||
case IEEE80211_AMPDU_RX_STOP:
|
||||
IWL_DEBUG_HT("stop Rx\n");
|
||||
return iwl_rx_agg_stop(priv, addr, tid);
|
||||
case IEEE80211_AMPDU_TX_START:
|
||||
IWL_DEBUG_HT("start Tx\n");
|
||||
return iwl_tx_agg_start(priv, addr, tid, ssn);
|
||||
case IEEE80211_AMPDU_TX_STOP:
|
||||
IWL_DEBUG_HT("stop Tx\n");
|
||||
return iwl_tx_agg_stop(priv, addr, tid);
|
||||
default:
|
||||
IWL_DEBUG_HT("unknown\n");
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len)
|
||||
{
|
||||
@ -2240,9 +2130,9 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
|
||||
bitmap = bitmap << sh;
|
||||
sh = 0;
|
||||
}
|
||||
bitmap |= (1 << sh);
|
||||
IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n",
|
||||
start, (u32)(bitmap & 0xFFFFFFFF));
|
||||
bitmap |= 1ULL << sh;
|
||||
IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
|
||||
start, (unsigned long long)bitmap);
|
||||
}
|
||||
|
||||
agg->bitmap = bitmap;
|
||||
@ -2368,6 +2258,40 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
|
||||
IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
|
||||
}
|
||||
|
||||
static int iwl4965_calc_rssi(struct iwl_priv *priv,
|
||||
struct iwl_rx_phy_res *rx_resp)
|
||||
{
|
||||
/* data from PHY/DSP regarding signal strength, etc.,
|
||||
* contents are always there, not configurable by host. */
|
||||
struct iwl4965_rx_non_cfg_phy *ncphy =
|
||||
(struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
|
||||
u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL49_AGC_DB_MASK)
|
||||
>> IWL49_AGC_DB_POS;
|
||||
|
||||
u32 valid_antennae =
|
||||
(le16_to_cpu(rx_resp->phy_flags) & IWL49_RX_PHY_FLAGS_ANTENNAE_MASK)
|
||||
>> IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET;
|
||||
u8 max_rssi = 0;
|
||||
u32 i;
|
||||
|
||||
/* Find max rssi among 3 possible receivers.
|
||||
* These values are measured by the digital signal processor (DSP).
|
||||
* They should stay fairly constant even as the signal strength varies,
|
||||
* if the radio's automatic gain control (AGC) is working right.
|
||||
* AGC value (see below) will provide the "interesting" info. */
|
||||
for (i = 0; i < 3; i++)
|
||||
if (valid_antennae & (1 << i))
|
||||
max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
|
||||
|
||||
IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
|
||||
ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
|
||||
max_rssi, agc);
|
||||
|
||||
/* dBm = max_rssi dB - agc dB - constant.
|
||||
* Higher AGC (higher radio gain) means lower signal. */
|
||||
return max_rssi - agc - IWL_RSSI_OFFSET;
|
||||
}
|
||||
|
||||
|
||||
/* Set up 4965-specific Rx frame reply handlers */
|
||||
static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
|
||||
@ -2399,6 +2323,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
|
||||
.chain_noise_reset = iwl4965_chain_noise_reset,
|
||||
.gain_computation = iwl4965_gain_computation,
|
||||
.rts_tx_cmd_flag = iwl4965_rts_tx_cmd_flag,
|
||||
.calc_rssi = iwl4965_calc_rssi,
|
||||
};
|
||||
|
||||
static struct iwl_lib_ops iwl4965_lib = {
|
||||
@ -2440,7 +2365,6 @@ static struct iwl_lib_ops iwl4965_lib = {
|
||||
.check_version = iwl4965_eeprom_check_version,
|
||||
.query_addr = iwlcore_eeprom_query_addr,
|
||||
},
|
||||
.set_power = iwl4965_set_power,
|
||||
.send_tx_power = iwl4965_send_tx_power,
|
||||
.update_chain_flags = iwl4965_update_chain_flags,
|
||||
.temperature = iwl4965_temperature_calib,
|
||||
|
@ -93,6 +93,13 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
|
||||
iwl_set_bit(priv, CSR_GIO_CHICKEN_BITS,
|
||||
CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
|
||||
|
||||
/* Set FH wait treshold to maximum (HW error during stress W/A) */
|
||||
iwl_set_bit(priv, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL);
|
||||
|
||||
/* enable HAP INTA to move device L1a -> L0s */
|
||||
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
|
||||
CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
|
||||
|
||||
iwl_set_bit(priv, CSR_ANA_PLL_CFG, CSR50_ANA_PLL_CFG_VAL);
|
||||
|
||||
/* set "initialization complete" bit to move adapter
|
||||
@ -230,6 +237,16 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
|
||||
CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
|
||||
CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
|
||||
|
||||
/* W/A : NIC is stuck in a reset state after Early PCIe power off
|
||||
* (PCIe power is lost before PERST# is asserted),
|
||||
* causing ME FW to lose ownership and not being able to obtain it back.
|
||||
*/
|
||||
iwl_grab_nic_access(priv);
|
||||
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
|
||||
APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
|
||||
~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
|
||||
iwl_release_nic_access(priv);
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
@ -924,8 +941,8 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
|
||||
len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
|
||||
|
||||
if (txq_id != IWL_CMD_QUEUE_NUM) {
|
||||
sta = txq->cmd[txq->q.write_ptr].cmd.tx.sta_id;
|
||||
sec_ctl = txq->cmd[txq->q.write_ptr].cmd.tx.sec_ctl;
|
||||
sta = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
|
||||
sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
|
||||
|
||||
switch (sec_ctl & TX_CMD_SEC_MSK) {
|
||||
case TX_CMD_SEC_CCM:
|
||||
@ -964,7 +981,7 @@ static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
|
||||
u8 sta = 0;
|
||||
|
||||
if (txq_id != IWL_CMD_QUEUE_NUM)
|
||||
sta = txq->cmd[txq->q.read_ptr].cmd.tx.sta_id;
|
||||
sta = txq->cmd[txq->q.read_ptr]->cmd.tx.sta_id;
|
||||
|
||||
shared_data->queues_byte_cnt_tbls[txq_id].tfd_offset[txq->q.read_ptr].
|
||||
val = cpu_to_le16(1 | (sta << 12));
|
||||
@ -1131,7 +1148,7 @@ static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask)
|
||||
|
||||
static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
|
||||
{
|
||||
return le32_to_cpup((__le32*)&tx_resp->status +
|
||||
return le32_to_cpup((__le32 *)&tx_resp->status +
|
||||
tx_resp->frame_count) & MAX_SN;
|
||||
}
|
||||
|
||||
@ -1228,9 +1245,9 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
|
||||
bitmap = bitmap << sh;
|
||||
sh = 0;
|
||||
}
|
||||
bitmap |= (1 << sh);
|
||||
IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%x\n",
|
||||
start, (u32)(bitmap & 0xFFFFFFFF));
|
||||
bitmap |= 1ULL << sh;
|
||||
IWL_DEBUG_TX_REPLY("start=%d bitmap=0x%llx\n",
|
||||
start, (unsigned long long)bitmap);
|
||||
}
|
||||
|
||||
agg->bitmap = bitmap;
|
||||
@ -1444,6 +1461,44 @@ static void iwl5000_temperature(struct iwl_priv *priv)
|
||||
priv->temperature = le32_to_cpu(priv->statistics.general.temperature);
|
||||
}
|
||||
|
||||
/* Calc max signal level (dBm) among 3 possible receivers */
|
||||
static int iwl5000_calc_rssi(struct iwl_priv *priv,
|
||||
struct iwl_rx_phy_res *rx_resp)
|
||||
{
|
||||
/* data from PHY/DSP regarding signal strength, etc.,
|
||||
* contents are always there, not configurable by host
|
||||
*/
|
||||
struct iwl5000_non_cfg_phy *ncphy =
|
||||
(struct iwl5000_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
|
||||
u32 val, rssi_a, rssi_b, rssi_c, max_rssi;
|
||||
u8 agc;
|
||||
|
||||
val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_AGC_IDX]);
|
||||
agc = (val & IWL50_OFDM_AGC_MSK) >> IWL50_OFDM_AGC_BIT_POS;
|
||||
|
||||
/* Find max rssi among 3 possible receivers.
|
||||
* These values are measured by the digital signal processor (DSP).
|
||||
* They should stay fairly constant even as the signal strength varies,
|
||||
* if the radio's automatic gain control (AGC) is working right.
|
||||
* AGC value (see below) will provide the "interesting" info.
|
||||
*/
|
||||
val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_AB_IDX]);
|
||||
rssi_a = (val & IWL50_OFDM_RSSI_A_MSK) >> IWL50_OFDM_RSSI_A_BIT_POS;
|
||||
rssi_b = (val & IWL50_OFDM_RSSI_B_MSK) >> IWL50_OFDM_RSSI_B_BIT_POS;
|
||||
val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_C_IDX]);
|
||||
rssi_c = (val & IWL50_OFDM_RSSI_C_MSK) >> IWL50_OFDM_RSSI_C_BIT_POS;
|
||||
|
||||
max_rssi = max_t(u32, rssi_a, rssi_b);
|
||||
max_rssi = max_t(u32, max_rssi, rssi_c);
|
||||
|
||||
IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
|
||||
rssi_a, rssi_b, rssi_c, max_rssi, agc);
|
||||
|
||||
/* dBm = max_rssi dB - agc dB - constant.
|
||||
* Higher AGC (higher radio gain) means lower signal. */
|
||||
return max_rssi - agc - IWL_RSSI_OFFSET;
|
||||
}
|
||||
|
||||
static struct iwl_hcmd_ops iwl5000_hcmd = {
|
||||
.rxon_assoc = iwl5000_send_rxon_assoc,
|
||||
};
|
||||
@ -1454,6 +1509,7 @@ static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
|
||||
.gain_computation = iwl5000_gain_computation,
|
||||
.chain_noise_reset = iwl5000_chain_noise_reset,
|
||||
.rts_tx_cmd_flag = iwl5000_rts_tx_cmd_flag,
|
||||
.calc_rssi = iwl5000_calc_rssi,
|
||||
};
|
||||
|
||||
static struct iwl_lib_ops iwl5000_lib = {
|
||||
@ -1474,6 +1530,7 @@ static struct iwl_lib_ops iwl5000_lib = {
|
||||
.alive_notify = iwl5000_alive_notify,
|
||||
.send_tx_power = iwl5000_send_tx_power,
|
||||
.temperature = iwl5000_temperature,
|
||||
.update_chain_flags = iwl4965_update_chain_flags,
|
||||
.apm_ops = {
|
||||
.init = iwl5000_apm_init,
|
||||
.reset = iwl5000_apm_reset,
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include "iwl-core.h"
|
||||
#include "iwl-helpers.h"
|
||||
|
||||
#define RS_NAME "iwl-4965-rs"
|
||||
#define RS_NAME "iwl-agn-rs"
|
||||
|
||||
#define NUM_TRY_BEFORE_ANT_TOGGLE 1
|
||||
#define IWL_NUMBER_TRY 1
|
||||
@ -77,9 +77,9 @@ static const u8 ant_toggle_lookup[] = {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl4965_rate_scale_data -- tx success history for one rate
|
||||
* struct iwl_rate_scale_data -- tx success history for one rate
|
||||
*/
|
||||
struct iwl4965_rate_scale_data {
|
||||
struct iwl_rate_scale_data {
|
||||
u64 data; /* bitmap of successful frames */
|
||||
s32 success_counter; /* number of frames successful */
|
||||
s32 success_ratio; /* per-cent * 128 */
|
||||
@ -89,12 +89,12 @@ struct iwl4965_rate_scale_data {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl4965_scale_tbl_info -- tx params and success history for all rates
|
||||
* struct iwl_scale_tbl_info -- tx params and success history for all rates
|
||||
*
|
||||
* There are two of these in struct iwl4965_lq_sta,
|
||||
* There are two of these in struct iwl_lq_sta,
|
||||
* one for "active", and one for "search".
|
||||
*/
|
||||
struct iwl4965_scale_tbl_info {
|
||||
struct iwl_scale_tbl_info {
|
||||
enum iwl_table_type lq_type;
|
||||
u8 ant_type;
|
||||
u8 is_SGI; /* 1 = short guard interval */
|
||||
@ -103,10 +103,10 @@ struct iwl4965_scale_tbl_info {
|
||||
u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
|
||||
s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
|
||||
u32 current_rate; /* rate_n_flags, uCode API format */
|
||||
struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
|
||||
struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
|
||||
};
|
||||
|
||||
struct iwl4965_traffic_load {
|
||||
struct iwl_traffic_load {
|
||||
unsigned long time_stamp; /* age of the oldest statistics */
|
||||
u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time
|
||||
* slice */
|
||||
@ -118,11 +118,11 @@ struct iwl4965_traffic_load {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl4965_lq_sta -- driver's rate scaling private structure
|
||||
* struct iwl_lq_sta -- driver's rate scaling private structure
|
||||
*
|
||||
* Pointer to this gets passed back and forth between driver and mac80211.
|
||||
*/
|
||||
struct iwl4965_lq_sta {
|
||||
struct iwl_lq_sta {
|
||||
u8 active_tbl; /* index of active table, range 0-1 */
|
||||
u8 enable_counter; /* indicates HT mode */
|
||||
u8 stay_in_tbl; /* 1: disallow, 0: allow search for new mode */
|
||||
@ -153,8 +153,8 @@ struct iwl4965_lq_sta {
|
||||
u16 active_rate_basic;
|
||||
|
||||
struct iwl_link_quality_cmd lq;
|
||||
struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
|
||||
struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT];
|
||||
struct iwl_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
|
||||
struct iwl_traffic_load load[TID_MAX_LOAD_COUNT];
|
||||
u8 tx_agg_tid_en;
|
||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
struct dentry *rs_sta_dbgfs_scale_table_file;
|
||||
@ -170,16 +170,15 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
|
||||
struct ieee80211_hdr *hdr,
|
||||
struct sta_info *sta);
|
||||
static void rs_fill_link_cmd(const struct iwl_priv *priv,
|
||||
struct iwl4965_lq_sta *lq_sta,
|
||||
u32 rate_n_flags);
|
||||
struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
|
||||
|
||||
|
||||
#ifdef CONFIG_MAC80211_DEBUGFS
|
||||
static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
|
||||
u32 *rate_n_flags, int index);
|
||||
static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
|
||||
u32 *rate_n_flags, int index);
|
||||
#else
|
||||
static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
|
||||
u32 *rate_n_flags, int index)
|
||||
static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
|
||||
u32 *rate_n_flags, int index)
|
||||
{}
|
||||
#endif
|
||||
|
||||
@ -234,7 +233,7 @@ static inline u8 rs_extract_rate(u32 rate_n_flags)
|
||||
return (u8)(rate_n_flags & 0xFF);
|
||||
}
|
||||
|
||||
static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window)
|
||||
static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
|
||||
{
|
||||
window->data = 0;
|
||||
window->success_counter = 0;
|
||||
@ -246,14 +245,14 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window)
|
||||
|
||||
static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type)
|
||||
{
|
||||
return ((ant_type & valid_antenna) == ant_type);
|
||||
return (ant_type & valid_antenna) == ant_type;
|
||||
}
|
||||
|
||||
/*
|
||||
* removes the old data from the statistics. All data that is older than
|
||||
* TID_MAX_TIME_DIFF, will be deleted.
|
||||
*/
|
||||
static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time)
|
||||
static void rs_tl_rm_old_stats(struct iwl_traffic_load *tl, u32 curr_time)
|
||||
{
|
||||
/* The oldest age we want to keep */
|
||||
u32 oldest_time = curr_time - TID_MAX_TIME_DIFF;
|
||||
@ -274,13 +273,13 @@ static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time)
|
||||
* increment traffic load value for tid and also remove
|
||||
* any old values if passed the certain time period
|
||||
*/
|
||||
static u8 rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,
|
||||
static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,
|
||||
struct ieee80211_hdr *hdr)
|
||||
{
|
||||
u32 curr_time = jiffies_to_msecs(jiffies);
|
||||
u32 time_diff;
|
||||
s32 index;
|
||||
struct iwl4965_traffic_load *tl = NULL;
|
||||
struct iwl_traffic_load *tl = NULL;
|
||||
__le16 fc = hdr->frame_control;
|
||||
u8 tid;
|
||||
|
||||
@ -325,12 +324,12 @@ static u8 rs_tl_add_packet(struct iwl4965_lq_sta *lq_data,
|
||||
/*
|
||||
get the traffic load value for tid
|
||||
*/
|
||||
static u32 rs_tl_get_load(struct iwl4965_lq_sta *lq_data, u8 tid)
|
||||
static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
|
||||
{
|
||||
u32 curr_time = jiffies_to_msecs(jiffies);
|
||||
u32 time_diff;
|
||||
s32 index;
|
||||
struct iwl4965_traffic_load *tl = NULL;
|
||||
struct iwl_traffic_load *tl = NULL;
|
||||
|
||||
if (tid >= TID_MAX_LOAD_COUNT)
|
||||
return 0;
|
||||
@ -354,8 +353,8 @@ static u32 rs_tl_get_load(struct iwl4965_lq_sta *lq_data, u8 tid)
|
||||
}
|
||||
|
||||
static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
|
||||
struct iwl4965_lq_sta *lq_data, u8 tid,
|
||||
struct sta_info *sta)
|
||||
struct iwl_lq_sta *lq_data, u8 tid,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
unsigned long state;
|
||||
DECLARE_MAC_BUF(mac);
|
||||
@ -373,8 +372,8 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
|
||||
}
|
||||
|
||||
static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
|
||||
struct iwl4965_lq_sta *lq_data,
|
||||
struct sta_info *sta)
|
||||
struct iwl_lq_sta *lq_data,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
if ((tid < TID_MAX_LOAD_COUNT))
|
||||
rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
|
||||
@ -385,9 +384,9 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
|
||||
|
||||
static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
|
||||
{
|
||||
return (!!(rate_n_flags & RATE_MCS_ANT_A_MSK) +
|
||||
!!(rate_n_flags & RATE_MCS_ANT_B_MSK) +
|
||||
!!(rate_n_flags & RATE_MCS_ANT_C_MSK));
|
||||
return !!(rate_n_flags & RATE_MCS_ANT_A_MSK) +
|
||||
!!(rate_n_flags & RATE_MCS_ANT_B_MSK) +
|
||||
!!(rate_n_flags & RATE_MCS_ANT_C_MSK);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -397,11 +396,11 @@ static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
|
||||
* at this rate. window->data contains the bitmask of successful
|
||||
* packets.
|
||||
*/
|
||||
static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
|
||||
static int rs_collect_tx_data(struct iwl_rate_scale_data *windows,
|
||||
int scale_index, s32 tpt, int retries,
|
||||
int successes)
|
||||
{
|
||||
struct iwl4965_rate_scale_data *window = NULL;
|
||||
struct iwl_rate_scale_data *window = NULL;
|
||||
static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
|
||||
s32 fail_count;
|
||||
|
||||
@ -473,7 +472,7 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
|
||||
* Fill uCode API rate_n_flags field, based on "search" or "active" table.
|
||||
*/
|
||||
/* FIXME:RS:remove this function and put the flags statically in the table */
|
||||
static u32 rate_n_flags_from_tbl(struct iwl4965_scale_tbl_info *tbl,
|
||||
static u32 rate_n_flags_from_tbl(struct iwl_scale_tbl_info *tbl,
|
||||
int index, u8 use_green)
|
||||
{
|
||||
u32 rate_n_flags = 0;
|
||||
@ -530,7 +529,7 @@ static u32 rate_n_flags_from_tbl(struct iwl4965_scale_tbl_info *tbl,
|
||||
*/
|
||||
static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
|
||||
enum ieee80211_band band,
|
||||
struct iwl4965_scale_tbl_info *tbl,
|
||||
struct iwl_scale_tbl_info *tbl,
|
||||
int *rate_idx)
|
||||
{
|
||||
u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK);
|
||||
@ -591,7 +590,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
|
||||
/* switch to another antenna/antennas and return 1 */
|
||||
/* if no other valid antenna found, return 0 */
|
||||
static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
|
||||
struct iwl4965_scale_tbl_info *tbl)
|
||||
struct iwl_scale_tbl_info *tbl)
|
||||
{
|
||||
u8 new_ant_type;
|
||||
|
||||
@ -621,9 +620,9 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
|
||||
#if 0
|
||||
static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)
|
||||
{
|
||||
return ((conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) &&
|
||||
return (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) &&
|
||||
priv->current_ht_config.is_green_field &&
|
||||
!priv->current_ht_config.non_GF_STA_present);
|
||||
!priv->current_ht_config.non_GF_STA_present;
|
||||
}
|
||||
#endif
|
||||
static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)
|
||||
@ -638,9 +637,9 @@ static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf
|
||||
* basic available rates.
|
||||
*
|
||||
*/
|
||||
static u16 rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta,
|
||||
struct ieee80211_hdr *hdr,
|
||||
enum iwl_table_type rate_type)
|
||||
static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta,
|
||||
struct ieee80211_hdr *hdr,
|
||||
enum iwl_table_type rate_type)
|
||||
{
|
||||
if (hdr && is_multicast_ether_addr(hdr->addr1) &&
|
||||
lq_sta->active_rate_basic)
|
||||
@ -714,9 +713,9 @@ static u16 rs_get_adjacent_rate(struct iwl_priv *priv, u8 index, u16 rate_mask,
|
||||
return (high << 8) | low;
|
||||
}
|
||||
|
||||
static u32 rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta,
|
||||
struct iwl4965_scale_tbl_info *tbl, u8 scale_index,
|
||||
u8 ht_possible)
|
||||
static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
|
||||
struct iwl_scale_tbl_info *tbl,
|
||||
u8 scale_index, u8 ht_possible)
|
||||
{
|
||||
s32 low;
|
||||
u16 rate_mask;
|
||||
@ -780,7 +779,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
|
||||
int status;
|
||||
u8 retries;
|
||||
int rs_index, index = 0;
|
||||
struct iwl4965_lq_sta *lq_sta;
|
||||
struct iwl_lq_sta *lq_sta;
|
||||
struct iwl_link_quality_cmd *table;
|
||||
struct sta_info *sta;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
@ -788,11 +787,11 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
|
||||
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
|
||||
struct ieee80211_hw *hw = local_to_hw(local);
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct iwl4965_rate_scale_data *window = NULL;
|
||||
struct iwl4965_rate_scale_data *search_win = NULL;
|
||||
struct iwl_rate_scale_data *window = NULL;
|
||||
struct iwl_rate_scale_data *search_win = NULL;
|
||||
u32 tx_rate;
|
||||
struct iwl4965_scale_tbl_info tbl_type;
|
||||
struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl;
|
||||
struct iwl_scale_tbl_info tbl_type;
|
||||
struct iwl_scale_tbl_info *curr_tbl, *search_tbl;
|
||||
u8 active_index = 0;
|
||||
__le16 fc = hdr->frame_control;
|
||||
s32 tpt = 0;
|
||||
@ -820,7 +819,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
|
||||
goto out;
|
||||
|
||||
|
||||
lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
|
||||
lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
|
||||
|
||||
if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
|
||||
!lq_sta->ibss_sta_added)
|
||||
@ -831,10 +830,8 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
|
||||
|
||||
curr_tbl = &(lq_sta->lq_info[active_index]);
|
||||
search_tbl = &(lq_sta->lq_info[(1 - active_index)]);
|
||||
window = (struct iwl4965_rate_scale_data *)
|
||||
&(curr_tbl->win[0]);
|
||||
search_win = (struct iwl4965_rate_scale_data *)
|
||||
&(search_tbl->win[0]);
|
||||
window = (struct iwl_rate_scale_data *)&(curr_tbl->win[0]);
|
||||
search_win = (struct iwl_rate_scale_data *)&(search_tbl->win[0]);
|
||||
|
||||
/*
|
||||
* Ignore this Tx frame response if its initial rate doesn't match
|
||||
@ -983,7 +980,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
|
||||
* searching for a new mode.
|
||||
*/
|
||||
static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
|
||||
struct iwl4965_lq_sta *lq_sta)
|
||||
struct iwl_lq_sta *lq_sta)
|
||||
{
|
||||
IWL_DEBUG_RATE("we are staying in the same table\n");
|
||||
lq_sta->stay_in_tbl = 1; /* only place this gets set */
|
||||
@ -1004,8 +1001,8 @@ static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
|
||||
/*
|
||||
* Find correct throughput table for given mode of modulation
|
||||
*/
|
||||
static void rs_set_expected_tpt_table(struct iwl4965_lq_sta *lq_sta,
|
||||
struct iwl4965_scale_tbl_info *tbl)
|
||||
static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
|
||||
struct iwl_scale_tbl_info *tbl)
|
||||
{
|
||||
if (is_legacy(tbl->lq_type)) {
|
||||
if (!is_a_band(tbl->lq_type))
|
||||
@ -1050,12 +1047,12 @@ static void rs_set_expected_tpt_table(struct iwl4965_lq_sta *lq_sta,
|
||||
* bit rate will typically need to increase, but not if performance was bad.
|
||||
*/
|
||||
static s32 rs_get_best_rate(struct iwl_priv *priv,
|
||||
struct iwl4965_lq_sta *lq_sta,
|
||||
struct iwl4965_scale_tbl_info *tbl, /* "search" */
|
||||
struct iwl_lq_sta *lq_sta,
|
||||
struct iwl_scale_tbl_info *tbl, /* "search" */
|
||||
u16 rate_mask, s8 index)
|
||||
{
|
||||
/* "active" values */
|
||||
struct iwl4965_scale_tbl_info *active_tbl =
|
||||
struct iwl_scale_tbl_info *active_tbl =
|
||||
&(lq_sta->lq_info[lq_sta->active_tbl]);
|
||||
s32 active_sr = active_tbl->win[index].success_ratio;
|
||||
s32 active_tpt = active_tbl->expected_tpt[index];
|
||||
@ -1143,10 +1140,10 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
|
||||
* Set up search table for MIMO
|
||||
*/
|
||||
static int rs_switch_to_mimo2(struct iwl_priv *priv,
|
||||
struct iwl4965_lq_sta *lq_sta,
|
||||
struct iwl_lq_sta *lq_sta,
|
||||
struct ieee80211_conf *conf,
|
||||
struct sta_info *sta,
|
||||
struct iwl4965_scale_tbl_info *tbl, int index)
|
||||
struct iwl_scale_tbl_info *tbl, int index)
|
||||
{
|
||||
u16 rate_mask;
|
||||
s32 rate;
|
||||
@ -1210,10 +1207,10 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
|
||||
* Set up search table for SISO
|
||||
*/
|
||||
static int rs_switch_to_siso(struct iwl_priv *priv,
|
||||
struct iwl4965_lq_sta *lq_sta,
|
||||
struct iwl_lq_sta *lq_sta,
|
||||
struct ieee80211_conf *conf,
|
||||
struct sta_info *sta,
|
||||
struct iwl4965_scale_tbl_info *tbl, int index)
|
||||
struct iwl_scale_tbl_info *tbl, int index)
|
||||
{
|
||||
u16 rate_mask;
|
||||
u8 is_green = lq_sta->is_green;
|
||||
@ -1270,18 +1267,17 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
|
||||
* Try to switch to new modulation mode from legacy
|
||||
*/
|
||||
static int rs_move_legacy_other(struct iwl_priv *priv,
|
||||
struct iwl4965_lq_sta *lq_sta,
|
||||
struct iwl_lq_sta *lq_sta,
|
||||
struct ieee80211_conf *conf,
|
||||
struct sta_info *sta,
|
||||
int index)
|
||||
{
|
||||
struct iwl4965_scale_tbl_info *tbl =
|
||||
&(lq_sta->lq_info[lq_sta->active_tbl]);
|
||||
struct iwl4965_scale_tbl_info *search_tbl =
|
||||
&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
|
||||
struct iwl4965_rate_scale_data *window = &(tbl->win[index]);
|
||||
u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
|
||||
(sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
|
||||
struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
|
||||
struct iwl_scale_tbl_info *search_tbl =
|
||||
&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
|
||||
struct iwl_rate_scale_data *window = &(tbl->win[index]);
|
||||
u32 sz = (sizeof(struct iwl_scale_tbl_info) -
|
||||
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
|
||||
u8 start_action = tbl->action;
|
||||
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
|
||||
int ret = 0;
|
||||
@ -1360,19 +1356,17 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
|
||||
* Try to switch to new modulation mode from SISO
|
||||
*/
|
||||
static int rs_move_siso_to_other(struct iwl_priv *priv,
|
||||
struct iwl4965_lq_sta *lq_sta,
|
||||
struct iwl_lq_sta *lq_sta,
|
||||
struct ieee80211_conf *conf,
|
||||
struct sta_info *sta,
|
||||
int index)
|
||||
struct sta_info *sta, int index)
|
||||
{
|
||||
u8 is_green = lq_sta->is_green;
|
||||
struct iwl4965_scale_tbl_info *tbl =
|
||||
&(lq_sta->lq_info[lq_sta->active_tbl]);
|
||||
struct iwl4965_scale_tbl_info *search_tbl =
|
||||
&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
|
||||
struct iwl4965_rate_scale_data *window = &(tbl->win[index]);
|
||||
u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
|
||||
(sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
|
||||
struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
|
||||
struct iwl_scale_tbl_info *search_tbl =
|
||||
&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
|
||||
struct iwl_rate_scale_data *window = &(tbl->win[index]);
|
||||
u32 sz = (sizeof(struct iwl_scale_tbl_info) -
|
||||
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
|
||||
u8 start_action = tbl->action;
|
||||
u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
|
||||
int ret;
|
||||
@ -1455,18 +1449,16 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
|
||||
* Try to switch to new modulation mode from MIMO
|
||||
*/
|
||||
static int rs_move_mimo_to_other(struct iwl_priv *priv,
|
||||
struct iwl4965_lq_sta *lq_sta,
|
||||
struct iwl_lq_sta *lq_sta,
|
||||
struct ieee80211_conf *conf,
|
||||
struct sta_info *sta,
|
||||
int index)
|
||||
struct sta_info *sta, int index)
|
||||
{
|
||||
s8 is_green = lq_sta->is_green;
|
||||
struct iwl4965_scale_tbl_info *tbl =
|
||||
&(lq_sta->lq_info[lq_sta->active_tbl]);
|
||||
struct iwl4965_scale_tbl_info *search_tbl =
|
||||
&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
|
||||
u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
|
||||
(sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
|
||||
struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
|
||||
struct iwl_scale_tbl_info *search_tbl =
|
||||
&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
|
||||
u32 sz = (sizeof(struct iwl_scale_tbl_info) -
|
||||
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
|
||||
u8 start_action = tbl->action;
|
||||
/*u8 valid_tx_ant = priv->hw_params.valid_tx_ant;*/
|
||||
int ret;
|
||||
@ -1552,9 +1544,9 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
|
||||
* 2) # times calling this function
|
||||
* 3) elapsed time in this mode (not used, for now)
|
||||
*/
|
||||
static void rs_stay_in_table(struct iwl4965_lq_sta *lq_sta)
|
||||
static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
|
||||
{
|
||||
struct iwl4965_scale_tbl_info *tbl;
|
||||
struct iwl_scale_tbl_info *tbl;
|
||||
int i;
|
||||
int active_tbl;
|
||||
int flush_interval_passed = 0;
|
||||
@ -1642,7 +1634,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
|
||||
int high = IWL_RATE_INVALID;
|
||||
int index;
|
||||
int i;
|
||||
struct iwl4965_rate_scale_data *window = NULL;
|
||||
struct iwl_rate_scale_data *window = NULL;
|
||||
int current_tpt = IWL_INVALID_VALUE;
|
||||
int low_tpt = IWL_INVALID_VALUE;
|
||||
int high_tpt = IWL_INVALID_VALUE;
|
||||
@ -1651,8 +1643,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
|
||||
__le16 fc;
|
||||
u16 rate_mask;
|
||||
u8 update_lq = 0;
|
||||
struct iwl4965_lq_sta *lq_sta;
|
||||
struct iwl4965_scale_tbl_info *tbl, *tbl1;
|
||||
struct iwl_lq_sta *lq_sta;
|
||||
struct iwl_scale_tbl_info *tbl, *tbl1;
|
||||
u16 rate_scale_index_msk = 0;
|
||||
u32 rate;
|
||||
u8 is_green = 0;
|
||||
@ -1675,7 +1667,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
|
||||
if (!sta || !sta->rate_ctrl_priv)
|
||||
return;
|
||||
|
||||
lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
|
||||
lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
|
||||
|
||||
tid = rs_tl_add_packet(lq_sta, hdr);
|
||||
|
||||
@ -2030,8 +2022,8 @@ static void rs_initialize_lq(struct iwl_priv *priv,
|
||||
struct ieee80211_conf *conf,
|
||||
struct sta_info *sta)
|
||||
{
|
||||
struct iwl4965_lq_sta *lq_sta;
|
||||
struct iwl4965_scale_tbl_info *tbl;
|
||||
struct iwl_lq_sta *lq_sta;
|
||||
struct iwl_scale_tbl_info *tbl;
|
||||
int rate_idx;
|
||||
int i;
|
||||
u32 rate;
|
||||
@ -2042,7 +2034,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
|
||||
if (!sta || !sta->rate_ctrl_priv)
|
||||
goto out;
|
||||
|
||||
lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
|
||||
lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
|
||||
i = sta->last_txrate_idx;
|
||||
|
||||
if ((lq_sta->lq.sta_id == 0xff) &&
|
||||
@ -2096,7 +2088,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
|
||||
struct sta_info *sta;
|
||||
__le16 fc;
|
||||
struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
|
||||
struct iwl4965_lq_sta *lq_sta;
|
||||
struct iwl_lq_sta *lq_sta;
|
||||
|
||||
IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
|
||||
|
||||
@ -2113,7 +2105,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
|
||||
goto out;
|
||||
}
|
||||
|
||||
lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv;
|
||||
lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
|
||||
i = sta->last_txrate_idx;
|
||||
|
||||
if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
|
||||
@ -2149,14 +2141,14 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
|
||||
|
||||
static void *rs_alloc_sta(void *priv_rate, gfp_t gfp)
|
||||
{
|
||||
struct iwl4965_lq_sta *lq_sta;
|
||||
struct iwl_lq_sta *lq_sta;
|
||||
struct iwl_priv *priv;
|
||||
int i, j;
|
||||
|
||||
priv = (struct iwl_priv *)priv_rate;
|
||||
IWL_DEBUG_RATE("create station rate scale window\n");
|
||||
|
||||
lq_sta = kzalloc(sizeof(struct iwl4965_lq_sta), gfp);
|
||||
lq_sta = kzalloc(sizeof(struct iwl_lq_sta), gfp);
|
||||
|
||||
if (lq_sta == NULL)
|
||||
return NULL;
|
||||
@ -2165,7 +2157,7 @@ static void *rs_alloc_sta(void *priv_rate, gfp_t gfp)
|
||||
|
||||
for (j = 0; j < LQ_SIZE; j++)
|
||||
for (i = 0; i < IWL_RATE_COUNT; i++)
|
||||
rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i]));
|
||||
rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
|
||||
|
||||
return lq_sta;
|
||||
}
|
||||
@ -2178,7 +2170,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
|
||||
struct ieee80211_conf *conf = &local->hw.conf;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
|
||||
struct iwl4965_lq_sta *lq_sta = priv_sta;
|
||||
struct iwl_lq_sta *lq_sta = priv_sta;
|
||||
|
||||
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
|
||||
|
||||
@ -2187,7 +2179,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
|
||||
sta->txrate_idx = 3;
|
||||
for (j = 0; j < LQ_SIZE; j++)
|
||||
for (i = 0; i < IWL_RATE_COUNT; i++)
|
||||
rs_rate_scale_clear_window(&(lq_sta->lq_info[j].win[i]));
|
||||
rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
|
||||
|
||||
IWL_DEBUG_RATE("LQ: *** rate scale global init ***\n");
|
||||
/* TODO: what is a good starting rate for STA? About middle? Maybe not
|
||||
@ -2271,10 +2263,9 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
|
||||
}
|
||||
|
||||
static void rs_fill_link_cmd(const struct iwl_priv *priv,
|
||||
struct iwl4965_lq_sta *lq_sta,
|
||||
u32 new_rate)
|
||||
struct iwl_lq_sta *lq_sta, u32 new_rate)
|
||||
{
|
||||
struct iwl4965_scale_tbl_info tbl_type;
|
||||
struct iwl_scale_tbl_info tbl_type;
|
||||
int index = 0;
|
||||
int rate_idx;
|
||||
int repeat_rate = 0;
|
||||
@ -2402,6 +2393,7 @@ static void rs_free(void *priv_rate)
|
||||
|
||||
static void rs_clear(void *priv_rate)
|
||||
{
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
struct iwl_priv *priv = (struct iwl_priv *) priv_rate;
|
||||
|
||||
IWL_DEBUG_RATE("enter\n");
|
||||
@ -2409,11 +2401,12 @@ static void rs_clear(void *priv_rate)
|
||||
/* TODO - add rate scale state reset */
|
||||
|
||||
IWL_DEBUG_RATE("leave\n");
|
||||
#endif /* CONFIG_IWLWIFI_DEBUG */
|
||||
}
|
||||
|
||||
static void rs_free_sta(void *priv_rate, void *priv_sta)
|
||||
{
|
||||
struct iwl4965_lq_sta *lq_sta = priv_sta;
|
||||
struct iwl_lq_sta *lq_sta = priv_sta;
|
||||
struct iwl_priv *priv;
|
||||
|
||||
priv = (struct iwl_priv *)priv_rate;
|
||||
@ -2429,8 +2422,8 @@ static int open_file_generic(struct inode *inode, struct file *file)
|
||||
file->private_data = inode->i_private;
|
||||
return 0;
|
||||
}
|
||||
static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
|
||||
u32 *rate_n_flags, int index)
|
||||
static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
|
||||
u32 *rate_n_flags, int index)
|
||||
{
|
||||
struct iwl_priv *priv;
|
||||
|
||||
@ -2453,7 +2446,7 @@ static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
|
||||
static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
|
||||
const char __user *user_buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl4965_lq_sta *lq_sta = file->private_data;
|
||||
struct iwl_lq_sta *lq_sta = file->private_data;
|
||||
struct iwl_priv *priv;
|
||||
char buf[64];
|
||||
int buf_size;
|
||||
@ -2493,7 +2486,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
|
||||
int desc = 0;
|
||||
int i = 0;
|
||||
|
||||
struct iwl4965_lq_sta *lq_sta = file->private_data;
|
||||
struct iwl_lq_sta *lq_sta = file->private_data;
|
||||
|
||||
desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);
|
||||
desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
|
||||
@ -2541,7 +2534,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
|
||||
int desc = 0;
|
||||
int i, j;
|
||||
|
||||
struct iwl4965_lq_sta *lq_sta = file->private_data;
|
||||
struct iwl_lq_sta *lq_sta = file->private_data;
|
||||
for (i = 0; i < LQ_SIZE; i++) {
|
||||
desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d\n"
|
||||
"rate=0x%X\n",
|
||||
@ -2570,7 +2563,7 @@ static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
|
||||
static void rs_add_debugfs(void *priv, void *priv_sta,
|
||||
struct dentry *dir)
|
||||
{
|
||||
struct iwl4965_lq_sta *lq_sta = priv_sta;
|
||||
struct iwl_lq_sta *lq_sta = priv_sta;
|
||||
lq_sta->rs_sta_dbgfs_scale_table_file =
|
||||
debugfs_create_file("rate_scale_table", 0600, dir,
|
||||
lq_sta, &rs_sta_dbgfs_scale_table_ops);
|
||||
@ -2585,7 +2578,7 @@ static void rs_add_debugfs(void *priv, void *priv_sta,
|
||||
|
||||
static void rs_remove_debugfs(void *priv, void *priv_sta)
|
||||
{
|
||||
struct iwl4965_lq_sta *lq_sta = priv_sta;
|
||||
struct iwl_lq_sta *lq_sta = priv_sta;
|
||||
debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
|
||||
debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
|
||||
debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
|
||||
@ -2609,104 +2602,12 @@ static struct rate_control_ops rs_ops = {
|
||||
#endif
|
||||
};
|
||||
|
||||
int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
struct iwl_priv *priv = hw->priv;
|
||||
struct iwl4965_lq_sta *lq_sta;
|
||||
struct sta_info *sta;
|
||||
int cnt = 0, i;
|
||||
u32 samples = 0, success = 0, good = 0;
|
||||
unsigned long now = jiffies;
|
||||
u32 max_time = 0;
|
||||
u8 lq_type, antenna;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr);
|
||||
if (!sta || !sta->rate_ctrl_priv) {
|
||||
if (sta)
|
||||
IWL_DEBUG_RATE("leave - no private rate data!\n");
|
||||
else
|
||||
IWL_DEBUG_RATE("leave - no station!\n");
|
||||
rcu_read_unlock();
|
||||
return sprintf(buf, "station %d not found\n", sta_id);
|
||||
}
|
||||
|
||||
lq_sta = (void *)sta->rate_ctrl_priv;
|
||||
|
||||
lq_type = lq_sta->lq_info[lq_sta->active_tbl].lq_type;
|
||||
antenna = lq_sta->lq_info[lq_sta->active_tbl].ant_type;
|
||||
|
||||
if (is_legacy(lq_type))
|
||||
i = IWL_RATE_54M_INDEX;
|
||||
else
|
||||
i = IWL_RATE_60M_INDEX;
|
||||
while (1) {
|
||||
u64 mask;
|
||||
int j;
|
||||
int active = lq_sta->active_tbl;
|
||||
|
||||
cnt +=
|
||||
sprintf(&buf[cnt], " %2dMbs: ", iwl_rates[i].ieee / 2);
|
||||
|
||||
mask = (1ULL << (IWL_RATE_MAX_WINDOW - 1));
|
||||
for (j = 0; j < IWL_RATE_MAX_WINDOW; j++, mask >>= 1)
|
||||
buf[cnt++] =
|
||||
(lq_sta->lq_info[active].win[i].data & mask)
|
||||
? '1' : '0';
|
||||
|
||||
samples += lq_sta->lq_info[active].win[i].counter;
|
||||
good += lq_sta->lq_info[active].win[i].success_counter;
|
||||
success += lq_sta->lq_info[active].win[i].success_counter *
|
||||
iwl_rates[i].ieee;
|
||||
|
||||
if (lq_sta->lq_info[active].win[i].stamp) {
|
||||
int delta =
|
||||
jiffies_to_msecs(now -
|
||||
lq_sta->lq_info[active].win[i].stamp);
|
||||
|
||||
if (delta > max_time)
|
||||
max_time = delta;
|
||||
|
||||
cnt += sprintf(&buf[cnt], "%5dms\n", delta);
|
||||
} else
|
||||
buf[cnt++] = '\n';
|
||||
|
||||
j = iwl4965_get_prev_ieee_rate(i);
|
||||
if (j == i)
|
||||
break;
|
||||
i = j;
|
||||
}
|
||||
|
||||
/*
|
||||
* Display the average rate of all samples taken.
|
||||
* NOTE: We multiply # of samples by 2 since the IEEE measurement
|
||||
* added from iwl_rates is actually 2X the rate.
|
||||
*/
|
||||
if (samples)
|
||||
cnt += sprintf(&buf[cnt],
|
||||
"\nAverage rate is %3d.%02dMbs over last %4dms\n"
|
||||
"%3d%% success (%d good packets over %d tries)\n",
|
||||
success / (2 * samples), (success * 5 / samples) % 10,
|
||||
max_time, good * 100 / samples, good, samples);
|
||||
else
|
||||
cnt += sprintf(&buf[cnt], "\nAverage rate: 0Mbs\n");
|
||||
|
||||
cnt += sprintf(&buf[cnt], "\nrate scale type %d antenna %d "
|
||||
"active_search %d rate index %d\n", lq_type, antenna,
|
||||
lq_sta->search_better_tbl, sta->last_txrate_idx);
|
||||
|
||||
rcu_read_unlock();
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int iwl4965_rate_control_register(void)
|
||||
int iwlagn_rate_control_register(void)
|
||||
{
|
||||
return ieee80211_rate_control_register(&rs_ops);
|
||||
}
|
||||
|
||||
void iwl4965_rate_control_unregister(void)
|
||||
void iwlagn_rate_control_unregister(void)
|
||||
{
|
||||
ieee80211_rate_control_unregister(&rs_ops);
|
||||
}
|
@ -24,8 +24,8 @@
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __iwl_4965_rs_h__
|
||||
#define __iwl_4965_rs_h__
|
||||
#ifndef __iwl_agn_rs_h__
|
||||
#define __iwl_agn_rs_h__
|
||||
|
||||
#include "iwl-dev.h"
|
||||
|
||||
@ -88,7 +88,7 @@ enum {
|
||||
#define IWL_RATE_5M_MASK (1 << IWL_RATE_5M_INDEX)
|
||||
#define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX)
|
||||
|
||||
/* 4965 uCode API values for legacy bit rates, both OFDM and CCK */
|
||||
/* uCode API values for legacy bit rates, both OFDM and CCK */
|
||||
enum {
|
||||
IWL_RATE_6M_PLCP = 13,
|
||||
IWL_RATE_9M_PLCP = 15,
|
||||
@ -107,7 +107,7 @@ enum {
|
||||
/*FIXME:RS:add IWL_RATE_LEGACY_INVM_PLCP = 0,*/
|
||||
};
|
||||
|
||||
/* 4965 uCode API values for OFDM high-throughput (HT) bit rates */
|
||||
/* uCode API values for OFDM high-throughput (HT) bit rates */
|
||||
enum {
|
||||
IWL_RATE_SISO_6M_PLCP = 0,
|
||||
IWL_RATE_SISO_12M_PLCP = 1,
|
||||
@ -286,15 +286,6 @@ static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
|
||||
return rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* iwl4965_fill_rs_info - Fill an output text buffer with the rate representation
|
||||
*
|
||||
* NOTE: This is provided as a quick mechanism for a user to visualize
|
||||
* the performance of the rate control algorithm and is not meant to be
|
||||
* parsed software.
|
||||
*/
|
||||
extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
|
||||
|
||||
/**
|
||||
* iwl4965_rate_control_register - Register the rate control algorithm callbacks
|
||||
*
|
||||
@ -305,7 +296,7 @@ extern int iwl4965_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
|
||||
* ieee80211_register_hw
|
||||
*
|
||||
*/
|
||||
extern int iwl4965_rate_control_register(void);
|
||||
extern int iwlagn_rate_control_register(void);
|
||||
|
||||
/**
|
||||
* iwl4965_rate_control_unregister - Unregister the rate control callbacks
|
||||
@ -313,6 +304,6 @@ extern int iwl4965_rate_control_register(void);
|
||||
* This should be called after calling ieee80211_unregister_hw, but before
|
||||
* the driver is unloaded.
|
||||
*/
|
||||
extern void iwl4965_rate_control_unregister(void);
|
||||
extern void iwlagn_rate_control_unregister(void);
|
||||
|
||||
#endif
|
||||
#endif /* __iwl_agn__rs__ */
|
@ -65,7 +65,7 @@
|
||||
* NOTE: DRV_NAME is defined in iwlwifi.h for use by iwl-debug.h and printk
|
||||
*/
|
||||
|
||||
#define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link 4965AGN driver for Linux"
|
||||
#define DRV_DESCRIPTION "Intel(R) Wireless WiFi Link AGN driver for Linux"
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
#define VD "d"
|
||||
@ -73,7 +73,7 @@
|
||||
#define VD
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
|
||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
||||
#define VS "s"
|
||||
#else
|
||||
#define VS
|
||||
@ -86,6 +86,7 @@ MODULE_DESCRIPTION(DRV_DESCRIPTION);
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
MODULE_AUTHOR(DRV_COPYRIGHT);
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("iwl4965");
|
||||
|
||||
/*************** STATION TABLE MANAGEMENT ****
|
||||
* mac80211 should be examined to determine if sta_info is duplicating
|
||||
@ -444,11 +445,10 @@ static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
|
||||
list_add(&frame->list, &priv->free_frames);
|
||||
}
|
||||
|
||||
unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
|
||||
struct ieee80211_hdr *hdr,
|
||||
const u8 *dest, int left)
|
||||
static unsigned int iwl_fill_beacon_frame(struct iwl_priv *priv,
|
||||
struct ieee80211_hdr *hdr,
|
||||
const u8 *dest, int left)
|
||||
{
|
||||
|
||||
if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
|
||||
((priv->iw_mode != IEEE80211_IF_TYPE_IBSS) &&
|
||||
(priv->iw_mode != IEEE80211_IF_TYPE_AP)))
|
||||
@ -487,6 +487,38 @@ static u8 iwl4965_rate_get_lowest_plcp(struct iwl_priv *priv)
|
||||
return IWL_RATE_6M_PLCP;
|
||||
}
|
||||
|
||||
unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
|
||||
struct iwl_frame *frame, u8 rate)
|
||||
{
|
||||
struct iwl_tx_beacon_cmd *tx_beacon_cmd;
|
||||
unsigned int frame_size;
|
||||
|
||||
tx_beacon_cmd = &frame->u.beacon;
|
||||
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
|
||||
|
||||
tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id;
|
||||
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
|
||||
|
||||
frame_size = iwl_fill_beacon_frame(priv, tx_beacon_cmd->frame,
|
||||
iwl_bcast_addr,
|
||||
sizeof(frame->u) - sizeof(*tx_beacon_cmd));
|
||||
|
||||
BUG_ON(frame_size > MAX_MPDU_SIZE);
|
||||
tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
|
||||
|
||||
if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP))
|
||||
tx_beacon_cmd->tx.rate_n_flags =
|
||||
iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK);
|
||||
else
|
||||
tx_beacon_cmd->tx.rate_n_flags =
|
||||
iwl_hw_set_rate_n_flags(rate, 0);
|
||||
|
||||
tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK |
|
||||
TX_CMD_FLG_TSF_MSK |
|
||||
TX_CMD_FLG_STA_RATE_MSK;
|
||||
|
||||
return sizeof(*tx_beacon_cmd) + frame_size;
|
||||
}
|
||||
static int iwl4965_send_beacon_cmd(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_frame *frame;
|
||||
@ -608,7 +640,6 @@ static void iwl_activate_qos(struct iwl_priv *priv, u8 force)
|
||||
}
|
||||
|
||||
#define MAX_UCODE_BEACON_INTERVAL 4096
|
||||
#define INTEL_CONN_LISTEN_INTERVAL __constant_cpu_to_le16(0xA)
|
||||
|
||||
static __le16 iwl4965_adjust_beacon_interval(u16 beacon_val)
|
||||
{
|
||||
@ -638,7 +669,7 @@ static void iwl4965_setup_rxon_timing(struct iwl_priv *priv)
|
||||
priv->rxon_timing.timestamp.dw[0] =
|
||||
cpu_to_le32(priv->timestamp & 0xFFFFFFFF);
|
||||
|
||||
priv->rxon_timing.listen_interval = INTEL_CONN_LISTEN_INTERVAL;
|
||||
priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);
|
||||
|
||||
tsf = priv->timestamp;
|
||||
|
||||
@ -853,7 +884,7 @@ static void iwl4965_set_rate(struct iwl_priv *priv)
|
||||
(IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
|
||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
||||
|
||||
#include "iwl-spectrum.h"
|
||||
|
||||
@ -1057,7 +1088,7 @@ static void iwl4965_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
static void iwl4965_rx_spectrum_measure_notif(struct iwl_priv *priv,
|
||||
struct iwl_rx_mem_buffer *rxb)
|
||||
{
|
||||
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
|
||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
||||
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
|
||||
struct iwl4965_spectrum_notification *report = &(pkt->u.spectrum_notif);
|
||||
|
||||
@ -1231,6 +1262,37 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv,
|
||||
wake_up_interruptible(&priv->wait_command_queue);
|
||||
}
|
||||
|
||||
int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
|
||||
{
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
ret = iwl_grab_nic_access(priv);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (src == IWL_PWR_SRC_VAUX) {
|
||||
u32 val;
|
||||
ret = pci_read_config_dword(priv->pci_dev, PCI_POWER_SOURCE,
|
||||
&val);
|
||||
|
||||
if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT)
|
||||
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
|
||||
APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
|
||||
~APMG_PS_CTRL_MSK_PWR_SRC);
|
||||
} else {
|
||||
iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
|
||||
APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
|
||||
~APMG_PS_CTRL_MSK_PWR_SRC);
|
||||
}
|
||||
|
||||
iwl_release_nic_access(priv);
|
||||
err:
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* iwl4965_setup_rx_handlers - Initialize Rx handler callbacks
|
||||
*
|
||||
@ -2170,17 +2232,16 @@ static int __iwl4965_up(struct iwl_priv *priv)
|
||||
}
|
||||
|
||||
/* If platform's RF_KILL switch is NOT set to KILL */
|
||||
if (iwl_read32(priv, CSR_GP_CNTRL) &
|
||||
CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
|
||||
if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
|
||||
clear_bit(STATUS_RF_KILL_HW, &priv->status);
|
||||
else
|
||||
set_bit(STATUS_RF_KILL_HW, &priv->status);
|
||||
|
||||
if (!test_bit(STATUS_IN_SUSPEND, &priv->status) &&
|
||||
iwl_is_rfkill(priv)) {
|
||||
if (iwl_is_rfkill(priv)) {
|
||||
iwl4965_enable_interrupts(priv);
|
||||
IWL_WARNING("Radio disabled by %s RF Kill switch\n",
|
||||
test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
|
||||
@ -2216,11 +2277,6 @@ static int __iwl4965_up(struct iwl_priv *priv)
|
||||
memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr,
|
||||
priv->ucode_data.len);
|
||||
|
||||
/* We return success when we resume from suspend and rf_kill is on. */
|
||||
if (test_bit(STATUS_RF_KILL_HW, &priv->status) ||
|
||||
test_bit(STATUS_RF_KILL_SW, &priv->status))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < MAX_HW_RESTARTS; i++) {
|
||||
|
||||
iwl_clear_stations_table(priv);
|
||||
@ -2415,7 +2471,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
|
||||
unsigned long flags;
|
||||
|
||||
if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
|
||||
IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__);
|
||||
IWL_ERROR("%s Should not be called in AP mode\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2491,7 +2547,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
|
||||
|
||||
default:
|
||||
IWL_ERROR("%s Should not be called in %d mode\n",
|
||||
__FUNCTION__, priv->iw_mode);
|
||||
__func__, priv->iw_mode);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2589,6 +2645,9 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
|
||||
if (ret)
|
||||
goto out_release_irq;
|
||||
|
||||
if (iwl_is_rfkill(priv))
|
||||
goto out;
|
||||
|
||||
IWL_DEBUG_INFO("Start UP work done.\n");
|
||||
|
||||
if (test_bit(STATUS_IN_SUSPEND, &priv->status))
|
||||
@ -2608,6 +2667,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
priv->is_open = 1;
|
||||
IWL_DEBUG_MAC80211("leave\n");
|
||||
return 0;
|
||||
@ -2773,6 +2833,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
|
||||
/* if we are switching from ht to 2.4 clear flags
|
||||
* from any ht related info since 2.4 does not
|
||||
* support ht */
|
||||
@ -3102,6 +3163,7 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
|
||||
if (bss_conf->assoc) {
|
||||
priv->assoc_id = bss_conf->aid;
|
||||
priv->beacon_int = bss_conf->beacon_int;
|
||||
priv->power_data.dtim_period = bss_conf->dtim_period;
|
||||
priv->timestamp = bss_conf->timestamp;
|
||||
priv->assoc_capability = bss_conf->assoc_capability;
|
||||
priv->next_scan_jiffies = jiffies +
|
||||
@ -3345,6 +3407,39 @@ static int iwl4965_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
const u8 *addr, u16 tid, u16 *ssn)
|
||||
{
|
||||
struct iwl_priv *priv = hw->priv;
|
||||
DECLARE_MAC_BUF(mac);
|
||||
|
||||
IWL_DEBUG_HT("A-MPDU action on addr %s tid %d\n",
|
||||
print_mac(mac, addr), tid);
|
||||
|
||||
if (!(priv->cfg->sku & IWL_SKU_N))
|
||||
return -EACCES;
|
||||
|
||||
switch (action) {
|
||||
case IEEE80211_AMPDU_RX_START:
|
||||
IWL_DEBUG_HT("start Rx\n");
|
||||
return iwl_rx_agg_start(priv, addr, tid, *ssn);
|
||||
case IEEE80211_AMPDU_RX_STOP:
|
||||
IWL_DEBUG_HT("stop Rx\n");
|
||||
return iwl_rx_agg_stop(priv, addr, tid);
|
||||
case IEEE80211_AMPDU_TX_START:
|
||||
IWL_DEBUG_HT("start Tx\n");
|
||||
return iwl_tx_agg_start(priv, addr, tid, ssn);
|
||||
case IEEE80211_AMPDU_TX_STOP:
|
||||
IWL_DEBUG_HT("stop Tx\n");
|
||||
return iwl_tx_agg_stop(priv, addr, tid);
|
||||
default:
|
||||
IWL_DEBUG_HT("unknown\n");
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int iwl4965_mac_get_tx_stats(struct ieee80211_hw *hw,
|
||||
struct ieee80211_tx_queue_stats *stats)
|
||||
{
|
||||
@ -3592,15 +3687,6 @@ static ssize_t show_temperature(struct device *d,
|
||||
|
||||
static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
|
||||
|
||||
static ssize_t show_rs_window(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct iwl_priv *priv = d->driver_data;
|
||||
return iwl4965_fill_rs_info(priv->hw, buf, IWL_AP_ID);
|
||||
}
|
||||
static DEVICE_ATTR(rs_window, S_IRUGO, show_rs_window, NULL);
|
||||
|
||||
static ssize_t show_tx_power(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@ -3699,7 +3785,7 @@ static ssize_t store_filter_flags(struct device *d,
|
||||
static DEVICE_ATTR(filter_flags, S_IWUSR | S_IRUGO, show_filter_flags,
|
||||
store_filter_flags);
|
||||
|
||||
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
|
||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
||||
|
||||
static ssize_t show_measurement(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
@ -3707,7 +3793,7 @@ static ssize_t show_measurement(struct device *d,
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
struct iwl4965_spectrum_notification measure_report;
|
||||
u32 size = sizeof(measure_report), len = 0, ofs = 0;
|
||||
u8 *data = (u8 *) & measure_report;
|
||||
u8 *data = (u8 *)&measure_report;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
@ -3770,7 +3856,7 @@ static ssize_t store_measurement(struct device *d,
|
||||
|
||||
static DEVICE_ATTR(measurement, S_IRUSR | S_IWUSR,
|
||||
show_measurement, store_measurement);
|
||||
#endif /* CONFIG_IWL4965_SPECTRUM_MEASUREMENT */
|
||||
#endif /* CONFIG_IWLAGN_SPECTRUM_MEASUREMENT */
|
||||
|
||||
static ssize_t store_retry_rate(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
@ -3800,77 +3886,54 @@ static ssize_t store_power_level(struct device *d,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
int rc;
|
||||
int ret;
|
||||
int mode;
|
||||
|
||||
mode = simple_strtoul(buf, NULL, 0);
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
if (!iwl_is_ready(priv)) {
|
||||
rc = -EAGAIN;
|
||||
ret = -EAGAIN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = iwl_power_set_user_mode(priv, mode);
|
||||
if (rc) {
|
||||
ret = iwl_power_set_user_mode(priv, mode);
|
||||
if (ret) {
|
||||
IWL_DEBUG_MAC80211("failed setting power mode.\n");
|
||||
goto out;
|
||||
}
|
||||
rc = count;
|
||||
ret = count;
|
||||
|
||||
out:
|
||||
mutex_unlock(&priv->mutex);
|
||||
return rc;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define MAX_WX_STRING 80
|
||||
|
||||
/* Values are in microsecond */
|
||||
static const s32 timeout_duration[] = {
|
||||
350000,
|
||||
250000,
|
||||
75000,
|
||||
37000,
|
||||
25000,
|
||||
};
|
||||
static const s32 period_duration[] = {
|
||||
400000,
|
||||
700000,
|
||||
1000000,
|
||||
1000000,
|
||||
1000000
|
||||
};
|
||||
|
||||
static ssize_t show_power_level(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
int mode = priv->power_data.user_power_setting;
|
||||
int system = priv->power_data.system_power_setting;
|
||||
int level = priv->power_data.power_mode;
|
||||
char *p = buf;
|
||||
|
||||
p += sprintf(p, "%d ", level);
|
||||
switch (level) {
|
||||
case IWL_POWER_MODE_CAM:
|
||||
case IWL_POWER_AC:
|
||||
p += sprintf(p, "(AC)");
|
||||
switch (system) {
|
||||
case IWL_POWER_SYS_AUTO:
|
||||
p += sprintf(p, "SYSTEM:auto");
|
||||
break;
|
||||
case IWL_POWER_BATTERY:
|
||||
p += sprintf(p, "(BATTERY)");
|
||||
case IWL_POWER_SYS_AC:
|
||||
p += sprintf(p, "SYSTEM:ac");
|
||||
break;
|
||||
case IWL_POWER_SYS_BATTERY:
|
||||
p += sprintf(p, "SYSTEM:battery");
|
||||
break;
|
||||
default:
|
||||
p += sprintf(p,
|
||||
"(Timeout %dms, Period %dms)",
|
||||
timeout_duration[level - 1] / 1000,
|
||||
period_duration[level - 1] / 1000);
|
||||
}
|
||||
/*
|
||||
if (!(priv->power_mode & IWL_POWER_ENABLED))
|
||||
p += sprintf(p, " OFF\n");
|
||||
else
|
||||
p += sprintf(p, " \n");
|
||||
*/
|
||||
p += sprintf(p, " \n");
|
||||
return (p - buf + 1);
|
||||
|
||||
p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO)?"fixed":"auto");
|
||||
p += sprintf(p, "\tINDEX:%d", level);
|
||||
p += sprintf(p, "\n");
|
||||
return p - buf + 1;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
|
||||
@ -3945,7 +4008,7 @@ static ssize_t show_statistics(struct device *d,
|
||||
struct iwl_priv *priv = dev_get_drvdata(d);
|
||||
u32 size = sizeof(struct iwl_notif_statistics);
|
||||
u32 len = 0, ofs = 0;
|
||||
u8 *data = (u8 *) & priv->statistics;
|
||||
u8 *data = (u8 *)&priv->statistics;
|
||||
int rc = 0;
|
||||
|
||||
if (!iwl_is_alive(priv))
|
||||
@ -4041,12 +4104,11 @@ static struct attribute *iwl4965_sysfs_entries[] = {
|
||||
&dev_attr_channels.attr,
|
||||
&dev_attr_flags.attr,
|
||||
&dev_attr_filter_flags.attr,
|
||||
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
|
||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
||||
&dev_attr_measurement.attr,
|
||||
#endif
|
||||
&dev_attr_power_level.attr,
|
||||
&dev_attr_retry_rate.attr,
|
||||
&dev_attr_rs_window.attr,
|
||||
&dev_attr_statistics.attr,
|
||||
&dev_attr_status.attr,
|
||||
&dev_attr_temperature.attr,
|
||||
@ -4394,8 +4456,10 @@ static int iwl4965_pci_resume(struct pci_dev *pdev)
|
||||
|
||||
/* Hardware specific file defines the PCI IDs table for that hardware module */
|
||||
static struct pci_device_id iwl_hw_card_ids[] = {
|
||||
#ifdef CONFIG_IWL4965
|
||||
{IWL_PCI_DEVICE(0x4229, PCI_ANY_ID, iwl4965_agn_cfg)},
|
||||
{IWL_PCI_DEVICE(0x4230, PCI_ANY_ID, iwl4965_agn_cfg)},
|
||||
#endif /* CONFIG_IWL4965 */
|
||||
#ifdef CONFIG_IWL5000
|
||||
{IWL_PCI_DEVICE(0x4232, 0x1205, iwl5100_bg_cfg)},
|
||||
{IWL_PCI_DEVICE(0x4232, 0x1305, iwl5100_bg_cfg)},
|
||||
@ -4431,7 +4495,7 @@ static int __init iwl4965_init(void)
|
||||
printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
|
||||
printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
|
||||
|
||||
ret = iwl4965_rate_control_register();
|
||||
ret = iwlagn_rate_control_register();
|
||||
if (ret) {
|
||||
IWL_ERROR("Unable to register rate control algorithm: %d\n", ret);
|
||||
return ret;
|
||||
@ -4446,14 +4510,14 @@ static int __init iwl4965_init(void)
|
||||
return ret;
|
||||
|
||||
error_register:
|
||||
iwl4965_rate_control_unregister();
|
||||
iwlagn_rate_control_unregister();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit iwl4965_exit(void)
|
||||
{
|
||||
pci_unregister_driver(&iwl_driver);
|
||||
iwl4965_rate_control_unregister();
|
||||
iwlagn_rate_control_unregister();
|
||||
}
|
||||
|
||||
module_exit(iwl4965_exit);
|
@ -666,8 +666,7 @@ struct iwl4965_rxon_assoc_cmd {
|
||||
__le16 reserved;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
|
||||
#define IWL_CONN_MAX_LISTEN_INTERVAL 10
|
||||
|
||||
/*
|
||||
* REPLY_RXON_TIMING = 0x14 (command, has simple generic response)
|
||||
@ -1076,10 +1075,12 @@ struct iwl4965_rx_frame {
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Fixed (non-configurable) rx data from phy */
|
||||
#define RX_PHY_FLAGS_ANTENNAE_OFFSET (4)
|
||||
#define RX_PHY_FLAGS_ANTENNAE_MASK (0x70)
|
||||
#define IWL_AGC_DB_MASK (0x3f80) /* MASK(7,13) */
|
||||
#define IWL_AGC_DB_POS (7)
|
||||
|
||||
#define IWL49_RX_RES_PHY_CNT 14
|
||||
#define IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET (4)
|
||||
#define IWL49_RX_PHY_FLAGS_ANTENNAE_MASK (0x70)
|
||||
#define IWL49_AGC_DB_MASK (0x3f80) /* MASK(7,13) */
|
||||
#define IWL49_AGC_DB_POS (7)
|
||||
struct iwl4965_rx_non_cfg_phy {
|
||||
__le16 ant_selection; /* ant A bit 4, ant B bit 5, ant C bit 6 */
|
||||
__le16 agc_info; /* agc code 0:6, agc dB 7:13, reserved 14:15 */
|
||||
@ -1087,12 +1088,30 @@ struct iwl4965_rx_non_cfg_phy {
|
||||
u8 pad[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
#define IWL50_RX_RES_PHY_CNT 8
|
||||
#define IWL50_RX_RES_AGC_IDX 1
|
||||
#define IWL50_RX_RES_RSSI_AB_IDX 2
|
||||
#define IWL50_RX_RES_RSSI_C_IDX 3
|
||||
#define IWL50_OFDM_AGC_MSK 0xfe00
|
||||
#define IWL50_OFDM_AGC_BIT_POS 9
|
||||
#define IWL50_OFDM_RSSI_A_MSK 0x00ff
|
||||
#define IWL50_OFDM_RSSI_A_BIT_POS 0
|
||||
#define IWL50_OFDM_RSSI_B_MSK 0xff0000
|
||||
#define IWL50_OFDM_RSSI_B_BIT_POS 16
|
||||
#define IWL50_OFDM_RSSI_C_MSK 0x00ff
|
||||
#define IWL50_OFDM_RSSI_C_BIT_POS 0
|
||||
|
||||
struct iwl5000_non_cfg_phy {
|
||||
__le32 non_cfg_phy[IWL50_RX_RES_PHY_CNT]; /* upto 8 phy entries */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/*
|
||||
* REPLY_RX = 0xc3 (response only, not a command)
|
||||
* Used only for legacy (non 11n) frames.
|
||||
*/
|
||||
#define RX_RES_PHY_CNT 14
|
||||
struct iwl4965_rx_phy_res {
|
||||
struct iwl_rx_phy_res {
|
||||
u8 non_cfg_phy_cnt; /* non configurable DSP phy data byte count */
|
||||
u8 cfg_phy_cnt; /* configurable DSP phy data byte count */
|
||||
u8 stat_id; /* configurable DSP phy data set ID */
|
||||
@ -1101,8 +1120,7 @@ struct iwl4965_rx_phy_res {
|
||||
__le32 beacon_time_stamp; /* beacon at on-air rise */
|
||||
__le16 phy_flags; /* general phy flags: band, modulation, ... */
|
||||
__le16 channel; /* channel number */
|
||||
__le16 non_cfg_phy[RX_RES_PHY_CNT]; /* upto 14 phy entries */
|
||||
__le32 reserved2;
|
||||
u8 non_cfg_phy_buf[32]; /* for various implementations of non_cfg_phy */
|
||||
__le32 rate_n_flags; /* RATE_MCS_* */
|
||||
__le16 byte_count; /* frame's byte-count */
|
||||
__le16 reserved3;
|
||||
@ -1993,7 +2011,7 @@ struct iwl4965_spectrum_notification {
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* struct iwl4965_powertable_cmd - Power Table Command
|
||||
* struct iwl_powertable_cmd - Power Table Command
|
||||
* @flags: See below:
|
||||
*
|
||||
* POWER_TABLE_CMD = 0x77 (command, has simple generic response)
|
||||
@ -2027,7 +2045,7 @@ struct iwl4965_spectrum_notification {
|
||||
#define IWL_POWER_PCI_PM_MSK __constant_cpu_to_le16(1 << 3)
|
||||
#define IWL_POWER_FAST_PD __constant_cpu_to_le16(1 << 4)
|
||||
|
||||
struct iwl4965_powertable_cmd {
|
||||
struct iwl_powertable_cmd {
|
||||
__le16 flags;
|
||||
u8 keep_alive_seconds;
|
||||
u8 debug_flags;
|
||||
@ -2324,7 +2342,7 @@ struct iwl4965_beacon_notif {
|
||||
/*
|
||||
* REPLY_TX_BEACON = 0x91 (command, has simple generic response)
|
||||
*/
|
||||
struct iwl4965_tx_beacon_cmd {
|
||||
struct iwl_tx_beacon_cmd {
|
||||
struct iwl_tx_cmd tx;
|
||||
__le16 tim_idx;
|
||||
u8 tim_size;
|
||||
|
@ -383,8 +383,8 @@ void iwl_reset_qos(struct iwl_priv *priv)
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_reset_qos);
|
||||
|
||||
#define MAX_BIT_RATE_40_MHZ 0x96; /* 150 Mbps */
|
||||
#define MAX_BIT_RATE_20_MHZ 0x48; /* 72 Mbps */
|
||||
#define MAX_BIT_RATE_40_MHZ 0x96 /* 150 Mbps */
|
||||
#define MAX_BIT_RATE_20_MHZ 0x48 /* 72 Mbps */
|
||||
static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
|
||||
struct ieee80211_ht_info *ht_info,
|
||||
enum ieee80211_band band)
|
||||
@ -815,7 +815,7 @@ int iwl_setup_mac(struct iwl_priv *priv)
|
||||
{
|
||||
int ret;
|
||||
struct ieee80211_hw *hw = priv->hw;
|
||||
hw->rate_control_algorithm = "iwl-4965-rs";
|
||||
hw->rate_control_algorithm = "iwl-agn-rs";
|
||||
|
||||
/* Tell mac80211 our characteristics */
|
||||
hw->flags = IEEE80211_HW_SIGNAL_DBM |
|
||||
@ -827,6 +827,7 @@ int iwl_setup_mac(struct iwl_priv *priv)
|
||||
hw->ampdu_queues = priv->cfg->mod_params->num_of_ampdu_queues;
|
||||
|
||||
hw->conf.beacon_int = 100;
|
||||
hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
|
||||
|
||||
if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
|
||||
priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
|
||||
|
@ -95,6 +95,8 @@ struct iwl_hcmd_utils_ops {
|
||||
void (*chain_noise_reset)(struct iwl_priv *priv);
|
||||
void (*rts_tx_cmd_flag)(struct ieee80211_tx_info *info,
|
||||
__le32 *tx_flags);
|
||||
int (*calc_rssi)(struct iwl_priv *priv,
|
||||
struct iwl_rx_phy_res *rx_resp);
|
||||
};
|
||||
|
||||
struct iwl_lib_ops {
|
||||
@ -139,7 +141,6 @@ struct iwl_lib_ops {
|
||||
int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
|
||||
} apm_ops;
|
||||
/* power */
|
||||
int (*set_power)(struct iwl_priv *priv, void *cmd);
|
||||
int (*send_tx_power) (struct iwl_priv *priv);
|
||||
void (*update_chain_flags)(struct iwl_priv *priv);
|
||||
void (*temperature) (struct iwl_priv *priv);
|
||||
|
@ -104,6 +104,7 @@
|
||||
* 3-2: 0 = A, 1 = B, 2 = C, 3 = D step
|
||||
*/
|
||||
#define CSR_HW_REV_WA_REG (CSR_BASE+0x22C)
|
||||
#define CSR_DBG_HPET_MEM_REG (CSR_BASE+0x240)
|
||||
|
||||
/* Bits for CSR_HW_IF_CONFIG_REG */
|
||||
#define CSR49_HW_IF_CONFIG_REG_BIT_4965_R (0x00000010)
|
||||
@ -118,7 +119,12 @@
|
||||
#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A (0x00000000)
|
||||
#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B (0x00001000)
|
||||
|
||||
#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000)
|
||||
#define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A (0x00080000)
|
||||
#define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM (0x00200000)
|
||||
#define CSR_HW_IF_CONFIG_REG_BIT_PCI_OWN_SEM (0x00400000)
|
||||
#define CSR_HW_IF_CONFIG_REG_BIT_ME_OWN (0x02000000)
|
||||
#define CSR_HW_IF_CONFIG_REG_BIT_WAKE_ME (0x08000000)
|
||||
|
||||
|
||||
/* interrupt flags in INTA, set by uCode or hardware (e.g. dma),
|
||||
* acknowledged (reset) by host writing "1" to flagged bits. */
|
||||
@ -236,6 +242,8 @@
|
||||
#define CSR39_ANA_PLL_CFG_VAL (0x01000000)
|
||||
#define CSR50_ANA_PLL_CFG_VAL (0x00880300)
|
||||
|
||||
/* HPET MEM debug */
|
||||
#define CSR_DBG_HPET_MEM_REG_VAL (0xFFFF0000)
|
||||
/*=== HBUS (Host-side Bus) ===*/
|
||||
#define HBUS_BASE (0x400)
|
||||
/*
|
||||
|
@ -33,12 +33,12 @@
|
||||
#define IWL_DEBUG(level, fmt, args...) \
|
||||
do { if (priv->debug_level & (level)) \
|
||||
dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
|
||||
in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
|
||||
in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
|
||||
|
||||
#define IWL_DEBUG_LIMIT(level, fmt, args...) \
|
||||
do { if ((priv->debug_level & (level)) && net_ratelimit()) \
|
||||
dev_printk(KERN_ERR, &(priv->hw->wiphy->dev), "%c %s " fmt, \
|
||||
in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
|
||||
in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
struct iwl_debugfs {
|
||||
|
@ -231,7 +231,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
|
||||
DECLARE_MAC_BUF(mac);
|
||||
|
||||
buf = kmalloc(bufsz, GFP_KERNEL);
|
||||
if(!buf)
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",
|
||||
@ -364,16 +364,19 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
|
||||
{
|
||||
struct iwl_debugfs *dbgfs;
|
||||
struct dentry *phyd = priv->hw->wiphy->debugfsdir;
|
||||
int ret = 0;
|
||||
|
||||
dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL);
|
||||
if (!dbgfs) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
priv->dbgfs = dbgfs;
|
||||
dbgfs->name = name;
|
||||
dbgfs->dir_drv = debugfs_create_dir(name, phyd);
|
||||
if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)){
|
||||
if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)) {
|
||||
ret = -ENOENT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -394,7 +397,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
|
||||
err:
|
||||
IWL_ERROR("Can't open the debugfs directory\n");
|
||||
iwl_dbgfs_unregister(priv);
|
||||
return -ENOENT;
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_dbgfs_register);
|
||||
|
||||
@ -404,7 +407,7 @@ EXPORT_SYMBOL(iwl_dbgfs_register);
|
||||
*/
|
||||
void iwl_dbgfs_unregister(struct iwl_priv *priv)
|
||||
{
|
||||
if (!(priv->dbgfs))
|
||||
if (!priv->dbgfs)
|
||||
return;
|
||||
|
||||
DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_eeprom);
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <net/ieee80211_radiotap.h>
|
||||
|
||||
#define DRV_NAME "iwl4965"
|
||||
#define DRV_NAME "iwlagn"
|
||||
#include "iwl-rfkill.h"
|
||||
#include "iwl-eeprom.h"
|
||||
#include "iwl-4965-hw.h"
|
||||
@ -45,6 +45,7 @@
|
||||
#include "iwl-debug.h"
|
||||
#include "iwl-led.h"
|
||||
#include "iwl-power.h"
|
||||
#include "iwl-agn-rs.h"
|
||||
|
||||
/* configuration for the iwl4965 */
|
||||
extern struct iwl_cfg iwl4965_agn_cfg;
|
||||
@ -134,8 +135,7 @@ struct iwl_tx_info {
|
||||
struct iwl_tx_queue {
|
||||
struct iwl_queue q;
|
||||
struct iwl_tfd_frame *bd;
|
||||
struct iwl_cmd *cmd;
|
||||
dma_addr_t dma_addr_cmd;
|
||||
struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS];
|
||||
struct iwl_tx_info *txb;
|
||||
int need_update;
|
||||
int sched_retry;
|
||||
@ -191,7 +191,6 @@ struct iwl4965_clip_group {
|
||||
const s8 clip_powers[IWL_MAX_RATES];
|
||||
};
|
||||
|
||||
#include "iwl-4965-rs.h"
|
||||
|
||||
#define IWL_TX_FIFO_AC0 0
|
||||
#define IWL_TX_FIFO_AC1 1
|
||||
@ -219,7 +218,7 @@ enum iwl_pwr_src {
|
||||
struct iwl_frame {
|
||||
union {
|
||||
struct ieee80211_hdr frame;
|
||||
struct iwl4965_tx_beacon_cmd beacon;
|
||||
struct iwl_tx_beacon_cmd beacon;
|
||||
u8 raw[IEEE80211_FRAME_LEN];
|
||||
u8 cmd[360];
|
||||
} u;
|
||||
@ -283,10 +282,9 @@ struct iwl_cmd {
|
||||
u32 val32;
|
||||
struct iwl4965_bt_cmd bt;
|
||||
struct iwl4965_rxon_time_cmd rxon_time;
|
||||
struct iwl4965_powertable_cmd powertable;
|
||||
struct iwl_powertable_cmd powertable;
|
||||
struct iwl_qosparam_cmd qosparam;
|
||||
struct iwl_tx_cmd tx;
|
||||
struct iwl4965_tx_beacon_cmd tx_beacon;
|
||||
struct iwl4965_rxon_assoc_cmd rxon_assoc;
|
||||
struct iwl_rem_sta_cmd rm_sta;
|
||||
u8 *indirect;
|
||||
@ -590,6 +588,7 @@ extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
|
||||
const u8 *dest, int left);
|
||||
extern void iwl4965_update_chain_flags(struct iwl_priv *priv);
|
||||
int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src);
|
||||
extern int iwl4965_set_power(struct iwl_priv *priv, void *cmd);
|
||||
|
||||
extern const u8 iwl_bcast_addr[ETH_ALEN];
|
||||
|
||||
@ -642,10 +641,6 @@ struct iwl_priv;
|
||||
* Forward declare iwl-4965.c functions for iwl-base.c
|
||||
*/
|
||||
extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv);
|
||||
|
||||
int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
const u8 *addr, u16 tid, u16 *ssn);
|
||||
int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id,
|
||||
u8 tid, int txq_id);
|
||||
|
||||
@ -812,14 +807,11 @@ struct iwl_chain_noise_data {
|
||||
#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */
|
||||
|
||||
|
||||
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
|
||||
|
||||
enum {
|
||||
MEASUREMENT_READY = (1 << 0),
|
||||
MEASUREMENT_ACTIVE = (1 << 1),
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#define IWL_MAX_NUM_QUEUES 20 /* FIXME: do dynamic allocation */
|
||||
|
||||
@ -844,7 +836,7 @@ struct iwl_priv {
|
||||
|
||||
struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
|
||||
|
||||
#ifdef CONFIG_IWL4965_SPECTRUM_MEASUREMENT
|
||||
#ifdef CONFIG_IWLAGN_SPECTRUM_MEASUREMENT
|
||||
/* spectrum measurement report caching */
|
||||
struct iwl4965_spectrum_notification measure_report;
|
||||
u8 measurement_status;
|
||||
|
@ -273,8 +273,7 @@ EXPORT_SYMBOL(iwl_eeprom_init);
|
||||
|
||||
void iwl_eeprom_free(struct iwl_priv *priv)
|
||||
{
|
||||
if(priv->eeprom)
|
||||
kfree(priv->eeprom);
|
||||
kfree(priv->eeprom);
|
||||
priv->eeprom = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_eeprom_free);
|
||||
|
@ -228,7 +228,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
|
||||
* TX cmd queue. Otherwise in case the cmd comes
|
||||
* in later, it will possibly set an invalid
|
||||
* address (cmd->meta.source). */
|
||||
qcmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx];
|
||||
qcmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx];
|
||||
qcmd->meta.flags &= ~CMD_WANT_SKB;
|
||||
}
|
||||
fail:
|
||||
|
@ -161,11 +161,31 @@ int iwl4965_led_off(struct iwl_priv *priv, int led_id)
|
||||
/* Set led register off */
|
||||
static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id)
|
||||
{
|
||||
IWL_DEBUG_LED("radio off\n");
|
||||
IWL_DEBUG_LED("LED Reg off\n");
|
||||
iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set led register in case of disassociation according to rfkill state
|
||||
*/
|
||||
static int iwl_led_associate(struct iwl_priv *priv, int led_id)
|
||||
{
|
||||
IWL_DEBUG_LED("Associated\n");
|
||||
priv->allow_blinking = 1;
|
||||
return iwl4965_led_on_reg(priv, led_id);
|
||||
}
|
||||
static int iwl_led_disassociate(struct iwl_priv *priv, int led_id)
|
||||
{
|
||||
priv->allow_blinking = 0;
|
||||
if (iwl_is_rfkill(priv))
|
||||
iwl4965_led_off_reg(priv, led_id);
|
||||
else
|
||||
iwl4965_led_on_reg(priv, led_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* brightness call back function for Tx/Rx LED
|
||||
*/
|
||||
@ -199,16 +219,10 @@ static void iwl_led_brightness_set(struct led_classdev *led_cdev,
|
||||
led_type_str[led->type], brightness);
|
||||
switch (brightness) {
|
||||
case LED_FULL:
|
||||
if (led->type == IWL_LED_TRG_ASSOC)
|
||||
priv->allow_blinking = 1;
|
||||
|
||||
if (led->led_on)
|
||||
led->led_on(priv, IWL_LED_LINK);
|
||||
break;
|
||||
case LED_OFF:
|
||||
if (led->type == IWL_LED_TRG_ASSOC)
|
||||
priv->allow_blinking = 0;
|
||||
|
||||
if (led->led_off)
|
||||
led->led_off(priv, IWL_LED_LINK);
|
||||
break;
|
||||
@ -228,12 +242,12 @@ static void iwl_led_brightness_set(struct led_classdev *led_cdev,
|
||||
*/
|
||||
static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led,
|
||||
enum led_type type, u8 set_led,
|
||||
const char *name, char *trigger)
|
||||
char *trigger)
|
||||
{
|
||||
struct device *device = wiphy_dev(priv->hw->wiphy);
|
||||
int ret;
|
||||
|
||||
led->led_dev.name = name;
|
||||
led->led_dev.name = led->name;
|
||||
led->led_dev.brightness_set = iwl_led_brightness_set;
|
||||
led->led_dev.default_trigger = trigger;
|
||||
|
||||
@ -284,12 +298,6 @@ static int iwl_get_blink_rate(struct iwl_priv *priv)
|
||||
return i;
|
||||
}
|
||||
|
||||
static inline int is_rf_kill(struct iwl_priv *priv)
|
||||
{
|
||||
return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
|
||||
test_bit(STATUS_RF_KILL_SW, &priv->status);
|
||||
}
|
||||
|
||||
/*
|
||||
* this function called from handler. Since setting Led command can
|
||||
* happen very frequent we postpone led command to be called from
|
||||
@ -303,7 +311,7 @@ void iwl_leds_background(struct iwl_priv *priv)
|
||||
priv->last_blink_time = 0;
|
||||
return;
|
||||
}
|
||||
if (is_rf_kill(priv)) {
|
||||
if (iwl_is_rfkill(priv)) {
|
||||
priv->last_blink_time = 0;
|
||||
return;
|
||||
}
|
||||
@ -337,7 +345,6 @@ EXPORT_SYMBOL(iwl_leds_background);
|
||||
int iwl_leds_register(struct iwl_priv *priv)
|
||||
{
|
||||
char *trigger;
|
||||
char name[32];
|
||||
int ret;
|
||||
|
||||
priv->last_blink_rate = 0;
|
||||
@ -346,7 +353,8 @@ int iwl_leds_register(struct iwl_priv *priv)
|
||||
priv->allow_blinking = 0;
|
||||
|
||||
trigger = ieee80211_get_radio_led_name(priv->hw);
|
||||
snprintf(name, sizeof(name), "iwl-%s:radio",
|
||||
snprintf(priv->led[IWL_LED_TRG_RADIO].name,
|
||||
sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s:radio",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
|
||||
priv->led[IWL_LED_TRG_RADIO].led_on = iwl4965_led_on_reg;
|
||||
@ -354,31 +362,33 @@ int iwl_leds_register(struct iwl_priv *priv)
|
||||
priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;
|
||||
|
||||
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RADIO],
|
||||
IWL_LED_TRG_RADIO, 1, name, trigger);
|
||||
IWL_LED_TRG_RADIO, 1, trigger);
|
||||
if (ret)
|
||||
goto exit_fail;
|
||||
|
||||
trigger = ieee80211_get_assoc_led_name(priv->hw);
|
||||
snprintf(name, sizeof(name), "iwl-%s:assoc",
|
||||
snprintf(priv->led[IWL_LED_TRG_ASSOC].name,
|
||||
sizeof(priv->led[IWL_LED_TRG_ASSOC].name), "iwl-%s:assoc",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
|
||||
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_ASSOC],
|
||||
IWL_LED_TRG_ASSOC, 0, name, trigger);
|
||||
IWL_LED_TRG_ASSOC, 0, trigger);
|
||||
|
||||
/* for assoc always turn led on */
|
||||
priv->led[IWL_LED_TRG_ASSOC].led_on = iwl4965_led_on_reg;
|
||||
priv->led[IWL_LED_TRG_ASSOC].led_off = iwl4965_led_on_reg;
|
||||
priv->led[IWL_LED_TRG_ASSOC].led_on = iwl_led_associate;
|
||||
priv->led[IWL_LED_TRG_ASSOC].led_off = iwl_led_disassociate;
|
||||
priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;
|
||||
|
||||
if (ret)
|
||||
goto exit_fail;
|
||||
|
||||
trigger = ieee80211_get_rx_led_name(priv->hw);
|
||||
snprintf(name, sizeof(name), "iwl-%s:RX", wiphy_name(priv->hw->wiphy));
|
||||
|
||||
snprintf(priv->led[IWL_LED_TRG_RX].name,
|
||||
sizeof(priv->led[IWL_LED_TRG_RX].name), "iwl-%s:RX",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
|
||||
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RX],
|
||||
IWL_LED_TRG_RX, 0, name, trigger);
|
||||
IWL_LED_TRG_RX, 0, trigger);
|
||||
|
||||
priv->led[IWL_LED_TRG_RX].led_on = iwl_led_associated;
|
||||
priv->led[IWL_LED_TRG_RX].led_off = iwl_led_associated;
|
||||
@ -388,9 +398,12 @@ int iwl_leds_register(struct iwl_priv *priv)
|
||||
goto exit_fail;
|
||||
|
||||
trigger = ieee80211_get_tx_led_name(priv->hw);
|
||||
snprintf(name, sizeof(name), "iwl-%s:TX", wiphy_name(priv->hw->wiphy));
|
||||
snprintf(priv->led[IWL_LED_TRG_TX].name,
|
||||
sizeof(priv->led[IWL_LED_TRG_TX].name), "iwl-%s:TX",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
|
||||
ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_TX],
|
||||
IWL_LED_TRG_TX, 0, name, trigger);
|
||||
IWL_LED_TRG_TX, 0, trigger);
|
||||
|
||||
priv->led[IWL_LED_TRG_TX].led_on = iwl_led_associated;
|
||||
priv->led[IWL_LED_TRG_TX].led_off = iwl_led_associated;
|
||||
|
@ -52,6 +52,7 @@ enum led_type {
|
||||
struct iwl_led {
|
||||
struct iwl_priv *priv;
|
||||
struct led_classdev led_dev;
|
||||
char name[32];
|
||||
|
||||
int (*led_on) (struct iwl_priv *priv, int led_id);
|
||||
int (*led_off) (struct iwl_priv *priv, int led_id);
|
||||
|
@ -82,7 +82,7 @@
|
||||
|
||||
/* default power management (not Tx power) table values */
|
||||
/* for tim 0-10 */
|
||||
static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = {
|
||||
static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = {
|
||||
{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
|
||||
@ -93,7 +93,7 @@ static struct iwl_power_vec_entry range_0[IWL_POWER_AC] = {
|
||||
|
||||
|
||||
/* for tim = 3-10 */
|
||||
static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = {
|
||||
static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = {
|
||||
{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0},
|
||||
@ -103,7 +103,7 @@ static struct iwl_power_vec_entry range_1[IWL_POWER_AC] = {
|
||||
};
|
||||
|
||||
/* for tim > 11 */
|
||||
static struct iwl_power_vec_entry range_2[IWL_POWER_AC] = {
|
||||
static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = {
|
||||
{{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
|
||||
{{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
|
||||
@ -112,12 +112,19 @@ static struct iwl_power_vec_entry range_2[IWL_POWER_AC] = {
|
||||
{{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
|
||||
};
|
||||
|
||||
/* set card power command */
|
||||
static int iwl_set_power(struct iwl_priv *priv, void *cmd)
|
||||
{
|
||||
return iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD,
|
||||
sizeof(struct iwl_powertable_cmd),
|
||||
cmd, NULL);
|
||||
}
|
||||
/* decide the right power level according to association status
|
||||
* and battery status
|
||||
*/
|
||||
static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
|
||||
{
|
||||
u16 mode = priv->power_data.user_power_setting;
|
||||
u16 mode;
|
||||
|
||||
switch (priv->power_data.user_power_setting) {
|
||||
case IWL_POWER_AUTO:
|
||||
@ -129,12 +136,16 @@ static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
|
||||
else
|
||||
mode = IWL_POWER_ON_AC_DISASSOC;
|
||||
break;
|
||||
/* FIXME: remove battery and ac from here */
|
||||
case IWL_POWER_BATTERY:
|
||||
mode = IWL_POWER_INDEX_3;
|
||||
break;
|
||||
case IWL_POWER_AC:
|
||||
mode = IWL_POWER_MODE_CAM;
|
||||
break;
|
||||
default:
|
||||
mode = priv->power_data.user_power_setting;
|
||||
break;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
@ -144,7 +155,7 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
|
||||
{
|
||||
int ret = 0, i;
|
||||
struct iwl_power_mgr *pow_data;
|
||||
int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_AC;
|
||||
int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX;
|
||||
u16 pci_pm;
|
||||
|
||||
IWL_DEBUG_POWER("Initialize power \n");
|
||||
@ -162,11 +173,11 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
|
||||
if (ret != 0)
|
||||
return 0;
|
||||
else {
|
||||
struct iwl4965_powertable_cmd *cmd;
|
||||
struct iwl_powertable_cmd *cmd;
|
||||
|
||||
IWL_DEBUG_POWER("adjust power command flags\n");
|
||||
|
||||
for (i = 0; i < IWL_POWER_AC; i++) {
|
||||
for (i = 0; i < IWL_POWER_MAX; i++) {
|
||||
cmd = &pow_data->pwr_range_0[i].cmd;
|
||||
|
||||
if (pci_pm & 0x1)
|
||||
@ -180,7 +191,7 @@ static int iwl_power_init_handle(struct iwl_priv *priv)
|
||||
|
||||
/* adjust power command according to dtim period and power level*/
|
||||
static int iwl_update_power_command(struct iwl_priv *priv,
|
||||
struct iwl4965_powertable_cmd *cmd,
|
||||
struct iwl_powertable_cmd *cmd,
|
||||
u16 mode)
|
||||
{
|
||||
int ret = 0, i;
|
||||
@ -204,7 +215,7 @@ static int iwl_update_power_command(struct iwl_priv *priv,
|
||||
range = &pow_data->pwr_range_2[0];
|
||||
|
||||
period = pow_data->dtim_period;
|
||||
memcpy(cmd, &range[mode].cmd, sizeof(struct iwl4965_powertable_cmd));
|
||||
memcpy(cmd, &range[mode].cmd, sizeof(struct iwl_powertable_cmd));
|
||||
|
||||
if (period == 0) {
|
||||
period = 1;
|
||||
@ -258,17 +269,18 @@ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh)
|
||||
* else user level */
|
||||
|
||||
switch (setting->system_power_setting) {
|
||||
case IWL_POWER_AUTO:
|
||||
case IWL_POWER_SYS_AUTO:
|
||||
final_mode = iwl_get_auto_power_mode(priv);
|
||||
break;
|
||||
case IWL_POWER_BATTERY:
|
||||
case IWL_POWER_SYS_BATTERY:
|
||||
final_mode = IWL_POWER_INDEX_3;
|
||||
break;
|
||||
case IWL_POWER_AC:
|
||||
case IWL_POWER_SYS_AC:
|
||||
final_mode = IWL_POWER_MODE_CAM;
|
||||
break;
|
||||
default:
|
||||
final_mode = setting->system_power_setting;
|
||||
final_mode = IWL_POWER_INDEX_3;
|
||||
WARN_ON(1);
|
||||
}
|
||||
|
||||
if (setting->critical_power_setting > final_mode)
|
||||
@ -280,7 +292,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh)
|
||||
|
||||
if (!iwl_is_rfkill(priv) && !setting->power_disabled &&
|
||||
((setting->power_mode != final_mode) || refresh)) {
|
||||
struct iwl4965_powertable_cmd cmd;
|
||||
struct iwl_powertable_cmd cmd;
|
||||
|
||||
if (final_mode != IWL_POWER_MODE_CAM)
|
||||
set_bit(STATUS_POWER_PMI, &priv->status);
|
||||
@ -291,8 +303,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, u8 refresh)
|
||||
if (final_mode == IWL_POWER_INDEX_5)
|
||||
cmd.flags |= IWL_POWER_FAST_PD;
|
||||
|
||||
if (priv->cfg->ops->lib->set_power)
|
||||
ret = priv->cfg->ops->lib->set_power(priv, &cmd);
|
||||
ret = iwl_set_power(priv, &cmd);
|
||||
|
||||
if (final_mode == IWL_POWER_MODE_CAM)
|
||||
clear_bit(STATUS_POWER_PMI, &priv->status);
|
||||
@ -388,7 +399,7 @@ void iwl_power_initialize(struct iwl_priv *priv)
|
||||
iwl_power_init_handle(priv);
|
||||
priv->power_data.user_power_setting = IWL_POWER_AUTO;
|
||||
priv->power_data.power_disabled = 0;
|
||||
priv->power_data.system_power_setting = IWL_POWER_AUTO;
|
||||
priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO;
|
||||
priv->power_data.is_battery_active = 0;
|
||||
priv->power_data.power_disabled = 0;
|
||||
priv->power_data.critical_power_setting = 0;
|
||||
|
@ -33,12 +33,25 @@
|
||||
|
||||
struct iwl_priv;
|
||||
|
||||
#define IWL_POWER_MODE_CAM 0x00 /* Continuously Aware Mode, always on */
|
||||
#define IWL_POWER_INDEX_3 0x03
|
||||
#define IWL_POWER_INDEX_5 0x05
|
||||
#define IWL_POWER_AC 0x06
|
||||
#define IWL_POWER_BATTERY 0x07
|
||||
#define IWL_POWER_AUTO 0x08
|
||||
enum {
|
||||
IWL_POWER_MODE_CAM, /* Continuously Aware Mode, always on */
|
||||
IWL_POWER_INDEX_1,
|
||||
IWL_POWER_INDEX_2,
|
||||
IWL_POWER_INDEX_3,
|
||||
IWL_POWER_INDEX_4,
|
||||
IWL_POWER_INDEX_5,
|
||||
IWL_POWER_AUTO,
|
||||
IWL_POWER_MAX = IWL_POWER_AUTO,
|
||||
IWL_POWER_AC,
|
||||
IWL_POWER_BATTERY,
|
||||
};
|
||||
|
||||
enum {
|
||||
IWL_POWER_SYS_AUTO,
|
||||
IWL_POWER_SYS_AC,
|
||||
IWL_POWER_SYS_BATTERY,
|
||||
};
|
||||
|
||||
#define IWL_POWER_LIMIT 0x08
|
||||
#define IWL_POWER_MASK 0x0F
|
||||
#define IWL_POWER_ENABLED 0x10
|
||||
@ -46,15 +59,15 @@ struct iwl_priv;
|
||||
/* Power management (not Tx power) structures */
|
||||
|
||||
struct iwl_power_vec_entry {
|
||||
struct iwl4965_powertable_cmd cmd;
|
||||
struct iwl_powertable_cmd cmd;
|
||||
u8 no_dtim;
|
||||
};
|
||||
|
||||
struct iwl_power_mgr {
|
||||
spinlock_t lock;
|
||||
struct iwl_power_vec_entry pwr_range_0[IWL_POWER_AC];
|
||||
struct iwl_power_vec_entry pwr_range_1[IWL_POWER_AC];
|
||||
struct iwl_power_vec_entry pwr_range_2[IWL_POWER_AC];
|
||||
struct iwl_power_vec_entry pwr_range_0[IWL_POWER_MAX];
|
||||
struct iwl_power_vec_entry pwr_range_1[IWL_POWER_MAX];
|
||||
struct iwl_power_vec_entry pwr_range_2[IWL_POWER_MAX];
|
||||
u32 dtim_period;
|
||||
/* final power level that used to calculate final power command */
|
||||
u8 power_mode;
|
||||
|
@ -84,14 +84,16 @@
|
||||
#define APMG_CLK_VAL_DMA_CLK_RQT (0x00000200)
|
||||
#define APMG_CLK_VAL_BSM_CLK_RQT (0x00000800)
|
||||
|
||||
#define APMG_PS_CTRL_VAL_RESET_REQ (0x04000000)
|
||||
|
||||
#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800)
|
||||
#define APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS (0x00400000)
|
||||
#define APMG_PS_CTRL_VAL_RESET_REQ (0x04000000)
|
||||
#define APMG_PS_CTRL_MSK_PWR_SRC (0x03000000)
|
||||
#define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN (0x00000000)
|
||||
#define APMG_PS_CTRL_VAL_PWR_SRC_MAX (0x01000000) /* 3945 only */
|
||||
#define APMG_PS_CTRL_VAL_PWR_SRC_VAUX (0x02000000)
|
||||
|
||||
#define APMG_PS_CTRL_MSK_PWR_SRC (0x03000000)
|
||||
#define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN (0x00000000)
|
||||
#define APMG_PS_CTRL_VAL_PWR_SRC_VAUX (0x01000000)
|
||||
|
||||
#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800)
|
||||
|
||||
/**
|
||||
* BSM (Bootstrap State Machine)
|
||||
|
@ -791,7 +791,7 @@ static inline void iwl_dbg_report_frame(struct iwl_priv *priv,
|
||||
|
||||
static void iwl_add_radiotap(struct iwl_priv *priv,
|
||||
struct sk_buff *skb,
|
||||
struct iwl4965_rx_phy_res *rx_start,
|
||||
struct iwl_rx_phy_res *rx_start,
|
||||
struct ieee80211_rx_status *stats,
|
||||
u32 ampdu_status)
|
||||
{
|
||||
@ -1010,8 +1010,8 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
|
||||
struct ieee80211_rx_status *stats)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
|
||||
struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
|
||||
(struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) : NULL;
|
||||
struct iwl_rx_phy_res *rx_start = (include_phy) ?
|
||||
(struct iwl_rx_phy_res *)&(pkt->u.raw[0]) : NULL;
|
||||
struct ieee80211_hdr *hdr;
|
||||
u16 len;
|
||||
__le32 *rx_end;
|
||||
@ -1020,7 +1020,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
|
||||
u32 ampdu_status_legacy;
|
||||
|
||||
if (!include_phy && priv->last_phy_res[0])
|
||||
rx_start = (struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
|
||||
rx_start = (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
|
||||
|
||||
if (!rx_start) {
|
||||
IWL_ERROR("MPDU frame without a PHY data\n");
|
||||
@ -1032,8 +1032,8 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
|
||||
|
||||
len = le16_to_cpu(rx_start->byte_count);
|
||||
|
||||
rx_end = (__le32 *) ((u8 *) &pkt->u.raw[0] +
|
||||
sizeof(struct iwl4965_rx_phy_res) +
|
||||
rx_end = (__le32 *)((u8 *) &pkt->u.raw[0] +
|
||||
sizeof(struct iwl_rx_phy_res) +
|
||||
rx_start->cfg_phy_cnt + len);
|
||||
|
||||
} else {
|
||||
@ -1084,40 +1084,13 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
|
||||
}
|
||||
|
||||
/* Calc max signal level (dBm) among 3 possible receivers */
|
||||
static int iwl_calc_rssi(struct iwl_priv *priv,
|
||||
struct iwl4965_rx_phy_res *rx_resp)
|
||||
static inline int iwl_calc_rssi(struct iwl_priv *priv,
|
||||
struct iwl_rx_phy_res *rx_resp)
|
||||
{
|
||||
/* data from PHY/DSP regarding signal strength, etc.,
|
||||
* contents are always there, not configurable by host. */
|
||||
struct iwl4965_rx_non_cfg_phy *ncphy =
|
||||
(struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy;
|
||||
u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL_AGC_DB_MASK)
|
||||
>> IWL_AGC_DB_POS;
|
||||
|
||||
u32 valid_antennae =
|
||||
(le16_to_cpu(rx_resp->phy_flags) & RX_PHY_FLAGS_ANTENNAE_MASK)
|
||||
>> RX_PHY_FLAGS_ANTENNAE_OFFSET;
|
||||
u8 max_rssi = 0;
|
||||
u32 i;
|
||||
|
||||
/* Find max rssi among 3 possible receivers.
|
||||
* These values are measured by the digital signal processor (DSP).
|
||||
* They should stay fairly constant even as the signal strength varies,
|
||||
* if the radio's automatic gain control (AGC) is working right.
|
||||
* AGC value (see below) will provide the "interesting" info. */
|
||||
for (i = 0; i < 3; i++)
|
||||
if (valid_antennae & (1 << i))
|
||||
max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
|
||||
|
||||
IWL_DEBUG_STATS("Rssi In A %d B %d C %d Max %d AGC dB %d\n",
|
||||
ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
|
||||
max_rssi, agc);
|
||||
|
||||
/* dBm = max_rssi dB - agc dB - constant.
|
||||
* Higher AGC (higher radio gain) means lower signal. */
|
||||
return max_rssi - agc - IWL_RSSI_OFFSET;
|
||||
return priv->cfg->ops->utils->calc_rssi(priv, rx_resp);
|
||||
}
|
||||
|
||||
|
||||
static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
|
||||
{
|
||||
unsigned long flags;
|
||||
@ -1180,9 +1153,9 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
|
||||
* this rx packet for legacy frames,
|
||||
* or phy data cached from REPLY_RX_PHY_CMD for HT frames. */
|
||||
int include_phy = (pkt->hdr.cmd == REPLY_RX);
|
||||
struct iwl4965_rx_phy_res *rx_start = (include_phy) ?
|
||||
(struct iwl4965_rx_phy_res *)&(pkt->u.raw[0]) :
|
||||
(struct iwl4965_rx_phy_res *)&priv->last_phy_res[1];
|
||||
struct iwl_rx_phy_res *rx_start = (include_phy) ?
|
||||
(struct iwl_rx_phy_res *)&(pkt->u.raw[0]) :
|
||||
(struct iwl_rx_phy_res *)&priv->last_phy_res[1];
|
||||
__le32 *rx_end;
|
||||
unsigned int len = 0;
|
||||
u16 fc;
|
||||
@ -1210,7 +1183,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
|
||||
|
||||
if (!include_phy) {
|
||||
if (priv->last_phy_res[0])
|
||||
rx_start = (struct iwl4965_rx_phy_res *)
|
||||
rx_start = (struct iwl_rx_phy_res *)
|
||||
&priv->last_phy_res[1];
|
||||
else
|
||||
rx_start = NULL;
|
||||
@ -1227,7 +1200,7 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
|
||||
|
||||
len = le16_to_cpu(rx_start->byte_count);
|
||||
rx_end = (__le32 *)(pkt->u.raw + rx_start->cfg_phy_cnt +
|
||||
sizeof(struct iwl4965_rx_phy_res) + len);
|
||||
sizeof(struct iwl_rx_phy_res) + len);
|
||||
} else {
|
||||
struct iwl4965_rx_mpdu_res_start *amsdu =
|
||||
(struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
|
||||
@ -1316,6 +1289,6 @@ void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
|
||||
struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
|
||||
priv->last_phy_res[0] = 1;
|
||||
memcpy(&priv->last_phy_res[1], &(pkt->u.raw[0]),
|
||||
sizeof(struct iwl4965_rx_phy_res));
|
||||
sizeof(struct iwl_rx_phy_res));
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_rx_reply_rx_phy);
|
||||
|
@ -202,6 +202,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
|
||||
clear_bit(STATUS_SCAN_HW, &priv->status);
|
||||
}
|
||||
|
||||
priv->alloc_rxb_skb--;
|
||||
dev_kfree_skb_any(cmd.meta.u.skb);
|
||||
|
||||
return ret;
|
||||
|
@ -823,7 +823,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
|
||||
if (lq->sta_id == 0xFF)
|
||||
lq->sta_id = IWL_AP_ID;
|
||||
|
||||
iwl_dump_lq_cmd(priv,lq);
|
||||
iwl_dump_lq_cmd(priv, lq);
|
||||
|
||||
if (iwl_is_associated(priv) && priv->assoc_station_added)
|
||||
return iwl_send_cmd(priv, &cmd);
|
||||
@ -839,7 +839,7 @@ EXPORT_SYMBOL(iwl_send_lq_cmd);
|
||||
* for automatic fallback during transmission.
|
||||
*
|
||||
* NOTE: This sets up a default set of values. These will be replaced later
|
||||
* if the driver's iwl-4965-rs rate scaling algorithm is used, instead of
|
||||
* if the driver's iwl-agn-rs rate scaling algorithm is used, instead of
|
||||
* rc80211_simple.
|
||||
*
|
||||
* NOTE: Run REPLY_ADD_STA command to set up station table entry, before
|
||||
|
@ -208,11 +208,12 @@ EXPORT_SYMBOL(iwl_txq_update_write_ptr);
|
||||
* Free all buffers.
|
||||
* 0-fill, but do not free "txq" descriptor structure.
|
||||
*/
|
||||
static void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq)
|
||||
static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
|
||||
{
|
||||
struct iwl_tx_queue *txq = &priv->txq[txq_id];
|
||||
struct iwl_queue *q = &txq->q;
|
||||
struct pci_dev *dev = priv->pci_dev;
|
||||
int len;
|
||||
int i, slots_num, len;
|
||||
|
||||
if (q->n_bd == 0)
|
||||
return;
|
||||
@ -227,7 +228,12 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq)
|
||||
len += IWL_MAX_SCAN_SIZE;
|
||||
|
||||
/* De-alloc array of command/tx buffers */
|
||||
pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
|
||||
slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
|
||||
TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
|
||||
for (i = 0; i < slots_num; i++)
|
||||
kfree(txq->cmd[i]);
|
||||
if (txq_id == IWL_CMD_QUEUE_NUM)
|
||||
kfree(txq->cmd[slots_num]);
|
||||
|
||||
/* De-alloc circular buffer of TFDs */
|
||||
if (txq->q.n_bd)
|
||||
@ -400,8 +406,7 @@ static int iwl_tx_queue_init(struct iwl_priv *priv,
|
||||
struct iwl_tx_queue *txq,
|
||||
int slots_num, u32 txq_id)
|
||||
{
|
||||
struct pci_dev *dev = priv->pci_dev;
|
||||
int len;
|
||||
int i, len;
|
||||
int rc = 0;
|
||||
|
||||
/*
|
||||
@ -412,17 +417,25 @@ static int iwl_tx_queue_init(struct iwl_priv *priv,
|
||||
* For normal Tx queues (all other queues), no super-size command
|
||||
* space is needed.
|
||||
*/
|
||||
len = sizeof(struct iwl_cmd) * slots_num;
|
||||
if (txq_id == IWL_CMD_QUEUE_NUM)
|
||||
len += IWL_MAX_SCAN_SIZE;
|
||||
txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd);
|
||||
if (!txq->cmd)
|
||||
return -ENOMEM;
|
||||
len = sizeof(struct iwl_cmd);
|
||||
for (i = 0; i <= slots_num; i++) {
|
||||
if (i == slots_num) {
|
||||
if (txq_id == IWL_CMD_QUEUE_NUM)
|
||||
len += IWL_MAX_SCAN_SIZE;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
txq->cmd[i] = kmalloc(len, GFP_KERNEL | GFP_DMA);
|
||||
if (!txq->cmd[i])
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Alloc driver data array and TFD circular buffer */
|
||||
rc = iwl_tx_queue_alloc(priv, txq, txq_id);
|
||||
if (rc) {
|
||||
pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd);
|
||||
for (i = 0; i < slots_num; i++)
|
||||
kfree(txq->cmd[i]);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -451,7 +464,7 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv)
|
||||
|
||||
/* Tx queues */
|
||||
for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
|
||||
iwl_tx_queue_free(priv, &priv->txq[txq_id]);
|
||||
iwl_tx_queue_free(priv, txq_id);
|
||||
|
||||
/* Keep-warm buffer */
|
||||
iwl_kw_free(priv);
|
||||
@ -859,7 +872,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
|
||||
txq->txb[q->write_ptr].skb[0] = skb;
|
||||
|
||||
/* Set up first empty entry in queue's array of Tx/cmd buffers */
|
||||
out_cmd = &txq->cmd[idx];
|
||||
out_cmd = txq->cmd[idx];
|
||||
tx_cmd = &out_cmd->cmd.tx;
|
||||
memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
|
||||
memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd));
|
||||
@ -899,8 +912,9 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
|
||||
|
||||
/* Physical address of this Tx command's header (not MAC header!),
|
||||
* within command buffer array. */
|
||||
txcmd_phys = txq->dma_addr_cmd + sizeof(struct iwl_cmd) * idx +
|
||||
offsetof(struct iwl_cmd, hdr);
|
||||
txcmd_phys = pci_map_single(priv->pci_dev, out_cmd,
|
||||
sizeof(struct iwl_cmd), PCI_DMA_TODEVICE);
|
||||
txcmd_phys += offsetof(struct iwl_cmd, hdr);
|
||||
|
||||
/* Add buffer containing Tx command and MAC(!) header to TFD's
|
||||
* first entry */
|
||||
@ -962,16 +976,16 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if ((iwl_queue_space(q) < q->high_mark)
|
||||
&& priv->mac80211_registered) {
|
||||
if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) {
|
||||
if (wait_write_ptr) {
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
txq->need_update = 1;
|
||||
iwl_txq_update_write_ptr(priv, txq);
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
} else {
|
||||
ieee80211_stop_queue(priv->hw,
|
||||
skb_get_queue_mapping(skb));
|
||||
}
|
||||
|
||||
ieee80211_stop_queue(priv->hw, skb_get_queue_mapping(skb));
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1004,7 +1018,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
|
||||
u32 idx;
|
||||
u16 fix_size;
|
||||
dma_addr_t phys_addr;
|
||||
int ret;
|
||||
int len, ret;
|
||||
unsigned long flags;
|
||||
|
||||
cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len);
|
||||
@ -1034,7 +1048,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
|
||||
control_flags = (u32 *) tfd;
|
||||
|
||||
idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE);
|
||||
out_cmd = &txq->cmd[idx];
|
||||
out_cmd = txq->cmd[idx];
|
||||
|
||||
out_cmd->hdr.cmd = cmd->id;
|
||||
memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta));
|
||||
@ -1048,9 +1062,11 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
|
||||
INDEX_TO_SEQ(q->write_ptr));
|
||||
if (out_cmd->meta.flags & CMD_SIZE_HUGE)
|
||||
out_cmd->hdr.sequence |= cpu_to_le16(SEQ_HUGE_FRAME);
|
||||
|
||||
phys_addr = txq->dma_addr_cmd + sizeof(txq->cmd[0]) * idx +
|
||||
offsetof(struct iwl_cmd, hdr);
|
||||
len = (idx == TFD_CMD_SLOTS) ?
|
||||
IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd);
|
||||
phys_addr = pci_map_single(priv->pci_dev, out_cmd, len,
|
||||
PCI_DMA_TODEVICE);
|
||||
phys_addr += offsetof(struct iwl_cmd, hdr);
|
||||
iwl_hw_txq_attach_buf_to_tfd(priv, tfd, phys_addr, fix_size);
|
||||
|
||||
IWL_DEBUG_HC("Sending command %s (#%x), seq: 0x%04X, "
|
||||
@ -1115,6 +1131,9 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
|
||||
{
|
||||
struct iwl_tx_queue *txq = &priv->txq[txq_id];
|
||||
struct iwl_queue *q = &txq->q;
|
||||
struct iwl_tfd_frame *bd = &txq->bd[index];
|
||||
dma_addr_t dma_addr;
|
||||
int is_odd, buf_len;
|
||||
int nfreed = 0;
|
||||
|
||||
if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
|
||||
@ -1132,6 +1151,19 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
|
||||
q->write_ptr, q->read_ptr);
|
||||
queue_work(priv->workqueue, &priv->restart);
|
||||
}
|
||||
is_odd = (index/2) & 0x1;
|
||||
if (is_odd) {
|
||||
dma_addr = IWL_GET_BITS(bd->pa[index], tb2_addr_lo16) |
|
||||
(IWL_GET_BITS(bd->pa[index],
|
||||
tb2_addr_hi20) << 16);
|
||||
buf_len = IWL_GET_BITS(bd->pa[index], tb2_len);
|
||||
} else {
|
||||
dma_addr = le32_to_cpu(bd->pa[index].tb1_addr);
|
||||
buf_len = IWL_GET_BITS(bd->pa[index], tb1_len);
|
||||
}
|
||||
|
||||
pci_unmap_single(priv->pci_dev, dma_addr, buf_len,
|
||||
PCI_DMA_TODEVICE);
|
||||
nfreed++;
|
||||
}
|
||||
}
|
||||
@ -1163,7 +1195,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
|
||||
|
||||
cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
|
||||
cmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
|
||||
cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
|
||||
|
||||
/* Input error checking is done when commands are added to queue. */
|
||||
if (cmd->meta.flags & CMD_WANT_SKB) {
|
||||
@ -1391,7 +1423,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv,
|
||||
/* For each frame attempted in aggregation,
|
||||
* update driver's record of tx frame's status. */
|
||||
for (i = 0; i < agg->frame_count ; i++) {
|
||||
ack = bitmap & (1 << i);
|
||||
ack = bitmap & (1ULL << i);
|
||||
successes += !!ack;
|
||||
IWL_DEBUG_TX_REPLY("%s ON i=%d idx=%d raw=%d\n",
|
||||
ack? "ACK":"NACK", i, (agg->start_idx + i) & 0xff,
|
||||
|
@ -275,10 +275,8 @@ static int iwl3945_tx_queue_alloc(struct iwl3945_priv *priv,
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (txq->txb) {
|
||||
kfree(txq->txb);
|
||||
txq->txb = NULL;
|
||||
}
|
||||
kfree(txq->txb);
|
||||
txq->txb = NULL;
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -365,10 +363,8 @@ void iwl3945_tx_queue_free(struct iwl3945_priv *priv, struct iwl3945_tx_queue *t
|
||||
txq->q.n_bd, txq->bd, txq->q.dma_addr);
|
||||
|
||||
/* De-alloc array of per-TFD driver data */
|
||||
if (txq->txb) {
|
||||
kfree(txq->txb);
|
||||
txq->txb = NULL;
|
||||
}
|
||||
kfree(txq->txb);
|
||||
txq->txb = NULL;
|
||||
|
||||
/* 0-fill queue descriptor structure */
|
||||
memset(txq, 0, sizeof(*txq));
|
||||
@ -2703,9 +2699,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb)
|
||||
|
||||
if (!ieee80211_has_morefrags(hdr->frame_control)) {
|
||||
txq->need_update = 1;
|
||||
if (qc) {
|
||||
if (qc)
|
||||
priv->stations[sta_id].tid[tid].seq_number = seq_number;
|
||||
}
|
||||
} else {
|
||||
wait_write_ptr = 1;
|
||||
txq->need_update = 0;
|
||||
@ -3813,7 +3808,7 @@ int iwl3945_calc_db_from_ratio(int sig_ratio)
|
||||
/* 100:1 or higher, divide by 10 and use table,
|
||||
* add 20 dB to make up for divide by 10 */
|
||||
if (sig_ratio >= 100)
|
||||
return (20 + (int)ratio2dB[sig_ratio/10]);
|
||||
return 20 + (int)ratio2dB[sig_ratio/10];
|
||||
|
||||
/* We shouldn't see this */
|
||||
if (sig_ratio < 1)
|
||||
@ -5088,7 +5083,7 @@ static void iwl3945_dealloc_ucode_pci(struct iwl3945_priv *priv)
|
||||
* iwl3945_verify_inst_full - verify runtime uCode image in card vs. host,
|
||||
* looking at all data.
|
||||
*/
|
||||
static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 * image, u32 len)
|
||||
static int iwl3945_verify_inst_full(struct iwl3945_priv *priv, __le32 *image, u32 len)
|
||||
{
|
||||
u32 val;
|
||||
u32 save_len = len;
|
||||
@ -5237,7 +5232,7 @@ static int iwl3945_verify_bsm(struct iwl3945_priv *priv)
|
||||
val = iwl3945_read_prph(priv, BSM_WR_DWCOUNT_REG);
|
||||
for (reg = BSM_SRAM_LOWER_BOUND;
|
||||
reg < BSM_SRAM_LOWER_BOUND + len;
|
||||
reg += sizeof(u32), image ++) {
|
||||
reg += sizeof(u32), image++) {
|
||||
val = iwl3945_read_prph(priv, reg);
|
||||
if (val != le32_to_cpu(*image)) {
|
||||
IWL_ERROR("BSM uCode verification failed at "
|
||||
@ -6336,7 +6331,7 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
|
||||
DECLARE_MAC_BUF(mac);
|
||||
|
||||
if (priv->iw_mode == IEEE80211_IF_TYPE_AP) {
|
||||
IWL_ERROR("%s Should not be called in AP mode\n", __FUNCTION__);
|
||||
IWL_ERROR("%s Should not be called in AP mode\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -6417,7 +6412,7 @@ static void iwl3945_bg_post_associate(struct work_struct *data)
|
||||
|
||||
default:
|
||||
IWL_ERROR("%s Should not be called in %d mode\n",
|
||||
__FUNCTION__, priv->iw_mode);
|
||||
__func__, priv->iw_mode);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -6594,12 +6589,6 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
|
||||
IWL_DEBUG_MAC80211("enter\n");
|
||||
|
||||
if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
|
||||
IWL_DEBUG_MAC80211("leave - monitor\n");
|
||||
dev_kfree_skb_any(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
|
||||
ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
|
||||
|
||||
@ -7456,7 +7445,7 @@ static ssize_t show_measurement(struct device *d,
|
||||
struct iwl3945_priv *priv = dev_get_drvdata(d);
|
||||
struct iwl3945_spectrum_notification measure_report;
|
||||
u32 size = sizeof(measure_report), len = 0, ofs = 0;
|
||||
u8 *data = (u8 *) & measure_report;
|
||||
u8 *data = (u8 *)&measure_report;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
@ -7627,7 +7616,7 @@ static ssize_t show_power_level(struct device *d,
|
||||
else
|
||||
p += sprintf(p, " \n");
|
||||
|
||||
return (p - buf + 1);
|
||||
return p - buf + 1;
|
||||
|
||||
}
|
||||
|
||||
@ -7649,7 +7638,7 @@ static ssize_t show_statistics(struct device *d,
|
||||
struct iwl3945_priv *priv = dev_get_drvdata(d);
|
||||
u32 size = sizeof(struct iwl3945_notif_statistics);
|
||||
u32 len = 0, ofs = 0;
|
||||
u8 *data = (u8 *) & priv->statistics;
|
||||
u8 *data = (u8 *)&priv->statistics;
|
||||
int rc = 0;
|
||||
|
||||
if (!iwl3945_is_alive(priv))
|
||||
@ -8003,16 +7992,16 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
|
||||
|
||||
/* nic init */
|
||||
iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
|
||||
CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
|
||||
CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER);
|
||||
|
||||
iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
|
||||
err = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
if (err < 0) {
|
||||
IWL_DEBUG_INFO("Failed to init the card\n");
|
||||
iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
|
||||
err = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
|
||||
CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
|
||||
if (err < 0) {
|
||||
IWL_DEBUG_INFO("Failed to init the card\n");
|
||||
goto out_remove_sysfs;
|
||||
}
|
||||
}
|
||||
/* Read the EEPROM */
|
||||
err = iwl3945_eeprom_init(priv);
|
||||
if (err) {
|
||||
@ -8114,9 +8103,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
|
||||
iwl3945_unset_hw_setting(priv);
|
||||
iwl3945_clear_stations_table(priv);
|
||||
|
||||
if (priv->mac80211_registered) {
|
||||
if (priv->mac80211_registered)
|
||||
ieee80211_unregister_hw(priv->hw);
|
||||
}
|
||||
|
||||
/*netif_stop_queue(dev); */
|
||||
flush_workqueue(priv->workqueue);
|
||||
|
@ -297,9 +297,7 @@ static ssize_t lbs_rtap_set(struct device *dev,
|
||||
lbs_add_rtap(priv);
|
||||
}
|
||||
priv->monitormode = monitor_mode;
|
||||
}
|
||||
|
||||
else {
|
||||
} else {
|
||||
if (!priv->monitormode)
|
||||
return strlen(buf);
|
||||
priv->monitormode = 0;
|
||||
@ -1242,8 +1240,6 @@ int lbs_start_card(struct lbs_private *priv)
|
||||
lbs_pr_err("cannot register ethX device\n");
|
||||
goto done;
|
||||
}
|
||||
if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
|
||||
lbs_pr_err("cannot register lbs_rtap attribute\n");
|
||||
|
||||
lbs_update_channel(priv);
|
||||
|
||||
@ -1275,6 +1271,13 @@ int lbs_start_card(struct lbs_private *priv)
|
||||
|
||||
if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
|
||||
lbs_pr_err("cannot register lbs_mesh attribute\n");
|
||||
|
||||
/* While rtap isn't related to mesh, only mesh-enabled
|
||||
* firmware implements the rtap functionality via
|
||||
* CMD_802_11_MONITOR_MODE.
|
||||
*/
|
||||
if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
|
||||
lbs_pr_err("cannot register lbs_rtap attribute\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1306,9 +1309,9 @@ void lbs_stop_card(struct lbs_private *priv)
|
||||
netif_carrier_off(priv->dev);
|
||||
|
||||
lbs_debugfs_remove_one(priv);
|
||||
device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
|
||||
if (priv->mesh_tlv) {
|
||||
device_remove_file(&dev->dev, &dev_attr_lbs_mesh);
|
||||
device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
|
||||
}
|
||||
|
||||
/* Flush pending command nodes */
|
||||
|
@ -52,6 +52,7 @@ struct p54_common {
|
||||
int (*open)(struct ieee80211_hw *dev);
|
||||
void (*stop)(struct ieee80211_hw *dev);
|
||||
int mode;
|
||||
struct mutex conf_mutex;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 bssid[ETH_ALEN];
|
||||
struct pda_iq_autocal_entry *iq_autocal;
|
||||
|
@ -886,9 +886,12 @@ static void p54_remove_interface(struct ieee80211_hw *dev,
|
||||
static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
|
||||
{
|
||||
int ret;
|
||||
struct p54_common *priv = dev->priv;
|
||||
|
||||
mutex_lock(&priv->conf_mutex);
|
||||
ret = p54_set_freq(dev, cpu_to_le16(conf->channel->center_freq));
|
||||
p54_set_vdcf(dev);
|
||||
mutex_unlock(&priv->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -898,10 +901,12 @@ static int p54_config_interface(struct ieee80211_hw *dev,
|
||||
{
|
||||
struct p54_common *priv = dev->priv;
|
||||
|
||||
mutex_lock(&priv->conf_mutex);
|
||||
p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 0, 1, 0, 0xF642);
|
||||
p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 2, 0, 0, 0);
|
||||
p54_set_leds(dev, 1, !is_multicast_ether_addr(conf->bssid), 0);
|
||||
memcpy(priv->bssid, conf->bssid, ETH_ALEN);
|
||||
mutex_unlock(&priv->conf_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1009,6 +1014,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
|
||||
}
|
||||
|
||||
p54_init_vdcf(dev);
|
||||
mutex_init(&priv->conf_mutex);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
@ -2518,7 +2518,7 @@ enum {
|
||||
|
||||
#define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
|
||||
#define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
|
||||
((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data))
|
||||
offsetof(struct prism2_hostapd_param, u.generic_elem.data)
|
||||
|
||||
/* Maximum length for algorithm names (-1 for nul termination)
|
||||
* used in ioctl() */
|
||||
|
@ -1220,6 +1220,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
|
||||
rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs);
|
||||
rt2x00_set_field32(&word, TXD_W0_RETRY_MODE,
|
||||
test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags));
|
||||
rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len);
|
||||
rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE);
|
||||
rt2x00_desc_write(txd, 0, word);
|
||||
}
|
||||
|
@ -633,6 +633,16 @@ static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
|
||||
rt2x00dev->link.vgc_level = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: This function is directly ported from legacy driver, but
|
||||
* despite it being declared it was never called. Although link tuning
|
||||
* sounds like a good idea, and usually works well for the other drivers,
|
||||
* it does _not_ work with rt2500usb. Enabling this function will result
|
||||
* in TX capabilities only until association kicks in. Immediately
|
||||
* after the successful association all TX frames will be kept in the
|
||||
* hardware queue and never transmitted.
|
||||
*/
|
||||
#if 0
|
||||
static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
|
||||
@ -752,6 +762,9 @@ static void rt2500usb_link_tuner(struct rt2x00_dev *rt2x00dev)
|
||||
rt2x00dev->link.vgc_level = r17;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define rt2500usb_link_tuner NULL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialization functions.
|
||||
@ -1376,6 +1389,9 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word);
|
||||
EEPROM(rt2x00dev, "BBPtune vgc: 0x%04x\n", word);
|
||||
} else {
|
||||
rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word);
|
||||
}
|
||||
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R17, &word);
|
||||
@ -1384,9 +1400,6 @@ static int rt2500usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
rt2x00_set_field16(&word, EEPROM_BBPTUNE_R17_HIGH, 0x41);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_R17, word);
|
||||
EEPROM(rt2x00dev, "BBPtune r17: 0x%04x\n", word);
|
||||
} else {
|
||||
rt2x00_set_field16(&word, EEPROM_BBPTUNE_VGCLOWER, bbp);
|
||||
rt2x00_eeprom_write(rt2x00dev, EEPROM_BBPTUNE_VGC, word);
|
||||
}
|
||||
|
||||
rt2x00_eeprom_read(rt2x00dev, EEPROM_BBPTUNE_R24, &word);
|
||||
@ -1737,6 +1750,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
__set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
|
||||
__set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags);
|
||||
__set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
|
||||
__set_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags);
|
||||
|
||||
/*
|
||||
* Set the rssi offset.
|
||||
|
@ -368,6 +368,12 @@ struct rt2x00_intf {
|
||||
#define DELAYED_CONFIG_ERP 0x00000002
|
||||
#define DELAYED_LED_ASSOC 0x00000004
|
||||
|
||||
/*
|
||||
* Software sequence counter, this is only required
|
||||
* for hardware which doesn't support hardware
|
||||
* sequence counting.
|
||||
*/
|
||||
spinlock_t seqlock;
|
||||
u16 seqno;
|
||||
};
|
||||
|
||||
|
@ -254,6 +254,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
|
||||
libconf.ant.rx = default_ant->rx;
|
||||
else if (active_ant->rx == ANTENNA_SW_DIVERSITY)
|
||||
libconf.ant.rx = ANTENNA_B;
|
||||
else
|
||||
libconf.ant.rx = active_ant->rx;
|
||||
|
||||
if (conf->antenna_sel_tx)
|
||||
libconf.ant.tx = conf->antenna_sel_tx;
|
||||
@ -261,6 +263,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
|
||||
libconf.ant.tx = default_ant->tx;
|
||||
else if (active_ant->tx == ANTENNA_SW_DIVERSITY)
|
||||
libconf.ant.tx = ANTENNA_B;
|
||||
else
|
||||
libconf.ant.tx = active_ant->tx;
|
||||
}
|
||||
|
||||
if (flags & CONFIG_UPDATE_SLOT_TIME) {
|
||||
|
@ -372,9 +372,6 @@ static ssize_t rt2x00debug_write_##__name(struct file *file, \
|
||||
if (*offset) \
|
||||
return 0; \
|
||||
\
|
||||
if (!capable(CAP_NET_ADMIN)) \
|
||||
return -EPERM; \
|
||||
\
|
||||
if (intf->offset_##__name >= debug->__name.word_count) \
|
||||
return -EINVAL; \
|
||||
\
|
||||
@ -454,7 +451,7 @@ static struct dentry *rt2x00debug_create_file_driver(const char *name,
|
||||
data += sprintf(data, "compiled: %s %s\n", __DATE__, __TIME__);
|
||||
blob->size = strlen(blob->data);
|
||||
|
||||
return debugfs_create_blob(name, S_IRUGO, intf->driver_folder, blob);
|
||||
return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
|
||||
}
|
||||
|
||||
static struct dentry *rt2x00debug_create_file_chipset(const char *name,
|
||||
@ -482,7 +479,7 @@ static struct dentry *rt2x00debug_create_file_chipset(const char *name,
|
||||
data += sprintf(data, "rf length: %d\n", debug->rf.word_count);
|
||||
blob->size = strlen(blob->data);
|
||||
|
||||
return debugfs_create_blob(name, S_IRUGO, intf->driver_folder, blob);
|
||||
return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
|
||||
}
|
||||
|
||||
void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
|
||||
@ -517,7 +514,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
|
||||
if (IS_ERR(intf->chipset_entry))
|
||||
goto exit;
|
||||
|
||||
intf->dev_flags = debugfs_create_file("dev_flags", S_IRUGO,
|
||||
intf->dev_flags = debugfs_create_file("dev_flags", S_IRUSR,
|
||||
intf->driver_folder, intf,
|
||||
&rt2x00debug_fop_dev_flags);
|
||||
if (IS_ERR(intf->dev_flags))
|
||||
@ -532,7 +529,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
|
||||
({ \
|
||||
(__intf)->__name##_off_entry = \
|
||||
debugfs_create_u32(__stringify(__name) "_offset", \
|
||||
S_IRUGO | S_IWUSR, \
|
||||
S_IRUSR | S_IWUSR, \
|
||||
(__intf)->register_folder, \
|
||||
&(__intf)->offset_##__name); \
|
||||
if (IS_ERR((__intf)->__name##_off_entry)) \
|
||||
@ -540,7 +537,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
|
||||
\
|
||||
(__intf)->__name##_val_entry = \
|
||||
debugfs_create_file(__stringify(__name) "_value", \
|
||||
S_IRUGO | S_IWUSR, \
|
||||
S_IRUSR | S_IWUSR, \
|
||||
(__intf)->register_folder, \
|
||||
(__intf), &rt2x00debug_fop_##__name);\
|
||||
if (IS_ERR((__intf)->__name##_val_entry)) \
|
||||
@ -560,7 +557,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
|
||||
goto exit;
|
||||
|
||||
intf->queue_frame_dump_entry =
|
||||
debugfs_create_file("dump", S_IRUGO, intf->queue_folder,
|
||||
debugfs_create_file("dump", S_IRUSR, intf->queue_folder,
|
||||
intf, &rt2x00debug_fop_queue_dump);
|
||||
if (IS_ERR(intf->queue_frame_dump_entry))
|
||||
goto exit;
|
||||
@ -569,7 +566,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
|
||||
init_waitqueue_head(&intf->frame_dump_waitqueue);
|
||||
|
||||
intf->queue_stats_entry =
|
||||
debugfs_create_file("queue", S_IRUGO, intf->queue_folder,
|
||||
debugfs_create_file("queue", S_IRUSR, intf->queue_folder,
|
||||
intf, &rt2x00debug_fop_queue_stats);
|
||||
|
||||
return;
|
||||
|
@ -247,6 +247,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
|
||||
rt2x00dev->intf_sta_count++;
|
||||
|
||||
spin_lock_init(&intf->lock);
|
||||
spin_lock_init(&intf->seqlock);
|
||||
intf->beacon = entry;
|
||||
|
||||
if (conf->type == IEEE80211_IF_TYPE_AP)
|
||||
|
@ -128,6 +128,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
|
||||
unsigned int data_length;
|
||||
unsigned int duration;
|
||||
unsigned int residual;
|
||||
unsigned long irqflags;
|
||||
|
||||
memset(txdesc, 0, sizeof(*txdesc));
|
||||
|
||||
@ -213,14 +214,14 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
|
||||
* sequence counter given by mac80211.
|
||||
*/
|
||||
if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
|
||||
spin_lock(&intf->lock);
|
||||
spin_lock_irqsave(&intf->seqlock, irqflags);
|
||||
|
||||
if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
|
||||
intf->seqno += 0x10;
|
||||
hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
|
||||
hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
|
||||
|
||||
spin_unlock(&intf->lock);
|
||||
spin_unlock_irqrestore(&intf->seqlock, irqflags);
|
||||
|
||||
__set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff);
|
||||
|
||||
int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
|
||||
const u8 request, const u8 requesttype,
|
||||
const u16 offset, void *buffer,
|
||||
const u16 offset, const void *buffer,
|
||||
const u16 buffer_length,
|
||||
const int timeout)
|
||||
{
|
||||
@ -134,7 +134,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
|
||||
|
||||
mutex_lock(&rt2x00dev->usb_cache_mutex);
|
||||
|
||||
tb = buffer;
|
||||
tb = (char *)buffer;
|
||||
off = offset;
|
||||
len = buffer_length;
|
||||
while (len && !status) {
|
||||
|
@ -185,7 +185,7 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev,
|
||||
*/
|
||||
int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,
|
||||
const u8 request, const u8 requesttype,
|
||||
const u16 offset, void *buffer,
|
||||
const u16 offset, const void *buffer,
|
||||
const u16 buffer_length,
|
||||
const int timeout);
|
||||
|
||||
|
@ -1003,6 +1003,11 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data,
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hardware needs another millisecond before it is ready.
|
||||
*/
|
||||
msleep(1);
|
||||
|
||||
/*
|
||||
* Reset MAC and BBP registers.
|
||||
*/
|
||||
|
@ -94,6 +94,10 @@ struct rtl8187_priv {
|
||||
const struct rtl818x_rf_ops *rf;
|
||||
struct ieee80211_vif *vif;
|
||||
int mode;
|
||||
/* The mutex protects the TX loopback state.
|
||||
* Any attempt to set channels concurrently locks the device.
|
||||
*/
|
||||
struct mutex conf_mutex;
|
||||
|
||||
/* rtl8187 specific */
|
||||
struct ieee80211_channel channels[14];
|
||||
|
@ -31,6 +31,8 @@ MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static struct usb_device_id rtl8187_table[] __devinitdata = {
|
||||
/* Asus */
|
||||
{USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187},
|
||||
/* Realtek */
|
||||
{USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187},
|
||||
{USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B},
|
||||
@ -726,6 +728,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&priv->conf_mutex);
|
||||
if (priv->is_rtl8187b) {
|
||||
reg = RTL818X_RX_CONF_MGMT |
|
||||
RTL818X_RX_CONF_DATA |
|
||||
@ -747,6 +750,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
|
||||
(7 << 0 /* long retry limit */) |
|
||||
(7 << 21 /* MAX TX DMA */));
|
||||
rtl8187_init_urbs(dev);
|
||||
mutex_unlock(&priv->conf_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -790,6 +794,7 @@ static int rtl8187_start(struct ieee80211_hw *dev)
|
||||
reg |= RTL818X_CMD_TX_ENABLE;
|
||||
reg |= RTL818X_CMD_RX_ENABLE;
|
||||
rtl818x_iowrite8(priv, &priv->map->CMD, reg);
|
||||
mutex_unlock(&priv->conf_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -801,6 +806,7 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
|
||||
struct sk_buff *skb;
|
||||
u32 reg;
|
||||
|
||||
mutex_lock(&priv->conf_mutex);
|
||||
rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
|
||||
|
||||
reg = rtl818x_ioread8(priv, &priv->map->CMD);
|
||||
@ -820,7 +826,7 @@ static void rtl8187_stop(struct ieee80211_hw *dev)
|
||||
usb_kill_urb(info->urb);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
return;
|
||||
mutex_unlock(&priv->conf_mutex);
|
||||
}
|
||||
|
||||
static int rtl8187_add_interface(struct ieee80211_hw *dev,
|
||||
@ -840,6 +846,7 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
mutex_lock(&priv->conf_mutex);
|
||||
priv->vif = conf->vif;
|
||||
|
||||
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
|
||||
@ -848,6 +855,7 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
|
||||
((u8 *)conf->mac_addr)[i]);
|
||||
rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
|
||||
|
||||
mutex_unlock(&priv->conf_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -855,8 +863,10 @@ static void rtl8187_remove_interface(struct ieee80211_hw *dev,
|
||||
struct ieee80211_if_init_conf *conf)
|
||||
{
|
||||
struct rtl8187_priv *priv = dev->priv;
|
||||
mutex_lock(&priv->conf_mutex);
|
||||
priv->mode = IEEE80211_IF_TYPE_MNTR;
|
||||
priv->vif = NULL;
|
||||
mutex_unlock(&priv->conf_mutex);
|
||||
}
|
||||
|
||||
static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
|
||||
@ -864,6 +874,7 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
|
||||
struct rtl8187_priv *priv = dev->priv;
|
||||
u32 reg;
|
||||
|
||||
mutex_lock(&priv->conf_mutex);
|
||||
reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
|
||||
/* Enable TX loopback on MAC level to avoid TX during channel
|
||||
* changes, as this has be seen to causes problems and the
|
||||
@ -896,6 +907,7 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
|
||||
rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100);
|
||||
rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
|
||||
rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100);
|
||||
mutex_unlock(&priv->conf_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -907,6 +919,7 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev,
|
||||
int i;
|
||||
u8 reg;
|
||||
|
||||
mutex_lock(&priv->conf_mutex);
|
||||
for (i = 0; i < ETH_ALEN; i++)
|
||||
rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
|
||||
|
||||
@ -920,6 +933,7 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev,
|
||||
rtl818x_iowrite8(priv, &priv->map->MSR, reg);
|
||||
}
|
||||
|
||||
mutex_unlock(&priv->conf_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1187,6 +1201,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
|
||||
printk(KERN_ERR "rtl8187: Cannot register device\n");
|
||||
goto err_free_dev;
|
||||
}
|
||||
mutex_init(&priv->conf_mutex);
|
||||
|
||||
printk(KERN_INFO "%s: hwaddr %s, %s V%d + %s\n",
|
||||
wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
|
||||
|
@ -506,6 +506,19 @@ struct ieee80211_channel_sw_ie {
|
||||
u8 count;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/**
|
||||
* struct ieee80211_tim
|
||||
*
|
||||
* This structure refers to "Traffic Indication Map information element"
|
||||
*/
|
||||
struct ieee80211_tim_ie {
|
||||
u8 dtim_count;
|
||||
u8 dtim_period;
|
||||
u8 bitmap_ctrl;
|
||||
/* variable size: 1 - 251 bytes */
|
||||
u8 virtual_map[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct ieee80211_mgmt {
|
||||
__le16 frame_control;
|
||||
__le16 duration;
|
||||
|
@ -61,9 +61,7 @@ struct wireless_dev;
|
||||
#define NET_XMIT_DROP 1 /* skb dropped */
|
||||
#define NET_XMIT_CN 2 /* congestion notification */
|
||||
#define NET_XMIT_POLICED 3 /* skb is shot by police */
|
||||
#define NET_XMIT_BYPASS 4 /* packet does not leave via dequeue;
|
||||
(TC use only - dev_queue_xmit
|
||||
returns this as NET_XMIT_SUCCESS) */
|
||||
#define NET_XMIT_MASK 0xFFFF /* qdisc flags in net/sch_generic.h */
|
||||
|
||||
/* Backlog congestion levels */
|
||||
#define NET_RX_SUCCESS 0 /* keep 'em coming, baby */
|
||||
|
@ -252,17 +252,7 @@ static inline int dst_output(struct sk_buff *skb)
|
||||
/* Input packet from network to transport. */
|
||||
static inline int dst_input(struct sk_buff *skb)
|
||||
{
|
||||
int err;
|
||||
|
||||
for (;;) {
|
||||
err = skb->dst->input(skb);
|
||||
|
||||
if (likely(err == 0))
|
||||
return err;
|
||||
/* Oh, Jamal... Seems, I will not forgive you this mess. :-) */
|
||||
if (unlikely(err != NET_XMIT_BYPASS))
|
||||
return err;
|
||||
}
|
||||
return skb->dst->input(skb);
|
||||
}
|
||||
|
||||
static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie)
|
||||
|
@ -47,7 +47,6 @@ struct flowi {
|
||||
#define fl4_scope nl_u.ip4_u.scope
|
||||
|
||||
__u8 proto;
|
||||
__u8 flags;
|
||||
union {
|
||||
struct {
|
||||
__be16 sport;
|
||||
|
@ -177,9 +177,10 @@ enum ieee80211_bss_change {
|
||||
* @aid: association ID number, valid only when @assoc is true
|
||||
* @use_cts_prot: use CTS protection
|
||||
* @use_short_preamble: use 802.11b short preamble
|
||||
* @dtim_period: num of beacons before the next DTIM, for PSM
|
||||
* @timestamp: beacon timestamp
|
||||
* @beacon_int: beacon interval
|
||||
* @assoc_capability: capabbilities taken from assoc resp
|
||||
* @assoc_capability: capabilities taken from assoc resp
|
||||
* @assoc_ht: association in HT mode
|
||||
* @ht_conf: ht capabilities
|
||||
* @ht_bss_conf: ht extended capabilities
|
||||
@ -191,6 +192,7 @@ struct ieee80211_bss_conf {
|
||||
/* erp related data */
|
||||
bool use_cts_prot;
|
||||
bool use_short_preamble;
|
||||
u8 dtim_period;
|
||||
u16 beacon_int;
|
||||
u16 assoc_capability;
|
||||
u64 timestamp;
|
||||
@ -430,6 +432,7 @@ enum ieee80211_conf_flags {
|
||||
* @radio_enabled: when zero, driver is required to switch off the radio.
|
||||
* TODO make a flag
|
||||
* @beacon_int: beacon interval (TODO make interface config)
|
||||
* @listen_interval: listen interval in units of beacon interval
|
||||
* @flags: configuration flags defined above
|
||||
* @power_level: requested transmit power (in dBm)
|
||||
* @max_antenna_gain: maximum antenna gain (in dBi)
|
||||
@ -444,6 +447,7 @@ struct ieee80211_conf {
|
||||
int radio_enabled;
|
||||
|
||||
int beacon_int;
|
||||
u16 listen_interval;
|
||||
u32 flags;
|
||||
int power_level;
|
||||
int max_antenna_gain;
|
||||
@ -785,6 +789,9 @@ enum ieee80211_hw_flags {
|
||||
* @max_signal: Maximum value for signal (rssi) in RX information, used
|
||||
* only when @IEEE80211_HW_SIGNAL_UNSPEC or @IEEE80211_HW_SIGNAL_DB
|
||||
*
|
||||
* @max_listen_interval: max listen interval in units of beacon interval
|
||||
* that HW supports
|
||||
*
|
||||
* @queues: number of available hardware transmit queues for
|
||||
* data packets. WMM/QoS requires at least four, these
|
||||
* queues need to have configurable access parameters.
|
||||
@ -812,7 +819,9 @@ struct ieee80211_hw {
|
||||
unsigned int extra_tx_headroom;
|
||||
int channel_change_time;
|
||||
int vif_data_size;
|
||||
u16 queues, ampdu_queues;
|
||||
u16 queues;
|
||||
u16 ampdu_queues;
|
||||
u16 max_listen_interval;
|
||||
s8 max_signal;
|
||||
};
|
||||
|
||||
|
@ -193,10 +193,22 @@ static inline struct Qdisc *qdisc_root(struct Qdisc *qdisc)
|
||||
return qdisc->dev_queue->qdisc;
|
||||
}
|
||||
|
||||
/* The qdisc root lock is a mechanism by which to top level
|
||||
* of a qdisc tree can be locked from any qdisc node in the
|
||||
* forest. This allows changing the configuration of some
|
||||
* aspect of the qdisc tree while blocking out asynchronous
|
||||
* qdisc access in the packet processing paths.
|
||||
*
|
||||
* It is only legal to do this when the root will not change
|
||||
* on us. Otherwise we'll potentially lock the wrong qdisc
|
||||
* root. This is enforced by holding the RTNL semaphore, which
|
||||
* all users of this lock accessor must do.
|
||||
*/
|
||||
static inline spinlock_t *qdisc_root_lock(struct Qdisc *qdisc)
|
||||
{
|
||||
struct Qdisc *root = qdisc_root(qdisc);
|
||||
|
||||
ASSERT_RTNL();
|
||||
return qdisc_lock(root);
|
||||
}
|
||||
|
||||
@ -331,6 +343,18 @@ static inline unsigned int qdisc_pkt_len(struct sk_buff *skb)
|
||||
return qdisc_skb_cb(skb)->pkt_len;
|
||||
}
|
||||
|
||||
/* additional qdisc xmit flags (NET_XMIT_MASK in linux/netdevice.h) */
|
||||
enum net_xmit_qdisc_t {
|
||||
__NET_XMIT_STOLEN = 0x00010000,
|
||||
__NET_XMIT_BYPASS = 0x00020000,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
#define net_xmit_drop_count(e) ((e) & __NET_XMIT_STOLEN ? 0 : 1)
|
||||
#else
|
||||
#define net_xmit_drop_count(e) (1)
|
||||
#endif
|
||||
|
||||
static inline int qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
{
|
||||
#ifdef CONFIG_NET_SCHED
|
||||
@ -343,7 +367,7 @@ static inline int qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
static inline int qdisc_enqueue_root(struct sk_buff *skb, struct Qdisc *sch)
|
||||
{
|
||||
qdisc_skb_cb(skb)->pkt_len = skb->len;
|
||||
return qdisc_enqueue(skb, sch);
|
||||
return qdisc_enqueue(skb, sch) & NET_XMIT_MASK;
|
||||
}
|
||||
|
||||
static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch,
|
||||
|
@ -524,8 +524,7 @@ static inline void sctp_ssn_skip(struct sctp_stream *stream, __u16 id,
|
||||
*/
|
||||
struct sctp_af {
|
||||
int (*sctp_xmit) (struct sk_buff *skb,
|
||||
struct sctp_transport *,
|
||||
int ipfragok);
|
||||
struct sctp_transport *);
|
||||
int (*setsockopt) (struct sock *sk,
|
||||
int level,
|
||||
int optname,
|
||||
|
@ -36,6 +36,7 @@ static struct ctl_path ax25_path[] = {
|
||||
{ .procname = "ax25", .ctl_name = NET_AX25, },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const ctl_table ax25_param_table[] = {
|
||||
{
|
||||
.ctl_name = NET_AX25_IP_DEFAULT_MODE,
|
||||
@ -167,6 +168,7 @@ static const ctl_table ax25_param_table[] = {
|
||||
.extra1 = &min_proto,
|
||||
.extra2 = &max_proto
|
||||
},
|
||||
#ifdef CONFIG_AX25_DAMA_SLAVE
|
||||
{
|
||||
.ctl_name = NET_AX25_DAMA_SLAVE_TIMEOUT,
|
||||
.procname = "dama_slave_timeout",
|
||||
@ -177,6 +179,8 @@ static const ctl_table ax25_param_table[] = {
|
||||
.extra1 = &min_ds_timeout,
|
||||
.extra2 = &max_ds_timeout
|
||||
},
|
||||
#endif
|
||||
|
||||
{ .ctl_name = 0 } /* that's all, folks! */
|
||||
};
|
||||
|
||||
@ -210,16 +214,6 @@ void ax25_register_sysctl(void)
|
||||
ax25_table[n].procname = ax25_dev->dev->name;
|
||||
ax25_table[n].mode = 0555;
|
||||
|
||||
#ifndef CONFIG_AX25_DAMA_SLAVE
|
||||
/*
|
||||
* We do not wish to have a representation of this parameter
|
||||
* in /proc/sys/ when configured *not* to include the
|
||||
* AX.25 DAMA slave code, do we?
|
||||
*/
|
||||
|
||||
child[AX25_VALUES_DS_TIMEOUT].procname = NULL;
|
||||
#endif
|
||||
|
||||
child[AX25_MAX_VALUES].ctl_name = 0; /* just in case... */
|
||||
|
||||
for (k = 0; k < AX25_MAX_VALUES; k++)
|
||||
|
@ -113,7 +113,7 @@ void br_netfilter_rtable_init(struct net_bridge *br)
|
||||
struct rtable *rt = &br->fake_rtable;
|
||||
|
||||
atomic_set(&rt->u.dst.__refcnt, 1);
|
||||
rt->u.dst.dev = &br->dev;
|
||||
rt->u.dst.dev = br->dev;
|
||||
rt->u.dst.path = &rt->u.dst;
|
||||
rt->u.dst.metrics[RTAX_MTU - 1] = 1500;
|
||||
rt->u.dst.flags = DST_NOXFRM;
|
||||
|
@ -368,14 +368,25 @@ static void br_make_blocking(struct net_bridge_port *p)
|
||||
/* called under bridge lock */
|
||||
static void br_make_forwarding(struct net_bridge_port *p)
|
||||
{
|
||||
if (p->state == BR_STATE_BLOCKING) {
|
||||
if (p->br->stp_enabled == BR_KERNEL_STP)
|
||||
p->state = BR_STATE_LISTENING;
|
||||
else
|
||||
p->state = BR_STATE_LEARNING;
|
||||
struct net_bridge *br = p->br;
|
||||
|
||||
br_log_state(p);
|
||||
mod_timer(&p->forward_delay_timer, jiffies + p->br->forward_delay); }
|
||||
if (p->state != BR_STATE_BLOCKING)
|
||||
return;
|
||||
|
||||
if (br->forward_delay == 0) {
|
||||
p->state = BR_STATE_FORWARDING;
|
||||
br_topology_change_detection(br);
|
||||
del_timer(&p->forward_delay_timer);
|
||||
}
|
||||
else if (p->br->stp_enabled == BR_KERNEL_STP)
|
||||
p->state = BR_STATE_LISTENING;
|
||||
else
|
||||
p->state = BR_STATE_LEARNING;
|
||||
|
||||
br_log_state(p);
|
||||
|
||||
if (br->forward_delay != 0)
|
||||
mod_timer(&p->forward_delay_timer, jiffies + br->forward_delay);
|
||||
}
|
||||
|
||||
/* called under bridge lock */
|
||||
|
@ -1796,7 +1796,7 @@ int dev_queue_xmit(struct sk_buff *skb)
|
||||
skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS);
|
||||
#endif
|
||||
if (q->enqueue) {
|
||||
spinlock_t *root_lock = qdisc_root_lock(q);
|
||||
spinlock_t *root_lock = qdisc_lock(q);
|
||||
|
||||
spin_lock(root_lock);
|
||||
|
||||
@ -1805,7 +1805,6 @@ int dev_queue_xmit(struct sk_buff *skb)
|
||||
|
||||
spin_unlock(root_lock);
|
||||
|
||||
rc = rc == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : rc;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -1909,7 +1908,6 @@ int netif_rx(struct sk_buff *skb)
|
||||
if (queue->input_pkt_queue.qlen <= netdev_max_backlog) {
|
||||
if (queue->input_pkt_queue.qlen) {
|
||||
enqueue:
|
||||
dev_hold(skb->dev);
|
||||
__skb_queue_tail(&queue->input_pkt_queue, skb);
|
||||
local_irq_restore(flags);
|
||||
return NET_RX_SUCCESS;
|
||||
@ -1995,7 +1993,7 @@ static void net_tx_action(struct softirq_action *h)
|
||||
smp_mb__before_clear_bit();
|
||||
clear_bit(__QDISC_STATE_SCHED, &q->state);
|
||||
|
||||
root_lock = qdisc_root_lock(q);
|
||||
root_lock = qdisc_lock(q);
|
||||
if (spin_trylock(root_lock)) {
|
||||
qdisc_run(q);
|
||||
spin_unlock(root_lock);
|
||||
@ -2270,6 +2268,20 @@ int netif_receive_skb(struct sk_buff *skb)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Network device is going away, flush any packets still pending */
|
||||
static void flush_backlog(void *arg)
|
||||
{
|
||||
struct net_device *dev = arg;
|
||||
struct softnet_data *queue = &__get_cpu_var(softnet_data);
|
||||
struct sk_buff *skb, *tmp;
|
||||
|
||||
skb_queue_walk_safe(&queue->input_pkt_queue, skb, tmp)
|
||||
if (skb->dev == dev) {
|
||||
__skb_unlink(skb, &queue->input_pkt_queue);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
|
||||
static int process_backlog(struct napi_struct *napi, int quota)
|
||||
{
|
||||
int work = 0;
|
||||
@ -2279,7 +2291,6 @@ static int process_backlog(struct napi_struct *napi, int quota)
|
||||
napi->weight = weight_p;
|
||||
do {
|
||||
struct sk_buff *skb;
|
||||
struct net_device *dev;
|
||||
|
||||
local_irq_disable();
|
||||
skb = __skb_dequeue(&queue->input_pkt_queue);
|
||||
@ -2288,14 +2299,9 @@ static int process_backlog(struct napi_struct *napi, int quota)
|
||||
local_irq_enable();
|
||||
break;
|
||||
}
|
||||
|
||||
local_irq_enable();
|
||||
|
||||
dev = skb->dev;
|
||||
|
||||
netif_receive_skb(skb);
|
||||
|
||||
dev_put(dev);
|
||||
} while (++work < quota && jiffies == start_time);
|
||||
|
||||
return work;
|
||||
@ -3988,6 +3994,10 @@ int register_netdevice(struct net_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable software GSO if SG is supported. */
|
||||
if (dev->features & NETIF_F_SG)
|
||||
dev->features |= NETIF_F_GSO;
|
||||
|
||||
netdev_initialize_kobject(dev);
|
||||
ret = netdev_register_kobject(dev);
|
||||
if (ret)
|
||||
@ -4165,6 +4175,8 @@ void netdev_run_todo(void)
|
||||
|
||||
dev->reg_state = NETREG_UNREGISTERED;
|
||||
|
||||
on_each_cpu(flush_backlog, dev, 1);
|
||||
|
||||
netdev_wait_allrefs(dev);
|
||||
|
||||
/* paranoia */
|
||||
|
@ -2281,6 +2281,7 @@ static struct neighbour *neigh_get_idx(struct seq_file *seq, loff_t *pos)
|
||||
struct neighbour *n = neigh_get_first(seq);
|
||||
|
||||
if (n) {
|
||||
--(*pos);
|
||||
while (*pos) {
|
||||
n = neigh_get_next(seq, n, pos);
|
||||
if (!n)
|
||||
@ -2341,6 +2342,7 @@ static struct pneigh_entry *pneigh_get_idx(struct seq_file *seq, loff_t *pos)
|
||||
struct pneigh_entry *pn = pneigh_get_first(seq);
|
||||
|
||||
if (pn) {
|
||||
--(*pos);
|
||||
while (*pos) {
|
||||
pn = pneigh_get_next(seq, pn, pos);
|
||||
if (!pn)
|
||||
@ -2354,10 +2356,11 @@ static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos)
|
||||
{
|
||||
struct neigh_seq_state *state = seq->private;
|
||||
void *rc;
|
||||
loff_t idxpos = *pos;
|
||||
|
||||
rc = neigh_get_idx(seq, pos);
|
||||
rc = neigh_get_idx(seq, &idxpos);
|
||||
if (!rc && !(state->flags & NEIGH_SEQ_NEIGH_ONLY))
|
||||
rc = pneigh_get_idx(seq, pos);
|
||||
rc = pneigh_get_idx(seq, &idxpos);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -2366,7 +2369,6 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl
|
||||
__acquires(tbl->lock)
|
||||
{
|
||||
struct neigh_seq_state *state = seq->private;
|
||||
loff_t pos_minus_one;
|
||||
|
||||
state->tbl = tbl;
|
||||
state->bucket = 0;
|
||||
@ -2374,8 +2376,7 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl
|
||||
|
||||
read_lock_bh(&tbl->lock);
|
||||
|
||||
pos_minus_one = *pos - 1;
|
||||
return *pos ? neigh_get_idx_any(seq, &pos_minus_one) : SEQ_START_TOKEN;
|
||||
return *pos ? neigh_get_idx_any(seq, pos) : SEQ_START_TOKEN;
|
||||
}
|
||||
EXPORT_SYMBOL(neigh_seq_start);
|
||||
|
||||
@ -2385,7 +2386,7 @@ void *neigh_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
void *rc;
|
||||
|
||||
if (v == SEQ_START_TOKEN) {
|
||||
rc = neigh_get_idx(seq, pos);
|
||||
rc = neigh_get_first(seq);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -2085,15 +2085,19 @@ static inline int f_pick(struct pktgen_dev *pkt_dev)
|
||||
if (pkt_dev->flows[flow].count >= pkt_dev->lflow) {
|
||||
/* reset time */
|
||||
pkt_dev->flows[flow].count = 0;
|
||||
pkt_dev->flows[flow].flags = 0;
|
||||
pkt_dev->curfl += 1;
|
||||
if (pkt_dev->curfl >= pkt_dev->cflows)
|
||||
pkt_dev->curfl = 0; /*reset */
|
||||
}
|
||||
} else {
|
||||
flow = random32() % pkt_dev->cflows;
|
||||
pkt_dev->curfl = flow;
|
||||
|
||||
if (pkt_dev->flows[flow].count > pkt_dev->lflow)
|
||||
if (pkt_dev->flows[flow].count > pkt_dev->lflow) {
|
||||
pkt_dev->flows[flow].count = 0;
|
||||
pkt_dev->flows[flow].flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return pkt_dev->curfl;
|
||||
@ -2162,7 +2166,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
|
||||
mc = random32() % pkt_dev->src_mac_count;
|
||||
else {
|
||||
mc = pkt_dev->cur_src_mac_offset++;
|
||||
if (pkt_dev->cur_src_mac_offset >
|
||||
if (pkt_dev->cur_src_mac_offset >=
|
||||
pkt_dev->src_mac_count)
|
||||
pkt_dev->cur_src_mac_offset = 0;
|
||||
}
|
||||
@ -2189,7 +2193,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
|
||||
|
||||
else {
|
||||
mc = pkt_dev->cur_dst_mac_offset++;
|
||||
if (pkt_dev->cur_dst_mac_offset >
|
||||
if (pkt_dev->cur_dst_mac_offset >=
|
||||
pkt_dev->dst_mac_count) {
|
||||
pkt_dev->cur_dst_mac_offset = 0;
|
||||
}
|
||||
|
@ -232,6 +232,7 @@ static struct ctl_table ipv4_table[] = {
|
||||
.mode = 0644,
|
||||
.proc_handler = &ipv4_doint_and_flush,
|
||||
.strategy = &ipv4_doint_and_flush_strategy,
|
||||
.extra2 = &init_net,
|
||||
},
|
||||
{
|
||||
.ctl_name = NET_IPV4_NO_PMTU_DISC,
|
||||
|
@ -269,7 +269,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
|
||||
skb->mark = sk->sk_mark;
|
||||
|
||||
mtu = dst_mtu(dst);
|
||||
if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) {
|
||||
if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) {
|
||||
IP6_INC_STATS(ip6_dst_idev(skb->dst),
|
||||
IPSTATS_MIB_OUTREQUESTS);
|
||||
return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
|
||||
|
@ -346,6 +346,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||
*/
|
||||
if (optlen == 0)
|
||||
optval = NULL;
|
||||
else if (optval == NULL)
|
||||
goto e_inval;
|
||||
else if (optlen < sizeof(struct ipv6_opt_hdr) ||
|
||||
optlen & 0x7 || optlen > 8 * 255)
|
||||
goto e_inval;
|
||||
|
@ -199,10 +199,8 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
|
||||
ireq6 = inet6_rsk(req);
|
||||
treq = tcp_rsk(req);
|
||||
|
||||
if (security_inet_conn_request(sk, skb, req)) {
|
||||
reqsk_free(req);
|
||||
goto out;
|
||||
}
|
||||
if (security_inet_conn_request(sk, skb, req))
|
||||
goto out_free;
|
||||
|
||||
req->mss = mss;
|
||||
ireq->rmt_port = th->source;
|
||||
@ -255,14 +253,13 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
|
||||
fl.fl_ip_dport = inet_rsk(req)->rmt_port;
|
||||
fl.fl_ip_sport = inet_sk(sk)->sport;
|
||||
security_req_classify_flow(req, &fl);
|
||||
if (ip6_dst_lookup(sk, &dst, &fl)) {
|
||||
reqsk_free(req);
|
||||
goto out;
|
||||
}
|
||||
if (ip6_dst_lookup(sk, &dst, &fl))
|
||||
goto out_free;
|
||||
|
||||
if (final_p)
|
||||
ipv6_addr_copy(&fl.fl6_dst, final_p);
|
||||
if ((xfrm_lookup(&dst, &fl, sk, 0)) < 0)
|
||||
goto out;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
req->window_clamp = tp->window_clamp ? :dst_metric(dst, RTAX_WINDOW);
|
||||
@ -273,7 +270,10 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
|
||||
ireq->rcv_wscale = rcv_wscale;
|
||||
|
||||
ret = get_cookie_sock(sk, skb, req, dst);
|
||||
|
||||
out: return ret;
|
||||
out:
|
||||
return ret;
|
||||
out_free:
|
||||
reqsk_free(req);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -82,6 +82,7 @@ struct ieee80211_sta_bss {
|
||||
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 ssid[IEEE80211_MAX_SSID_LEN];
|
||||
u8 dtim_period;
|
||||
u16 capability; /* host byte order */
|
||||
enum ieee80211_band band;
|
||||
int freq;
|
||||
@ -586,6 +587,7 @@ struct ieee80211_local {
|
||||
struct timer_list sta_cleanup;
|
||||
|
||||
unsigned long queues_pending[BITS_TO_LONGS(IEEE80211_MAX_QUEUES)];
|
||||
unsigned long queues_pending_run[BITS_TO_LONGS(IEEE80211_MAX_QUEUES)];
|
||||
struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_QUEUES];
|
||||
struct tasklet_struct tx_pending_tasklet;
|
||||
|
||||
|
@ -1689,6 +1689,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
|
||||
if (local->hw.conf.beacon_int < 10)
|
||||
local->hw.conf.beacon_int = 100;
|
||||
|
||||
if (local->hw.max_listen_interval == 0)
|
||||
local->hw.max_listen_interval = 1;
|
||||
|
||||
local->hw.conf.listen_interval = local->hw.max_listen_interval;
|
||||
|
||||
local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC |
|
||||
IEEE80211_HW_SIGNAL_DB |
|
||||
IEEE80211_HW_SIGNAL_DBM) ?
|
||||
|
@ -551,6 +551,7 @@ static void ieee80211_set_associated(struct net_device *dev,
|
||||
/* set timing information */
|
||||
sdata->bss_conf.beacon_int = bss->beacon_int;
|
||||
sdata->bss_conf.timestamp = bss->timestamp;
|
||||
sdata->bss_conf.dtim_period = bss->dtim_period;
|
||||
|
||||
changed |= ieee80211_handle_bss_capability(sdata, bss);
|
||||
|
||||
@ -773,7 +774,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
|
||||
mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
|
||||
IEEE80211_STYPE_REASSOC_REQ);
|
||||
mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
|
||||
mgmt->u.reassoc_req.listen_interval = cpu_to_le16(1);
|
||||
mgmt->u.reassoc_req.listen_interval =
|
||||
cpu_to_le16(local->hw.conf.listen_interval);
|
||||
memcpy(mgmt->u.reassoc_req.current_ap, ifsta->prev_bssid,
|
||||
ETH_ALEN);
|
||||
} else {
|
||||
@ -781,7 +783,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
|
||||
mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
|
||||
IEEE80211_STYPE_ASSOC_REQ);
|
||||
mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
|
||||
mgmt->u.assoc_req.listen_interval = cpu_to_le16(1);
|
||||
mgmt->u.reassoc_req.listen_interval =
|
||||
cpu_to_le16(local->hw.conf.listen_interval);
|
||||
}
|
||||
|
||||
/* SSID */
|
||||
@ -2688,6 +2691,16 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
|
||||
bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
|
||||
bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
|
||||
|
||||
if (elems->tim) {
|
||||
struct ieee80211_tim_ie *tim_ie =
|
||||
(struct ieee80211_tim_ie *)elems->tim;
|
||||
bss->dtim_period = tim_ie->dtim_period;
|
||||
}
|
||||
|
||||
/* set default value for buggy APs */
|
||||
if (!elems->tim || bss->dtim_period == 0)
|
||||
bss->dtim_period = 1;
|
||||
|
||||
bss->supp_rates_len = 0;
|
||||
if (elems->supp_rates) {
|
||||
clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
|
||||
@ -3650,11 +3663,21 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
|
||||
"%s\n", print_mac(mac, bssid),
|
||||
print_mac(mac2, ifsta->bssid));
|
||||
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
|
||||
if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 &&
|
||||
(bss = ieee80211_rx_bss_get(dev, bssid,
|
||||
local->hw.conf.channel->center_freq,
|
||||
ifsta->ssid, ifsta->ssid_len))) {
|
||||
|
||||
if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) {
|
||||
int ret;
|
||||
int search_freq;
|
||||
|
||||
if (ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL)
|
||||
search_freq = bss->freq;
|
||||
else
|
||||
search_freq = local->hw.conf.channel->center_freq;
|
||||
|
||||
bss = ieee80211_rx_bss_get(dev, bssid, search_freq,
|
||||
ifsta->ssid, ifsta->ssid_len);
|
||||
if (!bss)
|
||||
goto dont_join;
|
||||
|
||||
printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
|
||||
" based on configured SSID\n",
|
||||
dev->name, print_mac(mac, bssid));
|
||||
@ -3662,6 +3685,8 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
|
||||
ieee80211_rx_bss_put(local, bss);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dont_join:
|
||||
#ifdef CONFIG_MAC80211_IBSS_DEBUG
|
||||
printk(KERN_DEBUG " did not try to join ibss\n");
|
||||
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
|
||||
@ -3895,7 +3920,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
|
||||
if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
|
||||
struct ieee80211_if_sta *ifsta = &sdata->u.sta;
|
||||
if (!(ifsta->flags & IEEE80211_STA_BSSID_SET) ||
|
||||
(!ifsta->state == IEEE80211_IBSS_JOINED &&
|
||||
(!(ifsta->state == IEEE80211_IBSS_JOINED) &&
|
||||
!ieee80211_sta_active_ibss(dev)))
|
||||
ieee80211_sta_find_ibss(dev, ifsta);
|
||||
}
|
||||
|
@ -1060,13 +1060,14 @@ static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
|
||||
static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
|
||||
struct ieee80211_tx_data *tx)
|
||||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_tx_info *info;
|
||||
int ret, i;
|
||||
|
||||
if (netif_subqueue_stopped(local->mdev, skb))
|
||||
return IEEE80211_TX_AGAIN;
|
||||
|
||||
if (skb) {
|
||||
if (netif_subqueue_stopped(local->mdev, skb))
|
||||
return IEEE80211_TX_AGAIN;
|
||||
info = IEEE80211_SKB_CB(skb);
|
||||
|
||||
ieee80211_dump_frame(wiphy_name(local->hw.wiphy),
|
||||
"TX to low-level driver", skb);
|
||||
ret = local->ops->tx(local_to_hw(local), skb);
|
||||
@ -1215,6 +1216,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb)
|
||||
|
||||
if (ret == IEEE80211_TX_FRAG_AGAIN)
|
||||
skb = NULL;
|
||||
|
||||
set_bit(queue, local->queues_pending);
|
||||
smp_mb();
|
||||
/*
|
||||
@ -1708,14 +1710,19 @@ void ieee80211_tx_pending(unsigned long data)
|
||||
netif_tx_lock_bh(dev);
|
||||
for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) {
|
||||
/* Check that this queue is ok */
|
||||
if (__netif_subqueue_stopped(local->mdev, i))
|
||||
if (__netif_subqueue_stopped(local->mdev, i) &&
|
||||
!test_bit(i, local->queues_pending_run))
|
||||
continue;
|
||||
|
||||
if (!test_bit(i, local->queues_pending)) {
|
||||
clear_bit(i, local->queues_pending_run);
|
||||
ieee80211_wake_queue(&local->hw, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
clear_bit(i, local->queues_pending_run);
|
||||
netif_start_subqueue(local->mdev, i);
|
||||
|
||||
store = &local->pending_packet[i];
|
||||
tx.extra_frag = store->extra_frag;
|
||||
tx.num_extra_frag = store->num_extra_frag;
|
||||
|
@ -361,6 +361,7 @@ void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
|
||||
if (test_bit(queue, local->queues_pending)) {
|
||||
set_bit(queue, local->queues_pending_run);
|
||||
tasklet_schedule(&local->tx_pending_tasklet);
|
||||
} else {
|
||||
netif_wake_subqueue(local->mdev, queue);
|
||||
|
@ -241,12 +241,14 @@ void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local,
|
||||
} else {
|
||||
struct netdev_queue *txq;
|
||||
spinlock_t *root_lock;
|
||||
struct Qdisc *q;
|
||||
|
||||
txq = netdev_get_tx_queue(local->mdev, agg_queue);
|
||||
root_lock = qdisc_root_lock(txq->qdisc);
|
||||
q = rcu_dereference(txq->qdisc);
|
||||
root_lock = qdisc_lock(q);
|
||||
|
||||
spin_lock_bh(root_lock);
|
||||
qdisc_reset(txq->qdisc);
|
||||
qdisc_reset(q);
|
||||
spin_unlock_bh(root_lock);
|
||||
}
|
||||
}
|
||||
|
@ -109,6 +109,25 @@ static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB);
|
||||
static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX);
|
||||
static DEFINE_RFKILL_TASK(rfkill_wwan, RFKILL_TYPE_WWAN);
|
||||
|
||||
static void rfkill_schedule_evsw_rfkillall(int state)
|
||||
{
|
||||
/* EVERY radio type. state != 0 means radios ON */
|
||||
/* handle EPO (emergency power off) through shortcut */
|
||||
if (state) {
|
||||
rfkill_schedule_set(&rfkill_wwan,
|
||||
RFKILL_STATE_UNBLOCKED);
|
||||
rfkill_schedule_set(&rfkill_wimax,
|
||||
RFKILL_STATE_UNBLOCKED);
|
||||
rfkill_schedule_set(&rfkill_uwb,
|
||||
RFKILL_STATE_UNBLOCKED);
|
||||
rfkill_schedule_set(&rfkill_bt,
|
||||
RFKILL_STATE_UNBLOCKED);
|
||||
rfkill_schedule_set(&rfkill_wlan,
|
||||
RFKILL_STATE_UNBLOCKED);
|
||||
} else
|
||||
rfkill_schedule_epo();
|
||||
}
|
||||
|
||||
static void rfkill_event(struct input_handle *handle, unsigned int type,
|
||||
unsigned int code, int data)
|
||||
{
|
||||
@ -132,21 +151,7 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
|
||||
} else if (type == EV_SW) {
|
||||
switch (code) {
|
||||
case SW_RFKILL_ALL:
|
||||
/* EVERY radio type. data != 0 means radios ON */
|
||||
/* handle EPO (emergency power off) through shortcut */
|
||||
if (data) {
|
||||
rfkill_schedule_set(&rfkill_wwan,
|
||||
RFKILL_STATE_UNBLOCKED);
|
||||
rfkill_schedule_set(&rfkill_wimax,
|
||||
RFKILL_STATE_UNBLOCKED);
|
||||
rfkill_schedule_set(&rfkill_uwb,
|
||||
RFKILL_STATE_UNBLOCKED);
|
||||
rfkill_schedule_set(&rfkill_bt,
|
||||
RFKILL_STATE_UNBLOCKED);
|
||||
rfkill_schedule_set(&rfkill_wlan,
|
||||
RFKILL_STATE_UNBLOCKED);
|
||||
} else
|
||||
rfkill_schedule_epo();
|
||||
rfkill_schedule_evsw_rfkillall(data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -168,6 +173,7 @@ static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,
|
||||
handle->handler = handler;
|
||||
handle->name = "rfkill";
|
||||
|
||||
/* causes rfkill_start() to be called */
|
||||
error = input_register_handle(handle);
|
||||
if (error)
|
||||
goto err_free_handle;
|
||||
@ -185,6 +191,23 @@ static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,
|
||||
return error;
|
||||
}
|
||||
|
||||
static void rfkill_start(struct input_handle *handle)
|
||||
{
|
||||
/* Take event_lock to guard against configuration changes, we
|
||||
* should be able to deal with concurrency with rfkill_event()
|
||||
* just fine (which event_lock will also avoid). */
|
||||
spin_lock_irq(&handle->dev->event_lock);
|
||||
|
||||
if (test_bit(EV_SW, handle->dev->evbit)) {
|
||||
if (test_bit(SW_RFKILL_ALL, handle->dev->swbit))
|
||||
rfkill_schedule_evsw_rfkillall(test_bit(SW_RFKILL_ALL,
|
||||
handle->dev->sw));
|
||||
/* add resync for further EV_SW events here */
|
||||
}
|
||||
|
||||
spin_unlock_irq(&handle->dev->event_lock);
|
||||
}
|
||||
|
||||
static void rfkill_disconnect(struct input_handle *handle)
|
||||
{
|
||||
input_close_device(handle);
|
||||
@ -225,6 +248,7 @@ static struct input_handler rfkill_handler = {
|
||||
.event = rfkill_event,
|
||||
.connect = rfkill_connect,
|
||||
.disconnect = rfkill_disconnect,
|
||||
.start = rfkill_start,
|
||||
.name = "rfkill",
|
||||
.id_table = rfkill_ids,
|
||||
};
|
||||
|
@ -105,6 +105,16 @@ static void rfkill_led_trigger(struct rfkill *rfkill,
|
||||
#endif /* CONFIG_RFKILL_LEDS */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RFKILL_LEDS
|
||||
static void rfkill_led_trigger_activate(struct led_classdev *led)
|
||||
{
|
||||
struct rfkill *rfkill = container_of(led->trigger,
|
||||
struct rfkill, led_trigger);
|
||||
|
||||
rfkill_led_trigger(rfkill, rfkill->state);
|
||||
}
|
||||
#endif /* CONFIG_RFKILL_LEDS */
|
||||
|
||||
static void notify_rfkill_state_change(struct rfkill *rfkill)
|
||||
{
|
||||
blocking_notifier_call_chain(&rfkill_notifier_list,
|
||||
@ -589,7 +599,10 @@ static void rfkill_led_trigger_register(struct rfkill *rfkill)
|
||||
#ifdef CONFIG_RFKILL_LEDS
|
||||
int error;
|
||||
|
||||
rfkill->led_trigger.name = rfkill->dev.bus_id;
|
||||
if (!rfkill->led_trigger.name)
|
||||
rfkill->led_trigger.name = rfkill->dev.bus_id;
|
||||
if (!rfkill->led_trigger.activate)
|
||||
rfkill->led_trigger.activate = rfkill_led_trigger_activate;
|
||||
error = led_trigger_register(&rfkill->led_trigger);
|
||||
if (error)
|
||||
rfkill->led_trigger.name = NULL;
|
||||
|
@ -415,7 +415,7 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
case TC_ACT_QUEUED:
|
||||
case TC_ACT_STOLEN:
|
||||
kfree_skb(skb);
|
||||
return NET_XMIT_SUCCESS;
|
||||
return NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
|
||||
case TC_ACT_SHOT:
|
||||
kfree_skb(skb);
|
||||
goto drop;
|
||||
@ -432,9 +432,11 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
ret = qdisc_enqueue(skb, flow->q);
|
||||
if (ret != 0) {
|
||||
drop: __maybe_unused
|
||||
sch->qstats.drops++;
|
||||
if (flow)
|
||||
flow->qstats.drops++;
|
||||
if (net_xmit_drop_count(ret)) {
|
||||
sch->qstats.drops++;
|
||||
if (flow)
|
||||
flow->qstats.drops++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
sch->bstats.bytes += qdisc_pkt_len(skb);
|
||||
@ -455,7 +457,7 @@ drop: __maybe_unused
|
||||
return 0;
|
||||
}
|
||||
tasklet_schedule(&p->task);
|
||||
return NET_XMIT_BYPASS;
|
||||
return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -530,7 +532,7 @@ static int atm_tc_requeue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
if (!ret) {
|
||||
sch->q.qlen++;
|
||||
sch->qstats.requeues++;
|
||||
} else {
|
||||
} else if (net_xmit_drop_count(ret)) {
|
||||
sch->qstats.drops++;
|
||||
p->link.qstats.drops++;
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
|
||||
(cl = cbq_class_lookup(q, prio)) != NULL)
|
||||
return cl;
|
||||
|
||||
*qerr = NET_XMIT_BYPASS;
|
||||
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
|
||||
for (;;) {
|
||||
int result = 0;
|
||||
defmap = head->defaults;
|
||||
@ -256,7 +256,7 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
|
||||
switch (result) {
|
||||
case TC_ACT_QUEUED:
|
||||
case TC_ACT_STOLEN:
|
||||
*qerr = NET_XMIT_SUCCESS;
|
||||
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
|
||||
case TC_ACT_SHOT:
|
||||
return NULL;
|
||||
case TC_ACT_RECLASSIFY:
|
||||
@ -377,7 +377,7 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
q->rx_class = cl;
|
||||
#endif
|
||||
if (cl == NULL) {
|
||||
if (ret == NET_XMIT_BYPASS)
|
||||
if (ret & __NET_XMIT_BYPASS)
|
||||
sch->qstats.drops++;
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
@ -397,9 +397,11 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
return ret;
|
||||
}
|
||||
|
||||
sch->qstats.drops++;
|
||||
cbq_mark_toplevel(q, cl);
|
||||
cl->qstats.drops++;
|
||||
if (net_xmit_drop_count(ret)) {
|
||||
sch->qstats.drops++;
|
||||
cbq_mark_toplevel(q, cl);
|
||||
cl->qstats.drops++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -430,8 +432,10 @@ cbq_requeue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
cbq_activate_class(cl);
|
||||
return 0;
|
||||
}
|
||||
sch->qstats.drops++;
|
||||
cl->qstats.drops++;
|
||||
if (net_xmit_drop_count(ret)) {
|
||||
sch->qstats.drops++;
|
||||
cl->qstats.drops++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -664,13 +668,15 @@ static int cbq_reshape_fail(struct sk_buff *skb, struct Qdisc *child)
|
||||
q->rx_class = NULL;
|
||||
|
||||
if (cl && (cl = cbq_reclassify(skb, cl)) != NULL) {
|
||||
int ret;
|
||||
|
||||
cbq_mark_toplevel(q, cl);
|
||||
|
||||
q->rx_class = cl;
|
||||
cl->q->__parent = sch;
|
||||
|
||||
if (qdisc_enqueue(skb, cl->q) == 0) {
|
||||
ret = qdisc_enqueue(skb, cl->q);
|
||||
if (ret == NET_XMIT_SUCCESS) {
|
||||
sch->q.qlen++;
|
||||
sch->bstats.packets++;
|
||||
sch->bstats.bytes += qdisc_pkt_len(skb);
|
||||
@ -678,7 +684,8 @@ static int cbq_reshape_fail(struct sk_buff *skb, struct Qdisc *child)
|
||||
cbq_activate_class(cl);
|
||||
return 0;
|
||||
}
|
||||
sch->qstats.drops++;
|
||||
if (net_xmit_drop_count(ret))
|
||||
sch->qstats.drops++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -236,7 +236,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
case TC_ACT_QUEUED:
|
||||
case TC_ACT_STOLEN:
|
||||
kfree_skb(skb);
|
||||
return NET_XMIT_SUCCESS;
|
||||
return NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
|
||||
|
||||
case TC_ACT_SHOT:
|
||||
goto drop;
|
||||
@ -254,7 +254,8 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
|
||||
err = qdisc_enqueue(skb, p->q);
|
||||
if (err != NET_XMIT_SUCCESS) {
|
||||
sch->qstats.drops++;
|
||||
if (net_xmit_drop_count(err))
|
||||
sch->qstats.drops++;
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -267,7 +268,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
drop:
|
||||
kfree_skb(skb);
|
||||
sch->qstats.drops++;
|
||||
return NET_XMIT_BYPASS;
|
||||
return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
|
||||
}
|
||||
|
||||
static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
|
||||
@ -321,7 +322,8 @@ static int dsmark_requeue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
|
||||
err = p->q->ops->requeue(skb, p->q);
|
||||
if (err != NET_XMIT_SUCCESS) {
|
||||
sch->qstats.drops++;
|
||||
if (net_xmit_drop_count(err))
|
||||
sch->qstats.drops++;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
/* Main transmission queue. */
|
||||
|
||||
/* Modifications to data participating in scheduling must be protected with
|
||||
* qdisc_root_lock(qdisc) spinlock.
|
||||
* qdisc_lock(qdisc) spinlock.
|
||||
*
|
||||
* The idea is the following:
|
||||
* - enqueue, dequeue are serialized via qdisc root lock
|
||||
@ -126,7 +126,7 @@ static inline int qdisc_restart(struct Qdisc *q)
|
||||
if (unlikely((skb = dequeue_skb(q)) == NULL))
|
||||
return 0;
|
||||
|
||||
root_lock = qdisc_root_lock(q);
|
||||
root_lock = qdisc_lock(q);
|
||||
|
||||
/* And release qdisc */
|
||||
spin_unlock(root_lock);
|
||||
@ -507,7 +507,7 @@ struct Qdisc * qdisc_create_dflt(struct net_device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL(qdisc_create_dflt);
|
||||
|
||||
/* Under qdisc_root_lock(qdisc) and BH! */
|
||||
/* Under qdisc_lock(qdisc) and BH! */
|
||||
|
||||
void qdisc_reset(struct Qdisc *qdisc)
|
||||
{
|
||||
@ -543,7 +543,7 @@ static void __qdisc_destroy(struct rcu_head *head)
|
||||
kfree((char *) qdisc - qdisc->padded);
|
||||
}
|
||||
|
||||
/* Under qdisc_root_lock(qdisc) and BH! */
|
||||
/* Under qdisc_lock(qdisc) and BH! */
|
||||
|
||||
void qdisc_destroy(struct Qdisc *qdisc)
|
||||
{
|
||||
@ -659,7 +659,7 @@ static bool some_qdisc_is_running(struct net_device *dev, int lock)
|
||||
|
||||
dev_queue = netdev_get_tx_queue(dev, i);
|
||||
q = dev_queue->qdisc;
|
||||
root_lock = qdisc_root_lock(q);
|
||||
root_lock = qdisc_lock(q);
|
||||
|
||||
if (lock)
|
||||
spin_lock_bh(root_lock);
|
||||
@ -735,7 +735,7 @@ static void shutdown_scheduler_queue(struct net_device *dev,
|
||||
struct Qdisc *qdisc_default = _qdisc_default;
|
||||
|
||||
if (qdisc) {
|
||||
spinlock_t *root_lock = qdisc_root_lock(qdisc);
|
||||
spinlock_t *root_lock = qdisc_lock(qdisc);
|
||||
|
||||
dev_queue->qdisc = qdisc_default;
|
||||
dev_queue->qdisc_sleeping = qdisc_default;
|
||||
|
@ -1159,14 +1159,14 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
|
||||
if (cl->level == 0)
|
||||
return cl;
|
||||
|
||||
*qerr = NET_XMIT_BYPASS;
|
||||
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
|
||||
tcf = q->root.filter_list;
|
||||
while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
switch (result) {
|
||||
case TC_ACT_QUEUED:
|
||||
case TC_ACT_STOLEN:
|
||||
*qerr = NET_XMIT_SUCCESS;
|
||||
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
|
||||
case TC_ACT_SHOT:
|
||||
return NULL;
|
||||
}
|
||||
@ -1578,7 +1578,7 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
|
||||
cl = hfsc_classify(skb, sch, &err);
|
||||
if (cl == NULL) {
|
||||
if (err == NET_XMIT_BYPASS)
|
||||
if (err & __NET_XMIT_BYPASS)
|
||||
sch->qstats.drops++;
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
@ -1586,8 +1586,10 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
|
||||
err = qdisc_enqueue(skb, cl->qdisc);
|
||||
if (unlikely(err != NET_XMIT_SUCCESS)) {
|
||||
cl->qstats.drops++;
|
||||
sch->qstats.drops++;
|
||||
if (net_xmit_drop_count(err)) {
|
||||
cl->qstats.drops++;
|
||||
sch->qstats.drops++;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -214,14 +214,14 @@ static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch,
|
||||
if ((cl = htb_find(skb->priority, sch)) != NULL && cl->level == 0)
|
||||
return cl;
|
||||
|
||||
*qerr = NET_XMIT_BYPASS;
|
||||
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
|
||||
tcf = q->filter_list;
|
||||
while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
switch (result) {
|
||||
case TC_ACT_QUEUED:
|
||||
case TC_ACT_STOLEN:
|
||||
*qerr = NET_XMIT_SUCCESS;
|
||||
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
|
||||
case TC_ACT_SHOT:
|
||||
return NULL;
|
||||
}
|
||||
@ -567,14 +567,16 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
}
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
} else if (!cl) {
|
||||
if (ret == NET_XMIT_BYPASS)
|
||||
if (ret & __NET_XMIT_BYPASS)
|
||||
sch->qstats.drops++;
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
#endif
|
||||
} else if (qdisc_enqueue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) {
|
||||
sch->qstats.drops++;
|
||||
cl->qstats.drops++;
|
||||
} else if ((ret = qdisc_enqueue(skb, cl->un.leaf.q)) != NET_XMIT_SUCCESS) {
|
||||
if (net_xmit_drop_count(ret)) {
|
||||
sch->qstats.drops++;
|
||||
cl->qstats.drops++;
|
||||
}
|
||||
return NET_XMIT_DROP;
|
||||
} else {
|
||||
cl->bstats.packets +=
|
||||
@ -610,15 +612,17 @@ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
}
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
} else if (!cl) {
|
||||
if (ret == NET_XMIT_BYPASS)
|
||||
if (ret & __NET_XMIT_BYPASS)
|
||||
sch->qstats.drops++;
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
#endif
|
||||
} else if (cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q) !=
|
||||
} else if ((ret = cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q)) !=
|
||||
NET_XMIT_SUCCESS) {
|
||||
sch->qstats.drops++;
|
||||
cl->qstats.drops++;
|
||||
if (net_xmit_drop_count(ret)) {
|
||||
sch->qstats.drops++;
|
||||
cl->qstats.drops++;
|
||||
}
|
||||
return NET_XMIT_DROP;
|
||||
} else
|
||||
htb_activate(q, cl);
|
||||
|
@ -176,7 +176,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
if (count == 0) {
|
||||
sch->qstats.drops++;
|
||||
kfree_skb(skb);
|
||||
return NET_XMIT_BYPASS;
|
||||
return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
|
||||
}
|
||||
|
||||
skb_orphan(skb);
|
||||
@ -240,8 +240,9 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
sch->q.qlen++;
|
||||
sch->bstats.bytes += qdisc_pkt_len(skb);
|
||||
sch->bstats.packets++;
|
||||
} else
|
||||
} else if (net_xmit_drop_count(ret)) {
|
||||
sch->qstats.drops++;
|
||||
}
|
||||
|
||||
pr_debug("netem: enqueue ret %d\n", ret);
|
||||
return ret;
|
||||
|
@ -38,14 +38,14 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
|
||||
struct tcf_result res;
|
||||
int err;
|
||||
|
||||
*qerr = NET_XMIT_BYPASS;
|
||||
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
|
||||
if (TC_H_MAJ(skb->priority) != sch->handle) {
|
||||
err = tc_classify(skb, q->filter_list, &res);
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
switch (err) {
|
||||
case TC_ACT_STOLEN:
|
||||
case TC_ACT_QUEUED:
|
||||
*qerr = NET_XMIT_SUCCESS;
|
||||
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
|
||||
case TC_ACT_SHOT:
|
||||
return NULL;
|
||||
}
|
||||
@ -74,7 +74,7 @@ prio_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
if (qdisc == NULL) {
|
||||
|
||||
if (ret == NET_XMIT_BYPASS)
|
||||
if (ret & __NET_XMIT_BYPASS)
|
||||
sch->qstats.drops++;
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
@ -88,7 +88,8 @@ prio_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
sch->q.qlen++;
|
||||
return NET_XMIT_SUCCESS;
|
||||
}
|
||||
sch->qstats.drops++;
|
||||
if (net_xmit_drop_count(ret))
|
||||
sch->qstats.drops++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -102,7 +103,7 @@ prio_requeue(struct sk_buff *skb, struct Qdisc* sch)
|
||||
qdisc = prio_classify(skb, sch, &ret);
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
if (qdisc == NULL) {
|
||||
if (ret == NET_XMIT_BYPASS)
|
||||
if (ret & __NET_XMIT_BYPASS)
|
||||
sch->qstats.drops++;
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
@ -114,7 +115,8 @@ prio_requeue(struct sk_buff *skb, struct Qdisc* sch)
|
||||
sch->qstats.requeues++;
|
||||
return 0;
|
||||
}
|
||||
sch->qstats.drops++;
|
||||
if (net_xmit_drop_count(ret))
|
||||
sch->qstats.drops++;
|
||||
return NET_XMIT_DROP;
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc* sch)
|
||||
sch->bstats.bytes += qdisc_pkt_len(skb);
|
||||
sch->bstats.packets++;
|
||||
sch->q.qlen++;
|
||||
} else {
|
||||
} else if (net_xmit_drop_count(ret)) {
|
||||
q->stats.pdrop++;
|
||||
sch->qstats.drops++;
|
||||
}
|
||||
|
@ -171,14 +171,14 @@ static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch,
|
||||
if (!q->filter_list)
|
||||
return sfq_hash(q, skb) + 1;
|
||||
|
||||
*qerr = NET_XMIT_BYPASS;
|
||||
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
|
||||
result = tc_classify(skb, q->filter_list, &res);
|
||||
if (result >= 0) {
|
||||
#ifdef CONFIG_NET_CLS_ACT
|
||||
switch (result) {
|
||||
case TC_ACT_STOLEN:
|
||||
case TC_ACT_QUEUED:
|
||||
*qerr = NET_XMIT_SUCCESS;
|
||||
*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
|
||||
case TC_ACT_SHOT:
|
||||
return 0;
|
||||
}
|
||||
@ -285,7 +285,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
|
||||
hash = sfq_classify(skb, sch, &ret);
|
||||
if (hash == 0) {
|
||||
if (ret == NET_XMIT_BYPASS)
|
||||
if (ret & __NET_XMIT_BYPASS)
|
||||
sch->qstats.drops++;
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
@ -339,7 +339,7 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc *sch)
|
||||
|
||||
hash = sfq_classify(skb, sch, &ret);
|
||||
if (hash == 0) {
|
||||
if (ret == NET_XMIT_BYPASS)
|
||||
if (ret & __NET_XMIT_BYPASS)
|
||||
sch->qstats.drops++;
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
|
@ -135,7 +135,8 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch)
|
||||
|
||||
ret = qdisc_enqueue(skb, q->qdisc);
|
||||
if (ret != 0) {
|
||||
sch->qstats.drops++;
|
||||
if (net_xmit_drop_count(ret))
|
||||
sch->qstats.drops++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -195,8 +195,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
||||
}
|
||||
|
||||
/* Based on tcp_v6_xmit() in tcp_ipv6.c. */
|
||||
static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport,
|
||||
int ipfragok)
|
||||
static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport)
|
||||
{
|
||||
struct sock *sk = skb->sk;
|
||||
struct ipv6_pinfo *np = inet6_sk(sk);
|
||||
@ -231,7 +230,10 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport,
|
||||
|
||||
SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
|
||||
|
||||
return ip6_xmit(sk, skb, &fl, np->opt, ipfragok);
|
||||
if (!(transport->param_flags & SPP_PMTUD_ENABLE))
|
||||
skb->local_df = 1;
|
||||
|
||||
return ip6_xmit(sk, skb, &fl, np->opt, 0);
|
||||
}
|
||||
|
||||
/* Returns the dst cache entry for the given source and destination ip
|
||||
|
@ -586,10 +586,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
|
||||
SCTP_DEBUG_PRINTK("***sctp_transmit_packet*** skb len %d\n",
|
||||
nskb->len);
|
||||
|
||||
if (tp->param_flags & SPP_PMTUD_ENABLE)
|
||||
(*tp->af_specific->sctp_xmit)(nskb, tp, packet->ipfragok);
|
||||
else
|
||||
(*tp->af_specific->sctp_xmit)(nskb, tp, 1);
|
||||
nskb->local_df = packet->ipfragok;
|
||||
(*tp->af_specific->sctp_xmit)(nskb, tp);
|
||||
|
||||
out:
|
||||
packet->size = packet->overhead;
|
||||
|
@ -862,16 +862,21 @@ static int sctp_inet_supported_addrs(const struct sctp_sock *opt,
|
||||
|
||||
/* Wrapper routine that calls the ip transmit routine. */
|
||||
static inline int sctp_v4_xmit(struct sk_buff *skb,
|
||||
struct sctp_transport *transport, int ipfragok)
|
||||
struct sctp_transport *transport)
|
||||
{
|
||||
struct inet_sock *inet = inet_sk(skb->sk);
|
||||
|
||||
SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, "
|
||||
"src:%u.%u.%u.%u, dst:%u.%u.%u.%u\n",
|
||||
__func__, skb, skb->len,
|
||||
NIPQUAD(skb->rtable->rt_src),
|
||||
NIPQUAD(skb->rtable->rt_dst));
|
||||
|
||||
inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ?
|
||||
IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
|
||||
|
||||
SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
|
||||
return ip_queue_xmit(skb, ipfragok);
|
||||
return ip_queue_xmit(skb, 0);
|
||||
}
|
||||
|
||||
static struct sctp_af sctp_af_inet;
|
||||
|
Loading…
Reference in New Issue
Block a user