162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* Copyright 2012 Cisco Systems, Inc. All rights reserved. */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#ifndef __FNIC_TRACE_H__ 562306a36Sopenharmony_ci#define __FNIC_TRACE_H__ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#define FNIC_ENTRY_SIZE_BYTES 64 862306a36Sopenharmony_ci#define FC_TRC_SIZE_BYTES 256 962306a36Sopenharmony_ci#define FC_TRC_HEADER_SIZE sizeof(struct fc_trace_hdr) 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci/* 1262306a36Sopenharmony_ci * Fisrt bit of FNIC_FC_RECV and FNIC_FC_SEND is used to represent the type 1362306a36Sopenharmony_ci * of frame 1 => Eth frame, 0=> FC frame 1462306a36Sopenharmony_ci */ 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#define FNIC_FC_RECV 0x52 /* Character R */ 1762306a36Sopenharmony_ci#define FNIC_FC_SEND 0x54 /* Character T */ 1862306a36Sopenharmony_ci#define FNIC_FC_LE 0x4C /* Character L */ 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ciextern ssize_t simple_read_from_buffer(void __user *to, 2162306a36Sopenharmony_ci size_t count, 2262306a36Sopenharmony_ci loff_t *ppos, 2362306a36Sopenharmony_ci const void *from, 2462306a36Sopenharmony_ci size_t available); 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ciextern unsigned int fnic_trace_max_pages; 2762306a36Sopenharmony_ciextern int fnic_tracing_enabled; 2862306a36Sopenharmony_ciextern unsigned int trace_max_pages; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ciextern unsigned int fnic_fc_trace_max_pages; 3162306a36Sopenharmony_ciextern int fnic_fc_tracing_enabled; 3262306a36Sopenharmony_ciextern int fnic_fc_trace_cleared; 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_citypedef struct fnic_trace_dbg { 3562306a36Sopenharmony_ci int wr_idx; 3662306a36Sopenharmony_ci int rd_idx; 3762306a36Sopenharmony_ci unsigned long *page_offset; 3862306a36Sopenharmony_ci} fnic_trace_dbg_t; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_citypedef struct fnic_dbgfs { 4162306a36Sopenharmony_ci int buffer_len; 4262306a36Sopenharmony_ci char *buffer; 4362306a36Sopenharmony_ci} fnic_dbgfs_t; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistruct fnic_trace_data { 4662306a36Sopenharmony_ci union { 4762306a36Sopenharmony_ci struct { 4862306a36Sopenharmony_ci u32 low; 4962306a36Sopenharmony_ci u32 high; 5062306a36Sopenharmony_ci }; 5162306a36Sopenharmony_ci u64 val; 5262306a36Sopenharmony_ci } timestamp, fnaddr; 5362306a36Sopenharmony_ci u32 host_no; 5462306a36Sopenharmony_ci u32 tag; 5562306a36Sopenharmony_ci u64 data[5]; 5662306a36Sopenharmony_ci} __attribute__((__packed__)); 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_citypedef struct fnic_trace_data fnic_trace_data_t; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistruct fc_trace_hdr { 6162306a36Sopenharmony_ci struct timespec64 time_stamp; 6262306a36Sopenharmony_ci u32 host_no; 6362306a36Sopenharmony_ci u8 frame_type; 6462306a36Sopenharmony_ci u8 frame_len; 6562306a36Sopenharmony_ci} __attribute__((__packed__)); 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci#define FC_TRACE_ADDRESS(a) \ 6862306a36Sopenharmony_ci ((unsigned long)(a) + sizeof(struct fc_trace_hdr)) 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci#define FNIC_TRACE_ENTRY_SIZE \ 7162306a36Sopenharmony_ci (FNIC_ENTRY_SIZE_BYTES - sizeof(fnic_trace_data_t)) 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci#define FNIC_TRACE(_fn, _hn, _t, _a, _b, _c, _d, _e) \ 7462306a36Sopenharmony_ci if (unlikely(fnic_tracing_enabled)) { \ 7562306a36Sopenharmony_ci fnic_trace_data_t *trace_buf = fnic_trace_get_buf(); \ 7662306a36Sopenharmony_ci if (trace_buf) { \ 7762306a36Sopenharmony_ci if (sizeof(unsigned long) < 8) { \ 7862306a36Sopenharmony_ci trace_buf->timestamp.low = jiffies; \ 7962306a36Sopenharmony_ci trace_buf->fnaddr.low = (u32)(unsigned long)_fn; \ 8062306a36Sopenharmony_ci } else { \ 8162306a36Sopenharmony_ci trace_buf->timestamp.val = jiffies; \ 8262306a36Sopenharmony_ci trace_buf->fnaddr.val = (u64)(unsigned long)_fn; \ 8362306a36Sopenharmony_ci } \ 8462306a36Sopenharmony_ci trace_buf->host_no = _hn; \ 8562306a36Sopenharmony_ci trace_buf->tag = _t; \ 8662306a36Sopenharmony_ci trace_buf->data[0] = (u64)(unsigned long)_a; \ 8762306a36Sopenharmony_ci trace_buf->data[1] = (u64)(unsigned long)_b; \ 8862306a36Sopenharmony_ci trace_buf->data[2] = (u64)(unsigned long)_c; \ 8962306a36Sopenharmony_ci trace_buf->data[3] = (u64)(unsigned long)_d; \ 9062306a36Sopenharmony_ci trace_buf->data[4] = (u64)(unsigned long)_e; \ 9162306a36Sopenharmony_ci } \ 9262306a36Sopenharmony_ci } 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cifnic_trace_data_t *fnic_trace_get_buf(void); 9562306a36Sopenharmony_ciint fnic_get_trace_data(fnic_dbgfs_t *); 9662306a36Sopenharmony_ciint fnic_trace_buf_init(void); 9762306a36Sopenharmony_civoid fnic_trace_free(void); 9862306a36Sopenharmony_ciint fnic_debugfs_init(void); 9962306a36Sopenharmony_civoid fnic_debugfs_terminate(void); 10062306a36Sopenharmony_civoid fnic_trace_debugfs_init(void); 10162306a36Sopenharmony_civoid fnic_trace_debugfs_terminate(void); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci/* Fnic FC CTLR Trace releated function */ 10462306a36Sopenharmony_ciint fnic_fc_trace_init(void); 10562306a36Sopenharmony_civoid fnic_fc_trace_free(void); 10662306a36Sopenharmony_ciint fnic_fc_trace_set_data(u32 host_no, u8 frame_type, 10762306a36Sopenharmony_ci char *frame, u32 fc_frame_len); 10862306a36Sopenharmony_ciint fnic_fc_trace_get_data(fnic_dbgfs_t *fnic_dbgfs_prt, u8 rdata_flag); 10962306a36Sopenharmony_civoid copy_and_format_trace_data(struct fc_trace_hdr *tdata, 11062306a36Sopenharmony_ci fnic_dbgfs_t *fnic_dbgfs_prt, 11162306a36Sopenharmony_ci int *len, u8 rdata_flag); 11262306a36Sopenharmony_civoid fnic_fc_trace_debugfs_init(void); 11362306a36Sopenharmony_civoid fnic_fc_trace_debugfs_terminate(void); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci#endif 116