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