Skip to content

Commit 5e769ad

Browse files
committed
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 <[email protected]>
2 parents adc0a8b + cbbba30 commit 5e769ad

File tree

1 file changed

+48
-35
lines changed
  • drivers/net/wireless/intel/iwlwifi/mvm

1 file changed

+48
-35
lines changed

drivers/net/wireless/intel/iwlwifi/mvm/tx.c

Lines changed: 48 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
105105
struct iwl_tx_cmd *tx_cmd,
106106
struct ieee80211_tx_info *info, u8 sta_id)
107107
{
108+
struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb);
108109
struct ieee80211_hdr *hdr = (void *)skb->data;
109110
__le16 fc = hdr->frame_control;
110111
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,
185186
tx_cmd->tx_flags = cpu_to_le32(tx_flags);
186187
/* Total # bytes to be transmitted */
187188
tx_cmd->len = cpu_to_le16((u16)skb->len +
188-
(uintptr_t)info->driver_data[0]);
189+
(uintptr_t)skb_info->driver_data[0]);
189190
tx_cmd->next_frame_len = 0;
190191
tx_cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
191192
tx_cmd->sta_id = sta_id;
@@ -327,10 +328,11 @@ static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm,
327328
*/
328329
static struct iwl_device_cmd *
329330
iwl_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)
331333
{
332334
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);
334336
struct iwl_device_cmd *dev_cmd;
335337
struct iwl_tx_cmd *tx_cmd;
336338

@@ -350,33 +352,36 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
350352

351353
iwl_mvm_set_tx_cmd_rate(mvm, tx_cmd, info, sta, hdr->frame_control);
352354

353-
memset(&info->status, 0, sizeof(info->status));
354-
memset(info->driver_data, 0, sizeof(info->driver_data));
355+
memset(&skb_info->status, 0, sizeof(skb_info->status));
356+
memset(skb_info->driver_data, 0, sizeof(skb_info->driver_data));
355357

356-
info->driver_data[1] = dev_cmd;
358+
skb_info->driver_data[1] = dev_cmd;
357359

358360
return dev_cmd;
359361
}
360362

361363
int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
362364
{
363365
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;
365368
struct iwl_device_cmd *dev_cmd;
366369
struct iwl_tx_cmd *tx_cmd;
367370
u8 sta_id;
368371
int hdrlen = ieee80211_hdrlen(hdr->frame_control);
369372

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))
371376
return -1;
372377

373-
if (WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM &&
374-
(!info->control.vif ||
375-
info->hw_queue != info->control.vif->cab_queue)))
378+
if (WARN_ON_ONCE(info.flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM &&
379+
(!info.control.vif ||
380+
info.hw_queue != info.control.vif->cab_queue)))
376381
return -1;
377382

378383
/* 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;
380385

381386
/*
382387
* 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)
385390
* and hence needs to be sent on the aux queue
386391
*/
387392
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)
389394
IEEE80211_SKB_CB(skb)->hw_queue = mvm->aux_queue;
390395

391396
/*
@@ -398,14 +403,14 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
398403
* AUX station.
399404
*/
400405
sta_id = mvm->aux_sta.sta_id;
401-
if (info->control.vif) {
406+
if (info.control.vif) {
402407
struct iwl_mvm_vif *mvmvif =
403-
iwl_mvm_vif_from_mac80211(info->control.vif);
408+
iwl_mvm_vif_from_mac80211(info.control.vif);
404409

405-
if (info->control.vif->type == NL80211_IFTYPE_P2P_DEVICE ||
406-
info->control.vif->type == NL80211_IFTYPE_AP)
410+
if (info.control.vif->type == NL80211_IFTYPE_P2P_DEVICE ||
411+
info.control.vif->type == NL80211_IFTYPE_AP)
407412
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 &&
409414
is_multicast_ether_addr(hdr->addr1)) {
410415
u8 ap_sta_id = ACCESS_ONCE(mvmvif->ap_sta_id);
411416

@@ -414,19 +419,18 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
414419
}
415420
}
416421

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);
418423

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);
420425
if (!dev_cmd)
421426
return -1;
422427

423-
/* From now on, we cannot access info->control */
424428
tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload;
425429

426430
/* Copy MAC header from skb into command buffer */
427431
memcpy(tx_cmd->hdr, hdr, hdrlen);
428432

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)) {
430434
iwl_trans_free_tx_cmd(mvm->trans, dev_cmd);
431435
return -1;
432436
}
@@ -445,11 +449,11 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
445449

