@@ -548,6 +548,11 @@ static int ath10k_htt_rx_crypto_param_len(struct ath10k *ar,
548548 return IEEE80211_TKIP_IV_LEN ;
549549 case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2 :
550550 return IEEE80211_CCMP_HDR_LEN ;
551+ case HTT_RX_MPDU_ENCRYPT_AES_CCM256_WPA2 :
552+ return IEEE80211_CCMP_256_HDR_LEN ;
553+ case HTT_RX_MPDU_ENCRYPT_AES_GCMP_WPA2 :
554+ case HTT_RX_MPDU_ENCRYPT_AES_GCMP256_WPA2 :
555+ return IEEE80211_GCMP_HDR_LEN ;
551556 case HTT_RX_MPDU_ENCRYPT_WEP128 :
552557 case HTT_RX_MPDU_ENCRYPT_WAPI :
553558 break ;
@@ -573,6 +578,11 @@ static int ath10k_htt_rx_crypto_tail_len(struct ath10k *ar,
573578 return IEEE80211_TKIP_ICV_LEN ;
574579 case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2 :
575580 return IEEE80211_CCMP_MIC_LEN ;
581+ case HTT_RX_MPDU_ENCRYPT_AES_CCM256_WPA2 :
582+ return IEEE80211_CCMP_256_MIC_LEN ;
583+ case HTT_RX_MPDU_ENCRYPT_AES_GCMP_WPA2 :
584+ case HTT_RX_MPDU_ENCRYPT_AES_GCMP256_WPA2 :
585+ return IEEE80211_GCMP_MIC_LEN ;
576586 case HTT_RX_MPDU_ENCRYPT_WEP128 :
577587 case HTT_RX_MPDU_ENCRYPT_WAPI :
578588 break ;
@@ -1024,9 +1034,21 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar,
10241034 hdr = (void * )msdu -> data ;
10251035
10261036 /* Tail */
1027- if (status -> flag & RX_FLAG_IV_STRIPPED )
1037+ if (status -> flag & RX_FLAG_IV_STRIPPED ) {
10281038 skb_trim (msdu , msdu -> len -
10291039 ath10k_htt_rx_crypto_tail_len (ar , enctype ));
1040+ } else {
1041+ /* MIC */
1042+ if ((status -> flag & RX_FLAG_MIC_STRIPPED ) &&
1043+ enctype == HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2 )
1044+ skb_trim (msdu , msdu -> len - 8 );
1045+
1046+ /* ICV */
1047+ if (status -> flag & RX_FLAG_ICV_STRIPPED &&
1048+ enctype != HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2 )
1049+ skb_trim (msdu , msdu -> len -
1050+ ath10k_htt_rx_crypto_tail_len (ar , enctype ));
1051+ }
10301052
10311053 /* MMIC */
10321054 if ((status -> flag & RX_FLAG_MMIC_STRIPPED ) &&
@@ -1048,14 +1070,16 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar,
10481070static void ath10k_htt_rx_h_undecap_nwifi (struct ath10k * ar ,
10491071 struct sk_buff * msdu ,
10501072 struct ieee80211_rx_status * status ,
1051- const u8 first_hdr [64 ])
1073+ const u8 first_hdr [64 ],
1074+ enum htt_rx_mpdu_encrypt_type enctype )
10521075{
10531076 struct ieee80211_hdr * hdr ;
10541077 struct htt_rx_desc * rxd ;
10551078 size_t hdr_len ;
10561079 u8 da [ETH_ALEN ];
10571080 u8 sa [ETH_ALEN ];
10581081 int l3_pad_bytes ;
1082+ int bytes_aligned = ar -> hw_params .decap_align_bytes ;
10591083
10601084 /* Delivered decapped frame:
10611085 * [nwifi 802.11 header] <-- replaced with 802.11 hdr
@@ -1084,6 +1108,14 @@ static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar,
10841108 /* push original 802.11 header */
10851109 hdr = (struct ieee80211_hdr * )first_hdr ;
10861110 hdr_len = ieee80211_hdrlen (hdr -> frame_control );
1111+
1112+ if (!(status -> flag & RX_FLAG_IV_STRIPPED )) {
1113+ memcpy (skb_push (msdu ,
1114+ ath10k_htt_rx_crypto_param_len (ar , enctype )),
1115+ (void * )hdr + round_up (hdr_len , bytes_aligned ),
1116+ ath10k_htt_rx_crypto_param_len (ar , enctype ));
1117+ }
1118+
10871119 memcpy (skb_push (msdu , hdr_len ), hdr , hdr_len );
10881120
10891121 /* original 802.11 header has a different DA and in
@@ -1144,6 +1176,7 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar,
11441176 u8 sa [ETH_ALEN ];
11451177 int l3_pad_bytes ;
11461178 struct htt_rx_desc * rxd ;
1179+ int bytes_aligned = ar -> hw_params .decap_align_bytes ;
11471180
11481181 /* Delivered decapped frame:
11491182 * [eth header] <-- replaced with 802.11 hdr & rfc1042/llc
@@ -1172,6 +1205,14 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar,
11721205 /* push original 802.11 header */
11731206 hdr = (struct ieee80211_hdr * )first_hdr ;
11741207 hdr_len = ieee80211_hdrlen (hdr -> frame_control );
1208+
1209+ if (!(status -> flag & RX_FLAG_IV_STRIPPED )) {
1210+ memcpy (skb_push (msdu ,
1211+ ath10k_htt_rx_crypto_param_len (ar , enctype )),
1212+ (void * )hdr + round_up (hdr_len , bytes_aligned ),
1213+ ath10k_htt_rx_crypto_param_len (ar , enctype ));
1214+ }
1215+
11751216 memcpy (skb_push (msdu , hdr_len ), hdr , hdr_len );
11761217
11771218 /* original 802.11 header has a different DA and in
@@ -1185,12 +1226,14 @@ static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar,
11851226static void ath10k_htt_rx_h_undecap_snap (struct ath10k * ar ,
11861227 struct sk_buff * msdu ,
11871228 struct ieee80211_rx_status * status ,
1188- const u8 first_hdr [64 ])
1229+ const u8 first_hdr [64 ],
1230+ enum htt_rx_mpdu_encrypt_type enctype )
11891231{
11901232 struct ieee80211_hdr * hdr ;
11911233 size_t hdr_len ;
11921234 int l3_pad_bytes ;
11931235 struct htt_rx_desc * rxd ;
1236+ int bytes_aligned = ar -> hw_params .decap_align_bytes ;
11941237
11951238 /* Delivered decapped frame:
11961239 * [amsdu header] <-- replaced with 802.11 hdr
@@ -1206,6 +1249,14 @@ static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar,
12061249
12071250 hdr = (struct ieee80211_hdr * )first_hdr ;
12081251 hdr_len = ieee80211_hdrlen (hdr -> frame_control );
1252+
1253+ if (!(status -> flag & RX_FLAG_IV_STRIPPED )) {
1254+ memcpy (skb_push (msdu ,
1255+ ath10k_htt_rx_crypto_param_len (ar , enctype )),
1256+ (void * )hdr + round_up (hdr_len , bytes_aligned ),
1257+ ath10k_htt_rx_crypto_param_len (ar , enctype ));
1258+ }
1259+
12091260 memcpy (skb_push (msdu , hdr_len ), hdr , hdr_len );
12101261}
12111262
@@ -1240,13 +1291,15 @@ static void ath10k_htt_rx_h_undecap(struct ath10k *ar,
12401291 is_decrypted );
12411292 break ;
12421293 case RX_MSDU_DECAP_NATIVE_WIFI :
1243- ath10k_htt_rx_h_undecap_nwifi (ar , msdu , status , first_hdr );
1294+ ath10k_htt_rx_h_undecap_nwifi (ar , msdu , status , first_hdr ,
1295+ enctype );
12441296 break ;
12451297 case RX_MSDU_DECAP_ETHERNET2_DIX :
12461298 ath10k_htt_rx_h_undecap_eth (ar , msdu , status , first_hdr , enctype );
12471299 break ;
12481300 case RX_MSDU_DECAP_8023_SNAP_LLC :
1249- ath10k_htt_rx_h_undecap_snap (ar , msdu , status , first_hdr );
1301+ ath10k_htt_rx_h_undecap_snap (ar , msdu , status , first_hdr ,
1302+ enctype );
12501303 break ;
12511304 }
12521305}
@@ -1289,7 +1342,8 @@ static void ath10k_htt_rx_h_csum_offload(struct sk_buff *msdu)
12891342
12901343static void ath10k_htt_rx_h_mpdu (struct ath10k * ar ,
12911344 struct sk_buff_head * amsdu ,
1292- struct ieee80211_rx_status * status )
1345+ struct ieee80211_rx_status * status ,
1346+ bool fill_crypt_header )
12931347{
12941348 struct sk_buff * first ;
12951349 struct sk_buff * last ;
@@ -1299,7 +1353,6 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
12991353 enum htt_rx_mpdu_encrypt_type enctype ;
13001354 u8 first_hdr [64 ];
13011355 u8 * qos ;
1302- size_t hdr_len ;
13031356 bool has_fcs_err ;
13041357 bool has_crypto_err ;
13051358 bool has_tkip_err ;
@@ -1324,15 +1377,17 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
13241377 * decapped header. It'll be used for undecapping of each MSDU.
13251378 */
13261379 hdr = (void * )rxd -> rx_hdr_status ;
1327- hdr_len = ieee80211_hdrlen (hdr -> frame_control );
1328- memcpy (first_hdr , hdr , hdr_len );
1380+ memcpy (first_hdr , hdr , RX_HTT_HDR_STATUS_LEN );
13291381
13301382 /* Each A-MSDU subframe will use the original header as the base and be
13311383 * reported as a separate MSDU so strip the A-MSDU bit from QoS Ctl.
13321384 */
13331385 hdr = (void * )first_hdr ;
1334- qos = ieee80211_get_qos_ctl (hdr );
1335- qos [0 ] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT ;
1386+
1387+ if (ieee80211_is_data_qos (hdr -> frame_control )) {
1388+ qos = ieee80211_get_qos_ctl (hdr );
1389+ qos [0 ] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT ;
1390+ }
13361391
13371392 /* Some attention flags are valid only in the last MSDU. */
13381393 last = skb_peek_tail (amsdu );
@@ -1379,9 +1434,14 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
13791434 status -> flag |= RX_FLAG_DECRYPTED ;
13801435
13811436 if (likely (!is_mgmt ))
1382- status -> flag |= RX_FLAG_IV_STRIPPED |
1383- RX_FLAG_MMIC_STRIPPED ;
1384- }
1437+ status -> flag |= RX_FLAG_MMIC_STRIPPED ;
1438+
1439+ if (fill_crypt_header )
1440+ status -> flag |= RX_FLAG_MIC_STRIPPED |
1441+ RX_FLAG_ICV_STRIPPED ;
1442+ else
1443+ status -> flag |= RX_FLAG_IV_STRIPPED ;
1444+ }
13851445
13861446 skb_queue_walk (amsdu , msdu ) {
13871447 ath10k_htt_rx_h_csum_offload (msdu );
@@ -1397,6 +1457,9 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
13971457 if (is_mgmt )
13981458 continue ;
13991459
1460+ if (fill_crypt_header )
1461+ continue ;
1462+
14001463 hdr = (void * )msdu -> data ;
14011464 hdr -> frame_control &= ~__cpu_to_le16 (IEEE80211_FCTL_PROTECTED );
14021465 }
@@ -1407,6 +1470,9 @@ static void ath10k_htt_rx_h_deliver(struct ath10k *ar,
14071470 struct ieee80211_rx_status * status )
14081471{
14091472 struct sk_buff * msdu ;
1473+ struct sk_buff * first_subframe ;
1474+
1475+ first_subframe = skb_peek (amsdu );
14101476
14111477 while ((msdu = __skb_dequeue (amsdu ))) {
14121478 /* Setup per-MSDU flags */
@@ -1415,6 +1481,13 @@ static void ath10k_htt_rx_h_deliver(struct ath10k *ar,
14151481 else
14161482 status -> flag |= RX_FLAG_AMSDU_MORE ;
14171483
1484+ if (msdu == first_subframe ) {
1485+ first_subframe = NULL ;
1486+ status -> flag &= ~RX_FLAG_ALLOW_SAME_PN ;
1487+ } else {
1488+ status -> flag |= RX_FLAG_ALLOW_SAME_PN ;
1489+ }
1490+
14181491 ath10k_process_rx (ar , status , msdu );
14191492 }
14201493}
@@ -1557,7 +1630,7 @@ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt)
15571630 ath10k_htt_rx_h_ppdu (ar , & amsdu , rx_status , 0xffff );
15581631 ath10k_htt_rx_h_unchain (ar , & amsdu , ret > 0 );
15591632 ath10k_htt_rx_h_filter (ar , & amsdu , rx_status );
1560- ath10k_htt_rx_h_mpdu (ar , & amsdu , rx_status );
1633+ ath10k_htt_rx_h_mpdu (ar , & amsdu , rx_status , true );
15611634 ath10k_htt_rx_h_deliver (ar , & amsdu , rx_status );
15621635
15631636 return num_msdus ;
@@ -1892,7 +1965,7 @@ static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb)
18921965 num_msdus += skb_queue_len (& amsdu );
18931966 ath10k_htt_rx_h_ppdu (ar , & amsdu , status , vdev_id );
18941967 ath10k_htt_rx_h_filter (ar , & amsdu , status );
1895- ath10k_htt_rx_h_mpdu (ar , & amsdu , status );
1968+ ath10k_htt_rx_h_mpdu (ar , & amsdu , status , false );
18961969 ath10k_htt_rx_h_deliver (ar , & amsdu , status );
18971970 break ;
18981971 case - EAGAIN :
0 commit comments