qcacld-3.0: Reject Vdev trans when driver in unloading/recovering

Previously vdev trans will be rejected if psoc in trans. but
it causes issue when __hdd_psoc_idle_shutdown is in psoc trans,
if ifconfig comes here, the ifconfig will fail.

Add checking if psoc trans in driver recovering and unloading,
if yes, it will be safe to reject vdev trans, otherwise, we should
let vdev trans waiting for psoc trans.

At the same time, we also need to make sure driver state has been
set before psoc trans when unloading.

Change-Id: Ic47eebef76b8eadc90780b74f75d4ebef73b822d
CRs-Fixed: 2601435
This commit is contained in:
Jingxiang Ge
2020-01-16 20:36:53 +08:00
zatwierdzone przez nshrivas
rodzic fcb21d02f8
commit 19042f697f
4 zmienionych plików z 52 dodań i 16 usunięć

Wyświetl plik

@@ -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
@@ -23,6 +23,7 @@
#include "qdf_types.h"
#include "wlan_dsc.h"
#include "wlan_dsc_test.h"
#include "cds_api.h"
#define dsc_driver_trans_start(driver) dsc_driver_trans_start(driver, __func__)
#define dsc_psoc_trans_start(psoc) dsc_psoc_trans_start(psoc, __func__)
@@ -263,10 +264,30 @@ static uint32_t dsc_test_psoc_trans_blocks(void)
action_expect(psoc, op, QDF_STATUS_E_AGAIN, errors);
/* ... children vdev trans/ops to fail */
dsc_for_each_psoc_vdev(psoc, vdev) {
action_expect(vdev, trans, QDF_STATUS_E_AGAIN, errors);
action_expect(vdev, op, QDF_STATUS_E_AGAIN, errors);
}
/* ... while driver unload in progress vdev op and trans should be
* rejected with EINVAL
*/
cds_set_unload_in_progress(true);
dsc_for_each_psoc_vdev(psoc, vdev) {
action_expect(vdev, trans, QDF_STATUS_E_INVAL, errors);
action_expect(vdev, op, QDF_STATUS_E_INVAL, errors);
}
cds_set_unload_in_progress(false);
/* ... while SSR recovery in progress vdev op and trans should be
* rejected with EINVAL
*/
cds_set_recovery_in_progress(true);
dsc_for_each_psoc_vdev(psoc, vdev) {
action_expect(vdev, trans, QDF_STATUS_E_INVAL, errors);
action_expect(vdev, op, QDF_STATUS_E_INVAL, errors);
}
cds_set_recovery_in_progress(false);
/* a sibling psoc in transition should succeed and cause ... */
psoc = nth_psoc(driver, 2);
@@ -282,8 +303,8 @@ static uint32_t dsc_test_psoc_trans_blocks(void)
/* ... children vdev trans/ops to fail */
dsc_for_each_psoc_vdev(psoc, vdev) {
action_expect(vdev, trans, QDF_STATUS_E_INVAL, errors);
action_expect(vdev, op, QDF_STATUS_E_INVAL, errors);
action_expect(vdev, trans, QDF_STATUS_E_AGAIN, errors);
action_expect(vdev, op, QDF_STATUS_E_AGAIN, errors);
}
/* teardown */