/**create by hans*/ #include #include #include #include #include #include #include #include #include #include #include "commDebug.h" #include #include "qe8Stress.h" /* Function prototype */ struct seq_file; STATIC INT32 sysStressProcPermission(struct inode *inode, INT32 op); STATIC ssize_t sysStressProcRead(struct file *file, char *buf, size_t size, loff_t *offset); STATIC INT32 sysStressProcOpen(struct inode *inode, struct file *file); STATIC INT32 sysStressProcIoctl(struct inode *inode, struct file *file, UINT32 cmd, unsigned long arg); STATIC INT32 sysStressProcClose(struct inode *inode, struct file *file); #if 0 extern void qe8GetStressPortErrCnt(unsigned int port_idx, unsigned int *link_status1, unsigned int *link_status2); #endif /* Local variable */ STATIC BOOLEAN s_sysStress_opened = FALSE; STATIC UINT8 *s_pro_buffer = NULL; pid_t g_sysStressd_pid = 0; EXPORT_SYMBOL(g_sysStressd_pid); int g_sysStressInitFlag=0; int g_qe8SFPdevID=0; int g_qe8ErrCntPortID=0; extern unsigned int g_peer_qe8_cnt; extern int ssFun_SeqRelease(struct inode *inode, struct file *file); static struct inode_operations s_sysStress_proc_iops = { .permission = sysStressProcPermission, }; static struct file_operations s_sysStress_proc_fops = { .read = sysStressProcRead, .open = sysStressProcOpen, #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) .ioctl = sysStressProcIoctl, #else .unlocked_ioctl = sysStressProcIoctl, #endif .release = sysStressProcClose, }; STATIC INT32 sysStressProcPermission(struct inode *inode, INT32 op) { if (!s_sysStress_opened) return (0); else return (-EBUSY); } STATIC INT32 sysStressProcOpen(struct inode *inode, struct file *file) { if (!s_sysStress_opened) s_sysStress_opened = TRUE; else ASSERT(0); return(0); } STATIC INT32 sysStressProcClose(struct inode *inode, struct file *file) { if (s_sysStress_opened) s_sysStress_opened = FALSE; else ASSERT(0); return(0); } STATIC ssize_t sysStressProcRead(struct file *file, char *buf, size_t size, loff_t *offset) { printk("sysStress Programming Interface\n"); return (0); } STATIC INT32 sysStressProcIoctl(struct inode *inode, struct file *file, UINT32 cmd, unsigned long arg) { VOID __user *uarg = (VOID __user*)arg; switch (cmd) { case SYSSTRESS_CPI_CMD_IO: if (copy_from_user(&g_sysStressd_pid, uarg, sizeof(pid_t))) return (-EFAULT); printk("[%s]sysStressd pid: %d\n", __func__, g_sysStressd_pid); break; default: return (-EINVAL); } return(0); } STATIC INT32 sysStressProcInit(VOID) { struct proc_dir_entry *entry; entry = create_proc_entry("sysStress_cpi", 0644, NULL); if (!entry) return -ENOMEM; entry->proc_iops = &s_sysStress_proc_iops; entry->proc_fops = &s_sysStress_proc_fops; return (0); } #if 0 /*fcinfo*/ static proc_fc_status_t port_info; static void *fc_start(struct seq_file *m, loff_t *pos) { extern int qe8GetStressPortSpeed(unsigned int port_idx); if ( (*pos) < g_local_qe8_cnt ) { port_info.speed = qe8GetStressPortSpeed(*pos); // qe8GetStressPortErrCnt((*pos), &port_info.link_status1, &port_info.link_status2); port_info.idx = (*pos); return &port_info; } return NULL; } static void *fc_next(struct seq_file *m, void *v, loff_t *pos) { (*pos)++; return (fc_start(m,pos)); } static void fc_stop(struct seq_file *m, void *v) { } static int show_fcinfo(struct seq_file *m, void *v) { extern bool qe8TestPortDis(uint32_t port_idx); extern bit32 qe8StressPortStatus(uint32_t port_idx); proc_fc_status_t *c=v; if ( c->idx == 0 ) seq_printf(m, "g_local_qe8_cnt=%d\n", g_local_qe8_cnt); seq_printf(m,"#****************************************#\n"); if( qe8TestPortDis(c->idx)){ seq_printf(m,"PortEnable%d=\"Disable\"\n", c->idx); }else{ seq_printf(m,"PortEnable%d=\"Enable\"\n", c->idx); } switch (qe8StressPortStatus(c->idx)){ case PORT_STATE_STOP: seq_printf(m,"PortStatus%d=\"STOP\"\n", c->idx); break; case PORT_STATE_DOWN: seq_printf(m,"PortStatus%d=\"DOWN\"\n", c->idx); break; case PORT_STATE_UP: seq_printf(m,"PortStatus%d=\"UP\"\n", c->idx); break; case PORT_STATE_READY: seq_printf(m,"PortStatus%d=\"READY\"\n", c->idx); break; case PORT_STATE_RESETTING: seq_printf(m,"PortStatus%d=\"RESETTING\"\n", c->idx); break; default: seq_printf(m,"PortStatus%d=\"UNKNOW\"\n", c->idx); } seq_printf(m,"PortSpeed%d=%d\n", c->idx, c->speed); #if 0 seq_printf(m,"badRxChar_P%d=%d\n", c->idx, ( c->link_status1 & 0x00ff0000 >> 16 )); seq_printf(m,"lossOfSync_P%d=%d\n", c->idx, ( c->link_status1 & 0x0000ff00 >> 8 )); seq_printf(m,"discard_P%d=%d\n", c->idx,( c->link_status2 & 0x00ff0000 >> 16 )); seq_printf(m,"protoErr_P%d=%d\n", c->idx, ( c->link_status2 & 0x000000ff)); seq_printf(m,"lossOfSingnal_P%d=%d\n", c->idx, ( c->link_status1 & 0xff000000 >> 24 )); seq_printf(m,"badCRC_P%d=%d\n", c->idx, ( c->link_status2 & 0x0000ff00 >> 8 )); seq_printf(m,"RxEOFa_P%d=%d\n", c->idx, ( c->link_status2 & 0xff000000 >> 24 )); seq_printf(m,"linkFail_P%d=%d\n", c->idx, ( c->link_status1 & 0x000000ff)); #endif return 0; } const struct seq_operations fcinfo_op = { .start = fc_start, .next = fc_next, .stop = fc_stop, .show = show_fcinfo, }; static int fcinfo_open(struct inode *inode, struct file *file) { return seq_open(file, &fcinfo_op); } static const struct file_operations proc_fcinfo_operations = { .open = fcinfo_open, .release = ssFun_SeqRelease, .read = seq_read, }; #if 0 static int fcInfoProcInit(void) { struct proc_dir_entry *entry; entry = proc_create("fcinfo", 0444, NULL, &proc_fcinfo_operations); if (!entry) return -ENOMEM; return 0; } /*fcinfo end*/ #endif /*fcPar*/ extern fc_stress_Param_t g_local_fc_stress_param; static void *fcParStart(struct seq_file *m, loff_t *pos) { if ( *pos == 0 ) { return &g_local_fc_stress_param; } return NULL; } static void *fcParNext(struct seq_file *m, void *v, loff_t *pos) { (*pos)++; return (fcParStart(m,pos)); } static void fcParStop(struct seq_file *m, void *v) { } static int show_fcPar(struct seq_file *m, void *v) { fc_stress_Param_t *c=v; int i; seq_printf(m,"g_peer_qe8_cnt=%d\n",g_peer_qe8_cnt); for ( i=0; i<8; i++) { seq_printf(m,"g_fc_stress_channel%d=%d\n",i,c->channel[i]); } seq_printf(m,"times=%d\n",c->times); seq_printf(m,"blockSize=%d\n",c->BS); seq_printf(m,"speed=%d\n",c->speed); seq_printf(m,"pattern=\"0x%x\"\n",c->pattern); seq_printf(m,"SOE=%d\n",c->SOE); // if (c->dv == 0) // { seq_printf(m,"dv=\"NO\"\n"); } // else // { seq_printf(m,"dv=\"YES\"\n"); } seq_printf(m,"DV=%d\n",c->dv); return 0; } const struct seq_operations fcPar_op = { .start = fcParStart, .next = fcParNext, .stop = fcParStop, .show = show_fcPar, }; static int fcPar_open(struct inode *inode, struct file *file) { return seq_open(file, &fcPar_op); } static const struct file_operations proc_fcPar_operations = { .open = fcPar_open, .release = ssFun_SeqRelease, .read = seq_read, }; #if 0 static int fcParProcInit(void) { struct proc_dir_entry *entry; entry = proc_create("fcPar", 0444, NULL, &proc_fcPar_operations); if (!entry) return -ENOMEM; return 0; } /*fcPar end*/ #endif /* fc SFP device show*/ static void *fcSFPdev_start(struct seq_file *m, loff_t *pos) { if ( *pos == 0 ) { return &g_local_fc_stress_param; } return NULL; } static void *fcSFPdev_next(struct seq_file *m, void *v, loff_t *pos) { (*pos)++; return (fcSFPdev_start(m,pos)); } static void fcSFPdev_stop(struct seq_file *m, void *v) { } extern int qe8SFPread(int AdapID, uint8_t *data, int len); extern int qe8HICSFPread(int AdapID, uint8_t *data, int len); static int show_fcSFPdev(struct seq_file *m, void *v) { uint8_t data; int idx=0,cnt=0; int ret=0; while ( idx < 8 ) { if ( idx < 4 ){ ret = qe8SFPread(idx, &data, 1); cnt++; }else{ ret = qe8HICSFPread(( idx-4 ), &data, 1); cnt++; } if( cnt == 0 ) { seq_printf(m,"No SFP device found\n"); return 0; } if ( ret == 0 ) seq_printf(m,"HostSFP%d\n",idx); idx++; } return 0; } const struct seq_operations fcSFPdev_op = { .start = fcSFPdev_start, .next = fcSFPdev_next, .stop = fcSFPdev_stop, .show = show_fcSFPdev, }; static int fcSFPdev_open(struct inode *inode, struct file *file) { return seq_open(file, &fcSFPdev_op); } static const struct file_operations proc_fcSFPdev_operations = { .open = fcSFPdev_open, .release = ssFun_SeqRelease, .read = seq_read, }; #if 0 static int fcSFPdevProcInit(void) { struct proc_dir_entry *entry; entry = proc_create("fcSFPdev", 0444, NULL, &proc_fcSFPdev_operations); if (!entry) return -ENOMEM; return 0; } /* fc SFP device show end*/ #endif /* fc error count show*/ static void *fcErrCnt_start(struct seq_file *m, loff_t *pos) { if ( *pos == 0 ) { return &g_local_fc_stress_param; } return NULL; } static void *fcErrCnt_next(struct seq_file *m, void *v, loff_t *pos) { (*pos)++; return (fcErrCnt_start(m,pos)); } static void fcErrCnt_stop(struct seq_file *m, void *v) { } #define qe8ErrCnt_S struct qe8ErrCnt_Structure qe8ErrCnt_S { uint8_t NumLinkDowns; uint8_t NumBadChar; uint8_t NumBadFrames; uint8_t lossOfSync; uint8_t protoErr; uint8_t lossOfSingnal; uint8_t badCRC; uint8_t RxEOFa; }; qe8ErrCnt_S qe8ErrCntData[8]; qe8ErrCnt_S qe8ErrCntData_PEER[8]; void fcFillErrCnt_ToData(void *data) { memcpy(data, (void *)qe8ErrCntData, 8*sizeof(qe8ErrCnt_S)); } void fcFillErrCnt_PEERFromData(void *data) { memcpy((void *)qe8ErrCntData_PEER, data, 8*sizeof(qe8ErrCnt_S)); } void fcErrCntClean(int port) { /* int i; for (i=0; i<8; i++){ qe8ErrCntData[port].NumLinkDowns=0; qe8ErrCntData[port].NumBadChar=0; qe8ErrCntData[port].NumBadFrames=0; qe8ErrCntData[port].lossOfSync=0; qe8ErrCntData[port].protoErr=0; qe8ErrCntData[port].lossOfSingnal=0; qe8ErrCntData[port].badCRC=0; qe8ErrCntData[port].RxEOFa=0; } */ memset((void *)&qe8ErrCntData[port], 0, sizeof(qe8ErrCnt_S)); } void fcAllErrCntClean(void) { memset((void *)qe8ErrCntData, 0, 8*sizeof(qe8ErrCnt_S)); memset((void *)qe8ErrCntData_PEER, 0, 8*sizeof(qe8ErrCnt_S)); } int g_qe8NewErr; void fcErrCntUpdate(int port) { unsigned int link_status1, link_status2, errCnt; qe8ErrCnt_S *errInfo; g_qe8NewErr=0; if ( port > g_local_qe8_cnt) return; qe8GetStressPortErrCnt(port, &link_status1, &link_status2); errInfo=&qe8ErrCntData[port]; errCnt=(link_status1 & 0x000000ff) ; errInfo->NumLinkDowns +=errCnt; g_qe8NewErr+=errCnt; errCnt=(link_status1 & 0x0000ff00) >> 8 ; errInfo->lossOfSync +=errCnt; g_qe8NewErr+=errCnt; errCnt=(link_status1 & 0x00ff0000) >> 16; errInfo->NumBadChar +=errCnt; g_qe8NewErr+=errCnt; errCnt=(link_status1 & 0xff000000) >> 24; errInfo->lossOfSingnal+=errCnt; g_qe8NewErr+=errCnt; errCnt=(link_status2 & 0x000000ff) ; errInfo->protoErr +=errCnt; g_qe8NewErr+=errCnt; errCnt=(link_status2 & 0x0000ff00) >> 8 ; errInfo->badCRC +=errCnt; g_qe8NewErr+=errCnt; errCnt=(link_status2 & 0x00ff0000) >> 16; errInfo->NumBadFrames +=errCnt; g_qe8NewErr+=errCnt; errCnt=(link_status2 & 0xff000000) >> 24; errInfo->RxEOFa +=errCnt; g_qe8NewErr+=errCnt; } static int show_fcErrCnt(struct seq_file *m, void *v) { qe8ErrCnt_S *errInfo; if ( g_qe8ErrCntPortID < 8 ) { if ( g_qe8ErrCntPortID >= g_local_qe8_cnt ) return 0; fcErrCntUpdate(g_qe8ErrCntPortID); errInfo=&qe8ErrCntData[g_qe8ErrCntPortID]; } else { g_qe8ErrCntPortID -=8; if ( g_qe8ErrCntPortID >= g_local_qe8_cnt ) return 0; errInfo=&qe8ErrCntData_PEER[g_qe8ErrCntPortID]; } seq_printf(m,"NumLinkDowns=%d\n", errInfo->NumLinkDowns); seq_printf(m,"NumBadChar=%d\n", errInfo->NumBadChar); seq_printf(m,"NumBadFrames=%d\n", errInfo->NumBadFrames); seq_printf(m,"lossOfSync=%d\n", errInfo->lossOfSync); seq_printf(m,"protoErr=%d\n", errInfo->protoErr); seq_printf(m,"lossOfSingnal=%d\n", errInfo->lossOfSingnal); seq_printf(m,"badCRC=%d\n", errInfo->badCRC); seq_printf(m,"RxEOFa=%d\n", errInfo->RxEOFa); return 0; } const struct seq_operations fcErrCnt_op = { .start = fcErrCnt_start, .next = fcErrCnt_next, .stop = fcErrCnt_stop, .show = show_fcErrCnt, }; static int fcErrCnt_open(struct inode *inode, struct file *file) { return seq_open(file, &fcErrCnt_op); } static const struct file_operations proc_fcErrCnt_operations = { .open = fcErrCnt_open, .release = ssFun_SeqRelease, .read = seq_read, }; #if 0 static int fcErrCntProcInit(void) { struct proc_dir_entry *entry; fcAllErrCntClean(); entry = proc_create("fcErrCnt", 0444, NULL, &proc_fcErrCnt_operations); if (!entry) return -ENOMEM; return 0; } /* fc error count show end*/ #endif /* fc SFP DATA show*/ static void *fcSFPdata_start(struct seq_file *m, loff_t *pos) { if ( *pos == 0 ) { return &g_local_fc_stress_param; } return NULL; } static void *fcSFPdata_next(struct seq_file *m, void *v, loff_t *pos) { (*pos)++; return (fcSFPdata_start(m,pos)); } static void fcSFPdata_stop(struct seq_file *m, void *v) { } static int show_fcSFPdata(struct seq_file *m, void *v) { uint8_t data[256],buf[256]; int idx=0,ret=0; if ( g_qe8ErrCntPortID > g_local_qe8_cnt) return 0; if ( g_qe8SFPdevID < 4 ){ ret = qe8SFPread(g_qe8SFPdevID, data, 256); }else{ ret = qe8HICSFPread(( g_qe8SFPdevID-4 ), data, 256); } if ( ret != 0 ){ seq_printf(m,"HostSFP%d: FAILED �V SFP DOES NOT SUPPORT DIAGNOSTIC DATA REGION\n",g_qe8SFPdevID); return 0; } for ( idx=0; idx<256 ; idx=(idx+16) ){ memset(buf,0,256); sprintf(buf,"+%04x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x ",idx,data[idx],data[idx+1],data[idx+2],data[idx+3],data[idx+4],data[idx+5],data[idx+6],data[idx+7],data[idx+8],data[idx+9],data[idx+10],data[idx+11],data[idx+12],data[idx+13],data[idx+14],data[idx+15]); seq_printf(m,"%s\n",buf); } return 0; } const struct seq_operations fcSFPdata_op = { .start = fcSFPdata_start, .next = fcSFPdata_next, .stop = fcSFPdata_stop, .show = show_fcSFPdata, }; static int fcSFPdata_open(struct inode *inode, struct file *file) { return seq_open(file, &fcSFPdata_op); } static const struct file_operations proc_fcSFPdata_operations = { .open = fcSFPdata_open, .release = ssFun_SeqRelease, .read = seq_read, }; static int fcSFPdataProcInit(void) { struct proc_dir_entry *entry; entry = proc_create("fcSFPdata", 0444, NULL, &proc_fcSFPdata_operations); if (!entry) return -ENOMEM; return 0; } /* fc SFP DATA show end*/ /* fc SFP VPD DATA show*/ static int show_fcSFPVPDdata(struct seq_file *m, void *v) { uint8_t data[256]; char pn[16],sn[16],vn[16],dt[8]; int ret=0; if ( g_qe8ErrCntPortID > g_local_qe8_cnt) return 0; if ( g_qe8SFPdevID < 4 ){ ret = qe8SFPread(g_qe8SFPdevID, data, 256); }else{ ret = qe8HICSFPread(( g_qe8SFPdevID-4 ), data, 256); } if ( ret != 0 ){ seq_printf(m,"PN=\"\"\n"); seq_printf(m,"SN=\"\"\n"); seq_printf(m,"VN=\"\"\n"); seq_printf(m,"DN=\"\"\n"); //seq_printf(m,"FAILED - TRAY NOT FOUND\n"); return 0; } strncpy(pn, &data[40], 16); strncpy(sn, &data[68], 16); strncpy(vn, &data[20], 16); strncpy(dt, &data[84], 8); pn[15]='\0'; sn[15]='\0'; vn[15]='\0'; dt[7]='\0'; seq_printf(m,"PN=\"%s\"\n",pn); seq_printf(m,"SN=\"%s\"\n",sn); seq_printf(m,"VN=\"%s\"\n",vn); seq_printf(m,"DN=\"%s\"\n",dt); return 0; } const struct seq_operations fcSFPVPDdata_op = { .start = fcSFPdata_start, .next = fcSFPdata_next, .stop = fcSFPdata_stop, .show = show_fcSFPVPDdata, }; static int fcSFPVPDdata_open(struct inode *inode, struct file *file) { return seq_open(file, &fcSFPVPDdata_op); } static const struct file_operations proc_fcSFPVPDdata_operations = { .open = fcSFPVPDdata_open, .release = ssFun_SeqRelease, .read = seq_read, }; static int fcSFPVPDdataProcInit(void) { struct proc_dir_entry *entry; entry = proc_create("fcSFPVPDdata", 0444, NULL, &proc_fcSFPVPDdata_operations); if (!entry) return -ENOMEM; return 0; } #endif /* fc SFP VPD DATA show end*/ INT32 sysStressInit(VOID) { sysStressProcInit(); #if 0 fcInfoProcInit(); fcParProcInit(); fcSFPdevProcInit(); fcSFPdataProcInit(); fcSFPVPDdataProcInit(); fcErrCntProcInit(); #endif return (0); } VOID sysStressExit(VOID) { if (s_pro_buffer) kfree(s_pro_buffer); remove_proc_entry("sysStress_cpi", NULL); }