/* * Copyright (c) 2022-2023 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 * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef _DP_UMAC_RESET_H_ #define _DP_UMAC_RESET_H_ #include struct dp_soc; #define DP_UMAC_RESET_NOTIFY_DONE 20 /** * enum umac_reset_action - Actions supported by the UMAC reset * @UMAC_RESET_ACTION_NONE: No action * @UMAC_RESET_ACTION_DO_TRIGGER_RECOVERY: Trigger umac recovery * @UMAC_RESET_ACTION_DO_PRE_RESET: DO_PRE_RESET * @UMAC_RESET_ACTION_DO_POST_RESET_START: DO_POST_RESET_START * @UMAC_RESET_ACTION_DO_POST_RESET_COMPLETE: DO_POST_RESET_COMPLETE * @UMAC_RESET_ACTION_ABORT: Abort the current Umac reset session * @UMAC_RESET_ACTION_MAX: Maximum actions */ enum umac_reset_action { UMAC_RESET_ACTION_NONE, UMAC_RESET_ACTION_DO_TRIGGER_RECOVERY, UMAC_RESET_ACTION_DO_PRE_RESET, UMAC_RESET_ACTION_DO_POST_RESET_START, UMAC_RESET_ACTION_DO_POST_RESET_COMPLETE, UMAC_RESET_ACTION_ABORT, UMAC_RESET_ACTION_MAX }; #ifdef DP_UMAC_HW_RESET_SUPPORT #define dp_umac_reset_alert(params...) \ QDF_TRACE_FATAL(QDF_MODULE_ID_DP_UMAC_RESET, params) #define dp_umac_reset_err(params...) \ QDF_TRACE_ERROR(QDF_MODULE_ID_DP_UMAC_RESET, params) #define dp_umac_reset_warn(params...) \ QDF_TRACE_WARN(QDF_MODULE_ID_DP_UMAC_RESET, params) #define dp_umac_reset_notice(params...) \ QDF_TRACE_INFO(QDF_MODULE_ID_DP_UMAC_RESET, params) #define dp_umac_reset_info(params...) \ QDF_TRACE_INFO(QDF_MODULE_ID_DP_UMAC_RESET, params) #define dp_umac_reset_debug(params...) \ QDF_TRACE_DEBUG(QDF_MODULE_ID_DP_UMAC_RESET, params) #define DP_UMAC_RESET_PRINT_STATS(fmt, args ...)\ QDF_TRACE(QDF_MODULE_ID_DP_UMAC_RESET, QDF_TRACE_LEVEL_FATAL,\ fmt, ## args) #define DP_UMAC_RESET_SHMEM_ALIGN 8 #define DP_UMAC_RESET_SHMEM_MAGIC_NUM (0xDEADBEEF) /** * enum umac_reset_state - States required by the UMAC reset state machine * @UMAC_RESET_STATE_WAIT_FOR_TRIGGER: Waiting for trigger event * @UMAC_RESET_STATE_DO_TRIGGER_RECEIVED: Received the DO_TRIGGER event * @UMAC_RESET_STATE_HOST_TRIGGER_DONE: Host completed handling Trigger event * @UMAC_RESET_STATE_WAIT_FOR_DO_PRE_RESET: Waiting for the DO_PRE_RESET event * @UMAC_RESET_STATE_DO_PRE_RESET_RECEIVED: Received the DO_PRE_RESET event * @UMAC_RESET_STATE_HOST_PRE_RESET_DONE: Host has completed handling the * PRE_RESET event * @UMAC_RESET_STATE_WAIT_FOR_DO_POST_RESET_START: Waiting for the * DO_POST_RESET_START event * @UMAC_RESET_STATE_DO_POST_RESET_START_RECEIVED: Received the * DO_POST_RESET_START event * @UMAC_RESET_STATE_HOST_POST_RESET_START_DONE: Host has completed handling the * POST_RESET_START event * @UMAC_RESET_STATE_WAIT_FOR_DO_POST_RESET_COMPLETE: Waiting for the * DO_POST_RESET_COMPLETE event * @UMAC_RESET_STATE_DO_POST_RESET_COMPLETE_RECEIVED: Received the * DO_POST_RESET_COMPLETE event * @UMAC_RESET_STATE_HOST_POST_RESET_COMPLETE_DONE: Host has completed handling * the DO_POST_RESET_COMPLETE event */ enum umac_reset_state { UMAC_RESET_STATE_WAIT_FOR_TRIGGER = 0, UMAC_RESET_STATE_DO_TRIGGER_RECEIVED, UMAC_RESET_STATE_HOST_TRIGGER_DONE, UMAC_RESET_STATE_WAIT_FOR_DO_PRE_RESET, UMAC_RESET_STATE_DO_PRE_RESET_RECEIVED, UMAC_RESET_STATE_HOST_PRE_RESET_DONE, UMAC_RESET_STATE_WAIT_FOR_DO_POST_RESET_START, UMAC_RESET_STATE_DO_POST_RESET_START_RECEIVED, UMAC_RESET_STATE_HOST_POST_RESET_START_DONE, UMAC_RESET_STATE_WAIT_FOR_DO_POST_RESET_COMPLETE, UMAC_RESET_STATE_DO_POST_RESET_COMPLETE_RECEIVED, UMAC_RESET_STATE_HOST_POST_RESET_COMPLETE_DONE, }; /** * enum umac_reset_rx_event - Rx events deduced by the UMAC reset * @UMAC_RESET_RX_EVENT_NONE: No event * @UMAC_RESET_RX_EVENT_DO_TRIGGER_RECOVERY: ACTION_DO_TRIGGER_RECOVERY event * @UMAC_RESET_RX_EVENT_DO_TRIGGER_TR_SYNC: ACTION_DO_TRIGGER_RECOVERY event * @UMAC_RESET_RX_EVENT_DO_PRE_RESET: DO_PRE_RESET event * @UMAC_RESET_RX_EVENT_DO_POST_RESET_START: DO_POST_RESET_START event * @UMAC_RESET_RX_EVENT_DO_POST_RESET_COMPELTE: DO_POST_RESET_COMPELTE event * @UMAC_RESET_RX_EVENT_ERROR: Error while processing the Rx event */ enum umac_reset_rx_event { UMAC_RESET_RX_EVENT_NONE = 0x0, UMAC_RESET_RX_EVENT_DO_TRIGGER_RECOVERY, UMAC_RESET_RX_EVENT_DO_TRIGGER_TR_SYNC, UMAC_RESET_RX_EVENT_DO_PRE_RESET, UMAC_RESET_RX_EVENT_DO_POST_RESET_START, UMAC_RESET_RX_EVENT_DO_POST_RESET_COMPELTE, UMAC_RESET_RX_EVENT_ERROR = 0xFFFFFFFF, }; /** * enum umac_reset_tx_cmd: UMAC reset Tx command * @UMAC_RESET_TX_CMD_TRIGGER_DONE: TRIGGER_DONE * @UMAC_RESET_TX_CMD_PRE_RESET_DONE: PRE_RESET_DONE * @UMAC_RESET_TX_CMD_POST_RESET_START_DONE: POST_RESET_START_DONE * @UMAC_RESET_TX_CMD_POST_RESET_COMPLETE_DONE: POST_RESET_COMPLETE_DONE */ enum umac_reset_tx_cmd { UMAC_RESET_TX_CMD_TRIGGER_DONE, UMAC_RESET_TX_CMD_PRE_RESET_DONE, UMAC_RESET_TX_CMD_POST_RESET_START_DONE, UMAC_RESET_TX_CMD_POST_RESET_COMPLETE_DONE, }; /** * struct umac_reset_rx_actions - callbacks for handling UMAC reset actions * @cb: Array of pointers where each pointer contains callback for each UMAC * reset action for that index */ struct umac_reset_rx_actions { QDF_STATUS (*cb[UMAC_RESET_ACTION_MAX])(struct dp_soc *soc); }; /** * struct reset_ts - timestamps of for umac reset events for debug * @trigger_start: Umac reset trigger event timestamp * @trigger_done: Umac reset trigger done timestamp * @pre_reset_start: Umac prereset start event timestamp * @pre_reset_done: Umac prereset done timestamp * @post_reset_start: Umac postreset start event timestamp * @post_reset_done: Umac postreset done timestamp * @post_reset_complete_start: Umac postreset complete event timestamp * @post_reset_complete_done: Umac postreset complete done timestamp */ struct reset_ts { uint64_t trigger_start; uint64_t trigger_done; uint64_t pre_reset_start; uint64_t pre_reset_done; uint64_t post_reset_start; uint64_t post_reset_done; uint64_t post_reset_complete_start; uint64_t post_reset_complete_done; }; #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) /** * struct dp_soc_mlo_umac_reset_ctx - UMAC reset context at mlo group level * @partner_map: Partner soc map * @request_map: Partner soc request map * @response_map: Partner soc response map * @grp_ctx_lock: lock for accessing group level umac reset context * @umac_reset_in_progress: Flag to indicate if umac reset is in progress * @is_target_recovery: Flag to indicate if this is for target recovery * @tx_desc_pool_cleaned: Global tx_desc pool clean up has been done * @initiator_chip_id: chip id of the Umac reset initiator * @umac_reset_count: Number of times Umac reset happened on this MLO group */ struct dp_soc_mlo_umac_reset_ctx { unsigned long partner_map; unsigned long request_map; unsigned long response_map; qdf_spinlock_t grp_ctx_lock; uint8_t umac_reset_in_progress:1, is_target_recovery:1, tx_desc_pool_cleaned:1; uint8_t initiator_chip_id; uint32_t umac_reset_count; }; #endif /** * struct dp_soc_umac_reset_ctx - UMAC reset context at soc level * @shmem_paddr_unaligned: Physical address of the shared memory (unaligned) * @shmem_vaddr_unaligned: Virtual address of the shared memory (unaligned) * @shmem_paddr_aligned: Physical address of the shared memory (aligned) * @shmem_vaddr_aligned: Virtual address of the shared memory (aligned) * @shmem_size: Size of the shared memory * @intr_offset: Offset of the UMAC reset interrupt w.r.t DP base interrupt * @current_state: current state of the UMAC reset state machine * @shmem_exp_magic_num: Expected magic number in the shared memory * @rx_actions: callbacks for handling UMAC reset actions * @pending_action: Action pending to be executed. * @intr_ctx_bkp: DP Interrupts ring masks backup * @nbuf_list: skb list for delayed free * @skel_enable: Enable skeleton code for umac reset * @ts: timestamps debug */ struct dp_soc_umac_reset_ctx { qdf_dma_addr_t shmem_paddr_unaligned; void *shmem_vaddr_unaligned; qdf_dma_addr_t shmem_paddr_aligned; htt_umac_hang_recovery_msg_shmem_t *shmem_vaddr_aligned; size_t shmem_size; int intr_offset; enum umac_reset_state current_state; uint32_t shmem_exp_magic_num; struct umac_reset_rx_actions rx_actions; enum umac_reset_action pending_action; struct dp_intr_bkp *intr_ctx_bkp; qdf_nbuf_t nbuf_list; bool skel_enable; struct reset_ts ts; }; /** * dp_soc_umac_reset_init() - Initialize UMAC reset context * @txrx_soc: DP soc object * * Return: QDF status of operation */ QDF_STATUS dp_soc_umac_reset_init(struct cdp_soc_t *txrx_soc); /** * dp_soc_umac_reset_deinit() - De-initialize UMAC reset context * @txrx_soc: DP soc object * * Return: QDF status of operation */ QDF_STATUS dp_soc_umac_reset_deinit(struct cdp_soc_t *txrx_soc); /** * dp_umac_reset_interrupt_attach() - Register handlers for UMAC reset interrupt * @soc: DP soc object * * Return: QDF status of operation */ QDF_STATUS dp_umac_reset_interrupt_attach(struct dp_soc *soc); /** * dp_umac_reset_interrupt_detach() - Unregister UMAC reset interrupt handlers * @soc: DP soc object * * Return: QDF status of operation */ QDF_STATUS dp_umac_reset_interrupt_detach(struct dp_soc *soc); /** * dp_umac_reset_register_rx_action_callback() - Register a callback for a given * UMAC reset action * @soc: DP soc object * @handler: callback handler to be registered * @action: UMAC reset action for which @handler needs to be registered * * Return: QDF status of operation */ QDF_STATUS dp_umac_reset_register_rx_action_callback( struct dp_soc *soc, QDF_STATUS (*handler)(struct dp_soc *soc), enum umac_reset_action action); /** * dp_umac_reset_notify_action_completion() - Notify that a given action has * been completed * @soc: DP soc object * @action: UMAC reset action that got completed * * Return: QDF status of operation */ QDF_STATUS dp_umac_reset_notify_action_completion( struct dp_soc *soc, enum umac_reset_action action); /** * dp_umac_reset_post_tx_cmd_via_shmem() - Post Tx command using shared memory * @soc: DP soc object * @ctxt: Tx command to be posted * @chip_id: Chip id of the mlo soc * * Return: None */ void dp_umac_reset_post_tx_cmd_via_shmem(struct dp_soc *soc, void *ctxt, int chip_id); /** * dp_check_umac_reset_in_progress() - Check if Umac reset is in progress * @soc: dp soc handle * * Return: true if Umac reset is in progress or false otherwise */ bool dp_check_umac_reset_in_progress(struct dp_soc *soc); /** * dp_umac_reset_stats_print - API to print UMAC reset stats * @soc: dp soc handle * * Return: QDF_STATUS */ QDF_STATUS dp_umac_reset_stats_print(struct dp_soc *soc); /** * dp_umac_reset_validate_n_update_state_machine_on_rx() - Validate the state * machine for a given rx event and update the state machine * @umac_reset_ctx: UMAC reset context * @rx_event: Rx event * @current_exp_state: Expected state * @next_state: The state to which the state machine needs to be updated * * Return: QDF_STATUS of operation */ QDF_STATUS dp_umac_reset_validate_n_update_state_machine_on_rx( struct dp_soc_umac_reset_ctx *umac_reset_ctx, enum umac_reset_rx_event rx_event, enum umac_reset_state current_exp_state, enum umac_reset_state next_state); #else static inline bool dp_check_umac_reset_in_progress(struct dp_soc *soc) { return false; } static inline QDF_STATUS dp_soc_umac_reset_init(struct cdp_soc_t *txrx_soc) { return QDF_STATUS_SUCCESS; } static inline QDF_STATUS dp_soc_umac_reset_deinit(struct cdp_soc_t *txrx_soc) { return QDF_STATUS_SUCCESS; } static inline QDF_STATUS dp_umac_reset_register_rx_action_callback( struct dp_soc *soc, QDF_STATUS (*handler)(struct dp_soc *soc), enum umac_reset_action action) { return QDF_STATUS_SUCCESS; } static inline QDF_STATUS dp_umac_reset_notify_action_completion( struct dp_soc *soc, enum umac_reset_action action) { return QDF_STATUS_SUCCESS; } static inline QDF_STATUS dp_umac_reset_stats_print(struct dp_soc *soc) { return QDF_STATUS_SUCCESS; } #endif /* DP_UMAC_HW_RESET_SUPPORT */ #endif /* _DP_UMAC_RESET_H_ */