diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 284 |
1 files changed, 127 insertions, 157 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index ae62ad40ad63..24b14363d6e7 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -41,6 +41,8 @@ | |||
41 | */ | 41 | */ |
42 | struct ieee80211_tx_status_rtap_hdr { | 42 | struct ieee80211_tx_status_rtap_hdr { |
43 | struct ieee80211_radiotap_header hdr; | 43 | struct ieee80211_radiotap_header hdr; |
44 | u8 rate; | ||
45 | u8 padding_for_rate; | ||
44 | __le16 tx_flags; | 46 | __le16 tx_flags; |
45 | u8 data_retries; | 47 | u8 data_retries; |
46 | } __attribute__ ((packed)); | 48 | } __attribute__ ((packed)); |
@@ -169,19 +171,13 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) | |||
169 | conf.changed = changed; | 171 | conf.changed = changed; |
170 | 172 | ||
171 | if (sdata->vif.type == NL80211_IFTYPE_STATION || | 173 | if (sdata->vif.type == NL80211_IFTYPE_STATION || |
172 | sdata->vif.type == NL80211_IFTYPE_ADHOC) { | 174 | sdata->vif.type == NL80211_IFTYPE_ADHOC) |
173 | conf.bssid = sdata->u.sta.bssid; | 175 | conf.bssid = sdata->u.sta.bssid; |
174 | conf.ssid = sdata->u.sta.ssid; | 176 | else if (sdata->vif.type == NL80211_IFTYPE_AP) |
175 | conf.ssid_len = sdata->u.sta.ssid_len; | ||
176 | } else if (sdata->vif.type == NL80211_IFTYPE_AP) { | ||
177 | conf.bssid = sdata->dev->dev_addr; | 177 | conf.bssid = sdata->dev->dev_addr; |
178 | conf.ssid = sdata->u.ap.ssid; | 178 | else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
179 | conf.ssid_len = sdata->u.ap.ssid_len; | ||
180 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
181 | u8 zero[ETH_ALEN] = { 0 }; | 179 | u8 zero[ETH_ALEN] = { 0 }; |
182 | conf.bssid = zero; | 180 | conf.bssid = zero; |
183 | conf.ssid = zero; | ||
184 | conf.ssid_len = 0; | ||
185 | } else { | 181 | } else { |
186 | WARN_ON(1); | 182 | WARN_ON(1); |
187 | return -EINVAL; | 183 | return -EINVAL; |
@@ -190,136 +186,73 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) | |||
190 | if (WARN_ON(!conf.bssid && (changed & IEEE80211_IFCC_BSSID))) | 186 | if (WARN_ON(!conf.bssid && (changed & IEEE80211_IFCC_BSSID))) |
191 | return -EINVAL; | 187 | return -EINVAL; |
192 | 188 | ||
193 | if (WARN_ON(!conf.ssid && (changed & IEEE80211_IFCC_SSID))) | ||
194 | return -EINVAL; | ||
195 | |||
196 | return local->ops->config_interface(local_to_hw(local), | 189 | return local->ops->config_interface(local_to_hw(local), |
197 | &sdata->vif, &conf); | 190 | &sdata->vif, &conf); |
198 | } | 191 | } |
199 | 192 | ||
200 | int ieee80211_hw_config(struct ieee80211_local *local) | 193 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) |
201 | { | 194 | { |
202 | struct ieee80211_channel *chan; | 195 | struct ieee80211_channel *chan; |
203 | int ret = 0; | 196 | int ret = 0; |
197 | int power; | ||
198 | enum nl80211_channel_type channel_type; | ||
199 | |||
200 | might_sleep(); | ||
204 | 201 | ||
205 | if (local->sw_scanning) | 202 | if (local->sw_scanning) { |
206 | chan = local->scan_channel; | 203 | chan = local->scan_channel; |
207 | else | 204 | channel_type = NL80211_CHAN_NO_HT; |
205 | } else { | ||
208 | chan = local->oper_channel; | 206 | chan = local->oper_channel; |
207 | channel_type = local->oper_channel_type; | ||
208 | } | ||
209 | 209 | ||
210 | local->hw.conf.channel = chan; | 210 | if (chan != local->hw.conf.channel || |
211 | channel_type != local->hw.conf.ht.channel_type) { | ||
212 | local->hw.conf.channel = chan; | ||
213 | local->hw.conf.ht.channel_type = channel_type; | ||
214 | switch (channel_type) { | ||
215 | case NL80211_CHAN_NO_HT: | ||
216 | local->hw.conf.ht.enabled = false; | ||
217 | break; | ||
218 | case NL80211_CHAN_HT20: | ||
219 | case NL80211_CHAN_HT40MINUS: | ||
220 | case NL80211_CHAN_HT40PLUS: | ||
221 | local->hw.conf.ht.enabled = true; | ||
222 | break; | ||
223 | } | ||
224 | changed |= IEEE80211_CONF_CHANGE_CHANNEL; | ||
225 | } | ||
211 | 226 | ||
212 | if (!local->hw.conf.power_level) | 227 | if (!local->hw.conf.power_level) |
213 | local->hw.conf.power_level = chan->max_power; | 228 | power = chan->max_power; |
214 | else | 229 | else |
215 | local->hw.conf.power_level = min(chan->max_power, | 230 | power = min(chan->max_power, local->hw.conf.power_level); |
216 | local->hw.conf.power_level); | 231 | if (local->hw.conf.power_level != power) { |
217 | 232 | changed |= IEEE80211_CONF_CHANGE_POWER; | |
218 | local->hw.conf.max_antenna_gain = chan->max_antenna_gain; | 233 | local->hw.conf.power_level = power; |
219 | |||
220 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
221 | printk(KERN_DEBUG "%s: HW CONFIG: freq=%d\n", | ||
222 | wiphy_name(local->hw.wiphy), chan->center_freq); | ||
223 | #endif | ||
224 | |||
225 | if (local->open_count) | ||
226 | ret = local->ops->config(local_to_hw(local), &local->hw.conf); | ||
227 | |||
228 | return ret; | ||
229 | } | ||
230 | |||
231 | /** | ||
232 | * ieee80211_handle_ht should be used only after legacy configuration | ||
233 | * has been determined namely band, as ht configuration depends upon | ||
234 | * the hardware's HT abilities for a _specific_ band. | ||
235 | */ | ||
236 | u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, | ||
237 | struct ieee80211_ht_info *req_ht_cap, | ||
238 | struct ieee80211_ht_bss_info *req_bss_cap) | ||
239 | { | ||
240 | struct ieee80211_conf *conf = &local->hw.conf; | ||
241 | struct ieee80211_supported_band *sband; | ||
242 | struct ieee80211_ht_info ht_conf; | ||
243 | struct ieee80211_ht_bss_info ht_bss_conf; | ||
244 | u32 changed = 0; | ||
245 | int i; | ||
246 | u8 max_tx_streams = IEEE80211_HT_CAP_MAX_STREAMS; | ||
247 | u8 tx_mcs_set_cap; | ||
248 | |||
249 | sband = local->hw.wiphy->bands[conf->channel->band]; | ||
250 | |||
251 | memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info)); | ||
252 | memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); | ||
253 | |||
254 | /* HT is not supported */ | ||
255 | if (!sband->ht_info.ht_supported) { | ||
256 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | ||
257 | goto out; | ||
258 | } | 234 | } |
259 | 235 | ||
260 | /* disable HT */ | 236 | if (changed && local->open_count) { |
261 | if (!enable_ht) { | 237 | ret = local->ops->config(local_to_hw(local), changed); |
262 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) | 238 | /* |
263 | changed |= BSS_CHANGED_HT; | 239 | * Goal: |
264 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 240 | * HW reconfiguration should never fail, the driver has told |
265 | conf->ht_conf.ht_supported = 0; | 241 | * us what it can support so it should live up to that promise. |
266 | goto out; | 242 | * |
243 | * Current status: | ||
244 | * rfkill is not integrated with mac80211 and a | ||
245 | * configuration command can thus fail if hardware rfkill | ||
246 | * is enabled | ||
247 | * | ||
248 | * FIXME: integrate rfkill with mac80211 and then add this | ||
249 | * WARN_ON() back | ||
250 | * | ||
251 | */ | ||
252 | /* WARN_ON(ret); */ | ||
267 | } | 253 | } |
268 | 254 | ||
269 | 255 | return ret; | |
270 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) | ||
271 | changed |= BSS_CHANGED_HT; | ||
272 | |||
273 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; | ||
274 | ht_conf.ht_supported = 1; | ||
275 | |||
276 | ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; | ||
277 | ht_conf.cap &= ~(IEEE80211_HT_CAP_SM_PS); | ||
278 | ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_SM_PS; | ||
279 | ht_bss_conf.primary_channel = req_bss_cap->primary_channel; | ||
280 | ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | ||
281 | ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | ||
282 | |||
283 | ht_conf.ampdu_factor = req_ht_cap->ampdu_factor; | ||
284 | ht_conf.ampdu_density = req_ht_cap->ampdu_density; | ||
285 | |||
286 | /* Bits 96-100 */ | ||
287 | tx_mcs_set_cap = sband->ht_info.supp_mcs_set[12]; | ||
288 | |||
289 | /* configure suppoerted Tx MCS according to requested MCS | ||
290 | * (based in most cases on Rx capabilities of peer) and self | ||
291 | * Tx MCS capabilities (as defined by low level driver HW | ||
292 | * Tx capabilities) */ | ||
293 | if (!(tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_DEFINED)) | ||
294 | goto check_changed; | ||
295 | |||
296 | /* Counting from 0 therfore + 1 */ | ||
297 | if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_RX_DIFF) | ||
298 | max_tx_streams = ((tx_mcs_set_cap & | ||
299 | IEEE80211_HT_CAP_MCS_TX_STREAMS) >> 2) + 1; | ||
300 | |||
301 | for (i = 0; i < max_tx_streams; i++) | ||
302 | ht_conf.supp_mcs_set[i] = | ||
303 | sband->ht_info.supp_mcs_set[i] & | ||
304 | req_ht_cap->supp_mcs_set[i]; | ||
305 | |||
306 | if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_UEQM) | ||
307 | for (i = IEEE80211_SUPP_MCS_SET_UEQM; | ||
308 | i < IEEE80211_SUPP_MCS_SET_LEN; i++) | ||
309 | ht_conf.supp_mcs_set[i] = | ||
310 | sband->ht_info.supp_mcs_set[i] & | ||
311 | req_ht_cap->supp_mcs_set[i]; | ||
312 | |||
313 | check_changed: | ||
314 | /* if bss configuration changed store the new one */ | ||
315 | if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) || | ||
316 | memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { | ||
317 | changed |= BSS_CHANGED_HT; | ||
318 | memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf)); | ||
319 | memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); | ||
320 | } | ||
321 | out: | ||
322 | return changed; | ||
323 | } | 256 | } |
324 | 257 | ||
325 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | 258 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, |
@@ -336,15 +269,18 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
336 | if (local->ops->bss_info_changed) | 269 | if (local->ops->bss_info_changed) |
337 | local->ops->bss_info_changed(local_to_hw(local), | 270 | local->ops->bss_info_changed(local_to_hw(local), |
338 | &sdata->vif, | 271 | &sdata->vif, |
339 | &sdata->bss_conf, | 272 | &sdata->vif.bss_conf, |
340 | changed); | 273 | changed); |
341 | } | 274 | } |
342 | 275 | ||
343 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) | 276 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) |
344 | { | 277 | { |
345 | sdata->bss_conf.use_cts_prot = 0; | 278 | sdata->vif.bss_conf.use_cts_prot = false; |
346 | sdata->bss_conf.use_short_preamble = 0; | 279 | sdata->vif.bss_conf.use_short_preamble = false; |
347 | return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE; | 280 | sdata->vif.bss_conf.use_short_slot = false; |
281 | return BSS_CHANGED_ERP_CTS_PROT | | ||
282 | BSS_CHANGED_ERP_PREAMBLE | | ||
283 | BSS_CHANGED_ERP_SLOT; | ||
348 | } | 284 | } |
349 | 285 | ||
350 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | 286 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, |
@@ -405,7 +341,8 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
405 | dev_kfree_skb(skb); | 341 | dev_kfree_skb(skb); |
406 | break ; | 342 | break ; |
407 | default: | 343 | default: |
408 | WARN_ON(1); | 344 | WARN(1, "mac80211: Packet is of unknown type %d\n", |
345 | skb->pkt_type); | ||
409 | dev_kfree_skb(skb); | 346 | dev_kfree_skb(skb); |
410 | break; | 347 | break; |
411 | } | 348 | } |
@@ -466,8 +403,6 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
466 | struct sta_info *sta, | 403 | struct sta_info *sta, |
467 | struct sk_buff *skb) | 404 | struct sk_buff *skb) |
468 | { | 405 | { |
469 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
470 | |||
471 | sta->tx_filtered_count++; | 406 | sta->tx_filtered_count++; |
472 | 407 | ||
473 | /* | 408 | /* |
@@ -514,10 +449,9 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
514 | return; | 449 | return; |
515 | } | 450 | } |
516 | 451 | ||
517 | if (!test_sta_flags(sta, WLAN_STA_PS) && | 452 | if (!test_sta_flags(sta, WLAN_STA_PS) && !skb->requeue) { |
518 | !(info->flags & IEEE80211_TX_CTL_REQUEUE)) { | ||
519 | /* Software retry the packet once */ | 453 | /* Software retry the packet once */ |
520 | info->flags |= IEEE80211_TX_CTL_REQUEUE; | 454 | skb->requeue = 1; |
521 | ieee80211_remove_tx_extra(local, sta->key, skb); | 455 | ieee80211_remove_tx_extra(local, sta->key, skb); |
522 | dev_queue_xmit(skb); | 456 | dev_queue_xmit(skb); |
523 | return; | 457 | return; |
@@ -547,13 +481,28 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
547 | struct ieee80211_sub_if_data *sdata; | 481 | struct ieee80211_sub_if_data *sdata; |
548 | struct net_device *prev_dev = NULL; | 482 | struct net_device *prev_dev = NULL; |
549 | struct sta_info *sta; | 483 | struct sta_info *sta; |
484 | int retry_count = -1, i; | ||
485 | |||
486 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
487 | /* the HW cannot have attempted that rate */ | ||
488 | if (i >= hw->max_rates) { | ||
489 | info->status.rates[i].idx = -1; | ||
490 | info->status.rates[i].count = 0; | ||
491 | } | ||
492 | |||
493 | retry_count += info->status.rates[i].count; | ||
494 | } | ||
495 | if (retry_count < 0) | ||
496 | retry_count = 0; | ||
550 | 497 | ||
551 | rcu_read_lock(); | 498 | rcu_read_lock(); |
552 | 499 | ||
500 | sband = local->hw.wiphy->bands[info->band]; | ||
501 | |||
553 | sta = sta_info_get(local, hdr->addr1); | 502 | sta = sta_info_get(local, hdr->addr1); |
554 | 503 | ||
555 | if (sta) { | 504 | if (sta) { |
556 | if (info->status.excessive_retries && | 505 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
557 | test_sta_flags(sta, WLAN_STA_PS)) { | 506 | test_sta_flags(sta, WLAN_STA_PS)) { |
558 | /* | 507 | /* |
559 | * The STA is in power save mode, so assume | 508 | * The STA is in power save mode, so assume |
@@ -584,12 +533,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
584 | rcu_read_unlock(); | 533 | rcu_read_unlock(); |
585 | return; | 534 | return; |
586 | } else { | 535 | } else { |
587 | if (info->status.excessive_retries) | 536 | if (!(info->flags & IEEE80211_TX_STAT_ACK)) |
588 | sta->tx_retry_failed++; | 537 | sta->tx_retry_failed++; |
589 | sta->tx_retry_count += info->status.retry_count; | 538 | sta->tx_retry_count += retry_count; |
590 | } | 539 | } |
591 | 540 | ||
592 | sband = local->hw.wiphy->bands[info->band]; | ||
593 | rate_control_tx_status(local, sband, sta, skb); | 541 | rate_control_tx_status(local, sband, sta, skb); |
594 | } | 542 | } |
595 | 543 | ||
@@ -610,9 +558,9 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
610 | local->dot11TransmittedFrameCount++; | 558 | local->dot11TransmittedFrameCount++; |
611 | if (is_multicast_ether_addr(hdr->addr1)) | 559 | if (is_multicast_ether_addr(hdr->addr1)) |
612 | local->dot11MulticastTransmittedFrameCount++; | 560 | local->dot11MulticastTransmittedFrameCount++; |
613 | if (info->status.retry_count > 0) | 561 | if (retry_count > 0) |
614 | local->dot11RetryCount++; | 562 | local->dot11RetryCount++; |
615 | if (info->status.retry_count > 1) | 563 | if (retry_count > 1) |
616 | local->dot11MultipleRetryCount++; | 564 | local->dot11MultipleRetryCount++; |
617 | } | 565 | } |
618 | 566 | ||
@@ -656,19 +604,30 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
656 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); | 604 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); |
657 | rthdr->hdr.it_present = | 605 | rthdr->hdr.it_present = |
658 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | | 606 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | |
659 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); | 607 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES) | |
608 | (1 << IEEE80211_RADIOTAP_RATE)); | ||
660 | 609 | ||
661 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && | 610 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
662 | !is_multicast_ether_addr(hdr->addr1)) | 611 | !is_multicast_ether_addr(hdr->addr1)) |
663 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); | 612 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); |
664 | 613 | ||
665 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) && | 614 | /* |
666 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) | 615 | * XXX: Once radiotap gets the bitmap reset thing the vendor |
616 | * extensions proposal contains, we can actually report | ||
617 | * the whole set of tries we did. | ||
618 | */ | ||
619 | if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || | ||
620 | (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) | ||
667 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); | 621 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); |
668 | else if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) | 622 | else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) |
669 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); | 623 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); |
624 | if (info->status.rates[0].idx >= 0 && | ||
625 | !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) | ||
626 | rthdr->rate = sband->bitrates[ | ||
627 | info->status.rates[0].idx].bitrate / 5; | ||
670 | 628 | ||
671 | rthdr->data_retries = info->status.retry_count; | 629 | /* for now report the total retry_count */ |
630 | rthdr->data_retries = retry_count; | ||
672 | 631 | ||
673 | /* XXX: is this sufficient for BPF? */ | 632 | /* XXX: is this sufficient for BPF? */ |
674 | skb_set_mac_header(skb, 0); | 633 | skb_set_mac_header(skb, 0); |
@@ -753,20 +712,30 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
753 | BUG_ON(!ops->configure_filter); | 712 | BUG_ON(!ops->configure_filter); |
754 | local->ops = ops; | 713 | local->ops = ops; |
755 | 714 | ||
756 | local->hw.queues = 1; /* default */ | 715 | /* set up some defaults */ |
757 | 716 | local->hw.queues = 1; | |
717 | local->hw.max_rates = 1; | ||
758 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | 718 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; |
759 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; | 719 | local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; |
760 | local->short_retry_limit = 7; | 720 | local->hw.conf.long_frame_max_tx_count = 4; |
761 | local->long_retry_limit = 4; | 721 | local->hw.conf.short_frame_max_tx_count = 7; |
762 | local->hw.conf.radio_enabled = 1; | 722 | local->hw.conf.radio_enabled = true; |
763 | 723 | ||
764 | INIT_LIST_HEAD(&local->interfaces); | 724 | INIT_LIST_HEAD(&local->interfaces); |
765 | 725 | ||
766 | spin_lock_init(&local->key_lock); | 726 | spin_lock_init(&local->key_lock); |
767 | 727 | ||
728 | spin_lock_init(&local->queue_stop_reason_lock); | ||
729 | |||
768 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); | 730 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); |
769 | 731 | ||
732 | INIT_WORK(&local->dynamic_ps_enable_work, | ||
733 | ieee80211_dynamic_ps_enable_work); | ||
734 | INIT_WORK(&local->dynamic_ps_disable_work, | ||
735 | ieee80211_dynamic_ps_disable_work); | ||
736 | setup_timer(&local->dynamic_ps_timer, | ||
737 | ieee80211_dynamic_ps_timer, (unsigned long) local); | ||
738 | |||
770 | sta_info_init(local); | 739 | sta_info_init(local); |
771 | 740 | ||
772 | tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending, | 741 | tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending, |
@@ -788,7 +757,6 @@ EXPORT_SYMBOL(ieee80211_alloc_hw); | |||
788 | int ieee80211_register_hw(struct ieee80211_hw *hw) | 757 | int ieee80211_register_hw(struct ieee80211_hw *hw) |
789 | { | 758 | { |
790 | struct ieee80211_local *local = hw_to_local(hw); | 759 | struct ieee80211_local *local = hw_to_local(hw); |
791 | const char *name; | ||
792 | int result; | 760 | int result; |
793 | enum ieee80211_band band; | 761 | enum ieee80211_band band; |
794 | struct net_device *mdev; | 762 | struct net_device *mdev; |
@@ -853,8 +821,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
853 | mdev->header_ops = &ieee80211_header_ops; | 821 | mdev->header_ops = &ieee80211_header_ops; |
854 | mdev->set_multicast_list = ieee80211_master_set_multicast_list; | 822 | mdev->set_multicast_list = ieee80211_master_set_multicast_list; |
855 | 823 | ||
856 | name = wiphy_dev(local->hw.wiphy)->driver->name; | 824 | local->hw.workqueue = |
857 | local->hw.workqueue = create_freezeable_workqueue(name); | 825 | create_freezeable_workqueue(wiphy_name(local->hw.wiphy)); |
858 | if (!local->hw.workqueue) { | 826 | if (!local->hw.workqueue) { |
859 | result = -ENOMEM; | 827 | result = -ENOMEM; |
860 | goto fail_workqueue; | 828 | goto fail_workqueue; |
@@ -921,12 +889,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
921 | 889 | ||
922 | local->mdev->select_queue = ieee80211_select_queue; | 890 | local->mdev->select_queue = ieee80211_select_queue; |
923 | 891 | ||
924 | /* add one default STA interface */ | 892 | /* add one default STA interface if supported */ |
925 | result = ieee80211_if_add(local, "wlan%d", NULL, | 893 | if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) { |
926 | NL80211_IFTYPE_STATION, NULL); | 894 | result = ieee80211_if_add(local, "wlan%d", NULL, |
927 | if (result) | 895 | NL80211_IFTYPE_STATION, NULL); |
928 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", | 896 | if (result) |
929 | wiphy_name(local->hw.wiphy)); | 897 | printk(KERN_WARNING "%s: Failed to add default virtual iface\n", |
898 | wiphy_name(local->hw.wiphy)); | ||
899 | } | ||
930 | 900 | ||
931 | rtnl_unlock(); | 901 | rtnl_unlock(); |
932 | 902 | ||
@@ -1013,7 +983,7 @@ static int __init ieee80211_init(void) | |||
1013 | 983 | ||
1014 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb)); | 984 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb)); |
1015 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + | 985 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + |
1016 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); | 986 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); |
1017 | 987 | ||
1018 | ret = rc80211_minstrel_init(); | 988 | ret = rc80211_minstrel_init(); |
1019 | if (ret) | 989 | if (ret) |