qcacmn: Drop disconnect req in INIT state

In case the vdev is already disconnected, the indication to
the upper layer, would have been sent as part of previous
disconnect/connect failure.

If the upper layer is in process of connecting, sending
the disconnect indication back again may cause it to incorrectly
think it as connect failure. So sending a disconnect indication
again is not advisable.

So if a new disconnect is received in INIT state, drop the
disconnect and return failure.

Also remove osif_cm_reset_id_and_src() from osif disconnect
to avoid race between disconnect complete of old disconnect
and new disconnect request. With osif_cm_reset_id_and_src()
old disconnect might also get dropped in osif and with this
fix new disconnect will also get dropped, so make sure that
last/old disconnect indication is sent to upper layer.

Change-Id: Icf7352d8904473329edff9ec124c6197f214f88b
CRs-Fixed: 3074093
Цей коміт міститься в:
Abhishek Singh
2021-11-17 10:55:18 +05:30
зафіксовано Madan Koyyalamudi
джерело 9cba107914
коміт 3915bd37fb
3 змінених файлів з 27 додано та 25 видалено

Переглянути файл

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2012-2015,2020-2021 The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. 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 above
@@ -554,20 +555,6 @@ connect_start_fail:
return qdf_status_to_os_return(status);
}
static QDF_STATUS osif_cm_send_disconnect(struct wlan_objmgr_vdev *vdev,
uint16_t reason)
{
QDF_STATUS status;
status = osif_cm_reset_id_and_src(vdev);
if (QDF_IS_STATUS_ERROR(status))
return qdf_status_to_os_return(status);
status = mlo_disconnect(vdev, CM_OSIF_DISCONNECT, reason, NULL);
return status;
}
int osif_cm_disconnect(struct net_device *dev, struct wlan_objmgr_vdev *vdev,
uint16_t reason)
{
@@ -578,7 +565,7 @@ int osif_cm_disconnect(struct net_device *dev, struct wlan_objmgr_vdev *vdev,
dev->name, vdev_id, reason,
ucfg_cm_reason_code_to_str(reason));
status = osif_cm_send_disconnect(vdev, reason);
status = mlo_disconnect(vdev, CM_OSIF_DISCONNECT, reason, NULL);
if (QDF_IS_STATUS_ERROR(status))
osif_err("Disconnect failed with status %d", status);