From cde9070d9970eef1f7ec2360586c802a16230ad8 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 10 May 2024 07:43:50 +0000 Subject: [PATCH] rtl88x2CE_WiFi_linux driver --- kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_debug.h | 625 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 567 insertions(+), 58 deletions(-) diff --git a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_debug.h b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_debug.h index 0d0e860..ec893ae 100644 --- a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_debug.h +++ b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/dhd_debug.h @@ -1,15 +1,18 @@ -/* SPDX-License-Identifier: GPL-2.0 */ /* * DHD debugability header file * - * Copyright (C) 1999-2019, Broadcom Corporation - * + * <<Broadcom-WL-IPTag/Open:>> + * + * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation + * + * Copyright (C) 1999-2017, Broadcom Corporation + * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you * under the terms of the GNU General Public License version 2 (the "GPL"), * available at http://www.broadcom.com/licenses/GPLv2.php, with the * following added to such license: - * + * * As a special exception, the copyright holders of this software give you * permission to link this software with independent modules, and to copy and * distribute the resulting executable under terms of your choice, provided that @@ -17,22 +20,24 @@ * the license of that module. An independent module is a module which is not * derived from this software. The special exception does not apply to any * modifications of the software. - * + * * Notwithstanding the above, under no circumstances may you combine this * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: dhd_debug.h 560028 2015-05-29 10:50:33Z $ + * $Id: dhd_debug.h 701031 2017-05-23 11:19:09Z $ */ #ifndef _dhd_debug_h_ #define _dhd_debug_h_ +#include <event_log.h> +#include <bcmutils.h> +#include <dhd_dbg_ring.h> + enum { DEBUG_RING_ID_INVALID = 0, FW_VERBOSE_RING_ID, - FW_EVENT_RING_ID, DHD_EVENT_RING_ID, - NAN_EVENT_RING_ID, /* add new id here */ DEBUG_RING_ID_MAX }; @@ -46,7 +51,9 @@ DBG_WAKE_LOCK_SUPPORTED = (1 << (4)), /* WAKE LOCK of Driver */ DBG_VERBOSE_LOG_SUPPORTED = (1 << (5)), /* verbose log of FW */ DBG_HEALTH_CHECK_SUPPORTED = (1 << (6)), /* monitor the health of FW */ - DBG_NAN_EVENT_SUPPORTED = (1 << (7)), /* NAN Events */ + DBG_DRIVER_DUMP_SUPPORTED = (1 << (7)), /* dumps driver state */ + DBG_PACKET_FATE_SUPPORTED = (1 << (8)), /* tracks connection packets' fate */ + DBG_NAN_EVENT_SUPPORTED = (1 << (9)), /* NAN Events */ }; enum { @@ -56,10 +63,9 @@ DBG_RING_ENTRY_FLAGS_HAS_TIMESTAMP = (1 << (1)) }; -#define DBGRING_NAME_MAX 32 /* firmware verbose ring, ring id 1 */ #define FW_VERBOSE_RING_NAME "fw_verbose" -#define FW_VERBOSE_RING_SIZE (64 * 1024) +#define FW_VERBOSE_RING_SIZE (256 * 1024) /* firmware event ring, ring id 2 */ #define FW_EVENT_RING_NAME "fw_event" #define FW_EVENT_RING_SIZE (64 * 1024) @@ -70,10 +76,20 @@ #define NAN_EVENT_RING_NAME "nan_event" #define NAN_EVENT_RING_SIZE (64 * 1024) -#define DBG_RING_STATUS_SIZE (sizeof(dhd_dbg_ring_status_t)) +#define TLV_LOG_SIZE(tlv) ((tlv) ? (sizeof(tlv_log) + (tlv)->len) : 0) + +#define TLV_LOG_NEXT(tlv) \ + ((tlv) ? ((tlv_log *)((uint8 *)tlv + TLV_LOG_SIZE(tlv))) : 0) #define VALID_RING(id) \ - (id > DEBUG_RING_ID_INVALID && id < DEBUG_RING_ID_MAX) + ((id > DEBUG_RING_ID_INVALID) && (id < DEBUG_RING_ID_MAX)) + +#ifdef DEBUGABILITY +#define DBG_RING_ACTIVE(dhdp, ring_id) \ + ((dhdp)->dbg->dbg_rings[(ring_id)].state == RING_ACTIVE) +#else +#define DBG_RING_ACTIVE(dhdp, ring_id) 0 +#endif /* DEBUGABILITY */ enum { /* driver receive association command from kernel */ @@ -113,8 +129,7 @@ WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_STOP, /* kernel queue EAPOL for transmission in driver with EAPOL index 1-4 */ WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED, - /* - * with rate, regardless of the fact that EAPOL frame is accepted or + /* with rate, regardless of the fact that EAPOL frame is accepted or * rejected by firmware */ WIFI_EVENT_FW_EAPOL_FRAME_RECEIVED, @@ -138,7 +153,43 @@ /* firmware sends assoc/reassoc frame in */ WIFI_EVENT_ROAM_ASSOC_STARTED, /* firmware receive assoc/reassoc confirm from ap */ - WIFI_EVENT_ROAM_ASSOC_COMPLETE + WIFI_EVENT_ROAM_ASSOC_COMPLETE, + /* firmware sends stop G_SCAN */ + WIFI_EVENT_G_SCAN_STOP, + /* firmware indicates G_SCAN scan cycle started */ + WIFI_EVENT_G_SCAN_CYCLE_STARTED, + /* firmware indicates G_SCAN scan cycle completed */ + WIFI_EVENT_G_SCAN_CYCLE_COMPLETED, + /* firmware indicates G_SCAN scan start for a particular bucket */ + WIFI_EVENT_G_SCAN_BUCKET_STARTED, + /* firmware indicates G_SCAN scan completed for particular bucket */ + WIFI_EVENT_G_SCAN_BUCKET_COMPLETED, + /* Event received from firmware about G_SCAN scan results being available */ + WIFI_EVENT_G_SCAN_RESULTS_AVAILABLE, + /* Event received from firmware with G_SCAN capabilities */ + WIFI_EVENT_G_SCAN_CAPABILITIES, + /* Event received from firmware when eligible candidate is found */ + WIFI_EVENT_ROAM_CANDIDATE_FOUND, + /* Event received from firmware when roam scan configuration gets enabled or disabled */ + WIFI_EVENT_ROAM_SCAN_CONFIG, + /* firmware/driver timed out authentication */ + WIFI_EVENT_AUTH_TIMEOUT, + /* firmware/driver timed out association */ + WIFI_EVENT_ASSOC_TIMEOUT, + /* firmware/driver encountered allocation failure */ + WIFI_EVENT_MEM_ALLOC_FAILURE, + /* driver added a PNO network in firmware */ + WIFI_EVENT_DRIVER_PNO_ADD, + /* driver removed a PNO network in firmware */ + WIFI_EVENT_DRIVER_PNO_REMOVE, + /* driver received PNO networks found indication from firmware */ + WIFI_EVENT_DRIVER_PNO_NETWORK_FOUND, + /* driver triggered a scan for PNO networks */ + WIFI_EVENT_DRIVER_PNO_SCAN_REQUESTED, + /* driver received scan results of PNO networks */ + WIFI_EVENT_DRIVER_PNO_SCAN_RESULT_FOUND, + /* driver updated scan results from PNO candidates to cfg */ + WIFI_EVENT_DRIVER_PNO_SCAN_COMPLETE }; enum { @@ -158,9 +209,23 @@ /* take one or more specific 802.11 IEs parameter, IEs are in turn * indicated in TLV format as per 802.11 spec */ - WIFI_TAG_INTERFACE, /* take interface name as parameter */ - WIFI_TAG_REASON_CODE, /* take a reason code as per 802.11 as parameter */ - WIFI_TAG_RATE_MBPS, /* take a wifi rate in 0.5 mbps */ + WIFI_TAG_INTERFACE, /* take interface name as parameter */ + WIFI_TAG_REASON_CODE, /* take a reason code as per 802.11 as parameter */ + WIFI_TAG_RATE_MBPS, /* take a wifi rate in 0.5 mbps */ + WIFI_TAG_REQUEST_ID, /* take an integer as parameter */ + WIFI_TAG_BUCKET_ID, /* take an integer as parameter */ + WIFI_TAG_GSCAN_PARAMS, /* takes a wifi_scan_cmd_params struct as parameter */ + WIFI_TAG_GSCAN_CAPABILITIES, /* takes a wifi_gscan_capabilities struct as parameter */ + WIFI_TAG_SCAN_ID, /* take an integer as parameter */ + WIFI_TAG_RSSI, /* takes s16 as parameter */ + WIFI_TAG_CHANNEL, /* takes u16 as parameter */ + WIFI_TAG_LINK_ID, /* take an integer as parameter */ + WIFI_TAG_LINK_ROLE, /* take an integer as parameter */ + WIFI_TAG_LINK_STATE, /* take an integer as parameter */ + WIFI_TAG_LINK_TYPE, /* take an integer as parameter */ + WIFI_TAG_TSCO, /* take an integer as parameter */ + WIFI_TAG_RSCO, /* take an integer as parameter */ + WIFI_TAG_EAPOL_MESSAGE_TYPE /* take an integer as parameter */ }; /* NAN events */ @@ -179,7 +244,7 @@ typedef struct { uint16 tag; uint16 len; /* length of value */ - uint8 *value; + uint8 value[0]; } tlv_log; typedef struct per_packet_status_entry { @@ -221,6 +286,8 @@ uint8 *data; } per_packet_status_entry_t; +#define PACKED_STRUCT __attribute__ ((packed)) + typedef struct log_conn_event { uint16 event; tlv_log *tlvs; @@ -231,7 +298,7 @@ * as well, event_data can include a vendor proprietary part which is * understood by the developer only. */ -} log_conn_event_t; +} PACKED_STRUCT log_conn_event_t; /* * Ring buffer name for power events ring. note that power event are extremely frequents @@ -267,64 +334,481 @@ DBG_RING_ENTRY_NAN_EVENT_TYPE }; -typedef struct dhd_dbg_ring_entry { - uint16 len; /* payload length excluding the header */ - uint8 flags; - uint8 type; /* Per ring specific */ - uint64 timestamp; /* present if has_timestamp bit is set. */ -} dhd_dbg_ring_entry_t; - -#define DBG_RING_ENTRY_SIZE (sizeof(dhd_dbg_ring_entry_t)) -#define ENTRY_LENGTH(hdr) (hdr->len + DBG_RING_ENTRY_SIZE) -typedef struct dhd_dbg_ring_status { - uint8 name[DBGRING_NAME_MAX]; - uint32 flags; - int ring_id; /* unique integer representing the ring */ - /* total memory size allocated for the buffer */ - uint32 ring_buffer_byte_size; - uint32 verbose_level; - /* number of bytes that was written to the buffer by driver */ - uint32 written_bytes; - /* number of bytes that was read from the buffer by user land */ - uint32 read_bytes; - /* number of records that was read from the buffer by user land */ - uint32 written_records; -} dhd_dbg_ring_status_t; - struct log_level_table { int log_level; uint16 tag; char *desc; }; -typedef void (*dbg_pullreq_t)(void *os_priv, const int ring_id); - -typedef void (*dbg_urgent_noti_t) (dhd_pub_t *dhdp, const void *data, const uint32 len); - -#define DBG_EVENT_LOG(dhd, connect_state) \ -{ \ +#ifdef OEM_ANDROID +/* + * Assuming that the Ring lock is mutex, bailing out if the + * callers are from atomic context. On a long term, one has to + * schedule a job to execute in sleepable context so that + * contents are pushed to the ring. + */ +#define DBG_EVENT_LOG(dhdp, connect_state) \ +{ \ do { \ - uint16 state = connect_state; \ - dhd_os_push_push_ring_data(dhd, DHD_EVENT_RING_ID, &state, sizeof(state)); \ - } while (0); \ + uint16 state = connect_state; \ + if (CAN_SLEEP() && DBG_RING_ACTIVE(dhdp, DHD_EVENT_RING_ID)) \ + dhd_os_push_push_ring_data(dhdp, DHD_EVENT_RING_ID, \ + &state, sizeof(state)); \ + } while (0); \ } +#else +#define DBG_EVENT_LOG(dhd, connect_state) +#endif /* !OEM_ANDROID */ + +#define MD5_PREFIX_LEN 4 +#define MAX_FATE_LOG_LEN 32 +#define MAX_FRAME_LEN_ETHERNET 1518 +#define MAX_FRAME_LEN_80211_MGMT 2352 /* 802.11-2012 Fig. 8-34 */ + +typedef enum { + /* Sent over air and ACKed. */ + TX_PKT_FATE_ACKED, + + /* Sent over air but not ACKed. (Normal for broadcast/multicast.) */ + TX_PKT_FATE_SENT, + + /* Queued within firmware, but not yet sent over air. */ + TX_PKT_FATE_FW_QUEUED, + + /* + * Dropped by firmware as invalid. E.g. bad source address, + * bad checksum, or invalid for current state. + */ + TX_PKT_FATE_FW_DROP_INVALID, + + /* Dropped by firmware due to lifetime expiration. */ + TX_PKT_FATE_FW_DROP_EXPTIME, + + /* + * Dropped by firmware for any other reason. Includes + * frames that were sent by driver to firmware, but + * unaccounted for by firmware. + */ + TX_PKT_FATE_FW_DROP_OTHER, + + /* Queued within driver, not yet sent to firmware. */ + TX_PKT_FATE_DRV_QUEUED, + + /* + * Dropped by driver as invalid. E.g. bad source address, + * or invalid for current state. + */ + TX_PKT_FATE_DRV_DROP_INVALID, + + /* Dropped by driver due to lack of buffer space. */ + TX_PKT_FATE_DRV_DROP_NOBUFS, + + /* Dropped by driver for any other reason. */ + TX_PKT_FATE_DRV_DROP_OTHER, + + /* Packet free by firmware. */ + TX_PKT_FATE_FW_PKT_FREE, + + } wifi_tx_packet_fate; + +typedef enum { + /* Valid and delivered to network stack (e.g., netif_rx()). */ + RX_PKT_FATE_SUCCESS, + + /* Queued within firmware, but not yet sent to driver. */ + RX_PKT_FATE_FW_QUEUED, + + /* Dropped by firmware due to host-programmable filters. */ + RX_PKT_FATE_FW_DROP_FILTER, + + /* + * Dropped by firmware as invalid. E.g. bad checksum, + * decrypt failed, or invalid for current state. + */ + RX_PKT_FATE_FW_DROP_INVALID, + + /* Dropped by firmware due to lack of buffer space. */ + RX_PKT_FATE_FW_DROP_NOBUFS, + + /* Dropped by firmware for any other reason. */ + RX_PKT_FATE_FW_DROP_OTHER, + + /* Queued within driver, not yet delivered to network stack. */ + RX_PKT_FATE_DRV_QUEUED, + + /* Dropped by driver due to filter rules. */ + RX_PKT_FATE_DRV_DROP_FILTER, + + /* Dropped by driver as invalid. E.g. not permitted in current state. */ + RX_PKT_FATE_DRV_DROP_INVALID, + + /* Dropped by driver due to lack of buffer space. */ + RX_PKT_FATE_DRV_DROP_NOBUFS, + + /* Dropped by driver for any other reason. */ + RX_PKT_FATE_DRV_DROP_OTHER, + + } wifi_rx_packet_fate; + +typedef enum { + FRAME_TYPE_UNKNOWN, + FRAME_TYPE_ETHERNET_II, + FRAME_TYPE_80211_MGMT, + } frame_type; + +typedef struct wifi_frame_info { + /* + * The type of MAC-layer frame that this frame_info holds. + * - For data frames, use FRAME_TYPE_ETHERNET_II. + * - For management frames, use FRAME_TYPE_80211_MGMT. + * - If the type of the frame is unknown, use FRAME_TYPE_UNKNOWN. + */ + frame_type payload_type; + + /* + * The number of bytes included in |frame_content|. If the frame + * contents are missing (e.g. RX frame dropped in firmware), + * |frame_len| should be set to 0. + */ + size_t frame_len; + + /* + * Host clock when this frame was received by the driver (either + * outbound from the host network stack, or inbound from the + * firmware). + * - The timestamp should be taken from a clock which includes time + * the host spent suspended (e.g. ktime_get_boottime()). + * - If no host timestamp is available (e.g. RX frame was dropped in + * firmware), this field should be set to 0. + */ + uint32 driver_timestamp_usec; + + /* + * Firmware clock when this frame was received by the firmware + * (either outbound from the host, or inbound from a remote + * station). + * - The timestamp should be taken from a clock which includes time + * firmware spent suspended (if applicable). + * - If no firmware timestamp is available (e.g. TX frame was + * dropped by driver), this field should be set to 0. + * - Consumers of |frame_info| should _not_ assume any + * synchronization between driver and firmware clocks. + */ + uint32 firmware_timestamp_usec; + + /* + * Actual frame content. + * - Should be provided for TX frames originated by the host. + * - Should be provided for RX frames received by the driver. + * - Optionally provided for TX frames originated by firmware. (At + * discretion of HAL implementation.) + * - Optionally provided for RX frames dropped in firmware. (At + * discretion of HAL implementation.) + * - If frame content is not provided, |frame_len| should be set + * to 0. + */ + union { + char ethernet_ii[MAX_FRAME_LEN_ETHERNET]; + char ieee_80211_mgmt[MAX_FRAME_LEN_80211_MGMT]; + } frame_content; +} wifi_frame_info_t; + +typedef struct wifi_tx_report { + /* + * Prefix of MD5 hash of |frame_inf.frame_content|. If frame + * content is not provided, prefix of MD5 hash over the same data + * that would be in frame_content, if frame content were provided. + */ + char md5_prefix[MD5_PREFIX_LEN]; + wifi_tx_packet_fate fate; + wifi_frame_info_t frame_inf; +} wifi_tx_report_t; + +typedef struct wifi_rx_report { + /* + * Prefix of MD5 hash of |frame_inf.frame_content|. If frame + * content is not provided, prefix of MD5 hash over the same data + * that would be in frame_content, if frame content were provided. + */ + char md5_prefix[MD5_PREFIX_LEN]; + wifi_rx_packet_fate fate; + wifi_frame_info_t frame_inf; +} wifi_rx_report_t; + +typedef struct compat_wifi_frame_info { + frame_type payload_type; + + uint32 frame_len; + + uint32 driver_timestamp_usec; + + uint32 firmware_timestamp_usec; + + union { + char ethernet_ii[MAX_FRAME_LEN_ETHERNET]; + char ieee_80211_mgmt[MAX_FRAME_LEN_80211_MGMT]; + } frame_content; +} compat_wifi_frame_info_t; + +typedef struct compat_wifi_tx_report { + char md5_prefix[MD5_PREFIX_LEN]; + wifi_tx_packet_fate fate; + compat_wifi_frame_info_t frame_inf; +} compat_wifi_tx_report_t; + +typedef struct compat_wifi_rx_report { + char md5_prefix[MD5_PREFIX_LEN]; + wifi_rx_packet_fate fate; + compat_wifi_frame_info_t frame_inf; +} compat_wifi_rx_report_t; + +/* + * Packet logging - internal data + */ + +typedef enum dhd_dbg_pkt_mon_state { + PKT_MON_INVALID = 0, + PKT_MON_ATTACHED, + PKT_MON_STARTING, + PKT_MON_STARTED, + PKT_MON_STOPPING, + PKT_MON_STOPPED, + PKT_MON_DETACHED, + } dhd_dbg_pkt_mon_state_t; + +typedef struct dhd_dbg_pkt_info { + frame_type payload_type; + size_t pkt_len; + uint32 driver_ts; + uint32 firmware_ts; + uint32 pkt_hash; + void *pkt; +} dhd_dbg_pkt_info_t; + +typedef struct compat_dhd_dbg_pkt_info { + frame_type payload_type; + uint32 pkt_len; + uint32 driver_ts; + uint32 firmware_ts; + uint32 pkt_hash; + void *pkt; +} compat_dhd_dbg_pkt_info_t; + +typedef struct dhd_dbg_tx_info +{ + wifi_tx_packet_fate fate; + dhd_dbg_pkt_info_t info; +} dhd_dbg_tx_info_t; + +typedef struct dhd_dbg_rx_info +{ + wifi_rx_packet_fate fate; + dhd_dbg_pkt_info_t info; +} dhd_dbg_rx_info_t; + +typedef struct dhd_dbg_tx_report +{ + dhd_dbg_tx_info_t *tx_pkts; + uint16 pkt_pos; + uint16 status_pos; +} dhd_dbg_tx_report_t; + +typedef struct dhd_dbg_rx_report +{ + dhd_dbg_rx_info_t *rx_pkts; + uint16 pkt_pos; +} dhd_dbg_rx_report_t; + +typedef void (*dbg_pullreq_t)(void *os_priv, const int ring_id); +typedef void (*dbg_urgent_noti_t) (dhd_pub_t *dhdp, const void *data, const uint32 len); +typedef int (*dbg_mon_tx_pkts_t) (dhd_pub_t *dhdp, void *pkt, uint32 pktid); +typedef int (*dbg_mon_tx_status_t) (dhd_pub_t *dhdp, void *pkt, + uint32 pktid, uint16 status); +typedef int (*dbg_mon_rx_pkts_t) (dhd_pub_t *dhdp, void *pkt); + +typedef struct dhd_dbg_pkt_mon +{ + dhd_dbg_tx_report_t *tx_report; + dhd_dbg_rx_report_t *rx_report; + dhd_dbg_pkt_mon_state_t tx_pkt_state; + dhd_dbg_pkt_mon_state_t tx_status_state; + dhd_dbg_pkt_mon_state_t rx_pkt_state; + + /* call backs */ + dbg_mon_tx_pkts_t tx_pkt_mon; + dbg_mon_tx_status_t tx_status_mon; + dbg_mon_rx_pkts_t rx_pkt_mon; +} dhd_dbg_pkt_mon_t; + +typedef struct dhd_dbg { + dhd_dbg_ring_t dbg_rings[DEBUG_RING_ID_MAX]; + void *private; /* os private_data */ + dhd_dbg_pkt_mon_t pkt_mon; + void *pkt_mon_lock; /* spin lock for packet monitoring */ + dbg_pullreq_t pullreq; + dbg_urgent_noti_t urgent_notifier; +} dhd_dbg_t; + +#define PKT_MON_ATTACHED(state) \ + (((state) > PKT_MON_INVALID) && ((state) < PKT_MON_DETACHED)) +#define PKT_MON_DETACHED(state) \ + (((state) == PKT_MON_INVALID) || ((state) == PKT_MON_DETACHED)) +#define PKT_MON_STARTED(state) ((state) == PKT_MON_STARTED) +#define PKT_MON_STOPPED(state) ((state) == PKT_MON_STOPPED) +#define PKT_MON_NOT_OPERATIONAL(state) \ + (((state) != PKT_MON_STARTED) && ((state) != PKT_MON_STOPPED)) +#define PKT_MON_SAFE_TO_FREE(state) \ + (((state) == PKT_MON_STARTING) || ((state) == PKT_MON_STOPPED)) +#define PKT_MON_PKT_FULL(pkt_count) ((pkt_count) >= MAX_FATE_LOG_LEN) +#define PKT_MON_STATUS_FULL(pkt_count, status_count) \ + (((status_count) >= (pkt_count)) || ((status_count) >= MAX_FATE_LOG_LEN)) + +#ifdef DBG_PKT_MON +#define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid) \ + do { \ + if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.tx_pkt_mon && (pkt)) { \ + (dhdp)->dbg->pkt_mon.tx_pkt_mon((dhdp), (pkt), (pktid)); \ + } \ + } while (0); +#define DHD_DBG_PKT_MON_TX_STATUS(dhdp, pkt, pktid, status) \ + do { \ + if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.tx_status_mon && (pkt)) { \ + (dhdp)->dbg->pkt_mon.tx_status_mon((dhdp), (pkt), (pktid), (status)); \ + } \ + } while (0); +#define DHD_DBG_PKT_MON_RX(dhdp, pkt) \ + do { \ + if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.rx_pkt_mon && (pkt)) { \ + if (ntoh16((pkt)->protocol) != ETHER_TYPE_BRCM) { \ + (dhdp)->dbg->pkt_mon.rx_pkt_mon((dhdp), (pkt)); \ + } \ + } \ + } while (0); + +#define DHD_DBG_PKT_MON_START(dhdp) \ + dhd_os_dbg_start_pkt_monitor((dhdp)); +#define DHD_DBG_PKT_MON_STOP(dhdp) \ + dhd_os_dbg_stop_pkt_monitor((dhdp)); +#else +#define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid) +#define DHD_DBG_PKT_MON_TX_STATUS(dhdp, pkt, pktid, status) +#define DHD_DBG_PKT_MON_RX(dhdp, pkt) +#define DHD_DBG_PKT_MON_START(dhdp) +#define DHD_DBG_PKT_MON_STOP(dhdp) +#endif /* DBG_PKT_MON */ + +#ifdef DUMP_IOCTL_IOV_LIST +typedef struct dhd_iov_li { + dll_t list; + uint32 cmd; /* command number */ + char buff[100]; /* command name */ +} dhd_iov_li_t; +#endif /* DUMP_IOCTL_IOV_LIST */ + +#define IOV_LIST_MAX_LEN 5 + +#ifdef DHD_DEBUG +typedef struct { + dll_t list; + uint32 id; /* wasted chunk id */ + uint32 handle; /* wasted chunk handle */ + uint32 size; /* wasted chunk size */ +} dhd_dbg_mwli_t; +#endif /* DHD_DEBUG */ + +#define DHD_OW_BI_RAW_EVENT_LOG_FMT 0xFFFF + +/* LSB 2 bits of format number to identify the type of event log */ +#define DHD_EVENT_LOG_HDR_MASK 0x3 + +#define DHD_EVENT_LOG_FMT_NUM_OFFSET 2 +#define DHD_EVENT_LOG_FMT_NUM_MASK 0x3FFF +/** + * OW:- one word + * TW:- two word + * NB:- non binary + * BI:- binary + */ +#define DHD_OW_NB_EVENT_LOG_HDR 0 +#define DHD_TW_NB_EVENT_LOG_HDR 1 +#define DHD_BI_EVENT_LOG_HDR 3 +#define DHD_INVALID_EVENT_LOG_HDR 2 + +#define DHD_TW_VALID_TAG_BITS_MASK 0xF +#define DHD_OW_BI_EVENT_FMT_NUM 0x3FFF +#define DHD_TW_BI_EVENT_FMT_NUM 0x3FFE + +#define DHD_TW_EVENT_LOG_TAG_OFFSET 8 + +#define EVENT_TAG_TIMESTAMP_OFFSET 1 +#define EVENT_TAG_TIMESTAMP_EXT_OFFSET 2 + +typedef struct prcd_event_log_hdr { + uint32 tag; /* Event_log entry tag */ + uint32 count; /* Count of 4-byte entries */ + uint32 fmt_num_raw; /* Format number */ + uint32 fmt_num; /* Format number >> 2 */ + uint32 armcycle; /* global ARM CYCLE for TAG */ + uint32 *log_ptr; /* start of payload */ + uint32 payload_len; + /* Extended event log header info + * 0 - legacy, 1 - extended event log header present + */ + bool ext_event_log_hdr; + bool binary_payload; /* 0 - non binary payload, 1 - binary payload */ +} prcd_event_log_hdr_t; /* Processed event log header */ /* dhd_dbg functions */ extern void dhd_dbg_trace_evnt_handler(dhd_pub_t *dhdp, void *event_data, void *raw_event_ptr, uint datalen); +void dhd_dbg_msgtrace_log_parser(dhd_pub_t *dhdp, void *event_data, + void *raw_event_ptr, uint datalen, bool msgtrace_hdr_present, + uint32 msgtrace_seqnum); + extern int dhd_dbg_attach(dhd_pub_t *dhdp, dbg_pullreq_t os_pullreq, dbg_urgent_noti_t os_urgent_notifier, void *os_priv); extern void dhd_dbg_detach(dhd_pub_t *dhdp); extern int dhd_dbg_start(dhd_pub_t *dhdp, bool start); extern int dhd_dbg_set_configuration(dhd_pub_t *dhdp, int ring_id, int log_level, int flags, uint32 threshold); -extern int dhd_dbg_get_ring_status(dhd_pub_t *dhdp, int ring_id, - dhd_dbg_ring_status_t *dbg_ring_status); -extern int dhd_dbg_ring_push(dhd_pub_t *dhdp, int ring_id, dhd_dbg_ring_entry_t *hdr, void *data); -extern int dhd_dbg_ring_pull(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len); extern int dhd_dbg_find_ring_id(dhd_pub_t *dhdp, char *ring_name); +extern dhd_dbg_ring_t *dhd_dbg_get_ring_from_ring_id(dhd_pub_t *dhdp, int ring_id); extern void *dhd_dbg_get_priv(dhd_pub_t *dhdp); extern int dhd_dbg_send_urgent_evt(dhd_pub_t *dhdp, const void *data, const uint32 len); +extern void dhd_dbg_verboselog_printf(dhd_pub_t *dhdp, prcd_event_log_hdr_t *plog_hdr, + void *raw_event_ptr, uint32 *log_ptr, uint32 logset, uint16 block); +int dhd_dbg_pull_from_ring(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len); +int dhd_dbg_pull_single_from_ring(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len, + bool strip_header); +int dhd_dbg_push_to_ring(dhd_pub_t *dhdp, int ring_id, dhd_dbg_ring_entry_t *hdr, + void *data); +int __dhd_dbg_get_ring_status(dhd_dbg_ring_t *ring, dhd_dbg_ring_status_t *ring_status); +int dhd_dbg_get_ring_status(dhd_pub_t *dhdp, int ring_id, + dhd_dbg_ring_status_t *dbg_ring_status); +#ifdef SHOW_LOGTRACE +void dhd_dbg_read_ring_into_trace_buf(dhd_dbg_ring_t *ring, trace_buf_info_t *trace_buf_info); +#endif /* SHOW_LOGTRACE */ + +#ifdef DBG_PKT_MON +extern int dhd_dbg_attach_pkt_monitor(dhd_pub_t *dhdp, + dbg_mon_tx_pkts_t tx_pkt_mon, + dbg_mon_tx_status_t tx_status_mon, + dbg_mon_rx_pkts_t rx_pkt_mon); +extern int dhd_dbg_start_pkt_monitor(dhd_pub_t *dhdp); +extern int dhd_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid); +extern int dhd_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt, + uint32 pktid, uint16 status); +extern int dhd_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt); +extern int dhd_dbg_stop_pkt_monitor(dhd_pub_t *dhdp); +extern int dhd_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf, + uint16 req_count, uint16 *resp_count); +extern int dhd_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp, void __user *user_buf, + uint16 req_count, uint16 *resp_count); +extern int dhd_dbg_detach_pkt_monitor(dhd_pub_t *dhdp); +#endif /* DBG_PKT_MON */ + +extern bool dhd_dbg_process_tx_status(dhd_pub_t *dhdp, void *pkt, + uint32 pktid, uint16 status); /* os wrapper function */ extern int dhd_os_dbg_attach(dhd_pub_t *dhdp); @@ -346,4 +830,29 @@ extern int dhd_os_push_push_ring_data(dhd_pub_t *dhdp, int ring_id, void *data, int32 data_len); extern int dhd_os_dbg_get_feature(dhd_pub_t *dhdp, int32 *features); +#ifdef DBG_PKT_MON +extern int dhd_os_dbg_attach_pkt_monitor(dhd_pub_t *dhdp); +extern int dhd_os_dbg_start_pkt_monitor(dhd_pub_t *dhdp); +extern int dhd_os_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, + uint32 pktid); +extern int dhd_os_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt, + uint32 pktid, uint16 status); +extern int dhd_os_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt); +extern int dhd_os_dbg_stop_pkt_monitor(dhd_pub_t *dhdp); +extern int dhd_os_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, + void __user *user_buf, uint16 req_count, uint16 *resp_count); +extern int dhd_os_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp, + void __user *user_buf, uint16 req_count, uint16 *resp_count); +extern int dhd_os_dbg_detach_pkt_monitor(dhd_pub_t *dhdp); +#endif /* DBG_PKT_MON */ + +#ifdef DUMP_IOCTL_IOV_LIST +extern void dhd_iov_li_append(dhd_pub_t *dhd, dll_t *list_head, dll_t *node); +extern void dhd_iov_li_print(dll_t *list_head); +extern void dhd_iov_li_delete(dhd_pub_t *dhd, dll_t *list_head); +#endif /* DUMP_IOCTL_IOV_LIST */ + +#ifdef DHD_DEBUG +extern void dhd_mw_list_delete(dhd_pub_t *dhd, dll_t *list_head); +#endif /* DHD_DEBUG */ #endif /* _dhd_debug_h_ */ -- Gitblit v1.6.2