aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-05-18 17:48:30 -0400
committerDavid S. Miller <davem@davemloft.net>2009-05-18 17:48:30 -0400
commit82d048186e403f36e083b37ad42aa90abb7dcaac (patch)
treedc0b92ace036ef435318f38ef35b8c6e6b84103a
parent62551d3ea05242d97d47f26fb517b2dfdb752310 (diff)
parentd3707d9918d47c0997a6b1e4ae24e7ab55e43796 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c51
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c59
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c89
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c89
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c62
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c233
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h39
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c56
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c2
-rw-r--r--drivers/net/wireless/mwl8k.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c2
-rw-r--r--drivers/net/wireless/wl12xx/Kconfig2
-rw-r--r--include/linux/ieee80211.h8
-rw-r--r--include/linux/nl80211.h51
-rw-r--r--include/net/cfg80211.h57
-rw-r--r--include/net/mac80211.h28
-rw-r--r--net/mac80211/cfg.c50
-rw-r--r--net/mac80211/debugfs.c38
-rw-r--r--net/mac80211/ibss.c77
-rw-r--r--net/mac80211/ieee80211_i.h9
-rw-r--r--net/mac80211/iface.c3
-rw-r--r--net/mac80211/key.c21
-rw-r--r--net/mac80211/key.h3
-rw-r--r--net/mac80211/main.c14
-rw-r--r--net/mac80211/mlme.c41
-rw-r--r--net/mac80211/rx.c58
-rw-r--r--net/mac80211/scan.c32
-rw-r--r--net/mac80211/tx.c5
-rw-r--r--net/mac80211/util.c60
-rw-r--r--net/mac80211/wext.c282
-rw-r--r--net/mac80211/wme.c2
-rw-r--r--net/wireless/core.c10
-rw-r--r--net/wireless/core.h6
-rw-r--r--net/wireless/ibss.c60
-rw-r--r--net/wireless/nl80211.c128
-rw-r--r--net/wireless/util.c45
-rw-r--r--net/wireless/wext-compat.c286
-rw-r--r--net/wireless/wext.c20
49 files changed, 1116 insertions, 1013 deletions
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index 44fee5ae8925..a2fda702b620 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -694,7 +694,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
694#undef TMP_VAL_VPD_TABLE 694#undef TMP_VAL_VPD_TABLE
695} 695}
696 696
697static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, 697static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
698 struct ath9k_channel *chan, 698 struct ath9k_channel *chan,
699 int16_t *pTxPowerIndexOffset) 699 int16_t *pTxPowerIndexOffset)
700{ 700{
@@ -805,11 +805,9 @@ static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
805 } 805 }
806 806
807 *pTxPowerIndexOffset = 0; 807 *pTxPowerIndexOffset = 0;
808
809 return true;
810} 808}
811 809
812static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah, 810static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
813 struct ath9k_channel *chan, 811 struct ath9k_channel *chan,
814 int16_t *ratesArray, 812 int16_t *ratesArray,
815 u16 cfgCtl, 813 u16 cfgCtl,
@@ -1041,10 +1039,9 @@ static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
1041 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0]; 1039 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
1042 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0]; 1040 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
1043 } 1041 }
1044 return true;
1045} 1042}
1046 1043
1047static int ath9k_hw_4k_set_txpower(struct ath_hw *ah, 1044static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
1048 struct ath9k_channel *chan, 1045 struct ath9k_channel *chan,
1049 u16 cfgCtl, 1046 u16 cfgCtl,
1050 u8 twiceAntennaReduction, 1047 u8 twiceAntennaReduction,
@@ -1065,22 +1062,13 @@ static int ath9k_hw_4k_set_txpower(struct ath_hw *ah,
1065 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 1062 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
1066 } 1063 }
1067 1064
1068 if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan, 1065 ath9k_hw_set_4k_power_per_rate_table(ah, chan,
1069 &ratesArray[0], cfgCtl, 1066 &ratesArray[0], cfgCtl,
1070 twiceAntennaReduction, 1067 twiceAntennaReduction,
1071 twiceMaxRegulatoryPower, 1068 twiceMaxRegulatoryPower,
1072 powerLimit)) { 1069 powerLimit);
1073 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1074 "ath9k_hw_set_txpower: unable to set "
1075 "tx power per rate table\n");
1076 return -EIO;
1077 }
1078 1070
1079 if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) { 1071 ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset);
1080 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1081 "ath9k_hw_set_txpower: unable to set power table\n");
1082 return -EIO;
1083 }
1084 1072
1085 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 1073 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
1086 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 1074 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
@@ -1168,7 +1156,6 @@ static int ath9k_hw_4k_set_txpower(struct ath_hw *ah,
1168 else 1156 else
1169 ah->regulatory.max_power_level = ratesArray[i]; 1157 ah->regulatory.max_power_level = ratesArray[i];
1170 1158
1171 return 0;
1172} 1159}
1173 1160
1174static void ath9k_hw_4k_set_addac(struct ath_hw *ah, 1161static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
@@ -2103,7 +2090,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
2103 return; 2090 return;
2104} 2091}
2105 2092
2106static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, 2093static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
2107 struct ath9k_channel *chan, 2094 struct ath9k_channel *chan,
2108 int16_t *pTxPowerIndexOffset) 2095 int16_t *pTxPowerIndexOffset)
2109{ 2096{
@@ -2255,13 +2242,11 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
2255 } 2242 }
2256 2243
2257 *pTxPowerIndexOffset = 0; 2244 *pTxPowerIndexOffset = 0;
2258
2259 return true;
2260#undef SM_PD_GAIN 2245#undef SM_PD_GAIN
2261#undef SM_PDGAIN_B 2246#undef SM_PDGAIN_B
2262} 2247}
2263 2248
2264static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, 2249static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
2265 struct ath9k_channel *chan, 2250 struct ath9k_channel *chan,
2266 int16_t *ratesArray, 2251 int16_t *ratesArray,
2267 u16 cfgCtl, 2252 u16 cfgCtl,
@@ -2549,10 +2534,9 @@ static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
2549 targetPowerCckExt.tPow2x[0]; 2534 targetPowerCckExt.tPow2x[0];
2550 } 2535 }
2551 } 2536 }
2552 return true;
2553} 2537}
2554 2538
2555static int ath9k_hw_def_set_txpower(struct ath_hw *ah, 2539static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
2556 struct ath9k_channel *chan, 2540 struct ath9k_channel *chan,
2557 u16 cfgCtl, 2541 u16 cfgCtl,
2558 u8 twiceAntennaReduction, 2542 u8 twiceAntennaReduction,
@@ -2575,22 +2559,13 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
2575 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc; 2559 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
2576 } 2560 }
2577 2561
2578 if (!ath9k_hw_set_def_power_per_rate_table(ah, chan, 2562 ath9k_hw_set_def_power_per_rate_table(ah, chan,
2579 &ratesArray[0], cfgCtl, 2563 &ratesArray[0], cfgCtl,
2580 twiceAntennaReduction, 2564 twiceAntennaReduction,
2581 twiceMaxRegulatoryPower, 2565 twiceMaxRegulatoryPower,
2582 powerLimit)) { 2566 powerLimit);
2583 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2584 "ath9k_hw_set_txpower: unable to set "
2585 "tx power per rate table\n");
2586 return -EIO;
2587 }
2588 2567
2589 if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) { 2568 ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
2590 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2591 "ath9k_hw_set_txpower: unable to set power table\n");
2592 return -EIO;
2593 }
2594 2569
2595 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) { 2570 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
2596 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]); 2571 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
@@ -2717,8 +2692,6 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
2717 "Invalid chainmask configuration\n"); 2692 "Invalid chainmask configuration\n");
2718 break; 2693 break;
2719 } 2694 }
2720
2721 return 0;
2722} 2695}
2723 2696
2724static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah, 2697static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 7c59dc47f912..67b8bd12941a 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -494,7 +494,7 @@ struct eeprom_ops {
494 struct ath9k_channel *chan); 494 struct ath9k_channel *chan);
495 void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan); 495 void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
496 void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan); 496 void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
497 int (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan, 497 void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
498 u16 cfgCtl, u8 twiceAntennaReduction, 498 u16 cfgCtl, u8 twiceAntennaReduction,
499 u8 twiceMaxRegulatoryPower, u8 powerLimit); 499 u8 twiceMaxRegulatoryPower, u8 powerLimit);
500 u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz); 500 u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 5879c731e9e7..4acfab514916 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1274,7 +1274,6 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1274 int i, regWrites = 0; 1274 int i, regWrites = 0;
1275 struct ieee80211_channel *channel = chan->chan; 1275 struct ieee80211_channel *channel = chan->chan;
1276 u32 modesIndex, freqIndex; 1276 u32 modesIndex, freqIndex;
1277 int status;
1278 1277
1279 switch (chan->chanmode) { 1278 switch (chan->chanmode) {
1280 case CHANNEL_A: 1279 case CHANNEL_A:
@@ -1376,17 +1375,12 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1376 if (OLC_FOR_AR9280_20_LATER) 1375 if (OLC_FOR_AR9280_20_LATER)
1377 ath9k_olc_init(ah); 1376 ath9k_olc_init(ah);
1378 1377
1379 status = ah->eep_ops->set_txpower(ah, chan, 1378 ah->eep_ops->set_txpower(ah, chan,
1380 ath9k_regd_get_ctl(&ah->regulatory, chan), 1379 ath9k_regd_get_ctl(&ah->regulatory, chan),
1381 channel->max_antenna_gain * 2, 1380 channel->max_antenna_gain * 2,
1382 channel->max_power * 2, 1381 channel->max_power * 2,
1383 min((u32) MAX_RATE_POWER, 1382 min((u32) MAX_RATE_POWER,
1384 (u32) ah->regulatory.power_limit)); 1383 (u32) ah->regulatory.power_limit));
1385 if (status != 0) {
1386 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
1387 "Error initializing transmit power\n");
1388 return -EIO;
1389 }
1390 1384
1391 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { 1385 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
1392 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 1386 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
@@ -1617,11 +1611,9 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
1617 switch (type) { 1611 switch (type) {
1618 case ATH9K_RESET_POWER_ON: 1612 case ATH9K_RESET_POWER_ON:
1619 return ath9k_hw_set_reset_power_on(ah); 1613 return ath9k_hw_set_reset_power_on(ah);
1620 break;
1621 case ATH9K_RESET_WARM: 1614 case ATH9K_RESET_WARM:
1622 case ATH9K_RESET_COLD: 1615 case ATH9K_RESET_COLD:
1623 return ath9k_hw_set_reset(ah, type); 1616 return ath9k_hw_set_reset(ah, type);
1624 break;
1625 default: 1617 default:
1626 return false; 1618 return false;
1627 } 1619 }
@@ -1703,11 +1695,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1703 ath9k_hw_set_regs(ah, chan, macmode); 1695 ath9k_hw_set_regs(ah, chan, macmode);
1704 1696
1705 if (AR_SREV_9280_10_OR_LATER(ah)) { 1697 if (AR_SREV_9280_10_OR_LATER(ah)) {
1706 if (!(ath9k_hw_ar9280_set_channel(ah, chan))) { 1698 ath9k_hw_ar9280_set_channel(ah, chan);
1707 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
1708 "Failed to set channel\n");
1709 return false;
1710 }
1711 } else { 1699 } else {
1712 if (!(ath9k_hw_set_channel(ah, chan))) { 1700 if (!(ath9k_hw_set_channel(ah, chan))) {
1713 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 1701 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
@@ -1716,16 +1704,12 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1716 } 1704 }
1717 } 1705 }
1718 1706
1719 if (ah->eep_ops->set_txpower(ah, chan, 1707 ah->eep_ops->set_txpower(ah, chan,
1720 ath9k_regd_get_ctl(&ah->regulatory, chan), 1708 ath9k_regd_get_ctl(&ah->regulatory, chan),
1721 channel->max_antenna_gain * 2, 1709 channel->max_antenna_gain * 2,
1722 channel->max_power * 2, 1710 channel->max_power * 2,
1723 min((u32) MAX_RATE_POWER, 1711 min((u32) MAX_RATE_POWER,
1724 (u32) ah->regulatory.power_limit)) != 0) { 1712 (u32) ah->regulatory.power_limit));
1725 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1726 "Error initializing transmit power\n");
1727 return false;
1728 }
1729 1713
1730 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 1714 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
1731 if (IS_CHAN_B(chan)) 1715 if (IS_CHAN_B(chan))
@@ -2313,13 +2297,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2313 2297
2314 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); 2298 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
2315 2299
2316 if (AR_SREV_9280_10_OR_LATER(ah)) { 2300 if (AR_SREV_9280_10_OR_LATER(ah))
2317 if (!(ath9k_hw_ar9280_set_channel(ah, chan))) 2301 ath9k_hw_ar9280_set_channel(ah, chan);
2318 return -EIO; 2302 else
2319 } else {
2320 if (!(ath9k_hw_set_channel(ah, chan))) 2303 if (!(ath9k_hw_set_channel(ah, chan)))
2321 return -EIO; 2304 return -EIO;
2322 }
2323 2305
2324 for (i = 0; i < AR_NUM_DCU; i++) 2306 for (i = 0; i < AR_NUM_DCU; i++)
2325 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); 2307 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
@@ -3750,22 +3732,19 @@ bool ath9k_hw_disable(struct ath_hw *ah)
3750 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD); 3732 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
3751} 3733}
3752 3734
3753bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit) 3735void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
3754{ 3736{
3755 struct ath9k_channel *chan = ah->curchan; 3737 struct ath9k_channel *chan = ah->curchan;
3756 struct ieee80211_channel *channel = chan->chan; 3738 struct ieee80211_channel *channel = chan->chan;
3757 3739
3758 ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER); 3740 ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER);
3759 3741
3760 if (ah->eep_ops->set_txpower(ah, chan, 3742 ah->eep_ops->set_txpower(ah, chan,
3761 ath9k_regd_get_ctl(&ah->regulatory, chan), 3743 ath9k_regd_get_ctl(&ah->regulatory, chan),
3762 channel->max_antenna_gain * 2, 3744 channel->max_antenna_gain * 2,
3763 channel->max_power * 2, 3745 channel->max_power * 2,
3764 min((u32) MAX_RATE_POWER, 3746 min((u32) MAX_RATE_POWER,
3765 (u32) ah->regulatory.power_limit)) != 0) 3747 (u32) ah->regulatory.power_limit));
3766 return false;
3767
3768 return true;
3769} 3748}
3770 3749
3771void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac) 3750void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac)
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index ddb24c47ebcf..dd8508ef6e05 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -590,7 +590,7 @@ u32 ath9k_hw_getrxfilter(struct ath_hw *ah);
590void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits); 590void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
591bool ath9k_hw_phy_disable(struct ath_hw *ah); 591bool ath9k_hw_phy_disable(struct ath_hw *ah);
592bool ath9k_hw_disable(struct ath_hw *ah); 592bool ath9k_hw_disable(struct ath_hw *ah);
593bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit); 593void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
594void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac); 594void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac);
595void ath9k_hw_setopmode(struct ath_hw *ah); 595void ath9k_hw_setopmode(struct ath_hw *ah);
596void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1); 596void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index 5ec9ce91d979..aaa941561c36 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -96,9 +96,8 @@ ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
96 return true; 96 return true;
97} 97}
98 98
99bool 99void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
100ath9k_hw_ar9280_set_channel(struct ath_hw *ah, 100 struct ath9k_channel *chan)
101 struct ath9k_channel *chan)
102{ 101{
103 u16 bMode, fracMode, aModeRefSel = 0; 102 u16 bMode, fracMode, aModeRefSel = 0;
104 u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0; 103 u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
@@ -169,8 +168,6 @@ ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
169 168
170 ah->curchan = chan; 169 ah->curchan = chan;
171 ah->curchan_rad_index = -1; 170 ah->curchan_rad_index = -1;
172
173 return true;
174} 171}
175 172
176static void 173static void
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 296d0e985f25..c70f530642f6 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -17,7 +17,7 @@
17#ifndef PHY_H 17#ifndef PHY_H
18#define PHY_H 18#define PHY_H
19 19
20bool ath9k_hw_ar9280_set_channel(struct ath_hw *ah, 20void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
21 struct ath9k_channel 21 struct ath9k_channel
22 *chan); 22 *chan);
23bool ath9k_hw_set_channel(struct ath_hw *ah, 23bool ath9k_hw_set_channel(struct ath_hw *ah,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 41f1d66cfeba..5b0c6e5bda92 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1110,6 +1110,11 @@ static void iwl3945_nic_config(struct iwl_priv *priv)
1110 1110
1111 spin_lock_irqsave(&priv->lock, flags); 1111 spin_lock_irqsave(&priv->lock, flags);
1112 1112
1113 /* Determine HW type */
1114 pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
1115
1116 IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
1117
1113 if (rev_id & PCI_CFG_REV_ID_BIT_RTP) 1118 if (rev_id & PCI_CFG_REV_ID_BIT_RTP)
1114 IWL_DEBUG_INFO(priv, "RTP type \n"); 1119 IWL_DEBUG_INFO(priv, "RTP type \n");
1115 else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) { 1120 else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {
@@ -1163,7 +1168,6 @@ static void iwl3945_nic_config(struct iwl_priv *priv)
1163 1168
1164int iwl3945_hw_nic_init(struct iwl_priv *priv) 1169int iwl3945_hw_nic_init(struct iwl_priv *priv)
1165{ 1170{
1166 u8 rev_id;
1167 int rc; 1171 int rc;
1168 unsigned long flags; 1172 unsigned long flags;
1169 struct iwl_rx_queue *rxq = &priv->rxq; 1173 struct iwl_rx_queue *rxq = &priv->rxq;
@@ -1172,12 +1176,6 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
1172 priv->cfg->ops->lib->apm_ops.init(priv); 1176 priv->cfg->ops->lib->apm_ops.init(priv);
1173 spin_unlock_irqrestore(&priv->lock, flags); 1177 spin_unlock_irqrestore(&priv->lock, flags);
1174 1178
1175 /* Determine HW type */
1176 rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
1177 if (rc)
1178 return rc;
1179 IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
1180
1181 rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); 1179 rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
1182 if (rc) 1180 if (rc)
1183 return rc; 1181 return rc;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 0a71bb55d0ee..4c88e8715df2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -100,6 +100,7 @@ struct iwl_scale_tbl_info {
100 u8 is_fat; /* 1 = 40 MHz channel width */ 100 u8 is_fat; /* 1 = 40 MHz channel width */
101 u8 is_dup; /* 1 = duplicated data streams */ 101 u8 is_dup; /* 1 = duplicated data streams */
102 u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ 102 u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
103 u8 max_search; /* maximun number of tables we can search */
103 s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ 104 s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
104 u32 current_rate; /* rate_n_flags, uCode API format */ 105 u32 current_rate; /* rate_n_flags, uCode API format */
105 struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ 106 struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
@@ -160,6 +161,7 @@ struct iwl_lq_sta {
160#ifdef CONFIG_MAC80211_DEBUGFS 161#ifdef CONFIG_MAC80211_DEBUGFS
161 struct dentry *rs_sta_dbgfs_scale_table_file; 162 struct dentry *rs_sta_dbgfs_scale_table_file;
162 struct dentry *rs_sta_dbgfs_stats_table_file; 163 struct dentry *rs_sta_dbgfs_stats_table_file;
164 struct dentry *rs_sta_dbgfs_rate_scale_data_file;
163 struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; 165 struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
164 u32 dbg_fixed_rate; 166 u32 dbg_fixed_rate;
165#endif 167#endif
@@ -579,6 +581,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
579 tbl->is_dup = 0; 581 tbl->is_dup = 0;
580 tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS); 582 tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);
581 tbl->lq_type = LQ_NONE; 583 tbl->lq_type = LQ_NONE;
584 tbl->max_search = IWL_MAX_SEARCH;
582 585
583 /* legacy rate format */ 586 /* legacy rate format */
584 if (!(rate_n_flags & RATE_MCS_HT_MSK)) { 587 if (!(rate_n_flags & RATE_MCS_HT_MSK)) {
@@ -612,8 +615,10 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
612 tbl->lq_type = LQ_MIMO2; 615 tbl->lq_type = LQ_MIMO2;
613 /* MIMO3 */ 616 /* MIMO3 */
614 } else { 617 } else {
615 if (num_of_ant == 3) 618 if (num_of_ant == 3) {
619 tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
616 tbl->lq_type = LQ_MIMO3; 620 tbl->lq_type = LQ_MIMO3;
621 }
617 } 622 }
618 } 623 }
619 return 0; 624 return 0;
@@ -771,6 +776,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
771 776
772 tbl->is_fat = 0; 777 tbl->is_fat = 0;
773 tbl->is_SGI = 0; 778 tbl->is_SGI = 0;
779 tbl->max_search = IWL_MAX_SEARCH;
774 } 780 }
775 781
776 rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type); 782 rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type);
@@ -1026,6 +1032,7 @@ static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
1026 lq_sta->total_failed = 0; 1032 lq_sta->total_failed = 0;
1027 lq_sta->total_success = 0; 1033 lq_sta->total_success = 0;
1028 lq_sta->flush_timer = jiffies; 1034 lq_sta->flush_timer = jiffies;
1035 lq_sta->action_counter = 0;
1029} 1036}
1030 1037
1031/* 1038/*
@@ -1205,6 +1212,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
1205 tbl->lq_type = LQ_MIMO2; 1212 tbl->lq_type = LQ_MIMO2;
1206 tbl->is_dup = lq_sta->is_dup; 1213 tbl->is_dup = lq_sta->is_dup;
1207 tbl->action = 0; 1214 tbl->action = 0;
1215 tbl->max_search = IWL_MAX_SEARCH;
1208 rate_mask = lq_sta->active_mimo2_rate; 1216 rate_mask = lq_sta->active_mimo2_rate;
1209 1217
1210 if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap)) 1218 if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
@@ -1270,6 +1278,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv,
1270 tbl->lq_type = LQ_MIMO3; 1278 tbl->lq_type = LQ_MIMO3;
1271 tbl->is_dup = lq_sta->is_dup; 1279 tbl->is_dup = lq_sta->is_dup;
1272 tbl->action = 0; 1280 tbl->action = 0;
1281 tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
1273 rate_mask = lq_sta->active_mimo3_rate; 1282 rate_mask = lq_sta->active_mimo3_rate;
1274 1283
1275 if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap)) 1284 if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
@@ -1328,6 +1337,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
1328 tbl->is_dup = lq_sta->is_dup; 1337 tbl->is_dup = lq_sta->is_dup;
1329 tbl->lq_type = LQ_SISO; 1338 tbl->lq_type = LQ_SISO;
1330 tbl->action = 0; 1339 tbl->action = 0;
1340 tbl->max_search = IWL_MAX_SEARCH;
1331 rate_mask = lq_sta->active_siso_rate; 1341 rate_mask = lq_sta->active_siso_rate;
1332 1342
1333 if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap)) 1343 if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
@@ -1384,15 +1394,15 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1384 u8 valid_tx_ant = priv->hw_params.valid_tx_ant; 1394 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1385 u8 tx_chains_num = priv->hw_params.tx_chains_num; 1395 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1386 int ret = 0; 1396 int ret = 0;
1397 u8 update_search_tbl_counter = 0;
1387 1398
1388 for (; ;) { 1399 for (; ;) {
1400 lq_sta->action_counter++;
1389 switch (tbl->action) { 1401 switch (tbl->action) {
1390 case IWL_LEGACY_SWITCH_ANTENNA1: 1402 case IWL_LEGACY_SWITCH_ANTENNA1:
1391 case IWL_LEGACY_SWITCH_ANTENNA2: 1403 case IWL_LEGACY_SWITCH_ANTENNA2:
1392 IWL_DEBUG_RATE(priv, "LQ: Legacy toggle Antenna\n"); 1404 IWL_DEBUG_RATE(priv, "LQ: Legacy toggle Antenna\n");
1393 1405
1394 lq_sta->action_counter++;
1395
1396 if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 && 1406 if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 &&
1397 tx_chains_num <= 1) || 1407 tx_chains_num <= 1) ||
1398 (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 && 1408 (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 &&
@@ -1408,6 +1418,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1408 1418
1409 if (rs_toggle_antenna(valid_tx_ant, 1419 if (rs_toggle_antenna(valid_tx_ant,
1410 &search_tbl->current_rate, search_tbl)) { 1420 &search_tbl->current_rate, search_tbl)) {
1421 update_search_tbl_counter = 1;
1411 rs_set_expected_tpt_table(lq_sta, search_tbl); 1422 rs_set_expected_tpt_table(lq_sta, search_tbl);
1412 goto out; 1423 goto out;
1413 } 1424 }
@@ -1489,6 +1500,8 @@ out:
1489 tbl->action++; 1500 tbl->action++;
1490 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC) 1501 if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
1491 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; 1502 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1503 if (update_search_tbl_counter)
1504 search_tbl->action = tbl->action;
1492 return 0; 1505 return 0;
1493 1506
1494} 1507}
@@ -1511,6 +1524,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1511 u8 start_action = tbl->action; 1524 u8 start_action = tbl->action;
1512 u8 valid_tx_ant = priv->hw_params.valid_tx_ant; 1525 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1513 u8 tx_chains_num = priv->hw_params.tx_chains_num; 1526 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1527 u8 update_search_tbl_counter = 0;
1514 int ret; 1528 int ret;
1515 1529
1516 for (;;) { 1530 for (;;) {
@@ -1531,8 +1545,10 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1531 1545
1532 memcpy(search_tbl, tbl, sz); 1546 memcpy(search_tbl, tbl, sz);
1533 if (rs_toggle_antenna(valid_tx_ant, 1547 if (rs_toggle_antenna(valid_tx_ant,
1534 &search_tbl->current_rate, search_tbl)) 1548 &search_tbl->current_rate, search_tbl)) {
1549 update_search_tbl_counter = 1;
1535 goto out; 1550 goto out;
1551 }
1536 break; 1552 break;
1537 case IWL_SISO_SWITCH_MIMO2_AB: 1553 case IWL_SISO_SWITCH_MIMO2_AB:
1538 case IWL_SISO_SWITCH_MIMO2_AC: 1554 case IWL_SISO_SWITCH_MIMO2_AC:
@@ -1586,6 +1602,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1586 search_tbl->current_rate = 1602 search_tbl->current_rate =
1587 rate_n_flags_from_tbl(priv, search_tbl, 1603 rate_n_flags_from_tbl(priv, search_tbl,
1588 index, is_green); 1604 index, is_green);
1605 update_search_tbl_counter = 1;
1589 goto out; 1606 goto out;
1590 case IWL_SISO_SWITCH_MIMO3_ABC: 1607 case IWL_SISO_SWITCH_MIMO3_ABC:
1591 IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO3\n"); 1608 IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO3\n");
@@ -1617,6 +1634,9 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1617 tbl->action++; 1634 tbl->action++;
1618 if (tbl->action > IWL_SISO_SWITCH_MIMO3_ABC) 1635 if (tbl->action > IWL_SISO_SWITCH_MIMO3_ABC)
1619 tbl->action = IWL_SISO_SWITCH_ANTENNA1; 1636 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1637 if (update_search_tbl_counter)
1638 search_tbl->action = tbl->action;
1639
1620 return 0; 1640 return 0;
1621} 1641}
1622 1642
@@ -1638,6 +1658,7 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
1638 u8 start_action = tbl->action; 1658 u8 start_action = tbl->action;
1639 u8 valid_tx_ant = priv->hw_params.valid_tx_ant; 1659 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1640 u8 tx_chains_num = priv->hw_params.tx_chains_num; 1660 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1661 u8 update_search_tbl_counter = 0;
1641 int ret; 1662 int ret;
1642 1663
1643 for (;;) { 1664 for (;;) {
@@ -1655,8 +1676,10 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
1655 1676
1656 memcpy(search_tbl, tbl, sz); 1677 memcpy(search_tbl, tbl, sz);
1657 if (rs_toggle_antenna(valid_tx_ant, 1678 if (rs_toggle_antenna(valid_tx_ant,
1658 &search_tbl->current_rate, search_tbl)) 1679 &search_tbl->current_rate, search_tbl)) {
1680 update_search_tbl_counter = 1;
1659 goto out; 1681 goto out;
1682 }
1660 break; 1683 break;
1661 case IWL_MIMO2_SWITCH_SISO_A: 1684 case IWL_MIMO2_SWITCH_SISO_A:
1662 case IWL_MIMO2_SWITCH_SISO_B: 1685 case IWL_MIMO2_SWITCH_SISO_B:
@@ -1713,6 +1736,7 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
1713 search_tbl->current_rate = 1736 search_tbl->current_rate =
1714 rate_n_flags_from_tbl(priv, search_tbl, 1737 rate_n_flags_from_tbl(priv, search_tbl,
1715 index, is_green); 1738 index, is_green);
1739 update_search_tbl_counter = 1;
1716 goto out; 1740 goto out;
1717 1741
1718 case IWL_MIMO2_SWITCH_MIMO3_ABC: 1742 case IWL_MIMO2_SWITCH_MIMO3_ABC:
@@ -1745,6 +1769,9 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
1745 tbl->action++; 1769 tbl->action++;
1746 if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC) 1770 if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC)
1747 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; 1771 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
1772 if (update_search_tbl_counter)
1773 search_tbl->action = tbl->action;
1774
1748 return 0; 1775 return 0;
1749 1776
1750} 1777}
@@ -1768,6 +1795,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
1768 u8 valid_tx_ant = priv->hw_params.valid_tx_ant; 1795 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1769 u8 tx_chains_num = priv->hw_params.tx_chains_num; 1796 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1770 int ret; 1797 int ret;
1798 u8 update_search_tbl_counter = 0;
1771 1799
1772 for (;;) { 1800 for (;;) {
1773 lq_sta->action_counter++; 1801 lq_sta->action_counter++;
@@ -1866,6 +1894,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
1866 search_tbl->current_rate = 1894 search_tbl->current_rate =
1867 rate_n_flags_from_tbl(priv, search_tbl, 1895 rate_n_flags_from_tbl(priv, search_tbl,
1868 index, is_green); 1896 index, is_green);
1897 update_search_tbl_counter = 1;
1869 goto out; 1898 goto out;
1870 } 1899 }
1871 tbl->action++; 1900 tbl->action++;
@@ -1882,6 +1911,9 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
1882 tbl->action++; 1911 tbl->action++;
1883 if (tbl->action > IWL_MIMO3_SWITCH_GI) 1912 if (tbl->action > IWL_MIMO3_SWITCH_GI)
1884 tbl->action = IWL_MIMO3_SWITCH_ANTENNA1; 1913 tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
1914 if (update_search_tbl_counter)
1915 search_tbl->action = tbl->action;
1916
1885 return 0; 1917 return 0;
1886 1918
1887} 1919}
@@ -2326,8 +2358,7 @@ lq_update:
2326 * before next round of mode comparisons. */ 2358 * before next round of mode comparisons. */
2327 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); 2359 tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
2328 if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) && 2360 if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) &&
2329 lq_sta->action_counter >= 1) { 2361 lq_sta->action_counter > tbl1->max_search) {
2330 lq_sta->action_counter = 0;
2331 IWL_DEBUG_RATE(priv, "LQ: STAY in legacy table\n"); 2362 IWL_DEBUG_RATE(priv, "LQ: STAY in legacy table\n");
2332 rs_set_stay_in_table(priv, 1, lq_sta); 2363 rs_set_stay_in_table(priv, 1, lq_sta);
2333 } 2364 }
@@ -2336,7 +2367,7 @@ lq_update:
2336 * have been tried and compared, stay in this best modulation 2367 * have been tried and compared, stay in this best modulation
2337 * mode for a while before next round of mode comparisons. */ 2368 * mode for a while before next round of mode comparisons. */
2338 if (lq_sta->enable_counter && 2369 if (lq_sta->enable_counter &&
2339 (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { 2370 (lq_sta->action_counter >= tbl1->max_search)) {
2340 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && 2371 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
2341 (lq_sta->tx_agg_tid_en & (1 << tid)) && 2372 (lq_sta->tx_agg_tid_en & (1 << tid)) &&
2342 (tid != MAX_TID_COUNT)) { 2373 (tid != MAX_TID_COUNT)) {
@@ -2350,7 +2381,6 @@ lq_update:
2350 lq_sta, sta); 2381 lq_sta, sta);
2351 } 2382 }
2352 } 2383 }
2353 lq_sta->action_counter = 0;
2354 rs_set_stay_in_table(priv, 0, lq_sta); 2384 rs_set_stay_in_table(priv, 0, lq_sta);
2355 } 2385 }
2356 } 2386 }
@@ -2955,6 +2985,43 @@ static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
2955 .open = open_file_generic, 2985 .open = open_file_generic,
2956}; 2986};
2957 2987
2988static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
2989 char __user *user_buf, size_t count, loff_t *ppos)
2990{
2991 char buff[120];
2992 int desc = 0;
2993 ssize_t ret;
2994
2995 struct iwl_lq_sta *lq_sta = file->private_data;
2996 struct iwl_priv *priv;
2997 struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl];
2998
2999 priv = lq_sta->drv;
3000
3001 if (is_Ht(tbl->lq_type))
3002 desc += sprintf(buff+desc,
3003 "Bit Rate= %d Mb/s\n",
3004 tbl->expected_tpt[lq_sta->last_txrate_idx]);
3005 else
3006 desc += sprintf(buff+desc,
3007 "Bit Rate= %d Mb/s\n",
3008 iwl_rates[lq_sta->last_txrate_idx].ieee >> 1);
3009 desc += sprintf(buff+desc,
3010 "Signal Level= %d dBm\tNoise Level= %d dBm\n",
3011 priv->last_rx_rssi, priv->last_rx_noise);
3012 desc += sprintf(buff+desc,
3013 "Tsf= 0x%llx\tBeacon time= 0x%08X\n",
3014 priv->last_tsf, priv->last_beacon_time);
3015
3016 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
3017 return ret;
3018}
3019
3020static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
3021 .read = rs_sta_dbgfs_rate_scale_data_read,
3022 .open = open_file_generic,
3023};
3024
2958static void rs_add_debugfs(void *priv, void *priv_sta, 3025static void rs_add_debugfs(void *priv, void *priv_sta,
2959 struct dentry *dir) 3026 struct dentry *dir)
2960{ 3027{
@@ -2965,6 +3032,9 @@ static void rs_add_debugfs(void *priv, void *priv_sta,
2965 lq_sta->rs_sta_dbgfs_stats_table_file = 3032 lq_sta->rs_sta_dbgfs_stats_table_file =
2966 debugfs_create_file("rate_stats_table", 0600, dir, 3033 debugfs_create_file("rate_stats_table", 0600, dir,
2967 lq_sta, &rs_sta_dbgfs_stats_table_ops); 3034 lq_sta, &rs_sta_dbgfs_stats_table_ops);
3035 lq_sta->rs_sta_dbgfs_rate_scale_data_file =
3036 debugfs_create_file("rate_scale_data", 0600, dir,
3037 lq_sta, &rs_sta_dbgfs_rate_scale_data_ops);
2968 lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = 3038 lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =
2969 debugfs_create_u8("tx_agg_tid_enable", 0600, dir, 3039 debugfs_create_u8("tx_agg_tid_enable", 0600, dir,
2970 &lq_sta->tx_agg_tid_en); 3040 &lq_sta->tx_agg_tid_en);
@@ -2976,6 +3046,7 @@ static void rs_remove_debugfs(void *priv, void *priv_sta)
2976 struct iwl_lq_sta *lq_sta = priv_sta; 3046 struct iwl_lq_sta *lq_sta = priv_sta;
2977 debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); 3047 debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
2978 debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); 3048 debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
3049 debugfs_remove(lq_sta->rs_sta_dbgfs_rate_scale_data_file);
2979 debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file); 3050 debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
2980} 3051}
2981#endif 3052#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
index f875136bc5dc..25050bf315a2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
@@ -275,6 +275,8 @@ enum {
275#define IWL_MIMO3_SWITCH_GI 8 275#define IWL_MIMO3_SWITCH_GI 8
276 276
277 277
278#define IWL_MAX_11N_MIMO3_SEARCH IWL_MIMO3_SWITCH_GI
279#define IWL_MAX_SEARCH IWL_MIMO2_SWITCH_MIMO3_ABC
278 280
279/*FIXME:RS:add possible actions for MIMO3*/ 281/*FIXME:RS:add possible actions for MIMO3*/
280 282
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 6cdee0b4b486..3ebf6cf53a51 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -190,8 +190,7 @@ int iwl_commit_rxon(struct iwl_priv *priv)
190 190
191 priv->cfg->ops->smgmt->clear_station_table(priv); 191 priv->cfg->ops->smgmt->clear_station_table(priv);
192 192
193 if (!priv->error_recovering) 193 priv->start_calib = 0;
194 priv->start_calib = 0;
195 194
196 /* Add the broadcast address so we can send broadcast frames */ 195 /* Add the broadcast address so we can send broadcast frames */
197 if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) == 196 if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) ==
@@ -967,23 +966,6 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv)
967 tasklet_kill(&priv->irq_tasklet); 966 tasklet_kill(&priv->irq_tasklet);
968} 967}
969 968
970static void iwl_error_recovery(struct iwl_priv *priv)
971{
972 unsigned long flags;
973
974 memcpy(&priv->staging_rxon, &priv->recovery_rxon,
975 sizeof(priv->staging_rxon));
976 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
977 iwlcore_commit_rxon(priv);
978
979 iwl_rxon_add_station(priv, priv->bssid, 1);
980
981 spin_lock_irqsave(&priv->lock, flags);
982 priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
983 priv->error_recovering = 0;
984 spin_unlock_irqrestore(&priv->lock, flags);
985}
986
987static void iwl_irq_tasklet(struct iwl_priv *priv) 969static void iwl_irq_tasklet(struct iwl_priv *priv)
988{ 970{
989 u32 inta, handled = 0; 971 u32 inta, handled = 0;
@@ -1514,9 +1496,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
1514 set_bit(STATUS_READY, &priv->status); 1496 set_bit(STATUS_READY, &priv->status);
1515 wake_up_interruptible(&priv->wait_command_queue); 1497 wake_up_interruptible(&priv->wait_command_queue);
1516 1498
1517 if (priv->error_recovering)
1518 iwl_error_recovery(priv);
1519
1520 iwl_power_update_mode(priv, 1); 1499 iwl_power_update_mode(priv, 1);
1521 1500
1522 /* reassociate for ADHOC mode */ 1501 /* reassociate for ADHOC mode */
@@ -1715,9 +1694,6 @@ static int __iwl_up(struct iwl_priv *priv)
1715 continue; 1694 continue;
1716 } 1695 }
1717 1696
1718 /* Clear out the uCode error bit if it is set */
1719 clear_bit(STATUS_FW_ERROR, &priv->status);
1720
1721 /* start card; "initialize" will load runtime ucode */ 1697 /* start card; "initialize" will load runtime ucode */
1722 iwl_nic_start(priv); 1698 iwl_nic_start(priv);
1723 1699
@@ -1812,8 +1788,17 @@ static void iwl_bg_restart(struct work_struct *data)
1812 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 1788 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
1813 return; 1789 return;
1814 1790
1815 iwl_down(priv); 1791 if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
1816 queue_work(priv->workqueue, &priv->up); 1792 mutex_lock(&priv->mutex);
1793 priv->vif = NULL;
1794 priv->is_open = 0;
1795 mutex_unlock(&priv->mutex);
1796 iwl_down(priv);
1797 ieee80211_restart_hw(priv->hw);
1798 } else {
1799 iwl_down(priv);
1800 queue_work(priv->workqueue, &priv->up);
1801 }
1817} 1802}
1818 1803
1819static void iwl_bg_rx_replenish(struct work_struct *data) 1804static void iwl_bg_rx_replenish(struct work_struct *data)
@@ -1853,7 +1838,6 @@ void iwl_post_associate(struct iwl_priv *priv)
1853 if (!priv->vif || !priv->is_open) 1838 if (!priv->vif || !priv->is_open)
1854 return; 1839 return;
1855 1840
1856 iwl_power_cancel_timeout(priv);
1857 iwl_scan_cancel_timeout(priv, 200); 1841 iwl_scan_cancel_timeout(priv, 200);
1858 1842
1859 conf = ieee80211_get_hw_conf(priv->hw); 1843 conf = ieee80211_get_hw_conf(priv->hw);
@@ -1929,7 +1913,7 @@ void iwl_post_associate(struct iwl_priv *priv)
1929 * If chain noise has already been run, then we need to enable 1913 * If chain noise has already been run, then we need to enable
1930 * power management here */ 1914 * power management here */
1931 if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE) 1915 if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
1932 iwl_power_enable_management(priv); 1916 iwl_power_update_mode(priv, 0);
1933 1917
1934 /* Enable Rx differential gain and sensitivity calibrations */ 1918 /* Enable Rx differential gain and sensitivity calibrations */
1935 iwl_chain_noise_reset(priv); 1919 iwl_chain_noise_reset(priv);
@@ -2007,10 +1991,8 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
2007 1991
2008 IWL_DEBUG_MAC80211(priv, "enter\n"); 1992 IWL_DEBUG_MAC80211(priv, "enter\n");
2009 1993
2010 if (!priv->is_open) { 1994 if (!priv->is_open)
2011 IWL_DEBUG_MAC80211(priv, "leave - skip\n");
2012 return; 1995 return;
2013 }
2014 1996
2015 priv->is_open = 0; 1997 priv->is_open = 0;
2016 1998
@@ -2482,32 +2464,37 @@ static ssize_t show_power_level(struct device *d,
2482{ 2464{
2483 struct iwl_priv *priv = dev_get_drvdata(d); 2465 struct iwl_priv *priv = dev_get_drvdata(d);
2484 int mode = priv->power_data.user_power_setting; 2466 int mode = priv->power_data.user_power_setting;
2485 int system = priv->power_data.system_power_setting;
2486 int level = priv->power_data.power_mode; 2467 int level = priv->power_data.power_mode;
2487 char *p = buf; 2468 char *p = buf;
2488 2469
2489 switch (system) { 2470 p += sprintf(p, "INDEX:%d\t", level);
2490 case IWL_POWER_SYS_AUTO: 2471 p += sprintf(p, "USER:%d\n", mode);
2491 p += sprintf(p, "SYSTEM:auto");
2492 break;
2493 case IWL_POWER_SYS_AC:
2494 p += sprintf(p, "SYSTEM:ac");
2495 break;
2496 case IWL_POWER_SYS_BATTERY:
2497 p += sprintf(p, "SYSTEM:battery");
2498 break;
2499 }
2500
2501 p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?
2502 "fixed" : "auto");
2503 p += sprintf(p, "\tINDEX:%d", level);
2504 p += sprintf(p, "\n");
2505 return p - buf + 1; 2472 return p - buf + 1;
2506} 2473}
2507 2474
2508static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, 2475static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
2509 store_power_level); 2476 store_power_level);
2510 2477
2478static ssize_t show_qos(struct device *d,
2479 struct device_attribute *attr, char *buf)
2480{
2481 struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
2482 char *p = buf;
2483 int q;
2484
2485 for (q = 0; q < AC_NUM; q++) {
2486 p += sprintf(p, "\tcw_min\tcw_max\taifsn\ttxop\n");
2487 p += sprintf(p, "AC[%d]\t%u\t%u\t%u\t%u\n", q,
2488 priv->qos_data.def_qos_parm.ac[q].cw_min,
2489 priv->qos_data.def_qos_parm.ac[q].cw_max,
2490 priv->qos_data.def_qos_parm.ac[q].aifsn,
2491 priv->qos_data.def_qos_parm.ac[q].edca_txop);
2492 }
2493
2494 return p - buf + 1;
2495}
2496
2497static DEVICE_ATTR(qos, S_IRUGO, show_qos, NULL);
2511 2498
2512static ssize_t show_statistics(struct device *d, 2499static ssize_t show_statistics(struct device *d,
2513 struct device_attribute *attr, char *buf) 2500 struct device_attribute *attr, char *buf)
@@ -2570,7 +2557,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
2570 INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); 2557 INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
2571 2558
2572 iwl_setup_scan_deferred_work(priv); 2559 iwl_setup_scan_deferred_work(priv);
2573 iwl_setup_power_deferred_work(priv);
2574 2560
2575 if (priv->cfg->ops->lib->setup_deferred_work) 2561 if (priv->cfg->ops->lib->setup_deferred_work)
2576 priv->cfg->ops->lib->setup_deferred_work(priv); 2562 priv->cfg->ops->lib->setup_deferred_work(priv);
@@ -2590,7 +2576,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
2590 2576
2591 cancel_delayed_work_sync(&priv->init_alive_start); 2577 cancel_delayed_work_sync(&priv->init_alive_start);
2592 cancel_delayed_work(&priv->scan_check); 2578 cancel_delayed_work(&priv->scan_check);
2593 cancel_delayed_work_sync(&priv->set_power_save);
2594 cancel_delayed_work(&priv->alive_start); 2579 cancel_delayed_work(&priv->alive_start);
2595 cancel_work_sync(&priv->beacon_update); 2580 cancel_work_sync(&priv->beacon_update);
2596 del_timer_sync(&priv->statistics_periodic); 2581 del_timer_sync(&priv->statistics_periodic);
@@ -2607,7 +2592,7 @@ static struct attribute *iwl_sysfs_entries[] = {
2607 &dev_attr_debug_level.attr, 2592 &dev_attr_debug_level.attr,
2608#endif 2593#endif
2609 &dev_attr_version.attr, 2594 &dev_attr_version.attr,
2610 2595 &dev_attr_qos.attr,
2611 NULL 2596 NULL
2612}; 2597};
2613 2598
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 735f3f19928c..a5d63672ad39 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -857,7 +857,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
857 priv->cfg->ops->lib->update_chain_flags(priv); 857 priv->cfg->ops->lib->update_chain_flags(priv);
858 858
859 data->state = IWL_CHAIN_NOISE_DONE; 859 data->state = IWL_CHAIN_NOISE_DONE;
860 iwl_power_enable_management(priv); 860 iwl_power_update_mode(priv, 0);
861} 861}
862EXPORT_SYMBOL(iwl_chain_noise_calibration); 862EXPORT_SYMBOL(iwl_chain_noise_calibration);
863 863
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 1366222bb50a..5393fb3f452c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -273,6 +273,14 @@ void iwl_activate_qos(struct iwl_priv *priv, u8 force)
273} 273}
274EXPORT_SYMBOL(iwl_activate_qos); 274EXPORT_SYMBOL(iwl_activate_qos);
275 275
276/*
277 * AC CWmin CW max AIFSN TXOP Limit TXOP Limit
278 * (802.11b) (802.11a/g)
279 * AC_BK 15 1023 7 0 0
280 * AC_BE 15 1023 3 0 0
281 * AC_VI 7 15 2 6.016ms 3.008ms
282 * AC_VO 3 7 2 3.264ms 1.504ms
283 */
276void iwl_reset_qos(struct iwl_priv *priv) 284void iwl_reset_qos(struct iwl_priv *priv)
277{ 285{
278 u16 cw_min = 15; 286 u16 cw_min = 15;
@@ -304,6 +312,7 @@ void iwl_reset_qos(struct iwl_priv *priv)
304 if (priv->qos_data.qos_active) 312 if (priv->qos_data.qos_active)
305 aifs = 3; 313 aifs = 3;
306 314
315 /* AC_BE */
307 priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min); 316 priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min);
308 priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max); 317 priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max);
309 priv->qos_data.def_qos_parm.ac[0].aifsn = aifs; 318 priv->qos_data.def_qos_parm.ac[0].aifsn = aifs;
@@ -311,6 +320,7 @@ void iwl_reset_qos(struct iwl_priv *priv)
311 priv->qos_data.def_qos_parm.ac[0].reserved1 = 0; 320 priv->qos_data.def_qos_parm.ac[0].reserved1 = 0;
312 321
313 if (priv->qos_data.qos_active) { 322 if (priv->qos_data.qos_active) {
323 /* AC_BK */
314 i = 1; 324 i = 1;
315 priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min); 325 priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min);
316 priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max); 326 priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max);
@@ -318,11 +328,12 @@ void iwl_reset_qos(struct iwl_priv *priv)
318 priv->qos_data.def_qos_parm.ac[i].edca_txop = 0; 328 priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
319 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0; 329 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
320 330
331 /* AC_VI */
321 i = 2; 332 i = 2;
322 priv->qos_data.def_qos_parm.ac[i].cw_min = 333 priv->qos_data.def_qos_parm.ac[i].cw_min =
323 cpu_to_le16((cw_min + 1) / 2 - 1); 334 cpu_to_le16((cw_min + 1) / 2 - 1);
324 priv->qos_data.def_qos_parm.ac[i].cw_max = 335 priv->qos_data.def_qos_parm.ac[i].cw_max =
325 cpu_to_le16(cw_max); 336 cpu_to_le16(cw_min);
326 priv->qos_data.def_qos_parm.ac[i].aifsn = 2; 337 priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
327 if (is_legacy) 338 if (is_legacy)
328 priv->qos_data.def_qos_parm.ac[i].edca_txop = 339 priv->qos_data.def_qos_parm.ac[i].edca_txop =
@@ -332,11 +343,12 @@ void iwl_reset_qos(struct iwl_priv *priv)
332 cpu_to_le16(3008); 343 cpu_to_le16(3008);
333 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0; 344 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
334 345
346 /* AC_VO */
335 i = 3; 347 i = 3;
336 priv->qos_data.def_qos_parm.ac[i].cw_min = 348 priv->qos_data.def_qos_parm.ac[i].cw_min =
337 cpu_to_le16((cw_min + 1) / 4 - 1); 349 cpu_to_le16((cw_min + 1) / 4 - 1);
338 priv->qos_data.def_qos_parm.ac[i].cw_max = 350 priv->qos_data.def_qos_parm.ac[i].cw_max =
339 cpu_to_le16((cw_max + 1) / 2 - 1); 351 cpu_to_le16((cw_min + 1) / 2 - 1);
340 priv->qos_data.def_qos_parm.ac[i].aifsn = 2; 352 priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
341 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0; 353 priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
342 if (is_legacy) 354 if (is_legacy)
@@ -960,10 +972,10 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
960 if (iwl_is_monitor_mode(priv) && 972 if (iwl_is_monitor_mode(priv) &&
961 !(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) && 973 !(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) &&
962 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)) { 974 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)) {
963 rx_chain = 0x07 << RXON_RX_CHAIN_VALID_POS; 975 rx_chain = ANT_ABC << RXON_RX_CHAIN_VALID_POS;
964 rx_chain |= 0x06 << RXON_RX_CHAIN_FORCE_SEL_POS; 976 rx_chain |= ANT_BC << RXON_RX_CHAIN_FORCE_SEL_POS;
965 rx_chain |= 0x07 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; 977 rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
966 rx_chain |= 0x01 << RXON_RX_CHAIN_DRIVER_FORCE_POS; 978 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
967 } 979 }
968 980
969 priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain); 981 priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);
@@ -1120,7 +1132,7 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
1120} 1132}
1121EXPORT_SYMBOL(iwl_connection_init_rx_config); 1133EXPORT_SYMBOL(iwl_connection_init_rx_config);
1122 1134
1123void iwl_set_rate(struct iwl_priv *priv) 1135static void iwl_set_rate(struct iwl_priv *priv)
1124{ 1136{
1125 const struct ieee80211_supported_band *hw = NULL; 1137 const struct ieee80211_supported_band *hw = NULL;
1126 struct ieee80211_rate *rate; 1138 struct ieee80211_rate *rate;
@@ -1166,7 +1178,6 @@ void iwl_set_rate(struct iwl_priv *priv)
1166 priv->staging_rxon.ofdm_basic_rates = 1178 priv->staging_rxon.ofdm_basic_rates =
1167 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; 1179 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
1168} 1180}
1169EXPORT_SYMBOL(iwl_set_rate);
1170 1181
1171void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) 1182void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1172{ 1183{
@@ -1230,11 +1241,6 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
1230 IWL_DEBUG(priv, IWL_DL_FW_ERRORS, 1241 IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
1231 "Restarting adapter due to uCode error.\n"); 1242 "Restarting adapter due to uCode error.\n");
1232 1243
1233 if (iwl_is_associated(priv)) {
1234 memcpy(&priv->recovery_rxon, &priv->active_rxon,
1235 sizeof(priv->recovery_rxon));
1236 priv->error_recovering = 1;
1237 }
1238 if (priv->cfg->mod_params->restart_fw) 1244 if (priv->cfg->mod_params->restart_fw)
1239 queue_work(priv->workqueue, &priv->restart); 1245 queue_work(priv->workqueue, &priv->restart);
1240 } 1246 }
@@ -1358,7 +1364,6 @@ int iwl_init_drv(struct iwl_priv *priv)
1358 priv->ibss_beacon = NULL; 1364 priv->ibss_beacon = NULL;
1359 1365
1360 spin_lock_init(&priv->lock); 1366 spin_lock_init(&priv->lock);
1361 spin_lock_init(&priv->power_data.lock);
1362 spin_lock_init(&priv->sta_lock); 1367 spin_lock_init(&priv->sta_lock);
1363 spin_lock_init(&priv->hcmd_lock); 1368 spin_lock_init(&priv->hcmd_lock);
1364 1369
@@ -2226,9 +2231,9 @@ static void iwl_ht_conf(struct iwl_priv *priv,
2226 2231
2227 iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0; 2232 iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0;
2228 iwl_conf->ht_protection = 2233 iwl_conf->ht_protection =
2229 bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; 2234 bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
2230 iwl_conf->non_GF_STA_present = 2235 iwl_conf->non_GF_STA_present =
2231 !!(bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); 2236 !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
2232 2237
2233 rcu_read_unlock(); 2238 rcu_read_unlock();
2234 2239
@@ -2582,14 +2587,13 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2582 iwl_set_rate(priv); 2587 iwl_set_rate(priv);
2583 } 2588 }
2584 2589
2585 if (changed & IEEE80211_CONF_CHANGE_PS) { 2590 if (changed & IEEE80211_CONF_CHANGE_PS &&
2586 if (conf->flags & IEEE80211_CONF_PS) 2591 priv->iw_mode == NL80211_IFTYPE_STATION) {
2587 ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3); 2592 priv->power_data.power_disabled =
2588 else 2593 !(conf->flags & IEEE80211_CONF_PS);
2589 ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM); 2594 ret = iwl_power_update_mode(priv, 0);
2590 if (ret) 2595 if (ret)
2591 IWL_DEBUG_MAC80211(priv, "Error setting power level\n"); 2596 IWL_DEBUG_MAC80211(priv, "Error setting power level\n");
2592
2593 } 2597 }
2594 2598
2595 if (changed & IEEE80211_CONF_CHANGE_POWER) { 2599 if (changed & IEEE80211_CONF_CHANGE_POWER) {
@@ -2725,21 +2729,7 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2725 iwlcore_commit_rxon(priv); 2729 iwlcore_commit_rxon(priv);
2726 } 2730 }
2727 2731
2728 iwl_power_update_mode(priv, 0);
2729
2730 /* Per mac80211.h: This is only used in IBSS mode... */
2731 if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { 2732 if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
2732
2733 /* switch to CAM during association period.
2734 * the ucode will block any association/authentication
2735 * frome during assiciation period if it can not hear
2736 * the AP because of PM. the timer enable PM back is
2737 * association do not complete
2738 */
2739 if (priv->hw->conf.channel->flags &
2740 (IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_RADAR))
2741 iwl_power_disable_management(priv, 3000);
2742
2743 IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n"); 2733 IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
2744 mutex_unlock(&priv->mutex); 2734 mutex_unlock(&priv->mutex);
2745 return; 2735 return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index bd7f9d9616bc..f3544ea559a2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -363,8 +363,6 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
363 363
364u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv); 364u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv);
365 365
366void iwl_set_rate(struct iwl_priv *priv);
367
368u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx); 366u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx);
369 367
370static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) 368static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 5aa76a706320..3049ba25c3fc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -933,7 +933,6 @@ struct iwl_priv {
933 const struct iwl_rxon_cmd active_rxon; 933 const struct iwl_rxon_cmd active_rxon;
934 struct iwl_rxon_cmd staging_rxon; 934 struct iwl_rxon_cmd staging_rxon;
935 935
936 int error_recovering;
937 struct iwl_rxon_cmd recovery_rxon; 936 struct iwl_rxon_cmd recovery_rxon;
938 937
939 /* 1st responses from initialize and runtime uCode images. 938 /* 1st responses from initialize and runtime uCode images.
@@ -1076,7 +1075,6 @@ struct iwl_priv {
1076 1075
1077 struct tasklet_struct irq_tasklet; 1076 struct tasklet_struct irq_tasklet;
1078 1077
1079 struct delayed_work set_power_save;
1080 struct delayed_work init_alive_start; 1078 struct delayed_work init_alive_start;
1081 struct delayed_work alive_start; 1079 struct delayed_work alive_start;
1082 struct delayed_work scan_check; 1080 struct delayed_work scan_check;
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 75517d05df08..401438aec19c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -285,7 +285,7 @@ int iwl_eeprom_check_version(struct iwl_priv *priv)
285 285
286 return 0; 286 return 0;
287err: 287err:
288 IWL_ERR(priv, "Unsupported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n", 288 IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
289 eeprom_ver, priv->cfg->eeprom_ver, 289 eeprom_ver, priv->cfg->eeprom_ver,
290 calib_ver, priv->cfg->eeprom_calib_ver); 290 calib_ver, priv->cfg->eeprom_calib_ver);
291 return -EINVAL; 291 return -EINVAL;
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 47c894530eb5..f2ea3f05f6e1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -41,38 +41,33 @@
41#include "iwl-power.h" 41#include "iwl-power.h"
42 42
43/* 43/*
44 * Setting power level allow the card to go to sleep when not busy 44 * Setting power level allow the card to go to sleep when not busy.
45 * there are three factor that decide the power level to go to, they
46 * are list here with its priority
47 * 1- critical_power_setting this will be set according to card temperature.
48 * 2- system_power_setting this will be set by system PM manager.
49 * 3- user_power_setting this will be set by user either by writing to sys or
50 * mac80211
51 * 45 *
52 * if system_power_setting and user_power_setting is set to auto 46 * The power level is set to INDEX_1 (the least deep state) by
53 * the power level will be decided according to association status and battery 47 * default, and will, in the future, be the deepest state unless
54 * status. 48 * otherwise required by pm_qos network latency requirements.
55 * 49 *
50 * Using INDEX_1 without pm_qos is ok because mac80211 will disable
51 * PS when even checking every beacon for the TIM bit would exceed
52 * the required latency.
56 */ 53 */
57 54
58#define MSEC_TO_USEC 1024
59#define IWL_POWER_RANGE_0_MAX (2) 55#define IWL_POWER_RANGE_0_MAX (2)
60#define IWL_POWER_RANGE_1_MAX (10) 56#define IWL_POWER_RANGE_1_MAX (10)
61 57
62 58
63 59#define NOSLP cpu_to_le16(0), 0, 0
64#define IWL_POWER_ON_BATTERY IWL_POWER_INDEX_5 60#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
65#define IWL_POWER_ON_AC_DISASSOC IWL_POWER_MODE_CAM 61#define TU_TO_USEC 1024
66#define IWL_POWER_ON_AC_ASSOC IWL_POWER_MODE_CAM 62#define SLP_TOUT(T) cpu_to_le32((T) * TU_TO_USEC)
67 63#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \
68 64 cpu_to_le32(X1), \
69#define IWL_CT_KILL_TEMPERATURE 110 65 cpu_to_le32(X2), \
70#define IWL_MIN_POWER_TEMPERATURE 100 66 cpu_to_le32(X3), \
71#define IWL_REDUCED_POWER_TEMPERATURE 95 67 cpu_to_le32(X4)}
72
73/* default power management (not Tx power) table values */ 68/* default power management (not Tx power) table values */
74/* for TIM 0-10 */ 69/* for DTIM period 0 through IWL_POWER_RANGE_0_MAX */
75static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = { 70static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = {
76 {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, 71 {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
77 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, 72 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
78 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0}, 73 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
@@ -82,8 +77,8 @@ static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = {
82}; 77};
83 78
84 79
85/* for TIM = 3-10 */ 80/* for DTIM period IWL_POWER_RANGE_0_MAX + 1 through IWL_POWER_RANGE_1_MAX */
86static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = { 81static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = {
87 {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, 82 {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
88 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0}, 83 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
89 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0}, 84 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0},
@@ -92,8 +87,8 @@ static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = {
92 {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2} 87 {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2}
93}; 88};
94 89
95/* for TIM > 11 */ 90/* for DTIM period > IWL_POWER_RANGE_1_MAX */
96static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = { 91static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = {
97 {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0}, 92 {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
98 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0}, 93 {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
99 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0}, 94 {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
@@ -106,39 +101,15 @@ static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = {
106/* set card power command */ 101/* set card power command */
107static int iwl_set_power(struct iwl_priv *priv, void *cmd) 102static int iwl_set_power(struct iwl_priv *priv, void *cmd)
108{ 103{
109 return iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD, 104 return iwl_send_cmd_pdu(priv, POWER_TABLE_CMD,
110 sizeof(struct iwl_powertable_cmd), 105 sizeof(struct iwl_powertable_cmd), cmd);
111 cmd, NULL);
112}
113/* decide the right power level according to association status
114 * and battery status
115 */
116static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
117{
118 u16 mode;
119
120 switch (priv->power_data.user_power_setting) {
121 case IWL_POWER_AUTO:
122 /* if running on battery */
123 if (priv->power_data.is_battery_active)
124 mode = IWL_POWER_ON_BATTERY;
125 else if (iwl_is_associated(priv))
126 mode = IWL_POWER_ON_AC_ASSOC;
127 else
128 mode = IWL_POWER_ON_AC_DISASSOC;
129 break;
130 default:
131 mode = priv->power_data.user_power_setting;
132 break;
133 }
134 return mode;
135} 106}
136 107
137/* initialize to default */ 108/* initialize to default */
138static void iwl_power_init_handle(struct iwl_priv *priv) 109static void iwl_power_init_handle(struct iwl_priv *priv)
139{ 110{
140 struct iwl_power_mgr *pow_data; 111 struct iwl_power_mgr *pow_data;
141 int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX; 112 int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_NUM;
142 struct iwl_powertable_cmd *cmd; 113 struct iwl_powertable_cmd *cmd;
143 int i; 114 int i;
144 u16 lctl; 115 u16 lctl;
@@ -157,7 +128,7 @@ static void iwl_power_init_handle(struct iwl_priv *priv)
157 128
158 IWL_DEBUG_POWER(priv, "adjust power command flags\n"); 129 IWL_DEBUG_POWER(priv, "adjust power command flags\n");
159 130
160 for (i = 0; i < IWL_POWER_MAX; i++) { 131 for (i = 0; i < IWL_POWER_NUM; i++) {
161 cmd = &pow_data->pwr_range_0[i].cmd; 132 cmd = &pow_data->pwr_range_0[i].cmd;
162 133
163 if (lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN) 134 if (lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN)
@@ -247,33 +218,12 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
247 update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE || 218 update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
248 priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE; 219 priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
249 220
250 /* If on battery, set to 3, 221 final_mode = priv->power_data.user_power_setting;
251 * if plugged into AC power, set to CAM ("continuously aware mode"),
252 * else user level */
253
254 switch (setting->system_power_setting) {
255 case IWL_POWER_SYS_AUTO:
256 final_mode = iwl_get_auto_power_mode(priv);
257 break;
258 case IWL_POWER_SYS_BATTERY:
259 final_mode = IWL_POWER_INDEX_3;
260 break;
261 case IWL_POWER_SYS_AC:
262 final_mode = IWL_POWER_MODE_CAM;
263 break;
264 default:
265 final_mode = IWL_POWER_INDEX_3;
266 WARN_ON(1);
267 }
268
269 if (setting->critical_power_setting > final_mode)
270 final_mode = setting->critical_power_setting;
271 222
272 /* driver only support CAM for non STA network */ 223 if (setting->power_disabled)
273 if (priv->iw_mode != NL80211_IFTYPE_STATION)
274 final_mode = IWL_POWER_MODE_CAM; 224 final_mode = IWL_POWER_MODE_CAM;
275 225
276 if (iwl_is_ready_rf(priv) && !setting->power_disabled && 226 if (iwl_is_ready_rf(priv) &&
277 ((setting->power_mode != final_mode) || force)) { 227 ((setting->power_mode != final_mode) || force)) {
278 struct iwl_powertable_cmd cmd; 228 struct iwl_powertable_cmd cmd;
279 229
@@ -290,8 +240,6 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
290 240
291 if (final_mode == IWL_POWER_MODE_CAM) 241 if (final_mode == IWL_POWER_MODE_CAM)
292 clear_bit(STATUS_POWER_PMI, &priv->status); 242 clear_bit(STATUS_POWER_PMI, &priv->status);
293 else
294 set_bit(STATUS_POWER_PMI, &priv->status);
295 243
296 if (priv->cfg->ops->lib->update_chain_flags && update_chains) 244 if (priv->cfg->ops->lib->update_chain_flags && update_chains)
297 priv->cfg->ops->lib->update_chain_flags(priv); 245 priv->cfg->ops->lib->update_chain_flags(priv);
@@ -307,51 +255,10 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
307} 255}
308EXPORT_SYMBOL(iwl_power_update_mode); 256EXPORT_SYMBOL(iwl_power_update_mode);
309 257
310/* Allow other iwl code to disable/enable power management active
311 * this will be useful for rate scale to disable PM during heavy
312 * Tx/Rx activities
313 */
314int iwl_power_disable_management(struct iwl_priv *priv, u32 ms)
315{
316 u16 prev_mode;
317 int ret = 0;
318
319 if (priv->power_data.power_disabled)
320 return -EBUSY;
321
322 prev_mode = priv->power_data.user_power_setting;
323 priv->power_data.user_power_setting = IWL_POWER_MODE_CAM;
324 ret = iwl_power_update_mode(priv, 0);
325 priv->power_data.power_disabled = 1;
326 priv->power_data.user_power_setting = prev_mode;
327 cancel_delayed_work(&priv->set_power_save);
328 if (ms)
329 queue_delayed_work(priv->workqueue, &priv->set_power_save,
330 msecs_to_jiffies(ms));
331
332
333 return ret;
334}
335EXPORT_SYMBOL(iwl_power_disable_management);
336
337/* Allow other iwl code to disable/enable power management active
338 * this will be useful for rate scale to disable PM during high
339 * volume activities
340 */
341int iwl_power_enable_management(struct iwl_priv *priv)
342{
343 int ret = 0;
344
345 priv->power_data.power_disabled = 0;
346 ret = iwl_power_update_mode(priv, 0);
347 return ret;
348}
349EXPORT_SYMBOL(iwl_power_enable_management);
350
351/* set user_power_setting */ 258/* set user_power_setting */
352int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode) 259int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
353{ 260{
354 if (mode > IWL_POWER_MAX) 261 if (mode >= IWL_POWER_NUM)
355 return -EINVAL; 262 return -EINVAL;
356 263
357 priv->power_data.user_power_setting = mode; 264 priv->power_data.user_power_setting = mode;
@@ -360,86 +267,12 @@ int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
360} 267}
361EXPORT_SYMBOL(iwl_power_set_user_mode); 268EXPORT_SYMBOL(iwl_power_set_user_mode);
362 269
363/* set system_power_setting. This should be set by over all
364 * PM application.
365 */
366int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode)
367{
368 if (mode < IWL_POWER_SYS_MAX)
369 priv->power_data.system_power_setting = mode;
370 else
371 return -EINVAL;
372 return iwl_power_update_mode(priv, 0);
373}
374EXPORT_SYMBOL(iwl_power_set_system_mode);
375
376/* initialize to default */ 270/* initialize to default */
377void iwl_power_initialize(struct iwl_priv *priv) 271void iwl_power_initialize(struct iwl_priv *priv)
378{ 272{
379 iwl_power_init_handle(priv); 273 iwl_power_init_handle(priv);
380 priv->power_data.user_power_setting = IWL_POWER_AUTO; 274 priv->power_data.user_power_setting = IWL_POWER_INDEX_1;
381 priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO; 275 /* default to disabled until mac80211 says otherwise */
382 priv->power_data.power_disabled = 0; 276 priv->power_data.power_disabled = 1;
383 priv->power_data.is_battery_active = 0;
384 priv->power_data.critical_power_setting = 0;
385} 277}
386EXPORT_SYMBOL(iwl_power_initialize); 278EXPORT_SYMBOL(iwl_power_initialize);
387
388/* set critical_power_setting according to temperature value */
389int iwl_power_temperature_change(struct iwl_priv *priv)
390{
391 int ret = 0;
392 s32 temperature = KELVIN_TO_CELSIUS(priv->last_temperature);
393 u16 new_critical = priv->power_data.critical_power_setting;
394
395 if (temperature > IWL_CT_KILL_TEMPERATURE)
396 return 0;
397 else if (temperature > IWL_MIN_POWER_TEMPERATURE)
398 new_critical = IWL_POWER_INDEX_5;
399 else if (temperature > IWL_REDUCED_POWER_TEMPERATURE)
400 new_critical = IWL_POWER_INDEX_3;
401 else
402 new_critical = IWL_POWER_MODE_CAM;
403
404 if (new_critical != priv->power_data.critical_power_setting)
405 priv->power_data.critical_power_setting = new_critical;
406
407 if (priv->power_data.critical_power_setting >
408 priv->power_data.power_mode)
409 ret = iwl_power_update_mode(priv, 0);
410
411 return ret;
412}
413EXPORT_SYMBOL(iwl_power_temperature_change);
414
415static void iwl_bg_set_power_save(struct work_struct *work)
416{
417 struct iwl_priv *priv = container_of(work,
418 struct iwl_priv, set_power_save.work);
419 IWL_DEBUG_POWER(priv, "update power\n");
420
421 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
422 return;
423
424 mutex_lock(&priv->mutex);
425
426 /* on starting association we disable power management
427 * until association, if association failed then this
428 * timer will expire and enable PM again.
429 */
430 if (!iwl_is_associated(priv))
431 iwl_power_enable_management(priv);
432
433 mutex_unlock(&priv->mutex);
434}
435void iwl_setup_power_deferred_work(struct iwl_priv *priv)
436{
437 INIT_DELAYED_WORK(&priv->set_power_save, iwl_bg_set_power_save);
438}
439EXPORT_SYMBOL(iwl_setup_power_deferred_work);
440
441void iwl_power_cancel_timeout(struct iwl_priv *priv)
442{
443 cancel_delayed_work(&priv->set_power_save);
444}
445EXPORT_SYMBOL(iwl_power_cancel_timeout);
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index 18963392121e..37ba3bb7a25a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -40,56 +40,29 @@ enum {
40 IWL_POWER_INDEX_3, 40 IWL_POWER_INDEX_3,
41 IWL_POWER_INDEX_4, 41 IWL_POWER_INDEX_4,
42 IWL_POWER_INDEX_5, 42 IWL_POWER_INDEX_5,
43 IWL_POWER_AUTO, 43 IWL_POWER_NUM
44 IWL_POWER_MAX = IWL_POWER_AUTO,
45}; 44};
46 45
47enum {
48 IWL_POWER_SYS_AUTO,
49 IWL_POWER_SYS_AC,
50 IWL_POWER_SYS_BATTERY,
51 IWL_POWER_SYS_MAX,
52};
53
54
55/* Power management (not Tx power) structures */ 46/* Power management (not Tx power) structures */
56 47
57#define NOSLP cpu_to_le16(0), 0, 0
58#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
59#define SLP_TOUT(T) cpu_to_le32((T) * MSEC_TO_USEC)
60#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \
61 cpu_to_le32(X1), \
62 cpu_to_le32(X2), \
63 cpu_to_le32(X3), \
64 cpu_to_le32(X4)}
65struct iwl_power_vec_entry { 48struct iwl_power_vec_entry {
66 struct iwl_powertable_cmd cmd; 49 struct iwl_powertable_cmd cmd;
67 u8 no_dtim; 50 u8 no_dtim;
68}; 51};
69 52
70struct iwl_power_mgr { 53struct iwl_power_mgr {
71 spinlock_t lock; 54 struct iwl_power_vec_entry pwr_range_0[IWL_POWER_NUM];
72 struct iwl_power_vec_entry pwr_range_0[IWL_POWER_MAX]; 55 struct iwl_power_vec_entry pwr_range_1[IWL_POWER_NUM];
73 struct iwl_power_vec_entry pwr_range_1[IWL_POWER_MAX]; 56 struct iwl_power_vec_entry pwr_range_2[IWL_POWER_NUM];
74 struct iwl_power_vec_entry pwr_range_2[IWL_POWER_MAX];
75 u32 dtim_period; 57 u32 dtim_period;
76 /* final power level that used to calculate final power command */ 58 /* final power level that used to calculate final power command */
77 u8 power_mode; 59 u8 power_mode;
78 u8 user_power_setting; /* set by user through mac80211 or sysfs */ 60 u8 user_power_setting; /* set by user through sysfs */
79 u8 system_power_setting; /* set by kernel system tools */ 61 u8 power_disabled; /* set by mac80211's CONF_PS */
80 u8 critical_power_setting; /* set if driver over heated */
81 u8 is_battery_active; /* DC/AC power */
82 u8 power_disabled; /* flag to disable using power saving level */
83}; 62};
84 63
85void iwl_setup_power_deferred_work(struct iwl_priv *priv);
86void iwl_power_cancel_timeout(struct iwl_priv *priv);
87int iwl_power_update_mode(struct iwl_priv *priv, bool force); 64int iwl_power_update_mode(struct iwl_priv *priv, bool force);
88int iwl_power_disable_management(struct iwl_priv *priv, u32 ms);
89int iwl_power_enable_management(struct iwl_priv *priv);
90int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode); 65int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
91int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode);
92void iwl_power_initialize(struct iwl_priv *priv); 66void iwl_power_initialize(struct iwl_priv *priv);
93int iwl_power_temperature_change(struct iwl_priv *priv);
94 67
95#endif /* __iwl_power_setting_h__ */ 68#endif /* __iwl_power_setting_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index dd8766b80b34..065214b55895 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -580,9 +580,10 @@ static void iwl_bg_request_scan(struct work_struct *data)
580 int ret = 0; 580 int ret = 0;
581 u32 rate_flags = 0; 581 u32 rate_flags = 0;
582 u16 cmd_len; 582 u16 cmd_len;
583 u16 rx_chain = 0;
583 enum ieee80211_band band; 584 enum ieee80211_band band;
584 u8 n_probes = 0; 585 u8 n_probes = 0;
585 u8 rx_chain = priv->hw_params.valid_rx_ant; 586 u8 rx_ant = priv->hw_params.valid_rx_ant;
586 u8 rate; 587 u8 rate;
587 bool is_active = false; 588 bool is_active = false;
588 589
@@ -723,7 +724,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
723 * Avoid A (0x1) because of its off-channel reception on A-band. 724 * Avoid A (0x1) because of its off-channel reception on A-band.
724 */ 725 */
725 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) 726 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
726 rx_chain = 0x6; 727 rx_ant = ANT_BC;
727 } else { 728 } else {
728 IWL_WARN(priv, "Invalid scan band count\n"); 729 IWL_WARN(priv, "Invalid scan band count\n");
729 goto done; 730 goto done;
@@ -735,10 +736,11 @@ static void iwl_bg_request_scan(struct work_struct *data)
735 scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags); 736 scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
736 737
737 /* MIMO is not used here, but value is required */ 738 /* MIMO is not used here, but value is required */
738 scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK | 739 rx_chain |= ANT_ABC << RXON_RX_CHAIN_VALID_POS;
739 cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) | 740 rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
740 (rx_chain << RXON_RX_CHAIN_FORCE_SEL_POS) | 741 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
741 (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS)); 742 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
743 scan->rx_chain = cpu_to_le16(rx_chain);
742 cmd_len = iwl_fill_probe_req(priv, 744 cmd_len = iwl_fill_probe_req(priv,
743 (struct ieee80211_mgmt *)scan->data, 745 (struct ieee80211_mgmt *)scan->data,
744 priv->scan_request->ie, 746 priv->scan_request->ie,
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index f6c1489a0c4a..c32ec809053f 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1837,23 +1837,6 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
1837 iwl_release_nic_access(priv); 1837 iwl_release_nic_access(priv);
1838} 1838}
1839 1839
1840static void iwl3945_error_recovery(struct iwl_priv *priv)
1841{
1842 unsigned long flags;
1843
1844 memcpy(&priv->staging_rxon, &priv->recovery_rxon,
1845 sizeof(priv->staging_rxon));
1846 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1847 iwlcore_commit_rxon(priv);
1848
1849 priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 1, 0, NULL);
1850
1851 spin_lock_irqsave(&priv->lock, flags);
1852 priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
1853 priv->error_recovering = 0;
1854 spin_unlock_irqrestore(&priv->lock, flags);
1855}
1856
1857static void iwl3945_irq_tasklet(struct iwl_priv *priv) 1840static void iwl3945_irq_tasklet(struct iwl_priv *priv)
1858{ 1841{
1859 u32 inta, handled = 0; 1842 u32 inta, handled = 0;
@@ -2683,9 +2666,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2683 /* After the ALIVE response, we can send commands to 3945 uCode */ 2666 /* After the ALIVE response, we can send commands to 3945 uCode */
2684 set_bit(STATUS_ALIVE, &priv->status); 2667 set_bit(STATUS_ALIVE, &priv->status);
2685 2668
2686 /* Clear out the uCode error bit if it is set */
2687 clear_bit(STATUS_FW_ERROR, &priv->status);
2688
2689 if (iwl_is_rfkill(priv)) 2669 if (iwl_is_rfkill(priv))
2690 return; 2670 return;
2691 2671
@@ -2722,9 +2702,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2722 set_bit(STATUS_READY, &priv->status); 2702 set_bit(STATUS_READY, &priv->status);
2723 wake_up_interruptible(&priv->wait_command_queue); 2703 wake_up_interruptible(&priv->wait_command_queue);
2724 2704
2725 if (priv->error_recovering)
2726 iwl3945_error_recovery(priv);
2727
2728 /* reassociate for ADHOC mode */ 2705 /* reassociate for ADHOC mode */
2729 if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) { 2706 if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
2730 struct sk_buff *beacon = ieee80211_beacon_get(priv->hw, 2707 struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
@@ -3231,8 +3208,17 @@ static void iwl3945_bg_restart(struct work_struct *data)
3231 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3208 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3232 return; 3209 return;
3233 3210
3234 iwl3945_down(priv); 3211 if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
3235 queue_work(priv->workqueue, &priv->up); 3212 mutex_lock(&priv->mutex);
3213 priv->vif = NULL;
3214 priv->is_open = 0;
3215 mutex_unlock(&priv->mutex);
3216 iwl3945_down(priv);
3217 ieee80211_restart_hw(priv->hw);
3218 } else {
3219 iwl3945_down(priv);
3220 queue_work(priv->workqueue, &priv->up);
3221 }
3236} 3222}
3237 3223
3238static void iwl3945_bg_rx_replenish(struct work_struct *data) 3224static void iwl3945_bg_rx_replenish(struct work_struct *data)
@@ -3859,26 +3845,11 @@ static ssize_t show_power_level(struct device *d,
3859{ 3845{
3860 struct iwl_priv *priv = dev_get_drvdata(d); 3846 struct iwl_priv *priv = dev_get_drvdata(d);
3861 int mode = priv->power_data.user_power_setting; 3847 int mode = priv->power_data.user_power_setting;
3862 int system = priv->power_data.system_power_setting;
3863 int level = priv->power_data.power_mode; 3848 int level = priv->power_data.power_mode;
3864 char *p = buf; 3849 char *p = buf;
3865 3850
3866 switch (system) { 3851 p += sprintf(p, "INDEX:%d\t", level);
3867 case IWL_POWER_SYS_AUTO: 3852 p += sprintf(p, "USER:%d\n", mode);
3868 p += sprintf(p, "SYSTEM:auto");
3869 break;
3870 case IWL_POWER_SYS_AC:
3871 p += sprintf(p, "SYSTEM:ac");
3872 break;
3873 case IWL_POWER_SYS_BATTERY:
3874 p += sprintf(p, "SYSTEM:battery");
3875 break;
3876 }
3877
3878 p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?
3879 "fixed" : "auto");
3880 p += sprintf(p, "\tINDEX:%d", level);
3881 p += sprintf(p, "\n");
3882 return p - buf + 1; 3853 return p - buf + 1;
3883} 3854}
3884 3855
@@ -4122,7 +4093,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
4122 priv->ibss_beacon = NULL; 4093 priv->ibss_beacon = NULL;
4123 4094
4124 spin_lock_init(&priv->lock); 4095 spin_lock_init(&priv->lock);
4125 spin_lock_init(&priv->power_data.lock);
4126 spin_lock_init(&priv->sta_lock); 4096 spin_lock_init(&priv->sta_lock);
4127 spin_lock_init(&priv->hcmd_lock); 4097 spin_lock_init(&priv->hcmd_lock);
4128 4098
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index b1213b6a6b9f..61a4ad7cc1c2 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -642,7 +642,7 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
642 if (changed & BSS_CHANGED_HT) { 642 if (changed & BSS_CHANGED_HT) {
643 printk(KERN_DEBUG " %s: HT: op_mode=0x%x\n", 643 printk(KERN_DEBUG " %s: HT: op_mode=0x%x\n",
644 wiphy_name(hw->wiphy), 644 wiphy_name(hw->wiphy),
645 info->ht.operation_mode); 645 info->ht_operation_mode);
646 } 646 }
647 647
648 if (changed & BSS_CHANGED_BASIC_RATES) { 648 if (changed & BSS_CHANGED_BASIC_RATES) {
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 46b288dc8f4d..a263d5c84c08 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2369,7 +2369,7 @@ static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
2369 if (info->use_cts_prot) { 2369 if (info->use_cts_prot) {
2370 prot_mode = MWL8K_FRAME_PROT_11G; 2370 prot_mode = MWL8K_FRAME_PROT_11G;
2371 } else { 2371 } else {
2372 switch (info->ht.operation_mode & 2372 switch (info->ht_operation_mode &
2373 IEEE80211_HT_OP_MODE_PROTECTION) { 2373 IEEE80211_HT_OP_MODE_PROTECTION) {
2374 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ: 2374 case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
2375 prot_mode = MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY; 2375 prot_mode = MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY;
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index d10af3687a8e..270dd4e59f7f 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1847,7 +1847,7 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
1847 rt2x00_set_chip(rt2x00dev, RT2571, value, reg); 1847 rt2x00_set_chip(rt2x00dev, RT2571, value, reg);
1848 1848
1849 if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0x25730) || 1849 if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0x25730) ||
1850 !rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) { 1850 rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) {
1851 ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); 1851 ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
1852 return -ENODEV; 1852 return -ENODEV;
1853 } 1853 }
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
index 20a9633569f2..a82c4cd436d8 100644
--- a/drivers/net/wireless/wl12xx/Kconfig
+++ b/drivers/net/wireless/wl12xx/Kconfig
@@ -1,6 +1,6 @@
1config WL12XX 1config WL12XX
2 tristate "TI wl1251/wl1271 support" 2 tristate "TI wl1251/wl1271 support"
3 depends on MAC80211 && WLAN_80211 && SPI_MASTER && EXPERIMENTAL 3 depends on MAC80211 && WLAN_80211 && SPI_MASTER && GENERIC_HARDIRQS && EXPERIMENTAL
4 select FW_LOADER 4 select FW_LOADER
5 select CRC7 5 select CRC7
6 ---help--- 6 ---help---
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index dc92359f37e6..05c29c01174c 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1068,8 +1068,12 @@ enum ieee80211_category {
1068 WLAN_CATEGORY_DLS = 2, 1068 WLAN_CATEGORY_DLS = 2,
1069 WLAN_CATEGORY_BACK = 3, 1069 WLAN_CATEGORY_BACK = 3,
1070 WLAN_CATEGORY_PUBLIC = 4, 1070 WLAN_CATEGORY_PUBLIC = 4,
1071 WLAN_CATEGORY_HT = 7,
1071 WLAN_CATEGORY_SA_QUERY = 8, 1072 WLAN_CATEGORY_SA_QUERY = 8,
1073 WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9,
1072 WLAN_CATEGORY_WMM = 17, 1074 WLAN_CATEGORY_WMM = 17,
1075 WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
1076 WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
1073}; 1077};
1074 1078
1075/* SPECTRUM_MGMT action code */ 1079/* SPECTRUM_MGMT action code */
@@ -1261,7 +1265,9 @@ static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
1261 if (ieee80211_has_protected(hdr->frame_control)) 1265 if (ieee80211_has_protected(hdr->frame_control))
1262 return true; 1266 return true;
1263 category = ((u8 *) hdr) + 24; 1267 category = ((u8 *) hdr) + 24;
1264 return *category != WLAN_CATEGORY_PUBLIC; 1268 return *category != WLAN_CATEGORY_PUBLIC &&
1269 *category != WLAN_CATEGORY_HT &&
1270 *category != WLAN_CATEGORY_VENDOR_SPECIFIC;
1265 } 1271 }
1266 1272
1267 return false; 1273 return false;
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index e9fd13aa79f0..dbea93b694e5 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -25,6 +25,8 @@
25 * 25 *
26 */ 26 */
27 27
28#include <linux/types.h>
29
28/** 30/**
29 * DOC: Station handling 31 * DOC: Station handling
30 * 32 *
@@ -77,8 +79,8 @@
77 * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT, 79 * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT,
78 * %NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD. 80 * %NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD.
79 * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA, 81 * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA,
80 * %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC and %NL80211_ATTR_KEY_CIPHER 82 * %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC, %NL80211_ATTR_KEY_CIPHER,
81 * attributes. 83 * and %NL80211_ATTR_KEY_SEQ attributes.
82 * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX 84 * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX
83 * or %NL80211_ATTR_MAC. 85 * or %NL80211_ATTR_MAC.
84 * 86 *
@@ -380,7 +382,7 @@ enum nl80211_commands {
380 * 382 *
381 * @NL80211_ATTR_STA_AID: Association ID for the station (u16) 383 * @NL80211_ATTR_STA_AID: Association ID for the station (u16)
382 * @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of 384 * @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of
383 * &enum nl80211_sta_flags. 385 * &enum nl80211_sta_flags (deprecated, use %NL80211_ATTR_STA_FLAGS2)
384 * @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by 386 * @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by
385 * IEEE 802.11 7.3.1.6 (u16). 387 * IEEE 802.11 7.3.1.6 (u16).
386 * @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported 388 * @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported
@@ -494,6 +496,21 @@ enum nl80211_commands {
494 * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this 496 * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this
495 * is used, e.g., with %NL80211_CMD_AUTHENTICATE event 497 * is used, e.g., with %NL80211_CMD_AUTHENTICATE event
496 * 498 *
499 * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
500 * used for the association (&enum nl80211_mfp, represented as a u32);
501 * this attribute can be used
502 * with %NL80211_CMD_ASSOCIATE request
503 *
504 * @NL80211_ATTR_STA_FLAGS2: Attribute containing a
505 * &struct nl80211_sta_flag_update.
506 *
507 * @NL80211_ATTR_CONTROL_PORT: A flag indicating whether user space controls
508 * IEEE 802.1X port, i.e., sets/clears %NL80211_STA_FLAG_AUTHORIZED, in
509 * station mode. If the flag is included in %NL80211_CMD_ASSOCIATE
510 * request, the driver will assume that the port is unauthorized until
511 * authorized by user space. Otherwise, port is marked authorized by
512 * default in station mode.
513 *
497 * @NL80211_ATTR_MAX: highest attribute number currently defined 514 * @NL80211_ATTR_MAX: highest attribute number currently defined
498 * @__NL80211_ATTR_AFTER_LAST: internal use 515 * @__NL80211_ATTR_AFTER_LAST: internal use
499 */ 516 */
@@ -596,6 +613,12 @@ enum nl80211_attrs {
596 613
597 NL80211_ATTR_TIMED_OUT, 614 NL80211_ATTR_TIMED_OUT,
598 615
616 NL80211_ATTR_USE_MFP,
617
618 NL80211_ATTR_STA_FLAGS2,
619
620 NL80211_ATTR_CONTROL_PORT,
621
599 /* add attributes here, update the policy in nl80211.c */ 622 /* add attributes here, update the policy in nl80211.c */
600 623
601 __NL80211_ATTR_AFTER_LAST, 624 __NL80211_ATTR_AFTER_LAST,
@@ -685,6 +708,18 @@ enum nl80211_sta_flags {
685}; 708};
686 709
687/** 710/**
711 * struct nl80211_sta_flag_update - station flags mask/set
712 * @mask: mask of station flags to set
713 * @set: which values to set them to
714 *
715 * Both mask and set contain bits as per &enum nl80211_sta_flags.
716 */
717struct nl80211_sta_flag_update {
718 __u32 mask;
719 __u32 set;
720} __attribute__((packed));
721
722/**
688 * enum nl80211_rate_info - bitrate information 723 * enum nl80211_rate_info - bitrate information
689 * 724 *
690 * These attribute types are used with %NL80211_STA_INFO_TXRATE 725 * These attribute types are used with %NL80211_STA_INFO_TXRATE
@@ -1179,4 +1214,14 @@ enum nl80211_key_type {
1179 NL80211_KEYTYPE_PEERKEY, 1214 NL80211_KEYTYPE_PEERKEY,
1180}; 1215};
1181 1216
1217/**
1218 * enum nl80211_mfp - Management frame protection state
1219 * @NL80211_MFP_NO: Management frame protection not used
1220 * @NL80211_MFP_REQUIRED: Management frame protection required
1221 */
1222enum nl80211_mfp {
1223 NL80211_MFP_NO,
1224 NL80211_MFP_REQUIRED,
1225};
1226
1182#endif /* __LINUX_NL80211_H */ 1227#endif /* __LINUX_NL80211_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b8a76764e1c5..9e17a83d3432 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -252,27 +252,6 @@ struct beacon_parameters {
252}; 252};
253 253
254/** 254/**
255 * enum station_flags - station flags
256 *
257 * Station capability flags. Note that these must be the bits
258 * according to the nl80211 flags.
259 *
260 * @STATION_FLAG_CHANGED: station flags were changed
261 * @STATION_FLAG_AUTHORIZED: station is authorized to send frames (802.1X)
262 * @STATION_FLAG_SHORT_PREAMBLE: station is capable of receiving frames
263 * with short preambles
264 * @STATION_FLAG_WME: station is WME/QoS capable
265 * @STATION_FLAG_MFP: station uses management frame protection
266 */
267enum station_flags {
268 STATION_FLAG_CHANGED = 1<<0,
269 STATION_FLAG_AUTHORIZED = 1<<NL80211_STA_FLAG_AUTHORIZED,
270 STATION_FLAG_SHORT_PREAMBLE = 1<<NL80211_STA_FLAG_SHORT_PREAMBLE,
271 STATION_FLAG_WME = 1<<NL80211_STA_FLAG_WME,
272 STATION_FLAG_MFP = 1<<NL80211_STA_FLAG_MFP,
273};
274
275/**
276 * enum plink_action - actions to perform in mesh peers 255 * enum plink_action - actions to perform in mesh peers
277 * 256 *
278 * @PLINK_ACTION_INVALID: action 0 is reserved 257 * @PLINK_ACTION_INVALID: action 0 is reserved
@@ -294,14 +273,17 @@ enum plink_actions {
294 * @supported_rates: supported rates in IEEE 802.11 format 273 * @supported_rates: supported rates in IEEE 802.11 format
295 * (or NULL for no change) 274 * (or NULL for no change)
296 * @supported_rates_len: number of supported rates 275 * @supported_rates_len: number of supported rates
297 * @station_flags: station flags (see &enum station_flags) 276 * @sta_flags_mask: station flags that changed
277 * (bitmask of BIT(NL80211_STA_FLAG_...))
278 * @sta_flags_set: station flags values
279 * (bitmask of BIT(NL80211_STA_FLAG_...))
298 * @listen_interval: listen interval or -1 for no change 280 * @listen_interval: listen interval or -1 for no change
299 * @aid: AID or zero for no change 281 * @aid: AID or zero for no change
300 */ 282 */
301struct station_parameters { 283struct station_parameters {
302 u8 *supported_rates; 284 u8 *supported_rates;
303 struct net_device *vlan; 285 struct net_device *vlan;
304 u32 station_flags; 286 u32 sta_flags_mask, sta_flags_set;
305 int listen_interval; 287 int listen_interval;
306 u16 aid; 288 u16 aid;
307 u8 supported_rates_len; 289 u8 supported_rates_len;
@@ -672,6 +654,11 @@ struct cfg80211_auth_request {
672 * @ssid_len: Length of ssid in octets 654 * @ssid_len: Length of ssid in octets
673 * @ie: Extra IEs to add to (Re)Association Request frame or %NULL 655 * @ie: Extra IEs to add to (Re)Association Request frame or %NULL
674 * @ie_len: Length of ie buffer in octets 656 * @ie_len: Length of ie buffer in octets
657 * @use_mfp: Use management frame protection (IEEE 802.11w) in this association
658 * @control_port: Whether user space controls IEEE 802.1X port, i.e.,
659 * sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is
660 * required to assume that the port is unauthorized until authorized by
661 * user space. Otherwise, port is marked authorized by default.
675 */ 662 */
676struct cfg80211_assoc_request { 663struct cfg80211_assoc_request {
677 struct ieee80211_channel *chan; 664 struct ieee80211_channel *chan;
@@ -680,6 +667,8 @@ struct cfg80211_assoc_request {
680 size_t ssid_len; 667 size_t ssid_len;
681 const u8 *ie; 668 const u8 *ie;
682 size_t ie_len; 669 size_t ie_len;
670 bool use_mfp;
671 bool control_port;
683}; 672};
684 673
685/** 674/**
@@ -858,13 +847,13 @@ struct cfg80211_ops {
858 struct vif_params *params); 847 struct vif_params *params);
859 848
860 int (*add_key)(struct wiphy *wiphy, struct net_device *netdev, 849 int (*add_key)(struct wiphy *wiphy, struct net_device *netdev,
861 u8 key_index, u8 *mac_addr, 850 u8 key_index, const u8 *mac_addr,
862 struct key_params *params); 851 struct key_params *params);
863 int (*get_key)(struct wiphy *wiphy, struct net_device *netdev, 852 int (*get_key)(struct wiphy *wiphy, struct net_device *netdev,
864 u8 key_index, u8 *mac_addr, void *cookie, 853 u8 key_index, const u8 *mac_addr, void *cookie,
865 void (*callback)(void *cookie, struct key_params*)); 854 void (*callback)(void *cookie, struct key_params*));
866 int (*del_key)(struct wiphy *wiphy, struct net_device *netdev, 855 int (*del_key)(struct wiphy *wiphy, struct net_device *netdev,
867 u8 key_index, u8 *mac_addr); 856 u8 key_index, const u8 *mac_addr);
868 int (*set_default_key)(struct wiphy *wiphy, 857 int (*set_default_key)(struct wiphy *wiphy,
869 struct net_device *netdev, 858 struct net_device *netdev,
870 u8 key_index); 859 u8 key_index);
@@ -1145,8 +1134,11 @@ struct wireless_dev {
1145 1134
1146#ifdef CONFIG_WIRELESS_EXT 1135#ifdef CONFIG_WIRELESS_EXT
1147 /* wext data */ 1136 /* wext data */
1148 struct cfg80211_ibss_params wext; 1137 struct {
1149 u8 wext_bssid[ETH_ALEN]; 1138 struct cfg80211_ibss_params ibss;
1139 u8 bssid[ETH_ALEN];
1140 s8 default_key, default_mgmt_key;
1141 } wext;
1150#endif 1142#endif
1151}; 1143};
1152 1144
@@ -1396,6 +1388,15 @@ int cfg80211_wext_siwretry(struct net_device *dev,
1396int cfg80211_wext_giwretry(struct net_device *dev, 1388int cfg80211_wext_giwretry(struct net_device *dev,
1397 struct iw_request_info *info, 1389 struct iw_request_info *info,
1398 struct iw_param *retry, char *extra); 1390 struct iw_param *retry, char *extra);
1391int cfg80211_wext_siwencodeext(struct net_device *dev,
1392 struct iw_request_info *info,
1393 struct iw_point *erq, char *extra);
1394int cfg80211_wext_siwencode(struct net_device *dev,
1395 struct iw_request_info *info,
1396 struct iw_point *erq, char *keybuf);
1397int cfg80211_wext_giwencode(struct net_device *dev,
1398 struct iw_request_info *info,
1399 struct iw_point *erq, char *keybuf);
1399 1400
1400/* 1401/*
1401 * callbacks for asynchronous cfg80211 methods, notification 1402 * callbacks for asynchronous cfg80211 methods, notification
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 38dc1cd10270..d10ed1776fcd 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -73,22 +73,6 @@
73 */ 73 */
74 74
75/** 75/**
76 * struct ieee80211_ht_bss_info - describing BSS's HT characteristics
77 *
78 * This structure describes most essential parameters needed
79 * to describe 802.11n HT characteristics in a BSS.
80 *
81 * @primary_channel: channel number of primery channel
82 * @bss_cap: 802.11n's general BSS capabilities (e.g. channel width)
83 * @bss_op_mode: 802.11n's BSS operation modes (e.g. HT protection)
84 */
85struct ieee80211_ht_bss_info {
86 u8 primary_channel;
87 u8 bss_cap; /* use IEEE80211_HT_IE_CHA_ */
88 u8 bss_op_mode; /* use IEEE80211_HT_IE_ */
89};
90
91/**
92 * enum ieee80211_max_queues - maximum number of queues 76 * enum ieee80211_max_queues - maximum number of queues
93 * 77 *
94 * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues. 78 * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues.
@@ -171,14 +155,6 @@ enum ieee80211_bss_change {
171}; 155};
172 156
173/** 157/**
174 * struct ieee80211_bss_ht_conf - BSS's changing HT configuration
175 * @operation_mode: HT operation mode (like in &struct ieee80211_ht_info)
176 */
177struct ieee80211_bss_ht_conf {
178 u16 operation_mode;
179};
180
181/**
182 * struct ieee80211_bss_conf - holds the BSS's changing parameters 158 * struct ieee80211_bss_conf - holds the BSS's changing parameters
183 * 159 *
184 * This structure keeps information about a BSS (and an association 160 * This structure keeps information about a BSS (and an association
@@ -203,6 +179,8 @@ struct ieee80211_bss_ht_conf {
203 * the current band. 179 * the current band.
204 * @bssid: The BSSID for this BSS 180 * @bssid: The BSSID for this BSS
205 * @enable_beacon: whether beaconing should be enabled or not 181 * @enable_beacon: whether beaconing should be enabled or not
182 * @ht_operation_mode: HT operation mode (like in &struct ieee80211_ht_info).
183 * This field is only valid when the channel type is one of the HT types.
206 */ 184 */
207struct ieee80211_bss_conf { 185struct ieee80211_bss_conf {
208 const u8 *bssid; 186 const u8 *bssid;
@@ -219,7 +197,7 @@ struct ieee80211_bss_conf {
219 u16 assoc_capability; 197 u16 assoc_capability;
220 u64 timestamp; 198 u64 timestamp;
221 u32 basic_rates; 199 u32 basic_rates;
222 struct ieee80211_bss_ht_conf ht; 200 u16 ht_operation_mode;
223}; 201};
224 202
225/** 203/**
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index d0ca6da33ca9..77e9ff5ec4f3 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -112,7 +112,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
112} 112}
113 113
114static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, 114static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
115 u8 key_idx, u8 *mac_addr, 115 u8 key_idx, const u8 *mac_addr,
116 struct key_params *params) 116 struct key_params *params)
117{ 117{
118 struct ieee80211_sub_if_data *sdata; 118 struct ieee80211_sub_if_data *sdata;
@@ -141,7 +141,8 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
141 return -EINVAL; 141 return -EINVAL;
142 } 142 }
143 143
144 key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key); 144 key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key,
145 params->seq_len, params->seq);
145 if (!key) 146 if (!key)
146 return -ENOMEM; 147 return -ENOMEM;
147 148
@@ -166,7 +167,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
166} 167}
167 168
168static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, 169static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
169 u8 key_idx, u8 *mac_addr) 170 u8 key_idx, const u8 *mac_addr)
170{ 171{
171 struct ieee80211_sub_if_data *sdata; 172 struct ieee80211_sub_if_data *sdata;
172 struct sta_info *sta; 173 struct sta_info *sta;
@@ -208,7 +209,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
208} 209}
209 210
210static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, 211static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
211 u8 key_idx, u8 *mac_addr, void *cookie, 212 u8 key_idx, const u8 *mac_addr, void *cookie,
212 void (*callback)(void *cookie, 213 void (*callback)(void *cookie,
213 struct key_params *params)) 214 struct key_params *params))
214{ 215{
@@ -629,34 +630,38 @@ static void sta_apply_parameters(struct ieee80211_local *local,
629 int i, j; 630 int i, j;
630 struct ieee80211_supported_band *sband; 631 struct ieee80211_supported_band *sband;
631 struct ieee80211_sub_if_data *sdata = sta->sdata; 632 struct ieee80211_sub_if_data *sdata = sta->sdata;
633 u32 mask, set;
632 634
633 sband = local->hw.wiphy->bands[local->oper_channel->band]; 635 sband = local->hw.wiphy->bands[local->oper_channel->band];
634 636
635 /* 637 spin_lock_bh(&sta->lock);
636 * FIXME: updating the flags is racy when this function is 638 mask = params->sta_flags_mask;
637 * called from ieee80211_change_station(), this will 639 set = params->sta_flags_set;
638 * be resolved in a future patch.
639 */
640 640
641 if (params->station_flags & STATION_FLAG_CHANGED) { 641 if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
642 spin_lock_bh(&sta->lock);
643 sta->flags &= ~WLAN_STA_AUTHORIZED; 642 sta->flags &= ~WLAN_STA_AUTHORIZED;
644 if (params->station_flags & STATION_FLAG_AUTHORIZED) 643 if (set & BIT(NL80211_STA_FLAG_AUTHORIZED))
645 sta->flags |= WLAN_STA_AUTHORIZED; 644 sta->flags |= WLAN_STA_AUTHORIZED;
645 }
646 646
647 if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) {
647 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE; 648 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
648 if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE) 649 if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE))
649 sta->flags |= WLAN_STA_SHORT_PREAMBLE; 650 sta->flags |= WLAN_STA_SHORT_PREAMBLE;
651 }
650 652
653 if (mask & BIT(NL80211_STA_FLAG_WME)) {
651 sta->flags &= ~WLAN_STA_WME; 654 sta->flags &= ~WLAN_STA_WME;
652 if (params->station_flags & STATION_FLAG_WME) 655 if (set & BIT(NL80211_STA_FLAG_WME))
653 sta->flags |= WLAN_STA_WME; 656 sta->flags |= WLAN_STA_WME;
657 }
654 658
659 if (mask & BIT(NL80211_STA_FLAG_MFP)) {
655 sta->flags &= ~WLAN_STA_MFP; 660 sta->flags &= ~WLAN_STA_MFP;
656 if (params->station_flags & STATION_FLAG_MFP) 661 if (set & BIT(NL80211_STA_FLAG_MFP))
657 sta->flags |= WLAN_STA_MFP; 662 sta->flags |= WLAN_STA_MFP;
658 spin_unlock_bh(&sta->lock);
659 } 663 }
664 spin_unlock_bh(&sta->lock);
660 665
661 /* 666 /*
662 * FIXME: updating the following information is racy when this 667 * FIXME: updating the following information is racy when this
@@ -1253,6 +1258,19 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
1253 if (ret) 1258 if (ret)
1254 return ret; 1259 return ret;
1255 1260
1261 if (req->use_mfp) {
1262 sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED;
1263 sdata->u.mgd.flags |= IEEE80211_STA_MFP_ENABLED;
1264 } else {
1265 sdata->u.mgd.mfp = IEEE80211_MFP_DISABLED;
1266 sdata->u.mgd.flags &= ~IEEE80211_STA_MFP_ENABLED;
1267 }
1268
1269 if (req->control_port)
1270 sdata->u.mgd.flags |= IEEE80211_STA_CONTROL_PORT;
1271 else
1272 sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
1273
1256 sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME; 1274 sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME;
1257 sdata->u.mgd.state = IEEE80211_STA_MLME_ASSOCIATE; 1275 sdata->u.mgd.state = IEEE80211_STA_MLME_ASSOCIATE;
1258 ieee80211_sta_req_auth(sdata); 1276 ieee80211_sta_req_auth(sdata);
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index ac793201b701..e7682fe1c590 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -135,6 +135,42 @@ static const struct file_operations reset_ops = {
135 .open = mac80211_open_file_generic, 135 .open = mac80211_open_file_generic,
136}; 136};
137 137
138static ssize_t noack_read(struct file *file, char __user *user_buf,
139 size_t count, loff_t *ppos)
140{
141 struct ieee80211_local *local = file->private_data;
142 int res;
143 char buf[10];
144
145 res = scnprintf(buf, sizeof(buf), "%d\n", local->wifi_wme_noack_test);
146
147 return simple_read_from_buffer(user_buf, count, ppos, buf, res);
148}
149
150static ssize_t noack_write(struct file *file,
151 const char __user *user_buf,
152 size_t count, loff_t *ppos)
153{
154 struct ieee80211_local *local = file->private_data;
155 char buf[10];
156 size_t len;
157
158 len = min(count, sizeof(buf) - 1);
159 if (copy_from_user(buf, user_buf, len))
160 return -EFAULT;
161 buf[len] = '\0';
162
163 local->wifi_wme_noack_test = !!simple_strtoul(buf, NULL, 0);
164
165 return count;
166}
167
168static const struct file_operations noack_ops = {
169 .read = noack_read,
170 .write = noack_write,
171 .open = mac80211_open_file_generic
172};
173
138/* statistics stuff */ 174/* statistics stuff */
139 175
140#define DEBUGFS_STATS_FILE(name, buflen, fmt, value...) \ 176#define DEBUGFS_STATS_FILE(name, buflen, fmt, value...) \
@@ -275,6 +311,7 @@ void debugfs_hw_add(struct ieee80211_local *local)
275 DEBUGFS_ADD(wep_iv); 311 DEBUGFS_ADD(wep_iv);
276 DEBUGFS_ADD(tsf); 312 DEBUGFS_ADD(tsf);
277 DEBUGFS_ADD_MODE(reset, 0200); 313 DEBUGFS_ADD_MODE(reset, 0200);
314 DEBUGFS_ADD(noack);
278 315
279 statsd = debugfs_create_dir("statistics", phyd); 316 statsd = debugfs_create_dir("statistics", phyd);
280 local->debugfs.statistics = statsd; 317 local->debugfs.statistics = statsd;
@@ -330,6 +367,7 @@ void debugfs_hw_del(struct ieee80211_local *local)
330 DEBUGFS_DEL(wep_iv); 367 DEBUGFS_DEL(wep_iv);
331 DEBUGFS_DEL(tsf); 368 DEBUGFS_DEL(tsf);
332 DEBUGFS_DEL(reset); 369 DEBUGFS_DEL(reset);
370 DEBUGFS_DEL(noack);
333 371
334 DEBUGFS_STATS_DEL(transmitted_fragment_count); 372 DEBUGFS_STATS_DEL(transmitted_fragment_count);
335 DEBUGFS_STATS_DEL(multicast_transmitted_frame_count); 373 DEBUGFS_STATS_DEL(multicast_transmitted_frame_count);
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index aa537681f87c..c236079ed38a 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -63,19 +63,18 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
63static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 63static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
64 const u8 *bssid, const int beacon_int, 64 const u8 *bssid, const int beacon_int,
65 struct ieee80211_channel *chan, 65 struct ieee80211_channel *chan,
66 const size_t supp_rates_len, 66 const u32 basic_rates,
67 const u8 *supp_rates,
68 const u16 capability, u64 tsf) 67 const u16 capability, u64 tsf)
69{ 68{
70 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 69 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
71 struct ieee80211_local *local = sdata->local; 70 struct ieee80211_local *local = sdata->local;
72 int rates, i, j; 71 int rates, i;
73 struct sk_buff *skb; 72 struct sk_buff *skb;
74 struct ieee80211_mgmt *mgmt; 73 struct ieee80211_mgmt *mgmt;
75 u8 *pos; 74 u8 *pos;
76 struct ieee80211_supported_band *sband; 75 struct ieee80211_supported_band *sband;
77 u32 bss_change; 76 u32 bss_change;
78 77 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
79 78
80 /* Reset own TSF to allow time synchronization work. */ 79 /* Reset own TSF to allow time synchronization work. */
81 drv_reset_tsf(local); 80 drv_reset_tsf(local);
@@ -101,6 +100,16 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
101 100
102 sband = local->hw.wiphy->bands[chan->band]; 101 sband = local->hw.wiphy->bands[chan->band];
103 102
103 /* build supported rates array */
104 pos = supp_rates;
105 for (i = 0; i < sband->n_bitrates; i++) {
106 int rate = sband->bitrates[i].bitrate;
107 u8 basic = 0;
108 if (basic_rates & BIT(i))
109 basic = 0x80;
110 *pos++ = basic | (u8) (rate / 5);
111 }
112
104 /* Build IBSS probe response */ 113 /* Build IBSS probe response */
105 mgmt = (void *) skb_put(skb, 24 + sizeof(mgmt->u.beacon)); 114 mgmt = (void *) skb_put(skb, 24 + sizeof(mgmt->u.beacon));
106 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); 115 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
@@ -118,7 +127,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
118 *pos++ = ifibss->ssid_len; 127 *pos++ = ifibss->ssid_len;
119 memcpy(pos, ifibss->ssid, ifibss->ssid_len); 128 memcpy(pos, ifibss->ssid, ifibss->ssid_len);
120 129
121 rates = supp_rates_len; 130 rates = sband->n_bitrates;
122 if (rates > 8) 131 if (rates > 8)
123 rates = 8; 132 rates = 8;
124 pos = skb_put(skb, 2 + rates); 133 pos = skb_put(skb, 2 + rates);
@@ -140,8 +149,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
140 *pos++ = 0; 149 *pos++ = 0;
141 *pos++ = 0; 150 *pos++ = 0;
142 151
143 if (supp_rates_len > 8) { 152 if (sband->n_bitrates > 8) {
144 rates = supp_rates_len - 8; 153 rates = sband->n_bitrates - 8;
145 pos = skb_put(skb, 2 + rates); 154 pos = skb_put(skb, 2 + rates);
146 *pos++ = WLAN_EID_EXT_SUPP_RATES; 155 *pos++ = WLAN_EID_EXT_SUPP_RATES;
147 *pos++ = rates; 156 *pos++ = rates;
@@ -162,15 +171,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
162 bss_change |= BSS_CHANGED_BEACON_ENABLED; 171 bss_change |= BSS_CHANGED_BEACON_ENABLED;
163 ieee80211_bss_info_change_notify(sdata, bss_change); 172 ieee80211_bss_info_change_notify(sdata, bss_change);
164 173
165 rates = 0; 174 ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates);
166 for (i = 0; i < supp_rates_len; i++) {
167 int bitrate = (supp_rates[i] & 0x7f) * 5;
168 for (j = 0; j < sband->n_bitrates; j++)
169 if (sband->bitrates[j].bitrate == bitrate)
170 rates |= BIT(j);
171 }
172
173 ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates);
174 175
175 ifibss->state = IEEE80211_IBSS_MLME_JOINED; 176 ifibss->state = IEEE80211_IBSS_MLME_JOINED;
176 mod_timer(&ifibss->timer, 177 mod_timer(&ifibss->timer,
@@ -184,15 +185,35 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
184static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 185static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
185 struct ieee80211_bss *bss) 186 struct ieee80211_bss *bss)
186{ 187{
188 struct ieee80211_supported_band *sband;
189 u32 basic_rates;
190 int i, j;
187 u16 beacon_int = bss->cbss.beacon_interval; 191 u16 beacon_int = bss->cbss.beacon_interval;
188 192
189 if (beacon_int < 10) 193 if (beacon_int < 10)
190 beacon_int = 10; 194 beacon_int = 10;
191 195
196 sband = sdata->local->hw.wiphy->bands[bss->cbss.channel->band];
197
198 basic_rates = 0;
199
200 for (i = 0; i < bss->supp_rates_len; i++) {
201 int rate = (bss->supp_rates[i] & 0x7f) * 5;
202 bool is_basic = !!(bss->supp_rates[i] & 0x80);
203
204 for (j = 0; j < sband->n_bitrates; j++) {
205 if (sband->bitrates[j].bitrate == rate) {
206 if (is_basic)
207 basic_rates |= BIT(j);
208 break;
209 }
210 }
211 }
212
192 __ieee80211_sta_join_ibss(sdata, bss->cbss.bssid, 213 __ieee80211_sta_join_ibss(sdata, bss->cbss.bssid,
193 beacon_int, 214 beacon_int,
194 bss->cbss.channel, 215 bss->cbss.channel,
195 bss->supp_rates_len, bss->supp_rates, 216 basic_rates,
196 bss->cbss.capability, 217 bss->cbss.capability,
197 bss->cbss.tsf); 218 bss->cbss.tsf);
198} 219}
@@ -449,9 +470,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
449 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 470 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
450 struct ieee80211_local *local = sdata->local; 471 struct ieee80211_local *local = sdata->local;
451 struct ieee80211_supported_band *sband; 472 struct ieee80211_supported_band *sband;
452 u8 *pos;
453 u8 bssid[ETH_ALEN]; 473 u8 bssid[ETH_ALEN];
454 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
455 u16 capability; 474 u16 capability;
456 int i; 475 int i;
457 476
@@ -480,15 +499,9 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
480 else 499 else
481 sdata->drop_unencrypted = 0; 500 sdata->drop_unencrypted = 0;
482 501
483 pos = supp_rates;
484 for (i = 0; i < sband->n_bitrates; i++) {
485 int rate = sband->bitrates[i].bitrate;
486 *pos++ = (u8) (rate / 5);
487 }
488
489 __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, 502 __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
490 ifibss->channel, sband->n_bitrates, 503 ifibss->channel, 3, /* first two are basic */
491 supp_rates, capability, 0); 504 capability, 0);
492} 505}
493 506
494static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) 507static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
@@ -499,6 +512,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
499 struct ieee80211_channel *chan = NULL; 512 struct ieee80211_channel *chan = NULL;
500 const u8 *bssid = NULL; 513 const u8 *bssid = NULL;
501 int active_ibss; 514 int active_ibss;
515 u16 capability;
502 516
503 active_ibss = ieee80211_sta_active_ibss(sdata); 517 active_ibss = ieee80211_sta_active_ibss(sdata);
504#ifdef CONFIG_MAC80211_IBSS_DEBUG 518#ifdef CONFIG_MAC80211_IBSS_DEBUG
@@ -509,6 +523,10 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
509 if (active_ibss) 523 if (active_ibss)
510 return; 524 return;
511 525
526 capability = WLAN_CAPABILITY_IBSS;
527 if (sdata->default_key)
528 capability |= WLAN_CAPABILITY_PRIVACY;
529
512 if (ifibss->fixed_bssid) 530 if (ifibss->fixed_bssid)
513 bssid = ifibss->bssid; 531 bssid = ifibss->bssid;
514 if (ifibss->fixed_channel) 532 if (ifibss->fixed_channel)
@@ -517,8 +535,9 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
517 bssid = ifibss->bssid; 535 bssid = ifibss->bssid;
518 bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan, bssid, 536 bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan, bssid,
519 ifibss->ssid, ifibss->ssid_len, 537 ifibss->ssid, ifibss->ssid_len,
520 WLAN_CAPABILITY_IBSS, 538 capability,
521 WLAN_CAPABILITY_IBSS); 539 WLAN_CAPABILITY_IBSS |
540 WLAN_CAPABILITY_PRIVACY);
522 541
523#ifdef CONFIG_MAC80211_IBSS_DEBUG 542#ifdef CONFIG_MAC80211_IBSS_DEBUG
524 if (bss) 543 if (bss)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 03e0d22603c8..9d1514727f6e 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -235,7 +235,7 @@ struct mesh_preq_queue {
235#define IEEE80211_STA_ASSOCIATED BIT(4) 235#define IEEE80211_STA_ASSOCIATED BIT(4)
236#define IEEE80211_STA_PROBEREQ_POLL BIT(5) 236#define IEEE80211_STA_PROBEREQ_POLL BIT(5)
237#define IEEE80211_STA_CREATE_IBSS BIT(6) 237#define IEEE80211_STA_CREATE_IBSS BIT(6)
238/* hole at 7, please re-use */ 238#define IEEE80211_STA_CONTROL_PORT BIT(7)
239#define IEEE80211_STA_WMM_ENABLED BIT(8) 239#define IEEE80211_STA_WMM_ENABLED BIT(8)
240/* hole at 9, please re-use */ 240/* hole at 9, please re-use */
241#define IEEE80211_STA_AUTO_SSID_SEL BIT(10) 241#define IEEE80211_STA_AUTO_SSID_SEL BIT(10)
@@ -427,6 +427,12 @@ struct ieee80211_sub_if_data {
427 427
428 int drop_unencrypted; 428 int drop_unencrypted;
429 429
430 /*
431 * keep track of whether the HT opmode (stored in
432 * vif.bss_info.ht_operation_mode) is valid.
433 */
434 bool ht_opmode_valid;
435
430 /* Fragment table for host-based reassembly */ 436 /* Fragment table for host-based reassembly */
431 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; 437 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
432 unsigned int fragment_next; 438 unsigned int fragment_next;
@@ -760,6 +766,7 @@ struct ieee80211_local {
760 struct dentry *wep_iv; 766 struct dentry *wep_iv;
761 struct dentry *tsf; 767 struct dentry *tsf;
762 struct dentry *reset; 768 struct dentry *reset;
769 struct dentry *noack;
763 struct dentry *statistics; 770 struct dentry *statistics;
764 struct local_debugfsdentries_statsdentries { 771 struct local_debugfsdentries_statsdentries {
765 struct dentry *transmitted_fragment_count; 772 struct dentry *transmitted_fragment_count;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 8b6daf0219f4..8c9f1c722cdb 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -964,5 +964,6 @@ void ieee80211_recalc_idle(struct ieee80211_local *local)
964 mutex_lock(&local->iflist_mtx); 964 mutex_lock(&local->iflist_mtx);
965 chg = __ieee80211_recalc_idle(local); 965 chg = __ieee80211_recalc_idle(local);
966 mutex_unlock(&local->iflist_mtx); 966 mutex_unlock(&local->iflist_mtx);
967 ieee80211_hw_config(local, chg); 967 if (chg)
968 ieee80211_hw_config(local, chg);
968} 969}
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index b7e1350273bb..827ea8e6ee0a 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -290,9 +290,11 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
290struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, 290struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
291 int idx, 291 int idx,
292 size_t key_len, 292 size_t key_len,
293 const u8 *key_data) 293 const u8 *key_data,
294 size_t seq_len, const u8 *seq)
294{ 295{
295 struct ieee80211_key *key; 296 struct ieee80211_key *key;
297 int i, j;
296 298
297 BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS); 299 BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS);
298 300
@@ -318,14 +320,31 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
318 case ALG_TKIP: 320 case ALG_TKIP:
319 key->conf.iv_len = TKIP_IV_LEN; 321 key->conf.iv_len = TKIP_IV_LEN;
320 key->conf.icv_len = TKIP_ICV_LEN; 322 key->conf.icv_len = TKIP_ICV_LEN;
323 if (seq && seq_len == 6) {
324 for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
325 key->u.tkip.rx[i].iv32 =
326 get_unaligned_le32(&seq[2]);
327 key->u.tkip.rx[i].iv16 =
328 get_unaligned_le16(seq);
329 }
330 }
321 break; 331 break;
322 case ALG_CCMP: 332 case ALG_CCMP:
323 key->conf.iv_len = CCMP_HDR_LEN; 333 key->conf.iv_len = CCMP_HDR_LEN;
324 key->conf.icv_len = CCMP_MIC_LEN; 334 key->conf.icv_len = CCMP_MIC_LEN;
335 if (seq && seq_len == CCMP_PN_LEN) {
336 for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
337 for (j = 0; j < CCMP_PN_LEN; j++)
338 key->u.ccmp.rx_pn[i][j] =
339 seq[CCMP_PN_LEN - j - 1];
340 }
325 break; 341 break;
326 case ALG_AES_CMAC: 342 case ALG_AES_CMAC:
327 key->conf.iv_len = 0; 343 key->conf.iv_len = 0;
328 key->conf.icv_len = sizeof(struct ieee80211_mmie); 344 key->conf.icv_len = sizeof(struct ieee80211_mmie);
345 if (seq && seq_len == 6)
346 for (j = 0; j < 6; j++)
347 key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1];
329 break; 348 break;
330 } 349 }
331 memcpy(key->conf.key, key_data, key_len); 350 memcpy(key->conf.key, key_data, key_len);
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 215d3ef42a4f..9572e00f532c 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -144,7 +144,8 @@ struct ieee80211_key {
144struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, 144struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
145 int idx, 145 int idx,
146 size_t key_len, 146 size_t key_len,
147 const u8 *key_data); 147 const u8 *key_data,
148 size_t seq_len, const u8 *seq);
148/* 149/*
149 * Insert a key into data structures (sdata, sta if necessary) 150 * Insert a key into data structures (sdata, sta if necessary)
150 * to make it used, free old key. 151 * to make it used, free old key.
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index b80bc80e46cf..76df5eabf268 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -154,15 +154,17 @@ static void ieee80211_master_set_multicast_list(struct net_device *dev)
154 154
155int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) 155int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
156{ 156{
157 struct ieee80211_channel *chan; 157 struct ieee80211_channel *chan, *scan_chan;
158 int ret = 0; 158 int ret = 0;
159 int power; 159 int power;
160 enum nl80211_channel_type channel_type; 160 enum nl80211_channel_type channel_type;
161 161
162 might_sleep(); 162 might_sleep();
163 163
164 if (local->sw_scanning) { 164 scan_chan = local->scan_channel;
165 chan = local->scan_channel; 165
166 if (scan_chan) {
167 chan = scan_chan;
166 channel_type = NL80211_CHAN_NO_HT; 168 channel_type = NL80211_CHAN_NO_HT;
167 } else { 169 } else {
168 chan = local->oper_channel; 170 chan = local->oper_channel;
@@ -176,7 +178,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
176 changed |= IEEE80211_CONF_CHANGE_CHANNEL; 178 changed |= IEEE80211_CONF_CHANGE_CHANNEL;
177 } 179 }
178 180
179 if (local->sw_scanning) 181 if (scan_chan)
180 power = chan->max_power; 182 power = chan->max_power;
181 else 183 else
182 power = local->power_constr_level ? 184 power = local->power_constr_level ?
@@ -859,8 +861,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
859 if (!local->oper_channel) { 861 if (!local->oper_channel) {
860 /* init channel we're on */ 862 /* init channel we're on */
861 local->hw.conf.channel = 863 local->hw.conf.channel =
862 local->oper_channel = 864 local->oper_channel = &sband->channels[0];
863 local->scan_channel = &sband->channels[0]; 865 local->hw.conf.channel_type = NL80211_CHAN_NO_HT;
864 } 866 }
865 channels += sband->n_channels; 867 channels += sband->n_channels;
866 868
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 75c487229f2e..ae030688771f 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -33,6 +33,7 @@
33#define IEEE80211_ASSOC_TIMEOUT (HZ / 5) 33#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
34#define IEEE80211_ASSOC_MAX_TRIES 3 34#define IEEE80211_ASSOC_MAX_TRIES 3
35#define IEEE80211_MONITORING_INTERVAL (2 * HZ) 35#define IEEE80211_MONITORING_INTERVAL (2 * HZ)
36#define IEEE80211_PROBE_WAIT (HZ / 20)
36#define IEEE80211_PROBE_IDLE_TIME (60 * HZ) 37#define IEEE80211_PROBE_IDLE_TIME (60 * HZ)
37#define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ) 38#define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ)
38 39
@@ -95,16 +96,14 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
95 struct ieee80211_local *local = sdata->local; 96 struct ieee80211_local *local = sdata->local;
96 struct ieee80211_supported_band *sband; 97 struct ieee80211_supported_band *sband;
97 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 98 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
98 struct ieee80211_bss_ht_conf ht;
99 struct sta_info *sta; 99 struct sta_info *sta;
100 u32 changed = 0; 100 u32 changed = 0;
101 u16 ht_opmode;
101 bool enable_ht = true, ht_changed; 102 bool enable_ht = true, ht_changed;
102 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 103 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
103 104
104 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 105 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
105 106
106 memset(&ht, 0, sizeof(ht));
107
108 /* HT is not supported */ 107 /* HT is not supported */
109 if (!sband->ht_cap.ht_supported) 108 if (!sband->ht_cap.ht_supported)
110 enable_ht = false; 109 enable_ht = false;
@@ -148,19 +147,20 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
148 IEEE80211_RC_HT_CHANGED); 147 IEEE80211_RC_HT_CHANGED);
149 148
150 rcu_read_unlock(); 149 rcu_read_unlock();
151
152 } 150 }
153 151
154 /* disable HT */ 152 /* disable HT */
155 if (!enable_ht) 153 if (!enable_ht)
156 return 0; 154 return 0;
157 155
158 ht.operation_mode = le16_to_cpu(hti->operation_mode); 156 ht_opmode = le16_to_cpu(hti->operation_mode);
159 157
160 /* if bss configuration changed store the new one */ 158 /* if bss configuration changed store the new one */
161 if (memcmp(&sdata->vif.bss_conf.ht, &ht, sizeof(ht))) { 159 if (!sdata->ht_opmode_valid ||
160 sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
162 changed |= BSS_CHANGED_HT; 161 changed |= BSS_CHANGED_HT;
163 sdata->vif.bss_conf.ht = ht; 162 sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
163 sdata->ht_opmode_valid = true;
164 } 164 }
165 165
166 return changed; 166 return changed;
@@ -1043,11 +1043,16 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1043 1043
1044 rcu_read_unlock(); 1044 rcu_read_unlock();
1045 1045
1046 ieee80211_set_wmm_default(sdata);
1047
1046 ieee80211_recalc_idle(local); 1048 ieee80211_recalc_idle(local);
1047 1049
1048 /* channel(_type) changes are handled by ieee80211_hw_config */ 1050 /* channel(_type) changes are handled by ieee80211_hw_config */
1049 local->oper_channel_type = NL80211_CHAN_NO_HT; 1051 local->oper_channel_type = NL80211_CHAN_NO_HT;
1050 1052
1053 /* on the next assoc, re-program HT parameters */
1054 sdata->ht_opmode_valid = false;
1055
1051 local->power_constr_level = 0; 1056 local->power_constr_level = 0;
1052 1057
1053 del_timer_sync(&local->dynamic_ps_timer); 1058 del_timer_sync(&local->dynamic_ps_timer);
@@ -1178,6 +1183,17 @@ void ieee80211_beacon_loss_work(struct work_struct *work)
1178 u.mgd.beacon_loss_work); 1183 u.mgd.beacon_loss_work);
1179 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1184 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1180 1185
1186 /*
1187 * The driver has already reported this event and we have
1188 * already sent a probe request. Maybe the AP died and the
1189 * driver keeps reporting until we disassociate... We have
1190 * to ignore that because otherwise we would continually
1191 * reset the timer and never check whether we received a
1192 * probe response!
1193 */
1194 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL)
1195 return;
1196
1181#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1197#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1182 if (net_ratelimit()) { 1198 if (net_ratelimit()) {
1183 printk(KERN_DEBUG "%s: driver reports beacon loss from AP %pM " 1199 printk(KERN_DEBUG "%s: driver reports beacon loss from AP %pM "
@@ -1190,7 +1206,7 @@ void ieee80211_beacon_loss_work(struct work_struct *work)
1190 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, 1206 ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
1191 ifmgd->ssid_len, NULL, 0); 1207 ifmgd->ssid_len, NULL, 0);
1192 1208
1193 mod_timer(&ifmgd->timer, jiffies + IEEE80211_MONITORING_INTERVAL); 1209 mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT);
1194} 1210}
1195 1211
1196void ieee80211_beacon_loss(struct ieee80211_vif *vif) 1212void ieee80211_beacon_loss(struct ieee80211_vif *vif)
@@ -1227,7 +1243,7 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
1227 } 1243 }
1228 1244
1229 if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) && 1245 if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) &&
1230 time_after(jiffies, sta->last_rx + IEEE80211_MONITORING_INTERVAL)) { 1246 time_after(jiffies, sta->last_rx + IEEE80211_PROBE_WAIT)) {
1231 printk(KERN_DEBUG "%s: no probe response from AP %pM " 1247 printk(KERN_DEBUG "%s: no probe response from AP %pM "
1232 "- disassociating\n", 1248 "- disassociating\n",
1233 sdata->dev->name, ifmgd->bssid); 1249 sdata->dev->name, ifmgd->bssid);
@@ -1577,8 +1593,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1577 * to between the sta_info_alloc() and sta_info_insert() above. 1593 * to between the sta_info_alloc() and sta_info_insert() above.
1578 */ 1594 */
1579 1595
1580 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP | 1596 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP);
1581 WLAN_STA_AUTHORIZED); 1597 if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
1598 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
1582 1599
1583 rates = 0; 1600 rates = 0;
1584 basic_rates = 0; 1601 basic_rates = 0;
@@ -1658,6 +1675,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1658 if (elems.wmm_param) 1675 if (elems.wmm_param)
1659 ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param, 1676 ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param,
1660 elems.wmm_param_len); 1677 elems.wmm_param_len);
1678 else
1679 ieee80211_set_wmm_default(sdata);
1661 1680
1662 if (elems.ht_info_elem && elems.wmm_param && 1681 if (elems.ht_info_elem && elems.wmm_param &&
1663 (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) && 1682 (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) &&
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index d052f4004829..f962bd1b16e2 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -630,15 +630,6 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
630 * possible. 630 * possible.
631 */ 631 */
632 632
633 if (!ieee80211_has_protected(hdr->frame_control)) {
634 if (!ieee80211_is_mgmt(hdr->frame_control) ||
635 rx->sta == NULL || !test_sta_flags(rx->sta, WLAN_STA_MFP))
636 return RX_CONTINUE;
637 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
638 if (mmie_keyidx < 0)
639 return RX_CONTINUE;
640 }
641
642 /* 633 /*
643 * No point in finding a key and decrypting if the frame is neither 634 * No point in finding a key and decrypting if the frame is neither
644 * addressed to us nor a multicast frame. 635 * addressed to us nor a multicast frame.
@@ -649,8 +640,14 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
649 if (rx->sta) 640 if (rx->sta)
650 stakey = rcu_dereference(rx->sta->key); 641 stakey = rcu_dereference(rx->sta->key);
651 642
643 if (!ieee80211_has_protected(hdr->frame_control))
644 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
645
652 if (!is_multicast_ether_addr(hdr->addr1) && stakey) { 646 if (!is_multicast_ether_addr(hdr->addr1) && stakey) {
653 rx->key = stakey; 647 rx->key = stakey;
648 /* Skip decryption if the frame is not protected. */
649 if (!ieee80211_has_protected(hdr->frame_control))
650 return RX_CONTINUE;
654 } else if (mmie_keyidx >= 0) { 651 } else if (mmie_keyidx >= 0) {
655 /* Broadcast/multicast robust management frame / BIP */ 652 /* Broadcast/multicast robust management frame / BIP */
656 if ((rx->status->flag & RX_FLAG_DECRYPTED) && 653 if ((rx->status->flag & RX_FLAG_DECRYPTED) &&
@@ -661,6 +658,21 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
661 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) 658 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
662 return RX_DROP_MONITOR; /* unexpected BIP keyidx */ 659 return RX_DROP_MONITOR; /* unexpected BIP keyidx */
663 rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); 660 rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]);
661 } else if (!ieee80211_has_protected(hdr->frame_control)) {
662 /*
663 * The frame was not protected, so skip decryption. However, we
664 * need to set rx->key if there is a key that could have been
665 * used so that the frame may be dropped if encryption would
666 * have been expected.
667 */
668 struct ieee80211_key *key = NULL;
669 if (ieee80211_is_mgmt(hdr->frame_control) &&
670 is_multicast_ether_addr(hdr->addr1) &&
671 (key = rcu_dereference(rx->sdata->default_mgmt_key)))
672 rx->key = key;
673 else if ((key = rcu_dereference(rx->sdata->default_key)))
674 rx->key = key;
675 return RX_CONTINUE;
664 } else { 676 } else {
665 /* 677 /*
666 * The device doesn't give us the IV so we won't be 678 * The device doesn't give us the IV so we won't be
@@ -1209,17 +1221,27 @@ ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
1209 /* Drop unencrypted frames if key is set. */ 1221 /* Drop unencrypted frames if key is set. */
1210 if (unlikely(!ieee80211_has_protected(fc) && 1222 if (unlikely(!ieee80211_has_protected(fc) &&
1211 !ieee80211_is_nullfunc(fc) && 1223 !ieee80211_is_nullfunc(fc) &&
1212 (!ieee80211_is_mgmt(fc) || 1224 ieee80211_is_data(fc) &&
1213 (ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
1214 rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP))) &&
1215 (rx->key || rx->sdata->drop_unencrypted)))
1216 return -EACCES;
1217 /* BIP does not use Protected field, so need to check MMIE */
1218 if (unlikely(rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP) &&
1219 ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&
1220 ieee80211_get_mmie_keyidx(rx->skb) < 0 &&
1221 (rx->key || rx->sdata->drop_unencrypted))) 1225 (rx->key || rx->sdata->drop_unencrypted)))
1222 return -EACCES; 1226 return -EACCES;
1227 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) {
1228 if (unlikely(ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
1229 rx->key))
1230 return -EACCES;
1231 /* BIP does not use Protected field, so need to check MMIE */
1232 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb)
1233 && ieee80211_get_mmie_keyidx(rx->skb) < 0 &&
1234 rx->key))
1235 return -EACCES;
1236 /*
1237 * When using MFP, Action frames are not allowed prior to
1238 * having configured keys.
1239 */
1240 if (unlikely(ieee80211_is_action(fc) && !rx->key &&
1241 ieee80211_is_robust_mgmt_frame(
1242 (struct ieee80211_hdr *) rx->skb->data)))
1243 return -EACCES;
1244 }
1223 1245
1224 return 0; 1246 return 0;
1225} 1247}
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index c99ef8d04d3d..e65d74ba404b 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -298,6 +298,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
298 was_hw_scan = local->hw_scanning; 298 was_hw_scan = local->hw_scanning;
299 local->hw_scanning = false; 299 local->hw_scanning = false;
300 local->sw_scanning = false; 300 local->sw_scanning = false;
301 local->scan_channel = NULL;
301 302
302 /* we only have to protect scan_req and hw/sw scan */ 303 /* we only have to protect scan_req and hw/sw scan */
303 mutex_unlock(&local->scan_mtx); 304 mutex_unlock(&local->scan_mtx);
@@ -558,24 +559,39 @@ void ieee80211_scan_work(struct work_struct *work)
558 if (skip) 559 if (skip)
559 break; 560 break;
560 561
561 next_delay = IEEE80211_PROBE_DELAY + 562 /*
562 usecs_to_jiffies(local->hw.channel_change_time); 563 * Probe delay is used to update the NAV, cf. 11.1.3.2.2
564 * (which unfortunately doesn't say _why_ step a) is done,
565 * but it waits for the probe delay or until a frame is
566 * received - and the received frame would update the NAV).
567 * For now, we do not support waiting until a frame is
568 * received.
569 *
570 * In any case, it is not necessary for a passive scan.
571 */
572 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
573 !local->scan_req->n_ssids) {
574 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
575 break;
576 }
577
578 next_delay = IEEE80211_PROBE_DELAY;
563 local->scan_state = SCAN_SEND_PROBE; 579 local->scan_state = SCAN_SEND_PROBE;
564 break; 580 break;
565 case SCAN_SEND_PROBE: 581 case SCAN_SEND_PROBE:
566 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
567 local->scan_state = SCAN_SET_CHANNEL;
568
569 if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
570 !local->scan_req->n_ssids)
571 break;
572 for (i = 0; i < local->scan_req->n_ssids; i++) 582 for (i = 0; i < local->scan_req->n_ssids; i++)
573 ieee80211_send_probe_req( 583 ieee80211_send_probe_req(
574 sdata, NULL, 584 sdata, NULL,
575 local->scan_req->ssids[i].ssid, 585 local->scan_req->ssids[i].ssid,
576 local->scan_req->ssids[i].ssid_len, 586 local->scan_req->ssids[i].ssid_len,
577 local->scan_req->ie, local->scan_req->ie_len); 587 local->scan_req->ie, local->scan_req->ie_len);
588
589 /*
590 * After sending probe requests, wait for probe responses
591 * on the channel.
592 */
578 next_delay = IEEE80211_CHANNEL_TIME; 593 next_delay = IEEE80211_CHANNEL_TIME;
594 local->scan_state = SCAN_SET_CHANNEL;
579 break; 595 break;
580 } 596 }
581 597
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 5f9a8d7af83d..8f68bf9746d0 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1087,7 +1087,10 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1087 info->flags |= IEEE80211_TX_CTL_NO_ACK; 1087 info->flags |= IEEE80211_TX_CTL_NO_ACK;
1088 } else { 1088 } else {
1089 tx->flags |= IEEE80211_TX_UNICAST; 1089 tx->flags |= IEEE80211_TX_UNICAST;
1090 info->flags &= ~IEEE80211_TX_CTL_NO_ACK; 1090 if (unlikely(local->wifi_wme_noack_test))
1091 info->flags |= IEEE80211_TX_CTL_NO_ACK;
1092 else
1093 info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
1091 } 1094 }
1092 1095
1093 if (tx->flags & IEEE80211_TX_FRAGMENTED) { 1096 if (tx->flags & IEEE80211_TX_FRAGMENTED) {
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 97b613affe08..0689a8fbd1e6 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -708,26 +708,62 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
708{ 708{
709 struct ieee80211_local *local = sdata->local; 709 struct ieee80211_local *local = sdata->local;
710 struct ieee80211_tx_queue_params qparam; 710 struct ieee80211_tx_queue_params qparam;
711 int i; 711 int queue;
712 bool use_11b;
713 int aCWmin, aCWmax;
712 714
713 if (!local->ops->conf_tx) 715 if (!local->ops->conf_tx)
714 return; 716 return;
715 717
716 memset(&qparam, 0, sizeof(qparam)); 718 memset(&qparam, 0, sizeof(qparam));
717 719
718 qparam.aifs = 2; 720 use_11b = (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) &&
719 721 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE);
720 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
721 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE))
722 qparam.cw_min = 31;
723 else
724 qparam.cw_min = 15;
725 722
726 qparam.cw_max = 1023; 723 for (queue = 0; queue < local_to_hw(local)->queues; queue++) {
727 qparam.txop = 0; 724 /* Set defaults according to 802.11-2007 Table 7-37 */
725 aCWmax = 1023;
726 if (use_11b)
727 aCWmin = 31;
728 else
729 aCWmin = 15;
730
731 switch (queue) {
732 case 3: /* AC_BK */
733 qparam.cw_max = aCWmin;
734 qparam.cw_min = aCWmax;
735 qparam.txop = 0;
736 qparam.aifs = 7;
737 break;
738 default: /* never happens but let's not leave undefined */
739 case 2: /* AC_BE */
740 qparam.cw_max = aCWmin;
741 qparam.cw_min = aCWmax;
742 qparam.txop = 0;
743 qparam.aifs = 3;
744 break;
745 case 1: /* AC_VI */
746 qparam.cw_max = aCWmin;
747 qparam.cw_min = (aCWmin + 1) / 2 - 1;
748 if (use_11b)
749 qparam.txop = 6016/32;
750 else
751 qparam.txop = 3008/32;
752 qparam.aifs = 2;
753 break;
754 case 0: /* AC_VO */
755 qparam.cw_max = (aCWmin + 1) / 2 - 1;
756 qparam.cw_min = (aCWmin + 1) / 4 - 1;
757 if (use_11b)
758 qparam.txop = 3264/32;
759 else
760 qparam.txop = 1504/32;
761 qparam.aifs = 2;
762 break;
763 }
728 764
729 for (i = 0; i < local_to_hw(local)->queues; i++) 765 drv_conf_tx(local, queue, &qparam);
730 drv_conf_tx(local, i, &qparam); 766 }
731} 767}
732 768
733void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 769void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 6b4eb8d43a4e..c14394744a9c 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -27,100 +27,6 @@
27#include "aes_ccm.h" 27#include "aes_ccm.h"
28 28
29 29
30static int ieee80211_set_encryption(struct ieee80211_sub_if_data *sdata, u8 *sta_addr,
31 int idx, int alg, int remove,
32 int set_tx_key, const u8 *_key,
33 size_t key_len)
34{
35 struct ieee80211_local *local = sdata->local;
36 struct sta_info *sta;
37 struct ieee80211_key *key;
38 int err;
39
40 if (alg == ALG_AES_CMAC) {
41 if (idx < NUM_DEFAULT_KEYS ||
42 idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) {
43 printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d "
44 "(BIP)\n", sdata->dev->name, idx);
45 return -EINVAL;
46 }
47 } else if (idx < 0 || idx >= NUM_DEFAULT_KEYS) {
48 printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d\n",
49 sdata->dev->name, idx);
50 return -EINVAL;
51 }
52
53 if (remove) {
54 rcu_read_lock();
55
56 err = 0;
57
58 if (is_broadcast_ether_addr(sta_addr)) {
59 key = sdata->keys[idx];
60 } else {
61 sta = sta_info_get(local, sta_addr);
62 if (!sta) {
63 err = -ENOENT;
64 goto out_unlock;
65 }
66 key = sta->key;
67 }
68
69 ieee80211_key_free(key);
70 } else {
71 key = ieee80211_key_alloc(alg, idx, key_len, _key);
72 if (!key)
73 return -ENOMEM;
74
75 sta = NULL;
76 err = 0;
77
78 rcu_read_lock();
79
80 if (!is_broadcast_ether_addr(sta_addr)) {
81 set_tx_key = 0;
82 /*
83 * According to the standard, the key index of a
84 * pairwise key must be zero. However, some AP are
85 * broken when it comes to WEP key indices, so we
86 * work around this.
87 */
88 if (idx != 0 && alg != ALG_WEP) {
89 ieee80211_key_free(key);
90 err = -EINVAL;
91 goto out_unlock;
92 }
93
94 sta = sta_info_get(local, sta_addr);
95 if (!sta) {
96 ieee80211_key_free(key);
97 err = -ENOENT;
98 goto out_unlock;
99 }
100 }
101
102 if (alg == ALG_WEP &&
103 key_len != LEN_WEP40 && key_len != LEN_WEP104) {
104 ieee80211_key_free(key);
105 err = -EINVAL;
106 goto out_unlock;
107 }
108
109 ieee80211_key_link(key, sdata, sta);
110
111 if (set_tx_key || (!sta && !sdata->default_key && key))
112 ieee80211_set_default_key(sdata, idx);
113 if (alg == ALG_AES_CMAC &&
114 (set_tx_key || (!sta && !sdata->default_mgmt_key && key)))
115 ieee80211_set_default_mgmt_key(sdata, idx);
116 }
117
118 out_unlock:
119 rcu_read_unlock();
120
121 return err;
122}
123
124static int ieee80211_ioctl_siwgenie(struct net_device *dev, 30static int ieee80211_ioctl_siwgenie(struct net_device *dev,
125 struct iw_request_info *info, 31 struct iw_request_info *info,
126 struct iw_point *data, char *extra) 32 struct iw_point *data, char *extra)
@@ -135,6 +41,7 @@ static int ieee80211_ioctl_siwgenie(struct net_device *dev,
135 return ret; 41 return ret;
136 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL; 42 sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
137 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME; 43 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
44 sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
138 ieee80211_sta_req_auth(sdata); 45 ieee80211_sta_req_auth(sdata);
139 return 0; 46 return 0;
140 } 47 }
@@ -218,6 +125,7 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
218 return ret; 125 return ret;
219 126
220 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME; 127 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
128 sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
221 ieee80211_sta_req_auth(sdata); 129 ieee80211_sta_req_auth(sdata);
222 return 0; 130 return 0;
223 } 131 }
@@ -275,6 +183,7 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
275 if (ret) 183 if (ret)
276 return ret; 184 return ret;
277 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME; 185 sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
186 sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
278 ieee80211_sta_req_auth(sdata); 187 ieee80211_sta_req_auth(sdata);
279 return 0; 188 return 0;
280 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) { 189 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
@@ -472,109 +381,6 @@ static int ieee80211_ioctl_giwtxpower(struct net_device *dev,
472 return 0; 381 return 0;
473} 382}
474 383
475static int ieee80211_ioctl_siwencode(struct net_device *dev,
476 struct iw_request_info *info,
477 struct iw_point *erq, char *keybuf)
478{
479 struct ieee80211_sub_if_data *sdata;
480 int idx, i, alg = ALG_WEP;
481 u8 bcaddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
482 int remove = 0, ret;
483
484 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
485
486 idx = erq->flags & IW_ENCODE_INDEX;
487 if (idx == 0) {
488 if (sdata->default_key)
489 for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
490 if (sdata->default_key == sdata->keys[i]) {
491 idx = i;
492 break;
493 }
494 }
495 } else if (idx < 1 || idx > 4)
496 return -EINVAL;
497 else
498 idx--;
499
500 if (erq->flags & IW_ENCODE_DISABLED)
501 remove = 1;
502 else if (erq->length == 0) {
503 /* No key data - just set the default TX key index */
504 ieee80211_set_default_key(sdata, idx);
505 return 0;
506 }
507
508 ret = ieee80211_set_encryption(
509 sdata, bcaddr,
510 idx, alg, remove,
511 !sdata->default_key,
512 keybuf, erq->length);
513
514 if (!ret && sdata->vif.type == NL80211_IFTYPE_STATION) {
515 if (remove)
516 sdata->u.mgd.flags &= ~IEEE80211_STA_TKIP_WEP_USED;
517 else
518 sdata->u.mgd.flags |= IEEE80211_STA_TKIP_WEP_USED;
519 }
520
521 return ret;
522}
523
524
525static int ieee80211_ioctl_giwencode(struct net_device *dev,
526 struct iw_request_info *info,
527 struct iw_point *erq, char *key)
528{
529 struct ieee80211_sub_if_data *sdata;
530 int idx, i;
531
532 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
533
534 idx = erq->flags & IW_ENCODE_INDEX;
535 if (idx < 1 || idx > 4) {
536 idx = -1;
537 if (!sdata->default_key)
538 idx = 0;
539 else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
540 if (sdata->default_key == sdata->keys[i]) {
541 idx = i;
542 break;
543 }
544 }
545 if (idx < 0)
546 return -EINVAL;
547 } else
548 idx--;
549
550 erq->flags = idx + 1;
551
552 if (!sdata->keys[idx]) {
553 erq->length = 0;
554 erq->flags |= IW_ENCODE_DISABLED;
555 return 0;
556 }
557
558 memcpy(key, sdata->keys[idx]->conf.key,
559 min_t(int, erq->length, sdata->keys[idx]->conf.keylen));
560 erq->length = sdata->keys[idx]->conf.keylen;
561 erq->flags |= IW_ENCODE_ENABLED;
562
563 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
564 switch (sdata->u.mgd.auth_alg) {
565 case WLAN_AUTH_OPEN:
566 case WLAN_AUTH_LEAP:
567 erq->flags |= IW_ENCODE_OPEN;
568 break;
569 case WLAN_AUTH_SHARED_KEY:
570 erq->flags |= IW_ENCODE_RESTRICTED;
571 break;
572 }
573 }
574
575 return 0;
576}
577
578static int ieee80211_ioctl_siwpower(struct net_device *dev, 384static int ieee80211_ioctl_siwpower(struct net_device *dev,
579 struct iw_request_info *info, 385 struct iw_request_info *info,
580 struct iw_param *wrq, 386 struct iw_param *wrq,
@@ -809,82 +615,6 @@ static int ieee80211_ioctl_giwauth(struct net_device *dev,
809} 615}
810 616
811 617
812static int ieee80211_ioctl_siwencodeext(struct net_device *dev,
813 struct iw_request_info *info,
814 struct iw_point *erq, char *extra)
815{
816 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
817 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
818 int uninitialized_var(alg), idx, i, remove = 0;
819
820 switch (ext->alg) {
821 case IW_ENCODE_ALG_NONE:
822 remove = 1;
823 break;
824 case IW_ENCODE_ALG_WEP:
825 alg = ALG_WEP;
826 break;
827 case IW_ENCODE_ALG_TKIP:
828 alg = ALG_TKIP;
829 break;
830 case IW_ENCODE_ALG_CCMP:
831 alg = ALG_CCMP;
832 break;
833 case IW_ENCODE_ALG_AES_CMAC:
834 alg = ALG_AES_CMAC;
835 break;
836 default:
837 return -EOPNOTSUPP;
838 }
839
840 if (erq->flags & IW_ENCODE_DISABLED)
841 remove = 1;
842
843 idx = erq->flags & IW_ENCODE_INDEX;
844 if (alg == ALG_AES_CMAC) {
845 if (idx < NUM_DEFAULT_KEYS + 1 ||
846 idx > NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) {
847 idx = -1;
848 if (!sdata->default_mgmt_key)
849 idx = 0;
850 else for (i = NUM_DEFAULT_KEYS;
851 i < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS;
852 i++) {
853 if (sdata->default_mgmt_key == sdata->keys[i])
854 {
855 idx = i;
856 break;
857 }
858 }
859 if (idx < 0)
860 return -EINVAL;
861 } else
862 idx--;
863 } else {
864 if (idx < 1 || idx > 4) {
865 idx = -1;
866 if (!sdata->default_key)
867 idx = 0;
868 else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
869 if (sdata->default_key == sdata->keys[i]) {
870 idx = i;
871 break;
872 }
873 }
874 if (idx < 0)
875 return -EINVAL;
876 } else
877 idx--;
878 }
879
880 return ieee80211_set_encryption(sdata, ext->addr.sa_data, idx, alg,
881 remove,
882 ext->ext_flags &
883 IW_ENCODE_EXT_SET_TX_KEY,
884 ext->key, ext->key_len);
885}
886
887
888/* Structures to export the Wireless Handlers */ 618/* Structures to export the Wireless Handlers */
889 619
890static const iw_handler ieee80211_handler[] = 620static const iw_handler ieee80211_handler[] =
@@ -931,8 +661,8 @@ static const iw_handler ieee80211_handler[] =
931 (iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */ 661 (iw_handler) ieee80211_ioctl_giwtxpower, /* SIOCGIWTXPOW */
932 (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */ 662 (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */
933 (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */ 663 (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */
934 (iw_handler) ieee80211_ioctl_siwencode, /* SIOCSIWENCODE */ 664 (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */
935 (iw_handler) ieee80211_ioctl_giwencode, /* SIOCGIWENCODE */ 665 (iw_handler) cfg80211_wext_giwencode, /* SIOCGIWENCODE */
936 (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */ 666 (iw_handler) ieee80211_ioctl_siwpower, /* SIOCSIWPOWER */
937 (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */ 667 (iw_handler) ieee80211_ioctl_giwpower, /* SIOCGIWPOWER */
938 (iw_handler) NULL, /* -- hole -- */ 668 (iw_handler) NULL, /* -- hole -- */
@@ -941,7 +671,7 @@ static const iw_handler ieee80211_handler[] =
941 (iw_handler) NULL, /* SIOCGIWGENIE */ 671 (iw_handler) NULL, /* SIOCGIWGENIE */
942 (iw_handler) ieee80211_ioctl_siwauth, /* SIOCSIWAUTH */ 672 (iw_handler) ieee80211_ioctl_siwauth, /* SIOCSIWAUTH */
943 (iw_handler) ieee80211_ioctl_giwauth, /* SIOCGIWAUTH */ 673 (iw_handler) ieee80211_ioctl_giwauth, /* SIOCGIWAUTH */
944 (iw_handler) ieee80211_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */ 674 (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */
945 (iw_handler) NULL, /* SIOCGIWENCODEEXT */ 675 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
946 (iw_handler) NULL, /* SIOCSIWPMKSA */ 676 (iw_handler) NULL, /* SIOCSIWPMKSA */
947 (iw_handler) NULL, /* -- hole -- */ 677 (iw_handler) NULL, /* -- hole -- */
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 0b8ad1f4ecdd..45b74f38b867 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -133,7 +133,7 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb)
133 u8 *p = ieee80211_get_qos_ctl(hdr); 133 u8 *p = ieee80211_get_qos_ctl(hdr);
134 u8 ack_policy = 0; 134 u8 ack_policy = 0;
135 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; 135 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
136 if (local->wifi_wme_noack_test) 136 if (unlikely(local->wifi_wme_noack_test))
137 ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK << 137 ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK <<
138 QOS_CONTROL_ACK_POLICY_SHIFT; 138 QOS_CONTROL_ACK_POLICY_SHIFT;
139 /* qos header is 2 bytes, second reserved */ 139 /* qos header is 2 bytes, second reserved */
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 2006a4ee60eb..47c20eb0c04d 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * This is the linux wireless configuration interface. 2 * This is the linux wireless configuration interface.
3 * 3 *
4 * Copyright 2006-2008 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2009 Johannes Berg <johannes@sipsolutions.net>
5 */ 5 */
6 6
7#include <linux/if.h> 7#include <linux/if.h>
@@ -457,6 +457,10 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
457 "symlink to netdev!\n"); 457 "symlink to netdev!\n");
458 } 458 }
459 dev->ieee80211_ptr->netdev = dev; 459 dev->ieee80211_ptr->netdev = dev;
460#ifdef CONFIG_WIRELESS_EXT
461 dev->ieee80211_ptr->wext.default_key = -1;
462 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
463#endif
460 mutex_unlock(&rdev->devlist_mtx); 464 mutex_unlock(&rdev->devlist_mtx);
461 break; 465 break;
462 case NETDEV_GOING_DOWN: 466 case NETDEV_GOING_DOWN:
@@ -470,9 +474,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
470#ifdef CONFIG_WIRELESS_EXT 474#ifdef CONFIG_WIRELESS_EXT
471 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) 475 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
472 break; 476 break;
473 if (!dev->ieee80211_ptr->wext.ssid_len) 477 if (!dev->ieee80211_ptr->wext.ibss.ssid_len)
474 break; 478 break;
475 cfg80211_join_ibss(rdev, dev, &dev->ieee80211_ptr->wext); 479 cfg80211_join_ibss(rdev, dev, &dev->ieee80211_ptr->wext.ibss);
476 break; 480 break;
477#endif 481#endif
478 case NETDEV_UNREGISTER: 482 case NETDEV_UNREGISTER:
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 3e49d3399311..f14b6c5f4221 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Wireless configuration interface internals. 2 * Wireless configuration interface internals.
3 * 3 *
4 * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2009 Johannes Berg <johannes@sipsolutions.net>
5 */ 5 */
6#ifndef __NET_WIRELESS_CORE_H 6#ifndef __NET_WIRELESS_CORE_H
7#define __NET_WIRELESS_CORE_H 7#define __NET_WIRELESS_CORE_H
@@ -151,4 +151,8 @@ void cfg80211_clear_ibss(struct net_device *dev, bool nowext);
151int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, 151int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
152 struct net_device *dev, bool nowext); 152 struct net_device *dev, bool nowext);
153 153
154/* internal helpers */
155int cfg80211_validate_key_settings(struct key_params *params, int key_idx,
156 const u8 *mac_addr);
157
154#endif /* __NET_WIRELESS_CORE_H */ 158#endif /* __NET_WIRELESS_CORE_H */
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 3c38afaed28a..a4a1c3498ff2 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -63,7 +63,7 @@ int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
63 return -EALREADY; 63 return -EALREADY;
64 64
65#ifdef CONFIG_WIRELESS_EXT 65#ifdef CONFIG_WIRELESS_EXT
66 wdev->wext.channel = params->channel; 66 wdev->wext.ibss.channel = params->channel;
67#endif 67#endif
68 err = rdev->ops->join_ibss(&rdev->wiphy, dev, params); 68 err = rdev->ops->join_ibss(&rdev->wiphy, dev, params);
69 69
@@ -90,7 +90,7 @@ void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
90 memset(wdev->bssid, 0, ETH_ALEN); 90 memset(wdev->bssid, 0, ETH_ALEN);
91#ifdef CONFIG_WIRELESS_EXT 91#ifdef CONFIG_WIRELESS_EXT
92 if (!nowext) 92 if (!nowext)
93 wdev->wext.ssid_len = 0; 93 wdev->wext.ibss.ssid_len = 0;
94#endif 94#endif
95} 95}
96 96
@@ -116,11 +116,11 @@ static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
116 enum ieee80211_band band; 116 enum ieee80211_band band;
117 int i; 117 int i;
118 118
119 if (!wdev->wext.beacon_interval) 119 if (!wdev->wext.ibss.beacon_interval)
120 wdev->wext.beacon_interval = 100; 120 wdev->wext.ibss.beacon_interval = 100;
121 121
122 /* try to find an IBSS channel if none requested ... */ 122 /* try to find an IBSS channel if none requested ... */
123 if (!wdev->wext.channel) { 123 if (!wdev->wext.ibss.channel) {
124 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 124 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
125 struct ieee80211_supported_band *sband; 125 struct ieee80211_supported_band *sband;
126 struct ieee80211_channel *chan; 126 struct ieee80211_channel *chan;
@@ -135,27 +135,27 @@ static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
135 continue; 135 continue;
136 if (chan->flags & IEEE80211_CHAN_DISABLED) 136 if (chan->flags & IEEE80211_CHAN_DISABLED)
137 continue; 137 continue;
138 wdev->wext.channel = chan; 138 wdev->wext.ibss.channel = chan;
139 break; 139 break;
140 } 140 }
141 141
142 if (wdev->wext.channel) 142 if (wdev->wext.ibss.channel)
143 break; 143 break;
144 } 144 }
145 145
146 if (!wdev->wext.channel) 146 if (!wdev->wext.ibss.channel)
147 return -EINVAL; 147 return -EINVAL;
148 } 148 }
149 149
150 /* don't join -- SSID is not there */ 150 /* don't join -- SSID is not there */
151 if (!wdev->wext.ssid_len) 151 if (!wdev->wext.ibss.ssid_len)
152 return 0; 152 return 0;
153 153
154 if (!netif_running(wdev->netdev)) 154 if (!netif_running(wdev->netdev))
155 return 0; 155 return 0;
156 156
157 return cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy), 157 return cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy),
158 wdev->netdev, &wdev->wext); 158 wdev->netdev, &wdev->wext.ibss);
159} 159}
160 160
161int cfg80211_ibss_wext_siwfreq(struct net_device *dev, 161int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
@@ -182,7 +182,7 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
182 chan->flags & IEEE80211_CHAN_DISABLED)) 182 chan->flags & IEEE80211_CHAN_DISABLED))
183 return -EINVAL; 183 return -EINVAL;
184 184
185 if (wdev->wext.channel == chan) 185 if (wdev->wext.ibss.channel == chan)
186 return 0; 186 return 0;
187 187
188 if (wdev->ssid_len) { 188 if (wdev->ssid_len) {
@@ -193,11 +193,11 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
193 } 193 }
194 194
195 if (chan) { 195 if (chan) {
196 wdev->wext.channel = chan; 196 wdev->wext.ibss.channel = chan;
197 wdev->wext.channel_fixed = true; 197 wdev->wext.ibss.channel_fixed = true;
198 } else { 198 } else {
199 /* cfg80211_ibss_wext_join will pick one if needed */ 199 /* cfg80211_ibss_wext_join will pick one if needed */
200 wdev->wext.channel_fixed = false; 200 wdev->wext.ibss.channel_fixed = false;
201 } 201 }
202 202
203 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); 203 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
@@ -218,8 +218,8 @@ int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
218 218
219 if (wdev->current_bss) 219 if (wdev->current_bss)
220 chan = wdev->current_bss->channel; 220 chan = wdev->current_bss->channel;
221 else if (wdev->wext.channel) 221 else if (wdev->wext.ibss.channel)
222 chan = wdev->wext.channel; 222 chan = wdev->wext.ibss.channel;
223 223
224 if (chan) { 224 if (chan) {
225 freq->m = chan->center_freq; 225 freq->m = chan->center_freq;
@@ -259,9 +259,9 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev,
259 if (len > 0 && ssid[len - 1] == '\0') 259 if (len > 0 && ssid[len - 1] == '\0')
260 len--; 260 len--;
261 261
262 wdev->wext.ssid = wdev->ssid; 262 wdev->wext.ibss.ssid = wdev->ssid;
263 memcpy(wdev->wext.ssid, ssid, len); 263 memcpy(wdev->wext.ibss.ssid, ssid, len);
264 wdev->wext.ssid_len = len; 264 wdev->wext.ibss.ssid_len = len;
265 265
266 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); 266 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
267} 267}
@@ -284,10 +284,10 @@ int cfg80211_ibss_wext_giwessid(struct net_device *dev,
284 data->flags = 1; 284 data->flags = 1;
285 data->length = wdev->ssid_len; 285 data->length = wdev->ssid_len;
286 memcpy(ssid, wdev->ssid, data->length); 286 memcpy(ssid, wdev->ssid, data->length);
287 } else if (wdev->wext.ssid && wdev->wext.ssid_len) { 287 } else if (wdev->wext.ibss.ssid && wdev->wext.ibss.ssid_len) {
288 data->flags = 1; 288 data->flags = 1;
289 data->length = wdev->wext.ssid_len; 289 data->length = wdev->wext.ibss.ssid_len;
290 memcpy(ssid, wdev->wext.ssid, data->length); 290 memcpy(ssid, wdev->wext.ibss.ssid, data->length);
291 } 291 }
292 292
293 return 0; 293 return 0;
@@ -318,12 +318,12 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev,
318 bssid = NULL; 318 bssid = NULL;
319 319
320 /* both automatic */ 320 /* both automatic */
321 if (!bssid && !wdev->wext.bssid) 321 if (!bssid && !wdev->wext.ibss.bssid)
322 return 0; 322 return 0;
323 323
324 /* fixed already - and no change */ 324 /* fixed already - and no change */
325 if (wdev->wext.bssid && bssid && 325 if (wdev->wext.ibss.bssid && bssid &&
326 compare_ether_addr(bssid, wdev->wext.bssid) == 0) 326 compare_ether_addr(bssid, wdev->wext.ibss.bssid) == 0)
327 return 0; 327 return 0;
328 328
329 if (wdev->ssid_len) { 329 if (wdev->ssid_len) {
@@ -334,10 +334,10 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev,
334 } 334 }
335 335
336 if (bssid) { 336 if (bssid) {
337 memcpy(wdev->wext_bssid, bssid, ETH_ALEN); 337 memcpy(wdev->wext.bssid, bssid, ETH_ALEN);
338 wdev->wext.bssid = wdev->wext_bssid; 338 wdev->wext.ibss.bssid = wdev->wext.bssid;
339 } else 339 } else
340 wdev->wext.bssid = NULL; 340 wdev->wext.ibss.bssid = NULL;
341 341
342 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); 342 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
343} 343}
@@ -356,8 +356,8 @@ int cfg80211_ibss_wext_giwap(struct net_device *dev,
356 356
357 ap_addr->sa_family = ARPHRD_ETHER; 357 ap_addr->sa_family = ARPHRD_ETHER;
358 358
359 if (wdev->wext.bssid) { 359 if (wdev->wext.ibss.bssid) {
360 memcpy(ap_addr->sa_data, wdev->wext.bssid, ETH_ALEN); 360 memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN);
361 return 0; 361 return 0;
362 } 362 }
363 363
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 3c53c5cbc3a9..f0fec2f49828 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * This is the new netlink-based wireless configuration interface. 2 * This is the new netlink-based wireless configuration interface.
3 * 3 *
4 * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2009 Johannes Berg <johannes@sipsolutions.net>
5 */ 5 */
6 6
7#include <linux/if.h> 7#include <linux/if.h>
@@ -122,6 +122,11 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
122 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 }, 122 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
123 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG }, 123 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
124 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG }, 124 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
125 [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 },
126 [NL80211_ATTR_STA_FLAGS2] = {
127 .len = sizeof(struct nl80211_sta_flag_update),
128 },
129 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
125}; 130};
126 131
127/* IE validation */ 132/* IE validation */
@@ -1072,6 +1077,14 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1072 } 1077 }
1073 1078
1074 err = func(&drv->wiphy, dev, key_idx); 1079 err = func(&drv->wiphy, dev, key_idx);
1080#ifdef CONFIG_WIRELESS_EXT
1081 if (!err) {
1082 if (func == drv->ops->set_default_key)
1083 dev->ieee80211_ptr->wext.default_key = key_idx;
1084 else
1085 dev->ieee80211_ptr->wext.default_mgmt_key = key_idx;
1086 }
1087#endif
1075 1088
1076 out: 1089 out:
1077 cfg80211_put_dev(drv); 1090 cfg80211_put_dev(drv);
@@ -1102,6 +1115,11 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
1102 params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]); 1115 params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
1103 } 1116 }
1104 1117
1118 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
1119 params.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
1120 params.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
1121 }
1122
1105 if (info->attrs[NL80211_ATTR_KEY_IDX]) 1123 if (info->attrs[NL80211_ATTR_KEY_IDX])
1106 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); 1124 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
1107 1125
@@ -1110,44 +1128,8 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
1110 if (info->attrs[NL80211_ATTR_MAC]) 1128 if (info->attrs[NL80211_ATTR_MAC])
1111 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1129 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1112 1130
1113 if (key_idx > 5) 1131 if (cfg80211_validate_key_settings(&params, key_idx, mac_addr))
1114 return -EINVAL;
1115
1116 /*
1117 * Disallow pairwise keys with non-zero index unless it's WEP
1118 * (because current deployments use pairwise WEP keys with
1119 * non-zero indizes but 802.11i clearly specifies to use zero)
1120 */
1121 if (mac_addr && key_idx &&
1122 params.cipher != WLAN_CIPHER_SUITE_WEP40 &&
1123 params.cipher != WLAN_CIPHER_SUITE_WEP104)
1124 return -EINVAL;
1125
1126 /* TODO: add definitions for the lengths to linux/ieee80211.h */
1127 switch (params.cipher) {
1128 case WLAN_CIPHER_SUITE_WEP40:
1129 if (params.key_len != 5)
1130 return -EINVAL;
1131 break;
1132 case WLAN_CIPHER_SUITE_TKIP:
1133 if (params.key_len != 32)
1134 return -EINVAL;
1135 break;
1136 case WLAN_CIPHER_SUITE_CCMP:
1137 if (params.key_len != 16)
1138 return -EINVAL;
1139 break;
1140 case WLAN_CIPHER_SUITE_WEP104:
1141 if (params.key_len != 13)
1142 return -EINVAL;
1143 break;
1144 case WLAN_CIPHER_SUITE_AES_CMAC:
1145 if (params.key_len != 16)
1146 return -EINVAL;
1147 break;
1148 default:
1149 return -EINVAL; 1132 return -EINVAL;
1150 }
1151 1133
1152 rtnl_lock(); 1134 rtnl_lock();
1153 1135
@@ -1209,6 +1191,15 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
1209 1191
1210 err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr); 1192 err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
1211 1193
1194#ifdef CONFIG_WIRELESS_EXT
1195 if (!err) {
1196 if (key_idx == dev->ieee80211_ptr->wext.default_key)
1197 dev->ieee80211_ptr->wext.default_key = -1;
1198 else if (key_idx == dev->ieee80211_ptr->wext.default_mgmt_key)
1199 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
1200 }
1201#endif
1202
1212 out: 1203 out:
1213 cfg80211_put_dev(drv); 1204 cfg80211_put_dev(drv);
1214 dev_put(dev); 1205 dev_put(dev);
@@ -1349,15 +1340,36 @@ static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
1349 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG }, 1340 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
1350 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG }, 1341 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
1351 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG }, 1342 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
1343 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
1352}; 1344};
1353 1345
1354static int parse_station_flags(struct nlattr *nla, u32 *staflags) 1346static int parse_station_flags(struct genl_info *info,
1347 struct station_parameters *params)
1355{ 1348{
1356 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1]; 1349 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
1350 struct nlattr *nla;
1357 int flag; 1351 int flag;
1358 1352
1359 *staflags = 0; 1353 /*
1354 * Try parsing the new attribute first so userspace
1355 * can specify both for older kernels.
1356 */
1357 nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
1358 if (nla) {
1359 struct nl80211_sta_flag_update *sta_flags;
1360
1361 sta_flags = nla_data(nla);
1362 params->sta_flags_mask = sta_flags->mask;
1363 params->sta_flags_set = sta_flags->set;
1364 if ((params->sta_flags_mask |
1365 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
1366 return -EINVAL;
1367 return 0;
1368 }
1369
1370 /* if present, parse the old attribute */
1360 1371
1372 nla = info->attrs[NL80211_ATTR_STA_FLAGS];
1361 if (!nla) 1373 if (!nla)
1362 return 0; 1374 return 0;
1363 1375
@@ -1365,11 +1377,12 @@ static int parse_station_flags(struct nlattr *nla, u32 *staflags)
1365 nla, sta_flags_policy)) 1377 nla, sta_flags_policy))
1366 return -EINVAL; 1378 return -EINVAL;
1367 1379
1368 *staflags = STATION_FLAG_CHANGED; 1380 params->sta_flags_mask = (1 << __NL80211_STA_FLAG_AFTER_LAST) - 1;
1381 params->sta_flags_mask &= ~1;
1369 1382
1370 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) 1383 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
1371 if (flags[flag]) 1384 if (flags[flag])
1372 *staflags |= (1<<flag); 1385 params->sta_flags_set |= (1<<flag);
1373 1386
1374 return 0; 1387 return 0;
1375} 1388}
@@ -1665,8 +1678,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1665 params.ht_capa = 1678 params.ht_capa =
1666 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); 1679 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1667 1680
1668 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], 1681 if (parse_station_flags(info, &params))
1669 &params.station_flags))
1670 return -EINVAL; 1682 return -EINVAL;
1671 1683
1672 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) 1684 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
@@ -1735,8 +1747,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1735 params.ht_capa = 1747 params.ht_capa =
1736 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); 1748 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1737 1749
1738 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], 1750 if (parse_station_flags(info, &params))
1739 &params.station_flags))
1740 return -EINVAL; 1751 return -EINVAL;
1741 1752
1742 rtnl_lock(); 1753 rtnl_lock();
@@ -1745,6 +1756,12 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1745 if (err) 1756 if (err)
1746 goto out_rtnl; 1757 goto out_rtnl;
1747 1758
1759 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
1760 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) {
1761 err = -EINVAL;
1762 goto out;
1763 }
1764
1748 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan); 1765 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
1749 if (err) 1766 if (err)
1750 goto out; 1767 goto out;
@@ -1788,6 +1805,12 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
1788 if (err) 1805 if (err)
1789 goto out_rtnl; 1806 goto out_rtnl;
1790 1807
1808 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
1809 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) {
1810 err = -EINVAL;
1811 goto out;
1812 }
1813
1791 if (!drv->ops->del_station) { 1814 if (!drv->ops->del_station) {
1792 err = -EOPNOTSUPP; 1815 err = -EOPNOTSUPP;
1793 goto out; 1816 goto out;
@@ -3012,6 +3035,19 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3012 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 3035 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3013 } 3036 }
3014 3037
3038 if (info->attrs[NL80211_ATTR_USE_MFP]) {
3039 enum nl80211_mfp use_mfp =
3040 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
3041 if (use_mfp == NL80211_MFP_REQUIRED)
3042 req.use_mfp = true;
3043 else if (use_mfp != NL80211_MFP_NO) {
3044 err = -EINVAL;
3045 goto out;
3046 }
3047 }
3048
3049 req.control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
3050
3015 err = drv->ops->assoc(&drv->wiphy, dev, &req); 3051 err = drv->ops->assoc(&drv->wiphy, dev, &req);
3016 3052
3017out: 3053out:
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 5f7e997195c7..beb226e78cd7 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -138,3 +138,48 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
138 if (wiphy->bands[band]) 138 if (wiphy->bands[band])
139 set_mandatory_flags_band(wiphy->bands[band], band); 139 set_mandatory_flags_band(wiphy->bands[band], band);
140} 140}
141
142int cfg80211_validate_key_settings(struct key_params *params, int key_idx,
143 const u8 *mac_addr)
144{
145 if (key_idx > 5)
146 return -EINVAL;
147
148 /*
149 * Disallow pairwise keys with non-zero index unless it's WEP
150 * (because current deployments use pairwise WEP keys with
151 * non-zero indizes but 802.11i clearly specifies to use zero)
152 */
153 if (mac_addr && key_idx &&
154 params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
155 params->cipher != WLAN_CIPHER_SUITE_WEP104)
156 return -EINVAL;
157
158 /* TODO: add definitions for the lengths to linux/ieee80211.h */
159 switch (params->cipher) {
160 case WLAN_CIPHER_SUITE_WEP40:
161 if (params->key_len != 5)
162 return -EINVAL;
163 break;
164 case WLAN_CIPHER_SUITE_TKIP:
165 if (params->key_len != 32)
166 return -EINVAL;
167 break;
168 case WLAN_CIPHER_SUITE_CCMP:
169 if (params->key_len != 16)
170 return -EINVAL;
171 break;
172 case WLAN_CIPHER_SUITE_WEP104:
173 if (params->key_len != 13)
174 return -EINVAL;
175 break;
176 case WLAN_CIPHER_SUITE_AES_CMAC:
177 if (params->key_len != 16)
178 return -EINVAL;
179 break;
180 default:
181 return -EINVAL;
182 }
183
184 return 0;
185}
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 5ef82f2ca88f..f98090b90fbf 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -5,12 +5,13 @@
5 * into cfg80211, when that happens all the exports here go away and 5 * into cfg80211, when that happens all the exports here go away and
6 * we directly assign the wireless handlers of wireless interfaces. 6 * we directly assign the wireless handlers of wireless interfaces.
7 * 7 *
8 * Copyright 2008 Johannes Berg <johannes@sipsolutions.net> 8 * Copyright 2008-2009 Johannes Berg <johannes@sipsolutions.net>
9 */ 9 */
10 10
11#include <linux/wireless.h> 11#include <linux/wireless.h>
12#include <linux/nl80211.h> 12#include <linux/nl80211.h>
13#include <linux/if_arp.h> 13#include <linux/if_arp.h>
14#include <linux/etherdevice.h>
14#include <net/iw_handler.h> 15#include <net/iw_handler.h>
15#include <net/cfg80211.h> 16#include <net/cfg80211.h>
16#include "core.h" 17#include "core.h"
@@ -296,22 +297,34 @@ EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme);
296struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, 297struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
297 struct iw_freq *freq) 298 struct iw_freq *freq)
298{ 299{
300 struct ieee80211_channel *chan;
301 int f;
302
303 /*
304 * Parse frequency - return NULL for auto and
305 * -EINVAL for impossible things.
306 */
299 if (freq->e == 0) { 307 if (freq->e == 0) {
300 if (freq->m < 0) 308 if (freq->m < 0)
301 return NULL; 309 return NULL;
302 else 310 f = ieee80211_channel_to_frequency(freq->m);
303 return ieee80211_get_channel(wiphy,
304 ieee80211_channel_to_frequency(freq->m));
305 } else { 311 } else {
306 int i, div = 1000000; 312 int i, div = 1000000;
307 for (i = 0; i < freq->e; i++) 313 for (i = 0; i < freq->e; i++)
308 div /= 10; 314 div /= 10;
309 if (div > 0) 315 if (div <= 0)
310 return ieee80211_get_channel(wiphy, freq->m / div);
311 else
312 return ERR_PTR(-EINVAL); 316 return ERR_PTR(-EINVAL);
317 f = freq->m / div;
313 } 318 }
314 319
320 /*
321 * Look up channel struct and return -EINVAL when
322 * it cannot be found.
323 */
324 chan = ieee80211_get_channel(wiphy, f);
325 if (!chan)
326 return ERR_PTR(-EINVAL);
327 return chan;
315} 328}
316EXPORT_SYMBOL_GPL(cfg80211_wext_freq); 329EXPORT_SYMBOL_GPL(cfg80211_wext_freq);
317 330
@@ -465,3 +478,262 @@ int cfg80211_wext_giwretry(struct net_device *dev,
465 return 0; 478 return 0;
466} 479}
467EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry); 480EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry);
481
482static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
483 struct net_device *dev, const u8 *addr,
484 bool remove, bool tx_key, int idx,
485 struct key_params *params)
486{
487 struct wireless_dev *wdev = dev->ieee80211_ptr;
488 int err;
489
490 if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
491 if (!rdev->ops->set_default_mgmt_key)
492 return -EOPNOTSUPP;
493
494 if (idx < 4 || idx > 5)
495 return -EINVAL;
496 } else if (idx < 0 || idx > 3)
497 return -EINVAL;
498
499 if (remove) {
500 err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr);
501 if (!err) {
502 if (idx == wdev->wext.default_key)
503 wdev->wext.default_key = -1;
504 else if (idx == wdev->wext.default_mgmt_key)
505 wdev->wext.default_mgmt_key = -1;
506 }
507 return err;
508 } else {
509 if (addr)
510 tx_key = false;
511
512 if (cfg80211_validate_key_settings(params, idx, addr))
513 return -EINVAL;
514
515 err = rdev->ops->add_key(&rdev->wiphy, dev, idx, addr, params);
516 if (err)
517 return err;
518
519 if (tx_key || (!addr && wdev->wext.default_key == -1)) {
520 err = rdev->ops->set_default_key(&rdev->wiphy,
521 dev, idx);
522 if (!err)
523 wdev->wext.default_key = idx;
524 return err;
525 }
526
527 if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC &&
528 (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) {
529 err = rdev->ops->set_default_mgmt_key(&rdev->wiphy,
530 dev, idx);
531 if (!err)
532 wdev->wext.default_mgmt_key = idx;
533 return err;
534 }
535
536 return 0;
537 }
538}
539
540int cfg80211_wext_siwencode(struct net_device *dev,
541 struct iw_request_info *info,
542 struct iw_point *erq, char *keybuf)
543{
544 struct wireless_dev *wdev = dev->ieee80211_ptr;
545 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
546 int idx, err;
547 bool remove = false;
548 struct key_params params;
549
550 /* no use -- only MFP (set_default_mgmt_key) is optional */
551 if (!rdev->ops->del_key ||
552 !rdev->ops->add_key ||
553 !rdev->ops->set_default_key)
554 return -EOPNOTSUPP;
555
556 idx = erq->flags & IW_ENCODE_INDEX;
557 if (idx == 0) {
558 idx = wdev->wext.default_key;
559 if (idx < 0)
560 idx = 0;
561 } else if (idx < 1 || idx > 4)
562 return -EINVAL;
563 else
564 idx--;
565
566 if (erq->flags & IW_ENCODE_DISABLED)
567 remove = true;
568 else if (erq->length == 0) {
569 /* No key data - just set the default TX key index */
570 err = rdev->ops->set_default_key(&rdev->wiphy, dev, idx);
571 if (!err)
572 wdev->wext.default_key = idx;
573 return err;
574 }
575
576 memset(&params, 0, sizeof(params));
577 params.key = keybuf;
578 params.key_len = erq->length;
579 if (erq->length == 5)
580 params.cipher = WLAN_CIPHER_SUITE_WEP40;
581 else if (erq->length == 13)
582 params.cipher = WLAN_CIPHER_SUITE_WEP104;
583 else if (!remove)
584 return -EINVAL;
585
586 return cfg80211_set_encryption(rdev, dev, NULL, remove,
587 wdev->wext.default_key == -1,
588 idx, &params);
589}
590EXPORT_SYMBOL_GPL(cfg80211_wext_siwencode);
591
592int cfg80211_wext_siwencodeext(struct net_device *dev,
593 struct iw_request_info *info,
594 struct iw_point *erq, char *extra)
595{
596 struct wireless_dev *wdev = dev->ieee80211_ptr;
597 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
598 struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
599 const u8 *addr;
600 int idx;
601 bool remove = false;
602 struct key_params params;
603 u32 cipher;
604
605 /* no use -- only MFP (set_default_mgmt_key) is optional */
606 if (!rdev->ops->del_key ||
607 !rdev->ops->add_key ||
608 !rdev->ops->set_default_key)
609 return -EOPNOTSUPP;
610
611 switch (ext->alg) {
612 case IW_ENCODE_ALG_NONE:
613 remove = true;
614 cipher = 0;
615 break;
616 case IW_ENCODE_ALG_WEP:
617 if (ext->key_len == 5)
618 cipher = WLAN_CIPHER_SUITE_WEP40;
619 else if (ext->key_len == 13)
620 cipher = WLAN_CIPHER_SUITE_WEP104;
621 else
622 return -EINVAL;
623 break;
624 case IW_ENCODE_ALG_TKIP:
625 cipher = WLAN_CIPHER_SUITE_TKIP;
626 break;
627 case IW_ENCODE_ALG_CCMP:
628 cipher = WLAN_CIPHER_SUITE_CCMP;
629 break;
630 case IW_ENCODE_ALG_AES_CMAC:
631 cipher = WLAN_CIPHER_SUITE_AES_CMAC;
632 break;
633 default:
634 return -EOPNOTSUPP;
635 }
636
637 if (erq->flags & IW_ENCODE_DISABLED)
638 remove = true;
639
640 idx = erq->flags & IW_ENCODE_INDEX;
641 if (cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
642 if (idx < 4 || idx > 5) {
643 idx = wdev->wext.default_mgmt_key;
644 if (idx < 0)
645 return -EINVAL;
646 } else
647 idx--;
648 } else {
649 if (idx < 1 || idx > 4) {
650 idx = wdev->wext.default_key;
651 if (idx < 0)
652 return -EINVAL;
653 } else
654 idx--;
655 }
656
657 addr = ext->addr.sa_data;
658 if (is_broadcast_ether_addr(addr))
659 addr = NULL;
660
661 memset(&params, 0, sizeof(params));
662 params.key = ext->key;
663 params.key_len = ext->key_len;
664 params.cipher = cipher;
665
666 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
667 params.seq = ext->rx_seq;
668 params.seq_len = 6;
669 }
670
671 return cfg80211_set_encryption(
672 rdev, dev, addr, remove,
673 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
674 idx, &params);
675}
676EXPORT_SYMBOL_GPL(cfg80211_wext_siwencodeext);
677
678struct giwencode_cookie {
679 size_t buflen;
680 char *keybuf;
681};
682
683static void giwencode_get_key_cb(void *cookie, struct key_params *params)
684{
685 struct giwencode_cookie *data = cookie;
686
687 if (!params->key) {
688 data->buflen = 0;
689 return;
690 }
691
692 data->buflen = min_t(size_t, data->buflen, params->key_len);
693 memcpy(data->keybuf, params->key, data->buflen);
694}
695
696int cfg80211_wext_giwencode(struct net_device *dev,
697 struct iw_request_info *info,
698 struct iw_point *erq, char *keybuf)
699{
700 struct wireless_dev *wdev = dev->ieee80211_ptr;
701 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
702 int idx, err;
703 struct giwencode_cookie data = {
704 .keybuf = keybuf,
705 .buflen = erq->length,
706 };
707
708 if (!rdev->ops->get_key)
709 return -EOPNOTSUPP;
710
711 idx = erq->flags & IW_ENCODE_INDEX;
712 if (idx == 0) {
713 idx = wdev->wext.default_key;
714 if (idx < 0)
715 idx = 0;
716 } else if (idx < 1 || idx > 4)
717 return -EINVAL;
718 else
719 idx--;
720
721 erq->flags = idx + 1;
722
723 err = rdev->ops->get_key(&rdev->wiphy, dev, idx, NULL, &data,
724 giwencode_get_key_cb);
725 if (!err) {
726 erq->length = data.buflen;
727 erq->flags |= IW_ENCODE_ENABLED;
728 return 0;
729 }
730
731 if (err == -ENOENT) {
732 erq->flags |= IW_ENCODE_DISABLED;
733 erq->length = 0;
734 return 0;
735 }
736
737 return err;
738}
739EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode);
diff --git a/net/wireless/wext.c b/net/wireless/wext.c
index cb6a5bb85d80..d3bbef70cc7c 100644
--- a/net/wireless/wext.c
+++ b/net/wireless/wext.c
@@ -649,14 +649,26 @@ static int wireless_seq_show(struct seq_file *seq, void *v)
649 return 0; 649 return 0;
650} 650}
651 651
652static void *wireless_dev_seq_start(struct seq_file *seq, loff_t *pos)
653{
654 rtnl_lock();
655 return dev_seq_start(seq, pos);
656}
657
658static void wireless_dev_seq_stop(struct seq_file *seq, void *v)
659{
660 dev_seq_stop(seq, v);
661 rtnl_unlock();
662}
663
652static const struct seq_operations wireless_seq_ops = { 664static const struct seq_operations wireless_seq_ops = {
653 .start = dev_seq_start, 665 .start = wireless_dev_seq_start,
654 .next = dev_seq_next, 666 .next = dev_seq_next,
655 .stop = dev_seq_stop, 667 .stop = wireless_dev_seq_stop,
656 .show = wireless_seq_show, 668 .show = wireless_seq_show,
657}; 669};
658 670
659static int wireless_seq_open(struct inode *inode, struct file *file) 671static int seq_open_wireless(struct inode *inode, struct file *file)
660{ 672{
661 return seq_open_net(inode, file, &wireless_seq_ops, 673 return seq_open_net(inode, file, &wireless_seq_ops,
662 sizeof(struct seq_net_private)); 674 sizeof(struct seq_net_private));
@@ -664,7 +676,7 @@ static int wireless_seq_open(struct inode *inode, struct file *file)
664 676
665static const struct file_operations wireless_seq_fops = { 677static const struct file_operations wireless_seq_fops = {
666 .owner = THIS_MODULE, 678 .owner = THIS_MODULE,
667 .open = wireless_seq_open, 679 .open = seq_open_wireless,
668 .read = seq_read, 680 .read = seq_read,
669 .llseek = seq_lseek, 681 .llseek = seq_lseek,
670 .release = seq_release_net, 682 .release = seq_release_net,