diff --git a/components/dsc/inc/wlan_dsc.h b/components/dsc/inc/wlan_dsc.h index 49dd2ddfe2..6bacfc37a9 100644 --- a/components/dsc/inc/wlan_dsc.h +++ b/components/dsc/inc/wlan_dsc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 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 @@ -37,12 +37,12 @@ * and vdev. These levels are arranged into a tree, with a single driver at * the root, zero or more psocs per driver, and zero or more vdevs per psoc. * - * High level transitions block transitions and operations at the same level - * down, and low level transitions block transitions at the same level up. So a - * driver transition effectively prevents any new activity in the system, while - * a vdev transition prevents transtitions on the same vdev, its parent psoc, - * and the driver. This also means that sibling nodes can transition at the same - * time, e.g. one vdev going up at the same time another is going down. + * High level transitions block transitions and operations at the same level, + * down-tree, and up-tree. So a driver transition effectively prevents any new + * activity in the system, while a vdev transition prevents transtitions and + * operations on the same vdev, its parent psoc, and the driver. This also means + * that sibling nodes can transition at the same time, e.g. one vdev going up at + * the same time another is going down. */ #ifndef __WLAN_DSC_H diff --git a/components/dsc/src/wlan_dsc_driver.c b/components/dsc/src/wlan_dsc_driver.c index 192bf8e9a4..2933087544 100644 --- a/components/dsc/src/wlan_dsc_driver.c +++ b/components/dsc/src/wlan_dsc_driver.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 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 @@ -123,10 +123,7 @@ static bool __dsc_driver_trans_active_down_tree(struct dsc_driver *driver) return false; } -static bool __dsc_driver_can_op(struct dsc_driver *driver) -{ - return !__dsc_trans_active_or_queued(&driver->trans); -} +#define __dsc_driver_can_op(driver) __dsc_driver_can_trans(driver) static bool __dsc_driver_can_trans(struct dsc_driver *driver) { diff --git a/components/dsc/src/wlan_dsc_psoc.c b/components/dsc/src/wlan_dsc_psoc.c index 8c208eb461..f0cdc3a6ca 100644 --- a/components/dsc/src/wlan_dsc_psoc.c +++ b/components/dsc/src/wlan_dsc_psoc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 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 @@ -124,11 +124,7 @@ static bool __dsc_psoc_trans_active_down_tree(struct dsc_psoc *psoc) return false; } -static bool __dsc_psoc_can_op(struct dsc_psoc *psoc) -{ - return !__dsc_trans_active_or_queued(&psoc->driver->trans) && - !__dsc_trans_active_or_queued(&psoc->trans); -} +#define __dsc_psoc_can_op(psoc) __dsc_psoc_can_trans(psoc) static bool __dsc_psoc_can_trans(struct dsc_psoc *psoc) { diff --git a/components/dsc/src/wlan_dsc_vdev.c b/components/dsc/src/wlan_dsc_vdev.c index c0f19e482e..b14905674a 100644 --- a/components/dsc/src/wlan_dsc_vdev.c +++ b/components/dsc/src/wlan_dsc_vdev.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2019 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 @@ -106,18 +106,15 @@ void dsc_vdev_destroy(struct dsc_vdev **out_vdev) dsc_exit(); } -static bool __dsc_vdev_can_op(struct dsc_vdev *vdev) +#define __dsc_vdev_can_op(vdev) __dsc_vdev_can_trans(vdev) + +static bool __dsc_vdev_can_trans(struct dsc_vdev *vdev) { return !__dsc_trans_active_or_queued(&vdev->psoc->driver->trans) && !__dsc_trans_active_or_queued(&vdev->psoc->trans) && !__dsc_trans_active_or_queued(&vdev->trans); } -static bool __dsc_vdev_can_trans(struct dsc_vdev *vdev) -{ - return __dsc_vdev_can_op(vdev); -} - static QDF_STATUS __dsc_vdev_trans_start_nolock(struct dsc_vdev *vdev, const char *desc) { diff --git a/components/dsc/test/wlan_dsc_test.c b/components/dsc/test/wlan_dsc_test.c index dd9f286039..3eb54b87a4 100644 --- a/components/dsc/test/wlan_dsc_test.c +++ b/components/dsc/test/wlan_dsc_test.c @@ -199,17 +199,21 @@ static uint32_t dsc_test_driver_trans_blocks(void) goto exit; } - action_expect(driver, trans, QDF_STATUS_SUCCESS, errors); - /* test */ + /* a driver in transition should cause ... */ + action_expect(driver, trans, QDF_STATUS_SUCCESS, errors); + + /* ... the same driver trans/ops to fail */ action_expect(driver, trans, QDF_STATUS_E_AGAIN, errors); action_expect(driver, op, QDF_STATUS_E_AGAIN, errors); + /* ... children psoc trans/ops to fail */ dsc_for_each_driver_psoc(driver, psoc) { action_expect(psoc, trans, QDF_STATUS_E_AGAIN, errors); action_expect(psoc, op, QDF_STATUS_E_AGAIN, errors); + /* ... grandchildren 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); @@ -248,31 +252,37 @@ static uint32_t dsc_test_psoc_trans_blocks(void) /* test */ + /* a psoc in transition should cause ... */ psoc = nth_psoc(driver, 1); action_expect(psoc, trans, QDF_STATUS_SUCCESS, errors); + /* ... driver trans/ops to fail */ action_expect(driver, trans, QDF_STATUS_E_AGAIN, errors); - action_expect(driver, op, QDF_STATUS_SUCCESS, errors); - dsc_driver_op_stop(driver); + action_expect(driver, op, QDF_STATUS_E_AGAIN, errors); + /* ... the same psoc trans/ops to fail */ action_expect(psoc, trans, QDF_STATUS_E_AGAIN, errors); 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); } + /* a sibling psoc in transition should succeed and cause ... */ psoc = nth_psoc(driver, 2); action_expect(psoc, trans, QDF_STATUS_SUCCESS, errors); + /* ... driver trans/ops to fail */ action_expect(driver, trans, QDF_STATUS_E_AGAIN, errors); - action_expect(driver, op, QDF_STATUS_SUCCESS, errors); - dsc_driver_op_stop(driver); + action_expect(driver, op, QDF_STATUS_E_AGAIN, errors); + /* ... the same psoc trans/ops to fail */ action_expect(psoc, trans, QDF_STATUS_E_AGAIN, errors); 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); @@ -309,22 +319,24 @@ static uint32_t dsc_test_vdev_trans_blocks(void) goto exit; } + /* test */ + + /* a vdev in transition should cause ... */ dsc_for_each_driver_psoc(driver, psoc) { dsc_for_each_psoc_vdev(psoc, vdev) action_expect(vdev, trans, QDF_STATUS_SUCCESS, errors); } - /* test */ - + /* ... driver trans/ops to fail */ action_expect(driver, trans, QDF_STATUS_E_AGAIN, errors); - action_expect(driver, op, QDF_STATUS_SUCCESS, errors); - dsc_driver_op_stop(driver); + action_expect(driver, op, QDF_STATUS_E_AGAIN, errors); + /* ... psoc trans/ops to fail */ dsc_for_each_driver_psoc(driver, psoc) { action_expect(psoc, trans, QDF_STATUS_E_AGAIN, errors); - action_expect(psoc, op, QDF_STATUS_SUCCESS, errors); - dsc_psoc_op_stop(psoc); + action_expect(psoc, op, QDF_STATUS_E_AGAIN, errors); + /* ... the same 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);