162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2022 Google Corporation 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef __COREDUMP_H 762306a36Sopenharmony_ci#define __COREDUMP_H 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#define DEVCOREDUMP_TIMEOUT msecs_to_jiffies(10000) /* 10 sec */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_citypedef void (*coredump_t)(struct hci_dev *hdev); 1262306a36Sopenharmony_citypedef void (*dmp_hdr_t)(struct hci_dev *hdev, struct sk_buff *skb); 1362306a36Sopenharmony_citypedef void (*notify_change_t)(struct hci_dev *hdev, int state); 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/* struct hci_devcoredump - Devcoredump state 1662306a36Sopenharmony_ci * 1762306a36Sopenharmony_ci * @supported: Indicates if FW dump collection is supported by driver 1862306a36Sopenharmony_ci * @state: Current state of dump collection 1962306a36Sopenharmony_ci * @timeout: Indicates a timeout for collecting the devcoredump 2062306a36Sopenharmony_ci * 2162306a36Sopenharmony_ci * @alloc_size: Total size of the dump 2262306a36Sopenharmony_ci * @head: Start of the dump 2362306a36Sopenharmony_ci * @tail: Pointer to current end of dump 2462306a36Sopenharmony_ci * @end: head + alloc_size for easy comparisons 2562306a36Sopenharmony_ci * 2662306a36Sopenharmony_ci * @dump_q: Dump queue for state machine to process 2762306a36Sopenharmony_ci * @dump_rx: Devcoredump state machine work 2862306a36Sopenharmony_ci * @dump_timeout: Devcoredump timeout work 2962306a36Sopenharmony_ci * 3062306a36Sopenharmony_ci * @coredump: Called from the driver's .coredump() function. 3162306a36Sopenharmony_ci * @dmp_hdr: Create a dump header to identify controller/fw/driver info 3262306a36Sopenharmony_ci * @notify_change: Notify driver when devcoredump state has changed 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_cistruct hci_devcoredump { 3562306a36Sopenharmony_ci bool supported; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci enum devcoredump_state { 3862306a36Sopenharmony_ci HCI_DEVCOREDUMP_IDLE, 3962306a36Sopenharmony_ci HCI_DEVCOREDUMP_ACTIVE, 4062306a36Sopenharmony_ci HCI_DEVCOREDUMP_DONE, 4162306a36Sopenharmony_ci HCI_DEVCOREDUMP_ABORT, 4262306a36Sopenharmony_ci HCI_DEVCOREDUMP_TIMEOUT, 4362306a36Sopenharmony_ci } state; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci unsigned long timeout; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci size_t alloc_size; 4862306a36Sopenharmony_ci char *head; 4962306a36Sopenharmony_ci char *tail; 5062306a36Sopenharmony_ci char *end; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci struct sk_buff_head dump_q; 5362306a36Sopenharmony_ci struct work_struct dump_rx; 5462306a36Sopenharmony_ci struct delayed_work dump_timeout; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci coredump_t coredump; 5762306a36Sopenharmony_ci dmp_hdr_t dmp_hdr; 5862306a36Sopenharmony_ci notify_change_t notify_change; 5962306a36Sopenharmony_ci}; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci#ifdef CONFIG_DEV_COREDUMP 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_civoid hci_devcd_reset(struct hci_dev *hdev); 6462306a36Sopenharmony_civoid hci_devcd_rx(struct work_struct *work); 6562306a36Sopenharmony_civoid hci_devcd_timeout(struct work_struct *work); 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ciint hci_devcd_register(struct hci_dev *hdev, coredump_t coredump, 6862306a36Sopenharmony_ci dmp_hdr_t dmp_hdr, notify_change_t notify_change); 6962306a36Sopenharmony_ciint hci_devcd_init(struct hci_dev *hdev, u32 dump_size); 7062306a36Sopenharmony_ciint hci_devcd_append(struct hci_dev *hdev, struct sk_buff *skb); 7162306a36Sopenharmony_ciint hci_devcd_append_pattern(struct hci_dev *hdev, u8 pattern, u32 len); 7262306a36Sopenharmony_ciint hci_devcd_complete(struct hci_dev *hdev); 7362306a36Sopenharmony_ciint hci_devcd_abort(struct hci_dev *hdev); 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci#else 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistatic inline void hci_devcd_reset(struct hci_dev *hdev) {} 7862306a36Sopenharmony_cistatic inline void hci_devcd_rx(struct work_struct *work) {} 7962306a36Sopenharmony_cistatic inline void hci_devcd_timeout(struct work_struct *work) {} 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_cistatic inline int hci_devcd_register(struct hci_dev *hdev, coredump_t coredump, 8262306a36Sopenharmony_ci dmp_hdr_t dmp_hdr, 8362306a36Sopenharmony_ci notify_change_t notify_change) 8462306a36Sopenharmony_ci{ 8562306a36Sopenharmony_ci return -EOPNOTSUPP; 8662306a36Sopenharmony_ci} 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_cistatic inline int hci_devcd_init(struct hci_dev *hdev, u32 dump_size) 8962306a36Sopenharmony_ci{ 9062306a36Sopenharmony_ci return -EOPNOTSUPP; 9162306a36Sopenharmony_ci} 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_cistatic inline int hci_devcd_append(struct hci_dev *hdev, struct sk_buff *skb) 9462306a36Sopenharmony_ci{ 9562306a36Sopenharmony_ci return -EOPNOTSUPP; 9662306a36Sopenharmony_ci} 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_cistatic inline int hci_devcd_append_pattern(struct hci_dev *hdev, 9962306a36Sopenharmony_ci u8 pattern, u32 len) 10062306a36Sopenharmony_ci{ 10162306a36Sopenharmony_ci return -EOPNOTSUPP; 10262306a36Sopenharmony_ci} 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_cistatic inline int hci_devcd_complete(struct hci_dev *hdev) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci return -EOPNOTSUPP; 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistatic inline int hci_devcd_abort(struct hci_dev *hdev) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci return -EOPNOTSUPP; 11262306a36Sopenharmony_ci} 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci#endif /* CONFIG_DEV_COREDUMP */ 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci#endif /* __COREDUMP_H */ 117