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:
Kani M
2022-07-07 21:16:42 +05:30
committed by Madan Koyyalamudi
parent eb56570ae1
commit c9f08ae24b
8 changed files with 294 additions and 0 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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