qcacmn: Add beacon ratelimiting
Rate-limiting will be based on number of beacons received. When the beacon is not from connected AP, the beacons are dropped on a percentage of received beacons and rate limit, which is configured by the user. CRs-Fixed: 3230508 Change-Id: Iac591c37129fda6923ef254c2950cb0bdbb44ce9
This commit is contained in:

committed by
Madan Koyyalamudi

parent
eb56570ae1
commit
c9f08ae24b
@@ -803,6 +803,16 @@ struct frame_pn_params {
|
||||
uint8_t prev_pn[WLAN_MGMT_TXRX_HOST_MAX_PN_LEN];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct frm_conn_ap - connected ap
|
||||
* @mgmt_frm_sub_type: type of frame
|
||||
* @is_conn_ap_frm: set if frm is from connected ap
|
||||
*/
|
||||
struct frm_conn_ap {
|
||||
uint8_t mgmt_frm_sub_type;
|
||||
uint8_t is_conn_ap_frm;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mgmt_rx_event_ext_params - Host mgmt extended params
|
||||
* @ba_win_size: Block-Ack window size
|
||||
@@ -838,6 +848,7 @@ struct mgmt_rx_event_ext_params {
|
||||
* @reo_params: Pointer to MGMT Rx REO params
|
||||
* @pn_params: Frame PN params
|
||||
* @ext_params: Extended params
|
||||
* @frm_con_ap: Frame is from connected ap
|
||||
*/
|
||||
struct mgmt_rx_event_params {
|
||||
uint32_t chan_freq;
|
||||
@@ -859,6 +870,7 @@ struct mgmt_rx_event_params {
|
||||
#endif
|
||||
struct frame_pn_params pn_params;
|
||||
struct mgmt_rx_event_ext_params *ext_params;
|
||||
struct frm_conn_ap is_conn_ap;
|
||||
};
|
||||
|
||||
#ifdef WLAN_MGMT_RX_REO_SUPPORT
|
||||
|
@@ -1052,6 +1052,49 @@ static QDF_STATUS simulation_frame_update(struct wlan_objmgr_psoc *psoc,
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* wlan_mgmt_rx_beacon_rate_limit() - rate limiting mgmt beacons
|
||||
* @psoc - pointer to psoc struct
|
||||
* @mgmt_rx_params - rx params
|
||||
*
|
||||
* This function will drop the beacons if the number of beacons
|
||||
* received is greater than the percentage of limit of beacons to max
|
||||
* count of beacons, when beacon rate limiting is enabled
|
||||
*
|
||||
* Return : QDF_STATUS if success, else QDF_STATUS_E_RESOURCES
|
||||
*/
|
||||
static QDF_STATUS wlan_mgmt_rx_beacon_rate_limit(struct wlan_objmgr_psoc *psoc,
|
||||
struct mgmt_rx_event_params
|
||||
*mgmt_rx_params)
|
||||
{
|
||||
struct wlan_objmgr_pdev *pdev = NULL;
|
||||
|
||||
pdev = wlan_objmgr_get_pdev_by_id(psoc, mgmt_rx_params->pdev_id,
|
||||
WLAN_MGMT_SB_ID);
|
||||
|
||||
if (pdev && pdev->pdev_objmgr.bcn.bcn_rate_limit) {
|
||||
uint64_t b_limit = qdf_do_div(
|
||||
(wlan_pdev_get_max_beacon_count(pdev) *
|
||||
wlan_pdev_get_max_beacon_limit(pdev)), 100);
|
||||
wlan_pdev_incr_wlan_beacon_count(pdev);
|
||||
|
||||
if (wlan_pdev_get_wlan_beacon_count(pdev) >=
|
||||
wlan_pdev_get_max_beacon_count(pdev))
|
||||
wlan_pdev_set_wlan_beacon_count(pdev, 0);
|
||||
|
||||
if (wlan_pdev_get_wlan_beacon_count(pdev) >= b_limit) {
|
||||
wlan_pdev_incr_dropped_beacon_count(pdev);
|
||||
wlan_objmgr_pdev_release_ref(pdev, WLAN_MGMT_SB_ID);
|
||||
return QDF_STATUS_E_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
if (pdev)
|
||||
wlan_objmgr_pdev_release_ref(pdev, WLAN_MGMT_SB_ID);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_mgmt_txrx_rx_handler_list_copy() - copies rx handler list
|
||||
* @rx_handler: pointer to rx handler list
|
||||
@@ -1317,6 +1360,15 @@ QDF_STATUS tgt_mgmt_txrx_rx_frame_handler(
|
||||
}
|
||||
qdf_spin_unlock_bh(&mgmt_txrx_psoc_ctx->mgmt_txrx_psoc_ctx_lock);
|
||||
|
||||
if (mgmt_subtype == MGMT_SUBTYPE_BEACON &&
|
||||
mgmt_rx_params->is_conn_ap.is_conn_ap_frm == 0) {
|
||||
status = wlan_mgmt_rx_beacon_rate_limit(psoc, mgmt_rx_params);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
qdf_nbuf_free(buf);
|
||||
goto rx_handler_mem_free;
|
||||
}
|
||||
}
|
||||
|
||||
mac_addr = (uint8_t *)wh->i_addr2;
|
||||
/*
|
||||
* peer can be NULL in following 2 scenarios:
|
||||
|
@@ -181,6 +181,22 @@ struct wlan_objmgr_pdev_mlme {
|
||||
uint32_t pdev_op_flags;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wlan_beacon_process - wlan beacon structure
|
||||
* @bcn_rate_limit: To indicate if beacon ratelimiting is enabled or not
|
||||
* @wlan_beacon_count: Per pdev beacon count received
|
||||
* @max_beacon_count: Per vdev max beacon count, defaults to 100
|
||||
* @max_beacon_limit: Limit of beacons to be processed
|
||||
* @dropped_beacon: Dropped beacons
|
||||
*/
|
||||
struct wlan_beacon_process {
|
||||
bool bcn_rate_limit;
|
||||
uint64_t wlan_beacon_count;
|
||||
uint64_t max_beacon_count;
|
||||
uint8_t max_beacon_limit;
|
||||
uint64_t dropped_beacon;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wlan_objmgr_pdev_objmgr - pdev object object manager structure
|
||||
* @wlan_pdev_id: PDEV id
|
||||
@@ -196,6 +212,7 @@ struct wlan_objmgr_pdev_mlme {
|
||||
* @ref_cnt: Ref count
|
||||
* @ref_id_dbg: Array to track Ref count
|
||||
* @wlan_mlo_vdev_count: MLO VDEVs count
|
||||
* @bcn: Struct to keep track of beacon count
|
||||
*/
|
||||
struct wlan_objmgr_pdev_objmgr {
|
||||
uint8_t wlan_pdev_id;
|
||||
@@ -213,6 +230,7 @@ struct wlan_objmgr_pdev_objmgr {
|
||||
#ifdef WLAN_FEATURE_11BE_MLO
|
||||
qdf_atomic_t wlan_mlo_vdev_count;
|
||||
#endif
|
||||
struct wlan_beacon_process bcn;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1039,6 +1057,151 @@ static inline uint16_t wlan_pdev_get_max_peer_count(
|
||||
return pdev->pdev_objmgr.max_peer_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_pdev_set_max_beacon_count() - set max beacon count
|
||||
* @pdev: pdev object
|
||||
* @count: Max beacon count
|
||||
*
|
||||
* API to set max beacon count of pdev
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline void wlan_pdev_set_max_beacon_count(
|
||||
struct wlan_objmgr_pdev *pdev,
|
||||
uint64_t count)
|
||||
{
|
||||
pdev->pdev_objmgr.bcn.max_beacon_count = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_pdev_get_max_beacon_count() - get max beacon count
|
||||
* @pdev: pdev object
|
||||
*
|
||||
* API to get max beacon count of pdev
|
||||
*
|
||||
* Return: max beacon count
|
||||
*/
|
||||
static inline uint64_t wlan_pdev_get_max_beacon_count(
|
||||
struct wlan_objmgr_pdev *pdev)
|
||||
{
|
||||
return pdev->pdev_objmgr.bcn.max_beacon_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_pdev_incr_beacon_count() - incr beacon count for rx beacon frames
|
||||
* @pdev: pdev object
|
||||
*
|
||||
* API to incr beacon count of pdev
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static inline void wlan_pdev_incr_wlan_beacon_count(
|
||||
struct wlan_objmgr_pdev *pdev)
|
||||
{
|
||||
pdev->pdev_objmgr.bcn.wlan_beacon_count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_pdev_get_wlan_beacon_count() - set wlan beacon count
|
||||
* @pdev: pdev object
|
||||
* @count: count to reset beacon count
|
||||
*
|
||||
* API to get wlan beacon count of pdev
|
||||
*
|
||||
*/
|
||||
static inline void wlan_pdev_set_wlan_beacon_count(
|
||||
struct wlan_objmgr_pdev *pdev,
|
||||
uint64_t count)
|
||||
{
|
||||
pdev->pdev_objmgr.bcn.wlan_beacon_count = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_pdev_get_wlan_beacon_limit() - get wlan beacon limit
|
||||
* @pdev: pdev object
|
||||
*
|
||||
* API to get wlan beacon limit of pdev
|
||||
*
|
||||
* Return: beacon limit
|
||||
*/
|
||||
static inline uint64_t wlan_pdev_get_wlan_beacon_count(
|
||||
struct wlan_objmgr_pdev *pdev)
|
||||
{
|
||||
return pdev->pdev_objmgr.bcn.wlan_beacon_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_pdev_set_wlan_beacon_count() - set wlan beacon limit
|
||||
* @pdev: pdev object
|
||||
* @limit: limit for thresholding
|
||||
*
|
||||
* API to set wlan beacon limit of pdev
|
||||
*
|
||||
*/
|
||||
static inline void wlan_pdev_set_max_beacon_limit(
|
||||
struct wlan_objmgr_pdev *pdev,
|
||||
uint64_t limit)
|
||||
{
|
||||
pdev->pdev_objmgr.bcn.max_beacon_limit = limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_pdev_get_wlan_beacon_limit() - get wlan beacon limit
|
||||
* @pdev: pdev object
|
||||
*
|
||||
* API to get wlan beacon limit of pdev
|
||||
*
|
||||
* Return: beacon limit
|
||||
*/
|
||||
static inline uint64_t wlan_pdev_get_max_beacon_limit(
|
||||
struct wlan_objmgr_pdev *pdev)
|
||||
{
|
||||
return pdev->pdev_objmgr.bcn.max_beacon_limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_pdev_incr_dropped_beacon_count() - increment dropped bcn cnt
|
||||
* @pdev: pdev object
|
||||
*
|
||||
* API to increment dropped beacon count
|
||||
*
|
||||
* Return: beacon limit
|
||||
*/
|
||||
static inline void wlan_pdev_incr_dropped_beacon_count(
|
||||
struct wlan_objmgr_pdev *pdev)
|
||||
{
|
||||
pdev->pdev_objmgr.bcn.dropped_beacon++;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_pdev_set_dropped_beacon_count() - reset dropped beacon count
|
||||
* @pdev: pdev object
|
||||
* @count: count value
|
||||
*
|
||||
* API to set beacon drop count
|
||||
*
|
||||
*/
|
||||
static inline void wlan_pdev_set_dropped_beacon_count(
|
||||
struct wlan_objmgr_pdev *pdev,
|
||||
uint64_t count)
|
||||
{
|
||||
pdev->pdev_objmgr.bcn.dropped_beacon = count;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_pdev_get_dropped_beacon_count() - get drop beacon count
|
||||
* @pdev: pdev object
|
||||
*
|
||||
* API to get dropped beacon count
|
||||
*
|
||||
* Return: beacon limit
|
||||
*/
|
||||
static inline uint64_t wlan_pdev_get_dropped_beacon_count(
|
||||
struct wlan_objmgr_pdev *pdev)
|
||||
{
|
||||
return pdev->pdev_objmgr.bcn.dropped_beacon;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_pdev_set_max_monitor_vdev_count() - set max monitor vdev count
|
||||
* @pdev: PDEV object
|
||||
|
@@ -2993,6 +2993,18 @@ QDF_STATUS
|
||||
wmi_extract_frame_pn_params(wmi_unified_t wmi_handle, void *evt_buf,
|
||||
struct frame_pn_params *pn_params);
|
||||
|
||||
/**
|
||||
* wmi_extract_is_conn_ap_frame() - extract is_conn_ap_frame param from event
|
||||
* @wmi_handle: wmi handle
|
||||
* @evt_buf: pointer to event buffer
|
||||
* @is_conn_ap: is_conn_ap param
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure
|
||||
*/
|
||||
QDF_STATUS
|
||||
wmi_extract_is_conn_ap_frame(wmi_unified_t wmi_handle, void *evt_buf,
|
||||
struct frm_conn_ap *is_conn_ap);
|
||||
|
||||
/**
|
||||
* wmi_extract_vdev_roam_param() - extract vdev roam param from event
|
||||
* @wmi_handle: wmi handle
|
||||
|
@@ -5749,6 +5749,7 @@ typedef enum {
|
||||
#endif
|
||||
wmi_service_tdls_wideband_support,
|
||||
#endif
|
||||
wmi_service_is_my_mgmt_frame,
|
||||
wmi_services_max,
|
||||
} wmi_conv_service_ids;
|
||||
#define WMI_SERVICE_UNAVAILABLE 0xFFFF
|
||||
|
@@ -1885,6 +1885,10 @@ QDF_STATUS (*extract_mgmt_rx_params)(wmi_unified_t wmi_handle, void *evt_buf,
|
||||
QDF_STATUS (*extract_frame_pn_params)(wmi_unified_t wmi_handle, void *evt_buf,
|
||||
struct frame_pn_params *pn_params);
|
||||
|
||||
QDF_STATUS (*extract_is_conn_ap_frame)(wmi_unified_t wmi_handle,
|
||||
void *evt_buf,
|
||||
struct frm_conn_ap *is_conn_ap);
|
||||
|
||||
QDF_STATUS (*extract_vdev_stopped_param)(wmi_unified_t wmi_handle,
|
||||
void *evt_buf, uint32_t *vdev_id);
|
||||
|
||||
|
@@ -2118,6 +2118,18 @@ wmi_extract_frame_pn_params(wmi_unified_t wmi_handle, void *evt_buf,
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
wmi_extract_is_conn_ap_frame(wmi_unified_t wmi_handle, void *evt_buf,
|
||||
struct frm_conn_ap *is_conn_ap_frm)
|
||||
{
|
||||
if (wmi_handle->ops->extract_is_conn_ap_frame)
|
||||
return wmi_handle->ops->extract_is_conn_ap_frame(wmi_handle,
|
||||
evt_buf,
|
||||
is_conn_ap_frm);
|
||||
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
wmi_extract_vdev_roam_param(wmi_unified_t wmi_handle, void *evt_buf,
|
||||
wmi_host_roam_event *param)
|
||||
|
@@ -11943,6 +11943,43 @@ static QDF_STATUS extract_frame_pn_params_tlv(wmi_unified_t wmi_handle,
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* extract_is_conn_ap_param_tlv() - extract is_conn_ap_frame param from event
|
||||
* @wmi_handle: wmi handle
|
||||
* @evt_buf: pointer to event buffer
|
||||
* @is_conn_ap: Pointer for is_conn_ap frame
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS for success or error code
|
||||
*/
|
||||
static QDF_STATUS extract_is_conn_ap_frm_param_tlv(
|
||||
wmi_unified_t wmi_handle,
|
||||
void *evt_buf,
|
||||
struct frm_conn_ap *is_conn_ap)
|
||||
{
|
||||
WMI_MGMT_RX_EVENTID_param_tlvs *param_tlvs;
|
||||
wmi_is_my_mgmt_frame *my_frame_tlv;
|
||||
|
||||
param_tlvs = evt_buf;
|
||||
if (!param_tlvs) {
|
||||
wmi_err("Got NULL point message from FW");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (!is_conn_ap) {
|
||||
wmi_err(" is connected ap param is NULL");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
my_frame_tlv = param_tlvs->my_frame;
|
||||
if (!my_frame_tlv)
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
is_conn_ap->mgmt_frm_sub_type = my_frame_tlv->mgmt_frm_sub_type;
|
||||
is_conn_ap->is_conn_ap_frm = my_frame_tlv->is_my_frame;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* extract_vdev_roam_param_tlv() - extract vdev roam param from event
|
||||
* @wmi_handle: wmi handle
|
||||
@@ -18375,6 +18412,7 @@ struct wmi_ops tlv_ops = {
|
||||
.extract_dbglog_data_len = extract_dbglog_data_len_tlv,
|
||||
.extract_mgmt_rx_params = extract_mgmt_rx_params_tlv,
|
||||
.extract_frame_pn_params = extract_frame_pn_params_tlv,
|
||||
.extract_is_conn_ap_frame = extract_is_conn_ap_frm_param_tlv,
|
||||
.extract_vdev_roam_param = extract_vdev_roam_param_tlv,
|
||||
.extract_vdev_scan_ev_param = extract_vdev_scan_ev_param_tlv,
|
||||
#ifdef FEATURE_WLAN_SCAN_PNO
|
||||
|
Reference in New Issue
Block a user