diff options
author | Clément Viel <clement.viel@qorvo.com> | 2022-07-21 14:16:41 +0200 |
---|---|---|
committer | Victor Liu <victorliu@google.com> | 2022-08-11 16:55:40 +0000 |
commit | 0e80d4cc9397ae7f1e7e8c762b566807ca1f2fe7 (patch) | |
tree | f756d48caa4b83c0ef88dd823c9f83cb9b584dcf | |
parent | fae0c29c52897a18b7198c47c6f8268a26687fa8 (diff) | |
download | uwb-android-gs-raviole-5.10-t-qpr1-beta-2.tar.gz |
mac: only allow non recoverable errors to stall the MAC.android-t-qpr1-beta-2_r0.5android-t-qpr1-beta-2_r0.4android-gs-raviole-5.10-t-qpr1-beta-2android-gs-bluejay-5.10-t-qpr1-beta-2
Bug: 241137690
Change-Id: I0f5c250016205d8f505bb653810459e49688afb2
Signed-off-by: Clément Viel <clement.viel@qorvo.com>
-rw-r--r-- | kernel/drivers/net/ieee802154/dw3000_core.c | 9 | ||||
l--------- | kernel/net/mcps802154/mcps802154_fproc.h | 1 | ||||
-rw-r--r-- | mac/fira_session_fsm_active.c | 2 | ||||
-rw-r--r-- | mac/fproc.c | 29 | ||||
-rw-r--r-- | mac/fproc_multi.c | 50 | ||||
-rw-r--r-- | mac/fproc_rx.c | 30 | ||||
-rw-r--r-- | mac/fproc_tx.c | 25 | ||||
-rw-r--r-- | mac/mcps802154_fproc.h | 32 |
8 files changed, 128 insertions, 50 deletions
diff --git a/kernel/drivers/net/ieee802154/dw3000_core.c b/kernel/drivers/net/ieee802154/dw3000_core.c index 788c4f4..4b384b9 100644 --- a/kernel/drivers/net/ieee802154/dw3000_core.c +++ b/kernel/drivers/net/ieee802154/dw3000_core.c @@ -2316,7 +2316,7 @@ int dw3000_check_operational_state(struct dw3000 *dw, int delay_dtu, dw->deep_sleep_state.next_operational_state); if (dw->current_operational_state == DW3000_OP_STATE_OFF) - return -EIO; + return -ENODEV; /* In deep sleep or wake up in progress, we can store parameters only if no other operation queued. */ if ((dw->current_operational_state < DW3000_OP_STATE_IDLE_PLL) && @@ -2581,8 +2581,11 @@ int dw3000_do_rx_enable(struct dw3000 *dw, /* For delayed RX, where delay_dtu != 0, enter/leave deep sleep */ rc = dw3000_check_operational_state(dw, delay_dtu, can_sync); if (rc) { - /* Handle error cases first */ - if (rc < 0) + /* + * Handle error cases first : + * - Do not fail if we are in deep sleep/wakeup state + */ + if (rc < 0 && rc != -EIO) return rc; /* Save parameters to activate RX delayed when wakeup later */ diff --git a/kernel/net/mcps802154/mcps802154_fproc.h b/kernel/net/mcps802154/mcps802154_fproc.h new file mode 120000 index 0000000..add11c0 --- /dev/null +++ b/kernel/net/mcps802154/mcps802154_fproc.h @@ -0,0 +1 @@ +../../../mac/mcps802154_fproc.h
\ No newline at end of file diff --git a/mac/fira_session_fsm_active.c b/mac/fira_session_fsm_active.c index 2ba014c..feff6c9 100644 --- a/mac/fira_session_fsm_active.c +++ b/mac/fira_session_fsm_active.c @@ -780,7 +780,7 @@ static void fira_session_fsm_active_access_done(struct fira_local *local, /* Update local. */ local->current_session = NULL; - if ((error) && (session->last_error != -ETIME)) { + if (error) { /* * FIXME: * Why corrupt all status, the last slot_index is not diff --git a/mac/fproc.c b/mac/fproc.c index a9a5372..4e1274c 100644 --- a/mac/fproc.c +++ b/mac/fproc.c @@ -25,6 +25,25 @@ #include "mcps802154_i.h" #include "llhw-ops.h" +bool mcps802154_fproc_is_non_recoverable_error(struct mcps802154_access *access) +{ + bool rc = false; + if (access->error < 0) { + switch (access->error) { + case -ETIME: + case -EIO: + case -EAGAIN: + rc = false; + break; + default: + pr_err("mcps: error %d is not recoverable", access->error); + rc = true; + break; + } + } + return rc; +} + void mcps802154_fproc_init(struct mcps802154_local *local) { local->fproc.state = &mcps802154_fproc_stopped; @@ -94,11 +113,13 @@ void mcps802154_fproc_access(struct mcps802154_local *local, } if (access->error) { - mcps802154_fproc_access_done(local, true); - if (access->error == -ETIME) - mcps802154_fproc_access_now(local); - else + if (mcps802154_fproc_is_non_recoverable_error(access)) { + mcps802154_fproc_access_done(local, true); mcps802154_fproc_broken_handle(local); + } else { + mcps802154_fproc_access_done(local, false); + mcps802154_fproc_access_now(local); + } } } diff --git a/mac/fproc_multi.c b/mac/fproc_multi.c index af3edc3..2c7b2fa 100644 --- a/mac/fproc_multi.c +++ b/mac/fproc_multi.c @@ -23,6 +23,7 @@ #include <linux/errno.h> +#include "mcps802154_fproc.h" #include "mcps802154_i.h" #include "llhw-ops.h" @@ -114,9 +115,11 @@ static void mcps802154_fproc_multi_next(struct mcps802154_local *local, access->ops->access_extend(access); access->error = mcps802154_fproc_multi_check_frames(local, access, 0); if (access->error) { - mcps802154_fproc_access_done(local, true); - mcps802154_fproc_broken_handle(local); - return; + if (mcps802154_fproc_is_non_recoverable_error(access)) { + mcps802154_fproc_access_done(local, true); + mcps802154_fproc_broken_handle(local); + return; + } } } if (frame_idx < access->n_frames) { @@ -124,18 +127,22 @@ static void mcps802154_fproc_multi_next(struct mcps802154_local *local, access->error = mcps802154_fproc_multi_handle_frame(local, access, frame_idx); if (access->error) { - mcps802154_fproc_access_done(local, true); - if (access->error == -ETIME) - mcps802154_fproc_access_now(local); - else + if (mcps802154_fproc_is_non_recoverable_error(access)) { + mcps802154_fproc_access_done(local, true); mcps802154_fproc_broken_handle(local); + } else { + mcps802154_fproc_access_done(local, false); + mcps802154_fproc_access_now(local); + } } } else { access->error = mcps802154_fproc_multi_restore(local, access); mcps802154_fproc_access_done(local, !!access->error); if (access->error) { - mcps802154_fproc_broken_handle(local); - return; + if (mcps802154_fproc_is_non_recoverable_error(access)) { + mcps802154_fproc_broken_handle(local); + return; + } } /* Next access. */ if (access->duration_dtu) { @@ -164,13 +171,14 @@ static void mcps802154_fproc_multi_rx_rx_frame(struct mcps802154_local *local) access->ops->rx_frame(access, frame_idx, skb, &info, MCPS802154_RX_ERROR_NONE); - if (access->error && access->error != -EBUSY) { - mcps802154_fproc_access_done(local, true); - mcps802154_fproc_broken_handle(local); - } else { - /* Next. */ - mcps802154_fproc_multi_next(local, access, frame_idx); + if (access->error) { + if (mcps802154_fproc_is_non_recoverable_error(access)) { + mcps802154_fproc_access_done(local, true); + mcps802154_fproc_broken_handle(local); + return; + } } + mcps802154_fproc_multi_next(local, access, frame_idx); } static void mcps802154_fproc_multi_rx_rx_timeout(struct mcps802154_local *local) @@ -220,12 +228,14 @@ mcps802154_fproc_multi_rx_schedule_change(struct mcps802154_local *local) access->ops->rx_frame(access, frame_idx, NULL, NULL, MCPS802154_RX_ERROR_TIMEOUT); if (access->error) { - mcps802154_fproc_access_done(local, access->error); - mcps802154_fproc_broken_handle(local); - } else { - /* Next. */ - mcps802154_fproc_multi_next(local, access, frame_idx); + if (mcps802154_fproc_is_non_recoverable_error(access)) { + mcps802154_fproc_access_done(local, true); + mcps802154_fproc_broken_handle(local); + return; + } } + /* Next. */ + mcps802154_fproc_multi_next(local, access, frame_idx); } } diff --git a/mac/fproc_rx.c b/mac/fproc_rx.c index d92fb87..b7cc171 100644 --- a/mac/fproc_rx.c +++ b/mac/fproc_rx.c @@ -22,6 +22,7 @@ */ #include <linux/errno.h> +#include "mcps802154_fproc.h" #include "mcps802154_i.h" #include "llhw-ops.h" @@ -65,13 +66,16 @@ static void mcps802154_fproc_rx_rx_frame(struct mcps802154_local *local) return; } } - mcps802154_fproc_access_done(local, !!access->error); - - if (access->error && access->error != -EBUSY) - mcps802154_fproc_broken_handle(local); - else - /* Next access. */ - mcps802154_fproc_access_now(local); + if (access->error) { + if (mcps802154_fproc_is_non_recoverable_error(access)) { + mcps802154_fproc_access_done(local, true); + mcps802154_fproc_broken_handle(local); + return; + } + } + /* Next access. */ + mcps802154_fproc_access_done(local, false); + mcps802154_fproc_access_now(local); } static void mcps802154_fproc_rx_rx_error(struct mcps802154_local *local, @@ -91,11 +95,15 @@ static void mcps802154_fproc_rx_schedule_change(struct mcps802154_local *local) /* Wait for RX result. */ return; - mcps802154_fproc_access_done(local, !!access->error); - if (access->error) - mcps802154_fproc_broken_handle(local); - else + if (access->error) { + if (mcps802154_fproc_is_non_recoverable_error(access)) { + mcps802154_fproc_access_done(local, true); + mcps802154_fproc_broken_handle(local); + return; + } + } /* Next access. */ + mcps802154_fproc_access_done(local, false); mcps802154_fproc_access_now(local); } diff --git a/mac/fproc_tx.c b/mac/fproc_tx.c index eba18f6..f96a431 100644 --- a/mac/fproc_tx.c +++ b/mac/fproc_tx.c @@ -24,6 +24,7 @@ #include <linux/ieee802154.h> #include <linux/netdevice.h> +#include "mcps802154_fproc.h" #include "mcps802154_i.h" #include "llhw-ops.h" @@ -55,36 +56,38 @@ static const struct mcps802154_fproc_state mcps802154_fproc_tx = { static void mcps802154_fproc_tx_wack_rx_frame(struct mcps802154_local *local) { struct mcps802154_access *access = local->fproc.access; - int r; /* Read frame. */ struct sk_buff *skb = NULL; struct mcps802154_rx_frame_info info = { .flags = MCPS802154_RX_FRAME_INFO_LQI, }; - r = llhw_rx_get_frame(local, &skb, &info); - if (!r) { + access->error = llhw_rx_get_frame(local, &skb, &info); + if (!access->error) { /* Is it an ack frame? With same seq number? */ if (IEEE802154_FC_TYPE(skb->data[0]) == - IEEE802154_FC_TYPE_ACK && - skb->data[IEEE802154_FC_LEN] == - local->fproc.tx_skb->data[IEEE802154_FC_LEN]) { + IEEE802154_FC_TYPE_ACK && + skb->data[IEEE802154_FC_LEN] == + local->fproc.tx_skb->data[IEEE802154_FC_LEN]) { /* Ack frame. */ access->ops->tx_return( - access, 0, local->fproc.tx_skb, - MCPS802154_ACCESS_TX_RETURN_REASON_CONSUMED); + access, 0, local->fproc.tx_skb, + MCPS802154_ACCESS_TX_RETURN_REASON_CONSUMED); } else { /* Not an ack or read failure or a bad sequence number. */ access->ops->tx_return( - access, 0, local->fproc.tx_skb, - MCPS802154_ACCESS_TX_RETURN_REASON_FAILURE); + access, 0, local->fproc.tx_skb, + MCPS802154_ACCESS_TX_RETURN_REASON_FAILURE); } dev_kfree_skb_any(skb); local->fproc.tx_skb = NULL; mcps802154_fproc_access_done(local, false); mcps802154_fproc_access_now(local); - } else { + } else if (access->error && mcps802154_fproc_is_non_recoverable_error(access)) { mcps802154_fproc_broken_handle(local); + } else { + mcps802154_fproc_access_done(local, false); + mcps802154_fproc_access_now(local); } } diff --git a/mac/mcps802154_fproc.h b/mac/mcps802154_fproc.h new file mode 100644 index 0000000..fc6e871 --- /dev/null +++ b/mac/mcps802154_fproc.h @@ -0,0 +1,32 @@ +/* + * This file is part of the UWB stack for linux. + * + * Copyright (c) 2020-2021 Qorvo US, Inc. + * + * This software is provided under the GNU General Public License, version 2 + * (GPLv2), as well as under a Qorvo commercial license. + * + * You may choose to use this software under the terms of the GPLv2 License, + * version 2 ("GPLv2"), as published by the Free Software Foundation. + * You should have received a copy of the GPLv2 along with this program. If + * not, see <http://www.gnu.org/licenses/>. + * + * This program is distributed under the GPLv2 in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GPLv2 for more + * details. + * + * If you cannot meet the requirements of the GPLv2, you may not use this + * software for any purpose without first obtaining a commercial license from + * Qorvo. Please contact Qorvo to inquire about licensing terms. + */ + +#ifndef __MCPS802154_FPROC_H__ +#define __MCPS802154_FPROC_H__ + +#include <net/mcps802154_schedule.h> + +bool mcps802154_fproc_is_non_recoverable_error(struct mcps802154_access *access); + +#endif /* MCPS802154_FPROC_H */ + |