18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright 2012 Cisco Systems, Inc.  All rights reserved.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * This program is free software; you may redistribute it and/or modify
58c2ecf20Sopenharmony_ci * it under the terms of the GNU General Public License as published by
68c2ecf20Sopenharmony_ci * the Free Software Foundation; version 2 of the License.
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
98c2ecf20Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
108c2ecf20Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
118c2ecf20Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
128c2ecf20Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
138c2ecf20Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
148c2ecf20Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
158c2ecf20Sopenharmony_ci * SOFTWARE.
168c2ecf20Sopenharmony_ci */
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#ifndef __FNIC_TRACE_H__
198c2ecf20Sopenharmony_ci#define __FNIC_TRACE_H__
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci#define FNIC_ENTRY_SIZE_BYTES 64
228c2ecf20Sopenharmony_ci#define FC_TRC_SIZE_BYTES 256
238c2ecf20Sopenharmony_ci#define FC_TRC_HEADER_SIZE sizeof(struct fc_trace_hdr)
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci/*
268c2ecf20Sopenharmony_ci * Fisrt bit of FNIC_FC_RECV and FNIC_FC_SEND is used to represent the type
278c2ecf20Sopenharmony_ci * of frame 1 => Eth frame, 0=> FC frame
288c2ecf20Sopenharmony_ci */
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci#define FNIC_FC_RECV 0x52 /* Character R */
318c2ecf20Sopenharmony_ci#define FNIC_FC_SEND 0x54 /* Character T */
328c2ecf20Sopenharmony_ci#define FNIC_FC_LE 0x4C /* Character L */
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ciextern ssize_t simple_read_from_buffer(void __user *to,
358c2ecf20Sopenharmony_ci					  size_t count,
368c2ecf20Sopenharmony_ci					  loff_t *ppos,
378c2ecf20Sopenharmony_ci					  const void *from,
388c2ecf20Sopenharmony_ci					  size_t available);
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ciextern unsigned int fnic_trace_max_pages;
418c2ecf20Sopenharmony_ciextern int fnic_tracing_enabled;
428c2ecf20Sopenharmony_ciextern unsigned int trace_max_pages;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ciextern unsigned int fnic_fc_trace_max_pages;
458c2ecf20Sopenharmony_ciextern int fnic_fc_tracing_enabled;
468c2ecf20Sopenharmony_ciextern int fnic_fc_trace_cleared;
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_citypedef struct fnic_trace_dbg {
498c2ecf20Sopenharmony_ci	int wr_idx;
508c2ecf20Sopenharmony_ci	int rd_idx;
518c2ecf20Sopenharmony_ci	unsigned long *page_offset;
528c2ecf20Sopenharmony_ci} fnic_trace_dbg_t;
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_citypedef struct fnic_dbgfs {
558c2ecf20Sopenharmony_ci	int buffer_len;
568c2ecf20Sopenharmony_ci	char *buffer;
578c2ecf20Sopenharmony_ci} fnic_dbgfs_t;
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cistruct fnic_trace_data {
608c2ecf20Sopenharmony_ci	union {
618c2ecf20Sopenharmony_ci		struct {
628c2ecf20Sopenharmony_ci			u32 low;
638c2ecf20Sopenharmony_ci			u32 high;
648c2ecf20Sopenharmony_ci		};
658c2ecf20Sopenharmony_ci		u64 val;
668c2ecf20Sopenharmony_ci	} timestamp, fnaddr;
678c2ecf20Sopenharmony_ci	u32 host_no;
688c2ecf20Sopenharmony_ci	u32 tag;
698c2ecf20Sopenharmony_ci	u64 data[5];
708c2ecf20Sopenharmony_ci} __attribute__((__packed__));
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_citypedef struct fnic_trace_data fnic_trace_data_t;
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_cistruct fc_trace_hdr {
758c2ecf20Sopenharmony_ci	struct timespec64 time_stamp;
768c2ecf20Sopenharmony_ci	u32 host_no;
778c2ecf20Sopenharmony_ci	u8 frame_type;
788c2ecf20Sopenharmony_ci	u8 frame_len;
798c2ecf20Sopenharmony_ci} __attribute__((__packed__));
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci#define FC_TRACE_ADDRESS(a) \
828c2ecf20Sopenharmony_ci	((unsigned long)(a) + sizeof(struct fc_trace_hdr))
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci#define FNIC_TRACE_ENTRY_SIZE \
858c2ecf20Sopenharmony_ci		  (FNIC_ENTRY_SIZE_BYTES - sizeof(fnic_trace_data_t))
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci#define FNIC_TRACE(_fn, _hn, _t, _a, _b, _c, _d, _e)           \
888c2ecf20Sopenharmony_ci	if (unlikely(fnic_tracing_enabled)) {                   \
898c2ecf20Sopenharmony_ci		fnic_trace_data_t *trace_buf = fnic_trace_get_buf(); \
908c2ecf20Sopenharmony_ci		if (trace_buf) { \
918c2ecf20Sopenharmony_ci			if (sizeof(unsigned long) < 8) { \
928c2ecf20Sopenharmony_ci				trace_buf->timestamp.low = jiffies; \
938c2ecf20Sopenharmony_ci				trace_buf->fnaddr.low = (u32)(unsigned long)_fn; \
948c2ecf20Sopenharmony_ci			} else { \
958c2ecf20Sopenharmony_ci				trace_buf->timestamp.val = jiffies; \
968c2ecf20Sopenharmony_ci				trace_buf->fnaddr.val = (u64)(unsigned long)_fn; \
978c2ecf20Sopenharmony_ci			} \
988c2ecf20Sopenharmony_ci			trace_buf->host_no = _hn; \
998c2ecf20Sopenharmony_ci			trace_buf->tag = _t; \
1008c2ecf20Sopenharmony_ci			trace_buf->data[0] = (u64)(unsigned long)_a; \
1018c2ecf20Sopenharmony_ci			trace_buf->data[1] = (u64)(unsigned long)_b; \
1028c2ecf20Sopenharmony_ci			trace_buf->data[2] = (u64)(unsigned long)_c; \
1038c2ecf20Sopenharmony_ci			trace_buf->data[3] = (u64)(unsigned long)_d; \
1048c2ecf20Sopenharmony_ci			trace_buf->data[4] = (u64)(unsigned long)_e; \
1058c2ecf20Sopenharmony_ci		} \
1068c2ecf20Sopenharmony_ci	}
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_cifnic_trace_data_t *fnic_trace_get_buf(void);
1098c2ecf20Sopenharmony_ciint fnic_get_trace_data(fnic_dbgfs_t *);
1108c2ecf20Sopenharmony_ciint fnic_trace_buf_init(void);
1118c2ecf20Sopenharmony_civoid fnic_trace_free(void);
1128c2ecf20Sopenharmony_ciint fnic_debugfs_init(void);
1138c2ecf20Sopenharmony_civoid fnic_debugfs_terminate(void);
1148c2ecf20Sopenharmony_civoid fnic_trace_debugfs_init(void);
1158c2ecf20Sopenharmony_civoid fnic_trace_debugfs_terminate(void);
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci/* Fnic FC CTLR Trace releated function */
1188c2ecf20Sopenharmony_ciint fnic_fc_trace_init(void);
1198c2ecf20Sopenharmony_civoid fnic_fc_trace_free(void);
1208c2ecf20Sopenharmony_ciint fnic_fc_trace_set_data(u32 host_no, u8 frame_type,
1218c2ecf20Sopenharmony_ci				char *frame, u32 fc_frame_len);
1228c2ecf20Sopenharmony_ciint fnic_fc_trace_get_data(fnic_dbgfs_t *fnic_dbgfs_prt, u8 rdata_flag);
1238c2ecf20Sopenharmony_civoid copy_and_format_trace_data(struct fc_trace_hdr *tdata,
1248c2ecf20Sopenharmony_ci				fnic_dbgfs_t *fnic_dbgfs_prt,
1258c2ecf20Sopenharmony_ci				int *len, u8 rdata_flag);
1268c2ecf20Sopenharmony_civoid fnic_fc_trace_debugfs_init(void);
1278c2ecf20Sopenharmony_civoid fnic_fc_trace_debugfs_terminate(void);
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci#endif
130