📄 sdla_ppp.c
字号:
/****************************************************************************** sdla_ppp.c WANPIPE(tm) Multiprotocol WAN Link Driver. PPP module.** Author: Nenad Corbic <ncorbic@sangoma.com>** Copyright: (c) 1995-1999 Sangoma Technologies Inc.** This program is free software; you can redistribute it and/or* modify it under the terms of the GNU General Public License* as published by the Free Software Foundation; either version* 2 of the License, or (at your option) any later version.* ============================================================================** Oct 25, 1999 Nenad Corbic o Support for 2.0.X kernels* Moved dynamic route processing into * a polling routine.* Oct 07, 1999 Nenad Corbic o Support for S514 PCI card. * Gideon Hack o UPD and Updates executed using timer interrupt* Sep 10, 1999 Nenad Corbic o Fixed up the /proc statistics* Jul 20, 1999 Nenad Corbic o Remove the polling routines and use * interrupts instead.* Sep 17, 1998 Jaspreet Singh o Updates for 2.2.X Kernels.* Aug 13, 1998 Jaspreet Singh o Improved Line Tracing.* Jun 22, 1998 David Fong o Added remote IP address assignment* Mar 15, 1998 Alan Cox o 2.1.8x basic port.* Apr 16, 1998 Jaspreet Singh o using htons() for the IPX protocol.* Dec 09, 1997 Jaspreet Singh o Added PAP and CHAP.* o Implemented new routines like * ppp_set_inbnd_auth(), ppp_set_outbnd_auth(),* tokenize() and strstrip().* Nov 27, 1997 Jaspreet Singh o Added protection against enabling of irqs * while they have been disabled.* Nov 24, 1997 Jaspreet Singh o Fixed another RACE condition caused by* disabling and enabling of irqs.* o Added new counters for stats on disable/enable* IRQs.* Nov 10, 1997 Jaspreet Singh o Initialized 'skb->mac.raw' to 'skb->data'* before every netif_rx().* o Free up the device structure in del_if().* Nov 07, 1997 Jaspreet Singh o Changed the delay to zero for Line tracing* command.* Oct 20, 1997 Jaspreet Singh o Added hooks in for Router UP time.* Oct 16, 1997 Jaspreet Singh o The critical flag is used to maintain flow* control by avoiding RACE conditions. The * cli() and restore_flags() are taken out.* A new structure, "ppp_private_area", is added * to provide Driver Statistics. * Jul 21, 1997 Jaspreet Singh o Protected calls to sdla_peek() by adding * save_flags(), cli() and restore_flags().* Jul 07, 1997 Jaspreet Singh o Added configurable TTL for UDP packets* o Added ability to discard mulitcast and* broacast source addressed packets.* Jun 27, 1997 Jaspreet Singh o Added FT1 monitor capabilities* New case (0x25) statement in if_send routine.* Added a global variable rCount to keep track* of FT1 status enabled on the board.* May 22, 1997 Jaspreet Singh o Added change in the PPP_SET_CONFIG command for* 508 card to reflect changes in the new * ppp508.sfm for supporting:continous transmission* of Configure-Request packets without receiving a* reply * OR-ed 0x300 to conf_flags * o Changed connect_tmout from 900 to 0* May 21, 1997 Jaspreet Singh o Fixed UDP Management for multiple boards* Apr 25, 1997 Farhan Thawar o added UDP Management stuff* Mar 11, 1997 Farhan Thawar Version 3.1.1* o fixed (+1) bug in rx_intr()* o changed if_send() to return 0 if* wandev.critical() is true* o free socket buffer in if_send() if* returning 0 * Jan 15, 1997 Gene Kozin Version 3.1.0* o implemented exec() entry point* Jan 06, 1997 Gene Kozin Initial version.*****************************************************************************/#include <linux/config.h>#include <linux/version.h>#include <linux/kernel.h> /* printk(), and other useful stuff */#include <linux/stddef.h> /* offsetof(), etc. */#include <linux/errno.h> /* return codes */#include <linux/string.h> /* inline memset(), etc. */#include <linux/malloc.h> /* kmalloc(), kfree() */#include <linux/wanrouter.h> /* WAN router definitions */#include <linux/wanpipe.h> /* WANPIPE common user API definitions */#include <linux/if_arp.h> /* ARPHRD_* defines */#include <asm/byteorder.h> /* htons(), etc. */#include <linux/in.h> /* sockaddr_in */#include <linux/inet.h> /* in_aton(), in_ntoa() prototypes */#include <linux/inetdevice.h>#include <asm/uaccess.h>#include <linux/if.h>#include <linux/sdla_ppp.h> /* PPP firmware API definitions */#include <linux/sdlasfm.h> /* S514 Type Definition *//****** Defines & Macros ****************************************************/#ifdef _DEBUG_#define STATIC#else#define STATIC static#endif#define PPP_DFLT_MTU 1500 /* default MTU */#define PPP_MAX_MTU 4000 /* maximum MTU */#define PPP_HDR_LEN 1#define CONNECT_TIMEOUT (90*HZ) /* link connection timeout */#define HOLD_DOWN_TIME (5*HZ) /* link hold down time : Changed from 30 to 5 *//* For handle_IPXWAN() */#define CVHexToAscii(b) (((unsigned char)(b) > (unsigned char)9) ? ((unsigned char)'A' + ((unsigned char)(b) - (unsigned char)10)) : ((unsigned char)'0' + (unsigned char)(b)))/* Macro for enabling/disabling debugging comments *///#define NEX_DEBUG#ifdef NEX_DEBUG#define NEX_PRINTK(format, a...) printk(format, ## a)#else#define NEX_PRINTK(format, a...)#endif /* NEX_DEBUG */ #define DCD(a) ( a & 0x08 ? "HIGH" : "LOW" )#define CTS(a) ( a & 0x20 ? "HIGH" : "LOW" )#define LCP(a) ( a == 0x09 ? "OPEN" : "CLOSED" )#define IP(a) ( a == 0x09 ? "ENABLED" : "DISABLED" )#define TMR_INT_ENABLED_UPDATE 1#define TMR_INT_ENABLED_PPP_EVENT 2#define TMR_INT_ENABLED_UDP 4/* Set Configuraton Command Definitions */#define PERCENT_TX_BUFF 60#define TIME_BETWEEN_CONF_REQ 30#define TIME_BETWEEN_PAP_CHAP_REQ 30#define WAIT_PAP_CHAP_WITHOUT_REPLY 300#define WAIT_AFTER_DCD_CTS_LOW 5#define TIME_DCD_CTS_LOW_AFTER_LNK_DOWN 10#define WAIT_DCD_HIGH_AFTER_ENABLE_COMM 900#define MAX_CONF_REQ_WITHOUT_REPLY 10#define MAX_TERM_REQ_WITHOUT_REPLY 2#define NUM_CONF_NAK_WITHOUT_REPLY 5#define NUM_AUTH_REQ_WITHOUT_REPLY 10#define END_OFFSET 0x1F0#define TX_TIMEOUT (5*HZ)/******Data Structures*****************************************************//* This structure is placed in the private data area of the device structure. * The card structure used to occupy the private area but now the following * structure will incorporate the card structure along with PPP specific data */ typedef struct ppp_private_area{ /* This member must be first. */ struct net_device *slave; /* WAN slave */ sdla_t* card; unsigned long router_start_time; /*router start time in sec */ unsigned long tick_counter; /*used for 5 second counter*/ unsigned mc; /*multicast support on or off*/ unsigned char enable_IPX; unsigned long network_number; unsigned char pap; unsigned char chap; unsigned char sysname[31]; /* system name for in-bnd auth*/ unsigned char userid[511]; /* list of user ids */ unsigned char passwd[511]; /* list of passwords */ unsigned protocol; /* SKB Protocol */ u32 ip_local; /* Local IP Address */ u32 ip_remote; /* remote IP Address */ unsigned char timer_int_enabled; /* Who enabled the timer inter*/ unsigned char update_comms_stats; /* Used by update function */ unsigned long curr_trace_addr; /* Trace information */ unsigned long start_trace_addr; unsigned long end_trace_addr; unsigned short udp_pkt_lgth; char udp_pkt_src; char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT]; /* PPP specific statistics */ if_send_stat_t if_send_stat; rx_intr_stat_t rx_intr_stat; pipe_mgmt_stat_t pipe_mgmt_stat; unsigned long router_up_time; }ppp_private_area_t;/* variable for keeping track of enabling/disabling FT1 monitor status */static int rCount = 0;extern void disable_irq(unsigned int);extern void enable_irq(unsigned int);/****** Function Prototypes *************************************************//* WAN link driver entry points. These are called by the WAN router module. */static int update(wan_device_t *wandev);static int new_if(wan_device_t *wandev, struct net_device *dev, wanif_conf_t *conf);static int del_if(wan_device_t *wandev, struct net_device *dev);/* WANPIPE-specific entry points */static int wpp_exec (struct sdla *card, void *u_cmd, void *u_data);/* Network device interface */static int if_init(struct net_device *dev);static int if_open(struct net_device *dev);static int if_close(struct net_device *dev);static void if_tx_timeout (struct net_device *dev);static int if_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len);static int if_rebuild_hdr(struct sk_buff *skb);static struct net_device_stats *if_stats(struct net_device *dev);static int if_send(struct sk_buff *skb, struct net_device *dev);/* PPP firmware interface functions */static int ppp_read_version(sdla_t *card, char *str);static int ppp_set_outbnd_auth(sdla_t *card, ppp_private_area_t *ppp_priv_area);static int ppp_set_inbnd_auth(sdla_t *card, ppp_private_area_t *ppp_priv_area);static int ppp_configure(sdla_t *card, void *data);static int ppp_set_intr_mode(sdla_t *card, unsigned char mode);static int ppp_comm_enable(sdla_t *card);static int ppp_comm_disable(sdla_t *card);static int ppp_get_err_stats(sdla_t *card);static int ppp_send(sdla_t *card, void *data, unsigned len, unsigned proto);static int ppp_error(sdla_t *card, int err, ppp_mbox_t *mb);STATIC void wpp_isr(sdla_t *card);static void rx_intr(sdla_t *card);static void event_intr(sdla_t *card);static void timer_intr(sdla_t *card);/* Background polling routines */static void process_route(sdla_t *card);static void poll_disconnected(sdla_t *card);/* Miscellaneous functions */static int read_info( sdla_t *card );static int read_connection_info (sdla_t *card);static int remove_route( sdla_t *card );static int config508(ppp_private_area_t *ppp_priv_area, sdla_t *card);static void show_disc_cause(sdla_t * card, unsigned cause);static int reply_udp( unsigned char *data, unsigned int mbox_len );static void process_udp_mgmt_pkt(sdla_t *card, struct net_device *dev, ppp_private_area_t *ppp_priv_area);static void init_ppp_tx_rx_buff( sdla_t *card );static int intr_test( sdla_t *card );static int udp_pkt_type( struct sk_buff *skb , sdla_t *card);static void init_ppp_priv_struct( ppp_private_area_t *ppp_priv_area);static void init_global_statistics( sdla_t *card );static int tokenize(char *str, char **tokens);static char* strstrip(char *str, char *s);static int chk_bcast_mcast_addr(sdla_t* card, struct net_device* dev, struct sk_buff *skb);static int Read_connection_info;static int Intr_test_counter;static unsigned short available_buffer_space;/* IPX functions */static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming);static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_PX, unsigned long network_number, unsigned short proto);/* Lock Functions */static void s508_lock (sdla_t *card, unsigned long *smp_flags);static void s508_unlock (sdla_t *card, unsigned long *smp_flags);static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card, struct sk_buff *skb, struct net_device* dev, ppp_private_area_t* ppp_priv_area );static unsigned short calc_checksum (char *data, int len);/****** Public Functions ****************************************************//*============================================================================ * PPP protocol initialization routine. * * This routine is called by the main WANPIPE module during setup. At this * point adapter is completely initialized and firmware is running. * o read firmware version (to make sure it's alive) * o configure adapter * o initialize protocol-specific fields of the adapter data space. * * Return: 0 o.k. * < 0 failure. */int wpp_init(sdla_t *card, wandev_conf_t *conf){ union { char str[80]; } u; /* Verify configuration ID */ if (conf->config_id != WANCONFIG_PPP) { printk(KERN_INFO "%s: invalid configuration ID %u!\n", card->devname, conf->config_id); return -EINVAL; } /* Initialize miscellaneous pointers to structures on the adapter */ switch (card->hw.type) { case SDLA_S508: card->mbox =(void*)(card->hw.dpmbase + PPP508_MB_OFFS); card->flags=(void*)(card->hw.dpmbase + PPP508_FLG_OFFS); break; case SDLA_S514: card->mbox =(void*)(card->hw.dpmbase + PPP514_MB_OFFS); card->flags=(void*)(card->hw.dpmbase + PPP514_FLG_OFFS); break; default: return -EINVAL; } /* Read firmware version. Note that when adapter initializes, it * clears the mailbox, so it may appear that the first command was * executed successfully when in fact it was merely erased. To work * around this, we execute the first command twice. */ if (ppp_read_version(card, NULL) || ppp_read_version(card, u.str)) return -EIO; printk(KERN_INFO "%s: running PPP firmware v%s\n",card->devname, u.str); /* Adjust configuration and set defaults */ card->wandev.mtu = (conf->mtu) ? min(conf->mtu, PPP_MAX_MTU) : PPP_DFLT_MTU; card->wandev.bps = conf->bps; card->wandev.interface = conf->interface; card->wandev.clocking = conf->clocking; card->wandev.station = conf->station; card->isr = &wpp_isr; card->poll = NULL; card->exec = &wpp_exec; card->wandev.update = &update; card->wandev.new_if = &new_if; card->wandev.del_if = &del_if; card->wandev.state = WAN_DISCONNECTED; card->wandev.udp_port = conf->udp_port; card->wandev.ttl = conf->ttl; card->irq_dis_if_send_count = 0; card->irq_dis_poll_count = 0; card->u.p.authenticator = conf->u.ppp.authenticator; card->u.p.ip_mode = conf->u.ppp.ip_mode ? conf->u.ppp.ip_mode : WANOPT_PPP_STATIC; card->TracingEnabled = 0; Read_connection_info = 1; /* initialize global statistics */ init_global_statistics( card ); return 0;}/******* WAN Device Driver Entry Points *************************************//*============================================================================ * Update device status & statistics. */static int update(wan_device_t *wandev){ sdla_t* card = wandev->private; struct net_device* dev = card->wandev.dev; volatile ppp_private_area_t *ppp_priv_area = dev->priv; ppp_flags_t *flags = card->flags; unsigned long timeout; /* sanity checks */ if ((wandev == NULL) || (wandev->private == NULL)) return -EFAULT; if (wandev->state == WAN_UNCONFIGURED) return -ENODEV; //FIXME: Do we need this if (test_bit(0, (void*)&wandev->critical)) return -EAGAIN; ppp_priv_area->update_comms_stats = 2; ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_UPDATE; flags->imask |= PPP_INTR_TIMER; /* wait a maximum of 1 second for the statistics to be updated */ timeout = jiffies; for(;;) { if(ppp_priv_area->update_comms_stats == 0){ break; } if ((jiffies - timeout) > (1 * HZ)){ ppp_priv_area->update_comms_stats = 0; ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UPDATE; return -EAGAIN; } } return 0;}/*============================================================================ * Create new logical channel. * This routine is called by the router when ROUTER_IFNEW IOCTL is being * handled. * o parse media- and hardware-specific configuration * o make sure that a new channel can be created * o allocate resources, if necessary * o prepare network device structure for registaration. * * Return: 0 o.k. * < 0 failure (channel will not be created) */static int new_if(wan_device_t *wandev, struct net_device *dev, wanif_conf_t *conf){ sdla_t *card = wandev->private; ppp_private_area_t *ppp_priv_area; if (wandev->ndev) return -EEXIST; if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) { printk(KERN_INFO "%s: invalid interface name!\n", card->devname); return -EINVAL; } /* allocate and initialize private data */ ppp_priv_area = kmalloc(sizeof(ppp_private_area_t), GFP_KERNEL); if( ppp_priv_area == NULL ) return -ENOMEM; memset(ppp_priv_area, 0, sizeof(ppp_private_area_t)); ppp_priv_area->card = card; /* initialize data */ strcpy(card->u.p.if_name, conf->name); /* initialize data in ppp_private_area structure */ init_ppp_priv_struct( ppp_priv_area );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -