@@ -105,6 +105,7 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
105
105
struct iwl_tx_cmd * tx_cmd ,
106
106
struct ieee80211_tx_info * info , u8 sta_id )
107
107
{
108
+ struct ieee80211_tx_info * skb_info = IEEE80211_SKB_CB (skb );
108
109
struct ieee80211_hdr * hdr = (void * )skb -> data ;
109
110
__le16 fc = hdr -> frame_control ;
110
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
186
tx_cmd -> tx_flags = cpu_to_le32 (tx_flags );
186
187
/* Total # bytes to be transmitted */
187
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
190
tx_cmd -> next_frame_len = 0 ;
190
191
tx_cmd -> life_time = cpu_to_le32 (TX_CMD_LIFE_TIME_INFINITE );
191
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
*/
328
329
static struct iwl_device_cmd *
329
330
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 )
331
333
{
332
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
336
struct iwl_device_cmd * dev_cmd ;
335
337
struct iwl_tx_cmd * tx_cmd ;
336
338
@@ -350,33 +352,36 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
350
352
351
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 ));
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 ));
355
357
356
- info -> driver_data [1 ] = dev_cmd ;
358
+ skb_info -> driver_data [1 ] = dev_cmd ;
357
359
358
360
return dev_cmd ;
359
361
}
360
362
361
363
int iwl_mvm_tx_skb_non_sta (struct iwl_mvm * mvm , struct sk_buff * skb )
362
364
{
363
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
368
struct iwl_device_cmd * dev_cmd ;
366
369
struct iwl_tx_cmd * tx_cmd ;
367
370
u8 sta_id ;
368
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
376
return -1 ;
372
377
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 )))
376
381
return -1 ;
377
382
378
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
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
390
* and hence needs to be sent on the aux queue
386
391
*/
387
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
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
403
* AUX station.
399
404
*/
400
405
sta_id = mvm -> aux_sta .sta_id ;
401
- if (info -> control .vif ) {
406
+ if (info . control .vif ) {
402
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 ||
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 )
407
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
414
is_multicast_ether_addr (hdr -> addr1 )) {
410
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
425
if (!dev_cmd )
421
426
return -1 ;
422
427
423
- /* From now on, we cannot access info->control */
424
428
tx_cmd = (struct iwl_tx_cmd * )dev_cmd -> payload ;
425
429
426
430
/* Copy MAC header from skb into command buffer */
427
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
434
iwl_trans_free_tx_cmd (mvm -> trans , dev_cmd );
431
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
450
#ifdef CONFIG_INET
447
451
static int iwl_mvm_tx_tso (struct iwl_mvm * mvm , struct sk_buff * skb ,
452
+ struct ieee80211_tx_info * info ,
448
453
struct ieee80211_sta * sta ,
449
454
struct sk_buff_head * mpdus_skb )
450
455
{
451
456
struct iwl_mvm_sta * mvmsta = iwl_mvm_sta_from_mac80211 (sta );
452
- struct ieee80211_tx_info * info = IEEE80211_SKB_CB (skb );
453
457
struct ieee80211_hdr * hdr = (void * )skb -> data ;
454
458
unsigned int mss = skb_shinfo (skb )-> gso_size ;
455
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
549
/* This skb fits in one single A-MSDU */
546
550
if (num_subframes * mss >= tcp_payload_len ) {
551
+ struct ieee80211_tx_info * skb_info = IEEE80211_SKB_CB (skb );
552
+
547
553
/*
548
554
* Compute the length of all the data added for the A-MSDU.
549
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
558
* already had one set of SNAP / IP / TCP headers.
553
559
*/
554
560
num_subframes = DIV_ROUND_UP (tcp_payload_len , mss );
555
- info = IEEE80211_SKB_CB (skb );
556
561
amsdu_add = num_subframes * sizeof (struct ethhdr ) +
557
562
(num_subframes - 1 ) * (snap_ip_tcp + pad );
558
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
566
__skb_queue_tail (mpdus_skb , skb );
562
567
return 0 ;
@@ -596,11 +601,14 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb,
596
601
ip_hdr (tmp )-> id = htons (ip_base_id + i * num_subframes );
597
602
598
603
if (tcp_payload_len > mss ) {
604
+ struct ieee80211_tx_info * skb_info =
605
+ IEEE80211_SKB_CB (tmp );
606
+
599
607
num_subframes = DIV_ROUND_UP (tcp_payload_len , mss );
600
- info = IEEE80211_SKB_CB (tmp );
601
608
amsdu_add = num_subframes * sizeof (struct ethhdr ) +
602
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
612
skb_shinfo (tmp )-> gso_size = mss ;
605
613
} else {
606
614
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,
622
630
}
623
631
#else /* CONFIG_INET */
624
632
static int iwl_mvm_tx_tso (struct iwl_mvm * mvm , struct sk_buff * skb ,
633
+ struct ieee80211_tx_info * info ,
625
634
struct ieee80211_sta * sta ,
626
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
645
* Sets the fields in the Tx cmd that are crypto related
637
646
*/
638
647
static int iwl_mvm_tx_mpdu (struct iwl_mvm * mvm , struct sk_buff * skb ,
648
+ struct ieee80211_tx_info * info ,
639
649
struct ieee80211_sta * sta )
640
650
{
641
651
struct ieee80211_hdr * hdr = (struct ieee80211_hdr * )skb -> data ;
642
- struct ieee80211_tx_info * info = IEEE80211_SKB_CB (skb );
643
652
struct iwl_mvm_sta * mvmsta ;
644
653
struct iwl_device_cmd * dev_cmd ;
645
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
669
if (WARN_ON_ONCE (mvmsta -> sta_id == IWL_MVM_STATION_COUNT ))
661
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
674
if (!dev_cmd )
665
675
goto drop ;
666
676
@@ -736,7 +746,8 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
736
746
struct ieee80211_sta * sta )
737
747
{
738
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
751
struct sk_buff_head mpdus_skbs ;
741
752
unsigned int payload_len ;
742
753
int ret ;
@@ -747,21 +758,23 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
747
758
if (WARN_ON_ONCE (mvmsta -> sta_id == IWL_MVM_STATION_COUNT ))
748
759
return -1 ;
749
760
761
+ memcpy (& info , skb -> cb , sizeof (info ));
762
+
750
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
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
769
payload_len = skb_tail_pointer (skb ) - skb_transport_header (skb ) -
757
770
tcp_hdrlen (skb ) + skb -> data_len ;
758
771
759
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
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
778
if (ret )
766
779
return ret ;
767
780
@@ -771,7 +784,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb,
771
784
while (!skb_queue_empty (& mpdus_skbs )) {
772
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
788
if (ret ) {
776
789
__skb_queue_purge (& mpdus_skbs );
777
790
return ret ;
0 commit comments