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
This commit is contained in:
Arif Hussain
2016-11-10 20:28:50 -08:00
gecommit door qcabuildsw
bovenliggende c36f7ebe89
commit 776ee7a0f2
3 gewijzigde bestanden met toevoegingen van 100 en 6 verwijderingen

Bestand weergeven

@@ -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,

Bestand weergeven

@@ -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;
}

Bestand weergeven

@@ -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);