/* * SUNI device utility program * * for PMC-Sierra PM5384 SONET/SDH device. * * This is a user-space program to control, configure and monitor the device and its * driver. * * Certain operations communicate directly to the hardware (e.g. read/write), so as to be * able to debug the driver itself, or not use one at all. The rest of the operations * are implemented through the driver via ioctl calls. * * A.Fornaro, afor@intracom.gr * January 2004 * * A. Zeffertt * October 2005 * * To Build: * ppc_6xx-gcc -o pm5384_ctrl pm5384_ctrl.c -I$PATH_TO_KERNEL/include * * To install: * cp pm5384_ctrl /usr/bin */ /* * ATTENTION: This file requires an updated * You should be able to get it from the same place you got this file. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* Defines where PM5384 memory is mapped to in kernel */ static int fd; static unsigned char * map_mem() { unsigned char * reg_base; if ( (fd = open("/dev/mem",O_RDWR)) == -1) { perror("open /dev/mem error"); exit(1); } if ((reg_base = mmap(0, 0x145, PROT_READ | PROT_WRITE, MAP_SHARED, fd, CONFIG_PM5384_BASE)) == MAP_FAILED) { perror("mmap error"); exit(1); } return reg_base; } static unsigned long unmap_mem() { close(fd); } static int connectSocket() { struct sockaddr_atmpvc addr; int s; memset(&addr,0,sizeof(addr)); addr.sap_family = AF_ATMPVC; addr.sap_addr.itf = 0; addr.sap_addr.vpi = 0; addr.sap_addr.vci = 25; /* Open a socket to the ATM module */ if ((s = socket(PF_ATMPVC, SOCK_DGRAM, 0)) < 0) { //printf("error: could not open socket\n"); return -1; } return s; } static void showInfo() { unsigned char *reg_base; unsigned char byteValue = 0; int s; struct atmif_sioc req; int query=1; int set; struct sonet_stats stats; reg_base = map_mem(); byteValue = reg_base[0x11]; if (byteValue & 0x04) printf("Signal: LOS alarm\n"); else printf("Signal: OK\n"); if (byteValue & 0x01) printf("Framer: Out-of-frame state\n"); else if (byteValue & 0x02) printf("Framer: LOF alarm\n"); else printf("Framer: OK\n"); byteValue = reg_base[0x64] ; if (byteValue & 0x80) printf("Cell delineation state: HUNT or PRESYNC\n"); else printf("Cell delineation state: SYNC\n"); printf("\n"); unmap_mem(); /* Connect to the driver */ s = connectSocket(); if (s==-1) { printf("Failed to connect to the driver. Aborting...\n"); exit(1); } req.number = 0; /* Get frame mode */ req.arg = &set; req.length = sizeof(set); if (ioctl(s, SONET_GETFRAMING, &req) < 0) { printf("Error: ioctl failed: %s. Aborting\n", strerror(errno)); exit(1); } if (set==SONET_FRAME_SDH) printf("SDH Mode of operation.\n"); else printf("SONET Mode of operation.\n"); /* Get loopback mode */ req.arg = &set; req.length = sizeof(set); if (ioctl(s, SONET_GETLOOP, &req) < 0) { printf("Error: ioctl failed: %s. Aborting\n", strerror(errno)); exit(1); } if (set==ATM_LM_NONE) printf("Normal Operation (no loopback).\n"); else if (set==ATM_LM_LOC_PHY) printf("Internal loopback mode.\n"); else if (set==ATM_LM_RMT_PHY) printf("Echo loopback mode.\n"); /* Get diagnostic information */ req.arg = &set; req.length = sizeof(set); if (ioctl(s, SONET_GETDIAG, &req) < 0) { printf("Error: ioctl failed: %s. Aborting\n", strerror(errno)); exit(1); } if (set==0) printf("No diagnostics (error insertions) are enabled.\n\n"); else printf("Diagnostics: %d\n\n", set); /* Get statistics */ req.arg = &stats; req.length = sizeof(stats); if (ioctl(s, SONET_GETSTAT, &req) < 0) { printf("Error: ioctl failed: %s. Aborting\n", strerror(errno)); exit(1); } if (stats.section_bip != -1) printf("Section BIP errors: %10d\n",stats.section_bip); if (stats.line_bip != -1) printf("Line BIP errors: %10d\n",stats.line_bip); if (stats.path_bip != -1) printf("Path BIP errors: %10d\n",stats.path_bip); if (stats.line_febe != -1) printf("Line FEBE: %10d\n",stats.line_febe); if (stats.path_febe != -1) printf("Path FEBE: %10d\n",stats.path_febe); if (stats.uncorr_hcs != -1) printf("Uncorrectable HCS: %10d\n",stats.uncorr_hcs); if (stats.tx_cells != -1) printf("TX cells: %10d\n",stats.tx_cells); if (stats.rx_cells != -1) printf("RX cells: %10d\n",stats.rx_cells); if (stats.idle_rx_cells != -1) printf("Idle RX cells: %10d\n",stats.idle_rx_cells); close(s); exit(0); } static void read_reg(unsigned int address) { unsigned char *reg_base; unsigned char byteValue = 0; reg_base = map_mem(); byteValue = reg_base[address]; printf("Register at 0x%x is 0x%x \n\n", address, byteValue); unmap_mem(); exit(0); } static void read_regs(unsigned int address, int count) { unsigned char *reg_base; unsigned char byteValue = 0; int i; reg_base = map_mem(); for (i=0;i<=count-1;i++) { byteValue = reg_base[address + i]; printf("0x%x \t 0x%x \n", address+i, byteValue); } printf("\n"); unmap_mem(); exit(0); } static void write_reg(unsigned int address, int value) { unsigned char *reg_base; unsigned char byteValue = 0; reg_base = map_mem(); reg_base[address] = (unsigned char) value; printf("Register at 0x%x written with 0x%x \n\n", address, value); unmap_mem(); exit(0); } static void set_loop(char *mode) { int s; struct atmif_sioc req; int set; /* Connect to the driver */ s = connectSocket(); if (s==-1) { printf("Failed to connect to the driver. Aborting...\n"); exit(1); } req.number = 0; /* Set loopback mode */ if (!strcmp(mode,"noloop")) set = ATM_LM_NONE; else if (!strcmp(mode,"iloop")) set = ATM_LM_LOC_PHY; else if (!strcmp(mode,"eloop")) set = ATM_LM_RMT_PHY; else { printf("Invalid loopback mode. Aborting...\n"); exit(1); } req.arg = (void *) set; req.length = 0; if (ioctl(s, SONET_SETLOOP, &req) < 0) { printf("Error: ioctl failed: %s. Aborting\n", strerror(errno)); exit(1); } printf("Loopback mode was set to %s.\n", mode); close(s); exit(0); } static void set_frame(char *mode) { int s; struct atmif_sioc req; int frame; /* Connect to the driver */ s = connectSocket(); if (s==-1) { printf("Failed to connect to the driver. Aborting...\n"); exit(1); } req.number = 0; /* Set framing format */ if (!strcmp(mode,"sdh")) frame = SONET_FRAME_SDH; else frame = SONET_FRAME_SONET; req.arg = (void *) frame; req.length = 0; if (ioctl(s, SONET_SETFRAMING, &req) < 0) { printf("Error: ioctl failed: %s. Aborting\n", strerror(errno)); exit(1); } printf("Frame Mode of Operation was set to %s.\n", mode); close(s); exit(0); } static void clear_stats() { int s; struct atmif_sioc req; int frame; /* Connect to the driver */ s = connectSocket(); if (s==-1) { printf("Failed to connect to the driver. Aborting...\n"); exit(1); } req.number = 0; req.arg = 0; req.length = 0; if (ioctl(s, SONET_CLRSTAT, &req) < 0) { printf("Error: ioctl failed: %s. Aborting\n", strerror(errno)); exit(1); } printf("Counters were cleared.\n"); close(s); exit(0); } static void usage(const char *name) { printf("Usage: %s \t Display status and statistics \n", name); printf("\t -r address [count] \t Read device register(s), `count` in a row (omit for 1) \n"); printf("\t -w address value \t Write device register\n"); printf("\t -l mode \t\t Set loopback mode:\n"); printf("\t\t\t\t\t no loopback = \"noloop\"\n"); printf("\t\t\t\t\t internal loopback = \"iloop\"\n"); printf("\t\t\t\t\t echo loopback = \"eloop\"\n"); printf("\t -f mode \t\t Set frame mode:\n"); printf("\t\t\t\t SDH = \"sdh\"\n"); printf("\t\t\t\t SONET = \"sonet\"\n"); printf("\t -c \t\t\t Clear counters\n"); exit(1); } int getNumber(char * str) { char *newStr; int newInt; if ( (str[0]=='0') && (str[1]=='x') ) { sscanf(str, "%x", &newInt); return newInt; } else return atoi(str); } int main(int argc,char **argv) { const char *name; printf("\nSUNI Control Utility - PM 5384 \n\n"); name = argv[0]; if (argc==1) showInfo(); if (argv[1][0] != '-') usage(name); if (argv[1][0] == '-') { if (argv[1][1] == 'r') { if (argc==3) read_reg(getNumber(argv[2])); if (argc==4) read_regs(getNumber(argv[2]), getNumber(argv[3]) ); usage(name); } if (argv[1][1] == 'w') { if (argc!=4) usage(name); else write_reg(getNumber(argv[2]), getNumber(argv[3])); } if (argv[1][1] == 'l') { if (argc!=3) usage(name); else set_loop(argv[2]); } if (argv[1][1] == 'f') { if (argc!=3) usage(name); else set_frame(argv[2]); } if (argv[1][1] == 'c') { if (argc!=2) usage(name); else clear_stats(); } usage(name); } }