aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS6
-rw-r--r--drivers/net/wireless/adm8211.c42
-rw-r--r--drivers/net/wireless/at76c50x-usb.c12
-rw-r--r--drivers/net/wireless/ath/ar9170/ar9170.h16
-rw-r--r--drivers/net/wireless/ath/ar9170/mac.c22
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c112
-rw-r--r--drivers/net/wireless/ath/ath.h18
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h3
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c78
-rw-r--r--drivers/net/wireless/ath/ath5k/base.h13
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h20
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h14
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c44
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c28
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c81
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c52
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h9
-rw-r--r--drivers/net/wireless/ath/regd.h20
-rw-r--r--drivers/net/wireless/b43/Kconfig14
-rw-r--r--drivers/net/wireless/b43/dma.c2
-rw-r--r--drivers/net/wireless/b43/lo.c2
-rw-r--r--drivers/net/wireless/b43/main.c205
-rw-r--r--drivers/net/wireless/b43/main.h2
-rw-r--r--drivers/net/wireless/b43/phy_g.c6
-rw-r--r--drivers/net/wireless/b43/phy_lp.c1042
-rw-r--r--drivers/net/wireless/b43/phy_lp.h25
-rw-r--r--drivers/net/wireless/b43/pio.c4
-rw-r--r--drivers/net/wireless/b43/tables_lpphy.c12
-rw-r--r--drivers/net/wireless/b43/wa.c4
-rw-r--r--drivers/net/wireless/b43/xmit.c29
-rw-r--r--drivers/net/wireless/b43/xmit.h3
-rw-r--r--drivers/net/wireless/b43legacy/main.c4
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c14
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c73
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c25
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c116
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c74
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h20
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c222
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.h10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c207
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c2
-rw-r--r--drivers/net/wireless/libertas/assoc.c8
-rw-r--r--drivers/net/wireless/libertas_tf/main.c37
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c4
-rw-r--r--drivers/net/wireless/mwl8k.c1530
-rw-r--r--drivers/net/wireless/orinoco/wext.c2
-rw-r--r--drivers/net/wireless/p54/main.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c19
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.h10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c40
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c25
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c1
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c11
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c11
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_boot.c3
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c4
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_reg.h4
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c9
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c44
-rw-r--r--drivers/ssb/pci.c2
-rw-r--r--include/net/cfg80211.h2
-rw-r--r--include/net/mac80211.h36
-rw-r--r--net/mac80211/debugfs_netdev.c6
-rw-r--r--net/mac80211/driver-ops.h24
-rw-r--r--net/mac80211/driver-trace.h36
-rw-r--r--net/mac80211/ieee80211_i.h9
-rw-r--r--net/mac80211/iface.c15
-rw-r--r--net/mac80211/main.c32
-rw-r--r--net/mac80211/mesh.h2
-rw-r--r--net/mac80211/mesh_hwmp.c21
-rw-r--r--net/mac80211/rc80211_minstrel.c16
-rw-r--r--net/mac80211/rc80211_pid_algo.c16
-rw-r--r--net/mac80211/rx.c8
-rw-r--r--net/mac80211/scan.c16
-rw-r--r--net/mac80211/util.c2
-rw-r--r--net/wireless/core.c98
-rw-r--r--net/wireless/core.h2
-rw-r--r--net/wireless/mlme.c9
-rw-r--r--net/wireless/sme.c29
-rw-r--r--net/wireless/wext-compat.c1
99 files changed, 2790 insertions, 2170 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 866253d7abd7..9b55c661c3fb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3272,6 +3272,12 @@ S: Supported
3272F: drivers/net/mv643xx_eth.* 3272F: drivers/net/mv643xx_eth.*
3273F: include/linux/mv643xx.h 3273F: include/linux/mv643xx.h
3274 3274
3275MARVELL MWL8K WIRELESS DRIVER
3276M: Lennert Buytenhek <buytenh@marvell.com>
3277L: linux-wireless@vger.kernel.org
3278S: Supported
3279F: drivers/net/wireless/mwl8k.c
3280
3275MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER 3281MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER
3276M: Nicolas Pitre <nico@cam.org> 3282M: Nicolas Pitre <nico@cam.org>
3277S: Maintained 3283S: Maintained
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index 5695911bc602..b80f514877d8 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1328,16 +1328,39 @@ static void adm8211_bss_info_changed(struct ieee80211_hw *dev,
1328 } 1328 }
1329} 1329}
1330 1330
1331static u64 adm8211_prepare_multicast(struct ieee80211_hw *hw,
1332 int mc_count, struct dev_addr_list *mclist)
1333{
1334 unsigned int bit_nr, i;
1335 u32 mc_filter[2];
1336
1337 mc_filter[1] = mc_filter[0] = 0;
1338
1339 for (i = 0; i < mc_count; i++) {
1340 if (!mclist)
1341 break;
1342 bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
1343
1344 bit_nr &= 0x3F;
1345 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
1346 mclist = mclist->next;
1347 }
1348
1349 return mc_filter[0] | ((u64)(mc_filter[1]) << 32);
1350}
1351
1331static void adm8211_configure_filter(struct ieee80211_hw *dev, 1352static void adm8211_configure_filter(struct ieee80211_hw *dev,
1332 unsigned int changed_flags, 1353 unsigned int changed_flags,
1333 unsigned int *total_flags, 1354 unsigned int *total_flags,
1334 int mc_count, struct dev_mc_list *mclist) 1355 u64 multicast)
1335{ 1356{
1336 static const u8 bcast[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 1357 static const u8 bcast[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
1337 struct adm8211_priv *priv = dev->priv; 1358 struct adm8211_priv *priv = dev->priv;
1338 unsigned int bit_nr, new_flags; 1359 unsigned int new_flags;
1339 u32 mc_filter[2]; 1360 u32 mc_filter[2];
1340 int i; 1361
1362 mc_filter[0] = multicast;
1363 mc_filter[1] = multicast >> 32;
1341 1364
1342 new_flags = 0; 1365 new_flags = 0;
1343 1366
@@ -1346,23 +1369,13 @@ static void adm8211_configure_filter(struct ieee80211_hw *dev,
1346 priv->nar |= ADM8211_NAR_PR; 1369 priv->nar |= ADM8211_NAR_PR;
1347 priv->nar &= ~ADM8211_NAR_MM; 1370 priv->nar &= ~ADM8211_NAR_MM;
1348 mc_filter[1] = mc_filter[0] = ~0; 1371 mc_filter[1] = mc_filter[0] = ~0;
1349 } else if ((*total_flags & FIF_ALLMULTI) || (mc_count > 32)) { 1372 } else if (*total_flags & FIF_ALLMULTI || multicast == ~(0ULL)) {
1350 new_flags |= FIF_ALLMULTI; 1373 new_flags |= FIF_ALLMULTI;
1351 priv->nar &= ~ADM8211_NAR_PR; 1374 priv->nar &= ~ADM8211_NAR_PR;
1352 priv->nar |= ADM8211_NAR_MM; 1375 priv->nar |= ADM8211_NAR_MM;
1353 mc_filter[1] = mc_filter[0] = ~0; 1376 mc_filter[1] = mc_filter[0] = ~0;
1354 } else { 1377 } else {
1355 priv->nar &= ~(ADM8211_NAR_MM | ADM8211_NAR_PR); 1378 priv->nar &= ~(ADM8211_NAR_MM | ADM8211_NAR_PR);
1356 mc_filter[1] = mc_filter[0] = 0;
1357 for (i = 0; i < mc_count; i++) {
1358 if (!mclist)
1359 break;
1360 bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
1361
1362 bit_nr &= 0x3F;
1363 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
1364 mclist = mclist->next;
1365 }
1366 } 1379 }
1367 1380
1368 ADM8211_IDLE_RX(); 1381 ADM8211_IDLE_RX();
@@ -1757,6 +1770,7 @@ static const struct ieee80211_ops adm8211_ops = {
1757 .remove_interface = adm8211_remove_interface, 1770 .remove_interface = adm8211_remove_interface,
1758 .config = adm8211_config, 1771 .config = adm8211_config,
1759 .bss_info_changed = adm8211_bss_info_changed, 1772 .bss_info_changed = adm8211_bss_info_changed,
1773 .prepare_multicast = adm8211_prepare_multicast,
1760 .configure_filter = adm8211_configure_filter, 1774 .configure_filter = adm8211_configure_filter,
1761 .get_stats = adm8211_get_stats, 1775 .get_stats = adm8211_get_stats,
1762 .get_tx_stats = adm8211_get_tx_stats, 1776 .get_tx_stats = adm8211_get_tx_stats,
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 7218dbabad3e..8e1a55dec351 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1950,9 +1950,8 @@ static int at76_config(struct ieee80211_hw *hw, u32 changed)
1950{ 1950{
1951 struct at76_priv *priv = hw->priv; 1951 struct at76_priv *priv = hw->priv;
1952 1952
1953 at76_dbg(DBG_MAC80211, "%s(): channel %d radio %d", 1953 at76_dbg(DBG_MAC80211, "%s(): channel %d",
1954 __func__, hw->conf.channel->hw_value, 1954 __func__, hw->conf.channel->hw_value);
1955 hw->conf.radio_enabled);
1956 at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:"); 1955 at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:");
1957 1956
1958 mutex_lock(&priv->mtx); 1957 mutex_lock(&priv->mtx);
@@ -1997,15 +1996,14 @@ static void at76_bss_info_changed(struct ieee80211_hw *hw,
1997/* must be atomic */ 1996/* must be atomic */
1998static void at76_configure_filter(struct ieee80211_hw *hw, 1997static void at76_configure_filter(struct ieee80211_hw *hw,
1999 unsigned int changed_flags, 1998 unsigned int changed_flags,
2000 unsigned int *total_flags, int mc_count, 1999 unsigned int *total_flags, u64 multicast)
2001 struct dev_addr_list *mc_list)
2002{ 2000{
2003 struct at76_priv *priv = hw->priv; 2001 struct at76_priv *priv = hw->priv;
2004 int flags; 2002 int flags;
2005 2003
2006 at76_dbg(DBG_MAC80211, "%s(): changed_flags=0x%08x " 2004 at76_dbg(DBG_MAC80211, "%s(): changed_flags=0x%08x "
2007 "total_flags=0x%08x mc_count=%d", 2005 "total_flags=0x%08x",
2008 __func__, changed_flags, *total_flags, mc_count); 2006 __func__, changed_flags, *total_flags);
2009 2007
2010 flags = changed_flags & AT76_SUPPORTED_FILTERS; 2008 flags = changed_flags & AT76_SUPPORTED_FILTERS;
2011 *total_flags = AT76_SUPPORTED_FILTERS; 2009 *total_flags = AT76_SUPPORTED_FILTERS;
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
index e6c3ee3e0581..ce407248d7d8 100644
--- a/drivers/net/wireless/ath/ar9170/ar9170.h
+++ b/drivers/net/wireless/ath/ar9170/ar9170.h
@@ -157,6 +157,7 @@ struct ar9170_sta_tid {
157 157
158struct ar9170 { 158struct ar9170 {
159 struct ieee80211_hw *hw; 159 struct ieee80211_hw *hw;
160 struct ath_common common;
160 struct mutex mutex; 161 struct mutex mutex;
161 enum ar9170_device_state state; 162 enum ar9170_device_state state;
162 unsigned long bad_hw_nagger; 163 unsigned long bad_hw_nagger;
@@ -184,10 +185,8 @@ struct ar9170 {
184 bool disable_offload; 185 bool disable_offload;
185 186
186 /* filter settings */ 187 /* filter settings */
187 struct work_struct filter_config_work; 188 u64 cur_mc_hash;
188 u64 cur_mc_hash, want_mc_hash; 189 u32 cur_filter;
189 u32 cur_filter, want_filter;
190 unsigned long filter_changed;
191 unsigned int filter_state; 190 unsigned int filter_state;
192 bool sniffer_enabled; 191 bool sniffer_enabled;
193 192
@@ -222,7 +221,6 @@ struct ar9170 {
222 221
223 /* EEPROM */ 222 /* EEPROM */
224 struct ar9170_eeprom eeprom; 223 struct ar9170_eeprom eeprom;
225 struct ath_regulatory regulatory;
226 224
227 /* tx queues - as seen by hw - */ 225 /* tx queues - as seen by hw - */
228 struct sk_buff_head tx_pending[__AR9170_NUM_TXQ]; 226 struct sk_buff_head tx_pending[__AR9170_NUM_TXQ];
@@ -261,10 +259,6 @@ struct ar9170_tx_info {
261#define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) 259#define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED)
262#define IS_ACCEPTING_CMD(a) (((struct ar9170 *)a)->state >= AR9170_IDLE) 260#define IS_ACCEPTING_CMD(a) (((struct ar9170 *)a)->state >= AR9170_IDLE)
263 261
264#define AR9170_FILTER_CHANGED_MODE BIT(0)
265#define AR9170_FILTER_CHANGED_MULTICAST BIT(1)
266#define AR9170_FILTER_CHANGED_FRAMEFILTER BIT(2)
267
268/* exported interface */ 262/* exported interface */
269void *ar9170_alloc(size_t priv_size); 263void *ar9170_alloc(size_t priv_size);
270int ar9170_register(struct ar9170 *ar, struct device *pdev); 264int ar9170_register(struct ar9170 *ar, struct device *pdev);
@@ -278,8 +272,8 @@ int ar9170_nag_limiter(struct ar9170 *ar);
278int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); 272int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
279int ar9170_init_mac(struct ar9170 *ar); 273int ar9170_init_mac(struct ar9170 *ar);
280int ar9170_set_qos(struct ar9170 *ar); 274int ar9170_set_qos(struct ar9170 *ar);
281int ar9170_update_multicast(struct ar9170 *ar); 275int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hast);
282int ar9170_update_frame_filter(struct ar9170 *ar); 276int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter);
283int ar9170_set_operating_mode(struct ar9170 *ar); 277int ar9170_set_operating_mode(struct ar9170 *ar);
284int ar9170_set_beacon_timers(struct ar9170 *ar); 278int ar9170_set_beacon_timers(struct ar9170 *ar);
285int ar9170_set_dyn_sifs_ack(struct ar9170 *ar); 279int ar9170_set_dyn_sifs_ack(struct ar9170 *ar);
diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c
index d9f1f46de183..60049366e863 100644
--- a/drivers/net/wireless/ath/ar9170/mac.c
+++ b/drivers/net/wireless/ath/ar9170/mac.c
@@ -238,39 +238,31 @@ static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac)
238 return ar9170_regwrite_result(); 238 return ar9170_regwrite_result();
239} 239}
240 240
241int ar9170_update_multicast(struct ar9170 *ar) 241int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hash)
242{ 242{
243 int err; 243 int err;
244 244
245 ar9170_regwrite_begin(ar); 245 ar9170_regwrite_begin(ar);
246 ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, 246 ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32);
247 ar->want_mc_hash >> 32); 247 ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash);
248 ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L,
249 ar->want_mc_hash);
250
251 ar9170_regwrite_finish(); 248 ar9170_regwrite_finish();
252 err = ar9170_regwrite_result(); 249 err = ar9170_regwrite_result();
253
254 if (err) 250 if (err)
255 return err; 251 return err;
256 252
257 ar->cur_mc_hash = ar->want_mc_hash; 253 ar->cur_mc_hash = mc_hash;
258
259 return 0; 254 return 0;
260} 255}
261 256
262int ar9170_update_frame_filter(struct ar9170 *ar) 257int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter)
263{ 258{
264 int err; 259 int err;
265 260
266 err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER, 261 err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER, filter);
267 ar->want_filter);
268
269 if (err) 262 if (err)
270 return err; 263 return err;
271 264
272 ar->cur_filter = ar->want_filter; 265 ar->cur_filter = filter;
273
274 return 0; 266 return 0;
275} 267}
276 268
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index ea8c9419336d..658b32312caf 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -1232,8 +1232,6 @@ static int ar9170_op_start(struct ieee80211_hw *hw)
1232 1232
1233 mutex_lock(&ar->mutex); 1233 mutex_lock(&ar->mutex);
1234 1234
1235 ar->filter_changed = 0;
1236
1237 /* reinitialize queues statistics */ 1235 /* reinitialize queues statistics */
1238 memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); 1236 memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
1239 for (i = 0; i < __AR9170_NUM_TXQ; i++) 1237 for (i = 0; i < __AR9170_NUM_TXQ; i++)
@@ -1296,7 +1294,6 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
1296#ifdef CONFIG_AR9170_LEDS 1294#ifdef CONFIG_AR9170_LEDS
1297 cancel_delayed_work_sync(&ar->led_work); 1295 cancel_delayed_work_sync(&ar->led_work);
1298#endif 1296#endif
1299 cancel_work_sync(&ar->filter_config_work);
1300 cancel_work_sync(&ar->beacon_work); 1297 cancel_work_sync(&ar->beacon_work);
1301 1298
1302 mutex_lock(&ar->mutex); 1299 mutex_lock(&ar->mutex);
@@ -1973,8 +1970,7 @@ static int ar9170_op_add_interface(struct ieee80211_hw *hw,
1973 } 1970 }
1974 1971
1975 ar->cur_filter = 0; 1972 ar->cur_filter = 0;
1976 ar->want_filter = AR9170_MAC_REG_FTF_DEFAULTS; 1973 err = ar9170_update_frame_filter(ar, AR9170_MAC_REG_FTF_DEFAULTS);
1977 err = ar9170_update_frame_filter(ar);
1978 if (err) 1974 if (err)
1979 goto unlock; 1975 goto unlock;
1980 1976
@@ -1992,8 +1988,7 @@ static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
1992 1988
1993 mutex_lock(&ar->mutex); 1989 mutex_lock(&ar->mutex);
1994 ar->vif = NULL; 1990 ar->vif = NULL;
1995 ar->want_filter = 0; 1991 ar9170_update_frame_filter(ar, 0);
1996 ar9170_update_frame_filter(ar);
1997 ar9170_set_beacon_timers(ar); 1992 ar9170_set_beacon_timers(ar);
1998 dev_kfree_skb(ar->beacon); 1993 dev_kfree_skb(ar->beacon);
1999 ar->beacon = NULL; 1994 ar->beacon = NULL;
@@ -2065,48 +2060,37 @@ out:
2065 return err; 2060 return err;
2066} 2061}
2067 2062
2068static void ar9170_set_filters(struct work_struct *work) 2063static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
2064 struct dev_addr_list *mclist)
2069{ 2065{
2070 struct ar9170 *ar = container_of(work, struct ar9170, 2066 u64 mchash;
2071 filter_config_work); 2067 int i;
2072 int err;
2073
2074 if (unlikely(!IS_STARTED(ar)))
2075 return ;
2076
2077 mutex_lock(&ar->mutex);
2078 if (test_and_clear_bit(AR9170_FILTER_CHANGED_MODE,
2079 &ar->filter_changed)) {
2080 err = ar9170_set_operating_mode(ar);
2081 if (err)
2082 goto unlock;
2083 }
2084 2068
2085 if (test_and_clear_bit(AR9170_FILTER_CHANGED_MULTICAST, 2069 /* always get broadcast frames */
2086 &ar->filter_changed)) { 2070 mchash = 1ULL << (0xff >> 2);
2087 err = ar9170_update_multicast(ar);
2088 if (err)
2089 goto unlock;
2090 }
2091 2071
2092 if (test_and_clear_bit(AR9170_FILTER_CHANGED_FRAMEFILTER, 2072 for (i = 0; i < mc_count; i++) {
2093 &ar->filter_changed)) { 2073 if (WARN_ON(!mclist))
2094 err = ar9170_update_frame_filter(ar); 2074 break;
2095 if (err) 2075 mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
2096 goto unlock; 2076 mclist = mclist->next;
2097 } 2077 }
2098 2078
2099unlock: 2079 return mchash;
2100 mutex_unlock(&ar->mutex);
2101} 2080}
2102 2081
2103static void ar9170_op_configure_filter(struct ieee80211_hw *hw, 2082static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
2104 unsigned int changed_flags, 2083 unsigned int changed_flags,
2105 unsigned int *new_flags, 2084 unsigned int *new_flags,
2106 int mc_count, struct dev_mc_list *mclist) 2085 u64 multicast)
2107{ 2086{
2108 struct ar9170 *ar = hw->priv; 2087 struct ar9170 *ar = hw->priv;
2109 2088
2089 if (unlikely(!IS_ACCEPTING_CMD(ar)))
2090 return ;
2091
2092 mutex_lock(&ar->mutex);
2093
2110 /* mask supported flags */ 2094 /* mask supported flags */
2111 *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC | 2095 *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
2112 FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL; 2096 FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
@@ -2116,26 +2100,11 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
2116 * then checking the error flags, later. 2100 * then checking the error flags, later.
2117 */ 2101 */
2118 2102
2119 if (changed_flags & FIF_ALLMULTI) { 2103 if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI)
2120 if (*new_flags & FIF_ALLMULTI) { 2104 multicast = ~0ULL;
2121 ar->want_mc_hash = ~0ULL;
2122 } else {
2123 u64 mchash;
2124 int i;
2125 2105
2126 /* always get broadcast frames */ 2106 if (multicast != ar->cur_mc_hash)
2127 mchash = 1ULL << (0xff >> 2); 2107 ar9170_update_multicast(ar, multicast);
2128
2129 for (i = 0; i < mc_count; i++) {
2130 if (WARN_ON(!mclist))
2131 break;
2132 mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
2133 mclist = mclist->next;
2134 }
2135 ar->want_mc_hash = mchash;
2136 }
2137 set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed);
2138 }
2139 2108
2140 if (changed_flags & FIF_CONTROL) { 2109 if (changed_flags & FIF_CONTROL) {
2141 u32 filter = AR9170_MAC_REG_FTF_PSPOLL | 2110 u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
@@ -2146,24 +2115,22 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
2146 AR9170_MAC_REG_FTF_CFE_ACK; 2115 AR9170_MAC_REG_FTF_CFE_ACK;
2147 2116
2148 if (*new_flags & FIF_CONTROL) 2117 if (*new_flags & FIF_CONTROL)
2149 ar->want_filter = ar->cur_filter | filter; 2118 filter |= ar->cur_filter;
2150 else 2119 else
2151 ar->want_filter = ar->cur_filter & ~filter; 2120 filter &= (~ar->cur_filter);
2152 2121
2153 set_bit(AR9170_FILTER_CHANGED_FRAMEFILTER, 2122 ar9170_update_frame_filter(ar, filter);
2154 &ar->filter_changed);
2155 } 2123 }
2156 2124
2157 if (changed_flags & FIF_PROMISC_IN_BSS) { 2125 if (changed_flags & FIF_PROMISC_IN_BSS) {
2158 ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0; 2126 ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
2159 set_bit(AR9170_FILTER_CHANGED_MODE, 2127 ar9170_set_operating_mode(ar);
2160 &ar->filter_changed);
2161 } 2128 }
2162 2129
2163 if (likely(IS_STARTED(ar))) 2130 mutex_unlock(&ar->mutex);
2164 ieee80211_queue_work(ar->hw, &ar->filter_config_work);
2165} 2131}
2166 2132
2133
2167static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, 2134static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
2168 struct ieee80211_vif *vif, 2135 struct ieee80211_vif *vif,
2169 struct ieee80211_bss_conf *bss_conf, 2136 struct ieee80211_bss_conf *bss_conf,
@@ -2417,9 +2384,6 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw,
2417 default: 2384 default:
2418 break; 2385 break;
2419 } 2386 }
2420
2421 if (IS_STARTED(ar) && ar->filter_changed)
2422 ieee80211_queue_work(ar->hw, &ar->filter_config_work);
2423} 2387}
2424 2388
2425static int ar9170_get_stats(struct ieee80211_hw *hw, 2389static int ar9170_get_stats(struct ieee80211_hw *hw,
@@ -2543,6 +2507,7 @@ static const struct ieee80211_ops ar9170_ops = {
2543 .add_interface = ar9170_op_add_interface, 2507 .add_interface = ar9170_op_add_interface,
2544 .remove_interface = ar9170_op_remove_interface, 2508 .remove_interface = ar9170_op_remove_interface,
2545 .config = ar9170_op_config, 2509 .config = ar9170_op_config,
2510 .prepare_multicast = ar9170_op_prepare_multicast,
2546 .configure_filter = ar9170_op_configure_filter, 2511 .configure_filter = ar9170_op_configure_filter,
2547 .conf_tx = ar9170_conf_tx, 2512 .conf_tx = ar9170_conf_tx,
2548 .bss_info_changed = ar9170_op_bss_info_changed, 2513 .bss_info_changed = ar9170_op_bss_info_changed,
@@ -2589,7 +2554,6 @@ void *ar9170_alloc(size_t priv_size)
2589 skb_queue_head_init(&ar->tx_pending[i]); 2554 skb_queue_head_init(&ar->tx_pending[i]);
2590 } 2555 }
2591 ar9170_rx_reset_rx_mpdu(ar); 2556 ar9170_rx_reset_rx_mpdu(ar);
2592 INIT_WORK(&ar->filter_config_work, ar9170_set_filters);
2593 INIT_WORK(&ar->beacon_work, ar9170_new_beacon); 2557 INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
2594 INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor); 2558 INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
2595 INIT_LIST_HEAD(&ar->tx_ampdu_list); 2559 INIT_LIST_HEAD(&ar->tx_ampdu_list);
@@ -2634,6 +2598,7 @@ static int ar9170_read_eeprom(struct ar9170 *ar)
2634{ 2598{
2635#define RW 8 /* number of words to read at once */ 2599#define RW 8 /* number of words to read at once */
2636#define RB (sizeof(u32) * RW) 2600#define RB (sizeof(u32) * RW)
2601 struct ath_regulatory *regulatory = &ar->common.regulatory;
2637 u8 *eeprom = (void *)&ar->eeprom; 2602 u8 *eeprom = (void *)&ar->eeprom;
2638 u8 *addr = ar->eeprom.mac_address; 2603 u8 *addr = ar->eeprom.mac_address;
2639 __le32 offsets[RW]; 2604 __le32 offsets[RW];
@@ -2700,8 +2665,8 @@ static int ar9170_read_eeprom(struct ar9170 *ar)
2700 else 2665 else
2701 ar->hw->channel_change_time = 80 * 1000; 2666 ar->hw->channel_change_time = 80 * 1000;
2702 2667
2703 ar->regulatory.current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]); 2668 regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
2704 ar->regulatory.current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]); 2669 regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
2705 2670
2706 /* second part of wiphy init */ 2671 /* second part of wiphy init */
2707 SET_IEEE80211_PERM_ADDR(ar->hw, addr); 2672 SET_IEEE80211_PERM_ADDR(ar->hw, addr);
@@ -2715,11 +2680,12 @@ static int ar9170_reg_notifier(struct wiphy *wiphy,
2715 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 2680 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
2716 struct ar9170 *ar = hw->priv; 2681 struct ar9170 *ar = hw->priv;
2717 2682
2718 return ath_reg_notifier_apply(wiphy, request, &ar->regulatory); 2683 return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory);
2719} 2684}
2720 2685
2721int ar9170_register(struct ar9170 *ar, struct device *pdev) 2686int ar9170_register(struct ar9170 *ar, struct device *pdev)
2722{ 2687{
2688 struct ath_regulatory *regulatory = &ar->common.regulatory;
2723 int err; 2689 int err;
2724 2690
2725 /* try to read EEPROM, init MAC addr */ 2691 /* try to read EEPROM, init MAC addr */
@@ -2727,7 +2693,7 @@ int ar9170_register(struct ar9170 *ar, struct device *pdev)
2727 if (err) 2693 if (err)
2728 goto err_out; 2694 goto err_out;
2729 2695
2730 err = ath_regd_init(&ar->regulatory, ar->hw->wiphy, 2696 err = ath_regd_init(regulatory, ar->hw->wiphy,
2731 ar9170_reg_notifier); 2697 ar9170_reg_notifier);
2732 if (err) 2698 if (err)
2733 goto err_out; 2699 goto err_out;
@@ -2736,8 +2702,8 @@ int ar9170_register(struct ar9170 *ar, struct device *pdev)
2736 if (err) 2702 if (err)
2737 goto err_out; 2703 goto err_out;
2738 2704
2739 if (!ath_is_world_regd(&ar->regulatory)) 2705 if (!ath_is_world_regd(regulatory))
2740 regulatory_hint(ar->hw->wiphy, ar->regulatory.alpha2); 2706 regulatory_hint(ar->hw->wiphy, regulatory->alpha2);
2741 2707
2742 err = ar9170_init_leds(ar); 2708 err = ar9170_init_leds(ar);
2743 if (err) 2709 if (err)
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index e284cd3ac6d4..a63e90cbf9e5 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -19,8 +19,26 @@
19 19
20#include <linux/skbuff.h> 20#include <linux/skbuff.h>
21 21
22struct reg_dmn_pair_mapping {
23 u16 regDmnEnum;
24 u16 reg_5ghz_ctl;
25 u16 reg_2ghz_ctl;
26};
27
28struct ath_regulatory {
29 char alpha2[2];
30 u16 country_code;
31 u16 max_power_level;
32 u32 tp_scale;
33 u16 current_rd;
34 u16 current_rd_ext;
35 int16_t power_limit;
36 struct reg_dmn_pair_mapping *regpair;
37};
38
22struct ath_common { 39struct ath_common {
23 u16 cachelsz; 40 u16 cachelsz;
41 struct ath_regulatory regulatory;
24}; 42};
25 43
26struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, 44struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index c09402eea7f3..862762cea54c 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -27,8 +27,6 @@
27#include <linux/types.h> 27#include <linux/types.h>
28#include <net/mac80211.h> 28#include <net/mac80211.h>
29 29
30#include "../regd.h"
31
32/* RX/TX descriptor hw structs 30/* RX/TX descriptor hw structs
33 * TODO: Driver part should only see sw structs */ 31 * TODO: Driver part should only see sw structs */
34#include "desc.h" 32#include "desc.h"
@@ -1077,7 +1075,6 @@ struct ath5k_hw {
1077 1075
1078 int ah_gpio_npins; 1076 int ah_gpio_npins;
1079 1077
1080 struct ath_regulatory ah_regulatory;
1081 struct ath5k_capabilities ah_capabilities; 1078 struct ath5k_capabilities ah_capabilities;
1082 1079
1083 struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES]; 1080 struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES];
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 2b3cf39dd4b1..5056410d788a 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -229,10 +229,12 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
229static void ath5k_remove_interface(struct ieee80211_hw *hw, 229static void ath5k_remove_interface(struct ieee80211_hw *hw,
230 struct ieee80211_if_init_conf *conf); 230 struct ieee80211_if_init_conf *conf);
231static int ath5k_config(struct ieee80211_hw *hw, u32 changed); 231static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
232static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
233 int mc_count, struct dev_addr_list *mc_list);
232static void ath5k_configure_filter(struct ieee80211_hw *hw, 234static void ath5k_configure_filter(struct ieee80211_hw *hw,
233 unsigned int changed_flags, 235 unsigned int changed_flags,
234 unsigned int *new_flags, 236 unsigned int *new_flags,
235 int mc_count, struct dev_mc_list *mclist); 237 u64 multicast);
236static int ath5k_set_key(struct ieee80211_hw *hw, 238static int ath5k_set_key(struct ieee80211_hw *hw,
237 enum set_key_cmd cmd, 239 enum set_key_cmd cmd,
238 struct ieee80211_vif *vif, struct ieee80211_sta *sta, 240 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
@@ -260,6 +262,7 @@ static const struct ieee80211_ops ath5k_hw_ops = {
260 .add_interface = ath5k_add_interface, 262 .add_interface = ath5k_add_interface,
261 .remove_interface = ath5k_remove_interface, 263 .remove_interface = ath5k_remove_interface,
262 .config = ath5k_config, 264 .config = ath5k_config,
265 .prepare_multicast = ath5k_prepare_multicast,
263 .configure_filter = ath5k_configure_filter, 266 .configure_filter = ath5k_configure_filter,
264 .set_key = ath5k_set_key, 267 .set_key = ath5k_set_key,
265 .get_stats = ath5k_get_stats, 268 .get_stats = ath5k_get_stats,
@@ -715,9 +718,9 @@ static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *re
715{ 718{
716 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 719 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
717 struct ath5k_softc *sc = hw->priv; 720 struct ath5k_softc *sc = hw->priv;
718 struct ath_regulatory *reg = &sc->ah->ah_regulatory; 721 struct ath_regulatory *regulatory = &sc->common.regulatory;
719 722
720 return ath_reg_notifier_apply(wiphy, request, reg); 723 return ath_reg_notifier_apply(wiphy, request, regulatory);
721} 724}
722 725
723static int 726static int
@@ -725,6 +728,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
725{ 728{
726 struct ath5k_softc *sc = hw->priv; 729 struct ath5k_softc *sc = hw->priv;
727 struct ath5k_hw *ah = sc->ah; 730 struct ath5k_hw *ah = sc->ah;
731 struct ath_regulatory *regulatory = &sc->common.regulatory;
728 u8 mac[ETH_ALEN] = {}; 732 u8 mac[ETH_ALEN] = {};
729 int ret; 733 int ret;
730 734
@@ -814,9 +818,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
814 memset(sc->bssidmask, 0xff, ETH_ALEN); 818 memset(sc->bssidmask, 0xff, ETH_ALEN);
815 ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); 819 ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
816 820
817 ah->ah_regulatory.current_rd = 821 regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain;
818 ah->ah_capabilities.cap_eeprom.ee_regdomain; 822 ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier);
819 ret = ath_regd_init(&ah->ah_regulatory, hw->wiphy, ath5k_reg_notifier);
820 if (ret) { 823 if (ret) {
821 ATH5K_ERR(sc, "can't initialize regulatory system\n"); 824 ATH5K_ERR(sc, "can't initialize regulatory system\n");
822 goto err_queues; 825 goto err_queues;
@@ -828,8 +831,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
828 goto err_queues; 831 goto err_queues;
829 } 832 }
830 833
831 if (!ath_is_world_regd(&sc->ah->ah_regulatory)) 834 if (!ath_is_world_regd(regulatory))
832 regulatory_hint(hw->wiphy, sc->ah->ah_regulatory.alpha2); 835 regulatory_hint(hw->wiphy, regulatory->alpha2);
833 836
834 ath5k_init_leds(sc); 837 ath5k_init_leds(sc);
835 838
@@ -2853,6 +2856,37 @@ unlock:
2853 return ret; 2856 return ret;
2854} 2857}
2855 2858
2859static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw,
2860 int mc_count, struct dev_addr_list *mclist)
2861{
2862 u32 mfilt[2], val;
2863 int i;
2864 u8 pos;
2865
2866 mfilt[0] = 0;
2867 mfilt[1] = 1;
2868
2869 for (i = 0; i < mc_count; i++) {
2870 if (!mclist)
2871 break;
2872 /* calculate XOR of eight 6-bit values */
2873 val = get_unaligned_le32(mclist->dmi_addr + 0);
2874 pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
2875 val = get_unaligned_le32(mclist->dmi_addr + 3);
2876 pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
2877 pos &= 0x3f;
2878 mfilt[pos / 32] |= (1 << (pos % 32));
2879 /* XXX: we might be able to just do this instead,
2880 * but not sure, needs testing, if we do use this we'd
2881 * neet to inform below to not reset the mcast */
2882 /* ath5k_hw_set_mcast_filterindex(ah,
2883 * mclist->dmi_addr[5]); */
2884 mclist = mclist->next;
2885 }
2886
2887 return ((u64)(mfilt[1]) << 32) | mfilt[0];
2888}
2889
2856#define SUPPORTED_FIF_FLAGS \ 2890#define SUPPORTED_FIF_FLAGS \
2857 FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \ 2891 FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \
2858 FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ 2892 FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
@@ -2878,16 +2912,14 @@ unlock:
2878static void ath5k_configure_filter(struct ieee80211_hw *hw, 2912static void ath5k_configure_filter(struct ieee80211_hw *hw,
2879 unsigned int changed_flags, 2913 unsigned int changed_flags,
2880 unsigned int *new_flags, 2914 unsigned int *new_flags,
2881 int mc_count, struct dev_mc_list *mclist) 2915 u64 multicast)
2882{ 2916{
2883 struct ath5k_softc *sc = hw->priv; 2917 struct ath5k_softc *sc = hw->priv;
2884 struct ath5k_hw *ah = sc->ah; 2918 struct ath5k_hw *ah = sc->ah;
2885 u32 mfilt[2], val, rfilt; 2919 u32 mfilt[2], rfilt;
2886 u8 pos;
2887 int i;
2888 2920
2889 mfilt[0] = 0; 2921 mfilt[0] = multicast;
2890 mfilt[1] = 0; 2922 mfilt[1] = multicast >> 32;
2891 2923
2892 /* Only deal with supported flags */ 2924 /* Only deal with supported flags */
2893 changed_flags &= SUPPORTED_FIF_FLAGS; 2925 changed_flags &= SUPPORTED_FIF_FLAGS;
@@ -2913,24 +2945,6 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
2913 if (*new_flags & FIF_ALLMULTI) { 2945 if (*new_flags & FIF_ALLMULTI) {
2914 mfilt[0] = ~0; 2946 mfilt[0] = ~0;
2915 mfilt[1] = ~0; 2947 mfilt[1] = ~0;
2916 } else {
2917 for (i = 0; i < mc_count; i++) {
2918 if (!mclist)
2919 break;
2920 /* calculate XOR of eight 6-bit values */
2921 val = get_unaligned_le32(mclist->dmi_addr + 0);
2922 pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
2923 val = get_unaligned_le32(mclist->dmi_addr + 3);
2924 pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
2925 pos &= 0x3f;
2926 mfilt[pos / 32] |= (1 << (pos % 32));
2927 /* XXX: we might be able to just do this instead,
2928 * but not sure, needs testing, if we do use this we'd
2929 * neet to inform below to not reset the mcast */
2930 /* ath5k_hw_set_mcast_filterindex(ah,
2931 * mclist->dmi_addr[5]); */
2932 mclist = mclist->next;
2933 }
2934 } 2948 }
2935 2949
2936 /* This is the best we can do */ 2950 /* This is the best we can do */
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 25a72a85aaa5..a28c42f32c9d 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -50,6 +50,8 @@
50 50
51#include "ath5k.h" 51#include "ath5k.h"
52#include "debug.h" 52#include "debug.h"
53
54#include "../regd.h"
53#include "../ath.h" 55#include "../ath.h"
54 56
55#define ATH_RXBUF 40 /* number of RX buffers */ 57#define ATH_RXBUF 40 /* number of RX buffers */
@@ -200,4 +202,15 @@ struct ath5k_softc {
200#define ath5k_hw_hasveol(_ah) \ 202#define ath5k_hw_hasveol(_ah) \
201 (ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0) 203 (ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0)
202 204
205static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah)
206{
207 return &ah->ah_sc->common;
208}
209
210static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
211{
212 return &(ath5k_hw_common(ah)->regulatory);
213
214}
215
203#endif 216#endif
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 298fcf015227..1a039f2bd732 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -2198,6 +2198,7 @@ static void
2198ath5k_get_max_ctl_power(struct ath5k_hw *ah, 2198ath5k_get_max_ctl_power(struct ath5k_hw *ah,
2199 struct ieee80211_channel *channel) 2199 struct ieee80211_channel *channel)
2200{ 2200{
2201 struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
2201 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 2202 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
2202 struct ath5k_edge_power *rep = ee->ee_ctl_pwr; 2203 struct ath5k_edge_power *rep = ee->ee_ctl_pwr;
2203 u8 *ctl_val = ee->ee_ctl; 2204 u8 *ctl_val = ee->ee_ctl;
@@ -2208,7 +2209,7 @@ ath5k_get_max_ctl_power(struct ath5k_hw *ah,
2208 u8 ctl_idx = 0xFF; 2209 u8 ctl_idx = 0xFF;
2209 u32 target = channel->center_freq; 2210 u32 target = channel->center_freq;
2210 2211
2211 ctl_mode = ath_regd_get_band_ctl(&ah->ah_regulatory, channel->band); 2212 ctl_mode = ath_regd_get_band_ctl(regulatory, channel->band);
2212 2213
2213 switch (channel->hw_value & CHANNEL_MODES) { 2214 switch (channel->hw_value & CHANNEL_MODES) {
2214 case CHANNEL_A: 2215 case CHANNEL_A:
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index f264097a2f4e..a7cbb07988cf 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -538,7 +538,6 @@ void ath9k_ani_reset(struct ath_hw *ah)
538} 538}
539 539
540void ath9k_hw_ani_monitor(struct ath_hw *ah, 540void ath9k_hw_ani_monitor(struct ath_hw *ah,
541 const struct ath9k_node_stats *stats,
542 struct ath9k_channel *chan) 541 struct ath9k_channel *chan)
543{ 542{
544 struct ar5416AniState *aniState; 543 struct ar5416AniState *aniState;
@@ -550,7 +549,6 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah,
550 return; 549 return;
551 550
552 aniState = ah->curani; 551 aniState = ah->curani;
553 ah->stats.ast_nodestats = *stats;
554 552
555 listenTime = ath9k_hw_ani_get_listen_time(ah); 553 listenTime = ath9k_hw_ani_get_listen_time(ah);
556 if (listenTime < 0) { 554 if (listenTime < 0) {
@@ -693,8 +691,7 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
693 * any of the MIB counters overflow/trigger so don't assume we're 691 * any of the MIB counters overflow/trigger so don't assume we're
694 * here because a PHY error counter triggered. 692 * here because a PHY error counter triggered.
695 */ 693 */
696void ath9k_hw_procmibevent(struct ath_hw *ah, 694void ath9k_hw_procmibevent(struct ath_hw *ah)
697 const struct ath9k_node_stats *stats)
698{ 695{
699 u32 phyCnt1, phyCnt2; 696 u32 phyCnt1, phyCnt2;
700 697
@@ -706,7 +703,6 @@ void ath9k_hw_procmibevent(struct ath_hw *ah,
706 703
707 /* Clear the mib counters and save them in the stats */ 704 /* Clear the mib counters and save them in the stats */
708 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); 705 ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
709 ah->stats.ast_nodestats = *stats;
710 706
711 if (!DO_ANI(ah)) 707 if (!DO_ANI(ah))
712 return; 708 return;
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 119924511f85..4e1ab94a5153 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -18,15 +18,10 @@
18#define ANI_H 18#define ANI_H
19 19
20#define HAL_PROCESS_ANI 0x00000001 20#define HAL_PROCESS_ANI 0x00000001
21#define ATH9K_RSSI_EP_MULTIPLIER (1<<7)
22 21
23#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI)) 22#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI))
24 23
25#define HAL_EP_RND(x, mul) \ 24#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
26 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
27#define BEACON_RSSI(ahp) \
28 HAL_EP_RND(ahp->stats.ast_nodestats.ns_avgbrssi, \
29 ATH9K_RSSI_EP_MULTIPLIER)
30 25
31#define ATH9K_ANI_OFDM_TRIG_HIGH 500 26#define ATH9K_ANI_OFDM_TRIG_HIGH 500
32#define ATH9K_ANI_OFDM_TRIG_LOW 200 27#define ATH9K_ANI_OFDM_TRIG_LOW 200
@@ -65,13 +60,6 @@ struct ath9k_mib_stats {
65 u32 beacons; 60 u32 beacons;
66}; 61};
67 62
68struct ath9k_node_stats {
69 u32 ns_avgbrssi;
70 u32 ns_avgrssi;
71 u32 ns_avgtxrssi;
72 u32 ns_avgtxrate;
73};
74
75struct ar5416AniState { 63struct ar5416AniState {
76 struct ath9k_channel *c; 64 struct ath9k_channel *c;
77 u8 noiseImmunityLevel; 65 u8 noiseImmunityLevel;
@@ -115,21 +103,19 @@ struct ar5416Stats {
115 u32 ast_ani_reset; 103 u32 ast_ani_reset;
116 u32 ast_ani_lzero; 104 u32 ast_ani_lzero;
117 u32 ast_ani_lneg; 105 u32 ast_ani_lneg;
106 u32 avgbrssi;
118 struct ath9k_mib_stats ast_mibstats; 107 struct ath9k_mib_stats ast_mibstats;
119 struct ath9k_node_stats ast_nodestats;
120}; 108};
121#define ah_mibStats stats.ast_mibstats 109#define ah_mibStats stats.ast_mibstats
122 110
123void ath9k_ani_reset(struct ath_hw *ah); 111void ath9k_ani_reset(struct ath_hw *ah);
124void ath9k_hw_ani_monitor(struct ath_hw *ah, 112void ath9k_hw_ani_monitor(struct ath_hw *ah,
125 const struct ath9k_node_stats *stats,
126 struct ath9k_channel *chan); 113 struct ath9k_channel *chan);
127void ath9k_enable_mib_counters(struct ath_hw *ah); 114void ath9k_enable_mib_counters(struct ath_hw *ah);
128void ath9k_hw_disable_mib_counters(struct ath_hw *ah); 115void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
129u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt, 116u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
130 u32 *rxf_pcnt, u32 *txf_pcnt); 117 u32 *rxf_pcnt, u32 *txf_pcnt);
131void ath9k_hw_procmibevent(struct ath_hw *ah, 118void ath9k_hw_procmibevent(struct ath_hw *ah);
132 const struct ath9k_node_stats *stats);
133void ath9k_hw_ani_setup(struct ath_hw *ah); 119void ath9k_hw_ani_setup(struct ath_hw *ah);
134void ath9k_hw_ani_init(struct ath_hw *ah); 120void ath9k_hw_ani_init(struct ath_hw *ah);
135void ath9k_hw_ani_disable(struct ath_hw *ah); 121void ath9k_hw_ani_disable(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 2fd663c01b8e..7705da1103f4 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -454,7 +454,8 @@ struct ath_ani {
454/* LED Control */ 454/* LED Control */
455/********************/ 455/********************/
456 456
457#define ATH_LED_PIN 1 457#define ATH_LED_PIN_DEF 1
458#define ATH_LED_PIN_9287 8
458#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */ 459#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */
459#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */ 460#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */
460 461
@@ -602,7 +603,6 @@ struct ath_softc {
602 int beacon_interval; 603 int beacon_interval;
603 604
604 struct ath_ani ani; 605 struct ath_ani ani;
605 struct ath9k_node_stats nodestats;
606#ifdef CONFIG_ATH9K_DEBUG 606#ifdef CONFIG_ATH9K_DEBUG
607 struct ath9k_debug debug; 607 struct ath9k_debug debug;
608#endif 608#endif
@@ -630,6 +630,16 @@ int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
630int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); 630int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
631int ath_cabq_update(struct ath_softc *); 631int ath_cabq_update(struct ath_softc *);
632 632
633static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
634{
635 return &ah->ah_sc->common;
636}
637
638static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
639{
640 return &(ath9k_hw_common(ah)->regulatory);
641}
642
633static inline void ath_read_cachesize(struct ath_softc *sc, int *csz) 643static inline void ath_read_cachesize(struct ath_softc *sc, int *csz)
634{ 644{
635 sc->bus_ops->read_cachesize(sc, csz); 645 sc->bus_ops->read_cachesize(sc, csz);
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 26d87527acbd..20f74b5b5703 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -729,26 +729,42 @@ s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
729static void ath9k_olc_temp_compensation(struct ath_hw *ah) 729static void ath9k_olc_temp_compensation(struct ath_hw *ah)
730{ 730{
731 u32 rddata, i; 731 u32 rddata, i;
732 int delta, currPDADC, regval; 732 int delta, currPDADC, regval, slope;
733 733
734 rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4); 734 rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
735
736 currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT); 735 currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
737 736
738 if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
739 delta = (currPDADC - ah->initPDADC + 4) / 8;
740 else
741 delta = (currPDADC - ah->initPDADC + 5) / 10;
742 737
743 if (delta != ah->PDADCdelta) { 738 if (OLC_FOR_AR9287_10_LATER) {
744 ah->PDADCdelta = delta; 739 if (ah->initPDADC == 0 || currPDADC == 0) {
745 for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) { 740 return;
746 regval = ah->originalGain[i] - delta; 741 } else {
747 if (regval < 0) 742 slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE);
748 regval = 0; 743 if (slope == 0)
744 delta = 0;
745 else
746 delta = ((currPDADC - ah->initPDADC)*4) / slope;
747 REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11,
748 AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
749 REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11,
750 AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta);
751 }
752 } else {
753 if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
754 delta = (currPDADC - ah->initPDADC + 4) / 8;
755 else
756 delta = (currPDADC - ah->initPDADC + 5) / 10;
757
758 if (delta != ah->PDADCdelta) {
759 ah->PDADCdelta = delta;
760 for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
761 regval = ah->originalGain[i] - delta;
762 if (regval < 0)
763 regval = 0;
749 764
750 REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4, 765 REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4,
751 AR_PHY_TX_GAIN, regval); 766 AR_PHY_TX_GAIN, regval);
767 }
752 } 768 }
753 } 769 }
754} 770}
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index d34dd23e806a..b8eca7be5f3a 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -508,6 +508,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
508 || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \ 508 || (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
509 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL)) 509 ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
510 510
511 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
511 int i; 512 int i;
512 int16_t twiceLargestAntenna; 513 int16_t twiceLargestAntenna;
513 u16 twiceMinEdgePower; 514 u16 twiceMinEdgePower;
@@ -541,9 +542,9 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
541 twiceLargestAntenna, 0); 542 twiceLargestAntenna, 0);
542 543
543 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; 544 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
544 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) { 545 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
545 maxRegAllowedPower -= 546 maxRegAllowedPower -=
546 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2); 547 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
547 } 548 }
548 549
549 scaledPower = min(powerLimit, maxRegAllowedPower); 550 scaledPower = min(powerLimit, maxRegAllowedPower);
@@ -707,6 +708,7 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
707 u8 twiceMaxRegulatoryPower, 708 u8 twiceMaxRegulatoryPower,
708 u8 powerLimit) 709 u8 powerLimit)
709{ 710{
711 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
710 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k; 712 struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
711 struct modal_eep_4k_header *pModal = &pEepData->modalHeader; 713 struct modal_eep_4k_header *pModal = &pEepData->modalHeader;
712 int16_t ratesArray[Ar5416RateSize]; 714 int16_t ratesArray[Ar5416RateSize];
@@ -744,7 +746,7 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
744 else if (IS_CHAN_HT20(chan)) 746 else if (IS_CHAN_HT20(chan))
745 i = rateHt20_0; 747 i = rateHt20_0;
746 748
747 ah->regulatory.max_power_level = ratesArray[i]; 749 regulatory->max_power_level = ratesArray[i];
748 750
749 if (AR_SREV_9280_10_OR_LATER(ah)) { 751 if (AR_SREV_9280_10_OR_LATER(ah)) {
750 for (i = 0; i < Ar5416RateSize; i++) 752 for (i = 0; i < Ar5416RateSize; i++)
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index aeb7f484b6e1..c20c21a79b21 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -374,7 +374,6 @@ static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah,
374 u8 *pCalChans, u16 availPiers, 374 u8 *pCalChans, u16 availPiers,
375 int8_t *pPwr) 375 int8_t *pPwr)
376{ 376{
377 u8 pcdac, i = 0;
378 u16 idxL = 0, idxR = 0, numPiers; 377 u16 idxL = 0, idxR = 0, numPiers;
379 bool match; 378 bool match;
380 struct chan_centers centers; 379 struct chan_centers centers;
@@ -392,17 +391,12 @@ static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah,
392 &idxL, &idxR); 391 &idxL, &idxR);
393 392
394 if (match) { 393 if (match) {
395 pcdac = pRawDatasetOpLoop[idxL].pcdac[0][0]; 394 *pPwr = (int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0];
396 *pPwr = pRawDatasetOpLoop[idxL].pwrPdg[0][0];
397 } else { 395 } else {
398 pcdac = pRawDatasetOpLoop[idxR].pcdac[0][0]; 396 *pPwr = ((int8_t) pRawDatasetOpLoop[idxL].pwrPdg[0][0] +
399 *pPwr = (pRawDatasetOpLoop[idxL].pwrPdg[0][0] + 397 (int8_t) pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
400 pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
401 } 398 }
402 399
403 while ((pcdac > ah->originalGain[i]) &&
404 (i < (AR9280_TX_GAIN_TABLE_SIZE - 1)))
405 i++;
406} 400}
407 401
408static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah, 402static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah,
@@ -605,7 +599,7 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah,
605{ 599{
606#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 600#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6
607#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 601#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10
608 602 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
609 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 603 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
610 static const u16 tpScaleReductionTable[5] = 604 static const u16 tpScaleReductionTable[5] =
611 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER }; 605 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
@@ -638,9 +632,9 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah,
638 twiceLargestAntenna, 0); 632 twiceLargestAntenna, 0);
639 633
640 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; 634 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
641 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) 635 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX)
642 maxRegAllowedPower -= 636 maxRegAllowedPower -=
643 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2); 637 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
644 638
645 scaledPower = min(powerLimit, maxRegAllowedPower); 639 scaledPower = min(powerLimit, maxRegAllowedPower);
646 640
@@ -837,7 +831,7 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah,
837{ 831{
838#define INCREASE_MAXPOW_BY_TWO_CHAIN 6 832#define INCREASE_MAXPOW_BY_TWO_CHAIN 6
839#define INCREASE_MAXPOW_BY_THREE_CHAIN 10 833#define INCREASE_MAXPOW_BY_THREE_CHAIN 10
840 834 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
841 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; 835 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
842 struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader; 836 struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader;
843 int16_t ratesArray[Ar5416RateSize]; 837 int16_t ratesArray[Ar5416RateSize];
@@ -955,20 +949,20 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah,
955 i = rate6mb; 949 i = rate6mb;
956 950
957 if (AR_SREV_9280_10_OR_LATER(ah)) 951 if (AR_SREV_9280_10_OR_LATER(ah))
958 ah->regulatory.max_power_level = 952 regulatory->max_power_level =
959 ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2; 953 ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2;
960 else 954 else
961 ah->regulatory.max_power_level = ratesArray[i]; 955 regulatory->max_power_level = ratesArray[i];
962 956
963 switch (ar5416_get_ntxchains(ah->txchainmask)) { 957 switch (ar5416_get_ntxchains(ah->txchainmask)) {
964 case 1: 958 case 1:
965 break; 959 break;
966 case 2: 960 case 2:
967 ah->regulatory.max_power_level += 961 regulatory->max_power_level +=
968 INCREASE_MAXPOW_BY_TWO_CHAIN; 962 INCREASE_MAXPOW_BY_TWO_CHAIN;
969 break; 963 break;
970 case 3: 964 case 3:
971 ah->regulatory.max_power_level += 965 regulatory->max_power_level +=
972 INCREASE_MAXPOW_BY_THREE_CHAIN; 966 INCREASE_MAXPOW_BY_THREE_CHAIN;
973 break; 967 break;
974 default: 968 default:
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 5211ad94c8fb..ae7fb5dcb266 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -904,6 +904,7 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
904#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */ 904#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
905#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */ 905#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
906 906
907 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
907 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; 908 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
908 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER; 909 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
909 static const u16 tpScaleReductionTable[5] = 910 static const u16 tpScaleReductionTable[5] =
@@ -953,9 +954,9 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
953 954
954 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna; 955 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
955 956
956 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) { 957 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
957 maxRegAllowedPower -= 958 maxRegAllowedPower -=
958 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2); 959 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
959 } 960 }
960 961
961 scaledPower = min(powerLimit, maxRegAllowedPower); 962 scaledPower = min(powerLimit, maxRegAllowedPower);
@@ -1163,6 +1164,7 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1163 u8 powerLimit) 1164 u8 powerLimit)
1164{ 1165{
1165#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta) 1166#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
1167 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
1166 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; 1168 struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
1167 struct modal_eep_header *pModal = 1169 struct modal_eep_header *pModal =
1168 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]); 1170 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
@@ -1292,19 +1294,19 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
1292 i = rateHt20_0; 1294 i = rateHt20_0;
1293 1295
1294 if (AR_SREV_9280_10_OR_LATER(ah)) 1296 if (AR_SREV_9280_10_OR_LATER(ah))
1295 ah->regulatory.max_power_level = 1297 regulatory->max_power_level =
1296 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2; 1298 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
1297 else 1299 else
1298 ah->regulatory.max_power_level = ratesArray[i]; 1300 regulatory->max_power_level = ratesArray[i];
1299 1301
1300 switch(ar5416_get_ntxchains(ah->txchainmask)) { 1302 switch(ar5416_get_ntxchains(ah->txchainmask)) {
1301 case 1: 1303 case 1:
1302 break; 1304 break;
1303 case 2: 1305 case 2:
1304 ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN; 1306 regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
1305 break; 1307 break;
1306 case 3: 1308 case 3:
1307 ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN; 1309 regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
1308 break; 1310 break;
1309 default: 1311 default:
1310 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 1312 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 9f1b34d9861a..4f3d5ea34812 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -439,8 +439,13 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
439 439
440static void ath9k_hw_init_defaults(struct ath_hw *ah) 440static void ath9k_hw_init_defaults(struct ath_hw *ah)
441{ 441{
442 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
443
444 regulatory->country_code = CTRY_DEFAULT;
445 regulatory->power_limit = MAX_RATE_POWER;
446 regulatory->tp_scale = ATH9K_TP_SCALE_MAX;
447
442 ah->hw_version.magic = AR5416_MAGIC; 448 ah->hw_version.magic = AR5416_MAGIC;
443 ah->regulatory.country_code = CTRY_DEFAULT;
444 ah->hw_version.subvendorid = 0; 449 ah->hw_version.subvendorid = 0;
445 450
446 ah->ah_flags = 0; 451 ah->ah_flags = 0;
@@ -449,8 +454,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
449 if (!AR_SREV_9100(ah)) 454 if (!AR_SREV_9100(ah))
450 ah->ah_flags = AH_USE_EEPROM; 455 ah->ah_flags = AH_USE_EEPROM;
451 456
452 ah->regulatory.power_limit = MAX_RATE_POWER;
453 ah->regulatory.tp_scale = ATH9K_TP_SCALE_MAX;
454 ah->atim_window = 0; 457 ah->atim_window = 0;
455 ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE; 458 ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
456 ah->beacon_interval = 100; 459 ah->beacon_interval = 100;
@@ -1332,11 +1335,21 @@ static void ath9k_olc_init(struct ath_hw *ah)
1332{ 1335{
1333 u32 i; 1336 u32 i;
1334 1337
1335 for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++) 1338 if (OLC_FOR_AR9287_10_LATER) {
1336 ah->originalGain[i] = 1339 REG_SET_BIT(ah, AR_PHY_TX_PWRCTRL9,
1337 MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4), 1340 AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL);
1338 AR_PHY_TX_GAIN); 1341 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TXPC0,
1339 ah->PDADCdelta = 0; 1342 AR9287_AN_TXPC0_TXPCMODE,
1343 AR9287_AN_TXPC0_TXPCMODE_S,
1344 AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE);
1345 udelay(100);
1346 } else {
1347 for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
1348 ah->originalGain[i] =
1349 MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
1350 AR_PHY_TX_GAIN);
1351 ah->PDADCdelta = 0;
1352 }
1340} 1353}
1341 1354
1342static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, 1355static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg,
@@ -1358,6 +1371,7 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1358 struct ath9k_channel *chan, 1371 struct ath9k_channel *chan,
1359 enum ath9k_ht_macmode macmode) 1372 enum ath9k_ht_macmode macmode)
1360{ 1373{
1374 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
1361 int i, regWrites = 0; 1375 int i, regWrites = 0;
1362 struct ieee80211_channel *channel = chan->chan; 1376 struct ieee80211_channel *channel = chan->chan;
1363 u32 modesIndex, freqIndex; 1377 u32 modesIndex, freqIndex;
@@ -1464,11 +1478,11 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1464 ath9k_olc_init(ah); 1478 ath9k_olc_init(ah);
1465 1479
1466 ah->eep_ops->set_txpower(ah, chan, 1480 ah->eep_ops->set_txpower(ah, chan,
1467 ath9k_regd_get_ctl(&ah->regulatory, chan), 1481 ath9k_regd_get_ctl(regulatory, chan),
1468 channel->max_antenna_gain * 2, 1482 channel->max_antenna_gain * 2,
1469 channel->max_power * 2, 1483 channel->max_power * 2,
1470 min((u32) MAX_RATE_POWER, 1484 min((u32) MAX_RATE_POWER,
1471 (u32) ah->regulatory.power_limit)); 1485 (u32) regulatory->power_limit));
1472 1486
1473 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { 1487 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
1474 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, 1488 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
@@ -1786,6 +1800,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1786 struct ath9k_channel *chan, 1800 struct ath9k_channel *chan,
1787 enum ath9k_ht_macmode macmode) 1801 enum ath9k_ht_macmode macmode)
1788{ 1802{
1803 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
1789 struct ieee80211_channel *channel = chan->chan; 1804 struct ieee80211_channel *channel = chan->chan;
1790 u32 synthDelay, qnum; 1805 u32 synthDelay, qnum;
1791 1806
@@ -1818,11 +1833,11 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
1818 } 1833 }
1819 1834
1820 ah->eep_ops->set_txpower(ah, chan, 1835 ah->eep_ops->set_txpower(ah, chan,
1821 ath9k_regd_get_ctl(&ah->regulatory, chan), 1836 ath9k_regd_get_ctl(regulatory, chan),
1822 channel->max_antenna_gain * 2, 1837 channel->max_antenna_gain * 2,
1823 channel->max_power * 2, 1838 channel->max_power * 2,
1824 min((u32) MAX_RATE_POWER, 1839 min((u32) MAX_RATE_POWER,
1825 (u32) ah->regulatory.power_limit)); 1840 (u32) regulatory->power_limit));
1826 1841
1827 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 1842 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
1828 if (IS_CHAN_B(chan)) 1843 if (IS_CHAN_B(chan))
@@ -2382,7 +2397,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2382 if (AR_SREV_9280_10_OR_LATER(ah)) 2397 if (AR_SREV_9280_10_OR_LATER(ah))
2383 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); 2398 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
2384 2399
2385 if (AR_SREV_9287_10_OR_LATER(ah)) { 2400 if (AR_SREV_9287_12_OR_LATER(ah)) {
2386 /* Enable ASYNC FIFO */ 2401 /* Enable ASYNC FIFO */
2387 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, 2402 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
2388 AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL); 2403 AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
@@ -2468,7 +2483,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2468 2483
2469 ath9k_hw_init_user_settings(ah); 2484 ath9k_hw_init_user_settings(ah);
2470 2485
2471 if (AR_SREV_9287_10_OR_LATER(ah)) { 2486 if (AR_SREV_9287_12_OR_LATER(ah)) {
2472 REG_WRITE(ah, AR_D_GBL_IFS_SIFS, 2487 REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
2473 AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR); 2488 AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
2474 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, 2489 REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
@@ -2484,7 +2499,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2484 REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN, 2499 REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
2485 AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL); 2500 AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
2486 } 2501 }
2487 if (AR_SREV_9287_10_OR_LATER(ah)) { 2502 if (AR_SREV_9287_12_OR_LATER(ah)) {
2488 REG_SET_BIT(ah, AR_PCU_MISC_MODE2, 2503 REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
2489 AR_PCU_MISC_MODE2_ENABLE_AGGWEP); 2504 AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
2490 } 2505 }
@@ -3063,7 +3078,7 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
3063 if (ah->config.pcie_waen) { 3078 if (ah->config.pcie_waen) {
3064 REG_WRITE(ah, AR_WA, ah->config.pcie_waen); 3079 REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
3065 } else { 3080 } else {
3066 if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) 3081 if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || AR_SREV_9287(ah))
3067 REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT); 3082 REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
3068 /* 3083 /*
3069 * On AR9280 chips bit 22 of 0x4004 needs to be set to 3084 * On AR9280 chips bit 22 of 0x4004 needs to be set to
@@ -3470,27 +3485,29 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
3470void ath9k_hw_fill_cap_info(struct ath_hw *ah) 3485void ath9k_hw_fill_cap_info(struct ath_hw *ah)
3471{ 3486{
3472 struct ath9k_hw_capabilities *pCap = &ah->caps; 3487 struct ath9k_hw_capabilities *pCap = &ah->caps;
3488 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
3489
3473 u16 capField = 0, eeval; 3490 u16 capField = 0, eeval;
3474 3491
3475 eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0); 3492 eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
3476 ah->regulatory.current_rd = eeval; 3493 regulatory->current_rd = eeval;
3477 3494
3478 eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1); 3495 eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1);
3479 if (AR_SREV_9285_10_OR_LATER(ah)) 3496 if (AR_SREV_9285_10_OR_LATER(ah))
3480 eeval |= AR9285_RDEXT_DEFAULT; 3497 eeval |= AR9285_RDEXT_DEFAULT;
3481 ah->regulatory.current_rd_ext = eeval; 3498 regulatory->current_rd_ext = eeval;
3482 3499
3483 capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP); 3500 capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
3484 3501
3485 if (ah->opmode != NL80211_IFTYPE_AP && 3502 if (ah->opmode != NL80211_IFTYPE_AP &&
3486 ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) { 3503 ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
3487 if (ah->regulatory.current_rd == 0x64 || 3504 if (regulatory->current_rd == 0x64 ||
3488 ah->regulatory.current_rd == 0x65) 3505 regulatory->current_rd == 0x65)
3489 ah->regulatory.current_rd += 5; 3506 regulatory->current_rd += 5;
3490 else if (ah->regulatory.current_rd == 0x41) 3507 else if (regulatory->current_rd == 0x41)
3491 ah->regulatory.current_rd = 0x43; 3508 regulatory->current_rd = 0x43;
3492 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, 3509 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
3493 "regdomain mapped to 0x%x\n", ah->regulatory.current_rd); 3510 "regdomain mapped to 0x%x\n", regulatory->current_rd);
3494 } 3511 }
3495 3512
3496 eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE); 3513 eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
@@ -3625,7 +3642,7 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
3625 else 3642 else
3626 pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; 3643 pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
3627 3644
3628 if (ah->regulatory.current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) { 3645 if (regulatory->current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) {
3629 pCap->reg_cap = 3646 pCap->reg_cap =
3630 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A | 3647 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3631 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN | 3648 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
@@ -3654,6 +3671,7 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
3654bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, 3671bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
3655 u32 capability, u32 *result) 3672 u32 capability, u32 *result)
3656{ 3673{
3674 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
3657 switch (type) { 3675 switch (type) {
3658 case ATH9K_CAP_CIPHER: 3676 case ATH9K_CAP_CIPHER:
3659 switch (capability) { 3677 switch (capability) {
@@ -3702,13 +3720,13 @@ bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
3702 case 0: 3720 case 0:
3703 return 0; 3721 return 0;
3704 case 1: 3722 case 1:
3705 *result = ah->regulatory.power_limit; 3723 *result = regulatory->power_limit;
3706 return 0; 3724 return 0;
3707 case 2: 3725 case 2:
3708 *result = ah->regulatory.max_power_level; 3726 *result = regulatory->max_power_level;
3709 return 0; 3727 return 0;
3710 case 3: 3728 case 3:
3711 *result = ah->regulatory.tp_scale; 3729 *result = regulatory->tp_scale;
3712 return 0; 3730 return 0;
3713 } 3731 }
3714 return false; 3732 return false;
@@ -3946,17 +3964,18 @@ bool ath9k_hw_disable(struct ath_hw *ah)
3946 3964
3947void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit) 3965void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
3948{ 3966{
3967 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
3949 struct ath9k_channel *chan = ah->curchan; 3968 struct ath9k_channel *chan = ah->curchan;
3950 struct ieee80211_channel *channel = chan->chan; 3969 struct ieee80211_channel *channel = chan->chan;
3951 3970
3952 ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER); 3971 regulatory->power_limit = min(limit, (u32) MAX_RATE_POWER);
3953 3972
3954 ah->eep_ops->set_txpower(ah, chan, 3973 ah->eep_ops->set_txpower(ah, chan,
3955 ath9k_regd_get_ctl(&ah->regulatory, chan), 3974 ath9k_regd_get_ctl(regulatory, chan),
3956 channel->max_antenna_gain * 2, 3975 channel->max_antenna_gain * 2,
3957 channel->max_power * 2, 3976 channel->max_power * 2,
3958 min((u32) MAX_RATE_POWER, 3977 min((u32) MAX_RATE_POWER,
3959 (u32) ah->regulatory.power_limit)); 3978 (u32) regulatory->power_limit));
3960} 3979}
3961 3980
3962void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac) 3981void 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 0336981a70ec..24b30631d93e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -396,7 +396,6 @@ struct ath_hw {
396 struct ath9k_hw_version hw_version; 396 struct ath9k_hw_version hw_version;
397 struct ath9k_ops_config config; 397 struct ath9k_ops_config config;
398 struct ath9k_hw_capabilities caps; 398 struct ath9k_hw_capabilities caps;
399 struct ath_regulatory regulatory;
400 struct ath9k_channel channels[38]; 399 struct ath9k_channel channels[38];
401 struct ath9k_channel *curchan; 400 struct ath9k_channel *curchan;
402 401
@@ -522,6 +521,7 @@ struct ath_hw {
522 u32 originalGain[22]; 521 u32 originalGain[22];
523 int initPDADC; 522 int initPDADC;
524 int PDADCdelta; 523 int PDADCdelta;
524 u8 led_pin;
525 525
526 struct ar5416IniArray iniModes; 526 struct ar5416IniArray iniModes;
527 struct ar5416IniArray iniCommon; 527 struct ar5416IniArray iniCommon;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index fa4c6e74f977..9b9b4e8ee1ea 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -384,7 +384,7 @@ static void ath_ani_calibrate(unsigned long data)
384 if (longcal || shortcal || aniflag) { 384 if (longcal || shortcal || aniflag) {
385 /* Call ANI routine if necessary */ 385 /* Call ANI routine if necessary */
386 if (aniflag) 386 if (aniflag)
387 ath9k_hw_ani_monitor(ah, &sc->nodestats, ah->curchan); 387 ath9k_hw_ani_monitor(ah, ah->curchan);
388 388
389 /* Perform calibration if necessary */ 389 /* Perform calibration if necessary */
390 if (longcal || shortcal) { 390 if (longcal || shortcal) {
@@ -589,7 +589,7 @@ irqreturn_t ath_isr(int irq, void *dev)
589 * it will clear whatever condition caused 589 * it will clear whatever condition caused
590 * the interrupt. 590 * the interrupt.
591 */ 591 */
592 ath9k_hw_procmibevent(ah, &sc->nodestats); 592 ath9k_hw_procmibevent(ah);
593 ath9k_hw_set_interrupts(ah, sc->imask); 593 ath9k_hw_set_interrupts(ah, sc->imask);
594 } 594 }
595 595
@@ -940,10 +940,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
940 ath_beacon_config(sc, vif); 940 ath_beacon_config(sc, vif);
941 941
942 /* Reset rssi stats */ 942 /* Reset rssi stats */
943 sc->nodestats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER; 943 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
944 sc->nodestats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
945 sc->nodestats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
946 sc->nodestats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
947 944
948 ath_start_ani(sc); 945 ath_start_ani(sc);
949 } else { 946 } else {
@@ -968,9 +965,9 @@ static void ath_led_blink_work(struct work_struct *work)
968 965
969 if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) || 966 if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
970 (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE)) 967 (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
971 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0); 968 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
972 else 969 else
973 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 970 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
974 (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0); 971 (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
975 972
976 ieee80211_queue_delayed_work(sc->hw, 973 ieee80211_queue_delayed_work(sc->hw,
@@ -1002,7 +999,7 @@ static void ath_led_brightness(struct led_classdev *led_cdev,
1002 case LED_OFF: 999 case LED_OFF:
1003 if (led->led_type == ATH_LED_ASSOC || 1000 if (led->led_type == ATH_LED_ASSOC ||
1004 led->led_type == ATH_LED_RADIO) { 1001 led->led_type == ATH_LED_RADIO) {
1005 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1002 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
1006 (led->led_type == ATH_LED_RADIO)); 1003 (led->led_type == ATH_LED_RADIO));
1007 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; 1004 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
1008 if (led->led_type == ATH_LED_RADIO) 1005 if (led->led_type == ATH_LED_RADIO)
@@ -1017,7 +1014,7 @@ static void ath_led_brightness(struct led_classdev *led_cdev,
1017 ieee80211_queue_delayed_work(sc->hw, 1014 ieee80211_queue_delayed_work(sc->hw,
1018 &sc->ath_led_blink_work, 0); 1015 &sc->ath_led_blink_work, 0);
1019 } else if (led->led_type == ATH_LED_RADIO) { 1016 } else if (led->led_type == ATH_LED_RADIO) {
1020 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0); 1017 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
1021 sc->sc_flags |= SC_OP_LED_ON; 1018 sc->sc_flags |= SC_OP_LED_ON;
1022 } else { 1019 } else {
1023 sc->led_on_cnt++; 1020 sc->led_on_cnt++;
@@ -1062,7 +1059,7 @@ static void ath_deinit_leds(struct ath_softc *sc)
1062 ath_unregister_led(&sc->tx_led); 1059 ath_unregister_led(&sc->tx_led);
1063 ath_unregister_led(&sc->rx_led); 1060 ath_unregister_led(&sc->rx_led);
1064 ath_unregister_led(&sc->radio_led); 1061 ath_unregister_led(&sc->radio_led);
1065 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); 1062 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
1066} 1063}
1067 1064
1068static void ath_init_leds(struct ath_softc *sc) 1065static void ath_init_leds(struct ath_softc *sc)
@@ -1070,11 +1067,16 @@ static void ath_init_leds(struct ath_softc *sc)
1070 char *trigger; 1067 char *trigger;
1071 int ret; 1068 int ret;
1072 1069
1070 if (AR_SREV_9287(sc->sc_ah))
1071 sc->sc_ah->led_pin = ATH_LED_PIN_9287;
1072 else
1073 sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
1074
1073 /* Configure gpio 1 for output */ 1075 /* Configure gpio 1 for output */
1074 ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN, 1076 ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
1075 AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 1077 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1076 /* LED off, active low */ 1078 /* LED off, active low */
1077 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); 1079 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
1078 1080
1079 INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work); 1081 INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
1080 1082
@@ -1153,9 +1155,9 @@ void ath_radio_enable(struct ath_softc *sc)
1153 ath9k_hw_set_interrupts(ah, sc->imask); 1155 ath9k_hw_set_interrupts(ah, sc->imask);
1154 1156
1155 /* Enable LED */ 1157 /* Enable LED */
1156 ath9k_hw_cfg_output(ah, ATH_LED_PIN, 1158 ath9k_hw_cfg_output(ah, ah->led_pin,
1157 AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 1159 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1158 ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0); 1160 ath9k_hw_set_gpio(ah, ah->led_pin, 0);
1159 1161
1160 ieee80211_wake_queues(sc->hw); 1162 ieee80211_wake_queues(sc->hw);
1161 ath9k_ps_restore(sc); 1163 ath9k_ps_restore(sc);
@@ -1171,8 +1173,8 @@ void ath_radio_disable(struct ath_softc *sc)
1171 ieee80211_stop_queues(sc->hw); 1173 ieee80211_stop_queues(sc->hw);
1172 1174
1173 /* Disable LED */ 1175 /* Disable LED */
1174 ath9k_hw_set_gpio(ah, ATH_LED_PIN, 1); 1176 ath9k_hw_set_gpio(ah, ah->led_pin, 1);
1175 ath9k_hw_cfg_gpio_input(ah, ATH_LED_PIN); 1177 ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
1176 1178
1177 /* Disable interrupts */ 1179 /* Disable interrupts */
1178 ath9k_hw_set_interrupts(ah, 0); 1180 ath9k_hw_set_interrupts(ah, 0);
@@ -1288,7 +1290,7 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
1288 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 1290 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
1289 struct ath_wiphy *aphy = hw->priv; 1291 struct ath_wiphy *aphy = hw->priv;
1290 struct ath_softc *sc = aphy->sc; 1292 struct ath_softc *sc = aphy->sc;
1291 struct ath_regulatory *reg = &sc->sc_ah->regulatory; 1293 struct ath_regulatory *reg = &sc->common.regulatory;
1292 1294
1293 return ath_reg_notifier_apply(wiphy, request, reg); 1295 return ath_reg_notifier_apply(wiphy, request, reg);
1294} 1296}
@@ -1581,12 +1583,12 @@ int ath_init_device(u16 devid, struct ath_softc *sc)
1581 1583
1582 ath_set_hw_capab(sc, hw); 1584 ath_set_hw_capab(sc, hw);
1583 1585
1584 error = ath_regd_init(&sc->sc_ah->regulatory, sc->hw->wiphy, 1586 error = ath_regd_init(&sc->common.regulatory, sc->hw->wiphy,
1585 ath9k_reg_notifier); 1587 ath9k_reg_notifier);
1586 if (error) 1588 if (error)
1587 return error; 1589 return error;
1588 1590
1589 reg = &sc->sc_ah->regulatory; 1591 reg = &sc->common.regulatory;
1590 1592
1591 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { 1593 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
1592 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); 1594 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
@@ -2100,6 +2102,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
2100 struct ath_wiphy *aphy = hw->priv; 2102 struct ath_wiphy *aphy = hw->priv;
2101 struct ath_softc *sc = aphy->sc; 2103 struct ath_softc *sc = aphy->sc;
2102 2104
2105 mutex_lock(&sc->mutex);
2106
2103 aphy->state = ATH_WIPHY_INACTIVE; 2107 aphy->state = ATH_WIPHY_INACTIVE;
2104 2108
2105 cancel_delayed_work_sync(&sc->ath_led_blink_work); 2109 cancel_delayed_work_sync(&sc->ath_led_blink_work);
@@ -2112,13 +2116,10 @@ static void ath9k_stop(struct ieee80211_hw *hw)
2112 2116
2113 if (sc->sc_flags & SC_OP_INVALID) { 2117 if (sc->sc_flags & SC_OP_INVALID) {
2114 DPRINTF(sc, ATH_DBG_ANY, "Device not present\n"); 2118 DPRINTF(sc, ATH_DBG_ANY, "Device not present\n");
2119 mutex_unlock(&sc->mutex);
2115 return; 2120 return;
2116 } 2121 }
2117 2122
2118 mutex_lock(&sc->mutex);
2119
2120 cancel_delayed_work_sync(&sc->tx_complete_work);
2121
2122 if (ath9k_wiphy_started(sc)) { 2123 if (ath9k_wiphy_started(sc)) {
2123 mutex_unlock(&sc->mutex); 2124 mutex_unlock(&sc->mutex);
2124 return; /* another wiphy still in use */ 2125 return; /* another wiphy still in use */
@@ -2389,8 +2390,7 @@ skip_chan_change:
2389static void ath9k_configure_filter(struct ieee80211_hw *hw, 2390static void ath9k_configure_filter(struct ieee80211_hw *hw,
2390 unsigned int changed_flags, 2391 unsigned int changed_flags,
2391 unsigned int *total_flags, 2392 unsigned int *total_flags,
2392 int mc_count, 2393 u64 multicast)
2393 struct dev_mc_list *mclist)
2394{ 2394{
2395 struct ath_wiphy *aphy = hw->priv; 2395 struct ath_wiphy *aphy = hw->priv;
2396 struct ath_softc *sc = aphy->sc; 2396 struct ath_softc *sc = aphy->sc;
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 616bdff2b6a1..685a8cebb468 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -236,7 +236,7 @@ static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
236 struct ath_wiphy *aphy = hw->priv; 236 struct ath_wiphy *aphy = hw->priv;
237 struct ath_softc *sc = aphy->sc; 237 struct ath_softc *sc = aphy->sc;
238 238
239 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); 239 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
240 240
241 pci_save_state(pdev); 241 pci_save_state(pdev);
242 pci_disable_device(pdev); 242 pci_disable_device(pdev);
@@ -269,9 +269,9 @@ static int ath_pci_resume(struct pci_dev *pdev)
269 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); 269 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
270 270
271 /* Enable LED */ 271 /* Enable LED */
272 ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN, 272 ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
273 AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 273 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
274 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); 274 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
275 275
276 return 0; 276 return 0;
277} 277}
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index e83cd4ab87f0..dfda6f444648 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -490,11 +490,18 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
490#define AR_PHY_TX_PWRCTRL9 0xa27C 490#define AR_PHY_TX_PWRCTRL9 0xa27C
491#define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00 491#define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00
492#define AR_PHY_TX_DESIRED_SCALE_CCK_S 10 492#define AR_PHY_TX_DESIRED_SCALE_CCK_S 10
493#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000
494#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
493 495
494#define AR_PHY_TX_GAIN_TBL1 0xa300 496#define AR_PHY_TX_GAIN_TBL1 0xa300
495#define AR_PHY_TX_GAIN 0x0007F000 497#define AR_PHY_TX_GAIN 0x0007F000
496#define AR_PHY_TX_GAIN_S 12 498#define AR_PHY_TX_GAIN_S 12
497 499
500#define AR_PHY_CH0_TX_PWRCTRL11 0xa398
501#define AR_PHY_CH1_TX_PWRCTRL11 0xb398
502#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00
503#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
504
498#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0 505#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
499#define AR_PHY_MASK2_M_31_45 0xa3a4 506#define AR_PHY_MASK2_M_31_45 0xa3a4
500#define AR_PHY_MASK2_M_16_30 0xa3a8 507#define AR_PHY_MASK2_M_16_30 0xa3a8
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 61dbdd227444..7b62c220d5fd 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -222,7 +222,7 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
222 222
223 /* Update Beacon RSSI, this is used by ANI. */ 223 /* Update Beacon RSSI, this is used by ANI. */
224 if (ieee80211_is_beacon(fc)) 224 if (ieee80211_is_beacon(fc))
225 sc->nodestats.ns_avgbrssi = ds->ds_rxstat.rs_rssi; 225 sc->sc_ah->stats.avgbrssi = ds->ds_rxstat.rs_rssi;
226 226
227 rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp); 227 rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
228 rx_status->band = hw->conf.channel->band; 228 rx_status->band = hw->conf.channel->band;
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 13fd658b5d33..c9e1ac92d0e9 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -744,6 +744,7 @@
744#define AR_SREV_VERSION_9287 0x180 744#define AR_SREV_VERSION_9287 0x180
745#define AR_SREV_REVISION_9287_10 0 745#define AR_SREV_REVISION_9287_10 0
746#define AR_SREV_REVISION_9287_11 1 746#define AR_SREV_REVISION_9287_11 1
747#define AR_SREV_REVISION_9287_12 2
747#define AR_SREV_VERSION_9271 0x140 748#define AR_SREV_VERSION_9271 0x140
748#define AR_SREV_REVISION_9271_10 0 749#define AR_SREV_REVISION_9271_10 0
749#define AR_SREV_REVISION_9271_11 1 750#define AR_SREV_REVISION_9271_11 1
@@ -817,7 +818,13 @@
817 (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9287) || \ 818 (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9287) || \
818 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \ 819 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
819 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_11))) 820 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_11)))
820 821#define AR_SREV_9287_12(_ah) \
822 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
823 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_12))
824#define AR_SREV_9287_12_OR_LATER(_ah) \
825 (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9287) || \
826 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
827 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_12)))
821#define AR_SREV_9271(_ah) \ 828#define AR_SREV_9271(_ah) \
822 (((_ah))->hw_version.macVersion == AR_SREV_VERSION_9271) 829 (((_ah))->hw_version.macVersion == AR_SREV_VERSION_9271)
823#define AR_SREV_9271_10(_ah) \ 830#define AR_SREV_9271_10(_ah) \
diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h
index 07291ccb23f2..4d3c53674e5a 100644
--- a/drivers/net/wireless/ath/regd.h
+++ b/drivers/net/wireless/ath/regd.h
@@ -18,9 +18,10 @@
18#define REGD_H 18#define REGD_H
19 19
20#include <linux/nl80211.h> 20#include <linux/nl80211.h>
21
22#include <net/cfg80211.h> 21#include <net/cfg80211.h>
23 22
23#include "ath.h"
24
24#define NO_CTL 0xff 25#define NO_CTL 0xff
25#define SD_NO_CTL 0xE0 26#define SD_NO_CTL 0xE0
26#define NO_CTL 0xff 27#define NO_CTL 0xff
@@ -47,29 +48,12 @@
47#define CHANNEL_HALF_BW 10 48#define CHANNEL_HALF_BW 10
48#define CHANNEL_QUARTER_BW 5 49#define CHANNEL_QUARTER_BW 5
49 50
50struct reg_dmn_pair_mapping {
51 u16 regDmnEnum;
52 u16 reg_5ghz_ctl;
53 u16 reg_2ghz_ctl;
54};
55
56struct country_code_to_enum_rd { 51struct country_code_to_enum_rd {
57 u16 countryCode; 52 u16 countryCode;
58 u16 regDmnEnum; 53 u16 regDmnEnum;
59 const char *isoName; 54 const char *isoName;
60}; 55};
61 56
62struct ath_regulatory {
63 char alpha2[2];
64 u16 country_code;
65 u16 max_power_level;
66 u32 tp_scale;
67 u16 current_rd;
68 u16 current_rd_ext;
69 int16_t power_limit;
70 struct reg_dmn_pair_mapping *regpair;
71};
72
73enum CountryCode { 57enum CountryCode {
74 CTRY_ALBANIA = 8, 58 CTRY_ALBANIA = 8,
75 CTRY_ALGERIA = 12, 59 CTRY_ALGERIA = 12,
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 67f564e37225..237b1aadf9b6 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -80,16 +80,16 @@ config B43_NPHY
80 SAY N. 80 SAY N.
81 81
82config B43_PHY_LP 82config B43_PHY_LP
83 bool "IEEE 802.11g LP-PHY support (BROKEN)" 83 bool "Support for low-power (LP-PHY) devices (EXPERIMENTAL)"
84 depends on B43 && EXPERIMENTAL && BROKEN 84 depends on B43 && EXPERIMENTAL
85 ---help--- 85 ---help---
86 Support for the LP-PHY. 86 Support for the LP-PHY.
87 The LP-PHY is an IEEE 802.11g based PHY built into some notebooks 87 The LP-PHY is a low-power PHY built into some notebooks
88 and embedded devices. 88 and embedded devices. It supports 802.11a/g
89 89 (802.11a support is optional, and currently disabled).
90 THIS IS BROKEN AND DOES NOT WORK YET.
91 90
92 SAY N. 91 This is heavily experimental, and probably will not work for you.
92 Say N unless you want to help debug the driver.
93 93
94# This config option automatically enables b43 LEDS support, 94# This config option automatically enables b43 LEDS support,
95# if it's possible. 95# if it's possible.
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 41a0e9c2b339..289aaf6dfe79 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1188,7 +1188,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
1188 header = &(ring->txhdr_cache[(slot / TX_SLOTS_PER_FRAME) * hdrsize]); 1188 header = &(ring->txhdr_cache[(slot / TX_SLOTS_PER_FRAME) * hdrsize]);
1189 cookie = generate_cookie(ring, slot); 1189 cookie = generate_cookie(ring, slot);
1190 err = b43_generate_txhdr(ring->dev, header, 1190 err = b43_generate_txhdr(ring->dev, header,
1191 skb->data, skb->len, info, cookie); 1191 skb, info, cookie);
1192 if (unlikely(err)) { 1192 if (unlikely(err)) {
1193 ring->current_slot = old_top_slot; 1193 ring->current_slot = old_top_slot;
1194 ring->used_slots = old_used_slots; 1194 ring->used_slots = old_used_slots;
diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c
index 22d0fbd83a62..976104f634a1 100644
--- a/drivers/net/wireless/b43/lo.c
+++ b/drivers/net/wireless/b43/lo.c
@@ -477,7 +477,7 @@ static void lo_measure_setup(struct b43_wldev *dev,
477 } else 477 } else
478 b43_phy_write(dev, B43_PHY_CCK(0x2B), 0x0802); 478 b43_phy_write(dev, B43_PHY_CCK(0x2B), 0x0802);
479 if (phy->rev >= 2) 479 if (phy->rev >= 2)
480 b43_dummy_transmission(dev); 480 b43_dummy_transmission(dev, false, true);
481 b43_gphy_channel_switch(dev, 6, 0); 481 b43_gphy_channel_switch(dev, 6, 0);
482 b43_radio_read16(dev, 0x51); /* dummy read */ 482 b43_radio_read16(dev, 0x51); /* dummy read */
483 if (phy->type == B43_PHYTYPE_G) 483 if (phy->type == B43_PHYTYPE_G)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 950beefbeaeb..f5bdf1cae1d1 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -80,6 +80,10 @@ static int modparam_nohwcrypt;
80module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); 80module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
81MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 81MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
82 82
83static int modparam_hwtkip;
84module_param_named(hwtkip, modparam_hwtkip, int, 0444);
85MODULE_PARM_DESC(hwtkip, "Enable hardware tkip.");
86
83static int modparam_qos = 1; 87static int modparam_qos = 1;
84module_param_named(qos, modparam_qos, int, 0444); 88module_param_named(qos, modparam_qos, int, 0444);
85MODULE_PARM_DESC(qos, "Enable QOS support (default on)"); 89MODULE_PARM_DESC(qos, "Enable QOS support (default on)");
@@ -691,9 +695,9 @@ static void b43_synchronize_irq(struct b43_wldev *dev)
691} 695}
692 696
693/* DummyTransmission function, as documented on 697/* DummyTransmission function, as documented on
694 * http://bcm-specs.sipsolutions.net/DummyTransmission 698 * http://bcm-v4.sipsolutions.net/802.11/DummyTransmission
695 */ 699 */
696void b43_dummy_transmission(struct b43_wldev *dev) 700void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on)
697{ 701{
698 struct b43_wl *wl = dev->wl; 702 struct b43_wl *wl = dev->wl;
699 struct b43_phy *phy = &dev->phy; 703 struct b43_phy *phy = &dev->phy;
@@ -707,19 +711,12 @@ void b43_dummy_transmission(struct b43_wldev *dev)
707 0x00000000, 711 0x00000000,
708 }; 712 };
709 713
710 switch (phy->type) { 714 if (ofdm) {
711 case B43_PHYTYPE_A:
712 max_loop = 0x1E; 715 max_loop = 0x1E;
713 buffer[0] = 0x000201CC; 716 buffer[0] = 0x000201CC;
714 break; 717 } else {
715 case B43_PHYTYPE_B:
716 case B43_PHYTYPE_G:
717 max_loop = 0xFA; 718 max_loop = 0xFA;
718 buffer[0] = 0x000B846E; 719 buffer[0] = 0x000B846E;
719 break;
720 default:
721 B43_WARN_ON(1);
722 return;
723 } 720 }
724 721
725 spin_lock_irq(&wl->irq_lock); 722 spin_lock_irq(&wl->irq_lock);
@@ -728,20 +725,35 @@ void b43_dummy_transmission(struct b43_wldev *dev)
728 for (i = 0; i < 5; i++) 725 for (i = 0; i < 5; i++)
729 b43_ram_write(dev, i * 4, buffer[i]); 726 b43_ram_write(dev, i * 4, buffer[i]);
730 727
731 /* Commit writes */
732 b43_read32(dev, B43_MMIO_MACCTL);
733
734 b43_write16(dev, 0x0568, 0x0000); 728 b43_write16(dev, 0x0568, 0x0000);
735 b43_write16(dev, 0x07C0, 0x0000); 729 if (dev->dev->id.revision < 11)
736 value = ((phy->type == B43_PHYTYPE_A) ? 1 : 0); 730 b43_write16(dev, 0x07C0, 0x0000);
731 else
732 b43_write16(dev, 0x07C0, 0x0100);
733 value = (ofdm ? 0x41 : 0x40);
737 b43_write16(dev, 0x050C, value); 734 b43_write16(dev, 0x050C, value);
735 if ((phy->type == B43_PHYTYPE_N) || (phy->type == B43_PHYTYPE_LP))
736 b43_write16(dev, 0x0514, 0x1A02);
738 b43_write16(dev, 0x0508, 0x0000); 737 b43_write16(dev, 0x0508, 0x0000);
739 b43_write16(dev, 0x050A, 0x0000); 738 b43_write16(dev, 0x050A, 0x0000);
740 b43_write16(dev, 0x054C, 0x0000); 739 b43_write16(dev, 0x054C, 0x0000);
741 b43_write16(dev, 0x056A, 0x0014); 740 b43_write16(dev, 0x056A, 0x0014);
742 b43_write16(dev, 0x0568, 0x0826); 741 b43_write16(dev, 0x0568, 0x0826);
743 b43_write16(dev, 0x0500, 0x0000); 742 b43_write16(dev, 0x0500, 0x0000);
744 b43_write16(dev, 0x0502, 0x0030); 743 if (!pa_on && (phy->type == B43_PHYTYPE_N)) {
744 //SPEC TODO
745 }
746
747 switch (phy->type) {
748 case B43_PHYTYPE_N:
749 b43_write16(dev, 0x0502, 0x00D0);
750 break;
751 case B43_PHYTYPE_LP:
752 b43_write16(dev, 0x0502, 0x0050);
753 break;
754 default:
755 b43_write16(dev, 0x0502, 0x0030);
756 }
745 757
746 if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5) 758 if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5)
747 b43_radio_write16(dev, 0x0051, 0x0017); 759 b43_radio_write16(dev, 0x0051, 0x0017);
@@ -826,6 +838,85 @@ static void keymac_write(struct b43_wldev *dev, u8 index, const u8 *addr)
826 (index * 2) + 1, addrtmp[1]); 838 (index * 2) + 1, addrtmp[1]);
827} 839}
828 840
841/* The ucode will use phase1 key with TEK key to decrypt rx packets.
842 * When a packet is received, the iv32 is checked.
843 * - if it doesn't the packet is returned without modification (and software
844 * decryption can be done). That's what happen when iv16 wrap.
845 * - if it does, the rc4 key is computed, and decryption is tried.
846 * Either it will success and B43_RX_MAC_DEC is returned,
847 * either it fails and B43_RX_MAC_DEC|B43_RX_MAC_DECERR is returned
848 * and the packet is not usable (it got modified by the ucode).
849 * So in order to never have B43_RX_MAC_DECERR, we should provide
850 * a iv32 and phase1key that match. Because we drop packets in case of
851 * B43_RX_MAC_DECERR, if we have a correct iv32 but a wrong phase1key, all
852 * packets will be lost without higher layer knowing (ie no resync possible
853 * until next wrap).
854 *
855 * NOTE : this should support 50 key like RCMTA because
856 * (B43_SHM_SH_KEYIDXBLOCK - B43_SHM_SH_TKIPTSCTTAK)/14 = 50
857 */
858static void rx_tkip_phase1_write(struct b43_wldev *dev, u8 index, u32 iv32,
859 u16 *phase1key)
860{
861 unsigned int i;
862 u32 offset;
863 u8 pairwise_keys_start = B43_NR_GROUP_KEYS * 2;
864
865 if (!modparam_hwtkip)
866 return;
867
868 if (b43_new_kidx_api(dev))
869 pairwise_keys_start = B43_NR_GROUP_KEYS;
870
871 B43_WARN_ON(index < pairwise_keys_start);
872 /* We have four default TX keys and possibly four default RX keys.
873 * Physical mac 0 is mapped to physical key 4 or 8, depending
874 * on the firmware version.
875 * So we must adjust the index here.
876 */
877 index -= pairwise_keys_start;
878 B43_WARN_ON(index >= B43_NR_PAIRWISE_KEYS);
879
880 if (b43_debug(dev, B43_DBG_KEYS)) {
881 b43dbg(dev->wl, "rx_tkip_phase1_write : idx 0x%x, iv32 0x%x\n",
882 index, iv32);
883 }
884 /* Write the key to the RX tkip shared mem */
885 offset = B43_SHM_SH_TKIPTSCTTAK + index * (10 + 4);
886 for (i = 0; i < 10; i += 2) {
887 b43_shm_write16(dev, B43_SHM_SHARED, offset + i,
888 phase1key ? phase1key[i / 2] : 0);
889 }
890 b43_shm_write16(dev, B43_SHM_SHARED, offset + i, iv32);
891 b43_shm_write16(dev, B43_SHM_SHARED, offset + i + 2, iv32 >> 16);
892}
893
894static void b43_op_update_tkip_key(struct ieee80211_hw *hw,
895 struct ieee80211_key_conf *keyconf, const u8 *addr,
896 u32 iv32, u16 *phase1key)
897{
898 struct b43_wl *wl = hw_to_b43_wl(hw);
899 struct b43_wldev *dev;
900 int index = keyconf->hw_key_idx;
901
902 if (B43_WARN_ON(!modparam_hwtkip))
903 return;
904
905 mutex_lock(&wl->mutex);
906
907 dev = wl->current_dev;
908 if (!dev || b43_status(dev) < B43_STAT_INITIALIZED)
909 goto out_unlock;
910
911 keymac_write(dev, index, NULL); /* First zero out mac to avoid race */
912
913 rx_tkip_phase1_write(dev, index, iv32, phase1key);
914 keymac_write(dev, index, addr);
915
916out_unlock:
917 mutex_unlock(&wl->mutex);
918}
919
829static void do_key_write(struct b43_wldev *dev, 920static void do_key_write(struct b43_wldev *dev,
830 u8 index, u8 algorithm, 921 u8 index, u8 algorithm,
831 const u8 *key, size_t key_len, const u8 *mac_addr) 922 const u8 *key, size_t key_len, const u8 *mac_addr)
@@ -841,6 +932,19 @@ static void do_key_write(struct b43_wldev *dev,
841 932
842 if (index >= pairwise_keys_start) 933 if (index >= pairwise_keys_start)
843 keymac_write(dev, index, NULL); /* First zero out mac. */ 934 keymac_write(dev, index, NULL); /* First zero out mac. */
935 if (algorithm == B43_SEC_ALGO_TKIP) {
936 /*
937 * We should provide an initial iv32, phase1key pair.
938 * We could start with iv32=0 and compute the corresponding
939 * phase1key, but this means calling ieee80211_get_tkip_key
940 * with a fake skb (or export other tkip function).
941 * Because we are lazy we hope iv32 won't start with
942 * 0xffffffff and let's b43_op_update_tkip_key provide a
943 * correct pair.
944 */
945 rx_tkip_phase1_write(dev, index, 0xffffffff, (u16*)buf);
946 } else if (index >= pairwise_keys_start) /* clear it */
947 rx_tkip_phase1_write(dev, index, 0, NULL);
844 if (key) 948 if (key)
845 memcpy(buf, key, key_len); 949 memcpy(buf, key, key_len);
846 key_write(dev, index, algorithm, buf); 950 key_write(dev, index, algorithm, buf);
@@ -859,6 +963,15 @@ static int b43_key_write(struct b43_wldev *dev,
859 int i; 963 int i;
860 int pairwise_keys_start; 964 int pairwise_keys_start;
861 965
966 /* For ALG_TKIP the key is encoded as a 256-bit (32 byte) data block:
967 * - Temporal Encryption Key (128 bits)
968 * - Temporal Authenticator Tx MIC Key (64 bits)
969 * - Temporal Authenticator Rx MIC Key (64 bits)
970 *
971 * Hardware only store TEK
972 */
973 if (algorithm == B43_SEC_ALGO_TKIP && key_len == 32)
974 key_len = 16;
862 if (key_len > B43_SEC_KEYSIZE) 975 if (key_len > B43_SEC_KEYSIZE)
863 return -EINVAL; 976 return -EINVAL;
864 for (i = 0; i < ARRAY_SIZE(dev->key); i++) { 977 for (i = 0; i < ARRAY_SIZE(dev->key); i++) {
@@ -965,6 +1078,14 @@ static void b43_dump_keymemory(struct b43_wldev *dev)
965 printk(" Algo: %04X/%02X", algo, key->algorithm); 1078 printk(" Algo: %04X/%02X", algo, key->algorithm);
966 1079
967 if (index >= pairwise_keys_start) { 1080 if (index >= pairwise_keys_start) {
1081 if (key->algorithm == B43_SEC_ALGO_TKIP) {
1082 printk(" TKIP: ");
1083 offset = B43_SHM_SH_TKIPTSCTTAK + (index - 4) * (10 + 4);
1084 for (i = 0; i < 14; i += 2) {
1085 u16 tmp = b43_shm_read16(dev, B43_SHM_SHARED, offset + i);
1086 printk("%02X%02X", (tmp & 0xFF), ((tmp >> 8) & 0xFF));
1087 }
1088 }
968 rcmta0 = b43_shm_read32(dev, B43_SHM_RCMTA, 1089 rcmta0 = b43_shm_read32(dev, B43_SHM_RCMTA,
969 ((index - pairwise_keys_start) * 2) + 0); 1090 ((index - pairwise_keys_start) * 2) + 0);
970 rcmta1 = b43_shm_read16(dev, B43_SHM_RCMTA, 1091 rcmta1 = b43_shm_read16(dev, B43_SHM_RCMTA,
@@ -1947,8 +2068,12 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
1947 filename = "ucode5"; 2068 filename = "ucode5";
1948 else if ((rev >= 11) && (rev <= 12)) 2069 else if ((rev >= 11) && (rev <= 12))
1949 filename = "ucode11"; 2070 filename = "ucode11";
1950 else if (rev >= 13) 2071 else if (rev == 13)
1951 filename = "ucode13"; 2072 filename = "ucode13";
2073 else if (rev == 14)
2074 filename = "ucode14";
2075 else if (rev >= 15)
2076 filename = "ucode15";
1952 else 2077 else
1953 goto err_no_ucode; 2078 goto err_no_ucode;
1954 err = b43_do_request_fw(ctx, filename, &fw->ucode); 2079 err = b43_do_request_fw(ctx, filename, &fw->ucode);
@@ -1996,6 +2121,16 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
1996 else 2121 else
1997 goto err_no_initvals; 2122 goto err_no_initvals;
1998 break; 2123 break;
2124 case B43_PHYTYPE_LP:
2125 if (rev == 13)
2126 filename = "lp0initvals13";
2127 else if (rev == 14)
2128 filename = "lp0initvals14";
2129 else if (rev >= 15)
2130 filename = "lp0initvals15";
2131 else
2132 goto err_no_initvals;
2133 break;
1999 default: 2134 default:
2000 goto err_no_initvals; 2135 goto err_no_initvals;
2001 } 2136 }
@@ -2030,6 +2165,16 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
2030 else 2165 else
2031 goto err_no_initvals; 2166 goto err_no_initvals;
2032 break; 2167 break;
2168 case B43_PHYTYPE_LP:
2169 if (rev == 13)
2170 filename = "lp0bsinitvals13";
2171 else if (rev == 14)
2172 filename = "lp0bsinitvals14";
2173 else if (rev >= 15)
2174 filename = "lp0bsinitvals15";
2175 else
2176 goto err_no_initvals;
2177 break;
2033 default: 2178 default:
2034 goto err_no_initvals; 2179 goto err_no_initvals;
2035 } 2180 }
@@ -2557,6 +2702,7 @@ static void b43_rate_memory_init(struct b43_wldev *dev)
2557 case B43_PHYTYPE_A: 2702 case B43_PHYTYPE_A:
2558 case B43_PHYTYPE_G: 2703 case B43_PHYTYPE_G:
2559 case B43_PHYTYPE_N: 2704 case B43_PHYTYPE_N:
2705 case B43_PHYTYPE_LP:
2560 b43_rate_memory_write(dev, B43_OFDM_RATE_6MB, 1); 2706 b43_rate_memory_write(dev, B43_OFDM_RATE_6MB, 1);
2561 b43_rate_memory_write(dev, B43_OFDM_RATE_12MB, 1); 2707 b43_rate_memory_write(dev, B43_OFDM_RATE_12MB, 1);
2562 b43_rate_memory_write(dev, B43_OFDM_RATE_18MB, 1); 2708 b43_rate_memory_write(dev, B43_OFDM_RATE_18MB, 1);
@@ -3587,8 +3733,10 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3587 3733
3588 switch (cmd) { 3734 switch (cmd) {
3589 case SET_KEY: 3735 case SET_KEY:
3590 if (algorithm == B43_SEC_ALGO_TKIP) { 3736 if (algorithm == B43_SEC_ALGO_TKIP &&
3591 /* FIXME: No TKIP hardware encryption for now. */ 3737 (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE) ||
3738 !modparam_hwtkip)) {
3739 /* We support only pairwise key */
3592 err = -EOPNOTSUPP; 3740 err = -EOPNOTSUPP;
3593 goto out_unlock; 3741 goto out_unlock;
3594 } 3742 }
@@ -3618,6 +3766,8 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3618 b43_hf_read(dev) & ~B43_HF_USEDEFKEYS); 3766 b43_hf_read(dev) & ~B43_HF_USEDEFKEYS);
3619 } 3767 }
3620 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; 3768 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
3769 if (algorithm == B43_SEC_ALGO_TKIP)
3770 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
3621 break; 3771 break;
3622 case DISABLE_KEY: { 3772 case DISABLE_KEY: {
3623 err = b43_key_clear(dev, key->hw_key_idx); 3773 err = b43_key_clear(dev, key->hw_key_idx);
@@ -3646,7 +3796,7 @@ out_unlock:
3646 3796
3647static void b43_op_configure_filter(struct ieee80211_hw *hw, 3797static void b43_op_configure_filter(struct ieee80211_hw *hw,
3648 unsigned int changed, unsigned int *fflags, 3798 unsigned int changed, unsigned int *fflags,
3649 int mc_count, struct dev_addr_list *mc_list) 3799 u64 multicast)
3650{ 3800{
3651 struct b43_wl *wl = hw_to_b43_wl(hw); 3801 struct b43_wl *wl = hw_to_b43_wl(hw);
3652 struct b43_wldev *dev = wl->current_dev; 3802 struct b43_wldev *dev = wl->current_dev;
@@ -3785,7 +3935,7 @@ static int b43_phy_versioning(struct b43_wldev *dev)
3785#endif 3935#endif
3786#ifdef CONFIG_B43_PHY_LP 3936#ifdef CONFIG_B43_PHY_LP
3787 case B43_PHYTYPE_LP: 3937 case B43_PHYTYPE_LP:
3788 if (phy_rev > 1) 3938 if (phy_rev > 2)
3789 unsupported = 1; 3939 unsupported = 1;
3790 break; 3940 break;
3791#endif 3941#endif
@@ -3842,7 +3992,7 @@ static int b43_phy_versioning(struct b43_wldev *dev)
3842 unsupported = 1; 3992 unsupported = 1;
3843 break; 3993 break;
3844 case B43_PHYTYPE_LP: 3994 case B43_PHYTYPE_LP:
3845 if (radio_ver != 0x2062) 3995 if (radio_ver != 0x2062 && radio_ver != 0x2063)
3846 unsupported = 1; 3996 unsupported = 1;
3847 break; 3997 break;
3848 default: 3998 default:
@@ -4345,6 +4495,7 @@ static const struct ieee80211_ops b43_hw_ops = {
4345 .bss_info_changed = b43_op_bss_info_changed, 4495 .bss_info_changed = b43_op_bss_info_changed,
4346 .configure_filter = b43_op_configure_filter, 4496 .configure_filter = b43_op_configure_filter,
4347 .set_key = b43_op_set_key, 4497 .set_key = b43_op_set_key,
4498 .update_tkip_key = b43_op_update_tkip_key,
4348 .get_stats = b43_op_get_stats, 4499 .get_stats = b43_op_get_stats,
4349 .get_tx_stats = b43_op_get_tx_stats, 4500 .get_tx_stats = b43_op_get_tx_stats,
4350 .get_tsf = b43_op_get_tsf, 4501 .get_tsf = b43_op_get_tsf,
@@ -4480,9 +4631,12 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
4480 case B43_PHYTYPE_A: 4631 case B43_PHYTYPE_A:
4481 have_5ghz_phy = 1; 4632 have_5ghz_phy = 1;
4482 break; 4633 break;
4634 case B43_PHYTYPE_LP: //FIXME not always!
4635#if 0 //FIXME enabling 5GHz causes a NULL pointer dereference
4636 have_5ghz_phy = 1;
4637#endif
4483 case B43_PHYTYPE_G: 4638 case B43_PHYTYPE_G:
4484 case B43_PHYTYPE_N: 4639 case B43_PHYTYPE_N:
4485 case B43_PHYTYPE_LP:
4486 have_2ghz_phy = 1; 4640 have_2ghz_phy = 1;
4487 break; 4641 break;
4488 default: 4642 default:
@@ -4497,7 +4651,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
4497 } 4651 }
4498 if (1 /* disable A-PHY */) { 4652 if (1 /* disable A-PHY */) {
4499 /* FIXME: For now we disable the A-PHY on multi-PHY devices. */ 4653 /* FIXME: For now we disable the A-PHY on multi-PHY devices. */
4500 if (dev->phy.type != B43_PHYTYPE_N) { 4654 if (dev->phy.type != B43_PHYTYPE_N &&
4655 dev->phy.type != B43_PHYTYPE_LP) {
4501 have_2ghz_phy = 1; 4656 have_2ghz_phy = 1;
4502 have_5ghz_phy = 0; 4657 have_5ghz_phy = 0;
4503 } 4658 }
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h
index 950fb1b0546d..0406e06781d4 100644
--- a/drivers/net/wireless/b43/main.h
+++ b/drivers/net/wireless/b43/main.h
@@ -123,7 +123,7 @@ void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value
123u64 b43_hf_read(struct b43_wldev *dev); 123u64 b43_hf_read(struct b43_wldev *dev);
124void b43_hf_write(struct b43_wldev *dev, u64 value); 124void b43_hf_write(struct b43_wldev *dev, u64 value);
125 125
126void b43_dummy_transmission(struct b43_wldev *dev); 126void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on);
127 127
128void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags); 128void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags);
129 129
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index 5300232449f6..e47131216a67 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -333,7 +333,7 @@ static void b43_set_all_gains(struct b43_wldev *dev,
333 b43_phy_maskset(dev, 0x04A1, 0xBFBF, tmp); 333 b43_phy_maskset(dev, 0x04A1, 0xBFBF, tmp);
334 b43_phy_maskset(dev, 0x04A2, 0xBFBF, tmp); 334 b43_phy_maskset(dev, 0x04A2, 0xBFBF, tmp);
335 } 335 }
336 b43_dummy_transmission(dev); 336 b43_dummy_transmission(dev, false, true);
337} 337}
338 338
339static void b43_set_original_gains(struct b43_wldev *dev) 339static void b43_set_original_gains(struct b43_wldev *dev)
@@ -365,7 +365,7 @@ static void b43_set_original_gains(struct b43_wldev *dev)
365 b43_phy_maskset(dev, 0x04A0, 0xBFBF, 0x4040); 365 b43_phy_maskset(dev, 0x04A0, 0xBFBF, 0x4040);
366 b43_phy_maskset(dev, 0x04A1, 0xBFBF, 0x4040); 366 b43_phy_maskset(dev, 0x04A1, 0xBFBF, 0x4040);
367 b43_phy_maskset(dev, 0x04A2, 0xBFBF, 0x4000); 367 b43_phy_maskset(dev, 0x04A2, 0xBFBF, 0x4000);
368 b43_dummy_transmission(dev); 368 b43_dummy_transmission(dev, false, true);
369} 369}
370 370
371/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */ 371/* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
@@ -1964,7 +1964,7 @@ static void b43_phy_init_pctl(struct b43_wldev *dev)
1964 } 1964 }
1965 b43_set_txpower_g(dev, &bbatt, &rfatt, 0); 1965 b43_set_txpower_g(dev, &bbatt, &rfatt, 0);
1966 } 1966 }
1967 b43_dummy_transmission(dev); 1967 b43_dummy_transmission(dev, false, true);
1968 gphy->cur_idle_tssi = b43_phy_read(dev, B43_PHY_ITSSI); 1968 gphy->cur_idle_tssi = b43_phy_read(dev, B43_PHY_ITSSI);
1969 if (B43_DEBUG) { 1969 if (B43_DEBUG) {
1970 /* Current-Idle-TSSI sanity check. */ 1970 /* Current-Idle-TSSI sanity check. */
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index cfb8337d3859..2d3a5d812c42 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -29,6 +29,25 @@
29#include "tables_lpphy.h" 29#include "tables_lpphy.h"
30 30
31 31
32static inline u16 channel2freq_lp(u8 channel)
33{
34 if (channel < 14)
35 return (2407 + 5 * channel);
36 else if (channel == 14)
37 return 2484;
38 else if (channel < 184)
39 return (5000 + 5 * channel);
40 else
41 return (4000 + 5 * channel);
42}
43
44static unsigned int b43_lpphy_op_get_default_chan(struct b43_wldev *dev)
45{
46 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
47 return 1;
48 return 36;
49}
50
32static int b43_lpphy_op_allocate(struct b43_wldev *dev) 51static int b43_lpphy_op_allocate(struct b43_wldev *dev)
33{ 52{
34 struct b43_phy_lp *lpphy; 53 struct b43_phy_lp *lpphy;
@@ -142,10 +161,9 @@ static void lpphy_read_band_sprom(struct b43_wldev *dev)
142 } 161 }
143} 162}
144 163
145static void lpphy_adjust_gain_table(struct b43_wldev *dev) 164static void lpphy_adjust_gain_table(struct b43_wldev *dev, u32 freq)
146{ 165{
147 struct b43_phy_lp *lpphy = dev->phy.lp; 166 struct b43_phy_lp *lpphy = dev->phy.lp;
148 u32 freq = dev->wl->hw->conf.channel->center_freq;
149 u16 temp[3]; 167 u16 temp[3];
150 u16 isolation; 168 u16 isolation;
151 169
@@ -170,6 +188,8 @@ static void lpphy_adjust_gain_table(struct b43_wldev *dev)
170 188
171static void lpphy_table_init(struct b43_wldev *dev) 189static void lpphy_table_init(struct b43_wldev *dev)
172{ 190{
191 u32 freq = channel2freq_lp(b43_lpphy_op_get_default_chan(dev));
192
173 if (dev->phy.rev < 2) 193 if (dev->phy.rev < 2)
174 lpphy_rev0_1_table_init(dev); 194 lpphy_rev0_1_table_init(dev);
175 else 195 else
@@ -178,14 +198,68 @@ static void lpphy_table_init(struct b43_wldev *dev)
178 lpphy_init_tx_gain_table(dev); 198 lpphy_init_tx_gain_table(dev);
179 199
180 if (dev->phy.rev < 2) 200 if (dev->phy.rev < 2)
181 lpphy_adjust_gain_table(dev); 201 lpphy_adjust_gain_table(dev, freq);
182} 202}
183 203
184static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) 204static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
185{ 205{
186 struct ssb_bus *bus = dev->dev->bus; 206 struct ssb_bus *bus = dev->dev->bus;
207 struct b43_phy_lp *lpphy = dev->phy.lp;
187 u16 tmp, tmp2; 208 u16 tmp, tmp2;
188 209
210 b43_phy_mask(dev, B43_LPPHY_AFE_DAC_CTL, 0xF7FF);
211 b43_phy_write(dev, B43_LPPHY_AFE_CTL, 0);
212 b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVR, 0);
213 b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_0, 0);
214 b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_2, 0);
215 b43_phy_set(dev, B43_LPPHY_AFE_DAC_CTL, 0x0004);
216 b43_phy_maskset(dev, B43_LPPHY_OFDMSYNCTHRESH0, 0xFF00, 0x0078);
217 b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0x83FF, 0x5800);
218 b43_phy_write(dev, B43_LPPHY_ADC_COMPENSATION_CTL, 0x0016);
219 b43_phy_maskset(dev, B43_LPPHY_AFE_ADC_CTL_0, 0xFFF8, 0x0004);
220 b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0x00FF, 0x5400);
221 b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0x00FF, 0x2400);
222 b43_phy_maskset(dev, B43_LPPHY_LOWGAINDB, 0x00FF, 0x2100);
223 b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0xFF00, 0x0006);
224 b43_phy_mask(dev, B43_LPPHY_RX_RADIO_CTL, 0xFFFE);
225 b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFFE0, 0x0005);
226 b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFC10, 0x0180);
227 b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0x83FF, 0x3800);
228 b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xFFF0, 0x0005);
229 b43_phy_maskset(dev, B43_LPPHY_GAIN_MISMATCH_LIMIT, 0xFFC0, 0x001A);
230 b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0xFF00, 0x00B3);
231 b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0x00FF, 0xAD00);
232 b43_phy_maskset(dev, B43_LPPHY_INPUT_PWRDB,
233 0xFF00, lpphy->rx_pwr_offset);
234 if ((bus->sprom.boardflags_lo & B43_BFL_FEM) &&
235 ((b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ||
236 (bus->sprom.boardflags_hi & B43_BFH_PAREF))) {
237 /* TODO:
238 * Set the LDO voltage to 0x0028 - FIXME: What is this?
239 * Call sb_pmu_set_ldo_voltage with 4 and the LDO voltage
240 * as arguments
241 * Call sb_pmu_paref_ldo_enable with argument TRUE
242 */
243 if (dev->phy.rev == 0) {
244 b43_phy_maskset(dev, B43_LPPHY_LP_RF_SIGNAL_LUT,
245 0xFFCF, 0x0010);
246 }
247 b43_lptab_write(dev, B43_LPTAB16(11, 7), 60);
248 } else {
249 //TODO: Call ssb_pmu_paref_ldo_enable with argument FALSE
250 b43_phy_maskset(dev, B43_LPPHY_LP_RF_SIGNAL_LUT,
251 0xFFCF, 0x0020);
252 b43_lptab_write(dev, B43_LPTAB16(11, 7), 100);
253 }
254 tmp = lpphy->rssi_vf | lpphy->rssi_vc << 4 | 0xA000;
255 b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_0, tmp);
256 if (bus->sprom.boardflags_hi & B43_BFH_RSSIINV)
257 b43_phy_maskset(dev, B43_LPPHY_AFE_RSSI_CTL_1, 0xF000, 0x0AAA);
258 else
259 b43_phy_maskset(dev, B43_LPPHY_AFE_RSSI_CTL_1, 0xF000, 0x02AA);
260 b43_lptab_write(dev, B43_LPTAB16(11, 1), 24);
261 b43_phy_maskset(dev, B43_LPPHY_RX_RADIO_CTL,
262 0xFFF9, (lpphy->bx_arch << 1));
189 if (dev->phy.rev == 1 && 263 if (dev->phy.rev == 1 &&
190 (bus->sprom.boardflags_hi & B43_BFH_FEM_BT)) { 264 (bus->sprom.boardflags_hi & B43_BFH_FEM_BT)) {
191 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x000A); 265 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x000A);
@@ -235,7 +309,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
235 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0006); 309 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0006);
236 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0700); 310 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0700);
237 } 311 }
238 if (dev->phy.rev == 1) { 312 if (dev->phy.rev == 1 && (bus->sprom.boardflags_hi & B43_BFH_PAREF)) {
239 b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_5, B43_LPPHY_TR_LOOKUP_1); 313 b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_5, B43_LPPHY_TR_LOOKUP_1);
240 b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_6, B43_LPPHY_TR_LOOKUP_2); 314 b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_6, B43_LPPHY_TR_LOOKUP_2);
241 b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_7, B43_LPPHY_TR_LOOKUP_3); 315 b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_7, B43_LPPHY_TR_LOOKUP_3);
@@ -247,6 +321,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
247 b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x0006); 321 b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x0006);
248 b43_phy_write(dev, B43_LPPHY_GPIO_SELECT, 0x0005); 322 b43_phy_write(dev, B43_LPPHY_GPIO_SELECT, 0x0005);
249 b43_phy_write(dev, B43_LPPHY_GPIO_OUTEN, 0xFFFF); 323 b43_phy_write(dev, B43_LPPHY_GPIO_OUTEN, 0xFFFF);
324 //FIXME the Broadcom driver caches & delays this HF write!
250 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_PR45960W); 325 b43_hf_write(dev, b43_hf_read(dev) | B43_HF_PR45960W);
251 } 326 }
252 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 327 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
@@ -364,7 +439,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
364 b43_phy_maskset(dev, B43_LPPHY_PWR_THRESH1, 0xFFF0, 0x9); 439 b43_phy_maskset(dev, B43_LPPHY_PWR_THRESH1, 0xFFF0, 0x9);
365 b43_phy_mask(dev, B43_LPPHY_GAINDIRECTMISMATCH, ~0xF); 440 b43_phy_mask(dev, B43_LPPHY_GAINDIRECTMISMATCH, ~0xF);
366 b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0x00FF, 0x5500); 441 b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0x00FF, 0x5500);
367 b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xF81F, 0xA0); 442 b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFC1F, 0xA0);
368 b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xE0FF, 0x300); 443 b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xE0FF, 0x300);
369 b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0x00FF, 0x2A00); 444 b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0x00FF, 0x2A00);
370 if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) { 445 if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
@@ -385,7 +460,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
385 b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFFE0, 0x12); 460 b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFFE0, 0x12);
386 b43_phy_maskset(dev, B43_LPPHY_GAINMISMATCH, 0x0FFF, 0x9000); 461 b43_phy_maskset(dev, B43_LPPHY_GAINMISMATCH, 0x0FFF, 0x9000);
387 462
388 if ((bus->chip_id == 0x4325) && (bus->chip_rev == 1)) { 463 if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) {
389 b43_lptab_write(dev, B43_LPTAB16(0x08, 0x14), 0); 464 b43_lptab_write(dev, B43_LPTAB16(0x08, 0x14), 0);
390 b43_lptab_write(dev, B43_LPTAB16(0x08, 0x12), 0x40); 465 b43_lptab_write(dev, B43_LPTAB16(0x08, 0x12), 0x40);
391 } 466 }
@@ -396,6 +471,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
396 b43_phy_maskset(dev, B43_LPPHY_SYNCPEAKCNT, 0xFFF8, 0x6); 471 b43_phy_maskset(dev, B43_LPPHY_SYNCPEAKCNT, 0xFFF8, 0x6);
397 b43_phy_maskset(dev, B43_LPPHY_MINPWR_LEVEL, 0x00FF, 0x9D00); 472 b43_phy_maskset(dev, B43_LPPHY_MINPWR_LEVEL, 0x00FF, 0x9D00);
398 b43_phy_maskset(dev, B43_LPPHY_MINPWR_LEVEL, 0xFF00, 0xA1); 473 b43_phy_maskset(dev, B43_LPPHY_MINPWR_LEVEL, 0xFF00, 0xA1);
474 b43_phy_mask(dev, B43_LPPHY_IDLEAFTERPKTRXTO, 0x00FF);
399 } else /* 5GHz */ 475 } else /* 5GHz */
400 b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x40); 476 b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x40);
401 477
@@ -435,8 +511,9 @@ struct b2062_freqdata {
435/* Initialize the 2062 radio. */ 511/* Initialize the 2062 radio. */
436static void lpphy_2062_init(struct b43_wldev *dev) 512static void lpphy_2062_init(struct b43_wldev *dev)
437{ 513{
514 struct b43_phy_lp *lpphy = dev->phy.lp;
438 struct ssb_bus *bus = dev->dev->bus; 515 struct ssb_bus *bus = dev->dev->bus;
439 u32 crystalfreq, pdiv, tmp, ref; 516 u32 crystalfreq, tmp, ref;
440 unsigned int i; 517 unsigned int i;
441 const struct b2062_freqdata *fd = NULL; 518 const struct b2062_freqdata *fd = NULL;
442 519
@@ -460,10 +537,15 @@ static void lpphy_2062_init(struct b43_wldev *dev)
460 b43_radio_write(dev, B2062_N_TX_CTL3, 0); 537 b43_radio_write(dev, B2062_N_TX_CTL3, 0);
461 b43_radio_write(dev, B2062_N_TX_CTL4, 0); 538 b43_radio_write(dev, B2062_N_TX_CTL4, 0);
462 b43_radio_write(dev, B2062_N_TX_CTL5, 0); 539 b43_radio_write(dev, B2062_N_TX_CTL5, 0);
540 b43_radio_write(dev, B2062_N_TX_CTL6, 0);
463 b43_radio_write(dev, B2062_N_PDN_CTL0, 0x40); 541 b43_radio_write(dev, B2062_N_PDN_CTL0, 0x40);
464 b43_radio_write(dev, B2062_N_PDN_CTL0, 0); 542 b43_radio_write(dev, B2062_N_PDN_CTL0, 0);
465 b43_radio_write(dev, B2062_N_CALIB_TS, 0x10); 543 b43_radio_write(dev, B2062_N_CALIB_TS, 0x10);
466 b43_radio_write(dev, B2062_N_CALIB_TS, 0); 544 b43_radio_write(dev, B2062_N_CALIB_TS, 0);
545 if (dev->phy.rev > 0) {
546 b43_radio_write(dev, B2062_S_BG_CTL1,
547 (b43_radio_read(dev, B2062_N_COMM2) >> 1) | 0x80);
548 }
467 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 549 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
468 b43_radio_set(dev, B2062_N_TSSI_CTL0, 0x1); 550 b43_radio_set(dev, B2062_N_TSSI_CTL0, 0x1);
469 else 551 else
@@ -475,23 +557,27 @@ static void lpphy_2062_init(struct b43_wldev *dev)
475 B43_WARN_ON(!(bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)); 557 B43_WARN_ON(!(bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU));
476 B43_WARN_ON(crystalfreq == 0); 558 B43_WARN_ON(crystalfreq == 0);
477 559
478 if (crystalfreq >= 30000000) { 560 if (crystalfreq <= 30000000) {
479 pdiv = 1; 561 lpphy->pdiv = 1;
480 b43_radio_mask(dev, B2062_S_RFPLL_CTL1, 0xFFFB); 562 b43_radio_mask(dev, B2062_S_RFPLL_CTL1, 0xFFFB);
481 } else { 563 } else {
482 pdiv = 2; 564 lpphy->pdiv = 2;
483 b43_radio_set(dev, B2062_S_RFPLL_CTL1, 0x4); 565 b43_radio_set(dev, B2062_S_RFPLL_CTL1, 0x4);
484 } 566 }
485 567
486 tmp = (800000000 * pdiv + crystalfreq) / (32000000 * pdiv); 568 tmp = (((800000000 * lpphy->pdiv + crystalfreq) /
487 tmp = (tmp - 1) & 0xFF; 569 (2 * crystalfreq)) - 8) & 0xFF;
570 b43_radio_write(dev, B2062_S_RFPLL_CTL7, tmp);
571
572 tmp = (((100 * crystalfreq + 16000000 * lpphy->pdiv) /
573 (32000000 * lpphy->pdiv)) - 1) & 0xFF;
488 b43_radio_write(dev, B2062_S_RFPLL_CTL18, tmp); 574 b43_radio_write(dev, B2062_S_RFPLL_CTL18, tmp);
489 575
490 tmp = (2 * crystalfreq + 1000000 * pdiv) / (2000000 * pdiv); 576 tmp = (((2 * crystalfreq + 1000000 * lpphy->pdiv) /
491 tmp = ((tmp & 0xFF) - 1) & 0xFFFF; 577 (2000000 * lpphy->pdiv)) - 1) & 0xFF;
492 b43_radio_write(dev, B2062_S_RFPLL_CTL19, tmp); 578 b43_radio_write(dev, B2062_S_RFPLL_CTL19, tmp);
493 579
494 ref = (1000 * pdiv + 2 * crystalfreq) / (2000 * pdiv); 580 ref = (1000 * lpphy->pdiv + 2 * crystalfreq) / (2000 * lpphy->pdiv);
495 ref &= 0xFFFF; 581 ref &= 0xFFFF;
496 for (i = 0; i < ARRAY_SIZE(freqdata_tab); i++) { 582 for (i = 0; i < ARRAY_SIZE(freqdata_tab); i++) {
497 if (ref < freqdata_tab[i].freq) { 583 if (ref < freqdata_tab[i].freq) {
@@ -523,9 +609,14 @@ static void lpphy_2063_init(struct b43_wldev *dev)
523 b43_radio_write(dev, B2063_PA_SP7, 0); 609 b43_radio_write(dev, B2063_PA_SP7, 0);
524 b43_radio_write(dev, B2063_TX_RF_SP6, 0x20); 610 b43_radio_write(dev, B2063_TX_RF_SP6, 0x20);
525 b43_radio_write(dev, B2063_TX_RF_SP9, 0x40); 611 b43_radio_write(dev, B2063_TX_RF_SP9, 0x40);
526 b43_radio_write(dev, B2063_PA_SP3, 0xa0); 612 if (dev->phy.rev == 2) {
527 b43_radio_write(dev, B2063_PA_SP4, 0xa0); 613 b43_radio_write(dev, B2063_PA_SP3, 0xa0);
528 b43_radio_write(dev, B2063_PA_SP2, 0x18); 614 b43_radio_write(dev, B2063_PA_SP4, 0xa0);
615 b43_radio_write(dev, B2063_PA_SP2, 0x18);
616 } else {
617 b43_radio_write(dev, B2063_PA_SP3, 0x20);
618 b43_radio_write(dev, B2063_PA_SP2, 0x20);
619 }
529} 620}
530 621
531struct lpphy_stx_table_entry { 622struct lpphy_stx_table_entry {
@@ -592,7 +683,7 @@ static void lpphy_radio_init(struct b43_wldev *dev)
592 b43_phy_mask(dev, B43_LPPHY_FOURWIRE_CTL, 0xFFFD); 683 b43_phy_mask(dev, B43_LPPHY_FOURWIRE_CTL, 0xFFFD);
593 udelay(1); 684 udelay(1);
594 685
595 if (dev->phy.rev < 2) { 686 if (dev->phy.radio_ver == 0x2062) {
596 lpphy_2062_init(dev); 687 lpphy_2062_init(dev);
597 } else { 688 } else {
598 lpphy_2063_init(dev); 689 lpphy_2063_init(dev);
@@ -609,11 +700,18 @@ struct lpphy_iq_est { u32 iq_prod, i_pwr, q_pwr; };
609 700
610static void lpphy_set_rc_cap(struct b43_wldev *dev) 701static void lpphy_set_rc_cap(struct b43_wldev *dev)
611{ 702{
612 u8 rc_cap = dev->phy.lp->rc_cap; 703 struct b43_phy_lp *lpphy = dev->phy.lp;
704
705 u8 rc_cap = (lpphy->rc_cap & 0x1F) >> 1;
706
707 if (dev->phy.rev == 1) //FIXME check channel 14!
708 rc_cap = max_t(u8, rc_cap + 5, 15);
613 709
614 b43_radio_write(dev, B2062_N_RXBB_CALIB2, max_t(u8, rc_cap-4, 0x80)); 710 b43_radio_write(dev, B2062_N_RXBB_CALIB2,
615 b43_radio_write(dev, B2062_N_TX_CTL_A, ((rc_cap & 0x1F) >> 1) | 0x80); 711 max_t(u8, lpphy->rc_cap - 4, 0x80));
616 b43_radio_write(dev, B2062_S_RXG_CNT16, ((rc_cap & 0x1F) >> 2) | 0x80); 712 b43_radio_write(dev, B2062_N_TX_CTL_A, rc_cap | 0x80);
713 b43_radio_write(dev, B2062_S_RXG_CNT16,
714 ((lpphy->rc_cap & 0x1F) >> 2) | 0x80);
617} 715}
618 716
619static u8 lpphy_get_bb_mult(struct b43_wldev *dev) 717static u8 lpphy_get_bb_mult(struct b43_wldev *dev)
@@ -626,9 +724,39 @@ static void lpphy_set_bb_mult(struct b43_wldev *dev, u8 bb_mult)
626 b43_lptab_write(dev, B43_LPTAB16(0, 87), (u16)bb_mult << 8); 724 b43_lptab_write(dev, B43_LPTAB16(0, 87), (u16)bb_mult << 8);
627} 725}
628 726
629static void lpphy_disable_crs(struct b43_wldev *dev) 727static void lpphy_set_deaf(struct b43_wldev *dev, bool user)
630{ 728{
729 struct b43_phy_lp *lpphy = dev->phy.lp;
730
731 if (user)
732 lpphy->crs_usr_disable = 1;
733 else
734 lpphy->crs_sys_disable = 1;
631 b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFF1F, 0x80); 735 b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFF1F, 0x80);
736}
737
738static void lpphy_clear_deaf(struct b43_wldev *dev, bool user)
739{
740 struct b43_phy_lp *lpphy = dev->phy.lp;
741
742 if (user)
743 lpphy->crs_usr_disable = 0;
744 else
745 lpphy->crs_sys_disable = 0;
746
747 if (!lpphy->crs_usr_disable && !lpphy->crs_sys_disable) {
748 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
749 b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL,
750 0xFF1F, 0x60);
751 else
752 b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL,
753 0xFF1F, 0x20);
754 }
755}
756
757static void lpphy_disable_crs(struct b43_wldev *dev, bool user)
758{
759 lpphy_set_deaf(dev, user);
632 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, 0x1); 760 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFC, 0x1);
633 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3); 761 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x3);
634 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFB); 762 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xFFFB);
@@ -656,12 +784,9 @@ static void lpphy_disable_crs(struct b43_wldev *dev)
656 b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_2, 0x3FF); 784 b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_2, 0x3FF);
657} 785}
658 786
659static void lpphy_restore_crs(struct b43_wldev *dev) 787static void lpphy_restore_crs(struct b43_wldev *dev, bool user)
660{ 788{
661 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 789 lpphy_clear_deaf(dev, user);
662 b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFF1F, 0x60);
663 else
664 b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xFF1F, 0x20);
665 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFF80); 790 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFF80);
666 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFC00); 791 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFC00);
667} 792}
@@ -707,10 +832,11 @@ static void lpphy_set_tx_gains(struct b43_wldev *dev,
707 b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, 832 b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL,
708 0xF800, rf_gain); 833 0xF800, rf_gain);
709 } else { 834 } else {
710 pa_gain = b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0x7F00; 835 pa_gain = b43_phy_read(dev, B43_PHY_OFDM(0xFB)) & 0x1FC0;
836 pa_gain <<= 2;
711 b43_phy_write(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, 837 b43_phy_write(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL,
712 (gains.pga << 8) | gains.gm); 838 (gains.pga << 8) | gains.gm);
713 b43_phy_maskset(dev, B43_LPPHY_TX_GAIN_CTL_OVERRIDE_VAL, 839 b43_phy_maskset(dev, B43_PHY_OFDM(0xFB),
714 0x8000, gains.pad | pa_gain); 840 0x8000, gains.pad | pa_gain);
715 b43_phy_write(dev, B43_PHY_OFDM(0xFC), 841 b43_phy_write(dev, B43_PHY_OFDM(0xFC),
716 (gains.pga << 8) | gains.gm); 842 (gains.pga << 8) | gains.gm);
@@ -724,7 +850,7 @@ static void lpphy_set_tx_gains(struct b43_wldev *dev,
724 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFF7F, 1 << 7); 850 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFF7F, 1 << 7);
725 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xBFFF, 1 << 14); 851 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xBFFF, 1 << 14);
726 } 852 }
727 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFFBF, 1 << 4); 853 b43_phy_maskset(dev, B43_LPPHY_AFE_CTL_OVR, 0xFFBF, 1 << 6);
728} 854}
729 855
730static void lpphy_rev0_1_set_rx_gain(struct b43_wldev *dev, u32 gain) 856static void lpphy_rev0_1_set_rx_gain(struct b43_wldev *dev, u32 gain)
@@ -764,33 +890,33 @@ static void lpphy_rev2plus_set_rx_gain(struct b43_wldev *dev, u32 gain)
764 } 890 }
765} 891}
766 892
767static void lpphy_enable_rx_gain_override(struct b43_wldev *dev) 893static void lpphy_disable_rx_gain_override(struct b43_wldev *dev)
768{ 894{
769 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFE); 895 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFFE);
770 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFEF); 896 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFEF);
771 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFBF); 897 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xFFBF);
772 if (dev->phy.rev >= 2) { 898 if (dev->phy.rev >= 2) {
773 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF); 899 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFEFF);
774 if (b43_current_band(dev->wl) != IEEE80211_BAND_2GHZ) 900 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
775 return; 901 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFBFF);
776 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFBFF); 902 b43_phy_mask(dev, B43_PHY_OFDM(0xE5), 0xFFF7);
777 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFFF7); 903 }
778 } else { 904 } else {
779 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFDFF); 905 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_2, 0xFDFF);
780 } 906 }
781} 907}
782 908
783static void lpphy_disable_rx_gain_override(struct b43_wldev *dev) 909static void lpphy_enable_rx_gain_override(struct b43_wldev *dev)
784{ 910{
785 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1); 911 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x1);
786 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x10); 912 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x10);
787 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x40); 913 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_0, 0x40);
788 if (dev->phy.rev >= 2) { 914 if (dev->phy.rev >= 2) {
789 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100); 915 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x100);
790 if (b43_current_band(dev->wl) != IEEE80211_BAND_2GHZ) 916 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
791 return; 917 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x400);
792 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x400); 918 b43_phy_set(dev, B43_PHY_OFDM(0xE5), 0x8);
793 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x8); 919 }
794 } else { 920 } else {
795 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x200); 921 b43_phy_set(dev, B43_LPPHY_RF_OVERRIDE_2, 0x200);
796 } 922 }
@@ -909,26 +1035,22 @@ static u32 lpphy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision)
909{ 1035{
910 u32 quotient, remainder, rbit, roundup, tmp; 1036 u32 quotient, remainder, rbit, roundup, tmp;
911 1037
912 if (divisor == 0) { 1038 if (divisor == 0)
913 quotient = 0; 1039 return 0;
914 remainder = 0; 1040
915 } else { 1041 quotient = dividend / divisor;
916 quotient = dividend / divisor; 1042 remainder = dividend % divisor;
917 remainder = dividend % divisor;
918 }
919 1043
920 rbit = divisor & 0x1; 1044 rbit = divisor & 0x1;
921 roundup = (divisor >> 1) + rbit; 1045 roundup = (divisor >> 1) + rbit;
922 precision--;
923 1046
924 while (precision != 0xFF) { 1047 while (precision != 0) {
925 tmp = remainder - roundup; 1048 tmp = remainder - roundup;
926 quotient <<= 1; 1049 quotient <<= 1;
927 remainder <<= 1; 1050 if (remainder >= roundup)
928 if (remainder >= roundup) {
929 remainder = (tmp << 1) + rbit; 1051 remainder = (tmp << 1) + rbit;
930 quotient--; 1052 else
931 } 1053 remainder <<= 1;
932 precision--; 1054 precision--;
933 } 1055 }
934 1056
@@ -992,9 +1114,9 @@ static void lpphy_set_tx_power_control(struct b43_wldev *dev,
992 struct b43_phy_lp *lpphy = dev->phy.lp; 1114 struct b43_phy_lp *lpphy = dev->phy.lp;
993 enum b43_lpphy_txpctl_mode oldmode; 1115 enum b43_lpphy_txpctl_mode oldmode;
994 1116
995 oldmode = lpphy->txpctl_mode;
996 lpphy_read_tx_pctl_mode_from_hardware(dev); 1117 lpphy_read_tx_pctl_mode_from_hardware(dev);
997 if (lpphy->txpctl_mode == mode) 1118 oldmode = lpphy->txpctl_mode;
1119 if (oldmode == mode)
998 return; 1120 return;
999 lpphy->txpctl_mode = mode; 1121 lpphy->txpctl_mode = mode;
1000 1122
@@ -1022,28 +1144,37 @@ static void lpphy_set_tx_power_control(struct b43_wldev *dev,
1022 lpphy_write_tx_pctl_mode_to_hardware(dev); 1144 lpphy_write_tx_pctl_mode_to_hardware(dev);
1023} 1145}
1024 1146
1147static int b43_lpphy_op_switch_channel(struct b43_wldev *dev,
1148 unsigned int new_channel);
1149
1025static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev) 1150static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev)
1026{ 1151{
1027 struct b43_phy_lp *lpphy = dev->phy.lp; 1152 struct b43_phy_lp *lpphy = dev->phy.lp;
1028 struct lpphy_iq_est iq_est; 1153 struct lpphy_iq_est iq_est;
1029 struct lpphy_tx_gains tx_gains; 1154 struct lpphy_tx_gains tx_gains;
1030 static const u32 ideal_pwr_table[22] = { 1155 static const u32 ideal_pwr_table[21] = {
1031 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64, 1156 0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
1032 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35, 1157 0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
1033 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088, 1158 0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
1034 0x0004c, 0x0002c, 0x0001a, 0xc0006, 1159 0x0004c, 0x0002c, 0x0001a,
1035 }; 1160 };
1036 bool old_txg_ovr; 1161 bool old_txg_ovr;
1037 u8 old_bbmult; 1162 u8 old_bbmult;
1038 u16 old_rf_ovr, old_rf_ovrval, old_afe_ovr, old_afe_ovrval, 1163 u16 old_rf_ovr, old_rf_ovrval, old_afe_ovr, old_afe_ovrval,
1039 old_rf2_ovr, old_rf2_ovrval, old_phy_ctl, old_txpctl; 1164 old_rf2_ovr, old_rf2_ovrval, old_phy_ctl;
1165 enum b43_lpphy_txpctl_mode old_txpctl;
1040 u32 normal_pwr, ideal_pwr, mean_sq_pwr, tmp = 0, mean_sq_pwr_min = 0; 1166 u32 normal_pwr, ideal_pwr, mean_sq_pwr, tmp = 0, mean_sq_pwr_min = 0;
1041 int loopback, i, j, inner_sum; 1167 int loopback, i, j, inner_sum, err;
1042 1168
1043 memset(&iq_est, 0, sizeof(iq_est)); 1169 memset(&iq_est, 0, sizeof(iq_est));
1044 1170
1045 b43_switch_channel(dev, 7); 1171 err = b43_lpphy_op_switch_channel(dev, 7);
1046 old_txg_ovr = (b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) >> 6) & 1; 1172 if (err) {
1173 b43dbg(dev->wl,
1174 "RC calib: Failed to switch to channel 7, error = %d",
1175 err);
1176 }
1177 old_txg_ovr = !!(b43_phy_read(dev, B43_LPPHY_AFE_CTL_OVR) & 0x40);
1047 old_bbmult = lpphy_get_bb_mult(dev); 1178 old_bbmult = lpphy_get_bb_mult(dev);
1048 if (old_txg_ovr) 1179 if (old_txg_ovr)
1049 tx_gains = lpphy_get_tx_gains(dev); 1180 tx_gains = lpphy_get_tx_gains(dev);
@@ -1054,11 +1185,11 @@ static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev)
1054 old_rf2_ovr = b43_phy_read(dev, B43_LPPHY_RF_OVERRIDE_2); 1185 old_rf2_ovr = b43_phy_read(dev, B43_LPPHY_RF_OVERRIDE_2);
1055 old_rf2_ovrval = b43_phy_read(dev, B43_LPPHY_RF_OVERRIDE_2_VAL); 1186 old_rf2_ovrval = b43_phy_read(dev, B43_LPPHY_RF_OVERRIDE_2_VAL);
1056 old_phy_ctl = b43_phy_read(dev, B43_LPPHY_LP_PHY_CTL); 1187 old_phy_ctl = b43_phy_read(dev, B43_LPPHY_LP_PHY_CTL);
1057 old_txpctl = b43_phy_read(dev, B43_LPPHY_TX_PWR_CTL_CMD) & 1188 lpphy_read_tx_pctl_mode_from_hardware(dev);
1058 B43_LPPHY_TX_PWR_CTL_CMD_MODE; 1189 old_txpctl = lpphy->txpctl_mode;
1059 1190
1060 lpphy_set_tx_power_control(dev, B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF); 1191 lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF);
1061 lpphy_disable_crs(dev); 1192 lpphy_disable_crs(dev, true);
1062 loopback = lpphy_loopback(dev); 1193 loopback = lpphy_loopback(dev);
1063 if (loopback == -1) 1194 if (loopback == -1)
1064 goto finish; 1195 goto finish;
@@ -1091,7 +1222,7 @@ static void lpphy_rev0_1_rc_calib(struct b43_wldev *dev)
1091 lpphy_stop_ddfs(dev); 1222 lpphy_stop_ddfs(dev);
1092 1223
1093finish: 1224finish:
1094 lpphy_restore_crs(dev); 1225 lpphy_restore_crs(dev, true);
1095 b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, old_rf_ovrval); 1226 b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, old_rf_ovrval);
1096 b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_0, old_rf_ovr); 1227 b43_phy_write(dev, B43_LPPHY_RF_OVERRIDE_0, old_rf_ovr);
1097 b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVRVAL, old_afe_ovrval); 1228 b43_phy_write(dev, B43_LPPHY_AFE_CTL_OVRVAL, old_afe_ovrval);
@@ -1257,33 +1388,110 @@ static void lpphy_calibration(struct b43_wldev *dev)
1257 b43_mac_enable(dev); 1388 b43_mac_enable(dev);
1258} 1389}
1259 1390
1260/* Initialize TX power control */ 1391static void lpphy_set_tssi_mux(struct b43_wldev *dev, enum tssi_mux_mode mode)
1261static void lpphy_tx_pctl_init(struct b43_wldev *dev)
1262{ 1392{
1263 if (0/*FIXME HWPCTL capable */) { 1393 if (mode != TSSI_MUX_EXT) {
1264 //TODO 1394 b43_radio_set(dev, B2063_PA_SP1, 0x2);
1265 } else { /* This device is only software TX power control capable. */ 1395 b43_phy_set(dev, B43_PHY_OFDM(0xF3), 0x1000);
1266 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 1396 b43_radio_write(dev, B2063_PA_CTL10, 0x51);
1267 //TODO 1397 if (mode == TSSI_MUX_POSTPA) {
1398 b43_radio_mask(dev, B2063_PA_SP1, 0xFFFE);
1399 b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0xFFC7);
1268 } else { 1400 } else {
1269 //TODO 1401 b43_radio_maskset(dev, B2063_PA_SP1, 0xFFFE, 0x1);
1402 b43_phy_maskset(dev, B43_LPPHY_AFE_CTL_OVRVAL,
1403 0xFFC7, 0x20);
1270 } 1404 }
1271 //TODO set BB multiplier to 0x0096 1405 } else {
1406 B43_WARN_ON(1);
1272 } 1407 }
1273} 1408}
1274 1409
1275static int b43_lpphy_op_init(struct b43_wldev *dev) 1410static void lpphy_tx_pctl_init_hw(struct b43_wldev *dev)
1276{ 1411{
1277 lpphy_read_band_sprom(dev); //FIXME should this be in prepare_structs? 1412 u16 tmp;
1278 lpphy_baseband_init(dev); 1413 int i;
1279 lpphy_radio_init(dev);
1280 lpphy_calibrate_rc(dev);
1281 //TODO set channel
1282 lpphy_tx_pctl_init(dev);
1283 lpphy_calibration(dev);
1284 //TODO ACI init
1285 1414
1286 return 0; 1415 //SPEC TODO Call LP PHY Clear TX Power offsets
1416 for (i = 0; i < 64; i++) {
1417 if (dev->phy.rev >= 2)
1418 b43_lptab_write(dev, B43_LPTAB32(7, i + 1), i);
1419 else
1420 b43_lptab_write(dev, B43_LPTAB32(10, i + 1), i);
1421 }
1422
1423 b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_NNUM, 0xFF00, 0xFF);
1424 b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_NNUM, 0x8FFF, 0x5000);
1425 b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_IDLETSSI, 0xFFC0, 0x1F);
1426 if (dev->phy.rev < 2) {
1427 b43_phy_mask(dev, B43_LPPHY_LP_PHY_CTL, 0xEFFF);
1428 b43_phy_maskset(dev, B43_LPPHY_LP_PHY_CTL, 0xDFFF, 0x2000);
1429 } else {
1430 b43_phy_mask(dev, B43_PHY_OFDM(0x103), 0xFFFE);
1431 b43_phy_maskset(dev, B43_PHY_OFDM(0x103), 0xFFFB, 0x4);
1432 b43_phy_maskset(dev, B43_PHY_OFDM(0x103), 0xFFEF, 0x10);
1433 b43_radio_maskset(dev, B2063_IQ_CALIB_CTL2, 0xF3, 0x1);
1434 lpphy_set_tssi_mux(dev, TSSI_MUX_POSTPA);
1435 }
1436 b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_IDLETSSI, 0x7FFF, 0x8000);
1437 b43_phy_mask(dev, B43_LPPHY_TX_PWR_CTL_DELTAPWR_LIMIT, 0xFF);
1438 b43_phy_write(dev, B43_LPPHY_TX_PWR_CTL_DELTAPWR_LIMIT, 0xA);
1439 b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD,
1440 (u16)~B43_LPPHY_TX_PWR_CTL_CMD_MODE,
1441 B43_LPPHY_TX_PWR_CTL_CMD_MODE_OFF);
1442 b43_phy_mask(dev, B43_LPPHY_TX_PWR_CTL_NNUM, 0xF8FF);
1443 b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_CMD,
1444 (u16)~B43_LPPHY_TX_PWR_CTL_CMD_MODE,
1445 B43_LPPHY_TX_PWR_CTL_CMD_MODE_SW);
1446
1447 if (dev->phy.rev < 2) {
1448 b43_phy_maskset(dev, B43_LPPHY_RF_OVERRIDE_0, 0xEFFF, 0x1000);
1449 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_VAL_0, 0xEFFF);
1450 } else {
1451 lpphy_set_tx_power_by_index(dev, 0x7F);
1452 }
1453
1454 b43_dummy_transmission(dev, true, true);
1455
1456 tmp = b43_phy_read(dev, B43_LPPHY_TX_PWR_CTL_STAT);
1457 if (tmp & 0x8000) {
1458 b43_phy_maskset(dev, B43_LPPHY_TX_PWR_CTL_IDLETSSI,
1459 0xFFC0, (tmp & 0xFF) - 32);
1460 }
1461
1462 b43_phy_mask(dev, B43_LPPHY_RF_OVERRIDE_0, 0xEFFF);
1463
1464 // (SPEC?) TODO Set "Target TX frequency" variable to 0
1465 // SPEC FIXME "Set BB Multiplier to 0xE000" impossible - bb_mult is u8!
1466}
1467
1468static void lpphy_tx_pctl_init_sw(struct b43_wldev *dev)
1469{
1470 struct lpphy_tx_gains gains;
1471
1472 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1473 gains.gm = 4;
1474 gains.pad = 12;
1475 gains.pga = 12;
1476 gains.dac = 0;
1477 } else {
1478 gains.gm = 7;
1479 gains.pad = 14;
1480 gains.pga = 15;
1481 gains.dac = 0;
1482 }
1483 lpphy_set_tx_gains(dev, gains);
1484 lpphy_set_bb_mult(dev, 150);
1485}
1486
1487/* Initialize TX power control */
1488static void lpphy_tx_pctl_init(struct b43_wldev *dev)
1489{
1490 if (0/*FIXME HWPCTL capable */) {
1491 lpphy_tx_pctl_init_hw(dev);
1492 } else { /* This device is only software TX power control capable. */
1493 lpphy_tx_pctl_init_sw(dev);
1494 }
1287} 1495}
1288 1496
1289static u16 b43_lpphy_op_read(struct b43_wldev *dev, u16 reg) 1497static u16 b43_lpphy_op_read(struct b43_wldev *dev, u16 reg)
@@ -1328,18 +1536,668 @@ static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev,
1328 //TODO 1536 //TODO
1329} 1537}
1330 1538
1539struct b206x_channel {
1540 u8 channel;
1541 u16 freq;
1542 u8 data[12];
1543};
1544
1545static const struct b206x_channel b2062_chantbl[] = {
1546 { .channel = 1, .freq = 2412, .data[0] = 0xFF, .data[1] = 0xFF,
1547 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
1548 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
1549 { .channel = 2, .freq = 2417, .data[0] = 0xFF, .data[1] = 0xFF,
1550 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
1551 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
1552 { .channel = 3, .freq = 2422, .data[0] = 0xFF, .data[1] = 0xFF,
1553 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
1554 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
1555 { .channel = 4, .freq = 2427, .data[0] = 0xFF, .data[1] = 0xFF,
1556 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
1557 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
1558 { .channel = 5, .freq = 2432, .data[0] = 0xFF, .data[1] = 0xFF,
1559 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
1560 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
1561 { .channel = 6, .freq = 2437, .data[0] = 0xFF, .data[1] = 0xFF,
1562 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
1563 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
1564 { .channel = 7, .freq = 2442, .data[0] = 0xFF, .data[1] = 0xFF,
1565 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
1566 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
1567 { .channel = 8, .freq = 2447, .data[0] = 0xFF, .data[1] = 0xFF,
1568 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
1569 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
1570 { .channel = 9, .freq = 2452, .data[0] = 0xFF, .data[1] = 0xFF,
1571 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
1572 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
1573 { .channel = 10, .freq = 2457, .data[0] = 0xFF, .data[1] = 0xFF,
1574 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
1575 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
1576 { .channel = 11, .freq = 2462, .data[0] = 0xFF, .data[1] = 0xFF,
1577 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
1578 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
1579 { .channel = 12, .freq = 2467, .data[0] = 0xFF, .data[1] = 0xFF,
1580 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
1581 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
1582 { .channel = 13, .freq = 2472, .data[0] = 0xFF, .data[1] = 0xFF,
1583 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
1584 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
1585 { .channel = 14, .freq = 2484, .data[0] = 0xFF, .data[1] = 0xFF,
1586 .data[2] = 0xB5, .data[3] = 0x1B, .data[4] = 0x24, .data[5] = 0x32,
1587 .data[6] = 0x32, .data[7] = 0x88, .data[8] = 0x88, },
1588 { .channel = 34, .freq = 5170, .data[0] = 0x00, .data[1] = 0x22,
1589 .data[2] = 0x20, .data[3] = 0x84, .data[4] = 0x3C, .data[5] = 0x77,
1590 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
1591 { .channel = 38, .freq = 5190, .data[0] = 0x00, .data[1] = 0x11,
1592 .data[2] = 0x10, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
1593 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
1594 { .channel = 42, .freq = 5210, .data[0] = 0x00, .data[1] = 0x11,
1595 .data[2] = 0x10, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
1596 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
1597 { .channel = 46, .freq = 5230, .data[0] = 0x00, .data[1] = 0x00,
1598 .data[2] = 0x00, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
1599 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
1600 { .channel = 36, .freq = 5180, .data[0] = 0x00, .data[1] = 0x11,
1601 .data[2] = 0x20, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
1602 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
1603 { .channel = 40, .freq = 5200, .data[0] = 0x00, .data[1] = 0x11,
1604 .data[2] = 0x10, .data[3] = 0x84, .data[4] = 0x3C, .data[5] = 0x77,
1605 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
1606 { .channel = 44, .freq = 5220, .data[0] = 0x00, .data[1] = 0x11,
1607 .data[2] = 0x00, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
1608 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
1609 { .channel = 48, .freq = 5240, .data[0] = 0x00, .data[1] = 0x00,
1610 .data[2] = 0x00, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
1611 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
1612 { .channel = 52, .freq = 5260, .data[0] = 0x00, .data[1] = 0x00,
1613 .data[2] = 0x00, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
1614 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
1615 { .channel = 56, .freq = 5280, .data[0] = 0x00, .data[1] = 0x00,
1616 .data[2] = 0x00, .data[3] = 0x83, .data[4] = 0x3C, .data[5] = 0x77,
1617 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
1618 { .channel = 60, .freq = 5300, .data[0] = 0x00, .data[1] = 0x00,
1619 .data[2] = 0x00, .data[3] = 0x63, .data[4] = 0x3C, .data[5] = 0x77,
1620 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
1621 { .channel = 64, .freq = 5320, .data[0] = 0x00, .data[1] = 0x00,
1622 .data[2] = 0x00, .data[3] = 0x62, .data[4] = 0x3C, .data[5] = 0x77,
1623 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
1624 { .channel = 100, .freq = 5500, .data[0] = 0x00, .data[1] = 0x00,
1625 .data[2] = 0x00, .data[3] = 0x30, .data[4] = 0x3C, .data[5] = 0x77,
1626 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
1627 { .channel = 104, .freq = 5520, .data[0] = 0x00, .data[1] = 0x00,
1628 .data[2] = 0x00, .data[3] = 0x20, .data[4] = 0x3C, .data[5] = 0x77,
1629 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
1630 { .channel = 108, .freq = 5540, .data[0] = 0x00, .data[1] = 0x00,
1631 .data[2] = 0x00, .data[3] = 0x20, .data[4] = 0x3C, .data[5] = 0x77,
1632 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
1633 { .channel = 112, .freq = 5560, .data[0] = 0x00, .data[1] = 0x00,
1634 .data[2] = 0x00, .data[3] = 0x20, .data[4] = 0x3C, .data[5] = 0x77,
1635 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
1636 { .channel = 116, .freq = 5580, .data[0] = 0x00, .data[1] = 0x00,
1637 .data[2] = 0x00, .data[3] = 0x10, .data[4] = 0x3C, .data[5] = 0x77,
1638 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
1639 { .channel = 120, .freq = 5600, .data[0] = 0x00, .data[1] = 0x00,
1640 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
1641 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
1642 { .channel = 124, .freq = 5620, .data[0] = 0x00, .data[1] = 0x00,
1643 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
1644 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
1645 { .channel = 128, .freq = 5640, .data[0] = 0x00, .data[1] = 0x00,
1646 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
1647 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
1648 { .channel = 132, .freq = 5660, .data[0] = 0x00, .data[1] = 0x00,
1649 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
1650 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
1651 { .channel = 136, .freq = 5680, .data[0] = 0x00, .data[1] = 0x00,
1652 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
1653 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
1654 { .channel = 140, .freq = 5700, .data[0] = 0x00, .data[1] = 0x00,
1655 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
1656 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
1657 { .channel = 149, .freq = 5745, .data[0] = 0x00, .data[1] = 0x00,
1658 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
1659 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
1660 { .channel = 153, .freq = 5765, .data[0] = 0x00, .data[1] = 0x00,
1661 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
1662 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
1663 { .channel = 157, .freq = 5785, .data[0] = 0x00, .data[1] = 0x00,
1664 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
1665 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
1666 { .channel = 161, .freq = 5805, .data[0] = 0x00, .data[1] = 0x00,
1667 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
1668 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
1669 { .channel = 165, .freq = 5825, .data[0] = 0x00, .data[1] = 0x00,
1670 .data[2] = 0x00, .data[3] = 0x00, .data[4] = 0x3C, .data[5] = 0x77,
1671 .data[6] = 0x37, .data[7] = 0xFF, .data[8] = 0x88, },
1672 { .channel = 184, .freq = 4920, .data[0] = 0x55, .data[1] = 0x77,
1673 .data[2] = 0x90, .data[3] = 0xF7, .data[4] = 0x3C, .data[5] = 0x77,
1674 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
1675 { .channel = 188, .freq = 4940, .data[0] = 0x44, .data[1] = 0x77,
1676 .data[2] = 0x80, .data[3] = 0xE7, .data[4] = 0x3C, .data[5] = 0x77,
1677 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
1678 { .channel = 192, .freq = 4960, .data[0] = 0x44, .data[1] = 0x66,
1679 .data[2] = 0x80, .data[3] = 0xE7, .data[4] = 0x3C, .data[5] = 0x77,
1680 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
1681 { .channel = 196, .freq = 4980, .data[0] = 0x33, .data[1] = 0x66,
1682 .data[2] = 0x70, .data[3] = 0xC7, .data[4] = 0x3C, .data[5] = 0x77,
1683 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
1684 { .channel = 200, .freq = 5000, .data[0] = 0x22, .data[1] = 0x55,
1685 .data[2] = 0x60, .data[3] = 0xD7, .data[4] = 0x3C, .data[5] = 0x77,
1686 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
1687 { .channel = 204, .freq = 5020, .data[0] = 0x22, .data[1] = 0x55,
1688 .data[2] = 0x60, .data[3] = 0xC7, .data[4] = 0x3C, .data[5] = 0x77,
1689 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
1690 { .channel = 208, .freq = 5040, .data[0] = 0x22, .data[1] = 0x44,
1691 .data[2] = 0x50, .data[3] = 0xC7, .data[4] = 0x3C, .data[5] = 0x77,
1692 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0xFF, },
1693 { .channel = 212, .freq = 5060, .data[0] = 0x11, .data[1] = 0x44,
1694 .data[2] = 0x50, .data[3] = 0xA5, .data[4] = 0x3C, .data[5] = 0x77,
1695 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
1696 { .channel = 216, .freq = 5080, .data[0] = 0x00, .data[1] = 0x44,
1697 .data[2] = 0x40, .data[3] = 0xB6, .data[4] = 0x3C, .data[5] = 0x77,
1698 .data[6] = 0x35, .data[7] = 0xFF, .data[8] = 0x88, },
1699};
1700
1701static const struct b206x_channel b2063_chantbl[] = {
1702 { .channel = 1, .freq = 2412, .data[0] = 0x6F, .data[1] = 0x3C,
1703 .data[2] = 0x3C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
1704 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
1705 .data[10] = 0x80, .data[11] = 0x70, },
1706 { .channel = 2, .freq = 2417, .data[0] = 0x6F, .data[1] = 0x3C,
1707 .data[2] = 0x3C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
1708 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
1709 .data[10] = 0x80, .data[11] = 0x70, },
1710 { .channel = 3, .freq = 2422, .data[0] = 0x6F, .data[1] = 0x3C,
1711 .data[2] = 0x3C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
1712 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
1713 .data[10] = 0x80, .data[11] = 0x70, },
1714 { .channel = 4, .freq = 2427, .data[0] = 0x6F, .data[1] = 0x2C,
1715 .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
1716 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
1717 .data[10] = 0x80, .data[11] = 0x70, },
1718 { .channel = 5, .freq = 2432, .data[0] = 0x6F, .data[1] = 0x2C,
1719 .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
1720 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
1721 .data[10] = 0x80, .data[11] = 0x70, },
1722 { .channel = 6, .freq = 2437, .data[0] = 0x6F, .data[1] = 0x2C,
1723 .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
1724 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
1725 .data[10] = 0x80, .data[11] = 0x70, },
1726 { .channel = 7, .freq = 2442, .data[0] = 0x6F, .data[1] = 0x2C,
1727 .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
1728 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
1729 .data[10] = 0x80, .data[11] = 0x70, },
1730 { .channel = 8, .freq = 2447, .data[0] = 0x6F, .data[1] = 0x2C,
1731 .data[2] = 0x2C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
1732 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
1733 .data[10] = 0x80, .data[11] = 0x70, },
1734 { .channel = 9, .freq = 2452, .data[0] = 0x6F, .data[1] = 0x1C,
1735 .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
1736 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
1737 .data[10] = 0x80, .data[11] = 0x70, },
1738 { .channel = 10, .freq = 2457, .data[0] = 0x6F, .data[1] = 0x1C,
1739 .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
1740 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
1741 .data[10] = 0x80, .data[11] = 0x70, },
1742 { .channel = 11, .freq = 2462, .data[0] = 0x6E, .data[1] = 0x1C,
1743 .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
1744 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
1745 .data[10] = 0x80, .data[11] = 0x70, },
1746 { .channel = 12, .freq = 2467, .data[0] = 0x6E, .data[1] = 0x1C,
1747 .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
1748 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
1749 .data[10] = 0x80, .data[11] = 0x70, },
1750 { .channel = 13, .freq = 2472, .data[0] = 0x6E, .data[1] = 0x1C,
1751 .data[2] = 0x1C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
1752 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
1753 .data[10] = 0x80, .data[11] = 0x70, },
1754 { .channel = 14, .freq = 2484, .data[0] = 0x6E, .data[1] = 0x0C,
1755 .data[2] = 0x0C, .data[3] = 0x04, .data[4] = 0x05, .data[5] = 0x05,
1756 .data[6] = 0x05, .data[7] = 0x05, .data[8] = 0x77, .data[9] = 0x80,
1757 .data[10] = 0x80, .data[11] = 0x70, },
1758 { .channel = 34, .freq = 5170, .data[0] = 0x6A, .data[1] = 0x0C,
1759 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x02, .data[5] = 0x05,
1760 .data[6] = 0x0D, .data[7] = 0x0D, .data[8] = 0x77, .data[9] = 0x80,
1761 .data[10] = 0x20, .data[11] = 0x00, },
1762 { .channel = 36, .freq = 5180, .data[0] = 0x6A, .data[1] = 0x0C,
1763 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x01, .data[5] = 0x05,
1764 .data[6] = 0x0D, .data[7] = 0x0C, .data[8] = 0x77, .data[9] = 0x80,
1765 .data[10] = 0x20, .data[11] = 0x00, },
1766 { .channel = 38, .freq = 5190, .data[0] = 0x6A, .data[1] = 0x0C,
1767 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x01, .data[5] = 0x04,
1768 .data[6] = 0x0C, .data[7] = 0x0C, .data[8] = 0x77, .data[9] = 0x80,
1769 .data[10] = 0x20, .data[11] = 0x00, },
1770 { .channel = 40, .freq = 5200, .data[0] = 0x69, .data[1] = 0x0C,
1771 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x01, .data[5] = 0x04,
1772 .data[6] = 0x0C, .data[7] = 0x0C, .data[8] = 0x77, .data[9] = 0x70,
1773 .data[10] = 0x20, .data[11] = 0x00, },
1774 { .channel = 42, .freq = 5210, .data[0] = 0x69, .data[1] = 0x0C,
1775 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x01, .data[5] = 0x04,
1776 .data[6] = 0x0B, .data[7] = 0x0C, .data[8] = 0x77, .data[9] = 0x70,
1777 .data[10] = 0x20, .data[11] = 0x00, },
1778 { .channel = 44, .freq = 5220, .data[0] = 0x69, .data[1] = 0x0C,
1779 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x04,
1780 .data[6] = 0x0B, .data[7] = 0x0B, .data[8] = 0x77, .data[9] = 0x60,
1781 .data[10] = 0x20, .data[11] = 0x00, },
1782 { .channel = 46, .freq = 5230, .data[0] = 0x69, .data[1] = 0x0C,
1783 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x03,
1784 .data[6] = 0x0A, .data[7] = 0x0B, .data[8] = 0x77, .data[9] = 0x60,
1785 .data[10] = 0x20, .data[11] = 0x00, },
1786 { .channel = 48, .freq = 5240, .data[0] = 0x69, .data[1] = 0x0C,
1787 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x03,
1788 .data[6] = 0x0A, .data[7] = 0x0A, .data[8] = 0x77, .data[9] = 0x60,
1789 .data[10] = 0x20, .data[11] = 0x00, },
1790 { .channel = 52, .freq = 5260, .data[0] = 0x68, .data[1] = 0x0C,
1791 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x02,
1792 .data[6] = 0x09, .data[7] = 0x09, .data[8] = 0x77, .data[9] = 0x60,
1793 .data[10] = 0x20, .data[11] = 0x00, },
1794 { .channel = 56, .freq = 5280, .data[0] = 0x68, .data[1] = 0x0C,
1795 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x01,
1796 .data[6] = 0x08, .data[7] = 0x08, .data[8] = 0x77, .data[9] = 0x50,
1797 .data[10] = 0x10, .data[11] = 0x00, },
1798 { .channel = 60, .freq = 5300, .data[0] = 0x68, .data[1] = 0x0C,
1799 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x01,
1800 .data[6] = 0x08, .data[7] = 0x08, .data[8] = 0x77, .data[9] = 0x50,
1801 .data[10] = 0x10, .data[11] = 0x00, },
1802 { .channel = 64, .freq = 5320, .data[0] = 0x67, .data[1] = 0x0C,
1803 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1804 .data[6] = 0x08, .data[7] = 0x08, .data[8] = 0x77, .data[9] = 0x50,
1805 .data[10] = 0x10, .data[11] = 0x00, },
1806 { .channel = 100, .freq = 5500, .data[0] = 0x64, .data[1] = 0x0C,
1807 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1808 .data[6] = 0x02, .data[7] = 0x01, .data[8] = 0x77, .data[9] = 0x20,
1809 .data[10] = 0x00, .data[11] = 0x00, },
1810 { .channel = 104, .freq = 5520, .data[0] = 0x64, .data[1] = 0x0C,
1811 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1812 .data[6] = 0x01, .data[7] = 0x01, .data[8] = 0x77, .data[9] = 0x20,
1813 .data[10] = 0x00, .data[11] = 0x00, },
1814 { .channel = 108, .freq = 5540, .data[0] = 0x63, .data[1] = 0x0C,
1815 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1816 .data[6] = 0x01, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x10,
1817 .data[10] = 0x00, .data[11] = 0x00, },
1818 { .channel = 112, .freq = 5560, .data[0] = 0x63, .data[1] = 0x0C,
1819 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1820 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x10,
1821 .data[10] = 0x00, .data[11] = 0x00, },
1822 { .channel = 116, .freq = 5580, .data[0] = 0x62, .data[1] = 0x0C,
1823 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1824 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x10,
1825 .data[10] = 0x00, .data[11] = 0x00, },
1826 { .channel = 120, .freq = 5600, .data[0] = 0x62, .data[1] = 0x0C,
1827 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1828 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
1829 .data[10] = 0x00, .data[11] = 0x00, },
1830 { .channel = 124, .freq = 5620, .data[0] = 0x62, .data[1] = 0x0C,
1831 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1832 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
1833 .data[10] = 0x00, .data[11] = 0x00, },
1834 { .channel = 128, .freq = 5640, .data[0] = 0x61, .data[1] = 0x0C,
1835 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1836 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
1837 .data[10] = 0x00, .data[11] = 0x00, },
1838 { .channel = 132, .freq = 5660, .data[0] = 0x61, .data[1] = 0x0C,
1839 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1840 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
1841 .data[10] = 0x00, .data[11] = 0x00, },
1842 { .channel = 136, .freq = 5680, .data[0] = 0x61, .data[1] = 0x0C,
1843 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1844 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
1845 .data[10] = 0x00, .data[11] = 0x00, },
1846 { .channel = 140, .freq = 5700, .data[0] = 0x60, .data[1] = 0x0C,
1847 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1848 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
1849 .data[10] = 0x00, .data[11] = 0x00, },
1850 { .channel = 149, .freq = 5745, .data[0] = 0x60, .data[1] = 0x0C,
1851 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1852 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
1853 .data[10] = 0x00, .data[11] = 0x00, },
1854 { .channel = 153, .freq = 5765, .data[0] = 0x60, .data[1] = 0x0C,
1855 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1856 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
1857 .data[10] = 0x00, .data[11] = 0x00, },
1858 { .channel = 157, .freq = 5785, .data[0] = 0x60, .data[1] = 0x0C,
1859 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1860 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
1861 .data[10] = 0x00, .data[11] = 0x00, },
1862 { .channel = 161, .freq = 5805, .data[0] = 0x60, .data[1] = 0x0C,
1863 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1864 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
1865 .data[10] = 0x00, .data[11] = 0x00, },
1866 { .channel = 165, .freq = 5825, .data[0] = 0x60, .data[1] = 0x0C,
1867 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x00, .data[5] = 0x00,
1868 .data[6] = 0x00, .data[7] = 0x00, .data[8] = 0x77, .data[9] = 0x00,
1869 .data[10] = 0x00, .data[11] = 0x00, },
1870 { .channel = 184, .freq = 4920, .data[0] = 0x6E, .data[1] = 0x0C,
1871 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x09, .data[5] = 0x0E,
1872 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xC0,
1873 .data[10] = 0x50, .data[11] = 0x00, },
1874 { .channel = 188, .freq = 4940, .data[0] = 0x6E, .data[1] = 0x0C,
1875 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x09, .data[5] = 0x0D,
1876 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xB0,
1877 .data[10] = 0x50, .data[11] = 0x00, },
1878 { .channel = 192, .freq = 4960, .data[0] = 0x6E, .data[1] = 0x0C,
1879 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x08, .data[5] = 0x0C,
1880 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xB0,
1881 .data[10] = 0x50, .data[11] = 0x00, },
1882 { .channel = 196, .freq = 4980, .data[0] = 0x6D, .data[1] = 0x0C,
1883 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x08, .data[5] = 0x0C,
1884 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xA0,
1885 .data[10] = 0x40, .data[11] = 0x00, },
1886 { .channel = 200, .freq = 5000, .data[0] = 0x6D, .data[1] = 0x0C,
1887 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x08, .data[5] = 0x0B,
1888 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xA0,
1889 .data[10] = 0x40, .data[11] = 0x00, },
1890 { .channel = 204, .freq = 5020, .data[0] = 0x6D, .data[1] = 0x0C,
1891 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x08, .data[5] = 0x0A,
1892 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0xA0,
1893 .data[10] = 0x40, .data[11] = 0x00, },
1894 { .channel = 208, .freq = 5040, .data[0] = 0x6C, .data[1] = 0x0C,
1895 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x07, .data[5] = 0x09,
1896 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0x90,
1897 .data[10] = 0x40, .data[11] = 0x00, },
1898 { .channel = 212, .freq = 5060, .data[0] = 0x6C, .data[1] = 0x0C,
1899 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x06, .data[5] = 0x08,
1900 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0x90,
1901 .data[10] = 0x40, .data[11] = 0x00, },
1902 { .channel = 216, .freq = 5080, .data[0] = 0x6C, .data[1] = 0x0C,
1903 .data[2] = 0x0C, .data[3] = 0x00, .data[4] = 0x05, .data[5] = 0x08,
1904 .data[6] = 0x0F, .data[7] = 0x0F, .data[8] = 0x77, .data[9] = 0x90,
1905 .data[10] = 0x40, .data[11] = 0x00, },
1906};
1907
1908static void lpphy_b2062_reset_pll_bias(struct b43_wldev *dev)
1909{
1910 struct ssb_bus *bus = dev->dev->bus;
1911
1912 b43_radio_write(dev, B2062_S_RFPLL_CTL2, 0xFF);
1913 udelay(20);
1914 if (bus->chip_id == 0x5354) {
1915 b43_radio_write(dev, B2062_N_COMM1, 4);
1916 b43_radio_write(dev, B2062_S_RFPLL_CTL2, 4);
1917 } else {
1918 b43_radio_write(dev, B2062_S_RFPLL_CTL2, 0);
1919 }
1920 udelay(5);
1921}
1922
1923static void lpphy_b2062_vco_calib(struct b43_wldev *dev)
1924{
1925 b43_phy_write(dev, B2062_S_RFPLL_CTL21, 0x42);
1926 b43_phy_write(dev, B2062_S_RFPLL_CTL21, 0x62);
1927 udelay(200);
1928}
1929
1930static int lpphy_b2062_tune(struct b43_wldev *dev,
1931 unsigned int channel)
1932{
1933 struct b43_phy_lp *lpphy = dev->phy.lp;
1934 struct ssb_bus *bus = dev->dev->bus;
1935 const struct b206x_channel *chandata = NULL;
1936 u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
1937 u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9;
1938 int i, err = 0;
1939
1940 for (i = 0; i < ARRAY_SIZE(b2062_chantbl); i++) {
1941 if (b2062_chantbl[i].channel == channel) {
1942 chandata = &b2062_chantbl[i];
1943 break;
1944 }
1945 }
1946
1947 if (B43_WARN_ON(!chandata))
1948 return -EINVAL;
1949
1950 b43_radio_set(dev, B2062_S_RFPLL_CTL14, 0x04);
1951 b43_radio_write(dev, B2062_N_LGENA_TUNE0, chandata->data[0]);
1952 b43_radio_write(dev, B2062_N_LGENA_TUNE2, chandata->data[1]);
1953 b43_radio_write(dev, B2062_N_LGENA_TUNE3, chandata->data[2]);
1954 b43_radio_write(dev, B2062_N_TX_TUNE, chandata->data[3]);
1955 b43_radio_write(dev, B2062_S_LGENG_CTL1, chandata->data[4]);
1956 b43_radio_write(dev, B2062_N_LGENA_CTL5, chandata->data[5]);
1957 b43_radio_write(dev, B2062_N_LGENA_CTL6, chandata->data[6]);
1958 b43_radio_write(dev, B2062_N_TX_PGA, chandata->data[7]);
1959 b43_radio_write(dev, B2062_N_TX_PAD, chandata->data[8]);
1960
1961 tmp1 = crystal_freq / 1000;
1962 tmp2 = lpphy->pdiv * 1000;
1963 b43_radio_write(dev, B2062_S_RFPLL_CTL33, 0xCC);
1964 b43_radio_write(dev, B2062_S_RFPLL_CTL34, 0x07);
1965 lpphy_b2062_reset_pll_bias(dev);
1966 tmp3 = tmp2 * channel2freq_lp(channel);
1967 if (channel2freq_lp(channel) < 4000)
1968 tmp3 *= 2;
1969 tmp4 = 48 * tmp1;
1970 tmp6 = tmp3 / tmp4;
1971 tmp7 = tmp3 % tmp4;
1972 b43_radio_write(dev, B2062_S_RFPLL_CTL26, tmp6);
1973 tmp5 = tmp7 * 0x100;
1974 tmp6 = tmp5 / tmp4;
1975 tmp7 = tmp5 % tmp4;
1976 b43_radio_write(dev, B2062_S_RFPLL_CTL27, tmp6);
1977 tmp5 = tmp7 * 0x100;
1978 tmp6 = tmp5 / tmp4;
1979 tmp7 = tmp5 % tmp4;
1980 b43_radio_write(dev, B2062_S_RFPLL_CTL28, tmp6);
1981 tmp5 = tmp7 * 0x100;
1982 tmp6 = tmp5 / tmp4;
1983 tmp7 = tmp5 % tmp4;
1984 b43_radio_write(dev, B2062_S_RFPLL_CTL29, tmp6 + ((2 * tmp7) / tmp4));
1985 tmp8 = b43_phy_read(dev, B2062_S_RFPLL_CTL19);
1986 tmp9 = ((2 * tmp3 * (tmp8 + 1)) + (3 * tmp1)) / (6 * tmp1);
1987 b43_radio_write(dev, B2062_S_RFPLL_CTL23, (tmp9 >> 8) + 16);
1988 b43_radio_write(dev, B2062_S_RFPLL_CTL24, tmp9 & 0xFF);
1989
1990 lpphy_b2062_vco_calib(dev);
1991 if (b43_radio_read(dev, B2062_S_RFPLL_CTL3) & 0x10) {
1992 b43_radio_write(dev, B2062_S_RFPLL_CTL33, 0xFC);
1993 b43_radio_write(dev, B2062_S_RFPLL_CTL34, 0);
1994 lpphy_b2062_reset_pll_bias(dev);
1995 lpphy_b2062_vco_calib(dev);
1996 if (b43_radio_read(dev, B2062_S_RFPLL_CTL3) & 0x10)
1997 err = -EIO;
1998 }
1999
2000 b43_radio_mask(dev, B2062_S_RFPLL_CTL14, ~0x04);
2001 return err;
2002}
2003
2004
2005/* This was previously called lpphy_japan_filter */
2006static void lpphy_set_analog_filter(struct b43_wldev *dev, int channel)
2007{
2008 struct b43_phy_lp *lpphy = dev->phy.lp;
2009 u16 tmp = (channel == 14); //SPEC FIXME check japanwidefilter!
2010
2011 if (dev->phy.rev < 2) { //SPEC FIXME Isn't this rev0/1-specific?
2012 b43_phy_maskset(dev, B43_LPPHY_LP_PHY_CTL, 0xFCFF, tmp << 9);
2013 if ((dev->phy.rev == 1) && (lpphy->rc_cap))
2014 lpphy_set_rc_cap(dev);
2015 } else {
2016 b43_radio_write(dev, B2063_TX_BB_SP3, 0x3F);
2017 }
2018}
2019
2020static void lpphy_b2063_vco_calib(struct b43_wldev *dev)
2021{
2022 u16 tmp;
2023
2024 b43_phy_mask(dev, B2063_PLL_SP1, ~0x40);
2025 tmp = b43_phy_read(dev, B2063_PLL_JTAG_CALNRST) & 0xF8;
2026 b43_phy_write(dev, B2063_PLL_JTAG_CALNRST, tmp);
2027 udelay(1);
2028 b43_phy_write(dev, B2063_PLL_JTAG_CALNRST, tmp | 0x4);
2029 udelay(1);
2030 b43_phy_write(dev, B2063_PLL_JTAG_CALNRST, tmp | 0x6);
2031 udelay(1);
2032 b43_phy_write(dev, B2063_PLL_JTAG_CALNRST, tmp | 0x7);
2033 udelay(300);
2034 b43_phy_set(dev, B2063_PLL_SP1, 0x40);
2035}
2036
2037static int lpphy_b2063_tune(struct b43_wldev *dev,
2038 unsigned int channel)
2039{
2040 struct ssb_bus *bus = dev->dev->bus;
2041
2042 static const struct b206x_channel *chandata = NULL;
2043 u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
2044 u32 freqref, vco_freq, val1, val2, val3, timeout, timeoutref, count;
2045 u16 old_comm15, scale;
2046 u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
2047 int i, div = (crystal_freq <= 26000000 ? 1 : 2);
2048
2049 for (i = 0; i < ARRAY_SIZE(b2063_chantbl); i++) {
2050 if (b2063_chantbl[i].channel == channel) {
2051 chandata = &b2063_chantbl[i];
2052 break;
2053 }
2054 }
2055
2056 if (B43_WARN_ON(!chandata))
2057 return -EINVAL;
2058
2059 b43_radio_write(dev, B2063_LOGEN_VCOBUF1, chandata->data[0]);
2060 b43_radio_write(dev, B2063_LOGEN_MIXER2, chandata->data[1]);
2061 b43_radio_write(dev, B2063_LOGEN_BUF2, chandata->data[2]);
2062 b43_radio_write(dev, B2063_LOGEN_RCCR1, chandata->data[3]);
2063 b43_radio_write(dev, B2063_A_RX_1ST3, chandata->data[4]);
2064 b43_radio_write(dev, B2063_A_RX_2ND1, chandata->data[5]);
2065 b43_radio_write(dev, B2063_A_RX_2ND4, chandata->data[6]);
2066 b43_radio_write(dev, B2063_A_RX_2ND7, chandata->data[7]);
2067 b43_radio_write(dev, B2063_A_RX_PS6, chandata->data[8]);
2068 b43_radio_write(dev, B2063_TX_RF_CTL2, chandata->data[9]);
2069 b43_radio_write(dev, B2063_TX_RF_CTL5, chandata->data[10]);
2070 b43_radio_write(dev, B2063_PA_CTL11, chandata->data[11]);
2071
2072 old_comm15 = b43_radio_read(dev, B2063_COMM15);
2073 b43_radio_set(dev, B2063_COMM15, 0x1E);
2074
2075 if (chandata->freq > 4000) /* spec says 2484, but 4000 is safer */
2076 vco_freq = chandata->freq << 1;
2077 else
2078 vco_freq = chandata->freq << 2;
2079
2080 freqref = crystal_freq * 3;
2081 val1 = lpphy_qdiv_roundup(crystal_freq, 1000000, 16);
2082 val2 = lpphy_qdiv_roundup(crystal_freq, 1000000 * div, 16);
2083 val3 = lpphy_qdiv_roundup(vco_freq, 3, 16);
2084 timeout = ((((8 * crystal_freq) / (div * 5000000)) + 1) >> 1) - 1;
2085 b43_radio_write(dev, B2063_PLL_JTAG_PLL_VCO_CALIB3, 0x2);
2086 b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_VCO_CALIB6,
2087 0xFFF8, timeout >> 2);
2088 b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_VCO_CALIB7,
2089 0xFF9F,timeout << 5);
2090
2091 timeoutref = ((((8 * crystal_freq) / (div * (timeout + 1))) +
2092 999999) / 1000000) + 1;
2093 b43_radio_write(dev, B2063_PLL_JTAG_PLL_VCO_CALIB5, timeoutref);
2094
2095 count = lpphy_qdiv_roundup(val3, val2 + 16, 16);
2096 count *= (timeout + 1) * (timeoutref + 1);
2097 count--;
2098 b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_VCO_CALIB7,
2099 0xF0, count >> 8);
2100 b43_radio_write(dev, B2063_PLL_JTAG_PLL_VCO_CALIB8, count & 0xFF);
2101
2102 tmp1 = ((val3 * 62500) / freqref) << 4;
2103 tmp2 = ((val3 * 62500) % freqref) << 4;
2104 while (tmp2 >= freqref) {
2105 tmp1++;
2106 tmp2 -= freqref;
2107 }
2108 b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_SG1, 0xFFE0, tmp1 >> 4);
2109 b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_SG2, 0xFE0F, tmp1 << 4);
2110 b43_radio_maskset(dev, B2063_PLL_JTAG_PLL_SG2, 0xFFF0, tmp1 >> 16);
2111 b43_radio_write(dev, B2063_PLL_JTAG_PLL_SG3, (tmp2 >> 8) & 0xFF);
2112 b43_radio_write(dev, B2063_PLL_JTAG_PLL_SG4, tmp2 & 0xFF);
2113
2114 b43_radio_write(dev, B2063_PLL_JTAG_PLL_LF1, 0xB9);
2115 b43_radio_write(dev, B2063_PLL_JTAG_PLL_LF2, 0x88);
2116 b43_radio_write(dev, B2063_PLL_JTAG_PLL_LF3, 0x28);
2117 b43_radio_write(dev, B2063_PLL_JTAG_PLL_LF4, 0x63);
2118
2119 tmp3 = ((41 * (val3 - 3000)) /1200) + 27;
2120 tmp4 = lpphy_qdiv_roundup(132000 * tmp1, 8451, 16);
2121
2122 if ((tmp4 + tmp3 - 1) / tmp3 > 60) {
2123 scale = 1;
2124 tmp5 = ((tmp4 + tmp3) / (tmp3 << 1)) - 8;
2125 } else {
2126 scale = 0;
2127 tmp5 = ((tmp4 + (tmp3 >> 1)) / tmp3) - 8;
2128 }
2129 b43_phy_maskset(dev, B2063_PLL_JTAG_PLL_CP2, 0xFFC0, tmp5);
2130 b43_phy_maskset(dev, B2063_PLL_JTAG_PLL_CP2, 0xFFBF, scale << 6);
2131
2132 tmp6 = lpphy_qdiv_roundup(100 * val1, val3, 16);
2133 tmp6 *= (tmp5 * 8) * (scale + 1);
2134 if (tmp6 > 150)
2135 tmp6 = 0;
2136
2137 b43_phy_maskset(dev, B2063_PLL_JTAG_PLL_CP3, 0xFFE0, tmp6);
2138 b43_phy_maskset(dev, B2063_PLL_JTAG_PLL_CP3, 0xFFDF, scale << 5);
2139
2140 b43_phy_maskset(dev, B2063_PLL_JTAG_PLL_XTAL_12, 0xFFFB, 0x4);
2141 if (crystal_freq > 26000000)
2142 b43_phy_set(dev, B2063_PLL_JTAG_PLL_XTAL_12, 0x2);
2143 else
2144 b43_phy_mask(dev, B2063_PLL_JTAG_PLL_XTAL_12, 0xFD);
2145
2146 if (val1 == 45)
2147 b43_phy_set(dev, B2063_PLL_JTAG_PLL_VCO1, 0x2);
2148 else
2149 b43_phy_mask(dev, B2063_PLL_JTAG_PLL_VCO1, 0xFD);
2150
2151 b43_phy_set(dev, B2063_PLL_SP2, 0x3);
2152 udelay(1);
2153 b43_phy_mask(dev, B2063_PLL_SP2, 0xFFFC);
2154 lpphy_b2063_vco_calib(dev);
2155 b43_radio_write(dev, B2063_COMM15, old_comm15);
2156
2157 return 0;
2158}
2159
1331static int b43_lpphy_op_switch_channel(struct b43_wldev *dev, 2160static int b43_lpphy_op_switch_channel(struct b43_wldev *dev,
1332 unsigned int new_channel) 2161 unsigned int new_channel)
1333{ 2162{
1334 //TODO 2163 int err;
2164
2165 b43_write16(dev, B43_MMIO_CHANNEL, new_channel);
2166
2167 if (dev->phy.radio_ver == 0x2063) {
2168 err = lpphy_b2063_tune(dev, new_channel);
2169 if (err)
2170 return err;
2171 } else {
2172 err = lpphy_b2062_tune(dev, new_channel);
2173 if (err)
2174 return err;
2175 lpphy_set_analog_filter(dev, new_channel);
2176 lpphy_adjust_gain_table(dev, channel2freq_lp(new_channel));
2177 }
2178
1335 return 0; 2179 return 0;
1336} 2180}
1337 2181
1338static unsigned int b43_lpphy_op_get_default_chan(struct b43_wldev *dev) 2182static int b43_lpphy_op_init(struct b43_wldev *dev)
1339{ 2183{
1340 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) 2184 int err;
1341 return 1; 2185
1342 return 36; 2186 lpphy_read_band_sprom(dev); //FIXME should this be in prepare_structs?
2187 lpphy_baseband_init(dev);
2188 lpphy_radio_init(dev);
2189 lpphy_calibrate_rc(dev);
2190 err = b43_lpphy_op_switch_channel(dev,
2191 b43_lpphy_op_get_default_chan(dev));
2192 if (err) {
2193 b43dbg(dev->wl, "Switch to init channel failed, error = %d.\n",
2194 err);
2195 }
2196 lpphy_tx_pctl_init(dev);
2197 lpphy_calibration(dev);
2198 //TODO ACI init
2199
2200 return 0;
1343} 2201}
1344 2202
1345static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna) 2203static void b43_lpphy_op_set_rx_antenna(struct b43_wldev *dev, int antenna)
diff --git a/drivers/net/wireless/b43/phy_lp.h b/drivers/net/wireless/b43/phy_lp.h
index 0461d5b3144f..e158d1f66c0e 100644
--- a/drivers/net/wireless/b43/phy_lp.h
+++ b/drivers/net/wireless/b43/phy_lp.h
@@ -825,11 +825,11 @@ struct b43_phy_lp {
825 enum b43_lpphy_txpctl_mode txpctl_mode; 825 enum b43_lpphy_txpctl_mode txpctl_mode;
826 826
827 /* Transmit isolation medium band */ 827 /* Transmit isolation medium band */
828 u8 tx_isolation_med_band; /* FIXME initial value? */ 828 u8 tx_isolation_med_band;
829 /* Transmit isolation low band */ 829 /* Transmit isolation low band */
830 u8 tx_isolation_low_band; /* FIXME initial value? */ 830 u8 tx_isolation_low_band;
831 /* Transmit isolation high band */ 831 /* Transmit isolation high band */
832 u8 tx_isolation_hi_band; /* FIXME initial value? */ 832 u8 tx_isolation_hi_band;
833 833
834 /* Max transmit power medium band */ 834 /* Max transmit power medium band */
835 u16 max_tx_pwr_med_band; 835 u16 max_tx_pwr_med_band;
@@ -848,7 +848,7 @@ struct b43_phy_lp {
848 s16 txpa[3], txpal[3], txpah[3]; 848 s16 txpa[3], txpal[3], txpah[3];
849 849
850 /* Receive power offset */ 850 /* Receive power offset */
851 u8 rx_pwr_offset; /* FIXME initial value? */ 851 u8 rx_pwr_offset;
852 852
853 /* TSSI transmit count */ 853 /* TSSI transmit count */
854 u16 tssi_tx_count; 854 u16 tssi_tx_count;
@@ -864,16 +864,16 @@ struct b43_phy_lp {
864 s8 tx_pwr_idx_over; /* FIXME initial value? */ 864 s8 tx_pwr_idx_over; /* FIXME initial value? */
865 865
866 /* RSSI vf */ 866 /* RSSI vf */
867 u8 rssi_vf; /* FIXME initial value? */ 867 u8 rssi_vf;
868 /* RSSI vc */ 868 /* RSSI vc */
869 u8 rssi_vc; /* FIXME initial value? */ 869 u8 rssi_vc;
870 /* RSSI gs */ 870 /* RSSI gs */
871 u8 rssi_gs; /* FIXME initial value? */ 871 u8 rssi_gs;
872 872
873 /* RC cap */ 873 /* RC cap */
874 u8 rc_cap; /* FIXME initial value? */ 874 u8 rc_cap; /* FIXME initial value? */
875 /* BX arch */ 875 /* BX arch */
876 u8 bx_arch; /* FIXME initial value? */ 876 u8 bx_arch;
877 877
878 /* Full calibration channel */ 878 /* Full calibration channel */
879 u8 full_calib_chan; /* FIXME initial value? */ 879 u8 full_calib_chan; /* FIXME initial value? */
@@ -884,8 +884,17 @@ struct b43_phy_lp {
884 884
885 /* Used for "Save/Restore Dig Filt State" */ 885 /* Used for "Save/Restore Dig Filt State" */
886 u16 dig_flt_state[9]; 886 u16 dig_flt_state[9];
887
888 bool crs_usr_disable, crs_sys_disable;
889
890 unsigned int pdiv;
887}; 891};
888 892
893enum tssi_mux_mode {
894 TSSI_MUX_PREPA,
895 TSSI_MUX_POSTPA,
896 TSSI_MUX_EXT,
897};
889 898
890struct b43_phy_operations; 899struct b43_phy_operations;
891extern const struct b43_phy_operations b43_phyops_lp; 900extern const struct b43_phy_operations b43_phyops_lp;
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 73c047d8de40..3fd653c78b10 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -461,8 +461,8 @@ static int pio_tx_frame(struct b43_pio_txqueue *q,
461 461
462 cookie = generate_cookie(q, pack); 462 cookie = generate_cookie(q, pack);
463 hdrlen = b43_txhdr_size(q->dev); 463 hdrlen = b43_txhdr_size(q->dev);
464 err = b43_generate_txhdr(q->dev, (u8 *)&txhdr, skb->data, 464 err = b43_generate_txhdr(q->dev, (u8 *)&txhdr, skb,
465 skb->len, info, cookie); 465 info, cookie);
466 if (err) 466 if (err)
467 return err; 467 return err;
468 468
diff --git a/drivers/net/wireless/b43/tables_lpphy.c b/drivers/net/wireless/b43/tables_lpphy.c
index 2721310acb2a..60d472f285af 100644
--- a/drivers/net/wireless/b43/tables_lpphy.c
+++ b/drivers/net/wireless/b43/tables_lpphy.c
@@ -2367,7 +2367,17 @@ static void lpphy_rev2plus_write_gain_table(struct b43_wldev *dev, int offset,
2367 tmp = data.pad << 16; 2367 tmp = data.pad << 16;
2368 tmp |= data.pga << 8; 2368 tmp |= data.pga << 8;
2369 tmp |= data.gm; 2369 tmp |= data.gm;
2370 tmp |= 0x7f000000; 2370 if (dev->phy.rev >= 3) {
2371 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
2372 tmp |= 0x10 << 24;
2373 else
2374 tmp |= 0x70 << 24;
2375 } else {
2376 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
2377 tmp |= 0x14 << 24;
2378 else
2379 tmp |= 0x7F << 24;
2380 }
2371 b43_lptab_write(dev, B43_LPTAB32(7, 0xC0 + offset), tmp); 2381 b43_lptab_write(dev, B43_LPTAB32(7, 0xC0 + offset), tmp);
2372 tmp = data.bb_mult << 20; 2382 tmp = data.bb_mult << 20;
2373 tmp |= data.dac << 28; 2383 tmp |= data.dac << 28;
diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c
index e1e20f69f6d7..97c79161c208 100644
--- a/drivers/net/wireless/b43/wa.c
+++ b/drivers/net/wireless/b43/wa.c
@@ -37,7 +37,7 @@ static void b43_wa_papd(struct b43_wldev *dev)
37 backup = b43_ofdmtab_read16(dev, B43_OFDMTAB_PWRDYN2, 0); 37 backup = b43_ofdmtab_read16(dev, B43_OFDMTAB_PWRDYN2, 0);
38 b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, 7); 38 b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, 7);
39 b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 0, 0); 39 b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 0, 0);
40 b43_dummy_transmission(dev); 40 b43_dummy_transmission(dev, true, true);
41 b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, backup); 41 b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, backup);
42} 42}
43 43
@@ -628,7 +628,7 @@ void b43_wa_all(struct b43_wldev *dev)
628 B43_WARN_ON(1); 628 B43_WARN_ON(1);
629 } 629 }
630 b43_wa_boards_g(dev); 630 b43_wa_boards_g(dev);
631 } else { /* No N PHY support so far */ 631 } else { /* No N PHY support so far, LP PHY is in phy_lp.c */
632 B43_WARN_ON(1); 632 B43_WARN_ON(1);
633 } 633 }
634 634
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 5280ebc8c6e9..e7075d2c7757 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -180,11 +180,12 @@ static u8 b43_calc_fallback_rate(u8 bitrate)
180/* Generate a TX data header. */ 180/* Generate a TX data header. */
181int b43_generate_txhdr(struct b43_wldev *dev, 181int b43_generate_txhdr(struct b43_wldev *dev,
182 u8 *_txhdr, 182 u8 *_txhdr,
183 const unsigned char *fragment_data, 183 struct sk_buff *skb_frag,
184 unsigned int fragment_len,
185 struct ieee80211_tx_info *info, 184 struct ieee80211_tx_info *info,
186 u16 cookie) 185 u16 cookie)
187{ 186{
187 const unsigned char *fragment_data = skb_frag->data;
188 unsigned int fragment_len = skb_frag->len;
188 struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr; 189 struct b43_txhdr *txhdr = (struct b43_txhdr *)_txhdr;
189 const struct b43_phy *phy = &dev->phy; 190 const struct b43_phy *phy = &dev->phy;
190 const struct ieee80211_hdr *wlhdr = 191 const struct ieee80211_hdr *wlhdr =
@@ -258,9 +259,26 @@ int b43_generate_txhdr(struct b43_wldev *dev,
258 mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) & 259 mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
259 B43_TXH_MAC_KEYALG; 260 B43_TXH_MAC_KEYALG;
260 wlhdr_len = ieee80211_hdrlen(fctl); 261 wlhdr_len = ieee80211_hdrlen(fctl);
261 iv_len = min((size_t) info->control.hw_key->iv_len, 262 if (key->algorithm == B43_SEC_ALGO_TKIP) {
262 ARRAY_SIZE(txhdr->iv)); 263 u16 phase1key[5];
263 memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len); 264 int i;
265 /* we give the phase1key and iv16 here, the key is stored in
266 * shm. With that the hardware can do phase 2 and encryption.
267 */
268 ieee80211_get_tkip_key(info->control.hw_key, skb_frag,
269 IEEE80211_TKIP_P1_KEY, (u8*)phase1key);
270 /* phase1key is in host endian */
271 for (i = 0; i < 5; i++)
272 phase1key[i] = cpu_to_le16(phase1key[i]);
273
274 memcpy(txhdr->iv, phase1key, 10);
275 /* iv16 */
276 memcpy(txhdr->iv + 10, ((u8 *) wlhdr) + wlhdr_len, 3);
277 } else {
278 iv_len = min((size_t) info->control.hw_key->iv_len,
279 ARRAY_SIZE(txhdr->iv));
280 memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
281 }
264 } 282 }
265 if (b43_is_old_txhdr_format(dev)) { 283 if (b43_is_old_txhdr_format(dev)) {
266 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->old_format.plcp), 284 b43_generate_plcp_hdr((struct b43_plcp_hdr4 *)(&txhdr->old_format.plcp),
@@ -655,6 +673,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
655 status.freq = chanid + 2400; 673 status.freq = chanid + 2400;
656 break; 674 break;
657 case B43_PHYTYPE_N: 675 case B43_PHYTYPE_N:
676 case B43_PHYTYPE_LP:
658 /* chanid is the SHM channel cookie. Which is the plain 677 /* chanid is the SHM channel cookie. Which is the plain
659 * channel number in b43. */ 678 * channel number in b43. */
660 if (chanstat & B43_RX_CHAN_5GHZ) { 679 if (chanstat & B43_RX_CHAN_5GHZ) {
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index 4fb2a190f7a7..3530de871873 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -176,8 +176,7 @@ size_t b43_txhdr_size(struct b43_wldev *dev)
176 176
177int b43_generate_txhdr(struct b43_wldev *dev, 177int b43_generate_txhdr(struct b43_wldev *dev,
178 u8 * txhdr, 178 u8 * txhdr,
179 const unsigned char *fragment_data, 179 struct sk_buff *skb_frag,
180 unsigned int fragment_len,
181 struct ieee80211_tx_info *txctl, u16 cookie); 180 struct ieee80211_tx_info *txctl, u16 cookie);
182 181
183/* Transmit Status */ 182/* Transmit Status */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index b1435594921a..b166a6f9f055 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2836,9 +2836,7 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
2836 2836
2837static void b43legacy_op_configure_filter(struct ieee80211_hw *hw, 2837static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
2838 unsigned int changed, 2838 unsigned int changed,
2839 unsigned int *fflags, 2839 unsigned int *fflags,u64 multicast)
2840 int mc_count,
2841 struct dev_addr_list *mc_list)
2842{ 2840{
2843 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); 2841 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
2844 struct b43legacy_wldev *dev = wl->current_dev; 2842 struct b43legacy_wldev *dev = wl->current_dev;
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 742432388ca3..dee50ed0897d 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -185,7 +185,7 @@ MODULE_AUTHOR(DRV_COPYRIGHT);
185MODULE_LICENSE("GPL"); 185MODULE_LICENSE("GPL");
186 186
187static int debug = 0; 187static int debug = 0;
188static int mode = 0; 188static int network_mode = 0;
189static int channel = 0; 189static int channel = 0;
190static int associate = 0; 190static int associate = 0;
191static int disable = 0; 191static int disable = 0;
@@ -195,7 +195,7 @@ static struct ipw2100_fw ipw2100_firmware;
195 195
196#include <linux/moduleparam.h> 196#include <linux/moduleparam.h>
197module_param(debug, int, 0444); 197module_param(debug, int, 0444);
198module_param(mode, int, 0444); 198module_param_named(mode, network_mode, int, 0444);
199module_param(channel, int, 0444); 199module_param(channel, int, 0444);
200module_param(associate, int, 0444); 200module_param(associate, int, 0444);
201module_param(disable, int, 0444); 201module_param(disable, int, 0444);
@@ -2844,7 +2844,7 @@ static int __ipw2100_tx_process(struct ipw2100_priv *priv)
2844 2844
2845#ifdef CONFIG_IPW2100_DEBUG 2845#ifdef CONFIG_IPW2100_DEBUG
2846 { 2846 {
2847 int i = txq->oldest; 2847 i = txq->oldest;
2848 IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i, 2848 IPW_DEBUG_TX("TX%d V=%p P=%04X T=%04X L=%d\n", i,
2849 &txq->drv[i], 2849 &txq->drv[i],
2850 (u32) (txq->nic + i * sizeof(struct ipw2100_bd)), 2850 (u32) (txq->nic + i * sizeof(struct ipw2100_bd)),
@@ -6076,7 +6076,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
6076 priv->ieee->ieee802_1x = 1; 6076 priv->ieee->ieee802_1x = 1;
6077 6077
6078 /* Set module parameters */ 6078 /* Set module parameters */
6079 switch (mode) { 6079 switch (network_mode) {
6080 case 1: 6080 case 1:
6081 priv->ieee->iw_mode = IW_MODE_ADHOC; 6081 priv->ieee->iw_mode = IW_MODE_ADHOC;
6082 break; 6082 break;
@@ -8179,10 +8179,11 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
8179 int rssi_qual; 8179 int rssi_qual;
8180 int tx_qual; 8180 int tx_qual;
8181 int beacon_qual; 8181 int beacon_qual;
8182 int quality;
8182 8183
8183 struct ipw2100_priv *priv = ieee80211_priv(dev); 8184 struct ipw2100_priv *priv = ieee80211_priv(dev);
8184 struct iw_statistics *wstats; 8185 struct iw_statistics *wstats;
8185 u32 rssi, quality, tx_retries, missed_beacons, tx_failures; 8186 u32 rssi, tx_retries, missed_beacons, tx_failures;
8186 u32 ord_len = sizeof(u32); 8187 u32 ord_len = sizeof(u32);
8187 8188
8188 if (!priv) 8189 if (!priv)
@@ -8265,7 +8266,8 @@ static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev)
8265 beacon_qual = (20 - missed_beacons) * 8266 beacon_qual = (20 - missed_beacons) *
8266 (PERFECT - VERY_GOOD) / 20 + VERY_GOOD; 8267 (PERFECT - VERY_GOOD) / 20 + VERY_GOOD;
8267 8268
8268 quality = min(beacon_qual, min(tx_qual, rssi_qual)); 8269 quality = min(tx_qual, rssi_qual);
8270 quality = min(beacon_qual, quality);
8269 8271
8270#ifdef CONFIG_IPW2100_DEBUG 8272#ifdef CONFIG_IPW2100_DEBUG
8271 if (beacon_qual == quality) 8273 if (beacon_qual == quality)
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 07f171c4d30e..8e18d5348350 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -83,13 +83,13 @@ MODULE_LICENSE("GPL");
83 83
84static int cmdlog = 0; 84static int cmdlog = 0;
85static int debug = 0; 85static int debug = 0;
86static int channel = 0; 86static int default_channel = 0;
87static int mode = 0; 87static int network_mode = 0;
88 88
89static u32 ipw_debug_level; 89static u32 ipw_debug_level;
90static int associate; 90static int associate;
91static int auto_create = 1; 91static int auto_create = 1;
92static int led = 0; 92static int led_support = 0;
93static int disable = 0; 93static int disable = 0;
94static int bt_coexist = 0; 94static int bt_coexist = 0;
95static int hwcrypto = 0; 95static int hwcrypto = 0;
@@ -4265,9 +4265,10 @@ static void ipw_gather_stats(struct ipw_priv *priv)
4265 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n", 4265 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
4266 signal_quality, rssi); 4266 signal_quality, rssi);
4267 4267
4268 quality = min(beacon_quality, 4268 quality = min(rx_quality, signal_quality);
4269 min(rate_quality, 4269 quality = min(tx_quality, quality);
4270 min(tx_quality, min(rx_quality, signal_quality)))); 4270 quality = min(rate_quality, quality);
4271 quality = min(beacon_quality, quality);
4271 if (quality == beacon_quality) 4272 if (quality == beacon_quality)
4272 IPW_DEBUG_STATS("Quality (%d%%): Clamped to missed beacons.\n", 4273 IPW_DEBUG_STATS("Quality (%d%%): Clamped to missed beacons.\n",
4273 quality); 4274 quality);
@@ -4411,7 +4412,6 @@ static void ipw_rx_notification(struct ipw_priv *priv,
4411{ 4412{
4412 DECLARE_SSID_BUF(ssid); 4413 DECLARE_SSID_BUF(ssid);
4413 u16 size = le16_to_cpu(notif->size); 4414 u16 size = le16_to_cpu(notif->size);
4414 notif->size = le16_to_cpu(notif->size);
4415 4415
4416 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, size); 4416 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, size);
4417 4417
@@ -6101,11 +6101,10 @@ static void ipw_debug_config(struct ipw_priv *priv)
6101static void ipw_set_fixed_rate(struct ipw_priv *priv, int mode) 6101static void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
6102{ 6102{
6103 /* TODO: Verify that this works... */ 6103 /* TODO: Verify that this works... */
6104 struct ipw_fixed_rate fr = { 6104 struct ipw_fixed_rate fr;
6105 .tx_rates = priv->rates_mask
6106 };
6107 u32 reg; 6105 u32 reg;
6108 u16 mask = 0; 6106 u16 mask = 0;
6107 u16 new_tx_rates = priv->rates_mask;
6109 6108
6110 /* Identify 'current FW band' and match it with the fixed 6109 /* Identify 'current FW band' and match it with the fixed
6111 * Tx rates */ 6110 * Tx rates */
@@ -6117,54 +6116,56 @@ static void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)
6117 /* Invalid fixed rate mask */ 6116 /* Invalid fixed rate mask */
6118 IPW_DEBUG_WX 6117 IPW_DEBUG_WX
6119 ("invalid fixed rate mask in ipw_set_fixed_rate\n"); 6118 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
6120 fr.tx_rates = 0; 6119 new_tx_rates = 0;
6121 break; 6120 break;
6122 } 6121 }
6123 6122
6124 fr.tx_rates >>= IEEE80211_OFDM_SHIFT_MASK_A; 6123 new_tx_rates >>= IEEE80211_OFDM_SHIFT_MASK_A;
6125 break; 6124 break;
6126 6125
6127 default: /* 2.4Ghz or Mixed */ 6126 default: /* 2.4Ghz or Mixed */
6128 /* IEEE_B */ 6127 /* IEEE_B */
6129 if (mode == IEEE_B) { 6128 if (mode == IEEE_B) {
6130 if (fr.tx_rates & ~IEEE80211_CCK_RATES_MASK) { 6129 if (new_tx_rates & ~IEEE80211_CCK_RATES_MASK) {
6131 /* Invalid fixed rate mask */ 6130 /* Invalid fixed rate mask */
6132 IPW_DEBUG_WX 6131 IPW_DEBUG_WX
6133 ("invalid fixed rate mask in ipw_set_fixed_rate\n"); 6132 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
6134 fr.tx_rates = 0; 6133 new_tx_rates = 0;
6135 } 6134 }
6136 break; 6135 break;
6137 } 6136 }
6138 6137
6139 /* IEEE_G */ 6138 /* IEEE_G */
6140 if (fr.tx_rates & ~(IEEE80211_CCK_RATES_MASK | 6139 if (new_tx_rates & ~(IEEE80211_CCK_RATES_MASK |
6141 IEEE80211_OFDM_RATES_MASK)) { 6140 IEEE80211_OFDM_RATES_MASK)) {
6142 /* Invalid fixed rate mask */ 6141 /* Invalid fixed rate mask */
6143 IPW_DEBUG_WX 6142 IPW_DEBUG_WX
6144 ("invalid fixed rate mask in ipw_set_fixed_rate\n"); 6143 ("invalid fixed rate mask in ipw_set_fixed_rate\n");
6145 fr.tx_rates = 0; 6144 new_tx_rates = 0;
6146 break; 6145 break;
6147 } 6146 }
6148 6147
6149 if (IEEE80211_OFDM_RATE_6MB_MASK & fr.tx_rates) { 6148 if (IEEE80211_OFDM_RATE_6MB_MASK & new_tx_rates) {
6150 mask |= (IEEE80211_OFDM_RATE_6MB_MASK >> 1); 6149 mask |= (IEEE80211_OFDM_RATE_6MB_MASK >> 1);
6151 fr.tx_rates &= ~IEEE80211_OFDM_RATE_6MB_MASK; 6150 new_tx_rates &= ~IEEE80211_OFDM_RATE_6MB_MASK;
6152 } 6151 }
6153 6152
6154 if (IEEE80211_OFDM_RATE_9MB_MASK & fr.tx_rates) { 6153 if (IEEE80211_OFDM_RATE_9MB_MASK & new_tx_rates) {
6155 mask |= (IEEE80211_OFDM_RATE_9MB_MASK >> 1); 6154 mask |= (IEEE80211_OFDM_RATE_9MB_MASK >> 1);
6156 fr.tx_rates &= ~IEEE80211_OFDM_RATE_9MB_MASK; 6155 new_tx_rates &= ~IEEE80211_OFDM_RATE_9MB_MASK;
6157 } 6156 }
6158 6157
6159 if (IEEE80211_OFDM_RATE_12MB_MASK & fr.tx_rates) { 6158 if (IEEE80211_OFDM_RATE_12MB_MASK & new_tx_rates) {
6160 mask |= (IEEE80211_OFDM_RATE_12MB_MASK >> 1); 6159 mask |= (IEEE80211_OFDM_RATE_12MB_MASK >> 1);
6161 fr.tx_rates &= ~IEEE80211_OFDM_RATE_12MB_MASK; 6160 new_tx_rates &= ~IEEE80211_OFDM_RATE_12MB_MASK;
6162 } 6161 }
6163 6162
6164 fr.tx_rates |= mask; 6163 new_tx_rates |= mask;
6165 break; 6164 break;
6166 } 6165 }
6167 6166
6167 fr.tx_rates = cpu_to_le16(new_tx_rates);
6168
6168 reg = ipw_read32(priv, IPW_MEM_FIXED_OVERRIDE); 6169 reg = ipw_read32(priv, IPW_MEM_FIXED_OVERRIDE);
6169 ipw_write_reg32(priv, reg, *(u32 *) & fr); 6170 ipw_write_reg32(priv, reg, *(u32 *) & fr);
6170} 6171}
@@ -7850,7 +7851,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
7850 7851
7851 /* Convert signal to DBM */ 7852 /* Convert signal to DBM */
7852 ipw_rt->rt_dbmsignal = antsignal; 7853 ipw_rt->rt_dbmsignal = antsignal;
7853 ipw_rt->rt_dbmnoise = frame->noise; 7854 ipw_rt->rt_dbmnoise = (s8) le16_to_cpu(frame->noise);
7854 7855
7855 /* Convert the channel data and set the flags */ 7856 /* Convert the channel data and set the flags */
7856 ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel)); 7857 ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel));
@@ -7964,7 +7965,7 @@ static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
7964 u16 channel = frame->received_channel; 7965 u16 channel = frame->received_channel;
7965 u8 phy_flags = frame->antennaAndPhy; 7966 u8 phy_flags = frame->antennaAndPhy;
7966 s8 signal = frame->rssi_dbm - IPW_RSSI_TO_DBM; 7967 s8 signal = frame->rssi_dbm - IPW_RSSI_TO_DBM;
7967 s8 noise = frame->noise; 7968 s8 noise = (s8) le16_to_cpu(frame->noise);
7968 u8 rate = frame->rate; 7969 u8 rate = frame->rate;
7969 short len = le16_to_cpu(pkt->u.frame.length); 7970 short len = le16_to_cpu(pkt->u.frame.length);
7970 struct sk_buff *skb; 7971 struct sk_buff *skb;
@@ -8335,7 +8336,7 @@ static void ipw_rx(struct ipw_priv *priv)
8335 .rssi = pkt->u.frame.rssi_dbm - 8336 .rssi = pkt->u.frame.rssi_dbm -
8336 IPW_RSSI_TO_DBM, 8337 IPW_RSSI_TO_DBM,
8337 .signal = 8338 .signal =
8338 le16_to_cpu(pkt->u.frame.rssi_dbm) - 8339 pkt->u.frame.rssi_dbm -
8339 IPW_RSSI_TO_DBM + 0x100, 8340 IPW_RSSI_TO_DBM + 0x100,
8340 .noise = 8341 .noise =
8341 le16_to_cpu(pkt->u.frame.noise), 8342 le16_to_cpu(pkt->u.frame.noise),
@@ -8517,7 +8518,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
8517 8518
8518 /* We default to disabling the LED code as right now it causes 8519 /* We default to disabling the LED code as right now it causes
8519 * too many systems to lock up... */ 8520 * too many systems to lock up... */
8520 if (!led) 8521 if (!led_support)
8521 priv->config |= CFG_NO_LED; 8522 priv->config |= CFG_NO_LED;
8522 8523
8523 if (associate) 8524 if (associate)
@@ -8539,10 +8540,10 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
8539 IPW_DEBUG_INFO("Radio disabled.\n"); 8540 IPW_DEBUG_INFO("Radio disabled.\n");
8540 } 8541 }
8541 8542
8542 if (channel != 0) { 8543 if (default_channel != 0) {
8543 priv->config |= CFG_STATIC_CHANNEL; 8544 priv->config |= CFG_STATIC_CHANNEL;
8544 priv->channel = channel; 8545 priv->channel = default_channel;
8545 IPW_DEBUG_INFO("Bind to static channel %d\n", channel); 8546 IPW_DEBUG_INFO("Bind to static channel %d\n", default_channel);
8546 /* TODO: Validate that provided channel is in range */ 8547 /* TODO: Validate that provided channel is in range */
8547 } 8548 }
8548#ifdef CONFIG_IPW2200_QOS 8549#ifdef CONFIG_IPW2200_QOS
@@ -8550,7 +8551,7 @@ static int ipw_sw_reset(struct ipw_priv *priv, int option)
8550 burst_duration_CCK, burst_duration_OFDM); 8551 burst_duration_CCK, burst_duration_OFDM);
8551#endif /* CONFIG_IPW2200_QOS */ 8552#endif /* CONFIG_IPW2200_QOS */
8552 8553
8553 switch (mode) { 8554 switch (network_mode) {
8554 case 1: 8555 case 1:
8555 priv->ieee->iw_mode = IW_MODE_ADHOC; 8556 priv->ieee->iw_mode = IW_MODE_ADHOC;
8556 priv->net_dev->type = ARPHRD_ETHER; 8557 priv->net_dev->type = ARPHRD_ETHER;
@@ -10181,7 +10182,6 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
10181#endif 10182#endif
10182 struct clx2_queue *q = &txq->q; 10183 struct clx2_queue *q = &txq->q;
10183 u8 id, hdr_len, unicast; 10184 u8 id, hdr_len, unicast;
10184 u16 remaining_bytes;
10185 int fc; 10185 int fc;
10186 10186
10187 if (!(priv->status & STATUS_ASSOCIATED)) 10187 if (!(priv->status & STATUS_ASSOCIATED))
@@ -10220,7 +10220,6 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
10220 10220
10221 tfd->u.data.cmd_id = DINO_CMD_TX; 10221 tfd->u.data.cmd_id = DINO_CMD_TX;
10222 tfd->u.data.len = cpu_to_le16(txb->payload_size); 10222 tfd->u.data.len = cpu_to_le16(txb->payload_size);
10223 remaining_bytes = txb->payload_size;
10224 10223
10225 if (priv->assoc_request.ieee_mode == IPW_B_MODE) 10224 if (priv->assoc_request.ieee_mode == IPW_B_MODE)
10226 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_CCK; 10225 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_CCK;
@@ -11946,13 +11945,13 @@ MODULE_PARM_DESC(associate, "auto associate when scanning (default off)");
11946module_param(auto_create, int, 0444); 11945module_param(auto_create, int, 0444);
11947MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)"); 11946MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
11948 11947
11949module_param(led, int, 0444); 11948module_param_named(led, led_support, int, 0444);
11950MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)"); 11949MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)");
11951 11950
11952module_param(debug, int, 0444); 11951module_param(debug, int, 0444);
11953MODULE_PARM_DESC(debug, "debug output mask"); 11952MODULE_PARM_DESC(debug, "debug output mask");
11954 11953
11955module_param(channel, int, 0444); 11954module_param_named(channel, default_channel, int, 0444);
11956MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); 11955MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
11957 11956
11958#ifdef CONFIG_IPW2200_PROMISCUOUS 11957#ifdef CONFIG_IPW2200_PROMISCUOUS
@@ -11978,10 +11977,10 @@ MODULE_PARM_DESC(burst_duration_OFDM, "set OFDM burst value");
11978#endif /* CONFIG_IPW2200_QOS */ 11977#endif /* CONFIG_IPW2200_QOS */
11979 11978
11980#ifdef CONFIG_IPW2200_MONITOR 11979#ifdef CONFIG_IPW2200_MONITOR
11981module_param(mode, int, 0444); 11980module_param_named(mode, network_mode, int, 0444);
11982MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)"); 11981MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
11983#else 11982#else
11984module_param(mode, int, 0444); 11983module_param_named(mode, network_mode, int, 0444);
11985MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)"); 11984MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");
11986#endif 11985#endif
11987 11986
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 191718a0c545..a95caa014143 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -149,12 +149,15 @@ struct iwl_cfg iwl1000_bgn_cfg = {
149 .ucode_api_min = IWL1000_UCODE_API_MIN, 149 .ucode_api_min = IWL1000_UCODE_API_MIN,
150 .sku = IWL_SKU_G|IWL_SKU_N, 150 .sku = IWL_SKU_G|IWL_SKU_N,
151 .ops = &iwl1000_ops, 151 .ops = &iwl1000_ops,
152 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 152 .eeprom_size = OTP_LOW_IMAGE_SIZE,
153 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 153 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
154 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 154 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
155 .mod_params = &iwl50_mod_params, 155 .mod_params = &iwl50_mod_params,
156 .valid_tx_ant = ANT_A, 156 .valid_tx_ant = ANT_A,
157 .valid_rx_ant = ANT_AB, 157 .valid_rx_ant = ANT_AB,
158 .need_pll_cfg = true, 158 .need_pll_cfg = true,
159 .max_ll_items = OTP_MAX_LL_ITEMS_1000,
160 .shadow_ram_support = false,
161 .ht_greenfield_support = true,
159}; 162};
160 163
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index ba5ef832d770..e9a685d8e3a1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -349,12 +349,13 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv,
349 * 349 *
350 *****************************************************************************/ 350 *****************************************************************************/
351 351
352void iwl3945_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) 352void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
353 struct iwl_rx_mem_buffer *rxb)
353{ 354{
354 struct iwl_rx_packet *pkt = (void *)rxb->skb->data; 355 struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
355 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", 356 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
356 (int)sizeof(struct iwl3945_notif_statistics), 357 (int)sizeof(struct iwl3945_notif_statistics),
357 le32_to_cpu(pkt->len)); 358 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
358 359
359 memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39)); 360 memcpy(&priv->statistics_39, pkt->u.raw, sizeof(priv->statistics_39));
360 361
@@ -2889,7 +2890,8 @@ static struct iwl_cfg iwl3945_bg_cfg = {
2889 .eeprom_ver = EEPROM_3945_EEPROM_VERSION, 2890 .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
2890 .ops = &iwl3945_ops, 2891 .ops = &iwl3945_ops,
2891 .mod_params = &iwl3945_mod_params, 2892 .mod_params = &iwl3945_mod_params,
2892 .use_isr_legacy = true 2893 .use_isr_legacy = true,
2894 .ht_greenfield_support = false,
2893}; 2895};
2894 2896
2895static struct iwl_cfg iwl3945_abg_cfg = { 2897static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2902,7 +2904,8 @@ static struct iwl_cfg iwl3945_abg_cfg = {
2902 .eeprom_ver = EEPROM_3945_EEPROM_VERSION, 2904 .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
2903 .ops = &iwl3945_ops, 2905 .ops = &iwl3945_ops,
2904 .mod_params = &iwl3945_mod_params, 2906 .mod_params = &iwl3945_mod_params,
2905 .use_isr_legacy = true 2907 .use_isr_legacy = true,
2908 .ht_greenfield_support = false,
2906}; 2909};
2907 2910
2908struct pci_device_id iwl3945_hw_card_ids[] = { 2911struct pci_device_id iwl3945_hw_card_ids[] = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index e427a8937ed8..6a13bfbc9d98 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2344,7 +2344,8 @@ struct iwl_cfg iwl4965_agn_cfg = {
2344 .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, 2344 .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
2345 .ops = &iwl4965_ops, 2345 .ops = &iwl4965_ops,
2346 .mod_params = &iwl4965_mod_params, 2346 .mod_params = &iwl4965_mod_params,
2347 .use_isr_legacy = true 2347 .use_isr_legacy = true,
2348 .ht_greenfield_support = false,
2348}; 2349};
2349 2350
2350/* Module firmware */ 2351/* Module firmware */
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 755c184b3ecb..1d539e3b8db1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -494,7 +494,7 @@ static void iwl5000_rx_calib_result(struct iwl_priv *priv,
494{ 494{
495 struct iwl_rx_packet *pkt = (void *)rxb->skb->data; 495 struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
496 struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw; 496 struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
497 int len = le32_to_cpu(pkt->len) & FH_RSCSR_FRAME_SIZE_MSK; 497 int len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
498 int index; 498 int index;
499 499
500 /* reduce the size of the length field itself */ 500 /* reduce the size of the length field itself */
@@ -1411,6 +1411,7 @@ static void iwl5150_temperature(struct iwl_priv *priv)
1411 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset; 1411 vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
1412 /* now vt hold the temperature in Kelvin */ 1412 /* now vt hold the temperature in Kelvin */
1413 priv->temperature = KELVIN_TO_CELSIUS(vt); 1413 priv->temperature = KELVIN_TO_CELSIUS(vt);
1414 iwl_tt_handler(priv);
1414} 1415}
1415 1416
1416/* Calc max signal level (dBm) among 3 possible receivers */ 1417/* Calc max signal level (dBm) among 3 possible receivers */
@@ -1652,6 +1653,7 @@ struct iwl_cfg iwl5300_agn_cfg = {
1652 .valid_tx_ant = ANT_ABC, 1653 .valid_tx_ant = ANT_ABC,
1653 .valid_rx_ant = ANT_ABC, 1654 .valid_rx_ant = ANT_ABC,
1654 .need_pll_cfg = true, 1655 .need_pll_cfg = true,
1656 .ht_greenfield_support = true,
1655}; 1657};
1656 1658
1657struct iwl_cfg iwl5100_bg_cfg = { 1659struct iwl_cfg iwl5100_bg_cfg = {
@@ -1668,6 +1670,7 @@ struct iwl_cfg iwl5100_bg_cfg = {
1668 .valid_tx_ant = ANT_B, 1670 .valid_tx_ant = ANT_B,
1669 .valid_rx_ant = ANT_AB, 1671 .valid_rx_ant = ANT_AB,
1670 .need_pll_cfg = true, 1672 .need_pll_cfg = true,
1673 .ht_greenfield_support = true,
1671}; 1674};
1672 1675
1673struct iwl_cfg iwl5100_abg_cfg = { 1676struct iwl_cfg iwl5100_abg_cfg = {
@@ -1684,6 +1687,7 @@ struct iwl_cfg iwl5100_abg_cfg = {
1684 .valid_tx_ant = ANT_B, 1687 .valid_tx_ant = ANT_B,
1685 .valid_rx_ant = ANT_AB, 1688 .valid_rx_ant = ANT_AB,
1686 .need_pll_cfg = true, 1689 .need_pll_cfg = true,
1690 .ht_greenfield_support = true,
1687}; 1691};
1688 1692
1689struct iwl_cfg iwl5100_agn_cfg = { 1693struct iwl_cfg iwl5100_agn_cfg = {
@@ -1700,6 +1704,7 @@ struct iwl_cfg iwl5100_agn_cfg = {
1700 .valid_tx_ant = ANT_B, 1704 .valid_tx_ant = ANT_B,
1701 .valid_rx_ant = ANT_AB, 1705 .valid_rx_ant = ANT_AB,
1702 .need_pll_cfg = true, 1706 .need_pll_cfg = true,
1707 .ht_greenfield_support = true,
1703}; 1708};
1704 1709
1705struct iwl_cfg iwl5350_agn_cfg = { 1710struct iwl_cfg iwl5350_agn_cfg = {
@@ -1716,6 +1721,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
1716 .valid_tx_ant = ANT_ABC, 1721 .valid_tx_ant = ANT_ABC,
1717 .valid_rx_ant = ANT_ABC, 1722 .valid_rx_ant = ANT_ABC,
1718 .need_pll_cfg = true, 1723 .need_pll_cfg = true,
1724 .ht_greenfield_support = true,
1719}; 1725};
1720 1726
1721struct iwl_cfg iwl5150_agn_cfg = { 1727struct iwl_cfg iwl5150_agn_cfg = {
@@ -1732,6 +1738,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
1732 .valid_tx_ant = ANT_A, 1738 .valid_tx_ant = ANT_A,
1733 .valid_rx_ant = ANT_AB, 1739 .valid_rx_ant = ANT_AB,
1734 .need_pll_cfg = true, 1740 .need_pll_cfg = true,
1741 .ht_greenfield_support = true,
1735}; 1742};
1736 1743
1737MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); 1744MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index c3ec6c20cc94..383177db7de7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -161,7 +161,7 @@ struct iwl_cfg iwl6000h_2agn_cfg = {
161 .ucode_api_min = IWL6000_UCODE_API_MIN, 161 .ucode_api_min = IWL6000_UCODE_API_MIN,
162 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 162 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
163 .ops = &iwl6000_ops, 163 .ops = &iwl6000_ops,
164 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 164 .eeprom_size = OTP_LOW_IMAGE_SIZE,
165 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 165 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
166 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 166 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
167 .mod_params = &iwl50_mod_params, 167 .mod_params = &iwl50_mod_params,
@@ -169,6 +169,9 @@ struct iwl_cfg iwl6000h_2agn_cfg = {
169 .valid_rx_ant = ANT_AB, 169 .valid_rx_ant = ANT_AB,
170 .need_pll_cfg = false, 170 .need_pll_cfg = false,
171 .pa_type = IWL_PA_HYBRID, 171 .pa_type = IWL_PA_HYBRID,
172 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
173 .shadow_ram_support = true,
174 .ht_greenfield_support = true,
172}; 175};
173 176
174/* 177/*
@@ -181,7 +184,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
181 .ucode_api_min = IWL6000_UCODE_API_MIN, 184 .ucode_api_min = IWL6000_UCODE_API_MIN,
182 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 185 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
183 .ops = &iwl6000_ops, 186 .ops = &iwl6000_ops,
184 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 187 .eeprom_size = OTP_LOW_IMAGE_SIZE,
185 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 188 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
186 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 189 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
187 .mod_params = &iwl50_mod_params, 190 .mod_params = &iwl50_mod_params,
@@ -189,6 +192,9 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
189 .valid_rx_ant = ANT_BC, 192 .valid_rx_ant = ANT_BC,
190 .need_pll_cfg = false, 193 .need_pll_cfg = false,
191 .pa_type = IWL_PA_INTERNAL, 194 .pa_type = IWL_PA_INTERNAL,
195 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
196 .shadow_ram_support = true,
197 .ht_greenfield_support = true,
192}; 198};
193 199
194struct iwl_cfg iwl6050_2agn_cfg = { 200struct iwl_cfg iwl6050_2agn_cfg = {
@@ -198,7 +204,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
198 .ucode_api_min = IWL6050_UCODE_API_MIN, 204 .ucode_api_min = IWL6050_UCODE_API_MIN,
199 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 205 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
200 .ops = &iwl6000_ops, 206 .ops = &iwl6000_ops,
201 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 207 .eeprom_size = OTP_LOW_IMAGE_SIZE,
202 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 208 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
203 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 209 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
204 .mod_params = &iwl50_mod_params, 210 .mod_params = &iwl50_mod_params,
@@ -206,6 +212,9 @@ struct iwl_cfg iwl6050_2agn_cfg = {
206 .valid_rx_ant = ANT_AB, 212 .valid_rx_ant = ANT_AB,
207 .need_pll_cfg = false, 213 .need_pll_cfg = false,
208 .pa_type = IWL_PA_SYSTEM, 214 .pa_type = IWL_PA_SYSTEM,
215 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
216 .shadow_ram_support = true,
217 .ht_greenfield_support = true,
209}; 218};
210 219
211struct iwl_cfg iwl6000_3agn_cfg = { 220struct iwl_cfg iwl6000_3agn_cfg = {
@@ -215,7 +224,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
215 .ucode_api_min = IWL6000_UCODE_API_MIN, 224 .ucode_api_min = IWL6000_UCODE_API_MIN,
216 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 225 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
217 .ops = &iwl6000_ops, 226 .ops = &iwl6000_ops,
218 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 227 .eeprom_size = OTP_LOW_IMAGE_SIZE,
219 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 228 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
220 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 229 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
221 .mod_params = &iwl50_mod_params, 230 .mod_params = &iwl50_mod_params,
@@ -223,6 +232,9 @@ struct iwl_cfg iwl6000_3agn_cfg = {
223 .valid_rx_ant = ANT_ABC, 232 .valid_rx_ant = ANT_ABC,
224 .need_pll_cfg = false, 233 .need_pll_cfg = false,
225 .pa_type = IWL_PA_SYSTEM, 234 .pa_type = IWL_PA_SYSTEM,
235 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
236 .shadow_ram_support = true,
237 .ht_greenfield_support = true,
226}; 238};
227 239
228struct iwl_cfg iwl6050_3agn_cfg = { 240struct iwl_cfg iwl6050_3agn_cfg = {
@@ -232,7 +244,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
232 .ucode_api_min = IWL6050_UCODE_API_MIN, 244 .ucode_api_min = IWL6050_UCODE_API_MIN,
233 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, 245 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
234 .ops = &iwl6000_ops, 246 .ops = &iwl6000_ops,
235 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 247 .eeprom_size = OTP_LOW_IMAGE_SIZE,
236 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 248 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
237 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 249 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
238 .mod_params = &iwl50_mod_params, 250 .mod_params = &iwl50_mod_params,
@@ -240,6 +252,9 @@ struct iwl_cfg iwl6050_3agn_cfg = {
240 .valid_rx_ant = ANT_ABC, 252 .valid_rx_ant = ANT_ABC,
241 .need_pll_cfg = false, 253 .need_pll_cfg = false,
242 .pa_type = IWL_PA_SYSTEM, 254 .pa_type = IWL_PA_SYSTEM,
255 .max_ll_items = OTP_MAX_LL_ITEMS_6x00,
256 .shadow_ram_support = true,
257 .ht_greenfield_support = true,
243}; 258};
244 259
245MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 260MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 21331552ff2c..fee110de5c6a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -332,6 +332,9 @@ static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,
332 } else 332 } else
333 return MAX_TID_COUNT; 333 return MAX_TID_COUNT;
334 334
335 if (unlikely(tid >= TID_MAX_LOAD_COUNT))
336 return MAX_TID_COUNT;
337
335 tl = &lq_data->load[tid]; 338 tl = &lq_data->load[tid];
336 339
337 curr_time -= curr_time % TID_ROUND_VALUE; 340 curr_time -= curr_time % TID_ROUND_VALUE;
@@ -654,19 +657,15 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
654 return 1; 657 return 1;
655} 658}
656 659
657/* in 4965 we don't use greenfield at all */ 660/**
658static inline u8 rs_use_green(struct iwl_priv *priv, 661 * Green-field mode is valid if the station supports it and
659 struct ieee80211_conf *conf) 662 * there are no non-GF stations present in the BSS.
663 */
664static inline u8 rs_use_green(struct ieee80211_sta *sta,
665 struct iwl_ht_info *ht_conf)
660{ 666{
661 u8 is_green; 667 return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
662 668 !(ht_conf->non_GF_STA_present);
663 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
664 is_green = 0;
665 else
666 is_green = (conf_is_ht(conf) &&
667 priv->current_ht_config.is_green_field &&
668 !priv->current_ht_config.non_GF_STA_present);
669 return is_green;
670} 669}
671 670
672/** 671/**
@@ -1222,18 +1221,6 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
1222 else 1221 else
1223 tbl->is_ht40 = 0; 1222 tbl->is_ht40 = 0;
1224 1223
1225 /* FIXME: - don't toggle SGI here
1226 if (tbl->is_ht40) {
1227 if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY)
1228 tbl->is_SGI = 1;
1229 else
1230 tbl->is_SGI = 0;
1231 } else if (priv->current_ht_config.sgf & HT_SHORT_GI_20MHZ_ONLY)
1232 tbl->is_SGI = 1;
1233 else
1234 tbl->is_SGI = 0;
1235 */
1236
1237 rs_set_expected_tpt_table(lq_sta, tbl); 1224 rs_set_expected_tpt_table(lq_sta, tbl);
1238 1225
1239 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index); 1226 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
@@ -1288,18 +1275,6 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv,
1288 else 1275 else
1289 tbl->is_ht40 = 0; 1276 tbl->is_ht40 = 0;
1290 1277
1291 /* FIXME: - don't toggle SGI here
1292 if (tbl->is_ht40) {
1293 if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY)
1294 tbl->is_SGI = 1;
1295 else
1296 tbl->is_SGI = 0;
1297 } else if (priv->current_ht_config.sgf & HT_SHORT_GI_20MHZ_ONLY)
1298 tbl->is_SGI = 1;
1299 else
1300 tbl->is_SGI = 0;
1301 */
1302
1303 rs_set_expected_tpt_table(lq_sta, tbl); 1278 rs_set_expected_tpt_table(lq_sta, tbl);
1304 1279
1305 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index); 1280 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
@@ -1347,18 +1322,6 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
1347 else 1322 else
1348 tbl->is_ht40 = 0; 1323 tbl->is_ht40 = 0;
1349 1324
1350 /* FIXME: - don't toggle SGI here
1351 if (tbl->is_ht40) {
1352 if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY)
1353 tbl->is_SGI = 1;
1354 else
1355 tbl->is_SGI = 0;
1356 } else if (priv->current_ht_config.sgf & HT_SHORT_GI_20MHZ_ONLY)
1357 tbl->is_SGI = 1;
1358 else
1359 tbl->is_SGI = 0;
1360 */
1361
1362 if (is_green) 1325 if (is_green)
1363 tbl->is_SGI = 0; /*11n spec: no SGI in SISO+Greenfield*/ 1326 tbl->is_SGI = 0; /*11n spec: no SGI in SISO+Greenfield*/
1364 1327
@@ -1527,6 +1490,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1527 struct iwl_scale_tbl_info *search_tbl = 1490 struct iwl_scale_tbl_info *search_tbl =
1528 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); 1491 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1529 struct iwl_rate_scale_data *window = &(tbl->win[index]); 1492 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1493 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1530 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1494 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1531 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1495 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1532 u8 start_action = tbl->action; 1496 u8 start_action = tbl->action;
@@ -1586,13 +1550,11 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1586 goto out; 1550 goto out;
1587 break; 1551 break;
1588 case IWL_SISO_SWITCH_GI: 1552 case IWL_SISO_SWITCH_GI:
1589 if (!tbl->is_ht40 && 1553 if (!tbl->is_ht40 && !(ht_cap->cap &
1590 !(priv->current_ht_config.sgf & 1554 IEEE80211_HT_CAP_SGI_20))
1591 HT_SHORT_GI_20MHZ))
1592 break; 1555 break;
1593 if (tbl->is_ht40 && 1556 if (tbl->is_ht40 && !(ht_cap->cap &
1594 !(priv->current_ht_config.sgf & 1557 IEEE80211_HT_CAP_SGI_40))
1595 HT_SHORT_GI_40MHZ))
1596 break; 1558 break;
1597 1559
1598 IWL_DEBUG_RATE(priv, "LQ: SISO toggle SGI/NGI\n"); 1560 IWL_DEBUG_RATE(priv, "LQ: SISO toggle SGI/NGI\n");
@@ -1666,6 +1628,7 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
1666 struct iwl_scale_tbl_info *search_tbl = 1628 struct iwl_scale_tbl_info *search_tbl =
1667 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); 1629 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1668 struct iwl_rate_scale_data *window = &(tbl->win[index]); 1630 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1631 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1669 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1632 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1670 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1633 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1671 u8 start_action = tbl->action; 1634 u8 start_action = tbl->action;
@@ -1726,13 +1689,11 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
1726 break; 1689 break;
1727 1690
1728 case IWL_MIMO2_SWITCH_GI: 1691 case IWL_MIMO2_SWITCH_GI:
1729 if (!tbl->is_ht40 && 1692 if (!tbl->is_ht40 && !(ht_cap->cap &
1730 !(priv->current_ht_config.sgf & 1693 IEEE80211_HT_CAP_SGI_20))
1731 HT_SHORT_GI_20MHZ))
1732 break; 1694 break;
1733 if (tbl->is_ht40 && 1695 if (tbl->is_ht40 && !(ht_cap->cap &
1734 !(priv->current_ht_config.sgf & 1696 IEEE80211_HT_CAP_SGI_40))
1735 HT_SHORT_GI_40MHZ))
1736 break; 1697 break;
1737 1698
1738 IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle SGI/NGI\n"); 1699 IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle SGI/NGI\n");
@@ -1808,6 +1769,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
1808 struct iwl_scale_tbl_info *search_tbl = 1769 struct iwl_scale_tbl_info *search_tbl =
1809 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); 1770 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1810 struct iwl_rate_scale_data *window = &(tbl->win[index]); 1771 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1772 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1811 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1773 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1812 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1774 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1813 u8 start_action = tbl->action; 1775 u8 start_action = tbl->action;
@@ -1890,13 +1852,11 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
1890 break; 1852 break;
1891 1853
1892 case IWL_MIMO3_SWITCH_GI: 1854 case IWL_MIMO3_SWITCH_GI:
1893 if (!tbl->is_ht40 && 1855 if (!tbl->is_ht40 && !(ht_cap->cap &
1894 !(priv->current_ht_config.sgf & 1856 IEEE80211_HT_CAP_SGI_20))
1895 HT_SHORT_GI_20MHZ))
1896 break; 1857 break;
1897 if (tbl->is_ht40 && 1858 if (tbl->is_ht40 && !(ht_cap->cap &
1898 !(priv->current_ht_config.sgf & 1859 IEEE80211_HT_CAP_SGI_40))
1899 HT_SHORT_GI_40MHZ))
1900 break; 1860 break;
1901 1861
1902 IWL_DEBUG_RATE(priv, "LQ: MIMO3 toggle SGI/NGI\n"); 1862 IWL_DEBUG_RATE(priv, "LQ: MIMO3 toggle SGI/NGI\n");
@@ -2108,7 +2068,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2108 if (is_legacy(tbl->lq_type)) 2068 if (is_legacy(tbl->lq_type))
2109 lq_sta->is_green = 0; 2069 lq_sta->is_green = 0;
2110 else 2070 else
2111 lq_sta->is_green = rs_use_green(priv, conf); 2071 lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config);
2112 is_green = lq_sta->is_green; 2072 is_green = lq_sta->is_green;
2113 2073
2114 /* current tx rate */ 2074 /* current tx rate */
@@ -2466,7 +2426,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2466 int rate_idx; 2426 int rate_idx;
2467 int i; 2427 int i;
2468 u32 rate; 2428 u32 rate;
2469 u8 use_green = rs_use_green(priv, conf); 2429 u8 use_green = rs_use_green(sta, &priv->current_ht_config);
2470 u8 active_tbl = 0; 2430 u8 active_tbl = 0;
2471 u8 valid_tx_ant; 2431 u8 valid_tx_ant;
2472 2432
@@ -2519,6 +2479,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2519 struct ieee80211_supported_band *sband = txrc->sband; 2479 struct ieee80211_supported_band *sband = txrc->sband;
2520 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 2480 struct iwl_priv *priv = (struct iwl_priv *)priv_r;
2521 struct ieee80211_conf *conf = &priv->hw->conf; 2481 struct ieee80211_conf *conf = &priv->hw->conf;
2482 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
2522 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 2483 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
2523 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2484 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2524 struct iwl_lq_sta *lq_sta = priv_sta; 2485 struct iwl_lq_sta *lq_sta = priv_sta;
@@ -2551,7 +2512,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2551 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", 2512 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
2552 hdr->addr1); 2513 hdr->addr1);
2553 sta_id = iwl_add_station(priv, hdr->addr1, 2514 sta_id = iwl_add_station(priv, hdr->addr1,
2554 false, CMD_ASYNC, NULL); 2515 false, CMD_ASYNC, ht_cap);
2555 } 2516 }
2556 if ((sta_id != IWL_INVALID_STATION)) { 2517 if ((sta_id != IWL_INVALID_STATION)) {
2557 lq_sta->lq.sta_id = sta_id; 2518 lq_sta->lq.sta_id = sta_id;
@@ -2620,6 +2581,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2620 int i, j; 2581 int i, j;
2621 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 2582 struct iwl_priv *priv = (struct iwl_priv *)priv_r;
2622 struct ieee80211_conf *conf = &priv->hw->conf; 2583 struct ieee80211_conf *conf = &priv->hw->conf;
2584 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
2623 struct iwl_lq_sta *lq_sta = priv_sta; 2585 struct iwl_lq_sta *lq_sta = priv_sta;
2624 u16 mask_bit = 0; 2586 u16 mask_bit = 0;
2625 int count; 2587 int count;
@@ -2648,7 +2610,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2648 if (sta_id == IWL_INVALID_STATION) { 2610 if (sta_id == IWL_INVALID_STATION) {
2649 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr); 2611 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
2650 sta_id = iwl_add_station(priv, sta->addr, false, 2612 sta_id = iwl_add_station(priv, sta->addr, false,
2651 CMD_ASYNC, NULL); 2613 CMD_ASYNC, ht_cap);
2652 } 2614 }
2653 if ((sta_id != IWL_INVALID_STATION)) { 2615 if ((sta_id != IWL_INVALID_STATION)) {
2654 lq_sta->lq.sta_id = sta_id; 2616 lq_sta->lq.sta_id = sta_id;
@@ -2661,7 +2623,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2661 lq_sta->is_dup = 0; 2623 lq_sta->is_dup = 0;
2662 lq_sta->max_rate_idx = -1; 2624 lq_sta->max_rate_idx = -1;
2663 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; 2625 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
2664 lq_sta->is_green = rs_use_green(priv, conf); 2626 lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config);
2665 lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); 2627 lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
2666 lq_sta->active_rate_basic = priv->active_rate_basic; 2628 lq_sta->active_rate_basic = priv->active_rate_basic;
2667 lq_sta->band = priv->band; 2629 lq_sta->band = priv->band;
@@ -2669,19 +2631,19 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2669 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), 2631 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
2670 * supp_rates[] does not; shift to convert format, force 9 MBits off. 2632 * supp_rates[] does not; shift to convert format, force 9 MBits off.
2671 */ 2633 */
2672 lq_sta->active_siso_rate = sta->ht_cap.mcs.rx_mask[0] << 1; 2634 lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1;
2673 lq_sta->active_siso_rate |= sta->ht_cap.mcs.rx_mask[0] & 0x1; 2635 lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1;
2674 lq_sta->active_siso_rate &= ~((u16)0x2); 2636 lq_sta->active_siso_rate &= ~((u16)0x2);
2675 lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; 2637 lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;
2676 2638
2677 /* Same here */ 2639 /* Same here */
2678 lq_sta->active_mimo2_rate = sta->ht_cap.mcs.rx_mask[1] << 1; 2640 lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1;
2679 lq_sta->active_mimo2_rate |= sta->ht_cap.mcs.rx_mask[1] & 0x1; 2641 lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1;
2680 lq_sta->active_mimo2_rate &= ~((u16)0x2); 2642 lq_sta->active_mimo2_rate &= ~((u16)0x2);
2681 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; 2643 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
2682 2644
2683 lq_sta->active_mimo3_rate = sta->ht_cap.mcs.rx_mask[2] << 1; 2645 lq_sta->active_mimo3_rate = ht_cap->mcs.rx_mask[2] << 1;
2684 lq_sta->active_mimo3_rate |= sta->ht_cap.mcs.rx_mask[2] & 0x1; 2646 lq_sta->active_mimo3_rate |= ht_cap->mcs.rx_mask[2] & 0x1;
2685 lq_sta->active_mimo3_rate &= ~((u16)0x2); 2647 lq_sta->active_mimo3_rate &= ~((u16)0x2);
2686 lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE; 2648 lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;
2687 2649
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 68d7719071f7..f4303843ff9b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -1156,6 +1156,7 @@ struct iwl_wep_cmd {
1156#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2) 1156#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2)
1157#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3) 1157#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3)
1158#define RX_RES_PHY_FLAGS_ANTENNA_MSK cpu_to_le16(0xf0) 1158#define RX_RES_PHY_FLAGS_ANTENNA_MSK cpu_to_le16(0xf0)
1159#define RX_RES_PHY_FLAGS_ANTENNA_POS 4
1159 1160
1160#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8) 1161#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8)
1161#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8) 1162#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8)
@@ -3481,7 +3482,7 @@ struct iwl_wimax_coex_cmd {
3481 *****************************************************************************/ 3482 *****************************************************************************/
3482 3483
3483struct iwl_rx_packet { 3484struct iwl_rx_packet {
3484 __le32 len; 3485 __le32 len_n_flags;
3485 struct iwl_cmd_header hdr; 3486 struct iwl_cmd_header hdr;
3486 union { 3487 union {
3487 struct iwl3945_rx_frame rx_frame; 3488 struct iwl3945_rx_frame rx_frame;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index af735128333a..f1f6dabd8fbd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -394,7 +394,8 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
394 394
395 ht_info->ht_supported = true; 395 ht_info->ht_supported = true;
396 396
397 ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; 397 if (priv->cfg->ht_greenfield_support)
398 ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
398 ht_info->cap |= IEEE80211_HT_CAP_SGI_20; 399 ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
399 ht_info->cap |= (IEEE80211_HT_CAP_SM_PS & 400 ht_info->cap |= (IEEE80211_HT_CAP_SM_PS &
400 (WLAN_HT_CAP_SM_PS_DISABLED << 2)); 401 (WLAN_HT_CAP_SM_PS_DISABLED << 2));
@@ -1513,7 +1514,7 @@ EXPORT_SYMBOL(iwl_irq_handle_error);
1513void iwl_configure_filter(struct ieee80211_hw *hw, 1514void iwl_configure_filter(struct ieee80211_hw *hw,
1514 unsigned int changed_flags, 1515 unsigned int changed_flags,
1515 unsigned int *total_flags, 1516 unsigned int *total_flags,
1516 int mc_count, struct dev_addr_list *mc_list) 1517 u64 multicast)
1517{ 1518{
1518 struct iwl_priv *priv = hw->priv; 1519 struct iwl_priv *priv = hw->priv;
1519 __le32 *filter_flags = &priv->staging_rxon.filter_flags; 1520 __le32 *filter_flags = &priv->staging_rxon.filter_flags;
@@ -1579,6 +1580,12 @@ int iwl_setup_mac(struct iwl_priv *priv)
1579 /* Firmware does not support this */ 1580 /* Firmware does not support this */
1580 hw->wiphy->disable_beacon_hints = true; 1581 hw->wiphy->disable_beacon_hints = true;
1581 1582
1583 /*
1584 * For now, disable PS by default because it affects
1585 * RX performance significantly.
1586 */
1587 hw->wiphy->ps_default = false;
1588
1582 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; 1589 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
1583 /* we create the 802.11 header and a zero-length SSID element */ 1590 /* we create the 802.11 header and a zero-length SSID element */
1584 hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; 1591 hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
@@ -2293,10 +2300,11 @@ void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
2293 struct iwl_rx_mem_buffer *rxb) 2300 struct iwl_rx_mem_buffer *rxb)
2294{ 2301{
2295 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 2302 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
2303 u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
2296 IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " 2304 IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
2297 "notification for %s:\n", 2305 "notification for %s:\n", len,
2298 le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd)); 2306 get_cmd_string(pkt->hdr.cmd));
2299 iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len)); 2307 iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len);
2300} 2308}
2301EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif); 2309EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif);
2302 2310
@@ -2391,39 +2399,10 @@ static void iwl_ht_conf(struct iwl_priv *priv,
2391 } 2399 }
2392 ht_conf = &sta->ht_cap; 2400 ht_conf = &sta->ht_cap;
2393 2401
2394 if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
2395 iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
2396 if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
2397 iwl_conf->sgf |= HT_SHORT_GI_40MHZ;
2398
2399 iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
2400 iwl_conf->max_amsdu_size =
2401 !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
2402
2403 iwl_conf->supported_chan_width =
2404 !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
2405
2406 /*
2407 * XXX: The HT configuration needs to be moved into iwl_mac_config()
2408 * to be done there correctly.
2409 */
2410
2411 iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
2412 if (conf_is_ht40_minus(&priv->hw->conf))
2413 iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
2414 else if (conf_is_ht40_plus(&priv->hw->conf))
2415 iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
2416
2417 /* If no above or below channel supplied disable HT40 channel */
2418 if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE &&
2419 iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW)
2420 iwl_conf->supported_chan_width = 0;
2421
2422 iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2); 2402 iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
2423 2403
2424 memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16); 2404 memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16);
2425 2405
2426 iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0;
2427 iwl_conf->ht_protection = 2406 iwl_conf->ht_protection =
2428 bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; 2407 bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
2429 iwl_conf->non_GF_STA_present = 2408 iwl_conf->non_GF_STA_present =
@@ -2736,6 +2715,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2736 struct iwl_priv *priv = hw->priv; 2715 struct iwl_priv *priv = hw->priv;
2737 const struct iwl_channel_info *ch_info; 2716 const struct iwl_channel_info *ch_info;
2738 struct ieee80211_conf *conf = &hw->conf; 2717 struct ieee80211_conf *conf = &hw->conf;
2718 struct iwl_ht_info *ht_conf = &priv->current_ht_config;
2739 unsigned long flags = 0; 2719 unsigned long flags = 0;
2740 int ret = 0; 2720 int ret = 0;
2741 u16 ch; 2721 u16 ch;
@@ -2777,10 +2757,32 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2777 goto set_ch_out; 2757 goto set_ch_out;
2778 } 2758 }
2779 2759
2780 priv->current_ht_config.is_ht = conf_is_ht(conf);
2781
2782 spin_lock_irqsave(&priv->lock, flags); 2760 spin_lock_irqsave(&priv->lock, flags);
2783 2761
2762 /* Configure HT40 channels */
2763 ht_conf->is_ht = conf_is_ht(conf);
2764 if (ht_conf->is_ht) {
2765 if (conf_is_ht40_minus(conf)) {
2766 ht_conf->extension_chan_offset =
2767 IEEE80211_HT_PARAM_CHA_SEC_BELOW;
2768 ht_conf->supported_chan_width =
2769 IWL_CHANNEL_WIDTH_40MHZ;
2770 } else if (conf_is_ht40_plus(conf)) {
2771 ht_conf->extension_chan_offset =
2772 IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
2773 ht_conf->supported_chan_width =
2774 IWL_CHANNEL_WIDTH_40MHZ;
2775 } else {
2776 ht_conf->extension_chan_offset =
2777 IEEE80211_HT_PARAM_CHA_SEC_NONE;
2778 ht_conf->supported_chan_width =
2779 IWL_CHANNEL_WIDTH_20MHZ;
2780 }
2781 } else
2782 ht_conf->supported_chan_width = IWL_CHANNEL_WIDTH_20MHZ;
2783 /* Default to no protection. Protection mode will later be set
2784 * from BSS config in iwl_ht_conf */
2785 ht_conf->ht_protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
2784 2786
2785 /* if we are switching from ht to 2.4 clear flags 2787 /* if we are switching from ht to 2.4 clear flags
2786 * from any ht related info since 2.4 does not 2788 * from any ht related info since 2.4 does not
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 32750f4f1ce1..62d90364b61d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -209,6 +209,8 @@ struct iwl_mod_params {
209 * @ucode_api_max: Highest version of uCode API supported by driver. 209 * @ucode_api_max: Highest version of uCode API supported by driver.
210 * @ucode_api_min: Lowest version of uCode API supported by driver. 210 * @ucode_api_min: Lowest version of uCode API supported by driver.
211 * @pa_type: used by 6000 series only to identify the type of Power Amplifier 211 * @pa_type: used by 6000 series only to identify the type of Power Amplifier
212 * @max_ll_items: max number of OTP blocks
213 * @shadow_ram_support: shadow support for OTP memory
212 * 214 *
213 * We enable the driver to be backward compatible wrt API version. The 215 * We enable the driver to be backward compatible wrt API version. The
214 * driver specifies which APIs it supports (with @ucode_api_max being the 216 * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -247,6 +249,9 @@ struct iwl_cfg {
247 bool need_pll_cfg; 249 bool need_pll_cfg;
248 bool use_isr_legacy; 250 bool use_isr_legacy;
249 enum iwl_pa_type pa_type; 251 enum iwl_pa_type pa_type;
252 const u16 max_ll_items;
253 const bool shadow_ram_support;
254 const bool ht_greenfield_support;
250}; 255};
251 256
252/*************************** 257/***************************
@@ -277,8 +282,7 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv,
277void iwl_irq_handle_error(struct iwl_priv *priv); 282void iwl_irq_handle_error(struct iwl_priv *priv);
278void iwl_configure_filter(struct ieee80211_hw *hw, 283void iwl_configure_filter(struct ieee80211_hw *hw,
279 unsigned int changed_flags, 284 unsigned int changed_flags,
280 unsigned int *total_flags, 285 unsigned int *total_flags, u64 multicast);
281 int mc_count, struct dev_addr_list *mc_list);
282int iwl_hw_nic_init(struct iwl_priv *priv); 286int iwl_hw_nic_init(struct iwl_priv *priv);
283int iwl_setup_mac(struct iwl_priv *priv); 287int iwl_setup_mac(struct iwl_priv *priv);
284int iwl_set_hw_params(struct iwl_priv *priv); 288int iwl_set_hw_params(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index b96c3c9e92a9..0178734499f0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -507,15 +507,9 @@ struct iwl_ht_info {
507 u8 is_ht; 507 u8 is_ht;
508 u8 supported_chan_width; 508 u8 supported_chan_width;
509 u8 sm_ps; 509 u8 sm_ps;
510 u8 is_green_field;
511 u8 sgf; /* HT_SHORT_GI_* short guard interval */
512 u8 max_amsdu_size;
513 u8 ampdu_factor;
514 u8 mpdu_density;
515 struct ieee80211_mcs_info mcs; 510 struct ieee80211_mcs_info mcs;
516 /* BSS related data */ 511 /* BSS related data */
517 u8 extension_chan_offset; 512 u8 extension_chan_offset;
518 u8 tx_chan_width;
519 u8 ht_protection; 513 u8 ht_protection;
520 u8 non_GF_STA_present; 514 u8 non_GF_STA_present;
521}; 515};
@@ -732,9 +726,6 @@ struct iwl_dma_ptr {
732 size_t size; 726 size_t size;
733}; 727};
734 728
735#define HT_SHORT_GI_20MHZ (1 << 0)
736#define HT_SHORT_GI_40MHZ (1 << 1)
737
738#define IWL_CHANNEL_WIDTH_20MHZ 0 729#define IWL_CHANNEL_WIDTH_20MHZ 0
739#define IWL_CHANNEL_WIDTH_40MHZ 1 730#define IWL_CHANNEL_WIDTH_40MHZ 1
740 731
@@ -888,6 +879,17 @@ enum iwl_nvm_type {
888 NVM_DEVICE_TYPE_OTP, 879 NVM_DEVICE_TYPE_OTP,
889}; 880};
890 881
882/*
883 * Two types of OTP memory access modes
884 * IWL_OTP_ACCESS_ABSOLUTE - absolute address mode,
885 * based on physical memory addressing
886 * IWL_OTP_ACCESS_RELATIVE - relative address mode,
887 * based on logical memory addressing
888 */
889enum iwl_access_mode {
890 IWL_OTP_ACCESS_ABSOLUTE,
891 IWL_OTP_ACCESS_RELATIVE,
892};
891 893
892/** 894/**
893 * enum iwl_pa_type - Power Amplifier type 895 * enum iwl_pa_type - Power Amplifier type
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 78c4a324a3b5..01b95e89009a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -152,6 +152,19 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
152} 152}
153EXPORT_SYMBOL(iwlcore_eeprom_verify_signature); 153EXPORT_SYMBOL(iwlcore_eeprom_verify_signature);
154 154
155static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode)
156{
157 u32 otpgp;
158
159 otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
160 if (mode == IWL_OTP_ACCESS_ABSOLUTE)
161 iwl_clear_bit(priv, CSR_OTP_GP_REG,
162 CSR_OTP_GP_REG_OTP_ACCESS_MODE);
163 else
164 iwl_set_bit(priv, CSR_OTP_GP_REG,
165 CSR_OTP_GP_REG_OTP_ACCESS_MODE);
166}
167
155static int iwlcore_get_nvm_type(struct iwl_priv *priv) 168static int iwlcore_get_nvm_type(struct iwl_priv *priv)
156{ 169{
157 u32 otpgp; 170 u32 otpgp;
@@ -252,6 +265,124 @@ static int iwl_init_otp_access(struct iwl_priv *priv)
252 return ret; 265 return ret;
253} 266}
254 267
268static int iwl_read_otp_word(struct iwl_priv *priv, u16 addr, u16 *eeprom_data)
269{
270 int ret = 0;
271 u32 r;
272 u32 otpgp;
273
274 _iwl_write32(priv, CSR_EEPROM_REG,
275 CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
276 ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
277 CSR_EEPROM_REG_READ_VALID_MSK,
278 IWL_EEPROM_ACCESS_TIMEOUT);
279 if (ret < 0) {
280 IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
281 return ret;
282 }
283 r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
284 /* check for ECC errors: */
285 otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
286 if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
287 /* stop in this case */
288 /* set the uncorrectable OTP ECC bit for acknowledgement */
289 iwl_set_bit(priv, CSR_OTP_GP_REG,
290 CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
291 IWL_ERR(priv, "Uncorrectable OTP ECC error, abort OTP read\n");
292 return -EINVAL;
293 }
294 if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) {
295 /* continue in this case */
296 /* set the correctable OTP ECC bit for acknowledgement */
297 iwl_set_bit(priv, CSR_OTP_GP_REG,
298 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
299 IWL_ERR(priv, "Correctable OTP ECC error, continue read\n");
300 }
301 *eeprom_data = le16_to_cpu((__force __le16)(r >> 16));
302 return 0;
303}
304
305/*
306 * iwl_is_otp_empty: check for empty OTP
307 */
308static bool iwl_is_otp_empty(struct iwl_priv *priv)
309{
310 u16 next_link_addr = 0, link_value;
311 bool is_empty = false;
312
313 /* locate the beginning of OTP link list */
314 if (!iwl_read_otp_word(priv, next_link_addr, &link_value)) {
315 if (!link_value) {
316 IWL_ERR(priv, "OTP is empty\n");
317 is_empty = true;
318 }
319 } else {
320 IWL_ERR(priv, "Unable to read first block of OTP list.\n");
321 is_empty = true;
322 }
323
324 return is_empty;
325}
326
327
328/*
329 * iwl_find_otp_image: find EEPROM image in OTP
330 * finding the OTP block that contains the EEPROM image.
331 * the last valid block on the link list (the block _before_ the last block)
332 * is the block we should read and used to configure the device.
333 * If all the available OTP blocks are full, the last block will be the block
334 * we should read and used to configure the device.
335 * only perform this operation if shadow RAM is disabled
336 */
337static int iwl_find_otp_image(struct iwl_priv *priv,
338 u16 *validblockaddr)
339{
340 u16 next_link_addr = 0, link_value = 0, valid_addr;
341 int ret = 0;
342 int usedblocks = 0;
343
344 /* set addressing mode to absolute to traverse the link list */
345 iwl_set_otp_access(priv, IWL_OTP_ACCESS_ABSOLUTE);
346
347 /* checking for empty OTP or error */
348 if (iwl_is_otp_empty(priv))
349 return -EINVAL;
350
351 /*
352 * start traverse link list
353 * until reach the max number of OTP blocks
354 * different devices have different number of OTP blocks
355 */
356 do {
357 /* save current valid block address
358 * check for more block on the link list
359 */
360 valid_addr = next_link_addr;
361 next_link_addr = link_value;
362 IWL_DEBUG_INFO(priv, "OTP blocks %d addr 0x%x\n",
363 usedblocks, next_link_addr);
364 if (iwl_read_otp_word(priv, next_link_addr, &link_value))
365 return -EINVAL;
366 if (!link_value) {
367 /*
368 * reach the end of link list,
369 * set address point to the starting address
370 * of the image
371 */
372 goto done;
373 }
374 /* more in the link list, continue */
375 usedblocks++;
376 } while (usedblocks < priv->cfg->max_ll_items);
377 /* OTP full, use last block */
378 IWL_DEBUG_INFO(priv, "OTP is full, use last block\n");
379done:
380 *validblockaddr = valid_addr;
381 /* skip first 2 bytes (link list pointer) */
382 *validblockaddr += 2;
383 return ret;
384}
385
255/** 386/**
256 * iwl_eeprom_init - read EEPROM contents 387 * iwl_eeprom_init - read EEPROM contents
257 * 388 *
@@ -266,15 +397,14 @@ int iwl_eeprom_init(struct iwl_priv *priv)
266 int sz; 397 int sz;
267 int ret; 398 int ret;
268 u16 addr; 399 u16 addr;
269 u32 otpgp; 400 u16 validblockaddr = 0;
401 u16 cache_addr = 0;
270 402
271 priv->nvm_device_type = iwlcore_get_nvm_type(priv); 403 priv->nvm_device_type = iwlcore_get_nvm_type(priv);
272 if (priv->nvm_device_type == -ENOENT) 404 if (priv->nvm_device_type == -ENOENT)
273 return -ENOENT; 405 return -ENOENT;
274 /* allocate eeprom */ 406 /* allocate eeprom */
275 if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) 407 IWL_DEBUG_INFO(priv, "NVM size = %d\n", priv->cfg->eeprom_size);
276 priv->cfg->eeprom_size =
277 OTP_BLOCK_SIZE * OTP_LOWER_BLOCKS_TOTAL;
278 sz = priv->cfg->eeprom_size; 408 sz = priv->cfg->eeprom_size;
279 priv->eeprom = kzalloc(sz, GFP_KERNEL); 409 priv->eeprom = kzalloc(sz, GFP_KERNEL);
280 if (!priv->eeprom) { 410 if (!priv->eeprom) {
@@ -302,46 +432,31 @@ int iwl_eeprom_init(struct iwl_priv *priv)
302 if (ret) { 432 if (ret) {
303 IWL_ERR(priv, "Failed to initialize OTP access.\n"); 433 IWL_ERR(priv, "Failed to initialize OTP access.\n");
304 ret = -ENOENT; 434 ret = -ENOENT;
305 goto err; 435 goto done;
306 } 436 }
307 _iwl_write32(priv, CSR_EEPROM_GP, 437 _iwl_write32(priv, CSR_EEPROM_GP,
308 iwl_read32(priv, CSR_EEPROM_GP) & 438 iwl_read32(priv, CSR_EEPROM_GP) &
309 ~CSR_EEPROM_GP_IF_OWNER_MSK); 439 ~CSR_EEPROM_GP_IF_OWNER_MSK);
310 /* clear */ 440
311 _iwl_write32(priv, CSR_OTP_GP_REG, 441 iwl_set_bit(priv, CSR_OTP_GP_REG,
312 iwl_read32(priv, CSR_OTP_GP_REG) |
313 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | 442 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
314 CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); 443 CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
315 444 /* traversing the linked list if no shadow ram supported */
316 for (addr = 0; addr < sz; addr += sizeof(u16)) { 445 if (!priv->cfg->shadow_ram_support) {
317 u32 r; 446 if (iwl_find_otp_image(priv, &validblockaddr)) {
318 447 ret = -ENOENT;
319 _iwl_write32(priv, CSR_EEPROM_REG,
320 CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
321
322 ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
323 CSR_EEPROM_REG_READ_VALID_MSK,
324 IWL_EEPROM_ACCESS_TIMEOUT);
325 if (ret < 0) {
326 IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
327 goto done; 448 goto done;
328 } 449 }
329 r = _iwl_read_direct32(priv, CSR_EEPROM_REG); 450 }
330 /* check for ECC errors: */ 451 for (addr = validblockaddr; addr < validblockaddr + sz;
331 otpgp = iwl_read32(priv, CSR_OTP_GP_REG); 452 addr += sizeof(u16)) {
332 if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { 453 u16 eeprom_data;
333 /* stop in this case */ 454
334 IWL_ERR(priv, "Uncorrectable OTP ECC error, Abort OTP read\n"); 455 ret = iwl_read_otp_word(priv, addr, &eeprom_data);
456 if (ret)
335 goto done; 457 goto done;
336 } 458 e[cache_addr / 2] = eeprom_data;
337 if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { 459 cache_addr += sizeof(u16);
338 /* continue in this case */
339 _iwl_write32(priv, CSR_OTP_GP_REG,
340 iwl_read32(priv, CSR_OTP_GP_REG) |
341 CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
342 IWL_ERR(priv, "Correctable OTP ECC error, continue read\n");
343 }
344 e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
345 } 460 }
346 } else { 461 } else {
347 /* eeprom is an array of 16bit values */ 462 /* eeprom is an array of 16bit values */
@@ -484,14 +599,14 @@ static void iwl_init_band_reference(const struct iwl_priv *priv,
484 ? # x " " : "") 599 ? # x " " : "")
485 600
486/** 601/**
487 * iwl_set_ht40_chan_info - Copy ht40 channel info into driver's priv. 602 * iwl_mod_ht40_chan_info - Copy ht40 channel info into driver's priv.
488 * 603 *
489 * Does not set up a command, or touch hardware. 604 * Does not set up a command, or touch hardware.
490 */ 605 */
491static int iwl_set_ht40_chan_info(struct iwl_priv *priv, 606static int iwl_mod_ht40_chan_info(struct iwl_priv *priv,
492 enum ieee80211_band band, u16 channel, 607 enum ieee80211_band band, u16 channel,
493 const struct iwl_eeprom_channel *eeprom_ch, 608 const struct iwl_eeprom_channel *eeprom_ch,
494 u8 ht40_extension_channel) 609 u8 clear_ht40_extension_channel)
495{ 610{
496 struct iwl_channel_info *ch_info; 611 struct iwl_channel_info *ch_info;
497 612
@@ -523,7 +638,7 @@ static int iwl_set_ht40_chan_info(struct iwl_priv *priv,
523 ch_info->ht40_min_power = 0; 638 ch_info->ht40_min_power = 0;
524 ch_info->ht40_scan_power = eeprom_ch->max_power_avg; 639 ch_info->ht40_scan_power = eeprom_ch->max_power_avg;
525 ch_info->ht40_flags = eeprom_ch->flags; 640 ch_info->ht40_flags = eeprom_ch->flags;
526 ch_info->ht40_extension_channel = ht40_extension_channel; 641 ch_info->ht40_extension_channel &= ~clear_ht40_extension_channel;
527 642
528 return 0; 643 return 0;
529} 644}
@@ -592,8 +707,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
592 /* First write that ht40 is not enabled, and then enable 707 /* First write that ht40 is not enabled, and then enable
593 * one by one */ 708 * one by one */
594 ch_info->ht40_extension_channel = 709 ch_info->ht40_extension_channel =
595 (IEEE80211_CHAN_NO_HT40PLUS | 710 IEEE80211_CHAN_NO_HT40;
596 IEEE80211_CHAN_NO_HT40MINUS);
597 711
598 if (!(is_channel_valid(ch_info))) { 712 if (!(is_channel_valid(ch_info))) {
599 IWL_DEBUG_INFO(priv, "Ch. %d Flags %x [%sGHz] - " 713 IWL_DEBUG_INFO(priv, "Ch. %d Flags %x [%sGHz] - "
@@ -652,7 +766,6 @@ int iwl_init_channel_map(struct iwl_priv *priv)
652 /* Two additional EEPROM bands for 2.4 and 5 GHz HT40 channels */ 766 /* Two additional EEPROM bands for 2.4 and 5 GHz HT40 channels */
653 for (band = 6; band <= 7; band++) { 767 for (band = 6; band <= 7; band++) {
654 enum ieee80211_band ieeeband; 768 enum ieee80211_band ieeeband;
655 u8 ht40_extension_chan;
656 769
657 iwl_init_band_reference(priv, band, &eeprom_ch_count, 770 iwl_init_band_reference(priv, band, &eeprom_ch_count,
658 &eeprom_ch_info, &eeprom_ch_index); 771 &eeprom_ch_info, &eeprom_ch_index);
@@ -663,28 +776,17 @@ int iwl_init_channel_map(struct iwl_priv *priv)
663 776
664 /* Loop through each band adding each of the channels */ 777 /* Loop through each band adding each of the channels */
665 for (ch = 0; ch < eeprom_ch_count; ch++) { 778 for (ch = 0; ch < eeprom_ch_count; ch++) {
666
667 if ((band == 6) &&
668 ((eeprom_ch_index[ch] == 5) ||
669 (eeprom_ch_index[ch] == 6) ||
670 (eeprom_ch_index[ch] == 7)))
671 /* both are allowed: above and below */
672 ht40_extension_chan = 0;
673 else
674 ht40_extension_chan =
675 IEEE80211_CHAN_NO_HT40MINUS;
676
677 /* Set up driver's info for lower half */ 779 /* Set up driver's info for lower half */
678 iwl_set_ht40_chan_info(priv, ieeeband, 780 iwl_mod_ht40_chan_info(priv, ieeeband,
679 eeprom_ch_index[ch], 781 eeprom_ch_index[ch],
680 &(eeprom_ch_info[ch]), 782 &eeprom_ch_info[ch],
681 ht40_extension_chan); 783 IEEE80211_CHAN_NO_HT40PLUS);
682 784
683 /* Set up driver's info for upper half */ 785 /* Set up driver's info for upper half */
684 iwl_set_ht40_chan_info(priv, ieeeband, 786 iwl_mod_ht40_chan_info(priv, ieeeband,
685 (eeprom_ch_index[ch] + 4), 787 eeprom_ch_index[ch] + 4,
686 &(eeprom_ch_info[ch]), 788 &eeprom_ch_info[ch],
687 IEEE80211_CHAN_NO_HT40PLUS); 789 IEEE80211_CHAN_NO_HT40MINUS);
688 } 790 }
689 } 791 }
690 792
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index 05d4fc4451dc..ca7920a8f52f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -180,8 +180,14 @@ struct iwl_eeprom_channel {
180#define EEPROM_5050_EEPROM_VERSION (0x21E) 180#define EEPROM_5050_EEPROM_VERSION (0x21E)
181 181
182/* OTP */ 182/* OTP */
183#define OTP_LOWER_BLOCKS_TOTAL (3) 183/* lower blocks contain EEPROM image and calibration data */
184#define OTP_BLOCK_SIZE (0x400) 184#define OTP_LOW_IMAGE_SIZE (2 * 512 * sizeof(u16)) /* 2 KB */
185/* high blocks contain PAPD data */
186#define OTP_HIGH_IMAGE_SIZE_6x00 (6 * 512 * sizeof(u16)) /* 6 KB */
187#define OTP_HIGH_IMAGE_SIZE_1000 (0x200 * sizeof(u16)) /* 1024 bytes */
188#define OTP_MAX_LL_ITEMS_1000 (3) /* OTP blocks for 1000 */
189#define OTP_MAX_LL_ITEMS_6x00 (4) /* OTP blocks for 6x00 */
190#define OTP_MAX_LL_ITEMS_6x50 (7) /* OTP blocks for 6x50 */
185 191
186/* 2.4 GHz */ 192/* 2.4 GHz */
187extern const u8 iwl_eeprom_band_1[14]; 193extern const u8 iwl_eeprom_band_1[14];
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 43b2fce4cbf0..353d9a2ddbca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -539,7 +539,8 @@ void iwl_rx_statistics(struct iwl_priv *priv,
539 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 539 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
540 540
541 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", 541 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
542 (int)sizeof(priv->statistics), pkt->len); 542 (int)sizeof(priv->statistics),
543 le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
543 544
544 change = ((priv->statistics.general.temperature != 545 change = ((priv->statistics.general.temperature !=
545 pkt->u.stats.general.temperature) || 546 pkt->u.stats.general.temperature) ||
@@ -853,61 +854,12 @@ static u32 iwl_translate_rx_status(struct iwl_priv *priv, u32 decrypt_in)
853} 854}
854 855
855static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, 856static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
856 int include_phy, 857 struct ieee80211_hdr *hdr,
857 struct iwl_rx_mem_buffer *rxb, 858 u16 len,
858 struct ieee80211_rx_status *stats) 859 u32 ampdu_status,
860 struct iwl_rx_mem_buffer *rxb,
861 struct ieee80211_rx_status *stats)
859{ 862{
860 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
861 struct iwl_rx_phy_res *rx_start = (include_phy) ?
862 (struct iwl_rx_phy_res *)&(pkt->u.raw[0]) : NULL;
863 struct ieee80211_hdr *hdr;
864 u16 len;
865 __le32 *rx_end;
866 unsigned int skblen;
867 u32 ampdu_status;
868 u32 ampdu_status_legacy;
869
870 if (!include_phy && priv->last_phy_res[0])
871 rx_start = (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
872
873 if (!rx_start) {
874 IWL_ERR(priv, "MPDU frame without a PHY data\n");
875 return;
876 }
877 if (include_phy) {
878 hdr = (struct ieee80211_hdr *)((u8 *) &rx_start[1] +
879 rx_start->cfg_phy_cnt);
880
881 len = le16_to_cpu(rx_start->byte_count);
882
883 rx_end = (__le32 *)((u8 *) &pkt->u.raw[0] +
884 sizeof(struct iwl_rx_phy_res) +
885 rx_start->cfg_phy_cnt + len);
886
887 } else {
888 struct iwl4965_rx_mpdu_res_start *amsdu =
889 (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
890
891 hdr = (struct ieee80211_hdr *)(pkt->u.raw +
892 sizeof(struct iwl4965_rx_mpdu_res_start));
893 len = le16_to_cpu(amsdu->byte_count);
894 rx_start->byte_count = amsdu->byte_count;
895 rx_end = (__le32 *) (((u8 *) hdr) + len);
896 }
897
898 ampdu_status = le32_to_cpu(*rx_end);
899 skblen = ((u8 *) rx_end - (u8 *) &pkt->u.raw[0]) + sizeof(u32);
900
901 if (!include_phy) {
902 /* New status scheme, need to translate */
903 ampdu_status_legacy = ampdu_status;
904 ampdu_status = iwl_translate_rx_status(priv, ampdu_status);
905 }
906
907 /* start from MAC */
908 skb_reserve(rxb->skb, (void *)hdr - (void *)pkt);
909 skb_put(rxb->skb, len); /* end where data ends */
910
911 /* We only process data packets if the interface is open */ 863 /* We only process data packets if the interface is open */
912 if (unlikely(!priv->is_open)) { 864 if (unlikely(!priv->is_open)) {
913 IWL_DEBUG_DROP_LIMIT(priv, 865 IWL_DEBUG_DROP_LIMIT(priv,
@@ -915,13 +867,15 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
915 return; 867 return;
916 } 868 }
917 869
918 hdr = (struct ieee80211_hdr *)rxb->skb->data; 870 /* In case of HW accelerated crypto and bad decryption, drop */
919
920 /* in case of HW accelerated crypto and bad decryption, drop */
921 if (!priv->cfg->mod_params->sw_crypto && 871 if (!priv->cfg->mod_params->sw_crypto &&
922 iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) 872 iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
923 return; 873 return;
924 874
875 /* Resize SKB from mac header to end of packet */
876 skb_reserve(rxb->skb, (void *)hdr - (void *)rxb->skb->data);
877 skb_put(rxb->skb, len);
878
925 iwl_update_stats(priv, false, hdr->frame_control, len); 879 iwl_update_stats(priv, false, hdr->frame_control, len);
926 memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats)); 880 memcpy(IEEE80211_SKB_RXCB(rxb->skb), stats, sizeof(*stats));
927 ieee80211_rx_irqsafe(priv->hw, rxb->skb); 881 ieee80211_rx_irqsafe(priv->hw, rxb->skb);
@@ -955,25 +909,66 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
955 struct ieee80211_hdr *header; 909 struct ieee80211_hdr *header;
956 struct ieee80211_rx_status rx_status; 910 struct ieee80211_rx_status rx_status;
957 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 911 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
958 /* Use phy data (Rx signal strength, etc.) contained within 912 struct iwl_rx_phy_res *phy_res;
959 * this rx packet for legacy frames, 913 __le32 rx_pkt_status;
960 * or phy data cached from REPLY_RX_PHY_CMD for HT frames. */ 914 struct iwl4965_rx_mpdu_res_start *amsdu;
961 int include_phy = (pkt->hdr.cmd == REPLY_RX); 915 u32 len;
962 struct iwl_rx_phy_res *rx_start = (include_phy) ? 916 u32 ampdu_status;
963 (struct iwl_rx_phy_res *)&(pkt->u.raw[0]) :
964 (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
965 __le32 *rx_end;
966 unsigned int len = 0;
967 u16 fc; 917 u16 fc;
968 u8 network_packet;
969 918
970 rx_status.mactime = le64_to_cpu(rx_start->timestamp); 919 /**
920 * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently.
921 * REPLY_RX: physical layer info is in this buffer
922 * REPLY_RX_MPDU_CMD: physical layer info was sent in separate
923 * command and cached in priv->last_phy_res
924 *
925 * Here we set up local variables depending on which command is
926 * received.
927 */
928 if (pkt->hdr.cmd == REPLY_RX) {
929 phy_res = (struct iwl_rx_phy_res *)pkt->u.raw;
930 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*phy_res)
931 + phy_res->cfg_phy_cnt);
932
933 len = le16_to_cpu(phy_res->byte_count);
934 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*phy_res) +
935 phy_res->cfg_phy_cnt + len);
936 ampdu_status = le32_to_cpu(rx_pkt_status);
937 } else {
938 if (!priv->last_phy_res[0]) {
939 IWL_ERR(priv, "MPDU frame without cached PHY data\n");
940 return;
941 }
942 phy_res = (struct iwl_rx_phy_res *)&priv->last_phy_res[1];
943 amsdu = (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
944 header = (struct ieee80211_hdr *)(pkt->u.raw + sizeof(*amsdu));
945 len = le16_to_cpu(amsdu->byte_count);
946 rx_pkt_status = *(__le32 *)(pkt->u.raw + sizeof(*amsdu) + len);
947 ampdu_status = iwl_translate_rx_status(priv,
948 le32_to_cpu(rx_pkt_status));
949 }
950
951 if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
952 IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
953 phy_res->cfg_phy_cnt);
954 return;
955 }
956
957 if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) ||
958 !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
959 IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
960 le32_to_cpu(rx_pkt_status));
961 return;
962 }
963
964 /* rx_status carries information about the packet to mac80211 */
965 rx_status.mactime = le64_to_cpu(phy_res->timestamp);
971 rx_status.freq = 966 rx_status.freq =
972 ieee80211_channel_to_frequency(le16_to_cpu(rx_start->channel)); 967 ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel));
973 rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? 968 rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
974 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; 969 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
975 rx_status.rate_idx = 970 rx_status.rate_idx =
976 iwl_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags)); 971 iwl_hwrate_to_plcp_idx(le32_to_cpu(phy_res->rate_n_flags));
977 if (rx_status.band == IEEE80211_BAND_5GHZ) 972 if (rx_status.band == IEEE80211_BAND_5GHZ)
978 rx_status.rate_idx -= IWL_FIRST_OFDM_RATE; 973 rx_status.rate_idx -= IWL_FIRST_OFDM_RATE;
979 974
@@ -983,54 +978,10 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
983 * this W/A doesn't propagate it to the mac80211 */ 978 * this W/A doesn't propagate it to the mac80211 */
984 /*rx_status.flag |= RX_FLAG_TSFT;*/ 979 /*rx_status.flag |= RX_FLAG_TSFT;*/
985 980
986 if ((unlikely(rx_start->cfg_phy_cnt > 20))) { 981 priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
987 IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
988 rx_start->cfg_phy_cnt);
989 return;
990 }
991
992 if (!include_phy) {
993 if (priv->last_phy_res[0])
994 rx_start = (struct iwl_rx_phy_res *)
995 &priv->last_phy_res[1];
996 else
997 rx_start = NULL;
998 }
999
1000 if (!rx_start) {
1001 IWL_ERR(priv, "MPDU frame without a PHY data\n");
1002 return;
1003 }
1004
1005 if (include_phy) {
1006 header = (struct ieee80211_hdr *)((u8 *) &rx_start[1]
1007 + rx_start->cfg_phy_cnt);
1008
1009 len = le16_to_cpu(rx_start->byte_count);
1010 rx_end = (__le32 *)(pkt->u.raw + rx_start->cfg_phy_cnt +
1011 sizeof(struct iwl_rx_phy_res) + len);
1012 } else {
1013 struct iwl4965_rx_mpdu_res_start *amsdu =
1014 (struct iwl4965_rx_mpdu_res_start *)pkt->u.raw;
1015
1016 header = (void *)(pkt->u.raw +
1017 sizeof(struct iwl4965_rx_mpdu_res_start));
1018 len = le16_to_cpu(amsdu->byte_count);
1019 rx_end = (__le32 *) (pkt->u.raw +
1020 sizeof(struct iwl4965_rx_mpdu_res_start) + len);
1021 }
1022
1023 if (!(*rx_end & RX_RES_STATUS_NO_CRC32_ERROR) ||
1024 !(*rx_end & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
1025 IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
1026 le32_to_cpu(*rx_end));
1027 return;
1028 }
1029
1030 priv->ucode_beacon_time = le32_to_cpu(rx_start->beacon_time_stamp);
1031 982
1032 /* Find max signal strength (dBm) among 3 antenna/receiver chains */ 983 /* Find max signal strength (dBm) among 3 antenna/receiver chains */
1033 rx_status.signal = iwl_calc_rssi(priv, rx_start); 984 rx_status.signal = iwl_calc_rssi(priv, phy_res);
1034 985
1035 /* Meaningful noise values are available only from beacon statistics, 986 /* Meaningful noise values are available only from beacon statistics,
1036 * which are gathered only when associated, and indicate noise 987 * which are gathered only when associated, and indicate noise
@@ -1050,10 +1001,10 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
1050 if (!iwl_is_associated(priv)) 1001 if (!iwl_is_associated(priv))
1051 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE; 1002 priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
1052 1003
1053 /* Set "1" to report good data frames in groups of 100 */
1054#ifdef CONFIG_IWLWIFI_DEBUG 1004#ifdef CONFIG_IWLWIFI_DEBUG
1005 /* Set "1" to report good data frames in groups of 100 */
1055 if (unlikely(iwl_get_debug_level(priv) & IWL_DL_RX)) 1006 if (unlikely(iwl_get_debug_level(priv) & IWL_DL_RX))
1056 iwl_dbg_report_frame(priv, rx_start, len, header, 1); 1007 iwl_dbg_report_frame(priv, phy_res, len, header, 1);
1057#endif 1008#endif
1058 iwl_dbg_log_rx_data_frame(priv, len, header); 1009 iwl_dbg_log_rx_data_frame(priv, len, header);
1059 IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, qual %d, TSF %llu\n", 1010 IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, qual %d, TSF %llu\n",
@@ -1073,18 +1024,18 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
1073 * new 802.11n radiotap field "RX chains" that is defined 1024 * new 802.11n radiotap field "RX chains" that is defined
1074 * as a bitmask. 1025 * as a bitmask.
1075 */ 1026 */
1076 rx_status.antenna = le16_to_cpu(rx_start->phy_flags & 1027 rx_status.antenna =
1077 RX_RES_PHY_FLAGS_ANTENNA_MSK) >> 4; 1028 le16_to_cpu(phy_res->phy_flags & RX_RES_PHY_FLAGS_ANTENNA_MSK)
1029 >> RX_RES_PHY_FLAGS_ANTENNA_POS;
1078 1030
1079 /* set the preamble flag if appropriate */ 1031 /* set the preamble flag if appropriate */
1080 if (rx_start->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK) 1032 if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
1081 rx_status.flag |= RX_FLAG_SHORTPRE; 1033 rx_status.flag |= RX_FLAG_SHORTPRE;
1082 1034
1083 network_packet = iwl_is_network_packet(priv, header); 1035 if (iwl_is_network_packet(priv, header)) {
1084 if (network_packet) {
1085 priv->last_rx_rssi = rx_status.signal; 1036 priv->last_rx_rssi = rx_status.signal;
1086 priv->last_beacon_time = priv->ucode_beacon_time; 1037 priv->last_beacon_time = priv->ucode_beacon_time;
1087 priv->last_tsf = le64_to_cpu(rx_start->timestamp); 1038 priv->last_tsf = le64_to_cpu(phy_res->timestamp);
1088 } 1039 }
1089 1040
1090 fc = le16_to_cpu(header->frame_control); 1041 fc = le16_to_cpu(header->frame_control);
@@ -1096,8 +1047,8 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
1096 header->addr2); 1047 header->addr2);
1097 /* fall through */ 1048 /* fall through */
1098 default: 1049 default:
1099 iwl_pass_packet_to_mac80211(priv, include_phy, rxb, 1050 iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status,
1100 &rx_status); 1051 rxb, &rx_status);
1101 break; 1052 break;
1102 1053
1103 } 1054 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 9b76bd41f214..7686fc72eb89 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -745,6 +745,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
745 if (ieee80211_is_data_qos(fc)) { 745 if (ieee80211_is_data_qos(fc)) {
746 qc = ieee80211_get_qos_ctl(hdr); 746 qc = ieee80211_get_qos_ctl(hdr);
747 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 747 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
748 if (unlikely(tid >= MAX_TID_COUNT))
749 goto drop_unlock;
748 seq_number = priv->stations[sta_id].tid[tid].seq_number; 750 seq_number = priv->stations[sta_id].tid[tid].seq_number;
749 seq_number &= IEEE80211_SCTL_SEQ; 751 seq_number &= IEEE80211_SCTL_SEQ;
750 hdr->seq_ctrl = hdr->seq_ctrl & 752 hdr->seq_ctrl = hdr->seq_ctrl &
@@ -1238,6 +1240,9 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
1238 return -EINVAL; 1240 return -EINVAL;
1239 } 1241 }
1240 1242
1243 if (unlikely(tid >= MAX_TID_COUNT))
1244 return -EINVAL;
1245
1241 if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo))) 1246 if (likely(tid < ARRAY_SIZE(default_tid_to_tx_fifo)))
1242 tx_fifo_id = default_tid_to_tx_fifo[tid]; 1247 tx_fifo_id = default_tid_to_tx_fifo[tid];
1243 else 1248 else
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index e617411d0c5e..f339c5bd1fde 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -544,6 +544,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
544 if (ieee80211_is_data_qos(fc)) { 544 if (ieee80211_is_data_qos(fc)) {
545 qc = ieee80211_get_qos_ctl(hdr); 545 qc = ieee80211_get_qos_ctl(hdr);
546 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 546 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
547 if (unlikely(tid >= MAX_TID_COUNT))
548 goto drop;
547 seq_number = priv->stations[sta_id].tid[tid].seq_number & 549 seq_number = priv->stations[sta_id].tid[tid].seq_number &
548 IEEE80211_SCTL_SEQ; 550 IEEE80211_SCTL_SEQ;
549 hdr->seq_ctrl = cpu_to_le16(seq_number) | 551 hdr->seq_ctrl = cpu_to_le16(seq_number) |
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index 385b50f4b105..81f86ef26990 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -45,9 +45,14 @@ static int get_common_rates(struct lbs_private *priv,
45 u8 *card_rates = lbs_bg_rates; 45 u8 *card_rates = lbs_bg_rates;
46 size_t num_card_rates = sizeof(lbs_bg_rates); 46 size_t num_card_rates = sizeof(lbs_bg_rates);
47 int ret = 0, i, j; 47 int ret = 0, i, j;
48 u8 tmp[30]; 48 u8 *tmp;
49 size_t tmp_size = 0; 49 size_t tmp_size = 0;
50 50
51 tmp = kzalloc((ARRAY_SIZE(lbs_bg_rates) - 1) * (*rates_size - 1),
52 GFP_KERNEL);
53 if (!tmp)
54 return -1;
55
51 /* For each rate in card_rates that exists in rate1, copy to tmp */ 56 /* For each rate in card_rates that exists in rate1, copy to tmp */
52 for (i = 0; card_rates[i] && (i < num_card_rates); i++) { 57 for (i = 0; card_rates[i] && (i < num_card_rates); i++) {
53 for (j = 0; rates[j] && (j < *rates_size); j++) { 58 for (j = 0; rates[j] && (j < *rates_size); j++) {
@@ -77,6 +82,7 @@ done:
77 memset(rates, 0, *rates_size); 82 memset(rates, 0, *rates_size);
78 *rates_size = min_t(int, tmp_size, *rates_size); 83 *rates_size = min_t(int, tmp_size, *rates_size);
79 memcpy(rates, tmp, *rates_size); 84 memcpy(rates, tmp, *rates_size);
85 kfree(tmp);
80 return ret; 86 return ret;
81} 87}
82 88
diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c
index 4872345a2f61..019431d2f8a9 100644
--- a/drivers/net/wireless/libertas_tf/main.c
+++ b/drivers/net/wireless/libertas_tf/main.c
@@ -366,15 +366,35 @@ static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed)
366 return 0; 366 return 0;
367} 367}
368 368
369static u64 lbtf_op_prepare_multicast(struct ieee80211_hw *hw,
370 int mc_count, struct dev_addr_list *mclist)
371{
372 struct lbtf_private *priv = hw->priv;
373 int i;
374
375 if (!mc_count || mc_count > MRVDRV_MAX_MULTICAST_LIST_SIZE)
376 return mc_count;
377
378 priv->nr_of_multicastmacaddr = mc_count;
379 for (i = 0; i < mc_count; i++) {
380 if (!mclist)
381 break;
382 memcpy(&priv->multicastlist[i], mclist->da_addr,
383 ETH_ALEN);
384 mclist = mclist->next;
385 }
386
387 return mc_count;
388}
389
369#define SUPPORTED_FIF_FLAGS (FIF_PROMISC_IN_BSS | FIF_ALLMULTI) 390#define SUPPORTED_FIF_FLAGS (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)
370static void lbtf_op_configure_filter(struct ieee80211_hw *hw, 391static void lbtf_op_configure_filter(struct ieee80211_hw *hw,
371 unsigned int changed_flags, 392 unsigned int changed_flags,
372 unsigned int *new_flags, 393 unsigned int *new_flags,
373 int mc_count, struct dev_mc_list *mclist) 394 u64 multicast)
374{ 395{
375 struct lbtf_private *priv = hw->priv; 396 struct lbtf_private *priv = hw->priv;
376 int old_mac_control = priv->mac_control; 397 int old_mac_control = priv->mac_control;
377 int i;
378 changed_flags &= SUPPORTED_FIF_FLAGS; 398 changed_flags &= SUPPORTED_FIF_FLAGS;
379 *new_flags &= SUPPORTED_FIF_FLAGS; 399 *new_flags &= SUPPORTED_FIF_FLAGS;
380 400
@@ -386,20 +406,12 @@ static void lbtf_op_configure_filter(struct ieee80211_hw *hw,
386 else 406 else
387 priv->mac_control &= ~CMD_ACT_MAC_PROMISCUOUS_ENABLE; 407 priv->mac_control &= ~CMD_ACT_MAC_PROMISCUOUS_ENABLE;
388 if (*new_flags & (FIF_ALLMULTI) || 408 if (*new_flags & (FIF_ALLMULTI) ||
389 mc_count > MRVDRV_MAX_MULTICAST_LIST_SIZE) { 409 multicast > MRVDRV_MAX_MULTICAST_LIST_SIZE) {
390 priv->mac_control |= CMD_ACT_MAC_ALL_MULTICAST_ENABLE; 410 priv->mac_control |= CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
391 priv->mac_control &= ~CMD_ACT_MAC_MULTICAST_ENABLE; 411 priv->mac_control &= ~CMD_ACT_MAC_MULTICAST_ENABLE;
392 } else if (mc_count) { 412 } else if (multicast) {
393 priv->mac_control |= CMD_ACT_MAC_MULTICAST_ENABLE; 413 priv->mac_control |= CMD_ACT_MAC_MULTICAST_ENABLE;
394 priv->mac_control &= ~CMD_ACT_MAC_ALL_MULTICAST_ENABLE; 414 priv->mac_control &= ~CMD_ACT_MAC_ALL_MULTICAST_ENABLE;
395 priv->nr_of_multicastmacaddr = mc_count;
396 for (i = 0; i < mc_count; i++) {
397 if (!mclist)
398 break;
399 memcpy(&priv->multicastlist[i], mclist->da_addr,
400 ETH_ALEN);
401 mclist = mclist->next;
402 }
403 lbtf_cmd_set_mac_multicast_addr(priv); 415 lbtf_cmd_set_mac_multicast_addr(priv);
404 } else { 416 } else {
405 priv->mac_control &= ~(CMD_ACT_MAC_MULTICAST_ENABLE | 417 priv->mac_control &= ~(CMD_ACT_MAC_MULTICAST_ENABLE |
@@ -461,6 +473,7 @@ static const struct ieee80211_ops lbtf_ops = {
461 .add_interface = lbtf_op_add_interface, 473 .add_interface = lbtf_op_add_interface,
462 .remove_interface = lbtf_op_remove_interface, 474 .remove_interface = lbtf_op_remove_interface,
463 .config = lbtf_op_config, 475 .config = lbtf_op_config,
476 .prepare_multicast = lbtf_op_prepare_multicast,
464 .configure_filter = lbtf_op_configure_filter, 477 .configure_filter = lbtf_op_configure_filter,
465 .bss_info_changed = lbtf_op_bss_info_changed, 478 .bss_info_changed = lbtf_op_bss_info_changed,
466}; 479};
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 930f5c7da4a6..6f6cd43592c8 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -582,9 +582,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
582 582
583static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw, 583static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw,
584 unsigned int changed_flags, 584 unsigned int changed_flags,
585 unsigned int *total_flags, 585 unsigned int *total_flags,u64 multicast)
586 int mc_count,
587 struct dev_addr_list *mc_list)
588{ 586{
589 struct mac80211_hwsim_data *data = hw->priv; 587 struct mac80211_hwsim_data *data = hw->priv;
590 588
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 8a6d3afe4122..41a708ce8730 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * drivers/net/wireless/mwl8k.c driver for Marvell TOPDOG 802.11 Wireless cards 2 * drivers/net/wireless/mwl8k.c
3 * Driver for Marvell TOPDOG 802.11 Wireless cards
3 * 4 *
4 * Copyright (C) 2008 Marvell Semiconductor Inc. 5 * Copyright (C) 2008-2009 Marvell Semiconductor Inc.
5 * 6 *
6 * This file is licensed under the terms of the GNU General Public 7 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any 8 * License version 2. This program is licensed "as is" without any
@@ -24,7 +25,7 @@
24 25
25#define MWL8K_DESC "Marvell TOPDOG(R) 802.11 Wireless Network Driver" 26#define MWL8K_DESC "Marvell TOPDOG(R) 802.11 Wireless Network Driver"
26#define MWL8K_NAME KBUILD_MODNAME 27#define MWL8K_NAME KBUILD_MODNAME
27#define MWL8K_VERSION "0.9.1" 28#define MWL8K_VERSION "0.10"
28 29
29MODULE_DESCRIPTION(MWL8K_DESC); 30MODULE_DESCRIPTION(MWL8K_DESC);
30MODULE_VERSION(MWL8K_VERSION); 31MODULE_VERSION(MWL8K_VERSION);
@@ -38,16 +39,14 @@ static DEFINE_PCI_DEVICE_TABLE(mwl8k_table) = {
38}; 39};
39MODULE_DEVICE_TABLE(pci, mwl8k_table); 40MODULE_DEVICE_TABLE(pci, mwl8k_table);
40 41
41#define IEEE80211_ADDR_LEN ETH_ALEN
42
43/* Register definitions */ 42/* Register definitions */
44#define MWL8K_HIU_GEN_PTR 0x00000c10 43#define MWL8K_HIU_GEN_PTR 0x00000c10
45#define MWL8K_MODE_STA 0x0000005a 44#define MWL8K_MODE_STA 0x0000005a
46#define MWL8K_MODE_AP 0x000000a5 45#define MWL8K_MODE_AP 0x000000a5
47#define MWL8K_HIU_INT_CODE 0x00000c14 46#define MWL8K_HIU_INT_CODE 0x00000c14
48#define MWL8K_FWSTA_READY 0xf0f1f2f4 47#define MWL8K_FWSTA_READY 0xf0f1f2f4
49#define MWL8K_FWAP_READY 0xf1f2f4a5 48#define MWL8K_FWAP_READY 0xf1f2f4a5
50#define MWL8K_INT_CODE_CMD_FINISHED 0x00000005 49#define MWL8K_INT_CODE_CMD_FINISHED 0x00000005
51#define MWL8K_HIU_SCRATCH 0x00000c40 50#define MWL8K_HIU_SCRATCH 0x00000c40
52 51
53/* Host->device communications */ 52/* Host->device communications */
@@ -56,11 +55,10 @@ MODULE_DEVICE_TABLE(pci, mwl8k_table);
56#define MWL8K_HIU_H2A_INTERRUPT_MASK 0x00000c20 55#define MWL8K_HIU_H2A_INTERRUPT_MASK 0x00000c20
57#define MWL8K_HIU_H2A_INTERRUPT_CLEAR_SEL 0x00000c24 56#define MWL8K_HIU_H2A_INTERRUPT_CLEAR_SEL 0x00000c24
58#define MWL8K_HIU_H2A_INTERRUPT_STATUS_MASK 0x00000c28 57#define MWL8K_HIU_H2A_INTERRUPT_STATUS_MASK 0x00000c28
59#define MWL8K_H2A_INT_DUMMY (1 << 20) 58#define MWL8K_H2A_INT_DUMMY (1 << 20)
60#define MWL8K_H2A_INT_RESET (1 << 15) 59#define MWL8K_H2A_INT_RESET (1 << 15)
61#define MWL8K_H2A_INT_PS (1 << 2) 60#define MWL8K_H2A_INT_DOORBELL (1 << 1)
62#define MWL8K_H2A_INT_DOORBELL (1 << 1) 61#define MWL8K_H2A_INT_PPA_READY (1 << 0)
63#define MWL8K_H2A_INT_PPA_READY (1 << 0)
64 62
65/* Device->host communications */ 63/* Device->host communications */
66#define MWL8K_HIU_A2H_INTERRUPT_EVENTS 0x00000c2c 64#define MWL8K_HIU_A2H_INTERRUPT_EVENTS 0x00000c2c
@@ -68,16 +66,16 @@ MODULE_DEVICE_TABLE(pci, mwl8k_table);
68#define MWL8K_HIU_A2H_INTERRUPT_MASK 0x00000c34 66#define MWL8K_HIU_A2H_INTERRUPT_MASK 0x00000c34
69#define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL 0x00000c38 67#define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL 0x00000c38
70#define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK 0x00000c3c 68#define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK 0x00000c3c
71#define MWL8K_A2H_INT_DUMMY (1 << 20) 69#define MWL8K_A2H_INT_DUMMY (1 << 20)
72#define MWL8K_A2H_INT_CHNL_SWITCHED (1 << 11) 70#define MWL8K_A2H_INT_CHNL_SWITCHED (1 << 11)
73#define MWL8K_A2H_INT_QUEUE_EMPTY (1 << 10) 71#define MWL8K_A2H_INT_QUEUE_EMPTY (1 << 10)
74#define MWL8K_A2H_INT_RADAR_DETECT (1 << 7) 72#define MWL8K_A2H_INT_RADAR_DETECT (1 << 7)
75#define MWL8K_A2H_INT_RADIO_ON (1 << 6) 73#define MWL8K_A2H_INT_RADIO_ON (1 << 6)
76#define MWL8K_A2H_INT_RADIO_OFF (1 << 5) 74#define MWL8K_A2H_INT_RADIO_OFF (1 << 5)
77#define MWL8K_A2H_INT_MAC_EVENT (1 << 3) 75#define MWL8K_A2H_INT_MAC_EVENT (1 << 3)
78#define MWL8K_A2H_INT_OPC_DONE (1 << 2) 76#define MWL8K_A2H_INT_OPC_DONE (1 << 2)
79#define MWL8K_A2H_INT_RX_READY (1 << 1) 77#define MWL8K_A2H_INT_RX_READY (1 << 1)
80#define MWL8K_A2H_INT_TX_DONE (1 << 0) 78#define MWL8K_A2H_INT_TX_DONE (1 << 0)
81 79
82#define MWL8K_A2H_EVENTS (MWL8K_A2H_INT_DUMMY | \ 80#define MWL8K_A2H_EVENTS (MWL8K_A2H_INT_DUMMY | \
83 MWL8K_A2H_INT_CHNL_SWITCHED | \ 81 MWL8K_A2H_INT_CHNL_SWITCHED | \
@@ -113,17 +111,6 @@ struct mwl8k_rx_queue {
113 struct sk_buff **rx_skb; 111 struct sk_buff **rx_skb;
114}; 112};
115 113
116struct mwl8k_skb {
117 /*
118 * The DMA engine requires a modification to the payload.
119 * If the skbuff is shared/cloned, it needs to be unshared.
120 * This method is used to ensure the stack always gets back
121 * the skbuff it sent for transmission.
122 */
123 struct sk_buff *clone;
124 struct sk_buff *skb;
125};
126
127struct mwl8k_tx_queue { 114struct mwl8k_tx_queue {
128 /* hw transmits here */ 115 /* hw transmits here */
129 int tx_head; 116 int tx_head;
@@ -134,7 +121,7 @@ struct mwl8k_tx_queue {
134 struct ieee80211_tx_queue_stats tx_stats; 121 struct ieee80211_tx_queue_stats tx_stats;
135 struct mwl8k_tx_desc *tx_desc_area; 122 struct mwl8k_tx_desc *tx_desc_area;
136 dma_addr_t tx_desc_dma; 123 dma_addr_t tx_desc_dma;
137 struct mwl8k_skb *tx_skb; 124 struct sk_buff **tx_skb;
138}; 125};
139 126
140/* Pointers to the firmware data and meta information about it. */ 127/* Pointers to the firmware data and meta information about it. */
@@ -152,19 +139,22 @@ struct mwl8k_priv {
152 139
153 struct pci_dev *pdev; 140 struct pci_dev *pdev;
154 u8 name[16]; 141 u8 name[16];
155 /* firmware access lock */
156 spinlock_t fw_lock;
157 142
158 /* firmware files and meta data */ 143 /* firmware files and meta data */
159 struct mwl8k_firmware fw; 144 struct mwl8k_firmware fw;
160 u32 part_num; 145 u32 part_num;
161 146
147 /* firmware access */
148 struct mutex fw_mutex;
149 struct task_struct *fw_mutex_owner;
150 int fw_mutex_depth;
151 struct completion *tx_wait;
152 struct completion *hostcmd_wait;
153
162 /* lock held over TX and TX reap */ 154 /* lock held over TX and TX reap */
163 spinlock_t tx_lock; 155 spinlock_t tx_lock;
164 u32 int_mask;
165 156
166 struct ieee80211_vif *vif; 157 struct ieee80211_vif *vif;
167 struct list_head vif_list;
168 158
169 struct ieee80211_channel *current_channel; 159 struct ieee80211_channel *current_channel;
170 160
@@ -173,10 +163,8 @@ struct mwl8k_priv {
173 dma_addr_t cookie_dma; 163 dma_addr_t cookie_dma;
174 164
175 u16 num_mcaddrs; 165 u16 num_mcaddrs;
176 u16 region_code;
177 u8 hw_rev; 166 u8 hw_rev;
178 __le32 fw_rev; 167 __le32 fw_rev;
179 u32 wep_enabled;
180 168
181 /* 169 /*
182 * Running count of TX packets in flight, to avoid 170 * Running count of TX packets in flight, to avoid
@@ -192,19 +180,13 @@ struct mwl8k_priv {
192 struct ieee80211_channel channels[14]; 180 struct ieee80211_channel channels[14];
193 struct ieee80211_rate rates[12]; 181 struct ieee80211_rate rates[12];
194 182
195 /* RF preamble: Short, Long or Auto */ 183 bool radio_on;
196 u8 radio_preamble; 184 bool radio_short_preamble;
197 u8 radio_state; 185 bool wmm_enabled;
198
199 /* WMM MODE 1 for enabled; 0 for disabled */
200 bool wmm_mode;
201
202 /* Set if PHY config is in progress */
203 bool inconfig;
204 186
205 /* XXX need to convert this to handle multiple interfaces */ 187 /* XXX need to convert this to handle multiple interfaces */
206 bool capture_beacon; 188 bool capture_beacon;
207 u8 capture_bssid[IEEE80211_ADDR_LEN]; 189 u8 capture_bssid[ETH_ALEN];
208 struct sk_buff *beacon_skb; 190 struct sk_buff *beacon_skb;
209 191
210 /* 192 /*
@@ -220,14 +202,10 @@ struct mwl8k_priv {
220 202
221 /* Work thread to serialize configuration requests */ 203 /* Work thread to serialize configuration requests */
222 struct workqueue_struct *config_wq; 204 struct workqueue_struct *config_wq;
223 struct completion *hostcmd_wait;
224 struct completion *tx_wait;
225}; 205};
226 206
227/* Per interface specific private data */ 207/* Per interface specific private data */
228struct mwl8k_vif { 208struct mwl8k_vif {
229 struct list_head node;
230
231 /* backpointer to parent config block */ 209 /* backpointer to parent config block */
232 struct mwl8k_priv *priv; 210 struct mwl8k_priv *priv;
233 211
@@ -235,8 +213,8 @@ struct mwl8k_vif {
235 struct ieee80211_bss_conf bss_info; 213 struct ieee80211_bss_conf bss_info;
236 214
237 /* BSSID of AP or IBSS */ 215 /* BSSID of AP or IBSS */
238 u8 bssid[IEEE80211_ADDR_LEN]; 216 u8 bssid[ETH_ALEN];
239 u8 mac_addr[IEEE80211_ADDR_LEN]; 217 u8 mac_addr[ETH_ALEN];
240 218
241 /* 219 /*
242 * Subset of supported legacy rates. 220 * Subset of supported legacy rates.
@@ -247,18 +225,11 @@ struct mwl8k_vif {
247 /* number of supported legacy rates */ 225 /* number of supported legacy rates */
248 u8 legacy_nrates; 226 u8 legacy_nrates;
249 227
250 /* Number of supported MCS rates. Work in progress */
251 u8 mcs_nrates;
252
253 /* Index into station database.Returned by update_sta_db call */ 228 /* Index into station database.Returned by update_sta_db call */
254 u8 peer_id; 229 u8 peer_id;
255 230
256 /* Non AMPDU sequence number assigned by driver */ 231 /* Non AMPDU sequence number assigned by driver */
257 u16 seqno; 232 u16 seqno;
258
259 /* Note:There is no channel info,
260 * refer to the master channel info in priv
261 */
262}; 233};
263 234
264#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv)) 235#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
@@ -292,28 +263,6 @@ static const struct ieee80211_rate mwl8k_rates[] = {
292 { .bitrate = 540, .hw_value = 108, }, 263 { .bitrate = 540, .hw_value = 108, },
293}; 264};
294 265
295/* Radio settings */
296#define MWL8K_RADIO_FORCE 0x2
297#define MWL8K_RADIO_ENABLE 0x1
298#define MWL8K_RADIO_DISABLE 0x0
299#define MWL8K_RADIO_AUTO_PREAMBLE 0x0005
300#define MWL8K_RADIO_SHORT_PREAMBLE 0x0003
301#define MWL8K_RADIO_LONG_PREAMBLE 0x0001
302
303/* WMM */
304#define MWL8K_WMM_ENABLE 1
305#define MWL8K_WMM_DISABLE 0
306
307#define MWL8K_RADIO_DEFAULT_PREAMBLE MWL8K_RADIO_LONG_PREAMBLE
308
309/* Slot time */
310
311/* Short Slot: 9us slot time */
312#define MWL8K_SHORT_SLOTTIME 1
313
314/* Long slot: 20us slot time */
315#define MWL8K_LONG_SLOTTIME 0
316
317/* Set or get info from Firmware */ 266/* Set or get info from Firmware */
318#define MWL8K_CMD_SET 0x0001 267#define MWL8K_CMD_SET 0x0001
319#define MWL8K_CMD_GET 0x0000 268#define MWL8K_CMD_GET 0x0000
@@ -323,25 +272,23 @@ static const struct ieee80211_rate mwl8k_rates[] = {
323#define MWL8K_CMD_GET_HW_SPEC 0x0003 272#define MWL8K_CMD_GET_HW_SPEC 0x0003
324#define MWL8K_CMD_MAC_MULTICAST_ADR 0x0010 273#define MWL8K_CMD_MAC_MULTICAST_ADR 0x0010
325#define MWL8K_CMD_GET_STAT 0x0014 274#define MWL8K_CMD_GET_STAT 0x0014
326#define MWL8K_CMD_RADIO_CONTROL 0x001C 275#define MWL8K_CMD_RADIO_CONTROL 0x001c
327#define MWL8K_CMD_RF_TX_POWER 0x001E 276#define MWL8K_CMD_RF_TX_POWER 0x001e
328#define MWL8K_CMD_SET_PRE_SCAN 0x0107 277#define MWL8K_CMD_SET_PRE_SCAN 0x0107
329#define MWL8K_CMD_SET_POST_SCAN 0x0108 278#define MWL8K_CMD_SET_POST_SCAN 0x0108
330#define MWL8K_CMD_SET_RF_CHANNEL 0x010A 279#define MWL8K_CMD_SET_RF_CHANNEL 0x010a
280#define MWL8K_CMD_SET_AID 0x010d
281#define MWL8K_CMD_SET_RATE 0x0110
282#define MWL8K_CMD_SET_FINALIZE_JOIN 0x0111
283#define MWL8K_CMD_RTS_THRESHOLD 0x0113
331#define MWL8K_CMD_SET_SLOT 0x0114 284#define MWL8K_CMD_SET_SLOT 0x0114
285#define MWL8K_CMD_SET_EDCA_PARAMS 0x0115
286#define MWL8K_CMD_SET_WMM_MODE 0x0123
332#define MWL8K_CMD_MIMO_CONFIG 0x0125 287#define MWL8K_CMD_MIMO_CONFIG 0x0125
288#define MWL8K_CMD_USE_FIXED_RATE 0x0126
333#define MWL8K_CMD_ENABLE_SNIFFER 0x0150 289#define MWL8K_CMD_ENABLE_SNIFFER 0x0150
334#define MWL8K_CMD_SET_WMM_MODE 0x0123
335#define MWL8K_CMD_SET_EDCA_PARAMS 0x0115
336#define MWL8K_CMD_SET_FINALIZE_JOIN 0x0111
337#define MWL8K_CMD_UPDATE_STADB 0x1123
338#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203 290#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203
339#define MWL8K_CMD_SET_LINKADAPT_MODE 0x0129 291#define MWL8K_CMD_UPDATE_STADB 0x1123
340#define MWL8K_CMD_SET_AID 0x010d
341#define MWL8K_CMD_SET_RATE 0x0110
342#define MWL8K_CMD_USE_FIXED_RATE 0x0126
343#define MWL8K_CMD_RTS_THRESHOLD 0x0113
344#define MWL8K_CMD_ENCRYPTION 0x1122
345 292
346static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize) 293static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
347{ 294{
@@ -349,7 +296,7 @@ static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
349 snprintf(buf, bufsize, "%s", #x);\ 296 snprintf(buf, bufsize, "%s", #x);\
350 return buf;\ 297 return buf;\
351 } while (0) 298 } while (0)
352 switch (cmd & (~0x8000)) { 299 switch (cmd & ~0x8000) {
353 MWL8K_CMDNAME(CODE_DNLD); 300 MWL8K_CMDNAME(CODE_DNLD);
354 MWL8K_CMDNAME(GET_HW_SPEC); 301 MWL8K_CMDNAME(GET_HW_SPEC);
355 MWL8K_CMDNAME(MAC_MULTICAST_ADR); 302 MWL8K_CMDNAME(MAC_MULTICAST_ADR);
@@ -359,20 +306,18 @@ static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
359 MWL8K_CMDNAME(SET_PRE_SCAN); 306 MWL8K_CMDNAME(SET_PRE_SCAN);
360 MWL8K_CMDNAME(SET_POST_SCAN); 307 MWL8K_CMDNAME(SET_POST_SCAN);
361 MWL8K_CMDNAME(SET_RF_CHANNEL); 308 MWL8K_CMDNAME(SET_RF_CHANNEL);
309 MWL8K_CMDNAME(SET_AID);
310 MWL8K_CMDNAME(SET_RATE);
311 MWL8K_CMDNAME(SET_FINALIZE_JOIN);
312 MWL8K_CMDNAME(RTS_THRESHOLD);
362 MWL8K_CMDNAME(SET_SLOT); 313 MWL8K_CMDNAME(SET_SLOT);
314 MWL8K_CMDNAME(SET_EDCA_PARAMS);
315 MWL8K_CMDNAME(SET_WMM_MODE);
363 MWL8K_CMDNAME(MIMO_CONFIG); 316 MWL8K_CMDNAME(MIMO_CONFIG);
317 MWL8K_CMDNAME(USE_FIXED_RATE);
364 MWL8K_CMDNAME(ENABLE_SNIFFER); 318 MWL8K_CMDNAME(ENABLE_SNIFFER);
365 MWL8K_CMDNAME(SET_WMM_MODE);
366 MWL8K_CMDNAME(SET_EDCA_PARAMS);
367 MWL8K_CMDNAME(SET_FINALIZE_JOIN);
368 MWL8K_CMDNAME(UPDATE_STADB);
369 MWL8K_CMDNAME(SET_RATEADAPT_MODE); 319 MWL8K_CMDNAME(SET_RATEADAPT_MODE);
370 MWL8K_CMDNAME(SET_LINKADAPT_MODE); 320 MWL8K_CMDNAME(UPDATE_STADB);
371 MWL8K_CMDNAME(SET_AID);
372 MWL8K_CMDNAME(SET_RATE);
373 MWL8K_CMDNAME(USE_FIXED_RATE);
374 MWL8K_CMDNAME(RTS_THRESHOLD);
375 MWL8K_CMDNAME(ENCRYPTION);
376 default: 321 default:
377 snprintf(buf, bufsize, "0x%x", cmd); 322 snprintf(buf, bufsize, "0x%x", cmd);
378 } 323 }
@@ -466,7 +411,6 @@ mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
466{ 411{
467 void __iomem *regs = priv->regs; 412 void __iomem *regs = priv->regs;
468 dma_addr_t dma_addr; 413 dma_addr_t dma_addr;
469 int rc;
470 int loops; 414 int loops;
471 415
472 dma_addr = pci_map_single(priv->pdev, data, length, PCI_DMA_TODEVICE); 416 dma_addr = pci_map_single(priv->pdev, data, length, PCI_DMA_TODEVICE);
@@ -480,7 +424,6 @@ mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
480 iowrite32(MWL8K_H2A_INT_DUMMY, 424 iowrite32(MWL8K_H2A_INT_DUMMY,
481 regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); 425 regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
482 426
483 rc = -ETIMEDOUT;
484 loops = 1000; 427 loops = 1000;
485 do { 428 do {
486 u32 int_code; 429 u32 int_code;
@@ -488,7 +431,6 @@ mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
488 int_code = ioread32(regs + MWL8K_HIU_INT_CODE); 431 int_code = ioread32(regs + MWL8K_HIU_INT_CODE);
489 if (int_code == MWL8K_INT_CODE_CMD_FINISHED) { 432 if (int_code == MWL8K_INT_CODE_CMD_FINISHED) {
490 iowrite32(0, regs + MWL8K_HIU_INT_CODE); 433 iowrite32(0, regs + MWL8K_HIU_INT_CODE);
491 rc = 0;
492 break; 434 break;
493 } 435 }
494 436
@@ -497,26 +439,7 @@ mwl8k_send_fw_load_cmd(struct mwl8k_priv *priv, void *data, int length)
497 439
498 pci_unmap_single(priv->pdev, dma_addr, length, PCI_DMA_TODEVICE); 440 pci_unmap_single(priv->pdev, dma_addr, length, PCI_DMA_TODEVICE);
499 441
500 /* 442 return loops ? 0 : -ETIMEDOUT;
501 * Clear 'command done' interrupt bit.
502 */
503 loops = 1000;
504 do {
505 u32 status;
506
507 status = ioread32(priv->regs +
508 MWL8K_HIU_A2H_INTERRUPT_STATUS);
509 if (status & MWL8K_A2H_INT_OPC_DONE) {
510 iowrite32(~MWL8K_A2H_INT_OPC_DONE,
511 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
512 ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
513 break;
514 }
515
516 udelay(1);
517 } while (--loops);
518
519 return rc;
520} 443}
521 444
522static int mwl8k_load_fw_image(struct mwl8k_priv *priv, 445static int mwl8k_load_fw_image(struct mwl8k_priv *priv,
@@ -681,11 +604,9 @@ struct ewc_ht_info {
681 604
682/* Peer Entry flags - used to define the type of the peer node */ 605/* Peer Entry flags - used to define the type of the peer node */
683#define MWL8K_PEER_TYPE_ACCESSPOINT 2 606#define MWL8K_PEER_TYPE_ACCESSPOINT 2
684#define MWL8K_PEER_TYPE_ADHOC_STATION 4
685 607
686#define MWL8K_IEEE_LEGACY_DATA_RATES 12 608#define MWL8K_IEEE_LEGACY_DATA_RATES 12
687#define MWL8K_MCS_BITMAP_SIZE 16 609#define MWL8K_MCS_BITMAP_SIZE 16
688#define pad_size 16
689 610
690struct peer_capability_info { 611struct peer_capability_info {
691 /* Peer type - AP vs. STA. */ 612 /* Peer type - AP vs. STA. */
@@ -707,7 +628,7 @@ struct peer_capability_info {
707 628
708 /* HT rate table. Intersection of our rates and peer rates. */ 629 /* HT rate table. Intersection of our rates and peer rates. */
709 __u8 ht_rates[MWL8K_MCS_BITMAP_SIZE]; 630 __u8 ht_rates[MWL8K_MCS_BITMAP_SIZE];
710 __u8 pad[pad_size]; 631 __u8 pad[16];
711 632
712 /* If set, interoperability mode, no proprietary extensions. */ 633 /* If set, interoperability mode, no proprietary extensions. */
713 __u8 interop; 634 __u8 interop;
@@ -717,15 +638,6 @@ struct peer_capability_info {
717} __attribute__((packed)); 638} __attribute__((packed));
718 639
719/* Inline functions to manipulate QoS field in data descriptor. */ 640/* Inline functions to manipulate QoS field in data descriptor. */
720static inline u16 mwl8k_qos_setbit_tid(u16 qos, u8 tid)
721{
722 u16 val_mask = 0x000f;
723 u16 qos_mask = ~val_mask;
724
725 /* TID bits 0-3 */
726 return (qos & qos_mask) | (tid & val_mask);
727}
728
729static inline u16 mwl8k_qos_setbit_eosp(u16 qos) 641static inline u16 mwl8k_qos_setbit_eosp(u16 qos)
730{ 642{
731 u16 val_mask = 1 << 4; 643 u16 val_mask = 1 << 4;
@@ -769,12 +681,11 @@ struct mwl8k_dma_data {
769} __attribute__((packed)); 681} __attribute__((packed));
770 682
771/* Routines to add/remove DMA header from skb. */ 683/* Routines to add/remove DMA header from skb. */
772static inline int mwl8k_remove_dma_header(struct sk_buff *skb) 684static inline void mwl8k_remove_dma_header(struct sk_buff *skb)
773{ 685{
774 struct mwl8k_dma_data *tr = (struct mwl8k_dma_data *)(skb->data); 686 struct mwl8k_dma_data *tr = (struct mwl8k_dma_data *)skb->data;
775 void *dst, *src = &tr->wh; 687 void *dst, *src = &tr->wh;
776 __le16 fc = tr->wh.frame_control; 688 int hdrlen = ieee80211_hdrlen(tr->wh.frame_control);
777 int hdrlen = ieee80211_hdrlen(fc);
778 u16 space = sizeof(struct mwl8k_dma_data) - hdrlen; 689 u16 space = sizeof(struct mwl8k_dma_data) - hdrlen;
779 690
780 dst = (void *)tr + space; 691 dst = (void *)tr + space;
@@ -782,11 +693,9 @@ static inline int mwl8k_remove_dma_header(struct sk_buff *skb)
782 memmove(dst, src, hdrlen); 693 memmove(dst, src, hdrlen);
783 skb_pull(skb, space); 694 skb_pull(skb, space);
784 } 695 }
785
786 return 0;
787} 696}
788 697
789static inline struct sk_buff *mwl8k_add_dma_header(struct sk_buff *skb) 698static inline void mwl8k_add_dma_header(struct sk_buff *skb)
790{ 699{
791 struct ieee80211_hdr *wh; 700 struct ieee80211_hdr *wh;
792 u32 hdrlen, pktlen; 701 u32 hdrlen, pktlen;
@@ -810,7 +719,7 @@ static inline struct sk_buff *mwl8k_add_dma_header(struct sk_buff *skb)
810 memmove(&tr->wh, wh, hdrlen); 719 memmove(&tr->wh, wh, hdrlen);
811 720
812 /* Clear addr4 */ 721 /* Clear addr4 */
813 memset(tr->wh.addr4, 0, IEEE80211_ADDR_LEN); 722 memset(tr->wh.addr4, 0, ETH_ALEN);
814 723
815 /* 724 /*
816 * Firmware length is the length of the fully formed "802.11 725 * Firmware length is the length of the fully formed "802.11
@@ -818,17 +727,13 @@ static inline struct sk_buff *mwl8k_add_dma_header(struct sk_buff *skb)
818 * This includes all crypto material including the MIC. 727 * This includes all crypto material including the MIC.
819 */ 728 */
820 tr->fwlen = cpu_to_le16(pktlen - hdrlen); 729 tr->fwlen = cpu_to_le16(pktlen - hdrlen);
821
822 return skb;
823} 730}
824 731
825 732
826/* 733/*
827 * Packet reception. 734 * Packet reception.
828 */ 735 */
829#define MWL8K_RX_CTRL_KEY_INDEX_MASK 0x30
830#define MWL8K_RX_CTRL_OWNED_BY_HOST 0x02 736#define MWL8K_RX_CTRL_OWNED_BY_HOST 0x02
831#define MWL8K_RX_CTRL_AMPDU 0x01
832 737
833struct mwl8k_rx_desc { 738struct mwl8k_rx_desc {
834 __le16 pkt_len; 739 __le16 pkt_len;
@@ -979,7 +884,7 @@ static inline void mwl8k_save_beacon(struct mwl8k_priv *priv,
979 struct sk_buff *skb) 884 struct sk_buff *skb)
980{ 885{
981 priv->capture_beacon = false; 886 priv->capture_beacon = false;
982 memset(priv->capture_bssid, 0, IEEE80211_ADDR_LEN); 887 memset(priv->capture_bssid, 0, ETH_ALEN);
983 888
984 /* 889 /*
985 * Use GFP_ATOMIC as rxq_process is called from 890 * Use GFP_ATOMIC as rxq_process is called from
@@ -1024,10 +929,7 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
1024 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE); 929 MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
1025 930
1026 skb_put(skb, le16_to_cpu(rx_desc->pkt_len)); 931 skb_put(skb, le16_to_cpu(rx_desc->pkt_len));
1027 if (mwl8k_remove_dma_header(skb)) { 932 mwl8k_remove_dma_header(skb);
1028 dev_kfree_skb(skb);
1029 continue;
1030 }
1031 933
1032 wh = (struct ieee80211_hdr *)skb->data; 934 wh = (struct ieee80211_hdr *)skb->data;
1033 935
@@ -1073,8 +975,6 @@ enum {
1073 975
1074/* Transmit packet ACK policy */ 976/* Transmit packet ACK policy */
1075#define MWL8K_TXD_ACK_POLICY_NORMAL 0 977#define MWL8K_TXD_ACK_POLICY_NORMAL 0
1076#define MWL8K_TXD_ACK_POLICY_NONE 1
1077#define MWL8K_TXD_ACK_POLICY_NO_EXPLICIT 2
1078#define MWL8K_TXD_ACK_POLICY_BLOCKACK 3 978#define MWL8K_TXD_ACK_POLICY_BLOCKACK 3
1079 979
1080#define GET_TXQ(_ac) (\ 980#define GET_TXQ(_ac) (\
@@ -1083,20 +983,11 @@ enum {
1083 ((_ac) == WME_AC_BK) ? MWL8K_WME_AC_BK : \ 983 ((_ac) == WME_AC_BK) ? MWL8K_WME_AC_BK : \
1084 MWL8K_WME_AC_BE) 984 MWL8K_WME_AC_BE)
1085 985
1086#define MWL8K_TXD_STATUS_IDLE 0x00000000
1087#define MWL8K_TXD_STATUS_USED 0x00000001
1088#define MWL8K_TXD_STATUS_OK 0x00000001 986#define MWL8K_TXD_STATUS_OK 0x00000001
1089#define MWL8K_TXD_STATUS_OK_RETRY 0x00000002 987#define MWL8K_TXD_STATUS_OK_RETRY 0x00000002
1090#define MWL8K_TXD_STATUS_OK_MORE_RETRY 0x00000004 988#define MWL8K_TXD_STATUS_OK_MORE_RETRY 0x00000004
1091#define MWL8K_TXD_STATUS_MULTICAST_TX 0x00000008 989#define MWL8K_TXD_STATUS_MULTICAST_TX 0x00000008
1092#define MWL8K_TXD_STATUS_BROADCAST_TX 0x00000010
1093#define MWL8K_TXD_STATUS_FAILED_LINK_ERROR 0x00000020
1094#define MWL8K_TXD_STATUS_FAILED_EXCEED_LIMIT 0x00000040
1095#define MWL8K_TXD_STATUS_FAILED_AGING 0x00000080
1096#define MWL8K_TXD_STATUS_HOST_CMD 0x40000000
1097#define MWL8K_TXD_STATUS_FW_OWNED 0x80000000 990#define MWL8K_TXD_STATUS_FW_OWNED 0x80000000
1098#define MWL8K_TXD_SOFTSTALE 0x80
1099#define MWL8K_TXD_SOFTSTALE_MGMT_RETRY 0x01
1100 991
1101struct mwl8k_tx_desc { 992struct mwl8k_tx_desc {
1102 __le32 status; 993 __le32 status;
@@ -1105,7 +996,7 @@ struct mwl8k_tx_desc {
1105 __le16 qos_control; 996 __le16 qos_control;
1106 __le32 pkt_phys_addr; 997 __le32 pkt_phys_addr;
1107 __le16 pkt_len; 998 __le16 pkt_len;
1108 __u8 dest_MAC_addr[IEEE80211_ADDR_LEN]; 999 __u8 dest_MAC_addr[ETH_ALEN];
1109 __le32 next_tx_desc_phys_addr; 1000 __le32 next_tx_desc_phys_addr;
1110 __le32 reserved; 1001 __le32 reserved;
1111 __le16 rate_info; 1002 __le16 rate_info;
@@ -1122,8 +1013,7 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
1122 int size; 1013 int size;
1123 int i; 1014 int i;
1124 1015
1125 memset(&txq->tx_stats, 0, 1016 memset(&txq->tx_stats, 0, sizeof(struct ieee80211_tx_queue_stats));
1126 sizeof(struct ieee80211_tx_queue_stats));
1127 txq->tx_stats.limit = MWL8K_TX_DESCS; 1017 txq->tx_stats.limit = MWL8K_TX_DESCS;
1128 txq->tx_head = 0; 1018 txq->tx_head = 0;
1129 txq->tx_tail = 0; 1019 txq->tx_tail = 0;
@@ -1190,17 +1080,17 @@ struct mwl8k_txq_info {
1190}; 1080};
1191 1081
1192static int mwl8k_scan_tx_ring(struct mwl8k_priv *priv, 1082static int mwl8k_scan_tx_ring(struct mwl8k_priv *priv,
1193 struct mwl8k_txq_info txinfo[], 1083 struct mwl8k_txq_info *txinfo)
1194 u32 num_queues)
1195{ 1084{
1196 int count, desc, status; 1085 int count, desc, status;
1197 struct mwl8k_tx_queue *txq; 1086 struct mwl8k_tx_queue *txq;
1198 struct mwl8k_tx_desc *tx_desc; 1087 struct mwl8k_tx_desc *tx_desc;
1199 int ndescs = 0; 1088 int ndescs = 0;
1200 1089
1201 memset(txinfo, 0, num_queues * sizeof(struct mwl8k_txq_info)); 1090 memset(txinfo, 0, MWL8K_TX_QUEUES * sizeof(struct mwl8k_txq_info));
1091
1202 spin_lock_bh(&priv->tx_lock); 1092 spin_lock_bh(&priv->tx_lock);
1203 for (count = 0; count < num_queues; count++) { 1093 for (count = 0; count < MWL8K_TX_QUEUES; count++) {
1204 txq = priv->txq + count; 1094 txq = priv->txq + count;
1205 txinfo[count].len = txq->tx_stats.len; 1095 txinfo[count].len = txq->tx_stats.len;
1206 txinfo[count].head = txq->tx_head; 1096 txinfo[count].head = txq->tx_head;
@@ -1223,34 +1113,34 @@ static int mwl8k_scan_tx_ring(struct mwl8k_priv *priv,
1223 return ndescs; 1113 return ndescs;
1224} 1114}
1225 1115
1226static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw, u32 delay_ms) 1116/*
1117 * Must be called with hw->fw_mutex held and tx queues stopped.
1118 */
1119static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1227{ 1120{
1228 u32 count = 0;
1229 unsigned long timeout = 0;
1230 struct mwl8k_priv *priv = hw->priv; 1121 struct mwl8k_priv *priv = hw->priv;
1231 DECLARE_COMPLETION_ONSTACK(cmd_wait); 1122 DECLARE_COMPLETION_ONSTACK(cmd_wait);
1123 u32 count;
1124 unsigned long timeout;
1232 1125
1233 might_sleep(); 1126 might_sleep();
1234 1127
1235 if (priv->tx_wait != NULL)
1236 printk(KERN_ERR "WARNING Previous TXWaitEmpty instance\n");
1237
1238 spin_lock_bh(&priv->tx_lock); 1128 spin_lock_bh(&priv->tx_lock);
1239 count = mwl8k_txq_busy(priv); 1129 count = mwl8k_txq_busy(priv);
1240 if (count) { 1130 if (count) {
1241 priv->tx_wait = &cmd_wait; 1131 priv->tx_wait = &cmd_wait;
1242 if (priv->radio_state) 1132 if (priv->radio_on)
1243 mwl8k_tx_start(priv); 1133 mwl8k_tx_start(priv);
1244 } 1134 }
1245 spin_unlock_bh(&priv->tx_lock); 1135 spin_unlock_bh(&priv->tx_lock);
1246 1136
1247 if (count) { 1137 if (count) {
1248 struct mwl8k_txq_info txinfo[4]; 1138 struct mwl8k_txq_info txinfo[MWL8K_TX_QUEUES];
1249 int index; 1139 int index;
1250 int newcount; 1140 int newcount;
1251 1141
1252 timeout = wait_for_completion_timeout(&cmd_wait, 1142 timeout = wait_for_completion_timeout(&cmd_wait,
1253 msecs_to_jiffies(delay_ms)); 1143 msecs_to_jiffies(5000));
1254 if (timeout) 1144 if (timeout)
1255 return 0; 1145 return 0;
1256 1146
@@ -1259,11 +1149,11 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw, u32 delay_ms)
1259 newcount = mwl8k_txq_busy(priv); 1149 newcount = mwl8k_txq_busy(priv);
1260 spin_unlock_bh(&priv->tx_lock); 1150 spin_unlock_bh(&priv->tx_lock);
1261 1151
1262 printk(KERN_ERR "%s(%u) TIMEDOUT:%ums Pend:%u-->%u\n", 1152 printk(KERN_ERR "%s(%u) TIMEDOUT:5000ms Pend:%u-->%u\n",
1263 __func__, __LINE__, delay_ms, count, newcount); 1153 __func__, __LINE__, count, newcount);
1264 1154
1265 mwl8k_scan_tx_ring(priv, txinfo, 4); 1155 mwl8k_scan_tx_ring(priv, txinfo);
1266 for (index = 0 ; index < 4; index++) 1156 for (index = 0; index < MWL8K_TX_QUEUES; index++)
1267 printk(KERN_ERR 1157 printk(KERN_ERR
1268 "TXQ:%u L:%u H:%u T:%u FW:%u DRV:%u U:%u\n", 1158 "TXQ:%u L:%u H:%u T:%u FW:%u DRV:%u U:%u\n",
1269 index, 1159 index,
@@ -1273,18 +1163,17 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw, u32 delay_ms)
1273 txinfo[index].fw_owned, 1163 txinfo[index].fw_owned,
1274 txinfo[index].drv_owned, 1164 txinfo[index].drv_owned,
1275 txinfo[index].unused); 1165 txinfo[index].unused);
1166
1276 return -ETIMEDOUT; 1167 return -ETIMEDOUT;
1277 } 1168 }
1278 1169
1279 return 0; 1170 return 0;
1280} 1171}
1281 1172
1282#define MWL8K_TXD_OK (MWL8K_TXD_STATUS_OK | \ 1173#define MWL8K_TXD_SUCCESS(status) \
1283 MWL8K_TXD_STATUS_OK_RETRY | \ 1174 ((status) & (MWL8K_TXD_STATUS_OK | \
1284 MWL8K_TXD_STATUS_OK_MORE_RETRY) 1175 MWL8K_TXD_STATUS_OK_RETRY | \
1285#define MWL8K_TXD_SUCCESS(stat) ((stat) & MWL8K_TXD_OK) 1176 MWL8K_TXD_STATUS_OK_MORE_RETRY))
1286#define MWL8K_TXD_FAIL_RETRY(stat) \
1287 ((stat) & (MWL8K_TXD_STATUS_FAILED_EXCEED_LIMIT))
1288 1177
1289static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force) 1178static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
1290{ 1179{
@@ -1294,15 +1183,13 @@ static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
1294 1183
1295 while (txq->tx_stats.len > 0) { 1184 while (txq->tx_stats.len > 0) {
1296 int tx; 1185 int tx;
1297 int rc;
1298 struct mwl8k_tx_desc *tx_desc; 1186 struct mwl8k_tx_desc *tx_desc;
1299 unsigned long addr; 1187 unsigned long addr;
1300 size_t size; 1188 int size;
1301 struct sk_buff *skb; 1189 struct sk_buff *skb;
1302 struct ieee80211_tx_info *info; 1190 struct ieee80211_tx_info *info;
1303 u32 status; 1191 u32 status;
1304 1192
1305 rc = 0;
1306 tx = txq->tx_head; 1193 tx = txq->tx_head;
1307 tx_desc = txq->tx_desc_area + tx; 1194 tx_desc = txq->tx_desc_area + tx;
1308 1195
@@ -1321,56 +1208,30 @@ static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
1321 priv->pending_tx_pkts--; 1208 priv->pending_tx_pkts--;
1322 1209
1323 addr = le32_to_cpu(tx_desc->pkt_phys_addr); 1210 addr = le32_to_cpu(tx_desc->pkt_phys_addr);
1324 size = (u32)(le16_to_cpu(tx_desc->pkt_len)); 1211 size = le16_to_cpu(tx_desc->pkt_len);
1325 skb = txq->tx_skb[tx].skb; 1212 skb = txq->tx_skb[tx];
1326 txq->tx_skb[tx].skb = NULL; 1213 txq->tx_skb[tx] = NULL;
1327 1214
1328 BUG_ON(skb == NULL); 1215 BUG_ON(skb == NULL);
1329 pci_unmap_single(priv->pdev, addr, size, PCI_DMA_TODEVICE); 1216 pci_unmap_single(priv->pdev, addr, size, PCI_DMA_TODEVICE);
1330 1217
1331 rc = mwl8k_remove_dma_header(skb); 1218 mwl8k_remove_dma_header(skb);
1332 1219
1333 /* Mark descriptor as unused */ 1220 /* Mark descriptor as unused */
1334 tx_desc->pkt_phys_addr = 0; 1221 tx_desc->pkt_phys_addr = 0;
1335 tx_desc->pkt_len = 0; 1222 tx_desc->pkt_len = 0;
1336 1223
1337 if (txq->tx_skb[tx].clone) {
1338 /* Replace with original skb
1339 * before returning to stack
1340 * as buffer has been cloned
1341 */
1342 dev_kfree_skb(skb);
1343 skb = txq->tx_skb[tx].clone;
1344 txq->tx_skb[tx].clone = NULL;
1345 }
1346
1347 if (rc) {
1348 /* Something has gone wrong here.
1349 * Failed to remove DMA header.
1350 * Print error message and drop packet.
1351 */
1352 printk(KERN_ERR "%s: Error removing DMA header from "
1353 "tx skb 0x%p.\n", priv->name, skb);
1354
1355 dev_kfree_skb(skb);
1356 continue;
1357 }
1358
1359 info = IEEE80211_SKB_CB(skb); 1224 info = IEEE80211_SKB_CB(skb);
1360 ieee80211_tx_info_clear_status(info); 1225 ieee80211_tx_info_clear_status(info);
1361 1226 if (MWL8K_TXD_SUCCESS(status))
1362 /* Convert firmware status stuff into tx_status */
1363 if (MWL8K_TXD_SUCCESS(status)) {
1364 /* Transmit OK */
1365 info->flags |= IEEE80211_TX_STAT_ACK; 1227 info->flags |= IEEE80211_TX_STAT_ACK;
1366 }
1367 1228
1368 ieee80211_tx_status_irqsafe(hw, skb); 1229 ieee80211_tx_status_irqsafe(hw, skb);
1369 1230
1370 wake = !priv->inconfig && priv->radio_state; 1231 wake = 1;
1371 } 1232 }
1372 1233
1373 if (wake) 1234 if (wake && priv->radio_on && !mutex_is_locked(&priv->fw_mutex))
1374 ieee80211_wake_queue(hw, index); 1235 ieee80211_wake_queue(hw, index);
1375} 1236}
1376 1237
@@ -1396,56 +1257,60 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1396{ 1257{
1397 struct mwl8k_priv *priv = hw->priv; 1258 struct mwl8k_priv *priv = hw->priv;
1398 struct ieee80211_tx_info *tx_info; 1259 struct ieee80211_tx_info *tx_info;
1260 struct mwl8k_vif *mwl8k_vif;
1399 struct ieee80211_hdr *wh; 1261 struct ieee80211_hdr *wh;
1400 struct mwl8k_tx_queue *txq; 1262 struct mwl8k_tx_queue *txq;
1401 struct mwl8k_tx_desc *tx; 1263 struct mwl8k_tx_desc *tx;
1402 struct mwl8k_dma_data *tr;
1403 struct mwl8k_vif *mwl8k_vif;
1404 struct sk_buff *org_skb = skb;
1405 dma_addr_t dma; 1264 dma_addr_t dma;
1406 u16 qos = 0; 1265 u32 txstatus;
1407 bool qosframe = false, ampduframe = false; 1266 u8 txdatarate;
1408 bool mcframe = false, eapolframe = false; 1267 u16 qos;
1409 bool amsduframe = false;
1410 __le16 fc;
1411 1268
1412 txq = priv->txq + index; 1269 wh = (struct ieee80211_hdr *)skb->data;
1413 tx = txq->tx_desc_area + txq->tx_tail; 1270 if (ieee80211_is_data_qos(wh->frame_control))
1414 1271 qos = le16_to_cpu(*((__le16 *)ieee80211_get_qos_ctl(wh)));
1415 BUG_ON(txq->tx_skb[txq->tx_tail].skb != NULL); 1272 else
1416 1273 qos = 0;
1417 /*
1418 * Append HW DMA header to start of packet. Drop packet if
1419 * there is not enough space or a failure to unshare/unclone
1420 * the skb.
1421 */
1422 skb = mwl8k_add_dma_header(skb);
1423 1274
1424 if (skb == NULL) { 1275 mwl8k_add_dma_header(skb);
1425 printk(KERN_DEBUG "%s: failed to prepend HW DMA " 1276 wh = &((struct mwl8k_dma_data *)skb->data)->wh;
1426 "header, dropping TX frame.\n", priv->name);
1427 dev_kfree_skb(org_skb);
1428 return NETDEV_TX_OK;
1429 }
1430 1277
1431 tx_info = IEEE80211_SKB_CB(skb); 1278 tx_info = IEEE80211_SKB_CB(skb);
1432 mwl8k_vif = MWL8K_VIF(tx_info->control.vif); 1279 mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
1433 tr = (struct mwl8k_dma_data *)skb->data;
1434 wh = &tr->wh;
1435 fc = wh->frame_control;
1436 qosframe = ieee80211_is_data_qos(fc);
1437 mcframe = is_multicast_ether_addr(wh->addr1);
1438 ampduframe = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
1439 1280
1440 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 1281 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1441 u16 seqno = mwl8k_vif->seqno; 1282 u16 seqno = mwl8k_vif->seqno;
1283
1442 wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); 1284 wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
1443 wh->seq_ctrl |= cpu_to_le16(seqno << 4); 1285 wh->seq_ctrl |= cpu_to_le16(seqno << 4);
1444 mwl8k_vif->seqno = seqno++ % 4096; 1286 mwl8k_vif->seqno = seqno++ % 4096;
1445 } 1287 }
1446 1288
1447 if (qosframe) 1289 /* Setup firmware control bit fields for each frame type. */
1448 qos = le16_to_cpu(*((__le16 *)ieee80211_get_qos_ctl(wh))); 1290 txstatus = 0;
1291 txdatarate = 0;
1292 if (ieee80211_is_mgmt(wh->frame_control) ||
1293 ieee80211_is_ctl(wh->frame_control)) {
1294 txdatarate = 0;
1295 qos = mwl8k_qos_setbit_eosp(qos);
1296 /* Set Queue size to unspecified */
1297 qos = mwl8k_qos_setbit_qlen(qos, 0xff);
1298 } else if (ieee80211_is_data(wh->frame_control)) {
1299 txdatarate = 1;
1300 if (is_multicast_ether_addr(wh->addr1))
1301 txstatus |= MWL8K_TXD_STATUS_MULTICAST_TX;
1302
1303 /* Send pkt in an aggregate if AMPDU frame. */
1304 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
1305 qos = mwl8k_qos_setbit_ack(qos,
1306 MWL8K_TXD_ACK_POLICY_BLOCKACK);
1307 else
1308 qos = mwl8k_qos_setbit_ack(qos,
1309 MWL8K_TXD_ACK_POLICY_NORMAL);
1310
1311 if (qos & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
1312 qos = mwl8k_qos_setbit_amsdu(qos);
1313 }
1449 1314
1450 dma = pci_map_single(priv->pdev, skb->data, 1315 dma = pci_map_single(priv->pdev, skb->data,
1451 skb->len, PCI_DMA_TODEVICE); 1316 skb->len, PCI_DMA_TODEVICE);
@@ -1453,99 +1318,40 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1453 if (pci_dma_mapping_error(priv->pdev, dma)) { 1318 if (pci_dma_mapping_error(priv->pdev, dma)) {
1454 printk(KERN_DEBUG "%s: failed to dma map skb, " 1319 printk(KERN_DEBUG "%s: failed to dma map skb, "
1455 "dropping TX frame.\n", priv->name); 1320 "dropping TX frame.\n", priv->name);
1456 1321 dev_kfree_skb(skb);
1457 if (org_skb != NULL)
1458 dev_kfree_skb(org_skb);
1459 if (skb != NULL)
1460 dev_kfree_skb(skb);
1461 return NETDEV_TX_OK; 1322 return NETDEV_TX_OK;
1462 } 1323 }
1463 1324
1464 /* Set desc header, cpu bit order. */ 1325 spin_lock_bh(&priv->tx_lock);
1465 tx->status = 0;
1466 tx->data_rate = 0;
1467 tx->tx_priority = index;
1468 tx->qos_control = 0;
1469 tx->rate_info = 0;
1470 tx->peer_id = mwl8k_vif->peer_id;
1471
1472 amsduframe = !!(qos & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT);
1473
1474 /* Setup firmware control bit fields for each frame type. */
1475 if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) {
1476 tx->data_rate = 0;
1477 qos = mwl8k_qos_setbit_eosp(qos);
1478 /* Set Queue size to unspecified */
1479 qos = mwl8k_qos_setbit_qlen(qos, 0xff);
1480 } else if (ieee80211_is_data(fc)) {
1481 tx->data_rate = 1;
1482 if (mcframe)
1483 tx->status |= MWL8K_TXD_STATUS_MULTICAST_TX;
1484 1326
1485 /* 1327 txq = priv->txq + index;
1486 * Tell firmware to not send EAPOL pkts in an
1487 * aggregate. Verify against mac80211 tx path. If
1488 * stack turns off AMPDU for an EAPOL frame this
1489 * check will be removed.
1490 */
1491 if (eapolframe) {
1492 qos = mwl8k_qos_setbit_ack(qos,
1493 MWL8K_TXD_ACK_POLICY_NORMAL);
1494 } else {
1495 /* Send pkt in an aggregate if AMPDU frame. */
1496 if (ampduframe)
1497 qos = mwl8k_qos_setbit_ack(qos,
1498 MWL8K_TXD_ACK_POLICY_BLOCKACK);
1499 else
1500 qos = mwl8k_qos_setbit_ack(qos,
1501 MWL8K_TXD_ACK_POLICY_NORMAL);
1502 1328
1503 if (amsduframe) 1329 BUG_ON(txq->tx_skb[txq->tx_tail] != NULL);
1504 qos = mwl8k_qos_setbit_amsdu(qos); 1330 txq->tx_skb[txq->tx_tail] = skb;
1505 }
1506 }
1507 1331
1508 /* Convert to little endian */ 1332 tx = txq->tx_desc_area + txq->tx_tail;
1333 tx->data_rate = txdatarate;
1334 tx->tx_priority = index;
1509 tx->qos_control = cpu_to_le16(qos); 1335 tx->qos_control = cpu_to_le16(qos);
1510 tx->status = cpu_to_le32(tx->status);
1511 tx->pkt_phys_addr = cpu_to_le32(dma); 1336 tx->pkt_phys_addr = cpu_to_le32(dma);
1512 tx->pkt_len = cpu_to_le16(skb->len); 1337 tx->pkt_len = cpu_to_le16(skb->len);
1513 1338 tx->rate_info = 0;
1514 txq->tx_skb[txq->tx_tail].skb = skb; 1339 tx->peer_id = mwl8k_vif->peer_id;
1515 txq->tx_skb[txq->tx_tail].clone =
1516 skb == org_skb ? NULL : org_skb;
1517
1518 spin_lock_bh(&priv->tx_lock);
1519
1520 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_OK |
1521 MWL8K_TXD_STATUS_FW_OWNED);
1522 wmb(); 1340 wmb();
1341 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus);
1342
1343 txq->tx_stats.count++;
1523 txq->tx_stats.len++; 1344 txq->tx_stats.len++;
1524 priv->pending_tx_pkts++; 1345 priv->pending_tx_pkts++;
1525 txq->tx_stats.count++;
1526 txq->tx_tail++;
1527 1346
1347 txq->tx_tail++;
1528 if (txq->tx_tail == MWL8K_TX_DESCS) 1348 if (txq->tx_tail == MWL8K_TX_DESCS)
1529 txq->tx_tail = 0; 1349 txq->tx_tail = 0;
1350
1530 if (txq->tx_head == txq->tx_tail) 1351 if (txq->tx_head == txq->tx_tail)
1531 ieee80211_stop_queue(hw, index); 1352 ieee80211_stop_queue(hw, index);
1532 1353
1533 if (priv->inconfig) { 1354 mwl8k_tx_start(priv);
1534 /*
1535 * Silently queue packet when we are in the middle of
1536 * a config cycle. Notify firmware only if we are
1537 * waiting for TXQs to empty. If a packet is sent
1538 * before .config() is complete, perhaps it is better
1539 * to drop the packet, as the channel is being changed
1540 * and the packet will end up on the wrong channel.
1541 */
1542 printk(KERN_ERR "%s(): WARNING TX activity while "
1543 "in config\n", __func__);
1544
1545 if (priv->tx_wait != NULL)
1546 mwl8k_tx_start(priv);
1547 } else
1548 mwl8k_tx_start(priv);
1549 1355
1550 spin_unlock_bh(&priv->tx_lock); 1356 spin_unlock_bh(&priv->tx_lock);
1551 1357
@@ -1554,6 +1360,60 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1554 1360
1555 1361
1556/* 1362/*
1363 * Firmware access.
1364 *
1365 * We have the following requirements for issuing firmware commands:
1366 * - Some commands require that the packet transmit path is idle when
1367 * the command is issued. (For simplicity, we'll just quiesce the
1368 * transmit path for every command.)
1369 * - There are certain sequences of commands that need to be issued to
1370 * the hardware sequentially, with no other intervening commands.
1371 *
1372 * This leads to an implementation of a "firmware lock" as a mutex that
1373 * can be taken recursively, and which is taken by both the low-level
1374 * command submission function (mwl8k_post_cmd) as well as any users of
1375 * that function that require issuing of an atomic sequence of commands,
1376 * and quiesces the transmit path whenever it's taken.
1377 */
1378static int mwl8k_fw_lock(struct ieee80211_hw *hw)
1379{
1380 struct mwl8k_priv *priv = hw->priv;
1381
1382 if (priv->fw_mutex_owner != current) {
1383 int rc;
1384
1385 mutex_lock(&priv->fw_mutex);
1386 ieee80211_stop_queues(hw);
1387
1388 rc = mwl8k_tx_wait_empty(hw);
1389 if (rc) {
1390 ieee80211_wake_queues(hw);
1391 mutex_unlock(&priv->fw_mutex);
1392
1393 return rc;
1394 }
1395
1396 priv->fw_mutex_owner = current;
1397 }
1398
1399 priv->fw_mutex_depth++;
1400
1401 return 0;
1402}
1403
1404static void mwl8k_fw_unlock(struct ieee80211_hw *hw)
1405{
1406 struct mwl8k_priv *priv = hw->priv;
1407
1408 if (!--priv->fw_mutex_depth) {
1409 ieee80211_wake_queues(hw);
1410 priv->fw_mutex_owner = NULL;
1411 mutex_unlock(&priv->fw_mutex);
1412 }
1413}
1414
1415
1416/*
1557 * Command processing. 1417 * Command processing.
1558 */ 1418 */
1559 1419
@@ -1568,7 +1428,6 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
1568 dma_addr_t dma_addr; 1428 dma_addr_t dma_addr;
1569 unsigned int dma_size; 1429 unsigned int dma_size;
1570 int rc; 1430 int rc;
1571 u16 __iomem *result;
1572 unsigned long timeout = 0; 1431 unsigned long timeout = 0;
1573 u8 buf[32]; 1432 u8 buf[32];
1574 1433
@@ -1579,41 +1438,40 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
1579 if (pci_dma_mapping_error(priv->pdev, dma_addr)) 1438 if (pci_dma_mapping_error(priv->pdev, dma_addr))
1580 return -ENOMEM; 1439 return -ENOMEM;
1581 1440
1582 if (priv->hostcmd_wait != NULL) 1441 rc = mwl8k_fw_lock(hw);
1583 printk(KERN_ERR "WARNING host command in progress\n"); 1442 if (rc)
1443 return rc;
1584 1444
1585 spin_lock_irq(&priv->fw_lock);
1586 priv->hostcmd_wait = &cmd_wait; 1445 priv->hostcmd_wait = &cmd_wait;
1587 iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR); 1446 iowrite32(dma_addr, regs + MWL8K_HIU_GEN_PTR);
1588 iowrite32(MWL8K_H2A_INT_DOORBELL, 1447 iowrite32(MWL8K_H2A_INT_DOORBELL,
1589 regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); 1448 regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
1590 iowrite32(MWL8K_H2A_INT_DUMMY, 1449 iowrite32(MWL8K_H2A_INT_DUMMY,
1591 regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS); 1450 regs + MWL8K_HIU_H2A_INTERRUPT_EVENTS);
1592 spin_unlock_irq(&priv->fw_lock);
1593 1451
1594 timeout = wait_for_completion_timeout(&cmd_wait, 1452 timeout = wait_for_completion_timeout(&cmd_wait,
1595 msecs_to_jiffies(MWL8K_CMD_TIMEOUT_MS)); 1453 msecs_to_jiffies(MWL8K_CMD_TIMEOUT_MS));
1596 1454
1455 priv->hostcmd_wait = NULL;
1456
1457 mwl8k_fw_unlock(hw);
1458
1597 pci_unmap_single(priv->pdev, dma_addr, dma_size, 1459 pci_unmap_single(priv->pdev, dma_addr, dma_size,
1598 PCI_DMA_BIDIRECTIONAL); 1460 PCI_DMA_BIDIRECTIONAL);
1599 1461
1600 result = &cmd->result;
1601 if (!timeout) { 1462 if (!timeout) {
1602 spin_lock_irq(&priv->fw_lock);
1603 priv->hostcmd_wait = NULL;
1604 spin_unlock_irq(&priv->fw_lock);
1605 printk(KERN_ERR "%s: Command %s timeout after %u ms\n", 1463 printk(KERN_ERR "%s: Command %s timeout after %u ms\n",
1606 priv->name, 1464 priv->name,
1607 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), 1465 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
1608 MWL8K_CMD_TIMEOUT_MS); 1466 MWL8K_CMD_TIMEOUT_MS);
1609 rc = -ETIMEDOUT; 1467 rc = -ETIMEDOUT;
1610 } else { 1468 } else {
1611 rc = *result ? -EINVAL : 0; 1469 rc = cmd->result ? -EINVAL : 0;
1612 if (rc) 1470 if (rc)
1613 printk(KERN_ERR "%s: Command %s error 0x%x\n", 1471 printk(KERN_ERR "%s: Command %s error 0x%x\n",
1614 priv->name, 1472 priv->name,
1615 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), 1473 mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
1616 *result); 1474 cmd->result);
1617 } 1475 }
1618 1476
1619 return rc; 1477 return rc;
@@ -1627,7 +1485,7 @@ struct mwl8k_cmd_get_hw_spec {
1627 __u8 hw_rev; 1485 __u8 hw_rev;
1628 __u8 host_interface; 1486 __u8 host_interface;
1629 __le16 num_mcaddrs; 1487 __le16 num_mcaddrs;
1630 __u8 perm_addr[IEEE80211_ADDR_LEN]; 1488 __u8 perm_addr[ETH_ALEN];
1631 __le16 region_code; 1489 __le16 region_code;
1632 __le32 fw_rev; 1490 __le32 fw_rev;
1633 __le32 ps_cookie; 1491 __le32 ps_cookie;
@@ -1671,7 +1529,6 @@ static int mwl8k_cmd_get_hw_spec(struct ieee80211_hw *hw)
1671 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); 1529 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
1672 priv->fw_rev = le32_to_cpu(cmd->fw_rev); 1530 priv->fw_rev = le32_to_cpu(cmd->fw_rev);
1673 priv->hw_rev = cmd->hw_rev; 1531 priv->hw_rev = cmd->hw_rev;
1674 priv->region_code = le16_to_cpu(cmd->region_code);
1675 } 1532 }
1676 1533
1677 kfree(cmd); 1534 kfree(cmd);
@@ -1685,41 +1542,44 @@ struct mwl8k_cmd_mac_multicast_adr {
1685 struct mwl8k_cmd_pkt header; 1542 struct mwl8k_cmd_pkt header;
1686 __le16 action; 1543 __le16 action;
1687 __le16 numaddr; 1544 __le16 numaddr;
1688 __u8 addr[1][IEEE80211_ADDR_LEN]; 1545 __u8 addr[0][ETH_ALEN];
1689}; 1546};
1690 1547
1691#define MWL8K_ENABLE_RX_MULTICAST 0x000F 1548#define MWL8K_ENABLE_RX_MULTICAST 0x000F
1692static int mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw, 1549
1693 int mc_count, 1550static struct mwl8k_cmd_pkt *
1694 struct dev_addr_list *mclist) 1551__mwl8k_cmd_mac_multicast_adr(struct ieee80211_hw *hw,
1552 int mc_count, struct dev_addr_list *mclist)
1695{ 1553{
1554 struct mwl8k_priv *priv = hw->priv;
1696 struct mwl8k_cmd_mac_multicast_adr *cmd; 1555 struct mwl8k_cmd_mac_multicast_adr *cmd;
1697 int index = 0; 1556 int size;
1698 int rc; 1557 int i;
1699 int size = sizeof(*cmd) + ((mc_count - 1) * IEEE80211_ADDR_LEN); 1558
1700 cmd = kzalloc(size, GFP_KERNEL); 1559 if (mc_count > priv->num_mcaddrs)
1560 mc_count = priv->num_mcaddrs;
1561
1562 size = sizeof(*cmd) + mc_count * ETH_ALEN;
1563
1564 cmd = kzalloc(size, GFP_ATOMIC);
1701 if (cmd == NULL) 1565 if (cmd == NULL)
1702 return -ENOMEM; 1566 return NULL;
1703 1567
1704 cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR); 1568 cmd->header.code = cpu_to_le16(MWL8K_CMD_MAC_MULTICAST_ADR);
1705 cmd->header.length = cpu_to_le16(size); 1569 cmd->header.length = cpu_to_le16(size);
1706 cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST); 1570 cmd->action = cpu_to_le16(MWL8K_ENABLE_RX_MULTICAST);
1707 cmd->numaddr = cpu_to_le16(mc_count); 1571 cmd->numaddr = cpu_to_le16(mc_count);
1708 while ((index < mc_count) && mclist) { 1572
1709 if (mclist->da_addrlen != IEEE80211_ADDR_LEN) { 1573 for (i = 0; i < mc_count && mclist; i++) {
1710 rc = -EINVAL; 1574 if (mclist->da_addrlen != ETH_ALEN) {
1711 goto mwl8k_cmd_mac_multicast_adr_exit; 1575 kfree(cmd);
1576 return NULL;
1712 } 1577 }
1713 memcpy(cmd->addr[index], mclist->da_addr, IEEE80211_ADDR_LEN); 1578 memcpy(cmd->addr[i], mclist->da_addr, ETH_ALEN);
1714 index++;
1715 mclist = mclist->next; 1579 mclist = mclist->next;
1716 } 1580 }
1717 1581
1718 rc = mwl8k_post_cmd(hw, &cmd->header); 1582 return &cmd->header;
1719
1720mwl8k_cmd_mac_multicast_adr_exit:
1721 kfree(cmd);
1722 return rc;
1723} 1583}
1724 1584
1725/* 1585/*
@@ -1776,18 +1636,16 @@ struct mwl8k_cmd_802_11_radio_control {
1776 __le16 radio_on; 1636 __le16 radio_on;
1777} __attribute__((packed)); 1637} __attribute__((packed));
1778 1638
1779static int mwl8k_cmd_802_11_radio_control(struct ieee80211_hw *hw, int enable) 1639static int
1640mwl8k_cmd_802_11_radio_control(struct ieee80211_hw *hw, bool enable, bool force)
1780{ 1641{
1781 struct mwl8k_priv *priv = hw->priv; 1642 struct mwl8k_priv *priv = hw->priv;
1782 struct mwl8k_cmd_802_11_radio_control *cmd; 1643 struct mwl8k_cmd_802_11_radio_control *cmd;
1783 int rc; 1644 int rc;
1784 1645
1785 if (((enable & MWL8K_RADIO_ENABLE) == priv->radio_state) && 1646 if (enable == priv->radio_on && !force)
1786 !(enable & MWL8K_RADIO_FORCE))
1787 return 0; 1647 return 0;
1788 1648
1789 enable &= MWL8K_RADIO_ENABLE;
1790
1791 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 1649 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1792 if (cmd == NULL) 1650 if (cmd == NULL)
1793 return -ENOMEM; 1651 return -ENOMEM;
@@ -1795,18 +1653,28 @@ static int mwl8k_cmd_802_11_radio_control(struct ieee80211_hw *hw, int enable)
1795 cmd->header.code = cpu_to_le16(MWL8K_CMD_RADIO_CONTROL); 1653 cmd->header.code = cpu_to_le16(MWL8K_CMD_RADIO_CONTROL);
1796 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 1654 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1797 cmd->action = cpu_to_le16(MWL8K_CMD_SET); 1655 cmd->action = cpu_to_le16(MWL8K_CMD_SET);
1798 cmd->control = cpu_to_le16(priv->radio_preamble); 1656 cmd->control = cpu_to_le16(priv->radio_short_preamble ? 3 : 1);
1799 cmd->radio_on = cpu_to_le16(enable ? 0x0001 : 0x0000); 1657 cmd->radio_on = cpu_to_le16(enable ? 0x0001 : 0x0000);
1800 1658
1801 rc = mwl8k_post_cmd(hw, &cmd->header); 1659 rc = mwl8k_post_cmd(hw, &cmd->header);
1802 kfree(cmd); 1660 kfree(cmd);
1803 1661
1804 if (!rc) 1662 if (!rc)
1805 priv->radio_state = enable; 1663 priv->radio_on = enable;
1806 1664
1807 return rc; 1665 return rc;
1808} 1666}
1809 1667
1668static int mwl8k_cmd_802_11_radio_disable(struct ieee80211_hw *hw)
1669{
1670 return mwl8k_cmd_802_11_radio_control(hw, 0, 0);
1671}
1672
1673static int mwl8k_cmd_802_11_radio_enable(struct ieee80211_hw *hw)
1674{
1675 return mwl8k_cmd_802_11_radio_control(hw, 1, 0);
1676}
1677
1810static int 1678static int
1811mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble) 1679mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble)
1812{ 1680{
@@ -1816,12 +1684,9 @@ mwl8k_set_radio_preamble(struct ieee80211_hw *hw, bool short_preamble)
1816 return -EINVAL; 1684 return -EINVAL;
1817 priv = hw->priv; 1685 priv = hw->priv;
1818 1686
1819 priv->radio_preamble = (short_preamble ? 1687 priv->radio_short_preamble = short_preamble;
1820 MWL8K_RADIO_SHORT_PREAMBLE :
1821 MWL8K_RADIO_LONG_PREAMBLE);
1822 1688
1823 return mwl8k_cmd_802_11_radio_control(hw, 1689 return mwl8k_cmd_802_11_radio_control(hw, 1, 1);
1824 MWL8K_RADIO_ENABLE | MWL8K_RADIO_FORCE);
1825} 1690}
1826 1691
1827/* 1692/*
@@ -1889,11 +1754,11 @@ static int mwl8k_cmd_set_pre_scan(struct ieee80211_hw *hw)
1889struct mwl8k_cmd_set_post_scan { 1754struct mwl8k_cmd_set_post_scan {
1890 struct mwl8k_cmd_pkt header; 1755 struct mwl8k_cmd_pkt header;
1891 __le32 isibss; 1756 __le32 isibss;
1892 __u8 bssid[IEEE80211_ADDR_LEN]; 1757 __u8 bssid[ETH_ALEN];
1893} __attribute__((packed)); 1758} __attribute__((packed));
1894 1759
1895static int 1760static int
1896mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, __u8 mac[IEEE80211_ADDR_LEN]) 1761mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, __u8 *mac)
1897{ 1762{
1898 struct mwl8k_cmd_set_post_scan *cmd; 1763 struct mwl8k_cmd_set_post_scan *cmd;
1899 int rc; 1764 int rc;
@@ -1905,7 +1770,7 @@ mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, __u8 mac[IEEE80211_ADDR_LEN])
1905 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_POST_SCAN); 1770 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_POST_SCAN);
1906 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 1771 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1907 cmd->isibss = 0; 1772 cmd->isibss = 0;
1908 memcpy(cmd->bssid, mac, IEEE80211_ADDR_LEN); 1773 memcpy(cmd->bssid, mac, ETH_ALEN);
1909 1774
1910 rc = mwl8k_post_cmd(hw, &cmd->header); 1775 rc = mwl8k_post_cmd(hw, &cmd->header);
1911 kfree(cmd); 1776 kfree(cmd);
@@ -1957,7 +1822,7 @@ struct mwl8k_cmd_set_slot {
1957 __u8 short_slot; 1822 __u8 short_slot;
1958} __attribute__((packed)); 1823} __attribute__((packed));
1959 1824
1960static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, int slot_time) 1825static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, bool short_slot_time)
1961{ 1826{
1962 struct mwl8k_cmd_set_slot *cmd; 1827 struct mwl8k_cmd_set_slot *cmd;
1963 int rc; 1828 int rc;
@@ -1969,7 +1834,7 @@ static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, int slot_time)
1969 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT); 1834 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_SLOT);
1970 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 1835 cmd->header.length = cpu_to_le16(sizeof(*cmd));
1971 cmd->action = cpu_to_le16(MWL8K_CMD_SET); 1836 cmd->action = cpu_to_le16(MWL8K_CMD_SET);
1972 cmd->short_slot = slot_time == MWL8K_SHORT_SLOTTIME ? 1 : 0; 1837 cmd->short_slot = short_slot_time;
1973 1838
1974 rc = mwl8k_post_cmd(hw, &cmd->header); 1839 rc = mwl8k_post_cmd(hw, &cmd->header);
1975 kfree(cmd); 1840 kfree(cmd);
@@ -2027,7 +1892,7 @@ static int mwl8k_enable_sniffer(struct ieee80211_hw *hw, bool enable)
2027 1892
2028 cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER); 1893 cmd->header.code = cpu_to_le16(MWL8K_CMD_ENABLE_SNIFFER);
2029 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 1894 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2030 cmd->action = enable ? cpu_to_le32((u32)MWL8K_CMD_SET) : 0; 1895 cmd->action = cpu_to_le32(!!enable);
2031 1896
2032 rc = mwl8k_post_cmd(hw, &cmd->header); 1897 rc = mwl8k_post_cmd(hw, &cmd->header);
2033 kfree(cmd); 1898 kfree(cmd);
@@ -2036,7 +1901,7 @@ static int mwl8k_enable_sniffer(struct ieee80211_hw *hw, bool enable)
2036} 1901}
2037 1902
2038/* 1903/*
2039 * CMD_SET_RATE_ADAPT_MODE. 1904 * CMD_SET_RATEADAPT_MODE.
2040 */ 1905 */
2041struct mwl8k_cmd_set_rate_adapt_mode { 1906struct mwl8k_cmd_set_rate_adapt_mode {
2042 struct mwl8k_cmd_pkt header; 1907 struct mwl8k_cmd_pkt header;
@@ -2084,13 +1949,13 @@ static int mwl8k_set_wmm(struct ieee80211_hw *hw, bool enable)
2084 1949
2085 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE); 1950 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_WMM_MODE);
2086 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 1951 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2087 cmd->action = enable ? cpu_to_le16(MWL8K_CMD_SET) : 0; 1952 cmd->action = cpu_to_le16(!!enable);
2088 1953
2089 rc = mwl8k_post_cmd(hw, &cmd->header); 1954 rc = mwl8k_post_cmd(hw, &cmd->header);
2090 kfree(cmd); 1955 kfree(cmd);
2091 1956
2092 if (!rc) 1957 if (!rc)
2093 priv->wmm_mode = enable; 1958 priv->wmm_enabled = enable;
2094 1959
2095 return rc; 1960 return rc;
2096} 1961}
@@ -2105,7 +1970,7 @@ struct mwl8k_cmd_rts_threshold {
2105} __attribute__((packed)); 1970} __attribute__((packed));
2106 1971
2107static int mwl8k_rts_threshold(struct ieee80211_hw *hw, 1972static int mwl8k_rts_threshold(struct ieee80211_hw *hw,
2108 u16 action, u16 *threshold) 1973 u16 action, u16 threshold)
2109{ 1974{
2110 struct mwl8k_cmd_rts_threshold *cmd; 1975 struct mwl8k_cmd_rts_threshold *cmd;
2111 int rc; 1976 int rc;
@@ -2117,7 +1982,7 @@ static int mwl8k_rts_threshold(struct ieee80211_hw *hw,
2117 cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD); 1982 cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD);
2118 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 1983 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2119 cmd->action = cpu_to_le16(action); 1984 cmd->action = cpu_to_le16(action);
2120 cmd->threshold = cpu_to_le16(*threshold); 1985 cmd->threshold = cpu_to_le16(threshold);
2121 1986
2122 rc = mwl8k_post_cmd(hw, &cmd->header); 1987 rc = mwl8k_post_cmd(hw, &cmd->header);
2123 kfree(cmd); 1988 kfree(cmd);
@@ -2150,7 +2015,6 @@ struct mwl8k_cmd_set_edca_params {
2150 __u8 txq; 2015 __u8 txq;
2151} __attribute__((packed)); 2016} __attribute__((packed));
2152 2017
2153#define MWL8K_GET_EDCA_ALL 0
2154#define MWL8K_SET_EDCA_CW 0x01 2018#define MWL8K_SET_EDCA_CW 0x01
2155#define MWL8K_SET_EDCA_TXOP 0x02 2019#define MWL8K_SET_EDCA_TXOP 0x02
2156#define MWL8K_SET_EDCA_AIFS 0x04 2020#define MWL8K_SET_EDCA_AIFS 0x04
@@ -2165,22 +2029,18 @@ mwl8k_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
2165 __u8 aifs, __u16 txop) 2029 __u8 aifs, __u16 txop)
2166{ 2030{
2167 struct mwl8k_cmd_set_edca_params *cmd; 2031 struct mwl8k_cmd_set_edca_params *cmd;
2168 u32 log_cw_min, log_cw_max;
2169 int rc; 2032 int rc;
2170 2033
2171 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2034 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2172 if (cmd == NULL) 2035 if (cmd == NULL)
2173 return -ENOMEM; 2036 return -ENOMEM;
2174 2037
2175 log_cw_min = ilog2(cw_min+1);
2176 log_cw_max = ilog2(cw_max+1);
2177 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS); 2038 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS);
2178 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2039 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2179
2180 cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL); 2040 cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL);
2181 cmd->txop = cpu_to_le16(txop); 2041 cmd->txop = cpu_to_le16(txop);
2182 cmd->log_cw_max = (u8)log_cw_max; 2042 cmd->log_cw_max = (u8)ilog2(cw_max + 1);
2183 cmd->log_cw_min = (u8)log_cw_min; 2043 cmd->log_cw_min = (u8)ilog2(cw_min + 1);
2184 cmd->aifs = aifs; 2044 cmd->aifs = aifs;
2185 cmd->txq = qnum; 2045 cmd->txq = qnum;
2186 2046
@@ -2221,11 +2081,7 @@ static int mwl8k_finalize_join(struct ieee80211_hw *hw, void *frame,
2221 2081
2222 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN); 2082 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_FINALIZE_JOIN);
2223 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2083 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2224 2084 cmd->sleep_interval = cpu_to_le32(dtim ? dtim : 1);
2225 if (dtim)
2226 cmd->sleep_interval = cpu_to_le32(dtim);
2227 else
2228 cmd->sleep_interval = cpu_to_le32(1);
2229 2085
2230 hdrlen = ieee80211_hdrlen(payload->frame_control); 2086 hdrlen = ieee80211_hdrlen(payload->frame_control);
2231 2087
@@ -2237,8 +2093,8 @@ static int mwl8k_finalize_join(struct ieee80211_hw *hw, void *frame,
2237 "sent to firmware. Sz=%u MAX=%u\n", __func__, 2093 "sent to firmware. Sz=%u MAX=%u\n", __func__,
2238 payload_len, MWL8K_FJ_BEACON_MAXLEN); 2094 payload_len, MWL8K_FJ_BEACON_MAXLEN);
2239 2095
2240 payload_len = payload_len > MWL8K_FJ_BEACON_MAXLEN ? 2096 if (payload_len > MWL8K_FJ_BEACON_MAXLEN)
2241 MWL8K_FJ_BEACON_MAXLEN : payload_len; 2097 payload_len = MWL8K_FJ_BEACON_MAXLEN;
2242 2098
2243 if (payload && payload_len) 2099 if (payload && payload_len)
2244 memcpy(cmd->beacon_data, &payload->u.beacon, payload_len); 2100 memcpy(cmd->beacon_data, &payload->u.beacon, payload_len);
@@ -2258,7 +2114,7 @@ struct mwl8k_cmd_update_sta_db {
2258 __le32 action; 2114 __le32 action;
2259 2115
2260 /* Peer MAC address */ 2116 /* Peer MAC address */
2261 __u8 peer_addr[IEEE80211_ADDR_LEN]; 2117 __u8 peer_addr[ETH_ALEN];
2262 2118
2263 __le32 reserved; 2119 __le32 reserved;
2264 2120
@@ -2286,7 +2142,7 @@ static int mwl8k_cmd_update_sta_db(struct ieee80211_hw *hw,
2286 2142
2287 cmd->action = cpu_to_le32(action); 2143 cmd->action = cpu_to_le32(action);
2288 peer_info = &cmd->peer_info; 2144 peer_info = &cmd->peer_info;
2289 memcpy(cmd->peer_addr, mv_vif->bssid, IEEE80211_ADDR_LEN); 2145 memcpy(cmd->peer_addr, mv_vif->bssid, ETH_ALEN);
2290 2146
2291 switch (action) { 2147 switch (action) {
2292 case MWL8K_STA_DB_ADD_ENTRY: 2148 case MWL8K_STA_DB_ADD_ENTRY:
@@ -2298,7 +2154,7 @@ static int mwl8k_cmd_update_sta_db(struct ieee80211_hw *hw,
2298 peer_info->amsdu_enabled = 0; 2154 peer_info->amsdu_enabled = 0;
2299 2155
2300 rates = peer_info->legacy_rates; 2156 rates = peer_info->legacy_rates;
2301 for (count = 0 ; count < mv_vif->legacy_nrates; count++) 2157 for (count = 0; count < mv_vif->legacy_nrates; count++)
2302 rates[count] = bitrates[count].hw_value; 2158 rates[count] = bitrates[count].hw_value;
2303 2159
2304 rc = mwl8k_post_cmd(hw, &cmd->header); 2160 rc = mwl8k_post_cmd(hw, &cmd->header);
@@ -2323,25 +2179,19 @@ static int mwl8k_cmd_update_sta_db(struct ieee80211_hw *hw,
2323/* 2179/*
2324 * CMD_SET_AID. 2180 * CMD_SET_AID.
2325 */ 2181 */
2326#define IEEE80211_OPMODE_DISABLED 0x00
2327#define IEEE80211_OPMODE_NON_MEMBER_PROT_MODE 0x01
2328#define IEEE80211_OPMODE_ONE_20MHZ_STA_PROT_MODE 0x02
2329#define IEEE80211_OPMODE_HTMIXED_PROT_MODE 0x03
2330
2331#define MWL8K_RATE_INDEX_MAX_ARRAY 14 2182#define MWL8K_RATE_INDEX_MAX_ARRAY 14
2332 2183
2333#define MWL8K_FRAME_PROT_DISABLED 0x00 2184#define MWL8K_FRAME_PROT_DISABLED 0x00
2334#define MWL8K_FRAME_PROT_11G 0x07 2185#define MWL8K_FRAME_PROT_11G 0x07
2335#define MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY 0x02 2186#define MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY 0x02
2336#define MWL8K_FRAME_PROT_11N_HT_ALL 0x06 2187#define MWL8K_FRAME_PROT_11N_HT_ALL 0x06
2337#define MWL8K_FRAME_PROT_MASK 0x07
2338 2188
2339struct mwl8k_cmd_update_set_aid { 2189struct mwl8k_cmd_update_set_aid {
2340 struct mwl8k_cmd_pkt header; 2190 struct mwl8k_cmd_pkt header;
2341 __le16 aid; 2191 __le16 aid;
2342 2192
2343 /* AP's MAC address (BSSID) */ 2193 /* AP's MAC address (BSSID) */
2344 __u8 bssid[IEEE80211_ADDR_LEN]; 2194 __u8 bssid[ETH_ALEN];
2345 __le16 protection_mode; 2195 __le16 protection_mode;
2346 __u8 supp_rates[MWL8K_RATE_INDEX_MAX_ARRAY]; 2196 __u8 supp_rates[MWL8K_RATE_INDEX_MAX_ARRAY];
2347} __attribute__((packed)); 2197} __attribute__((packed));
@@ -2365,9 +2215,7 @@ static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
2365 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2215 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2366 cmd->aid = cpu_to_le16(info->aid); 2216 cmd->aid = cpu_to_le16(info->aid);
2367 2217
2368 memcpy(cmd->bssid, mv_vif->bssid, IEEE80211_ADDR_LEN); 2218 memcpy(cmd->bssid, mv_vif->bssid, ETH_ALEN);
2369
2370 prot_mode = MWL8K_FRAME_PROT_DISABLED;
2371 2219
2372 if (info->use_cts_prot) { 2220 if (info->use_cts_prot) {
2373 prot_mode = MWL8K_FRAME_PROT_11G; 2221 prot_mode = MWL8K_FRAME_PROT_11G;
@@ -2385,7 +2233,6 @@ static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
2385 break; 2233 break;
2386 } 2234 }
2387 } 2235 }
2388
2389 cmd->protection_mode = cpu_to_le16(prot_mode); 2236 cmd->protection_mode = cpu_to_le16(prot_mode);
2390 2237
2391 for (count = 0; count < mv_vif->legacy_nrates; count++) 2238 for (count = 0; count < mv_vif->legacy_nrates; count++)
@@ -2439,10 +2286,6 @@ static int mwl8k_update_rateset(struct ieee80211_hw *hw,
2439 */ 2286 */
2440#define MWL8K_RATE_TABLE_SIZE 8 2287#define MWL8K_RATE_TABLE_SIZE 8
2441#define MWL8K_UCAST_RATE 0 2288#define MWL8K_UCAST_RATE 0
2442#define MWL8K_MCAST_RATE 1
2443#define MWL8K_BCAST_RATE 2
2444
2445#define MWL8K_USE_FIXED_RATE 0x0001
2446#define MWL8K_USE_AUTO_RATE 0x0002 2289#define MWL8K_USE_AUTO_RATE 0x0002
2447 2290
2448struct mwl8k_rate_entry { 2291struct mwl8k_rate_entry {
@@ -2535,7 +2378,6 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
2535 status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 2378 status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
2536 iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 2379 iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
2537 2380
2538 status &= priv->int_mask;
2539 if (!status) 2381 if (!status)
2540 return IRQ_NONE; 2382 return IRQ_NONE;
2541 2383
@@ -2548,17 +2390,14 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
2548 } 2390 }
2549 2391
2550 if (status & MWL8K_A2H_INT_OPC_DONE) { 2392 if (status & MWL8K_A2H_INT_OPC_DONE) {
2551 if (priv->hostcmd_wait != NULL) { 2393 if (priv->hostcmd_wait != NULL)
2552 complete(priv->hostcmd_wait); 2394 complete(priv->hostcmd_wait);
2553 priv->hostcmd_wait = NULL;
2554 }
2555 } 2395 }
2556 2396
2557 if (status & MWL8K_A2H_INT_QUEUE_EMPTY) { 2397 if (status & MWL8K_A2H_INT_QUEUE_EMPTY) {
2558 if (!priv->inconfig && 2398 if (!mutex_is_locked(&priv->fw_mutex) &&
2559 priv->radio_state && 2399 priv->radio_on && mwl8k_txq_busy(priv))
2560 mwl8k_txq_busy(priv)) 2400 mwl8k_tx_start(priv);
2561 mwl8k_tx_start(priv);
2562 } 2401 }
2563 2402
2564 return IRQ_HANDLED; 2403 return IRQ_HANDLED;
@@ -2586,365 +2425,68 @@ static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2586 return rc; 2425 return rc;
2587} 2426}
2588 2427
2589struct mwl8k_work_struct {
2590 /* Initialized by mwl8k_queue_work(). */
2591 struct work_struct wt;
2592
2593 /* Required field passed in to mwl8k_queue_work(). */
2594 struct ieee80211_hw *hw;
2595
2596 /* Required field passed in to mwl8k_queue_work(). */
2597 int (*wfunc)(struct work_struct *w);
2598
2599 /* Initialized by mwl8k_queue_work(). */
2600 struct completion *cmd_wait;
2601
2602 /* Result code. */
2603 int rc;
2604
2605 /*
2606 * Optional field. Refer to explanation of MWL8K_WQ_XXX_XXX
2607 * flags for explanation. Defaults to MWL8K_WQ_DEFAULT_OPTIONS.
2608 */
2609 u32 options;
2610
2611 /* Optional field. Defaults to MWL8K_CONFIG_TIMEOUT_MS. */
2612 unsigned long timeout_ms;
2613
2614 /* Optional field. Defaults to MWL8K_WQ_TXWAIT_ATTEMPTS. */
2615 u32 txwait_attempts;
2616
2617 /* Optional field. Defaults to MWL8K_TXWAIT_MS. */
2618 u32 tx_timeout_ms;
2619 u32 step;
2620};
2621
2622/* Flags controlling behavior of config queue requests */
2623
2624/* Caller spins while waiting for completion. */
2625#define MWL8K_WQ_SPIN 0x00000001
2626
2627/* Wait for TX queues to empty before proceeding with configuration. */
2628#define MWL8K_WQ_TX_WAIT_EMPTY 0x00000002
2629
2630/* Queue request and return immediately. */
2631#define MWL8K_WQ_POST_REQUEST 0x00000004
2632
2633/*
2634 * Caller sleeps and waits for task complete notification.
2635 * Do not use in atomic context.
2636 */
2637#define MWL8K_WQ_SLEEP 0x00000008
2638
2639/* Free work struct when task is done. */
2640#define MWL8K_WQ_FREE_WORKSTRUCT 0x00000010
2641
2642/*
2643 * Config request is queued and returns to caller imediately. Use
2644 * this in atomic context. Work struct is freed by mwl8k_queue_work()
2645 * when this flag is set.
2646 */
2647#define MWL8K_WQ_QUEUE_ONLY (MWL8K_WQ_POST_REQUEST | \
2648 MWL8K_WQ_FREE_WORKSTRUCT)
2649
2650/* Default work queue behavior is to sleep and wait for tx completion. */
2651#define MWL8K_WQ_DEFAULT_OPTIONS (MWL8K_WQ_SLEEP | MWL8K_WQ_TX_WAIT_EMPTY)
2652
2653/*
2654 * Default config request timeout. Add adjustments to make sure the
2655 * config thread waits long enough for both tx wait and cmd wait before
2656 * timing out.
2657 */
2658
2659/* Time to wait for all TXQs to drain. TX Doorbell is pressed each time. */
2660#define MWL8K_TXWAIT_TIMEOUT_MS 1000
2661
2662/* Default number of TX wait attempts. */
2663#define MWL8K_WQ_TXWAIT_ATTEMPTS 4
2664
2665/* Total time to wait for TXQ to drain. */
2666#define MWL8K_TXWAIT_MS (MWL8K_TXWAIT_TIMEOUT_MS * \
2667 MWL8K_WQ_TXWAIT_ATTEMPTS)
2668
2669/* Scheduling slop. */
2670#define MWL8K_OS_SCHEDULE_OVERHEAD_MS 200
2671
2672#define MWL8K_CONFIG_TIMEOUT_MS (MWL8K_CMD_TIMEOUT_MS + \
2673 MWL8K_TXWAIT_MS + \
2674 MWL8K_OS_SCHEDULE_OVERHEAD_MS)
2675
2676static void mwl8k_config_thread(struct work_struct *wt)
2677{
2678 struct mwl8k_work_struct *worker = (struct mwl8k_work_struct *)wt;
2679 struct ieee80211_hw *hw = worker->hw;
2680 struct mwl8k_priv *priv = hw->priv;
2681 int rc = 0;
2682
2683 spin_lock_irq(&priv->tx_lock);
2684 priv->inconfig = true;
2685 spin_unlock_irq(&priv->tx_lock);
2686
2687 ieee80211_stop_queues(hw);
2688
2689 /*
2690 * Wait for host queues to drain before doing PHY
2691 * reconfiguration. This avoids interrupting any in-flight
2692 * DMA transfers to the hardware.
2693 */
2694 if (worker->options & MWL8K_WQ_TX_WAIT_EMPTY) {
2695 u32 timeout;
2696 u32 time_remaining;
2697 u32 iter;
2698 u32 tx_wait_attempts = worker->txwait_attempts;
2699
2700 time_remaining = worker->tx_timeout_ms;
2701 if (!tx_wait_attempts)
2702 tx_wait_attempts = 1;
2703
2704 timeout = worker->tx_timeout_ms/tx_wait_attempts;
2705 if (!timeout)
2706 timeout = 1;
2707
2708 iter = tx_wait_attempts;
2709 do {
2710 int wait_time;
2711
2712 if (time_remaining > timeout) {
2713 time_remaining -= timeout;
2714 wait_time = timeout;
2715 } else
2716 wait_time = time_remaining;
2717
2718 if (!wait_time)
2719 wait_time = 1;
2720
2721 rc = mwl8k_tx_wait_empty(hw, wait_time);
2722 if (rc)
2723 printk(KERN_ERR "%s() txwait timeout=%ums "
2724 "Retry:%u/%u\n", __func__, timeout,
2725 tx_wait_attempts - iter + 1,
2726 tx_wait_attempts);
2727
2728 } while (rc && --iter);
2729
2730 rc = iter ? 0 : -ETIMEDOUT;
2731 }
2732 if (!rc)
2733 rc = worker->wfunc(wt);
2734
2735 spin_lock_irq(&priv->tx_lock);
2736 priv->inconfig = false;
2737 if (priv->pending_tx_pkts && priv->radio_state)
2738 mwl8k_tx_start(priv);
2739 spin_unlock_irq(&priv->tx_lock);
2740 ieee80211_wake_queues(hw);
2741
2742 worker->rc = rc;
2743 if (worker->options & MWL8K_WQ_SLEEP)
2744 complete(worker->cmd_wait);
2745
2746 if (worker->options & MWL8K_WQ_FREE_WORKSTRUCT)
2747 kfree(wt);
2748}
2749
2750static int mwl8k_queue_work(struct ieee80211_hw *hw,
2751 struct mwl8k_work_struct *worker,
2752 struct workqueue_struct *wqueue,
2753 int (*wfunc)(struct work_struct *w))
2754{
2755 unsigned long timeout = 0;
2756 int rc = 0;
2757
2758 DECLARE_COMPLETION_ONSTACK(cmd_wait);
2759
2760 if (!worker->timeout_ms)
2761 worker->timeout_ms = MWL8K_CONFIG_TIMEOUT_MS;
2762
2763 if (!worker->options)
2764 worker->options = MWL8K_WQ_DEFAULT_OPTIONS;
2765
2766 if (!worker->txwait_attempts)
2767 worker->txwait_attempts = MWL8K_WQ_TXWAIT_ATTEMPTS;
2768
2769 if (!worker->tx_timeout_ms)
2770 worker->tx_timeout_ms = MWL8K_TXWAIT_MS;
2771
2772 worker->hw = hw;
2773 worker->cmd_wait = &cmd_wait;
2774 worker->rc = 1;
2775 worker->wfunc = wfunc;
2776
2777 INIT_WORK(&worker->wt, mwl8k_config_thread);
2778 queue_work(wqueue, &worker->wt);
2779
2780 if (worker->options & MWL8K_WQ_POST_REQUEST) {
2781 rc = 0;
2782 } else {
2783 if (worker->options & MWL8K_WQ_SPIN) {
2784 timeout = worker->timeout_ms;
2785 while (timeout && (worker->rc > 0)) {
2786 mdelay(1);
2787 timeout--;
2788 }
2789 } else if (worker->options & MWL8K_WQ_SLEEP)
2790 timeout = wait_for_completion_timeout(&cmd_wait,
2791 msecs_to_jiffies(worker->timeout_ms));
2792
2793 if (timeout)
2794 rc = worker->rc;
2795 else {
2796 cancel_work_sync(&worker->wt);
2797 rc = -ETIMEDOUT;
2798 }
2799 }
2800
2801 return rc;
2802}
2803
2804struct mwl8k_start_worker {
2805 struct mwl8k_work_struct header;
2806};
2807
2808static int mwl8k_start_wt(struct work_struct *wt)
2809{
2810 struct mwl8k_start_worker *worker = (struct mwl8k_start_worker *)wt;
2811 struct ieee80211_hw *hw = worker->header.hw;
2812 struct mwl8k_priv *priv = hw->priv;
2813 int rc = 0;
2814
2815 if (priv->vif != NULL) {
2816 rc = -EIO;
2817 goto mwl8k_start_exit;
2818 }
2819
2820 /* Turn on radio */
2821 if (mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_ENABLE)) {
2822 rc = -EIO;
2823 goto mwl8k_start_exit;
2824 }
2825
2826 /* Purge TX/RX HW queues */
2827 if (mwl8k_cmd_set_pre_scan(hw)) {
2828 rc = -EIO;
2829 goto mwl8k_start_exit;
2830 }
2831
2832 if (mwl8k_cmd_set_post_scan(hw, "\x00\x00\x00\x00\x00\x00")) {
2833 rc = -EIO;
2834 goto mwl8k_start_exit;
2835 }
2836
2837 /* Enable firmware rate adaptation */
2838 if (mwl8k_cmd_setrateadaptmode(hw, 0)) {
2839 rc = -EIO;
2840 goto mwl8k_start_exit;
2841 }
2842
2843 /* Disable WMM. WMM gets enabled when stack sends WMM parms */
2844 if (mwl8k_set_wmm(hw, MWL8K_WMM_DISABLE)) {
2845 rc = -EIO;
2846 goto mwl8k_start_exit;
2847 }
2848
2849 /* Disable sniffer mode */
2850 if (mwl8k_enable_sniffer(hw, 0))
2851 rc = -EIO;
2852
2853mwl8k_start_exit:
2854 return rc;
2855}
2856
2857static int mwl8k_start(struct ieee80211_hw *hw) 2428static int mwl8k_start(struct ieee80211_hw *hw)
2858{ 2429{
2859 struct mwl8k_start_worker *worker;
2860 struct mwl8k_priv *priv = hw->priv; 2430 struct mwl8k_priv *priv = hw->priv;
2861 int rc; 2431 int rc;
2862 2432
2863 /* Enable tx reclaim tasklet */
2864 tasklet_enable(&priv->tx_reclaim_task);
2865
2866 rc = request_irq(priv->pdev->irq, &mwl8k_interrupt, 2433 rc = request_irq(priv->pdev->irq, &mwl8k_interrupt,
2867 IRQF_SHARED, MWL8K_NAME, hw); 2434 IRQF_SHARED, MWL8K_NAME, hw);
2868 if (rc) { 2435 if (rc) {
2869 printk(KERN_ERR "%s: failed to register IRQ handler\n", 2436 printk(KERN_ERR "%s: failed to register IRQ handler\n",
2870 priv->name); 2437 priv->name);
2871 rc = -EIO; 2438 return -EIO;
2872 goto mwl8k_start_disable_tasklet;
2873 } 2439 }
2874 2440
2875 /* Enable interrupts */ 2441 /* Enable tx reclaim tasklet */
2876 iowrite32(priv->int_mask, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 2442 tasklet_enable(&priv->tx_reclaim_task);
2877
2878 worker = kzalloc(sizeof(*worker), GFP_KERNEL);
2879 if (worker == NULL) {
2880 rc = -ENOMEM;
2881 goto mwl8k_start_disable_irq;
2882 }
2883 2443
2884 rc = mwl8k_queue_work(hw, &worker->header, 2444 /* Enable interrupts */
2885 priv->config_wq, mwl8k_start_wt); 2445 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
2886 kfree(worker);
2887 if (!rc)
2888 return rc;
2889 2446
2890 if (rc == -ETIMEDOUT) 2447 rc = mwl8k_fw_lock(hw);
2891 printk(KERN_ERR "%s() timed out\n", __func__); 2448 if (!rc) {
2449 rc = mwl8k_cmd_802_11_radio_enable(hw);
2892 2450
2893 rc = -EIO; 2451 if (!rc)
2452 rc = mwl8k_cmd_set_pre_scan(hw);
2894 2453
2895mwl8k_start_disable_irq: 2454 if (!rc)
2896 spin_lock_irq(&priv->tx_lock); 2455 rc = mwl8k_cmd_set_post_scan(hw,
2897 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 2456 "\x00\x00\x00\x00\x00\x00");
2898 spin_unlock_irq(&priv->tx_lock);
2899 free_irq(priv->pdev->irq, hw);
2900 2457
2901mwl8k_start_disable_tasklet: 2458 if (!rc)
2902 tasklet_disable(&priv->tx_reclaim_task); 2459 rc = mwl8k_cmd_setrateadaptmode(hw, 0);
2903 2460
2904 return rc; 2461 if (!rc)
2905} 2462 rc = mwl8k_set_wmm(hw, 0);
2906 2463
2907struct mwl8k_stop_worker { 2464 if (!rc)
2908 struct mwl8k_work_struct header; 2465 rc = mwl8k_enable_sniffer(hw, 0);
2909};
2910 2466
2911static int mwl8k_stop_wt(struct work_struct *wt) 2467 mwl8k_fw_unlock(hw);
2912{ 2468 }
2913 struct mwl8k_stop_worker *worker = (struct mwl8k_stop_worker *)wt;
2914 struct ieee80211_hw *hw = worker->header.hw;
2915 int rc;
2916 2469
2917 rc = mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_DISABLE); 2470 if (rc) {
2471 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
2472 free_irq(priv->pdev->irq, hw);
2473 tasklet_disable(&priv->tx_reclaim_task);
2474 }
2918 2475
2919 return rc; 2476 return rc;
2920} 2477}
2921 2478
2922static void mwl8k_stop(struct ieee80211_hw *hw) 2479static void mwl8k_stop(struct ieee80211_hw *hw)
2923{ 2480{
2924 int rc;
2925 struct mwl8k_stop_worker *worker;
2926 struct mwl8k_priv *priv = hw->priv; 2481 struct mwl8k_priv *priv = hw->priv;
2927 int i; 2482 int i;
2928 2483
2929 if (priv->vif != NULL) 2484 mwl8k_cmd_802_11_radio_disable(hw);
2930 return;
2931 2485
2932 ieee80211_stop_queues(hw); 2486 ieee80211_stop_queues(hw);
2933 2487
2934 worker = kzalloc(sizeof(*worker), GFP_KERNEL);
2935 if (worker == NULL)
2936 return;
2937
2938 rc = mwl8k_queue_work(hw, &worker->header,
2939 priv->config_wq, mwl8k_stop_wt);
2940 kfree(worker);
2941 if (rc == -ETIMEDOUT)
2942 printk(KERN_ERR "%s() timed out\n", __func__);
2943
2944 /* Disable interrupts */ 2488 /* Disable interrupts */
2945 spin_lock_irq(&priv->tx_lock);
2946 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 2489 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
2947 spin_unlock_irq(&priv->tx_lock);
2948 free_irq(priv->pdev->irq, hw); 2490 free_irq(priv->pdev->irq, hw);
2949 2491
2950 /* Stop finalize join worker */ 2492 /* Stop finalize join worker */
@@ -2978,8 +2520,7 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
2978 /* 2520 /*
2979 * We only support managed interfaces for now. 2521 * We only support managed interfaces for now.
2980 */ 2522 */
2981 if (conf->type != NL80211_IFTYPE_STATION && 2523 if (conf->type != NL80211_IFTYPE_STATION)
2982 conf->type != NL80211_IFTYPE_MONITOR)
2983 return -EINVAL; 2524 return -EINVAL;
2984 2525
2985 /* Clean out driver private area */ 2526 /* Clean out driver private area */
@@ -2987,13 +2528,13 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
2987 memset(mwl8k_vif, 0, sizeof(*mwl8k_vif)); 2528 memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
2988 2529
2989 /* Save the mac address */ 2530 /* Save the mac address */
2990 memcpy(mwl8k_vif->mac_addr, conf->mac_addr, IEEE80211_ADDR_LEN); 2531 memcpy(mwl8k_vif->mac_addr, conf->mac_addr, ETH_ALEN);
2991 2532
2992 /* Back pointer to parent config block */ 2533 /* Back pointer to parent config block */
2993 mwl8k_vif->priv = priv; 2534 mwl8k_vif->priv = priv;
2994 2535
2995 /* Setup initial PHY parameters */ 2536 /* Setup initial PHY parameters */
2996 memcpy(mwl8k_vif->legacy_rates , 2537 memcpy(mwl8k_vif->legacy_rates,
2997 priv->rates, sizeof(mwl8k_vif->legacy_rates)); 2538 priv->rates, sizeof(mwl8k_vif->legacy_rates));
2998 mwl8k_vif->legacy_nrates = ARRAY_SIZE(priv->rates); 2539 mwl8k_vif->legacy_nrates = ARRAY_SIZE(priv->rates);
2999 2540
@@ -3017,213 +2558,148 @@ static void mwl8k_remove_interface(struct ieee80211_hw *hw,
3017 priv->vif = NULL; 2558 priv->vif = NULL;
3018} 2559}
3019 2560
3020struct mwl8k_config_worker { 2561static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
3021 struct mwl8k_work_struct header;
3022 u32 changed;
3023};
3024
3025static int mwl8k_config_wt(struct work_struct *wt)
3026{ 2562{
3027 struct mwl8k_config_worker *worker =
3028 (struct mwl8k_config_worker *)wt;
3029 struct ieee80211_hw *hw = worker->header.hw;
3030 struct ieee80211_conf *conf = &hw->conf; 2563 struct ieee80211_conf *conf = &hw->conf;
3031 struct mwl8k_priv *priv = hw->priv; 2564 struct mwl8k_priv *priv = hw->priv;
3032 int rc = 0; 2565 int rc;
3033 2566
3034 if (!conf->radio_enabled) { 2567 if (conf->flags & IEEE80211_CONF_IDLE) {
3035 mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_DISABLE); 2568 mwl8k_cmd_802_11_radio_disable(hw);
3036 priv->current_channel = NULL; 2569 priv->current_channel = NULL;
3037 rc = 0; 2570 return 0;
3038 goto mwl8k_config_exit;
3039 } 2571 }
3040 2572
3041 if (mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_ENABLE)) { 2573 rc = mwl8k_fw_lock(hw);
3042 rc = -EINVAL; 2574 if (rc)
3043 goto mwl8k_config_exit; 2575 return rc;
3044 }
3045 2576
3046 priv->current_channel = conf->channel; 2577 rc = mwl8k_cmd_802_11_radio_enable(hw);
2578 if (rc)
2579 goto out;
3047 2580
3048 if (mwl8k_cmd_set_rf_channel(hw, conf->channel)) { 2581 rc = mwl8k_cmd_set_rf_channel(hw, conf->channel);
3049 rc = -EINVAL; 2582 if (rc)
3050 goto mwl8k_config_exit; 2583 goto out;
3051 } 2584
2585 priv->current_channel = conf->channel;
3052 2586
3053 if (conf->power_level > 18) 2587 if (conf->power_level > 18)
3054 conf->power_level = 18; 2588 conf->power_level = 18;
3055 if (mwl8k_cmd_802_11_rf_tx_power(hw, conf->power_level)) { 2589 rc = mwl8k_cmd_802_11_rf_tx_power(hw, conf->power_level);
3056 rc = -EINVAL; 2590 if (rc)
3057 goto mwl8k_config_exit; 2591 goto out;
3058 }
3059 2592
3060 if (mwl8k_cmd_mimo_config(hw, 0x7, 0x7)) 2593 if (mwl8k_cmd_mimo_config(hw, 0x7, 0x7))
3061 rc = -EINVAL; 2594 rc = -EINVAL;
3062 2595
3063mwl8k_config_exit: 2596out:
2597 mwl8k_fw_unlock(hw);
2598
3064 return rc; 2599 return rc;
3065} 2600}
3066 2601
3067static int mwl8k_config(struct ieee80211_hw *hw, u32 changed) 2602static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
2603 struct ieee80211_vif *vif,
2604 struct ieee80211_bss_conf *info,
2605 u32 changed)
3068{ 2606{
3069 int rc = 0;
3070 struct mwl8k_config_worker *worker;
3071 struct mwl8k_priv *priv = hw->priv; 2607 struct mwl8k_priv *priv = hw->priv;
3072 2608 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
3073 worker = kzalloc(sizeof(*worker), GFP_KERNEL);
3074 if (worker == NULL)
3075 return -ENOMEM;
3076
3077 worker->changed = changed;
3078 rc = mwl8k_queue_work(hw, &worker->header,
3079 priv->config_wq, mwl8k_config_wt);
3080 if (rc == -ETIMEDOUT) {
3081 printk(KERN_ERR "%s() timed out.\n", __func__);
3082 rc = -EINVAL;
3083 }
3084
3085 kfree(worker);
3086
3087 /*
3088 * mac80211 will crash on anything other than -EINVAL on
3089 * error. Looks like wireless extensions which calls mac80211
3090 * may be the actual culprit...
3091 */
3092 return rc ? -EINVAL : 0;
3093}
3094
3095struct mwl8k_bss_info_changed_worker {
3096 struct mwl8k_work_struct header;
3097 struct ieee80211_vif *vif;
3098 struct ieee80211_bss_conf *info;
3099 u32 changed;
3100};
3101
3102static int mwl8k_bss_info_changed_wt(struct work_struct *wt)
3103{
3104 struct mwl8k_bss_info_changed_worker *worker =
3105 (struct mwl8k_bss_info_changed_worker *)wt;
3106 struct ieee80211_hw *hw = worker->header.hw;
3107 struct ieee80211_vif *vif = worker->vif;
3108 struct ieee80211_bss_conf *info = worker->info;
3109 u32 changed;
3110 int rc; 2609 int rc;
3111 2610
3112 struct mwl8k_priv *priv = hw->priv; 2611 if (changed & BSS_CHANGED_BSSID)
3113 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); 2612 memcpy(mwl8k_vif->bssid, info->bssid, ETH_ALEN);
2613
2614 if ((changed & BSS_CHANGED_ASSOC) == 0)
2615 return;
3114 2616
3115 changed = worker->changed;
3116 priv->capture_beacon = false; 2617 priv->capture_beacon = false;
3117 2618
2619 rc = mwl8k_fw_lock(hw);
2620 if (!rc)
2621 return;
2622
3118 if (info->assoc) { 2623 if (info->assoc) {
3119 memcpy(&mwl8k_vif->bss_info, info, 2624 memcpy(&mwl8k_vif->bss_info, info,
3120 sizeof(struct ieee80211_bss_conf)); 2625 sizeof(struct ieee80211_bss_conf));
3121 2626
3122 /* Install rates */ 2627 /* Install rates */
3123 if (mwl8k_update_rateset(hw, vif)) 2628 rc = mwl8k_update_rateset(hw, vif);
3124 goto mwl8k_bss_info_changed_exit; 2629 if (rc)
2630 goto out;
3125 2631
3126 /* Turn on rate adaptation */ 2632 /* Turn on rate adaptation */
3127 if (mwl8k_cmd_use_fixed_rate(hw, MWL8K_USE_AUTO_RATE, 2633 rc = mwl8k_cmd_use_fixed_rate(hw, MWL8K_USE_AUTO_RATE,
3128 MWL8K_UCAST_RATE, NULL)) 2634 MWL8K_UCAST_RATE, NULL);
3129 goto mwl8k_bss_info_changed_exit; 2635 if (rc)
2636 goto out;
3130 2637
3131 /* Set radio preamble */ 2638 /* Set radio preamble */
3132 if (mwl8k_set_radio_preamble(hw, 2639 rc = mwl8k_set_radio_preamble(hw, info->use_short_preamble);
3133 info->use_short_preamble)) 2640 if (rc)
3134 goto mwl8k_bss_info_changed_exit; 2641 goto out;
3135 2642
3136 /* Set slot time */ 2643 /* Set slot time */
3137 if (mwl8k_cmd_set_slot(hw, info->use_short_slot ? 2644 rc = mwl8k_cmd_set_slot(hw, info->use_short_slot);
3138 MWL8K_SHORT_SLOTTIME : MWL8K_LONG_SLOTTIME)) 2645 if (rc)
3139 goto mwl8k_bss_info_changed_exit; 2646 goto out;
3140 2647
3141 /* Update peer rate info */ 2648 /* Update peer rate info */
3142 if (mwl8k_cmd_update_sta_db(hw, vif, 2649 rc = mwl8k_cmd_update_sta_db(hw, vif,
3143 MWL8K_STA_DB_MODIFY_ENTRY)) 2650 MWL8K_STA_DB_MODIFY_ENTRY);
3144 goto mwl8k_bss_info_changed_exit; 2651 if (rc)
2652 goto out;
3145 2653
3146 /* Set AID */ 2654 /* Set AID */
3147 if (mwl8k_cmd_set_aid(hw, vif)) 2655 rc = mwl8k_cmd_set_aid(hw, vif);
3148 goto mwl8k_bss_info_changed_exit; 2656 if (rc)
2657 goto out;
3149 2658
3150 /* 2659 /*
3151 * Finalize the join. Tell rx handler to process 2660 * Finalize the join. Tell rx handler to process
3152 * next beacon from our BSSID. 2661 * next beacon from our BSSID.
3153 */ 2662 */
3154 memcpy(priv->capture_bssid, 2663 memcpy(priv->capture_bssid, mwl8k_vif->bssid, ETH_ALEN);
3155 mwl8k_vif->bssid, IEEE80211_ADDR_LEN);
3156 priv->capture_beacon = true; 2664 priv->capture_beacon = true;
3157 } else { 2665 } else {
3158 mwl8k_cmd_update_sta_db(hw, vif, MWL8K_STA_DB_DEL_ENTRY); 2666 rc = mwl8k_cmd_update_sta_db(hw, vif, MWL8K_STA_DB_DEL_ENTRY);
3159 memset(&mwl8k_vif->bss_info, 0, 2667 memset(&mwl8k_vif->bss_info, 0,
3160 sizeof(struct ieee80211_bss_conf)); 2668 sizeof(struct ieee80211_bss_conf));
3161 memset(mwl8k_vif->bssid, 0, IEEE80211_ADDR_LEN); 2669 memset(mwl8k_vif->bssid, 0, ETH_ALEN);
3162 } 2670 }
3163 2671
3164mwl8k_bss_info_changed_exit: 2672out:
3165 rc = 0; 2673 mwl8k_fw_unlock(hw);
3166 return rc;
3167} 2674}
3168 2675
3169static void mwl8k_bss_info_changed(struct ieee80211_hw *hw, 2676static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
3170 struct ieee80211_vif *vif, 2677 int mc_count, struct dev_addr_list *mclist)
3171 struct ieee80211_bss_conf *info,
3172 u32 changed)
3173{ 2678{
3174 struct mwl8k_bss_info_changed_worker *worker; 2679 struct mwl8k_cmd_pkt *cmd;
3175 struct mwl8k_priv *priv = hw->priv;
3176 struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
3177 int rc;
3178
3179 if (changed & BSS_CHANGED_BSSID)
3180 memcpy(mv_vif->bssid, info->bssid, IEEE80211_ADDR_LEN);
3181
3182 if ((changed & BSS_CHANGED_ASSOC) == 0)
3183 return;
3184
3185 worker = kzalloc(sizeof(*worker), GFP_KERNEL);
3186 if (worker == NULL)
3187 return;
3188 2680
3189 worker->vif = vif; 2681 cmd = __mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist);
3190 worker->info = info;
3191 worker->changed = changed;
3192 rc = mwl8k_queue_work(hw, &worker->header,
3193 priv->config_wq,
3194 mwl8k_bss_info_changed_wt);
3195 kfree(worker);
3196 if (rc == -ETIMEDOUT)
3197 printk(KERN_ERR "%s() timed out\n", __func__);
3198}
3199
3200struct mwl8k_configure_filter_worker {
3201 struct mwl8k_work_struct header;
3202 unsigned int changed_flags;
3203 unsigned int *total_flags;
3204 int mc_count;
3205 struct dev_addr_list *mclist;
3206};
3207 2682
3208#define MWL8K_SUPPORTED_IF_FLAGS FIF_BCN_PRBRESP_PROMISC 2683 return (unsigned long)cmd;
2684}
3209 2685
3210static int mwl8k_configure_filter_wt(struct work_struct *wt) 2686static void mwl8k_configure_filter(struct ieee80211_hw *hw,
2687 unsigned int changed_flags,
2688 unsigned int *total_flags,
2689 u64 multicast)
3211{ 2690{
3212 struct mwl8k_configure_filter_worker *worker = 2691 struct mwl8k_priv *priv = hw->priv;
3213 (struct mwl8k_configure_filter_worker *)wt; 2692 struct mwl8k_cmd_pkt *multicast_adr_cmd;
3214 2693
3215 struct ieee80211_hw *hw = worker->header.hw; 2694 /* Clear unsupported feature flags */
3216 unsigned int changed_flags = worker->changed_flags; 2695 *total_flags &= FIF_BCN_PRBRESP_PROMISC;
3217 unsigned int *total_flags = worker->total_flags;
3218 int mc_count = worker->mc_count;
3219 struct dev_addr_list *mclist = worker->mclist;
3220 2696
3221 struct mwl8k_priv *priv = hw->priv; 2697 if (mwl8k_fw_lock(hw))
3222 int rc = 0; 2698 return;
3223 2699
3224 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { 2700 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
3225 if (*total_flags & FIF_BCN_PRBRESP_PROMISC) 2701 if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
3226 rc = mwl8k_cmd_set_pre_scan(hw); 2702 mwl8k_cmd_set_pre_scan(hw);
3227 else { 2703 else {
3228 u8 *bssid; 2704 u8 *bssid;
3229 2705
@@ -3231,151 +2707,45 @@ static int mwl8k_configure_filter_wt(struct work_struct *wt)
3231 if (priv->vif != NULL) 2707 if (priv->vif != NULL)
3232 bssid = MWL8K_VIF(priv->vif)->bssid; 2708 bssid = MWL8K_VIF(priv->vif)->bssid;
3233 2709
3234 rc = mwl8k_cmd_set_post_scan(hw, bssid); 2710 mwl8k_cmd_set_post_scan(hw, bssid);
3235 } 2711 }
3236 } 2712 }
3237 2713
3238 if (rc) 2714 multicast_adr_cmd = (void *)(unsigned long)multicast;
3239 goto mwl8k_configure_filter_exit; 2715 if (multicast_adr_cmd != NULL) {
3240 if (mc_count) { 2716 mwl8k_post_cmd(hw, multicast_adr_cmd);
3241 mc_count = mc_count < priv->num_mcaddrs ? 2717 kfree(multicast_adr_cmd);
3242 mc_count : priv->num_mcaddrs;
3243 rc = mwl8k_cmd_mac_multicast_adr(hw, mc_count, mclist);
3244 if (rc)
3245 printk(KERN_ERR
3246 "%s()Error setting multicast addresses\n",
3247 __func__);
3248 } 2718 }
3249 2719
3250mwl8k_configure_filter_exit: 2720 mwl8k_fw_unlock(hw);
3251 return rc;
3252}
3253
3254static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3255 unsigned int changed_flags,
3256 unsigned int *total_flags,
3257 int mc_count,
3258 struct dev_addr_list *mclist)
3259{
3260
3261 struct mwl8k_configure_filter_worker *worker;
3262 struct mwl8k_priv *priv = hw->priv;
3263
3264 /* Clear unsupported feature flags */
3265 *total_flags &= MWL8K_SUPPORTED_IF_FLAGS;
3266
3267 if (!(changed_flags & MWL8K_SUPPORTED_IF_FLAGS) && !mc_count)
3268 return;
3269
3270 worker = kzalloc(sizeof(*worker), GFP_ATOMIC);
3271 if (worker == NULL)
3272 return;
3273
3274 worker->header.options = MWL8K_WQ_QUEUE_ONLY | MWL8K_WQ_TX_WAIT_EMPTY;
3275 worker->changed_flags = changed_flags;
3276 worker->total_flags = total_flags;
3277 worker->mc_count = mc_count;
3278 worker->mclist = mclist;
3279
3280 mwl8k_queue_work(hw, &worker->header, priv->config_wq,
3281 mwl8k_configure_filter_wt);
3282}
3283
3284struct mwl8k_set_rts_threshold_worker {
3285 struct mwl8k_work_struct header;
3286 u32 value;
3287};
3288
3289static int mwl8k_set_rts_threshold_wt(struct work_struct *wt)
3290{
3291 struct mwl8k_set_rts_threshold_worker *worker =
3292 (struct mwl8k_set_rts_threshold_worker *)wt;
3293
3294 struct ieee80211_hw *hw = worker->header.hw;
3295 u16 threshold = (u16)(worker->value);
3296 int rc;
3297
3298 rc = mwl8k_rts_threshold(hw, MWL8K_CMD_SET, &threshold);
3299
3300 return rc;
3301} 2721}
3302 2722
3303static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 2723static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
3304{ 2724{
3305 int rc; 2725 return mwl8k_rts_threshold(hw, MWL8K_CMD_SET, value);
3306 struct mwl8k_set_rts_threshold_worker *worker;
3307 struct mwl8k_priv *priv = hw->priv;
3308
3309 worker = kzalloc(sizeof(*worker), GFP_KERNEL);
3310 if (worker == NULL)
3311 return -ENOMEM;
3312
3313 worker->value = value;
3314
3315 rc = mwl8k_queue_work(hw, &worker->header,
3316 priv->config_wq,
3317 mwl8k_set_rts_threshold_wt);
3318 kfree(worker);
3319
3320 if (rc == -ETIMEDOUT) {
3321 printk(KERN_ERR "%s() timed out\n", __func__);
3322 rc = -EINVAL;
3323 }
3324
3325 return rc;
3326}
3327
3328struct mwl8k_conf_tx_worker {
3329 struct mwl8k_work_struct header;
3330 u16 queue;
3331 const struct ieee80211_tx_queue_params *params;
3332};
3333
3334static int mwl8k_conf_tx_wt(struct work_struct *wt)
3335{
3336 struct mwl8k_conf_tx_worker *worker =
3337 (struct mwl8k_conf_tx_worker *)wt;
3338
3339 struct ieee80211_hw *hw = worker->header.hw;
3340 u16 queue = worker->queue;
3341 const struct ieee80211_tx_queue_params *params = worker->params;
3342
3343 struct mwl8k_priv *priv = hw->priv;
3344 int rc = 0;
3345
3346 if (priv->wmm_mode == MWL8K_WMM_DISABLE)
3347 if (mwl8k_set_wmm(hw, MWL8K_WMM_ENABLE)) {
3348 rc = -EINVAL;
3349 goto mwl8k_conf_tx_exit;
3350 }
3351
3352 if (mwl8k_set_edca_params(hw, GET_TXQ(queue), params->cw_min,
3353 params->cw_max, params->aifs, params->txop))
3354 rc = -EINVAL;
3355mwl8k_conf_tx_exit:
3356 return rc;
3357} 2726}
3358 2727
3359static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue, 2728static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
3360 const struct ieee80211_tx_queue_params *params) 2729 const struct ieee80211_tx_queue_params *params)
3361{ 2730{
3362 int rc;
3363 struct mwl8k_conf_tx_worker *worker;
3364 struct mwl8k_priv *priv = hw->priv; 2731 struct mwl8k_priv *priv = hw->priv;
2732 int rc;
3365 2733
3366 worker = kzalloc(sizeof(*worker), GFP_KERNEL); 2734 rc = mwl8k_fw_lock(hw);
3367 if (worker == NULL) 2735 if (!rc) {
3368 return -ENOMEM; 2736 if (!priv->wmm_enabled)
2737 rc = mwl8k_set_wmm(hw, 1);
3369 2738
3370 worker->queue = queue; 2739 if (!rc)
3371 worker->params = params; 2740 rc = mwl8k_set_edca_params(hw, queue,
3372 rc = mwl8k_queue_work(hw, &worker->header, 2741 params->cw_min,
3373 priv->config_wq, mwl8k_conf_tx_wt); 2742 params->cw_max,
3374 kfree(worker); 2743 params->aifs,
3375 if (rc == -ETIMEDOUT) { 2744 params->txop);
3376 printk(KERN_ERR "%s() timed out\n", __func__); 2745
3377 rc = -EINVAL; 2746 mwl8k_fw_unlock(hw);
3378 } 2747 }
2748
3379 return rc; 2749 return rc;
3380} 2750}
3381 2751
@@ -3393,44 +2763,14 @@ static int mwl8k_get_tx_stats(struct ieee80211_hw *hw,
3393 sizeof(struct ieee80211_tx_queue_stats)); 2763 sizeof(struct ieee80211_tx_queue_stats));
3394 } 2764 }
3395 spin_unlock_bh(&priv->tx_lock); 2765 spin_unlock_bh(&priv->tx_lock);
3396 return 0;
3397}
3398
3399struct mwl8k_get_stats_worker {
3400 struct mwl8k_work_struct header;
3401 struct ieee80211_low_level_stats *stats;
3402};
3403
3404static int mwl8k_get_stats_wt(struct work_struct *wt)
3405{
3406 struct mwl8k_get_stats_worker *worker =
3407 (struct mwl8k_get_stats_worker *)wt;
3408 2766
3409 return mwl8k_cmd_802_11_get_stat(worker->header.hw, worker->stats); 2767 return 0;
3410} 2768}
3411 2769
3412static int mwl8k_get_stats(struct ieee80211_hw *hw, 2770static int mwl8k_get_stats(struct ieee80211_hw *hw,
3413 struct ieee80211_low_level_stats *stats) 2771 struct ieee80211_low_level_stats *stats)
3414{ 2772{
3415 int rc; 2773 return mwl8k_cmd_802_11_get_stat(hw, stats);
3416 struct mwl8k_get_stats_worker *worker;
3417 struct mwl8k_priv *priv = hw->priv;
3418
3419 worker = kzalloc(sizeof(*worker), GFP_KERNEL);
3420 if (worker == NULL)
3421 return -ENOMEM;
3422
3423 worker->stats = stats;
3424 rc = mwl8k_queue_work(hw, &worker->header,
3425 priv->config_wq, mwl8k_get_stats_wt);
3426
3427 kfree(worker);
3428 if (rc == -ETIMEDOUT) {
3429 printk(KERN_ERR "%s() timed out\n", __func__);
3430 rc = -EINVAL;
3431 }
3432
3433 return rc;
3434} 2774}
3435 2775
3436static const struct ieee80211_ops mwl8k_ops = { 2776static const struct ieee80211_ops mwl8k_ops = {
@@ -3441,6 +2781,7 @@ static const struct ieee80211_ops mwl8k_ops = {
3441 .remove_interface = mwl8k_remove_interface, 2781 .remove_interface = mwl8k_remove_interface,
3442 .config = mwl8k_config, 2782 .config = mwl8k_config,
3443 .bss_info_changed = mwl8k_bss_info_changed, 2783 .bss_info_changed = mwl8k_bss_info_changed,
2784 .prepare_multicast = mwl8k_prepare_multicast,
3444 .configure_filter = mwl8k_configure_filter, 2785 .configure_filter = mwl8k_configure_filter,
3445 .set_rts_threshold = mwl8k_set_rts_threshold, 2786 .set_rts_threshold = mwl8k_set_rts_threshold,
3446 .conf_tx = mwl8k_conf_tx, 2787 .conf_tx = mwl8k_conf_tx,
@@ -3458,12 +2799,9 @@ static void mwl8k_tx_reclaim_handler(unsigned long data)
3458 for (i = 0; i < MWL8K_TX_QUEUES; i++) 2799 for (i = 0; i < MWL8K_TX_QUEUES; i++)
3459 mwl8k_txq_reclaim(hw, i, 0); 2800 mwl8k_txq_reclaim(hw, i, 0);
3460 2801
3461 if (priv->tx_wait != NULL) { 2802 if (priv->tx_wait != NULL && mwl8k_txq_busy(priv) == 0) {
3462 int count = mwl8k_txq_busy(priv); 2803 complete(priv->tx_wait);
3463 if (count == 0) { 2804 priv->tx_wait = NULL;
3464 complete(priv->tx_wait);
3465 priv->tx_wait = NULL;
3466 }
3467 } 2805 }
3468 spin_unlock_bh(&priv->tx_lock); 2806 spin_unlock_bh(&priv->tx_lock);
3469} 2807}
@@ -3473,7 +2811,7 @@ static void mwl8k_finalize_join_worker(struct work_struct *work)
3473 struct mwl8k_priv *priv = 2811 struct mwl8k_priv *priv =
3474 container_of(work, struct mwl8k_priv, finalize_join_worker); 2812 container_of(work, struct mwl8k_priv, finalize_join_worker);
3475 struct sk_buff *skb = priv->beacon_skb; 2813 struct sk_buff *skb = priv->beacon_skb;
3476 u8 dtim = (MWL8K_VIF(priv->vif))->bss_info.dtim_period; 2814 u8 dtim = MWL8K_VIF(priv->vif)->bss_info.dtim_period;
3477 2815
3478 mwl8k_finalize_join(priv->hw, skb->data, skb->len, dtim); 2816 mwl8k_finalize_join(priv->hw, skb->data, skb->len, dtim);
3479 dev_kfree_skb(skb); 2817 dev_kfree_skb(skb);
@@ -3516,16 +2854,10 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3516 priv = hw->priv; 2854 priv = hw->priv;
3517 priv->hw = hw; 2855 priv->hw = hw;
3518 priv->pdev = pdev; 2856 priv->pdev = pdev;
3519 priv->hostcmd_wait = NULL; 2857 priv->wmm_enabled = false;
3520 priv->tx_wait = NULL;
3521 priv->inconfig = false;
3522 priv->wep_enabled = 0;
3523 priv->wmm_mode = false;
3524 priv->pending_tx_pkts = 0; 2858 priv->pending_tx_pkts = 0;
3525 strncpy(priv->name, MWL8K_NAME, sizeof(priv->name)); 2859 strncpy(priv->name, MWL8K_NAME, sizeof(priv->name));
3526 2860
3527 spin_lock_init(&priv->fw_lock);
3528
3529 SET_IEEE80211_DEV(hw, &pdev->dev); 2861 SET_IEEE80211_DEV(hw, &pdev->dev);
3530 pci_set_drvdata(pdev, hw); 2862 pci_set_drvdata(pdev, hw);
3531 2863
@@ -3557,17 +2889,16 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3557 2889
3558 hw->queues = MWL8K_TX_QUEUES; 2890 hw->queues = MWL8K_TX_QUEUES;
3559 2891
3560 hw->wiphy->interface_modes = 2892 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
3561 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_MONITOR);
3562 2893
3563 /* Set rssi and noise values to dBm */ 2894 /* Set rssi and noise values to dBm */
3564 hw->flags |= (IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM); 2895 hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM;
3565 hw->vif_data_size = sizeof(struct mwl8k_vif); 2896 hw->vif_data_size = sizeof(struct mwl8k_vif);
3566 priv->vif = NULL; 2897 priv->vif = NULL;
3567 2898
3568 /* Set default radio state and preamble */ 2899 /* Set default radio state and preamble */
3569 priv->radio_preamble = MWL8K_RADIO_DEFAULT_PREAMBLE; 2900 priv->radio_on = 0;
3570 priv->radio_state = MWL8K_RADIO_DISABLE; 2901 priv->radio_short_preamble = 0;
3571 2902
3572 /* Finalize join worker */ 2903 /* Finalize join worker */
3573 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); 2904 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
@@ -3592,6 +2923,12 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3592 goto err_iounmap; 2923 goto err_iounmap;
3593 rxq_refill(hw, 0, INT_MAX); 2924 rxq_refill(hw, 0, INT_MAX);
3594 2925
2926 mutex_init(&priv->fw_mutex);
2927 priv->fw_mutex_owner = NULL;
2928 priv->fw_mutex_depth = 0;
2929 priv->tx_wait = NULL;
2930 priv->hostcmd_wait = NULL;
2931
3595 spin_lock_init(&priv->tx_lock); 2932 spin_lock_init(&priv->tx_lock);
3596 2933
3597 for (i = 0; i < MWL8K_TX_QUEUES; i++) { 2934 for (i = 0; i < MWL8K_TX_QUEUES; i++) {
@@ -3601,8 +2938,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3601 } 2938 }
3602 2939
3603 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 2940 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3604 priv->int_mask = 0; 2941 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
3605 iowrite32(priv->int_mask, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
3606 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); 2942 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
3607 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); 2943 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
3608 2944
@@ -3639,9 +2975,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3639 * commands use interrupts and avoids polling. Disable 2975 * commands use interrupts and avoids polling. Disable
3640 * interrupts when done. 2976 * interrupts when done.
3641 */ 2977 */
3642 priv->int_mask |= MWL8K_A2H_EVENTS; 2978 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
3643
3644 iowrite32(priv->int_mask, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
3645 2979
3646 /* Get config data, mac addrs etc */ 2980 /* Get config data, mac addrs etc */
3647 rc = mwl8k_cmd_get_hw_spec(hw); 2981 rc = mwl8k_cmd_get_hw_spec(hw);
@@ -3651,16 +2985,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3651 } 2985 }
3652 2986
3653 /* Turn radio off */ 2987 /* Turn radio off */
3654 rc = mwl8k_cmd_802_11_radio_control(hw, MWL8K_RADIO_DISABLE); 2988 rc = mwl8k_cmd_802_11_radio_disable(hw);
3655 if (rc) { 2989 if (rc) {
3656 printk(KERN_ERR "%s: Cannot disable\n", priv->name); 2990 printk(KERN_ERR "%s: Cannot disable\n", priv->name);
3657 goto err_stop_firmware; 2991 goto err_stop_firmware;
3658 } 2992 }
3659 2993
3660 /* Disable interrupts */ 2994 /* Disable interrupts */
3661 spin_lock_irq(&priv->tx_lock);
3662 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 2995 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
3663 spin_unlock_irq(&priv->tx_lock);
3664 free_irq(priv->pdev->irq, hw); 2996 free_irq(priv->pdev->irq, hw);
3665 2997
3666 rc = ieee80211_register_hw(hw); 2998 rc = ieee80211_register_hw(hw);
@@ -3684,9 +3016,7 @@ err_stop_firmware:
3684 mwl8k_release_firmware(priv); 3016 mwl8k_release_firmware(priv);
3685 3017
3686err_free_irq: 3018err_free_irq:
3687 spin_lock_irq(&priv->tx_lock);
3688 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 3019 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
3689 spin_unlock_irq(&priv->tx_lock);
3690 free_irq(priv->pdev->irq, hw); 3020 free_irq(priv->pdev->irq, hw);
3691 3021
3692err_free_queues: 3022err_free_queues:
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index 3e56f7643df5..7698fdd6a3a2 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -1291,7 +1291,7 @@ static int orinoco_ioctl_setibssport(struct net_device *dev,
1291 if (orinoco_lock(priv, &flags) != 0) 1291 if (orinoco_lock(priv, &flags) != 0)
1292 return -EBUSY; 1292 return -EBUSY;
1293 1293
1294 priv->ibss_port = val ; 1294 priv->ibss_port = val;
1295 1295
1296 /* Actually update the mode we are using */ 1296 /* Actually update the mode we are using */
1297 set_port_type(priv); 1297 set_port_type(priv);
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index 4a741df9c081..4d486bf9f725 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -302,7 +302,7 @@ out:
302static void p54_configure_filter(struct ieee80211_hw *dev, 302static void p54_configure_filter(struct ieee80211_hw *dev,
303 unsigned int changed_flags, 303 unsigned int changed_flags,
304 unsigned int *total_flags, 304 unsigned int *total_flags,
305 int mc_count, struct dev_mc_list *mclist) 305 u64 multicast)
306{ 306{
307 struct p54_common *priv = dev->priv; 307 struct p54_common *priv = dev->priv;
308 308
@@ -575,6 +575,12 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
575 dev->extra_tx_headroom = sizeof(struct p54_hdr) + 4 + 575 dev->extra_tx_headroom = sizeof(struct p54_hdr) + 4 +
576 sizeof(struct p54_tx_data); 576 sizeof(struct p54_tx_data);
577 577
578 /*
579 * For now, disable PS by default because it affects
580 * link stability significantly.
581 */
582 dev->wiphy->ps_default = false;
583
578 mutex_init(&priv->conf_mutex); 584 mutex_init(&priv->conf_mutex);
579 mutex_init(&priv->eeprom_mutex); 585 mutex_init(&priv->eeprom_mutex);
580 init_completion(&priv->eeprom_comp); 586 init_completion(&priv->eeprom_comp);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 09a589432dab..b04f59bab3b0 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1874,7 +1874,6 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
1874 */ 1874 */
1875 __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); 1875 __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
1876 __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); 1876 __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags);
1877 __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
1878 if (!modparam_nohwcrypt) { 1877 if (!modparam_nohwcrypt) {
1879 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); 1878 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
1880 __set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags); 1879 __set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 3856f06fdca7..639dc6cc04b9 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -1463,6 +1463,10 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
1463 /* 1463 /*
1464 * ASIC will keep garbage value after boot, clear encryption keys. 1464 * ASIC will keep garbage value after boot, clear encryption keys.
1465 */ 1465 */
1466 for (i = 0; i < 4; i++)
1467 rt2x00usb_register_write(rt2x00dev,
1468 SHARED_KEY_MODE_ENTRY(i), 0);
1469
1466 for (i = 0; i < 256; i++) { 1470 for (i = 0; i < 256; i++) {
1467 u32 wcid[2] = { 0xffffffff, 0x00ffffff }; 1471 u32 wcid[2] = { 0xffffffff, 0x00ffffff };
1468 rt2x00usb_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i), 1472 rt2x00usb_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i),
@@ -1472,10 +1476,6 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
1472 rt2x00usb_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0); 1476 rt2x00usb_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
1473 } 1477 }
1474 1478
1475 for (i = 0; i < 16; i++)
1476 rt2x00usb_register_write(rt2x00dev,
1477 SHARED_KEY_MODE_ENTRY(i), 0);
1478
1479 /* 1479 /*
1480 * Clear all beacons 1480 * Clear all beacons
1481 * For the Beacon base registers we only need to clear 1481 * For the Beacon base registers we only need to clear
@@ -1520,7 +1520,7 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
1520 rt2x00usb_register_read(rt2x00dev, LG_FBK_CFG0, &reg); 1520 rt2x00usb_register_read(rt2x00dev, LG_FBK_CFG0, &reg);
1521 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS0FBK, 8); 1521 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS0FBK, 8);
1522 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS1FBK, 8); 1522 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS1FBK, 8);
1523 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS2FBK, 3); 1523 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS2FBK, 9);
1524 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS3FBK, 10); 1524 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS3FBK, 10);
1525 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS4FBK, 11); 1525 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS4FBK, 11);
1526 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS5FBK, 12); 1526 rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS5FBK, 12);
@@ -1995,11 +1995,11 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
1995 rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size); 1995 rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size);
1996 rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID, 1996 rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
1997 test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ? 1997 test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
1998 txdesc->key_idx : 0xff); 1998 (skbdesc->entry->entry_idx + 1) : 0xff);
1999 rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, 1999 rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
2000 skb->len - txdesc->l2pad); 2000 skb->len - txdesc->l2pad);
2001 rt2x00_set_field32(&word, TXWI_W1_PACKETID, 2001 rt2x00_set_field32(&word, TXWI_W1_PACKETID,
2002 skbdesc->entry->entry_idx); 2002 skbdesc->entry->queue->qid + 1);
2003 rt2x00_desc_write(txwi, 1, word); 2003 rt2x00_desc_write(txwi, 1, word);
2004 2004
2005 /* 2005 /*
@@ -2163,8 +2163,10 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
2163 if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS)) 2163 if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS))
2164 rxdesc->dev_flags |= RXDONE_MY_BSS; 2164 rxdesc->dev_flags |= RXDONE_MY_BSS;
2165 2165
2166 if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD)) 2166 if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD)) {
2167 rxdesc->dev_flags |= RXDONE_L2PAD; 2167 rxdesc->dev_flags |= RXDONE_L2PAD;
2168 skbdesc->flags |= SKBDESC_L2_PADDED;
2169 }
2168 2170
2169 if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI)) 2171 if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
2170 rxdesc->flags |= RX_FLAG_SHORT_GI; 2172 rxdesc->flags |= RX_FLAG_SHORT_GI;
@@ -2632,7 +2634,6 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
2632 * This device requires firmware. 2634 * This device requires firmware.
2633 */ 2635 */
2634 __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); 2636 __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
2635 __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
2636 __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); 2637 __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
2637 if (!modparam_nohwcrypt) 2638 if (!modparam_nohwcrypt)
2638 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); 2639 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
index 2d9dc3783361..4d9991c9a51c 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.h
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -36,6 +36,9 @@
36 * RF2750 2.4G/5G 1T2R 36 * RF2750 2.4G/5G 1T2R
37 * RF3020 2.4G 1T1R 37 * RF3020 2.4G 1T1R
38 * RF2020 2.4G B/G 38 * RF2020 2.4G B/G
39 * RF3021 2.4G 1T2R
40 * RF3022 2.4G 2T2R
41 * RF3052 2.4G 2T2R
39 */ 42 */
40#define RF2820 0x0001 43#define RF2820 0x0001
41#define RF2850 0x0002 44#define RF2850 0x0002
@@ -43,6 +46,9 @@
43#define RF2750 0x0004 46#define RF2750 0x0004
44#define RF3020 0x0005 47#define RF3020 0x0005
45#define RF2020 0x0006 48#define RF2020 0x0006
49#define RF3021 0x0007
50#define RF3022 0x0008
51#define RF3052 0x0009
46 52
47/* 53/*
48 * RT2870 version 54 * RT2870 version
@@ -1300,8 +1306,8 @@
1300 * PAIRWISE_KEY_TABLE_BASE: 32-byte * 256 entry 1306 * PAIRWISE_KEY_TABLE_BASE: 32-byte * 256 entry
1301 * MAC_IVEIV_TABLE_BASE: 8-byte * 256-entry 1307 * MAC_IVEIV_TABLE_BASE: 8-byte * 256-entry
1302 * MAC_WCID_ATTRIBUTE_BASE: 4-byte * 256-entry 1308 * MAC_WCID_ATTRIBUTE_BASE: 4-byte * 256-entry
1303 * SHARED_KEY_TABLE_BASE: 32-byte * 16-entry 1309 * SHARED_KEY_TABLE_BASE: 32 bytes * 32-entry
1304 * SHARED_KEY_MODE_BASE: 4-byte * 16-entry 1310 * SHARED_KEY_MODE_BASE: 4 bits * 32-entry
1305 */ 1311 */
1306#define MAC_WCID_BASE 0x1800 1312#define MAC_WCID_BASE 0x1800
1307#define PAIRWISE_KEY_TABLE_BASE 0x4000 1313#define PAIRWISE_KEY_TABLE_BASE 0x4000
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 99e89596cef6..555a777db6df 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -350,8 +350,6 @@ struct rt2x00_intf {
350 */ 350 */
351 unsigned int delayed_flags; 351 unsigned int delayed_flags;
352#define DELAYED_UPDATE_BEACON 0x00000001 352#define DELAYED_UPDATE_BEACON 0x00000001
353#define DELAYED_CONFIG_ERP 0x00000002
354#define DELAYED_LED_ASSOC 0x00000004
355 353
356 /* 354 /*
357 * Software sequence counter, this is only required 355 * Software sequence counter, this is only required
@@ -614,7 +612,6 @@ enum rt2x00_flags {
614 DRIVER_REQUIRE_FIRMWARE, 612 DRIVER_REQUIRE_FIRMWARE,
615 DRIVER_REQUIRE_BEACON_GUARD, 613 DRIVER_REQUIRE_BEACON_GUARD,
616 DRIVER_REQUIRE_ATIM_QUEUE, 614 DRIVER_REQUIRE_ATIM_QUEUE,
617 DRIVER_REQUIRE_SCHEDULED,
618 DRIVER_REQUIRE_DMA, 615 DRIVER_REQUIRE_DMA,
619 DRIVER_REQUIRE_COPY_IV, 616 DRIVER_REQUIRE_COPY_IV,
620 DRIVER_REQUIRE_L2PAD, 617 DRIVER_REQUIRE_L2PAD,
@@ -826,7 +823,6 @@ struct rt2x00_dev {
826 * due to RTNL locking requirements. 823 * due to RTNL locking requirements.
827 */ 824 */
828 struct work_struct intf_work; 825 struct work_struct intf_work;
829 struct work_struct filter_work;
830 826
831 /* 827 /*
832 * Data queue arrays for RX, TX and Beacon. 828 * Data queue arrays for RX, TX and Beacon.
@@ -978,7 +974,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed);
978void rt2x00mac_configure_filter(struct ieee80211_hw *hw, 974void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
979 unsigned int changed_flags, 975 unsigned int changed_flags,
980 unsigned int *total_flags, 976 unsigned int *total_flags,
981 int mc_count, struct dev_addr_list *mc_list); 977 u64 multicast);
982int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, 978int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
983 bool set); 979 bool set);
984#ifdef CONFIG_RT2X00_LIB_CRYPTO 980#ifdef CONFIG_RT2X00_LIB_CRYPTO
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index b6676c6722fc..3f8c70ebe9ad 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -118,20 +118,11 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, enum dev_state state)
118 rt2x00link_start_tuner(rt2x00dev); 118 rt2x00link_start_tuner(rt2x00dev);
119} 119}
120 120
121static void rt2x00lib_packetfilter_scheduled(struct work_struct *work)
122{
123 struct rt2x00_dev *rt2x00dev =
124 container_of(work, struct rt2x00_dev, filter_work);
125
126 rt2x00dev->ops->lib->config_filter(rt2x00dev, rt2x00dev->packet_filter);
127}
128
129static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, 121static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
130 struct ieee80211_vif *vif) 122 struct ieee80211_vif *vif)
131{ 123{
132 struct rt2x00_dev *rt2x00dev = data; 124 struct rt2x00_dev *rt2x00dev = data;
133 struct rt2x00_intf *intf = vif_to_intf(vif); 125 struct rt2x00_intf *intf = vif_to_intf(vif);
134 struct ieee80211_bss_conf conf;
135 int delayed_flags; 126 int delayed_flags;
136 127
137 /* 128 /*
@@ -141,7 +132,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
141 */ 132 */
142 spin_lock(&intf->lock); 133 spin_lock(&intf->lock);
143 134
144 memcpy(&conf, &vif->bss_conf, sizeof(conf));
145 delayed_flags = intf->delayed_flags; 135 delayed_flags = intf->delayed_flags;
146 intf->delayed_flags = 0; 136 intf->delayed_flags = 0;
147 137
@@ -158,12 +148,6 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
158 148
159 if (delayed_flags & DELAYED_UPDATE_BEACON) 149 if (delayed_flags & DELAYED_UPDATE_BEACON)
160 rt2x00queue_update_beacon(rt2x00dev, vif, true); 150 rt2x00queue_update_beacon(rt2x00dev, vif, true);
161
162 if (delayed_flags & DELAYED_CONFIG_ERP)
163 rt2x00lib_config_erp(rt2x00dev, intf, &conf);
164
165 if (delayed_flags & DELAYED_LED_ASSOC)
166 rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated);
167} 151}
168 152
169static void rt2x00lib_intf_scheduled(struct work_struct *work) 153static void rt2x00lib_intf_scheduled(struct work_struct *work)
@@ -220,7 +204,8 @@ void rt2x00lib_txdone(struct queue_entry *entry,
220 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 204 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
221 enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); 205 enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
222 unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb); 206 unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
223 u8 rate_idx, rate_flags; 207 u8 rate_idx, rate_flags, retry_rates;
208 unsigned int i;
224 209
225 /* 210 /*
226 * Unmap the skb. 211 * Unmap the skb.
@@ -259,16 +244,27 @@ void rt2x00lib_txdone(struct queue_entry *entry,
259 244
260 rate_idx = skbdesc->tx_rate_idx; 245 rate_idx = skbdesc->tx_rate_idx;
261 rate_flags = skbdesc->tx_rate_flags; 246 rate_flags = skbdesc->tx_rate_flags;
247 retry_rates = test_bit(TXDONE_FALLBACK, &txdesc->flags) ?
248 (txdesc->retry + 1) : 1;
262 249
263 /* 250 /*
264 * Initialize TX status 251 * Initialize TX status
265 */ 252 */
266 memset(&tx_info->status, 0, sizeof(tx_info->status)); 253 memset(&tx_info->status, 0, sizeof(tx_info->status));
267 tx_info->status.ack_signal = 0; 254 tx_info->status.ack_signal = 0;
268 tx_info->status.rates[0].idx = rate_idx; 255
269 tx_info->status.rates[0].flags = rate_flags; 256 /*
270 tx_info->status.rates[0].count = txdesc->retry + 1; 257 * Frame was send with retries, hardware tried
271 tx_info->status.rates[1].idx = -1; /* terminate */ 258 * different rates to send out the frame, at each
259 * retry it lowered the rate 1 step.
260 */
261 for (i = 0; i < retry_rates && i < IEEE80211_TX_MAX_RATES; i++) {
262 tx_info->status.rates[i].idx = rate_idx - i;
263 tx_info->status.rates[i].flags = rate_flags;
264 tx_info->status.rates[i].count = 1;
265 }
266 if (i < (IEEE80211_TX_MAX_RATES -1))
267 tx_info->status.rates[i].idx = -1; /* terminate */
272 268
273 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) { 269 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
274 if (test_bit(TXDONE_SUCCESS, &txdesc->flags) || 270 if (test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
@@ -847,7 +843,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
847 * Initialize configuration work. 843 * Initialize configuration work.
848 */ 844 */
849 INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); 845 INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
850 INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled);
851 846
852 /* 847 /*
853 * Allocate queue array. 848 * Allocate queue array.
@@ -895,7 +890,6 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
895 /* 890 /*
896 * Stop all work. 891 * Stop all work.
897 */ 892 */
898 cancel_work_sync(&rt2x00dev->filter_work);
899 cancel_work_sync(&rt2x00dev->intf_work); 893 cancel_work_sync(&rt2x00dev->intf_work);
900 894
901 /* 895 /*
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index cb7b6d459331..a91f316cd452 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -379,7 +379,7 @@ EXPORT_SYMBOL_GPL(rt2x00mac_config);
379void rt2x00mac_configure_filter(struct ieee80211_hw *hw, 379void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
380 unsigned int changed_flags, 380 unsigned int changed_flags,
381 unsigned int *total_flags, 381 unsigned int *total_flags,
382 int mc_count, struct dev_addr_list *mc_list) 382 u64 multicast)
383{ 383{
384 struct rt2x00_dev *rt2x00dev = hw->priv; 384 struct rt2x00_dev *rt2x00dev = hw->priv;
385 385
@@ -430,10 +430,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
430 return; 430 return;
431 rt2x00dev->packet_filter = *total_flags; 431 rt2x00dev->packet_filter = *total_flags;
432 432
433 if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) 433 rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
434 rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
435 else
436 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->filter_work);
437} 434}
438EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); 435EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
439 436
@@ -639,23 +636,15 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
639 else 636 else
640 rt2x00dev->intf_associated--; 637 rt2x00dev->intf_associated--;
641 638
642 if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) 639 rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated);
643 rt2x00leds_led_assoc(rt2x00dev,
644 !!rt2x00dev->intf_associated);
645 else
646 delayed |= DELAYED_LED_ASSOC;
647 } 640 }
648 641
649 /* 642 /*
650 * When the erp information has changed, we should perform 643 * When the erp information has changed, we should perform
651 * additional configuration steps. For all other changes we are done. 644 * additional configuration steps. For all other changes we are done.
652 */ 645 */
653 if (changes & ~(BSS_CHANGED_ASSOC | BSS_CHANGED_HT)) { 646 if (changes & ~(BSS_CHANGED_ASSOC | BSS_CHANGED_HT))
654 if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) 647 rt2x00lib_config_erp(rt2x00dev, intf, bss_conf);
655 rt2x00lib_config_erp(rt2x00dev, intf, bss_conf);
656 else
657 delayed |= DELAYED_CONFIG_ERP;
658 }
659 648
660 spin_lock(&intf->lock); 649 spin_lock(&intf->lock);
661 if (delayed) { 650 if (delayed) {
@@ -704,8 +693,8 @@ EXPORT_SYMBOL_GPL(rt2x00mac_conf_tx);
704void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw) 693void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw)
705{ 694{
706 struct rt2x00_dev *rt2x00dev = hw->priv; 695 struct rt2x00_dev *rt2x00dev = hw->priv;
707 bool blocked = !!rt2x00dev->ops->lib->rfkill_poll(rt2x00dev); 696 bool active = !!rt2x00dev->ops->lib->rfkill_poll(rt2x00dev);
708 697
709 wiphy_rfkill_set_hw_state(hw->wiphy, blocked); 698 wiphy_rfkill_set_hw_state(hw->wiphy, !active);
710} 699}
711EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll); 700EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index 47d175a13790..a5591fb2b191 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -214,6 +214,7 @@ struct rxdone_entry_desc {
214 * 214 *
215 * @TXDONE_UNKNOWN: Hardware could not determine success of transmission. 215 * @TXDONE_UNKNOWN: Hardware could not determine success of transmission.
216 * @TXDONE_SUCCESS: Frame was successfully send 216 * @TXDONE_SUCCESS: Frame was successfully send
217 * @TXDONE_FALLBACK: Frame was successfully send using a fallback rate.
217 * @TXDONE_FAILURE: Frame was not successfully send 218 * @TXDONE_FAILURE: Frame was not successfully send
218 * @TXDONE_EXCESSIVE_RETRY: In addition to &TXDONE_FAILURE, the 219 * @TXDONE_EXCESSIVE_RETRY: In addition to &TXDONE_FAILURE, the
219 * frame transmission failed due to excessive retries. 220 * frame transmission failed due to excessive retries.
@@ -221,6 +222,7 @@ struct rxdone_entry_desc {
221enum txdone_entry_desc_flags { 222enum txdone_entry_desc_flags {
222 TXDONE_UNKNOWN, 223 TXDONE_UNKNOWN,
223 TXDONE_SUCCESS, 224 TXDONE_SUCCESS,
225 TXDONE_FALLBACK,
224 TXDONE_FAILURE, 226 TXDONE_FAILURE,
225 TXDONE_EXCESSIVE_RETRY, 227 TXDONE_EXCESSIVE_RETRY,
226}; 228};
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 4d94b65943f1..90e117263051 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2151,7 +2151,6 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
2151 * This device requires firmware. 2151 * This device requires firmware.
2152 */ 2152 */
2153 __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); 2153 __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
2154 __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
2155 if (!modparam_nohwcrypt) 2154 if (!modparam_nohwcrypt)
2156 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); 2155 __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
2157 2156
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 09f46abc730a..16429c49139c 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -728,10 +728,16 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
728 priv->rf->conf_erp(dev, info); 728 priv->rf->conf_erp(dev, info);
729} 729}
730 730
731static u64 rtl8180_prepare_multicast(struct ieee80211_hw *dev, int mc_count,
732 struct dev_addr_list *mc_list)
733{
734 return mc_count;
735}
736
731static void rtl8180_configure_filter(struct ieee80211_hw *dev, 737static void rtl8180_configure_filter(struct ieee80211_hw *dev,
732 unsigned int changed_flags, 738 unsigned int changed_flags,
733 unsigned int *total_flags, 739 unsigned int *total_flags,
734 int mc_count, struct dev_addr_list *mclist) 740 u64 multicast)
735{ 741{
736 struct rtl8180_priv *priv = dev->priv; 742 struct rtl8180_priv *priv = dev->priv;
737 743
@@ -741,7 +747,7 @@ static void rtl8180_configure_filter(struct ieee80211_hw *dev,
741 priv->rx_conf ^= RTL818X_RX_CONF_CTRL; 747 priv->rx_conf ^= RTL818X_RX_CONF_CTRL;
742 if (changed_flags & FIF_OTHER_BSS) 748 if (changed_flags & FIF_OTHER_BSS)
743 priv->rx_conf ^= RTL818X_RX_CONF_MONITOR; 749 priv->rx_conf ^= RTL818X_RX_CONF_MONITOR;
744 if (*total_flags & FIF_ALLMULTI || mc_count > 0) 750 if (*total_flags & FIF_ALLMULTI || multicast > 0)
745 priv->rx_conf |= RTL818X_RX_CONF_MULTICAST; 751 priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
746 else 752 else
747 priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST; 753 priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST;
@@ -768,6 +774,7 @@ static const struct ieee80211_ops rtl8180_ops = {
768 .remove_interface = rtl8180_remove_interface, 774 .remove_interface = rtl8180_remove_interface,
769 .config = rtl8180_config, 775 .config = rtl8180_config,
770 .bss_info_changed = rtl8180_bss_info_changed, 776 .bss_info_changed = rtl8180_bss_info_changed,
777 .prepare_multicast = rtl8180_prepare_multicast,
771 .configure_filter = rtl8180_configure_filter, 778 .configure_filter = rtl8180_configure_filter,
772}; 779};
773 780
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index 53f57dc52226..90f38357393c 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -1192,10 +1192,16 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
1192 info->use_short_preamble); 1192 info->use_short_preamble);
1193} 1193}
1194 1194
1195static u64 rtl8187_prepare_multicast(struct ieee80211_hw *dev,
1196 int mc_count, struct dev_addr_list *mc_list)
1197{
1198 return mc_count;
1199}
1200
1195static void rtl8187_configure_filter(struct ieee80211_hw *dev, 1201static void rtl8187_configure_filter(struct ieee80211_hw *dev,
1196 unsigned int changed_flags, 1202 unsigned int changed_flags,
1197 unsigned int *total_flags, 1203 unsigned int *total_flags,
1198 int mc_count, struct dev_addr_list *mclist) 1204 u64 multicast)
1199{ 1205{
1200 struct rtl8187_priv *priv = dev->priv; 1206 struct rtl8187_priv *priv = dev->priv;
1201 1207
@@ -1205,7 +1211,7 @@ static void rtl8187_configure_filter(struct ieee80211_hw *dev,
1205 priv->rx_conf ^= RTL818X_RX_CONF_CTRL; 1211 priv->rx_conf ^= RTL818X_RX_CONF_CTRL;
1206 if (changed_flags & FIF_OTHER_BSS) 1212 if (changed_flags & FIF_OTHER_BSS)
1207 priv->rx_conf ^= RTL818X_RX_CONF_MONITOR; 1213 priv->rx_conf ^= RTL818X_RX_CONF_MONITOR;
1208 if (*total_flags & FIF_ALLMULTI || mc_count > 0) 1214 if (*total_flags & FIF_ALLMULTI || multicast > 0)
1209 priv->rx_conf |= RTL818X_RX_CONF_MULTICAST; 1215 priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
1210 else 1216 else
1211 priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST; 1217 priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST;
@@ -1268,6 +1274,7 @@ static const struct ieee80211_ops rtl8187_ops = {
1268 .remove_interface = rtl8187_remove_interface, 1274 .remove_interface = rtl8187_remove_interface,
1269 .config = rtl8187_config, 1275 .config = rtl8187_config,
1270 .bss_info_changed = rtl8187_bss_info_changed, 1276 .bss_info_changed = rtl8187_bss_info_changed,
1277 .prepare_multicast = rtl8187_prepare_multicast,
1271 .configure_filter = rtl8187_configure_filter, 1278 .configure_filter = rtl8187_configure_filter,
1272 .conf_tx = rtl8187_conf_tx 1279 .conf_tx = rtl8187_conf_tx
1273}; 1280};
diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl12xx/wl1251_boot.c
index 592c3b5cc8f8..452d748e42c6 100644
--- a/drivers/net/wireless/wl12xx/wl1251_boot.c
+++ b/drivers/net/wireless/wl12xx/wl1251_boot.c
@@ -465,6 +465,9 @@ int wl1251_boot(struct wl1251 *wl)
465 int ret = 0, minor_minor_e2_ver; 465 int ret = 0, minor_minor_e2_ver;
466 u32 tmp, boot_data; 466 u32 tmp, boot_data;
467 467
468 /* halt embedded ARM CPU while loading firmware */
469 wl1251_reg_write32(wl, ACX_REG_ECPU_CONTROL, ECPU_CONTROL_HALT);
470
468 ret = wl1251_boot_soft_reset(wl); 471 ret = wl1251_boot_soft_reset(wl);
469 if (ret < 0) 472 if (ret < 0)
470 goto out; 473 goto out;
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 7148934e464d..5809ef5b18f8 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -652,9 +652,7 @@ out:
652 652
653static void wl1251_op_configure_filter(struct ieee80211_hw *hw, 653static void wl1251_op_configure_filter(struct ieee80211_hw *hw,
654 unsigned int changed, 654 unsigned int changed,
655 unsigned int *total, 655 unsigned int *total,u64 multicast)
656 int mc_count,
657 struct dev_addr_list *mc_list)
658{ 656{
659 struct wl1251 *wl = hw->priv; 657 struct wl1251 *wl = hw->priv;
660 658
diff --git a/drivers/net/wireless/wl12xx/wl1251_reg.h b/drivers/net/wireless/wl12xx/wl1251_reg.h
index bdd561001dcb..06e1bd94a739 100644
--- a/drivers/net/wireless/wl12xx/wl1251_reg.h
+++ b/drivers/net/wireless/wl12xx/wl1251_reg.h
@@ -245,8 +245,8 @@ enum wl12xx_acx_int_reg {
245 ACX_REG_TABLE_LEN 245 ACX_REG_TABLE_LEN
246}; 246};
247 247
248#define ACX_SLV_SOFT_RESET_BIT BIT(1) 248#define ACX_SLV_SOFT_RESET_BIT BIT(0)
249#define ACX_REG_EEPROM_START_BIT BIT(1) 249#define ACX_REG_EEPROM_START_BIT BIT(0)
250 250
251/* Command/Information Mailbox Pointers */ 251/* Command/Information Mailbox Pointers */
252 252
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 4102d590b798..d9169b47ac42 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -605,11 +605,10 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
605 struct ieee80211_if_init_conf *conf) 605 struct ieee80211_if_init_conf *conf)
606{ 606{
607 struct wl1271 *wl = hw->priv; 607 struct wl1271 *wl = hw->priv;
608 DECLARE_MAC_BUF(mac);
609 int ret = 0; 608 int ret = 0;
610 609
611 wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %s", 610 wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
612 conf->type, print_mac(mac, conf->mac_addr)); 611 conf->type, conf->mac_addr);
613 612
614 mutex_lock(&wl->mutex); 613 mutex_lock(&wl->mutex);
615 614
@@ -793,9 +792,7 @@ out:
793 792
794static void wl1271_op_configure_filter(struct ieee80211_hw *hw, 793static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
795 unsigned int changed, 794 unsigned int changed,
796 unsigned int *total, 795 unsigned int *total,u64 multicast)
797 int mc_count,
798 struct dev_addr_list *mc_list)
799{ 796{
800 struct wl1271 *wl = hw->priv; 797 struct wl1271 *wl = hw->priv;
801 798
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 55b7fbdc85dc..6d666359a42f 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -796,18 +796,40 @@ static void set_rx_filter_handler(struct work_struct *work)
796 dev_err(zd_mac_dev(mac), "set_rx_filter_handler error %d\n", r); 796 dev_err(zd_mac_dev(mac), "set_rx_filter_handler error %d\n", r);
797} 797}
798 798
799static u64 zd_op_prepare_multicast(struct ieee80211_hw *hw,
800 int mc_count, struct dev_addr_list *mclist)
801{
802 struct zd_mac *mac = zd_hw_mac(hw);
803 struct zd_mc_hash hash;
804 int i;
805
806 zd_mc_clear(&hash);
807
808 for (i = 0; i < mc_count; i++) {
809 if (!mclist)
810 break;
811 dev_dbg_f(zd_mac_dev(mac), "mc addr %pM\n", mclist->dmi_addr);
812 zd_mc_add_addr(&hash, mclist->dmi_addr);
813 mclist = mclist->next;
814 }
815
816 return hash.low | ((u64)hash.high << 32);
817}
818
799#define SUPPORTED_FIF_FLAGS \ 819#define SUPPORTED_FIF_FLAGS \
800 (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \ 820 (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \
801 FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC) 821 FIF_OTHER_BSS | FIF_BCN_PRBRESP_PROMISC)
802static void zd_op_configure_filter(struct ieee80211_hw *hw, 822static void zd_op_configure_filter(struct ieee80211_hw *hw,
803 unsigned int changed_flags, 823 unsigned int changed_flags,
804 unsigned int *new_flags, 824 unsigned int *new_flags,
805 int mc_count, struct dev_mc_list *mclist) 825 u64 multicast)
806{ 826{
807 struct zd_mc_hash hash; 827 struct zd_mc_hash hash = {
828 .low = multicast,
829 .high = multicast >> 32,
830 };
808 struct zd_mac *mac = zd_hw_mac(hw); 831 struct zd_mac *mac = zd_hw_mac(hw);
809 unsigned long flags; 832 unsigned long flags;
810 int i;
811 833
812 /* Only deal with supported flags */ 834 /* Only deal with supported flags */
813 changed_flags &= SUPPORTED_FIF_FLAGS; 835 changed_flags &= SUPPORTED_FIF_FLAGS;
@@ -819,25 +841,16 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw,
819 if (!changed_flags) 841 if (!changed_flags)
820 return; 842 return;
821 843
822 if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) { 844 if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI))
823 zd_mc_add_all(&hash); 845 zd_mc_add_all(&hash);
824 } else {
825 zd_mc_clear(&hash);
826 for (i = 0; i < mc_count; i++) {
827 if (!mclist)
828 break;
829 dev_dbg_f(zd_mac_dev(mac), "mc addr %pM\n",
830 mclist->dmi_addr);
831 zd_mc_add_addr(&hash, mclist->dmi_addr);
832 mclist = mclist->next;
833 }
834 }
835 846
836 spin_lock_irqsave(&mac->lock, flags); 847 spin_lock_irqsave(&mac->lock, flags);
837 mac->pass_failed_fcs = !!(*new_flags & FIF_FCSFAIL); 848 mac->pass_failed_fcs = !!(*new_flags & FIF_FCSFAIL);
838 mac->pass_ctrl = !!(*new_flags & FIF_CONTROL); 849 mac->pass_ctrl = !!(*new_flags & FIF_CONTROL);
839 mac->multicast_hash = hash; 850 mac->multicast_hash = hash;
840 spin_unlock_irqrestore(&mac->lock, flags); 851 spin_unlock_irqrestore(&mac->lock, flags);
852
853 /* XXX: these can be called here now, can sleep now! */
841 queue_work(zd_workqueue, &mac->set_multicast_hash_work); 854 queue_work(zd_workqueue, &mac->set_multicast_hash_work);
842 855
843 if (changed_flags & FIF_CONTROL) 856 if (changed_flags & FIF_CONTROL)
@@ -940,6 +953,7 @@ static const struct ieee80211_ops zd_ops = {
940 .add_interface = zd_op_add_interface, 953 .add_interface = zd_op_add_interface,
941 .remove_interface = zd_op_remove_interface, 954 .remove_interface = zd_op_remove_interface,
942 .config = zd_op_config, 955 .config = zd_op_config,
956 .prepare_multicast = zd_op_prepare_multicast,
943 .configure_filter = zd_op_configure_filter, 957 .configure_filter = zd_op_configure_filter,
944 .bss_info_changed = zd_op_bss_info_changed, 958 .bss_info_changed = zd_op_bss_info_changed,
945 .get_tsf = zd_op_get_tsf, 959 .get_tsf = zd_op_get_tsf,
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
index 593fc618a2ea..f853d5600ca7 100644
--- a/drivers/ssb/pci.c
+++ b/drivers/ssb/pci.c
@@ -480,7 +480,7 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
480 480
481 /* extract the MAC address */ 481 /* extract the MAC address */
482 for (i = 0; i < 3; i++) { 482 for (i = 0; i < 3; i++) {
483 v = in[SPOFF(SSB_SPROM1_IL0MAC) + i]; 483 v = in[SPOFF(SSB_SPROM8_IL0MAC) + i];
484 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v); 484 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
485 } 485 }
486 SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0); 486 SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0);
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0b146bb2dd14..3d874c620219 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1325,6 +1325,8 @@ struct wireless_dev {
1325 1325
1326 struct mutex mtx; 1326 struct mutex mtx;
1327 1327
1328 struct work_struct cleanup_work;
1329
1328 /* currently used for IBSS and SME - might be rearranged later */ 1330 /* currently used for IBSS and SME - might be rearranged later */
1329 u8 ssid[IEEE80211_MAX_SSID_LEN]; 1331 u8 ssid[IEEE80211_MAX_SSID_LEN];
1330 u8 ssid_len; 1332 u8 ssid_len;
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 76d43e12cc29..aac84d7bd46e 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -583,7 +583,6 @@ enum ieee80211_conf_flags {
583/** 583/**
584 * enum ieee80211_conf_changed - denotes which configuration changed 584 * enum ieee80211_conf_changed - denotes which configuration changed
585 * 585 *
586 * @_IEEE80211_CONF_CHANGE_RADIO_ENABLED: DEPRECATED
587 * @IEEE80211_CONF_CHANGE_LISTEN_INTERVAL: the listen interval changed 586 * @IEEE80211_CONF_CHANGE_LISTEN_INTERVAL: the listen interval changed
588 * @IEEE80211_CONF_CHANGE_RADIOTAP: the radiotap flag changed 587 * @IEEE80211_CONF_CHANGE_RADIOTAP: the radiotap flag changed
589 * @IEEE80211_CONF_CHANGE_PS: the PS flag or dynamic PS timeout changed 588 * @IEEE80211_CONF_CHANGE_PS: the PS flag or dynamic PS timeout changed
@@ -593,7 +592,6 @@ enum ieee80211_conf_flags {
593 * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed 592 * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed
594 */ 593 */
595enum ieee80211_conf_changed { 594enum ieee80211_conf_changed {
596 _IEEE80211_CONF_CHANGE_RADIO_ENABLED = BIT(0),
597 IEEE80211_CONF_CHANGE_LISTEN_INTERVAL = BIT(2), 595 IEEE80211_CONF_CHANGE_LISTEN_INTERVAL = BIT(2),
598 IEEE80211_CONF_CHANGE_RADIOTAP = BIT(3), 596 IEEE80211_CONF_CHANGE_RADIOTAP = BIT(3),
599 IEEE80211_CONF_CHANGE_PS = BIT(4), 597 IEEE80211_CONF_CHANGE_PS = BIT(4),
@@ -603,14 +601,6 @@ enum ieee80211_conf_changed {
603 IEEE80211_CONF_CHANGE_IDLE = BIT(8), 601 IEEE80211_CONF_CHANGE_IDLE = BIT(8),
604}; 602};
605 603
606static inline __deprecated enum ieee80211_conf_changed
607__IEEE80211_CONF_CHANGE_RADIO_ENABLED(void)
608{
609 return _IEEE80211_CONF_CHANGE_RADIO_ENABLED;
610}
611#define IEEE80211_CONF_CHANGE_RADIO_ENABLED \
612 __IEEE80211_CONF_CHANGE_RADIO_ENABLED()
613
614/** 604/**
615 * struct ieee80211_conf - configuration of the device 605 * struct ieee80211_conf - configuration of the device
616 * 606 *
@@ -618,9 +608,6 @@ __IEEE80211_CONF_CHANGE_RADIO_ENABLED(void)
618 * 608 *
619 * @flags: configuration flags defined above 609 * @flags: configuration flags defined above
620 * 610 *
621 * @radio_enabled: when zero, driver is required to switch off the radio.
622 * @beacon_int: DEPRECATED, DO NOT USE
623 *
624 * @listen_interval: listen interval in units of beacon interval 611 * @listen_interval: listen interval in units of beacon interval
625 * @max_sleep_period: the maximum number of beacon intervals to sleep for 612 * @max_sleep_period: the maximum number of beacon intervals to sleep for
626 * before checking the beacon for a TIM bit (managed mode only); this 613 * before checking the beacon for a TIM bit (managed mode only); this
@@ -644,13 +631,11 @@ __IEEE80211_CONF_CHANGE_RADIO_ENABLED(void)
644 * number of transmissions not the number of retries 631 * number of transmissions not the number of retries
645 */ 632 */
646struct ieee80211_conf { 633struct ieee80211_conf {
647 int __deprecated beacon_int;
648 u32 flags; 634 u32 flags;
649 int power_level, dynamic_ps_timeout; 635 int power_level, dynamic_ps_timeout;
650 int max_sleep_period; 636 int max_sleep_period;
651 637
652 u16 listen_interval; 638 u16 listen_interval;
653 bool __deprecated radio_enabled;
654 639
655 u8 long_frame_max_tx_count, short_frame_max_tx_count; 640 u8 long_frame_max_tx_count, short_frame_max_tx_count;
656 641
@@ -1219,10 +1204,13 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
1219 * the driver's configure_filter() function which frames should be 1204 * the driver's configure_filter() function which frames should be
1220 * passed to mac80211 and which should be filtered out. 1205 * passed to mac80211 and which should be filtered out.
1221 * 1206 *
1222 * The configure_filter() callback is invoked with the parameters 1207 * Before configure_filter() is invoked, the prepare_multicast()
1223 * @mc_count and @mc_list for the combined multicast address list 1208 * callback is invoked with the parameters @mc_count and @mc_list
1224 * of all virtual interfaces, @changed_flags telling which flags 1209 * for the combined multicast address list of all virtual interfaces.
1225 * were changed and @total_flags with the new flag states. 1210 * It's use is optional, and it returns a u64 that is passed to
1211 * configure_filter(). Additionally, configure_filter() has the
1212 * arguments @changed_flags telling which flags were changed and
1213 * @total_flags with the new flag states.
1226 * 1214 *
1227 * If your device has no multicast address filters your driver will 1215 * If your device has no multicast address filters your driver will
1228 * need to check both the %FIF_ALLMULTI flag and the @mc_count 1216 * need to check both the %FIF_ALLMULTI flag and the @mc_count
@@ -1375,9 +1363,13 @@ enum ieee80211_ampdu_mlme_action {
1375 * for association indication. The @changed parameter indicates which 1363 * for association indication. The @changed parameter indicates which
1376 * of the bss parameters has changed when a call is made. 1364 * of the bss parameters has changed when a call is made.
1377 * 1365 *
1366 * @prepare_multicast: Prepare for multicast filter configuration.
1367 * This callback is optional, and its return value is passed
1368 * to configure_filter(). This callback must be atomic.
1369 *
1378 * @configure_filter: Configure the device's RX filter. 1370 * @configure_filter: Configure the device's RX filter.
1379 * See the section "Frame filtering" for more information. 1371 * See the section "Frame filtering" for more information.
1380 * This callback must be implemented and atomic. 1372 * This callback must be implemented.
1381 * 1373 *
1382 * @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit 1374 * @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit
1383 * must be set or cleared for a given STA. Must be atomic. 1375 * must be set or cleared for a given STA. Must be atomic.
@@ -1479,10 +1471,12 @@ struct ieee80211_ops {
1479 struct ieee80211_vif *vif, 1471 struct ieee80211_vif *vif,
1480 struct ieee80211_bss_conf *info, 1472 struct ieee80211_bss_conf *info,
1481 u32 changed); 1473 u32 changed);
1474 u64 (*prepare_multicast)(struct ieee80211_hw *hw,
1475 int mc_count, struct dev_addr_list *mc_list);
1482 void (*configure_filter)(struct ieee80211_hw *hw, 1476 void (*configure_filter)(struct ieee80211_hw *hw,
1483 unsigned int changed_flags, 1477 unsigned int changed_flags,
1484 unsigned int *total_flags, 1478 unsigned int *total_flags,
1485 int mc_count, struct dev_addr_list *mc_list); 1479 u64 multicast);
1486 int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta, 1480 int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
1487 bool set); 1481 bool set);
1488 int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd, 1482 int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd,
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index e9ec6cae2d39..61234e79022b 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -116,6 +116,8 @@ IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
116 116
117#ifdef CONFIG_MAC80211_MESH 117#ifdef CONFIG_MAC80211_MESH
118/* Mesh stats attributes */ 118/* Mesh stats attributes */
119IEEE80211_IF_FILE(fwded_mcast, u.mesh.mshstats.fwded_mcast, DEC);
120IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC);
119IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC); 121IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC);
120IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC); 122IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC);
121IEEE80211_IF_FILE(dropped_frames_no_route, 123IEEE80211_IF_FILE(dropped_frames_no_route,
@@ -205,6 +207,8 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
205{ 207{
206 sdata->mesh_stats_dir = debugfs_create_dir("mesh_stats", 208 sdata->mesh_stats_dir = debugfs_create_dir("mesh_stats",
207 sdata->debugfsdir); 209 sdata->debugfsdir);
210 MESHSTATS_ADD(fwded_mcast);
211 MESHSTATS_ADD(fwded_unicast);
208 MESHSTATS_ADD(fwded_frames); 212 MESHSTATS_ADD(fwded_frames);
209 MESHSTATS_ADD(dropped_frames_ttl); 213 MESHSTATS_ADD(dropped_frames_ttl);
210 MESHSTATS_ADD(dropped_frames_no_route); 214 MESHSTATS_ADD(dropped_frames_no_route);
@@ -327,6 +331,8 @@ static void del_monitor_files(struct ieee80211_sub_if_data *sdata)
327 331
328static void del_mesh_stats(struct ieee80211_sub_if_data *sdata) 332static void del_mesh_stats(struct ieee80211_sub_if_data *sdata)
329{ 333{
334 MESHSTATS_DEL(fwded_mcast);
335 MESHSTATS_DEL(fwded_unicast);
330 MESHSTATS_DEL(fwded_frames); 336 MESHSTATS_DEL(fwded_frames);
331 MESHSTATS_DEL(dropped_frames_ttl); 337 MESHSTATS_DEL(dropped_frames_ttl);
332 MESHSTATS_DEL(dropped_frames_no_route); 338 MESHSTATS_DEL(dropped_frames_no_route);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 4100c361a99d..d231c9323ad1 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -55,16 +55,32 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
55 trace_drv_bss_info_changed(local, vif, info, changed); 55 trace_drv_bss_info_changed(local, vif, info, changed);
56} 56}
57 57
58static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
59 int mc_count,
60 struct dev_addr_list *mc_list)
61{
62 u64 ret = 0;
63
64 if (local->ops->prepare_multicast)
65 ret = local->ops->prepare_multicast(&local->hw, mc_count,
66 mc_list);
67
68 trace_drv_prepare_multicast(local, mc_count, ret);
69
70 return ret;
71}
72
58static inline void drv_configure_filter(struct ieee80211_local *local, 73static inline void drv_configure_filter(struct ieee80211_local *local,
59 unsigned int changed_flags, 74 unsigned int changed_flags,
60 unsigned int *total_flags, 75 unsigned int *total_flags,
61 int mc_count, 76 u64 multicast)
62 struct dev_addr_list *mc_list)
63{ 77{
78 might_sleep();
79
64 local->ops->configure_filter(&local->hw, changed_flags, total_flags, 80 local->ops->configure_filter(&local->hw, changed_flags, total_flags,
65 mc_count, mc_list); 81 multicast);
66 trace_drv_configure_filter(local, changed_flags, total_flags, 82 trace_drv_configure_filter(local, changed_flags, total_flags,
67 mc_count); 83 multicast);
68} 84}
69 85
70static inline int drv_set_tim(struct ieee80211_local *local, 86static inline int drv_set_tim(struct ieee80211_local *local,
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 5a10da2d70fd..37b9051afcf3 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -191,31 +191,55 @@ TRACE_EVENT(drv_bss_info_changed,
191 ) 191 )
192); 192);
193 193
194TRACE_EVENT(drv_prepare_multicast,
195 TP_PROTO(struct ieee80211_local *local, int mc_count, u64 ret),
196
197 TP_ARGS(local, mc_count, ret),
198
199 TP_STRUCT__entry(
200 LOCAL_ENTRY
201 __field(int, mc_count)
202 __field(u64, ret)
203 ),
204
205 TP_fast_assign(
206 LOCAL_ASSIGN;
207 __entry->mc_count = mc_count;
208 __entry->ret = ret;
209 ),
210
211 TP_printk(
212 LOCAL_PR_FMT " prepare mc (%d): %llx",
213 LOCAL_PR_ARG, __entry->mc_count,
214 (unsigned long long) __entry->ret
215 )
216);
217
194TRACE_EVENT(drv_configure_filter, 218TRACE_EVENT(drv_configure_filter,
195 TP_PROTO(struct ieee80211_local *local, 219 TP_PROTO(struct ieee80211_local *local,
196 unsigned int changed_flags, 220 unsigned int changed_flags,
197 unsigned int *total_flags, 221 unsigned int *total_flags,
198 int mc_count), 222 u64 multicast),
199 223
200 TP_ARGS(local, changed_flags, total_flags, mc_count), 224 TP_ARGS(local, changed_flags, total_flags, multicast),
201 225
202 TP_STRUCT__entry( 226 TP_STRUCT__entry(
203 LOCAL_ENTRY 227 LOCAL_ENTRY
204 __field(unsigned int, changed) 228 __field(unsigned int, changed)
205 __field(unsigned int, total) 229 __field(unsigned int, total)
206 __field(int, mc) 230 __field(u64, multicast)
207 ), 231 ),
208 232
209 TP_fast_assign( 233 TP_fast_assign(
210 LOCAL_ASSIGN; 234 LOCAL_ASSIGN;
211 __entry->changed = changed_flags; 235 __entry->changed = changed_flags;
212 __entry->total = *total_flags; 236 __entry->total = *total_flags;
213 __entry->mc = mc_count; 237 __entry->multicast = multicast;
214 ), 238 ),
215 239
216 TP_printk( 240 TP_printk(
217 LOCAL_PR_FMT " changed:%#x total:%#x mc:%d", 241 LOCAL_PR_FMT " changed:%#x total:%#x",
218 LOCAL_PR_ARG, __entry->changed, __entry->total, __entry->mc 242 LOCAL_PR_ARG, __entry->changed, __entry->total
219 ) 243 )
220); 244);
221 245
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index a6abc7dfd903..93e618a980d1 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -212,7 +212,9 @@ struct ieee80211_if_vlan {
212}; 212};
213 213
214struct mesh_stats { 214struct mesh_stats {
215 __u32 fwded_frames; /* Mesh forwarded frames */ 215 __u32 fwded_mcast; /* Mesh forwarded multicast frames */
216 __u32 fwded_unicast; /* Mesh forwarded unicast frames */
217 __u32 fwded_frames; /* Mesh total forwarded frames */
216 __u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/ 218 __u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/
217 __u32 dropped_frames_no_route; /* Not transmitted, no route found */ 219 __u32 dropped_frames_no_route; /* Not transmitted, no route found */
218 atomic_t estab_plinks; 220 atomic_t estab_plinks;
@@ -506,6 +508,8 @@ struct ieee80211_sub_if_data {
506#ifdef CONFIG_MAC80211_MESH 508#ifdef CONFIG_MAC80211_MESH
507 struct dentry *mesh_stats_dir; 509 struct dentry *mesh_stats_dir;
508 struct { 510 struct {
511 struct dentry *fwded_mcast;
512 struct dentry *fwded_unicast;
509 struct dentry *fwded_frames; 513 struct dentry *fwded_frames;
510 struct dentry *dropped_frames_ttl; 514 struct dentry *dropped_frames_ttl;
511 struct dentry *dropped_frames_no_route; 515 struct dentry *dropped_frames_no_route;
@@ -636,6 +640,9 @@ struct ieee80211_local {
636 /* protects the aggregated multicast list and filter calls */ 640 /* protects the aggregated multicast list and filter calls */
637 spinlock_t filter_lock; 641 spinlock_t filter_lock;
638 642
643 /* used for uploading changed mc list */
644 struct work_struct reconfig_filter;
645
639 /* aggregated multicast list */ 646 /* aggregated multicast list */
640 struct dev_addr_list *mc_list; 647 struct dev_addr_list *mc_list;
641 int mc_count; 648 int mc_count;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index e8fb03b91a44..b161301056df 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -227,9 +227,7 @@ static int ieee80211_open(struct net_device *dev)
227 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) 227 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
228 local->fif_other_bss++; 228 local->fif_other_bss++;
229 229
230 spin_lock_bh(&local->filter_lock);
231 ieee80211_configure_filter(local); 230 ieee80211_configure_filter(local);
232 spin_unlock_bh(&local->filter_lock);
233 break; 231 break;
234 default: 232 default:
235 conf.vif = &sdata->vif; 233 conf.vif = &sdata->vif;
@@ -241,17 +239,13 @@ static int ieee80211_open(struct net_device *dev)
241 239
242 if (ieee80211_vif_is_mesh(&sdata->vif)) { 240 if (ieee80211_vif_is_mesh(&sdata->vif)) {
243 local->fif_other_bss++; 241 local->fif_other_bss++;
244 spin_lock_bh(&local->filter_lock);
245 ieee80211_configure_filter(local); 242 ieee80211_configure_filter(local);
246 spin_unlock_bh(&local->filter_lock);
247 243
248 ieee80211_start_mesh(sdata); 244 ieee80211_start_mesh(sdata);
249 } else if (sdata->vif.type == NL80211_IFTYPE_AP) { 245 } else if (sdata->vif.type == NL80211_IFTYPE_AP) {
250 local->fif_pspoll++; 246 local->fif_pspoll++;
251 247
252 spin_lock_bh(&local->filter_lock);
253 ieee80211_configure_filter(local); 248 ieee80211_configure_filter(local);
254 spin_unlock_bh(&local->filter_lock);
255 } 249 }
256 250
257 changed |= ieee80211_reset_erp_info(sdata); 251 changed |= ieee80211_reset_erp_info(sdata);
@@ -404,10 +398,11 @@ static int ieee80211_stop(struct net_device *dev)
404 spin_lock_bh(&local->filter_lock); 398 spin_lock_bh(&local->filter_lock);
405 __dev_addr_unsync(&local->mc_list, &local->mc_count, 399 __dev_addr_unsync(&local->mc_list, &local->mc_count,
406 &dev->mc_list, &dev->mc_count); 400 &dev->mc_list, &dev->mc_count);
407 ieee80211_configure_filter(local);
408 spin_unlock_bh(&local->filter_lock); 401 spin_unlock_bh(&local->filter_lock);
409 netif_addr_unlock_bh(dev); 402 netif_addr_unlock_bh(dev);
410 403
404 ieee80211_configure_filter(local);
405
411 del_timer_sync(&local->dynamic_ps_timer); 406 del_timer_sync(&local->dynamic_ps_timer);
412 cancel_work_sync(&local->dynamic_ps_enable_work); 407 cancel_work_sync(&local->dynamic_ps_enable_work);
413 408
@@ -458,9 +453,7 @@ static int ieee80211_stop(struct net_device *dev)
458 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) 453 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
459 local->fif_other_bss--; 454 local->fif_other_bss--;
460 455
461 spin_lock_bh(&local->filter_lock);
462 ieee80211_configure_filter(local); 456 ieee80211_configure_filter(local);
463 spin_unlock_bh(&local->filter_lock);
464 break; 457 break;
465 case NL80211_IFTYPE_STATION: 458 case NL80211_IFTYPE_STATION:
466 del_timer_sync(&sdata->u.mgd.chswitch_timer); 459 del_timer_sync(&sdata->u.mgd.chswitch_timer);
@@ -503,9 +496,7 @@ static int ieee80211_stop(struct net_device *dev)
503 local->fif_other_bss--; 496 local->fif_other_bss--;
504 atomic_dec(&local->iff_allmultis); 497 atomic_dec(&local->iff_allmultis);
505 498
506 spin_lock_bh(&local->filter_lock);
507 ieee80211_configure_filter(local); 499 ieee80211_configure_filter(local);
508 spin_unlock_bh(&local->filter_lock);
509 500
510 ieee80211_stop_mesh(sdata); 501 ieee80211_stop_mesh(sdata);
511 } 502 }
@@ -622,8 +613,8 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
622 spin_lock_bh(&local->filter_lock); 613 spin_lock_bh(&local->filter_lock);
623 __dev_addr_sync(&local->mc_list, &local->mc_count, 614 __dev_addr_sync(&local->mc_list, &local->mc_count,
624 &dev->mc_list, &dev->mc_count); 615 &dev->mc_list, &dev->mc_count);
625 ieee80211_configure_filter(local);
626 spin_unlock_bh(&local->filter_lock); 616 spin_unlock_bh(&local->filter_lock);
617 ieee80211_queue_work(&local->hw, &local->reconfig_filter);
627} 618}
628 619
629/* 620/*
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index b03fd84777fa..dd3b0816614d 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -50,9 +50,9 @@ struct ieee80211_tx_status_rtap_hdr {
50} __attribute__ ((packed)); 50} __attribute__ ((packed));
51 51
52 52
53/* must be called under mdev tx lock */
54void ieee80211_configure_filter(struct ieee80211_local *local) 53void ieee80211_configure_filter(struct ieee80211_local *local)
55{ 54{
55 u64 mc;
56 unsigned int changed_flags; 56 unsigned int changed_flags;
57 unsigned int new_flags = 0; 57 unsigned int new_flags = 0;
58 58
@@ -62,7 +62,7 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
62 if (atomic_read(&local->iff_allmultis)) 62 if (atomic_read(&local->iff_allmultis))
63 new_flags |= FIF_ALLMULTI; 63 new_flags |= FIF_ALLMULTI;
64 64
65 if (local->monitors) 65 if (local->monitors || local->scanning)
66 new_flags |= FIF_BCN_PRBRESP_PROMISC; 66 new_flags |= FIF_BCN_PRBRESP_PROMISC;
67 67
68 if (local->fif_fcsfail) 68 if (local->fif_fcsfail)
@@ -80,20 +80,30 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
80 if (local->fif_pspoll) 80 if (local->fif_pspoll)
81 new_flags |= FIF_PSPOLL; 81 new_flags |= FIF_PSPOLL;
82 82
83 spin_lock_bh(&local->filter_lock);
83 changed_flags = local->filter_flags ^ new_flags; 84 changed_flags = local->filter_flags ^ new_flags;
84 85
86 mc = drv_prepare_multicast(local, local->mc_count, local->mc_list);
87 spin_unlock_bh(&local->filter_lock);
88
85 /* be a bit nasty */ 89 /* be a bit nasty */
86 new_flags |= (1<<31); 90 new_flags |= (1<<31);
87 91
88 drv_configure_filter(local, changed_flags, &new_flags, 92 drv_configure_filter(local, changed_flags, &new_flags, mc);
89 local->mc_count,
90 local->mc_list);
91 93
92 WARN_ON(new_flags & (1<<31)); 94 WARN_ON(new_flags & (1<<31));
93 95
94 local->filter_flags = new_flags & ~(1<<31); 96 local->filter_flags = new_flags & ~(1<<31);
95} 97}
96 98
99static void ieee80211_reconfig_filter(struct work_struct *work)
100{
101 struct ieee80211_local *local =
102 container_of(work, struct ieee80211_local, reconfig_filter);
103
104 ieee80211_configure_filter(local);
105}
106
97int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) 107int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
98{ 108{
99 struct ieee80211_channel *chan, *scan_chan; 109 struct ieee80211_channel *chan, *scan_chan;
@@ -231,9 +241,6 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
231 241
232 drv_bss_info_changed(local, &sdata->vif, 242 drv_bss_info_changed(local, &sdata->vif,
233 &sdata->vif.bss_conf, changed); 243 &sdata->vif.bss_conf, changed);
234
235 /* DEPRECATED */
236 local->hw.conf.beacon_int = sdata->vif.bss_conf.beacon_int;
237} 244}
238 245
239u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) 246u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
@@ -475,6 +482,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
475 } 482 }
476 483
477 rate_control_tx_status(local, sband, sta, skb); 484 rate_control_tx_status(local, sband, sta, skb);
485 if (ieee80211_vif_is_mesh(&sta->sdata->vif))
486 ieee80211s_update_metric(local, sta, skb);
478 } 487 }
479 488
480 rcu_read_unlock(); 489 rcu_read_unlock();
@@ -677,7 +686,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
677 local->hw.max_rates = 1; 686 local->hw.max_rates = 1;
678 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; 687 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
679 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; 688 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
680 local->hw.conf.radio_enabled = true;
681 local->user_power_level = -1; 689 local->user_power_level = -1;
682 690
683 INIT_LIST_HEAD(&local->interfaces); 691 INIT_LIST_HEAD(&local->interfaces);
@@ -692,6 +700,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
692 700
693 INIT_WORK(&local->restart_work, ieee80211_restart_work); 701 INIT_WORK(&local->restart_work, ieee80211_restart_work);
694 702
703 INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter);
704
695 INIT_WORK(&local->dynamic_ps_enable_work, 705 INIT_WORK(&local->dynamic_ps_enable_work,
696 ieee80211_dynamic_ps_enable_work); 706 ieee80211_dynamic_ps_enable_work);
697 INIT_WORK(&local->dynamic_ps_disable_work, 707 INIT_WORK(&local->dynamic_ps_disable_work,
@@ -920,7 +930,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
920 fail_workqueue: 930 fail_workqueue:
921 wiphy_unregister(local->hw.wiphy); 931 wiphy_unregister(local->hw.wiphy);
922 fail_wiphy_register: 932 fail_wiphy_register:
923 kfree(local->int_scan_req->channels); 933 kfree(local->int_scan_req);
924 return result; 934 return result;
925} 935}
926EXPORT_SYMBOL(ieee80211_register_hw); 936EXPORT_SYMBOL(ieee80211_register_hw);
@@ -946,6 +956,8 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
946 956
947 rtnl_unlock(); 957 rtnl_unlock();
948 958
959 cancel_work_sync(&local->reconfig_filter);
960
949 ieee80211_clear_tx_pending(local); 961 ieee80211_clear_tx_pending(local);
950 sta_info_stop(local); 962 sta_info_stop(local);
951 rate_control_deinitialize(local); 963 rate_control_deinitialize(local);
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index eb23fc639b2b..dd1c19319f0a 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -226,6 +226,8 @@ void mesh_mgmt_ies_add(struct sk_buff *skb,
226void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); 226void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
227int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); 227int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
228void ieee80211s_init(void); 228void ieee80211s_init(void);
229void ieee80211s_update_metric(struct ieee80211_local *local,
230 struct sta_info *stainfo, struct sk_buff *skb);
229void ieee80211s_stop(void); 231void ieee80211s_stop(void);
230void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); 232void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
231ieee80211_rx_result 233ieee80211_rx_result
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index ef1efd362691..e12a786e26b8 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -201,6 +201,24 @@ int mesh_path_error_tx(u8 *dst, __le32 dst_dsn, u8 *ra,
201 return 0; 201 return 0;
202} 202}
203 203
204void ieee80211s_update_metric(struct ieee80211_local *local,
205 struct sta_info *stainfo, struct sk_buff *skb)
206{
207 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
208 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
209 int failed;
210
211 if (!ieee80211_is_data(hdr->frame_control))
212 return;
213
214 failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK);
215
216 /* moving average, scaled to 100 */
217 stainfo->fail_avg = ((80 * stainfo->fail_avg + 5) / 100 + 20 * failed);
218 if (stainfo->fail_avg > 95)
219 mesh_plink_broken(stainfo);
220}
221
204static u32 airtime_link_metric_get(struct ieee80211_local *local, 222static u32 airtime_link_metric_get(struct ieee80211_local *local,
205 struct sta_info *sta) 223 struct sta_info *sta)
206{ 224{
@@ -479,6 +497,7 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
479 hopcount, ttl, cpu_to_le32(lifetime), 497 hopcount, ttl, cpu_to_le32(lifetime),
480 cpu_to_le32(metric), cpu_to_le32(preq_id), 498 cpu_to_le32(metric), cpu_to_le32(preq_id),
481 sdata); 499 sdata);
500 ifmsh->mshstats.fwded_mcast++;
482 ifmsh->mshstats.fwded_frames++; 501 ifmsh->mshstats.fwded_frames++;
483 } 502 }
484} 503}
@@ -537,6 +556,8 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
537 cpu_to_le32(lifetime), cpu_to_le32(metric), 556 cpu_to_le32(lifetime), cpu_to_le32(metric),
538 0, sdata); 557 0, sdata);
539 rcu_read_unlock(); 558 rcu_read_unlock();
559
560 sdata->u.mesh.mshstats.fwded_unicast++;
540 sdata->u.mesh.mshstats.fwded_frames++; 561 sdata->u.mesh.mshstats.fwded_frames++;
541 return; 562 return;
542 563
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 007164919e02..7c5142988bbb 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -51,7 +51,6 @@
51#include <linux/random.h> 51#include <linux/random.h>
52#include <linux/ieee80211.h> 52#include <linux/ieee80211.h>
53#include <net/mac80211.h> 53#include <net/mac80211.h>
54#include "mesh.h"
55#include "rate.h" 54#include "rate.h"
56#include "rc80211_minstrel.h" 55#include "rc80211_minstrel.h"
57 56
@@ -156,16 +155,12 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
156 struct sk_buff *skb) 155 struct sk_buff *skb)
157{ 156{
158 struct minstrel_sta_info *mi = priv_sta; 157 struct minstrel_sta_info *mi = priv_sta;
159 struct minstrel_priv *mp = (struct minstrel_priv *)priv;
160 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 158 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
161 struct ieee80211_tx_rate *ar = info->status.rates; 159 struct ieee80211_tx_rate *ar = info->status.rates;
162 struct ieee80211_local *local = hw_to_local(mp->hw);
163 struct sta_info *si;
164 int i, ndx; 160 int i, ndx;
165 int success; 161 int success;
166 162
167 success = !!(info->flags & IEEE80211_TX_STAT_ACK); 163 success = !!(info->flags & IEEE80211_TX_STAT_ACK);
168 si = sta_info_get(local, sta->addr);
169 164
170 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 165 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
171 if (ar[i].idx < 0) 166 if (ar[i].idx < 0)
@@ -177,17 +172,8 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
177 172
178 mi->r[ndx].attempts += ar[i].count; 173 mi->r[ndx].attempts += ar[i].count;
179 174
180 if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0)) { 175 if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0))
181 mi->r[ndx].success += success; 176 mi->r[ndx].success += success;
182 if (si) {
183 si->fail_avg = (18050 - mi->r[ndx].probability)
184 / 180;
185 WARN_ON(si->fail_avg > 100);
186 if (si->fail_avg == 100 &&
187 ieee80211_vif_is_mesh(&si->sdata->vif))
188 mesh_plink_broken(si);
189 }
190 }
191 } 177 }
192 178
193 if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && (i >= 0)) 179 if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && (i >= 0))
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index 8c053be9dc24..699d3ed869c4 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -169,19 +169,9 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
169 * still a good measurement and copy it. */ 169 * still a good measurement and copy it. */
170 if (unlikely(spinfo->tx_num_xmit == 0)) 170 if (unlikely(spinfo->tx_num_xmit == 0))
171 pf = spinfo->last_pf; 171 pf = spinfo->last_pf;
172 else { 172 else
173 /* XXX: BAD HACK!!! */
174 struct sta_info *si = container_of(sta, struct sta_info, sta);
175
176 pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit; 173 pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit;
177 174
178 if (ieee80211_vif_is_mesh(&si->sdata->vif) && pf == 100)
179 mesh_plink_broken(si);
180 pf <<= RC_PID_ARITH_SHIFT;
181 si->fail_avg = ((pf + (spinfo->last_pf << 3)) / 9)
182 >> RC_PID_ARITH_SHIFT;
183 }
184
185 spinfo->tx_num_xmit = 0; 175 spinfo->tx_num_xmit = 0;
186 spinfo->tx_num_failed = 0; 176 spinfo->tx_num_failed = 0;
187 177
@@ -311,7 +301,6 @@ rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
311 struct rc_pid_sta_info *spinfo = priv_sta; 301 struct rc_pid_sta_info *spinfo = priv_sta;
312 struct rc_pid_info *pinfo = priv; 302 struct rc_pid_info *pinfo = priv;
313 struct rc_pid_rateinfo *rinfo = pinfo->rinfo; 303 struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
314 struct sta_info *si;
315 int i, j, tmp; 304 int i, j, tmp;
316 bool s; 305 bool s;
317 306
@@ -348,9 +337,6 @@ rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
348 } 337 }
349 338
350 spinfo->txrate_idx = rate_lowest_index(sband, sta); 339 spinfo->txrate_idx = rate_lowest_index(sband, sta);
351 /* HACK */
352 si = container_of(sta, struct sta_info, sta);
353 si->fail_avg = 0;
354} 340}
355 341
356static void *rate_control_pid_alloc(struct ieee80211_hw *hw, 342static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 4cd9e45b1443..7065fd7e7ba2 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1550,7 +1550,10 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1550 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; 1550 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1551 info->control.vif = &rx->sdata->vif; 1551 info->control.vif = &rx->sdata->vif;
1552 ieee80211_select_queue(local, fwd_skb); 1552 ieee80211_select_queue(local, fwd_skb);
1553 if (!is_multicast_ether_addr(fwd_hdr->addr1)) { 1553 if (is_multicast_ether_addr(fwd_hdr->addr1))
1554 IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
1555 fwded_mcast);
1556 else {
1554 int err; 1557 int err;
1555 /* 1558 /*
1556 * Save TA to addr1 to send TA a path error if a 1559 * Save TA to addr1 to send TA a path error if a
@@ -1564,6 +1567,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1564 * later to the pending skb queue. */ 1567 * later to the pending skb queue. */
1565 if (err) 1568 if (err)
1566 return RX_DROP_MONITOR; 1569 return RX_DROP_MONITOR;
1570
1571 IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
1572 fwded_unicast);
1567 } 1573 }
1568 IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, 1574 IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
1569 fwded_frames); 1575 fwded_frames);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index e091cbc3434f..1e04be6b9129 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -292,13 +292,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
292 if (was_hw_scan) 292 if (was_hw_scan)
293 goto done; 293 goto done;
294 294
295 spin_lock_bh(&local->filter_lock); 295 ieee80211_configure_filter(local);
296 local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC;
297 drv_configure_filter(local, FIF_BCN_PRBRESP_PROMISC,
298 &local->filter_flags,
299 local->mc_count,
300 local->mc_list);
301 spin_unlock_bh(&local->filter_lock);
302 296
303 drv_sw_scan_complete(local); 297 drv_sw_scan_complete(local);
304 298
@@ -376,13 +370,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
376 local->next_scan_state = SCAN_DECISION; 370 local->next_scan_state = SCAN_DECISION;
377 local->scan_channel_idx = 0; 371 local->scan_channel_idx = 0;
378 372
379 spin_lock_bh(&local->filter_lock); 373 ieee80211_configure_filter(local);
380 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
381 drv_configure_filter(local, FIF_BCN_PRBRESP_PROMISC,
382 &local->filter_flags,
383 local->mc_count,
384 local->mc_list);
385 spin_unlock_bh(&local->filter_lock);
386 374
387 /* TODO: start scan as soon as all nullfunc frames are ACKed */ 375 /* TODO: start scan as soon as all nullfunc frames are ACKed */
388 ieee80211_queue_delayed_work(&local->hw, 376 ieee80211_queue_delayed_work(&local->hw,
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index e55d57f559ec..5eb306377c63 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1076,9 +1076,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1076 /* reconfigure hardware */ 1076 /* reconfigure hardware */
1077 ieee80211_hw_config(local, ~0); 1077 ieee80211_hw_config(local, ~0);
1078 1078
1079 spin_lock_bh(&local->filter_lock);
1080 ieee80211_configure_filter(local); 1079 ieee80211_configure_filter(local);
1081 spin_unlock_bh(&local->filter_lock);
1082 1080
1083 /* Finally also reconfigure all the BSS information */ 1081 /* Finally also reconfigure all the BSS information */
1084 list_for_each_entry(sdata, &local->interfaces, list) { 1082 list_for_each_entry(sdata, &local->interfaces, list) {
diff --git a/net/wireless/core.c b/net/wireless/core.c
index bc99e4ec7463..154e1e294cb9 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -12,6 +12,7 @@
12#include <linux/debugfs.h> 12#include <linux/debugfs.h>
13#include <linux/notifier.h> 13#include <linux/notifier.h>
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/etherdevice.h>
15#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
16#include <net/genetlink.h> 17#include <net/genetlink.h>
17#include <net/cfg80211.h> 18#include <net/cfg80211.h>
@@ -309,7 +310,8 @@ static void cfg80211_process_events(struct wireless_dev *wdev)
309 switch (ev->type) { 310 switch (ev->type) {
310 case EVENT_CONNECT_RESULT: 311 case EVENT_CONNECT_RESULT:
311 __cfg80211_connect_result( 312 __cfg80211_connect_result(
312 wdev->netdev, ev->cr.bssid, 313 wdev->netdev, is_zero_ether_addr(ev->cr.bssid) ?
314 NULL : ev->cr.bssid,
313 ev->cr.req_ie, ev->cr.req_ie_len, 315 ev->cr.req_ie, ev->cr.req_ie_len,
314 ev->cr.resp_ie, ev->cr.resp_ie_len, 316 ev->cr.resp_ie, ev->cr.resp_ie_len,
315 ev->cr.status, 317 ev->cr.status,
@@ -430,6 +432,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
430 INIT_WORK(&rdev->conn_work, cfg80211_conn_work); 432 INIT_WORK(&rdev->conn_work, cfg80211_conn_work);
431 INIT_WORK(&rdev->event_work, cfg80211_event_work); 433 INIT_WORK(&rdev->event_work, cfg80211_event_work);
432 434
435 init_waitqueue_head(&rdev->dev_wait);
436
433 /* 437 /*
434 * Initialize wiphy parameters to IEEE 802.11 MIB default values. 438 * Initialize wiphy parameters to IEEE 802.11 MIB default values.
435 * Fragmentation and RTS threshold are disabled by default with the 439 * Fragmentation and RTS threshold are disabled by default with the
@@ -574,7 +578,23 @@ void wiphy_unregister(struct wiphy *wiphy)
574 /* protect the device list */ 578 /* protect the device list */
575 mutex_lock(&cfg80211_mutex); 579 mutex_lock(&cfg80211_mutex);
576 580
581 wait_event(rdev->dev_wait, ({
582 int __count;
583 mutex_lock(&rdev->devlist_mtx);
584 __count = rdev->opencount;
585 mutex_unlock(&rdev->devlist_mtx);
586 __count == 0;}));
587
588 mutex_lock(&rdev->devlist_mtx);
577 BUG_ON(!list_empty(&rdev->netdev_list)); 589 BUG_ON(!list_empty(&rdev->netdev_list));
590 mutex_unlock(&rdev->devlist_mtx);
591
592 /*
593 * First remove the hardware from everywhere, this makes
594 * it impossible to find from userspace.
595 */
596 cfg80211_debugfs_rdev_del(rdev);
597 list_del(&rdev->list);
578 598
579 /* 599 /*
580 * Try to grab rdev->mtx. If a command is still in progress, 600 * Try to grab rdev->mtx. If a command is still in progress,
@@ -582,21 +602,18 @@ void wiphy_unregister(struct wiphy *wiphy)
582 * down the device already. We wait for this command to complete 602 * down the device already. We wait for this command to complete
583 * before unlinking the item from the list. 603 * before unlinking the item from the list.
584 * Note: as codified by the BUG_ON above we cannot get here if 604 * Note: as codified by the BUG_ON above we cannot get here if
585 * a virtual interface is still associated. Hence, we can only 605 * a virtual interface is still present. Hence, we can only get
586 * get to lock contention here if userspace issues a command 606 * to lock contention here if userspace issues a command that
587 * that identified the hardware by wiphy index. 607 * identified the hardware by wiphy index.
588 */ 608 */
589 mutex_lock(&rdev->mtx); 609 cfg80211_lock_rdev(rdev);
590 /* unlock again before freeing */ 610 /* nothing */
591 mutex_unlock(&rdev->mtx); 611 cfg80211_unlock_rdev(rdev);
592
593 cfg80211_debugfs_rdev_del(rdev);
594 612
595 /* If this device got a regulatory hint tell core its 613 /* If this device got a regulatory hint tell core its
596 * free to listen now to a new shiny device regulatory hint */ 614 * free to listen now to a new shiny device regulatory hint */
597 reg_device_remove(wiphy); 615 reg_device_remove(wiphy);
598 616
599 list_del(&rdev->list);
600 cfg80211_rdev_list_generation++; 617 cfg80211_rdev_list_generation++;
601 device_del(&rdev->wiphy.dev); 618 device_del(&rdev->wiphy.dev);
602 debugfs_remove(rdev->wiphy.debugfsdir); 619 debugfs_remove(rdev->wiphy.debugfsdir);
@@ -605,7 +622,6 @@ void wiphy_unregister(struct wiphy *wiphy)
605 622
606 flush_work(&rdev->scan_done_wk); 623 flush_work(&rdev->scan_done_wk);
607 cancel_work_sync(&rdev->conn_work); 624 cancel_work_sync(&rdev->conn_work);
608 kfree(rdev->scan_req);
609 flush_work(&rdev->event_work); 625 flush_work(&rdev->event_work);
610} 626}
611EXPORT_SYMBOL(wiphy_unregister); 627EXPORT_SYMBOL(wiphy_unregister);
@@ -636,6 +652,31 @@ void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked)
636} 652}
637EXPORT_SYMBOL(wiphy_rfkill_set_hw_state); 653EXPORT_SYMBOL(wiphy_rfkill_set_hw_state);
638 654
655static void wdev_cleanup_work(struct work_struct *work)
656{
657 struct wireless_dev *wdev;
658 struct cfg80211_registered_device *rdev;
659
660 wdev = container_of(work, struct wireless_dev, cleanup_work);
661 rdev = wiphy_to_dev(wdev->wiphy);
662
663 cfg80211_lock_rdev(rdev);
664
665 if (WARN_ON(rdev->scan_req && rdev->scan_req->dev == wdev->netdev)) {
666 rdev->scan_req->aborted = true;
667 ___cfg80211_scan_done(rdev);
668 }
669
670 cfg80211_unlock_rdev(rdev);
671
672 mutex_lock(&rdev->devlist_mtx);
673 rdev->opencount--;
674 mutex_unlock(&rdev->devlist_mtx);
675 wake_up(&rdev->dev_wait);
676
677 dev_put(wdev->netdev);
678}
679
639static int cfg80211_netdev_notifier_call(struct notifier_block * nb, 680static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
640 unsigned long state, 681 unsigned long state,
641 void *ndev) 682 void *ndev)
@@ -653,7 +694,13 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
653 694
654 switch (state) { 695 switch (state) {
655 case NETDEV_REGISTER: 696 case NETDEV_REGISTER:
697 /*
698 * NB: cannot take rdev->mtx here because this may be
699 * called within code protected by it when interfaces
700 * are added with nl80211.
701 */
656 mutex_init(&wdev->mtx); 702 mutex_init(&wdev->mtx);
703 INIT_WORK(&wdev->cleanup_work, wdev_cleanup_work);
657 INIT_LIST_HEAD(&wdev->event_list); 704 INIT_LIST_HEAD(&wdev->event_list);
658 spin_lock_init(&wdev->event_lock); 705 spin_lock_init(&wdev->event_lock);
659 mutex_lock(&rdev->devlist_mtx); 706 mutex_lock(&rdev->devlist_mtx);
@@ -708,8 +755,22 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
708 default: 755 default:
709 break; 756 break;
710 } 757 }
758 dev_hold(dev);
759 schedule_work(&wdev->cleanup_work);
711 break; 760 break;
712 case NETDEV_UP: 761 case NETDEV_UP:
762 /*
763 * If we have a really quick DOWN/UP succession we may
764 * have this work still pending ... cancel it and see
765 * if it was pending, in which case we need to account
766 * for some of the work it would have done.
767 */
768 if (cancel_work_sync(&wdev->cleanup_work)) {
769 mutex_lock(&rdev->devlist_mtx);
770 rdev->opencount--;
771 mutex_unlock(&rdev->devlist_mtx);
772 dev_put(dev);
773 }
713#ifdef CONFIG_WIRELESS_EXT 774#ifdef CONFIG_WIRELESS_EXT
714 cfg80211_lock_rdev(rdev); 775 cfg80211_lock_rdev(rdev);
715 mutex_lock(&rdev->devlist_mtx); 776 mutex_lock(&rdev->devlist_mtx);
@@ -725,18 +786,17 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
725 break; 786 break;
726 } 787 }
727 wdev_unlock(wdev); 788 wdev_unlock(wdev);
789 rdev->opencount++;
728 mutex_unlock(&rdev->devlist_mtx); 790 mutex_unlock(&rdev->devlist_mtx);
729 cfg80211_unlock_rdev(rdev); 791 cfg80211_unlock_rdev(rdev);
730#endif 792#endif
731 break; 793 break;
732 case NETDEV_UNREGISTER: 794 case NETDEV_UNREGISTER:
733 cfg80211_lock_rdev(rdev); 795 /*
734 796 * NB: cannot take rdev->mtx here because this may be
735 if (WARN_ON(rdev->scan_req && rdev->scan_req->dev == dev)) { 797 * called within code protected by it when interfaces
736 rdev->scan_req->aborted = true; 798 * are removed with nl80211.
737 ___cfg80211_scan_done(rdev); 799 */
738 }
739
740 mutex_lock(&rdev->devlist_mtx); 800 mutex_lock(&rdev->devlist_mtx);
741 /* 801 /*
742 * It is possible to get NETDEV_UNREGISTER 802 * It is possible to get NETDEV_UNREGISTER
@@ -749,13 +809,11 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
749 sysfs_remove_link(&dev->dev.kobj, "phy80211"); 809 sysfs_remove_link(&dev->dev.kobj, "phy80211");
750 list_del_init(&wdev->list); 810 list_del_init(&wdev->list);
751 rdev->devlist_generation++; 811 rdev->devlist_generation++;
752 mutex_destroy(&wdev->mtx);
753#ifdef CONFIG_WIRELESS_EXT 812#ifdef CONFIG_WIRELESS_EXT
754 kfree(wdev->wext.keys); 813 kfree(wdev->wext.keys);
755#endif 814#endif
756 } 815 }
757 mutex_unlock(&rdev->devlist_mtx); 816 mutex_unlock(&rdev->devlist_mtx);
758 cfg80211_unlock_rdev(rdev);
759 break; 817 break;
760 case NETDEV_PRE_UP: 818 case NETDEV_PRE_UP:
761 if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) 819 if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
diff --git a/net/wireless/core.h b/net/wireless/core.h
index c603f5286326..f565432ae22f 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -50,6 +50,8 @@ struct cfg80211_registered_device {
50 struct mutex devlist_mtx; 50 struct mutex devlist_mtx;
51 struct list_head netdev_list; 51 struct list_head netdev_list;
52 int devlist_generation; 52 int devlist_generation;
53 int opencount; /* also protected by devlist_mtx */
54 wait_queue_head_t dev_wait;
53 55
54 /* BSSes/scanning */ 56 /* BSSes/scanning */
55 spinlock_t bss_lock; 57 spinlock_t bss_lock;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index da64071ceb84..79d2eec54cec 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -96,6 +96,15 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
96 WARN_ON(!bss); 96 WARN_ON(!bss);
97 } 97 }
98 98
99 if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) {
100 /*
101 * This is for the userspace SME, the CONNECTING
102 * state will be changed to CONNECTED by
103 * __cfg80211_connect_result() below.
104 */
105 wdev->sme_state = CFG80211_SME_CONNECTING;
106 }
107
99 /* this consumes one bss reference (unless bss is NULL) */ 108 /* this consumes one bss reference (unless bss is NULL) */
100 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs, 109 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
101 status_code, 110 status_code,
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 8e2ef54ea714..4a8289f9b4f0 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -351,15 +351,13 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
351 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) 351 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
352 return; 352 return;
353 353
354 if (wdev->sme_state == CFG80211_SME_CONNECTED) 354 if (WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING))
355 nl80211_send_roamed(wiphy_to_dev(wdev->wiphy), dev, 355 return;
356
357 nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev,
356 bssid, req_ie, req_ie_len, 358 bssid, req_ie, req_ie_len,
357 resp_ie, resp_ie_len, GFP_KERNEL); 359 resp_ie, resp_ie_len,
358 else 360 status, GFP_KERNEL);
359 nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev,
360 bssid, req_ie, req_ie_len,
361 resp_ie, resp_ie_len,
362 status, GFP_KERNEL);
363 361
364#ifdef CONFIG_WIRELESS_EXT 362#ifdef CONFIG_WIRELESS_EXT
365 if (wextev) { 363 if (wextev) {
@@ -392,18 +390,13 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
392 wdev->current_bss = NULL; 390 wdev->current_bss = NULL;
393 } 391 }
394 392
395 if (status == WLAN_STATUS_SUCCESS &&
396 wdev->sme_state == CFG80211_SME_IDLE)
397 goto success;
398
399 if (wdev->sme_state != CFG80211_SME_CONNECTING)
400 return;
401
402 if (wdev->conn) 393 if (wdev->conn)
403 wdev->conn->state = CFG80211_CONN_IDLE; 394 wdev->conn->state = CFG80211_CONN_IDLE;
404 395
405 if (status != WLAN_STATUS_SUCCESS) { 396 if (status != WLAN_STATUS_SUCCESS) {
406 wdev->sme_state = CFG80211_SME_IDLE; 397 wdev->sme_state = CFG80211_SME_IDLE;
398 if (wdev->conn)
399 kfree(wdev->conn->ie);
407 kfree(wdev->conn); 400 kfree(wdev->conn);
408 wdev->conn = NULL; 401 wdev->conn = NULL;
409 kfree(wdev->connect_keys); 402 kfree(wdev->connect_keys);
@@ -412,7 +405,6 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
412 return; 405 return;
413 } 406 }
414 407
415 success:
416 if (!bss) 408 if (!bss)
417 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, 409 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
418 wdev->ssid, wdev->ssid_len, 410 wdev->ssid, wdev->ssid_len,
@@ -458,7 +450,8 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
458 return; 450 return;
459 451
460 ev->type = EVENT_CONNECT_RESULT; 452 ev->type = EVENT_CONNECT_RESULT;
461 memcpy(ev->cr.bssid, bssid, ETH_ALEN); 453 if (bssid)
454 memcpy(ev->cr.bssid, bssid, ETH_ALEN);
462 ev->cr.req_ie = ((u8 *)ev) + sizeof(*ev); 455 ev->cr.req_ie = ((u8 *)ev) + sizeof(*ev);
463 ev->cr.req_ie_len = req_ie_len; 456 ev->cr.req_ie_len = req_ie_len;
464 memcpy((void *)ev->cr.req_ie, req_ie, req_ie_len); 457 memcpy((void *)ev->cr.req_ie, req_ie, req_ie_len);
@@ -789,6 +782,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
789 } 782 }
790 } 783 }
791 if (err) { 784 if (err) {
785 kfree(wdev->conn->ie);
792 kfree(wdev->conn); 786 kfree(wdev->conn);
793 wdev->conn = NULL; 787 wdev->conn = NULL;
794 wdev->sme_state = CFG80211_SME_IDLE; 788 wdev->sme_state = CFG80211_SME_IDLE;
@@ -858,6 +852,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
858 (wdev->conn->state == CFG80211_CONN_SCANNING || 852 (wdev->conn->state == CFG80211_CONN_SCANNING ||
859 wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)) { 853 wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)) {
860 wdev->sme_state = CFG80211_SME_IDLE; 854 wdev->sme_state = CFG80211_SME_IDLE;
855 kfree(wdev->conn->ie);
861 kfree(wdev->conn); 856 kfree(wdev->conn);
862 wdev->conn = NULL; 857 wdev->conn = NULL;
863 wdev->ssid_len = 0; 858 wdev->ssid_len = 0;
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index c44917492210..c12029b1def0 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -771,6 +771,7 @@ int cfg80211_wext_siwfreq(struct net_device *dev,
771 return err; 771 return err;
772 } 772 }
773} 773}
774EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq);
774 775
775int cfg80211_wext_giwfreq(struct net_device *dev, 776int cfg80211_wext_giwfreq(struct net_device *dev,
776 struct iw_request_info *info, 777 struct iw_request_info *info,