summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArif Hussain <arifhussain@codeaurora.org>2016-11-10 20:28:50 -0800
committerqcabuildsw <qcabuildsw@localhost>2016-11-12 09:31:22 -0800
commitc421f3128af1102a2f827a3f1d0fa193ee85701e (patch)
treecdd468c1593043c8da3ebf3e6a5b23133b5a609c
parent59835ed7f4dcae513e75020f5e89e8e7e986e06a (diff)
qcacld-3.0: Do not process duplicate rrm link measurement request
Add a logic to avoid processing duplicate rrm link measurement request. Cache last processed frame with timestamp to validate new frame. If retry bit set, compare sequence number and source address of last processed frame. If both are matches and is within retry time than ignore that frame, else process. Update last processed frame cache every time new frame processed successfully Change-Id: Ic2bff028c7bcd79d6b3dca186edb35464b1fd059 CRs-Fixed: 1088735
-rw-r--r--core/mac/src/pe/lim/lim_process_action_frame.c24
-rw-r--r--core/mac/src/pe/lim/lim_utils.c73
-rw-r--r--core/mac/src/pe/lim/lim_utils.h9
3 files changed, 100 insertions, 6 deletions
diff --git a/core/mac/src/pe/lim/lim_process_action_frame.c b/core/mac/src/pe/lim/lim_process_action_frame.c
index d2889095b1b9..d25e61e2c4f1 100644
--- a/core/mac/src/pe/lim/lim_process_action_frame.c
+++ b/core/mac/src/pe/lim/lim_process_action_frame.c
@@ -60,6 +60,8 @@
#define BA_DEFAULT_TX_BUFFER_SIZE 64
+static last_processed_msg rrm_link_action_frm;
+
/* Note: The test passes if the STAUT stops sending any frames, and no further
frames are transmitted on this channel by the station when the AP has sent
the last 6 beacons, with the channel switch information elements as seen
@@ -1406,7 +1408,7 @@ err:
qdf_mem_free(frm);
}
-static void
+static tSirRetStatus
__lim_process_link_measurement_req(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
tpPESession psessionEntry)
{
@@ -1420,7 +1422,7 @@ __lim_process_link_measurement_req(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
if (psessionEntry == NULL) {
- return;
+ return eSIR_FAILURE;
}
/**Unpack the received frame */
@@ -1435,7 +1437,7 @@ __lim_process_link_measurement_req(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
PELOG2(sir_dump_buf
(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen);
)
- return;
+ return eSIR_FAILURE;
} else if (DOT11F_WARNED(nStatus)) {
lim_log(pMac, LOGW,
FL
@@ -1447,7 +1449,7 @@ __lim_process_link_measurement_req(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
}
/* Call rrm function to handle the request. */
- rrm_process_link_measurement_request(pMac, pRxPacketInfo, &frm,
+ return rrm_process_link_measurement_request(pMac, pRxPacketInfo, &frm,
psessionEntry);
}
@@ -1912,9 +1914,19 @@ void lim_process_action_frame(tpAniSirGlobal mac_ctx,
session);
break;
case SIR_MAC_RRM_LINK_MEASUREMENT_REQ:
- __lim_process_link_measurement_req(mac_ctx,
+ if (!lim_is_valid_frame(
+ &rrm_link_action_frm,
+ rx_pkt_info))
+ break;
+
+ if (__lim_process_link_measurement_req(
+ mac_ctx,
(uint8_t *)rx_pkt_info,
- session);
+ session) == eSIR_SUCCESS)
+ lim_update_last_processed_frame(
+ &rrm_link_action_frm,
+ rx_pkt_info);
+
break;
case SIR_MAC_RRM_NEIGHBOR_RPT:
__lim_process_neighbor_report(mac_ctx,
diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c
index 0518ae8fe92d..ba731b8ff299 100644
--- a/core/mac/src/pe/lim/lim_utils.c
+++ b/core/mac/src/pe/lim/lim_utils.c
@@ -7218,3 +7218,76 @@ void lim_send_set_dtim_period(tpAniSirGlobal mac_ctx, uint8_t dtim_period,
qdf_mem_free(dtim_params);
}
}
+
+/**
+ * lim_is_valid_frame(): validate RX frame using last processed frame details
+ * to find if it is duplicate frame.
+ *
+ * @last_processed_frm: last processed frame pointer.
+ * @pRxPacketInfo: RX packet.
+ *
+ * Frame treat as duplicate:
+ * if retry bit is set and
+ * if source address and seq number matches with the last processed frame
+ *
+ * Return: false if duplicate frame, else true.
+ */
+bool lim_is_valid_frame(last_processed_msg *last_processed_frm,
+ uint8_t *pRxPacketInfo)
+{
+ uint16_t seq_num;
+ tpSirMacMgmtHdr pHdr;
+
+ if (!pRxPacketInfo) {
+ QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid RX frame"));
+ return false;
+ }
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+ if (pHdr->fc.retry == 0)
+ return true;
+
+ seq_num = (((pHdr->seqControl.seqNumHi <<
+ HIGH_SEQ_NUM_OFFSET) |
+ pHdr->seqControl.seqNumLo));
+
+ if (last_processed_frm->seq_num == seq_num &&
+ qdf_mem_cmp(last_processed_frm->sa, pHdr->sa, ETH_ALEN) == 0) {
+ QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+ FL("Duplicate frame from "MAC_ADDRESS_STR " Seq Number %d"),
+ MAC_ADDR_ARRAY(pHdr->sa), seq_num);
+ return false;
+ }
+ return true;
+}
+
+/**
+ * lim_update_last_processed_frame(): update new processed frame info to cache.
+ *
+ * @last_processed_frm: last processed frame pointer.
+ * @pRxPacketInfo: Successfully processed RX packet.
+ *
+ * Return: None.
+ */
+void lim_update_last_processed_frame(last_processed_msg *last_processed_frm,
+ uint8_t *pRxPacketInfo)
+{
+ uint16_t seq_num;
+ tpSirMacMgmtHdr pHdr;
+
+ if (!pRxPacketInfo) {
+ QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid RX frame"));
+ return;
+ }
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ seq_num = (((pHdr->seqControl.seqNumHi <<
+ HIGH_SEQ_NUM_OFFSET) |
+ pHdr->seqControl.seqNumLo));
+
+ qdf_mem_copy(last_processed_frm->sa, pHdr->sa, ETH_ALEN);
+ last_processed_frm->seq_num = seq_num;
+}
diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h
index 5ad6bd0921e4..5c6d26b57fa7 100644
--- a/core/mac/src/pe/lim/lim_utils.h
+++ b/core/mac/src/pe/lim/lim_utils.h
@@ -79,7 +79,16 @@ typedef union uPmfSaQueryTimerId {
} tPmfSaQueryTimerId, *tpPmfSaQueryTimerId;
#endif
+typedef struct last_processed_frame {
+ tSirMacAddr sa;
+ uint16_t seq_num;
+} last_processed_msg;
+
/* LIM utility functions */
+bool lim_is_valid_frame(last_processed_msg *last_processed_frm,
+ uint8_t *pRxPacketInfo);
+void lim_update_last_processed_frame(last_processed_msg *last_processed_frm,
+ uint8_t *pRxPacketInfo);
void limGetBssidFromPkt(tpAniSirGlobal, uint8_t *, uint8_t *, uint32_t *);
char *lim_dot11_reason_str(uint16_t reasonCode);
char *lim_mlm_state_str(tLimMlmStates state);