446450
#ifdef CONFIG_INET
447451
static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
452+
struct ieee80211_tx_info *info,
448453
struct ieee80211_sta *sta,
449454
struct sk_buff_head *mpdus_skb)
450455
{
451456
struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
452-
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
453457
struct ieee80211_hdr *hdr = (void *)skb->data;
454458
unsigned int mss = skb_shinfo(skb)->gso_size;
455459
struct sk_buff *tmp, *next;
@@ -544,6 +548,8 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
544548

545549
/* This skb fits in one single A-MSDU */
546550
if (num_subframes * mss >= tcp_payload_len) {
551+
struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb);
552+
547553
/*
548554
* Compute the length of all the data added for the A-MSDU.
549555
* 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,
552558
* already had one set of SNAP / IP / TCP headers.
553559
*/
554560
num_subframes = DIV_ROUND_UP(tcp_payload_len, mss);
555-
info = IEEE80211_SKB_CB(skb);
556561
amsdu_add = num_subframes * sizeof(struct ethhdr) +
557562
(num_subframes - 1) * (snap_ip_tcp + pad);
558563
/* 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;
560565

561566
__skb_queue_tail(mpdus_skb, skb);
562567
return 0;
@@ -596,11 +601,14 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
596601
ip_hdr(tmp)->id = htons(ip_base_id + i * num_subframes);
597602

598603
if (tcp_payload_len > mss) {
604+
struct ieee80211_tx_info *skb_info =
605+
IEEE80211_SKB_CB(tmp);
606+
599607
num_subframes = DIV_ROUND_UP(tcp_payload_len, mss);
600-
info = IEEE80211_SKB_CB(tmp);
601608
amsdu_add = num_subframes * sizeof(struct ethhdr) +
602609
(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;
604612
skb_shinfo(tmp)->gso_size = mss;
605613
} else {
606614
qc = ieee80211_get_qos_ctl((void *)tmp->data);
@@ -622,6 +630,7 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
622630
}
623631
#else /* CONFIG_INET */
624632
static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
633+
struct ieee80211_tx_info *info,
625634
struct ieee80211_sta *sta,
626635
struct sk_buff_head *mpdus_skb)
627636
{
@@ -636,10 +645,10 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
636645
* Sets the fields in the Tx cmd that are crypto related
637646
*/
638647
static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
648+
struct ieee80211_tx_info *info,
639649
struct ieee80211_sta *sta)
640650
{
641651
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
642-
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
643652
struct iwl_mvm_sta *mvmsta;
644653
struct iwl_device_cmd *dev_cmd;
645654
struct iwl_tx_cmd *tx_cmd;
@@ -660,7 +669,8 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
660669
if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_STATION_COUNT))
661670
return -1;
662671

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);
664674
if (!dev_cmd)
665675
goto drop;
666676

@@ -736,7 +746,8 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
736746
struct ieee80211_sta *sta)
737747
{
738748
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;
740751
struct sk_buff_head mpdus_skbs;
741752
unsigned int payload_len;
742753
int ret;
@@ -747,21 +758,23 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
747758
if (WARN_ON_ONCE(mvmsta->sta_id == IWL_MVM_STATION_COUNT))
748759
return -1;
749760

761+
memcpy(&info, skb->cb, sizeof(info));
762+
750763
/* 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;
752765

753766
if (!skb_is_gso(skb))
754-
return iwl_mvm_tx_mpdu(mvm, skb, sta);
767+
return iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
755768

756769
payload_len = skb_tail_pointer(skb) - skb_transport_header(skb) -
757770
tcp_hdrlen(skb) + skb->data_len;
758771

759772
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);
761774

762775
__skb_queue_head_init(&mpdus_skbs);
763776

764-
ret = iwl_mvm_tx_tso(mvm, skb, sta, &mpdus_skbs);
777+
ret = iwl_mvm_tx_tso(mvm, skb, &info, sta, &mpdus_skbs);
765778
if (ret)
766779
return ret;
767780

@@ -771,7 +784,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
771784
while (!skb_queue_empty(&mpdus_skbs)) {
772785
skb = __skb_dequeue(&mpdus_skbs);
773786

774-
ret = iwl_mvm_tx_mpdu(mvm, skb, sta);
787+
ret = iwl_mvm_tx_mpdu(mvm, skb, &info, sta);
775788
if (ret) {
776789
__skb_queue_purge(&mpdus_skbs);
777790
return ret;

0 commit comments

Comments
 (0)