aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/bcma/host_pci.c1
-rw-r--r--drivers/net/wireless/airo.c33
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_initvals.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9001_initvals.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_calib.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_initvals.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_phy.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.h16
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_paprd.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9485_initvals.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c48
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_9287.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h25
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_gpio.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c79
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c42
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h4
-rw-r--r--drivers/net/wireless/ath/carl9170/fw.c19
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c10
-rw-r--r--drivers/net/wireless/ath/hw.c10
-rw-r--r--drivers/net/wireless/b43/b43.h24
-rw-r--r--drivers/net/wireless/b43/dma.c37
-rw-r--r--drivers/net/wireless/b43/leds.c4
-rw-r--r--drivers/net/wireless/b43/lo.c4
-rw-r--r--drivers/net/wireless/b43/main.c194
-rw-r--r--drivers/net/wireless/b43/phy_a.c16
-rw-r--r--drivers/net/wireless/b43/phy_common.c8
-rw-r--r--drivers/net/wireless/b43/phy_g.c48
-rw-r--r--drivers/net/wireless/b43/phy_lp.c22
-rw-r--r--drivers/net/wireless/b43/phy_n.c24
-rw-r--r--drivers/net/wireless/b43/pio.c30
-rw-r--r--drivers/net/wireless/b43/rfkill.c6
-rw-r--r--drivers/net/wireless/b43/sdio.c4
-rw-r--r--drivers/net/wireless/b43/sysfs.c4
-rw-r--r--drivers/net/wireless/b43/tables_lpphy.c4
-rw-r--r--drivers/net/wireless/b43/wa.c4
-rw-r--r--drivers/net/wireless/b43/xmit.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-2000.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c86
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-sta.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-ucode.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c250
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h66
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h58
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sv-open.c177
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-testmode.h34
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c364
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c4
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c4
-rw-r--r--drivers/net/wireless/mwifiex/main.h9
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c4
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c59
-rw-r--r--drivers/net/wireless/p54/p54usb.c1
-rw-r--r--drivers/net/wireless/rndis_wlan.c3
-rw-r--r--drivers/net/wireless/rtlwifi/ps.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/phy.c69
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/phy.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.c1
-rw-r--r--drivers/staging/ath6kl/os/linux/cfg80211.c2
-rw-r--r--drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c4
-rw-r--r--drivers/staging/wlan-ng/cfg80211.c2
-rw-r--r--fs/proc/generic.c1
-rw-r--r--include/linux/rfkill-gpio.h43
-rw-r--r--include/net/cfg80211.h8
-rw-r--r--net/mac80211/iface.c4
-rw-r--r--net/mac80211/main.c22
-rw-r--r--net/mac80211/mesh.h7
-rw-r--r--net/mac80211/mesh_pathtbl.c204
-rw-r--r--net/mac80211/scan.c5
-rw-r--r--net/rfkill/Kconfig9
-rw-r--r--net/rfkill/Makefile1
-rw-r--r--net/rfkill/rfkill-gpio.c227
-rw-r--r--net/wireless/core.h5
-rw-r--r--net/wireless/nl80211.c12
-rw-r--r--net/wireless/sme.c19
-rw-r--r--net/wireless/util.c2
142 files changed, 1820 insertions, 976 deletions
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
index 99dd36e8500b..ffd8797faf4f 100644
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -171,6 +171,7 @@ static void bcma_host_pci_remove(struct pci_dev *dev)
171} 171}
172 172
173static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { 173static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
174 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
174 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) }, 175 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
175 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, 176 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
176 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, 177 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index a70c512f05d2..55cf71fbffe3 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -4501,17 +4501,15 @@ static int setup_proc_entry( struct net_device *dev,
4501 struct proc_dir_entry *entry; 4501 struct proc_dir_entry *entry;
4502 /* First setup the device directory */ 4502 /* First setup the device directory */
4503 strcpy(apriv->proc_name,dev->name); 4503 strcpy(apriv->proc_name,dev->name);
4504 apriv->proc_entry = create_proc_entry(apriv->proc_name, 4504 apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm,
4505 S_IFDIR|airo_perm, 4505 airo_entry);
4506 airo_entry);
4507 if (!apriv->proc_entry) 4506 if (!apriv->proc_entry)
4508 goto fail; 4507 goto fail;
4509 apriv->proc_entry->uid = proc_uid; 4508 apriv->proc_entry->uid = proc_uid;
4510 apriv->proc_entry->gid = proc_gid; 4509 apriv->proc_entry->gid = proc_gid;
4511 4510
4512 /* Setup the StatsDelta */ 4511 /* Setup the StatsDelta */
4513 entry = proc_create_data("StatsDelta", 4512 entry = proc_create_data("StatsDelta", S_IRUGO & proc_perm,
4514 S_IFREG | (S_IRUGO&proc_perm),
4515 apriv->proc_entry, &proc_statsdelta_ops, dev); 4513 apriv->proc_entry, &proc_statsdelta_ops, dev);
4516 if (!entry) 4514 if (!entry)
4517 goto fail_stats_delta; 4515 goto fail_stats_delta;
@@ -4519,8 +4517,7 @@ static int setup_proc_entry( struct net_device *dev,
4519 entry->gid = proc_gid; 4517 entry->gid = proc_gid;
4520 4518
4521 /* Setup the Stats */ 4519 /* Setup the Stats */
4522 entry = proc_create_data("Stats", 4520 entry = proc_create_data("Stats", S_IRUGO & proc_perm,
4523 S_IFREG | (S_IRUGO&proc_perm),
4524 apriv->proc_entry, &proc_stats_ops, dev); 4521 apriv->proc_entry, &proc_stats_ops, dev);
4525 if (!entry) 4522 if (!entry)
4526 goto fail_stats; 4523 goto fail_stats;
@@ -4528,8 +4525,7 @@ static int setup_proc_entry( struct net_device *dev,
4528 entry->gid = proc_gid; 4525 entry->gid = proc_gid;
4529 4526
4530 /* Setup the Status */ 4527 /* Setup the Status */
4531 entry = proc_create_data("Status", 4528 entry = proc_create_data("Status", S_IRUGO & proc_perm,
4532 S_IFREG | (S_IRUGO&proc_perm),
4533 apriv->proc_entry, &proc_status_ops, dev); 4529 apriv->proc_entry, &proc_status_ops, dev);
4534 if (!entry) 4530 if (!entry)
4535 goto fail_status; 4531 goto fail_status;
@@ -4537,8 +4533,7 @@ static int setup_proc_entry( struct net_device *dev,
4537 entry->gid = proc_gid; 4533 entry->gid = proc_gid;
4538 4534
4539 /* Setup the Config */ 4535 /* Setup the Config */
4540 entry = proc_create_data("Config", 4536 entry = proc_create_data("Config", proc_perm,
4541 S_IFREG | proc_perm,
4542 apriv->proc_entry, &proc_config_ops, dev); 4537 apriv->proc_entry, &proc_config_ops, dev);
4543 if (!entry) 4538 if (!entry)
4544 goto fail_config; 4539 goto fail_config;
@@ -4546,8 +4541,7 @@ static int setup_proc_entry( struct net_device *dev,
4546 entry->gid = proc_gid; 4541 entry->gid = proc_gid;
4547 4542
4548 /* Setup the SSID */ 4543 /* Setup the SSID */
4549 entry = proc_create_data("SSID", 4544 entry = proc_create_data("SSID", proc_perm,
4550 S_IFREG | proc_perm,
4551 apriv->proc_entry, &proc_SSID_ops, dev); 4545 apriv->proc_entry, &proc_SSID_ops, dev);
4552 if (!entry) 4546 if (!entry)
4553 goto fail_ssid; 4547 goto fail_ssid;
@@ -4555,8 +4549,7 @@ static int setup_proc_entry( struct net_device *dev,
4555 entry->gid = proc_gid; 4549 entry->gid = proc_gid;
4556 4550
4557 /* Setup the APList */ 4551 /* Setup the APList */
4558 entry = proc_create_data("APList", 4552 entry = proc_create_data("APList", proc_perm,
4559 S_IFREG | proc_perm,
4560 apriv->proc_entry, &proc_APList_ops, dev); 4553 apriv->proc_entry, &proc_APList_ops, dev);
4561 if (!entry) 4554 if (!entry)
4562 goto fail_aplist; 4555 goto fail_aplist;
@@ -4564,8 +4557,7 @@ static int setup_proc_entry( struct net_device *dev,
4564 entry->gid = proc_gid; 4557 entry->gid = proc_gid;
4565 4558
4566 /* Setup the BSSList */ 4559 /* Setup the BSSList */
4567 entry = proc_create_data("BSSList", 4560 entry = proc_create_data("BSSList", proc_perm,
4568 S_IFREG | proc_perm,
4569 apriv->proc_entry, &proc_BSSList_ops, dev); 4561 apriv->proc_entry, &proc_BSSList_ops, dev);
4570 if (!entry) 4562 if (!entry)
4571 goto fail_bsslist; 4563 goto fail_bsslist;
@@ -4573,8 +4565,7 @@ static int setup_proc_entry( struct net_device *dev,
4573 entry->gid = proc_gid; 4565 entry->gid = proc_gid;
4574 4566
4575 /* Setup the WepKey */ 4567 /* Setup the WepKey */
4576 entry = proc_create_data("WepKey", 4568 entry = proc_create_data("WepKey", proc_perm,
4577 S_IFREG | proc_perm,
4578 apriv->proc_entry, &proc_wepkey_ops, dev); 4569 apriv->proc_entry, &proc_wepkey_ops, dev);
4579 if (!entry) 4570 if (!entry)
4580 goto fail_wepkey; 4571 goto fail_wepkey;
@@ -5706,9 +5697,7 @@ static int __init airo_init_module( void )
5706{ 5697{
5707 int i; 5698 int i;
5708 5699
5709 airo_entry = create_proc_entry("driver/aironet", 5700 airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL);
5710 S_IFDIR | airo_perm,
5711 NULL);
5712 5701
5713 if (airo_entry) { 5702 if (airo_entry) {
5714 airo_entry->uid = proc_uid; 5703 airo_entry->uid = proc_uid;
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 61956392f2da..5b49cd03bfdf 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org> 3 * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
4 * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org> 4 * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
5 * 5 *
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 5a1f4f511bc1..bfb6481f01f9 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 0cd6783de883..dbab5b9ce494 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h
index 36f7d0639db3..234617c948a1 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index 4bf9dab4f2b3..441bb33f17ad 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h
index 69a94c7e45cb..6d2e2f3303f9 100644
--- a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index cb611b287b35..015d97439935 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index f44c84ab5dce..f344cc2b3d59 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
index 6203eed860dd..7573257731b6 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index 7a332f16b79a..077e8a6983fa 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index a57e963cf0dc..2fe0a34cbabc 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
index 47780ef1c892..453af6dc514b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index f915a3dbfcad..e8ac70da5ac7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index f276cb922b4d..f48051c50092 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index d985841ff401..0ca7635d0669 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
index afb0b5ee1865..ab21a4915981 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
@@ -1,3 +1,19 @@
1/*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
1#ifndef AR9003_EEPROM_H 17#ifndef AR9003_EEPROM_H
2#define AR9003_EEPROM_H 18#define AR9003_EEPROM_H
3 19
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index a55eddbb2589..392bf0f8ff16 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index be6adec33ddb..10d71f7d3fc2 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
index 45cc7e80436c..c50449387bf1 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 356d2fd78822..e4d6a87ec538 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 25f3c2fdf2bc..eee23ecd118a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index c7505b48e5c0..443090d278e3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2002-2010 Atheros Communications, Inc. 2 * Copyright (c) 2010-2011 Atheros Communications, Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
index fbdde29f0ab8..611ea6ce8508 100644
--- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 03b37d7be1c3..f75068b4b310 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -397,6 +397,9 @@ struct ath_beacon {
397 struct ath_descdma bdma; 397 struct ath_descdma bdma;
398 struct ath_txq *cabq; 398 struct ath_txq *cabq;
399 struct list_head bbuf; 399 struct list_head bbuf;
400
401 bool tx_processed;
402 bool tx_last;
400}; 403};
401 404
402void ath_beacon_tasklet(unsigned long data); 405void ath_beacon_tasklet(unsigned long data);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 637dbc5f7b67..d4d8ceced89b 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -18,6 +18,12 @@
18 18
19#define FUDGE 2 19#define FUDGE 2
20 20
21static void ath9k_reset_beacon_status(struct ath_softc *sc)
22{
23 sc->beacon.tx_processed = false;
24 sc->beacon.tx_last = false;
25}
26
21/* 27/*
22 * This function will modify certain transmit queue properties depending on 28 * This function will modify certain transmit queue properties depending on
23 * the operating mode of the station (AP or AdHoc). Parameters are AIFS 29 * the operating mode of the station (AP or AdHoc). Parameters are AIFS
@@ -72,6 +78,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
72 struct ieee80211_supported_band *sband; 78 struct ieee80211_supported_band *sband;
73 u8 rate = 0; 79 u8 rate = 0;
74 80
81 ath9k_reset_beacon_status(sc);
82
75 ds = bf->bf_desc; 83 ds = bf->bf_desc;
76 flags = ATH9K_TXDESC_NOACK; 84 flags = ATH9K_TXDESC_NOACK;
77 85
@@ -134,6 +142,8 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
134 struct ieee80211_tx_info *info; 142 struct ieee80211_tx_info *info;
135 int cabq_depth; 143 int cabq_depth;
136 144
145 ath9k_reset_beacon_status(sc);
146
137 avp = (void *)vif->drv_priv; 147 avp = (void *)vif->drv_priv;
138 cabq = sc->beacon.cabq; 148 cabq = sc->beacon.cabq;
139 149
@@ -351,9 +361,7 @@ void ath_beacon_tasklet(unsigned long data)
351 struct ath_buf *bf = NULL; 361 struct ath_buf *bf = NULL;
352 struct ieee80211_vif *vif; 362 struct ieee80211_vif *vif;
353 int slot; 363 int slot;
354 u32 bfaddr, bc = 0, tsftu; 364 u32 bfaddr, bc = 0;
355 u64 tsf;
356 u16 intval;
357 365
358 /* 366 /*
359 * Check if the previous beacon has gone out. If 367 * Check if the previous beacon has gone out. If
@@ -388,17 +396,27 @@ void ath_beacon_tasklet(unsigned long data)
388 * on the tsf to safeguard against missing an swba. 396 * on the tsf to safeguard against missing an swba.
389 */ 397 */
390 398
391 intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
392 399
393 tsf = ath9k_hw_gettsf64(ah); 400 if (ah->opmode == NL80211_IFTYPE_AP) {
394 tsf += TU_TO_USEC(ah->config.sw_beacon_response_time); 401 u16 intval;
395 tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF); 402 u32 tsftu;
396 slot = (tsftu % (intval * ATH_BCBUF)) / intval; 403 u64 tsf;
397 vif = sc->beacon.bslot[slot]; 404
405 intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
406 tsf = ath9k_hw_gettsf64(ah);
407 tsf += TU_TO_USEC(ah->config.sw_beacon_response_time);
408 tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF);
409 slot = (tsftu % (intval * ATH_BCBUF)) / intval;
410 vif = sc->beacon.bslot[slot];
411
412 ath_dbg(common, ATH_DBG_BEACON,
413 "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
414 slot, tsf, tsftu / ATH_BCBUF, intval, vif);
415 } else {
416 slot = 0;
417 vif = sc->beacon.bslot[slot];
418 }
398 419
399 ath_dbg(common, ATH_DBG_BEACON,
400 "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
401 slot, tsf, tsftu / ATH_BCBUF, intval, vif);
402 420
403 bfaddr = 0; 421 bfaddr = 0;
404 if (vif) { 422 if (vif) {
@@ -636,6 +654,8 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
636 struct ath_common *common = ath9k_hw_common(ah); 654 struct ath_common *common = ath9k_hw_common(ah);
637 u32 tsf, delta, intval, nexttbtt; 655 u32 tsf, delta, intval, nexttbtt;
638 656
657 ath9k_reset_beacon_status(sc);
658
639 tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE); 659 tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE);
640 intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD); 660 intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD);
641 661
@@ -646,7 +666,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
646 delta = (tsf - sc->beacon.bc_tstamp); 666 delta = (tsf - sc->beacon.bc_tstamp);
647 else 667 else
648 delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp)); 668 delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp));
649 nexttbtt = tsf + roundup(delta, intval); 669 nexttbtt = tsf + intval - (delta % intval);
650 } 670 }
651 671
652 ath_dbg(common, ATH_DBG_BEACON, 672 ath_dbg(common, ATH_DBG_BEACON,
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 23f15a7ca7f1..41ce0b139886 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2009 Atheros Communications Inc. 2 * Copyright (c) 2009-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index a9efca83d676..234f77689b14 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2009 Atheros Communications Inc. 2 * Copyright (c) 2009-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 558b228a717f..a1250c586e40 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index 4420780fa3b8..1bef41d1b1ff 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 74535e6dfb82..fa6bd2d189e5 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2009 Atheros Communications Inc. 2 * Copyright (c) 2009-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 5124f1420b3a..77ec288b5a70 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2009 Atheros Communications Inc. 2 * Copyright (c) 2009-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index bad1a87249b6..d55ffd7d4bd2 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -435,6 +435,7 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
435 conf->channel_type, 435 conf->channel_type,
436 channel_type_str(conf->channel_type)); 436 channel_type_str(conf->channel_type));
437 437
438 ath9k_ps_wakeup(sc);
438 put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr); 439 put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr);
439 put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4); 440 put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4);
440 len += snprintf(buf + len, sizeof(buf) - len, 441 len += snprintf(buf + len, sizeof(buf) - len,
@@ -444,6 +445,7 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
444 len += snprintf(buf + len, sizeof(buf) - len, 445 len += snprintf(buf + len, sizeof(buf) - len,
445 "addrmask: %pM\n", addr); 446 "addrmask: %pM\n", addr);
446 tmp = ath9k_hw_getrxfilter(sc->sc_ah); 447 tmp = ath9k_hw_getrxfilter(sc->sc_ah);
448 ath9k_ps_restore(sc);
447 len += snprintf(buf + len, sizeof(buf) - len, 449 len += snprintf(buf + len, sizeof(buf) - len,
448 "rfilt: 0x%x", tmp); 450 "rfilt: 0x%x", tmp);
449 if (tmp & ATH9K_RX_FILTER_UCAST) 451 if (tmp & ATH9K_RX_FILTER_UCAST)
@@ -725,6 +727,7 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
725 break; 727 break;
726 } 728 }
727 729
730 ath9k_ps_wakeup(sc);
728 len += snprintf(buf + len, size - len, 731 len += snprintf(buf + len, size - len,
729 "curbssid: %pM\n" 732 "curbssid: %pM\n"
730 "OP-Mode: %s(%i)\n" 733 "OP-Mode: %s(%i)\n"
@@ -734,6 +737,7 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
734 REG_READ(ah, AR_BEACON_PERIOD)); 737 REG_READ(ah, AR_BEACON_PERIOD));
735 738
736 reg = REG_READ(ah, AR_TIMER_MODE); 739 reg = REG_READ(ah, AR_TIMER_MODE);
740 ath9k_ps_restore(sc);
737 len += snprintf(buf + len, size - len, "Timer-Mode-Register: 0x%x (", 741 len += snprintf(buf + len, size - len, "Timer-Mode-Register: 0x%x (",
738 reg); 742 reg);
739 if (reg & AR_TBTT_TIMER_EN) 743 if (reg & AR_TBTT_TIMER_EN)
@@ -1050,7 +1054,9 @@ static ssize_t read_file_regval(struct file *file, char __user *user_buf,
1050 unsigned int len; 1054 unsigned int len;
1051 u32 regval; 1055 u32 regval;
1052 1056
1057 ath9k_ps_wakeup(sc);
1053 regval = REG_READ_D(ah, sc->debug.regidx); 1058 regval = REG_READ_D(ah, sc->debug.regidx);
1059 ath9k_ps_restore(sc);
1054 len = sprintf(buf, "0x%08x\n", regval); 1060 len = sprintf(buf, "0x%08x\n", regval);
1055 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1061 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1056} 1062}
@@ -1072,7 +1078,9 @@ static ssize_t write_file_regval(struct file *file, const char __user *user_buf,
1072 if (strict_strtoul(buf, 0, &regval)) 1078 if (strict_strtoul(buf, 0, &regval))
1073 return -EINVAL; 1079 return -EINVAL;
1074 1080
1081 ath9k_ps_wakeup(sc);
1075 REG_WRITE_D(ah, sc->debug.regidx, regval); 1082 REG_WRITE_D(ah, sc->debug.regidx, regval);
1083 ath9k_ps_restore(sc);
1076 return count; 1084 return count;
1077} 1085}
1078 1086
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 5488a324cc10..8ce6ad80f4e2 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index 8c18bed3a558..e61404dda8c5 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 3e316133f114..de99c0da52e4 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index 6f714dd72365..5b1e894f3d67 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
index b87db4763098..7856f0d4512d 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index c031854b569f..17f0a6806207 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 0349b3a1cc58..bc713fc28191 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 2e3a33a53406..260f1f37a60e 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
index 2bdcdbc14b1e..794f63094e5d 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -18,7 +18,7 @@
18#define HTC_USB_H 18#define HTC_USB_H
19 19
20#define MAJOR_VERSION_REQ 1 20#define MAJOR_VERSION_REQ 1
21#define MINOR_VERSION_REQ 2 21#define MINOR_VERSION_REQ 3
22 22
23#define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB)) 23#define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB))
24 24
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index dfc7a982fc7e..5bc022087e65 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -46,15 +46,8 @@ extern struct ieee80211_ops ath9k_htc_ops;
46extern int htc_modparam_nohwcrypt; 46extern int htc_modparam_nohwcrypt;
47 47
48enum htc_phymode { 48enum htc_phymode {
49 HTC_MODE_AUTO = 0, 49 HTC_MODE_11NA = 0,
50 HTC_MODE_11A = 1, 50 HTC_MODE_11NG = 1
51 HTC_MODE_11B = 2,
52 HTC_MODE_11G = 3,
53 HTC_MODE_FH = 4,
54 HTC_MODE_TURBO_A = 5,
55 HTC_MODE_TURBO_G = 6,
56 HTC_MODE_11NA = 7,
57 HTC_MODE_11NG = 8
58}; 51};
59 52
60enum htc_opmode { 53enum htc_opmode {
@@ -123,18 +116,13 @@ struct ath9k_htc_target_vif {
123 u8 pad; 116 u8 pad;
124} __packed; 117} __packed;
125 118
126#define ATH_HTC_STA_AUTH 0x0001
127#define ATH_HTC_STA_QOS 0x0002
128#define ATH_HTC_STA_ERP 0x0004
129#define ATH_HTC_STA_HT 0x0008
130
131struct ath9k_htc_target_sta { 119struct ath9k_htc_target_sta {
132 u8 macaddr[ETH_ALEN]; 120 u8 macaddr[ETH_ALEN];
133 u8 bssid[ETH_ALEN]; 121 u8 bssid[ETH_ALEN];
134 u8 sta_index; 122 u8 sta_index;
135 u8 vif_index; 123 u8 vif_index;
136 u8 is_vif_sta; 124 u8 is_vif_sta;
137 __be16 flags; /* ATH_HTC_STA_* */ 125 __be16 flags;
138 __be16 htcap; 126 __be16 htcap;
139 __be16 maxampdu; 127 __be16 maxampdu;
140 u8 pad; 128 u8 pad;
@@ -285,9 +273,9 @@ struct ath9k_htc_rx {
285}; 273};
286 274
287#define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */ 275#define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */
288#define ATH9K_HTC_TX_TIMEOUT_INTERVAL 2500 /* ms */ 276#define ATH9K_HTC_TX_TIMEOUT_INTERVAL 3000 /* ms */
289#define ATH9K_HTC_TX_RESERVE 10 277#define ATH9K_HTC_TX_RESERVE 10
290#define ATH9K_HTC_TX_TIMEOUT_COUNT 20 278#define ATH9K_HTC_TX_TIMEOUT_COUNT 40
291#define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE) 279#define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE)
292 280
293#define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0) 281#define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0)
@@ -450,6 +438,7 @@ struct ath9k_htc_priv {
450 u8 vif_sta_pos[ATH9K_HTC_MAX_VIF]; 438 u8 vif_sta_pos[ATH9K_HTC_MAX_VIF];
451 u8 num_ibss_vif; 439 u8 num_ibss_vif;
452 u8 num_sta_vif; 440 u8 num_sta_vif;
441 u8 num_sta_assoc_vif;
453 u8 num_ap_vif; 442 u8 num_ap_vif;
454 443
455 u16 op_flags; 444 u16 op_flags;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index 0ded2c66d5ff..aa6a73118706 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
index af57fe5aab98..db2352e5cc0d 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index bfdc8a887183..61e6d3950718 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -258,7 +258,7 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid,
258 */ 258 */
259 259
260 if (IS_AR7010_DEVICE(drv_info)) 260 if (IS_AR7010_DEVICE(drv_info))
261 priv->htc->credits = 48; 261 priv->htc->credits = 45;
262 else 262 else
263 priv->htc->credits = 33; 263 priv->htc->credits = 33;
264 264
@@ -769,11 +769,6 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
769 hw->channel_change_time = 5000; 769 hw->channel_change_time = 5000;
770 hw->max_listen_interval = 10; 770 hw->max_listen_interval = 10;
771 771
772 if (AR_SREV_9271(priv->ah))
773 hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_9271;
774 else
775 hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_7010;
776
777 hw->vif_data_size = sizeof(struct ath9k_htc_vif); 772 hw->vif_data_size = sizeof(struct ath9k_htc_vif);
778 hw->sta_data_size = sizeof(struct ath9k_htc_sta); 773 hw->sta_data_size = sizeof(struct ath9k_htc_sta);
779 774
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 5aa104fe7eeb..7b7796895432 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -26,7 +26,7 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
26{ 26{
27 enum htc_phymode mode; 27 enum htc_phymode mode;
28 28
29 mode = HTC_MODE_AUTO; 29 mode = -EINVAL;
30 30
31 switch (ichan->chanmode) { 31 switch (ichan->chanmode) {
32 case CHANNEL_G: 32 case CHANNEL_G:
@@ -45,6 +45,8 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
45 break; 45 break;
46 } 46 }
47 47
48 WARN_ON(mode < 0);
49
48 return mode; 50 return mode;
49} 51}
50 52
@@ -500,9 +502,6 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
500 tsta.maxampdu = cpu_to_be16(maxampdu); 502 tsta.maxampdu = cpu_to_be16(maxampdu);
501 } 503 }
502 504
503 if (sta && sta->ht_cap.ht_supported)
504 tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
505
506 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); 505 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
507 if (ret) { 506 if (ret) {
508 if (sta) 507 if (sta)
@@ -582,7 +581,7 @@ int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
582 memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target)); 581 memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
583 582
584 tcap.ampdu_limit = cpu_to_be32(0xffff); 583 tcap.ampdu_limit = cpu_to_be32(0xffff);
585 tcap.ampdu_subframes = priv->hw->max_tx_aggregation_subframes; 584 tcap.ampdu_subframes = 0xff;
586 tcap.enable_coex = enable_coex; 585 tcap.enable_coex = enable_coex;
587 tcap.tx_chainmask = priv->ah->caps.tx_chainmask; 586 tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
588 587
@@ -1165,6 +1164,8 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1165 1164
1166 ath9k_htc_set_opmode(priv); 1165 ath9k_htc_set_opmode(priv);
1167 1166
1167 ath9k_htc_set_bssid_mask(priv, vif);
1168
1168 /* 1169 /*
1169 * Stop ANI only if there are no associated station interfaces. 1170 * Stop ANI only if there are no associated station interfaces.
1170 */ 1171 */
@@ -1435,6 +1436,37 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw,
1435 return ret; 1436 return ret;
1436} 1437}
1437 1438
1439static void ath9k_htc_set_bssid(struct ath9k_htc_priv *priv)
1440{
1441 struct ath_common *common = ath9k_hw_common(priv->ah);
1442
1443 ath9k_hw_write_associd(priv->ah);
1444 ath_dbg(common, ATH_DBG_CONFIG,
1445 "BSSID: %pM aid: 0x%x\n",
1446 common->curbssid, common->curaid);
1447}
1448
1449static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1450{
1451 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
1452 struct ath_common *common = ath9k_hw_common(priv->ah);
1453 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1454
1455 if ((vif->type == NL80211_IFTYPE_STATION) && bss_conf->assoc) {
1456 common->curaid = bss_conf->aid;
1457 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1458 }
1459}
1460
1461static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv)
1462{
1463 if (priv->num_sta_assoc_vif == 1) {
1464 ieee80211_iterate_active_interfaces_atomic(priv->hw,
1465 ath9k_htc_bss_iter, priv);
1466 ath9k_htc_set_bssid(priv);
1467 }
1468}
1469
1438static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, 1470static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1439 struct ieee80211_vif *vif, 1471 struct ieee80211_vif *vif,
1440 struct ieee80211_bss_conf *bss_conf, 1472 struct ieee80211_bss_conf *bss_conf,
@@ -1443,43 +1475,32 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1443 struct ath9k_htc_priv *priv = hw->priv; 1475 struct ath9k_htc_priv *priv = hw->priv;
1444 struct ath_hw *ah = priv->ah; 1476 struct ath_hw *ah = priv->ah;
1445 struct ath_common *common = ath9k_hw_common(ah); 1477 struct ath_common *common = ath9k_hw_common(ah);
1446 bool set_assoc;
1447 1478
1448 mutex_lock(&priv->mutex); 1479 mutex_lock(&priv->mutex);
1449 ath9k_htc_ps_wakeup(priv); 1480 ath9k_htc_ps_wakeup(priv);
1450 1481
1451 /*
1452 * Set the HW AID/BSSID only for the first station interface
1453 * or in IBSS mode.
1454 */
1455 set_assoc = !!((priv->ah->opmode == NL80211_IFTYPE_ADHOC) ||
1456 ((priv->ah->opmode == NL80211_IFTYPE_STATION) &&
1457 (priv->num_sta_vif == 1)));
1458
1459
1460 if (changed & BSS_CHANGED_ASSOC) { 1482 if (changed & BSS_CHANGED_ASSOC) {
1461 if (set_assoc) { 1483 ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1462 ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", 1484 bss_conf->assoc);
1463 bss_conf->assoc);
1464 1485
1465 common->curaid = bss_conf->assoc ? 1486 bss_conf->assoc ?
1466 bss_conf->aid : 0; 1487 priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--;
1467 1488
1468 if (bss_conf->assoc) 1489 if (priv->ah->opmode == NL80211_IFTYPE_STATION) {
1490 if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1))
1469 ath9k_htc_start_ani(priv); 1491 ath9k_htc_start_ani(priv);
1470 else 1492 else if (priv->num_sta_assoc_vif == 0)
1471 ath9k_htc_stop_ani(priv); 1493 ath9k_htc_stop_ani(priv);
1472 } 1494 }
1473 } 1495 }
1474 1496
1475 if (changed & BSS_CHANGED_BSSID) { 1497 if (changed & BSS_CHANGED_BSSID) {
1476 if (set_assoc) { 1498 if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) {
1499 common->curaid = bss_conf->aid;
1477 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); 1500 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1478 ath9k_hw_write_associd(ah); 1501 ath9k_htc_set_bssid(priv);
1479 1502 } else if (priv->ah->opmode == NL80211_IFTYPE_STATION) {
1480 ath_dbg(common, ATH_DBG_CONFIG, 1503 ath9k_htc_choose_set_bssid(priv);
1481 "BSSID: %pM aid: 0x%x\n",
1482 common->curbssid, common->curaid);
1483 } 1504 }
1484 } 1505 }
1485 1506
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index a898dac22337..2d81c700e201 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -875,6 +875,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
875 rfilt |= ATH9K_RX_FILTER_CONTROL; 875 rfilt |= ATH9K_RX_FILTER_CONTROL;
876 876
877 if ((ah->opmode == NL80211_IFTYPE_STATION) && 877 if ((ah->opmode == NL80211_IFTYPE_STATION) &&
878 (priv->nvifs <= 1) &&
878 !(priv->rxfilter & FIF_BCN_PRBRESP_PROMISC)) 879 !(priv->rxfilter & FIF_BCN_PRBRESP_PROMISC))
879 rfilt |= ATH9K_RX_FILTER_MYBEACON; 880 rfilt |= ATH9K_RX_FILTER_MYBEACON;
880 else 881 else
@@ -888,6 +889,9 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
888 if (priv->rxfilter & FIF_PSPOLL) 889 if (priv->rxfilter & FIF_PSPOLL)
889 rfilt |= ATH9K_RX_FILTER_PSPOLL; 890 rfilt |= ATH9K_RX_FILTER_PSPOLL;
890 891
892 if (priv->nvifs > 1)
893 rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
894
891 return rfilt; 895 return rfilt;
892 896
893#undef RX_FILTER_PRESERVE 897#undef RX_FILTER_PRESERVE
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
index cee970fdf652..1b90ed8795c3 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h
index 91a5305db95a..e1ffbb6bd636 100644
--- a/drivers/net/wireless/ath/ath9k/htc_hst.h
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 8b8f0445aef8..2f3e07263fcb 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index b75b5dca4e29..72543ce8f616 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 7af2773d2bfc..57435ce62792 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index b172d1509515..45c585a337e9 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index bd6d2b9d736f..c2091f1f4096 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index b60c130917f7..8e848c4d16ba 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 17ebdf1e8b7b..a198ee374b05 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
@@ -2332,6 +2332,45 @@ static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
2332 return false; 2332 return false;
2333} 2333}
2334 2334
2335int ath9k_tx_last_beacon(struct ieee80211_hw *hw)
2336{
2337 struct ath_softc *sc = hw->priv;
2338 struct ath_hw *ah = sc->sc_ah;
2339 struct ieee80211_vif *vif;
2340 struct ath_vif *avp;
2341 struct ath_buf *bf;
2342 struct ath_tx_status ts;
2343 int status;
2344
2345 vif = sc->beacon.bslot[0];
2346 if (!vif)
2347 return 0;
2348
2349 avp = (void *)vif->drv_priv;
2350 if (!avp->is_bslot_active)
2351 return 0;
2352
2353 if (!sc->beacon.tx_processed) {
2354 tasklet_disable(&sc->bcon_tasklet);
2355
2356 bf = avp->av_bcbuf;
2357 if (!bf || !bf->bf_mpdu)
2358 goto skip;
2359
2360 status = ath9k_hw_txprocdesc(ah, bf->bf_desc, &ts);
2361 if (status == -EINPROGRESS)
2362 goto skip;
2363
2364 sc->beacon.tx_processed = true;
2365 sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK);
2366
2367skip:
2368 tasklet_enable(&sc->bcon_tasklet);
2369 }
2370
2371 return sc->beacon.tx_last;
2372}
2373
2335struct ieee80211_ops ath9k_ops = { 2374struct ieee80211_ops ath9k_ops = {
2336 .tx = ath9k_tx, 2375 .tx = ath9k_tx,
2337 .start = ath9k_start, 2376 .start = ath9k_start,
@@ -2356,4 +2395,5 @@ struct ieee80211_ops ath9k_ops = {
2356 .set_coverage_class = ath9k_set_coverage_class, 2395 .set_coverage_class = ath9k_set_coverage_class,
2357 .flush = ath9k_flush, 2396 .flush = ath9k_flush,
2358 .tx_frames_pending = ath9k_tx_frames_pending, 2397 .tx_frames_pending = ath9k_tx_frames_pending,
2398 .tx_last_beacon = ath9k_tx_last_beacon,
2359}; 2399};
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 9c65459be100..b8cbfc707213 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index 9441bf8ca2fd..8b380305b0fc 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 4ccbf2ddb553..17542214c93f 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004 Video54 Technologies, Inc. 2 * Copyright (c) 2004 Video54 Technologies, Inc.
3 * Copyright (c) 2004-2009 Atheros Communications, Inc. 3 * Copyright (c) 2004-2011 Atheros Communications, Inc.
4 * 4 *
5 * Permission to use, copy, modify, and/or distribute this software for any 5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above 6 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index 5d984b8acdb1..c3d850207bee 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004 Sam Leffler, Errno Consulting 2 * Copyright (c) 2004 Sam Leffler, Errno Consulting
3 * Copyright (c) 2004 Video54 Technologies, Inc. 3 * Copyright (c) 2004 Video54 Technologies, Inc.
4 * Copyright (c) 2008-2009 Atheros Communications Inc. 4 * Copyright (c) 2008-2011 Atheros Communications Inc.
5 * 5 *
6 * Permission to use, copy, modify, and/or distribute this software for any 6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 4f52e0429f99..07e35e59c9e3 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 456f3ec20fef..c18ee9921fb1 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
index f9b1eb4853c4..35422fc1f2ce 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h
index 6095eeb6e025..fde6da619f30 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.h
+++ b/drivers/net/wireless/ath/ath9k/wmi.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Atheros Communications Inc. 2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 97dd1fac98b6..3779b8977d47 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc. 2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 * 3 *
4 * Permission to use, copy, modify, and/or distribute this software for any 4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above 5 * purpose with or without fee is hereby granted, provided that the above
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index bb578690935e..4da01a9f5680 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -286,6 +286,10 @@ struct ar9170 {
286 unsigned int tx_seq_table; 286 unsigned int tx_seq_table;
287 } fw; 287 } fw;
288 288
289 /* interface configuration combinations */
290 struct ieee80211_iface_limit if_comb_limits[1];
291 struct ieee80211_iface_combination if_combs[1];
292
289 /* reset / stuck frames/queue detection */ 293 /* reset / stuck frames/queue detection */
290 struct work_struct restart_work; 294 struct work_struct restart_work;
291 struct work_struct ping_work; 295 struct work_struct ping_work;
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c
index 9517ede9e2df..221957c5d373 100644
--- a/drivers/net/wireless/ath/carl9170/fw.c
+++ b/drivers/net/wireless/ath/carl9170/fw.c
@@ -151,6 +151,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
151 const struct carl9170fw_chk_desc *chk_desc; 151 const struct carl9170fw_chk_desc *chk_desc;
152 const struct carl9170fw_last_desc *last_desc; 152 const struct carl9170fw_last_desc *last_desc;
153 const struct carl9170fw_txsq_desc *txsq_desc; 153 const struct carl9170fw_txsq_desc *txsq_desc;
154 u16 if_comb_types;
154 155
155 last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC, 156 last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC,
156 sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER); 157 sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER);
@@ -268,6 +269,9 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
268 if (SUPP(CARL9170FW_WOL)) 269 if (SUPP(CARL9170FW_WOL))
269 device_set_wakeup_enable(&ar->udev->dev, true); 270 device_set_wakeup_enable(&ar->udev->dev, true);
270 271
272 if_comb_types = BIT(NL80211_IFTYPE_STATION) |
273 BIT(NL80211_IFTYPE_P2P_CLIENT);
274
271 ar->fw.vif_num = otus_desc->vif_num; 275 ar->fw.vif_num = otus_desc->vif_num;
272 ar->fw.cmd_bufs = otus_desc->cmd_bufs; 276 ar->fw.cmd_bufs = otus_desc->cmd_bufs;
273 ar->fw.address = le32_to_cpu(otus_desc->fw_address); 277 ar->fw.address = le32_to_cpu(otus_desc->fw_address);
@@ -294,12 +298,25 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
294 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); 298 ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
295 299
296 if (SUPP(CARL9170FW_WLANTX_CAB)) { 300 if (SUPP(CARL9170FW_WLANTX_CAB)) {
297 ar->hw->wiphy->interface_modes |= 301 if_comb_types |=
298 BIT(NL80211_IFTYPE_AP) | 302 BIT(NL80211_IFTYPE_AP) |
299 BIT(NL80211_IFTYPE_P2P_GO); 303 BIT(NL80211_IFTYPE_P2P_GO);
300 } 304 }
301 } 305 }
302 306
307 ar->if_comb_limits[0].max = ar->fw.vif_num;
308 ar->if_comb_limits[0].types = if_comb_types;
309
310 ar->if_combs[0].num_different_channels = 1;
311 ar->if_combs[0].max_interfaces = ar->fw.vif_num;
312 ar->if_combs[0].limits = ar->if_comb_limits;
313 ar->if_combs[0].n_limits = ARRAY_SIZE(ar->if_comb_limits);
314
315 ar->hw->wiphy->iface_combinations = ar->if_combs;
316 ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ar->if_combs);
317
318 ar->hw->wiphy->interface_modes |= if_comb_types;
319
303 txsq_desc = carl9170_fw_find_desc(ar, TXSQ_MAGIC, 320 txsq_desc = carl9170_fw_find_desc(ar, TXSQ_MAGIC,
304 sizeof(*txsq_desc), CARL9170FW_TXSQ_DESC_CUR_VER); 321 sizeof(*txsq_desc), CARL9170FW_TXSQ_DESC_CUR_VER);
305 322
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 7d5c65ea94e6..54d093c2ab44 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -1570,14 +1570,8 @@ void *carl9170_alloc(size_t priv_size)
1570 INIT_LIST_HEAD(&ar->vif_list); 1570 INIT_LIST_HEAD(&ar->vif_list);
1571 init_completion(&ar->tx_flush); 1571 init_completion(&ar->tx_flush);
1572 1572
1573 /* 1573 /* firmware decides which modes we support */
1574 * Note: 1574 hw->wiphy->interface_modes = 0;
1575 * IBSS/ADHOC and AP mode are only enabled, if the firmware
1576 * supports these modes. The code which will add the
1577 * additional interface_modes is in fw.c.
1578 */
1579 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1580 BIT(NL80211_IFTYPE_P2P_CLIENT);
1581 1575
1582 hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | 1576 hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
1583 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 1577 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c
index cc11d66f15bc..3f508e59f146 100644
--- a/drivers/net/wireless/ath/hw.c
+++ b/drivers/net/wireless/ath/hw.c
@@ -43,7 +43,7 @@
43 * set of ~ ( MAC XOR BSSID ) for all bssids we handle. 43 * set of ~ ( MAC XOR BSSID ) for all bssids we handle.
44 * 44 *
45 * When you do this you are essentially computing the common bits of all your 45 * When you do this you are essentially computing the common bits of all your
46 * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with 46 * BSSes. Later it is assumed the hardware will "and" (&) the BSSID mask with
47 * the MAC address to obtain the relevant bits and compare the result with 47 * the MAC address to obtain the relevant bits and compare the result with
48 * (frame's BSSID & mask) to see if they match. 48 * (frame's BSSID & mask) to see if they match.
49 * 49 *
@@ -71,8 +71,8 @@
71 * On loop iteration for BSSID-02: 71 * On loop iteration for BSSID-02:
72 * bssid_mask &= ~(0001 ^ 1001) 72 * bssid_mask &= ~(0001 ^ 1001)
73 * bssid_mask = (1010) & ~(0001 ^ 1001) 73 * bssid_mask = (1010) & ~(0001 ^ 1001)
74 * bssid_mask = (1010) & ~(1001) 74 * bssid_mask = (1010) & ~(1000)
75 * bssid_mask = (1010) & (0110) 75 * bssid_mask = (1010) & (0111)
76 * bssid_mask = 0010 76 * bssid_mask = 0010
77 * 77 *
78 * A bssid_mask of 0010 means "only pay attention to the second least 78 * A bssid_mask of 0010 means "only pay attention to the second least
@@ -102,11 +102,9 @@
102 * 102 *
103 * IFRAME-02: 0001 (we should allow) 103 * IFRAME-02: 0001 (we should allow)
104 * 104 *
105 * allow = (0001 & 1010) == 1010
106 *
107 * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0; 105 * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
108 * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0; 106 * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0;
109 * --> allow = (0010) == (0010) 107 * --> allow = (0000) == (0000)
110 * --> allow = 1 108 * --> allow = 1
111 * 109 *
112 * Other examples: 110 * Other examples:
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index ebc93c1bb5e7..25a78cfb7d15 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -567,6 +567,8 @@ struct b43_dma {
567 struct b43_dmaring *tx_ring_mcast; /* Multicast */ 567 struct b43_dmaring *tx_ring_mcast; /* Multicast */
568 568
569 struct b43_dmaring *rx_ring; 569 struct b43_dmaring *rx_ring;
570
571 u32 translation; /* Routing bits */
570}; 572};
571 573
572struct b43_pio_txqueue; 574struct b43_pio_txqueue;
@@ -705,7 +707,7 @@ enum {
705 707
706/* Data structure for one wireless device (802.11 core) */ 708/* Data structure for one wireless device (802.11 core) */
707struct b43_wldev { 709struct b43_wldev {
708 struct ssb_device *dev; 710 struct ssb_device *sdev;
709 struct b43_wl *wl; 711 struct b43_wl *wl;
710 712
711 /* The device initialization status. 713 /* The device initialization status.
@@ -879,22 +881,34 @@ static inline enum ieee80211_band b43_current_band(struct b43_wl *wl)
879 881
880static inline u16 b43_read16(struct b43_wldev *dev, u16 offset) 882static inline u16 b43_read16(struct b43_wldev *dev, u16 offset)
881{ 883{
882 return ssb_read16(dev->dev, offset); 884 return ssb_read16(dev->sdev, offset);
883} 885}
884 886
885static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value) 887static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value)
886{ 888{
887 ssb_write16(dev->dev, offset, value); 889 ssb_write16(dev->sdev, offset, value);
888} 890}
889 891
890static inline u32 b43_read32(struct b43_wldev *dev, u16 offset) 892static inline u32 b43_read32(struct b43_wldev *dev, u16 offset)
891{ 893{
892 return ssb_read32(dev->dev, offset); 894 return ssb_read32(dev->sdev, offset);
893} 895}
894 896
895static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value) 897static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value)
896{ 898{
897 ssb_write32(dev->dev, offset, value); 899 ssb_write32(dev->sdev, offset, value);
900}
901
902static inline void b43_block_read(struct b43_wldev *dev, void *buffer,
903 size_t count, u16 offset, u8 reg_width)
904{
905 ssb_block_read(dev->sdev, buffer, count, offset, reg_width);
906}
907
908static inline void b43_block_write(struct b43_wldev *dev, const void *buffer,
909 size_t count, u16 offset, u8 reg_width)
910{
911 ssb_block_write(dev->sdev, buffer, count, offset, reg_width);
898} 912}
899 913
900static inline bool b43_using_pio_transfers(struct b43_wldev *dev) 914static inline bool b43_using_pio_transfers(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index ff0f5ba14b2c..47d44bcff37d 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -80,7 +80,7 @@ static void op32_fill_descriptor(struct b43_dmaring *ring,
80 addr = (u32) (dmaaddr & ~SSB_DMA_TRANSLATION_MASK); 80 addr = (u32) (dmaaddr & ~SSB_DMA_TRANSLATION_MASK);
81 addrext = (u32) (dmaaddr & SSB_DMA_TRANSLATION_MASK) 81 addrext = (u32) (dmaaddr & SSB_DMA_TRANSLATION_MASK)
82 >> SSB_DMA_TRANSLATION_SHIFT; 82 >> SSB_DMA_TRANSLATION_SHIFT;
83 addr |= ssb_dma_translation(ring->dev->dev); 83 addr |= ring->dev->dma.translation;
84 ctl = bufsize & B43_DMA32_DCTL_BYTECNT; 84 ctl = bufsize & B43_DMA32_DCTL_BYTECNT;
85 if (slot == ring->nr_slots - 1) 85 if (slot == ring->nr_slots - 1)
86 ctl |= B43_DMA32_DCTL_DTABLEEND; 86 ctl |= B43_DMA32_DCTL_DTABLEEND;
@@ -174,7 +174,7 @@ static void op64_fill_descriptor(struct b43_dmaring *ring,
174 addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK); 174 addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK);
175 addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK) 175 addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK)
176 >> SSB_DMA_TRANSLATION_SHIFT; 176 >> SSB_DMA_TRANSLATION_SHIFT;
177 addrhi |= (ssb_dma_translation(ring->dev->dev) << 1); 177 addrhi |= (ring->dev->dma.translation << 1);
178 if (slot == ring->nr_slots - 1) 178 if (slot == ring->nr_slots - 1)
179 ctl0 |= B43_DMA64_DCTL0_DTABLEEND; 179 ctl0 |= B43_DMA64_DCTL0_DTABLEEND;
180 if (start) 180 if (start)
@@ -333,10 +333,10 @@ static inline
333 dma_addr_t dmaaddr; 333 dma_addr_t dmaaddr;
334 334
335 if (tx) { 335 if (tx) {
336 dmaaddr = dma_map_single(ring->dev->dev->dma_dev, 336 dmaaddr = dma_map_single(ring->dev->sdev->dma_dev,
337 buf, len, DMA_TO_DEVICE); 337 buf, len, DMA_TO_DEVICE);
338 } else { 338 } else {
339 dmaaddr = dma_map_single(ring->dev->dev->dma_dev, 339 dmaaddr = dma_map_single(ring->dev->sdev->dma_dev,
340 buf, len, DMA_FROM_DEVICE); 340 buf, len, DMA_FROM_DEVICE);
341 } 341 }
342 342
@@ -348,10 +348,10 @@ static inline
348 dma_addr_t addr, size_t len, int tx) 348 dma_addr_t addr, size_t len, int tx)
349{ 349{
350 if (tx) { 350 if (tx) {
351 dma_unmap_single(ring->dev->dev->dma_dev, 351 dma_unmap_single(ring->dev->sdev->dma_dev,
352 addr, len, DMA_TO_DEVICE); 352 addr, len, DMA_TO_DEVICE);
353 } else { 353 } else {
354 dma_unmap_single(ring->dev->dev->dma_dev, 354 dma_unmap_single(ring->dev->sdev->dma_dev,
355 addr, len, DMA_FROM_DEVICE); 355 addr, len, DMA_FROM_DEVICE);
356 } 356 }
357} 357}
@@ -361,7 +361,7 @@ static inline
361 dma_addr_t addr, size_t len) 361 dma_addr_t addr, size_t len)
362{ 362{
363 B43_WARN_ON(ring->tx); 363 B43_WARN_ON(ring->tx);
364 dma_sync_single_for_cpu(ring->dev->dev->dma_dev, 364 dma_sync_single_for_cpu(ring->dev->sdev->dma_dev,
365 addr, len, DMA_FROM_DEVICE); 365 addr, len, DMA_FROM_DEVICE);
366} 366}
367 367
@@ -370,7 +370,7 @@ static inline
370 dma_addr_t addr, size_t len) 370 dma_addr_t addr, size_t len)
371{ 371{
372 B43_WARN_ON(ring->tx); 372 B43_WARN_ON(ring->tx);
373 dma_sync_single_for_device(ring->dev->dev->dma_dev, 373 dma_sync_single_for_device(ring->dev->sdev->dma_dev,
374 addr, len, DMA_FROM_DEVICE); 374 addr, len, DMA_FROM_DEVICE);
375} 375}
376 376
@@ -401,7 +401,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
401 */ 401 */
402 if (ring->type == B43_DMA_64BIT) 402 if (ring->type == B43_DMA_64BIT)
403 flags |= GFP_DMA; 403 flags |= GFP_DMA;
404 ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev, 404 ring->descbase = dma_alloc_coherent(ring->dev->sdev->dma_dev,
405 B43_DMA_RINGMEMSIZE, 405 B43_DMA_RINGMEMSIZE,
406 &(ring->dmabase), flags); 406 &(ring->dmabase), flags);
407 if (!ring->descbase) { 407 if (!ring->descbase) {
@@ -415,7 +415,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
415 415
416static void free_ringmemory(struct b43_dmaring *ring) 416static void free_ringmemory(struct b43_dmaring *ring)
417{ 417{
418 dma_free_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE, 418 dma_free_coherent(ring->dev->sdev->dma_dev, B43_DMA_RINGMEMSIZE,
419 ring->descbase, ring->dmabase); 419 ring->descbase, ring->dmabase);
420} 420}
421 421
@@ -523,7 +523,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring,
523 dma_addr_t addr, 523 dma_addr_t addr,
524 size_t buffersize, bool dma_to_device) 524 size_t buffersize, bool dma_to_device)
525{ 525{
526 if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr))) 526 if (unlikely(dma_mapping_error(ring->dev->sdev->dma_dev, addr)))
527 return 1; 527 return 1;
528 528
529 switch (ring->type) { 529 switch (ring->type) {
@@ -658,7 +658,7 @@ static int dmacontroller_setup(struct b43_dmaring *ring)
658 int err = 0; 658 int err = 0;
659 u32 value; 659 u32 value;
660 u32 addrext; 660 u32 addrext;
661 u32 trans = ssb_dma_translation(ring->dev->dev); 661 u32 trans = ring->dev->dma.translation;
662 662
663 if (ring->tx) { 663 if (ring->tx) {
664 if (ring->type == B43_DMA_64BIT) { 664 if (ring->type == B43_DMA_64BIT) {
@@ -869,7 +869,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
869 goto err_kfree_meta; 869 goto err_kfree_meta;
870 870
871 /* test for ability to dma to txhdr_cache */ 871 /* test for ability to dma to txhdr_cache */
872 dma_test = dma_map_single(dev->dev->dma_dev, 872 dma_test = dma_map_single(dev->sdev->dma_dev,
873 ring->txhdr_cache, 873 ring->txhdr_cache,
874 b43_txhdr_size(dev), 874 b43_txhdr_size(dev),
875 DMA_TO_DEVICE); 875 DMA_TO_DEVICE);
@@ -884,7 +884,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
884 if (!ring->txhdr_cache) 884 if (!ring->txhdr_cache)
885 goto err_kfree_meta; 885 goto err_kfree_meta;
886 886
887 dma_test = dma_map_single(dev->dev->dma_dev, 887 dma_test = dma_map_single(dev->sdev->dma_dev,
888 ring->txhdr_cache, 888 ring->txhdr_cache,
889 b43_txhdr_size(dev), 889 b43_txhdr_size(dev),
890 DMA_TO_DEVICE); 890 DMA_TO_DEVICE);
@@ -898,7 +898,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
898 } 898 }
899 } 899 }
900 900
901 dma_unmap_single(dev->dev->dma_dev, 901 dma_unmap_single(dev->sdev->dma_dev,
902 dma_test, b43_txhdr_size(dev), 902 dma_test, b43_txhdr_size(dev),
903 DMA_TO_DEVICE); 903 DMA_TO_DEVICE);
904 } 904 }
@@ -1013,9 +1013,9 @@ static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask)
1013 /* Try to set the DMA mask. If it fails, try falling back to a 1013 /* Try to set the DMA mask. If it fails, try falling back to a
1014 * lower mask, as we can always also support a lower one. */ 1014 * lower mask, as we can always also support a lower one. */
1015 while (1) { 1015 while (1) {
1016 err = dma_set_mask(dev->dev->dma_dev, mask); 1016 err = dma_set_mask(dev->sdev->dma_dev, mask);
1017 if (!err) { 1017 if (!err) {
1018 err = dma_set_coherent_mask(dev->dev->dma_dev, mask); 1018 err = dma_set_coherent_mask(dev->sdev->dma_dev, mask);
1019 if (!err) 1019 if (!err)
1020 break; 1020 break;
1021 } 1021 }
@@ -1055,6 +1055,7 @@ int b43_dma_init(struct b43_wldev *dev)
1055 err = b43_dma_set_mask(dev, dmamask); 1055 err = b43_dma_set_mask(dev, dmamask);
1056 if (err) 1056 if (err)
1057 return err; 1057 return err;
1058 dma->translation = ssb_dma_translation(dev->sdev);
1058 1059
1059 err = -ENOMEM; 1060 err = -ENOMEM;
1060 /* setup TX DMA channels. */ 1061 /* setup TX DMA channels. */
@@ -1084,7 +1085,7 @@ int b43_dma_init(struct b43_wldev *dev)
1084 goto err_destroy_mcast; 1085 goto err_destroy_mcast;
1085 1086
1086 /* No support for the TX status DMA ring. */ 1087 /* No support for the TX status DMA ring. */
1087 B43_WARN_ON(dev->dev->id.revision < 5); 1088 B43_WARN_ON(dev->sdev->id.revision < 5);
1088 1089
1089 b43dbg(dev->wl, "%u-bit DMA initialized\n", 1090 b43dbg(dev->wl, "%u-bit DMA initialized\n",
1090 (unsigned int)type); 1091 (unsigned int)type);
diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c
index c587115dd2b9..0cafafe368af 100644
--- a/drivers/net/wireless/b43/leds.c
+++ b/drivers/net/wireless/b43/leds.c
@@ -138,7 +138,7 @@ static int b43_register_led(struct b43_wldev *dev, struct b43_led *led,
138 led->led_dev.default_trigger = default_trigger; 138 led->led_dev.default_trigger = default_trigger;
139 led->led_dev.brightness_set = b43_led_brightness_set; 139 led->led_dev.brightness_set = b43_led_brightness_set;
140 140
141 err = led_classdev_register(dev->dev->dev, &led->led_dev); 141 err = led_classdev_register(dev->sdev->dev, &led->led_dev);
142 if (err) { 142 if (err) {
143 b43warn(dev->wl, "LEDs: Failed to register %s\n", name); 143 b43warn(dev->wl, "LEDs: Failed to register %s\n", name);
144 led->wl = NULL; 144 led->wl = NULL;
@@ -215,7 +215,7 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev,
215 enum b43_led_behaviour *behaviour, 215 enum b43_led_behaviour *behaviour,
216 bool *activelow) 216 bool *activelow)
217{ 217{
218 struct ssb_bus *bus = dev->dev->bus; 218 struct ssb_bus *bus = dev->sdev->bus;
219 u8 sprom[4]; 219 u8 sprom[4];
220 220
221 sprom[0] = bus->sprom.gpio0; 221 sprom[0] = bus->sprom.gpio0;
diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c
index 94e4f1378fc3..2ef7d4b38540 100644
--- a/drivers/net/wireless/b43/lo.c
+++ b/drivers/net/wireless/b43/lo.c
@@ -98,7 +98,7 @@ static u16 lo_measure_feedthrough(struct b43_wldev *dev,
98 rfover |= pga; 98 rfover |= pga;
99 rfover |= lna; 99 rfover |= lna;
100 rfover |= trsw_rx; 100 rfover |= trsw_rx;
101 if ((dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) 101 if ((dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA)
102 && phy->rev > 6) 102 && phy->rev > 6)
103 rfover |= B43_PHY_RFOVERVAL_EXTLNA; 103 rfover |= B43_PHY_RFOVERVAL_EXTLNA;
104 104
@@ -387,7 +387,7 @@ struct lo_g_saved_values {
387static void lo_measure_setup(struct b43_wldev *dev, 387static void lo_measure_setup(struct b43_wldev *dev,
388 struct lo_g_saved_values *sav) 388 struct lo_g_saved_values *sav)
389{ 389{
390 struct ssb_sprom *sprom = &dev->dev->bus->sprom; 390 struct ssb_sprom *sprom = &dev->sdev->bus->sprom;
391 struct b43_phy *phy = &dev->phy; 391 struct b43_phy *phy = &dev->phy;
392 struct b43_phy_g *gphy = phy->g; 392 struct b43_phy_g *gphy = phy->g;
393 struct b43_txpower_lo_control *lo = gphy->lo_control; 393 struct b43_txpower_lo_control *lo = gphy->lo_control;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 5a43984bdcea..eb4159686985 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -548,7 +548,7 @@ void b43_tsf_read(struct b43_wldev *dev, u64 *tsf)
548{ 548{
549 u32 low, high; 549 u32 low, high;
550 550
551 B43_WARN_ON(dev->dev->id.revision < 3); 551 B43_WARN_ON(dev->sdev->id.revision < 3);
552 552
553 /* The hardware guarantees us an atomic read, if we 553 /* The hardware guarantees us an atomic read, if we
554 * read the low register first. */ 554 * read the low register first. */
@@ -586,7 +586,7 @@ static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf)
586{ 586{
587 u32 low, high; 587 u32 low, high;
588 588
589 B43_WARN_ON(dev->dev->id.revision < 3); 589 B43_WARN_ON(dev->sdev->id.revision < 3);
590 590
591 low = tsf; 591 low = tsf;
592 high = (tsf >> 32); 592 high = (tsf >> 32);
@@ -714,7 +714,7 @@ void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on)
714 b43_ram_write(dev, i * 4, buffer[i]); 714 b43_ram_write(dev, i * 4, buffer[i]);
715 715
716 b43_write16(dev, 0x0568, 0x0000); 716 b43_write16(dev, 0x0568, 0x0000);
717 if (dev->dev->id.revision < 11) 717 if (dev->sdev->id.revision < 11)
718 b43_write16(dev, 0x07C0, 0x0000); 718 b43_write16(dev, 0x07C0, 0x0000);
719 else 719 else
720 b43_write16(dev, 0x07C0, 0x0100); 720 b43_write16(dev, 0x07C0, 0x0100);
@@ -1132,7 +1132,7 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags)
1132 b43_write32(dev, B43_MMIO_MACCTL, macctl); 1132 b43_write32(dev, B43_MMIO_MACCTL, macctl);
1133 /* Commit write */ 1133 /* Commit write */
1134 b43_read32(dev, B43_MMIO_MACCTL); 1134 b43_read32(dev, B43_MMIO_MACCTL);
1135 if (awake && dev->dev->id.revision >= 5) { 1135 if (awake && dev->sdev->id.revision >= 5) {
1136 /* Wait for the microcode to wake up. */ 1136 /* Wait for the microcode to wake up. */
1137 for (i = 0; i < 100; i++) { 1137 for (i = 0; i < 100; i++) {
1138 ucstat = b43_shm_read16(dev, B43_SHM_SHARED, 1138 ucstat = b43_shm_read16(dev, B43_SHM_SHARED,
@@ -1144,29 +1144,35 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags)
1144 } 1144 }
1145} 1145}
1146 1146
1147void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) 1147static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, u32 flags)
1148{ 1148{
1149 u32 tmslow; 1149 u32 tmslow;
1150 u32 macctl;
1151 1150
1152 flags |= B43_TMSLOW_PHYCLKEN; 1151 flags |= B43_TMSLOW_PHYCLKEN;
1153 flags |= B43_TMSLOW_PHYRESET; 1152 flags |= B43_TMSLOW_PHYRESET;
1154 if (dev->phy.type == B43_PHYTYPE_N) 1153 if (dev->phy.type == B43_PHYTYPE_N)
1155 flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */ 1154 flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */
1156 ssb_device_enable(dev->dev, flags); 1155 ssb_device_enable(dev->sdev, flags);
1157 msleep(2); /* Wait for the PLL to turn on. */ 1156 msleep(2); /* Wait for the PLL to turn on. */
1158 1157
1159 /* Now take the PHY out of Reset again */ 1158 /* Now take the PHY out of Reset again */
1160 tmslow = ssb_read32(dev->dev, SSB_TMSLOW); 1159 tmslow = ssb_read32(dev->sdev, SSB_TMSLOW);
1161 tmslow |= SSB_TMSLOW_FGC; 1160 tmslow |= SSB_TMSLOW_FGC;
1162 tmslow &= ~B43_TMSLOW_PHYRESET; 1161 tmslow &= ~B43_TMSLOW_PHYRESET;
1163 ssb_write32(dev->dev, SSB_TMSLOW, tmslow); 1162 ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
1164 ssb_read32(dev->dev, SSB_TMSLOW); /* flush */ 1163 ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */
1165 msleep(1); 1164 msleep(1);
1166 tmslow &= ~SSB_TMSLOW_FGC; 1165 tmslow &= ~SSB_TMSLOW_FGC;
1167 ssb_write32(dev->dev, SSB_TMSLOW, tmslow); 1166 ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
1168 ssb_read32(dev->dev, SSB_TMSLOW); /* flush */ 1167 ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */
1169 msleep(1); 1168 msleep(1);
1169}
1170
1171void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)
1172{
1173 u32 macctl;
1174
1175 b43_ssb_wireless_core_reset(dev, flags);
1170 1176
1171 /* Turn Analog ON, but only if we already know the PHY-type. 1177 /* Turn Analog ON, but only if we already know the PHY-type.
1172 * This protects against very early setup where we don't know the 1178 * This protects against very early setup where we don't know the
@@ -1215,7 +1221,7 @@ static void drain_txstatus_queue(struct b43_wldev *dev)
1215{ 1221{
1216 u32 dummy; 1222 u32 dummy;
1217 1223
1218 if (dev->dev->id.revision < 5) 1224 if (dev->sdev->id.revision < 5)
1219 return; 1225 return;
1220 /* Read all entries from the microcode TXstatus FIFO 1226 /* Read all entries from the microcode TXstatus FIFO
1221 * and throw them away. 1227 * and throw them away.
@@ -1421,9 +1427,9 @@ u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev,
1421 1427
1422 /* Get the mask of available antennas. */ 1428 /* Get the mask of available antennas. */
1423 if (dev->phy.gmode) 1429 if (dev->phy.gmode)
1424 antenna_mask = dev->dev->bus->sprom.ant_available_bg; 1430 antenna_mask = dev->sdev->bus->sprom.ant_available_bg;
1425 else 1431 else
1426 antenna_mask = dev->dev->bus->sprom.ant_available_a; 1432 antenna_mask = dev->sdev->bus->sprom.ant_available_a;
1427 1433
1428 if (!(antenna_mask & (1 << (antenna_nr - 1)))) { 1434 if (!(antenna_mask & (1 << (antenna_nr - 1)))) {
1429 /* This antenna is not available. Fall back to default. */ 1435 /* This antenna is not available. Fall back to default. */
@@ -1638,7 +1644,7 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
1638 mutex_lock(&wl->mutex); 1644 mutex_lock(&wl->mutex);
1639 dev = wl->current_dev; 1645 dev = wl->current_dev;
1640 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { 1646 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
1641 if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) { 1647 if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) {
1642 /* wl->mutex is enough. */ 1648 /* wl->mutex is enough. */
1643 b43_do_beacon_update_trigger_work(dev); 1649 b43_do_beacon_update_trigger_work(dev);
1644 mmiowb(); 1650 mmiowb();
@@ -1683,7 +1689,7 @@ static void b43_update_templates(struct b43_wl *wl)
1683static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) 1689static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)
1684{ 1690{
1685 b43_time_lock(dev); 1691 b43_time_lock(dev);
1686 if (dev->dev->id.revision >= 3) { 1692 if (dev->sdev->id.revision >= 3) {
1687 b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16)); 1693 b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16));
1688 b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10)); 1694 b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10));
1689 } else { 1695 } else {
@@ -2057,7 +2063,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx,
2057 B43_WARN_ON(1); 2063 B43_WARN_ON(1);
2058 return -ENOSYS; 2064 return -ENOSYS;
2059 } 2065 }
2060 err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev); 2066 err = request_firmware(&blob, ctx->fwname, ctx->dev->sdev->dev);
2061 if (err == -ENOENT) { 2067 if (err == -ENOENT) {
2062 snprintf(ctx->errors[ctx->req_type], 2068 snprintf(ctx->errors[ctx->req_type],
2063 sizeof(ctx->errors[ctx->req_type]), 2069 sizeof(ctx->errors[ctx->req_type]),
@@ -2107,13 +2113,12 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
2107{ 2113{
2108 struct b43_wldev *dev = ctx->dev; 2114 struct b43_wldev *dev = ctx->dev;
2109 struct b43_firmware *fw = &ctx->dev->fw; 2115 struct b43_firmware *fw = &ctx->dev->fw;
2110 const u8 rev = ctx->dev->dev->id.revision; 2116 const u8 rev = ctx->dev->sdev->id.revision;
2111 const char *filename; 2117 const char *filename;
2112 u32 tmshigh; 2118 u32 tmshigh;
2113 int err; 2119 int err;
2114 2120
2115 /* Get microcode */ 2121 /* Get microcode */
2116 tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH);
2117 if ((rev >= 5) && (rev <= 10)) 2122 if ((rev >= 5) && (rev <= 10))
2118 filename = "ucode5"; 2123 filename = "ucode5";
2119 else if ((rev >= 11) && (rev <= 12)) 2124 else if ((rev >= 11) && (rev <= 12))
@@ -2152,6 +2157,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
2152 switch (dev->phy.type) { 2157 switch (dev->phy.type) {
2153 case B43_PHYTYPE_A: 2158 case B43_PHYTYPE_A:
2154 if ((rev >= 5) && (rev <= 10)) { 2159 if ((rev >= 5) && (rev <= 10)) {
2160 tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH);
2155 if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) 2161 if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
2156 filename = "a0g1initvals5"; 2162 filename = "a0g1initvals5";
2157 else 2163 else
@@ -2196,6 +2202,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)
2196 switch (dev->phy.type) { 2202 switch (dev->phy.type) {
2197 case B43_PHYTYPE_A: 2203 case B43_PHYTYPE_A:
2198 if ((rev >= 5) && (rev <= 10)) { 2204 if ((rev >= 5) && (rev <= 10)) {
2205 tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH);
2199 if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) 2206 if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
2200 filename = "a0g1bsinitvals5"; 2207 filename = "a0g1bsinitvals5";
2201 else 2208 else
@@ -2441,7 +2448,7 @@ static int b43_upload_microcode(struct b43_wldev *dev)
2441 2448
2442 snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u", 2449 snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u",
2443 dev->fw.rev, dev->fw.patch); 2450 dev->fw.rev, dev->fw.patch);
2444 wiphy->hw_version = dev->dev->id.coreid; 2451 wiphy->hw_version = dev->sdev->id.coreid;
2445 2452
2446 if (b43_is_old_txhdr_format(dev)) { 2453 if (b43_is_old_txhdr_format(dev)) {
2447 /* We're over the deadline, but we keep support for old fw 2454 /* We're over the deadline, but we keep support for old fw
@@ -2557,10 +2564,20 @@ out:
2557/* Initialize the GPIOs 2564/* Initialize the GPIOs
2558 * http://bcm-specs.sipsolutions.net/GPIO 2565 * http://bcm-specs.sipsolutions.net/GPIO
2559 */ 2566 */
2567static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev)
2568{
2569 struct ssb_bus *bus = dev->sdev->bus;
2570
2571#ifdef CONFIG_SSB_DRIVER_PCICORE
2572 return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
2573#else
2574 return bus->chipco.dev;
2575#endif
2576}
2577
2560static int b43_gpio_init(struct b43_wldev *dev) 2578static int b43_gpio_init(struct b43_wldev *dev)
2561{ 2579{
2562 struct ssb_bus *bus = dev->dev->bus; 2580 struct ssb_device *gpiodev;
2563 struct ssb_device *gpiodev, *pcidev = NULL;
2564 u32 mask, set; 2581 u32 mask, set;
2565 2582
2566 b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) 2583 b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
@@ -2571,7 +2588,7 @@ static int b43_gpio_init(struct b43_wldev *dev)
2571 2588
2572 mask = 0x0000001F; 2589 mask = 0x0000001F;
2573 set = 0x0000000F; 2590 set = 0x0000000F;
2574 if (dev->dev->bus->chip_id == 0x4301) { 2591 if (dev->sdev->bus->chip_id == 0x4301) {
2575 mask |= 0x0060; 2592 mask |= 0x0060;
2576 set |= 0x0060; 2593 set |= 0x0060;
2577 } 2594 }
@@ -2582,25 +2599,21 @@ static int b43_gpio_init(struct b43_wldev *dev)
2582 mask |= 0x0180; 2599 mask |= 0x0180;
2583 set |= 0x0180; 2600 set |= 0x0180;
2584 } 2601 }
2585 if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) { 2602 if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) {
2586 b43_write16(dev, B43_MMIO_GPIO_MASK, 2603 b43_write16(dev, B43_MMIO_GPIO_MASK,
2587 b43_read16(dev, B43_MMIO_GPIO_MASK) 2604 b43_read16(dev, B43_MMIO_GPIO_MASK)
2588 | 0x0200); 2605 | 0x0200);
2589 mask |= 0x0200; 2606 mask |= 0x0200;
2590 set |= 0x0200; 2607 set |= 0x0200;
2591 } 2608 }
2592 if (dev->dev->id.revision >= 2) 2609 if (dev->sdev->id.revision >= 2)
2593 mask |= 0x0010; /* FIXME: This is redundant. */ 2610 mask |= 0x0010; /* FIXME: This is redundant. */
2594 2611
2595#ifdef CONFIG_SSB_DRIVER_PCICORE 2612 gpiodev = b43_ssb_gpio_dev(dev);
2596 pcidev = bus->pcicore.dev; 2613 if (gpiodev)
2597#endif 2614 ssb_write32(gpiodev, B43_GPIO_CONTROL,
2598 gpiodev = bus->chipco.dev ? : pcidev; 2615 (ssb_read32(gpiodev, B43_GPIO_CONTROL)
2599 if (!gpiodev) 2616 & mask) | set);
2600 return 0;
2601 ssb_write32(gpiodev, B43_GPIO_CONTROL,
2602 (ssb_read32(gpiodev, B43_GPIO_CONTROL)
2603 & mask) | set);
2604 2617
2605 return 0; 2618 return 0;
2606} 2619}
@@ -2608,16 +2621,11 @@ static int b43_gpio_init(struct b43_wldev *dev)
2608/* Turn off all GPIO stuff. Call this on module unload, for example. */ 2621/* Turn off all GPIO stuff. Call this on module unload, for example. */
2609static void b43_gpio_cleanup(struct b43_wldev *dev) 2622static void b43_gpio_cleanup(struct b43_wldev *dev)
2610{ 2623{
2611 struct ssb_bus *bus = dev->dev->bus; 2624 struct ssb_device *gpiodev;
2612 struct ssb_device *gpiodev, *pcidev = NULL;
2613 2625
2614#ifdef CONFIG_SSB_DRIVER_PCICORE 2626 gpiodev = b43_ssb_gpio_dev(dev);
2615 pcidev = bus->pcicore.dev; 2627 if (gpiodev)
2616#endif 2628 ssb_write32(gpiodev, B43_GPIO_CONTROL, 0);
2617 gpiodev = bus->chipco.dev ? : pcidev;
2618 if (!gpiodev)
2619 return;
2620 ssb_write32(gpiodev, B43_GPIO_CONTROL, 0);
2621} 2629}
2622 2630
2623/* http://bcm-specs.sipsolutions.net/EnableMac */ 2631/* http://bcm-specs.sipsolutions.net/EnableMac */
@@ -2689,12 +2697,12 @@ out:
2689/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */ 2697/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */
2690void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on) 2698void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on)
2691{ 2699{
2692 u32 tmslow = ssb_read32(dev->dev, SSB_TMSLOW); 2700 u32 tmslow = ssb_read32(dev->sdev, SSB_TMSLOW);
2693 if (on) 2701 if (on)
2694 tmslow |= B43_TMSLOW_MACPHYCLKEN; 2702 tmslow |= B43_TMSLOW_MACPHYCLKEN;
2695 else 2703 else
2696 tmslow &= ~B43_TMSLOW_MACPHYCLKEN; 2704 tmslow &= ~B43_TMSLOW_MACPHYCLKEN;
2697 ssb_write32(dev->dev, SSB_TMSLOW, tmslow); 2705 ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
2698} 2706}
2699 2707
2700static void b43_adjust_opmode(struct b43_wldev *dev) 2708static void b43_adjust_opmode(struct b43_wldev *dev)
@@ -2733,15 +2741,15 @@ static void b43_adjust_opmode(struct b43_wldev *dev)
2733 /* Workaround: On old hardware the HW-MAC-address-filter 2741 /* Workaround: On old hardware the HW-MAC-address-filter
2734 * doesn't work properly, so always run promisc in filter 2742 * doesn't work properly, so always run promisc in filter
2735 * it in software. */ 2743 * it in software. */
2736 if (dev->dev->id.revision <= 4) 2744 if (dev->sdev->id.revision <= 4)
2737 ctl |= B43_MACCTL_PROMISC; 2745 ctl |= B43_MACCTL_PROMISC;
2738 2746
2739 b43_write32(dev, B43_MMIO_MACCTL, ctl); 2747 b43_write32(dev, B43_MMIO_MACCTL, ctl);
2740 2748
2741 cfp_pretbtt = 2; 2749 cfp_pretbtt = 2;
2742 if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) { 2750 if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) {
2743 if (dev->dev->bus->chip_id == 0x4306 && 2751 if (dev->sdev->bus->chip_id == 0x4306 &&
2744 dev->dev->bus->chip_rev == 3) 2752 dev->sdev->bus->chip_rev == 3)
2745 cfp_pretbtt = 100; 2753 cfp_pretbtt = 100;
2746 else 2754 else
2747 cfp_pretbtt = 50; 2755 cfp_pretbtt = 50;
@@ -2899,7 +2907,7 @@ static int b43_chip_init(struct b43_wldev *dev)
2899 b43_write16(dev, 0x005E, value16); 2907 b43_write16(dev, 0x005E, value16);
2900 } 2908 }
2901 b43_write32(dev, 0x0100, 0x01000000); 2909 b43_write32(dev, 0x0100, 0x01000000);
2902 if (dev->dev->id.revision < 5) 2910 if (dev->sdev->id.revision < 5)
2903 b43_write32(dev, 0x010C, 0x01000000); 2911 b43_write32(dev, 0x010C, 0x01000000);
2904 2912
2905 b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) 2913 b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
@@ -2914,7 +2922,7 @@ static int b43_chip_init(struct b43_wldev *dev)
2914 /* Initially set the wireless operation mode. */ 2922 /* Initially set the wireless operation mode. */
2915 b43_adjust_opmode(dev); 2923 b43_adjust_opmode(dev);
2916 2924
2917 if (dev->dev->id.revision < 3) { 2925 if (dev->sdev->id.revision < 3) {
2918 b43_write16(dev, 0x060E, 0x0000); 2926 b43_write16(dev, 0x060E, 0x0000);
2919 b43_write16(dev, 0x0610, 0x8000); 2927 b43_write16(dev, 0x0610, 0x8000);
2920 b43_write16(dev, 0x0604, 0x0000); 2928 b43_write16(dev, 0x0604, 0x0000);
@@ -2934,7 +2942,7 @@ static int b43_chip_init(struct b43_wldev *dev)
2934 b43_mac_phy_clock_set(dev, true); 2942 b43_mac_phy_clock_set(dev, true);
2935 2943
2936 b43_write16(dev, B43_MMIO_POWERUP_DELAY, 2944 b43_write16(dev, B43_MMIO_POWERUP_DELAY,
2937 dev->dev->bus->chipco.fast_pwrup_delay); 2945 dev->sdev->bus->chipco.fast_pwrup_delay);
2938 2946
2939 err = 0; 2947 err = 0;
2940 b43dbg(dev->wl, "Chip initialized\n"); 2948 b43dbg(dev->wl, "Chip initialized\n");
@@ -3097,7 +3105,7 @@ static int b43_validate_chipaccess(struct b43_wldev *dev)
3097 b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0); 3105 b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0);
3098 b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4); 3106 b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4);
3099 3107
3100 if ((dev->dev->id.revision >= 3) && (dev->dev->id.revision <= 10)) { 3108 if ((dev->sdev->id.revision >= 3) && (dev->sdev->id.revision <= 10)) {
3101 /* The 32bit register shadows the two 16bit registers 3109 /* The 32bit register shadows the two 16bit registers
3102 * with update sideeffects. Validate this. */ 3110 * with update sideeffects. Validate this. */
3103 b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA); 3111 b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA);
@@ -3450,7 +3458,7 @@ static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
3450 3458
3451static void b43_put_phy_into_reset(struct b43_wldev *dev) 3459static void b43_put_phy_into_reset(struct b43_wldev *dev)
3452{ 3460{
3453 struct ssb_device *sdev = dev->dev; 3461 struct ssb_device *sdev = dev->sdev;
3454 u32 tmslow; 3462 u32 tmslow;
3455 3463
3456 tmslow = ssb_read32(sdev, SSB_TMSLOW); 3464 tmslow = ssb_read32(sdev, SSB_TMSLOW);
@@ -3946,7 +3954,7 @@ redo:
3946 3954
3947 /* Disable interrupts on the device. */ 3955 /* Disable interrupts on the device. */
3948 b43_set_status(dev, B43_STAT_INITIALIZED); 3956 b43_set_status(dev, B43_STAT_INITIALIZED);
3949 if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) { 3957 if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) {
3950 /* wl->mutex is locked. That is enough. */ 3958 /* wl->mutex is locked. That is enough. */
3951 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); 3959 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
3952 b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */ 3960 b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */
@@ -3959,11 +3967,11 @@ redo:
3959 /* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */ 3967 /* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */
3960 orig_dev = dev; 3968 orig_dev = dev;
3961 mutex_unlock(&wl->mutex); 3969 mutex_unlock(&wl->mutex);
3962 if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) { 3970 if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) {
3963 b43_sdio_free_irq(dev); 3971 b43_sdio_free_irq(dev);
3964 } else { 3972 } else {
3965 synchronize_irq(dev->dev->irq); 3973 synchronize_irq(dev->sdev->irq);
3966 free_irq(dev->dev->irq, dev); 3974 free_irq(dev->sdev->irq, dev);
3967 } 3975 }
3968 mutex_lock(&wl->mutex); 3976 mutex_lock(&wl->mutex);
3969 dev = wl->current_dev; 3977 dev = wl->current_dev;
@@ -3996,18 +4004,19 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
3996 B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED); 4004 B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED);
3997 4005
3998 drain_txstatus_queue(dev); 4006 drain_txstatus_queue(dev);
3999 if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) { 4007 if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) {
4000 err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler); 4008 err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler);
4001 if (err) { 4009 if (err) {
4002 b43err(dev->wl, "Cannot request SDIO IRQ\n"); 4010 b43err(dev->wl, "Cannot request SDIO IRQ\n");
4003 goto out; 4011 goto out;
4004 } 4012 }
4005 } else { 4013 } else {
4006 err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler, 4014 err = request_threaded_irq(dev->sdev->irq, b43_interrupt_handler,
4007 b43_interrupt_thread_handler, 4015 b43_interrupt_thread_handler,
4008 IRQF_SHARED, KBUILD_MODNAME, dev); 4016 IRQF_SHARED, KBUILD_MODNAME, dev);
4009 if (err) { 4017 if (err) {
4010 b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq); 4018 b43err(dev->wl, "Cannot request IRQ-%d\n",
4019 dev->sdev->irq);
4011 goto out; 4020 goto out;
4012 } 4021 }
4013 } 4022 }
@@ -4087,10 +4096,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4087 analog_type, phy_type, phy_rev); 4096 analog_type, phy_type, phy_rev);
4088 4097
4089 /* Get RADIO versioning */ 4098 /* Get RADIO versioning */
4090 if (dev->dev->bus->chip_id == 0x4317) { 4099 if (dev->sdev->bus->chip_id == 0x4317) {
4091 if (dev->dev->bus->chip_rev == 0) 4100 if (dev->sdev->bus->chip_rev == 0)
4092 tmp = 0x3205017F; 4101 tmp = 0x3205017F;
4093 else if (dev->dev->bus->chip_rev == 1) 4102 else if (dev->sdev->bus->chip_rev == 1)
4094 tmp = 0x4205017F; 4103 tmp = 0x4205017F;
4095 else 4104 else
4096 tmp = 0x5205017F; 4105 tmp = 0x5205017F;
@@ -4195,7 +4204,7 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev)
4195 4204
4196static void b43_bluetooth_coext_enable(struct b43_wldev *dev) 4205static void b43_bluetooth_coext_enable(struct b43_wldev *dev)
4197{ 4206{
4198 struct ssb_sprom *sprom = &dev->dev->bus->sprom; 4207 struct ssb_sprom *sprom = &dev->sdev->bus->sprom;
4199 u64 hf; 4208 u64 hf;
4200 4209
4201 if (!modparam_btcoex) 4210 if (!modparam_btcoex)
@@ -4222,16 +4231,16 @@ static void b43_bluetooth_coext_disable(struct b43_wldev *dev)
4222 4231
4223static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev) 4232static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev)
4224{ 4233{
4225 struct ssb_bus *bus = dev->dev->bus; 4234 struct ssb_bus *bus = dev->sdev->bus;
4226 u32 tmp; 4235 u32 tmp;
4227 4236
4228 if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) || 4237 if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) ||
4229 (bus->chip_id == 0x4312)) { 4238 (bus->chip_id == 0x4312)) {
4230 tmp = ssb_read32(dev->dev, SSB_IMCFGLO); 4239 tmp = ssb_read32(dev->sdev, SSB_IMCFGLO);
4231 tmp &= ~SSB_IMCFGLO_REQTO; 4240 tmp &= ~SSB_IMCFGLO_REQTO;
4232 tmp &= ~SSB_IMCFGLO_SERTO; 4241 tmp &= ~SSB_IMCFGLO_SERTO;
4233 tmp |= 0x3; 4242 tmp |= 0x3;
4234 ssb_write32(dev->dev, SSB_IMCFGLO, tmp); 4243 ssb_write32(dev->sdev, SSB_IMCFGLO, tmp);
4235 ssb_commit_settings(bus); 4244 ssb_commit_settings(bus);
4236 } 4245 }
4237} 4246}
@@ -4301,14 +4310,14 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
4301 dev->wl->current_beacon = NULL; 4310 dev->wl->current_beacon = NULL;
4302 } 4311 }
4303 4312
4304 ssb_device_disable(dev->dev, 0); 4313 ssb_device_disable(dev->sdev, 0);
4305 ssb_bus_may_powerdown(dev->dev->bus); 4314 ssb_bus_may_powerdown(dev->sdev->bus);
4306} 4315}
4307 4316
4308/* Initialize a wireless core */ 4317/* Initialize a wireless core */
4309static int b43_wireless_core_init(struct b43_wldev *dev) 4318static int b43_wireless_core_init(struct b43_wldev *dev)
4310{ 4319{
4311 struct ssb_bus *bus = dev->dev->bus; 4320 struct ssb_bus *bus = dev->sdev->bus;
4312 struct ssb_sprom *sprom = &bus->sprom; 4321 struct ssb_sprom *sprom = &bus->sprom;
4313 struct b43_phy *phy = &dev->phy; 4322 struct b43_phy *phy = &dev->phy;
4314 int err; 4323 int err;
@@ -4320,7 +4329,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4320 err = ssb_bus_powerup(bus, 0); 4329 err = ssb_bus_powerup(bus, 0);
4321 if (err) 4330 if (err)
4322 goto out; 4331 goto out;
4323 if (!ssb_device_is_enabled(dev->dev)) { 4332 if (!ssb_device_is_enabled(dev->sdev)) {
4324 tmp = phy->gmode ? B43_TMSLOW_GMODE : 0; 4333 tmp = phy->gmode ? B43_TMSLOW_GMODE : 0;
4325 b43_wireless_core_reset(dev, tmp); 4334 b43_wireless_core_reset(dev, tmp);
4326 } 4335 }
@@ -4330,7 +4339,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4330 phy->ops->prepare_structs(dev); 4339 phy->ops->prepare_structs(dev);
4331 4340
4332 /* Enable IRQ routing to this device. */ 4341 /* Enable IRQ routing to this device. */
4333 ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev); 4342 ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->sdev);
4334 4343
4335 b43_imcfglo_timeouts_workaround(dev); 4344 b43_imcfglo_timeouts_workaround(dev);
4336 b43_bluetooth_coext_disable(dev); 4345 b43_bluetooth_coext_disable(dev);
@@ -4343,7 +4352,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4343 if (err) 4352 if (err)
4344 goto err_busdown; 4353 goto err_busdown;
4345 b43_shm_write16(dev, B43_SHM_SHARED, 4354 b43_shm_write16(dev, B43_SHM_SHARED,
4346 B43_SHM_SH_WLCOREREV, dev->dev->id.revision); 4355 B43_SHM_SH_WLCOREREV, dev->sdev->id.revision);
4347 hf = b43_hf_read(dev); 4356 hf = b43_hf_read(dev);
4348 if (phy->type == B43_PHYTYPE_G) { 4357 if (phy->type == B43_PHYTYPE_G) {
4349 hf |= B43_HF_SYMW; 4358 hf |= B43_HF_SYMW;
@@ -4390,8 +4399,8 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4390 /* Maximum Contention Window */ 4399 /* Maximum Contention Window */
4391 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); 4400 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
4392 4401
4393 if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) || 4402 if ((dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA) ||
4394 (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) || 4403 (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) ||
4395 dev->use_pio) { 4404 dev->use_pio) {
4396 dev->__using_pio_transfers = 1; 4405 dev->__using_pio_transfers = 1;
4397 err = b43_pio_init(dev); 4406 err = b43_pio_init(dev);
@@ -4728,7 +4737,7 @@ static void b43_wireless_core_detach(struct b43_wldev *dev)
4728static int b43_wireless_core_attach(struct b43_wldev *dev) 4737static int b43_wireless_core_attach(struct b43_wldev *dev)
4729{ 4738{
4730 struct b43_wl *wl = dev->wl; 4739 struct b43_wl *wl = dev->wl;
4731 struct ssb_bus *bus = dev->dev->bus; 4740 struct ssb_bus *bus = dev->sdev->bus;
4732 struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL; 4741 struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL;
4733 int err; 4742 int err;
4734 bool have_2ghz_phy = 0, have_5ghz_phy = 0; 4743 bool have_2ghz_phy = 0, have_5ghz_phy = 0;
@@ -4747,10 +4756,10 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
4747 goto out; 4756 goto out;
4748 } 4757 }
4749 /* Get the PHY type. */ 4758 /* Get the PHY type. */
4750 if (dev->dev->id.revision >= 5) { 4759 if (dev->sdev->id.revision >= 5) {
4751 u32 tmshigh; 4760 u32 tmshigh;
4752 4761
4753 tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH); 4762 tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH);
4754 have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY); 4763 have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY);
4755 have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY); 4764 have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY);
4756 } else 4765 } else
@@ -4823,7 +4832,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
4823 INIT_WORK(&dev->restart_work, b43_chip_reset); 4832 INIT_WORK(&dev->restart_work, b43_chip_reset);
4824 4833
4825 dev->phy.ops->switch_analog(dev, 0); 4834 dev->phy.ops->switch_analog(dev, 0);
4826 ssb_device_disable(dev->dev, 0); 4835 ssb_device_disable(dev->sdev, 0);
4827 ssb_bus_may_powerdown(bus); 4836 ssb_bus_may_powerdown(bus);
4828 4837
4829out: 4838out:
@@ -4864,7 +4873,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)
4864 goto out; 4873 goto out;
4865 4874
4866 wldev->use_pio = b43_modparam_pio; 4875 wldev->use_pio = b43_modparam_pio;
4867 wldev->dev = dev; 4876 wldev->sdev = dev;
4868 wldev->wl = wl; 4877 wldev->wl = wl;
4869 b43_set_status(wldev, B43_STAT_UNINIT); 4878 b43_set_status(wldev, B43_STAT_UNINIT);
4870 wldev->bad_frames_preempt = modparam_bad_frames_preempt; 4879 wldev->bad_frames_preempt = modparam_bad_frames_preempt;
@@ -4925,19 +4934,16 @@ static void b43_wireless_exit(struct ssb_device *dev, struct b43_wl *wl)
4925 ieee80211_free_hw(hw); 4934 ieee80211_free_hw(hw);
4926} 4935}
4927 4936
4928static int b43_wireless_init(struct ssb_device *dev) 4937static struct b43_wl *b43_wireless_init(struct ssb_device *dev)
4929{ 4938{
4930 struct ssb_sprom *sprom = &dev->bus->sprom; 4939 struct ssb_sprom *sprom = &dev->bus->sprom;
4931 struct ieee80211_hw *hw; 4940 struct ieee80211_hw *hw;
4932 struct b43_wl *wl; 4941 struct b43_wl *wl;
4933 int err = -ENOMEM;
4934
4935 b43_sprom_fixup(dev->bus);
4936 4942
4937 hw = ieee80211_alloc_hw(sizeof(*wl), &b43_hw_ops); 4943 hw = ieee80211_alloc_hw(sizeof(*wl), &b43_hw_ops);
4938 if (!hw) { 4944 if (!hw) {
4939 b43err(NULL, "Could not allocate ieee80211 device\n"); 4945 b43err(NULL, "Could not allocate ieee80211 device\n");
4940 goto out; 4946 return ERR_PTR(-ENOMEM);
4941 } 4947 }
4942 wl = hw_to_b43_wl(hw); 4948 wl = hw_to_b43_wl(hw);
4943 4949
@@ -4971,12 +4977,9 @@ static int b43_wireless_init(struct ssb_device *dev)
4971 INIT_WORK(&wl->tx_work, b43_tx_work); 4977 INIT_WORK(&wl->tx_work, b43_tx_work);
4972 skb_queue_head_init(&wl->tx_queue); 4978 skb_queue_head_init(&wl->tx_queue);
4973 4979
4974 ssb_set_devtypedata(dev, wl);
4975 b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n", 4980 b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n",
4976 dev->bus->chip_id, dev->id.revision); 4981 dev->bus->chip_id, dev->id.revision);
4977 err = 0; 4982 return wl;
4978out:
4979 return err;
4980} 4983}
4981 4984
4982static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id) 4985static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id)
@@ -4989,11 +4992,14 @@ static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id)
4989 if (!wl) { 4992 if (!wl) {
4990 /* Probing the first core. Must setup common struct b43_wl */ 4993 /* Probing the first core. Must setup common struct b43_wl */
4991 first = 1; 4994 first = 1;
4992 err = b43_wireless_init(dev); 4995 b43_sprom_fixup(dev->bus);
4993 if (err) 4996 wl = b43_wireless_init(dev);
4997 if (IS_ERR(wl)) {
4998 err = PTR_ERR(wl);
4994 goto out; 4999 goto out;
4995 wl = ssb_get_devtypedata(dev); 5000 }
4996 B43_WARN_ON(!wl); 5001 ssb_set_devtypedata(dev, wl);
5002 B43_WARN_ON(ssb_get_devtypedata(dev) != wl);
4997 } 5003 }
4998 err = b43_one_core_attach(dev, wl); 5004 err = b43_one_core_attach(dev, wl);
4999 if (err) 5005 if (err)
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index b6428ec16dd6..b01c8ced57c3 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -265,7 +265,7 @@ static void hardware_pctl_init_aphy(struct b43_wldev *dev)
265 265
266void b43_phy_inita(struct b43_wldev *dev) 266void b43_phy_inita(struct b43_wldev *dev)
267{ 267{
268 struct ssb_bus *bus = dev->dev->bus; 268 struct ssb_bus *bus = dev->sdev->bus;
269 struct b43_phy *phy = &dev->phy; 269 struct b43_phy *phy = &dev->phy;
270 270
271 /* This lowlevel A-PHY init is also called from G-PHY init. 271 /* This lowlevel A-PHY init is also called from G-PHY init.
@@ -311,7 +311,7 @@ void b43_phy_inita(struct b43_wldev *dev)
311 } 311 }
312 312
313 if ((phy->type == B43_PHYTYPE_G) && 313 if ((phy->type == B43_PHYTYPE_G) &&
314 (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) { 314 (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) {
315 b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF); 315 b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF);
316 } 316 }
317} 317}
@@ -323,17 +323,17 @@ static int b43_aphy_init_tssi2dbm_table(struct b43_wldev *dev)
323 struct b43_phy_a *aphy = phy->a; 323 struct b43_phy_a *aphy = phy->a;
324 s16 pab0, pab1, pab2; 324 s16 pab0, pab1, pab2;
325 325
326 pab0 = (s16) (dev->dev->bus->sprom.pa1b0); 326 pab0 = (s16) (dev->sdev->bus->sprom.pa1b0);
327 pab1 = (s16) (dev->dev->bus->sprom.pa1b1); 327 pab1 = (s16) (dev->sdev->bus->sprom.pa1b1);
328 pab2 = (s16) (dev->dev->bus->sprom.pa1b2); 328 pab2 = (s16) (dev->sdev->bus->sprom.pa1b2);
329 329
330 if (pab0 != 0 && pab1 != 0 && pab2 != 0 && 330 if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
331 pab0 != -1 && pab1 != -1 && pab2 != -1) { 331 pab0 != -1 && pab1 != -1 && pab2 != -1) {
332 /* The pabX values are set in SPROM. Use them. */ 332 /* The pabX values are set in SPROM. Use them. */
333 if ((s8) dev->dev->bus->sprom.itssi_a != 0 && 333 if ((s8) dev->sdev->bus->sprom.itssi_a != 0 &&
334 (s8) dev->dev->bus->sprom.itssi_a != -1) 334 (s8) dev->sdev->bus->sprom.itssi_a != -1)
335 aphy->tgt_idle_tssi = 335 aphy->tgt_idle_tssi =
336 (s8) (dev->dev->bus->sprom.itssi_a); 336 (s8) (dev->sdev->bus->sprom.itssi_a);
337 else 337 else
338 aphy->tgt_idle_tssi = 62; 338 aphy->tgt_idle_tssi = 62;
339 aphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0, 339 aphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0,
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index b5c5ce94d3fd..e46b2f4f0920 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -168,7 +168,7 @@ void b43_phy_lock(struct b43_wldev *dev)
168 B43_WARN_ON(dev->phy.phy_locked); 168 B43_WARN_ON(dev->phy.phy_locked);
169 dev->phy.phy_locked = 1; 169 dev->phy.phy_locked = 1;
170#endif 170#endif
171 B43_WARN_ON(dev->dev->id.revision < 3); 171 B43_WARN_ON(dev->sdev->id.revision < 3);
172 172
173 if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) 173 if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP))
174 b43_power_saving_ctl_bits(dev, B43_PS_AWAKE); 174 b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
@@ -180,7 +180,7 @@ void b43_phy_unlock(struct b43_wldev *dev)
180 B43_WARN_ON(!dev->phy.phy_locked); 180 B43_WARN_ON(!dev->phy.phy_locked);
181 dev->phy.phy_locked = 0; 181 dev->phy.phy_locked = 0;
182#endif 182#endif
183 B43_WARN_ON(dev->dev->id.revision < 3); 183 B43_WARN_ON(dev->sdev->id.revision < 3);
184 184
185 if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) 185 if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP))
186 b43_power_saving_ctl_bits(dev, 0); 186 b43_power_saving_ctl_bits(dev, 0);
@@ -368,8 +368,8 @@ void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags)
368 /* The next check will be needed in two seconds, or later. */ 368 /* The next check will be needed in two seconds, or later. */
369 phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2)); 369 phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2));
370 370
371 if ((dev->dev->bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && 371 if ((dev->sdev->bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
372 (dev->dev->bus->boardinfo.type == SSB_BOARD_BU4306)) 372 (dev->sdev->bus->boardinfo.type == SSB_BOARD_BU4306))
373 return; /* No software txpower adjustment needed */ 373 return; /* No software txpower adjustment needed */
374 374
375 result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI)); 375 result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI));
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index be4828167012..1758a282f913 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -718,7 +718,7 @@ static void b43_calc_nrssi_threshold(struct b43_wldev *dev)
718 B43_WARN_ON(phy->type != B43_PHYTYPE_G); 718 B43_WARN_ON(phy->type != B43_PHYTYPE_G);
719 719
720 if (!phy->gmode || 720 if (!phy->gmode ||
721 !(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { 721 !(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
722 tmp16 = b43_nrssi_hw_read(dev, 0x20); 722 tmp16 = b43_nrssi_hw_read(dev, 0x20);
723 if (tmp16 >= 0x20) 723 if (tmp16 >= 0x20)
724 tmp16 -= 0x40; 724 tmp16 -= 0x40;
@@ -1114,7 +1114,7 @@ static u16 radio2050_rfover_val(struct b43_wldev *dev,
1114{ 1114{
1115 struct b43_phy *phy = &dev->phy; 1115 struct b43_phy *phy = &dev->phy;
1116 struct b43_phy_g *gphy = phy->g; 1116 struct b43_phy_g *gphy = phy->g;
1117 struct ssb_sprom *sprom = &(dev->dev->bus->sprom); 1117 struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
1118 1118
1119 if (!phy->gmode) 1119 if (!phy->gmode)
1120 return 0; 1120 return 0;
@@ -1491,7 +1491,7 @@ static u16 b43_radio_init2050(struct b43_wldev *dev)
1491 1491
1492static void b43_phy_initb5(struct b43_wldev *dev) 1492static void b43_phy_initb5(struct b43_wldev *dev)
1493{ 1493{
1494 struct ssb_bus *bus = dev->dev->bus; 1494 struct ssb_bus *bus = dev->sdev->bus;
1495 struct b43_phy *phy = &dev->phy; 1495 struct b43_phy *phy = &dev->phy;
1496 struct b43_phy_g *gphy = phy->g; 1496 struct b43_phy_g *gphy = phy->g;
1497 u16 offset, value; 1497 u16 offset, value;
@@ -1620,7 +1620,7 @@ static void b43_phy_initb6(struct b43_wldev *dev)
1620 b43_radio_write16(dev, 0x5A, 0x88); 1620 b43_radio_write16(dev, 0x5A, 0x88);
1621 b43_radio_write16(dev, 0x5B, 0x6B); 1621 b43_radio_write16(dev, 0x5B, 0x6B);
1622 b43_radio_write16(dev, 0x5C, 0x0F); 1622 b43_radio_write16(dev, 0x5C, 0x0F);
1623 if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) { 1623 if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) {
1624 b43_radio_write16(dev, 0x5D, 0xFA); 1624 b43_radio_write16(dev, 0x5D, 0xFA);
1625 b43_radio_write16(dev, 0x5E, 0xD8); 1625 b43_radio_write16(dev, 0x5E, 0xD8);
1626 } else { 1626 } else {
@@ -1787,7 +1787,7 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev)
1787 b43_phy_set(dev, B43_PHY_RFOVER, 0x0100); 1787 b43_phy_set(dev, B43_PHY_RFOVER, 0x0100);
1788 b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xCFFF); 1788 b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xCFFF);
1789 1789
1790 if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) { 1790 if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) {
1791 if (phy->rev >= 7) { 1791 if (phy->rev >= 7) {
1792 b43_phy_set(dev, B43_PHY_RFOVER, 0x0800); 1792 b43_phy_set(dev, B43_PHY_RFOVER, 0x0800);
1793 b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x8000); 1793 b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x8000);
@@ -1922,7 +1922,7 @@ static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev)
1922/* Initialize B/G PHY power control */ 1922/* Initialize B/G PHY power control */
1923static void b43_phy_init_pctl(struct b43_wldev *dev) 1923static void b43_phy_init_pctl(struct b43_wldev *dev)
1924{ 1924{
1925 struct ssb_bus *bus = dev->dev->bus; 1925 struct ssb_bus *bus = dev->sdev->bus;
1926 struct b43_phy *phy = &dev->phy; 1926 struct b43_phy *phy = &dev->phy;
1927 struct b43_phy_g *gphy = phy->g; 1927 struct b43_phy_g *gphy = phy->g;
1928 struct b43_rfatt old_rfatt; 1928 struct b43_rfatt old_rfatt;
@@ -2053,7 +2053,7 @@ static void b43_phy_initg(struct b43_wldev *dev)
2053 if (phy->rev >= 6) { 2053 if (phy->rev >= 6) {
2054 b43_phy_maskset(dev, B43_PHY_CCK(0x36), 0x0FFF, (gphy->lo_control->tx_bias << 12)); 2054 b43_phy_maskset(dev, B43_PHY_CCK(0x36), 0x0FFF, (gphy->lo_control->tx_bias << 12));
2055 } 2055 }
2056 if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) 2056 if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
2057 b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075); 2057 b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075);
2058 else 2058 else
2059 b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F); 2059 b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F);
@@ -2066,7 +2066,7 @@ static void b43_phy_initg(struct b43_wldev *dev)
2066 b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078); 2066 b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078);
2067 } 2067 }
2068 2068
2069 if (!(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { 2069 if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
2070 /* The specs state to update the NRSSI LT with 2070 /* The specs state to update the NRSSI LT with
2071 * the value 0x7FFFFFFF here. I think that is some weird 2071 * the value 0x7FFFFFFF here. I think that is some weird
2072 * compiler optimization in the original driver. 2072 * compiler optimization in the original driver.
@@ -2088,8 +2088,8 @@ static void b43_phy_initg(struct b43_wldev *dev)
2088 /* FIXME: The spec says in the following if, the 0 should be replaced 2088 /* FIXME: The spec says in the following if, the 0 should be replaced
2089 'if OFDM may not be used in the current locale' 2089 'if OFDM may not be used in the current locale'
2090 but OFDM is legal everywhere */ 2090 but OFDM is legal everywhere */
2091 if ((dev->dev->bus->chip_id == 0x4306 2091 if ((dev->sdev->bus->chip_id == 0x4306
2092 && dev->dev->bus->chip_package == 2) || 0) { 2092 && dev->sdev->bus->chip_package == 2) || 0) {
2093 b43_phy_mask(dev, B43_PHY_CRS0, 0xBFFF); 2093 b43_phy_mask(dev, B43_PHY_CRS0, 0xBFFF);
2094 b43_phy_mask(dev, B43_PHY_OFDM(0xC3), 0x7FFF); 2094 b43_phy_mask(dev, B43_PHY_OFDM(0xC3), 0x7FFF);
2095 } 2095 }
@@ -2105,7 +2105,7 @@ void b43_gphy_channel_switch(struct b43_wldev *dev,
2105 b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel)); 2105 b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel));
2106 2106
2107 if (channel == 14) { 2107 if (channel == 14) {
2108 if (dev->dev->bus->sprom.country_code == 2108 if (dev->sdev->bus->sprom.country_code ==
2109 SSB_SPROM1CCODE_JAPAN) 2109 SSB_SPROM1CCODE_JAPAN)
2110 b43_hf_write(dev, 2110 b43_hf_write(dev,
2111 b43_hf_read(dev) & ~B43_HF_ACPR); 2111 b43_hf_read(dev) & ~B43_HF_ACPR);
@@ -2136,7 +2136,7 @@ static void default_baseband_attenuation(struct b43_wldev *dev,
2136static void default_radio_attenuation(struct b43_wldev *dev, 2136static void default_radio_attenuation(struct b43_wldev *dev,
2137 struct b43_rfatt *rf) 2137 struct b43_rfatt *rf)
2138{ 2138{
2139 struct ssb_bus *bus = dev->dev->bus; 2139 struct ssb_bus *bus = dev->sdev->bus;
2140 struct b43_phy *phy = &dev->phy; 2140 struct b43_phy *phy = &dev->phy;
2141 2141
2142 rf->with_padmix = 0; 2142 rf->with_padmix = 0;
@@ -2384,11 +2384,11 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev)
2384 struct b43_phy_g *gphy = phy->g; 2384 struct b43_phy_g *gphy = phy->g;
2385 s16 pab0, pab1, pab2; 2385 s16 pab0, pab1, pab2;
2386 2386
2387 pab0 = (s16) (dev->dev->bus->sprom.pa0b0); 2387 pab0 = (s16) (dev->sdev->bus->sprom.pa0b0);
2388 pab1 = (s16) (dev->dev->bus->sprom.pa0b1); 2388 pab1 = (s16) (dev->sdev->bus->sprom.pa0b1);
2389 pab2 = (s16) (dev->dev->bus->sprom.pa0b2); 2389 pab2 = (s16) (dev->sdev->bus->sprom.pa0b2);
2390 2390
2391 B43_WARN_ON((dev->dev->bus->chip_id == 0x4301) && 2391 B43_WARN_ON((dev->sdev->bus->chip_id == 0x4301) &&
2392 (phy->radio_ver != 0x2050)); /* Not supported anymore */ 2392 (phy->radio_ver != 0x2050)); /* Not supported anymore */
2393 2393
2394 gphy->dyn_tssi_tbl = 0; 2394 gphy->dyn_tssi_tbl = 0;
@@ -2396,10 +2396,10 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev)
2396 if (pab0 != 0 && pab1 != 0 && pab2 != 0 && 2396 if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
2397 pab0 != -1 && pab1 != -1 && pab2 != -1) { 2397 pab0 != -1 && pab1 != -1 && pab2 != -1) {
2398 /* The pabX values are set in SPROM. Use them. */ 2398 /* The pabX values are set in SPROM. Use them. */
2399 if ((s8) dev->dev->bus->sprom.itssi_bg != 0 && 2399 if ((s8) dev->sdev->bus->sprom.itssi_bg != 0 &&
2400 (s8) dev->dev->bus->sprom.itssi_bg != -1) { 2400 (s8) dev->sdev->bus->sprom.itssi_bg != -1) {
2401 gphy->tgt_idle_tssi = 2401 gphy->tgt_idle_tssi =
2402 (s8) (dev->dev->bus->sprom.itssi_bg); 2402 (s8) (dev->sdev->bus->sprom.itssi_bg);
2403 } else 2403 } else
2404 gphy->tgt_idle_tssi = 62; 2404 gphy->tgt_idle_tssi = 62;
2405 gphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0, 2405 gphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0,
@@ -2840,7 +2840,7 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev)
2840 B43_TXCTL_TXMIX; 2840 B43_TXCTL_TXMIX;
2841 rfatt += 2; 2841 rfatt += 2;
2842 bbatt += 2; 2842 bbatt += 2;
2843 } else if (dev->dev->bus->sprom. 2843 } else if (dev->sdev->bus->sprom.
2844 boardflags_lo & 2844 boardflags_lo &
2845 B43_BFL_PACTRL) { 2845 B43_BFL_PACTRL) {
2846 bbatt += 4 * (rfatt - 2); 2846 bbatt += 4 * (rfatt - 2);
@@ -2914,14 +2914,14 @@ static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev,
2914 estimated_pwr = b43_gphy_estimate_power_out(dev, average_tssi); 2914 estimated_pwr = b43_gphy_estimate_power_out(dev, average_tssi);
2915 2915
2916 B43_WARN_ON(phy->type != B43_PHYTYPE_G); 2916 B43_WARN_ON(phy->type != B43_PHYTYPE_G);
2917 max_pwr = dev->dev->bus->sprom.maxpwr_bg; 2917 max_pwr = dev->sdev->bus->sprom.maxpwr_bg;
2918 if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) 2918 if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
2919 max_pwr -= 3; /* minus 0.75 */ 2919 max_pwr -= 3; /* minus 0.75 */
2920 if (unlikely(max_pwr >= INT_TO_Q52(30/*dBm*/))) { 2920 if (unlikely(max_pwr >= INT_TO_Q52(30/*dBm*/))) {
2921 b43warn(dev->wl, 2921 b43warn(dev->wl,
2922 "Invalid max-TX-power value in SPROM.\n"); 2922 "Invalid max-TX-power value in SPROM.\n");
2923 max_pwr = INT_TO_Q52(20); /* fake it */ 2923 max_pwr = INT_TO_Q52(20); /* fake it */
2924 dev->dev->bus->sprom.maxpwr_bg = max_pwr; 2924 dev->sdev->bus->sprom.maxpwr_bg = max_pwr;
2925 } 2925 }
2926 2926
2927 /* Get desired power (in Q5.2) */ 2927 /* Get desired power (in Q5.2) */
@@ -3014,7 +3014,7 @@ static void b43_gphy_op_pwork_60sec(struct b43_wldev *dev)
3014{ 3014{
3015 struct b43_phy *phy = &dev->phy; 3015 struct b43_phy *phy = &dev->phy;
3016 3016
3017 if (!(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) 3017 if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI))
3018 return; 3018 return;
3019 3019
3020 b43_mac_suspend(dev); 3020 b43_mac_suspend(dev);
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index fd50eb116243..012c8da2f944 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -86,7 +86,7 @@ static void b43_lpphy_op_free(struct b43_wldev *dev)
86static void lpphy_read_band_sprom(struct b43_wldev *dev) 86static void lpphy_read_band_sprom(struct b43_wldev *dev)
87{ 87{
88 struct b43_phy_lp *lpphy = dev->phy.lp; 88 struct b43_phy_lp *lpphy = dev->phy.lp;
89 struct ssb_bus *bus = dev->dev->bus; 89 struct ssb_bus *bus = dev->sdev->bus;
90 u16 cckpo, maxpwr; 90 u16 cckpo, maxpwr;
91 u32 ofdmpo; 91 u32 ofdmpo;
92 int i; 92 int i;
@@ -214,7 +214,7 @@ static void lpphy_table_init(struct b43_wldev *dev)
214 214
215static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) 215static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
216{ 216{
217 struct ssb_bus *bus = dev->dev->bus; 217 struct ssb_bus *bus = dev->sdev->bus;
218 struct b43_phy_lp *lpphy = dev->phy.lp; 218 struct b43_phy_lp *lpphy = dev->phy.lp;
219 u16 tmp, tmp2; 219 u16 tmp, tmp2;
220 220
@@ -412,7 +412,7 @@ static void lpphy_restore_dig_flt_state(struct b43_wldev *dev)
412 412
413static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) 413static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
414{ 414{
415 struct ssb_bus *bus = dev->dev->bus; 415 struct ssb_bus *bus = dev->sdev->bus;
416 struct b43_phy_lp *lpphy = dev->phy.lp; 416 struct b43_phy_lp *lpphy = dev->phy.lp;
417 417
418 b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50); 418 b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50);
@@ -519,7 +519,7 @@ struct b2062_freqdata {
519static void lpphy_2062_init(struct b43_wldev *dev) 519static void lpphy_2062_init(struct b43_wldev *dev)
520{ 520{
521 struct b43_phy_lp *lpphy = dev->phy.lp; 521 struct b43_phy_lp *lpphy = dev->phy.lp;
522 struct ssb_bus *bus = dev->dev->bus; 522 struct ssb_bus *bus = dev->sdev->bus;
523 u32 crystalfreq, tmp, ref; 523 u32 crystalfreq, tmp, ref;
524 unsigned int i; 524 unsigned int i;
525 const struct b2062_freqdata *fd = NULL; 525 const struct b2062_freqdata *fd = NULL;
@@ -697,7 +697,7 @@ static void lpphy_radio_init(struct b43_wldev *dev)
697 lpphy_sync_stx(dev); 697 lpphy_sync_stx(dev);
698 b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80); 698 b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80);
699 b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0); 699 b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0);
700 if (dev->dev->bus->chip_id == 0x4325) { 700 if (dev->sdev->bus->chip_id == 0x4325) {
701 // TODO SSB PMU recalibration 701 // TODO SSB PMU recalibration
702 } 702 }
703 } 703 }
@@ -1289,7 +1289,7 @@ finish:
1289 1289
1290static void lpphy_rev2plus_rc_calib(struct b43_wldev *dev) 1290static void lpphy_rev2plus_rc_calib(struct b43_wldev *dev)
1291{ 1291{
1292 struct ssb_bus *bus = dev->dev->bus; 1292 struct ssb_bus *bus = dev->sdev->bus;
1293 u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; 1293 u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
1294 u8 tmp = b43_radio_read(dev, B2063_RX_BB_SP8) & 0xFF; 1294 u8 tmp = b43_radio_read(dev, B2063_RX_BB_SP8) & 0xFF;
1295 int i; 1295 int i;
@@ -1840,7 +1840,7 @@ static void lpphy_papd_cal(struct b43_wldev *dev, struct lpphy_tx_gains gains,
1840static void lpphy_papd_cal_txpwr(struct b43_wldev *dev) 1840static void lpphy_papd_cal_txpwr(struct b43_wldev *dev)
1841{ 1841{
1842 struct b43_phy_lp *lpphy = dev->phy.lp; 1842 struct b43_phy_lp *lpphy = dev->phy.lp;
1843 struct ssb_bus *bus = dev->dev->bus; 1843 struct ssb_bus *bus = dev->sdev->bus;
1844 struct lpphy_tx_gains gains, oldgains; 1844 struct lpphy_tx_gains gains, oldgains;
1845 int old_txpctl, old_afe_ovr, old_rf, old_bbmult; 1845 int old_txpctl, old_afe_ovr, old_rf, old_bbmult;
1846 1846
@@ -1870,7 +1870,7 @@ static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx,
1870 bool rx, bool pa, struct lpphy_tx_gains *gains) 1870 bool rx, bool pa, struct lpphy_tx_gains *gains)
1871{ 1871{
1872 struct b43_phy_lp *lpphy = dev->phy.lp; 1872 struct b43_phy_lp *lpphy = dev->phy.lp;
1873 struct ssb_bus *bus = dev->dev->bus; 1873 struct ssb_bus *bus = dev->sdev->bus;
1874 const struct lpphy_rx_iq_comp *iqcomp = NULL; 1874 const struct lpphy_rx_iq_comp *iqcomp = NULL;
1875 struct lpphy_tx_gains nogains, oldgains; 1875 struct lpphy_tx_gains nogains, oldgains;
1876 u16 tmp; 1876 u16 tmp;
@@ -2408,7 +2408,7 @@ static const struct b206x_channel b2063_chantbl[] = {
2408 2408
2409static void lpphy_b2062_reset_pll_bias(struct b43_wldev *dev) 2409static void lpphy_b2062_reset_pll_bias(struct b43_wldev *dev)
2410{ 2410{
2411 struct ssb_bus *bus = dev->dev->bus; 2411 struct ssb_bus *bus = dev->sdev->bus;
2412 2412
2413 b43_radio_write(dev, B2062_S_RFPLL_CTL2, 0xFF); 2413 b43_radio_write(dev, B2062_S_RFPLL_CTL2, 0xFF);
2414 udelay(20); 2414 udelay(20);
@@ -2432,7 +2432,7 @@ static int lpphy_b2062_tune(struct b43_wldev *dev,
2432 unsigned int channel) 2432 unsigned int channel)
2433{ 2433{
2434 struct b43_phy_lp *lpphy = dev->phy.lp; 2434 struct b43_phy_lp *lpphy = dev->phy.lp;
2435 struct ssb_bus *bus = dev->dev->bus; 2435 struct ssb_bus *bus = dev->sdev->bus;
2436 const struct b206x_channel *chandata = NULL; 2436 const struct b206x_channel *chandata = NULL;
2437 u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; 2437 u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
2438 u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; 2438 u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9;
@@ -2522,7 +2522,7 @@ static void lpphy_b2063_vco_calib(struct b43_wldev *dev)
2522static int lpphy_b2063_tune(struct b43_wldev *dev, 2522static int lpphy_b2063_tune(struct b43_wldev *dev,
2523 unsigned int channel) 2523 unsigned int channel)
2524{ 2524{
2525 struct ssb_bus *bus = dev->dev->bus; 2525 struct ssb_bus *bus = dev->sdev->bus;
2526 2526
2527 static const struct b206x_channel *chandata = NULL; 2527 static const struct b206x_channel *chandata = NULL;
2528 u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; 2528 u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index b075a3f82a43..9ed65157bef5 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -299,7 +299,7 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
299static void b43_nphy_tx_power_fix(struct b43_wldev *dev) 299static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
300{ 300{
301 struct b43_phy_n *nphy = dev->phy.n; 301 struct b43_phy_n *nphy = dev->phy.n;
302 struct ssb_sprom *sprom = &(dev->dev->bus->sprom); 302 struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
303 303
304 u8 txpi[2], bbmult, i; 304 u8 txpi[2], bbmult, i;
305 u16 tmp, radio_gain, dac_gain; 305 u16 tmp, radio_gain, dac_gain;
@@ -423,8 +423,8 @@ static void b43_radio_init2055_pre(struct b43_wldev *dev)
423static void b43_radio_init2055_post(struct b43_wldev *dev) 423static void b43_radio_init2055_post(struct b43_wldev *dev)
424{ 424{
425 struct b43_phy_n *nphy = dev->phy.n; 425 struct b43_phy_n *nphy = dev->phy.n;
426 struct ssb_sprom *sprom = &(dev->dev->bus->sprom); 426 struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
427 struct ssb_boardinfo *binfo = &(dev->dev->bus->boardinfo); 427 struct ssb_boardinfo *binfo = &(dev->sdev->bus->boardinfo);
428 int i; 428 int i;
429 u16 val; 429 u16 val;
430 bool workaround = false; 430 bool workaround = false;
@@ -609,12 +609,12 @@ static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force)
609 if (dev->phy.type != B43_PHYTYPE_N) 609 if (dev->phy.type != B43_PHYTYPE_N)
610 return; 610 return;
611 611
612 tmslow = ssb_read32(dev->dev, SSB_TMSLOW); 612 tmslow = ssb_read32(dev->sdev, SSB_TMSLOW);
613 if (force) 613 if (force)
614 tmslow |= SSB_TMSLOW_FGC; 614 tmslow |= SSB_TMSLOW_FGC;
615 else 615 else
616 tmslow &= ~SSB_TMSLOW_FGC; 616 tmslow &= ~SSB_TMSLOW_FGC;
617 ssb_write32(dev->dev, SSB_TMSLOW, tmslow); 617 ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
618} 618}
619 619
620/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */ 620/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */
@@ -959,7 +959,7 @@ static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init)
959 b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0); 959 b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0);
960 b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0); 960 b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0);
961 961
962 ssb_chipco_gpio_control(&dev->dev->bus->chipco, 0xFC00, 962 ssb_chipco_gpio_control(&dev->sdev->bus->chipco, 0xFC00,
963 0xFC00); 963 0xFC00);
964 b43_write32(dev, B43_MMIO_MACCTL, 964 b43_write32(dev, B43_MMIO_MACCTL,
965 b43_read32(dev, B43_MMIO_MACCTL) & 965 b43_read32(dev, B43_MMIO_MACCTL) &
@@ -983,7 +983,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
983{ 983{
984 u16 tmp; 984 u16 tmp;
985 985
986 if (dev->dev->id.revision == 16) 986 if (dev->sdev->id.revision == 16)
987 b43_mac_suspend(dev); 987 b43_mac_suspend(dev);
988 988
989 tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL); 989 tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL);
@@ -993,7 +993,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
993 tmp |= (val & mask); 993 tmp |= (val & mask);
994 b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp); 994 b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp);
995 995
996 if (dev->dev->id.revision == 16) 996 if (dev->sdev->id.revision == 16)
997 b43_mac_enable(dev); 997 b43_mac_enable(dev);
998 998
999 return tmp; 999 return tmp;
@@ -1168,7 +1168,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev)
1168static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) 1168static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
1169{ 1169{
1170 struct b43_phy_n *nphy = dev->phy.n; 1170 struct b43_phy_n *nphy = dev->phy.n;
1171 struct ssb_sprom *sprom = &(dev->dev->bus->sprom); 1171 struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
1172 1172
1173 /* PHY rev 0, 1, 2 */ 1173 /* PHY rev 0, 1, 2 */
1174 u8 i, j; 1174 u8 i, j;
@@ -1373,7 +1373,7 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
1373/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ 1373/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */
1374static void b43_nphy_workarounds(struct b43_wldev *dev) 1374static void b43_nphy_workarounds(struct b43_wldev *dev)
1375{ 1375{
1376 struct ssb_bus *bus = dev->dev->bus; 1376 struct ssb_bus *bus = dev->sdev->bus;
1377 struct b43_phy *phy = &dev->phy; 1377 struct b43_phy *phy = &dev->phy;
1378 struct b43_phy_n *nphy = phy->n; 1378 struct b43_phy_n *nphy = phy->n;
1379 1379
@@ -3586,7 +3586,7 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask)
3586 */ 3586 */
3587int b43_phy_initn(struct b43_wldev *dev) 3587int b43_phy_initn(struct b43_wldev *dev)
3588{ 3588{
3589 struct ssb_bus *bus = dev->dev->bus; 3589 struct ssb_bus *bus = dev->sdev->bus;
3590 struct b43_phy *phy = &dev->phy; 3590 struct b43_phy *phy = &dev->phy;
3591 struct b43_phy_n *nphy = phy->n; 3591 struct b43_phy_n *nphy = phy->n;
3592 u8 tx_pwr_state; 3592 u8 tx_pwr_state;
@@ -3601,7 +3601,7 @@ int b43_phy_initn(struct b43_wldev *dev)
3601 if ((dev->phy.rev >= 3) && 3601 if ((dev->phy.rev >= 3) &&
3602 (bus->sprom.boardflags_lo & B43_BFL_EXTLNA) && 3602 (bus->sprom.boardflags_lo & B43_BFL_EXTLNA) &&
3603 (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) { 3603 (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) {
3604 chipco_set32(&dev->dev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40); 3604 chipco_set32(&dev->sdev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40);
3605 } 3605 }
3606 nphy->deaf_count = 0; 3606 nphy->deaf_count = 0;
3607 b43_nphy_tables_init(dev); 3607 b43_nphy_tables_init(dev);
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index aa12273ae716..72ab94df7569 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -111,7 +111,7 @@ static u16 index_to_pioqueue_base(struct b43_wldev *dev,
111 B43_MMIO_PIO11_BASE5, 111 B43_MMIO_PIO11_BASE5,
112 }; 112 };
113 113
114 if (dev->dev->id.revision >= 11) { 114 if (dev->sdev->id.revision >= 11) {
115 B43_WARN_ON(index >= ARRAY_SIZE(bases_rev11)); 115 B43_WARN_ON(index >= ARRAY_SIZE(bases_rev11));
116 return bases_rev11[index]; 116 return bases_rev11[index];
117 } 117 }
@@ -121,14 +121,14 @@ static u16 index_to_pioqueue_base(struct b43_wldev *dev,
121 121
122static u16 pio_txqueue_offset(struct b43_wldev *dev) 122static u16 pio_txqueue_offset(struct b43_wldev *dev)
123{ 123{
124 if (dev->dev->id.revision >= 11) 124 if (dev->sdev->id.revision >= 11)
125 return 0x18; 125 return 0x18;
126 return 0; 126 return 0;
127} 127}
128 128
129static u16 pio_rxqueue_offset(struct b43_wldev *dev) 129static u16 pio_rxqueue_offset(struct b43_wldev *dev)
130{ 130{
131 if (dev->dev->id.revision >= 11) 131 if (dev->sdev->id.revision >= 11)
132 return 0x38; 132 return 0x38;
133 return 8; 133 return 8;
134} 134}
@@ -144,7 +144,7 @@ static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev,
144 if (!q) 144 if (!q)
145 return NULL; 145 return NULL;
146 q->dev = dev; 146 q->dev = dev;
147 q->rev = dev->dev->id.revision; 147 q->rev = dev->sdev->id.revision;
148 q->mmio_base = index_to_pioqueue_base(dev, index) + 148 q->mmio_base = index_to_pioqueue_base(dev, index) +
149 pio_txqueue_offset(dev); 149 pio_txqueue_offset(dev);
150 q->index = index; 150 q->index = index;
@@ -178,7 +178,7 @@ static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev,
178 if (!q) 178 if (!q)
179 return NULL; 179 return NULL;
180 q->dev = dev; 180 q->dev = dev;
181 q->rev = dev->dev->id.revision; 181 q->rev = dev->sdev->id.revision;
182 q->mmio_base = index_to_pioqueue_base(dev, index) + 182 q->mmio_base = index_to_pioqueue_base(dev, index) +
183 pio_rxqueue_offset(dev); 183 pio_rxqueue_offset(dev);
184 184
@@ -339,7 +339,7 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
339 ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI; 339 ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI;
340 b43_piotx_write16(q, B43_PIO_TXCTL, ctl); 340 b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
341 341
342 ssb_block_write(dev->dev, data, (data_len & ~1), 342 b43_block_write(dev, data, (data_len & ~1),
343 q->mmio_base + B43_PIO_TXDATA, 343 q->mmio_base + B43_PIO_TXDATA,
344 sizeof(u16)); 344 sizeof(u16));
345 if (data_len & 1) { 345 if (data_len & 1) {
@@ -351,7 +351,7 @@ static u16 tx_write_2byte_queue(struct b43_pio_txqueue *q,
351 b43_piotx_write16(q, B43_PIO_TXCTL, ctl); 351 b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
352 tail[0] = data[data_len - 1]; 352 tail[0] = data[data_len - 1];
353 tail[1] = 0; 353 tail[1] = 0;
354 ssb_block_write(dev->dev, tail, 2, 354 b43_block_write(dev, tail, 2,
355 q->mmio_base + B43_PIO_TXDATA, 355 q->mmio_base + B43_PIO_TXDATA,
356 sizeof(u16)); 356 sizeof(u16));
357 } 357 }
@@ -393,7 +393,7 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
393 B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_24_31; 393 B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_24_31;
394 b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); 394 b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
395 395
396 ssb_block_write(dev->dev, data, (data_len & ~3), 396 b43_block_write(dev, data, (data_len & ~3),
397 q->mmio_base + B43_PIO8_TXDATA, 397 q->mmio_base + B43_PIO8_TXDATA,
398 sizeof(u32)); 398 sizeof(u32));
399 if (data_len & 3) { 399 if (data_len & 3) {
@@ -421,7 +421,7 @@ static u32 tx_write_4byte_queue(struct b43_pio_txqueue *q,
421 break; 421 break;
422 } 422 }
423 b43_piotx_write32(q, B43_PIO8_TXCTL, ctl); 423 b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
424 ssb_block_write(dev->dev, tail, 4, 424 b43_block_write(dev, tail, 4,
425 q->mmio_base + B43_PIO8_TXDATA, 425 q->mmio_base + B43_PIO8_TXDATA,
426 sizeof(u32)); 426 sizeof(u32));
427 } 427 }
@@ -657,11 +657,11 @@ data_ready:
657 657
658 /* Get the preamble (RX header) */ 658 /* Get the preamble (RX header) */
659 if (q->rev >= 8) { 659 if (q->rev >= 8) {
660 ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr), 660 b43_block_read(dev, rxhdr, sizeof(*rxhdr),
661 q->mmio_base + B43_PIO8_RXDATA, 661 q->mmio_base + B43_PIO8_RXDATA,
662 sizeof(u32)); 662 sizeof(u32));
663 } else { 663 } else {
664 ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr), 664 b43_block_read(dev, rxhdr, sizeof(*rxhdr),
665 q->mmio_base + B43_PIO_RXDATA, 665 q->mmio_base + B43_PIO_RXDATA,
666 sizeof(u16)); 666 sizeof(u16));
667 } 667 }
@@ -697,7 +697,7 @@ data_ready:
697 skb_reserve(skb, 2); 697 skb_reserve(skb, 2);
698 skb_put(skb, len + padding); 698 skb_put(skb, len + padding);
699 if (q->rev >= 8) { 699 if (q->rev >= 8) {
700 ssb_block_read(dev->dev, skb->data + padding, (len & ~3), 700 b43_block_read(dev, skb->data + padding, (len & ~3),
701 q->mmio_base + B43_PIO8_RXDATA, 701 q->mmio_base + B43_PIO8_RXDATA,
702 sizeof(u32)); 702 sizeof(u32));
703 if (len & 3) { 703 if (len & 3) {
@@ -705,7 +705,7 @@ data_ready:
705 BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4); 705 BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4);
706 706
707 /* Read the last few bytes. */ 707 /* Read the last few bytes. */
708 ssb_block_read(dev->dev, tail, 4, 708 b43_block_read(dev, tail, 4,
709 q->mmio_base + B43_PIO8_RXDATA, 709 q->mmio_base + B43_PIO8_RXDATA,
710 sizeof(u32)); 710 sizeof(u32));
711 switch (len & 3) { 711 switch (len & 3) {
@@ -724,7 +724,7 @@ data_ready:
724 } 724 }
725 } 725 }
726 } else { 726 } else {
727 ssb_block_read(dev->dev, skb->data + padding, (len & ~1), 727 b43_block_read(dev, skb->data + padding, (len & ~1),
728 q->mmio_base + B43_PIO_RXDATA, 728 q->mmio_base + B43_PIO_RXDATA,
729 sizeof(u16)); 729 sizeof(u16));
730 if (len & 1) { 730 if (len & 1) {
@@ -732,7 +732,7 @@ data_ready:
732 BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2); 732 BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2);
733 733
734 /* Read the last byte. */ 734 /* Read the last byte. */
735 ssb_block_read(dev->dev, tail, 2, 735 b43_block_read(dev, tail, 2,
736 q->mmio_base + B43_PIO_RXDATA, 736 q->mmio_base + B43_PIO_RXDATA,
737 sizeof(u16)); 737 sizeof(u16));
738 skb->data[len + padding - 1] = tail[0]; 738 skb->data[len + padding - 1] = tail[0];
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
index 86bc0a0f735c..a617efe38289 100644
--- a/drivers/net/wireless/b43/rfkill.c
+++ b/drivers/net/wireless/b43/rfkill.c
@@ -37,7 +37,7 @@ void b43_rfkill_poll(struct ieee80211_hw *hw)
37{ 37{
38 struct b43_wl *wl = hw_to_b43_wl(hw); 38 struct b43_wl *wl = hw_to_b43_wl(hw);
39 struct b43_wldev *dev = wl->current_dev; 39 struct b43_wldev *dev = wl->current_dev;
40 struct ssb_bus *bus = dev->dev->bus; 40 struct ssb_bus *bus = dev->sdev->bus;
41 bool enabled; 41 bool enabled;
42 bool brought_up = false; 42 bool brought_up = false;
43 43
@@ -47,7 +47,7 @@ void b43_rfkill_poll(struct ieee80211_hw *hw)
47 mutex_unlock(&wl->mutex); 47 mutex_unlock(&wl->mutex);
48 return; 48 return;
49 } 49 }
50 ssb_device_enable(dev->dev, 0); 50 ssb_device_enable(dev->sdev, 0);
51 brought_up = true; 51 brought_up = true;
52 } 52 }
53 53
@@ -63,7 +63,7 @@ void b43_rfkill_poll(struct ieee80211_hw *hw)
63 } 63 }
64 64
65 if (brought_up) { 65 if (brought_up) {
66 ssb_device_disable(dev->dev, 0); 66 ssb_device_disable(dev->sdev, 0);
67 ssb_bus_may_powerdown(bus); 67 ssb_bus_may_powerdown(bus);
68 } 68 }
69 69
diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c
index 09e2dfd7b175..808e25b79703 100644
--- a/drivers/net/wireless/b43/sdio.c
+++ b/drivers/net/wireless/b43/sdio.c
@@ -66,7 +66,7 @@ static void b43_sdio_interrupt_dispatcher(struct sdio_func *func)
66int b43_sdio_request_irq(struct b43_wldev *dev, 66int b43_sdio_request_irq(struct b43_wldev *dev,
67 void (*handler)(struct b43_wldev *dev)) 67 void (*handler)(struct b43_wldev *dev))
68{ 68{
69 struct ssb_bus *bus = dev->dev->bus; 69 struct ssb_bus *bus = dev->sdev->bus;
70 struct sdio_func *func = bus->host_sdio; 70 struct sdio_func *func = bus->host_sdio;
71 struct b43_sdio *sdio = sdio_get_drvdata(func); 71 struct b43_sdio *sdio = sdio_get_drvdata(func);
72 int err; 72 int err;
@@ -82,7 +82,7 @@ int b43_sdio_request_irq(struct b43_wldev *dev,
82 82
83void b43_sdio_free_irq(struct b43_wldev *dev) 83void b43_sdio_free_irq(struct b43_wldev *dev)
84{ 84{
85 struct ssb_bus *bus = dev->dev->bus; 85 struct ssb_bus *bus = dev->sdev->bus;
86 struct sdio_func *func = bus->host_sdio; 86 struct sdio_func *func = bus->host_sdio;
87 struct b43_sdio *sdio = sdio_get_drvdata(func); 87 struct b43_sdio *sdio = sdio_get_drvdata(func);
88 88
diff --git a/drivers/net/wireless/b43/sysfs.c b/drivers/net/wireless/b43/sysfs.c
index f1ae4e05a32c..57af619725c3 100644
--- a/drivers/net/wireless/b43/sysfs.c
+++ b/drivers/net/wireless/b43/sysfs.c
@@ -140,7 +140,7 @@ static DEVICE_ATTR(interference, 0644,
140 140
141int b43_sysfs_register(struct b43_wldev *wldev) 141int b43_sysfs_register(struct b43_wldev *wldev)
142{ 142{
143 struct device *dev = wldev->dev->dev; 143 struct device *dev = wldev->sdev->dev;
144 144
145 B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED); 145 B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED);
146 146
@@ -149,7 +149,7 @@ int b43_sysfs_register(struct b43_wldev *wldev)
149 149
150void b43_sysfs_unregister(struct b43_wldev *wldev) 150void b43_sysfs_unregister(struct b43_wldev *wldev)
151{ 151{
152 struct device *dev = wldev->dev->dev; 152 struct device *dev = wldev->sdev->dev;
153 153
154 device_remove_file(dev, &dev_attr_interference); 154 device_remove_file(dev, &dev_attr_interference);
155} 155}
diff --git a/drivers/net/wireless/b43/tables_lpphy.c b/drivers/net/wireless/b43/tables_lpphy.c
index 61027ee84fb5..59df3c64af63 100644
--- a/drivers/net/wireless/b43/tables_lpphy.c
+++ b/drivers/net/wireless/b43/tables_lpphy.c
@@ -2304,7 +2304,7 @@ void lpphy_rev0_1_table_init(struct b43_wldev *dev)
2304 2304
2305void lpphy_rev2plus_table_init(struct b43_wldev *dev) 2305void lpphy_rev2plus_table_init(struct b43_wldev *dev)
2306{ 2306{
2307 struct ssb_bus *bus = dev->dev->bus; 2307 struct ssb_bus *bus = dev->sdev->bus;
2308 int i; 2308 int i;
2309 2309
2310 B43_WARN_ON(dev->phy.rev < 2); 2310 B43_WARN_ON(dev->phy.rev < 2);
@@ -2416,7 +2416,7 @@ void lpphy_write_gain_table_bulk(struct b43_wldev *dev, int offset, int count,
2416 2416
2417void lpphy_init_tx_gain_table(struct b43_wldev *dev) 2417void lpphy_init_tx_gain_table(struct b43_wldev *dev)
2418{ 2418{
2419 struct ssb_bus *bus = dev->dev->bus; 2419 struct ssb_bus *bus = dev->sdev->bus;
2420 2420
2421 switch (dev->phy.rev) { 2421 switch (dev->phy.rev) {
2422 case 0: 2422 case 0:
diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c
index 9a335da65b42..8f4db448ec33 100644
--- a/drivers/net/wireless/b43/wa.c
+++ b/drivers/net/wireless/b43/wa.c
@@ -458,7 +458,7 @@ static void b43_wa_rssi_adc(struct b43_wldev *dev)
458 458
459static void b43_wa_boards_a(struct b43_wldev *dev) 459static void b43_wa_boards_a(struct b43_wldev *dev)
460{ 460{
461 struct ssb_bus *bus = dev->dev->bus; 461 struct ssb_bus *bus = dev->sdev->bus;
462 462
463 if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM && 463 if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM &&
464 bus->boardinfo.type == SSB_BOARD_BU4306 && 464 bus->boardinfo.type == SSB_BOARD_BU4306 &&
@@ -486,7 +486,7 @@ static void b43_wa_boards_a(struct b43_wldev *dev)
486 486
487static void b43_wa_boards_g(struct b43_wldev *dev) 487static void b43_wa_boards_g(struct b43_wldev *dev)
488{ 488{
489 struct ssb_bus *bus = dev->dev->bus; 489 struct ssb_bus *bus = dev->sdev->bus;
490 struct b43_phy *phy = &dev->phy; 490 struct b43_phy *phy = &dev->phy;
491 491
492 if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM || 492 if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM ||
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index e5be381c17bc..c8f99aebe01f 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -547,7 +547,7 @@ static s8 b43_rssi_postprocess(struct b43_wldev *dev,
547 else 547 else
548 tmp -= 3; 548 tmp -= 3;
549 } else { 549 } else {
550 if (dev->dev->bus->sprom. 550 if (dev->sdev->bus->sprom.
551 boardflags_lo & B43_BFL_RSSI) { 551 boardflags_lo & B43_BFL_RSSI) {
552 if (in_rssi > 63) 552 if (in_rssi > 63)
553 in_rssi = 63; 553 in_rssi = 63;
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index b4c81931e136..61d4a11f566b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -171,10 +171,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
171 171
172static struct iwl_lib_ops iwl1000_lib = { 172static struct iwl_lib_ops iwl1000_lib = {
173 .set_hw_params = iwl1000_hw_set_hw_params, 173 .set_hw_params = iwl1000_hw_set_hw_params,
174 .txq_set_sched = iwlagn_txq_set_sched,
175 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
176 .txq_free_tfd = iwl_hw_txq_free_tfd,
177 .txq_init = iwl_hw_tx_queue_init,
178 .rx_handler_setup = iwlagn_rx_handler_setup, 174 .rx_handler_setup = iwlagn_rx_handler_setup,
179 .setup_deferred_work = iwlagn_setup_deferred_work, 175 .setup_deferred_work = iwlagn_setup_deferred_work,
180 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, 176 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c
index 89b8da7a6c8b..86feec86d130 100644
--- a/drivers/net/wireless/iwlwifi/iwl-2000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-2000.c
@@ -195,9 +195,9 @@ static int iwl2030_hw_channel_switch(struct iwl_priv *priv,
195 struct ieee80211_vif *vif = ctx->vif; 195 struct ieee80211_vif *vif = ctx->vif;
196 struct iwl_host_cmd hcmd = { 196 struct iwl_host_cmd hcmd = {
197 .id = REPLY_CHANNEL_SWITCH, 197 .id = REPLY_CHANNEL_SWITCH,
198 .len = sizeof(cmd), 198 .len = { sizeof(cmd), },
199 .flags = CMD_SYNC, 199 .flags = CMD_SYNC,
200 .data = &cmd, 200 .data = { &cmd, },
201 }; 201 };
202 202
203 cmd.band = priv->band == IEEE80211_BAND_2GHZ; 203 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
@@ -252,10 +252,6 @@ static int iwl2030_hw_channel_switch(struct iwl_priv *priv,
252 252
253static struct iwl_lib_ops iwl2000_lib = { 253static struct iwl_lib_ops iwl2000_lib = {
254 .set_hw_params = iwl2000_hw_set_hw_params, 254 .set_hw_params = iwl2000_hw_set_hw_params,
255 .txq_set_sched = iwlagn_txq_set_sched,
256 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
257 .txq_free_tfd = iwl_hw_txq_free_tfd,
258 .txq_init = iwl_hw_tx_queue_init,
259 .rx_handler_setup = iwlagn_rx_handler_setup, 255 .rx_handler_setup = iwlagn_rx_handler_setup,
260 .setup_deferred_work = iwlagn_bt_setup_deferred_work, 256 .setup_deferred_work = iwlagn_bt_setup_deferred_work,
261 .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, 257 .cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 98f81df166e3..a70b8cfafda1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -282,9 +282,9 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
282 struct ieee80211_vif *vif = ctx->vif; 282 struct ieee80211_vif *vif = ctx->vif;
283 struct iwl_host_cmd hcmd = { 283 struct iwl_host_cmd hcmd = {
284 .id = REPLY_CHANNEL_SWITCH, 284 .id = REPLY_CHANNEL_SWITCH,
285 .len = sizeof(cmd), 285 .len = { sizeof(cmd), },
286 .flags = CMD_SYNC, 286 .flags = CMD_SYNC,
287 .data = &cmd, 287 .data = { &cmd, },
288 }; 288 };
289 289
290 cmd.band = priv->band == IEEE80211_BAND_2GHZ; 290 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
@@ -339,10 +339,6 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
339 339
340static struct iwl_lib_ops iwl5000_lib = { 340static struct iwl_lib_ops iwl5000_lib = {
341 .set_hw_params = iwl5000_hw_set_hw_params, 341 .set_hw_params = iwl5000_hw_set_hw_params,
342 .txq_set_sched = iwlagn_txq_set_sched,
343 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
344 .txq_free_tfd = iwl_hw_txq_free_tfd,
345 .txq_init = iwl_hw_tx_queue_init,
346 .rx_handler_setup = iwlagn_rx_handler_setup, 342 .rx_handler_setup = iwlagn_rx_handler_setup,
347 .setup_deferred_work = iwlagn_setup_deferred_work, 343 .setup_deferred_work = iwlagn_setup_deferred_work,
348 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, 344 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
@@ -374,10 +370,6 @@ static struct iwl_lib_ops iwl5000_lib = {
374 370
375static struct iwl_lib_ops iwl5150_lib = { 371static struct iwl_lib_ops iwl5150_lib = {
376 .set_hw_params = iwl5150_hw_set_hw_params, 372 .set_hw_params = iwl5150_hw_set_hw_params,
377 .txq_set_sched = iwlagn_txq_set_sched,
378 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
379 .txq_free_tfd = iwl_hw_txq_free_tfd,
380 .txq_init = iwl_hw_tx_queue_init,
381 .rx_handler_setup = iwlagn_rx_handler_setup, 373 .rx_handler_setup = iwlagn_rx_handler_setup,
382 .setup_deferred_work = iwlagn_setup_deferred_work, 374 .setup_deferred_work = iwlagn_setup_deferred_work,
383 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, 375 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index a7921f9a03c6..f8c710db6e6f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -221,9 +221,9 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
221 struct ieee80211_vif *vif = ctx->vif; 221 struct ieee80211_vif *vif = ctx->vif;
222 struct iwl_host_cmd hcmd = { 222 struct iwl_host_cmd hcmd = {
223 .id = REPLY_CHANNEL_SWITCH, 223 .id = REPLY_CHANNEL_SWITCH,
224 .len = sizeof(cmd), 224 .len = { sizeof(cmd), },
225 .flags = CMD_SYNC, 225 .flags = CMD_SYNC,
226 .data = &cmd, 226 .data = { &cmd, },
227 }; 227 };
228 228
229 cmd.band = priv->band == IEEE80211_BAND_2GHZ; 229 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
@@ -278,10 +278,6 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
278 278
279static struct iwl_lib_ops iwl6000_lib = { 279static struct iwl_lib_ops iwl6000_lib = {
280 .set_hw_params = iwl6000_hw_set_hw_params, 280 .set_hw_params = iwl6000_hw_set_hw_params,
281 .txq_set_sched = iwlagn_txq_set_sched,
282 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
283 .txq_free_tfd = iwl_hw_txq_free_tfd,
284 .txq_init = iwl_hw_tx_queue_init,
285 .rx_handler_setup = iwlagn_rx_handler_setup, 281 .rx_handler_setup = iwlagn_rx_handler_setup,
286 .setup_deferred_work = iwlagn_setup_deferred_work, 282 .setup_deferred_work = iwlagn_setup_deferred_work,
287 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, 283 .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
@@ -314,10 +310,6 @@ static struct iwl_lib_ops iwl6000_lib = {
314 310
315static struct iwl_lib_ops iwl6030_lib = { 311static struct iwl_lib_ops iwl6030_lib = {
316 .set_hw_params = iwl6000_hw_set_hw_params, 312 .set_hw_params = iwl6000_hw_set_hw_params,
317 .txq_set_sched = iwlagn_txq_set_sched,
318 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
319 .txq_free_tfd = iwl_hw_txq_free_tfd,
320 .txq_init = iwl_hw_tx_queue_init,
321 .rx_handler_setup = iwlagn_bt_rx_handler_setup, 313 .rx_handler_setup = iwlagn_bt_rx_handler_setup,
322 .setup_deferred_work = iwlagn_bt_setup_deferred_work, 314 .setup_deferred_work = iwlagn_bt_setup_deferred_work,
323 .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, 315 .cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index 39d1e47a0978..c9255def1080 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -87,14 +87,14 @@ int iwl_send_calib_results(struct iwl_priv *priv)
87 87
88 struct iwl_host_cmd hcmd = { 88 struct iwl_host_cmd hcmd = {
89 .id = REPLY_PHY_CALIBRATION_CMD, 89 .id = REPLY_PHY_CALIBRATION_CMD,
90 .flags = CMD_SIZE_HUGE,
91 }; 90 };
92 91
93 for (i = 0; i < IWL_CALIB_MAX; i++) { 92 for (i = 0; i < IWL_CALIB_MAX; i++) {
94 if ((BIT(i) & priv->hw_params.calib_init_cfg) && 93 if ((BIT(i) & priv->hw_params.calib_init_cfg) &&
95 priv->calib_results[i].buf) { 94 priv->calib_results[i].buf) {
96 hcmd.len = priv->calib_results[i].buf_len; 95 hcmd.len[0] = priv->calib_results[i].buf_len;
97 hcmd.data = priv->calib_results[i].buf; 96 hcmd.data[0] = priv->calib_results[i].buf;
97 hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
98 ret = iwl_send_cmd_sync(priv, &hcmd); 98 ret = iwl_send_cmd_sync(priv, &hcmd);
99 if (ret) { 99 if (ret) {
100 IWL_ERR(priv, "Error %d iteration %d\n", 100 IWL_ERR(priv, "Error %d iteration %d\n",
@@ -456,9 +456,9 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
456 struct iwl_sensitivity_data *data = NULL; 456 struct iwl_sensitivity_data *data = NULL;
457 struct iwl_host_cmd cmd_out = { 457 struct iwl_host_cmd cmd_out = {
458 .id = SENSITIVITY_CMD, 458 .id = SENSITIVITY_CMD,
459 .len = sizeof(struct iwl_sensitivity_cmd), 459 .len = { sizeof(struct iwl_sensitivity_cmd), },
460 .flags = CMD_ASYNC, 460 .flags = CMD_ASYNC,
461 .data = &cmd, 461 .data = { &cmd, },
462 }; 462 };
463 463
464 data = &(priv->sensitivity_data); 464 data = &(priv->sensitivity_data);
@@ -491,9 +491,9 @@ static int iwl_enhance_sensitivity_write(struct iwl_priv *priv)
491 struct iwl_sensitivity_data *data = NULL; 491 struct iwl_sensitivity_data *data = NULL;
492 struct iwl_host_cmd cmd_out = { 492 struct iwl_host_cmd cmd_out = {
493 .id = SENSITIVITY_CMD, 493 .id = SENSITIVITY_CMD,
494 .len = sizeof(struct iwl_enhance_sensitivity_cmd), 494 .len = { sizeof(struct iwl_enhance_sensitivity_cmd), },
495 .flags = CMD_ASYNC, 495 .flags = CMD_ASYNC,
496 .data = &cmd, 496 .data = { &cmd, },
497 }; 497 };
498 498
499 data = &(priv->sensitivity_data); 499 data = &(priv->sensitivity_data);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 8e79653aed9a..f803fb62f8bc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1140,8 +1140,7 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1140{ 1140{
1141 struct iwl_host_cmd cmd = { 1141 struct iwl_host_cmd cmd = {
1142 .id = REPLY_SCAN_CMD, 1142 .id = REPLY_SCAN_CMD,
1143 .len = sizeof(struct iwl_scan_cmd), 1143 .len = { sizeof(struct iwl_scan_cmd), },
1144 .flags = CMD_SIZE_HUGE,
1145 }; 1144 };
1146 struct iwl_scan_cmd *scan; 1145 struct iwl_scan_cmd *scan;
1147 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; 1146 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
@@ -1425,10 +1424,11 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1425 return -EIO; 1424 return -EIO;
1426 } 1425 }
1427 1426
1428 cmd.len += le16_to_cpu(scan->tx_cmd.len) + 1427 cmd.len[0] += le16_to_cpu(scan->tx_cmd.len) +
1429 scan->channel_count * sizeof(struct iwl_scan_channel); 1428 scan->channel_count * sizeof(struct iwl_scan_channel);
1430 cmd.data = scan; 1429 cmd.data[0] = scan;
1431 scan->len = cpu_to_le16(cmd.len); 1430 cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
1431 scan->len = cpu_to_le16(cmd.len[0]);
1432 1432
1433 /* set scan bit here for PAN params */ 1433 /* set scan bit here for PAN params */
1434 set_bit(STATUS_SCAN_HW, &priv->status); 1434 set_bit(STATUS_SCAN_HW, &priv->status);
@@ -1520,9 +1520,9 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
1520 struct iwl_txfifo_flush_cmd flush_cmd; 1520 struct iwl_txfifo_flush_cmd flush_cmd;
1521 struct iwl_host_cmd cmd = { 1521 struct iwl_host_cmd cmd = {
1522 .id = REPLY_TXFIFO_FLUSH, 1522 .id = REPLY_TXFIFO_FLUSH,
1523 .len = sizeof(struct iwl_txfifo_flush_cmd), 1523 .len = { sizeof(struct iwl_txfifo_flush_cmd), },
1524 .flags = CMD_SYNC, 1524 .flags = CMD_SYNC,
1525 .data = &flush_cmd, 1525 .data = { &flush_cmd, },
1526 }; 1526 };
1527 1527
1528 might_sleep(); 1528 might_sleep();
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 91f26556ac23..592b0cfcf717 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -335,6 +335,32 @@ static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,
335 return tid; 335 return tid;
336} 336}
337 337
338#ifdef CONFIG_MAC80211_DEBUGFS
339static void rs_program_fix_rate(struct iwl_priv *priv,
340 struct iwl_lq_sta *lq_sta)
341{
342 struct iwl_station_priv *sta_priv =
343 container_of(lq_sta, struct iwl_station_priv, lq_sta);
344 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
345
346 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */
347 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
348 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
349 lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
350
351 lq_sta->dbg_fixed_rate = priv->dbg_fixed_rate;
352
353 IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",
354 lq_sta->lq.sta_id, priv->dbg_fixed_rate);
355
356 if (priv->dbg_fixed_rate) {
357 rs_fill_link_cmd(NULL, lq_sta, priv->dbg_fixed_rate);
358 iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC,
359 false);
360 }
361}
362#endif
363
338/* 364/*
339 get the traffic load value for tid 365 get the traffic load value for tid
340*/ 366*/
@@ -1046,7 +1072,10 @@ done:
1046 /* See if there's a better rate or modulation mode to try. */ 1072 /* See if there's a better rate or modulation mode to try. */
1047 if (sta && sta->supp_rates[sband->band]) 1073 if (sta && sta->supp_rates[sband->band])
1048 rs_rate_scale_perform(priv, skb, sta, lq_sta); 1074 rs_rate_scale_perform(priv, skb, sta, lq_sta);
1049 1075#ifdef CONFIG_MAC80211_DEBUGFS
1076 if (priv->dbg_fixed_rate != lq_sta->dbg_fixed_rate)
1077 rs_program_fix_rate(priv, lq_sta);
1078#endif
1050 if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) 1079 if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist)
1051 rs_bt_update_lq(priv, ctx, lq_sta); 1080 rs_bt_update_lq(priv, ctx, lq_sta);
1052} 1081}
@@ -2170,11 +2199,11 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search)
2170 * setup rate table in uCode 2199 * setup rate table in uCode
2171 * return rate_n_flags as used in the table 2200 * return rate_n_flags as used in the table
2172 */ 2201 */
2173static u32 rs_update_rate_tbl(struct iwl_priv *priv, 2202static void rs_update_rate_tbl(struct iwl_priv *priv,
2174 struct iwl_rxon_context *ctx, 2203 struct iwl_rxon_context *ctx,
2175 struct iwl_lq_sta *lq_sta, 2204 struct iwl_lq_sta *lq_sta,
2176 struct iwl_scale_tbl_info *tbl, 2205 struct iwl_scale_tbl_info *tbl,
2177 int index, u8 is_green) 2206 int index, u8 is_green)
2178{ 2207{
2179 u32 rate; 2208 u32 rate;
2180 2209
@@ -2182,8 +2211,6 @@ static u32 rs_update_rate_tbl(struct iwl_priv *priv,
2182 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); 2211 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
2183 rs_fill_link_cmd(priv, lq_sta, rate); 2212 rs_fill_link_cmd(priv, lq_sta, rate);
2184 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false); 2213 iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
2185
2186 return rate;
2187} 2214}
2188 2215
2189/* 2216/*
@@ -2212,7 +2239,6 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2212 u8 update_lq = 0; 2239 u8 update_lq = 0;
2213 struct iwl_scale_tbl_info *tbl, *tbl1; 2240 struct iwl_scale_tbl_info *tbl, *tbl1;
2214 u16 rate_scale_index_msk = 0; 2241 u16 rate_scale_index_msk = 0;
2215 u32 rate;
2216 u8 is_green = 0; 2242 u8 is_green = 0;
2217 u8 active_tbl = 0; 2243 u8 active_tbl = 0;
2218 u8 done_search = 0; 2244 u8 done_search = 0;
@@ -2299,8 +2325,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2299 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 2325 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
2300 /* get "active" rate info */ 2326 /* get "active" rate info */
2301 index = iwl_hwrate_to_plcp_idx(tbl->current_rate); 2327 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
2302 rate = rs_update_rate_tbl(priv, ctx, lq_sta, 2328 rs_update_rate_tbl(priv, ctx, lq_sta, tbl,
2303 tbl, index, is_green); 2329 index, is_green);
2304 } 2330 }
2305 return; 2331 return;
2306 } 2332 }
@@ -2541,8 +2567,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2541lq_update: 2567lq_update:
2542 /* Replace uCode's rate table for the destination station. */ 2568 /* Replace uCode's rate table for the destination station. */
2543 if (update_lq) 2569 if (update_lq)
2544 rate = rs_update_rate_tbl(priv, ctx, lq_sta, 2570 rs_update_rate_tbl(priv, ctx, lq_sta, tbl, index, is_green);
2545 tbl, index, is_green);
2546 2571
2547 if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) { 2572 if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) {
2548 /* Should we stay with this modulation mode, 2573 /* Should we stay with this modulation mode,
@@ -2871,6 +2896,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
2871 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; 2896 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
2872 lq_sta->is_agg = 0; 2897 lq_sta->is_agg = 0;
2873 2898
2899 priv->dbg_fixed_rate = 0;
2874#ifdef CONFIG_MAC80211_DEBUGFS 2900#ifdef CONFIG_MAC80211_DEBUGFS
2875 lq_sta->dbg_fixed_rate = 0; 2901 lq_sta->dbg_fixed_rate = 0;
2876#endif 2902#endif
@@ -3045,7 +3071,6 @@ static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,
3045 IWL_DEBUG_RATE(priv, "leave\n"); 3071 IWL_DEBUG_RATE(priv, "leave\n");
3046} 3072}
3047 3073
3048
3049#ifdef CONFIG_MAC80211_DEBUGFS 3074#ifdef CONFIG_MAC80211_DEBUGFS
3050static int open_file_generic(struct inode *inode, struct file *file) 3075static int open_file_generic(struct inode *inode, struct file *file)
3051{ 3076{
@@ -3070,6 +3095,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
3070 IWL_DEBUG_RATE(priv, "Fixed rate ON\n"); 3095 IWL_DEBUG_RATE(priv, "Fixed rate ON\n");
3071 } else { 3096 } else {
3072 lq_sta->dbg_fixed_rate = 0; 3097 lq_sta->dbg_fixed_rate = 0;
3098 priv->dbg_fixed_rate = 0;
3073 IWL_ERR(priv, 3099 IWL_ERR(priv,
3074 "Invalid antenna selection 0x%X, Valid is 0x%X\n", 3100 "Invalid antenna selection 0x%X, Valid is 0x%X\n",
3075 ant_sel_tx, valid_tx_ant); 3101 ant_sel_tx, valid_tx_ant);
@@ -3088,9 +3114,7 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
3088 char buf[64]; 3114 char buf[64];
3089 size_t buf_size; 3115 size_t buf_size;
3090 u32 parsed_rate; 3116 u32 parsed_rate;
3091 struct iwl_station_priv *sta_priv = 3117
3092 container_of(lq_sta, struct iwl_station_priv, lq_sta);
3093 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
3094 3118
3095 priv = lq_sta->drv; 3119 priv = lq_sta->drv;
3096 memset(buf, 0, sizeof(buf)); 3120 memset(buf, 0, sizeof(buf));
@@ -3099,23 +3123,11 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
3099 return -EFAULT; 3123 return -EFAULT;
3100 3124
3101 if (sscanf(buf, "%x", &parsed_rate) == 1) 3125 if (sscanf(buf, "%x", &parsed_rate) == 1)
3102 lq_sta->dbg_fixed_rate = parsed_rate; 3126 priv->dbg_fixed_rate = lq_sta->dbg_fixed_rate = parsed_rate;
3103 else 3127 else
3104 lq_sta->dbg_fixed_rate = 0; 3128 priv->dbg_fixed_rate = lq_sta->dbg_fixed_rate = 0;
3105 3129
3106 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ 3130 rs_program_fix_rate(priv, lq_sta);
3107 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
3108 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
3109 lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
3110
3111 IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",
3112 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
3113
3114 if (lq_sta->dbg_fixed_rate) {
3115 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
3116 iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC,
3117 false);
3118 }
3119 3131
3120 return count; 3132 return count;
3121} 3133}
@@ -3143,7 +3155,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
3143 lq_sta->total_failed, lq_sta->total_success, 3155 lq_sta->total_failed, lq_sta->total_success,
3144 lq_sta->active_legacy_rate); 3156 lq_sta->active_legacy_rate);
3145 desc += sprintf(buff+desc, "fixed rate 0x%X\n", 3157 desc += sprintf(buff+desc, "fixed rate 0x%X\n",
3146 lq_sta->dbg_fixed_rate); 3158 priv->dbg_fixed_rate);
3147 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n", 3159 desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
3148 (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "", 3160 (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "",
3149 (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "", 3161 (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "",
@@ -3254,14 +3266,10 @@ static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
3254static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file, 3266static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
3255 char __user *user_buf, size_t count, loff_t *ppos) 3267 char __user *user_buf, size_t count, loff_t *ppos)
3256{ 3268{
3257 char buff[120];
3258 int desc = 0;
3259
3260 struct iwl_lq_sta *lq_sta = file->private_data; 3269 struct iwl_lq_sta *lq_sta = file->private_data;
3261 struct iwl_priv *priv;
3262 struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl]; 3270 struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl];
3263 3271 char buff[120];
3264 priv = lq_sta->drv; 3272 int desc = 0;
3265 3273
3266 if (is_Ht(tbl->lq_type)) 3274 if (is_Ht(tbl->lq_type))
3267 desc += sprintf(buff+desc, 3275 desc += sprintf(buff+desc,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index 02387430f7fe..a95ad84c5377 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -289,7 +289,6 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
289 /* cast away the const for active_rxon in this function */ 289 /* cast away the const for active_rxon in this function */
290 struct iwl_rxon_cmd *active = (void *)&ctx->active; 290 struct iwl_rxon_cmd *active = (void *)&ctx->active;
291 bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); 291 bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
292 bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK);
293 int ret; 292 int ret;
294 293
295 lockdep_assert_held(&priv->mutex); 294 lockdep_assert_held(&priv->mutex);
@@ -389,11 +388,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
389 * AP station must be done after the BSSID is set to correctly 388 * AP station must be done after the BSSID is set to correctly
390 * set up filters in the device. 389 * set up filters in the device.
391 */ 390 */
392 if ((old_assoc && new_assoc) || !new_assoc) { 391 ret = iwlagn_rxon_disconn(priv, ctx);
393 ret = iwlagn_rxon_disconn(priv, ctx); 392 if (ret)
394 if (ret) 393 return ret;
395 return ret;
396 }
397 394
398 if (new_assoc) 395 if (new_assoc)
399 return iwlagn_rxon_connect(priv, ctx); 396 return iwlagn_rxon_connect(priv, ctx);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
index 079275f2c64d..0bd722cee5ae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
@@ -144,7 +144,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
144 size_t cmd_size = sizeof(struct iwl_wep_cmd); 144 size_t cmd_size = sizeof(struct iwl_wep_cmd);
145 struct iwl_host_cmd cmd = { 145 struct iwl_host_cmd cmd = {
146 .id = ctx->wep_key_cmd, 146 .id = ctx->wep_key_cmd,
147 .data = wep_cmd, 147 .data = { wep_cmd, },
148 .flags = CMD_SYNC, 148 .flags = CMD_SYNC,
149 }; 149 };
150 150
@@ -172,7 +172,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv,
172 172
173 cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX; 173 cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX;
174 174
175 cmd.len = cmd_size; 175 cmd.len[0] = cmd_size;
176 176
177 if (not_empty || send_if_empty) 177 if (not_empty || send_if_empty)
178 return iwl_send_cmd(priv, &cmd); 178 return iwl_send_cmd(priv, &cmd);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 342de780a366..4974cd7837cb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -755,12 +755,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
755 spin_unlock(&priv->sta_lock); 755 spin_unlock(&priv->sta_lock);
756 756
757 /* Attach buffers to TFD */ 757 /* Attach buffers to TFD */
758 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, 758 iwlagn_txq_attach_buf_to_tfd(priv, txq, txcmd_phys, firstlen, 1);
759 txcmd_phys, firstlen, 1, 0);
760 if (secondlen > 0) 759 if (secondlen > 0)
761 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, 760 iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr,
762 phys_addr, secondlen, 761 secondlen, 0);
763 0, 0);
764 762
765 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + 763 scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
766 offsetof(struct iwl_tx_cmd, scratch); 764 offsetof(struct iwl_tx_cmd, scratch);
@@ -916,7 +914,7 @@ int iwlagn_txq_ctx_alloc(struct iwl_priv *priv)
916 spin_lock_irqsave(&priv->lock, flags); 914 spin_lock_irqsave(&priv->lock, flags);
917 915
918 /* Turn off all Tx DMA fifos */ 916 /* Turn off all Tx DMA fifos */
919 priv->cfg->ops->lib->txq_set_sched(priv, 0); 917 iwlagn_txq_set_sched(priv, 0);
920 918
921 /* Tell NIC where to find the "keep warm" buffer */ 919 /* Tell NIC where to find the "keep warm" buffer */
922 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); 920 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
@@ -954,7 +952,7 @@ void iwlagn_txq_ctx_reset(struct iwl_priv *priv)
954 spin_lock_irqsave(&priv->lock, flags); 952 spin_lock_irqsave(&priv->lock, flags);
955 953
956 /* Turn off all Tx DMA fifos */ 954 /* Turn off all Tx DMA fifos */
957 priv->cfg->ops->lib->txq_set_sched(priv, 0); 955 iwlagn_txq_set_sched(priv, 0);
958 956
959 /* Tell NIC where to find the "keep warm" buffer */ 957 /* Tell NIC where to find the "keep warm" buffer */
960 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4); 958 iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
@@ -980,7 +978,7 @@ void iwlagn_txq_ctx_stop(struct iwl_priv *priv)
980 /* Turn off all Tx DMA fifos */ 978 /* Turn off all Tx DMA fifos */
981 spin_lock_irqsave(&priv->lock, flags); 979 spin_lock_irqsave(&priv->lock, flags);
982 980
983 priv->cfg->ops->lib->txq_set_sched(priv, 0); 981 iwlagn_txq_set_sched(priv, 0);
984 982
985 /* Stop each Tx DMA channel, and wait for it to be idle */ 983 /* Stop each Tx DMA channel, and wait for it to be idle */
986 for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) { 984 for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) {
@@ -1263,7 +1261,7 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
1263 1261
1264 iwlagn_txq_inval_byte_cnt_tbl(priv, txq); 1262 iwlagn_txq_inval_byte_cnt_tbl(priv, txq);
1265 1263
1266 priv->cfg->ops->lib->txq_free_tfd(priv, txq); 1264 iwlagn_txq_free_tfd(priv, txq);
1267 } 1265 }
1268 return nfreed; 1266 return nfreed;
1269} 1267}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index 8bda0e8d6661..97de5d9de67b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -217,8 +217,8 @@ static int iwlagn_send_calib_cfg(struct iwl_priv *priv)
217 struct iwl_calib_cfg_cmd calib_cfg_cmd; 217 struct iwl_calib_cfg_cmd calib_cfg_cmd;
218 struct iwl_host_cmd cmd = { 218 struct iwl_host_cmd cmd = {
219 .id = CALIBRATION_CFG_CMD, 219 .id = CALIBRATION_CFG_CMD,
220 .len = sizeof(struct iwl_calib_cfg_cmd), 220 .len = { sizeof(struct iwl_calib_cfg_cmd), },
221 .data = &calib_cfg_cmd, 221 .data = { &calib_cfg_cmd, },
222 }; 222 };
223 223
224 memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd)); 224 memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
@@ -440,7 +440,7 @@ static int iwlagn_alive_notify(struct iwl_priv *priv)
440 IWL_MASK(0, priv->hw_params.max_txq_num)); 440 IWL_MASK(0, priv->hw_params.max_txq_num));
441 441
442 /* Activate all Tx DMA/FIFO channels */ 442 /* Activate all Tx DMA/FIFO channels */
443 priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7)); 443 iwlagn_txq_set_sched(priv, IWL_MASK(0, 7));
444 444
445 /* map queues to FIFOs */ 445 /* map queues to FIFOs */
446 if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) 446 if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 08e3cae4fa5a..11c6c1169e78 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -134,12 +134,10 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
134 struct iwl_tx_beacon_cmd *tx_beacon_cmd; 134 struct iwl_tx_beacon_cmd *tx_beacon_cmd;
135 struct iwl_host_cmd cmd = { 135 struct iwl_host_cmd cmd = {
136 .id = REPLY_TX_BEACON, 136 .id = REPLY_TX_BEACON,
137 .flags = CMD_SIZE_HUGE,
138 }; 137 };
139 u32 frame_size; 138 u32 frame_size;
140 u32 rate_flags; 139 u32 rate_flags;
141 u32 rate; 140 u32 rate;
142 int err;
143 141
144 /* 142 /*
145 * We have to set up the TX command, the TX Beacon command, and the 143 * We have to set up the TX command, the TX Beacon command, and the
@@ -156,17 +154,15 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
156 if (WARN_ON(!priv->beacon_skb)) 154 if (WARN_ON(!priv->beacon_skb))
157 return -EINVAL; 155 return -EINVAL;
158 156
159 /* Allocate beacon memory */ 157 /* Allocate beacon command */
160 tx_beacon_cmd = kzalloc(sizeof(*tx_beacon_cmd) + priv->beacon_skb->len, 158 if (!priv->beacon_cmd)
161 GFP_KERNEL); 159 priv->beacon_cmd = kzalloc(sizeof(*tx_beacon_cmd), GFP_KERNEL);
160 tx_beacon_cmd = priv->beacon_cmd;
162 if (!tx_beacon_cmd) 161 if (!tx_beacon_cmd)
163 return -ENOMEM; 162 return -ENOMEM;
164 163
165 frame_size = priv->beacon_skb->len; 164 frame_size = priv->beacon_skb->len;
166 165
167 /* Set up TX beacon contents */
168 memcpy(tx_beacon_cmd->frame, priv->beacon_skb->data, frame_size);
169
170 /* Set up TX command fields */ 166 /* Set up TX command fields */
171 tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); 167 tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
172 tx_beacon_cmd->tx.sta_id = priv->beacon_ctx->bcast_sta_id; 168 tx_beacon_cmd->tx.sta_id = priv->beacon_ctx->bcast_sta_id;
@@ -175,7 +171,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
175 TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK; 171 TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK;
176 172
177 /* Set up TX beacon command fields */ 173 /* Set up TX beacon command fields */
178 iwl_set_beacon_tim(priv, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame, 174 iwl_set_beacon_tim(priv, tx_beacon_cmd, priv->beacon_skb->data,
179 frame_size); 175 frame_size);
180 176
181 /* Set up packet rate and flags */ 177 /* Set up packet rate and flags */
@@ -189,164 +185,14 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
189 rate_flags); 185 rate_flags);
190 186
191 /* Submit command */ 187 /* Submit command */
192 cmd.len = sizeof(*tx_beacon_cmd) + frame_size; 188 cmd.len[0] = sizeof(*tx_beacon_cmd);
193 cmd.data = tx_beacon_cmd; 189 cmd.data[0] = tx_beacon_cmd;
194 190 cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
195 err = iwl_send_cmd_sync(priv, &cmd); 191 cmd.len[1] = frame_size;
196 192 cmd.data[1] = priv->beacon_skb->data;
197 /* Free temporary storage */ 193 cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY;
198 kfree(tx_beacon_cmd);
199
200 return err;
201}
202
203static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
204{
205 struct iwl_tfd_tb *tb = &tfd->tbs[idx];
206 194
207 dma_addr_t addr = get_unaligned_le32(&tb->lo); 195 return iwl_send_cmd_sync(priv, &cmd);
208 if (sizeof(dma_addr_t) > sizeof(u32))
209 addr |=
210 ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;
211
212 return addr;
213}
214
215static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
216{
217 struct iwl_tfd_tb *tb = &tfd->tbs[idx];
218
219 return le16_to_cpu(tb->hi_n_len) >> 4;
220}
221
222static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
223 dma_addr_t addr, u16 len)
224{
225 struct iwl_tfd_tb *tb = &tfd->tbs[idx];
226 u16 hi_n_len = len << 4;
227
228 put_unaligned_le32(addr, &tb->lo);
229 if (sizeof(dma_addr_t) > sizeof(u32))
230 hi_n_len |= ((addr >> 16) >> 16) & 0xF;
231
232 tb->hi_n_len = cpu_to_le16(hi_n_len);
233
234 tfd->num_tbs = idx + 1;
235}
236
237static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
238{
239 return tfd->num_tbs & 0x1f;
240}
241
242/**
243 * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
244 * @priv - driver private data
245 * @txq - tx queue
246 *
247 * Does NOT advance any TFD circular buffer read/write indexes
248 * Does NOT free the TFD itself (which is within circular buffer)
249 */
250void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
251{
252 struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)txq->tfds;
253 struct iwl_tfd *tfd;
254 struct pci_dev *dev = priv->pci_dev;
255 int index = txq->q.read_ptr;
256 int i;
257 int num_tbs;
258
259 tfd = &tfd_tmp[index];
260
261 /* Sanity check on number of chunks */
262 num_tbs = iwl_tfd_get_num_tbs(tfd);
263
264 if (num_tbs >= IWL_NUM_OF_TBS) {
265 IWL_ERR(priv, "Too many chunks: %i\n", num_tbs);
266 /* @todo issue fatal error, it is quite serious situation */
267 return;
268 }
269
270 /* Unmap tx_cmd */
271 if (num_tbs)
272 pci_unmap_single(dev,
273 dma_unmap_addr(&txq->meta[index], mapping),
274 dma_unmap_len(&txq->meta[index], len),
275 PCI_DMA_BIDIRECTIONAL);
276
277 /* Unmap chunks, if any. */
278 for (i = 1; i < num_tbs; i++)
279 pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
280 iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE);
281
282 /* free SKB */
283 if (txq->txb) {
284 struct sk_buff *skb;
285
286 skb = txq->txb[txq->q.read_ptr].skb;
287
288 /* can be called from irqs-disabled context */
289 if (skb) {
290 dev_kfree_skb_any(skb);
291 txq->txb[txq->q.read_ptr].skb = NULL;
292 }
293 }
294}
295
296int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
297 struct iwl_tx_queue *txq,
298 dma_addr_t addr, u16 len,
299 u8 reset, u8 pad)
300{
301 struct iwl_queue *q;
302 struct iwl_tfd *tfd, *tfd_tmp;
303 u32 num_tbs;
304
305 q = &txq->q;
306 tfd_tmp = (struct iwl_tfd *)txq->tfds;
307 tfd = &tfd_tmp[q->write_ptr];
308
309 if (reset)
310 memset(tfd, 0, sizeof(*tfd));
311
312 num_tbs = iwl_tfd_get_num_tbs(tfd);
313
314 /* Each TFD can point to a maximum 20 Tx buffers */
315 if (num_tbs >= IWL_NUM_OF_TBS) {
316 IWL_ERR(priv, "Error can not send more than %d chunks\n",
317 IWL_NUM_OF_TBS);
318 return -EINVAL;
319 }
320
321 if (WARN_ON(addr & ~DMA_BIT_MASK(36)))
322 return -EINVAL;
323
324 if (unlikely(addr & ~IWL_TX_DMA_MASK))
325 IWL_ERR(priv, "Unaligned address = %llx\n",
326 (unsigned long long)addr);
327
328 iwl_tfd_set_tb(tfd, num_tbs, addr, len);
329
330 return 0;
331}
332
333/*
334 * Tell nic where to find circular buffer of Tx Frame Descriptors for
335 * given Tx queue, and enable the DMA channel used for that queue.
336 *
337 * supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
338 * channels supported in hardware.
339 */
340int iwl_hw_tx_queue_init(struct iwl_priv *priv,
341 struct iwl_tx_queue *txq)
342{
343 int txq_id = txq->q.id;
344
345 /* Circular buffer (TFD queue in DRAM) physical base address */
346 iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
347 txq->q.dma_addr >> 8);
348
349 return 0;
350} 196}
351 197
352static void iwl_bg_beacon_update(struct work_struct *work) 198static void iwl_bg_beacon_update(struct work_struct *work)
@@ -1776,10 +1622,7 @@ static const char *desc_lookup(u32 num)
1776 1622
1777void iwl_dump_nic_error_log(struct iwl_priv *priv) 1623void iwl_dump_nic_error_log(struct iwl_priv *priv)
1778{ 1624{
1779 u32 data2, line; 1625 u32 base;
1780 u32 desc, time, count, base, data1;
1781 u32 blink1, blink2, ilink1, ilink2;
1782 u32 pc, hcmd;
1783 struct iwl_error_event_table table; 1626 struct iwl_error_event_table table;
1784 1627
1785 base = priv->device_pointers.error_event_table; 1628 base = priv->device_pointers.error_event_table;
@@ -1802,37 +1645,40 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
1802 1645
1803 iwl_read_targ_mem_words(priv, base, &table, sizeof(table)); 1646 iwl_read_targ_mem_words(priv, base, &table, sizeof(table));
1804 1647
1805 count = table.valid; 1648 if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
1806
1807 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
1808 IWL_ERR(priv, "Start IWL Error Log Dump:\n"); 1649 IWL_ERR(priv, "Start IWL Error Log Dump:\n");
1809 IWL_ERR(priv, "Status: 0x%08lX, count: %d\n", 1650 IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
1810 priv->status, count); 1651 priv->status, table.valid);
1811 } 1652 }
1812 1653
1813 desc = table.error_id; 1654 priv->isr_stats.err_code = table.error_id;
1814 priv->isr_stats.err_code = desc; 1655
1815 pc = table.pc; 1656 trace_iwlwifi_dev_ucode_error(priv, table.error_id, table.tsf_low,
1816 blink1 = table.blink1; 1657 table.data1, table.data2, table.line,
1817 blink2 = table.blink2; 1658 table.blink1, table.blink2, table.ilink1,
1818 ilink1 = table.ilink1; 1659 table.ilink2, table.bcon_time, table.gp1,
1819 ilink2 = table.ilink2; 1660 table.gp2, table.gp3, table.ucode_ver,
1820 data1 = table.data1; 1661 table.hw_ver, table.brd_ver);
1821 data2 = table.data2; 1662 IWL_ERR(priv, "0x%08X | %-28s\n", table.error_id,
1822 line = table.line; 1663 desc_lookup(table.error_id));
1823 time = table.tsf_low; 1664 IWL_ERR(priv, "0x%08X | uPc\n", table.pc);
1824 hcmd = table.hcmd; 1665 IWL_ERR(priv, "0x%08X | branchlink1\n", table.blink1);
1825 1666 IWL_ERR(priv, "0x%08X | branchlink2\n", table.blink2);
1826 trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line, 1667 IWL_ERR(priv, "0x%08X | interruptlink1\n", table.ilink1);
1827 blink1, blink2, ilink1, ilink2); 1668 IWL_ERR(priv, "0x%08X | interruptlink2\n", table.ilink2);
1828 1669 IWL_ERR(priv, "0x%08X | data1\n", table.data1);
1829 IWL_ERR(priv, "Desc Time " 1670 IWL_ERR(priv, "0x%08X | data2\n", table.data2);
1830 "data1 data2 line\n"); 1671 IWL_ERR(priv, "0x%08X | line\n", table.line);
1831 IWL_ERR(priv, "%-28s (0x%04X) %010u 0x%08X 0x%08X %u\n", 1672 IWL_ERR(priv, "0x%08X | beacon time\n", table.bcon_time);
1832 desc_lookup(desc), desc, time, data1, data2, line); 1673 IWL_ERR(priv, "0x%08X | tsf low\n", table.tsf_low);
1833 IWL_ERR(priv, "pc blink1 blink2 ilink1 ilink2 hcmd\n"); 1674 IWL_ERR(priv, "0x%08X | tsf hi\n", table.tsf_hi);
1834 IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X 0x%05X 0x%05X\n", 1675 IWL_ERR(priv, "0x%08X | time gp1\n", table.gp1);
1835 pc, blink1, blink2, ilink1, ilink2, hcmd); 1676 IWL_ERR(priv, "0x%08X | time gp2\n", table.gp2);
1677 IWL_ERR(priv, "0x%08X | time gp3\n", table.gp3);
1678 IWL_ERR(priv, "0x%08X | uCode version\n", table.ucode_ver);
1679 IWL_ERR(priv, "0x%08X | hw version\n", table.hw_ver);
1680 IWL_ERR(priv, "0x%08X | board version\n", table.brd_ver);
1681 IWL_ERR(priv, "0x%08X | hcmd\n", table.hcmd);
1836} 1682}
1837 1683
1838#define EVENT_START_OFFSET (4 * sizeof(u32)) 1684#define EVENT_START_OFFSET (4 * sizeof(u32))
@@ -2114,8 +1960,8 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg)
2114 struct iwl_calib_cfg_cmd calib_cfg_cmd; 1960 struct iwl_calib_cfg_cmd calib_cfg_cmd;
2115 struct iwl_host_cmd cmd = { 1961 struct iwl_host_cmd cmd = {
2116 .id = CALIBRATION_CFG_CMD, 1962 .id = CALIBRATION_CFG_CMD,
2117 .len = sizeof(struct iwl_calib_cfg_cmd), 1963 .len = { sizeof(struct iwl_calib_cfg_cmd), },
2118 .data = &calib_cfg_cmd, 1964 .data = { &calib_cfg_cmd, },
2119 }; 1965 };
2120 1966
2121 memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd)); 1967 memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
@@ -3395,6 +3241,7 @@ static void iwl_uninit_drv(struct iwl_priv *priv)
3395 iwlcore_free_geos(priv); 3241 iwlcore_free_geos(priv);
3396 iwl_free_channel_map(priv); 3242 iwl_free_channel_map(priv);
3397 kfree(priv->scan_cmd); 3243 kfree(priv->scan_cmd);
3244 kfree(priv->beacon_cmd);
3398} 3245}
3399 3246
3400struct ieee80211_ops iwlagn_hw_ops = { 3247struct ieee80211_ops iwlagn_hw_ops = {
@@ -3812,6 +3659,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
3812 */ 3659 */
3813 set_bit(STATUS_EXIT_PENDING, &priv->status); 3660 set_bit(STATUS_EXIT_PENDING, &priv->status);
3814 3661
3662 iwl_testmode_cleanup(priv);
3815 iwl_leds_exit(priv); 3663 iwl_leds_exit(priv);
3816 3664
3817 if (priv->mac80211_registered) { 3665 if (priv->mac80211_registered) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index fe33fe8aa418..2495fe7a58cb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -191,12 +191,10 @@ int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
191void iwl_setup_rx_handlers(struct iwl_priv *priv); 191void iwl_setup_rx_handlers(struct iwl_priv *priv);
192 192
193/* tx */ 193/* tx */
194void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); 194void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
195int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, 195int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv,
196 struct iwl_tx_queue *txq, 196 struct iwl_tx_queue *txq,
197 dma_addr_t addr, u16 len, u8 reset, u8 pad); 197 dma_addr_t addr, u16 len, u8 reset);
198int iwl_hw_tx_queue_init(struct iwl_priv *priv,
199 struct iwl_tx_queue *txq);
200void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, 198void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
201 struct ieee80211_tx_info *info); 199 struct ieee80211_tx_info *info);
202int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); 200int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
@@ -345,6 +343,7 @@ extern int iwl_alive_start(struct iwl_priv *priv);
345#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL 343#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
346extern int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len); 344extern int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len);
347extern void iwl_testmode_init(struct iwl_priv *priv); 345extern void iwl_testmode_init(struct iwl_priv *priv);
346extern void iwl_testmode_cleanup(struct iwl_priv *priv);
348#else 347#else
349static inline 348static inline
350int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) 349int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
@@ -355,6 +354,10 @@ static inline
355void iwl_testmode_init(struct iwl_priv *priv) 354void iwl_testmode_init(struct iwl_priv *priv)
356{ 355{
357} 356}
357static inline
358void iwl_testmode_cleanup(struct iwl_priv *priv)
359{
360}
358#endif 361#endif
359 362
360#endif /* __iwl_agn_h__ */ 363#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 5fdad6532118..6ee5f1aa555c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -205,7 +205,6 @@ enum {
205#define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8) 205#define QUEUE_TO_SEQ(q) (((q) & 0x1f) << 8)
206#define SEQ_TO_INDEX(s) ((s) & 0xff) 206#define SEQ_TO_INDEX(s) ((s) & 0xff)
207#define INDEX_TO_SEQ(i) ((i) & 0xff) 207#define INDEX_TO_SEQ(i) ((i) & 0xff)
208#define SEQ_HUGE_FRAME cpu_to_le16(0x4000)
209#define SEQ_RX_FRAME cpu_to_le16(0x8000) 208#define SEQ_RX_FRAME cpu_to_le16(0x8000)
210 209
211/** 210/**
@@ -234,9 +233,7 @@ struct iwl_cmd_header {
234 * 233 *
235 * 0:7 tfd index - position within TX queue 234 * 0:7 tfd index - position within TX queue
236 * 8:12 TX queue id 235 * 8:12 TX queue id
237 * 13 reserved 236 * 13:14 reserved
238 * 14 huge - driver sets this to indicate command is in the
239 * 'huge' storage at the end of the command buffers
240 * 15 unsolicited RX or uCode-originated notification 237 * 15 unsolicited RX or uCode-originated notification
241 */ 238 */
242 __le16 sequence; 239 __le16 sequence;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 5b5b0cce4a54..3bb76f6ea410 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -127,16 +127,6 @@ struct iwl_temp_ops {
127struct iwl_lib_ops { 127struct iwl_lib_ops {
128 /* set hw dependent parameters */ 128 /* set hw dependent parameters */
129 int (*set_hw_params)(struct iwl_priv *priv); 129 int (*set_hw_params)(struct iwl_priv *priv);
130 /* Handling TX */
131 void (*txq_set_sched)(struct iwl_priv *priv, u32 mask);
132 int (*txq_attach_buf_to_tfd)(struct iwl_priv *priv,
133 struct iwl_tx_queue *txq,
134 dma_addr_t addr,
135 u16 len, u8 reset, u8 pad);
136 void (*txq_free_tfd)(struct iwl_priv *priv,
137 struct iwl_tx_queue *txq);
138 int (*txq_init)(struct iwl_priv *priv,
139 struct iwl_tx_queue *txq);
140 /* setup Rx handler */ 130 /* setup Rx handler */
141 void (*rx_handler_setup)(struct iwl_priv *priv); 131 void (*rx_handler_setup)(struct iwl_priv *priv);
142 /* setup deferred work */ 132 /* setup deferred work */
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 214e4658c495..22a6e3ec7094 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -48,8 +48,6 @@
48#include "iwl-agn-rs.h" 48#include "iwl-agn-rs.h"
49#include "iwl-agn-tt.h" 49#include "iwl-agn-tt.h"
50 50
51#define U32_PAD(n) ((4-(n))&0x3)
52
53struct iwl_tx_queue; 51struct iwl_tx_queue;
54 52
55/* CT-KILL constants */ 53/* CT-KILL constants */
@@ -83,7 +81,7 @@ struct iwl_tx_queue;
83#define MAX_RTS_THRESHOLD 2347U 81#define MAX_RTS_THRESHOLD 2347U
84#define MAX_MSDU_SIZE 2304U 82#define MAX_MSDU_SIZE 2304U
85#define MAX_MPDU_SIZE 2346U 83#define MAX_MPDU_SIZE 2346U
86#define DEFAULT_BEACON_INTERVAL 100U 84#define DEFAULT_BEACON_INTERVAL 200U
87#define DEFAULT_SHORT_RETRY_LIMIT 7U 85#define DEFAULT_SHORT_RETRY_LIMIT 7U
88#define DEFAULT_LONG_RETRY_LIMIT 4U 86#define DEFAULT_LONG_RETRY_LIMIT 4U
89 87
@@ -112,8 +110,6 @@ struct iwl_cmd_meta {
112 struct iwl_device_cmd *cmd, 110 struct iwl_device_cmd *cmd,
113 struct iwl_rx_packet *pkt); 111 struct iwl_rx_packet *pkt);
114 112
115 /* The CMD_SIZE_HUGE flag bit indicates that the command
116 * structure is stored at the end of the shared queue memory. */
117 u32 flags; 113 u32 flags;
118 114
119 DEFINE_DMA_UNMAP_ADDR(mapping); 115 DEFINE_DMA_UNMAP_ADDR(mapping);
@@ -123,7 +119,23 @@ struct iwl_cmd_meta {
123/* 119/*
124 * Generic queue structure 120 * Generic queue structure
125 * 121 *
126 * Contains common data for Rx and Tx queues 122 * Contains common data for Rx and Tx queues.
123 *
124 * Note the difference between n_bd and n_window: the hardware
125 * always assumes 256 descriptors, so n_bd is always 256 (unless
126 * there might be HW changes in the future). For the normal TX
127 * queues, n_window, which is the size of the software queue data
128 * is also 256; however, for the command queue, n_window is only
129 * 32 since we don't need so many commands pending. Since the HW
130 * still uses 256 BDs for DMA though, n_bd stays 256. As a result,
131 * the software buffers (in the variables @meta, @txb in struct
132 * iwl_tx_queue) only have 32 entries, while the HW buffers (@tfds
133 * in the same struct) have 256.
134 * This means that we end up with the following:
135 * HW entries: | 0 | ... | N * 32 | ... | N * 32 + 31 | ... | 255 |
136 * SW entries: | 0 | ... | 31 |
137 * where N is a number between 0 and 7. This means that the SW
138 * data is a window overlayed over the HW queue.
127 */ 139 */
128struct iwl_queue { 140struct iwl_queue {
129 int n_bd; /* number of BDs in this queue */ 141 int n_bd; /* number of BDs in this queue */
@@ -165,7 +177,7 @@ struct iwl_tx_info {
165 177
166struct iwl_tx_queue { 178struct iwl_tx_queue {
167 struct iwl_queue q; 179 struct iwl_queue q;
168 void *tfds; 180 struct iwl_tfd *tfds;
169 struct iwl_device_cmd **cmd; 181 struct iwl_device_cmd **cmd;
170 struct iwl_cmd_meta *meta; 182 struct iwl_cmd_meta *meta;
171 struct iwl_tx_info *txb; 183 struct iwl_tx_info *txb;
@@ -247,7 +259,6 @@ enum {
247 CMD_SYNC = 0, 259 CMD_SYNC = 0,
248 CMD_SIZE_NORMAL = 0, 260 CMD_SIZE_NORMAL = 0,
249 CMD_NO_SKB = 0, 261 CMD_NO_SKB = 0,
250 CMD_SIZE_HUGE = (1 << 0),
251 CMD_ASYNC = (1 << 1), 262 CMD_ASYNC = (1 << 1),
252 CMD_WANT_SKB = (1 << 2), 263 CMD_WANT_SKB = (1 << 2),
253 CMD_MAPPED = (1 << 3), 264 CMD_MAPPED = (1 << 3),
@@ -259,8 +270,8 @@ enum {
259 * struct iwl_device_cmd 270 * struct iwl_device_cmd
260 * 271 *
261 * For allocation of the command and tx queues, this establishes the overall 272 * For allocation of the command and tx queues, this establishes the overall
262 * size of the largest command we send to uCode, except for a scan command 273 * size of the largest command we send to uCode, except for commands that
263 * (which is relatively huge; space is allocated separately). 274 * aren't fully copied and use other TFD space.
264 */ 275 */
265struct iwl_device_cmd { 276struct iwl_device_cmd {
266 struct iwl_cmd_header hdr; /* uCode API */ 277 struct iwl_cmd_header hdr; /* uCode API */
@@ -277,15 +288,21 @@ struct iwl_device_cmd {
277 288
278#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) 289#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
279 290
291#define IWL_MAX_CMD_TFDS 2
292
293enum iwl_hcmd_dataflag {
294 IWL_HCMD_DFL_NOCOPY = BIT(0),
295};
280 296
281struct iwl_host_cmd { 297struct iwl_host_cmd {
282 const void *data; 298 const void *data[IWL_MAX_CMD_TFDS];
283 unsigned long reply_page; 299 unsigned long reply_page;
284 void (*callback)(struct iwl_priv *priv, 300 void (*callback)(struct iwl_priv *priv,
285 struct iwl_device_cmd *cmd, 301 struct iwl_device_cmd *cmd,
286 struct iwl_rx_packet *pkt); 302 struct iwl_rx_packet *pkt);
287 u32 flags; 303 u32 flags;
288 u16 len; 304 u16 len[IWL_MAX_CMD_TFDS];
305 u8 dataflags[IWL_MAX_CMD_TFDS];
289 u8 id; 306 u8 id;
290}; 307};
291 308
@@ -688,17 +705,8 @@ static inline int iwl_queue_used(const struct iwl_queue *q, int i)
688} 705}
689 706
690 707
691static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge) 708static inline u8 get_cmd_index(struct iwl_queue *q, u32 index)
692{ 709{
693 /*
694 * This is for init calibration result and scan command which
695 * required buffer > TFD_MAX_PAYLOAD_SIZE,
696 * the big buffer at end of command array
697 */
698 if (is_huge)
699 return q->n_window; /* must be power of 2 */
700
701 /* Otherwise, use normal size buffers */
702 return index & (q->n_window - 1); 710 return index & (q->n_window - 1);
703} 711}
704 712
@@ -1171,6 +1179,14 @@ enum iwl_scan_type {
1171 IWL_SCAN_OFFCH_TX, 1179 IWL_SCAN_OFFCH_TX,
1172}; 1180};
1173 1181
1182#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
1183struct iwl_testmode_trace {
1184 u8 *cpu_addr;
1185 u8 *trace_addr;
1186 dma_addr_t dma_addr;
1187 bool trace_enabled;
1188};
1189#endif
1174struct iwl_priv { 1190struct iwl_priv {
1175 1191
1176 /* ieee device used by generic ieee processing code */ 1192 /* ieee device used by generic ieee processing code */
@@ -1452,6 +1468,7 @@ struct iwl_priv {
1452 struct work_struct beacon_update; 1468 struct work_struct beacon_update;
1453 struct iwl_rxon_context *beacon_ctx; 1469 struct iwl_rxon_context *beacon_ctx;
1454 struct sk_buff *beacon_skb; 1470 struct sk_buff *beacon_skb;
1471 void *beacon_cmd;
1455 1472
1456 struct work_struct tt_work; 1473 struct work_struct tt_work;
1457 struct work_struct ct_enter; 1474 struct work_struct ct_enter;
@@ -1501,6 +1518,11 @@ struct iwl_priv {
1501 struct led_classdev led; 1518 struct led_classdev led;
1502 unsigned long blink_on, blink_off; 1519 unsigned long blink_on, blink_off;
1503 bool led_registered; 1520 bool led_registered;
1521#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
1522 struct iwl_testmode_trace testmode_trace;
1523#endif
1524 u32 dbg_fixed_rate;
1525
1504}; /*iwl_priv */ 1526}; /*iwl_priv */
1505 1527
1506static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id) 1528static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index f00172cb8a6d..2c84ba95afca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -137,20 +137,27 @@ TRACE_EVENT(iwlwifi_dev_ucode_wrap_event,
137#define TRACE_SYSTEM iwlwifi 137#define TRACE_SYSTEM iwlwifi
138 138
139TRACE_EVENT(iwlwifi_dev_hcmd, 139TRACE_EVENT(iwlwifi_dev_hcmd,
140 TP_PROTO(struct iwl_priv *priv, void *hcmd, size_t len, u32 flags), 140 TP_PROTO(struct iwl_priv *priv, u32 flags,
141 TP_ARGS(priv, hcmd, len, flags), 141 const void *hcmd0, size_t len0,
142 const void *hcmd1, size_t len1,
143 const void *hcmd2, size_t len2),
144 TP_ARGS(priv, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2),
142 TP_STRUCT__entry( 145 TP_STRUCT__entry(
143 PRIV_ENTRY 146 PRIV_ENTRY
144 __dynamic_array(u8, hcmd, len) 147 __dynamic_array(u8, hcmd0, len0)
148 __dynamic_array(u8, hcmd1, len1)
149 __dynamic_array(u8, hcmd2, len2)
145 __field(u32, flags) 150 __field(u32, flags)
146 ), 151 ),
147 TP_fast_assign( 152 TP_fast_assign(
148 PRIV_ASSIGN; 153 PRIV_ASSIGN;
149 memcpy(__get_dynamic_array(hcmd), hcmd, len); 154 memcpy(__get_dynamic_array(hcmd0), hcmd0, len0);
155 memcpy(__get_dynamic_array(hcmd1), hcmd1, len1);
156 memcpy(__get_dynamic_array(hcmd2), hcmd2, len2);
150 __entry->flags = flags; 157 __entry->flags = flags;
151 ), 158 ),
152 TP_printk("[%p] hcmd %#.2x (%ssync)", 159 TP_printk("[%p] hcmd %#.2x (%ssync)",
153 __entry->priv, ((u8 *)__get_dynamic_array(hcmd))[0], 160 __entry->priv, ((u8 *)__get_dynamic_array(hcmd0))[0],
154 __entry->flags & CMD_ASYNC ? "a" : "") 161 __entry->flags & CMD_ASYNC ? "a" : "")
155); 162);
156 163
@@ -202,15 +209,18 @@ TRACE_EVENT(iwlwifi_dev_tx,
202); 209);
203 210
204TRACE_EVENT(iwlwifi_dev_ucode_error, 211TRACE_EVENT(iwlwifi_dev_ucode_error,
205 TP_PROTO(struct iwl_priv *priv, u32 desc, u32 time, 212 TP_PROTO(struct iwl_priv *priv, u32 desc, u32 tsf_low,
206 u32 data1, u32 data2, u32 line, u32 blink1, 213 u32 data1, u32 data2, u32 line, u32 blink1,
207 u32 blink2, u32 ilink1, u32 ilink2), 214 u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time,
208 TP_ARGS(priv, desc, time, data1, data2, line, 215 u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver,
209 blink1, blink2, ilink1, ilink2), 216 u32 brd_ver),
217 TP_ARGS(priv, desc, tsf_low, data1, data2, line,
218 blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2,
219 gp3, ucode_ver, hw_ver, brd_ver),
210 TP_STRUCT__entry( 220 TP_STRUCT__entry(
211 PRIV_ENTRY 221 PRIV_ENTRY
212 __field(u32, desc) 222 __field(u32, desc)
213 __field(u32, time) 223 __field(u32, tsf_low)
214 __field(u32, data1) 224 __field(u32, data1)
215 __field(u32, data2) 225 __field(u32, data2)
216 __field(u32, line) 226 __field(u32, line)
@@ -218,11 +228,18 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
218 __field(u32, blink2) 228 __field(u32, blink2)
219 __field(u32, ilink1) 229 __field(u32, ilink1)
220 __field(u32, ilink2) 230 __field(u32, ilink2)
231 __field(u32, bcon_time)
232 __field(u32, gp1)
233 __field(u32, gp2)
234 __field(u32, gp3)
235 __field(u32, ucode_ver)
236 __field(u32, hw_ver)
237 __field(u32, brd_ver)
221 ), 238 ),
222 TP_fast_assign( 239 TP_fast_assign(
223 PRIV_ASSIGN; 240 PRIV_ASSIGN;
224 __entry->desc = desc; 241 __entry->desc = desc;
225 __entry->time = time; 242 __entry->tsf_low = tsf_low;
226 __entry->data1 = data1; 243 __entry->data1 = data1;
227 __entry->data2 = data2; 244 __entry->data2 = data2;
228 __entry->line = line; 245 __entry->line = line;
@@ -230,12 +247,25 @@ TRACE_EVENT(iwlwifi_dev_ucode_error,
230 __entry->blink2 = blink2; 247 __entry->blink2 = blink2;
231 __entry->ilink1 = ilink1; 248 __entry->ilink1 = ilink1;
232 __entry->ilink2 = ilink2; 249 __entry->ilink2 = ilink2;
250 __entry->bcon_time = bcon_time;
251 __entry->gp1 = gp1;
252 __entry->gp2 = gp2;
253 __entry->gp3 = gp3;
254 __entry->ucode_ver = ucode_ver;
255 __entry->hw_ver = hw_ver;
256 __entry->brd_ver = brd_ver;
233 ), 257 ),
234 TP_printk("[%p] #%02d %010u data 0x%08X 0x%08X line %u, " 258 TP_printk("[%p] #%02d %010u data 0x%08X 0x%08X line %u, "
235 "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X", 259 "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X "
236 __entry->priv, __entry->desc, __entry->time, __entry->data1, 260 "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X "
261 "hw 0x%08X brd 0x%08X",
262 __entry->priv, __entry->desc, __entry->tsf_low,
263 __entry->data1,
237 __entry->data2, __entry->line, __entry->blink1, 264 __entry->data2, __entry->line, __entry->blink1,
238 __entry->blink2, __entry->ilink1, __entry->ilink2) 265 __entry->blink2, __entry->ilink1, __entry->ilink2,
266 __entry->bcon_time, __entry->gp1, __entry->gp2,
267 __entry->gp3, __entry->ucode_ver, __entry->hw_ver,
268 __entry->brd_ver)
239); 269);
240 270
241TRACE_EVENT(iwlwifi_dev_ucode_event, 271TRACE_EVENT(iwlwifi_dev_ucode_event,
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index c8397962632c..47a56bc1cd12 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -216,15 +216,14 @@ static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
216 216
217static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode) 217static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode)
218{ 218{
219 u32 otpgp; 219 iwl_read32(priv, CSR_OTP_GP_REG);
220 220
221 otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
222 if (mode == IWL_OTP_ACCESS_ABSOLUTE) 221 if (mode == IWL_OTP_ACCESS_ABSOLUTE)
223 iwl_clear_bit(priv, CSR_OTP_GP_REG, 222 iwl_clear_bit(priv, CSR_OTP_GP_REG,
224 CSR_OTP_GP_REG_OTP_ACCESS_MODE); 223 CSR_OTP_GP_REG_OTP_ACCESS_MODE);
225 else 224 else
226 iwl_set_bit(priv, CSR_OTP_GP_REG, 225 iwl_set_bit(priv, CSR_OTP_GP_REG,
227 CSR_OTP_GP_REG_OTP_ACCESS_MODE); 226 CSR_OTP_GP_REG_OTP_ACCESS_MODE);
228} 227}
229 228
230static int iwlcore_get_nvm_type(struct iwl_priv *priv, u32 hw_rev) 229static int iwlcore_get_nvm_type(struct iwl_priv *priv, u32 hw_rev)
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 8f0beb992ccf..76f996623140 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -188,6 +188,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
188 cmd_idx = iwl_enqueue_hcmd(priv, cmd); 188 cmd_idx = iwl_enqueue_hcmd(priv, cmd);
189 if (cmd_idx < 0) { 189 if (cmd_idx < 0) {
190 ret = cmd_idx; 190 ret = cmd_idx;
191 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
191 IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n", 192 IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
192 get_cmd_string(cmd->id), ret); 193 get_cmd_string(cmd->id), ret);
193 return ret; 194 return ret;
@@ -264,8 +265,8 @@ int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data)
264{ 265{
265 struct iwl_host_cmd cmd = { 266 struct iwl_host_cmd cmd = {
266 .id = id, 267 .id = id,
267 .len = len, 268 .len = { len, },
268 .data = data, 269 .data = { data, },
269 }; 270 };
270 271
271 return iwl_send_cmd_sync(priv, &cmd); 272 return iwl_send_cmd_sync(priv, &cmd);
@@ -279,8 +280,8 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv,
279{ 280{
280 struct iwl_host_cmd cmd = { 281 struct iwl_host_cmd cmd = {
281 .id = id, 282 .id = id,
282 .len = len, 283 .len = { len, },
283 .data = data, 284 .data = { data, },
284 }; 285 };
285 286
286 cmd.flags |= CMD_ASYNC; 287 cmd.flags |= CMD_ASYNC;
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 439187f903c9..7c23beb49d7c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -107,8 +107,8 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
107{ 107{
108 struct iwl_host_cmd cmd = { 108 struct iwl_host_cmd cmd = {
109 .id = REPLY_LEDS_CMD, 109 .id = REPLY_LEDS_CMD,
110 .len = sizeof(struct iwl_led_cmd), 110 .len = { sizeof(struct iwl_led_cmd), },
111 .data = led_cmd, 111 .data = { led_cmd, },
112 .flags = CMD_ASYNC, 112 .flags = CMD_ASYNC,
113 .callback = NULL, 113 .callback = NULL,
114 }; 114 };
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 3c8cebde16cc..7df2814fd4f8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -141,7 +141,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
141 struct iwl_host_cmd cmd = { 141 struct iwl_host_cmd cmd = {
142 .id = REPLY_ADD_STA, 142 .id = REPLY_ADD_STA,
143 .flags = flags, 143 .flags = flags,
144 .data = data, 144 .data = { data, },
145 }; 145 };
146 u8 sta_id __maybe_unused = sta->sta.sta_id; 146 u8 sta_id __maybe_unused = sta->sta.sta_id;
147 147
@@ -155,7 +155,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
155 might_sleep(); 155 might_sleep();
156 } 156 }
157 157
158 cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); 158 cmd.len[0] = priv->cfg->ops->utils->build_addsta_hcmd(sta, data);
159 ret = iwl_send_cmd(priv, &cmd); 159 ret = iwl_send_cmd(priv, &cmd);
160 160
161 if (ret || (flags & CMD_ASYNC)) 161 if (ret || (flags & CMD_ASYNC))
@@ -401,9 +401,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
401 401
402 struct iwl_host_cmd cmd = { 402 struct iwl_host_cmd cmd = {
403 .id = REPLY_REMOVE_STA, 403 .id = REPLY_REMOVE_STA,
404 .len = sizeof(struct iwl_rem_sta_cmd), 404 .len = { sizeof(struct iwl_rem_sta_cmd), },
405 .flags = CMD_SYNC, 405 .flags = CMD_SYNC,
406 .data = &rm_sta_cmd, 406 .data = { &rm_sta_cmd, },
407 }; 407 };
408 408
409 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); 409 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
@@ -760,9 +760,9 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
760 760
761 struct iwl_host_cmd cmd = { 761 struct iwl_host_cmd cmd = {
762 .id = REPLY_TX_LINK_QUALITY_CMD, 762 .id = REPLY_TX_LINK_QUALITY_CMD,
763 .len = sizeof(struct iwl_link_quality_cmd), 763 .len = { sizeof(struct iwl_link_quality_cmd), },
764 .flags = flags, 764 .flags = flags,
765 .data = lq, 765 .data = { lq, },
766 }; 766 };
767 767
768 if (WARN_ON(lq->sta_id == IWL_INVALID_STATION)) 768 if (WARN_ON(lq->sta_id == IWL_INVALID_STATION))
diff --git a/drivers/net/wireless/iwlwifi/iwl-sv-open.c b/drivers/net/wireless/iwlwifi/iwl-sv-open.c
index 89b6696622c1..69b7e6bf2d6f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sv-open.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sv-open.c
@@ -97,6 +97,13 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
97 97
98 [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, }, 98 [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, },
99 [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, }, 99 [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, },
100
101 [IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, },
102
103 [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, },
104 [IWL_TM_ATTR_TRACE_DATA] = { .type = NLA_UNSPEC, },
105
106 [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, },
100}; 107};
101 108
102/* 109/*
@@ -167,6 +174,31 @@ nla_put_failure:
167void iwl_testmode_init(struct iwl_priv *priv) 174void iwl_testmode_init(struct iwl_priv *priv)
168{ 175{
169 priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt; 176 priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
177 priv->testmode_trace.trace_enabled = false;
178}
179
180static void iwl_trace_cleanup(struct iwl_priv *priv)
181{
182 struct device *dev = &priv->pci_dev->dev;
183
184 if (priv->testmode_trace.trace_enabled) {
185 if (priv->testmode_trace.cpu_addr &&
186 priv->testmode_trace.dma_addr)
187 dma_free_coherent(dev,
188 TRACE_TOTAL_SIZE,
189 priv->testmode_trace.cpu_addr,
190 priv->testmode_trace.dma_addr);
191 priv->testmode_trace.trace_enabled = false;
192 priv->testmode_trace.cpu_addr = NULL;
193 priv->testmode_trace.trace_addr = NULL;
194 priv->testmode_trace.dma_addr = 0;
195 }
196}
197
198
199void iwl_testmode_cleanup(struct iwl_priv *priv)
200{
201 iwl_trace_cleanup(priv);
170} 202}
171 203
172/* 204/*
@@ -198,10 +230,11 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
198 } 230 }
199 231
200 cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]); 232 cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]);
201 cmd.data = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); 233 cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
202 cmd.len = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]); 234 cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
235 cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
203 IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x," 236 IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x,"
204 " len %d\n", cmd.id, cmd.flags, cmd.len); 237 " len %d\n", cmd.id, cmd.flags, cmd.len[0]);
205 /* ok, let's submit the command to ucode */ 238 /* ok, let's submit the command to ucode */
206 return iwl_send_cmd(priv, &cmd); 239 return iwl_send_cmd(priv, &cmd);
207} 240}
@@ -388,6 +421,38 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
388 "Error starting the device: %d\n", status); 421 "Error starting the device: %d\n", status);
389 break; 422 break;
390 423
424 case IWL_TM_CMD_APP2DEV_GET_EEPROM:
425 if (priv->eeprom) {
426 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
427 priv->cfg->base_params->eeprom_size + 20);
428 if (!skb) {
429 IWL_DEBUG_INFO(priv,
430 "Error allocating memory\n");
431 return -ENOMEM;
432 }
433 NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
434 IWL_TM_CMD_DEV2APP_EEPROM_RSP);
435 NLA_PUT(skb, IWL_TM_ATTR_EEPROM,
436 priv->cfg->base_params->eeprom_size,
437 priv->eeprom);
438 status = cfg80211_testmode_reply(skb);
439 if (status < 0)
440 IWL_DEBUG_INFO(priv,
441 "Error sending msg : %d\n",
442 status);
443 } else
444 return -EFAULT;
445 break;
446
447 case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
448 if (!tb[IWL_TM_ATTR_FIXRATE]) {
449 IWL_DEBUG_INFO(priv,
450 "Error finding fixrate setting\n");
451 return -ENOMSG;
452 }
453 priv->dbg_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]);
454 break;
455
391 default: 456 default:
392 IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n"); 457 IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n");
393 return -ENOSYS; 458 return -ENOSYS;
@@ -399,6 +464,102 @@ nla_put_failure:
399 return -EMSGSIZE; 464 return -EMSGSIZE;
400} 465}
401 466
467
468/*
469 * This function handles the user application commands for uCode trace
470 *
471 * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
472 * handlers respectively.
473 *
474 * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned
475 * value of the actual command execution is replied to the user application.
476 *
477 * @hw: ieee80211_hw object that represents the device
478 * @tb: gnl message fields from the user space
479 */
480static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
481{
482 struct iwl_priv *priv = hw->priv;
483 struct sk_buff *skb;
484 int status = 0;
485 struct device *dev = &priv->pci_dev->dev;
486
487 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
488 case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
489 if (priv->testmode_trace.trace_enabled)
490 return -EBUSY;
491
492 priv->testmode_trace.cpu_addr =
493 dma_alloc_coherent(dev,
494 TRACE_TOTAL_SIZE,
495 &priv->testmode_trace.dma_addr,
496 GFP_KERNEL);
497 if (!priv->testmode_trace.cpu_addr)
498 return -ENOMEM;
499 priv->testmode_trace.trace_enabled = true;
500 priv->testmode_trace.trace_addr = (u8 *)PTR_ALIGN(
501 priv->testmode_trace.cpu_addr, 0x100);
502 memset(priv->testmode_trace.trace_addr, 0x03B,
503 TRACE_BUFF_SIZE);
504 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
505 sizeof(priv->testmode_trace.dma_addr) + 20);
506 if (!skb) {
507 IWL_DEBUG_INFO(priv,
508 "Error allocating memory\n");
509 iwl_trace_cleanup(priv);
510 return -ENOMEM;
511 }
512 NLA_PUT(skb, IWL_TM_ATTR_TRACE_ADDR,
513 sizeof(priv->testmode_trace.dma_addr),
514 (u64 *)&priv->testmode_trace.dma_addr);
515 status = cfg80211_testmode_reply(skb);
516 if (status < 0) {
517 IWL_DEBUG_INFO(priv,
518 "Error sending msg : %d\n",
519 status);
520 }
521 break;
522
523 case IWL_TM_CMD_APP2DEV_END_TRACE:
524 iwl_trace_cleanup(priv);
525 break;
526
527 case IWL_TM_CMD_APP2DEV_READ_TRACE:
528 if (priv->testmode_trace.trace_enabled &&
529 priv->testmode_trace.trace_addr) {
530 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
531 20 + TRACE_BUFF_SIZE);
532 if (skb == NULL) {
533 IWL_DEBUG_INFO(priv,
534 "Error allocating memory\n");
535 return -ENOMEM;
536 }
537 NLA_PUT(skb, IWL_TM_ATTR_TRACE_DATA,
538 TRACE_BUFF_SIZE,
539 priv->testmode_trace.trace_addr);
540 status = cfg80211_testmode_reply(skb);
541 if (status < 0) {
542 IWL_DEBUG_INFO(priv,
543 "Error sending msg : %d\n", status);
544 }
545 } else
546 return -EFAULT;
547 break;
548
549 default:
550 IWL_DEBUG_INFO(priv, "Unknown testmode mem command ID\n");
551 return -ENOSYS;
552 }
553 return status;
554
555nla_put_failure:
556 kfree_skb(skb);
557 if (nla_get_u32(tb[IWL_TM_ATTR_COMMAND]) ==
558 IWL_TM_CMD_APP2DEV_BEGIN_TRACE)
559 iwl_trace_cleanup(priv);
560 return -EMSGSIZE;
561}
562
402/* The testmode gnl message handler that takes the gnl message from the 563/* The testmode gnl message handler that takes the gnl message from the
403 * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then 564 * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
404 * invoke the corresponding handlers. 565 * invoke the corresponding handlers.
@@ -455,9 +616,19 @@ int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
455 case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: 616 case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
456 case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: 617 case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
457 case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: 618 case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
619 case IWL_TM_CMD_APP2DEV_GET_EEPROM:
620 case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
458 IWL_DEBUG_INFO(priv, "testmode cmd to driver\n"); 621 IWL_DEBUG_INFO(priv, "testmode cmd to driver\n");
459 result = iwl_testmode_driver(hw, tb); 622 result = iwl_testmode_driver(hw, tb);
460 break; 623 break;
624
625 case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
626 case IWL_TM_CMD_APP2DEV_END_TRACE:
627 case IWL_TM_CMD_APP2DEV_READ_TRACE:
628 IWL_DEBUG_INFO(priv, "testmode uCode trace cmd to driver\n");
629 result = iwl_testmode_trace(hw, tb);
630 break;
631
461 default: 632 default:
462 IWL_DEBUG_INFO(priv, "Unknown testmode command\n"); 633 IWL_DEBUG_INFO(priv, "Unknown testmode command\n");
463 result = -ENOSYS; 634 result = -ENOSYS;
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h
index 31f8949f2801..a88085e9b361 100644
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.h
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h
@@ -88,9 +88,15 @@ enum iwl_tm_cmd_t {
88 IWL_TM_CMD_APP2DEV_LOAD_INIT_FW, 88 IWL_TM_CMD_APP2DEV_LOAD_INIT_FW,
89 IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB, 89 IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB,
90 IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW, 90 IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW,
91 IWL_TM_CMD_APP2DEV_GET_EEPROM,
92 IWL_TM_CMD_APP2DEV_FIXRATE_REQ,
91 /* if there is other new command for the driver layer operation, 93 /* if there is other new command for the driver layer operation,
92 * append them here */ 94 * append them here */
93 95
96 /* commands fom user space for uCode trace operations */
97 IWL_TM_CMD_APP2DEV_BEGIN_TRACE,
98 IWL_TM_CMD_APP2DEV_END_TRACE,
99 IWL_TM_CMD_APP2DEV_READ_TRACE,
94 100
95 /* commands from kernel space to carry the synchronous response 101 /* commands from kernel space to carry the synchronous response
96 * to user application */ 102 * to user application */
@@ -99,6 +105,11 @@ enum iwl_tm_cmd_t {
99 /* commands from kernel space to multicast the spontaneous messages 105 /* commands from kernel space to multicast the spontaneous messages
100 * to user application */ 106 * to user application */
101 IWL_TM_CMD_DEV2APP_UCODE_RX_PKT, 107 IWL_TM_CMD_DEV2APP_UCODE_RX_PKT,
108
109 /* commands from kernel space to carry the eeprom response
110 * to user application */
111 IWL_TM_CMD_DEV2APP_EEPROM_RSP,
112
102 IWL_TM_CMD_MAX, 113 IWL_TM_CMD_MAX,
103}; 114};
104 115
@@ -144,8 +155,31 @@ enum iwl_tm_attr_t {
144 * application */ 155 * application */
145 IWL_TM_ATTR_UCODE_RX_PKT, 156 IWL_TM_ATTR_UCODE_RX_PKT,
146 157
158 /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_EEPROM,
159 * The mandatory fields are:
160 * IWL_TM_ATTR_EEPROM for the data content responging to the user
161 * application */
162 IWL_TM_ATTR_EEPROM,
163
164 /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_XXX_TRACE,
165 * The mandatory fields are:
166 * IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address
167 */
168 IWL_TM_ATTR_TRACE_ADDR,
169 IWL_TM_ATTR_TRACE_DATA,
170
171 /* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ,
172 * The mandatory fields are:
173 * IWL_TM_ATTR_FIXRATE for the fixed rate
174 */
175 IWL_TM_ATTR_FIXRATE,
176
147 IWL_TM_ATTR_MAX, 177 IWL_TM_ATTR_MAX,
148}; 178};
149 179
180/* uCode trace buffer */
181#define TRACE_BUFF_SIZE 0x20000
182#define TRACE_BUFF_PADD 0x2000
183#define TRACE_TOTAL_SIZE (TRACE_BUFF_SIZE + TRACE_BUFF_PADD)
150 184
151#endif 185#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index e69597ea43e2..686e176b5ebd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -32,6 +32,7 @@
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <net/mac80211.h> 33#include <net/mac80211.h>
34#include "iwl-eeprom.h" 34#include "iwl-eeprom.h"
35#include "iwl-agn.h"
35#include "iwl-dev.h" 36#include "iwl-dev.h"
36#include "iwl-core.h" 37#include "iwl-core.h"
37#include "iwl-sta.h" 38#include "iwl-sta.h"
@@ -85,6 +86,158 @@ void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
85 txq->need_update = 0; 86 txq->need_update = 0;
86} 87}
87 88
89static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
90{
91 struct iwl_tfd_tb *tb = &tfd->tbs[idx];
92
93 dma_addr_t addr = get_unaligned_le32(&tb->lo);
94 if (sizeof(dma_addr_t) > sizeof(u32))
95 addr |=
96 ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;
97
98 return addr;
99}
100
101static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
102{
103 struct iwl_tfd_tb *tb = &tfd->tbs[idx];
104
105 return le16_to_cpu(tb->hi_n_len) >> 4;
106}
107
108static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
109 dma_addr_t addr, u16 len)
110{
111 struct iwl_tfd_tb *tb = &tfd->tbs[idx];
112 u16 hi_n_len = len << 4;
113
114 put_unaligned_le32(addr, &tb->lo);
115 if (sizeof(dma_addr_t) > sizeof(u32))
116 hi_n_len |= ((addr >> 16) >> 16) & 0xF;
117
118 tb->hi_n_len = cpu_to_le16(hi_n_len);
119
120 tfd->num_tbs = idx + 1;
121}
122
123static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
124{
125 return tfd->num_tbs & 0x1f;
126}
127
128static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta,
129 struct iwl_tfd *tfd)
130{
131 struct pci_dev *dev = priv->pci_dev;
132 int i;
133 int num_tbs;
134
135 /* Sanity check on number of chunks */
136 num_tbs = iwl_tfd_get_num_tbs(tfd);
137
138 if (num_tbs >= IWL_NUM_OF_TBS) {
139 IWL_ERR(priv, "Too many chunks: %i\n", num_tbs);
140 /* @todo issue fatal error, it is quite serious situation */
141 return;
142 }
143
144 /* Unmap tx_cmd */
145 if (num_tbs)
146 pci_unmap_single(dev,
147 dma_unmap_addr(meta, mapping),
148 dma_unmap_len(meta, len),
149 PCI_DMA_BIDIRECTIONAL);
150
151 /* Unmap chunks, if any. */
152 for (i = 1; i < num_tbs; i++)
153 pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
154 iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE);
155}
156
157/**
158 * iwlagn_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
159 * @priv - driver private data
160 * @txq - tx queue
161 *
162 * Does NOT advance any TFD circular buffer read/write indexes
163 * Does NOT free the TFD itself (which is within circular buffer)
164 */
165void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
166{
167 struct iwl_tfd *tfd_tmp = txq->tfds;
168 int index = txq->q.read_ptr;
169
170 iwlagn_unmap_tfd(priv, &txq->meta[index], &tfd_tmp[index]);
171
172 /* free SKB */
173 if (txq->txb) {
174 struct sk_buff *skb;
175
176 skb = txq->txb[txq->q.read_ptr].skb;
177
178 /* can be called from irqs-disabled context */
179 if (skb) {
180 dev_kfree_skb_any(skb);
181 txq->txb[txq->q.read_ptr].skb = NULL;
182 }
183 }
184}
185
186int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv,
187 struct iwl_tx_queue *txq,
188 dma_addr_t addr, u16 len,
189 u8 reset)
190{
191 struct iwl_queue *q;
192 struct iwl_tfd *tfd, *tfd_tmp;
193 u32 num_tbs;
194
195 q = &txq->q;
196 tfd_tmp = txq->tfds;
197 tfd = &tfd_tmp[q->write_ptr];
198
199 if (reset)
200 memset(tfd, 0, sizeof(*tfd));
201
202 num_tbs = iwl_tfd_get_num_tbs(tfd);
203
204 /* Each TFD can point to a maximum 20 Tx buffers */
205 if (num_tbs >= IWL_NUM_OF_TBS) {
206 IWL_ERR(priv, "Error can not send more than %d chunks\n",
207 IWL_NUM_OF_TBS);
208 return -EINVAL;
209 }
210
211 if (WARN_ON(addr & ~DMA_BIT_MASK(36)))
212 return -EINVAL;
213
214 if (unlikely(addr & ~IWL_TX_DMA_MASK))
215 IWL_ERR(priv, "Unaligned address = %llx\n",
216 (unsigned long long)addr);
217
218 iwl_tfd_set_tb(tfd, num_tbs, addr, len);
219
220 return 0;
221}
222
223/*
224 * Tell nic where to find circular buffer of Tx Frame Descriptors for
225 * given Tx queue, and enable the DMA channel used for that queue.
226 *
227 * supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
228 * channels supported in hardware.
229 */
230static int iwlagn_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
231{
232 int txq_id = txq->q.id;
233
234 /* Circular buffer (TFD queue in DRAM) physical base address */
235 iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
236 txq->q.dma_addr >> 8);
237
238 return 0;
239}
240
88/** 241/**
89 * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's 242 * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's
90 */ 243 */
@@ -97,7 +250,7 @@ void iwl_tx_queue_unmap(struct iwl_priv *priv, int txq_id)
97 return; 250 return;
98 251
99 while (q->write_ptr != q->read_ptr) { 252 while (q->write_ptr != q->read_ptr) {
100 priv->cfg->ops->lib->txq_free_tfd(priv, txq); 253 iwlagn_txq_free_tfd(priv, txq);
101 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); 254 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
102 } 255 }
103} 256}
@@ -154,7 +307,7 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv)
154 return; 307 return;
155 308
156 while (q->read_ptr != q->write_ptr) { 309 while (q->read_ptr != q->write_ptr) {
157 i = get_cmd_index(q, q->read_ptr, 0); 310 i = get_cmd_index(q, q->read_ptr);
158 311
159 if (txq->meta[i].flags & CMD_MAPPED) { 312 if (txq->meta[i].flags & CMD_MAPPED) {
160 pci_unmap_single(priv->pci_dev, 313 pci_unmap_single(priv->pci_dev,
@@ -166,15 +319,6 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv)
166 319
167 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); 320 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
168 } 321 }
169
170 i = q->n_window;
171 if (txq->meta[i].flags & CMD_MAPPED) {
172 pci_unmap_single(priv->pci_dev,
173 dma_unmap_addr(&txq->meta[i], mapping),
174 dma_unmap_len(&txq->meta[i], len),
175 PCI_DMA_BIDIRECTIONAL);
176 txq->meta[i].flags = 0;
177 }
178} 322}
179 323
180/** 324/**
@@ -194,7 +338,7 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
194 iwl_cmd_queue_unmap(priv); 338 iwl_cmd_queue_unmap(priv);
195 339
196 /* De-alloc array of command/tx buffers */ 340 /* De-alloc array of command/tx buffers */
197 for (i = 0; i <= TFD_CMD_SLOTS; i++) 341 for (i = 0; i < TFD_CMD_SLOTS; i++)
198 kfree(txq->cmd[i]); 342 kfree(txq->cmd[i]);
199 343
200 /* De-alloc circular buffer of TFDs */ 344 /* De-alloc circular buffer of TFDs */
@@ -334,33 +478,17 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
334{ 478{
335 int i, len; 479 int i, len;
336 int ret; 480 int ret;
337 int actual_slots = slots_num;
338
339 /*
340 * Alloc buffer array for commands (Tx or other types of commands).
341 * For the command queue (#4/#9), allocate command space + one big
342 * command for scan, since scan command is very huge; the system will
343 * not have two scans at the same time, so only one is needed.
344 * For normal Tx queues (all other queues), no super-size command
345 * space is needed.
346 */
347 if (txq_id == priv->cmd_queue)
348 actual_slots++;
349 481
350 txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * actual_slots, 482 txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * slots_num,
351 GFP_KERNEL); 483 GFP_KERNEL);
352 txq->cmd = kzalloc(sizeof(struct iwl_device_cmd *) * actual_slots, 484 txq->cmd = kzalloc(sizeof(struct iwl_device_cmd *) * slots_num,
353 GFP_KERNEL); 485 GFP_KERNEL);
354 486
355 if (!txq->meta || !txq->cmd) 487 if (!txq->meta || !txq->cmd)
356 goto out_free_arrays; 488 goto out_free_arrays;
357 489
358 len = sizeof(struct iwl_device_cmd); 490 len = sizeof(struct iwl_device_cmd);
359 for (i = 0; i < actual_slots; i++) { 491 for (i = 0; i < slots_num; i++) {
360 /* only happens for cmd queue */
361 if (i == slots_num)
362 len = IWL_MAX_CMD_SIZE;
363
364 txq->cmd[i] = kmalloc(len, GFP_KERNEL); 492 txq->cmd[i] = kmalloc(len, GFP_KERNEL);
365 if (!txq->cmd[i]) 493 if (!txq->cmd[i])
366 goto err; 494 goto err;
@@ -391,11 +519,11 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
391 return ret; 519 return ret;
392 520
393 /* Tell device where to find queue */ 521 /* Tell device where to find queue */
394 priv->cfg->ops->lib->txq_init(priv, txq); 522 iwlagn_tx_queue_init(priv, txq);
395 523
396 return 0; 524 return 0;
397err: 525err:
398 for (i = 0; i < actual_slots; i++) 526 for (i = 0; i < slots_num; i++)
399 kfree(txq->cmd[i]); 527 kfree(txq->cmd[i]);
400out_free_arrays: 528out_free_arrays:
401 kfree(txq->meta); 529 kfree(txq->meta);
@@ -420,7 +548,7 @@ void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq,
420 iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); 548 iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
421 549
422 /* Tell device where to find queue */ 550 /* Tell device where to find queue */
423 priv->cfg->ops->lib->txq_init(priv, txq); 551 iwlagn_tx_queue_init(priv, txq);
424} 552}
425 553
426/*************** HOST COMMAND QUEUE FUNCTIONS *****/ 554/*************** HOST COMMAND QUEUE FUNCTIONS *****/
@@ -443,23 +571,49 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
443 dma_addr_t phys_addr; 571 dma_addr_t phys_addr;
444 unsigned long flags; 572 unsigned long flags;
445 u32 idx; 573 u32 idx;
446 u16 fix_size; 574 u16 copy_size, cmd_size;
447 bool is_ct_kill = false; 575 bool is_ct_kill = false;
576 bool had_nocopy = false;
577 int i;
578 u8 *cmd_dest;
579#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
580 const void *trace_bufs[IWL_MAX_CMD_TFDS + 1] = {};
581 int trace_lens[IWL_MAX_CMD_TFDS + 1] = {};
582 int trace_idx;
583#endif
584
585 if (test_bit(STATUS_FW_ERROR, &priv->status)) {
586 IWL_WARN(priv, "fw recovery, no hcmd send\n");
587 return -EIO;
588 }
448 589
449 fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); 590 copy_size = sizeof(out_cmd->hdr);
591 cmd_size = sizeof(out_cmd->hdr);
592
593 /* need one for the header if the first is NOCOPY */
594 BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1);
595
596 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
597 if (!cmd->len[i])
598 continue;
599 if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) {
600 had_nocopy = true;
601 } else {
602 /* NOCOPY must not be followed by normal! */
603 if (WARN_ON(had_nocopy))
604 return -EINVAL;
605 copy_size += cmd->len[i];
606 }
607 cmd_size += cmd->len[i];
608 }
450 609
451 /* 610 /*
452 * If any of the command structures end up being larger than 611 * If any of the command structures end up being larger than
453 * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then 612 * the TFD_MAX_PAYLOAD_SIZE and they aren't dynamically
454 * we will need to increase the size of the TFD entries 613 * allocated into separate TFDs, then we will need to
455 * Also, check to see if command buffer should not exceed the size 614 * increase the size of the buffers.
456 * of device_cmd and max_cmd_size.
457 */ 615 */
458 if (WARN_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && 616 if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE))
459 !(cmd->flags & CMD_SIZE_HUGE)))
460 return -EINVAL;
461
462 if (WARN_ON(fix_size > IWL_MAX_CMD_SIZE))
463 return -EINVAL; 617 return -EINVAL;
464 618
465 if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) { 619 if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) {
@@ -468,14 +622,6 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
468 return -EIO; 622 return -EIO;
469 } 623 }
470 624
471 /*
472 * As we only have a single huge buffer, check that the command
473 * is synchronous (otherwise buffers could end up being reused).
474 */
475
476 if (WARN_ON((cmd->flags & CMD_ASYNC) && (cmd->flags & CMD_SIZE_HUGE)))
477 return -EINVAL;
478
479 spin_lock_irqsave(&priv->hcmd_lock, flags); 625 spin_lock_irqsave(&priv->hcmd_lock, flags);
480 626
481 if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { 627 if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
@@ -490,7 +636,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
490 return -ENOSPC; 636 return -ENOSPC;
491 } 637 }
492 638
493 idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); 639 idx = get_cmd_index(q, q->write_ptr);
494 out_cmd = txq->cmd[idx]; 640 out_cmd = txq->cmd[idx];
495 out_meta = &txq->meta[idx]; 641 out_meta = &txq->meta[idx];
496 642
@@ -505,57 +651,84 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
505 if (cmd->flags & CMD_ASYNC) 651 if (cmd->flags & CMD_ASYNC)
506 out_meta->callback = cmd->callback; 652 out_meta->callback = cmd->callback;
507 653
508 out_cmd->hdr.cmd = cmd->id; 654 /* set up the header */
509 memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
510
511 /* At this point, the out_cmd now has all of the incoming cmd
512 * information */
513 655
656 out_cmd->hdr.cmd = cmd->id;
514 out_cmd->hdr.flags = 0; 657 out_cmd->hdr.flags = 0;
515 out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(priv->cmd_queue) | 658 out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(priv->cmd_queue) |
516 INDEX_TO_SEQ(q->write_ptr)); 659 INDEX_TO_SEQ(q->write_ptr));
517 if (cmd->flags & CMD_SIZE_HUGE) 660
518 out_cmd->hdr.sequence |= SEQ_HUGE_FRAME; 661 /* and copy the data that needs to be copied */
519 662
520#ifdef CONFIG_IWLWIFI_DEBUG 663 cmd_dest = &out_cmd->cmd.payload[0];
521 switch (out_cmd->hdr.cmd) { 664 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
522 case REPLY_TX_LINK_QUALITY_CMD: 665 if (!cmd->len[i])
523 case SENSITIVITY_CMD: 666 continue;
524 IWL_DEBUG_HC_DUMP(priv, "Sending command %s (#%x), seq: 0x%04X, " 667 if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)
525 "%d bytes at %d[%d]:%d\n", 668 break;
526 get_cmd_string(out_cmd->hdr.cmd), 669 memcpy(cmd_dest, cmd->data[i], cmd->len[i]);
527 out_cmd->hdr.cmd, 670 cmd_dest += cmd->len[i];
528 le16_to_cpu(out_cmd->hdr.sequence), fix_size,
529 q->write_ptr, idx, priv->cmd_queue);
530 break;
531 default:
532 IWL_DEBUG_HC(priv, "Sending command %s (#%x), seq: 0x%04X, "
533 "%d bytes at %d[%d]:%d\n",
534 get_cmd_string(out_cmd->hdr.cmd),
535 out_cmd->hdr.cmd,
536 le16_to_cpu(out_cmd->hdr.sequence), fix_size,
537 q->write_ptr, idx, priv->cmd_queue);
538 } 671 }
539#endif 672
673 IWL_DEBUG_HC(priv, "Sending command %s (#%x), seq: 0x%04X, "
674 "%d bytes at %d[%d]:%d\n",
675 get_cmd_string(out_cmd->hdr.cmd),
676 out_cmd->hdr.cmd,
677 le16_to_cpu(out_cmd->hdr.sequence), cmd_size,
678 q->write_ptr, idx, priv->cmd_queue);
679
540 phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr, 680 phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr,
541 fix_size, PCI_DMA_BIDIRECTIONAL); 681 copy_size, PCI_DMA_BIDIRECTIONAL);
542 if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) { 682 if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) {
543 idx = -ENOMEM; 683 idx = -ENOMEM;
544 goto out; 684 goto out;
545 } 685 }
546 686
547 dma_unmap_addr_set(out_meta, mapping, phys_addr); 687 dma_unmap_addr_set(out_meta, mapping, phys_addr);
548 dma_unmap_len_set(out_meta, len, fix_size); 688 dma_unmap_len_set(out_meta, len, copy_size);
689
690 iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr, copy_size, 1);
691#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
692 trace_bufs[0] = &out_cmd->hdr;
693 trace_lens[0] = copy_size;
694 trace_idx = 1;
695#endif
696
697 for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
698 if (!cmd->len[i])
699 continue;
700 if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
701 continue;
702 phys_addr = pci_map_single(priv->pci_dev, (void *)cmd->data[i],
703 cmd->len[i], PCI_DMA_TODEVICE);
704 if (pci_dma_mapping_error(priv->pci_dev, phys_addr)) {
705 iwlagn_unmap_tfd(priv, out_meta,
706 &txq->tfds[q->write_ptr]);
707 idx = -ENOMEM;
708 goto out;
709 }
710
711 iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr,
712 cmd->len[i], 0);
713#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
714 trace_bufs[trace_idx] = cmd->data[i];
715 trace_lens[trace_idx] = cmd->len[i];
716 trace_idx++;
717#endif
718 }
549 719
550 out_meta->flags = cmd->flags | CMD_MAPPED; 720 out_meta->flags = cmd->flags | CMD_MAPPED;
551 721
552 txq->need_update = 1; 722 txq->need_update = 1;
553 723
554 trace_iwlwifi_dev_hcmd(priv, &out_cmd->hdr, fix_size, cmd->flags); 724 /* check that tracing gets all possible blocks */
555 725 BUILD_BUG_ON(IWL_MAX_CMD_TFDS + 1 != 3);
556 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, 726#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
557 phys_addr, fix_size, 1, 727 trace_iwlwifi_dev_hcmd(priv, cmd->flags,
558 U32_PAD(cmd->len)); 728 trace_bufs[0], trace_lens[0],
729 trace_bufs[1], trace_lens[1],
730 trace_bufs[2], trace_lens[2]);
731#endif
559 732
560 /* Increment and update queue's write index */ 733 /* Increment and update queue's write index */
561 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); 734 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
@@ -573,8 +746,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
573 * need to be reclaimed. As result, some free space forms. If there is 746 * need to be reclaimed. As result, some free space forms. If there is
574 * enough free space (> low mark), wake the stack that feeds us. 747 * enough free space (> low mark), wake the stack that feeds us.
575 */ 748 */
576static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, 749static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int idx)
577 int idx, int cmd_idx)
578{ 750{
579 struct iwl_tx_queue *txq = &priv->txq[txq_id]; 751 struct iwl_tx_queue *txq = &priv->txq[txq_id];
580 struct iwl_queue *q = &txq->q; 752 struct iwl_queue *q = &txq->q;
@@ -614,7 +786,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
614 int txq_id = SEQ_TO_QUEUE(sequence); 786 int txq_id = SEQ_TO_QUEUE(sequence);
615 int index = SEQ_TO_INDEX(sequence); 787 int index = SEQ_TO_INDEX(sequence);
616 int cmd_index; 788 int cmd_index;
617 bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
618 struct iwl_device_cmd *cmd; 789 struct iwl_device_cmd *cmd;
619 struct iwl_cmd_meta *meta; 790 struct iwl_cmd_meta *meta;
620 struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; 791 struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
@@ -632,14 +803,11 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
632 return; 803 return;
633 } 804 }
634 805
635 cmd_index = get_cmd_index(&txq->q, index, huge); 806 cmd_index = get_cmd_index(&txq->q, index);
636 cmd = txq->cmd[cmd_index]; 807 cmd = txq->cmd[cmd_index];
637 meta = &txq->meta[cmd_index]; 808 meta = &txq->meta[cmd_index];
638 809
639 pci_unmap_single(priv->pci_dev, 810 iwlagn_unmap_tfd(priv, meta, &txq->tfds[index]);
640 dma_unmap_addr(meta, mapping),
641 dma_unmap_len(meta, len),
642 PCI_DMA_BIDIRECTIONAL);
643 811
644 /* Input error checking is done when commands are added to queue. */ 812 /* Input error checking is done when commands are added to queue. */
645 if (meta->flags & CMD_WANT_SKB) { 813 if (meta->flags & CMD_WANT_SKB) {
@@ -650,7 +818,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
650 818
651 spin_lock_irqsave(&priv->hcmd_lock, flags); 819 spin_lock_irqsave(&priv->hcmd_lock, flags);
652 820
653 iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); 821 iwl_hcmd_queue_reclaim(priv, txq_id, index);
654 822
655 if (!(meta->flags & CMD_ASYNC)) { 823 if (!(meta->flags & CMD_ASYNC)) {
656 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 824 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 5665a1a9b99e..a414768f40f1 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -565,7 +565,7 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
565 if (!test_and_clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status) 565 if (!test_and_clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status)
566 && iwm->conf.mode == UMAC_MODE_BSS) { 566 && iwm->conf.mode == UMAC_MODE_BSS) {
567 cancel_delayed_work(&iwm->disconnect); 567 cancel_delayed_work(&iwm->disconnect);
568 cfg80211_roamed(iwm_to_ndev(iwm), 568 cfg80211_roamed(iwm_to_ndev(iwm), NULL,
569 complete->bssid, 569 complete->bssid,
570 iwm->req_ie, iwm->req_ie_len, 570 iwm->req_ie, iwm->req_ie_len,
571 iwm->resp_ie, iwm->resp_ie_len, 571 iwm->resp_ie, iwm->resp_ie_len,
@@ -586,7 +586,7 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
586 WLAN_STATUS_SUCCESS, 586 WLAN_STATUS_SUCCESS,
587 GFP_KERNEL); 587 GFP_KERNEL);
588 else 588 else
589 cfg80211_roamed(iwm_to_ndev(iwm), 589 cfg80211_roamed(iwm_to_ndev(iwm), NULL,
590 complete->bssid, 590 complete->bssid,
591 iwm->req_ie, iwm->req_ie_len, 591 iwm->req_ie, iwm->req_ie_len,
592 iwm->resp_ie, iwm->resp_ie_len, 592 iwm->resp_ie, iwm->resp_ie_len,
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index d3d5e0853c45..f807447e4d99 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -196,6 +196,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
196 if (skb_src) 196 if (skb_src)
197 pra_list->total_pkts_size -= skb_src->len; 197 pra_list->total_pkts_size -= skb_src->len;
198 198
199 atomic_dec(&priv->wmm.tx_pkts_queued);
200
199 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 201 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
200 ra_list_flags); 202 ra_list_flags);
201 mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad); 203 mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad);
@@ -257,6 +259,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
257 259
258 pra_list->total_pkts_size += skb_aggr->len; 260 pra_list->total_pkts_size += skb_aggr->len;
259 261
262 atomic_inc(&priv->wmm.tx_pkts_queued);
263
260 tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT; 264 tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
261 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 265 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
262 ra_list_flags); 266 ra_list_flags);
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 672701dc2721..8316b3cd92cd 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -69,7 +69,8 @@ struct mwifiex_drv_mode {
69#define MWIFIEX_TIMER_10S 10000 69#define MWIFIEX_TIMER_10S 10000
70#define MWIFIEX_TIMER_1S 1000 70#define MWIFIEX_TIMER_1S 1000
71 71
72#define MAX_TX_PENDING 60 72#define MAX_TX_PENDING 100
73#define LOW_TX_PENDING 80
73 74
74#define MWIFIEX_UPLD_SIZE (2312) 75#define MWIFIEX_UPLD_SIZE (2312)
75 76
@@ -202,6 +203,7 @@ struct mwifiex_tid_tbl {
202#define WMM_HIGHEST_PRIORITY 7 203#define WMM_HIGHEST_PRIORITY 7
203#define HIGH_PRIO_TID 7 204#define HIGH_PRIO_TID 7
204#define LOW_PRIO_TID 0 205#define LOW_PRIO_TID 0
206#define NO_PKT_PRIO_TID (-1)
205 207
206struct mwifiex_wmm_desc { 208struct mwifiex_wmm_desc {
207 struct mwifiex_tid_tbl tid_tbl_ptr[MAX_NUM_TID]; 209 struct mwifiex_tid_tbl tid_tbl_ptr[MAX_NUM_TID];
@@ -213,7 +215,10 @@ struct mwifiex_wmm_desc {
213 u32 drv_pkt_delay_max; 215 u32 drv_pkt_delay_max;
214 u8 queue_priority[IEEE80211_MAX_QUEUES]; 216 u8 queue_priority[IEEE80211_MAX_QUEUES];
215 u32 user_pri_pkt_tx_ctrl[WMM_HIGHEST_PRIORITY + 1]; /* UP: 0 to 7 */ 217 u32 user_pri_pkt_tx_ctrl[WMM_HIGHEST_PRIORITY + 1]; /* UP: 0 to 7 */
216 218 /* Number of transmit packets queued */
219 atomic_t tx_pkts_queued;
220 /* Tracks highest priority with a packet queued */
221 atomic_t highest_queued_prio;
217}; 222};
218 223
219struct mwifiex_802_11_security { 224struct mwifiex_802_11_security {
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index 210120889dfe..aaa50c074196 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -140,7 +140,9 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
140 } else { 140 } else {
141 priv->stats.tx_errors++; 141 priv->stats.tx_errors++;
142 } 142 }
143 atomic_dec(&adapter->tx_pending); 143
144 if (atomic_dec_return(&adapter->tx_pending) >= LOW_TX_PENDING)
145 goto done;
144 146
145 for (i = 0; i < adapter->priv_num; i++) { 147 for (i = 0; i < adapter->priv_num; i++) {
146 148
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index faa09e32902e..91634daec306 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -177,14 +177,20 @@ static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv)
177 * This function map ACs to TIDs. 177 * This function map ACs to TIDs.
178 */ 178 */
179static void 179static void
180mwifiex_wmm_queue_priorities_tid(u8 queue_priority[]) 180mwifiex_wmm_queue_priorities_tid(struct mwifiex_wmm_desc *wmm)
181{ 181{
182 u8 *queue_priority = wmm->queue_priority;
182 int i; 183 int i;
183 184
184 for (i = 0; i < 4; ++i) { 185 for (i = 0; i < 4; ++i) {
185 tos_to_tid[7 - (i * 2)] = ac_to_tid[queue_priority[i]][1]; 186 tos_to_tid[7 - (i * 2)] = ac_to_tid[queue_priority[i]][1];
186 tos_to_tid[6 - (i * 2)] = ac_to_tid[queue_priority[i]][0]; 187 tos_to_tid[6 - (i * 2)] = ac_to_tid[queue_priority[i]][0];
187 } 188 }
189
190 for (i = 0; i < MAX_NUM_TID; ++i)
191 tos_to_tid_inv[tos_to_tid[i]] = (u8)i;
192
193 atomic_set(&wmm->highest_queued_prio, HIGH_PRIO_TID);
188} 194}
189 195
190/* 196/*
@@ -246,7 +252,7 @@ mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv,
246 } 252 }
247 } 253 }
248 254
249 mwifiex_wmm_queue_priorities_tid(priv->wmm.queue_priority); 255 mwifiex_wmm_queue_priorities_tid(&priv->wmm);
250} 256}
251 257
252/* 258/*
@@ -399,6 +405,9 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter)
399 priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT; 405 priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT;
400 priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; 406 priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE;
401 priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; 407 priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE;
408
409 atomic_set(&priv->wmm.tx_pkts_queued, 0);
410 atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID);
402 } 411 }
403} 412}
404 413
@@ -408,17 +417,13 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter)
408int 417int
409mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter) 418mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter)
410{ 419{
411 int i, j; 420 int i;
412 struct mwifiex_private *priv; 421 struct mwifiex_private *priv;
413 422
414 for (j = 0; j < adapter->priv_num; ++j) { 423 for (i = 0; i < adapter->priv_num; ++i) {
415 priv = adapter->priv[j]; 424 priv = adapter->priv[i];
416 if (priv) { 425 if (priv && atomic_read(&priv->wmm.tx_pkts_queued))
417 for (i = 0; i < MAX_NUM_TID; i++) 426 return false;
418 if (!mwifiex_wmm_is_ra_list_empty(
419 &priv->wmm.tid_tbl_ptr[i].ra_list))
420 return false;
421 }
422 } 427 }
423 428
424 return true; 429 return true;
@@ -468,6 +473,9 @@ static void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv)
468 for (i = 0; i < MAX_NUM_TID; i++) 473 for (i = 0; i < MAX_NUM_TID; i++)
469 mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i]. 474 mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i].
470 ra_list); 475 ra_list);
476
477 atomic_set(&priv->wmm.tx_pkts_queued, 0);
478 atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID);
471} 479}
472 480
473/* 481/*
@@ -638,6 +646,13 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
638 646
639 ra_list->total_pkts_size += skb->len; 647 ra_list->total_pkts_size += skb->len;
640 648
649 atomic_inc(&priv->wmm.tx_pkts_queued);
650
651 if (atomic_read(&priv->wmm.highest_queued_prio) <
652 tos_to_tid_inv[tid_down])
653 atomic_set(&priv->wmm.highest_queued_prio,
654 tos_to_tid_inv[tid_down]);
655
641 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); 656 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
642} 657}
643 658
@@ -863,9 +878,14 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
863 } 878 }
864 879
865 do { 880 do {
881 atomic_t *hqp;
882 spinlock_t *lock;
883
866 priv_tmp = bssprio_node->priv; 884 priv_tmp = bssprio_node->priv;
885 hqp = &priv_tmp->wmm.highest_queued_prio;
886 lock = &priv_tmp->wmm.ra_list_spinlock;
867 887
868 for (i = HIGH_PRIO_TID; i >= LOW_PRIO_TID; --i) { 888 for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) {
869 889
870 tid_ptr = &(priv_tmp)->wmm. 890 tid_ptr = &(priv_tmp)->wmm.
871 tid_tbl_ptr[tos_to_tid[i]]; 891 tid_tbl_ptr[tos_to_tid[i]];
@@ -903,6 +923,11 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
903 is_list_empty = 923 is_list_empty =
904 skb_queue_empty(&ptr->skb_head); 924 skb_queue_empty(&ptr->skb_head);
905 if (!is_list_empty) { 925 if (!is_list_empty) {
926 spin_lock_irqsave(lock, flags);
927 if (atomic_read(hqp) > i)
928 atomic_set(hqp, i);
929 spin_unlock_irqrestore(lock,
930 flags);
906 *priv = priv_tmp; 931 *priv = priv_tmp;
907 *tid = tos_to_tid[i]; 932 *tid = tos_to_tid[i];
908 return ptr; 933 return ptr;
@@ -921,6 +946,12 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
921 } while (ptr != head); 946 } while (ptr != head);
922 } 947 }
923 948
949 /* No packet at any TID for this priv. Mark as such
950 * to skip checking TIDs for this priv (until pkt is
951 * added).
952 */
953 atomic_set(hqp, NO_PKT_PRIO_TID);
954
924 /* Get next bss priority node */ 955 /* Get next bss priority node */
925 bssprio_node = list_first_entry(&bssprio_node->list, 956 bssprio_node = list_first_entry(&bssprio_node->list,
926 struct mwifiex_bss_prio_node, 957 struct mwifiex_bss_prio_node,
@@ -1028,6 +1059,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv,
1028 .bss_prio_cur->list, 1059 .bss_prio_cur->list,
1029 struct mwifiex_bss_prio_node, 1060 struct mwifiex_bss_prio_node,
1030 list); 1061 list);
1062 atomic_dec(&priv->wmm.tx_pkts_queued);
1031 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 1063 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1032 ra_list_flags); 1064 ra_list_flags);
1033 } 1065 }
@@ -1134,6 +1166,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
1134 .bss_prio_cur->list, 1166 .bss_prio_cur->list,
1135 struct mwifiex_bss_prio_node, 1167 struct mwifiex_bss_prio_node,
1136 list); 1168 list);
1169 atomic_dec(&priv->wmm.tx_pkts_queued);
1137 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 1170 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1138 ra_list_flags); 1171 ra_list_flags);
1139 } 1172 }
@@ -1227,5 +1260,5 @@ mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter)
1227 1260
1228 if (mwifiex_dequeue_tx_packet(adapter)) 1261 if (mwifiex_dequeue_tx_packet(adapter))
1229 break; 1262 break;
1230 } while (true); 1263 } while (!mwifiex_wmm_lists_empty(adapter));
1231} 1264}
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index e18358725b69..a8f3bc740dfa 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -82,6 +82,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
82 {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ 82 {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */
83 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ 83 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
84 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ 84 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
85 {USB_DEVICE(0x083a, 0xc501)}, /* Zoom Wireless-G 4410 */
85 {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */ 86 {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */
86 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */ 87 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */
87 {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */ 88 {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 518542b4bf9e..29f938930667 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -2830,7 +2830,8 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
2830 req_ie_len, resp_ie, 2830 req_ie_len, resp_ie,
2831 resp_ie_len, 0, GFP_KERNEL); 2831 resp_ie_len, 0, GFP_KERNEL);
2832 else 2832 else
2833 cfg80211_roamed(usbdev->net, bssid, req_ie, req_ie_len, 2833 cfg80211_roamed(usbdev->net, NULL, bssid,
2834 req_ie, req_ie_len,
2834 resp_ie, resp_ie_len, GFP_KERNEL); 2835 resp_ie, resp_ie_len, GFP_KERNEL);
2835 } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) 2836 } else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
2836 cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL); 2837 cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c
index 2bb71195e976..39b0297ce925 100644
--- a/drivers/net/wireless/rtlwifi/ps.c
+++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -190,7 +190,7 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw)
190 190
191 ppsc->swrf_processing = true; 191 ppsc->swrf_processing = true;
192 192
193 if (ppsc->inactive_pwrstate == ERFOFF && 193 if (ppsc->inactive_pwrstate == ERFON &&
194 rtlhal->interface == INTF_PCI) { 194 rtlhal->interface == INTF_PCI) {
195 if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && 195 if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
196 RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) && 196 RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
index c5424cad43cb..d2cc81586a6a 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
@@ -728,7 +728,7 @@ void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
728 return; 728 return;
729 rtlphy->set_bwmode_inprogress = true; 729 rtlphy->set_bwmode_inprogress = true;
730 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { 730 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
731 rtlphy->set_bwmode_inprogress = false; 731 rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw);
732 } else { 732 } else {
733 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 733 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
734 ("FALSE driver sleep or unload\n")); 734 ("FALSE driver sleep or unload\n"));
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
index 73ae8a431848..abe0fcc75368 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
@@ -366,6 +366,75 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
366 return true; 366 return true;
367} 367}
368 368
369void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
370{
371 struct rtl_priv *rtlpriv = rtl_priv(hw);
372 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
373 struct rtl_phy *rtlphy = &(rtlpriv->phy);
374 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
375 u8 reg_bw_opmode;
376 u8 reg_prsr_rsc;
377
378 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
379 ("Switch to %s bandwidth\n",
380 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
381 "20MHz" : "40MHz"))
382
383 if (is_hal_stop(rtlhal)) {
384 rtlphy->set_bwmode_inprogress = false;
385 return;
386 }
387
388 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
389 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
390
391 switch (rtlphy->current_chan_bw) {
392 case HT_CHANNEL_WIDTH_20:
393 reg_bw_opmode |= BW_OPMODE_20MHZ;
394 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
395 break;
396 case HT_CHANNEL_WIDTH_20_40:
397 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
398 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
399 reg_prsr_rsc =
400 (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
401 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
402 break;
403 default:
404 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
405 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
406 break;
407 }
408
409 switch (rtlphy->current_chan_bw) {
410 case HT_CHANNEL_WIDTH_20:
411 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
412 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
413 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
414 break;
415 case HT_CHANNEL_WIDTH_20_40:
416 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
417 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
418
419 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
420 (mac->cur_40_prime_sc >> 1));
421 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
422 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
423
424 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
425 (mac->cur_40_prime_sc ==
426 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
427 break;
428 default:
429 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
430 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
431 break;
432 }
433 rtl92ce_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
434 rtlphy->set_bwmode_inprogress = false;
435 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
436}
437
369void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) 438void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
370{ 439{
371 u8 tmpreg; 440 u8 tmpreg;
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
index ad580852cc76..be2c92adef33 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
@@ -257,5 +257,6 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
257 u8 configtype); 257 u8 configtype);
258bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, 258bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
259 u8 configtype); 259 u8 configtype);
260void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
260 261
261#endif 262#endif
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
index 390bbb5ee11d..373dc78af1dc 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -232,6 +232,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = {
232 .config_bb_with_headerfile = _rtl92ce_phy_config_bb_with_headerfile, 232 .config_bb_with_headerfile = _rtl92ce_phy_config_bb_with_headerfile,
233 .config_bb_with_pgheaderfile = _rtl92ce_phy_config_bb_with_pgheaderfile, 233 .config_bb_with_pgheaderfile = _rtl92ce_phy_config_bb_with_pgheaderfile,
234 .phy_lc_calibrate = _rtl92ce_phy_lc_calibrate, 234 .phy_lc_calibrate = _rtl92ce_phy_lc_calibrate,
235 .phy_set_bw_mode_callback = rtl92ce_phy_set_bw_mode_callback,
235 .dm_dynamic_txpower = rtl92ce_dm_dynamic_txpower, 236 .dm_dynamic_txpower = rtl92ce_dm_dynamic_txpower,
236}; 237};
237 238
diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c
index bcca39418f90..5bda24e26c0e 100644
--- a/drivers/staging/ath6kl/os/linux/cfg80211.c
+++ b/drivers/staging/ath6kl/os/linux/cfg80211.c
@@ -570,7 +570,7 @@ ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel,
570 WLAN_STATUS_SUCCESS, GFP_KERNEL); 570 WLAN_STATUS_SUCCESS, GFP_KERNEL);
571 } else { 571 } else {
572 /* inform roam event to cfg80211 */ 572 /* inform roam event to cfg80211 */
573 cfg80211_roamed(ar->arNetDev, bssid, 573 cfg80211_roamed(ar->arNetDev, ibss_channel, bssid,
574 assocReqIe, assocReqLen, 574 assocReqIe, assocReqLen,
575 assocRespIe, assocRespLen, 575 assocRespIe, assocRespLen,
576 GFP_KERNEL); 576 GFP_KERNEL);
diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
index 555b056b49b1..7aaf99cc3a7b 100644
--- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
@@ -2630,7 +2630,7 @@ wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev,
2630 wl_get_assoc_ies(wl); 2630 wl_get_assoc_ies(wl);
2631 memcpy(&wl->bssid, &e->addr, ETH_ALEN); 2631 memcpy(&wl->bssid, &e->addr, ETH_ALEN);
2632 wl_update_bss_info(wl); 2632 wl_update_bss_info(wl);
2633 cfg80211_roamed(ndev, 2633 cfg80211_roamed(ndev, NULL,
2634 (u8 *)&wl->bssid, 2634 (u8 *)&wl->bssid,
2635 conn_info->req_ie, conn_info->req_ie_len, 2635 conn_info->req_ie, conn_info->req_ie_len,
2636 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); 2636 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
@@ -2663,7 +2663,7 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev,
2663 WL_DBG("Report connect result - connection %s\n", 2663 WL_DBG("Report connect result - connection %s\n",
2664 completed ? "succeeded" : "failed"); 2664 completed ? "succeeded" : "failed");
2665 } else { 2665 } else {
2666 cfg80211_roamed(ndev, 2666 cfg80211_roamed(ndev, NULL,
2667 (u8 *)&wl->bssid, 2667 (u8 *)&wl->bssid,
2668 conn_info->req_ie, conn_info->req_ie_len, 2668 conn_info->req_ie, conn_info->req_ie_len,
2669 conn_info->resp_ie, conn_info->resp_ie_len, 2669 conn_info->resp_ie, conn_info->resp_ie_len,
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c
index 76378397b763..fb466f4c92e0 100644
--- a/drivers/staging/wlan-ng/cfg80211.c
+++ b/drivers/staging/wlan-ng/cfg80211.c
@@ -695,7 +695,7 @@ void prism2_disconnected(wlandevice_t *wlandev)
695 695
696void prism2_roamed(wlandevice_t *wlandev) 696void prism2_roamed(wlandevice_t *wlandev)
697{ 697{
698 cfg80211_roamed(wlandev->netdev, wlandev->bssid, 698 cfg80211_roamed(wlandev->netdev, NULL, wlandev->bssid,
699 NULL, 0, NULL, 0, GFP_KERNEL); 699 NULL, 0, NULL, 0, GFP_KERNEL);
700} 700}
701 701
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index f1281339b6fa..f1637f17c37c 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -674,6 +674,7 @@ struct proc_dir_entry *proc_mkdir_mode(const char *name, mode_t mode,
674 } 674 }
675 return ent; 675 return ent;
676} 676}
677EXPORT_SYMBOL(proc_mkdir_mode);
677 678
678struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name, 679struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
679 struct proc_dir_entry *parent) 680 struct proc_dir_entry *parent)
diff --git a/include/linux/rfkill-gpio.h b/include/linux/rfkill-gpio.h
new file mode 100644
index 000000000000..a175d0598033
--- /dev/null
+++ b/include/linux/rfkill-gpio.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (c) 2011, NVIDIA Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19
20#ifndef __RFKILL_GPIO_H
21#define __RFKILL_GPIO_H
22
23#include <linux/types.h>
24#include <linux/rfkill.h>
25
26/**
27 * struct rfkill_gpio_platform_data - platform data for rfkill gpio device.
28 * for unused gpio's, the expected value is -1.
29 * @name: name for the gpio rf kill instance
30 * @reset_gpio: GPIO which is used for reseting rfkill switch
31 * @shutdown_gpio: GPIO which is used for shutdown of rfkill switch
32 * @power_clk_name: [optional] name of clk to turn off while blocked
33 */
34
35struct rfkill_gpio_platform_data {
36 char *name;
37 int reset_gpio;
38 int shutdown_gpio;
39 const char *power_clk_name;
40 enum rfkill_type type;
41};
42
43#endif /* __RFKILL_GPIO_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index bfd6557946be..0589f554788a 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -531,6 +531,7 @@ struct sta_bss_parameters {
531 * @tx_retries: cumulative retry counts 531 * @tx_retries: cumulative retry counts
532 * @tx_failed: number of failed transmissions (retries exceeded, no ACK) 532 * @tx_failed: number of failed transmissions (retries exceeded, no ACK)
533 * @rx_dropped_misc: Dropped for un-specified reason. 533 * @rx_dropped_misc: Dropped for un-specified reason.
534 * @bss_param: current BSS parameters
534 * @generation: generation number for nl80211 dumps. 535 * @generation: generation number for nl80211 dumps.
535 * This number should increase every time the list of stations 536 * This number should increase every time the list of stations
536 * changes, i.e. when a station is added or removed, so that 537 * changes, i.e. when a station is added or removed, so that
@@ -1537,7 +1538,7 @@ struct cfg80211_ops {
1537 * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. 1538 * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN.
1538 * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing 1539 * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing
1539 * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH. 1540 * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH.
1540 * @WIPHY_FLAG_SCHED_SCAN: The device supports scheduled scans. 1541 * @WIPHY_FLAG_SUPPORTS_SCHED_SCAN: The device supports scheduled scans.
1541 */ 1542 */
1542enum wiphy_flags { 1543enum wiphy_flags {
1543 WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), 1544 WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -2878,6 +2879,7 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
2878 * cfg80211_roamed - notify cfg80211 of roaming 2879 * cfg80211_roamed - notify cfg80211 of roaming
2879 * 2880 *
2880 * @dev: network device 2881 * @dev: network device
2882 * @channel: the channel of the new AP
2881 * @bssid: the BSSID of the new AP 2883 * @bssid: the BSSID of the new AP
2882 * @req_ie: association request IEs (maybe be %NULL) 2884 * @req_ie: association request IEs (maybe be %NULL)
2883 * @req_ie_len: association request IEs length 2885 * @req_ie_len: association request IEs length
@@ -2888,7 +2890,9 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
2888 * It should be called by the underlying driver whenever it roamed 2890 * It should be called by the underlying driver whenever it roamed
2889 * from one AP to another while connected. 2891 * from one AP to another while connected.
2890 */ 2892 */
2891void cfg80211_roamed(struct net_device *dev, const u8 *bssid, 2893void cfg80211_roamed(struct net_device *dev,
2894 struct ieee80211_channel *channel,
2895 const u8 *bssid,
2892 const u8 *req_ie, size_t req_ie_len, 2896 const u8 *req_ie, size_t req_ie_len,
2893 const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp); 2897 const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp);
2894 2898
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 7dfbe71dc637..49d4f869e0bc 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -384,11 +384,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
384 int i; 384 int i;
385 enum nl80211_channel_type orig_ct; 385 enum nl80211_channel_type orig_ct;
386 386
387 clear_bit(SDATA_STATE_RUNNING, &sdata->state);
388
387 if (local->scan_sdata == sdata) 389 if (local->scan_sdata == sdata)
388 ieee80211_scan_cancel(local); 390 ieee80211_scan_cancel(local);
389 391
390 clear_bit(SDATA_STATE_RUNNING, &sdata->state);
391
392 /* 392 /*
393 * Stop TX on this interface first. 393 * Stop TX on this interface first.
394 */ 394 */
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 0d7b08db8e56..866f269183cf 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -752,11 +752,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
752 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); 752 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
753 hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); 753 hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
754 754
755 /* mac80211 doesn't support more than 1 channel */ 755 /*
756 for (i = 0; i < hw->wiphy->n_iface_combinations; i++) 756 * mac80211 doesn't support more than 1 channel, and also not more
757 if (hw->wiphy->iface_combinations[i].num_different_channels > 1) 757 * than one IBSS interface
758 */
759 for (i = 0; i < hw->wiphy->n_iface_combinations; i++) {
760 const struct ieee80211_iface_combination *c;
761 int j;
762
763 c = &hw->wiphy->iface_combinations[i];
764
765 if (c->num_different_channels > 1)
758 return -EINVAL; 766 return -EINVAL;
759 767
768 for (j = 0; j < c->n_limits; j++)
769 if ((c->limits[j].types & BIT(NL80211_IFTYPE_ADHOC)) &&
770 c->limits[j].max > 1)
771 return -EINVAL;
772 }
773
760#ifndef CONFIG_MAC80211_MESH 774#ifndef CONFIG_MAC80211_MESH
761 /* mesh depends on Kconfig, but drivers should set it if they want */ 775 /* mesh depends on Kconfig, but drivers should set it if they want */
762 local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); 776 local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT);
@@ -1076,6 +1090,8 @@ static void __exit ieee80211_exit(void)
1076 ieee80211s_stop(); 1090 ieee80211s_stop();
1077 1091
1078 ieee80211_iface_exit(); 1092 ieee80211_iface_exit();
1093
1094 rcu_barrier();
1079} 1095}
1080 1096
1081 1097
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index e7c5fddb4804..249e733362e7 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -120,6 +120,7 @@ struct mesh_path {
120 * buckets 120 * buckets
121 * @mean_chain_len: maximum average length for the hash buckets' list, if it is 121 * @mean_chain_len: maximum average length for the hash buckets' list, if it is
122 * reached, the table will grow 122 * reached, the table will grow
123 * rcu_head: RCU head to free the table
123 */ 124 */
124struct mesh_table { 125struct mesh_table {
125 /* Number of buckets will be 2^N */ 126 /* Number of buckets will be 2^N */
@@ -132,6 +133,8 @@ struct mesh_table {
132 int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl); 133 int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl);
133 int size_order; 134 int size_order;
134 int mean_chain_len; 135 int mean_chain_len;
136
137 struct rcu_head rcu_head;
135}; 138};
136 139
137/* Recent multicast cache */ 140/* Recent multicast cache */
@@ -286,10 +289,6 @@ static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
286 return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP; 289 return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
287} 290}
288 291
289#define for_each_mesh_entry(x, p, node, i) \
290 for (i = 0; i <= x->hash_mask; i++) \
291 hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list)
292
293void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local); 292void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local);
294 293
295void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata); 294void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 83ce48e31913..0d2faacc3e87 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -36,8 +36,8 @@ struct mpath_node {
36 struct mesh_path *mpath; 36 struct mesh_path *mpath;
37}; 37};
38 38
39static struct mesh_table *mesh_paths; 39static struct mesh_table __rcu *mesh_paths;
40static struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */ 40static struct mesh_table __rcu *mpp_paths; /* Store paths for MPP&MAP */
41 41
42int mesh_paths_generation; 42int mesh_paths_generation;
43 43
@@ -48,17 +48,40 @@ int mesh_paths_generation;
48static DEFINE_RWLOCK(pathtbl_resize_lock); 48static DEFINE_RWLOCK(pathtbl_resize_lock);
49 49
50 50
51static inline struct mesh_table *resize_dereference_mesh_paths(void)
52{
53 return rcu_dereference_protected(mesh_paths,
54 lockdep_is_held(&pathtbl_resize_lock));
55}
56
57static inline struct mesh_table *resize_dereference_mpp_paths(void)
58{
59 return rcu_dereference_protected(mpp_paths,
60 lockdep_is_held(&pathtbl_resize_lock));
61}
62
63/*
64 * CAREFUL -- "tbl" must not be an expression,
65 * in particular not an rcu_dereference(), since
66 * it's used twice. So it is illegal to do
67 * for_each_mesh_entry(rcu_dereference(...), ...)
68 */
69#define for_each_mesh_entry(tbl, p, node, i) \
70 for (i = 0; i <= tbl->hash_mask; i++) \
71 hlist_for_each_entry_rcu(node, p, &tbl->hash_buckets[i], list)
72
73
51static struct mesh_table *mesh_table_alloc(int size_order) 74static struct mesh_table *mesh_table_alloc(int size_order)
52{ 75{
53 int i; 76 int i;
54 struct mesh_table *newtbl; 77 struct mesh_table *newtbl;
55 78
56 newtbl = kmalloc(sizeof(struct mesh_table), GFP_KERNEL); 79 newtbl = kmalloc(sizeof(struct mesh_table), GFP_ATOMIC);
57 if (!newtbl) 80 if (!newtbl)
58 return NULL; 81 return NULL;
59 82
60 newtbl->hash_buckets = kzalloc(sizeof(struct hlist_head) * 83 newtbl->hash_buckets = kzalloc(sizeof(struct hlist_head) *
61 (1 << size_order), GFP_KERNEL); 84 (1 << size_order), GFP_ATOMIC);
62 85
63 if (!newtbl->hash_buckets) { 86 if (!newtbl->hash_buckets) {
64 kfree(newtbl); 87 kfree(newtbl);
@@ -66,7 +89,7 @@ static struct mesh_table *mesh_table_alloc(int size_order)
66 } 89 }
67 90
68 newtbl->hashwlock = kmalloc(sizeof(spinlock_t) * 91 newtbl->hashwlock = kmalloc(sizeof(spinlock_t) *
69 (1 << size_order), GFP_KERNEL); 92 (1 << size_order), GFP_ATOMIC);
70 if (!newtbl->hashwlock) { 93 if (!newtbl->hashwlock) {
71 kfree(newtbl->hash_buckets); 94 kfree(newtbl->hash_buckets);
72 kfree(newtbl); 95 kfree(newtbl);
@@ -258,12 +281,13 @@ struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
258 */ 281 */
259struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data *sdata) 282struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data *sdata)
260{ 283{
284 struct mesh_table *tbl = rcu_dereference(mesh_paths);
261 struct mpath_node *node; 285 struct mpath_node *node;
262 struct hlist_node *p; 286 struct hlist_node *p;
263 int i; 287 int i;
264 int j = 0; 288 int j = 0;
265 289
266 for_each_mesh_entry(mesh_paths, p, node, i) { 290 for_each_mesh_entry(tbl, p, node, i) {
267 if (sdata && node->mpath->sdata != sdata) 291 if (sdata && node->mpath->sdata != sdata)
268 continue; 292 continue;
269 if (j++ == idx) { 293 if (j++ == idx) {
@@ -293,6 +317,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
293{ 317{
294 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 318 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
295 struct ieee80211_local *local = sdata->local; 319 struct ieee80211_local *local = sdata->local;
320 struct mesh_table *tbl;
296 struct mesh_path *mpath, *new_mpath; 321 struct mesh_path *mpath, *new_mpath;
297 struct mpath_node *node, *new_node; 322 struct mpath_node *node, *new_node;
298 struct hlist_head *bucket; 323 struct hlist_head *bucket;
@@ -332,10 +357,12 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
332 spin_lock_init(&new_mpath->state_lock); 357 spin_lock_init(&new_mpath->state_lock);
333 init_timer(&new_mpath->timer); 358 init_timer(&new_mpath->timer);
334 359
335 hash_idx = mesh_table_hash(dst, sdata, mesh_paths); 360 tbl = resize_dereference_mesh_paths();
336 bucket = &mesh_paths->hash_buckets[hash_idx]; 361
362 hash_idx = mesh_table_hash(dst, sdata, tbl);
363 bucket = &tbl->hash_buckets[hash_idx];
337 364
338 spin_lock_bh(&mesh_paths->hashwlock[hash_idx]); 365 spin_lock_bh(&tbl->hashwlock[hash_idx]);
339 366
340 err = -EEXIST; 367 err = -EEXIST;
341 hlist_for_each_entry(node, n, bucket, list) { 368 hlist_for_each_entry(node, n, bucket, list) {
@@ -345,13 +372,13 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
345 } 372 }
346 373
347 hlist_add_head_rcu(&new_node->list, bucket); 374 hlist_add_head_rcu(&new_node->list, bucket);
348 if (atomic_inc_return(&mesh_paths->entries) >= 375 if (atomic_inc_return(&tbl->entries) >=
349 mesh_paths->mean_chain_len * (mesh_paths->hash_mask + 1)) 376 tbl->mean_chain_len * (tbl->hash_mask + 1))
350 grow = 1; 377 grow = 1;
351 378
352 mesh_paths_generation++; 379 mesh_paths_generation++;
353 380
354 spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]); 381 spin_unlock_bh(&tbl->hashwlock[hash_idx]);
355 read_unlock_bh(&pathtbl_resize_lock); 382 read_unlock_bh(&pathtbl_resize_lock);
356 if (grow) { 383 if (grow) {
357 set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags); 384 set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags);
@@ -360,7 +387,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
360 return 0; 387 return 0;
361 388
362err_exists: 389err_exists:
363 spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]); 390 spin_unlock_bh(&tbl->hashwlock[hash_idx]);
364 read_unlock_bh(&pathtbl_resize_lock); 391 read_unlock_bh(&pathtbl_resize_lock);
365 kfree(new_node); 392 kfree(new_node);
366err_node_alloc: 393err_node_alloc:
@@ -370,58 +397,59 @@ err_path_alloc:
370 return err; 397 return err;
371} 398}
372 399
400static void mesh_table_free_rcu(struct rcu_head *rcu)
401{
402 struct mesh_table *tbl = container_of(rcu, struct mesh_table, rcu_head);
403
404 mesh_table_free(tbl, false);
405}
406
373void mesh_mpath_table_grow(void) 407void mesh_mpath_table_grow(void)
374{ 408{
375 struct mesh_table *oldtbl, *newtbl; 409 struct mesh_table *oldtbl, *newtbl;
376 410
377 rcu_read_lock();
378 newtbl = mesh_table_alloc(rcu_dereference(mesh_paths)->size_order + 1);
379 if (!newtbl)
380 return;
381 write_lock_bh(&pathtbl_resize_lock); 411 write_lock_bh(&pathtbl_resize_lock);
382 oldtbl = mesh_paths; 412 oldtbl = resize_dereference_mesh_paths();
383 if (mesh_table_grow(mesh_paths, newtbl) < 0) { 413 newtbl = mesh_table_alloc(oldtbl->size_order + 1);
384 rcu_read_unlock(); 414 if (!newtbl)
415 goto out;
416 if (mesh_table_grow(oldtbl, newtbl) < 0) {
385 __mesh_table_free(newtbl); 417 __mesh_table_free(newtbl);
386 write_unlock_bh(&pathtbl_resize_lock); 418 goto out;
387 return;
388 } 419 }
389 rcu_read_unlock();
390 rcu_assign_pointer(mesh_paths, newtbl); 420 rcu_assign_pointer(mesh_paths, newtbl);
391 write_unlock_bh(&pathtbl_resize_lock);
392 421
393 synchronize_rcu(); 422 call_rcu(&oldtbl->rcu_head, mesh_table_free_rcu);
394 mesh_table_free(oldtbl, false); 423
424 out:
425 write_unlock_bh(&pathtbl_resize_lock);
395} 426}
396 427
397void mesh_mpp_table_grow(void) 428void mesh_mpp_table_grow(void)
398{ 429{
399 struct mesh_table *oldtbl, *newtbl; 430 struct mesh_table *oldtbl, *newtbl;
400 431
401 rcu_read_lock();
402 newtbl = mesh_table_alloc(rcu_dereference(mpp_paths)->size_order + 1);
403 if (!newtbl)
404 return;
405 write_lock_bh(&pathtbl_resize_lock); 432 write_lock_bh(&pathtbl_resize_lock);
406 oldtbl = mpp_paths; 433 oldtbl = resize_dereference_mpp_paths();
407 if (mesh_table_grow(mpp_paths, newtbl) < 0) { 434 newtbl = mesh_table_alloc(oldtbl->size_order + 1);
408 rcu_read_unlock(); 435 if (!newtbl)
436 goto out;
437 if (mesh_table_grow(oldtbl, newtbl) < 0) {
409 __mesh_table_free(newtbl); 438 __mesh_table_free(newtbl);
410 write_unlock_bh(&pathtbl_resize_lock); 439 goto out;
411 return;
412 } 440 }
413 rcu_read_unlock();
414 rcu_assign_pointer(mpp_paths, newtbl); 441 rcu_assign_pointer(mpp_paths, newtbl);
415 write_unlock_bh(&pathtbl_resize_lock); 442 call_rcu(&oldtbl->rcu_head, mesh_table_free_rcu);
416 443
417 synchronize_rcu(); 444 out:
418 mesh_table_free(oldtbl, false); 445 write_unlock_bh(&pathtbl_resize_lock);
419} 446}
420 447
421int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata) 448int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
422{ 449{
423 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 450 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
424 struct ieee80211_local *local = sdata->local; 451 struct ieee80211_local *local = sdata->local;
452 struct mesh_table *tbl;
425 struct mesh_path *mpath, *new_mpath; 453 struct mesh_path *mpath, *new_mpath;
426 struct mpath_node *node, *new_node; 454 struct mpath_node *node, *new_node;
427 struct hlist_head *bucket; 455 struct hlist_head *bucket;
@@ -456,10 +484,12 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
456 new_mpath->exp_time = jiffies; 484 new_mpath->exp_time = jiffies;
457 spin_lock_init(&new_mpath->state_lock); 485 spin_lock_init(&new_mpath->state_lock);
458 486
459 hash_idx = mesh_table_hash(dst, sdata, mpp_paths); 487 tbl = resize_dereference_mpp_paths();
460 bucket = &mpp_paths->hash_buckets[hash_idx];
461 488
462 spin_lock_bh(&mpp_paths->hashwlock[hash_idx]); 489 hash_idx = mesh_table_hash(dst, sdata, tbl);
490 bucket = &tbl->hash_buckets[hash_idx];
491
492 spin_lock_bh(&tbl->hashwlock[hash_idx]);
463 493
464 err = -EEXIST; 494 err = -EEXIST;
465 hlist_for_each_entry(node, n, bucket, list) { 495 hlist_for_each_entry(node, n, bucket, list) {
@@ -469,11 +499,11 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
469 } 499 }
470 500
471 hlist_add_head_rcu(&new_node->list, bucket); 501 hlist_add_head_rcu(&new_node->list, bucket);
472 if (atomic_inc_return(&mpp_paths->entries) >= 502 if (atomic_inc_return(&tbl->entries) >=
473 mpp_paths->mean_chain_len * (mpp_paths->hash_mask + 1)) 503 tbl->mean_chain_len * (tbl->hash_mask + 1))
474 grow = 1; 504 grow = 1;
475 505
476 spin_unlock_bh(&mpp_paths->hashwlock[hash_idx]); 506 spin_unlock_bh(&tbl->hashwlock[hash_idx]);
477 read_unlock_bh(&pathtbl_resize_lock); 507 read_unlock_bh(&pathtbl_resize_lock);
478 if (grow) { 508 if (grow) {
479 set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags); 509 set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags);
@@ -482,7 +512,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
482 return 0; 512 return 0;
483 513
484err_exists: 514err_exists:
485 spin_unlock_bh(&mpp_paths->hashwlock[hash_idx]); 515 spin_unlock_bh(&tbl->hashwlock[hash_idx]);
486 read_unlock_bh(&pathtbl_resize_lock); 516 read_unlock_bh(&pathtbl_resize_lock);
487 kfree(new_node); 517 kfree(new_node);
488err_node_alloc: 518err_node_alloc:
@@ -502,6 +532,7 @@ err_path_alloc:
502 */ 532 */
503void mesh_plink_broken(struct sta_info *sta) 533void mesh_plink_broken(struct sta_info *sta)
504{ 534{
535 struct mesh_table *tbl;
505 static const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 536 static const u8 bcast[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
506 struct mesh_path *mpath; 537 struct mesh_path *mpath;
507 struct mpath_node *node; 538 struct mpath_node *node;
@@ -510,10 +541,11 @@ void mesh_plink_broken(struct sta_info *sta)
510 int i; 541 int i;
511 542
512 rcu_read_lock(); 543 rcu_read_lock();
513 for_each_mesh_entry(mesh_paths, p, node, i) { 544 tbl = rcu_dereference(mesh_paths);
545 for_each_mesh_entry(tbl, p, node, i) {
514 mpath = node->mpath; 546 mpath = node->mpath;
515 spin_lock_bh(&mpath->state_lock); 547 spin_lock_bh(&mpath->state_lock);
516 if (mpath->next_hop == sta && 548 if (rcu_dereference(mpath->next_hop) == sta &&
517 mpath->flags & MESH_PATH_ACTIVE && 549 mpath->flags & MESH_PATH_ACTIVE &&
518 !(mpath->flags & MESH_PATH_FIXED)) { 550 !(mpath->flags & MESH_PATH_FIXED)) {
519 mpath->flags &= ~MESH_PATH_ACTIVE; 551 mpath->flags &= ~MESH_PATH_ACTIVE;
@@ -542,30 +574,38 @@ void mesh_plink_broken(struct sta_info *sta)
542 */ 574 */
543void mesh_path_flush_by_nexthop(struct sta_info *sta) 575void mesh_path_flush_by_nexthop(struct sta_info *sta)
544{ 576{
577 struct mesh_table *tbl;
545 struct mesh_path *mpath; 578 struct mesh_path *mpath;
546 struct mpath_node *node; 579 struct mpath_node *node;
547 struct hlist_node *p; 580 struct hlist_node *p;
548 int i; 581 int i;
549 582
550 for_each_mesh_entry(mesh_paths, p, node, i) { 583 rcu_read_lock();
584 tbl = rcu_dereference(mesh_paths);
585 for_each_mesh_entry(tbl, p, node, i) {
551 mpath = node->mpath; 586 mpath = node->mpath;
552 if (mpath->next_hop == sta) 587 if (rcu_dereference(mpath->next_hop) == sta)
553 mesh_path_del(mpath->dst, mpath->sdata); 588 mesh_path_del(mpath->dst, mpath->sdata);
554 } 589 }
590 rcu_read_unlock();
555} 591}
556 592
557void mesh_path_flush(struct ieee80211_sub_if_data *sdata) 593void mesh_path_flush(struct ieee80211_sub_if_data *sdata)
558{ 594{
595 struct mesh_table *tbl;
559 struct mesh_path *mpath; 596 struct mesh_path *mpath;
560 struct mpath_node *node; 597 struct mpath_node *node;
561 struct hlist_node *p; 598 struct hlist_node *p;
562 int i; 599 int i;
563 600
564 for_each_mesh_entry(mesh_paths, p, node, i) { 601 rcu_read_lock();
602 tbl = rcu_dereference(mesh_paths);
603 for_each_mesh_entry(tbl, p, node, i) {
565 mpath = node->mpath; 604 mpath = node->mpath;
566 if (mpath->sdata == sdata) 605 if (mpath->sdata == sdata)
567 mesh_path_del(mpath->dst, mpath->sdata); 606 mesh_path_del(mpath->dst, mpath->sdata);
568 } 607 }
608 rcu_read_unlock();
569} 609}
570 610
571static void mesh_path_node_reclaim(struct rcu_head *rp) 611static void mesh_path_node_reclaim(struct rcu_head *rp)
@@ -589,6 +629,7 @@ static void mesh_path_node_reclaim(struct rcu_head *rp)
589 */ 629 */
590int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) 630int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
591{ 631{
632 struct mesh_table *tbl;
592 struct mesh_path *mpath; 633 struct mesh_path *mpath;
593 struct mpath_node *node; 634 struct mpath_node *node;
594 struct hlist_head *bucket; 635 struct hlist_head *bucket;
@@ -597,19 +638,20 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
597 int err = 0; 638 int err = 0;
598 639
599 read_lock_bh(&pathtbl_resize_lock); 640 read_lock_bh(&pathtbl_resize_lock);
600 hash_idx = mesh_table_hash(addr, sdata, mesh_paths); 641 tbl = resize_dereference_mesh_paths();
601 bucket = &mesh_paths->hash_buckets[hash_idx]; 642 hash_idx = mesh_table_hash(addr, sdata, tbl);
643 bucket = &tbl->hash_buckets[hash_idx];
602 644
603 spin_lock_bh(&mesh_paths->hashwlock[hash_idx]); 645 spin_lock_bh(&tbl->hashwlock[hash_idx]);
604 hlist_for_each_entry(node, n, bucket, list) { 646 hlist_for_each_entry(node, n, bucket, list) {
605 mpath = node->mpath; 647 mpath = node->mpath;
606 if (mpath->sdata == sdata && 648 if (mpath->sdata == sdata &&
607 memcmp(addr, mpath->dst, ETH_ALEN) == 0) { 649 memcmp(addr, mpath->dst, ETH_ALEN) == 0) {
608 spin_lock_bh(&mpath->state_lock); 650 spin_lock_bh(&mpath->state_lock);
609 mpath->flags |= MESH_PATH_RESOLVING; 651 mpath->flags |= MESH_PATH_RESOLVING;
610 hlist_del_rcu(&node->list); 652 hlist_del_rcu(&node->list);
611 call_rcu(&node->rcu, mesh_path_node_reclaim); 653 call_rcu(&node->rcu, mesh_path_node_reclaim);
612 atomic_dec(&mesh_paths->entries); 654 atomic_dec(&tbl->entries);
613 spin_unlock_bh(&mpath->state_lock); 655 spin_unlock_bh(&mpath->state_lock);
614 goto enddel; 656 goto enddel;
615 } 657 }
@@ -618,7 +660,7 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
618 err = -ENXIO; 660 err = -ENXIO;
619enddel: 661enddel:
620 mesh_paths_generation++; 662 mesh_paths_generation++;
621 spin_unlock_bh(&mesh_paths->hashwlock[hash_idx]); 663 spin_unlock_bh(&tbl->hashwlock[hash_idx]);
622 read_unlock_bh(&pathtbl_resize_lock); 664 read_unlock_bh(&pathtbl_resize_lock);
623 return err; 665 return err;
624} 666}
@@ -719,8 +761,10 @@ static void mesh_path_node_free(struct hlist_node *p, bool free_leafs)
719 struct mpath_node *node = hlist_entry(p, struct mpath_node, list); 761 struct mpath_node *node = hlist_entry(p, struct mpath_node, list);
720 mpath = node->mpath; 762 mpath = node->mpath;
721 hlist_del_rcu(p); 763 hlist_del_rcu(p);
722 if (free_leafs) 764 if (free_leafs) {
765 del_timer_sync(&mpath->timer);
723 kfree(mpath); 766 kfree(mpath);
767 }
724 kfree(node); 768 kfree(node);
725} 769}
726 770
@@ -745,52 +789,60 @@ static int mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl)
745 789
746int mesh_pathtbl_init(void) 790int mesh_pathtbl_init(void)
747{ 791{
748 mesh_paths = mesh_table_alloc(INIT_PATHS_SIZE_ORDER); 792 struct mesh_table *tbl_path, *tbl_mpp;
749 if (!mesh_paths) 793
794 tbl_path = mesh_table_alloc(INIT_PATHS_SIZE_ORDER);
795 if (!tbl_path)
750 return -ENOMEM; 796 return -ENOMEM;
751 mesh_paths->free_node = &mesh_path_node_free; 797 tbl_path->free_node = &mesh_path_node_free;
752 mesh_paths->copy_node = &mesh_path_node_copy; 798 tbl_path->copy_node = &mesh_path_node_copy;
753 mesh_paths->mean_chain_len = MEAN_CHAIN_LEN; 799 tbl_path->mean_chain_len = MEAN_CHAIN_LEN;
754 800
755 mpp_paths = mesh_table_alloc(INIT_PATHS_SIZE_ORDER); 801 tbl_mpp = mesh_table_alloc(INIT_PATHS_SIZE_ORDER);
756 if (!mpp_paths) { 802 if (!tbl_mpp) {
757 mesh_table_free(mesh_paths, true); 803 mesh_table_free(tbl_path, true);
758 return -ENOMEM; 804 return -ENOMEM;
759 } 805 }
760 mpp_paths->free_node = &mesh_path_node_free; 806 tbl_mpp->free_node = &mesh_path_node_free;
761 mpp_paths->copy_node = &mesh_path_node_copy; 807 tbl_mpp->copy_node = &mesh_path_node_copy;
762 mpp_paths->mean_chain_len = MEAN_CHAIN_LEN; 808 tbl_mpp->mean_chain_len = MEAN_CHAIN_LEN;
809
810 /* Need no locking since this is during init */
811 RCU_INIT_POINTER(mesh_paths, tbl_path);
812 RCU_INIT_POINTER(mpp_paths, tbl_mpp);
763 813
764 return 0; 814 return 0;
765} 815}
766 816
767void mesh_path_expire(struct ieee80211_sub_if_data *sdata) 817void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
768{ 818{
819 struct mesh_table *tbl;
769 struct mesh_path *mpath; 820 struct mesh_path *mpath;
770 struct mpath_node *node; 821 struct mpath_node *node;
771 struct hlist_node *p; 822 struct hlist_node *p;
772 int i; 823 int i;
773 824
774 read_lock_bh(&pathtbl_resize_lock); 825 rcu_read_lock();
775 for_each_mesh_entry(mesh_paths, p, node, i) { 826 tbl = rcu_dereference(mesh_paths);
827 for_each_mesh_entry(tbl, p, node, i) {
776 if (node->mpath->sdata != sdata) 828 if (node->mpath->sdata != sdata)
777 continue; 829 continue;
778 mpath = node->mpath; 830 mpath = node->mpath;
779 spin_lock_bh(&mpath->state_lock); 831 spin_lock_bh(&mpath->state_lock);
780 if ((!(mpath->flags & MESH_PATH_RESOLVING)) && 832 if ((!(mpath->flags & MESH_PATH_RESOLVING)) &&
781 (!(mpath->flags & MESH_PATH_FIXED)) && 833 (!(mpath->flags & MESH_PATH_FIXED)) &&
782 time_after(jiffies, 834 time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE)) {
783 mpath->exp_time + MESH_PATH_EXPIRE)) {
784 spin_unlock_bh(&mpath->state_lock); 835 spin_unlock_bh(&mpath->state_lock);
785 mesh_path_del(mpath->dst, mpath->sdata); 836 mesh_path_del(mpath->dst, mpath->sdata);
786 } else 837 } else
787 spin_unlock_bh(&mpath->state_lock); 838 spin_unlock_bh(&mpath->state_lock);
788 } 839 }
789 read_unlock_bh(&pathtbl_resize_lock); 840 rcu_read_unlock();
790} 841}
791 842
792void mesh_pathtbl_unregister(void) 843void mesh_pathtbl_unregister(void)
793{ 844{
794 mesh_table_free(mesh_paths, true); 845 /* no need for locking during exit path */
795 mesh_table_free(mpp_paths, true); 846 mesh_table_free(rcu_dereference_raw(mesh_paths), true);
847 mesh_table_free(rcu_dereference_raw(mpp_paths), true);
796} 848}
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index d20046b5d8f4..27af6723cb5e 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -719,6 +719,11 @@ void ieee80211_scan_work(struct work_struct *work)
719 * without scheduling a new work 719 * without scheduling a new work
720 */ 720 */
721 do { 721 do {
722 if (!ieee80211_sdata_running(sdata)) {
723 aborted = true;
724 goto out_complete;
725 }
726
722 switch (local->next_scan_state) { 727 switch (local->next_scan_state) {
723 case SCAN_DECISION: 728 case SCAN_DECISION:
724 /* if no more bands/channels left, complete scan */ 729 /* if no more bands/channels left, complete scan */
diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig
index 48464ca13b24..78efe895b663 100644
--- a/net/rfkill/Kconfig
+++ b/net/rfkill/Kconfig
@@ -33,3 +33,12 @@ config RFKILL_REGULATOR
33 33
34 To compile this driver as a module, choose M here: the module will 34 To compile this driver as a module, choose M here: the module will
35 be called rfkill-regulator. 35 be called rfkill-regulator.
36
37config RFKILL_GPIO
38 tristate "GPIO RFKILL driver"
39 depends on RFKILL && GPIOLIB && HAVE_CLK
40 default n
41 help
42 If you say yes here you get support of a generic gpio RFKILL
43 driver. The platform should fill in the appropriate fields in the
44 rfkill_gpio_platform_data structure and pass that to the driver.
diff --git a/net/rfkill/Makefile b/net/rfkill/Makefile
index d9a5a58ffd8c..311768783f4a 100644
--- a/net/rfkill/Makefile
+++ b/net/rfkill/Makefile
@@ -6,3 +6,4 @@ rfkill-y += core.o
6rfkill-$(CONFIG_RFKILL_INPUT) += input.o 6rfkill-$(CONFIG_RFKILL_INPUT) += input.o
7obj-$(CONFIG_RFKILL) += rfkill.o 7obj-$(CONFIG_RFKILL) += rfkill.o
8obj-$(CONFIG_RFKILL_REGULATOR) += rfkill-regulator.o 8obj-$(CONFIG_RFKILL_REGULATOR) += rfkill-regulator.o
9obj-$(CONFIG_RFKILL_GPIO) += rfkill-gpio.o
diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c
new file mode 100644
index 000000000000..256c5ddd2d72
--- /dev/null
+++ b/net/rfkill/rfkill-gpio.c
@@ -0,0 +1,227 @@
1/*
2 * Copyright (c) 2011, NVIDIA Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19#include <linux/gpio.h>
20#include <linux/init.h>
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/rfkill.h>
24#include <linux/platform_device.h>
25#include <linux/clk.h>
26#include <linux/slab.h>
27
28#include <linux/rfkill-gpio.h>
29
30enum rfkill_gpio_clk_state {
31 UNSPECIFIED = 0,
32 PWR_ENABLED,
33 PWR_DISABLED
34};
35
36#define PWR_CLK_SET(_RF, _EN) \
37 ((_RF)->pwr_clk_enabled = (!(_EN) ? PWR_ENABLED : PWR_DISABLED))
38#define PWR_CLK_ENABLED(_RF) ((_RF)->pwr_clk_enabled == PWR_ENABLED)
39#define PWR_CLK_DISABLED(_RF) ((_RF)->pwr_clk_enabled != PWR_ENABLED)
40
41struct rfkill_gpio_data {
42 struct rfkill_gpio_platform_data *pdata;
43 struct rfkill *rfkill_dev;
44 char *reset_name;
45 char *shutdown_name;
46 enum rfkill_gpio_clk_state pwr_clk_enabled;
47 struct clk *pwr_clk;
48};
49
50static int rfkill_gpio_set_power(void *data, bool blocked)
51{
52 struct rfkill_gpio_data *rfkill = data;
53
54 if (blocked) {
55 if (gpio_is_valid(rfkill->pdata->shutdown_gpio))
56 gpio_direction_output(rfkill->pdata->shutdown_gpio, 0);
57 if (gpio_is_valid(rfkill->pdata->reset_gpio))
58 gpio_direction_output(rfkill->pdata->reset_gpio, 0);
59 if (rfkill->pwr_clk && PWR_CLK_ENABLED(rfkill))
60 clk_disable(rfkill->pwr_clk);
61 } else {
62 if (rfkill->pwr_clk && PWR_CLK_DISABLED(rfkill))
63 clk_enable(rfkill->pwr_clk);
64 if (gpio_is_valid(rfkill->pdata->reset_gpio))
65 gpio_direction_output(rfkill->pdata->reset_gpio, 1);
66 if (gpio_is_valid(rfkill->pdata->shutdown_gpio))
67 gpio_direction_output(rfkill->pdata->shutdown_gpio, 1);
68 }
69
70 if (rfkill->pwr_clk)
71 PWR_CLK_SET(rfkill, blocked);
72
73 return 0;
74}
75
76static const struct rfkill_ops rfkill_gpio_ops = {
77 .set_block = rfkill_gpio_set_power,
78};
79
80static int rfkill_gpio_probe(struct platform_device *pdev)
81{
82 struct rfkill_gpio_data *rfkill;
83 struct rfkill_gpio_platform_data *pdata = pdev->dev.platform_data;
84 int ret = 0;
85 int len = 0;
86
87 if (!pdata) {
88 pr_warn("%s: No platform data specified\n", __func__);
89 return -EINVAL;
90 }
91
92 /* make sure at-least one of the GPIO is defined and that
93 * a name is specified for this instance */
94 if (!pdata->name || (!gpio_is_valid(pdata->reset_gpio) &&
95 !gpio_is_valid(pdata->shutdown_gpio))) {
96 pr_warn("%s: invalid platform data\n", __func__);
97 return -EINVAL;
98 }
99
100 rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL);
101 if (!rfkill)
102 return -ENOMEM;
103
104 rfkill->pdata = pdata;
105
106 len = strlen(pdata->name);
107 rfkill->reset_name = kzalloc(len + 7, GFP_KERNEL);
108 if (!rfkill->reset_name) {
109 ret = -ENOMEM;
110 goto fail_alloc;
111 }
112
113 rfkill->shutdown_name = kzalloc(len + 10, GFP_KERNEL);
114 if (!rfkill->shutdown_name) {
115 ret = -ENOMEM;
116 goto fail_reset_name;
117 }
118
119 snprintf(rfkill->reset_name, len + 6 , "%s_reset", pdata->name);
120 snprintf(rfkill->shutdown_name, len + 9, "%s_shutdown", pdata->name);
121
122 if (pdata->power_clk_name) {
123 rfkill->pwr_clk = clk_get(&pdev->dev, pdata->power_clk_name);
124 if (IS_ERR(rfkill->pwr_clk)) {
125 pr_warn("%s: can't find pwr_clk.\n", __func__);
126 goto fail_shutdown_name;
127 }
128 }
129
130 if (gpio_is_valid(pdata->reset_gpio)) {
131 ret = gpio_request(pdata->reset_gpio, rfkill->reset_name);
132 if (ret) {
133 pr_warn("%s: failed to get reset gpio.\n", __func__);
134 goto fail_clock;
135 }
136 }
137
138 if (gpio_is_valid(pdata->shutdown_gpio)) {
139 ret = gpio_request(pdata->shutdown_gpio, rfkill->shutdown_name);
140 if (ret) {
141 pr_warn("%s: failed to get shutdown gpio.\n", __func__);
142 goto fail_reset;
143 }
144 }
145
146 rfkill->rfkill_dev = rfkill_alloc(pdata->name, &pdev->dev, pdata->type,
147 &rfkill_gpio_ops, rfkill);
148 if (!rfkill->rfkill_dev)
149 goto fail_shutdown;
150
151 ret = rfkill_register(rfkill->rfkill_dev);
152 if (ret < 0)
153 goto fail_rfkill;
154
155 platform_set_drvdata(pdev, rfkill);
156
157 dev_info(&pdev->dev, "%s device registered.\n", pdata->name);
158
159 return 0;
160
161fail_rfkill:
162 rfkill_destroy(rfkill->rfkill_dev);
163fail_shutdown:
164 if (gpio_is_valid(pdata->shutdown_gpio))
165 gpio_free(pdata->shutdown_gpio);
166fail_reset:
167 if (gpio_is_valid(pdata->reset_gpio))
168 gpio_free(pdata->reset_gpio);
169fail_clock:
170 if (rfkill->pwr_clk)
171 clk_put(rfkill->pwr_clk);
172fail_shutdown_name:
173 kfree(rfkill->shutdown_name);
174fail_reset_name:
175 kfree(rfkill->reset_name);
176fail_alloc:
177 kfree(rfkill);
178
179 return ret;
180}
181
182static int rfkill_gpio_remove(struct platform_device *pdev)
183{
184 struct rfkill_gpio_data *rfkill = platform_get_drvdata(pdev);
185
186 rfkill_unregister(rfkill->rfkill_dev);
187 rfkill_destroy(rfkill->rfkill_dev);
188 if (gpio_is_valid(rfkill->pdata->shutdown_gpio))
189 gpio_free(rfkill->pdata->shutdown_gpio);
190 if (gpio_is_valid(rfkill->pdata->reset_gpio))
191 gpio_free(rfkill->pdata->reset_gpio);
192 if (rfkill->pwr_clk && PWR_CLK_ENABLED(rfkill))
193 clk_disable(rfkill->pwr_clk);
194 if (rfkill->pwr_clk)
195 clk_put(rfkill->pwr_clk);
196 kfree(rfkill->shutdown_name);
197 kfree(rfkill->reset_name);
198 kfree(rfkill);
199
200 return 0;
201}
202
203static struct platform_driver rfkill_gpio_driver = {
204 .probe = rfkill_gpio_probe,
205 .remove = __devexit_p(rfkill_gpio_remove),
206 .driver = {
207 .name = "rfkill_gpio",
208 .owner = THIS_MODULE,
209 },
210};
211
212static int __init rfkill_gpio_init(void)
213{
214 return platform_driver_register(&rfkill_gpio_driver);
215}
216
217static void __exit rfkill_gpio_exit(void)
218{
219 platform_driver_unregister(&rfkill_gpio_driver);
220}
221
222module_init(rfkill_gpio_init);
223module_exit(rfkill_gpio_exit);
224
225MODULE_DESCRIPTION("gpio rfkill");
226MODULE_AUTHOR("NVIDIA");
227MODULE_LICENSE("GPL");
diff --git a/net/wireless/core.h b/net/wireless/core.h
index bf0fb40e3c8b..3dce1f167eba 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -245,6 +245,7 @@ struct cfg80211_event {
245 u16 status; 245 u16 status;
246 } cr; 246 } cr;
247 struct { 247 struct {
248 struct ieee80211_channel *channel;
248 u8 bssid[ETH_ALEN]; 249 u8 bssid[ETH_ALEN];
249 const u8 *req_ie; 250 const u8 *req_ie;
250 const u8 *resp_ie; 251 const u8 *resp_ie;
@@ -392,7 +393,9 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
392int cfg80211_disconnect(struct cfg80211_registered_device *rdev, 393int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
393 struct net_device *dev, u16 reason, 394 struct net_device *dev, u16 reason,
394 bool wextev); 395 bool wextev);
395void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid, 396void __cfg80211_roamed(struct wireless_dev *wdev,
397 struct ieee80211_channel *channel,
398 const u8 *bssid,
396 const u8 *req_ie, size_t req_ie_len, 399 const u8 *req_ie, size_t req_ie_len,
397 const u8 *resp_ie, size_t resp_ie_len); 400 const u8 *resp_ie, size_t resp_ie_len);
398int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, 401int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 2222ce08ee91..ec83f413a7ed 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3294,8 +3294,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3294 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 3294 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3295 struct net_device *dev = info->user_ptr[1]; 3295 struct net_device *dev = info->user_ptr[1];
3296 struct cfg80211_scan_request *request; 3296 struct cfg80211_scan_request *request;
3297 struct cfg80211_ssid *ssid;
3298 struct ieee80211_channel *channel;
3299 struct nlattr *attr; 3297 struct nlattr *attr;
3300 struct wiphy *wiphy; 3298 struct wiphy *wiphy;
3301 int err, tmp, n_ssids = 0, n_channels, i; 3299 int err, tmp, n_ssids = 0, n_channels, i;
@@ -3342,8 +3340,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3342 return -EINVAL; 3340 return -EINVAL;
3343 3341
3344 request = kzalloc(sizeof(*request) 3342 request = kzalloc(sizeof(*request)
3345 + sizeof(*ssid) * n_ssids 3343 + sizeof(*request->ssids) * n_ssids
3346 + sizeof(channel) * n_channels 3344 + sizeof(*request->channels) * n_channels
3347 + ie_len, GFP_KERNEL); 3345 + ie_len, GFP_KERNEL);
3348 if (!request) 3346 if (!request)
3349 return -ENOMEM; 3347 return -ENOMEM;
@@ -3449,8 +3447,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3449 struct cfg80211_sched_scan_request *request; 3447 struct cfg80211_sched_scan_request *request;
3450 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 3448 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3451 struct net_device *dev = info->user_ptr[1]; 3449 struct net_device *dev = info->user_ptr[1];
3452 struct cfg80211_ssid *ssid;
3453 struct ieee80211_channel *channel;
3454 struct nlattr *attr; 3450 struct nlattr *attr;
3455 struct wiphy *wiphy; 3451 struct wiphy *wiphy;
3456 int err, tmp, n_ssids = 0, n_channels, i; 3452 int err, tmp, n_ssids = 0, n_channels, i;
@@ -3507,8 +3503,8 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
3507 return -EINVAL; 3503 return -EINVAL;
3508 3504
3509 request = kzalloc(sizeof(*request) 3505 request = kzalloc(sizeof(*request)
3510 + sizeof(*ssid) * n_ssids 3506 + sizeof(*request->ssids) * n_ssids
3511 + sizeof(channel) * n_channels 3507 + sizeof(*request->channels) * n_channels
3512 + ie_len, GFP_KERNEL); 3508 + ie_len, GFP_KERNEL);
3513 if (!request) 3509 if (!request)
3514 return -ENOMEM; 3510 return -ENOMEM;
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index e17b0bee6bdc..b7b6ff8be553 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -250,7 +250,8 @@ static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
250 if (wdev->conn->params.privacy) 250 if (wdev->conn->params.privacy)
251 capa |= WLAN_CAPABILITY_PRIVACY; 251 capa |= WLAN_CAPABILITY_PRIVACY;
252 252
253 bss = cfg80211_get_bss(wdev->wiphy, NULL, wdev->conn->params.bssid, 253 bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel,
254 wdev->conn->params.bssid,
254 wdev->conn->params.ssid, 255 wdev->conn->params.ssid,
255 wdev->conn->params.ssid_len, 256 wdev->conn->params.ssid_len,
256 WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY, 257 WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY,
@@ -470,7 +471,10 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
470 } 471 }
471 472
472 if (!bss) 473 if (!bss)
473 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, 474 bss = cfg80211_get_bss(wdev->wiphy,
475 wdev->conn ? wdev->conn->params.channel :
476 NULL,
477 bssid,
474 wdev->ssid, wdev->ssid_len, 478 wdev->ssid, wdev->ssid_len,
475 WLAN_CAPABILITY_ESS, 479 WLAN_CAPABILITY_ESS,
476 WLAN_CAPABILITY_ESS); 480 WLAN_CAPABILITY_ESS);
@@ -538,7 +542,9 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
538} 542}
539EXPORT_SYMBOL(cfg80211_connect_result); 543EXPORT_SYMBOL(cfg80211_connect_result);
540 544
541void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid, 545void __cfg80211_roamed(struct wireless_dev *wdev,
546 struct ieee80211_channel *channel,
547 const u8 *bssid,
542 const u8 *req_ie, size_t req_ie_len, 548 const u8 *req_ie, size_t req_ie_len,
543 const u8 *resp_ie, size_t resp_ie_len) 549 const u8 *resp_ie, size_t resp_ie_len)
544{ 550{
@@ -565,7 +571,7 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
565 cfg80211_put_bss(&wdev->current_bss->pub); 571 cfg80211_put_bss(&wdev->current_bss->pub);
566 wdev->current_bss = NULL; 572 wdev->current_bss = NULL;
567 573
568 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, 574 bss = cfg80211_get_bss(wdev->wiphy, channel, bssid,
569 wdev->ssid, wdev->ssid_len, 575 wdev->ssid, wdev->ssid_len,
570 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 576 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
571 577
@@ -603,7 +609,9 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
603#endif 609#endif
604} 610}
605 611
606void cfg80211_roamed(struct net_device *dev, const u8 *bssid, 612void cfg80211_roamed(struct net_device *dev,
613 struct ieee80211_channel *channel,
614 const u8 *bssid,
607 const u8 *req_ie, size_t req_ie_len, 615 const u8 *req_ie, size_t req_ie_len,
608 const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp) 616 const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
609{ 617{
@@ -619,6 +627,7 @@ void cfg80211_roamed(struct net_device *dev, const u8 *bssid,
619 return; 627 return;
620 628
621 ev->type = EVENT_ROAMED; 629 ev->type = EVENT_ROAMED;
630 ev->rm.channel = channel;
622 memcpy(ev->rm.bssid, bssid, ETH_ALEN); 631 memcpy(ev->rm.bssid, bssid, ETH_ALEN);
623 ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev); 632 ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev);
624 ev->rm.req_ie_len = req_ie_len; 633 ev->rm.req_ie_len = req_ie_len;
diff --git a/net/wireless/util.c b/net/wireless/util.c
index f0536d44d43c..4d7b83fbc32f 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -746,7 +746,7 @@ static void cfg80211_process_wdev_events(struct wireless_dev *wdev)
746 NULL); 746 NULL);
747 break; 747 break;
748 case EVENT_ROAMED: 748 case EVENT_ROAMED:
749 __cfg80211_roamed(wdev, ev->rm.bssid, 749 __cfg80211_roamed(wdev, ev->rm.channel, ev->rm.bssid,
750 ev->rm.req_ie, ev->rm.req_ie_len, 750 ev->rm.req_ie, ev->rm.req_ie_len,
751 ev->rm.resp_ie, ev->rm.resp_ie_len); 751 ev->rm.resp_ie, ev->rm.resp_ie_len);
752 break; 752 break;