aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-06-07 07:24:21 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-07 07:24:21 -0400
commitb1bc81a0ef86b86fa410dd303d84c8c7bd09a64d (patch)
treea0d2e6dd179e5d057776edd0ed865bc744dfa54d /drivers
parenta93958ac980f0ce594ad90657ecbc595ff157a40 (diff)
parent0c0c9e7076b69f93678e4ec711e2bf237398e623 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/usb/hso.c42
-rw-r--r--drivers/net/wireless/Kconfig2
-rw-r--r--drivers/net/wireless/ath/ar9170/ar9170.h10
-rw-r--r--drivers/net/wireless/ath/ar9170/hw.h5
-rw-r--r--drivers/net/wireless/ath/ar9170/led.c17
-rw-r--r--drivers/net/wireless/ath/ar9170/mac.c55
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c98
-rw-r--r--drivers/net/wireless/ath/ar9170/phy.c6
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.c69
-rw-r--r--drivers/net/wireless/ath/ar9170/usb.h2
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c24
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c155
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h10
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c115
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c15
-rw-r--r--drivers/net/wireless/ath/regd.c29
-rw-r--r--drivers/net/wireless/b43/Kconfig2
-rw-r--r--drivers/net/wireless/b43/leds.c2
-rw-r--r--drivers/net/wireless/b43/main.c4
-rw-r--r--drivers/net/wireless/b43/phy_a.c4
-rw-r--r--drivers/net/wireless/b43/phy_common.c17
-rw-r--r--drivers/net/wireless/b43/phy_common.h4
-rw-r--r--drivers/net/wireless/b43/phy_g.c4
-rw-r--r--drivers/net/wireless/b43/phy_lp.c2
-rw-r--r--drivers/net/wireless/b43/phy_n.c2
-rw-r--r--drivers/net/wireless/b43/rfkill.c123
-rw-r--r--drivers/net/wireless/b43/rfkill.h5
-rw-r--r--drivers/net/wireless/b43legacy/Kconfig2
-rw-r--r--drivers/net/wireless/b43legacy/leds.c3
-rw-r--r--drivers/net/wireless/b43legacy/rfkill.c123
-rw-r--r--drivers/net/wireless/b43legacy/rfkill.h6
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c73
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rfkill.c69
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c56
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c228
-rw-r--r--drivers/net/wireless/iwmc3200wifi/Kconfig3
-rw-r--r--drivers/net/wireless/iwmc3200wifi/Makefile2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/fw.c2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/iwm.h4
-rw-r--r--drivers/net/wireless/iwmc3200wifi/netdev.c10
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rfkill.c88
-rw-r--r--drivers/net/wireless/iwmc3200wifi/sdio.c2
-rw-r--r--drivers/net/wireless/libertas/11d.c26
-rw-r--r--drivers/net/wireless/libertas/11d.h29
-rw-r--r--drivers/net/wireless/libertas/assoc.c758
-rw-r--r--drivers/net/wireless/libertas/assoc.h13
-rw-r--r--drivers/net/wireless/libertas/cmd.c16
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c17
-rw-r--r--drivers/net/wireless/libertas/debugfs.c8
-rw-r--r--drivers/net/wireless/libertas/dev.h10
-rw-r--r--drivers/net/wireless/libertas/hostcmd.h41
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c76
-rw-r--r--drivers/net/wireless/libertas/if_spi.c34
-rw-r--r--drivers/net/wireless/libertas/main.c20
-rw-r--r--drivers/net/wireless/libertas/scan.c63
-rw-r--r--drivers/net/wireless/libertas/types.h150
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c27
-rw-r--r--drivers/net/wireless/p54/p54usb.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c12
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h5
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c2
-rw-r--r--drivers/platform/x86/Kconfig14
-rw-r--r--drivers/platform/x86/acer-wmi.c50
-rw-r--r--drivers/platform/x86/dell-laptop.c101
-rw-r--r--drivers/platform/x86/eeepc-laptop.c99
-rw-r--r--drivers/platform/x86/hp-wmi.c103
-rw-r--r--drivers/platform/x86/sony-laptop.c191
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c873
-rw-r--r--drivers/platform/x86/toshiba_acpi.c159
93 files changed, 2019 insertions, 2565 deletions
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 837135f0390a..5ddd8c4f9019 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -2481,10 +2481,10 @@ static int add_net_device(struct hso_device *hso_dev)
2481 return 0; 2481 return 0;
2482} 2482}
2483 2483
2484static int hso_radio_toggle(void *data, enum rfkill_state state) 2484static int hso_rfkill_set_block(void *data, bool blocked)
2485{ 2485{
2486 struct hso_device *hso_dev = data; 2486 struct hso_device *hso_dev = data;
2487 int enabled = (state == RFKILL_STATE_UNBLOCKED); 2487 int enabled = !blocked;
2488 int rv; 2488 int rv;
2489 2489
2490 mutex_lock(&hso_dev->mutex); 2490 mutex_lock(&hso_dev->mutex);
@@ -2498,6 +2498,10 @@ static int hso_radio_toggle(void *data, enum rfkill_state state)
2498 return rv; 2498 return rv;
2499} 2499}
2500 2500
2501static const struct rfkill_ops hso_rfkill_ops = {
2502 .set_block = hso_rfkill_set_block,
2503};
2504
2501/* Creates and sets up everything for rfkill */ 2505/* Creates and sets up everything for rfkill */
2502static void hso_create_rfkill(struct hso_device *hso_dev, 2506static void hso_create_rfkill(struct hso_device *hso_dev,
2503 struct usb_interface *interface) 2507 struct usb_interface *interface)
@@ -2506,29 +2510,25 @@ static void hso_create_rfkill(struct hso_device *hso_dev,
2506 struct device *dev = &hso_net->net->dev; 2510 struct device *dev = &hso_net->net->dev;
2507 char *rfkn; 2511 char *rfkn;
2508 2512
2509 hso_net->rfkill = rfkill_allocate(&interface_to_usbdev(interface)->dev,
2510 RFKILL_TYPE_WWAN);
2511 if (!hso_net->rfkill) {
2512 dev_err(dev, "%s - Out of memory\n", __func__);
2513 return;
2514 }
2515 rfkn = kzalloc(20, GFP_KERNEL); 2513 rfkn = kzalloc(20, GFP_KERNEL);
2516 if (!rfkn) { 2514 if (!rfkn)
2517 rfkill_free(hso_net->rfkill);
2518 hso_net->rfkill = NULL;
2519 dev_err(dev, "%s - Out of memory\n", __func__); 2515 dev_err(dev, "%s - Out of memory\n", __func__);
2520 return; 2516
2521 }
2522 snprintf(rfkn, 20, "hso-%d", 2517 snprintf(rfkn, 20, "hso-%d",
2523 interface->altsetting->desc.bInterfaceNumber); 2518 interface->altsetting->desc.bInterfaceNumber);
2524 hso_net->rfkill->name = rfkn; 2519
2525 hso_net->rfkill->state = RFKILL_STATE_UNBLOCKED; 2520 hso_net->rfkill = rfkill_alloc(rfkn,
2526 hso_net->rfkill->data = hso_dev; 2521 &interface_to_usbdev(interface)->dev,
2527 hso_net->rfkill->toggle_radio = hso_radio_toggle; 2522 RFKILL_TYPE_WWAN,
2523 &hso_rfkill_ops, hso_dev);
2524 if (!hso_net->rfkill) {
2525 dev_err(dev, "%s - Out of memory\n", __func__);
2526 kfree(rfkn);
2527 return;
2528 }
2528 if (rfkill_register(hso_net->rfkill) < 0) { 2529 if (rfkill_register(hso_net->rfkill) < 0) {
2530 rfkill_destroy(hso_net->rfkill);
2529 kfree(rfkn); 2531 kfree(rfkn);
2530 hso_net->rfkill->name = NULL;
2531 rfkill_free(hso_net->rfkill);
2532 hso_net->rfkill = NULL; 2532 hso_net->rfkill = NULL;
2533 dev_err(dev, "%s - Failed to register rfkill\n", __func__); 2533 dev_err(dev, "%s - Failed to register rfkill\n", __func__);
2534 return; 2534 return;
@@ -3165,8 +3165,10 @@ static void hso_free_interface(struct usb_interface *interface)
3165 hso_stop_net_device(network_table[i]); 3165 hso_stop_net_device(network_table[i]);
3166 cancel_work_sync(&network_table[i]->async_put_intf); 3166 cancel_work_sync(&network_table[i]->async_put_intf);
3167 cancel_work_sync(&network_table[i]->async_get_intf); 3167 cancel_work_sync(&network_table[i]->async_get_intf);
3168 if (rfk) 3168 if (rfk) {
3169 rfkill_unregister(rfk); 3169 rfkill_unregister(rfk);
3170 rfkill_destroy(rfk);
3171 }
3170 hso_free_net_device(network_table[i]); 3172 hso_free_net_device(network_table[i]);
3171 } 3173 }
3172 } 3174 }
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 867324163ca2..daf4c805be58 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -333,11 +333,11 @@ config USB_ZD1201
333config USB_NET_RNDIS_WLAN 333config USB_NET_RNDIS_WLAN
334 tristate "Wireless RNDIS USB support" 334 tristate "Wireless RNDIS USB support"
335 depends on USB && WLAN_80211 && EXPERIMENTAL 335 depends on USB && WLAN_80211 && EXPERIMENTAL
336 depends on CFG80211
336 select USB_USBNET 337 select USB_USBNET
337 select USB_NET_CDCETHER 338 select USB_NET_CDCETHER
338 select USB_NET_RNDIS_HOST 339 select USB_NET_RNDIS_HOST
339 select WIRELESS_EXT 340 select WIRELESS_EXT
340 select CFG80211
341 ---help--- 341 ---help---
342 This is a driver for wireless RNDIS devices. 342 This is a driver for wireless RNDIS devices.
343 These are USB based adapters found in devices such as: 343 These are USB based adapters found in devices such as:
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
index 17bd3eaf3e03..c7cba66b63cb 100644
--- a/drivers/net/wireless/ath/ar9170/ar9170.h
+++ b/drivers/net/wireless/ath/ar9170/ar9170.h
@@ -91,6 +91,7 @@ struct ar9170_led {
91 struct led_classdev l; 91 struct led_classdev l;
92 char name[32]; 92 char name[32];
93 unsigned int toggled; 93 unsigned int toggled;
94 bool last_state;
94 bool registered; 95 bool registered;
95}; 96};
96 97
@@ -101,7 +102,6 @@ enum ar9170_device_state {
101 AR9170_STOPPED, 102 AR9170_STOPPED,
102 AR9170_IDLE, 103 AR9170_IDLE,
103 AR9170_STARTED, 104 AR9170_STARTED,
104 AR9170_ASSOCIATED,
105}; 105};
106 106
107struct ar9170_rxstream_mpdu_merge { 107struct ar9170_rxstream_mpdu_merge {
@@ -140,7 +140,7 @@ struct ar9170 {
140 struct work_struct filter_config_work; 140 struct work_struct filter_config_work;
141 u64 cur_mc_hash, want_mc_hash; 141 u64 cur_mc_hash, want_mc_hash;
142 u32 cur_filter, want_filter; 142 u32 cur_filter, want_filter;
143 unsigned int filter_changed; 143 unsigned long filter_changed;
144 unsigned int filter_state; 144 unsigned int filter_state;
145 bool sniffer_enabled; 145 bool sniffer_enabled;
146 146
@@ -195,7 +195,7 @@ struct ar9170_sta_info {
195#define IS_STARTED(a) (a->state >= AR9170_STARTED) 195#define IS_STARTED(a) (a->state >= AR9170_STARTED)
196#define IS_ACCEPTING_CMD(a) (a->state >= AR9170_IDLE) 196#define IS_ACCEPTING_CMD(a) (a->state >= AR9170_IDLE)
197 197
198#define AR9170_FILTER_CHANGED_PROMISC BIT(0) 198#define AR9170_FILTER_CHANGED_MODE BIT(0)
199#define AR9170_FILTER_CHANGED_MULTICAST BIT(1) 199#define AR9170_FILTER_CHANGED_MULTICAST BIT(1)
200#define AR9170_FILTER_CHANGED_FRAMEFILTER BIT(2) 200#define AR9170_FILTER_CHANGED_FRAMEFILTER BIT(2)
201 201
@@ -206,6 +206,7 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb);
206void ar9170_unregister(struct ar9170 *ar); 206void ar9170_unregister(struct ar9170 *ar);
207void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, 207void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
208 bool update_statistics, u16 tx_status); 208 bool update_statistics, u16 tx_status);
209void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len);
209 210
210/* MAC */ 211/* MAC */
211int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); 212int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -215,6 +216,9 @@ int ar9170_update_multicast(struct ar9170 *ar);
215int ar9170_update_frame_filter(struct ar9170 *ar); 216int ar9170_update_frame_filter(struct ar9170 *ar);
216int ar9170_set_operating_mode(struct ar9170 *ar); 217int ar9170_set_operating_mode(struct ar9170 *ar);
217int ar9170_set_beacon_timers(struct ar9170 *ar); 218int ar9170_set_beacon_timers(struct ar9170 *ar);
219int ar9170_set_dyn_sifs_ack(struct ar9170 *ar);
220int ar9170_set_slot_time(struct ar9170 *ar);
221int ar9170_set_basic_rates(struct ar9170 *ar);
218int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry); 222int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry);
219int ar9170_update_beacon(struct ar9170 *ar); 223int ar9170_update_beacon(struct ar9170 *ar);
220void ar9170_new_beacon(struct work_struct *work); 224void ar9170_new_beacon(struct work_struct *work);
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h
index 3293e0fb24fb..3c8004fb7307 100644
--- a/drivers/net/wireless/ath/ar9170/hw.h
+++ b/drivers/net/wireless/ath/ar9170/hw.h
@@ -207,7 +207,8 @@ enum ar9170_cmd {
207#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xB44) 207#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xB44)
208#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xB48) 208#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xB48)
209 209
210#define AR9170_MAC_REG_AMPDU_SET (AR9170_MAC_REG_BASE + 0xba0) 210#define AR9170_MAC_REG_AMPDU_FACTOR (AR9170_MAC_REG_BASE + 0xB9C)
211#define AR9170_MAC_REG_AMPDU_DENSITY (AR9170_MAC_REG_BASE + 0xBA0)
211 212
212#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xC00) 213#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xC00)
213#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xC50) 214#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xC50)
@@ -376,7 +377,6 @@ static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t)
376#define AR9170_RX_ERROR_FATAL 0x80 377#define AR9170_RX_ERROR_FATAL 0x80
377 378
378struct ar9170_cmd_tx_status { 379struct ar9170_cmd_tx_status {
379 __le16 unkn;
380 u8 dst[ETH_ALEN]; 380 u8 dst[ETH_ALEN];
381 __le32 rate; 381 __le32 rate;
382 __le16 status; 382 __le16 status;
@@ -394,6 +394,7 @@ struct ar9170_cmd_ba_failed_count {
394struct ar9170_cmd_response { 394struct ar9170_cmd_response {
395 u8 flag; 395 u8 flag;
396 u8 type; 396 u8 type;
397 __le16 padding;
397 398
398 union { 399 union {
399 struct ar9170_cmd_tx_status tx_status; 400 struct ar9170_cmd_tx_status tx_status;
diff --git a/drivers/net/wireless/ath/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c
index 341cead7f606..63fda6cd2101 100644
--- a/drivers/net/wireless/ath/ar9170/led.c
+++ b/drivers/net/wireless/ath/ar9170/led.c
@@ -74,7 +74,7 @@ static void ar9170_update_leds(struct work_struct *work)
74 74
75 mutex_lock(&ar->mutex); 75 mutex_lock(&ar->mutex);
76 for (i = 0; i < AR9170_NUM_LEDS; i++) 76 for (i = 0; i < AR9170_NUM_LEDS; i++)
77 if (ar->leds[i].toggled) { 77 if (ar->leds[i].registered && ar->leds[i].toggled) {
78 led_val |= 1 << i; 78 led_val |= 1 << i;
79 79
80 tmp = 70 + 200 / (ar->leds[i].toggled); 80 tmp = 70 + 200 / (ar->leds[i].toggled);
@@ -101,9 +101,15 @@ static void ar9170_led_brightness_set(struct led_classdev *led,
101 struct ar9170_led *arl = container_of(led, struct ar9170_led, l); 101 struct ar9170_led *arl = container_of(led, struct ar9170_led, l);
102 struct ar9170 *ar = arl->ar; 102 struct ar9170 *ar = arl->ar;
103 103
104 arl->toggled++; 104 if (unlikely(!arl->registered))
105 return ;
106
107 if (arl->last_state != !!brightness) {
108 arl->toggled++;
109 arl->last_state = !!brightness;
110 }
105 111
106 if (likely(IS_ACCEPTING_CMD(ar) && brightness)) 112 if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled))
107 queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10); 113 queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10);
108} 114}
109 115
@@ -136,13 +142,14 @@ void ar9170_unregister_leds(struct ar9170 *ar)
136{ 142{
137 int i; 143 int i;
138 144
139 cancel_delayed_work_sync(&ar->led_work);
140
141 for (i = 0; i < AR9170_NUM_LEDS; i++) 145 for (i = 0; i < AR9170_NUM_LEDS; i++)
142 if (ar->leds[i].registered) { 146 if (ar->leds[i].registered) {
143 led_classdev_unregister(&ar->leds[i].l); 147 led_classdev_unregister(&ar->leds[i].l);
144 ar->leds[i].registered = false; 148 ar->leds[i].registered = false;
149 ar->leds[i].toggled = 0;
145 } 150 }
151
152 cancel_delayed_work_sync(&ar->led_work);
146} 153}
147 154
148int ar9170_register_leds(struct ar9170 *ar) 155int ar9170_register_leds(struct ar9170 *ar)
diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c
index 43aeb69685d3..d9f1f46de183 100644
--- a/drivers/net/wireless/ath/ar9170/mac.c
+++ b/drivers/net/wireless/ath/ar9170/mac.c
@@ -38,6 +38,55 @@
38#include "ar9170.h" 38#include "ar9170.h"
39#include "cmd.h" 39#include "cmd.h"
40 40
41int ar9170_set_dyn_sifs_ack(struct ar9170 *ar)
42{
43 u32 val;
44
45 if (conf_is_ht40(&ar->hw->conf))
46 val = 0x010a;
47 else {
48 if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
49 val = 0x105;
50 else
51 val = 0x104;
52 }
53
54 return ar9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val);
55}
56
57int ar9170_set_slot_time(struct ar9170 *ar)
58{
59 u32 slottime = 20;
60
61 if (!ar->vif)
62 return 0;
63
64 if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) ||
65 ar->vif->bss_conf.use_short_slot)
66 slottime = 9;
67
68 return ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME, slottime << 10);
69}
70
71int ar9170_set_basic_rates(struct ar9170 *ar)
72{
73 u8 cck, ofdm;
74
75 if (!ar->vif)
76 return 0;
77
78 ofdm = ar->vif->bss_conf.basic_rates >> 4;
79
80 /* FIXME: is still necessary? */
81 if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
82 cck = 0;
83 else
84 cck = ar->vif->bss_conf.basic_rates & 0xf;
85
86 return ar9170_write_reg(ar, AR9170_MAC_REG_BASIC_RATE,
87 ofdm << 8 | cck);
88}
89
41int ar9170_set_qos(struct ar9170 *ar) 90int ar9170_set_qos(struct ar9170 *ar)
42{ 91{
43 ar9170_regwrite_begin(ar); 92 ar9170_regwrite_begin(ar);
@@ -84,7 +133,7 @@ static int ar9170_set_ampdu_density(struct ar9170 *ar, u8 mpdudensity)
84 val = 0x140a00 | (mpdudensity ? (mpdudensity + 1) : 0); 133 val = 0x140a00 | (mpdudensity ? (mpdudensity + 1) : 0);
85 134
86 ar9170_regwrite_begin(ar); 135 ar9170_regwrite_begin(ar);
87 ar9170_regwrite(AR9170_MAC_REG_AMPDU_SET, val); 136 ar9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, val);
88 ar9170_regwrite_finish(); 137 ar9170_regwrite_finish();
89 138
90 return ar9170_regwrite_result(); 139 return ar9170_regwrite_result();
@@ -398,10 +447,10 @@ int ar9170_update_beacon(struct ar9170 *ar)
398 /* XXX: use skb->cb info */ 447 /* XXX: use skb->cb info */
399 if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) 448 if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
400 ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP, 449 ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
401 ((skb->len + 4) << (3+16)) + 0x0400); 450 ((skb->len + 4) << (3 + 16)) + 0x0400);
402 else 451 else
403 ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP, 452 ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
404 ((skb->len + 4) << (3+16)) + 0x0400); 453 ((skb->len + 4) << 16) + 0x001b);
405 454
406 ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4); 455 ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4);
407 ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS); 456 ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS);
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index 99df9ddae9cb..b104d7efd676 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -146,7 +146,6 @@ static struct ieee80211_channel ar9170_5ghz_chantable[] = {
146{ \ 146{ \
147 .ht_supported = true, \ 147 .ht_supported = true, \
148 .cap = IEEE80211_HT_CAP_MAX_AMSDU | \ 148 .cap = IEEE80211_HT_CAP_MAX_AMSDU | \
149 IEEE80211_HT_CAP_SM_PS | \
150 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \ 149 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
151 IEEE80211_HT_CAP_SGI_40 | \ 150 IEEE80211_HT_CAP_SGI_40 | \
152 IEEE80211_HT_CAP_DSSSCCK40 | \ 151 IEEE80211_HT_CAP_DSSSCCK40 | \
@@ -344,7 +343,6 @@ static void ar9170_tx_status_janitor(struct work_struct *work)
344 if (unlikely(!IS_STARTED(ar))) 343 if (unlikely(!IS_STARTED(ar)))
345 return ; 344 return ;
346 345
347 mutex_lock(&ar->mutex);
348 /* recycle the garbage back to mac80211... one by one. */ 346 /* recycle the garbage back to mac80211... one by one. */
349 while ((skb = skb_dequeue(&ar->global_tx_status_waste))) { 347 while ((skb = skb_dequeue(&ar->global_tx_status_waste))) {
350#ifdef AR9170_QUEUE_DEBUG 348#ifdef AR9170_QUEUE_DEBUG
@@ -370,12 +368,9 @@ static void ar9170_tx_status_janitor(struct work_struct *work)
370 if (skb_queue_len(&ar->global_tx_status_waste) > 0) 368 if (skb_queue_len(&ar->global_tx_status_waste) > 0)
371 queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor, 369 queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
372 msecs_to_jiffies(100)); 370 msecs_to_jiffies(100));
373
374 mutex_unlock(&ar->mutex);
375} 371}
376 372
377static void ar9170_handle_command_response(struct ar9170 *ar, 373void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
378 void *buf, u32 len)
379{ 374{
380 struct ar9170_cmd_response *cmd = (void *) buf; 375 struct ar9170_cmd_response *cmd = (void *) buf;
381 376
@@ -957,6 +952,8 @@ static int ar9170_op_start(struct ieee80211_hw *hw)
957 952
958 mutex_lock(&ar->mutex); 953 mutex_lock(&ar->mutex);
959 954
955 ar->filter_changed = 0;
956
960 /* reinitialize queues statistics */ 957 /* reinitialize queues statistics */
961 memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); 958 memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
962 for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++) 959 for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++)
@@ -1012,10 +1009,10 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
1012 1009
1013 flush_workqueue(ar->hw->workqueue); 1010 flush_workqueue(ar->hw->workqueue);
1014 1011
1015 mutex_lock(&ar->mutex);
1016 cancel_delayed_work_sync(&ar->tx_status_janitor); 1012 cancel_delayed_work_sync(&ar->tx_status_janitor);
1017 cancel_work_sync(&ar->filter_config_work); 1013 cancel_work_sync(&ar->filter_config_work);
1018 cancel_work_sync(&ar->beacon_work); 1014 cancel_work_sync(&ar->beacon_work);
1015 mutex_lock(&ar->mutex);
1019 skb_queue_purge(&ar->global_tx_status_waste); 1016 skb_queue_purge(&ar->global_tx_status_waste);
1020 skb_queue_purge(&ar->global_tx_status); 1017 skb_queue_purge(&ar->global_tx_status);
1021 1018
@@ -1306,11 +1303,6 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
1306 1303
1307 mutex_lock(&ar->mutex); 1304 mutex_lock(&ar->mutex);
1308 1305
1309 if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
1310 /* TODO */
1311 err = 0;
1312 }
1313
1314 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { 1306 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
1315 /* TODO */ 1307 /* TODO */
1316 err = 0; 1308 err = 0;
@@ -1344,15 +1336,21 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
1344 } 1336 }
1345 1337
1346 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 1338 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1339
1340 /* adjust slot time for 5 GHz */
1341 err = ar9170_set_slot_time(ar);
1342 if (err)
1343 goto out;
1344
1345 err = ar9170_set_dyn_sifs_ack(ar);
1346 if (err)
1347 goto out;
1348
1347 err = ar9170_set_channel(ar, hw->conf.channel, 1349 err = ar9170_set_channel(ar, hw->conf.channel,
1348 AR9170_RFI_NONE, 1350 AR9170_RFI_NONE,
1349 nl80211_to_ar9170(hw->conf.channel_type)); 1351 nl80211_to_ar9170(hw->conf.channel_type));
1350 if (err) 1352 if (err)
1351 goto out; 1353 goto out;
1352 /* adjust slot time for 5 GHz */
1353 if (hw->conf.channel->band == IEEE80211_BAND_5GHZ)
1354 err = ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
1355 9 << 10);
1356 } 1354 }
1357 1355
1358out: 1356out:
@@ -1370,20 +1368,26 @@ static void ar9170_set_filters(struct work_struct *work)
1370 return ; 1368 return ;
1371 1369
1372 mutex_lock(&ar->mutex); 1370 mutex_lock(&ar->mutex);
1373 if (ar->filter_changed & AR9170_FILTER_CHANGED_PROMISC) { 1371 if (test_and_clear_bit(AR9170_FILTER_CHANGED_MODE,
1372 &ar->filter_changed)) {
1374 err = ar9170_set_operating_mode(ar); 1373 err = ar9170_set_operating_mode(ar);
1375 if (err) 1374 if (err)
1376 goto unlock; 1375 goto unlock;
1377 } 1376 }
1378 1377
1379 if (ar->filter_changed & AR9170_FILTER_CHANGED_MULTICAST) { 1378 if (test_and_clear_bit(AR9170_FILTER_CHANGED_MULTICAST,
1379 &ar->filter_changed)) {
1380 err = ar9170_update_multicast(ar); 1380 err = ar9170_update_multicast(ar);
1381 if (err) 1381 if (err)
1382 goto unlock; 1382 goto unlock;
1383 } 1383 }
1384 1384
1385 if (ar->filter_changed & AR9170_FILTER_CHANGED_FRAMEFILTER) 1385 if (test_and_clear_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
1386 &ar->filter_changed)) {
1386 err = ar9170_update_frame_filter(ar); 1387 err = ar9170_update_frame_filter(ar);
1388 if (err)
1389 goto unlock;
1390 }
1387 1391
1388unlock: 1392unlock:
1389 mutex_unlock(&ar->mutex); 1393 mutex_unlock(&ar->mutex);
@@ -1413,7 +1417,7 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
1413 int i; 1417 int i;
1414 1418
1415 /* always get broadcast frames */ 1419 /* always get broadcast frames */
1416 mchash = 1ULL << (0xff>>2); 1420 mchash = 1ULL << (0xff >> 2);
1417 1421
1418 for (i = 0; i < mc_count; i++) { 1422 for (i = 0; i < mc_count; i++) {
1419 if (WARN_ON(!mclist)) 1423 if (WARN_ON(!mclist))
@@ -1423,7 +1427,7 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
1423 } 1427 }
1424 ar->want_mc_hash = mchash; 1428 ar->want_mc_hash = mchash;
1425 } 1429 }
1426 ar->filter_changed |= AR9170_FILTER_CHANGED_MULTICAST; 1430 set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed);
1427 } 1431 }
1428 1432
1429 if (changed_flags & FIF_CONTROL) { 1433 if (changed_flags & FIF_CONTROL) {
@@ -1439,12 +1443,14 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
1439 else 1443 else
1440 ar->want_filter = ar->cur_filter & ~filter; 1444 ar->want_filter = ar->cur_filter & ~filter;
1441 1445
1442 ar->filter_changed |= AR9170_FILTER_CHANGED_FRAMEFILTER; 1446 set_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
1447 &ar->filter_changed);
1443 } 1448 }
1444 1449
1445 if (changed_flags & FIF_PROMISC_IN_BSS) { 1450 if (changed_flags & FIF_PROMISC_IN_BSS) {
1446 ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0; 1451 ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
1447 ar->filter_changed |= AR9170_FILTER_CHANGED_PROMISC; 1452 set_bit(AR9170_FILTER_CHANGED_MODE,
1453 &ar->filter_changed);
1448 } 1454 }
1449 1455
1450 if (likely(IS_STARTED(ar))) 1456 if (likely(IS_STARTED(ar)))
@@ -1464,27 +1470,32 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
1464 if (changed & BSS_CHANGED_BSSID) { 1470 if (changed & BSS_CHANGED_BSSID) {
1465 memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN); 1471 memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN);
1466 err = ar9170_set_operating_mode(ar); 1472 err = ar9170_set_operating_mode(ar);
1473 if (err)
1474 goto out;
1467 } 1475 }
1468 1476
1469 if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) { 1477 if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) {
1470 err = ar9170_update_beacon(ar); 1478 err = ar9170_update_beacon(ar);
1471 if (!err) 1479 if (err)
1472 ar9170_set_beacon_timers(ar); 1480 goto out;
1473 }
1474 1481
1475 ar9170_regwrite_begin(ar); 1482 err = ar9170_set_beacon_timers(ar);
1483 if (err)
1484 goto out;
1485 }
1476 1486
1477 if (changed & BSS_CHANGED_ASSOC) { 1487 if (changed & BSS_CHANGED_ASSOC) {
1478 ar->state = bss_conf->assoc ? AR9170_ASSOCIATED : ar->state;
1479
1480#ifndef CONFIG_AR9170_LEDS 1488#ifndef CONFIG_AR9170_LEDS
1481 /* enable assoc LED. */ 1489 /* enable assoc LED. */
1482 err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0); 1490 err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
1483#endif /* CONFIG_AR9170_LEDS */ 1491#endif /* CONFIG_AR9170_LEDS */
1484 } 1492 }
1485 1493
1486 if (changed & BSS_CHANGED_BEACON_INT) 1494 if (changed & BSS_CHANGED_BEACON_INT) {
1487 err = ar9170_set_beacon_timers(ar); 1495 err = ar9170_set_beacon_timers(ar);
1496 if (err)
1497 goto out;
1498 }
1488 1499
1489 if (changed & BSS_CHANGED_HT) { 1500 if (changed & BSS_CHANGED_HT) {
1490 /* TODO */ 1501 /* TODO */
@@ -1492,31 +1503,18 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
1492 } 1503 }
1493 1504
1494 if (changed & BSS_CHANGED_ERP_SLOT) { 1505 if (changed & BSS_CHANGED_ERP_SLOT) {
1495 u32 slottime = 20; 1506 err = ar9170_set_slot_time(ar);
1496 1507 if (err)
1497 if (bss_conf->use_short_slot) 1508 goto out;
1498 slottime = 9;
1499
1500 ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, slottime << 10);
1501 } 1509 }
1502 1510
1503 if (changed & BSS_CHANGED_BASIC_RATES) { 1511 if (changed & BSS_CHANGED_BASIC_RATES) {
1504 u32 cck, ofdm; 1512 err = ar9170_set_basic_rates(ar);
1505 1513 if (err)
1506 if (hw->conf.channel->band == IEEE80211_BAND_5GHZ) { 1514 goto out;
1507 ofdm = bss_conf->basic_rates;
1508 cck = 0;
1509 } else {
1510 /* four cck rates */
1511 cck = bss_conf->basic_rates & 0xf;
1512 ofdm = bss_conf->basic_rates >> 4;
1513 }
1514 ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE,
1515 ofdm << 8 | cck);
1516 } 1515 }
1517 1516
1518 ar9170_regwrite_finish(); 1517out:
1519 err = ar9170_regwrite_result();
1520 mutex_unlock(&ar->mutex); 1518 mutex_unlock(&ar->mutex);
1521} 1519}
1522 1520
diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c
index 6ce20754b8e7..df86f70cd817 100644
--- a/drivers/net/wireless/ath/ar9170/phy.c
+++ b/drivers/net/wireless/ath/ar9170/phy.c
@@ -401,7 +401,7 @@ int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
401 int i, err; 401 int i, err;
402 u32 val; 402 u32 val;
403 bool is_2ghz = band == IEEE80211_BAND_2GHZ; 403 bool is_2ghz = band == IEEE80211_BAND_2GHZ;
404 bool is_40mhz = false; /* XXX: for now */ 404 bool is_40mhz = conf_is_ht40(&ar->hw->conf);
405 405
406 ar9170_regwrite_begin(ar); 406 ar9170_regwrite_begin(ar);
407 407
@@ -1200,7 +1200,7 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1200 return -ENOSYS; 1200 return -ENOSYS;
1201 } 1201 }
1202 1202
1203 if (0 /* 2 streams capable */) 1203 if (ar->eeprom.tx_mask != 1)
1204 tmp |= 0x100; 1204 tmp |= 0x100;
1205 1205
1206 err = ar9170_write_reg(ar, 0x1c5804, tmp); 1206 err = ar9170_write_reg(ar, 0x1c5804, tmp);
@@ -1214,7 +1214,7 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1214 freqpar = ar9170_get_hw_dyn_params(channel, bw); 1214 freqpar = ar9170_get_hw_dyn_params(channel, bw);
1215 1215
1216 vals[0] = cpu_to_le32(channel->center_freq * 1000); 1216 vals[0] = cpu_to_le32(channel->center_freq * 1000);
1217 vals[1] = cpu_to_le32(bw == AR9170_BW_20 ? 0 : 1); 1217 vals[1] = cpu_to_le32(conf_is_ht40(&ar->hw->conf));
1218 vals[2] = cpu_to_le32(offs << 2 | 1); 1218 vals[2] = cpu_to_le32(offs << 2 | 1);
1219 vals[3] = cpu_to_le32(freqpar->coeff_exp); 1219 vals[3] = cpu_to_le32(freqpar->coeff_exp);
1220 vals[4] = cpu_to_le32(freqpar->coeff_man); 1220 vals[4] = cpu_to_le32(freqpar->coeff_man);
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
index d7c13c0177ca..f752698669d2 100644
--- a/drivers/net/wireless/ath/ar9170/usb.c
+++ b/drivers/net/wireless/ath/ar9170/usb.c
@@ -51,9 +51,14 @@ MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
51MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>"); 51MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
52MODULE_LICENSE("GPL"); 52MODULE_LICENSE("GPL");
53MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless"); 53MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
54MODULE_FIRMWARE("ar9170.fw");
54MODULE_FIRMWARE("ar9170-1.fw"); 55MODULE_FIRMWARE("ar9170-1.fw");
55MODULE_FIRMWARE("ar9170-2.fw"); 56MODULE_FIRMWARE("ar9170-2.fw");
56 57
58enum ar9170_requirements {
59 AR9170_REQ_FW1_ONLY = 1,
60};
61
57static struct usb_device_id ar9170_usb_ids[] = { 62static struct usb_device_id ar9170_usb_ids[] = {
58 /* Atheros 9170 */ 63 /* Atheros 9170 */
59 { USB_DEVICE(0x0cf3, 0x9170) }, 64 { USB_DEVICE(0x0cf3, 0x9170) },
@@ -81,6 +86,10 @@ static struct usb_device_id ar9170_usb_ids[] = {
81 { USB_DEVICE(0x2019, 0x5304) }, 86 { USB_DEVICE(0x2019, 0x5304) },
82 /* IO-Data WNGDNUS2 */ 87 /* IO-Data WNGDNUS2 */
83 { USB_DEVICE(0x04bb, 0x093f) }, 88 { USB_DEVICE(0x04bb, 0x093f) },
89 /* AVM FRITZ!WLAN USB Stick N */
90 { USB_DEVICE(0x057C, 0x8401) },
91 /* AVM FRITZ!WLAN USB Stick N 2.4 */
92 { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
84 93
85 /* terminate */ 94 /* terminate */
86 {} 95 {}
@@ -93,7 +102,7 @@ static void ar9170_usb_tx_urb_complete_free(struct urb *urb)
93 struct ar9170_usb *aru = (struct ar9170_usb *) 102 struct ar9170_usb *aru = (struct ar9170_usb *)
94 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); 103 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
95 104
96 if (!aru) { 105 if (unlikely(!aru)) {
97 dev_kfree_skb_irq(skb); 106 dev_kfree_skb_irq(skb);
98 return ; 107 return ;
99 } 108 }
@@ -126,8 +135,8 @@ static void ar9170_usb_irq_completed(struct urb *urb)
126 goto resubmit; 135 goto resubmit;
127 } 136 }
128 137
129 print_hex_dump_bytes("ar9170 irq: ", DUMP_PREFIX_OFFSET, 138 ar9170_handle_command_response(&aru->common, urb->transfer_buffer,
130 urb->transfer_buffer, urb->actual_length); 139 urb->actual_length);
131 140
132resubmit: 141resubmit:
133 usb_anchor_urb(urb, &aru->rx_submitted); 142 usb_anchor_urb(urb, &aru->rx_submitted);
@@ -177,16 +186,15 @@ resubmit:
177 186
178 usb_anchor_urb(urb, &aru->rx_submitted); 187 usb_anchor_urb(urb, &aru->rx_submitted);
179 err = usb_submit_urb(urb, GFP_ATOMIC); 188 err = usb_submit_urb(urb, GFP_ATOMIC);
180 if (err) { 189 if (unlikely(err)) {
181 usb_unanchor_urb(urb); 190 usb_unanchor_urb(urb);
182 dev_kfree_skb_irq(skb); 191 goto free;
183 } 192 }
184 193
185 return ; 194 return ;
186 195
187free: 196free:
188 dev_kfree_skb_irq(skb); 197 dev_kfree_skb_irq(skb);
189 return;
190} 198}
191 199
192static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru, 200static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
@@ -337,7 +345,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
337 345
338 usb_anchor_urb(urb, &aru->tx_submitted); 346 usb_anchor_urb(urb, &aru->tx_submitted);
339 err = usb_submit_urb(urb, GFP_ATOMIC); 347 err = usb_submit_urb(urb, GFP_ATOMIC);
340 if (err) { 348 if (unlikely(err)) {
341 usb_unanchor_urb(urb); 349 usb_unanchor_urb(urb);
342 usb_free_urb(urb); 350 usb_free_urb(urb);
343 goto err_unbuf; 351 goto err_unbuf;
@@ -418,7 +426,7 @@ static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
418 unsigned long flags; 426 unsigned long flags;
419 u32 in, out; 427 u32 in, out;
420 428
421 if (!buffer) 429 if (unlikely(!buffer))
422 return ; 430 return ;
423 431
424 in = le32_to_cpup((__le32 *)buffer); 432 in = le32_to_cpup((__le32 *)buffer);
@@ -504,17 +512,29 @@ static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
504{ 512{
505 int err = 0; 513 int err = 0;
506 514
507 err = request_firmware(&aru->init_values, "ar9170-1.fw", 515 err = request_firmware(&aru->firmware, "ar9170.fw",
508 &aru->udev->dev); 516 &aru->udev->dev);
509 if (err) { 517 if (!err) {
510 dev_err(&aru->udev->dev, "file with init values not found.\n"); 518 aru->init_values = NULL;
511 return err; 519 return 0;
512 } 520 }
513 521
522 if (aru->req_one_stage_fw) {
523 dev_err(&aru->udev->dev, "ar9170.fw firmware file "
524 "not found and is required for this device\n");
525 return -EINVAL;
526 }
527
528 dev_err(&aru->udev->dev, "ar9170.fw firmware file "
529 "not found, trying old firmware...\n");
530
531 err = request_firmware(&aru->init_values, "ar9170-1.fw",
532 &aru->udev->dev);
533
514 err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev); 534 err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
515 if (err) { 535 if (err) {
516 release_firmware(aru->init_values); 536 release_firmware(aru->init_values);
517 dev_err(&aru->udev->dev, "firmware file not found.\n"); 537 dev_err(&aru->udev->dev, "file with init values not found.\n");
518 return err; 538 return err;
519 } 539 }
520 540
@@ -548,6 +568,9 @@ static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
548{ 568{
549 int err; 569 int err;
550 570
571 if (!aru->init_values)
572 goto upload_fw_start;
573
551 /* First, upload initial values to device RAM */ 574 /* First, upload initial values to device RAM */
552 err = ar9170_usb_upload(aru, aru->init_values->data, 575 err = ar9170_usb_upload(aru, aru->init_values->data,
553 aru->init_values->size, 0x102800, false); 576 aru->init_values->size, 0x102800, false);
@@ -557,6 +580,8 @@ static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
557 return err; 580 return err;
558 } 581 }
559 582
583upload_fw_start:
584
560 /* Then, upload the firmware itself and start it */ 585 /* Then, upload the firmware itself and start it */
561 return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size, 586 return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
562 0x200000, true); 587 0x200000, true);
@@ -656,6 +681,15 @@ err_out:
656 return err; 681 return err;
657} 682}
658 683
684static bool ar9170_requires_one_stage(const struct usb_device_id *id)
685{
686 if (!id->driver_info)
687 return false;
688 if (id->driver_info == AR9170_REQ_FW1_ONLY)
689 return true;
690 return false;
691}
692
659static int ar9170_usb_probe(struct usb_interface *intf, 693static int ar9170_usb_probe(struct usb_interface *intf,
660 const struct usb_device_id *id) 694 const struct usb_device_id *id)
661{ 695{
@@ -676,6 +710,8 @@ static int ar9170_usb_probe(struct usb_interface *intf,
676 aru->intf = intf; 710 aru->intf = intf;
677 ar = &aru->common; 711 ar = &aru->common;
678 712
713 aru->req_one_stage_fw = ar9170_requires_one_stage(id);
714
679 usb_set_intfdata(intf, aru); 715 usb_set_intfdata(intf, aru);
680 SET_IEEE80211_DEV(ar->hw, &udev->dev); 716 SET_IEEE80211_DEV(ar->hw, &udev->dev);
681 717
@@ -691,7 +727,7 @@ static int ar9170_usb_probe(struct usb_interface *intf,
691 727
692#ifdef CONFIG_PM 728#ifdef CONFIG_PM
693 udev->reset_resume = 1; 729 udev->reset_resume = 1;
694#endif 730#endif /* CONFIG_PM */
695 err = ar9170_usb_reset(aru); 731 err = ar9170_usb_reset(aru);
696 if (err) 732 if (err)
697 goto err_freehw; 733 goto err_freehw;
@@ -776,11 +812,6 @@ static int ar9170_resume(struct usb_interface *intf)
776 usb_unpoison_anchored_urbs(&aru->rx_submitted); 812 usb_unpoison_anchored_urbs(&aru->rx_submitted);
777 usb_unpoison_anchored_urbs(&aru->tx_submitted); 813 usb_unpoison_anchored_urbs(&aru->tx_submitted);
778 814
779 /*
780 * FIXME: firmware upload will fail on resume.
781 * but this is better than a hang!
782 */
783
784 err = ar9170_usb_init_device(aru); 815 err = ar9170_usb_init_device(aru);
785 if (err) 816 if (err)
786 goto err_unrx; 817 goto err_unrx;
diff --git a/drivers/net/wireless/ath/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h
index ac42586495d8..69f4bceb0af3 100644
--- a/drivers/net/wireless/ath/ar9170/usb.h
+++ b/drivers/net/wireless/ath/ar9170/usb.h
@@ -62,6 +62,8 @@ struct ar9170_usb {
62 struct usb_anchor rx_submitted; 62 struct usb_anchor rx_submitted;
63 struct usb_anchor tx_submitted; 63 struct usb_anchor tx_submitted;
64 64
65 bool req_one_stage_fw;
66
65 spinlock_t cmdlock; 67 spinlock_t cmdlock;
66 struct completion cmd_wait; 68 struct completion cmd_wait;
67 int readlen; 69 int readlen;
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index fb5193764afa..85a00db4867d 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2070,6 +2070,13 @@ err_unmap:
2070 return ret; 2070 return ret;
2071} 2071}
2072 2072
2073static void ath5k_beacon_disable(struct ath5k_softc *sc)
2074{
2075 sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
2076 ath5k_hw_set_imr(sc->ah, sc->imask);
2077 ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq);
2078}
2079
2073/* 2080/*
2074 * Transmit a beacon frame at SWBA. Dynamic updates to the 2081 * Transmit a beacon frame at SWBA. Dynamic updates to the
2075 * frame contents are done as needed and the slot time is 2082 * frame contents are done as needed and the slot time is
@@ -2757,6 +2764,7 @@ ath5k_remove_interface(struct ieee80211_hw *hw,
2757 goto end; 2764 goto end;
2758 2765
2759 ath5k_hw_set_lladdr(sc->ah, mac); 2766 ath5k_hw_set_lladdr(sc->ah, mac);
2767 ath5k_beacon_disable(sc);
2760 sc->vif = NULL; 2768 sc->vif = NULL;
2761end: 2769end:
2762 mutex_unlock(&sc->lock); 2770 mutex_unlock(&sc->lock);
@@ -2775,11 +2783,9 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
2775 2783
2776 mutex_lock(&sc->lock); 2784 mutex_lock(&sc->lock);
2777 2785
2778 sc->bintval = conf->beacon_int;
2779
2780 ret = ath5k_chan_set(sc, conf->channel); 2786 ret = ath5k_chan_set(sc, conf->channel);
2781 if (ret < 0) 2787 if (ret < 0)
2782 return ret; 2788 goto unlock;
2783 2789
2784 if ((changed & IEEE80211_CONF_CHANGE_POWER) && 2790 if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
2785 (sc->power_level != conf->power_level)) { 2791 (sc->power_level != conf->power_level)) {
@@ -2808,8 +2814,9 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed)
2808 */ 2814 */
2809 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT); 2815 ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT);
2810 2816
2817unlock:
2811 mutex_unlock(&sc->lock); 2818 mutex_unlock(&sc->lock);
2812 return 0; 2819 return ret;
2813} 2820}
2814 2821
2815#define SUPPORTED_FIF_FLAGS \ 2822#define SUPPORTED_FIF_FLAGS \
@@ -3061,7 +3068,14 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
3061{ 3068{
3062 int ret; 3069 int ret;
3063 struct ath5k_softc *sc = hw->priv; 3070 struct ath5k_softc *sc = hw->priv;
3064 struct sk_buff *skb = ieee80211_beacon_get(hw, vif); 3071 struct sk_buff *skb;
3072
3073 if (WARN_ON(!vif)) {
3074 ret = -EINVAL;
3075 goto out;
3076 }
3077
3078 skb = ieee80211_beacon_get(hw, vif);
3065 3079
3066 if (!skb) { 3080 if (!skb) {
3067 ret = -ENOMEM; 3081 ret = -ENOMEM;
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 796a3adffea0..515880aa2116 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -460,12 +460,9 @@ struct ath_led {
460 bool registered; 460 bool registered;
461}; 461};
462 462
463/* Rfkill */
464#define ATH_RFKILL_POLL_INTERVAL 2000 /* msecs */
465
466struct ath_rfkill { 463struct ath_rfkill {
467 struct rfkill *rfkill; 464 struct rfkill *rfkill;
468 struct delayed_work rfkill_poll; 465 struct rfkill_ops ops;
469 char rfkill_name[32]; 466 char rfkill_name[32];
470}; 467};
471 468
@@ -509,8 +506,6 @@ struct ath_rfkill {
509#define SC_OP_RXFLUSH BIT(7) 506#define SC_OP_RXFLUSH BIT(7)
510#define SC_OP_LED_ASSOCIATED BIT(8) 507#define SC_OP_LED_ASSOCIATED BIT(8)
511#define SC_OP_RFKILL_REGISTERED BIT(9) 508#define SC_OP_RFKILL_REGISTERED BIT(9)
512#define SC_OP_RFKILL_SW_BLOCKED BIT(10)
513#define SC_OP_RFKILL_HW_BLOCKED BIT(11)
514#define SC_OP_WAIT_FOR_BEACON BIT(12) 509#define SC_OP_WAIT_FOR_BEACON BIT(12)
515#define SC_OP_LED_ON BIT(13) 510#define SC_OP_LED_ON BIT(13)
516#define SC_OP_SCANNING BIT(14) 511#define SC_OP_SCANNING BIT(14)
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index a21b21339fbc..3639a2e6987d 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -411,6 +411,7 @@ void ath_beacon_tasklet(unsigned long data)
411 } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { 411 } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
412 DPRINTF(sc, ATH_DBG_BEACON, 412 DPRINTF(sc, ATH_DBG_BEACON,
413 "beacon is officially stuck\n"); 413 "beacon is officially stuck\n");
414 sc->sc_flags |= SC_OP_TSF_RESET;
414 ath_reset(sc, false); 415 ath_reset(sc, false);
415 } 416 }
416 417
@@ -673,6 +674,14 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
673 674
674 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; 675 intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
675 676
677 /*
678 * It looks like mac80211 may end up using beacon interval of zero in
679 * some cases (at least for mesh point). Avoid getting into an
680 * infinite loop by using a bit safer value instead..
681 */
682 if (intval == 0)
683 intval = 100;
684
676 /* Pull nexttbtt forward to reflect the current TSF */ 685 /* Pull nexttbtt forward to reflect the current TSF */
677 686
678 nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp); 687 nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 97df20cbf528..6d20725d6451 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -44,6 +44,44 @@ static int ath9k_debugfs_open(struct inode *inode, struct file *file)
44 return 0; 44 return 0;
45} 45}
46 46
47static ssize_t read_file_debug(struct file *file, char __user *user_buf,
48 size_t count, loff_t *ppos)
49{
50 struct ath_softc *sc = file->private_data;
51 char buf[32];
52 unsigned int len;
53
54 len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.debug_mask);
55 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
56}
57
58static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
59 size_t count, loff_t *ppos)
60{
61 struct ath_softc *sc = file->private_data;
62 unsigned long mask;
63 char buf[32];
64 ssize_t len;
65
66 len = min(count, sizeof(buf) - 1);
67 if (copy_from_user(buf, user_buf, len))
68 return -EINVAL;
69
70 buf[len] = '\0';
71 if (strict_strtoul(buf, 0, &mask))
72 return -EINVAL;
73
74 sc->debug.debug_mask = mask;
75 return count;
76}
77
78static const struct file_operations fops_debug = {
79 .read = read_file_debug,
80 .write = write_file_debug,
81 .open = ath9k_debugfs_open,
82 .owner = THIS_MODULE
83};
84
47static ssize_t read_file_dma(struct file *file, char __user *user_buf, 85static ssize_t read_file_dma(struct file *file, char __user *user_buf,
48 size_t count, loff_t *ppos) 86 size_t count, loff_t *ppos)
49{ 87{
@@ -224,111 +262,66 @@ static const struct file_operations fops_interrupt = {
224 .owner = THIS_MODULE 262 .owner = THIS_MODULE
225}; 263};
226 264
227static void ath_debug_stat_11n_rc(struct ath_softc *sc, struct sk_buff *skb) 265void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
228{
229 struct ath_tx_info_priv *tx_info_priv = NULL;
230 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
231 struct ieee80211_tx_rate *rates = tx_info->status.rates;
232 int final_ts_idx, idx;
233
234 tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
235 final_ts_idx = tx_info_priv->tx.ts_rateindex;
236 idx = sc->cur_rate_table->info[rates[final_ts_idx].idx].dot11rate;
237
238 sc->debug.stats.n_rcstats[idx].success++;
239}
240
241static void ath_debug_stat_legacy_rc(struct ath_softc *sc, struct sk_buff *skb)
242{ 266{
243 struct ath_tx_info_priv *tx_info_priv = NULL; 267 struct ath_tx_info_priv *tx_info_priv = NULL;
244 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 268 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
245 struct ieee80211_tx_rate *rates = tx_info->status.rates; 269 struct ieee80211_tx_rate *rates = tx_info->status.rates;
246 int final_ts_idx, idx; 270 int final_ts_idx, idx;
271 struct ath_rc_stats *stats;
247 272
248 tx_info_priv = ATH_TX_INFO_PRIV(tx_info); 273 tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
249 final_ts_idx = tx_info_priv->tx.ts_rateindex; 274 final_ts_idx = tx_info_priv->tx.ts_rateindex;
250 idx = rates[final_ts_idx].idx; 275 idx = rates[final_ts_idx].idx;
251 276 stats = &sc->debug.stats.rcstats[idx];
252 sc->debug.stats.legacy_rcstats[idx].success++; 277 stats->success++;
253}
254
255void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
256{
257 if (conf_is_ht(&sc->hw->conf))
258 ath_debug_stat_11n_rc(sc, skb);
259 else
260 ath_debug_stat_legacy_rc(sc, skb);
261} 278}
262 279
263/* FIXME: legacy rates, later on .. */
264void ath_debug_stat_retries(struct ath_softc *sc, int rix, 280void ath_debug_stat_retries(struct ath_softc *sc, int rix,
265 int xretries, int retries, u8 per) 281 int xretries, int retries, u8 per)
266{ 282{
267 if (conf_is_ht(&sc->hw->conf)) { 283 struct ath_rc_stats *stats = &sc->debug.stats.rcstats[rix];
268 int idx = sc->cur_rate_table->info[rix].dot11rate;
269 284
270 sc->debug.stats.n_rcstats[idx].xretries += xretries; 285 stats->xretries += xretries;
271 sc->debug.stats.n_rcstats[idx].retries += retries; 286 stats->retries += retries;
272 sc->debug.stats.n_rcstats[idx].per = per; 287 stats->per = per;
273 }
274} 288}
275 289
276static ssize_t ath_read_file_stat_11n_rc(struct file *file, 290static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
277 char __user *user_buf, 291 size_t count, loff_t *ppos)
278 size_t count, loff_t *ppos)
279{ 292{
280 struct ath_softc *sc = file->private_data; 293 struct ath_softc *sc = file->private_data;
281 char buf[1024]; 294 char *buf;
282 unsigned int len = 0; 295 unsigned int len = 0, max;
283 int i = 0; 296 int i = 0;
297 ssize_t retval;
284 298
285 len += sprintf(buf, "%7s %13s %8s %8s %6s\n\n", "Rate", "Success", 299 if (sc->cur_rate_table == NULL)
286 "Retries", "XRetries", "PER"); 300 return 0;
287
288 for (i = 0; i <= 15; i++) {
289 len += snprintf(buf + len, sizeof(buf) - len,
290 "%5s%3d: %8u %8u %8u %8u\n", "MCS", i,
291 sc->debug.stats.n_rcstats[i].success,
292 sc->debug.stats.n_rcstats[i].retries,
293 sc->debug.stats.n_rcstats[i].xretries,
294 sc->debug.stats.n_rcstats[i].per);
295 }
296
297 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
298}
299 301
300static ssize_t ath_read_file_stat_legacy_rc(struct file *file, 302 max = 80 + sc->cur_rate_table->rate_cnt * 64;
301 char __user *user_buf, 303 buf = kmalloc(max + 1, GFP_KERNEL);
302 size_t count, loff_t *ppos) 304 if (buf == NULL)
303{ 305 return 0;
304 struct ath_softc *sc = file->private_data; 306 buf[max] = 0;
305 char buf[512];
306 unsigned int len = 0;
307 int i = 0;
308 307
309 len += sprintf(buf, "%7s %13s\n\n", "Rate", "Success"); 308 len += sprintf(buf, "%5s %15s %8s %9s %3s\n\n", "Rate", "Success",
309 "Retries", "XRetries", "PER");
310 310
311 for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) { 311 for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
312 len += snprintf(buf + len, sizeof(buf) - len, "%5u: %12u\n", 312 u32 ratekbps = sc->cur_rate_table->info[i].ratekbps;
313 sc->cur_rate_table->info[i].ratekbps / 1000, 313 struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i];
314 sc->debug.stats.legacy_rcstats[i].success); 314
315 len += snprintf(buf + len, max - len,
316 "%3u.%d: %8u %8u %8u %8u\n", ratekbps / 1000,
317 (ratekbps % 1000) / 100, stats->success,
318 stats->retries, stats->xretries,
319 stats->per);
315 } 320 }
316 321
317 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 322 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
318} 323 kfree(buf);
319 324 return retval;
320static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
321 size_t count, loff_t *ppos)
322{
323 struct ath_softc *sc = file->private_data;
324
325 if (sc->cur_rate_table == NULL)
326 return 0;
327
328 if (conf_is_ht(&sc->hw->conf))
329 return ath_read_file_stat_11n_rc(file, user_buf, count, ppos);
330 else
331 return ath_read_file_stat_legacy_rc(file, user_buf, count ,ppos);
332} 325}
333 326
334static const struct file_operations fops_rcstat = { 327static const struct file_operations fops_rcstat = {
@@ -506,6 +499,11 @@ int ath9k_init_debug(struct ath_softc *sc)
506 if (!sc->debug.debugfs_phy) 499 if (!sc->debug.debugfs_phy)
507 goto err; 500 goto err;
508 501
502 sc->debug.debugfs_debug = debugfs_create_file("debug",
503 S_IRUGO | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug);
504 if (!sc->debug.debugfs_debug)
505 goto err;
506
509 sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO, 507 sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
510 sc->debug.debugfs_phy, sc, &fops_dma); 508 sc->debug.debugfs_phy, sc, &fops_dma);
511 if (!sc->debug.debugfs_dma) 509 if (!sc->debug.debugfs_dma)
@@ -543,6 +541,7 @@ void ath9k_exit_debug(struct ath_softc *sc)
543 debugfs_remove(sc->debug.debugfs_rcstat); 541 debugfs_remove(sc->debug.debugfs_rcstat);
544 debugfs_remove(sc->debug.debugfs_interrupt); 542 debugfs_remove(sc->debug.debugfs_interrupt);
545 debugfs_remove(sc->debug.debugfs_dma); 543 debugfs_remove(sc->debug.debugfs_dma);
544 debugfs_remove(sc->debug.debugfs_debug);
546 debugfs_remove(sc->debug.debugfs_phy); 545 debugfs_remove(sc->debug.debugfs_phy);
547} 546}
548 547
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index db845cf960c9..edda15bf2c15 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -80,11 +80,7 @@ struct ath_interrupt_stats {
80 u32 dtim; 80 u32 dtim;
81}; 81};
82 82
83struct ath_legacy_rc_stats { 83struct ath_rc_stats {
84 u32 success;
85};
86
87struct ath_11n_rc_stats {
88 u32 success; 84 u32 success;
89 u32 retries; 85 u32 retries;
90 u32 xretries; 86 u32 xretries;
@@ -93,13 +89,13 @@ struct ath_11n_rc_stats {
93 89
94struct ath_stats { 90struct ath_stats {
95 struct ath_interrupt_stats istats; 91 struct ath_interrupt_stats istats;
96 struct ath_legacy_rc_stats legacy_rcstats[12]; /* max(11a,11b,11g) */ 92 struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
97 struct ath_11n_rc_stats n_rcstats[16]; /* 0..15 MCS rates */
98}; 93};
99 94
100struct ath9k_debug { 95struct ath9k_debug {
101 int debug_mask; 96 int debug_mask;
102 struct dentry *debugfs_phy; 97 struct dentry *debugfs_phy;
98 struct dentry *debugfs_debug;
103 struct dentry *debugfs_dma; 99 struct dentry *debugfs_dma;
104 struct dentry *debugfs_interrupt; 100 struct dentry *debugfs_interrupt;
105 struct dentry *debugfs_rcstat; 101 struct dentry *debugfs_rcstat;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 61da08a1648c..f7baa406918b 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1192,120 +1192,69 @@ static bool ath_is_rfkill_set(struct ath_softc *sc)
1192 ah->rfkill_polarity; 1192 ah->rfkill_polarity;
1193} 1193}
1194 1194
1195/* h/w rfkill poll function */ 1195/* s/w rfkill handlers */
1196static void ath_rfkill_poll(struct work_struct *work) 1196static int ath_rfkill_set_block(void *data, bool blocked)
1197{ 1197{
1198 struct ath_softc *sc = container_of(work, struct ath_softc, 1198 struct ath_softc *sc = data;
1199 rf_kill.rfkill_poll.work);
1200 bool radio_on;
1201
1202 if (sc->sc_flags & SC_OP_INVALID)
1203 return;
1204
1205 radio_on = !ath_is_rfkill_set(sc);
1206
1207 /*
1208 * enable/disable radio only when there is a
1209 * state change in RF switch
1210 */
1211 if (radio_on == !!(sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED)) {
1212 enum rfkill_state state;
1213
1214 if (sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED) {
1215 state = radio_on ? RFKILL_STATE_SOFT_BLOCKED
1216 : RFKILL_STATE_HARD_BLOCKED;
1217 } else if (radio_on) {
1218 ath_radio_enable(sc);
1219 state = RFKILL_STATE_UNBLOCKED;
1220 } else {
1221 ath_radio_disable(sc);
1222 state = RFKILL_STATE_HARD_BLOCKED;
1223 }
1224
1225 if (state == RFKILL_STATE_HARD_BLOCKED)
1226 sc->sc_flags |= SC_OP_RFKILL_HW_BLOCKED;
1227 else
1228 sc->sc_flags &= ~SC_OP_RFKILL_HW_BLOCKED;
1229 1199
1230 rfkill_force_state(sc->rf_kill.rfkill, state); 1200 if (blocked)
1231 } 1201 ath_radio_disable(sc);
1202 else
1203 ath_radio_enable(sc);
1232 1204
1233 queue_delayed_work(sc->hw->workqueue, &sc->rf_kill.rfkill_poll, 1205 return 0;
1234 msecs_to_jiffies(ATH_RFKILL_POLL_INTERVAL));
1235} 1206}
1236 1207
1237/* s/w rfkill handler */ 1208static void ath_rfkill_poll_state(struct rfkill *rfkill, void *data)
1238static int ath_sw_toggle_radio(void *data, enum rfkill_state state)
1239{ 1209{
1240 struct ath_softc *sc = data; 1210 struct ath_softc *sc = data;
1211 bool blocked = !!ath_is_rfkill_set(sc);
1241 1212
1242 switch (state) { 1213 if (rfkill_set_hw_state(rfkill, blocked))
1243 case RFKILL_STATE_SOFT_BLOCKED: 1214 ath_radio_disable(sc);
1244 if (!(sc->sc_flags & (SC_OP_RFKILL_HW_BLOCKED | 1215 else
1245 SC_OP_RFKILL_SW_BLOCKED))) 1216 ath_radio_enable(sc);
1246 ath_radio_disable(sc);
1247 sc->sc_flags |= SC_OP_RFKILL_SW_BLOCKED;
1248 return 0;
1249 case RFKILL_STATE_UNBLOCKED:
1250 if ((sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED)) {
1251 sc->sc_flags &= ~SC_OP_RFKILL_SW_BLOCKED;
1252 if (sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED) {
1253 DPRINTF(sc, ATH_DBG_FATAL, "Can't turn on the"
1254 "radio as it is disabled by h/w\n");
1255 return -EPERM;
1256 }
1257 ath_radio_enable(sc);
1258 }
1259 return 0;
1260 default:
1261 return -EINVAL;
1262 }
1263} 1217}
1264 1218
1265/* Init s/w rfkill */ 1219/* Init s/w rfkill */
1266static int ath_init_sw_rfkill(struct ath_softc *sc) 1220static int ath_init_sw_rfkill(struct ath_softc *sc)
1267{ 1221{
1268 sc->rf_kill.rfkill = rfkill_allocate(wiphy_dev(sc->hw->wiphy), 1222 sc->rf_kill.ops.set_block = ath_rfkill_set_block;
1269 RFKILL_TYPE_WLAN); 1223 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1224 sc->rf_kill.ops.poll = ath_rfkill_poll_state;
1225
1226 snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name),
1227 "ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy));
1228
1229 sc->rf_kill.rfkill = rfkill_alloc(sc->rf_kill.rfkill_name,
1230 wiphy_dev(sc->hw->wiphy),
1231 RFKILL_TYPE_WLAN,
1232 &sc->rf_kill.ops, sc);
1270 if (!sc->rf_kill.rfkill) { 1233 if (!sc->rf_kill.rfkill) {
1271 DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n"); 1234 DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n");
1272 return -ENOMEM; 1235 return -ENOMEM;
1273 } 1236 }
1274 1237
1275 snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name),
1276 "ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy));
1277 sc->rf_kill.rfkill->name = sc->rf_kill.rfkill_name;
1278 sc->rf_kill.rfkill->data = sc;
1279 sc->rf_kill.rfkill->toggle_radio = ath_sw_toggle_radio;
1280 sc->rf_kill.rfkill->state = RFKILL_STATE_UNBLOCKED;
1281
1282 return 0; 1238 return 0;
1283} 1239}
1284 1240
1285/* Deinitialize rfkill */ 1241/* Deinitialize rfkill */
1286static void ath_deinit_rfkill(struct ath_softc *sc) 1242static void ath_deinit_rfkill(struct ath_softc *sc)
1287{ 1243{
1288 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1289 cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
1290
1291 if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) { 1244 if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) {
1292 rfkill_unregister(sc->rf_kill.rfkill); 1245 rfkill_unregister(sc->rf_kill.rfkill);
1246 rfkill_destroy(sc->rf_kill.rfkill);
1293 sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED; 1247 sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED;
1294 sc->rf_kill.rfkill = NULL;
1295 } 1248 }
1296} 1249}
1297 1250
1298static int ath_start_rfkill_poll(struct ath_softc *sc) 1251static int ath_start_rfkill_poll(struct ath_softc *sc)
1299{ 1252{
1300 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1301 queue_delayed_work(sc->hw->workqueue,
1302 &sc->rf_kill.rfkill_poll, 0);
1303
1304 if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) { 1253 if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) {
1305 if (rfkill_register(sc->rf_kill.rfkill)) { 1254 if (rfkill_register(sc->rf_kill.rfkill)) {
1306 DPRINTF(sc, ATH_DBG_FATAL, 1255 DPRINTF(sc, ATH_DBG_FATAL,
1307 "Unable to register rfkill\n"); 1256 "Unable to register rfkill\n");
1308 rfkill_free(sc->rf_kill.rfkill); 1257 rfkill_destroy(sc->rf_kill.rfkill);
1309 1258
1310 /* Deinitialize the device */ 1259 /* Deinitialize the device */
1311 ath_cleanup(sc); 1260 ath_cleanup(sc);
@@ -1678,10 +1627,6 @@ int ath_attach(u16 devid, struct ath_softc *sc)
1678 goto error_attach; 1627 goto error_attach;
1679 1628
1680#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) 1629#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
1681 /* Initialze h/w Rfkill */
1682 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1683 INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll);
1684
1685 /* Initialize s/w rfkill */ 1630 /* Initialize s/w rfkill */
1686 error = ath_init_sw_rfkill(sc); 1631 error = ath_init_sw_rfkill(sc);
1687 if (error) 1632 if (error)
@@ -2214,10 +2159,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
2214 } else 2159 } else
2215 sc->rx.rxlink = NULL; 2160 sc->rx.rxlink = NULL;
2216 2161
2217#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE) 2162 rfkill_pause_polling(sc->rf_kill.rfkill);
2218 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 2163
2219 cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
2220#endif
2221 /* disable HAL and put h/w to sleep */ 2164 /* disable HAL and put h/w to sleep */
2222 ath9k_hw_disable(sc->sc_ah); 2165 ath9k_hw_disable(sc->sc_ah);
2223 ath9k_hw_configpcipowersave(sc->sc_ah, 1); 2166 ath9k_hw_configpcipowersave(sc->sc_ah, 1);
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 168411d322a2..ccdf20a2e9be 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -227,11 +227,6 @@ static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
227 227
228 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); 228 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
229 229
230#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
231 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
232 cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
233#endif
234
235 pci_save_state(pdev); 230 pci_save_state(pdev);
236 pci_disable_device(pdev); 231 pci_disable_device(pdev);
237 pci_set_power_state(pdev, PCI_D3hot); 232 pci_set_power_state(pdev, PCI_D3hot);
@@ -256,16 +251,6 @@ static int ath_pci_resume(struct pci_dev *pdev)
256 AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 251 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
257 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1); 252 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
258 253
259#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
260 /*
261 * check the h/w rfkill state on resume
262 * and start the rfkill poll timer
263 */
264 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
265 queue_delayed_work(sc->hw->workqueue,
266 &sc->rf_kill.rfkill_poll, 0);
267#endif
268
269 return 0; 254 return 0;
270} 255}
271 256
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
index 7a89f9fac7d4..eef370bd1211 100644
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -366,11 +366,17 @@ static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg)
366 if (rd & COUNTRY_ERD_FLAG) { 366 if (rd & COUNTRY_ERD_FLAG) {
367 /* EEPROM value is a country code */ 367 /* EEPROM value is a country code */
368 u16 cc = rd & ~COUNTRY_ERD_FLAG; 368 u16 cc = rd & ~COUNTRY_ERD_FLAG;
369 printk(KERN_DEBUG
370 "ath: EEPROM indicates we should expect "
371 "a country code\n");
369 for (i = 0; i < ARRAY_SIZE(allCountries); i++) 372 for (i = 0; i < ARRAY_SIZE(allCountries); i++)
370 if (allCountries[i].countryCode == cc) 373 if (allCountries[i].countryCode == cc)
371 return true; 374 return true;
372 } else { 375 } else {
373 /* EEPROM value is a regpair value */ 376 /* EEPROM value is a regpair value */
377 if (rd != CTRY_DEFAULT)
378 printk(KERN_DEBUG "ath: EEPROM indicates we "
379 "should expect a direct regpair map\n");
374 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) 380 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
375 if (regDomainPairs[i].regDmnEnum == rd) 381 if (regDomainPairs[i].regDmnEnum == rd)
376 return true; 382 return true;
@@ -477,6 +483,11 @@ ath_regd_init(struct ath_regulatory *reg,
477 struct country_code_to_enum_rd *country = NULL; 483 struct country_code_to_enum_rd *country = NULL;
478 u16 regdmn; 484 u16 regdmn;
479 485
486 if (!reg)
487 return -EINVAL;
488
489 printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd);
490
480 if (!ath_regd_is_eeprom_valid(reg)) { 491 if (!ath_regd_is_eeprom_valid(reg)) {
481 printk(KERN_ERR "ath: Invalid EEPROM contents\n"); 492 printk(KERN_ERR "ath: Invalid EEPROM contents\n");
482 return -EINVAL; 493 return -EINVAL;
@@ -486,20 +497,30 @@ ath_regd_init(struct ath_regulatory *reg,
486 reg->country_code = ath_regd_get_default_country(regdmn); 497 reg->country_code = ath_regd_get_default_country(regdmn);
487 498
488 if (reg->country_code == CTRY_DEFAULT && 499 if (reg->country_code == CTRY_DEFAULT &&
489 regdmn == CTRY_DEFAULT) 500 regdmn == CTRY_DEFAULT) {
501 printk(KERN_DEBUG "ath: EEPROM indicates default "
502 "country code should be used\n");
490 reg->country_code = CTRY_UNITED_STATES; 503 reg->country_code = CTRY_UNITED_STATES;
504 }
491 505
492 if (reg->country_code == CTRY_DEFAULT) { 506 if (reg->country_code == CTRY_DEFAULT) {
493 country = NULL; 507 country = NULL;
494 } else { 508 } else {
509 printk(KERN_DEBUG "ath: doing EEPROM country->regdmn "
510 "map search\n");
495 country = ath_regd_find_country(reg->country_code); 511 country = ath_regd_find_country(reg->country_code);
496 if (country == NULL) { 512 if (country == NULL) {
497 printk(KERN_DEBUG 513 printk(KERN_DEBUG
498 "ath: Country is NULL!!!!, cc= %d\n", 514 "ath: no valid country maps found for "
515 "country code: 0x%0x\n",
499 reg->country_code); 516 reg->country_code);
500 return -EINVAL; 517 return -EINVAL;
501 } else 518 } else {
502 regdmn = country->regDmnEnum; 519 regdmn = country->regDmnEnum;
520 printk(KERN_DEBUG "ath: country maps to "
521 "regdmn code: 0x%0x\n",
522 regdmn);
523 }
503 } 524 }
504 525
505 reg->regpair = ath_get_regpair(regdmn); 526 reg->regpair = ath_get_regpair(regdmn);
@@ -523,7 +544,7 @@ ath_regd_init(struct ath_regulatory *reg,
523 544
524 printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n", 545 printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n",
525 reg->alpha2[0], reg->alpha2[1]); 546 reg->alpha2[0], reg->alpha2[1]);
526 printk(KERN_DEBUG "ath: Regpair detected: 0x%0x\n", 547 printk(KERN_DEBUG "ath: Regpair used: 0x%0x\n",
527 reg->regpair->regDmnEnum); 548 reg->regpair->regDmnEnum);
528 549
529 ath_regd_init_wiphy(reg, wiphy, reg_notifier); 550 ath_regd_init_wiphy(reg, wiphy, reg_notifier);
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 21572e40b79d..07a99e3faf94 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -102,7 +102,7 @@ config B43_LEDS
102# if it's possible. 102# if it's possible.
103config B43_RFKILL 103config B43_RFKILL
104 bool 104 bool
105 depends on B43 && (RFKILL = y || RFKILL = B43) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43) 105 depends on B43 && (RFKILL = y || RFKILL = B43)
106 default y 106 default y
107 107
108# This config option automatically enables b43 HW-RNG support, 108# This config option automatically enables b43 HW-RNG support,
diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c
index 76f4c7bad8b8..9a498d3fc653 100644
--- a/drivers/net/wireless/b43/leds.c
+++ b/drivers/net/wireless/b43/leds.c
@@ -87,7 +87,7 @@ static void b43_led_brightness_set(struct led_classdev *led_dev,
87} 87}
88 88
89static int b43_register_led(struct b43_wldev *dev, struct b43_led *led, 89static int b43_register_led(struct b43_wldev *dev, struct b43_led *led,
90 const char *name, char *default_trigger, 90 const char *name, const char *default_trigger,
91 u8 led_index, bool activelow) 91 u8 led_index, bool activelow)
92{ 92{
93 int err; 93 int err;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index cb4a8712946a..1d3e40095ada 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3470,7 +3470,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3470 3470
3471 if (!!conf->radio_enabled != phy->radio_on) { 3471 if (!!conf->radio_enabled != phy->radio_on) {
3472 if (conf->radio_enabled) { 3472 if (conf->radio_enabled) {
3473 b43_software_rfkill(dev, RFKILL_STATE_UNBLOCKED); 3473 b43_software_rfkill(dev, false);
3474 b43info(dev->wl, "Radio turned on by software\n"); 3474 b43info(dev->wl, "Radio turned on by software\n");
3475 if (!dev->radio_hw_enable) { 3475 if (!dev->radio_hw_enable) {
3476 b43info(dev->wl, "The hardware RF-kill button " 3476 b43info(dev->wl, "The hardware RF-kill button "
@@ -3478,7 +3478,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3478 "Press the button to turn it on.\n"); 3478 "Press the button to turn it on.\n");
3479 } 3479 }
3480 } else { 3480 } else {
3481 b43_software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED); 3481 b43_software_rfkill(dev, true);
3482 b43info(dev->wl, "Radio turned off by software\n"); 3482 b43info(dev->wl, "Radio turned off by software\n");
3483 } 3483 }
3484 } 3484 }
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c
index c836c077d51d..816e028a2620 100644
--- a/drivers/net/wireless/b43/phy_a.c
+++ b/drivers/net/wireless/b43/phy_a.c
@@ -480,11 +480,11 @@ static bool b43_aphy_op_supports_hwpctl(struct b43_wldev *dev)
480} 480}
481 481
482static void b43_aphy_op_software_rfkill(struct b43_wldev *dev, 482static void b43_aphy_op_software_rfkill(struct b43_wldev *dev,
483 enum rfkill_state state) 483 bool blocked)
484{ 484{
485 struct b43_phy *phy = &dev->phy; 485 struct b43_phy *phy = &dev->phy;
486 486
487 if (state == RFKILL_STATE_UNBLOCKED) { 487 if (!blocked) {
488 if (phy->radio_on) 488 if (phy->radio_on)
489 return; 489 return;
490 b43_radio_write16(dev, 0x0004, 0x00C0); 490 b43_radio_write16(dev, 0x0004, 0x00C0);
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index e176b6e0d9cf..6d241622210e 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -84,7 +84,7 @@ int b43_phy_init(struct b43_wldev *dev)
84 84
85 phy->channel = ops->get_default_chan(dev); 85 phy->channel = ops->get_default_chan(dev);
86 86
87 ops->software_rfkill(dev, RFKILL_STATE_UNBLOCKED); 87 ops->software_rfkill(dev, false);
88 err = ops->init(dev); 88 err = ops->init(dev);
89 if (err) { 89 if (err) {
90 b43err(dev->wl, "PHY init failed\n"); 90 b43err(dev->wl, "PHY init failed\n");
@@ -104,7 +104,7 @@ err_phy_exit:
104 if (ops->exit) 104 if (ops->exit)
105 ops->exit(dev); 105 ops->exit(dev);
106err_block_rf: 106err_block_rf:
107 ops->software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED); 107 ops->software_rfkill(dev, true);
108 108
109 return err; 109 return err;
110} 110}
@@ -113,7 +113,7 @@ void b43_phy_exit(struct b43_wldev *dev)
113{ 113{
114 const struct b43_phy_operations *ops = dev->phy.ops; 114 const struct b43_phy_operations *ops = dev->phy.ops;
115 115
116 ops->software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED); 116 ops->software_rfkill(dev, true);
117 if (ops->exit) 117 if (ops->exit)
118 ops->exit(dev); 118 ops->exit(dev);
119} 119}
@@ -295,18 +295,13 @@ err_restore_cookie:
295 return err; 295 return err;
296} 296}
297 297
298void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state) 298void b43_software_rfkill(struct b43_wldev *dev, bool blocked)
299{ 299{
300 struct b43_phy *phy = &dev->phy; 300 struct b43_phy *phy = &dev->phy;
301 301
302 if (state == RFKILL_STATE_HARD_BLOCKED) {
303 /* We cannot hardware-block the device */
304 state = RFKILL_STATE_SOFT_BLOCKED;
305 }
306
307 b43_mac_suspend(dev); 302 b43_mac_suspend(dev);
308 phy->ops->software_rfkill(dev, state); 303 phy->ops->software_rfkill(dev, blocked);
309 phy->radio_on = (state == RFKILL_STATE_UNBLOCKED); 304 phy->radio_on = !blocked;
310 b43_mac_enable(dev); 305 b43_mac_enable(dev);
311} 306}
312 307
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index b2d99101947b..f4c2d79cbc89 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -159,7 +159,7 @@ struct b43_phy_operations {
159 159
160 /* Radio */ 160 /* Radio */
161 bool (*supports_hwpctl)(struct b43_wldev *dev); 161 bool (*supports_hwpctl)(struct b43_wldev *dev);
162 void (*software_rfkill)(struct b43_wldev *dev, enum rfkill_state state); 162 void (*software_rfkill)(struct b43_wldev *dev, bool blocked);
163 void (*switch_analog)(struct b43_wldev *dev, bool on); 163 void (*switch_analog)(struct b43_wldev *dev, bool on);
164 int (*switch_channel)(struct b43_wldev *dev, unsigned int new_channel); 164 int (*switch_channel)(struct b43_wldev *dev, unsigned int new_channel);
165 unsigned int (*get_default_chan)(struct b43_wldev *dev); 165 unsigned int (*get_default_chan)(struct b43_wldev *dev);
@@ -364,7 +364,7 @@ int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel);
364/** 364/**
365 * b43_software_rfkill - Turn the radio ON or OFF in software. 365 * b43_software_rfkill - Turn the radio ON or OFF in software.
366 */ 366 */
367void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state); 367void b43_software_rfkill(struct b43_wldev *dev, bool blocked);
368 368
369/** 369/**
370 * b43_phy_txpower_check - Check TX power output. 370 * b43_phy_txpower_check - Check TX power output.
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c
index e7b98f013b0f..5300232449f6 100644
--- a/drivers/net/wireless/b43/phy_g.c
+++ b/drivers/net/wireless/b43/phy_g.c
@@ -2592,7 +2592,7 @@ static bool b43_gphy_op_supports_hwpctl(struct b43_wldev *dev)
2592} 2592}
2593 2593
2594static void b43_gphy_op_software_rfkill(struct b43_wldev *dev, 2594static void b43_gphy_op_software_rfkill(struct b43_wldev *dev,
2595 enum rfkill_state state) 2595 bool blocked)
2596{ 2596{
2597 struct b43_phy *phy = &dev->phy; 2597 struct b43_phy *phy = &dev->phy;
2598 struct b43_phy_g *gphy = phy->g; 2598 struct b43_phy_g *gphy = phy->g;
@@ -2600,7 +2600,7 @@ static void b43_gphy_op_software_rfkill(struct b43_wldev *dev,
2600 2600
2601 might_sleep(); 2601 might_sleep();
2602 2602
2603 if (state == RFKILL_STATE_UNBLOCKED) { 2603 if (!blocked) {
2604 /* Turn radio ON */ 2604 /* Turn radio ON */
2605 if (phy->radio_on) 2605 if (phy->radio_on)
2606 return; 2606 return;
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 58e319d6b1ed..ea0d3a3a6a64 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -488,7 +488,7 @@ static void b43_lpphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
488} 488}
489 489
490static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev, 490static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev,
491 enum rfkill_state state) 491 bool blocked)
492{ 492{
493 //TODO 493 //TODO
494} 494}
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 8bcfda5f3f07..be7b5604947b 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -579,7 +579,7 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
579} 579}
580 580
581static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, 581static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
582 enum rfkill_state state) 582 bool blocked)
583{//TODO 583{//TODO
584} 584}
585 585
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c
index 9e1d00bc24d3..96047843cd56 100644
--- a/drivers/net/wireless/b43/rfkill.c
+++ b/drivers/net/wireless/b43/rfkill.c
@@ -45,12 +45,11 @@ static bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
45} 45}
46 46
47/* The poll callback for the hardware button. */ 47/* The poll callback for the hardware button. */
48static void b43_rfkill_poll(struct input_polled_dev *poll_dev) 48static void b43_rfkill_poll(struct rfkill *rfkill, void *data)
49{ 49{
50 struct b43_wldev *dev = poll_dev->private; 50 struct b43_wldev *dev = data;
51 struct b43_wl *wl = dev->wl; 51 struct b43_wl *wl = dev->wl;
52 bool enabled; 52 bool enabled;
53 bool report_change = 0;
54 53
55 mutex_lock(&wl->mutex); 54 mutex_lock(&wl->mutex);
56 if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { 55 if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) {
@@ -60,68 +59,55 @@ static void b43_rfkill_poll(struct input_polled_dev *poll_dev)
60 enabled = b43_is_hw_radio_enabled(dev); 59 enabled = b43_is_hw_radio_enabled(dev);
61 if (unlikely(enabled != dev->radio_hw_enable)) { 60 if (unlikely(enabled != dev->radio_hw_enable)) {
62 dev->radio_hw_enable = enabled; 61 dev->radio_hw_enable = enabled;
63 report_change = 1;
64 b43info(wl, "Radio hardware status changed to %s\n", 62 b43info(wl, "Radio hardware status changed to %s\n",
65 enabled ? "ENABLED" : "DISABLED"); 63 enabled ? "ENABLED" : "DISABLED");
64 enabled = !rfkill_set_hw_state(rfkill, !enabled);
65 if (enabled != dev->phy.radio_on)
66 b43_software_rfkill(dev, !enabled);
66 } 67 }
67 mutex_unlock(&wl->mutex); 68 mutex_unlock(&wl->mutex);
68
69 /* send the radio switch event to the system - note both a key press
70 * and a release are required */
71 if (unlikely(report_change)) {
72 input_report_key(poll_dev->input, KEY_WLAN, 1);
73 input_report_key(poll_dev->input, KEY_WLAN, 0);
74 }
75} 69}
76 70
77/* Called when the RFKILL toggled in software. */ 71/* Called when the RFKILL toggled in software. */
78static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) 72static int b43_rfkill_soft_set(void *data, bool blocked)
79{ 73{
80 struct b43_wldev *dev = data; 74 struct b43_wldev *dev = data;
81 struct b43_wl *wl = dev->wl; 75 struct b43_wl *wl = dev->wl;
82 int err = -EBUSY; 76 int err = -EINVAL;
83 77
84 if (!wl->rfkill.registered) 78 if (WARN_ON(!wl->rfkill.registered))
85 return 0; 79 return -EINVAL;
86 80
87 mutex_lock(&wl->mutex); 81 mutex_lock(&wl->mutex);
82
88 if (b43_status(dev) < B43_STAT_INITIALIZED) 83 if (b43_status(dev) < B43_STAT_INITIALIZED)
89 goto out_unlock; 84 goto out_unlock;
85
86 if (!dev->radio_hw_enable)
87 goto out_unlock;
88
89 if (!blocked != dev->phy.radio_on)
90 b43_software_rfkill(dev, blocked);
90 err = 0; 91 err = 0;
91 switch (state) {
92 case RFKILL_STATE_UNBLOCKED:
93 if (!dev->radio_hw_enable) {
94 /* No luck. We can't toggle the hardware RF-kill
95 * button from software. */
96 err = -EBUSY;
97 goto out_unlock;
98 }
99 if (!dev->phy.radio_on)
100 b43_software_rfkill(dev, state);
101 break;
102 case RFKILL_STATE_SOFT_BLOCKED:
103 if (dev->phy.radio_on)
104 b43_software_rfkill(dev, state);
105 break;
106 default:
107 b43warn(wl, "Received unexpected rfkill state %d.\n", state);
108 break;
109 }
110out_unlock: 92out_unlock:
111 mutex_unlock(&wl->mutex); 93 mutex_unlock(&wl->mutex);
112
113 return err; 94 return err;
114} 95}
115 96
116char *b43_rfkill_led_name(struct b43_wldev *dev) 97const char *b43_rfkill_led_name(struct b43_wldev *dev)
117{ 98{
118 struct b43_rfkill *rfk = &(dev->wl->rfkill); 99 struct b43_rfkill *rfk = &(dev->wl->rfkill);
119 100
120 if (!rfk->registered) 101 if (!rfk->registered)
121 return NULL; 102 return NULL;
122 return rfkill_get_led_name(rfk->rfkill); 103 return rfkill_get_led_trigger_name(rfk->rfkill);
123} 104}
124 105
106static const struct rfkill_ops b43_rfkill_ops = {
107 .set_block = b43_rfkill_soft_set,
108 .poll = b43_rfkill_poll,
109};
110
125void b43_rfkill_init(struct b43_wldev *dev) 111void b43_rfkill_init(struct b43_wldev *dev)
126{ 112{
127 struct b43_wl *wl = dev->wl; 113 struct b43_wl *wl = dev->wl;
@@ -130,65 +116,26 @@ void b43_rfkill_init(struct b43_wldev *dev)
130 116
131 rfk->registered = 0; 117 rfk->registered = 0;
132 118
133 rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);
134 if (!rfk->rfkill)
135 goto out_error;
136 snprintf(rfk->name, sizeof(rfk->name), 119 snprintf(rfk->name, sizeof(rfk->name),
137 "b43-%s", wiphy_name(wl->hw->wiphy)); 120 "b43-%s", wiphy_name(wl->hw->wiphy));
138 rfk->rfkill->name = rfk->name;
139 rfk->rfkill->state = RFKILL_STATE_UNBLOCKED;
140 rfk->rfkill->data = dev;
141 rfk->rfkill->toggle_radio = b43_rfkill_soft_toggle;
142
143 rfk->poll_dev = input_allocate_polled_device();
144 if (!rfk->poll_dev) {
145 rfkill_free(rfk->rfkill);
146 goto err_freed_rfk;
147 }
148
149 rfk->poll_dev->private = dev;
150 rfk->poll_dev->poll = b43_rfkill_poll;
151 rfk->poll_dev->poll_interval = 1000; /* msecs */
152 121
153 rfk->poll_dev->input->name = rfk->name; 122 rfk->rfkill = rfkill_alloc(rfk->name,
154 rfk->poll_dev->input->id.bustype = BUS_HOST; 123 dev->dev->dev,
155 rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor; 124 RFKILL_TYPE_WLAN,
156 rfk->poll_dev->input->evbit[0] = BIT(EV_KEY); 125 &b43_rfkill_ops, dev);
157 set_bit(KEY_WLAN, rfk->poll_dev->input->keybit); 126 if (!rfk->rfkill)
127 goto out_error;
158 128
159 err = rfkill_register(rfk->rfkill); 129 err = rfkill_register(rfk->rfkill);
160 if (err) 130 if (err)
161 goto err_free_polldev; 131 goto err_free;
162
163#ifdef CONFIG_RFKILL_INPUT_MODULE
164 /* B43 RF-kill isn't useful without the rfkill-input subsystem.
165 * Try to load the module. */
166 err = request_module("rfkill-input");
167 if (err)
168 b43warn(wl, "Failed to load the rfkill-input module. "
169 "The built-in radio LED will not work.\n");
170#endif /* CONFIG_RFKILL_INPUT */
171
172#if !defined(CONFIG_RFKILL_INPUT) && !defined(CONFIG_RFKILL_INPUT_MODULE)
173 b43warn(wl, "The rfkill-input subsystem is not available. "
174 "The built-in radio LED will not work.\n");
175#endif
176
177 err = input_register_polled_device(rfk->poll_dev);
178 if (err)
179 goto err_unreg_rfk;
180 132
181 rfk->registered = 1; 133 rfk->registered = 1;
182 134
183 return; 135 return;
184err_unreg_rfk: 136 err_free:
185 rfkill_unregister(rfk->rfkill); 137 rfkill_destroy(rfk->rfkill);
186err_free_polldev: 138 out_error:
187 input_free_polled_device(rfk->poll_dev);
188 rfk->poll_dev = NULL;
189err_freed_rfk:
190 rfk->rfkill = NULL;
191out_error:
192 rfk->registered = 0; 139 rfk->registered = 0;
193 b43warn(wl, "RF-kill button init failed\n"); 140 b43warn(wl, "RF-kill button init failed\n");
194} 141}
@@ -201,9 +148,7 @@ void b43_rfkill_exit(struct b43_wldev *dev)
201 return; 148 return;
202 rfk->registered = 0; 149 rfk->registered = 0;
203 150
204 input_unregister_polled_device(rfk->poll_dev);
205 rfkill_unregister(rfk->rfkill); 151 rfkill_unregister(rfk->rfkill);
206 input_free_polled_device(rfk->poll_dev); 152 rfkill_destroy(rfk->rfkill);
207 rfk->poll_dev = NULL;
208 rfk->rfkill = NULL; 153 rfk->rfkill = NULL;
209} 154}
diff --git a/drivers/net/wireless/b43/rfkill.h b/drivers/net/wireless/b43/rfkill.h
index adacf936d815..da497e01bbb1 100644
--- a/drivers/net/wireless/b43/rfkill.h
+++ b/drivers/net/wireless/b43/rfkill.h
@@ -7,14 +7,11 @@ struct b43_wldev;
7#ifdef CONFIG_B43_RFKILL 7#ifdef CONFIG_B43_RFKILL
8 8
9#include <linux/rfkill.h> 9#include <linux/rfkill.h>
10#include <linux/input-polldev.h>
11 10
12 11
13struct b43_rfkill { 12struct b43_rfkill {
14 /* The RFKILL subsystem data structure */ 13 /* The RFKILL subsystem data structure */
15 struct rfkill *rfkill; 14 struct rfkill *rfkill;
16 /* The poll device for the RFKILL input button */
17 struct input_polled_dev *poll_dev;
18 /* Did initialization succeed? Used for freeing. */ 15 /* Did initialization succeed? Used for freeing. */
19 bool registered; 16 bool registered;
20 /* The unique name of this rfkill switch */ 17 /* The unique name of this rfkill switch */
@@ -26,7 +23,7 @@ struct b43_rfkill {
26void b43_rfkill_init(struct b43_wldev *dev); 23void b43_rfkill_init(struct b43_wldev *dev);
27void b43_rfkill_exit(struct b43_wldev *dev); 24void b43_rfkill_exit(struct b43_wldev *dev);
28 25
29char * b43_rfkill_led_name(struct b43_wldev *dev); 26const char *b43_rfkill_led_name(struct b43_wldev *dev);
30 27
31 28
32#else /* CONFIG_B43_RFKILL */ 29#else /* CONFIG_B43_RFKILL */
diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig
index d4f628a74bbd..6893f439df70 100644
--- a/drivers/net/wireless/b43legacy/Kconfig
+++ b/drivers/net/wireless/b43legacy/Kconfig
@@ -47,7 +47,7 @@ config B43LEGACY_LEDS
47# if it's possible. 47# if it's possible.
48config B43LEGACY_RFKILL 48config B43LEGACY_RFKILL
49 bool 49 bool
50 depends on B43LEGACY && (RFKILL = y || RFKILL = B43LEGACY) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43LEGACY) 50 depends on B43LEGACY && (RFKILL = y || RFKILL = B43LEGACY)
51 default y 51 default y
52 52
53# This config option automatically enables b43 HW-RNG support, 53# This config option automatically enables b43 HW-RNG support,
diff --git a/drivers/net/wireless/b43legacy/leds.c b/drivers/net/wireless/b43legacy/leds.c
index 3ea55b18c700..538d3117594b 100644
--- a/drivers/net/wireless/b43legacy/leds.c
+++ b/drivers/net/wireless/b43legacy/leds.c
@@ -86,7 +86,8 @@ static void b43legacy_led_brightness_set(struct led_classdev *led_dev,
86 86
87static int b43legacy_register_led(struct b43legacy_wldev *dev, 87static int b43legacy_register_led(struct b43legacy_wldev *dev,
88 struct b43legacy_led *led, 88 struct b43legacy_led *led,
89 const char *name, char *default_trigger, 89 const char *name,
90 const char *default_trigger,
90 u8 led_index, bool activelow) 91 u8 led_index, bool activelow)
91{ 92{
92 int err; 93 int err;
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c
index 4b0c7d27a51f..c6230a64505a 100644
--- a/drivers/net/wireless/b43legacy/rfkill.c
+++ b/drivers/net/wireless/b43legacy/rfkill.c
@@ -45,12 +45,11 @@ static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev)
45} 45}
46 46
47/* The poll callback for the hardware button. */ 47/* The poll callback for the hardware button. */
48static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev) 48static void b43legacy_rfkill_poll(struct rfkill *rfkill, void *data)
49{ 49{
50 struct b43legacy_wldev *dev = poll_dev->private; 50 struct b43legacy_wldev *dev = data;
51 struct b43legacy_wl *wl = dev->wl; 51 struct b43legacy_wl *wl = dev->wl;
52 bool enabled; 52 bool enabled;
53 bool report_change = 0;
54 53
55 mutex_lock(&wl->mutex); 54 mutex_lock(&wl->mutex);
56 if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) { 55 if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) {
@@ -60,71 +59,64 @@ static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev)
60 enabled = b43legacy_is_hw_radio_enabled(dev); 59 enabled = b43legacy_is_hw_radio_enabled(dev);
61 if (unlikely(enabled != dev->radio_hw_enable)) { 60 if (unlikely(enabled != dev->radio_hw_enable)) {
62 dev->radio_hw_enable = enabled; 61 dev->radio_hw_enable = enabled;
63 report_change = 1;
64 b43legacyinfo(wl, "Radio hardware status changed to %s\n", 62 b43legacyinfo(wl, "Radio hardware status changed to %s\n",
65 enabled ? "ENABLED" : "DISABLED"); 63 enabled ? "ENABLED" : "DISABLED");
64 enabled = !rfkill_set_hw_state(rfkill, !enabled);
65 if (enabled != dev->phy.radio_on) {
66 if (enabled)
67 b43legacy_radio_turn_on(dev);
68 else
69 b43legacy_radio_turn_off(dev, 0);
70 }
66 } 71 }
67 mutex_unlock(&wl->mutex); 72 mutex_unlock(&wl->mutex);
68
69 /* send the radio switch event to the system - note both a key press
70 * and a release are required */
71 if (unlikely(report_change)) {
72 input_report_key(poll_dev->input, KEY_WLAN, 1);
73 input_report_key(poll_dev->input, KEY_WLAN, 0);
74 }
75} 73}
76 74
77/* Called when the RFKILL toggled in software. 75/* Called when the RFKILL toggled in software.
78 * This is called without locking. */ 76 * This is called without locking. */
79static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state) 77static int b43legacy_rfkill_soft_set(void *data, bool blocked)
80{ 78{
81 struct b43legacy_wldev *dev = data; 79 struct b43legacy_wldev *dev = data;
82 struct b43legacy_wl *wl = dev->wl; 80 struct b43legacy_wl *wl = dev->wl;
83 int err = -EBUSY; 81 int ret = -EINVAL;
84 82
85 if (!wl->rfkill.registered) 83 if (!wl->rfkill.registered)
86 return 0; 84 return -EINVAL;
87 85
88 mutex_lock(&wl->mutex); 86 mutex_lock(&wl->mutex);
89 if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) 87 if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)
90 goto out_unlock; 88 goto out_unlock;
91 err = 0; 89
92 switch (state) { 90 if (!dev->radio_hw_enable)
93 case RFKILL_STATE_UNBLOCKED: 91 goto out_unlock;
94 if (!dev->radio_hw_enable) { 92
95 /* No luck. We can't toggle the hardware RF-kill 93 if (!blocked != dev->phy.radio_on) {
96 * button from software. */ 94 if (!blocked)
97 err = -EBUSY;
98 goto out_unlock;
99 }
100 if (!dev->phy.radio_on)
101 b43legacy_radio_turn_on(dev); 95 b43legacy_radio_turn_on(dev);
102 break; 96 else
103 case RFKILL_STATE_SOFT_BLOCKED:
104 if (dev->phy.radio_on)
105 b43legacy_radio_turn_off(dev, 0); 97 b43legacy_radio_turn_off(dev, 0);
106 break;
107 default:
108 b43legacywarn(wl, "Received unexpected rfkill state %d.\n",
109 state);
110 break;
111 } 98 }
99 ret = 0;
112 100
113out_unlock: 101out_unlock:
114 mutex_unlock(&wl->mutex); 102 mutex_unlock(&wl->mutex);
115 103 return ret;
116 return err;
117} 104}
118 105
119char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) 106const char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev)
120{ 107{
121 struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); 108 struct b43legacy_rfkill *rfk = &(dev->wl->rfkill);
122 109
123 if (!rfk->registered) 110 if (!rfk->registered)
124 return NULL; 111 return NULL;
125 return rfkill_get_led_name(rfk->rfkill); 112 return rfkill_get_led_trigger_name(rfk->rfkill);
126} 113}
127 114
115static const struct rfkill_ops b43legacy_rfkill_ops = {
116 .set_block = b43legacy_rfkill_soft_set,
117 .poll = b43legacy_rfkill_poll,
118};
119
128void b43legacy_rfkill_init(struct b43legacy_wldev *dev) 120void b43legacy_rfkill_init(struct b43legacy_wldev *dev)
129{ 121{
130 struct b43legacy_wl *wl = dev->wl; 122 struct b43legacy_wl *wl = dev->wl;
@@ -133,60 +125,25 @@ void b43legacy_rfkill_init(struct b43legacy_wldev *dev)
133 125
134 rfk->registered = 0; 126 rfk->registered = 0;
135 127
136 rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);
137 if (!rfk->rfkill)
138 goto out_error;
139 snprintf(rfk->name, sizeof(rfk->name), 128 snprintf(rfk->name, sizeof(rfk->name),
140 "b43legacy-%s", wiphy_name(wl->hw->wiphy)); 129 "b43legacy-%s", wiphy_name(wl->hw->wiphy));
141 rfk->rfkill->name = rfk->name; 130 rfk->rfkill = rfkill_alloc(rfk->name,
142 rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; 131 dev->dev->dev,
143 rfk->rfkill->data = dev; 132 RFKILL_TYPE_WLAN,
144 rfk->rfkill->toggle_radio = b43legacy_rfkill_soft_toggle; 133 &b43legacy_rfkill_ops, dev);
145 134 if (!rfk->rfkill)
146 rfk->poll_dev = input_allocate_polled_device(); 135 goto out_error;
147 if (!rfk->poll_dev) {
148 rfkill_free(rfk->rfkill);
149 goto err_freed_rfk;
150 }
151
152 rfk->poll_dev->private = dev;
153 rfk->poll_dev->poll = b43legacy_rfkill_poll;
154 rfk->poll_dev->poll_interval = 1000; /* msecs */
155
156 rfk->poll_dev->input->name = rfk->name;
157 rfk->poll_dev->input->id.bustype = BUS_HOST;
158 rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor;
159 rfk->poll_dev->input->evbit[0] = BIT(EV_KEY);
160 set_bit(KEY_WLAN, rfk->poll_dev->input->keybit);
161 136
162 err = rfkill_register(rfk->rfkill); 137 err = rfkill_register(rfk->rfkill);
163 if (err) 138 if (err)
164 goto err_free_polldev; 139 goto err_free;
165
166#ifdef CONFIG_RFKILL_INPUT_MODULE
167 /* B43legacy RF-kill isn't useful without the rfkill-input subsystem.
168 * Try to load the module. */
169 err = request_module("rfkill-input");
170 if (err)
171 b43legacywarn(wl, "Failed to load the rfkill-input module."
172 "The built-in radio LED will not work.\n");
173#endif /* CONFIG_RFKILL_INPUT */
174
175 err = input_register_polled_device(rfk->poll_dev);
176 if (err)
177 goto err_unreg_rfk;
178 140
179 rfk->registered = 1; 141 rfk->registered = 1;
180 142
181 return; 143 return;
182err_unreg_rfk: 144 err_free:
183 rfkill_unregister(rfk->rfkill); 145 rfkill_destroy(rfk->rfkill);
184err_free_polldev: 146 out_error:
185 input_free_polled_device(rfk->poll_dev);
186 rfk->poll_dev = NULL;
187err_freed_rfk:
188 rfk->rfkill = NULL;
189out_error:
190 rfk->registered = 0; 147 rfk->registered = 0;
191 b43legacywarn(wl, "RF-kill button init failed\n"); 148 b43legacywarn(wl, "RF-kill button init failed\n");
192} 149}
@@ -199,10 +156,8 @@ void b43legacy_rfkill_exit(struct b43legacy_wldev *dev)
199 return; 156 return;
200 rfk->registered = 0; 157 rfk->registered = 0;
201 158
202 input_unregister_polled_device(rfk->poll_dev);
203 rfkill_unregister(rfk->rfkill); 159 rfkill_unregister(rfk->rfkill);
204 input_free_polled_device(rfk->poll_dev); 160 rfkill_destroy(rfk->rfkill);
205 rfk->poll_dev = NULL;
206 rfk->rfkill = NULL; 161 rfk->rfkill = NULL;
207} 162}
208 163
diff --git a/drivers/net/wireless/b43legacy/rfkill.h b/drivers/net/wireless/b43legacy/rfkill.h
index 11150a8032f0..adffc503a6a1 100644
--- a/drivers/net/wireless/b43legacy/rfkill.h
+++ b/drivers/net/wireless/b43legacy/rfkill.h
@@ -6,16 +6,12 @@ struct b43legacy_wldev;
6#ifdef CONFIG_B43LEGACY_RFKILL 6#ifdef CONFIG_B43LEGACY_RFKILL
7 7
8#include <linux/rfkill.h> 8#include <linux/rfkill.h>
9#include <linux/workqueue.h>
10#include <linux/input-polldev.h>
11 9
12 10
13 11
14struct b43legacy_rfkill { 12struct b43legacy_rfkill {
15 /* The RFKILL subsystem data structure */ 13 /* The RFKILL subsystem data structure */
16 struct rfkill *rfkill; 14 struct rfkill *rfkill;
17 /* The poll device for the RFKILL input button */
18 struct input_polled_dev *poll_dev;
19 /* Did initialization succeed? Used for freeing. */ 15 /* Did initialization succeed? Used for freeing. */
20 bool registered; 16 bool registered;
21 /* The unique name of this rfkill switch */ 17 /* The unique name of this rfkill switch */
@@ -27,7 +23,7 @@ struct b43legacy_rfkill {
27void b43legacy_rfkill_init(struct b43legacy_wldev *dev); 23void b43legacy_rfkill_init(struct b43legacy_wldev *dev);
28void b43legacy_rfkill_exit(struct b43legacy_wldev *dev); 24void b43legacy_rfkill_exit(struct b43legacy_wldev *dev);
29 25
30char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev); 26const char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev);
31 27
32 28
33#else /* CONFIG_B43LEGACY_RFKILL */ 29#else /* CONFIG_B43LEGACY_RFKILL */
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 8304f6406a17..6fe259fcfb8f 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -5,15 +5,14 @@ config IWLWIFI
5 select FW_LOADER 5 select FW_LOADER
6 select MAC80211_LEDS if IWLWIFI_LEDS 6 select MAC80211_LEDS if IWLWIFI_LEDS
7 select LEDS_CLASS if IWLWIFI_LEDS 7 select LEDS_CLASS if IWLWIFI_LEDS
8 select RFKILL if IWLWIFI_RFKILL
9 8
10config IWLWIFI_LEDS 9config IWLWIFI_LEDS
11 bool "Enable LED support in iwlagn and iwl3945 drivers" 10 bool "Enable LED support in iwlagn and iwl3945 drivers"
12 depends on IWLWIFI 11 depends on IWLWIFI
13 12
14config IWLWIFI_RFKILL 13config IWLWIFI_RFKILL
15 bool "Enable RF kill support in iwlagn and iwl3945 drivers" 14 def_bool y
16 depends on IWLWIFI 15 depends on IWLWIFI && RFKILL
17 16
18config IWLWIFI_SPECTRUM_MEASUREMENT 17config IWLWIFI_SPECTRUM_MEASUREMENT
19 bool "Enable Spectrum Measurement in iwlagn driver" 18 bool "Enable Spectrum Measurement in iwlagn driver"
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index bd7e520d98c2..225e5f889346 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -167,10 +167,6 @@ static int iwl3945_led_disassociate(struct iwl_priv *priv, int led_id)
167 IWL_DEBUG_LED(priv, "Disassociated\n"); 167 IWL_DEBUG_LED(priv, "Disassociated\n");
168 168
169 priv->allow_blinking = 0; 169 priv->allow_blinking = 0;
170 if (iwl_is_rfkill(priv))
171 iwl3945_led_off(priv, led_id);
172 else
173 iwl3945_led_on(priv, led_id);
174 170
175 return 0; 171 return 0;
176} 172}
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 814afaf6d10b..5eb538d18a80 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -38,6 +38,7 @@
38 38
39#include "iwl-commands.h" 39#include "iwl-commands.h"
40#include "iwl-3945.h" 40#include "iwl-3945.h"
41#include "iwl-sta.h"
41 42
42#define RS_NAME "iwl-3945-rs" 43#define RS_NAME "iwl-3945-rs"
43 44
@@ -714,13 +715,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
714 715
715 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && 716 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
716 !rs_sta->ibss_sta_added) { 717 !rs_sta->ibss_sta_added) {
717 u8 sta_id = iwl3945_hw_find_station(priv, hdr->addr1); 718 u8 sta_id = iwl_find_station(priv, hdr->addr1);
718 719
719 if (sta_id == IWL_INVALID_STATION) { 720 if (sta_id == IWL_INVALID_STATION) {
720 IWL_DEBUG_RATE(priv, "LQ: ADD station %pm\n", 721 IWL_DEBUG_RATE(priv, "LQ: ADD station %pm\n",
721 hdr->addr1); 722 hdr->addr1);
722 sta_id = iwl3945_add_station(priv, 723 sta_id = iwl_add_station(priv, hdr->addr1, false,
723 hdr->addr1, 0, CMD_ASYNC, NULL); 724 CMD_ASYNC, NULL);
724 } 725 }
725 if (sta_id != IWL_INVALID_STATION) 726 if (sta_id != IWL_INVALID_STATION)
726 rs_sta->ibss_sta_added = 1; 727 rs_sta->ibss_sta_added = 1;
@@ -975,7 +976,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
975 976
976 rcu_read_lock(); 977 rcu_read_lock();
977 978
978 sta = ieee80211_find_sta(hw, priv->stations_39[sta_id].sta.sta.addr); 979 sta = ieee80211_find_sta(hw, priv->stations[sta_id].sta.sta.addr);
979 if (!sta) { 980 if (!sta) {
980 rcu_read_unlock(); 981 rcu_read_unlock();
981 return; 982 return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index fd65e1c3e055..46288e724889 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -769,35 +769,6 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
769 return ; 769 return ;
770} 770}
771 771
772u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *addr)
773{
774 int i, start = IWL_AP_ID;
775 int ret = IWL_INVALID_STATION;
776 unsigned long flags;
777
778 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) ||
779 (priv->iw_mode == NL80211_IFTYPE_AP))
780 start = IWL_STA_ID;
781
782 if (is_broadcast_ether_addr(addr))
783 return priv->hw_params.bcast_sta_id;
784
785 spin_lock_irqsave(&priv->sta_lock, flags);
786 for (i = start; i < priv->hw_params.max_stations; i++)
787 if ((priv->stations_39[i].used) &&
788 (!compare_ether_addr
789 (priv->stations_39[i].sta.sta.addr, addr))) {
790 ret = i;
791 goto out;
792 }
793
794 IWL_DEBUG_INFO(priv, "can not find STA %pM (total %d)\n",
795 addr, priv->num_stations);
796 out:
797 spin_unlock_irqrestore(&priv->sta_lock, flags);
798 return ret;
799}
800
801/** 772/**
802 * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD: 773 * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
803 * 774 *
@@ -875,13 +846,13 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
875u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags) 846u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
876{ 847{
877 unsigned long flags_spin; 848 unsigned long flags_spin;
878 struct iwl3945_station_entry *station; 849 struct iwl_station_entry *station;
879 850
880 if (sta_id == IWL_INVALID_STATION) 851 if (sta_id == IWL_INVALID_STATION)
881 return IWL_INVALID_STATION; 852 return IWL_INVALID_STATION;
882 853
883 spin_lock_irqsave(&priv->sta_lock, flags_spin); 854 spin_lock_irqsave(&priv->sta_lock, flags_spin);
884 station = &priv->stations_39[sta_id]; 855 station = &priv->stations[sta_id];
885 856
886 station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK; 857 station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;
887 station->sta.rate_n_flags = cpu_to_le16(tx_rate); 858 station->sta.rate_n_flags = cpu_to_le16(tx_rate);
@@ -889,8 +860,7 @@ u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
889 860
890 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 861 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
891 862
892 iwl_send_add_sta(priv, 863 iwl_send_add_sta(priv, &station->sta, flags);
893 (struct iwl_addsta_cmd *)&station->sta, flags);
894 IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n", 864 IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n",
895 sta_id, tx_rate); 865 sta_id, tx_rate);
896 return sta_id; 866 return sta_id;
@@ -2029,7 +1999,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
2029 1999
2030 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); 2000 memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
2031 2001
2032 priv->cfg->ops->smgmt->clear_station_table(priv); 2002 iwl_clear_stations_table(priv);
2033 2003
2034 /* If we issue a new RXON command which required a tune then we must 2004 /* If we issue a new RXON command which required a tune then we must
2035 * send a new TXPOWER command or we won't be able to Tx any frames */ 2005 * send a new TXPOWER command or we won't be able to Tx any frames */
@@ -2040,7 +2010,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
2040 } 2010 }
2041 2011
2042 /* Add the broadcast address so we can send broadcast frames */ 2012 /* Add the broadcast address so we can send broadcast frames */
2043 if (priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0, NULL) == 2013 if (iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL) ==
2044 IWL_INVALID_STATION) { 2014 IWL_INVALID_STATION) {
2045 IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n"); 2015 IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
2046 return -EIO; 2016 return -EIO;
@@ -2050,9 +2020,8 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
2050 * add the IWL_AP_ID to the station rate table */ 2020 * add the IWL_AP_ID to the station rate table */
2051 if (iwl_is_associated(priv) && 2021 if (iwl_is_associated(priv) &&
2052 (priv->iw_mode == NL80211_IFTYPE_STATION)) 2022 (priv->iw_mode == NL80211_IFTYPE_STATION))
2053 if (priv->cfg->ops->smgmt->add_station(priv, 2023 if (iwl_add_station(priv, priv->active_rxon.bssid_addr,
2054 priv->active_rxon.bssid_addr, 1, 0, NULL) 2024 true, CMD_SYNC, NULL) == IWL_INVALID_STATION) {
2055 == IWL_INVALID_STATION) {
2056 IWL_ERR(priv, "Error adding AP address for transmit\n"); 2025 IWL_ERR(priv, "Error adding AP address for transmit\n");
2057 return -EIO; 2026 return -EIO;
2058 } 2027 }
@@ -2466,13 +2435,25 @@ static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len)
2466 } 2435 }
2467} 2436}
2468 2437
2438
2469static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) 2439static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
2470{ 2440{
2471 u16 size = (u16)sizeof(struct iwl3945_addsta_cmd); 2441 struct iwl3945_addsta_cmd *addsta = (struct iwl3945_addsta_cmd *)data;
2472 memcpy(data, cmd, size); 2442 addsta->mode = cmd->mode;
2473 return size; 2443 memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify));
2444 memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo));
2445 addsta->station_flags = cmd->station_flags;
2446 addsta->station_flags_msk = cmd->station_flags_msk;
2447 addsta->tid_disable_tx = cpu_to_le16(0);
2448 addsta->rate_n_flags = cmd->rate_n_flags;
2449 addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid;
2450 addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid;
2451 addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn;
2452
2453 return (u16)sizeof(struct iwl3945_addsta_cmd);
2474} 2454}
2475 2455
2456
2476/** 2457/**
2477 * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table 2458 * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table
2478 */ 2459 */
@@ -2842,15 +2823,6 @@ static struct iwl_lib_ops iwl3945_lib = {
2842 .config_ap = iwl3945_config_ap, 2823 .config_ap = iwl3945_config_ap,
2843}; 2824};
2844 2825
2845static struct iwl_station_mgmt_ops iwl3945_station_mgmt = {
2846 .add_station = iwl3945_add_station,
2847#if 0
2848 .remove_station = iwl3945_remove_station,
2849#endif
2850 .find_station = iwl3945_hw_find_station,
2851 .clear_station_table = iwl3945_clear_stations_table,
2852};
2853
2854static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { 2826static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
2855 .get_hcmd_size = iwl3945_get_hcmd_size, 2827 .get_hcmd_size = iwl3945_get_hcmd_size,
2856 .build_addsta_hcmd = iwl3945_build_addsta_hcmd, 2828 .build_addsta_hcmd = iwl3945_build_addsta_hcmd,
@@ -2860,7 +2832,6 @@ static struct iwl_ops iwl3945_ops = {
2860 .lib = &iwl3945_lib, 2832 .lib = &iwl3945_lib,
2861 .hcmd = &iwl3945_hcmd, 2833 .hcmd = &iwl3945_hcmd,
2862 .utils = &iwl3945_hcmd_utils, 2834 .utils = &iwl3945_hcmd_utils,
2863 .smgmt = &iwl3945_station_mgmt,
2864}; 2835};
2865 2836
2866static struct iwl_cfg iwl3945_bg_cfg = { 2837static struct iwl_cfg iwl3945_bg_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index da87528f355f..4d8a325ea9d8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -202,12 +202,6 @@ struct iwl3945_ibss_seq {
202 * for use by iwl-*.c 202 * for use by iwl-*.c
203 * 203 *
204 *****************************************************************************/ 204 *****************************************************************************/
205struct iwl3945_addsta_cmd;
206extern int iwl3945_send_add_station(struct iwl_priv *priv,
207 struct iwl3945_addsta_cmd *sta, u8 flags);
208extern u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *bssid,
209 int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info);
210extern void iwl3945_clear_stations_table(struct iwl_priv *priv);
211extern int iwl3945_power_init_handle(struct iwl_priv *priv); 205extern int iwl3945_power_init_handle(struct iwl_priv *priv);
212extern int iwl3945_eeprom_init(struct iwl_priv *priv); 206extern int iwl3945_eeprom_init(struct iwl_priv *priv);
213extern int iwl3945_calc_db_from_ratio(int sig_ratio); 207extern int iwl3945_calc_db_from_ratio(int sig_ratio);
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index a0b29411a4b3..8f3d4bc6a03f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2221,13 +2221,6 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
2221 cancel_work_sync(&priv->txpower_work); 2221 cancel_work_sync(&priv->txpower_work);
2222} 2222}
2223 2223
2224static struct iwl_station_mgmt_ops iwl4965_station_mgmt = {
2225 .add_station = iwl_add_station_flags,
2226 .remove_station = iwl_remove_station,
2227 .find_station = iwl_find_station,
2228 .clear_station_table = iwl_clear_stations_table,
2229};
2230
2231static struct iwl_hcmd_ops iwl4965_hcmd = { 2224static struct iwl_hcmd_ops iwl4965_hcmd = {
2232 .rxon_assoc = iwl4965_send_rxon_assoc, 2225 .rxon_assoc = iwl4965_send_rxon_assoc,
2233 .commit_rxon = iwl_commit_rxon, 2226 .commit_rxon = iwl_commit_rxon,
@@ -2297,7 +2290,6 @@ static struct iwl_ops iwl4965_ops = {
2297 .lib = &iwl4965_lib, 2290 .lib = &iwl4965_lib,
2298 .hcmd = &iwl4965_hcmd, 2291 .hcmd = &iwl4965_hcmd,
2299 .utils = &iwl4965_hcmd_utils, 2292 .utils = &iwl4965_hcmd_utils,
2300 .smgmt = &iwl4965_station_mgmt,
2301}; 2293};
2302 2294
2303struct iwl_cfg iwl4965_agn_cfg = { 2295struct iwl_cfg iwl4965_agn_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index ab29aab6b2d5..b3c648ce8c7b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -651,7 +651,7 @@ static void iwl5000_init_alive_start(struct iwl_priv *priv)
651 goto restart; 651 goto restart;
652 } 652 }
653 653
654 priv->cfg->ops->smgmt->clear_station_table(priv); 654 iwl_clear_stations_table(priv);
655 ret = priv->cfg->ops->lib->alive_notify(priv); 655 ret = priv->cfg->ops->lib->alive_notify(priv);
656 if (ret) { 656 if (ret) {
657 IWL_WARN(priv, 657 IWL_WARN(priv,
@@ -1049,7 +1049,10 @@ static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
1049u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) 1049u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
1050{ 1050{
1051 u16 size = (u16)sizeof(struct iwl_addsta_cmd); 1051 u16 size = (u16)sizeof(struct iwl_addsta_cmd);
1052 memcpy(data, cmd, size); 1052 struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data;
1053 memcpy(addsta, cmd, size);
1054 /* resrved in 5000 */
1055 addsta->rate_n_flags = cpu_to_le16(0);
1053 return size; 1056 return size;
1054} 1057}
1055 1058
@@ -1423,13 +1426,6 @@ int iwl5000_calc_rssi(struct iwl_priv *priv,
1423 return max_rssi - agc - IWL49_RSSI_OFFSET; 1426 return max_rssi - agc - IWL49_RSSI_OFFSET;
1424} 1427}
1425 1428
1426struct iwl_station_mgmt_ops iwl5000_station_mgmt = {
1427 .add_station = iwl_add_station_flags,
1428 .remove_station = iwl_remove_station,
1429 .find_station = iwl_find_station,
1430 .clear_station_table = iwl_clear_stations_table,
1431};
1432
1433struct iwl_hcmd_ops iwl5000_hcmd = { 1429struct iwl_hcmd_ops iwl5000_hcmd = {
1434 .rxon_assoc = iwl5000_send_rxon_assoc, 1430 .rxon_assoc = iwl5000_send_rxon_assoc,
1435 .commit_rxon = iwl_commit_rxon, 1431 .commit_rxon = iwl_commit_rxon,
@@ -1549,14 +1545,12 @@ struct iwl_ops iwl5000_ops = {
1549 .lib = &iwl5000_lib, 1545 .lib = &iwl5000_lib,
1550 .hcmd = &iwl5000_hcmd, 1546 .hcmd = &iwl5000_hcmd,
1551 .utils = &iwl5000_hcmd_utils, 1547 .utils = &iwl5000_hcmd_utils,
1552 .smgmt = &iwl5000_station_mgmt,
1553}; 1548};
1554 1549
1555static struct iwl_ops iwl5150_ops = { 1550static struct iwl_ops iwl5150_ops = {
1556 .lib = &iwl5150_lib, 1551 .lib = &iwl5150_lib,
1557 .hcmd = &iwl5000_hcmd, 1552 .hcmd = &iwl5000_hcmd,
1558 .utils = &iwl5000_hcmd_utils, 1553 .utils = &iwl5000_hcmd_utils,
1559 .smgmt = &iwl5000_station_mgmt,
1560}; 1554};
1561 1555
1562struct iwl_mod_params iwl50_mod_params = { 1556struct iwl_mod_params iwl50_mod_params = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 7236382aeaa6..bd438d8acf55 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -72,7 +72,6 @@ static struct iwl_ops iwl6000_ops = {
72 .lib = &iwl5000_lib, 72 .lib = &iwl5000_lib,
73 .hcmd = &iwl5000_hcmd, 73 .hcmd = &iwl5000_hcmd,
74 .utils = &iwl6000_hcmd_utils, 74 .utils = &iwl6000_hcmd_utils,
75 .smgmt = &iwl5000_station_mgmt,
76}; 75};
77 76
78struct iwl_cfg iwl6000_2ag_cfg = { 77struct iwl_cfg iwl6000_2ag_cfg = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 23a58b00f180..ff20e5048a55 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -2502,15 +2502,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2502 2502
2503 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && 2503 if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
2504 !lq_sta->ibss_sta_added) { 2504 !lq_sta->ibss_sta_added) {
2505 u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, 2505 u8 sta_id = iwl_find_station(priv, hdr->addr1);
2506 hdr->addr1);
2507 2506
2508 if (sta_id == IWL_INVALID_STATION) { 2507 if (sta_id == IWL_INVALID_STATION) {
2509 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", 2508 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
2510 hdr->addr1); 2509 hdr->addr1);
2511 sta_id = priv->cfg->ops->smgmt->add_station(priv, 2510 sta_id = iwl_add_station(priv, hdr->addr1,
2512 hdr->addr1, 0, 2511 false, CMD_ASYNC, NULL);
2513 CMD_ASYNC, NULL);
2514 } 2512 }
2515 if ((sta_id != IWL_INVALID_STATION)) { 2513 if ((sta_id != IWL_INVALID_STATION)) {
2516 lq_sta->lq.sta_id = sta_id; 2514 lq_sta->lq.sta_id = sta_id;
@@ -2598,7 +2596,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2598 2596
2599 lq_sta->ibss_sta_added = 0; 2597 lq_sta->ibss_sta_added = 0;
2600 if (priv->iw_mode == NL80211_IFTYPE_AP) { 2598 if (priv->iw_mode == NL80211_IFTYPE_AP) {
2601 u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, 2599 u8 sta_id = iwl_find_station(priv,
2602 sta->addr); 2600 sta->addr);
2603 2601
2604 /* for IBSS the call are from tasklet */ 2602 /* for IBSS the call are from tasklet */
@@ -2606,9 +2604,8 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2606 2604
2607 if (sta_id == IWL_INVALID_STATION) { 2605 if (sta_id == IWL_INVALID_STATION) {
2608 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr); 2606 IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
2609 sta_id = priv->cfg->ops->smgmt->add_station(priv, 2607 sta_id = iwl_add_station(priv, sta->addr, false,
2610 sta->addr, 0, 2608 CMD_ASYNC, NULL);
2611 CMD_ASYNC, NULL);
2612 } 2609 }
2613 if ((sta_id != IWL_INVALID_STATION)) { 2610 if ((sta_id != IWL_INVALID_STATION)) {
2614 lq_sta->lq.sta_id = sta_id; 2611 lq_sta->lq.sta_id = sta_id;
@@ -2790,9 +2787,10 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv,
2790 repeat_rate--; 2787 repeat_rate--;
2791 } 2788 }
2792 2789
2793 lq_cmd->agg_params.agg_frame_cnt_limit = 64; 2790 lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_MAX;
2794 lq_cmd->agg_params.agg_dis_start_th = 3; 2791 lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
2795 lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000); 2792 lq_cmd->agg_params.agg_time_limit =
2793 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
2796} 2794}
2797 2795
2798static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 2796static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 0a5507cbeb3f..b77208de92ad 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -188,7 +188,7 @@ int iwl_commit_rxon(struct iwl_priv *priv)
188 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); 188 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
189 } 189 }
190 190
191 priv->cfg->ops->smgmt->clear_station_table(priv); 191 iwl_clear_stations_table(priv);
192 192
193 priv->start_calib = 0; 193 priv->start_calib = 0;
194 194
@@ -1617,7 +1617,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
1617 goto restart; 1617 goto restart;
1618 } 1618 }
1619 1619
1620 priv->cfg->ops->smgmt->clear_station_table(priv); 1620 iwl_clear_stations_table(priv);
1621 ret = priv->cfg->ops->lib->alive_notify(priv); 1621 ret = priv->cfg->ops->lib->alive_notify(priv);
1622 if (ret) { 1622 if (ret) {
1623 IWL_WARN(priv, 1623 IWL_WARN(priv,
@@ -1703,7 +1703,7 @@ static void __iwl_down(struct iwl_priv *priv)
1703 1703
1704 iwl_leds_unregister(priv); 1704 iwl_leds_unregister(priv);
1705 1705
1706 priv->cfg->ops->smgmt->clear_station_table(priv); 1706 iwl_clear_stations_table(priv);
1707 1707
1708 /* Unblock any waiting calls */ 1708 /* Unblock any waiting calls */
1709 wake_up_interruptible_all(&priv->wait_command_queue); 1709 wake_up_interruptible_all(&priv->wait_command_queue);
@@ -1887,8 +1887,6 @@ static int __iwl_up(struct iwl_priv *priv)
1887 1887
1888 /* clear (again), then enable host interrupts */ 1888 /* clear (again), then enable host interrupts */
1889 iwl_write32(priv, CSR_INT, 0xFFFFFFFF); 1889 iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
1890 /* enable dram interrupt */
1891 iwl_reset_ict(priv);
1892 iwl_enable_interrupts(priv); 1890 iwl_enable_interrupts(priv);
1893 1891
1894 /* really make sure rfkill handshake bits are cleared */ 1892 /* really make sure rfkill handshake bits are cleared */
@@ -1903,7 +1901,7 @@ static int __iwl_up(struct iwl_priv *priv)
1903 1901
1904 for (i = 0; i < MAX_HW_RESTARTS; i++) { 1902 for (i = 0; i < MAX_HW_RESTARTS; i++) {
1905 1903
1906 priv->cfg->ops->smgmt->clear_station_table(priv); 1904 iwl_clear_stations_table(priv);
1907 1905
1908 /* load bootstrap state machine, 1906 /* load bootstrap state machine,
1909 * load bootstrap program into processor's memory, 1907 * load bootstrap program into processor's memory,
@@ -1962,6 +1960,9 @@ static void iwl_bg_alive_start(struct work_struct *data)
1962 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 1960 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
1963 return; 1961 return;
1964 1962
1963 /* enable dram interrupt */
1964 iwl_reset_ict(priv);
1965
1965 mutex_lock(&priv->mutex); 1966 mutex_lock(&priv->mutex);
1966 iwl_alive_start(priv); 1967 iwl_alive_start(priv);
1967 mutex_unlock(&priv->mutex); 1968 mutex_unlock(&priv->mutex);
@@ -2348,7 +2349,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2348 return -EOPNOTSUPP; 2349 return -EOPNOTSUPP;
2349 } 2350 }
2350 addr = sta ? sta->addr : iwl_bcast_addr; 2351 addr = sta ? sta->addr : iwl_bcast_addr;
2351 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); 2352 sta_id = iwl_find_station(priv, addr);
2352 if (sta_id == IWL_INVALID_STATION) { 2353 if (sta_id == IWL_INVALID_STATION) {
2353 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", 2354 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
2354 addr); 2355 addr);
@@ -3121,7 +3122,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
3121 iwl_rx_queue_free(priv, &priv->rxq); 3122 iwl_rx_queue_free(priv, &priv->rxq);
3122 iwl_hw_txq_ctx_free(priv); 3123 iwl_hw_txq_ctx_free(priv);
3123 3124
3124 priv->cfg->ops->smgmt->clear_station_table(priv); 3125 iwl_clear_stations_table(priv);
3125 iwl_eeprom_free(priv); 3126 iwl_eeprom_free(priv);
3126 3127
3127 3128
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index e581dc323f0a..c87033bf3ad2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -1067,7 +1067,7 @@ struct iwl_addsta_cmd {
1067 * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */ 1067 * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
1068 __le16 tid_disable_tx; 1068 __le16 tid_disable_tx;
1069 1069
1070 __le16 reserved1; 1070 __le16 rate_n_flags; /* 3945 only */
1071 1071
1072 /* TID for which to add block-ack support. 1072 /* TID for which to add block-ack support.
1073 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */ 1073 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
@@ -1913,6 +1913,18 @@ struct iwl_link_qual_general_params {
1913 u8 start_rate_index[LINK_QUAL_AC_NUM]; 1913 u8 start_rate_index[LINK_QUAL_AC_NUM];
1914} __attribute__ ((packed)); 1914} __attribute__ ((packed));
1915 1915
1916#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
1917#define LINK_QUAL_AGG_TIME_LIMIT_MAX (65535)
1918#define LINK_QUAL_AGG_TIME_LIMIT_MIN (0)
1919
1920#define LINK_QUAL_AGG_DISABLE_START_DEF (3)
1921#define LINK_QUAL_AGG_DISABLE_START_MAX (255)
1922#define LINK_QUAL_AGG_DISABLE_START_MIN (0)
1923
1924#define LINK_QUAL_AGG_FRAME_LIMIT_DEF (31)
1925#define LINK_QUAL_AGG_FRAME_LIMIT_MAX (64)
1926#define LINK_QUAL_AGG_FRAME_LIMIT_MIN (0)
1927
1916/** 1928/**
1917 * struct iwl_link_qual_agg_params 1929 * struct iwl_link_qual_agg_params
1918 * 1930 *
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index e93ddb74457e..51cae4ec26a5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1389,7 +1389,7 @@ int iwl_init_drv(struct iwl_priv *priv)
1389 mutex_init(&priv->mutex); 1389 mutex_init(&priv->mutex);
1390 1390
1391 /* Clear the driver's (not device's) station table */ 1391 /* Clear the driver's (not device's) station table */
1392 priv->cfg->ops->smgmt->clear_station_table(priv); 1392 iwl_clear_stations_table(priv);
1393 1393
1394 priv->data_retry_limit = -1; 1394 priv->data_retry_limit = -1;
1395 priv->ieee_channels = NULL; 1395 priv->ieee_channels = NULL;
@@ -1704,8 +1704,9 @@ static irqreturn_t iwl_isr(int irq, void *data)
1704{ 1704{
1705 struct iwl_priv *priv = data; 1705 struct iwl_priv *priv = data;
1706 u32 inta, inta_mask; 1706 u32 inta, inta_mask;
1707#ifdef CONFIG_IWLWIFI_DEBUG
1707 u32 inta_fh; 1708 u32 inta_fh;
1708 1709#endif
1709 if (!priv) 1710 if (!priv)
1710 return IRQ_NONE; 1711 return IRQ_NONE;
1711 1712
@@ -2679,19 +2680,12 @@ int iwl_set_mode(struct iwl_priv *priv, int mode)
2679 2680
2680 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); 2681 memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
2681 2682
2682 priv->cfg->ops->smgmt->clear_station_table(priv); 2683 iwl_clear_stations_table(priv);
2683 2684
2684 /* dont commit rxon if rf-kill is on*/ 2685 /* dont commit rxon if rf-kill is on*/
2685 if (!iwl_is_ready_rf(priv)) 2686 if (!iwl_is_ready_rf(priv))
2686 return -EAGAIN; 2687 return -EAGAIN;
2687 2688
2688 cancel_delayed_work(&priv->scan_check);
2689 if (iwl_scan_cancel_timeout(priv, 100)) {
2690 IWL_WARN(priv, "Aborted scan still in progress after 100ms\n");
2691 IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
2692 return -EAGAIN;
2693 }
2694
2695 iwlcore_commit_rxon(priv); 2689 iwlcore_commit_rxon(priv);
2696 2690
2697 return 0; 2691 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 87df1b767941..b52d0fb16060 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -83,15 +83,6 @@ struct iwl_cmd;
83#define IWL_SKU_A 0x2 83#define IWL_SKU_A 0x2
84#define IWL_SKU_N 0x8 84#define IWL_SKU_N 0x8
85 85
86struct iwl_station_mgmt_ops {
87 u8 (*add_station)(struct iwl_priv *priv, const u8 *addr,
88 int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info);
89 int (*remove_station)(struct iwl_priv *priv, const u8 *addr,
90 int is_ap);
91 u8 (*find_station)(struct iwl_priv *priv, const u8 *addr);
92 void (*clear_station_table)(struct iwl_priv *priv);
93};
94
95struct iwl_hcmd_ops { 86struct iwl_hcmd_ops {
96 int (*rxon_assoc)(struct iwl_priv *priv); 87 int (*rxon_assoc)(struct iwl_priv *priv);
97 int (*commit_rxon)(struct iwl_priv *priv); 88 int (*commit_rxon)(struct iwl_priv *priv);
@@ -183,7 +174,6 @@ struct iwl_ops {
183 const struct iwl_lib_ops *lib; 174 const struct iwl_lib_ops *lib;
184 const struct iwl_hcmd_ops *hcmd; 175 const struct iwl_hcmd_ops *hcmd;
185 const struct iwl_hcmd_utils_ops *utils; 176 const struct iwl_hcmd_utils_ops *utils;
186 const struct iwl_station_mgmt_ops *smgmt;
187}; 177};
188 178
189struct iwl_mod_params { 179struct iwl_mod_params {
@@ -192,7 +182,7 @@ struct iwl_mod_params {
192 int disable_hw_scan; /* def: 0 = use h/w scan */ 182 int disable_hw_scan; /* def: 0 = use h/w scan */
193 int num_of_queues; /* def: HW dependent */ 183 int num_of_queues; /* def: HW dependent */
194 int num_of_ampdu_queues;/* def: HW dependent */ 184 int num_of_ampdu_queues;/* def: HW dependent */
195 int disable_11n; /* def: 0 = disable 11n capabilities */ 185 int disable_11n; /* def: 0 = 11n capabilities enabled */
196 int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */ 186 int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */
197 int antenna; /* def: 0 = both antennas (use diversity) */ 187 int antenna; /* def: 0 = both antennas (use diversity) */
198 int restart_fw; /* def: 1 = restart firmware */ 188 int restart_fw; /* def: 1 = restart firmware */
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 2dafc26fb6a8..28c39cf8b126 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -70,7 +70,6 @@ extern struct iwl_ops iwl5000_ops;
70extern struct iwl_lib_ops iwl5000_lib; 70extern struct iwl_lib_ops iwl5000_lib;
71extern struct iwl_hcmd_ops iwl5000_hcmd; 71extern struct iwl_hcmd_ops iwl5000_hcmd;
72extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils; 72extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils;
73extern struct iwl_station_mgmt_ops iwl5000_station_mgmt;
74 73
75/* shared functions from iwl-5000.c */ 74/* shared functions from iwl-5000.c */
76extern u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len); 75extern u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len);
@@ -290,11 +289,11 @@ struct iwl_frame {
290#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) 289#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
291 290
292enum { 291enum {
293 /* CMD_SIZE_NORMAL = 0, */ 292 CMD_SYNC = 0,
293 CMD_SIZE_NORMAL = 0,
294 CMD_NO_SKB = 0,
294 CMD_SIZE_HUGE = (1 << 0), 295 CMD_SIZE_HUGE = (1 << 0),
295 /* CMD_SYNC = 0, */
296 CMD_ASYNC = (1 << 1), 296 CMD_ASYNC = (1 << 1),
297 /* CMD_NO_SKB = 0, */
298 CMD_WANT_SKB = (1 << 2), 297 CMD_WANT_SKB = (1 << 2),
299}; 298};
300 299
@@ -1119,8 +1118,6 @@ struct iwl_priv {
1119 1118
1120 struct iwl3945_notif_statistics statistics_39; 1119 struct iwl3945_notif_statistics statistics_39;
1121 1120
1122 struct iwl3945_station_entry stations_39[IWL_STATION_COUNT];
1123
1124 u32 sta_supp_rates; 1121 u32 sta_supp_rates;
1125}; /*iwl_priv */ 1122}; /*iwl_priv */
1126 1123
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index cefa501e5971..7d7554a2f341 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -240,13 +240,11 @@ static int iwl_init_otp_access(struct iwl_priv *priv)
240 if (ret < 0) 240 if (ret < 0)
241 IWL_ERR(priv, "Time out access OTP\n"); 241 IWL_ERR(priv, "Time out access OTP\n");
242 else { 242 else {
243 if (!ret) { 243 iwl_set_bits_prph(priv, APMG_PS_CTRL_REG,
244 iwl_set_bits_prph(priv, APMG_PS_CTRL_REG, 244 APMG_PS_CTRL_VAL_RESET_REQ);
245 APMG_PS_CTRL_VAL_RESET_REQ); 245 udelay(5);
246 udelay(5); 246 iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
247 iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG, 247 APMG_PS_CTRL_VAL_RESET_REQ);
248 APMG_PS_CTRL_VAL_RESET_REQ);
249 }
250 } 248 }
251 return ret; 249 return ret;
252} 250}
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 19680f72087f..5e64252f80f6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -176,10 +176,6 @@ static int iwl_led_associate(struct iwl_priv *priv, int led_id)
176static int iwl_led_disassociate(struct iwl_priv *priv, int led_id) 176static int iwl_led_disassociate(struct iwl_priv *priv, int led_id)
177{ 177{
178 priv->allow_blinking = 0; 178 priv->allow_blinking = 0;
179 if (iwl_is_rfkill(priv))
180 iwl4965_led_off_reg(priv, led_id);
181 else
182 iwl4965_led_on_reg(priv, led_id);
183 179
184 return 0; 180 return 0;
185} 181}
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
index 65605ad44e4b..13149936fd26 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
@@ -36,42 +36,37 @@
36#include "iwl-core.h" 36#include "iwl-core.h"
37 37
38/* software rf-kill from user */ 38/* software rf-kill from user */
39static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) 39static int iwl_rfkill_soft_rf_kill(void *data, bool blocked)
40{ 40{
41 struct iwl_priv *priv = data; 41 struct iwl_priv *priv = data;
42 int err = 0;
43 42
44 if (!priv->rfkill) 43 if (!priv->rfkill)
45 return 0; 44 return -EINVAL;
46 45
47 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 46 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
48 return 0; 47 return 0;
49 48
50 IWL_DEBUG_RF_KILL(priv, "we received soft RFKILL set to state %d\n", state); 49 IWL_DEBUG_RF_KILL(priv, "received soft RFKILL: block=%d\n", blocked);
50
51 mutex_lock(&priv->mutex); 51 mutex_lock(&priv->mutex);
52 52
53 switch (state) { 53 if (iwl_is_rfkill_hw(priv))
54 case RFKILL_STATE_UNBLOCKED: 54 goto out_unlock;
55 if (iwl_is_rfkill_hw(priv)) { 55
56 err = -EBUSY; 56 if (!blocked)
57 goto out_unlock;
58 }
59 iwl_radio_kill_sw_enable_radio(priv); 57 iwl_radio_kill_sw_enable_radio(priv);
60 break; 58 else
61 case RFKILL_STATE_SOFT_BLOCKED:
62 iwl_radio_kill_sw_disable_radio(priv); 59 iwl_radio_kill_sw_disable_radio(priv);
63 break; 60
64 default:
65 IWL_WARN(priv, "we received unexpected RFKILL state %d\n",
66 state);
67 break;
68 }
69out_unlock: 61out_unlock:
70 mutex_unlock(&priv->mutex); 62 mutex_unlock(&priv->mutex);
71 63 return 0;
72 return err;
73} 64}
74 65
66static const struct rfkill_ops iwl_rfkill_ops = {
67 .set_block = iwl_rfkill_soft_rf_kill,
68};
69
75int iwl_rfkill_init(struct iwl_priv *priv) 70int iwl_rfkill_init(struct iwl_priv *priv)
76{ 71{
77 struct device *device = wiphy_dev(priv->hw->wiphy); 72 struct device *device = wiphy_dev(priv->hw->wiphy);
@@ -80,21 +75,16 @@ int iwl_rfkill_init(struct iwl_priv *priv)
80 BUG_ON(device == NULL); 75 BUG_ON(device == NULL);
81 76
82 IWL_DEBUG_RF_KILL(priv, "Initializing RFKILL.\n"); 77 IWL_DEBUG_RF_KILL(priv, "Initializing RFKILL.\n");
83 priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); 78 priv->rfkill = rfkill_alloc(priv->cfg->name,
79 device,
80 RFKILL_TYPE_WLAN,
81 &iwl_rfkill_ops, priv);
84 if (!priv->rfkill) { 82 if (!priv->rfkill) {
85 IWL_ERR(priv, "Unable to allocate RFKILL device.\n"); 83 IWL_ERR(priv, "Unable to allocate RFKILL device.\n");
86 ret = -ENOMEM; 84 ret = -ENOMEM;
87 goto error; 85 goto error;
88 } 86 }
89 87
90 priv->rfkill->name = priv->cfg->name;
91 priv->rfkill->data = priv;
92 priv->rfkill->state = RFKILL_STATE_UNBLOCKED;
93 priv->rfkill->toggle_radio = iwl_rfkill_soft_rf_kill;
94
95 priv->rfkill->dev.class->suspend = NULL;
96 priv->rfkill->dev.class->resume = NULL;
97
98 ret = rfkill_register(priv->rfkill); 88 ret = rfkill_register(priv->rfkill);
99 if (ret) { 89 if (ret) {
100 IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret); 90 IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret);
@@ -102,11 +92,10 @@ int iwl_rfkill_init(struct iwl_priv *priv)
102 } 92 }
103 93
104 IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n"); 94 IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n");
105 return ret; 95 return 0;
106 96
107free_rfkill: 97free_rfkill:
108 if (priv->rfkill != NULL) 98 rfkill_destroy(priv->rfkill);
109 rfkill_free(priv->rfkill);
110 priv->rfkill = NULL; 99 priv->rfkill = NULL;
111 100
112error: 101error:
@@ -118,8 +107,10 @@ EXPORT_SYMBOL(iwl_rfkill_init);
118void iwl_rfkill_unregister(struct iwl_priv *priv) 107void iwl_rfkill_unregister(struct iwl_priv *priv)
119{ 108{
120 109
121 if (priv->rfkill) 110 if (priv->rfkill) {
122 rfkill_unregister(priv->rfkill); 111 rfkill_unregister(priv->rfkill);
112 rfkill_destroy(priv->rfkill);
113 }
123 114
124 priv->rfkill = NULL; 115 priv->rfkill = NULL;
125} 116}
@@ -131,14 +122,10 @@ void iwl_rfkill_set_hw_state(struct iwl_priv *priv)
131 if (!priv->rfkill) 122 if (!priv->rfkill)
132 return; 123 return;
133 124
134 if (iwl_is_rfkill_hw(priv)) { 125 if (rfkill_set_hw_state(priv->rfkill,
135 rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED); 126 !!iwl_is_rfkill_hw(priv)))
136 return; 127 iwl_radio_kill_sw_disable_radio(priv);
137 }
138
139 if (!iwl_is_rfkill_sw(priv))
140 rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
141 else 128 else
142 rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED); 129 iwl_radio_kill_sw_enable_radio(priv);
143} 130}
144EXPORT_SYMBOL(iwl_rfkill_set_hw_state); 131EXPORT_SYMBOL(iwl_rfkill_set_hw_state);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 0eb939c40ac1..2addf735b193 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -75,7 +75,7 @@ int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
75 return IWL_AP_ID; 75 return IWL_AP_ID;
76 } else { 76 } else {
77 u8 *da = ieee80211_get_DA(hdr); 77 u8 *da = ieee80211_get_DA(hdr);
78 return priv->cfg->ops->smgmt->find_station(priv, da); 78 return iwl_find_station(priv, da);
79 } 79 }
80} 80}
81EXPORT_SYMBOL(iwl_get_ra_sta_id); 81EXPORT_SYMBOL(iwl_get_ra_sta_id);
@@ -86,8 +86,7 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
86 86
87 spin_lock_irqsave(&priv->sta_lock, flags); 87 spin_lock_irqsave(&priv->sta_lock, flags);
88 88
89 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) && 89 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
90 !(priv->stations_39[sta_id].used & IWL_STA_DRIVER_ACTIVE))
91 IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n", 90 IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n",
92 sta_id); 91 sta_id);
93 92
@@ -228,15 +227,16 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
228} 227}
229 228
230/** 229/**
231 * iwl_add_station_flags - Add station to tables in driver and device 230 * iwl_add_station - Add station to tables in driver and device
232 */ 231 */
233u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap, 232u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
234 u8 flags, struct ieee80211_sta_ht_cap *ht_info) 233 struct ieee80211_sta_ht_cap *ht_info)
235{ 234{
236 int i;
237 int sta_id = IWL_INVALID_STATION;
238 struct iwl_station_entry *station; 235 struct iwl_station_entry *station;
239 unsigned long flags_spin; 236 unsigned long flags_spin;
237 int i;
238 int sta_id = IWL_INVALID_STATION;
239 u16 rate;
240 240
241 spin_lock_irqsave(&priv->sta_lock, flags_spin); 241 spin_lock_irqsave(&priv->sta_lock, flags_spin);
242 if (is_ap) 242 if (is_ap)
@@ -288,6 +288,12 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
288 priv->iw_mode != NL80211_IFTYPE_ADHOC) 288 priv->iw_mode != NL80211_IFTYPE_ADHOC)
289 iwl_set_ht_add_station(priv, sta_id, ht_info); 289 iwl_set_ht_add_station(priv, sta_id, ht_info);
290 290
291 /* 3945 only */
292 rate = (priv->band == IEEE80211_BAND_5GHZ) ?
293 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP;
294 /* Turn on both antennas for the station... */
295 station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK);
296
291 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 297 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
292 298
293 /* Add station to device's station table */ 299 /* Add station to device's station table */
@@ -295,12 +301,12 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
295 return sta_id; 301 return sta_id;
296 302
297} 303}
298EXPORT_SYMBOL(iwl_add_station_flags); 304EXPORT_SYMBOL(iwl_add_station);
299 305
300static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr) 306static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)
301{ 307{
302 unsigned long flags; 308 unsigned long flags;
303 u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); 309 u8 sta_id = iwl_find_station(priv, addr);
304 310
305 BUG_ON(sta_id == IWL_INVALID_STATION); 311 BUG_ON(sta_id == IWL_INVALID_STATION);
306 312
@@ -408,7 +414,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
408/** 414/**
409 * iwl_remove_station - Remove driver's knowledge of station. 415 * iwl_remove_station - Remove driver's knowledge of station.
410 */ 416 */
411int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap) 417int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
412{ 418{
413 int sta_id = IWL_INVALID_STATION; 419 int sta_id = IWL_INVALID_STATION;
414 int i, ret = -EINVAL; 420 int i, ret = -EINVAL;
@@ -767,7 +773,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
767 unsigned long flags; 773 unsigned long flags;
768 int i; 774 int i;
769 775
770 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); 776 sta_id = iwl_find_station(priv, addr);
771 if (sta_id == IWL_INVALID_STATION) { 777 if (sta_id == IWL_INVALID_STATION) {
772 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", 778 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
773 addr); 779 addr);
@@ -946,7 +952,7 @@ EXPORT_SYMBOL(iwl_send_lq_cmd);
946 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD, 952 * calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
947 * which requires station table entry to exist). 953 * which requires station table entry to exist).
948 */ 954 */
949static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap) 955static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap)
950{ 956{
951 int i, r; 957 int i, r;
952 struct iwl_link_quality_cmd link_cmd = { 958 struct iwl_link_quality_cmd link_cmd = {
@@ -979,8 +985,9 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
979 link_cmd.general_params.single_stream_ant_msk = 985 link_cmd.general_params.single_stream_ant_msk =
980 first_antenna(priv->hw_params.valid_tx_ant); 986 first_antenna(priv->hw_params.valid_tx_ant);
981 link_cmd.general_params.dual_stream_ant_msk = 3; 987 link_cmd.general_params.dual_stream_ant_msk = 3;
982 link_cmd.agg_params.agg_dis_start_th = 3; 988 link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
983 link_cmd.agg_params.agg_time_limit = cpu_to_le16(4000); 989 link_cmd.agg_params.agg_time_limit =
990 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
984 991
985 /* Update the rate scaling for control frame Tx to AP */ 992 /* Update the rate scaling for control frame Tx to AP */
986 link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id; 993 link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id;
@@ -995,7 +1002,7 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
995 * there is only one AP station with id= IWL_AP_ID 1002 * there is only one AP station with id= IWL_AP_ID
996 * NOTE: mutex must be held before calling this function 1003 * NOTE: mutex must be held before calling this function
997 */ 1004 */
998int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) 1005int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
999{ 1006{
1000 struct ieee80211_sta *sta; 1007 struct ieee80211_sta *sta;
1001 struct ieee80211_sta_ht_cap ht_config; 1008 struct ieee80211_sta_ht_cap ht_config;
@@ -1020,8 +1027,7 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
1020 rcu_read_unlock(); 1027 rcu_read_unlock();
1021 } 1028 }
1022 1029
1023 sta_id = priv->cfg->ops->smgmt->add_station(priv, addr, is_ap, 1030 sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config);
1024 0, cur_ht_config);
1025 1031
1026 /* Set up default rate scaling table in device's station table */ 1032 /* Set up default rate scaling table in device's station table */
1027 iwl_sta_init_lq(priv, addr, is_ap); 1033 iwl_sta_init_lq(priv, addr, is_ap);
@@ -1054,7 +1060,7 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
1054 1060
1055 /* If we are an AP, then find the station, or use BCAST */ 1061 /* If we are an AP, then find the station, or use BCAST */
1056 case NL80211_IFTYPE_AP: 1062 case NL80211_IFTYPE_AP:
1057 sta_id = priv->cfg->ops->smgmt->find_station(priv, hdr->addr1); 1063 sta_id = iwl_find_station(priv, hdr->addr1);
1058 if (sta_id != IWL_INVALID_STATION) 1064 if (sta_id != IWL_INVALID_STATION)
1059 return sta_id; 1065 return sta_id;
1060 return priv->hw_params.bcast_sta_id; 1066 return priv->hw_params.bcast_sta_id;
@@ -1062,13 +1068,13 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
1062 /* If this frame is going out to an IBSS network, find the station, 1068 /* If this frame is going out to an IBSS network, find the station,
1063 * or create a new station table entry */ 1069 * or create a new station table entry */
1064 case NL80211_IFTYPE_ADHOC: 1070 case NL80211_IFTYPE_ADHOC:
1065 sta_id = priv->cfg->ops->smgmt->find_station(priv, hdr->addr1); 1071 sta_id = iwl_find_station(priv, hdr->addr1);
1066 if (sta_id != IWL_INVALID_STATION) 1072 if (sta_id != IWL_INVALID_STATION)
1067 return sta_id; 1073 return sta_id;
1068 1074
1069 /* Create new station table entry */ 1075 /* Create new station table entry */
1070 sta_id = priv->cfg->ops->smgmt->add_station(priv, hdr->addr1, 1076 sta_id = iwl_add_station(priv, hdr->addr1, false,
1071 0, CMD_ASYNC, NULL); 1077 CMD_ASYNC, NULL);
1072 1078
1073 if (sta_id != IWL_INVALID_STATION) 1079 if (sta_id != IWL_INVALID_STATION)
1074 return sta_id; 1080 return sta_id;
@@ -1111,7 +1117,7 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv,
1111 unsigned long flags; 1117 unsigned long flags;
1112 int sta_id; 1118 int sta_id;
1113 1119
1114 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); 1120 sta_id = iwl_find_station(priv, addr);
1115 if (sta_id == IWL_INVALID_STATION) 1121 if (sta_id == IWL_INVALID_STATION)
1116 return -ENXIO; 1122 return -ENXIO;
1117 1123
@@ -1133,7 +1139,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid)
1133 unsigned long flags; 1139 unsigned long flags;
1134 int sta_id; 1140 int sta_id;
1135 1141
1136 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); 1142 sta_id = iwl_find_station(priv, addr);
1137 if (sta_id == IWL_INVALID_STATION) { 1143 if (sta_id == IWL_INVALID_STATION) {
1138 IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid); 1144 IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
1139 return -ENXIO; 1145 return -ENXIO;
@@ -1168,7 +1174,7 @@ static void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
1168void iwl_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) 1174void iwl_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr)
1169{ 1175{
1170 /* FIXME: need locking over ps_status ??? */ 1176 /* FIXME: need locking over ps_status ??? */
1171 u8 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); 1177 u8 sta_id = iwl_find_station(priv, addr);
1172 1178
1173 if (sta_id != IWL_INVALID_STATION) { 1179 if (sta_id != IWL_INVALID_STATION) {
1174 u8 sta_awake = priv->stations[sta_id]. 1180 u8 sta_awake = priv->stations[sta_id].
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 59a586b6b56c..6deebade6361 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -51,16 +51,15 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
51 struct ieee80211_key_conf *keyconf, 51 struct ieee80211_key_conf *keyconf,
52 const u8 *addr, u32 iv32, u16 *phase1key); 52 const u8 *addr, u32 iv32, u16 *phase1key);
53 53
54int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap); 54int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
55int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap); 55int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
56void iwl_clear_stations_table(struct iwl_priv *priv); 56void iwl_clear_stations_table(struct iwl_priv *priv);
57int iwl_get_free_ucode_key_index(struct iwl_priv *priv); 57int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
58int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); 58int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
59int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); 59int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
60int iwl_send_add_sta(struct iwl_priv *priv, 60int iwl_send_add_sta(struct iwl_priv *priv,
61 struct iwl_addsta_cmd *sta, u8 flags); 61 struct iwl_addsta_cmd *sta, u8 flags);
62u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, 62u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
63 int is_ap, u8 flags,
64 struct ieee80211_sta_ht_cap *ht_info); 63 struct ieee80211_sta_ht_cap *ht_info);
65void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); 64void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
66int iwl_sta_rx_agg_start(struct iwl_priv *priv, 65int iwl_sta_rx_agg_start(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 5c10b87d0336..92fa1a39c446 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -95,144 +95,6 @@ struct iwl_mod_params iwl3945_mod_params = {
95 /* the rest are 0 by default */ 95 /* the rest are 0 by default */
96}; 96};
97 97
98/*************** STATION TABLE MANAGEMENT ****
99 * mac80211 should be examined to determine if sta_info is duplicating
100 * the functionality provided here
101 */
102
103/**************************************************************/
104#if 0 /* temporary disable till we add real remove station */
105/**
106 * iwl3945_remove_station - Remove driver's knowledge of station.
107 *
108 * NOTE: This does not remove station from device's station table.
109 */
110static u8 iwl3945_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
111{
112 int index = IWL_INVALID_STATION;
113 int i;
114 unsigned long flags;
115
116 spin_lock_irqsave(&priv->sta_lock, flags);
117
118 if (is_ap)
119 index = IWL_AP_ID;
120 else if (is_broadcast_ether_addr(addr))
121 index = priv->hw_params.bcast_sta_id;
122 else
123 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
124 if (priv->stations_39[i].used &&
125 !compare_ether_addr(priv->stations_39[i].sta.sta.addr,
126 addr)) {
127 index = i;
128 break;
129 }
130
131 if (unlikely(index == IWL_INVALID_STATION))
132 goto out;
133
134 if (priv->stations_39[index].used) {
135 priv->stations_39[index].used = 0;
136 priv->num_stations--;
137 }
138
139 BUG_ON(priv->num_stations < 0);
140
141out:
142 spin_unlock_irqrestore(&priv->sta_lock, flags);
143 return 0;
144}
145#endif
146
147/**
148 * iwl3945_clear_stations_table - Clear the driver's station table
149 *
150 * NOTE: This does not clear or otherwise alter the device's station table.
151 */
152void iwl3945_clear_stations_table(struct iwl_priv *priv)
153{
154 unsigned long flags;
155
156 spin_lock_irqsave(&priv->sta_lock, flags);
157
158 priv->num_stations = 0;
159 memset(priv->stations_39, 0, sizeof(priv->stations_39));
160
161 spin_unlock_irqrestore(&priv->sta_lock, flags);
162}
163
164/**
165 * iwl3945_add_station - Add station to station tables in driver and device
166 */
167u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info)
168{
169 int i;
170 int index = IWL_INVALID_STATION;
171 struct iwl3945_station_entry *station;
172 unsigned long flags_spin;
173 u8 rate;
174
175 spin_lock_irqsave(&priv->sta_lock, flags_spin);
176 if (is_ap)
177 index = IWL_AP_ID;
178 else if (is_broadcast_ether_addr(addr))
179 index = priv->hw_params.bcast_sta_id;
180 else
181 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) {
182 if (!compare_ether_addr(priv->stations_39[i].sta.sta.addr,
183 addr)) {
184 index = i;
185 break;
186 }
187
188 if (!priv->stations_39[i].used &&
189 index == IWL_INVALID_STATION)
190 index = i;
191 }
192
193 /* These two conditions has the same outcome but keep them separate
194 since they have different meaning */
195 if (unlikely(index == IWL_INVALID_STATION)) {
196 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
197 return index;
198 }
199
200 if (priv->stations_39[index].used &&
201 !compare_ether_addr(priv->stations_39[index].sta.sta.addr, addr)) {
202 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
203 return index;
204 }
205
206 IWL_DEBUG_ASSOC(priv, "Add STA ID %d: %pM\n", index, addr);
207 station = &priv->stations_39[index];
208 station->used = 1;
209 priv->num_stations++;
210
211 /* Set up the REPLY_ADD_STA command to send to device */
212 memset(&station->sta, 0, sizeof(struct iwl3945_addsta_cmd));
213 memcpy(station->sta.sta.addr, addr, ETH_ALEN);
214 station->sta.mode = 0;
215 station->sta.sta.sta_id = index;
216 station->sta.station_flags = 0;
217
218 if (priv->band == IEEE80211_BAND_5GHZ)
219 rate = IWL_RATE_6M_PLCP;
220 else
221 rate = IWL_RATE_1M_PLCP;
222
223 /* Turn on both antennas for the station... */
224 station->sta.rate_n_flags =
225 iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);
226
227 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
228
229 /* Add station to device's station table */
230 iwl_send_add_sta(priv,
231 (struct iwl_addsta_cmd *)&station->sta, flags);
232 return index;
233
234}
235
236/** 98/**
237 * iwl3945_get_antenna_flags - Get antenna flags for RXON command 99 * iwl3945_get_antenna_flags - Get antenna flags for RXON command
238 * @priv: eeprom and antenna fields are used to determine antenna flags 100 * @priv: eeprom and antenna fields are used to determine antenna flags
@@ -289,32 +151,31 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
289 key_flags &= ~STA_KEY_FLG_INVALID; 151 key_flags &= ~STA_KEY_FLG_INVALID;
290 152
291 spin_lock_irqsave(&priv->sta_lock, flags); 153 spin_lock_irqsave(&priv->sta_lock, flags);
292 priv->stations_39[sta_id].keyinfo.alg = keyconf->alg; 154 priv->stations[sta_id].keyinfo.alg = keyconf->alg;
293 priv->stations_39[sta_id].keyinfo.keylen = keyconf->keylen; 155 priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
294 memcpy(priv->stations_39[sta_id].keyinfo.key, keyconf->key, 156 memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
295 keyconf->keylen); 157 keyconf->keylen);
296 158
297 memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key, 159 memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
298 keyconf->keylen); 160 keyconf->keylen);
299 161
300 if ((priv->stations_39[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) 162 if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
301 == STA_KEY_FLG_NO_ENC) 163 == STA_KEY_FLG_NO_ENC)
302 priv->stations_39[sta_id].sta.key.key_offset = 164 priv->stations[sta_id].sta.key.key_offset =
303 iwl_get_free_ucode_key_index(priv); 165 iwl_get_free_ucode_key_index(priv);
304 /* else, we are overriding an existing key => no need to allocated room 166 /* else, we are overriding an existing key => no need to allocated room
305 * in uCode. */ 167 * in uCode. */
306 168
307 WARN(priv->stations_39[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, 169 WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
308 "no space for a new key"); 170 "no space for a new key");
309 171
310 priv->stations_39[sta_id].sta.key.key_flags = key_flags; 172 priv->stations[sta_id].sta.key.key_flags = key_flags;
311 priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 173 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
312 priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 174 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
313 175
314 IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n"); 176 IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n");
315 177
316 ret = iwl_send_add_sta(priv, 178 ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
317 (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, CMD_ASYNC);
318 179
319 spin_unlock_irqrestore(&priv->sta_lock, flags); 180 spin_unlock_irqrestore(&priv->sta_lock, flags);
320 181
@@ -340,17 +201,16 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
340 unsigned long flags; 201 unsigned long flags;
341 202
342 spin_lock_irqsave(&priv->sta_lock, flags); 203 spin_lock_irqsave(&priv->sta_lock, flags);
343 memset(&priv->stations_39[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); 204 memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));
344 memset(&priv->stations_39[sta_id].sta.key, 0, 205 memset(&priv->stations[sta_id].sta.key, 0,
345 sizeof(struct iwl4965_keyinfo)); 206 sizeof(struct iwl4965_keyinfo));
346 priv->stations_39[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; 207 priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
347 priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 208 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
348 priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 209 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
349 spin_unlock_irqrestore(&priv->sta_lock, flags); 210 spin_unlock_irqrestore(&priv->sta_lock, flags);
350 211
351 IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n"); 212 IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n");
352 iwl_send_add_sta(priv, 213 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0);
353 (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0);
354 return 0; 214 return 0;
355} 215}
356 216
@@ -578,7 +438,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
578 int sta_id) 438 int sta_id)
579{ 439{
580 struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload; 440 struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
581 struct iwl_hw_key *keyinfo = &priv->stations_39[sta_id].keyinfo; 441 struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo;
582 442
583 switch (keyinfo->alg) { 443 switch (keyinfo->alg) {
584 case ALG_CCMP: 444 case ALG_CCMP:
@@ -753,7 +613,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
753 if (ieee80211_is_data_qos(fc)) { 613 if (ieee80211_is_data_qos(fc)) {
754 qc = ieee80211_get_qos_ctl(hdr); 614 qc = ieee80211_get_qos_ctl(hdr);
755 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 615 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
756 seq_number = priv->stations_39[sta_id].tid[tid].seq_number & 616 seq_number = priv->stations[sta_id].tid[tid].seq_number &
757 IEEE80211_SCTL_SEQ; 617 IEEE80211_SCTL_SEQ;
758 hdr->seq_ctrl = cpu_to_le16(seq_number) | 618 hdr->seq_ctrl = cpu_to_le16(seq_number) |
759 (hdr->seq_ctrl & 619 (hdr->seq_ctrl &
@@ -813,7 +673,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
813 if (!ieee80211_has_morefrags(hdr->frame_control)) { 673 if (!ieee80211_has_morefrags(hdr->frame_control)) {
814 txq->need_update = 1; 674 txq->need_update = 1;
815 if (qc) 675 if (qc)
816 priv->stations_39[sta_id].tid[tid].seq_number = seq_number; 676 priv->stations[sta_id].tid[tid].seq_number = seq_number;
817 } else { 677 } else {
818 wait_write_ptr = 1; 678 wait_write_ptr = 1;
819 txq->need_update = 0; 679 txq->need_update = 0;
@@ -1316,7 +1176,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
1316 1176
1317 /* If we've added more space for the firmware to place data, tell it. 1177 /* If we've added more space for the firmware to place data, tell it.
1318 * Increment device's write pointer in multiples of 8. */ 1178 * Increment device's write pointer in multiples of 8. */
1319 if ((write != (rxq->write & ~0x7)) 1179 if ((rxq->write_actual != (rxq->write & ~0x7))
1320 || (abs(rxq->write - rxq->read) > 7)) { 1180 || (abs(rxq->write - rxq->read) > 7)) {
1321 spin_lock_irqsave(&rxq->lock, flags); 1181 spin_lock_irqsave(&rxq->lock, flags);
1322 rxq->need_update = 1; 1182 rxq->need_update = 1;
@@ -1337,7 +1197,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
1337 * Also restock the Rx queue via iwl3945_rx_queue_restock. 1197 * Also restock the Rx queue via iwl3945_rx_queue_restock.
1338 * This is called as a scheduled work item (except for during initialization) 1198 * This is called as a scheduled work item (except for during initialization)
1339 */ 1199 */
1340static void iwl3945_rx_allocate(struct iwl_priv *priv) 1200static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
1341{ 1201{
1342 struct iwl_rx_queue *rxq = &priv->rxq; 1202 struct iwl_rx_queue *rxq = &priv->rxq;
1343 struct list_head *element; 1203 struct list_head *element;
@@ -1360,7 +1220,7 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv)
1360 /* Alloc a new receive buffer */ 1220 /* Alloc a new receive buffer */
1361 rxb->skb = 1221 rxb->skb =
1362 alloc_skb(priv->hw_params.rx_buf_size, 1222 alloc_skb(priv->hw_params.rx_buf_size,
1363 GFP_KERNEL); 1223 priority);
1364 if (!rxb->skb) { 1224 if (!rxb->skb) {
1365 if (net_ratelimit()) 1225 if (net_ratelimit())
1366 IWL_CRIT(priv, ": Can not allocate SKB buffers\n"); 1226 IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
@@ -1419,6 +1279,7 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
1419 * not restocked the Rx queue with fresh buffers */ 1279 * not restocked the Rx queue with fresh buffers */
1420 rxq->read = rxq->write = 0; 1280 rxq->read = rxq->write = 0;
1421 rxq->free_count = 0; 1281 rxq->free_count = 0;
1282 rxq->write_actual = 0;
1422 spin_unlock_irqrestore(&rxq->lock, flags); 1283 spin_unlock_irqrestore(&rxq->lock, flags);
1423} 1284}
1424 1285
@@ -1427,13 +1288,21 @@ void iwl3945_rx_replenish(void *data)
1427 struct iwl_priv *priv = data; 1288 struct iwl_priv *priv = data;
1428 unsigned long flags; 1289 unsigned long flags;
1429 1290
1430 iwl3945_rx_allocate(priv); 1291 iwl3945_rx_allocate(priv, GFP_KERNEL);
1431 1292
1432 spin_lock_irqsave(&priv->lock, flags); 1293 spin_lock_irqsave(&priv->lock, flags);
1433 iwl3945_rx_queue_restock(priv); 1294 iwl3945_rx_queue_restock(priv);
1434 spin_unlock_irqrestore(&priv->lock, flags); 1295 spin_unlock_irqrestore(&priv->lock, flags);
1435} 1296}
1436 1297
1298static void iwl3945_rx_replenish_now(struct iwl_priv *priv)
1299{
1300 iwl3945_rx_allocate(priv, GFP_ATOMIC);
1301
1302 iwl3945_rx_queue_restock(priv);
1303}
1304
1305
1437/* Assumes that the skb field of the buffers in 'pool' is kept accurate. 1306/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
1438 * If an SKB has been detached, the POOL needs to have its SKB set to NULL 1307 * If an SKB has been detached, the POOL needs to have its SKB set to NULL
1439 * This free routine walks the list of POOL entries and if SKB is set to 1308 * This free routine walks the list of POOL entries and if SKB is set to
@@ -1556,13 +1425,19 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
1556 unsigned long flags; 1425 unsigned long flags;
1557 u8 fill_rx = 0; 1426 u8 fill_rx = 0;
1558 u32 count = 8; 1427 u32 count = 8;
1428 int total_empty = 0;
1559 1429
1560 /* uCode's read index (stored in shared DRAM) indicates the last Rx 1430 /* uCode's read index (stored in shared DRAM) indicates the last Rx
1561 * buffer that the driver may process (last buffer filled by ucode). */ 1431 * buffer that the driver may process (last buffer filled by ucode). */
1562 r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; 1432 r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF;
1563 i = rxq->read; 1433 i = rxq->read;
1564 1434
1565 if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) 1435 /* calculate total frames need to be restock after handling RX */
1436 total_empty = r - priv->rxq.write_actual;
1437 if (total_empty < 0)
1438 total_empty += RX_QUEUE_SIZE;
1439
1440 if (total_empty > (RX_QUEUE_SIZE / 2))
1566 fill_rx = 1; 1441 fill_rx = 1;
1567 /* Rx interrupt, but nothing sent from uCode */ 1442 /* Rx interrupt, but nothing sent from uCode */
1568 if (i == r) 1443 if (i == r)
@@ -1639,7 +1514,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
1639 count++; 1514 count++;
1640 if (count >= 8) { 1515 if (count >= 8) {
1641 priv->rxq.read = i; 1516 priv->rxq.read = i;
1642 iwl3945_rx_queue_restock(priv); 1517 iwl3945_rx_replenish_now(priv);
1643 count = 0; 1518 count = 0;
1644 } 1519 }
1645 } 1520 }
@@ -1647,7 +1522,10 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
1647 1522
1648 /* Backtrack one entry */ 1523 /* Backtrack one entry */
1649 priv->rxq.read = i; 1524 priv->rxq.read = i;
1650 iwl3945_rx_queue_restock(priv); 1525 if (fill_rx)
1526 iwl3945_rx_replenish_now(priv);
1527 else
1528 iwl3945_rx_queue_restock(priv);
1651} 1529}
1652 1530
1653/* call this function to flush any scheduled tasklet */ 1531/* call this function to flush any scheduled tasklet */
@@ -2589,7 +2467,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2589 goto restart; 2467 goto restart;
2590 } 2468 }
2591 2469
2592 priv->cfg->ops->smgmt->clear_station_table(priv); 2470 iwl_clear_stations_table(priv);
2593 2471
2594 rfkill = iwl_read_prph(priv, APMG_RFKILL_REG); 2472 rfkill = iwl_read_prph(priv, APMG_RFKILL_REG);
2595 IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill); 2473 IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill);
@@ -2681,7 +2559,7 @@ static void __iwl3945_down(struct iwl_priv *priv)
2681 set_bit(STATUS_EXIT_PENDING, &priv->status); 2559 set_bit(STATUS_EXIT_PENDING, &priv->status);
2682 2560
2683 iwl3945_led_unregister(priv); 2561 iwl3945_led_unregister(priv);
2684 priv->cfg->ops->smgmt->clear_station_table(priv); 2562 iwl_clear_stations_table(priv);
2685 2563
2686 /* Unblock any waiting calls */ 2564 /* Unblock any waiting calls */
2687 wake_up_interruptible_all(&priv->wait_command_queue); 2565 wake_up_interruptible_all(&priv->wait_command_queue);
@@ -2833,7 +2711,7 @@ static int __iwl3945_up(struct iwl_priv *priv)
2833 2711
2834 for (i = 0; i < MAX_HW_RESTARTS; i++) { 2712 for (i = 0; i < MAX_HW_RESTARTS; i++) {
2835 2713
2836 priv->cfg->ops->smgmt->clear_station_table(priv); 2714 iwl_clear_stations_table(priv);
2837 2715
2838 /* load bootstrap state machine, 2716 /* load bootstrap state machine,
2839 * load bootstrap program into processor's memory, 2717 * load bootstrap program into processor's memory,
@@ -3247,7 +3125,7 @@ void iwl3945_post_associate(struct iwl_priv *priv)
3247 case NL80211_IFTYPE_ADHOC: 3125 case NL80211_IFTYPE_ADHOC:
3248 3126
3249 priv->assoc_id = 1; 3127 priv->assoc_id = 1;
3250 priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 0, 0, NULL); 3128 iwl_add_station(priv, priv->bssid, 0, CMD_SYNC, NULL);
3251 iwl3945_sync_sta(priv, IWL_STA_ID, 3129 iwl3945_sync_sta(priv, IWL_STA_ID,
3252 (priv->band == IEEE80211_BAND_5GHZ) ? 3130 (priv->band == IEEE80211_BAND_5GHZ) ?
3253 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, 3131 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
@@ -3438,7 +3316,7 @@ void iwl3945_config_ap(struct iwl_priv *priv)
3438 /* restore RXON assoc */ 3316 /* restore RXON assoc */
3439 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3317 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
3440 iwlcore_commit_rxon(priv); 3318 iwlcore_commit_rxon(priv);
3441 priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0, NULL); 3319 iwl_add_station(priv, iwl_bcast_addr, 0, CMD_SYNC, NULL);
3442 } 3320 }
3443 iwl3945_send_beacon_cmd(priv); 3321 iwl3945_send_beacon_cmd(priv);
3444 3322
@@ -3469,7 +3347,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3469 static_key = !iwl_is_associated(priv); 3347 static_key = !iwl_is_associated(priv);
3470 3348
3471 if (!static_key) { 3349 if (!static_key) {
3472 sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); 3350 sta_id = iwl_find_station(priv, addr);
3473 if (sta_id == IWL_INVALID_STATION) { 3351 if (sta_id == IWL_INVALID_STATION) {
3474 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", 3352 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
3475 addr); 3353 addr);
@@ -4044,7 +3922,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
4044 mutex_init(&priv->mutex); 3922 mutex_init(&priv->mutex);
4045 3923
4046 /* Clear the driver's (not device's) station table */ 3924 /* Clear the driver's (not device's) station table */
4047 priv->cfg->ops->smgmt->clear_station_table(priv); 3925 iwl_clear_stations_table(priv);
4048 3926
4049 priv->data_retry_limit = -1; 3927 priv->data_retry_limit = -1;
4050 priv->ieee_channels = NULL; 3928 priv->ieee_channels = NULL;
@@ -4407,7 +4285,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
4407 iwl3945_hw_txq_ctx_free(priv); 4285 iwl3945_hw_txq_ctx_free(priv);
4408 4286
4409 iwl3945_unset_hw_params(priv); 4287 iwl3945_unset_hw_params(priv);
4410 priv->cfg->ops->smgmt->clear_station_table(priv); 4288 iwl_clear_stations_table(priv);
4411 4289
4412 /*netif_stop_queue(dev); */ 4290 /*netif_stop_queue(dev); */
4413 flush_workqueue(priv->workqueue); 4291 flush_workqueue(priv->workqueue);
diff --git a/drivers/net/wireless/iwmc3200wifi/Kconfig b/drivers/net/wireless/iwmc3200wifi/Kconfig
index 41bd4b2b5411..1eccb6df46dd 100644
--- a/drivers/net/wireless/iwmc3200wifi/Kconfig
+++ b/drivers/net/wireless/iwmc3200wifi/Kconfig
@@ -1,10 +1,9 @@
1config IWM 1config IWM
2 tristate "Intel Wireless Multicomm 3200 WiFi driver" 2 tristate "Intel Wireless Multicomm 3200 WiFi driver"
3 depends on MMC && WLAN_80211 && EXPERIMENTAL 3 depends on MMC && WLAN_80211 && EXPERIMENTAL
4 depends on CFG80211
4 select WIRELESS_EXT 5 select WIRELESS_EXT
5 select CFG80211
6 select FW_LOADER 6 select FW_LOADER
7 select RFKILL
8 7
9config IWM_DEBUG 8config IWM_DEBUG
10 bool "Enable full debugging output in iwmc3200wifi" 9 bool "Enable full debugging output in iwmc3200wifi"
diff --git a/drivers/net/wireless/iwmc3200wifi/Makefile b/drivers/net/wireless/iwmc3200wifi/Makefile
index 7cb415e5c11b..927f022545c1 100644
--- a/drivers/net/wireless/iwmc3200wifi/Makefile
+++ b/drivers/net/wireless/iwmc3200wifi/Makefile
@@ -1,5 +1,5 @@
1obj-$(CONFIG_IWM) := iwmc3200wifi.o 1obj-$(CONFIG_IWM) := iwmc3200wifi.o
2iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o 2iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o
3iwmc3200wifi-objs += commands.o wext.o cfg80211.o eeprom.o rfkill.o 3iwmc3200wifi-objs += commands.o wext.o cfg80211.o eeprom.o
4 4
5iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o 5iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index 3256ad2c96ce..96f714e6e12b 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -268,7 +268,7 @@ static int iwm_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
268 268
269 iwm->conf.frag_threshold = wiphy->frag_threshold; 269 iwm->conf.frag_threshold = wiphy->frag_threshold;
270 270
271 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX, 271 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
272 CFG_FRAG_THRESHOLD, 272 CFG_FRAG_THRESHOLD,
273 iwm->conf.frag_threshold); 273 iwm->conf.frag_threshold);
274 if (ret < 0) 274 if (ret < 0)
diff --git a/drivers/net/wireless/iwmc3200wifi/fw.c b/drivers/net/wireless/iwmc3200wifi/fw.c
index db4ba0864730..ec1a15a5a0e4 100644
--- a/drivers/net/wireless/iwmc3200wifi/fw.c
+++ b/drivers/net/wireless/iwmc3200wifi/fw.c
@@ -72,7 +72,7 @@ static int iwm_fw_op_offset(struct iwm_priv *iwm, const struct firmware *fw,
72 } 72 }
73 73
74 if (fw->size < IWM_HDR_LEN) { 74 if (fw->size < IWM_HDR_LEN) {
75 IWM_ERR(iwm, "FW is too small (%d)\n", fw->size); 75 IWM_ERR(iwm, "FW is too small (%zu)\n", fw->size);
76 return -EINVAL; 76 return -EINVAL;
77 } 77 }
78 78
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index 3b29681792bb..635c16ee6186 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -343,8 +343,4 @@ int iwm_rx_handle_resp(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size,
343 struct iwm_wifi_cmd *cmd); 343 struct iwm_wifi_cmd *cmd);
344void iwm_rx_free(struct iwm_priv *iwm); 344void iwm_rx_free(struct iwm_priv *iwm);
345 345
346/* RF Kill API */
347int iwm_rfkill_init(struct iwm_priv *iwm);
348void iwm_rfkill_exit(struct iwm_priv *iwm);
349
350#endif 346#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c
index eec7201e91a8..68e2c3b6c7a1 100644
--- a/drivers/net/wireless/iwmc3200wifi/netdev.c
+++ b/drivers/net/wireless/iwmc3200wifi/netdev.c
@@ -136,17 +136,8 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev,
136 136
137 wdev->netdev = ndev; 137 wdev->netdev = ndev;
138 138
139 ret = iwm_rfkill_init(iwm);
140 if (ret) {
141 dev_err(dev, "Failed to init rfkill\n");
142 goto out_rfkill;
143 }
144
145 return iwm; 139 return iwm;
146 140
147 out_rfkill:
148 unregister_netdev(ndev);
149
150 out_ndev: 141 out_ndev:
151 free_netdev(ndev); 142 free_netdev(ndev);
152 143
@@ -162,7 +153,6 @@ void iwm_if_free(struct iwm_priv *iwm)
162 if (!iwm_to_ndev(iwm)) 153 if (!iwm_to_ndev(iwm))
163 return; 154 return;
164 155
165 iwm_rfkill_exit(iwm);
166 unregister_netdev(iwm_to_ndev(iwm)); 156 unregister_netdev(iwm_to_ndev(iwm));
167 free_netdev(iwm_to_ndev(iwm)); 157 free_netdev(iwm_to_ndev(iwm));
168 iwm_wdev_free(iwm); 158 iwm_wdev_free(iwm);
diff --git a/drivers/net/wireless/iwmc3200wifi/rfkill.c b/drivers/net/wireless/iwmc3200wifi/rfkill.c
deleted file mode 100644
index 4ca8b495f82d..000000000000
--- a/drivers/net/wireless/iwmc3200wifi/rfkill.c
+++ /dev/null
@@ -1,88 +0,0 @@
1/*
2 * Intel Wireless Multicomm 3200 WiFi driver
3 *
4 * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
5 * Samuel Ortiz <samuel.ortiz@intel.com>
6 * Zhu Yi <yi.zhu@intel.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version
10 * 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 *
22 */
23
24#include <linux/rfkill.h>
25
26#include "iwm.h"
27
28static int iwm_rfkill_soft_toggle(void *data, enum rfkill_state state)
29{
30 struct iwm_priv *iwm = data;
31
32 switch (state) {
33 case RFKILL_STATE_UNBLOCKED:
34 if (test_bit(IWM_RADIO_RFKILL_HW, &iwm->radio))
35 return -EBUSY;
36
37 if (test_and_clear_bit(IWM_RADIO_RFKILL_SW, &iwm->radio) &&
38 (iwm_to_ndev(iwm)->flags & IFF_UP))
39 iwm_up(iwm);
40
41 break;
42 case RFKILL_STATE_SOFT_BLOCKED:
43 if (!test_and_set_bit(IWM_RADIO_RFKILL_SW, &iwm->radio))
44 iwm_down(iwm);
45
46 break;
47 default:
48 break;
49 }
50
51 return 0;
52}
53
54int iwm_rfkill_init(struct iwm_priv *iwm)
55{
56 int ret;
57
58 iwm->rfkill = rfkill_allocate(iwm_to_dev(iwm), RFKILL_TYPE_WLAN);
59 if (!iwm->rfkill) {
60 IWM_ERR(iwm, "Unable to allocate rfkill device\n");
61 return -ENOMEM;
62 }
63
64 iwm->rfkill->name = KBUILD_MODNAME;
65 iwm->rfkill->data = iwm;
66 iwm->rfkill->state = RFKILL_STATE_UNBLOCKED;
67 iwm->rfkill->toggle_radio = iwm_rfkill_soft_toggle;
68
69 ret = rfkill_register(iwm->rfkill);
70 if (ret) {
71 IWM_ERR(iwm, "Failed to register rfkill device\n");
72 goto fail;
73 }
74
75 return 0;
76 fail:
77 rfkill_free(iwm->rfkill);
78 return ret;
79}
80
81void iwm_rfkill_exit(struct iwm_priv *iwm)
82{
83 if (iwm->rfkill)
84 rfkill_unregister(iwm->rfkill);
85
86 rfkill_free(iwm->rfkill);
87 iwm->rfkill = NULL;
88}
diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c
index edc0a0091058..b54da677b371 100644
--- a/drivers/net/wireless/iwmc3200wifi/sdio.c
+++ b/drivers/net/wireless/iwmc3200wifi/sdio.c
@@ -395,7 +395,7 @@ static struct iwm_if_ops if_sdio_ops = {
395 .debugfs_init = if_sdio_debugfs_init, 395 .debugfs_init = if_sdio_debugfs_init,
396 .debugfs_exit = if_sdio_debugfs_exit, 396 .debugfs_exit = if_sdio_debugfs_exit,
397 .umac_name = "iwmc3200wifi-umac-sdio.bin", 397 .umac_name = "iwmc3200wifi-umac-sdio.bin",
398 .calib_lmac_name = "iwmc3200wifi-lmac-calib-sdio.bin", 398 .calib_lmac_name = "iwmc3200wifi-calib-sdio.bin",
399 .lmac_name = "iwmc3200wifi-lmac-sdio.bin", 399 .lmac_name = "iwmc3200wifi-lmac-sdio.bin",
400}; 400};
401 401
diff --git a/drivers/net/wireless/libertas/11d.c b/drivers/net/wireless/libertas/11d.c
index 4bc46a60ae2f..9a5408e7d94a 100644
--- a/drivers/net/wireless/libertas/11d.c
+++ b/drivers/net/wireless/libertas/11d.c
@@ -207,7 +207,7 @@ static int generate_domain_info_11d(struct parsed_region_chan_11d
207 lbs_deb_11d("nr_subband=%x\n", domaininfo->nr_subband); 207 lbs_deb_11d("nr_subband=%x\n", domaininfo->nr_subband);
208 lbs_deb_hex(LBS_DEB_11D, "domaininfo", (char *)domaininfo, 208 lbs_deb_hex(LBS_DEB_11D, "domaininfo", (char *)domaininfo,
209 COUNTRY_CODE_LEN + 1 + 209 COUNTRY_CODE_LEN + 1 +
210 sizeof(struct ieeetypes_subbandset) * nr_subband); 210 sizeof(struct ieee_subbandset) * nr_subband);
211 return 0; 211 return 0;
212} 212}
213 213
@@ -302,11 +302,9 @@ done:
302 * @param parsed_region_chan pointer to parsed_region_chan_11d 302 * @param parsed_region_chan pointer to parsed_region_chan_11d
303 * @return 0 303 * @return 0
304*/ 304*/
305static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* 305static int parse_domain_info_11d(struct ieee_ie_country_info_full_set *countryinfo,
306 countryinfo,
307 u8 band, 306 u8 band,
308 struct parsed_region_chan_11d * 307 struct parsed_region_chan_11d *parsed_region_chan)
309 parsed_region_chan)
310{ 308{
311 u8 nr_subband, nrchan; 309 u8 nr_subband, nrchan;
312 u8 lastchan, firstchan; 310 u8 lastchan, firstchan;
@@ -331,7 +329,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
331 lbs_deb_hex(LBS_DEB_11D, "countryinfo", (u8 *) countryinfo, 30); 329 lbs_deb_hex(LBS_DEB_11D, "countryinfo", (u8 *) countryinfo, 30);
332 330
333 if ((*(countryinfo->countrycode)) == 0 331 if ((*(countryinfo->countrycode)) == 0
334 || (countryinfo->len <= COUNTRY_CODE_LEN)) { 332 || (countryinfo->header.len <= COUNTRY_CODE_LEN)) {
335 /* No region Info or Wrong region info: treat as No 11D info */ 333 /* No region Info or Wrong region info: treat as No 11D info */
336 goto done; 334 goto done;
337 } 335 }
@@ -349,8 +347,8 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
349 memcpy(parsed_region_chan->countrycode, countryinfo->countrycode, 347 memcpy(parsed_region_chan->countrycode, countryinfo->countrycode,
350 COUNTRY_CODE_LEN); 348 COUNTRY_CODE_LEN);
351 349
352 nr_subband = (countryinfo->len - COUNTRY_CODE_LEN) / 350 nr_subband = (countryinfo->header.len - COUNTRY_CODE_LEN) /
353 sizeof(struct ieeetypes_subbandset); 351 sizeof(struct ieee_subbandset);
354 352
355 for (j = 0, lastchan = 0; j < nr_subband; j++) { 353 for (j = 0, lastchan = 0; j < nr_subband; j++) {
356 354
@@ -502,7 +500,7 @@ int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
502{ 500{
503 struct cmd_ds_802_11d_domain_info *pdomaininfo = 501 struct cmd_ds_802_11d_domain_info *pdomaininfo =
504 &cmd->params.domaininfo; 502 &cmd->params.domaininfo;
505 struct mrvlietypes_domainparamset *domain = &pdomaininfo->domain; 503 struct mrvl_ie_domain_param_set *domain = &pdomaininfo->domain;
506 u8 nr_subband = priv->domainreg.nr_subband; 504 u8 nr_subband = priv->domainreg.nr_subband;
507 505
508 lbs_deb_enter(LBS_DEB_11D); 506 lbs_deb_enter(LBS_DEB_11D);
@@ -524,16 +522,16 @@ int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
524 sizeof(domain->countrycode)); 522 sizeof(domain->countrycode));
525 523
526 domain->header.len = 524 domain->header.len =
527 cpu_to_le16(nr_subband * sizeof(struct ieeetypes_subbandset) + 525 cpu_to_le16(nr_subband * sizeof(struct ieee_subbandset) +
528 sizeof(domain->countrycode)); 526 sizeof(domain->countrycode));
529 527
530 if (nr_subband) { 528 if (nr_subband) {
531 memcpy(domain->subband, priv->domainreg.subband, 529 memcpy(domain->subband, priv->domainreg.subband,
532 nr_subband * sizeof(struct ieeetypes_subbandset)); 530 nr_subband * sizeof(struct ieee_subbandset));
533 531
534 cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) + 532 cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
535 le16_to_cpu(domain->header.len) + 533 le16_to_cpu(domain->header.len) +
536 sizeof(struct mrvlietypesheader) + 534 sizeof(struct mrvl_ie_header) +
537 S_DS_GEN); 535 S_DS_GEN);
538 } else { 536 } else {
539 cmd->size = 537 cmd->size =
@@ -556,7 +554,7 @@ done:
556int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp) 554int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp)
557{ 555{
558 struct cmd_ds_802_11d_domain_info *domaininfo = &resp->params.domaininforesp; 556 struct cmd_ds_802_11d_domain_info *domaininfo = &resp->params.domaininforesp;
559 struct mrvlietypes_domainparamset *domain = &domaininfo->domain; 557 struct mrvl_ie_domain_param_set *domain = &domaininfo->domain;
560 u16 action = le16_to_cpu(domaininfo->action); 558 u16 action = le16_to_cpu(domaininfo->action);
561 s16 ret = 0; 559 s16 ret = 0;
562 u8 nr_subband = 0; 560 u8 nr_subband = 0;
@@ -567,7 +565,7 @@ int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp)
567 (int)le16_to_cpu(resp->size)); 565 (int)le16_to_cpu(resp->size));
568 566
569 nr_subband = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) / 567 nr_subband = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) /
570 sizeof(struct ieeetypes_subbandset); 568 sizeof(struct ieee_subbandset);
571 569
572 lbs_deb_11d("domain info resp: nr_subband %d\n", nr_subband); 570 lbs_deb_11d("domain info resp: nr_subband %d\n", nr_subband);
573 571
diff --git a/drivers/net/wireless/libertas/11d.h b/drivers/net/wireless/libertas/11d.h
index 4f4f47f0f878..fb75d3e321a0 100644
--- a/drivers/net/wireless/libertas/11d.h
+++ b/drivers/net/wireless/libertas/11d.h
@@ -20,35 +20,36 @@
20struct cmd_ds_command; 20struct cmd_ds_command;
21 21
22/** Data structure for Country IE*/ 22/** Data structure for Country IE*/
23struct ieeetypes_subbandset { 23struct ieee_subbandset {
24 u8 firstchan; 24 u8 firstchan;
25 u8 nrchan; 25 u8 nrchan;
26 u8 maxtxpwr; 26 u8 maxtxpwr;
27} __attribute__ ((packed)); 27} __attribute__ ((packed));
28 28
29struct ieeetypes_countryinfoset { 29struct ieee_ie_country_info_set {
30 u8 element_id; 30 struct ieee_ie_header header;
31 u8 len; 31
32 u8 countrycode[COUNTRY_CODE_LEN]; 32 u8 countrycode[COUNTRY_CODE_LEN];
33 struct ieeetypes_subbandset subband[1]; 33 struct ieee_subbandset subband[1];
34}; 34};
35 35
36struct ieeetypes_countryinfofullset { 36struct ieee_ie_country_info_full_set {
37 u8 element_id; 37 struct ieee_ie_header header;
38 u8 len; 38
39 u8 countrycode[COUNTRY_CODE_LEN]; 39 u8 countrycode[COUNTRY_CODE_LEN];
40 struct ieeetypes_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D]; 40 struct ieee_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D];
41} __attribute__ ((packed)); 41} __attribute__ ((packed));
42 42
43struct mrvlietypes_domainparamset { 43struct mrvl_ie_domain_param_set {
44 struct mrvlietypesheader header; 44 struct mrvl_ie_header header;
45
45 u8 countrycode[COUNTRY_CODE_LEN]; 46 u8 countrycode[COUNTRY_CODE_LEN];
46 struct ieeetypes_subbandset subband[1]; 47 struct ieee_subbandset subband[1];
47} __attribute__ ((packed)); 48} __attribute__ ((packed));
48 49
49struct cmd_ds_802_11d_domain_info { 50struct cmd_ds_802_11d_domain_info {
50 __le16 action; 51 __le16 action;
51 struct mrvlietypes_domainparamset domain; 52 struct mrvl_ie_domain_param_set domain;
52} __attribute__ ((packed)); 53} __attribute__ ((packed));
53 54
54/** domain regulatory information */ 55/** domain regulatory information */
@@ -57,7 +58,7 @@ struct lbs_802_11d_domain_reg {
57 u8 countrycode[COUNTRY_CODE_LEN]; 58 u8 countrycode[COUNTRY_CODE_LEN];
58 /** No. of subband*/ 59 /** No. of subband*/
59 u8 nr_subband; 60 u8 nr_subband;
60 struct ieeetypes_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D]; 61 struct ieee_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D];
61}; 62};
62 63
63struct chan_power_11d { 64struct chan_power_11d {
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index a0e440cd8967..b9b374119033 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -12,15 +12,14 @@
12#include "scan.h" 12#include "scan.h"
13#include "cmd.h" 13#include "cmd.h"
14 14
15static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp);
16
17static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) = 15static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) =
18 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 16 { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
19static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) = 17static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) =
20 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 18 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
21 19
22/* The firmware needs certain bits masked out of the beacon-derviced capability 20/* The firmware needs the following bits masked out of the beacon-derived
23 * field when associating/joining to BSSs. 21 * capability field when associating/joining to a BSS:
22 * 9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused)
24 */ 23 */
25#define CAPINFO_MASK (~(0xda00)) 24#define CAPINFO_MASK (~(0xda00))
26 25
@@ -102,6 +101,295 @@ static void lbs_set_basic_rate_flags(u8 *rates, size_t len)
102} 101}
103 102
104 103
104static u8 iw_auth_to_ieee_auth(u8 auth)
105{
106 if (auth == IW_AUTH_ALG_OPEN_SYSTEM)
107 return 0x00;
108 else if (auth == IW_AUTH_ALG_SHARED_KEY)
109 return 0x01;
110 else if (auth == IW_AUTH_ALG_LEAP)
111 return 0x80;
112
113 lbs_deb_join("%s: invalid auth alg 0x%X\n", __func__, auth);
114 return 0;
115}
116
117/**
118 * @brief This function prepares the authenticate command. AUTHENTICATE only
119 * sets the authentication suite for future associations, as the firmware
120 * handles authentication internally during the ASSOCIATE command.
121 *
122 * @param priv A pointer to struct lbs_private structure
123 * @param bssid The peer BSSID with which to authenticate
124 * @param auth The authentication mode to use (from wireless.h)
125 *
126 * @return 0 or -1
127 */
128static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth)
129{
130 struct cmd_ds_802_11_authenticate cmd;
131 int ret = -1;
132 DECLARE_MAC_BUF(mac);
133
134 lbs_deb_enter(LBS_DEB_JOIN);
135
136 cmd.hdr.size = cpu_to_le16(sizeof(cmd));
137 memcpy(cmd.bssid, bssid, ETH_ALEN);
138
139 cmd.authtype = iw_auth_to_ieee_auth(auth);
140
141 lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
142 print_mac(mac, bssid), cmd.authtype);
143
144 ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd);
145
146 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
147 return ret;
148}
149
150
151static int lbs_assoc_post(struct lbs_private *priv,
152 struct cmd_ds_802_11_associate_response *resp)
153{
154 int ret = 0;
155 union iwreq_data wrqu;
156 struct bss_descriptor *bss;
157 u16 status_code;
158
159 lbs_deb_enter(LBS_DEB_ASSOC);
160
161 if (!priv->in_progress_assoc_req) {
162 lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n");
163 ret = -1;
164 goto done;
165 }
166 bss = &priv->in_progress_assoc_req->bss;
167
168 /*
169 * Older FW versions map the IEEE 802.11 Status Code in the association
170 * response to the following values returned in resp->statuscode:
171 *
172 * IEEE Status Code Marvell Status Code
173 * 0 -> 0x0000 ASSOC_RESULT_SUCCESS
174 * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
175 * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
176 * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
177 * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
178 * others -> 0x0003 ASSOC_RESULT_REFUSED
179 *
180 * Other response codes:
181 * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
182 * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
183 * association response from the AP)
184 */
185
186 status_code = le16_to_cpu(resp->statuscode);
187 if (priv->fwrelease < 0x09000000) {
188 switch (status_code) {
189 case 0x00:
190 break;
191 case 0x01:
192 lbs_deb_assoc("ASSOC_RESP: invalid parameters\n");
193 break;
194 case 0x02:
195 lbs_deb_assoc("ASSOC_RESP: internal timer "
196 "expired while waiting for the AP\n");
197 break;
198 case 0x03:
199 lbs_deb_assoc("ASSOC_RESP: association "
200 "refused by AP\n");
201 break;
202 case 0x04:
203 lbs_deb_assoc("ASSOC_RESP: authentication "
204 "refused by AP\n");
205 break;
206 default:
207 lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x "
208 " unknown\n", status_code);
209 break;
210 }
211 } else {
212 /* v9+ returns the AP's association response */
213 lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x\n", status_code);
214 }
215
216 if (status_code) {
217 lbs_mac_event_disconnected(priv);
218 ret = -1;
219 goto done;
220 }
221
222 lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP",
223 (void *) (resp + sizeof (resp->hdr)),
224 le16_to_cpu(resp->hdr.size) - sizeof (resp->hdr));
225
226 /* Send a Media Connected event, according to the Spec */
227 priv->connect_status = LBS_CONNECTED;
228
229 /* Update current SSID and BSSID */
230 memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
231 priv->curbssparams.ssid_len = bss->ssid_len;
232 memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
233
234 priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
235 priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
236
237 memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
238 memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
239 priv->nextSNRNF = 0;
240 priv->numSNRNF = 0;
241
242 netif_carrier_on(priv->dev);
243 if (!priv->tx_pending_len)
244 netif_wake_queue(priv->dev);
245
246 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
247 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
248 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
249
250done:
251 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
252 return ret;
253}
254
255/**
256 * @brief This function prepares an association-class command.
257 *
258 * @param priv A pointer to struct lbs_private structure
259 * @param assoc_req The association request describing the BSS to associate
260 * or reassociate with
261 * @param command The actual command, either CMD_802_11_ASSOCIATE or
262 * CMD_802_11_REASSOCIATE
263 *
264 * @return 0 or -1
265 */
266static int lbs_associate(struct lbs_private *priv,
267 struct assoc_request *assoc_req,
268 u16 command)
269{
270 struct cmd_ds_802_11_associate cmd;
271 int ret = 0;
272 struct bss_descriptor *bss = &assoc_req->bss;
273 u8 *pos = &(cmd.iebuf[0]);
274 u16 tmpcap, tmplen, tmpauth;
275 struct mrvl_ie_ssid_param_set *ssid;
276 struct mrvl_ie_ds_param_set *ds;
277 struct mrvl_ie_cf_param_set *cf;
278 struct mrvl_ie_rates_param_set *rates;
279 struct mrvl_ie_rsn_param_set *rsn;
280 struct mrvl_ie_auth_type *auth;
281
282 lbs_deb_enter(LBS_DEB_ASSOC);
283
284 BUG_ON((command != CMD_802_11_ASSOCIATE) &&
285 (command != CMD_802_11_REASSOCIATE));
286
287 memset(&cmd, 0, sizeof(cmd));
288 cmd.hdr.command = cpu_to_le16(command);
289
290 /* Fill in static fields */
291 memcpy(cmd.bssid, bss->bssid, ETH_ALEN);
292 cmd.listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
293
294 /* Capability info */
295 tmpcap = (bss->capability & CAPINFO_MASK);
296 if (bss->mode == IW_MODE_INFRA)
297 tmpcap |= WLAN_CAPABILITY_ESS;
298 cmd.capability = cpu_to_le16(tmpcap);
299 lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap);
300
301 /* SSID */
302 ssid = (struct mrvl_ie_ssid_param_set *) pos;
303 ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
304 tmplen = bss->ssid_len;
305 ssid->header.len = cpu_to_le16(tmplen);
306 memcpy(ssid->ssid, bss->ssid, tmplen);
307 pos += sizeof(ssid->header) + tmplen;
308
309 ds = (struct mrvl_ie_ds_param_set *) pos;
310 ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
311 ds->header.len = cpu_to_le16(1);
312 ds->channel = bss->phy.ds.channel;
313 pos += sizeof(ds->header) + 1;
314
315 cf = (struct mrvl_ie_cf_param_set *) pos;
316 cf->header.type = cpu_to_le16(TLV_TYPE_CF);
317 tmplen = sizeof(*cf) - sizeof (cf->header);
318 cf->header.len = cpu_to_le16(tmplen);
319 /* IE payload should be zeroed, firmware fills it in for us */
320 pos += sizeof(*cf);
321
322 rates = (struct mrvl_ie_rates_param_set *) pos;
323 rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
324 memcpy(&rates->rates, &bss->rates, MAX_RATES);
325 tmplen = MAX_RATES;
326 if (get_common_rates(priv, rates->rates, &tmplen)) {
327 ret = -1;
328 goto done;
329 }
330 pos += sizeof(rates->header) + tmplen;
331 rates->header.len = cpu_to_le16(tmplen);
332 lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen);
333
334 /* Copy the infra. association rates into Current BSS state structure */
335 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
336 memcpy(&priv->curbssparams.rates, &rates->rates, tmplen);
337
338 /* Set MSB on basic rates as the firmware requires, but _after_
339 * copying to current bss rates.
340 */
341 lbs_set_basic_rate_flags(rates->rates, tmplen);
342
343 /* Firmware v9+ indicate authentication suites as a TLV */
344 if (priv->fwrelease >= 0x09000000) {
345 DECLARE_MAC_BUF(mac);
346
347 auth = (struct mrvl_ie_auth_type *) pos;
348 auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
349 auth->header.len = cpu_to_le16(2);
350 tmpauth = iw_auth_to_ieee_auth(priv->secinfo.auth_mode);
351 auth->auth = cpu_to_le16(tmpauth);
352 pos += sizeof(auth->header) + 2;
353
354 lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
355 print_mac(mac, bss->bssid), priv->secinfo.auth_mode);
356 }
357
358 /* WPA/WPA2 IEs */
359 if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
360 rsn = (struct mrvl_ie_rsn_param_set *) pos;
361 /* WPA_IE or WPA2_IE */
362 rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]);
363 tmplen = (u16) assoc_req->wpa_ie[1];
364 rsn->header.len = cpu_to_le16(tmplen);
365 memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen);
366 lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: WPA/RSN IE", (u8 *) rsn,
367 sizeof(rsn->header) + tmplen);
368 pos += sizeof(rsn->header) + tmplen;
369 }
370
371 cmd.hdr.size = cpu_to_le16((sizeof(cmd) - sizeof(cmd.iebuf)) +
372 (u16)(pos - (u8 *) &cmd.iebuf));
373
374 /* update curbssparams */
375 priv->curbssparams.channel = bss->phy.ds.channel;
376
377 if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
378 ret = -1;
379 goto done;
380 }
381
382 ret = lbs_cmd_with_response(priv, command, &cmd);
383 if (ret == 0) {
384 ret = lbs_assoc_post(priv,
385 (struct cmd_ds_802_11_associate_response *) &cmd);
386 }
387
388done:
389 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
390 return ret;
391}
392
105/** 393/**
106 * @brief Associate to a specific BSS discovered in a scan 394 * @brief Associate to a specific BSS discovered in a scan
107 * 395 *
@@ -110,7 +398,7 @@ static void lbs_set_basic_rate_flags(u8 *rates, size_t len)
110 * 398 *
111 * @return 0-success, otherwise fail 399 * @return 0-success, otherwise fail
112 */ 400 */
113static int lbs_associate(struct lbs_private *priv, 401static int lbs_try_associate(struct lbs_private *priv,
114 struct assoc_request *assoc_req) 402 struct assoc_request *assoc_req)
115{ 403{
116 int ret; 404 int ret;
@@ -118,11 +406,15 @@ static int lbs_associate(struct lbs_private *priv,
118 406
119 lbs_deb_enter(LBS_DEB_ASSOC); 407 lbs_deb_enter(LBS_DEB_ASSOC);
120 408
121 ret = lbs_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE, 409 /* FW v9 and higher indicate authentication suites as a TLV in the
122 0, CMD_OPTION_WAITFORRSP, 410 * association command, not as a separate authentication command.
123 0, assoc_req->bss.bssid); 411 */
124 if (ret) 412 if (priv->fwrelease < 0x09000000) {
125 goto out; 413 ret = lbs_set_authentication(priv, assoc_req->bss.bssid,
414 priv->secinfo.auth_mode);
415 if (ret)
416 goto out;
417 }
126 418
127 /* Use short preamble only when both the BSS and firmware support it */ 419 /* Use short preamble only when both the BSS and firmware support it */
128 if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) && 420 if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
@@ -133,14 +425,78 @@ static int lbs_associate(struct lbs_private *priv,
133 if (ret) 425 if (ret)
134 goto out; 426 goto out;
135 427
136 ret = lbs_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE, 428 ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE);
137 0, CMD_OPTION_WAITFORRSP, 0, assoc_req);
138 429
139out: 430out:
140 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 431 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
141 return ret; 432 return ret;
142} 433}
143 434
435static int lbs_adhoc_post(struct lbs_private *priv,
436 struct cmd_ds_802_11_ad_hoc_result *resp)
437{
438 int ret = 0;
439 u16 command = le16_to_cpu(resp->hdr.command);
440 u16 result = le16_to_cpu(resp->hdr.result);
441 union iwreq_data wrqu;
442 struct bss_descriptor *bss;
443 DECLARE_SSID_BUF(ssid);
444
445 lbs_deb_enter(LBS_DEB_JOIN);
446
447 if (!priv->in_progress_assoc_req) {
448 lbs_deb_join("ADHOC_RESP: no in-progress association "
449 "request\n");
450 ret = -1;
451 goto done;
452 }
453 bss = &priv->in_progress_assoc_req->bss;
454
455 /*
456 * Join result code 0 --> SUCCESS
457 */
458 if (result) {
459 lbs_deb_join("ADHOC_RESP: failed (result 0x%X)\n", result);
460 if (priv->connect_status == LBS_CONNECTED)
461 lbs_mac_event_disconnected(priv);
462 ret = -1;
463 goto done;
464 }
465
466 /* Send a Media Connected event, according to the Spec */
467 priv->connect_status = LBS_CONNECTED;
468
469 if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
470 /* Update the created network descriptor with the new BSSID */
471 memcpy(bss->bssid, resp->bssid, ETH_ALEN);
472 }
473
474 /* Set the BSSID from the joined/started descriptor */
475 memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
476
477 /* Set the new SSID to current SSID */
478 memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
479 priv->curbssparams.ssid_len = bss->ssid_len;
480
481 netif_carrier_on(priv->dev);
482 if (!priv->tx_pending_len)
483 netif_wake_queue(priv->dev);
484
485 memset(&wrqu, 0, sizeof(wrqu));
486 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
487 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
488 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
489
490 lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n",
491 print_ssid(ssid, bss->ssid, bss->ssid_len),
492 priv->curbssparams.bssid,
493 priv->curbssparams.channel);
494
495done:
496 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
497 return ret;
498}
499
144/** 500/**
145 * @brief Join an adhoc network found in a previous scan 501 * @brief Join an adhoc network found in a previous scan
146 * 502 *
@@ -219,11 +575,10 @@ static int lbs_adhoc_join(struct lbs_private *priv,
219 memcpy(&cmd.bss.bssid, &bss->bssid, ETH_ALEN); 575 memcpy(&cmd.bss.bssid, &bss->bssid, ETH_ALEN);
220 memcpy(&cmd.bss.ssid, &bss->ssid, bss->ssid_len); 576 memcpy(&cmd.bss.ssid, &bss->ssid, bss->ssid_len);
221 577
222 memcpy(&cmd.bss.phyparamset, &bss->phyparamset, 578 memcpy(&cmd.bss.ds, &bss->phy.ds, sizeof(struct ieee_ie_ds_param_set));
223 sizeof(union ieeetypes_phyparamset));
224 579
225 memcpy(&cmd.bss.ssparamset, &bss->ssparamset, 580 memcpy(&cmd.bss.ibss, &bss->ss.ibss,
226 sizeof(union IEEEtypes_ssparamset)); 581 sizeof(struct ieee_ie_ibss_param_set));
227 582
228 cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK); 583 cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK);
229 lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n", 584 lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
@@ -260,7 +615,7 @@ static int lbs_adhoc_join(struct lbs_private *priv,
260 */ 615 */
261 lbs_set_basic_rate_flags(cmd.bss.rates, ratesize); 616 lbs_set_basic_rate_flags(cmd.bss.rates, ratesize);
262 617
263 cmd.bss.ssparamset.ibssparamset.atimwindow = cpu_to_le16(bss->atimwindow); 618 cmd.bss.ibss.atimwindow = bss->atimwindow;
264 619
265 if (assoc_req->secinfo.wep_enabled) { 620 if (assoc_req->secinfo.wep_enabled) {
266 u16 tmp = le16_to_cpu(cmd.bss.capability); 621 u16 tmp = le16_to_cpu(cmd.bss.capability);
@@ -287,8 +642,10 @@ static int lbs_adhoc_join(struct lbs_private *priv,
287 } 642 }
288 643
289 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd); 644 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd);
290 if (ret == 0) 645 if (ret == 0) {
291 ret = lbs_adhoc_post(priv, (struct cmd_header *) &cmd); 646 ret = lbs_adhoc_post(priv,
647 (struct cmd_ds_802_11_ad_hoc_result *)&cmd);
648 }
292 649
293out: 650out:
294 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 651 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -343,22 +700,24 @@ static int lbs_adhoc_start(struct lbs_private *priv,
343 WARN_ON(!assoc_req->channel); 700 WARN_ON(!assoc_req->channel);
344 701
345 /* set Physical parameter set */ 702 /* set Physical parameter set */
346 cmd.phyparamset.dsparamset.elementid = WLAN_EID_DS_PARAMS; 703 cmd.ds.header.id = WLAN_EID_DS_PARAMS;
347 cmd.phyparamset.dsparamset.len = 1; 704 cmd.ds.header.len = 1;
348 cmd.phyparamset.dsparamset.currentchan = assoc_req->channel; 705 cmd.ds.channel = assoc_req->channel;
349 706
350 /* set IBSS parameter set */ 707 /* set IBSS parameter set */
351 cmd.ssparamset.ibssparamset.elementid = WLAN_EID_IBSS_PARAMS; 708 cmd.ibss.header.id = WLAN_EID_IBSS_PARAMS;
352 cmd.ssparamset.ibssparamset.len = 2; 709 cmd.ibss.header.len = 2;
353 cmd.ssparamset.ibssparamset.atimwindow = 0; 710 cmd.ibss.atimwindow = cpu_to_le16(0);
354 711
355 /* set capability info */ 712 /* set capability info */
356 tmpcap = WLAN_CAPABILITY_IBSS; 713 tmpcap = WLAN_CAPABILITY_IBSS;
357 if (assoc_req->secinfo.wep_enabled) { 714 if (assoc_req->secinfo.wep_enabled ||
358 lbs_deb_join("ADHOC_START: WEP enabled, setting privacy on\n"); 715 assoc_req->secinfo.WPAenabled ||
716 assoc_req->secinfo.WPA2enabled) {
717 lbs_deb_join("ADHOC_START: WEP/WPA enabled, privacy on\n");
359 tmpcap |= WLAN_CAPABILITY_PRIVACY; 718 tmpcap |= WLAN_CAPABILITY_PRIVACY;
360 } else 719 } else
361 lbs_deb_join("ADHOC_START: WEP disabled, setting privacy off\n"); 720 lbs_deb_join("ADHOC_START: WEP disabled, privacy off\n");
362 721
363 cmd.capability = cpu_to_le16(tmpcap); 722 cmd.capability = cpu_to_le16(tmpcap);
364 723
@@ -395,7 +754,8 @@ static int lbs_adhoc_start(struct lbs_private *priv,
395 754
396 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd); 755 ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd);
397 if (ret == 0) 756 if (ret == 0)
398 ret = lbs_adhoc_post(priv, (struct cmd_header *) &cmd); 757 ret = lbs_adhoc_post(priv,
758 (struct cmd_ds_802_11_ad_hoc_result *)&cmd);
399 759
400out: 760out:
401 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); 761 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -720,7 +1080,7 @@ static int assoc_helper_essid(struct lbs_private *priv,
720 assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel); 1080 assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel);
721 if (bss != NULL) { 1081 if (bss != NULL) {
722 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); 1082 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
723 ret = lbs_associate(priv, assoc_req); 1083 ret = lbs_try_associate(priv, assoc_req);
724 } else { 1084 } else {
725 lbs_deb_assoc("SSID not found; cannot associate\n"); 1085 lbs_deb_assoc("SSID not found; cannot associate\n");
726 } 1086 }
@@ -772,8 +1132,9 @@ static int assoc_helper_bssid(struct lbs_private *priv,
772 1132
773 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); 1133 memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
774 if (assoc_req->mode == IW_MODE_INFRA) { 1134 if (assoc_req->mode == IW_MODE_INFRA) {
775 ret = lbs_associate(priv, assoc_req); 1135 ret = lbs_try_associate(priv, assoc_req);
776 lbs_deb_assoc("ASSOC: lbs_associate(bssid) returned %d\n", ret); 1136 lbs_deb_assoc("ASSOC: lbs_try_associate(bssid) returned %d\n",
1137 ret);
777 } else if (assoc_req->mode == IW_MODE_ADHOC) { 1138 } else if (assoc_req->mode == IW_MODE_ADHOC) {
778 lbs_adhoc_join(priv, assoc_req); 1139 lbs_adhoc_join(priv, assoc_req);
779 } 1140 }
@@ -1467,57 +1828,6 @@ struct assoc_request *lbs_get_association_request(struct lbs_private *priv)
1467 1828
1468 1829
1469/** 1830/**
1470 * @brief This function prepares command of authenticate.
1471 *
1472 * @param priv A pointer to struct lbs_private structure
1473 * @param cmd A pointer to cmd_ds_command structure
1474 * @param pdata_buf Void cast of pointer to a BSSID to authenticate with
1475 *
1476 * @return 0 or -1
1477 */
1478int lbs_cmd_80211_authenticate(struct lbs_private *priv,
1479 struct cmd_ds_command *cmd,
1480 void *pdata_buf)
1481{
1482 struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth;
1483 int ret = -1;
1484 u8 *bssid = pdata_buf;
1485
1486 lbs_deb_enter(LBS_DEB_JOIN);
1487
1488 cmd->command = cpu_to_le16(CMD_802_11_AUTHENTICATE);
1489 cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate)
1490 + S_DS_GEN);
1491
1492 /* translate auth mode to 802.11 defined wire value */
1493 switch (priv->secinfo.auth_mode) {
1494 case IW_AUTH_ALG_OPEN_SYSTEM:
1495 pauthenticate->authtype = 0x00;
1496 break;
1497 case IW_AUTH_ALG_SHARED_KEY:
1498 pauthenticate->authtype = 0x01;
1499 break;
1500 case IW_AUTH_ALG_LEAP:
1501 pauthenticate->authtype = 0x80;
1502 break;
1503 default:
1504 lbs_deb_join("AUTH_CMD: invalid auth alg 0x%X\n",
1505 priv->secinfo.auth_mode);
1506 goto out;
1507 }
1508
1509 memcpy(pauthenticate->macaddr, bssid, ETH_ALEN);
1510
1511 lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n",
1512 bssid, pauthenticate->authtype);
1513 ret = 0;
1514
1515out:
1516 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
1517 return ret;
1518}
1519
1520/**
1521 * @brief Deauthenticate from a specific BSS 1831 * @brief Deauthenticate from a specific BSS
1522 * 1832 *
1523 * @param priv A pointer to struct lbs_private structure 1833 * @param priv A pointer to struct lbs_private structure
@@ -1550,285 +1860,3 @@ int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, u8 bssid[ETH_ALEN],
1550 return ret; 1860 return ret;
1551} 1861}
1552 1862
1553int lbs_cmd_80211_associate(struct lbs_private *priv,
1554 struct cmd_ds_command *cmd, void *pdata_buf)
1555{
1556 struct cmd_ds_802_11_associate *passo = &cmd->params.associate;
1557 int ret = 0;
1558 struct assoc_request *assoc_req = pdata_buf;
1559 struct bss_descriptor *bss = &assoc_req->bss;
1560 u8 *pos;
1561 u16 tmpcap, tmplen;
1562 struct mrvlietypes_ssidparamset *ssid;
1563 struct mrvlietypes_phyparamset *phy;
1564 struct mrvlietypes_ssparamset *ss;
1565 struct mrvlietypes_ratesparamset *rates;
1566 struct mrvlietypes_rsnparamset *rsn;
1567
1568 lbs_deb_enter(LBS_DEB_ASSOC);
1569
1570 pos = (u8 *) passo;
1571
1572 if (!priv) {
1573 ret = -1;
1574 goto done;
1575 }
1576
1577 cmd->command = cpu_to_le16(CMD_802_11_ASSOCIATE);
1578
1579 memcpy(passo->peerstaaddr, bss->bssid, sizeof(passo->peerstaaddr));
1580 pos += sizeof(passo->peerstaaddr);
1581
1582 /* set the listen interval */
1583 passo->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
1584
1585 pos += sizeof(passo->capability);
1586 pos += sizeof(passo->listeninterval);
1587 pos += sizeof(passo->bcnperiod);
1588 pos += sizeof(passo->dtimperiod);
1589
1590 ssid = (struct mrvlietypes_ssidparamset *) pos;
1591 ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
1592 tmplen = bss->ssid_len;
1593 ssid->header.len = cpu_to_le16(tmplen);
1594 memcpy(ssid->ssid, bss->ssid, tmplen);
1595 pos += sizeof(ssid->header) + tmplen;
1596
1597 phy = (struct mrvlietypes_phyparamset *) pos;
1598 phy->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
1599 tmplen = sizeof(phy->fh_ds.dsparamset);
1600 phy->header.len = cpu_to_le16(tmplen);
1601 memcpy(&phy->fh_ds.dsparamset,
1602 &bss->phyparamset.dsparamset.currentchan,
1603 tmplen);
1604 pos += sizeof(phy->header) + tmplen;
1605
1606 ss = (struct mrvlietypes_ssparamset *) pos;
1607 ss->header.type = cpu_to_le16(TLV_TYPE_CF);
1608 tmplen = sizeof(ss->cf_ibss.cfparamset);
1609 ss->header.len = cpu_to_le16(tmplen);
1610 pos += sizeof(ss->header) + tmplen;
1611
1612 rates = (struct mrvlietypes_ratesparamset *) pos;
1613 rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
1614 memcpy(&rates->rates, &bss->rates, MAX_RATES);
1615 tmplen = MAX_RATES;
1616 if (get_common_rates(priv, rates->rates, &tmplen)) {
1617 ret = -1;
1618 goto done;
1619 }
1620 pos += sizeof(rates->header) + tmplen;
1621 rates->header.len = cpu_to_le16(tmplen);
1622 lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen);
1623
1624 /* Copy the infra. association rates into Current BSS state structure */
1625 memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
1626 memcpy(&priv->curbssparams.rates, &rates->rates, tmplen);
1627
1628 /* Set MSB on basic rates as the firmware requires, but _after_
1629 * copying to current bss rates.
1630 */
1631 lbs_set_basic_rate_flags(rates->rates, tmplen);
1632
1633 if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
1634 rsn = (struct mrvlietypes_rsnparamset *) pos;
1635 /* WPA_IE or WPA2_IE */
1636 rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]);
1637 tmplen = (u16) assoc_req->wpa_ie[1];
1638 rsn->header.len = cpu_to_le16(tmplen);
1639 memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen);
1640 lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: RSN IE", (u8 *) rsn,
1641 sizeof(rsn->header) + tmplen);
1642 pos += sizeof(rsn->header) + tmplen;
1643 }
1644
1645 /* update curbssparams */
1646 priv->curbssparams.channel = bss->phyparamset.dsparamset.currentchan;
1647
1648 if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
1649 ret = -1;
1650 goto done;
1651 }
1652
1653 cmd->size = cpu_to_le16((u16) (pos - (u8 *) passo) + S_DS_GEN);
1654
1655 /* set the capability info */
1656 tmpcap = (bss->capability & CAPINFO_MASK);
1657 if (bss->mode == IW_MODE_INFRA)
1658 tmpcap |= WLAN_CAPABILITY_ESS;
1659 passo->capability = cpu_to_le16(tmpcap);
1660 lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap);
1661
1662done:
1663 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1664 return ret;
1665}
1666
1667int lbs_ret_80211_associate(struct lbs_private *priv,
1668 struct cmd_ds_command *resp)
1669{
1670 int ret = 0;
1671 union iwreq_data wrqu;
1672 struct ieeetypes_assocrsp *passocrsp;
1673 struct bss_descriptor *bss;
1674 u16 status_code;
1675
1676 lbs_deb_enter(LBS_DEB_ASSOC);
1677
1678 if (!priv->in_progress_assoc_req) {
1679 lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n");
1680 ret = -1;
1681 goto done;
1682 }
1683 bss = &priv->in_progress_assoc_req->bss;
1684
1685 passocrsp = (struct ieeetypes_assocrsp *) &resp->params;
1686
1687 /*
1688 * Older FW versions map the IEEE 802.11 Status Code in the association
1689 * response to the following values returned in passocrsp->statuscode:
1690 *
1691 * IEEE Status Code Marvell Status Code
1692 * 0 -> 0x0000 ASSOC_RESULT_SUCCESS
1693 * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1694 * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1695 * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1696 * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED
1697 * others -> 0x0003 ASSOC_RESULT_REFUSED
1698 *
1699 * Other response codes:
1700 * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
1701 * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
1702 * association response from the AP)
1703 */
1704
1705 status_code = le16_to_cpu(passocrsp->statuscode);
1706 switch (status_code) {
1707 case 0x00:
1708 break;
1709 case 0x01:
1710 lbs_deb_assoc("ASSOC_RESP: invalid parameters\n");
1711 break;
1712 case 0x02:
1713 lbs_deb_assoc("ASSOC_RESP: internal timer "
1714 "expired while waiting for the AP\n");
1715 break;
1716 case 0x03:
1717 lbs_deb_assoc("ASSOC_RESP: association "
1718 "refused by AP\n");
1719 break;
1720 case 0x04:
1721 lbs_deb_assoc("ASSOC_RESP: authentication "
1722 "refused by AP\n");
1723 break;
1724 default:
1725 lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x "
1726 " unknown\n", status_code);
1727 break;
1728 }
1729
1730 if (status_code) {
1731 lbs_mac_event_disconnected(priv);
1732 ret = -1;
1733 goto done;
1734 }
1735
1736 lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP", (void *)&resp->params,
1737 le16_to_cpu(resp->size) - S_DS_GEN);
1738
1739 /* Send a Media Connected event, according to the Spec */
1740 priv->connect_status = LBS_CONNECTED;
1741
1742 /* Update current SSID and BSSID */
1743 memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
1744 priv->curbssparams.ssid_len = bss->ssid_len;
1745 memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
1746
1747 priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
1748 priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
1749
1750 memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
1751 memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
1752 priv->nextSNRNF = 0;
1753 priv->numSNRNF = 0;
1754
1755 netif_carrier_on(priv->dev);
1756 if (!priv->tx_pending_len)
1757 netif_wake_queue(priv->dev);
1758
1759 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
1760 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1761 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1762
1763done:
1764 lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
1765 return ret;
1766}
1767
1768static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp)
1769{
1770 int ret = 0;
1771 u16 command = le16_to_cpu(resp->command);
1772 u16 result = le16_to_cpu(resp->result);
1773 struct cmd_ds_802_11_ad_hoc_result *adhoc_resp;
1774 union iwreq_data wrqu;
1775 struct bss_descriptor *bss;
1776 DECLARE_SSID_BUF(ssid);
1777
1778 lbs_deb_enter(LBS_DEB_JOIN);
1779
1780 adhoc_resp = (struct cmd_ds_802_11_ad_hoc_result *) resp;
1781
1782 if (!priv->in_progress_assoc_req) {
1783 lbs_deb_join("ADHOC_RESP: no in-progress association "
1784 "request\n");
1785 ret = -1;
1786 goto done;
1787 }
1788 bss = &priv->in_progress_assoc_req->bss;
1789
1790 /*
1791 * Join result code 0 --> SUCCESS
1792 */
1793 if (result) {
1794 lbs_deb_join("ADHOC_RESP: failed (result 0x%X)\n", result);
1795 if (priv->connect_status == LBS_CONNECTED)
1796 lbs_mac_event_disconnected(priv);
1797 ret = -1;
1798 goto done;
1799 }
1800
1801 /* Send a Media Connected event, according to the Spec */
1802 priv->connect_status = LBS_CONNECTED;
1803
1804 if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
1805 /* Update the created network descriptor with the new BSSID */
1806 memcpy(bss->bssid, adhoc_resp->bssid, ETH_ALEN);
1807 }
1808
1809 /* Set the BSSID from the joined/started descriptor */
1810 memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
1811
1812 /* Set the new SSID to current SSID */
1813 memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
1814 priv->curbssparams.ssid_len = bss->ssid_len;
1815
1816 netif_carrier_on(priv->dev);
1817 if (!priv->tx_pending_len)
1818 netif_wake_queue(priv->dev);
1819
1820 memset(&wrqu, 0, sizeof(wrqu));
1821 memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
1822 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1823 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1824
1825 lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n",
1826 print_ssid(ssid, bss->ssid, bss->ssid_len),
1827 priv->curbssparams.bssid,
1828 priv->curbssparams.channel);
1829
1830done:
1831 lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
1832 return ret;
1833}
1834
diff --git a/drivers/net/wireless/libertas/assoc.h b/drivers/net/wireless/libertas/assoc.h
index 8b7336dd02a3..6e765e9f91a3 100644
--- a/drivers/net/wireless/libertas/assoc.h
+++ b/drivers/net/wireless/libertas/assoc.h
@@ -8,22 +8,9 @@
8void lbs_association_worker(struct work_struct *work); 8void lbs_association_worker(struct work_struct *work);
9struct assoc_request *lbs_get_association_request(struct lbs_private *priv); 9struct assoc_request *lbs_get_association_request(struct lbs_private *priv);
10 10
11struct cmd_ds_command;
12int lbs_cmd_80211_authenticate(struct lbs_private *priv,
13 struct cmd_ds_command *cmd,
14 void *pdata_buf);
15
16int lbs_adhoc_stop(struct lbs_private *priv); 11int lbs_adhoc_stop(struct lbs_private *priv);
17 12
18int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, 13int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
19 u8 bssid[ETH_ALEN], u16 reason); 14 u8 bssid[ETH_ALEN], u16 reason);
20int lbs_cmd_80211_associate(struct lbs_private *priv,
21 struct cmd_ds_command *cmd,
22 void *pdata_buf);
23
24int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
25 struct cmd_ds_command *resp);
26int lbs_ret_80211_associate(struct lbs_private *priv,
27 struct cmd_ds_command *resp);
28 15
29#endif /* _LBS_ASSOC_H */ 16#endif /* _LBS_ASSOC_H */
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index c455b9abbfc0..01db705a38ec 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1220,8 +1220,7 @@ static void lbs_submit_command(struct lbs_private *priv,
1220 command = le16_to_cpu(cmd->command); 1220 command = le16_to_cpu(cmd->command);
1221 1221
1222 /* These commands take longer */ 1222 /* These commands take longer */
1223 if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE || 1223 if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE)
1224 command == CMD_802_11_AUTHENTICATE)
1225 timeo = 5 * HZ; 1224 timeo = 5 * HZ;
1226 1225
1227 lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n", 1226 lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n",
@@ -1415,15 +1414,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1415 ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action); 1414 ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action);
1416 break; 1415 break;
1417 1416
1418 case CMD_802_11_ASSOCIATE:
1419 case CMD_802_11_REASSOCIATE:
1420 ret = lbs_cmd_80211_associate(priv, cmdptr, pdata_buf);
1421 break;
1422
1423 case CMD_802_11_AUTHENTICATE:
1424 ret = lbs_cmd_80211_authenticate(priv, cmdptr, pdata_buf);
1425 break;
1426
1427 case CMD_MAC_REG_ACCESS: 1417 case CMD_MAC_REG_ACCESS:
1428 case CMD_BBP_REG_ACCESS: 1418 case CMD_BBP_REG_ACCESS:
1429 case CMD_RF_REG_ACCESS: 1419 case CMD_RF_REG_ACCESS:
@@ -1470,8 +1460,8 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
1470 break; 1460 break;
1471 case CMD_802_11_LED_GPIO_CTRL: 1461 case CMD_802_11_LED_GPIO_CTRL:
1472 { 1462 {
1473 struct mrvlietypes_ledgpio *gpio = 1463 struct mrvl_ie_ledgpio *gpio =
1474 (struct mrvlietypes_ledgpio*) 1464 (struct mrvl_ie_ledgpio*)
1475 cmdptr->params.ledgpio.data; 1465 cmdptr->params.ledgpio.data;
1476 1466
1477 memmove(&cmdptr->params.ledgpio, 1467 memmove(&cmdptr->params.ledgpio,
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index bcf2a9756fb6..c42d3faa2660 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -5,7 +5,7 @@
5#include <linux/delay.h> 5#include <linux/delay.h>
6#include <linux/if_arp.h> 6#include <linux/if_arp.h>
7#include <linux/netdevice.h> 7#include <linux/netdevice.h>
8 8#include <asm/unaligned.h>
9#include <net/iw_handler.h> 9#include <net/iw_handler.h>
10 10
11#include "host.h" 11#include "host.h"
@@ -154,11 +154,11 @@ static int lbs_ret_802_11_rssi(struct lbs_private *priv,
154 lbs_deb_enter(LBS_DEB_CMD); 154 lbs_deb_enter(LBS_DEB_CMD);
155 155
156 /* store the non average value */ 156 /* store the non average value */
157 priv->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR); 157 priv->SNR[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->SNR);
158 priv->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor); 158 priv->NF[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->noisefloor);
159 159
160 priv->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR); 160 priv->SNR[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgSNR);
161 priv->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor); 161 priv->NF[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgnoisefloor);
162 162
163 priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = 163 priv->RSSI[TYPE_BEACON][TYPE_NOAVG] =
164 CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG], 164 CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
@@ -210,12 +210,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
210 ret = lbs_ret_reg_access(priv, respcmd, resp); 210 ret = lbs_ret_reg_access(priv, respcmd, resp);
211 break; 211 break;
212 212
213 case CMD_RET_802_11_ASSOCIATE:
214 case CMD_RET(CMD_802_11_ASSOCIATE):
215 case CMD_RET(CMD_802_11_REASSOCIATE):
216 ret = lbs_ret_80211_associate(priv, resp);
217 break;
218
219 case CMD_RET(CMD_802_11_SET_AFC): 213 case CMD_RET(CMD_802_11_SET_AFC):
220 case CMD_RET(CMD_802_11_GET_AFC): 214 case CMD_RET(CMD_802_11_GET_AFC):
221 spin_lock_irqsave(&priv->driver_lock, flags); 215 spin_lock_irqsave(&priv->driver_lock, flags);
@@ -225,7 +219,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
225 219
226 break; 220 break;
227 221
228 case CMD_RET(CMD_802_11_AUTHENTICATE):
229 case CMD_RET(CMD_802_11_BEACON_STOP): 222 case CMD_RET(CMD_802_11_BEACON_STOP):
230 break; 223 break;
231 224
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index 50e28a0cdfee..811ffc3ef414 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -183,12 +183,12 @@ out_unlock:
183 */ 183 */
184static void *lbs_tlv_find(uint16_t tlv_type, const uint8_t *tlv, uint16_t size) 184static void *lbs_tlv_find(uint16_t tlv_type, const uint8_t *tlv, uint16_t size)
185{ 185{
186 struct mrvlietypesheader *tlv_h; 186 struct mrvl_ie_header *tlv_h;
187 uint16_t length; 187 uint16_t length;
188 ssize_t pos = 0; 188 ssize_t pos = 0;
189 189
190 while (pos < size) { 190 while (pos < size) {
191 tlv_h = (struct mrvlietypesheader *) tlv; 191 tlv_h = (struct mrvl_ie_header *) tlv;
192 if (!tlv_h->len) 192 if (!tlv_h->len)
193 return NULL; 193 return NULL;
194 if (tlv_h->type == cpu_to_le16(tlv_type)) 194 if (tlv_h->type == cpu_to_le16(tlv_type))
@@ -206,7 +206,7 @@ static ssize_t lbs_threshold_read(uint16_t tlv_type, uint16_t event_mask,
206 size_t count, loff_t *ppos) 206 size_t count, loff_t *ppos)
207{ 207{
208 struct cmd_ds_802_11_subscribe_event *subscribed; 208 struct cmd_ds_802_11_subscribe_event *subscribed;
209 struct mrvlietypes_thresholds *got; 209 struct mrvl_ie_thresholds *got;
210 struct lbs_private *priv = file->private_data; 210 struct lbs_private *priv = file->private_data;
211 ssize_t ret = 0; 211 ssize_t ret = 0;
212 size_t pos = 0; 212 size_t pos = 0;
@@ -259,7 +259,7 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask,
259 loff_t *ppos) 259 loff_t *ppos)
260{ 260{
261 struct cmd_ds_802_11_subscribe_event *events; 261 struct cmd_ds_802_11_subscribe_event *events;
262 struct mrvlietypes_thresholds *tlv; 262 struct mrvl_ie_thresholds *tlv;
263 struct lbs_private *priv = file->private_data; 263 struct lbs_private *priv = file->private_data;
264 ssize_t buf_size; 264 ssize_t buf_size;
265 int value, freq, new_mask; 265 int value, freq, new_mask;
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index a4455ec7c354..f9ec69e04734 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -321,8 +321,6 @@ struct lbs_private {
321 321
322 u32 monitormode; 322 u32 monitormode;
323 u8 fw_ready; 323 u8 fw_ready;
324 u8 fn_init_required;
325 u8 fn_shutdown_required;
326}; 324};
327 325
328extern struct cmd_confirm_sleep confirm_sleep; 326extern struct cmd_confirm_sleep confirm_sleep;
@@ -340,7 +338,7 @@ struct bss_descriptor {
340 u32 rssi; 338 u32 rssi;
341 u32 channel; 339 u32 channel;
342 u16 beaconperiod; 340 u16 beaconperiod;
343 u32 atimwindow; 341 __le16 atimwindow;
344 342
345 /* IW_MODE_AUTO, IW_MODE_ADHOC, IW_MODE_INFRA */ 343 /* IW_MODE_AUTO, IW_MODE_ADHOC, IW_MODE_INFRA */
346 u8 mode; 344 u8 mode;
@@ -350,10 +348,10 @@ struct bss_descriptor {
350 348
351 unsigned long last_scanned; 349 unsigned long last_scanned;
352 350
353 union ieeetypes_phyparamset phyparamset; 351 union ieee_phy_param_set phy;
354 union IEEEtypes_ssparamset ssparamset; 352 union ieee_ss_param_set ss;
355 353
356 struct ieeetypes_countryinfofullset countryinfo; 354 struct ieee_ie_country_info_full_set countryinfo;
357 355
358 u8 wpa_ie[MAX_WPA_IE_LEN]; 356 u8 wpa_ie[MAX_WPA_IE_LEN];
359 size_t wpa_ie_len; 357 size_t wpa_ie_len;
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h
index 391c54ab2b09..0a2e29140add 100644
--- a/drivers/net/wireless/libertas/hostcmd.h
+++ b/drivers/net/wireless/libertas/hostcmd.h
@@ -250,7 +250,9 @@ struct cmd_ds_gspi_bus_config {
250} __attribute__ ((packed)); 250} __attribute__ ((packed));
251 251
252struct cmd_ds_802_11_authenticate { 252struct cmd_ds_802_11_authenticate {
253 u8 macaddr[ETH_ALEN]; 253 struct cmd_header hdr;
254
255 u8 bssid[ETH_ALEN];
254 u8 authtype; 256 u8 authtype;
255 u8 reserved[10]; 257 u8 reserved[10];
256} __attribute__ ((packed)); 258} __attribute__ ((packed));
@@ -263,22 +265,23 @@ struct cmd_ds_802_11_deauthenticate {
263} __attribute__ ((packed)); 265} __attribute__ ((packed));
264 266
265struct cmd_ds_802_11_associate { 267struct cmd_ds_802_11_associate {
266 u8 peerstaaddr[6]; 268 struct cmd_header hdr;
269
270 u8 bssid[6];
267 __le16 capability; 271 __le16 capability;
268 __le16 listeninterval; 272 __le16 listeninterval;
269 __le16 bcnperiod; 273 __le16 bcnperiod;
270 u8 dtimperiod; 274 u8 dtimperiod;
271 275 u8 iebuf[512]; /* Enough for required and most optional IEs */
272#if 0
273 mrvlietypes_ssidparamset_t ssidParamSet;
274 mrvlietypes_phyparamset_t phyparamset;
275 mrvlietypes_ssparamset_t ssparamset;
276 mrvlietypes_ratesparamset_t ratesParamSet;
277#endif
278} __attribute__ ((packed)); 276} __attribute__ ((packed));
279 277
280struct cmd_ds_802_11_associate_rsp { 278struct cmd_ds_802_11_associate_response {
281 struct ieeetypes_assocrsp assocRsp; 279 struct cmd_header hdr;
280
281 __le16 capability;
282 __le16 statuscode;
283 __le16 aid;
284 u8 iebuf[512];
282} __attribute__ ((packed)); 285} __attribute__ ((packed));
283 286
284struct cmd_ds_802_11_set_wep { 287struct cmd_ds_802_11_set_wep {
@@ -535,9 +538,11 @@ struct cmd_ds_802_11_ad_hoc_start {
535 u8 bsstype; 538 u8 bsstype;
536 __le16 beaconperiod; 539 __le16 beaconperiod;
537 u8 dtimperiod; /* Reserved on v9 and later */ 540 u8 dtimperiod; /* Reserved on v9 and later */
538 union IEEEtypes_ssparamset ssparamset; 541 struct ieee_ie_ibss_param_set ibss;
539 union ieeetypes_phyparamset phyparamset; 542 u8 reserved1[4];
540 __le16 probedelay; 543 struct ieee_ie_ds_param_set ds;
544 u8 reserved2[4];
545 __le16 probedelay; /* Reserved on v9 and later */
541 __le16 capability; 546 __le16 capability;
542 u8 rates[MAX_RATES]; 547 u8 rates[MAX_RATES];
543 u8 tlv_memory_size_pad[100]; 548 u8 tlv_memory_size_pad[100];
@@ -558,8 +563,10 @@ struct adhoc_bssdesc {
558 u8 dtimperiod; 563 u8 dtimperiod;
559 __le64 timestamp; 564 __le64 timestamp;
560 __le64 localtime; 565 __le64 localtime;
561 union ieeetypes_phyparamset phyparamset; 566 struct ieee_ie_ds_param_set ds;
562 union IEEEtypes_ssparamset ssparamset; 567 u8 reserved1[4];
568 struct ieee_ie_ibss_param_set ibss;
569 u8 reserved2[4];
563 __le16 capability; 570 __le16 capability;
564 u8 rates[MAX_RATES]; 571 u8 rates[MAX_RATES];
565 572
@@ -765,8 +772,6 @@ struct cmd_ds_command {
765 /* command Body */ 772 /* command Body */
766 union { 773 union {
767 struct cmd_ds_802_11_ps_mode psmode; 774 struct cmd_ds_802_11_ps_mode psmode;
768 struct cmd_ds_802_11_associate associate;
769 struct cmd_ds_802_11_authenticate auth;
770 struct cmd_ds_802_11_get_stat gstat; 775 struct cmd_ds_802_11_get_stat gstat;
771 struct cmd_ds_802_3_get_stat gstat_8023; 776 struct cmd_ds_802_3_get_stat gstat_8023;
772 struct cmd_ds_802_11_rf_antenna rant; 777 struct cmd_ds_802_11_rf_antenna rant;
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index a7e3fc119b70..8cdb88c6ca28 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -39,8 +39,24 @@
39#include "decl.h" 39#include "decl.h"
40#include "defs.h" 40#include "defs.h"
41#include "dev.h" 41#include "dev.h"
42#include "cmd.h"
42#include "if_sdio.h" 43#include "if_sdio.h"
43 44
45/* The if_sdio_remove() callback function is called when
46 * user removes this module from kernel space or ejects
47 * the card from the slot. The driver handles these 2 cases
48 * differently for SD8688 combo chip.
49 * If the user is removing the module, the FUNC_SHUTDOWN
50 * command for SD8688 is sent to the firmware.
51 * If the card is removed, there is no need to send this command.
52 *
53 * The variable 'user_rmmod' is used to distinguish these two
54 * scenarios. This flag is initialized as FALSE in case the card
55 * is removed, and will be set to TRUE for module removal when
56 * module_exit function is called.
57 */
58static u8 user_rmmod;
59
44static char *lbs_helper_name = NULL; 60static char *lbs_helper_name = NULL;
45module_param_named(helper_name, lbs_helper_name, charp, 0644); 61module_param_named(helper_name, lbs_helper_name, charp, 0644);
46 62
@@ -61,7 +77,6 @@ struct if_sdio_model {
61 int model; 77 int model;
62 const char *helper; 78 const char *helper;
63 const char *firmware; 79 const char *firmware;
64 struct if_sdio_card *card;
65}; 80};
66 81
67static struct if_sdio_model if_sdio_models[] = { 82static struct if_sdio_model if_sdio_models[] = {
@@ -70,21 +85,18 @@ static struct if_sdio_model if_sdio_models[] = {
70 .model = IF_SDIO_MODEL_8385, 85 .model = IF_SDIO_MODEL_8385,
71 .helper = "sd8385_helper.bin", 86 .helper = "sd8385_helper.bin",
72 .firmware = "sd8385.bin", 87 .firmware = "sd8385.bin",
73 .card = NULL,
74 }, 88 },
75 { 89 {
76 /* 8686 */ 90 /* 8686 */
77 .model = IF_SDIO_MODEL_8686, 91 .model = IF_SDIO_MODEL_8686,
78 .helper = "sd8686_helper.bin", 92 .helper = "sd8686_helper.bin",
79 .firmware = "sd8686.bin", 93 .firmware = "sd8686.bin",
80 .card = NULL,
81 }, 94 },
82 { 95 {
83 /* 8688 */ 96 /* 8688 */
84 .model = IF_SDIO_MODEL_8688, 97 .model = IF_SDIO_MODEL_8688,
85 .helper = "sd8688_helper.bin", 98 .helper = "sd8688_helper.bin",
86 .firmware = "sd8688.bin", 99 .firmware = "sd8688.bin",
87 .card = NULL,
88 }, 100 },
89}; 101};
90 102
@@ -927,8 +939,6 @@ static int if_sdio_probe(struct sdio_func *func,
927 goto free; 939 goto free;
928 } 940 }
929 941
930 if_sdio_models[i].card = card;
931
932 card->helper = if_sdio_models[i].helper; 942 card->helper = if_sdio_models[i].helper;
933 card->firmware = if_sdio_models[i].firmware; 943 card->firmware = if_sdio_models[i].firmware;
934 944
@@ -1014,8 +1024,16 @@ static int if_sdio_probe(struct sdio_func *func,
1014 /* 1024 /*
1015 * FUNC_INIT is required for SD8688 WLAN/BT multiple functions 1025 * FUNC_INIT is required for SD8688 WLAN/BT multiple functions
1016 */ 1026 */
1017 priv->fn_init_required = 1027 if (card->model == IF_SDIO_MODEL_8688) {
1018 (card->model == IF_SDIO_MODEL_8688) ? 1 : 0; 1028 struct cmd_header cmd;
1029
1030 memset(&cmd, 0, sizeof(cmd));
1031
1032 lbs_deb_sdio("send function INIT command\n");
1033 if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd),
1034 lbs_cmd_copyback, (unsigned long) &cmd))
1035 lbs_pr_alert("CMD_FUNC_INIT cmd failed\n");
1036 }
1019 1037
1020 ret = lbs_start_card(priv); 1038 ret = lbs_start_card(priv);
1021 if (ret) 1039 if (ret)
@@ -1057,30 +1075,39 @@ static void if_sdio_remove(struct sdio_func *func)
1057{ 1075{
1058 struct if_sdio_card *card; 1076 struct if_sdio_card *card;
1059 struct if_sdio_packet *packet; 1077 struct if_sdio_packet *packet;
1060 int ret;
1061 1078
1062 lbs_deb_enter(LBS_DEB_SDIO); 1079 lbs_deb_enter(LBS_DEB_SDIO);
1063 1080
1064 card = sdio_get_drvdata(func); 1081 card = sdio_get_drvdata(func);
1065 1082
1066 lbs_stop_card(card->priv); 1083 if (user_rmmod && (card->model == IF_SDIO_MODEL_8688)) {
1084 /*
1085 * FUNC_SHUTDOWN is required for SD8688 WLAN/BT
1086 * multiple functions
1087 */
1088 struct cmd_header cmd;
1089
1090 memset(&cmd, 0, sizeof(cmd));
1091
1092 lbs_deb_sdio("send function SHUTDOWN command\n");
1093 if (__lbs_cmd(card->priv, CMD_FUNC_SHUTDOWN,
1094 &cmd, sizeof(cmd), lbs_cmd_copyback,
1095 (unsigned long) &cmd))
1096 lbs_pr_alert("CMD_FUNC_SHUTDOWN cmd failed\n");
1097 }
1067 1098
1068 card->priv->surpriseremoved = 1; 1099 card->priv->surpriseremoved = 1;
1069 1100
1070 lbs_deb_sdio("call remove card\n"); 1101 lbs_deb_sdio("call remove card\n");
1102 lbs_stop_card(card->priv);
1071 lbs_remove_card(card->priv); 1103 lbs_remove_card(card->priv);
1072 1104
1073 flush_workqueue(card->workqueue); 1105 flush_workqueue(card->workqueue);
1074 destroy_workqueue(card->workqueue); 1106 destroy_workqueue(card->workqueue);
1075 1107
1076 sdio_claim_host(func); 1108 sdio_claim_host(func);
1077
1078 /* Disable interrupts */
1079 sdio_writeb(func, 0x00, IF_SDIO_H_INT_MASK, &ret);
1080
1081 sdio_release_irq(func); 1109 sdio_release_irq(func);
1082 sdio_disable_func(func); 1110 sdio_disable_func(func);
1083
1084 sdio_release_host(func); 1111 sdio_release_host(func);
1085 1112
1086 while (card->packets) { 1113 while (card->packets) {
@@ -1116,6 +1143,9 @@ static int __init if_sdio_init_module(void)
1116 1143
1117 ret = sdio_register_driver(&if_sdio_driver); 1144 ret = sdio_register_driver(&if_sdio_driver);
1118 1145
1146 /* Clear the flag in case user removes the card. */
1147 user_rmmod = 0;
1148
1119 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); 1149 lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
1120 1150
1121 return ret; 1151 return ret;
@@ -1123,22 +1153,10 @@ static int __init if_sdio_init_module(void)
1123 1153
1124static void __exit if_sdio_exit_module(void) 1154static void __exit if_sdio_exit_module(void)
1125{ 1155{
1126 int i;
1127 struct if_sdio_card *card;
1128
1129 lbs_deb_enter(LBS_DEB_SDIO); 1156 lbs_deb_enter(LBS_DEB_SDIO);
1130 1157
1131 for (i = 0; i < ARRAY_SIZE(if_sdio_models); i++) { 1158 /* Set the flag as user is removing this module. */
1132 card = if_sdio_models[i].card; 1159 user_rmmod = 1;
1133
1134 /*
1135 * FUNC_SHUTDOWN is required for SD8688 WLAN/BT
1136 * multiple functions
1137 */
1138 if (card && card->priv)
1139 card->priv->fn_shutdown_required =
1140 (card->model == IF_SDIO_MODEL_8688) ? 1 : 0;
1141 }
1142 1160
1143 sdio_unregister_driver(&if_sdio_driver); 1161 sdio_unregister_driver(&if_sdio_driver);
1144 1162
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 5fa55fe1f860..ea23c5de1420 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -119,9 +119,6 @@ static struct chip_ident chip_id_to_device_name[] = {
119 * First we have to put a SPU register name on the bus. Then we can 119 * First we have to put a SPU register name on the bus. Then we can
120 * either read from or write to that register. 120 * either read from or write to that register.
121 * 121 *
122 * For 16-bit transactions, byte order on the bus is big-endian.
123 * We don't have to worry about that here, though.
124 * The translation takes place in the SPI routines.
125 */ 122 */
126 123
127static void spu_transaction_init(struct if_spi_card *card) 124static void spu_transaction_init(struct if_spi_card *card)
@@ -147,7 +144,7 @@ static void spu_transaction_finish(struct if_spi_card *card)
147static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) 144static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
148{ 145{
149 int err = 0; 146 int err = 0;
150 u16 reg_out = reg | IF_SPI_WRITE_OPERATION_MASK; 147 u16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK);
151 148
152 /* You must give an even number of bytes to the SPU, even if it 149 /* You must give an even number of bytes to the SPU, even if it
153 * doesn't care about the last one. */ 150 * doesn't care about the last one. */
@@ -169,16 +166,10 @@ out:
169 166
170static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val) 167static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val)
171{ 168{
172 return spu_write(card, reg, (u8 *)&val, sizeof(u16)); 169 u16 buff;
173}
174 170
175static inline int spu_write_u32(struct if_spi_card *card, u16 reg, u32 val) 171 buff = cpu_to_le16(val);
176{ 172 return spu_write(card, reg, (u8 *)&buff, sizeof(u16));
177 /* The lower 16 bits are written first. */
178 u16 out[2];
179 out[0] = val & 0xffff;
180 out[1] = (val & 0xffff0000) >> 16;
181 return spu_write(card, reg, (u8 *)&out, sizeof(u32));
182} 173}
183 174
184static inline int spu_reg_is_port_reg(u16 reg) 175static inline int spu_reg_is_port_reg(u16 reg)
@@ -198,7 +189,7 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
198 unsigned int i, delay; 189 unsigned int i, delay;
199 int err = 0; 190 int err = 0;
200 u16 zero = 0; 191 u16 zero = 0;
201 u16 reg_out = reg | IF_SPI_READ_OPERATION_MASK; 192 u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK);
202 193
203 /* You must take an even number of bytes from the SPU, even if you 194 /* You must take an even number of bytes from the SPU, even if you
204 * don't care about the last one. */ 195 * don't care about the last one. */
@@ -236,18 +227,25 @@ out:
236/* Read 16 bits from an SPI register */ 227/* Read 16 bits from an SPI register */
237static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val) 228static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val)
238{ 229{
239 return spu_read(card, reg, (u8 *)val, sizeof(u16)); 230 u16 buf;
231 int ret;
232
233 ret = spu_read(card, reg, (u8 *)&buf, sizeof(buf));
234 if (ret == 0)
235 *val = le16_to_cpup(&buf);
236 return ret;
240} 237}
241 238
242/* Read 32 bits from an SPI register. 239/* Read 32 bits from an SPI register.
243 * The low 16 bits are read first. */ 240 * The low 16 bits are read first. */
244static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) 241static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val)
245{ 242{
246 u16 buf[2]; 243 u32 buf;
247 int err; 244 int err;
248 err = spu_read(card, reg, (u8 *)buf, sizeof(u32)); 245
246 err = spu_read(card, reg, (u8 *)&buf, sizeof(buf));
249 if (!err) 247 if (!err)
250 *val = buf[0] | (buf[1] << 16); 248 *val = le32_to_cpup(&buf);
251 return err; 249 return err;
252} 250}
253 251
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index a58a12352672..89575e448015 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1002,17 +1002,9 @@ static int lbs_setup_firmware(struct lbs_private *priv)
1002{ 1002{
1003 int ret = -1; 1003 int ret = -1;
1004 s16 curlevel = 0, minlevel = 0, maxlevel = 0; 1004 s16 curlevel = 0, minlevel = 0, maxlevel = 0;
1005 struct cmd_header cmd;
1006 1005
1007 lbs_deb_enter(LBS_DEB_FW); 1006 lbs_deb_enter(LBS_DEB_FW);
1008 1007
1009 if (priv->fn_init_required) {
1010 memset(&cmd, 0, sizeof(cmd));
1011 if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd),
1012 lbs_cmd_copyback, (unsigned long) &cmd))
1013 lbs_pr_alert("CMD_FUNC_INIT command failed\n");
1014 }
1015
1016 /* Read MAC address from firmware */ 1008 /* Read MAC address from firmware */
1017 memset(priv->current_addr, 0xff, ETH_ALEN); 1009 memset(priv->current_addr, 0xff, ETH_ALEN);
1018 ret = lbs_update_hw_spec(priv); 1010 ret = lbs_update_hw_spec(priv);
@@ -1200,9 +1192,6 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
1200 priv->mesh_open = 0; 1192 priv->mesh_open = 0;
1201 priv->infra_open = 0; 1193 priv->infra_open = 0;
1202 1194
1203 priv->fn_init_required = 0;
1204 priv->fn_shutdown_required = 0;
1205
1206 /* Setup the OS Interface to our functions */ 1195 /* Setup the OS Interface to our functions */
1207 dev->netdev_ops = &lbs_netdev_ops; 1196 dev->netdev_ops = &lbs_netdev_ops;
1208 dev->watchdog_timeo = 5 * HZ; 1197 dev->watchdog_timeo = 5 * HZ;
@@ -1384,20 +1373,11 @@ void lbs_stop_card(struct lbs_private *priv)
1384 struct net_device *dev; 1373 struct net_device *dev;
1385 struct cmd_ctrl_node *cmdnode; 1374 struct cmd_ctrl_node *cmdnode;
1386 unsigned long flags; 1375 unsigned long flags;
1387 struct cmd_header cmd;
1388 1376
1389 lbs_deb_enter(LBS_DEB_MAIN); 1377 lbs_deb_enter(LBS_DEB_MAIN);
1390 1378
1391 if (!priv) 1379 if (!priv)
1392 goto out; 1380 goto out;
1393
1394 if (priv->fn_shutdown_required) {
1395 memset(&cmd, 0, sizeof(cmd));
1396 if (__lbs_cmd(priv, CMD_FUNC_SHUTDOWN, &cmd, sizeof(cmd),
1397 lbs_cmd_copyback, (unsigned long) &cmd))
1398 lbs_pr_alert("CMD_FUNC_SHUTDOWN command failed\n");
1399 }
1400
1401 dev = priv->dev; 1381 dev = priv->dev;
1402 1382
1403 netif_stop_queue(dev); 1383 netif_stop_queue(dev);
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 8124db36aaff..601b54249677 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -27,12 +27,12 @@
27 + 40) /* 40 for WPAIE */ 27 + 40) /* 40 for WPAIE */
28 28
29//! Memory needed to store a max sized channel List TLV for a firmware scan 29//! Memory needed to store a max sized channel List TLV for a firmware scan
30#define CHAN_TLV_MAX_SIZE (sizeof(struct mrvlietypesheader) \ 30#define CHAN_TLV_MAX_SIZE (sizeof(struct mrvl_ie_header) \
31 + (MRVDRV_MAX_CHANNELS_PER_SCAN \ 31 + (MRVDRV_MAX_CHANNELS_PER_SCAN \
32 * sizeof(struct chanscanparamset))) 32 * sizeof(struct chanscanparamset)))
33 33
34//! Memory needed to store a max number/size SSID TLV for a firmware scan 34//! Memory needed to store a max number/size SSID TLV for a firmware scan
35#define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvlietypes_ssidparamset)) 35#define SSID_TLV_MAX_SIZE (1 * sizeof(struct mrvl_ie_ssid_param_set))
36 36
37//! Maximum memory needed for a cmd_ds_802_11_scan with all TLVs at max 37//! Maximum memory needed for a cmd_ds_802_11_scan with all TLVs at max
38#define MAX_SCAN_CFG_ALLOC (sizeof(struct cmd_ds_802_11_scan) \ 38#define MAX_SCAN_CFG_ALLOC (sizeof(struct cmd_ds_802_11_scan) \
@@ -211,7 +211,7 @@ static int lbs_scan_create_channel_list(struct lbs_private *priv,
211 */ 211 */
212static int lbs_scan_add_ssid_tlv(struct lbs_private *priv, u8 *tlv) 212static int lbs_scan_add_ssid_tlv(struct lbs_private *priv, u8 *tlv)
213{ 213{
214 struct mrvlietypes_ssidparamset *ssid_tlv = (void *)tlv; 214 struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv;
215 215
216 ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID); 216 ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
217 ssid_tlv->header.len = cpu_to_le16(priv->scan_ssid_len); 217 ssid_tlv->header.len = cpu_to_le16(priv->scan_ssid_len);
@@ -249,7 +249,7 @@ static int lbs_scan_add_chanlist_tlv(uint8_t *tlv,
249 int chan_count) 249 int chan_count)
250{ 250{
251 size_t size = sizeof(struct chanscanparamset) *chan_count; 251 size_t size = sizeof(struct chanscanparamset) *chan_count;
252 struct mrvlietypes_chanlistparamset *chan_tlv = (void *)tlv; 252 struct mrvl_ie_chanlist_param_set *chan_tlv = (void *)tlv;
253 253
254 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST); 254 chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
255 memcpy(chan_tlv->chanscanparam, chan_list, size); 255 memcpy(chan_tlv->chanscanparam, chan_list, size);
@@ -270,7 +270,7 @@ static int lbs_scan_add_chanlist_tlv(uint8_t *tlv,
270static int lbs_scan_add_rates_tlv(uint8_t *tlv) 270static int lbs_scan_add_rates_tlv(uint8_t *tlv)
271{ 271{
272 int i; 272 int i;
273 struct mrvlietypes_ratesparamset *rate_tlv = (void *)tlv; 273 struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
274 274
275 rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES); 275 rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
276 tlv += sizeof(rate_tlv->header); 276 tlv += sizeof(rate_tlv->header);
@@ -513,12 +513,12 @@ void lbs_scan_worker(struct work_struct *work)
513static int lbs_process_bss(struct bss_descriptor *bss, 513static int lbs_process_bss(struct bss_descriptor *bss,
514 uint8_t **pbeaconinfo, int *bytesleft) 514 uint8_t **pbeaconinfo, int *bytesleft)
515{ 515{
516 struct ieeetypes_fhparamset *pFH; 516 struct ieee_ie_fh_param_set *fh;
517 struct ieeetypes_dsparamset *pDS; 517 struct ieee_ie_ds_param_set *ds;
518 struct ieeetypes_cfparamset *pCF; 518 struct ieee_ie_cf_param_set *cf;
519 struct ieeetypes_ibssparamset *pibss; 519 struct ieee_ie_ibss_param_set *ibss;
520 DECLARE_SSID_BUF(ssid); 520 DECLARE_SSID_BUF(ssid);
521 struct ieeetypes_countryinfoset *pcountryinfo; 521 struct ieee_ie_country_info_set *pcountryinfo;
522 uint8_t *pos, *end, *p; 522 uint8_t *pos, *end, *p;
523 uint8_t n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0; 523 uint8_t n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0;
524 uint16_t beaconsize = 0; 524 uint16_t beaconsize = 0;
@@ -616,50 +616,49 @@ static int lbs_process_bss(struct bss_descriptor *bss,
616 break; 616 break;
617 617
618 case WLAN_EID_FH_PARAMS: 618 case WLAN_EID_FH_PARAMS:
619 pFH = (struct ieeetypes_fhparamset *) pos; 619 fh = (struct ieee_ie_fh_param_set *) pos;
620 memmove(&bss->phyparamset.fhparamset, pFH, 620 memcpy(&bss->phy.fh, fh, sizeof(*fh));
621 sizeof(struct ieeetypes_fhparamset));
622 lbs_deb_scan("got FH IE\n"); 621 lbs_deb_scan("got FH IE\n");
623 break; 622 break;
624 623
625 case WLAN_EID_DS_PARAMS: 624 case WLAN_EID_DS_PARAMS:
626 pDS = (struct ieeetypes_dsparamset *) pos; 625 ds = (struct ieee_ie_ds_param_set *) pos;
627 bss->channel = pDS->currentchan; 626 bss->channel = ds->channel;
628 memcpy(&bss->phyparamset.dsparamset, pDS, 627 memcpy(&bss->phy.ds, ds, sizeof(*ds));
629 sizeof(struct ieeetypes_dsparamset));
630 lbs_deb_scan("got DS IE, channel %d\n", bss->channel); 628 lbs_deb_scan("got DS IE, channel %d\n", bss->channel);
631 break; 629 break;
632 630
633 case WLAN_EID_CF_PARAMS: 631 case WLAN_EID_CF_PARAMS:
634 pCF = (struct ieeetypes_cfparamset *) pos; 632 cf = (struct ieee_ie_cf_param_set *) pos;
635 memcpy(&bss->ssparamset.cfparamset, pCF, 633 memcpy(&bss->ss.cf, cf, sizeof(*cf));
636 sizeof(struct ieeetypes_cfparamset));
637 lbs_deb_scan("got CF IE\n"); 634 lbs_deb_scan("got CF IE\n");
638 break; 635 break;
639 636
640 case WLAN_EID_IBSS_PARAMS: 637 case WLAN_EID_IBSS_PARAMS:
641 pibss = (struct ieeetypes_ibssparamset *) pos; 638 ibss = (struct ieee_ie_ibss_param_set *) pos;
642 bss->atimwindow = le16_to_cpu(pibss->atimwindow); 639 bss->atimwindow = ibss->atimwindow;
643 memmove(&bss->ssparamset.ibssparamset, pibss, 640 memcpy(&bss->ss.ibss, ibss, sizeof(*ibss));
644 sizeof(struct ieeetypes_ibssparamset));
645 lbs_deb_scan("got IBSS IE\n"); 641 lbs_deb_scan("got IBSS IE\n");
646 break; 642 break;
647 643
648 case WLAN_EID_COUNTRY: 644 case WLAN_EID_COUNTRY:
649 pcountryinfo = (struct ieeetypes_countryinfoset *) pos; 645 pcountryinfo = (struct ieee_ie_country_info_set *) pos;
650 lbs_deb_scan("got COUNTRY IE\n"); 646 lbs_deb_scan("got COUNTRY IE\n");
651 if (pcountryinfo->len < sizeof(pcountryinfo->countrycode) 647 if (pcountryinfo->header.len < sizeof(pcountryinfo->countrycode)
652 || pcountryinfo->len > 254) { 648 || pcountryinfo->header.len > 254) {
653 lbs_deb_scan("process_bss: 11D- Err CountryInfo len %d, min %zd, max 254\n", 649 lbs_deb_scan("%s: 11D- Err CountryInfo len %d, min %zd, max 254\n",
654 pcountryinfo->len, sizeof(pcountryinfo->countrycode)); 650 __func__,
651 pcountryinfo->header.len,
652 sizeof(pcountryinfo->countrycode));
655 ret = -1; 653 ret = -1;
656 goto done; 654 goto done;
657 } 655 }
658 656
659 memcpy(&bss->countryinfo, pcountryinfo, pcountryinfo->len + 2); 657 memcpy(&bss->countryinfo, pcountryinfo,
658 pcountryinfo->header.len + 2);
660 lbs_deb_hex(LBS_DEB_SCAN, "process_bss: 11d countryinfo", 659 lbs_deb_hex(LBS_DEB_SCAN, "process_bss: 11d countryinfo",
661 (uint8_t *) pcountryinfo, 660 (uint8_t *) pcountryinfo,
662 (int) (pcountryinfo->len + 2)); 661 (int) (pcountryinfo->header.len + 2));
663 break; 662 break;
664 663
665 case WLAN_EID_EXT_SUPP_RATES: 664 case WLAN_EID_EXT_SUPP_RATES:
@@ -1130,7 +1129,7 @@ static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy,
1130 goto done; 1129 goto done;
1131 } 1130 }
1132 1131
1133 bytesleft = le16_to_cpu(scanresp->bssdescriptsize); 1132 bytesleft = get_unaligned_le16(&scanresp->bssdescriptsize);
1134 lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft); 1133 lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft);
1135 1134
1136 scanrespsize = le16_to_cpu(resp->size); 1135 scanrespsize = le16_to_cpu(resp->size);
diff --git a/drivers/net/wireless/libertas/types.h b/drivers/net/wireless/libertas/types.h
index de03b9c9c204..99905df65b25 100644
--- a/drivers/net/wireless/libertas/types.h
+++ b/drivers/net/wireless/libertas/types.h
@@ -8,9 +8,14 @@
8#include <asm/byteorder.h> 8#include <asm/byteorder.h>
9#include <linux/wireless.h> 9#include <linux/wireless.h>
10 10
11struct ieeetypes_cfparamset { 11struct ieee_ie_header {
12 u8 elementid; 12 u8 id;
13 u8 len; 13 u8 len;
14} __attribute__ ((packed));
15
16struct ieee_ie_cf_param_set {
17 struct ieee_ie_header header;
18
14 u8 cfpcnt; 19 u8 cfpcnt;
15 u8 cfpperiod; 20 u8 cfpperiod;
16 __le16 cfpmaxduration; 21 __le16 cfpmaxduration;
@@ -18,42 +23,35 @@ struct ieeetypes_cfparamset {
18} __attribute__ ((packed)); 23} __attribute__ ((packed));
19 24
20 25
21struct ieeetypes_ibssparamset { 26struct ieee_ie_ibss_param_set {
22 u8 elementid; 27 struct ieee_ie_header header;
23 u8 len; 28
24 __le16 atimwindow; 29 __le16 atimwindow;
25} __attribute__ ((packed)); 30} __attribute__ ((packed));
26 31
27union IEEEtypes_ssparamset { 32union ieee_ss_param_set {
28 struct ieeetypes_cfparamset cfparamset; 33 struct ieee_ie_cf_param_set cf;
29 struct ieeetypes_ibssparamset ibssparamset; 34 struct ieee_ie_ibss_param_set ibss;
30} __attribute__ ((packed)); 35} __attribute__ ((packed));
31 36
32struct ieeetypes_fhparamset { 37struct ieee_ie_fh_param_set {
33 u8 elementid; 38 struct ieee_ie_header header;
34 u8 len; 39
35 __le16 dwelltime; 40 __le16 dwelltime;
36 u8 hopset; 41 u8 hopset;
37 u8 hoppattern; 42 u8 hoppattern;
38 u8 hopindex; 43 u8 hopindex;
39} __attribute__ ((packed)); 44} __attribute__ ((packed));
40 45
41struct ieeetypes_dsparamset { 46struct ieee_ie_ds_param_set {
42 u8 elementid; 47 struct ieee_ie_header header;
43 u8 len;
44 u8 currentchan;
45} __attribute__ ((packed));
46 48
47union ieeetypes_phyparamset { 49 u8 channel;
48 struct ieeetypes_fhparamset fhparamset;
49 struct ieeetypes_dsparamset dsparamset;
50} __attribute__ ((packed)); 50} __attribute__ ((packed));
51 51
52struct ieeetypes_assocrsp { 52union ieee_phy_param_set {
53 __le16 capability; 53 struct ieee_ie_fh_param_set fh;
54 __le16 statuscode; 54 struct ieee_ie_ds_param_set ds;
55 __le16 aid;
56 u8 iebuffer[1];
57} __attribute__ ((packed)); 55} __attribute__ ((packed));
58 56
59/** TLV type ID definition */ 57/** TLV type ID definition */
@@ -94,32 +92,33 @@ struct ieeetypes_assocrsp {
94#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19) 92#define TLV_TYPE_TSFTIMESTAMP (PROPRIETARY_TLV_BASE_ID + 19)
95#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22) 93#define TLV_TYPE_RSSI_HIGH (PROPRIETARY_TLV_BASE_ID + 22)
96#define TLV_TYPE_SNR_HIGH (PROPRIETARY_TLV_BASE_ID + 23) 94#define TLV_TYPE_SNR_HIGH (PROPRIETARY_TLV_BASE_ID + 23)
95#define TLV_TYPE_AUTH_TYPE (PROPRIETARY_TLV_BASE_ID + 31)
97#define TLV_TYPE_MESH_ID (PROPRIETARY_TLV_BASE_ID + 37) 96#define TLV_TYPE_MESH_ID (PROPRIETARY_TLV_BASE_ID + 37)
98#define TLV_TYPE_OLD_MESH_ID (PROPRIETARY_TLV_BASE_ID + 291) 97#define TLV_TYPE_OLD_MESH_ID (PROPRIETARY_TLV_BASE_ID + 291)
99 98
100/** TLV related data structures*/ 99/** TLV related data structures*/
101struct mrvlietypesheader { 100struct mrvl_ie_header {
102 __le16 type; 101 __le16 type;
103 __le16 len; 102 __le16 len;
104} __attribute__ ((packed)); 103} __attribute__ ((packed));
105 104
106struct mrvlietypes_data { 105struct mrvl_ie_data {
107 struct mrvlietypesheader header; 106 struct mrvl_ie_header header;
108 u8 Data[1]; 107 u8 Data[1];
109} __attribute__ ((packed)); 108} __attribute__ ((packed));
110 109
111struct mrvlietypes_ratesparamset { 110struct mrvl_ie_rates_param_set {
112 struct mrvlietypesheader header; 111 struct mrvl_ie_header header;
113 u8 rates[1]; 112 u8 rates[1];
114} __attribute__ ((packed)); 113} __attribute__ ((packed));
115 114
116struct mrvlietypes_ssidparamset { 115struct mrvl_ie_ssid_param_set {
117 struct mrvlietypesheader header; 116 struct mrvl_ie_header header;
118 u8 ssid[1]; 117 u8 ssid[1];
119} __attribute__ ((packed)); 118} __attribute__ ((packed));
120 119
121struct mrvlietypes_wildcardssidparamset { 120struct mrvl_ie_wildcard_ssid_param_set {
122 struct mrvlietypesheader header; 121 struct mrvl_ie_header header;
123 u8 MaxSsidlength; 122 u8 MaxSsidlength;
124 u8 ssid[1]; 123 u8 ssid[1];
125} __attribute__ ((packed)); 124} __attribute__ ((packed));
@@ -144,91 +143,72 @@ struct chanscanparamset {
144 __le16 maxscantime; 143 __le16 maxscantime;
145} __attribute__ ((packed)); 144} __attribute__ ((packed));
146 145
147struct mrvlietypes_chanlistparamset { 146struct mrvl_ie_chanlist_param_set {
148 struct mrvlietypesheader header; 147 struct mrvl_ie_header header;
149 struct chanscanparamset chanscanparam[1]; 148 struct chanscanparamset chanscanparam[1];
150} __attribute__ ((packed)); 149} __attribute__ ((packed));
151 150
152struct cfparamset { 151struct mrvl_ie_cf_param_set {
152 struct mrvl_ie_header header;
153 u8 cfpcnt; 153 u8 cfpcnt;
154 u8 cfpperiod; 154 u8 cfpperiod;
155 __le16 cfpmaxduration; 155 __le16 cfpmaxduration;
156 __le16 cfpdurationremaining; 156 __le16 cfpdurationremaining;
157} __attribute__ ((packed)); 157} __attribute__ ((packed));
158 158
159struct ibssparamset { 159struct mrvl_ie_ds_param_set {
160 __le16 atimwindow; 160 struct mrvl_ie_header header;
161} __attribute__ ((packed)); 161 u8 channel;
162
163struct mrvlietypes_ssparamset {
164 struct mrvlietypesheader header;
165 union {
166 struct cfparamset cfparamset[1];
167 struct ibssparamset ibssparamset[1];
168 } cf_ibss;
169} __attribute__ ((packed)); 162} __attribute__ ((packed));
170 163
171struct fhparamset { 164struct mrvl_ie_rsn_param_set {
172 __le16 dwelltime; 165 struct mrvl_ie_header header;
173 u8 hopset;
174 u8 hoppattern;
175 u8 hopindex;
176} __attribute__ ((packed));
177
178struct dsparamset {
179 u8 currentchan;
180} __attribute__ ((packed));
181
182struct mrvlietypes_phyparamset {
183 struct mrvlietypesheader header;
184 union {
185 struct fhparamset fhparamset[1];
186 struct dsparamset dsparamset[1];
187 } fh_ds;
188} __attribute__ ((packed));
189
190struct mrvlietypes_rsnparamset {
191 struct mrvlietypesheader header;
192 u8 rsnie[1]; 166 u8 rsnie[1];
193} __attribute__ ((packed)); 167} __attribute__ ((packed));
194 168
195struct mrvlietypes_tsftimestamp { 169struct mrvl_ie_tsf_timestamp {
196 struct mrvlietypesheader header; 170 struct mrvl_ie_header header;
197 __le64 tsftable[1]; 171 __le64 tsftable[1];
198} __attribute__ ((packed)); 172} __attribute__ ((packed));
199 173
174/* v9 and later firmware only */
175struct mrvl_ie_auth_type {
176 struct mrvl_ie_header header;
177 __le16 auth;
178} __attribute__ ((packed));
179
200/** Local Power capability */ 180/** Local Power capability */
201struct mrvlietypes_powercapability { 181struct mrvl_ie_power_capability {
202 struct mrvlietypesheader header; 182 struct mrvl_ie_header header;
203 s8 minpower; 183 s8 minpower;
204 s8 maxpower; 184 s8 maxpower;
205} __attribute__ ((packed)); 185} __attribute__ ((packed));
206 186
207/* used in CMD_802_11_SUBSCRIBE_EVENT for SNR, RSSI and Failure */ 187/* used in CMD_802_11_SUBSCRIBE_EVENT for SNR, RSSI and Failure */
208struct mrvlietypes_thresholds { 188struct mrvl_ie_thresholds {
209 struct mrvlietypesheader header; 189 struct mrvl_ie_header header;
210 u8 value; 190 u8 value;
211 u8 freq; 191 u8 freq;
212} __attribute__ ((packed)); 192} __attribute__ ((packed));
213 193
214struct mrvlietypes_beaconsmissed { 194struct mrvl_ie_beacons_missed {
215 struct mrvlietypesheader header; 195 struct mrvl_ie_header header;
216 u8 beaconmissed; 196 u8 beaconmissed;
217 u8 reserved; 197 u8 reserved;
218} __attribute__ ((packed)); 198} __attribute__ ((packed));
219 199
220struct mrvlietypes_numprobes { 200struct mrvl_ie_num_probes {
221 struct mrvlietypesheader header; 201 struct mrvl_ie_header header;
222 __le16 numprobes; 202 __le16 numprobes;
223} __attribute__ ((packed)); 203} __attribute__ ((packed));
224 204
225struct mrvlietypes_bcastprobe { 205struct mrvl_ie_bcast_probe {
226 struct mrvlietypesheader header; 206 struct mrvl_ie_header header;
227 __le16 bcastprobe; 207 __le16 bcastprobe;
228} __attribute__ ((packed)); 208} __attribute__ ((packed));
229 209
230struct mrvlietypes_numssidprobe { 210struct mrvl_ie_num_ssid_probe {
231 struct mrvlietypesheader header; 211 struct mrvl_ie_header header;
232 __le16 numssidprobe; 212 __le16 numssidprobe;
233} __attribute__ ((packed)); 213} __attribute__ ((packed));
234 214
@@ -237,8 +217,8 @@ struct led_pin {
237 u8 pin; 217 u8 pin;
238} __attribute__ ((packed)); 218} __attribute__ ((packed));
239 219
240struct mrvlietypes_ledgpio { 220struct mrvl_ie_ledgpio {
241 struct mrvlietypesheader header; 221 struct mrvl_ie_header header;
242 struct led_pin ledpin[1]; 222 struct led_pin ledpin[1];
243} __attribute__ ((packed)); 223} __attribute__ ((packed));
244 224
@@ -250,8 +230,8 @@ struct led_bhv {
250} __attribute__ ((packed)); 230} __attribute__ ((packed));
251 231
252 232
253struct mrvlietypes_ledbhv { 233struct mrvl_ie_ledbhv {
254 struct mrvlietypesheader header; 234 struct mrvl_ie_header header;
255 struct led_bhv ledbhv[1]; 235 struct led_bhv ledbhv[1];
256} __attribute__ ((packed)); 236} __attribute__ ((packed));
257 237
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 574b8bb121e1..e789c6e9938c 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -280,7 +280,6 @@ struct mac80211_hwsim_data {
280 struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)]; 280 struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
281 281
282 struct ieee80211_channel *channel; 282 struct ieee80211_channel *channel;
283 int radio_enabled;
284 unsigned long beacon_int; /* in jiffies unit */ 283 unsigned long beacon_int; /* in jiffies unit */
285 unsigned int rx_filter; 284 unsigned int rx_filter;
286 int started; 285 int started;
@@ -418,8 +417,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
418 if (data == data2) 417 if (data == data2)
419 continue; 418 continue;
420 419
421 if (!data2->started || !data2->radio_enabled || 420 if (!data2->started || !hwsim_ps_rx_ok(data2, skb) ||
422 !hwsim_ps_rx_ok(data2, skb) ||
423 data->channel->center_freq != data2->channel->center_freq || 421 data->channel->center_freq != data2->channel->center_freq ||
424 !(data->group & data2->group)) 422 !(data->group & data2->group))
425 continue; 423 continue;
@@ -441,7 +439,6 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
441 439
442static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 440static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
443{ 441{
444 struct mac80211_hwsim_data *data = hw->priv;
445 bool ack; 442 bool ack;
446 struct ieee80211_tx_info *txi; 443 struct ieee80211_tx_info *txi;
447 444
@@ -453,13 +450,6 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
453 return NETDEV_TX_OK; 450 return NETDEV_TX_OK;
454 } 451 }
455 452
456 if (!data->radio_enabled) {
457 printk(KERN_DEBUG "%s: dropped TX frame since radio "
458 "disabled\n", wiphy_name(hw->wiphy));
459 dev_kfree_skb(skb);
460 return NETDEV_TX_OK;
461 }
462
463 ack = mac80211_hwsim_tx_frame(hw, skb); 453 ack = mac80211_hwsim_tx_frame(hw, skb);
464 454
465 txi = IEEE80211_SKB_CB(skb); 455 txi = IEEE80211_SKB_CB(skb);
@@ -546,7 +536,7 @@ static void mac80211_hwsim_beacon(unsigned long arg)
546 struct ieee80211_hw *hw = (struct ieee80211_hw *) arg; 536 struct ieee80211_hw *hw = (struct ieee80211_hw *) arg;
547 struct mac80211_hwsim_data *data = hw->priv; 537 struct mac80211_hwsim_data *data = hw->priv;
548 538
549 if (!data->started || !data->radio_enabled) 539 if (!data->started)
550 return; 540 return;
551 541
552 ieee80211_iterate_active_interfaces_atomic( 542 ieee80211_iterate_active_interfaces_atomic(
@@ -562,15 +552,14 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
562 struct mac80211_hwsim_data *data = hw->priv; 552 struct mac80211_hwsim_data *data = hw->priv;
563 struct ieee80211_conf *conf = &hw->conf; 553 struct ieee80211_conf *conf = &hw->conf;
564 554
565 printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d idle=%d ps=%d)\n", 555 printk(KERN_DEBUG "%s:%s (freq=%d idle=%d ps=%d)\n",
566 wiphy_name(hw->wiphy), __func__, 556 wiphy_name(hw->wiphy), __func__,
567 conf->channel->center_freq, conf->radio_enabled, 557 conf->channel->center_freq,
568 !!(conf->flags & IEEE80211_CONF_IDLE), 558 !!(conf->flags & IEEE80211_CONF_IDLE),
569 !!(conf->flags & IEEE80211_CONF_PS)); 559 !!(conf->flags & IEEE80211_CONF_PS));
570 560
571 data->channel = conf->channel; 561 data->channel = conf->channel;
572 data->radio_enabled = conf->radio_enabled; 562 if (!data->started || !data->beacon_int)
573 if (!data->started || !data->radio_enabled || !data->beacon_int)
574 del_timer(&data->beacon_timer); 563 del_timer(&data->beacon_timer);
575 else 564 else
576 mod_timer(&data->beacon_timer, jiffies + data->beacon_int); 565 mod_timer(&data->beacon_timer, jiffies + data->beacon_int);
@@ -787,8 +776,7 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
787 pspoll->aid = cpu_to_le16(0xc000 | vp->aid); 776 pspoll->aid = cpu_to_le16(0xc000 | vp->aid);
788 memcpy(pspoll->bssid, vp->bssid, ETH_ALEN); 777 memcpy(pspoll->bssid, vp->bssid, ETH_ALEN);
789 memcpy(pspoll->ta, mac, ETH_ALEN); 778 memcpy(pspoll->ta, mac, ETH_ALEN);
790 if (data->radio_enabled && 779 if (!mac80211_hwsim_tx_frame(data->hw, skb))
791 !mac80211_hwsim_tx_frame(data->hw, skb))
792 printk(KERN_DEBUG "%s: PS-Poll frame not ack'ed\n", __func__); 780 printk(KERN_DEBUG "%s: PS-Poll frame not ack'ed\n", __func__);
793 dev_kfree_skb(skb); 781 dev_kfree_skb(skb);
794} 782}
@@ -819,8 +807,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
819 memcpy(hdr->addr1, vp->bssid, ETH_ALEN); 807 memcpy(hdr->addr1, vp->bssid, ETH_ALEN);
820 memcpy(hdr->addr2, mac, ETH_ALEN); 808 memcpy(hdr->addr2, mac, ETH_ALEN);
821 memcpy(hdr->addr3, vp->bssid, ETH_ALEN); 809 memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
822 if (data->radio_enabled && 810 if (!mac80211_hwsim_tx_frame(data->hw, skb))
823 !mac80211_hwsim_tx_frame(data->hw, skb))
824 printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__); 811 printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__);
825 dev_kfree_skb(skb); 812 dev_kfree_skb(skb);
826} 813}
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index f40c0f468b27..0e877a104a89 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -84,8 +84,8 @@ MODULE_DEVICE_TABLE(usb, p54u_table);
84static const struct { 84static const struct {
85 u32 intf; 85 u32 intf;
86 enum p54u_hw_type type; 86 enum p54u_hw_type type;
87 char fw[FIRMWARE_NAME_MAX]; 87 const char *fw;
88 char fw_legacy[FIRMWARE_NAME_MAX]; 88 const char *fw_legacy;
89 char hw[20]; 89 char hw[20];
90} p54u_fwlist[__NUM_P54U_HWTYPES] = { 90} p54u_fwlist[__NUM_P54U_HWTYPES] = {
91 { 91 {
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 0197531bd88c..435f945fe64d 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -520,7 +520,7 @@ static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev,
520 if (state == STATE_SLEEP) { 520 if (state == STATE_SLEEP) {
521 rt2x00pci_register_read(rt2x00dev, CSR20, &reg); 521 rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
522 rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN, 522 rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
523 (libconf->conf->beacon_int - 20) * 16); 523 (rt2x00dev->beacon_int - 20) * 16);
524 rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP, 524 rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
525 libconf->conf->listen_interval - 1); 525 libconf->conf->listen_interval - 1);
526 526
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index f95cb646f85a..08b30d01e67d 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -569,7 +569,7 @@ static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev,
569 if (state == STATE_SLEEP) { 569 if (state == STATE_SLEEP) {
570 rt2x00pci_register_read(rt2x00dev, CSR20, &reg); 570 rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
571 rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN, 571 rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
572 (libconf->conf->beacon_int - 20) * 16); 572 (rt2x00dev->beacon_int - 20) * 16);
573 rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP, 573 rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
574 libconf->conf->listen_interval - 1); 574 libconf->conf->listen_interval - 1);
575 575
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 69f966f1ce54..66daf68ff0ee 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -647,7 +647,7 @@ static void rt2500usb_config_ps(struct rt2x00_dev *rt2x00dev,
647 if (state == STATE_SLEEP) { 647 if (state == STATE_SLEEP) {
648 rt2500usb_register_read(rt2x00dev, MAC_CSR18, &reg); 648 rt2500usb_register_read(rt2x00dev, MAC_CSR18, &reg);
649 rt2x00_set_field16(&reg, MAC_CSR18_DELAY_AFTER_BEACON, 649 rt2x00_set_field16(&reg, MAC_CSR18_DELAY_AFTER_BEACON,
650 libconf->conf->beacon_int - 20); 650 rt2x00dev->beacon_int - 20);
651 rt2x00_set_field16(&reg, MAC_CSR18_BEACONS_BEFORE_WAKEUP, 651 rt2x00_set_field16(&reg, MAC_CSR18_BEACONS_BEFORE_WAKEUP,
652 libconf->conf->listen_interval - 1); 652 libconf->conf->listen_interval - 1);
653 653
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 142ad34fdc49..37561667925b 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -2927,12 +2927,17 @@ static struct usb_device_id rt2800usb_device_table[] = {
2927 { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) }, 2927 { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
2928 { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) }, 2928 { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) },
2929 { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) }, 2929 { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) },
2930 { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) },
2931 { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) },
2932 { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) },
2930 { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) }, 2933 { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
2931 { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) }, 2934 { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) },
2932 /* Edimax */ 2935 /* Edimax */
2933 { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) }, 2936 { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) },
2934 { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) }, 2937 { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) },
2935 { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) }, 2938 { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) },
2939 /* Encore */
2940 { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) },
2936 /* EnGenius */ 2941 /* EnGenius */
2937 { USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) }, 2942 { USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) },
2938 { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) }, 2943 { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -2951,6 +2956,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
2951 { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) }, 2956 { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) },
2952 { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) }, 2957 { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) },
2953 { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) }, 2958 { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) },
2959 /* I-O DATA */
2960 { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
2954 /* LevelOne */ 2961 /* LevelOne */
2955 { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) }, 2962 { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) },
2956 { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) }, 2963 { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -2970,6 +2977,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
2970 /* Pegatron */ 2977 /* Pegatron */
2971 { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) }, 2978 { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) },
2972 { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) }, 2979 { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
2980 { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
2973 /* Philips */ 2981 /* Philips */
2974 { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) }, 2982 { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) },
2975 /* Planex */ 2983 /* Planex */
@@ -2981,6 +2989,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
2981 /* Quanta */ 2989 /* Quanta */
2982 { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) }, 2990 { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
2983 /* Ralink */ 2991 /* Ralink */
2992 { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
2984 { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) }, 2993 { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) },
2985 { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) }, 2994 { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
2986 { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) }, 2995 { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -3005,6 +3014,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
3005 { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) }, 3014 { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
3006 { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) }, 3015 { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
3007 { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) }, 3016 { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
3017 { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
3008 /* SMC */ 3018 /* SMC */
3009 { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) }, 3019 { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) },
3010 { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) }, 3020 { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
@@ -3029,6 +3039,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
3029 /* Zinwell */ 3039 /* Zinwell */
3030 { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) }, 3040 { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) },
3031 { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) }, 3041 { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) },
3042 { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
3043 { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
3032 /* Zyxel */ 3044 /* Zyxel */
3033 { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) }, 3045 { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
3034 { USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) }, 3046 { USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) },
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 2b64a6198698..a498dde024e1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -802,6 +802,11 @@ struct rt2x00_dev {
802 u8 calibration[2]; 802 u8 calibration[2];
803 803
804 /* 804 /*
805 * Beacon interval.
806 */
807 u16 beacon_int;
808
809 /*
805 * Low level statistics which will have 810 * Low level statistics which will have
806 * to be kept up to date while device is running. 811 * to be kept up to date while device is running.
807 */ 812 */
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index c5bbf0b6e207..3e019a12df2e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -108,6 +108,9 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
108 erp.basic_rates = bss_conf->basic_rates; 108 erp.basic_rates = bss_conf->basic_rates;
109 erp.beacon_int = bss_conf->beacon_int; 109 erp.beacon_int = bss_conf->beacon_int;
110 110
111 /* Update global beacon interval time, this is needed for PS support */
112 rt2x00dev->beacon_int = bss_conf->beacon_int;
113
111 rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp); 114 rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp);
112} 115}
113 116
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index a8bf5c432858..49b29ff90c47 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -956,7 +956,7 @@ static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev,
956 if (state == STATE_SLEEP) { 956 if (state == STATE_SLEEP) {
957 rt2x00pci_register_read(rt2x00dev, MAC_CSR11, &reg); 957 rt2x00pci_register_read(rt2x00dev, MAC_CSR11, &reg);
958 rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN, 958 rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
959 libconf->conf->beacon_int - 10); 959 rt2x00dev->beacon_int - 10);
960 rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP, 960 rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP,
961 libconf->conf->listen_interval - 1); 961 libconf->conf->listen_interval - 1);
962 rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5); 962 rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 211a3d6bc054..c18848836f2d 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -852,7 +852,7 @@ static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev,
852 if (state == STATE_SLEEP) { 852 if (state == STATE_SLEEP) {
853 rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg); 853 rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg);
854 rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN, 854 rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
855 libconf->conf->beacon_int - 10); 855 rt2x00dev->beacon_int - 10);
856 rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP, 856 rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP,
857 libconf->conf->listen_interval - 1); 857 libconf->conf->listen_interval - 1);
858 rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5); 858 rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5);
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 284ebaca6e45..c682ac536415 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -21,7 +21,7 @@ config ACER_WMI
21 depends on NEW_LEDS 21 depends on NEW_LEDS
22 depends on BACKLIGHT_CLASS_DEVICE 22 depends on BACKLIGHT_CLASS_DEVICE
23 depends on SERIO_I8042 23 depends on SERIO_I8042
24 depends on RFKILL 24 depends on RFKILL || RFKILL = n
25 select ACPI_WMI 25 select ACPI_WMI
26 ---help--- 26 ---help---
27 This is a driver for newer Acer (and Wistron) laptops. It adds 27 This is a driver for newer Acer (and Wistron) laptops. It adds
@@ -60,7 +60,7 @@ config DELL_LAPTOP
60 depends on DCDBAS 60 depends on DCDBAS
61 depends on EXPERIMENTAL 61 depends on EXPERIMENTAL
62 depends on BACKLIGHT_CLASS_DEVICE 62 depends on BACKLIGHT_CLASS_DEVICE
63 depends on RFKILL 63 depends on RFKILL || RFKILL = n
64 depends on POWER_SUPPLY 64 depends on POWER_SUPPLY
65 default n 65 default n
66 ---help--- 66 ---help---
@@ -117,7 +117,7 @@ config HP_WMI
117 tristate "HP WMI extras" 117 tristate "HP WMI extras"
118 depends on ACPI_WMI 118 depends on ACPI_WMI
119 depends on INPUT 119 depends on INPUT
120 depends on RFKILL 120 depends on RFKILL || RFKILL = n
121 help 121 help
122 Say Y here if you want to support WMI-based hotkeys on HP laptops and 122 Say Y here if you want to support WMI-based hotkeys on HP laptops and
123 to read data from WMI such as docking or ambient light sensor state. 123 to read data from WMI such as docking or ambient light sensor state.
@@ -196,14 +196,13 @@ config THINKPAD_ACPI
196 tristate "ThinkPad ACPI Laptop Extras" 196 tristate "ThinkPad ACPI Laptop Extras"
197 depends on ACPI 197 depends on ACPI
198 depends on INPUT 198 depends on INPUT
199 depends on RFKILL || RFKILL = n
199 select BACKLIGHT_LCD_SUPPORT 200 select BACKLIGHT_LCD_SUPPORT
200 select BACKLIGHT_CLASS_DEVICE 201 select BACKLIGHT_CLASS_DEVICE
201 select HWMON 202 select HWMON
202 select NVRAM 203 select NVRAM
203 select NEW_LEDS 204 select NEW_LEDS
204 select LEDS_CLASS 205 select LEDS_CLASS
205 select NET
206 select RFKILL
207 ---help--- 206 ---help---
208 This is a driver for the IBM and Lenovo ThinkPad laptops. It adds 207 This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
209 support for Fn-Fx key combinations, Bluetooth control, video 208 support for Fn-Fx key combinations, Bluetooth control, video
@@ -338,9 +337,9 @@ config EEEPC_LAPTOP
338 depends on ACPI 337 depends on ACPI
339 depends on INPUT 338 depends on INPUT
340 depends on EXPERIMENTAL 339 depends on EXPERIMENTAL
340 depends on RFKILL || RFKILL = n
341 select BACKLIGHT_CLASS_DEVICE 341 select BACKLIGHT_CLASS_DEVICE
342 select HWMON 342 select HWMON
343 select RFKILL
344 ---help--- 343 ---help---
345 This driver supports the Fn-Fx keys on Eee PC laptops. 344 This driver supports the Fn-Fx keys on Eee PC laptops.
346 It also adds the ability to switch camera/wlan on/off. 345 It also adds the ability to switch camera/wlan on/off.
@@ -405,9 +404,8 @@ config ACPI_TOSHIBA
405 tristate "Toshiba Laptop Extras" 404 tristate "Toshiba Laptop Extras"
406 depends on ACPI 405 depends on ACPI
407 depends on INPUT 406 depends on INPUT
407 depends on RFKILL || RFKILL = n
408 select INPUT_POLLDEV 408 select INPUT_POLLDEV
409 select NET
410 select RFKILL
411 select BACKLIGHT_CLASS_DEVICE 409 select BACKLIGHT_CLASS_DEVICE
412 ---help--- 410 ---help---
413 This driver adds support for access to certain system settings 411 This driver adds support for access to certain system settings
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 62d02b3c998e..b618fa51db2d 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -958,58 +958,50 @@ static void acer_rfkill_update(struct work_struct *ignored)
958 958
959 status = get_u32(&state, ACER_CAP_WIRELESS); 959 status = get_u32(&state, ACER_CAP_WIRELESS);
960 if (ACPI_SUCCESS(status)) 960 if (ACPI_SUCCESS(status))
961 rfkill_force_state(wireless_rfkill, state ? 961 rfkill_set_sw_state(wireless_rfkill, !!state);
962 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED);
963 962
964 if (has_cap(ACER_CAP_BLUETOOTH)) { 963 if (has_cap(ACER_CAP_BLUETOOTH)) {
965 status = get_u32(&state, ACER_CAP_BLUETOOTH); 964 status = get_u32(&state, ACER_CAP_BLUETOOTH);
966 if (ACPI_SUCCESS(status)) 965 if (ACPI_SUCCESS(status))
967 rfkill_force_state(bluetooth_rfkill, state ? 966 rfkill_set_sw_state(bluetooth_rfkill, !!state);
968 RFKILL_STATE_UNBLOCKED :
969 RFKILL_STATE_SOFT_BLOCKED);
970 } 967 }
971 968
972 schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); 969 schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
973} 970}
974 971
975static int acer_rfkill_set(void *data, enum rfkill_state state) 972static int acer_rfkill_set(void *data, bool blocked)
976{ 973{
977 acpi_status status; 974 acpi_status status;
978 u32 *cap = data; 975 u32 cap = (unsigned long)data;
979 status = set_u32((u32) (state == RFKILL_STATE_UNBLOCKED), *cap); 976 status = set_u32(!!blocked, cap);
980 if (ACPI_FAILURE(status)) 977 if (ACPI_FAILURE(status))
981 return -ENODEV; 978 return -ENODEV;
982 return 0; 979 return 0;
983} 980}
984 981
985static struct rfkill * acer_rfkill_register(struct device *dev, 982static const struct rfkill_ops acer_rfkill_ops = {
986enum rfkill_type type, char *name, u32 cap) 983 .set_block = acer_rfkill_set,
984};
985
986static struct rfkill *acer_rfkill_register(struct device *dev,
987 enum rfkill_type type,
988 char *name, u32 cap)
987{ 989{
988 int err; 990 int err;
989 u32 state; 991 u32 state;
990 u32 *data;
991 struct rfkill *rfkill_dev; 992 struct rfkill *rfkill_dev;
992 993
993 rfkill_dev = rfkill_allocate(dev, type); 994 rfkill_dev = rfkill_alloc(name, dev, type,
995 &acer_rfkill_ops,
996 (void *)(unsigned long)cap);
994 if (!rfkill_dev) 997 if (!rfkill_dev)
995 return ERR_PTR(-ENOMEM); 998 return ERR_PTR(-ENOMEM);
996 rfkill_dev->name = name;
997 get_u32(&state, cap); 999 get_u32(&state, cap);
998 rfkill_dev->state = state ? RFKILL_STATE_UNBLOCKED : 1000 rfkill_set_sw_state(rfkill_dev, !state);
999 RFKILL_STATE_SOFT_BLOCKED;
1000 data = kzalloc(sizeof(u32), GFP_KERNEL);
1001 if (!data) {
1002 rfkill_free(rfkill_dev);
1003 return ERR_PTR(-ENOMEM);
1004 }
1005 *data = cap;
1006 rfkill_dev->data = data;
1007 rfkill_dev->toggle_radio = acer_rfkill_set;
1008 1001
1009 err = rfkill_register(rfkill_dev); 1002 err = rfkill_register(rfkill_dev);
1010 if (err) { 1003 if (err) {
1011 kfree(rfkill_dev->data); 1004 rfkill_destroy(rfkill_dev);
1012 rfkill_free(rfkill_dev);
1013 return ERR_PTR(err); 1005 return ERR_PTR(err);
1014 } 1006 }
1015 return rfkill_dev; 1007 return rfkill_dev;
@@ -1027,8 +1019,8 @@ static int acer_rfkill_init(struct device *dev)
1027 RFKILL_TYPE_BLUETOOTH, "acer-bluetooth", 1019 RFKILL_TYPE_BLUETOOTH, "acer-bluetooth",
1028 ACER_CAP_BLUETOOTH); 1020 ACER_CAP_BLUETOOTH);
1029 if (IS_ERR(bluetooth_rfkill)) { 1021 if (IS_ERR(bluetooth_rfkill)) {
1030 kfree(wireless_rfkill->data);
1031 rfkill_unregister(wireless_rfkill); 1022 rfkill_unregister(wireless_rfkill);
1023 rfkill_destroy(wireless_rfkill);
1032 return PTR_ERR(bluetooth_rfkill); 1024 return PTR_ERR(bluetooth_rfkill);
1033 } 1025 }
1034 } 1026 }
@@ -1041,11 +1033,13 @@ static int acer_rfkill_init(struct device *dev)
1041static void acer_rfkill_exit(void) 1033static void acer_rfkill_exit(void)
1042{ 1034{
1043 cancel_delayed_work_sync(&acer_rfkill_work); 1035 cancel_delayed_work_sync(&acer_rfkill_work);
1044 kfree(wireless_rfkill->data); 1036
1045 rfkill_unregister(wireless_rfkill); 1037 rfkill_unregister(wireless_rfkill);
1038 rfkill_destroy(wireless_rfkill);
1039
1046 if (has_cap(ACER_CAP_BLUETOOTH)) { 1040 if (has_cap(ACER_CAP_BLUETOOTH)) {
1047 kfree(bluetooth_rfkill->data);
1048 rfkill_unregister(bluetooth_rfkill); 1041 rfkill_unregister(bluetooth_rfkill);
1042 rfkill_destroy(bluetooth_rfkill);
1049 } 1043 }
1050 return; 1044 return;
1051} 1045}
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index af9f43021172..2faf0e14f05a 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -174,10 +174,11 @@ dell_send_request(struct calling_interface_buffer *buffer, int class,
174 result[3]: NVRAM format version number 174 result[3]: NVRAM format version number
175*/ 175*/
176 176
177static int dell_rfkill_set(int radio, enum rfkill_state state) 177static int dell_rfkill_set(void *data, bool blocked)
178{ 178{
179 struct calling_interface_buffer buffer; 179 struct calling_interface_buffer buffer;
180 int disable = (state == RFKILL_STATE_UNBLOCKED) ? 0 : 1; 180 int disable = blocked ? 0 : 1;
181 unsigned long radio = (unsigned long)data;
181 182
182 memset(&buffer, 0, sizeof(struct calling_interface_buffer)); 183 memset(&buffer, 0, sizeof(struct calling_interface_buffer));
183 buffer.input[0] = (1 | (radio<<8) | (disable << 16)); 184 buffer.input[0] = (1 | (radio<<8) | (disable << 16));
@@ -186,56 +187,24 @@ static int dell_rfkill_set(int radio, enum rfkill_state state)
186 return 0; 187 return 0;
187} 188}
188 189
189static int dell_wifi_set(void *data, enum rfkill_state state) 190static void dell_rfkill_query(struct rfkill *rfkill, void *data)
190{
191 return dell_rfkill_set(1, state);
192}
193
194static int dell_bluetooth_set(void *data, enum rfkill_state state)
195{
196 return dell_rfkill_set(2, state);
197}
198
199static int dell_wwan_set(void *data, enum rfkill_state state)
200{
201 return dell_rfkill_set(3, state);
202}
203
204static int dell_rfkill_get(int bit, enum rfkill_state *state)
205{ 191{
206 struct calling_interface_buffer buffer; 192 struct calling_interface_buffer buffer;
207 int status; 193 int status;
208 int new_state = RFKILL_STATE_HARD_BLOCKED; 194 int bit = (unsigned long)data + 16;
209 195
210 memset(&buffer, 0, sizeof(struct calling_interface_buffer)); 196 memset(&buffer, 0, sizeof(struct calling_interface_buffer));
211 dell_send_request(&buffer, 17, 11); 197 dell_send_request(&buffer, 17, 11);
212 status = buffer.output[1]; 198 status = buffer.output[1];
213 199
214 if (status & (1<<16)) 200 if (status & BIT(bit))
215 new_state = RFKILL_STATE_SOFT_BLOCKED; 201 rfkill_set_hw_state(rfkill, !!(status & BIT(16)));
216
217 if (status & (1<<bit))
218 *state = new_state;
219 else
220 *state = RFKILL_STATE_UNBLOCKED;
221
222 return 0;
223}
224
225static int dell_wifi_get(void *data, enum rfkill_state *state)
226{
227 return dell_rfkill_get(17, state);
228}
229
230static int dell_bluetooth_get(void *data, enum rfkill_state *state)
231{
232 return dell_rfkill_get(18, state);
233} 202}
234 203
235static int dell_wwan_get(void *data, enum rfkill_state *state) 204static const struct rfkill_ops dell_rfkill_ops = {
236{ 205 .set_block = dell_rfkill_set,
237 return dell_rfkill_get(19, state); 206 .query = dell_rfkill_query,
238} 207};
239 208
240static int dell_setup_rfkill(void) 209static int dell_setup_rfkill(void)
241{ 210{
@@ -248,36 +217,37 @@ static int dell_setup_rfkill(void)
248 status = buffer.output[1]; 217 status = buffer.output[1];
249 218
250 if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) { 219 if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) {
251 wifi_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_WLAN); 220 wifi_rfkill = rfkill_alloc("dell-wifi", NULL, RFKILL_TYPE_WLAN,
252 if (!wifi_rfkill) 221 &dell_rfkill_ops, (void *) 1);
222 if (!wifi_rfkill) {
223 ret = -ENOMEM;
253 goto err_wifi; 224 goto err_wifi;
254 wifi_rfkill->name = "dell-wifi"; 225 }
255 wifi_rfkill->toggle_radio = dell_wifi_set;
256 wifi_rfkill->get_state = dell_wifi_get;
257 ret = rfkill_register(wifi_rfkill); 226 ret = rfkill_register(wifi_rfkill);
258 if (ret) 227 if (ret)
259 goto err_wifi; 228 goto err_wifi;
260 } 229 }
261 230
262 if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) { 231 if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) {
263 bluetooth_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_BLUETOOTH); 232 bluetooth_rfkill = rfkill_alloc("dell-bluetooth", NULL,
264 if (!bluetooth_rfkill) 233 RFKILL_TYPE_BLUETOOTH,
234 &dell_rfkill_ops, (void *) 2);
235 if (!bluetooth_rfkill) {
236 ret = -ENOMEM;
265 goto err_bluetooth; 237 goto err_bluetooth;
266 bluetooth_rfkill->name = "dell-bluetooth"; 238 }
267 bluetooth_rfkill->toggle_radio = dell_bluetooth_set;
268 bluetooth_rfkill->get_state = dell_bluetooth_get;
269 ret = rfkill_register(bluetooth_rfkill); 239 ret = rfkill_register(bluetooth_rfkill);
270 if (ret) 240 if (ret)
271 goto err_bluetooth; 241 goto err_bluetooth;
272 } 242 }
273 243
274 if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) { 244 if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) {
275 wwan_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_WWAN); 245 wwan_rfkill = rfkill_alloc("dell-wwan", NULL, RFKILL_TYPE_WWAN,
276 if (!wwan_rfkill) 246 &dell_rfkill_ops, (void *) 3);
247 if (!wwan_rfkill) {
248 ret = -ENOMEM;
277 goto err_wwan; 249 goto err_wwan;
278 wwan_rfkill->name = "dell-wwan"; 250 }
279 wwan_rfkill->toggle_radio = dell_wwan_set;
280 wwan_rfkill->get_state = dell_wwan_get;
281 ret = rfkill_register(wwan_rfkill); 251 ret = rfkill_register(wwan_rfkill);
282 if (ret) 252 if (ret)
283 goto err_wwan; 253 goto err_wwan;
@@ -285,22 +255,15 @@ static int dell_setup_rfkill(void)
285 255
286 return 0; 256 return 0;
287err_wwan: 257err_wwan:
288 if (wwan_rfkill) 258 rfkill_destroy(wwan_rfkill);
289 rfkill_free(wwan_rfkill); 259 if (bluetooth_rfkill)
290 if (bluetooth_rfkill) {
291 rfkill_unregister(bluetooth_rfkill); 260 rfkill_unregister(bluetooth_rfkill);
292 bluetooth_rfkill = NULL;
293 }
294err_bluetooth: 261err_bluetooth:
295 if (bluetooth_rfkill) 262 rfkill_destroy(bluetooth_rfkill);
296 rfkill_free(bluetooth_rfkill); 263 if (wifi_rfkill)
297 if (wifi_rfkill) {
298 rfkill_unregister(wifi_rfkill); 264 rfkill_unregister(wifi_rfkill);
299 wifi_rfkill = NULL;
300 }
301err_wifi: 265err_wifi:
302 if (wifi_rfkill) 266 rfkill_destroy(wifi_rfkill);
303 rfkill_free(wifi_rfkill);
304 267
305 return ret; 268 return ret;
306} 269}
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 353a898c3693..1208d0cedd15 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -299,39 +299,22 @@ static int update_bl_status(struct backlight_device *bd)
299 * Rfkill helpers 299 * Rfkill helpers
300 */ 300 */
301 301
302static int eeepc_wlan_rfkill_set(void *data, enum rfkill_state state) 302static bool eeepc_wlan_rfkill_blocked(void)
303{
304 if (state == RFKILL_STATE_SOFT_BLOCKED)
305 return set_acpi(CM_ASL_WLAN, 0);
306 else
307 return set_acpi(CM_ASL_WLAN, 1);
308}
309
310static int eeepc_wlan_rfkill_state(void *data, enum rfkill_state *state)
311{ 303{
312 if (get_acpi(CM_ASL_WLAN) == 1) 304 if (get_acpi(CM_ASL_WLAN) == 1)
313 *state = RFKILL_STATE_UNBLOCKED; 305 return false;
314 else 306 return true;
315 *state = RFKILL_STATE_SOFT_BLOCKED;
316 return 0;
317} 307}
318 308
319static int eeepc_bluetooth_rfkill_set(void *data, enum rfkill_state state) 309static int eeepc_rfkill_set(void *data, bool blocked)
320{ 310{
321 if (state == RFKILL_STATE_SOFT_BLOCKED) 311 unsigned long asl = (unsigned long)data;
322 return set_acpi(CM_ASL_BLUETOOTH, 0); 312 return set_acpi(asl, !blocked);
323 else
324 return set_acpi(CM_ASL_BLUETOOTH, 1);
325} 313}
326 314
327static int eeepc_bluetooth_rfkill_state(void *data, enum rfkill_state *state) 315static const struct rfkill_ops eeepc_rfkill_ops = {
328{ 316 .set_block = eeepc_rfkill_set,
329 if (get_acpi(CM_ASL_BLUETOOTH) == 1) 317};
330 *state = RFKILL_STATE_UNBLOCKED;
331 else
332 *state = RFKILL_STATE_SOFT_BLOCKED;
333 return 0;
334}
335 318
336/* 319/*
337 * Sys helpers 320 * Sys helpers
@@ -531,9 +514,9 @@ static int notify_brn(void)
531 514
532static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) 515static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
533{ 516{
534 enum rfkill_state state;
535 struct pci_dev *dev; 517 struct pci_dev *dev;
536 struct pci_bus *bus = pci_find_bus(0, 1); 518 struct pci_bus *bus = pci_find_bus(0, 1);
519 bool blocked;
537 520
538 if (event != ACPI_NOTIFY_BUS_CHECK) 521 if (event != ACPI_NOTIFY_BUS_CHECK)
539 return; 522 return;
@@ -543,9 +526,8 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
543 return; 526 return;
544 } 527 }
545 528
546 eeepc_wlan_rfkill_state(ehotk->eeepc_wlan_rfkill, &state); 529 blocked = eeepc_wlan_rfkill_blocked();
547 530 if (!blocked) {
548 if (state == RFKILL_STATE_UNBLOCKED) {
549 dev = pci_get_slot(bus, 0); 531 dev = pci_get_slot(bus, 0);
550 if (dev) { 532 if (dev) {
551 /* Device already present */ 533 /* Device already present */
@@ -566,7 +548,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
566 } 548 }
567 } 549 }
568 550
569 rfkill_force_state(ehotk->eeepc_wlan_rfkill, state); 551 rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked);
570} 552}
571 553
572static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data) 554static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
@@ -684,26 +666,17 @@ static int eeepc_hotk_add(struct acpi_device *device)
684 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); 666 eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
685 667
686 if (get_acpi(CM_ASL_WLAN) != -1) { 668 if (get_acpi(CM_ASL_WLAN) != -1) {
687 ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev, 669 ehotk->eeepc_wlan_rfkill = rfkill_alloc("eeepc-wlan",
688 RFKILL_TYPE_WLAN); 670 &device->dev,
671 RFKILL_TYPE_WLAN,
672 &eeepc_rfkill_ops,
673 (void *)CM_ASL_WLAN);
689 674
690 if (!ehotk->eeepc_wlan_rfkill) 675 if (!ehotk->eeepc_wlan_rfkill)
691 goto wlan_fail; 676 goto wlan_fail;
692 677
693 ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan"; 678 rfkill_set_global_sw_state(RFKILL_TYPE_WLAN,
694 ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set; 679 get_acpi(CM_ASL_WLAN) != 1);
695 ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state;
696 if (get_acpi(CM_ASL_WLAN) == 1) {
697 ehotk->eeepc_wlan_rfkill->state =
698 RFKILL_STATE_UNBLOCKED;
699 rfkill_set_default(RFKILL_TYPE_WLAN,
700 RFKILL_STATE_UNBLOCKED);
701 } else {
702 ehotk->eeepc_wlan_rfkill->state =
703 RFKILL_STATE_SOFT_BLOCKED;
704 rfkill_set_default(RFKILL_TYPE_WLAN,
705 RFKILL_STATE_SOFT_BLOCKED);
706 }
707 result = rfkill_register(ehotk->eeepc_wlan_rfkill); 680 result = rfkill_register(ehotk->eeepc_wlan_rfkill);
708 if (result) 681 if (result)
709 goto wlan_fail; 682 goto wlan_fail;
@@ -711,28 +684,17 @@ static int eeepc_hotk_add(struct acpi_device *device)
711 684
712 if (get_acpi(CM_ASL_BLUETOOTH) != -1) { 685 if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
713 ehotk->eeepc_bluetooth_rfkill = 686 ehotk->eeepc_bluetooth_rfkill =
714 rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH); 687 rfkill_alloc("eeepc-bluetooth",
688 &device->dev,
689 RFKILL_TYPE_BLUETOOTH,
690 &eeepc_rfkill_ops,
691 (void *)CM_ASL_BLUETOOTH);
715 692
716 if (!ehotk->eeepc_bluetooth_rfkill) 693 if (!ehotk->eeepc_bluetooth_rfkill)
717 goto bluetooth_fail; 694 goto bluetooth_fail;
718 695
719 ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth"; 696 rfkill_set_global_sw_state(RFKILL_TYPE_BLUETOOTH,
720 ehotk->eeepc_bluetooth_rfkill->toggle_radio = 697 get_acpi(CM_ASL_BLUETOOTH) != 1);
721 eeepc_bluetooth_rfkill_set;
722 ehotk->eeepc_bluetooth_rfkill->get_state =
723 eeepc_bluetooth_rfkill_state;
724 if (get_acpi(CM_ASL_BLUETOOTH) == 1) {
725 ehotk->eeepc_bluetooth_rfkill->state =
726 RFKILL_STATE_UNBLOCKED;
727 rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
728 RFKILL_STATE_UNBLOCKED);
729 } else {
730 ehotk->eeepc_bluetooth_rfkill->state =
731 RFKILL_STATE_SOFT_BLOCKED;
732 rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
733 RFKILL_STATE_SOFT_BLOCKED);
734 }
735
736 result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); 698 result = rfkill_register(ehotk->eeepc_bluetooth_rfkill);
737 if (result) 699 if (result)
738 goto bluetooth_fail; 700 goto bluetooth_fail;
@@ -741,13 +703,10 @@ static int eeepc_hotk_add(struct acpi_device *device)
741 return 0; 703 return 0;
742 704
743 bluetooth_fail: 705 bluetooth_fail:
744 if (ehotk->eeepc_bluetooth_rfkill) 706 rfkill_destroy(ehotk->eeepc_bluetooth_rfkill);
745 rfkill_free(ehotk->eeepc_bluetooth_rfkill);
746 rfkill_unregister(ehotk->eeepc_wlan_rfkill); 707 rfkill_unregister(ehotk->eeepc_wlan_rfkill);
747 ehotk->eeepc_wlan_rfkill = NULL;
748 wlan_fail: 708 wlan_fail:
749 if (ehotk->eeepc_wlan_rfkill) 709 rfkill_destroy(ehotk->eeepc_wlan_rfkill);
750 rfkill_free(ehotk->eeepc_wlan_rfkill);
751 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); 710 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
752 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); 711 eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
753 ehotk_fail: 712 ehotk_fail:
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index fe171fad12cf..8d931145cbfa 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -154,58 +154,46 @@ static int hp_wmi_dock_state(void)
154 return hp_wmi_perform_query(HPWMI_DOCK_QUERY, 0, 0); 154 return hp_wmi_perform_query(HPWMI_DOCK_QUERY, 0, 0);
155} 155}
156 156
157static int hp_wmi_wifi_set(void *data, enum rfkill_state state) 157static int hp_wmi_set_block(void *data, bool blocked)
158{ 158{
159 if (state) 159 unsigned long b = (unsigned long) data;
160 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x101); 160 int query = BIT(b + 8) | ((!!blocked) << b);
161 else
162 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x100);
163}
164 161
165static int hp_wmi_bluetooth_set(void *data, enum rfkill_state state) 162 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, query);
166{
167 if (state)
168 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x202);
169 else
170 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x200);
171} 163}
172 164
173static int hp_wmi_wwan_set(void *data, enum rfkill_state state) 165static const struct rfkill_ops hp_wmi_rfkill_ops = {
174{ 166 .set_block = hp_wmi_set_block,
175 if (state) 167};
176 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x404);
177 else
178 return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x400);
179}
180 168
181static int hp_wmi_wifi_state(void) 169static bool hp_wmi_wifi_state(void)
182{ 170{
183 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); 171 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
184 172
185 if (wireless & 0x100) 173 if (wireless & 0x100)
186 return RFKILL_STATE_UNBLOCKED; 174 return false;
187 else 175 else
188 return RFKILL_STATE_SOFT_BLOCKED; 176 return true;
189} 177}
190 178
191static int hp_wmi_bluetooth_state(void) 179static bool hp_wmi_bluetooth_state(void)
192{ 180{
193 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); 181 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
194 182
195 if (wireless & 0x10000) 183 if (wireless & 0x10000)
196 return RFKILL_STATE_UNBLOCKED; 184 return false;
197 else 185 else
198 return RFKILL_STATE_SOFT_BLOCKED; 186 return true;
199} 187}
200 188
201static int hp_wmi_wwan_state(void) 189static bool hp_wmi_wwan_state(void)
202{ 190{
203 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0); 191 int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
204 192
205 if (wireless & 0x1000000) 193 if (wireless & 0x1000000)
206 return RFKILL_STATE_UNBLOCKED; 194 return false;
207 else 195 else
208 return RFKILL_STATE_SOFT_BLOCKED; 196 return true;
209} 197}
210 198
211static ssize_t show_display(struct device *dev, struct device_attribute *attr, 199static ssize_t show_display(struct device *dev, struct device_attribute *attr,
@@ -347,14 +335,14 @@ static void hp_wmi_notify(u32 value, void *context)
347 } 335 }
348 } else if (eventcode == 0x5) { 336 } else if (eventcode == 0x5) {
349 if (wifi_rfkill) 337 if (wifi_rfkill)
350 rfkill_force_state(wifi_rfkill, 338 rfkill_set_sw_state(wifi_rfkill,
351 hp_wmi_wifi_state()); 339 hp_wmi_wifi_state());
352 if (bluetooth_rfkill) 340 if (bluetooth_rfkill)
353 rfkill_force_state(bluetooth_rfkill, 341 rfkill_set_sw_state(bluetooth_rfkill,
354 hp_wmi_bluetooth_state()); 342 hp_wmi_bluetooth_state());
355 if (wwan_rfkill) 343 if (wwan_rfkill)
356 rfkill_force_state(wwan_rfkill, 344 rfkill_set_sw_state(wwan_rfkill,
357 hp_wmi_wwan_state()); 345 hp_wmi_wwan_state());
358 } else 346 } else
359 printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n", 347 printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n",
360 eventcode); 348 eventcode);
@@ -430,31 +418,34 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
430 goto add_sysfs_error; 418 goto add_sysfs_error;
431 419
432 if (wireless & 0x1) { 420 if (wireless & 0x1) {
433 wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN); 421 wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev,
434 wifi_rfkill->name = "hp-wifi"; 422 RFKILL_TYPE_WLAN,
435 wifi_rfkill->state = hp_wmi_wifi_state(); 423 &hp_wmi_rfkill_ops,
436 wifi_rfkill->toggle_radio = hp_wmi_wifi_set; 424 (void *) 0);
425 rfkill_set_sw_state(wifi_rfkill, hp_wmi_wifi_state());
437 err = rfkill_register(wifi_rfkill); 426 err = rfkill_register(wifi_rfkill);
438 if (err) 427 if (err)
439 goto add_sysfs_error; 428 goto register_wifi_error;
440 } 429 }
441 430
442 if (wireless & 0x2) { 431 if (wireless & 0x2) {
443 bluetooth_rfkill = rfkill_allocate(&device->dev, 432 bluetooth_rfkill = rfkill_alloc("hp-bluetooth", &device->dev,
444 RFKILL_TYPE_BLUETOOTH); 433 RFKILL_TYPE_BLUETOOTH,
445 bluetooth_rfkill->name = "hp-bluetooth"; 434 &hp_wmi_rfkill_ops,
446 bluetooth_rfkill->state = hp_wmi_bluetooth_state(); 435 (void *) 1);
447 bluetooth_rfkill->toggle_radio = hp_wmi_bluetooth_set; 436 rfkill_set_sw_state(bluetooth_rfkill,
437 hp_wmi_bluetooth_state());
448 err = rfkill_register(bluetooth_rfkill); 438 err = rfkill_register(bluetooth_rfkill);
449 if (err) 439 if (err)
450 goto register_bluetooth_error; 440 goto register_bluetooth_error;
451 } 441 }
452 442
453 if (wireless & 0x4) { 443 if (wireless & 0x4) {
454 wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN); 444 wwan_rfkill = rfkill_alloc("hp-wwan", &device->dev,
455 wwan_rfkill->name = "hp-wwan"; 445 RFKILL_TYPE_WWAN,
456 wwan_rfkill->state = hp_wmi_wwan_state(); 446 &hp_wmi_rfkill_ops,
457 wwan_rfkill->toggle_radio = hp_wmi_wwan_set; 447 (void *) 2);
448 rfkill_set_sw_state(wwan_rfkill, hp_wmi_wwan_state());
458 err = rfkill_register(wwan_rfkill); 449 err = rfkill_register(wwan_rfkill);
459 if (err) 450 if (err)
460 goto register_wwan_err; 451 goto register_wwan_err;
@@ -462,11 +453,15 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
462 453
463 return 0; 454 return 0;
464register_wwan_err: 455register_wwan_err:
456 rfkill_destroy(wwan_rfkill);
465 if (bluetooth_rfkill) 457 if (bluetooth_rfkill)
466 rfkill_unregister(bluetooth_rfkill); 458 rfkill_unregister(bluetooth_rfkill);
467register_bluetooth_error: 459register_bluetooth_error:
460 rfkill_destroy(bluetooth_rfkill);
468 if (wifi_rfkill) 461 if (wifi_rfkill)
469 rfkill_unregister(wifi_rfkill); 462 rfkill_unregister(wifi_rfkill);
463register_wifi_error:
464 rfkill_destroy(wifi_rfkill);
470add_sysfs_error: 465add_sysfs_error:
471 cleanup_sysfs(device); 466 cleanup_sysfs(device);
472 return err; 467 return err;
@@ -476,12 +471,18 @@ static int __exit hp_wmi_bios_remove(struct platform_device *device)
476{ 471{
477 cleanup_sysfs(device); 472 cleanup_sysfs(device);
478 473
479 if (wifi_rfkill) 474 if (wifi_rfkill) {
480 rfkill_unregister(wifi_rfkill); 475 rfkill_unregister(wifi_rfkill);
481 if (bluetooth_rfkill) 476 rfkill_destroy(wifi_rfkill);
477 }
478 if (bluetooth_rfkill) {
482 rfkill_unregister(bluetooth_rfkill); 479 rfkill_unregister(bluetooth_rfkill);
483 if (wwan_rfkill) 480 rfkill_destroy(wifi_rfkill);
481 }
482 if (wwan_rfkill) {
484 rfkill_unregister(wwan_rfkill); 483 rfkill_unregister(wwan_rfkill);
484 rfkill_destroy(wwan_rfkill);
485 }
485 486
486 return 0; 487 return 0;
487} 488}
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index f1963b05175b..aec0b27fd774 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -128,11 +128,11 @@ enum sony_nc_rfkill {
128 SONY_BLUETOOTH, 128 SONY_BLUETOOTH,
129 SONY_WWAN, 129 SONY_WWAN,
130 SONY_WIMAX, 130 SONY_WIMAX,
131 SONY_RFKILL_MAX, 131 N_SONY_RFKILL,
132}; 132};
133 133
134static struct rfkill *sony_rfkill_devices[SONY_RFKILL_MAX]; 134static struct rfkill *sony_rfkill_devices[N_SONY_RFKILL];
135static int sony_rfkill_address[SONY_RFKILL_MAX] = {0x300, 0x500, 0x700, 0x900}; 135static int sony_rfkill_address[N_SONY_RFKILL] = {0x300, 0x500, 0x700, 0x900};
136static void sony_nc_rfkill_update(void); 136static void sony_nc_rfkill_update(void);
137 137
138/*********** Input Devices ***********/ 138/*********** Input Devices ***********/
@@ -1051,147 +1051,98 @@ static void sony_nc_rfkill_cleanup(void)
1051{ 1051{
1052 int i; 1052 int i;
1053 1053
1054 for (i = 0; i < SONY_RFKILL_MAX; i++) { 1054 for (i = 0; i < N_SONY_RFKILL; i++) {
1055 if (sony_rfkill_devices[i]) 1055 if (sony_rfkill_devices[i]) {
1056 rfkill_unregister(sony_rfkill_devices[i]); 1056 rfkill_unregister(sony_rfkill_devices[i]);
1057 rfkill_destroy(sony_rfkill_devices[i]);
1058 }
1057 } 1059 }
1058} 1060}
1059 1061
1060static int sony_nc_rfkill_get(void *data, enum rfkill_state *state) 1062static int sony_nc_rfkill_set(void *data, bool blocked)
1061{
1062 int result;
1063 int argument = sony_rfkill_address[(long) data];
1064
1065 sony_call_snc_handle(0x124, 0x200, &result);
1066 if (result & 0x1) {
1067 sony_call_snc_handle(0x124, argument, &result);
1068 if (result & 0xf)
1069 *state = RFKILL_STATE_UNBLOCKED;
1070 else
1071 *state = RFKILL_STATE_SOFT_BLOCKED;
1072 } else {
1073 *state = RFKILL_STATE_HARD_BLOCKED;
1074 }
1075
1076 return 0;
1077}
1078
1079static int sony_nc_rfkill_set(void *data, enum rfkill_state state)
1080{ 1063{
1081 int result; 1064 int result;
1082 int argument = sony_rfkill_address[(long) data] + 0x100; 1065 int argument = sony_rfkill_address[(long) data] + 0x100;
1083 1066
1084 if (state == RFKILL_STATE_UNBLOCKED) 1067 if (!blocked)
1085 argument |= 0xff0000; 1068 argument |= 0xff0000;
1086 1069
1087 return sony_call_snc_handle(0x124, argument, &result); 1070 return sony_call_snc_handle(0x124, argument, &result);
1088} 1071}
1089 1072
1090static int sony_nc_setup_wifi_rfkill(struct acpi_device *device) 1073static const struct rfkill_ops sony_rfkill_ops = {
1091{ 1074 .set_block = sony_nc_rfkill_set,
1092 int err = 0; 1075};
1093 struct rfkill *sony_wifi_rfkill;
1094
1095 sony_wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN);
1096 if (!sony_wifi_rfkill)
1097 return -1;
1098 sony_wifi_rfkill->name = "sony-wifi";
1099 sony_wifi_rfkill->toggle_radio = sony_nc_rfkill_set;
1100 sony_wifi_rfkill->get_state = sony_nc_rfkill_get;
1101 sony_wifi_rfkill->data = (void *)SONY_WIFI;
1102 err = rfkill_register(sony_wifi_rfkill);
1103 if (err)
1104 rfkill_free(sony_wifi_rfkill);
1105 else {
1106 sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill;
1107 sony_nc_rfkill_set(sony_wifi_rfkill->data,
1108 RFKILL_STATE_UNBLOCKED);
1109 }
1110 return err;
1111}
1112 1076
1113static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device) 1077static int sony_nc_setup_rfkill(struct acpi_device *device,
1078 enum sony_nc_rfkill nc_type)
1114{ 1079{
1115 int err = 0; 1080 int err = 0;
1116 struct rfkill *sony_bluetooth_rfkill; 1081 struct rfkill *rfk;
1117 1082 enum rfkill_type type;
1118 sony_bluetooth_rfkill = rfkill_allocate(&device->dev, 1083 const char *name;
1119 RFKILL_TYPE_BLUETOOTH); 1084
1120 if (!sony_bluetooth_rfkill) 1085 switch (nc_type) {
1121 return -1; 1086 case SONY_WIFI:
1122 sony_bluetooth_rfkill->name = "sony-bluetooth"; 1087 type = RFKILL_TYPE_WLAN;
1123 sony_bluetooth_rfkill->toggle_radio = sony_nc_rfkill_set; 1088 name = "sony-wifi";
1124 sony_bluetooth_rfkill->get_state = sony_nc_rfkill_get; 1089 break;
1125 sony_bluetooth_rfkill->data = (void *)SONY_BLUETOOTH; 1090 case SONY_BLUETOOTH:
1126 err = rfkill_register(sony_bluetooth_rfkill); 1091 type = RFKILL_TYPE_BLUETOOTH;
1127 if (err) 1092 name = "sony-bluetooth";
1128 rfkill_free(sony_bluetooth_rfkill); 1093 break;
1129 else { 1094 case SONY_WWAN:
1130 sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill; 1095 type = RFKILL_TYPE_WWAN;
1131 sony_nc_rfkill_set(sony_bluetooth_rfkill->data, 1096 name = "sony-wwan";
1132 RFKILL_STATE_UNBLOCKED); 1097 break;
1098 case SONY_WIMAX:
1099 type = RFKILL_TYPE_WIMAX;
1100 name = "sony-wimax";
1101 break;
1102 default:
1103 return -EINVAL;
1133 } 1104 }
1134 return err;
1135}
1136 1105
1137static int sony_nc_setup_wwan_rfkill(struct acpi_device *device) 1106 rfk = rfkill_alloc(name, &device->dev, type,
1138{ 1107 &sony_rfkill_ops, (void *)nc_type);
1139 int err = 0; 1108 if (!rfk)
1140 struct rfkill *sony_wwan_rfkill; 1109 return -ENOMEM;
1141 1110
1142 sony_wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN); 1111 err = rfkill_register(rfk);
1143 if (!sony_wwan_rfkill) 1112 if (err) {
1144 return -1; 1113 rfkill_destroy(rfk);
1145 sony_wwan_rfkill->name = "sony-wwan"; 1114 return err;
1146 sony_wwan_rfkill->toggle_radio = sony_nc_rfkill_set;
1147 sony_wwan_rfkill->get_state = sony_nc_rfkill_get;
1148 sony_wwan_rfkill->data = (void *)SONY_WWAN;
1149 err = rfkill_register(sony_wwan_rfkill);
1150 if (err)
1151 rfkill_free(sony_wwan_rfkill);
1152 else {
1153 sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill;
1154 sony_nc_rfkill_set(sony_wwan_rfkill->data,
1155 RFKILL_STATE_UNBLOCKED);
1156 } 1115 }
1116 sony_rfkill_devices[nc_type] = rfk;
1117 sony_nc_rfkill_set((void *)nc_type, false);
1157 return err; 1118 return err;
1158} 1119}
1159 1120
1160static int sony_nc_setup_wimax_rfkill(struct acpi_device *device) 1121static void sony_nc_rfkill_update()
1161{ 1122{
1162 int err = 0; 1123 enum sony_nc_rfkill i;
1163 struct rfkill *sony_wimax_rfkill; 1124 int result;
1125 bool hwblock;
1164 1126
1165 sony_wimax_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WIMAX); 1127 sony_call_snc_handle(0x124, 0x200, &result);
1166 if (!sony_wimax_rfkill) 1128 hwblock = !(result & 0x1);
1167 return -1;
1168 sony_wimax_rfkill->name = "sony-wimax";
1169 sony_wimax_rfkill->toggle_radio = sony_nc_rfkill_set;
1170 sony_wimax_rfkill->get_state = sony_nc_rfkill_get;
1171 sony_wimax_rfkill->data = (void *)SONY_WIMAX;
1172 err = rfkill_register(sony_wimax_rfkill);
1173 if (err)
1174 rfkill_free(sony_wimax_rfkill);
1175 else {
1176 sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill;
1177 sony_nc_rfkill_set(sony_wimax_rfkill->data,
1178 RFKILL_STATE_UNBLOCKED);
1179 }
1180 return err;
1181}
1182 1129
1183static void sony_nc_rfkill_update() 1130 for (i = 0; i < N_SONY_RFKILL; i++) {
1184{ 1131 int argument = sony_rfkill_address[i];
1185 int i;
1186 enum rfkill_state state;
1187 1132
1188 for (i = 0; i < SONY_RFKILL_MAX; i++) { 1133 if (!sony_rfkill_devices[i])
1189 if (sony_rfkill_devices[i]) { 1134 continue;
1190 sony_rfkill_devices[i]-> 1135
1191 get_state(sony_rfkill_devices[i]->data, 1136 if (hwblock) {
1192 &state); 1137 if (rfkill_set_hw_state(sony_rfkill_devices[i], true))
1193 rfkill_force_state(sony_rfkill_devices[i], state); 1138 sony_nc_rfkill_set(sony_rfkill_devices[i],
1139 true);
1140 continue;
1194 } 1141 }
1142
1143 sony_call_snc_handle(0x124, argument, &result);
1144 rfkill_set_states(sony_rfkill_devices[i],
1145 !(result & 0xf), false);
1195 } 1146 }
1196} 1147}
1197 1148
@@ -1210,13 +1161,13 @@ static int sony_nc_rfkill_setup(struct acpi_device *device)
1210 } 1161 }
1211 1162
1212 if (result & 0x1) 1163 if (result & 0x1)
1213 sony_nc_setup_wifi_rfkill(device); 1164 sony_nc_setup_rfkill(device, SONY_WIFI);
1214 if (result & 0x2) 1165 if (result & 0x2)
1215 sony_nc_setup_bluetooth_rfkill(device); 1166 sony_nc_setup_rfkill(device, SONY_BLUETOOTH);
1216 if (result & 0x1c) 1167 if (result & 0x1c)
1217 sony_nc_setup_wwan_rfkill(device); 1168 sony_nc_setup_rfkill(device, SONY_WWAN);
1218 if (result & 0x20) 1169 if (result & 0x20)
1219 sony_nc_setup_wimax_rfkill(device); 1170 sony_nc_setup_rfkill(device, SONY_WIMAX);
1220 1171
1221 return 0; 1172 return 0;
1222} 1173}
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 912be65b6261..cfcafa4e9473 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -166,13 +166,6 @@ enum {
166 166
167#define TPACPI_MAX_ACPI_ARGS 3 167#define TPACPI_MAX_ACPI_ARGS 3
168 168
169/* rfkill switches */
170enum {
171 TPACPI_RFK_BLUETOOTH_SW_ID = 0,
172 TPACPI_RFK_WWAN_SW_ID,
173 TPACPI_RFK_UWB_SW_ID,
174};
175
176/* printk headers */ 169/* printk headers */
177#define TPACPI_LOG TPACPI_FILE ": " 170#define TPACPI_LOG TPACPI_FILE ": "
178#define TPACPI_EMERG KERN_EMERG TPACPI_LOG 171#define TPACPI_EMERG KERN_EMERG TPACPI_LOG
@@ -1005,67 +998,237 @@ static int __init tpacpi_check_std_acpi_brightness_support(void)
1005 return 0; 998 return 0;
1006} 999}
1007 1000
1008static int __init tpacpi_new_rfkill(const unsigned int id, 1001static void printk_deprecated_attribute(const char * const what,
1009 struct rfkill **rfk, 1002 const char * const details)
1003{
1004 tpacpi_log_usertask("deprecated sysfs attribute");
1005 printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and "
1006 "will be removed. %s\n",
1007 what, details);
1008}
1009
1010/*************************************************************************
1011 * rfkill and radio control support helpers
1012 */
1013
1014/*
1015 * ThinkPad-ACPI firmware handling model:
1016 *
1017 * WLSW (master wireless switch) is event-driven, and is common to all
1018 * firmware-controlled radios. It cannot be controlled, just monitored,
1019 * as expected. It overrides all radio state in firmware
1020 *
1021 * The kernel, a masked-off hotkey, and WLSW can change the radio state
1022 * (TODO: verify how WLSW interacts with the returned radio state).
1023 *
1024 * The only time there are shadow radio state changes, is when
1025 * masked-off hotkeys are used.
1026 */
1027
1028/*
1029 * Internal driver API for radio state:
1030 *
1031 * int: < 0 = error, otherwise enum tpacpi_rfkill_state
1032 * bool: true means radio blocked (off)
1033 */
1034enum tpacpi_rfkill_state {
1035 TPACPI_RFK_RADIO_OFF = 0,
1036 TPACPI_RFK_RADIO_ON
1037};
1038
1039/* rfkill switches */
1040enum tpacpi_rfk_id {
1041 TPACPI_RFK_BLUETOOTH_SW_ID = 0,
1042 TPACPI_RFK_WWAN_SW_ID,
1043 TPACPI_RFK_UWB_SW_ID,
1044 TPACPI_RFK_SW_MAX
1045};
1046
1047static const char *tpacpi_rfkill_names[] = {
1048 [TPACPI_RFK_BLUETOOTH_SW_ID] = "bluetooth",
1049 [TPACPI_RFK_WWAN_SW_ID] = "wwan",
1050 [TPACPI_RFK_UWB_SW_ID] = "uwb",
1051 [TPACPI_RFK_SW_MAX] = NULL
1052};
1053
1054/* ThinkPad-ACPI rfkill subdriver */
1055struct tpacpi_rfk {
1056 struct rfkill *rfkill;
1057 enum tpacpi_rfk_id id;
1058 const struct tpacpi_rfk_ops *ops;
1059};
1060
1061struct tpacpi_rfk_ops {
1062 /* firmware interface */
1063 int (*get_status)(void);
1064 int (*set_status)(const enum tpacpi_rfkill_state);
1065};
1066
1067static struct tpacpi_rfk *tpacpi_rfkill_switches[TPACPI_RFK_SW_MAX];
1068
1069/* Query FW and update rfkill sw state for a given rfkill switch */
1070static int tpacpi_rfk_update_swstate(const struct tpacpi_rfk *tp_rfk)
1071{
1072 int status;
1073
1074 if (!tp_rfk)
1075 return -ENODEV;
1076
1077 status = (tp_rfk->ops->get_status)();
1078 if (status < 0)
1079 return status;
1080
1081 rfkill_set_sw_state(tp_rfk->rfkill,
1082 (status == TPACPI_RFK_RADIO_OFF));
1083
1084 return status;
1085}
1086
1087/* Query FW and update rfkill sw state for all rfkill switches */
1088static void tpacpi_rfk_update_swstate_all(void)
1089{
1090 unsigned int i;
1091
1092 for (i = 0; i < TPACPI_RFK_SW_MAX; i++)
1093 tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[i]);
1094}
1095
1096/*
1097 * Sync the HW-blocking state of all rfkill switches,
1098 * do notice it causes the rfkill core to schedule uevents
1099 */
1100static void tpacpi_rfk_update_hwblock_state(bool blocked)
1101{
1102 unsigned int i;
1103 struct tpacpi_rfk *tp_rfk;
1104
1105 for (i = 0; i < TPACPI_RFK_SW_MAX; i++) {
1106 tp_rfk = tpacpi_rfkill_switches[i];
1107 if (tp_rfk) {
1108 if (rfkill_set_hw_state(tp_rfk->rfkill,
1109 blocked)) {
1110 /* ignore -- we track sw block */
1111 }
1112 }
1113 }
1114}
1115
1116/* Call to get the WLSW state from the firmware */
1117static int hotkey_get_wlsw(void);
1118
1119/* Call to query WLSW state and update all rfkill switches */
1120static bool tpacpi_rfk_check_hwblock_state(void)
1121{
1122 int res = hotkey_get_wlsw();
1123 int hw_blocked;
1124
1125 /* When unknown or unsupported, we have to assume it is unblocked */
1126 if (res < 0)
1127 return false;
1128
1129 hw_blocked = (res == TPACPI_RFK_RADIO_OFF);
1130 tpacpi_rfk_update_hwblock_state(hw_blocked);
1131
1132 return hw_blocked;
1133}
1134
1135static int tpacpi_rfk_hook_set_block(void *data, bool blocked)
1136{
1137 struct tpacpi_rfk *tp_rfk = data;
1138 int res;
1139
1140 dbg_printk(TPACPI_DBG_RFKILL,
1141 "request to change radio state to %s\n",
1142 blocked ? "blocked" : "unblocked");
1143
1144 /* try to set radio state */
1145 res = (tp_rfk->ops->set_status)(blocked ?
1146 TPACPI_RFK_RADIO_OFF : TPACPI_RFK_RADIO_ON);
1147
1148 /* and update the rfkill core with whatever the FW really did */
1149 tpacpi_rfk_update_swstate(tp_rfk);
1150
1151 return (res < 0) ? res : 0;
1152}
1153
1154static const struct rfkill_ops tpacpi_rfk_rfkill_ops = {
1155 .set_block = tpacpi_rfk_hook_set_block,
1156};
1157
1158static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,
1159 const struct tpacpi_rfk_ops *tp_rfkops,
1010 const enum rfkill_type rfktype, 1160 const enum rfkill_type rfktype,
1011 const char *name, 1161 const char *name,
1012 const bool set_default, 1162 const bool set_default)
1013 int (*toggle_radio)(void *, enum rfkill_state),
1014 int (*get_state)(void *, enum rfkill_state *))
1015{ 1163{
1164 struct tpacpi_rfk *atp_rfk;
1016 int res; 1165 int res;
1017 enum rfkill_state initial_state = RFKILL_STATE_SOFT_BLOCKED; 1166 bool initial_sw_state = false;
1167 int initial_sw_status;
1018 1168
1019 res = get_state(NULL, &initial_state); 1169 BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]);
1020 if (res < 0) { 1170
1171 initial_sw_status = (tp_rfkops->get_status)();
1172 if (initial_sw_status < 0) {
1021 printk(TPACPI_ERR 1173 printk(TPACPI_ERR
1022 "failed to read initial state for %s, error %d; " 1174 "failed to read initial state for %s, error %d; "
1023 "will turn radio off\n", name, res); 1175 "will turn radio off\n", name, initial_sw_status);
1024 } else if (set_default) { 1176 } else {
1025 /* try to set the initial state as the default for the rfkill 1177 initial_sw_state = (initial_sw_status == TPACPI_RFK_RADIO_OFF);
1026 * type, since we ask the firmware to preserve it across S5 in 1178 if (set_default) {
1027 * NVRAM */ 1179 /* try to set the initial state as the default for the
1028 if (rfkill_set_default(rfktype, 1180 * rfkill type, since we ask the firmware to preserve
1029 (initial_state == RFKILL_STATE_UNBLOCKED) ? 1181 * it across S5 in NVRAM */
1030 RFKILL_STATE_UNBLOCKED : 1182 rfkill_set_global_sw_state(rfktype, initial_sw_state);
1031 RFKILL_STATE_SOFT_BLOCKED) == -EPERM) 1183 }
1032 vdbg_printk(TPACPI_DBG_RFKILL, 1184 }
1033 "Default state for %s cannot be changed\n", 1185
1034 name); 1186 atp_rfk = kzalloc(sizeof(struct tpacpi_rfk), GFP_KERNEL);
1035 } 1187 if (atp_rfk)
1036 1188 atp_rfk->rfkill = rfkill_alloc(name,
1037 *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype); 1189 &tpacpi_pdev->dev,
1038 if (!*rfk) { 1190 rfktype,
1191 &tpacpi_rfk_rfkill_ops,
1192 atp_rfk);
1193 if (!atp_rfk || !atp_rfk->rfkill) {
1039 printk(TPACPI_ERR 1194 printk(TPACPI_ERR
1040 "failed to allocate memory for rfkill class\n"); 1195 "failed to allocate memory for rfkill class\n");
1196 kfree(atp_rfk);
1041 return -ENOMEM; 1197 return -ENOMEM;
1042 } 1198 }
1043 1199
1044 (*rfk)->name = name; 1200 atp_rfk->id = id;
1045 (*rfk)->get_state = get_state; 1201 atp_rfk->ops = tp_rfkops;
1046 (*rfk)->toggle_radio = toggle_radio; 1202
1047 (*rfk)->state = initial_state; 1203 rfkill_set_states(atp_rfk->rfkill, initial_sw_state,
1204 tpacpi_rfk_check_hwblock_state());
1048 1205
1049 res = rfkill_register(*rfk); 1206 res = rfkill_register(atp_rfk->rfkill);
1050 if (res < 0) { 1207 if (res < 0) {
1051 printk(TPACPI_ERR 1208 printk(TPACPI_ERR
1052 "failed to register %s rfkill switch: %d\n", 1209 "failed to register %s rfkill switch: %d\n",
1053 name, res); 1210 name, res);
1054 rfkill_free(*rfk); 1211 rfkill_destroy(atp_rfk->rfkill);
1055 *rfk = NULL; 1212 kfree(atp_rfk);
1056 return res; 1213 return res;
1057 } 1214 }
1058 1215
1216 tpacpi_rfkill_switches[id] = atp_rfk;
1059 return 0; 1217 return 0;
1060} 1218}
1061 1219
1062static void printk_deprecated_attribute(const char * const what, 1220static void tpacpi_destroy_rfkill(const enum tpacpi_rfk_id id)
1063 const char * const details)
1064{ 1221{
1065 tpacpi_log_usertask("deprecated sysfs attribute"); 1222 struct tpacpi_rfk *tp_rfk;
1066 printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and " 1223
1067 "will be removed. %s\n", 1224 BUG_ON(id >= TPACPI_RFK_SW_MAX);
1068 what, details); 1225
1226 tp_rfk = tpacpi_rfkill_switches[id];
1227 if (tp_rfk) {
1228 rfkill_unregister(tp_rfk->rfkill);
1229 tpacpi_rfkill_switches[id] = NULL;
1230 kfree(tp_rfk);
1231 }
1069} 1232}
1070 1233
1071static void printk_deprecated_rfkill_attribute(const char * const what) 1234static void printk_deprecated_rfkill_attribute(const char * const what)
@@ -1074,6 +1237,112 @@ static void printk_deprecated_rfkill_attribute(const char * const what)
1074 "Please switch to generic rfkill before year 2010"); 1237 "Please switch to generic rfkill before year 2010");
1075} 1238}
1076 1239
1240/* sysfs <radio> enable ------------------------------------------------ */
1241static ssize_t tpacpi_rfk_sysfs_enable_show(const enum tpacpi_rfk_id id,
1242 struct device_attribute *attr,
1243 char *buf)
1244{
1245 int status;
1246
1247 printk_deprecated_rfkill_attribute(attr->attr.name);
1248
1249 /* This is in the ABI... */
1250 if (tpacpi_rfk_check_hwblock_state()) {
1251 status = TPACPI_RFK_RADIO_OFF;
1252 } else {
1253 status = tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);
1254 if (status < 0)
1255 return status;
1256 }
1257
1258 return snprintf(buf, PAGE_SIZE, "%d\n",
1259 (status == TPACPI_RFK_RADIO_ON) ? 1 : 0);
1260}
1261
1262static ssize_t tpacpi_rfk_sysfs_enable_store(const enum tpacpi_rfk_id id,
1263 struct device_attribute *attr,
1264 const char *buf, size_t count)
1265{
1266 unsigned long t;
1267 int res;
1268
1269 printk_deprecated_rfkill_attribute(attr->attr.name);
1270
1271 if (parse_strtoul(buf, 1, &t))
1272 return -EINVAL;
1273
1274 tpacpi_disclose_usertask(attr->attr.name, "set to %ld\n", t);
1275
1276 /* This is in the ABI... */
1277 if (tpacpi_rfk_check_hwblock_state() && !!t)
1278 return -EPERM;
1279
1280 res = tpacpi_rfkill_switches[id]->ops->set_status((!!t) ?
1281 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF);
1282 tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);
1283
1284 return (res < 0) ? res : count;
1285}
1286
1287/* procfs -------------------------------------------------------------- */
1288static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, char *p)
1289{
1290 int len = 0;
1291
1292 if (id >= TPACPI_RFK_SW_MAX)
1293 len += sprintf(p + len, "status:\t\tnot supported\n");
1294 else {
1295 int status;
1296
1297 /* This is in the ABI... */
1298 if (tpacpi_rfk_check_hwblock_state()) {
1299 status = TPACPI_RFK_RADIO_OFF;
1300 } else {
1301 status = tpacpi_rfk_update_swstate(
1302 tpacpi_rfkill_switches[id]);
1303 if (status < 0)
1304 return status;
1305 }
1306
1307 len += sprintf(p + len, "status:\t\t%s\n",
1308 (status == TPACPI_RFK_RADIO_ON) ?
1309 "enabled" : "disabled");
1310 len += sprintf(p + len, "commands:\tenable, disable\n");
1311 }
1312
1313 return len;
1314}
1315
1316static int tpacpi_rfk_procfs_write(const enum tpacpi_rfk_id id, char *buf)
1317{
1318 char *cmd;
1319 int status = -1;
1320 int res = 0;
1321
1322 if (id >= TPACPI_RFK_SW_MAX)
1323 return -ENODEV;
1324
1325 while ((cmd = next_cmd(&buf))) {
1326 if (strlencmp(cmd, "enable") == 0)
1327 status = TPACPI_RFK_RADIO_ON;
1328 else if (strlencmp(cmd, "disable") == 0)
1329 status = TPACPI_RFK_RADIO_OFF;
1330 else
1331 return -EINVAL;
1332 }
1333
1334 if (status != -1) {
1335 tpacpi_disclose_usertask("procfs", "attempt to %s %s\n",
1336 (status == TPACPI_RFK_RADIO_ON) ?
1337 "enable" : "disable",
1338 tpacpi_rfkill_names[id]);
1339 res = (tpacpi_rfkill_switches[id]->ops->set_status)(status);
1340 tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);
1341 }
1342
1343 return res;
1344}
1345
1077/************************************************************************* 1346/*************************************************************************
1078 * thinkpad-acpi driver attributes 1347 * thinkpad-acpi driver attributes
1079 */ 1348 */
@@ -1127,8 +1396,6 @@ static DRIVER_ATTR(version, S_IRUGO,
1127 1396
1128#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 1397#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
1129 1398
1130static void tpacpi_send_radiosw_update(void);
1131
1132/* wlsw_emulstate ------------------------------------------------------ */ 1399/* wlsw_emulstate ------------------------------------------------------ */
1133static ssize_t tpacpi_driver_wlsw_emulstate_show(struct device_driver *drv, 1400static ssize_t tpacpi_driver_wlsw_emulstate_show(struct device_driver *drv,
1134 char *buf) 1401 char *buf)
@@ -1144,11 +1411,10 @@ static ssize_t tpacpi_driver_wlsw_emulstate_store(struct device_driver *drv,
1144 if (parse_strtoul(buf, 1, &t)) 1411 if (parse_strtoul(buf, 1, &t))
1145 return -EINVAL; 1412 return -EINVAL;
1146 1413
1147 if (tpacpi_wlsw_emulstate != t) { 1414 if (tpacpi_wlsw_emulstate != !!t) {
1148 tpacpi_wlsw_emulstate = !!t;
1149 tpacpi_send_radiosw_update();
1150 } else
1151 tpacpi_wlsw_emulstate = !!t; 1415 tpacpi_wlsw_emulstate = !!t;
1416 tpacpi_rfk_update_hwblock_state(!t); /* negative logic */
1417 }
1152 1418
1153 return count; 1419 return count;
1154} 1420}
@@ -1463,17 +1729,23 @@ static struct attribute_set *hotkey_dev_attributes;
1463/* HKEY.MHKG() return bits */ 1729/* HKEY.MHKG() return bits */
1464#define TP_HOTKEY_TABLET_MASK (1 << 3) 1730#define TP_HOTKEY_TABLET_MASK (1 << 3)
1465 1731
1466static int hotkey_get_wlsw(int *status) 1732static int hotkey_get_wlsw(void)
1467{ 1733{
1734 int status;
1735
1736 if (!tp_features.hotkey_wlsw)
1737 return -ENODEV;
1738
1468#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 1739#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
1469 if (dbg_wlswemul) { 1740 if (dbg_wlswemul)
1470 *status = !!tpacpi_wlsw_emulstate; 1741 return (tpacpi_wlsw_emulstate) ?
1471 return 0; 1742 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
1472 }
1473#endif 1743#endif
1474 if (!acpi_evalf(hkey_handle, status, "WLSW", "d")) 1744
1745 if (!acpi_evalf(hkey_handle, &status, "WLSW", "d"))
1475 return -EIO; 1746 return -EIO;
1476 return 0; 1747
1748 return (status) ? TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
1477} 1749}
1478 1750
1479static int hotkey_get_tablet_mode(int *status) 1751static int hotkey_get_tablet_mode(int *status)
@@ -2107,12 +2379,16 @@ static ssize_t hotkey_radio_sw_show(struct device *dev,
2107 struct device_attribute *attr, 2379 struct device_attribute *attr,
2108 char *buf) 2380 char *buf)
2109{ 2381{
2110 int res, s; 2382 int res;
2111 res = hotkey_get_wlsw(&s); 2383 res = hotkey_get_wlsw();
2112 if (res < 0) 2384 if (res < 0)
2113 return res; 2385 return res;
2114 2386
2115 return snprintf(buf, PAGE_SIZE, "%d\n", !!s); 2387 /* Opportunistic update */
2388 tpacpi_rfk_update_hwblock_state((res == TPACPI_RFK_RADIO_OFF));
2389
2390 return snprintf(buf, PAGE_SIZE, "%d\n",
2391 (res == TPACPI_RFK_RADIO_OFF) ? 0 : 1);
2116} 2392}
2117 2393
2118static struct device_attribute dev_attr_hotkey_radio_sw = 2394static struct device_attribute dev_attr_hotkey_radio_sw =
@@ -2223,30 +2499,52 @@ static struct attribute *hotkey_mask_attributes[] __initdata = {
2223 &dev_attr_hotkey_wakeup_hotunplug_complete.attr, 2499 &dev_attr_hotkey_wakeup_hotunplug_complete.attr,
2224}; 2500};
2225 2501
2226static void bluetooth_update_rfk(void); 2502/*
2227static void wan_update_rfk(void); 2503 * Sync both the hw and sw blocking state of all switches
2228static void uwb_update_rfk(void); 2504 */
2229static void tpacpi_send_radiosw_update(void) 2505static void tpacpi_send_radiosw_update(void)
2230{ 2506{
2231 int wlsw; 2507 int wlsw;
2232 2508
2233 /* Sync these BEFORE sending any rfkill events */ 2509 /*
2234 if (tp_features.bluetooth) 2510 * We must sync all rfkill controllers *before* issuing any
2235 bluetooth_update_rfk(); 2511 * rfkill input events, or we will race the rfkill core input
2236 if (tp_features.wan) 2512 * handler.
2237 wan_update_rfk(); 2513 *
2238 if (tp_features.uwb) 2514 * tpacpi_inputdev_send_mutex works as a syncronization point
2239 uwb_update_rfk(); 2515 * for the above.
2516 *
2517 * We optimize to avoid numerous calls to hotkey_get_wlsw.
2518 */
2240 2519
2241 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) { 2520 wlsw = hotkey_get_wlsw();
2521
2522 /* Sync hw blocking state first if it is hw-blocked */
2523 if (wlsw == TPACPI_RFK_RADIO_OFF)
2524 tpacpi_rfk_update_hwblock_state(true);
2525
2526 /* Sync sw blocking state */
2527 tpacpi_rfk_update_swstate_all();
2528
2529 /* Sync hw blocking state last if it is hw-unblocked */
2530 if (wlsw == TPACPI_RFK_RADIO_ON)
2531 tpacpi_rfk_update_hwblock_state(false);
2532
2533 /* Issue rfkill input event for WLSW switch */
2534 if (!(wlsw < 0)) {
2242 mutex_lock(&tpacpi_inputdev_send_mutex); 2535 mutex_lock(&tpacpi_inputdev_send_mutex);
2243 2536
2244 input_report_switch(tpacpi_inputdev, 2537 input_report_switch(tpacpi_inputdev,
2245 SW_RFKILL_ALL, !!wlsw); 2538 SW_RFKILL_ALL, (wlsw > 0));
2246 input_sync(tpacpi_inputdev); 2539 input_sync(tpacpi_inputdev);
2247 2540
2248 mutex_unlock(&tpacpi_inputdev_send_mutex); 2541 mutex_unlock(&tpacpi_inputdev_send_mutex);
2249 } 2542 }
2543
2544 /*
2545 * this can be unconditional, as we will poll state again
2546 * if userspace uses the notify to read data
2547 */
2250 hotkey_radio_sw_notify_change(); 2548 hotkey_radio_sw_notify_change();
2251} 2549}
2252 2550
@@ -3056,8 +3354,6 @@ enum {
3056 3354
3057#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw" 3355#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw"
3058 3356
3059static struct rfkill *tpacpi_bluetooth_rfkill;
3060
3061static void bluetooth_suspend(pm_message_t state) 3357static void bluetooth_suspend(pm_message_t state)
3062{ 3358{
3063 /* Try to make sure radio will resume powered off */ 3359 /* Try to make sure radio will resume powered off */
@@ -3067,83 +3363,47 @@ static void bluetooth_suspend(pm_message_t state)
3067 "bluetooth power down on resume request failed\n"); 3363 "bluetooth power down on resume request failed\n");
3068} 3364}
3069 3365
3070static int bluetooth_get_radiosw(void) 3366static int bluetooth_get_status(void)
3071{ 3367{
3072 int status; 3368 int status;
3073 3369
3074 if (!tp_features.bluetooth)
3075 return -ENODEV;
3076
3077 /* WLSW overrides bluetooth in firmware/hardware, reflect that */
3078 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
3079 return RFKILL_STATE_HARD_BLOCKED;
3080
3081#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3370#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3082 if (dbg_bluetoothemul) 3371 if (dbg_bluetoothemul)
3083 return (tpacpi_bluetooth_emulstate) ? 3372 return (tpacpi_bluetooth_emulstate) ?
3084 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3373 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3085#endif 3374#endif
3086 3375
3087 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d")) 3376 if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
3088 return -EIO; 3377 return -EIO;
3089 3378
3090 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0) ? 3379 return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0) ?
3091 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3380 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3092} 3381}
3093 3382
3094static void bluetooth_update_rfk(void) 3383static int bluetooth_set_status(enum tpacpi_rfkill_state state)
3095{ 3384{
3096 int status; 3385 int status;
3097 3386
3098 if (!tpacpi_bluetooth_rfkill)
3099 return;
3100
3101 status = bluetooth_get_radiosw();
3102 if (status < 0)
3103 return;
3104 rfkill_force_state(tpacpi_bluetooth_rfkill, status);
3105
3106 vdbg_printk(TPACPI_DBG_RFKILL, 3387 vdbg_printk(TPACPI_DBG_RFKILL,
3107 "forced rfkill state to %d\n", 3388 "will attempt to %s bluetooth\n",
3108 status); 3389 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
3109}
3110
3111static int bluetooth_set_radiosw(int radio_on, int update_rfk)
3112{
3113 int status;
3114
3115 if (!tp_features.bluetooth)
3116 return -ENODEV;
3117
3118 /* WLSW overrides bluetooth in firmware/hardware, but there is no
3119 * reason to risk weird behaviour. */
3120 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
3121 && radio_on)
3122 return -EPERM;
3123
3124 vdbg_printk(TPACPI_DBG_RFKILL,
3125 "will %s bluetooth\n", radio_on ? "enable" : "disable");
3126 3390
3127#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3391#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3128 if (dbg_bluetoothemul) { 3392 if (dbg_bluetoothemul) {
3129 tpacpi_bluetooth_emulstate = !!radio_on; 3393 tpacpi_bluetooth_emulstate = (state == TPACPI_RFK_RADIO_ON);
3130 if (update_rfk)
3131 bluetooth_update_rfk();
3132 return 0; 3394 return 0;
3133 } 3395 }
3134#endif 3396#endif
3135 3397
3136 /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */ 3398 /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */
3137 if (radio_on) 3399 if (state == TPACPI_RFK_RADIO_ON)
3138 status = TP_ACPI_BLUETOOTH_RADIOSSW; 3400 status = TP_ACPI_BLUETOOTH_RADIOSSW;
3139 else 3401 else
3140 status = 0; 3402 status = 0;
3403
3141 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) 3404 if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
3142 return -EIO; 3405 return -EIO;
3143 3406
3144 if (update_rfk)
3145 bluetooth_update_rfk();
3146
3147 return 0; 3407 return 0;
3148} 3408}
3149 3409
@@ -3152,35 +3412,16 @@ static ssize_t bluetooth_enable_show(struct device *dev,
3152 struct device_attribute *attr, 3412 struct device_attribute *attr,
3153 char *buf) 3413 char *buf)
3154{ 3414{
3155 int status; 3415 return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_BLUETOOTH_SW_ID,
3156 3416 attr, buf);
3157 printk_deprecated_rfkill_attribute("bluetooth_enable");
3158
3159 status = bluetooth_get_radiosw();
3160 if (status < 0)
3161 return status;
3162
3163 return snprintf(buf, PAGE_SIZE, "%d\n",
3164 (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0);
3165} 3417}
3166 3418
3167static ssize_t bluetooth_enable_store(struct device *dev, 3419static ssize_t bluetooth_enable_store(struct device *dev,
3168 struct device_attribute *attr, 3420 struct device_attribute *attr,
3169 const char *buf, size_t count) 3421 const char *buf, size_t count)
3170{ 3422{
3171 unsigned long t; 3423 return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_BLUETOOTH_SW_ID,
3172 int res; 3424 attr, buf, count);
3173
3174 printk_deprecated_rfkill_attribute("bluetooth_enable");
3175
3176 if (parse_strtoul(buf, 1, &t))
3177 return -EINVAL;
3178
3179 tpacpi_disclose_usertask("bluetooth_enable", "set to %ld\n", t);
3180
3181 res = bluetooth_set_radiosw(t, 1);
3182
3183 return (res) ? res : count;
3184} 3425}
3185 3426
3186static struct device_attribute dev_attr_bluetooth_enable = 3427static struct device_attribute dev_attr_bluetooth_enable =
@@ -3198,23 +3439,10 @@ static const struct attribute_group bluetooth_attr_group = {
3198 .attrs = bluetooth_attributes, 3439 .attrs = bluetooth_attributes,
3199}; 3440};
3200 3441
3201static int tpacpi_bluetooth_rfk_get(void *data, enum rfkill_state *state) 3442static const struct tpacpi_rfk_ops bluetooth_tprfk_ops = {
3202{ 3443 .get_status = bluetooth_get_status,
3203 int bts = bluetooth_get_radiosw(); 3444 .set_status = bluetooth_set_status,
3204 3445};
3205 if (bts < 0)
3206 return bts;
3207
3208 *state = bts;
3209 return 0;
3210}
3211
3212static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state)
3213{
3214 dbg_printk(TPACPI_DBG_RFKILL,
3215 "request to change radio state to %d\n", state);
3216 return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
3217}
3218 3446
3219static void bluetooth_shutdown(void) 3447static void bluetooth_shutdown(void)
3220{ 3448{
@@ -3230,13 +3458,12 @@ static void bluetooth_shutdown(void)
3230 3458
3231static void bluetooth_exit(void) 3459static void bluetooth_exit(void)
3232{ 3460{
3233 bluetooth_shutdown();
3234
3235 if (tpacpi_bluetooth_rfkill)
3236 rfkill_unregister(tpacpi_bluetooth_rfkill);
3237
3238 sysfs_remove_group(&tpacpi_pdev->dev.kobj, 3461 sysfs_remove_group(&tpacpi_pdev->dev.kobj,
3239 &bluetooth_attr_group); 3462 &bluetooth_attr_group);
3463
3464 tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID);
3465
3466 bluetooth_shutdown();
3240} 3467}
3241 3468
3242static int __init bluetooth_init(struct ibm_init_struct *iibm) 3469static int __init bluetooth_init(struct ibm_init_struct *iibm)
@@ -3277,20 +3504,18 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
3277 if (!tp_features.bluetooth) 3504 if (!tp_features.bluetooth)
3278 return 1; 3505 return 1;
3279 3506
3280 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3281 &bluetooth_attr_group);
3282 if (res)
3283 return res;
3284
3285 res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID, 3507 res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID,
3286 &tpacpi_bluetooth_rfkill, 3508 &bluetooth_tprfk_ops,
3287 RFKILL_TYPE_BLUETOOTH, 3509 RFKILL_TYPE_BLUETOOTH,
3288 TPACPI_RFK_BLUETOOTH_SW_NAME, 3510 TPACPI_RFK_BLUETOOTH_SW_NAME,
3289 true, 3511 true);
3290 tpacpi_bluetooth_rfk_set, 3512 if (res)
3291 tpacpi_bluetooth_rfk_get); 3513 return res;
3514
3515 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3516 &bluetooth_attr_group);
3292 if (res) { 3517 if (res) {
3293 bluetooth_exit(); 3518 tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID);
3294 return res; 3519 return res;
3295 } 3520 }
3296 3521
@@ -3300,46 +3525,12 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
3300/* procfs -------------------------------------------------------------- */ 3525/* procfs -------------------------------------------------------------- */
3301static int bluetooth_read(char *p) 3526static int bluetooth_read(char *p)
3302{ 3527{
3303 int len = 0; 3528 return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, p);
3304 int status = bluetooth_get_radiosw();
3305
3306 if (!tp_features.bluetooth)
3307 len += sprintf(p + len, "status:\t\tnot supported\n");
3308 else {
3309 len += sprintf(p + len, "status:\t\t%s\n",
3310 (status == RFKILL_STATE_UNBLOCKED) ?
3311 "enabled" : "disabled");
3312 len += sprintf(p + len, "commands:\tenable, disable\n");
3313 }
3314
3315 return len;
3316} 3529}
3317 3530
3318static int bluetooth_write(char *buf) 3531static int bluetooth_write(char *buf)
3319{ 3532{
3320 char *cmd; 3533 return tpacpi_rfk_procfs_write(TPACPI_RFK_BLUETOOTH_SW_ID, buf);
3321 int state = -1;
3322
3323 if (!tp_features.bluetooth)
3324 return -ENODEV;
3325
3326 while ((cmd = next_cmd(&buf))) {
3327 if (strlencmp(cmd, "enable") == 0) {
3328 state = 1;
3329 } else if (strlencmp(cmd, "disable") == 0) {
3330 state = 0;
3331 } else
3332 return -EINVAL;
3333 }
3334
3335 if (state != -1) {
3336 tpacpi_disclose_usertask("procfs bluetooth",
3337 "attempt to %s\n",
3338 state ? "enable" : "disable");
3339 bluetooth_set_radiosw(state, 1);
3340 }
3341
3342 return 0;
3343} 3534}
3344 3535
3345static struct ibm_struct bluetooth_driver_data = { 3536static struct ibm_struct bluetooth_driver_data = {
@@ -3365,8 +3556,6 @@ enum {
3365 3556
3366#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" 3557#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"
3367 3558
3368static struct rfkill *tpacpi_wan_rfkill;
3369
3370static void wan_suspend(pm_message_t state) 3559static void wan_suspend(pm_message_t state)
3371{ 3560{
3372 /* Try to make sure radio will resume powered off */ 3561 /* Try to make sure radio will resume powered off */
@@ -3376,83 +3565,47 @@ static void wan_suspend(pm_message_t state)
3376 "WWAN power down on resume request failed\n"); 3565 "WWAN power down on resume request failed\n");
3377} 3566}
3378 3567
3379static int wan_get_radiosw(void) 3568static int wan_get_status(void)
3380{ 3569{
3381 int status; 3570 int status;
3382 3571
3383 if (!tp_features.wan)
3384 return -ENODEV;
3385
3386 /* WLSW overrides WWAN in firmware/hardware, reflect that */
3387 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
3388 return RFKILL_STATE_HARD_BLOCKED;
3389
3390#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3572#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3391 if (dbg_wwanemul) 3573 if (dbg_wwanemul)
3392 return (tpacpi_wwan_emulstate) ? 3574 return (tpacpi_wwan_emulstate) ?
3393 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3575 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3394#endif 3576#endif
3395 3577
3396 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d")) 3578 if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
3397 return -EIO; 3579 return -EIO;
3398 3580
3399 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0) ? 3581 return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0) ?
3400 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3582 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3401}
3402
3403static void wan_update_rfk(void)
3404{
3405 int status;
3406
3407 if (!tpacpi_wan_rfkill)
3408 return;
3409
3410 status = wan_get_radiosw();
3411 if (status < 0)
3412 return;
3413 rfkill_force_state(tpacpi_wan_rfkill, status);
3414
3415 vdbg_printk(TPACPI_DBG_RFKILL,
3416 "forced rfkill state to %d\n",
3417 status);
3418} 3583}
3419 3584
3420static int wan_set_radiosw(int radio_on, int update_rfk) 3585static int wan_set_status(enum tpacpi_rfkill_state state)
3421{ 3586{
3422 int status; 3587 int status;
3423 3588
3424 if (!tp_features.wan)
3425 return -ENODEV;
3426
3427 /* WLSW overrides bluetooth in firmware/hardware, but there is no
3428 * reason to risk weird behaviour. */
3429 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
3430 && radio_on)
3431 return -EPERM;
3432
3433 vdbg_printk(TPACPI_DBG_RFKILL, 3589 vdbg_printk(TPACPI_DBG_RFKILL,
3434 "will %s WWAN\n", radio_on ? "enable" : "disable"); 3590 "will attempt to %s wwan\n",
3591 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
3435 3592
3436#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3593#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3437 if (dbg_wwanemul) { 3594 if (dbg_wwanemul) {
3438 tpacpi_wwan_emulstate = !!radio_on; 3595 tpacpi_wwan_emulstate = (state == TPACPI_RFK_RADIO_ON);
3439 if (update_rfk)
3440 wan_update_rfk();
3441 return 0; 3596 return 0;
3442 } 3597 }
3443#endif 3598#endif
3444 3599
3445 /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */ 3600 /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */
3446 if (radio_on) 3601 if (state == TPACPI_RFK_RADIO_ON)
3447 status = TP_ACPI_WANCARD_RADIOSSW; 3602 status = TP_ACPI_WANCARD_RADIOSSW;
3448 else 3603 else
3449 status = 0; 3604 status = 0;
3605
3450 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) 3606 if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
3451 return -EIO; 3607 return -EIO;
3452 3608
3453 if (update_rfk)
3454 wan_update_rfk();
3455
3456 return 0; 3609 return 0;
3457} 3610}
3458 3611
@@ -3461,35 +3614,16 @@ static ssize_t wan_enable_show(struct device *dev,
3461 struct device_attribute *attr, 3614 struct device_attribute *attr,
3462 char *buf) 3615 char *buf)
3463{ 3616{
3464 int status; 3617 return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_WWAN_SW_ID,
3465 3618 attr, buf);
3466 printk_deprecated_rfkill_attribute("wwan_enable");
3467
3468 status = wan_get_radiosw();
3469 if (status < 0)
3470 return status;
3471
3472 return snprintf(buf, PAGE_SIZE, "%d\n",
3473 (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0);
3474} 3619}
3475 3620
3476static ssize_t wan_enable_store(struct device *dev, 3621static ssize_t wan_enable_store(struct device *dev,
3477 struct device_attribute *attr, 3622 struct device_attribute *attr,
3478 const char *buf, size_t count) 3623 const char *buf, size_t count)
3479{ 3624{
3480 unsigned long t; 3625 return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_WWAN_SW_ID,
3481 int res; 3626 attr, buf, count);
3482
3483 printk_deprecated_rfkill_attribute("wwan_enable");
3484
3485 if (parse_strtoul(buf, 1, &t))
3486 return -EINVAL;
3487
3488 tpacpi_disclose_usertask("wwan_enable", "set to %ld\n", t);
3489
3490 res = wan_set_radiosw(t, 1);
3491
3492 return (res) ? res : count;
3493} 3627}
3494 3628
3495static struct device_attribute dev_attr_wan_enable = 3629static struct device_attribute dev_attr_wan_enable =
@@ -3507,23 +3641,10 @@ static const struct attribute_group wan_attr_group = {
3507 .attrs = wan_attributes, 3641 .attrs = wan_attributes,
3508}; 3642};
3509 3643
3510static int tpacpi_wan_rfk_get(void *data, enum rfkill_state *state) 3644static const struct tpacpi_rfk_ops wan_tprfk_ops = {
3511{ 3645 .get_status = wan_get_status,
3512 int wans = wan_get_radiosw(); 3646 .set_status = wan_set_status,
3513 3647};
3514 if (wans < 0)
3515 return wans;
3516
3517 *state = wans;
3518 return 0;
3519}
3520
3521static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state)
3522{
3523 dbg_printk(TPACPI_DBG_RFKILL,
3524 "request to change radio state to %d\n", state);
3525 return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
3526}
3527 3648
3528static void wan_shutdown(void) 3649static void wan_shutdown(void)
3529{ 3650{
@@ -3539,13 +3660,12 @@ static void wan_shutdown(void)
3539 3660
3540static void wan_exit(void) 3661static void wan_exit(void)
3541{ 3662{
3542 wan_shutdown();
3543
3544 if (tpacpi_wan_rfkill)
3545 rfkill_unregister(tpacpi_wan_rfkill);
3546
3547 sysfs_remove_group(&tpacpi_pdev->dev.kobj, 3663 sysfs_remove_group(&tpacpi_pdev->dev.kobj,
3548 &wan_attr_group); 3664 &wan_attr_group);
3665
3666 tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID);
3667
3668 wan_shutdown();
3549} 3669}
3550 3670
3551static int __init wan_init(struct ibm_init_struct *iibm) 3671static int __init wan_init(struct ibm_init_struct *iibm)
@@ -3584,20 +3704,19 @@ static int __init wan_init(struct ibm_init_struct *iibm)
3584 if (!tp_features.wan) 3704 if (!tp_features.wan)
3585 return 1; 3705 return 1;
3586 3706
3587 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3588 &wan_attr_group);
3589 if (res)
3590 return res;
3591
3592 res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID, 3707 res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID,
3593 &tpacpi_wan_rfkill, 3708 &wan_tprfk_ops,
3594 RFKILL_TYPE_WWAN, 3709 RFKILL_TYPE_WWAN,
3595 TPACPI_RFK_WWAN_SW_NAME, 3710 TPACPI_RFK_WWAN_SW_NAME,
3596 true, 3711 true);
3597 tpacpi_wan_rfk_set, 3712 if (res)
3598 tpacpi_wan_rfk_get); 3713 return res;
3714
3715 res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
3716 &wan_attr_group);
3717
3599 if (res) { 3718 if (res) {
3600 wan_exit(); 3719 tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID);
3601 return res; 3720 return res;
3602 } 3721 }
3603 3722
@@ -3607,48 +3726,12 @@ static int __init wan_init(struct ibm_init_struct *iibm)
3607/* procfs -------------------------------------------------------------- */ 3726/* procfs -------------------------------------------------------------- */
3608static int wan_read(char *p) 3727static int wan_read(char *p)
3609{ 3728{
3610 int len = 0; 3729 return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, p);
3611 int status = wan_get_radiosw();
3612
3613 tpacpi_disclose_usertask("procfs wan", "read");
3614
3615 if (!tp_features.wan)
3616 len += sprintf(p + len, "status:\t\tnot supported\n");
3617 else {
3618 len += sprintf(p + len, "status:\t\t%s\n",
3619 (status == RFKILL_STATE_UNBLOCKED) ?
3620 "enabled" : "disabled");
3621 len += sprintf(p + len, "commands:\tenable, disable\n");
3622 }
3623
3624 return len;
3625} 3730}
3626 3731
3627static int wan_write(char *buf) 3732static int wan_write(char *buf)
3628{ 3733{
3629 char *cmd; 3734 return tpacpi_rfk_procfs_write(TPACPI_RFK_WWAN_SW_ID, buf);
3630 int state = -1;
3631
3632 if (!tp_features.wan)
3633 return -ENODEV;
3634
3635 while ((cmd = next_cmd(&buf))) {
3636 if (strlencmp(cmd, "enable") == 0) {
3637 state = 1;
3638 } else if (strlencmp(cmd, "disable") == 0) {
3639 state = 0;
3640 } else
3641 return -EINVAL;
3642 }
3643
3644 if (state != -1) {
3645 tpacpi_disclose_usertask("procfs wan",
3646 "attempt to %s\n",
3647 state ? "enable" : "disable");
3648 wan_set_radiosw(state, 1);
3649 }
3650
3651 return 0;
3652} 3735}
3653 3736
3654static struct ibm_struct wan_driver_data = { 3737static struct ibm_struct wan_driver_data = {
@@ -3672,108 +3755,59 @@ enum {
3672 3755
3673#define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw" 3756#define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw"
3674 3757
3675static struct rfkill *tpacpi_uwb_rfkill; 3758static int uwb_get_status(void)
3676
3677static int uwb_get_radiosw(void)
3678{ 3759{
3679 int status; 3760 int status;
3680 3761
3681 if (!tp_features.uwb)
3682 return -ENODEV;
3683
3684 /* WLSW overrides UWB in firmware/hardware, reflect that */
3685 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
3686 return RFKILL_STATE_HARD_BLOCKED;
3687
3688#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3762#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3689 if (dbg_uwbemul) 3763 if (dbg_uwbemul)
3690 return (tpacpi_uwb_emulstate) ? 3764 return (tpacpi_uwb_emulstate) ?
3691 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3765 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3692#endif 3766#endif
3693 3767
3694 if (!acpi_evalf(hkey_handle, &status, "GUWB", "d")) 3768 if (!acpi_evalf(hkey_handle, &status, "GUWB", "d"))
3695 return -EIO; 3769 return -EIO;
3696 3770
3697 return ((status & TP_ACPI_UWB_RADIOSSW) != 0) ? 3771 return ((status & TP_ACPI_UWB_RADIOSSW) != 0) ?
3698 RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED; 3772 TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
3699} 3773}
3700 3774
3701static void uwb_update_rfk(void) 3775static int uwb_set_status(enum tpacpi_rfkill_state state)
3702{ 3776{
3703 int status; 3777 int status;
3704 3778
3705 if (!tpacpi_uwb_rfkill)
3706 return;
3707
3708 status = uwb_get_radiosw();
3709 if (status < 0)
3710 return;
3711 rfkill_force_state(tpacpi_uwb_rfkill, status);
3712
3713 vdbg_printk(TPACPI_DBG_RFKILL, 3779 vdbg_printk(TPACPI_DBG_RFKILL,
3714 "forced rfkill state to %d\n", 3780 "will attempt to %s UWB\n",
3715 status); 3781 (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
3716}
3717
3718static int uwb_set_radiosw(int radio_on, int update_rfk)
3719{
3720 int status;
3721
3722 if (!tp_features.uwb)
3723 return -ENODEV;
3724
3725 /* WLSW overrides UWB in firmware/hardware, but there is no
3726 * reason to risk weird behaviour. */
3727 if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
3728 && radio_on)
3729 return -EPERM;
3730
3731 vdbg_printk(TPACPI_DBG_RFKILL,
3732 "will %s UWB\n", radio_on ? "enable" : "disable");
3733 3782
3734#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES 3783#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
3735 if (dbg_uwbemul) { 3784 if (dbg_uwbemul) {
3736 tpacpi_uwb_emulstate = !!radio_on; 3785 tpacpi_uwb_emulstate = (state == TPACPI_RFK_RADIO_ON);
3737 if (update_rfk)
3738 uwb_update_rfk();
3739 return 0; 3786 return 0;
3740 } 3787 }
3741#endif 3788#endif
3742 3789
3743 status = (radio_on) ? TP_ACPI_UWB_RADIOSSW : 0; 3790 if (state == TPACPI_RFK_RADIO_ON)
3791 status = TP_ACPI_UWB_RADIOSSW;
3792 else
3793 status = 0;
3794
3744 if (!acpi_evalf(hkey_handle, NULL, "SUWB", "vd", status)) 3795 if (!acpi_evalf(hkey_handle, NULL, "SUWB", "vd", status))
3745 return -EIO; 3796 return -EIO;
3746 3797
3747 if (update_rfk)
3748 uwb_update_rfk();
3749
3750 return 0; 3798 return 0;
3751} 3799}
3752 3800
3753/* --------------------------------------------------------------------- */ 3801/* --------------------------------------------------------------------- */
3754 3802
3755static int tpacpi_uwb_rfk_get(void *data, enum rfkill_state *state) 3803static const struct tpacpi_rfk_ops uwb_tprfk_ops = {
3756{ 3804 .get_status = uwb_get_status,
3757 int uwbs = uwb_get_radiosw(); 3805 .set_status = uwb_set_status,
3758 3806};
3759 if (uwbs < 0)
3760 return uwbs;
3761
3762 *state = uwbs;
3763 return 0;
3764}
3765
3766static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state)
3767{
3768 dbg_printk(TPACPI_DBG_RFKILL,
3769 "request to change radio state to %d\n", state);
3770 return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
3771}
3772 3807
3773static void uwb_exit(void) 3808static void uwb_exit(void)
3774{ 3809{
3775 if (tpacpi_uwb_rfkill) 3810 tpacpi_destroy_rfkill(TPACPI_RFK_UWB_SW_ID);
3776 rfkill_unregister(tpacpi_uwb_rfkill);
3777} 3811}
3778 3812
3779static int __init uwb_init(struct ibm_init_struct *iibm) 3813static int __init uwb_init(struct ibm_init_struct *iibm)
@@ -3813,13 +3847,10 @@ static int __init uwb_init(struct ibm_init_struct *iibm)
3813 return 1; 3847 return 1;
3814 3848
3815 res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID, 3849 res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID,
3816 &tpacpi_uwb_rfkill, 3850 &uwb_tprfk_ops,
3817 RFKILL_TYPE_UWB, 3851 RFKILL_TYPE_UWB,
3818 TPACPI_RFK_UWB_SW_NAME, 3852 TPACPI_RFK_UWB_SW_NAME,
3819 false, 3853 false);
3820 tpacpi_uwb_rfk_set,
3821 tpacpi_uwb_rfk_get);
3822
3823 return res; 3854 return res;
3824} 3855}
3825 3856
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 4345089f5171..81d31ea507d1 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -45,7 +45,6 @@
45#include <linux/backlight.h> 45#include <linux/backlight.h>
46#include <linux/platform_device.h> 46#include <linux/platform_device.h>
47#include <linux/rfkill.h> 47#include <linux/rfkill.h>
48#include <linux/input-polldev.h>
49 48
50#include <asm/uaccess.h> 49#include <asm/uaccess.h>
51 50
@@ -250,21 +249,15 @@ static acpi_status hci_read2(u32 reg, u32 *out1, u32 *out2, u32 *result)
250 249
251struct toshiba_acpi_dev { 250struct toshiba_acpi_dev {
252 struct platform_device *p_dev; 251 struct platform_device *p_dev;
253 struct rfkill *rfk_dev; 252 struct rfkill *bt_rfk;
254 struct input_polled_dev *poll_dev;
255 253
256 const char *bt_name; 254 const char *bt_name;
257 const char *rfk_name;
258
259 bool last_rfk_state;
260 255
261 struct mutex mutex; 256 struct mutex mutex;
262}; 257};
263 258
264static struct toshiba_acpi_dev toshiba_acpi = { 259static struct toshiba_acpi_dev toshiba_acpi = {
265 .bt_name = "Toshiba Bluetooth", 260 .bt_name = "Toshiba Bluetooth",
266 .rfk_name = "Toshiba RFKill Switch",
267 .last_rfk_state = false,
268}; 261};
269 262
270/* Bluetooth rfkill handlers */ 263/* Bluetooth rfkill handlers */
@@ -283,21 +276,6 @@ static u32 hci_get_bt_present(bool *present)
283 return hci_result; 276 return hci_result;
284} 277}
285 278
286static u32 hci_get_bt_on(bool *on)
287{
288 u32 hci_result;
289 u32 value, value2;
290
291 value = 0;
292 value2 = 0x0001;
293 hci_read2(HCI_WIRELESS, &value, &value2, &hci_result);
294 if (hci_result == HCI_SUCCESS)
295 *on = (value & HCI_WIRELESS_BT_POWER) &&
296 (value & HCI_WIRELESS_BT_ATTACH);
297
298 return hci_result;
299}
300
301static u32 hci_get_radio_state(bool *radio_state) 279static u32 hci_get_radio_state(bool *radio_state)
302{ 280{
303 u32 hci_result; 281 u32 hci_result;
@@ -311,70 +289,67 @@ static u32 hci_get_radio_state(bool *radio_state)
311 return hci_result; 289 return hci_result;
312} 290}
313 291
314static int bt_rfkill_toggle_radio(void *data, enum rfkill_state state) 292static int bt_rfkill_set_block(void *data, bool blocked)
315{ 293{
294 struct toshiba_acpi_dev *dev = data;
316 u32 result1, result2; 295 u32 result1, result2;
317 u32 value; 296 u32 value;
297 int err;
318 bool radio_state; 298 bool radio_state;
319 struct toshiba_acpi_dev *dev = data;
320 299
321 value = (state == RFKILL_STATE_UNBLOCKED); 300 value = (blocked == false);
322 301
323 if (hci_get_radio_state(&radio_state) != HCI_SUCCESS) 302 mutex_lock(&dev->mutex);
324 return -EFAULT; 303 if (hci_get_radio_state(&radio_state) != HCI_SUCCESS) {
304 err = -EBUSY;
305 goto out;
306 }
325 307
326 switch (state) { 308 if (!radio_state) {
327 case RFKILL_STATE_UNBLOCKED: 309 err = 0;
328 if (!radio_state) 310 goto out;
329 return -EPERM;
330 break;
331 case RFKILL_STATE_SOFT_BLOCKED:
332 break;
333 default:
334 return -EINVAL;
335 } 311 }
336 312
337 mutex_lock(&dev->mutex);
338 hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_POWER, &result1); 313 hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_POWER, &result1);
339 hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_ATTACH, &result2); 314 hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_ATTACH, &result2);
340 mutex_unlock(&dev->mutex);
341 315
342 if (result1 != HCI_SUCCESS || result2 != HCI_SUCCESS) 316 if (result1 != HCI_SUCCESS || result2 != HCI_SUCCESS)
343 return -EFAULT; 317 err = -EBUSY;
344 318 else
345 return 0; 319 err = 0;
320 out:
321 mutex_unlock(&dev->mutex);
322 return err;
346} 323}
347 324
348static void bt_poll_rfkill(struct input_polled_dev *poll_dev) 325static void bt_rfkill_poll(struct rfkill *rfkill, void *data)
349{ 326{
350 bool state_changed;
351 bool new_rfk_state; 327 bool new_rfk_state;
352 bool value; 328 bool value;
353 u32 hci_result; 329 u32 hci_result;
354 struct toshiba_acpi_dev *dev = poll_dev->private; 330 struct toshiba_acpi_dev *dev = data;
331
332 mutex_lock(&dev->mutex);
355 333
356 hci_result = hci_get_radio_state(&value); 334 hci_result = hci_get_radio_state(&value);
357 if (hci_result != HCI_SUCCESS) 335 if (hci_result != HCI_SUCCESS) {
358 return; /* Can't do anything useful */ 336 /* Can't do anything useful */
337 mutex_unlock(&dev->mutex);
338 }
359 339
360 new_rfk_state = value; 340 new_rfk_state = value;
361 341
362 mutex_lock(&dev->mutex);
363 state_changed = new_rfk_state != dev->last_rfk_state;
364 dev->last_rfk_state = new_rfk_state;
365 mutex_unlock(&dev->mutex); 342 mutex_unlock(&dev->mutex);
366 343
367 if (unlikely(state_changed)) { 344 if (rfkill_set_hw_state(rfkill, !new_rfk_state))
368 rfkill_force_state(dev->rfk_dev, 345 bt_rfkill_set_block(data, true);
369 new_rfk_state ?
370 RFKILL_STATE_SOFT_BLOCKED :
371 RFKILL_STATE_HARD_BLOCKED);
372 input_report_switch(poll_dev->input, SW_RFKILL_ALL,
373 new_rfk_state);
374 input_sync(poll_dev->input);
375 }
376} 346}
377 347
348static const struct rfkill_ops toshiba_rfk_ops = {
349 .set_block = bt_rfkill_set_block,
350 .poll = bt_rfkill_poll,
351};
352
378static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ; 353static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
379static struct backlight_device *toshiba_backlight_device; 354static struct backlight_device *toshiba_backlight_device;
380static int force_fan; 355static int force_fan;
@@ -702,14 +677,11 @@ static struct backlight_ops toshiba_backlight_data = {
702 677
703static void toshiba_acpi_exit(void) 678static void toshiba_acpi_exit(void)
704{ 679{
705 if (toshiba_acpi.poll_dev) { 680 if (toshiba_acpi.bt_rfk) {
706 input_unregister_polled_device(toshiba_acpi.poll_dev); 681 rfkill_unregister(toshiba_acpi.bt_rfk);
707 input_free_polled_device(toshiba_acpi.poll_dev); 682 rfkill_destroy(toshiba_acpi.bt_rfk);
708 } 683 }
709 684
710 if (toshiba_acpi.rfk_dev)
711 rfkill_unregister(toshiba_acpi.rfk_dev);
712
713 if (toshiba_backlight_device) 685 if (toshiba_backlight_device)
714 backlight_device_unregister(toshiba_backlight_device); 686 backlight_device_unregister(toshiba_backlight_device);
715 687
@@ -728,8 +700,6 @@ static int __init toshiba_acpi_init(void)
728 acpi_status status = AE_OK; 700 acpi_status status = AE_OK;
729 u32 hci_result; 701 u32 hci_result;
730 bool bt_present; 702 bool bt_present;
731 bool bt_on;
732 bool radio_on;
733 int ret = 0; 703 int ret = 0;
734 704
735 if (acpi_disabled) 705 if (acpi_disabled)
@@ -793,60 +763,21 @@ static int __init toshiba_acpi_init(void)
793 763
794 /* Register rfkill switch for Bluetooth */ 764 /* Register rfkill switch for Bluetooth */
795 if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) { 765 if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) {
796 toshiba_acpi.rfk_dev = rfkill_allocate(&toshiba_acpi.p_dev->dev, 766 toshiba_acpi.bt_rfk = rfkill_alloc(toshiba_acpi.bt_name,
797 RFKILL_TYPE_BLUETOOTH); 767 &toshiba_acpi.p_dev->dev,
798 if (!toshiba_acpi.rfk_dev) { 768 RFKILL_TYPE_BLUETOOTH,
769 &toshiba_rfk_ops,
770 &toshiba_acpi);
771 if (!toshiba_acpi.bt_rfk) {
799 printk(MY_ERR "unable to allocate rfkill device\n"); 772 printk(MY_ERR "unable to allocate rfkill device\n");
800 toshiba_acpi_exit(); 773 toshiba_acpi_exit();
801 return -ENOMEM; 774 return -ENOMEM;
802 } 775 }
803 776
804 toshiba_acpi.rfk_dev->name = toshiba_acpi.bt_name; 777 ret = rfkill_register(toshiba_acpi.bt_rfk);
805 toshiba_acpi.rfk_dev->toggle_radio = bt_rfkill_toggle_radio;
806 toshiba_acpi.rfk_dev->data = &toshiba_acpi;
807
808 if (hci_get_bt_on(&bt_on) == HCI_SUCCESS && bt_on) {
809 toshiba_acpi.rfk_dev->state = RFKILL_STATE_UNBLOCKED;
810 } else if (hci_get_radio_state(&radio_on) == HCI_SUCCESS &&
811 radio_on) {
812 toshiba_acpi.rfk_dev->state = RFKILL_STATE_SOFT_BLOCKED;
813 } else {
814 toshiba_acpi.rfk_dev->state = RFKILL_STATE_HARD_BLOCKED;
815 }
816
817 ret = rfkill_register(toshiba_acpi.rfk_dev);
818 if (ret) { 778 if (ret) {
819 printk(MY_ERR "unable to register rfkill device\n"); 779 printk(MY_ERR "unable to register rfkill device\n");
820 toshiba_acpi_exit(); 780 rfkill_destroy(toshiba_acpi.bt_rfk);
821 return -ENOMEM;
822 }
823
824 /* Register input device for kill switch */
825 toshiba_acpi.poll_dev = input_allocate_polled_device();
826 if (!toshiba_acpi.poll_dev) {
827 printk(MY_ERR
828 "unable to allocate kill-switch input device\n");
829 toshiba_acpi_exit();
830 return -ENOMEM;
831 }
832 toshiba_acpi.poll_dev->private = &toshiba_acpi;
833 toshiba_acpi.poll_dev->poll = bt_poll_rfkill;
834 toshiba_acpi.poll_dev->poll_interval = 1000; /* msecs */
835
836 toshiba_acpi.poll_dev->input->name = toshiba_acpi.rfk_name;
837 toshiba_acpi.poll_dev->input->id.bustype = BUS_HOST;
838 /* Toshiba USB ID */
839 toshiba_acpi.poll_dev->input->id.vendor = 0x0930;
840 set_bit(EV_SW, toshiba_acpi.poll_dev->input->evbit);
841 set_bit(SW_RFKILL_ALL, toshiba_acpi.poll_dev->input->swbit);
842 input_report_switch(toshiba_acpi.poll_dev->input,
843 SW_RFKILL_ALL, TRUE);
844 input_sync(toshiba_acpi.poll_dev->input);
845
846 ret = input_register_polled_device(toshiba_acpi.poll_dev);
847 if (ret) {
848 printk(MY_ERR
849 "unable to register kill-switch input device\n");
850 toshiba_acpi_exit(); 781 toshiba_acpi_exit();
851 return ret; 782 return ret;
852 } 783 }