📄 sdla_ppp.c
字号:
} else { if (net_ratelimit()){ printk(KERN_INFO "%s: no socket buffers available!\n", card->devname); } ++card->wandev.stats.rx_dropped; ++ppp_priv_area->rx_intr_stat.rx_intr_no_socket; } } else { ++card->statistics.rx_intr_dev_not_started; } /* Release buffer element and calculate a pointer to the next one */ rxbuf->flag = 0x00; card->rxmb = ++rxbuf; if ((void*)rxbuf > card->u.p.rxbuf_last) card->rxmb = card->u.p.rxbuf_base;}void event_intr (sdla_t *card){ struct net_device* dev = card->wandev.dev; ppp_private_area_t* ppp_priv_area = dev->priv; volatile ppp_flags_t *flags = card->flags; switch (flags->iflag){ case PPP_INTR_MODEM: /* modem status change (DCD, CTS) 0x04 (bit 2)*/ if (net_ratelimit()){ printk (KERN_INFO "%s: Modem status: DCD=%s CTS=%s\n", card->devname, DCD(flags->mstatus), CTS(flags->mstatus)); } break; case PPP_INTR_DISC: /* Data link disconnected 0x10 (bit 4)*/ NEX_PRINTK (KERN_INFO "Data link disconnected intr Cause %X\n", flags->disc_cause); if (flags->disc_cause & (PPP_LOCAL_TERMINATION | PPP_DCD_CTS_DROP | PPP_REMOTE_TERMINATION)) { if (card->u.p.ip_mode == WANOPT_PPP_PEER) { set_bit(0,&Read_connection_info); } wanpipe_set_state(card, WAN_DISCONNECTED); show_disc_cause(card, flags->disc_cause); ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_PPP_EVENT; flags->imask |= PPP_INTR_TIMER; trigger_ppp_poll(dev); } break; case PPP_INTR_OPEN: /* Data link open 0x20 (bit 5)*/ NEX_PRINTK (KERN_INFO "%s: PPP Link Open, LCP=%s IP=%s\n", card->devname,LCP(flags->lcp_state), IP(flags->ip_state)); if (flags->lcp_state == 0x09 && (flags->ip_state == 0x09 || flags->ipx_state == 0x09)){ /* Initialize the polling timer and set the state * to WAN_CONNNECTED */ /* BUG FIX: When the protocol restarts, during heavy * traffic, board tx buffers and driver tx buffers * can go out of sync. This checks the condition * and if the tx buffers are out of sync, the * protocols are restarted. * I don't know why the board tx buffer is out * of sync. It could be that a packets is tx * while the link is down, but that is not * possible. The other possiblility is that the * firmware doesn't reinitialize properly. * FIXME: A better fix should be found. */ if (detect_and_fix_tx_bug(card)){ ppp_comm_disable(card); wanpipe_set_state(card, WAN_DISCONNECTED); ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_PPP_EVENT; flags->imask |= PPP_INTR_TIMER; break; } card->state_tick = jiffies; wanpipe_set_state(card, WAN_CONNECTED); NEX_PRINTK(KERN_INFO "CON: L Tx: %lx B Tx: %lx || L Rx %lx B Rx %lx\n", (unsigned long)card->u.p.txbuf, *card->u.p.txbuf_next, (unsigned long)card->rxmb, *card->u.p.rxbuf_next); /* Tell timer interrupt that PPP event occurred */ ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_PPP_EVENT; flags->imask |= PPP_INTR_TIMER; /* If we are in PEER mode, we must first obtain the * IP information and then go into the poll routine */ if (card->u.p.ip_mode != WANOPT_PPP_PEER){ trigger_ppp_poll(dev); } } break; case PPP_INTR_DROP_DTR: /* DTR drop timeout expired 0x40 bit 6 */ NEX_PRINTK(KERN_INFO "DTR Drop Timeout Interrrupt \n"); if (card->u.p.ip_mode == WANOPT_PPP_PEER) { set_bit(0,&Read_connection_info); } wanpipe_set_state(card, WAN_DISCONNECTED); show_disc_cause(card, flags->disc_cause); ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_PPP_EVENT; flags->imask |= PPP_INTR_TIMER; trigger_ppp_poll(dev); break; default: printk(KERN_INFO "%s: Error, Invalid PPP Event\n",card->devname); }}/* TIMER INTERRUPT */void timer_intr (sdla_t *card){ struct net_device* dev = card->wandev.dev; ppp_private_area_t* ppp_priv_area = dev->priv; ppp_flags_t *flags = card->flags; if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_CONFIG){ if (!config_ppp(card)){ ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_CONFIG; } } /* Update statistics */ if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE){ ppp_get_err_stats(card); if(!(--ppp_priv_area->update_comms_stats)){ ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UPDATE; } } /* PPIPEMON UDP request */ if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP){ process_udp_mgmt_pkt(card,dev, ppp_priv_area); ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP; } /* PPP Event */ if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_PPP_EVENT){ if (card->wandev.state == WAN_DISCONNECTED){ retrigger_comm(card); } /* If the state is CONNECTING, it means that communicatins were * enabled. When the remote side enables its comminication we * should get an interrupt PPP_INTR_OPEN, thus turn off polling */ else if (card->wandev.state == WAN_CONNECTING){ /* Turn off the timer interrupt */ ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_PPP_EVENT; } /* If state is connected and we are in PEER mode * poll for an IP address which will be provided by remote end. */ else if ((card->wandev.state == WAN_CONNECTED && card->u.p.ip_mode == WANOPT_PPP_PEER) && test_bit(0,&Read_connection_info)){ card->state_tick = jiffies; if (read_connection_info (card)){ printk(KERN_INFO "%s: Failed to read PEER IP Addresses\n", card->devname); }else{ clear_bit(0,&Read_connection_info); set_bit(1,&Read_connection_info); trigger_ppp_poll(dev); } }else{ //FIXME Put the comment back int ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_PPP_EVENT; } }/* End of PPP_EVENT */ /* Only disable the timer interrupt if there are no udp, statistic */ /* updates or events pending */ if(!ppp_priv_area->timer_int_enabled) { flags->imask &= ~PPP_INTR_TIMER; }}static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number, unsigned short proto){ int i; if( proto == htons(ETH_P_IPX) ) { //It's an IPX packet if(!enable_IPX) { //Return 1 so we don't pass it up the stack. return 1; } } else { //It's not IPX so pass it up the stack. return 0; } if( sendpacket[16] == 0x90 && sendpacket[17] == 0x04) { //It's IPXWAN if( sendpacket[2] == 0x02 && sendpacket[34] == 0x00) { //It's a timer request packet printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n",devname); //Go through the routing options and answer no to every //option except Unnumbered RIP/SAP for(i = 41; sendpacket[i] == 0x00; i += 5) { //0x02 is the option for Unnumbered RIP/SAP if( sendpacket[i + 4] != 0x02) { sendpacket[i + 1] = 0; } } //Skip over the extended Node ID option if( sendpacket[i] == 0x04 ) { i += 8; } //We also want to turn off all header compression opt. for(; sendpacket[i] == 0x80 ;) { sendpacket[i + 1] = 0; i += (sendpacket[i + 2] << 8) + (sendpacket[i + 3]) + 4; } //Set the packet type to timer response sendpacket[34] = 0x01; printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n",devname); } else if( sendpacket[34] == 0x02 ) { //This is an information request packet printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n",devname); //Set the packet type to information response sendpacket[34] = 0x03; //Set the router name sendpacket[51] = 'P'; sendpacket[52] = 'T'; sendpacket[53] = 'P'; sendpacket[54] = 'I'; sendpacket[55] = 'P'; sendpacket[56] = 'E'; sendpacket[57] = '-'; sendpacket[58] = CVHexToAscii(network_number >> 28); sendpacket[59] = CVHexToAscii((network_number & 0x0F000000)>> 24); sendpacket[60] = CVHexToAscii((network_number & 0x00F00000)>> 20); sendpacket[61] = CVHexToAscii((network_number & 0x000F0000)>> 16); sendpacket[62] = CVHexToAscii((network_number & 0x0000F000)>> 12); sendpacket[63] = CVHexToAscii((network_number & 0x00000F00)>> 8); sendpacket[64] = CVHexToAscii((network_number & 0x000000F0)>> 4); sendpacket[65] = CVHexToAscii(network_number & 0x0000000F); for(i = 66; i < 99; i+= 1) { sendpacket[i] = 0; } printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n",devname); } else { printk(KERN_INFO "%s: Unknown IPXWAN packet!\n",devname); return 0; } //Set the WNodeID to our network address sendpacket[35] = (unsigned char)(network_number >> 24); sendpacket[36] = (unsigned char)((network_number & 0x00FF0000) >> 16); sendpacket[37] = (unsigned char)((network_number & 0x0000FF00) >> 8); sendpacket[38] = (unsigned char)(network_number & 0x000000FF); return 1; } else { //If we get here it's an IPX-data packet, so it'll get passed up the stack. //switch the network numbers switch_net_numbers(sendpacket, network_number, 1); return 0; }}/****** Background Polling Routines ****************************************//* All polling functions are invoked by the TIMER interrupt in the wpp_isr * routine. *//*============================================================================ * Monitor active link phase. */static void process_route (sdla_t *card){ ppp_flags_t *flags = card->flags; struct net_device *dev = card->wandev.dev; ppp_private_area_t *ppp_priv_area = dev->priv; if ((card->u.p.ip_mode == WANOPT_PPP_PEER) && (flags->ip_state == 0x09)){ /* We get ip_local from the firmware in PEER mode. * Therefore, if ip_local is 0, we failed to obtain * the remote IP address. */ if (ppp_priv_area->ip_local == 0) return; printk(KERN_INFO "%s: IPCP State Opened.\n", card->devname); if (read_info( card )) { printk(KERN_INFO "%s: An error occurred in IP assignment.\n", card->devname); } else { struct in_device *in_dev = dev->ip_ptr; if (in_dev != NULL ) { struct in_ifaddr *ifa = in_dev->ifa_list; printk(KERN_INFO "%s: Assigned Lcl. Addr: %u.%u.%u.%u\n", card->devname, NIPQUAD(ifa->ifa_local)); printk(KERN_INFO "%s: Assigned Rmt. Addr: %u.%u.%u.%u\n", card->devname, NIPQUAD(ifa->ifa_address)); }else{ printk(KERN_INFO "%s: Error: Failed to add a route for PPP interface %s\n", card->devname,dev->name); } } }}/*============================================================================ * Monitor physical link disconnected phase. * o if interface is up and the hold-down timeout has expired, then retry * connection. */static void retrigger_comm(sdla_t *card){ struct net_device *dev = card->wandev.dev; if (dev && ((jiffies - card->state_tick) > HOLD_DOWN_TIME)) { wanpipe_set_state(card, WAN_CONNECTING); if(ppp_comm_enable(card) == CMD_OK){ init_ppp_tx_rx_buff( card ); } }}/****** Miscellaneous Functions *********************************************//*============================================================================ * Configure S508 adapter. */static int config508(struct net_device *dev, sdla_t *card){ ppp508_conf_t cfg; struct in_device *in_dev = dev->ip_ptr; ppp_private_area_t *ppp_priv_area = dev->priv; /* Prepare PPP configuration structure */ memset(&cfg, 0, sizeof(ppp508_conf_t)); if (card->wandev.clocking) cfg.line_speed = card->wandev.bps; if (card->wandev.interface == WANOPT_RS232) cfg.conf_flags |= INTERFACE_LEVEL_RS232; cfg.conf_flags |= DONT_TERMINATE_LNK_MAX_CONFIG; /*send Configure-Request packets forever*/ cfg.txbuf_percent = PERCENT_TX_BUFF; /* % of Tx bufs */ cfg.mtu_local = card->wandev.mtu; cfg.mtu_remote = card->wandev.mtu; /* Default */ cfg.restart_tmr = TIME_BETWEEN_CONF_REQ; /* 30 = 3sec */ cfg.auth_rsrt_tmr = TIME_BETWEEN_PAP_CHAP_REQ; /* 30 = 3sec */ cfg.auth_wait_tmr = WAIT_PAP_CHAP_WITHOUT_REPLY; /* 300 = 30s */ cfg.mdm_fail_tmr = WAIT_AFTER_DCD_CTS_LOW; /* 5 = 0.5s */ cfg.dtr_drop_tmr = TIME_DCD_CTS_LOW_AFTER_LNK_DOWN; /* 10 = 1s */ cfg.connect_tmout = WAIT_DCD_HIGH_AFTER_ENABLE_COMM; /* 900 = 90s */ cfg.conf_retry = MAX_CONF_REQ_WITHOUT_REPLY; /* 10 = 1s */ cfg.term_retry = MAX_TERM_REQ_WITHOUT_REPLY; /* 2 times */ cfg.fail_retry = NUM_CONF_NAK_WITHOUT_REPLY; /* 5 times */ cfg.auth_retry = NUM_AUTH_REQ_WITHOUT_REPLY; /* 10 times */ if( !card->u.p.authenticator ) { printk(KERN_INFO "%s: Device is not configured as an authenticator\n", card->devname); cfg.auth_options = NO_AUTHENTICATION; }else{ printk(KERN_INFO "%s: Device is configured as an authenticator\n", card->devname); cfg.auth_options
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -