diff options
author | David S. Miller <davem@davemloft.net> | 2009-06-11 02:41:43 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-06-11 02:41:43 -0400 |
commit | 84503ddd65e804ccdeedee3f307b40d80ff793e6 (patch) | |
tree | c7b805f441b1d8cb2e86b8411cf2302ff46186b4 /drivers/net/wireless | |
parent | 51611a120e8120290152edd7d0020d22a7f4b4a3 (diff) | |
parent | 2f0accc13520b2644b85f80aedce10d10d88b0ca (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net/wireless')
45 files changed, 1067 insertions, 1244 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index daf4c805be58..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 | ||
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h index c7cba66b63cb..bb97981fb248 100644 --- a/drivers/net/wireless/ath/ar9170/ar9170.h +++ b/drivers/net/wireless/ath/ar9170/ar9170.h | |||
@@ -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; |
@@ -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,11 +195,19 @@ 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_MODE 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) |
@@ -204,9 +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); | ||
209 | void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); | 222 | void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); |
223 | int ar9170_nag_limiter(struct ar9170 *ar); | ||
210 | 224 | ||
211 | /* MAC */ | 225 | /* MAC */ |
212 | 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); |
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h index 3c8004fb7307..6cbfb2f83391 100644 --- a/drivers/net/wireless/ath/ar9170/hw.h +++ b/drivers/net/wireless/ath/ar9170/hw.h | |||
@@ -420,4 +420,7 @@ enum ar9170_txq { | |||
420 | __AR9170_NUM_TXQ, | 420 | __AR9170_NUM_TXQ, |
421 | }; | 421 | }; |
422 | 422 | ||
423 | #define AR9170_TXQ_DEPTH 32 | ||
424 | #define AR9170_TX_MAX_PENDING 128 | ||
425 | |||
423 | #endif /* __AR9170_HW_H */ | 426 | #endif /* __AR9170_HW_H */ |
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index b104d7efd676..9d38cf60a0db 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c | |||
@@ -173,59 +173,122 @@ static struct ieee80211_supported_band ar9170_band_5GHz = { | |||
173 | .ht_cap = AR9170_HT_CAP, | 173 | .ht_cap = AR9170_HT_CAP, |
174 | }; | 174 | }; |
175 | 175 | ||
176 | #ifdef AR9170_QUEUE_DEBUG | 176 | static void ar9170_tx(struct ar9170 *ar); |
177 | /* | ||
178 | * In case some wants works with AR9170's crazy tx_status queueing techniques. | ||
179 | * He might need this rather useful probing function. | ||
180 | * | ||
181 | * NOTE: caller must hold the queue's spinlock! | ||
182 | */ | ||
183 | 177 | ||
178 | #ifdef AR9170_QUEUE_DEBUG | ||
184 | 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) |
185 | { | 180 | { |
186 | struct ar9170_tx_control *txc = (void *) skb->data; | 181 | struct ar9170_tx_control *txc = (void *) skb->data; |
187 | 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; | ||
188 | 185 | ||
189 | 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 " |
190 | "mac_control:%04x, phy_control:%08x]\n", | 187 | "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", |
191 | wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), | 188 | wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), |
192 | ieee80211_get_DA(hdr), le16_to_cpu(txc->mac_control), | 189 | ieee80211_get_DA(hdr), arinfo->flags, |
193 | 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)); | ||
194 | } | 192 | } |
195 | 193 | ||
196 | static void ar9170_dump_station_tx_status_queue(struct ar9170 *ar, | 194 | static void __ar9170_dump_txqueue(struct ar9170 *ar, |
197 | struct sk_buff_head *queue) | 195 | struct sk_buff_head *queue) |
198 | { | 196 | { |
199 | struct sk_buff *skb; | 197 | struct sk_buff *skb; |
200 | int i = 0; | 198 | int i = 0; |
201 | 199 | ||
202 | printk(KERN_DEBUG "---[ cut here ]---\n"); | 200 | printk(KERN_DEBUG "---[ cut here ]---\n"); |
203 | printk(KERN_DEBUG "%s: %d entries in tx_status queue.\n", | 201 | printk(KERN_DEBUG "%s: %d entries in queue.\n", |
204 | wiphy_name(ar->hw->wiphy), skb_queue_len(queue)); | 202 | wiphy_name(ar->hw->wiphy), skb_queue_len(queue)); |
205 | 203 | ||
206 | skb_queue_walk(queue, skb) { | 204 | skb_queue_walk(queue, skb) { |
207 | struct ar9170_tx_control *txc = (void *) skb->data; | 205 | printk(KERN_DEBUG "index:%d => \n", i++); |
208 | struct ieee80211_hdr *hdr = (void *)txc->frame_data; | ||
209 | |||
210 | printk(KERN_DEBUG "index:%d => \n", i); | ||
211 | ar9170_print_txheader(ar, skb); | 206 | ar9170_print_txheader(ar, skb); |
212 | } | 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); | ||
213 | printk(KERN_DEBUG "---[ end ]---\n"); | 211 | printk(KERN_DEBUG "---[ end ]---\n"); |
214 | } | 212 | } |
215 | #endif /* AR9170_QUEUE_DEBUG */ | ||
216 | 213 | ||
217 | void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, | 214 | static void ar9170_dump_txqueue(struct ar9170 *ar, |
218 | 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) | ||
219 | { | 238 | { |
220 | struct ieee80211_tx_info *txinfo; | ||
221 | unsigned int retries = 0, queue = skb_get_queue_mapping(skb); | ||
222 | unsigned long flags; | 239 | unsigned long flags; |
223 | 240 | ||
224 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | 241 | spin_lock_irqsave(&ar->tx_stats_lock, flags); |
225 | ar->tx_stats[queue].len--; | 242 | __ar9170_dump_txstats(ar); |
226 | if (ieee80211_queue_stopped(ar->hw, queue)) | ||
227 | ieee80211_wake_queue(ar->hw, queue); | ||
228 | 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; | ||
229 | 292 | ||
230 | txinfo = IEEE80211_SKB_CB(skb); | 293 | txinfo = IEEE80211_SKB_CB(skb); |
231 | ieee80211_tx_info_clear_status(txinfo); | 294 | ieee80211_tx_info_clear_status(txinfo); |
@@ -247,45 +310,61 @@ void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb, | |||
247 | break; | 310 | break; |
248 | } | 311 | } |
249 | 312 | ||
250 | if (valid_status) | 313 | txinfo->status.rates[0].count = retries + 1; |
251 | txinfo->status.rates[0].count = retries + 1; | ||
252 | |||
253 | skb_pull(skb, sizeof(struct ar9170_tx_control)); | 314 | skb_pull(skb, sizeof(struct ar9170_tx_control)); |
254 | ieee80211_tx_status_irqsafe(ar->hw, skb); | 315 | ieee80211_tx_status_irqsafe(ar->hw, skb); |
255 | } | 316 | } |
256 | 317 | ||
257 | static struct sk_buff *ar9170_find_skb_in_queue(struct ar9170 *ar, | 318 | void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) |
258 | const u8 *mac, | ||
259 | const u32 queue, | ||
260 | struct sk_buff_head *q) | ||
261 | { | 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); | ||
262 | unsigned long flags; | 323 | unsigned long flags; |
263 | struct sk_buff *skb; | ||
264 | 324 | ||
265 | spin_lock_irqsave(&q->lock, flags); | 325 | spin_lock_irqsave(&ar->tx_stats_lock, flags); |
266 | skb_queue_walk(q, skb) { | 326 | ar->tx_stats[queue].len--; |
267 | struct ar9170_tx_control *txc = (void *) skb->data; | ||
268 | struct ieee80211_hdr *hdr = (void *) txc->frame_data; | ||
269 | u32 txc_queue = (le32_to_cpu(txc->phy_control) & | ||
270 | AR9170_TX_PHY_QOS_MASK) >> | ||
271 | AR9170_TX_PHY_QOS_SHIFT; | ||
272 | 327 | ||
273 | if ((queue != txc_queue) || | 328 | if (skb_queue_empty(&ar->tx_pending[queue])) { |
274 | (compare_ether_addr(ieee80211_get_DA(hdr), mac))) | 329 | #ifdef AR9170_QUEUE_STOP_DEBUG |
275 | 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); | ||
276 | 337 | ||
277 | __skb_unlink(skb, q); | 338 | if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) { |
278 | spin_unlock_irqrestore(&q->lock, flags); | 339 | dev_kfree_skb_any(skb); |
279 | 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); | ||
280 | } | 359 | } |
281 | spin_unlock_irqrestore(&q->lock, flags); | ||
282 | return NULL; | ||
283 | } | 360 | } |
284 | 361 | ||
285 | 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, |
286 | const u32 queue) | 363 | const u8 *mac, |
364 | struct sk_buff_head *queue, | ||
365 | const u32 rate) | ||
287 | { | 366 | { |
288 | struct ieee80211_sta *sta; | 367 | unsigned long flags; |
289 | struct sk_buff *skb; | 368 | struct sk_buff *skb; |
290 | 369 | ||
291 | /* | 370 | /* |
@@ -296,78 +375,91 @@ static struct sk_buff *ar9170_find_queued_skb(struct ar9170 *ar, const u8 *mac, | |||
296 | * the firmware provided (-> destination MAC, and phy_control) - | 375 | * the firmware provided (-> destination MAC, and phy_control) - |
297 | * and hope that we picked the right one... | 376 | * and hope that we picked the right one... |
298 | */ | 377 | */ |
299 | rcu_read_lock(); | ||
300 | sta = ieee80211_find_sta(ar->hw, mac); | ||
301 | |||
302 | if (likely(sta)) { | ||
303 | struct ar9170_sta_info *sta_priv = (void *) sta->drv_priv; | ||
304 | skb = skb_dequeue(&sta_priv->tx_status[queue]); | ||
305 | rcu_read_unlock(); | ||
306 | if (likely(skb)) | ||
307 | return skb; | ||
308 | } else | ||
309 | rcu_read_unlock(); | ||
310 | |||
311 | /* scan the waste queue for candidates */ | ||
312 | skb = ar9170_find_skb_in_queue(ar, mac, queue, | ||
313 | &ar->global_tx_status_waste); | ||
314 | if (!skb) { | ||
315 | /* so it still _must_ be in the global list. */ | ||
316 | skb = ar9170_find_skb_in_queue(ar, mac, queue, | ||
317 | &ar->global_tx_status); | ||
318 | } | ||
319 | 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)) { | ||
320 | #ifdef AR9170_QUEUE_DEBUG | 386 | #ifdef AR9170_QUEUE_DEBUG |
321 | if (unlikely((!skb) && net_ratelimit())) { | 387 | printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n", |
322 | printk(KERN_ERR "%s: ESS:[%pM] does not have any " | 388 | wiphy_name(ar->hw->wiphy), mac, |
323 | "outstanding frames in this queue (%d).\n", | 389 | ieee80211_get_DA(hdr)); |
324 | wiphy_name(ar->hw->wiphy), mac, queue); | 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)) { | ||
399 | #ifdef AR9170_QUEUE_DEBUG | ||
400 | printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n", | ||
401 | wiphy_name(ar->hw->wiphy), rate, r); | ||
402 | ar9170_print_txheader(ar, skb); | ||
403 | #endif /* AR9170_QUEUE_DEBUG */ | ||
404 | continue; | ||
405 | } | ||
406 | |||
407 | __skb_unlink(skb, queue); | ||
408 | spin_unlock_irqrestore(&queue->lock, flags); | ||
409 | return skb; | ||
325 | } | 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); | ||
326 | #endif /* AR9170_QUEUE_DEBUG */ | 417 | #endif /* AR9170_QUEUE_DEBUG */ |
327 | return skb; | 418 | spin_unlock_irqrestore(&queue->lock, flags); |
419 | |||
420 | return NULL; | ||
328 | } | 421 | } |
329 | 422 | ||
330 | /* | 423 | /* |
331 | * This worker tries to keep the global tx_status queue empty. | 424 | * This worker tries to keeps an maintain tx_status queues. |
332 | * So we can guarantee that incoming tx_status reports for | 425 | * So we can guarantee that incoming tx_status reports are |
333 | * unregistered stations are always synced with the actual | 426 | * actually for a pending frame. |
334 | * frame - which we think - belongs to. | ||
335 | */ | 427 | */ |
336 | 428 | ||
337 | static void ar9170_tx_status_janitor(struct work_struct *work) | 429 | static void ar9170_tx_janitor(struct work_struct *work) |
338 | { | 430 | { |
339 | struct ar9170 *ar = container_of(work, struct ar9170, | 431 | struct ar9170 *ar = container_of(work, struct ar9170, |
340 | tx_status_janitor.work); | 432 | tx_janitor.work); |
341 | struct sk_buff *skb; | 433 | struct sk_buff_head waste; |
434 | unsigned int i; | ||
435 | bool resched = false; | ||
342 | 436 | ||
343 | if (unlikely(!IS_STARTED(ar))) | 437 | if (unlikely(!IS_STARTED(ar))) |
344 | return ; | 438 | return ; |
345 | 439 | ||
346 | /* recycle the garbage back to mac80211... one by one. */ | 440 | skb_queue_head_init(&waste); |
347 | while ((skb = skb_dequeue(&ar->global_tx_status_waste))) { | 441 | |
442 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { | ||
348 | #ifdef AR9170_QUEUE_DEBUG | 443 | #ifdef AR9170_QUEUE_DEBUG |
349 | printk(KERN_DEBUG "%s: dispose queued frame =>\n", | 444 | printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n", |
350 | wiphy_name(ar->hw->wiphy)); | 445 | wiphy_name(ar->hw->wiphy), i); |
351 | ar9170_print_txheader(ar, skb); | 446 | ar9170_dump_txqueue(ar, &ar->tx_pending[i]); |
447 | ar9170_dump_txqueue(ar, &ar->tx_status[i]); | ||
352 | #endif /* AR9170_QUEUE_DEBUG */ | 448 | #endif /* AR9170_QUEUE_DEBUG */ |
353 | ar9170_handle_tx_status(ar, skb, false, | ||
354 | AR9170_TX_STATUS_FAILED); | ||
355 | } | ||
356 | 449 | ||
357 | while ((skb = skb_dequeue(&ar->global_tx_status))) { | 450 | ar9170_recycle_expired(ar, &ar->tx_status[i], &waste); |
358 | #ifdef AR9170_QUEUE_DEBUG | 451 | ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste); |
359 | printk(KERN_DEBUG "%s: moving frame into waste queue =>\n", | 452 | skb_queue_purge(&waste); |
360 | wiphy_name(ar->hw->wiphy)); | ||
361 | 453 | ||
362 | ar9170_print_txheader(ar, skb); | 454 | if (!skb_queue_empty(&ar->tx_status[i]) || |
363 | #endif /* AR9170_QUEUE_DEBUG */ | 455 | !skb_queue_empty(&ar->tx_pending[i])) |
364 | skb_queue_tail(&ar->global_tx_status_waste, skb); | 456 | resched = true; |
365 | } | 457 | } |
366 | 458 | ||
367 | /* recall the janitor in 100ms - if there's garbage in the can. */ | 459 | if (resched) |
368 | if (skb_queue_len(&ar->global_tx_status_waste) > 0) | 460 | queue_delayed_work(ar->hw->workqueue, |
369 | queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor, | 461 | &ar->tx_janitor, |
370 | msecs_to_jiffies(100)); | 462 | msecs_to_jiffies(AR9170_JANITOR_DELAY)); |
371 | } | 463 | } |
372 | 464 | ||
373 | void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) | 465 | void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) |
@@ -394,15 +486,21 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) | |||
394 | */ | 486 | */ |
395 | 487 | ||
396 | struct sk_buff *skb; | 488 | struct sk_buff *skb; |
397 | u32 queue = (le32_to_cpu(cmd->tx_status.rate) & | 489 | u32 phy = le32_to_cpu(cmd->tx_status.rate); |
398 | 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 */ | ||
399 | 496 | ||
400 | 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); | ||
401 | if (unlikely(!skb)) | 500 | if (unlikely(!skb)) |
402 | return ; | 501 | return ; |
403 | 502 | ||
404 | ar9170_handle_tx_status(ar, skb, true, | 503 | ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status)); |
405 | le16_to_cpu(cmd->tx_status.status)); | ||
406 | break; | 504 | break; |
407 | } | 505 | } |
408 | 506 | ||
@@ -442,6 +540,38 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) | |||
442 | /* retransmission issue / SIFS/EIFS collision ?! */ | 540 | /* retransmission issue / SIFS/EIFS collision ?! */ |
443 | break; | 541 | break; |
444 | 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 | |||
445 | default: | 575 | default: |
446 | printk(KERN_INFO "received unhandled event %x\n", cmd->type); | 576 | printk(KERN_INFO "received unhandled event %x\n", cmd->type); |
447 | print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len); | 577 | print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len); |
@@ -455,7 +585,7 @@ static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar) | |||
455 | ar->rx_mpdu.has_plcp = false; | 585 | ar->rx_mpdu.has_plcp = false; |
456 | } | 586 | } |
457 | 587 | ||
458 | static int ar9170_nag_limiter(struct ar9170 *ar) | 588 | int ar9170_nag_limiter(struct ar9170 *ar) |
459 | { | 589 | { |
460 | bool print_message; | 590 | bool print_message; |
461 | 591 | ||
@@ -956,8 +1086,8 @@ static int ar9170_op_start(struct ieee80211_hw *hw) | |||
956 | 1086 | ||
957 | /* reinitialize queues statistics */ | 1087 | /* reinitialize queues statistics */ |
958 | memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); | 1088 | memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); |
959 | for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++) | 1089 | for (i = 0; i < __AR9170_NUM_TXQ; i++) |
960 | ar->tx_stats[i].limit = 8; | 1090 | ar->tx_stats[i].limit = AR9170_TXQ_DEPTH; |
961 | 1091 | ||
962 | /* reset QoS defaults */ | 1092 | /* reset QoS defaults */ |
963 | 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*/ |
@@ -1003,18 +1133,17 @@ out: | |||
1003 | static void ar9170_op_stop(struct ieee80211_hw *hw) | 1133 | static void ar9170_op_stop(struct ieee80211_hw *hw) |
1004 | { | 1134 | { |
1005 | struct ar9170 *ar = hw->priv; | 1135 | struct ar9170 *ar = hw->priv; |
1136 | unsigned int i; | ||
1006 | 1137 | ||
1007 | if (IS_STARTED(ar)) | 1138 | if (IS_STARTED(ar)) |
1008 | ar->state = AR9170_IDLE; | 1139 | ar->state = AR9170_IDLE; |
1009 | 1140 | ||
1010 | flush_workqueue(ar->hw->workqueue); | 1141 | flush_workqueue(ar->hw->workqueue); |
1011 | 1142 | ||
1012 | cancel_delayed_work_sync(&ar->tx_status_janitor); | 1143 | cancel_delayed_work_sync(&ar->tx_janitor); |
1013 | cancel_work_sync(&ar->filter_config_work); | 1144 | cancel_work_sync(&ar->filter_config_work); |
1014 | cancel_work_sync(&ar->beacon_work); | 1145 | cancel_work_sync(&ar->beacon_work); |
1015 | mutex_lock(&ar->mutex); | 1146 | mutex_lock(&ar->mutex); |
1016 | skb_queue_purge(&ar->global_tx_status_waste); | ||
1017 | skb_queue_purge(&ar->global_tx_status); | ||
1018 | 1147 | ||
1019 | if (IS_ACCEPTING_CMD(ar)) { | 1148 | if (IS_ACCEPTING_CMD(ar)) { |
1020 | ar9170_set_leds_state(ar, 0); | 1149 | ar9170_set_leds_state(ar, 0); |
@@ -1024,51 +1153,32 @@ static void ar9170_op_stop(struct ieee80211_hw *hw) | |||
1024 | ar->stop(ar); | 1153 | ar->stop(ar); |
1025 | } | 1154 | } |
1026 | 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 | } | ||
1027 | mutex_unlock(&ar->mutex); | 1160 | mutex_unlock(&ar->mutex); |
1028 | } | 1161 | } |
1029 | 1162 | ||
1030 | 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) |
1031 | { | 1164 | { |
1032 | struct ar9170 *ar = hw->priv; | ||
1033 | struct ieee80211_hdr *hdr; | 1165 | struct ieee80211_hdr *hdr; |
1034 | struct ar9170_tx_control *txc; | 1166 | struct ar9170_tx_control *txc; |
1035 | struct ieee80211_tx_info *info; | 1167 | struct ieee80211_tx_info *info; |
1036 | struct ieee80211_rate *rate = NULL; | ||
1037 | struct ieee80211_tx_rate *txrate; | 1168 | struct ieee80211_tx_rate *txrate; |
1169 | struct ar9170_tx_info *arinfo; | ||
1038 | unsigned int queue = skb_get_queue_mapping(skb); | 1170 | unsigned int queue = skb_get_queue_mapping(skb); |
1039 | unsigned long flags = 0; | ||
1040 | struct ar9170_sta_info *sta_info = NULL; | ||
1041 | u32 power, chains; | ||
1042 | u16 keytype = 0; | 1171 | u16 keytype = 0; |
1043 | u16 len, icv = 0; | 1172 | u16 len, icv = 0; |
1044 | int err; | ||
1045 | bool tx_status; | ||
1046 | 1173 | ||
1047 | if (unlikely(!IS_STARTED(ar))) | 1174 | BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); |
1048 | goto err_free; | ||
1049 | 1175 | ||
1050 | hdr = (void *)skb->data; | 1176 | hdr = (void *)skb->data; |
1051 | info = IEEE80211_SKB_CB(skb); | 1177 | info = IEEE80211_SKB_CB(skb); |
1052 | len = skb->len; | 1178 | len = skb->len; |
1053 | 1179 | ||
1054 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | ||
1055 | if (ar->tx_stats[queue].limit < ar->tx_stats[queue].len) { | ||
1056 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1057 | return NETDEV_TX_OK; | ||
1058 | } | ||
1059 | |||
1060 | ar->tx_stats[queue].len++; | ||
1061 | ar->tx_stats[queue].count++; | ||
1062 | if (ar->tx_stats[queue].limit == ar->tx_stats[queue].len) | ||
1063 | ieee80211_stop_queue(hw, queue); | ||
1064 | |||
1065 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1066 | |||
1067 | txc = (void *)skb_push(skb, sizeof(*txc)); | 1180 | txc = (void *)skb_push(skb, sizeof(*txc)); |
1068 | 1181 | ||
1069 | tx_status = (((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) != 0) || | ||
1070 | ((info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) != 0)); | ||
1071 | |||
1072 | if (info->control.hw_key) { | 1182 | if (info->control.hw_key) { |
1073 | icv = info->control.hw_key->icv_len; | 1183 | icv = info->control.hw_key->icv_len; |
1074 | 1184 | ||
@@ -1084,7 +1194,7 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1084 | break; | 1194 | break; |
1085 | default: | 1195 | default: |
1086 | WARN_ON(1); | 1196 | WARN_ON(1); |
1087 | goto err_dequeue; | 1197 | goto err_out; |
1088 | } | 1198 | } |
1089 | } | 1199 | } |
1090 | 1200 | ||
@@ -1101,16 +1211,65 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1101 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) | 1211 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) |
1102 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK); | 1212 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK); |
1103 | 1213 | ||
1104 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | ||
1105 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); | ||
1106 | |||
1107 | txrate = &info->control.rates[0]; | 1214 | txrate = &info->control.rates[0]; |
1108 | |||
1109 | if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) | 1215 | if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) |
1110 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); | 1216 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); |
1111 | else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS) | 1217 | else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS) |
1112 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); | 1218 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); |
1113 | 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 | |||
1114 | if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) | 1273 | if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) |
1115 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD); | 1274 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD); |
1116 | 1275 | ||
@@ -1130,9 +1289,12 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1130 | u32 r = txrate->idx; | 1289 | u32 r = txrate->idx; |
1131 | u8 *txpower; | 1290 | u8 *txpower; |
1132 | 1291 | ||
1292 | /* heavy clip control */ | ||
1293 | txc->phy_control |= cpu_to_le32((r & 0x7) << 7); | ||
1294 | |||
1133 | r <<= AR9170_TX_PHY_MCS_SHIFT; | 1295 | r <<= AR9170_TX_PHY_MCS_SHIFT; |
1134 | if (WARN_ON(r & ~AR9170_TX_PHY_MCS_MASK)) | 1296 | BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK); |
1135 | goto err_dequeue; | 1297 | |
1136 | 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); |
1137 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT); | 1299 | txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT); |
1138 | 1300 | ||
@@ -1194,53 +1356,154 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1194 | chains = AR9170_TX_PHY_TXCHAIN_1; | 1356 | chains = AR9170_TX_PHY_TXCHAIN_1; |
1195 | } | 1357 | } |
1196 | 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 | } | ||
1197 | 1360 | ||
1198 | if (tx_status) { | 1361 | static void ar9170_tx(struct ar9170 *ar) |
1199 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); | 1362 | { |
1200 | /* | 1363 | struct sk_buff *skb; |
1201 | * WARNING: | 1364 | unsigned long flags; |
1202 | * Putting the QoS queue bits into an unexplored territory is | 1365 | struct ieee80211_tx_info *info; |
1203 | * certainly not elegant. | 1366 | struct ar9170_tx_info *arinfo; |
1204 | * | 1367 | unsigned int i, frames, frames_failed, remaining_space; |
1205 | * In my defense: This idea provides a reasonable way to | 1368 | int err; |
1206 | * smuggle valuable information to the tx_status callback. | 1369 | bool schedule_garbagecollector = false; |
1207 | * Also, the idea behind this bit-abuse came straight from | ||
1208 | * the original driver code. | ||
1209 | */ | ||
1210 | 1370 | ||
1211 | txc->phy_control |= | 1371 | BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); |
1212 | cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); | ||
1213 | 1372 | ||
1214 | if (info->control.sta) { | 1373 | if (unlikely(!IS_STARTED(ar))) |
1215 | sta_info = (void *) info->control.sta->drv_priv; | 1374 | return ; |
1216 | skb_queue_tail(&sta_info->tx_status[queue], skb); | 1375 | |
1217 | } else { | 1376 | remaining_space = AR9170_TX_MAX_PENDING; |
1218 | 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); | ||
1384 | |||
1385 | __ar9170_dump_txstats(ar); | ||
1386 | printk(KERN_DEBUG "stuck frames: ===> \n"); | ||
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 | } | ||
1219 | 1450 | ||
1220 | queue_delayed_work(ar->hw->workqueue, | 1451 | #ifdef AR9170_QUEUE_DEBUG |
1221 | &ar->tx_status_janitor, | 1452 | printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n", |
1222 | msecs_to_jiffies(100)); | 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); | ||
1223 | } | 1471 | } |
1224 | } | 1472 | } |
1225 | 1473 | ||
1226 | err = ar->tx(ar, skb, tx_status, 0); | 1474 | if (schedule_garbagecollector) |
1227 | if (unlikely(tx_status && err)) { | 1475 | queue_delayed_work(ar->hw->workqueue, |
1228 | if (info->control.sta) | 1476 | &ar->tx_janitor, |
1229 | skb_unlink(skb, &sta_info->tx_status[queue]); | 1477 | msecs_to_jiffies(AR9170_JANITOR_DELAY)); |
1230 | else | 1478 | } |
1231 | 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); | ||
1232 | } | 1500 | } |
1233 | 1501 | ||
1502 | ar9170_tx(ar); | ||
1234 | return NETDEV_TX_OK; | 1503 | return NETDEV_TX_OK; |
1235 | 1504 | ||
1236 | err_dequeue: | ||
1237 | spin_lock_irqsave(&ar->tx_stats_lock, flags); | ||
1238 | ar->tx_stats[queue].len--; | ||
1239 | ar->tx_stats[queue].count--; | ||
1240 | spin_unlock_irqrestore(&ar->tx_stats_lock, flags); | ||
1241 | |||
1242 | err_free: | 1505 | err_free: |
1243 | dev_kfree_skb(skb); | 1506 | dev_kfree_skb_any(skb); |
1244 | return NETDEV_TX_OK; | 1507 | return NETDEV_TX_OK; |
1245 | } | 1508 | } |
1246 | 1509 | ||
@@ -1666,43 +1929,6 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw, | |||
1666 | enum sta_notify_cmd cmd, | 1929 | enum sta_notify_cmd cmd, |
1667 | struct ieee80211_sta *sta) | 1930 | struct ieee80211_sta *sta) |
1668 | { | 1931 | { |
1669 | struct ar9170 *ar = hw->priv; | ||
1670 | struct ar9170_sta_info *info = (void *) sta->drv_priv; | ||
1671 | struct sk_buff *skb; | ||
1672 | unsigned int i; | ||
1673 | |||
1674 | switch (cmd) { | ||
1675 | case STA_NOTIFY_ADD: | ||
1676 | for (i = 0; i < ar->hw->queues; i++) | ||
1677 | skb_queue_head_init(&info->tx_status[i]); | ||
1678 | break; | ||
1679 | |||
1680 | case STA_NOTIFY_REMOVE: | ||
1681 | |||
1682 | /* | ||
1683 | * transfer all outstanding frames that need a tx_status | ||
1684 | * reports to the global tx_status queue | ||
1685 | */ | ||
1686 | |||
1687 | for (i = 0; i < ar->hw->queues; i++) { | ||
1688 | while ((skb = skb_dequeue(&info->tx_status[i]))) { | ||
1689 | #ifdef AR9170_QUEUE_DEBUG | ||
1690 | printk(KERN_DEBUG "%s: queueing frame in " | ||
1691 | "global tx_status queue =>\n", | ||
1692 | wiphy_name(ar->hw->wiphy)); | ||
1693 | |||
1694 | ar9170_print_txheader(ar, skb); | ||
1695 | #endif /* AR9170_QUEUE_DEBUG */ | ||
1696 | skb_queue_tail(&ar->global_tx_status, skb); | ||
1697 | } | ||
1698 | } | ||
1699 | queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor, | ||
1700 | msecs_to_jiffies(100)); | ||
1701 | break; | ||
1702 | |||
1703 | default: | ||
1704 | break; | ||
1705 | } | ||
1706 | } | 1932 | } |
1707 | 1933 | ||
1708 | static int ar9170_get_stats(struct ieee80211_hw *hw, | 1934 | static int ar9170_get_stats(struct ieee80211_hw *hw, |
@@ -1741,7 +1967,7 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
1741 | int ret; | 1967 | int ret; |
1742 | 1968 | ||
1743 | mutex_lock(&ar->mutex); | 1969 | mutex_lock(&ar->mutex); |
1744 | if ((param) && !(queue > ar->hw->queues)) { | 1970 | if ((param) && !(queue > __AR9170_NUM_TXQ)) { |
1745 | memcpy(&ar->edcf[ar9170_qos_hwmap[queue]], | 1971 | memcpy(&ar->edcf[ar9170_qos_hwmap[queue]], |
1746 | param, sizeof(*param)); | 1972 | param, sizeof(*param)); |
1747 | 1973 | ||
@@ -1817,12 +2043,14 @@ void *ar9170_alloc(size_t priv_size) | |||
1817 | mutex_init(&ar->mutex); | 2043 | mutex_init(&ar->mutex); |
1818 | spin_lock_init(&ar->cmdlock); | 2044 | spin_lock_init(&ar->cmdlock); |
1819 | spin_lock_init(&ar->tx_stats_lock); | 2045 | spin_lock_init(&ar->tx_stats_lock); |
1820 | skb_queue_head_init(&ar->global_tx_status); | 2046 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { |
1821 | 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 | } | ||
1822 | ar9170_rx_reset_rx_mpdu(ar); | 2050 | ar9170_rx_reset_rx_mpdu(ar); |
1823 | INIT_WORK(&ar->filter_config_work, ar9170_set_filters); | 2051 | INIT_WORK(&ar->filter_config_work, ar9170_set_filters); |
1824 | INIT_WORK(&ar->beacon_work, ar9170_new_beacon); | 2052 | INIT_WORK(&ar->beacon_work, ar9170_new_beacon); |
1825 | INIT_DELAYED_WORK(&ar->tx_status_janitor, ar9170_tx_status_janitor); | 2053 | INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor); |
1826 | 2054 | ||
1827 | /* 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 */ |
1828 | ar->channel = &ar9170_2ghz_chantable[0]; | 2056 | ar->channel = &ar9170_2ghz_chantable[0]; |
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index f752698669d2..754b1f8d8da9 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c | |||
@@ -96,7 +96,49 @@ static struct usb_device_id ar9170_usb_ids[] = { | |||
96 | }; | 96 | }; |
97 | MODULE_DEVICE_TABLE(usb, ar9170_usb_ids); | 97 | MODULE_DEVICE_TABLE(usb, ar9170_usb_ids); |
98 | 98 | ||
99 | 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) | ||
100 | { | 142 | { |
101 | struct sk_buff *skb = urb->context; | 143 | struct sk_buff *skb = urb->context; |
102 | struct ar9170_usb *aru = (struct ar9170_usb *) | 144 | struct ar9170_usb *aru = (struct ar9170_usb *) |
@@ -107,8 +149,11 @@ static void ar9170_usb_tx_urb_complete_free(struct urb *urb) | |||
107 | return ; | 149 | return ; |
108 | } | 150 | } |
109 | 151 | ||
110 | ar9170_handle_tx_status(&aru->common, skb, false, | 152 | aru->tx_submitted_urbs--; |
111 | AR9170_TX_STATUS_COMPLETE); | 153 | |
154 | ar9170_tx_callback(&aru->common, skb); | ||
155 | |||
156 | ar9170_usb_submit_urb(aru); | ||
112 | } | 157 | } |
113 | 158 | ||
114 | static void ar9170_usb_tx_urb_complete(struct urb *urb) | 159 | static void ar9170_usb_tx_urb_complete(struct urb *urb) |
@@ -290,21 +335,47 @@ err_out: | |||
290 | return err; | 335 | return err; |
291 | } | 336 | } |
292 | 337 | ||
293 | static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru) | 338 | static int ar9170_usb_flush(struct ar9170 *ar) |
294 | { | 339 | { |
295 | int ret; | 340 | struct ar9170_usb *aru = (void *) ar; |
341 | struct urb *urb; | ||
342 | int ret, err = 0; | ||
296 | 343 | ||
297 | aru->common.state = AR9170_UNKNOWN_STATE; | 344 | if (IS_STARTED(ar)) |
345 | aru->common.state = AR9170_IDLE; | ||
298 | 346 | ||
299 | 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 | } | ||
300 | 353 | ||
301 | /* 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 */ |
302 | ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, | 355 | ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, |
303 | msecs_to_jiffies(100)); | 356 | msecs_to_jiffies(100)); |
304 | if (ret == 0) | 357 | if (ret == 0) |
305 | dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); | 358 | err = -ETIMEDOUT; |
306 | 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; | ||
364 | |||
365 | return err; | ||
366 | } | ||
367 | |||
368 | static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru) | ||
369 | { | ||
370 | int err; | ||
307 | 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); | ||
308 | usb_poison_anchored_urbs(&aru->rx_submitted); | 379 | usb_poison_anchored_urbs(&aru->rx_submitted); |
309 | } | 380 | } |
310 | 381 | ||
@@ -388,12 +459,10 @@ err_free: | |||
388 | return err; | 459 | return err; |
389 | } | 460 | } |
390 | 461 | ||
391 | 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) |
392 | bool txstatus_needed, unsigned int extra_len) | ||
393 | { | 463 | { |
394 | struct ar9170_usb *aru = (struct ar9170_usb *) ar; | 464 | struct ar9170_usb *aru = (struct ar9170_usb *) ar; |
395 | struct urb *urb; | 465 | struct urb *urb; |
396 | int err; | ||
397 | 466 | ||
398 | if (unlikely(!IS_STARTED(ar))) { | 467 | if (unlikely(!IS_STARTED(ar))) { |
399 | /* Seriously, what were you drink... err... thinking!? */ | 468 | /* Seriously, what were you drink... err... thinking!? */ |
@@ -406,18 +475,17 @@ static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb, | |||
406 | 475 | ||
407 | usb_fill_bulk_urb(urb, aru->udev, | 476 | usb_fill_bulk_urb(urb, aru->udev, |
408 | usb_sndbulkpipe(aru->udev, AR9170_EP_TX), | 477 | usb_sndbulkpipe(aru->udev, AR9170_EP_TX), |
409 | skb->data, skb->len + extra_len, (txstatus_needed ? | 478 | skb->data, skb->len, |
410 | ar9170_usb_tx_urb_complete : | 479 | ar9170_usb_tx_urb_complete_frame, skb); |
411 | ar9170_usb_tx_urb_complete_free), skb); | ||
412 | urb->transfer_flags |= URB_ZERO_PACKET; | 480 | urb->transfer_flags |= URB_ZERO_PACKET; |
413 | 481 | ||
414 | usb_anchor_urb(urb, &aru->tx_submitted); | 482 | usb_anchor_urb(urb, &aru->tx_pending); |
415 | err = usb_submit_urb(urb, GFP_ATOMIC); | 483 | aru->tx_pending_urbs++; |
416 | if (unlikely(err)) | ||
417 | usb_unanchor_urb(urb); | ||
418 | 484 | ||
419 | usb_free_urb(urb); | 485 | usb_free_urb(urb); |
420 | return err; | 486 | |
487 | ar9170_usb_submit_urb(aru); | ||
488 | return 0; | ||
421 | } | 489 | } |
422 | 490 | ||
423 | 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) |
@@ -617,10 +685,8 @@ static void ar9170_usb_stop(struct ar9170 *ar) | |||
617 | if (IS_ACCEPTING_CMD(ar)) | 685 | if (IS_ACCEPTING_CMD(ar)) |
618 | aru->common.state = AR9170_STOPPED; | 686 | aru->common.state = AR9170_STOPPED; |
619 | 687 | ||
620 | /* lets wait a while until the tx - queues are dried out */ | 688 | ret = ar9170_usb_flush(ar); |
621 | ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted, | 689 | if (ret) |
622 | msecs_to_jiffies(1000)); | ||
623 | if (ret == 0) | ||
624 | dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); | 690 | dev_err(&aru->udev->dev, "kill pending tx urbs.\n"); |
625 | 691 | ||
626 | usb_poison_anchored_urbs(&aru->tx_submitted); | 692 | usb_poison_anchored_urbs(&aru->tx_submitted); |
@@ -716,10 +782,16 @@ static int ar9170_usb_probe(struct usb_interface *intf, | |||
716 | SET_IEEE80211_DEV(ar->hw, &udev->dev); | 782 | SET_IEEE80211_DEV(ar->hw, &udev->dev); |
717 | 783 | ||
718 | init_usb_anchor(&aru->rx_submitted); | 784 | init_usb_anchor(&aru->rx_submitted); |
785 | init_usb_anchor(&aru->tx_pending); | ||
719 | init_usb_anchor(&aru->tx_submitted); | 786 | init_usb_anchor(&aru->tx_submitted); |
720 | 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; | ||
721 | 792 | ||
722 | aru->common.stop = ar9170_usb_stop; | 793 | aru->common.stop = ar9170_usb_stop; |
794 | aru->common.flush = ar9170_usb_flush; | ||
723 | aru->common.open = ar9170_usb_open; | 795 | aru->common.open = ar9170_usb_open; |
724 | aru->common.tx = ar9170_usb_tx; | 796 | aru->common.tx = ar9170_usb_tx; |
725 | aru->common.exec_cmd = ar9170_usb_exec_cmd; | 797 | aru->common.exec_cmd = ar9170_usb_exec_cmd; |
diff --git a/drivers/net/wireless/ath/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h index 69f4bceb0af3..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,11 +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 | bool req_one_stage_fw; | 67 | bool req_one_stage_fw; |
66 | 68 | ||
67 | spinlock_t cmdlock; | 69 | spinlock_t tx_urb_lock; |
70 | unsigned int tx_submitted_urbs; | ||
71 | unsigned int tx_pending_urbs; | ||
72 | |||
68 | struct completion cmd_wait; | 73 | struct completion cmd_wait; |
69 | int readlen; | 74 | int readlen; |
70 | 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 85a00db4867d..55f7de09d134 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -2360,6 +2360,8 @@ ath5k_init(struct ath5k_softc *sc) | |||
2360 | if (ret) | 2360 | if (ret) |
2361 | goto done; | 2361 | goto done; |
2362 | 2362 | ||
2363 | ath5k_rfkill_hw_start(ah); | ||
2364 | |||
2363 | /* | 2365 | /* |
2364 | * Reset the key cache since some parts do not reset the | 2366 | * Reset the key cache since some parts do not reset the |
2365 | * contents on initial power up or resume from suspend. | 2367 | * contents on initial power up or resume from suspend. |
@@ -2468,6 +2470,8 @@ ath5k_stop_hw(struct ath5k_softc *sc) | |||
2468 | tasklet_kill(&sc->restq); | 2470 | tasklet_kill(&sc->restq); |
2469 | tasklet_kill(&sc->beacontq); | 2471 | tasklet_kill(&sc->beacontq); |
2470 | 2472 | ||
2473 | ath5k_rfkill_hw_stop(sc->ah); | ||
2474 | |||
2471 | return ret; | 2475 | return ret; |
2472 | } | 2476 | } |
2473 | 2477 | ||
@@ -2526,6 +2530,9 @@ ath5k_intr(int irq, void *dev_id) | |||
2526 | */ | 2530 | */ |
2527 | ath5k_hw_update_mib_counters(ah, &sc->ll_stats); | 2531 | ath5k_hw_update_mib_counters(ah, &sc->ll_stats); |
2528 | } | 2532 | } |
2533 | if (status & AR5K_INT_GPIO) | ||
2534 | tasklet_schedule(&sc->rf_kill.toggleq); | ||
2535 | |||
2529 | } | 2536 | } |
2530 | } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); | 2537 | } while (ath5k_hw_is_intr_pending(ah) && --counter > 0); |
2531 | 2538 | ||
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/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/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 07a99e3faf94..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) | ||
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 9a498d3fc653..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, |
@@ -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 1d3e40095ada..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", |
@@ -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_common.h b/drivers/net/wireless/b43/phy_common.h index f4c2d79cbc89..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 | ||
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 96047843cd56..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,110 +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 rfkill *rfkill, void *data) | 44 | void b43_rfkill_poll(struct ieee80211_hw *hw) |
49 | { | 45 | { |
50 | struct b43_wldev *dev = data; | 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; |
50 | bool brought_up = false; | ||
53 | 51 | ||
54 | mutex_lock(&wl->mutex); | 52 | mutex_lock(&wl->mutex); |
55 | if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { | 53 | if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { |
56 | mutex_unlock(&wl->mutex); | 54 | if (ssb_bus_powerup(bus, 0)) { |
57 | return; | 55 | mutex_unlock(&wl->mutex); |
56 | return; | ||
57 | } | ||
58 | ssb_device_enable(dev->dev, 0); | ||
59 | brought_up = true; | ||
58 | } | 60 | } |
61 | |||
59 | enabled = b43_is_hw_radio_enabled(dev); | 62 | enabled = b43_is_hw_radio_enabled(dev); |
63 | |||
60 | if (unlikely(enabled != dev->radio_hw_enable)) { | 64 | if (unlikely(enabled != dev->radio_hw_enable)) { |
61 | dev->radio_hw_enable = enabled; | 65 | dev->radio_hw_enable = enabled; |
62 | b43info(wl, "Radio hardware status changed to %s\n", | 66 | b43info(wl, "Radio hardware status changed to %s\n", |
63 | enabled ? "ENABLED" : "DISABLED"); | 67 | enabled ? "ENABLED" : "DISABLED"); |
64 | enabled = !rfkill_set_hw_state(rfkill, !enabled); | 68 | wiphy_rfkill_set_hw_state(hw->wiphy, !enabled); |
65 | if (enabled != dev->phy.radio_on) | 69 | if (enabled != dev->phy.radio_on) |
66 | b43_software_rfkill(dev, !enabled); | 70 | b43_software_rfkill(dev, !enabled); |
67 | } | 71 | } |
68 | mutex_unlock(&wl->mutex); | ||
69 | } | ||
70 | |||
71 | /* Called when the RFKILL toggled in software. */ | ||
72 | static int b43_rfkill_soft_set(void *data, bool blocked) | ||
73 | { | ||
74 | struct b43_wldev *dev = data; | ||
75 | struct b43_wl *wl = dev->wl; | ||
76 | int err = -EINVAL; | ||
77 | |||
78 | if (WARN_ON(!wl->rfkill.registered)) | ||
79 | return -EINVAL; | ||
80 | 72 | ||
81 | mutex_lock(&wl->mutex); | 73 | if (brought_up) { |
82 | 74 | ssb_device_disable(dev->dev, 0); | |
83 | if (b43_status(dev) < B43_STAT_INITIALIZED) | 75 | ssb_bus_may_powerdown(bus); |
84 | goto out_unlock; | 76 | } |
85 | |||
86 | if (!dev->radio_hw_enable) | ||
87 | goto out_unlock; | ||
88 | 77 | ||
89 | if (!blocked != dev->phy.radio_on) | ||
90 | b43_software_rfkill(dev, blocked); | ||
91 | err = 0; | ||
92 | out_unlock: | ||
93 | mutex_unlock(&wl->mutex); | 78 | mutex_unlock(&wl->mutex); |
94 | return err; | ||
95 | } | ||
96 | |||
97 | const char *b43_rfkill_led_name(struct b43_wldev *dev) | ||
98 | { | ||
99 | struct b43_rfkill *rfk = &(dev->wl->rfkill); | ||
100 | |||
101 | if (!rfk->registered) | ||
102 | return NULL; | ||
103 | return rfkill_get_led_trigger_name(rfk->rfkill); | ||
104 | } | ||
105 | |||
106 | static const struct rfkill_ops b43_rfkill_ops = { | ||
107 | .set_block = b43_rfkill_soft_set, | ||
108 | .poll = b43_rfkill_poll, | ||
109 | }; | ||
110 | |||
111 | void b43_rfkill_init(struct b43_wldev *dev) | ||
112 | { | ||
113 | struct b43_wl *wl = dev->wl; | ||
114 | struct b43_rfkill *rfk = &(wl->rfkill); | ||
115 | int err; | ||
116 | |||
117 | rfk->registered = 0; | ||
118 | |||
119 | snprintf(rfk->name, sizeof(rfk->name), | ||
120 | "b43-%s", wiphy_name(wl->hw->wiphy)); | ||
121 | |||
122 | rfk->rfkill = rfkill_alloc(rfk->name, | ||
123 | dev->dev->dev, | ||
124 | RFKILL_TYPE_WLAN, | ||
125 | &b43_rfkill_ops, dev); | ||
126 | if (!rfk->rfkill) | ||
127 | goto out_error; | ||
128 | |||
129 | err = rfkill_register(rfk->rfkill); | ||
130 | if (err) | ||
131 | goto err_free; | ||
132 | |||
133 | rfk->registered = 1; | ||
134 | |||
135 | return; | ||
136 | err_free: | ||
137 | rfkill_destroy(rfk->rfkill); | ||
138 | out_error: | ||
139 | rfk->registered = 0; | ||
140 | b43warn(wl, "RF-kill button init failed\n"); | ||
141 | } | ||
142 | |||
143 | void b43_rfkill_exit(struct b43_wldev *dev) | ||
144 | { | ||
145 | struct b43_rfkill *rfk = &(dev->wl->rfkill); | ||
146 | |||
147 | if (!rfk->registered) | ||
148 | return; | ||
149 | rfk->registered = 0; | ||
150 | |||
151 | rfkill_unregister(rfk->rfkill); | ||
152 | rfkill_destroy(rfk->rfkill); | ||
153 | rfk->rfkill = NULL; | ||
154 | } | 79 | } |
diff --git a/drivers/net/wireless/b43/rfkill.h b/drivers/net/wireless/b43/rfkill.h index da497e01bbb1..f046c3ca0519 100644 --- a/drivers/net/wireless/b43/rfkill.h +++ b/drivers/net/wireless/b43/rfkill.h | |||
@@ -1,49 +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 | |||
11 | |||
12 | struct b43_rfkill { | ||
13 | /* The RFKILL subsystem data structure */ | ||
14 | struct rfkill *rfkill; | ||
15 | /* Did initialization succeed? Used for freeing. */ | ||
16 | bool registered; | ||
17 | /* The unique name of this rfkill switch */ | ||
18 | char name[sizeof("b43-phy4294967295")]; | ||
19 | }; | ||
20 | |||
21 | /* The init function returns void, because we are not interested | ||
22 | * in failing the b43 init process when rfkill init failed. */ | ||
23 | void b43_rfkill_init(struct b43_wldev *dev); | ||
24 | void b43_rfkill_exit(struct b43_wldev *dev); | ||
25 | |||
26 | const char *b43_rfkill_led_name(struct b43_wldev *dev); | ||
27 | |||
28 | |||
29 | #else /* CONFIG_B43_RFKILL */ | ||
30 | /* No RFKILL support. */ | ||
31 | |||
32 | struct b43_rfkill { | ||
33 | /* empty */ | ||
34 | }; | ||
35 | |||
36 | static inline void b43_rfkill_init(struct b43_wldev *dev) | ||
37 | { | ||
38 | } | ||
39 | static inline void b43_rfkill_exit(struct b43_wldev *dev) | ||
40 | { | ||
41 | } | ||
42 | static inline char * b43_rfkill_led_name(struct b43_wldev *dev) | ||
43 | { | ||
44 | return NULL; | ||
45 | } | ||
46 | |||
47 | #endif /* CONFIG_B43_RFKILL */ | ||
48 | 10 | ||
49 | #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 6893f439df70..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) | ||
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 538d3117594b..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, |
@@ -164,10 +165,10 @@ static void b43legacy_map_led(struct b43legacy_wldev *dev, | |||
164 | snprintf(name, sizeof(name), | 165 | snprintf(name, sizeof(name), |
165 | "b43legacy-%s::radio", wiphy_name(hw->wiphy)); | 166 | "b43legacy-%s::radio", wiphy_name(hw->wiphy)); |
166 | b43legacy_register_led(dev, &dev->led_radio, name, | 167 | b43legacy_register_led(dev, &dev->led_radio, name, |
167 | b43legacy_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 && b43legacy_is_hw_radio_enabled(dev)) |
171 | b43legacy_led_turn_on(dev, led_index, activelow); | 172 | b43legacy_led_turn_on(dev, led_index, activelow); |
172 | break; | 173 | break; |
173 | 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 c6230a64505a..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,23 +42,31 @@ 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 rfkill *rfkill, void *data) | 45 | void b43legacy_rfkill_poll(struct ieee80211_hw *hw) |
49 | { | 46 | { |
50 | struct b43legacy_wldev *dev = data; | 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; |
51 | bool brought_up = false; | ||
53 | 52 | ||
54 | mutex_lock(&wl->mutex); | 53 | mutex_lock(&wl->mutex); |
55 | if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) { | 54 | if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) { |
56 | mutex_unlock(&wl->mutex); | 55 | if (ssb_bus_powerup(bus, 0)) { |
57 | return; | 56 | mutex_unlock(&wl->mutex); |
57 | return; | ||
58 | } | ||
59 | ssb_device_enable(dev->dev, 0); | ||
60 | brought_up = true; | ||
58 | } | 61 | } |
62 | |||
59 | enabled = b43legacy_is_hw_radio_enabled(dev); | 63 | enabled = b43legacy_is_hw_radio_enabled(dev); |
64 | |||
60 | if (unlikely(enabled != dev->radio_hw_enable)) { | 65 | if (unlikely(enabled != dev->radio_hw_enable)) { |
61 | dev->radio_hw_enable = enabled; | 66 | dev->radio_hw_enable = enabled; |
62 | b43legacyinfo(wl, "Radio hardware status changed to %s\n", | 67 | b43legacyinfo(wl, "Radio hardware status changed to %s\n", |
63 | enabled ? "ENABLED" : "DISABLED"); | 68 | enabled ? "ENABLED" : "DISABLED"); |
64 | enabled = !rfkill_set_hw_state(rfkill, !enabled); | 69 | wiphy_rfkill_set_hw_state(hw->wiphy, !enabled); |
65 | if (enabled != dev->phy.radio_on) { | 70 | if (enabled != dev->phy.radio_on) { |
66 | if (enabled) | 71 | if (enabled) |
67 | b43legacy_radio_turn_on(dev); | 72 | b43legacy_radio_turn_on(dev); |
@@ -69,95 +74,11 @@ static void b43legacy_rfkill_poll(struct rfkill *rfkill, void *data) | |||
69 | b43legacy_radio_turn_off(dev, 0); | 74 | b43legacy_radio_turn_off(dev, 0); |
70 | } | 75 | } |
71 | } | 76 | } |
72 | mutex_unlock(&wl->mutex); | ||
73 | } | ||
74 | |||
75 | /* Called when the RFKILL toggled in software. | ||
76 | * This is called without locking. */ | ||
77 | static int b43legacy_rfkill_soft_set(void *data, bool blocked) | ||
78 | { | ||
79 | struct b43legacy_wldev *dev = data; | ||
80 | struct b43legacy_wl *wl = dev->wl; | ||
81 | int ret = -EINVAL; | ||
82 | 77 | ||
83 | if (!wl->rfkill.registered) | 78 | if (brought_up) { |
84 | return -EINVAL; | 79 | ssb_device_disable(dev->dev, 0); |
85 | 80 | ssb_bus_may_powerdown(bus); | |
86 | mutex_lock(&wl->mutex); | ||
87 | if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) | ||
88 | goto out_unlock; | ||
89 | |||
90 | if (!dev->radio_hw_enable) | ||
91 | goto out_unlock; | ||
92 | |||
93 | if (!blocked != dev->phy.radio_on) { | ||
94 | if (!blocked) | ||
95 | b43legacy_radio_turn_on(dev); | ||
96 | else | ||
97 | b43legacy_radio_turn_off(dev, 0); | ||
98 | } | 81 | } |
99 | ret = 0; | ||
100 | 82 | ||
101 | out_unlock: | ||
102 | mutex_unlock(&wl->mutex); | 83 | mutex_unlock(&wl->mutex); |
103 | return ret; | ||
104 | } | ||
105 | |||
106 | const char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) | ||
107 | { | ||
108 | struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); | ||
109 | |||
110 | if (!rfk->registered) | ||
111 | return NULL; | ||
112 | return rfkill_get_led_trigger_name(rfk->rfkill); | ||
113 | } | 84 | } |
114 | |||
115 | static const struct rfkill_ops b43legacy_rfkill_ops = { | ||
116 | .set_block = b43legacy_rfkill_soft_set, | ||
117 | .poll = b43legacy_rfkill_poll, | ||
118 | }; | ||
119 | |||
120 | void b43legacy_rfkill_init(struct b43legacy_wldev *dev) | ||
121 | { | ||
122 | struct b43legacy_wl *wl = dev->wl; | ||
123 | struct b43legacy_rfkill *rfk = &(wl->rfkill); | ||
124 | int err; | ||
125 | |||
126 | rfk->registered = 0; | ||
127 | |||
128 | snprintf(rfk->name, sizeof(rfk->name), | ||
129 | "b43legacy-%s", wiphy_name(wl->hw->wiphy)); | ||
130 | rfk->rfkill = rfkill_alloc(rfk->name, | ||
131 | dev->dev->dev, | ||
132 | RFKILL_TYPE_WLAN, | ||
133 | &b43legacy_rfkill_ops, dev); | ||
134 | if (!rfk->rfkill) | ||
135 | goto out_error; | ||
136 | |||
137 | err = rfkill_register(rfk->rfkill); | ||
138 | if (err) | ||
139 | goto err_free; | ||
140 | |||
141 | rfk->registered = 1; | ||
142 | |||
143 | return; | ||
144 | err_free: | ||
145 | rfkill_destroy(rfk->rfkill); | ||
146 | out_error: | ||
147 | rfk->registered = 0; | ||
148 | b43legacywarn(wl, "RF-kill button init failed\n"); | ||
149 | } | ||
150 | |||
151 | void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) | ||
152 | { | ||
153 | struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); | ||
154 | |||
155 | if (!rfk->registered) | ||
156 | return; | ||
157 | rfk->registered = 0; | ||
158 | |||
159 | rfkill_unregister(rfk->rfkill); | ||
160 | rfkill_destroy(rfk->rfkill); | ||
161 | rfk->rfkill = NULL; | ||
162 | } | ||
163 | |||
diff --git a/drivers/net/wireless/b43legacy/rfkill.h b/drivers/net/wireless/b43legacy/rfkill.h index adffc503a6a1..75585571c544 100644 --- a/drivers/net/wireless/b43legacy/rfkill.h +++ b/drivers/net/wireless/b43legacy/rfkill.h | |||
@@ -1,55 +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 | |||
10 | |||
11 | |||
12 | struct b43legacy_rfkill { | ||
13 | /* The RFKILL subsystem data structure */ | ||
14 | struct rfkill *rfkill; | ||
15 | /* Did initialization succeed? Used for freeing. */ | ||
16 | bool registered; | ||
17 | /* The unique name of this rfkill switch */ | ||
18 | char name[sizeof("b43legacy-phy4294967295")]; | ||
19 | }; | ||
20 | |||
21 | /* The init function returns void, because we are not interested | ||
22 | * in failing the b43 init process when rfkill init failed. */ | ||
23 | void b43legacy_rfkill_init(struct b43legacy_wldev *dev); | ||
24 | void b43legacy_rfkill_exit(struct b43legacy_wldev *dev); | ||
25 | |||
26 | const char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev); | ||
27 | |||
28 | |||
29 | #else /* CONFIG_B43LEGACY_RFKILL */ | ||
30 | /* No RFKILL support. */ | ||
31 | |||
32 | struct b43legacy_rfkill { | ||
33 | /* empty */ | ||
34 | }; | ||
35 | |||
36 | static inline void b43legacy_rfkill_alloc(struct b43legacy_wldev *dev) | ||
37 | { | ||
38 | } | ||
39 | static inline void b43legacy_rfkill_free(struct b43legacy_wldev *dev) | ||
40 | { | ||
41 | } | ||
42 | static inline void b43legacy_rfkill_init(struct b43legacy_wldev *dev) | ||
43 | { | ||
44 | } | ||
45 | static inline void b43legacy_rfkill_exit(struct b43legacy_wldev *dev) | ||
46 | { | ||
47 | } | ||
48 | static inline char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev) | ||
49 | { | ||
50 | return NULL; | ||
51 | } | ||
52 | |||
53 | #endif /* CONFIG_B43LEGACY_RFKILL */ | ||
54 | 10 | ||
55 | #endif /* B43legacy_RFKILL_H_ */ | 11 | #endif /* B43legacy_RFKILL_H_ */ |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 6fe259fcfb8f..029ccb6bdbaa 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -10,10 +10,6 @@ config IWLWIFI_LEDS | |||
10 | bool "Enable LED support in iwlagn and iwl3945 drivers" | 10 | bool "Enable LED support in iwlagn and iwl3945 drivers" |
11 | depends on IWLWIFI | 11 | depends on IWLWIFI |
12 | 12 | ||
13 | config IWLWIFI_RFKILL | ||
14 | def_bool y | ||
15 | depends on IWLWIFI && RFKILL | ||
16 | |||
17 | config IWLWIFI_SPECTRUM_MEASUREMENT | 13 | config IWLWIFI_SPECTRUM_MEASUREMENT |
18 | bool "Enable Spectrum Measurement in iwlagn driver" | 14 | bool "Enable Spectrum Measurement in iwlagn driver" |
19 | 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.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 4d8a325ea9d8..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 |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b77208de92ad..a5637c4aa85d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -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; |
@@ -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 | ||
@@ -2001,7 +1992,6 @@ static void iwl_bg_up(struct work_struct *data) | |||
2001 | mutex_lock(&priv->mutex); | 1992 | mutex_lock(&priv->mutex); |
2002 | __iwl_up(priv); | 1993 | __iwl_up(priv); |
2003 | mutex_unlock(&priv->mutex); | 1994 | mutex_unlock(&priv->mutex); |
2004 | iwl_rfkill_set_hw_state(priv); | ||
2005 | } | 1995 | } |
2006 | 1996 | ||
2007 | static void iwl_bg_restart(struct work_struct *data) | 1997 | static void iwl_bg_restart(struct work_struct *data) |
@@ -2179,8 +2169,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw) | |||
2179 | 2169 | ||
2180 | mutex_unlock(&priv->mutex); | 2170 | mutex_unlock(&priv->mutex); |
2181 | 2171 | ||
2182 | iwl_rfkill_set_hw_state(priv); | ||
2183 | |||
2184 | if (ret) | 2172 | if (ret) |
2185 | return ret; | 2173 | return ret; |
2186 | 2174 | ||
@@ -2775,7 +2763,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
2775 | INIT_WORK(&priv->up, iwl_bg_up); | 2763 | INIT_WORK(&priv->up, iwl_bg_up); |
2776 | INIT_WORK(&priv->restart, iwl_bg_restart); | 2764 | INIT_WORK(&priv->restart, iwl_bg_restart); |
2777 | INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); | 2765 | INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); |
2778 | INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); | ||
2779 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); | 2766 | INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); |
2780 | 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); |
2781 | 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); |
@@ -3046,12 +3033,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
3046 | else | 3033 | else |
3047 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 3034 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
3048 | 3035 | ||
3049 | err = iwl_rfkill_init(priv); | 3036 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
3050 | if (err) | 3037 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
3051 | IWL_ERR(priv, "Unable to initialize RFKILL system. " | ||
3052 | "Ignoring error: %d\n", err); | ||
3053 | else | ||
3054 | iwl_rfkill_set_hw_state(priv); | ||
3055 | 3038 | ||
3056 | iwl_power_initialize(priv); | 3039 | iwl_power_initialize(priv); |
3057 | return 0; | 3040 | return 0; |
@@ -3115,7 +3098,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
3115 | 3098 | ||
3116 | iwl_synchronize_irq(priv); | 3099 | iwl_synchronize_irq(priv); |
3117 | 3100 | ||
3118 | iwl_rfkill_unregister(priv); | ||
3119 | iwl_dealloc_ucode_pci(priv); | 3101 | iwl_dealloc_ucode_pci(priv); |
3120 | 3102 | ||
3121 | if (priv->rxq.bd) | 3103 | if (priv->rxq.bd) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 51cae4ec26a5..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" |
@@ -2211,126 +2210,6 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) | |||
2211 | } | 2210 | } |
2212 | EXPORT_SYMBOL(iwl_send_card_state); | 2211 | EXPORT_SYMBOL(iwl_send_card_state); |
2213 | 2212 | ||
2214 | void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv) | ||
2215 | { | ||
2216 | unsigned long flags; | ||
2217 | |||
2218 | if (test_bit(STATUS_RF_KILL_SW, &priv->status)) | ||
2219 | return; | ||
2220 | |||
2221 | IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO OFF\n"); | ||
2222 | |||
2223 | iwl_scan_cancel(priv); | ||
2224 | /* FIXME: This is a workaround for AP */ | ||
2225 | if (priv->iw_mode != NL80211_IFTYPE_AP) { | ||
2226 | spin_lock_irqsave(&priv->lock, flags); | ||
2227 | iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, | ||
2228 | CSR_UCODE_SW_BIT_RFKILL); | ||
2229 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2230 | /* call the host command only if no hw rf-kill set */ | ||
2231 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status) && | ||
2232 | iwl_is_ready(priv)) | ||
2233 | iwl_send_card_state(priv, | ||
2234 | CARD_STATE_CMD_DISABLE, 0); | ||
2235 | set_bit(STATUS_RF_KILL_SW, &priv->status); | ||
2236 | /* make sure mac80211 stop sending Tx frame */ | ||
2237 | if (priv->mac80211_registered) | ||
2238 | ieee80211_stop_queues(priv->hw); | ||
2239 | } | ||
2240 | } | ||
2241 | EXPORT_SYMBOL(iwl_radio_kill_sw_disable_radio); | ||
2242 | |||
2243 | int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv) | ||
2244 | { | ||
2245 | unsigned long flags; | ||
2246 | |||
2247 | if (!test_bit(STATUS_RF_KILL_SW, &priv->status)) | ||
2248 | return 0; | ||
2249 | |||
2250 | IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO ON\n"); | ||
2251 | |||
2252 | spin_lock_irqsave(&priv->lock, flags); | ||
2253 | iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||
2254 | |||
2255 | /* If the driver is up it will receive CARD_STATE_NOTIFICATION | ||
2256 | * notification where it will clear SW rfkill status. | ||
2257 | * Setting it here would break the handler. Only if the | ||
2258 | * interface is down we can set here since we don't | ||
2259 | * receive any further notification. | ||
2260 | */ | ||
2261 | if (!priv->is_open) | ||
2262 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
2263 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2264 | |||
2265 | /* wake up ucode */ | ||
2266 | msleep(10); | ||
2267 | |||
2268 | iwl_read32(priv, CSR_UCODE_DRV_GP1); | ||
2269 | spin_lock_irqsave(&priv->reg_lock, flags); | ||
2270 | if (!iwl_grab_nic_access(priv)) | ||
2271 | iwl_release_nic_access(priv); | ||
2272 | spin_unlock_irqrestore(&priv->reg_lock, flags); | ||
2273 | |||
2274 | if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { | ||
2275 | IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - " | ||
2276 | "disabled by HW switch\n"); | ||
2277 | return 0; | ||
2278 | } | ||
2279 | |||
2280 | /* when driver is up while rfkill is on, it wont receive | ||
2281 | * any CARD_STATE_NOTIFICATION notifications so we have to | ||
2282 | * restart it in here | ||
2283 | */ | ||
2284 | if (priv->is_open && !test_bit(STATUS_ALIVE, &priv->status)) { | ||
2285 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
2286 | if (!iwl_is_rfkill(priv)) | ||
2287 | queue_work(priv->workqueue, &priv->up); | ||
2288 | } | ||
2289 | |||
2290 | /* If the driver is already loaded, it will receive | ||
2291 | * CARD_STATE_NOTIFICATION notifications and the handler will | ||
2292 | * call restart to reload the driver. | ||
2293 | */ | ||
2294 | return 1; | ||
2295 | } | ||
2296 | EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio); | ||
2297 | |||
2298 | void iwl_bg_rf_kill(struct work_struct *work) | ||
2299 | { | ||
2300 | struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill); | ||
2301 | |||
2302 | wake_up_interruptible(&priv->wait_command_queue); | ||
2303 | |||
2304 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
2305 | return; | ||
2306 | |||
2307 | mutex_lock(&priv->mutex); | ||
2308 | |||
2309 | if (!iwl_is_rfkill(priv)) { | ||
2310 | IWL_DEBUG_RF_KILL(priv, | ||
2311 | "HW and/or SW RF Kill no longer active, restarting " | ||
2312 | "device\n"); | ||
2313 | if (!test_bit(STATUS_EXIT_PENDING, &priv->status) && | ||
2314 | priv->is_open) | ||
2315 | queue_work(priv->workqueue, &priv->restart); | ||
2316 | } else { | ||
2317 | /* make sure mac80211 stop sending Tx frame */ | ||
2318 | if (priv->mac80211_registered) | ||
2319 | ieee80211_stop_queues(priv->hw); | ||
2320 | |||
2321 | if (!test_bit(STATUS_RF_KILL_HW, &priv->status)) | ||
2322 | IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - " | ||
2323 | "disabled by SW switch\n"); | ||
2324 | else | ||
2325 | IWL_WARN(priv, "Radio Frequency Kill Switch is On:\n" | ||
2326 | "Kill switch must be turned off for " | ||
2327 | "wireless networking to work.\n"); | ||
2328 | } | ||
2329 | mutex_unlock(&priv->mutex); | ||
2330 | iwl_rfkill_set_hw_state(priv); | ||
2331 | } | ||
2332 | EXPORT_SYMBOL(iwl_bg_rf_kill); | ||
2333 | |||
2334 | void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, | 2213 | void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, |
2335 | struct iwl_rx_mem_buffer *rxb) | 2214 | struct iwl_rx_mem_buffer *rxb) |
2336 | { | 2215 | { |
@@ -2849,23 +2728,6 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
2849 | if (priv->cfg->ops->hcmd->set_rxon_chain) | 2728 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
2850 | priv->cfg->ops->hcmd->set_rxon_chain(priv); | 2729 | priv->cfg->ops->hcmd->set_rxon_chain(priv); |
2851 | 2730 | ||
2852 | if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) { | ||
2853 | if (conf->radio_enabled && | ||
2854 | iwl_radio_kill_sw_enable_radio(priv)) { | ||
2855 | IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - " | ||
2856 | "waiting for uCode\n"); | ||
2857 | goto out; | ||
2858 | } | ||
2859 | |||
2860 | if (!conf->radio_enabled) | ||
2861 | iwl_radio_kill_sw_disable_radio(priv); | ||
2862 | } | ||
2863 | |||
2864 | if (!conf->radio_enabled) { | ||
2865 | IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n"); | ||
2866 | goto out; | ||
2867 | } | ||
2868 | |||
2869 | if (!iwl_is_ready(priv)) { | 2731 | if (!iwl_is_ready(priv)) { |
2870 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); | 2732 | IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); |
2871 | goto out; | 2733 | goto out; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index b52d0fb16060..dabf663e36e5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -348,14 +348,6 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id); | |||
348 | ****************************************************/ | 348 | ****************************************************/ |
349 | 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); |
350 | 350 | ||
351 | /***************************************************** | ||
352 | * RF -Kill - here and not in iwl-rfkill.h to be available when | ||
353 | * RF-kill subsystem is not compiled. | ||
354 | ****************************************************/ | ||
355 | void iwl_bg_rf_kill(struct work_struct *work); | ||
356 | void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv); | ||
357 | int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv); | ||
358 | |||
359 | /******************************************************************************* | 351 | /******************************************************************************* |
360 | * Rate | 352 | * Rate |
361 | ******************************************************************************/ | 353 | ******************************************************************************/ |
@@ -498,7 +490,6 @@ void iwlcore_free_geos(struct iwl_priv *priv); | |||
498 | #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ | 490 | #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ |
499 | #define STATUS_INT_ENABLED 2 | 491 | #define STATUS_INT_ENABLED 2 |
500 | #define STATUS_RF_KILL_HW 3 | 492 | #define STATUS_RF_KILL_HW 3 |
501 | #define STATUS_RF_KILL_SW 4 | ||
502 | #define STATUS_INIT 5 | 493 | #define STATUS_INIT 5 |
503 | #define STATUS_ALIVE 6 | 494 | #define STATUS_ALIVE 6 |
504 | #define STATUS_READY 7 | 495 | #define STATUS_READY 7 |
@@ -533,11 +524,6 @@ static inline int iwl_is_init(struct iwl_priv *priv) | |||
533 | return test_bit(STATUS_INIT, &priv->status); | 524 | return test_bit(STATUS_INIT, &priv->status); |
534 | } | 525 | } |
535 | 526 | ||
536 | static inline int iwl_is_rfkill_sw(struct iwl_priv *priv) | ||
537 | { | ||
538 | return test_bit(STATUS_RF_KILL_SW, &priv->status); | ||
539 | } | ||
540 | |||
541 | static inline int iwl_is_rfkill_hw(struct iwl_priv *priv) | 527 | static inline int iwl_is_rfkill_hw(struct iwl_priv *priv) |
542 | { | 528 | { |
543 | return test_bit(STATUS_RF_KILL_HW, &priv->status); | 529 | return test_bit(STATUS_RF_KILL_HW, &priv->status); |
@@ -545,7 +531,7 @@ static inline int iwl_is_rfkill_hw(struct iwl_priv *priv) | |||
545 | 531 | ||
546 | static inline int iwl_is_rfkill(struct iwl_priv *priv) | 532 | static inline int iwl_is_rfkill(struct iwl_priv *priv) |
547 | { | 533 | { |
548 | return iwl_is_rfkill_hw(priv) || iwl_is_rfkill_sw(priv); | 534 | return iwl_is_rfkill_hw(priv); |
549 | } | 535 | } |
550 | 536 | ||
551 | 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 28c39cf8b126..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" |
@@ -936,9 +935,6 @@ struct iwl_priv { | |||
936 | * 4965's initialize alive response contains some calibration data. */ | 935 | * 4965's initialize alive response contains some calibration data. */ |
937 | struct iwl_init_alive_resp card_alive_init; | 936 | struct iwl_init_alive_resp card_alive_init; |
938 | struct iwl_alive_resp card_alive; | 937 | struct iwl_alive_resp card_alive; |
939 | #if defined(CONFIG_IWLWIFI_RFKILL) | ||
940 | struct rfkill *rfkill; | ||
941 | #endif | ||
942 | 938 | ||
943 | #ifdef CONFIG_IWLWIFI_LEDS | 939 | #ifdef CONFIG_IWLWIFI_LEDS |
944 | unsigned long last_blink_time; | 940 | unsigned long last_blink_time; |
@@ -1072,7 +1068,6 @@ struct iwl_priv { | |||
1072 | struct work_struct calibrated_work; | 1068 | struct work_struct calibrated_work; |
1073 | struct work_struct scan_completed; | 1069 | struct work_struct scan_completed; |
1074 | struct work_struct rx_replenish; | 1070 | struct work_struct rx_replenish; |
1075 | struct work_struct rf_kill; | ||
1076 | struct work_struct abort_scan; | 1071 | struct work_struct abort_scan; |
1077 | struct work_struct update_link_led; | 1072 | struct work_struct update_link_led; |
1078 | struct work_struct auth_work; | 1073 | struct work_struct auth_work; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c deleted file mode 100644 index 13149936fd26..000000000000 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c +++ /dev/null | |||
@@ -1,131 +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, bool blocked) | ||
40 | { | ||
41 | struct iwl_priv *priv = data; | ||
42 | |||
43 | if (!priv->rfkill) | ||
44 | return -EINVAL; | ||
45 | |||
46 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||
47 | return 0; | ||
48 | |||
49 | IWL_DEBUG_RF_KILL(priv, "received soft RFKILL: block=%d\n", blocked); | ||
50 | |||
51 | mutex_lock(&priv->mutex); | ||
52 | |||
53 | if (iwl_is_rfkill_hw(priv)) | ||
54 | goto out_unlock; | ||
55 | |||
56 | if (!blocked) | ||
57 | iwl_radio_kill_sw_enable_radio(priv); | ||
58 | else | ||
59 | iwl_radio_kill_sw_disable_radio(priv); | ||
60 | |||
61 | out_unlock: | ||
62 | mutex_unlock(&priv->mutex); | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static const struct rfkill_ops iwl_rfkill_ops = { | ||
67 | .set_block = iwl_rfkill_soft_rf_kill, | ||
68 | }; | ||
69 | |||
70 | int iwl_rfkill_init(struct iwl_priv *priv) | ||
71 | { | ||
72 | struct device *device = wiphy_dev(priv->hw->wiphy); | ||
73 | int ret = 0; | ||
74 | |||
75 | BUG_ON(device == NULL); | ||
76 | |||
77 | IWL_DEBUG_RF_KILL(priv, "Initializing RFKILL.\n"); | ||
78 | priv->rfkill = rfkill_alloc(priv->cfg->name, | ||
79 | device, | ||
80 | RFKILL_TYPE_WLAN, | ||
81 | &iwl_rfkill_ops, priv); | ||
82 | if (!priv->rfkill) { | ||
83 | IWL_ERR(priv, "Unable to allocate RFKILL device.\n"); | ||
84 | ret = -ENOMEM; | ||
85 | goto error; | ||
86 | } | ||
87 | |||
88 | ret = rfkill_register(priv->rfkill); | ||
89 | if (ret) { | ||
90 | IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret); | ||
91 | goto free_rfkill; | ||
92 | } | ||
93 | |||
94 | IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n"); | ||
95 | return 0; | ||
96 | |||
97 | free_rfkill: | ||
98 | rfkill_destroy(priv->rfkill); | ||
99 | priv->rfkill = NULL; | ||
100 | |||
101 | error: | ||
102 | IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n"); | ||
103 | return ret; | ||
104 | } | ||
105 | EXPORT_SYMBOL(iwl_rfkill_init); | ||
106 | |||
107 | void iwl_rfkill_unregister(struct iwl_priv *priv) | ||
108 | { | ||
109 | |||
110 | if (priv->rfkill) { | ||
111 | rfkill_unregister(priv->rfkill); | ||
112 | rfkill_destroy(priv->rfkill); | ||
113 | } | ||
114 | |||
115 | priv->rfkill = NULL; | ||
116 | } | ||
117 | EXPORT_SYMBOL(iwl_rfkill_unregister); | ||
118 | |||
119 | /* set RFKILL to the right state. */ | ||
120 | void iwl_rfkill_set_hw_state(struct iwl_priv *priv) | ||
121 | { | ||
122 | if (!priv->rfkill) | ||
123 | return; | ||
124 | |||
125 | if (rfkill_set_hw_state(priv->rfkill, | ||
126 | !!iwl_is_rfkill_hw(priv))) | ||
127 | iwl_radio_kill_sw_disable_radio(priv); | ||
128 | else | ||
129 | iwl_radio_kill_sw_enable_radio(priv); | ||
130 | } | ||
131 | 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/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 92fa1a39c446..83d31606dd00 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -1009,18 +1009,12 @@ static void iwl3945_rx_card_state_notif(struct iwl_priv *priv, | |||
1009 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 1009 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
1010 | 1010 | ||
1011 | 1011 | ||
1012 | if (flags & SW_CARD_DISABLED) | ||
1013 | set_bit(STATUS_RF_KILL_SW, &priv->status); | ||
1014 | else | ||
1015 | clear_bit(STATUS_RF_KILL_SW, &priv->status); | ||
1016 | |||
1017 | iwl_scan_cancel(priv); | 1012 | iwl_scan_cancel(priv); |
1018 | 1013 | ||
1019 | if ((test_bit(STATUS_RF_KILL_HW, &status) != | 1014 | if ((test_bit(STATUS_RF_KILL_HW, &status) != |
1020 | test_bit(STATUS_RF_KILL_HW, &priv->status)) || | 1015 | test_bit(STATUS_RF_KILL_HW, &priv->status))) |
1021 | (test_bit(STATUS_RF_KILL_SW, &status) != | 1016 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
1022 | test_bit(STATUS_RF_KILL_SW, &priv->status))) | 1017 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
1023 | queue_work(priv->workqueue, &priv->rf_kill); | ||
1024 | else | 1018 | else |
1025 | wake_up_interruptible(&priv->wait_command_queue); | 1019 | wake_up_interruptible(&priv->wait_command_queue); |
1026 | } | 1020 | } |
@@ -2586,8 +2580,6 @@ static void __iwl3945_down(struct iwl_priv *priv) | |||
2586 | if (!iwl_is_init(priv)) { | 2580 | if (!iwl_is_init(priv)) { |
2587 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << | 2581 | priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << |
2588 | STATUS_RF_KILL_HW | | 2582 | STATUS_RF_KILL_HW | |
2589 | test_bit(STATUS_RF_KILL_SW, &priv->status) << | ||
2590 | STATUS_RF_KILL_SW | | ||
2591 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 2583 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
2592 | STATUS_GEO_CONFIGURED | | 2584 | STATUS_GEO_CONFIGURED | |
2593 | test_bit(STATUS_EXIT_PENDING, &priv->status) << | 2585 | test_bit(STATUS_EXIT_PENDING, &priv->status) << |
@@ -2596,11 +2588,9 @@ static void __iwl3945_down(struct iwl_priv *priv) | |||
2596 | } | 2588 | } |
2597 | 2589 | ||
2598 | /* ...otherwise clear out all the status bits but the RF Kill | 2590 | /* ...otherwise clear out all the status bits but the RF Kill |
2599 | * bits and continue taking the NIC down. */ | 2591 | * bit and continue taking the NIC down. */ |
2600 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << | 2592 | priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << |
2601 | STATUS_RF_KILL_HW | | 2593 | STATUS_RF_KILL_HW | |
2602 | test_bit(STATUS_RF_KILL_SW, &priv->status) << | ||
2603 | STATUS_RF_KILL_SW | | ||
2604 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | 2594 | test_bit(STATUS_GEO_CONFIGURED, &priv->status) << |
2605 | STATUS_GEO_CONFIGURED | | 2595 | STATUS_GEO_CONFIGURED | |
2606 | test_bit(STATUS_FW_ERROR, &priv->status) << | 2596 | test_bit(STATUS_FW_ERROR, &priv->status) << |
@@ -2657,12 +2647,6 @@ static int __iwl3945_up(struct iwl_priv *priv) | |||
2657 | return -EIO; | 2647 | return -EIO; |
2658 | } | 2648 | } |
2659 | 2649 | ||
2660 | if (test_bit(STATUS_RF_KILL_SW, &priv->status)) { | ||
2661 | IWL_WARN(priv, "Radio disabled by SW RF kill (module " | ||
2662 | "parameter)\n"); | ||
2663 | return -ENODEV; | ||
2664 | } | ||
2665 | |||
2666 | 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) { |
2667 | IWL_ERR(priv, "ucode not available for device bring up\n"); | 2651 | IWL_ERR(priv, "ucode not available for device bring up\n"); |
2668 | return -EIO; | 2652 | return -EIO; |
@@ -2779,15 +2763,14 @@ static void iwl3945_rfkill_poll(struct work_struct *data) | |||
2779 | { | 2763 | { |
2780 | struct iwl_priv *priv = | 2764 | struct iwl_priv *priv = |
2781 | container_of(data, struct iwl_priv, rfkill_poll.work); | 2765 | container_of(data, struct iwl_priv, rfkill_poll.work); |
2782 | unsigned long status = priv->status; | ||
2783 | 2766 | ||
2784 | 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) |
2785 | clear_bit(STATUS_RF_KILL_HW, &priv->status); | 2768 | clear_bit(STATUS_RF_KILL_HW, &priv->status); |
2786 | else | 2769 | else |
2787 | set_bit(STATUS_RF_KILL_HW, &priv->status); | 2770 | set_bit(STATUS_RF_KILL_HW, &priv->status); |
2788 | 2771 | ||
2789 | 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, |
2790 | queue_work(priv->workqueue, &priv->rf_kill); | 2773 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
2791 | 2774 | ||
2792 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, | 2775 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, |
2793 | round_jiffies_relative(2 * HZ)); | 2776 | round_jiffies_relative(2 * HZ)); |
@@ -3019,7 +3002,6 @@ static void iwl3945_bg_up(struct work_struct *data) | |||
3019 | mutex_lock(&priv->mutex); | 3002 | mutex_lock(&priv->mutex); |
3020 | __iwl3945_up(priv); | 3003 | __iwl3945_up(priv); |
3021 | mutex_unlock(&priv->mutex); | 3004 | mutex_unlock(&priv->mutex); |
3022 | iwl_rfkill_set_hw_state(priv); | ||
3023 | } | 3005 | } |
3024 | 3006 | ||
3025 | static void iwl3945_bg_restart(struct work_struct *data) | 3007 | static void iwl3945_bg_restart(struct work_struct *data) |
@@ -3182,8 +3164,6 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw) | |||
3182 | 3164 | ||
3183 | mutex_unlock(&priv->mutex); | 3165 | mutex_unlock(&priv->mutex); |
3184 | 3166 | ||
3185 | iwl_rfkill_set_hw_state(priv); | ||
3186 | |||
3187 | if (ret) | 3167 | if (ret) |
3188 | goto out_release_irq; | 3168 | goto out_release_irq; |
3189 | 3169 | ||
@@ -3836,7 +3816,6 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv) | |||
3836 | INIT_WORK(&priv->up, iwl3945_bg_up); | 3816 | INIT_WORK(&priv->up, iwl3945_bg_up); |
3837 | INIT_WORK(&priv->restart, iwl3945_bg_restart); | 3817 | INIT_WORK(&priv->restart, iwl3945_bg_restart); |
3838 | INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); | 3818 | INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish); |
3839 | INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill); | ||
3840 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); | 3819 | INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update); |
3841 | 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); |
3842 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); | 3821 | INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); |
@@ -4203,13 +4182,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
4203 | if (err) | 4182 | if (err) |
4204 | 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); |
4205 | 4184 | ||
4206 | err = iwl_rfkill_init(priv); | ||
4207 | if (err) | ||
4208 | IWL_ERR(priv, "Unable to initialize RFKILL system. " | ||
4209 | "Ignoring error: %d\n", err); | ||
4210 | else | ||
4211 | iwl_rfkill_set_hw_state(priv); | ||
4212 | |||
4213 | /* Start monitoring the killswitch */ | 4185 | /* Start monitoring the killswitch */ |
4214 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, | 4186 | queue_delayed_work(priv->workqueue, &priv->rfkill_poll, |
4215 | 2 * HZ); | 4187 | 2 * HZ); |
@@ -4275,7 +4247,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
4275 | 4247 | ||
4276 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); | 4248 | sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group); |
4277 | 4249 | ||
4278 | iwl_rfkill_unregister(priv); | ||
4279 | cancel_delayed_work_sync(&priv->rfkill_poll); | 4250 | cancel_delayed_work_sync(&priv->rfkill_poll); |
4280 | 4251 | ||
4281 | iwl3945_dealloc_ucode_pci(priv); | 4252 | iwl3945_dealloc_ucode_pci(priv); |
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index ea23c5de1420..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 | ||
@@ -130,12 +122,10 @@ static void spu_transaction_init(struct if_spi_card *card) | |||
130 | * 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. */ |
131 | ndelay(400); | 123 | ndelay(400); |
132 | } | 124 | } |
133 | gpio_set_value(card->gpio_cs, 0); /* assert CS */ | ||
134 | } | 125 | } |
135 | 126 | ||
136 | static void spu_transaction_finish(struct if_spi_card *card) | 127 | static void spu_transaction_finish(struct if_spi_card *card) |
137 | { | 128 | { |
138 | gpio_set_value(card->gpio_cs, 1); /* drop CS */ | ||
139 | card->prev_xfer_time = jiffies; | 129 | card->prev_xfer_time = jiffies; |
140 | } | 130 | } |
141 | 131 | ||
@@ -145,6 +135,13 @@ static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) | |||
145 | { | 135 | { |
146 | int err = 0; | 136 | int err = 0; |
147 | u16 reg_out = cpu_to_le16(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)); | ||
148 | 145 | ||
149 | /* 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 |
150 | * doesn't care about the last one. */ | 147 | * doesn't care about the last one. */ |
@@ -153,13 +150,16 @@ static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) | |||
153 | spu_transaction_init(card); | 150 | spu_transaction_init(card); |
154 | 151 | ||
155 | /* write SPU register index */ | 152 | /* write SPU register index */ |
156 | err = spi_write(card->spi, (u8 *)®_out, sizeof(u16)); | 153 | reg_trans.tx_buf = ®_out; |
157 | if (err) | 154 | reg_trans.len = sizeof(reg_out); |
158 | goto out; | ||
159 | 155 | ||
160 | err = spi_write(card->spi, buf, len); | 156 | data_trans.tx_buf = buf; |
157 | data_trans.len = len; | ||
161 | 158 | ||
162 | out: | 159 | spi_message_add_tail(®_trans, &m); |
160 | spi_message_add_tail(&data_trans, &m); | ||
161 | |||
162 | err = spi_sync(card->spi, &m); | ||
163 | spu_transaction_finish(card); | 163 | spu_transaction_finish(card); |
164 | return err; | 164 | return err; |
165 | } | 165 | } |
@@ -186,10 +186,13 @@ static inline int spu_reg_is_port_reg(u16 reg) | |||
186 | 186 | ||
187 | 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) |
188 | { | 188 | { |
189 | unsigned int i, delay; | 189 | unsigned int delay; |
190 | int err = 0; | 190 | int err = 0; |
191 | u16 zero = 0; | ||
192 | u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK); | 191 | u16 reg_out = cpu_to_le16(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; | ||
193 | 196 | ||
194 | /* 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 |
195 | * don't care about the last one. */ | 198 | * don't care about the last one. */ |
@@ -197,29 +200,34 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) | |||
197 | 200 | ||
198 | spu_transaction_init(card); | 201 | spu_transaction_init(card); |
199 | 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 | |||
200 | /* write SPU register index */ | 208 | /* write SPU register index */ |
201 | err = spi_write(card->spi, (u8 *)®_out, sizeof(u16)); | 209 | reg_trans.tx_buf = ®_out; |
202 | if (err) | 210 | reg_trans.len = sizeof(reg_out); |
203 | goto out; | 211 | spi_message_add_tail(®_trans, &m); |
204 | 212 | ||
205 | delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay : | 213 | delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay : |
206 | card->spu_reg_delay; | 214 | card->spu_reg_delay; |
207 | if (card->use_dummy_writes) { | 215 | if (card->use_dummy_writes) { |
208 | /* Clock in dummy cycles while the SPU fills the FIFO */ | 216 | /* Clock in dummy cycles while the SPU fills the FIFO */ |
209 | for (i = 0; i < delay / 16; ++i) { | 217 | dummy_trans.len = delay / 8; |
210 | err = spi_write(card->spi, (u8 *)&zero, sizeof(u16)); | 218 | spi_message_add_tail(&dummy_trans, &m); |
211 | if (err) | ||
212 | return err; | ||
213 | } | ||
214 | } else { | 219 | } else { |
215 | /* Busy-wait while the SPU fills the FIFO */ | 220 | /* Busy-wait while the SPU fills the FIFO */ |
216 | ndelay(100 + (delay * 10)); | 221 | reg_trans.delay_usecs = |
222 | DIV_ROUND_UP((100 + (delay * 10)), 1000); | ||
217 | } | 223 | } |
218 | 224 | ||
219 | /* read in data */ | 225 | /* read in data */ |
220 | 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); | ||
221 | 229 | ||
222 | out: | 230 | err = spi_sync(card->spi, &m); |
223 | spu_transaction_finish(card); | 231 | spu_transaction_finish(card); |
224 | return err; | 232 | return err; |
225 | } | 233 | } |
@@ -1049,7 +1057,6 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1049 | spi_set_drvdata(spi, card); | 1057 | spi_set_drvdata(spi, card); |
1050 | card->pdata = pdata; | 1058 | card->pdata = pdata; |
1051 | card->spi = spi; | 1059 | card->spi = spi; |
1052 | card->gpio_cs = pdata->gpio_cs; | ||
1053 | card->prev_xfer_time = jiffies; | 1060 | card->prev_xfer_time = jiffies; |
1054 | 1061 | ||
1055 | sema_init(&card->spi_ready, 0); | 1062 | sema_init(&card->spi_ready, 0); |
@@ -1058,26 +1065,18 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1058 | INIT_LIST_HEAD(&card->data_packet_list); | 1065 | INIT_LIST_HEAD(&card->data_packet_list); |
1059 | spin_lock_init(&card->buffer_lock); | 1066 | spin_lock_init(&card->buffer_lock); |
1060 | 1067 | ||
1061 | /* set up GPIO CS line. TODO: use regular CS line */ | ||
1062 | err = gpio_request(card->gpio_cs, "if_spi_gpio_chip_select"); | ||
1063 | if (err) | ||
1064 | goto free_card; | ||
1065 | err = gpio_direction_output(card->gpio_cs, 1); | ||
1066 | if (err) | ||
1067 | goto free_gpio; | ||
1068 | |||
1069 | /* Initialize the SPI Interface Unit */ | 1068 | /* Initialize the SPI Interface Unit */ |
1070 | err = spu_init(card, pdata->use_dummy_writes); | 1069 | err = spu_init(card, pdata->use_dummy_writes); |
1071 | if (err) | 1070 | if (err) |
1072 | goto free_gpio; | 1071 | goto free_card; |
1073 | 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); |
1074 | if (err) | 1073 | if (err) |
1075 | goto free_gpio; | 1074 | goto free_card; |
1076 | 1075 | ||
1077 | /* Firmware load */ | 1076 | /* Firmware load */ |
1078 | err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch); | 1077 | err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch); |
1079 | if (err) | 1078 | if (err) |
1080 | goto free_gpio; | 1079 | goto free_card; |
1081 | if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC) | 1080 | if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC) |
1082 | lbs_deb_spi("Firmware is already loaded for " | 1081 | lbs_deb_spi("Firmware is already loaded for " |
1083 | "Marvell WLAN 802.11 adapter\n"); | 1082 | "Marvell WLAN 802.11 adapter\n"); |
@@ -1085,7 +1084,7 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1085 | err = if_spi_calculate_fw_names(card->card_id, | 1084 | err = if_spi_calculate_fw_names(card->card_id, |
1086 | card->helper_fw_name, card->main_fw_name); | 1085 | card->helper_fw_name, card->main_fw_name); |
1087 | if (err) | 1086 | if (err) |
1088 | goto free_gpio; | 1087 | goto free_card; |
1089 | 1088 | ||
1090 | lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " | 1089 | lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " |
1091 | "(chip_id = 0x%04x, chip_rev = 0x%02x) " | 1090 | "(chip_id = 0x%04x, chip_rev = 0x%02x) " |
@@ -1096,23 +1095,23 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1096 | spi->max_speed_hz); | 1095 | spi->max_speed_hz); |
1097 | err = if_spi_prog_helper_firmware(card); | 1096 | err = if_spi_prog_helper_firmware(card); |
1098 | if (err) | 1097 | if (err) |
1099 | goto free_gpio; | 1098 | goto free_card; |
1100 | err = if_spi_prog_main_firmware(card); | 1099 | err = if_spi_prog_main_firmware(card); |
1101 | if (err) | 1100 | if (err) |
1102 | goto free_gpio; | 1101 | goto free_card; |
1103 | 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"); |
1104 | } | 1103 | } |
1105 | 1104 | ||
1106 | err = spu_set_interrupt_mode(card, 0, 1); | 1105 | err = spu_set_interrupt_mode(card, 0, 1); |
1107 | if (err) | 1106 | if (err) |
1108 | goto free_gpio; | 1107 | goto free_card; |
1109 | 1108 | ||
1110 | /* Register our card with libertas. | 1109 | /* Register our card with libertas. |
1111 | * This will call alloc_etherdev */ | 1110 | * This will call alloc_etherdev */ |
1112 | priv = lbs_add_card(card, &spi->dev); | 1111 | priv = lbs_add_card(card, &spi->dev); |
1113 | if (!priv) { | 1112 | if (!priv) { |
1114 | err = -ENOMEM; | 1113 | err = -ENOMEM; |
1115 | goto free_gpio; | 1114 | goto free_card; |
1116 | } | 1115 | } |
1117 | card->priv = priv; | 1116 | card->priv = priv; |
1118 | priv->card = card; | 1117 | priv->card = card; |
@@ -1157,8 +1156,6 @@ terminate_thread: | |||
1157 | if_spi_terminate_spi_thread(card); | 1156 | if_spi_terminate_spi_thread(card); |
1158 | remove_card: | 1157 | remove_card: |
1159 | lbs_remove_card(priv); /* will call free_netdev */ | 1158 | lbs_remove_card(priv); /* will call free_netdev */ |
1160 | free_gpio: | ||
1161 | gpio_free(card->gpio_cs); | ||
1162 | free_card: | 1159 | free_card: |
1163 | free_if_spi_card(card); | 1160 | free_if_spi_card(card); |
1164 | out: | 1161 | out: |
@@ -1179,7 +1176,6 @@ static int __devexit libertas_spi_remove(struct spi_device *spi) | |||
1179 | free_irq(spi->irq, card); | 1176 | free_irq(spi->irq, card); |
1180 | if_spi_terminate_spi_thread(card); | 1177 | if_spi_terminate_spi_thread(card); |
1181 | lbs_remove_card(priv); /* will call free_netdev */ | 1178 | lbs_remove_card(priv); /* will call free_netdev */ |
1182 | gpio_free(card->gpio_cs); | ||
1183 | if (card->pdata->teardown) | 1179 | if (card->pdata->teardown) |
1184 | card->pdata->teardown(spi); | 1180 | card->pdata->teardown(spi); |
1185 | free_if_spi_card(card); | 1181 | free_if_spi_card(card); |
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 | }; |