aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r--net/mac80211/main.c209
1 files changed, 76 insertions, 133 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index ae62ad40ad63..fa0cc7a1e6b4 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -41,6 +41,8 @@
41 */ 41 */
42struct ieee80211_tx_status_rtap_hdr { 42struct 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));
@@ -197,129 +199,44 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
197 &sdata->vif, &conf); 199 &sdata->vif, &conf);
198} 200}
199 201
200int ieee80211_hw_config(struct ieee80211_local *local) 202int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
201{ 203{
202 struct ieee80211_channel *chan; 204 struct ieee80211_channel *chan;
203 int ret = 0; 205 int ret = 0;
206 int power;
207
208 might_sleep();
204 209
205 if (local->sw_scanning) 210 if (local->sw_scanning)
206 chan = local->scan_channel; 211 chan = local->scan_channel;
207 else 212 else
208 chan = local->oper_channel; 213 chan = local->oper_channel;
209 214
210 local->hw.conf.channel = chan; 215 if (chan != local->hw.conf.channel) {
216 local->hw.conf.channel = chan;
217 changed |= IEEE80211_CONF_CHANGE_CHANNEL;
218 }
219
211 220
212 if (!local->hw.conf.power_level) 221 if (!local->hw.conf.power_level)
213 local->hw.conf.power_level = chan->max_power; 222 power = chan->max_power;
214 else 223 else
215 local->hw.conf.power_level = min(chan->max_power, 224 power = min(chan->max_power, local->hw.conf.power_level);
216 local->hw.conf.power_level); 225 if (local->hw.conf.power_level != power) {
217 226 changed |= IEEE80211_CONF_CHANGE_POWER;
218 local->hw.conf.max_antenna_gain = chan->max_antenna_gain; 227 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 */
236u32 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 } 228 }
259 229
260 /* disable HT */ 230 if (changed && local->open_count) {
261 if (!enable_ht) { 231 ret = local->ops->config(local_to_hw(local), changed);
262 if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) 232 /*
263 changed |= BSS_CHANGED_HT; 233 * HW reconfiguration should never fail, the driver has told
264 conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; 234 * us what it can support so it should live up to that promise.
265 conf->ht_conf.ht_supported = 0; 235 */
266 goto out; 236 WARN_ON(ret);
267 } 237 }
268 238
269 239 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
313check_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 }
321out:
322 return changed;
323} 240}
324 241
325void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, 242void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
@@ -336,15 +253,18 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
336 if (local->ops->bss_info_changed) 253 if (local->ops->bss_info_changed)
337 local->ops->bss_info_changed(local_to_hw(local), 254 local->ops->bss_info_changed(local_to_hw(local),
338 &sdata->vif, 255 &sdata->vif,
339 &sdata->bss_conf, 256 &sdata->vif.bss_conf,
340 changed); 257 changed);
341} 258}
342 259
343u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) 260u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
344{ 261{
345 sdata->bss_conf.use_cts_prot = 0; 262 sdata->vif.bss_conf.use_cts_prot = false;
346 sdata->bss_conf.use_short_preamble = 0; 263 sdata->vif.bss_conf.use_short_preamble = false;
347 return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE; 264 sdata->vif.bss_conf.use_short_slot = false;
265 return BSS_CHANGED_ERP_CTS_PROT |
266 BSS_CHANGED_ERP_PREAMBLE |
267 BSS_CHANGED_ERP_SLOT;
348} 268}
349 269
350void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, 270void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
@@ -466,8 +386,6 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
466 struct sta_info *sta, 386 struct sta_info *sta,
467 struct sk_buff *skb) 387 struct sk_buff *skb)
468{ 388{
469 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
470
471 sta->tx_filtered_count++; 389 sta->tx_filtered_count++;
472 390
473 /* 391 /*
@@ -514,10 +432,9 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
514 return; 432 return;
515 } 433 }
516 434
517 if (!test_sta_flags(sta, WLAN_STA_PS) && 435 if (!test_sta_flags(sta, WLAN_STA_PS) && !skb->requeue) {
518 !(info->flags & IEEE80211_TX_CTL_REQUEUE)) {
519 /* Software retry the packet once */ 436 /* Software retry the packet once */
520 info->flags |= IEEE80211_TX_CTL_REQUEUE; 437 skb->requeue = 1;
521 ieee80211_remove_tx_extra(local, sta->key, skb); 438 ieee80211_remove_tx_extra(local, sta->key, skb);
522 dev_queue_xmit(skb); 439 dev_queue_xmit(skb);
523 return; 440 return;
@@ -547,13 +464,28 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
547 struct ieee80211_sub_if_data *sdata; 464 struct ieee80211_sub_if_data *sdata;
548 struct net_device *prev_dev = NULL; 465 struct net_device *prev_dev = NULL;
549 struct sta_info *sta; 466 struct sta_info *sta;
467 int retry_count = -1, i;
468
469 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
470 /* the HW cannot have attempted that rate */
471 if (i >= hw->max_rates) {
472 info->status.rates[i].idx = -1;
473 info->status.rates[i].count = 0;
474 }
475
476 retry_count += info->status.rates[i].count;
477 }
478 if (retry_count < 0)
479 retry_count = 0;
550 480
551 rcu_read_lock(); 481 rcu_read_lock();
552 482
483 sband = local->hw.wiphy->bands[info->band];
484
553 sta = sta_info_get(local, hdr->addr1); 485 sta = sta_info_get(local, hdr->addr1);
554 486
555 if (sta) { 487 if (sta) {
556 if (info->status.excessive_retries && 488 if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
557 test_sta_flags(sta, WLAN_STA_PS)) { 489 test_sta_flags(sta, WLAN_STA_PS)) {
558 /* 490 /*
559 * The STA is in power save mode, so assume 491 * The STA is in power save mode, so assume
@@ -584,12 +516,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
584 rcu_read_unlock(); 516 rcu_read_unlock();
585 return; 517 return;
586 } else { 518 } else {
587 if (info->status.excessive_retries) 519 if (!(info->flags & IEEE80211_TX_STAT_ACK))
588 sta->tx_retry_failed++; 520 sta->tx_retry_failed++;
589 sta->tx_retry_count += info->status.retry_count; 521 sta->tx_retry_count += retry_count;
590 } 522 }
591 523
592 sband = local->hw.wiphy->bands[info->band];
593 rate_control_tx_status(local, sband, sta, skb); 524 rate_control_tx_status(local, sband, sta, skb);
594 } 525 }
595 526
@@ -610,9 +541,9 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
610 local->dot11TransmittedFrameCount++; 541 local->dot11TransmittedFrameCount++;
611 if (is_multicast_ether_addr(hdr->addr1)) 542 if (is_multicast_ether_addr(hdr->addr1))
612 local->dot11MulticastTransmittedFrameCount++; 543 local->dot11MulticastTransmittedFrameCount++;
613 if (info->status.retry_count > 0) 544 if (retry_count > 0)
614 local->dot11RetryCount++; 545 local->dot11RetryCount++;
615 if (info->status.retry_count > 1) 546 if (retry_count > 1)
616 local->dot11MultipleRetryCount++; 547 local->dot11MultipleRetryCount++;
617 } 548 }
618 549
@@ -656,19 +587,30 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
656 rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); 587 rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr));
657 rthdr->hdr.it_present = 588 rthdr->hdr.it_present =
658 cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | 589 cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) |
659 (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); 590 (1 << IEEE80211_RADIOTAP_DATA_RETRIES) |
591 (1 << IEEE80211_RADIOTAP_RATE));
660 592
661 if (!(info->flags & IEEE80211_TX_STAT_ACK) && 593 if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
662 !is_multicast_ether_addr(hdr->addr1)) 594 !is_multicast_ether_addr(hdr->addr1))
663 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); 595 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL);
664 596
665 if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) && 597 /*
666 (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) 598 * XXX: Once radiotap gets the bitmap reset thing the vendor
599 * extensions proposal contains, we can actually report
600 * the whole set of tries we did.
601 */
602 if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
603 (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
667 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); 604 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS);
668 else if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) 605 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); 606 rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS);
607 if (info->status.rates[0].idx >= 0 &&
608 !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS))
609 rthdr->rate = sband->bitrates[
610 info->status.rates[0].idx].bitrate / 5;
670 611
671 rthdr->data_retries = info->status.retry_count; 612 /* for now report the total retry_count */
613 rthdr->data_retries = retry_count;
672 614
673 /* XXX: is this sufficient for BPF? */ 615 /* XXX: is this sufficient for BPF? */
674 skb_set_mac_header(skb, 0); 616 skb_set_mac_header(skb, 0);
@@ -753,13 +695,14 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
753 BUG_ON(!ops->configure_filter); 695 BUG_ON(!ops->configure_filter);
754 local->ops = ops; 696 local->ops = ops;
755 697
756 local->hw.queues = 1; /* default */ 698 /* set up some defaults */
757 699 local->hw.queues = 1;
700 local->hw.max_rates = 1;
758 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 701 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
759 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; 702 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
760 local->short_retry_limit = 7; 703 local->hw.conf.long_frame_max_tx_count = 4;
761 local->long_retry_limit = 4; 704 local->hw.conf.short_frame_max_tx_count = 7;
762 local->hw.conf.radio_enabled = 1; 705 local->hw.conf.radio_enabled = true;
763 706
764 INIT_LIST_HEAD(&local->interfaces); 707 INIT_LIST_HEAD(&local->interfaces);
765 708
@@ -1013,7 +956,7 @@ static int __init ieee80211_init(void)
1013 956
1014 BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb)); 957 BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb));
1015 BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + 958 BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) +
1016 IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); 959 IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb));
1017 960
1018 ret = rc80211_minstrel_init(); 961 ret = rc80211_minstrel_init();
1019 if (ret) 962 if (ret)