📄 wanpipe_multppp.c
字号:
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; card->wandev.stats.tx_bytes += len; } } 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); dev->last_rx = jiffies; } 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, struct net_device *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 initialization (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_INTR_TEST_COUNTER; i ++) { mb->buffer_length = 0; mb->command = READ_CHDLC_CODE_VERSION; err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT; } } else { return err; } err = chdlc_set_intr_mode(card, 0); if (err != CMD_OK) return err; return 0;}/*============================================================================== * Determine what type of UDP call it is. CPIPEAB ? */static int udp_pkt_type(struct sk_buff *skb, sdla_t* card){ chdlc_udp_pkt_t *chdlc_udp_pkt = (chdlc_udp_pkt_t *)skb->data; if (!strncmp(chdlc_udp_pkt->wp_mgmt.signature,UDPMGMT_SIGNATURE,8) && (chdlc_udp_pkt->udp_pkt.udp_dst_port == ntohs(card->wandev.udp_port)) && (chdlc_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) && (chdlc_udp_pkt->wp_mgmt.request_reply == UDPMGMT_REQUEST)) { return UDP_CPIPE_TYPE; } else return UDP_INVALID_TYPE;}/*============================================================================ * Set PORT state. */static void port_set_state (sdla_t *card, int state){ struct net_device *dev = card->wandev.dev; chdlc_private_area_t *chdlc_priv_area = dev->priv; if (card->u.c.state != state) { switch (state) { case WAN_CONNECTED: printk (KERN_INFO "%s: HDLC link connected!\n", card->devname); break; case WAN_CONNECTING: printk (KERN_INFO "%s: HDLC link connecting...\n", card->devname); break; case WAN_DISCONNECTED: printk (KERN_INFO "%s: HDLC link disconnected!\n", card->devname); break; } card->wandev.state = card->u.c.state = state; chdlc_priv_area->common.state = state; }}void s508_lock (sdla_t *card, unsigned long *smp_flags){ spin_lock_irqsave(&card->wandev.lock, *smp_flags); if (card->next){ /* It is ok to use spin_lock here, since we * already turned off interrupts */ spin_lock(&card->next->wandev.lock); }}void s508_unlock (sdla_t *card, unsigned long *smp_flags){ if (card->next){ spin_unlock(&card->next->wandev.lock); } spin_unlock_irq
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -