|
@@ -377,18 +377,69 @@ QDF_STATUS cm_disconnect_active(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
|
|
|
{
|
|
|
struct wlan_cm_vdev_discon_req *req;
|
|
|
struct cm_req *cm_req;
|
|
|
- struct qdf_mac_addr bssid = QDF_MAC_ADDR_ZERO_INIT;
|
|
|
- QDF_STATUS status;
|
|
|
+ QDF_STATUS status = QDF_STATUS_E_NOSUPPORT;
|
|
|
|
|
|
cm_req = cm_get_req_by_cm_id(cm_ctx, *cm_id);
|
|
|
if (!cm_req)
|
|
|
return QDF_STATUS_E_INVAL;
|
|
|
|
|
|
+ cm_ctx->active_cm_id = *cm_id;
|
|
|
+
|
|
|
+ if (wlan_vdev_mlme_get_opmode(cm_ctx->vdev) == QDF_STA_MODE)
|
|
|
+ status = mlme_cm_rso_stop_req(cm_ctx->vdev);
|
|
|
+
|
|
|
+ if (status != QDF_STATUS_E_NOSUPPORT)
|
|
|
+ return status;
|
|
|
+
|
|
|
req = qdf_mem_malloc(sizeof(*req));
|
|
|
if (!req)
|
|
|
return QDF_STATUS_E_NOMEM;
|
|
|
|
|
|
- cm_ctx->active_cm_id = *cm_id;
|
|
|
+ req->cm_id = *cm_id;
|
|
|
+ req->req.vdev_id = wlan_vdev_get_id(cm_ctx->vdev);
|
|
|
+ req->req.source = cm_req->discon_req.req.source;
|
|
|
+ req->req.reason_code = cm_req->discon_req.req.reason_code;
|
|
|
+ req->req.is_no_disassoc_disconnect =
|
|
|
+ cm_req->discon_req.req.is_no_disassoc_disconnect;
|
|
|
+
|
|
|
+ cm_disconnect_continue_after_rso_stop(cm_ctx->vdev, false,
|
|
|
+ req);
|
|
|
+ qdf_mem_free(req);
|
|
|
+
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+QDF_STATUS
|
|
|
+cm_disconnect_continue_after_rso_stop(struct wlan_objmgr_vdev *vdev,
|
|
|
+ bool is_ho_fail,
|
|
|
+ struct wlan_cm_vdev_discon_req *req)
|
|
|
+{
|
|
|
+ struct cm_req *cm_req;
|
|
|
+ QDF_STATUS status;
|
|
|
+ struct qdf_mac_addr bssid = QDF_MAC_ADDR_ZERO_INIT;
|
|
|
+ struct cnx_mgr *cm_ctx = cm_get_cm_ctx(vdev);
|
|
|
+
|
|
|
+ if (!cm_ctx)
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+
|
|
|
+ if ((CM_ID_GET_PREFIX(req->cm_id)) != DISCONNECT_REQ_PREFIX) {
|
|
|
+ mlme_err(CM_PREFIX_FMT "active req is not disconnect req",
|
|
|
+ CM_PREFIX_REF(wlan_vdev_get_id(vdev), req->cm_id));
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ cm_req = cm_get_req_by_cm_id(cm_ctx, req->cm_id);
|
|
|
+ if (!cm_req)
|
|
|
+ return QDF_STATUS_E_INVAL;
|
|
|
+
|
|
|
+ if (is_ho_fail) {
|
|
|
+ mlme_debug(CM_PREFIX_FMT "Updating source(%d) and reason code (%d) to RSO reason and source as ho fail is received in RSO stop",
|
|
|
+ CM_PREFIX_REF(req->req.vdev_id, req->cm_id),
|
|
|
+ req->req.source, req->req.reason_code);
|
|
|
+ req->req.source = CM_MLME_DISCONNECT;
|
|
|
+ req->req.reason_code = REASON_FW_TRIGGERED_ROAM_FAILURE;
|
|
|
+ }
|
|
|
+
|
|
|
wlan_vdev_get_bss_peer_mac(cm_ctx->vdev, &bssid);
|
|
|
/*
|
|
|
* for northbound req, bssid is not provided so update it from vdev
|
|
@@ -396,31 +447,25 @@ QDF_STATUS cm_disconnect_active(struct cnx_mgr *cm_ctx, wlan_cm_id *cm_id)
|
|
|
*/
|
|
|
if (qdf_is_macaddr_zero(&cm_req->discon_req.req.bssid) ||
|
|
|
qdf_is_macaddr_broadcast(&cm_req->discon_req.req.bssid))
|
|
|
- qdf_copy_macaddr(&cm_req->discon_req.req.bssid, &bssid);
|
|
|
+ qdf_copy_macaddr(&cm_req->discon_req.req.bssid,
|
|
|
+ &req->req.bssid);
|
|
|
|
|
|
qdf_copy_macaddr(&req->req.bssid, &bssid);
|
|
|
-
|
|
|
- req->cm_id = *cm_id;
|
|
|
- req->req.vdev_id = wlan_vdev_get_id(cm_ctx->vdev);
|
|
|
- req->req.source = cm_req->discon_req.req.source;
|
|
|
- req->req.reason_code = cm_req->discon_req.req.reason_code;
|
|
|
- req->req.is_no_disassoc_disconnect =
|
|
|
- cm_req->discon_req.req.is_no_disassoc_disconnect;
|
|
|
-
|
|
|
cm_update_scan_mlme_on_disconnect(cm_ctx->vdev,
|
|
|
&cm_req->discon_req);
|
|
|
|
|
|
- mlme_debug(CM_PREFIX_FMT "disconnect " QDF_MAC_ADDR_FMT " source %d reason %d",
|
|
|
+ mlme_debug(CM_PREFIX_FMT "disconnect " QDF_MAC_ADDR_FMT
|
|
|
+ " source %d reason %d is_ho_fail: %u",
|
|
|
CM_PREFIX_REF(req->req.vdev_id, req->cm_id),
|
|
|
QDF_MAC_ADDR_REF(req->req.bssid.bytes),
|
|
|
- req->req.source, req->req.reason_code);
|
|
|
+ req->req.source, req->req.reason_code, is_ho_fail);
|
|
|
+
|
|
|
status = mlme_cm_disconnect_req(cm_ctx->vdev, req);
|
|
|
if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
mlme_err(CM_PREFIX_FMT "disconnect req fail",
|
|
|
CM_PREFIX_REF(req->req.vdev_id, req->cm_id));
|
|
|
cm_send_disconnect_resp(cm_ctx, req->cm_id);
|
|
|
}
|
|
|
- qdf_mem_free(req);
|
|
|
|
|
|
return status;
|
|
|
}
|