#include <linux/kconfig.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> #include <bspgpio.h> #include "xdsl_ctrl.h" #if defined(ERB_DEBUG) //To-Do: create a proc to control erb_debug int erb_debug = 1; static const char *cate_name[] = { "CTRL_2DSL_SET", "CTRL_2DSL_GET", "CTRL_2SOC_RET", "CTRL_2MASTER_SET", "CTRL_2MASTER_GET", "CTRL_2SLAVE_RET", }; static const char *proto_name[] = { "XDSL_CMD_SET", "XDSL_CMD_GET", "XDSL_CMD_DATA", "XDSL_CMD_DATA_EOF", "XDSL_ERB_SET", "PTM_CMD_SET", "PTM_CMD_GET" }; void dump_rxbuf(unsigned char *b, int l) { unsigned char *byte; int i; if (!erb_debug) return; //dump rxbuf byte = b; printk("rxbuf (total: %d bytes):", l); for(i = 0; i < l; i++) { if (!(i%16)) printk("\n"); printk("%02x ", byte[i]); } printk("\n\n"); } void dump_ctrlp(ctrl_pkt_t *p) { int i; unsigned char *byte; if (!erb_debug) return; printk("ctrlp->devnum: %d\n", p->devnum); printk("ctrlp->category: %s\n", cate_name[p->category]); printk("ctrlp->protocol: %s\n", proto_name[p->protocol]); printk("ctrlp->command: %d\n", p->command); printk("ctrlp->argsize: %d\n", p->argsize); printk("ctrlp->msg: 0x%x\n", p->msg); //dump arg array byte = p->arg; printk("ctrlp->arg:"); for(i = 0; i < 96; i++) { if (!(i%16)) printk("\n"); printk("%02x ", byte[i]); } printk("\n"); printk("ctrlp->ret: %d\n", p->ret); //dump rxbuf byte = p->rxbuf; printk("ctrlp->rxbuf:"); for(i = 0; i < 96; i++) { if (!(i%16)) printk("\n"); printk("%02x ", byte[i]); } printk("\n\n"); } #endif #if defined(CONFIG_PTM_BONDING_MASTER) static int erbTester_proc_read(struct seq_file *f, void *data) { seq_printf(f, "erb proc read\n"); return 0; } int erbTester_proc_write(struct file *file, const char *buffer, unsigned long count, void *data) { char proc_buffer[count+1]; char *strptr; char *cmdptr; /* write data to the buffer */ memset(proc_buffer, 0, sizeof(proc_buffer)); if ( copy_from_user(proc_buffer, buffer, count) ) { return -EFAULT; } proc_buffer[count] = '\0'; strptr = proc_buffer; if (strlen(strptr) == 0) { goto errout; } cmdptr = strsep(&strptr," "); if (cmdptr==NULL) { goto errout; } //int re865x_send_ERB(char* ERB_data, int ERB_data_len, int line_id,int sync_symbol_count,int segment_code,unsigned char* VCE_macaddr) /*parse command*/ if (strncmp(cmdptr, "1",1) == 0) { //xdsl_ctrl_erb_init(); }; errout: return count; } static int read_proc_open_erbTester(struct inode *inode, struct file *file) { return(single_open(file, erbTester_proc_read, NULL)); } static ssize_t write_proc_erbTester(struct file *file, const char __user * userbuf, size_t count, loff_t * off) { return erbTester_proc_write(file, userbuf, count, NULL); } static struct file_operations fops_erbTester = { .open = read_proc_open_erbTester, .read = seq_read, .llseek = seq_lseek, .release = single_release, .write = write_proc_erbTester, }; void erbTester_proc_init(void) { struct proc_dir_entry *entry; entry = proc_create_data("erbTester", 0644, NULL, &fops_erbTester, NULL); if (!entry) printk("\n\n proc entry erbTester created fail!\n\n"); } #elif defined(CONFIG_PTM_BONDING_SLAVE) extern struct mutex slave_dsl_mutex; static int erb_send_cnt = 0; /* * Called by DSL driver to send ERB Ethernet packet in G.Vector mode. * It is actually a wrapper for nfbi tx. */ int re865x_send_ERB(char* ERB_data, int ERB_data_len ,int line_id,int sync_symbol_count,int segment_code,unsigned char* VCE_macaddr) { extern int xdsl_ctrl_tx_final(uint8 category, uint8 protocol, uint8 devnum, uint32 command, uint32 arg, uint32 argsize, uint32 ret, uint32 seg_num); unsigned char *data; unsigned char dev_addr[6] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; ERB_header_t* ERB_header_p; int len = ((ERB_data_len+27)>=60)?(ERB_data_len+27):60; static int should_interrupt = 0; erb_printk("alloc data for ERB, len = %d, ERB_data_len (from DSP) = %d, (total %d times)\n", len, ERB_data_len, erb_send_cnt); data= (unsigned char*)kmalloc(len, GFP_KERNEL); if(!data) { printk("[%s] unalbe to alloc data buf for ERB\n", __func__); return 0; } memset(data, 0, len); /* header */ ERB_header_p = (ERB_header_t*)(&data[0]); memcpy(ERB_header_p->VCE_macaddr,VCE_macaddr,6); memcpy(ERB_header_p->VTU_R_macaddr,dev_addr,6); *(unsigned short *)(&ERB_header_p->length) = len-14; // L2 header ERB_header_p->LLC_header[0] = 0xAA; ERB_header_p->LLC_header[1] = 0xAA; ERB_header_p->LLC_header[2] = 0x03; ERB_header_p->ITU_T[0] = 0x00; ERB_header_p->ITU_T[1] = 0x19; ERB_header_p->ITU_T[2] = 0xA7; ERB_header_p->protocol_id[0] = 0x00; ERB_header_p->protocol_id[1] = 0x03; *(unsigned short *)(&ERB_header_p->line_id) =(unsigned short)(line_id&0xFFFF); *(unsigned short *)(&ERB_header_p->sync_sumbol_count) =(unsigned short)(sync_symbol_count&0xFFFF); ERB_header_p->segment_code =segment_code&0xFF; /*payload*/ if ((ERB_data != NULL) && (&(data[27]) != NULL)) memcpy(&(data[27]),ERB_data,ERB_data_len); else printk("[%s] some data ptr is NULL\n", __func__); /*send to master*/ mutex_lock(&slave_dsl_mutex); xdsl_ctrl_tx_final(CTRL_2MASTER_SET, XDSL_ERB_SET, 1, 0, data, len, 0, 0); mutex_unlock(&slave_dsl_mutex); /*free data since we've transmitted it to Master*/ kfree(data); erb_send_cnt++; return 0; } static int erbTester_proc_read(struct seq_file *f, void *data) { seq_printf(f, "erb packet sent: %d\n", erb_send_cnt); return 0; } const char erb_dummy_data0[] = { 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21 }; const char erb_dummy_mac0[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x11 }; const char erb_dummy_data1[] = { 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x5a, 0x5a, 0xa5, 0xa5, 0xbe, 0xef, 0xca, 0xfe, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21, 0x6b, 0x49, 0xc7, 0xd8, 0xad, 0xde, 0xca, 0xfe, 0x01, 0x23, 0x45, 0x67, 0xab, 0xcd, 0xef, 0xcc, 0x6b, 0x49, 0xc7, 0xd8, 0xad, 0xde, 0xca, 0xfe, 0x01, 0x23, 0x45, 0x67, 0xab, 0xcd, 0xef, 0xcc, 0x6b, 0x49, 0xc7, 0xd8, 0xad, 0xde, 0xca, 0xfe, 0x01, 0x23, 0x45, 0x67, 0xab, 0xcd, 0xef, 0xcc, 0x6b, 0x49, 0xc7, 0xd8, 0xad, 0xde, 0xca, 0xfe, 0x01, 0x23, 0x45, 0x67, 0xab, 0xcd, 0xef, 0xcc, 0x6b, 0x49, 0xc7, 0xd8, 0xad, 0xde, 0xca, 0xfe, 0x01, 0x23, 0x45, 0x67, 0xab, 0xcd, 0xef, 0xcc, 0x6b, 0x49, 0xc7, 0xd8, 0xad, 0xde, 0xca, 0xfe, 0x01, 0x23, 0x45, 0x67, 0xab, 0xcd, 0xef, 0xcc, 0x6b, 0x49, 0xc7, 0xd8, 0xad, 0xde, 0xca, 0xfe, 0x01, 0x23, 0x45, 0x67, 0xab, 0xcd, 0xef, 0xcc, 0x6b, 0x49, 0xc7, 0xd8, 0xad, 0xde, 0xca, 0xfe, 0x01, 0x23, 0x45, 0x67, 0xab, 0xcd, 0xef, 0xcc, 0x6b, 0x49, 0xc7, 0xd8, 0xad, 0xde, 0xca, 0xfe, 0x01, 0x23, 0x45, 0x67, 0xab, 0xcd, 0xef, 0xcc, 0x6b, 0x49, 0xc7, 0xd8, 0xad, 0xde, 0xca, 0xfe, 0x01, 0x23, 0x45, 0x67, 0xab, 0xcd, 0xef, 0xcc }; const char erb_dummy_mac1[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x22 }; const char erb_dummy_data2[] = { 0x55, 0x66, 0x77, 0x88, 0x88, 0x77, 0x66, 0x55, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0xca, 0xfe, 0x55, 0x66, 0x77, 0x88, 0x88, 0x77, 0x66, 0x55, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0xca, 0xfe, 0xca, 0xfe, 0x77, 0x55, 0x66, 0x5a, 0xa5, 0xcc, 0x00, 0xbe, 0xef, 0x55, 0x66, 0xcc, 0xca, 0xfe, 0x55, 0x66, 0x77, 0x88, 0x88, 0x77, 0x66, 0x55, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0xca, 0xfe, 0x55, 0x66, 0x77, 0x88, 0x88, 0x77, 0x66, 0x55, 0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0xca, 0xfe }; const char erb_dummy_mac2[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x33 }; int erbTester_proc_write(struct file *file, const char *buffer, unsigned long count, void *data) { char proc_buffer[count]; char *strptr; char *cmdptr; static int testcnt = 0; /* write data to the buffer */ memset(proc_buffer, 0, sizeof(proc_buffer)); if ( copy_from_user(proc_buffer, buffer, count) ) { return -EFAULT; } proc_buffer[count] = '\0'; strptr = proc_buffer; if (strlen(strptr) == 0) { goto errout; } cmdptr = strsep(&strptr," "); if (cmdptr==NULL) { goto errout; } //int re865x_send_ERB(char* ERB_data, int ERB_data_len, int line_id,int sync_symbol_count,int segment_code,unsigned char* VCE_macaddr) /*parse command*/ if (strncmp(cmdptr, "1",1) == 0) { switch (testcnt%3) { case 0: re865x_send_ERB(erb_dummy_data0, sizeof(erb_dummy_data0), 1, 0, 0, erb_dummy_mac0); break; case 1: re865x_send_ERB(erb_dummy_data1, sizeof(erb_dummy_data1), 1, 0, 0, erb_dummy_mac1); break; case 2: re865x_send_ERB(erb_dummy_data2, sizeof(erb_dummy_data2), 1, 0, 0, erb_dummy_mac2); break; } }; testcnt++; if (testcnt > 65536) testcnt = 0; errout: return count; } static int read_proc_open_erbTester(struct inode *inode, struct file *file) { return(single_open(file, erbTester_proc_read, NULL)); } static ssize_t write_proc_erbTester(struct file *file, const char __user * userbuf, size_t count, loff_t * off) { return erbTester_proc_write(file, userbuf, count, NULL); } static struct file_operations fops_erbTester = { .open = read_proc_open_erbTester, .read = seq_read, .llseek = seq_lseek, .release = single_release, .write = write_proc_erbTester, }; void erbTester_proc_init(void) { struct proc_dir_entry *entry; entry = proc_create_data("erbTester", 0644, NULL, &fops_erbTester, NULL); if (!entry) printk("\n\n proc entry erbTester created fail!\n\n"); } #endif