From ee10f9089e469a815d2f3d551afd87d9eb6f11f4 Mon Sep 17 00:00:00 2001 From: Arif Hussain Date: Wed, 27 Dec 2017 16:30:17 -0800 Subject: [PATCH] qcacld-3.0: Add obss detection offload support Add support for obss detection offload support. Change-Id: I27fdef1604f6f92890dda024fbc8f9d13df602a3 CRs-Fixed: 2170187 --- components/pmo/core/src/wlan_pmo_wow.c | 121 +++++++++--------- core/hdd/src/wlan_hdd_main.c | 26 ++-- core/mac/inc/ani_global.h | 1 + core/mac/inc/wni_cfg.h | 1 + core/mac/src/cfg/cfg_param_name.c | 1 + core/mac/src/cfg/cfg_proc_msg.c | 3 + core/mac/src/include/sir_params.h | 4 +- core/mac/src/pe/include/lim_session.h | 22 ++++ core/mac/src/pe/lim/lim_api.c | 9 ++ .../src/pe/lim/lim_process_message_queue.c | 6 +- core/wma/inc/wma_internal.h | 14 ++ core/wma/inc/wma_tgt_cfg.h | 2 + core/wma/inc/wma_types.h | 2 + core/wma/src/wma_features.c | 39 ++++++ core/wma/src/wma_main.c | 63 +++++++++ 15 files changed, 244 insertions(+), 70 deletions(-) diff --git a/components/pmo/core/src/wlan_pmo_wow.c b/components/pmo/core/src/wlan_pmo_wow.c index 615e80486f..f1ff442ea8 100644 --- a/components/pmo/core/src/wlan_pmo_wow.c +++ b/components/pmo/core/src/wlan_pmo_wow.c @@ -49,7 +49,7 @@ QDF_STATUS pmo_core_add_wow_user_pattern(struct wlan_objmgr_vdev *vdev, pmo_set_wow_default_ptrn(vdev_ctx, 0); pmo_debug("Add user passed wow pattern id %d vdev id %d", - ptrn->pattern_id, ptrn->session_id); + ptrn->pattern_id, ptrn->session_id); /* * Convert received pattern mask value from bit representation * to byte representation. @@ -72,15 +72,17 @@ QDF_STATUS pmo_core_add_wow_user_pattern(struct wlan_objmgr_vdev *vdev, (pos % PMO_NUM_BITS_IN_BYTE); bit_to_check = 0x1 << bit_to_check; if (ptrn->pattern_mask[pos / PMO_NUM_BITS_IN_BYTE] & - bit_to_check) + bit_to_check) new_mask[pos] = PMO_WOW_PTRN_MASK_VALID; } status = pmo_tgt_send_wow_patterns_to_fw(vdev, - ptrn->pattern_id, - ptrn->pattern, ptrn->pattern_size, - ptrn->pattern_byte_offset, new_mask, - ptrn->pattern_size, true); + ptrn->pattern_id, + ptrn->pattern, + ptrn->pattern_size, + ptrn->pattern_byte_offset, + new_mask, + ptrn->pattern_size, true); if (status != QDF_STATUS_SUCCESS) pmo_err("Failed to add wow pattern %d", ptrn->pattern_id); @@ -110,7 +112,7 @@ QDF_STATUS pmo_core_del_wow_user_pattern(struct wlan_objmgr_vdev *vdev, } pmo_debug("Delete user passed wow pattern id %d total user pattern %d", - pattern_id, pmo_get_wow_user_ptrn(vdev_ctx)); + pattern_id, pmo_get_wow_user_ptrn(vdev_ctx)); pmo_tgt_del_wow_pattern(vdev, pattern_id, true); @@ -160,7 +162,7 @@ void pmo_core_enable_wakeup_event(struct wlan_objmgr_psoc *psoc, goto out; pmo_info("enable wakeup event vdev_id %d wake up event 0x%x%x%x%x", - vdev_id, bitmap[0], bitmap[1], bitmap[2], bitmap[3]); + vdev_id, bitmap[0], bitmap[1], bitmap[2], bitmap[3]); pmo_tgt_enable_wow_wakeup_event(vdev, bitmap); pmo_vdev_put_ref(vdev); @@ -192,7 +194,7 @@ void pmo_core_disable_wakeup_event(struct wlan_objmgr_psoc *psoc, goto out; pmo_info("Disable wakeup event vdev_id %d wake up event 0x%x%x%x%x", - vdev_id, bitmap[0], bitmap[1], bitmap[2], bitmap[3]); + vdev_id, bitmap[0], bitmap[1], bitmap[2], bitmap[3]); pmo_tgt_disable_wow_wakeup_event(vdev, bitmap); pmo_vdev_put_ref(vdev); @@ -228,7 +230,7 @@ bool pmo_is_beaconing_vdev_up(struct wlan_objmgr_psoc *psoc) vdev_opmode = pmo_get_vdev_opmode(vdev); is_beaconing = pmo_is_vdev_in_beaconning_mode(vdev_opmode) && - pmo_is_vdev_up(vdev); + pmo_is_vdev_up(vdev); pmo_vdev_put_ref(vdev); @@ -310,7 +312,7 @@ bool pmo_core_is_wow_applicable(struct wlan_objmgr_psoc *psoc) is_wow_applicable = true; } else if (pmo_core_get_vdev_op_mode(vdev) == QDF_NDI_MODE) { pmo_debug("vdev %d is in NAN data mode, enabling wow", - vdev_id); + vdev_id); is_wow_applicable = true; } @@ -321,7 +323,7 @@ bool pmo_core_is_wow_applicable(struct wlan_objmgr_psoc *psoc) } pmo_debug("All vdev are in disconnected state\n" - "and pno/extscan is not in progress, skipping wow"); + "and pno/extscan is not in progress, skipping wow"); return false; } @@ -334,64 +336,64 @@ void pmo_set_wow_event_bitmap(WOW_WAKE_EVENT_TYPE event, if (!bitmask || wow_bitmap_size < PMO_WOW_MAX_EVENT_BM_LEN) { pmo_err("wow bitmask length shorter than %d", - PMO_WOW_MAX_EVENT_BM_LEN); + PMO_WOW_MAX_EVENT_BM_LEN); return; } pmo_get_event_bitmap_idx(event, wow_bitmap_size, &bit_idx, &idx); bitmask[idx] |= 1 << bit_idx; pmo_debug("%s: bitmask updated %x%x%x%x", - __func__, bitmask[0], bitmask[1], bitmask[2], bitmask[3]); + __func__, bitmask[0], bitmask[1], bitmask[2], bitmask[3]); } void pmo_set_sta_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmap_size) { pmo_set_wow_event_bitmap(WOW_CSA_IE_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_CLIENT_KICKOUT_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_PATTERN_MATCH_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_MAGIC_PKT_RECVD_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_DEAUTH_RECVD_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_DISASSOC_RECVD_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_BMISS_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_GTK_ERR_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_BETTER_AP_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_HTT_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_RA_MATCH_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_NLO_DETECTED_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_EXTSCAN_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_OEM_RESPONSE_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_TDLS_CONN_TRACKER_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_11D_SCAN_EVENT, wow_bitmap_size, bitmask); @@ -402,24 +404,27 @@ void pmo_set_sap_wow_bitmask(uint32_t *bitmask, uint32_t wow_bitmap_size) { pmo_set_wow_event_bitmap(WOW_PROBE_REQ_WPS_IE_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_PATTERN_MATCH_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_AUTH_REQ_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_ASSOC_REQ_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_DEAUTH_RECVD_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_DISASSOC_RECVD_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); pmo_set_wow_event_bitmap(WOW_HTT_EVENT, - wow_bitmap_size, - bitmask); + wow_bitmap_size, + bitmask); + pmo_set_wow_event_bitmap(WOW_SAP_OBSS_DETECTION_EVENT, + wow_bitmap_size, + bitmask); } diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 415da720ce..e6bf1cdb87 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -1849,6 +1849,7 @@ void hdd_update_tgt_cfg(void *context, void *param) uint8_t temp_band_cap; struct cds_config_info *cds_cfg = cds_get_ini_config(); uint8_t antenna_mode; + QDF_STATUS status; ret = hdd_objmgr_create_and_store_pdev(hdd_ctx); if (ret) { @@ -1856,7 +1857,7 @@ void hdd_update_tgt_cfg(void *context, void *param) QDF_BUG(0); } else { hdd_debug("New pdev has been created with pdev_id = %u", - hdd_ctx->hdd_pdev->pdev_objmgr.wlan_pdev_id); + hdd_ctx->hdd_pdev->pdev_objmgr.wlan_pdev_id); } ret = hdd_update_green_ap_config(hdd_ctx); @@ -1952,13 +1953,13 @@ void hdd_update_tgt_cfg(void *context, void *param) hdd_ctx->config->fine_time_meas_cap &= cfg->fine_time_measurement_cap; hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap; hdd_debug("fine_time_meas_cap: 0x%x", - hdd_ctx->config->fine_time_meas_cap); + hdd_ctx->config->fine_time_meas_cap); antenna_mode = (hdd_ctx->config->enable2x2 == 0x01) ? HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1; hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode); hdd_debug("Init current antenna mode: %d", - hdd_ctx->current_antenna_mode); + hdd_ctx->current_antenna_mode); hdd_ctx->bpf_enabled = (cfg->bpf_enabled && hdd_ctx->config->bpf_packet_filter_enable); @@ -1966,20 +1967,21 @@ void hdd_update_tgt_cfg(void *context, void *param) hdd_update_ra_rate_limit(hdd_ctx, cfg); if ((hdd_ctx->config->txBFCsnValue > - WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) && - !cfg->tx_bfee_8ss_enabled) + WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) && + !cfg->tx_bfee_8ss_enabled) hdd_ctx->config->txBFCsnValue = WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF; - if (sme_cfg_set_int(hdd_ctx->hHal, - WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED, - hdd_ctx->config->txBFCsnValue) == QDF_STATUS_E_FAILURE) + status = sme_cfg_set_int(hdd_ctx->hHal, + WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED, + hdd_ctx->config->txBFCsnValue); + if (QDF_IS_STATUS_ERROR(status)) hdd_err("fw update WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED to CFG fails"); hdd_debug("Target BPF %d Host BPF %d 8ss fw support %d txBFCsnValue %d", - cfg->bpf_enabled, hdd_ctx->config->bpf_packet_filter_enable, - cfg->tx_bfee_8ss_enabled, hdd_ctx->config->txBFCsnValue); + cfg->bpf_enabled, hdd_ctx->config->bpf_packet_filter_enable, + cfg->tx_bfee_8ss_enabled, hdd_ctx->config->txBFCsnValue); /* * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy @@ -2006,6 +2008,10 @@ void hdd_update_tgt_cfg(void *context, void *param) hdd_nan_datapath_target_config(hdd_ctx, cfg); hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload; hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share; + status = sme_cfg_set_int(hdd_ctx->hHal, WNI_CFG_OBSS_DETECTION_OFFLOAD, + cfg->obss_detection_offloaded); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("Couldn't pass WNI_CFG_OBSS_DETECTION_OFFLOAD to CFG"); } bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx) diff --git a/core/mac/inc/ani_global.h b/core/mac/inc/ani_global.h index 5750210976..7cd8b1cbc2 100644 --- a/core/mac/inc/ani_global.h +++ b/core/mac/inc/ani_global.h @@ -828,6 +828,7 @@ typedef struct sAniSirLim { uint8_t scan_disabled; uint8_t beacon_probe_rsp_cnt_per_scan; wlan_scan_requester req_id; + uint8_t obss_detection_offloaded; } tAniSirLim, *tpAniSirLim; struct mgmt_frm_reg_info { diff --git a/core/mac/inc/wni_cfg.h b/core/mac/inc/wni_cfg.h index 828e4030b0..3d41783f82 100644 --- a/core/mac/inc/wni_cfg.h +++ b/core/mac/inc/wni_cfg.h @@ -353,6 +353,7 @@ enum { WNI_CFG_EDCA_ETSI_ACBE, WNI_CFG_EDCA_ETSI_ACVI, WNI_CFG_EDCA_ETSI_ACVO, + WNI_CFG_OBSS_DETECTION_OFFLOAD, /* Any new items to be added should be above this strictly */ CFG_PARAM_MAX_NUM }; diff --git a/core/mac/src/cfg/cfg_param_name.c b/core/mac/src/cfg/cfg_param_name.c index f417b7a56e..857ea17f13 100644 --- a/core/mac/src/cfg/cfg_param_name.c +++ b/core/mac/src/cfg/cfg_param_name.c @@ -355,6 +355,7 @@ const char *cfg_get_string(uint16_t cfg_id) CASE_RETURN_STRING(WNI_CFG_EDCA_ETSI_ACBE); CASE_RETURN_STRING(WNI_CFG_EDCA_ETSI_ACVI); CASE_RETURN_STRING(WNI_CFG_EDCA_ETSI_ACVO); + CASE_RETURN_STRING(WNI_CFG_OBSS_DETECTION_OFFLOAD); } return "invalid"; diff --git a/core/mac/src/cfg/cfg_proc_msg.c b/core/mac/src/cfg/cfg_proc_msg.c index ea80bc1855..0644b84862 100644 --- a/core/mac/src/cfg/cfg_proc_msg.c +++ b/core/mac/src/cfg/cfg_proc_msg.c @@ -1581,6 +1581,9 @@ cgstatic cfg_static[CFG_PARAM_MAX_NUM] = { {WNI_CFG_EDCA_ETSI_ACVO, CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_RESTART, 0, 0, 0}, + {WNI_CFG_OBSS_DETECTION_OFFLOAD, + CFG_CTL_VALID | CFG_CTL_RE | CFG_CTL_WE | CFG_CTL_INT, + 0, 1, 0}, }; diff --git a/core/mac/src/include/sir_params.h b/core/mac/src/include/sir_params.h index 498d0a36b5..94212a37a3 100644 --- a/core/mac/src/include/sir_params.h +++ b/core/mac/src/include/sir_params.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -678,6 +678,8 @@ typedef struct sSirMbMsgP2p { #define SIR_HAL_SET_DEL_PMKID_CACHE (SIR_HAL_ITC_MSG_TYPES_BEGIN + 391) #define SIR_HAL_HLP_IE_INFO (SIR_HAL_ITC_MSG_TYPES_BEGIN + 392) +#define SIR_HAL_OBSS_DETECTION_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 393) +#define SIR_HAL_OBSS_DETECTION_INFO (SIR_HAL_ITC_MSG_TYPES_BEGIN + 394) #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) /* CFG message types */ diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h index 07b948f80a..ca3b506bf4 100644 --- a/core/mac/src/pe/include/lim_session.h +++ b/core/mac/src/pe/include/lim_session.h @@ -106,6 +106,26 @@ struct bss_color_info { }; #endif +/** + * struct obss_detection_cfg - current obss detection cfg set to firmware + * @obss_11b_ap_detect_mode: detection mode for 11b access point. + * @obss_11b_sta_detect_mode: detection mode for 11b station. + * @obss_11g_ap_detect_mode: detection mode for 11g access point. + * @obss_11a_detect_mode: detection mode for 11a access point. + * @obss_ht_legacy_detect_mode: detection mode for ht ap with legacy mode. + * @obss_ht_mixed_detect_mode: detection mode for ht ap with mixed mode. + * @obss_ht_20mhz_detect_mode: detection mode for ht ap with 20mhz mode. + */ +struct obss_detection_cfg { + uint8_t obss_11b_ap_detect_mode; + uint8_t obss_11b_sta_detect_mode; + uint8_t obss_11g_ap_detect_mode; + uint8_t obss_11a_detect_mode; + uint8_t obss_ht_legacy_detect_mode; + uint8_t obss_ht_mixed_detect_mode; + uint8_t obss_ht_20mhz_detect_mode; +}; + typedef struct sPESession /* Added to Support BT-AMP */ { /* To check session table is in use or free */ @@ -526,6 +546,8 @@ typedef struct sPESession /* Added to Support BT-AMP */ #endif /* previous auth frame's sequence number */ uint16_t prev_auth_seq_num; + struct obss_detection_cfg obss_offload_cfg; + bool enable_obss_detection_offload; } tPESession, *tpPESession; /*------------------------------------------------------------------------- diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index 91a6907362..d3430d5715 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -466,6 +466,15 @@ static tSirRetStatus __lim_init_config(tpAniSirGlobal pMac) return eSIR_FAILURE; } #endif + + if (eSIR_SUCCESS != wlan_cfg_get_int(pMac, + WNI_CFG_OBSS_DETECTION_OFFLOAD, + (uint32_t *)&pMac->lim. + obss_detection_offloaded)) { + pe_err("cfg get obss_detection_offloaded failed"); + return eSIR_FAILURE; + } + return eSIR_SUCCESS; } diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c index 6ff444c7e5..cf7b7316e1 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/core/mac/src/pe/lim/lim_process_message_queue.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2018 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -1900,6 +1900,10 @@ static void lim_process_messages(tpAniSirGlobal mac_ctx, qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; break; + case WMA_OBSS_DETECTION_INFO: + qdf_mem_free(msg->bodyptr); + msg->bodyptr = NULL; + break; default: qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 1695e0f30a..8cc21cccfc 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -1350,4 +1350,18 @@ int wma_fill_beacon_interval_reset_req(tp_wma_handle wma, uint8_t vdev_id, * Return: 'true' on valid vdev else 'false' */ bool wma_is_vdev_valid(uint32_t vdev_id); + +/** + * wma_vdev_obss_detection_info_handler - event handler to handle obss detection + * @handle: the wma handle + * @event: buffer with event + * @len: buffer length + * + * This function receives obss detection info from firmware which is used to + * decide obss protection. + * + * Return: 0 on success + */ +int wma_vdev_obss_detection_info_handler(void *handle, uint8_t *event, + uint32_t len); #endif diff --git a/core/wma/inc/wma_tgt_cfg.h b/core/wma/inc/wma_tgt_cfg.h index b3a7236a3b..6ca66f0a10 100644 --- a/core/wma/inc/wma_tgt_cfg.h +++ b/core/wma/inc/wma_tgt_cfg.h @@ -159,6 +159,7 @@ struct wma_dfs_radar_ind { * @dfs_cac_offload: dfs and cac timer offloaded * @tx_bfee_8ss_enabled: Tx Beamformee support for 8x8 * @rcpi_enabled: for checking rcpi support + * @obss_detection_offloaded: obss detection offloaded to firmware */ struct wma_tgt_cfg { uint32_t target_fw_version; @@ -196,5 +197,6 @@ struct wma_tgt_cfg { bool dfs_cac_offload; bool tx_bfee_8ss_enabled; bool rcpi_enabled; + bool obss_detection_offloaded; }; #endif /* WMA_TGT_CFG_H */ diff --git a/core/wma/inc/wma_types.h b/core/wma/inc/wma_types.h index 56500f4c93..b53823cc15 100644 --- a/core/wma/inc/wma_types.h +++ b/core/wma/inc/wma_types.h @@ -476,6 +476,8 @@ #define WMA_SET_ARP_STATS_REQ SIR_HAL_SET_ARP_STATS_REQ #define WMA_GET_ARP_STATS_REQ SIR_HAL_GET_ARP_STATS_REQ #define WMA_SET_LIMIT_OFF_CHAN SIR_HAL_SET_LIMIT_OFF_CHAN +#define WMA_OBSS_DETECTION_REQ SIR_HAL_OBSS_DETECTION_REQ +#define WMA_OBSS_DETECTION_INFO SIR_HAL_OBSS_DETECTION_INFO /* Bit 6 will be used to control BD rate for Management frames */ #define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index 73f498c037..dce9eae424 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -5253,3 +5253,42 @@ int wma_peer_ant_info_evt_handler(void *handle, u_int8_t *event, return 0; } + +int wma_vdev_obss_detection_info_handler(void *handle, uint8_t *event, + uint32_t len) +{ + tp_wma_handle wma = (tp_wma_handle) handle; + struct wmi_obss_detect_info *obss_detection; + QDF_STATUS status; + + if (!event) { + WMA_LOGE("Invalid obss_detection_info event buffer"); + return -EINVAL; + } + + obss_detection = qdf_mem_malloc(sizeof(*obss_detection)); + if (!obss_detection) { + WMA_LOGE("%s: Failed to malloc", __func__); + return -ENOMEM; + } + + status = wmi_unified_extract_obss_detection_info(wma->wmi_handle, + event, obss_detection); + + if (QDF_IS_STATUS_ERROR(status)) { + WMA_LOGE("%s: Failed to extract obss info", __func__); + qdf_mem_free(obss_detection); + return -EINVAL; + } + + if (!wma_is_vdev_valid(obss_detection->vdev_id)) { + WMA_LOGE("%s: Invalid vdev id %d", __func__, + obss_detection->vdev_id); + qdf_mem_free(obss_detection); + return -EINVAL; + } + + wma_send_msg(wma, WMA_OBSS_DETECTION_INFO, obss_detection, 0); + + return 0; +} diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index f866e3fb5b..784a1b405f 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -2951,6 +2951,11 @@ QDF_STATUS wma_open(struct wlan_objmgr_psoc *psoc, wma_unified_phyerr_rx_event_handler, WMA_RX_WORK_CTX); + wmi_unified_register_event_handler(wma_handle->wmi_handle, + wmi_sap_obss_detection_report_event_id, + wma_vdev_obss_detection_info_handler, + WMA_RX_SERIALIZER_CTX); + return QDF_STATUS_SUCCESS; err_dbglog_init: @@ -4822,6 +4827,26 @@ static void wma_update_hdd_band_cap(WMI_PHY_CAPABILITY supported_band, } } +/** + * wma_update_obss_detection_support() - update obss detection offload support + * @wh: wma handle + * @tgt_cfg: target configuration to be updated + * + * Update obss detection offload support based on service bit. + * + * Return: None + */ +static void wma_update_obss_detection_support(tp_wma_handle wh, + struct wma_tgt_cfg *tgt_cfg) +{ + if (WMI_SERVICE_EXT_IS_ENABLED(wh->wmi_service_bitmap, + wh->wmi_service_ext_bitmap, + WMI_SERVICE_AP_OBSS_DETECTION_OFFLOAD)) + tgt_cfg->obss_detection_offloaded = true; + else + tgt_cfg->obss_detection_offloaded = false; +} + /** * wma_update_hdd_cfg() - update HDD config * @wma_handle: wma handle @@ -4873,6 +4898,7 @@ static void wma_update_hdd_cfg(tp_wma_handle wma_handle) - WMI_TLV_HEADROOM; wma_setup_egap_support(&tgt_cfg, wma_handle); tgt_cfg.tx_bfee_8ss_enabled = wma_handle->tx_bfee_8ss_enabled; + wma_update_obss_detection_support(wma_handle, &tgt_cfg); wma_update_hdd_cfg_ndp(wma_handle, &tgt_cfg); wma_handle->tgt_cfg_update_cb(hdd_ctx, &tgt_cfg); } @@ -7224,6 +7250,39 @@ static QDF_STATUS wma_process_limit_off_chan(tp_wma_handle wma_handle, return QDF_STATUS_SUCCESS; } +/** + * wma_send_obss_detection_cfg() - send obss detection cfg to firmware + * @wma_handle: pointer to wma handle + * @cfg: obss detection configuration + * + * Send obss detection configuration to firmware. + * + * Return: None + */ +static void wma_send_obss_detection_cfg(tp_wma_handle wma_handle, + struct wmi_obss_detection_cfg_param + *cfg) +{ + QDF_STATUS status; + + if (cfg->vdev_id >= wma_handle->max_bssid) { + WMA_LOGE(FL("Invalid vdev_id: %d"), cfg->vdev_id); + return; + } + if (!wma_is_vdev_up(cfg->vdev_id)) { + WMA_LOGE("vdev %d is not up skipping obss detection req", + cfg->vdev_id); + return; + } + + status = wmi_unified_send_obss_detection_cfg_cmd(wma_handle->wmi_handle, + cfg); + if (QDF_IS_STATUS_ERROR(status)) + WMA_LOGE("Failed to send obss detection cfg"); + + return; +} + /** * wma_mc_process_msg() - process wma messages and call appropriate function. * @msg: message @@ -8000,6 +8059,10 @@ static QDF_STATUS wma_mc_process_msg(struct scheduler_msg *msg) wma_process_limit_off_chan(wma_handle, msg->bodyptr); qdf_mem_free(msg->bodyptr); break; + case WMA_OBSS_DETECTION_REQ: + wma_send_obss_detection_cfg(wma_handle, msg->bodyptr); + qdf_mem_free(msg->bodyptr); + break; default: WMA_LOGE("Unhandled WMA message of type %d", msg->type); if (msg->bodyptr)