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 | |
| parent | 51611a120e8120290152edd7d0020d22a7f4b4a3 (diff) | |
| parent | 2f0accc13520b2644b85f80aedce10d10d88b0ca (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
69 files changed, 1275 insertions, 1482 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 | }; |
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index b618fa51db2d..09a503e5da6a 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
| @@ -988,7 +988,6 @@ static struct rfkill *acer_rfkill_register(struct device *dev, | |||
| 988 | char *name, u32 cap) | 988 | char *name, u32 cap) |
| 989 | { | 989 | { |
| 990 | int err; | 990 | int err; |
| 991 | u32 state; | ||
| 992 | struct rfkill *rfkill_dev; | 991 | struct rfkill *rfkill_dev; |
| 993 | 992 | ||
| 994 | rfkill_dev = rfkill_alloc(name, dev, type, | 993 | rfkill_dev = rfkill_alloc(name, dev, type, |
| @@ -996,8 +995,6 @@ static struct rfkill *acer_rfkill_register(struct device *dev, | |||
| 996 | (void *)(unsigned long)cap); | 995 | (void *)(unsigned long)cap); |
| 997 | if (!rfkill_dev) | 996 | if (!rfkill_dev) |
| 998 | return ERR_PTR(-ENOMEM); | 997 | return ERR_PTR(-ENOMEM); |
| 999 | get_u32(&state, cap); | ||
| 1000 | rfkill_set_sw_state(rfkill_dev, !state); | ||
| 1001 | 998 | ||
| 1002 | err = rfkill_register(rfkill_dev); | 999 | err = rfkill_register(rfkill_dev); |
| 1003 | if (err) { | 1000 | if (err) { |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 1208d0cedd15..03bf522bd7ab 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
| @@ -675,8 +675,8 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
| 675 | if (!ehotk->eeepc_wlan_rfkill) | 675 | if (!ehotk->eeepc_wlan_rfkill) |
| 676 | goto wlan_fail; | 676 | goto wlan_fail; |
| 677 | 677 | ||
| 678 | rfkill_set_global_sw_state(RFKILL_TYPE_WLAN, | 678 | rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, |
| 679 | get_acpi(CM_ASL_WLAN) != 1); | 679 | get_acpi(CM_ASL_WLAN) != 1); |
| 680 | result = rfkill_register(ehotk->eeepc_wlan_rfkill); | 680 | result = rfkill_register(ehotk->eeepc_wlan_rfkill); |
| 681 | if (result) | 681 | if (result) |
| 682 | goto wlan_fail; | 682 | goto wlan_fail; |
| @@ -693,8 +693,8 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
| 693 | if (!ehotk->eeepc_bluetooth_rfkill) | 693 | if (!ehotk->eeepc_bluetooth_rfkill) |
| 694 | goto bluetooth_fail; | 694 | goto bluetooth_fail; |
| 695 | 695 | ||
| 696 | rfkill_set_global_sw_state(RFKILL_TYPE_BLUETOOTH, | 696 | rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill, |
| 697 | get_acpi(CM_ASL_BLUETOOTH) != 1); | 697 | get_acpi(CM_ASL_BLUETOOTH) != 1); |
| 698 | result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); | 698 | result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); |
| 699 | if (result) | 699 | if (result) |
| 700 | goto bluetooth_fail; | 700 | goto bluetooth_fail; |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 8d931145cbfa..16fffe44e333 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
| @@ -422,7 +422,6 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) | |||
| 422 | RFKILL_TYPE_WLAN, | 422 | RFKILL_TYPE_WLAN, |
| 423 | &hp_wmi_rfkill_ops, | 423 | &hp_wmi_rfkill_ops, |
| 424 | (void *) 0); | 424 | (void *) 0); |
| 425 | rfkill_set_sw_state(wifi_rfkill, hp_wmi_wifi_state()); | ||
| 426 | err = rfkill_register(wifi_rfkill); | 425 | err = rfkill_register(wifi_rfkill); |
| 427 | if (err) | 426 | if (err) |
| 428 | goto register_wifi_error; | 427 | goto register_wifi_error; |
| @@ -433,8 +432,6 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) | |||
| 433 | RFKILL_TYPE_BLUETOOTH, | 432 | RFKILL_TYPE_BLUETOOTH, |
| 434 | &hp_wmi_rfkill_ops, | 433 | &hp_wmi_rfkill_ops, |
| 435 | (void *) 1); | 434 | (void *) 1); |
| 436 | rfkill_set_sw_state(bluetooth_rfkill, | ||
| 437 | hp_wmi_bluetooth_state()); | ||
| 438 | err = rfkill_register(bluetooth_rfkill); | 435 | err = rfkill_register(bluetooth_rfkill); |
| 439 | if (err) | 436 | if (err) |
| 440 | goto register_bluetooth_error; | 437 | goto register_bluetooth_error; |
| @@ -445,7 +442,6 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) | |||
| 445 | RFKILL_TYPE_WWAN, | 442 | RFKILL_TYPE_WWAN, |
| 446 | &hp_wmi_rfkill_ops, | 443 | &hp_wmi_rfkill_ops, |
| 447 | (void *) 2); | 444 | (void *) 2); |
| 448 | rfkill_set_sw_state(wwan_rfkill, hp_wmi_wwan_state()); | ||
| 449 | err = rfkill_register(wwan_rfkill); | 445 | err = rfkill_register(wwan_rfkill); |
| 450 | if (err) | 446 | if (err) |
| 451 | goto register_wwan_err; | 447 | goto register_wwan_err; |
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index aec0b27fd774..e48d9a4506ff 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
| @@ -1114,7 +1114,6 @@ static int sony_nc_setup_rfkill(struct acpi_device *device, | |||
| 1114 | return err; | 1114 | return err; |
| 1115 | } | 1115 | } |
| 1116 | sony_rfkill_devices[nc_type] = rfk; | 1116 | sony_rfkill_devices[nc_type] = rfk; |
| 1117 | sony_nc_rfkill_set((void *)nc_type, false); | ||
| 1118 | return err; | 1117 | return err; |
| 1119 | } | 1118 | } |
| 1120 | 1119 | ||
| @@ -1135,8 +1134,7 @@ static void sony_nc_rfkill_update() | |||
| 1135 | 1134 | ||
| 1136 | if (hwblock) { | 1135 | if (hwblock) { |
| 1137 | if (rfkill_set_hw_state(sony_rfkill_devices[i], true)) | 1136 | if (rfkill_set_hw_state(sony_rfkill_devices[i], true)) |
| 1138 | sony_nc_rfkill_set(sony_rfkill_devices[i], | 1137 | sony_nc_rfkill_set((void *)i, true); |
| 1139 | true); | ||
| 1140 | continue; | 1138 | continue; |
| 1141 | } | 1139 | } |
| 1142 | 1140 | ||
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index cfcafa4e9473..86e958539f46 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
| @@ -1168,21 +1168,6 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, | |||
| 1168 | 1168 | ||
| 1169 | BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]); | 1169 | BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]); |
| 1170 | 1170 | ||
| 1171 | initial_sw_status = (tp_rfkops->get_status)(); | ||
| 1172 | if (initial_sw_status < 0) { | ||
| 1173 | printk(TPACPI_ERR | ||
| 1174 | "failed to read initial state for %s, error %d; " | ||
| 1175 | "will turn radio off\n", name, initial_sw_status); | ||
| 1176 | } else { | ||
| 1177 | initial_sw_state = (initial_sw_status == TPACPI_RFK_RADIO_OFF); | ||
| 1178 | if (set_default) { | ||
| 1179 | /* try to set the initial state as the default for the | ||
| 1180 | * rfkill type, since we ask the firmware to preserve | ||
| 1181 | * it across S5 in NVRAM */ | ||
| 1182 | rfkill_set_global_sw_state(rfktype, initial_sw_state); | ||
| 1183 | } | ||
| 1184 | } | ||
| 1185 | |||
| 1186 | atp_rfk = kzalloc(sizeof(struct tpacpi_rfk), GFP_KERNEL); | 1171 | atp_rfk = kzalloc(sizeof(struct tpacpi_rfk), GFP_KERNEL); |
| 1187 | if (atp_rfk) | 1172 | if (atp_rfk) |
| 1188 | atp_rfk->rfkill = rfkill_alloc(name, | 1173 | atp_rfk->rfkill = rfkill_alloc(name, |
| @@ -1200,8 +1185,20 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, | |||
| 1200 | atp_rfk->id = id; | 1185 | atp_rfk->id = id; |
| 1201 | atp_rfk->ops = tp_rfkops; | 1186 | atp_rfk->ops = tp_rfkops; |
| 1202 | 1187 | ||
| 1203 | rfkill_set_states(atp_rfk->rfkill, initial_sw_state, | 1188 | initial_sw_status = (tp_rfkops->get_status)(); |
| 1204 | tpacpi_rfk_check_hwblock_state()); | 1189 | if (initial_sw_status < 0) { |
| 1190 | printk(TPACPI_ERR | ||
| 1191 | "failed to read initial state for %s, error %d\n", | ||
| 1192 | name, initial_sw_status); | ||
| 1193 | } else { | ||
| 1194 | initial_sw_state = (initial_sw_status == TPACPI_RFK_RADIO_OFF); | ||
| 1195 | if (set_default) { | ||
| 1196 | /* try to keep the initial state, since we ask the | ||
| 1197 | * firmware to preserve it across S5 in NVRAM */ | ||
| 1198 | rfkill_set_sw_state(atp_rfk->rfkill, initial_sw_state); | ||
| 1199 | } | ||
| 1200 | } | ||
| 1201 | rfkill_set_hw_state(atp_rfk->rfkill, tpacpi_rfk_check_hwblock_state()); | ||
| 1205 | 1202 | ||
| 1206 | res = rfkill_register(atp_rfk->rfkill); | 1203 | res = rfkill_register(atp_rfk->rfkill); |
| 1207 | if (res < 0) { | 1204 | if (res < 0) { |
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index d7e818ad0bc4..16e39c7a67fc 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h | |||
| @@ -157,8 +157,14 @@ struct rfkill * __must_check rfkill_alloc(const char *name, | |||
| 157 | * @rfkill: rfkill structure to be registered | 157 | * @rfkill: rfkill structure to be registered |
| 158 | * | 158 | * |
| 159 | * This function should be called by the transmitter driver to register | 159 | * This function should be called by the transmitter driver to register |
| 160 | * the rfkill structure needs to be registered. Before calling this function | 160 | * the rfkill structure. Before calling this function the driver needs |
| 161 | * the driver needs to be ready to service method calls from rfkill. | 161 | * to be ready to service method calls from rfkill. |
| 162 | * | ||
| 163 | * If the software blocked state is not set before registration, | ||
| 164 | * set_block will be called to initialize it to a default value. | ||
| 165 | * | ||
| 166 | * If the hardware blocked state is not set before registration, | ||
| 167 | * it is assumed to be unblocked. | ||
| 162 | */ | 168 | */ |
| 163 | int __must_check rfkill_register(struct rfkill *rfkill); | 169 | int __must_check rfkill_register(struct rfkill *rfkill); |
| 164 | 170 | ||
| @@ -206,7 +212,7 @@ void rfkill_destroy(struct rfkill *rfkill); | |||
| 206 | * | 212 | * |
| 207 | * rfkill drivers that get events when the hard-blocked state changes | 213 | * rfkill drivers that get events when the hard-blocked state changes |
| 208 | * use this function to notify the rfkill core (and through that also | 214 | * use this function to notify the rfkill core (and through that also |
| 209 | * userspace) of the current state -- they should also use this after | 215 | * userspace) of the current state. They should also use this after |
| 210 | * resume if the state could have changed. | 216 | * resume if the state could have changed. |
| 211 | * | 217 | * |
| 212 | * You need not (but may) call this function if poll_state is assigned. | 218 | * You need not (but may) call this function if poll_state is assigned. |
| @@ -228,8 +234,9 @@ bool __must_check rfkill_set_hw_state(struct rfkill *rfkill, bool blocked); | |||
| 228 | * rfkill drivers that get events when the soft-blocked state changes | 234 | * rfkill drivers that get events when the soft-blocked state changes |
| 229 | * (yes, some platforms directly act on input but allow changing again) | 235 | * (yes, some platforms directly act on input but allow changing again) |
| 230 | * use this function to notify the rfkill core (and through that also | 236 | * use this function to notify the rfkill core (and through that also |
| 231 | * userspace) of the current state -- they should also use this after | 237 | * userspace) of the current state. It is not necessary to notify on |
| 232 | * resume if the state could have changed. | 238 | * resume; since hibernation can always change the soft-blocked state, |
| 239 | * the rfkill core will unconditionally restore the previous state. | ||
| 233 | * | 240 | * |
| 234 | * This function can be called in any context, even from within rfkill | 241 | * This function can be called in any context, even from within rfkill |
| 235 | * callbacks. | 242 | * callbacks. |
| @@ -251,19 +258,6 @@ bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked); | |||
| 251 | void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw); | 258 | void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw); |
| 252 | 259 | ||
| 253 | /** | 260 | /** |
| 254 | * rfkill_set_global_sw_state - set global sw block default | ||
| 255 | * @type: rfkill type to set default for | ||
| 256 | * @blocked: default to set | ||
| 257 | * | ||
| 258 | * This function sets the global default -- use at boot if your platform has | ||
| 259 | * an rfkill switch. If not early enough this call may be ignored. | ||
| 260 | * | ||
| 261 | * XXX: instead of ignoring -- how about just updating all currently | ||
| 262 | * registered drivers? | ||
| 263 | */ | ||
| 264 | void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked); | ||
| 265 | |||
| 266 | /** | ||
| 267 | * rfkill_blocked - query rfkill block | 261 | * rfkill_blocked - query rfkill block |
| 268 | * | 262 | * |
| 269 | * @rfkill: rfkill struct to query | 263 | * @rfkill: rfkill struct to query |
| @@ -317,11 +311,6 @@ static inline void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) | |||
| 317 | { | 311 | { |
| 318 | } | 312 | } |
| 319 | 313 | ||
| 320 | static inline void rfkill_set_global_sw_state(const enum rfkill_type type, | ||
| 321 | bool blocked) | ||
| 322 | { | ||
| 323 | } | ||
| 324 | |||
| 325 | static inline bool rfkill_blocked(struct rfkill *rfkill) | 314 | static inline bool rfkill_blocked(struct rfkill *rfkill) |
| 326 | { | 315 | { |
| 327 | return false; | 316 | return false; |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index f1c93b878b3b..fa51293f2708 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
| @@ -304,9 +304,6 @@ typedef unsigned char *sk_buff_data_t; | |||
| 304 | * @tc_verd: traffic control verdict | 304 | * @tc_verd: traffic control verdict |
| 305 | * @ndisc_nodetype: router type (from link layer) | 305 | * @ndisc_nodetype: router type (from link layer) |
| 306 | * @do_not_encrypt: set to prevent encryption of this frame | 306 | * @do_not_encrypt: set to prevent encryption of this frame |
| 307 | * @requeue: set to indicate that the wireless core should attempt | ||
| 308 | * a software retry on this frame if we failed to | ||
| 309 | * receive an ACK for it | ||
| 310 | * @dma_cookie: a cookie to one of several possible DMA operations | 307 | * @dma_cookie: a cookie to one of several possible DMA operations |
| 311 | * done by skb DMA functions | 308 | * done by skb DMA functions |
| 312 | * @secmark: security marking | 309 | * @secmark: security marking |
| @@ -380,7 +377,6 @@ struct sk_buff { | |||
| 380 | #endif | 377 | #endif |
| 381 | #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) | 378 | #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) |
| 382 | __u8 do_not_encrypt:1; | 379 | __u8 do_not_encrypt:1; |
| 383 | __u8 requeue:1; | ||
| 384 | #endif | 380 | #endif |
| 385 | /* 0/13/14 bit hole */ | 381 | /* 0/13/14 bit hole */ |
| 386 | 382 | ||
diff --git a/include/linux/spi/libertas_spi.h b/include/linux/spi/libertas_spi.h index 79506f5f9e67..1b5d5384fcd3 100644 --- a/include/linux/spi/libertas_spi.h +++ b/include/linux/spi/libertas_spi.h | |||
| @@ -22,9 +22,6 @@ struct libertas_spi_platform_data { | |||
| 22 | * speed, you may want to use 0 here. */ | 22 | * speed, you may want to use 0 here. */ |
| 23 | u16 use_dummy_writes; | 23 | u16 use_dummy_writes; |
| 24 | 24 | ||
| 25 | /* GPIO number to use as chip select */ | ||
| 26 | u16 gpio_cs; | ||
| 27 | |||
| 28 | /* Board specific setup/teardown */ | 25 | /* Board specific setup/teardown */ |
| 29 | int (*setup)(struct spi_device *spi); | 26 | int (*setup)(struct spi_device *spi); |
| 30 | int (*teardown)(struct spi_device *spi); | 27 | int (*teardown)(struct spi_device *spi); |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 17d61d19d912..c06104476973 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
| @@ -239,6 +239,8 @@ struct ieee80211_bss_conf { | |||
| 239 | * @IEEE80211_TX_INTFL_NEED_TXPROCESSING: completely internal to mac80211, | 239 | * @IEEE80211_TX_INTFL_NEED_TXPROCESSING: completely internal to mac80211, |
| 240 | * used to indicate that a pending frame requires TX processing before | 240 | * used to indicate that a pending frame requires TX processing before |
| 241 | * it can be sent out. | 241 | * it can be sent out. |
| 242 | * @IEEE80211_TX_INTFL_RETRIED: completely internal to mac80211, | ||
| 243 | * used to indicate that a frame was already retried due to PS | ||
| 242 | */ | 244 | */ |
| 243 | enum mac80211_tx_control_flags { | 245 | enum mac80211_tx_control_flags { |
| 244 | IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), | 246 | IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), |
| @@ -256,6 +258,7 @@ enum mac80211_tx_control_flags { | |||
| 256 | IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12), | 258 | IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12), |
| 257 | IEEE80211_TX_INTFL_RCALGO = BIT(13), | 259 | IEEE80211_TX_INTFL_RCALGO = BIT(13), |
| 258 | IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14), | 260 | IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14), |
| 261 | IEEE80211_TX_INTFL_RETRIED = BIT(15), | ||
| 259 | }; | 262 | }; |
| 260 | 263 | ||
| 261 | /** | 264 | /** |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 49961ba3c0f6..b94d777e3eb4 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -552,7 +552,6 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
| 552 | new->vlan_tci = old->vlan_tci; | 552 | new->vlan_tci = old->vlan_tci; |
| 553 | #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) | 553 | #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) |
| 554 | new->do_not_encrypt = old->do_not_encrypt; | 554 | new->do_not_encrypt = old->do_not_encrypt; |
| 555 | new->requeue = old->requeue; | ||
| 556 | #endif | 555 | #endif |
| 557 | 556 | ||
| 558 | skb_copy_secmark(new, old); | 557 | skb_copy_secmark(new, old); |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 43d00ffd3988..9e5762ad307d 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
| @@ -132,6 +132,9 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
| 132 | 132 | ||
| 133 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 133 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
| 134 | 134 | ||
| 135 | if (*state == HT_AGG_STATE_OPERATIONAL) | ||
| 136 | sta->ampdu_mlme.addba_req_num[tid] = 0; | ||
| 137 | |||
| 135 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | | 138 | *state = HT_AGG_STATE_REQ_STOP_BA_MSK | |
| 136 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | 139 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); |
| 137 | 140 | ||
| @@ -337,6 +340,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
| 337 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, | 340 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, |
| 338 | sta->ampdu_mlme.tid_tx[tid]->ssn, | 341 | sta->ampdu_mlme.tid_tx[tid]->ssn, |
| 339 | 0x40, 5000); | 342 | 0x40, 5000); |
| 343 | sta->ampdu_mlme.addba_req_num[tid]++; | ||
| 340 | /* activate the timer for the recipient's addBA response */ | 344 | /* activate the timer for the recipient's addBA response */ |
| 341 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = | 345 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = |
| 342 | jiffies + ADDBA_RESP_INTERVAL; | 346 | jiffies + ADDBA_RESP_INTERVAL; |
| @@ -606,7 +610,6 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
| 606 | 610 | ||
| 607 | *state = HT_AGG_STATE_IDLE; | 611 | *state = HT_AGG_STATE_IDLE; |
| 608 | /* from now on packets are no longer put onto sta->pending */ | 612 | /* from now on packets are no longer put onto sta->pending */ |
| 609 | sta->ampdu_mlme.addba_req_num[tid] = 0; | ||
| 610 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 613 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
| 611 | sta->ampdu_mlme.tid_tx[tid] = NULL; | 614 | sta->ampdu_mlme.tid_tx[tid] = NULL; |
| 612 | 615 | ||
| @@ -689,7 +692,6 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
| 689 | 692 | ||
| 690 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 693 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
| 691 | } else { | 694 | } else { |
| 692 | sta->ampdu_mlme.addba_req_num[tid]++; | ||
| 693 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); | 695 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); |
| 694 | } | 696 | } |
| 695 | spin_unlock_bh(&sta->lock); | 697 | spin_unlock_bh(&sta->lock); |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index a9211cc183cb..3f47276caeb8 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
| @@ -1122,8 +1122,8 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, | |||
| 1122 | p.txop = params->txop; | 1122 | p.txop = params->txop; |
| 1123 | if (drv_conf_tx(local, params->queue, &p)) { | 1123 | if (drv_conf_tx(local, params->queue, &p)) { |
| 1124 | printk(KERN_DEBUG "%s: failed to set TX queue " | 1124 | printk(KERN_DEBUG "%s: failed to set TX queue " |
| 1125 | "parameters for queue %d\n", local->mdev->name, | 1125 | "parameters for queue %d\n", |
| 1126 | params->queue); | 1126 | wiphy_name(local->hw.wiphy), params->queue); |
| 1127 | return -EINVAL; | 1127 | return -EINVAL; |
| 1128 | } | 1128 | } |
| 1129 | 1129 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c088c46704a3..4dbc28964196 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -589,6 +589,7 @@ enum queue_stop_reason { | |||
| 589 | IEEE80211_QUEUE_STOP_REASON_AGGREGATION, | 589 | IEEE80211_QUEUE_STOP_REASON_AGGREGATION, |
| 590 | IEEE80211_QUEUE_STOP_REASON_SUSPEND, | 590 | IEEE80211_QUEUE_STOP_REASON_SUSPEND, |
| 591 | IEEE80211_QUEUE_STOP_REASON_PENDING, | 591 | IEEE80211_QUEUE_STOP_REASON_PENDING, |
| 592 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD, | ||
| 592 | }; | 593 | }; |
| 593 | 594 | ||
| 594 | struct ieee80211_master_priv { | 595 | struct ieee80211_master_priv { |
| @@ -1121,6 +1122,10 @@ void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, | |||
| 1121 | enum queue_stop_reason reason); | 1122 | enum queue_stop_reason reason); |
| 1122 | void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, | 1123 | void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, |
| 1123 | enum queue_stop_reason reason); | 1124 | enum queue_stop_reason reason); |
| 1125 | void ieee80211_add_pending_skb(struct ieee80211_local *local, | ||
| 1126 | struct sk_buff *skb); | ||
| 1127 | int ieee80211_add_pending_skbs(struct ieee80211_local *local, | ||
| 1128 | struct sk_buff_head *skbs); | ||
| 1124 | 1129 | ||
| 1125 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | 1130 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, |
| 1126 | u16 transaction, u16 auth_alg, | 1131 | u16 transaction, u16 auth_alg, |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 2683df918073..092a017b237e 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
| @@ -369,60 +369,12 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
| 369 | } | 369 | } |
| 370 | } | 370 | } |
| 371 | 371 | ||
| 372 | /* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to | ||
| 373 | * make a prepared TX frame (one that has been given to hw) to look like brand | ||
| 374 | * new IEEE 802.11 frame that is ready to go through TX processing again. | ||
| 375 | */ | ||
| 376 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, | ||
| 377 | struct ieee80211_key *key, | ||
| 378 | struct sk_buff *skb) | ||
| 379 | { | ||
| 380 | unsigned int hdrlen, iv_len, mic_len; | ||
| 381 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
| 382 | |||
| 383 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | ||
| 384 | |||
| 385 | if (!key) | ||
| 386 | goto no_key; | ||
| 387 | |||
| 388 | switch (key->conf.alg) { | ||
| 389 | case ALG_WEP: | ||
| 390 | iv_len = WEP_IV_LEN; | ||
| 391 | mic_len = WEP_ICV_LEN; | ||
| 392 | break; | ||
| 393 | case ALG_TKIP: | ||
| 394 | iv_len = TKIP_IV_LEN; | ||
| 395 | mic_len = TKIP_ICV_LEN; | ||
| 396 | break; | ||
| 397 | case ALG_CCMP: | ||
| 398 | iv_len = CCMP_HDR_LEN; | ||
| 399 | mic_len = CCMP_MIC_LEN; | ||
| 400 | break; | ||
| 401 | default: | ||
| 402 | goto no_key; | ||
| 403 | } | ||
| 404 | |||
| 405 | if (skb->len >= hdrlen + mic_len && | ||
| 406 | !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | ||
| 407 | skb_trim(skb, skb->len - mic_len); | ||
| 408 | if (skb->len >= hdrlen + iv_len) { | ||
| 409 | memmove(skb->data + iv_len, skb->data, hdrlen); | ||
| 410 | hdr = (struct ieee80211_hdr *)skb_pull(skb, iv_len); | ||
| 411 | } | ||
| 412 | |||
| 413 | no_key: | ||
| 414 | if (ieee80211_is_data_qos(hdr->frame_control)) { | ||
| 415 | hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA); | ||
| 416 | memmove(skb->data + IEEE80211_QOS_CTL_LEN, skb->data, | ||
| 417 | hdrlen - IEEE80211_QOS_CTL_LEN); | ||
| 418 | skb_pull(skb, IEEE80211_QOS_CTL_LEN); | ||
| 419 | } | ||
| 420 | } | ||
| 421 | |||
| 422 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | 372 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, |
| 423 | struct sta_info *sta, | 373 | struct sta_info *sta, |
| 424 | struct sk_buff *skb) | 374 | struct sk_buff *skb) |
| 425 | { | 375 | { |
| 376 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
| 377 | |||
| 426 | sta->tx_filtered_count++; | 378 | sta->tx_filtered_count++; |
| 427 | 379 | ||
| 428 | /* | 380 | /* |
| @@ -464,16 +416,15 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
| 464 | */ | 416 | */ |
| 465 | if (test_sta_flags(sta, WLAN_STA_PS) && | 417 | if (test_sta_flags(sta, WLAN_STA_PS) && |
| 466 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | 418 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { |
| 467 | ieee80211_remove_tx_extra(local, sta->key, skb); | ||
| 468 | skb_queue_tail(&sta->tx_filtered, skb); | 419 | skb_queue_tail(&sta->tx_filtered, skb); |
| 469 | return; | 420 | return; |
| 470 | } | 421 | } |
| 471 | 422 | ||
| 472 | if (!test_sta_flags(sta, WLAN_STA_PS) && !skb->requeue) { | 423 | if (!test_sta_flags(sta, WLAN_STA_PS) && |
| 424 | !(info->flags & IEEE80211_TX_INTFL_RETRIED)) { | ||
| 473 | /* Software retry the packet once */ | 425 | /* Software retry the packet once */ |
| 474 | skb->requeue = 1; | 426 | info->flags |= IEEE80211_TX_INTFL_RETRIED; |
| 475 | ieee80211_remove_tx_extra(local, sta->key, skb); | 427 | ieee80211_add_pending_skb(local, skb); |
| 476 | dev_queue_xmit(skb); | ||
| 477 | return; | 428 | return; |
| 478 | } | 429 | } |
| 479 | 430 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 509469cb9265..d779c57a8220 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -621,9 +621,6 @@ static void ieee80211_change_ps(struct ieee80211_local *local) | |||
| 621 | struct ieee80211_conf *conf = &local->hw.conf; | 621 | struct ieee80211_conf *conf = &local->hw.conf; |
| 622 | 622 | ||
| 623 | if (local->ps_sdata) { | 623 | if (local->ps_sdata) { |
| 624 | if (!(local->ps_sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED)) | ||
| 625 | return; | ||
| 626 | |||
| 627 | ieee80211_enable_ps(local, local->ps_sdata); | 624 | ieee80211_enable_ps(local, local->ps_sdata); |
| 628 | } else if (conf->flags & IEEE80211_CONF_PS) { | 625 | } else if (conf->flags & IEEE80211_CONF_PS) { |
| 629 | conf->flags &= ~IEEE80211_CONF_PS; | 626 | conf->flags &= ~IEEE80211_CONF_PS; |
| @@ -653,7 +650,9 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) | |||
| 653 | count++; | 650 | count++; |
| 654 | } | 651 | } |
| 655 | 652 | ||
| 656 | if (count == 1 && found->u.mgd.powersave) { | 653 | if (count == 1 && found->u.mgd.powersave && |
| 654 | (found->u.mgd.flags & IEEE80211_STA_ASSOCIATED) && | ||
| 655 | !(found->u.mgd.flags & IEEE80211_STA_PROBEREQ_POLL)) { | ||
| 657 | s32 beaconint_us; | 656 | s32 beaconint_us; |
| 658 | 657 | ||
| 659 | if (latency < 0) | 658 | if (latency < 0) |
| @@ -793,13 +792,13 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
| 793 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 792 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
| 794 | printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " | 793 | printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " |
| 795 | "cWmin=%d cWmax=%d txop=%d\n", | 794 | "cWmin=%d cWmax=%d txop=%d\n", |
| 796 | local->mdev->name, queue, aci, acm, params.aifs, params.cw_min, | 795 | wiphy_name(local->hw.wiphy), queue, aci, acm, |
| 797 | params.cw_max, params.txop); | 796 | params.aifs, params.cw_min, params.cw_max, params.txop); |
| 798 | #endif | 797 | #endif |
| 799 | if (drv_conf_tx(local, queue, ¶ms) && local->ops->conf_tx) | 798 | if (drv_conf_tx(local, queue, ¶ms) && local->ops->conf_tx) |
| 800 | printk(KERN_DEBUG "%s: failed to set TX queue " | 799 | printk(KERN_DEBUG "%s: failed to set TX queue " |
| 801 | "parameters for queue %d\n", local->mdev->name, | 800 | "parameters for queue %d\n", |
| 802 | queue); | 801 | wiphy_name(local->hw.wiphy), queue); |
| 803 | } | 802 | } |
| 804 | } | 803 | } |
| 805 | 804 | ||
| @@ -1322,6 +1321,11 @@ void ieee80211_beacon_loss_work(struct work_struct *work) | |||
| 1322 | #endif | 1321 | #endif |
| 1323 | 1322 | ||
| 1324 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; | 1323 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; |
| 1324 | |||
| 1325 | mutex_lock(&sdata->local->iflist_mtx); | ||
| 1326 | ieee80211_recalc_ps(sdata->local, -1); | ||
| 1327 | mutex_unlock(&sdata->local->iflist_mtx); | ||
| 1328 | |||
| 1325 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, | 1329 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, |
| 1326 | ifmgd->ssid_len, NULL, 0); | 1330 | ifmgd->ssid_len, NULL, 0); |
| 1327 | 1331 | ||
| @@ -1342,6 +1346,7 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) | |||
| 1342 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1346 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
| 1343 | struct ieee80211_local *local = sdata->local; | 1347 | struct ieee80211_local *local = sdata->local; |
| 1344 | struct sta_info *sta; | 1348 | struct sta_info *sta; |
| 1349 | unsigned long last_rx; | ||
| 1345 | bool disassoc = false; | 1350 | bool disassoc = false; |
| 1346 | 1351 | ||
| 1347 | /* TODO: start monitoring current AP signal quality and number of | 1352 | /* TODO: start monitoring current AP signal quality and number of |
| @@ -1358,17 +1363,21 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) | |||
| 1358 | printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n", | 1363 | printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n", |
| 1359 | sdata->dev->name, ifmgd->bssid); | 1364 | sdata->dev->name, ifmgd->bssid); |
| 1360 | disassoc = true; | 1365 | disassoc = true; |
| 1361 | goto unlock; | 1366 | rcu_read_unlock(); |
| 1367 | goto out; | ||
| 1362 | } | 1368 | } |
| 1363 | 1369 | ||
| 1370 | last_rx = sta->last_rx; | ||
| 1371 | rcu_read_unlock(); | ||
| 1372 | |||
| 1364 | if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) && | 1373 | if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) && |
| 1365 | time_after(jiffies, sta->last_rx + IEEE80211_PROBE_WAIT)) { | 1374 | time_after(jiffies, last_rx + IEEE80211_PROBE_WAIT)) { |
| 1366 | printk(KERN_DEBUG "%s: no probe response from AP %pM " | 1375 | printk(KERN_DEBUG "%s: no probe response from AP %pM " |
| 1367 | "- disassociating\n", | 1376 | "- disassociating\n", |
| 1368 | sdata->dev->name, ifmgd->bssid); | 1377 | sdata->dev->name, ifmgd->bssid); |
| 1369 | disassoc = true; | 1378 | disassoc = true; |
| 1370 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; | 1379 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; |
| 1371 | goto unlock; | 1380 | goto out; |
| 1372 | } | 1381 | } |
| 1373 | 1382 | ||
| 1374 | /* | 1383 | /* |
| @@ -1387,26 +1396,29 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) | |||
| 1387 | } | 1396 | } |
| 1388 | #endif | 1397 | #endif |
| 1389 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; | 1398 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; |
| 1399 | mutex_lock(&local->iflist_mtx); | ||
| 1400 | ieee80211_recalc_ps(local, -1); | ||
| 1401 | mutex_unlock(&local->iflist_mtx); | ||
| 1390 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, | 1402 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, |
| 1391 | ifmgd->ssid_len, NULL, 0); | 1403 | ifmgd->ssid_len, NULL, 0); |
| 1392 | mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT); | 1404 | mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT); |
| 1393 | goto unlock; | 1405 | goto out; |
| 1394 | } | 1406 | } |
| 1395 | 1407 | ||
| 1396 | if (time_after(jiffies, sta->last_rx + IEEE80211_PROBE_IDLE_TIME)) { | 1408 | if (time_after(jiffies, last_rx + IEEE80211_PROBE_IDLE_TIME)) { |
| 1397 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; | 1409 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; |
| 1410 | mutex_lock(&local->iflist_mtx); | ||
| 1411 | ieee80211_recalc_ps(local, -1); | ||
| 1412 | mutex_unlock(&local->iflist_mtx); | ||
| 1398 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, | 1413 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, |
| 1399 | ifmgd->ssid_len, NULL, 0); | 1414 | ifmgd->ssid_len, NULL, 0); |
| 1400 | } | 1415 | } |
| 1401 | 1416 | ||
| 1417 | out: | ||
| 1402 | if (!disassoc) | 1418 | if (!disassoc) |
| 1403 | mod_timer(&ifmgd->timer, | 1419 | mod_timer(&ifmgd->timer, |
| 1404 | jiffies + IEEE80211_MONITORING_INTERVAL); | 1420 | jiffies + IEEE80211_MONITORING_INTERVAL); |
| 1405 | 1421 | else | |
| 1406 | unlock: | ||
| 1407 | rcu_read_unlock(); | ||
| 1408 | |||
| 1409 | if (disassoc) | ||
| 1410 | ieee80211_set_disassoc(sdata, true, true, | 1422 | ieee80211_set_disassoc(sdata, true, true, |
| 1411 | WLAN_REASON_PREV_AUTH_NOT_VALID); | 1423 | WLAN_REASON_PREV_AUTH_NOT_VALID); |
| 1412 | } | 1424 | } |
| @@ -1889,8 +1901,12 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
| 1889 | ieee80211_authenticate(sdata); | 1901 | ieee80211_authenticate(sdata); |
| 1890 | } | 1902 | } |
| 1891 | 1903 | ||
| 1892 | if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) | 1904 | if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) { |
| 1893 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; | 1905 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; |
| 1906 | mutex_lock(&sdata->local->iflist_mtx); | ||
| 1907 | ieee80211_recalc_ps(sdata->local, -1); | ||
| 1908 | mutex_unlock(&sdata->local->iflist_mtx); | ||
| 1909 | } | ||
| 1894 | } | 1910 | } |
| 1895 | 1911 | ||
| 1896 | /* | 1912 | /* |
| @@ -1948,6 +1964,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
| 1948 | } | 1964 | } |
| 1949 | #endif | 1965 | #endif |
| 1950 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; | 1966 | ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; |
| 1967 | mutex_lock(&local->iflist_mtx); | ||
| 1968 | ieee80211_recalc_ps(local, -1); | ||
| 1969 | mutex_unlock(&local->iflist_mtx); | ||
| 1951 | } | 1970 | } |
| 1952 | 1971 | ||
| 1953 | ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); | 1972 | ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); |
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 0a11515341ba..b218b98fba7f 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
| @@ -215,7 +215,7 @@ minstrel_get_next_sample(struct minstrel_sta_info *mi) | |||
| 215 | unsigned int sample_ndx; | 215 | unsigned int sample_ndx; |
| 216 | sample_ndx = SAMPLE_TBL(mi, mi->sample_idx, mi->sample_column); | 216 | sample_ndx = SAMPLE_TBL(mi, mi->sample_idx, mi->sample_column); |
| 217 | mi->sample_idx++; | 217 | mi->sample_idx++; |
| 218 | if (mi->sample_idx > (mi->n_rates - 2)) { | 218 | if ((int) mi->sample_idx > (mi->n_rates - 2)) { |
| 219 | mi->sample_idx = 0; | 219 | mi->sample_idx = 0; |
| 220 | mi->sample_column++; | 220 | mi->sample_column++; |
| 221 | if (mi->sample_column >= SAMPLE_COLUMNS) | 221 | if (mi->sample_column >= SAMPLE_COLUMNS) |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 6a9b8e63a6bf..de5bba7f910a 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -797,8 +797,7 @@ static int ap_sta_ps_end(struct sta_info *sta) | |||
| 797 | { | 797 | { |
| 798 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 798 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
| 799 | struct ieee80211_local *local = sdata->local; | 799 | struct ieee80211_local *local = sdata->local; |
| 800 | struct sk_buff *skb; | 800 | int sent, buffered; |
| 801 | int sent = 0; | ||
| 802 | 801 | ||
| 803 | atomic_dec(&sdata->bss->num_sta_ps); | 802 | atomic_dec(&sdata->bss->num_sta_ps); |
| 804 | 803 | ||
| @@ -814,22 +813,16 @@ static int ap_sta_ps_end(struct sta_info *sta) | |||
| 814 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 813 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
| 815 | 814 | ||
| 816 | /* Send all buffered frames to the station */ | 815 | /* Send all buffered frames to the station */ |
| 817 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { | 816 | sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered); |
| 818 | sent++; | 817 | buffered = ieee80211_add_pending_skbs(local, &sta->ps_tx_buf); |
| 819 | skb->requeue = 1; | 818 | sent += buffered; |
| 820 | dev_queue_xmit(skb); | 819 | local->total_ps_buffered -= buffered; |
| 821 | } | 820 | |
| 822 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { | ||
| 823 | local->total_ps_buffered--; | ||
| 824 | sent++; | ||
| 825 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 821 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
| 826 | printk(KERN_DEBUG "%s: STA %pM aid %d send PS frame " | 822 | printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames " |
| 827 | "since STA not sleeping anymore\n", sdata->dev->name, | 823 | "since STA not sleeping anymore\n", sdata->dev->name, |
| 828 | sta->sta.addr, sta->sta.aid); | 824 | sta->sta.addr, sta->sta.aid, sent - buffered, buffered); |
| 829 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 825 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
| 830 | skb->requeue = 1; | ||
| 831 | dev_queue_xmit(skb); | ||
| 832 | } | ||
| 833 | 826 | ||
| 834 | return sent; | 827 | return sent; |
| 835 | } | 828 | } |
| @@ -1335,7 +1328,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
| 1335 | * mac80211. That also explains the __skb_push() | 1328 | * mac80211. That also explains the __skb_push() |
| 1336 | * below. | 1329 | * below. |
| 1337 | */ | 1330 | */ |
| 1338 | align = (unsigned long)skb->data & 3; | 1331 | align = ((unsigned long)(skb->data + sizeof(struct ethhdr))) & 3; |
| 1339 | if (align) { | 1332 | if (align) { |
| 1340 | if (WARN_ON(skb_headroom(skb) < 3)) { | 1333 | if (WARN_ON(skb_headroom(skb) < 3)) { |
| 1341 | dev_kfree_skb(skb); | 1334 | dev_kfree_skb(skb); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 1436f747531a..364222bfb10d 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -400,6 +400,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
| 400 | sta_info_set_tim_bit(sta); | 400 | sta_info_set_tim_bit(sta); |
| 401 | 401 | ||
| 402 | info->control.jiffies = jiffies; | 402 | info->control.jiffies = jiffies; |
| 403 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | ||
| 403 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); | 404 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); |
| 404 | return TX_QUEUED; | 405 | return TX_QUEUED; |
| 405 | } | 406 | } |
| @@ -420,7 +421,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
| 420 | * frame filtering and keeps a station blacklist on its own | 421 | * frame filtering and keeps a station blacklist on its own |
| 421 | * (e.g: p54), so that frames can be delivered unimpeded. | 422 | * (e.g: p54), so that frames can be delivered unimpeded. |
| 422 | * | 423 | * |
| 423 | * Note: It should be save to disable the filter now. | 424 | * Note: It should be safe to disable the filter now. |
| 424 | * As, it is really unlikely that we still have any pending | 425 | * As, it is really unlikely that we still have any pending |
| 425 | * frame for this station in the hw's buffers/fifos left, | 426 | * frame for this station in the hw's buffers/fifos left, |
| 426 | * that is not rejected with a unsuccessful tx_status yet. | 427 | * that is not rejected with a unsuccessful tx_status yet. |
| @@ -907,9 +908,8 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) | |||
| 907 | * deal with packet injection down monitor interface | 908 | * deal with packet injection down monitor interface |
| 908 | * with Radiotap Header -- only called for monitor mode interface | 909 | * with Radiotap Header -- only called for monitor mode interface |
| 909 | */ | 910 | */ |
| 910 | static ieee80211_tx_result | 911 | static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, |
| 911 | __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | 912 | struct sk_buff *skb) |
| 912 | struct sk_buff *skb) | ||
| 913 | { | 913 | { |
| 914 | /* | 914 | /* |
| 915 | * this is the moment to interpret and discard the radiotap header that | 915 | * this is the moment to interpret and discard the radiotap header that |
| @@ -960,7 +960,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
| 960 | * on transmission | 960 | * on transmission |
| 961 | */ | 961 | */ |
| 962 | if (skb->len < (iterator.max_length + FCS_LEN)) | 962 | if (skb->len < (iterator.max_length + FCS_LEN)) |
| 963 | return TX_DROP; | 963 | return false; |
| 964 | 964 | ||
| 965 | skb_trim(skb, skb->len - FCS_LEN); | 965 | skb_trim(skb, skb->len - FCS_LEN); |
| 966 | } | 966 | } |
| @@ -982,7 +982,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
| 982 | } | 982 | } |
| 983 | 983 | ||
| 984 | if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */ | 984 | if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */ |
| 985 | return TX_DROP; | 985 | return false; |
| 986 | 986 | ||
| 987 | /* | 987 | /* |
| 988 | * remove the radiotap header | 988 | * remove the radiotap header |
| @@ -991,7 +991,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
| 991 | */ | 991 | */ |
| 992 | skb_pull(skb, iterator.max_length); | 992 | skb_pull(skb, iterator.max_length); |
| 993 | 993 | ||
| 994 | return TX_CONTINUE; | 994 | return true; |
| 995 | } | 995 | } |
| 996 | 996 | ||
| 997 | /* | 997 | /* |
| @@ -1025,7 +1025,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
| 1025 | /* process and remove the injection radiotap header */ | 1025 | /* process and remove the injection radiotap header */ |
| 1026 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1026 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
| 1027 | if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) { | 1027 | if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) { |
| 1028 | if (__ieee80211_parse_tx_radiotap(tx, skb) == TX_DROP) | 1028 | if (!__ieee80211_parse_tx_radiotap(tx, skb)) |
| 1029 | return TX_DROP; | 1029 | return TX_DROP; |
| 1030 | 1030 | ||
| 1031 | /* | 1031 | /* |
| @@ -1415,7 +1415,8 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1415 | } | 1415 | } |
| 1416 | 1416 | ||
| 1417 | if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && | 1417 | if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && |
| 1418 | local->hw.conf.dynamic_ps_timeout > 0) { | 1418 | local->hw.conf.dynamic_ps_timeout > 0 && |
| 1419 | !local->sw_scanning && !local->hw_scanning && local->ps_sdata) { | ||
| 1419 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 1420 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
| 1420 | ieee80211_stop_queues_by_reason(&local->hw, | 1421 | ieee80211_stop_queues_by_reason(&local->hw, |
| 1421 | IEEE80211_QUEUE_STOP_REASON_PS); | 1422 | IEEE80211_QUEUE_STOP_REASON_PS); |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 22f63815fb36..66ce96a69f31 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -341,6 +341,52 @@ void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) | |||
| 341 | } | 341 | } |
| 342 | EXPORT_SYMBOL(ieee80211_stop_queue); | 342 | EXPORT_SYMBOL(ieee80211_stop_queue); |
| 343 | 343 | ||
| 344 | void ieee80211_add_pending_skb(struct ieee80211_local *local, | ||
| 345 | struct sk_buff *skb) | ||
| 346 | { | ||
| 347 | struct ieee80211_hw *hw = &local->hw; | ||
| 348 | unsigned long flags; | ||
| 349 | int queue = skb_get_queue_mapping(skb); | ||
| 350 | |||
| 351 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
| 352 | __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); | ||
| 353 | __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_PENDING); | ||
| 354 | skb_queue_tail(&local->pending[queue], skb); | ||
| 355 | __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); | ||
| 356 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
| 357 | } | ||
| 358 | |||
| 359 | int ieee80211_add_pending_skbs(struct ieee80211_local *local, | ||
| 360 | struct sk_buff_head *skbs) | ||
| 361 | { | ||
| 362 | struct ieee80211_hw *hw = &local->hw; | ||
| 363 | struct sk_buff *skb; | ||
| 364 | unsigned long flags; | ||
| 365 | int queue, ret = 0, i; | ||
| 366 | |||
| 367 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
| 368 | for (i = 0; i < hw->queues; i++) | ||
| 369 | __ieee80211_stop_queue(hw, i, | ||
| 370 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD); | ||
| 371 | |||
| 372 | while ((skb = skb_dequeue(skbs))) { | ||
| 373 | ret++; | ||
| 374 | queue = skb_get_queue_mapping(skb); | ||
| 375 | skb_queue_tail(&local->pending[queue], skb); | ||
| 376 | } | ||
| 377 | |||
| 378 | for (i = 0; i < hw->queues; i++) { | ||
| 379 | if (ret) | ||
| 380 | __ieee80211_stop_queue(hw, i, | ||
| 381 | IEEE80211_QUEUE_STOP_REASON_PENDING); | ||
| 382 | __ieee80211_wake_queue(hw, i, | ||
| 383 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD); | ||
| 384 | } | ||
| 385 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
| 386 | |||
| 387 | return ret; | ||
| 388 | } | ||
| 389 | |||
| 344 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, | 390 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, |
| 345 | enum queue_stop_reason reason) | 391 | enum queue_stop_reason reason) |
| 346 | { | 392 | { |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 694343b9102b..116a923b14d6 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
| @@ -101,7 +101,7 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb) | |||
| 101 | * Now we know the 1d priority, fill in the QoS header if | 101 | * Now we know the 1d priority, fill in the QoS header if |
| 102 | * there is one (and we haven't done this before). | 102 | * there is one (and we haven't done this before). |
| 103 | */ | 103 | */ |
| 104 | if (!skb->requeue && ieee80211_is_data_qos(hdr->frame_control)) { | 104 | if (ieee80211_is_data_qos(hdr->frame_control)) { |
| 105 | u8 *p = ieee80211_get_qos_ctl(hdr); | 105 | u8 *p = ieee80211_get_qos_ctl(hdr); |
| 106 | u8 ack_policy = 0; | 106 | u8 ack_policy = 0; |
| 107 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; | 107 | tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; |
diff --git a/net/rfkill/Kconfig b/net/rfkill/Kconfig index fd7600d8ab14..eaf765876458 100644 --- a/net/rfkill/Kconfig +++ b/net/rfkill/Kconfig | |||
| @@ -18,7 +18,7 @@ config RFKILL_LEDS | |||
| 18 | default y | 18 | default y |
| 19 | 19 | ||
| 20 | config RFKILL_INPUT | 20 | config RFKILL_INPUT |
| 21 | bool "RF switch input support" | 21 | bool "RF switch input support" if EMBEDDED |
| 22 | depends on RFKILL | 22 | depends on RFKILL |
| 23 | depends on INPUT = y || RFKILL = INPUT | 23 | depends on INPUT = y || RFKILL = INPUT |
| 24 | default y if !EMBEDDED | 24 | default y if !EMBEDDED |
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index 11b7314723df..4e68ab439d5d 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
| @@ -57,6 +57,7 @@ struct rfkill { | |||
| 57 | 57 | ||
| 58 | bool registered; | 58 | bool registered; |
| 59 | bool suspended; | 59 | bool suspended; |
| 60 | bool persistent; | ||
| 60 | 61 | ||
| 61 | const struct rfkill_ops *ops; | 62 | const struct rfkill_ops *ops; |
| 62 | void *data; | 63 | void *data; |
| @@ -116,11 +117,9 @@ MODULE_PARM_DESC(default_state, | |||
| 116 | "Default initial state for all radio types, 0 = radio off"); | 117 | "Default initial state for all radio types, 0 = radio off"); |
| 117 | 118 | ||
| 118 | static struct { | 119 | static struct { |
| 119 | bool cur, def; | 120 | bool cur, sav; |
| 120 | } rfkill_global_states[NUM_RFKILL_TYPES]; | 121 | } rfkill_global_states[NUM_RFKILL_TYPES]; |
| 121 | 122 | ||
| 122 | static unsigned long rfkill_states_default_locked; | ||
| 123 | |||
| 124 | static bool rfkill_epo_lock_active; | 123 | static bool rfkill_epo_lock_active; |
| 125 | 124 | ||
| 126 | 125 | ||
| @@ -392,7 +391,7 @@ void rfkill_epo(void) | |||
| 392 | rfkill_set_block(rfkill, true); | 391 | rfkill_set_block(rfkill, true); |
| 393 | 392 | ||
| 394 | for (i = 0; i < NUM_RFKILL_TYPES; i++) { | 393 | for (i = 0; i < NUM_RFKILL_TYPES; i++) { |
| 395 | rfkill_global_states[i].def = rfkill_global_states[i].cur; | 394 | rfkill_global_states[i].sav = rfkill_global_states[i].cur; |
| 396 | rfkill_global_states[i].cur = true; | 395 | rfkill_global_states[i].cur = true; |
| 397 | } | 396 | } |
| 398 | 397 | ||
| @@ -417,7 +416,7 @@ void rfkill_restore_states(void) | |||
| 417 | 416 | ||
| 418 | rfkill_epo_lock_active = false; | 417 | rfkill_epo_lock_active = false; |
| 419 | for (i = 0; i < NUM_RFKILL_TYPES; i++) | 418 | for (i = 0; i < NUM_RFKILL_TYPES; i++) |
| 420 | __rfkill_switch_all(i, rfkill_global_states[i].def); | 419 | __rfkill_switch_all(i, rfkill_global_states[i].sav); |
| 421 | mutex_unlock(&rfkill_global_mutex); | 420 | mutex_unlock(&rfkill_global_mutex); |
| 422 | } | 421 | } |
| 423 | 422 | ||
| @@ -464,29 +463,6 @@ bool rfkill_get_global_sw_state(const enum rfkill_type type) | |||
| 464 | } | 463 | } |
| 465 | #endif | 464 | #endif |
| 466 | 465 | ||
| 467 | void rfkill_set_global_sw_state(const enum rfkill_type type, bool blocked) | ||
| 468 | { | ||
| 469 | BUG_ON(type == RFKILL_TYPE_ALL); | ||
| 470 | |||
| 471 | mutex_lock(&rfkill_global_mutex); | ||
| 472 | |||
| 473 | /* don't allow unblock when epo */ | ||
| 474 | if (rfkill_epo_lock_active && !blocked) | ||
| 475 | goto out; | ||
| 476 | |||
| 477 | /* too late */ | ||
| 478 | if (rfkill_states_default_locked & BIT(type)) | ||
| 479 | goto out; | ||
| 480 | |||
| 481 | rfkill_states_default_locked |= BIT(type); | ||
| 482 | |||
| 483 | rfkill_global_states[type].cur = blocked; | ||
| 484 | rfkill_global_states[type].def = blocked; | ||
| 485 | out: | ||
| 486 | mutex_unlock(&rfkill_global_mutex); | ||
| 487 | } | ||
| 488 | EXPORT_SYMBOL(rfkill_set_global_sw_state); | ||
| 489 | |||
| 490 | 466 | ||
| 491 | bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked) | 467 | bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked) |
| 492 | { | 468 | { |
| @@ -532,13 +508,14 @@ bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked) | |||
| 532 | blocked = blocked || hwblock; | 508 | blocked = blocked || hwblock; |
| 533 | spin_unlock_irqrestore(&rfkill->lock, flags); | 509 | spin_unlock_irqrestore(&rfkill->lock, flags); |
| 534 | 510 | ||
| 535 | if (!rfkill->registered) | 511 | if (!rfkill->registered) { |
| 536 | return blocked; | 512 | rfkill->persistent = true; |
| 537 | 513 | } else { | |
| 538 | if (prev != blocked && !hwblock) | 514 | if (prev != blocked && !hwblock) |
| 539 | schedule_work(&rfkill->uevent_work); | 515 | schedule_work(&rfkill->uevent_work); |
| 540 | 516 | ||
| 541 | rfkill_led_trigger_event(rfkill); | 517 | rfkill_led_trigger_event(rfkill); |
| 518 | } | ||
| 542 | 519 | ||
| 543 | return blocked; | 520 | return blocked; |
| 544 | } | 521 | } |
| @@ -563,13 +540,14 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) | |||
| 563 | 540 | ||
| 564 | spin_unlock_irqrestore(&rfkill->lock, flags); | 541 | spin_unlock_irqrestore(&rfkill->lock, flags); |
| 565 | 542 | ||
| 566 | if (!rfkill->registered) | 543 | if (!rfkill->registered) { |
| 567 | return; | 544 | rfkill->persistent = true; |
| 568 | 545 | } else { | |
| 569 | if (swprev != sw || hwprev != hw) | 546 | if (swprev != sw || hwprev != hw) |
| 570 | schedule_work(&rfkill->uevent_work); | 547 | schedule_work(&rfkill->uevent_work); |
| 571 | 548 | ||
| 572 | rfkill_led_trigger_event(rfkill); | 549 | rfkill_led_trigger_event(rfkill); |
| 550 | } | ||
| 573 | } | 551 | } |
| 574 | EXPORT_SYMBOL(rfkill_set_states); | 552 | EXPORT_SYMBOL(rfkill_set_states); |
| 575 | 553 | ||
| @@ -750,15 +728,11 @@ static int rfkill_resume(struct device *dev) | |||
| 750 | struct rfkill *rfkill = to_rfkill(dev); | 728 | struct rfkill *rfkill = to_rfkill(dev); |
| 751 | bool cur; | 729 | bool cur; |
| 752 | 730 | ||
| 753 | mutex_lock(&rfkill_global_mutex); | 731 | cur = !!(rfkill->state & RFKILL_BLOCK_SW); |
| 754 | cur = rfkill_global_states[rfkill->type].cur; | ||
| 755 | rfkill_set_block(rfkill, cur); | 732 | rfkill_set_block(rfkill, cur); |
| 756 | mutex_unlock(&rfkill_global_mutex); | ||
| 757 | 733 | ||
| 758 | rfkill->suspended = false; | 734 | rfkill->suspended = false; |
| 759 | 735 | ||
| 760 | schedule_work(&rfkill->uevent_work); | ||
| 761 | |||
| 762 | rfkill_resume_polling(rfkill); | 736 | rfkill_resume_polling(rfkill); |
| 763 | 737 | ||
| 764 | return 0; | 738 | return 0; |
| @@ -888,15 +862,6 @@ int __must_check rfkill_register(struct rfkill *rfkill) | |||
| 888 | dev_set_name(dev, "rfkill%lu", rfkill_no); | 862 | dev_set_name(dev, "rfkill%lu", rfkill_no); |
| 889 | rfkill_no++; | 863 | rfkill_no++; |
| 890 | 864 | ||
| 891 | if (!(rfkill_states_default_locked & BIT(rfkill->type))) { | ||
| 892 | /* first of its kind */ | ||
| 893 | BUILD_BUG_ON(NUM_RFKILL_TYPES > | ||
| 894 | sizeof(rfkill_states_default_locked) * 8); | ||
| 895 | rfkill_states_default_locked |= BIT(rfkill->type); | ||
| 896 | rfkill_global_states[rfkill->type].cur = | ||
| 897 | rfkill_global_states[rfkill->type].def; | ||
| 898 | } | ||
| 899 | |||
| 900 | list_add_tail(&rfkill->node, &rfkill_list); | 865 | list_add_tail(&rfkill->node, &rfkill_list); |
| 901 | 866 | ||
| 902 | error = device_add(dev); | 867 | error = device_add(dev); |
| @@ -916,7 +881,17 @@ int __must_check rfkill_register(struct rfkill *rfkill) | |||
| 916 | if (rfkill->ops->poll) | 881 | if (rfkill->ops->poll) |
| 917 | schedule_delayed_work(&rfkill->poll_work, | 882 | schedule_delayed_work(&rfkill->poll_work, |
| 918 | round_jiffies_relative(POLL_INTERVAL)); | 883 | round_jiffies_relative(POLL_INTERVAL)); |
| 919 | schedule_work(&rfkill->sync_work); | 884 | |
| 885 | if (!rfkill->persistent || rfkill_epo_lock_active) { | ||
| 886 | schedule_work(&rfkill->sync_work); | ||
| 887 | } else { | ||
| 888 | #ifdef CONFIG_RFKILL_INPUT | ||
| 889 | bool soft_blocked = !!(rfkill->state & RFKILL_BLOCK_SW); | ||
| 890 | |||
| 891 | if (!atomic_read(&rfkill_input_disabled)) | ||
| 892 | __rfkill_switch_all(rfkill->type, soft_blocked); | ||
| 893 | #endif | ||
| 894 | } | ||
| 920 | 895 | ||
| 921 | rfkill_send_events(rfkill, RFKILL_OP_ADD); | 896 | rfkill_send_events(rfkill, RFKILL_OP_ADD); |
| 922 | 897 | ||
| @@ -1134,7 +1109,8 @@ static int rfkill_fop_release(struct inode *inode, struct file *file) | |||
| 1134 | 1109 | ||
| 1135 | #ifdef CONFIG_RFKILL_INPUT | 1110 | #ifdef CONFIG_RFKILL_INPUT |
| 1136 | if (data->input_handler) | 1111 | if (data->input_handler) |
| 1137 | atomic_dec(&rfkill_input_disabled); | 1112 | if (atomic_dec_return(&rfkill_input_disabled) == 0) |
| 1113 | printk(KERN_DEBUG "rfkill: input handler enabled\n"); | ||
| 1138 | #endif | 1114 | #endif |
| 1139 | 1115 | ||
| 1140 | kfree(data); | 1116 | kfree(data); |
| @@ -1157,7 +1133,8 @@ static long rfkill_fop_ioctl(struct file *file, unsigned int cmd, | |||
| 1157 | mutex_lock(&data->mtx); | 1133 | mutex_lock(&data->mtx); |
| 1158 | 1134 | ||
| 1159 | if (!data->input_handler) { | 1135 | if (!data->input_handler) { |
| 1160 | atomic_inc(&rfkill_input_disabled); | 1136 | if (atomic_inc_return(&rfkill_input_disabled) == 1) |
| 1137 | printk(KERN_DEBUG "rfkill: input handler disabled\n"); | ||
| 1161 | data->input_handler = true; | 1138 | data->input_handler = true; |
| 1162 | } | 1139 | } |
| 1163 | 1140 | ||
| @@ -1191,7 +1168,7 @@ static int __init rfkill_init(void) | |||
| 1191 | int i; | 1168 | int i; |
| 1192 | 1169 | ||
| 1193 | for (i = 0; i < NUM_RFKILL_TYPES; i++) | 1170 | for (i = 0; i < NUM_RFKILL_TYPES; i++) |
| 1194 | rfkill_global_states[i].def = !rfkill_default_state; | 1171 | rfkill_global_states[i].cur = !rfkill_default_state; |
| 1195 | 1172 | ||
| 1196 | error = class_register(&rfkill_class); | 1173 | error = class_register(&rfkill_class); |
| 1197 | if (error) | 1174 | if (error) |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 3b74b88e10a3..d5850292b3df 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
| @@ -395,21 +395,23 @@ int wiphy_register(struct wiphy *wiphy) | |||
| 395 | /* check and set up bitrates */ | 395 | /* check and set up bitrates */ |
| 396 | ieee80211_set_bitrate_flags(wiphy); | 396 | ieee80211_set_bitrate_flags(wiphy); |
| 397 | 397 | ||
| 398 | mutex_lock(&cfg80211_mutex); | ||
| 399 | |||
| 400 | /* set up regulatory info */ | ||
| 401 | wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); | ||
| 402 | |||
| 403 | res = device_add(&drv->wiphy.dev); | 398 | res = device_add(&drv->wiphy.dev); |
| 404 | if (res) | 399 | if (res) |
| 405 | goto out_unlock; | 400 | return res; |
| 406 | 401 | ||
| 407 | res = rfkill_register(drv->rfkill); | 402 | res = rfkill_register(drv->rfkill); |
| 408 | if (res) | 403 | if (res) |
| 409 | goto out_rm_dev; | 404 | goto out_rm_dev; |
| 410 | 405 | ||
| 406 | mutex_lock(&cfg80211_mutex); | ||
| 407 | |||
| 408 | /* set up regulatory info */ | ||
| 409 | wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); | ||
| 410 | |||
| 411 | list_add(&drv->list, &cfg80211_drv_list); | 411 | list_add(&drv->list, &cfg80211_drv_list); |
| 412 | 412 | ||
| 413 | mutex_unlock(&cfg80211_mutex); | ||
| 414 | |||
| 413 | /* add to debugfs */ | 415 | /* add to debugfs */ |
| 414 | drv->wiphy.debugfsdir = | 416 | drv->wiphy.debugfsdir = |
| 415 | debugfs_create_dir(wiphy_name(&drv->wiphy), | 417 | debugfs_create_dir(wiphy_name(&drv->wiphy), |
| @@ -430,13 +432,10 @@ int wiphy_register(struct wiphy *wiphy) | |||
| 430 | 432 | ||
| 431 | cfg80211_debugfs_drv_add(drv); | 433 | cfg80211_debugfs_drv_add(drv); |
| 432 | 434 | ||
| 433 | res = 0; | 435 | return 0; |
| 434 | goto out_unlock; | ||
| 435 | 436 | ||
| 436 | out_rm_dev: | 437 | out_rm_dev: |
| 437 | device_del(&drv->wiphy.dev); | 438 | device_del(&drv->wiphy.dev); |
| 438 | out_unlock: | ||
| 439 | mutex_unlock(&cfg80211_mutex); | ||
| 440 | return res; | 439 | return res; |
| 441 | } | 440 | } |
| 442 | EXPORT_SYMBOL(wiphy_register); | 441 | EXPORT_SYMBOL(wiphy_register); |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index ea4c299fbe3b..5e14371cda70 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
| @@ -2129,7 +2129,12 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
| 2129 | * driver wanted to the wiphy to deal with conflicts | 2129 | * driver wanted to the wiphy to deal with conflicts |
| 2130 | */ | 2130 | */ |
| 2131 | 2131 | ||
| 2132 | BUG_ON(request_wiphy->regd); | 2132 | /* |
| 2133 | * Userspace could have sent two replies with only | ||
| 2134 | * one kernel request. | ||
| 2135 | */ | ||
| 2136 | if (request_wiphy->regd) | ||
| 2137 | return -EALREADY; | ||
| 2133 | 2138 | ||
| 2134 | r = reg_copy_regd(&request_wiphy->regd, rd); | 2139 | r = reg_copy_regd(&request_wiphy->regd, rd); |
| 2135 | if (r) | 2140 | if (r) |
