|
@@ -952,6 +952,55 @@ static int ath10k_unchain_msdu(struct sk_buff *msdu_head)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
|
|
|
|
+ struct sk_buff *head,
|
|
|
|
+ struct htt_rx_info *info)
|
|
|
|
+{
|
|
|
|
+ enum htt_rx_mpdu_status status = info->status;
|
|
|
|
+
|
|
|
|
+ if (!head) {
|
|
|
|
+ ath10k_warn("htt rx no data!\n");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (head->len == 0) {
|
|
|
|
+ ath10k_dbg(ATH10K_DBG_HTT,
|
|
|
|
+ "htt rx dropping due to zero-len\n");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (ath10k_htt_rx_has_decrypt_err(head)) {
|
|
|
|
+ ath10k_dbg(ATH10K_DBG_HTT,
|
|
|
|
+ "htt rx dropping due to decrypt-err\n");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Skip mgmt frames while we handle this in WMI */
|
|
|
|
+ if (status == HTT_RX_IND_MPDU_STATUS_MGMT_CTRL ||
|
|
|
|
+ ath10k_htt_rx_is_mgmt(head)) {
|
|
|
|
+ ath10k_dbg(ATH10K_DBG_HTT, "htt rx mgmt ctrl\n");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (status != HTT_RX_IND_MPDU_STATUS_OK &&
|
|
|
|
+ status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR &&
|
|
|
|
+ status != HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER &&
|
|
|
|
+ !htt->ar->monitor_enabled) {
|
|
|
|
+ ath10k_dbg(ATH10K_DBG_HTT,
|
|
|
|
+ "htt rx ignoring frame w/ status %d\n",
|
|
|
|
+ status);
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (test_bit(ATH10K_CAC_RUNNING, &htt->ar->dev_flags)) {
|
|
|
|
+ ath10k_dbg(ATH10K_DBG_HTT,
|
|
|
|
+ "htt rx CAC running\n");
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
|
|
static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
|
|
struct htt_rx_indication *rx)
|
|
struct htt_rx_indication *rx)
|
|
{
|
|
{
|
|
@@ -984,7 +1033,6 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
|
|
|
|
|
|
for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) {
|
|
for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) {
|
|
struct sk_buff *msdu_head, *msdu_tail;
|
|
struct sk_buff *msdu_head, *msdu_tail;
|
|
- enum htt_rx_mpdu_status status;
|
|
|
|
int msdu_chaining;
|
|
int msdu_chaining;
|
|
|
|
|
|
msdu_head = NULL;
|
|
msdu_head = NULL;
|
|
@@ -995,49 +1043,8 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
|
|
&msdu_head,
|
|
&msdu_head,
|
|
&msdu_tail);
|
|
&msdu_tail);
|
|
|
|
|
|
- if (!msdu_head) {
|
|
|
|
- ath10k_warn("htt rx no data!\n");
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (msdu_head->len == 0) {
|
|
|
|
- ath10k_dbg(ATH10K_DBG_HTT,
|
|
|
|
- "htt rx dropping due to zero-len\n");
|
|
|
|
- ath10k_htt_rx_free_msdu_chain(msdu_head);
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (ath10k_htt_rx_has_decrypt_err(msdu_head)) {
|
|
|
|
- ath10k_dbg(ATH10K_DBG_HTT,
|
|
|
|
- "htt rx dropping due to decrypt-err\n");
|
|
|
|
- ath10k_htt_rx_free_msdu_chain(msdu_head);
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- status = info.status;
|
|
|
|
-
|
|
|
|
- /* Skip mgmt frames while we handle this in WMI */
|
|
|
|
- if (status == HTT_RX_IND_MPDU_STATUS_MGMT_CTRL ||
|
|
|
|
- ath10k_htt_rx_is_mgmt(msdu_head)) {
|
|
|
|
- ath10k_dbg(ATH10K_DBG_HTT, "htt rx mgmt ctrl\n");
|
|
|
|
- ath10k_htt_rx_free_msdu_chain(msdu_head);
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (status != HTT_RX_IND_MPDU_STATUS_OK &&
|
|
|
|
- status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR &&
|
|
|
|
- status != HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER &&
|
|
|
|
- !htt->ar->monitor_enabled) {
|
|
|
|
- ath10k_dbg(ATH10K_DBG_HTT,
|
|
|
|
- "htt rx ignoring frame w/ status %d\n",
|
|
|
|
- status);
|
|
|
|
- ath10k_htt_rx_free_msdu_chain(msdu_head);
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (test_bit(ATH10K_CAC_RUNNING, &htt->ar->dev_flags)) {
|
|
|
|
- ath10k_dbg(ATH10K_DBG_HTT,
|
|
|
|
- "htt rx CAC running\n");
|
|
|
|
|
|
+ if (!ath10k_htt_rx_amsdu_allowed(htt, msdu_head,
|
|
|
|
+ &info)) {
|
|
ath10k_htt_rx_free_msdu_chain(msdu_head);
|
|
ath10k_htt_rx_free_msdu_chain(msdu_head);
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|