diff options
author | Patrick McHardy <kaber@trash.net> | 2009-06-11 10:00:49 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2009-06-11 10:00:49 -0400 |
commit | 36432dae73cf2c90a59b39c8df9fd8219272b005 (patch) | |
tree | 660b9104305a809ec4fdeb295ca13d6e90790ecc /drivers/net/wireless | |
parent | 440f0d588555892601cfe511728a0fc0c8204063 (diff) | |
parent | bb400801c2f40bbd9a688818323ad09abfc4e581 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
Diffstat (limited to 'drivers/net/wireless')
108 files changed, 2284 insertions, 2856 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index a67d29290ba0..fb7541c28e58 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig | |||
@@ -153,7 +153,7 @@ config LIBERTAS_SDIO | |||
153 | 153 | ||
154 | config LIBERTAS_SPI | 154 | config LIBERTAS_SPI |
155 | tristate "Marvell Libertas 8686 SPI 802.11b/g cards" | 155 | tristate "Marvell Libertas 8686 SPI 802.11b/g cards" |
156 | depends on LIBERTAS && SPI && GENERIC_GPIO | 156 | depends on LIBERTAS && SPI |
157 | ---help--- | 157 | ---help--- |
158 | A driver for Marvell Libertas 8686 SPI devices. | 158 | A driver for Marvell Libertas 8686 SPI devices. |
159 | 159 | ||
@@ -333,11 +333,11 @@ config USB_ZD1201 | |||
333 | config USB_NET_RNDIS_WLAN | 333 | config 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: |
@@ -431,6 +431,7 @@ config RTL8187 | |||
431 | ASUS P5B Deluxe | 431 | ASUS P5B Deluxe |
432 | Toshiba Satellite Pro series of laptops | 432 | Toshiba Satellite Pro series of laptops |
433 | Asus Wireless Link | 433 | Asus Wireless Link |
434 | Linksys WUSB54GC-EU | ||
434 | 435 | ||
435 | Thanks to Realtek for their support! | 436 | Thanks to Realtek for their support! |
436 | 437 | ||
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index cea7f1466c54..4efbdbe6d6bf 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c | |||
@@ -1873,18 +1873,18 @@ static void at76_dwork_hw_scan(struct work_struct *work) | |||
1873 | if (ret != CMD_STATUS_COMPLETE) { | 1873 | if (ret != CMD_STATUS_COMPLETE) { |
1874 | queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan, | 1874 | queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan, |
1875 | SCAN_POLL_INTERVAL); | 1875 | SCAN_POLL_INTERVAL); |
1876 | goto exit; | 1876 | mutex_unlock(&priv->mtx); |
1877 | return; | ||
1877 | } | 1878 | } |
1878 | 1879 | ||
1879 | ieee80211_scan_completed(priv->hw, false); | ||
1880 | |||
1881 | if (is_valid_ether_addr(priv->bssid)) | 1880 | if (is_valid_ether_addr(priv->bssid)) |
1882 | at76_join(priv); | 1881 | at76_join(priv); |
1883 | 1882 | ||
1884 | ieee80211_wake_queues(priv->hw); | ||
1885 | |||
1886 | exit: | ||
1887 | mutex_unlock(&priv->mtx); | 1883 | mutex_unlock(&priv->mtx); |
1884 | |||
1885 | ieee80211_scan_completed(priv->hw, false); | ||
1886 | |||
1887 | ieee80211_wake_queues(priv->hw); | ||
1888 | } | 1888 | } |
1889 | 1889 | ||
1890 | static int at76_hw_scan(struct ieee80211_hw *hw, | 1890 | static int at76_hw_scan(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h index 17bd3eaf3e03..bb97981fb248 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 | ||
107 | struct ar9170_rxstream_mpdu_merge { | 107 | struct ar9170_rxstream_mpdu_merge { |
@@ -109,6 +109,11 @@ struct ar9170_rxstream_mpdu_merge { | |||
109 | bool has_plcp; | 109 | bool has_plcp; |
110 | }; | 110 | }; |
111 | 111 | ||
112 | #define AR9170_QUEUE_TIMEOUT 64 | ||
113 | #define AR9170_TX_TIMEOUT 8 | ||
114 | #define AR9170_JANITOR_DELAY 128 | ||
115 | #define AR9170_TX_INVALID_RATE 0xffffffff | ||
116 | |||
112 | struct ar9170 { | 117 | struct ar9170 { |
113 | struct ieee80211_hw *hw; | 118 | struct ieee80211_hw *hw; |
114 | struct mutex mutex; | 119 | struct mutex mutex; |
@@ -117,10 +122,11 @@ struct ar9170 { | |||
117 | 122 | ||
118 | int (*open)(struct ar9170 *); | 123 | int (*open)(struct ar9170 *); |
119 | void (*stop)(struct ar9170 *); | 124 | void (*stop)(struct ar9170 *); |
120 | int (*tx)(struct ar9170 *, struct sk_buff *, bool, unsigned int); | 125 | int (*tx)(struct ar9170 *, struct sk_buff *); |
121 | int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 , | 126 | int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 , |
122 | void *, u32 , void *); | 127 | void *, u32 , void *); |
123 | void (*callback_cmd)(struct ar9170 *, u32 , void *); | 128 | void (*callback_cmd)(struct ar9170 *, u32 , void *); |
129 | int (*flush)(struct ar9170 *); | ||
124 | 130 | ||
125 | /* interface mode settings */ | 131 | /* interface mode settings */ |
126 | struct ieee80211_vif *vif; | 132 | struct ieee80211_vif *vif; |
@@ -140,7 +146,7 @@ struct ar9170 { | |||
140 | struct work_struct filter_config_work; | 146 | struct work_struct filter_config_work; |
141 | u64 cur_mc_hash, want_mc_hash; | 147 | u64 cur_mc_hash, want_mc_hash; |
142 | u32 cur_filter, want_filter; | 148 | u32 cur_filter, want_filter; |
143 | unsigned int filter_changed; | 149 | unsigned long filter_changed; |
144 | unsigned int filter_state; | 150 | unsigned int filter_state; |
145 | bool sniffer_enabled; | 151 | bool sniffer_enabled; |
146 | 152 | ||
@@ -177,10 +183,10 @@ struct ar9170 { | |||
177 | struct ar9170_eeprom eeprom; | 183 | struct ar9170_eeprom eeprom; |
178 | struct ath_regulatory regulatory; | 184 | struct ath_regulatory regulatory; |
179 | 185 | ||
180 | /* global tx status for unregistered Stations. */ | 186 | /* tx queues - as seen by hw - */ |
181 | struct sk_buff_head global_tx_status; | 187 | struct sk_buff_head tx_pending[__AR9170_NUM_TXQ]; |
182 | struct sk_buff_head global_tx_status_waste; | 188 | struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; |
183 | struct delayed_work tx_status_janitor; | 189 | struct delayed_work tx_janitor; |
184 | 190 | ||
185 | /* rxstream mpdu merge */ | 191 | /* rxstream mpdu merge */ |
186 | struct ar9170_rxstream_mpdu_merge rx_mpdu; | 192 | struct ar9170_rxstream_mpdu_merge rx_mpdu; |
@@ -189,13 +195,21 @@ struct ar9170 { | |||
189 | }; | 195 | }; |
190 | 196 | ||
191 | struct ar9170_sta_info { | 197 | struct ar9170_sta_info { |
192 | struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; | ||
193 | }; | 198 | }; |
194 | 199 | ||
195 | #define IS_STARTED(a) (a->state >= AR9170_STARTED) | 200 | #define AR9170_TX_FLAG_WAIT_FOR_ACK BIT(0) |
196 | #define IS_ACCEPTING_CMD(a) (a->state >= AR9170_IDLE) | 201 | #define AR9170_TX_FLAG_NO_ACK BIT(1) |
202 | #define AR9170_TX_FLAG_BLOCK_ACK BIT(2) | ||
203 | |||
204 | struct ar9170_tx_info { | ||
205 | unsigned long timeout; | ||
206 | unsigned int flags; | ||
207 | }; | ||
208 | |||
209 | #define IS_STARTED(a) (((struct ar9170 *)a)->state >= AR9170_STARTED) | ||
210 | #define IS_ACCEPTING_CMD(a) (((struct ar9170 *)a)->state >= AR9170_IDLE) | ||
197 | 211 | ||
198 | #define AR9170_FILTER_CHANGED_PROMISC BIT(0) | 212 | #define AR9170_FILTER_CHANGED_MODE BIT(0) |
199 | #define AR9170_FILTER_CHANGED_MULTICAST BIT(1) | 213 | #define AR9170_FILTER_CHANGED_MULTICAST BIT(1) |
200 | #define AR9170_FILTER_CHANGED_FRAMEFILTER BIT(2) | 214 | #define AR9170_FILTER_CHANGED_FRAMEFILTER BIT(2) |
201 | 215 | ||
@@ -204,8 +218,9 @@ void *ar9170_alloc(size_t priv_size); | |||
204 | int ar9170_register(struct ar9170 *ar, struct device *pdev); | 218 | int ar9170_register(struct ar9170 *ar, struct device *pdev); |
205 | void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb); | 219 | void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb); |
206 | void ar9170_unregister(struct ar9170 *ar); | 220 | void ar9170_unregister(struct ar9170 *ar); |
207 | void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, | 221 | void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb); |
208 | bool update_statistics, u16 tx_status); | 222 | void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); |
223 | int ar9170_nag_limiter(struct ar9170 *ar); | ||
209 | 224 | ||
210 | /* MAC */ | 225 | /* MAC */ |
211 | int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); | 226 | int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); |
@@ -215,6 +230,9 @@ int ar9170_update_multicast(struct ar9170 *ar); | |||
215 | int ar9170_update_frame_filter(struct ar9170 *ar); | 230 | int ar9170_update_frame_filter(struct ar9170 *ar); |
216 | int ar9170_set_operating_mode(struct ar9170 *ar); | 231 | int ar9170_set_operating_mode(struct ar9170 *ar); |
217 | int ar9170_set_beacon_timers(struct ar9170 *ar); | 232 | int ar9170_set_beacon_timers(struct ar9170 *ar); |
233 | int ar9170_set_dyn_sifs_ack(struct ar9170 *ar); | ||
234 | int ar9170_set_slot_time(struct ar9170 *ar); | ||
235 | int ar9170_set_basic_rates(struct ar9170 *ar); | ||
218 | int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry); | 236 | int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry); |
219 | int ar9170_update_beacon(struct ar9170 *ar); | 237 | int ar9170_update_beacon(struct ar9170 *ar); |
220 | void ar9170_new_beacon(struct work_struct *work); | 238 | void 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..6cbfb2f83391 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 | ||
378 | struct ar9170_cmd_tx_status { | 379 | struct 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 { | |||
394 | struct ar9170_cmd_response { | 394 | struct 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; |
@@ -419,4 +420,7 @@ enum ar9170_txq { | |||
419 | __AR9170_NUM_TXQ, | 420 | __AR9170_NUM_TXQ, |
420 | }; | 421 | }; |
421 | 422 | ||
423 | #define AR9170_TXQ_DEPTH 32 | ||
424 | #define AR9170_TX_MAX_PENDING 128 | ||
425 | |||
422 | #endif /* __AR9170_HW_H */ | 426 | #endif /* __AR9170_HW_H */ |
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 | ||
148 | int ar9170_register_leds(struct ar9170 *ar) | 155 | int 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 | ||
41 | int 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 | |||
57 | int 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 | |||
71 | int 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 | |||
41 | int ar9170_set_qos(struct ar9170 *ar) | 90 | int 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..9d38cf60a0db 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 | \ |
@@ -174,59 +173,122 @@ static struct ieee80211_supported_band ar9170_band_5GHz = { | |||
174 | .ht_cap = AR9170_HT_CAP, | 173 | .ht_cap = AR9170_HT_CAP, |
175 | }; | 174 | }; |
176 | 175 | ||
177 | #ifdef AR9170_QUEUE_DEBUG | 176 | static void ar9170_tx(struct ar9170 *ar); |
178 | /* | ||
179 | * In case some wants works with AR9170's crazy tx_status queueing techniques. | ||
180 | * He might need this rather useful probing function. | ||
181 | * | ||
182 | * NOTE: caller must hold the queue's spinlock! | ||
183 | */ | ||
184 | 177 | ||
178 | #ifdef AR9170_QUEUE_DEBUG | ||
185 | static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) | 179 | static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) |
186 | { | 180 | { |
187 | struct ar9170_tx_control *txc = (void *) skb->data; | 181 | struct ar9170_tx_control *txc = (void *) skb->data; |
188 | struct ieee80211_hdr *hdr = (void *)txc->frame_data; | 182 | struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); |
183 | struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; | ||
184 | struct ieee80211_hdr *hdr = (void *) txc->frame_data; | ||
189 | 185 | ||
190 | printk(KERN_DEBUG "%s: => FRAME [skb:%p, queue:%d, DA:[%pM] " | 186 | printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x " |
191 | "mac_control:%04x, phy_control:%08x]\n", | 187 | "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", |
192 | wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), | 188 | wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), |
193 | ieee80211_get_DA(hdr), le16_to_cpu(txc->mac_control), | 189 | ieee80211_get_DA(hdr), arinfo->flags, |
194 | le32_to_cpu(txc->phy_control)); | 190 | le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), |
191 | jiffies_to_msecs(arinfo->timeout - jiffies)); | ||
195 | } | 192 | } |
196 | 193 | ||
197 | static void ar9170_dump_station_tx_status_queue(struct ar9170 *ar, | 194 | static void __ar9170_dump_txqueue(struct ar9170 *ar, |
198 | struct sk_buff_head *queue) | 195 | struct sk_buff_head *queue) |
199 | { | 196 | { |
200 | struct sk_buff *skb; | 197 | struct sk_buff *skb; |
201 | int i = 0; | 198 | int i = 0; |
202 | 199 | ||
203 | printk(KERN_DEBUG "---[ cut here ]---\n"); | 200 | printk(KERN_DEBUG "---[ cut here ]---\n"); |
204 | printk(KERN_DEBUG "%s: %d entries in tx_status queue.\n", | 201 | printk(KERN_DEBUG "%s: %d entries in queue.\n", |
205 | wiphy_name(ar->hw->wiphy), skb_queue_len(queue)); | 202 | wiphy_name(ar->hw->wiphy), skb_queue_len(queue)); |
206 | 203 | ||
207 | skb_queue_walk(queue, skb) { | 204 | skb_queue_walk(queue, skb) { |
208 | struct ar9170_tx_control *txc = (void *) skb->data; | 205 | printk(KERN_DEBUG "index:%d => \n", i++); |
209 | struct ieee80211_hdr *hdr = (void *)txc->frame_data; | ||
210 | |||
211 | printk(KERN_DEBUG "index:%d => \n", i); | ||
212 | ar9170_print_txheader(ar, skb); | 206 | ar9170_print_txheader(ar, skb); |
213 | } | 207 | } |
208 | if (i != skb_queue_len(queue)) | ||
209 | printk(KERN_DEBUG "WARNING: queue frame counter " | ||
210 | "mismatch %d != %d\n", skb_queue_len(queue), i); | ||
214 | printk(KERN_DEBUG "---[ end ]---\n"); | 211 | printk(KERN_DEBUG "---[ end ]---\n"); |
215 | } | 212 | } |
216 | #endif /* AR9170_QUEUE_DEBUG */ | ||
217 | 213 | ||
218 | void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, | 214 | static void ar9170_dump_txqueue(struct ar9170 *ar, |
219 | bool valid_status, u16 tx_status) | 215 | struct sk_buff_head *queue) |
216 | { | ||
217 | unsigned long flags; | ||
218 | |||
219 | spin_lock_irqsave(&queue->lock, flags); | ||
220 | __ar9170_dump_txqueue(ar, queue); | ||
221 | spin_unlock_irqrestore(&queue->lock, flags); | ||
222 | } | ||
223 | |||
224 | static void __ar9170_dump_txstats(struct ar9170 *ar) | ||
225 | { | ||
226 | int i; | ||
227 | |||
228 | printk(KERN_DEBUG "%s: QoS queue stats\n", | ||
229 | wiphy_name(ar->hw->wiphy)); | ||
230 | |||
231 | for (i = 0; i < __AR9170_NUM_TXQ; i++) | ||
232 | printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d\n", | ||
233 | wiphy_name(ar->hw->wiphy), i, ar->tx_stats[i].limit, | ||
234 | ar->tx_stats[i].len, skb_queue_len(&ar->tx_status[i])); | ||
235 | } | ||
236 | |||
237 | static void ar9170_dump_txstats(struct ar9170 *ar) | ||
220 | { | 238 | { |
221 | struct ieee80211_tx_info *txinfo; | ||
222 | unsigned int retries = 0, queue = skb_get_queue_mapping(skb); | ||
223 | unsigned long flags; | 239 | unsigned long flags; |
224 | 240 | ||
225 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | 241 | spin_lock_irqsave(&ar->tx_stats_lock, flags); |
226 | ar->tx_stats[queue].len--; | 242 | __ar9170_dump_txstats(ar); |
227 | if (ieee80211_queue_stopped(ar->hw, queue)) | ||
228 | ieee80211_wake_queue(ar->hw, queue); | ||
229 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | 243 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); |
244 | } | ||
245 | #endif /* AR9170_QUEUE_DEBUG */ | ||
246 | |||
247 | /* caller must guarantee exclusive access for _bin_ queue. */ | ||
248 | static void ar9170_recycle_expired(struct ar9170 *ar, | ||
249 | struct sk_buff_head *queue, | ||
250 | struct sk_buff_head *bin) | ||
251 | { | ||
252 | struct sk_buff *skb, *old = NULL; | ||
253 | unsigned long flags; | ||
254 | |||
255 | spin_lock_irqsave(&queue->lock, flags); | ||
256 | while ((skb = skb_peek(queue))) { | ||
257 | struct ieee80211_tx_info *txinfo; | ||
258 | struct ar9170_tx_info *arinfo; | ||
259 | |||
260 | txinfo = IEEE80211_SKB_CB(skb); | ||
261 | arinfo = (void *) txinfo->rate_driver_data; | ||
262 | |||
263 | if (time_is_before_jiffies(arinfo->timeout)) { | ||
264 | #ifdef AR9170_QUEUE_DEBUG | ||
265 | printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => " | ||
266 | "recycle \n", wiphy_name(ar->hw->wiphy), | ||
267 | jiffies, arinfo->timeout); | ||
268 | ar9170_print_txheader(ar, skb); | ||
269 | #endif /* AR9170_QUEUE_DEBUG */ | ||
270 | __skb_unlink(skb, queue); | ||
271 | __skb_queue_tail(bin, skb); | ||
272 | } else { | ||
273 | break; | ||
274 | } | ||
275 | |||
276 | if (unlikely(old == skb)) { | ||
277 | /* bail out - queue is shot. */ | ||
278 | |||
279 | WARN_ON(1); | ||
280 | break; | ||
281 | } | ||
282 | old = skb; | ||
283 | } | ||
284 | spin_unlock_irqrestore(&queue->lock, flags); | ||
285 | } | ||
286 | |||
287 | static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, | ||
288 | u16 tx_status) | ||
289 | { | ||
290 | struct ieee80211_tx_info *txinfo; | ||
291 | unsigned int retries = 0; | ||
230 | 292 | ||
231 | txinfo = IEEE80211_SKB_CB(skb); | 293 | txinfo = IEEE80211_SKB_CB(skb); |
232 | ieee80211_tx_info_clear_status(txinfo); | 294 | ieee80211_tx_info_clear_status(txinfo); |
@@ -248,45 +310,61 @@ void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, | |||
248 | break; | 310 | break; |
249 | } | 311 | } |
250 | 312 | ||
251 | if (valid_status) | 313 | txinfo->status.rates[0].count = retries + 1; |
252 | txinfo->status.rates[0].count = retries + 1; | ||
253 | |||
254 | skb_pull(skb, sizeof(struct ar9170_tx_control)); | 314 | skb_pull(skb, sizeof(struct ar9170_tx_control)); |
255 | ieee80211_tx_status_irqsafe(ar->hw, skb); | 315 | ieee80211_tx_status_irqsafe(ar->hw, skb); |
256 | } | 316 | } |
257 | 317 | ||
258 | static struct sk_buff *ar9170_find_skb_in_queue(struct ar9170 *ar, | 318 | void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) |
259 | const u8 *mac, | ||
260 | const u32 queue, | ||
261 | struct sk_buff_head *q) | ||
262 | { | 319 | { |
320 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
321 | struct ar9170_tx_info *arinfo = (void *) info->rate_driver_data; | ||
322 | unsigned int queue = skb_get_queue_mapping(skb); | ||
263 | unsigned long flags; | 323 | unsigned long flags; |
264 | struct sk_buff *skb; | ||
265 | 324 | ||
266 | spin_lock_irqsave(&q->lock, flags); | 325 | spin_lock_irqsave(&ar->tx_stats_lock, flags); |
267 | skb_queue_walk(q, skb) { | 326 | ar->tx_stats[queue].len--; |
268 | struct ar9170_tx_control *txc = (void *) skb->data; | ||
269 | struct ieee80211_hdr *hdr = (void *) txc->frame_data; | ||
270 | u32 txc_queue = (le32_to_cpu(txc->phy_control) & | ||
271 | AR9170_TX_PHY_QOS_MASK) >> | ||
272 | AR9170_TX_PHY_QOS_SHIFT; | ||
273 | 327 | ||
274 | if ((queue != txc_queue) || | 328 | if (skb_queue_empty(&ar->tx_pending[queue])) { |
275 | (compare_ether_addr(ieee80211_get_DA(hdr), mac))) | 329 | #ifdef AR9170_QUEUE_STOP_DEBUG |
276 | continue; | 330 | printk(KERN_DEBUG "%s: wake queue %d\n", |
331 | wiphy_name(ar->hw->wiphy), queue); | ||
332 | __ar9170_dump_txstats(ar); | ||
333 | #endif /* AR9170_QUEUE_STOP_DEBUG */ | ||
334 | ieee80211_wake_queue(ar->hw, queue); | ||
335 | } | ||
336 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
277 | 337 | ||
278 | __skb_unlink(skb, q); | 338 | if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) { |
279 | spin_unlock_irqrestore(&q->lock, flags); | 339 | dev_kfree_skb_any(skb); |
280 | return skb; | 340 | } else if (arinfo->flags & AR9170_TX_FLAG_WAIT_FOR_ACK) { |
341 | arinfo->timeout = jiffies + | ||
342 | msecs_to_jiffies(AR9170_TX_TIMEOUT); | ||
343 | |||
344 | skb_queue_tail(&ar->tx_status[queue], skb); | ||
345 | } else if (arinfo->flags & AR9170_TX_FLAG_NO_ACK) { | ||
346 | ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED); | ||
347 | } else { | ||
348 | #ifdef AR9170_QUEUE_DEBUG | ||
349 | printk(KERN_DEBUG "%s: unsupported frame flags!\n", | ||
350 | wiphy_name(ar->hw->wiphy)); | ||
351 | ar9170_print_txheader(ar, skb); | ||
352 | #endif /* AR9170_QUEUE_DEBUG */ | ||
353 | dev_kfree_skb_any(skb); | ||
354 | } | ||
355 | |||
356 | if (!ar->tx_stats[queue].len && | ||
357 | !skb_queue_empty(&ar->tx_pending[queue])) { | ||
358 | ar9170_tx(ar); | ||
281 | } | 359 | } |
282 | spin_unlock_irqrestore(&q->lock, flags); | ||
283 | return NULL; | ||
284 | } | 360 | } |
285 | 361 | ||
286 | static struct sk_buff *ar9170_find_queued_skb(struct ar9170 *ar, const u8 *mac, | 362 | static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, |
287 | const u32 queue) | 363 | const u8 *mac, |
364 | struct sk_buff_head *queue, | ||
365 | const u32 rate) | ||
288 | { | 366 | { |
289 | struct ieee80211_sta *sta; | 367 | unsigned long flags; |
290 | struct sk_buff *skb; | 368 | struct sk_buff *skb; |
291 | 369 | ||
292 | /* | 370 | /* |
@@ -297,85 +375,94 @@ static struct sk_buff *ar9170_find_queued_skb(struct ar9170 *ar, const u8 *mac, | |||
297 | * the firmware provided (-> destination MAC, and phy_control) - | 375 | * the firmware provided (-> destination MAC, and phy_control) - |
298 | * and hope that we picked the right one... | 376 | * and hope that we picked the right one... |
299 | */ | 377 | */ |
300 | rcu_read_lock(); | ||
301 | sta = ieee80211_find_sta(ar->hw, mac); | ||
302 | |||
303 | if (likely(sta)) { | ||
304 | struct ar9170_sta_info *sta_priv = (void *) sta->drv_priv; | ||
305 | skb = skb_dequeue(&sta_priv->tx_status[queue]); | ||
306 | rcu_read_unlock(); | ||
307 | if (likely(skb)) | ||
308 | return skb; | ||
309 | } else | ||
310 | rcu_read_unlock(); | ||
311 | |||
312 | /* scan the waste queue for candidates */ | ||
313 | skb = ar9170_find_skb_in_queue(ar, mac, queue, | ||
314 | &ar->global_tx_status_waste); | ||
315 | if (!skb) { | ||
316 | /* so it still _must_ be in the global list. */ | ||
317 | skb = ar9170_find_skb_in_queue(ar, mac, queue, | ||
318 | &ar->global_tx_status); | ||
319 | } | ||
320 | 378 | ||
379 | spin_lock_irqsave(&queue->lock, flags); | ||
380 | skb_queue_walk(queue, skb) { | ||
381 | struct ar9170_tx_control *txc = (void *) skb->data; | ||
382 | struct ieee80211_hdr *hdr = (void *) txc->frame_data; | ||
383 | u32 r; | ||
384 | |||
385 | if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) { | ||
386 | #ifdef AR9170_QUEUE_DEBUG | ||
387 | printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n", | ||
388 | wiphy_name(ar->hw->wiphy), mac, | ||
389 | ieee80211_get_DA(hdr)); | ||
390 | ar9170_print_txheader(ar, skb); | ||
391 | #endif /* AR9170_QUEUE_DEBUG */ | ||
392 | continue; | ||
393 | } | ||
394 | |||
395 | r = (le32_to_cpu(txc->phy_control) & AR9170_TX_PHY_MCS_MASK) >> | ||
396 | AR9170_TX_PHY_MCS_SHIFT; | ||
397 | |||
398 | if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) { | ||
321 | #ifdef AR9170_QUEUE_DEBUG | 399 | #ifdef AR9170_QUEUE_DEBUG |
322 | if (unlikely((!skb) && net_ratelimit())) { | 400 | printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n", |
323 | printk(KERN_ERR "%s: ESS:[%pM] does not have any " | 401 | wiphy_name(ar->hw->wiphy), rate, r); |
324 | "outstanding frames in this queue (%d).\n", | 402 | ar9170_print_txheader(ar, skb); |
325 | wiphy_name(ar->hw->wiphy), mac, queue); | 403 | #endif /* AR9170_QUEUE_DEBUG */ |
404 | continue; | ||
405 | } | ||
406 | |||
407 | __skb_unlink(skb, queue); | ||
408 | spin_unlock_irqrestore(&queue->lock, flags); | ||
409 | return skb; | ||
326 | } | 410 | } |
411 | |||
412 | #ifdef AR9170_QUEUE_DEBUG | ||
413 | printk(KERN_ERR "%s: ESS:[%pM] does not have any " | ||
414 | "outstanding frames in queue.\n", | ||
415 | wiphy_name(ar->hw->wiphy), mac); | ||
416 | __ar9170_dump_txqueue(ar, queue); | ||
327 | #endif /* AR9170_QUEUE_DEBUG */ | 417 | #endif /* AR9170_QUEUE_DEBUG */ |
328 | return skb; | 418 | spin_unlock_irqrestore(&queue->lock, flags); |
419 | |||
420 | return NULL; | ||
329 | } | 421 | } |
330 | 422 | ||
331 | /* | 423 | /* |
332 | * This worker tries to keep the global tx_status queue empty. | 424 | * This worker tries to keeps an maintain tx_status queues. |
333 | * So we can guarantee that incoming tx_status reports for | 425 | * So we can guarantee that incoming tx_status reports are |
334 | * unregistered stations are always synced with the actual | 426 | * actually for a pending frame. |
335 | * frame - which we think - belongs to. | ||
336 | */ | 427 | */ |
337 | 428 | ||
338 | static void ar9170_tx_status_janitor(struct work_struct *work) | 429 | static void ar9170_tx_janitor(struct work_struct *work) |
339 | { | 430 | { |
340 | struct ar9170 *ar = container_of(work, struct ar9170, | 431 | struct ar9170 *ar = container_of(work, struct ar9170, |
341 | tx_status_janitor.work); | 432 | tx_janitor.work); |
342 | struct sk_buff *skb; | 433 | struct sk_buff_head waste; |
434 | unsigned int i; | ||
435 | bool resched = false; | ||
343 | 436 | ||
344 | if (unlikely(!IS_STARTED(ar))) | 437 | if (unlikely(!IS_STARTED(ar))) |
345 | return ; | 438 | return ; |
346 | 439 | ||
347 | mutex_lock(&ar->mutex); | 440 | skb_queue_head_init(&waste); |
348 | /* recycle the garbage back to mac80211... one by one. */ | 441 | |
349 | while ((skb = skb_dequeue(&ar->global_tx_status_waste))) { | 442 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { |
350 | #ifdef AR9170_QUEUE_DEBUG | 443 | #ifdef AR9170_QUEUE_DEBUG |
351 | printk(KERN_DEBUG "%s: dispose queued frame =>\n", | 444 | printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n", |
352 | wiphy_name(ar->hw->wiphy)); | 445 | wiphy_name(ar->hw->wiphy), i); |
353 | ar9170_print_txheader(ar, skb); | 446 | ar9170_dump_txqueue(ar, &ar->tx_pending[i]); |
447 | ar9170_dump_txqueue(ar, &ar->tx_status[i]); | ||
354 | #endif /* AR9170_QUEUE_DEBUG */ | 448 | #endif /* AR9170_QUEUE_DEBUG */ |
355 | ar9170_handle_tx_status(ar, skb, false, | ||
356 | AR9170_TX_STATUS_FAILED); | ||
357 | } | ||
358 | 449 | ||
359 | while ((skb = skb_dequeue(&ar->global_tx_status))) { | 450 | ar9170_recycle_expired(ar, &ar->tx_status[i], &waste); |
360 | #ifdef AR9170_QUEUE_DEBUG | 451 | ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste); |
361 | printk(KERN_DEBUG "%s: moving frame into waste queue =>\n", | 452 | skb_queue_purge(&waste); |
362 | wiphy_name(ar->hw->wiphy)); | ||
363 | 453 | ||
364 | ar9170_print_txheader(ar, skb); | 454 | if (!skb_queue_empty(&ar->tx_status[i]) || |
365 | #endif /* AR9170_QUEUE_DEBUG */ | 455 | !skb_queue_empty(&ar->tx_pending[i])) |
366 | skb_queue_tail(&ar->global_tx_status_waste, skb); | 456 | resched = true; |
367 | } | 457 | } |
368 | 458 | ||
369 | /* recall the janitor in 100ms - if there's garbage in the can. */ | 459 | if (resched) |
370 | if (skb_queue_len(&ar->global_tx_status_waste) > 0) | 460 | queue_delayed_work(ar->hw->workqueue, |
371 | queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor, | 461 | &ar->tx_janitor, |
372 | msecs_to_jiffies(100)); | 462 | msecs_to_jiffies(AR9170_JANITOR_DELAY)); |
373 | |||
374 | mutex_unlock(&ar->mutex); | ||
375 | } | 463 | } |
376 | 464 | ||
377 | static void ar9170_handle_command_response(struct ar9170 *ar, | 465 | void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) |
378 | void *buf, u32 len) | ||
379 | { | 466 | { |
380 | struct ar9170_cmd_response *cmd = (void *) buf; | 467 | struct ar9170_cmd_response *cmd = (void *) buf; |
381 | 468 | ||
@@ -399,15 +486,21 @@ static void ar9170_handle_command_response(struct ar9170 *ar, | |||
399 | */ | 486 | */ |
400 | 487 | ||
401 | struct sk_buff *skb; | 488 | struct sk_buff *skb; |
402 | u32 queue = (le32_to_cpu(cmd->tx_status.rate) & | 489 | u32 phy = le32_to_cpu(cmd->tx_status.rate); |
403 | AR9170_TX_PHY_QOS_MASK) >> AR9170_TX_PHY_QOS_SHIFT; | 490 | u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >> |
491 | AR9170_TX_PHY_QOS_SHIFT; | ||
492 | #ifdef AR9170_QUEUE_DEBUG | ||
493 | printk(KERN_DEBUG "%s: recv tx_status for %pM, p:%08x, q:%d\n", | ||
494 | wiphy_name(ar->hw->wiphy), cmd->tx_status.dst, phy, q); | ||
495 | #endif /* AR9170_QUEUE_DEBUG */ | ||
404 | 496 | ||
405 | skb = ar9170_find_queued_skb(ar, cmd->tx_status.dst, queue); | 497 | skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst, |
498 | &ar->tx_status[q], | ||
499 | AR9170_TX_INVALID_RATE); | ||
406 | if (unlikely(!skb)) | 500 | if (unlikely(!skb)) |
407 | return ; | 501 | return ; |
408 | 502 | ||
409 | ar9170_handle_tx_status(ar, skb, true, | 503 | ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status)); |
410 | le16_to_cpu(cmd->tx_status.status)); | ||
411 | break; | 504 | break; |
412 | } | 505 | } |
413 | 506 | ||
@@ -447,6 +540,38 @@ static void ar9170_handle_command_response(struct ar9170 *ar, | |||
447 | /* retransmission issue / SIFS/EIFS collision ?! */ | 540 | /* retransmission issue / SIFS/EIFS collision ?! */ |
448 | break; | 541 | break; |
449 | 542 | ||
543 | /* firmware debug */ | ||
544 | case 0xca: | ||
545 | printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4, (char *)buf + 4); | ||
546 | break; | ||
547 | case 0xcb: | ||
548 | len -= 4; | ||
549 | |||
550 | switch (len) { | ||
551 | case 1: | ||
552 | printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n", | ||
553 | *((char *)buf + 4)); | ||
554 | break; | ||
555 | case 2: | ||
556 | printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n", | ||
557 | le16_to_cpup((__le16 *)((char *)buf + 4))); | ||
558 | break; | ||
559 | case 4: | ||
560 | printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n", | ||
561 | le32_to_cpup((__le32 *)((char *)buf + 4))); | ||
562 | break; | ||
563 | case 8: | ||
564 | printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n", | ||
565 | (unsigned long)le64_to_cpup( | ||
566 | (__le64 *)((char *)buf + 4))); | ||
567 | break; | ||
568 | } | ||
569 | break; | ||
570 | case 0xcc: | ||
571 | print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE, | ||
572 | (char *)buf + 4, len - 4); | ||
573 | break; | ||
574 | |||
450 | default: | 575 | default: |
451 | printk(KERN_INFO "received unhandled event %x\n", cmd->type); | 576 | printk(KERN_INFO "received unhandled event %x\n", cmd->type); |
452 | print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len); | 577 | print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len); |
@@ -460,7 +585,7 @@ static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar) | |||
460 | ar->rx_mpdu.has_plcp = false; | 585 | ar->rx_mpdu.has_plcp = false; |
461 | } | 586 | } |
462 | 587 | ||
463 | static int ar9170_nag_limiter(struct ar9170 *ar) | 588 | int ar9170_nag_limiter(struct ar9170 *ar) |
464 | { | 589 | { |
465 | bool print_message; | 590 | bool print_message; |
466 | 591 | ||
@@ -957,10 +1082,12 @@ static int ar9170_op_start(struct ieee80211_hw *hw) | |||
957 | 1082 | ||
958 | mutex_lock(&ar->mutex); | 1083 | mutex_lock(&ar->mutex); |
959 | 1084 | ||
1085 | ar->filter_changed = 0; | ||
1086 | |||
960 | /* reinitialize queues statistics */ | 1087 | /* reinitialize queues statistics */ |
961 | memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); | 1088 | memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); |
962 | for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++) | 1089 | for (i = 0; i < __AR9170_NUM_TXQ; i++) |
963 | ar->tx_stats[i].limit = 8; | 1090 | ar->tx_stats[i].limit = AR9170_TXQ_DEPTH; |
964 | 1091 | ||
965 | /* reset QoS defaults */ | 1092 | /* reset QoS defaults */ |
966 | AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/ | 1093 | AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT*/ |
@@ -1006,18 +1133,17 @@ out: | |||
1006 | static void ar9170_op_stop(struct ieee80211_hw *hw) | 1133 | static void ar9170_op_stop(struct ieee80211_hw *hw) |
1007 | { | 1134 | { |
1008 | struct ar9170 *ar = hw->priv; | 1135 | struct ar9170 *ar = hw->priv; |
1136 | unsigned int i; | ||
1009 | 1137 | ||
1010 | if (IS_STARTED(ar)) | 1138 | if (IS_STARTED(ar)) |
1011 | ar->state = AR9170_IDLE; | 1139 | ar->state = AR9170_IDLE; |
1012 | 1140 | ||
1013 | flush_workqueue(ar->hw->workqueue); | 1141 | flush_workqueue(ar->hw->workqueue); |
1014 | 1142 | ||
1015 | mutex_lock(&ar->mutex); | 1143 | cancel_delayed_work_sync(&ar->tx_janitor); |
1016 | cancel_delayed_work_sync(&ar->tx_status_janitor); | ||
1017 | cancel_work_sync(&ar->filter_config_work); | 1144 | cancel_work_sync(&ar->filter_config_work); |
1018 | cancel_work_sync(&ar->beacon_work); | 1145 | cancel_work_sync(&ar->beacon_work); |
1019 | skb_queue_purge(&ar->global_tx_status_waste); | 1146 | mutex_lock(&ar->mutex); |
1020 | skb_queue_purge(&ar->global_tx_status); | ||
1021 | 1147 | ||
1022 | if (IS_ACCEPTING_CMD(ar)) { | 1148 | if (IS_ACCEPTING_CMD(ar)) { |
1023 | ar9170_set_leds_state(ar, 0); | 1149 | ar9170_set_leds_state(ar, 0); |
@@ -1027,51 +1153,32 @@ static void ar9170_op_stop(struct ieee80211_hw *hw) | |||
1027 | ar->stop(ar); | 1153 | ar->stop(ar); |
1028 | } | 1154 | } |
1029 | 1155 | ||
1156 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { | ||
1157 | skb_queue_purge(&ar->tx_pending[i]); | ||
1158 | skb_queue_purge(&ar->tx_status[i]); | ||
1159 | } | ||
1030 | mutex_unlock(&ar->mutex); | 1160 | mutex_unlock(&ar->mutex); |
1031 | } | 1161 | } |
1032 | 1162 | ||
1033 | int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 1163 | static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) |
1034 | { | 1164 | { |
1035 | struct ar9170 *ar = hw->priv; | ||
1036 | struct ieee80211_hdr *hdr; | 1165 | struct ieee80211_hdr *hdr; |
1037 | struct ar9170_tx_control *txc; | 1166 | struct ar9170_tx_control *txc; |
1038 | struct ieee80211_tx_info *info; | 1167 | struct ieee80211_tx_info *info; |
1039 | struct ieee80211_rate *rate = NULL; | ||
1040 | struct ieee80211_tx_rate *txrate; | 1168 | struct ieee80211_tx_rate *txrate; |
1169 | struct ar9170_tx_info *arinfo; | ||
1041 | unsigned int queue = skb_get_queue_mapping(skb); | 1170 | unsigned int queue = skb_get_queue_mapping(skb); |
1042 | unsigned long flags = 0; | ||
1043 | struct ar9170_sta_info *sta_info = NULL; | ||
1044 | u32 power, chains; | ||
1045 | u16 keytype = 0; | 1171 | u16 keytype = 0; |
1046 | u16 len, icv = 0; | 1172 | u16 len, icv = 0; |
1047 | int err; | ||
1048 | bool tx_status; | ||
1049 | 1173 | ||
1050 | if (unlikely(!IS_STARTED(ar))) | 1174 | BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); |
1051 | goto err_free; | ||
1052 | 1175 | ||
1053 | hdr = (void *)skb->data; | 1176 | hdr = (void *)skb->data; |
1054 | info = IEEE80211_SKB_CB(skb); | 1177 | info = IEEE80211_SKB_CB(skb); |
1055 | len = skb->len; | 1178 | len = skb->len; |
1056 | 1179 | ||
1057 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | ||
1058 | if (ar->tx_stats[queue].limit < ar->tx_stats[queue].len) { | ||
1059 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1060 | return NETDEV_TX_OK; | ||
1061 | } | ||
1062 | |||
1063 | ar->tx_stats[queue].len++; | ||
1064 | ar->tx_stats[queue].count++; | ||
1065 | if (ar->tx_stats[queue].limit == ar->tx_stats[queue].len) | ||
1066 | ieee80211_stop_queue(hw, queue); | ||
1067 | |||
1068 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1069 | |||
1070 | txc = (void *)skb_push(skb, sizeof(*txc)); | 1180 | txc = (void *)skb_push(skb, sizeof(*txc)); |
1071 | 1181 | ||
1072 | tx_status = (((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) != 0) || | ||
1073 | ((info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) != 0)); | ||
1074 | |||
1075 | if (info->control.hw_key) { | 1182 | if (info->control.hw_key) { |
1076 | icv = info->control.hw_key->icv_len; | 1183 | icv = info->control.hw_key->icv_len; |
1077 | 1184 | ||
@@ -1087,7 +1194,7 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1087 | break; | 1194 | break; |
1088 | default: | 1195 | default: |
1089 | WARN_ON(1); | 1196 | WARN_ON(1); |
1090 | goto err_dequeue; | 1197 | goto err_out; |
1091 | } | 1198 | } |
1092 | } | 1199 | } |
1093 | 1200 | ||
@@ -1104,16 +1211,65 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1104 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) | 1211 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) |
1105 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK); | 1212 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK); |
1106 | 1213 | ||
1107 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | ||
1108 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); | ||
1109 | |||
1110 | txrate = &info->control.rates[0]; | 1214 | txrate = &info->control.rates[0]; |
1111 | |||
1112 | if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) | 1215 | if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) |
1113 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); | 1216 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); |
1114 | else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS) | 1217 | else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS) |
1115 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); | 1218 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); |
1116 | 1219 | ||
1220 | arinfo = (void *)info->rate_driver_data; | ||
1221 | arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT); | ||
1222 | |||
1223 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) && | ||
1224 | (is_valid_ether_addr(ieee80211_get_DA(hdr)))) { | ||
1225 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
1226 | if (unlikely(!info->control.sta)) | ||
1227 | goto err_out; | ||
1228 | |||
1229 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); | ||
1230 | arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK; | ||
1231 | goto out; | ||
1232 | } | ||
1233 | |||
1234 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); | ||
1235 | /* | ||
1236 | * WARNING: | ||
1237 | * Putting the QoS queue bits into an unexplored territory is | ||
1238 | * certainly not elegant. | ||
1239 | * | ||
1240 | * In my defense: This idea provides a reasonable way to | ||
1241 | * smuggle valuable information to the tx_status callback. | ||
1242 | * Also, the idea behind this bit-abuse came straight from | ||
1243 | * the original driver code. | ||
1244 | */ | ||
1245 | |||
1246 | txc->phy_control |= | ||
1247 | cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); | ||
1248 | arinfo->flags = AR9170_TX_FLAG_WAIT_FOR_ACK; | ||
1249 | } else { | ||
1250 | arinfo->flags = AR9170_TX_FLAG_NO_ACK; | ||
1251 | } | ||
1252 | |||
1253 | out: | ||
1254 | return 0; | ||
1255 | |||
1256 | err_out: | ||
1257 | skb_pull(skb, sizeof(*txc)); | ||
1258 | return -EINVAL; | ||
1259 | } | ||
1260 | |||
1261 | static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb) | ||
1262 | { | ||
1263 | struct ar9170_tx_control *txc; | ||
1264 | struct ieee80211_tx_info *info; | ||
1265 | struct ieee80211_rate *rate = NULL; | ||
1266 | struct ieee80211_tx_rate *txrate; | ||
1267 | u32 power, chains; | ||
1268 | |||
1269 | txc = (void *) skb->data; | ||
1270 | info = IEEE80211_SKB_CB(skb); | ||
1271 | txrate = &info->control.rates[0]; | ||
1272 | |||
1117 | if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) | 1273 | if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) |
1118 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD); | 1274 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD); |
1119 | 1275 | ||
@@ -1133,9 +1289,12 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1133 | u32 r = txrate->idx; | 1289 | u32 r = txrate->idx; |
1134 | u8 *txpower; | 1290 | u8 *txpower; |
1135 | 1291 | ||
1292 | /* heavy clip control */ | ||
1293 | txc->phy_control |= cpu_to_le32((r & 0x7) << 7); | ||
1294 | |||
1136 | r <<= AR9170_TX_PHY_MCS_SHIFT; | 1295 | r <<= AR9170_TX_PHY_MCS_SHIFT; |
1137 | if (WARN_ON(r & ~AR9170_TX_PHY_MCS_MASK)) | 1296 | BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK); |
1138 | goto err_dequeue; | 1297 | |
1139 | txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK); | 1298 | txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK); |
1140 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT); | 1299 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT); |
1141 | 1300 | ||
@@ -1197,53 +1356,154 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1197 | chains = AR9170_TX_PHY_TXCHAIN_1; | 1356 | chains = AR9170_TX_PHY_TXCHAIN_1; |
1198 | } | 1357 | } |
1199 | txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT); | 1358 | txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT); |
1359 | } | ||
1200 | 1360 | ||
1201 | if (tx_status) { | 1361 | static void ar9170_tx(struct ar9170 *ar) |
1202 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); | 1362 | { |
1203 | /* | 1363 | struct sk_buff *skb; |
1204 | * WARNING: | 1364 | unsigned long flags; |
1205 | * Putting the QoS queue bits into an unexplored territory is | 1365 | struct ieee80211_tx_info *info; |
1206 | * certainly not elegant. | 1366 | struct ar9170_tx_info *arinfo; |
1207 | * | 1367 | unsigned int i, frames, frames_failed, remaining_space; |
1208 | * In my defense: This idea provides a reasonable way to | 1368 | int err; |
1209 | * smuggle valuable information to the tx_status callback. | 1369 | bool schedule_garbagecollector = false; |
1210 | * Also, the idea behind this bit-abuse came straight from | ||
1211 | * the original driver code. | ||
1212 | */ | ||
1213 | 1370 | ||
1214 | txc->phy_control |= | 1371 | BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); |
1215 | cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); | ||
1216 | 1372 | ||
1217 | if (info->control.sta) { | 1373 | if (unlikely(!IS_STARTED(ar))) |
1218 | sta_info = (void *) info->control.sta->drv_priv; | 1374 | return ; |
1219 | skb_queue_tail(&sta_info->tx_status[queue], skb); | 1375 | |
1220 | } else { | 1376 | remaining_space = AR9170_TX_MAX_PENDING; |
1221 | skb_queue_tail(&ar->global_tx_status, skb); | 1377 | |
1378 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { | ||
1379 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | ||
1380 | if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) { | ||
1381 | #ifdef AR9170_QUEUE_DEBUG | ||
1382 | printk(KERN_DEBUG "%s: queue %d full\n", | ||
1383 | wiphy_name(ar->hw->wiphy), i); | ||
1222 | 1384 | ||
1223 | queue_delayed_work(ar->hw->workqueue, | 1385 | __ar9170_dump_txstats(ar); |
1224 | &ar->tx_status_janitor, | 1386 | printk(KERN_DEBUG "stuck frames: ===> \n"); |
1225 | msecs_to_jiffies(100)); | 1387 | ar9170_dump_txqueue(ar, &ar->tx_pending[i]); |
1388 | ar9170_dump_txqueue(ar, &ar->tx_status[i]); | ||
1389 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1390 | ieee80211_stop_queue(ar->hw, i); | ||
1391 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1392 | continue; | ||
1393 | } | ||
1394 | |||
1395 | frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len, | ||
1396 | skb_queue_len(&ar->tx_pending[i])); | ||
1397 | |||
1398 | if (remaining_space < frames) { | ||
1399 | #ifdef AR9170_QUEUE_DEBUG | ||
1400 | printk(KERN_DEBUG "%s: tx quota reached queue:%d, " | ||
1401 | "remaining slots:%d, needed:%d\n", | ||
1402 | wiphy_name(ar->hw->wiphy), i, remaining_space, | ||
1403 | frames); | ||
1404 | |||
1405 | ar9170_dump_txstats(ar); | ||
1406 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1407 | frames = remaining_space; | ||
1408 | } | ||
1409 | |||
1410 | ar->tx_stats[i].len += frames; | ||
1411 | ar->tx_stats[i].count += frames; | ||
1412 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1413 | |||
1414 | if (!frames) | ||
1415 | continue; | ||
1416 | |||
1417 | frames_failed = 0; | ||
1418 | while (frames) { | ||
1419 | skb = skb_dequeue(&ar->tx_pending[i]); | ||
1420 | if (unlikely(!skb)) { | ||
1421 | frames_failed += frames; | ||
1422 | frames = 0; | ||
1423 | break; | ||
1424 | } | ||
1425 | |||
1426 | info = IEEE80211_SKB_CB(skb); | ||
1427 | arinfo = (void *) info->rate_driver_data; | ||
1428 | |||
1429 | /* TODO: cancel stuck frames */ | ||
1430 | arinfo->timeout = jiffies + | ||
1431 | msecs_to_jiffies(AR9170_TX_TIMEOUT); | ||
1432 | |||
1433 | #ifdef AR9170_QUEUE_DEBUG | ||
1434 | printk(KERN_DEBUG "%s: send frame q:%d =>\n", | ||
1435 | wiphy_name(ar->hw->wiphy), i); | ||
1436 | ar9170_print_txheader(ar, skb); | ||
1437 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1438 | |||
1439 | err = ar->tx(ar, skb); | ||
1440 | if (unlikely(err)) { | ||
1441 | frames_failed++; | ||
1442 | dev_kfree_skb_any(skb); | ||
1443 | } else { | ||
1444 | remaining_space--; | ||
1445 | schedule_garbagecollector = true; | ||
1446 | } | ||
1447 | |||
1448 | frames--; | ||
1449 | } | ||
1450 | |||
1451 | #ifdef AR9170_QUEUE_DEBUG | ||
1452 | printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n", | ||
1453 | wiphy_name(ar->hw->wiphy), i); | ||
1454 | |||
1455 | printk(KERN_DEBUG "%s: unprocessed pending frames left:\n", | ||
1456 | wiphy_name(ar->hw->wiphy)); | ||
1457 | ar9170_dump_txqueue(ar, &ar->tx_pending[i]); | ||
1458 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1459 | |||
1460 | if (unlikely(frames_failed)) { | ||
1461 | #ifdef AR9170_QUEUE_DEBUG | ||
1462 | printk(KERN_DEBUG "%s: frames failed =>\n", | ||
1463 | wiphy_name(ar->hw->wiphy), frames_failed); | ||
1464 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1465 | |||
1466 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | ||
1467 | ar->tx_stats[i].len -= frames_failed; | ||
1468 | ar->tx_stats[i].count -= frames_failed; | ||
1469 | ieee80211_wake_queue(ar->hw, i); | ||
1470 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1226 | } | 1471 | } |
1227 | } | 1472 | } |
1228 | 1473 | ||
1229 | err = ar->tx(ar, skb, tx_status, 0); | 1474 | if (schedule_garbagecollector) |
1230 | if (unlikely(tx_status && err)) { | 1475 | queue_delayed_work(ar->hw->workqueue, |
1231 | if (info->control.sta) | 1476 | &ar->tx_janitor, |
1232 | skb_unlink(skb, &sta_info->tx_status[queue]); | 1477 | msecs_to_jiffies(AR9170_JANITOR_DELAY)); |
1233 | else | 1478 | } |
1234 | skb_unlink(skb, &ar->global_tx_status); | 1479 | |
1480 | int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
1481 | { | ||
1482 | struct ar9170 *ar = hw->priv; | ||
1483 | struct ieee80211_tx_info *info; | ||
1484 | |||
1485 | if (unlikely(!IS_STARTED(ar))) | ||
1486 | goto err_free; | ||
1487 | |||
1488 | if (unlikely(ar9170_tx_prepare(ar, skb))) | ||
1489 | goto err_free; | ||
1490 | |||
1491 | info = IEEE80211_SKB_CB(skb); | ||
1492 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
1493 | /* drop frame, we do not allow TX A-MPDU aggregation yet. */ | ||
1494 | goto err_free; | ||
1495 | } else { | ||
1496 | unsigned int queue = skb_get_queue_mapping(skb); | ||
1497 | |||
1498 | ar9170_tx_prepare_phy(ar, skb); | ||
1499 | skb_queue_tail(&ar->tx_pending[queue], skb); | ||
1235 | } | 1500 | } |
1236 | 1501 | ||
1502 | ar9170_tx(ar); | ||
1237 | return NETDEV_TX_OK; | 1503 | return NETDEV_TX_OK; |
1238 | 1504 | ||
1239 | err_dequeue: | ||
1240 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | ||
1241 | ar->tx_stats[queue].len--; | ||
1242 | ar->tx_stats[queue].count--; | ||
1243 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1244 | |||
1245 | err_free: | 1505 | err_free: |
1246 | dev_kfree_skb(skb); | 1506 | dev_kfree_skb_any(skb); |
1247 | return NETDEV_TX_OK; | 1507 | return NETDEV_TX_OK; |
1248 | } | 1508 | } |
1249 | 1509 | ||
@@ -1306,11 +1566,6 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed) | |||
1306 | 1566 | ||
1307 | mutex_lock(&ar->mutex); | 1567 | mutex_lock(&ar->mutex); |
1308 | 1568 | ||
1309 | if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) { | ||
1310 | /* TODO */ | ||
1311 | err = 0; | ||
1312 | } | ||
1313 | |||
1314 | if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { | 1569 | if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { |
1315 | /* TODO */ | 1570 | /* TODO */ |
1316 | err = 0; | 1571 | err = 0; |
@@ -1344,15 +1599,21 @@ static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed) | |||
1344 | } | 1599 | } |
1345 | 1600 | ||
1346 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 1601 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
1602 | |||
1603 | /* adjust slot time for 5 GHz */ | ||
1604 | err = ar9170_set_slot_time(ar); | ||
1605 | if (err) | ||
1606 | goto out; | ||
1607 | |||
1608 | err = ar9170_set_dyn_sifs_ack(ar); | ||
1609 | if (err) | ||
1610 | goto out; | ||
1611 | |||
1347 | err = ar9170_set_channel(ar, hw->conf.channel, | 1612 | err = ar9170_set_channel(ar, hw->conf.channel, |
1348 | AR9170_RFI_NONE, | 1613 | AR9170_RFI_NONE, |
1349 | nl80211_to_ar9170(hw->conf.channel_type)); | 1614 | nl80211_to_ar9170(hw->conf.channel_type)); |
1350 | if (err) | 1615 | if (err) |
1351 | goto out; | 1616 | 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 | } | 1617 | } |
1357 | 1618 | ||
1358 | out: | 1619 | out: |
@@ -1370,20 +1631,26 @@ static void ar9170_set_filters(struct work_struct *work) | |||
1370 | return ; | 1631 | return ; |
1371 | 1632 | ||
1372 | mutex_lock(&ar->mutex); | 1633 | mutex_lock(&ar->mutex); |
1373 | if (ar->filter_changed & AR9170_FILTER_CHANGED_PROMISC) { | 1634 | if (test_and_clear_bit(AR9170_FILTER_CHANGED_MODE, |
1635 | &ar->filter_changed)) { | ||
1374 | err = ar9170_set_operating_mode(ar); | 1636 | err = ar9170_set_operating_mode(ar); |
1375 | if (err) | 1637 | if (err) |
1376 | goto unlock; | 1638 | goto unlock; |
1377 | } | 1639 | } |
1378 | 1640 | ||
1379 | if (ar->filter_changed & AR9170_FILTER_CHANGED_MULTICAST) { | 1641 | if (test_and_clear_bit(AR9170_FILTER_CHANGED_MULTICAST, |
1642 | &ar->filter_changed)) { | ||
1380 | err = ar9170_update_multicast(ar); | 1643 | err = ar9170_update_multicast(ar); |
1381 | if (err) | 1644 | if (err) |
1382 | goto unlock; | 1645 | goto unlock; |
1383 | } | 1646 | } |
1384 | 1647 | ||
1385 | if (ar->filter_changed & AR9170_FILTER_CHANGED_FRAMEFILTER) | 1648 | if (test_and_clear_bit(AR9170_FILTER_CHANGED_FRAMEFILTER, |
1649 | &ar->filter_changed)) { | ||
1386 | err = ar9170_update_frame_filter(ar); | 1650 | err = ar9170_update_frame_filter(ar); |
1651 | if (err) | ||
1652 | goto unlock; | ||
1653 | } | ||
1387 | 1654 | ||
1388 | unlock: | 1655 | unlock: |
1389 | mutex_unlock(&ar->mutex); | 1656 | mutex_unlock(&ar->mutex); |
@@ -1413,7 +1680,7 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw, | |||
1413 | int i; | 1680 | int i; |
1414 | 1681 | ||
1415 | /* always get broadcast frames */ | 1682 | /* always get broadcast frames */ |
1416 | mchash = 1ULL << (0xff>>2); | 1683 | mchash = 1ULL << (0xff >> 2); |
1417 | 1684 | ||
1418 | for (i = 0; i < mc_count; i++) { | 1685 | for (i = 0; i < mc_count; i++) { |
1419 | if (WARN_ON(!mclist)) | 1686 | if (WARN_ON(!mclist)) |
@@ -1423,7 +1690,7 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw, | |||
1423 | } | 1690 | } |
1424 | ar->want_mc_hash = mchash; | 1691 | ar->want_mc_hash = mchash; |
1425 | } | 1692 | } |
1426 | ar->filter_changed |= AR9170_FILTER_CHANGED_MULTICAST; | 1693 | set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed); |
1427 | } | 1694 | } |
1428 | 1695 | ||
1429 | if (changed_flags & FIF_CONTROL) { | 1696 | if (changed_flags & FIF_CONTROL) { |
@@ -1439,12 +1706,14 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw, | |||
1439 | else | 1706 | else |
1440 | ar->want_filter = ar->cur_filter & ~filter; | 1707 | ar->want_filter = ar->cur_filter & ~filter; |
1441 | 1708 | ||
1442 | ar->filter_changed |= AR9170_FILTER_CHANGED_FRAMEFILTER; | 1709 | set_bit(AR9170_FILTER_CHANGED_FRAMEFILTER, |
1710 | &ar->filter_changed); | ||
1443 | } | 1711 | } |
1444 | 1712 | ||
1445 | if (changed_flags & FIF_PROMISC_IN_BSS) { | 1713 | if (changed_flags & FIF_PROMISC_IN_BSS) { |
1446 | ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0; | 1714 | ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0; |
1447 | ar->filter_changed |= AR9170_FILTER_CHANGED_PROMISC; | 1715 | set_bit(AR9170_FILTER_CHANGED_MODE, |
1716 | &ar->filter_changed); | ||
1448 | } | 1717 | } |
1449 | 1718 | ||
1450 | if (likely(IS_STARTED(ar))) | 1719 | if (likely(IS_STARTED(ar))) |
@@ -1464,27 +1733,32 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1464 | if (changed & BSS_CHANGED_BSSID) { | 1733 | if (changed & BSS_CHANGED_BSSID) { |
1465 | memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN); | 1734 | memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN); |
1466 | err = ar9170_set_operating_mode(ar); | 1735 | err = ar9170_set_operating_mode(ar); |
1736 | if (err) | ||
1737 | goto out; | ||
1467 | } | 1738 | } |
1468 | 1739 | ||
1469 | if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) { | 1740 | if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) { |
1470 | err = ar9170_update_beacon(ar); | 1741 | err = ar9170_update_beacon(ar); |
1471 | if (!err) | 1742 | if (err) |
1472 | ar9170_set_beacon_timers(ar); | 1743 | goto out; |
1473 | } | ||
1474 | 1744 | ||
1475 | ar9170_regwrite_begin(ar); | 1745 | err = ar9170_set_beacon_timers(ar); |
1746 | if (err) | ||
1747 | goto out; | ||
1748 | } | ||
1476 | 1749 | ||
1477 | if (changed & BSS_CHANGED_ASSOC) { | 1750 | if (changed & BSS_CHANGED_ASSOC) { |
1478 | ar->state = bss_conf->assoc ? AR9170_ASSOCIATED : ar->state; | ||
1479 | |||
1480 | #ifndef CONFIG_AR9170_LEDS | 1751 | #ifndef CONFIG_AR9170_LEDS |
1481 | /* enable assoc LED. */ | 1752 | /* enable assoc LED. */ |
1482 | err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0); | 1753 | err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0); |
1483 | #endif /* CONFIG_AR9170_LEDS */ | 1754 | #endif /* CONFIG_AR9170_LEDS */ |
1484 | } | 1755 | } |
1485 | 1756 | ||
1486 | if (changed & BSS_CHANGED_BEACON_INT) | 1757 | if (changed & BSS_CHANGED_BEACON_INT) { |
1487 | err = ar9170_set_beacon_timers(ar); | 1758 | err = ar9170_set_beacon_timers(ar); |
1759 | if (err) | ||
1760 | goto out; | ||
1761 | } | ||
1488 | 1762 | ||
1489 | if (changed & BSS_CHANGED_HT) { | 1763 | if (changed & BSS_CHANGED_HT) { |
1490 | /* TODO */ | 1764 | /* TODO */ |
@@ -1492,31 +1766,18 @@ static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, | |||
1492 | } | 1766 | } |
1493 | 1767 | ||
1494 | if (changed & BSS_CHANGED_ERP_SLOT) { | 1768 | if (changed & BSS_CHANGED_ERP_SLOT) { |
1495 | u32 slottime = 20; | 1769 | err = ar9170_set_slot_time(ar); |
1496 | 1770 | if (err) | |
1497 | if (bss_conf->use_short_slot) | 1771 | goto out; |
1498 | slottime = 9; | ||
1499 | |||
1500 | ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, slottime << 10); | ||
1501 | } | 1772 | } |
1502 | 1773 | ||
1503 | if (changed & BSS_CHANGED_BASIC_RATES) { | 1774 | if (changed & BSS_CHANGED_BASIC_RATES) { |
1504 | u32 cck, ofdm; | 1775 | err = ar9170_set_basic_rates(ar); |
1505 | 1776 | if (err) | |
1506 | if (hw->conf.channel->band == IEEE80211_BAND_5GHZ) { | 1777 | 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 | } | 1778 | } |
1517 | 1779 | ||
1518 | ar9170_regwrite_finish(); | 1780 | out: |
1519 | err = ar9170_regwrite_result(); | ||
1520 | mutex_unlock(&ar->mutex); | 1781 | mutex_unlock(&ar->mutex); |
1521 | } | 1782 | } |
1522 | 1783 | ||
@@ -1668,43 +1929,6 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw, | |||
1668 | enum sta_notify_cmd cmd, | 1929 | enum sta_notify_cmd cmd, |
1669 | struct ieee80211_sta *sta) | 1930 | struct ieee80211_sta *sta) |
1670 | { | 1931 | { |
1671 | struct ar9170 *ar = hw->priv; | ||
1672 | struct ar9170_sta_info *info = (void *) sta->drv_priv; | ||
1673 | struct sk_buff *skb; | ||
1674 | unsigned int i; | ||
1675 | |||
1676 | switch (cmd) { | ||
1677 | case STA_NOTIFY_ADD: | ||
1678 | for (i = 0; i < ar->hw->queues; i++) | ||
1679 | skb_queue_head_init(&info->tx_status[i]); | ||
1680 | break; | ||
1681 | |||
1682 | case STA_NOTIFY_REMOVE: | ||
1683 | |||
1684 | /* | ||
1685 | * transfer all outstanding frames that need a tx_status | ||
1686 | * reports to the global tx_status queue | ||
1687 | */ | ||
1688 | |||
1689 | for (i = 0; i < ar->hw->queues; i++) { | ||
1690 | while ((skb = skb_dequeue(&info->tx_status[i]))) { | ||
1691 | #ifdef AR9170_QUEUE_DEBUG | ||
1692 | printk(KERN_DEBUG "%s: queueing frame in " | ||
1693 | "global tx_status queue =>\n", | ||
1694 | wiphy_name(ar->hw->wiphy)); | ||
1695 | |||
1696 | ar9170_print_txheader(ar, skb); | ||
1697 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1698 | skb_queue_tail(&ar->global_tx_status, skb); | ||
1699 | } | ||
1700 | } | ||
1701 | queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor, | ||
1702 | msecs_to_jiffies(100)); | ||
1703 | break; | ||
1704 | |||
1705 | default: | ||
1706 | break; | ||
1707 | } | ||
1708 | } | 1932 | } |
1709 | 1933 | ||
1710 | static int ar9170_get_stats(struct ieee80211_hw *hw, | 1934 | static int ar9170_get_stats(struct ieee80211_hw *hw, |
@@ -1743,7 +1967,7 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
1743 | int ret; | 1967 | int ret; |
1744 | 1968 | ||
1745 | mutex_lock(&ar->mutex); | 1969 | mutex_lock(&ar->mutex); |
1746 | if ((param) && !(queue > ar->hw->queues)) { | 1970 | if ((param) && !(queue > __AR9170_NUM_TXQ)) { |
1747 | memcpy(&ar->edcf[ar9170_qos_hwmap[queue]], | 1971 | memcpy(&ar->edcf[ar9170_qos_hwmap[queue]], |
1748 | param, sizeof(*param)); | 1972 | param, sizeof(*param)); |
1749 | 1973 | ||
@@ -1819,12 +2043,14 @@ void *ar9170_alloc(size_t priv_size) | |||
1819 | mutex_init(&ar->mutex); | 2043 | mutex_init(&ar->mutex); |
1820 | spin_lock_init(&ar->cmdlock); | 2044 | spin_lock_init(&ar->cmdlock); |
1821 | spin_lock_init(&ar->tx_stats_lock); | 2045 | spin_lock_init(&ar->tx_stats_lock); |
1822 | skb_queue_head_init(&ar->global_tx_status); | 2046 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { |
1823 | skb_queue_head_init(&ar->global_tx_status_waste); | 2047 | skb_queue_head_init(&ar->tx_status[i]); |
2048 | skb_queue_head_init(&ar->tx_pending[i]); | ||
2049 | } | ||
1824 | ar9170_rx_reset_rx_mpdu(ar); | 2050 | ar9170_rx_reset_rx_mpdu(ar); |
1825 | INIT_WORK(&ar->filter_config_work, ar9170_set_filters); | 2051 | INIT_WORK(&ar->filter_config_work, ar9170_set_filters); |
1826 | INIT_WORK(&ar->beacon_work, ar9170_new_beacon); | 2052 | INIT_WORK(&ar->beacon_work, ar9170_new_beacon); |
1827 | INIT_DELAYED_WORK(&ar->tx_status_janitor, ar9170_tx_status_janitor); | 2053 | INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor); |
1828 | 2054 | ||
1829 | /* all hw supports 2.4 GHz, so set channel to 1 by default */ | 2055 | /* all hw supports 2.4 GHz, so set channel to 1 by default */ |
1830 | ar->channel = &ar9170_2ghz_chantable[0]; | 2056 | ar->channel = &ar9170_2ghz_chantable[0]; |
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..754b1f8d8da9 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>"); | |||
51 | MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>"); | 51 | MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>"); |
52 | MODULE_LICENSE("GPL"); | 52 | MODULE_LICENSE("GPL"); |
53 | MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless"); | 53 | MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless"); |
54 | MODULE_FIRMWARE("ar9170.fw"); | ||
54 | MODULE_FIRMWARE("ar9170-1.fw"); | 55 | MODULE_FIRMWARE("ar9170-1.fw"); |
55 | MODULE_FIRMWARE("ar9170-2.fw"); | 56 | MODULE_FIRMWARE("ar9170-2.fw"); |
56 | 57 | ||
58 | enum ar9170_requirements { | ||
59 | AR9170_REQ_FW1_ONLY = 1, | ||
60 | }; | ||
61 | |||
57 | static struct usb_device_id ar9170_usb_ids[] = { | 62 | static struct usb_device_id ar9170_usb_ids[] = { |
58 | /* Atheros 9170 */ | 63 | /* Atheros 9170 */ |
59 | { USB_DEVICE(0x0cf3, 0x9170) }, | 64 | { USB_DEVICE(0x0cf3, 0x9170) }, |
@@ -81,25 +86,74 @@ 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 | {} |
87 | }; | 96 | }; |
88 | MODULE_DEVICE_TABLE(usb, ar9170_usb_ids); | 97 | MODULE_DEVICE_TABLE(usb, ar9170_usb_ids); |
89 | 98 | ||
90 | static void ar9170_usb_tx_urb_complete_free(struct urb *urb) | 99 | static void ar9170_usb_submit_urb(struct ar9170_usb *aru) |
100 | { | ||
101 | struct urb *urb; | ||
102 | unsigned long flags; | ||
103 | int err; | ||
104 | |||
105 | if (unlikely(!IS_STARTED(&aru->common))) | ||
106 | return ; | ||
107 | |||
108 | spin_lock_irqsave(&aru->tx_urb_lock, flags); | ||
109 | if (aru->tx_submitted_urbs >= AR9170_NUM_TX_URBS) { | ||
110 | spin_unlock_irqrestore(&aru->tx_urb_lock, flags); | ||
111 | return ; | ||
112 | } | ||
113 | aru->tx_submitted_urbs++; | ||
114 | |||
115 | urb = usb_get_from_anchor(&aru->tx_pending); | ||
116 | if (!urb) { | ||
117 | aru->tx_submitted_urbs--; | ||
118 | spin_unlock_irqrestore(&aru->tx_urb_lock, flags); | ||
119 | |||
120 | return ; | ||
121 | } | ||
122 | spin_unlock_irqrestore(&aru->tx_urb_lock, flags); | ||
123 | |||
124 | aru->tx_pending_urbs--; | ||
125 | usb_anchor_urb(urb, &aru->tx_submitted); | ||
126 | |||
127 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
128 | if (unlikely(err)) { | ||
129 | if (ar9170_nag_limiter(&aru->common)) | ||
130 | dev_err(&aru->udev->dev, "submit_urb failed (%d).\n", | ||
131 | err); | ||
132 | |||
133 | usb_unanchor_urb(urb); | ||
134 | aru->tx_submitted_urbs--; | ||
135 | ar9170_tx_callback(&aru->common, urb->context); | ||
136 | } | ||
137 | |||
138 | usb_free_urb(urb); | ||
139 | } | ||
140 | |||
141 | static void ar9170_usb_tx_urb_complete_frame(struct urb *urb) | ||
91 | { | 142 | { |
92 | struct sk_buff *skb = urb->context; | 143 | struct sk_buff *skb = urb->context; |
93 | struct ar9170_usb *aru = (struct ar9170_usb *) | 144 | struct ar9170_usb *aru = (struct ar9170_usb *) |
94 | usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); | 145 | usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); |
95 | 146 | ||
96 | if (!aru) { | 147 | if (unlikely(!aru)) { |
97 | dev_kfree_skb_irq(skb); | 148 | dev_kfree_skb_irq(skb); |
98 | return ; | 149 | return ; |
99 | } | 150 | } |
100 | 151 | ||
101 | ar9170_handle_tx_status(&aru->common, skb, false, | 152 | aru->tx_submitted_urbs--; |
102 | AR9170_TX_STATUS_COMPLETE); | 153 | |
154 | ar9170_tx_callback(&aru->common, skb); | ||
155 | |||
156 | ar9170_usb_submit_urb(aru); | ||
103 | } | 157 | } |
104 | 158 | ||
105 | static void ar9170_usb_tx_urb_complete(struct urb *urb) | 159 | static void ar9170_usb_tx_urb_complete(struct urb *urb) |
@@ -126,8 +180,8 @@ static void ar9170_usb_irq_completed(struct urb *urb) | |||
126 | goto resubmit; | 180 | goto resubmit; |
127 | } | 181 | } |
128 | 182 | ||
129 | print_hex_dump_bytes("ar9170 irq: ", DUMP_PREFIX_OFFSET, | 183 | ar9170_handle_command_response(&aru->common, urb->transfer_buffer, |
130 | urb->transfer_buffer, urb->actual_length); | 184 | urb->actual_length); |
131 | 185 | ||
132 | resubmit: | 186 | resubmit: |
133 | usb_anchor_urb(urb, &aru->rx_submitted); | 187 | usb_anchor_urb(urb, &aru->rx_submitted); |
@@ -177,16 +231,15 @@ resubmit: | |||
177 | 231 | ||
178 | usb_anchor_urb(urb, &aru->rx_submitted); | 232 | usb_anchor_urb(urb, &aru->rx_submitted); |
179 | err = usb_submit_urb(urb, GFP_ATOMIC); | 233 | err = usb_submit_urb(urb, GFP_ATOMIC); |
180 | if (err) { | 234 | if (unlikely(err)) { |
181 | usb_unanchor_urb(urb); | 235 | usb_unanchor_urb(urb); |
182 | dev_kfree_skb_irq(skb); | 236 | goto free; |
183 | } | 237 | } |
184 | 238 | ||
185 | return ; | 239 | return ; |
186 | 240 | ||
187 | free: | 241 | free: |
188 | dev_kfree_skb_irq(skb); | 242 | dev_kfree_skb_irq(skb); |
189 | return; | ||
190 | } | 243 | } |
191 | 244 | ||
192 | static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru, | 245 | static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru, |
@@ -282,21 +335,47 @@ err_out: | |||
282 | return err; | 335 | return err; |
283 | } | 336 | } |
284 | 337 | ||
285 | static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru) | 338 | static int ar9170_usb_flush(struct ar9170 *ar) |
286 | { | 339 | { |
287 | int ret; | 340 | struct ar9170_usb *aru = (void *) ar; |
341 | struct urb *urb; | ||
342 | int ret, err = 0; | ||
288 | 343 | ||
289 | aru->common.state = AR9170_UNKNOWN_STATE; | 344 | if (IS_STARTED(ar)) |
345 | aru->common.state = AR9170_IDLE; | ||
290 | 346 | ||
291 | usb_unlink_anchored_urbs(&aru->tx_submitted); | 347 | usb_wait_anchor_empty_timeout(&aru->tx_pending, |
348 | msecs_to_jiffies(800)); | ||
349 | while ((urb = usb_get_from_anchor(&aru->tx_pending))) { | ||
350 | ar9170_tx_callback(&aru->common, (void *) urb->context); | ||
351 | usb_free_urb(urb); | ||
352 | } | ||
292 | 353 | ||
293 | /* give the LED OFF command and the deauth frame a chance to air. */ | 354 | /* lets wait a while until the tx - queues are dried out */ |
294 | ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, | 355 | ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, |
295 | msecs_to_jiffies(100)); | 356 | msecs_to_jiffies(100)); |
296 | if (ret == 0) | 357 | if (ret == 0) |
297 | dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); | 358 | err = -ETIMEDOUT; |
298 | usb_poison_anchored_urbs(&aru->tx_submitted); | 359 | |
360 | usb_kill_anchored_urbs(&aru->tx_submitted); | ||
361 | |||
362 | if (IS_ACCEPTING_CMD(ar)) | ||
363 | aru->common.state = AR9170_STARTED; | ||
299 | 364 | ||
365 | return err; | ||
366 | } | ||
367 | |||
368 | static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru) | ||
369 | { | ||
370 | int err; | ||
371 | |||
372 | aru->common.state = AR9170_UNKNOWN_STATE; | ||
373 | |||
374 | err = ar9170_usb_flush(&aru->common); | ||
375 | if (err) | ||
376 | dev_err(&aru->udev->dev, "stuck tx urbs!\n"); | ||
377 | |||
378 | usb_poison_anchored_urbs(&aru->tx_submitted); | ||
300 | usb_poison_anchored_urbs(&aru->rx_submitted); | 379 | usb_poison_anchored_urbs(&aru->rx_submitted); |
301 | } | 380 | } |
302 | 381 | ||
@@ -337,7 +416,7 @@ static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd, | |||
337 | 416 | ||
338 | usb_anchor_urb(urb, &aru->tx_submitted); | 417 | usb_anchor_urb(urb, &aru->tx_submitted); |
339 | err = usb_submit_urb(urb, GFP_ATOMIC); | 418 | err = usb_submit_urb(urb, GFP_ATOMIC); |
340 | if (err) { | 419 | if (unlikely(err)) { |
341 | usb_unanchor_urb(urb); | 420 | usb_unanchor_urb(urb); |
342 | usb_free_urb(urb); | 421 | usb_free_urb(urb); |
343 | goto err_unbuf; | 422 | goto err_unbuf; |
@@ -380,12 +459,10 @@ err_free: | |||
380 | return err; | 459 | return err; |
381 | } | 460 | } |
382 | 461 | ||
383 | static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb, | 462 | static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb) |
384 | bool txstatus_needed, unsigned int extra_len) | ||
385 | { | 463 | { |
386 | struct ar9170_usb *aru = (struct ar9170_usb *) ar; | 464 | struct ar9170_usb *aru = (struct ar9170_usb *) ar; |
387 | struct urb *urb; | 465 | struct urb *urb; |
388 | int err; | ||
389 | 466 | ||
390 | if (unlikely(!IS_STARTED(ar))) { | 467 | if (unlikely(!IS_STARTED(ar))) { |
391 | /* Seriously, what were you drink... err... thinking!? */ | 468 | /* Seriously, what were you drink... err... thinking!? */ |
@@ -398,18 +475,17 @@ static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb, | |||
398 | 475 | ||
399 | usb_fill_bulk_urb(urb, aru->udev, | 476 | usb_fill_bulk_urb(urb, aru->udev, |
400 | usb_sndbulkpipe(aru->udev, AR9170_EP_TX), | 477 | usb_sndbulkpipe(aru->udev, AR9170_EP_TX), |
401 | skb->data, skb->len + extra_len, (txstatus_needed ? | 478 | skb->data, skb->len, |
402 | ar9170_usb_tx_urb_complete : | 479 | ar9170_usb_tx_urb_complete_frame, skb); |
403 | ar9170_usb_tx_urb_complete_free), skb); | ||
404 | urb->transfer_flags |= URB_ZERO_PACKET; | 480 | urb->transfer_flags |= URB_ZERO_PACKET; |
405 | 481 | ||
406 | usb_anchor_urb(urb, &aru->tx_submitted); | 482 | usb_anchor_urb(urb, &aru->tx_pending); |
407 | err = usb_submit_urb(urb, GFP_ATOMIC); | 483 | aru->tx_pending_urbs++; |
408 | if (unlikely(err)) | ||
409 | usb_unanchor_urb(urb); | ||
410 | 484 | ||
411 | usb_free_urb(urb); | 485 | usb_free_urb(urb); |
412 | return err; | 486 | |
487 | ar9170_usb_submit_urb(aru); | ||
488 | return 0; | ||
413 | } | 489 | } |
414 | 490 | ||
415 | static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer) | 491 | static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer) |
@@ -418,7 +494,7 @@ static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer) | |||
418 | unsigned long flags; | 494 | unsigned long flags; |
419 | u32 in, out; | 495 | u32 in, out; |
420 | 496 | ||
421 | if (!buffer) | 497 | if (unlikely(!buffer)) |
422 | return ; | 498 | return ; |
423 | 499 | ||
424 | in = le32_to_cpup((__le32 *)buffer); | 500 | in = le32_to_cpup((__le32 *)buffer); |
@@ -504,17 +580,29 @@ static int ar9170_usb_request_firmware(struct ar9170_usb *aru) | |||
504 | { | 580 | { |
505 | int err = 0; | 581 | int err = 0; |
506 | 582 | ||
507 | err = request_firmware(&aru->init_values, "ar9170-1.fw", | 583 | err = request_firmware(&aru->firmware, "ar9170.fw", |
508 | &aru->udev->dev); | 584 | &aru->udev->dev); |
509 | if (err) { | 585 | if (!err) { |
510 | dev_err(&aru->udev->dev, "file with init values not found.\n"); | 586 | aru->init_values = NULL; |
511 | return err; | 587 | return 0; |
588 | } | ||
589 | |||
590 | if (aru->req_one_stage_fw) { | ||
591 | dev_err(&aru->udev->dev, "ar9170.fw firmware file " | ||
592 | "not found and is required for this device\n"); | ||
593 | return -EINVAL; | ||
512 | } | 594 | } |
513 | 595 | ||
596 | dev_err(&aru->udev->dev, "ar9170.fw firmware file " | ||
597 | "not found, trying old firmware...\n"); | ||
598 | |||
599 | err = request_firmware(&aru->init_values, "ar9170-1.fw", | ||
600 | &aru->udev->dev); | ||
601 | |||
514 | err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev); | 602 | err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev); |
515 | if (err) { | 603 | if (err) { |
516 | release_firmware(aru->init_values); | 604 | release_firmware(aru->init_values); |
517 | dev_err(&aru->udev->dev, "firmware file not found.\n"); | 605 | dev_err(&aru->udev->dev, "file with init values not found.\n"); |
518 | return err; | 606 | return err; |
519 | } | 607 | } |
520 | 608 | ||
@@ -548,6 +636,9 @@ static int ar9170_usb_upload_firmware(struct ar9170_usb *aru) | |||
548 | { | 636 | { |
549 | int err; | 637 | int err; |
550 | 638 | ||
639 | if (!aru->init_values) | ||
640 | goto upload_fw_start; | ||
641 | |||
551 | /* First, upload initial values to device RAM */ | 642 | /* First, upload initial values to device RAM */ |
552 | err = ar9170_usb_upload(aru, aru->init_values->data, | 643 | err = ar9170_usb_upload(aru, aru->init_values->data, |
553 | aru->init_values->size, 0x102800, false); | 644 | aru->init_values->size, 0x102800, false); |
@@ -557,6 +648,8 @@ static int ar9170_usb_upload_firmware(struct ar9170_usb *aru) | |||
557 | return err; | 648 | return err; |
558 | } | 649 | } |
559 | 650 | ||
651 | upload_fw_start: | ||
652 | |||
560 | /* Then, upload the firmware itself and start it */ | 653 | /* Then, upload the firmware itself and start it */ |
561 | return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size, | 654 | return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size, |
562 | 0x200000, true); | 655 | 0x200000, true); |
@@ -592,10 +685,8 @@ static void ar9170_usb_stop(struct ar9170 *ar) | |||
592 | if (IS_ACCEPTING_CMD(ar)) | 685 | if (IS_ACCEPTING_CMD(ar)) |
593 | aru->common.state = AR9170_STOPPED; | 686 | aru->common.state = AR9170_STOPPED; |
594 | 687 | ||
595 | /* lets wait a while until the tx - queues are dried out */ | 688 | ret = ar9170_usb_flush(ar); |
596 | ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, | 689 | if (ret) |
597 | msecs_to_jiffies(1000)); | ||
598 | if (ret == 0) | ||
599 | dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); | 690 | dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); |
600 | 691 | ||
601 | usb_poison_anchored_urbs(&aru->tx_submitted); | 692 | usb_poison_anchored_urbs(&aru->tx_submitted); |
@@ -656,6 +747,15 @@ err_out: | |||
656 | return err; | 747 | return err; |
657 | } | 748 | } |
658 | 749 | ||
750 | static bool ar9170_requires_one_stage(const struct usb_device_id *id) | ||
751 | { | ||
752 | if (!id->driver_info) | ||
753 | return false; | ||
754 | if (id->driver_info == AR9170_REQ_FW1_ONLY) | ||
755 | return true; | ||
756 | return false; | ||
757 | } | ||
758 | |||
659 | static int ar9170_usb_probe(struct usb_interface *intf, | 759 | static int ar9170_usb_probe(struct usb_interface *intf, |
660 | const struct usb_device_id *id) | 760 | const struct usb_device_id *id) |
661 | { | 761 | { |
@@ -676,14 +776,22 @@ static int ar9170_usb_probe(struct usb_interface *intf, | |||
676 | aru->intf = intf; | 776 | aru->intf = intf; |
677 | ar = &aru->common; | 777 | ar = &aru->common; |
678 | 778 | ||
779 | aru->req_one_stage_fw = ar9170_requires_one_stage(id); | ||
780 | |||
679 | usb_set_intfdata(intf, aru); | 781 | usb_set_intfdata(intf, aru); |
680 | SET_IEEE80211_DEV(ar->hw, &udev->dev); | 782 | SET_IEEE80211_DEV(ar->hw, &udev->dev); |
681 | 783 | ||
682 | init_usb_anchor(&aru->rx_submitted); | 784 | init_usb_anchor(&aru->rx_submitted); |
785 | init_usb_anchor(&aru->tx_pending); | ||
683 | init_usb_anchor(&aru->tx_submitted); | 786 | init_usb_anchor(&aru->tx_submitted); |
684 | init_completion(&aru->cmd_wait); | 787 | init_completion(&aru->cmd_wait); |
788 | spin_lock_init(&aru->tx_urb_lock); | ||
789 | |||
790 | aru->tx_pending_urbs = 0; | ||
791 | aru->tx_submitted_urbs = 0; | ||
685 | 792 | ||
686 | aru->common.stop = ar9170_usb_stop; | 793 | aru->common.stop = ar9170_usb_stop; |
794 | aru->common.flush = ar9170_usb_flush; | ||
687 | aru->common.open = ar9170_usb_open; | 795 | aru->common.open = ar9170_usb_open; |
688 | aru->common.tx = ar9170_usb_tx; | 796 | aru->common.tx = ar9170_usb_tx; |
689 | aru->common.exec_cmd = ar9170_usb_exec_cmd; | 797 | aru->common.exec_cmd = ar9170_usb_exec_cmd; |
@@ -691,7 +799,7 @@ static int ar9170_usb_probe(struct usb_interface *intf, | |||
691 | 799 | ||
692 | #ifdef CONFIG_PM | 800 | #ifdef CONFIG_PM |
693 | udev->reset_resume = 1; | 801 | udev->reset_resume = 1; |
694 | #endif | 802 | #endif /* CONFIG_PM */ |
695 | err = ar9170_usb_reset(aru); | 803 | err = ar9170_usb_reset(aru); |
696 | if (err) | 804 | if (err) |
697 | goto err_freehw; | 805 | goto err_freehw; |
@@ -776,11 +884,6 @@ static int ar9170_resume(struct usb_interface *intf) | |||
776 | usb_unpoison_anchored_urbs(&aru->rx_submitted); | 884 | usb_unpoison_anchored_urbs(&aru->rx_submitted); |
777 | usb_unpoison_anchored_urbs(&aru->tx_submitted); | 885 | usb_unpoison_anchored_urbs(&aru->tx_submitted); |
778 | 886 | ||
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); | 887 | err = ar9170_usb_init_device(aru); |
785 | if (err) | 888 | if (err) |
786 | goto err_unrx; | 889 | goto err_unrx; |
diff --git a/drivers/net/wireless/ath/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h index ac42586495d8..d098f4d5d2f2 100644 --- a/drivers/net/wireless/ath/ar9170/usb.h +++ b/drivers/net/wireless/ath/ar9170/usb.h | |||
@@ -51,6 +51,7 @@ | |||
51 | #include "ar9170.h" | 51 | #include "ar9170.h" |
52 | 52 | ||
53 | #define AR9170_NUM_RX_URBS 16 | 53 | #define AR9170_NUM_RX_URBS 16 |
54 | #define AR9170_NUM_TX_URBS 8 | ||
54 | 55 | ||
55 | struct firmware; | 56 | struct firmware; |
56 | 57 | ||
@@ -60,9 +61,15 @@ struct ar9170_usb { | |||
60 | struct usb_interface *intf; | 61 | struct usb_interface *intf; |
61 | 62 | ||
62 | struct usb_anchor rx_submitted; | 63 | struct usb_anchor rx_submitted; |
64 | struct usb_anchor tx_pending; | ||
63 | struct usb_anchor tx_submitted; | 65 | struct usb_anchor tx_submitted; |
64 | 66 | ||
65 | spinlock_t cmdlock; | 67 | bool req_one_stage_fw; |
68 | |||
69 | spinlock_t tx_urb_lock; | ||
70 | unsigned int tx_submitted_urbs; | ||
71 | unsigned int tx_pending_urbs; | ||
72 | |||
66 | struct completion cmd_wait; | 73 | struct completion cmd_wait; |
67 | int readlen; | 74 | int readlen; |
68 | u8 *readbuf; | 75 | u8 *readbuf; |
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile index 84a74c5248e5..090dc6d268a3 100644 --- a/drivers/net/wireless/ath/ath5k/Makefile +++ b/drivers/net/wireless/ath/ath5k/Makefile | |||
@@ -11,5 +11,6 @@ ath5k-y += reset.o | |||
11 | ath5k-y += attach.o | 11 | ath5k-y += attach.o |
12 | ath5k-y += base.o | 12 | ath5k-y += base.o |
13 | ath5k-y += led.o | 13 | ath5k-y += led.o |
14 | ath5k-y += rfkill.o | ||
14 | ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o | 15 | ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o |
15 | obj-$(CONFIG_ATH5K) += ath5k.o | 16 | obj-$(CONFIG_ATH5K) += ath5k.o |
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index 813718210338..6358233bac99 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -1256,6 +1256,10 @@ extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); | |||
1256 | extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); | 1256 | extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); |
1257 | extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); | 1257 | extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); |
1258 | 1258 | ||
1259 | /* rfkill Functions */ | ||
1260 | extern void ath5k_rfkill_hw_start(struct ath5k_hw *ah); | ||
1261 | extern void ath5k_rfkill_hw_stop(struct ath5k_hw *ah); | ||
1262 | |||
1259 | /* Misc functions */ | 1263 | /* Misc functions */ |
1260 | int ath5k_hw_set_capabilities(struct ath5k_hw *ah); | 1264 | int ath5k_hw_set_capabilities(struct ath5k_hw *ah); |
1261 | extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); | 1265 | extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index fb5193764afa..55f7de09d134 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 | ||
2073 | static 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 |
@@ -2353,6 +2360,8 @@ ath5k_init(struct ath5k_softc *sc) | |||
2353 | if (ret) | 2360 | if (ret) |
2354 | goto done; | 2361 | goto done; |
2355 | 2362 | ||
2363 | ath5k_rfkill_hw_start(ah); | ||
2364 | |||
2356 | /* | 2365 | /* |
2357 | * Reset the key cache since some parts do not reset the | 2366 | * Reset the key cache since some parts do not reset the |
2358 | * contents on initial power up or resume from suspend. | 2367 | * contents on initial power up or resume from suspend. |
@@ -2461,6 +2470,8 @@ ath5k_stop_hw(struct ath5k_softc *sc) | |||
2461 | tasklet_kill(&sc->restq); | 2470 | tasklet_kill(&sc->restq); |
2462 | tasklet_kill(&sc->beacontq); | 2471 | tasklet_kill(&sc->beacontq); |
2463 | 2472 | ||
2473 | ath5k_rfkill_hw_stop(sc->ah); | ||
2474 | |||
2464 | return ret; | 2475 | return ret; |
2465 | } | 2476 | } |
2466 | 2477 | ||
@@ -2519,6 +2530,9 @@ ath5k_intr(int irq, void *dev_id) | |||
2519 | */ | 2530 | */ |
2520 | ath5k_hw_update_mib_counters(ah, &sc->ll_stats); | 2531 | ath5k_hw_update_mib_counters(ah, &sc->ll_stats); |
2521 | } | 2532 | } |
2533 | if (status & AR5K_INT_GPIO) | ||
2534 | tasklet_schedule(&sc->rf_kill.toggleq); | ||
2535 | |||
2522 | } | 2536 | } |
2523 | } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); | 2537 | } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); |
2524 | 2538 | ||
@@ -2757,6 +2771,7 @@ ath5k_remove_interface(struct ieee80211_hw *hw, | |||
2757 | goto end; | 2771 | goto end; |
2758 | 2772 | ||
2759 | ath5k_hw_set_lladdr(sc->ah, mac); | 2773 | ath5k_hw_set_lladdr(sc->ah, mac); |
2774 | ath5k_beacon_disable(sc); | ||
2760 | sc->vif = NULL; | 2775 | sc->vif = NULL; |
2761 | end: | 2776 | end: |
2762 | mutex_unlock(&sc->lock); | 2777 | mutex_unlock(&sc->lock); |
@@ -2775,11 +2790,9 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed) | |||
2775 | 2790 | ||
2776 | mutex_lock(&sc->lock); | 2791 | mutex_lock(&sc->lock); |
2777 | 2792 | ||
2778 | sc->bintval = conf->beacon_int; | ||
2779 | |||
2780 | ret = ath5k_chan_set(sc, conf->channel); | 2793 | ret = ath5k_chan_set(sc, conf->channel); |
2781 | if (ret < 0) | 2794 | if (ret < 0) |
2782 | return ret; | 2795 | goto unlock; |
2783 | 2796 | ||
2784 | if ((changed & IEEE80211_CONF_CHANGE_POWER) && | 2797 | if ((changed & IEEE80211_CONF_CHANGE_POWER) && |
2785 | (sc->power_level != conf->power_level)) { | 2798 | (sc->power_level != conf->power_level)) { |
@@ -2808,8 +2821,9 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed) | |||
2808 | */ | 2821 | */ |
2809 | ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT); | 2822 | ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT); |
2810 | 2823 | ||
2824 | unlock: | ||
2811 | mutex_unlock(&sc->lock); | 2825 | mutex_unlock(&sc->lock); |
2812 | return 0; | 2826 | return ret; |
2813 | } | 2827 | } |
2814 | 2828 | ||
2815 | #define SUPPORTED_FIF_FLAGS \ | 2829 | #define SUPPORTED_FIF_FLAGS \ |
@@ -3061,7 +3075,14 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
3061 | { | 3075 | { |
3062 | int ret; | 3076 | int ret; |
3063 | struct ath5k_softc *sc = hw->priv; | 3077 | struct ath5k_softc *sc = hw->priv; |
3064 | struct sk_buff *skb = ieee80211_beacon_get(hw, vif); | 3078 | struct sk_buff *skb; |
3079 | |||
3080 | if (WARN_ON(!vif)) { | ||
3081 | ret = -EINVAL; | ||
3082 | goto out; | ||
3083 | } | ||
3084 | |||
3085 | skb = ieee80211_beacon_get(hw, vif); | ||
3065 | 3086 | ||
3066 | if (!skb) { | 3087 | if (!skb) { |
3067 | ret = -ENOMEM; | 3088 | ret = -ENOMEM; |
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 852b2c189fd8..f9b7f2f819b7 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/wireless.h> | 46 | #include <linux/wireless.h> |
47 | #include <linux/if_ether.h> | 47 | #include <linux/if_ether.h> |
48 | #include <linux/leds.h> | 48 | #include <linux/leds.h> |
49 | #include <linux/rfkill.h> | ||
49 | 50 | ||
50 | #include "ath5k.h" | 51 | #include "ath5k.h" |
51 | #include "debug.h" | 52 | #include "debug.h" |
@@ -91,6 +92,15 @@ struct ath5k_led | |||
91 | struct led_classdev led_dev; /* led classdev */ | 92 | struct led_classdev led_dev; /* led classdev */ |
92 | }; | 93 | }; |
93 | 94 | ||
95 | /* Rfkill */ | ||
96 | struct ath5k_rfkill { | ||
97 | /* GPIO PIN for rfkill */ | ||
98 | u16 gpio; | ||
99 | /* polarity of rfkill GPIO PIN */ | ||
100 | bool polarity; | ||
101 | /* RFKILL toggle tasklet */ | ||
102 | struct tasklet_struct toggleq; | ||
103 | }; | ||
94 | 104 | ||
95 | #if CHAN_DEBUG | 105 | #if CHAN_DEBUG |
96 | #define ATH_CHAN_MAX (26+26+26+200+200) | 106 | #define ATH_CHAN_MAX (26+26+26+200+200) |
@@ -167,6 +177,8 @@ struct ath5k_softc { | |||
167 | struct tasklet_struct txtq; /* tx intr tasklet */ | 177 | struct tasklet_struct txtq; /* tx intr tasklet */ |
168 | struct ath5k_led tx_led; /* tx led */ | 178 | struct ath5k_led tx_led; /* tx led */ |
169 | 179 | ||
180 | struct ath5k_rfkill rf_kill; | ||
181 | |||
170 | spinlock_t block; /* protects beacon */ | 182 | spinlock_t block; /* protects beacon */ |
171 | struct tasklet_struct beacontq; /* beacon intr tasklet */ | 183 | struct tasklet_struct beacontq; /* beacon intr tasklet */ |
172 | struct ath5k_buf *bbuf; /* beacon buffer */ | 184 | struct ath5k_buf *bbuf; /* beacon buffer */ |
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 66067733ddd3..bd0a97a38d34 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c | |||
@@ -1304,23 +1304,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1304 | if (ah->ah_version != AR5K_AR5210) | 1304 | if (ah->ah_version != AR5K_AR5210) |
1305 | ath5k_hw_set_imr(ah, ah->ah_imr); | 1305 | ath5k_hw_set_imr(ah, ah->ah_imr); |
1306 | 1306 | ||
1307 | /* | ||
1308 | * Setup RFKill interrupt if rfkill flag is set on eeprom. | ||
1309 | * TODO: Use gpio pin and polarity infos from eeprom | ||
1310 | * TODO: Handle this in ath5k_intr because it'll result | ||
1311 | * a nasty interrupt storm. | ||
1312 | */ | ||
1313 | #if 0 | ||
1314 | if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) { | ||
1315 | ath5k_hw_set_gpio_input(ah, 0); | ||
1316 | ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0); | ||
1317 | if (ah->ah_gpio[0] == 0) | ||
1318 | ath5k_hw_set_gpio_intr(ah, 0, 1); | ||
1319 | else | ||
1320 | ath5k_hw_set_gpio_intr(ah, 0, 0); | ||
1321 | } | ||
1322 | #endif | ||
1323 | |||
1324 | /* Enable 32KHz clock function for AR5212+ chips | 1307 | /* Enable 32KHz clock function for AR5212+ chips |
1325 | * Set clocks to 32KHz operation and use an | 1308 | * Set clocks to 32KHz operation and use an |
1326 | * external 32KHz crystal when sleeping if one | 1309 | * external 32KHz crystal when sleeping if one |
diff --git a/drivers/net/wireless/ath/ath5k/rfkill.c b/drivers/net/wireless/ath/ath5k/rfkill.c new file mode 100644 index 000000000000..41a877b73fce --- /dev/null +++ b/drivers/net/wireless/ath/ath5k/rfkill.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * RFKILL support for ath5k | ||
3 | * | ||
4 | * Copyright (c) 2009 Tobias Doerffel <tobias.doerffel@gmail.com> | ||
5 | * | ||
6 | * All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * 1. Redistributions of source code must retain the above copyright | ||
12 | * notice, this list of conditions and the following disclaimer, | ||
13 | * without modification. | ||
14 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
15 | * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any | ||
16 | * redistribution must be conditioned upon including a substantially | ||
17 | * similar Disclaimer requirement for further binary redistribution. | ||
18 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
19 | * of any contributors may be used to endorse or promote products derived | ||
20 | * from this software without specific prior written permission. | ||
21 | * | ||
22 | * NO WARRANTY | ||
23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
24 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
25 | * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY | ||
26 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | ||
27 | * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, | ||
28 | * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER | ||
31 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
32 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | ||
33 | * THE POSSIBILITY OF SUCH DAMAGES. | ||
34 | */ | ||
35 | |||
36 | #include "base.h" | ||
37 | |||
38 | |||
39 | static inline void ath5k_rfkill_disable(struct ath5k_softc *sc) | ||
40 | { | ||
41 | ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill disable (gpio:%d polarity:%d)\n", | ||
42 | sc->rf_kill.gpio, sc->rf_kill.polarity); | ||
43 | ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio); | ||
44 | ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, !sc->rf_kill.polarity); | ||
45 | } | ||
46 | |||
47 | |||
48 | static inline void ath5k_rfkill_enable(struct ath5k_softc *sc) | ||
49 | { | ||
50 | ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill enable (gpio:%d polarity:%d)\n", | ||
51 | sc->rf_kill.gpio, sc->rf_kill.polarity); | ||
52 | ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio); | ||
53 | ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, sc->rf_kill.polarity); | ||
54 | } | ||
55 | |||
56 | static inline void ath5k_rfkill_set_intr(struct ath5k_softc *sc, bool enable) | ||
57 | { | ||
58 | struct ath5k_hw *ah = sc->ah; | ||
59 | u32 curval; | ||
60 | |||
61 | ath5k_hw_set_gpio_input(ah, sc->rf_kill.gpio); | ||
62 | curval = ath5k_hw_get_gpio(ah, sc->rf_kill.gpio); | ||
63 | ath5k_hw_set_gpio_intr(ah, sc->rf_kill.gpio, enable ? | ||
64 | !!curval : !curval); | ||
65 | } | ||
66 | |||
67 | static bool | ||
68 | ath5k_is_rfkill_set(struct ath5k_softc *sc) | ||
69 | { | ||
70 | /* configuring GPIO for input for some reason disables rfkill */ | ||
71 | /*ath5k_hw_set_gpio_input(sc->ah, sc->rf_kill.gpio);*/ | ||
72 | return ath5k_hw_get_gpio(sc->ah, sc->rf_kill.gpio) == | ||
73 | sc->rf_kill.polarity; | ||
74 | } | ||
75 | |||
76 | static void | ||
77 | ath5k_tasklet_rfkill_toggle(unsigned long data) | ||
78 | { | ||
79 | struct ath5k_softc *sc = (void *)data; | ||
80 | bool blocked; | ||
81 | |||
82 | blocked = ath5k_is_rfkill_set(sc); | ||
83 | wiphy_rfkill_set_hw_state(sc->hw->wiphy, blocked); | ||
84 | } | ||
85 | |||
86 | |||
87 | void | ||
88 | ath5k_rfkill_hw_start(struct ath5k_hw *ah) | ||
89 | { | ||
90 | struct ath5k_softc *sc = ah->ah_sc; | ||
91 | |||
92 | /* read rfkill GPIO configuration from EEPROM header */ | ||
93 | sc->rf_kill.gpio = ah->ah_capabilities.cap_eeprom.ee_rfkill_pin; | ||
94 | sc->rf_kill.polarity = ah->ah_capabilities.cap_eeprom.ee_rfkill_pol; | ||
95 | |||
96 | tasklet_init(&sc->rf_kill.toggleq, ath5k_tasklet_rfkill_toggle, | ||
97 | (unsigned long)sc); | ||
98 | |||
99 | ath5k_rfkill_disable(sc); | ||
100 | |||
101 | /* enable interrupt for rfkill switch */ | ||
102 | if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) | ||
103 | ath5k_rfkill_set_intr(sc, true); | ||
104 | } | ||
105 | |||
106 | |||
107 | void | ||
108 | ath5k_rfkill_hw_stop(struct ath5k_hw *ah) | ||
109 | { | ||
110 | struct ath5k_softc *sc = ah->ah_sc; | ||
111 | |||
112 | /* disable interrupt for rfkill switch */ | ||
113 | if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) | ||
114 | ath5k_rfkill_set_intr(sc, false); | ||
115 | |||
116 | tasklet_kill(&sc->rf_kill.toggleq); | ||
117 | |||
118 | /* enable RFKILL when stopping HW so Wifi LED is turned off */ | ||
119 | ath5k_rfkill_enable(sc); | ||
120 | } | ||
121 | |||
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 | |||
466 | struct ath_rfkill { | 463 | struct 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 | ||
47 | static 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 | |||
58 | static 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 | |||
78 | static 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 | |||
47 | static ssize_t read_file_dma(struct file *file, char __user *user_buf, | 85 | static 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 | ||
227 | static void ath_debug_stat_11n_rc(struct ath_softc *sc, struct sk_buff *skb) | 265 | void 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 | |||
241 | static 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 | |||
255 | void 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 .. */ | ||
264 | void ath_debug_stat_retries(struct ath_softc *sc, int rix, | 280 | void 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 | ||
276 | static ssize_t ath_read_file_stat_11n_rc(struct file *file, | 290 | static 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 | ||
300 | static 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; | |
320 | static 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 | ||
334 | static const struct file_operations fops_rcstat = { | 327 | static 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 | ||
83 | struct ath_legacy_rc_stats { | 83 | struct ath_rc_stats { |
84 | u32 success; | ||
85 | }; | ||
86 | |||
87 | struct 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 | ||
94 | struct ath_stats { | 90 | struct 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 | ||
100 | struct ath9k_debug { | 95 | struct 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 */ |
1196 | static void ath_rfkill_poll(struct work_struct *work) | 1196 | static 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 */ | 1208 | static void ath_rfkill_poll_state(struct rfkill *rfkill, void *data) |
1238 | static 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 */ |
1266 | static int ath_init_sw_rfkill(struct ath_softc *sc) | 1220 | static 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 */ |
1286 | static void ath_deinit_rfkill(struct ath_softc *sc) | 1242 | static 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 | ||
1298 | static int ath_start_rfkill_poll(struct ath_softc *sc) | 1251 | static 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/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index a8def4fa449c..b61a071788a5 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -711,6 +711,7 @@ int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | |||
711 | return 0; | 711 | return 0; |
712 | 712 | ||
713 | if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { | 713 | if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { |
714 | txtid->state &= ~AGGR_ADDBA_PROGRESS; | ||
714 | txtid->addba_exchangeattempts = 0; | 715 | txtid->addba_exchangeattempts = 0; |
715 | return 0; | 716 | return 0; |
716 | } | 717 | } |
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..67f564e37225 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig | |||
@@ -98,13 +98,6 @@ config B43_LEDS | |||
98 | depends on B43 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43) | 98 | depends on B43 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43) |
99 | default y | 99 | default y |
100 | 100 | ||
101 | # This config option automatically enables b43 RFKILL support, | ||
102 | # if it's possible. | ||
103 | config B43_RFKILL | ||
104 | bool | ||
105 | depends on B43 && (RFKILL = y || RFKILL = B43) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43) | ||
106 | default y | ||
107 | |||
108 | # This config option automatically enables b43 HW-RNG support, | 101 | # This config option automatically enables b43 HW-RNG support, |
109 | # if the HW-RNG core is enabled. | 102 | # if the HW-RNG core is enabled. |
110 | config B43_HWRNG | 103 | config B43_HWRNG |
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index 281ef8310350..da379f4b0c3a 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile | |||
@@ -13,7 +13,7 @@ b43-y += lo.o | |||
13 | b43-y += wa.o | 13 | b43-y += wa.o |
14 | b43-y += dma.o | 14 | b43-y += dma.o |
15 | b43-$(CONFIG_B43_PIO) += pio.o | 15 | b43-$(CONFIG_B43_PIO) += pio.o |
16 | b43-$(CONFIG_B43_RFKILL) += rfkill.o | 16 | b43-y += rfkill.o |
17 | b43-$(CONFIG_B43_LEDS) += leds.o | 17 | b43-$(CONFIG_B43_LEDS) += leds.o |
18 | b43-$(CONFIG_B43_PCMCIA) += pcmcia.o | 18 | b43-$(CONFIG_B43_PCMCIA) += pcmcia.o |
19 | b43-$(CONFIG_B43_DEBUG) += debugfs.o | 19 | b43-$(CONFIG_B43_DEBUG) += debugfs.o |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 4e8ad841c3c5..f580c2812d91 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -163,6 +163,7 @@ enum { | |||
163 | #define B43_SHM_SH_WLCOREREV 0x0016 /* 802.11 core revision */ | 163 | #define B43_SHM_SH_WLCOREREV 0x0016 /* 802.11 core revision */ |
164 | #define B43_SHM_SH_PCTLWDPOS 0x0008 | 164 | #define B43_SHM_SH_PCTLWDPOS 0x0008 |
165 | #define B43_SHM_SH_RXPADOFF 0x0034 /* RX Padding data offset (PIO only) */ | 165 | #define B43_SHM_SH_RXPADOFF 0x0034 /* RX Padding data offset (PIO only) */ |
166 | #define B43_SHM_SH_FWCAPA 0x0042 /* Firmware capabilities (Opensource firmware only) */ | ||
166 | #define B43_SHM_SH_PHYVER 0x0050 /* PHY version */ | 167 | #define B43_SHM_SH_PHYVER 0x0050 /* PHY version */ |
167 | #define B43_SHM_SH_PHYTYPE 0x0052 /* PHY type */ | 168 | #define B43_SHM_SH_PHYTYPE 0x0052 /* PHY type */ |
168 | #define B43_SHM_SH_ANTSWAP 0x005C /* Antenna swap threshold */ | 169 | #define B43_SHM_SH_ANTSWAP 0x005C /* Antenna swap threshold */ |
@@ -297,6 +298,10 @@ enum { | |||
297 | #define B43_HF_MLADVW 0x001000000000ULL /* N PHY ML ADV workaround (rev >= 13 only) */ | 298 | #define B43_HF_MLADVW 0x001000000000ULL /* N PHY ML ADV workaround (rev >= 13 only) */ |
298 | #define B43_HF_PR45960W 0x080000000000ULL /* PR 45960 workaround (rev >= 13 only) */ | 299 | #define B43_HF_PR45960W 0x080000000000ULL /* PR 45960 workaround (rev >= 13 only) */ |
299 | 300 | ||
301 | /* Firmware capabilities field in SHM (Opensource firmware only) */ | ||
302 | #define B43_FWCAPA_HWCRYPTO 0x0001 | ||
303 | #define B43_FWCAPA_QOS 0x0002 | ||
304 | |||
300 | /* MacFilter offsets. */ | 305 | /* MacFilter offsets. */ |
301 | #define B43_MACFILTER_SELF 0x0000 | 306 | #define B43_MACFILTER_SELF 0x0000 |
302 | #define B43_MACFILTER_BSSID 0x0003 | 307 | #define B43_MACFILTER_BSSID 0x0003 |
@@ -596,6 +601,13 @@ struct b43_wl { | |||
596 | /* Pointer to the ieee80211 hardware data structure */ | 601 | /* Pointer to the ieee80211 hardware data structure */ |
597 | struct ieee80211_hw *hw; | 602 | struct ieee80211_hw *hw; |
598 | 603 | ||
604 | /* The number of queues that were registered with the mac80211 subsystem | ||
605 | * initially. This is a backup copy of hw->queues in case hw->queues has | ||
606 | * to be dynamically lowered at runtime (Firmware does not support QoS). | ||
607 | * hw->queues has to be restored to the original value before unregistering | ||
608 | * from the mac80211 subsystem. */ | ||
609 | u16 mac80211_initially_registered_queues; | ||
610 | |||
599 | struct mutex mutex; | 611 | struct mutex mutex; |
600 | spinlock_t irq_lock; | 612 | spinlock_t irq_lock; |
601 | /* R/W lock for data transmission. | 613 | /* R/W lock for data transmission. |
@@ -631,9 +643,6 @@ struct b43_wl { | |||
631 | char rng_name[30 + 1]; | 643 | char rng_name[30 + 1]; |
632 | #endif /* CONFIG_B43_HWRNG */ | 644 | #endif /* CONFIG_B43_HWRNG */ |
633 | 645 | ||
634 | /* The RF-kill button */ | ||
635 | struct b43_rfkill rfkill; | ||
636 | |||
637 | /* List of all wireless devices on this chip */ | 646 | /* List of all wireless devices on this chip */ |
638 | struct list_head devlist; | 647 | struct list_head devlist; |
639 | u8 nr_devs; | 648 | u8 nr_devs; |
@@ -752,6 +761,8 @@ struct b43_wldev { | |||
752 | bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */ | 761 | bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */ |
753 | bool radio_hw_enable; /* saved state of radio hardware enabled state */ | 762 | bool radio_hw_enable; /* saved state of radio hardware enabled state */ |
754 | bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */ | 763 | bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */ |
764 | bool qos_enabled; /* TRUE, if QoS is used. */ | ||
765 | bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */ | ||
755 | 766 | ||
756 | /* PHY/Radio device. */ | 767 | /* PHY/Radio device. */ |
757 | struct b43_phy phy; | 768 | struct b43_phy phy; |
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index eae680b53052..7964cc32b258 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -1285,7 +1285,7 @@ static struct b43_dmaring *select_ring_by_priority(struct b43_wldev *dev, | |||
1285 | { | 1285 | { |
1286 | struct b43_dmaring *ring; | 1286 | struct b43_dmaring *ring; |
1287 | 1287 | ||
1288 | if (b43_modparam_qos) { | 1288 | if (dev->qos_enabled) { |
1289 | /* 0 = highest priority */ | 1289 | /* 0 = highest priority */ |
1290 | switch (queue_prio) { | 1290 | switch (queue_prio) { |
1291 | default: | 1291 | default: |
diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c index 76f4c7bad8b8..c8b317094c31 100644 --- a/drivers/net/wireless/b43/leds.c +++ b/drivers/net/wireless/b43/leds.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include "b43.h" | 29 | #include "b43.h" |
30 | #include "leds.h" | 30 | #include "leds.h" |
31 | #include "rfkill.h" | ||
31 | 32 | ||
32 | 33 | ||
33 | static void b43_led_turn_on(struct b43_wldev *dev, u8 led_index, | 34 | static void b43_led_turn_on(struct b43_wldev *dev, u8 led_index, |
@@ -87,7 +88,7 @@ static void b43_led_brightness_set(struct led_classdev *led_dev, | |||
87 | } | 88 | } |
88 | 89 | ||
89 | static int b43_register_led(struct b43_wldev *dev, struct b43_led *led, | 90 | static int b43_register_led(struct b43_wldev *dev, struct b43_led *led, |
90 | const char *name, char *default_trigger, | 91 | const char *name, const char *default_trigger, |
91 | u8 led_index, bool activelow) | 92 | u8 led_index, bool activelow) |
92 | { | 93 | { |
93 | int err; | 94 | int err; |
@@ -164,10 +165,10 @@ static void b43_map_led(struct b43_wldev *dev, | |||
164 | snprintf(name, sizeof(name), | 165 | snprintf(name, sizeof(name), |
165 | "b43-%s::radio", wiphy_name(hw->wiphy)); | 166 | "b43-%s::radio", wiphy_name(hw->wiphy)); |
166 | b43_register_led(dev, &dev->led_radio, name, | 167 | b43_register_led(dev, &dev->led_radio, name, |
167 | b43_rfkill_led_name(dev), | 168 | ieee80211_get_radio_led_name(hw), |
168 | led_index, activelow); | 169 | led_index, activelow); |
169 | /* Sync the RF-kill LED state with the switch state. */ | 170 | /* Sync the RF-kill LED state with radio and switch states. */ |
170 | if (dev->radio_hw_enable) | 171 | if (dev->phy.radio_on && b43_is_hw_radio_enabled(dev)) |
171 | b43_led_turn_on(dev, led_index, activelow); | 172 | b43_led_turn_on(dev, led_index, activelow); |
172 | break; | 173 | break; |
173 | case B43_LED_WEIRD: | 174 | case B43_LED_WEIRD: |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index cb4a8712946a..6456afebdba1 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -80,8 +80,8 @@ static int modparam_nohwcrypt; | |||
80 | module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); | 80 | module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); |
81 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 81 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
82 | 82 | ||
83 | int b43_modparam_qos = 1; | 83 | static int modparam_qos = 1; |
84 | module_param_named(qos, b43_modparam_qos, int, 0444); | 84 | module_param_named(qos, modparam_qos, int, 0444); |
85 | MODULE_PARM_DESC(qos, "Enable QOS support (default on)"); | 85 | MODULE_PARM_DESC(qos, "Enable QOS support (default on)"); |
86 | 86 | ||
87 | static int modparam_btcoex = 1; | 87 | static int modparam_btcoex = 1; |
@@ -538,6 +538,13 @@ void b43_hf_write(struct b43_wldev *dev, u64 value) | |||
538 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi); | 538 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi); |
539 | } | 539 | } |
540 | 540 | ||
541 | /* Read the firmware capabilities bitmask (Opensource firmware only) */ | ||
542 | static u16 b43_fwcapa_read(struct b43_wldev *dev) | ||
543 | { | ||
544 | B43_WARN_ON(!dev->fw.opensource); | ||
545 | return b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_FWCAPA); | ||
546 | } | ||
547 | |||
541 | void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) | 548 | void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) |
542 | { | 549 | { |
543 | u32 low, high; | 550 | u32 low, high; |
@@ -2307,12 +2314,34 @@ static int b43_upload_microcode(struct b43_wldev *dev) | |||
2307 | dev->fw.patch = fwpatch; | 2314 | dev->fw.patch = fwpatch; |
2308 | dev->fw.opensource = (fwdate == 0xFFFF); | 2315 | dev->fw.opensource = (fwdate == 0xFFFF); |
2309 | 2316 | ||
2317 | /* Default to use-all-queues. */ | ||
2318 | dev->wl->hw->queues = dev->wl->mac80211_initially_registered_queues; | ||
2319 | dev->qos_enabled = !!modparam_qos; | ||
2320 | /* Default to firmware/hardware crypto acceleration. */ | ||
2321 | dev->hwcrypto_enabled = 1; | ||
2322 | |||
2310 | if (dev->fw.opensource) { | 2323 | if (dev->fw.opensource) { |
2324 | u16 fwcapa; | ||
2325 | |||
2311 | /* Patchlevel info is encoded in the "time" field. */ | 2326 | /* Patchlevel info is encoded in the "time" field. */ |
2312 | dev->fw.patch = fwtime; | 2327 | dev->fw.patch = fwtime; |
2313 | b43info(dev->wl, "Loading OpenSource firmware version %u.%u%s\n", | 2328 | b43info(dev->wl, "Loading OpenSource firmware version %u.%u\n", |
2314 | dev->fw.rev, dev->fw.patch, | 2329 | dev->fw.rev, dev->fw.patch); |
2315 | dev->fw.pcm_request_failed ? " (Hardware crypto not supported)" : ""); | 2330 | |
2331 | fwcapa = b43_fwcapa_read(dev); | ||
2332 | if (!(fwcapa & B43_FWCAPA_HWCRYPTO) || dev->fw.pcm_request_failed) { | ||
2333 | b43info(dev->wl, "Hardware crypto acceleration not supported by firmware\n"); | ||
2334 | /* Disable hardware crypto and fall back to software crypto. */ | ||
2335 | dev->hwcrypto_enabled = 0; | ||
2336 | } | ||
2337 | if (!(fwcapa & B43_FWCAPA_QOS)) { | ||
2338 | b43info(dev->wl, "QoS not supported by firmware\n"); | ||
2339 | /* Disable QoS. Tweak hw->queues to 1. It will be restored before | ||
2340 | * ieee80211_unregister to make sure the networking core can | ||
2341 | * properly free possible resources. */ | ||
2342 | dev->wl->hw->queues = 1; | ||
2343 | dev->qos_enabled = 0; | ||
2344 | } | ||
2316 | } else { | 2345 | } else { |
2317 | b43info(dev->wl, "Loading firmware version %u.%u " | 2346 | b43info(dev->wl, "Loading firmware version %u.%u " |
2318 | "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", | 2347 | "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", |
@@ -3470,7 +3499,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) | |||
3470 | 3499 | ||
3471 | if (!!conf->radio_enabled != phy->radio_on) { | 3500 | if (!!conf->radio_enabled != phy->radio_on) { |
3472 | if (conf->radio_enabled) { | 3501 | if (conf->radio_enabled) { |
3473 | b43_software_rfkill(dev, RFKILL_STATE_UNBLOCKED); | 3502 | b43_software_rfkill(dev, false); |
3474 | b43info(dev->wl, "Radio turned on by software\n"); | 3503 | b43info(dev->wl, "Radio turned on by software\n"); |
3475 | if (!dev->radio_hw_enable) { | 3504 | if (!dev->radio_hw_enable) { |
3476 | b43info(dev->wl, "The hardware RF-kill button " | 3505 | b43info(dev->wl, "The hardware RF-kill button " |
@@ -3478,7 +3507,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) | |||
3478 | "Press the button to turn it on.\n"); | 3507 | "Press the button to turn it on.\n"); |
3479 | } | 3508 | } |
3480 | } else { | 3509 | } else { |
3481 | b43_software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED); | 3510 | b43_software_rfkill(dev, true); |
3482 | b43info(dev->wl, "Radio turned off by software\n"); | 3511 | b43info(dev->wl, "Radio turned off by software\n"); |
3483 | } | 3512 | } |
3484 | } | 3513 | } |
@@ -3627,7 +3656,7 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3627 | if (!dev || b43_status(dev) < B43_STAT_INITIALIZED) | 3656 | if (!dev || b43_status(dev) < B43_STAT_INITIALIZED) |
3628 | goto out_unlock; | 3657 | goto out_unlock; |
3629 | 3658 | ||
3630 | if (dev->fw.pcm_request_failed) { | 3659 | if (dev->fw.pcm_request_failed || !dev->hwcrypto_enabled) { |
3631 | /* We don't have firmware for the crypto engine. | 3660 | /* We don't have firmware for the crypto engine. |
3632 | * Must use software-crypto. */ | 3661 | * Must use software-crypto. */ |
3633 | err = -EOPNOTSUPP; | 3662 | err = -EOPNOTSUPP; |
@@ -4298,7 +4327,6 @@ static int b43_op_start(struct ieee80211_hw *hw) | |||
4298 | struct b43_wldev *dev = wl->current_dev; | 4327 | struct b43_wldev *dev = wl->current_dev; |
4299 | int did_init = 0; | 4328 | int did_init = 0; |
4300 | int err = 0; | 4329 | int err = 0; |
4301 | bool do_rfkill_exit = 0; | ||
4302 | 4330 | ||
4303 | /* Kill all old instance specific information to make sure | 4331 | /* Kill all old instance specific information to make sure |
4304 | * the card won't use it in the short timeframe between start | 4332 | * the card won't use it in the short timeframe between start |
@@ -4312,18 +4340,12 @@ static int b43_op_start(struct ieee80211_hw *hw) | |||
4312 | wl->beacon1_uploaded = 0; | 4340 | wl->beacon1_uploaded = 0; |
4313 | wl->beacon_templates_virgin = 1; | 4341 | wl->beacon_templates_virgin = 1; |
4314 | 4342 | ||
4315 | /* First register RFkill. | ||
4316 | * LEDs that are registered later depend on it. */ | ||
4317 | b43_rfkill_init(dev); | ||
4318 | |||
4319 | mutex_lock(&wl->mutex); | 4343 | mutex_lock(&wl->mutex); |
4320 | 4344 | ||
4321 | if (b43_status(dev) < B43_STAT_INITIALIZED) { | 4345 | if (b43_status(dev) < B43_STAT_INITIALIZED) { |
4322 | err = b43_wireless_core_init(dev); | 4346 | err = b43_wireless_core_init(dev); |
4323 | if (err) { | 4347 | if (err) |
4324 | do_rfkill_exit = 1; | ||
4325 | goto out_mutex_unlock; | 4348 | goto out_mutex_unlock; |
4326 | } | ||
4327 | did_init = 1; | 4349 | did_init = 1; |
4328 | } | 4350 | } |
4329 | 4351 | ||
@@ -4332,17 +4354,16 @@ static int b43_op_start(struct ieee80211_hw *hw) | |||
4332 | if (err) { | 4354 | if (err) { |
4333 | if (did_init) | 4355 | if (did_init) |
4334 | b43_wireless_core_exit(dev); | 4356 | b43_wireless_core_exit(dev); |
4335 | do_rfkill_exit = 1; | ||
4336 | goto out_mutex_unlock; | 4357 | goto out_mutex_unlock; |
4337 | } | 4358 | } |
4338 | } | 4359 | } |
4339 | 4360 | ||
4361 | /* XXX: only do if device doesn't support rfkill irq */ | ||
4362 | wiphy_rfkill_start_polling(hw->wiphy); | ||
4363 | |||
4340 | out_mutex_unlock: | 4364 | out_mutex_unlock: |
4341 | mutex_unlock(&wl->mutex); | 4365 | mutex_unlock(&wl->mutex); |
4342 | 4366 | ||
4343 | if (do_rfkill_exit) | ||
4344 | b43_rfkill_exit(dev); | ||
4345 | |||
4346 | return err; | 4367 | return err; |
4347 | } | 4368 | } |
4348 | 4369 | ||
@@ -4351,7 +4372,6 @@ static void b43_op_stop(struct ieee80211_hw *hw) | |||
4351 | struct b43_wl *wl = hw_to_b43_wl(hw); | 4372 | struct b43_wl *wl = hw_to_b43_wl(hw); |
4352 | struct b43_wldev *dev = wl->current_dev; | 4373 | struct b43_wldev *dev = wl->current_dev; |
4353 | 4374 | ||
4354 | b43_rfkill_exit(dev); | ||
4355 | cancel_work_sync(&(wl->beacon_update_trigger)); | 4375 | cancel_work_sync(&(wl->beacon_update_trigger)); |
4356 | 4376 | ||
4357 | mutex_lock(&wl->mutex); | 4377 | mutex_lock(&wl->mutex); |
@@ -4433,6 +4453,7 @@ static const struct ieee80211_ops b43_hw_ops = { | |||
4433 | .sta_notify = b43_op_sta_notify, | 4453 | .sta_notify = b43_op_sta_notify, |
4434 | .sw_scan_start = b43_op_sw_scan_start_notifier, | 4454 | .sw_scan_start = b43_op_sw_scan_start_notifier, |
4435 | .sw_scan_complete = b43_op_sw_scan_complete_notifier, | 4455 | .sw_scan_complete = b43_op_sw_scan_complete_notifier, |
4456 | .rfkill_poll = b43_rfkill_poll, | ||
4436 | }; | 4457 | }; |
4437 | 4458 | ||
4438 | /* Hard-reset the chip. Do not call this directly. | 4459 | /* Hard-reset the chip. Do not call this directly. |
@@ -4735,6 +4756,7 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4735 | b43err(NULL, "Could not allocate ieee80211 device\n"); | 4756 | b43err(NULL, "Could not allocate ieee80211 device\n"); |
4736 | goto out; | 4757 | goto out; |
4737 | } | 4758 | } |
4759 | wl = hw_to_b43_wl(hw); | ||
4738 | 4760 | ||
4739 | /* fill hw info */ | 4761 | /* fill hw info */ |
4740 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 4762 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
@@ -4748,7 +4770,8 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4748 | BIT(NL80211_IFTYPE_WDS) | | 4770 | BIT(NL80211_IFTYPE_WDS) | |
4749 | BIT(NL80211_IFTYPE_ADHOC); | 4771 | BIT(NL80211_IFTYPE_ADHOC); |
4750 | 4772 | ||
4751 | hw->queues = b43_modparam_qos ? 4 : 1; | 4773 | hw->queues = modparam_qos ? 4 : 1; |
4774 | wl->mac80211_initially_registered_queues = hw->queues; | ||
4752 | hw->max_rates = 2; | 4775 | hw->max_rates = 2; |
4753 | SET_IEEE80211_DEV(hw, dev->dev); | 4776 | SET_IEEE80211_DEV(hw, dev->dev); |
4754 | if (is_valid_ether_addr(sprom->et1mac)) | 4777 | if (is_valid_ether_addr(sprom->et1mac)) |
@@ -4756,9 +4779,7 @@ static int b43_wireless_init(struct ssb_device *dev) | |||
4756 | else | 4779 | else |
4757 | SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac); | 4780 | SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac); |
4758 | 4781 | ||
4759 | /* Get and initialize struct b43_wl */ | 4782 | /* Initialize struct b43_wl */ |
4760 | wl = hw_to_b43_wl(hw); | ||
4761 | memset(wl, 0, sizeof(*wl)); | ||
4762 | wl->hw = hw; | 4783 | wl->hw = hw; |
4763 | spin_lock_init(&wl->irq_lock); | 4784 | spin_lock_init(&wl->irq_lock); |
4764 | rwlock_init(&wl->tx_lock); | 4785 | rwlock_init(&wl->tx_lock); |
@@ -4824,8 +4845,13 @@ static void b43_remove(struct ssb_device *dev) | |||
4824 | cancel_work_sync(&wldev->restart_work); | 4845 | cancel_work_sync(&wldev->restart_work); |
4825 | 4846 | ||
4826 | B43_WARN_ON(!wl); | 4847 | B43_WARN_ON(!wl); |
4827 | if (wl->current_dev == wldev) | 4848 | if (wl->current_dev == wldev) { |
4849 | /* Restore the queues count before unregistering, because firmware detect | ||
4850 | * might have modified it. Restoring is important, so the networking | ||
4851 | * stack can properly free resources. */ | ||
4852 | wl->hw->queues = wl->mac80211_initially_registered_queues; | ||
4828 | ieee80211_unregister_hw(wl->hw); | 4853 | ieee80211_unregister_hw(wl->hw); |
4854 | } | ||
4829 | 4855 | ||
4830 | b43_one_core_detach(dev); | 4856 | b43_one_core_detach(dev); |
4831 | 4857 | ||
@@ -4920,7 +4946,7 @@ static struct ssb_driver b43_ssb_driver = { | |||
4920 | static void b43_print_driverinfo(void) | 4946 | static void b43_print_driverinfo(void) |
4921 | { | 4947 | { |
4922 | const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", | 4948 | const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", |
4923 | *feat_leds = "", *feat_rfkill = ""; | 4949 | *feat_leds = ""; |
4924 | 4950 | ||
4925 | #ifdef CONFIG_B43_PCI_AUTOSELECT | 4951 | #ifdef CONFIG_B43_PCI_AUTOSELECT |
4926 | feat_pci = "P"; | 4952 | feat_pci = "P"; |
@@ -4934,14 +4960,11 @@ static void b43_print_driverinfo(void) | |||
4934 | #ifdef CONFIG_B43_LEDS | 4960 | #ifdef CONFIG_B43_LEDS |
4935 | feat_leds = "L"; | 4961 | feat_leds = "L"; |
4936 | #endif | 4962 | #endif |
4937 | #ifdef CONFIG_B43_RFKILL | ||
4938 | feat_rfkill = "R"; | ||
4939 | #endif | ||
4940 | printk(KERN_INFO "Broadcom 43xx driver loaded " | 4963 | printk(KERN_INFO "Broadcom 43xx driver loaded " |
4941 | "[ Features: %s%s%s%s%s, Firmware-ID: " | 4964 | "[ Features: %s%s%s%s, Firmware-ID: " |
4942 | B43_SUPPORTED_FIRMWARE_ID " ]\n", | 4965 | B43_SUPPORTED_FIRMWARE_ID " ]\n", |
4943 | feat_pci, feat_pcmcia, feat_nphy, | 4966 | feat_pci, feat_pcmcia, feat_nphy, |
4944 | feat_leds, feat_rfkill); | 4967 | feat_leds); |
4945 | } | 4968 | } |
4946 | 4969 | ||
4947 | static int __init b43_init(void) | 4970 | static int __init b43_init(void) |
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h index 40abcf5d1b43..950fb1b0546d 100644 --- a/drivers/net/wireless/b43/main.h +++ b/drivers/net/wireless/b43/main.h | |||
@@ -39,7 +39,6 @@ | |||
39 | #define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes)) | 39 | #define PAD_BYTES(nr_bytes) P4D_BYTES( __LINE__ , (nr_bytes)) |
40 | 40 | ||
41 | 41 | ||
42 | extern int b43_modparam_qos; | ||
43 | extern int b43_modparam_verbose; | 42 | extern int b43_modparam_verbose; |
44 | 43 | ||
45 | /* Logmessage verbosity levels. Update the b43_modparam_verbose helptext, if | 44 | /* Logmessage verbosity levels. Update the b43_modparam_verbose helptext, if |
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 | ||
482 | static void b43_aphy_op_software_rfkill(struct b43_wldev *dev, | 482 | static 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); |
106 | err_block_rf: | 106 | err_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 | ||
298 | void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state) | 298 | void 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..44cc918e4fc6 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef LINUX_B43_PHY_COMMON_H_ | 1 | #ifndef LINUX_B43_PHY_COMMON_H_ |
2 | #define LINUX_B43_PHY_COMMON_H_ | 2 | #define LINUX_B43_PHY_COMMON_H_ |
3 | 3 | ||
4 | #include <linux/rfkill.h> | 4 | #include <linux/types.h> |
5 | 5 | ||
6 | struct b43_wldev; | 6 | struct b43_wldev; |
7 | 7 | ||
@@ -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 | */ |
367 | void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state); | 367 | void 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 | ||
2594 | static void b43_gphy_op_software_rfkill(struct b43_wldev *dev, | 2594 | static 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 | ||
490 | static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev, | 490 | static 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 | ||
581 | static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, | 581 | static 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/pio.c b/drivers/net/wireless/b43/pio.c index 8cd9776752e6..69138e8c1db6 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c | |||
@@ -313,7 +313,7 @@ static struct b43_pio_txqueue *select_queue_by_priority(struct b43_wldev *dev, | |||
313 | { | 313 | { |
314 | struct b43_pio_txqueue *q; | 314 | struct b43_pio_txqueue *q; |
315 | 315 | ||
316 | if (b43_modparam_qos) { | 316 | if (dev->qos_enabled) { |
317 | /* 0 = highest priority */ | 317 | /* 0 = highest priority */ |
318 | switch (queue_prio) { | 318 | switch (queue_prio) { |
319 | default: | 319 | default: |
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index 9e1d00bc24d3..31e55999893f 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c | |||
@@ -22,15 +22,11 @@ | |||
22 | 22 | ||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "rfkill.h" | ||
26 | #include "b43.h" | 25 | #include "b43.h" |
27 | #include "phy_common.h" | ||
28 | |||
29 | #include <linux/kmod.h> | ||
30 | 26 | ||
31 | 27 | ||
32 | /* Returns TRUE, if the radio is enabled in hardware. */ | 28 | /* Returns TRUE, if the radio is enabled in hardware. */ |
33 | static bool b43_is_hw_radio_enabled(struct b43_wldev *dev) | 29 | bool b43_is_hw_radio_enabled(struct b43_wldev *dev) |
34 | { | 30 | { |
35 | if (dev->phy.rev >= 3) { | 31 | if (dev->phy.rev >= 3) { |
36 | if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI) | 32 | if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI) |
@@ -45,165 +41,39 @@ static bool b43_is_hw_radio_enabled(struct b43_wldev *dev) | |||
45 | } | 41 | } |
46 | 42 | ||
47 | /* The poll callback for the hardware button. */ | 43 | /* The poll callback for the hardware button. */ |
48 | static void b43_rfkill_poll(struct input_polled_dev *poll_dev) | 44 | void b43_rfkill_poll(struct ieee80211_hw *hw) |
49 | { | 45 | { |
50 | struct b43_wldev *dev = poll_dev->private; | 46 | struct b43_wl *wl = hw_to_b43_wl(hw); |
51 | struct b43_wl *wl = dev->wl; | 47 | struct b43_wldev *dev = wl->current_dev; |
48 | struct ssb_bus *bus = dev->dev->bus; | ||
52 | bool enabled; | 49 | bool enabled; |
53 | bool report_change = 0; | 50 | bool brought_up = false; |
54 | 51 | ||
55 | mutex_lock(&wl->mutex); | 52 | mutex_lock(&wl->mutex); |
56 | if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { | 53 | if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { |
57 | mutex_unlock(&wl->mutex); | 54 | if (ssb_bus_powerup(bus, 0)) { |
58 | return; | 55 | mutex_unlock(&wl->mutex); |
56 | return; | ||
57 | } | ||
58 | ssb_device_enable(dev->dev, 0); | ||
59 | brought_up = true; | ||
59 | } | 60 | } |
61 | |||
60 | enabled = b43_is_hw_radio_enabled(dev); | 62 | enabled = b43_is_hw_radio_enabled(dev); |
63 | |||
61 | if (unlikely(enabled != dev->radio_hw_enable)) { | 64 | if (unlikely(enabled != dev->radio_hw_enable)) { |
62 | dev->radio_hw_enable = enabled; | 65 | dev->radio_hw_enable = enabled; |
63 | report_change = 1; | ||
64 | b43info(wl, "Radio hardware status changed to %s\n", | 66 | b43info(wl, "Radio hardware status changed to %s\n", |
65 | enabled ? "ENABLED" : "DISABLED"); | 67 | enabled ? "ENABLED" : "DISABLED"); |
68 | wiphy_rfkill_set_hw_state(hw->wiphy, !enabled); | ||
69 | if (enabled != dev->phy.radio_on) | ||
70 | b43_software_rfkill(dev, !enabled); | ||
66 | } | 71 | } |
67 | mutex_unlock(&wl->mutex); | ||
68 | 72 | ||
69 | /* send the radio switch event to the system - note both a key press | 73 | if (brought_up) { |
70 | * and a release are required */ | 74 | ssb_device_disable(dev->dev, 0); |
71 | if (unlikely(report_change)) { | 75 | ssb_bus_may_powerdown(bus); |
72 | input_report_key(poll_dev->input, KEY_WLAN, 1); | ||
73 | input_report_key(poll_dev->input, KEY_WLAN, 0); | ||
74 | } | 76 | } |
75 | } | ||
76 | |||
77 | /* Called when the RFKILL toggled in software. */ | ||
78 | static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) | ||
79 | { | ||
80 | struct b43_wldev *dev = data; | ||
81 | struct b43_wl *wl = dev->wl; | ||
82 | int err = -EBUSY; | ||
83 | 77 | ||
84 | if (!wl->rfkill.registered) | ||
85 | return 0; | ||
86 | |||
87 | mutex_lock(&wl->mutex); | ||
88 | if (b43_status(dev) < B43_STAT_INITIALIZED) | ||
89 | goto out_unlock; | ||
90 | 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 | } | ||
110 | out_unlock: | ||
111 | mutex_unlock(&wl->mutex); | 78 | mutex_unlock(&wl->mutex); |
112 | |||
113 | return err; | ||
114 | } | ||
115 | |||
116 | char *b43_rfkill_led_name(struct b43_wldev *dev) | ||
117 | { | ||
118 | struct b43_rfkill *rfk = &(dev->wl->rfkill); | ||
119 | |||
120 | if (!rfk->registered) | ||
121 | return NULL; | ||
122 | return rfkill_get_led_name(rfk->rfkill); | ||
123 | } | ||
124 | |||
125 | void b43_rfkill_init(struct b43_wldev *dev) | ||
126 | { | ||
127 | struct b43_wl *wl = dev->wl; | ||
128 | struct b43_rfkill *rfk = &(wl->rfkill); | ||
129 | int err; | ||
130 | |||
131 | rfk->registered = 0; | ||
132 | |||
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), | ||
137 | "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 | |||
153 | rfk->poll_dev->input->name = rfk->name; | ||
154 | rfk->poll_dev->input->id.bustype = BUS_HOST; | ||
155 | rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor; | ||
156 | rfk->poll_dev->input->evbit[0] = BIT(EV_KEY); | ||
157 | set_bit(KEY_WLAN, rfk->poll_dev->input->keybit); | ||
158 | |||
159 | err = rfkill_register(rfk->rfkill); | ||
160 | if (err) | ||
161 | goto err_free_polldev; | ||
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 | |||
181 | rfk->registered = 1; | ||
182 | |||
183 | return; | ||
184 | err_unreg_rfk: | ||
185 | rfkill_unregister(rfk->rfkill); | ||
186 | err_free_polldev: | ||
187 | input_free_polled_device(rfk->poll_dev); | ||
188 | rfk->poll_dev = NULL; | ||
189 | err_freed_rfk: | ||
190 | rfk->rfkill = NULL; | ||
191 | out_error: | ||
192 | rfk->registered = 0; | ||
193 | b43warn(wl, "RF-kill button init failed\n"); | ||
194 | } | ||
195 | |||
196 | void b43_rfkill_exit(struct b43_wldev *dev) | ||
197 | { | ||
198 | struct b43_rfkill *rfk = &(dev->wl->rfkill); | ||
199 | |||
200 | if (!rfk->registered) | ||
201 | return; | ||
202 | rfk->registered = 0; | ||
203 | |||
204 | input_unregister_polled_device(rfk->poll_dev); | ||
205 | rfkill_unregister(rfk->rfkill); | ||
206 | input_free_polled_device(rfk->poll_dev); | ||
207 | rfk->poll_dev = NULL; | ||
208 | rfk->rfkill = NULL; | ||
209 | } | 79 | } |
diff --git a/drivers/net/wireless/b43/rfkill.h b/drivers/net/wireless/b43/rfkill.h index adacf936d815..f046c3ca0519 100644 --- a/drivers/net/wireless/b43/rfkill.h +++ b/drivers/net/wireless/b43/rfkill.h | |||
@@ -1,52 +1,11 @@ | |||
1 | #ifndef B43_RFKILL_H_ | 1 | #ifndef B43_RFKILL_H_ |
2 | #define B43_RFKILL_H_ | 2 | #define B43_RFKILL_H_ |
3 | 3 | ||
4 | struct ieee80211_hw; | ||
4 | struct b43_wldev; | 5 | struct b43_wldev; |
5 | 6 | ||
7 | void b43_rfkill_poll(struct ieee80211_hw *hw); | ||
6 | 8 | ||
7 | #ifdef CONFIG_B43_RFKILL | 9 | bool b43_is_hw_radio_enabled(struct b43_wldev *dev); |
8 | |||
9 | #include <linux/rfkill.h> | ||
10 | #include <linux/input-polldev.h> | ||
11 | |||
12 | |||
13 | struct b43_rfkill { | ||
14 | /* The RFKILL subsystem data structure */ | ||
15 | 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. */ | ||
19 | bool registered; | ||
20 | /* The unique name of this rfkill switch */ | ||
21 | char name[sizeof("b43-phy4294967295")]; | ||
22 | }; | ||
23 | |||
24 | /* The init function returns void, because we are not interested | ||
25 | * in failing the b43 init process when rfkill init failed. */ | ||
26 | void b43_rfkill_init(struct b43_wldev *dev); | ||
27 | void b43_rfkill_exit(struct b43_wldev *dev); | ||
28 | |||
29 | char * b43_rfkill_led_name(struct b43_wldev *dev); | ||
30 | |||
31 | |||
32 | #else /* CONFIG_B43_RFKILL */ | ||
33 | /* No RFKILL support. */ | ||
34 | |||
35 | struct b43_rfkill { | ||
36 | /* empty */ | ||
37 | }; | ||
38 | |||
39 | static inline void b43_rfkill_init(struct b43_wldev *dev) | ||
40 | { | ||
41 | } | ||
42 | static inline void b43_rfkill_exit(struct b43_wldev *dev) | ||
43 | { | ||
44 | } | ||
45 | static inline char * b43_rfkill_led_name(struct b43_wldev *dev) | ||
46 | { | ||
47 | return NULL; | ||
48 | } | ||
49 | |||
50 | #endif /* CONFIG_B43_RFKILL */ | ||
51 | 10 | ||
52 | #endif /* B43_RFKILL_H_ */ | 11 | #endif /* B43_RFKILL_H_ */ |
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index a63d88841df8..55f36a7254d9 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -118,7 +118,6 @@ u8 b43_plcp_get_ratecode_ofdm(const u8 bitrate) | |||
118 | void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, | 118 | void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, |
119 | const u16 octets, const u8 bitrate) | 119 | const u16 octets, const u8 bitrate) |
120 | { | 120 | { |
121 | __le32 *data = &(plcp->data); | ||
122 | __u8 *raw = plcp->raw; | 121 | __u8 *raw = plcp->raw; |
123 | 122 | ||
124 | if (b43_is_ofdm_rate(bitrate)) { | 123 | if (b43_is_ofdm_rate(bitrate)) { |
@@ -127,7 +126,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, | |||
127 | d = b43_plcp_get_ratecode_ofdm(bitrate); | 126 | d = b43_plcp_get_ratecode_ofdm(bitrate); |
128 | B43_WARN_ON(octets & 0xF000); | 127 | B43_WARN_ON(octets & 0xF000); |
129 | d |= (octets << 5); | 128 | d |= (octets << 5); |
130 | *data = cpu_to_le32(d); | 129 | plcp->data = cpu_to_le32(d); |
131 | } else { | 130 | } else { |
132 | u32 plen; | 131 | u32 plen; |
133 | 132 | ||
@@ -141,7 +140,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp, | |||
141 | raw[1] = 0x04; | 140 | raw[1] = 0x04; |
142 | } else | 141 | } else |
143 | raw[1] = 0x04; | 142 | raw[1] = 0x04; |
144 | *data |= cpu_to_le32(plen << 16); | 143 | plcp->data |= cpu_to_le32(plen << 16); |
145 | raw[0] = b43_plcp_get_ratecode_cck(bitrate); | 144 | raw[0] = b43_plcp_get_ratecode_cck(bitrate); |
146 | } | 145 | } |
147 | } | 146 | } |
diff --git a/drivers/net/wireless/b43legacy/Kconfig b/drivers/net/wireless/b43legacy/Kconfig index d4f628a74bbd..94a463478053 100644 --- a/drivers/net/wireless/b43legacy/Kconfig +++ b/drivers/net/wireless/b43legacy/Kconfig | |||
@@ -42,14 +42,6 @@ config B43LEGACY_LEDS | |||
42 | depends on B43LEGACY && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43LEGACY) | 42 | depends on B43LEGACY && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43LEGACY) |
43 | default y | 43 | default y |
44 | 44 | ||
45 | # RFKILL support | ||
46 | # This config option automatically enables b43legacy RFKILL support, | ||
47 | # if it's possible. | ||
48 | config B43LEGACY_RFKILL | ||
49 | bool | ||
50 | depends on B43LEGACY && (RFKILL = y || RFKILL = B43LEGACY) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43LEGACY) | ||
51 | default y | ||
52 | |||
53 | # This config option automatically enables b43 HW-RNG support, | 45 | # This config option automatically enables b43 HW-RNG support, |
54 | # if the HW-RNG core is enabled. | 46 | # if the HW-RNG core is enabled. |
55 | config B43LEGACY_HWRNG | 47 | config B43LEGACY_HWRNG |
diff --git a/drivers/net/wireless/b43legacy/Makefile b/drivers/net/wireless/b43legacy/Makefile index 80cdb73bd140..227a77e84362 100644 --- a/drivers/net/wireless/b43legacy/Makefile +++ b/drivers/net/wireless/b43legacy/Makefile | |||
@@ -6,7 +6,7 @@ b43legacy-y += radio.o | |||
6 | b43legacy-y += sysfs.o | 6 | b43legacy-y += sysfs.o |
7 | b43legacy-y += xmit.o | 7 | b43legacy-y += xmit.o |
8 | # b43 RFKILL button support | 8 | # b43 RFKILL button support |
9 | b43legacy-$(CONFIG_B43LEGACY_RFKILL) += rfkill.o | 9 | b43legacy-y += rfkill.o |
10 | # b43legacy LED support | 10 | # b43legacy LED support |
11 | b43legacy-$(CONFIG_B43LEGACY_LEDS) += leds.o | 11 | b43legacy-$(CONFIG_B43LEGACY_LEDS) += leds.o |
12 | # b43legacy debugging | 12 | # b43legacy debugging |
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 19a4b0bc0d87..77fda148ac46 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h | |||
@@ -602,9 +602,6 @@ struct b43legacy_wl { | |||
602 | char rng_name[30 + 1]; | 602 | char rng_name[30 + 1]; |
603 | #endif | 603 | #endif |
604 | 604 | ||
605 | /* The RF-kill button */ | ||
606 | struct b43legacy_rfkill rfkill; | ||
607 | |||
608 | /* List of all wireless devices on this chip */ | 605 | /* List of all wireless devices on this chip */ |
609 | struct list_head devlist; | 606 | struct list_head devlist; |
610 | u8 nr_devs; | 607 | u8 nr_devs; |
diff --git a/drivers/net/wireless/b43legacy/leds.c b/drivers/net/wireless/b43legacy/leds.c index 3ea55b18c700..37e9be893560 100644 --- a/drivers/net/wireless/b43legacy/leds.c +++ b/drivers/net/wireless/b43legacy/leds.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include "b43legacy.h" | 29 | #include "b43legacy.h" |
30 | #include "leds.h" | 30 | #include "leds.h" |
31 | #include "rfkill.h" | ||
31 | 32 | ||
32 | 33 | ||
33 | static void b43legacy_led_turn_on(struct b43legacy_wldev *dev, u8 led_index, | 34 | static void b43legacy_led_turn_on(struct b43legacy_wldev *dev, u8 led_index, |
@@ -86,7 +87,8 @@ static void b43legacy_led_brightness_set(struct led_classdev *led_dev, | |||
86 | 87 | ||
87 | static int b43legacy_register_led(struct b43legacy_wldev *dev, | 88 | static int b43legacy_register_led(struct b43legacy_wldev *dev, |
88 | struct b43legacy_led *led, | 89 | struct b43legacy_led *led, |
89 | const char *name, char *default_trigger, | 90 | const char *name, |
91 | const char *default_trigger, | ||
90 | u8 led_index, bool activelow) | 92 | u8 led_index, bool activelow) |
91 | { | 93 | { |
92 | int err; | 94 | int err; |
@@ -163,10 +165,10 @@ static void b43legacy_map_led(struct b43legacy_wldev *dev, | |||
163 | snprintf(name, sizeof(name), | 165 | snprintf(name, sizeof(name), |
164 | "b43legacy-%s::radio", wiphy_name(hw->wiphy)); | 166 | "b43legacy-%s::radio", wiphy_name(hw->wiphy)); |
165 | b43legacy_register_led(dev, &dev->led_radio, name, | 167 | b43legacy_register_led(dev, &dev->led_radio, name, |
166 | b43legacy_rfkill_led_name(dev), | 168 | ieee80211_get_radio_led_name(hw), |
167 | led_index, activelow); | 169 | led_index, activelow); |
168 | /* Sync the RF-kill LED state with the switch state. */ | 170 | /* Sync the RF-kill LED state with radio and switch states. */ |
169 | if (dev->radio_hw_enable) | 171 | if (dev->phy.radio_on && b43legacy_is_hw_radio_enabled(dev)) |
170 | b43legacy_led_turn_on(dev, led_index, activelow); | 172 | b43legacy_led_turn_on(dev, led_index, activelow); |
171 | break; | 173 | break; |
172 | case B43legacy_LED_WEIRD: | 174 | case B43legacy_LED_WEIRD: |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index f6f3fbf0a2f4..e5136fb65ddd 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -3431,11 +3431,6 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) | |||
3431 | struct b43legacy_wldev *dev = wl->current_dev; | 3431 | struct b43legacy_wldev *dev = wl->current_dev; |
3432 | int did_init = 0; | 3432 | int did_init = 0; |
3433 | int err = 0; | 3433 | int err = 0; |
3434 | bool do_rfkill_exit = 0; | ||
3435 | |||
3436 | /* First register RFkill. | ||
3437 | * LEDs that are registered later depend on it. */ | ||
3438 | b43legacy_rfkill_init(dev); | ||
3439 | 3434 | ||
3440 | /* Kill all old instance specific information to make sure | 3435 | /* Kill all old instance specific information to make sure |
3441 | * the card won't use it in the short timeframe between start | 3436 | * the card won't use it in the short timeframe between start |
@@ -3451,10 +3446,8 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) | |||
3451 | 3446 | ||
3452 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) { | 3447 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) { |
3453 | err = b43legacy_wireless_core_init(dev); | 3448 | err = b43legacy_wireless_core_init(dev); |
3454 | if (err) { | 3449 | if (err) |
3455 | do_rfkill_exit = 1; | ||
3456 | goto out_mutex_unlock; | 3450 | goto out_mutex_unlock; |
3457 | } | ||
3458 | did_init = 1; | 3451 | did_init = 1; |
3459 | } | 3452 | } |
3460 | 3453 | ||
@@ -3463,17 +3456,15 @@ static int b43legacy_op_start(struct ieee80211_hw *hw) | |||
3463 | if (err) { | 3456 | if (err) { |
3464 | if (did_init) | 3457 | if (did_init) |
3465 | b43legacy_wireless_core_exit(dev); | 3458 | b43legacy_wireless_core_exit(dev); |
3466 | do_rfkill_exit = 1; | ||
3467 | goto out_mutex_unlock; | 3459 | goto out_mutex_unlock; |
3468 | } | 3460 | } |
3469 | } | 3461 | } |
3470 | 3462 | ||
3463 | wiphy_rfkill_start_polling(hw->wiphy); | ||
3464 | |||
3471 | out_mutex_unlock: | 3465 | out_mutex_unlock: |
3472 | mutex_unlock(&wl->mutex); | 3466 | mutex_unlock(&wl->mutex); |
3473 | 3467 | ||
3474 | if (do_rfkill_exit) | ||
3475 | b43legacy_rfkill_exit(dev); | ||
3476 | |||
3477 | return err; | 3468 | return err; |
3478 | } | 3469 | } |
3479 | 3470 | ||
@@ -3482,7 +3473,6 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw) | |||
3482 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); | 3473 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); |
3483 | struct b43legacy_wldev *dev = wl->current_dev; | 3474 | struct b43legacy_wldev *dev = wl->current_dev; |
3484 | 3475 | ||
3485 | b43legacy_rfkill_exit(dev); | ||
3486 | cancel_work_sync(&(wl->beacon_update_trigger)); | 3476 | cancel_work_sync(&(wl->beacon_update_trigger)); |
3487 | 3477 | ||
3488 | mutex_lock(&wl->mutex); | 3478 | mutex_lock(&wl->mutex); |
@@ -3518,6 +3508,7 @@ static const struct ieee80211_ops b43legacy_hw_ops = { | |||
3518 | .start = b43legacy_op_start, | 3508 | .start = b43legacy_op_start, |
3519 | .stop = b43legacy_op_stop, | 3509 | .stop = b43legacy_op_stop, |
3520 | .set_tim = b43legacy_op_beacon_set_tim, | 3510 | .set_tim = b43legacy_op_beacon_set_tim, |
3511 | .rfkill_poll = b43legacy_rfkill_poll, | ||
3521 | }; | 3512 | }; |
3522 | 3513 | ||
3523 | /* Hard-reset the chip. Do not call this directly. | 3514 | /* Hard-reset the chip. Do not call this directly. |
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c index 4b0c7d27a51f..8783022db11e 100644 --- a/drivers/net/wireless/b43legacy/rfkill.c +++ b/drivers/net/wireless/b43legacy/rfkill.c | |||
@@ -22,15 +22,12 @@ | |||
22 | 22 | ||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "rfkill.h" | ||
26 | #include "radio.h" | 25 | #include "radio.h" |
27 | #include "b43legacy.h" | 26 | #include "b43legacy.h" |
28 | 27 | ||
29 | #include <linux/kmod.h> | ||
30 | |||
31 | 28 | ||
32 | /* Returns TRUE, if the radio is enabled in hardware. */ | 29 | /* Returns TRUE, if the radio is enabled in hardware. */ |
33 | static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) | 30 | bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) |
34 | { | 31 | { |
35 | if (dev->phy.rev >= 3) { | 32 | if (dev->phy.rev >= 3) { |
36 | if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI) | 33 | if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI) |
@@ -45,164 +42,43 @@ static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) | |||
45 | } | 42 | } |
46 | 43 | ||
47 | /* The poll callback for the hardware button. */ | 44 | /* The poll callback for the hardware button. */ |
48 | static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev) | 45 | void b43legacy_rfkill_poll(struct ieee80211_hw *hw) |
49 | { | 46 | { |
50 | struct b43legacy_wldev *dev = poll_dev->private; | 47 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); |
51 | struct b43legacy_wl *wl = dev->wl; | 48 | struct b43legacy_wldev *dev = wl->current_dev; |
49 | struct ssb_bus *bus = dev->dev->bus; | ||
52 | bool enabled; | 50 | bool enabled; |
53 | bool report_change = 0; | 51 | bool brought_up = false; |
54 | 52 | ||
55 | mutex_lock(&wl->mutex); | 53 | mutex_lock(&wl->mutex); |
56 | if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) { | 54 | if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) { |
57 | mutex_unlock(&wl->mutex); | 55 | if (ssb_bus_powerup(bus, 0)) { |
58 | return; | 56 | mutex_unlock(&wl->mutex); |
57 | return; | ||
58 | } | ||
59 | ssb_device_enable(dev->dev, 0); | ||
60 | brought_up = true; | ||
59 | } | 61 | } |
62 | |||
60 | enabled = b43legacy_is_hw_radio_enabled(dev); | 63 | enabled = b43legacy_is_hw_radio_enabled(dev); |
64 | |||
61 | if (unlikely(enabled != dev->radio_hw_enable)) { | 65 | if (unlikely(enabled != dev->radio_hw_enable)) { |
62 | dev->radio_hw_enable = enabled; | 66 | dev->radio_hw_enable = enabled; |
63 | report_change = 1; | ||
64 | b43legacyinfo(wl, "Radio hardware status changed to %s\n", | 67 | b43legacyinfo(wl, "Radio hardware status changed to %s\n", |
65 | enabled ? "ENABLED" : "DISABLED"); | 68 | enabled ? "ENABLED" : "DISABLED"); |
66 | } | 69 | wiphy_rfkill_set_hw_state(hw->wiphy, !enabled); |
67 | mutex_unlock(&wl->mutex); | 70 | if (enabled != dev->phy.radio_on) { |
68 | 71 | if (enabled) | |
69 | /* send the radio switch event to the system - note both a key press | 72 | b43legacy_radio_turn_on(dev); |
70 | * and a release are required */ | 73 | else |
71 | if (unlikely(report_change)) { | 74 | b43legacy_radio_turn_off(dev, 0); |
72 | input_report_key(poll_dev->input, KEY_WLAN, 1); | ||
73 | input_report_key(poll_dev->input, KEY_WLAN, 0); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | /* Called when the RFKILL toggled in software. | ||
78 | * This is called without locking. */ | ||
79 | static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state) | ||
80 | { | ||
81 | struct b43legacy_wldev *dev = data; | ||
82 | struct b43legacy_wl *wl = dev->wl; | ||
83 | int err = -EBUSY; | ||
84 | |||
85 | if (!wl->rfkill.registered) | ||
86 | return 0; | ||
87 | |||
88 | mutex_lock(&wl->mutex); | ||
89 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) | ||
90 | goto out_unlock; | ||
91 | err = 0; | ||
92 | switch (state) { | ||
93 | case RFKILL_STATE_UNBLOCKED: | ||
94 | if (!dev->radio_hw_enable) { | ||
95 | /* No luck. We can't toggle the hardware RF-kill | ||
96 | * button from software. */ | ||
97 | err = -EBUSY; | ||
98 | goto out_unlock; | ||
99 | } | 75 | } |
100 | if (!dev->phy.radio_on) | ||
101 | b43legacy_radio_turn_on(dev); | ||
102 | break; | ||
103 | case RFKILL_STATE_SOFT_BLOCKED: | ||
104 | if (dev->phy.radio_on) | ||
105 | b43legacy_radio_turn_off(dev, 0); | ||
106 | break; | ||
107 | default: | ||
108 | b43legacywarn(wl, "Received unexpected rfkill state %d.\n", | ||
109 | state); | ||
110 | break; | ||
111 | } | 76 | } |
112 | 77 | ||
113 | out_unlock: | 78 | if (brought_up) { |
114 | mutex_unlock(&wl->mutex); | 79 | ssb_device_disable(dev->dev, 0); |
115 | 80 | ssb_bus_may_powerdown(bus); | |
116 | return err; | ||
117 | } | ||
118 | |||
119 | char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) | ||
120 | { | ||
121 | struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); | ||
122 | |||
123 | if (!rfk->registered) | ||
124 | return NULL; | ||
125 | return rfkill_get_led_name(rfk->rfkill); | ||
126 | } | ||
127 | |||
128 | void b43legacy_rfkill_init(struct b43legacy_wldev *dev) | ||
129 | { | ||
130 | struct b43legacy_wl *wl = dev->wl; | ||
131 | struct b43legacy_rfkill *rfk = &(wl->rfkill); | ||
132 | int err; | ||
133 | |||
134 | rfk->registered = 0; | ||
135 | |||
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), | ||
140 | "b43legacy-%s", wiphy_name(wl->hw->wiphy)); | ||
141 | rfk->rfkill->name = rfk->name; | ||
142 | rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; | ||
143 | rfk->rfkill->data = dev; | ||
144 | rfk->rfkill->toggle_radio = b43legacy_rfkill_soft_toggle; | ||
145 | |||
146 | rfk->poll_dev = input_allocate_polled_device(); | ||
147 | if (!rfk->poll_dev) { | ||
148 | rfkill_free(rfk->rfkill); | ||
149 | goto err_freed_rfk; | ||
150 | } | 81 | } |
151 | 82 | ||
152 | rfk->poll_dev->private = dev; | 83 | mutex_unlock(&wl->mutex); |
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 | |||
162 | err = rfkill_register(rfk->rfkill); | ||
163 | if (err) | ||
164 | goto err_free_polldev; | ||
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 | |||
179 | rfk->registered = 1; | ||
180 | |||
181 | return; | ||
182 | err_unreg_rfk: | ||
183 | rfkill_unregister(rfk->rfkill); | ||
184 | err_free_polldev: | ||
185 | input_free_polled_device(rfk->poll_dev); | ||
186 | rfk->poll_dev = NULL; | ||
187 | err_freed_rfk: | ||
188 | rfk->rfkill = NULL; | ||
189 | out_error: | ||
190 | rfk->registered = 0; | ||
191 | b43legacywarn(wl, "RF-kill button init failed\n"); | ||
192 | } | ||
193 | |||
194 | void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) | ||
195 | { | ||
196 | struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); | ||
197 | |||
198 | if (!rfk->registered) | ||
199 | return; | ||
200 | rfk->registered = 0; | ||
201 | |||
202 | input_unregister_polled_device(rfk->poll_dev); | ||
203 | rfkill_unregister(rfk->rfkill); | ||
204 | input_free_polled_device(rfk->poll_dev); | ||
205 | rfk->poll_dev = NULL; | ||
206 | rfk->rfkill = NULL; | ||
207 | } | 84 | } |
208 | |||
diff --git a/drivers/net/wireless/b43legacy/rfkill.h b/drivers/net/wireless/b43legacy/rfkill.h index 11150a8032f0..75585571c544 100644 --- a/drivers/net/wireless/b43legacy/rfkill.h +++ b/drivers/net/wireless/b43legacy/rfkill.h | |||
@@ -1,59 +1,11 @@ | |||
1 | #ifndef B43legacy_RFKILL_H_ | 1 | #ifndef B43legacy_RFKILL_H_ |
2 | #define B43legacy_RFKILL_H_ | 2 | #define B43legacy_RFKILL_H_ |
3 | 3 | ||
4 | struct ieee80211_hw; | ||
4 | struct b43legacy_wldev; | 5 | struct b43legacy_wldev; |
5 | 6 | ||
6 | #ifdef CONFIG_B43LEGACY_RFKILL | 7 | void b43legacy_rfkill_poll(struct ieee80211_hw *hw); |
7 | 8 | ||
8 | #include <linux/rfkill.h> | 9 | bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev); |
9 | #include <linux/workqueue.h> | ||
10 | #include <linux/input-polldev.h> | ||
11 | |||
12 | |||
13 | |||
14 | struct b43legacy_rfkill { | ||
15 | /* The RFKILL subsystem data structure */ | ||
16 | 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. */ | ||
20 | bool registered; | ||
21 | /* The unique name of this rfkill switch */ | ||
22 | char name[sizeof("b43legacy-phy4294967295")]; | ||
23 | }; | ||
24 | |||
25 | /* The init function returns void, because we are not interested | ||
26 | * in failing the b43 init process when rfkill init failed. */ | ||
27 | void b43legacy_rfkill_init(struct b43legacy_wldev *dev); | ||
28 | void b43legacy_rfkill_exit(struct b43legacy_wldev *dev); | ||
29 | |||
30 | char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev); | ||
31 | |||
32 | |||
33 | #else /* CONFIG_B43LEGACY_RFKILL */ | ||
34 | /* No RFKILL support. */ | ||
35 | |||
36 | struct b43legacy_rfkill { | ||
37 | /* empty */ | ||
38 | }; | ||
39 | |||
40 | static inline void b43legacy_rfkill_alloc(struct b43legacy_wldev *dev) | ||
41 | { | ||
42 | } | ||
43 | static inline void b43legacy_rfkill_free(struct b43legacy_wldev *dev) | ||
44 | { | ||
45 | } | ||
46 | static inline void b43legacy_rfkill_init(struct b43legacy_wldev *dev) | ||
47 | { | ||
48 | } | ||
49 | static inline void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) | ||
50 | { | ||
51 | } | ||
52 | static inline char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) | ||
53 | { | ||
54 | return NULL; | ||
55 | } | ||
56 | |||
57 | #endif /* CONFIG_B43LEGACY_RFKILL */ | ||
58 | 10 | ||
59 | #endif /* B43legacy_RFKILL_H_ */ | 11 | #endif /* B43legacy_RFKILL_H_ */ |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 8304f6406a17..029ccb6bdbaa 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -5,16 +5,11 @@ 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 | ||
10 | config IWLWIFI_LEDS | 9 | config 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 | ||
14 | config IWLWIFI_RFKILL | ||
15 | bool "Enable RF kill support in iwlagn and iwl3945 drivers" | ||
16 | depends on IWLWIFI | ||
17 | |||
18 | config IWLWIFI_SPECTRUM_MEASUREMENT | 13 | config IWLWIFI_SPECTRUM_MEASUREMENT |
19 | bool "Enable Spectrum Measurement in iwlagn driver" | 14 | bool "Enable Spectrum Measurement in iwlagn driver" |
20 | depends on IWLWIFI | 15 | depends on IWLWIFI |
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index d79d97ad61a5..1d4e0a226fd4 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -4,7 +4,6 @@ iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o | |||
4 | iwlcore-objs += iwl-scan.o | 4 | iwlcore-objs += iwl-scan.o |
5 | iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | 5 | iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o |
6 | iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o | 6 | iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o |
7 | iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o | ||
8 | iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o | 7 | iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o |
9 | 8 | ||
10 | obj-$(CONFIG_IWLAGN) += iwlagn.o | 9 | obj-$(CONFIG_IWLAGN) += iwlagn.o |
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 | ||
772 | u8 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, | |||
875 | u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags) | 846 | u8 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 | |||
2469 | static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) | 2439 | static 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 | ||
2845 | static 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 | |||
2854 | static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { | 2826 | static 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 | ||
2866 | static struct iwl_cfg iwl3945_bg_cfg = { | 2837 | static 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..fbb3a573463e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -36,10 +36,6 @@ | |||
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <net/ieee80211_radiotap.h> | 37 | #include <net/ieee80211_radiotap.h> |
38 | 38 | ||
39 | /*used for rfkill*/ | ||
40 | #include <linux/rfkill.h> | ||
41 | #include <linux/input.h> | ||
42 | |||
43 | /* Hardware specific file defines the PCI IDs table for that hardware module */ | 39 | /* Hardware specific file defines the PCI IDs table for that hardware module */ |
44 | extern struct pci_device_id iwl3945_hw_card_ids[]; | 40 | extern struct pci_device_id iwl3945_hw_card_ids[]; |
45 | 41 | ||
@@ -155,7 +151,6 @@ struct iwl3945_frame { | |||
155 | #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ | 151 | #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ |
156 | #define STATUS_INT_ENABLED 2 | 152 | #define STATUS_INT_ENABLED 2 |
157 | #define STATUS_RF_KILL_HW 3 | 153 | #define STATUS_RF_KILL_HW 3 |
158 | #define STATUS_RF_KILL_SW 4 | ||
159 | #define STATUS_INIT 5 | 154 | #define STATUS_INIT 5 |
160 | #define STATUS_ALIVE 6 | 155 | #define STATUS_ALIVE 6 |
161 | #define STATUS_READY 7 | 156 | #define STATUS_READY 7 |
@@ -202,12 +197,6 @@ struct iwl3945_ibss_seq { | |||
202 | * for use by iwl-*.c | 197 | * for use by iwl-*.c |
203 | * | 198 | * |
204 | *****************************************************************************/ | 199 | *****************************************************************************/ |
205 | struct iwl3945_addsta_cmd; | ||
206 | extern int iwl3945_send_add_station(struct iwl_priv *priv, | ||
207 | struct iwl3945_addsta_cmd *sta, u8 flags); | ||
208 | extern u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *bssid, | ||
209 | int is_ap, u8 flags, struct ieee80211_sta_ht_cap *ht_info); | ||
210 | extern void iwl3945_clear_stations_table(struct iwl_priv *priv); | ||
211 | extern int iwl3945_power_init_handle(struct iwl_priv *priv); | 200 | extern int iwl3945_power_init_handle(struct iwl_priv *priv); |
212 | extern int iwl3945_eeprom_init(struct iwl_priv *priv); | 201 | extern int iwl3945_eeprom_init(struct iwl_priv *priv); |
213 | extern int iwl3945_calc_db_from_ratio(int sig_ratio); | 202 | extern 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 | ||
2224 | static 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 | |||
2231 | static struct iwl_hcmd_ops iwl4965_hcmd = { | 2224 | static 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 | ||
2303 | struct iwl_cfg iwl4965_agn_cfg = { | 2295 | struct 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, | |||
1049 | u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) | 1049 | u16 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 | ||
1426 | struct 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 | |||
1433 | struct iwl_hcmd_ops iwl5000_hcmd = { | 1429 | struct 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 | ||
1555 | static struct iwl_ops iwl5150_ops = { | 1550 | static 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 | ||
1562 | struct iwl_mod_params iwl50_mod_params = { | 1556 | struct 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 | ||
78 | struct iwl_cfg iwl6000_2ag_cfg = { | 77 | struct 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 | ||
2798 | static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | 2796 | static 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..a5637c4aa85d 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 | ||
@@ -737,19 +737,13 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, | |||
737 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 737 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
738 | 738 | ||
739 | 739 | ||
740 | if (flags & SW_CARD_DISABLED) | ||
741 | set_bit(STATUS_RF_KILL_SW, &priv->status); | ||
742 | else | ||
743 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
744 | |||
745 | if (!(flags & RXON_CARD_DISABLED)) | 740 | if (!(flags & RXON_CARD_DISABLED)) |
746 | iwl_scan_cancel(priv); | 741 | iwl_scan_cancel(priv); |
747 | 742 | ||
748 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | 743 | if ((test_bit(STATUS_RF_KILL_HW, &status) != |
749 | test_bit(STATUS_RF_KILL_HW, &priv->status)) || | 744 | test_bit(STATUS_RF_KILL_HW, &priv->status))) |
750 | (test_bit(STATUS_RF_KILL_SW, &status) != | 745 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
751 | test_bit(STATUS_RF_KILL_SW, &priv->status))) | 746 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
752 | queue_work(priv->workqueue, &priv->rf_kill); | ||
753 | else | 747 | else |
754 | wake_up_interruptible(&priv->wait_command_queue); | 748 | wake_up_interruptible(&priv->wait_command_queue); |
755 | } | 749 | } |
@@ -1045,7 +1039,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) | |||
1045 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 1039 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
1046 | else | 1040 | else |
1047 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 1041 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
1048 | queue_work(priv->workqueue, &priv->rf_kill); | 1042 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill); |
1049 | } | 1043 | } |
1050 | 1044 | ||
1051 | handled |= CSR_INT_BIT_RF_KILL; | 1045 | handled |= CSR_INT_BIT_RF_KILL; |
@@ -1218,7 +1212,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1218 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 1212 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
1219 | else | 1213 | else |
1220 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 1214 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
1221 | queue_work(priv->workqueue, &priv->rf_kill); | 1215 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill); |
1222 | } | 1216 | } |
1223 | 1217 | ||
1224 | handled |= CSR_INT_BIT_RF_KILL; | 1218 | handled |= CSR_INT_BIT_RF_KILL; |
@@ -1617,7 +1611,7 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
1617 | goto restart; | 1611 | goto restart; |
1618 | } | 1612 | } |
1619 | 1613 | ||
1620 | priv->cfg->ops->smgmt->clear_station_table(priv); | 1614 | iwl_clear_stations_table(priv); |
1621 | ret = priv->cfg->ops->lib->alive_notify(priv); | 1615 | ret = priv->cfg->ops->lib->alive_notify(priv); |
1622 | if (ret) { | 1616 | if (ret) { |
1623 | IWL_WARN(priv, | 1617 | IWL_WARN(priv, |
@@ -1703,7 +1697,7 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1703 | 1697 | ||
1704 | iwl_leds_unregister(priv); | 1698 | iwl_leds_unregister(priv); |
1705 | 1699 | ||
1706 | priv->cfg->ops->smgmt->clear_station_table(priv); | 1700 | iwl_clear_stations_table(priv); |
1707 | 1701 | ||
1708 | /* Unblock any waiting calls */ | 1702 | /* Unblock any waiting calls */ |
1709 | wake_up_interruptible_all(&priv->wait_command_queue); | 1703 | wake_up_interruptible_all(&priv->wait_command_queue); |
@@ -1726,12 +1720,10 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1726 | ieee80211_stop_queues(priv->hw); | 1720 | ieee80211_stop_queues(priv->hw); |
1727 | 1721 | ||
1728 | /* If we have not previously called iwl_init() then | 1722 | /* If we have not previously called iwl_init() then |
1729 | * clear all bits but the RF Kill bits and return */ | 1723 | * clear all bits but the RF Kill bit and return */ |
1730 | if (!iwl_is_init(priv)) { | 1724 | if (!iwl_is_init(priv)) { |
1731 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << | 1725 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << |
1732 | STATUS_RF_KILL_HW | | 1726 | STATUS_RF_KILL_HW | |
1733 | test_bit(STATUS_RF_KILL_SW, &priv->status) << | ||
1734 | STATUS_RF_KILL_SW | | ||
1735 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 1727 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
1736 | STATUS_GEO_CONFIGURED | | 1728 | STATUS_GEO_CONFIGURED | |
1737 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | 1729 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
@@ -1740,11 +1732,9 @@ static void __iwl_down(struct iwl_priv *priv) | |||
1740 | } | 1732 | } |
1741 | 1733 | ||
1742 | /* ...otherwise clear out all the status bits but the RF Kill | 1734 | /* ...otherwise clear out all the status bits but the RF Kill |
1743 | * bits and continue taking the NIC down. */ | 1735 | * bit and continue taking the NIC down. */ |
1744 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << | 1736 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << |
1745 | STATUS_RF_KILL_HW | | 1737 | STATUS_RF_KILL_HW | |
1746 | test_bit(STATUS_RF_KILL_SW, &priv->status) << | ||
1747 | STATUS_RF_KILL_SW | | ||
1748 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 1738 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
1749 | STATUS_GEO_CONFIGURED | | 1739 | STATUS_GEO_CONFIGURED | |
1750 | test_bit(STATUS_FW_ERROR, &priv->status) << | 1740 | test_bit(STATUS_FW_ERROR, &priv->status) << |
@@ -1866,9 +1856,10 @@ static int __iwl_up(struct iwl_priv *priv) | |||
1866 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 1856 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
1867 | 1857 | ||
1868 | if (iwl_is_rfkill(priv)) { | 1858 | if (iwl_is_rfkill(priv)) { |
1859 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, true); | ||
1860 | |||
1869 | iwl_enable_interrupts(priv); | 1861 | iwl_enable_interrupts(priv); |
1870 | IWL_WARN(priv, "Radio disabled by %s RF Kill switch\n", | 1862 | IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); |
1871 | test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW"); | ||
1872 | return 0; | 1863 | return 0; |
1873 | } | 1864 | } |
1874 | 1865 | ||
@@ -1887,8 +1878,6 @@ static int __iwl_up(struct iwl_priv *priv) | |||
1887 | 1878 | ||
1888 | /* clear (again), then enable host interrupts */ | 1879 | /* clear (again), then enable host interrupts */ |
1889 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | 1880 | iwl_write32(priv, CSR_INT, 0xFFFFFFFF); |
1890 | /* enable dram interrupt */ | ||
1891 | iwl_reset_ict(priv); | ||
1892 | iwl_enable_interrupts(priv); | 1881 | iwl_enable_interrupts(priv); |
1893 | 1882 | ||
1894 | /* really make sure rfkill handshake bits are cleared */ | 1883 | /* really make sure rfkill handshake bits are cleared */ |
@@ -1903,7 +1892,7 @@ static int __iwl_up(struct iwl_priv *priv) | |||
1903 | 1892 | ||
1904 | for (i = 0; i < MAX_HW_RESTARTS; i++) { | 1893 | for (i = 0; i < MAX_HW_RESTARTS; i++) { |
1905 | 1894 | ||
1906 | priv->cfg->ops->smgmt->clear_station_table(priv); | 1895 | iwl_clear_stations_table(priv); |
1907 | 1896 | ||
1908 | /* load bootstrap state machine, | 1897 | /* load bootstrap state machine, |
1909 | * load bootstrap program into processor's memory, | 1898 | * load bootstrap program into processor's memory, |
@@ -1962,6 +1951,9 @@ static void iwl_bg_alive_start(struct work_struct *data) | |||
1962 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 1951 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
1963 | return; | 1952 | return; |
1964 | 1953 | ||
1954 | /* enable dram interrupt */ | ||
1955 | iwl_reset_ict(priv); | ||
1956 | |||
1965 | mutex_lock(&priv->mutex); | 1957 | mutex_lock(&priv->mutex); |
1966 | iwl_alive_start(priv); | 1958 | iwl_alive_start(priv); |
1967 | mutex_unlock(&priv->mutex); | 1959 | mutex_unlock(&priv->mutex); |
@@ -2000,7 +1992,6 @@ static void iwl_bg_up(struct work_struct *data) | |||
2000 | mutex_lock(&priv->mutex); | 1992 | mutex_lock(&priv->mutex); |
2001 | __iwl_up(priv); | 1993 | __iwl_up(priv); |
2002 | mutex_unlock(&priv->mutex); | 1994 | mutex_unlock(&priv->mutex); |
2003 | iwl_rfkill_set_hw_state(priv); | ||
2004 | } | 1995 | } |
2005 | 1996 | ||
2006 | static void iwl_bg_restart(struct work_struct *data) | 1997 | static void iwl_bg_restart(struct work_struct *data) |
@@ -2178,8 +2169,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw) | |||
2178 | 2169 | ||
2179 | mutex_unlock(&priv->mutex); | 2170 | mutex_unlock(&priv->mutex); |
2180 | 2171 | ||
2181 | iwl_rfkill_set_hw_state(priv); | ||
2182 | |||
2183 | if (ret) | 2172 | if (ret) |
2184 | return ret; | 2173 | return ret; |
2185 | 2174 | ||
@@ -2348,7 +2337,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
2348 | return -EOPNOTSUPP; | 2337 | return -EOPNOTSUPP; |
2349 | } | 2338 | } |
2350 | addr = sta ? sta->addr : iwl_bcast_addr; | 2339 | addr = sta ? sta->addr : iwl_bcast_addr; |
2351 | sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); | 2340 | sta_id = iwl_find_station(priv, addr); |
2352 | if (sta_id == IWL_INVALID_STATION) { | 2341 | if (sta_id == IWL_INVALID_STATION) { |
2353 | IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", | 2342 | IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", |
2354 | addr); | 2343 | addr); |
@@ -2774,7 +2763,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
2774 | INIT_WORK(&priv->up, iwl_bg_up); | 2763 | INIT_WORK(&priv->up, iwl_bg_up); |
2775 | INIT_WORK(&priv->restart, iwl_bg_restart); | 2764 | INIT_WORK(&priv->restart, iwl_bg_restart); |
2776 | INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); | 2765 | INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); |
2777 | INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); | ||
2778 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); | 2766 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); |
2779 | INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); | 2767 | INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); |
2780 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); | 2768 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); |
@@ -3045,12 +3033,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3045 | else | 3033 | else |
3046 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 3034 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
3047 | 3035 | ||
3048 | err = iwl_rfkill_init(priv); | 3036 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
3049 | if (err) | 3037 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
3050 | IWL_ERR(priv, "Unable to initialize RFKILL system. " | ||
3051 | "Ignoring error: %d\n", err); | ||
3052 | else | ||
3053 | iwl_rfkill_set_hw_state(priv); | ||
3054 | 3038 | ||
3055 | iwl_power_initialize(priv); | 3039 | iwl_power_initialize(priv); |
3056 | return 0; | 3040 | return 0; |
@@ -3114,14 +3098,13 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
3114 | 3098 | ||
3115 | iwl_synchronize_irq(priv); | 3099 | iwl_synchronize_irq(priv); |
3116 | 3100 | ||
3117 | iwl_rfkill_unregister(priv); | ||
3118 | iwl_dealloc_ucode_pci(priv); | 3101 | iwl_dealloc_ucode_pci(priv); |
3119 | 3102 | ||
3120 | if (priv->rxq.bd) | 3103 | if (priv->rxq.bd) |
3121 | iwl_rx_queue_free(priv, &priv->rxq); | 3104 | iwl_rx_queue_free(priv, &priv->rxq); |
3122 | iwl_hw_txq_ctx_free(priv); | 3105 | iwl_hw_txq_ctx_free(priv); |
3123 | 3106 | ||
3124 | priv->cfg->ops->smgmt->clear_station_table(priv); | 3107 | iwl_clear_stations_table(priv); |
3125 | iwl_eeprom_free(priv); | 3108 | iwl_eeprom_free(priv); |
3126 | 3109 | ||
3127 | 3110 | ||
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..f9d16ca5b3d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include "iwl-debug.h" | 36 | #include "iwl-debug.h" |
37 | #include "iwl-core.h" | 37 | #include "iwl-core.h" |
38 | #include "iwl-io.h" | 38 | #include "iwl-io.h" |
39 | #include "iwl-rfkill.h" | ||
40 | #include "iwl-power.h" | 39 | #include "iwl-power.h" |
41 | #include "iwl-sta.h" | 40 | #include "iwl-sta.h" |
42 | #include "iwl-helpers.h" | 41 | #include "iwl-helpers.h" |
@@ -1389,7 +1388,7 @@ int iwl_init_drv(struct iwl_priv *priv) | |||
1389 | mutex_init(&priv->mutex); | 1388 | mutex_init(&priv->mutex); |
1390 | 1389 | ||
1391 | /* Clear the driver's (not device's) station table */ | 1390 | /* Clear the driver's (not device's) station table */ |
1392 | priv->cfg->ops->smgmt->clear_station_table(priv); | 1391 | iwl_clear_stations_table(priv); |
1393 | 1392 | ||
1394 | priv->data_retry_limit = -1; | 1393 | priv->data_retry_limit = -1; |
1395 | priv->ieee_channels = NULL; | 1394 | priv->ieee_channels = NULL; |
@@ -1704,8 +1703,9 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
1704 | { | 1703 | { |
1705 | struct iwl_priv *priv = data; | 1704 | struct iwl_priv *priv = data; |
1706 | u32 inta, inta_mask; | 1705 | u32 inta, inta_mask; |
1706 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1707 | u32 inta_fh; | 1707 | u32 inta_fh; |
1708 | 1708 | #endif | |
1709 | if (!priv) | 1709 | if (!priv) |
1710 | return IRQ_NONE; | 1710 | return IRQ_NONE; |
1711 | 1711 | ||
@@ -2210,126 +2210,6 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) | |||
2210 | } | 2210 | } |
2211 | EXPORT_SYMBOL(iwl_send_card_state); | 2211 | EXPORT_SYMBOL(iwl_send_card_state); |
2212 | 2212 | ||
2213 | void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv) | ||
2214 | { | ||
2215 | unsigned long flags; | ||
2216 | |||
2217 | if (test_bit(STATUS_RF_KILL_SW, &priv->status)) | ||
2218 | return; | ||
2219 | |||
2220 | IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO OFF\n"); | ||
2221 | |||
2222 | iwl_scan_cancel(priv); | ||
2223 | /* FIXME: This is a workaround for AP */ | ||
2224 | if (priv->iw_mode != NL80211_IFTYPE_AP) { | ||
2225 | spin_lock_irqsave(&priv->lock, flags); | ||
2226 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, | ||
2227 | CSR_UCODE_SW_BIT_RFKILL); | ||
2228 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2229 | /* call the host command only if no hw rf-kill set */ | ||
2230 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status) && | ||
2231 | iwl_is_ready(priv)) | ||
2232 | iwl_send_card_state(priv, | ||
2233 | CARD_STATE_CMD_DISABLE, 0); | ||
2234 | set_bit(STATUS_RF_KILL_SW, &priv->status); | ||
2235 | /* make sure mac80211 stop sending Tx frame */ | ||
2236 | if (priv->mac80211_registered) | ||
2237 | ieee80211_stop_queues(priv->hw); | ||
2238 | } | ||
2239 | } | ||
2240 | EXPORT_SYMBOL(iwl_radio_kill_sw_disable_radio); | ||
2241 | |||
2242 | int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv) | ||
2243 | { | ||
2244 | unsigned long flags; | ||
2245 | |||
2246 | if (!test_bit(STATUS_RF_KILL_SW, &priv->status)) | ||
2247 | return 0; | ||
2248 | |||
2249 | IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO ON\n"); | ||
2250 | |||
2251 | spin_lock_irqsave(&priv->lock, flags); | ||
2252 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
2253 | |||
2254 | /* If the driver is up it will receive CARD_STATE_NOTIFICATION | ||
2255 | * notification where it will clear SW rfkill status. | ||
2256 | * Setting it here would break the handler. Only if the | ||
2257 | * interface is down we can set here since we don't | ||
2258 | * receive any further notification. | ||
2259 | */ | ||
2260 | if (!priv->is_open) | ||
2261 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
2262 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2263 | |||
2264 | /* wake up ucode */ | ||
2265 | msleep(10); | ||
2266 | |||
2267 | iwl_read32(priv, CSR_UCODE_DRV_GP1); | ||
2268 | spin_lock_irqsave(&priv->reg_lock, flags); | ||
2269 | if (!iwl_grab_nic_access(priv)) | ||
2270 | iwl_release_nic_access(priv); | ||
2271 | spin_unlock_irqrestore(&priv->reg_lock, flags); | ||
2272 | |||
2273 | if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { | ||
2274 | IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - " | ||
2275 | "disabled by HW switch\n"); | ||
2276 | return 0; | ||
2277 | } | ||
2278 | |||
2279 | /* when driver is up while rfkill is on, it wont receive | ||
2280 | * any CARD_STATE_NOTIFICATION notifications so we have to | ||
2281 | * restart it in here | ||
2282 | */ | ||
2283 | if (priv->is_open && !test_bit(STATUS_ALIVE, &priv->status)) { | ||
2284 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
2285 | if (!iwl_is_rfkill(priv)) | ||
2286 | queue_work(priv->workqueue, &priv->up); | ||
2287 | } | ||
2288 | |||
2289 | /* If the driver is already loaded, it will receive | ||
2290 | * CARD_STATE_NOTIFICATION notifications and the handler will | ||
2291 | * call restart to reload the driver. | ||
2292 | */ | ||
2293 | return 1; | ||
2294 | } | ||
2295 | EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio); | ||
2296 | |||
2297 | void iwl_bg_rf_kill(struct work_struct *work) | ||
2298 | { | ||
2299 | struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill); | ||
2300 | |||
2301 | wake_up_interruptible(&priv->wait_command_queue); | ||
2302 | |||
2303 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
2304 | return; | ||
2305 | |||
2306 | mutex_lock(&priv->mutex); | ||
2307 | |||
2308 | if (!iwl_is_rfkill(priv)) { | ||
2309 | IWL_DEBUG_RF_KILL(priv, | ||
2310 | "HW and/or SW RF Kill no longer active, restarting " | ||
2311 | "device\n"); | ||
2312 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status) && | ||
2313 | priv->is_open) | ||
2314 | queue_work(priv->workqueue, &priv->restart); | ||
2315 | } else { | ||
2316 | /* make sure mac80211 stop sending Tx frame */ | ||
2317 | if (priv->mac80211_registered) | ||
2318 | ieee80211_stop_queues(priv->hw); | ||
2319 | |||
2320 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status)) | ||
2321 | IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - " | ||
2322 | "disabled by SW switch\n"); | ||
2323 | else | ||
2324 | IWL_WARN(priv, "Radio Frequency Kill Switch is On:\n" | ||
2325 | "Kill switch must be turned off for " | ||
2326 | "wireless networking to work.\n"); | ||
2327 | } | ||
2328 | mutex_unlock(&priv->mutex); | ||
2329 | iwl_rfkill_set_hw_state(priv); | ||
2330 | } | ||
2331 | EXPORT_SYMBOL(iwl_bg_rf_kill); | ||
2332 | |||
2333 | void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, | 2213 | void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, |
2334 | struct iwl_rx_mem_buffer *rxb) | 2214 | struct iwl_rx_mem_buffer *rxb) |
2335 | { | 2215 | { |
@@ -2679,19 +2559,12 @@ int iwl_set_mode(struct iwl_priv *priv, int mode) | |||
2679 | 2559 | ||
2680 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); | 2560 | memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); |
2681 | 2561 | ||
2682 | priv->cfg->ops->smgmt->clear_station_table(priv); | 2562 | iwl_clear_stations_table(priv); |
2683 | 2563 | ||
2684 | /* dont commit rxon if rf-kill is on*/ | 2564 | /* dont commit rxon if rf-kill is on*/ |
2685 | if (!iwl_is_ready_rf(priv)) | 2565 | if (!iwl_is_ready_rf(priv)) |
2686 | return -EAGAIN; | 2566 | return -EAGAIN; |
2687 | 2567 | ||
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); | 2568 | iwlcore_commit_rxon(priv); |
2696 | 2569 | ||
2697 | return 0; | 2570 | return 0; |
@@ -2855,23 +2728,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2855 | if (priv->cfg->ops->hcmd->set_rxon_chain) | 2728 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
2856 | priv->cfg->ops->hcmd->set_rxon_chain(priv); | 2729 | priv->cfg->ops->hcmd->set_rxon_chain(priv); |
2857 | 2730 | ||
2858 | if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) { | ||
2859 | if (conf->radio_enabled && | ||
2860 | iwl_radio_kill_sw_enable_radio(priv)) { | ||
2861 | IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - " | ||
2862 | "waiting for uCode\n"); | ||
2863 | goto out; | ||
2864 | } | ||
2865 | |||
2866 | if (!conf->radio_enabled) | ||
2867 | iwl_radio_kill_sw_disable_radio(priv); | ||
2868 | } | ||
2869 | |||
2870 | if (!conf->radio_enabled) { | ||
2871 | IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n"); | ||
2872 | goto out; | ||
2873 | } | ||
2874 | |||
2875 | if (!iwl_is_ready(priv)) { | 2731 | if (!iwl_is_ready(priv)) { |
2876 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); | 2732 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); |
2877 | goto out; | 2733 | goto out; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 87df1b767941..dabf663e36e5 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 | ||
86 | struct 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 | |||
95 | struct iwl_hcmd_ops { | 86 | struct 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 | ||
189 | struct iwl_mod_params { | 179 | struct 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 */ |
@@ -358,14 +348,6 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id); | |||
358 | ****************************************************/ | 348 | ****************************************************/ |
359 | int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); | 349 | int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); |
360 | 350 | ||
361 | /***************************************************** | ||
362 | * RF -Kill - here and not in iwl-rfkill.h to be available when | ||
363 | * RF-kill subsystem is not compiled. | ||
364 | ****************************************************/ | ||
365 | void iwl_bg_rf_kill(struct work_struct *work); | ||
366 | void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv); | ||
367 | int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv); | ||
368 | |||
369 | /******************************************************************************* | 351 | /******************************************************************************* |
370 | * Rate | 352 | * Rate |
371 | ******************************************************************************/ | 353 | ******************************************************************************/ |
@@ -508,7 +490,6 @@ void iwlcore_free_geos(struct iwl_priv *priv); | |||
508 | #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ | 490 | #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ |
509 | #define STATUS_INT_ENABLED 2 | 491 | #define STATUS_INT_ENABLED 2 |
510 | #define STATUS_RF_KILL_HW 3 | 492 | #define STATUS_RF_KILL_HW 3 |
511 | #define STATUS_RF_KILL_SW 4 | ||
512 | #define STATUS_INIT 5 | 493 | #define STATUS_INIT 5 |
513 | #define STATUS_ALIVE 6 | 494 | #define STATUS_ALIVE 6 |
514 | #define STATUS_READY 7 | 495 | #define STATUS_READY 7 |
@@ -543,11 +524,6 @@ static inline int iwl_is_init(struct iwl_priv *priv) | |||
543 | return test_bit(STATUS_INIT, &priv->status); | 524 | return test_bit(STATUS_INIT, &priv->status); |
544 | } | 525 | } |
545 | 526 | ||
546 | static inline int iwl_is_rfkill_sw(struct iwl_priv *priv) | ||
547 | { | ||
548 | return test_bit(STATUS_RF_KILL_SW, &priv->status); | ||
549 | } | ||
550 | |||
551 | static inline int iwl_is_rfkill_hw(struct iwl_priv *priv) | 527 | static inline int iwl_is_rfkill_hw(struct iwl_priv *priv) |
552 | { | 528 | { |
553 | return test_bit(STATUS_RF_KILL_HW, &priv->status); | 529 | return test_bit(STATUS_RF_KILL_HW, &priv->status); |
@@ -555,7 +531,7 @@ static inline int iwl_is_rfkill_hw(struct iwl_priv *priv) | |||
555 | 531 | ||
556 | static inline int iwl_is_rfkill(struct iwl_priv *priv) | 532 | static inline int iwl_is_rfkill(struct iwl_priv *priv) |
557 | { | 533 | { |
558 | return iwl_is_rfkill_hw(priv) || iwl_is_rfkill_sw(priv); | 534 | return iwl_is_rfkill_hw(priv); |
559 | } | 535 | } |
560 | 536 | ||
561 | static inline int iwl_is_ready_rf(struct iwl_priv *priv) | 537 | static inline int iwl_is_ready_rf(struct iwl_priv *priv) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index af70229144b3..11e08c068917 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c | |||
@@ -449,8 +449,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file, | |||
449 | test_bit(STATUS_INT_ENABLED, &priv->status)); | 449 | test_bit(STATUS_INT_ENABLED, &priv->status)); |
450 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", | 450 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", |
451 | test_bit(STATUS_RF_KILL_HW, &priv->status)); | 451 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
452 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_SW:\t %d\n", | ||
453 | test_bit(STATUS_RF_KILL_SW, &priv->status)); | ||
454 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", | 452 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", |
455 | test_bit(STATUS_INIT, &priv->status)); | 453 | test_bit(STATUS_INIT, &priv->status)); |
456 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", | 454 | pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 2dafc26fb6a8..e2d620f0b6e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -41,7 +41,6 @@ | |||
41 | #include "iwl-prph.h" | 41 | #include "iwl-prph.h" |
42 | #include "iwl-fh.h" | 42 | #include "iwl-fh.h" |
43 | #include "iwl-debug.h" | 43 | #include "iwl-debug.h" |
44 | #include "iwl-rfkill.h" | ||
45 | #include "iwl-4965-hw.h" | 44 | #include "iwl-4965-hw.h" |
46 | #include "iwl-3945-hw.h" | 45 | #include "iwl-3945-hw.h" |
47 | #include "iwl-3945-led.h" | 46 | #include "iwl-3945-led.h" |
@@ -70,7 +69,6 @@ extern struct iwl_ops iwl5000_ops; | |||
70 | extern struct iwl_lib_ops iwl5000_lib; | 69 | extern struct iwl_lib_ops iwl5000_lib; |
71 | extern struct iwl_hcmd_ops iwl5000_hcmd; | 70 | extern struct iwl_hcmd_ops iwl5000_hcmd; |
72 | extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils; | 71 | extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils; |
73 | extern struct iwl_station_mgmt_ops iwl5000_station_mgmt; | ||
74 | 72 | ||
75 | /* shared functions from iwl-5000.c */ | 73 | /* shared functions from iwl-5000.c */ |
76 | extern u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len); | 74 | extern u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len); |
@@ -290,11 +288,11 @@ struct iwl_frame { | |||
290 | #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) | 288 | #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) |
291 | 289 | ||
292 | enum { | 290 | enum { |
293 | /* CMD_SIZE_NORMAL = 0, */ | 291 | CMD_SYNC = 0, |
292 | CMD_SIZE_NORMAL = 0, | ||
293 | CMD_NO_SKB = 0, | ||
294 | CMD_SIZE_HUGE = (1 << 0), | 294 | CMD_SIZE_HUGE = (1 << 0), |
295 | /* CMD_SYNC = 0, */ | ||
296 | CMD_ASYNC = (1 << 1), | 295 | CMD_ASYNC = (1 << 1), |
297 | /* CMD_NO_SKB = 0, */ | ||
298 | CMD_WANT_SKB = (1 << 2), | 296 | CMD_WANT_SKB = (1 << 2), |
299 | }; | 297 | }; |
300 | 298 | ||
@@ -937,9 +935,6 @@ struct iwl_priv { | |||
937 | * 4965's initialize alive response contains some calibration data. */ | 935 | * 4965's initialize alive response contains some calibration data. */ |
938 | struct iwl_init_alive_resp card_alive_init; | 936 | struct iwl_init_alive_resp card_alive_init; |
939 | struct iwl_alive_resp card_alive; | 937 | struct iwl_alive_resp card_alive; |
940 | #if defined(CONFIG_IWLWIFI_RFKILL) | ||
941 | struct rfkill *rfkill; | ||
942 | #endif | ||
943 | 938 | ||
944 | #ifdef CONFIG_IWLWIFI_LEDS | 939 | #ifdef CONFIG_IWLWIFI_LEDS |
945 | unsigned long last_blink_time; | 940 | unsigned long last_blink_time; |
@@ -1073,7 +1068,6 @@ struct iwl_priv { | |||
1073 | struct work_struct calibrated_work; | 1068 | struct work_struct calibrated_work; |
1074 | struct work_struct scan_completed; | 1069 | struct work_struct scan_completed; |
1075 | struct work_struct rx_replenish; | 1070 | struct work_struct rx_replenish; |
1076 | struct work_struct rf_kill; | ||
1077 | struct work_struct abort_scan; | 1071 | struct work_struct abort_scan; |
1078 | struct work_struct update_link_led; | 1072 | struct work_struct update_link_led; |
1079 | struct work_struct auth_work; | 1073 | struct work_struct auth_work; |
@@ -1119,8 +1113,6 @@ struct iwl_priv { | |||
1119 | 1113 | ||
1120 | struct iwl3945_notif_statistics statistics_39; | 1114 | struct iwl3945_notif_statistics statistics_39; |
1121 | 1115 | ||
1122 | struct iwl3945_station_entry stations_39[IWL_STATION_COUNT]; | ||
1123 | |||
1124 | u32 sta_supp_rates; | 1116 | u32 sta_supp_rates; |
1125 | }; /*iwl_priv */ | 1117 | }; /*iwl_priv */ |
1126 | 1118 | ||
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) | |||
176 | static int iwl_led_disassociate(struct iwl_priv *priv, int led_id) | 176 | static 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 deleted file mode 100644 index 65605ad44e4b..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c +++ /dev/null | |||
@@ -1,144 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * Portions of this file are derived from the ipw3945 project, as well | ||
6 | * as portions of the ieee80211 subsystem header files. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of version 2 of the GNU General Public License as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution in the | ||
22 | * file called LICENSE. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | *****************************************************************************/ | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/init.h> | ||
31 | |||
32 | #include <net/mac80211.h> | ||
33 | |||
34 | #include "iwl-eeprom.h" | ||
35 | #include "iwl-dev.h" | ||
36 | #include "iwl-core.h" | ||
37 | |||
38 | /* software rf-kill from user */ | ||
39 | static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) | ||
40 | { | ||
41 | struct iwl_priv *priv = data; | ||
42 | int err = 0; | ||
43 | |||
44 | if (!priv->rfkill) | ||
45 | return 0; | ||
46 | |||
47 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
48 | return 0; | ||
49 | |||
50 | IWL_DEBUG_RF_KILL(priv, "we received soft RFKILL set to state %d\n", state); | ||
51 | mutex_lock(&priv->mutex); | ||
52 | |||
53 | switch (state) { | ||
54 | case RFKILL_STATE_UNBLOCKED: | ||
55 | if (iwl_is_rfkill_hw(priv)) { | ||
56 | err = -EBUSY; | ||
57 | goto out_unlock; | ||
58 | } | ||
59 | iwl_radio_kill_sw_enable_radio(priv); | ||
60 | break; | ||
61 | case RFKILL_STATE_SOFT_BLOCKED: | ||
62 | iwl_radio_kill_sw_disable_radio(priv); | ||
63 | break; | ||
64 | default: | ||
65 | IWL_WARN(priv, "we received unexpected RFKILL state %d\n", | ||
66 | state); | ||
67 | break; | ||
68 | } | ||
69 | out_unlock: | ||
70 | mutex_unlock(&priv->mutex); | ||
71 | |||
72 | return err; | ||
73 | } | ||
74 | |||
75 | int iwl_rfkill_init(struct iwl_priv *priv) | ||
76 | { | ||
77 | struct device *device = wiphy_dev(priv->hw->wiphy); | ||
78 | int ret = 0; | ||
79 | |||
80 | BUG_ON(device == NULL); | ||
81 | |||
82 | IWL_DEBUG_RF_KILL(priv, "Initializing RFKILL.\n"); | ||
83 | priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN); | ||
84 | if (!priv->rfkill) { | ||
85 | IWL_ERR(priv, "Unable to allocate RFKILL device.\n"); | ||
86 | ret = -ENOMEM; | ||
87 | goto error; | ||
88 | } | ||
89 | |||
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); | ||
99 | if (ret) { | ||
100 | IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret); | ||
101 | goto free_rfkill; | ||
102 | } | ||
103 | |||
104 | IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n"); | ||
105 | return ret; | ||
106 | |||
107 | free_rfkill: | ||
108 | if (priv->rfkill != NULL) | ||
109 | rfkill_free(priv->rfkill); | ||
110 | priv->rfkill = NULL; | ||
111 | |||
112 | error: | ||
113 | IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n"); | ||
114 | return ret; | ||
115 | } | ||
116 | EXPORT_SYMBOL(iwl_rfkill_init); | ||
117 | |||
118 | void iwl_rfkill_unregister(struct iwl_priv *priv) | ||
119 | { | ||
120 | |||
121 | if (priv->rfkill) | ||
122 | rfkill_unregister(priv->rfkill); | ||
123 | |||
124 | priv->rfkill = NULL; | ||
125 | } | ||
126 | EXPORT_SYMBOL(iwl_rfkill_unregister); | ||
127 | |||
128 | /* set RFKILL to the right state. */ | ||
129 | void iwl_rfkill_set_hw_state(struct iwl_priv *priv) | ||
130 | { | ||
131 | if (!priv->rfkill) | ||
132 | return; | ||
133 | |||
134 | if (iwl_is_rfkill_hw(priv)) { | ||
135 | rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED); | ||
136 | return; | ||
137 | } | ||
138 | |||
139 | if (!iwl_is_rfkill_sw(priv)) | ||
140 | rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED); | ||
141 | else | ||
142 | rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED); | ||
143 | } | ||
144 | EXPORT_SYMBOL(iwl_rfkill_set_hw_state); | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h deleted file mode 100644 index 633dafb4bf1b..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.h +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * Portions of this file are derived from the ipw3945 project, as well | ||
6 | * as portions of the ieee80211 subsystem header files. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of version 2 of the GNU General Public License as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution in the | ||
22 | * file called LICENSE. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | *****************************************************************************/ | ||
28 | #ifndef __iwl_rf_kill_h__ | ||
29 | #define __iwl_rf_kill_h__ | ||
30 | |||
31 | struct iwl_priv; | ||
32 | |||
33 | #include <linux/rfkill.h> | ||
34 | |||
35 | #ifdef CONFIG_IWLWIFI_RFKILL | ||
36 | |||
37 | void iwl_rfkill_set_hw_state(struct iwl_priv *priv); | ||
38 | void iwl_rfkill_unregister(struct iwl_priv *priv); | ||
39 | int iwl_rfkill_init(struct iwl_priv *priv); | ||
40 | #else | ||
41 | static inline void iwl_rfkill_set_hw_state(struct iwl_priv *priv) {} | ||
42 | static inline void iwl_rfkill_unregister(struct iwl_priv *priv) {} | ||
43 | static inline int iwl_rfkill_init(struct iwl_priv *priv) { return 0; } | ||
44 | #endif | ||
45 | |||
46 | |||
47 | |||
48 | #endif /* __iwl_rf_kill_h__ */ | ||
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 | } |
81 | EXPORT_SYMBOL(iwl_get_ra_sta_id); | 81 | EXPORT_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 | */ |
233 | u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap, | 232 | u8 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 | } |
298 | EXPORT_SYMBOL(iwl_add_station_flags); | 304 | EXPORT_SYMBOL(iwl_add_station); |
299 | 305 | ||
300 | static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr) | 306 | static 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 | */ |
411 | int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | 417 | int 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 | */ |
949 | static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap) | 955 | static 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 | */ |
998 | int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | 1005 | int 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) | |||
1168 | void iwl_update_ps_mode(struct iwl_priv *priv, u16 ps_bit, u8 *addr) | 1174 | void 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 | ||
54 | int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap); | 54 | int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap); |
55 | int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap); | 55 | int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap); |
56 | void iwl_clear_stations_table(struct iwl_priv *priv); | 56 | void iwl_clear_stations_table(struct iwl_priv *priv); |
57 | int iwl_get_free_ucode_key_index(struct iwl_priv *priv); | 57 | int iwl_get_free_ucode_key_index(struct iwl_priv *priv); |
58 | int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); | 58 | int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); |
59 | int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); | 59 | int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); |
60 | int iwl_send_add_sta(struct iwl_priv *priv, | 60 | int iwl_send_add_sta(struct iwl_priv *priv, |
61 | struct iwl_addsta_cmd *sta, u8 flags); | 61 | struct iwl_addsta_cmd *sta, u8 flags); |
62 | u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, | 62 | u8 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); |
65 | void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); | 64 | void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); |
66 | int iwl_sta_rx_agg_start(struct iwl_priv *priv, | 65 | int 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..83d31606dd00 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 | */ | ||
110 | static 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 | |||
141 | out: | ||
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 | */ | ||
152 | void 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 | */ | ||
167 | u8 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; |
@@ -1149,18 +1009,12 @@ static void iwl3945_rx_card_state_notif(struct iwl_priv *priv, | |||
1149 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 1009 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
1150 | 1010 | ||
1151 | 1011 | ||
1152 | if (flags & SW_CARD_DISABLED) | ||
1153 | set_bit(STATUS_RF_KILL_SW, &priv->status); | ||
1154 | else | ||
1155 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
1156 | |||
1157 | iwl_scan_cancel(priv); | 1012 | iwl_scan_cancel(priv); |
1158 | 1013 | ||
1159 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | 1014 | if ((test_bit(STATUS_RF_KILL_HW, &status) != |
1160 | test_bit(STATUS_RF_KILL_HW, &priv->status)) || | 1015 | test_bit(STATUS_RF_KILL_HW, &priv->status))) |
1161 | (test_bit(STATUS_RF_KILL_SW, &status) != | 1016 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
1162 | test_bit(STATUS_RF_KILL_SW, &priv->status))) | 1017 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
1163 | queue_work(priv->workqueue, &priv->rf_kill); | ||
1164 | else | 1018 | else |
1165 | wake_up_interruptible(&priv->wait_command_queue); | 1019 | wake_up_interruptible(&priv->wait_command_queue); |
1166 | } | 1020 | } |
@@ -1316,7 +1170,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv) | |||
1316 | 1170 | ||
1317 | /* If we've added more space for the firmware to place data, tell it. | 1171 | /* If we've added more space for the firmware to place data, tell it. |
1318 | * Increment device's write pointer in multiples of 8. */ | 1172 | * Increment device's write pointer in multiples of 8. */ |
1319 | if ((write != (rxq->write & ~0x7)) | 1173 | if ((rxq->write_actual != (rxq->write & ~0x7)) |
1320 | || (abs(rxq->write - rxq->read) > 7)) { | 1174 | || (abs(rxq->write - rxq->read) > 7)) { |
1321 | spin_lock_irqsave(&rxq->lock, flags); | 1175 | spin_lock_irqsave(&rxq->lock, flags); |
1322 | rxq->need_update = 1; | 1176 | rxq->need_update = 1; |
@@ -1337,7 +1191,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv) | |||
1337 | * Also restock the Rx queue via iwl3945_rx_queue_restock. | 1191 | * Also restock the Rx queue via iwl3945_rx_queue_restock. |
1338 | * This is called as a scheduled work item (except for during initialization) | 1192 | * This is called as a scheduled work item (except for during initialization) |
1339 | */ | 1193 | */ |
1340 | static void iwl3945_rx_allocate(struct iwl_priv *priv) | 1194 | static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority) |
1341 | { | 1195 | { |
1342 | struct iwl_rx_queue *rxq = &priv->rxq; | 1196 | struct iwl_rx_queue *rxq = &priv->rxq; |
1343 | struct list_head *element; | 1197 | struct list_head *element; |
@@ -1360,7 +1214,7 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv) | |||
1360 | /* Alloc a new receive buffer */ | 1214 | /* Alloc a new receive buffer */ |
1361 | rxb->skb = | 1215 | rxb->skb = |
1362 | alloc_skb(priv->hw_params.rx_buf_size, | 1216 | alloc_skb(priv->hw_params.rx_buf_size, |
1363 | GFP_KERNEL); | 1217 | priority); |
1364 | if (!rxb->skb) { | 1218 | if (!rxb->skb) { |
1365 | if (net_ratelimit()) | 1219 | if (net_ratelimit()) |
1366 | IWL_CRIT(priv, ": Can not allocate SKB buffers\n"); | 1220 | IWL_CRIT(priv, ": Can not allocate SKB buffers\n"); |
@@ -1419,6 +1273,7 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
1419 | * not restocked the Rx queue with fresh buffers */ | 1273 | * not restocked the Rx queue with fresh buffers */ |
1420 | rxq->read = rxq->write = 0; | 1274 | rxq->read = rxq->write = 0; |
1421 | rxq->free_count = 0; | 1275 | rxq->free_count = 0; |
1276 | rxq->write_actual = 0; | ||
1422 | spin_unlock_irqrestore(&rxq->lock, flags); | 1277 | spin_unlock_irqrestore(&rxq->lock, flags); |
1423 | } | 1278 | } |
1424 | 1279 | ||
@@ -1427,13 +1282,21 @@ void iwl3945_rx_replenish(void *data) | |||
1427 | struct iwl_priv *priv = data; | 1282 | struct iwl_priv *priv = data; |
1428 | unsigned long flags; | 1283 | unsigned long flags; |
1429 | 1284 | ||
1430 | iwl3945_rx_allocate(priv); | 1285 | iwl3945_rx_allocate(priv, GFP_KERNEL); |
1431 | 1286 | ||
1432 | spin_lock_irqsave(&priv->lock, flags); | 1287 | spin_lock_irqsave(&priv->lock, flags); |
1433 | iwl3945_rx_queue_restock(priv); | 1288 | iwl3945_rx_queue_restock(priv); |
1434 | spin_unlock_irqrestore(&priv->lock, flags); | 1289 | spin_unlock_irqrestore(&priv->lock, flags); |
1435 | } | 1290 | } |
1436 | 1291 | ||
1292 | static void iwl3945_rx_replenish_now(struct iwl_priv *priv) | ||
1293 | { | ||
1294 | iwl3945_rx_allocate(priv, GFP_ATOMIC); | ||
1295 | |||
1296 | iwl3945_rx_queue_restock(priv); | ||
1297 | } | ||
1298 | |||
1299 | |||
1437 | /* Assumes that the skb field of the buffers in 'pool' is kept accurate. | 1300 | /* 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 | 1301 | * 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 | 1302 | * This free routine walks the list of POOL entries and if SKB is set to |
@@ -1556,13 +1419,19 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) | |||
1556 | unsigned long flags; | 1419 | unsigned long flags; |
1557 | u8 fill_rx = 0; | 1420 | u8 fill_rx = 0; |
1558 | u32 count = 8; | 1421 | u32 count = 8; |
1422 | int total_empty = 0; | ||
1559 | 1423 | ||
1560 | /* uCode's read index (stored in shared DRAM) indicates the last Rx | 1424 | /* uCode's read index (stored in shared DRAM) indicates the last Rx |
1561 | * buffer that the driver may process (last buffer filled by ucode). */ | 1425 | * buffer that the driver may process (last buffer filled by ucode). */ |
1562 | r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; | 1426 | r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF; |
1563 | i = rxq->read; | 1427 | i = rxq->read; |
1564 | 1428 | ||
1565 | if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2)) | 1429 | /* calculate total frames need to be restock after handling RX */ |
1430 | total_empty = r - priv->rxq.write_actual; | ||
1431 | if (total_empty < 0) | ||
1432 | total_empty += RX_QUEUE_SIZE; | ||
1433 | |||
1434 | if (total_empty > (RX_QUEUE_SIZE / 2)) | ||
1566 | fill_rx = 1; | 1435 | fill_rx = 1; |
1567 | /* Rx interrupt, but nothing sent from uCode */ | 1436 | /* Rx interrupt, but nothing sent from uCode */ |
1568 | if (i == r) | 1437 | if (i == r) |
@@ -1639,7 +1508,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) | |||
1639 | count++; | 1508 | count++; |
1640 | if (count >= 8) { | 1509 | if (count >= 8) { |
1641 | priv->rxq.read = i; | 1510 | priv->rxq.read = i; |
1642 | iwl3945_rx_queue_restock(priv); | 1511 | iwl3945_rx_replenish_now(priv); |
1643 | count = 0; | 1512 | count = 0; |
1644 | } | 1513 | } |
1645 | } | 1514 | } |
@@ -1647,7 +1516,10 @@ static void iwl3945_rx_handle(struct iwl_priv *priv) | |||
1647 | 1516 | ||
1648 | /* Backtrack one entry */ | 1517 | /* Backtrack one entry */ |
1649 | priv->rxq.read = i; | 1518 | priv->rxq.read = i; |
1650 | iwl3945_rx_queue_restock(priv); | 1519 | if (fill_rx) |
1520 | iwl3945_rx_replenish_now(priv); | ||
1521 | else | ||
1522 | iwl3945_rx_queue_restock(priv); | ||
1651 | } | 1523 | } |
1652 | 1524 | ||
1653 | /* call this function to flush any scheduled tasklet */ | 1525 | /* call this function to flush any scheduled tasklet */ |
@@ -2589,7 +2461,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) | |||
2589 | goto restart; | 2461 | goto restart; |
2590 | } | 2462 | } |
2591 | 2463 | ||
2592 | priv->cfg->ops->smgmt->clear_station_table(priv); | 2464 | iwl_clear_stations_table(priv); |
2593 | 2465 | ||
2594 | rfkill = iwl_read_prph(priv, APMG_RFKILL_REG); | 2466 | rfkill = iwl_read_prph(priv, APMG_RFKILL_REG); |
2595 | IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill); | 2467 | IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill); |
@@ -2681,7 +2553,7 @@ static void __iwl3945_down(struct iwl_priv *priv) | |||
2681 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 2553 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
2682 | 2554 | ||
2683 | iwl3945_led_unregister(priv); | 2555 | iwl3945_led_unregister(priv); |
2684 | priv->cfg->ops->smgmt->clear_station_table(priv); | 2556 | iwl_clear_stations_table(priv); |
2685 | 2557 | ||
2686 | /* Unblock any waiting calls */ | 2558 | /* Unblock any waiting calls */ |
2687 | wake_up_interruptible_all(&priv->wait_command_queue); | 2559 | wake_up_interruptible_all(&priv->wait_command_queue); |
@@ -2708,8 +2580,6 @@ static void __iwl3945_down(struct iwl_priv *priv) | |||
2708 | if (!iwl_is_init(priv)) { | 2580 | if (!iwl_is_init(priv)) { |
2709 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << | 2581 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << |
2710 | STATUS_RF_KILL_HW | | 2582 | STATUS_RF_KILL_HW | |
2711 | test_bit(STATUS_RF_KILL_SW, &priv->status) << | ||
2712 | STATUS_RF_KILL_SW | | ||
2713 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 2583 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
2714 | STATUS_GEO_CONFIGURED | | 2584 | STATUS_GEO_CONFIGURED | |
2715 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | 2585 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
@@ -2718,11 +2588,9 @@ static void __iwl3945_down(struct iwl_priv *priv) | |||
2718 | } | 2588 | } |
2719 | 2589 | ||
2720 | /* ...otherwise clear out all the status bits but the RF Kill | 2590 | /* ...otherwise clear out all the status bits but the RF Kill |
2721 | * bits and continue taking the NIC down. */ | 2591 | * bit and continue taking the NIC down. */ |
2722 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << | 2592 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << |
2723 | STATUS_RF_KILL_HW | | 2593 | STATUS_RF_KILL_HW | |
2724 | test_bit(STATUS_RF_KILL_SW, &priv->status) << | ||
2725 | STATUS_RF_KILL_SW | | ||
2726 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 2594 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
2727 | STATUS_GEO_CONFIGURED | | 2595 | STATUS_GEO_CONFIGURED | |
2728 | test_bit(STATUS_FW_ERROR, &priv->status) << | 2596 | test_bit(STATUS_FW_ERROR, &priv->status) << |
@@ -2779,12 +2647,6 @@ static int __iwl3945_up(struct iwl_priv *priv) | |||
2779 | return -EIO; | 2647 | return -EIO; |
2780 | } | 2648 | } |
2781 | 2649 | ||
2782 | if (test_bit(STATUS_RF_KILL_SW, &priv->status)) { | ||
2783 | IWL_WARN(priv, "Radio disabled by SW RF kill (module " | ||
2784 | "parameter)\n"); | ||
2785 | return -ENODEV; | ||
2786 | } | ||
2787 | |||
2788 | if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { | 2650 | if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { |
2789 | IWL_ERR(priv, "ucode not available for device bring up\n"); | 2651 | IWL_ERR(priv, "ucode not available for device bring up\n"); |
2790 | return -EIO; | 2652 | return -EIO; |
@@ -2833,7 +2695,7 @@ static int __iwl3945_up(struct iwl_priv *priv) | |||
2833 | 2695 | ||
2834 | for (i = 0; i < MAX_HW_RESTARTS; i++) { | 2696 | for (i = 0; i < MAX_HW_RESTARTS; i++) { |
2835 | 2697 | ||
2836 | priv->cfg->ops->smgmt->clear_station_table(priv); | 2698 | iwl_clear_stations_table(priv); |
2837 | 2699 | ||
2838 | /* load bootstrap state machine, | 2700 | /* load bootstrap state machine, |
2839 | * load bootstrap program into processor's memory, | 2701 | * load bootstrap program into processor's memory, |
@@ -2901,15 +2763,14 @@ static void iwl3945_rfkill_poll(struct work_struct *data) | |||
2901 | { | 2763 | { |
2902 | struct iwl_priv *priv = | 2764 | struct iwl_priv *priv = |
2903 | container_of(data, struct iwl_priv, rfkill_poll.work); | 2765 | container_of(data, struct iwl_priv, rfkill_poll.work); |
2904 | unsigned long status = priv->status; | ||
2905 | 2766 | ||
2906 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | 2767 | if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) |
2907 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 2768 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
2908 | else | 2769 | else |
2909 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 2770 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
2910 | 2771 | ||
2911 | if (test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status)) | 2772 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
2912 | queue_work(priv->workqueue, &priv->rf_kill); | 2773 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
2913 | 2774 | ||
2914 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, | 2775 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, |
2915 | round_jiffies_relative(2 * HZ)); | 2776 | round_jiffies_relative(2 * HZ)); |
@@ -3141,7 +3002,6 @@ static void iwl3945_bg_up(struct work_struct *data) | |||
3141 | mutex_lock(&priv->mutex); | 3002 | mutex_lock(&priv->mutex); |
3142 | __iwl3945_up(priv); | 3003 | __iwl3945_up(priv); |
3143 | mutex_unlock(&priv->mutex); | 3004 | mutex_unlock(&priv->mutex); |
3144 | iwl_rfkill_set_hw_state(priv); | ||
3145 | } | 3005 | } |
3146 | 3006 | ||
3147 | static void iwl3945_bg_restart(struct work_struct *data) | 3007 | static void iwl3945_bg_restart(struct work_struct *data) |
@@ -3247,7 +3107,7 @@ void iwl3945_post_associate(struct iwl_priv *priv) | |||
3247 | case NL80211_IFTYPE_ADHOC: | 3107 | case NL80211_IFTYPE_ADHOC: |
3248 | 3108 | ||
3249 | priv->assoc_id = 1; | 3109 | priv->assoc_id = 1; |
3250 | priv->cfg->ops->smgmt->add_station(priv, priv->bssid, 0, 0, NULL); | 3110 | iwl_add_station(priv, priv->bssid, 0, CMD_SYNC, NULL); |
3251 | iwl3945_sync_sta(priv, IWL_STA_ID, | 3111 | iwl3945_sync_sta(priv, IWL_STA_ID, |
3252 | (priv->band == IEEE80211_BAND_5GHZ) ? | 3112 | (priv->band == IEEE80211_BAND_5GHZ) ? |
3253 | IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, | 3113 | IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, |
@@ -3304,8 +3164,6 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) | |||
3304 | 3164 | ||
3305 | mutex_unlock(&priv->mutex); | 3165 | mutex_unlock(&priv->mutex); |
3306 | 3166 | ||
3307 | iwl_rfkill_set_hw_state(priv); | ||
3308 | |||
3309 | if (ret) | 3167 | if (ret) |
3310 | goto out_release_irq; | 3168 | goto out_release_irq; |
3311 | 3169 | ||
@@ -3438,7 +3296,7 @@ void iwl3945_config_ap(struct iwl_priv *priv) | |||
3438 | /* restore RXON assoc */ | 3296 | /* restore RXON assoc */ |
3439 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 3297 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
3440 | iwlcore_commit_rxon(priv); | 3298 | iwlcore_commit_rxon(priv); |
3441 | priv->cfg->ops->smgmt->add_station(priv, iwl_bcast_addr, 0, 0, NULL); | 3299 | iwl_add_station(priv, iwl_bcast_addr, 0, CMD_SYNC, NULL); |
3442 | } | 3300 | } |
3443 | iwl3945_send_beacon_cmd(priv); | 3301 | iwl3945_send_beacon_cmd(priv); |
3444 | 3302 | ||
@@ -3469,7 +3327,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
3469 | static_key = !iwl_is_associated(priv); | 3327 | static_key = !iwl_is_associated(priv); |
3470 | 3328 | ||
3471 | if (!static_key) { | 3329 | if (!static_key) { |
3472 | sta_id = priv->cfg->ops->smgmt->find_station(priv, addr); | 3330 | sta_id = iwl_find_station(priv, addr); |
3473 | if (sta_id == IWL_INVALID_STATION) { | 3331 | if (sta_id == IWL_INVALID_STATION) { |
3474 | IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", | 3332 | IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", |
3475 | addr); | 3333 | addr); |
@@ -3958,7 +3816,6 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv) | |||
3958 | INIT_WORK(&priv->up, iwl3945_bg_up); | 3816 | INIT_WORK(&priv->up, iwl3945_bg_up); |
3959 | INIT_WORK(&priv->restart, iwl3945_bg_restart); | 3817 | INIT_WORK(&priv->restart, iwl3945_bg_restart); |
3960 | INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); | 3818 | INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); |
3961 | INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); | ||
3962 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); | 3819 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); |
3963 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); | 3820 | INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); |
3964 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); | 3821 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); |
@@ -4044,7 +3901,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv) | |||
4044 | mutex_init(&priv->mutex); | 3901 | mutex_init(&priv->mutex); |
4045 | 3902 | ||
4046 | /* Clear the driver's (not device's) station table */ | 3903 | /* Clear the driver's (not device's) station table */ |
4047 | priv->cfg->ops->smgmt->clear_station_table(priv); | 3904 | iwl_clear_stations_table(priv); |
4048 | 3905 | ||
4049 | priv->data_retry_limit = -1; | 3906 | priv->data_retry_limit = -1; |
4050 | priv->ieee_channels = NULL; | 3907 | priv->ieee_channels = NULL; |
@@ -4325,13 +4182,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
4325 | if (err) | 4182 | if (err) |
4326 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); | 4183 | IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); |
4327 | 4184 | ||
4328 | err = iwl_rfkill_init(priv); | ||
4329 | if (err) | ||
4330 | IWL_ERR(priv, "Unable to initialize RFKILL system. " | ||
4331 | "Ignoring error: %d\n", err); | ||
4332 | else | ||
4333 | iwl_rfkill_set_hw_state(priv); | ||
4334 | |||
4335 | /* Start monitoring the killswitch */ | 4185 | /* Start monitoring the killswitch */ |
4336 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, | 4186 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, |
4337 | 2 * HZ); | 4187 | 2 * HZ); |
@@ -4397,7 +4247,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
4397 | 4247 | ||
4398 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); | 4248 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); |
4399 | 4249 | ||
4400 | iwl_rfkill_unregister(priv); | ||
4401 | cancel_delayed_work_sync(&priv->rfkill_poll); | 4250 | cancel_delayed_work_sync(&priv->rfkill_poll); |
4402 | 4251 | ||
4403 | iwl3945_dealloc_ucode_pci(priv); | 4252 | iwl3945_dealloc_ucode_pci(priv); |
@@ -4407,7 +4256,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
4407 | iwl3945_hw_txq_ctx_free(priv); | 4256 | iwl3945_hw_txq_ctx_free(priv); |
4408 | 4257 | ||
4409 | iwl3945_unset_hw_params(priv); | 4258 | iwl3945_unset_hw_params(priv); |
4410 | priv->cfg->ops->smgmt->clear_station_table(priv); | 4259 | iwl_clear_stations_table(priv); |
4411 | 4260 | ||
4412 | /*netif_stop_queue(dev); */ | 4261 | /*netif_stop_queue(dev); */ |
4413 | flush_workqueue(priv->workqueue); | 4262 | 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 @@ | |||
1 | config IWM | 1 | config 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 | ||
9 | config IWM_DEBUG | 8 | config 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 @@ | |||
1 | obj-$(CONFIG_IWM) := iwmc3200wifi.o | 1 | obj-$(CONFIG_IWM) := iwmc3200wifi.o |
2 | iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o | 2 | iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o |
3 | iwmc3200wifi-objs += commands.o wext.o cfg80211.o eeprom.o rfkill.o | 3 | iwmc3200wifi-objs += commands.o wext.o cfg80211.o eeprom.o |
4 | 4 | ||
5 | iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o | 5 | iwmc3200wifi-$(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); |
344 | void iwm_rx_free(struct iwm_priv *iwm); | 344 | void iwm_rx_free(struct iwm_priv *iwm); |
345 | 345 | ||
346 | /* RF Kill API */ | ||
347 | int iwm_rfkill_init(struct iwm_priv *iwm); | ||
348 | void 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 | |||
28 | static 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 | |||
54 | int 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 | |||
81 | void 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 | */ |
305 | static int parse_domain_info_11d(struct ieeetypes_countryinfofullset* | 305 | static 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: | |||
556 | int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp) | 554 | int 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 @@ | |||
20 | struct cmd_ds_command; | 20 | struct cmd_ds_command; |
21 | 21 | ||
22 | /** Data structure for Country IE*/ | 22 | /** Data structure for Country IE*/ |
23 | struct ieeetypes_subbandset { | 23 | struct 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 | ||
29 | struct ieeetypes_countryinfoset { | 29 | struct 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 | ||
36 | struct ieeetypes_countryinfofullset { | 36 | struct 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 | ||
43 | struct mrvlietypes_domainparamset { | 43 | struct 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 | ||
49 | struct cmd_ds_802_11d_domain_info { | 50 | struct 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 | ||
63 | struct chan_power_11d { | 64 | struct 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 | ||
15 | static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp); | ||
16 | |||
17 | static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) = | 15 | static const u8 bssid_any[ETH_ALEN] __attribute__ ((aligned (2))) = |
18 | { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 16 | { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
19 | static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) = | 17 | static 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 | ||
104 | static 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 | */ | ||
128 | static 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 | |||
151 | static 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 | |||
250 | done: | ||
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 | */ | ||
266 | static 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 | |||
388 | done: | ||
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 | */ |
113 | static int lbs_associate(struct lbs_private *priv, | 401 | static 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 | ||
139 | out: | 430 | out: |
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 | ||
435 | static 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 | |||
495 | done: | ||
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 | ||
293 | out: | 650 | out: |
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 | ||
400 | out: | 760 | out: |
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 | */ | ||
1478 | int 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 | |||
1515 | out: | ||
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 | ||
1553 | int 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 | |||
1662 | done: | ||
1663 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); | ||
1664 | return ret; | ||
1665 | } | ||
1666 | |||
1667 | int 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 | |||
1763 | done: | ||
1764 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); | ||
1765 | return ret; | ||
1766 | } | ||
1767 | |||
1768 | static 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 | |||
1830 | done: | ||
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 @@ | |||
8 | void lbs_association_worker(struct work_struct *work); | 8 | void lbs_association_worker(struct work_struct *work); |
9 | struct assoc_request *lbs_get_association_request(struct lbs_private *priv); | 9 | struct assoc_request *lbs_get_association_request(struct lbs_private *priv); |
10 | 10 | ||
11 | struct cmd_ds_command; | ||
12 | int lbs_cmd_80211_authenticate(struct lbs_private *priv, | ||
13 | struct cmd_ds_command *cmd, | ||
14 | void *pdata_buf); | ||
15 | |||
16 | int lbs_adhoc_stop(struct lbs_private *priv); | 11 | int lbs_adhoc_stop(struct lbs_private *priv); |
17 | 12 | ||
18 | int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, | 13 | int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, |
19 | u8 bssid[ETH_ALEN], u16 reason); | 14 | u8 bssid[ETH_ALEN], u16 reason); |
20 | int lbs_cmd_80211_associate(struct lbs_private *priv, | ||
21 | struct cmd_ds_command *cmd, | ||
22 | void *pdata_buf); | ||
23 | |||
24 | int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv, | ||
25 | struct cmd_ds_command *resp); | ||
26 | int 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 | */ |
184 | static void *lbs_tlv_find(uint16_t tlv_type, const uint8_t *tlv, uint16_t size) | 184 | static 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 | ||
328 | extern struct cmd_confirm_sleep confirm_sleep; | 326 | extern 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 | ||
252 | struct cmd_ds_802_11_authenticate { | 252 | struct 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 | ||
265 | struct cmd_ds_802_11_associate { | 267 | struct 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 | ||
280 | struct cmd_ds_802_11_associate_rsp { | 278 | struct 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 | ||
284 | struct cmd_ds_802_11_set_wep { | 287 | struct 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 | */ | ||
58 | static u8 user_rmmod; | ||
59 | |||
44 | static char *lbs_helper_name = NULL; | 60 | static char *lbs_helper_name = NULL; |
45 | module_param_named(helper_name, lbs_helper_name, charp, 0644); | 61 | module_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 | ||
67 | static struct if_sdio_model if_sdio_models[] = { | 82 | static 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 | ||
1124 | static void __exit if_sdio_exit_module(void) | 1154 | static 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..f8c2898d82b0 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c | |||
@@ -19,7 +19,6 @@ | |||
19 | 19 | ||
20 | #include <linux/moduleparam.h> | 20 | #include <linux/moduleparam.h> |
21 | #include <linux/firmware.h> | 21 | #include <linux/firmware.h> |
22 | #include <linux/gpio.h> | ||
23 | #include <linux/jiffies.h> | 22 | #include <linux/jiffies.h> |
24 | #include <linux/kthread.h> | 23 | #include <linux/kthread.h> |
25 | #include <linux/list.h> | 24 | #include <linux/list.h> |
@@ -51,13 +50,6 @@ struct if_spi_card { | |||
51 | u16 card_id; | 50 | u16 card_id; |
52 | u8 card_rev; | 51 | u8 card_rev; |
53 | 52 | ||
54 | /* Pin number for our GPIO chip-select. */ | ||
55 | /* TODO: Once the generic SPI layer has some additional features, we | ||
56 | * should take this out and use the normal chip select here. | ||
57 | * We need support for chip select delays, and not dropping chipselect | ||
58 | * after each word. */ | ||
59 | int gpio_cs; | ||
60 | |||
61 | /* The last time that we initiated an SPU operation */ | 53 | /* The last time that we initiated an SPU operation */ |
62 | unsigned long prev_xfer_time; | 54 | unsigned long prev_xfer_time; |
63 | 55 | ||
@@ -119,9 +111,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 | 111 | * First we have to put a SPU register name on the bus. Then we can |
120 | * either read from or write to that register. | 112 | * either read from or write to that register. |
121 | * | 113 | * |
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 | */ | 114 | */ |
126 | 115 | ||
127 | static void spu_transaction_init(struct if_spi_card *card) | 116 | static void spu_transaction_init(struct if_spi_card *card) |
@@ -133,12 +122,10 @@ static void spu_transaction_init(struct if_spi_card *card) | |||
133 | * If not, we have to busy-wait to be on the safe side. */ | 122 | * If not, we have to busy-wait to be on the safe side. */ |
134 | ndelay(400); | 123 | ndelay(400); |
135 | } | 124 | } |
136 | gpio_set_value(card->gpio_cs, 0); /* assert CS */ | ||
137 | } | 125 | } |
138 | 126 | ||
139 | static void spu_transaction_finish(struct if_spi_card *card) | 127 | static void spu_transaction_finish(struct if_spi_card *card) |
140 | { | 128 | { |
141 | gpio_set_value(card->gpio_cs, 1); /* drop CS */ | ||
142 | card->prev_xfer_time = jiffies; | 129 | card->prev_xfer_time = jiffies; |
143 | } | 130 | } |
144 | 131 | ||
@@ -147,7 +134,14 @@ static void spu_transaction_finish(struct if_spi_card *card) | |||
147 | static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) | 134 | static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) |
148 | { | 135 | { |
149 | int err = 0; | 136 | int err = 0; |
150 | u16 reg_out = reg | IF_SPI_WRITE_OPERATION_MASK; | 137 | u16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK); |
138 | struct spi_message m; | ||
139 | struct spi_transfer reg_trans; | ||
140 | struct spi_transfer data_trans; | ||
141 | |||
142 | spi_message_init(&m); | ||
143 | memset(®_trans, 0, sizeof(reg_trans)); | ||
144 | memset(&data_trans, 0, sizeof(data_trans)); | ||
151 | 145 | ||
152 | /* You must give an even number of bytes to the SPU, even if it | 146 | /* You must give an even number of bytes to the SPU, even if it |
153 | * doesn't care about the last one. */ | 147 | * doesn't care about the last one. */ |
@@ -156,29 +150,26 @@ static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) | |||
156 | spu_transaction_init(card); | 150 | spu_transaction_init(card); |
157 | 151 | ||
158 | /* write SPU register index */ | 152 | /* write SPU register index */ |
159 | err = spi_write(card->spi, (u8 *)®_out, sizeof(u16)); | 153 | reg_trans.tx_buf = ®_out; |
160 | if (err) | 154 | reg_trans.len = sizeof(reg_out); |
161 | goto out; | ||
162 | 155 | ||
163 | err = spi_write(card->spi, buf, len); | 156 | data_trans.tx_buf = buf; |
157 | data_trans.len = len; | ||
164 | 158 | ||
165 | out: | 159 | spi_message_add_tail(®_trans, &m); |
160 | spi_message_add_tail(&data_trans, &m); | ||
161 | |||
162 | err = spi_sync(card->spi, &m); | ||
166 | spu_transaction_finish(card); | 163 | spu_transaction_finish(card); |
167 | return err; | 164 | return err; |
168 | } | 165 | } |
169 | 166 | ||
170 | static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val) | 167 | static 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 | ||
175 | static 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 | ||
184 | static inline int spu_reg_is_port_reg(u16 reg) | 175 | static inline int spu_reg_is_port_reg(u16 reg) |
@@ -195,10 +186,13 @@ static inline int spu_reg_is_port_reg(u16 reg) | |||
195 | 186 | ||
196 | static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) | 187 | static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) |
197 | { | 188 | { |
198 | unsigned int i, delay; | 189 | unsigned int delay; |
199 | int err = 0; | 190 | int err = 0; |
200 | u16 zero = 0; | 191 | u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK); |
201 | u16 reg_out = reg | IF_SPI_READ_OPERATION_MASK; | 192 | struct spi_message m; |
193 | struct spi_transfer reg_trans; | ||
194 | struct spi_transfer dummy_trans; | ||
195 | struct spi_transfer data_trans; | ||
202 | 196 | ||
203 | /* You must take an even number of bytes from the SPU, even if you | 197 | /* You must take an even number of bytes from the SPU, even if you |
204 | * don't care about the last one. */ | 198 | * don't care about the last one. */ |
@@ -206,29 +200,34 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) | |||
206 | 200 | ||
207 | spu_transaction_init(card); | 201 | spu_transaction_init(card); |
208 | 202 | ||
203 | spi_message_init(&m); | ||
204 | memset(®_trans, 0, sizeof(reg_trans)); | ||
205 | memset(&dummy_trans, 0, sizeof(dummy_trans)); | ||
206 | memset(&data_trans, 0, sizeof(data_trans)); | ||
207 | |||
209 | /* write SPU register index */ | 208 | /* write SPU register index */ |
210 | err = spi_write(card->spi, (u8 *)®_out, sizeof(u16)); | 209 | reg_trans.tx_buf = ®_out; |
211 | if (err) | 210 | reg_trans.len = sizeof(reg_out); |
212 | goto out; | 211 | spi_message_add_tail(®_trans, &m); |
213 | 212 | ||
214 | delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay : | 213 | delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay : |
215 | card->spu_reg_delay; | 214 | card->spu_reg_delay; |
216 | if (card->use_dummy_writes) { | 215 | if (card->use_dummy_writes) { |
217 | /* Clock in dummy cycles while the SPU fills the FIFO */ | 216 | /* Clock in dummy cycles while the SPU fills the FIFO */ |
218 | for (i = 0; i < delay / 16; ++i) { | 217 | dummy_trans.len = delay / 8; |
219 | err = spi_write(card->spi, (u8 *)&zero, sizeof(u16)); | 218 | spi_message_add_tail(&dummy_trans, &m); |
220 | if (err) | ||
221 | return err; | ||
222 | } | ||
223 | } else { | 219 | } else { |
224 | /* Busy-wait while the SPU fills the FIFO */ | 220 | /* Busy-wait while the SPU fills the FIFO */ |
225 | ndelay(100 + (delay * 10)); | 221 | reg_trans.delay_usecs = |
222 | DIV_ROUND_UP((100 + (delay * 10)), 1000); | ||
226 | } | 223 | } |
227 | 224 | ||
228 | /* read in data */ | 225 | /* read in data */ |
229 | err = spi_read(card->spi, buf, len); | 226 | data_trans.rx_buf = buf; |
227 | data_trans.len = len; | ||
228 | spi_message_add_tail(&data_trans, &m); | ||
230 | 229 | ||
231 | out: | 230 | err = spi_sync(card->spi, &m); |
232 | spu_transaction_finish(card); | 231 | spu_transaction_finish(card); |
233 | return err; | 232 | return err; |
234 | } | 233 | } |
@@ -236,18 +235,25 @@ out: | |||
236 | /* Read 16 bits from an SPI register */ | 235 | /* Read 16 bits from an SPI register */ |
237 | static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val) | 236 | static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val) |
238 | { | 237 | { |
239 | return spu_read(card, reg, (u8 *)val, sizeof(u16)); | 238 | u16 buf; |
239 | int ret; | ||
240 | |||
241 | ret = spu_read(card, reg, (u8 *)&buf, sizeof(buf)); | ||
242 | if (ret == 0) | ||
243 | *val = le16_to_cpup(&buf); | ||
244 | return ret; | ||
240 | } | 245 | } |
241 | 246 | ||
242 | /* Read 32 bits from an SPI register. | 247 | /* Read 32 bits from an SPI register. |
243 | * The low 16 bits are read first. */ | 248 | * The low 16 bits are read first. */ |
244 | static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) | 249 | static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) |
245 | { | 250 | { |
246 | u16 buf[2]; | 251 | u32 buf; |
247 | int err; | 252 | int err; |
248 | err = spu_read(card, reg, (u8 *)buf, sizeof(u32)); | 253 | |
254 | err = spu_read(card, reg, (u8 *)&buf, sizeof(buf)); | ||
249 | if (!err) | 255 | if (!err) |
250 | *val = buf[0] | (buf[1] << 16); | 256 | *val = le32_to_cpup(&buf); |
251 | return err; | 257 | return err; |
252 | } | 258 | } |
253 | 259 | ||
@@ -1051,7 +1057,6 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1051 | spi_set_drvdata(spi, card); | 1057 | spi_set_drvdata(spi, card); |
1052 | card->pdata = pdata; | 1058 | card->pdata = pdata; |
1053 | card->spi = spi; | 1059 | card->spi = spi; |
1054 | card->gpio_cs = pdata->gpio_cs; | ||
1055 | card->prev_xfer_time = jiffies; | 1060 | card->prev_xfer_time = jiffies; |
1056 | 1061 | ||
1057 | sema_init(&card->spi_ready, 0); | 1062 | sema_init(&card->spi_ready, 0); |
@@ -1060,26 +1065,18 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1060 | INIT_LIST_HEAD(&card->data_packet_list); | 1065 | INIT_LIST_HEAD(&card->data_packet_list); |
1061 | spin_lock_init(&card->buffer_lock); | 1066 | spin_lock_init(&card->buffer_lock); |
1062 | 1067 | ||
1063 | /* set up GPIO CS line. TODO: use regular CS line */ | ||
1064 | err = gpio_request(card->gpio_cs, "if_spi_gpio_chip_select"); | ||
1065 | if (err) | ||
1066 | goto free_card; | ||
1067 | err = gpio_direction_output(card->gpio_cs, 1); | ||
1068 | if (err) | ||
1069 | goto free_gpio; | ||
1070 | |||
1071 | /* Initialize the SPI Interface Unit */ | 1068 | /* Initialize the SPI Interface Unit */ |
1072 | err = spu_init(card, pdata->use_dummy_writes); | 1069 | err = spu_init(card, pdata->use_dummy_writes); |
1073 | if (err) | 1070 | if (err) |
1074 | goto free_gpio; | 1071 | goto free_card; |
1075 | err = spu_get_chip_revision(card, &card->card_id, &card->card_rev); | 1072 | err = spu_get_chip_revision(card, &card->card_id, &card->card_rev); |
1076 | if (err) | 1073 | if (err) |
1077 | goto free_gpio; | 1074 | goto free_card; |
1078 | 1075 | ||
1079 | /* Firmware load */ | 1076 | /* Firmware load */ |
1080 | err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch); | 1077 | err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch); |
1081 | if (err) | 1078 | if (err) |
1082 | goto free_gpio; | 1079 | goto free_card; |
1083 | if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC) | 1080 | if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC) |
1084 | lbs_deb_spi("Firmware is already loaded for " | 1081 | lbs_deb_spi("Firmware is already loaded for " |
1085 | "Marvell WLAN 802.11 adapter\n"); | 1082 | "Marvell WLAN 802.11 adapter\n"); |
@@ -1087,7 +1084,7 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1087 | err = if_spi_calculate_fw_names(card->card_id, | 1084 | err = if_spi_calculate_fw_names(card->card_id, |
1088 | card->helper_fw_name, card->main_fw_name); | 1085 | card->helper_fw_name, card->main_fw_name); |
1089 | if (err) | 1086 | if (err) |
1090 | goto free_gpio; | 1087 | goto free_card; |
1091 | 1088 | ||
1092 | lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " | 1089 | lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " |
1093 | "(chip_id = 0x%04x, chip_rev = 0x%02x) " | 1090 | "(chip_id = 0x%04x, chip_rev = 0x%02x) " |
@@ -1098,23 +1095,23 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1098 | spi->max_speed_hz); | 1095 | spi->max_speed_hz); |
1099 | err = if_spi_prog_helper_firmware(card); | 1096 | err = if_spi_prog_helper_firmware(card); |
1100 | if (err) | 1097 | if (err) |
1101 | goto free_gpio; | 1098 | goto free_card; |
1102 | err = if_spi_prog_main_firmware(card); | 1099 | err = if_spi_prog_main_firmware(card); |
1103 | if (err) | 1100 | if (err) |
1104 | goto free_gpio; | 1101 | goto free_card; |
1105 | lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n"); | 1102 | lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n"); |
1106 | } | 1103 | } |
1107 | 1104 | ||
1108 | err = spu_set_interrupt_mode(card, 0, 1); | 1105 | err = spu_set_interrupt_mode(card, 0, 1); |
1109 | if (err) | 1106 | if (err) |
1110 | goto free_gpio; | 1107 | goto free_card; |
1111 | 1108 | ||
1112 | /* Register our card with libertas. | 1109 | /* Register our card with libertas. |
1113 | * This will call alloc_etherdev */ | 1110 | * This will call alloc_etherdev */ |
1114 | priv = lbs_add_card(card, &spi->dev); | 1111 | priv = lbs_add_card(card, &spi->dev); |
1115 | if (!priv) { | 1112 | if (!priv) { |
1116 | err = -ENOMEM; | 1113 | err = -ENOMEM; |
1117 | goto free_gpio; | 1114 | goto free_card; |
1118 | } | 1115 | } |
1119 | card->priv = priv; | 1116 | card->priv = priv; |
1120 | priv->card = card; | 1117 | priv->card = card; |
@@ -1159,8 +1156,6 @@ terminate_thread: | |||
1159 | if_spi_terminate_spi_thread(card); | 1156 | if_spi_terminate_spi_thread(card); |
1160 | remove_card: | 1157 | remove_card: |
1161 | lbs_remove_card(priv); /* will call free_netdev */ | 1158 | lbs_remove_card(priv); /* will call free_netdev */ |
1162 | free_gpio: | ||
1163 | gpio_free(card->gpio_cs); | ||
1164 | free_card: | 1159 | free_card: |
1165 | free_if_spi_card(card); | 1160 | free_if_spi_card(card); |
1166 | out: | 1161 | out: |
@@ -1181,7 +1176,6 @@ static int __devexit libertas_spi_remove(struct spi_device *spi) | |||
1181 | free_irq(spi->irq, card); | 1176 | free_irq(spi->irq, card); |
1182 | if_spi_terminate_spi_thread(card); | 1177 | if_spi_terminate_spi_thread(card); |
1183 | lbs_remove_card(priv); /* will call free_netdev */ | 1178 | lbs_remove_card(priv); /* will call free_netdev */ |
1184 | gpio_free(card->gpio_cs); | ||
1185 | if (card->pdata->teardown) | 1179 | if (card->pdata->teardown) |
1186 | card->pdata->teardown(spi); | 1180 | card->pdata->teardown(spi); |
1187 | free_if_spi_card(card); | 1181 | free_if_spi_card(card); |
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 | */ |
212 | static int lbs_scan_add_ssid_tlv(struct lbs_private *priv, u8 *tlv) | 212 | static 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, | |||
270 | static int lbs_scan_add_rates_tlv(uint8_t *tlv) | 270 | static 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) | |||
513 | static int lbs_process_bss(struct bss_descriptor *bss, | 513 | static 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 | ||
11 | struct ieeetypes_cfparamset { | 11 | struct ieee_ie_header { |
12 | u8 elementid; | 12 | u8 id; |
13 | u8 len; | 13 | u8 len; |
14 | } __attribute__ ((packed)); | ||
15 | |||
16 | struct 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 | ||
21 | struct ieeetypes_ibssparamset { | 26 | struct 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 | ||
27 | union IEEEtypes_ssparamset { | 32 | union 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 | ||
32 | struct ieeetypes_fhparamset { | 37 | struct 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 | ||
41 | struct ieeetypes_dsparamset { | 46 | struct 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 | ||
47 | union ieeetypes_phyparamset { | 49 | u8 channel; |
48 | struct ieeetypes_fhparamset fhparamset; | ||
49 | struct ieeetypes_dsparamset dsparamset; | ||
50 | } __attribute__ ((packed)); | 50 | } __attribute__ ((packed)); |
51 | 51 | ||
52 | struct ieeetypes_assocrsp { | 52 | union 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*/ |
101 | struct mrvlietypesheader { | 100 | struct mrvl_ie_header { |
102 | __le16 type; | 101 | __le16 type; |
103 | __le16 len; | 102 | __le16 len; |
104 | } __attribute__ ((packed)); | 103 | } __attribute__ ((packed)); |
105 | 104 | ||
106 | struct mrvlietypes_data { | 105 | struct 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 | ||
111 | struct mrvlietypes_ratesparamset { | 110 | struct 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 | ||
116 | struct mrvlietypes_ssidparamset { | 115 | struct 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 | ||
121 | struct mrvlietypes_wildcardssidparamset { | 120 | struct 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 | ||
147 | struct mrvlietypes_chanlistparamset { | 146 | struct 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 | ||
152 | struct cfparamset { | 151 | struct 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 | ||
159 | struct ibssparamset { | 159 | struct mrvl_ie_ds_param_set { |
160 | __le16 atimwindow; | 160 | struct mrvl_ie_header header; |
161 | } __attribute__ ((packed)); | 161 | u8 channel; |
162 | |||
163 | struct 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 | ||
171 | struct fhparamset { | 164 | struct 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 | |||
178 | struct dsparamset { | ||
179 | u8 currentchan; | ||
180 | } __attribute__ ((packed)); | ||
181 | |||
182 | struct 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 | |||
190 | struct mrvlietypes_rsnparamset { | ||
191 | struct mrvlietypesheader header; | ||
192 | u8 rsnie[1]; | 166 | u8 rsnie[1]; |
193 | } __attribute__ ((packed)); | 167 | } __attribute__ ((packed)); |
194 | 168 | ||
195 | struct mrvlietypes_tsftimestamp { | 169 | struct 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 */ | ||
175 | struct 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 */ |
201 | struct mrvlietypes_powercapability { | 181 | struct 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 */ |
208 | struct mrvlietypes_thresholds { | 188 | struct 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 | ||
214 | struct mrvlietypes_beaconsmissed { | 194 | struct 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 | ||
220 | struct mrvlietypes_numprobes { | 200 | struct 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 | ||
225 | struct mrvlietypes_bcastprobe { | 205 | struct 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 | ||
230 | struct mrvlietypes_numssidprobe { | 210 | struct 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 | ||
240 | struct mrvlietypes_ledgpio { | 220 | struct 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 | ||
253 | struct mrvlietypes_ledbhv { | 233 | struct 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 | ||
442 | static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 440 | static 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/p54common.c b/drivers/net/wireless/p54/p54common.c index 48d81d98e12d..b618bd14583f 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c | |||
@@ -823,30 +823,30 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
823 | struct p54_tx_info *range; | 823 | struct p54_tx_info *range; |
824 | unsigned long flags; | 824 | unsigned long flags; |
825 | 825 | ||
826 | if (unlikely(!skb || !dev || !skb_queue_len(&priv->tx_queue))) | 826 | if (unlikely(!skb || !dev || skb_queue_empty(&priv->tx_queue))) |
827 | return; | 827 | return; |
828 | 828 | ||
829 | /* | 829 | /* There used to be a check here to see if the SKB was on the |
830 | * don't try to free an already unlinked skb | 830 | * TX queue or not. This can never happen because all SKBs we |
831 | * see here successfully went through p54_assign_address() | ||
832 | * which means the SKB is on the ->tx_queue. | ||
831 | */ | 833 | */ |
832 | if (unlikely((!skb->next) || (!skb->prev))) | ||
833 | return; | ||
834 | 834 | ||
835 | spin_lock_irqsave(&priv->tx_queue.lock, flags); | 835 | spin_lock_irqsave(&priv->tx_queue.lock, flags); |
836 | info = IEEE80211_SKB_CB(skb); | 836 | info = IEEE80211_SKB_CB(skb); |
837 | range = (void *)info->rate_driver_data; | 837 | range = (void *)info->rate_driver_data; |
838 | if (skb->prev != (struct sk_buff *)&priv->tx_queue) { | 838 | if (!skb_queue_is_first(&priv->tx_queue, skb)) { |
839 | struct ieee80211_tx_info *ni; | 839 | struct ieee80211_tx_info *ni; |
840 | struct p54_tx_info *mr; | 840 | struct p54_tx_info *mr; |
841 | 841 | ||
842 | ni = IEEE80211_SKB_CB(skb->prev); | 842 | ni = IEEE80211_SKB_CB(skb_queue_prev(&priv->tx_queue, skb)); |
843 | mr = (struct p54_tx_info *)ni->rate_driver_data; | 843 | mr = (struct p54_tx_info *)ni->rate_driver_data; |
844 | } | 844 | } |
845 | if (skb->next != (struct sk_buff *)&priv->tx_queue) { | 845 | if (!skb_queue_is_last(&priv->tx_queue, skb)) { |
846 | struct ieee80211_tx_info *ni; | 846 | struct ieee80211_tx_info *ni; |
847 | struct p54_tx_info *mr; | 847 | struct p54_tx_info *mr; |
848 | 848 | ||
849 | ni = IEEE80211_SKB_CB(skb->next); | 849 | ni = IEEE80211_SKB_CB(skb_queue_next(&priv->tx_queue, skb)); |
850 | mr = (struct p54_tx_info *)ni->rate_driver_data; | 850 | mr = (struct p54_tx_info *)ni->rate_driver_data; |
851 | } | 851 | } |
852 | __skb_unlink(skb, &priv->tx_queue); | 852 | __skb_unlink(skb, &priv->tx_queue); |
@@ -864,15 +864,13 @@ static struct sk_buff *p54_find_tx_entry(struct ieee80211_hw *dev, | |||
864 | unsigned long flags; | 864 | unsigned long flags; |
865 | 865 | ||
866 | spin_lock_irqsave(&priv->tx_queue.lock, flags); | 866 | spin_lock_irqsave(&priv->tx_queue.lock, flags); |
867 | entry = priv->tx_queue.next; | 867 | skb_queue_walk(&priv->tx_queue, entry) { |
868 | while (entry != (struct sk_buff *)&priv->tx_queue) { | ||
869 | struct p54_hdr *hdr = (struct p54_hdr *) entry->data; | 868 | struct p54_hdr *hdr = (struct p54_hdr *) entry->data; |
870 | 869 | ||
871 | if (hdr->req_id == req_id) { | 870 | if (hdr->req_id == req_id) { |
872 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); | 871 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); |
873 | return entry; | 872 | return entry; |
874 | } | 873 | } |
875 | entry = entry->next; | ||
876 | } | 874 | } |
877 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); | 875 | spin_unlock_irqrestore(&priv->tx_queue.lock, flags); |
878 | return NULL; | 876 | return NULL; |
@@ -890,24 +888,22 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
890 | int count, idx; | 888 | int count, idx; |
891 | 889 | ||
892 | spin_lock_irqsave(&priv->tx_queue.lock, flags); | 890 | spin_lock_irqsave(&priv->tx_queue.lock, flags); |
893 | entry = (struct sk_buff *) priv->tx_queue.next; | 891 | skb_queue_walk(&priv->tx_queue, entry) { |
894 | while (entry != (struct sk_buff *)&priv->tx_queue) { | ||
895 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry); | 892 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry); |
896 | struct p54_hdr *entry_hdr; | 893 | struct p54_hdr *entry_hdr; |
897 | struct p54_tx_data *entry_data; | 894 | struct p54_tx_data *entry_data; |
898 | unsigned int pad = 0, frame_len; | 895 | unsigned int pad = 0, frame_len; |
899 | 896 | ||
900 | range = (void *)info->rate_driver_data; | 897 | range = (void *)info->rate_driver_data; |
901 | if (range->start_addr != addr) { | 898 | if (range->start_addr != addr) |
902 | entry = entry->next; | ||
903 | continue; | 899 | continue; |
904 | } | ||
905 | 900 | ||
906 | if (entry->next != (struct sk_buff *)&priv->tx_queue) { | 901 | if (!skb_queue_is_last(&priv->tx_queue, entry)) { |
907 | struct ieee80211_tx_info *ni; | 902 | struct ieee80211_tx_info *ni; |
908 | struct p54_tx_info *mr; | 903 | struct p54_tx_info *mr; |
909 | 904 | ||
910 | ni = IEEE80211_SKB_CB(entry->next); | 905 | ni = IEEE80211_SKB_CB(skb_queue_next(&priv->tx_queue, |
906 | entry)); | ||
911 | mr = (struct p54_tx_info *)ni->rate_driver_data; | 907 | mr = (struct p54_tx_info *)ni->rate_driver_data; |
912 | } | 908 | } |
913 | 909 | ||
@@ -1168,23 +1164,21 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1168 | } | 1164 | } |
1169 | } | 1165 | } |
1170 | 1166 | ||
1171 | entry = priv->tx_queue.next; | 1167 | skb_queue_walk(&priv->tx_queue, entry) { |
1172 | while (left--) { | ||
1173 | u32 hole_size; | 1168 | u32 hole_size; |
1174 | info = IEEE80211_SKB_CB(entry); | 1169 | info = IEEE80211_SKB_CB(entry); |
1175 | range = (void *)info->rate_driver_data; | 1170 | range = (void *)info->rate_driver_data; |
1176 | hole_size = range->start_addr - last_addr; | 1171 | hole_size = range->start_addr - last_addr; |
1177 | if (!target_skb && hole_size >= len) { | 1172 | if (!target_skb && hole_size >= len) { |
1178 | target_skb = entry->prev; | 1173 | target_skb = skb_queue_prev(&priv->tx_queue, entry); |
1179 | hole_size -= len; | 1174 | hole_size -= len; |
1180 | target_addr = last_addr; | 1175 | target_addr = last_addr; |
1181 | } | 1176 | } |
1182 | largest_hole = max(largest_hole, hole_size); | 1177 | largest_hole = max(largest_hole, hole_size); |
1183 | last_addr = range->end_addr; | 1178 | last_addr = range->end_addr; |
1184 | entry = entry->next; | ||
1185 | } | 1179 | } |
1186 | if (!target_skb && priv->rx_end - last_addr >= len) { | 1180 | if (!target_skb && priv->rx_end - last_addr >= len) { |
1187 | target_skb = priv->tx_queue.prev; | 1181 | target_skb = skb_peek_tail(&priv->tx_queue); |
1188 | largest_hole = max(largest_hole, priv->rx_end - last_addr - len); | 1182 | largest_hole = max(largest_hole, priv->rx_end - last_addr - len); |
1189 | if (!skb_queue_empty(&priv->tx_queue)) { | 1183 | if (!skb_queue_empty(&priv->tx_queue)) { |
1190 | info = IEEE80211_SKB_CB(target_skb); | 1184 | info = IEEE80211_SKB_CB(target_skb); |
@@ -2090,7 +2084,6 @@ out: | |||
2090 | static void p54_stop(struct ieee80211_hw *dev) | 2084 | static void p54_stop(struct ieee80211_hw *dev) |
2091 | { | 2085 | { |
2092 | struct p54_common *priv = dev->priv; | 2086 | struct p54_common *priv = dev->priv; |
2093 | struct sk_buff *skb; | ||
2094 | 2087 | ||
2095 | mutex_lock(&priv->conf_mutex); | 2088 | mutex_lock(&priv->conf_mutex); |
2096 | priv->mode = NL80211_IFTYPE_UNSPECIFIED; | 2089 | priv->mode = NL80211_IFTYPE_UNSPECIFIED; |
@@ -2105,8 +2098,7 @@ static void p54_stop(struct ieee80211_hw *dev) | |||
2105 | p54_tx_cancel(dev, priv->cached_beacon); | 2098 | p54_tx_cancel(dev, priv->cached_beacon); |
2106 | 2099 | ||
2107 | priv->stop(dev); | 2100 | priv->stop(dev); |
2108 | while ((skb = skb_dequeue(&priv->tx_queue))) | 2101 | skb_queue_purge(&priv->tx_queue); |
2109 | kfree_skb(skb); | ||
2110 | priv->cached_beacon = NULL; | 2102 | priv->cached_beacon = NULL; |
2111 | priv->tsf_high32 = priv->tsf_low32 = 0; | 2103 | priv->tsf_high32 = priv->tsf_low32 = 0; |
2112 | mutex_unlock(&priv->conf_mutex); | 2104 | mutex_unlock(&priv->conf_mutex); |
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); | |||
84 | static const struct { | 84 | static 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/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index c254fdf446fd..7441d5585110 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -157,55 +157,55 @@ MODULE_PARM_DESC(workaround_interval, | |||
157 | #define NDIS_802_11_LENGTH_RATES_EX 16 | 157 | #define NDIS_802_11_LENGTH_RATES_EX 16 |
158 | 158 | ||
159 | enum ndis_80211_net_type { | 159 | enum ndis_80211_net_type { |
160 | ndis_80211_type_freq_hop, | 160 | NDIS_80211_TYPE_FREQ_HOP, |
161 | ndis_80211_type_direct_seq, | 161 | NDIS_80211_TYPE_DIRECT_SEQ, |
162 | ndis_80211_type_ofdm_a, | 162 | NDIS_80211_TYPE_OFDM_A, |
163 | ndis_80211_type_ofdm_g | 163 | NDIS_80211_TYPE_OFDM_G |
164 | }; | 164 | }; |
165 | 165 | ||
166 | enum ndis_80211_net_infra { | 166 | enum ndis_80211_net_infra { |
167 | ndis_80211_infra_adhoc, | 167 | NDIS_80211_INFRA_ADHOC, |
168 | ndis_80211_infra_infra, | 168 | NDIS_80211_INFRA_INFRA, |
169 | ndis_80211_infra_auto_unknown | 169 | NDIS_80211_INFRA_AUTO_UNKNOWN |
170 | }; | 170 | }; |
171 | 171 | ||
172 | enum ndis_80211_auth_mode { | 172 | enum ndis_80211_auth_mode { |
173 | ndis_80211_auth_open, | 173 | NDIS_80211_AUTH_OPEN, |
174 | ndis_80211_auth_shared, | 174 | NDIS_80211_AUTH_SHARED, |
175 | ndis_80211_auth_auto_switch, | 175 | NDIS_80211_AUTH_AUTO_SWITCH, |
176 | ndis_80211_auth_wpa, | 176 | NDIS_80211_AUTH_WPA, |
177 | ndis_80211_auth_wpa_psk, | 177 | NDIS_80211_AUTH_WPA_PSK, |
178 | ndis_80211_auth_wpa_none, | 178 | NDIS_80211_AUTH_WPA_NONE, |
179 | ndis_80211_auth_wpa2, | 179 | NDIS_80211_AUTH_WPA2, |
180 | ndis_80211_auth_wpa2_psk | 180 | NDIS_80211_AUTH_WPA2_PSK |
181 | }; | 181 | }; |
182 | 182 | ||
183 | enum ndis_80211_encr_status { | 183 | enum ndis_80211_encr_status { |
184 | ndis_80211_encr_wep_enabled, | 184 | NDIS_80211_ENCR_WEP_ENABLED, |
185 | ndis_80211_encr_disabled, | 185 | NDIS_80211_ENCR_DISABLED, |
186 | ndis_80211_encr_wep_key_absent, | 186 | NDIS_80211_ENCR_WEP_KEY_ABSENT, |
187 | ndis_80211_encr_not_supported, | 187 | NDIS_80211_ENCR_NOT_SUPPORTED, |
188 | ndis_80211_encr_tkip_enabled, | 188 | NDIS_80211_ENCR_TKIP_ENABLED, |
189 | ndis_80211_encr_tkip_key_absent, | 189 | NDIS_80211_ENCR_TKIP_KEY_ABSENT, |
190 | ndis_80211_encr_ccmp_enabled, | 190 | NDIS_80211_ENCR_CCMP_ENABLED, |
191 | ndis_80211_encr_ccmp_key_absent | 191 | NDIS_80211_ENCR_CCMP_KEY_ABSENT |
192 | }; | 192 | }; |
193 | 193 | ||
194 | enum ndis_80211_priv_filter { | 194 | enum ndis_80211_priv_filter { |
195 | ndis_80211_priv_accept_all, | 195 | NDIS_80211_PRIV_ACCEPT_ALL, |
196 | ndis_80211_priv_8021x_wep | 196 | NDIS_80211_PRIV_8021X_WEP |
197 | }; | 197 | }; |
198 | 198 | ||
199 | enum ndis_80211_addkey_bits { | 199 | enum ndis_80211_addkey_bits { |
200 | ndis_80211_addkey_8021x_auth = cpu_to_le32(1 << 28), | 200 | NDIS_80211_ADDKEY_8021X_AUTH = cpu_to_le32(1 << 28), |
201 | ndis_80211_addkey_set_init_recv_seq = cpu_to_le32(1 << 29), | 201 | NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ = cpu_to_le32(1 << 29), |
202 | ndis_80211_addkey_pairwise_key = cpu_to_le32(1 << 30), | 202 | NDIS_80211_ADDKEY_PAIRWISE_KEY = cpu_to_le32(1 << 30), |
203 | ndis_80211_addkey_transmit_key = cpu_to_le32(1 << 31), | 203 | NDIS_80211_ADDKEY_TRANSMIT_KEY = cpu_to_le32(1 << 31) |
204 | }; | 204 | }; |
205 | 205 | ||
206 | enum ndis_80211_addwep_bits { | 206 | enum ndis_80211_addwep_bits { |
207 | ndis_80211_addwep_perclient_key = cpu_to_le32(1 << 30), | 207 | NDIS_80211_ADDWEP_PERCLIENT_KEY = cpu_to_le32(1 << 30), |
208 | ndis_80211_addwep_transmit_key = cpu_to_le32(1 << 31), | 208 | NDIS_80211_ADDWEP_TRANSMIT_KEY = cpu_to_le32(1 << 31) |
209 | }; | 209 | }; |
210 | 210 | ||
211 | struct ndis_80211_ssid { | 211 | struct ndis_80211_ssid { |
@@ -361,7 +361,7 @@ static const struct ieee80211_rate rndis_rates[] = { | |||
361 | }; | 361 | }; |
362 | 362 | ||
363 | /* RNDIS device private data */ | 363 | /* RNDIS device private data */ |
364 | struct rndis_wext_private { | 364 | struct rndis_wlan_private { |
365 | struct usbnet *usbdev; | 365 | struct usbnet *usbdev; |
366 | 366 | ||
367 | struct wireless_dev wdev; | 367 | struct wireless_dev wdev; |
@@ -441,13 +441,13 @@ static const unsigned char ffff_bssid[ETH_ALEN] = { 0xff, 0xff, 0xff, | |||
441 | 0xff, 0xff, 0xff }; | 441 | 0xff, 0xff, 0xff }; |
442 | 442 | ||
443 | 443 | ||
444 | static struct rndis_wext_private *get_rndis_wext_priv(struct usbnet *dev) | 444 | static struct rndis_wlan_private *get_rndis_wlan_priv(struct usbnet *dev) |
445 | { | 445 | { |
446 | return (struct rndis_wext_private *)dev->driver_priv; | 446 | return (struct rndis_wlan_private *)dev->driver_priv; |
447 | } | 447 | } |
448 | 448 | ||
449 | 449 | ||
450 | static u32 get_bcm4320_power(struct rndis_wext_private *priv) | 450 | static u32 get_bcm4320_power(struct rndis_wlan_private *priv) |
451 | { | 451 | { |
452 | return BCM4320_DEFAULT_TXPOWER * | 452 | return BCM4320_DEFAULT_TXPOWER * |
453 | bcm4320_power_output[priv->param_power_output] / 100; | 453 | bcm4320_power_output[priv->param_power_output] / 100; |
@@ -480,7 +480,7 @@ static int rndis_error_status(__le32 rndis_status) | |||
480 | 480 | ||
481 | static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) | 481 | static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) |
482 | { | 482 | { |
483 | struct rndis_wext_private *priv = get_rndis_wext_priv(dev); | 483 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev); |
484 | union { | 484 | union { |
485 | void *buf; | 485 | void *buf; |
486 | struct rndis_msg_hdr *header; | 486 | struct rndis_msg_hdr *header; |
@@ -526,7 +526,7 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) | |||
526 | 526 | ||
527 | static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) | 527 | static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) |
528 | { | 528 | { |
529 | struct rndis_wext_private *priv = get_rndis_wext_priv(dev); | 529 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev); |
530 | union { | 530 | union { |
531 | void *buf; | 531 | void *buf; |
532 | struct rndis_msg_hdr *header; | 532 | struct rndis_msg_hdr *header; |
@@ -747,7 +747,7 @@ static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) | |||
747 | 747 | ||
748 | static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) | 748 | static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) |
749 | { | 749 | { |
750 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 750 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
751 | int ret; | 751 | int ret; |
752 | 752 | ||
753 | ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid)); | 753 | ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid)); |
@@ -794,7 +794,7 @@ static int is_associated(struct usbnet *usbdev) | |||
794 | 794 | ||
795 | static int disassociate(struct usbnet *usbdev, int reset_ssid) | 795 | static int disassociate(struct usbnet *usbdev, int reset_ssid) |
796 | { | 796 | { |
797 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 797 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
798 | struct ndis_80211_ssid ssid; | 798 | struct ndis_80211_ssid ssid; |
799 | int i, ret = 0; | 799 | int i, ret = 0; |
800 | 800 | ||
@@ -826,7 +826,7 @@ static int disassociate(struct usbnet *usbdev, int reset_ssid) | |||
826 | 826 | ||
827 | static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg) | 827 | static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg) |
828 | { | 828 | { |
829 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 829 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
830 | __le32 tmp; | 830 | __le32 tmp; |
831 | int auth_mode, ret; | 831 | int auth_mode, ret; |
832 | 832 | ||
@@ -835,23 +835,23 @@ static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg) | |||
835 | 835 | ||
836 | if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) { | 836 | if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) { |
837 | if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X) | 837 | if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X) |
838 | auth_mode = ndis_80211_auth_wpa2; | 838 | auth_mode = NDIS_80211_AUTH_WPA2; |
839 | else | 839 | else |
840 | auth_mode = ndis_80211_auth_wpa2_psk; | 840 | auth_mode = NDIS_80211_AUTH_WPA2_PSK; |
841 | } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) { | 841 | } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) { |
842 | if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X) | 842 | if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X) |
843 | auth_mode = ndis_80211_auth_wpa; | 843 | auth_mode = NDIS_80211_AUTH_WPA; |
844 | else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK) | 844 | else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK) |
845 | auth_mode = ndis_80211_auth_wpa_psk; | 845 | auth_mode = NDIS_80211_AUTH_WPA_PSK; |
846 | else | 846 | else |
847 | auth_mode = ndis_80211_auth_wpa_none; | 847 | auth_mode = NDIS_80211_AUTH_WPA_NONE; |
848 | } else if (authalg & IW_AUTH_ALG_SHARED_KEY) { | 848 | } else if (authalg & IW_AUTH_ALG_SHARED_KEY) { |
849 | if (authalg & IW_AUTH_ALG_OPEN_SYSTEM) | 849 | if (authalg & IW_AUTH_ALG_OPEN_SYSTEM) |
850 | auth_mode = ndis_80211_auth_auto_switch; | 850 | auth_mode = NDIS_80211_AUTH_AUTO_SWITCH; |
851 | else | 851 | else |
852 | auth_mode = ndis_80211_auth_shared; | 852 | auth_mode = NDIS_80211_AUTH_SHARED; |
853 | } else | 853 | } else |
854 | auth_mode = ndis_80211_auth_open; | 854 | auth_mode = NDIS_80211_AUTH_OPEN; |
855 | 855 | ||
856 | tmp = cpu_to_le32(auth_mode); | 856 | tmp = cpu_to_le32(auth_mode); |
857 | ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp, | 857 | ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp, |
@@ -869,16 +869,16 @@ static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg) | |||
869 | 869 | ||
870 | static int set_priv_filter(struct usbnet *usbdev) | 870 | static int set_priv_filter(struct usbnet *usbdev) |
871 | { | 871 | { |
872 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 872 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
873 | __le32 tmp; | 873 | __le32 tmp; |
874 | 874 | ||
875 | devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version); | 875 | devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version); |
876 | 876 | ||
877 | if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 || | 877 | if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 || |
878 | priv->wpa_version & IW_AUTH_WPA_VERSION_WPA) | 878 | priv->wpa_version & IW_AUTH_WPA_VERSION_WPA) |
879 | tmp = cpu_to_le32(ndis_80211_priv_8021x_wep); | 879 | tmp = cpu_to_le32(NDIS_80211_PRIV_8021X_WEP); |
880 | else | 880 | else |
881 | tmp = cpu_to_le32(ndis_80211_priv_accept_all); | 881 | tmp = cpu_to_le32(NDIS_80211_PRIV_ACCEPT_ALL); |
882 | 882 | ||
883 | return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp, | 883 | return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp, |
884 | sizeof(tmp)); | 884 | sizeof(tmp)); |
@@ -887,7 +887,7 @@ static int set_priv_filter(struct usbnet *usbdev) | |||
887 | 887 | ||
888 | static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) | 888 | static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) |
889 | { | 889 | { |
890 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 890 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
891 | __le32 tmp; | 891 | __le32 tmp; |
892 | int encr_mode, ret; | 892 | int encr_mode, ret; |
893 | 893 | ||
@@ -896,18 +896,18 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) | |||
896 | groupwise); | 896 | groupwise); |
897 | 897 | ||
898 | if (pairwise & IW_AUTH_CIPHER_CCMP) | 898 | if (pairwise & IW_AUTH_CIPHER_CCMP) |
899 | encr_mode = ndis_80211_encr_ccmp_enabled; | 899 | encr_mode = NDIS_80211_ENCR_CCMP_ENABLED; |
900 | else if (pairwise & IW_AUTH_CIPHER_TKIP) | 900 | else if (pairwise & IW_AUTH_CIPHER_TKIP) |
901 | encr_mode = ndis_80211_encr_tkip_enabled; | 901 | encr_mode = NDIS_80211_ENCR_TKIP_ENABLED; |
902 | else if (pairwise & | 902 | else if (pairwise & |
903 | (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) | 903 | (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) |
904 | encr_mode = ndis_80211_encr_wep_enabled; | 904 | encr_mode = NDIS_80211_ENCR_WEP_ENABLED; |
905 | else if (groupwise & IW_AUTH_CIPHER_CCMP) | 905 | else if (groupwise & IW_AUTH_CIPHER_CCMP) |
906 | encr_mode = ndis_80211_encr_ccmp_enabled; | 906 | encr_mode = NDIS_80211_ENCR_CCMP_ENABLED; |
907 | else if (groupwise & IW_AUTH_CIPHER_TKIP) | 907 | else if (groupwise & IW_AUTH_CIPHER_TKIP) |
908 | encr_mode = ndis_80211_encr_tkip_enabled; | 908 | encr_mode = NDIS_80211_ENCR_TKIP_ENABLED; |
909 | else | 909 | else |
910 | encr_mode = ndis_80211_encr_disabled; | 910 | encr_mode = NDIS_80211_ENCR_DISABLED; |
911 | 911 | ||
912 | tmp = cpu_to_le32(encr_mode); | 912 | tmp = cpu_to_le32(encr_mode); |
913 | ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp, | 913 | ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp, |
@@ -925,7 +925,7 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise) | |||
925 | 925 | ||
926 | static int set_assoc_params(struct usbnet *usbdev) | 926 | static int set_assoc_params(struct usbnet *usbdev) |
927 | { | 927 | { |
928 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 928 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
929 | 929 | ||
930 | set_auth_mode(usbdev, priv->wpa_version, priv->wpa_authalg); | 930 | set_auth_mode(usbdev, priv->wpa_version, priv->wpa_authalg); |
931 | set_priv_filter(usbdev); | 931 | set_priv_filter(usbdev); |
@@ -937,7 +937,7 @@ static int set_assoc_params(struct usbnet *usbdev) | |||
937 | 937 | ||
938 | static int set_infra_mode(struct usbnet *usbdev, int mode) | 938 | static int set_infra_mode(struct usbnet *usbdev, int mode) |
939 | { | 939 | { |
940 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 940 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
941 | __le32 tmp; | 941 | __le32 tmp; |
942 | int ret, i; | 942 | int ret, i; |
943 | 943 | ||
@@ -970,12 +970,12 @@ static int set_infra_mode(struct usbnet *usbdev, int mode) | |||
970 | 970 | ||
971 | static void set_default_iw_params(struct usbnet *usbdev) | 971 | static void set_default_iw_params(struct usbnet *usbdev) |
972 | { | 972 | { |
973 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 973 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
974 | 974 | ||
975 | priv->wpa_keymgmt = 0; | 975 | priv->wpa_keymgmt = 0; |
976 | priv->wpa_version = 0; | 976 | priv->wpa_version = 0; |
977 | 977 | ||
978 | set_infra_mode(usbdev, ndis_80211_infra_infra); | 978 | set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA); |
979 | set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED, | 979 | set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED, |
980 | IW_AUTH_ALG_OPEN_SYSTEM); | 980 | IW_AUTH_ALG_OPEN_SYSTEM); |
981 | set_priv_filter(usbdev); | 981 | set_priv_filter(usbdev); |
@@ -996,7 +996,7 @@ static int deauthenticate(struct usbnet *usbdev) | |||
996 | /* index must be 0 - N, as per NDIS */ | 996 | /* index must be 0 - N, as per NDIS */ |
997 | static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index) | 997 | static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index) |
998 | { | 998 | { |
999 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 999 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1000 | struct ndis_80211_wep_key ndis_key; | 1000 | struct ndis_80211_wep_key ndis_key; |
1001 | int ret; | 1001 | int ret; |
1002 | 1002 | ||
@@ -1011,7 +1011,7 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index) | |||
1011 | memcpy(&ndis_key.material, key, key_len); | 1011 | memcpy(&ndis_key.material, key, key_len); |
1012 | 1012 | ||
1013 | if (index == priv->encr_tx_key_index) { | 1013 | if (index == priv->encr_tx_key_index) { |
1014 | ndis_key.index |= ndis_80211_addwep_transmit_key; | 1014 | ndis_key.index |= NDIS_80211_ADDWEP_TRANSMIT_KEY; |
1015 | ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104, | 1015 | ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104, |
1016 | IW_AUTH_CIPHER_NONE); | 1016 | IW_AUTH_CIPHER_NONE); |
1017 | if (ret) | 1017 | if (ret) |
@@ -1039,7 +1039,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1039 | int index, const struct sockaddr *addr, | 1039 | int index, const struct sockaddr *addr, |
1040 | const u8 *rx_seq, int alg, int flags) | 1040 | const u8 *rx_seq, int alg, int flags) |
1041 | { | 1041 | { |
1042 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1042 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1043 | struct ndis_80211_key ndis_key; | 1043 | struct ndis_80211_key ndis_key; |
1044 | int ret; | 1044 | int ret; |
1045 | 1045 | ||
@@ -1047,15 +1047,15 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1047 | return -EINVAL; | 1047 | return -EINVAL; |
1048 | if (key_len > sizeof(ndis_key.material) || key_len < 0) | 1048 | if (key_len > sizeof(ndis_key.material) || key_len < 0) |
1049 | return -EINVAL; | 1049 | return -EINVAL; |
1050 | if ((flags & ndis_80211_addkey_set_init_recv_seq) && !rx_seq) | 1050 | if ((flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) && !rx_seq) |
1051 | return -EINVAL; | 1051 | return -EINVAL; |
1052 | if ((flags & ndis_80211_addkey_pairwise_key) && !addr) | 1052 | if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !addr) |
1053 | return -EINVAL; | 1053 | return -EINVAL; |
1054 | 1054 | ||
1055 | devdbg(usbdev, "add_wpa_key(%i): flags:%i%i%i", index, | 1055 | devdbg(usbdev, "add_wpa_key(%i): flags:%i%i%i", index, |
1056 | !!(flags & ndis_80211_addkey_transmit_key), | 1056 | !!(flags & NDIS_80211_ADDKEY_TRANSMIT_KEY), |
1057 | !!(flags & ndis_80211_addkey_pairwise_key), | 1057 | !!(flags & NDIS_80211_ADDKEY_PAIRWISE_KEY), |
1058 | !!(flags & ndis_80211_addkey_set_init_recv_seq)); | 1058 | !!(flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ)); |
1059 | 1059 | ||
1060 | memset(&ndis_key, 0, sizeof(ndis_key)); | 1060 | memset(&ndis_key, 0, sizeof(ndis_key)); |
1061 | 1061 | ||
@@ -1073,15 +1073,15 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1073 | } else | 1073 | } else |
1074 | memcpy(ndis_key.material, key, key_len); | 1074 | memcpy(ndis_key.material, key, key_len); |
1075 | 1075 | ||
1076 | if (flags & ndis_80211_addkey_set_init_recv_seq) | 1076 | if (flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) |
1077 | memcpy(ndis_key.rsc, rx_seq, 6); | 1077 | memcpy(ndis_key.rsc, rx_seq, 6); |
1078 | 1078 | ||
1079 | if (flags & ndis_80211_addkey_pairwise_key) { | 1079 | if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) { |
1080 | /* pairwise key */ | 1080 | /* pairwise key */ |
1081 | memcpy(ndis_key.bssid, addr->sa_data, ETH_ALEN); | 1081 | memcpy(ndis_key.bssid, addr->sa_data, ETH_ALEN); |
1082 | } else { | 1082 | } else { |
1083 | /* group key */ | 1083 | /* group key */ |
1084 | if (priv->infra_mode == ndis_80211_infra_adhoc) | 1084 | if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) |
1085 | memset(ndis_key.bssid, 0xff, ETH_ALEN); | 1085 | memset(ndis_key.bssid, 0xff, ETH_ALEN); |
1086 | else | 1086 | else |
1087 | get_bssid(usbdev, ndis_key.bssid); | 1087 | get_bssid(usbdev, ndis_key.bssid); |
@@ -1096,7 +1096,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1096 | priv->encr_key_len[index] = key_len; | 1096 | priv->encr_key_len[index] = key_len; |
1097 | priv->encr_key_wpa[index] = 1; | 1097 | priv->encr_key_wpa[index] = 1; |
1098 | 1098 | ||
1099 | if (flags & ndis_80211_addkey_transmit_key) | 1099 | if (flags & NDIS_80211_ADDKEY_TRANSMIT_KEY) |
1100 | priv->encr_tx_key_index = index; | 1100 | priv->encr_tx_key_index = index; |
1101 | 1101 | ||
1102 | return 0; | 1102 | return 0; |
@@ -1106,7 +1106,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | |||
1106 | /* remove_key is for both wep and wpa */ | 1106 | /* remove_key is for both wep and wpa */ |
1107 | static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) | 1107 | static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) |
1108 | { | 1108 | { |
1109 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1109 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1110 | struct ndis_80211_remove_key remove_key; | 1110 | struct ndis_80211_remove_key remove_key; |
1111 | __le32 keyindex; | 1111 | __le32 keyindex; |
1112 | int ret; | 1112 | int ret; |
@@ -1128,7 +1128,7 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) | |||
1128 | /* pairwise key */ | 1128 | /* pairwise key */ |
1129 | if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0) | 1129 | if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0) |
1130 | remove_key.index |= | 1130 | remove_key.index |= |
1131 | ndis_80211_addkey_pairwise_key; | 1131 | NDIS_80211_ADDKEY_PAIRWISE_KEY; |
1132 | memcpy(remove_key.bssid, bssid, | 1132 | memcpy(remove_key.bssid, bssid, |
1133 | sizeof(remove_key.bssid)); | 1133 | sizeof(remove_key.bssid)); |
1134 | } else | 1134 | } else |
@@ -1161,7 +1161,7 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) | |||
1161 | 1161 | ||
1162 | static void set_multicast_list(struct usbnet *usbdev) | 1162 | static void set_multicast_list(struct usbnet *usbdev) |
1163 | { | 1163 | { |
1164 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1164 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1165 | struct dev_mc_list *mclist; | 1165 | struct dev_mc_list *mclist; |
1166 | __le32 filter; | 1166 | __le32 filter; |
1167 | int ret, i, size; | 1167 | int ret, i, size; |
@@ -1238,10 +1238,10 @@ static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex, | |||
1238 | 1238 | ||
1239 | switch (type) { | 1239 | switch (type) { |
1240 | case NL80211_IFTYPE_ADHOC: | 1240 | case NL80211_IFTYPE_ADHOC: |
1241 | mode = ndis_80211_infra_adhoc; | 1241 | mode = NDIS_80211_INFRA_ADHOC; |
1242 | break; | 1242 | break; |
1243 | case NL80211_IFTYPE_STATION: | 1243 | case NL80211_IFTYPE_STATION: |
1244 | mode = ndis_80211_infra_infra; | 1244 | mode = NDIS_80211_INFRA_INFRA; |
1245 | break; | 1245 | break; |
1246 | default: | 1246 | default: |
1247 | return -EINVAL; | 1247 | return -EINVAL; |
@@ -1256,7 +1256,7 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, | |||
1256 | struct cfg80211_scan_request *request) | 1256 | struct cfg80211_scan_request *request) |
1257 | { | 1257 | { |
1258 | struct usbnet *usbdev = netdev_priv(dev); | 1258 | struct usbnet *usbdev = netdev_priv(dev); |
1259 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1259 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1260 | int ret; | 1260 | int ret; |
1261 | __le32 tmp; | 1261 | __le32 tmp; |
1262 | 1262 | ||
@@ -1286,7 +1286,7 @@ static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, | |||
1286 | static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev, | 1286 | static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev, |
1287 | struct ndis_80211_bssid_ex *bssid) | 1287 | struct ndis_80211_bssid_ex *bssid) |
1288 | { | 1288 | { |
1289 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1289 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1290 | struct ieee80211_channel *channel; | 1290 | struct ieee80211_channel *channel; |
1291 | s32 signal; | 1291 | s32 signal; |
1292 | u64 timestamp; | 1292 | u64 timestamp; |
@@ -1371,8 +1371,8 @@ out: | |||
1371 | 1371 | ||
1372 | static void rndis_get_scan_results(struct work_struct *work) | 1372 | static void rndis_get_scan_results(struct work_struct *work) |
1373 | { | 1373 | { |
1374 | struct rndis_wext_private *priv = | 1374 | struct rndis_wlan_private *priv = |
1375 | container_of(work, struct rndis_wext_private, scan_work.work); | 1375 | container_of(work, struct rndis_wlan_private, scan_work.work); |
1376 | struct usbnet *usbdev = priv->usbdev; | 1376 | struct usbnet *usbdev = priv->usbdev; |
1377 | int ret; | 1377 | int ret; |
1378 | 1378 | ||
@@ -1497,7 +1497,7 @@ static int rndis_iw_set_auth(struct net_device *dev, | |||
1497 | { | 1497 | { |
1498 | struct iw_param *p = &wrqu->param; | 1498 | struct iw_param *p = &wrqu->param; |
1499 | struct usbnet *usbdev = netdev_priv(dev); | 1499 | struct usbnet *usbdev = netdev_priv(dev); |
1500 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1500 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1501 | int ret = -ENOTSUPP; | 1501 | int ret = -ENOTSUPP; |
1502 | 1502 | ||
1503 | switch (p->flags & IW_AUTH_INDEX) { | 1503 | switch (p->flags & IW_AUTH_INDEX) { |
@@ -1578,7 +1578,7 @@ static int rndis_iw_get_auth(struct net_device *dev, | |||
1578 | { | 1578 | { |
1579 | struct iw_param *p = &wrqu->param; | 1579 | struct iw_param *p = &wrqu->param; |
1580 | struct usbnet *usbdev = netdev_priv(dev); | 1580 | struct usbnet *usbdev = netdev_priv(dev); |
1581 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1581 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1582 | 1582 | ||
1583 | switch (p->flags & IW_AUTH_INDEX) { | 1583 | switch (p->flags & IW_AUTH_INDEX) { |
1584 | case IW_AUTH_WPA_VERSION: | 1584 | case IW_AUTH_WPA_VERSION: |
@@ -1609,7 +1609,7 @@ static int rndis_iw_set_encode(struct net_device *dev, | |||
1609 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) | 1609 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) |
1610 | { | 1610 | { |
1611 | struct usbnet *usbdev = netdev_priv(dev); | 1611 | struct usbnet *usbdev = netdev_priv(dev); |
1612 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1612 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1613 | int ret, index, key_len; | 1613 | int ret, index, key_len; |
1614 | u8 *key; | 1614 | u8 *key; |
1615 | 1615 | ||
@@ -1672,7 +1672,7 @@ static int rndis_iw_set_encode_ext(struct net_device *dev, | |||
1672 | { | 1672 | { |
1673 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; | 1673 | struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; |
1674 | struct usbnet *usbdev = netdev_priv(dev); | 1674 | struct usbnet *usbdev = netdev_priv(dev); |
1675 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1675 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1676 | int keyidx, flags; | 1676 | int keyidx, flags; |
1677 | 1677 | ||
1678 | keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX; | 1678 | keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX; |
@@ -1698,11 +1698,11 @@ static int rndis_iw_set_encode_ext(struct net_device *dev, | |||
1698 | 1698 | ||
1699 | flags = 0; | 1699 | flags = 0; |
1700 | if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) | 1700 | if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) |
1701 | flags |= ndis_80211_addkey_set_init_recv_seq; | 1701 | flags |= NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ; |
1702 | if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)) | 1702 | if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)) |
1703 | flags |= ndis_80211_addkey_pairwise_key; | 1703 | flags |= NDIS_80211_ADDKEY_PAIRWISE_KEY; |
1704 | if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) | 1704 | if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) |
1705 | flags |= ndis_80211_addkey_transmit_key; | 1705 | flags |= NDIS_80211_ADDKEY_TRANSMIT_KEY; |
1706 | 1706 | ||
1707 | return add_wpa_key(usbdev, ext->key, ext->key_len, keyidx, &ext->addr, | 1707 | return add_wpa_key(usbdev, ext->key, ext->key_len, keyidx, &ext->addr, |
1708 | ext->rx_seq, ext->alg, flags); | 1708 | ext->rx_seq, ext->alg, flags); |
@@ -1713,7 +1713,7 @@ static int rndis_iw_set_genie(struct net_device *dev, | |||
1713 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) | 1713 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) |
1714 | { | 1714 | { |
1715 | struct usbnet *usbdev = netdev_priv(dev); | 1715 | struct usbnet *usbdev = netdev_priv(dev); |
1716 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1716 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1717 | int ret = 0; | 1717 | int ret = 0; |
1718 | 1718 | ||
1719 | #ifdef DEBUG | 1719 | #ifdef DEBUG |
@@ -1747,7 +1747,7 @@ static int rndis_iw_get_genie(struct net_device *dev, | |||
1747 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) | 1747 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) |
1748 | { | 1748 | { |
1749 | struct usbnet *usbdev = netdev_priv(dev); | 1749 | struct usbnet *usbdev = netdev_priv(dev); |
1750 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1750 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1751 | 1751 | ||
1752 | devdbg(usbdev, "SIOCGIWGENIE"); | 1752 | devdbg(usbdev, "SIOCGIWGENIE"); |
1753 | 1753 | ||
@@ -1886,7 +1886,7 @@ static int rndis_iw_get_txpower(struct net_device *dev, | |||
1886 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) | 1886 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) |
1887 | { | 1887 | { |
1888 | struct usbnet *usbdev = netdev_priv(dev); | 1888 | struct usbnet *usbdev = netdev_priv(dev); |
1889 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1889 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1890 | __le32 tx_power; | 1890 | __le32 tx_power; |
1891 | 1891 | ||
1892 | if (priv->radio_on) { | 1892 | if (priv->radio_on) { |
@@ -1912,7 +1912,7 @@ static int rndis_iw_set_txpower(struct net_device *dev, | |||
1912 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) | 1912 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) |
1913 | { | 1913 | { |
1914 | struct usbnet *usbdev = netdev_priv(dev); | 1914 | struct usbnet *usbdev = netdev_priv(dev); |
1915 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1915 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1916 | __le32 tx_power = 0; | 1916 | __le32 tx_power = 0; |
1917 | 1917 | ||
1918 | if (!wrqu->txpower.disabled) { | 1918 | if (!wrqu->txpower.disabled) { |
@@ -1969,7 +1969,7 @@ static int rndis_iw_set_mlme(struct net_device *dev, | |||
1969 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) | 1969 | struct iw_request_info *info, union iwreq_data *wrqu, char *extra) |
1970 | { | 1970 | { |
1971 | struct usbnet *usbdev = netdev_priv(dev); | 1971 | struct usbnet *usbdev = netdev_priv(dev); |
1972 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1972 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1973 | struct iw_mlme *mlme = (struct iw_mlme *)extra; | 1973 | struct iw_mlme *mlme = (struct iw_mlme *)extra; |
1974 | unsigned char bssid[ETH_ALEN]; | 1974 | unsigned char bssid[ETH_ALEN]; |
1975 | 1975 | ||
@@ -1994,7 +1994,7 @@ static int rndis_iw_set_mlme(struct net_device *dev, | |||
1994 | static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev) | 1994 | static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev) |
1995 | { | 1995 | { |
1996 | struct usbnet *usbdev = netdev_priv(dev); | 1996 | struct usbnet *usbdev = netdev_priv(dev); |
1997 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 1997 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1998 | unsigned long flags; | 1998 | unsigned long flags; |
1999 | 1999 | ||
2000 | spin_lock_irqsave(&priv->stats_lock, flags); | 2000 | spin_lock_irqsave(&priv->stats_lock, flags); |
@@ -2037,28 +2037,28 @@ static const iw_handler rndis_iw_handler[] = | |||
2037 | IW_IOCTL(SIOCSIWMLME) = rndis_iw_set_mlme, | 2037 | IW_IOCTL(SIOCSIWMLME) = rndis_iw_set_mlme, |
2038 | }; | 2038 | }; |
2039 | 2039 | ||
2040 | static const iw_handler rndis_wext_private_handler[] = { | 2040 | static const iw_handler rndis_wlan_private_handler[] = { |
2041 | }; | 2041 | }; |
2042 | 2042 | ||
2043 | static const struct iw_priv_args rndis_wext_private_args[] = { | 2043 | static const struct iw_priv_args rndis_wlan_private_args[] = { |
2044 | }; | 2044 | }; |
2045 | 2045 | ||
2046 | 2046 | ||
2047 | static const struct iw_handler_def rndis_iw_handlers = { | 2047 | static const struct iw_handler_def rndis_iw_handlers = { |
2048 | .num_standard = ARRAY_SIZE(rndis_iw_handler), | 2048 | .num_standard = ARRAY_SIZE(rndis_iw_handler), |
2049 | .num_private = ARRAY_SIZE(rndis_wext_private_handler), | 2049 | .num_private = ARRAY_SIZE(rndis_wlan_private_handler), |
2050 | .num_private_args = ARRAY_SIZE(rndis_wext_private_args), | 2050 | .num_private_args = ARRAY_SIZE(rndis_wlan_private_args), |
2051 | .standard = (iw_handler *)rndis_iw_handler, | 2051 | .standard = (iw_handler *)rndis_iw_handler, |
2052 | .private = (iw_handler *)rndis_wext_private_handler, | 2052 | .private = (iw_handler *)rndis_wlan_private_handler, |
2053 | .private_args = (struct iw_priv_args *)rndis_wext_private_args, | 2053 | .private_args = (struct iw_priv_args *)rndis_wlan_private_args, |
2054 | .get_wireless_stats = rndis_get_wireless_stats, | 2054 | .get_wireless_stats = rndis_get_wireless_stats, |
2055 | }; | 2055 | }; |
2056 | 2056 | ||
2057 | 2057 | ||
2058 | static void rndis_wext_worker(struct work_struct *work) | 2058 | static void rndis_wlan_worker(struct work_struct *work) |
2059 | { | 2059 | { |
2060 | struct rndis_wext_private *priv = | 2060 | struct rndis_wlan_private *priv = |
2061 | container_of(work, struct rndis_wext_private, work); | 2061 | container_of(work, struct rndis_wlan_private, work); |
2062 | struct usbnet *usbdev = priv->usbdev; | 2062 | struct usbnet *usbdev = priv->usbdev; |
2063 | union iwreq_data evt; | 2063 | union iwreq_data evt; |
2064 | unsigned char bssid[ETH_ALEN]; | 2064 | unsigned char bssid[ETH_ALEN]; |
@@ -2119,10 +2119,10 @@ get_bssid: | |||
2119 | set_multicast_list(usbdev); | 2119 | set_multicast_list(usbdev); |
2120 | } | 2120 | } |
2121 | 2121 | ||
2122 | static void rndis_wext_set_multicast_list(struct net_device *dev) | 2122 | static void rndis_wlan_set_multicast_list(struct net_device *dev) |
2123 | { | 2123 | { |
2124 | struct usbnet *usbdev = netdev_priv(dev); | 2124 | struct usbnet *usbdev = netdev_priv(dev); |
2125 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 2125 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
2126 | 2126 | ||
2127 | if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending)) | 2127 | if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending)) |
2128 | return; | 2128 | return; |
@@ -2131,9 +2131,9 @@ static void rndis_wext_set_multicast_list(struct net_device *dev) | |||
2131 | queue_work(priv->workqueue, &priv->work); | 2131 | queue_work(priv->workqueue, &priv->work); |
2132 | } | 2132 | } |
2133 | 2133 | ||
2134 | static void rndis_wext_link_change(struct usbnet *usbdev, int state) | 2134 | static void rndis_wlan_link_change(struct usbnet *usbdev, int state) |
2135 | { | 2135 | { |
2136 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 2136 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
2137 | 2137 | ||
2138 | /* queue work to avoid recursive calls into rndis_command */ | 2138 | /* queue work to avoid recursive calls into rndis_command */ |
2139 | set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending); | 2139 | set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending); |
@@ -2141,14 +2141,14 @@ static void rndis_wext_link_change(struct usbnet *usbdev, int state) | |||
2141 | } | 2141 | } |
2142 | 2142 | ||
2143 | 2143 | ||
2144 | static int rndis_wext_get_caps(struct usbnet *usbdev) | 2144 | static int rndis_wlan_get_caps(struct usbnet *usbdev) |
2145 | { | 2145 | { |
2146 | struct { | 2146 | struct { |
2147 | __le32 num_items; | 2147 | __le32 num_items; |
2148 | __le32 items[8]; | 2148 | __le32 items[8]; |
2149 | } networks_supported; | 2149 | } networks_supported; |
2150 | int len, retval, i, n; | 2150 | int len, retval, i, n; |
2151 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 2151 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
2152 | 2152 | ||
2153 | /* determine supported modes */ | 2153 | /* determine supported modes */ |
2154 | len = sizeof(networks_supported); | 2154 | len = sizeof(networks_supported); |
@@ -2160,14 +2160,14 @@ static int rndis_wext_get_caps(struct usbnet *usbdev) | |||
2160 | n = 8; | 2160 | n = 8; |
2161 | for (i = 0; i < n; i++) { | 2161 | for (i = 0; i < n; i++) { |
2162 | switch (le32_to_cpu(networks_supported.items[i])) { | 2162 | switch (le32_to_cpu(networks_supported.items[i])) { |
2163 | case ndis_80211_type_freq_hop: | 2163 | case NDIS_80211_TYPE_FREQ_HOP: |
2164 | case ndis_80211_type_direct_seq: | 2164 | case NDIS_80211_TYPE_DIRECT_SEQ: |
2165 | priv->caps |= CAP_MODE_80211B; | 2165 | priv->caps |= CAP_MODE_80211B; |
2166 | break; | 2166 | break; |
2167 | case ndis_80211_type_ofdm_a: | 2167 | case NDIS_80211_TYPE_OFDM_A: |
2168 | priv->caps |= CAP_MODE_80211A; | 2168 | priv->caps |= CAP_MODE_80211A; |
2169 | break; | 2169 | break; |
2170 | case ndis_80211_type_ofdm_g: | 2170 | case NDIS_80211_TYPE_OFDM_G: |
2171 | priv->caps |= CAP_MODE_80211G; | 2171 | priv->caps |= CAP_MODE_80211G; |
2172 | break; | 2172 | break; |
2173 | } | 2173 | } |
@@ -2181,8 +2181,8 @@ static int rndis_wext_get_caps(struct usbnet *usbdev) | |||
2181 | #define STATS_UPDATE_JIFFIES (HZ) | 2181 | #define STATS_UPDATE_JIFFIES (HZ) |
2182 | static void rndis_update_wireless_stats(struct work_struct *work) | 2182 | static void rndis_update_wireless_stats(struct work_struct *work) |
2183 | { | 2183 | { |
2184 | struct rndis_wext_private *priv = | 2184 | struct rndis_wlan_private *priv = |
2185 | container_of(work, struct rndis_wext_private, stats_work.work); | 2185 | container_of(work, struct rndis_wlan_private, stats_work.work); |
2186 | struct usbnet *usbdev = priv->usbdev; | 2186 | struct usbnet *usbdev = priv->usbdev; |
2187 | struct iw_statistics iwstats; | 2187 | struct iw_statistics iwstats; |
2188 | __le32 rssi, tmp; | 2188 | __le32 rssi, tmp; |
@@ -2297,7 +2297,7 @@ static int bcm4320a_early_init(struct usbnet *usbdev) | |||
2297 | 2297 | ||
2298 | static int bcm4320b_early_init(struct usbnet *usbdev) | 2298 | static int bcm4320b_early_init(struct usbnet *usbdev) |
2299 | { | 2299 | { |
2300 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 2300 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
2301 | char buf[8]; | 2301 | char buf[8]; |
2302 | 2302 | ||
2303 | /* Early initialization settings, setting these won't have effect | 2303 | /* Early initialization settings, setting these won't have effect |
@@ -2363,21 +2363,21 @@ static int bcm4320b_early_init(struct usbnet *usbdev) | |||
2363 | } | 2363 | } |
2364 | 2364 | ||
2365 | /* same as rndis_netdev_ops but with local multicast handler */ | 2365 | /* same as rndis_netdev_ops but with local multicast handler */ |
2366 | static const struct net_device_ops rndis_wext_netdev_ops = { | 2366 | static const struct net_device_ops rndis_wlan_netdev_ops = { |
2367 | .ndo_open = usbnet_open, | 2367 | .ndo_open = usbnet_open, |
2368 | .ndo_stop = usbnet_stop, | 2368 | .ndo_stop = usbnet_stop, |
2369 | .ndo_start_xmit = usbnet_start_xmit, | 2369 | .ndo_start_xmit = usbnet_start_xmit, |
2370 | .ndo_tx_timeout = usbnet_tx_timeout, | 2370 | .ndo_tx_timeout = usbnet_tx_timeout, |
2371 | .ndo_set_mac_address = eth_mac_addr, | 2371 | .ndo_set_mac_address = eth_mac_addr, |
2372 | .ndo_validate_addr = eth_validate_addr, | 2372 | .ndo_validate_addr = eth_validate_addr, |
2373 | .ndo_set_multicast_list = rndis_wext_set_multicast_list, | 2373 | .ndo_set_multicast_list = rndis_wlan_set_multicast_list, |
2374 | }; | 2374 | }; |
2375 | 2375 | ||
2376 | 2376 | ||
2377 | static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) | 2377 | static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf) |
2378 | { | 2378 | { |
2379 | struct wiphy *wiphy; | 2379 | struct wiphy *wiphy; |
2380 | struct rndis_wext_private *priv; | 2380 | struct rndis_wlan_private *priv; |
2381 | int retval, len; | 2381 | int retval, len; |
2382 | __le32 tmp; | 2382 | __le32 tmp; |
2383 | 2383 | ||
@@ -2385,7 +2385,7 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2385 | * NOTE: We only support a single virtual interface, so wiphy | 2385 | * NOTE: We only support a single virtual interface, so wiphy |
2386 | * and wireless_dev are somewhat synonymous for this device. | 2386 | * and wireless_dev are somewhat synonymous for this device. |
2387 | */ | 2387 | */ |
2388 | wiphy = wiphy_new(&rndis_config_ops, sizeof(struct rndis_wext_private)); | 2388 | wiphy = wiphy_new(&rndis_config_ops, sizeof(struct rndis_wlan_private)); |
2389 | if (!wiphy) | 2389 | if (!wiphy) |
2390 | return -ENOMEM; | 2390 | return -ENOMEM; |
2391 | 2391 | ||
@@ -2395,7 +2395,7 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2395 | priv->wdev.iftype = NL80211_IFTYPE_STATION; | 2395 | priv->wdev.iftype = NL80211_IFTYPE_STATION; |
2396 | 2396 | ||
2397 | /* These have to be initialized before calling generic_rndis_bind(). | 2397 | /* These have to be initialized before calling generic_rndis_bind(). |
2398 | * Otherwise we'll be in big trouble in rndis_wext_early_init(). | 2398 | * Otherwise we'll be in big trouble in rndis_wlan_early_init(). |
2399 | */ | 2399 | */ |
2400 | usbdev->driver_priv = priv; | 2400 | usbdev->driver_priv = priv; |
2401 | usbdev->net->wireless_handlers = &rndis_iw_handlers; | 2401 | usbdev->net->wireless_handlers = &rndis_iw_handlers; |
@@ -2406,7 +2406,7 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2406 | 2406 | ||
2407 | /* because rndis_command() sleeps we need to use workqueue */ | 2407 | /* because rndis_command() sleeps we need to use workqueue */ |
2408 | priv->workqueue = create_singlethread_workqueue("rndis_wlan"); | 2408 | priv->workqueue = create_singlethread_workqueue("rndis_wlan"); |
2409 | INIT_WORK(&priv->work, rndis_wext_worker); | 2409 | INIT_WORK(&priv->work, rndis_wlan_worker); |
2410 | INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats); | 2410 | INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats); |
2411 | INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results); | 2411 | INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results); |
2412 | 2412 | ||
@@ -2420,9 +2420,9 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2420 | * picks up rssi to closest station instead of to access point). | 2420 | * picks up rssi to closest station instead of to access point). |
2421 | * | 2421 | * |
2422 | * rndis_host wants to avoid all OID as much as possible | 2422 | * rndis_host wants to avoid all OID as much as possible |
2423 | * so do promisc/multicast handling in rndis_wext. | 2423 | * so do promisc/multicast handling in rndis_wlan. |
2424 | */ | 2424 | */ |
2425 | usbdev->net->netdev_ops = &rndis_wext_netdev_ops; | 2425 | usbdev->net->netdev_ops = &rndis_wlan_netdev_ops; |
2426 | 2426 | ||
2427 | tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; | 2427 | tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; |
2428 | retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp, | 2428 | retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp, |
@@ -2455,7 +2455,7 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2455 | wiphy->max_scan_ssids = 1; | 2455 | wiphy->max_scan_ssids = 1; |
2456 | 2456 | ||
2457 | /* TODO: fill-out band information based on priv->caps */ | 2457 | /* TODO: fill-out band information based on priv->caps */ |
2458 | rndis_wext_get_caps(usbdev); | 2458 | rndis_wlan_get_caps(usbdev); |
2459 | 2459 | ||
2460 | memcpy(priv->channels, rndis_channels, sizeof(rndis_channels)); | 2460 | memcpy(priv->channels, rndis_channels, sizeof(rndis_channels)); |
2461 | memcpy(priv->rates, rndis_rates, sizeof(rndis_rates)); | 2461 | memcpy(priv->rates, rndis_rates, sizeof(rndis_rates)); |
@@ -2497,9 +2497,9 @@ fail: | |||
2497 | } | 2497 | } |
2498 | 2498 | ||
2499 | 2499 | ||
2500 | static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf) | 2500 | static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf) |
2501 | { | 2501 | { |
2502 | struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); | 2502 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
2503 | 2503 | ||
2504 | /* turn radio off */ | 2504 | /* turn radio off */ |
2505 | disassociate(usbdev, 0); | 2505 | disassociate(usbdev, 0); |
@@ -2520,7 +2520,7 @@ static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2520 | } | 2520 | } |
2521 | 2521 | ||
2522 | 2522 | ||
2523 | static int rndis_wext_reset(struct usbnet *usbdev) | 2523 | static int rndis_wlan_reset(struct usbnet *usbdev) |
2524 | { | 2524 | { |
2525 | return deauthenticate(usbdev); | 2525 | return deauthenticate(usbdev); |
2526 | } | 2526 | } |
@@ -2529,40 +2529,40 @@ static int rndis_wext_reset(struct usbnet *usbdev) | |||
2529 | static const struct driver_info bcm4320b_info = { | 2529 | static const struct driver_info bcm4320b_info = { |
2530 | .description = "Wireless RNDIS device, BCM4320b based", | 2530 | .description = "Wireless RNDIS device, BCM4320b based", |
2531 | .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, | 2531 | .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, |
2532 | .bind = rndis_wext_bind, | 2532 | .bind = rndis_wlan_bind, |
2533 | .unbind = rndis_wext_unbind, | 2533 | .unbind = rndis_wlan_unbind, |
2534 | .status = rndis_status, | 2534 | .status = rndis_status, |
2535 | .rx_fixup = rndis_rx_fixup, | 2535 | .rx_fixup = rndis_rx_fixup, |
2536 | .tx_fixup = rndis_tx_fixup, | 2536 | .tx_fixup = rndis_tx_fixup, |
2537 | .reset = rndis_wext_reset, | 2537 | .reset = rndis_wlan_reset, |
2538 | .early_init = bcm4320b_early_init, | 2538 | .early_init = bcm4320b_early_init, |
2539 | .link_change = rndis_wext_link_change, | 2539 | .link_change = rndis_wlan_link_change, |
2540 | }; | 2540 | }; |
2541 | 2541 | ||
2542 | static const struct driver_info bcm4320a_info = { | 2542 | static const struct driver_info bcm4320a_info = { |
2543 | .description = "Wireless RNDIS device, BCM4320a based", | 2543 | .description = "Wireless RNDIS device, BCM4320a based", |
2544 | .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, | 2544 | .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, |
2545 | .bind = rndis_wext_bind, | 2545 | .bind = rndis_wlan_bind, |
2546 | .unbind = rndis_wext_unbind, | 2546 | .unbind = rndis_wlan_unbind, |
2547 | .status = rndis_status, | 2547 | .status = rndis_status, |
2548 | .rx_fixup = rndis_rx_fixup, | 2548 | .rx_fixup = rndis_rx_fixup, |
2549 | .tx_fixup = rndis_tx_fixup, | 2549 | .tx_fixup = rndis_tx_fixup, |
2550 | .reset = rndis_wext_reset, | 2550 | .reset = rndis_wlan_reset, |
2551 | .early_init = bcm4320a_early_init, | 2551 | .early_init = bcm4320a_early_init, |
2552 | .link_change = rndis_wext_link_change, | 2552 | .link_change = rndis_wlan_link_change, |
2553 | }; | 2553 | }; |
2554 | 2554 | ||
2555 | static const struct driver_info rndis_wext_info = { | 2555 | static const struct driver_info rndis_wlan_info = { |
2556 | .description = "Wireless RNDIS device", | 2556 | .description = "Wireless RNDIS device", |
2557 | .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, | 2557 | .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, |
2558 | .bind = rndis_wext_bind, | 2558 | .bind = rndis_wlan_bind, |
2559 | .unbind = rndis_wext_unbind, | 2559 | .unbind = rndis_wlan_unbind, |
2560 | .status = rndis_status, | 2560 | .status = rndis_status, |
2561 | .rx_fixup = rndis_rx_fixup, | 2561 | .rx_fixup = rndis_rx_fixup, |
2562 | .tx_fixup = rndis_tx_fixup, | 2562 | .tx_fixup = rndis_tx_fixup, |
2563 | .reset = rndis_wext_reset, | 2563 | .reset = rndis_wlan_reset, |
2564 | .early_init = bcm4320a_early_init, | 2564 | .early_init = bcm4320a_early_init, |
2565 | .link_change = rndis_wext_link_change, | 2565 | .link_change = rndis_wlan_link_change, |
2566 | }; | 2566 | }; |
2567 | 2567 | ||
2568 | /*-------------------------------------------------------------------------*/ | 2568 | /*-------------------------------------------------------------------------*/ |
@@ -2672,11 +2672,11 @@ static const struct usb_device_id products [] = { | |||
2672 | { | 2672 | { |
2673 | /* RNDIS is MSFT's un-official variant of CDC ACM */ | 2673 | /* RNDIS is MSFT's un-official variant of CDC ACM */ |
2674 | USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), | 2674 | USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), |
2675 | .driver_info = (unsigned long) &rndis_wext_info, | 2675 | .driver_info = (unsigned long) &rndis_wlan_info, |
2676 | }, { | 2676 | }, { |
2677 | /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */ | 2677 | /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */ |
2678 | USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1), | 2678 | USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1), |
2679 | .driver_info = (unsigned long) &rndis_wext_info, | 2679 | .driver_info = (unsigned long) &rndis_wlan_info, |
2680 | }, | 2680 | }, |
2681 | { }, // END | 2681 | { }, // END |
2682 | }; | 2682 | }; |
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, ®); | 521 | rt2x00pci_register_read(rt2x00dev, CSR20, ®); |
522 | rt2x00_set_field32(®, CSR20_DELAY_AFTER_TBCN, | 522 | rt2x00_set_field32(®, CSR20_DELAY_AFTER_TBCN, |
523 | (libconf->conf->beacon_int - 20) * 16); | 523 | (rt2x00dev->beacon_int - 20) * 16); |
524 | rt2x00_set_field32(®, CSR20_TBCN_BEFORE_WAKEUP, | 524 | rt2x00_set_field32(®, 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, ®); | 570 | rt2x00pci_register_read(rt2x00dev, CSR20, ®); |
571 | rt2x00_set_field32(®, CSR20_DELAY_AFTER_TBCN, | 571 | rt2x00_set_field32(®, CSR20_DELAY_AFTER_TBCN, |
572 | (libconf->conf->beacon_int - 20) * 16); | 572 | (rt2x00dev->beacon_int - 20) * 16); |
573 | rt2x00_set_field32(®, CSR20_TBCN_BEFORE_WAKEUP, | 573 | rt2x00_set_field32(®, 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, ®); | 648 | rt2500usb_register_read(rt2x00dev, MAC_CSR18, ®); |
649 | rt2x00_set_field16(®, MAC_CSR18_DELAY_AFTER_BEACON, | 649 | rt2x00_set_field16(®, MAC_CSR18_DELAY_AFTER_BEACON, |
650 | libconf->conf->beacon_int - 20); | 650 | rt2x00dev->beacon_int - 20); |
651 | rt2x00_set_field16(®, MAC_CSR18_BEACONS_BEFORE_WAKEUP, | 651 | rt2x00_set_field16(®, 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, ®); | 957 | rt2x00pci_register_read(rt2x00dev, MAC_CSR11, ®); |
958 | rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, | 958 | rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, |
959 | libconf->conf->beacon_int - 10); | 959 | rt2x00dev->beacon_int - 10); |
960 | rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, | 960 | rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, |
961 | libconf->conf->listen_interval - 1); | 961 | libconf->conf->listen_interval - 1); |
962 | rt2x00_set_field32(®, MAC_CSR11_WAKEUP_LATENCY, 5); | 962 | rt2x00_set_field32(®, 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, ®); | 853 | rt2x00usb_register_read(rt2x00dev, MAC_CSR11, ®); |
854 | rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, | 854 | rt2x00_set_field32(®, MAC_CSR11_DELAY_AFTER_TBCN, |
855 | libconf->conf->beacon_int - 10); | 855 | rt2x00dev->beacon_int - 10); |
856 | rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, | 856 | rt2x00_set_field32(®, MAC_CSR11_TBCN_BEFORE_WAKEUP, |
857 | libconf->conf->listen_interval - 1); | 857 | libconf->conf->listen_interval - 1); |
858 | rt2x00_set_field32(®, MAC_CSR11_WAKEUP_LATENCY, 5); | 858 | rt2x00_set_field32(®, MAC_CSR11_WAKEUP_LATENCY, 5); |
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 6499ccc34c94..294250e294dd 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c | |||
@@ -74,6 +74,8 @@ static struct usb_device_id rtl8187_table[] __devinitdata = { | |||
74 | {USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187}, | 74 | {USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187}, |
75 | /* AirLive */ | 75 | /* AirLive */ |
76 | {USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187}, | 76 | {USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187}, |
77 | /* Linksys */ | ||
78 | {USB_DEVICE(0x1737, 0x0073), .driver_info = DEVICE_RTL8187B}, | ||
77 | {} | 79 | {} |
78 | }; | 80 | }; |
79 | 81 | ||
@@ -321,12 +323,7 @@ static void rtl8187_rx_cb(struct urb *urb) | |||
321 | unsigned long f; | 323 | unsigned long f; |
322 | 324 | ||
323 | spin_lock_irqsave(&priv->rx_queue.lock, f); | 325 | spin_lock_irqsave(&priv->rx_queue.lock, f); |
324 | if (skb->next) | 326 | __skb_unlink(skb, &priv->rx_queue); |
325 | __skb_unlink(skb, &priv->rx_queue); | ||
326 | else { | ||
327 | spin_unlock_irqrestore(&priv->rx_queue.lock, f); | ||
328 | return; | ||
329 | } | ||
330 | spin_unlock_irqrestore(&priv->rx_queue.lock, f); | 327 | spin_unlock_irqrestore(&priv->rx_queue.lock, f); |
331 | skb_put(skb, urb->actual_length); | 328 | skb_put(skb, urb->actual_length); |
332 | 329 | ||
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c index 3ab3eb957189..25d27b64f528 100644 --- a/drivers/net/wireless/wavelan.c +++ b/drivers/net/wireless/wavelan.c | |||
@@ -2869,10 +2869,6 @@ static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev) | |||
2869 | if (lp->tx_n_in_use == (NTXBLOCKS - 1)) | 2869 | if (lp->tx_n_in_use == (NTXBLOCKS - 1)) |
2870 | return 1; | 2870 | return 1; |
2871 | } | 2871 | } |
2872 | #ifdef DEBUG_TX_ERROR | ||
2873 | if (skb->next) | ||
2874 | printk(KERN_INFO "skb has next\n"); | ||
2875 | #endif | ||
2876 | 2872 | ||
2877 | /* Do we need some padding? */ | 2873 | /* Do we need some padding? */ |
2878 | /* Note : on wireless the propagation time is in the order of 1us, | 2874 | /* Note : on wireless the propagation time is in the order of 1us, |
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index e55b33961aeb..1a90d69f18a9 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c | |||
@@ -3107,11 +3107,6 @@ wavelan_packet_xmit(struct sk_buff * skb, | |||
3107 | * so the Tx buffer is now free */ | 3107 | * so the Tx buffer is now free */ |
3108 | } | 3108 | } |
3109 | 3109 | ||
3110 | #ifdef DEBUG_TX_ERROR | ||
3111 | if (skb->next) | ||
3112 | printk(KERN_INFO "skb has next\n"); | ||
3113 | #endif | ||
3114 | |||
3115 | /* Check if we need some padding */ | 3110 | /* Check if we need some padding */ |
3116 | /* Note : on wireless the propagation time is in the order of 1us, | 3111 | /* Note : on wireless the propagation time is in the order of 1us, |
3117 | * and we don't have the Ethernet specific requirement of beeing | 3112 | * and we don't have the Ethernet specific requirement of beeing |