diff --git a/os_if/linux/qca_vendor.h b/os_if/linux/qca_vendor.h index e731410a12..43dbc29487 100644 --- a/os_if/linux/qca_vendor.h +++ b/os_if/linux/qca_vendor.h @@ -2642,6 +2642,8 @@ enum qca_wlan_vendor_attr_pno_config_params { * set bssid params num bssid * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID: * set bssid params bssid + * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_HINT: + * flag attribute to specify whether the AP is avoided, or blacklisted. * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_AFTER_LAST: After last * @QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX: Max */ @@ -2673,6 +2675,7 @@ enum qca_wlan_vendor_attr_roaming_config_params { QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS = 18, QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID = 19, QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID = 20, + QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_HINT = 21, /* keep last */ QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_AFTER_LAST, diff --git a/qdf/inc/qdf_types.h b/qdf/inc/qdf_types.h index 52b02df05a..886a509efb 100644 --- a/qdf/inc/qdf_types.h +++ b/qdf/inc/qdf_types.h @@ -366,6 +366,7 @@ typedef bool (*qdf_irqlocked_func_t)(void *); * @QDF_MODULE_ID_CFR: CFR module ID * @QDF_MODULE_ID_TX_CAPTURE: Tx capture enhancement feature ID * @QDF_MODULE_ID_INTEROP_ISSUES_AP: interop issues ap module ID + * @QDF_MODULE_ID_BLACKLIST_MGR: Blacklist Manager module * @QDF_MODULE_ID_ANY: anything * @QDF_MODULE_ID_MAX: Max place holder module ID */ @@ -481,6 +482,7 @@ typedef enum { QDF_MODULE_ID_CFR, QDF_MODULE_ID_TX_CAPTURE, QDF_MODULE_ID_INTEROP_ISSUES_AP, + QDF_MODULE_ID_BLACKLIST_MGR, QDF_MODULE_ID_ANY, QDF_MODULE_ID_MAX, } QDF_MODULE_ID; diff --git a/qdf/linux/src/qdf_trace.c b/qdf/linux/src/qdf_trace.c index 4239147325..b2f7e98ae3 100644 --- a/qdf/linux/src/qdf_trace.c +++ b/qdf/linux/src/qdf_trace.c @@ -2709,6 +2709,7 @@ struct category_name_info g_qdf_category_name[MAX_SUPPORTED_CATEGORY] = { [QDF_MODULE_ID_CFR] = {"CFR"}, [QDF_MODULE_ID_TX_CAPTURE] = {"TX_CAPTURE_ENHANCE"}, [QDF_MODULE_ID_INTEROP_ISSUES_AP] = {"INTEROP_ISSUES_AP"}, + [QDF_MODULE_ID_BLACKLIST_MGR] = {"blm"}, [QDF_MODULE_ID_ANY] = {"ANY"}, }; qdf_export_symbol(g_qdf_category_name); @@ -3166,6 +3167,7 @@ static void set_default_trace_levels(struct category_info *cinfo) [QDF_MODULE_ID_CFR] = QDF_TRACE_LEVEL_ERROR, [QDF_MODULE_ID_TX_CAPTURE] = QDF_TRACE_LEVEL_NONE, [QDF_MODULE_ID_INTEROP_ISSUES_AP] = QDF_TRACE_LEVEL_NONE, + [QDF_MODULE_ID_BLACKLIST_MGR] = QDF_TRACE_LEVEL_NONE, [QDF_MODULE_ID_ANY] = QDF_TRACE_LEVEL_INFO, }; diff --git a/umac/cmn_services/inc/wlan_cmn.h b/umac/cmn_services/inc/wlan_cmn.h index 1b6f8c4df6..fa0b24185d 100644 --- a/umac/cmn_services/inc/wlan_cmn.h +++ b/umac/cmn_services/inc/wlan_cmn.h @@ -271,6 +271,7 @@ * @WLAN_UMAC_COMP_ACTION_OUI: ACTION OUI * @WLAN_UMAC_COMP_FWOL FW Offload * @WLAN_UMAC_COMP_INTEROP_ISSUES_AP interop issues ap component + * @WLAN_UMAC_COMP_BLACKLIST_MGR: Blacklist mgr component * @WLAN_UMAC_COMP_ID_MAX: Maximum components in UMAC * * This id is static. @@ -308,7 +309,8 @@ enum wlan_umac_comp_id { WLAN_UMAC_COMP_ACTION_OUI = 28, WLAN_UMAC_COMP_FWOL = 29, WLAN_UMAC_COMP_CFR = 30, - WLAN_UMAC_COMP_INTEROP_ISSUES_AP = 31, + WLAN_UMAC_COMP_INTEROP_ISSUES_AP = 31, + WLAN_UMAC_COMP_BLACKLIST_MGR = 32, WLAN_UMAC_COMP_ID_MAX, }; diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index 04043526f6..7889281c11 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -5310,6 +5310,7 @@ typedef enum { wmi_service_wpa3_ft_suite_b_support, wmi_service_ft_fils, wmi_service_adaptive_11r_support, + wmi_service_data_stall_recovery_support, wmi_service_tx_compl_tsf64, wmi_services_max, } wmi_conv_service_ids; diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index e34c66ed9c..6d45d8de12 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -352,6 +352,12 @@ QDF_STATUS (*send_d0wow_disable_cmd)(wmi_unified_t wmi_handle, uint8_t mac_id); #endif +#ifdef FEATURE_BLACKLIST_MGR +QDF_STATUS +(*send_reject_ap_list_cmd)(struct wmi_unified *wmi_handle, + struct reject_ap_params *reject_params); +#endif + QDF_STATUS (*send_wow_enable_cmd)(wmi_unified_t wmi_handle, struct wow_cmd_params *param, uint8_t mac_id); @@ -2322,6 +2328,15 @@ void wmi_policy_mgr_attach_tlv(struct wmi_unified *wmi_handle) } #endif +#ifdef FEATURE_BLACKLIST_MGR +void wmi_blacklist_mgr_attach_tlv(struct wmi_unified *wmi_handle); +#else +static inline +void wmi_blacklist_mgr_attach_tlv(struct wmi_unified *wmi_handle) +{ +} +#endif + #ifdef WMI_STA_SUPPORT void wmi_sta_attach_tlv(struct wmi_unified *wmi_handle); #else diff --git a/wmi/inc/wmi_unified_roam_param.h b/wmi/inc/wmi_unified_roam_param.h index 8997500e69..c63f2847ce 100644 --- a/wmi/inc/wmi_unified_roam_param.h +++ b/wmi/inc/wmi_unified_roam_param.h @@ -23,6 +23,8 @@ #ifndef _WMI_UNIFIED_ROAM_PARAM_H_ #define _WMI_UNIFIED_ROAM_PARAM_H_ +#include + /** * struct gateway_update_req_param - gateway parameter update request * @request_id: request id @@ -168,19 +170,6 @@ struct wmi_mawc_roam_params { #define MAX_SSID_ALLOWED_LIST 4 #define MAX_BSSID_AVOID_LIST 16 #define MAX_BSSID_FAVORED 16 -#define MAX_RSSI_AVOID_BSSID_LIST 10 - -/** - * struct rssi_disallow_bssid - Structure holding Rssi based avoid candidate - * @bssid: BSSID of the AP - * @remaining_duration: remaining disallow duration in ms - * @expected_rssi: RSSI at which STA can initate in dBm - */ -struct rssi_disallow_bssid { - struct qdf_mac_addr bssid; - uint32_t remaining_duration; - int8_t expected_rssi; -}; /** * struct roam_scan_filter_params - Structure holding roaming scan @@ -228,7 +217,8 @@ struct roam_scan_filter_params { uint32_t rssi_channel_penalization; uint32_t num_disallowed_aps; uint32_t num_rssi_rejection_ap; - struct rssi_disallow_bssid rssi_rejection_ap[MAX_RSSI_AVOID_BSSID_LIST]; + struct reject_ap_config_params + rssi_rejection_ap[MAX_RSSI_AVOID_BSSID_LIST]; }; #define WMI_CFG_VALID_CHANNEL_LIST_LEN 100 @@ -534,6 +524,7 @@ struct ap_profile_params { * @frame_len: frame length, includs mac header, fixed params and ies * @frame_buf: buffer contaning probe response or beacon * @is_same_bssid: flag to indicate if roaming is requested for same bssid + * @forced_roaming: Roam to any bssid in any ch (here bssid & ch is not given) */ struct wmi_roam_invoke_cmd { uint32_t vdev_id; @@ -542,6 +533,7 @@ struct wmi_roam_invoke_cmd { uint32_t frame_len; uint8_t *frame_buf; uint8_t is_same_bssid; + bool forced_roaming; }; /** diff --git a/wmi/inc/wmi_unified_sta_api.h b/wmi/inc/wmi_unified_sta_api.h index f40db701bd..9cecbae341 100644 --- a/wmi/inc/wmi_unified_sta_api.h +++ b/wmi/inc/wmi_unified_sta_api.h @@ -96,6 +96,20 @@ QDF_STATUS wmi_extract_encrypt_decrypt_resp_params(void *wmi_hdl, struct disa_encrypt_decrypt_resp_params *resp); #endif /* WLAN_FEATURE_DISA */ +#ifdef FEATURE_BLACKLIST_MGR +/** + * wmi_unified_send_reject_ap_list() - send the reject ap list maintained by + * BLM to FW for roaming cases. + * @wmi_handle: wmi handle + * @reject_params: This contains the reject ap list, and the num of BSSIDs. + * + * Return: QDF_STATUS_SUCCESS for success or error code + */ +QDF_STATUS +wmi_unified_send_reject_ap_list(struct wmi_unified *wmi_handle, + struct reject_ap_params *reject_params); +#endif + /** * wmi_unified_process_dhcp_ind() - process dhcp indication from SME * @wmi_handle: wmi handle diff --git a/wmi/src/wmi_unified_roam_tlv.c b/wmi/src/wmi_unified_roam_tlv.c index 86f9f2740e..99bd63e85a 100644 --- a/wmi/src/wmi_unified_roam_tlv.c +++ b/wmi/src/wmi_unified_roam_tlv.c @@ -511,7 +511,7 @@ static QDF_STATUS send_roam_scan_filter_cmd_tlv(wmi_unified_t wmi_handle, roam_req->rssi_rejection_ap[i].bssid.bytes, &rssi_rej->bssid); rssi_rej->remaining_disallow_duration = - roam_req->rssi_rejection_ap[i].remaining_duration; + roam_req->rssi_rejection_ap[i].reject_duration; rssi_rej->requested_rssi = (int32_t)roam_req->rssi_rejection_ap[i].expected_rssi; buf_ptr += @@ -836,7 +836,6 @@ static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle, wmi_mac_addr *bssid_list; wmi_tlv_buf_len_param *buf_len_tlv; - /* Host sends only one channel and one bssid */ args_tlv_len = (4 * WMI_TLV_HDR_SIZE) + sizeof(uint32_t) + sizeof(wmi_mac_addr) + sizeof(wmi_tlv_buf_len_param) + roundup(roaminvoke->frame_len, sizeof(uint32_t)); @@ -871,6 +870,12 @@ static QDF_STATUS send_roam_invoke_cmd_tlv(wmi_unified_t wmi_handle, cmd->num_chan = 1; cmd->num_bssid = 1; + if (roaminvoke->forced_roaming) { + cmd->num_chan = 0; + cmd->num_bssid = 0; + cmd->roam_scan_mode = WMI_ROAM_INVOKE_SCAN_MODE_CACHE_MAP; + } + buf_ptr += sizeof(wmi_roam_invoke_cmd_fixed_param); WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, (sizeof(u_int32_t))); diff --git a/wmi/src/wmi_unified_sta_api.c b/wmi/src/wmi_unified_sta_api.c index 98a998509c..9585dd88e4 100644 --- a/wmi/src/wmi_unified_sta_api.c +++ b/wmi/src/wmi_unified_sta_api.c @@ -223,6 +223,19 @@ QDF_STATUS wmi_extract_encrypt_decrypt_resp_params(void *wmi_hdl, } #endif /* WLAN_FEATURE_DISA */ +#ifdef FEATURE_BLACKLIST_MGR +QDF_STATUS +wmi_unified_send_reject_ap_list(struct wmi_unified *wmi_handle, + struct reject_ap_params *reject_params) +{ + if (wmi_handle->ops->send_reject_ap_list_cmd) + return wmi_handle->ops->send_reject_ap_list_cmd(wmi_handle, + reject_params); + + return QDF_STATUS_E_FAILURE; +} +#endif + QDF_STATUS wmi_unified_send_sar_limit_cmd(void *wmi_hdl, struct sar_limit_cmd_params *params) { diff --git a/wmi/src/wmi_unified_sta_tlv.c b/wmi/src/wmi_unified_sta_tlv.c index 4c9e3fce0f..dfcfbc0cc0 100644 --- a/wmi/src/wmi_unified_sta_tlv.c +++ b/wmi/src/wmi_unified_sta_tlv.c @@ -1088,6 +1088,107 @@ static QDF_STATUS send_set_base_macaddr_indicate_cmd_tlv(wmi_unified_t wmi_handl return 0; } +#ifdef FEATURE_BLACKLIST_MGR + +static WMI_BSSID_DISALLOW_LIST_TYPE +wmi_get_wmi_reject_ap_type(enum blm_reject_ap_type reject_ap_type) +{ + switch (reject_ap_type) { + case USERSPACE_AVOID_TYPE: + return WMI_BSSID_DISALLOW_USER_SPACE_AVOID_LIST; + case DRIVER_AVOID_TYPE: + return WMI_BSSID_DISALLOW_DRIVER_AVOID_LIST; + case USERSPACE_BLACKLIST_TYPE: + return WMI_BSSID_DISALLOW_USER_SPACE_BLACK_LIST; + case DRIVER_BLACKLIST_TYPE: + return WMI_BSSID_DISALLOW_DRIVER_BLACK_LIST; + case DRIVER_RSSI_REJECT_TYPE: + return WMI_BSSID_DISALLOW_RSSI_REJECT_LIST; + default: + return WMI_BSSID_DISALLOW_DRIVER_AVOID_LIST; + } +} + +static QDF_STATUS +send_reject_ap_list_cmd_tlv(wmi_unified_t wmi_handle, + struct reject_ap_params *reject_params) +{ + wmi_buf_t buf; + QDF_STATUS status; + uint32_t len, list_tlv_len; + int i; + uint8_t *buf_ptr; + wmi_pdev_dsm_filter_fixed_param *chan_list_fp; + wmi_pdev_bssid_disallow_list_config_param *chan_list; + struct reject_ap_config_params *reject_list = reject_params->bssid_list; + uint8_t num_of_reject_bssid = reject_params->num_of_reject_bssid; + + if (!num_of_reject_bssid) { + WMI_LOGD("%s : invalid number of channels %d", __func__, + num_of_reject_bssid); + return QDF_STATUS_E_EMPTY; + } + + list_tlv_len = sizeof(*chan_list) * num_of_reject_bssid; + + len = sizeof(*chan_list_fp) + list_tlv_len + WMI_TLV_HDR_SIZE; + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) + return QDF_STATUS_E_NOMEM; + + WMI_LOGD("num of reject BSSIDs %d", num_of_reject_bssid); + + buf_ptr = (uint8_t *)wmi_buf_data(buf); + chan_list_fp = (wmi_pdev_dsm_filter_fixed_param *)buf_ptr; + WMITLV_SET_HDR(&chan_list_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_pdev_dsm_filter_fixed_param, + WMITLV_GET_STRUCT_TLVLEN + (wmi_pdev_dsm_filter_fixed_param)); + + buf_ptr += sizeof(wmi_pdev_dsm_filter_fixed_param); + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, list_tlv_len); + + buf_ptr += WMI_TLV_HDR_SIZE; + chan_list = (wmi_pdev_bssid_disallow_list_config_param *)buf_ptr; + for (i = 0; i < num_of_reject_bssid; i++) { + + WMITLV_SET_HDR(&chan_list->tlv_header, + WMITLV_TAG_STRUC_wmi_pdev_bssid_disallow_list_config_param, + WMITLV_GET_STRUCT_TLVLEN + (wmi_pdev_bssid_disallow_list_config_param)); + WMI_CHAR_ARRAY_TO_MAC_ADDR(reject_list[i].bssid.bytes, + &chan_list->bssid); + chan_list->bssid_type = + wmi_get_wmi_reject_ap_type(reject_list[i].reject_ap_type); + chan_list->expected_rssi = reject_list[i].expected_rssi; + chan_list->remaining_disallow_duration = + reject_list[i].reject_duration; + chan_list++; + } + + wmi_mtrace(WMI_PDEV_DSM_FILTER_CMDID, NO_SESSION, 0); + status = wmi_unified_cmd_send(wmi_handle, buf, + len, WMI_PDEV_DSM_FILTER_CMDID); + if (QDF_IS_STATUS_ERROR(status)) { + WMI_LOGE("wmi_unified_cmd_send WMI_PDEV_DSM_FILTER_CMDID returned Error %d", + status); + goto error; + } + + return QDF_STATUS_SUCCESS; +error: + wmi_buf_free(buf); + return status; +} + +void wmi_blacklist_mgr_attach_tlv(struct wmi_unified *wmi_handle) +{ + struct wmi_ops *ops = wmi_handle->ops; + + ops->send_reject_ap_list_cmd = send_reject_ap_list_cmd_tlv; +} +#endif + #ifdef WLAN_FEATURE_DISA /** * send_encrypt_decrypt_send_cmd() - send encrypt/decrypt cmd to fw @@ -2498,5 +2599,6 @@ void wmi_sta_attach_tlv(wmi_unified_t wmi_handle) wmi_tdls_attach_tlv(wmi_handle); wmi_disa_attach_tlv(wmi_handle); wmi_policy_mgr_attach_tlv(wmi_handle); + wmi_blacklist_mgr_attach_tlv(wmi_handle); } diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 47b4e109ff..b5648b3454 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -12476,6 +12476,8 @@ static void populate_tlv_service(uint32_t *wmi_service) WMI_SERVICE_ADAPTIVE_11R_ROAM; wmi_service[wmi_service_tx_compl_tsf64] = WMI_SERVICE_TX_COMPL_TSF64; + wmi_service[wmi_service_data_stall_recovery_support] = + WMI_SERVICE_DSM_ROAM_FILTER; } /**