|
4 | 4 | * Copyright 2006-2007 Jiri Benc <[email protected]>
|
5 | 5 | * Copyright 2013-2014 Intel Mobile Communications GmbH
|
6 | 6 | * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
|
7 |
| - * Copyright (C) 2018-2023 Intel Corporation |
| 7 | + * Copyright (C) 2018-2024 Intel Corporation |
8 | 8 | */
|
9 | 9 |
|
10 | 10 | #include <linux/module.h>
|
@@ -1335,9 +1335,13 @@ static int _sta_info_move_state(struct sta_info *sta,
|
1335 | 1335 | sta->sta.addr, new_state);
|
1336 | 1336 |
|
1337 | 1337 | /* notify the driver before the actual changes so it can
|
1338 |
| - * fail the transition |
| 1338 | + * fail the transition if the state is increasing. |
| 1339 | + * The driver is required not to fail when the transition |
| 1340 | + * is decreasing the state, so first, do all the preparation |
| 1341 | + * work and only then, notify the driver. |
1339 | 1342 | */
|
1340 |
| - if (test_sta_flag(sta, WLAN_STA_INSERTED)) { |
| 1343 | + if (new_state > sta->sta_state && |
| 1344 | + test_sta_flag(sta, WLAN_STA_INSERTED)) { |
1341 | 1345 | int err = drv_sta_state(sta->local, sta->sdata, sta,
|
1342 | 1346 | sta->sta_state, new_state);
|
1343 | 1347 | if (err)
|
@@ -1413,6 +1417,16 @@ static int _sta_info_move_state(struct sta_info *sta,
|
1413 | 1417 | break;
|
1414 | 1418 | }
|
1415 | 1419 |
|
| 1420 | + if (new_state < sta->sta_state && |
| 1421 | + test_sta_flag(sta, WLAN_STA_INSERTED)) { |
| 1422 | + int err = drv_sta_state(sta->local, sta->sdata, sta, |
| 1423 | + sta->sta_state, new_state); |
| 1424 | + |
| 1425 | + WARN_ONCE(err, |
| 1426 | + "Driver is not allowed to fail if the sta_state is transitioning down the list: %d\n", |
| 1427 | + err); |
| 1428 | + } |
| 1429 | + |
1416 | 1430 | sta->sta_state = new_state;
|
1417 | 1431 |
|
1418 | 1432 | return 0;
|
|
0 commit comments