@@ -545,13 +545,24 @@ static bool iwl_mvm_use_host_rate(struct iwl_mvm *mvm,
545
545
return mvm -> trans -> trans_cfg -> device_family < IWL_DEVICE_FAMILY_BZ ;
546
546
}
547
547
548
+ static void iwl_mvm_copy_hdr (void * cmd , const void * hdr , int hdrlen ,
549
+ const u8 * addr3_override )
550
+ {
551
+ struct ieee80211_hdr * out_hdr = cmd ;
552
+
553
+ memcpy (cmd , hdr , hdrlen );
554
+ if (addr3_override )
555
+ memcpy (out_hdr -> addr3 , addr3_override , ETH_ALEN );
556
+ }
557
+
548
558
/*
549
559
* Allocates and sets the Tx cmd the driver data pointers in the skb
550
560
*/
551
561
static struct iwl_device_tx_cmd *
552
562
iwl_mvm_set_tx_params (struct iwl_mvm * mvm , struct sk_buff * skb ,
553
563
struct ieee80211_tx_info * info , int hdrlen ,
554
- struct ieee80211_sta * sta , u8 sta_id )
564
+ struct ieee80211_sta * sta , u8 sta_id ,
565
+ const u8 * addr3_override )
555
566
{
556
567
struct ieee80211_hdr * hdr = (struct ieee80211_hdr * )skb -> data ;
557
568
struct iwl_device_tx_cmd * dev_cmd ;
@@ -609,7 +620,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
609
620
cmd -> len = cpu_to_le16 ((u16 )skb -> len );
610
621
611
622
/* Copy MAC header from skb into command buffer */
612
- memcpy (cmd -> hdr , hdr , hdrlen );
623
+ iwl_mvm_copy_hdr (cmd -> hdr , hdr , hdrlen , addr3_override );
613
624
614
625
cmd -> flags = cpu_to_le16 (flags );
615
626
cmd -> rate_n_flags = cpu_to_le32 (rate_n_flags );
@@ -624,7 +635,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
624
635
cmd -> len = cpu_to_le16 ((u16 )skb -> len );
625
636
626
637
/* Copy MAC header from skb into command buffer */
627
- memcpy (cmd -> hdr , hdr , hdrlen );
638
+ iwl_mvm_copy_hdr (cmd -> hdr , hdr , hdrlen , addr3_override );
628
639
629
640
cmd -> flags = cpu_to_le32 (flags );
630
641
cmd -> rate_n_flags = cpu_to_le32 (rate_n_flags );
@@ -642,7 +653,7 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb,
642
653
iwl_mvm_set_tx_cmd_rate (mvm , tx_cmd , info , sta , hdr -> frame_control );
643
654
644
655
/* Copy MAC header from skb into command buffer */
645
- memcpy (tx_cmd -> hdr , hdr , hdrlen );
656
+ iwl_mvm_copy_hdr (tx_cmd -> hdr , hdr , hdrlen , addr3_override );
646
657
647
658
out :
648
659
return dev_cmd ;
@@ -845,7 +856,8 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb)
845
856
846
857
IWL_DEBUG_TX (mvm , "station Id %d, queue=%d\n" , sta_id , queue );
847
858
848
- dev_cmd = iwl_mvm_set_tx_params (mvm , skb , & info , hdrlen , NULL , sta_id );
859
+ dev_cmd = iwl_mvm_set_tx_params (mvm , skb , & info , hdrlen , NULL , sta_id ,
860
+ NULL );
849
861
if (!dev_cmd )
850
862
return -1 ;
851
863
@@ -1171,7 +1183,8 @@ static int iwl_mvm_tx_pkt_queued(struct iwl_mvm *mvm,
1171
1183
*/
1172
1184
static int iwl_mvm_tx_mpdu (struct iwl_mvm * mvm , struct sk_buff * skb ,
1173
1185
struct ieee80211_tx_info * info ,
1174
- struct ieee80211_sta * sta )
1186
+ struct ieee80211_sta * sta ,
1187
+ const u8 * addr3_override )
1175
1188
{
1176
1189
struct ieee80211_hdr * hdr = (struct ieee80211_hdr * )skb -> data ;
1177
1190
struct iwl_mvm_sta * mvmsta ;
@@ -1203,7 +1216,8 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
1203
1216
iwl_mvm_probe_resp_set_noa (mvm , skb );
1204
1217
1205
1218
dev_cmd = iwl_mvm_set_tx_params (mvm , skb , info , hdrlen ,
1206
- sta , mvmsta -> deflink .sta_id );
1219
+ sta , mvmsta -> deflink .sta_id ,
1220
+ addr3_override );
1207
1221
if (!dev_cmd )
1208
1222
goto drop ;
1209
1223
@@ -1325,9 +1339,11 @@ int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
1325
1339
struct iwl_mvm_sta * mvmsta = iwl_mvm_sta_from_mac80211 (sta );
1326
1340
struct ieee80211_tx_info info ;
1327
1341
struct sk_buff_head mpdus_skbs ;
1342
+ struct ieee80211_vif * vif ;
1328
1343
unsigned int payload_len ;
1329
1344
int ret ;
1330
1345
struct sk_buff * orig_skb = skb ;
1346
+ const u8 * addr3 ;
1331
1347
1332
1348
if (WARN_ON_ONCE (!mvmsta ))
1333
1349
return -1 ;
@@ -1338,26 +1354,59 @@ int iwl_mvm_tx_skb_sta(struct iwl_mvm *mvm, struct sk_buff *skb,
1338
1354
memcpy (& info , skb -> cb , sizeof (info ));
1339
1355
1340
1356
if (!skb_is_gso (skb ))
1341
- return iwl_mvm_tx_mpdu (mvm , skb , & info , sta );
1357
+ return iwl_mvm_tx_mpdu (mvm , skb , & info , sta , NULL );
1342
1358
1343
1359
payload_len = skb_tail_pointer (skb ) - skb_transport_header (skb ) -
1344
1360
tcp_hdrlen (skb ) + skb -> data_len ;
1345
1361
1346
1362
if (payload_len <= skb_shinfo (skb )-> gso_size )
1347
- return iwl_mvm_tx_mpdu (mvm , skb , & info , sta );
1363
+ return iwl_mvm_tx_mpdu (mvm , skb , & info , sta , NULL );
1348
1364
1349
1365
__skb_queue_head_init (& mpdus_skbs );
1350
1366
1367
+ vif = info .control .vif ;
1368
+ if (!vif )
1369
+ return -1 ;
1370
+
1351
1371
ret = iwl_mvm_tx_tso (mvm , skb , & info , sta , & mpdus_skbs );
1352
1372
if (ret )
1353
1373
return ret ;
1354
1374
1355
1375
WARN_ON (skb_queue_empty (& mpdus_skbs ));
1356
1376
1377
+ /*
1378
+ * As described in IEEE sta 802.11-2020, table 9-30 (Address
1379
+ * field contents), A-MSDU address 3 should contain the BSSID
1380
+ * address.
1381
+ * Pass address 3 down to iwl_mvm_tx_mpdu() and further to set it
1382
+ * in the command header. We need to preserve the original
1383
+ * address 3 in the skb header to correctly create all the
1384
+ * A-MSDU subframe headers from it.
1385
+ */
1386
+ switch (vif -> type ) {
1387
+ case NL80211_IFTYPE_STATION :
1388
+ addr3 = vif -> cfg .ap_addr ;
1389
+ break ;
1390
+ case NL80211_IFTYPE_AP :
1391
+ addr3 = vif -> addr ;
1392
+ break ;
1393
+ default :
1394
+ addr3 = NULL ;
1395
+ break ;
1396
+ }
1397
+
1357
1398
while (!skb_queue_empty (& mpdus_skbs )) {
1399
+ struct ieee80211_hdr * hdr ;
1400
+ bool amsdu ;
1401
+
1358
1402
skb = __skb_dequeue (& mpdus_skbs );
1403
+ hdr = (void * )skb -> data ;
1404
+ amsdu = ieee80211_is_data_qos (hdr -> frame_control ) &&
1405
+ (* ieee80211_get_qos_ctl (hdr ) &
1406
+ IEEE80211_QOS_CTL_A_MSDU_PRESENT );
1359
1407
1360
- ret = iwl_mvm_tx_mpdu (mvm , skb , & info , sta );
1408
+ ret = iwl_mvm_tx_mpdu (mvm , skb , & info , sta ,
1409
+ amsdu ? addr3 : NULL );
1361
1410
if (ret ) {
1362
1411
/* Free skbs created as part of TSO logic that have not yet been dequeued */
1363
1412
__skb_queue_purge (& mpdus_skbs );
0 commit comments