Commit abb14148 authored by Hiral Shah's avatar Hiral Shah Committed by Christoph Hellwig

fnic: fnic Control Path Trace Utility

Fnic Ctlr Path Trace utility is a tracing functionality built directly into fnic
driver to trace the control path frames like discovery, FLOGI request/reply,
PLOGI request/reply, link event etc.  It will be one trace file for all fnics.
It will help us to debug and resolve the discovery and initialization related
issues in more convenient way. This trace information includes time stamp,
Host Number, Frame type, Frame Length and Frame. By default,64 pages are
allocated but we can change the number of allocated pages by module parameter
fnic_fc_trace_max_page. Each entry is of 256 byte and available entries are
depends on allocated number of pages. We can turn on or off the fnic control
path trace functionality by module paramter fc_trace_enable and/or reset the
trace contain by module paramter fc_trace_clear.
Signed-off-by: default avatarHiral Shah <hishah@cisco.com>
Signed-off-by: default avatarSesidhar Baddela <sebaddel@cisco.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 66818663
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#define DRV_NAME "fnic" #define DRV_NAME "fnic"
#define DRV_DESCRIPTION "Cisco FCoE HBA Driver" #define DRV_DESCRIPTION "Cisco FCoE HBA Driver"
#define DRV_VERSION "1.5.0.45" #define DRV_VERSION "1.6.0.10"
#define PFX DRV_NAME ": " #define PFX DRV_NAME ": "
#define DFX DRV_NAME "%d: " #define DFX DRV_NAME "%d: "
......
...@@ -25,6 +25,21 @@ static struct dentry *fnic_trace_debugfs_file; ...@@ -25,6 +25,21 @@ static struct dentry *fnic_trace_debugfs_file;
static struct dentry *fnic_trace_enable; static struct dentry *fnic_trace_enable;
static struct dentry *fnic_stats_debugfs_root; static struct dentry *fnic_stats_debugfs_root;
static struct dentry *fnic_fc_trace_debugfs_file;
static struct dentry *fnic_fc_rdata_trace_debugfs_file;
static struct dentry *fnic_fc_trace_enable;
static struct dentry *fnic_fc_trace_clear;
struct fc_trace_flag_type {
u8 fc_row_file;
u8 fc_normal_file;
u8 fnic_trace;
u8 fc_trace;
u8 fc_clear;
};
static struct fc_trace_flag_type *fc_trc_flag;
/* /*
* fnic_debugfs_init - Initialize debugfs for fnic debug logging * fnic_debugfs_init - Initialize debugfs for fnic debug logging
* *
...@@ -56,6 +71,18 @@ int fnic_debugfs_init(void) ...@@ -56,6 +71,18 @@ int fnic_debugfs_init(void)
return rc; return rc;
} }
/* Allocate memory to structure */
fc_trc_flag = (struct fc_trace_flag_type *)
vmalloc(sizeof(struct fc_trace_flag_type));
if (fc_trc_flag) {
fc_trc_flag->fc_row_file = 0;
fc_trc_flag->fc_normal_file = 1;
fc_trc_flag->fnic_trace = 2;
fc_trc_flag->fc_trace = 3;
fc_trc_flag->fc_clear = 4;
}
rc = 0; rc = 0;
return rc; return rc;
} }
...@@ -74,15 +101,19 @@ void fnic_debugfs_terminate(void) ...@@ -74,15 +101,19 @@ void fnic_debugfs_terminate(void)
debugfs_remove(fnic_trace_debugfs_root); debugfs_remove(fnic_trace_debugfs_root);
fnic_trace_debugfs_root = NULL; fnic_trace_debugfs_root = NULL;
if (fc_trc_flag)
vfree(fc_trc_flag);
} }
/* /*
* fnic_trace_ctrl_open - Open the trace_enable file * fnic_trace_ctrl_open - Open the trace_enable file for fnic_trace
* Or Open fc_trace_enable file for fc_trace
* @inode: The inode pointer. * @inode: The inode pointer.
* @file: The file pointer to attach the trace enable/disable flag. * @file: The file pointer to attach the trace enable/disable flag.
* *
* Description: * Description:
* This routine opens a debugsfs file trace_enable. * This routine opens a debugsfs file trace_enable or fc_trace_enable.
* *
* Returns: * Returns:
* This function returns zero if successful. * This function returns zero if successful.
...@@ -94,15 +125,19 @@ static int fnic_trace_ctrl_open(struct inode *inode, struct file *filp) ...@@ -94,15 +125,19 @@ static int fnic_trace_ctrl_open(struct inode *inode, struct file *filp)
} }
/* /*
* fnic_trace_ctrl_read - Read a trace_enable debugfs file * fnic_trace_ctrl_read -
* Read trace_enable ,fc_trace_enable
* or fc_trace_clear debugfs file
* @filp: The file pointer to read from. * @filp: The file pointer to read from.
* @ubuf: The buffer to copy the data to. * @ubuf: The buffer to copy the data to.
* @cnt: The number of bytes to read. * @cnt: The number of bytes to read.
* @ppos: The position in the file to start reading from. * @ppos: The position in the file to start reading from.
* *
* Description: * Description:
* This routine reads value of variable fnic_tracing_enabled * This routine reads value of variable fnic_tracing_enabled or
* and stores into local @buf. It will start reading file at @ppos and * fnic_fc_tracing_enabled or fnic_fc_trace_cleared
* and stores into local @buf.
* It will start reading file at @ppos and
* copy up to @cnt of data to @ubuf from @buf. * copy up to @cnt of data to @ubuf from @buf.
* *
* Returns: * Returns:
...@@ -114,13 +149,25 @@ static ssize_t fnic_trace_ctrl_read(struct file *filp, ...@@ -114,13 +149,25 @@ static ssize_t fnic_trace_ctrl_read(struct file *filp,
{ {
char buf[64]; char buf[64];
int len; int len;
u8 *trace_type;
len = 0;
trace_type = (u8 *)filp->private_data;
if (*trace_type == fc_trc_flag->fnic_trace)
len = sprintf(buf, "%u\n", fnic_tracing_enabled); len = sprintf(buf, "%u\n", fnic_tracing_enabled);
else if (*trace_type == fc_trc_flag->fc_trace)
len = sprintf(buf, "%u\n", fnic_fc_tracing_enabled);
else if (*trace_type == fc_trc_flag->fc_clear)
len = sprintf(buf, "%u\n", fnic_fc_trace_cleared);
else
pr_err("fnic: Cannot read to any debugfs file\n");
return simple_read_from_buffer(ubuf, cnt, ppos, buf, len); return simple_read_from_buffer(ubuf, cnt, ppos, buf, len);
} }
/* /*
* fnic_trace_ctrl_write - Write to trace_enable debugfs file * fnic_trace_ctrl_write -
* Write to trace_enable, fc_trace_enable or
* fc_trace_clear debugfs file
* @filp: The file pointer to write from. * @filp: The file pointer to write from.
* @ubuf: The buffer to copy the data from. * @ubuf: The buffer to copy the data from.
* @cnt: The number of bytes to write. * @cnt: The number of bytes to write.
...@@ -128,7 +175,8 @@ static ssize_t fnic_trace_ctrl_read(struct file *filp, ...@@ -128,7 +175,8 @@ static ssize_t fnic_trace_ctrl_read(struct file *filp,
* *
* Description: * Description:
* This routine writes data from user buffer @ubuf to buffer @buf and * This routine writes data from user buffer @ubuf to buffer @buf and
* sets fnic_tracing_enabled value as per user input. * sets fc_trace_enable ,tracing_enable or fnic_fc_trace_cleared
* value as per user input.
* *
* Returns: * Returns:
* This function returns the amount of data that was written. * This function returns the amount of data that was written.
...@@ -140,6 +188,8 @@ static ssize_t fnic_trace_ctrl_write(struct file *filp, ...@@ -140,6 +188,8 @@ static ssize_t fnic_trace_ctrl_write(struct file *filp,
char buf[64]; char buf[64];
unsigned long val; unsigned long val;
int ret; int ret;
u8 *trace_type;
trace_type = (u8 *)filp->private_data;
if (cnt >= sizeof(buf)) if (cnt >= sizeof(buf))
return -EINVAL; return -EINVAL;
...@@ -153,12 +203,27 @@ static ssize_t fnic_trace_ctrl_write(struct file *filp, ...@@ -153,12 +203,27 @@ static ssize_t fnic_trace_ctrl_write(struct file *filp,
if (ret < 0) if (ret < 0)
return ret; return ret;
if (*trace_type == fc_trc_flag->fnic_trace)
fnic_tracing_enabled = val; fnic_tracing_enabled = val;
else if (*trace_type == fc_trc_flag->fc_trace)
fnic_fc_tracing_enabled = val;
else if (*trace_type == fc_trc_flag->fc_clear)
fnic_fc_trace_cleared = val;
else
pr_err("fnic: cannot write to any debufs file\n");
(*ppos)++; (*ppos)++;
return cnt; return cnt;
} }
static const struct file_operations fnic_trace_ctrl_fops = {
.owner = THIS_MODULE,
.open = fnic_trace_ctrl_open,
.read = fnic_trace_ctrl_read,
.write = fnic_trace_ctrl_write,
};
/* /*
* fnic_trace_debugfs_open - Open the fnic trace log * fnic_trace_debugfs_open - Open the fnic trace log
* @inode: The inode pointer * @inode: The inode pointer
...@@ -178,19 +243,36 @@ static int fnic_trace_debugfs_open(struct inode *inode, ...@@ -178,19 +243,36 @@ static int fnic_trace_debugfs_open(struct inode *inode,
struct file *file) struct file *file)
{ {
fnic_dbgfs_t *fnic_dbg_prt; fnic_dbgfs_t *fnic_dbg_prt;
u8 *rdata_ptr;
rdata_ptr = (u8 *)inode->i_private;
fnic_dbg_prt = kzalloc(sizeof(fnic_dbgfs_t), GFP_KERNEL); fnic_dbg_prt = kzalloc(sizeof(fnic_dbgfs_t), GFP_KERNEL);
if (!fnic_dbg_prt) if (!fnic_dbg_prt)
return -ENOMEM; return -ENOMEM;
fnic_dbg_prt->buffer = vmalloc((3*(trace_max_pages * PAGE_SIZE))); if (*rdata_ptr == fc_trc_flag->fnic_trace) {
fnic_dbg_prt->buffer = vmalloc(3 *
(trace_max_pages * PAGE_SIZE));
if (!fnic_dbg_prt->buffer) { if (!fnic_dbg_prt->buffer) {
kfree(fnic_dbg_prt); kfree(fnic_dbg_prt);
return -ENOMEM; return -ENOMEM;
} }
memset((void *)fnic_dbg_prt->buffer, 0, memset((void *)fnic_dbg_prt->buffer, 0,
(3*(trace_max_pages * PAGE_SIZE))); 3 * (trace_max_pages * PAGE_SIZE));
fnic_dbg_prt->buffer_len = fnic_get_trace_data(fnic_dbg_prt); fnic_dbg_prt->buffer_len = fnic_get_trace_data(fnic_dbg_prt);
} else {
fnic_dbg_prt->buffer =
vmalloc(3 * (fnic_fc_trace_max_pages * PAGE_SIZE));
if (!fnic_dbg_prt->buffer) {
kfree(fnic_dbg_prt);
return -ENOMEM;
}
memset((void *)fnic_dbg_prt->buffer, 0,
3 * (fnic_fc_trace_max_pages * PAGE_SIZE));
fnic_dbg_prt->buffer_len =
fnic_fc_trace_get_data(fnic_dbg_prt, *rdata_ptr);
}
file->private_data = fnic_dbg_prt; file->private_data = fnic_dbg_prt;
return 0; return 0;
} }
...@@ -272,13 +354,6 @@ static int fnic_trace_debugfs_release(struct inode *inode, ...@@ -272,13 +354,6 @@ static int fnic_trace_debugfs_release(struct inode *inode,
return 0; return 0;
} }
static const struct file_operations fnic_trace_ctrl_fops = {
.owner = THIS_MODULE,
.open = fnic_trace_ctrl_open,
.read = fnic_trace_ctrl_read,
.write = fnic_trace_ctrl_write,
};
static const struct file_operations fnic_trace_debugfs_fops = { static const struct file_operations fnic_trace_debugfs_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.open = fnic_trace_debugfs_open, .open = fnic_trace_debugfs_open,
...@@ -308,7 +383,8 @@ int fnic_trace_debugfs_init(void) ...@@ -308,7 +383,8 @@ int fnic_trace_debugfs_init(void)
fnic_trace_enable = debugfs_create_file("tracing_enable", fnic_trace_enable = debugfs_create_file("tracing_enable",
S_IFREG|S_IRUGO|S_IWUSR, S_IFREG|S_IRUGO|S_IWUSR,
fnic_trace_debugfs_root, fnic_trace_debugfs_root,
NULL, &fnic_trace_ctrl_fops); &(fc_trc_flag->fnic_trace),
&fnic_trace_ctrl_fops);
if (!fnic_trace_enable) { if (!fnic_trace_enable) {
printk(KERN_DEBUG printk(KERN_DEBUG
...@@ -319,7 +395,7 @@ int fnic_trace_debugfs_init(void) ...@@ -319,7 +395,7 @@ int fnic_trace_debugfs_init(void)
fnic_trace_debugfs_file = debugfs_create_file("trace", fnic_trace_debugfs_file = debugfs_create_file("trace",
S_IFREG|S_IRUGO|S_IWUSR, S_IFREG|S_IRUGO|S_IWUSR,
fnic_trace_debugfs_root, fnic_trace_debugfs_root,
NULL, &(fc_trc_flag->fnic_trace),
&fnic_trace_debugfs_fops); &fnic_trace_debugfs_fops);
if (!fnic_trace_debugfs_file) { if (!fnic_trace_debugfs_file) {
...@@ -340,14 +416,104 @@ int fnic_trace_debugfs_init(void) ...@@ -340,14 +416,104 @@ int fnic_trace_debugfs_init(void)
*/ */
void fnic_trace_debugfs_terminate(void) void fnic_trace_debugfs_terminate(void)
{ {
if (fnic_trace_debugfs_file) {
debugfs_remove(fnic_trace_debugfs_file); debugfs_remove(fnic_trace_debugfs_file);
fnic_trace_debugfs_file = NULL; fnic_trace_debugfs_file = NULL;
}
if (fnic_trace_enable) {
debugfs_remove(fnic_trace_enable); debugfs_remove(fnic_trace_enable);
fnic_trace_enable = NULL; fnic_trace_enable = NULL;
}
/*
* fnic_fc_trace_debugfs_init -
* Initialize debugfs for fnic control frame trace logging
*
* Description:
* When Debugfs is configured this routine sets up the fnic_fc debugfs
* file system. If not already created, this routine will create the
* create file trace to log fnic fc trace buffer output into debugfs and
* it will also create file fc_trace_enable to control enable/disable of
* trace logging into trace buffer.
*/
int fnic_fc_trace_debugfs_init(void)
{
int rc = -1;
if (!fnic_trace_debugfs_root) {
pr_err("fnic:Debugfs root directory doesn't exist\n");
return rc;
}
fnic_fc_trace_enable = debugfs_create_file("fc_trace_enable",
S_IFREG|S_IRUGO|S_IWUSR,
fnic_trace_debugfs_root,
&(fc_trc_flag->fc_trace),
&fnic_trace_ctrl_fops);
if (!fnic_fc_trace_enable) {
pr_err("fnic: Failed create fc_trace_enable file\n");
return rc;
}
fnic_fc_trace_clear = debugfs_create_file("fc_trace_clear",
S_IFREG|S_IRUGO|S_IWUSR,
fnic_trace_debugfs_root,
&(fc_trc_flag->fc_clear),
&fnic_trace_ctrl_fops);
if (!fnic_fc_trace_clear) {
pr_err("fnic: Failed to create fc_trace_enable file\n");
return rc;
}
fnic_fc_rdata_trace_debugfs_file =
debugfs_create_file("fc_trace_rdata",
S_IFREG|S_IRUGO|S_IWUSR,
fnic_trace_debugfs_root,
&(fc_trc_flag->fc_normal_file),
&fnic_trace_debugfs_fops);
if (!fnic_fc_rdata_trace_debugfs_file) {
pr_err("fnic: Failed create fc_rdata_trace file\n");
return rc;
} }
fnic_fc_trace_debugfs_file =
debugfs_create_file("fc_trace",
S_IFREG|S_IRUGO|S_IWUSR,
fnic_trace_debugfs_root,
&(fc_trc_flag->fc_row_file),
&fnic_trace_debugfs_fops);
if (!fnic_fc_trace_debugfs_file) {
pr_err("fnic: Failed to create fc_trace file\n");
return rc;
}
rc = 0;
return rc;
}
/*
* fnic_fc_trace_debugfs_terminate - Tear down debugfs infrastructure
*
* Description:
* When Debugfs is configured this routine removes debugfs file system
* elements that are specific to fnic_fc trace logging.
*/
void fnic_fc_trace_debugfs_terminate(void)
{
debugfs_remove(fnic_fc_trace_debugfs_file);
fnic_fc_trace_debugfs_file = NULL;
debugfs_remove(fnic_fc_rdata_trace_debugfs_file);
fnic_fc_rdata_trace_debugfs_file = NULL;
debugfs_remove(fnic_fc_trace_enable);
fnic_fc_trace_enable = NULL;
debugfs_remove(fnic_fc_trace_clear);
fnic_fc_trace_clear = NULL;
} }
/* /*
......
...@@ -66,19 +66,35 @@ void fnic_handle_link(struct work_struct *work) ...@@ -66,19 +66,35 @@ void fnic_handle_link(struct work_struct *work)
fnic->link_down_cnt = vnic_dev_link_down_cnt(fnic->vdev); fnic->link_down_cnt = vnic_dev_link_down_cnt(fnic->vdev);
if (old_link_status == fnic->link_status) { if (old_link_status == fnic->link_status) {
if (!fnic->link_status) if (!fnic->link_status) {
/* DOWN -> DOWN */ /* DOWN -> DOWN */
spin_unlock_irqrestore(&fnic->fnic_lock, flags); spin_unlock_irqrestore(&fnic->fnic_lock, flags);
else { fnic_fc_trace_set_data(fnic->lport->host->host_no,
FNIC_FC_LE, "Link Status: DOWN->DOWN",
strlen("Link Status: DOWN->DOWN"));
} else {
if (old_link_down_cnt != fnic->link_down_cnt) { if (old_link_down_cnt != fnic->link_down_cnt) {
/* UP -> DOWN -> UP */ /* UP -> DOWN -> UP */
fnic->lport->host_stats.link_failure_count++; fnic->lport->host_stats.link_failure_count++;
spin_unlock_irqrestore(&fnic->fnic_lock, flags); spin_unlock_irqrestore(&fnic->fnic_lock, flags);
fnic_fc_trace_set_data(
fnic->lport->host->host_no,
FNIC_FC_LE,
"Link Status:UP_DOWN_UP",
strlen("Link_Status:UP_DOWN_UP")
);
FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
"link down\n"); "link down\n");
fcoe_ctlr_link_down(&fnic->ctlr); fcoe_ctlr_link_down(&fnic->ctlr);
if (fnic->config.flags & VFCF_FIP_CAPABLE) { if (fnic->config.flags & VFCF_FIP_CAPABLE) {
/* start FCoE VLAN discovery */ /* start FCoE VLAN discovery */
fnic_fc_trace_set_data(
fnic->lport->host->host_no,
FNIC_FC_LE,
"Link Status: UP_DOWN_UP_VLAN",
strlen(
"Link Status: UP_DOWN_UP_VLAN")
);
fnic_fcoe_send_vlan_req(fnic); fnic_fcoe_send_vlan_req(fnic);
return; return;
} }
...@@ -88,22 +104,36 @@ void fnic_handle_link(struct work_struct *work) ...@@ -88,22 +104,36 @@ void fnic_handle_link(struct work_struct *work)
} else } else
/* UP -> UP */ /* UP -> UP */
spin_unlock_irqrestore(&fnic->fnic_lock, flags); spin_unlock_irqrestore(&fnic->fnic_lock, flags);
fnic_fc_trace_set_data(
fnic->lport->host->host_no, FNIC_FC_LE,
"Link Status: UP_UP",
strlen("Link Status: UP_UP"));
} }
} else if (fnic->link_status) { } else if (fnic->link_status) {
/* DOWN -> UP */ /* DOWN -> UP */
spin_unlock_irqrestore(&fnic->fnic_lock, flags); spin_unlock_irqrestore(&fnic->fnic_lock, flags);
if (fnic->config.flags & VFCF_FIP_CAPABLE) { if (fnic->config.flags & VFCF_FIP_CAPABLE) {
/* start FCoE VLAN discovery */ /* start FCoE VLAN discovery */
fnic_fc_trace_set_data(
fnic->lport->host->host_no,
FNIC_FC_LE, "Link Status: DOWN_UP_VLAN",
strlen("Link Status: DOWN_UP_VLAN"));
fnic_fcoe_send_vlan_req(fnic); fnic_fcoe_send_vlan_req(fnic);
return; return;
} }
FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n"); FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link up\n");
fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_LE,
"Link Status: DOWN_UP", strlen("Link Status: DOWN_UP"));
fcoe_ctlr_link_up(&fnic->ctlr); fcoe_ctlr_link_up(&fnic->ctlr);
} else { } else {
/* UP -> DOWN */ /* UP -> DOWN */
fnic->lport->host_stats.link_failure_count++; fnic->lport->host_stats.link_failure_count++;
spin_unlock_irqrestore(&fnic->fnic_lock, flags); spin_unlock_irqrestore(&fnic->fnic_lock, flags);
FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link down\n"); FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host, "link down\n");
fnic_fc_trace_set_data(
fnic->lport->host->host_no, FNIC_FC_LE,
"Link Status: UP_DOWN",
strlen("Link Status: UP_DOWN"));
fcoe_ctlr_link_down(&fnic->ctlr); fcoe_ctlr_link_down(&fnic->ctlr);
} }
...@@ -611,6 +641,10 @@ static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb) ...@@ -611,6 +641,10 @@ static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, struct sk_buff *skb)
"using UCSM\n"); "using UCSM\n");
goto drop; goto drop;
} }
if ((fnic_fc_trace_set_data(fnic->lport->host->host_no,
FNIC_FC_RECV|0x80, (char *)skb->data, skb->len)) != 0) {
printk(KERN_ERR "fnic ctlr frame trace error!!!");
}
skb_queue_tail(&fnic->fip_frame_queue, skb); skb_queue_tail(&fnic->fip_frame_queue, skb);
queue_work(fnic_fip_queue, &fnic->fip_frame_work); queue_work(fnic_fip_queue, &fnic->fip_frame_work);
return 1; /* let caller know packet was used */ return 1; /* let caller know packet was used */
...@@ -839,6 +873,10 @@ static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc ...@@ -839,6 +873,10 @@ static void fnic_rq_cmpl_frame_recv(struct vnic_rq *rq, struct cq_desc
} }
fr_dev(fp) = fnic->lport; fr_dev(fp) = fnic->lport;
spin_unlock_irqrestore(&fnic->fnic_lock, flags); spin_unlock_irqrestore(&fnic->fnic_lock, flags);
if ((fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_RECV,
(char *)skb->data, skb->len)) != 0) {
printk(KERN_ERR "fnic ctlr frame trace error!!!");
}
skb_queue_tail(&fnic->frame_queue, skb); skb_queue_tail(&fnic->frame_queue, skb);
queue_work(fnic_event_queue, &fnic->frame_work); queue_work(fnic_event_queue, &fnic->frame_work);
...@@ -946,6 +984,15 @@ void fnic_eth_send(struct fcoe_ctlr *fip, struct sk_buff *skb) ...@@ -946,6 +984,15 @@ void fnic_eth_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q); vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q);
vlan_hdr->h_vlan_encapsulated_proto = eth_hdr->h_proto; vlan_hdr->h_vlan_encapsulated_proto = eth_hdr->h_proto;
vlan_hdr->h_vlan_TCI = htons(fnic->vlan_id); vlan_hdr->h_vlan_TCI = htons(fnic->vlan_id);
if ((fnic_fc_trace_set_data(fnic->lport->host->host_no,
FNIC_FC_SEND|0x80, (char *)eth_hdr, skb->len)) != 0) {
printk(KERN_ERR "fnic ctlr frame trace error!!!");
}
} else {
if ((fnic_fc_trace_set_data(fnic->lport->host->host_no,
FNIC_FC_SEND|0x80, (char *)skb->data, skb->len)) != 0) {
printk(KERN_ERR "fnic ctlr frame trace error!!!");
}
} }
pa = pci_map_single(fnic->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); pa = pci_map_single(fnic->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
...@@ -1018,6 +1065,11 @@ static int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp) ...@@ -1018,6 +1065,11 @@ static int fnic_send_frame(struct fnic *fnic, struct fc_frame *fp)
pa = pci_map_single(fnic->pdev, eth_hdr, tot_len, PCI_DMA_TODEVICE); pa = pci_map_single(fnic->pdev, eth_hdr, tot_len, PCI_DMA_TODEVICE);
if ((fnic_fc_trace_set_data(fnic->lport->host->host_no, FNIC_FC_SEND,
(char *)eth_hdr, tot_len)) != 0) {
printk(KERN_ERR "fnic ctlr frame trace error!!!");
}
spin_lock_irqsave(&fnic->wq_lock[0], flags); spin_lock_irqsave(&fnic->wq_lock[0], flags);
if (!vnic_wq_desc_avail(wq)) { if (!vnic_wq_desc_avail(wq)) {
......
...@@ -74,6 +74,11 @@ module_param(fnic_trace_max_pages, uint, S_IRUGO|S_IWUSR); ...@@ -74,6 +74,11 @@ module_param(fnic_trace_max_pages, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(fnic_trace_max_pages, "Total allocated memory pages " MODULE_PARM_DESC(fnic_trace_max_pages, "Total allocated memory pages "
"for fnic trace buffer"); "for fnic trace buffer");
unsigned int fnic_fc_trace_max_pages = 64;
module_param(fnic_fc_trace_max_pages, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(fnic_fc_trace_max_pages,
"Total allocated memory pages for fc trace buffer");
static unsigned int fnic_max_qdepth = FNIC_DFLT_QUEUE_DEPTH; static unsigned int fnic_max_qdepth = FNIC_DFLT_QUEUE_DEPTH;
module_param(fnic_max_qdepth, uint, S_IRUGO|S_IWUSR); module_param(fnic_max_qdepth, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(fnic_max_qdepth, "Queue depth to report for each LUN"); MODULE_PARM_DESC(fnic_max_qdepth, "Queue depth to report for each LUN");
...@@ -1034,11 +1039,20 @@ static int __init fnic_init_module(void) ...@@ -1034,11 +1039,20 @@ static int __init fnic_init_module(void)
/* Allocate memory for trace buffer */ /* Allocate memory for trace buffer */
err = fnic_trace_buf_init(); err = fnic_trace_buf_init();
if (err < 0) { if (err < 0) {
printk(KERN_ERR PFX "Trace buffer initialization Failed " printk(KERN_ERR PFX
"Trace buffer initialization Failed. "
"Fnic Tracing utility is disabled\n"); "Fnic Tracing utility is disabled\n");
fnic_trace_free(); fnic_trace_free();
} }
/* Allocate memory for fc trace buffer */
err = fnic_fc_trace_init();
if (err < 0) {
printk(KERN_ERR PFX "FC trace buffer initialization Failed "
"FC frame tracing utility is disabled\n");
fnic_fc_trace_free();
}
/* Create a cache for allocation of default size sgls */ /* Create a cache for allocation of default size sgls */
len = sizeof(struct fnic_dflt_sgl_list); len = sizeof(struct fnic_dflt_sgl_list);
fnic_sgl_cache[FNIC_SGL_CACHE_DFLT] = kmem_cache_create fnic_sgl_cache[FNIC_SGL_CACHE_DFLT] = kmem_cache_create
...@@ -1119,6 +1133,7 @@ static int __init fnic_init_module(void) ...@@ -1119,6 +1133,7 @@ static int __init fnic_init_module(void)
kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]); kmem_cache_destroy(fnic_sgl_cache[FNIC_SGL_CACHE_DFLT]);
err_create_fnic_sgl_slab_dflt: err_create_fnic_sgl_slab_dflt:
fnic_trace_free(); fnic_trace_free();
fnic_fc_trace_free();
fnic_debugfs_terminate(); fnic_debugfs_terminate();
return err; return err;
} }
...@@ -1136,6 +1151,7 @@ static void __exit fnic_cleanup_module(void) ...@@ -1136,6 +1151,7 @@ static void __exit fnic_cleanup_module(void)
kmem_cache_destroy(fnic_io_req_cache); kmem_cache_destroy(fnic_io_req_cache);
fc_release_transport(fnic_fc_transport); fc_release_transport(fnic_fc_transport);
fnic_trace_free(); fnic_trace_free();
fnic_fc_trace_free();
fnic_debugfs_terminate(); fnic_debugfs_terminate();
} }
......
This diff is collapsed.
...@@ -19,6 +19,17 @@ ...@@ -19,6 +19,17 @@
#define __FNIC_TRACE_H__ #define __FNIC_TRACE_H__
#define FNIC_ENTRY_SIZE_BYTES 64 #define FNIC_ENTRY_SIZE_BYTES 64
#define FC_TRC_SIZE_BYTES 256
#define FC_TRC_HEADER_SIZE sizeof(struct fc_trace_hdr)
/*
* Fisrt bit of FNIC_FC_RECV and FNIC_FC_SEND is used to represent the type
* of frame 1 => Eth frame, 0=> FC frame
*/
#define FNIC_FC_RECV 0x52 /* Character R */
#define FNIC_FC_SEND 0x54 /* Character T */
#define FNIC_FC_LE 0x4C /* Character L */
extern ssize_t simple_read_from_buffer(void __user *to, extern ssize_t simple_read_from_buffer(void __user *to,
size_t count, size_t count,
...@@ -30,6 +41,10 @@ extern unsigned int fnic_trace_max_pages; ...@@ -30,6 +41,10 @@ extern unsigned int fnic_trace_max_pages;
extern int fnic_tracing_enabled; extern int fnic_tracing_enabled;
extern unsigned int trace_max_pages; extern unsigned int trace_max_pages;
extern unsigned int fnic_fc_trace_max_pages;
extern int fnic_fc_tracing_enabled;
extern int fnic_fc_trace_cleared;
typedef struct fnic_trace_dbg { typedef struct fnic_trace_dbg {
int wr_idx; int wr_idx;
int rd_idx; int rd_idx;
...@@ -56,6 +71,16 @@ struct fnic_trace_data { ...@@ -56,6 +71,16 @@ struct fnic_trace_data {
typedef struct fnic_trace_data fnic_trace_data_t; typedef struct fnic_trace_data fnic_trace_data_t;
struct fc_trace_hdr {
struct timespec time_stamp;
u32 host_no;
u8 frame_type;
u8 frame_len;
} __attribute__((__packed__));
#define FC_TRACE_ADDRESS(a) \
((unsigned long)(a) + sizeof(struct fc_trace_hdr))
#define FNIC_TRACE_ENTRY_SIZE \ #define FNIC_TRACE_ENTRY_SIZE \
(FNIC_ENTRY_SIZE_BYTES - sizeof(fnic_trace_data_t)) (FNIC_ENTRY_SIZE_BYTES - sizeof(fnic_trace_data_t))
...@@ -88,4 +113,17 @@ int fnic_debugfs_init(void); ...@@ -88,4 +113,17 @@ int fnic_debugfs_init(void);
void fnic_debugfs_terminate(void); void fnic_debugfs_terminate(void);
int fnic_trace_debugfs_init(void); int fnic_trace_debugfs_init(void);
void fnic_trace_debugfs_terminate(void); void fnic_trace_debugfs_terminate(void);
/* Fnic FC CTLR Trace releated function */
int fnic_fc_trace_init(void);
void fnic_fc_trace_free(void);
int fnic_fc_trace_set_data(u32 host_no, u8 frame_type,
char *frame, u32 fc_frame_len);
int fnic_fc_trace_get_data(fnic_dbgfs_t *fnic_dbgfs_prt, u8 rdata_flag);
void copy_and_format_trace_data(struct fc_trace_hdr *tdata,
fnic_dbgfs_t *fnic_dbgfs_prt,
int *len, u8 rdata_flag);
int fnic_fc_trace_debugfs_init(void);
void fnic_fc_trace_debugfs_terminate(void);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment