diff options
| author | Arif Hussain <arifhussain@codeaurora.org> | 2016-11-10 20:28:50 -0800 |
|---|---|---|
| committer | qcabuildsw <qcabuildsw@localhost> | 2016-11-12 09:31:22 -0800 |
| commit | c421f3128af1102a2f827a3f1d0fa193ee85701e (patch) | |
| tree | cdd468c1593043c8da3ebf3e6a5b23133b5a609c | |
| parent | 59835ed7f4dcae513e75020f5e89e8e7e986e06a (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.c | 24 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_utils.c | 73 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_utils.h | 9 |
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); |
