qcacld-3.0: Add support for disabling an NDI concurrency
NAN Datapath implementation allows more than one concurrent NDI's to be active at the same time. But this isn't supported if there is a higher priority incoming connection such as STA. Add modules that check for unsupported NDI concurrency and initiates termination of all NDP's on it. Add modules that check and disable unsupported NDI concurrency. Change-Id: I6ad9afbfc41beda1d1c8f31bf58a8ea70027f5ca CRs-Fixed: 2407215
This commit is contained in:

committed by
nshrivas

parent
147dfb4c96
commit
9ea5f13a28
@@ -29,6 +29,7 @@
|
||||
#include "wlan_objmgr_pdev_obj.h"
|
||||
#include "wlan_objmgr_vdev_obj.h"
|
||||
#include "wlan_osif_request_manager.h"
|
||||
#include "wlan_policy_mgr_api.h"
|
||||
|
||||
struct wlan_objmgr_psoc;
|
||||
struct wlan_objmgr_vdev;
|
||||
@@ -275,6 +276,9 @@ static QDF_STATUS ucfg_nan_sch_msg_flush_cb(struct scheduler_msg *msg)
|
||||
case NDP_END_REQ:
|
||||
vdev = ((struct nan_datapath_end_req *)msg->bodyptr)->vdev;
|
||||
break;
|
||||
case NDP_END_ALL:
|
||||
vdev = ((struct nan_datapath_end_all_ndps *)msg->bodyptr)->vdev;
|
||||
break;
|
||||
default:
|
||||
nan_err("Invalid NAN msg type during sch flush");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
@@ -310,6 +314,9 @@ QDF_STATUS ucfg_nan_req_processor(struct wlan_objmgr_vdev *vdev,
|
||||
case NDP_END_REQ:
|
||||
len = sizeof(struct nan_datapath_end_req);
|
||||
break;
|
||||
case NDP_END_ALL:
|
||||
len = sizeof(struct nan_datapath_end_all_ndps);
|
||||
break;
|
||||
default:
|
||||
nan_err("in correct message req type: %d", req_type);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
@@ -463,6 +470,19 @@ bool ucfg_is_nan_dbs_supported(struct wlan_objmgr_psoc *psoc)
|
||||
return (psoc_priv->nan_caps.nan_dbs_supported == 1);
|
||||
}
|
||||
|
||||
bool ucfg_is_ndi_dbs_supported(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
struct nan_psoc_priv_obj *psoc_priv;
|
||||
|
||||
psoc_priv = nan_get_psoc_priv_obj(psoc);
|
||||
if (!psoc_priv) {
|
||||
nan_err("nan psoc priv object is NULL");
|
||||
return false;
|
||||
}
|
||||
|
||||
return (psoc_priv->nan_caps.ndi_dbs_supported == 1);
|
||||
}
|
||||
|
||||
bool ucfg_is_nan_enable_allowed(struct wlan_objmgr_psoc *psoc, uint8_t nan_chan)
|
||||
{
|
||||
return nan_is_enable_allowed(psoc, nan_chan);
|
||||
@@ -619,16 +639,15 @@ void ucfg_nan_disable_concurrency(struct wlan_objmgr_psoc *psoc)
|
||||
nan_req.psoc = psoc;
|
||||
nan_req.disable_2g_discovery = true;
|
||||
nan_req.disable_5g_discovery = true;
|
||||
psoc_priv->disable_context = osif_request_cookie(request);
|
||||
|
||||
status = ucfg_nan_discovery_req(&nan_req, NAN_DISABLE_REQ);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
nan_err("Unable to disable NAN Discovery");
|
||||
osif_request_put(request);
|
||||
return;
|
||||
}
|
||||
|
||||
psoc_priv->disable_context = osif_request_cookie(request);
|
||||
psoc_priv->is_explicit_disable = true;
|
||||
nan_debug("Successfully sent NAN Disable request");
|
||||
|
||||
@@ -641,3 +660,113 @@ void ucfg_nan_disable_concurrency(struct wlan_objmgr_psoc *psoc)
|
||||
psoc_priv->is_explicit_disable = false;
|
||||
osif_request_put(request);
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
ucfg_nan_check_and_disable_unsupported_ndi(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
enum nan_datapath_state curr_ndi_state;
|
||||
struct nan_datapath_host_event *event;
|
||||
uint32_t ndi_count, first_ndi_vdev_id;
|
||||
struct nan_vdev_priv_obj *ndi_vdev_priv;
|
||||
struct nan_datapath_end_all_ndps req = {0};
|
||||
struct wlan_objmgr_vdev *ndi_vdev;
|
||||
struct osif_request *request;
|
||||
QDF_STATUS status;
|
||||
int err;
|
||||
static const struct osif_request_params params = {
|
||||
.priv_size = sizeof(struct nan_datapath_host_event),
|
||||
.timeout_ms = 1000,
|
||||
};
|
||||
|
||||
if (!psoc) {
|
||||
nan_err("psoc object is NULL, no action will be taken");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
if (!ucfg_is_ndi_dbs_supported(psoc))
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
ndi_count = policy_mgr_mode_specific_connection_count(psoc, PM_NDI_MODE,
|
||||
NULL);
|
||||
if (ndi_count < 2) {
|
||||
nan_debug("No more than one NDI is active, nothing to do...");
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* At least 2 NDI active concurrencies exist. Disable all NDP's on the
|
||||
* first NDI to support an incoming connection.
|
||||
*/
|
||||
first_ndi_vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_NDI_MODE);
|
||||
ndi_vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, first_ndi_vdev_id,
|
||||
WLAN_NAN_ID);
|
||||
if (!ndi_vdev) {
|
||||
nan_err("Cannot obtain NDI vdev object!");
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
ndi_vdev_priv = nan_get_vdev_priv_obj(ndi_vdev);
|
||||
if (!ndi_vdev_priv) {
|
||||
nan_err("ndi vdev priv object is NULL");
|
||||
wlan_objmgr_vdev_release_ref(ndi_vdev, WLAN_NAN_ID);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
|
||||
qdf_spin_lock_bh(&ndi_vdev_priv->lock);
|
||||
curr_ndi_state = ndi_vdev_priv->state;
|
||||
/* Nothing to do if NDI is in DELETING or DATA_END state */
|
||||
if (curr_ndi_state == NAN_DATA_NDI_DELETING_STATE ||
|
||||
curr_ndi_state == NAN_DATA_END_STATE) {
|
||||
qdf_spin_unlock_bh(&ndi_vdev_priv->lock);
|
||||
wlan_objmgr_vdev_release_ref(ndi_vdev, WLAN_NAN_ID);
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
ndi_vdev_priv->state = NAN_DATA_END_STATE;
|
||||
qdf_spin_unlock_bh(&ndi_vdev_priv->lock);
|
||||
|
||||
request = osif_request_alloc(¶ms);
|
||||
if (!request) {
|
||||
nan_err("Request allocation failure");
|
||||
status = QDF_STATUS_E_NOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
ndi_vdev_priv->disable_context = osif_request_cookie(request);
|
||||
|
||||
req.vdev = ndi_vdev;
|
||||
status = ucfg_nan_req_processor(NULL, &req, NDP_END_ALL);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
nan_err("Unable to disable NDP's on NDI");
|
||||
wlan_objmgr_vdev_release_ref(ndi_vdev, WLAN_NAN_ID);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
nan_debug("Disabling all NDP's on NDI vdev id - %d", first_ndi_vdev_id);
|
||||
|
||||
err = osif_request_wait_for_response(request);
|
||||
if (err) {
|
||||
nan_err("Disabling NDP's timed out waiting for confirmation");
|
||||
status = QDF_STATUS_E_TIMEOUT;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
event = osif_request_priv(request);
|
||||
if (!event->ndp_termination_in_progress) {
|
||||
nan_err("Failed to terminate NDP's on NDI");
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
/* Restore original NDI state in case of failure */
|
||||
qdf_spin_lock_bh(&ndi_vdev_priv->lock);
|
||||
if (QDF_IS_STATUS_SUCCESS(status))
|
||||
ndi_vdev_priv->state = NAN_DATA_DISCONNECTED_STATE;
|
||||
else
|
||||
ndi_vdev_priv->state = curr_ndi_state;
|
||||
qdf_spin_unlock_bh(&ndi_vdev_priv->lock);
|
||||
|
||||
if (request)
|
||||
osif_request_put(request);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
Reference in New Issue
Block a user