📄 wanpipe_multppp.c
字号:
/* These two commands are executed for * each request */ case READ_CHDLC_CONFIGURATION: case READ_CHDLC_CODE_VERSION: udp_mgmt_req_valid = 1; break; default: udp_mgmt_req_valid = 0; break; } } if(!udp_mgmt_req_valid) { /* set length to 0 */ chdlc_udp_pkt->cblock.buffer_length = 0; /* set return code */ chdlc_udp_pkt->cblock.return_code = 0xCD; if (net_ratelimit()){ printk(KERN_INFO "%s: Warning, Illegal UDP command attempted from network: %x\n", card->devname,chdlc_udp_pkt->cblock.command); } } else { unsigned long trace_status_cfg_addr = 0; TRACE_STATUS_EL_CFG_STRUCT trace_cfg_struct; TRACE_STATUS_ELEMENT_STRUCT trace_element_struct; switch(chdlc_udp_pkt->cblock.command) { case CPIPE_ENABLE_TRACING: if (!chdlc_priv_area->TracingEnabled) { /* OPERATE_DATALINE_MONITOR */ mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT); mb->command = SET_TRACE_CONFIGURATION; ((LINE_TRACE_CONFIG_STRUCT *)mb->data)-> trace_config = TRACE_ACTIVE; /* Trace delay mode is not used because it slows down transfer and results in a standoff situation when there is a lot of data */ /* Configure the Trace based on user inputs */ ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->trace_config |= chdlc_udp_pkt->data[0]; ((LINE_TRACE_CONFIG_STRUCT *)mb->data)-> trace_deactivation_timer = 4000; err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; if (err != COMMAND_OK) { chdlc_error(card,err,mb); card->TracingEnabled = 0; chdlc_udp_pkt->cblock.return_code = err; mb->buffer_length = 0; break; } /* Get the base address of the trace element list */ mb->buffer_length = 0; mb->command = READ_TRACE_CONFIGURATION; err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; if (err != COMMAND_OK) { chdlc_error(card,err,mb); chdlc_priv_area->TracingEnabled = 0; chdlc_udp_pkt->cblock.return_code = err; mb->buffer_length = 0; break; } trace_status_cfg_addr =((LINE_TRACE_CONFIG_STRUCT *) mb->data) -> ptr_trace_stat_el_cfg_struct; sdla_peek(&card->hw, trace_status_cfg_addr, &trace_cfg_struct, sizeof(trace_cfg_struct)); chdlc_priv_area->start_trace_addr = trace_cfg_struct. base_addr_trace_status_elements; chdlc_priv_area->number_trace_elements = trace_cfg_struct.number_trace_status_elements; chdlc_priv_area->end_trace_addr = (unsigned long) ((TRACE_STATUS_ELEMENT_STRUCT *) chdlc_priv_area->start_trace_addr + (chdlc_priv_area->number_trace_elements - 1)); chdlc_priv_area->base_addr_trace_buffer = trace_cfg_struct.base_addr_trace_buffer; chdlc_priv_area->end_addr_trace_buffer = trace_cfg_struct.end_addr_trace_buffer; chdlc_priv_area->curr_trace_addr = trace_cfg_struct.next_trace_element_to_use; chdlc_priv_area->available_buffer_space = 2000 - sizeof(ip_pkt_t) - sizeof(udp_pkt_t) - sizeof(wp_mgmt_t) - sizeof(cblock_t) - sizeof(trace_info_t); } chdlc_udp_pkt->cblock.return_code = COMMAND_OK; mb->buffer_length = 0; chdlc_priv_area->TracingEnabled = 1; break; case CPIPE_DISABLE_TRACING: if (chdlc_priv_area->TracingEnabled) { /* OPERATE_DATALINE_MONITOR */ mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT); mb->command = SET_TRACE_CONFIGURATION; ((LINE_TRACE_CONFIG_STRUCT *)mb->data)-> trace_config = TRACE_INACTIVE; err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; } chdlc_priv_area->TracingEnabled = 0; chdlc_udp_pkt->cblock.return_code = COMMAND_OK; mb->buffer_length = 0; break; case CPIPE_GET_TRACE_INFO: if (!chdlc_priv_area->TracingEnabled) { chdlc_udp_pkt->cblock.return_code = 1; mb->buffer_length = 0; break; } chdlc_udp_pkt->trace_info.ismoredata = 0x00; buffer_length = 0; /* offset of packet already occupied */ for (frames=0; frames < chdlc_priv_area->number_trace_elements; frames++){ trace_pkt_t *trace_pkt = (trace_pkt_t *) &chdlc_udp_pkt->data[buffer_length]; sdla_peek(&card->hw, chdlc_priv_area->curr_trace_addr, (unsigned char *)&trace_element_struct, sizeof(TRACE_STATUS_ELEMENT_STRUCT)); if (trace_element_struct.opp_flag == 0x00) { break; } /* get pointer to real data */ data_ptr = trace_element_struct.ptr_data_bfr; /* See if there is actual data on the trace buffer */ if (data_ptr){ data_length = trace_element_struct.trace_length; }else{ data_length = 0; chdlc_udp_pkt->trace_info.ismoredata = 0x01; } if( (chdlc_priv_area->available_buffer_space - buffer_length) < ( sizeof(trace_pkt_t) + data_length) ) { /* indicate there are more frames on board & exit */ chdlc_udp_pkt->trace_info.ismoredata = 0x01; break; } trace_pkt->status = trace_element_struct.trace_type; trace_pkt->time_stamp = trace_element_struct.trace_time_stamp; trace_pkt->real_length = trace_element_struct.trace_length; /* see if we can fit the frame into the user buffer */ real_len = trace_pkt->real_length; if (data_ptr == 0) { trace_pkt->data_avail = 0x00; } else { unsigned tmp = 0; /* get the data from circular buffer must check for end of buffer */ trace_pkt->data_avail = 0x01; if ((data_ptr + real_len) > chdlc_priv_area->end_addr_trace_buffer + 1){ tmp = chdlc_priv_area->end_addr_trace_buffer - data_ptr + 1; sdla_peek(&card->hw, data_ptr, trace_pkt->data,tmp); data_ptr = chdlc_priv_area->base_addr_trace_buffer; } sdla_peek(&card->hw, data_ptr, &trace_pkt->data[tmp], real_len - tmp); } /* zero the opp flag to show we got the frame */ ut_char = 0x00; sdla_poke(&card->hw, chdlc_priv_area->curr_trace_addr, &ut_char, 1); /* now move onto the next frame */ chdlc_priv_area->curr_trace_addr += sizeof(TRACE_STATUS_ELEMENT_STRUCT); /* check if we went over the last address */ if ( chdlc_priv_area->curr_trace_addr > chdlc_priv_area->end_trace_addr ) { chdlc_priv_area->curr_trace_addr = chdlc_priv_area->start_trace_addr; } if(trace_pkt->data_avail == 0x01) { buffer_length += real_len - 1; } /* for the header */ buffer_length += sizeof(trace_pkt_t); } /* For Loop */ if (frames == chdlc_priv_area->number_trace_elements){ chdlc_udp_pkt->trace_info.ismoredata = 0x01; } chdlc_udp_pkt->trace_info.num_frames = frames; mb->buffer_length = buffer_length; chdlc_udp_pkt->cblock.buffer_length = buffer_length; chdlc_udp_pkt->cblock.return_code = COMMAND_OK; break; case CPIPE_FT1_READ_STATUS: ((unsigned char *)chdlc_udp_pkt->data )[0] = flags->FT1_info_struct.parallel_port_A_input; ((unsigned char *)chdlc_udp_pkt->data )[1] = flags->FT1_info_struct.parallel_port_B_input; chdlc_udp_pkt->cblock.return_code = COMMAND_OK; mb->buffer_length = 2; break; case CPIPE_ROUTER_UP_TIME: do_gettimeofday( &tv ); chdlc_priv_area->router_up_time = tv.tv_sec - chdlc_priv_area->router_start_time; *(unsigned long *)&chdlc_udp_pkt->data = chdlc_priv_area->router_up_time; mb->buffer_length = sizeof(unsigned long); break; case FT1_MONITOR_STATUS_CTRL: /* Enable FT1 MONITOR STATUS */ if ((chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_STATUS) || (chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_OP_STATS)) { if( rCount++ != 0 ) { chdlc_udp_pkt->cblock. return_code = COMMAND_OK; mb->buffer_length = 1; break; } } /* Disable FT1 MONITOR STATUS */ if( chdlc_udp_pkt->data[0] == 0) { if( --rCount != 0) { chdlc_udp_pkt->cblock. return_code = COMMAND_OK; mb->buffer_length = 1; break; } } default: /* it's a board command */ mb->command = chdlc_udp_pkt->cblock.command; mb->buffer_length = chdlc_udp_pkt->cblock.buffer_length; if (mb->buffer_length) { memcpy(&mb->data, (unsigned char *) chdlc_udp_pkt-> data, mb->buffer_length); } /* run the command on the board */ err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; if (err != COMMAND_OK) { break; } /* copy the result back to our buffer */ memcpy(&chdlc_udp_pkt->cblock, mb, sizeof(cblock_t)); if (mb->buffer_length) { memcpy(&chdlc_udp_pkt->data, &mb->data, mb->buffer_length); } } /* end of switch */ } /* end of else */ /* Fill UDP TTL */ chdlc_udp_pkt->ip_pkt.ttl = card->wandev.ttl; len = reply_udp(chdlc_priv_area->udp_pkt_data, mb->buffer_length); if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) { if(!chdlc_send(card, chdlc_priv_area->udp_pkt_data, len)) { ++ card->wandev.stats.tx_packets;#if defined(LINUX_2_1) || defined(LINUX_2_4) card->wandev.stats.tx_bytes += len;#endif } } else { /* Pass it up the stack Allocate socket buffer */ if ((new_skb = dev_alloc_skb(len)) != NULL) { /* copy data into new_skb */ buf = skb_put(new_skb, len); memcpy(buf, chdlc_priv_area->udp_pkt_data, len); /* Decapsulate pkt and pass it up the protocol stack */ new_skb->protocol = htons(ETH_P_IP); new_skb->dev = dev; new_skb->mac.raw = new_skb->data; netif_rx(new_skb); } else { printk(KERN_INFO "%s: no socket buffers available!\n", card->devname); } } chdlc_priv_area->udp_pkt_lgth = 0; return 0;}/*============================================================================ * Initialize Receive and Transmit Buffers. */static void init_chdlc_tx_rx_buff( sdla_t* card, netdevice_t *dev ){ CHDLC_MAILBOX_STRUCT* mb = card->mbox; CHDLC_TX_STATUS_EL_CFG_STRUCT *tx_config; CHDLC_RX_STATUS_EL_CFG_STRUCT *rx_config; char err; mb->buffer_length = 0; mb->command = READ_CHDLC_CONFIGURATION; err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; if(err != COMMAND_OK) { chdlc_error(card,err,mb); return; } if(card->hw.type == SDLA_S514) { tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase + (((CHDLC_CONFIGURATION_STRUCT *)mb->data)-> ptr_CHDLC_Tx_stat_el_cfg_struct)); rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase + (((CHDLC_CONFIGURATION_STRUCT *)mb->data)-> ptr_CHDLC_Rx_stat_el_cfg_struct)); /* Setup Head and Tails for buffers */ card->u.c.txbuf_base = (void *)(card->hw.dpmbase + tx_config->base_addr_Tx_status_elements); card->u.c.txbuf_last = (CHDLC_DATA_TX_STATUS_EL_STRUCT *) card->u.c.txbuf_base + (tx_config->number_Tx_status_elements - 1); card->u.c.rxbuf_base = (void *)(card->hw.dpmbase + rx_config->base_addr_Rx_status_elements); card->u.c.rxbuf_last = (CHDLC_DATA_RX_STATUS_EL_STRUCT *) card->u.c.rxbuf_base + (rx_config->number_Rx_status_elements - 1); /* Set up next pointer to be used */ card->u.c.txbuf = (void *)(card->hw.dpmbase + tx_config->next_Tx_status_element_to_use); card->u.c.rxmb = (void *)(card->hw.dpmbase + rx_config->next_Rx_status_element_to_use); } else { tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase + (((CHDLC_CONFIGURATION_STRUCT *)mb->data)-> ptr_CHDLC_Tx_stat_el_cfg_struct % SDLA_WINDOWSIZE)); rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase + (((CHDLC_CONFIGURATION_STRUCT *)mb->data)-> ptr_CHDLC_Rx_stat_el_cfg_struct % SDLA_WINDOWSIZE)); /* Setup Head and Tails for buffers */ card->u.c.txbuf_base = (void *)(card->hw.dpmbase + (tx_config->base_addr_Tx_status_elements % SDLA_WINDOWSIZE)); card->u.c.txbuf_last = (CHDLC_DATA_TX_STATUS_EL_STRUCT *)card->u.c.txbuf_base + (tx_config->number_Tx_status_elements - 1); card->u.c.rxbuf_base = (void *)(card->hw.dpmbase + (rx_config->base_addr_Rx_status_elements % SDLA_WINDOWSIZE)); card->u.c.rxbuf_last = (CHDLC_DATA_RX_STATUS_EL_STRUCT *)card->u.c.rxbuf_base + (rx_config->number_Rx_status_elements - 1); /* Set up next pointer to be used */ card->u.c.txbuf = (void *)(card->hw.dpmbase + (tx_config->next_Tx_status_element_to_use % SDLA_WINDOWSIZE)); card->u.c.rxmb = (void *)(card->hw.dpmbase + (rx_config->next_Rx_status_element_to_use % SDLA_WINDOWSIZE)); } /* Setup Actual Buffer Start and end addresses */ card->u.c.rx_base = rx_config->base_addr_Rx_buffer; card->u.c.rx_top = rx_config->end_addr_Rx_buffer;}/*============================================================================= * Perform Interrupt Test by running READ_CHDLC_CODE_VERSION command MAX_INTR * _TEST_COUNTER times. */static int intr_test( sdla_t* card){ CHDLC_MAILBOX_STRUCT* mb = card->mbox; int err,i; Intr_test_counter = 0; /* The critical flag is unset because during intialization (if_open) * we want the interrupts to be enabled so that when the wpc_isr is * called it does not exit due to critical flag set. */ err = chdlc_set_intr_mode(card, APP_INT_ON_COMMAND_COMPLETE); if (err == CMD_OK) { for (i = 0; i < MAX
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -