aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-05-10 01:02:51 -0400
committerDavid S. Miller <davem@davemloft.net>2016-05-10 01:02:51 -0400
commit5e769ada93b2111010d3ca96213fc0b37c95afc8 (patch)
treed9e7f009a0e061d6bb3bc26724667573a3d13867
parentadc0a8bfdc52cbbfe76730b166a17cb0d5cbc0f4 (diff)
parentcbbba30f1ac95a04aae9c61a55aebe5e6fdf29f0 (diff)
Merge tag 'wireless-drivers-for-davem-2016-05-09' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers
Kalle Valo says: ==================== wireless-drivers fixes for 4.6 iwlwifi * fix P2P rates (and possibly other issues) ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/tx.c83
1 files changed, 48 insertions, 35 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index 75870e68a7c3..34731e29c589 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -105,6 +105,7 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
105 struct iwl_tx_cmd *tx_cmd, 105 struct iwl_tx_cmd *tx_cmd,
106 struct ieee80211_tx_info *info, u8 sta_id) 106 struct ieee80211_tx_info *info, u8 sta_id)
107{ 107{
108 struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb);
108 struct ieee80211_hdr *hdr = (void *)skb->data; 109 struct ieee80211_hdr *hdr = (void *)skb->data;
109 __le16 fc = hdr->frame_control; 110 __le16 fc = hdr->frame_control;
110 u32 tx_flags = le32_to_cpu(tx_cmd->tx_flags); 111 u32 tx_flags = le32_to_cpu(tx_cmd->tx_flags);
@@ -185,7 +186,7 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
185 tx_cmd->tx_flags = cpu_to_le32(tx_flags); 186 tx_cmd->tx_flags = cpu_to_le32(tx_flags);
186 /* Total # bytes to be transmitted */ 187 /* Total # bytes to be transmitted */
187 tx_cmd->len = cpu_to_le16((u16)skb->len + 188 tx_cmd->len = cpu_to_le16((u16)skb->len +
188 (uintptr_t)info->driver_data[0]); 189 (uintptr_t)skb_info->driver_data[0]);
189 tx_cmd->next_frame_len = 0; 190 tx_cmd->next_frame_len = 0;
190 tx_cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); 191 tx_cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
191 tx_cmd->sta_id = sta_id; 192 tx_cmd->sta_id = sta_id;
@@ -327,10 +328,11 @@ static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm,
327 */ 328 */
328static struct iwl_device_cmd * 329static struct iwl_device_cmd *
329iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, 330iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
330 int hdrlen, struct ieee80211_sta *sta, u8 sta_id) 331 struct ieee80211_tx_info *info, int hdrlen,
332 struct ieee80211_sta *sta, u8 sta_id)
331{ 333{
332 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 334 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
333 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 335 struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb);
334 struct iwl_device_cmd *dev_cmd; 336 struct iwl_device_cmd *dev_cmd;
335 struct iwl_tx_cmd *tx_cmd; 337 struct iwl_tx_cmd *tx_cmd;
336 338
@@ -350,10 +352,10 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
350 352
351 iwl_mvm_set_tx_cmd_rate(mvm, tx_cmd, info, sta, hdr->frame_control); 353 iwl_mvm_set_tx_cmd_rate(mvm, tx_cmd, info, sta, hdr->frame_control);
352 354
353 memset(&info->status, 0, sizeof(info->status)); 355 memset(&skb_info->status, 0, sizeof(skb_info->status));
354 memset(info->driver_data, 0, sizeof(info->driver_data)); 356 memset(skb_info->driver_data, 0, sizeof(skb_info->driver_data));
355 357
356 info->driver_data[1] = dev_cmd; 358 skb_info->driver_data[1] = dev_cmd;
357 359
358 return dev_cmd; 360 return dev_cmd;
359} 361}
@@ -361,22 +363,25 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
361int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) 363int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
362{ 364{
363 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 365 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
364 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 366 struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb);
367 struct ieee80211_tx_info info;
365 struct iwl_device_cmd *dev_cmd; 368 struct iwl_device_cmd *dev_cmd;
366 struct iwl_tx_cmd *tx_cmd; 369 struct iwl_tx_cmd *tx_cmd;
367 u8 sta_id; 370 u8 sta_id;
368 int hdrlen = ieee80211_hdrlen(hdr->frame_control); 371 int hdrlen = ieee80211_hdrlen(hdr->frame_control);
369 372
370 if (WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_AMPDU)) 373 memcpy(&info, skb->cb, sizeof(info));
374
375 if (WARN_ON_ONCE(info.flags & IEEE80211_TX_CTL_AMPDU))
371 return -1; 376 return -1;
372 377
373 if (WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM && 378 if (WARN_ON_ONCE(info.flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM &&
374 (!info->control.vif || 379 (!info.control.vif ||
375 info->hw_queue != info->control.vif->cab_queue))) 380 info.hw_queue != info.control.vif->cab_queue)))
376 return -1; 381 return -1;
377 382
378 /* This holds the amsdu headers length */ 383 /* This holds the amsdu headers length */
379 info->driver_data[0] = (void *)(uintptr_t)0; 384 skb_info->driver_data[0] = (void *)(uintptr_t)0;
380 385
381 /* 386 /*
382 * IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets that can be used 387 * IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets that can be used
@@ -385,7 +390,7 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
385 * and hence needs to be sent on the aux queue 390 * and hence needs to be sent on the aux queue
386 */ 391 */
387 if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE && 392 if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE &&
388 info->control.vif->type == NL80211_IFTYPE_STATION) 393 info.control.vif->type == NL80211_IFTYPE_STATION)
389 IEEE80211_SKB_CB(skb)->hw_queue = mvm->aux_queue; 394 IEEE80211_SKB_CB(skb)->hw_queue = mvm->aux_queue;
390 395
391 /* 396 /*
@@ -398,14 +403,14 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
398 * AUX station. 403 * AUX station.
399 */ 404 */
400 sta_id = mvm->aux_sta.sta_id; 405 sta_id = mvm->aux_sta.sta_id;
401 if (info->control.vif) { 406 if (info.control.vif) {
402 struct iwl_mvm_vif *mvmvif = 407 struct iwl_mvm_vif *mvmvif =
403 iwl_mvm_vif_from_mac80211(info->control.vif); 408 iwl_mvm_vif_from_mac80211(info.control.vif);
404 409
405 if (info->control.vif->type == NL80211_IFTYPE_P2P_DEVICE || 410 if (info.control.vif->type == NL80211_IFTYPE_P2P_DEVICE ||
406 info->control.vif->type == NL80211_IFTYPE_AP) 411 info.control.vif->type == NL80211_IFTYPE_AP)
407 sta_id = mvmvif->bcast_sta.sta_id; 412 sta_id = mvmvif->bcast_sta.sta_id;
408 else if (info->control.vif->type == NL80211_IFTYPE_STATION && 413 else if (info.control.vif->type == NL80211_IFTYPE_STATION &&
409 is_multicast_ether_addr(hdr->addr1)) { 414 is_multicast_ether_addr(hdr->addr1)) {
410 u8 ap_sta_id = ACCESS_ONCE(mvmvif->ap_sta_id); 415 u8 ap_sta_id = ACCESS_ONCE(mvmvif->ap_sta_id);
411 416
@@ -414,19 +419,18 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
414 } 419 }
415 } 420 }
416 421
417 IWL_DEBUG_TX(mvm, "station Id %d, queue=%d\n", sta_id, info->hw_queue); 422 IWL_DEBUG_TX(mvm, "station Id %d, queue=%d\n", sta_id, info.hw_queue);
418 423
419 dev_cmd = iwl_mvm_set_tx_params(mvm, skb, hdrlen, NULL, sta_id); 424 dev_cmd = iwl_mvm_set_tx_params(mvm, skb, &info, hdrlen, NULL, sta_id);
420 if (!dev_cmd) 425 if (!dev_cmd)
421 return -1; 426 return -1;
422 427
423 /* From now on, we cannot access info->control */
424 tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload; 428 tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload;
425 429
426 /* Copy MAC header from skb into command buffer */ 430 /* Copy MAC header from skb into command buffer */
427 memcpy(tx_cmd->hdr, hdr, hdrlen); 431 memcpy(tx_cmd->hdr, hdr, hdrlen);
428 432
429 if (iwl_trans_tx(mvm->trans, skb, dev_cmd, info->hw_queue)) { 433 if (iwl_trans_tx(mvm->trans, skb, dev_cmd, info.hw_queue)) {
430 iwl_trans_free_tx_cmd(mvm->trans, dev_cmd); 434 iwl_trans_free_tx_cmd(mvm->trans, dev_cmd);
431 return -1; 435 return -1;
432 } 436 }
@@ -445,11 +449,11 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
445 449
446#ifdef CONFIG_INET 450#ifdef CONFIG_INET
447static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, 451static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
452 struct ieee80211_tx_info *info,
448 struct ieee80211_sta *sta, 453 struct ieee80211_sta *sta,
449 struct sk_buff_head *mpdus_skb) 454 struct sk_buff_head *mpdus_skb)
450{ 455{
451 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 456 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
452 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
453 struct ieee80211_hdr *hdr = (void *)skb->data; 457 struct ieee80211_hdr *hdr = (void *)skb->data;
454 unsigned int mss = skb_shinfo(skb)->gso_size; 458 unsigned int mss = skb_shinfo(skb)->gso_size;
455 struct sk_buff *tmp, *next; 459 struct sk_buff *tmp, *next;
@@ -544,6 +548,8 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
544 548
545 /* This skb fits in one single A-MSDU */ 549 /* This skb fits in one single A-MSDU */
546 if (num_subframes * mss >= tcp_payload_len) { 550 if (num_subframes * mss >= tcp_payload_len) {
551 struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb);
552
547 /* 553 /*
548 * Compute the length of all the data added for the A-MSDU. 554 * Compute the length of all the data added for the A-MSDU.
549 * This will be used to compute the length to write in the TX 555 * This will be used to compute the length to write in the TX
@@ -552,11 +558,10 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
552 * already had one set of SNAP / IP / TCP headers. 558 * already had one set of SNAP / IP / TCP headers.
553 */ 559 */
554 num_subframes = DIV_ROUND_UP(tcp_payload_len, mss); 560 num_subframes = DIV_ROUND_UP(tcp_payload_len, mss);
555 info = IEEE80211_SKB_CB(skb);
556 amsdu_add = num_subframes * sizeof(struct ethhdr) + 561 amsdu_add = num_subframes * sizeof(struct ethhdr) +
557 (num_subframes - 1) * (snap_ip_tcp + pad); 562 (num_subframes - 1) * (snap_ip_tcp + pad);
558 /* This holds the amsdu headers length */ 563 /* This holds the amsdu headers length */
559 info->driver_data[0] = (void *)(uintptr_t)amsdu_add; 564 skb_info->driver_data[0] = (void *)(uintptr_t)amsdu_add;
560 565
561 __skb_queue_tail(mpdus_skb, skb); 566 __skb_queue_tail(mpdus_skb, skb);
562 return 0; 567 return 0;
@@ -596,11 +601,14 @@ segment:
596 ip_hdr(tmp)->id = htons(ip_base_id + i * num_subframes); 601 ip_hdr(tmp)->id = htons(ip_base_id + i * num_subframes);
597 602
598 if (tcp_payload_len > mss) { 603 if (tcp_payload_len > mss) {
604 struct ieee80211_tx_info *skb_info =
605 IEEE80211_SKB_CB(tmp);
606
599 num_subframes = DIV_ROUND_UP(tcp_payload_len, mss); 607 num_subframes = DIV_ROUND_UP(tcp_payload_len, mss);
600 info = IEEE80211_SKB_CB(tmp);
601 amsdu_add = num_subframes * sizeof(struct ethhdr) + 608 amsdu_add = num_subframes * sizeof(struct ethhdr) +
602 (num_subframes - 1) * (snap_ip_tcp + pad); 609 (num_subframes - 1) * (snap_ip_tcp + pad);
603 info->driver_data[0] = (void *)(uintptr_t)amsdu_add; 610 skb_info->driver_data[0] =
611 (void *)(uintptr_t)amsdu_add;
604 skb_shinfo(tmp)->gso_size = mss; 612 skb_shinfo(tmp)->gso_size = mss;
605 } else { 613 } else {
606 qc = ieee80211_get_qos_ctl((void *)tmp->data); 614 qc = ieee80211_get_qos_ctl((void *)tmp->data);
@@ -622,6 +630,7 @@ segment:
622} 630}
623#else /* CONFIG_INET */ 631#else /* CONFIG_INET */
624static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, 632static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
633 struct ieee80211_tx_info *info,
625 struct ieee80211_sta *sta, 634 struct ieee80211_sta *sta,
626 struct sk_buff_head *mpdus_skb) 635 struct sk_buff_head *mpdus_skb)
627{ 636{
@@ -636,10 +645,10 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
636 * Sets the fields in the Tx cmd that are crypto related 645 * Sets the fields in the Tx cmd that are crypto related
637 */ 646 */
638static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb, 647static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
648 struct ieee80211_tx_info *info,
639 struct ieee80211_sta *sta) 649 struct ieee80211_sta *sta)
640{ 650{
641 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 651 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
642 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
643 struct iwl_mvm_sta *mvmsta; 652 struct iwl_mvm_sta *mvmsta;
644 struct iwl_device_cmd *dev_cmd; 653 struct iwl_device_cmd *dev_cmd;
645 struct iwl_tx_cmd *tx_cmd; 654 struct iwl_tx_cmd *tx_cmd;
@@ -660,7 +669,8 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
660 if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_STATION_COUNT)) 669 if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_STATION_COUNT))
661 return -1; 670 return -1;
662 671
663 dev_cmd = iwl_mvm_set_tx_params(mvm, skb, hdrlen, sta, mvmsta->sta_id); 672 dev_cmd = iwl_mvm_set_tx_params(mvm, skb, info, hdrlen,
673 sta, mvmsta->sta_id);
664 if (!dev_cmd) 674 if (!dev_cmd)
665 goto drop; 675 goto drop;
666 676
@@ -736,7 +746,8 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
736 struct ieee80211_sta *sta) 746 struct ieee80211_sta *sta)
737{ 747{
738 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 748 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
739 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 749 struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb);
750 struct ieee80211_tx_info info;
740 struct sk_buff_head mpdus_skbs; 751 struct sk_buff_head mpdus_skbs;
741 unsigned int payload_len; 752 unsigned int payload_len;
742 int ret; 753 int ret;
@@ -747,21 +758,23 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
747 if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_STATION_COUNT)) 758 if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_STATION_COUNT))
748 return -1; 759 return -1;
749 760
761 memcpy(&info, skb->cb, sizeof(info));
762
750 /* This holds the amsdu headers length */ 763 /* This holds the amsdu headers length */
751 info->driver_data[0] = (void *)(uintptr_t)0; 764 skb_info->driver_data[0] = (void *)(uintptr_t)0;
752 765
753 if (!skb_is_gso(skb)) 766 if (!skb_is_gso(skb))
754 return iwl_mvm_tx_mpdu(mvm, skb, sta); 767 return iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
755 768
756 payload_len = skb_tail_pointer(skb) - skb_transport_header(skb) - 769 payload_len = skb_tail_pointer(skb) - skb_transport_header(skb) -
757 tcp_hdrlen(skb) + skb->data_len; 770 tcp_hdrlen(skb) + skb->data_len;
758 771
759 if (payload_len <= skb_shinfo(skb)->gso_size) 772 if (payload_len <= skb_shinfo(skb)->gso_size)
760 return iwl_mvm_tx_mpdu(mvm, skb, sta); 773 return iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
761 774
762 __skb_queue_head_init(&mpdus_skbs); 775 __skb_queue_head_init(&mpdus_skbs);
763 776
764 ret = iwl_mvm_tx_tso(mvm, skb, sta, &mpdus_skbs); 777 ret = iwl_mvm_tx_tso(mvm, skb, &info, sta, &mpdus_skbs);
765 if (ret) 778 if (ret)
766 return ret; 779 return ret;
767 780
@@ -771,7 +784,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
771 while (!skb_queue_empty(&mpdus_skbs)) { 784 while (!skb_queue_empty(&mpdus_skbs)) {
772 skb = __skb_dequeue(&mpdus_skbs); 785 skb = __skb_dequeue(&mpdus_skbs);
773 786
774 ret = iwl_mvm_tx_mpdu(mvm, skb, sta); 787 ret = iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
775 if (ret) { 788 if (ret) {
776 __skb_queue_purge(&mpdus_skbs); 789 __skb_queue_purge(&mpdus_skbs);
777 return ret; 790 return ret;