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:
Linus Torvalds 2008-08-05 19:37:42 -07:00
commit e63e03273b
95 changed files with 2168 additions and 1293 deletions

View File

@ -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;

View File

@ -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!

View File

@ -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 */

View File

@ -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;

View File

@ -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),

View File

@ -63,7 +63,6 @@
struct ath5k_softc;
struct ath5k_hw;
struct ieee80211_hw_mode;
struct sk_buff;
struct ath5k_buf;

View File

@ -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)

View File

@ -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 },*/

View File

@ -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

View File

@ -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))

View File

@ -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"

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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,

View File

@ -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,

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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);

View File

@ -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;

View File

@ -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] =

View File

@ -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);

View File

@ -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)
/*

View File

@ -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 {

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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:

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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;
}

View File

@ -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() */

View File

@ -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);
}

View File

@ -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.

View File

@ -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;
};

View File

@ -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) {

View File

@ -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;

View File

@ -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)

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);

View File

@ -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.
*/

View File

@ -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];

View File

@ -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),

View File

@ -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;

View File

@ -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 */

View File

@ -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)

View File

@ -47,7 +47,6 @@ struct flowi {
#define fl4_scope nl_u.ip4_u.scope
__u8 proto;
__u8 flags;
union {
struct {
__be16 sport;

View File

@ -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;
};

View File

@ -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,

View File

@ -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,

View File

@ -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++)

View File

@ -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;

View File

@ -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 */

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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,

View File

@ -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,

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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) ?

View File

@ -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);
}

View File

@ -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;

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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,
};

View File

@ -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;

View File

@ -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++;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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++;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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;