diff --git a/components/p2p/core/src/wlan_p2p_main.c b/components/p2p/core/src/wlan_p2p_main.c index 4c835df29231..cc9694812fa1 100644 --- a/components/p2p/core/src/wlan_p2p_main.c +++ b/components/p2p/core/src/wlan_p2p_main.c @@ -552,6 +552,8 @@ static QDF_STATUS p2p_object_init_params( cfg_get(psoc, CFG_GO_LINK_MONITOR_PERIOD); p2p_soc_obj->param.p2p_device_addr_admin = cfg_get(psoc, CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED); + p2p_soc_obj->param.p2p_disable_roam = + cfg_get(psoc, CFG_P2P_DISABLE_ROAM); return QDF_STATUS_SUCCESS; } diff --git a/components/p2p/core/src/wlan_p2p_main.h b/components/p2p/core/src/wlan_p2p_main.h index 1336cf42d341..67eae6c080ac 100644 --- a/components/p2p/core/src/wlan_p2p_main.h +++ b/components/p2p/core/src/wlan_p2p_main.h @@ -198,11 +198,14 @@ enum p2p_connection_status { * @p2p_device_addr_admin: enable/disable to derive the P2P * MAC address from the primary MAC address * @skip_dfs_channel_p2p_search: skip DFS Channel in case of P2P Search + * @p2p_disable_roam: Disable Roam on sta interface during P2P + * connection */ struct p2p_param { uint32_t go_keepalive_period; uint32_t go_link_monitor_period; bool p2p_device_addr_admin; + bool p2p_disable_roam; }; /** diff --git a/components/p2p/dispatcher/inc/wlan_p2p_cfg.h b/components/p2p/dispatcher/inc/wlan_p2p_cfg.h index c2f5541b5237..05b8341df08f 100644 --- a/components/p2p/dispatcher/inc/wlan_p2p_cfg.h +++ b/components/p2p/dispatcher/inc/wlan_p2p_cfg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -98,9 +98,32 @@ 1, \ "derive the P2P MAC address from the primary MAC address") +/* + * + * p2p_disable_roam - Disable Roam on sta interface during P2P connection + * @Min: 0 - Roam Enabled on sta interface during P2P connection + * @Max: 1 - Roam Disabled on sta interface during P2P connection + * @Default: 0 + * + * Disable roaming on STA iface to avoid audio glitches on p2p if its connected + * + * Related: None. + * + * Supported Feature: Disable Roam during P2P + * + * Usage: Internal + * + * + */ +#define CFG_P2P_DISABLE_ROAM CFG_INI_BOOL( \ + "p2p_disable_roam", \ + 0, \ + "disable roam on STA iface if p2p is connected") + #define CFG_P2P_ALL \ CFG(CFG_GO_KEEP_ALIVE_PERIOD) \ CFG(CFG_GO_LINK_MONITOR_PERIOD) \ - CFG(CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED) + CFG(CFG_P2P_DEVICE_ADDRESS_ADMINISTRATED) \ + CFG(CFG_P2P_DISABLE_ROAM) #endif diff --git a/components/p2p/dispatcher/inc/wlan_p2p_cfg_api.h b/components/p2p/dispatcher/inc/wlan_p2p_cfg_api.h index b3167be4b87e..72e864833a97 100644 --- a/components/p2p/dispatcher/inc/wlan_p2p_cfg_api.h +++ b/components/p2p/dispatcher/inc/wlan_p2p_cfg_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -61,4 +61,13 @@ QDF_STATUS cfg_p2p_get_device_addr_admin(struct wlan_objmgr_psoc *psoc, bool *enable); +/** + * cfg_p2p_is_roam_config_disabled() - get disable roam config on sta interface + * during p2p connection + * @psoc: pointer to psoc object + * + * Get disable roam configuration during p2p connection + */ +bool cfg_p2p_is_roam_config_disabled(struct wlan_objmgr_psoc *psoc); + #endif /* _WLAN_P2P_CFG_API_H_ */ diff --git a/components/p2p/dispatcher/inc/wlan_p2p_ucfg_api.h b/components/p2p/dispatcher/inc/wlan_p2p_ucfg_api.h index 4f1c4d38fbd7..c855e7fd0b8b 100644 --- a/components/p2p/dispatcher/inc/wlan_p2p_ucfg_api.h +++ b/components/p2p/dispatcher/inc/wlan_p2p_ucfg_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018,2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -23,6 +23,7 @@ #ifndef _WLAN_P2P_UCFG_API_H_ #define _WLAN_P2P_UCFG_API_H_ +#include "wlan_p2p_cfg_api.h" #include struct wlan_objmgr_psoc; @@ -409,4 +410,18 @@ QDF_STATUS ucfg_p2p_status_start_bss(struct wlan_objmgr_vdev *vdev); */ QDF_STATUS ucfg_p2p_status_stop_bss(struct wlan_objmgr_vdev *vdev); +/** + * ucfg_p2p_is_roam_config_disabled() - Roam disable config during p2p + * connection + * @psoc: psoc context + * + * During P2P connection disable roam on STA interface + * + * Return: p2p disable roam - in case of success else false + */ +static inline +bool ucfg_p2p_is_roam_config_disabled(struct wlan_objmgr_psoc *psoc) +{ + return cfg_p2p_is_roam_config_disabled(psoc); +} #endif /* _WLAN_P2P_UCFG_API_H_ */ diff --git a/components/p2p/dispatcher/src/wlan_p2p_cfg.c b/components/p2p/dispatcher/src/wlan_p2p_cfg.c index f0cfa76710c0..bc946f4c2f8d 100644 --- a/components/p2p/dispatcher/src/wlan_p2p_cfg.c +++ b/components/p2p/dispatcher/src/wlan_p2p_cfg.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -86,3 +86,15 @@ cfg_p2p_get_device_addr_admin(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +bool cfg_p2p_is_roam_config_disabled(struct wlan_objmgr_psoc *psoc) +{ + struct p2p_soc_priv_obj *p2p_soc_obj; + + p2p_soc_obj = wlan_psoc_get_p2p_object(psoc); + if (!p2p_soc_obj) { + p2p_err("p2p psoc null"); + return false; + } + + return p2p_soc_obj->param.p2p_disable_roam; +} diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 169f2f3b66cd..78c93563b317 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -1759,6 +1759,20 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, /* indicate 'disconnect' status to wpa_supplicant... */ hdd_send_association_event(dev, roam_info); + + /* + * Due to audio share glitch with P2P clients due + * to roam scan on concurrent interface, disable + * roaming if "p2p_disable_roam" ini is enabled. + * Re-enable roaming again once the p2p client + * gets disconnected. + */ + if (ucfg_p2p_is_roam_config_disabled(hdd_ctx->psoc) && + adapter->device_mode == QDF_P2P_CLIENT_MODE) { + hdd_debug("P2P client disconnected, enable roam"); + wlan_hdd_enable_roaming(adapter, RSO_CONNECT_START); + } + /* indicate disconnected event to nl80211 */ if (roam_status != eCSR_ROAM_IBSS_LEAVE) { /* @@ -2938,11 +2952,23 @@ hdd_association_completion_handler(struct hdd_adapter *adapter, } /* - * Enable roaming on other STA iface except this one. - * Firmware dosent support connection on one STA iface while - * roaming on other STA iface + * Due to audio share glitch with P2P clients due + * to roam scan on concurrent interface, disable + * roaming if "p2p_disable_roam" ini is enabled. + * Donot re-enable roaming again on other STA interface + * if p2p client connection is active on any vdev. */ - wlan_hdd_enable_roaming(adapter, RSO_CONNECT_START); + if (ucfg_p2p_is_roam_config_disabled(hdd_ctx->psoc) && + adapter->device_mode == QDF_P2P_CLIENT_MODE) { + hdd_debug("p2p cli active keep roam disabled"); + } else { + /* + * Enable roaming on other STA iface except this one. + * Firmware dosent support connection on one STA iface + * while roaming on other STA iface + */ + wlan_hdd_enable_roaming(adapter, RSO_CONNECT_START); + } /* Save the connection info from CSR... */ hdd_conn_save_connect_info(adapter, roam_info, diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 59533b63020d..9d53dcf3c3be 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -5723,8 +5723,20 @@ error: wlansap_reset_sap_config_add_ie(config, eUPDATE_IE_ALL); free: - /* Enable Roaming after start bss in case of failure/success */ - wlan_hdd_enable_roaming(adapter, RSO_START_BSS); + /* + * Due to audio share glitch with P2P GO due + * to roam scan on concurrent interface, disable + * roaming if "p2p_disable_roam" ini is enabled. + * Donot re-enable roaming again on other STA interface + * if p2p GO is active on any vdev. + */ + if (ucfg_p2p_is_roam_config_disabled(hdd_ctx->psoc) && + adapter->device_mode == QDF_P2P_GO_MODE) { + hdd_debug("p2p go mode, keep roam disabled"); + } else { + /* Enable Roaming after start bss in case of failure/success */ + wlan_hdd_enable_roaming(adapter, RSO_START_BSS); + } qdf_mem_free(sme_config); return ret; } @@ -5879,6 +5891,19 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode, false); + /* + * Due to audio share glitch with P2P GO due + * to roam scan on concurrent interface, disable + * roaming if "p2p_disable_roam" ini is enabled. + * Re-enable roaming on other STA interface if p2p GO + * is active on any vdev. + */ + if (ucfg_p2p_is_roam_config_disabled(hdd_ctx->psoc) && + adapter->device_mode == QDF_P2P_GO_MODE) { + hdd_debug("p2p go disconnected enable roam"); + wlan_hdd_enable_roaming(adapter, RSO_START_BSS); + } + if (adapter->session.ap.beacon) { qdf_mem_free(adapter->session.ap.beacon); adapter->session.ap.beacon = NULL; diff --git a/core/mac/src/pe/lim/lim_process_action_frame.c b/core/mac/src/pe/lim/lim_process_action_frame.c index 7cc212bb3800..d88cdf9c3f25 100644 --- a/core/mac/src/pe/lim/lim_process_action_frame.c +++ b/core/mac/src/pe/lim/lim_process_action_frame.c @@ -51,6 +51,7 @@ #include #include #include "dot11f.h" +#include "wlan_p2p_cfg_api.h" static last_processed_msg rrm_link_action_frm; @@ -1911,6 +1912,15 @@ void lim_process_action_frame(struct mac_context *mac_ctx, case WNM_BSS_TM_QUERY: case WNM_BSS_TM_REQUEST: case WNM_BSS_TM_RESPONSE: + if (cfg_p2p_is_roam_config_disabled(mac_ctx->psoc) && + session && LIM_IS_STA_ROLE(session) && + (policy_mgr_mode_specific_connection_count( + mac_ctx->psoc, PM_P2P_CLIENT_MODE, NULL) || + policy_mgr_mode_specific_connection_count( + mac_ctx->psoc, PM_P2P_GO_MODE, NULL))) { + pe_debug("p2p session active drop BTM frame"); + break; + } case WNM_NOTIF_REQUEST: case WNM_NOTIF_RESPONSE: rssi = WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info); 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 263390935fca..ba57f775045f 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/core/mac/src/pe/lim/lim_process_message_queue.c @@ -62,6 +62,7 @@ #include "wma.h" #include "wma_internal.h" #include "../../core/src/vdev_mgr_ops.h" +#include "wlan_p2p_cfg_api.h" void lim_log_session_states(struct mac_context *mac); static void lim_process_normal_hdd_msg(struct mac_context *mac_ctx, @@ -1089,12 +1090,15 @@ lim_check_mgmt_registered_frames(struct mac_context *mac_ctx, uint8_t *buff_desc uint16_t frm_len; uint8_t type, sub_type; bool match = false; + tpSirMacActionFrameHdr action_hdr; + uint8_t actionID, category; QDF_STATUS qdf_status; hdr = WMA_GET_RX_MAC_HEADER(buff_desc); fc = hdr->fc; frm_type = (fc.type << 2) | (fc.subType << 4); body = WMA_GET_RX_MPDU_DATA(buff_desc); + action_hdr = (tpSirMacActionFrameHdr)body; frm_len = WMA_GET_RX_PAYLOAD_LEN(buff_desc); qdf_mutex_acquire(&mac_ctx->lim.lim_frame_register_lock); @@ -1138,10 +1142,36 @@ lim_check_mgmt_registered_frames(struct mac_context *mac_ctx, uint8_t *buff_desc mgmt_frame = next_frm; next_frm = NULL; } - if (match) { - QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, - FL("rcvd frame match with registered frame params")); + pe_debug("rcvd frame match with registered frame params"); + + /* + * Drop BTM frame received on STA interface if concurrent + * P2P connection is active and p2p_disable_roam ini is + * enabled. This will help to avoid scan triggered by + * userspace after processing the BTM frame from AP so the + * audio glitches are not seen in P2P connection. + */ + if (cfg_p2p_is_roam_config_disabled(mac_ctx->psoc) && + session_entry && LIM_IS_STA_ROLE(session_entry) && + (policy_mgr_mode_specific_connection_count(mac_ctx->psoc, + PM_P2P_CLIENT_MODE, NULL) || + policy_mgr_mode_specific_connection_count(mac_ctx->psoc, + PM_P2P_GO_MODE, NULL))) { + if (frm_len >= sizeof(*action_hdr) && action_hdr && + fc.type == SIR_MAC_MGMT_FRAME && + fc.subType == SIR_MAC_MGMT_ACTION) { + actionID = action_hdr->actionID; + category = action_hdr->category; + if (category == ACTION_CATEGORY_WNM && + (actionID == WNM_BSS_TM_QUERY || + actionID == WNM_BSS_TM_REQUEST || + actionID == WNM_BSS_TM_RESPONSE)) { + pe_debug("p2p session active drop BTM frame"); + return match; + } + } + } /* Indicate this to SME */ lim_send_sme_mgmt_frame_ind(mac_ctx, hdr->fc.subType, (uint8_t *) hdr, diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 10b43aa25ae4..e9a3a9f6638a 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -65,6 +65,7 @@ #include "wlan_blm_api.h" #include "wlan_policy_mgr_i.h" #include "wlan_scan_utils_api.h" +#include "wlan_p2p_cfg_api.h" #include #include "wlan_pkt_capture_ucfg_api.h" @@ -19521,6 +19522,16 @@ csr_roam_offload_scan(struct mac_context *mac_ctx, uint8_t session_id, } } + if (cfg_p2p_is_roam_config_disabled(mac_ctx->psoc) && + (command == ROAM_SCAN_OFFLOAD_START || + command == ROAM_SCAN_OFFLOAD_UPDATE_CFG) && + (policy_mgr_mode_specific_connection_count(mac_ctx->psoc, + PM_P2P_CLIENT_MODE, NULL) || + policy_mgr_mode_specific_connection_count(mac_ctx->psoc, + PM_P2P_GO_MODE, NULL))) { + sme_info("roaming not supported for active p2p connection"); + return QDF_STATUS_E_FAILURE; + } /* * The Dynamic Config Items Update may happen even if the state is in * INIT. It is important to ensure that the command is passed down to