aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2014-11-19 05:32:12 -0500
committerJames Morris <james.l.morris@oracle.com>2014-11-19 05:32:12 -0500
commitb10778a00d40b3d9fdaaf5891e802794781ff71c (patch)
tree6ba4cbac86eecedc3f30650e7f764ecf00c83898 /net/mac80211/util.c
parent594081ee7145cc30a3977cb4e218f81213b63dc5 (diff)
parentbfe01a5ba2490f299e1d2d5508cbbbadd897bbe9 (diff)
Merge commit 'v3.17' into next
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c285
1 files changed, 215 insertions, 70 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index a6cda52ed920..725af7a468d2 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -317,7 +317,8 @@ void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
317} 317}
318 318
319static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, 319static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
320 enum queue_stop_reason reason) 320 enum queue_stop_reason reason,
321 bool refcounted)
321{ 322{
322 struct ieee80211_local *local = hw_to_local(hw); 323 struct ieee80211_local *local = hw_to_local(hw);
323 324
@@ -329,7 +330,13 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
329 if (!test_bit(reason, &local->queue_stop_reasons[queue])) 330 if (!test_bit(reason, &local->queue_stop_reasons[queue]))
330 return; 331 return;
331 332
332 __clear_bit(reason, &local->queue_stop_reasons[queue]); 333 if (!refcounted)
334 local->q_stop_reasons[queue][reason] = 0;
335 else
336 local->q_stop_reasons[queue][reason]--;
337
338 if (local->q_stop_reasons[queue][reason] == 0)
339 __clear_bit(reason, &local->queue_stop_reasons[queue]);
333 340
334 if (local->queue_stop_reasons[queue] != 0) 341 if (local->queue_stop_reasons[queue] != 0)
335 /* someone still has this queue stopped */ 342 /* someone still has this queue stopped */
@@ -344,25 +351,28 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
344} 351}
345 352
346void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, 353void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
347 enum queue_stop_reason reason) 354 enum queue_stop_reason reason,
355 bool refcounted)
348{ 356{
349 struct ieee80211_local *local = hw_to_local(hw); 357 struct ieee80211_local *local = hw_to_local(hw);
350 unsigned long flags; 358 unsigned long flags;
351 359
352 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 360 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
353 __ieee80211_wake_queue(hw, queue, reason); 361 __ieee80211_wake_queue(hw, queue, reason, refcounted);
354 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 362 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
355} 363}
356 364
357void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) 365void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
358{ 366{
359 ieee80211_wake_queue_by_reason(hw, queue, 367 ieee80211_wake_queue_by_reason(hw, queue,
360 IEEE80211_QUEUE_STOP_REASON_DRIVER); 368 IEEE80211_QUEUE_STOP_REASON_DRIVER,
369 false);
361} 370}
362EXPORT_SYMBOL(ieee80211_wake_queue); 371EXPORT_SYMBOL(ieee80211_wake_queue);
363 372
364static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, 373static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
365 enum queue_stop_reason reason) 374 enum queue_stop_reason reason,
375 bool refcounted)
366{ 376{
367 struct ieee80211_local *local = hw_to_local(hw); 377 struct ieee80211_local *local = hw_to_local(hw);
368 struct ieee80211_sub_if_data *sdata; 378 struct ieee80211_sub_if_data *sdata;
@@ -373,10 +383,13 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
373 if (WARN_ON(queue >= hw->queues)) 383 if (WARN_ON(queue >= hw->queues))
374 return; 384 return;
375 385
376 if (test_bit(reason, &local->queue_stop_reasons[queue])) 386 if (!refcounted)
377 return; 387 local->q_stop_reasons[queue][reason] = 1;
388 else
389 local->q_stop_reasons[queue][reason]++;
378 390
379 __set_bit(reason, &local->queue_stop_reasons[queue]); 391 if (__test_and_set_bit(reason, &local->queue_stop_reasons[queue]))
392 return;
380 393
381 if (local->hw.queues < IEEE80211_NUM_ACS) 394 if (local->hw.queues < IEEE80211_NUM_ACS)
382 n_acs = 1; 395 n_acs = 1;
@@ -398,20 +411,22 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
398} 411}
399 412
400void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, 413void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
401 enum queue_stop_reason reason) 414 enum queue_stop_reason reason,
415 bool refcounted)
402{ 416{
403 struct ieee80211_local *local = hw_to_local(hw); 417 struct ieee80211_local *local = hw_to_local(hw);
404 unsigned long flags; 418 unsigned long flags;
405 419
406 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 420 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
407 __ieee80211_stop_queue(hw, queue, reason); 421 __ieee80211_stop_queue(hw, queue, reason, refcounted);
408 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 422 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
409} 423}
410 424
411void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) 425void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
412{ 426{
413 ieee80211_stop_queue_by_reason(hw, queue, 427 ieee80211_stop_queue_by_reason(hw, queue,
414 IEEE80211_QUEUE_STOP_REASON_DRIVER); 428 IEEE80211_QUEUE_STOP_REASON_DRIVER,
429 false);
415} 430}
416EXPORT_SYMBOL(ieee80211_stop_queue); 431EXPORT_SYMBOL(ieee80211_stop_queue);
417 432
@@ -429,9 +444,11 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
429 } 444 }
430 445
431 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 446 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
432 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 447 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
448 false);
433 __skb_queue_tail(&local->pending[queue], skb); 449 __skb_queue_tail(&local->pending[queue], skb);
434 __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 450 __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
451 false);
435 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 452 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
436} 453}
437 454
@@ -455,20 +472,23 @@ void ieee80211_add_pending_skbs(struct ieee80211_local *local,
455 queue = info->hw_queue; 472 queue = info->hw_queue;
456 473
457 __ieee80211_stop_queue(hw, queue, 474 __ieee80211_stop_queue(hw, queue,
458 IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 475 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
476 false);
459 477
460 __skb_queue_tail(&local->pending[queue], skb); 478 __skb_queue_tail(&local->pending[queue], skb);
461 } 479 }
462 480
463 for (i = 0; i < hw->queues; i++) 481 for (i = 0; i < hw->queues; i++)
464 __ieee80211_wake_queue(hw, i, 482 __ieee80211_wake_queue(hw, i,
465 IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 483 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
484 false);
466 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 485 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
467} 486}
468 487
469void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, 488void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
470 unsigned long queues, 489 unsigned long queues,
471 enum queue_stop_reason reason) 490 enum queue_stop_reason reason,
491 bool refcounted)
472{ 492{
473 struct ieee80211_local *local = hw_to_local(hw); 493 struct ieee80211_local *local = hw_to_local(hw);
474 unsigned long flags; 494 unsigned long flags;
@@ -477,7 +497,7 @@ void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
477 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 497 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
478 498
479 for_each_set_bit(i, &queues, hw->queues) 499 for_each_set_bit(i, &queues, hw->queues)
480 __ieee80211_stop_queue(hw, i, reason); 500 __ieee80211_stop_queue(hw, i, reason, refcounted);
481 501
482 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 502 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
483} 503}
@@ -485,7 +505,8 @@ void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
485void ieee80211_stop_queues(struct ieee80211_hw *hw) 505void ieee80211_stop_queues(struct ieee80211_hw *hw)
486{ 506{
487 ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, 507 ieee80211_stop_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
488 IEEE80211_QUEUE_STOP_REASON_DRIVER); 508 IEEE80211_QUEUE_STOP_REASON_DRIVER,
509 false);
489} 510}
490EXPORT_SYMBOL(ieee80211_stop_queues); 511EXPORT_SYMBOL(ieee80211_stop_queues);
491 512
@@ -508,7 +529,8 @@ EXPORT_SYMBOL(ieee80211_queue_stopped);
508 529
509void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, 530void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
510 unsigned long queues, 531 unsigned long queues,
511 enum queue_stop_reason reason) 532 enum queue_stop_reason reason,
533 bool refcounted)
512{ 534{
513 struct ieee80211_local *local = hw_to_local(hw); 535 struct ieee80211_local *local = hw_to_local(hw);
514 unsigned long flags; 536 unsigned long flags;
@@ -517,7 +539,7 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
517 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 539 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
518 540
519 for_each_set_bit(i, &queues, hw->queues) 541 for_each_set_bit(i, &queues, hw->queues)
520 __ieee80211_wake_queue(hw, i, reason); 542 __ieee80211_wake_queue(hw, i, reason, refcounted);
521 543
522 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 544 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
523} 545}
@@ -525,17 +547,16 @@ void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
525void ieee80211_wake_queues(struct ieee80211_hw *hw) 547void ieee80211_wake_queues(struct ieee80211_hw *hw)
526{ 548{
527 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, 549 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
528 IEEE80211_QUEUE_STOP_REASON_DRIVER); 550 IEEE80211_QUEUE_STOP_REASON_DRIVER,
551 false);
529} 552}
530EXPORT_SYMBOL(ieee80211_wake_queues); 553EXPORT_SYMBOL(ieee80211_wake_queues);
531 554
532void ieee80211_flush_queues(struct ieee80211_local *local, 555static unsigned int
533 struct ieee80211_sub_if_data *sdata) 556ieee80211_get_vif_queues(struct ieee80211_local *local,
557 struct ieee80211_sub_if_data *sdata)
534{ 558{
535 u32 queues; 559 unsigned int queues;
536
537 if (!local->ops->flush)
538 return;
539 560
540 if (sdata && local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) { 561 if (sdata && local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) {
541 int ac; 562 int ac;
@@ -551,13 +572,46 @@ void ieee80211_flush_queues(struct ieee80211_local *local,
551 queues = BIT(local->hw.queues) - 1; 572 queues = BIT(local->hw.queues) - 1;
552 } 573 }
553 574
554 ieee80211_stop_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP, 575 return queues;
555 IEEE80211_QUEUE_STOP_REASON_FLUSH); 576}
577
578void ieee80211_flush_queues(struct ieee80211_local *local,
579 struct ieee80211_sub_if_data *sdata)
580{
581 unsigned int queues;
582
583 if (!local->ops->flush)
584 return;
585
586 queues = ieee80211_get_vif_queues(local, sdata);
587
588 ieee80211_stop_queues_by_reason(&local->hw, queues,
589 IEEE80211_QUEUE_STOP_REASON_FLUSH,
590 false);
556 591
557 drv_flush(local, sdata, queues, false); 592 drv_flush(local, sdata, queues, false);
558 593
559 ieee80211_wake_queues_by_reason(&local->hw, IEEE80211_MAX_QUEUE_MAP, 594 ieee80211_wake_queues_by_reason(&local->hw, queues,
560 IEEE80211_QUEUE_STOP_REASON_FLUSH); 595 IEEE80211_QUEUE_STOP_REASON_FLUSH,
596 false);
597}
598
599void ieee80211_stop_vif_queues(struct ieee80211_local *local,
600 struct ieee80211_sub_if_data *sdata,
601 enum queue_stop_reason reason)
602{
603 ieee80211_stop_queues_by_reason(&local->hw,
604 ieee80211_get_vif_queues(local, sdata),
605 reason, true);
606}
607
608void ieee80211_wake_vif_queues(struct ieee80211_local *local,
609 struct ieee80211_sub_if_data *sdata,
610 enum queue_stop_reason reason)
611{
612 ieee80211_wake_queues_by_reason(&local->hw,
613 ieee80211_get_vif_queues(local, sdata),
614 reason, true);
561} 615}
562 616
563static void __iterate_active_interfaces(struct ieee80211_local *local, 617static void __iterate_active_interfaces(struct ieee80211_local *local,
@@ -1166,14 +1220,17 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
1166 } 1220 }
1167} 1221}
1168 1222
1169int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 1223static int ieee80211_build_preq_ies_band(struct ieee80211_local *local,
1170 size_t buffer_len, const u8 *ie, size_t ie_len, 1224 u8 *buffer, size_t buffer_len,
1171 enum ieee80211_band band, u32 rate_mask, 1225 const u8 *ie, size_t ie_len,
1172 struct cfg80211_chan_def *chandef) 1226 enum ieee80211_band band,
1227 u32 rate_mask,
1228 struct cfg80211_chan_def *chandef,
1229 size_t *offset)
1173{ 1230{
1174 struct ieee80211_supported_band *sband; 1231 struct ieee80211_supported_band *sband;
1175 u8 *pos = buffer, *end = buffer + buffer_len; 1232 u8 *pos = buffer, *end = buffer + buffer_len;
1176 size_t offset = 0, noffset; 1233 size_t noffset;
1177 int supp_rates_len, i; 1234 int supp_rates_len, i;
1178 u8 rates[32]; 1235 u8 rates[32];
1179 int num_rates; 1236 int num_rates;
@@ -1181,6 +1238,8 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1181 int shift; 1238 int shift;
1182 u32 rate_flags; 1239 u32 rate_flags;
1183 1240
1241 *offset = 0;
1242
1184 sband = local->hw.wiphy->bands[band]; 1243 sband = local->hw.wiphy->bands[band];
1185 if (WARN_ON_ONCE(!sband)) 1244 if (WARN_ON_ONCE(!sband))
1186 return 0; 1245 return 0;
@@ -1219,12 +1278,12 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1219 noffset = ieee80211_ie_split(ie, ie_len, 1278 noffset = ieee80211_ie_split(ie, ie_len,
1220 before_extrates, 1279 before_extrates,
1221 ARRAY_SIZE(before_extrates), 1280 ARRAY_SIZE(before_extrates),
1222 offset); 1281 *offset);
1223 if (end - pos < noffset - offset) 1282 if (end - pos < noffset - *offset)
1224 goto out_err; 1283 goto out_err;
1225 memcpy(pos, ie + offset, noffset - offset); 1284 memcpy(pos, ie + *offset, noffset - *offset);
1226 pos += noffset - offset; 1285 pos += noffset - *offset;
1227 offset = noffset; 1286 *offset = noffset;
1228 } 1287 }
1229 1288
1230 ext_rates_len = num_rates - supp_rates_len; 1289 ext_rates_len = num_rates - supp_rates_len;
@@ -1258,12 +1317,12 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1258 }; 1317 };
1259 noffset = ieee80211_ie_split(ie, ie_len, 1318 noffset = ieee80211_ie_split(ie, ie_len,
1260 before_ht, ARRAY_SIZE(before_ht), 1319 before_ht, ARRAY_SIZE(before_ht),
1261 offset); 1320 *offset);
1262 if (end - pos < noffset - offset) 1321 if (end - pos < noffset - *offset)
1263 goto out_err; 1322 goto out_err;
1264 memcpy(pos, ie + offset, noffset - offset); 1323 memcpy(pos, ie + *offset, noffset - *offset);
1265 pos += noffset - offset; 1324 pos += noffset - *offset;
1266 offset = noffset; 1325 *offset = noffset;
1267 } 1326 }
1268 1327
1269 if (sband->ht_cap.ht_supported) { 1328 if (sband->ht_cap.ht_supported) {
@@ -1298,12 +1357,12 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1298 }; 1357 };
1299 noffset = ieee80211_ie_split(ie, ie_len, 1358 noffset = ieee80211_ie_split(ie, ie_len,
1300 before_vht, ARRAY_SIZE(before_vht), 1359 before_vht, ARRAY_SIZE(before_vht),
1301 offset); 1360 *offset);
1302 if (end - pos < noffset - offset) 1361 if (end - pos < noffset - *offset)
1303 goto out_err; 1362 goto out_err;
1304 memcpy(pos, ie + offset, noffset - offset); 1363 memcpy(pos, ie + *offset, noffset - *offset);
1305 pos += noffset - offset; 1364 pos += noffset - *offset;
1306 offset = noffset; 1365 *offset = noffset;
1307 } 1366 }
1308 1367
1309 if (sband->vht_cap.vht_supported) { 1368 if (sband->vht_cap.vht_supported) {
@@ -1313,21 +1372,54 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1313 sband->vht_cap.cap); 1372 sband->vht_cap.cap);
1314 } 1373 }
1315 1374
1316 /* add any remaining custom IEs */
1317 if (ie && ie_len) {
1318 noffset = ie_len;
1319 if (end - pos < noffset - offset)
1320 goto out_err;
1321 memcpy(pos, ie + offset, noffset - offset);
1322 pos += noffset - offset;
1323 }
1324
1325 return pos - buffer; 1375 return pos - buffer;
1326 out_err: 1376 out_err:
1327 WARN_ONCE(1, "not enough space for preq IEs\n"); 1377 WARN_ONCE(1, "not enough space for preq IEs\n");
1328 return pos - buffer; 1378 return pos - buffer;
1329} 1379}
1330 1380
1381int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1382 size_t buffer_len,
1383 struct ieee80211_scan_ies *ie_desc,
1384 const u8 *ie, size_t ie_len,
1385 u8 bands_used, u32 *rate_masks,
1386 struct cfg80211_chan_def *chandef)
1387{
1388 size_t pos = 0, old_pos = 0, custom_ie_offset = 0;
1389 int i;
1390
1391 memset(ie_desc, 0, sizeof(*ie_desc));
1392
1393 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
1394 if (bands_used & BIT(i)) {
1395 pos += ieee80211_build_preq_ies_band(local,
1396 buffer + pos,
1397 buffer_len - pos,
1398 ie, ie_len, i,
1399 rate_masks[i],
1400 chandef,
1401 &custom_ie_offset);
1402 ie_desc->ies[i] = buffer + old_pos;
1403 ie_desc->len[i] = pos - old_pos;
1404 old_pos = pos;
1405 }
1406 }
1407
1408 /* add any remaining custom IEs */
1409 if (ie && ie_len) {
1410 if (WARN_ONCE(buffer_len - pos < ie_len - custom_ie_offset,
1411 "not enough space for preq custom IEs\n"))
1412 return pos;
1413 memcpy(buffer + pos, ie + custom_ie_offset,
1414 ie_len - custom_ie_offset);
1415 ie_desc->common_ies = buffer + pos;
1416 ie_desc->common_ie_len = ie_len - custom_ie_offset;
1417 pos += ie_len - custom_ie_offset;
1418 }
1419
1420 return pos;
1421};
1422
1331struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, 1423struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1332 u8 *dst, u32 ratemask, 1424 u8 *dst, u32 ratemask,
1333 struct ieee80211_channel *chan, 1425 struct ieee80211_channel *chan,
@@ -1340,6 +1432,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1340 struct sk_buff *skb; 1432 struct sk_buff *skb;
1341 struct ieee80211_mgmt *mgmt; 1433 struct ieee80211_mgmt *mgmt;
1342 int ies_len; 1434 int ies_len;
1435 u32 rate_masks[IEEE80211_NUM_BANDS] = {};
1436 struct ieee80211_scan_ies dummy_ie_desc;
1343 1437
1344 /* 1438 /*
1345 * Do not send DS Channel parameter for directed probe requests 1439 * Do not send DS Channel parameter for directed probe requests
@@ -1357,10 +1451,11 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1357 if (!skb) 1451 if (!skb)
1358 return NULL; 1452 return NULL;
1359 1453
1454 rate_masks[chan->band] = ratemask;
1360 ies_len = ieee80211_build_preq_ies(local, skb_tail_pointer(skb), 1455 ies_len = ieee80211_build_preq_ies(local, skb_tail_pointer(skb),
1361 skb_tailroom(skb), 1456 skb_tailroom(skb), &dummy_ie_desc,
1362 ie, ie_len, chan->band, 1457 ie, ie_len, BIT(chan->band),
1363 ratemask, &chandef); 1458 rate_masks, &chandef);
1364 skb_put(skb, ies_len); 1459 skb_put(skb, ies_len);
1365 1460
1366 if (dst) { 1461 if (dst) {
@@ -1604,7 +1699,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1604 if (local->use_chanctx) { 1699 if (local->use_chanctx) {
1605 mutex_lock(&local->chanctx_mtx); 1700 mutex_lock(&local->chanctx_mtx);
1606 list_for_each_entry(ctx, &local->chanctx_list, list) 1701 list_for_each_entry(ctx, &local->chanctx_list, list)
1607 WARN_ON(drv_add_chanctx(local, ctx)); 1702 if (ctx->replace_state !=
1703 IEEE80211_CHANCTX_REPLACES_OTHER)
1704 WARN_ON(drv_add_chanctx(local, ctx));
1608 mutex_unlock(&local->chanctx_mtx); 1705 mutex_unlock(&local->chanctx_mtx);
1609 1706
1610 list_for_each_entry(sdata, &local->interfaces, list) { 1707 list_for_each_entry(sdata, &local->interfaces, list) {
@@ -1798,7 +1895,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1798 } 1895 }
1799 1896
1800 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP, 1897 ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
1801 IEEE80211_QUEUE_STOP_REASON_SUSPEND); 1898 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
1899 false);
1802 1900
1803 /* 1901 /*
1804 * Reconfigure sched scan if it was interrupted by FW restart or 1902 * Reconfigure sched scan if it was interrupted by FW restart or
@@ -2836,6 +2934,35 @@ void ieee80211_recalc_dtim(struct ieee80211_local *local,
2836 ps->dtim_count = dtim_count; 2934 ps->dtim_count = dtim_count;
2837} 2935}
2838 2936
2937static u8 ieee80211_chanctx_radar_detect(struct ieee80211_local *local,
2938 struct ieee80211_chanctx *ctx)
2939{
2940 struct ieee80211_sub_if_data *sdata;
2941 u8 radar_detect = 0;
2942
2943 lockdep_assert_held(&local->chanctx_mtx);
2944
2945 if (WARN_ON(ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED))
2946 return 0;
2947
2948 list_for_each_entry(sdata, &ctx->reserved_vifs, reserved_chanctx_list)
2949 if (sdata->reserved_radar_required)
2950 radar_detect |= BIT(sdata->reserved_chandef.width);
2951
2952 /*
2953 * An in-place reservation context should not have any assigned vifs
2954 * until it replaces the other context.
2955 */
2956 WARN_ON(ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER &&
2957 !list_empty(&ctx->assigned_vifs));
2958
2959 list_for_each_entry(sdata, &ctx->assigned_vifs, assigned_chanctx_list)
2960 if (sdata->radar_required)
2961 radar_detect |= BIT(sdata->vif.bss_conf.chandef.width);
2962
2963 return radar_detect;
2964}
2965
2839int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, 2966int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
2840 const struct cfg80211_chan_def *chandef, 2967 const struct cfg80211_chan_def *chandef,
2841 enum ieee80211_chanctx_mode chanmode, 2968 enum ieee80211_chanctx_mode chanmode,
@@ -2877,8 +3004,9 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
2877 num[iftype] = 1; 3004 num[iftype] = 1;
2878 3005
2879 list_for_each_entry(ctx, &local->chanctx_list, list) { 3006 list_for_each_entry(ctx, &local->chanctx_list, list) {
2880 if (ctx->conf.radar_enabled) 3007 if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
2881 radar_detect |= BIT(ctx->conf.def.width); 3008 continue;
3009 radar_detect |= ieee80211_chanctx_radar_detect(local, ctx);
2882 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) { 3010 if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) {
2883 num_different_channels++; 3011 num_different_channels++;
2884 continue; 3012 continue;
@@ -2935,10 +3063,12 @@ int ieee80211_max_num_channels(struct ieee80211_local *local)
2935 lockdep_assert_held(&local->chanctx_mtx); 3063 lockdep_assert_held(&local->chanctx_mtx);
2936 3064
2937 list_for_each_entry(ctx, &local->chanctx_list, list) { 3065 list_for_each_entry(ctx, &local->chanctx_list, list) {
3066 if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED)
3067 continue;
3068
2938 num_different_channels++; 3069 num_different_channels++;
2939 3070
2940 if (ctx->conf.radar_enabled) 3071 radar_detect |= ieee80211_chanctx_radar_detect(local, ctx);
2941 radar_detect |= BIT(ctx->conf.def.width);
2942 } 3072 }
2943 3073
2944 list_for_each_entry_rcu(sdata, &local->interfaces, list) 3074 list_for_each_entry_rcu(sdata, &local->interfaces, list)
@@ -2953,3 +3083,18 @@ int ieee80211_max_num_channels(struct ieee80211_local *local)
2953 3083
2954 return max_num_different_channels; 3084 return max_num_different_channels;
2955} 3085}
3086
3087u8 *ieee80211_add_wmm_info_ie(u8 *buf, u8 qosinfo)
3088{
3089 *buf++ = WLAN_EID_VENDOR_SPECIFIC;
3090 *buf++ = 7; /* len */
3091 *buf++ = 0x00; /* Microsoft OUI 00:50:F2 */
3092 *buf++ = 0x50;
3093 *buf++ = 0xf2;
3094 *buf++ = 2; /* WME */
3095 *buf++ = 0; /* WME info */
3096 *buf++ = 1; /* WME ver */
3097 *buf++ = qosinfo; /* U-APSD no in use */
3098
3099 return buf;
3100}